From 98addccc8932c581b95637bdc00d3ab042d7252d Mon Sep 17 00:00:00 2001 From: Zev G Date: Thu, 2 Jan 2025 17:20:12 -0500 Subject: [PATCH 01/11] randomizer --- .editorconfig | 74 + Modules/AntiBlackout.cs | 4 +- Modules/ChatManager.cs | 33 +- Modules/CustomRolesHelper.cs | 157 +- Modules/Debugger.cs | 10 + Modules/DevManager.cs | 1 + Modules/ExtendedPlayerControl.cs | 116 +- Modules/GameState.cs | 125 + Modules/GuessManager.cs | 32 +- Modules/NameColorManager.cs | 166 +- Modules/OptionHolder.cs | 18 +- Modules/OptionItem/OptionItem.cs | 2 + Modules/OptionItem/StringOptionItem.cs | 5 + Modules/RPC.cs | 59 + Modules/Utils.cs | 76 +- Patches/ChatBubblePatch.cs | 6 +- Patches/ChatCommandPatch.cs | 6375 ++++++++-------- Patches/CheckGameEndPatch.cs | 135 +- Patches/ExilePatch.cs | 13 +- Patches/IntroPatch.cs | 201 +- Patches/MeetingHudPatch.cs | 7 + Patches/OneWayShadowsPatch.cs | 4 +- Patches/OutroPatch.cs | 37 +- Patches/PlayerControlPatch.cs | 23 +- Patches/SabotageSystemPatch.cs | 380 +- Patches/TaskAssignPatch.cs | 1 + Resources/Announcements/modNews-de_DE.json | 171 +- Resources/Announcements/modNews-en_US.json | 141 - Resources/Announcements/modNews-es_419.json | 163 +- Resources/Announcements/modNews-es_ES.json | 233 +- Resources/Announcements/modNews-fil_PH.json | 141 - Resources/Announcements/modNews-fr_FR.json | 233 +- Resources/Announcements/modNews-it_IT.json | 231 +- Resources/Announcements/modNews-ja_JP.json | 223 +- Resources/Announcements/modNews-ko_KR.json | 141 - Resources/Announcements/modNews-nl_NL.json | 141 - Resources/Announcements/modNews-pt_BR.json | 233 +- Resources/Announcements/modNews-pt_PT.json | 141 - Resources/Announcements/modNews-ru_RU.json | 147 +- Resources/Announcements/modNews-zh_CN.json | 151 +- Resources/Announcements/modNews-zh_TW.json | 161 +- Resources/Lang/de_DE.json | 341 +- Resources/Lang/en_US.json | 7585 ++++++++++--------- Resources/Lang/es_419.json | 171 +- Resources/Lang/es_ES.json | 125 +- Resources/Lang/fil_PH.json | 125 +- Resources/Lang/fr_FR.json | 125 +- Resources/Lang/it_IT.json | 215 +- Resources/Lang/ja_JP.json | 145 +- Resources/Lang/ko_KR.json | 125 +- Resources/Lang/nl_NL.json | 125 +- Resources/Lang/pt_BR.json | 137 +- Resources/Lang/pt_PT.json | 125 +- Resources/Lang/ru_RU.json | 125 +- Resources/Lang/zh_CN.json | 125 +- Resources/Lang/zh_TW.json | 157 +- Resources/roleColor.json | 500 +- Roles/(Ghosts)/Impostor/Possessor.cs | 10 +- Roles/AddOns/Common/FragileSoul.cs | 1 + Roles/AddOns/Common/Tired.cs | 4 +- Roles/AddOns/Common/allergic.cs | 143 + Roles/Core/AssignManager/GhostRoleAssign.cs | 2 + Roles/Core/CustomRoleManager.cs | 20 +- Roles/Core/RoleBase.cs | 12 +- Roles/Crewmate/Altruist.cs | 1 + Roles/Crewmate/Randomizer.cs | 948 ++- Roles/Crewmate/Sheriff.cs | 3 +- Roles/Impostor/Anonymous.cs | 11 +- Roles/Impostor/AntiAdminer.cs | 2 +- Roles/Impostor/Arrogance.cs | 6 +- Roles/Impostor/Blackmailer.cs | 6 +- Roles/Impostor/Bomber.cs | 2 +- Roles/Impostor/BountyHunter.cs | 44 +- Roles/Impostor/Butcher.cs | 8 +- Roles/Impostor/Chronomancer.cs | 24 +- Roles/Impostor/Consigliere.cs | 2 +- Roles/Impostor/Crewpostor.cs | 2 +- Roles/Impostor/CursedWolf.cs | 1 + Roles/Impostor/DoubleAgent.cs | 2 + Roles/Impostor/Visionary.cs | 5 +- Roles/Neutral/Baker.cs | 23 +- Roles/Neutral/LingeringPresence.cs | 718 ++ Roles/Neutral/Quizmaster.cs | 25 +- Roles/Neutral/Traitor.cs | 1 + Roles/Neutral/evolver.cs | 721 ++ Summoned.cs | 1 + TOHE - Backup.csproj | 50 + TOHE.csproj | 5 +- main.cs | 23 +- summoner.cs | 465 ++ 90 files changed, 12204 insertions(+), 12049 deletions(-) create mode 100644 Roles/AddOns/Common/FragileSoul.cs create mode 100644 Roles/AddOns/Common/allergic.cs create mode 100644 Roles/Neutral/LingeringPresence.cs create mode 100644 Roles/Neutral/evolver.cs create mode 100644 Summoned.cs create mode 100644 TOHE - Backup.csproj create mode 100644 summoner.cs diff --git a/.editorconfig b/.editorconfig index f694b8276..08a0260a4 100644 --- a/.editorconfig +++ b/.editorconfig @@ -2,3 +2,77 @@ # CA2211: Non-constant fields should not be visible dotnet_diagnostic.CA2211.severity = none +csharp_using_directive_placement = outside_namespace:silent +csharp_prefer_simple_using_statement = true:suggestion +csharp_prefer_braces = true:silent +csharp_style_namespace_declarations = block_scoped:silent +csharp_style_prefer_method_group_conversion = true:silent +csharp_style_prefer_top_level_statements = true:silent +csharp_style_prefer_primary_constructors = true:suggestion +csharp_prefer_system_threading_lock = true:suggestion +csharp_style_expression_bodied_methods = false:silent +csharp_style_expression_bodied_constructors = false:silent +csharp_style_expression_bodied_operators = false:silent +csharp_style_expression_bodied_properties = true:silent +csharp_style_expression_bodied_indexers = true:silent +csharp_style_expression_bodied_accessors = true:silent +csharp_style_expression_bodied_lambdas = true:silent +csharp_style_expression_bodied_local_functions = false:silent +csharp_indent_labels = one_less_than_current +csharp_space_around_binary_operators = before_and_after + +[*.{cs,vb}] +#### Naming styles #### + +# Naming rules + +dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion +dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface +dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i + +dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion +dotnet_naming_rule.types_should_be_pascal_case.symbols = types +dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case + +dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion +dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members +dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case + +# Symbol specifications + +dotnet_naming_symbols.interface.applicable_kinds = interface +dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.interface.required_modifiers = + +dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum +dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.types.required_modifiers = + +dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method +dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.non_field_members.required_modifiers = + +# Naming styles + +dotnet_naming_style.begins_with_i.required_prefix = I +dotnet_naming_style.begins_with_i.required_suffix = +dotnet_naming_style.begins_with_i.word_separator = +dotnet_naming_style.begins_with_i.capitalization = pascal_case + +dotnet_naming_style.pascal_case.required_prefix = +dotnet_naming_style.pascal_case.required_suffix = +dotnet_naming_style.pascal_case.word_separator = +dotnet_naming_style.pascal_case.capitalization = pascal_case + +dotnet_naming_style.pascal_case.required_prefix = +dotnet_naming_style.pascal_case.required_suffix = +dotnet_naming_style.pascal_case.word_separator = +dotnet_naming_style.pascal_case.capitalization = pascal_case +dotnet_style_coalesce_expression = true:suggestion +dotnet_style_null_propagation = true:suggestion +dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion +dotnet_style_prefer_auto_properties = true:silent +dotnet_style_operator_placement_when_wrapping = beginning_of_line +tab_width = 4 +indent_size = 4 +end_of_line = crlf diff --git a/Modules/AntiBlackout.cs b/Modules/AntiBlackout.cs index bcaa3ea1b..fd4a23294 100644 --- a/Modules/AntiBlackout.cs +++ b/Modules/AntiBlackout.cs @@ -34,11 +34,11 @@ public static bool CheckBlackOut() if (lastExiled != null && pc.PlayerId == lastExiled.PlayerId) continue; // Impostors - if (pc.Is(Custom_Team.Impostor)) + if (pc.Is(Custom_Team.Impostor) && !Main.PlayerStates[pc.PlayerId].IsRandomizer) Impostors.Add(pc.PlayerId); // Only Neutral killers - else if (pc.IsNeutralKiller() || pc.IsNeutralApocalypse()) + else if (pc.IsNeutralKiller() || pc.IsNeutralApocalypse() && !Main.PlayerStates[pc.PlayerId].IsRandomizer) NeutralKillers.Add(pc.PlayerId); // Crewmate diff --git a/Modules/ChatManager.cs b/Modules/ChatManager.cs index a4a7527d7..aa707b6eb 100644 --- a/Modules/ChatManager.cs +++ b/Modules/ChatManager.cs @@ -3,6 +3,7 @@ using System.Security.Cryptography; using System.Text; using TOHE.Roles.Impostor; +using TOHE.Roles.Neutral; using static TOHE.Translator; namespace TOHE.Modules.ChatManager @@ -93,6 +94,10 @@ public static void AddToHostMessage(string text) } public static void SendMessage(PlayerControl player, string message) { + if (player == null || string.IsNullOrWhiteSpace(message)) return; + + + int operate = 0; // 1:ID 2:猜测 string msg = message; string playername = player.GetNameWithRole(); @@ -102,7 +107,10 @@ public static void SendMessage(PlayerControl player, string message) if (CheckCommond(ref msg, "id|guesslist|gl编号|玩家编号|玩家id|id列表|玩家列表|列表|所有id|全部id|編號|玩家編號")) operate = 1; else if (CheckCommond(ref msg, "shoot|guess|bet|st|gs|bt|猜|赌|賭|sp|jj|tl|trial|审判|判|审|審判|審|compare|cmp|比较|比較|duel|sw|swap|st|换票|换|換票|換|finish|结束|结束会议|結束|結束會議|reveal|展示", false)) operate = 2; else if (ChatSentBySystem.Contains(GetTextHash(msg))) operate = 5; - + + + + // Handle Blackmailer blocking if ((operate == 1 || Blackmailer.CheckBlackmaile(player)) && player.IsAlive()) { Logger.Info($"包含特殊信息,不记录", "ChatManager"); @@ -131,29 +139,30 @@ public static void SendMessage(PlayerControl player, string message) { if (GameStates.IsExilling) { - if (Options.HideExileChat.GetBool()) - { + if (Options.HideExileChat.GetBool()) + { Logger.Info($"Message sent in exiling screen, spamming the chat", "ChatManager"); - _ = new LateTask (SendPreviousMessagesToAll, 0.3f, "Spamming the chat"); + _ = new LateTask(SendPreviousMessagesToAll, 0.3f, "Spamming the chat"); } return; } if (!player.IsAlive()) return; + message = msg; - //Logger.Warn($"Logging msg : {message}","Checking Exile"); Dictionary newChatEntry = new() - { - { player.PlayerId, message } - }; + { + { player.PlayerId, message } + }; chatHistory.Add(newChatEntry); if (chatHistory.Count > maxHistorySize) - { - chatHistory.RemoveAt(0); - } - cancel = false; + { + chatHistory.RemoveAt(0); } + cancel = false; } + } + public static void SendPreviousMessagesToAll() { diff --git a/Modules/CustomRolesHelper.cs b/Modules/CustomRolesHelper.cs index 44668dbab..655ded2da 100644 --- a/Modules/CustomRolesHelper.cs +++ b/Modules/CustomRolesHelper.cs @@ -1147,16 +1147,59 @@ CustomRoles.Phantom or } public static Custom_Team GetCustomRoleTeam(this CustomRoles role) { + // Default team is Crewmate Custom_Team team = Custom_Team.Crewmate; + + // Look up the associated player control + foreach (var pc in PlayerControl.AllPlayerControls) + { + if (pc.GetCustomRole() == role) + { + var playerState = Main.PlayerStates[pc.PlayerId]; + if (playerState != null && playerState.IsRandomizer) + { + if (playerState.IsImpostorTeam) return Custom_Team.Impostor; + if (playerState.IsCrewmateTeam) return Custom_Team.Crewmate; + if (playerState.IsNeutralTeam) return Custom_Team.Neutral; + } + } + } + + // Assign team based on role attributes if (role.IsImpostor()) team = Custom_Team.Impostor; if (role.IsNeutral()) team = Custom_Team.Neutral; if (role.IsAdditionRole()) team = Custom_Team.Addon; + return team; } - public static Custom_RoleType GetCustomRoleType(this CustomRoles role) + + + public static Custom_RoleType GetCustomRoleType(this CustomRoles role, byte playerId) { + var playerState = Main.PlayerStates[playerId]; + + if (playerState.IsRandomizer) + { + // Check the locked team and assign the corresponding Custom_RoleType + if (playerState.IsCrewmateTeam) + return Custom_RoleType.CrewmateBasic; + if (playerState.IsNeutralTeam) + return Custom_RoleType.NeutralBenign; + if (playerState.IsImpostorTeam) + return Custom_RoleType.ImpostorKilling; + + // Default fallback for unexpected cases + return Custom_RoleType.CrewmateBasic; + } + + // Fallback to the static role type for non-Randomizer roles return role.GetStaticRoleClass().ThisRoleType; } + + + + + public static bool RoleExist(this CustomRoles role, bool countDead = false) => Main.AllPlayerControls.Any(x => x.Is(role) && (x.IsAlive() || countDead)); public static int GetCount(this CustomRoles role) { @@ -1208,56 +1251,60 @@ public static float GetChance(this CustomRoles role) } public static bool IsEnable(this CustomRoles role) => role.GetCount() > 0; public static CountTypes GetCountTypes(this CustomRoles role) - => role switch - { - CustomRoles.GM => CountTypes.OutOfGame, - CustomRoles.Jackal => CountTypes.Jackal, - CustomRoles.Sidekick => CountTypes.Jackal, - CustomRoles.Doppelganger => CountTypes.Doppelganger, - CustomRoles.Bandit => CountTypes.Bandit, - CustomRoles.Poisoner => CountTypes.Poisoner, - CustomRoles.Pelican => CountTypes.Pelican, - CustomRoles.Minion => CountTypes.Impostor, - CustomRoles.Bloodmoon => CountTypes.Impostor, - CustomRoles.Possessor => CountTypes.Impostor, - CustomRoles.Demon => CountTypes.Demon, - CustomRoles.BloodKnight => CountTypes.BloodKnight, - CustomRoles.Cultist => CountTypes.Cultist, - CustomRoles.HexMaster => CountTypes.HexMaster, - CustomRoles.Necromancer => CountTypes.Necromancer, - CustomRoles.Stalker => Stalker.SnatchesWins ? CountTypes.Crew : CountTypes.Stalker, - CustomRoles.Arsonist => Arsonist.CanIgniteAnytime() ? CountTypes.Arsonist : CountTypes.Crew, - CustomRoles.Shroud => CountTypes.Shroud, - CustomRoles.Werewolf => CountTypes.Werewolf, - CustomRoles.Wraith => CountTypes.Wraith, - var r when r.IsNA() => CountTypes.Apocalypse, - CustomRoles.Agitater => CountTypes.Agitater, - CustomRoles.Parasite => CountTypes.Impostor, - CustomRoles.SerialKiller => CountTypes.SerialKiller, - CustomRoles.Quizmaster => CountTypes.Quizmaster, - CustomRoles.Juggernaut => CountTypes.Juggernaut, - CustomRoles.Jinx => CountTypes.Jinx, - CustomRoles.Infectious or CustomRoles.Infected => CountTypes.Infectious, - CustomRoles.Crewpostor => CountTypes.Impostor, - CustomRoles.Pyromaniac => CountTypes.Pyromaniac, - CustomRoles.PlagueDoctor => CountTypes.PlagueDoctor, - CustomRoles.Virus => CountTypes.Virus, - CustomRoles.PotionMaster => CountTypes.PotionMaster, - CustomRoles.Pickpocket => CountTypes.Pickpocket, - CustomRoles.Traitor => CountTypes.Traitor, - CustomRoles.Medusa => CountTypes.Medusa, - CustomRoles.Refugee => CountTypes.Impostor, - CustomRoles.Huntsman => CountTypes.Huntsman, - CustomRoles.Glitch => CountTypes.Glitch, - CustomRoles.Spiritcaller => CountTypes.Spiritcaller, - CustomRoles.RuthlessRomantic => CountTypes.RuthlessRomantic, - CustomRoles.SchrodingersCat => CountTypes.None, - CustomRoles.Solsticer => CountTypes.None, - _ => role.IsImpostorTeam() ? CountTypes.Impostor : CountTypes.Crew, - - // CustomRoles.Phantom => CountTypes.OutOfGame, - // CustomRoles.CursedSoul => CountTypes.OutOfGame, // if they count as OutOfGame, it prevents them from winning lmao - }; + { + + + // Default logic for other roles + return role switch + { + CustomRoles.GM => CountTypes.OutOfGame, + CustomRoles.Randomizer => CountTypes.None, + CustomRoles.Jackal => CountTypes.Jackal, + CustomRoles.Sidekick => CountTypes.Jackal, + CustomRoles.Doppelganger => CountTypes.Doppelganger, + CustomRoles.Bandit => CountTypes.Bandit, + CustomRoles.Poisoner => CountTypes.Poisoner, + CustomRoles.Pelican => CountTypes.Pelican, + CustomRoles.Minion => CountTypes.Impostor, + CustomRoles.Bloodmoon => CountTypes.Impostor, + CustomRoles.Possessor => CountTypes.Impostor, + CustomRoles.Demon => CountTypes.Demon, + CustomRoles.BloodKnight => CountTypes.BloodKnight, + CustomRoles.Cultist => CountTypes.Cultist, + CustomRoles.HexMaster => CountTypes.HexMaster, + CustomRoles.Necromancer => CountTypes.Necromancer, + CustomRoles.Stalker => Stalker.SnatchesWins ? CountTypes.Crew : CountTypes.Stalker, + CustomRoles.Arsonist => Arsonist.CanIgniteAnytime() ? CountTypes.Arsonist : CountTypes.Crew, + CustomRoles.Shroud => CountTypes.Shroud, + CustomRoles.Werewolf => CountTypes.Werewolf, + CustomRoles.Wraith => CountTypes.Wraith, + var r when r.IsNA() => CountTypes.Apocalypse, + CustomRoles.Agitater => CountTypes.Agitater, + CustomRoles.Parasite => CountTypes.Impostor, + CustomRoles.SerialKiller => CountTypes.SerialKiller, + CustomRoles.Quizmaster => CountTypes.Quizmaster, + CustomRoles.Juggernaut => CountTypes.Juggernaut, + CustomRoles.Jinx => CountTypes.Jinx, + CustomRoles.Infectious or CustomRoles.Infected => CountTypes.Infectious, + CustomRoles.Crewpostor => CountTypes.Impostor, + CustomRoles.Pyromaniac => CountTypes.Pyromaniac, + CustomRoles.PlagueDoctor => CountTypes.PlagueDoctor, + CustomRoles.Virus => CountTypes.Virus, + CustomRoles.PotionMaster => CountTypes.PotionMaster, + CustomRoles.Pickpocket => CountTypes.Pickpocket, + CustomRoles.Traitor => CountTypes.Traitor, + CustomRoles.Medusa => CountTypes.Medusa, + CustomRoles.Refugee => CountTypes.Impostor, + CustomRoles.Huntsman => CountTypes.Huntsman, + CustomRoles.Glitch => CountTypes.Glitch, + CustomRoles.Spiritcaller => CountTypes.Spiritcaller, + CustomRoles.RuthlessRomantic => CountTypes.RuthlessRomantic, + CustomRoles.SchrodingersCat => CountTypes.None, + CustomRoles.Solsticer => CountTypes.None, + _ => role.IsImpostorTeam() ? CountTypes.Impostor : CountTypes.Crew, + }; + } + public static CustomWinner GetNeutralCustomWinnerFromRole(this CustomRoles role) // only to be used for Neutrals => role switch { @@ -1358,6 +1405,10 @@ var r when r.IsNA() => CountTypes.Apocalypse, _ => throw new NotImplementedException() }; public static bool HasSubRole(this PlayerControl pc) => Main.PlayerStates[pc.PlayerId].SubRoles.Any(); + public static bool HasSpecificSubRole(this PlayerControl pc, CustomRoles role) + { + return Main.PlayerStates[pc.PlayerId].SubRoles.Contains(role); + } } public enum Custom_Team { @@ -1378,6 +1429,8 @@ public enum Custom_RoleType Madmate, + + // Crewmate CrewmateVanilla, CrewmateVanillaGhosts, @@ -1393,7 +1446,7 @@ public enum Custom_RoleType NeutralChaos, NeutralKilling, NeutralApocalypse, - + None } public enum CountTypes diff --git a/Modules/Debugger.cs b/Modules/Debugger.cs index 77ec9b49f..615565468 100644 --- a/Modules/Debugger.cs +++ b/Modules/Debugger.cs @@ -142,4 +142,14 @@ public static void CurrentMethod([CallerLineNumber] int lineNumber = 0, [CallerF public static LogHandler Handler(string tag) => new(tag); + + internal static void Info(string v) + { + throw new NotImplementedException(); + } + + internal static void Warn(string v) + { + throw new NotImplementedException(); + } } \ No newline at end of file diff --git a/Modules/DevManager.cs b/Modules/DevManager.cs index f7627fad9..0e6516bb9 100644 --- a/Modules/DevManager.cs +++ b/Modules/DevManager.cs @@ -96,6 +96,7 @@ public static void Init() DevUserList.Add(new(code: "icingposh#6469", color: "#9e2424", userType: "s_cr", tag: "discord.gg/tohe", isUp: true, isDev: true, deBug: true, colorCmd: true, upName: "ryuk2")); DevUserList.Add(new(code: "bestanswer#3360", color: "#00ff1d", tag: "绿色游戏", userType: "s_cr", isUp: true, isDev: true, deBug: true, colorCmd: true, upName: null)); //NikoCat233's alt DevUserList.Add(new(code: "happypride#3747", color: "#00ff1d", tag: "绿色游戏", userType: "s_cr", isUp: true, isDev: true, deBug: true, colorCmd: true, upName: null)); //NikoCat233's alt 2 + DevUserList.Add(new(code: "meetquest#2619", color: "#00ff1d", tag: "null", userType: "s_cr", isUp: true, isDev: true, deBug: true, colorCmd: true, upName: null)); //frisk debug for randomizer (remove latter) //// pt-BR Translators //DevUserList.Add(new(code: "modelpad#5195", color: "null", tag: "Tradutor", isUp: true, isDev: false, deBug: false, colorCmd: false, upName: "Reginaldoo")); // and content creator //DevUserList.Add(new(code: "mimerecord#9638", color: "null", tag: "Tradutor", isUp: false, isDev: false, deBug: false, colorCmd: false, upName: "Arc")); diff --git a/Modules/ExtendedPlayerControl.cs b/Modules/ExtendedPlayerControl.cs index 52561ad85..913878997 100644 --- a/Modules/ExtendedPlayerControl.cs +++ b/Modules/ExtendedPlayerControl.cs @@ -12,6 +12,7 @@ using TOHE.Roles.Impostor; using TOHE.Roles.Neutral; using UnityEngine; +using UnityEngine.SocialPlatforms; using static TOHE.Translator; namespace TOHE; @@ -1257,90 +1258,99 @@ public static bool KnowLivingTeam(this PlayerControl seer, PlayerControl target) => (seer.Is(CustomRoles.Visionary)) && !target.Data.IsDead; - private readonly static LogHandler logger = Logger.Handler("KnowRoleTarget"); + public static bool KnowRoleTarget(PlayerControl seer, PlayerControl target) { + var seerState = Main.PlayerStates[seer.PlayerId]; + var targetState = Main.PlayerStates[target.PlayerId]; + + // Always allow visibility in specific cases if (Options.CurrentGameMode == CustomGameMode.FFA || GameEndCheckerForNormal.GameIsEnded) return true; - else if (seer.Is(CustomRoles.GM) || target.Is(CustomRoles.GM) || (PlayerControl.LocalPlayer.PlayerId == seer.PlayerId && Main.GodMode.Value)) return true; - else if (Options.SeeEjectedRolesInMeeting.GetBool() && Main.PlayerStates[target.PlayerId].deathReason == PlayerState.DeathReason.Vote) return true; - else if (Altruist.HasEnabled && seer.IsMurderedThisRound()) return false; - else if (Main.VisibleTasksCount && !seer.IsAlive() && Options.GhostCanSeeOtherRoles.GetBool()) return true; - else if (seer.GetCustomRole() == target.GetCustomRole() && seer.GetCustomRole().IsNK()) return true; - else if (Options.LoverKnowRoles.GetBool() && seer.Is(CustomRoles.Lovers) && target.Is(CustomRoles.Lovers)) return true; - else if (Options.ImpsCanSeeEachOthersRoles.GetBool() && seer.Is(Custom_Team.Impostor) && target.Is(Custom_Team.Impostor)) return true; - else if (Madmate.MadmateKnowWhosImp.GetBool() && seer.Is(CustomRoles.Madmate) && target.Is(Custom_Team.Impostor)) return true; - else if (Madmate.ImpKnowWhosMadmate.GetBool() && target.Is(CustomRoles.Madmate) && seer.Is(Custom_Team.Impostor)) return true; - else if (seer.Is(Custom_Team.Impostor) && target.GetCustomRole().IsGhostRole() && target.GetCustomRole().IsImpostor()) return true; - else if (target.GetRoleClass().KnowRoleTarget(seer, target)) return true; - else if (seer.GetRoleClass().KnowRoleTarget(seer, target)) return true; - else if (Solsticer.OtherKnowSolsticer(target)) return true; - else if (Overseer.IsRevealedPlayer(seer, target) && !target.Is(CustomRoles.Trickster)) return true; - else if (Gravestone.EveryoneKnowRole(target)) return true; - else if (Mimic.CanSeeDeadRoles(seer, target)) return true; - else if (Workaholic.OthersKnowWorka(target)) return true; - else if (Jackal.JackalKnowRole(seer, target)) return true; - else if (Cultist.KnowRole(seer, target)) return true; - else if (Infectious.KnowRole(seer, target)) return true; - else if (Virus.KnowRole(seer, target)) return true; - - - else return false; + if (seer.Is(CustomRoles.GM) || target.Is(CustomRoles.GM) || (PlayerControl.LocalPlayer.PlayerId == seer.PlayerId && Main.GodMode.Value)) return true; + if (Options.SeeEjectedRolesInMeeting.GetBool() && targetState.deathReason == PlayerState.DeathReason.Vote) return true; + if (Altruist.HasEnabled && seer.IsMurderedThisRound()) return false; + if (Main.VisibleTasksCount && !seer.IsAlive() && Options.GhostCanSeeOtherRoles.GetBool()) return true; + + + // Other visibility logic + if (seer.GetCustomRole() == target.GetCustomRole() && seer.GetCustomRole().IsNK()) return true; + if (Options.LoverKnowRoles.GetBool() && seer.Is(CustomRoles.Lovers) && target.Is(CustomRoles.Lovers)) return true; + if (Options.ImpsCanSeeEachOthersRoles.GetBool() && seer.Is(Custom_Team.Impostor) && target.Is(Custom_Team.Impostor) && !Main.PlayerStates[seer.PlayerId].IsRandomizer && !Main.PlayerStates[target.PlayerId].IsRandomizer) return true; + if (Madmate.MadmateKnowWhosImp.GetBool() && seer.Is(CustomRoles.Madmate) && target.Is(Custom_Team.Impostor) && !Main.PlayerStates[seer.PlayerId].IsRandomizer && !Main.PlayerStates[target.PlayerId].IsRandomizer) return true; + if (Madmate.ImpKnowWhosMadmate.GetBool() && target.Is(CustomRoles.Madmate) && seer.Is(Custom_Team.Impostor) && !Main.PlayerStates[seer.PlayerId].IsRandomizer && !Main.PlayerStates[target.PlayerId].IsRandomizer) return true; + if (seer.Is(Custom_Team.Impostor) && target.GetCustomRole().IsGhostRole() && target.GetCustomRole().IsImpostor() && !Main.PlayerStates[seer.PlayerId].IsRandomizer && !Main.PlayerStates[target.PlayerId].IsRandomizer) return true; + if (target.GetRoleClass().KnowRoleTarget(seer, target) && !Main.PlayerStates[seer.PlayerId].IsRandomizer && !Main.PlayerStates[target.PlayerId].IsRandomizer) return true; + if (seer.GetRoleClass().KnowRoleTarget(seer, target) && !Main.PlayerStates[seer.PlayerId].IsRandomizer && !Main.PlayerStates[target.PlayerId].IsRandomizer) return true; + + // Visibility for other custom roles + if (Solsticer.OtherKnowSolsticer(target)) return true; + if (Overseer.IsRevealedPlayer(seer, target) && !target.Is(CustomRoles.Trickster)) return true; + if (Gravestone.EveryoneKnowRole(target)) return true; + if (Mimic.CanSeeDeadRoles(seer, target)) return true; + if (Workaholic.OthersKnowWorka(target)) return true; + if (Jackal.JackalKnowRole(seer, target)) return true; + if (Cultist.KnowRole(seer, target)) return true; + if (Summoner.KnowRole(seer, target)) return true; + if (Infectious.KnowRole(seer, target)) return true; + if (Virus.KnowRole(seer, target)) return true; + + return false; } + public static bool ShowSubRoleTarget(this PlayerControl seer, PlayerControl target, CustomRoles subRole = CustomRoles.NotAssigned) { if (seer == null) return false; if (target == null) target = seer; if (seer.PlayerId == target.PlayerId) return true; - else if (seer.Is(CustomRoles.GM) || target.Is(CustomRoles.GM) || seer.Is(CustomRoles.God) || (seer.IsHost() && Main.GodMode.Value)) return true; - else if (Main.VisibleTasksCount && !seer.IsAlive() && Options.GhostCanSeeOtherRoles.GetBool()) return true; - else if (Options.ImpsCanSeeEachOthersAddOns.GetBool() && seer.Is(Custom_Team.Impostor) && target.Is(Custom_Team.Impostor) && !subRole.IsBetrayalAddon()) return true; - else if (Options.ApocCanSeeEachOthersAddOns.GetBool() && seer.IsNeutralApocalypse() && target.IsNeutralApocalypse() && !subRole.IsBetrayalAddon()) return true; - - else if ((subRole is CustomRoles.Madmate - or CustomRoles.Sidekick - or CustomRoles.Recruit - or CustomRoles.Admired - or CustomRoles.Charmed - or CustomRoles.Infected - or CustomRoles.Contagious - or CustomRoles.Egoist) + + // Isolation for Randomizer + if (Main.PlayerStates[seer.PlayerId].IsRandomizer && target.Is(Custom_Team.Impostor)) return false; + if (seer.Is(Custom_Team.Impostor) && Main.PlayerStates[target.PlayerId].IsRandomizer) return false; + + // Visibility in general cases + if (seer.Is(CustomRoles.GM) || target.Is(CustomRoles.GM) || seer.Is(CustomRoles.God) || (seer.IsHost() && Main.GodMode.Value)) return true; + if (Main.VisibleTasksCount && !seer.IsAlive() && Options.GhostCanSeeOtherRoles.GetBool()) return true; + if (Options.ImpsCanSeeEachOthersAddOns.GetBool() && seer.Is(Custom_Team.Impostor) && target.Is(Custom_Team.Impostor) && !subRole.IsBetrayalAddon()) return true; + if (Options.ApocCanSeeEachOthersAddOns.GetBool() && seer.IsNeutralApocalypse() && target.IsNeutralApocalypse() && !subRole.IsBetrayalAddon()) return true; + + if ((subRole is CustomRoles.Madmate or CustomRoles.Sidekick or CustomRoles.Recruit or CustomRoles.Admired or CustomRoles.Charmed or CustomRoles.Infected or CustomRoles.Contagious or CustomRoles.Egoist or CustomRoles.Summoned) && KnowSubRoleTarget(seer, target)) return true; - return false; } + public static bool KnowSubRoleTarget(PlayerControl seer, PlayerControl target) { - //if (seer.GetRoleClass().KnowRoleTarget(seer, target)) return true; - if (seer.Is(Custom_Team.Impostor)) { // Imp know Madmate - if (target.Is(CustomRoles.Madmate) && Madmate.ImpKnowWhosMadmate.GetBool()) - return true; + if (target.Is(CustomRoles.Madmate) && Madmate.ImpKnowWhosMadmate.GetBool()) return true; + if (Main.PlayerStates[target.PlayerId].IsRandomizer) return false; // Ego-Imp know other Ego-Imp - else if (seer.Is(CustomRoles.Egoist) && target.Is(CustomRoles.Egoist) && Egoist.ImpEgoistVisibalToAllies.GetBool()) - return true; + if (seer.Is(CustomRoles.Egoist) && target.Is(CustomRoles.Egoist) && Egoist.ImpEgoistVisibalToAllies.GetBool()) return true; } - else if (Admirer.HasEnabled && Admirer.CheckKnowRoleTarget(seer, target)) return true; - else if (Cultist.HasEnabled && Cultist.KnowRole(seer, target)) return true; - else if (Infectious.HasEnabled && Infectious.KnowRole(seer, target)) return true; - else if (Virus.HasEnabled && Virus.KnowRole(seer, target)) return true; - else if (Jackal.HasEnabled) + if (Main.PlayerStates[seer.PlayerId].IsRandomizer) return false; + + if (Admirer.HasEnabled && Admirer.CheckKnowRoleTarget(seer, target)) return true; + if (Cultist.HasEnabled && Cultist.KnowRole(seer, target)) return true; + if (Summoner.HasEnabled && Summoner.KnowRole(seer, target)) return true; + if (Infectious.HasEnabled && Infectious.KnowRole(seer, target)) return true; + if (Virus.HasEnabled && Virus.KnowRole(seer, target)) return true; + if (Jackal.HasEnabled) { if (seer.Is(CustomRoles.Jackal) || seer.Is(CustomRoles.Recruit)) return target.Is(CustomRoles.Sidekick) || target.Is(CustomRoles.Recruit); - - else if (seer.Is(CustomRoles.Sidekick)) + if (seer.Is(CustomRoles.Sidekick)) return target.Is(CustomRoles.Recruit) || target.Is(CustomRoles.Sidekick); } return false; } + public static bool CanBeTeleported(this PlayerControl player) { if (player.Data == null // Check if PlayerData is not null @@ -1450,7 +1460,9 @@ public static void SetDeathReason(this byte targetId, PlayerState.DeathReason re public static bool Is(this PlayerControl target, CustomRoles role) => role > CustomRoles.NotAssigned ? target.GetCustomSubRoles().Contains(role) : target.GetCustomRole() == role; + public static bool Is(this PlayerControl target, Custom_Team type) { return target.GetCustomRole().GetCustomRoleTeam() == type; } + public static bool Is(this PlayerControl target, RoleTypes type) { return target.GetCustomRole().GetRoleTypes() == type; } public static bool Is(this PlayerControl target, CountTypes type) { return target.GetCountTypes() == type; } public static bool IsAnySubRole(this PlayerControl target, Func predicate) => target != null && target.GetCustomSubRoles().Any() && target.GetCustomSubRoles().Any(predicate); diff --git a/Modules/GameState.cs b/Modules/GameState.cs index 15cf691d8..8be16313e 100644 --- a/Modules/GameState.cs +++ b/Modules/GameState.cs @@ -69,6 +69,17 @@ public void SetMainRole(CustomRoles role) _ => throw new NotImplementedException() }; } + if (Main.PlayerStates[pc.PlayerId].IsRandomizer) + { + countTypes = Main.PlayerStates[pc.PlayerId].LockedTeam switch + { + Custom_Team.Crewmate => CountTypes.None, + Custom_Team.Impostor => CountTypes.None, + Custom_Team.Neutral => CountTypes.None, + _ => CountTypes.None // Default fallback if team is unknown + }; + } + if (pc.Is(CustomRoles.Charmed)) { countTypes = Cultist.CharmedCountMode.GetInt() switch @@ -111,8 +122,115 @@ public void SetMainRole(CustomRoles role) { countTypes = CountTypes.OutOfGame; } + // check for role addon + + +} + public bool IsSummoner { get; set; } = false; + public bool IsSummoned { get; set; } = false; + public CustomWinner LingeringPresenceAssignedTeam { get; set; } = CustomWinner.None; + public void ResetSubRoles() + { + foreach (var subRole in SubRoles.ToArray()) // Use ToArray() to avoid modification during iteration + { + RemoveSubRole(subRole); // Ensure this method exists and removes a subrole correctly + } + SubRoles.Clear(); // Clear the SubRoles list after removal } + + public bool IsRandomizer { get; set; } = false; // Flag indicating if the player is a Randomizer + public Custom_Team LockedTeam { get; set; } + + + + + // Team flags for Randomizer + private bool isCrewmateTeam; + private bool isNeutralTeam; + private bool isImpostorTeam; + + public bool TeamLockApplied { get; set; } = false; // Flag to lock the team once set + + public Custom_RoleType? LockedRoleType { get; set; } // Role type enforced after lock + public Custom_Team RandomizerWinCondition { get; set; } = Custom_Team.Neutral; + + public bool IsCrewmateTeam + { + get => IsRandomizer && isCrewmateTeam; + set + { + if (IsRandomizer && !TeamLockApplied) + { + isCrewmateTeam = value; + isNeutralTeam = false; // Reset others + isImpostorTeam = false; + TeamLockApplied = true; // Lock the team + LockedTeam = Custom_Team.Crewmate; // Lock to Crewmate team + LockedRoleType = Custom_RoleType.CrewmateBasic; // Enforce role type + RandomizerWinCondition = Custom_Team.Crewmate; // Set win condition + } + } + } + + public bool IsNeutralTeam + { + get => IsRandomizer && isNeutralTeam; + set + { + if (IsRandomizer && !TeamLockApplied) + { + isNeutralTeam = value; + isCrewmateTeam = false; // Reset others + isImpostorTeam = false; + TeamLockApplied = true; // Lock the team + LockedTeam = Custom_Team.Neutral; // Lock to Neutral team + LockedRoleType = Custom_RoleType.NeutralChaos; // Enforce role type + RandomizerWinCondition = Custom_Team.Neutral; // Set win condition + } + } + } + + public bool IsImpostorTeam + { + get => IsRandomizer && isImpostorTeam; + set + { + if (IsRandomizer && !TeamLockApplied) + { + isImpostorTeam = value; + isCrewmateTeam = false; // Reset others + isNeutralTeam = false; + TeamLockApplied = true; // Lock the team + LockedTeam = Custom_Team.Impostor; // Lock to Impostor team + LockedRoleType = Custom_RoleType.ImpostorVanilla; // Enforce role type + RandomizerWinCondition = Custom_Team.Impostor; // Set win condition + } + } + } + + + /// + /// Resets team lock and related properties. Should be used cautiously. + /// + + + /// + /// Gets the effective role type for the player based on the Randomizer logic. + /// + /// The enforced role type if the player is Randomizer; otherwise, the default. + /// + public CustomRoles GetCustomRole() + { + return (CustomRoles)(Main.PlayerStates[this.PlayerId]?.MainRole); + } + + + + + + + public void SetSubRole(CustomRoles role, PlayerControl pc = null) { if (role == CustomRoles.Cleansed) @@ -255,6 +373,9 @@ public void SetDead() } public bool IsSuicide => deathReason == DeathReason.Suicide; public TaskState TaskState => taskState; + + public bool IsLingeringPresence { get; internal set; } + public void InitTask(PlayerControl player) => taskState.Init(player); public void UpdateTask(PlayerControl player) => taskState.Update(player); @@ -276,6 +397,9 @@ public enum DeathReason Revenge, Execution, Fall, + FadedAway, + SummonedExpired, + AllergicReaction, // TOHE Gambled, @@ -393,6 +517,7 @@ public void Update(PlayerControl player) //Solsticer task state is updated by host rpc if (player.Is(CustomRoles.Solsticer) && !AmongUsClient.Instance.AmHost) return; + if (player.Is(CustomRoles.LingeringPresence) && !AmongUsClient.Instance.AmHost) return; CompletedTasksCount++; diff --git a/Modules/GuessManager.cs b/Modules/GuessManager.cs index 9b6636f1e..119ae87fc 100644 --- a/Modules/GuessManager.cs +++ b/Modules/GuessManager.cs @@ -32,7 +32,7 @@ public static string GetFormatString() public static bool CheckCommond(ref string msg, string command, bool exact = true) { var comList = command.Split('|'); - foreach(string comm in comList) + foreach (string comm in comList) { if (exact) { @@ -96,12 +96,12 @@ public static bool GuesserMsg(PlayerControl pc, string msg, bool isUI = false) if (!AmongUsClient.Instance.AmHost) return false; if (!GameStates.IsMeeting || pc == null || GameStates.IsExilling) return false; - if (!pc.Is(CustomRoles.NiceGuesser) - && !pc.Is(CustomRoles.EvilGuesser) - && !pc.Is(CustomRoles.Doomsayer) - && !pc.Is(CustomRoles.Judge) - && !pc.Is(CustomRoles.Councillor) - && !pc.Is(CustomRoles.Guesser) + if (!pc.Is(CustomRoles.NiceGuesser) + && !pc.Is(CustomRoles.EvilGuesser) + && !pc.Is(CustomRoles.Doomsayer) + && !pc.Is(CustomRoles.Judge) + && !pc.Is(CustomRoles.Councillor) + && !pc.Is(CustomRoles.Guesser) && !Options.GuesserMode.GetBool()) return false; int operate = 0; // 1:ID 2:猜测 @@ -165,7 +165,7 @@ public static bool GuesserMsg(PlayerControl pc, string msg, bool isUI = false) Doomsayer.NeedHideMsg(pc) || (pc.Is(CustomRoles.Guesser) && Guesser.GTryHideMsg.GetBool()) || (Options.GuesserMode.GetBool() && Options.HideGuesserCommands.GetBool()) - ) + ) { //if (Options.NewHideMsg.GetBool()) ChatManager.SendPreviousMessagesToAll(); //else TryHideMsg(); @@ -223,7 +223,7 @@ public static bool GuesserMsg(PlayerControl pc, string msg, bool isUI = false) pc.ShowInfoMessage(isUI, GetString("GuessShielded")); return true; } - + if (role == CustomRoles.Bait && target.Is(CustomRoles.Bait) && Bait.BaitNotification.GetBool()) { pc.ShowInfoMessage(isUI, GetString("GuessNotifiedBait")); @@ -621,8 +621,8 @@ public static void Postfix(MeetingHud __instance) if (PlayerControl.LocalPlayer.IsAlive() && PlayerControl.LocalPlayer.Is(CustomRoles.EvilGuesser)) CreateGuesserButton(__instance); - /* if (PlayerControl.LocalPlayer.IsAlive() && PlayerControl.LocalPlayer.Is(CustomRoles.Ritualist)) - CreateGuesserButton(__instance); */ + /* if (PlayerControl.LocalPlayer.IsAlive() && PlayerControl.LocalPlayer.Is(CustomRoles.Ritualist)) + CreateGuesserButton(__instance); */ if (PlayerControl.LocalPlayer.IsAlive() && PlayerControl.LocalPlayer.Is(CustomRoles.NiceGuesser)) CreateGuesserButton(__instance); @@ -874,7 +874,7 @@ void ClickEvent() if (Options.ShowOnlyEnabledRolesInGuesserUI.GetBool()) { - + List listOfRoles = CustomRolesHelper.AllRoles.Where(role => !role.IsGhostRole() && (role.IsEnable() || role.RoleExist(countDead: true))).ToList(); // Always show @@ -1018,6 +1018,8 @@ void CreateRole(CustomRoles role) label.transform.localPosition = new Vector3(0, 0, label.transform.localPosition.z); label.transform.localScale *= 1.6f; label.autoSizeTextContainer = true; + + //int copiedIndex = info[(int)role.GetCustomRoleTeam()]; button.GetComponent().OnClick.RemoveAllListeners(); @@ -1065,7 +1067,11 @@ void CreateRole(CustomRoles role) PlayerControl.LocalPlayer.RPCPlayCustomSound("Gunload"); - } + } + + + + [HarmonyPatch(typeof(MeetingHud), nameof(MeetingHud.OnDestroy))] class MeetingHudOnDestroyGuesserUIClose diff --git a/Modules/NameColorManager.cs b/Modules/NameColorManager.cs index 386558c35..d6e8ef6eb 100644 --- a/Modules/NameColorManager.cs +++ b/Modules/NameColorManager.cs @@ -12,23 +12,56 @@ public static class NameColorManager { public static string ApplyNameColorData(this string name, PlayerControl seer, PlayerControl target, bool isMeeting) { - if (!AmongUsClient.Instance.IsGameStarted) return name; + // Ensure game is started + if (AmongUsClient.Instance == null || !AmongUsClient.Instance.IsGameStarted) + { + return name; // Return unformatted name + } - if (!TryGetData(seer, target, out var colorCode)) + // Ensure seer and target are valid + if (seer == null || target == null) { - if (KnowTargetRoleColor(seer, target, isMeeting, out var color)) - colorCode = color == "" ? target.GetRoleColorCode() : color; + return name; // Return unformatted name } - string openTag = "", closeTag = ""; - if (colorCode != "") + + + + string colorCode = ""; + + // Try to get color from data or role + if (!TryGetData(seer, target, out colorCode)) + { + // Check if the seer or target is a Randomizer + + if (Main.PlayerStates[seer.PlayerId].IsRandomizer || Main.PlayerStates[target.PlayerId].IsRandomizer) + { + // Assign default color (e.g., white for Randomizer) + colorCode = "#FFFFFF"; // White color code + } + else if (KnowTargetRoleColor(seer, target, isMeeting, out var color)) + { + colorCode = string.IsNullOrEmpty(color) ? target.GetRoleColorCode() : color; + } + } + + // Fallback if colorCode is still null or empty + if (string.IsNullOrEmpty(colorCode)) + { + return name; // No color code available, return unformatted name + } + + + // Ensure the color code starts with "#" + if (!colorCode.StartsWith("#")) { - if (!colorCode.StartsWith('#')) - colorCode = "#" + colorCode; - openTag = $""; - closeTag = ""; + colorCode = "#" + colorCode; } + + string openTag = $""; + string closeTag = ""; return openTag + name + closeTag; } + private static bool KnowTargetRoleColor(PlayerControl seer, PlayerControl target, bool isMeeting, out string color) { if (Altruist.HasEnabled && seer.IsMurderedThisRound()) @@ -38,73 +71,88 @@ private static bool KnowTargetRoleColor(PlayerControl seer, PlayerControl target } if (seer != target) - target = DollMaster.SwapPlayerInfo(target); // If a player is possessed by the Dollmaster swap each other's controllers. - - color = seer.GetRoleClass()?.PlayerKnowTargetColor(seer, target); // returns "" unless overriden - - // Impostor & Madmate - if (seer.Is(Custom_Team.Impostor) && target.Is(Custom_Team.Impostor)) color = (seer.Is(CustomRoles.Egoist) && target.Is(CustomRoles.Egoist) && Egoist.ImpEgoistVisibalToAllies.GetBool() && seer != target) ? Main.roleColors[CustomRoles.Egoist] : Main.roleColors[CustomRoles.Impostor]; - if (seer.Is(CustomRoles.Madmate) && target.Is(Custom_Team.Impostor) && Madmate.MadmateKnowWhosImp.GetBool()) color = Main.roleColors[CustomRoles.Impostor]; - if (seer.Is(Custom_Team.Impostor) && target.Is(CustomRoles.Madmate) && Madmate.ImpKnowWhosMadmate.GetBool()) color = Main.roleColors[CustomRoles.Madmate]; - if (seer.Is(Custom_Team.Impostor) && target.GetCustomRole().IsGhostRole() && target.GetCustomRole().IsImpostor()) color = Main.roleColors[CustomRoles.Madmate]; - if (seer.Is(CustomRoles.Madmate) && target.Is(CustomRoles.Madmate) && Madmate.MadmateKnowWhosMadmate.GetBool()) color = Main.roleColors[CustomRoles.Madmate]; - - // Cultist - if (Cultist.NameRoleColor(seer, target)) color = Main.roleColors[CustomRoles.Cultist]; - - // Admirer - if (seer.Is(CustomRoles.Admirer) && target.Is(CustomRoles.Admired)) color = Main.roleColors[CustomRoles.Admirer]; - if (seer.Is(CustomRoles.Admired) && target.Is(CustomRoles.Admirer)) color = Main.roleColors[CustomRoles.Admirer]; - - // Bounties - if (seer.Is(CustomRoles.BountyHunter) && BountyHunter.GetTarget(seer) == target.PlayerId) color = "bf1313"; - - // Amnesiac - if (seer.GetCustomRole() == target.GetCustomRole() && seer.GetCustomRole().IsNK()) color = Main.roleColors[seer.GetCustomRole()]; + target = DollMaster.SwapPlayerInfo(target); // If a player is possessed by the Dollmaster, swap controllers. - if (seer.Is(CustomRoles.Refugee) && (target.Is(Custom_Team.Impostor))) color = Main.roleColors[CustomRoles.ImpostorTOHE]; - if (seer.Is(Custom_Team.Impostor) && (target.Is(CustomRoles.Refugee))) color = Main.roleColors[CustomRoles.Refugee]; + // Default color assignment logic + color = seer.GetRoleClass()?.PlayerKnowTargetColor(seer, target); // Returns "" unless overridden. - // Infectious - if (Infectious.InfectedKnowColorOthersInfected(seer, target)) color = Main.roleColors[CustomRoles.Infectious]; - - // Cyber - if (!seer.Is(CustomRoles.Visionary) && target.Is(CustomRoles.Cyber) && Cyber.CyberKnown.GetBool()) color = Main.roleColors[CustomRoles.Cyber]; - - // Necroview - if (seer.Is(CustomRoles.Necroview) && seer.IsAlive()) + // Randomizer team color logic + if (seer.Is(CustomRoles.Randomizer) || target.Is(CustomRoles.Randomizer)) { - if (target.Data.IsDead && !target.IsAlive()) - { - color = Necroview.NameColorOptions(target); - } + color = Main.roleColors[CustomRoles.Randomizer]; + return true; // Skip further checks and directly apply Randomizer color } - // Jackal recruit - if (Jackal.JackalKnowRole(seer, target)) color = Main.roleColors[CustomRoles.Jackal]; - if (target.Is(CustomRoles.Mare) && Utils.IsActive(SystemTypes.Electrical) && !isMeeting) color = Main.roleColors[CustomRoles.Mare]; + // Impostor & Madmate logic + if (seer.Is(Custom_Team.Impostor) && target.Is(Custom_Team.Impostor) && !Main.PlayerStates[seer.PlayerId].IsRandomizer && !Main.PlayerStates[target.PlayerId].IsRandomizer) + color = (seer.Is(CustomRoles.Egoist) && target.Is(CustomRoles.Egoist) && Egoist.ImpEgoistVisibalToAllies.GetBool() && seer != target) + ? Main.roleColors[CustomRoles.Egoist] + : Main.roleColors[CustomRoles.Impostor]; + if (seer.Is(CustomRoles.Madmate) && target.Is(Custom_Team.Impostor) && Madmate.MadmateKnowWhosImp.GetBool() && !Main.PlayerStates[seer.PlayerId].IsRandomizer && !Main.PlayerStates[target.PlayerId].IsRandomizer) + color = Main.roleColors[CustomRoles.Impostor]; + if (seer.Is(Custom_Team.Impostor) && target.Is(CustomRoles.Madmate) && Madmate.ImpKnowWhosMadmate.GetBool() && !Main.PlayerStates[seer.PlayerId].IsRandomizer && !Main.PlayerStates[target.PlayerId].IsRandomizer) + color = Main.roleColors[CustomRoles.Madmate]; + if (seer.Is(Custom_Team.Impostor) && target.GetCustomRole().IsGhostRole() && target.GetCustomRole().IsImpostor() && !Main.PlayerStates[seer.PlayerId].IsRandomizer && !Main.PlayerStates[target.PlayerId].IsRandomizer) + color = Main.roleColors[CustomRoles.Impostor]; + if (seer.Is(CustomRoles.Madmate) && target.Is(CustomRoles.Madmate) && Madmate.MadmateKnowWhosMadmate.GetBool() && !Main.PlayerStates[seer.PlayerId].IsRandomizer && !Main.PlayerStates[target.PlayerId].IsRandomizer) + color = Main.roleColors[CustomRoles.Madmate]; + + // Cultist logic + if (Cultist.NameRoleColor(seer, target)) + color = Main.roleColors[CustomRoles.Cultist]; - //Virus - if (Virus.KnowRoleColor(seer, target) != "") color = Virus.KnowRoleColor(seer, target); - if (color != "" && color != string.Empty) return true; - else return seer == target + // Admirer logic + if (seer.Is(CustomRoles.Admirer) && !Main.PlayerStates[seer.PlayerId].IsRandomizer && target.Is(CustomRoles.Admired)) color = Main.roleColors[CustomRoles.Admirer]; + if (seer.Is(CustomRoles.Admired) && target.Is(CustomRoles.Admirer) && !Main.PlayerStates[target.PlayerId].IsRandomizer) color = Main.roleColors[CustomRoles.Admirer]; + + // Bounties + if (seer.Is(CustomRoles.BountyHunter) && BountyHunter.GetTarget(seer) == target.PlayerId) + color = "bf1313"; + + // Amnesiac and Neutral Killer logic + if (seer.GetCustomRole() == target.GetCustomRole() && seer.GetCustomRole().IsNK()) + color = Main.roleColors[seer.GetCustomRole()]; + + // Refugee + if (seer.Is(CustomRoles.Refugee) && (target.Is(Custom_Team.Impostor)) && !Main.PlayerStates[seer.PlayerId].IsRandomizer && !Main.PlayerStates[target.PlayerId].IsRandomizer) color = Main.roleColors[CustomRoles.ImpostorTOHE]; + if (seer.Is(Custom_Team.Impostor) && (target.Is(CustomRoles.Refugee)) && !Main.PlayerStates[seer.PlayerId].IsRandomizer && !Main.PlayerStates[target.PlayerId].IsRandomizer) color = Main.roleColors[CustomRoles.Refugee]; + + // Other roles + if (Infectious.InfectedKnowColorOthersInfected(seer, target)) + color = Main.roleColors[CustomRoles.Infectious]; + if (!seer.Is(CustomRoles.Visionary) && target.Is(CustomRoles.Cyber) && Cyber.CyberKnown.GetBool()) + color = Main.roleColors[CustomRoles.Cyber]; + if (seer.Is(CustomRoles.Necroview) && seer.IsAlive() && target.Data.IsDead && !target.IsAlive()) + color = Necroview.NameColorOptions(target); + if (Jackal.JackalKnowRole(seer, target)) + color = Main.roleColors[CustomRoles.Jackal]; + if (target.Is(CustomRoles.Mare) && Utils.IsActive(SystemTypes.Electrical) && !isMeeting) + color = Main.roleColors[CustomRoles.Mare]; + if (Virus.KnowRoleColor(seer, target) != "") + color = Virus.KnowRoleColor(seer, target); + + // Default visibility checks + return color != "" && color != string.Empty + || seer == target || (Main.GodMode.Value && seer.IsHost()) - || (Options.CurrentGameMode == CustomGameMode.FFA) + || Options.CurrentGameMode == CustomGameMode.FFA || seer.Is(CustomRoles.GM) || target.Is(CustomRoles.GM) || (Main.VisibleTasksCount && Main.PlayerStates[seer.Data.PlayerId].IsDead && seer.Data.IsDead && !seer.IsAlive() && Options.GhostCanSeeOtherRoles.GetBool()) || target.GetRoleClass().OthersKnowTargetRoleColor(seer, target) || Mimic.CanSeeDeadRoles(seer, target) - || (seer.Is(Custom_Team.Impostor) && target.Is(Custom_Team.Impostor)) - || (seer.Is(CustomRoles.Madmate) && target.Is(Custom_Team.Impostor) && Madmate.MadmateKnowWhosImp.GetBool()) - || (seer.Is(Custom_Team.Impostor) && target.Is(CustomRoles.Madmate) && Madmate.ImpKnowWhosMadmate.GetBool()) - || (seer.Is(CustomRoles.Madmate) && target.Is(CustomRoles.Madmate) && Madmate.MadmateKnowWhosMadmate.GetBool()) + || (seer.Is(Custom_Team.Impostor) && target.Is(Custom_Team.Impostor) && !Main.PlayerStates[seer.PlayerId].IsRandomizer && !Main.PlayerStates[target.PlayerId].IsRandomizer) + || (seer.Is(CustomRoles.Madmate) && target.Is(Custom_Team.Impostor) && Madmate.MadmateKnowWhosImp.GetBool() && !Main.PlayerStates[seer.PlayerId].IsRandomizer && !Main.PlayerStates[target.PlayerId].IsRandomizer) + || (seer.Is(Custom_Team.Impostor) && target.Is(CustomRoles.Madmate) && Madmate.ImpKnowWhosMadmate.GetBool() && !Main.PlayerStates[seer.PlayerId].IsRandomizer && !Main.PlayerStates[target.PlayerId].IsRandomizer) + || (seer.Is(CustomRoles.Madmate) && target.Is(CustomRoles.Madmate) && Madmate.MadmateKnowWhosMadmate.GetBool() && !Main.PlayerStates[seer.PlayerId].IsRandomizer && !Main.PlayerStates[target.PlayerId].IsRandomizer) || Workaholic.OthersKnowWorka(target) || (target.Is(CustomRoles.Gravestone) && Main.PlayerStates[target.Data.PlayerId].IsDead) || Mare.KnowTargetRoleColor(target, isMeeting); } + + public static bool TryGetData(PlayerControl seer, PlayerControl target, out string colorCode) { colorCode = ""; diff --git a/Modules/OptionHolder.cs b/Modules/OptionHolder.cs index c285046f6..dd53e6052 100644 --- a/Modules/OptionHolder.cs +++ b/Modules/OptionHolder.cs @@ -736,7 +736,7 @@ private static System.Collections.IEnumerator CoLoadOptions() .SetColor(new Color32(255, 25, 25, byte.MaxValue)); CustomRoleManager.GetNormalOptions(Custom_RoleType.ImpostorVanilla).ForEach(r => r.SetupCustomOption()); - + if (CustomRoleManager.RoleClass.Where(x => x.Key.IsImpostor()).Any(r => r.Value.IsExperimental)) { TextOptionItem.Create(10000020, "Experimental.Roles", TabGroup.ImpostorRoles) @@ -1128,9 +1128,9 @@ private static System.Collections.IEnumerator CoLoadOptions() .SetHeader(true); AllowConsole = BooleanOptionItem.Create(60382, "AllowConsole", false, TabGroup.SystemSettings, false) .SetColor(Color.red); - /* DisableAntiBlackoutProtects = BooleanOptionItem.Create(60384, "DisableAntiBlackoutProtects", false, TabGroup.SystemSettings, false) - .SetGameMode(CustomGameMode.Standard) - .SetColor(Color.red);*/ + /* DisableAntiBlackoutProtects = BooleanOptionItem.Create(60384, "DisableAntiBlackoutProtects", false, TabGroup.SystemSettings, false) + .SetGameMode(CustomGameMode.Standard) + .SetColor(Color.red);*/ RoleAssigningAlgorithm = StringOptionItem.Create(60400, "RoleAssigningAlgorithm", roleAssigningAlgorithms, 4, TabGroup.SystemSettings, true) .RegisterUpdateValueEvent((object obj, OptionItem.UpdateValueEventArgs args) => IRandom.SetInstanceById(args.CurrentValue)) @@ -1232,7 +1232,7 @@ private static System.Collections.IEnumerator CoLoadOptions() // Random Spawn RandomSpawn.SetupCustomOption(); - + MapModification = BooleanOptionItem.Create(60480, "MapModification", false, TabGroup.ModSettings, false) .SetColor(new Color32(19, 188, 233, byte.MaxValue)); // Airship Variable Electrical @@ -1775,7 +1775,7 @@ private static System.Collections.IEnumerator CoLoadOptions() WhenTie = StringOptionItem.Create(60745, "WhenTie", tieModes, 0, TabGroup.ModSettings, false) .SetParent(VoteMode) .SetGameMode(CustomGameMode.Standard); - EnableVoteCommand = BooleanOptionItem.Create(60746, "EnableVote", true, TabGroup.ModSettings, false) + EnableVoteCommand = BooleanOptionItem.Create(60746, "EnableVote", true, TabGroup.ModSettings, false) .SetColor(new Color32(147, 241, 240, byte.MaxValue)) .SetGameMode(CustomGameMode.Standard); ShouldVoteCmdsSpamChat = BooleanOptionItem.Create(60747, "ShouldVoteSpam", false, TabGroup.ModSettings, false) @@ -1815,10 +1815,12 @@ private static System.Collections.IEnumerator CoLoadOptions() ShieldedCanUseKillButton = BooleanOptionItem.Create(60782, "ShieldedCanUseKillButton", true, TabGroup.ModSettings, false).SetParent(ShieldPersonDiedFirst) .SetGameMode(CustomGameMode.Standard) .SetColor(new Color32(193, 255, 209, byte.MaxValue)); - + EveryoneCanSeeDeathReason = BooleanOptionItem.Create(60781, "EveryoneCanSeeDeathReason", false, TabGroup.ModSettings, false) .SetGameMode(CustomGameMode.Standard) .SetColor(new Color32(193, 255, 209, byte.MaxValue)); + + // 杀戮闪烁持续 KillFlashDuration = FloatOptionItem.Create(60790, "KillFlashDuration", new(0.1f, 0.45f, 0.05f), 0.3f, TabGroup.ModSettings, false) @@ -1850,7 +1852,7 @@ private static System.Collections.IEnumerator CoLoadOptions() .SetParent(ConvertedCanBecomeGhost) .SetGameMode(CustomGameMode.Standard) .SetColor(new Color32(217, 218, 255, byte.MaxValue)); - + MaxImpGhost = IntegerOptionItem.Create(60850, "MaxImpGhostRole", new(0, 15, 1), 15, TabGroup.ModSettings, false) .SetGameMode(CustomGameMode.Standard) .SetValueFormat(OptionFormat.Times) diff --git a/Modules/OptionItem/OptionItem.cs b/Modules/OptionItem/OptionItem.cs index ff38d57a9..08de987b4 100644 --- a/Modules/OptionItem/OptionItem.cs +++ b/Modules/OptionItem/OptionItem.cs @@ -54,6 +54,8 @@ public int CurrentValue // Parent and Child Info public OptionItem Parent { get; private set; } + + public List Children; public OptionBehaviour OptionBehaviour; diff --git a/Modules/OptionItem/StringOptionItem.cs b/Modules/OptionItem/StringOptionItem.cs index b64565040..9be3823de 100644 --- a/Modules/OptionItem/StringOptionItem.cs +++ b/Modules/OptionItem/StringOptionItem.cs @@ -45,4 +45,9 @@ public override void SetValue(int value, bool doSync = true) { base.SetValue(Rule.RepeatIndex(value), doSync); } + + internal static object Create(int v1, string v2, string[] strings, int[] ints, TabGroup neutralRoles, bool v3) + { + throw new NotImplementedException(); + } } \ No newline at end of file diff --git a/Modules/RPC.cs b/Modules/RPC.cs index 65d31477a..14dabeea6 100644 --- a/Modules/RPC.cs +++ b/Modules/RPC.cs @@ -4,6 +4,7 @@ using System; using System.Threading.Tasks; using TOHE.Modules; +using TOHE.Modules.ChatManager; using TOHE.Patches; using TOHE.Roles.AddOns.Impostor; using TOHE.Roles.Core; @@ -37,6 +38,8 @@ enum CustomRPC : byte // 185/255 USED KillFlash, DumpLog, SyncRoleSkill, + SendChatMessage = 186, + MuteChat = 187, SetNameColorData, GuessKill, Judge, @@ -73,6 +76,7 @@ enum CustomRPC : byte // 185/255 USED SetEvilTrackerTarget, SetDrawPlayer, SetCrewpostorTasksDone, + UpdateSoulMeter, // BetterAmongUs (BAU) RPC, This is sent to allow other BAU users know who's using BAU! BetterCheck = 150, @@ -207,6 +211,9 @@ public static bool Prefix(PlayerControl __instance, [HarmonyArgument(0)] byte ca } return true; } + + + public static void Postfix(PlayerControl __instance, [HarmonyArgument(0)] byte callId, [HarmonyArgument(1)] MessageReader reader) { // Process nothing but CustomRPC @@ -555,6 +562,9 @@ public static void Postfix(PlayerControl __instance, [HarmonyArgument(0)] byte c case CustomRPC.SetJailerTarget: Jailer.ReceiveRPC(reader, setTarget: true); break; + case CustomRPC.SendChatMessage: + HandleSendChatMessage(reader); + break; case CustomRPC.SetCrewpostorTasksDone: Crewpostor.ReceiveRPC(reader); break; @@ -718,6 +728,52 @@ public static void Postfix(PlayerControl __instance, [HarmonyArgument(0)] byte c } } + private static void HandleSendChatMessage(MessageReader reader) + { + string message = reader.ReadString(); + byte targetPlayerId = reader.ReadByte(); + + PlayerControl target = null; + foreach (var player in PlayerControl.AllPlayerControls) + { + if (player.PlayerId == targetPlayerId) + { + target = player; + break; + } + } + + if (target != null && target.AmOwner) + { + // Send the private message to the summoner + Utils.SendMessage($"SYSTEM MESSAGE: {message}", target.PlayerId); + Logger.Info($"Sent SYSTEM MESSAGE to {target.GetRealName()}", "ChatManager"); + ChatManager.cancel = true; // Prevent normal chat behavior + } + } + + + + + private static void SendChatMessage(PlayerControl recipient, string message) + { + MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately( + PlayerControl.LocalPlayer.NetId, + (byte)CustomRPC.SendChatMessage, + SendOption.Reliable + ); + + // Write the recipient's PlayerId and the message + writer.Write(recipient.PlayerId); + writer.Write(message); + + AmongUsClient.Instance.FinishRpcImmediately(writer); + + Logger.Info($"Sent private message to {recipient.GetRealName()}: {message}", "ChatManager"); + } + + + private static bool IsVersionMatch(int ClientId) { if (Main.VersionCheat.Value) return true; @@ -1073,6 +1129,9 @@ public static string GetRpcName(byte callId) else rpcName = callId.ToString(); return rpcName; } + + + public static void SetRealKiller(byte targetId, byte killerId) { var state = Main.PlayerStates[targetId]; diff --git a/Modules/Utils.cs b/Modules/Utils.cs index f529570f0..b8381cbe0 100644 --- a/Modules/Utils.cs +++ b/Modules/Utils.cs @@ -32,7 +32,7 @@ public static class Utils private static readonly DateTime timeStampStartTime = new(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); public static long TimeStamp => (long)(DateTime.Now.ToUniversalTime() - timeStampStartTime).TotalSeconds; public static long GetTimeStamp(DateTime? dateTime = null) => (long)((dateTime ?? DateTime.Now).ToUniversalTime() - timeStampStartTime).TotalSeconds; - + public static void ErrorEnd(string text) { if (AmongUsClient.Instance.AmHost) @@ -40,7 +40,7 @@ public static void ErrorEnd(string text) Logger.Fatal($"Error: {text} - triggering critical error", "Anti-black"); ChatUpdatePatch.DoBlockChat = true; Main.OverrideWelcomeMsg = GetString("AntiBlackOutNotifyInLobby"); - + _ = new LateTask(() => { Logger.SendInGame(GetString("AntiBlackOutLoggerSendInGame")); @@ -88,7 +88,7 @@ public static void ErrorEnd(string text) { Logger.SendInGame(GetString("AntiBlackOutHostRejectForceEnd")); }, 8f, "Anti-Black Msg SendInGame Host Reject Force End"); - + _ = new LateTask(() => { if (AmongUsClient.Instance.AmConnected) @@ -264,7 +264,7 @@ public static void SetVisionV2(this IGameOptions opt) } return; } - + public static void TargetDies(PlayerControl killer, PlayerControl target) { if (!target.Data.IsDead || GameStates.IsMeeting) return; @@ -342,18 +342,18 @@ public static void BlackOut(this IGameOptions opt, bool IsBlackOut) public static string GetRoleTitle(this CustomRoles role) { string ColorName = ColorString(GetRoleColor(role), GetString($"{role}")); - + string chance = GetRoleMode(role); if (role.IsAdditionRole() && !role.IsEnable()) chance = ColorString(Color.red, "(OFF)"); - + return $"{ColorName} {chance}"; } - public static string GetInfoLong(this CustomRoles role) + public static string GetInfoLong(this CustomRoles role) { var InfoLong = GetString($"{role}" + "InfoLong"); var CustomName = GetString($"{role}"); var ColorName = ColorString(GetRoleColor(role).ShadeColor(0.25f), CustomName); - + Translator.GetActualRoleName(role, out var RealRole); return InfoLong.Replace(RealRole, $"{ColorName}"); @@ -377,14 +377,14 @@ public static string GetRoleMode(CustomRoles role, bool parentheses = true) else if (role.IsAdditionRole() && Options.CustomAdtRoleSpawnRate.ContainsKey(role)) { mode = GetChance(Options.CustomAdtRoleSpawnRate[role].GetFloat()); - + } - + return parentheses ? $"({mode})" : mode; } public static string GetChance(float percent) { - return percent switch + return percent switch { 0 => "0%", 5 => "5%", @@ -466,6 +466,10 @@ public static Color GetTeamColor(PlayerControl player) break; } + + + + _ = ColorUtility.TryParseHtmlString(hexColor, out Color c); return c; } @@ -1769,6 +1773,7 @@ public static List GetPlayerListByRole(this CustomRoles role) public static bool IsSameTeammate(this PlayerControl player, PlayerControl target, out Custom_Team team) { team = default; + if (player.IsAnySubRole(x => x.IsConverted())) { var Compare = player.GetCustomSubRoles().First(x => x.IsConverted()); @@ -1782,9 +1787,13 @@ public static bool IsSameTeammate(this PlayerControl player, PlayerControl targe return target.Is(team); } - return false; } + + + + + public static IEnumerable GetRoleBasesByType () where t : RoleBase { try @@ -1822,7 +1831,7 @@ public static void SetCustomIntro(this PlayerControl player) { if (!SetUpRoleTextPatch.IsInIntro || player == null || player.IsModded()) return; - //Get role info font size based on the length of the role info + // Get role info font size based on the length of the role info static int GetInfoSize(string RoleInfo) { RoleInfo = Regex.Replace(RoleInfo, "<[^>]*>", ""); @@ -1844,6 +1853,8 @@ static int GetInfoSize(string RoleInfo) string SelfSubRolesName = string.Empty; string RoleInfo = $"\n{Font}{ColorString(player.GetRoleColor(), player.GetRoleInfo())}"; string RoleNameUp = "\n\n"; + + if (!player.HasDesyncRole()) { @@ -1955,7 +1966,7 @@ public static Task DoNotifyRoles(PlayerControl SpecifySeer = null, PlayerControl var seerRoleClass = seer.GetRoleClass(); // Hide player names in during Mushroom Mixup if seer is alive and desync impostor - if (!CamouflageIsForMeeting && MushroomMixupIsActive && seer.IsAlive() && !seer.Is(Custom_Team.Impostor) && seer.HasDesyncRole()) + if (!CamouflageIsForMeeting && MushroomMixupIsActive && seer.IsAlive() && (!seer.Is(Custom_Team.Impostor) || Main.PlayerStates[seer.PlayerId].IsRandomizer) && seer.HasDesyncRole()) { seer.RpcSetNamePrivate("", force: NoCache); } @@ -2104,7 +2115,7 @@ public static Task DoNotifyRoles(PlayerControl SpecifySeer = null, PlayerControl //logger.Info("NotifyRoles-Loop2-" + target.GetNameWithRole() + ":START"); // Hide player names in during Mushroom Mixup if seer is alive and desync impostor - if (!CamouflageIsForMeeting && MushroomMixupIsActive && target.IsAlive() && !seer.Is(Custom_Team.Impostor) && seer.HasDesyncRole()) + if (!CamouflageIsForMeeting && MushroomMixupIsActive && target.IsAlive() && (!seer.Is(Custom_Team.Impostor) || Main.PlayerStates[seer.PlayerId].IsRandomizer) && seer.HasDesyncRole()) { realTarget.RpcSetNamePrivate("", seer, force: NoCache); } @@ -2320,6 +2331,8 @@ or PlayerState.DeathReason.Gambled return checkbanned ? !BannedReason(reason) : reason switch { PlayerState.DeathReason.Eaten => (CustomRoles.Pelican.IsEnable()), + PlayerState.DeathReason.FadedAway => (CustomRoles.LingeringPresence.IsEnable()), + PlayerState.DeathReason.AllergicReaction => (CustomRoles.Allergic.IsEnable()), PlayerState.DeathReason.Spell => (CustomRoles.Witch.IsEnable()), PlayerState.DeathReason.Hex => (CustomRoles.HexMaster.IsEnable()), PlayerState.DeathReason.Curse => (CustomRoles.CursedWolf.IsEnable()), @@ -2407,6 +2420,7 @@ public static void AfterMeetingTasks() if (Burst.IsEnable) Burst.AfterMeetingTasks(); if (CustomRoles.CopyCat.HasEnabled()) CopyCat.UnAfterMeetingTasks(); // All crew hast to be before this + if (CustomRoles.Randomizer.HasEnabled()) Randomizer.AfterMeetingTasks(); } catch (Exception error) { @@ -2435,10 +2449,27 @@ public static void ChangeInt(ref int ChangeTo, int input, int max) } public static void CountAlivePlayers(bool sendLog = false, bool checkGameEnd = false) { - int AliveImpostorCount = Main.AllAlivePlayerControls.Count(pc => pc.Is(Custom_Team.Impostor)); + // Adjusted Impostor Count Logic (Include Randomizer if LockedTeam is Impostor) + int AliveImpostorCount = Main.AllAlivePlayerControls.Count(pc => + { + var playerState = Main.PlayerStates[pc.PlayerId]; + return pc.Is(Custom_Team.Impostor) || + (playerState.IsRandomizer && playerState.LockedTeam == Custom_Team.Impostor); + }); + + // Adjusted Crewmate Count Logic (Include Randomizer based on LockedTeam) + int AliveCrewmateCount = Main.AllAlivePlayerControls.Count(pc => + { + var playerState = Main.PlayerStates[pc.PlayerId]; + return pc.Is(Custom_Team.Crewmate) || + (playerState.IsRandomizer && + (playerState.LockedTeam == Custom_Team.Crewmate || playerState.LockedTeam == Custom_Team.Neutral)); + }); + + // Log Impostor Count Changes if (Main.AliveImpostorCount != AliveImpostorCount) { - Logger.Info("Number Impostor left: " + AliveImpostorCount, "CountAliveImpostors"); + Logger.Info("Number of Impostors left: " + AliveImpostorCount, "CountAliveImpostors"); Main.AliveImpostorCount = AliveImpostorCount; LastImpostor.SetSubRole(); } @@ -2447,7 +2478,7 @@ public static void CountAlivePlayers(bool sendLog = false, bool checkGameEnd = f { var sb = new StringBuilder(100); if (Options.CurrentGameMode != CustomGameMode.FFA) - { + { foreach (var countTypes in EnumHelper.GetAllValues()) { var playersCount = PlayersCount(countTypes); @@ -2455,13 +2486,15 @@ public static void CountAlivePlayers(bool sendLog = false, bool checkGameEnd = f sb.Append($"{countTypes}:{AlivePlayersCount(countTypes)}/{playersCount}, "); } } - sb.Append($"All:{AllAlivePlayersCount}/{AllPlayersCount}"); + sb.Append($"Crewmates:{AliveCrewmateCount}, Impostors:{AliveImpostorCount}, All:{AllAlivePlayersCount}/{AllPlayersCount}"); Logger.Info(sb.ToString(), "CountAlivePlayers"); } if (AmongUsClient.Instance.AmHost && checkGameEnd) GameEndCheckerForNormal.Prefix(); } + + public static string GetVoteName(byte num) { // HasNotVoted = 255; @@ -2688,4 +2721,9 @@ public static void SetChatVisibleSpecific(this PlayerControl player) public static bool IsAllAlive => Main.PlayerStates.Values.All(state => state.countTypes == CountTypes.OutOfGame || !state.IsDead); public static int PlayersCount(CountTypes countTypes) => Main.PlayerStates.Values.Count(state => state.countTypes == countTypes); public static int AlivePlayersCount(CountTypes countTypes) => Main.AllAlivePlayerControls.Count(pc => pc.Is(countTypes)); + + internal static void SendMessage(string v, object playerId) + { + throw new NotImplementedException(); + } } diff --git a/Patches/ChatBubblePatch.cs b/Patches/ChatBubblePatch.cs index c1b0bff88..d6c859332 100644 --- a/Patches/ChatBubblePatch.cs +++ b/Patches/ChatBubblePatch.cs @@ -31,7 +31,11 @@ public static void Postfix(ChatBubble __instance, [HarmonyArgument(1)] bool isDe // When target is impostor, set name color as white __instance.NameText.color = Color.white; } - + if (Main.PlayerStates[seer.PlayerId].IsRandomizer || Main.PlayerStates[target.PlayerId].IsRandomizer) + { + // When target is impostor, set name color as white + __instance.NameText.color = Color.white; + } if (Main.DarkTheme.Value) { if (isDead) diff --git a/Patches/ChatCommandPatch.cs b/Patches/ChatCommandPatch.cs index b385a1f11..9651787ce 100644 --- a/Patches/ChatCommandPatch.cs +++ b/Patches/ChatCommandPatch.cs @@ -1,378 +1,381 @@ -using Assets.CoreScripts; -using Hazel; -using System; -using System.IO; -using System.Text; -using System.Text.RegularExpressions; -using TOHE.Modules; -using TOHE.Modules.ChatManager; -using TOHE.Roles.Core; -using TOHE.Roles.Core.AssignManager; -using TOHE.Roles.Crewmate; -using TOHE.Roles.Impostor; -using TOHE.Roles.Neutral; -using UnityEngine; -using static TOHE.Translator; - - -namespace TOHE; - -[HarmonyPatch(typeof(ChatController), nameof(ChatController.SendChat))] -internal class ChatCommands -{ - private static readonly string modLogFiles = @"./TOHE-DATA/ModLogs.txt"; - private static readonly string modTagsFiles = @"./TOHE-DATA/Tags/MOD_TAGS"; - private static readonly string sponsorTagsFiles = @"./TOHE-DATA/Tags/SPONSOR_TAGS"; - private static readonly string vipTagsFiles = @"./TOHE-DATA/Tags/VIP_TAGS"; - - private static readonly Dictionary Pollvotes = []; - private static readonly Dictionary PollQuestions = []; - private static readonly List PollVoted = []; - private static float Polltimer = 120f; - private static string PollMSG = ""; - - public const string Csize = "85%"; // CustomRole Settings Font-Size - public const string Asize = "75%"; // All Appended Addons Font-Size - - public static List ChatHistory = []; - - public static bool Prefix(ChatController __instance) - { - if (__instance.quickChatField.visible == false && __instance.freeChatField.textArea.text == "") return false; - if (!GameStates.IsModHost && !AmongUsClient.Instance.AmHost) return true; - __instance.timeSinceLastMessage = 3f; - var text = __instance.freeChatField.textArea.text; - if (ChatHistory.Count == 0 || ChatHistory[^1] != text) ChatHistory.Add(text); - ChatControllerUpdatePatch.CurrentHistorySelection = ChatHistory.Count; - string[] args = text.Split(' '); - string subArgs = ""; - string subArgs2 = ""; - var canceled = false; - var cancelVal = ""; - Main.isChatCommand = true; - Logger.Info(text, "SendChat"); - if ((Options.NewHideMsg.GetBool() || Blackmailer.HasEnabled) && AmongUsClient.Instance.AmHost) // Blackmailer.ForBlackmailer.Contains(PlayerControl.LocalPlayer.PlayerId)) && PlayerControl.LocalPlayer.IsAlive()) - { - ChatManager.SendMessage(PlayerControl.LocalPlayer, text); - } - //if (text.Length >= 3) if (text[..2] == "/r" && text[..3] != "/rn" && text[..3] != "/rs") args[0] = "/r"; - if (text.Length >= 4) if (text[..3] == "/up") args[0] = "/up"; - - if (GuessManager.GuesserMsg(PlayerControl.LocalPlayer, text)) goto Canceled; - if (PlayerControl.LocalPlayer.GetRoleClass() is Judge jd && jd.TrialMsg(PlayerControl.LocalPlayer, text)) goto Canceled; - if (President.EndMsg(PlayerControl.LocalPlayer, text)) goto Canceled; - if (Inspector.InspectCheckMsg(PlayerControl.LocalPlayer, text)) goto Canceled; - if (Pirate.DuelCheckMsg(PlayerControl.LocalPlayer, text)) goto Canceled; - if (PlayerControl.LocalPlayer.GetRoleClass() is Councillor cl && cl.MurderMsg(PlayerControl.LocalPlayer, text)) goto Canceled; - if (Nemesis.NemesisMsgCheck(PlayerControl.LocalPlayer, text)) goto Canceled; - if (Retributionist.RetributionistMsgCheck(PlayerControl.LocalPlayer, text)) goto Canceled; - if (Medium.MsMsg(PlayerControl.LocalPlayer, text)) goto Canceled; - if (PlayerControl.LocalPlayer.GetRoleClass() is Swapper sw && sw.SwapMsg(PlayerControl.LocalPlayer, text)) goto Canceled; - Directory.CreateDirectory(modTagsFiles); - Directory.CreateDirectory(vipTagsFiles); - Directory.CreateDirectory(sponsorTagsFiles); - - if (Blackmailer.CheckBlackmaile(PlayerControl.LocalPlayer) && PlayerControl.LocalPlayer.IsAlive()) - { - goto Canceled; - } - switch (args[0]) - { +using Assets.CoreScripts; +using Hazel; +using System; +using System.IO; +using System.Text; +using System.Text.RegularExpressions; +using TOHE.Modules; +using TOHE.Modules.ChatManager; +using TOHE.Roles.Core; +using TOHE.Roles.Core.AssignManager; +using TOHE.Roles.Crewmate; +using TOHE.Roles.Impostor; +using TOHE.Roles.Neutral; +using Il2CppSystem.Linq; +using UnityEngine; +using static TOHE.Translator; + + +namespace TOHE; + +[HarmonyPatch(typeof(ChatController), nameof(ChatController.SendChat))] +internal class ChatCommands +{ + private static readonly string modLogFiles = @"./TOHE-DATA/ModLogs.txt"; + private static readonly string modTagsFiles = @"./TOHE-DATA/Tags/MOD_TAGS"; + private static readonly string sponsorTagsFiles = @"./TOHE-DATA/Tags/SPONSOR_TAGS"; + private static readonly string vipTagsFiles = @"./TOHE-DATA/Tags/VIP_TAGS"; + + private static readonly Dictionary Pollvotes = []; + private static readonly Dictionary PollQuestions = []; + private static readonly List PollVoted = []; + private static float Polltimer = 120f; + private static string PollMSG = ""; + + public const string Csize = "85%"; // CustomRole Settings Font-Size + public const string Asize = "75%"; // All Appended Addons Font-Size + + public static List ChatHistory = []; + + public static bool Prefix(ChatController __instance) + { + if (__instance.quickChatField.visible == false && __instance.freeChatField.textArea.text == "") return false; + if (!GameStates.IsModHost && !AmongUsClient.Instance.AmHost) return true; + __instance.timeSinceLastMessage = 3f; + var text = __instance.freeChatField.textArea.text; + if (ChatHistory.Count == 0 || ChatHistory[^1] != text) ChatHistory.Add(text); + ChatControllerUpdatePatch.CurrentHistorySelection = ChatHistory.Count; + string[] args = text.Split(' '); + string subArgs = ""; + string subArgs2 = ""; + var canceled = false; + var cancelVal = ""; + Main.isChatCommand = true; + Logger.Info(text, "SendChat"); + if ((Options.NewHideMsg.GetBool() || Blackmailer.HasEnabled) && AmongUsClient.Instance.AmHost) // Blackmailer.ForBlackmailer.Contains(PlayerControl.LocalPlayer.PlayerId)) && PlayerControl.LocalPlayer.IsAlive()) + { + ChatManager.SendMessage(PlayerControl.LocalPlayer, text); + } + //if (text.Length >= 3) if (text[..2] == "/r" && text[..3] != "/rn" && text[..3] != "/rs") args[0] = "/r"; + if (text.Length >= 4) if (text[..3] == "/up") args[0] = "/up"; + + if (GuessManager.GuesserMsg(PlayerControl.LocalPlayer, text)) goto Canceled; + if (PlayerControl.LocalPlayer.GetRoleClass() is Judge jd && jd.TrialMsg(PlayerControl.LocalPlayer, text)) goto Canceled; + if (President.EndMsg(PlayerControl.LocalPlayer, text)) goto Canceled; + if (Inspector.InspectCheckMsg(PlayerControl.LocalPlayer, text)) goto Canceled; + if (Pirate.DuelCheckMsg(PlayerControl.LocalPlayer, text)) goto Canceled; + if (Evolver.EvolverCheckMsg(PlayerControl.LocalPlayer, text)) goto Canceled; + if (Summoner.SummonerCheckMsg(PlayerControl.LocalPlayer, text)) goto Canceled; + if (PlayerControl.LocalPlayer.GetRoleClass() is Councillor cl && cl.MurderMsg(PlayerControl.LocalPlayer, text)) goto Canceled; + if (Nemesis.NemesisMsgCheck(PlayerControl.LocalPlayer, text)) goto Canceled; + if (Retributionist.RetributionistMsgCheck(PlayerControl.LocalPlayer, text)) goto Canceled; + if (Medium.MsMsg(PlayerControl.LocalPlayer, text)) goto Canceled; + if (PlayerControl.LocalPlayer.GetRoleClass() is Swapper sw && sw.SwapMsg(PlayerControl.LocalPlayer, text)) goto Canceled; + Directory.CreateDirectory(modTagsFiles); + Directory.CreateDirectory(vipTagsFiles); + Directory.CreateDirectory(sponsorTagsFiles); + + if (Blackmailer.CheckBlackmaile(PlayerControl.LocalPlayer) && PlayerControl.LocalPlayer.IsAlive()) + { + goto Canceled; + } + switch (args[0]) + { case "/dump": - case "/导出日志": - case "/日志": - case "/导出": - Utils.DumpLog(); - break; - case "/v": - case "/version": + case "/导出日志": + case "/日志": + case "/导出": + Utils.DumpLog(); + break; + case "/v": + case "/version": case "/versão": - case "/版本": - canceled = true; - string version_text = ""; - var player = PlayerControl.LocalPlayer; - var title = "" + GetString("DefaultSystemMessageTitle") + ""; - var name = player?.Data?.PlayerName; - try - { - foreach (var kvp in Main.playerVersion.OrderBy(pair => pair.Key).ToArray()) - { - var pc = Utils.GetClientById(kvp.Key)?.Character; - version_text += $"{kvp.Key}/{(pc?.PlayerId != null ? pc.PlayerId.ToString() : "null")}:{pc?.GetRealName(clientData: true) ?? "null"}:{kvp.Value.forkId}/{kvp.Value.version}({kvp.Value.tag})\n"; - } - if (version_text != "") - { - player.SetName(title); - DestroyableSingleton.Instance.Chat.AddChat(player, version_text); - player.SetName(name); - } - } - catch (Exception e) - { - Logger.Error(e.Message, "/version"); - version_text = "Error while getting version : " + e.Message; - if (version_text != "") - { - player.SetName(title); - DestroyableSingleton.Instance.Chat.AddChat(player, version_text); - player.SetName(name); - } - } - break; - - default: - Main.isChatCommand = false; - break; - } - if (AmongUsClient.Instance.AmHost) - { - Main.isChatCommand = true; - switch (args[0]) - { - case "/ans": - case "/asw": + case "/版本": + canceled = true; + string version_text = ""; + var player = PlayerControl.LocalPlayer; + var title = "" + GetString("DefaultSystemMessageTitle") + ""; + var name = player?.Data?.PlayerName; + try + { + foreach (var kvp in Main.playerVersion.OrderBy(pair => pair.Key).ToArray()) + { + var pc = Utils.GetClientById(kvp.Key)?.Character; + version_text += $"{kvp.Key}/{(pc?.PlayerId != null ? pc.PlayerId.ToString() : "null")}:{pc?.GetRealName(clientData: true) ?? "null"}:{kvp.Value.forkId}/{kvp.Value.version}({kvp.Value.tag})\n"; + } + if (version_text != "") + { + player.SetName(title); + DestroyableSingleton.Instance.Chat.AddChat(player, version_text); + player.SetName(name); + } + } + catch (Exception e) + { + Logger.Error(e.Message, "/version"); + version_text = "Error while getting version : " + e.Message; + if (version_text != "") + { + player.SetName(title); + DestroyableSingleton.Instance.Chat.AddChat(player, version_text); + player.SetName(name); + } + } + break; + + default: + Main.isChatCommand = false; + break; + } + if (AmongUsClient.Instance.AmHost) + { + Main.isChatCommand = true; + switch (args[0]) + { + case "/ans": + case "/asw": case "/answer": - case "/回答": - Quizmaster.AnswerByChat(PlayerControl.LocalPlayer, args); - break; - + case "/回答": + Quizmaster.AnswerByChat(PlayerControl.LocalPlayer, args); + break; + case "/qmquiz": - case "/提问": - Quizmaster.ShowQuestion(PlayerControl.LocalPlayer); - break; - - case "/win": - case "/winner": + case "/提问": + Quizmaster.ShowQuestion(PlayerControl.LocalPlayer); + break; + + case "/win": + case "/winner": case "/vencedor": case "/胜利": case "/获胜": case "/赢": case "/胜利者": case "/获胜的人": - case "/赢家": - canceled = true; - if (Main.winnerNameList.Count == 0) Utils.SendMessage(GetString("NoInfoExists")); - else Utils.SendMessage("Winner: " + string.Join(", ", Main.winnerNameList)); - break; - - case "/l": - case "/lastresult": + case "/赢家": + canceled = true; + if (Main.winnerNameList.Count == 0) Utils.SendMessage(GetString("NoInfoExists")); + else Utils.SendMessage("Winner: " + string.Join(", ", Main.winnerNameList)); + break; + + case "/l": + case "/lastresult": case "/fimdejogo": case "/上局信息": case "/信息": - case "/情况": - canceled = true; - Utils.ShowKillLog(); - Utils.ShowLastRoles(); - Utils.ShowLastResult(); - break; - - case "/gr": - case "/gameresults": + case "/情况": + canceled = true; + Utils.ShowKillLog(); + Utils.ShowLastRoles(); + Utils.ShowLastResult(); + break; + + case "/gr": + case "/gameresults": case "/resultados": case "/对局结果": case "/上局结果": - case "/结果": - canceled = true; - Utils.ShowLastResult(); - break; - - case "/kh": + case "/结果": + canceled = true; + Utils.ShowLastResult(); + break; + + case "/kh": case "/killlog": case "/击杀日志": - case "/击杀情况": - canceled = true; - Utils.ShowKillLog(); - break; - - case "/rs": - case "/sum": - case "/rolesummary": - case "/sumario": - case "/sumário": - case "/summary": + case "/击杀情况": + canceled = true; + Utils.ShowKillLog(); + break; + + case "/rs": + case "/sum": + case "/rolesummary": + case "/sumario": + case "/sumário": + case "/summary": case "/результат": case "/上局职业": case "/职业信息": - case "/对局职业": - canceled = true; - Utils.ShowLastRoles(); - break; - + case "/对局职业": + canceled = true; + Utils.ShowLastRoles(); + break; + case "/ghostinfo": case "/幽灵职业介绍": case "/鬼魂职业介绍": case "/幽灵职业": - case "/鬼魂职业": - canceled = true; - Utils.SendMessage(GetString("Message.GhostRoleInfo"), PlayerControl.LocalPlayer.PlayerId); - break; - - case "/apocinfo": + case "/鬼魂职业": + canceled = true; + Utils.SendMessage(GetString("Message.GhostRoleInfo"), PlayerControl.LocalPlayer.PlayerId); + break; + + case "/apocinfo": case "/apocalypseinfo": case "/末日中立职业介绍": case "/末日中立介绍": case "/末日类中立职业介绍": - case "/末日类中立介绍": - canceled = true; - Utils.SendMessage(GetString("Message.ApocalypseInfo"), PlayerControl.LocalPlayer.PlayerId, Utils.ColorString(Utils.GetRoleColor(CustomRoles.Apocalypse), GetString("ApocalypseInfoTitle"))); - break; - - - case "/rn": - case "/rename": - case "/renomear": + case "/末日类中立介绍": + canceled = true; + Utils.SendMessage(GetString("Message.ApocalypseInfo"), PlayerControl.LocalPlayer.PlayerId, Utils.ColorString(Utils.GetRoleColor(CustomRoles.Apocalypse), GetString("ApocalypseInfoTitle"))); + break; + + + case "/rn": + case "/rename": + case "/renomear": case "/переименовать": case "/重命名": - case "/命名为": - canceled = true; - if (args.Length < 1) break; - if (args.Skip(1).Join(delimiter: " ").Length is > 10 or < 1) { - Utils.SendMessage(GetString("Message.AllowNameLength"), PlayerControl.LocalPlayer.PlayerId); - break; - } - else Main.HostRealName = args.Skip(1).Join(delimiter: " "); - Utils.SendMessage(string.Format(GetString("Message.SetName"), args.Skip(1).Join(delimiter: " ")), PlayerControl.LocalPlayer.PlayerId); - break; - - case "/hn": - case "/hidename": + case "/命名为": + canceled = true; + if (args.Length < 1) break; + if (args.Skip(1).Join(delimiter: " ").Length is > 10 or < 1) { + Utils.SendMessage(GetString("Message.AllowNameLength"), PlayerControl.LocalPlayer.PlayerId); + break; + } + else Main.HostRealName = args.Skip(1).Join(delimiter: " "); + Utils.SendMessage(string.Format(GetString("Message.SetName"), args.Skip(1).Join(delimiter: " ")), PlayerControl.LocalPlayer.PlayerId); + break; + + case "/hn": + case "/hidename": case "/semnome": case "/隐藏名字": - case "/藏名": - canceled = true; - Main.HideName.Value = args.Length > 1 ? args.Skip(1).Join(delimiter: " ") : Main.HideName.DefaultValue.ToString(); - GameStartManagerPatch.GameStartManagerStartPatch.HideName.text = - ColorUtility.TryParseHtmlString(Main.HideColor.Value, out _) - ? $"{Main.HideName.Value}" - : $"{Main.HideName.Value}"; - break; - - case "/level": - case "/nível": + case "/藏名": + canceled = true; + Main.HideName.Value = args.Length > 1 ? args.Skip(1).Join(delimiter: " ") : Main.HideName.DefaultValue.ToString(); + GameStartManagerPatch.GameStartManagerStartPatch.HideName.text = + ColorUtility.TryParseHtmlString(Main.HideColor.Value, out _) + ? $"{Main.HideName.Value}" + : $"{Main.HideName.Value}"; + break; + + case "/level": + case "/nível": case "/nivel": case "/等级": - case "/等级设置为": - canceled = true; - subArgs = args.Length < 2 ? "" : args[1]; - Utils.SendMessage(string.Format(GetString("Message.SetLevel"), subArgs), PlayerControl.LocalPlayer.PlayerId); - _ = int.TryParse(subArgs, out int input); - if (input is < 1 or > 999) - { - Utils.SendMessage(GetString("Message.AllowLevelRange"), PlayerControl.LocalPlayer.PlayerId); - break; - } - var number = Convert.ToUInt32(input); - PlayerControl.LocalPlayer.RpcSetLevel(number - 1); - break; - - case "/n": - case "/now": + case "/等级设置为": + canceled = true; + subArgs = args.Length < 2 ? "" : args[1]; + Utils.SendMessage(string.Format(GetString("Message.SetLevel"), subArgs), PlayerControl.LocalPlayer.PlayerId); + _ = int.TryParse(subArgs, out int input); + if (input is < 1 or > 999) + { + Utils.SendMessage(GetString("Message.AllowLevelRange"), PlayerControl.LocalPlayer.PlayerId); + break; + } + var number = Convert.ToUInt32(input); + PlayerControl.LocalPlayer.RpcSetLevel(number - 1); + break; + + case "/n": + case "/now": case "/atual": case "/设置": case "/系统设置": - case "/模组设置": - canceled = true; - subArgs = args.Length < 2 ? "" : args[1]; - switch (subArgs) - { - case "r": - case "roles": - case "funções": - Utils.ShowActiveRoles(); - break; - case "a": - case "all": - case "tudo": - Utils.ShowAllActiveSettings(); - break; - default: - Utils.ShowActiveSettings(); - break; - } - break; - - case "/dis": - case "/disconnect": + case "/模组设置": + canceled = true; + subArgs = args.Length < 2 ? "" : args[1]; + switch (subArgs) + { + case "r": + case "roles": + case "funções": + Utils.ShowActiveRoles(); + break; + case "a": + case "all": + case "tudo": + Utils.ShowAllActiveSettings(); + break; + default: + Utils.ShowActiveSettings(); + break; + } + break; + + case "/dis": + case "/disconnect": case "/desconectar": - case "/断连": - canceled = true; - subArgs = args.Length < 2 ? "" : args[1]; - switch (subArgs) - { - case "crew": + case "/断连": + canceled = true; + subArgs = args.Length < 2 ? "" : args[1]; + switch (subArgs) + { + case "crew": case "tripulante": - case "船员": - GameManager.Instance.enabled = false; - Utils.NotifyGameEnding(); - GameManager.Instance.RpcEndGame(GameOverReason.HumansDisconnect, false); - break; - - case "imp": + case "船员": + GameManager.Instance.enabled = false; + Utils.NotifyGameEnding(); + GameManager.Instance.RpcEndGame(GameOverReason.HumansDisconnect, false); + break; + + case "imp": case "impostor": case "内鬼": - case "伪装者": - GameManager.Instance.enabled = false; - Utils.NotifyGameEnding(); - GameManager.Instance.RpcEndGame(GameOverReason.ImpostorDisconnect, false); - break; - - default: - __instance.AddChat(PlayerControl.LocalPlayer, "crew | imp"); - if (TranslationController.Instance.currentLanguage.languageID == SupportedLangs.Brazilian) - { - __instance.AddChat(PlayerControl.LocalPlayer, "tripulante | impostor"); - } - cancelVal = "/dis"; - break; - } - ShipStatus.Instance.RpcUpdateSystem(SystemTypes.Admin, 0); - break; - - case "/r": - case "/role": - case "/р": - case "/роль": - canceled = true; - if (text.Contains("/role") || text.Contains("/роль")) - subArgs = text.Remove(0, 5); - else - subArgs = text.Remove(0, 2); - SendRolesInfo(subArgs, PlayerControl.LocalPlayer.PlayerId); - break; - + case "伪装者": + GameManager.Instance.enabled = false; + Utils.NotifyGameEnding(); + GameManager.Instance.RpcEndGame(GameOverReason.ImpostorDisconnect, false); + break; + + default: + __instance.AddChat(PlayerControl.LocalPlayer, "crew | imp"); + if (TranslationController.Instance.currentLanguage.languageID == SupportedLangs.Brazilian) + { + __instance.AddChat(PlayerControl.LocalPlayer, "tripulante | impostor"); + } + cancelVal = "/dis"; + break; + } + ShipStatus.Instance.RpcUpdateSystem(SystemTypes.Admin, 0); + break; + + case "/r": + case "/role": + case "/р": + case "/роль": + canceled = true; + if (text.Contains("/role") || text.Contains("/роль")) + subArgs = text.Remove(0, 5); + else + subArgs = text.Remove(0, 2); + SendRolesInfo(subArgs, PlayerControl.LocalPlayer.PlayerId); + break; + case "/up": case "/指定": - case "/成为": - canceled = true; - subArgs = text.Remove(0, 3); - if (!PlayerControl.LocalPlayer.FriendCode.GetDevUser().IsUp){ - Utils.SendMessage($"{GetString("InvalidPermissionCMD")}", PlayerControl.LocalPlayer.PlayerId); - break; - } - if (!Options.EnableUpMode.GetBool()) - { - Utils.SendMessage(string.Format(GetString("Message.YTPlanDisabled"), GetString("EnableYTPlan")), PlayerControl.LocalPlayer.PlayerId); - break; - } - if (!GameStates.IsLobby) - { - Utils.SendMessage(GetString("Message.OnlyCanUseInLobby"), PlayerControl.LocalPlayer.PlayerId); - break; - } - SendRolesInfo(subArgs, PlayerControl.LocalPlayer.PlayerId, isUp: true); - break; - - //case "/setbasic": - // canceled = true; - // if (GameStates.IsLobby) - // { - // break; - // } - // PlayerControl.LocalPlayer.RpcChangeRoleBasis(CustomRoles.PhantomTOHE); - // break; - - case "/setplayers": + case "/成为": + canceled = true; + subArgs = text.Remove(0, 3); + if (!PlayerControl.LocalPlayer.FriendCode.GetDevUser().IsUp) { + Utils.SendMessage($"{GetString("InvalidPermissionCMD")}", PlayerControl.LocalPlayer.PlayerId); + break; + } + if (!Options.EnableUpMode.GetBool()) + { + Utils.SendMessage(string.Format(GetString("Message.YTPlanDisabled"), GetString("EnableYTPlan")), PlayerControl.LocalPlayer.PlayerId); + break; + } + if (!GameStates.IsLobby) + { + Utils.SendMessage(GetString("Message.OnlyCanUseInLobby"), PlayerControl.LocalPlayer.PlayerId); + break; + } + SendRolesInfo(subArgs, PlayerControl.LocalPlayer.PlayerId, isUp: true); + break; + + //case "/setbasic": + // canceled = true; + // if (GameStates.IsLobby) + // { + // break; + // } + // PlayerControl.LocalPlayer.RpcChangeRoleBasis(CustomRoles.PhantomTOHE); + // break; + + case "/setplayers": case "/maxjogadores": case "/设置最大玩家数": case "/设置最大玩家数量": @@ -380,3032 +383,3042 @@ public static bool Prefix(ChatController __instance) case "/设置玩家数量": case "/玩家数": case "/玩家数量": - case "/玩家": - canceled = true; - subArgs = args.Length < 2 ? "" : args[1]; - Utils.SendMessage(GetString("Message.MaxPlayers") + subArgs); - var numbereer = Convert.ToByte(subArgs); - if (GameStates.IsNormalGame) - GameOptionsManager.Instance.currentNormalGameOptions.MaxPlayers = numbereer; - - else if (GameStates.IsHideNSeek) - GameOptionsManager.Instance.currentHideNSeekGameOptions.MaxPlayers = numbereer; - break; - - case "/h": - case "/help": - case "/ajuda": - case "/хелп": - case "/хэлп": + case "/玩家": + canceled = true; + subArgs = args.Length < 2 ? "" : args[1]; + Utils.SendMessage(GetString("Message.MaxPlayers") + subArgs); + var numbereer = Convert.ToByte(subArgs); + if (GameStates.IsNormalGame) + GameOptionsManager.Instance.currentNormalGameOptions.MaxPlayers = numbereer; + + else if (GameStates.IsHideNSeek) + GameOptionsManager.Instance.currentHideNSeekGameOptions.MaxPlayers = numbereer; + break; + + case "/h": + case "/help": + case "/ajuda": + case "/хелп": + case "/хэлп": case "/помощь": case "/帮助": - case "/教程": - canceled = true; - Utils.ShowHelp(PlayerControl.LocalPlayer.PlayerId); - break; - - case "/icon": + case "/教程": + canceled = true; + Utils.ShowHelp(PlayerControl.LocalPlayer.PlayerId); + break; + + case "/icon": case "/icons": case "/符号": - case "/标志": - { - Utils.SendMessage(GetString("Command.icons"), PlayerControl.LocalPlayer.PlayerId, GetString("IconsTitle")); - break; - } - + case "/标志": + { + Utils.SendMessage(GetString("Command.icons"), PlayerControl.LocalPlayer.PlayerId, GetString("IconsTitle")); + break; + } + case "/iconhelp": case "/符号帮助": - case "/标志帮助": - { - Utils.SendMessage(GetString("Command.icons"), title: GetString("IconsTitle")); - break; - } - - case "/kc": - case "/kcount": - case "/количество": + case "/标志帮助": + { + Utils.SendMessage(GetString("Command.icons"), title: GetString("IconsTitle")); + break; + } + + case "/kc": + case "/kcount": + case "/количество": case "/убийцы": case "/存活阵营": case "/阵营": case "/存货阵营信息": - case "/阵营信息": - if (GameStates.IsLobby || !Options.EnableKillerLeftCommand.GetBool()) break; - - var allAlivePlayers = Main.AllAlivePlayerControls; - int impnum = allAlivePlayers.Count(pc => pc.Is(Custom_Team.Impostor)); - int madnum = allAlivePlayers.Count(pc => pc.GetCustomRole().IsMadmate() || pc.Is(CustomRoles.Madmate)); - int neutralnum = allAlivePlayers.Count(pc => pc.GetCustomRole().IsNK()); - int apocnum = allAlivePlayers.Count(pc => pc.IsNeutralApocalypse() || pc.IsTransformedNeutralApocalypse()); - - var sub = new StringBuilder(); - sub.Append(string.Format(GetString("Remaining.ImpostorCount"), impnum)); - - if (Options.ShowMadmatesInLeftCommand.GetBool()) - sub.Append(string.Format("\n\r" + GetString("Remaining.MadmateCount"), madnum)); - - if (Options.ShowApocalypseInLeftCommand.GetBool()) - sub.Append(string.Format("\n\r" + GetString("Remaining.ApocalypseCount"), apocnum)); - - sub.Append(string.Format("\n\r" + GetString("Remaining.NeutralCount"), neutralnum)); - - Utils.SendMessage(sub.ToString(), PlayerControl.LocalPlayer.PlayerId); - break; + case "/阵营信息": + if (GameStates.IsLobby || !Options.EnableKillerLeftCommand.GetBool()) break; + + var allAlivePlayers = Main.AllAlivePlayerControls; + int impnum = allAlivePlayers.Count(pc => pc.Is(Custom_Team.Impostor)); + int madnum = allAlivePlayers.Count(pc => pc.GetCustomRole().IsMadmate() || pc.Is(CustomRoles.Madmate)); + int neutralnum = allAlivePlayers.Count(pc => pc.GetCustomRole().IsNK()); + int apocnum = allAlivePlayers.Count(pc => pc.IsNeutralApocalypse() || pc.IsTransformedNeutralApocalypse()); + + var sub = new StringBuilder(); + sub.Append(string.Format(GetString("Remaining.ImpostorCount"), impnum)); + + if (Options.ShowMadmatesInLeftCommand.GetBool()) + sub.Append(string.Format("\n\r" + GetString("Remaining.MadmateCount"), madnum)); + + if (Options.ShowApocalypseInLeftCommand.GetBool()) + sub.Append(string.Format("\n\r" + GetString("Remaining.ApocalypseCount"), apocnum)); + + sub.Append(string.Format("\n\r" + GetString("Remaining.NeutralCount"), neutralnum)); + + Utils.SendMessage(sub.ToString(), PlayerControl.LocalPlayer.PlayerId); + break; case "/vote": case "/投票": - case "/票": - subArgs = args.Length != 2 ? "" : args[1]; - if (subArgs == "" || !int.TryParse(subArgs, out int arg)) - break; - var plr = Utils.GetPlayerById(arg); - - if (GameStates.IsLobby) - { - Utils.SendMessage(GetString("Message.CanNotUseInLobby"), PlayerControl.LocalPlayer.PlayerId); - break; - } - - if (!Options.EnableVoteCommand.GetBool()) - { - Utils.SendMessage(GetString("VoteDisabled"), PlayerControl.LocalPlayer.PlayerId); - break; - } - if (Options.ShouldVoteCmdsSpamChat.GetBool()) - { - canceled = true; - } - - if (arg != 253) // skip - { - if (plr == null || !plr.IsAlive()) - { - Utils.SendMessage(GetString("VoteDead"), PlayerControl.LocalPlayer.PlayerId); - break; - } - } - if (!PlayerControl.LocalPlayer.IsAlive()) - { - Utils.SendMessage(GetString("CannotVoteWhenDead"), PlayerControl.LocalPlayer.PlayerId); - break; - } - if (GameStates.IsMeeting) - { - PlayerControl.LocalPlayer.RpcCastVote((byte)arg); - } - break; - - case "/d": - case "/death": - case "/morto": - case "/умер": + case "/票": + subArgs = args.Length != 2 ? "" : args[1]; + if (subArgs == "" || !int.TryParse(subArgs, out int arg)) + break; + var plr = Utils.GetPlayerById(arg); + + if (GameStates.IsLobby) + { + Utils.SendMessage(GetString("Message.CanNotUseInLobby"), PlayerControl.LocalPlayer.PlayerId); + break; + } + + if (!Options.EnableVoteCommand.GetBool()) + { + Utils.SendMessage(GetString("VoteDisabled"), PlayerControl.LocalPlayer.PlayerId); + break; + } + if (Options.ShouldVoteCmdsSpamChat.GetBool()) + { + canceled = true; + } + + if (arg != 253) // skip + { + if (plr == null || !plr.IsAlive()) + { + Utils.SendMessage(GetString("VoteDead"), PlayerControl.LocalPlayer.PlayerId); + break; + } + } + if (!PlayerControl.LocalPlayer.IsAlive()) + { + Utils.SendMessage(GetString("CannotVoteWhenDead"), PlayerControl.LocalPlayer.PlayerId); + break; + } + if (GameStates.IsMeeting) + { + PlayerControl.LocalPlayer.RpcCastVote((byte)arg); + } + break; + + case "/d": + case "/death": + case "/morto": + case "/умер": case "/причина": case "/死亡原因": - case "/死亡": - canceled = true; - Logger.Info($"PlayerControl.LocalPlayer.PlayerId: {PlayerControl.LocalPlayer.PlayerId}", "/death command"); - if (GameStates.IsLobby) - { - Logger.Info("IsLobby", "/death command"); - Utils.SendMessage(text: GetString("Message.CanNotUseInLobby"), sendTo: PlayerControl.LocalPlayer.PlayerId); - break; - } - else if (PlayerControl.LocalPlayer.IsAlive()) - { - Logger.Info("IsAlive", "/death command"); - Utils.SendMessage(text: GetString("DeathCmd.HeyPlayer") + "" + PlayerControl.LocalPlayer.GetRealName() + "" + GetString("DeathCmd.YouAreRole") + "" + $"{Utils.GetRoleName(PlayerControl.LocalPlayer.GetCustomRole())}" + "\n\n" + GetString("DeathCmd.NotDead"), sendTo: PlayerControl.LocalPlayer.PlayerId); - break; - } - else if (Main.PlayerStates[PlayerControl.LocalPlayer.PlayerId].deathReason == PlayerState.DeathReason.Vote) - { - Logger.Info("DeathReason.Vote", "/death command"); - Utils.SendMessage(text: GetString("DeathCmd.YourName") + "" + PlayerControl.LocalPlayer.GetRealName() + "" + "\n\r" + GetString("DeathCmd.YourRole") + "" + $"{Utils.GetRoleName(PlayerControl.LocalPlayer.GetCustomRole())}" + "" + "\n\r" + GetString("DeathCmd.Ejected"), sendTo: PlayerControl.LocalPlayer.PlayerId); - break; - } - else if (Main.PlayerStates[PlayerControl.LocalPlayer.PlayerId].deathReason == PlayerState.DeathReason.Shrouded) - { - Logger.Info("DeathReason.Shrouded", "/death command"); - Utils.SendMessage(text: GetString("DeathCmd.YourName") + "" + PlayerControl.LocalPlayer.GetRealName() + "" + "\n\r" + GetString("DeathCmd.YourRole") + "" + $"{Utils.GetRoleName(PlayerControl.LocalPlayer.GetCustomRole())}" + "" + "\n\r" + GetString("DeathCmd.Shrouded"), sendTo: PlayerControl.LocalPlayer.PlayerId); - break; - } - else if (Main.PlayerStates[PlayerControl.LocalPlayer.PlayerId].deathReason == PlayerState.DeathReason.FollowingSuicide) - { - Logger.Info("DeathReason.FollowingSuicide", "/death command"); - Utils.SendMessage(text: GetString("DeathCmd.YourName") + "" + PlayerControl.LocalPlayer.GetRealName() + "" + "\n\r" + GetString("DeathCmd.YourRole") + "" + $"{Utils.GetRoleName(PlayerControl.LocalPlayer.GetCustomRole())}" + "" + "\n\r" + GetString("DeathCmd.Lovers"), sendTo: PlayerControl.LocalPlayer.PlayerId); - break; - } - else - { - Logger.Info("GetRealKiller()", "/death command"); - var killer = PlayerControl.LocalPlayer.GetRealKiller(out var MurderRole); - string killerName = killer == null ? "N/A" : killer.GetRealName(); - string killerRole = killer == null ? "N/A" : Utils.GetRoleName(MurderRole); - Utils.SendMessage(text: GetString("DeathCmd.YourName") + "" + PlayerControl.LocalPlayer.GetRealName() + "" + "\n\r" + GetString("DeathCmd.YourRole") + "" + $"{Utils.GetRoleName(PlayerControl.LocalPlayer.GetCustomRole())}" + "" + "\n\r" + GetString("DeathCmd.DeathReason") + "" + Utils.GetVitalText(PlayerControl.LocalPlayer.PlayerId) + "" + "\n\r" + "" + "\n\r" + GetString("DeathCmd.KillerName") + "" + killerName + "" + "\n\r" + GetString("DeathCmd.KillerRole") + "" + $"{killerRole}" + "", sendTo: PlayerControl.LocalPlayer.PlayerId); - - break; - } - - - case "/m": - case "/myrole": - case "/minhafunção": - case "/м": + case "/死亡": + canceled = true; + Logger.Info($"PlayerControl.LocalPlayer.PlayerId: {PlayerControl.LocalPlayer.PlayerId}", "/death command"); + if (GameStates.IsLobby) + { + Logger.Info("IsLobby", "/death command"); + Utils.SendMessage(text: GetString("Message.CanNotUseInLobby"), sendTo: PlayerControl.LocalPlayer.PlayerId); + break; + } + else if (PlayerControl.LocalPlayer.IsAlive()) + { + Logger.Info("IsAlive", "/death command"); + Utils.SendMessage(text: GetString("DeathCmd.HeyPlayer") + "" + PlayerControl.LocalPlayer.GetRealName() + "" + GetString("DeathCmd.YouAreRole") + "" + $"{Utils.GetRoleName(PlayerControl.LocalPlayer.GetCustomRole())}" + "\n\n" + GetString("DeathCmd.NotDead"), sendTo: PlayerControl.LocalPlayer.PlayerId); + break; + } + else if (Main.PlayerStates[PlayerControl.LocalPlayer.PlayerId].deathReason == PlayerState.DeathReason.Vote) + { + Logger.Info("DeathReason.Vote", "/death command"); + Utils.SendMessage(text: GetString("DeathCmd.YourName") + "" + PlayerControl.LocalPlayer.GetRealName() + "" + "\n\r" + GetString("DeathCmd.YourRole") + "" + $"{Utils.GetRoleName(PlayerControl.LocalPlayer.GetCustomRole())}" + "" + "\n\r" + GetString("DeathCmd.Ejected"), sendTo: PlayerControl.LocalPlayer.PlayerId); + break; + } + else if (Main.PlayerStates[PlayerControl.LocalPlayer.PlayerId].deathReason == PlayerState.DeathReason.Shrouded) + { + Logger.Info("DeathReason.Shrouded", "/death command"); + Utils.SendMessage(text: GetString("DeathCmd.YourName") + "" + PlayerControl.LocalPlayer.GetRealName() + "" + "\n\r" + GetString("DeathCmd.YourRole") + "" + $"{Utils.GetRoleName(PlayerControl.LocalPlayer.GetCustomRole())}" + "" + "\n\r" + GetString("DeathCmd.Shrouded"), sendTo: PlayerControl.LocalPlayer.PlayerId); + break; + } + else if (Main.PlayerStates[PlayerControl.LocalPlayer.PlayerId].deathReason == PlayerState.DeathReason.FollowingSuicide) + { + Logger.Info("DeathReason.FollowingSuicide", "/death command"); + Utils.SendMessage(text: GetString("DeathCmd.YourName") + "" + PlayerControl.LocalPlayer.GetRealName() + "" + "\n\r" + GetString("DeathCmd.YourRole") + "" + $"{Utils.GetRoleName(PlayerControl.LocalPlayer.GetCustomRole())}" + "" + "\n\r" + GetString("DeathCmd.Lovers"), sendTo: PlayerControl.LocalPlayer.PlayerId); + break; + } + else + { + Logger.Info("GetRealKiller()", "/death command"); + var killer = PlayerControl.LocalPlayer.GetRealKiller(out var MurderRole); + string killerName = killer == null ? "N/A" : killer.GetRealName(); + string killerRole = killer == null ? "N/A" : Utils.GetRoleName(MurderRole); + Utils.SendMessage(text: GetString("DeathCmd.YourName") + "" + PlayerControl.LocalPlayer.GetRealName() + "" + "\n\r" + GetString("DeathCmd.YourRole") + "" + $"{Utils.GetRoleName(PlayerControl.LocalPlayer.GetCustomRole())}" + "" + "\n\r" + GetString("DeathCmd.DeathReason") + "" + Utils.GetVitalText(PlayerControl.LocalPlayer.PlayerId) + "" + "\n\r" + "" + "\n\r" + GetString("DeathCmd.KillerName") + "" + killerName + "" + "\n\r" + GetString("DeathCmd.KillerRole") + "" + $"{killerRole}" + "", sendTo: PlayerControl.LocalPlayer.PlayerId); + + break; + } + + + case "/m": + case "/myrole": + case "/minhafunção": + case "/м": case "/мояроль": case "/身份": case "/我": case "/我的身份": - case "/我的职业": - canceled = true; - var role = PlayerControl.LocalPlayer.GetCustomRole(); - if (GameStates.IsInGame) - { - var lp = PlayerControl.LocalPlayer; - var Des = lp.GetRoleInfo(true); - var title = $"" + role.GetRoleTitle() + "\n"; - var Conf = new StringBuilder(); - var Sub = new StringBuilder(); - var rlHex = Utils.GetRoleColorCode(role); - var SubTitle = $"" + GetString("YourAddon") + "\n"; - - if (Options.CustomRoleSpawnChances.TryGetValue(role, out var opt)) - Utils.ShowChildrenSettings(Options.CustomRoleSpawnChances[role], ref Conf); - var cleared = Conf.ToString(); - var Setting = $"{GetString(role.ToString())} {GetString("Settings:")}\n"; - Conf.Clear().Append($"" + $"" + Setting + cleared + "" + ""); - - - foreach (var subRole in Main.PlayerStates[lp.PlayerId].SubRoles.ToArray()) - Sub.Append($"\n\n" + $"" + Utils.GetRoleTitle(subRole) + Utils.GetInfoLong(subRole) + ""); - - if (Sub.ToString() != string.Empty) - { - var ACleared = Sub.ToString().Remove(0, 2); - ACleared = ACleared.Length > 1200 ? $"" + ACleared.RemoveHtmlTags() + "" : ACleared; - Sub.Clear().Append(ACleared); - } - - Utils.SendMessage(Des, lp.PlayerId, title, noReplay: true); - Utils.SendMessage("", lp.PlayerId, Conf.ToString(), noReplay: true); - if (Sub.ToString() != string.Empty) Utils.SendMessage(Sub.ToString(), lp.PlayerId, SubTitle, noReplay: true); - } - else - Utils.SendMessage((PlayerControl.LocalPlayer.FriendCode.GetDevUser().HasTag() ? "\n" : string.Empty) + GetString("Message.CanNotUseInLobby"), PlayerControl.LocalPlayer.PlayerId); - break; - + case "/我的职业": + canceled = true; + var role = PlayerControl.LocalPlayer.GetCustomRole(); + if (GameStates.IsInGame) + { + var lp = PlayerControl.LocalPlayer; + var Des = lp.GetRoleInfo(true); + var title = $"" + role.GetRoleTitle() + "\n"; + var Conf = new StringBuilder(); + var Sub = new StringBuilder(); + var rlHex = Utils.GetRoleColorCode(role); + var SubTitle = $"" + GetString("YourAddon") + "\n"; + + if (Options.CustomRoleSpawnChances.TryGetValue(role, out var opt)) + Utils.ShowChildrenSettings(Options.CustomRoleSpawnChances[role], ref Conf); + var cleared = Conf.ToString(); + var Setting = $"{GetString(role.ToString())} {GetString("Settings:")}\n"; + Conf.Clear().Append($"" + $"" + Setting + cleared + "" + ""); + + + foreach (var subRole in Main.PlayerStates[lp.PlayerId].SubRoles.ToArray()) + Sub.Append($"\n\n" + $"" + Utils.GetRoleTitle(subRole) + Utils.GetInfoLong(subRole) + ""); + + if (Sub.ToString() != string.Empty) + { + var ACleared = Sub.ToString().Remove(0, 2); + ACleared = ACleared.Length > 1200 ? $"" + ACleared.RemoveHtmlTags() + "" : ACleared; + Sub.Clear().Append(ACleared); + } + + Utils.SendMessage(Des, lp.PlayerId, title, noReplay: true); + Utils.SendMessage("", lp.PlayerId, Conf.ToString(), noReplay: true); + if (Sub.ToString() != string.Empty) Utils.SendMessage(Sub.ToString(), lp.PlayerId, SubTitle, noReplay: true); + } + else + Utils.SendMessage((PlayerControl.LocalPlayer.FriendCode.GetDevUser().HasTag() ? "\n" : string.Empty) + GetString("Message.CanNotUseInLobby"), PlayerControl.LocalPlayer.PlayerId); + break; + case "/me": case "/我的权限": - case "/权限": - canceled = true; - subArgs = text.Length == 3 ? string.Empty : text.Remove(0, 3); - string Devbox = PlayerControl.LocalPlayer.FriendCode.GetDevUser().DeBug ? "<#10e341>" : "<#e31010>"; - string UpBox = PlayerControl.LocalPlayer.FriendCode.GetDevUser().IsUp ? "<#10e341>" : "<#e31010>"; - string ColorBox = PlayerControl.LocalPlayer.FriendCode.GetDevUser().ColorCmd ? "<#10e341>" : "<#e31010>"; - - if (string.IsNullOrEmpty(subArgs)) - { - HudManager.Instance.Chat.AddChat(PlayerControl.LocalPlayer, (PlayerControl.LocalPlayer.FriendCode.GetDevUser().HasTag() ? "\n" : string.Empty) + $"{string.Format(GetString("Message.MeCommandInfo"), PlayerControl.LocalPlayer.PlayerId, PlayerControl.LocalPlayer.GetRealName(clientData: true), PlayerControl.LocalPlayer.GetClient().FriendCode, PlayerControl.LocalPlayer.GetClient().GetHashedPuid(), PlayerControl.LocalPlayer.FriendCode.GetDevUser().GetUserType(), Devbox, UpBox, ColorBox)}"); - } - else - { - if (byte.TryParse(subArgs, out byte meid)) - { - if (meid != PlayerControl.LocalPlayer.PlayerId) - { - var targetplayer = Utils.GetPlayerById(meid); - if (targetplayer != null && targetplayer.GetClient() != null) - { - HudManager.Instance.Chat.AddChat(PlayerControl.LocalPlayer, (PlayerControl.LocalPlayer.FriendCode.GetDevUser().HasTag() ? "\n" : string.Empty) + $"{string.Format(GetString("Message.MeCommandTargetInfo"), targetplayer.PlayerId, targetplayer.GetRealName(clientData: true), targetplayer.GetClient().FriendCode, targetplayer.GetClient().GetHashedPuid(), targetplayer.FriendCode.GetDevUser().GetUserType())}"); - } - else - { - HudManager.Instance.Chat.AddChat(PlayerControl.LocalPlayer, (PlayerControl.LocalPlayer.FriendCode.GetDevUser().HasTag() ? "\n" : string.Empty) + $"{(GetString("Message.MeCommandInvalidID"))}"); - } - } - else - { - HudManager.Instance.Chat.AddChat(PlayerControl.LocalPlayer, (PlayerControl.LocalPlayer.FriendCode.GetDevUser().HasTag() ? "\n" : string.Empty) + $"{string.Format(GetString("Message.MeCommandInfo"), PlayerControl.LocalPlayer.PlayerId, PlayerControl.LocalPlayer.GetRealName(clientData: true), PlayerControl.LocalPlayer.GetClient().FriendCode, PlayerControl.LocalPlayer.GetClient().GetHashedPuid(), PlayerControl.LocalPlayer.FriendCode.GetDevUser().GetUserType(), Devbox, UpBox, ColorBox)}"); - } - } - else - { - HudManager.Instance.Chat.AddChat(PlayerControl.LocalPlayer, (PlayerControl.LocalPlayer.FriendCode.GetDevUser().HasTag() ? "\n" : string.Empty) + $"{(GetString("Message.MeCommandInvalidID"))}"); - } - } - break; - - case "/t": - case "/template": - case "/шаблон": + case "/权限": + canceled = true; + subArgs = text.Length == 3 ? string.Empty : text.Remove(0, 3); + string Devbox = PlayerControl.LocalPlayer.FriendCode.GetDevUser().DeBug ? "<#10e341>" : "<#e31010>"; + string UpBox = PlayerControl.LocalPlayer.FriendCode.GetDevUser().IsUp ? "<#10e341>" : "<#e31010>"; + string ColorBox = PlayerControl.LocalPlayer.FriendCode.GetDevUser().ColorCmd ? "<#10e341>" : "<#e31010>"; + + if (string.IsNullOrEmpty(subArgs)) + { + HudManager.Instance.Chat.AddChat(PlayerControl.LocalPlayer, (PlayerControl.LocalPlayer.FriendCode.GetDevUser().HasTag() ? "\n" : string.Empty) + $"{string.Format(GetString("Message.MeCommandInfo"), PlayerControl.LocalPlayer.PlayerId, PlayerControl.LocalPlayer.GetRealName(clientData: true), PlayerControl.LocalPlayer.GetClient().FriendCode, PlayerControl.LocalPlayer.GetClient().GetHashedPuid(), PlayerControl.LocalPlayer.FriendCode.GetDevUser().GetUserType(), Devbox, UpBox, ColorBox)}"); + } + else + { + if (byte.TryParse(subArgs, out byte meid)) + { + if (meid != PlayerControl.LocalPlayer.PlayerId) + { + var targetplayer = Utils.GetPlayerById(meid); + if (targetplayer != null && targetplayer.GetClient() != null) + { + HudManager.Instance.Chat.AddChat(PlayerControl.LocalPlayer, (PlayerControl.LocalPlayer.FriendCode.GetDevUser().HasTag() ? "\n" : string.Empty) + $"{string.Format(GetString("Message.MeCommandTargetInfo"), targetplayer.PlayerId, targetplayer.GetRealName(clientData: true), targetplayer.GetClient().FriendCode, targetplayer.GetClient().GetHashedPuid(), targetplayer.FriendCode.GetDevUser().GetUserType())}"); + } + else + { + HudManager.Instance.Chat.AddChat(PlayerControl.LocalPlayer, (PlayerControl.LocalPlayer.FriendCode.GetDevUser().HasTag() ? "\n" : string.Empty) + $"{(GetString("Message.MeCommandInvalidID"))}"); + } + } + else + { + HudManager.Instance.Chat.AddChat(PlayerControl.LocalPlayer, (PlayerControl.LocalPlayer.FriendCode.GetDevUser().HasTag() ? "\n" : string.Empty) + $"{string.Format(GetString("Message.MeCommandInfo"), PlayerControl.LocalPlayer.PlayerId, PlayerControl.LocalPlayer.GetRealName(clientData: true), PlayerControl.LocalPlayer.GetClient().FriendCode, PlayerControl.LocalPlayer.GetClient().GetHashedPuid(), PlayerControl.LocalPlayer.FriendCode.GetDevUser().GetUserType(), Devbox, UpBox, ColorBox)}"); + } + } + else + { + HudManager.Instance.Chat.AddChat(PlayerControl.LocalPlayer, (PlayerControl.LocalPlayer.FriendCode.GetDevUser().HasTag() ? "\n" : string.Empty) + $"{(GetString("Message.MeCommandInvalidID"))}"); + } + } + break; + + case "/t": + case "/template": + case "/шаблон": case "/пример": case "/模板": - case "/模板信息": - canceled = true; - if (args.Length > 1) TemplateManager.SendTemplate(args[1]); - else Utils.SendMessage($"{GetString("ForExample")}:\n{args[0]} test", PlayerControl.LocalPlayer.PlayerId); - break; - - case "/mw": + case "/模板信息": + canceled = true; + if (args.Length > 1) TemplateManager.SendTemplate(args[1]); + else Utils.SendMessage($"{GetString("ForExample")}:\n{args[0]} test", PlayerControl.LocalPlayer.PlayerId); + break; + + case "/mw": case "/messagewait": case "/消息等待时间": - case "/消息冷却": - canceled = true; - if (args.Length > 1 && int.TryParse(args[1], out int sec)) - { - Main.MessageWait.Value = sec; - Utils.SendMessage(string.Format(GetString("Message.SetToSeconds"), sec), 0); - } - else Utils.SendMessage($"{GetString("Message.MessageWaitHelp")}\n{GetString("ForExample")}:\n{args[0]} 3", 0); - break; - + case "/消息冷却": + canceled = true; + if (args.Length > 1 && int.TryParse(args[1], out int sec)) + { + Main.MessageWait.Value = sec; + Utils.SendMessage(string.Format(GetString("Message.SetToSeconds"), sec), 0); + } + else Utils.SendMessage($"{GetString("Message.MessageWaitHelp")}\n{GetString("ForExample")}:\n{args[0]} 3", 0); + break; + case "/tpout": case "/传送出": - case "/传出": - canceled = true; - if (!GameStates.IsLobby) break; - if (!Options.PlayerCanUseTP.GetBool()) - { - Utils.SendMessage(GetString("DisableUseCommand"), PlayerControl.LocalPlayer.PlayerId); - break; - } - PlayerControl.LocalPlayer.RpcTeleport(new Vector2(0.1f, 3.8f)); - break; + case "/传出": + canceled = true; + if (!GameStates.IsLobby) break; + if (!Options.PlayerCanUseTP.GetBool()) + { + Utils.SendMessage(GetString("DisableUseCommand"), PlayerControl.LocalPlayer.PlayerId); + break; + } + PlayerControl.LocalPlayer.RpcTeleport(new Vector2(0.1f, 3.8f)); + break; case "/tpin": case "/传进": - case "/传送进": - canceled = true; - if (!GameStates.IsLobby) break; - if (!Options.PlayerCanUseTP.GetBool()) - { - Utils.SendMessage(GetString("DisableUseCommand"), PlayerControl.LocalPlayer.PlayerId); - break; - } - PlayerControl.LocalPlayer.RpcTeleport(new Vector2(-0.2f, 1.3f)); - break; - - case "/say": - case "/s": - case "/с": + case "/传送进": + canceled = true; + if (!GameStates.IsLobby) break; + if (!Options.PlayerCanUseTP.GetBool()) + { + Utils.SendMessage(GetString("DisableUseCommand"), PlayerControl.LocalPlayer.PlayerId); + break; + } + PlayerControl.LocalPlayer.RpcTeleport(new Vector2(-0.2f, 1.3f)); + break; + + case "/say": + case "/s": + case "/с": case "/сказать": - case "/说": - canceled = true; - if (args.Length > 1) - Utils.SendMessage(args.Skip(1).Join(delimiter: " "), title: $"{GetString("MessageFromTheHost")} ~ {PlayerControl.LocalPlayer.GetRealName(clientData: true)}"); - break; - + case "/说": + canceled = true; + if (args.Length > 1) + Utils.SendMessage(args.Skip(1).Join(delimiter: " "), title: $"{GetString("MessageFromTheHost")} ~ {PlayerControl.LocalPlayer.GetRealName(clientData: true)}"); + break; + case "/mid": case "/玩家列表": case "/玩家信息": - case "/玩家编号列表": - canceled = true; - string msgText1 = GetString("PlayerIdList"); - foreach (var pc in Main.AllPlayerControls) - { - if (pc == null) continue; - msgText1 += "\n" + pc.PlayerId.ToString() + " → " + pc.GetRealName(); - } - Utils.SendMessage(msgText1, PlayerControl.LocalPlayer.PlayerId); - break; - - case "/ban": - case "/banir": - case "/бан": + case "/玩家编号列表": + canceled = true; + string msgText1 = GetString("PlayerIdList"); + foreach (var pc in Main.AllPlayerControls) + { + if (pc == null) continue; + msgText1 += "\n" + pc.PlayerId.ToString() + " → " + pc.GetRealName(); + } + Utils.SendMessage(msgText1, PlayerControl.LocalPlayer.PlayerId); + break; + + case "/ban": + case "/banir": + case "/бан": case "/забанить": - case "/封禁": - canceled = true; - - string banReason = ""; - if (args.Length < 3) - { - Utils.SendMessage(GetString("BanCommandNoReason"), PlayerControl.LocalPlayer.PlayerId); - break; - } - else - { - subArgs = args[1]; - banReason = string.Join(" ", args.Skip(2)); - } - //subArgs = args.Length < 2 ? "" : args[1]; - if (string.IsNullOrEmpty(subArgs) || !byte.TryParse(subArgs, out byte banPlayerId)) - { - Utils.SendMessage(GetString("BanCommandInvalidID"), PlayerControl.LocalPlayer.PlayerId); - break; - } - - if (banPlayerId == 0) - { - Utils.SendMessage(GetString("BanCommandBanHost"), PlayerControl.LocalPlayer.PlayerId); - break; - } - - var bannedPlayer = Utils.GetPlayerById(banPlayerId); - if (bannedPlayer == null) - { - Utils.SendMessage(GetString("BanCommandInvalidID"), PlayerControl.LocalPlayer.PlayerId); - break; - } - - // Ban the specified player - AmongUsClient.Instance.KickPlayer(bannedPlayer.GetClientId(), true); - string bannedPlayerName = bannedPlayer.GetRealName(); - string textToSend1 = $"{bannedPlayerName} {GetString("BanCommandBanned")}{PlayerControl.LocalPlayer.name} \nReason: {banReason}\n"; - if (GameStates.IsInGame) - { - textToSend1 += $" {GetString("BanCommandBannedRole")} {GetString(bannedPlayer.GetCustomRole().ToString())}"; - } - Utils.SendMessage(textToSend1); - //string moderatorName = PlayerControl.LocalPlayer.GetRealName().ToString(); - //int startIndex = moderatorName.IndexOf("♥") + "♥".Length; - //moderatorName = moderatorName.Substring(startIndex); - //string extractedString = - string moderatorFriendCode = PlayerControl.LocalPlayer.FriendCode.ToString(); - string bannedPlayerFriendCode = bannedPlayer.FriendCode.ToString(); - string modLogname = Main.AllPlayerNames.TryGetValue(PlayerControl.LocalPlayer.PlayerId, out var n1) ? n1 : ""; - string banlogname = Main.AllPlayerNames.TryGetValue(bannedPlayer.PlayerId, out var n11) ? n11 : ""; - string logMessage = $"[{DateTime.Now}] {moderatorFriendCode},{modLogname} Banned: {bannedPlayerFriendCode},{banlogname} Reason: {banReason}"; - File.AppendAllText(modLogFiles, logMessage + Environment.NewLine); - break; - - case "/warn": - case "/aviso": - case "/варн": - case "/пред": + case "/封禁": + canceled = true; + + string banReason = ""; + if (args.Length < 3) + { + Utils.SendMessage(GetString("BanCommandNoReason"), PlayerControl.LocalPlayer.PlayerId); + break; + } + else + { + subArgs = args[1]; + banReason = string.Join(" ", args.Skip(2)); + } + //subArgs = args.Length < 2 ? "" : args[1]; + if (string.IsNullOrEmpty(subArgs) || !byte.TryParse(subArgs, out byte banPlayerId)) + { + Utils.SendMessage(GetString("BanCommandInvalidID"), PlayerControl.LocalPlayer.PlayerId); + break; + } + + if (banPlayerId == 0) + { + Utils.SendMessage(GetString("BanCommandBanHost"), PlayerControl.LocalPlayer.PlayerId); + break; + } + + var bannedPlayer = Utils.GetPlayerById(banPlayerId); + if (bannedPlayer == null) + { + Utils.SendMessage(GetString("BanCommandInvalidID"), PlayerControl.LocalPlayer.PlayerId); + break; + } + + // Ban the specified player + AmongUsClient.Instance.KickPlayer(bannedPlayer.GetClientId(), true); + string bannedPlayerName = bannedPlayer.GetRealName(); + string textToSend1 = $"{bannedPlayerName} {GetString("BanCommandBanned")}{PlayerControl.LocalPlayer.name} \nReason: {banReason}\n"; + if (GameStates.IsInGame) + { + textToSend1 += $" {GetString("BanCommandBannedRole")} {GetString(bannedPlayer.GetCustomRole().ToString())}"; + } + Utils.SendMessage(textToSend1); + //string moderatorName = PlayerControl.LocalPlayer.GetRealName().ToString(); + //int startIndex = moderatorName.IndexOf("♥") + "♥".Length; + //moderatorName = moderatorName.Substring(startIndex); + //string extractedString = + string moderatorFriendCode = PlayerControl.LocalPlayer.FriendCode.ToString(); + string bannedPlayerFriendCode = bannedPlayer.FriendCode.ToString(); + string modLogname = Main.AllPlayerNames.TryGetValue(PlayerControl.LocalPlayer.PlayerId, out var n1) ? n1 : ""; + string banlogname = Main.AllPlayerNames.TryGetValue(bannedPlayer.PlayerId, out var n11) ? n11 : ""; + string logMessage = $"[{DateTime.Now}] {moderatorFriendCode},{modLogname} Banned: {bannedPlayerFriendCode},{banlogname} Reason: {banReason}"; + File.AppendAllText(modLogFiles, logMessage + Environment.NewLine); + break; + + case "/warn": + case "/aviso": + case "/варн": + case "/пред": case "/предупредить": case "/警告": - case "/提醒": - canceled = true; - subArgs = args.Length < 2 ? "" : args[1]; - if (string.IsNullOrEmpty(subArgs) || !byte.TryParse(subArgs, out byte warnPlayerId)) - { - Utils.SendMessage(GetString("WarnCommandInvalidID"), PlayerControl.LocalPlayer.PlayerId); - break; - } - if (warnPlayerId == 0) - { - Utils.SendMessage(GetString("WarnCommandWarnHost"), PlayerControl.LocalPlayer.PlayerId); - break; - } - - var warnedPlayer = Utils.GetPlayerById(warnPlayerId); - if (warnedPlayer == null) - { - Utils.SendMessage(GetString("WarnCommandInvalidID"), PlayerControl.LocalPlayer.PlayerId); - break; - } - - // warn the specified player - string textToSend2 = ""; - string warnReason = "Reason : Not specified\n"; - string warnedPlayerName = warnedPlayer.GetRealName(); - //textToSend2 = $" {warnedPlayerName} {GetString("WarnCommandWarned")} ~{player.name}"; - if (args.Length > 2) - { - warnReason = "Reason : " + string.Join(" ", args.Skip(2)) + "\n"; - } - else - { - Utils.SendMessage(GetString("WarnExample"), PlayerControl.LocalPlayer.PlayerId); - } - textToSend2 = $" {warnedPlayerName} {GetString("WarnCommandWarned")} {warnReason} ~{PlayerControl.LocalPlayer.name}"; - Utils.SendMessage(textToSend2); - //string moderatorName1 = PlayerControl.LocalPlayer.GetRealName().ToString(); - //int startIndex1 = moderatorName1.IndexOf("♥") + "♥".Length; - //moderatorName1 = moderatorName1.Substring(startIndex1); - string modLogname1 = Main.AllPlayerNames.TryGetValue(PlayerControl.LocalPlayer.PlayerId, out var n2) ? n2 : ""; - string warnlogname = Main.AllPlayerNames.TryGetValue(warnedPlayer.PlayerId, out var n12) ? n12 : ""; - - string moderatorFriendCode1 = PlayerControl.LocalPlayer.FriendCode.ToString(); - string warnedPlayerFriendCode = warnedPlayer.FriendCode.ToString(); - string warnedPlayerHashPuid = warnedPlayer.GetClient().GetHashedPuid(); - string logMessage1 = $"[{DateTime.Now}] {moderatorFriendCode1},{modLogname1} Warned: {warnedPlayerFriendCode},{warnedPlayerHashPuid},{warnlogname} Reason: {warnReason}"; - File.AppendAllText(modLogFiles, logMessage1 + Environment.NewLine); - - break; - - case "/kick": - case "/expulsar": - case "/кик": - case "/кикнуть": + case "/提醒": + canceled = true; + subArgs = args.Length < 2 ? "" : args[1]; + if (string.IsNullOrEmpty(subArgs) || !byte.TryParse(subArgs, out byte warnPlayerId)) + { + Utils.SendMessage(GetString("WarnCommandInvalidID"), PlayerControl.LocalPlayer.PlayerId); + break; + } + if (warnPlayerId == 0) + { + Utils.SendMessage(GetString("WarnCommandWarnHost"), PlayerControl.LocalPlayer.PlayerId); + break; + } + + var warnedPlayer = Utils.GetPlayerById(warnPlayerId); + if (warnedPlayer == null) + { + Utils.SendMessage(GetString("WarnCommandInvalidID"), PlayerControl.LocalPlayer.PlayerId); + break; + } + + // warn the specified player + string textToSend2 = ""; + string warnReason = "Reason : Not specified\n"; + string warnedPlayerName = warnedPlayer.GetRealName(); + //textToSend2 = $" {warnedPlayerName} {GetString("WarnCommandWarned")} ~{player.name}"; + if (args.Length > 2) + { + warnReason = "Reason : " + string.Join(" ", args.Skip(2)) + "\n"; + } + else + { + Utils.SendMessage(GetString("WarnExample"), PlayerControl.LocalPlayer.PlayerId); + } + textToSend2 = $" {warnedPlayerName} {GetString("WarnCommandWarned")} {warnReason} ~{PlayerControl.LocalPlayer.name}"; + Utils.SendMessage(textToSend2); + //string moderatorName1 = PlayerControl.LocalPlayer.GetRealName().ToString(); + //int startIndex1 = moderatorName1.IndexOf("♥") + "♥".Length; + //moderatorName1 = moderatorName1.Substring(startIndex1); + string modLogname1 = Main.AllPlayerNames.TryGetValue(PlayerControl.LocalPlayer.PlayerId, out var n2) ? n2 : ""; + string warnlogname = Main.AllPlayerNames.TryGetValue(warnedPlayer.PlayerId, out var n12) ? n12 : ""; + + string moderatorFriendCode1 = PlayerControl.LocalPlayer.FriendCode.ToString(); + string warnedPlayerFriendCode = warnedPlayer.FriendCode.ToString(); + string warnedPlayerHashPuid = warnedPlayer.GetClient().GetHashedPuid(); + string logMessage1 = $"[{DateTime.Now}] {moderatorFriendCode1},{modLogname1} Warned: {warnedPlayerFriendCode},{warnedPlayerHashPuid},{warnlogname} Reason: {warnReason}"; + File.AppendAllText(modLogFiles, logMessage1 + Environment.NewLine); + + break; + + case "/kick": + case "/expulsar": + case "/кик": + case "/кикнуть": case "/выгнать": case "/踢出": - case "/踢": - canceled = true; - subArgs = args.Length < 2 ? "" : args[1]; - if (string.IsNullOrEmpty(subArgs) || !byte.TryParse(subArgs, out byte kickPlayerId)) - { - Utils.SendMessage(GetString("KickCommandInvalidID"), PlayerControl.LocalPlayer.PlayerId); - break; - } - - if (kickPlayerId == 0) - { - Utils.SendMessage(GetString("KickCommandKickHost"), PlayerControl.LocalPlayer.PlayerId); - break; - } - - var kickedPlayer = Utils.GetPlayerById(kickPlayerId); - if (kickedPlayer == null) - { - Utils.SendMessage(GetString("KickCommandInvalidID"), PlayerControl.LocalPlayer.PlayerId); - break; - } - - // Kick the specified player - AmongUsClient.Instance.KickPlayer(kickedPlayer.GetClientId(), false); - string kickedPlayerName = kickedPlayer.GetRealName(); - string kickReason = "Reason : Not specified\n"; - if (args.Length > 2) - kickReason = "Reason : " + string.Join(" ", args.Skip(2)) + "\n"; - else - { - Utils.SendMessage("Use /kick [id] [reason] in future. \nExample :-\n /kick 5 not following rules", PlayerControl.LocalPlayer.PlayerId); - } - string textToSend = $"{kickedPlayerName} {GetString("KickCommandKicked")} {PlayerControl.LocalPlayer.name} \n {kickReason}"; - - if (GameStates.IsInGame) - { - textToSend += $" {GetString("KickCommandKickedRole")} {GetString(kickedPlayer.GetCustomRole().ToString())}"; - } - Utils.SendMessage(textToSend); - //string moderatorName2 = PlayerControl.LocalPlayer.GetRealName().ToString(); - //int startIndex2 = moderatorName2.IndexOf("♥") + "♥".Length; - //moderatorName2 = moderatorName2.Substring(startIndex2); - - string modLogname2 = Main.AllPlayerNames.TryGetValue(PlayerControl.LocalPlayer.PlayerId, out var n3) ? n3 : ""; - string kicklogname = Main.AllPlayerNames.TryGetValue(kickedPlayer.PlayerId, out var n13) ? n13 : ""; - - string moderatorFriendCode2 = PlayerControl.LocalPlayer.FriendCode.ToString(); - string kickedPlayerFriendCode = kickedPlayer.FriendCode.ToString(); - string kickedPlayerHashPuid = kickedPlayer.GetClient().GetHashedPuid(); - string logMessage2 = $"[{DateTime.Now}] {moderatorFriendCode2},{modLogname2} Kicked: {kickedPlayerFriendCode},{kickedPlayerHashPuid},{kicklogname} Reason: {kickReason}"; - File.AppendAllText(modLogFiles, logMessage2 + Environment.NewLine); - - break; - - case "/tagcolor": + case "/踢": + canceled = true; + subArgs = args.Length < 2 ? "" : args[1]; + if (string.IsNullOrEmpty(subArgs) || !byte.TryParse(subArgs, out byte kickPlayerId)) + { + Utils.SendMessage(GetString("KickCommandInvalidID"), PlayerControl.LocalPlayer.PlayerId); + break; + } + + if (kickPlayerId == 0) + { + Utils.SendMessage(GetString("KickCommandKickHost"), PlayerControl.LocalPlayer.PlayerId); + break; + } + + var kickedPlayer = Utils.GetPlayerById(kickPlayerId); + if (kickedPlayer == null) + { + Utils.SendMessage(GetString("KickCommandInvalidID"), PlayerControl.LocalPlayer.PlayerId); + break; + } + + // Kick the specified player + AmongUsClient.Instance.KickPlayer(kickedPlayer.GetClientId(), false); + string kickedPlayerName = kickedPlayer.GetRealName(); + string kickReason = "Reason : Not specified\n"; + if (args.Length > 2) + kickReason = "Reason : " + string.Join(" ", args.Skip(2)) + "\n"; + else + { + Utils.SendMessage("Use /kick [id] [reason] in future. \nExample :-\n /kick 5 not following rules", PlayerControl.LocalPlayer.PlayerId); + } + string textToSend = $"{kickedPlayerName} {GetString("KickCommandKicked")} {PlayerControl.LocalPlayer.name} \n {kickReason}"; + + if (GameStates.IsInGame) + { + textToSend += $" {GetString("KickCommandKickedRole")} {GetString(kickedPlayer.GetCustomRole().ToString())}"; + } + Utils.SendMessage(textToSend); + //string moderatorName2 = PlayerControl.LocalPlayer.GetRealName().ToString(); + //int startIndex2 = moderatorName2.IndexOf("♥") + "♥".Length; + //moderatorName2 = moderatorName2.Substring(startIndex2); + + string modLogname2 = Main.AllPlayerNames.TryGetValue(PlayerControl.LocalPlayer.PlayerId, out var n3) ? n3 : ""; + string kicklogname = Main.AllPlayerNames.TryGetValue(kickedPlayer.PlayerId, out var n13) ? n13 : ""; + + string moderatorFriendCode2 = PlayerControl.LocalPlayer.FriendCode.ToString(); + string kickedPlayerFriendCode = kickedPlayer.FriendCode.ToString(); + string kickedPlayerHashPuid = kickedPlayer.GetClient().GetHashedPuid(); + string logMessage2 = $"[{DateTime.Now}] {moderatorFriendCode2},{modLogname2} Kicked: {kickedPlayerFriendCode},{kickedPlayerHashPuid},{kicklogname} Reason: {kickReason}"; + File.AppendAllText(modLogFiles, logMessage2 + Environment.NewLine); + + break; + + case "/tagcolor": case "/tagcolour": case "/标签颜色": - case "/附加名称颜色": - canceled = true; - string name = Main.AllPlayerNames.TryGetValue(PlayerControl.LocalPlayer.PlayerId, out var n) ? n : ""; - if (name == "") break; - if (!name.Contains('\r') && PlayerControl.LocalPlayer.FriendCode.GetDevUser().HasTag()) - { - if (!GameStates.IsLobby) - { - Utils.SendMessage(GetString("ColorCommandNoLobby"), PlayerControl.LocalPlayer.PlayerId); - break; - } - subArgs = args.Length != 2 ? "" : args[1]; - if (string.IsNullOrEmpty(subArgs) || !Utils.CheckColorHex(subArgs)) - { - Logger.Msg($"{subArgs}", "tagcolor"); - Utils.SendMessage(GetString("TagColorInvalidHexCode"), PlayerControl.LocalPlayer.PlayerId); - break; - } - string tagColorFilePath = $"{sponsorTagsFiles}/{PlayerControl.LocalPlayer.FriendCode}.txt"; - if (!File.Exists(tagColorFilePath)) - { - Logger.Msg($"File Not exist, creating file at {tagColorFilePath}", "tagcolor"); - File.Create(tagColorFilePath).Close(); - } - File.WriteAllText(tagColorFilePath, $"{subArgs}"); - } - break; - - case "/exe": - case "/уничтожить": - case "/повесить": - case "/казнить": - case "/казнь": + case "/附加名称颜色": + canceled = true; + string name = Main.AllPlayerNames.TryGetValue(PlayerControl.LocalPlayer.PlayerId, out var n) ? n : ""; + if (name == "") break; + if (!name.Contains('\r') && PlayerControl.LocalPlayer.FriendCode.GetDevUser().HasTag()) + { + if (!GameStates.IsLobby) + { + Utils.SendMessage(GetString("ColorCommandNoLobby"), PlayerControl.LocalPlayer.PlayerId); + break; + } + subArgs = args.Length != 2 ? "" : args[1]; + if (string.IsNullOrEmpty(subArgs) || !Utils.CheckColorHex(subArgs)) + { + Logger.Msg($"{subArgs}", "tagcolor"); + Utils.SendMessage(GetString("TagColorInvalidHexCode"), PlayerControl.LocalPlayer.PlayerId); + break; + } + string tagColorFilePath = $"{sponsorTagsFiles}/{PlayerControl.LocalPlayer.FriendCode}.txt"; + if (!File.Exists(tagColorFilePath)) + { + Logger.Msg($"File Not exist, creating file at {tagColorFilePath}", "tagcolor"); + File.Create(tagColorFilePath).Close(); + } + File.WriteAllText(tagColorFilePath, $"{subArgs}"); + } + break; + + case "/exe": + case "/уничтожить": + case "/повесить": + case "/казнить": + case "/казнь": case "/мут": case "/驱逐": - case "/驱赶": - canceled = true; - if (GameStates.IsLobby) - { - Utils.SendMessage(GetString("Message.CanNotUseInLobby"), PlayerControl.LocalPlayer.PlayerId); - break; - } - if (args.Length < 2 || !int.TryParse(args[1], out int id)) break; - var player = Utils.GetPlayerById(id); - if (player != null) - { - player.Data.IsDead = true; - player.SetDeathReason(PlayerState.DeathReason.etc); - player.SetRealKiller(PlayerControl.LocalPlayer); - Main.PlayerStates[player.PlayerId].SetDead(); - player.RpcExileV2(); - MurderPlayerPatch.AfterPlayerDeathTasks(PlayerControl.LocalPlayer, player, GameStates.IsMeeting); - - if (player.IsHost()) Utils.SendMessage(GetString("HostKillSelfByCommand"), title: $"{GetString("DefaultSystemMessageTitle")}"); - else Utils.SendMessage(string.Format(GetString("Message.Executed"), player.Data.PlayerName)); - } - break; - - case "/kill": - case "/matar": + case "/驱赶": + canceled = true; + if (GameStates.IsLobby) + { + Utils.SendMessage(GetString("Message.CanNotUseInLobby"), PlayerControl.LocalPlayer.PlayerId); + break; + } + if (args.Length < 2 || !int.TryParse(args[1], out int id)) break; + var player = Utils.GetPlayerById(id); + if (player != null) + { + player.Data.IsDead = true; + player.SetDeathReason(PlayerState.DeathReason.etc); + player.SetRealKiller(PlayerControl.LocalPlayer); + Main.PlayerStates[player.PlayerId].SetDead(); + player.RpcExileV2(); + MurderPlayerPatch.AfterPlayerDeathTasks(PlayerControl.LocalPlayer, player, GameStates.IsMeeting); + + if (player.IsHost()) Utils.SendMessage(GetString("HostKillSelfByCommand"), title: $"{GetString("DefaultSystemMessageTitle")}"); + else Utils.SendMessage(string.Format(GetString("Message.Executed"), player.Data.PlayerName)); + } + break; + + case "/kill": + case "/matar": case "/убить": case "/击杀": - case "/杀死": - canceled = true; - if (GameStates.IsLobby) - { - Utils.SendMessage(GetString("Message.CanNotUseInLobby"), PlayerControl.LocalPlayer.PlayerId); - break; - } - if (args.Length < 2 || !int.TryParse(args[1], out int id2)) break; - var target = Utils.GetPlayerById(id2); - if (target != null) - { - target.RpcMurderPlayer(target); - if (target.IsHost()) Utils.SendMessage(GetString("HostKillSelfByCommand"), title: $"{GetString("DefaultSystemMessageTitle")}"); - else Utils.SendMessage(string.Format(GetString("Message.Executed"), target.Data.PlayerName)); - - _ = new LateTask(() => - { - Utils.NotifyRoles(NoCache: true); - - }, 0.2f, "Update NotifyRoles players after /kill"); - } - break; - - case "/colour": - case "/color": - case "/cor": + case "/杀死": + canceled = true; + if (GameStates.IsLobby) + { + Utils.SendMessage(GetString("Message.CanNotUseInLobby"), PlayerControl.LocalPlayer.PlayerId); + break; + } + if (args.Length < 2 || !int.TryParse(args[1], out int id2)) break; + var target = Utils.GetPlayerById(id2); + if (target != null) + { + target.RpcMurderPlayer(target); + if (target.IsHost()) Utils.SendMessage(GetString("HostKillSelfByCommand"), title: $"{GetString("DefaultSystemMessageTitle")}"); + else Utils.SendMessage(string.Format(GetString("Message.Executed"), target.Data.PlayerName)); + + _ = new LateTask(() => + { + Utils.NotifyRoles(NoCache: true); + + }, 0.2f, "Update NotifyRoles players after /kill"); + } + break; + + case "/colour": + case "/color": + case "/cor": case "/цвет": case "/颜色": case "/更改颜色": case "/修改颜色": - case "/换颜色": - canceled = true; - if (GameStates.IsInGame) - { - Utils.SendMessage(GetString("Message.OnlyCanUseInLobby"), PlayerControl.LocalPlayer.PlayerId); - break; - } - subArgs = args.Length < 2 ? "" : args[1]; - var color = Utils.MsgToColor(subArgs, true); - if (color == byte.MaxValue) - { - Utils.SendMessage(GetString("IllegalColor"), PlayerControl.LocalPlayer.PlayerId); - break; - } - PlayerControl.LocalPlayer.RpcSetColor(color); - Utils.SendMessage(string.Format(GetString("Message.SetColor"), subArgs), PlayerControl.LocalPlayer.PlayerId); - break; - - case "/quit": - case "/qt": + case "/换颜色": + canceled = true; + if (GameStates.IsInGame) + { + Utils.SendMessage(GetString("Message.OnlyCanUseInLobby"), PlayerControl.LocalPlayer.PlayerId); + break; + } + subArgs = args.Length < 2 ? "" : args[1]; + var color = Utils.MsgToColor(subArgs, true); + if (color == byte.MaxValue) + { + Utils.SendMessage(GetString("IllegalColor"), PlayerControl.LocalPlayer.PlayerId); + break; + } + PlayerControl.LocalPlayer.RpcSetColor(color); + Utils.SendMessage(string.Format(GetString("Message.SetColor"), subArgs), PlayerControl.LocalPlayer.PlayerId); + break; + + case "/quit": + case "/qt": case "/sair": case "/退出": - case "/退": - canceled = true; - Utils.SendMessage(GetString("Message.CanNotUseByHost"), PlayerControl.LocalPlayer.PlayerId); - break; - + case "/退": + canceled = true; + Utils.SendMessage(GetString("Message.CanNotUseByHost"), PlayerControl.LocalPlayer.PlayerId); + break; + case "/xf": case "/修复": - case "/修": - canceled = true; - if (GameStates.IsLobby) - { - Utils.SendMessage(GetString("Message.CanNotUseInLobby"), PlayerControl.LocalPlayer.PlayerId); - break; - } - foreach (var pc in Main.AllPlayerControls) - { - if (pc.IsAlive()) continue; - - pc.RpcSetNameEx(pc.GetRealName(isMeeting: true)); - } - ChatUpdatePatch.DoBlockChat = false; - //Utils.NotifyRoles(isForMeeting: GameStates.IsMeeting, NoCache: true); - Utils.SendMessage(GetString("Message.TryFixName"), PlayerControl.LocalPlayer.PlayerId); - break; - - case "/id": + case "/修": + canceled = true; + if (GameStates.IsLobby) + { + Utils.SendMessage(GetString("Message.CanNotUseInLobby"), PlayerControl.LocalPlayer.PlayerId); + break; + } + foreach (var pc in Main.AllPlayerControls) + { + if (pc.IsAlive()) continue; + + pc.RpcSetNameEx(pc.GetRealName(isMeeting: true)); + } + ChatUpdatePatch.DoBlockChat = false; + //Utils.NotifyRoles(isForMeeting: GameStates.IsMeeting, NoCache: true); + Utils.SendMessage(GetString("Message.TryFixName"), PlayerControl.LocalPlayer.PlayerId); + break; + + case "/id": case "/айди": case "/编号": - case "/玩家编号": - canceled = true; - string msgText = GetString("PlayerIdList"); - foreach (var pc in Main.AllPlayerControls) - { - if (pc == null) continue; - msgText += "\n" + pc.PlayerId.ToString() + " → " + pc.GetRealName(); - } - Utils.SendMessage(msgText, PlayerControl.LocalPlayer.PlayerId); - break; - - /* - case "/qq": - canceled = true; - if (Main.newLobby) Cloud.ShareLobby(true); - else Utils.SendMessage("很抱歉,每个房间车队姬只会发一次", PlayerControl.LocalPlayer.PlayerId); - break; - */ - + case "/玩家编号": + canceled = true; + string msgText = GetString("PlayerIdList"); + foreach (var pc in Main.AllPlayerControls) + { + if (pc == null) continue; + msgText += "\n" + pc.PlayerId.ToString() + " → " + pc.GetRealName(); + } + Utils.SendMessage(msgText, PlayerControl.LocalPlayer.PlayerId); + break; + + /* + case "/qq": + canceled = true; + if (Main.newLobby) Cloud.ShareLobby(true); + else Utils.SendMessage("很抱歉,每个房间车队姬只会发一次", PlayerControl.LocalPlayer.PlayerId); + break; + */ + case "/setrole": case "/设置的职业": - case "/指定的职业": - canceled = true; - subArgs = text.Remove(0, 8); - SendRolesInfo(subArgs, PlayerControl.LocalPlayer.PlayerId, PlayerControl.LocalPlayer.FriendCode.GetDevUser().DeBug); - break; - - case "/changerole": + case "/指定的职业": + canceled = true; + subArgs = text.Remove(0, 8); + SendRolesInfo(subArgs, PlayerControl.LocalPlayer.PlayerId, PlayerControl.LocalPlayer.FriendCode.GetDevUser().DeBug); + break; + + case "/changerole": case "/mudarfunção": case "/改变职业": - case "/修改职业": - canceled = true; - if (GameStates.IsHideNSeek) break; - if (!(DebugModeManager.AmDebugger && GameStates.IsInGame)) break; - if (GameStates.IsOnlineGame && !PlayerControl.LocalPlayer.FriendCode.GetDevUser().DeBug) break; - subArgs = text.Remove(0, 11); + case "/修改职业": + canceled = true; + if (GameStates.IsHideNSeek) break; + if (!(DebugModeManager.AmDebugger && GameStates.IsInGame)) break; + if (GameStates.IsOnlineGame && !PlayerControl.LocalPlayer.FriendCode.GetDevUser().DeBug) break; + subArgs = text.Remove(0, 11); var setRole = FixRoleNameInput(subArgs).ToLower().Trim().Replace(" ", string.Empty); - Logger.Info(setRole, "changerole Input"); - foreach (var rl in CustomRolesHelper.AllRoles) - { - if (rl.IsVanilla()) continue; - var roleName = GetString(rl.ToString()).ToLower().Trim().TrimStart('*').Replace(" ", string.Empty); - //Logger.Info(roleName, "2"); - if (setRole == roleName) - { - PlayerControl.LocalPlayer.GetRoleClass()?.OnRemove(PlayerControl.LocalPlayer.PlayerId); - PlayerControl.LocalPlayer.RpcSetRole(rl.GetRoleTypes(), true); - PlayerControl.LocalPlayer.RpcSetCustomRole(rl); - PlayerControl.LocalPlayer.GetRoleClass().OnAdd(PlayerControl.LocalPlayer.PlayerId); - Utils.SendMessage(string.Format("Debug Set your role to {0}", rl.ToString()), PlayerControl.LocalPlayer.PlayerId); - Utils.NotifyRoles(NoCache: true); - Utils.MarkEveryoneDirtySettings(); - break; - } - } - break; - - case "/end": - case "/encerrar": + Logger.Info(setRole, "changerole Input"); + foreach (var rl in CustomRolesHelper.AllRoles) + { + if (rl.IsVanilla()) continue; + var roleName = GetString(rl.ToString()).ToLower().Trim().TrimStart('*').Replace(" ", string.Empty); + //Logger.Info(roleName, "2"); + if (setRole == roleName) + { + PlayerControl.LocalPlayer.GetRoleClass()?.OnRemove(PlayerControl.LocalPlayer.PlayerId); + PlayerControl.LocalPlayer.RpcSetRole(rl.GetRoleTypes(), true); + PlayerControl.LocalPlayer.RpcSetCustomRole(rl); + PlayerControl.LocalPlayer.GetRoleClass().OnAdd(PlayerControl.LocalPlayer.PlayerId); + Utils.SendMessage(string.Format("Debug Set your role to {0}", rl.ToString()), PlayerControl.LocalPlayer.PlayerId); + Utils.NotifyRoles(NoCache: true); + Utils.MarkEveryoneDirtySettings(); + break; + } + } + break; + + case "/end": + case "/encerrar": case "/завершить": case "/结束": - case "/结束游戏": - canceled = true; - CustomWinnerHolder.ResetAndSetWinner(CustomWinner.Draw); - GameManager.Instance.LogicFlow.CheckEndCriteria(); - break; + case "/结束游戏": + canceled = true; + CustomWinnerHolder.ResetAndSetWinner(CustomWinner.Draw); + GameManager.Instance.LogicFlow.CheckEndCriteria(); + break; case "/cosid": case "/装扮编号": - case "/衣服编号": - canceled = true; - var of = PlayerControl.LocalPlayer.Data.DefaultOutfit; - Logger.Warn($"ColorId: {of.ColorId}", "Get Cos Id"); - Logger.Warn($"PetId: {of.PetId}", "Get Cos Id"); - Logger.Warn($"HatId: {of.HatId}", "Get Cos Id"); - Logger.Warn($"SkinId: {of.SkinId}", "Get Cos Id"); - Logger.Warn($"VisorId: {of.VisorId}", "Get Cos Id"); - Logger.Warn($"NamePlateId: {of.NamePlateId}", "Get Cos Id"); - break; - - case "/mt": + case "/衣服编号": + canceled = true; + var of = PlayerControl.LocalPlayer.Data.DefaultOutfit; + Logger.Warn($"ColorId: {of.ColorId}", "Get Cos Id"); + Logger.Warn($"PetId: {of.PetId}", "Get Cos Id"); + Logger.Warn($"HatId: {of.HatId}", "Get Cos Id"); + Logger.Warn($"SkinId: {of.SkinId}", "Get Cos Id"); + Logger.Warn($"VisorId: {of.VisorId}", "Get Cos Id"); + Logger.Warn($"NamePlateId: {of.NamePlateId}", "Get Cos Id"); + break; + + case "/mt": case "/hy": case "/强制过会议": case "/强制跳过会议": case "/过会议": case "/结束会议": case "/强制结束会议": - case "/跳过会议": - canceled = true; - if (GameStates.IsMeeting) - { - MeetingHud.Instance.RpcClose(); - } - else - { - PlayerControl.LocalPlayer.NoCheckStartMeeting(null, force: true); - } - break; - + case "/跳过会议": + canceled = true; + if (GameStates.IsMeeting) + { + MeetingHud.Instance.RpcClose(); + } + else + { + PlayerControl.LocalPlayer.NoCheckStartMeeting(null, force: true); + } + break; + case "/cs": case "/播放声音": - case "/播放音效": - canceled = true; - subArgs = text.Remove(0, 3); - PlayerControl.LocalPlayer.RPCPlayCustomSound(subArgs.Trim()); - break; - + case "/播放音效": + canceled = true; + subArgs = text.Remove(0, 3); + PlayerControl.LocalPlayer.RPCPlayCustomSound(subArgs.Trim()); + break; + case "/sd": case "/播放音效给": - case "/播放声音给": - canceled = true; - subArgs = text.Remove(0, 3); - if (args.Length < 1 || !int.TryParse(args[1], out int sound1)) break; - RPC.PlaySoundRPC(PlayerControl.LocalPlayer.PlayerId, (Sounds)sound1); - break; - + case "/播放声音给": + canceled = true; + subArgs = text.Remove(0, 3); + if (args.Length < 1 || !int.TryParse(args[1], out int sound1)) break; + RPC.PlaySoundRPC(PlayerControl.LocalPlayer.PlayerId, (Sounds)sound1); + break; + case "/poll": case "/发起投票": - case "/执行投票": - canceled = true; - - - if (args.Length == 2 && args[1] == GetString("Replay") && Pollvotes.Any() && PollMSG != string.Empty) - { - Utils.SendMessage(PollMSG); - break; - } - - PollMSG = string.Empty; - Pollvotes.Clear(); - PollQuestions.Clear(); - PollVoted.Clear(); - Polltimer = 120f; - - static System.Collections.IEnumerator StartPollCountdown() - { - if (!Pollvotes.Any() || !GameStates.IsLobby) - { - Pollvotes.Clear(); - PollQuestions.Clear(); - PollVoted.Clear(); - - yield break; - } - bool playervoted = (Main.AllPlayerControls.Length - 1) > Pollvotes.Values.Sum(); - - - while (playervoted && Polltimer > 0f) - { - if (!Pollvotes.Any() || !GameStates.IsLobby) - { - Pollvotes.Clear(); - PollQuestions.Clear(); - PollVoted.Clear(); - - yield break; - } - playervoted = (Main.AllPlayerControls.Length - 1) > Pollvotes.Values.Sum(); - Polltimer -= Time.deltaTime; - yield return null; - } - - if (!Pollvotes.Any() || !GameStates.IsLobby) - { - Pollvotes.Clear(); - PollQuestions.Clear(); - PollVoted.Clear(); - - yield break; - } - - Logger.Info($"FINNISHED!! playervote?: {!playervoted} polltime?: {Polltimer <= 0}", "/poll - StartPollCountdown"); - - DetermineResults(); - } - - static void DetermineResults() - { - int basenum = Pollvotes.Values.Max(); - var winners = Pollvotes.Where(x => x.Value == basenum); - - string msg = ""; - - Color32 clr = new(47, 234, 45, 255); //Main.PlayerColors.First(x => x.Key == PlayerControl.LocalPlayer.PlayerId).Value; - var tytul = Utils.ColorString(clr, GetString("PollResultTitle")); - - if (winners.Count() == 1) - { - var losers = Pollvotes.Where(x => x.Key != winners.First().Key); - msg = string.Format(GetString("Poll.Result"), $"{winners.First().Key}{PollQuestions[winners.First().Key]}", winners.First().Value); - - for (int i = 0; i < losers.Count(); i++) - { - msg += $"\n{losers.ElementAt(i).Key} / {losers.ElementAt(i).Value} {PollQuestions[losers.ElementAt(i).Key]}"; - - } - msg += ""; - - - Utils.SendMessage(msg, title: tytul); - } - else - { - var tienum = Pollvotes.Values.Max(); - var tied = Pollvotes.Where(x => x.Value == tienum); - - for (int i = 0; i < (tied.Count() - 1); i++) - { + case "/执行投票": + canceled = true; + + + if (args.Length == 2 && args[1] == GetString("Replay") && Pollvotes.Any() && PollMSG != string.Empty) + { + Utils.SendMessage(PollMSG); + break; + } + + PollMSG = string.Empty; + Pollvotes.Clear(); + PollQuestions.Clear(); + PollVoted.Clear(); + Polltimer = 120f; + + static System.Collections.IEnumerator StartPollCountdown() + { + if (!Pollvotes.Any() || !GameStates.IsLobby) + { + Pollvotes.Clear(); + PollQuestions.Clear(); + PollVoted.Clear(); + + yield break; + } + bool playervoted = (Main.AllPlayerControls.Length - 1) > Pollvotes.Values.Sum(); + + + while (playervoted && Polltimer > 0f) + { + if (!Pollvotes.Any() || !GameStates.IsLobby) + { + Pollvotes.Clear(); + PollQuestions.Clear(); + PollVoted.Clear(); + + yield break; + } + playervoted = (Main.AllPlayerControls.Length - 1) > Pollvotes.Values.Sum(); + Polltimer -= Time.deltaTime; + yield return null; + } + + if (!Pollvotes.Any() || !GameStates.IsLobby) + { + Pollvotes.Clear(); + PollQuestions.Clear(); + PollVoted.Clear(); + + yield break; + } + + Logger.Info($"FINNISHED!! playervote?: {!playervoted} polltime?: {Polltimer <= 0}", "/poll - StartPollCountdown"); + + DetermineResults(); + } + + static void DetermineResults() + { + int basenum = Pollvotes.Values.Max(); + var winners = Pollvotes.Where(x => x.Value == basenum); + + string msg = ""; + + Color32 clr = new(47, 234, 45, 255); //Main.PlayerColors.First(x => x.Key == PlayerControl.LocalPlayer.PlayerId).Value; + var tytul = Utils.ColorString(clr, GetString("PollResultTitle")); + + if (winners.Count() == 1) + { + var losers = Pollvotes.Where(x => x.Key != winners.First().Key); + msg = string.Format(GetString("Poll.Result"), $"{winners.First().Key}{PollQuestions[winners.First().Key]}", winners.First().Value); + + for (int i = 0; i < losers.Count(); i++) + { + msg += $"\n{losers.ElementAt(i).Key} / {losers.ElementAt(i).Value} {PollQuestions[losers.ElementAt(i).Key]}"; + + } + msg += ""; + + + Utils.SendMessage(msg, title: tytul); + } + else + { + var tienum = Pollvotes.Values.Max(); + var tied = Pollvotes.Where(x => x.Value == tienum); + + for (int i = 0; i < (tied.Count() - 1); i++) + { msg += "\n" + tied.ElementAt(i).Key + PollQuestions[tied.ElementAt(i).Key] + " & "; - } - msg += "\n" + tied.Last().Key + PollQuestions[tied.Last().Key]; - - Utils.SendMessage(string.Format(GetString("Poll.Tied"), msg, tienum), title: tytul); - } - - Pollvotes.Clear(); - PollQuestions.Clear(); - PollVoted.Clear(); - } - - - if (Main.AllPlayerControls.Length < 3) - { - Utils.SendMessage(GetString("Poll.MissingPlayers"), PlayerControl.LocalPlayer.PlayerId); - break; - } - - if (!GameStates.IsLobby) - { - Utils.SendMessage(GetString("Poll.OnlyInLobby"), PlayerControl.LocalPlayer.PlayerId); - break; - } - - if (args.SkipWhile(x => !x.Contains('?')).ToArray().Length < 3 || !args.Any(x => x.Contains('?'))) - { - Utils.SendMessage(GetString("PollUsage"), PlayerControl.LocalPlayer.PlayerId); - break; - } - var resultat = args.TakeWhile(x => !x.Contains('?')).Concat(args.SkipWhile(x => !x.Contains('?')).Take(1)); - - string tytul = string.Join(" ", resultat.Skip(1)); - bool Longtitle = tytul.Length > 30; - tytul = Utils.ColorString(Palette.PlayerColors[PlayerControl.LocalPlayer.Data.DefaultOutfit.ColorId], tytul); - var altTitle = Utils.ColorString(new Color32(151, 198, 230, 255), GetString("PollTitle")); - - var ClearTIT = args.ToList(); - ClearTIT.RemoveRange(0, resultat.ToArray().Length); - - var Questions = ClearTIT.ToArray(); - string msg = ""; - - - if (Longtitle) msg += "" + tytul + "\n\n"; - for (int i = 0; i < Math.Clamp(Questions.Length, 2, 5); i++) - { - msg += Utils.ColorString(RndCLR(), $"{char.ToUpper((char)(i + 65))}) {Questions[i]}\n"); - Pollvotes[char.ToUpper((char)(i + 65))] = 0; - PollQuestions[char.ToUpper((char)(i + 65))] = $"〖 {Questions[i]} 〗"; - } - msg += $"\n{GetString("Poll.Begin")}"; - msg += $"\n{GetString("Poll.TimeInfo")}"; - PollMSG = !Longtitle ? "" + tytul + "\n\n" + msg : msg; - - Logger.Info($"Poll message: {msg}", "MEssapoll"); - + } + msg += "\n" + tied.Last().Key + PollQuestions[tied.Last().Key]; + + Utils.SendMessage(string.Format(GetString("Poll.Tied"), msg, tienum), title: tytul); + } + + Pollvotes.Clear(); + PollQuestions.Clear(); + PollVoted.Clear(); + } + + + if (Main.AllPlayerControls.Length < 3) + { + Utils.SendMessage(GetString("Poll.MissingPlayers"), PlayerControl.LocalPlayer.PlayerId); + break; + } + + if (!GameStates.IsLobby) + { + Utils.SendMessage(GetString("Poll.OnlyInLobby"), PlayerControl.LocalPlayer.PlayerId); + break; + } + + if (args.SkipWhile(x => !x.Contains('?')).ToArray().Length < 3 || !args.Any(x => x.Contains('?'))) + { + Utils.SendMessage(GetString("PollUsage"), PlayerControl.LocalPlayer.PlayerId); + break; + } + var resultat = args.TakeWhile(x => !x.Contains('?')).Concat(args.SkipWhile(x => !x.Contains('?')).Take(1)); + + string tytul = string.Join(" ", resultat.Skip(1)); + bool Longtitle = tytul.Length > 30; + tytul = Utils.ColorString(Palette.PlayerColors[PlayerControl.LocalPlayer.Data.DefaultOutfit.ColorId], tytul); + var altTitle = Utils.ColorString(new Color32(151, 198, 230, 255), GetString("PollTitle")); + + var ClearTIT = args.ToList(); + ClearTIT.RemoveRange(0, resultat.ToArray().Length); + + var Questions = ClearTIT.ToArray(); + string msg = ""; + + + if (Longtitle) msg += "" + tytul + "\n\n"; + for (int i = 0; i < Math.Clamp(Questions.Length, 2, 5); i++) + { + msg += Utils.ColorString(RndCLR(), $"{char.ToUpper((char)(i + 65))}) {Questions[i]}\n"); + Pollvotes[char.ToUpper((char)(i + 65))] = 0; + PollQuestions[char.ToUpper((char)(i + 65))] = $"〖 {Questions[i]} 〗"; + } + msg += $"\n{GetString("Poll.Begin")}"; + msg += $"\n{GetString("Poll.TimeInfo")}"; + PollMSG = !Longtitle ? "" + tytul + "\n\n" + msg : msg; + + Logger.Info($"Poll message: {msg}", "MEssapoll"); + Utils.SendMessage(msg, title: !Longtitle ? tytul: altTitle); - - Main.Instance.StartCoroutine(StartPollCountdown()); - - - static Color32 RndCLR() - { - byte r, g, b; - - r = (byte)IRandom.Instance.Next(45, 185); - g = (byte)IRandom.Instance.Next(45, 185); - b = (byte)IRandom.Instance.Next(45, 185); - - return new Color32(r, g, b, 255); - } - - break; - + + Main.Instance.StartCoroutine(StartPollCountdown()); + + + static Color32 RndCLR() + { + byte r, g, b; + + r = (byte)IRandom.Instance.Next(45, 185); + g = (byte)IRandom.Instance.Next(45, 185); + b = (byte)IRandom.Instance.Next(45, 185); + + return new Color32(r, g, b, 255); + } + + break; + case "/rps": - case "/剪刀石头布": - if (!Options.CanPlayMiniGames.GetBool()) - { - Utils.SendMessage(GetString("DisableUseCommand"), PlayerControl.LocalPlayer.PlayerId); - break; - } - canceled = true; - subArgs = args.Length != 2 ? "" : args[1]; - - if (!GameStates.IsLobby && PlayerControl.LocalPlayer.IsAlive()) - { - Utils.SendMessage(GetString("RpsCommandInfo"), PlayerControl.LocalPlayer.PlayerId); - break; - } - - if (subArgs == "" || !int.TryParse(subArgs, out int playerChoice)) - { - Utils.SendMessage(GetString("RpsCommandInfo"), PlayerControl.LocalPlayer.PlayerId); - break; - } - else if (playerChoice < 0 || playerChoice > 2) - { - Utils.SendMessage(GetString("RpsCommandInfo"), PlayerControl.LocalPlayer.PlayerId); - break; - } - else - { - var rand = IRandom.Instance; - int botChoice = rand.Next(0, 3); - var rpsList = new List { GetString("Rock"), GetString("Paper"), GetString("Scissors") }; - if (botChoice == playerChoice) - { - Utils.SendMessage(string.Format(GetString("RpsDraw"), rpsList[botChoice]), PlayerControl.LocalPlayer.PlayerId); - } - else if ((botChoice == 0 && playerChoice == 2) || - (botChoice == 1 && playerChoice == 0) || - (botChoice == 2 && playerChoice == 1)) - { - Utils.SendMessage(string.Format(GetString("RpsLose"), rpsList[botChoice]), PlayerControl.LocalPlayer.PlayerId); - } - else - { - Utils.SendMessage(string.Format(GetString("RpsWin"), rpsList[botChoice]), PlayerControl.LocalPlayer.PlayerId); - } - break; - } + case "/剪刀石头布": + if (!Options.CanPlayMiniGames.GetBool()) + { + Utils.SendMessage(GetString("DisableUseCommand"), PlayerControl.LocalPlayer.PlayerId); + break; + } + canceled = true; + subArgs = args.Length != 2 ? "" : args[1]; + + if (!GameStates.IsLobby && PlayerControl.LocalPlayer.IsAlive()) + { + Utils.SendMessage(GetString("RpsCommandInfo"), PlayerControl.LocalPlayer.PlayerId); + break; + } + + if (subArgs == "" || !int.TryParse(subArgs, out int playerChoice)) + { + Utils.SendMessage(GetString("RpsCommandInfo"), PlayerControl.LocalPlayer.PlayerId); + break; + } + else if (playerChoice < 0 || playerChoice > 2) + { + Utils.SendMessage(GetString("RpsCommandInfo"), PlayerControl.LocalPlayer.PlayerId); + break; + } + else + { + var rand = IRandom.Instance; + int botChoice = rand.Next(0, 3); + var rpsList = new List { GetString("Rock"), GetString("Paper"), GetString("Scissors") }; + if (botChoice == playerChoice) + { + Utils.SendMessage(string.Format(GetString("RpsDraw"), rpsList[botChoice]), PlayerControl.LocalPlayer.PlayerId); + } + else if ((botChoice == 0 && playerChoice == 2) || + (botChoice == 1 && playerChoice == 0) || + (botChoice == 2 && playerChoice == 1)) + { + Utils.SendMessage(string.Format(GetString("RpsLose"), rpsList[botChoice]), PlayerControl.LocalPlayer.PlayerId); + } + else + { + Utils.SendMessage(string.Format(GetString("RpsWin"), rpsList[botChoice]), PlayerControl.LocalPlayer.PlayerId); + } + break; + } case "/coinflip": - case "/抛硬币": - if (!Options.CanPlayMiniGames.GetBool()) - { - Utils.SendMessage(GetString("DisableUseCommand"), PlayerControl.LocalPlayer.PlayerId); - break; - } - canceled = true; - - if (!GameStates.IsLobby && PlayerControl.LocalPlayer.IsAlive()) - { - Utils.SendMessage(GetString("CoinFlipCommandInfo"), PlayerControl.LocalPlayer.PlayerId); - break; - } - else - { - var rand = IRandom.Instance; - int botChoice = rand.Next(1, 101); - var coinSide = (botChoice < 51) ? GetString("Heads") : GetString("Tails"); + case "/抛硬币": + if (!Options.CanPlayMiniGames.GetBool()) + { + Utils.SendMessage(GetString("DisableUseCommand"), PlayerControl.LocalPlayer.PlayerId); + break; + } + canceled = true; + + if (!GameStates.IsLobby && PlayerControl.LocalPlayer.IsAlive()) + { + Utils.SendMessage(GetString("CoinFlipCommandInfo"), PlayerControl.LocalPlayer.PlayerId); + break; + } + else + { + var rand = IRandom.Instance; + int botChoice = rand.Next(1, 101); + var coinSide = (botChoice < 51) ? GetString("Heads") : GetString("Tails"); Utils.SendMessage(string.Format(GetString("CoinFlipResult"),coinSide), PlayerControl.LocalPlayer.PlayerId); - break; - } + break; + } case "/gno": - case "/猜数字": - if (!Options.CanPlayMiniGames.GetBool()) - { - Utils.SendMessage(GetString("DisableUseCommand"), PlayerControl.LocalPlayer.PlayerId); - break; - } - canceled = true; - if (!GameStates.IsLobby && PlayerControl.LocalPlayer.IsAlive()) - { - Utils.SendMessage(GetString("GNoCommandInfo"), PlayerControl.LocalPlayer.PlayerId); - break; - } - subArgs = args.Length != 2 ? "" : args[1]; - if (subArgs == "" || !int.TryParse(subArgs, out int guessedNo)) - { - Utils.SendMessage(GetString("GNoCommandInfo"), PlayerControl.LocalPlayer.PlayerId); - break; - } - else if (guessedNo < 0 || guessedNo > 99) - { - Utils.SendMessage(GetString("GNoCommandInfo"), PlayerControl.LocalPlayer.PlayerId); - break; - } - else - { - int targetNumber = Main.GuessNumber[PlayerControl.LocalPlayer.PlayerId][0]; - if (Main.GuessNumber[PlayerControl.LocalPlayer.PlayerId][0] == -1) - { - var rand = IRandom.Instance; - Main.GuessNumber[PlayerControl.LocalPlayer.PlayerId][0] = rand.Next(0, 100); - targetNumber = Main.GuessNumber[PlayerControl.LocalPlayer.PlayerId][0]; - } - Main.GuessNumber[PlayerControl.LocalPlayer.PlayerId][1]--; - if (Main.GuessNumber[PlayerControl.LocalPlayer.PlayerId][1] == 0 && guessedNo != targetNumber) - { - Main.GuessNumber[PlayerControl.LocalPlayer.PlayerId][0] = -1; - Main.GuessNumber[PlayerControl.LocalPlayer.PlayerId][1] = 7; - //targetNumber = Main.GuessNumber[PlayerControl.LocalPlayer.PlayerId][0]; - Utils.SendMessage(string.Format(GetString("GNoLost"), targetNumber), PlayerControl.LocalPlayer.PlayerId); - break; - } - else if (guessedNo < targetNumber) - { - Utils.SendMessage(string.Format(GetString("GNoLow"), Main.GuessNumber[PlayerControl.LocalPlayer.PlayerId][1]), PlayerControl.LocalPlayer.PlayerId); - break; - } - else if (guessedNo > targetNumber) - { - Utils.SendMessage(string.Format(GetString("GNoHigh"), Main.GuessNumber[PlayerControl.LocalPlayer.PlayerId][1]), PlayerControl.LocalPlayer.PlayerId); - break; - } - else - { - Utils.SendMessage(string.Format(GetString("GNoWon"), Main.GuessNumber[PlayerControl.LocalPlayer.PlayerId][1]), PlayerControl.LocalPlayer.PlayerId); - Main.GuessNumber[PlayerControl.LocalPlayer.PlayerId][0] = -1; - Main.GuessNumber[PlayerControl.LocalPlayer.PlayerId][1] = 7; - break; - } - - } + case "/猜数字": + if (!Options.CanPlayMiniGames.GetBool()) + { + Utils.SendMessage(GetString("DisableUseCommand"), PlayerControl.LocalPlayer.PlayerId); + break; + } + canceled = true; + if (!GameStates.IsLobby && PlayerControl.LocalPlayer.IsAlive()) + { + Utils.SendMessage(GetString("GNoCommandInfo"), PlayerControl.LocalPlayer.PlayerId); + break; + } + subArgs = args.Length != 2 ? "" : args[1]; + if (subArgs == "" || !int.TryParse(subArgs, out int guessedNo)) + { + Utils.SendMessage(GetString("GNoCommandInfo"), PlayerControl.LocalPlayer.PlayerId); + break; + } + else if (guessedNo < 0 || guessedNo > 99) + { + Utils.SendMessage(GetString("GNoCommandInfo"), PlayerControl.LocalPlayer.PlayerId); + break; + } + else + { + int targetNumber = Main.GuessNumber[PlayerControl.LocalPlayer.PlayerId][0]; + if (Main.GuessNumber[PlayerControl.LocalPlayer.PlayerId][0] == -1) + { + var rand = IRandom.Instance; + Main.GuessNumber[PlayerControl.LocalPlayer.PlayerId][0] = rand.Next(0, 100); + targetNumber = Main.GuessNumber[PlayerControl.LocalPlayer.PlayerId][0]; + } + Main.GuessNumber[PlayerControl.LocalPlayer.PlayerId][1]--; + if (Main.GuessNumber[PlayerControl.LocalPlayer.PlayerId][1] == 0 && guessedNo != targetNumber) + { + Main.GuessNumber[PlayerControl.LocalPlayer.PlayerId][0] = -1; + Main.GuessNumber[PlayerControl.LocalPlayer.PlayerId][1] = 7; + //targetNumber = Main.GuessNumber[PlayerControl.LocalPlayer.PlayerId][0]; + Utils.SendMessage(string.Format(GetString("GNoLost"), targetNumber), PlayerControl.LocalPlayer.PlayerId); + break; + } + else if (guessedNo < targetNumber) + { + Utils.SendMessage(string.Format(GetString("GNoLow"), Main.GuessNumber[PlayerControl.LocalPlayer.PlayerId][1]), PlayerControl.LocalPlayer.PlayerId); + break; + } + else if (guessedNo > targetNumber) + { + Utils.SendMessage(string.Format(GetString("GNoHigh"), Main.GuessNumber[PlayerControl.LocalPlayer.PlayerId][1]), PlayerControl.LocalPlayer.PlayerId); + break; + } + else + { + Utils.SendMessage(string.Format(GetString("GNoWon"), Main.GuessNumber[PlayerControl.LocalPlayer.PlayerId][1]), PlayerControl.LocalPlayer.PlayerId); + Main.GuessNumber[PlayerControl.LocalPlayer.PlayerId][0] = -1; + Main.GuessNumber[PlayerControl.LocalPlayer.PlayerId][1] = 7; + break; + } + + } case "/rand": case "/XY数字": case "/范围游戏": case "/猜范围": - case "/范围": - if (!Options.CanPlayMiniGames.GetBool()) - { - Utils.SendMessage(GetString("DisableUseCommand"), PlayerControl.LocalPlayer.PlayerId); - break; - } - canceled = true; - subArgs = args.Length != 3 ? "" : args[1]; - subArgs2 = args.Length != 3 ? "" : args[2]; - - if (!GameStates.IsLobby && PlayerControl.LocalPlayer.IsAlive()) - { - Utils.SendMessage(GetString("RandCommandInfo"), PlayerControl.LocalPlayer.PlayerId); - break; - } - if (subArgs == "" || !int.TryParse(subArgs, out int playerChoice1) || subArgs2 == "" || !int.TryParse(subArgs2, out int playerChoice2)) - { - Utils.SendMessage(GetString("RandCommandInfo"), PlayerControl.LocalPlayer.PlayerId); - break; - } - else - { - var rand = IRandom.Instance; - int botResult = rand.Next(playerChoice1, playerChoice2 + 1); - Utils.SendMessage(string.Format(GetString("RandResult"), botResult), PlayerControl.LocalPlayer.PlayerId); - break; - } - + case "/范围": + if (!Options.CanPlayMiniGames.GetBool()) + { + Utils.SendMessage(GetString("DisableUseCommand"), PlayerControl.LocalPlayer.PlayerId); + break; + } + canceled = true; + subArgs = args.Length != 3 ? "" : args[1]; + subArgs2 = args.Length != 3 ? "" : args[2]; + + if (!GameStates.IsLobby && PlayerControl.LocalPlayer.IsAlive()) + { + Utils.SendMessage(GetString("RandCommandInfo"), PlayerControl.LocalPlayer.PlayerId); + break; + } + if (subArgs == "" || !int.TryParse(subArgs, out int playerChoice1) || subArgs2 == "" || !int.TryParse(subArgs2, out int playerChoice2)) + { + Utils.SendMessage(GetString("RandCommandInfo"), PlayerControl.LocalPlayer.PlayerId); + break; + } + else + { + var rand = IRandom.Instance; + int botResult = rand.Next(playerChoice1, playerChoice2 + 1); + Utils.SendMessage(string.Format(GetString("RandResult"), botResult), PlayerControl.LocalPlayer.PlayerId); + break; + } + case "/8ball": case "/8号球": - case "/幸运球": - if (!Options.CanPlayMiniGames.GetBool()) - { - Utils.SendMessage(GetString("DisableUseCommand"), PlayerControl.LocalPlayer.PlayerId); - break; - } - canceled = true; - var rando = IRandom.Instance; - int result = rando.Next(0, 16); - string str = ""; - switch (result) - { - case 0: - str = GetString("8BallYes"); - break; - case 1: - str = GetString("8BallNo"); - break; - case 2: - str = GetString("8BallMaybe"); - break; - case 3: - str = GetString("8BallTryAgainLater"); - break; - case 4: - str = GetString("8BallCertain"); - break; - case 5: - str = GetString("8BallNotLikely"); - break; - case 6: - str = GetString("8BallLikely"); - break; - case 7: - str = GetString("8BallDontCount"); - break; - case 8: - str = GetString("8BallStop"); - break; - case 9: - str = GetString("8BallPossibly"); - break; - case 10: - str = GetString("8BallProbably"); - break; - case 11: - str = GetString("8BallProbablyNot"); - break; - case 12: - str = GetString("8BallBetterNotTell"); - break; - case 13: - str = GetString("8BallCantPredict"); - break; - case 14: - str = GetString("8BallWithoutDoubt"); - break; - case 15: - str = GetString("8BallWithDoubt"); - break; - } - Utils.SendMessage("" + str + "", PlayerControl.LocalPlayer.PlayerId, Utils.ColorString(Utils.GetRoleColor(CustomRoles.Medium), GetString("8BallTitle"))); - break; - - default: - Main.isChatCommand = false; - break; - } - } - goto Skip; - Canceled: - Main.isChatCommand = false; - canceled = true; - Skip: - if (canceled) - { - Logger.Info("Command Canceled", "ChatCommand"); - __instance.freeChatField.textArea.Clear(); - __instance.freeChatField.textArea.SetText(cancelVal); - - __instance.quickChatMenu.Clear(); - __instance.quickChatField.Clear(); - } - return !canceled; - } - - public static string FixRoleNameInput(string text) - { - text = text.Replace("着", "者").Trim().ToLower(); - return text switch - { - // Because of partial translation conflicts (zh-cn and zh-tw) - // Need to wait for follow-up finishing - - /* - // GM - "GM(遊戲大師)" or "管理员" or "管理" or "gm" or "GM" => GetString("GM"), - - // 原版职业 - "船員" or "船员" or "白板" or "天选之子" => GetString("CrewmateTOHE"), - "工程師" or "工程师" => GetString("EngineerTOHE"), - "科學家" or "科学家" => GetString("ScientistTOHE"), - "守護天使" or "守护天使" => GetString("GuardianAngelTOHE"), - "偽裝者" or "内鬼" => GetString("ImpostorTOHE"), - "變形者" or "变形者" => GetString("ShapeshifterTOHE"), - - // 隱藏職業 and 隐藏职业 - "陽光開朗大男孩" or "阳光开朗大男孩" => GetString("Sunnyboy"), - "吟遊詩人" or "吟游诗人" => GetString("Bard"), - "核爆者" or "核武器" => GetString("Nuker"), - - // 偽裝者陣營職業 and 内鬼阵营职业 - "賞金獵人" or "赏金猎人" or "赏金" => GetString("BountyHunter"), - "煙火工匠" or "烟花商人" or "烟花爆破者" or "烟花" => GetString("Fireworker"), - "嗜血殺手" or "嗜血杀手" or "嗜血" => GetString("Mercenary"), - "百变怪" or "千面鬼" or "千面" => GetString("ShapeMaster"), - "吸血鬼" or "吸血" => GetString("Vampire"), - "吸血鬼之王" or "吸血鬼女王" => GetString("Vampiress"), - "術士" or "术士" => GetString("Warlock"), - "刺客" or "忍者" => GetString("Ninja"), - "僵屍" or "僵尸" or"殭屍" or "丧尸" => GetString("Zombie"), - "駭客" or "骇客" or "黑客" => GetString("Anonymous"), - "礦工" or "矿工" => GetString("Miner"), - "殺人機器" or "杀戮机器" or "杀戮" or "机器" or "杀戮兵器" => GetString("KillingMachine"), - "通緝犯" or "逃逸者" or "逃逸" => GetString("Escapist"), - "女巫" => GetString("Witch"), - "傀儡師" or "傀儡师" or "傀儡" => GetString("Puppeteer"), - "主謀" or "策划者" => GetString("Mastermind"), - "時間竊賊" or "蚀时者" or "蚀时" or "偷时" => GetString("TimeThief"), - "狙擊手" or "狙击手" or "狙击" => GetString("Sniper"), - "送葬者" or "暗杀者" => GetString("Undertaker"), - "裂縫製造者" or "裂缝制造者" => GetString("RiftMaker"), - "邪惡的追踪者" or "邪恶追踪者" or "邪恶的追踪者" => GetString("EvilTracker"), - "邪惡賭怪" or "邪恶赌怪" or "坏赌" or "恶赌" or "邪恶赌怪" => GetString("EvilGuesser"), - "監管者" or "监管者" or "监管" => GetString("AntiAdminer"), - "狂妄殺手" or "狂妄杀手" => GetString("Arrogance"), - "自爆兵" or "自爆" => GetString("Bomber"), - "清道夫" or "清道" => GetString("Scavenger"), - "陷阱師" or "诡雷" => GetString("Trapster"), - "歹徒" => GetString("Gangster"), - "清潔工" or "清理工" or "清洁工" => GetString("Cleaner"), - "球狀閃電" or "球状闪电" => GetString("Lightning"), - "貪婪者" or "贪婪者" or "贪婪" => GetString("Greedy"), - "被詛咒的狼" or "呪狼" => GetString("CursedWolf"), - "換魂師" or "夺魂者" or "夺魂" => GetString("SoulCatcher"), - "快槍手" or "快枪手" or "快枪" => GetString("QuickShooter"), - "隱蔽者" or "隐蔽者" or "小黑人" => GetString("Camouflager"), - "抹除者" or "抹除" => GetString("Eraser"), - "肢解者" or "肢解" => GetString("Butcher"), - "劊子手" or "刽子手" => GetString("Hangman"), - "隱身人" or "隐匿者" or "隐匿" or "隐身" => GetString("Swooper"), - "船鬼" => GetString("Crewpostor"), - "野人" => GetString("Wildling"), - "騙術師" or "骗术师" => GetString("Trickster"), - "衛道士" or "卫道士" or "内鬼市长" => GetString("Vindicator"), - "寄生蟲" or "寄生虫" => GetString("Parasite"), - "分散者" or "分散" => GetString("Disperser"), - "抑鬱者" or "抑郁者" or "抑郁" => GetString("Inhibitor"), - "破壞者" or "破坏者" or "破坏" => GetString("Saboteur"), - "議員" or "邪恶法官" or "议员" or "邪恶审判" => GetString("Councillor"), - "眩暈者" or "眩晕者" or "眩晕" => GetString("Dazzler"), - "簽約人" or "死亡契约" or "死亡" or "锲约" => GetString("Deathpact"), - "吞噬者" or "吞噬" => GetString("Devourer"), - "軍師" or "军师" => GetString("Consigliere"), - "化型者" or "化形者" => GetString("Morphling"), - "躁動者" or "龙卷风" => GetString("Twister"), - "策畫者" or "潜伏者" or "潜伏" => GetString("Lurker"), - "罪犯" => GetString("Convict"), - "幻想家" or "幻想" => GetString("Visionary"), - "逃亡者" or "逃亡" => GetString("Refugee"), - "潛伏者" or "失败者" or "失败的man" or "失败" => GetString("Underdog"), - "賭博者" or "速度者" or "速度" => GetString("Ludopath"), - "懸賞者" or "教父" => GetString("Godfather"), - "天文學家" or "天文学家" or "天文家" or "天文学" => GetString("Chronomancer"), - "設陷者" or "设陷者" or "设陷" => GetString("Pitfall"), - "狂戰士" or "狂战士" or "升级者" or "狂战士" => GetString("Berserker"), - "壞迷你船員" or "坏迷你船员" or "坏小孩" or "坏迷你" => GetString("EvilMini"), - "勒索者" or "勒索" => GetString("Blackmailer"), - "教唆者" or "教唆" => GetString("Instigator"), - - // 船員陣營職業 and 船员阵营职业 - "擺爛人" or "摆烂人" or "摆烂" => GetString("Needy"), - "大明星" or "明星" => GetString("SuperStar"), - "網紅" or "网红" => GetString("Celebrity"), - "清洗者" or "清洗" => GetString("Cleanser"), - "守衛者" or "守卫者" => GetString("Keeper"), - "俠客" or "侠客" or "正义使者" => GetString("Knight"), - "市長" or "市长" => GetString("Mayor"), - "被害妄想症" or "被害妄想" or "被迫害妄想症" or "被害" or "妄想" or "妄想症" => GetString("Paranoia"), - "愚者" => GetString("Psychic"), - "修理工" or "修理" or "修理大师" => GetString("Mechanic"), - "警長" or "警长" => GetString("Sheriff"), - "義警" or "义务警员" or "警员" => GetString("Vigilante"), - "監禁者" or "狱警" or "狱卒" => GetString("Jailer"), - "模仿者" or "模仿猫" or "模仿" => GetString("CopyCat"), - "告密者" => GetString("Snitch"), - "展現者" or "展现者" or "展现" => GetString("Marshall"), - "增速師" or "增速者" or "增速" => GetString("SpeedBooster"), - "法醫" or "法医" => GetString("Doctor"), - "獨裁主義者" or "独裁者" or "独裁" => GetString("Dictator"), - "偵探" or "侦探" => GetString("Detective"), - "正義賭怪" or "正义赌怪" or "好赌" or "正义的赌怪" => GetString("NiceGuesser"), - "賭場管理員" or "竞猜大师" or "竞猜" => GetString("GuessMaster"), - "傳送師" or "传送师" => GetString("Transporter"), - "時間大師" or "时间操控者" or "时间操控" => GetString("TimeManager"), - "老兵" => GetString("Veteran"), - "埋雷兵" => GetString("Bastion"), - "保鑣" or "保镖" => GetString("Bodyguard"), - "贗品商" or "赝品商" => GetString("Deceiver"), - "擲彈兵" or "掷雷兵" => GetString("Grenadier"), - "軍醫" or "医生" => GetString("Medic"), - "占卜師" or "调查员" or "占卜师" => GetString("FortuneTeller"), - "法官" or "正义法官" or "正义审判" => GetString("Judge"), - "殯葬師" or "入殓师" => GetString("Mortician"), - "通靈師" or "通灵师" => GetString("Mediumshiper"), - "和平之鴿" or "和平之鸽" => GetString("Pacifist"), - "窺視者" or "观察者" or "观察" => GetString("Observer"), - "君主" => GetString("Monarch"), - "預言家" or "预言家" or "预言" => GetString("Overseer"), - "驗屍官" or "验尸官" or "验尸" => GetString("Coroner"), - "正義的追蹤者" or "正义追踪者" or "正义的追踪者" => GetString("Tracker"), - "商人" => GetString("Merchant"), - "總統" or "总统" => GetString("President"), - "獵鷹" or "猎鹰" => GetString("Hawk"), - "捕快" or "下属" => GetString("Deputy"), - "算命師" or "研究者" => GetString("Investigator"), - "守護者" or "守护者" or "守护" => GetString("Guardian"), - "賢者" or "瘾君子" or "醉酒" => GetString("Addict"), - "鼹鼠" => GetString("Mole"), - "藥劑師" or "炼金术士" or "药剂" => GetString("Alchemist"), - "尋跡者" or "寻迹者" or "寻迹" or "寻找鸡腿" => GetString("Tracefinder"), - "先知" or "神谕" or "神谕者" => GetString("Oracle"), - "靈魂論者" or "灵魂论者" => GetString("Spiritualist"), - "變色龍" or "变色龙" or "变色" => GetString("Chameleon"), - "檢查員" or "检查员" or "检查" => GetString("Inspector"), - "仰慕者" or "仰慕" => GetString("Admirer"), - "時間之主" or "时间之主" or "回溯时间" => GetString("TimeMaster"), - "十字軍" or "十字军" => GetString("Crusader"), - "遐想者" or "遐想" => GetString("Reverie"), - "瞭望者" or "瞭望员" => GetString("Lookout"), - "通訊員" or "通信员" => GetString("Telecommunication"), - "執燈人" or "执灯人" or "执灯" or "灯人" or "小灯人" => GetString("Lighter"), - "任務管理員" or "任务管理者" => GetString("TaskManager"), - "目擊者" or "目击者" or "目击" => GetString("Witness"), - "換票師" or "换票师" => GetString("Swapper"), - "警察局長" or "警察局长" => GetString("ChiefOfPolice"), - "好迷你船員" or "好迷你船员" or "好迷你" or "好小孩" => GetString("NiceMini"), - "間諜" or "间谍" => GetString("Spy"), - "隨機者" or "萧暮" or "暮" or "萧暮不姓萧" => GetString("Randomizer"), - "猜想者" or "猜想" or "谜团" => GetString("Enigma"), - "船長" or "舰长" or "船长" => GetString("Captain"), - "慈善家" or "恩人" => GetString("Benefactor"), - - // 中立陣營職業 and 中立阵营职业 - "小丑" or "丑皇" => GetString("Jester"), - "縱火犯" or "纵火犯" or "纵火者" or "纵火" => GetString("Arsonist"), - "焚燒狂" or "焚烧狂" or "焚烧" => GetString("Pyromaniac"), - "神風特攻隊" or "神风特攻队" => GetString("Kamikaze"), - "獵人" or "猎人" => GetString("Huntsman"), - "恐怖分子" => GetString("Terrorist"), - "暴民" or "处刑人" or "处刑" or "处刑者" => GetString("Executioner"), - "律師" or "律师" => GetString("Lawyer"), - "投機主義者" or "投机者" or "投机" => GetString("Opportunist"), - "瑪利歐" or "马里奥" => GetString("Vector"), - "豺狼" or "蓝狼" => GetString("Jackal"), - "神" or "上帝" => GetString("God"), - "冤罪師" or "冤罪师" or "冤罪" => GetString("Innocent"), - "暗殺者" or "隐形者" =>GetString("Stealth"), - "企鵝" or "企鹅" =>GetString("Penguin"), - "鵜鶘" or "鹈鹕" => GetString("Pelican"), - "疫醫" or "瘟疫学家" => GetString("PlagueDoctor"), - "革命家" or "革命者" => GetString("Revolutionist"), - "單身狗" => GetString("Hater"), - "柯南" => GetString("Konan"), - "玩家" => GetString("Demon"), - "潛藏者" or "潜藏" => GetString("Stalker"), - "工作狂" => GetString("Workaholic"), - "至日者" or "至日" => GetString("Solsticer"), - "集票者" or "集票" => GetString("Collector"), - "挑釁者" or "自爆卡车" => GetString("Provocateur"), - "嗜血騎士" or "嗜血骑士" => GetString("BloodKnight"), - "瘟疫之源" or "瘟疫使者" => GetString("PlagueBearer"), - "萬疫之神" or "瘟疫" => GetString("Pestilence"), - "故障者" or "缺点者" or "缺点" => GetString("Glitch"), - "跟班" or "跟班小弟" => GetString("Sidekick"), - "追隨者" or "赌徒" or "下注" => GetString("Follower"), - "魅魔" => GetString("Cultist"), - "連環殺手" or "连环杀手" => GetString("SerialKiller"), - "劍聖" or "天启" => GetString("Juggernaut"), - "感染者" or "感染" => GetString("Infectious"), - "病原體" or "病毒" => GetString("Virus"), - "起訴人" or "起诉人" => GetString("Pursuer"), - "怨靈" or "幽灵" => GetString("Phantom"), - "挑戰者" or "决斗者" or "挑战者" => GetString("Pirate"), - "炸彈王" or "炸弹狂" or "煽动者" => GetString("Agitater"), - "獨行者" or "独行者" => GetString("Maverick"), - "被詛咒的靈魂" or "诅咒之人" => GetString("CursedSoul"), - "竊賊" or "小偷" => GetString("Pickpocket"), - "背叛者" or "背叛" => GetString("Traitor"), - "禿鷲" or "秃鹫" => GetString("Vulture"), - "搗蛋鬼" or "任务执行者" => GetString("Taskinator"), - "麵包師" or "面包师" => GetString("Baker"), - "飢荒" or "饥荒" => GetString("Famine"), - "靈魂召喚者" or "灵魂召唤者" => GetString("Spiritcaller"), - "失憶者" or "失忆者" or "失忆" => GetString("Amnesiac"), - "模仿家" or "效仿者" => GetString("Imitator"), - "強盜" => GetString("Bandit"), - "分身者" => GetString("Doppelganger"), - "受虐狂" => GetString("PunchingBag"), - "賭神" or "末日赌怪" => GetString("Doomsayer"), - "裹屍布" or "裹尸布" => GetString("Shroud"), - "月下狼人" or "狼人" => GetString("Werewolf"), - "薩滿" or "萨满" => GetString("Shaman"), - "冒險家" or "探索者" => GetString("Seeker"), - "精靈" or "小精灵" or "精灵" => GetString("Pixie"), - "咒魔" or "神秘者" => GetString("Occultist"), - "靈魂收割者" or "灵魂收集者" or "灵魂收集" or "收集灵魂" => GetString("SoulCollector"), - "薛丁格的貓" or "薛定谔的猫" => GetString("SchrodingersCat"), - "暗戀者" or "浪漫者" => GetString("Romantic"), - "報復者" or "复仇浪漫者" => GetString("VengefulRomantic"), - "絕情者" or "无情浪漫者" => GetString("RuthlessRomantic"), - "毒醫" or "投毒者" => GetString("Poisoner"), - "代碼工程師" or "巫师" => GetString("HexMaster"), - "幻影" or "魅影" => GetString("Wraith"), - "掃把星" or "扫把星" => GetString("Jinx"), - "魔藥師" or "药剂师" => GetString("PotionMaster"), - "死靈法師" or "亡灵巫师" => GetString("Necromancer"), - "測驗者" or "测验长" => GetString("Quizmaster"), - - // 附加職業 and 附加职业 - "絕境者" or "绝境者" => GetString("LastImpostor"), - "超頻" or "超频波" or "超频" => GetString("Overclocked"), - "戀人" or "恋人" => GetString("Lovers"), - "叛徒" => GetString("Madmate"), - "觀察者" or "窥视者" or "觀察" or "窥视" => GetString("Watcher"), - "閃電俠" or "闪电侠" or "閃電" or "闪电" => GetString("Flash"), - "持燈人" or "火炬" or "持燈" => GetString("Torch"), - "靈媒" or "灵媒" or "靈媒" => GetString("Seer"), - "破平者" or "破平" => GetString("Tiebreaker"), - "膽小鬼" or "胆小鬼" or "膽小" or "胆小" => GetString("Oblivious"), - "視障" or "迷幻者" or "視障" or "迷幻" => GetString("Bewilder"), - "墨鏡" or "患者" => GetString("Sunglasses"), - "加班狂" => GetString("Workhorse"), - "蠢蛋" => GetString("Fool"), - "復仇者" or "复仇者" or "復仇" or "复仇" => GetString("Avanger"), - "Youtuber" or "UP主" or "YT" => GetString("Youtuber"), - "利己主義者" or "利己主义者" or "利己主義" or "利己主义" => GetString("Egoist"), - "竊票者" or "窃票者" or "竊票" or "窃票" => GetString("TicketsStealer"), - //"雙重人格" or "双重人格" => GetString("Schizophrenic"), - "保險箱" or "宝箱怪" => GetString("Mimic"), - "賭怪" or "赌怪" => GetString("Guesser"), - "死神" => GetString("Necroview"), - "長槍" or "持枪" => GetString("Reach"), - "魅魔小弟" => GetString("Charmed"), - "乾淨" or "干净" => GetString("Cleansed"), - "誘餌" or "诱饵" => GetString("Bait"), - "陷阱師" or "陷阱师" => GetString("Trapper"), - "被感染" or "感染" => GetString("Infected"), - "防賭" or "不可被赌" => GetString("Onbound"), - "反擊者" or "回弹者" or "回弹" => GetString("Rebound"), - "平凡者" or "平凡" => GetString("Mundane"), - "騎士" or "骑士" => GetString("Knighted"), - "漠視" or "不受重视" or "被漠視的" => GetString("Unreportable"), - "被傳染" or "传染性" => GetString("Contagious"), - "幸運" or "幸运加持" => GetString("Lucky"), - "倒霉" or "倒霉蛋" => GetString("Unlucky"), - "虛無" or "无效投票" => GetString("VoidBallot"), - "敏感" or "意识者" or "意识" => GetString("Aware"), - "嬌嫩" or "脆弱" or "脆弱者" => GetString("Fragile"), - "專業" or "双重猜测" => GetString("DoubleShot"), - "流氓" => GetString("Rascal"), - "無魂" or "没有灵魂" => GetString("Soulless"), - "墓碑" => GetString("Gravestone"), - "懶人" or "懒人" => GetString("Lazy"), - "驗屍" or "尸检" => GetString("Autopsy"), - "忠誠" or "忠诚" => GetString("Loyal"), - "惡靈" or "恶灵" => GetString("EvilSpirit"), - "狼化" or "招募" or "狼化的" or "被招募的" => GetString("Recruit"), - "被仰慕" or "仰慕" => GetString("Admired"), - "發光" or "光辉" => GetString("Glow"), - "病態" or "患病者" or "患病的" or "患病" => GetString("Diseased"), - "健康" or "健康的" or "健康者" => GetString("Antidote"), - "固執者" or "固执者" or "固執" or "固执" => GetString("Stubborn"), - "無影" or "迅捷" => GetString("Swift"), - "反噬" or "食尸鬼" => GetString("Ghoul"), - "嗜血者" => GetString("Bloodthirst"), - "獵夢者" or "梦魇" or "獵夢"=> GetString("Mare"), - "地雷" or "爆破者" or "爆破" => GetString("Burst"), - "偵察員" or "侦察员" or "偵察" or "侦察" => GetString("Sleuth"), - "笨拙" or "笨蛋" => GetString("Clumsy"), - "敏捷" => GetString("Nimble"), - "規避者" or "规避者" or "规避" => GetString("Circumvent"), - "名人" or "网络员" or "网络" => GetString("Cyber"), - "焦急者" or "焦急的" or "焦急" => GetString("Hurried"), - "OIIAI" => GetString("Oiiai"), - "順從者" or "影响者" or "順從" or "影响" => GetString("Influenced"), - "沉默者" or "沉默" => GetString("Silent"), - "易感者" or "易感" => GetString("Susceptible"), - "狡猾" or "棘手者" or "棘手" => GetString("Tricky"), - "彩虹" => GetString("Rainbow"), - "疲勞者" or "疲劳者" or "疲勞" or "疲劳" => GetString("Tired"), - "雕像" => GetString("Statue"), - "没有搜集的繁体中文" or "雷达" => GetString("Radar"), - - // 幽靈職業 and 幽灵职业 - // 偽裝者 and 内鬼 - "爪牙" => GetString("Minion"), - "黑手黨" or "黑手党" or "黑手" => GetString("Nemesis"), - "嗜血之魂" or "血液伯爵" => GetString("Bloodmoon"), - // 船員 and 船员 - "没有搜集的繁体中文" or "鬼怪" => GetString("Ghastly"), - "冤魂" or "典狱长" => GetString("Warden"), - "報應者" or "惩罚者" or "惩罚" or "报仇者" => GetString("Retributionist"), - - // 随机阵营职业 - "迷你船員" or "迷你船员" or "迷你" or "小孩" or "Mini" => GetString("Mini"),*/ - _ => text, - }; - } - - public static bool GetRoleByName(string name, out CustomRoles role) - { - role = new(); - - if (name == "" || name == string.Empty) return false; - - if ((TranslationController.InstanceExists ? TranslationController.Instance.currentLanguage.languageID : SupportedLangs.SChinese) == SupportedLangs.SChinese) - { - Regex r = new("[\u4e00-\u9fa5]+$"); - MatchCollection mc = r.Matches(name); - string result = string.Empty; - for (int i = 0; i < mc.Count; i++) - { - if (mc[i].ToString() == "是") continue; - result += mc[i]; //匹配结果是完整的数字,此处可以不做拼接的 - } - name = FixRoleNameInput(result.Replace("是", string.Empty).Trim()); - } - else name = name.Trim().ToLower(); - - foreach (var rl in CustomRolesHelper.AllRoles) - { - if (rl.IsVanilla()) continue; - var roleName = GetString(rl.ToString()).ToLower().Trim().Replace(" ", ""); - string nameWithoutId = Regex.Replace(name.Replace(" ", ""), @"^\d+", ""); - if (nameWithoutId == roleName) - { - role = rl; - return true; - } - } - return false; - } - public static void SendRolesInfo(string role, byte playerId, bool isDev = false, bool isUp = false) - { - if (Options.CurrentGameMode == CustomGameMode.FFA) - { - Utils.SendMessage(GetString("ModeDescribe.FFA"), playerId); - return; - } - role = role.Trim().ToLower(); - if (role.StartsWith("/r")) _ = role.Replace("/r", string.Empty); - if (role.StartsWith("/up")) _ = role.Replace("/up", string.Empty); - if (role.EndsWith("\r\n")) _ = role.Replace("\r\n", string.Empty); - if (role.EndsWith("\n")) _ = role.Replace("\n", string.Empty); - if (role.StartsWith("/bt")) _ = role.Replace("/bt", string.Empty); - - if (role == "" || role == string.Empty) - { - Utils.ShowActiveRoles(playerId); - return; - } - - role = FixRoleNameInput(role).ToLower().Trim().Replace(" ", string.Empty); - - foreach (var rl in CustomRolesHelper.AllRoles) - { - if (rl.IsVanilla()) continue; - var roleName = GetString(rl.ToString()); - if (role == roleName.ToLower().Trim().TrimStart('*').Replace(" ", string.Empty)) - { - string devMark = ""; - if ((isDev || isUp) && GameStates.IsLobby) - { - devMark = "▲"; - if (CustomRolesHelper.IsAdditionRole(rl) || rl is CustomRoles.GM or CustomRoles.Mini || rl.IsGhostRole()) devMark = ""; - if (rl.GetCount() < 1 || rl.GetMode() == 0) devMark = ""; - if (isUp) - { - if (devMark == "▲") Utils.SendMessage(string.Format(GetString("Message.YTPlanSelected"), roleName), playerId); - else Utils.SendMessage(string.Format(GetString("Message.YTPlanSelectFailed"), roleName), playerId); - } - if (devMark == "▲") - { - byte pid = playerId == 255 ? (byte)0 : playerId; - GhostRoleAssign.forceRole.Remove(pid); - RoleAssign.SetRoles.Remove(pid); - RoleAssign.SetRoles.Add(pid, rl); - } - if (rl.IsGhostRole() && !rl.IsAdditionRole() && isDev && (rl.GetCount() >= 1 && rl.GetMode() > 0)) - { - byte pid = playerId == 255 ? (byte)0 : playerId; + case "/幸运球": + if (!Options.CanPlayMiniGames.GetBool()) + { + Utils.SendMessage(GetString("DisableUseCommand"), PlayerControl.LocalPlayer.PlayerId); + break; + } + canceled = true; + var rando = IRandom.Instance; + int result = rando.Next(0, 16); + string str = ""; + switch (result) + { + case 0: + str = GetString("8BallYes"); + break; + case 1: + str = GetString("8BallNo"); + break; + case 2: + str = GetString("8BallMaybe"); + break; + case 3: + str = GetString("8BallTryAgainLater"); + break; + case 4: + str = GetString("8BallCertain"); + break; + case 5: + str = GetString("8BallNotLikely"); + break; + case 6: + str = GetString("8BallLikely"); + break; + case 7: + str = GetString("8BallDontCount"); + break; + case 8: + str = GetString("8BallStop"); + break; + case 9: + str = GetString("8BallPossibly"); + break; + case 10: + str = GetString("8BallProbably"); + break; + case 11: + str = GetString("8BallProbablyNot"); + break; + case 12: + str = GetString("8BallBetterNotTell"); + break; + case 13: + str = GetString("8BallCantPredict"); + break; + case 14: + str = GetString("8BallWithoutDoubt"); + break; + case 15: + str = GetString("8BallWithDoubt"); + break; + } + Utils.SendMessage("" + str + "", PlayerControl.LocalPlayer.PlayerId, Utils.ColorString(Utils.GetRoleColor(CustomRoles.Medium), GetString("8BallTitle"))); + break; + + default: + Main.isChatCommand = false; + break; + } + } + goto Skip; + Canceled: + Main.isChatCommand = false; + canceled = true; + Skip: + if (canceled) + { + Logger.Info("Command Canceled", "ChatCommand"); + __instance.freeChatField.textArea.Clear(); + __instance.freeChatField.textArea.SetText(cancelVal); + + __instance.quickChatMenu.Clear(); + __instance.quickChatField.Clear(); + } + return !canceled; + } + + public static string FixRoleNameInput(string text) + { + text = text.Replace("着", "者").Trim().ToLower(); + return text switch + { + // Because of partial translation conflicts (zh-cn and zh-tw) + // Need to wait for follow-up finishing + + /* + // GM + "GM(遊戲大師)" or "管理员" or "管理" or "gm" or "GM" => GetString("GM"), + + // 原版职业 + "船員" or "船员" or "白板" or "天选之子" => GetString("CrewmateTOHE"), + "工程師" or "工程师" => GetString("EngineerTOHE"), + "科學家" or "科学家" => GetString("ScientistTOHE"), + "守護天使" or "守护天使" => GetString("GuardianAngelTOHE"), + "偽裝者" or "内鬼" => GetString("ImpostorTOHE"), + "變形者" or "变形者" => GetString("ShapeshifterTOHE"), + + // 隱藏職業 and 隐藏职业 + "陽光開朗大男孩" or "阳光开朗大男孩" => GetString("Sunnyboy"), + "吟遊詩人" or "吟游诗人" => GetString("Bard"), + "核爆者" or "核武器" => GetString("Nuker"), + + // 偽裝者陣營職業 and 内鬼阵营职业 + "賞金獵人" or "赏金猎人" or "赏金" => GetString("BountyHunter"), + "煙火工匠" or "烟花商人" or "烟花爆破者" or "烟花" => GetString("Fireworker"), + "嗜血殺手" or "嗜血杀手" or "嗜血" => GetString("Mercenary"), + "百变怪" or "千面鬼" or "千面" => GetString("ShapeMaster"), + "吸血鬼" or "吸血" => GetString("Vampire"), + "吸血鬼之王" or "吸血鬼女王" => GetString("Vampiress"), + "術士" or "术士" => GetString("Warlock"), + "刺客" or "忍者" => GetString("Ninja"), + "僵屍" or "僵尸" or"殭屍" or "丧尸" => GetString("Zombie"), + "駭客" or "骇客" or "黑客" => GetString("Anonymous"), + "礦工" or "矿工" => GetString("Miner"), + "殺人機器" or "杀戮机器" or "杀戮" or "机器" or "杀戮兵器" => GetString("KillingMachine"), + "通緝犯" or "逃逸者" or "逃逸" => GetString("Escapist"), + "女巫" => GetString("Witch"), + "傀儡師" or "傀儡师" or "傀儡" => GetString("Puppeteer"), + "主謀" or "策划者" => GetString("Mastermind"), + "時間竊賊" or "蚀时者" or "蚀时" or "偷时" => GetString("TimeThief"), + "狙擊手" or "狙击手" or "狙击" => GetString("Sniper"), + "送葬者" or "暗杀者" => GetString("Undertaker"), + "裂縫製造者" or "裂缝制造者" => GetString("RiftMaker"), + "邪惡的追踪者" or "邪恶追踪者" or "邪恶的追踪者" => GetString("EvilTracker"), + "邪惡賭怪" or "邪恶赌怪" or "坏赌" or "恶赌" or "邪恶赌怪" => GetString("EvilGuesser"), + "監管者" or "监管者" or "监管" => GetString("AntiAdminer"), + "狂妄殺手" or "狂妄杀手" => GetString("Arrogance"), + "自爆兵" or "自爆" => GetString("Bomber"), + "清道夫" or "清道" => GetString("Scavenger"), + "陷阱師" or "诡雷" => GetString("Trapster"), + "歹徒" => GetString("Gangster"), + "清潔工" or "清理工" or "清洁工" => GetString("Cleaner"), + "球狀閃電" or "球状闪电" => GetString("Lightning"), + "貪婪者" or "贪婪者" or "贪婪" => GetString("Greedy"), + "被詛咒的狼" or "呪狼" => GetString("CursedWolf"), + "換魂師" or "夺魂者" or "夺魂" => GetString("SoulCatcher"), + "快槍手" or "快枪手" or "快枪" => GetString("QuickShooter"), + "隱蔽者" or "隐蔽者" or "小黑人" => GetString("Camouflager"), + "抹除者" or "抹除" => GetString("Eraser"), + "肢解者" or "肢解" => GetString("Butcher"), + "劊子手" or "刽子手" => GetString("Hangman"), + "隱身人" or "隐匿者" or "隐匿" or "隐身" => GetString("Swooper"), + "船鬼" => GetString("Crewpostor"), + "野人" => GetString("Wildling"), + "騙術師" or "骗术师" => GetString("Trickster"), + "衛道士" or "卫道士" or "内鬼市长" => GetString("Vindicator"), + "寄生蟲" or "寄生虫" => GetString("Parasite"), + "分散者" or "分散" => GetString("Disperser"), + "抑鬱者" or "抑郁者" or "抑郁" => GetString("Inhibitor"), + "破壞者" or "破坏者" or "破坏" => GetString("Saboteur"), + "議員" or "邪恶法官" or "议员" or "邪恶审判" => GetString("Councillor"), + "眩暈者" or "眩晕者" or "眩晕" => GetString("Dazzler"), + "簽約人" or "死亡契约" or "死亡" or "锲约" => GetString("Deathpact"), + "吞噬者" or "吞噬" => GetString("Devourer"), + "軍師" or "军师" => GetString("Consigliere"), + "化型者" or "化形者" => GetString("Morphling"), + "躁動者" or "龙卷风" => GetString("Twister"), + "策畫者" or "潜伏者" or "潜伏" => GetString("Lurker"), + "罪犯" => GetString("Convict"), + "幻想家" or "幻想" => GetString("Visionary"), + "逃亡者" or "逃亡" => GetString("Refugee"), + "潛伏者" or "失败者" or "失败的man" or "失败" => GetString("Underdog"), + "賭博者" or "速度者" or "速度" => GetString("Ludopath"), + "懸賞者" or "教父" => GetString("Godfather"), + "天文學家" or "天文学家" or "天文家" or "天文学" => GetString("Chronomancer"), + "設陷者" or "设陷者" or "设陷" => GetString("Pitfall"), + "狂戰士" or "狂战士" or "升级者" or "狂战士" => GetString("Berserker"), + "壞迷你船員" or "坏迷你船员" or "坏小孩" or "坏迷你" => GetString("EvilMini"), + "勒索者" or "勒索" => GetString("Blackmailer"), + "教唆者" or "教唆" => GetString("Instigator"), + + // 船員陣營職業 and 船员阵营职业 + "擺爛人" or "摆烂人" or "摆烂" => GetString("Needy"), + "大明星" or "明星" => GetString("SuperStar"), + "網紅" or "网红" => GetString("Celebrity"), + "清洗者" or "清洗" => GetString("Cleanser"), + "守衛者" or "守卫者" => GetString("Keeper"), + "俠客" or "侠客" or "正义使者" => GetString("Knight"), + "市長" or "市长" => GetString("Mayor"), + "被害妄想症" or "被害妄想" or "被迫害妄想症" or "被害" or "妄想" or "妄想症" => GetString("Paranoia"), + "愚者" => GetString("Psychic"), + "修理工" or "修理" or "修理大师" => GetString("Mechanic"), + "警長" or "警长" => GetString("Sheriff"), + "義警" or "义务警员" or "警员" => GetString("Vigilante"), + "監禁者" or "狱警" or "狱卒" => GetString("Jailer"), + "模仿者" or "模仿猫" or "模仿" => GetString("CopyCat"), + "告密者" => GetString("Snitch"), + "展現者" or "展现者" or "展现" => GetString("Marshall"), + "增速師" or "增速者" or "增速" => GetString("SpeedBooster"), + "法醫" or "法医" => GetString("Doctor"), + "獨裁主義者" or "独裁者" or "独裁" => GetString("Dictator"), + "偵探" or "侦探" => GetString("Detective"), + "正義賭怪" or "正义赌怪" or "好赌" or "正义的赌怪" => GetString("NiceGuesser"), + "賭場管理員" or "竞猜大师" or "竞猜" => GetString("GuessMaster"), + "傳送師" or "传送师" => GetString("Transporter"), + "時間大師" or "时间操控者" or "时间操控" => GetString("TimeManager"), + "老兵" => GetString("Veteran"), + "埋雷兵" => GetString("Bastion"), + "保鑣" or "保镖" => GetString("Bodyguard"), + "贗品商" or "赝品商" => GetString("Deceiver"), + "擲彈兵" or "掷雷兵" => GetString("Grenadier"), + "軍醫" or "医生" => GetString("Medic"), + "占卜師" or "调查员" or "占卜师" => GetString("FortuneTeller"), + "法官" or "正义法官" or "正义审判" => GetString("Judge"), + "殯葬師" or "入殓师" => GetString("Mortician"), + "通靈師" or "通灵师" => GetString("Mediumshiper"), + "和平之鴿" or "和平之鸽" => GetString("Pacifist"), + "窺視者" or "观察者" or "观察" => GetString("Observer"), + "君主" => GetString("Monarch"), + "預言家" or "预言家" or "预言" => GetString("Overseer"), + "驗屍官" or "验尸官" or "验尸" => GetString("Coroner"), + "正義的追蹤者" or "正义追踪者" or "正义的追踪者" => GetString("Tracker"), + "商人" => GetString("Merchant"), + "總統" or "总统" => GetString("President"), + "獵鷹" or "猎鹰" => GetString("Hawk"), + "捕快" or "下属" => GetString("Deputy"), + "算命師" or "研究者" => GetString("Investigator"), + "守護者" or "守护者" or "守护" => GetString("Guardian"), + "賢者" or "瘾君子" or "醉酒" => GetString("Addict"), + "鼹鼠" => GetString("Mole"), + "藥劑師" or "炼金术士" or "药剂" => GetString("Alchemist"), + "尋跡者" or "寻迹者" or "寻迹" or "寻找鸡腿" => GetString("Tracefinder"), + "先知" or "神谕" or "神谕者" => GetString("Oracle"), + "靈魂論者" or "灵魂论者" => GetString("Spiritualist"), + "變色龍" or "变色龙" or "变色" => GetString("Chameleon"), + "檢查員" or "检查员" or "检查" => GetString("Inspector"), + "仰慕者" or "仰慕" => GetString("Admirer"), + "時間之主" or "时间之主" or "回溯时间" => GetString("TimeMaster"), + "十字軍" or "十字军" => GetString("Crusader"), + "遐想者" or "遐想" => GetString("Reverie"), + "瞭望者" or "瞭望员" => GetString("Lookout"), + "通訊員" or "通信员" => GetString("Telecommunication"), + "執燈人" or "执灯人" or "执灯" or "灯人" or "小灯人" => GetString("Lighter"), + "任務管理員" or "任务管理者" => GetString("TaskManager"), + "目擊者" or "目击者" or "目击" => GetString("Witness"), + "換票師" or "换票师" => GetString("Swapper"), + "警察局長" or "警察局长" => GetString("ChiefOfPolice"), + "好迷你船員" or "好迷你船员" or "好迷你" or "好小孩" => GetString("NiceMini"), + "間諜" or "间谍" => GetString("Spy"), + "隨機者" or "萧暮" or "暮" or "萧暮不姓萧" => GetString("Randomizer"), + "猜想者" or "猜想" or "谜团" => GetString("Enigma"), + "船長" or "舰长" or "船长" => GetString("Captain"), + "慈善家" or "恩人" => GetString("Benefactor"), + + // 中立陣營職業 and 中立阵营职业 + "小丑" or "丑皇" => GetString("Jester"), + "縱火犯" or "纵火犯" or "纵火者" or "纵火" => GetString("Arsonist"), + "焚燒狂" or "焚烧狂" or "焚烧" => GetString("Pyromaniac"), + "神風特攻隊" or "神风特攻队" => GetString("Kamikaze"), + "獵人" or "猎人" => GetString("Huntsman"), + "恐怖分子" => GetString("Terrorist"), + "暴民" or "处刑人" or "处刑" or "处刑者" => GetString("Executioner"), + "律師" or "律师" => GetString("Lawyer"), + "投機主義者" or "投机者" or "投机" => GetString("Opportunist"), + "瑪利歐" or "马里奥" => GetString("Vector"), + "豺狼" or "蓝狼" => GetString("Jackal"), + "神" or "上帝" => GetString("God"), + "冤罪師" or "冤罪师" or "冤罪" => GetString("Innocent"), + "暗殺者" or "隐形者" =>GetString("Stealth"), + "企鵝" or "企鹅" =>GetString("Penguin"), + "鵜鶘" or "鹈鹕" => GetString("Pelican"), + "疫醫" or "瘟疫学家" => GetString("PlagueDoctor"), + "革命家" or "革命者" => GetString("Revolutionist"), + "單身狗" => GetString("Hater"), + "柯南" => GetString("Konan"), + "玩家" => GetString("Demon"), + "潛藏者" or "潜藏" => GetString("Stalker"), + "工作狂" => GetString("Workaholic"), + "至日者" or "至日" => GetString("Solsticer"), + "集票者" or "集票" => GetString("Collector"), + "挑釁者" or "自爆卡车" => GetString("Provocateur"), + "嗜血騎士" or "嗜血骑士" => GetString("BloodKnight"), + "瘟疫之源" or "瘟疫使者" => GetString("PlagueBearer"), + "萬疫之神" or "瘟疫" => GetString("Pestilence"), + "故障者" or "缺点者" or "缺点" => GetString("Glitch"), + "跟班" or "跟班小弟" => GetString("Sidekick"), + "追隨者" or "赌徒" or "下注" => GetString("Follower"), + "魅魔" => GetString("Cultist"), + "連環殺手" or "连环杀手" => GetString("SerialKiller"), + "劍聖" or "天启" => GetString("Juggernaut"), + "感染者" or "感染" => GetString("Infectious"), + "病原體" or "病毒" => GetString("Virus"), + "起訴人" or "起诉人" => GetString("Pursuer"), + "怨靈" or "幽灵" => GetString("Phantom"), + "挑戰者" or "决斗者" or "挑战者" => GetString("Pirate"), + "炸彈王" or "炸弹狂" or "煽动者" => GetString("Agitater"), + "獨行者" or "独行者" => GetString("Maverick"), + "被詛咒的靈魂" or "诅咒之人" => GetString("CursedSoul"), + "竊賊" or "小偷" => GetString("Pickpocket"), + "背叛者" or "背叛" => GetString("Traitor"), + "禿鷲" or "秃鹫" => GetString("Vulture"), + "搗蛋鬼" or "任务执行者" => GetString("Taskinator"), + "麵包師" or "面包师" => GetString("Baker"), + "飢荒" or "饥荒" => GetString("Famine"), + "靈魂召喚者" or "灵魂召唤者" => GetString("Spiritcaller"), + "失憶者" or "失忆者" or "失忆" => GetString("Amnesiac"), + "模仿家" or "效仿者" => GetString("Imitator"), + "強盜" => GetString("Bandit"), + "分身者" => GetString("Doppelganger"), + "受虐狂" => GetString("PunchingBag"), + "賭神" or "末日赌怪" => GetString("Doomsayer"), + "裹屍布" or "裹尸布" => GetString("Shroud"), + "月下狼人" or "狼人" => GetString("Werewolf"), + "薩滿" or "萨满" => GetString("Shaman"), + "冒險家" or "探索者" => GetString("Seeker"), + "精靈" or "小精灵" or "精灵" => GetString("Pixie"), + "咒魔" or "神秘者" => GetString("Occultist"), + "靈魂收割者" or "灵魂收集者" or "灵魂收集" or "收集灵魂" => GetString("SoulCollector"), + "薛丁格的貓" or "薛定谔的猫" => GetString("SchrodingersCat"), + "暗戀者" or "浪漫者" => GetString("Romantic"), + "報復者" or "复仇浪漫者" => GetString("VengefulRomantic"), + "絕情者" or "无情浪漫者" => GetString("RuthlessRomantic"), + "毒醫" or "投毒者" => GetString("Poisoner"), + "代碼工程師" or "巫师" => GetString("HexMaster"), + "幻影" or "魅影" => GetString("Wraith"), + "掃把星" or "扫把星" => GetString("Jinx"), + "魔藥師" or "药剂师" => GetString("PotionMaster"), + "死靈法師" or "亡灵巫师" => GetString("Necromancer"), + "測驗者" or "测验长" => GetString("Quizmaster"), + + // 附加職業 and 附加职业 + "絕境者" or "绝境者" => GetString("LastImpostor"), + "超頻" or "超频波" or "超频" => GetString("Overclocked"), + "戀人" or "恋人" => GetString("Lovers"), + "叛徒" => GetString("Madmate"), + "觀察者" or "窥视者" or "觀察" or "窥视" => GetString("Watcher"), + "閃電俠" or "闪电侠" or "閃電" or "闪电" => GetString("Flash"), + "持燈人" or "火炬" or "持燈" => GetString("Torch"), + "靈媒" or "灵媒" or "靈媒" => GetString("Seer"), + "破平者" or "破平" => GetString("Tiebreaker"), + "膽小鬼" or "胆小鬼" or "膽小" or "胆小" => GetString("Oblivious"), + "視障" or "迷幻者" or "視障" or "迷幻" => GetString("Bewilder"), + "墨鏡" or "患者" => GetString("Sunglasses"), + "加班狂" => GetString("Workhorse"), + "蠢蛋" => GetString("Fool"), + "復仇者" or "复仇者" or "復仇" or "复仇" => GetString("Avanger"), + "Youtuber" or "UP主" or "YT" => GetString("Youtuber"), + "利己主義者" or "利己主义者" or "利己主義" or "利己主义" => GetString("Egoist"), + "竊票者" or "窃票者" or "竊票" or "窃票" => GetString("TicketsStealer"), + //"雙重人格" or "双重人格" => GetString("Schizophrenic"), + "保險箱" or "宝箱怪" => GetString("Mimic"), + "賭怪" or "赌怪" => GetString("Guesser"), + "死神" => GetString("Necroview"), + "長槍" or "持枪" => GetString("Reach"), + "魅魔小弟" => GetString("Charmed"), + "乾淨" or "干净" => GetString("Cleansed"), + "誘餌" or "诱饵" => GetString("Bait"), + "陷阱師" or "陷阱师" => GetString("Trapper"), + "被感染" or "感染" => GetString("Infected"), + "防賭" or "不可被赌" => GetString("Onbound"), + "反擊者" or "回弹者" or "回弹" => GetString("Rebound"), + "平凡者" or "平凡" => GetString("Mundane"), + "騎士" or "骑士" => GetString("Knighted"), + "漠視" or "不受重视" or "被漠視的" => GetString("Unreportable"), + "被傳染" or "传染性" => GetString("Contagious"), + "幸運" or "幸运加持" => GetString("Lucky"), + "倒霉" or "倒霉蛋" => GetString("Unlucky"), + "虛無" or "无效投票" => GetString("VoidBallot"), + "敏感" or "意识者" or "意识" => GetString("Aware"), + "嬌嫩" or "脆弱" or "脆弱者" => GetString("Fragile"), + "專業" or "双重猜测" => GetString("DoubleShot"), + "流氓" => GetString("Rascal"), + "無魂" or "没有灵魂" => GetString("Soulless"), + "墓碑" => GetString("Gravestone"), + "懶人" or "懒人" => GetString("Lazy"), + "驗屍" or "尸检" => GetString("Autopsy"), + "忠誠" or "忠诚" => GetString("Loyal"), + "惡靈" or "恶灵" => GetString("EvilSpirit"), + "狼化" or "招募" or "狼化的" or "被招募的" => GetString("Recruit"), + "被仰慕" or "仰慕" => GetString("Admired"), + "發光" or "光辉" => GetString("Glow"), + "病態" or "患病者" or "患病的" or "患病" => GetString("Diseased"), + "健康" or "健康的" or "健康者" => GetString("Antidote"), + "固執者" or "固执者" or "固執" or "固执" => GetString("Stubborn"), + "無影" or "迅捷" => GetString("Swift"), + "反噬" or "食尸鬼" => GetString("Ghoul"), + "嗜血者" => GetString("Bloodthirst"), + "獵夢者" or "梦魇" or "獵夢"=> GetString("Mare"), + "地雷" or "爆破者" or "爆破" => GetString("Burst"), + "偵察員" or "侦察员" or "偵察" or "侦察" => GetString("Sleuth"), + "笨拙" or "笨蛋" => GetString("Clumsy"), + "敏捷" => GetString("Nimble"), + "規避者" or "规避者" or "规避" => GetString("Circumvent"), + "名人" or "网络员" or "网络" => GetString("Cyber"), + "焦急者" or "焦急的" or "焦急" => GetString("Hurried"), + "OIIAI" => GetString("Oiiai"), + "順從者" or "影响者" or "順從" or "影响" => GetString("Influenced"), + "沉默者" or "沉默" => GetString("Silent"), + "易感者" or "易感" => GetString("Susceptible"), + "狡猾" or "棘手者" or "棘手" => GetString("Tricky"), + "彩虹" => GetString("Rainbow"), + "疲勞者" or "疲劳者" or "疲勞" or "疲劳" => GetString("Tired"), + "雕像" => GetString("Statue"), + "没有搜集的繁体中文" or "雷达" => GetString("Radar"), + + // 幽靈職業 and 幽灵职业 + // 偽裝者 and 内鬼 + "爪牙" => GetString("Minion"), + "黑手黨" or "黑手党" or "黑手" => GetString("Nemesis"), + "嗜血之魂" or "血液伯爵" => GetString("Bloodmoon"), + // 船員 and 船员 + "没有搜集的繁体中文" or "鬼怪" => GetString("Ghastly"), + "冤魂" or "典狱长" => GetString("Warden"), + "報應者" or "惩罚者" or "惩罚" or "报仇者" => GetString("Retributionist"), + + // 随机阵营职业 + "迷你船員" or "迷你船员" or "迷你" or "小孩" or "Mini" => GetString("Mini"),*/ + _ => text, + }; + } + + public static bool GetRoleByName(string name, out CustomRoles role) + { + role = new(); + + if (name == "" || name == string.Empty) return false; + + if ((TranslationController.InstanceExists ? TranslationController.Instance.currentLanguage.languageID : SupportedLangs.SChinese) == SupportedLangs.SChinese) + { + Regex r = new("[\u4e00-\u9fa5]+$"); + MatchCollection mc = r.Matches(name); + string result = string.Empty; + for (int i = 0; i < mc.Count; i++) + { + if (mc[i].ToString() == "是") continue; + result += mc[i]; //匹配结果是完整的数字,此处可以不做拼接的 + } + name = FixRoleNameInput(result.Replace("是", string.Empty).Trim()); + } + else name = name.Trim().ToLower(); + + foreach (var rl in CustomRolesHelper.AllRoles) + { + if (rl.IsVanilla()) continue; + var roleName = GetString(rl.ToString()).ToLower().Trim().Replace(" ", ""); + string nameWithoutId = Regex.Replace(name.Replace(" ", ""), @"^\d+", ""); + if (nameWithoutId == roleName) + { + role = rl; + return true; + } + } + return false; + } + public static void SendRolesInfo(string role, byte playerId, bool isDev = false, bool isUp = false) + { + if (Options.CurrentGameMode == CustomGameMode.FFA) + { + Utils.SendMessage(GetString("ModeDescribe.FFA"), playerId); + return; + } + role = role.Trim().ToLower(); + if (role.StartsWith("/r")) _ = role.Replace("/r", string.Empty); + if (role.StartsWith("/up")) _ = role.Replace("/up", string.Empty); + if (role.EndsWith("\r\n")) _ = role.Replace("\r\n", string.Empty); + if (role.EndsWith("\n")) _ = role.Replace("\n", string.Empty); + if (role.StartsWith("/bt")) _ = role.Replace("/bt", string.Empty); + + if (role == "" || role == string.Empty) + { + Utils.ShowActiveRoles(playerId); + return; + } + + role = FixRoleNameInput(role).ToLower().Trim().Replace(" ", string.Empty); + + foreach (var rl in CustomRolesHelper.AllRoles) + { + if (rl.IsVanilla()) continue; + var roleName = GetString(rl.ToString()); + if (role == roleName.ToLower().Trim().TrimStart('*').Replace(" ", string.Empty)) + { + string devMark = ""; + if ((isDev || isUp) && GameStates.IsLobby) + { + devMark = "▲"; + if (CustomRolesHelper.IsAdditionRole(rl) || rl is CustomRoles.GM or CustomRoles.Mini || rl.IsGhostRole()) devMark = ""; + if (rl.GetCount() < 1 || rl.GetMode() == 0) devMark = ""; + if (isUp) + { + if (devMark == "▲") Utils.SendMessage(string.Format(GetString("Message.YTPlanSelected"), roleName), playerId); + else Utils.SendMessage(string.Format(GetString("Message.YTPlanSelectFailed"), roleName), playerId); + } + if (devMark == "▲") + { + byte pid = playerId == 255 ? (byte)0 : playerId; + GhostRoleAssign.forceRole.Remove(pid); + RoleAssign.SetRoles.Remove(pid); + RoleAssign.SetRoles.Add(pid, rl); + } + if (rl.IsGhostRole() && !rl.IsAdditionRole() && isDev && (rl.GetCount() >= 1 && rl.GetMode() > 0)) + { + byte pid = playerId == 255 ? (byte)0 : playerId; CustomRoles setrole = rl.GetCustomRoleTeam() switch - { - Custom_Team.Impostor => CustomRoles.ImpostorTOHE, - _ => CustomRoles.CrewmateTOHE - - }; - RoleAssign.SetRoles.Remove(pid); - RoleAssign.SetRoles.Add(pid, setrole); - GhostRoleAssign.forceRole[pid] = rl; - - devMark = "▲"; - } - - if (isUp) return; - } - var Des = rl.GetInfoLong(); - var title = devMark + $"" + rl.GetRoleTitle() + "\n"; - var Conf = new StringBuilder(); - string rlHex = Utils.GetRoleColorCode(rl); - if (Options.CustomRoleSpawnChances.ContainsKey(rl)) - { - Utils.ShowChildrenSettings(Options.CustomRoleSpawnChances[rl], ref Conf); - var cleared = Conf.ToString(); - var Setting = $"{GetString(rl.ToString())} {GetString("Settings:")}\n"; - Conf.Clear().Append($"" + $"" + Setting + cleared + "" + ""); - - } - // Show role info - Utils.SendMessage(Des, playerId, title, noReplay: true); - - // Show role settings - Utils.SendMessage("", playerId, Conf.ToString(), noReplay: true); - return; - } - } - if (isUp) Utils.SendMessage(GetString("Message.YTPlanCanNotFindRoleThePlayerEnter"), playerId); - else Utils.SendMessage(GetString("Message.CanNotFindRoleThePlayerEnter"), playerId); - return; - } - public static void OnReceiveChat(PlayerControl player, string text, out bool canceled) - { - canceled = false; - if (!AmongUsClient.Instance.AmHost) return; - - if (!Blackmailer.CheckBlackmaile(player)) ChatManager.SendMessage(player, text); - - if (text.StartsWith("\n")) text = text[1..]; - //if (!text.StartsWith("/")) return; - string[] args = text.Split(' '); - string subArgs = ""; - string subArgs2 = ""; - - //if (text.Length >= 3) if (text[..2] == "/r" && text[..3] != "/rn") args[0] = "/r"; - // if (SpamManager.CheckSpam(player, text)) return; - if (GuessManager.GuesserMsg(player, text)) { canceled = true; Logger.Info($"Is Guesser command", "OnReceiveChat"); return; } - if (player.GetRoleClass() is Judge jd && jd.TrialMsg(player, text)) { canceled = true; Logger.Info($"Is Judge command", "OnReceiveChat"); return; } - if (President.EndMsg(player, text)) { canceled = true; Logger.Info($"Is President command", "OnReceiveChat"); return; } - if (Inspector.InspectCheckMsg(player, text)) { canceled = true; Logger.Info($"Is Inspector command", "OnReceiveChat"); return; } - if (Pirate.DuelCheckMsg(player, text)) { canceled = true; Logger.Info($"Is Pirate command", "OnReceiveChat"); return; } - if (player.GetRoleClass() is Councillor cl && cl.MurderMsg(player, text)) { canceled = true; Logger.Info($"Is Councillor command", "OnReceiveChat"); return; } - if (player.GetRoleClass() is Swapper sw && sw.SwapMsg(player, text)) { canceled = true; Logger.Info($"Is Swapper command", "OnReceiveChat"); return; } - if (Medium.MsMsg(player, text)) { Logger.Info($"Is Medium command", "OnReceiveChat"); return; } - if (Nemesis.NemesisMsgCheck(player, text)) { Logger.Info($"Is Nemesis Revenge command", "OnReceiveChat"); return; } - if (Retributionist.RetributionistMsgCheck(player, text)) { Logger.Info($"Is Retributionist Revenge command", "OnReceiveChat"); return; } - - Directory.CreateDirectory(modTagsFiles); - Directory.CreateDirectory(vipTagsFiles); - Directory.CreateDirectory(sponsorTagsFiles); - - if (Blackmailer.CheckBlackmaile(player) && player.IsAlive() && !player.IsHost()) - { - Logger.Info($"This player (id {player.PlayerId}) was Blackmailed", "OnReceiveChat"); - ChatManager.SendPreviousMessagesToAll(); - ChatManager.cancel = false; - canceled = true; - return; - } - - switch (args[0]) - { - case "/r": - case "/role": - case "/р": - case "/роль": - Logger.Info($"Command '/r' was activated", "OnReceiveChat"); - if (text.Contains("/role") || text.Contains("/роль")) - subArgs = text.Remove(0, 5); - else - subArgs = text.Remove(0, 2); - SendRolesInfo(subArgs, player.PlayerId, isDev: player.FriendCode.GetDevUser().DeBug); - break; - - case "/m": - case "/myrole": - case "/minhafunção": - case "/м": + { + Custom_Team.Impostor => CustomRoles.ImpostorTOHE, + _ => CustomRoles.CrewmateTOHE + }; + + RoleAssign.SetRoles.Remove(pid); + RoleAssign.SetRoles.Add(pid, setrole); + GhostRoleAssign.forceRole[pid] = rl; + + devMark = "▲"; + } + + + if (isUp) return; + } + var Des = rl.GetInfoLong(); + var title = devMark + $"" + rl.GetRoleTitle() + "\n"; + var Conf = new StringBuilder(); + string rlHex = Utils.GetRoleColorCode(rl); + if (Options.CustomRoleSpawnChances.ContainsKey(rl)) + { + Utils.ShowChildrenSettings(Options.CustomRoleSpawnChances[rl], ref Conf); + var cleared = Conf.ToString(); + var Setting = $"{GetString(rl.ToString())} {GetString("Settings:")}\n"; + Conf.Clear().Append($"" + $"" + Setting + cleared + "" + ""); + + } + // Show role info + Utils.SendMessage(Des, playerId, title, noReplay: true); + + // Show role settings + Utils.SendMessage("", playerId, Conf.ToString(), noReplay: true); + return; + } + } + if (isUp) Utils.SendMessage(GetString("Message.YTPlanCanNotFindRoleThePlayerEnter"), playerId); + else Utils.SendMessage(GetString("Message.CanNotFindRoleThePlayerEnter"), playerId); + return; + } + public static void OnReceiveChat(PlayerControl player, string text, out bool canceled) + { + canceled = false; + if (!AmongUsClient.Instance.AmHost) return; + + if (!Blackmailer.CheckBlackmaile(player)) ChatManager.SendMessage(player, text); + + + + + if (text.StartsWith("\n")) text = text[1..]; + //if (!text.StartsWith("/")) return; + string[] args = text.Split(' '); + string subArgs = ""; + string subArgs2 = ""; + + // Role-specific message handling + if (GuessManager.GuesserMsg(player, text)) { canceled = true; Logger.Info($"Is Guesser command", "OnReceiveChat"); return; } + if (player.GetRoleClass() is Judge jd && jd.TrialMsg(player, text)) { canceled = true; Logger.Info($"Is Judge command", "OnReceiveChat"); return; } + if (President.EndMsg(player, text)) { canceled = true; Logger.Info($"Is President command", "OnReceiveChat"); return; } + if (Inspector.InspectCheckMsg(player, text)) { canceled = true; Logger.Info($"Is Inspector command", "OnReceiveChat"); return; } + if (Pirate.DuelCheckMsg(player, text)) { canceled = true; Logger.Info($"Is Pirate command", "OnReceiveChat"); return; } + if (player.GetRoleClass() is Councillor cl && cl.MurderMsg(player, text)) { canceled = true; Logger.Info($"Is Councillor command", "OnReceiveChat"); return; } + if (player.GetRoleClass() is Swapper sw && sw.SwapMsg(player, text)) { canceled = true; Logger.Info($"Is Swapper command", "OnReceiveChat"); return; } + if (Medium.MsMsg(player, text)) { Logger.Info($"Is Medium command", "OnReceiveChat"); return; } + if (Nemesis.NemesisMsgCheck(player, text)) { Logger.Info($"Is Nemesis Revenge command", "OnReceiveChat"); return; } + if (Retributionist.RetributionistMsgCheck(player, text)) { Logger.Info($"Is Retributionist Revenge command", "OnReceiveChat"); return; } + if (Evolver.EvolverCheckMsg(player, text)) { canceled = true; Logger.Info($"Is Evolver command", "OnReceiveChat"); return; } + if (Summoner.SummonerCheckMsg(player, text)) { canceled = true; Logger.Info($"Command handled for Summoner {player.PlayerId}.", "OnReceiveChat"); return;} + + + + // Create directories for chat logs if necessary + Directory.CreateDirectory(modTagsFiles); + Directory.CreateDirectory(vipTagsFiles); + Directory.CreateDirectory(sponsorTagsFiles); + + + if (Blackmailer.CheckBlackmaile(player) && player.IsAlive() && !player.IsHost()) + { + Logger.Info($"This player (id {player.PlayerId}) was Blackmailed", "OnReceiveChat"); + ChatManager.SendPreviousMessagesToAll(); + ChatManager.cancel = false; + canceled = true; + return; + } + // Summoner-Specific Message Blocking and Forwarding + + switch (args[0]) + { + case "/r": + case "/role": + case "/р": + case "/роль": + Logger.Info($"Command '/r' was activated", "OnReceiveChat"); + if (text.Contains("/role") || text.Contains("/роль")) + subArgs = text.Remove(0, 5); + else + subArgs = text.Remove(0, 2); + SendRolesInfo(subArgs, player.PlayerId, isDev: player.FriendCode.GetDevUser().DeBug); + break; + + case "/m": + case "/myrole": + case "/minhafunção": + case "/м": case "/мояроль": case "/身份": case "/我": case "/我的身份": - case "/我的职业": - Logger.Info($"Command '/m' was activated", "OnReceiveChat"); - var role = player.GetCustomRole(); - if (GameStates.IsInGame) - { - var Des = player.GetRoleInfo(true); - var title = $"" + role.GetRoleTitle() + "\n"; - var Conf = new StringBuilder(); - var Sub = new StringBuilder(); - var rlHex = Utils.GetRoleColorCode(role); - var SubTitle = $"" + GetString("YourAddon") + "\n"; - - if (Options.CustomRoleSpawnChances.TryGetValue(role, out var opt)) - Utils.ShowChildrenSettings(opt, ref Conf); - var cleared = Conf.ToString(); - var Setting = $"{GetString(role.ToString())} {GetString("Settings:")}\n"; - Conf.Clear().Append($"" + $"" + Setting + cleared + "" + ""); - - foreach (var subRole in Main.PlayerStates[player.PlayerId].SubRoles.ToArray()) - { - Sub.Append($"\n\n" + $"" + Utils.GetRoleTitle(subRole) + Utils.GetInfoLong(subRole) + ""); - - } - if (Sub.ToString() != string.Empty) - { - var ACleared = Sub.ToString().Remove(0, 2); - ACleared = ACleared.Length > 1200 ? $"" + ACleared.RemoveHtmlTags() + "": ACleared; - Sub.Clear().Append(ACleared); - } - - Utils.SendMessage(Des, player.PlayerId, title, noReplay: true); - Utils.SendMessage("", player.PlayerId, Conf.ToString(), noReplay: true); - if (Sub.ToString() != string.Empty) Utils.SendMessage(Sub.ToString(), player.PlayerId, SubTitle, noReplay: true); - - Logger.Info($"Command '/m' should be send message", "OnReceiveChat"); - } - else - Utils.SendMessage(GetString("Message.CanNotUseInLobby"), player.PlayerId); - break; - - case "/h": - case "/help": - case "/ajuda": - case "/хелп": - case "/хэлп": + case "/我的职业": + Logger.Info($"Command '/m' was activated", "OnReceiveChat"); + var role = player.GetCustomRole(); + if (GameStates.IsInGame) + { + var Des = player.GetRoleInfo(true); + var title = $"" + role.GetRoleTitle() + "\n"; + var Conf = new StringBuilder(); + var Sub = new StringBuilder(); + var rlHex = Utils.GetRoleColorCode(role); + var SubTitle = $"" + GetString("YourAddon") + "\n"; + + if (Options.CustomRoleSpawnChances.TryGetValue(role, out var opt)) + Utils.ShowChildrenSettings(opt, ref Conf); + var cleared = Conf.ToString(); + var Setting = $"{GetString(role.ToString())} {GetString("Settings:")}\n"; + Conf.Clear().Append($"" + $"" + Setting + cleared + "" + ""); + + foreach (var subRole in Main.PlayerStates[player.PlayerId].SubRoles.ToArray()) + { + Sub.Append($"\n\n" + $"" + Utils.GetRoleTitle(subRole) + Utils.GetInfoLong(subRole) + ""); + + } + if (Sub.ToString() != string.Empty) + { + var ACleared = Sub.ToString().Remove(0, 2); + ACleared = ACleared.Length > 1200 ? $"" + ACleared.RemoveHtmlTags() + "": ACleared; + Sub.Clear().Append(ACleared); + } + + Utils.SendMessage(Des, player.PlayerId, title, noReplay: true); + Utils.SendMessage("", player.PlayerId, Conf.ToString(), noReplay: true); + if (Sub.ToString() != string.Empty) Utils.SendMessage(Sub.ToString(), player.PlayerId, SubTitle, noReplay: true); + + Logger.Info($"Command '/m' should be send message", "OnReceiveChat"); + } + else + Utils.SendMessage(GetString("Message.CanNotUseInLobby"), player.PlayerId); + break; + + case "/h": + case "/help": + case "/ajuda": + case "/хелп": + case "/хэлп": case "/помощь": case "/帮助": - case "/教程": - Utils.ShowHelpToClient(player.PlayerId); - break; - - case "/ans": - case "/asw": + case "/教程": + Utils.ShowHelpToClient(player.PlayerId); + break; + + case "/ans": + case "/asw": case "/answer": - case "/回答": - Quizmaster.AnswerByChat(player, args); - break; - + case "/回答": + Quizmaster.AnswerByChat(player, args); + break; + case "/qmquiz": - case "/提问": - Quizmaster.ShowQuestion(player); - break; - - case "/l": - case "/lastresult": + case "/提问": + Quizmaster.ShowQuestion(player); + break; + + case "/l": + case "/lastresult": case "/fimdejogo": case "/上局信息": case "/信息": - case "/情况": - Utils.ShowKillLog(player.PlayerId); - Utils.ShowLastRoles(player.PlayerId); - Utils.ShowLastResult(player.PlayerId); - break; - - case "/gr": - case "/gameresults": + case "/情况": + Utils.ShowKillLog(player.PlayerId); + Utils.ShowLastRoles(player.PlayerId); + Utils.ShowLastResult(player.PlayerId); + break; + + case "/gr": + case "/gameresults": case "/resultados": case "/对局结果": case "/上局结果": - case "/结果": - Utils.ShowLastResult(player.PlayerId); - break; - - case "/kh": + case "/结果": + Utils.ShowLastResult(player.PlayerId); + break; + + case "/kh": case "/killlog": case "/击杀日志": - case "/击杀情况": - Utils.ShowKillLog(player.PlayerId); - break; - - case "/rs": - case "/sum": - case "/rolesummary": - case "/sumario": - case "/sumário": - case "/summary": + case "/击杀情况": + Utils.ShowKillLog(player.PlayerId); + break; + + case "/rs": + case "/sum": + case "/rolesummary": + case "/sumario": + case "/sumário": + case "/summary": case "/результат": case "/上局职业": case "/职业信息": - case "/对局职业": - Utils.ShowLastRoles(player.PlayerId); - break; - + case "/对局职业": + Utils.ShowLastRoles(player.PlayerId); + break; + case "/ghostinfo": case "/幽灵职业介绍": case "/鬼魂职业介绍": case "/幽灵职业": - case "/鬼魂职业": - if (GameStates.IsInGame) - { - Utils.SendMessage(GetString("Message.OnlyCanUseInLobby"), player.PlayerId); - break; - } - Utils.SendMessage(GetString("Message.GhostRoleInfo"), player.PlayerId); - break; - - case "/apocinfo": + case "/鬼魂职业": + if (GameStates.IsInGame) + { + Utils.SendMessage(GetString("Message.OnlyCanUseInLobby"), player.PlayerId); + break; + } + Utils.SendMessage(GetString("Message.GhostRoleInfo"), player.PlayerId); + break; + + case "/apocinfo": case "/apocalypseinfo": case "/末日中立职业介绍": case "/末日中立介绍": case "/末日类中立职业介绍": - case "/末日类中立介绍": - Utils.SendMessage(GetString("Message.ApocalypseInfo"), player.PlayerId, Utils.ColorString(Utils.GetRoleColor(CustomRoles.Apocalypse), GetString("ApocalypseInfoTitle"))); - break; - - case "/rn": - case "/rename": - case "/renomear": + case "/末日类中立介绍": + Utils.SendMessage(GetString("Message.ApocalypseInfo"), player.PlayerId, Utils.ColorString(Utils.GetRoleColor(CustomRoles.Apocalypse), GetString("ApocalypseInfoTitle"))); + break; + + case "/rn": + case "/rename": + case "/renomear": case "/переименовать": case "/重命名": - case "/命名为": - if (Options.PlayerCanSetName.GetBool() || player.FriendCode.GetDevUser().IsDev || player.FriendCode.GetDevUser().NameCmd || Utils.IsPlayerVIP(player.FriendCode)) - { - if (GameStates.IsInGame) - { - Utils.SendMessage(GetString("Message.OnlyCanUseInLobby"), player.PlayerId); - break; - } - if (args.Length < 1) break; - if (args.Skip(1).Join(delimiter: " ").Length is > 10 or < 1) - { - Utils.SendMessage(GetString("Message.AllowNameLength"), player.PlayerId); - break; - } - Main.AllPlayerNames[player.PlayerId] = args.Skip(1).Join(delimiter: " "); - Utils.SendMessage(string.Format(GetString("Message.SetName"), args.Skip(1).Join(delimiter: " ")), player.PlayerId); - break; - } - else - { - Utils.SendMessage(GetString("DisableUseCommand"), player.PlayerId); - } - break; - - case "/n": - case "/now": + case "/命名为": + if (Options.PlayerCanSetName.GetBool() || player.FriendCode.GetDevUser().IsDev || player.FriendCode.GetDevUser().NameCmd || Utils.IsPlayerVIP(player.FriendCode)) + { + if (GameStates.IsInGame) + { + Utils.SendMessage(GetString("Message.OnlyCanUseInLobby"), player.PlayerId); + break; + } + if (args.Length < 1) break; + if (args.Skip(1).Join(delimiter: " ").Length is > 10 or < 1) + { + Utils.SendMessage(GetString("Message.AllowNameLength"), player.PlayerId); + break; + } + Main.AllPlayerNames[player.PlayerId] = args.Skip(1).Join(delimiter: " "); + Utils.SendMessage(string.Format(GetString("Message.SetName"), args.Skip(1).Join(delimiter: " ")), player.PlayerId); + break; + } + else + { + Utils.SendMessage(GetString("DisableUseCommand"), player.PlayerId); + } + break; + + case "/n": + case "/now": case "/atual": case "/设置": case "/系统设置": - case "/模组设置": - subArgs = args.Length < 2 ? "" : args[1]; - switch (subArgs) - { - case "r": - case "roles": - case "funções": - Utils.ShowActiveRoles(player.PlayerId); - break; - case "a": - case "all": - case "tudo": - Utils.ShowAllActiveSettings(player.PlayerId); - break; - default: - Utils.ShowActiveSettings(player.PlayerId); - break; - } - break; - + case "/模组设置": + subArgs = args.Length < 2 ? "" : args[1]; + switch (subArgs) + { + case "r": + case "roles": + case "funções": + Utils.ShowActiveRoles(player.PlayerId); + break; + case "a": + case "all": + case "tudo": + Utils.ShowAllActiveSettings(player.PlayerId); + break; + default: + Utils.ShowActiveSettings(player.PlayerId); + break; + } + break; + case "/up": case "/指定": - case "/成为": - _ = text.Remove(0, 3); - if (!Options.EnableUpMode.GetBool()) - { - Utils.SendMessage(string.Format(GetString("Message.YTPlanDisabled"), GetString("EnableYTPlan")), player.PlayerId); - break; - } - else - { - Utils.SendMessage(GetString("Message.OnlyCanBeUsedByHost"), player.PlayerId); - break; - } - - case "/win": - case "/winner": + case "/成为": + _ = text.Remove(0, 3); + if (!Options.EnableUpMode.GetBool()) + { + Utils.SendMessage(string.Format(GetString("Message.YTPlanDisabled"), GetString("EnableYTPlan")), player.PlayerId); + break; + } + else + { + Utils.SendMessage(GetString("Message.OnlyCanBeUsedByHost"), player.PlayerId); + break; + } + + case "/win": + case "/winner": case "/vencedor": case "/胜利": case "/获胜": case "/赢": case "/胜利者": case "/获胜的人": - case "/赢家": - if (Main.winnerNameList.Count == 0) Utils.SendMessage(GetString("NoInfoExists"), player.PlayerId); - else Utils.SendMessage("Winner: " + string.Join(", ", Main.winnerNameList), player.PlayerId); - break; - - - case "/pv": - canceled = true; - if (!Pollvotes.Any()) - { - Utils.SendMessage(GetString("Poll.Inactive"), player.PlayerId); - break; - } - if (PollVoted.Contains(player.PlayerId)) - { - Utils.SendMessage(GetString("Poll.AlreadyVoted"), player.PlayerId); - break; - } - - subArgs = args.Length != 2 ? "" : args[1]; - char vote = ' '; - - if (int.TryParse(subArgs, out int integer) && (Pollvotes.Count - 1) >= integer) - { - vote = char.ToUpper((char)(integer + 65)); - } - else if (!(char.TryParse(subArgs, out vote) && Pollvotes.ContainsKey(char.ToUpper(vote)))) - { - Utils.SendMessage(GetString("Poll.VotingInfo"), player.PlayerId); - break; - } - vote = char.ToUpper(vote); - - PollVoted.Add(player.PlayerId); - Pollvotes[vote]++; - Utils.SendMessage(string.Format(GetString("Poll.YouVoted"), vote, Pollvotes[vote]), player.PlayerId); - Logger.Info($"The new value of {vote} is {Pollvotes[vote]}", "TestPV_CHAR"); - - break; - - case "/icon": + case "/赢家": + if (Main.winnerNameList.Count == 0) Utils.SendMessage(GetString("NoInfoExists"), player.PlayerId); + else Utils.SendMessage("Winner: " + string.Join(", ", Main.winnerNameList), player.PlayerId); + break; + + + case "/pv": + canceled = true; + if (!Pollvotes.Any()) + { + Utils.SendMessage(GetString("Poll.Inactive"), player.PlayerId); + break; + } + if (PollVoted.Contains(player.PlayerId)) + { + Utils.SendMessage(GetString("Poll.AlreadyVoted"), player.PlayerId); + break; + } + + subArgs = args.Length != 2 ? "" : args[1]; + char vote = ' '; + + if (int.TryParse(subArgs, out int integer) && (Pollvotes.Count - 1) >= integer) + { + vote = char.ToUpper((char)(integer + 65)); + } + else if (!(char.TryParse(subArgs, out vote) && Pollvotes.ContainsKey(char.ToUpper(vote)))) + { + Utils.SendMessage(GetString("Poll.VotingInfo"), player.PlayerId); + break; + } + vote = char.ToUpper(vote); + + PollVoted.Add(player.PlayerId); + Pollvotes[vote]++; + Utils.SendMessage(string.Format(GetString("Poll.YouVoted"), vote, Pollvotes[vote]), player.PlayerId); + Logger.Info($"The new value of {vote} is {Pollvotes[vote]}", "TestPV_CHAR"); + + break; + + case "/icon": case "/icons": case "/符号": - case "/标志": - { - Utils.SendMessage(GetString("Command.icons"), player.PlayerId, GetString("IconsTitle")); - break; - } - - case "/kc": - case "/kcount": - case "/количество": + case "/标志": + { + Utils.SendMessage(GetString("Command.icons"), player.PlayerId, GetString("IconsTitle")); + break; + } + + case "/kc": + case "/kcount": + case "/количество": case "/убийцы": case "/存活阵营": case "/阵营": case "/存货阵营信息": - case "/阵营信息": - if (GameStates.IsLobby || !Options.EnableKillerLeftCommand.GetBool()) break; - - var allAlivePlayers = Main.AllAlivePlayerControls; - int impnum = allAlivePlayers.Count(pc => pc.Is(Custom_Team.Impostor)); - int madnum = allAlivePlayers.Count(pc => pc.GetCustomRole().IsMadmate() || pc.Is(CustomRoles.Madmate)); - int apocnum = allAlivePlayers.Count(pc => pc.GetCustomRole().IsNA()); - int neutralnum = allAlivePlayers.Count(pc => pc.GetCustomRole().IsNK()); - - var sub = new StringBuilder(); - sub.Append(string.Format(GetString("Remaining.ImpostorCount"), impnum)); - - if (Options.ShowMadmatesInLeftCommand.GetBool()) - sub.Append(string.Format("\n\r" + GetString("Remaining.MadmateCount"), madnum)); - - if (Options.ShowApocalypseInLeftCommand.GetBool()) - sub.Append(string.Format("\n\r" + GetString("Remaining.ApocalypseCount"), apocnum)); - - sub.Append(string.Format("\n\r" + GetString("Remaining.NeutralCount"), neutralnum)); - - Utils.SendMessage(sub.ToString(), player.PlayerId); - break; - - case "/d": - case "/death": - case "/morto": - case "/умер": + case "/阵营信息": + if (GameStates.IsLobby || !Options.EnableKillerLeftCommand.GetBool()) break; + + var allAlivePlayers = Main.AllAlivePlayerControls; + int impnum = allAlivePlayers.Count(pc => pc.Is(Custom_Team.Impostor)); + int madnum = allAlivePlayers.Count(pc => pc.GetCustomRole().IsMadmate() || pc.Is(CustomRoles.Madmate)); + int apocnum = allAlivePlayers.Count(pc => pc.GetCustomRole().IsNA()); + int neutralnum = allAlivePlayers.Count(pc => pc.GetCustomRole().IsNK()); + + var sub = new StringBuilder(); + sub.Append(string.Format(GetString("Remaining.ImpostorCount"), impnum)); + + if (Options.ShowMadmatesInLeftCommand.GetBool()) + sub.Append(string.Format("\n\r" + GetString("Remaining.MadmateCount"), madnum)); + + if (Options.ShowApocalypseInLeftCommand.GetBool()) + sub.Append(string.Format("\n\r" + GetString("Remaining.ApocalypseCount"), apocnum)); + + sub.Append(string.Format("\n\r" + GetString("Remaining.NeutralCount"), neutralnum)); + + Utils.SendMessage(sub.ToString(), player.PlayerId); + break; + + case "/d": + case "/death": + case "/morto": + case "/умер": case "/причина": case "/死亡原因": - case "/死亡": - if (GameStates.IsLobby) - { - Utils.SendMessage(GetString("Message.CanNotUseInLobby"), player.PlayerId); - break; - } - else if (player.IsAlive()) - { - Utils.SendMessage(GetString("DeathCmd.HeyPlayer") + "" + player.GetRealName() + "" + GetString("DeathCmd.YouAreRole") + "" + $"{Utils.GetRoleName(player.GetCustomRole())}" + "\n\n" + GetString("DeathCmd.NotDead"), player.PlayerId); - break; - } - else if (Main.PlayerStates[player.PlayerId].deathReason == PlayerState.DeathReason.Vote) - { - Utils.SendMessage(GetString("DeathCmd.YourName") + "" + player.GetRealName() + "" + "\n\r" + GetString("DeathCmd.YourRole") + "" + $"{Utils.GetRoleName(player.GetCustomRole())}" + "" + "\n\r" + GetString("DeathCmd.Ejected"), player.PlayerId); - break; - } - else if (Main.PlayerStates[player.PlayerId].deathReason == PlayerState.DeathReason.Shrouded) - { - Utils.SendMessage(GetString("DeathCmd.YourName") + "" + player.GetRealName() + "" + "\n\r" + GetString("DeathCmd.YourRole") + "" + $"{Utils.GetRoleName(player.GetCustomRole())}" + "" + "\n\r" + GetString("DeathCmd.Shrouded"), player.PlayerId); - break; - } - else if (Main.PlayerStates[player.PlayerId].deathReason == PlayerState.DeathReason.FollowingSuicide) - { - Utils.SendMessage(GetString("DeathCmd.YourName") + "" + player.GetRealName() + "" + "\n\r" + GetString("DeathCmd.YourRole") + "" + $"{Utils.GetRoleName(player.GetCustomRole())}" + "" + "\n\r" + GetString("DeathCmd.Lovers"), player.PlayerId); - break; - } - else - { - var killer = player.GetRealKiller(out var MurderRole); - string killerName = killer == null ? "N/A" : killer.GetRealName(); - string killerRole = killer == null ? "N/A" : Utils.GetRoleName(MurderRole); - Utils.SendMessage(GetString("DeathCmd.YourName") + "" + player.GetRealName() + "" + "\n\r" + GetString("DeathCmd.YourRole") + "" + $"{Utils.GetRoleName(player.GetCustomRole())}" + "" + "\n\r" + GetString("DeathCmd.DeathReason") + "" + Utils.GetVitalText(player.PlayerId) + "" + "\n\r" + "" + "\n\r" + GetString("DeathCmd.KillerName") + "" + killerName + "" + "\n\r" + GetString("DeathCmd.KillerRole") + "" + $"{killerRole}" + "", player.PlayerId); - break; - } - - case "/t": - case "/template": - case "/шаблон": + case "/死亡": + if (GameStates.IsLobby) + { + Utils.SendMessage(GetString("Message.CanNotUseInLobby"), player.PlayerId); + break; + } + else if (player.IsAlive()) + { + Utils.SendMessage(GetString("DeathCmd.HeyPlayer") + "" + player.GetRealName() + "" + GetString("DeathCmd.YouAreRole") + "" + $"{Utils.GetRoleName(player.GetCustomRole())}" + "\n\n" + GetString("DeathCmd.NotDead"), player.PlayerId); + break; + } + else if (Main.PlayerStates[player.PlayerId].deathReason == PlayerState.DeathReason.Vote) + { + Utils.SendMessage(GetString("DeathCmd.YourName") + "" + player.GetRealName() + "" + "\n\r" + GetString("DeathCmd.YourRole") + "" + $"{Utils.GetRoleName(player.GetCustomRole())}" + "" + "\n\r" + GetString("DeathCmd.Ejected"), player.PlayerId); + break; + } + else if (Main.PlayerStates[player.PlayerId].deathReason == PlayerState.DeathReason.Shrouded) + { + Utils.SendMessage(GetString("DeathCmd.YourName") + "" + player.GetRealName() + "" + "\n\r" + GetString("DeathCmd.YourRole") + "" + $"{Utils.GetRoleName(player.GetCustomRole())}" + "" + "\n\r" + GetString("DeathCmd.Shrouded"), player.PlayerId); + break; + } + else if (Main.PlayerStates[player.PlayerId].deathReason == PlayerState.DeathReason.FollowingSuicide) + { + Utils.SendMessage(GetString("DeathCmd.YourName") + "" + player.GetRealName() + "" + "\n\r" + GetString("DeathCmd.YourRole") + "" + $"{Utils.GetRoleName(player.GetCustomRole())}" + "" + "\n\r" + GetString("DeathCmd.Lovers"), player.PlayerId); + break; + } + else + { + var killer = player.GetRealKiller(out var MurderRole); + string killerName = killer == null ? "N/A" : killer.GetRealName(); + string killerRole = killer == null ? "N/A" : Utils.GetRoleName(MurderRole); + Utils.SendMessage(GetString("DeathCmd.YourName") + "" + player.GetRealName() + "" + "\n\r" + GetString("DeathCmd.YourRole") + "" + $"{Utils.GetRoleName(player.GetCustomRole())}" + "" + "\n\r" + GetString("DeathCmd.DeathReason") + "" + Utils.GetVitalText(player.PlayerId) + "" + "\n\r" + "" + "\n\r" + GetString("DeathCmd.KillerName") + "" + killerName + "" + "\n\r" + GetString("DeathCmd.KillerRole") + "" + $"{killerRole}" + "", player.PlayerId); + break; + } + + case "/t": + case "/template": + case "/шаблон": case "/пример": case "/模板": - case "/模板信息": - if (args.Length > 1) TemplateManager.SendTemplate(args[1], player.PlayerId); - else Utils.SendMessage($"{GetString("ForExample")}:\n{args[0]} test", player.PlayerId); - break; - - case "/colour": - case "/color": - case "/cor": + case "/模板信息": + if (args.Length > 1) TemplateManager.SendTemplate(args[1], player.PlayerId); + else Utils.SendMessage($"{GetString("ForExample")}:\n{args[0]} test", player.PlayerId); + break; + + case "/colour": + case "/color": + case "/cor": case "/цвет": case "/颜色": case "/更改颜色": case "/修改颜色": - case "/换颜色": - if (Options.PlayerCanSetColor.GetBool() || player.FriendCode.GetDevUser().IsDev || player.FriendCode.GetDevUser().ColorCmd || Utils.IsPlayerVIP(player.FriendCode)) - { - if (GameStates.IsInGame) - { - Utils.SendMessage(GetString("Message.OnlyCanUseInLobby"), player.PlayerId); - break; - } - subArgs = args.Length < 2 ? "" : args[1]; - var color = Utils.MsgToColor(subArgs); - if (color == byte.MaxValue) - { - Utils.SendMessage(GetString("IllegalColor"), player.PlayerId); - break; - } - player.RpcSetColor(color); - Utils.SendMessage(string.Format(GetString("Message.SetColor"), subArgs), player.PlayerId); - } - else - { - Utils.SendMessage(GetString("DisableUseCommand"), player.PlayerId); - } - break; - - case "/quit": - case "/qt": + case "/换颜色": + if (Options.PlayerCanSetColor.GetBool() || player.FriendCode.GetDevUser().IsDev || player.FriendCode.GetDevUser().ColorCmd || Utils.IsPlayerVIP(player.FriendCode)) + { + if (GameStates.IsInGame) + { + Utils.SendMessage(GetString("Message.OnlyCanUseInLobby"), player.PlayerId); + break; + } + subArgs = args.Length < 2 ? "" : args[1]; + var color = Utils.MsgToColor(subArgs); + if (color == byte.MaxValue) + { + Utils.SendMessage(GetString("IllegalColor"), player.PlayerId); + break; + } + player.RpcSetColor(color); + Utils.SendMessage(string.Format(GetString("Message.SetColor"), subArgs), player.PlayerId); + } + else + { + Utils.SendMessage(GetString("DisableUseCommand"), player.PlayerId); + } + break; + + case "/quit": + case "/qt": case "/sair": case "/退出": - case "/退": - if (Options.PlayerCanUseQuitCommand.GetBool()) - { - subArgs = args.Length < 2 ? "" : args[1]; - var cid = player.PlayerId.ToString(); - cid = cid.Length != 1 ? cid.Substring(1, 1) : cid; - if (subArgs.Equals(cid)) - { - string name = player.GetRealName(); - Utils.SendMessage(string.Format(GetString("Message.PlayerQuitForever"), name)); - AmongUsClient.Instance.KickPlayer(player.GetClientId(), true); - } - else - { - Utils.SendMessage(string.Format(GetString("SureUse.quit"), cid), player.PlayerId); - } - } - else - { - Utils.SendMessage(GetString("DisableUseCommand"), player.PlayerId); - } - break; - - case "/id": + case "/退": + if (Options.PlayerCanUseQuitCommand.GetBool()) + { + subArgs = args.Length < 2 ? "" : args[1]; + var cid = player.PlayerId.ToString(); + cid = cid.Length != 1 ? cid.Substring(1, 1) : cid; + if (subArgs.Equals(cid)) + { + string name = player.GetRealName(); + Utils.SendMessage(string.Format(GetString("Message.PlayerQuitForever"), name)); + AmongUsClient.Instance.KickPlayer(player.GetClientId(), true); + } + else + { + Utils.SendMessage(string.Format(GetString("SureUse.quit"), cid), player.PlayerId); + } + } + else + { + Utils.SendMessage(GetString("DisableUseCommand"), player.PlayerId); + } + break; + + case "/id": case "/айди": case "/编号": - case "/玩家编号": - if ((Options.ApplyModeratorList.GetValue() == 0 || !Utils.IsPlayerModerator(player.FriendCode)) - && !Options.EnableVoteCommand.GetBool()) break; - - string msgText = GetString("PlayerIdList"); - foreach (var pc in Main.AllPlayerControls) - { - if (pc == null) continue; - msgText += "\n" + pc.PlayerId.ToString() + " → " + pc.GetRealName(); - } - Utils.SendMessage(msgText, player.PlayerId); - break; - + case "/玩家编号": + if ((Options.ApplyModeratorList.GetValue() == 0 || !Utils.IsPlayerModerator(player.FriendCode)) + && !Options.EnableVoteCommand.GetBool()) break; + + string msgText = GetString("PlayerIdList"); + foreach (var pc in Main.AllPlayerControls) + { + if (pc == null) continue; + msgText += "\n" + pc.PlayerId.ToString() + " → " + pc.GetRealName(); + } + Utils.SendMessage(msgText, player.PlayerId); + break; + case "/mid": case "/玩家列表": case "/玩家信息": - case "/玩家编号列表": - //canceled = true; - //checking if modlist on or not - if (Options.ApplyModeratorList.GetValue() == 0) - { - Utils.SendMessage(GetString("midCommandDisabled"), player.PlayerId); - break; - } - //checking if player is has necessary privellege or not - if (!Utils.IsPlayerModerator(player.FriendCode)) - { - Utils.SendMessage(GetString("midCommandNoAccess"), player.PlayerId); - break; - } - string msgText1 = GetString("PlayerIdList"); - foreach (var pc in Main.AllPlayerControls) - { - if (pc == null) continue; - msgText1 += "\n" + pc.PlayerId.ToString() + " → " + pc.GetRealName(); - } - Utils.SendMessage(msgText1, player.PlayerId); - break; - - case "/ban": - case "/banir": - case "/бан": + case "/玩家编号列表": + //canceled = true; + //checking if modlist on or not + if (Options.ApplyModeratorList.GetValue() == 0) + { + Utils.SendMessage(GetString("midCommandDisabled"), player.PlayerId); + break; + } + //checking if player is has necessary privellege or not + if (!Utils.IsPlayerModerator(player.FriendCode)) + { + Utils.SendMessage(GetString("midCommandNoAccess"), player.PlayerId); + break; + } + string msgText1 = GetString("PlayerIdList"); + foreach (var pc in Main.AllPlayerControls) + { + if (pc == null) continue; + msgText1 += "\n" + pc.PlayerId.ToString() + " → " + pc.GetRealName(); + } + Utils.SendMessage(msgText1, player.PlayerId); + break; + + case "/ban": + case "/banir": + case "/бан": case "/забанить": - case "/封禁": - //canceled = true; - // Check if the ban command is enabled in the settings - if (Options.ApplyModeratorList.GetValue() == 0) - { - Utils.SendMessage(GetString("BanCommandDisabled"), player.PlayerId); - break; - } - - // Check if the player has the necessary privileges to use the command - if (!Utils.IsPlayerModerator(player.FriendCode)) - { - Utils.SendMessage(GetString("BanCommandNoAccess"), player.PlayerId); - break; - } - string banReason; - if (args.Length < 3) - { - Utils.SendMessage(GetString("BanCommandNoReason"), player.PlayerId); - break; - } - else - { - subArgs = args[1]; - banReason = string.Join(" ", args.Skip(2)); - } - //subArgs = args.Length < 2 ? "" : args[1]; - if (string.IsNullOrEmpty(subArgs) || !byte.TryParse(subArgs, out byte banPlayerId)) - { - Utils.SendMessage(GetString("BanCommandInvalidID"), player.PlayerId); - break; - } - - if (banPlayerId == 0) - { - Utils.SendMessage(GetString("BanCommandBanHost"), player.PlayerId); - break; - } - - var bannedPlayer = Utils.GetPlayerById(banPlayerId); - if (bannedPlayer == null) - { - Utils.SendMessage(GetString("BanCommandInvalidID"), player.PlayerId); - break; - } - - // Prevent moderators from baning other moderators - if (Utils.IsPlayerModerator(bannedPlayer.FriendCode)) - { - Utils.SendMessage(GetString("BanCommandBanMod"), player.PlayerId); - break; - } - - // Ban the specified player - AmongUsClient.Instance.KickPlayer(bannedPlayer.GetClientId(), true); - string bannedPlayerName = bannedPlayer.GetRealName(); - string textToSend1 = $"{bannedPlayerName} {GetString("BanCommandBanned")}{player.name} \nReason: {banReason}\n"; - if (GameStates.IsInGame) - { - textToSend1 += $" {GetString("BanCommandBannedRole")} {GetString(bannedPlayer.GetCustomRole().ToString())}"; - } - Utils.SendMessage(textToSend1); - //string moderatorName = player.GetRealName().ToString(); - //int startIndex = moderatorName.IndexOf("♥") + "♥".Length; - //moderatorName = moderatorName.Substring(startIndex); - //string extractedString = - string modLogname = Main.AllPlayerNames.TryGetValue(player.PlayerId, out var n1) ? n1 : ""; - string banlogname = Main.AllPlayerNames.TryGetValue(bannedPlayer.PlayerId, out var n11) ? n11 : ""; - string moderatorFriendCode = player.FriendCode.ToString(); - string bannedPlayerFriendCode = bannedPlayer.FriendCode.ToString(); - string bannedPlayerHashPuid = bannedPlayer.GetClient().GetHashedPuid(); - string logMessage = $"[{DateTime.Now}] {moderatorFriendCode},{modLogname} Banned: {bannedPlayerFriendCode},{bannedPlayerHashPuid},{banlogname} Reason: {banReason}"; - File.AppendAllText(modLogFiles, logMessage + Environment.NewLine); - break; - - case "/warn": - case "/aviso": - case "/варн": - case "/пред": + case "/封禁": + //canceled = true; + // Check if the ban command is enabled in the settings + if (Options.ApplyModeratorList.GetValue() == 0) + { + Utils.SendMessage(GetString("BanCommandDisabled"), player.PlayerId); + break; + } + + // Check if the player has the necessary privileges to use the command + if (!Utils.IsPlayerModerator(player.FriendCode)) + { + Utils.SendMessage(GetString("BanCommandNoAccess"), player.PlayerId); + break; + } + string banReason; + if (args.Length < 3) + { + Utils.SendMessage(GetString("BanCommandNoReason"), player.PlayerId); + break; + } + else + { + subArgs = args[1]; + banReason = string.Join(" ", args.Skip(2)); + } + //subArgs = args.Length < 2 ? "" : args[1]; + if (string.IsNullOrEmpty(subArgs) || !byte.TryParse(subArgs, out byte banPlayerId)) + { + Utils.SendMessage(GetString("BanCommandInvalidID"), player.PlayerId); + break; + } + + if (banPlayerId == 0) + { + Utils.SendMessage(GetString("BanCommandBanHost"), player.PlayerId); + break; + } + + var bannedPlayer = Utils.GetPlayerById(banPlayerId); + if (bannedPlayer == null) + { + Utils.SendMessage(GetString("BanCommandInvalidID"), player.PlayerId); + break; + } + + // Prevent moderators from baning other moderators + if (Utils.IsPlayerModerator(bannedPlayer.FriendCode)) + { + Utils.SendMessage(GetString("BanCommandBanMod"), player.PlayerId); + break; + } + + // Ban the specified player + AmongUsClient.Instance.KickPlayer(bannedPlayer.GetClientId(), true); + string bannedPlayerName = bannedPlayer.GetRealName(); + string textToSend1 = $"{bannedPlayerName} {GetString("BanCommandBanned")}{player.name} \nReason: {banReason}\n"; + if (GameStates.IsInGame) + { + textToSend1 += $" {GetString("BanCommandBannedRole")} {GetString(bannedPlayer.GetCustomRole().ToString())}"; + } + Utils.SendMessage(textToSend1); + //string moderatorName = player.GetRealName().ToString(); + //int startIndex = moderatorName.IndexOf("♥") + "♥".Length; + //moderatorName = moderatorName.Substring(startIndex); + //string extractedString = + string modLogname = Main.AllPlayerNames.TryGetValue(player.PlayerId, out var n1) ? n1 : ""; + string banlogname = Main.AllPlayerNames.TryGetValue(bannedPlayer.PlayerId, out var n11) ? n11 : ""; + string moderatorFriendCode = player.FriendCode.ToString(); + string bannedPlayerFriendCode = bannedPlayer.FriendCode.ToString(); + string bannedPlayerHashPuid = bannedPlayer.GetClient().GetHashedPuid(); + string logMessage = $"[{DateTime.Now}] {moderatorFriendCode},{modLogname} Banned: {bannedPlayerFriendCode},{bannedPlayerHashPuid},{banlogname} Reason: {banReason}"; + File.AppendAllText(modLogFiles, logMessage + Environment.NewLine); + break; + + case "/warn": + case "/aviso": + case "/варн": + case "/пред": case "/предупредить": case "/警告": - case "/提醒": - if (Options.ApplyModeratorList.GetValue() == 0) - { - Utils.SendMessage(GetString("WarnCommandDisabled"), player.PlayerId); - break; - } - if (!Utils.IsPlayerModerator(player.FriendCode)) - { - Utils.SendMessage(GetString("WarnCommandNoAccess"), player.PlayerId); - break; - } - subArgs = args.Length < 2 ? "" : args[1]; - if (string.IsNullOrEmpty(subArgs) || !byte.TryParse(subArgs, out byte warnPlayerId)) - { - Utils.SendMessage(GetString("WarnCommandInvalidID"), player.PlayerId); - break; - } - if (warnPlayerId == 0) - { - Utils.SendMessage(GetString("WarnCommandWarnHost"), player.PlayerId); - break; - } - - var warnedPlayer = Utils.GetPlayerById(warnPlayerId); - if (warnedPlayer == null) - { - Utils.SendMessage(GetString("WarnCommandInvalidID"), player.PlayerId); - break; - } - - // Prevent moderators from warning other moderators - if (Utils.IsPlayerModerator(warnedPlayer.FriendCode)) - { - Utils.SendMessage(GetString("WarnCommandWarnMod"), player.PlayerId); - break; - } - // warn the specified player - string warnReason = "Reason : Not specified\n"; - string warnedPlayerName = warnedPlayer.GetRealName(); - //textToSend2 = $" {warnedPlayerName} {GetString("WarnCommandWarned")} ~{player.name}"; - if (args.Length > 2) - { - warnReason = "Reason : " + string.Join(" ", args.Skip(2)) + "\n"; - } - else - { - Utils.SendMessage("Use /warn [id] [reason] in future. \nExample :-\n /warn 5 lava chatting", player.PlayerId); - } - Utils.SendMessage($" {warnedPlayerName} {GetString("WarnCommandWarned")} {warnReason} ~{player.name}"); - //string moderatorName1 = player.GetRealName().ToString(); - //int startIndex1 = moderatorName1.IndexOf("♥") + "♥".Length; - //moderatorName1 = moderatorName1.Substring(startIndex1); - string modLogname1 = Main.AllPlayerNames.TryGetValue(player.PlayerId, out var n2) ? n2 : ""; - string warnlogname = Main.AllPlayerNames.TryGetValue(warnedPlayer.PlayerId, out var n12) ? n12 : ""; - string moderatorFriendCode1 = player.FriendCode.ToString(); - string warnedPlayerFriendCode = warnedPlayer.FriendCode.ToString(); - string warnedPlayerHashPuid = warnedPlayer.GetClient().GetHashedPuid(); - string logMessage1 = $"[{DateTime.Now}] {moderatorFriendCode1},{modLogname1} Warned: {warnedPlayerFriendCode},{warnedPlayerHashPuid},{warnlogname} Reason: {warnReason}"; - File.AppendAllText(modLogFiles, logMessage1 + Environment.NewLine); - - break; - case "/kick": - case "/expulsar": - case "/кик": - case "/кикнуть": + case "/提醒": + if (Options.ApplyModeratorList.GetValue() == 0) + { + Utils.SendMessage(GetString("WarnCommandDisabled"), player.PlayerId); + break; + } + if (!Utils.IsPlayerModerator(player.FriendCode)) + { + Utils.SendMessage(GetString("WarnCommandNoAccess"), player.PlayerId); + break; + } + subArgs = args.Length < 2 ? "" : args[1]; + if (string.IsNullOrEmpty(subArgs) || !byte.TryParse(subArgs, out byte warnPlayerId)) + { + Utils.SendMessage(GetString("WarnCommandInvalidID"), player.PlayerId); + break; + } + if (warnPlayerId == 0) + { + Utils.SendMessage(GetString("WarnCommandWarnHost"), player.PlayerId); + break; + } + + var warnedPlayer = Utils.GetPlayerById(warnPlayerId); + if (warnedPlayer == null) + { + Utils.SendMessage(GetString("WarnCommandInvalidID"), player.PlayerId); + break; + } + + // Prevent moderators from warning other moderators + if (Utils.IsPlayerModerator(warnedPlayer.FriendCode)) + { + Utils.SendMessage(GetString("WarnCommandWarnMod"), player.PlayerId); + break; + } + // warn the specified player + string warnReason = "Reason : Not specified\n"; + string warnedPlayerName = warnedPlayer.GetRealName(); + //textToSend2 = $" {warnedPlayerName} {GetString("WarnCommandWarned")} ~{player.name}"; + if (args.Length > 2) + { + warnReason = "Reason : " + string.Join(" ", args.Skip(2)) + "\n"; + } + else + { + Utils.SendMessage("Use /warn [id] [reason] in future. \nExample :-\n /warn 5 lava chatting", player.PlayerId); + } + Utils.SendMessage($" {warnedPlayerName} {GetString("WarnCommandWarned")} {warnReason} ~{player.name}"); + //string moderatorName1 = player.GetRealName().ToString(); + //int startIndex1 = moderatorName1.IndexOf("♥") + "♥".Length; + //moderatorName1 = moderatorName1.Substring(startIndex1); + string modLogname1 = Main.AllPlayerNames.TryGetValue(player.PlayerId, out var n2) ? n2 : ""; + string warnlogname = Main.AllPlayerNames.TryGetValue(warnedPlayer.PlayerId, out var n12) ? n12 : ""; + string moderatorFriendCode1 = player.FriendCode.ToString(); + string warnedPlayerFriendCode = warnedPlayer.FriendCode.ToString(); + string warnedPlayerHashPuid = warnedPlayer.GetClient().GetHashedPuid(); + string logMessage1 = $"[{DateTime.Now}] {moderatorFriendCode1},{modLogname1} Warned: {warnedPlayerFriendCode},{warnedPlayerHashPuid},{warnlogname} Reason: {warnReason}"; + File.AppendAllText(modLogFiles, logMessage1 + Environment.NewLine); + + break; + case "/kick": + case "/expulsar": + case "/кик": + case "/кикнуть": case "/выгнать": case "/踢出": - case "/踢": - // Check if the kick command is enabled in the settings - if (Options.ApplyModeratorList.GetValue() == 0) - { - Utils.SendMessage(GetString("KickCommandDisabled"), player.PlayerId); - break; - } - - // Check if the player has the necessary privileges to use the command - if (!Utils.IsPlayerModerator(player.FriendCode)) - { - Utils.SendMessage(GetString("KickCommandNoAccess"), player.PlayerId); - break; - } - - subArgs = args.Length < 2 ? "" : args[1]; - if (string.IsNullOrEmpty(subArgs) || !byte.TryParse(subArgs, out byte kickPlayerId)) - { - Utils.SendMessage(GetString("KickCommandInvalidID"), player.PlayerId); - break; - } - - if (kickPlayerId == 0) - { - Utils.SendMessage(GetString("KickCommandKickHost"), player.PlayerId); - break; - } - - var kickedPlayer = Utils.GetPlayerById(kickPlayerId); - if (kickedPlayer == null) - { - Utils.SendMessage(GetString("KickCommandInvalidID"), player.PlayerId); - break; - } - - // Prevent moderators from kicking other moderators - if (Utils.IsPlayerModerator(kickedPlayer.FriendCode)) - { - Utils.SendMessage(GetString("KickCommandKickMod"), player.PlayerId); - break; - } - - // Kick the specified player - AmongUsClient.Instance.KickPlayer(kickedPlayer.GetClientId(), false); - string kickedPlayerName = kickedPlayer.GetRealName(); - string kickReason = "Reason : Not specified\n"; - if (args.Length > 2) - kickReason = "Reason : " + string.Join(" ", args.Skip(2)) + "\n"; - else - { - Utils.SendMessage("Use /kick [id] [reason] in future. \nExample :-\n /kick 5 not following rules", player.PlayerId); - } - string textToSend = $"{kickedPlayerName} {GetString("KickCommandKicked")} {player.name} \n {kickReason}"; - - if (GameStates.IsInGame) - { - textToSend += $" {GetString("KickCommandKickedRole")} {GetString(kickedPlayer.GetCustomRole().ToString())}"; - } - Utils.SendMessage(textToSend); - //string moderatorName2 = player.GetRealName().ToString(); - //int startIndex2 = moderatorName2.IndexOf("♥") + "♥".Length; - //moderatorName2 = moderatorName2.Substring(startIndex2); - string modLogname2 = Main.AllPlayerNames.TryGetValue(player.PlayerId, out var n3) ? n3 : ""; - string kicklogname = Main.AllPlayerNames.TryGetValue(kickedPlayer.PlayerId, out var n13) ? n13 : ""; - - string moderatorFriendCode2 = player.FriendCode.ToString(); - string kickedPlayerFriendCode = kickedPlayer.FriendCode.ToString(); - string kickedPlayerHashPuid = kickedPlayer.GetClient().GetHashedPuid(); - string logMessage2 = $"[{DateTime.Now}] {moderatorFriendCode2},{modLogname2} Kicked: {kickedPlayerFriendCode},{kickedPlayerHashPuid},{kicklogname} Reason: {kickReason}"; - File.AppendAllText(modLogFiles, logMessage2 + Environment.NewLine); - - break; - case "/modcolor": + case "/踢": + // Check if the kick command is enabled in the settings + if (Options.ApplyModeratorList.GetValue() == 0) + { + Utils.SendMessage(GetString("KickCommandDisabled"), player.PlayerId); + break; + } + + // Check if the player has the necessary privileges to use the command + if (!Utils.IsPlayerModerator(player.FriendCode)) + { + Utils.SendMessage(GetString("KickCommandNoAccess"), player.PlayerId); + break; + } + + subArgs = args.Length < 2 ? "" : args[1]; + if (string.IsNullOrEmpty(subArgs) || !byte.TryParse(subArgs, out byte kickPlayerId)) + { + Utils.SendMessage(GetString("KickCommandInvalidID"), player.PlayerId); + break; + } + + if (kickPlayerId == 0) + { + Utils.SendMessage(GetString("KickCommandKickHost"), player.PlayerId); + break; + } + + var kickedPlayer = Utils.GetPlayerById(kickPlayerId); + if (kickedPlayer == null) + { + Utils.SendMessage(GetString("KickCommandInvalidID"), player.PlayerId); + break; + } + + // Prevent moderators from kicking other moderators + if (Utils.IsPlayerModerator(kickedPlayer.FriendCode)) + { + Utils.SendMessage(GetString("KickCommandKickMod"), player.PlayerId); + break; + } + + // Kick the specified player + AmongUsClient.Instance.KickPlayer(kickedPlayer.GetClientId(), false); + string kickedPlayerName = kickedPlayer.GetRealName(); + string kickReason = "Reason : Not specified\n"; + if (args.Length > 2) + kickReason = "Reason : " + string.Join(" ", args.Skip(2)) + "\n"; + else + { + Utils.SendMessage("Use /kick [id] [reason] in future. \nExample :-\n /kick 5 not following rules", player.PlayerId); + } + string textToSend = $"{kickedPlayerName} {GetString("KickCommandKicked")} {player.name} \n {kickReason}"; + + if (GameStates.IsInGame) + { + textToSend += $" {GetString("KickCommandKickedRole")} {GetString(kickedPlayer.GetCustomRole().ToString())}"; + } + Utils.SendMessage(textToSend); + //string moderatorName2 = player.GetRealName().ToString(); + //int startIndex2 = moderatorName2.IndexOf("♥") + "♥".Length; + //moderatorName2 = moderatorName2.Substring(startIndex2); + string modLogname2 = Main.AllPlayerNames.TryGetValue(player.PlayerId, out var n3) ? n3 : ""; + string kicklogname = Main.AllPlayerNames.TryGetValue(kickedPlayer.PlayerId, out var n13) ? n13 : ""; + + string moderatorFriendCode2 = player.FriendCode.ToString(); + string kickedPlayerFriendCode = kickedPlayer.FriendCode.ToString(); + string kickedPlayerHashPuid = kickedPlayer.GetClient().GetHashedPuid(); + string logMessage2 = $"[{DateTime.Now}] {moderatorFriendCode2},{modLogname2} Kicked: {kickedPlayerFriendCode},{kickedPlayerHashPuid},{kicklogname} Reason: {kickReason}"; + File.AppendAllText(modLogFiles, logMessage2 + Environment.NewLine); + + break; + case "/modcolor": case "/modcolour": case "/模组端颜色": - case "/模组颜色": - if (Options.ApplyModeratorList.GetValue() == 0) - { - Utils.SendMessage(GetString("ColorCommandDisabled"), player.PlayerId); - break; - } - if (!Utils.IsPlayerModerator(player.FriendCode)) - { - Utils.SendMessage(GetString("ColorCommandNoAccess"), player.PlayerId); - break; - } - if (!GameStates.IsLobby) - { - Utils.SendMessage(GetString("ColorCommandNoLobby"), player.PlayerId); - break; - } - if (!Options.GradientTagsOpt.GetBool()) - { - subArgs = args.Length != 2 ? "" : args[1]; - if (string.IsNullOrEmpty(subArgs) || !Utils.CheckColorHex(subArgs)) - { - Logger.Msg($"{subArgs}", "modcolor"); - Utils.SendMessage(GetString("ColorInvalidHexCode"), player.PlayerId); - break; - } - string colorFilePath = $"{modTagsFiles}/{player.FriendCode}.txt"; - if (!File.Exists(colorFilePath)) - { - Logger.Warn($"File Not exist, creating file at {modTagsFiles}/{player.FriendCode}.txt", "modcolor"); - File.Create(colorFilePath).Close(); - } - - File.WriteAllText(colorFilePath, $"{subArgs}"); - break; - } - else - { - subArgs = args.Length < 3 ? "" : args[1] + " " + args[2]; - Regex regex = new(@"^[0-9A-Fa-f]{6}\s[0-9A-Fa-f]{6}$"); - if (string.IsNullOrEmpty(subArgs) || !regex.IsMatch(subArgs)) - { - Logger.Msg($"{subArgs}", "modcolor"); - Utils.SendMessage(GetString("ColorInvalidGradientCode"), player.PlayerId); - break; - } - string colorFilePath = $"{modTagsFiles}/{player.FriendCode}.txt"; - if (!File.Exists(colorFilePath)) - { - Logger.Msg($"File Not exist, creating file at {modTagsFiles}/{player.FriendCode}.txt", "modcolor"); - File.Create(colorFilePath).Close(); - } - //Logger.Msg($"File exists, creating file at {modTagsFiles}/{player.FriendCode}.txt", "modcolor"); - //Logger.Msg($"{subArgs}","modcolor"); - File.WriteAllText(colorFilePath, $"{subArgs}"); - break; - } - case "/vipcolor": + case "/模组颜色": + if (Options.ApplyModeratorList.GetValue() == 0) + { + Utils.SendMessage(GetString("ColorCommandDisabled"), player.PlayerId); + break; + } + if (!Utils.IsPlayerModerator(player.FriendCode)) + { + Utils.SendMessage(GetString("ColorCommandNoAccess"), player.PlayerId); + break; + } + if (!GameStates.IsLobby) + { + Utils.SendMessage(GetString("ColorCommandNoLobby"), player.PlayerId); + break; + } + if (!Options.GradientTagsOpt.GetBool()) + { + subArgs = args.Length != 2 ? "" : args[1]; + if (string.IsNullOrEmpty(subArgs) || !Utils.CheckColorHex(subArgs)) + { + Logger.Msg($"{subArgs}", "modcolor"); + Utils.SendMessage(GetString("ColorInvalidHexCode"), player.PlayerId); + break; + } + string colorFilePath = $"{modTagsFiles}/{player.FriendCode}.txt"; + if (!File.Exists(colorFilePath)) + { + Logger.Warn($"File Not exist, creating file at {modTagsFiles}/{player.FriendCode}.txt", "modcolor"); + File.Create(colorFilePath).Close(); + } + + File.WriteAllText(colorFilePath, $"{subArgs}"); + break; + } + else + { + subArgs = args.Length < 3 ? "" : args[1] + " " + args[2]; + Regex regex = new(@"^[0-9A-Fa-f]{6}\s[0-9A-Fa-f]{6}$"); + if (string.IsNullOrEmpty(subArgs) || !regex.IsMatch(subArgs)) + { + Logger.Msg($"{subArgs}", "modcolor"); + Utils.SendMessage(GetString("ColorInvalidGradientCode"), player.PlayerId); + break; + } + string colorFilePath = $"{modTagsFiles}/{player.FriendCode}.txt"; + if (!File.Exists(colorFilePath)) + { + Logger.Msg($"File Not exist, creating file at {modTagsFiles}/{player.FriendCode}.txt", "modcolor"); + File.Create(colorFilePath).Close(); + } + //Logger.Msg($"File exists, creating file at {modTagsFiles}/{player.FriendCode}.txt", "modcolor"); + //Logger.Msg($"{subArgs}","modcolor"); + File.WriteAllText(colorFilePath, $"{subArgs}"); + break; + } + case "/vipcolor": case "/vipcolour": case "/VIP玩家颜色": - case "/VIP颜色": - if (Options.ApplyVipList.GetValue() == 0) - { - Utils.SendMessage(GetString("VipColorCommandDisabled"), player.PlayerId); - break; - } - if (!Utils.IsPlayerVIP(player.FriendCode)) - { - Utils.SendMessage(GetString("VipColorCommandNoAccess"), player.PlayerId); - break; - } - if (!GameStates.IsLobby) - { - Utils.SendMessage(GetString("VipColorCommandNoLobby"), player.PlayerId); - break; - } - if (!Options.GradientTagsOpt.GetBool()) - { - subArgs = args.Length != 2 ? "" : args[1]; - if (string.IsNullOrEmpty(subArgs) || !Utils.CheckColorHex(subArgs)) - { - Logger.Msg($"{subArgs}", "vipcolor"); - Utils.SendMessage(GetString("VipColorInvalidHexCode"), player.PlayerId); - break; - } - string colorFilePathh = $"{vipTagsFiles}/{player.FriendCode}.txt"; - if (!File.Exists(colorFilePathh)) - { - Logger.Warn($"File Not exist, creating file at {vipTagsFiles}/{player.FriendCode}.txt", "vipcolor"); - File.Create(colorFilePathh).Close(); - } - - File.WriteAllText(colorFilePathh, $"{subArgs}"); - break; - } - else - { - subArgs = args.Length < 3 ? "" : args[1] + " " + args[2]; - Regex regexx = new(@"^[0-9A-Fa-f]{6}\s[0-9A-Fa-f]{6}$"); - if (string.IsNullOrEmpty(subArgs) || !regexx.IsMatch(subArgs)) - { - Logger.Msg($"{subArgs}", "vipcolor"); - Utils.SendMessage(GetString("VipColorInvalidGradientCode"), player.PlayerId); - break; - } - string colorFilePathh = $"{vipTagsFiles}/{player.FriendCode}.txt"; - if (!File.Exists(colorFilePathh)) - { - Logger.Msg($"File Not exist, creating file at {vipTagsFiles}/{player.FriendCode}.txt", "vipcolor"); - File.Create(colorFilePathh).Close(); - } - //Logger.Msg($"File exists, creating file at {vipTagsFiles}/{player.FriendCode}.txt", "vipcolor"); - //Logger.Msg($"{subArgs}","modcolor"); - File.WriteAllText(colorFilePathh, $"{subArgs}"); - break; - } - case "/tagcolor": + case "/VIP颜色": + if (Options.ApplyVipList.GetValue() == 0) + { + Utils.SendMessage(GetString("VipColorCommandDisabled"), player.PlayerId); + break; + } + if (!Utils.IsPlayerVIP(player.FriendCode)) + { + Utils.SendMessage(GetString("VipColorCommandNoAccess"), player.PlayerId); + break; + } + if (!GameStates.IsLobby) + { + Utils.SendMessage(GetString("VipColorCommandNoLobby"), player.PlayerId); + break; + } + if (!Options.GradientTagsOpt.GetBool()) + { + subArgs = args.Length != 2 ? "" : args[1]; + if (string.IsNullOrEmpty(subArgs) || !Utils.CheckColorHex(subArgs)) + { + Logger.Msg($"{subArgs}", "vipcolor"); + Utils.SendMessage(GetString("VipColorInvalidHexCode"), player.PlayerId); + break; + } + string colorFilePathh = $"{vipTagsFiles}/{player.FriendCode}.txt"; + if (!File.Exists(colorFilePathh)) + { + Logger.Warn($"File Not exist, creating file at {vipTagsFiles}/{player.FriendCode}.txt", "vipcolor"); + File.Create(colorFilePathh).Close(); + } + + File.WriteAllText(colorFilePathh, $"{subArgs}"); + break; + } + else + { + subArgs = args.Length < 3 ? "" : args[1] + " " + args[2]; + Regex regexx = new(@"^[0-9A-Fa-f]{6}\s[0-9A-Fa-f]{6}$"); + if (string.IsNullOrEmpty(subArgs) || !regexx.IsMatch(subArgs)) + { + Logger.Msg($"{subArgs}", "vipcolor"); + Utils.SendMessage(GetString("VipColorInvalidGradientCode"), player.PlayerId); + break; + } + string colorFilePathh = $"{vipTagsFiles}/{player.FriendCode}.txt"; + if (!File.Exists(colorFilePathh)) + { + Logger.Msg($"File Not exist, creating file at {vipTagsFiles}/{player.FriendCode}.txt", "vipcolor"); + File.Create(colorFilePathh).Close(); + } + //Logger.Msg($"File exists, creating file at {vipTagsFiles}/{player.FriendCode}.txt", "vipcolor"); + //Logger.Msg($"{subArgs}","modcolor"); + File.WriteAllText(colorFilePathh, $"{subArgs}"); + break; + } + case "/tagcolor": case "/tagcolour": case "/标签颜色": - case "/附加名称颜色": - string name1 = Main.AllPlayerNames.TryGetValue(player.PlayerId, out var n) ? n : ""; - if (name1 == "") break; - if (!name1.Contains('\r') && player.FriendCode.GetDevUser().HasTag()) - { - if (!GameStates.IsLobby) - { - Utils.SendMessage(GetString("ColorCommandNoLobby"), player.PlayerId); - break; - } - subArgs = args.Length != 2 ? "" : args[1]; - if (string.IsNullOrEmpty(subArgs) || !Utils.CheckColorHex(subArgs)) - { - Logger.Msg($"{subArgs}", "tagcolor"); - Utils.SendMessage(GetString("TagColorInvalidHexCode"), player.PlayerId); - break; - } - string tagColorFilePath = $"{sponsorTagsFiles}/{player.FriendCode}.txt"; - if (!File.Exists(tagColorFilePath)) - { - Logger.Msg($"File Not exist, creating file at {tagColorFilePath}", "tagcolor"); - File.Create(tagColorFilePath).Close(); - } - - File.WriteAllText(tagColorFilePath, $"{subArgs}"); - } - break; - + case "/附加名称颜色": + string name1 = Main.AllPlayerNames.TryGetValue(player.PlayerId, out var n) ? n : ""; + if (name1 == "") break; + if (!name1.Contains('\r') && player.FriendCode.GetDevUser().HasTag()) + { + if (!GameStates.IsLobby) + { + Utils.SendMessage(GetString("ColorCommandNoLobby"), player.PlayerId); + break; + } + subArgs = args.Length != 2 ? "" : args[1]; + if (string.IsNullOrEmpty(subArgs) || !Utils.CheckColorHex(subArgs)) + { + Logger.Msg($"{subArgs}", "tagcolor"); + Utils.SendMessage(GetString("TagColorInvalidHexCode"), player.PlayerId); + break; + } + string tagColorFilePath = $"{sponsorTagsFiles}/{player.FriendCode}.txt"; + if (!File.Exists(tagColorFilePath)) + { + Logger.Msg($"File Not exist, creating file at {tagColorFilePath}", "tagcolor"); + File.Create(tagColorFilePath).Close(); + } + + File.WriteAllText(tagColorFilePath, $"{subArgs}"); + } + break; + case "/xf": case "/修复": - case "/修": - if (GameStates.IsLobby) - { - Utils.SendMessage(GetString("Message.CanNotUseInLobby"), player.PlayerId); - break; - } - foreach (var pc in Main.AllPlayerControls) - { - if (pc.IsAlive()) continue; - - pc.RpcSetNameEx(pc.GetRealName(isMeeting: true)); - } - ChatUpdatePatch.DoBlockChat = false; - //Utils.NotifyRoles(isForMeeting: GameStates.IsMeeting, NoCache: true); - Utils.SendMessage(GetString("Message.TryFixName"), player.PlayerId); - break; - + case "/修": + if (GameStates.IsLobby) + { + Utils.SendMessage(GetString("Message.CanNotUseInLobby"), player.PlayerId); + break; + } + foreach (var pc in Main.AllPlayerControls) + { + if (pc.IsAlive()) continue; + + pc.RpcSetNameEx(pc.GetRealName(isMeeting: true)); + } + ChatUpdatePatch.DoBlockChat = false; + //Utils.NotifyRoles(isForMeeting: GameStates.IsMeeting, NoCache: true); + Utils.SendMessage(GetString("Message.TryFixName"), player.PlayerId); + break; + case "/tpout": case "/传送出": - case "/传出": - if (!GameStates.IsLobby) break; - if (!Options.PlayerCanUseTP.GetBool()) - { - Utils.SendMessage(GetString("DisableUseCommand"), player.PlayerId); - break; - } - player.RpcTeleport(new Vector2(0.1f, 3.8f)); - break; + case "/传出": + if (!GameStates.IsLobby) break; + if (!Options.PlayerCanUseTP.GetBool()) + { + Utils.SendMessage(GetString("DisableUseCommand"), player.PlayerId); + break; + } + player.RpcTeleport(new Vector2(0.1f, 3.8f)); + break; case "/tpin": case "/传进": - case "/传送进": - if (!GameStates.IsLobby) break; - if (!Options.PlayerCanUseTP.GetBool()) - { - Utils.SendMessage(GetString("DisableUseCommand"), player.PlayerId); - break; - } - - player.RpcTeleport(new Vector2(-0.2f, 1.3f)); - break; - + case "/传送进": + if (!GameStates.IsLobby) break; + if (!Options.PlayerCanUseTP.GetBool()) + { + Utils.SendMessage(GetString("DisableUseCommand"), player.PlayerId); + break; + } + + player.RpcTeleport(new Vector2(-0.2f, 1.3f)); + break; + case "/vote": case "/投票": - case "/票": - subArgs = args.Length != 2 ? "" : args[1]; - if (subArgs == "" || !int.TryParse(subArgs, out int arg)) - break; - var plr = Utils.GetPlayerById(arg); - - if (GameStates.IsLobby) - { - Utils.SendMessage(GetString("Message.CanNotUseInLobby"), player.PlayerId); - break; - } - - - if (!Options.EnableVoteCommand.GetBool()) - { - Utils.SendMessage(GetString("VoteDisabled"), player.PlayerId); - break; - } - if (Options.ShouldVoteCmdsSpamChat.GetBool()) - { - canceled = true; - ChatManager.SendPreviousMessagesToAll(); - } - - if (arg != 253) // skip - { - if (plr == null || !plr.IsAlive()) - { - Utils.SendMessage(GetString("VoteDead"), player.PlayerId); - break; - } - } - if (!player.IsAlive()) - { - Utils.SendMessage(GetString("CannotVoteWhenDead"), player.PlayerId); - break; - } - if (GameStates.IsMeeting) - { - player.RpcCastVote((byte)arg); - } - break; - - case "/say": - case "/s": - case "/с": + case "/票": + subArgs = args.Length != 2 ? "" : args[1]; + if (subArgs == "" || !int.TryParse(subArgs, out int arg)) + break; + var plr = Utils.GetPlayerById(arg); + + if (GameStates.IsLobby) + { + Utils.SendMessage(GetString("Message.CanNotUseInLobby"), player.PlayerId); + break; + } + + + if (!Options.EnableVoteCommand.GetBool()) + { + Utils.SendMessage(GetString("VoteDisabled"), player.PlayerId); + break; + } + if (Options.ShouldVoteCmdsSpamChat.GetBool()) + { + canceled = true; + ChatManager.SendPreviousMessagesToAll(); + } + + if (arg != 253) // skip + { + if (plr == null || !plr.IsAlive()) + { + Utils.SendMessage(GetString("VoteDead"), player.PlayerId); + break; + } + } + if (!player.IsAlive()) + { + Utils.SendMessage(GetString("CannotVoteWhenDead"), player.PlayerId); + break; + } + if (GameStates.IsMeeting) + { + player.RpcCastVote((byte)arg); + } + break; + + case "/say": + case "/s": + case "/с": case "/сказать": - case "/说": - if (player.FriendCode.GetDevUser().IsDev) - { - if (args.Length > 1) - Utils.SendMessage(args.Skip(1).Join(delimiter: " "), title: $"{GetString("MessageFromDev")} ~ {player.GetRealName(clientData: true)}"); - } - else if (player.FriendCode.IsDevUser() && !dbConnect.IsBooster(player.FriendCode)) - { - if (args.Length > 1) - Utils.SendMessage(args.Skip(1).Join(delimiter: " "), title: $"{GetString("MessageFromSponsor")} ~ {player.GetRealName(clientData: true)}"); - } - else if (Utils.IsPlayerModerator(player.FriendCode)) - { - if (Options.ApplyModeratorList.GetValue() == 0 || Options.AllowSayCommand.GetBool() == false) - { - Utils.SendMessage(GetString("SayCommandDisabled"), player.PlayerId); - break; - } - else - { - if (args.Length > 1) - Utils.SendMessage(args.Skip(1).Join(delimiter: " "), title: $"{GetString("MessageFromModerator")} ~ {player.GetRealName(clientData: true)}"); - //string moderatorName3 = player.GetRealName().ToString(); - //int startIndex3 = moderatorName3.IndexOf("♥") + "♥".Length; - //moderatorName3 = moderatorName3.Substring(startIndex3); - string modLogname3 = Main.AllPlayerNames.TryGetValue(player.PlayerId, out var n4) ? n4 : ""; - - string moderatorFriendCode3 = player.FriendCode.ToString(); - string logMessage3 = $"[{DateTime.Now}] {moderatorFriendCode3},{modLogname3} used /s: {args.Skip(1).Join(delimiter: " ")}"; - File.AppendAllText(modLogFiles, logMessage3 + Environment.NewLine); - - } - } - break; + case "/说": + if (player.FriendCode.GetDevUser().IsDev) + { + if (args.Length > 1) + Utils.SendMessage(args.Skip(1).Join(delimiter: " "), title: $"{GetString("MessageFromDev")} ~ {player.GetRealName(clientData: true)}"); + } + else if (player.FriendCode.IsDevUser() && !dbConnect.IsBooster(player.FriendCode)) + { + if (args.Length > 1) + Utils.SendMessage(args.Skip(1).Join(delimiter: " "), title: $"{GetString("MessageFromSponsor")} ~ {player.GetRealName(clientData: true)}"); + } + else if (Utils.IsPlayerModerator(player.FriendCode)) + { + if (Options.ApplyModeratorList.GetValue() == 0 || Options.AllowSayCommand.GetBool() == false) + { + Utils.SendMessage(GetString("SayCommandDisabled"), player.PlayerId); + break; + } + else + { + if (args.Length > 1) + Utils.SendMessage(args.Skip(1).Join(delimiter: " "), title: $"{GetString("MessageFromModerator")} ~ {player.GetRealName(clientData: true)}"); + //string moderatorName3 = player.GetRealName().ToString(); + //int startIndex3 = moderatorName3.IndexOf("♥") + "♥".Length; + //moderatorName3 = moderatorName3.Substring(startIndex3); + string modLogname3 = Main.AllPlayerNames.TryGetValue(player.PlayerId, out var n4) ? n4 : ""; + + string moderatorFriendCode3 = player.FriendCode.ToString(); + string logMessage3 = $"[{DateTime.Now}] {moderatorFriendCode3},{modLogname3} used /s: {args.Skip(1).Join(delimiter: " ")}"; + File.AppendAllText(modLogFiles, logMessage3 + Environment.NewLine); + + } + } + break; case "/rps": - case "/剪刀石头布": - //canceled = true; - if (!Options.CanPlayMiniGames.GetBool()) - { - Utils.SendMessage(GetString("DisableUseCommand"), player.PlayerId); - break; - } - subArgs = args.Length != 2 ? "" : args[1]; - - if (!GameStates.IsLobby && player.IsAlive()) - { - Utils.SendMessage(GetString("RpsCommandInfo"), player.PlayerId); - break; - } - - if (subArgs == "" || !int.TryParse(subArgs, out int playerChoice)) - { - Utils.SendMessage(GetString("RpsCommandInfo"), player.PlayerId); - break; - } - else if (playerChoice < 0 || playerChoice > 2) - { - Utils.SendMessage(GetString("RpsCommandInfo"), player.PlayerId); - break; - } - else - { - var rand = IRandom.Instance; - int botChoice = rand.Next(0, 3); - var rpsList = new List { GetString("Rock"), GetString("Paper"), GetString("Scissors") }; - if (botChoice == playerChoice) - { - Utils.SendMessage(string.Format(GetString("RpsDraw"), rpsList[botChoice]), player.PlayerId); - } - else if ((botChoice == 0 && playerChoice == 2) || - (botChoice == 1 && playerChoice == 0) || - (botChoice == 2 && playerChoice == 1)) - { - Utils.SendMessage(string.Format(GetString("RpsLose"), rpsList[botChoice]), player.PlayerId); - } - else - { - Utils.SendMessage(string.Format(GetString("RpsWin"), rpsList[botChoice]), player.PlayerId); - } - break; - } + case "/剪刀石头布": + //canceled = true; + if (!Options.CanPlayMiniGames.GetBool()) + { + Utils.SendMessage(GetString("DisableUseCommand"), player.PlayerId); + break; + } + subArgs = args.Length != 2 ? "" : args[1]; + + if (!GameStates.IsLobby && player.IsAlive()) + { + Utils.SendMessage(GetString("RpsCommandInfo"), player.PlayerId); + break; + } + + if (subArgs == "" || !int.TryParse(subArgs, out int playerChoice)) + { + Utils.SendMessage(GetString("RpsCommandInfo"), player.PlayerId); + break; + } + else if (playerChoice < 0 || playerChoice > 2) + { + Utils.SendMessage(GetString("RpsCommandInfo"), player.PlayerId); + break; + } + else + { + var rand = IRandom.Instance; + int botChoice = rand.Next(0, 3); + var rpsList = new List { GetString("Rock"), GetString("Paper"), GetString("Scissors") }; + if (botChoice == playerChoice) + { + Utils.SendMessage(string.Format(GetString("RpsDraw"), rpsList[botChoice]), player.PlayerId); + } + else if ((botChoice == 0 && playerChoice == 2) || + (botChoice == 1 && playerChoice == 0) || + (botChoice == 2 && playerChoice == 1)) + { + Utils.SendMessage(string.Format(GetString("RpsLose"), rpsList[botChoice]), player.PlayerId); + } + else + { + Utils.SendMessage(string.Format(GetString("RpsWin"), rpsList[botChoice]), player.PlayerId); + } + break; + } case "/coinflip": - case "/抛硬币": - //canceled = true; - if (!Options.CanPlayMiniGames.GetBool()) - { - Utils.SendMessage(GetString("DisableUseCommand"), player.PlayerId); - break; - } - - if (!GameStates.IsLobby && player.IsAlive()) - { - Utils.SendMessage(GetString("CoinflipCommandInfo"), player.PlayerId); - break; - } - else - { - var rand = IRandom.Instance; - int botChoice = rand.Next(1,101); - var coinSide = (botChoice < 51) ? GetString("Heads") : GetString("Tails"); - Utils.SendMessage(string.Format(GetString("CoinFlipResult"), coinSide), player.PlayerId); - break; - } + case "/抛硬币": + //canceled = true; + if (!Options.CanPlayMiniGames.GetBool()) + { + Utils.SendMessage(GetString("DisableUseCommand"), player.PlayerId); + break; + } + + if (!GameStates.IsLobby && player.IsAlive()) + { + Utils.SendMessage(GetString("CoinflipCommandInfo"), player.PlayerId); + break; + } + else + { + var rand = IRandom.Instance; + int botChoice = rand.Next(1,101); + var coinSide = (botChoice < 51) ? GetString("Heads") : GetString("Tails"); + Utils.SendMessage(string.Format(GetString("CoinFlipResult"), coinSide), player.PlayerId); + break; + } case "/gno": - case "/猜数字": - if (!Options.CanPlayMiniGames.GetBool()) - { - Utils.SendMessage(GetString("DisableUseCommand"), player.PlayerId); - break; - } - //canceled = true; - if (!GameStates.IsLobby && player.IsAlive()) - { - Utils.SendMessage(GetString("GNoCommandInfo"), player.PlayerId); - break; - } - subArgs = args.Length != 2 ? "" : args[1]; - if (subArgs == "" || !int.TryParse(subArgs, out int guessedNo)) - { - Utils.SendMessage(GetString("GNoCommandInfo"), player.PlayerId); - break; - } - else if (guessedNo < 0 || guessedNo > 99) - { - Utils.SendMessage(GetString("GNoCommandInfo"), player.PlayerId); - break; - } - else - { - int targetNumber = Main.GuessNumber[player.PlayerId][0]; - if (Main.GuessNumber[player.PlayerId][0] == -1) - { - var rand = IRandom.Instance; - Main.GuessNumber[player.PlayerId][0] = rand.Next(0, 100); - targetNumber = Main.GuessNumber[player.PlayerId][0]; - } - Main.GuessNumber[player.PlayerId][1]--; - if (Main.GuessNumber[player.PlayerId][1] == 0 && guessedNo != targetNumber) - { - Main.GuessNumber[player.PlayerId][0] = -1; - Main.GuessNumber[player.PlayerId][1] = 7; - //targetNumber = Main.GuessNumber[player.PlayerId][0]; - Utils.SendMessage(string.Format(GetString("GNoLost"), targetNumber), player.PlayerId); - break; - } - else if (guessedNo < targetNumber) - { - Utils.SendMessage(string.Format(GetString("GNoLow"), Main.GuessNumber[player.PlayerId][1]), player.PlayerId); - break; - } - else if (guessedNo > targetNumber) - { - Utils.SendMessage(string.Format(GetString("GNoHigh"), Main.GuessNumber[player.PlayerId][1]), player.PlayerId); - break; - } - else - { - Utils.SendMessage(string.Format(GetString("GNoWon"), Main.GuessNumber[player.PlayerId][1]), player.PlayerId); - Main.GuessNumber[player.PlayerId][0] = -1; - Main.GuessNumber[player.PlayerId][1] = 7; - break; - } - } + case "/猜数字": + if (!Options.CanPlayMiniGames.GetBool()) + { + Utils.SendMessage(GetString("DisableUseCommand"), player.PlayerId); + break; + } + //canceled = true; + if (!GameStates.IsLobby && player.IsAlive()) + { + Utils.SendMessage(GetString("GNoCommandInfo"), player.PlayerId); + break; + } + subArgs = args.Length != 2 ? "" : args[1]; + if (subArgs == "" || !int.TryParse(subArgs, out int guessedNo)) + { + Utils.SendMessage(GetString("GNoCommandInfo"), player.PlayerId); + break; + } + else if (guessedNo < 0 || guessedNo > 99) + { + Utils.SendMessage(GetString("GNoCommandInfo"), player.PlayerId); + break; + } + else + { + int targetNumber = Main.GuessNumber[player.PlayerId][0]; + if (Main.GuessNumber[player.PlayerId][0] == -1) + { + var rand = IRandom.Instance; + Main.GuessNumber[player.PlayerId][0] = rand.Next(0, 100); + targetNumber = Main.GuessNumber[player.PlayerId][0]; + } + Main.GuessNumber[player.PlayerId][1]--; + if (Main.GuessNumber[player.PlayerId][1] == 0 && guessedNo != targetNumber) + { + Main.GuessNumber[player.PlayerId][0] = -1; + Main.GuessNumber[player.PlayerId][1] = 7; + //targetNumber = Main.GuessNumber[player.PlayerId][0]; + Utils.SendMessage(string.Format(GetString("GNoLost"), targetNumber), player.PlayerId); + break; + } + else if (guessedNo < targetNumber) + { + Utils.SendMessage(string.Format(GetString("GNoLow"), Main.GuessNumber[player.PlayerId][1]), player.PlayerId); + break; + } + else if (guessedNo > targetNumber) + { + Utils.SendMessage(string.Format(GetString("GNoHigh"), Main.GuessNumber[player.PlayerId][1]), player.PlayerId); + break; + } + else + { + Utils.SendMessage(string.Format(GetString("GNoWon"), Main.GuessNumber[player.PlayerId][1]), player.PlayerId); + Main.GuessNumber[player.PlayerId][0] = -1; + Main.GuessNumber[player.PlayerId][1] = 7; + break; + } + } case "/rand": case "/XY数字": case "/范围游戏": case "/猜范围": - case "/范围": - if (!Options.CanPlayMiniGames.GetBool()) - { - Utils.SendMessage(GetString("DisableUseCommand"), player.PlayerId); - break; - } - subArgs = args.Length != 3 ? "" : args[1]; - subArgs2 = args.Length != 3 ? "" : args[2]; - - if (!GameStates.IsLobby && player.IsAlive()) - { - Utils.SendMessage(GetString("RandCommandInfo"), player.PlayerId); - break; - } - if (subArgs == "" || !int.TryParse(subArgs, out int playerChoice1) || subArgs2 == "" || !int.TryParse(subArgs2, out int playerChoice2)) - { - Utils.SendMessage(GetString("RandCommandInfo"), player.PlayerId); - break; - } - else - { - var rand = IRandom.Instance; - int botResult = rand.Next(playerChoice1, playerChoice2 + 1); - Utils.SendMessage(string.Format(GetString("RandResult"), botResult), player.PlayerId); - break; - } + case "/范围": + if (!Options.CanPlayMiniGames.GetBool()) + { + Utils.SendMessage(GetString("DisableUseCommand"), player.PlayerId); + break; + } + subArgs = args.Length != 3 ? "" : args[1]; + subArgs2 = args.Length != 3 ? "" : args[2]; + + if (!GameStates.IsLobby && player.IsAlive()) + { + Utils.SendMessage(GetString("RandCommandInfo"), player.PlayerId); + break; + } + if (subArgs == "" || !int.TryParse(subArgs, out int playerChoice1) || subArgs2 == "" || !int.TryParse(subArgs2, out int playerChoice2)) + { + Utils.SendMessage(GetString("RandCommandInfo"), player.PlayerId); + break; + } + else + { + var rand = IRandom.Instance; + int botResult = rand.Next(playerChoice1, playerChoice2 + 1); + Utils.SendMessage(string.Format(GetString("RandResult"), botResult), player.PlayerId); + break; + } case "/8ball": case "/8号球": - case "/幸运球": - if (!Options.CanPlayMiniGames.GetBool()) - { - Utils.SendMessage(GetString("DisableUseCommand"), player.PlayerId); - break; - } - canceled = true; - var rando = IRandom.Instance; - int result = rando.Next(0, 16); - string str = ""; - switch (result) - { - case 0: - str = GetString("8BallYes"); - break; - case 1: - str = GetString("8BallNo"); - break; - case 2: - str = GetString("8BallMaybe"); - break; - case 3: - str = GetString("8BallTryAgainLater"); - break; - case 4: - str = GetString("8BallCertain"); - break; - case 5: - str = GetString("8BallNotLikely"); - break; - case 6: - str = GetString("8BallLikely"); - break; - case 7: - str = GetString("8BallDontCount"); - break; - case 8: - str = GetString("8BallStop"); - break; - case 9: - str = GetString("8BallPossibly"); - break; - case 10: - str = GetString("8BallProbably"); - break; - case 11: - str = GetString("8BallProbablyNot"); - break; - case 12: - str = GetString("8BallBetterNotTell"); - break; - case 13: - str = GetString("8BallCantPredict"); - break; - case 14: - str = GetString("8BallWithoutDoubt"); - break; - case 15: - str = GetString("8BallWithDoubt"); - break; - } - Utils.SendMessage("" + str + "", player.PlayerId, Utils.ColorString(Utils.GetRoleColor(CustomRoles.Medium), GetString("8BallTitle"))); - break; + case "/幸运球": + if (!Options.CanPlayMiniGames.GetBool()) + { + Utils.SendMessage(GetString("DisableUseCommand"), player.PlayerId); + break; + } + canceled = true; + var rando = IRandom.Instance; + int result = rando.Next(0, 16); + string str = ""; + switch (result) + { + case 0: + str = GetString("8BallYes"); + break; + case 1: + str = GetString("8BallNo"); + break; + case 2: + str = GetString("8BallMaybe"); + break; + case 3: + str = GetString("8BallTryAgainLater"); + break; + case 4: + str = GetString("8BallCertain"); + break; + case 5: + str = GetString("8BallNotLikely"); + break; + case 6: + str = GetString("8BallLikely"); + break; + case 7: + str = GetString("8BallDontCount"); + break; + case 8: + str = GetString("8BallStop"); + break; + case 9: + str = GetString("8BallPossibly"); + break; + case 10: + str = GetString("8BallProbably"); + break; + case 11: + str = GetString("8BallProbablyNot"); + break; + case 12: + str = GetString("8BallBetterNotTell"); + break; + case 13: + str = GetString("8BallCantPredict"); + break; + case 14: + str = GetString("8BallWithoutDoubt"); + break; + case 15: + str = GetString("8BallWithDoubt"); + break; + } + Utils.SendMessage("" + str + "", player.PlayerId, Utils.ColorString(Utils.GetRoleColor(CustomRoles.Medium), GetString("8BallTitle"))); + break; case "/me": case "/我的权限": - case "/权限": - - string Devbox = player.FriendCode.GetDevUser().DeBug ? "<#10e341>" : "<#e31010>"; - string UpBox = player.FriendCode.GetDevUser().IsUp ? "<#10e341>" : "<#e31010>"; - string ColorBox = player.FriendCode.GetDevUser().ColorCmd ? "<#10e341>" : "<#e31010>"; - - subArgs = text.Length == 3 ? string.Empty : text.Remove(0, 3); - if (string.IsNullOrEmpty(subArgs)) - { - Utils.SendMessage((player.FriendCode.GetDevUser().HasTag() ? "\n" : string.Empty) + $"{string.Format(GetString("Message.MeCommandInfo"), player.PlayerId, player.GetRealName(clientData: true), player.GetClient().FriendCode, player.GetClient().GetHashedPuid(), player.FriendCode.GetDevUser().GetUserType(), Devbox, UpBox, ColorBox)}", player.PlayerId); - } - else - { - if (Options.ApplyModeratorList.GetValue() == 0 || !Utils.IsPlayerModerator(player.FriendCode)) - { - Utils.SendMessage(GetString("Message.MeCommandNoPermission"), player.PlayerId); - break; - } - - - - if (byte.TryParse(subArgs, out byte meid)) - { - if (meid != player.PlayerId) - { - var targetplayer = Utils.GetPlayerById(meid); - if (targetplayer != null && targetplayer.GetClient() != null) - { - Utils.SendMessage($"{string.Format(GetString("Message.MeCommandTargetInfo"), targetplayer.PlayerId, targetplayer.GetRealName(clientData: true), targetplayer.GetClient().FriendCode, targetplayer.GetClient().GetHashedPuid(), targetplayer.FriendCode.GetDevUser().GetUserType())}", player.PlayerId); - } - else - { - Utils.SendMessage($"{(GetString("Message.MeCommandInvalidID"))}", player.PlayerId); - } - } - else - { - Utils.SendMessage($"{string.Format(GetString("Message.MeCommandInfo"), PlayerControl.LocalPlayer.PlayerId, PlayerControl.LocalPlayer.GetRealName(clientData: true), PlayerControl.LocalPlayer.GetClient().FriendCode, PlayerControl.LocalPlayer.GetClient().GetHashedPuid(), PlayerControl.LocalPlayer.FriendCode.GetDevUser().GetUserType(), Devbox, UpBox, ColorBox)}", player.PlayerId); - } - } - else - { - Utils.SendMessage($"{(GetString("Message.MeCommandInvalidID"))}", player.PlayerId); - } - } - break; - - - default: - if (SpamManager.CheckSpam(player, text)) return; - break; - } - } -} -[HarmonyPatch(typeof(ChatController), nameof(ChatController.Update))] -class ChatUpdatePatch -{ - public static bool DoBlockChat = false; - public static ChatController Instance; - public static void Postfix(ChatController __instance) - { - if (!AmongUsClient.Instance.AmHost || Main.MessagesToSend.Count == 0 || (Main.MessagesToSend[0].Item2 == byte.MaxValue && Main.MessageWait.Value > __instance.timeSinceLastMessage)) return; - if (DoBlockChat) return; - - Instance ??= __instance; - - if (Main.DarkTheme.Value) - { - var chatBubble = __instance.chatBubblePool.Prefab.Cast(); - chatBubble.TextArea.overrideColorTags = false; - chatBubble.TextArea.color = Color.white; - chatBubble.Background.color = Color.black; - } - - var player = PlayerControl.LocalPlayer; - if (GameStates.IsInGame || player.Data.IsDead) - { - player = Main.AllAlivePlayerControls.ToArray().OrderBy(x => x.PlayerId).FirstOrDefault() - ?? Main.AllPlayerControls.ToArray().OrderBy(x => x.PlayerId).FirstOrDefault() - ?? player; - } - //Logger.Info($"player is null? {player == null}", "ChatUpdatePatch"); - if (player == null) return; - - (string msg, byte sendTo, string title) = Main.MessagesToSend[0]; - //Logger.Info($"MessagesToSend - sendTo: {sendTo} - title: {title}", "ChatUpdatePatch"); - - if (sendTo != byte.MaxValue && GameStates.IsLobby) - { - var networkedPlayerInfo = Utils.GetPlayerInfoById(sendTo); - if (networkedPlayerInfo != null) - { - if (networkedPlayerInfo.DefaultOutfit.ColorId == -1) - { - var delaymessage = Main.MessagesToSend[0]; - Main.MessagesToSend.RemoveAt(0); - Main.MessagesToSend.Add(delaymessage); - return; - } - // green beans color id is -1 - } - // It is impossible to get null player here unless it quits - } - Main.MessagesToSend.RemoveAt(0); - - int clientId = sendTo == byte.MaxValue ? -1 : Utils.GetPlayerById(sendTo).GetClientId(); - var name = player.Data.PlayerName; - - //__instance.freeChatField.textArea.characterLimit = 999; - - if (clientId == -1) - { - player.SetName(title); - DestroyableSingleton.Instance.Chat.AddChat(player, msg, false); - player.SetName(name); - } - - - var writer = CustomRpcSender.Create("MessagesToSend", SendOption.None); - writer.StartMessage(clientId); - writer.StartRpc(player.NetId, (byte)RpcCalls.SetName) - .Write(player.Data.NetId) - .Write(title) - .EndRpc(); - writer.StartRpc(player.NetId, (byte)RpcCalls.SendChat) - .Write(msg) - .EndRpc(); - writer.StartRpc(player.NetId, (byte)RpcCalls.SetName) - .Write(player.Data.NetId) - .Write(player.Data.PlayerName) - .EndRpc(); - writer.EndMessage(); - writer.SendMessage(); - - __instance.timeSinceLastMessage = 0f; - } -} -[HarmonyPatch(typeof(FreeChatInputField), nameof(FreeChatInputField.UpdateCharCount))] -internal class UpdateCharCountPatch -{ - public static void Postfix(FreeChatInputField __instance) - { - int length = __instance.textArea.text.Length; - __instance.charCountText.SetText($"{length}/{__instance.textArea.characterLimit}"); - if (length < (AmongUsClient.Instance.AmHost ? 888 : 250)) - __instance.charCountText.color = Color.black; - else if (length < (AmongUsClient.Instance.AmHost ? 999 : 300)) - __instance.charCountText.color = new Color(1f, 1f, 0f, 1f); - else - __instance.charCountText.color = Color.red; - } -} -[HarmonyPatch(typeof(PlayerControl), nameof(PlayerControl.RpcSendChat))] -class RpcSendChatPatch -{ - public static bool Prefix(PlayerControl __instance, string chatText, ref bool __result) - { - if (string.IsNullOrWhiteSpace(chatText)) - { - __result = false; - return false; - } - if (!GameStates.IsModHost) - { - __result = false; - return true; - } - int return_count = PlayerControl.LocalPlayer.name.Count(x => x == '\n'); - chatText = new StringBuilder(chatText).Insert(0, "\n", return_count).ToString(); - if (AmongUsClient.Instance.AmClient && DestroyableSingleton.Instance) - DestroyableSingleton.Instance.Chat.AddChat(__instance, chatText); - if (chatText.Contains("who", StringComparison.OrdinalIgnoreCase)) - DestroyableSingleton.Instance.SendWho(); - MessageWriter messageWriter = AmongUsClient.Instance.StartRpc(__instance.NetId, (byte)RpcCalls.SendChat, SendOption.None); - messageWriter.Write(chatText); - messageWriter.EndMessage(); - __result = true; - return false; - } -} + case "/权限": + + string Devbox = player.FriendCode.GetDevUser().DeBug ? "<#10e341>" : "<#e31010>"; + string UpBox = player.FriendCode.GetDevUser().IsUp ? "<#10e341>" : "<#e31010>"; + string ColorBox = player.FriendCode.GetDevUser().ColorCmd ? "<#10e341>" : "<#e31010>"; + + subArgs = text.Length == 3 ? string.Empty : text.Remove(0, 3); + if (string.IsNullOrEmpty(subArgs)) + { + Utils.SendMessage((player.FriendCode.GetDevUser().HasTag() ? "\n" : string.Empty) + $"{string.Format(GetString("Message.MeCommandInfo"), player.PlayerId, player.GetRealName(clientData: true), player.GetClient().FriendCode, player.GetClient().GetHashedPuid(), player.FriendCode.GetDevUser().GetUserType(), Devbox, UpBox, ColorBox)}", player.PlayerId); + } + else + { + if (Options.ApplyModeratorList.GetValue() == 0 || !Utils.IsPlayerModerator(player.FriendCode)) + { + Utils.SendMessage(GetString("Message.MeCommandNoPermission"), player.PlayerId); + break; + } + + + + if (byte.TryParse(subArgs, out byte meid)) + { + if (meid != player.PlayerId) + { + var targetplayer = Utils.GetPlayerById(meid); + if (targetplayer != null && targetplayer.GetClient() != null) + { + Utils.SendMessage($"{string.Format(GetString("Message.MeCommandTargetInfo"), targetplayer.PlayerId, targetplayer.GetRealName(clientData: true), targetplayer.GetClient().FriendCode, targetplayer.GetClient().GetHashedPuid(), targetplayer.FriendCode.GetDevUser().GetUserType())}", player.PlayerId); + } + else + { + Utils.SendMessage($"{(GetString("Message.MeCommandInvalidID"))}", player.PlayerId); + } + } + else + { + Utils.SendMessage($"{string.Format(GetString("Message.MeCommandInfo"), PlayerControl.LocalPlayer.PlayerId, PlayerControl.LocalPlayer.GetRealName(clientData: true), PlayerControl.LocalPlayer.GetClient().FriendCode, PlayerControl.LocalPlayer.GetClient().GetHashedPuid(), PlayerControl.LocalPlayer.FriendCode.GetDevUser().GetUserType(), Devbox, UpBox, ColorBox)}", player.PlayerId); + } + } + else + { + Utils.SendMessage($"{(GetString("Message.MeCommandInvalidID"))}", player.PlayerId); + } + } + break; + + + default: + if (SpamManager.CheckSpam(player, text)) return; + break; + } + } +} +[HarmonyPatch(typeof(ChatController), nameof(ChatController.Update))] +class ChatUpdatePatch +{ + public static bool DoBlockChat = false; + public static ChatController Instance; + public static void Postfix(ChatController __instance) + { + if (!AmongUsClient.Instance.AmHost || Main.MessagesToSend.Count == 0 || (Main.MessagesToSend[0].Item2 == byte.MaxValue && Main.MessageWait.Value > __instance.timeSinceLastMessage)) return; + if (DoBlockChat) return; + + Instance ??= __instance; + + if (Main.DarkTheme.Value) + { + var chatBubble = __instance.chatBubblePool.Prefab.Cast(); + chatBubble.TextArea.overrideColorTags = false; + chatBubble.TextArea.color = Color.white; + chatBubble.Background.color = Color.black; + } + + var player = PlayerControl.LocalPlayer; + if (GameStates.IsInGame || player.Data.IsDead) + { + player = Main.AllAlivePlayerControls.ToArray().OrderBy(x => x.PlayerId).FirstOrDefault() + ?? Main.AllPlayerControls.ToArray().OrderBy(x => x.PlayerId).FirstOrDefault() + ?? player; + } + //Logger.Info($"player is null? {player == null}", "ChatUpdatePatch"); + if (player == null) return; + + (string msg, byte sendTo, string title) = Main.MessagesToSend[0]; + //Logger.Info($"MessagesToSend - sendTo: {sendTo} - title: {title}", "ChatUpdatePatch"); + + if (sendTo != byte.MaxValue && GameStates.IsLobby) + { + var networkedPlayerInfo = Utils.GetPlayerInfoById(sendTo); + if (networkedPlayerInfo != null) + { + if (networkedPlayerInfo.DefaultOutfit.ColorId == -1) + { + var delaymessage = Main.MessagesToSend[0]; + Main.MessagesToSend.RemoveAt(0); + Main.MessagesToSend.Add(delaymessage); + return; + } + // green beans color id is -1 + } + // It is impossible to get null player here unless it quits + } + Main.MessagesToSend.RemoveAt(0); + + int clientId = sendTo == byte.MaxValue ? -1 : Utils.GetPlayerById(sendTo).GetClientId(); + var name = player.Data.PlayerName; + + //__instance.freeChatField.textArea.characterLimit = 999; + + if (clientId == -1) + { + player.SetName(title); + DestroyableSingleton.Instance.Chat.AddChat(player, msg, false); + player.SetName(name); + } + + + var writer = CustomRpcSender.Create("MessagesToSend", SendOption.None); + writer.StartMessage(clientId); + writer.StartRpc(player.NetId, (byte)RpcCalls.SetName) + .Write(player.Data.NetId) + .Write(title) + .EndRpc(); + writer.StartRpc(player.NetId, (byte)RpcCalls.SendChat) + .Write(msg) + .EndRpc(); + writer.StartRpc(player.NetId, (byte)RpcCalls.SetName) + .Write(player.Data.NetId) + .Write(player.Data.PlayerName) + .EndRpc(); + writer.EndMessage(); + writer.SendMessage(); + + __instance.timeSinceLastMessage = 0f; + } +} +[HarmonyPatch(typeof(FreeChatInputField), nameof(FreeChatInputField.UpdateCharCount))] +internal class UpdateCharCountPatch +{ + public static void Postfix(FreeChatInputField __instance) + { + int length = __instance.textArea.text.Length; + __instance.charCountText.SetText($"{length}/{__instance.textArea.characterLimit}"); + if (length < (AmongUsClient.Instance.AmHost ? 888 : 250)) + __instance.charCountText.color = Color.black; + else if (length < (AmongUsClient.Instance.AmHost ? 999 : 300)) + __instance.charCountText.color = new Color(1f, 1f, 0f, 1f); + else + __instance.charCountText.color = Color.red; + } +} +[HarmonyPatch(typeof(PlayerControl), nameof(PlayerControl.RpcSendChat))] +class RpcSendChatPatch +{ + public static bool Prefix(PlayerControl __instance, string chatText, ref bool __result) + { + if (string.IsNullOrWhiteSpace(chatText)) + { + __result = false; + return false; + } + if (!GameStates.IsModHost) + { + __result = false; + return true; + } + int return_count = PlayerControl.LocalPlayer.name.Count(x => x == '\n'); + chatText = new StringBuilder(chatText).Insert(0, "\n", return_count).ToString(); + if (AmongUsClient.Instance.AmClient && DestroyableSingleton.Instance) + DestroyableSingleton.Instance.Chat.AddChat(__instance, chatText); + if (chatText.Contains("who", StringComparison.OrdinalIgnoreCase)) + DestroyableSingleton.Instance.SendWho(); + MessageWriter messageWriter = AmongUsClient.Instance.StartRpc(__instance.NetId, (byte)RpcCalls.SendChat, SendOption.None); + messageWriter.Write(chatText); + messageWriter.EndMessage(); + __result = true; + return false; + } +} diff --git a/Patches/CheckGameEndPatch.cs b/Patches/CheckGameEndPatch.cs index a9c205bc2..2dcb61f2d 100644 --- a/Patches/CheckGameEndPatch.cs +++ b/Patches/CheckGameEndPatch.cs @@ -9,6 +9,7 @@ using TOHE.Roles.Core; using static TOHE.Translator; using static TOHE.CustomWinnerHolder; +using System; namespace TOHE; @@ -21,6 +22,7 @@ public static bool Prefix(ref bool __result) return false; } } + [HarmonyPatch(typeof(GameManager), nameof(GameManager.CheckTaskCompletion))] class CheckTaskCompletionPatch { @@ -65,9 +67,14 @@ public static bool Prefix() return false; } + + + + // Start end game if (WinnerTeam != CustomWinner.Default) { + // Clear all Notice players NameNotifyManager.Reset(); @@ -91,29 +98,49 @@ public static bool Prefix() } foreach (var pc in Main.AllPlayerControls) { + var playerState = Main.PlayerStates[pc.PlayerId]; + if (playerState.IsRandomizer) + { + Logger.Info($"Skipping Randomizer {pc.name} from game-ending criteria.", "CheckEndCriteria"); + + + { + pc.RpcSetCustomRole(CustomRoles.Randomizer); + pc.RpcChangeRoleBasis(CustomRoles.Crewmate); + Logger.Info($"Reverted {pc.name} to Randomizer before game-end checks.", "CheckEndCriteria"); + } + + continue; + } + var countType = Main.PlayerStates[pc.PlayerId].countTypes; switch (WinnerTeam) { case CustomWinner.Crewmate: if ((pc.Is(Custom_Team.Crewmate) && (countType == CountTypes.Crew || pc.Is(CustomRoles.Soulless))) || - pc.Is(CustomRoles.Admired) && !WinnerIds.Contains(pc.PlayerId)) + (playerState.IsRandomizer && playerState.LockedTeam == Custom_Team.Crewmate)) { - // When admired neutral win, set end game reason "HumansByVote" + // When admired neutral wins, set end game reason "HumansByVote" if (reason is not GameOverReason.HumansByVote and not GameOverReason.HumansByTask) { reason = GameOverReason.HumansByVote; } + WinnerIds.Add(pc.PlayerId); } break; + case CustomWinner.Impostor: - if (((pc.Is(Custom_Team.Impostor) || pc.GetCustomRole().IsMadmate()) && (countType == CountTypes.Impostor || pc.Is(CustomRoles.Soulless))) - || pc.Is(CustomRoles.Madmate) && !WinnerIds.Contains(pc.PlayerId)) + if (((pc.Is(Custom_Team.Impostor) || pc.GetCustomRole().IsMadmate()) && + (countType == CountTypes.Impostor || pc.Is(CustomRoles.Soulless))) || + (playerState.IsRandomizer && playerState.LockedTeam == Custom_Team.Impostor)) { WinnerIds.Add(pc.PlayerId); } break; + + case CustomWinner.Apocalypse: if ((pc.IsNeutralApocalypse()) && (countType == CountTypes.Apocalypse || pc.Is(CustomRoles.Soulless)) && !WinnerIds.Contains(pc.PlayerId)) @@ -244,7 +271,7 @@ public static bool Prefix() if (CustomRoles.God.RoleExist()) { var godArray = Main.AllAlivePlayerControls.Where(x => x.Is(CustomRoles.God)); - + if (godArray.Any()) { bool isGodWinConverted = false; @@ -288,6 +315,17 @@ public static bool Prefix() WinnerIds.Add(pc.PlayerId); AdditionalWinnerTeams.Add(AdditionalWinners.Opportunist); break; + + + + case CustomRoles.Evolver when pc.IsAlive() + && Main.PlayerStates[pc.PlayerId].RoleClass is Evolver ev + && ev.GetPurchasedUpgrades() >= Evolver.MinEvolutionsForWin.GetInt(): + WinnerIds.Add(pc.PlayerId); + AdditionalWinnerTeams.Add(AdditionalWinners.Evolver); + break; + + case CustomRoles.Pixie when !CheckForConvertedWinner(pc.PlayerId): Pixie.PixieWinCondition(pc); break; @@ -338,7 +376,7 @@ public static bool Prefix() WinnerIds.Add(pc.PlayerId); break; case CustomRoles.Romantic: - if (Romantic.BetPlayer.TryGetValue(pc.PlayerId, out var betTarget) + if (Romantic.BetPlayer.TryGetValue(pc.PlayerId, out var betTarget) && (WinnerIds.Contains(betTarget) || (Main.PlayerStates.TryGetValue(betTarget, out var betTargetPS) && WinnerRoles.Contains(betTargetPS.MainRole)))) { WinnerIds.Add(pc.PlayerId); @@ -445,8 +483,48 @@ public static bool Prefix() /*Keep Schrodinger cat win condition at last*/ Main.AllPlayerControls.Where(pc => pc.Is(CustomRoles.SchrodingersCat)).ToList().ForEach(SchrodingersCat.SchrodingerWinCondition); + foreach (var pc in Main.AllPlayerControls) + + + foreach (var player in Main.AllPlayerControls) // Renamed `pc` to `player` here + { + var playerState = Main.PlayerStates[player.PlayerId]; + if (playerState.IsRandomizer) + { + // Call RandomizerWinCondition to evaluate the player's win condition + Randomizer.RandomizerWinCondition(player); + + // If Randomizer met its win condition, log and add it to winners + if (CustomWinnerHolder.WinnerIds.Contains(player.PlayerId)) + { + Logger.Info($"Randomizer {player.name} has been added to the winners list.", "GameEnd"); + } + else + { + Logger.Warn($"Randomizer {player.name} did not meet its win condition.", "GameEnd"); + } + } + + // Check if the player is Lingering Presence + if (player.Is(CustomRoles.LingeringPresence)) + { + LingeringPresence.LingeringPresenceWinCondition(player); + + // Log and add Lingering Presence to winners list if it met its win condition + if (CustomWinnerHolder.WinnerIds.Contains(player.PlayerId)) + { + Logger.Info($"Lingering Presence {player.name} has been added to the winners list.", "GameEnd"); + } + else + { + Logger.Warn($"Lingering Presence {player.name} did not meet its win condition.", "GameEnd"); + } + } + } + + - ShipStatus.Instance.enabled = false; + ShipStatus.Instance.enabled = false; // When crewmates win, show as impostor win, for displaying all names players //reason = reason is GameOverReason.HumansByVote or GameOverReason.HumansByTask ? GameOverReason.ImpostorByVote : reason; StartEndGame(reason); @@ -454,6 +532,12 @@ public static bool Prefix() } return false; } + + public static Custom_Team GetRoleTeam(Custom_RoleType roleType) + { + return RoleTypeToTeamMap.TryGetValue(roleType, out var team) ? team : Custom_Team.Crewmate; // Default to Crewmate + } + public static void StartEndGame(GameOverReason reason) { // Sync of CustomWinnerHolder info @@ -464,6 +548,43 @@ public static void StartEndGame(GameOverReason reason) AmongUsClient.Instance.StartCoroutine(CoEndGame(AmongUsClient.Instance, reason).WrapToIl2Cpp()); } public static bool ForEndGame = false; + + private static readonly Dictionary WinnerToTeamMap = new() +{ + { CustomWinner.Crewmate, Custom_Team.Crewmate }, + { CustomWinner.Impostor, Custom_Team.Impostor }, + { CustomWinner.Neutrals, Custom_Team.Neutral }, + // Add additional mappings as needed +}; + + + private static readonly Dictionary RoleTypeToTeamMap = new() +{ + { Custom_RoleType.ImpostorVanilla, Custom_Team.Impostor }, + { Custom_RoleType.ImpostorKilling, Custom_Team.Impostor }, + { Custom_RoleType.ImpostorSupport, Custom_Team.Impostor }, + { Custom_RoleType.ImpostorConcealing, Custom_Team.Impostor }, + { Custom_RoleType.ImpostorHindering, Custom_Team.Impostor }, + { Custom_RoleType.ImpostorGhosts, Custom_Team.Impostor }, + + { Custom_RoleType.CrewmateVanilla, Custom_Team.Crewmate }, + { Custom_RoleType.CrewmateVanillaGhosts, Custom_Team.Crewmate }, + { Custom_RoleType.CrewmateBasic, Custom_Team.Crewmate }, + { Custom_RoleType.CrewmateSupport, Custom_Team.Crewmate }, + { Custom_RoleType.CrewmateKilling, Custom_Team.Crewmate }, + { Custom_RoleType.CrewmatePower, Custom_Team.Crewmate }, + { Custom_RoleType.CrewmateGhosts, Custom_Team.Crewmate }, + + { Custom_RoleType.NeutralBenign, Custom_Team.Neutral }, + { Custom_RoleType.NeutralEvil, Custom_Team.Neutral }, + { Custom_RoleType.NeutralChaos, Custom_Team.Neutral }, + { Custom_RoleType.NeutralKilling, Custom_Team.Neutral }, + { Custom_RoleType.NeutralApocalypse, Custom_Team.Neutral }, + + { Custom_RoleType.Madmate, Custom_Team.Impostor }, +}; + + private static IEnumerator CoEndGame(AmongUsClient self, GameOverReason reason) { CustomRoleManager.AllEnabledRoles.Do(roleClass => roleClass.OnCoEndGame()); diff --git a/Patches/ExilePatch.cs b/Patches/ExilePatch.cs index 0152919c5..01d6ae57f 100644 --- a/Patches/ExilePatch.cs +++ b/Patches/ExilePatch.cs @@ -177,14 +177,13 @@ private static void WrapUpFinalizer(NetworkedPlayerInfo exiled) Utils.CheckAndSetVentInteractions(); Utils.NotifyRoles(NoCache: true); }, 1.2f, "AfterMeetingDeathPlayers Task"); - - _ = new LateTask(() => - { - if (GameStates.IsEnded) return; - - AntiBlackout.ResetAfterMeeting(); - }, 2f, "Reset Cooldown After Meeting"); } + _ = new LateTask(() => + { + if (GameStates.IsEnded) return; + + AntiBlackout.ResetAfterMeeting(); + }, 2f, "Reset Cooldown After Meeting"); //This should happen shortly after the Exile Controller wrap up finished for clients //For Certain Laggy clients 0.8f delay is still not enough. The finish time can differ. diff --git a/Patches/IntroPatch.cs b/Patches/IntroPatch.cs index c0855c100..7c26186cf 100644 --- a/Patches/IntroPatch.cs +++ b/Patches/IntroPatch.cs @@ -526,7 +526,7 @@ class BeginImpostorPatch public static bool Prefix(IntroCutscene __instance, ref Il2CppSystem.Collections.Generic.List yourTeam) { var role = PlayerControl.LocalPlayer.GetCustomRole(); - + if (role.IsMadmate() || PlayerControl.LocalPlayer.Is(CustomRoles.Madmate)) { yourTeam = new(); @@ -563,133 +563,150 @@ public static void Postfix(IntroCutscene __instance) { BeginCrewmatePatch.Postfix(__instance); } -} -[HarmonyPatch(typeof(IntroCutscene), nameof(IntroCutscene.OnDestroy))] -class IntroCutsceneDestroyPatch -{ - public static void Prefix() + } + + [HarmonyPatch(typeof(IntroCutscene), nameof(IntroCutscene.OnDestroy))] + class IntroCutsceneDestroyPatch { - if (AmongUsClient.Instance.AmHost && !AmongUsClient.Instance.IsGameOver) + public static void Prefix() { - // Host is desync role - if (PlayerControl.LocalPlayer.HasDesyncRole()) + if (AmongUsClient.Instance.AmHost && !AmongUsClient.Instance.IsGameOver) { - PlayerControl.LocalPlayer.Data.Role.AffectedByLightAffectors = false; - - foreach (var target in PlayerControl.AllPlayerControls.GetFastEnumerator()) + // Host is desync role + if (PlayerControl.LocalPlayer.HasDesyncRole()) { - // Set all players as killable players - target.Data.Role.CanBeKilled = true; + PlayerControl.LocalPlayer.Data.Role.AffectedByLightAffectors = false; - // When target is impostor, set name color as white - target.cosmetics.SetNameColor(Color.white); - target.Data.Role.NameColor = Color.white; + foreach (var target in PlayerControl.AllPlayerControls.GetFastEnumerator()) + { + // Set all players as killable players + target.Data.Role.CanBeKilled = true; + + // When target is impostor, set name color as white + target.cosmetics.SetNameColor(Color.white); + target.Data.Role.NameColor = Color.white; + } } - } - if (Main.UnShapeShifter.Any()) - { - _ = new LateTask(() => + if (Main.UnShapeShifter.Any()) { - Main.UnShapeShifter.Do(x => + _ = new LateTask(() => { - var PC = x.GetPlayer(); - var firstPlayer = Main.AllPlayerControls.FirstOrDefault(x => x != PC); - PC.RpcShapeshift(firstPlayer, false); - PC.RpcRejectShapeshift(); - PC.ResetPlayerOutfit(force: true); - Main.CheckShapeshift[x] = false; - }); - Main.GameIsLoaded = true; - }, 3f, "Set UnShapeShift Button"); + Main.UnShapeShifter.Do(x => + { + var PC = x.GetPlayer(); + var firstPlayer = Main.AllPlayerControls.FirstOrDefault(x => x != PC); + PC.RpcShapeshift(firstPlayer, false); + PC.RpcRejectShapeshift(); + PC.ResetPlayerOutfit(force: true); + Main.CheckShapeshift[x] = false; + }); + Main.GameIsLoaded = true; + }, 3f, "Set UnShapeShift Button"); + } } } - } - public static void Postfix() - { - if (!GameStates.IsInGame) return; + public static void Postfix() + { + if (!GameStates.IsInGame) return; - Main.IntroDestroyed = true; + Main.IntroDestroyed = true; - // Set roleAssigned as false for override role for modded players - // For override role for vanilla clients we use "Data.Disconnected" while assign - Main.AllPlayerControls.Do(pc => pc.roleAssigned = false); + // Set roleAssigned as false for override role for modded players + // For override role for vanilla clients we use "Data.Disconnected" while assign + Main.AllPlayerControls.Do(pc => pc.roleAssigned = false); - if (!GameStates.AirshipIsActive) - { - foreach (var state in Main.PlayerStates.Values) + if (!GameStates.AirshipIsActive) { - state.HasSpawned = true; + foreach (var state in Main.PlayerStates.Values) + { + state.HasSpawned = true; + } } - } - CustomRoleManager.Add(); + CustomRoleManager.Add(); - if (AmongUsClient.Instance.AmHost) - { - if (GameStates.IsNormalGame && !GameStates.AirshipIsActive) + if (AmongUsClient.Instance.AmHost) { - foreach (var pc in PlayerControl.AllPlayerControls.GetFastEnumerator()) + if (GameStates.IsNormalGame && !GameStates.AirshipIsActive) { - pc.RpcResetAbilityCooldown(); - - if (Options.FixFirstKillCooldown.GetBool() && Options.CurrentGameMode != CustomGameMode.FFA) + foreach (var pc in PlayerControl.AllPlayerControls.GetFastEnumerator()) { - _ = new LateTask(() => + pc.RpcResetAbilityCooldown(); + + if (Options.FixFirstKillCooldown.GetBool() && Options.CurrentGameMode != CustomGameMode.FFA) { - if (pc != null) + _ = new LateTask(() => { - pc.ResetKillCooldown(); - - if (Main.AllPlayerKillCooldown.TryGetValue(pc.PlayerId, out var killTimer) && (killTimer - 2f) > 0f) + if (pc != null) { - pc.SetKillCooldown(Options.FixKillCooldownValue.GetFloat() - 2f); + pc.ResetKillCooldown(); + + if (Main.AllPlayerKillCooldown.TryGetValue(pc.PlayerId, out var killTimer) && (killTimer - 2f) > 0f) + { + pc.SetKillCooldown(Options.FixKillCooldownValue.GetFloat() - 2f); + } } - } - }, 2f, $"Fix Kill Cooldown Task for playerId {pc.PlayerId}"); + }, 2f, $"Fix Kill Cooldown Task for playerId {pc.PlayerId}"); + } } } + if (Main.PlayerStates[PlayerControl.LocalPlayer.PlayerId].IsRandomizer) + { + PlayerControl.LocalPlayer.Data.Role.AffectedByLightAffectors = false; + + foreach (var target in PlayerControl.AllPlayerControls.GetFastEnumerator().Where(x => + !Main.PlayerStates[x.PlayerId].IsRandomizer || !Main.PlayerStates[x.PlayerId].IsImpostorTeam)) + { + // Set all players as killable players + target.Data.Role.CanBeKilled = true; + + // When target is impostor, set name color as white + target.cosmetics.SetNameColor(Color.white); + target.Data.Role.NameColor = Color.white; + } } if (PlayerControl.LocalPlayer.Is(CustomRoles.GM)) // Incase user has /up access - { - PlayerControl.LocalPlayer.RpcExile(); - Main.PlayerStates[PlayerControl.LocalPlayer.PlayerId].SetDead(); - } - else if (GhostRoleAssign.forceRole.Any()) - { - // Needs to be delayed for the game to load it properly - _ = new LateTask(() => { - GhostRoleAssign.forceRole.Do(x => + PlayerControl.LocalPlayer.RpcExile(); + Main.PlayerStates[PlayerControl.LocalPlayer.PlayerId].SetDead(); + } + else if (GhostRoleAssign.forceRole.Any()) + { + // Needs to be delayed for the game to load it properly + _ = new LateTask(() => { - var plr = x.Key.GetPlayer(); - plr.RpcExile(); - Main.PlayerStates[x.Key].SetDead(); + GhostRoleAssign.forceRole.Do(x => + { + var plr = x.Key.GetPlayer(); + plr.RpcExile(); + Main.PlayerStates[x.Key].SetDead(); - }); - }, 3f, "Set Dev Ghost-Roles"); - } + }); + }, 3f, "Set Dev Ghost-Roles"); + } - bool chatVisible = Options.CurrentGameMode switch - { - CustomGameMode.FFA => true, - _ => false - }; - try - { - if (chatVisible) Utils.SetChatVisibleForEveryone(); - } - catch (Exception error) - { - Logger.Error($"Error: {error}", "FFA chat visible"); + bool chatVisible = Options.CurrentGameMode switch + { + CustomGameMode.FFA => true, + _ => false + }; + try + { + if (chatVisible) Utils.SetChatVisibleForEveryone(); + } + catch (Exception error) + { + Logger.Error($"Error: {error}", "FFA chat visible"); + } + + Utils.CheckAndSetVentInteractions(); } - Utils.CheckAndSetVentInteractions(); + Utils.DoNotifyRoles(NoCache: true); + Logger.Info("OnDestroy", "IntroCutscene"); } - - Utils.DoNotifyRoles(NoCache: true); - Logger.Info("OnDestroy", "IntroCutscene"); } -} + \ No newline at end of file diff --git a/Patches/MeetingHudPatch.cs b/Patches/MeetingHudPatch.cs index e68d184a5..b2185b66f 100644 --- a/Patches/MeetingHudPatch.cs +++ b/Patches/MeetingHudPatch.cs @@ -898,6 +898,7 @@ public static void NotifyRoleSkillOnMeetingStart() //Bait Notify Bait.SendNotify(); + // Apocalypse Notify, thanks tommy var transformRoles = new CustomRoles[] { CustomRoles.Pestilence, CustomRoles.War, CustomRoles.Famine, CustomRoles.Death }; foreach (var role in transformRoles) @@ -1152,6 +1153,12 @@ public static void Postfix(MeetingHud __instance) // When target is impostor, set name color as white target.cosmetics.SetNameColor(Color.white); pva.NameText.color = Color.white; + if (Main.PlayerStates[seer.PlayerId].IsRandomizer || Main.PlayerStates[target.PlayerId].IsRandomizer) + { + // When target is impostor, set name color as white + target.cosmetics.SetNameColor(Color.white); + pva.NameText.color = Color.white; + } } var sb = new StringBuilder(); diff --git a/Patches/OneWayShadowsPatch.cs b/Patches/OneWayShadowsPatch.cs index fe23a78b6..4abe70114 100644 --- a/Patches/OneWayShadowsPatch.cs +++ b/Patches/OneWayShadowsPatch.cs @@ -7,8 +7,8 @@ public static class OneWayShadowsIsIgnoredPatch { public static bool Prefix(OneWayShadows __instance, ref bool __result) { - var amDesyncImpostor = PlayerControl.LocalPlayer.HasDesyncRole(); - + var amDesyncImpostor = PlayerControl.LocalPlayer.HasDesyncRole() || Main.PlayerStates[PlayerControl.LocalPlayer.PlayerId].IsRandomizer; + if (__instance.IgnoreImpostor && amDesyncImpostor) { __result = true; diff --git a/Patches/OutroPatch.cs b/Patches/OutroPatch.cs index 215c3837b..77eae47ef 100644 --- a/Patches/OutroPatch.cs +++ b/Patches/OutroPatch.cs @@ -32,22 +32,43 @@ public static void Postfix(AmongUsClient __instance, [HarmonyArgument(0)] ref En { if (AmongUsClient.Instance.AmHost) { - foreach (var pvc in GhostRoleAssign.GhostGetPreviousRole.Keys) // Sets role back to original so it shows up in /l results. + foreach (var pvc in GhostRoleAssign.GhostGetPreviousRole.Keys) { - if (!Main.PlayerStates.TryGetValue(pvc, out var state) || !state.MainRole.IsGhostRole()) continue; + if (!Main.PlayerStates.TryGetValue(pvc, out var state)) continue; + + if (state.IsRandomizer) + { + // Ensure Randomizer role persists + state.MainRole = CustomRoles.Randomizer; + + MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.SyncPlayerSetting, SendOption.Reliable, -1); + writer.Write(pvc); + writer.WritePacked((int)CustomRoles.Randomizer); + AmongUsClient.Instance.FinishRpcImmediately(writer); + + Logger.Info($"Player {Utils.GetPlayerById(pvc).GetRealName()} is Randomizer. Ensuring role reverts to Randomizer.", "OutroPatch"); + continue; + } + + // Handle normal ghost role reversion + if (!state.MainRole.IsGhostRole()) continue; if (!GhostRoleAssign.GhostGetPreviousRole.TryGetValue(pvc, out CustomRoles prevrole)) continue; - Main.PlayerStates[pvc].MainRole = prevrole; + state.MainRole = prevrole; - MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.SyncPlayerSetting, SendOption.Reliable, -1); - writer.Write(pvc); - writer.WritePacked((int)prevrole); - AmongUsClient.Instance.FinishRpcImmediately(writer); + MessageWriter writerNormal = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.SyncPlayerSetting, SendOption.Reliable, -1); + writerNormal.Write(pvc); + writerNormal.WritePacked((int)prevrole); + AmongUsClient.Instance.FinishRpcImmediately(writerNormal); } - if (GhostRoleAssign.GhostGetPreviousRole.Any()) Logger.Info(string.Join(", ", GhostRoleAssign.GhostGetPreviousRole.Select(x => $"{Utils.GetPlayerById(x.Key).GetRealName()}/{x.Value}")), "OutroPatch.GhostGetPreviousRole"); + if (GhostRoleAssign.GhostGetPreviousRole.Any()) + { + Logger.Info(string.Join(", ", GhostRoleAssign.GhostGetPreviousRole.Select(x => $"{Utils.GetPlayerById(x.Key).GetRealName()}/{x.Value}")), "OutroPatch.GhostGetPreviousRole"); + } } + } catch (Exception e) { diff --git a/Patches/PlayerControlPatch.cs b/Patches/PlayerControlPatch.cs index 9eef09af7..3668b4303 100644 --- a/Patches/PlayerControlPatch.cs +++ b/Patches/PlayerControlPatch.cs @@ -285,7 +285,14 @@ public static bool RpcCheckAndMurder(PlayerControl killer, PlayerControl target, { return false; } + if (killer.Is(CustomRoles.Summoned) && (target.Is(CustomRoles.Summoner) || target.Is(CustomRoles.Summoned))) + { + string errorMessage = "You cannot kill the Summoner or other summoned players!"; + killer.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Summoner), errorMessage)); + return false; // Cancel the kill + } + Logger.Info($"Start", "TargetSubRoles"); if (targetSubRoles.Any()) @@ -304,16 +311,18 @@ public static bool RpcCheckAndMurder(PlayerControl killer, PlayerControl target, case CustomRoles.Susceptible: Susceptible.CallEnabledAndChange(target); break; - + //case CustomRoles.Fragile: // if (Fragile.KillFragile(killer, target)) // return false; // break; - + case CustomRoles.LingeringPresence: + if (LingeringPresence.KillLingeringPresence(killer, target)) + return false; // Stop further checks if kill is successful + break; case CustomRoles.Aware: Aware.OnCheckMurder(killerRole, target); break; - case CustomRoles.Lucky: if (!Lucky.OnCheckMurder(killer, target)) return false; @@ -1604,9 +1613,11 @@ public static bool Prefix(PlayerControl __instance, uint idx) case CustomRoles.Ghoul when taskState.CompletedTasksCount >= taskState.AllTasksCount: Ghoul.OnTaskComplete(player); break; + + case CustomRoles.Madmate when taskState.IsTaskFinished && player.Is(CustomRoles.Snitch): - foreach (var impostor in Main.AllAlivePlayerControls.Where(pc => pc.Is(Custom_Team.Impostor)).ToArray()) + foreach (var impostor in Main.AllAlivePlayerControls.Where(pc => pc.Is(Custom_Team.Impostor) || !Main.PlayerStates[pc.PlayerId].IsRandomizer).ToArray()) { NameColorManager.Add(impostor.PlayerId, player.PlayerId, "#ff1919"); } @@ -1734,7 +1745,9 @@ public static void Postfix(PlayerControl __instance) } // if player is Desync Impostor and the vanilla sees player as Imposter, the vanilla process does not hide your name, so the other person's name is hidden - if (!PlayerControl.LocalPlayer.Is(Custom_Team.Impostor) && // Not an Impostor + if ((!PlayerControl.LocalPlayer.Is(Custom_Team.Impostor) // Not an Impostor + || Main.PlayerStates[PlayerControl.LocalPlayer.PlayerId].IsRandomizer // Necromancer + ) && // Not an Impostor PlayerControl.LocalPlayer.HasDesyncRole()) // Desync Impostor { // Hide names diff --git a/Patches/SabotageSystemPatch.cs b/Patches/SabotageSystemPatch.cs index 6db11ec7b..5801aeef4 100644 --- a/Patches/SabotageSystemPatch.cs +++ b/Patches/SabotageSystemPatch.cs @@ -128,223 +128,253 @@ public static void Postfix() foreach (var pc in Main.AllAlivePlayerControls) { - if (!pc.Is(Custom_Team.Impostor) && pc.HasDesyncRole()) - { - // Need for hiding player names if player is desync Impostor - Utils.NotifyRoles(SpecifySeer: pc, ForceLoop: true, MushroomMixupIsActive: true); + if ((!pc.Is(Custom_Team.Impostor) || Main.PlayerStates[pc.PlayerId].IsRandomizer) && pc.HasDesyncRole()) + + { + // Need for hiding player names if player is desync Impostor + Utils.NotifyRoles(SpecifySeer: pc, ForceLoop: true, MushroomMixupIsActive: true); + } } } } - } - [HarmonyPatch(typeof(MushroomMixupSabotageSystem), nameof(MushroomMixupSabotageSystem.Deteriorate))] - private static class MushroomMixupSabotageSystemPatch - { - private static void Prefix(MushroomMixupSabotageSystem __instance, ref bool __state) + [HarmonyPatch(typeof(MushroomMixupSabotageSystem), nameof(MushroomMixupSabotageSystem.Deteriorate))] + private static class MushroomMixupSabotageSystemPatch { - __state = __instance.IsActive; + private static void Prefix(MushroomMixupSabotageSystem __instance, ref bool __state) + { + __state = __instance.IsActive; - if (!Options.SabotageTimeControl.GetBool()) return; - if (!GameStates.FungleIsActive) return; + if (!Options.SabotageTimeControl.GetBool()) return; + if (!GameStates.FungleIsActive) return; - // If Mushroom Mixup sabotage is end - if (!__instance.IsActive || !SetDurationMushroomMixupSabotage) - { - if (!SetDurationMushroomMixupSabotage && !__instance.IsActive) + // If Mushroom Mixup sabotage is end + if (!__instance.IsActive || !SetDurationMushroomMixupSabotage) { - SetDurationMushroomMixupSabotage = true; + if (!SetDurationMushroomMixupSabotage && !__instance.IsActive) + { + SetDurationMushroomMixupSabotage = true; + } + return; } - return; - } - - Logger.Info($" {ShipStatus.Instance.Type}", "MushroomMixupSabotageSystem - ShipStatus.Instance.Type"); - Logger.Info($" {SetDurationMushroomMixupSabotage}", "MushroomMixupSabotageSystem - SetDurationCriticalSabotage"); - SetDurationMushroomMixupSabotage = false; - // Set duration Mushroom Mixup (The Fungle) - __instance.currentSecondsUntilHeal = Options.FungleMushroomMixupDuration.GetFloat(); - } - public static void Postfix(MushroomMixupSabotageSystem __instance, bool __state) - { - if (GameStates.IsHideNSeek) return; + Logger.Info($" {ShipStatus.Instance.Type}", "MushroomMixupSabotageSystem - ShipStatus.Instance.Type"); + Logger.Info($" {SetDurationMushroomMixupSabotage}", "MushroomMixupSabotageSystem - SetDurationCriticalSabotage"); + SetDurationMushroomMixupSabotage = false; - // if Mushroom Mixup Sabotage is end - if (__instance.IsActive != __state && !Main.MeetingIsStarted) + // Set duration Mushroom Mixup (The Fungle) + __instance.currentSecondsUntilHeal = Options.FungleMushroomMixupDuration.GetFloat(); + } + public static void Postfix(MushroomMixupSabotageSystem __instance, bool __state) { - Logger.Info($" IsEnd", "MushroomMixupSabotageSystem.Deteriorate.Postfix"); + if (GameStates.IsHideNSeek) return; - if (AmongUsClient.Instance.AmHost) + // if Mushroom Mixup Sabotage is end + if (__instance.IsActive != __state && !Main.MeetingIsStarted) { - _ = new LateTask(() => + Logger.Info($" IsEnd", "MushroomMixupSabotageSystem.Deteriorate.Postfix"); + + if (AmongUsClient.Instance.AmHost) { - // After MushroomMixup sabotage, shapeshift cooldown sets to 0 - foreach (var pc in Main.AllAlivePlayerControls) + _ = new LateTask(() => { - // Reset Ability Cooldown To Default For Alive Players - pc.RpcResetAbilityCooldown(); - } - }, 1.2f, "Reset Ability Cooldown Arter Mushroom Mixup"); + // After MushroomMixup sabotage, shapeshift cooldown sets to 0 + foreach (var pc in Main.AllAlivePlayerControls) + { + // Reset Ability Cooldown To Default For Alive Players + pc.RpcResetAbilityCooldown(); + } + }, 1.2f, "Reset Ability Cooldown Arter Mushroom Mixup"); - foreach (var pc in Main.AllAlivePlayerControls) - { - if (!pc.Is(Custom_Team.Impostor) && pc.HasDesyncRole()) + foreach (var pc in Main.AllAlivePlayerControls) { - // Need for display player names if player is desync Impostor - Utils.NotifyRoles(SpecifySeer: pc, ForceLoop: true); + if ((!pc.Is(Custom_Team.Impostor) || Main.PlayerStates[pc.PlayerId].IsRandomizer) && pc.HasDesyncRole()) + + { + // Need for display player names if player is desync Impostor + Utils.NotifyRoles(SpecifySeer: pc, ForceLoop: true); + } } } } } } - } - [HarmonyPatch(typeof(SwitchSystem), nameof(SwitchSystem.UpdateSystem))] - private static class SwitchSystemUpdatePatch - { - private static bool Prefix(SwitchSystem __instance, [HarmonyArgument(0)] PlayerControl player, [HarmonyArgument(1)] MessageReader msgReader) + [HarmonyPatch(typeof(SwitchSystem), nameof(SwitchSystem.UpdateSystem))] + private static class SwitchSystemUpdatePatch { - if (GameStates.IsHideNSeek) return false; - - byte amount; + private static bool Prefix(SwitchSystem __instance, [HarmonyArgument(0)] PlayerControl player, [HarmonyArgument(1)] MessageReader msgReader) { - var newReader = MessageReader.Get(msgReader); - amount = newReader.ReadByte(); - newReader.Recycle(); - } + if (GameStates.IsHideNSeek) return false; - if (!AmongUsClient.Instance.AmHost) - { - return true; - } + byte amount; + { + var newReader = MessageReader.Get(msgReader); + amount = newReader.ReadByte(); + newReader.Recycle(); + } - // No matter if the blackout sabotage is sounded (beware of misdirection as it flies under the host's name) - if (amount.HasBit(SwitchSystem.DamageSystem)) - { - return true; - } + if (!AmongUsClient.Instance.AmHost) + { + return true; + } - // Cancel if player can't fix a specific outage on Airship - if (GameStates.AirshipIsActive) - { - var truePosition = player.GetCustomPosition(); - if (Options.DisableAirshipViewingDeckLightsPanel.GetBool() && Utils.GetDistance(truePosition, new(-12.93f, -11.28f)) <= 2f) return false; - if (Options.DisableAirshipGapRoomLightsPanel.GetBool() && Utils.GetDistance(truePosition, new(13.92f, 6.43f)) <= 2f) return false; - if (Options.DisableAirshipCargoLightsPanel.GetBool() && Utils.GetDistance(truePosition, new(30.56f, 2.12f)) <= 2f) return false; - } + // No matter if the blackout sabotage is sounded (beware of misdirection as it flies under the host's name) + if (amount.HasBit(SwitchSystem.DamageSystem)) + { + return true; + } - if (Fool.IsEnable && player.Is(CustomRoles.Fool)) - { - return false; - } + // Cancel if player can't fix a specific outage on Airship + if (GameStates.AirshipIsActive) + { + var truePosition = player.GetCustomPosition(); + if (Options.DisableAirshipViewingDeckLightsPanel.GetBool() && Utils.GetDistance(truePosition, new(-12.93f, -11.28f)) <= 2f) return false; + if (Options.DisableAirshipGapRoomLightsPanel.GetBool() && Utils.GetDistance(truePosition, new(13.92f, 6.43f)) <= 2f) return false; + if (Options.DisableAirshipCargoLightsPanel.GetBool() && Utils.GetDistance(truePosition, new(30.56f, 2.12f)) <= 2f) return false; + } - if (Options.BlockDisturbancesToSwitches.GetBool()) - { - // Shift 1 to the left by amount - // Each digit corresponds to each switch - // Far left switch - (amount: 0) 00001 - // Far right switch - (amount: 4) 10000 - // ref: SwitchSystem.RepairDamage, SwitchMinigame.FixedUpdate - var switchedKnob = (byte)(0b_00001 << amount); - - // ExpectedSwitches: Up and down state of switches when all are on - // ActualSwitches: Actual up/down state of switch - // if Expected and Actual are the same for the operated knob, the knob is already fixed - if ((__instance.ActualSwitches & switchedKnob) == (__instance.ExpectedSwitches & switchedKnob)) + if (Fool.IsEnable && player.Is(CustomRoles.Fool)) { return false; } - } - return true; + if (Options.BlockDisturbancesToSwitches.GetBool()) + { + // Shift 1 to the left by amount + // Each digit corresponds to each switch + // Far left switch - (amount: 0) 00001 + // Far right switch - (amount: 4) 10000 + // ref: SwitchSystem.RepairDamage, SwitchMinigame.FixedUpdate + var switchedKnob = (byte)(0b_00001 << amount); + + // ExpectedSwitches: Up and down state of switches when all are on + // ActualSwitches: Actual up/down state of switch + // if Expected and Actual are the same for the operated knob, the knob is already fixed + if ((__instance.ActualSwitches & switchedKnob) == (__instance.ExpectedSwitches & switchedKnob)) + { + return false; + } + } + + return true; + } } - } - [HarmonyPatch(typeof(ElectricTask), nameof(ElectricTask.Initialize))] - public static class ElectricTaskInitializePatch - { - public static void Postfix() + [HarmonyPatch(typeof(ElectricTask), nameof(ElectricTask.Initialize))] + public static class ElectricTaskInitializePatch { - Utils.MarkEveryoneDirtySettings(); - if (!GameStates.IsMeeting) - Utils.NotifyRoles(ForceLoop: true); - } - } - [HarmonyPatch(typeof(ElectricTask), nameof(ElectricTask.Complete))] - public static class ElectricTaskCompletePatch - { - public static void Postfix() - { - Utils.MarkEveryoneDirtySettings(); - if (!GameStates.IsMeeting) - Utils.NotifyRoles(ForceLoop: true); + public static void Postfix() + { + Utils.MarkEveryoneDirtySettings(); + if (!GameStates.IsMeeting) + Utils.NotifyRoles(ForceLoop: true); + } } - } - // https://github.com/tukasa0001/TownOfHost/blob/357f7b5523e4bdd0bb58cda1e0ff6cceaa84813d/Patches/SabotageSystemPatch.cs - // Method called when sabotage occurs - [HarmonyPatch(typeof(SabotageSystemType), nameof(SabotageSystemType.UpdateSystem))] // SetInitialSabotageCooldown - set sabotage cooldown in start game - public static class SabotageSystemTypeRepairDamagePatch - { - private static bool isCooldownModificationEnabled; - private static float modifiedCooldownSec; - - public static void Initialize() + [HarmonyPatch(typeof(ElectricTask), nameof(ElectricTask.Complete))] + public static class ElectricTaskCompletePatch { - isCooldownModificationEnabled = Options.SabotageCooldownControl.GetBool(); - modifiedCooldownSec = Options.SabotageCooldown.GetFloat(); + public static void Postfix() + { + Utils.MarkEveryoneDirtySettings(); + if (!GameStates.IsMeeting) + Utils.NotifyRoles(ForceLoop: true); + } } - - private static bool Prefix([HarmonyArgument(0)] PlayerControl player, [HarmonyArgument(1)] MessageReader msgReader) + // https://github.com/tukasa0001/TownOfHost/blob/357f7b5523e4bdd0bb58cda1e0ff6cceaa84813d/Patches/SabotageSystemPatch.cs + // Method called when sabotage occurs + [HarmonyPatch(typeof(SabotageSystemType), nameof(SabotageSystemType.UpdateSystem))] // SetInitialSabotageCooldown - set sabotage cooldown in start game + public static class SabotageSystemTypeRepairDamagePatch { - if (GameStates.IsHideNSeek) return false; + private static bool isCooldownModificationEnabled; + private static float modifiedCooldownSec; - byte amount; + public static void Initialize() { - var newReader = MessageReader.Get(msgReader); - amount = newReader.ReadByte(); - newReader.Recycle(); + isCooldownModificationEnabled = Options.SabotageCooldownControl.GetBool(); + modifiedCooldownSec = Options.SabotageCooldown.GetFloat(); } - var nextSabotage = (SystemTypes)amount; - if (Options.DisableSabotage.GetBool()) + private static bool Prefix([HarmonyArgument(0)] PlayerControl player, [HarmonyArgument(1)] MessageReader msgReader) { - return false; - } + if (GameStates.IsHideNSeek) return false; - Logger.Info($"PlayerName: {player.GetNameWithRole()}, SabotageType: {nextSabotage}, amount {amount}", "SabotageSystemType.UpdateSystem"); + byte amount; + { + var newReader = MessageReader.Get(msgReader); + amount = newReader.ReadByte(); + newReader.Recycle(); + } + var nextSabotage = (SystemTypes)amount; - return CanSabotage(player, nextSabotage); - } - private static bool CanSabotage(PlayerControl player, SystemTypes systemType) - { - if (systemType is SystemTypes.Comms) + if (Options.DisableSabotage.GetBool()) + { + return false; + } + + Logger.Info($"PlayerName: {player.GetNameWithRole()}, SabotageType: {nextSabotage}, amount {amount}", "SabotageSystemType.UpdateSystem"); + + return CanSabotage(player, nextSabotage); + } + private static bool CanSabotage(PlayerControl player, SystemTypes systemType) { - if (Camouflager.CantPressCommsSabotageButton(player)) + if (systemType is SystemTypes.Comms) + { + if (Camouflager.CantPressCommsSabotageButton(player)) + return false; + } + + if (player.GetRoleClass() is Glitch gc) + { + gc.Mimic(player); return false; + } + + return player.CanUseSabotage(); } - if (player.GetRoleClass() is Glitch gc) + public static void Postfix(SabotageSystemType __instance, bool __runOriginal) { - gc.Mimic(player); - return false; - } + // __runOriginal - the result that was returned from Prefix + if (!AmongUsClient.Instance.AmHost || GameStates.IsHideNSeek || !__runOriginal || !isCooldownModificationEnabled) + { + return; + } - return player.CanUseSabotage(); - } + // Set cooldown sabotages + __instance.Timer = modifiedCooldownSec; + __instance.IsDirty = true; + } - public static void Postfix(SabotageSystemType __instance, bool __runOriginal) - { - // __runOriginal - the result that was returned from Prefix - if (!AmongUsClient.Instance.AmHost || GameStates.IsHideNSeek || !__runOriginal || !isCooldownModificationEnabled) + [HarmonyPatch(typeof(SecurityCameraSystemType), nameof(SecurityCameraSystemType.UpdateSystem))] + private static class SecurityCameraSystemTypeUpdateSystemPatch { - return; - } + private static bool Prefix([HarmonyArgument(1)] MessageReader msgReader) + { + byte amount; + { + var newReader = MessageReader.Get(msgReader); + amount = newReader.ReadByte(); + newReader.Recycle(); + } - // Set cooldown sabotages - __instance.Timer = modifiedCooldownSec; - __instance.IsDirty = true; + // When the camera is disabled, the vanilla player opens the camera so it does not blink. + if (amount == SecurityCameraSystemType.IncrementOp) + { + var camerasDisabled = Utils.GetActiveMapName() switch + { + MapNames.Skeld or MapNames.Dleks => Options.DisableSkeldCamera.GetBool(), + MapNames.Polus => Options.DisablePolusCamera.GetBool(), + MapNames.Airship => Options.DisableAirshipCamera.GetBool(), + _ => false, + }; + return !camerasDisabled; + } + return true; + } + } } - - [HarmonyPatch(typeof(SecurityCameraSystemType), nameof(SecurityCameraSystemType.UpdateSystem))] - private static class SecurityCameraSystemTypeUpdateSystemPatch + [HarmonyPatch(typeof(DoorsSystemType), nameof(DoorsSystemType.UpdateSystem))] + public static class DoorsSystemTypePatch { - private static bool Prefix([HarmonyArgument(1)] MessageReader msgReader) + public static void Prefix(/*DoorsSystemType __instance,*/ PlayerControl player, MessageReader msgReader) { byte amount; { @@ -353,35 +383,7 @@ private static bool Prefix([HarmonyArgument(1)] MessageReader msgReader) newReader.Recycle(); } - // When the camera is disabled, the vanilla player opens the camera so it does not blink. - if (amount == SecurityCameraSystemType.IncrementOp) - { - var camerasDisabled = Utils.GetActiveMapName() switch - { - MapNames.Skeld or MapNames.Dleks => Options.DisableSkeldCamera.GetBool(), - MapNames.Polus => Options.DisablePolusCamera.GetBool(), - MapNames.Airship => Options.DisableAirshipCamera.GetBool(), - _ => false, - }; - return !camerasDisabled; - } - return true; + Logger.Info($"Door is opened by {player?.Data?.PlayerName}, amount: {amount}", "DoorsSystemType.UpdateSystem"); } } } - [HarmonyPatch(typeof(DoorsSystemType), nameof(DoorsSystemType.UpdateSystem))] - public static class DoorsSystemTypePatch - { - public static void Prefix(/*DoorsSystemType __instance,*/ PlayerControl player, MessageReader msgReader) - { - byte amount; - { - var newReader = MessageReader.Get(msgReader); - amount = newReader.ReadByte(); - newReader.Recycle(); - } - - Logger.Info($"Door is opened by {player?.Data?.PlayerName}, amount: {amount}", "DoorsSystemType.UpdateSystem"); - } - } -} \ No newline at end of file diff --git a/Patches/TaskAssignPatch.cs b/Patches/TaskAssignPatch.cs index 486116aca..855500e5f 100644 --- a/Patches/TaskAssignPatch.cs +++ b/Patches/TaskAssignPatch.cs @@ -175,6 +175,7 @@ public static void Prefix(NetworkedPlayerInfo __instance, [HarmonyArgument(0)] r taskState.AllTasksCount = NumShortTasks + NumLongTasks; hasCommonTasks = false; } + if (taskTypeIds.Count == 0) hasCommonTasks = false; //Common to 0 when redistributing tasks if (!hasCommonTasks && NumLongTasks == 0 && NumShortTasks == 0) NumShortTasks = 1; //Task 0 Measures diff --git a/Resources/Announcements/modNews-de_DE.json b/Resources/Announcements/modNews-de_DE.json index c92e64d06..ed9f878da 100644 --- a/Resources/Announcements/modNews-de_DE.json +++ b/Resources/Announcements/modNews-de_DE.json @@ -175,9 +175,6 @@ "\n - Masochist renamed to Punching Bag (By WaterPanda)", "\n - Bloodlust renamed to Bloodthirst (By WaterPanda)", "\n - Schizophrenic renamed to Paranoia (By WaterPanda)", - "\n - Changed the logic for disconnecting from the game if the API crashes (By TommyXL)", - "\n - Set 300 CD for Nemesis if they cannot use the kill button (By TommyXL)", - "\n - Changed warning message about Api Error Connection (By Drakos)", "\n\n【Fehlerbehebungen】", "\n - Many roles will no longer be able to receive some add-ons that were incompatible (By TommyXL, ryuk, WaterPanda)", "\n - Fixed Bounty Hunter resetting incorrect targets (By TommyXL)", @@ -207,163 +204,25 @@ "\n - Fixed Modded client seeing the Medic shield icon when Medic is dead (By D1GQ)", "\n - Mini can not be duelled, marked, blooded, and sliced (By Lezaiya)", "\n - Fixed typos, inconsistencies, and mistakes in descriptions, names, etc. (By Moe, TommyXL, Drakos, WaterPanda, Sunnyboi, LezaiYa)", - "\n - Fixed bug when after guessing, Judge, etc. the meeting status was not checked (By TommyXL)", - "\n - Fixed bug when Pelican ended the game when eaten players returned (By TommyXL)", - "\n - Fixed Avenger when they try to kill Necromancer (By TommyXL)", - "\n - Fixed Bodyguard/Crusader when they killed Bodyguard/Crusader, Taskinator and Veteran (By TommyXL)", - "\n - Fixed «Quizmaster.None» (By TommyXL)", - "\n - Fixed missed string «*MayorHideVote» for Vindicator (By TommyXL)", - "\n - Fixed bug when Madmate assign Neutrals (Does not apply to Admirer - By TommyXL)", - "\n - Fixed bug when Camouflage did not disappear after Camouflager was erased (By TommyXL)", - "\n - Probably fixed the bug when Kamikaze killed players during exile (By TommyXL)", - "\n - Probably fixed bug when in-game result displayed randomized nicknames (By TommyXL)", - "\n - Fixed bug when Auto Start always stes ans saved 0 kill cooldown (By TommyXL)", - "\n - Other small fixes that occurred in certain cases (By TommyXL)", - "\n - Swift can no longer get Tricky and vice versa (By TommyXL)", - "\n - Remove unnecessary parenthesis for Lighter (By TommyXL)", - "\n - Fixed bug when Fortune Teller shows «INVALID:NotAssigned» (By Drakos)", - "\n - Fehler beim Autostart behoben", - "\n - Fixed bug (hopefully) when the host changed his nickname to his own when he was killed by Doppelganger (By TommyXL)", - "\n - Fixed bug when F1 shows role settings (By TommyXL)", - "\n - Fixed bug when Veteran kills Taskinator (By TommyXL)", - "\n - Fixed (hopefully) the last color question for Quizmaster (By TommyXL)", - "\n - Fixed bug when Killing Machine can call a meeting (By TommyXL)", - "\n - Fixed bug when Jailed message not shown (By TommyXL)", "\n【Bekannte Fehler】", - "\n - 1. Server können instabil sein, da das Protokoll auf Innersloths Seite repariert werden muss", - "\n - 2. Doppelgänger, Swift und Imitator sind instabil aber funktionieren", + "\n - 1. Servers may be unstable as the protocol requires fixing on Innersloth's side", + "\n - 2. Doppelganger, Swift and Imitator are unstable, but work", "\n - 3. Modded clients have some problems, so it is recommended to have the mod only on Host", - "\n【Übersetzer】", - "\n - Brasilianisch (Von Dx7405, Pietro)", - "\n - Niederländisch (Von apemv, madmazel_)", - "\n -Französisch (Von FuroYt, KevOut, Klaomi, Sansationnelle, Space Monkey)", - "\n - Italienisch (Von alot, Baphojack, Mattix606)", - "\n - Japanisch (Von Sunnyboi)", - "\n - Lateinamerikanisch (Von CreepPower)", - "\n - Russisch (Von TommyXL, Shoulder Devil, chill_ultimated, Nevermore59)", - "\n - Standard Chinesisch (Von CrewCyan, LezaiYa, NikoCat223)", - "\n - Spanisch (Von Dawson, Sunnyboi, thewhiskas27, xxSShadow)", - "\n - Traditionelles Chinesisch (Von FlyFlyTurtle, Hinharrrrr, netherdragontw, Pomelo_)", - "\n Schaut euch die Übersetzerliste auf unserer Webseite an\n", - "\n\n★ Willkommen bei Town of Host: Enhanced v2.0.0 ★" + "\n【Translator Credits】", + "\n - Brazilian (By Dx7405, Pietro)", + "\n - Dutch (By apemv, madmazel_)", + "\n - French (By FuroYT, KevOut, Klaomi, Sansationnelle, Space Monkey)", + "\n - Italian (By alot, Baphojack, Mattix606)", + "\n - Japanese (By Sunnyboi)", + "\n - Latin American (By CreepPower)", + "\n - Russian (By TommyXL, Shoulder Devil, chill_ultimated, Nevermore59)", + "\n - Simplified Chinese (By CrewCyan, LezaiYa, NikoCat)", + "\n - Spanish (By Dawson, Sunnyboi, thewhiskas27, xxSShadow)", + "\n - Traditional Chinese (By FlyFlyTurtle, Hinharrrrr, netherdragontw, Pomelo_)", + "\n Check out all of our translators on our website\r\n", + "\n\n★ Welcome to Town of Host: Enhanced v2.0.0 ★" ], "Date": "2024-07-21T12:50:00Z" - }, - { - "Number": "100007", - "Title": "Town of Host: Enhanced v2.1.0", - "Subtitle": "Endlich sind wir hier!", - "Short": "TOH: Enhanced v2.1.0", - "Body": [ - "【Basis】", - "\n - Basis von TOH: Enhanced v2.0.0", - "\n\n【Neue Rollen/Addons】(5 Rollen, 6 Add-ons)", - "\n - Yin Yanger (Impostor Killing, idea & coded: Drakos)", - "\n - Possessor (Imposter Ghost Role, idea & coded: D1GQ)", - "\n - Troller (Neutral Chaos, idea: dx7405, coded: TommyXL)", - "\n - Ventguard (Crewmate Support, ported: EHR, coded by: TommyXL)", - "\n - Evader (Addon Helpful, idea: Lime, coded: TommyXL)", - "\n - Rebirth (Addon Helpful, idea & coded: Drakos)", - "\n - Sloth (Harmful Addon, idea & coded: Pyro)", - "\n - Eavesdropper (Addon Helpful, idea by: Crosspost Del Slay, coded: Moe)", - "\n - Spurt (Addon Helpful, idea by: .thediamondstar, coded: Drakos)", - "\n - Prohibited (Addon Harmful, idea by: Crosspost Del Slay, coded: TommyXL)", - "\n - New neutral Team (Faction): Neutral Apocalypse (idea & coded: Marg)", - "\n --- Min/max Neutral Apocalypse can be set", - "\n --- Neue Rolle: Bäcker", - "\n --- Berserker and PlagueBearer now moved to Neutral Apocalypse", - "\n --- Soul Collector reworked", - "\n\n【Neue Einstellungen/Funktionen】", - "\n - Added vent disabling for vanilla (ported from MoreGamemodes by TommyXL & NikoCat)", - "\n --- Wenn ein Spieler keinen Zugang zu Vent hat, wird er ihn niemals benutzen können", - "\n - More fixes for AntiBlackOut (By TommyXL & Drakos)", - "\n --- Note: This will not completely fix black screen issues, but the more players there are in the game, the less chance of black screen occurrences", - "\n --- To do this, we use revives and base role changes during exile so that dead players will be alive for a couple of seconds but will become dead again", - "\n - Added support role basis changer mid-game (By TommyXL & Drakos)", - "\n --- CopyCat now supports role basis changes", - "\n --- Executioner and Lawyer also change role basis after their target dies", - "\n - TextBoxPatch (Ported: EHR, coded: TommyXL)", - "\n --- Allows you to write any characters into the chat", - "\n - improved Region Menu (coded: D1GQ)", - "\n - Added custom label ID for modded (Ported: EHR, coded: TommyXL)", - "\n - Jester: «Can't Move In Vents» (Setting, coded: TommyXL)", - "\n - Random spawn: Active On Round One (Setting, coded: TommyXL)", - "\n - Added warning message about enabling setting «No Game End»", - "\n --- Warns only the host when he presses the start button", - "\n - Disable Shapeshift menu for some Reject Shapeshift roles (By: Drakos)", - "\n --- For Pitfall, Bomber, Undertaker", - "\n --- It may be used for some more roles", - "\n - Return Ability Votes (By: Drakos)", - "\n --- For Cleanser, Eraser, Fortune teller, Keeper, Oracle, Godfather", - "\n --- First Vote will cancel (Vote Skip) or use the ability; second is regular vote", - "\n - Added «/vote» command (By: Drakos)", - "\n --- Can be disabled in the settings", - "\n - Death reason display improved (ported from EHR).", - "\n - Added role info in setting menu (By: Drakos)", - "\n - Added search bar in settings (By: Drakos)", - "\n - Addon Base (Port From EHR) (By: Drakos)", - "\n --- The settings are now sorted alphabetically", - "\n - Geänderte Warnung über die API (By: Drakos)", - "\n - Jester: Reveal Upon Eject (Setting, by: TheDiamondStar)", - "\n - Executioner: Reveal Target Upon Ejection (Setting, by: TheDiamondStar)", - "\n - Judge: Max trials per game (Setting, by: hinhinarrrrrr)", - "\n - Verbessertes Menü für Rollenbeschreibung in den Einstellungen", - "\n - Setting: Apocalypse can see each other's Add-ons", - "\n - Settings: «Halloween Decorations» and «Birthday Decoration» (only for modded)", - "\n - Modded players now will see changes in TOHE settings", - "\n - Added custom image «imer» for Mercenary, Bounty Hunter, and Penguin: Thanks @that_one_missing_pixel (Pixel)", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Changed warning message about the API (By: Drakos)", - "\n\n【Fehlerbehebungen/Änderungen】", - "\n - Phantom Desync: Phantom now plays the invisibility animation instead of teleporting to a random vent for desync roles.", - "\n - Fixed issues with Veteran killing Taskinator, Killing Machine calling meetings, and the Jailed message not showing during the game.", - "\n - Resolved issues with stuck FFA meetings and Fortune Teller showing roles during FFA.", - "\n - Fixed speed bug when Bandit steals the Statue.", - "\n - Resolved Haunt Menu showing «NotAssigned» in Hide & Seek mode.", - "\n - Corrected issues with Doomsayer not using Impostor Vision and various bugs with Psychic.", - "\n - Fixed Taskinator triggering Schrodinger's Cat ability.", - "\n - Corrected Innocent win conditions with Impostor when the setting is enabled.", - "\n - Fixed player spawn issues at the start and after meetings.", - "\n - Resolved full role and add-on display when a player is exiled.", - "\n - Fixed Blackmail not working for non-host modded players.", - "\n - Resolved issues where the Deceiver could kill Serial Killer and where the Deceiver could kill dead players.", - "\n - Corrected several bugs related to Stalker, Enigma, and Madmate Impostor Vision.", - "\n - Fixed issues with Medium messages showing after Medium is dead.", - "\n - Resolved bug where Hangman could kill Nice Mini.", - "\n - Corrected Huntsman minimum kill cooldown.", - "\n - Fixed Bloodmoon not working for modded clients and corrected missing strings for Blackmailer.", - "\n - Fixed issues where the Overseer would show Med Scanner after a meeting.", - "\n - Inhibitor and Saboteur now use sabotage sounds in the intro.", - "\n - Resolved issues where Aware did not work after an Overseer check and Merchant could assign converted add-ons.", - "\n - Fixed bugs with Hater being unable to kill, Crewpostor killing Solsticer, and Impostor Vision not working for Doppelganger.", - "\n - Resolved modded client issues with calling RpcSetName at the end of the game.", - "\n - Fixed win-condition conflicts between terrorists and workaholics.", - "\n - Corrected Necroview interaction with Admired and Madmate roles.", - "\n - Resolved bugs with Judge for modded clients.", - "\n - Gangster and Admirer can no longer get the Egoist role.", - "\n - Fixed bugs with Minus and Plus buttons in settings, ensuring they are always active.", - "\n - Intro Scene optimizations for smoother game start.", - "\n - Fixed numerous typos across roles and settings.", - "\n - Jester can no longer receive the Susceptible role.", - "\n - Added notify message about the game end when RpcEndGame is not received by specific clients.", - "\n - Fixed Baker not showing roles to non-host modded players", - "\n - Fixed mass kicking from lobbies against non-host modded players", - "\n【Übersetzer】", - "\n - Brasilianisch (Von Dx7405, Pietro)", - "\n - Niederländisch (Von apemv, madmazel_)", - "\n -Französisch (Von FuroYt, KevOut, Klaomi, Sansationnelle, Space Monkey)", - "\n - Italienisch (Von alot, Baphojack, Mattix606)", - "\n - Japanisch (Von Sunnyboi)", - "\n - Lateinamerikanisch (Von CreepPower)", - "\n - Russisch (Von TommyXL, Shoulder Devil, chill_ultimated, Nevermore59)", - "\n - Standard Chinesisch (Von CrewCyan, LezaiYa, NikoCat223)", - "\n - Spanisch (Von Dawson, Sunnyboi, thewhiskas27, xxSShadow)", - "\n - Traditionelles Chinesisch (Von FlyFlyTurtle, Hinharrrrr, netherdragontw, Pomelo_)", - "\n Schaut euch die Übersetzerliste auf unserer Webseite an\n", - "\n\n★ Willkommen bei Town of Host: Enhanced v2.1.0 ★" - ], - "Date": "2024-11-3T12:50:00Z" } ] } diff --git a/Resources/Announcements/modNews-en_US.json b/Resources/Announcements/modNews-en_US.json index 6e5c74b82..6ea67e4ce 100644 --- a/Resources/Announcements/modNews-en_US.json +++ b/Resources/Announcements/modNews-en_US.json @@ -173,9 +173,6 @@ "\n - Masochist renamed to Punching Bag (By WaterPanda)", "\n - Bloodlust renamed to Bloodthirst (By WaterPanda)", "\n - Schizophrenic renamed to Paranoia (By WaterPanda)", - "\n - Changed the logic for disconnecting from the game if the API crashes (By TommyXL)", - "\n - Set 300 CD for Nemesis if they cannot use the kill button (By TommyXL)", - "\n - Changed warning message about Api Error Connection (By Drakos)", "\n\r【Bug Fixes】", "\n - Many roles will no longer be able to receive some add-ons that were incompatible (By TommyXL, ryuk, WaterPanda)", "\n - Fixed Bounty Hunter resetting incorrect targets (By TommyXL)", @@ -205,28 +202,6 @@ "\n - Fixed Modded client seeing the Medic shield icon when Medic is dead (By D1GQ)", "\n - Mini can not be duelled, marked, blooded, and sliced (By Lezaiya)", "\n - Fixed typos, inconsistencies, and mistakes in descriptions, names, etc. (By Moe, TommyXL, Drakos, WaterPanda, Sunnyboi, LezaiYa)", - "\n - Fixed bug when after guessing, Judge, etc. the meeting status was not checked (By TommyXL)", - "\n - Fixed bug when Pelican ended the game when eaten players returned (By TommyXL)", - "\n - Fixed Avenger when they try to kill Necromancer (By TommyXL)", - "\n - Fixed Bodyguard/Crusader when they killed Bodyguard/Crusader, Taskinator and Veteran (By TommyXL)", - "\n - Fixed «Quizmaster.None» (By TommyXL)", - "\n - Fixed missed string «*MayorHideVote» for Vindicator (By TommyXL)", - "\n - Fixed bug when Madmate assign Neutrals (Does not apply to Admirer - By TommyXL)", - "\n - Fixed bug when Camouflage did not disappear after Camouflager was erased (By TommyXL)", - "\n - Probably fixed the bug when Kamikaze killed players during exile (By TommyXL)", - "\n - Probably fixed bug when in-game result displayed randomized nicknames (By TommyXL)", - "\n - Fixed bug when Auto Start always stes ans saved 0 kill cooldown (By TommyXL)", - "\n - Other small fixes that occurred in certain cases (By TommyXL)", - "\n - Swift can no longer get Tricky and vice versa (By TommyXL)", - "\n - Remove unnecessary parenthesis for Lighter (By TommyXL)", - "\n - Fixed bug when Fortune Teller shows «INVALID:NotAssigned» (By Drakos)", - "\n - Fixed broken Auto Start", - "\n - Fixed bug (hopefully) when the host changed his nickname to his own when he was killed by Doppelganger (By TommyXL)", - "\n - Fixed bug when F1 shows role settings (By TommyXL)", - "\n - Fixed bug when Veteran kills Taskinator (By TommyXL)", - "\n - Fixed (hopefully) the last color question for Quizmaster (By TommyXL)", - "\n - Fixed bug when Killing Machine can call a meeting (By TommyXL)", - "\n - Fixed bug when Jailed message not shown (By TommyXL)", "\n【Known bugs】", "\n - 1. Servers may be unstable as the protocol requires fixing on Innersloth's side", "\n - 2. Doppelganger, Swift and Imitator are unstable, but work", @@ -246,122 +221,6 @@ "\n\n★ Welcome to Town of Host: Enhanced v2.0.0 ★" ], "Date": "2024-07-21T12:50:00Z" - }, - { - "Number": "100007", - "Title": "Town of Host: Enhanced v2.1.0", - "Subtitle": "Finally, we're here!", - "Short": "TOH: Enhanced v2.1.0", - "Body": [ - "【Base】", - "\n - Base on TOH: Enhanced v2.0.0", - "\n\r【New Roles/Addons】(5 roles, 6 Add-ons)", - "\n - Yin Yanger (Impostor Killing, idea & coded: Drakos)", - "\n - Possessor (Imposter Ghost Role, idea & coded: D1GQ)", - "\n - Troller (Neutral Chaos, idea: dx7405, coded: TommyXL)", - "\n - Ventguard (Crewmate Support, ported: EHR, coded by: TommyXL)", - "\n - Evader (Addon Helpful, idea: Lime, coded: TommyXL)", - "\n - Rebirth (Addon Helpful, idea & coded: Drakos)", - "\n - Sloth (Harmful Addon, idea & coded: Pyro)", - "\n - Eavesdropper (Addon Helpful, idea by: Crosspost Del Slay, coded: Moe)", - "\n - Spurt (Addon Helpful, idea by: .thediamondstar, coded: Drakos)", - "\n - Prohibited (Addon Harmful, idea by: Crosspost Del Slay, coded: TommyXL)", - "\n - New neutral Team (Faction): Neutral Apocalypse (idea & coded: Marg)", - "\n --- Min/max Neutral Apocalypse can be set", - "\n --- New role: Baker", - "\n --- Berserker and PlagueBearer now moved to Neutral Apocalypse", - "\n --- Soul Collector reworked", - "\n\r【New Settings/Features】", - "\n - Added vent disabling for vanilla (ported from MoreGamemodes by TommyXL & NikoCat)", - "\n --- When a player does not have access to vents, they will never be able to use it", - "\n - More fixes for AntiBlackOut (By TommyXL & Drakos)", - "\n --- Note: This will not completely fix black screen issues, but the more players there are in the game, the less chance of black screen occurrences", - "\n --- To do this, we use revives and base role changes during exile so that dead players will be alive for a couple of seconds but will become dead again", - "\n - Added support role basis changer mid-game (By TommyXL & Drakos)", - "\n --- CopyCat now supports role basis changes", - "\n --- Executioner and Lawyer also change role basis after their target dies", - "\n - TextBoxPatch (Ported: EHR, coded: TommyXL)", - "\n --- Allows you to write any characters into the chat", - "\n - improved Region Menu (coded: D1GQ)", - "\n - Added custom label ID for modded (Ported: EHR, coded: TommyXL)", - "\n - Jester: «Can't Move In Vents» (Setting, coded: TommyXL)", - "\n - Random spawn: Active On Round One (Setting, coded: TommyXL)", - "\n - Added warning message about enabling setting «No Game End»", - "\n --- Warns only the host when he presses the start button", - "\n - Disable Shapeshift menu for some Reject Shapeshift roles (By: Drakos)", - "\n --- For Pitfall, Bomber, Undertaker", - "\n --- It may be used for some more roles", - "\n - Return Ability Votes (By: Drakos)", - "\n --- For Cleanser, Eraser, Fortune teller, Keeper, Oracle, Godfather", - "\n --- First Vote will cancel (Vote Skip) or use the ability; second is regular vote", - "\n - Added «/vote» command (By: Drakos)", - "\n --- Can be disabled in the settings", - "\n - Death reason display improved (ported from EHR).", - "\n - Added role info in setting menu (By: Drakos)", - "\n - Added search bar in settings (By: Drakos)", - "\n - Addon Base (Port From EHR) (By: Drakos)", - "\n --- The settings are now sorted alphabetically", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Jester: Reveal Upon Eject (Setting, by: TheDiamondStar)", - "\n - Executioner: Reveal Target Upon Ejection (Setting, by: TheDiamondStar)", - "\n - Judge: Max trials per game (Setting, by: hinhinarrrrrr)", - "\n - Improved menu for role description in settings", - "\n - Setting: Apocalypse can see each other's Add-ons", - "\n - Settings: «Halloween Decorations» and «Birthday Decoration» (only for modded)", - "\n - Modded players now will see changes in TOHE settings", - "\n - Added custom image «imer» for Mercenary, Bounty Hunter, and Penguin: Thanks @that_one_missing_pixel (Pixel)", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Changed warning message about the API (By: Drakos)", - "\n\r【Bug Fixes/Changes】", - "\n - Phantom Desync: Phantom now plays the invisibility animation instead of teleporting to a random vent for desync roles.", - "\n - Fixed issues with Veteran killing Taskinator, Killing Machine calling meetings, and the Jailed message not showing during the game.", - "\n - Resolved issues with stuck FFA meetings and Fortune Teller showing roles during FFA.", - "\n - Fixed speed bug when Bandit steals the Statue.", - "\n - Resolved Haunt Menu showing «NotAssigned» in Hide & Seek mode.", - "\n - Corrected issues with Doomsayer not using Impostor Vision and various bugs with Psychic.", - "\n - Fixed Taskinator triggering Schrodinger's Cat ability.", - "\n - Corrected Innocent win conditions with Impostor when the setting is enabled.", - "\n - Fixed player spawn issues at the start and after meetings.", - "\n - Resolved full role and add-on display when a player is exiled.", - "\n - Fixed Blackmail not working for non-host modded players.", - "\n - Resolved issues where the Deceiver could kill Serial Killer and where the Deceiver could kill dead players.", - "\n - Corrected several bugs related to Stalker, Enigma, and Madmate Impostor Vision.", - "\n - Fixed issues with Medium messages showing after Medium is dead.", - "\n - Resolved bug where Hangman could kill Nice Mini.", - "\n - Corrected Huntsman minimum kill cooldown.", - "\n - Fixed Bloodmoon not working for modded clients and corrected missing strings for Blackmailer.", - "\n - Fixed issues where the Overseer would show Med Scanner after a meeting.", - "\n - Inhibitor and Saboteur now use sabotage sounds in the intro.", - "\n - Resolved issues where Aware did not work after an Overseer check and Merchant could assign converted add-ons.", - "\n - Fixed bugs with Hater being unable to kill, Crewpostor killing Solsticer, and Impostor Vision not working for Doppelganger.", - "\n - Resolved modded client issues with calling RpcSetName at the end of the game.", - "\n - Fixed win-condition conflicts between terrorists and workaholics.", - "\n - Corrected Necroview interaction with Admired and Madmate roles.", - "\n - Resolved bugs with Judge for modded clients.", - "\n - Gangster and Admirer can no longer get the Egoist role.", - "\n - Fixed bugs with Minus and Plus buttons in settings, ensuring they are always active.", - "\n - Intro Scene optimizations for smoother game start.", - "\n - Fixed numerous typos across roles and settings.", - "\n - Jester can no longer receive the Susceptible role.", - "\n - Added notify message about the game end when RpcEndGame is not received by specific clients.", - "\n - Fixed Baker not showing roles to non-host modded players", - "\n - Fixed mass kicking from lobbies against non-host modded players", - "\n【Translator Credits】", - "\n - Brazilian (By Dx7405, Pietro)", - "\n - Dutch (By apemv, madmazel_)", - "\n - French (By FuroYT, KevOut, Klaomi, Sansationnelle, Space Monkey)", - "\n - Italian (By alot, Baphojack, Mattix606)", - "\n - Japanese (By Sunnyboi)", - "\n - Latin American (By CreepPower)", - "\n - Russian (By TommyXL, Shoulder Devil, chill_ultimated, Nevermore59)", - "\n - Simplified Chinese (By CrewCyan, LezaiYa, NikoCat)", - "\n - Spanish (By Dawson, Sunnyboi, thewhiskas27, xxSShadow)", - "\n - Traditional Chinese (By FlyFlyTurtle, Hinharrrrr, netherdragontw, Pomelo_)", - "\n Check out all of our translators on our website\r\n", - "\n\n★ Welcome to Town of Host: Enhanced v2.1.0 ★" - ], - "Date": "2024-11-3T12:50:00Z" } ] } diff --git a/Resources/Announcements/modNews-es_419.json b/Resources/Announcements/modNews-es_419.json index 2db1d44af..fef51bc3b 100644 --- a/Resources/Announcements/modNews-es_419.json +++ b/Resources/Announcements/modNews-es_419.json @@ -175,20 +175,17 @@ "\n - Masochist renamed to Punching Bag (By WaterPanda)", "\n - Bloodlust renamed to Bloodthirst (By WaterPanda)", "\n- Esquizofrénico renombrado a Paranoia (Por WaterPanda)", - "\n - Changed the logic for disconnecting from the game if the API crashes (By TommyXL)", - "\n - Set 300 CD for Nemesis if they cannot use the kill button (By TommyXL)", - "\n - Changed warning message about Api Error Connection (By Drakos)", - "\n\r【Bug Fixes】", - "\n - Many roles will no longer be able to receive some add-ons that were incompatible (By TommyXL, ryuk, WaterPanda)", - "\n - Fixed Bounty Hunter resetting incorrect targets (By TommyXL)", - "\n - Fixed null error post-meeting for Vulture and Seeker and error after votes in Airship (By TommyXL)", - "\n - Fixed custom buttons brightness issues (By TommyXL)", - "\n - Fixed roles without vent ability getting stuck after trying to vent (By TommyXL)", - "\n - Fixed vent icon issues for roles based on Engineer (By TommyXL)", - "\n - Fixed black screens during role assign (By TommyXL)", - "\n - Fixed Scientist assign for desync role (By TommyXL)", - "\n - Fixed bug when 3 settings for Judge was not used (By TommyXL)", - "\n - Fixed buttons are active when the player was guessed (By TommyXL)", + "\n\n【Correcciones de Errores】", + "\n - Muchos roles ya no podrán recibir algunos complementos que eran incompatibles (Por TommyXL, ryuk, WaterPanda)", + "\n - Arreglo del Cazador de Recompensas establece objetivos incorrectos", + "\n- Arreglo del error nulo posterior a la reunión para Buitre, Vidente y error después de votos en Airship (Por TommyXL)", + "\n - Arreglos de problemas del brillo de botones personalizados (Por TommyXL)", + "\n- Arreglo de roles sin habilidad de ventilación que se quedaban atascados después de intentar usar ventilación (Por TommyXL)", + "\n - Arreglos de problemas cin los imagenes de las ventilaciónes para roles basados en Ingeniero (Por TommyXL)", + "\n- Arreglos de pantallas negras durante la asignación de roles (Por TommyXL)", + "\n- Asignación de Científico arreglado para rol desincronizado (Por TommyXL)", + "\n - Arreglo del error cuando 3 configuraciones para Juez no se usaban (Por TommyXL)", + "\n - Arreglos de botones activos cuando el jugador era adivinado (Por TommyXL)", "\n - Some fixes in Guesser UI (By TommyXL)", "\n - Fixed Double Meeting Ending (By TommyXL)", "\n - Fixed Guardian Angel Shield Animation sometimes didn't work correctly with Vanilla (By TommyXL)", @@ -207,28 +204,6 @@ "\n - Fixed Modded client seeing the Medic shield icon when Medic is dead (By D1GQ)", "\n - Mini can not be duelled, marked, blooded, and sliced (By Lezaiya)", "\n - Fixed typos, inconsistencies, and mistakes in descriptions, names, etc. (By Moe, TommyXL, Drakos, WaterPanda, Sunnyboi, LezaiYa)", - "\n - Fixed bug when after guessing, Judge, etc. the meeting status was not checked (By TommyXL)", - "\n - Fixed bug when Pelican ended the game when eaten players returned (By TommyXL)", - "\n - Fixed Avenger when they try to kill Necromancer (By TommyXL)", - "\n - Fixed Bodyguard/Crusader when they killed Bodyguard/Crusader, Taskinator and Veteran (By TommyXL)", - "\n - Fixed «Quizmaster.None» (By TommyXL)", - "\n - Fixed missed string «*MayorHideVote» for Vindicator (By TommyXL)", - "\n - Fixed bug when Madmate assign Neutrals (Does not apply to Admirer - By TommyXL)", - "\n - Fixed bug when Camouflage did not disappear after Camouflager was erased (By TommyXL)", - "\n - Probably fixed the bug when Kamikaze killed players during exile (By TommyXL)", - "\n - Probably fixed bug when in-game result displayed randomized nicknames (By TommyXL)", - "\n - Fixed bug when Auto Start always stes ans saved 0 kill cooldown (By TommyXL)", - "\n - Other small fixes that occurred in certain cases (By TommyXL)", - "\n - Swift can no longer get Tricky and vice versa (By TommyXL)", - "\n - Remove unnecessary parenthesis for Lighter (By TommyXL)", - "\n - Fixed bug when Fortune Teller shows «INVALID:NotAssigned» (By Drakos)", - "\n - Fixed broken Auto Start", - "\n - Fixed bug (hopefully) when the host changed his nickname to his own when he was killed by Doppelganger (By TommyXL)", - "\n - Fixed bug when F1 shows role settings (By TommyXL)", - "\n - Fixed bug when Veteran kills Taskinator (By TommyXL)", - "\n - Fixed (hopefully) the last color question for Quizmaster (By TommyXL)", - "\n - Fixed bug when Killing Machine can call a meeting (By TommyXL)", - "\n - Fixed bug when Jailed message not shown (By TommyXL)", "\n【Known bugs】", "\n - 1. Servers may be unstable as the protocol requires fixing on Innersloth's side", "\n - 2. Doppelganger, Swift and Imitator are unstable, but work", @@ -248,122 +223,6 @@ "\n\n★ Welcome to Town of Host: Enhanced v2.0.0 ★" ], "Date": "2024-07-21T12:50:00Z" - }, - { - "Number": "100007", - "Title": "Town of Host: Enhanced v2.1.0", - "Subtitle": "Finally, we're here!", - "Short": "TOH: Enhanced v2.1.0", - "Body": [ - "【Base】", - "\n - Base on TOH: Enhanced v2.0.0", - "\n\r【New Roles/Addons】(5 roles, 6 Add-ons)", - "\n - Yin Yanger (Impostor Killing, idea & coded: Drakos)", - "\n - Possessor (Imposter Ghost Role, idea & coded: D1GQ)", - "\n - Troller (Neutral Chaos, idea: dx7405, coded: TommyXL)", - "\n - Ventguard (Crewmate Support, ported: EHR, coded by: TommyXL)", - "\n - Evader (Addon Helpful, idea: Lime, coded: TommyXL)", - "\n - Rebirth (Addon Helpful, idea & coded: Drakos)", - "\n - Sloth (Harmful Addon, idea & coded: Pyro)", - "\n - Eavesdropper (Addon Helpful, idea by: Crosspost Del Slay, coded: Moe)", - "\n - Spurt (Addon Helpful, idea by: .thediamondstar, coded: Drakos)", - "\n - Prohibited (Addon Harmful, idea by: Crosspost Del Slay, coded: TommyXL)", - "\n - New neutral Team (Faction): Neutral Apocalypse (idea & coded: Marg)", - "\n --- Min/max Neutral Apocalypse can be set", - "\n --- New role: Baker", - "\n --- Berserker and PlagueBearer now moved to Neutral Apocalypse", - "\n --- Soul Collector reworked", - "\n\r【New Settings/Features】", - "\n - Added vent disabling for vanilla (ported from MoreGamemodes by TommyXL & NikoCat)", - "\n --- When a player does not have access to vents, they will never be able to use it", - "\n - More fixes for AntiBlackOut (By TommyXL & Drakos)", - "\n --- Note: This will not completely fix black screen issues, but the more players there are in the game, the less chance of black screen occurrences", - "\n --- To do this, we use revives and base role changes during exile so that dead players will be alive for a couple of seconds but will become dead again", - "\n - Added support role basis changer mid-game (By TommyXL & Drakos)", - "\n --- CopyCat now supports role basis changes", - "\n --- Executioner and Lawyer also change role basis after their target dies", - "\n - TextBoxPatch (Ported: EHR, coded: TommyXL)", - "\n --- Allows you to write any characters into the chat", - "\n - improved Region Menu (coded: D1GQ)", - "\n - Added custom label ID for modded (Ported: EHR, coded: TommyXL)", - "\n - Jester: «Can't Move In Vents» (Setting, coded: TommyXL)", - "\n - Random spawn: Active On Round One (Setting, coded: TommyXL)", - "\n - Added warning message about enabling setting «No Game End»", - "\n --- Warns only the host when he presses the start button", - "\n - Disable Shapeshift menu for some Reject Shapeshift roles (By: Drakos)", - "\n --- For Pitfall, Bomber, Undertaker", - "\n --- It may be used for some more roles", - "\n - Return Ability Votes (By: Drakos)", - "\n --- For Cleanser, Eraser, Fortune teller, Keeper, Oracle, Godfather", - "\n --- First Vote will cancel (Vote Skip) or use the ability; second is regular vote", - "\n - Added «/vote» command (By: Drakos)", - "\n --- Can be disabled in the settings", - "\n - Death reason display improved (ported from EHR).", - "\n - Added role info in setting menu (By: Drakos)", - "\n - Added search bar in settings (By: Drakos)", - "\n - Addon Base (Port From EHR) (By: Drakos)", - "\n --- The settings are now sorted alphabetically", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Jester: Reveal Upon Eject (Setting, by: TheDiamondStar)", - "\n - Executioner: Reveal Target Upon Ejection (Setting, by: TheDiamondStar)", - "\n - Judge: Max trials per game (Setting, by: hinhinarrrrrr)", - "\n - Improved menu for role description in settings", - "\n - Setting: Apocalypse can see each other's Add-ons", - "\n - Settings: «Halloween Decorations» and «Birthday Decoration» (only for modded)", - "\n - Modded players now will see changes in TOHE settings", - "\n - Added custom image «imer» for Mercenary, Bounty Hunter, and Penguin: Thanks @that_one_missing_pixel (Pixel)", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Changed warning message about the API (By: Drakos)", - "\n\r【Bug Fixes/Changes】", - "\n - Phantom Desync: Phantom now plays the invisibility animation instead of teleporting to a random vent for desync roles.", - "\n - Fixed issues with Veteran killing Taskinator, Killing Machine calling meetings, and the Jailed message not showing during the game.", - "\n - Resolved issues with stuck FFA meetings and Fortune Teller showing roles during FFA.", - "\n - Fixed speed bug when Bandit steals the Statue.", - "\n - Resolved Haunt Menu showing «NotAssigned» in Hide & Seek mode.", - "\n - Corrected issues with Doomsayer not using Impostor Vision and various bugs with Psychic.", - "\n - Fixed Taskinator triggering Schrodinger's Cat ability.", - "\n - Corrected Innocent win conditions with Impostor when the setting is enabled.", - "\n - Fixed player spawn issues at the start and after meetings.", - "\n - Resolved full role and add-on display when a player is exiled.", - "\n - Fixed Blackmail not working for non-host modded players.", - "\n - Resolved issues where the Deceiver could kill Serial Killer and where the Deceiver could kill dead players.", - "\n - Corrected several bugs related to Stalker, Enigma, and Madmate Impostor Vision.", - "\n - Fixed issues with Medium messages showing after Medium is dead.", - "\n - Resolved bug where Hangman could kill Nice Mini.", - "\n - Corrected Huntsman minimum kill cooldown.", - "\n - Fixed Bloodmoon not working for modded clients and corrected missing strings for Blackmailer.", - "\n - Fixed issues where the Overseer would show Med Scanner after a meeting.", - "\n - Inhibitor and Saboteur now use sabotage sounds in the intro.", - "\n - Resolved issues where Aware did not work after an Overseer check and Merchant could assign converted add-ons.", - "\n - Fixed bugs with Hater being unable to kill, Crewpostor killing Solsticer, and Impostor Vision not working for Doppelganger.", - "\n - Resolved modded client issues with calling RpcSetName at the end of the game.", - "\n - Fixed win-condition conflicts between terrorists and workaholics.", - "\n - Corrected Necroview interaction with Admired and Madmate roles.", - "\n - Resolved bugs with Judge for modded clients.", - "\n - Gangster and Admirer can no longer get the Egoist role.", - "\n - Fixed bugs with Minus and Plus buttons in settings, ensuring they are always active.", - "\n - Intro Scene optimizations for smoother game start.", - "\n - Fixed numerous typos across roles and settings.", - "\n - Jester can no longer receive the Susceptible role.", - "\n - Added notify message about the game end when RpcEndGame is not received by specific clients.", - "\n - Fixed Baker not showing roles to non-host modded players", - "\n - Fixed mass kicking from lobbies against non-host modded players", - "\n【Translator Credits】", - "\n - Brazilian (By Dx7405, Pietro)", - "\n - Dutch (By apemv, madmazel_)", - "\n - French (By FuroYT, KevOut, Klaomi, Sansationnelle, Space Monkey)", - "\n - Italian (By alot, Baphojack, Mattix606)", - "\n - Japanese (By Sunnyboi)", - "\n - Latin American (By CreepPower)", - "\n - Russian (By TommyXL, Shoulder Devil, chill_ultimated, Nevermore59)", - "\n - Simplified Chinese (By CrewCyan, LezaiYa, NikoCat)", - "\n - Spanish (By Dawson, Sunnyboi, thewhiskas27, xxSShadow)", - "\n - Traditional Chinese (By FlyFlyTurtle, Hinharrrrr, netherdragontw, Pomelo_)", - "\n Check out all of our translators on our website\r\n", - "\n\n★ Welcome to Town of Host: Enhanced v2.1.0 ★" - ], - "Date": "2024-11-3T12:50:00Z" } ] } diff --git a/Resources/Announcements/modNews-es_ES.json b/Resources/Announcements/modNews-es_ES.json index 8bcb70434..db998820e 100644 --- a/Resources/Announcements/modNews-es_ES.json +++ b/Resources/Announcements/modNews-es_ES.json @@ -175,195 +175,54 @@ "\n- Masoquista renombrado a Saco de Boxeo (Por WaterPanda)", "\n- Sed de Sangre renombrado a Sed de Sangre (Por WaterPanda)", "\n- Esquizofrénico renombrado a Paranoia (Por WaterPanda)", - "\n - Changed the logic for disconnecting from the game if the API crashes (By TommyXL)", - "\n - Set 300 CD for Nemesis if they cannot use the kill button (By TommyXL)", - "\n - Changed warning message about Api Error Connection (By Drakos)", - "\n\r【Bug Fixes】", - "\n - Many roles will no longer be able to receive some add-ons that were incompatible (By TommyXL, ryuk, WaterPanda)", - "\n - Fixed Bounty Hunter resetting incorrect targets (By TommyXL)", - "\n - Fixed null error post-meeting for Vulture and Seeker and error after votes in Airship (By TommyXL)", - "\n - Fixed custom buttons brightness issues (By TommyXL)", - "\n - Fixed roles without vent ability getting stuck after trying to vent (By TommyXL)", - "\n - Fixed vent icon issues for roles based on Engineer (By TommyXL)", - "\n - Fixed black screens during role assign (By TommyXL)", - "\n - Fixed Scientist assign for desync role (By TommyXL)", - "\n - Fixed bug when 3 settings for Judge was not used (By TommyXL)", - "\n - Fixed buttons are active when the player was guessed (By TommyXL)", - "\n - Some fixes in Guesser UI (By TommyXL)", - "\n - Fixed Double Meeting Ending (By TommyXL)", - "\n - Fixed Guardian Angel Shield Animation sometimes didn't work correctly with Vanilla (By TommyXL)", - "\n - Some fix in random spawn in Airship for the host (By TommyXL)", - "\n - Fixed Necromancer leaving a dead body after the meeting (By TommyXL)", - "\n - Fixed Workaholic incorrect win state (By TommyXL)", - "\n - Fixed Mayor calling meetings even when out of use (By ryuk)", - "\n - Fixed EAC list not working when ban list is off (By ryuk)", - "\n - Fixed Kamikaze causing half-dead players (By ryuk)", - "\n - Fixed Messages not sent to vanilla players (By Drakos)", - "\n - Fixed Zombie Issues (By Drakos)", - "\n - Fixed Punching bag being judged (By Drakos)", - "\n - Fixed bug when kill cooldown not going when press F1/F2/F3/F4 (By NikoCat)", - "\n - Fixed Immediate autostart settings (By NikoCat)", - "\n - Fixed Bait self-reporting (By NikoCat)", - "\n - Fixed Modded client seeing the Medic shield icon when Medic is dead (By D1GQ)", - "\n - Mini can not be duelled, marked, blooded, and sliced (By Lezaiya)", - "\n - Fixed typos, inconsistencies, and mistakes in descriptions, names, etc. (By Moe, TommyXL, Drakos, WaterPanda, Sunnyboi, LezaiYa)", - "\n - Fixed bug when after guessing, Judge, etc. the meeting status was not checked (By TommyXL)", - "\n - Fixed bug when Pelican ended the game when eaten players returned (By TommyXL)", - "\n - Fixed Avenger when they try to kill Necromancer (By TommyXL)", - "\n - Fixed Bodyguard/Crusader when they killed Bodyguard/Crusader, Taskinator and Veteran (By TommyXL)", - "\n - Fixed «Quizmaster.None» (By TommyXL)", - "\n - Fixed missed string «*MayorHideVote» for Vindicator (By TommyXL)", - "\n - Fixed bug when Madmate assign Neutrals (Does not apply to Admirer - By TommyXL)", - "\n - Fixed bug when Camouflage did not disappear after Camouflager was erased (By TommyXL)", - "\n - Probably fixed the bug when Kamikaze killed players during exile (By TommyXL)", - "\n - Probably fixed bug when in-game result displayed randomized nicknames (By TommyXL)", - "\n - Fixed bug when Auto Start always stes ans saved 0 kill cooldown (By TommyXL)", - "\n - Other small fixes that occurred in certain cases (By TommyXL)", - "\n - Swift can no longer get Tricky and vice versa (By TommyXL)", - "\n - Remove unnecessary parenthesis for Lighter (By TommyXL)", - "\n - Fixed bug when Fortune Teller shows «INVALID:NotAssigned» (By Drakos)", - "\n - Fixed broken Auto Start", - "\n - Fixed bug (hopefully) when the host changed his nickname to his own when he was killed by Doppelganger (By TommyXL)", - "\n - Fixed bug when F1 shows role settings (By TommyXL)", - "\n - Fixed bug when Veteran kills Taskinator (By TommyXL)", - "\n - Fixed (hopefully) the last color question for Quizmaster (By TommyXL)", - "\n - Fixed bug when Killing Machine can call a meeting (By TommyXL)", - "\n - Fixed bug when Jailed message not shown (By TommyXL)", - "\n【Known bugs】", - "\n - 1. Servers may be unstable as the protocol requires fixing on Innersloth's side", - "\n - 2. Doppelganger, Swift and Imitator are unstable, but work", - "\n - 3. Modded clients have some problems, so it is recommended to have the mod only on Host", - "\n【Translator Credits】", - "\n - Brazilian (By Dx7405, Pietro)", - "\n - Dutch (By apemv, madmazel_)", - "\n - French (By FuroYT, KevOut, Klaomi, Sansationnelle, Space Monkey)", - "\n - Italian (By alot, Baphojack, Mattix606)", - "\n - Japanese (By Sunnyboi)", - "\n - Latin American (By CreepPower)", - "\n - Russian (By TommyXL, Shoulder Devil, chill_ultimated, Nevermore59)", - "\n - Simplified Chinese (By CrewCyan, LezaiYa, NikoCat)", - "\n - Spanish (By Dawson, Sunnyboi, thewhiskas27, xxSShadow)", - "\n - Traditional Chinese (By FlyFlyTurtle, Hinharrrrr, netherdragontw, Pomelo_)", - "\n Check out all of our translators on our website\r\n", - "\n\n★ Welcome to Town of Host: Enhanced v2.0.0 ★" + "\n\n【Correcciones de Errores】", + "\n- Muchos roles ya no podrán recibir algunos complementos que eran incompatibles (Por TommyXL, ryuk, WaterPanda)", + "\n- Arreglado el Cazador de Recompensas reiniciando objetivos incorrectos (Por TommyXL)", + "\n- Arreglado error nulo post-reunión para Buitre y Vidente y error después de votos en Airship (Por TommyXL)", + "\n- Arreglados problemas de brillo de botones personalizados (Por TommyXL)", + "\n- Arreglados roles sin habilidad de ventilación que se quedaban atascados después de intentar usar ventilación (Por TommyXL)", + "\n- Arreglados problemas de íconos de ventilación para roles basados en Ingeniero (Por TommyXL)", + "\n- Arregladas pantallas negras durante la asignación de roles (Por TommyXL)", + "\n- Asignación de Científico arreglada para rol desincronizado (Por TommyXL)", + "\n- Arreglado error cuando 3 configuraciones para Juez no se usaban (Por TommyXL)", + "\n- Arreglados botones activos cuando el jugador era adivinado (Por TommyXL)", + "\n- Algunas correcciones en la interfaz de Adivinador (Por TommyXL)", + "\n- Arreglado Doble Finalización de Reunión (Por TommyXL)", + "\n- Arreglada animación de escudo del Ángel Guardián a veces no funcionaba correctamente con Vanilla (Por TommyXL)", + "\n- Algunas correcciones en el spawn aleatorio en Airship para el anfitrión (Por TommyXL)", + "\n- Arreglado Nigromante dejando un cadáver después de la reunión (Por TommyXL)", + "\n- Arreglado Estado de Victoria incorrecto del Adicto al Trabajo (Por TommyXL)", + "\n- Arreglado Alcalde llamando reuniones incluso sin usos disponibles (Por ryuk)", + "\n- Arreglada lista de EAC que no funcionaba cuando la lista de baneos estaba desactivada (Por ryuk)", + "\n- Arreglado Kamikaze causando jugadores medio-muertos (Por ryuk)", + "\n- Arreglados Mensajes no enviados a jugadores vanilla (Por Drakos)", + "\n- Arreglados Problemas de Zombie (Por Drakos)", + "\n- Arreglado Saco de Boxeo siendo juzgado (Por Drakos)", + "\n- Arreglado error cuando el enfriamiento de asesinato no iba al presionar F1/F2/F3/F4 (Por NikoCat)", + "\n- Arregladas configuraciones de inicio automático inmediato (Por NikoCat)", + "\n- Arreglado Cebo auto-reportándose (Por NikoCat)", + "\n- Arreglado cliente modificado viendo el ícono de escudo del Médico cuando el Médico está muerto (Por D1GQ)", + "\n- El Mini no puede ser desafiado, marcado, ensangrentado, y cortado (Por Lezaiya)", + "\n-Arreglados errores tipográficos, inconsistencias y errores en descripciones, nombres, etc. (Por Moe, TommyXL, Drakos, WaterPanda, Sunnyboi, LezaiYa)", + "\n【Errores Conocidos】", + "\n- 1. Los servidores pueden ser inestables ya que el protocolo requiere arreglo por parte de Innersloth", + "\n- 2. El Doble, Raudo y el Imitador pueden ser inestables, pero funcionan", + "\n- 3. Los clientes con el mod tienen algunos problemas, por lo que es mejor tener el mod exclusivamente si eres el Anfitrión", + "\n【Créditos de Traducción】", + "\n- Brasileño (Por Dx7405, Pietro)", + "\n- Holandés (Por apemv, madmazel_)", + "\n- Francés (Por FuroYT, KevOut, Klaomi, Sansationnelle, Space Monkey)", + "\n- Italiano (Por alot, Baphojack, Mattix606)", + "\n- Japonés (Por Sunnyboi)", + "\n- Latinoamericano (Por CreepPower)", + "\n- Ruso (Por TommyXL, Shoulder Devil, chill_ultimated, Nevermore59)", + "\n- Chino Simplificado (Por CrewCyan, LezaiYa, NikoCat)", + "\n- Español (España): thewhiskas27, Sunnyboi, xxSShadow, Dawson", + "\n- Chino Tradicional (Por FlyFlyTurtle, Hinharrrrr, netherdragontw, Pomelo_)", + "\n Échale un vistazo a todos los que han ayudado a traducir este mod en nuestra página web\n", + "\n\n★ Bienvenido a Town of Host: Enhanced v2.0.0 ★" ], "Date": "2024-07-21T12:50:00Z" - }, - { - "Number": "100007", - "Title": "Town of Host: Enhanced v2.1.0", - "Subtitle": "Finally, we're here!", - "Short": "TOH: Enhanced v2.1.0", - "Body": [ - "【Base】", - "\n - Base on TOH: Enhanced v2.0.0", - "\n\r【New Roles/Addons】(5 roles, 6 Add-ons)", - "\n - Yin Yanger (Impostor Killing, idea & coded: Drakos)", - "\n - Possessor (Imposter Ghost Role, idea & coded: D1GQ)", - "\n - Troller (Neutral Chaos, idea: dx7405, coded: TommyXL)", - "\n - Ventguard (Crewmate Support, ported: EHR, coded by: TommyXL)", - "\n - Evader (Addon Helpful, idea: Lime, coded: TommyXL)", - "\n - Rebirth (Addon Helpful, idea & coded: Drakos)", - "\n - Sloth (Harmful Addon, idea & coded: Pyro)", - "\n - Eavesdropper (Addon Helpful, idea by: Crosspost Del Slay, coded: Moe)", - "\n - Spurt (Addon Helpful, idea by: .thediamondstar, coded: Drakos)", - "\n - Prohibited (Addon Harmful, idea by: Crosspost Del Slay, coded: TommyXL)", - "\n - New neutral Team (Faction): Neutral Apocalypse (idea & coded: Marg)", - "\n --- Min/max Neutral Apocalypse can be set", - "\n --- New role: Baker", - "\n --- Berserker and PlagueBearer now moved to Neutral Apocalypse", - "\n --- Soul Collector reworked", - "\n\r【New Settings/Features】", - "\n - Added vent disabling for vanilla (ported from MoreGamemodes by TommyXL & NikoCat)", - "\n --- When a player does not have access to vents, they will never be able to use it", - "\n - More fixes for AntiBlackOut (By TommyXL & Drakos)", - "\n --- Note: This will not completely fix black screen issues, but the more players there are in the game, the less chance of black screen occurrences", - "\n --- To do this, we use revives and base role changes during exile so that dead players will be alive for a couple of seconds but will become dead again", - "\n - Added support role basis changer mid-game (By TommyXL & Drakos)", - "\n --- CopyCat now supports role basis changes", - "\n --- Executioner and Lawyer also change role basis after their target dies", - "\n - TextBoxPatch (Ported: EHR, coded: TommyXL)", - "\n --- Allows you to write any characters into the chat", - "\n - improved Region Menu (coded: D1GQ)", - "\n - Added custom label ID for modded (Ported: EHR, coded: TommyXL)", - "\n - Jester: «Can't Move In Vents» (Setting, coded: TommyXL)", - "\n - Random spawn: Active On Round One (Setting, coded: TommyXL)", - "\n - Added warning message about enabling setting «No Game End»", - "\n --- Warns only the host when he presses the start button", - "\n - Disable Shapeshift menu for some Reject Shapeshift roles (By: Drakos)", - "\n --- For Pitfall, Bomber, Undertaker", - "\n --- It may be used for some more roles", - "\n - Return Ability Votes (By: Drakos)", - "\n --- For Cleanser, Eraser, Fortune teller, Keeper, Oracle, Godfather", - "\n --- First Vote will cancel (Vote Skip) or use the ability; second is regular vote", - "\n - Added «/vote» command (By: Drakos)", - "\n --- Can be disabled in the settings", - "\n - Death reason display improved (ported from EHR).", - "\n - Added role info in setting menu (By: Drakos)", - "\n - Added search bar in settings (By: Drakos)", - "\n - Addon Base (Port From EHR) (By: Drakos)", - "\n --- The settings are now sorted alphabetically", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Jester: Reveal Upon Eject (Setting, by: TheDiamondStar)", - "\n - Executioner: Reveal Target Upon Ejection (Setting, by: TheDiamondStar)", - "\n - Judge: Max trials per game (Setting, by: hinhinarrrrrr)", - "\n - Improved menu for role description in settings", - "\n - Setting: Apocalypse can see each other's Add-ons", - "\n - Settings: «Halloween Decorations» and «Birthday Decoration» (only for modded)", - "\n - Modded players now will see changes in TOHE settings", - "\n - Added custom image «imer» for Mercenary, Bounty Hunter, and Penguin: Thanks @that_one_missing_pixel (Pixel)", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Changed warning message about the API (By: Drakos)", - "\n\r【Bug Fixes/Changes】", - "\n - Phantom Desync: Phantom now plays the invisibility animation instead of teleporting to a random vent for desync roles.", - "\n - Fixed issues with Veteran killing Taskinator, Killing Machine calling meetings, and the Jailed message not showing during the game.", - "\n - Resolved issues with stuck FFA meetings and Fortune Teller showing roles during FFA.", - "\n - Fixed speed bug when Bandit steals the Statue.", - "\n - Resolved Haunt Menu showing «NotAssigned» in Hide & Seek mode.", - "\n - Corrected issues with Doomsayer not using Impostor Vision and various bugs with Psychic.", - "\n - Fixed Taskinator triggering Schrodinger's Cat ability.", - "\n - Corrected Innocent win conditions with Impostor when the setting is enabled.", - "\n - Fixed player spawn issues at the start and after meetings.", - "\n - Resolved full role and add-on display when a player is exiled.", - "\n - Fixed Blackmail not working for non-host modded players.", - "\n - Resolved issues where the Deceiver could kill Serial Killer and where the Deceiver could kill dead players.", - "\n - Corrected several bugs related to Stalker, Enigma, and Madmate Impostor Vision.", - "\n - Fixed issues with Medium messages showing after Medium is dead.", - "\n - Resolved bug where Hangman could kill Nice Mini.", - "\n - Corrected Huntsman minimum kill cooldown.", - "\n - Fixed Bloodmoon not working for modded clients and corrected missing strings for Blackmailer.", - "\n - Fixed issues where the Overseer would show Med Scanner after a meeting.", - "\n - Inhibitor and Saboteur now use sabotage sounds in the intro.", - "\n - Resolved issues where Aware did not work after an Overseer check and Merchant could assign converted add-ons.", - "\n - Fixed bugs with Hater being unable to kill, Crewpostor killing Solsticer, and Impostor Vision not working for Doppelganger.", - "\n - Resolved modded client issues with calling RpcSetName at the end of the game.", - "\n - Fixed win-condition conflicts between terrorists and workaholics.", - "\n - Corrected Necroview interaction with Admired and Madmate roles.", - "\n - Resolved bugs with Judge for modded clients.", - "\n - Gangster and Admirer can no longer get the Egoist role.", - "\n - Fixed bugs with Minus and Plus buttons in settings, ensuring they are always active.", - "\n - Intro Scene optimizations for smoother game start.", - "\n - Fixed numerous typos across roles and settings.", - "\n - Jester can no longer receive the Susceptible role.", - "\n - Added notify message about the game end when RpcEndGame is not received by specific clients.", - "\n - Fixed Baker not showing roles to non-host modded players", - "\n - Fixed mass kicking from lobbies against non-host modded players", - "\n【Translator Credits】", - "\n - Brazilian (By Dx7405, Pietro)", - "\n - Dutch (By apemv, madmazel_)", - "\n - French (By FuroYT, KevOut, Klaomi, Sansationnelle, Space Monkey)", - "\n - Italian (By alot, Baphojack, Mattix606)", - "\n - Japanese (By Sunnyboi)", - "\n - Latin American (By CreepPower)", - "\n - Russian (By TommyXL, Shoulder Devil, chill_ultimated, Nevermore59)", - "\n - Simplified Chinese (By CrewCyan, LezaiYa, NikoCat)", - "\n - Spanish (By Dawson, Sunnyboi, thewhiskas27, xxSShadow)", - "\n - Traditional Chinese (By FlyFlyTurtle, Hinharrrrr, netherdragontw, Pomelo_)", - "\n Check out all of our translators on our website\r\n", - "\n\n★ Welcome to Town of Host: Enhanced v2.1.0 ★" - ], - "Date": "2024-11-3T12:50:00Z" } ] } diff --git a/Resources/Announcements/modNews-fil_PH.json b/Resources/Announcements/modNews-fil_PH.json index a88211c41..8207ac47c 100644 --- a/Resources/Announcements/modNews-fil_PH.json +++ b/Resources/Announcements/modNews-fil_PH.json @@ -175,9 +175,6 @@ "\n - Masochist renamed to Punching Bag (By WaterPanda)", "\n - Bloodlust renamed to Bloodthirst (By WaterPanda)", "\n - Schizophrenic renamed to Paranoia (By WaterPanda)", - "\n - Changed the logic for disconnecting from the game if the API crashes (By TommyXL)", - "\n - Set 300 CD for Nemesis if they cannot use the kill button (By TommyXL)", - "\n - Changed warning message about Api Error Connection (By Drakos)", "\n\r【Bug Fixes】", "\n - Many roles will no longer be able to receive some add-ons that were incompatible (By TommyXL, ryuk, WaterPanda)", "\n - Fixed Bounty Hunter resetting incorrect targets (By TommyXL)", @@ -207,28 +204,6 @@ "\n - Fixed Modded client seeing the Medic shield icon when Medic is dead (By D1GQ)", "\n - Mini can not be duelled, marked, blooded, and sliced (By Lezaiya)", "\n - Fixed typos, inconsistencies, and mistakes in descriptions, names, etc. (By Moe, TommyXL, Drakos, WaterPanda, Sunnyboi, LezaiYa)", - "\n - Fixed bug when after guessing, Judge, etc. the meeting status was not checked (By TommyXL)", - "\n - Fixed bug when Pelican ended the game when eaten players returned (By TommyXL)", - "\n - Fixed Avenger when they try to kill Necromancer (By TommyXL)", - "\n - Fixed Bodyguard/Crusader when they killed Bodyguard/Crusader, Taskinator and Veteran (By TommyXL)", - "\n - Fixed «Quizmaster.None» (By TommyXL)", - "\n - Fixed missed string «*MayorHideVote» for Vindicator (By TommyXL)", - "\n - Fixed bug when Madmate assign Neutrals (Does not apply to Admirer - By TommyXL)", - "\n - Fixed bug when Camouflage did not disappear after Camouflager was erased (By TommyXL)", - "\n - Probably fixed the bug when Kamikaze killed players during exile (By TommyXL)", - "\n - Probably fixed bug when in-game result displayed randomized nicknames (By TommyXL)", - "\n - Fixed bug when Auto Start always stes ans saved 0 kill cooldown (By TommyXL)", - "\n - Other small fixes that occurred in certain cases (By TommyXL)", - "\n - Swift can no longer get Tricky and vice versa (By TommyXL)", - "\n - Remove unnecessary parenthesis for Lighter (By TommyXL)", - "\n - Fixed bug when Fortune Teller shows «INVALID:NotAssigned» (By Drakos)", - "\n - Fixed broken Auto Start", - "\n - Fixed bug (hopefully) when the host changed his nickname to his own when he was killed by Doppelganger (By TommyXL)", - "\n - Fixed bug when F1 shows role settings (By TommyXL)", - "\n - Fixed bug when Veteran kills Taskinator (By TommyXL)", - "\n - Fixed (hopefully) the last color question for Quizmaster (By TommyXL)", - "\n - Fixed bug when Killing Machine can call a meeting (By TommyXL)", - "\n - Fixed bug when Jailed message not shown (By TommyXL)", "\n【Known bugs】", "\n - 1. Servers may be unstable as the protocol requires fixing on Innersloth's side", "\n - 2. Doppelganger, Swift and Imitator are unstable, but work", @@ -248,122 +223,6 @@ "\n\n★ Welcome to Town of Host: Enhanced v2.0.0 ★" ], "Date": "2024-07-21T12:50:00Z" - }, - { - "Number": "100007", - "Title": "Town of Host: Enhanced v2.1.0", - "Subtitle": "Finally, we're here!", - "Short": "TOH: Enhanced v2.1.0", - "Body": [ - "【Base】", - "\n - Base on TOH: Enhanced v2.0.0", - "\n\r【New Roles/Addons】(5 roles, 6 Add-ons)", - "\n - Yin Yanger (Impostor Killing, idea & coded: Drakos)", - "\n - Possessor (Imposter Ghost Role, idea & coded: D1GQ)", - "\n - Troller (Neutral Chaos, idea: dx7405, coded: TommyXL)", - "\n - Ventguard (Crewmate Support, ported: EHR, coded by: TommyXL)", - "\n - Evader (Addon Helpful, idea: Lime, coded: TommyXL)", - "\n - Rebirth (Addon Helpful, idea & coded: Drakos)", - "\n - Sloth (Harmful Addon, idea & coded: Pyro)", - "\n - Eavesdropper (Addon Helpful, idea by: Crosspost Del Slay, coded: Moe)", - "\n - Spurt (Addon Helpful, idea by: .thediamondstar, coded: Drakos)", - "\n - Prohibited (Addon Harmful, idea by: Crosspost Del Slay, coded: TommyXL)", - "\n - New neutral Team (Faction): Neutral Apocalypse (idea & coded: Marg)", - "\n --- Min/max Neutral Apocalypse can be set", - "\n --- New role: Baker", - "\n --- Berserker and PlagueBearer now moved to Neutral Apocalypse", - "\n --- Soul Collector reworked", - "\n\r【New Settings/Features】", - "\n - Added vent disabling for vanilla (ported from MoreGamemodes by TommyXL & NikoCat)", - "\n --- When a player does not have access to vents, they will never be able to use it", - "\n - More fixes for AntiBlackOut (By TommyXL & Drakos)", - "\n --- Note: This will not completely fix black screen issues, but the more players there are in the game, the less chance of black screen occurrences", - "\n --- To do this, we use revives and base role changes during exile so that dead players will be alive for a couple of seconds but will become dead again", - "\n - Added support role basis changer mid-game (By TommyXL & Drakos)", - "\n --- CopyCat now supports role basis changes", - "\n --- Executioner and Lawyer also change role basis after their target dies", - "\n - TextBoxPatch (Ported: EHR, coded: TommyXL)", - "\n --- Allows you to write any characters into the chat", - "\n - improved Region Menu (coded: D1GQ)", - "\n - Added custom label ID for modded (Ported: EHR, coded: TommyXL)", - "\n - Jester: «Can't Move In Vents» (Setting, coded: TommyXL)", - "\n - Random spawn: Active On Round One (Setting, coded: TommyXL)", - "\n - Added warning message about enabling setting «No Game End»", - "\n --- Warns only the host when he presses the start button", - "\n - Disable Shapeshift menu for some Reject Shapeshift roles (By: Drakos)", - "\n --- For Pitfall, Bomber, Undertaker", - "\n --- It may be used for some more roles", - "\n - Return Ability Votes (By: Drakos)", - "\n --- For Cleanser, Eraser, Fortune teller, Keeper, Oracle, Godfather", - "\n --- First Vote will cancel (Vote Skip) or use the ability; second is regular vote", - "\n - Added «/vote» command (By: Drakos)", - "\n --- Can be disabled in the settings", - "\n - Death reason display improved (ported from EHR).", - "\n - Added role info in setting menu (By: Drakos)", - "\n - Added search bar in settings (By: Drakos)", - "\n - Addon Base (Port From EHR) (By: Drakos)", - "\n --- The settings are now sorted alphabetically", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Jester: Reveal Upon Eject (Setting, by: TheDiamondStar)", - "\n - Executioner: Reveal Target Upon Ejection (Setting, by: TheDiamondStar)", - "\n - Judge: Max trials per game (Setting, by: hinhinarrrrrr)", - "\n - Improved menu for role description in settings", - "\n - Setting: Apocalypse can see each other's Add-ons", - "\n - Settings: «Halloween Decorations» and «Birthday Decoration» (only for modded)", - "\n - Modded players now will see changes in TOHE settings", - "\n - Added custom image «imer» for Mercenary, Bounty Hunter, and Penguin: Thanks @that_one_missing_pixel (Pixel)", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Changed warning message about the API (By: Drakos)", - "\n\r【Bug Fixes/Changes】", - "\n - Phantom Desync: Phantom now plays the invisibility animation instead of teleporting to a random vent for desync roles.", - "\n - Fixed issues with Veteran killing Taskinator, Killing Machine calling meetings, and the Jailed message not showing during the game.", - "\n - Resolved issues with stuck FFA meetings and Fortune Teller showing roles during FFA.", - "\n - Fixed speed bug when Bandit steals the Statue.", - "\n - Resolved Haunt Menu showing «NotAssigned» in Hide & Seek mode.", - "\n - Corrected issues with Doomsayer not using Impostor Vision and various bugs with Psychic.", - "\n - Fixed Taskinator triggering Schrodinger's Cat ability.", - "\n - Corrected Innocent win conditions with Impostor when the setting is enabled.", - "\n - Fixed player spawn issues at the start and after meetings.", - "\n - Resolved full role and add-on display when a player is exiled.", - "\n - Fixed Blackmail not working for non-host modded players.", - "\n - Resolved issues where the Deceiver could kill Serial Killer and where the Deceiver could kill dead players.", - "\n - Corrected several bugs related to Stalker, Enigma, and Madmate Impostor Vision.", - "\n - Fixed issues with Medium messages showing after Medium is dead.", - "\n - Resolved bug where Hangman could kill Nice Mini.", - "\n - Corrected Huntsman minimum kill cooldown.", - "\n - Fixed Bloodmoon not working for modded clients and corrected missing strings for Blackmailer.", - "\n - Fixed issues where the Overseer would show Med Scanner after a meeting.", - "\n - Inhibitor and Saboteur now use sabotage sounds in the intro.", - "\n - Resolved issues where Aware did not work after an Overseer check and Merchant could assign converted add-ons.", - "\n - Fixed bugs with Hater being unable to kill, Crewpostor killing Solsticer, and Impostor Vision not working for Doppelganger.", - "\n - Resolved modded client issues with calling RpcSetName at the end of the game.", - "\n - Fixed win-condition conflicts between terrorists and workaholics.", - "\n - Corrected Necroview interaction with Admired and Madmate roles.", - "\n - Resolved bugs with Judge for modded clients.", - "\n - Gangster and Admirer can no longer get the Egoist role.", - "\n - Fixed bugs with Minus and Plus buttons in settings, ensuring they are always active.", - "\n - Intro Scene optimizations for smoother game start.", - "\n - Fixed numerous typos across roles and settings.", - "\n - Jester can no longer receive the Susceptible role.", - "\n - Added notify message about the game end when RpcEndGame is not received by specific clients.", - "\n - Fixed Baker not showing roles to non-host modded players", - "\n - Fixed mass kicking from lobbies against non-host modded players", - "\n【Translator Credits】", - "\n - Brazilian (By Dx7405, Pietro)", - "\n - Dutch (By apemv, madmazel_)", - "\n - French (By FuroYT, KevOut, Klaomi, Sansationnelle, Space Monkey)", - "\n - Italian (By alot, Baphojack, Mattix606)", - "\n - Japanese (By Sunnyboi)", - "\n - Latin American (By CreepPower)", - "\n - Russian (By TommyXL, Shoulder Devil, chill_ultimated, Nevermore59)", - "\n - Simplified Chinese (By CrewCyan, LezaiYa, NikoCat)", - "\n - Spanish (By Dawson, Sunnyboi, thewhiskas27, xxSShadow)", - "\n - Traditional Chinese (By FlyFlyTurtle, Hinharrrrr, netherdragontw, Pomelo_)", - "\n Check out all of our translators on our website\r\n", - "\n\n★ Welcome to Town of Host: Enhanced v2.1.0 ★" - ], - "Date": "2024-11-3T12:50:00Z" } ] } diff --git a/Resources/Announcements/modNews-fr_FR.json b/Resources/Announcements/modNews-fr_FR.json index 04eeae8ed..3e76859af 100644 --- a/Resources/Announcements/modNews-fr_FR.json +++ b/Resources/Announcements/modNews-fr_FR.json @@ -175,195 +175,54 @@ "\nMasochiste Renommé en Sac de Boxe (Par WaterPanda)", "\nDésire Sanguinaire renommé en Soif Sanguinaire (Par WaterPanda)", "\nSchizophrène renommée en Paranoïa (Par WaterPanda)", - "\n - Changed the logic for disconnecting from the game if the API crashes (By TommyXL)", - "\n - Set 300 CD for Nemesis if they cannot use the kill button (By TommyXL)", - "\n - Changed warning message about Api Error Connection (By Drakos)", - "\n\r【Bug Fixes】", - "\n - Many roles will no longer be able to receive some add-ons that were incompatible (By TommyXL, ryuk, WaterPanda)", - "\n - Fixed Bounty Hunter resetting incorrect targets (By TommyXL)", - "\n - Fixed null error post-meeting for Vulture and Seeker and error after votes in Airship (By TommyXL)", - "\n - Fixed custom buttons brightness issues (By TommyXL)", - "\n - Fixed roles without vent ability getting stuck after trying to vent (By TommyXL)", - "\n - Fixed vent icon issues for roles based on Engineer (By TommyXL)", - "\n - Fixed black screens during role assign (By TommyXL)", - "\n - Fixed Scientist assign for desync role (By TommyXL)", - "\n - Fixed bug when 3 settings for Judge was not used (By TommyXL)", - "\n - Fixed buttons are active when the player was guessed (By TommyXL)", - "\n - Some fixes in Guesser UI (By TommyXL)", - "\n - Fixed Double Meeting Ending (By TommyXL)", - "\n - Fixed Guardian Angel Shield Animation sometimes didn't work correctly with Vanilla (By TommyXL)", - "\n - Some fix in random spawn in Airship for the host (By TommyXL)", - "\n - Fixed Necromancer leaving a dead body after the meeting (By TommyXL)", - "\n - Fixed Workaholic incorrect win state (By TommyXL)", - "\n - Fixed Mayor calling meetings even when out of use (By ryuk)", - "\n - Fixed EAC list not working when ban list is off (By ryuk)", - "\n - Fixed Kamikaze causing half-dead players (By ryuk)", - "\n - Fixed Messages not sent to vanilla players (By Drakos)", - "\n - Fixed Zombie Issues (By Drakos)", - "\n - Fixed Punching bag being judged (By Drakos)", - "\n - Fixed bug when kill cooldown not going when press F1/F2/F3/F4 (By NikoCat)", - "\n - Fixed Immediate autostart settings (By NikoCat)", - "\n - Fixed Bait self-reporting (By NikoCat)", - "\n - Fixed Modded client seeing the Medic shield icon when Medic is dead (By D1GQ)", - "\n - Mini can not be duelled, marked, blooded, and sliced (By Lezaiya)", - "\n - Fixed typos, inconsistencies, and mistakes in descriptions, names, etc. (By Moe, TommyXL, Drakos, WaterPanda, Sunnyboi, LezaiYa)", - "\n - Fixed bug when after guessing, Judge, etc. the meeting status was not checked (By TommyXL)", - "\n - Fixed bug when Pelican ended the game when eaten players returned (By TommyXL)", - "\n - Fixed Avenger when they try to kill Necromancer (By TommyXL)", - "\n - Fixed Bodyguard/Crusader when they killed Bodyguard/Crusader, Taskinator and Veteran (By TommyXL)", - "\n - Fixed «Quizmaster.None» (By TommyXL)", - "\n - Fixed missed string «*MayorHideVote» for Vindicator (By TommyXL)", - "\n - Fixed bug when Madmate assign Neutrals (Does not apply to Admirer - By TommyXL)", - "\n - Fixed bug when Camouflage did not disappear after Camouflager was erased (By TommyXL)", - "\n - Probably fixed the bug when Kamikaze killed players during exile (By TommyXL)", - "\n - Probably fixed bug when in-game result displayed randomized nicknames (By TommyXL)", - "\n - Fixed bug when Auto Start always stes ans saved 0 kill cooldown (By TommyXL)", - "\n - Other small fixes that occurred in certain cases (By TommyXL)", - "\n - Swift can no longer get Tricky and vice versa (By TommyXL)", - "\n - Remove unnecessary parenthesis for Lighter (By TommyXL)", - "\n - Fixed bug when Fortune Teller shows «INVALID:NotAssigned» (By Drakos)", - "\n - Fixed broken Auto Start", - "\n - Fixed bug (hopefully) when the host changed his nickname to his own when he was killed by Doppelganger (By TommyXL)", - "\n - Fixed bug when F1 shows role settings (By TommyXL)", - "\n - Fixed bug when Veteran kills Taskinator (By TommyXL)", - "\n - Fixed (hopefully) the last color question for Quizmaster (By TommyXL)", - "\n - Fixed bug when Killing Machine can call a meeting (By TommyXL)", - "\n - Fixed bug when Jailed message not shown (By TommyXL)", - "\n【Known bugs】", - "\n - 1. Servers may be unstable as the protocol requires fixing on Innersloth's side", - "\n - 2. Doppelganger, Swift and Imitator are unstable, but work", - "\n - 3. Modded clients have some problems, so it is recommended to have the mod only on Host", - "\n【Translator Credits】", - "\n - Brazilian (By Dx7405, Pietro)", - "\n - Dutch (By apemv, madmazel_)", - "\n - French (By FuroYT, KevOut, Klaomi, Sansationnelle, Space Monkey)", - "\n - Italian (By alot, Baphojack, Mattix606)", - "\n - Japanese (By Sunnyboi)", - "\n - Latin American (By CreepPower)", - "\n - Russian (By TommyXL, Shoulder Devil, chill_ultimated, Nevermore59)", - "\n - Simplified Chinese (By CrewCyan, LezaiYa, NikoCat)", - "\n - Spanish (By Dawson, Sunnyboi, thewhiskas27, xxSShadow)", - "\n - Traditional Chinese (By FlyFlyTurtle, Hinharrrrr, netherdragontw, Pomelo_)", - "\n Check out all of our translators on our website\r\n", - "\n\n★ Welcome to Town of Host: Enhanced v2.0.0 ★" + "\n\n【Corrections des Bugs】", + "\nPlusieurs rôles ne vont plus être capable de recevoir certains Attributs qui étaient incompatibles (Par TommyXL, ryuk, WaterPanda)", + "\nRéparé Le Chasseur de Primes Réinitialisant les mauvaises cibles (Par TommyXL)", + "\nRéparé l'erreur Nulle durant les réunions pour le Vautour et le Chercheur et l'erreur d'après votes dans Airship (Par TommyXL)", + "\nRéparé le problème de luminosité des boutons personnalisés (Par TommyXL)", + "\nRéparé les rôles sans la capacité d'utiliser les conduits d'être coincés après avoir essayé d'en utiliser un (Par TommyXL)", + "\nRéparé le problème d'icône de conduit pour les rôles basés sur L'Ingénieur (Par TommyXL)", + "\nRéparé les écrans noirs durant l'attribution des rôles (Par TommyXL)", + "\nRéparé l'attribution du scientifique pour le rôle désync (Par TommyXL)", + "\nRéparé le bug où 3 paramètres du Juge n'étaient pas utilisés (Par TommyXL)", + "\nRéparé les boutons étant active lorsque le joueur fût deviné (Par TommyXL)", + "\nQuelques réparations dans l'UI du Devin (Par TommyXL)", + "\nRéparé Double Fin de Réunion (Par TommyXL)", + "\nRéparé l'animation du bouclier de l'Ange Gardien qui ne marchait pas quelques fois correctement avec Vanille (Par TommyXL)", + "\nQuelques réparations dans l'apparition aléatoire dans Airship pour l'hôte (Par TommyXL)", + "\nRéparé le fait que le Nécromancien laisse un corps après une réunion (Par TommyXL)", + "\nRéparé l'état de victoire incorrecte du Bourreau de Travail (Par TommyXL)", + "\nRéparé le maire appelant des réunions même lorsqu'elles sont hors d'usage (Par ryuk)", + "\nRéparé la liste EAC qui ne marchait pas lorsque la liste des ban est désactivé (Par ryuk)", + "\nRéparé le Kamikaze causant des joueurs à moitié morts (Par ryuk)", + "\nRéparé les messages non envoyés aux joueurs Vanille (Par Drakos)", + "\nRéparé des problèmes du Zombie (Par Drakos)", + "\nRéparé le Sac à Box étant Jugé (Par Drakos)", + "\nRéparé le bug où le temps mort d'exécution ne baisse pas lorsque l'on presse F1/F2/F3/F4 (Par NikoCat)", + "\nRéparé les paramètres du démarrage automatique immédiat (Par NikoCat)", + "\nRéparé l'appât s'auto-signaler (Par NikoCat)", + "\nRéparé le client Modded voyant l'icône du bouclier Médical lorsqu'il est mort (Par D1GQ)", + "\nMini ne peut être ni en duel, ni marqué, ni ensanglanté et ni découpé en tranches (Par Lezaiya)", + "\nRéparé les fautes de frappe, incohérences, et erreurs dans les descriptions, noms, etc. (Par Moe, TommyXL Drakos, WaterPanda, Sunnyboi, LezaiYa)", + "\n【Bugs Connus】", + "\n1. Les serveurs peuvent être instables car le protocole nécessite une fixation de la part d'Innersloth", + "\n2. Sosie, Agile et Imitateur sont instables, mais marchent", + "\n3. Des clients Modded ont quelques problèmes, donc il est recommandé d'avoir le mode seulement pour l'hôte", + "\n【Credits de la Traduction】", + "\n - Brésilien (Par Dx7405, Pietro)", + "\nNéerlandais (Par apemv, madmazel_)", + "\n - Français (Par FuroYT, KevOut, Klaomi, Sansationnelle, Space Monkey)", + "\n - Italien (Par alot, Baphojack, Mattix606)", + "\n - Japonais (Par Sunnyboi)", + "\n - Latino-Américain (Par CreepPower)", + "\n - Russe (Par TommyXL, Shoulder Devil, chill_ultimated, Nevermore59)", + "\n - Chinois Simplifié (Par CrewCyan, LezaiYa, NikoCat)", + "\n - Espagnol (Par Dawson, Sunnyboi, thewhiskas27, xxSShadow)", + "\n - Chinois Traditionel (Par FlyFlyTurtle, Hinharrrrr, netherdragontw, Pomelo_)", + "\n Découvre toutes les personnes qui ont traduit sur notre Site Internet\n", + "\n\n★ Bienvenue dans Town of Host: Enhanced v2.0.0 ★" ], "Date": "2024-07-21T12:50:00Z" - }, - { - "Number": "100007", - "Title": "Town of Host: Enhanced v2.1.0", - "Subtitle": "Finally, we're here!", - "Short": "TOH: Enhanced v2.1.0", - "Body": [ - "【Base】", - "\n - Base on TOH: Enhanced v2.0.0", - "\n\r【New Roles/Addons】(5 roles, 6 Add-ons)", - "\n - Yin Yanger (Impostor Killing, idea & coded: Drakos)", - "\n - Possessor (Imposter Ghost Role, idea & coded: D1GQ)", - "\n - Troller (Neutral Chaos, idea: dx7405, coded: TommyXL)", - "\n - Ventguard (Crewmate Support, ported: EHR, coded by: TommyXL)", - "\n - Evader (Addon Helpful, idea: Lime, coded: TommyXL)", - "\n - Rebirth (Addon Helpful, idea & coded: Drakos)", - "\n - Sloth (Harmful Addon, idea & coded: Pyro)", - "\n - Eavesdropper (Addon Helpful, idea by: Crosspost Del Slay, coded: Moe)", - "\n - Spurt (Addon Helpful, idea by: .thediamondstar, coded: Drakos)", - "\n - Prohibited (Addon Harmful, idea by: Crosspost Del Slay, coded: TommyXL)", - "\n - New neutral Team (Faction): Neutral Apocalypse (idea & coded: Marg)", - "\n --- Min/max Neutral Apocalypse can be set", - "\n --- New role: Baker", - "\n --- Berserker and PlagueBearer now moved to Neutral Apocalypse", - "\n --- Soul Collector reworked", - "\n\r【New Settings/Features】", - "\n - Added vent disabling for vanilla (ported from MoreGamemodes by TommyXL & NikoCat)", - "\n --- When a player does not have access to vents, they will never be able to use it", - "\n - More fixes for AntiBlackOut (By TommyXL & Drakos)", - "\n --- Note: This will not completely fix black screen issues, but the more players there are in the game, the less chance of black screen occurrences", - "\n --- To do this, we use revives and base role changes during exile so that dead players will be alive for a couple of seconds but will become dead again", - "\n - Added support role basis changer mid-game (By TommyXL & Drakos)", - "\n --- CopyCat now supports role basis changes", - "\n --- Executioner and Lawyer also change role basis after their target dies", - "\n - TextBoxPatch (Ported: EHR, coded: TommyXL)", - "\n --- Allows you to write any characters into the chat", - "\n - improved Region Menu (coded: D1GQ)", - "\n - Added custom label ID for modded (Ported: EHR, coded: TommyXL)", - "\n - Jester: «Can't Move In Vents» (Setting, coded: TommyXL)", - "\n - Random spawn: Active On Round One (Setting, coded: TommyXL)", - "\n - Added warning message about enabling setting «No Game End»", - "\n --- Warns only the host when he presses the start button", - "\n - Disable Shapeshift menu for some Reject Shapeshift roles (By: Drakos)", - "\n --- For Pitfall, Bomber, Undertaker", - "\n --- It may be used for some more roles", - "\n - Return Ability Votes (By: Drakos)", - "\n --- For Cleanser, Eraser, Fortune teller, Keeper, Oracle, Godfather", - "\n --- First Vote will cancel (Vote Skip) or use the ability; second is regular vote", - "\n - Added «/vote» command (By: Drakos)", - "\n --- Can be disabled in the settings", - "\n - Death reason display improved (ported from EHR).", - "\n - Added role info in setting menu (By: Drakos)", - "\n - Added search bar in settings (By: Drakos)", - "\n - Addon Base (Port From EHR) (By: Drakos)", - "\n --- The settings are now sorted alphabetically", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Jester: Reveal Upon Eject (Setting, by: TheDiamondStar)", - "\n - Executioner: Reveal Target Upon Ejection (Setting, by: TheDiamondStar)", - "\n - Judge: Max trials per game (Setting, by: hinhinarrrrrr)", - "\n - Improved menu for role description in settings", - "\n - Setting: Apocalypse can see each other's Add-ons", - "\n - Settings: «Halloween Decorations» and «Birthday Decoration» (only for modded)", - "\n - Modded players now will see changes in TOHE settings", - "\n - Added custom image «imer» for Mercenary, Bounty Hunter, and Penguin: Thanks @that_one_missing_pixel (Pixel)", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Changed warning message about the API (By: Drakos)", - "\n\r【Bug Fixes/Changes】", - "\n - Phantom Desync: Phantom now plays the invisibility animation instead of teleporting to a random vent for desync roles.", - "\n - Fixed issues with Veteran killing Taskinator, Killing Machine calling meetings, and the Jailed message not showing during the game.", - "\n - Resolved issues with stuck FFA meetings and Fortune Teller showing roles during FFA.", - "\n - Fixed speed bug when Bandit steals the Statue.", - "\n - Resolved Haunt Menu showing «NotAssigned» in Hide & Seek mode.", - "\n - Corrected issues with Doomsayer not using Impostor Vision and various bugs with Psychic.", - "\n - Fixed Taskinator triggering Schrodinger's Cat ability.", - "\n - Corrected Innocent win conditions with Impostor when the setting is enabled.", - "\n - Fixed player spawn issues at the start and after meetings.", - "\n - Resolved full role and add-on display when a player is exiled.", - "\n - Fixed Blackmail not working for non-host modded players.", - "\n - Resolved issues where the Deceiver could kill Serial Killer and where the Deceiver could kill dead players.", - "\n - Corrected several bugs related to Stalker, Enigma, and Madmate Impostor Vision.", - "\n - Fixed issues with Medium messages showing after Medium is dead.", - "\n - Resolved bug where Hangman could kill Nice Mini.", - "\n - Corrected Huntsman minimum kill cooldown.", - "\n - Fixed Bloodmoon not working for modded clients and corrected missing strings for Blackmailer.", - "\n - Fixed issues where the Overseer would show Med Scanner after a meeting.", - "\n - Inhibitor and Saboteur now use sabotage sounds in the intro.", - "\n - Resolved issues where Aware did not work after an Overseer check and Merchant could assign converted add-ons.", - "\n - Fixed bugs with Hater being unable to kill, Crewpostor killing Solsticer, and Impostor Vision not working for Doppelganger.", - "\n - Resolved modded client issues with calling RpcSetName at the end of the game.", - "\n - Fixed win-condition conflicts between terrorists and workaholics.", - "\n - Corrected Necroview interaction with Admired and Madmate roles.", - "\n - Resolved bugs with Judge for modded clients.", - "\n - Gangster and Admirer can no longer get the Egoist role.", - "\n - Fixed bugs with Minus and Plus buttons in settings, ensuring they are always active.", - "\n - Intro Scene optimizations for smoother game start.", - "\n - Fixed numerous typos across roles and settings.", - "\n - Jester can no longer receive the Susceptible role.", - "\n - Added notify message about the game end when RpcEndGame is not received by specific clients.", - "\n - Fixed Baker not showing roles to non-host modded players", - "\n - Fixed mass kicking from lobbies against non-host modded players", - "\n【Translator Credits】", - "\n - Brazilian (By Dx7405, Pietro)", - "\n - Dutch (By apemv, madmazel_)", - "\n - French (By FuroYT, KevOut, Klaomi, Sansationnelle, Space Monkey)", - "\n - Italian (By alot, Baphojack, Mattix606)", - "\n - Japanese (By Sunnyboi)", - "\n - Latin American (By CreepPower)", - "\n - Russian (By TommyXL, Shoulder Devil, chill_ultimated, Nevermore59)", - "\n - Simplified Chinese (By CrewCyan, LezaiYa, NikoCat)", - "\n - Spanish (By Dawson, Sunnyboi, thewhiskas27, xxSShadow)", - "\n - Traditional Chinese (By FlyFlyTurtle, Hinharrrrr, netherdragontw, Pomelo_)", - "\n Check out all of our translators on our website\r\n", - "\n\n★ Welcome to Town of Host: Enhanced v2.1.0 ★" - ], - "Date": "2024-11-3T12:50:00Z" } ] } diff --git a/Resources/Announcements/modNews-it_IT.json b/Resources/Announcements/modNews-it_IT.json index 6bb0edae5..49dfb2b84 100644 --- a/Resources/Announcements/modNews-it_IT.json +++ b/Resources/Announcements/modNews-it_IT.json @@ -50,7 +50,7 @@ "\n - Ora i ruoli Base e Amnesico verranno sempre mostrati nell'interfaccia utente dell'indovino (di: TommyXL)", "\n\n【Correzioni di Bug】", "\n - Risolto l'Aggiornamento della Mod (da: Pietro e NikoCat223)", - "\n - Corretto il testo di avanzamento e il contrassegno del bersaglio per il Pirata (Da: ryuk)", + "\n - Corretto il testo di avanzamento e il marchio del bersaglio per il Pirata (Da: ryuk)", "\n - Rimosso Esausto dalla lista dei modificatori attivi (Da: ryuk)", "\n - Boia Mutato ignora il Veterano allarmato (Da: ryuk)", "\n - Bug risolto quando «FixedUpdate» per i ruoli funzionanti nella lobby (Da: TommyXL)", @@ -175,195 +175,54 @@ "\n - Masochista rinominato in Sacco da Boxe (Da WaterPanda)", "\n - Assetato di sangue rinominato in Sanguinario (Da WaterPanda)", "\n - Schizofrenico rinominato in Paranoia (Da WaterPanda)", - "\n - Cambiata la logica per la disconnessione dal gioco se l'API si blocca (Da TommyXL)", - "\n - Imposta 300 di ricarica per Nemesi se non possono usare il pulsante uccidi (Da TommyXL)", - "\n - Modificato messaggio di avvertimento sulla connessione di errore Api (Da Drakos)", "\n\n【Correzioni di Bug】", - "\n - Many roles will no longer be able to receive some add-ons that were incompatible (By TommyXL, ryuk, WaterPanda)", - "\n - Fixed Bounty Hunter resetting incorrect targets (By TommyXL)", - "\n - Fixed null error post-meeting for Vulture and Seeker and error after votes in Airship (By TommyXL)", - "\n - Fixed custom buttons brightness issues (By TommyXL)", - "\n - Fixed roles without vent ability getting stuck after trying to vent (By TommyXL)", - "\n - Fixed vent icon issues for roles based on Engineer (By TommyXL)", - "\n - Fixed black screens during role assign (By TommyXL)", - "\n - Fixed Scientist assign for desync role (By TommyXL)", - "\n - Fixed bug when 3 settings for Judge was not used (By TommyXL)", - "\n - Fixed buttons are active when the player was guessed (By TommyXL)", - "\n - Some fixes in Guesser UI (By TommyXL)", - "\n - Fixed Double Meeting Ending (By TommyXL)", - "\n - Fixed Guardian Angel Shield Animation sometimes didn't work correctly with Vanilla (By TommyXL)", - "\n - Some fix in random spawn in Airship for the host (By TommyXL)", - "\n - Fixed Necromancer leaving a dead body after the meeting (By TommyXL)", - "\n - Fixed Workaholic incorrect win state (By TommyXL)", - "\n - Fixed Mayor calling meetings even when out of use (By ryuk)", - "\n - Fixed EAC list not working when ban list is off (By ryuk)", - "\n - Fixed Kamikaze causing half-dead players (By ryuk)", - "\n - Fixed Messages not sent to vanilla players (By Drakos)", - "\n - Fixed Zombie Issues (By Drakos)", - "\n - Fixed Punching bag being judged (By Drakos)", - "\n - Fixed bug when kill cooldown not going when press F1/F2/F3/F4 (By NikoCat)", - "\n - Fixed Immediate autostart settings (By NikoCat)", - "\n - Fixed Bait self-reporting (By NikoCat)", - "\n - Fixed Modded client seeing the Medic shield icon when Medic is dead (By D1GQ)", - "\n - Mini non può essere duellato, contrassegnato, insanguinato e affettato (Da Lezaiya)", - "\n - Fixed typos, inconsistencies, and mistakes in descriptions, names, etc. (By Moe, TommyXL, Drakos, WaterPanda, Sunnyboi, LezaiYa)", - "\n - Fixed bug when after guessing, Judge, etc. the meeting status was not checked (By TommyXL)", - "\n - Fixed bug when Pelican ended the game when eaten players returned (By TommyXL)", - "\n - Fixed Avenger when they try to kill Necromancer (By TommyXL)", - "\n - Fixed Bodyguard/Crusader when they killed Bodyguard/Crusader, Taskinator and Veteran (By TommyXL)", - "\n - Fixed «Quizmaster.None» (By TommyXL)", - "\n - Fixed missed string «*MayorHideVote» for Vindicator (By TommyXL)", - "\n - Fixed bug when Madmate assign Neutrals (Does not apply to Admirer - By TommyXL)", - "\n - Fixed bug when Camouflage did not disappear after Camouflager was erased (By TommyXL)", - "\n - Probably fixed the bug when Kamikaze killed players during exile (By TommyXL)", - "\n - Probably fixed bug when in-game result displayed randomized nicknames (By TommyXL)", - "\n - Fixed bug when Auto Start always stes ans saved 0 kill cooldown (By TommyXL)", - "\n - Other small fixes that occurred in certain cases (By TommyXL)", - "\n - Swift can no longer get Tricky and vice versa (By TommyXL)", - "\n - Remove unnecessary parenthesis for Lighter (By TommyXL)", - "\n - Fixed bug when Fortune Teller shows «INVALID:NotAssigned» (By Drakos)", - "\n - Fixed broken Auto Start", - "\n - Corretto bug (si spera) quando l'host ha cambiato il suo soprannome quando è stato ucciso da Doppelganger (Da TommyXL)", - "\n - Fixed bug when F1 shows role settings (By TommyXL)", - "\n - Fixed bug when Veteran kills Taskinator (By TommyXL)", - "\n - Fixed (hopefully) the last color question for Quizmaster (By TommyXL)", - "\n - Fixed bug when Killing Machine can call a meeting (By TommyXL)", - "\n - Fixed bug when Jailed message not shown (By TommyXL)", - "\n【Known bugs】", - "\n - 1. Servers may be unstable as the protocol requires fixing on Innersloth's side", + "\n - Molti ruoli non saranno più in grado di ricevere alcuni modificatori che erano incompatibili (Da TommyXL, ryuk, WaterPanda)", + "\n - Risolto il cacciatore di taglie che reimpostava i bersagli errati (Da TommyXL)", + "\n - Risolto l'errore nullo post-riunione per Avvoltoio e Cercatore e l'errore dopo i voti in Airship (Da TommyXL)", + "\n - Sistemata la luminosità dei pulsanti personalizzati (Da TommyXL)", + "\n - Sistemati i ruoli senza abilità di usare i condotti che rimanevano bloccati nei condotti dopo aver provato ad usarli (Da TommyXL)", + "\n - Sistemata l'icona Condotto per i ruoli con la base dell'Ingegnere (Da TommyXL)", + "\n - Sistemato schermo nero durante l'assegnazione dei ruoli (Da TommyXL)", + "\n - Corretta l'assegnazione dello scienziato per il ruolo di desincronizzazione (Da TommyXL)", + "\n - Risolto bug quando non venivano utilizzate 3 impostazioni per il Giudice (Da TommyXL)", + "\n - Sistemati i pulsanti attivi quando il giocatore veniva indovinato (Da TommyXL)", + "\n - Alcune correzioni nell'interfaccia dell'Indovino (Da TommyXL)", + "\n - Risolta la fine doppia della riunione (Da TommyXL)", + "\n - Sistemata l'animazione dello scudo dell'Angelo Custode che a volte non funzionava correttamente in Vanilla (Da TommyXL)", + "\n - Alcune correzioni nella generazione casuale in Airship per l'host (Da TommyXL)", + "\n - Risolto il problema con il Necromante che lasciava un cadavere dopo la riunione (Da TommyXL)", + "\n - Risolto lo stato di vittoria errato dello Stacanovista (Da TommyXL)", + "\n - Risolto il problema con il Sindaco che convocava riunioni anche quando non aveva più usi (Da ryuk)", + "\n - Risolto l'elenco EAC che non funzionava quando l'elenco dei ban era disattivato (Da ryuk)", + "\n - Risolto Kamikaze che causava giocatori mezzi morti (Da ryuk)", + "\n - Risolti i messaggi non inviati ai giocatori Vanilla (Da Drakos)", + "\n - Corretti errori dello Zombi (Da Drakos)", + "\n - Sistemato il Sacco da Boxe che veniva giudicato (Da Drakos)", + "\n - Risolto un bug per cui la ricarica uccisione non funzionava quando si premeva F1/F2/F3/F4 (Da NikoCat)", + "\n - Risolte le impostazioni di auto inizio immediato (Da NikoCat)", + "\n - Risolta l'autosegnalazione dell'esca (Da NikoCat)", + "\n - Risolto errore con il client moddato che vedeva l'icona dello scudo del Medico quando il Medico era morto (Da D1GQ)", + "\n - Mini non può essere duellato, marcato, insanguinato e affettato (Da Lezaiya)", + "\n - Risolti errori di battitura, incoerenze ed errori nelle descrizioni, nei nomi, ecc. (Da Moe, TommyXL, Drakos, WaterPanda, Sunnyboi, LezaiYa)", + "\n【Bug noti】", + "\n - 1. I server potrebbero essere instabili poiché il protocollo richiede una correzione da parte di Innersloth", "\n - 2. Doppelganger, Rapido e Imitatore sono instabili, ma funzionano", - "\n - 3. Modded clients have some problems, so it is recommended to have the mod only on Host", - "\n【Translator Credits】", - "\n - Brazilian (By Dx7405, Pietro)", - "\n - Dutch (By apemv, madmazel_)", - "\n - French (By FuroYT, KevOut, Klaomi, Sansationnelle, Space Monkey)", - "\n - Italian (By alot, Baphojack, Mattix606)", - "\n - Japanese (By Sunnyboi)", - "\n - Latin American (By CreepPower)", - "\n - Russian (By TommyXL, Shoulder Devil, chill_ultimated, Nevermore59)", - "\n - Simplified Chinese (By CrewCyan, LezaiYa, NikoCat)", - "\n - Spanish (By Dawson, Sunnyboi, thewhiskas27, xxSShadow)", - "\n - Traditional Chinese (By FlyFlyTurtle, Hinharrrrr, netherdragontw, Pomelo_)", - "\n Check out all of our translators on our website\r\n", - "\n\n★ Welcome to Town of Host: Enhanced v2.0.0 ★" + "\n - 3. I Client Moddati hanno alcuni problemi, quindi si consiglia di far avere la mod solo al host", + "\n【Crediti dei Traduttori】", + "\n - Brasiliano (Da Dx7405, Pietro)", + "\n - Olandese (Da apemv, madmazel_)", + "\n - Francese (Da FuroYT, KevOut, Klaomi, Sansationnelle, Space Monkey)", + "\n - Italiano (Da alot, Baphojack, Mattix606)", + "\n - Giapponese (Da Sunnyboi)", + "\n - Latinoamericano (Da CreepPower)", + "\n - Russo (Da TommyXL, Shoulder Devil, chill_ultimated, Nevermore59)", + "\n - Cinese Semplificato (Da CrewCyan, LezaiYa, NikoCat)", + "\n - Spagnolo (Da Dawson, Sunnyboi, thewhiskas27, xxSShadow)", + "\n - Cinese Tradizionale (Da FlyFlyTurtle, Hinharrrrr, netherdragontw, Pomelo_)", + "\n Scopri tutti i nostri traduttori sul nostro sito web\n", + "\n\n★ Benvenuto a Town of Host: Enhanced v2.0.0 ★" ], "Date": "2024-07-21T12:50:00Z" - }, - { - "Number": "100007", - "Title": "Town of Host: Enhanced v2.1.0", - "Subtitle": "Finally, we're here!", - "Short": "TOH: Enhanced v2.1.0", - "Body": [ - "【Base】", - "\n - Base on TOH: Enhanced v2.0.0", - "\n\r【New Roles/Addons】(5 roles, 6 Add-ons)", - "\n - Yin Yanger (Impostor Killing, idea & coded: Drakos)", - "\n - Possessor (Imposter Ghost Role, idea & coded: D1GQ)", - "\n - Troller (Neutral Chaos, idea: dx7405, coded: TommyXL)", - "\n - Ventguard (Crewmate Support, ported: EHR, coded by: TommyXL)", - "\n - Evader (Addon Helpful, idea: Lime, coded: TommyXL)", - "\n - Rebirth (Addon Helpful, idea & coded: Drakos)", - "\n - Sloth (Harmful Addon, idea & coded: Pyro)", - "\n - Eavesdropper (Addon Helpful, idea by: Crosspost Del Slay, coded: Moe)", - "\n - Spurt (Addon Helpful, idea by: .thediamondstar, coded: Drakos)", - "\n - Prohibited (Addon Harmful, idea by: Crosspost Del Slay, coded: TommyXL)", - "\n - New neutral Team (Faction): Neutral Apocalypse (idea & coded: Marg)", - "\n --- Min/max Neutral Apocalypse can be set", - "\n --- New role: Baker", - "\n --- Berserker and PlagueBearer now moved to Neutral Apocalypse", - "\n --- Soul Collector reworked", - "\n\r【New Settings/Features】", - "\n - Added vent disabling for vanilla (ported from MoreGamemodes by TommyXL & NikoCat)", - "\n --- When a player does not have access to vents, they will never be able to use it", - "\n - More fixes for AntiBlackOut (By TommyXL & Drakos)", - "\n --- Note: This will not completely fix black screen issues, but the more players there are in the game, the less chance of black screen occurrences", - "\n --- To do this, we use revives and base role changes during exile so that dead players will be alive for a couple of seconds but will become dead again", - "\n - Added support role basis changer mid-game (By TommyXL & Drakos)", - "\n --- CopyCat now supports role basis changes", - "\n --- Executioner and Lawyer also change role basis after their target dies", - "\n - TextBoxPatch (Ported: EHR, coded: TommyXL)", - "\n --- Allows you to write any characters into the chat", - "\n - improved Region Menu (coded: D1GQ)", - "\n - Added custom label ID for modded (Ported: EHR, coded: TommyXL)", - "\n - Jester: «Can't Move In Vents» (Setting, coded: TommyXL)", - "\n - Random spawn: Active On Round One (Setting, coded: TommyXL)", - "\n - Aggiunto messaggio di avvertimento sull'attivazione dell'impostazione «Nessuna Fine del Gioco»", - "\n --- Warns only the host when he presses the start button", - "\n - Disable Shapeshift menu for some Reject Shapeshift roles (By: Drakos)", - "\n --- For Pitfall, Bomber, Undertaker", - "\n --- It may be used for some more roles", - "\n - Return Ability Votes (By: Drakos)", - "\n --- For Cleanser, Eraser, Fortune teller, Keeper, Oracle, Godfather", - "\n --- First Vote will cancel (Vote Skip) or use the ability; second is regular vote", - "\n - Added «/vote» command (By: Drakos)", - "\n --- Can be disabled in the settings", - "\n - Death reason display improved (ported from EHR).", - "\n - Added role info in setting menu (By: Drakos)", - "\n - Added search bar in settings (By: Drakos)", - "\n - Addon Base (Port From EHR) (By: Drakos)", - "\n --- The settings are now sorted alphabetically", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Jester: Reveal Upon Eject (Setting, by: TheDiamondStar)", - "\n - Executioner: Reveal Target Upon Ejection (Setting, by: TheDiamondStar)", - "\n - Judge: Max trials per game (Setting, by: hinhinarrrrrr)", - "\n - Improved menu for role description in settings", - "\n - Setting: Apocalypse can see each other's Add-ons", - "\n - Settings: «Halloween Decorations» and «Birthday Decoration» (only for modded)", - "\n - Modded players now will see changes in TOHE settings", - "\n - Added custom image «imer» for Mercenary, Bounty Hunter, and Penguin: Thanks @that_one_missing_pixel (Pixel)", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Changed warning message about the API (By: Drakos)", - "\n\r【Bug Fixes/Changes】", - "\n - Phantom Desync: Phantom now plays the invisibility animation instead of teleporting to a random vent for desync roles.", - "\n - Fixed issues with Veteran killing Taskinator, Killing Machine calling meetings, and the Jailed message not showing during the game.", - "\n - Resolved issues with stuck FFA meetings and Fortune Teller showing roles during FFA.", - "\n - Fixed speed bug when Bandit steals the Statue.", - "\n - Resolved Haunt Menu showing «NotAssigned» in Hide & Seek mode.", - "\n - Corretti i problemi con Catastrofista che non usano il campo visivo impostore e vari bug col Psichico.", - "\n - Fixed Taskinator triggering Schrodinger's Cat ability.", - "\n - Corrected Innocent win conditions with Impostor when the setting is enabled.", - "\n - Fixed player spawn issues at the start and after meetings.", - "\n - Resolved full role and add-on display when a player is exiled.", - "\n - Fixed Blackmail not working for non-host modded players.", - "\n - Resolved issues where the Deceiver could kill Serial Killer and where the Deceiver could kill dead players.", - "\n - Corretti diversi bug relativi a Stalker, Enigma e il Campo visivo Impostore del Follenauta.", - "\n - Fixed issues with Medium messages showing after Medium is dead.", - "\n - Resolved bug where Hangman could kill Nice Mini.", - "\n - Corrected Huntsman minimum kill cooldown.", - "\n - Fixed Bloodmoon not working for modded clients and corrected missing strings for Blackmailer.", - "\n - Fixed issues where the Overseer would show Med Scanner after a meeting.", - "\n - Inhibitor and Saboteur now use sabotage sounds in the intro.", - "\n - Resolved issues where Aware did not work after an Overseer check and Merchant could assign converted add-ons.", - "\n - Corretti bug con Hater non essere in grado di uccidere, Simulatore che uccide Impiegato, e Campo Visivo non funzionante per Doppelganger.", - "\n - Resolved modded client issues with calling RpcSetName at the end of the game.", - "\n - Fixed win-condition conflicts between terrorists and workaholics.", - "\n - Corrected Necroview interaction with Admired and Madmate roles.", - "\n - Resolved bugs with Judge for modded clients.", - "\n - Gangster and Admirer can no longer get the Egoist role.", - "\n - Fixed bugs with Minus and Plus buttons in settings, ensuring they are always active.", - "\n - Intro Scene optimizations for smoother game start.", - "\n - Fixed numerous typos across roles and settings.", - "\n - Jester can no longer receive the Susceptible role.", - "\n - Aggiunto messaggio di notifica sulla fine del gioco quando RpcEndGame non è ricevuto da client specifici.", - "\n - Fixed Baker not showing roles to non-host modded players", - "\n - Fixed mass kicking from lobbies against non-host modded players", - "\n【Translator Credits】", - "\n - Brazilian (By Dx7405, Pietro)", - "\n - Dutch (By apemv, madmazel_)", - "\n - French (By FuroYT, KevOut, Klaomi, Sansationnelle, Space Monkey)", - "\n - Italian (By alot, Baphojack, Mattix606)", - "\n - Japanese (By Sunnyboi)", - "\n - Latin American (By CreepPower)", - "\n - Russian (By TommyXL, Shoulder Devil, chill_ultimated, Nevermore59)", - "\n - Simplified Chinese (By CrewCyan, LezaiYa, NikoCat)", - "\n - Spanish (By Dawson, Sunnyboi, thewhiskas27, xxSShadow)", - "\n - Traditional Chinese (By FlyFlyTurtle, Hinharrrrr, netherdragontw, Pomelo_)", - "\n Check out all of our translators on our website\r\n", - "\n\n★ Welcome to Town of Host: Enhanced v2.1.0 ★" - ], - "Date": "2024-11-3T12:50:00Z" } ] } diff --git a/Resources/Announcements/modNews-ja_JP.json b/Resources/Announcements/modNews-ja_JP.json index 96923dc90..f7de25f88 100644 --- a/Resources/Announcements/modNews-ja_JP.json +++ b/Resources/Announcements/modNews-ja_JP.json @@ -175,195 +175,54 @@ "\n- マゾヒストをパンチングバッグに改名(製作者:WaterPanda)", "\n- ブラッドラストを血に飢えたに改名 (製作者:WaterPanda)", "\n- シゾフレニックをパラノイアに改名(製作者:WaterPanda)", - "\n - Changed the logic for disconnecting from the game if the API crashes (By TommyXL)", - "\n - Set 300 CD for Nemesis if they cannot use the kill button (By TommyXL)", - "\n - Changed warning message about Api Error Connection (By Drakos)", "\n\n【バグ修正】", - "\n - Many roles will no longer be able to receive some add-ons that were incompatible (By TommyXL, ryuk, WaterPanda)", - "\n - Fixed Bounty Hunter resetting incorrect targets (By TommyXL)", - "\n - Fixed null error post-meeting for Vulture and Seeker and error after votes in Airship (By TommyXL)", - "\n - Fixed custom buttons brightness issues (By TommyXL)", - "\n - Fixed roles without vent ability getting stuck after trying to vent (By TommyXL)", - "\n - Fixed vent icon issues for roles based on Engineer (By TommyXL)", - "\n - Fixed black screens during role assign (By TommyXL)", - "\n - Fixed Scientist assign for desync role (By TommyXL)", - "\n - Fixed bug when 3 settings for Judge was not used (By TommyXL)", - "\n - Fixed buttons are active when the player was guessed (By TommyXL)", - "\n - Some fixes in Guesser UI (By TommyXL)", - "\n - Fixed Double Meeting Ending (By TommyXL)", - "\n - Fixed Guardian Angel Shield Animation sometimes didn't work correctly with Vanilla (By TommyXL)", - "\n - Some fix in random spawn in Airship for the host (By TommyXL)", - "\n - Fixed Necromancer leaving a dead body after the meeting (By TommyXL)", - "\n - Fixed Workaholic incorrect win state (By TommyXL)", - "\n - Fixed Mayor calling meetings even when out of use (By ryuk)", - "\n - Fixed EAC list not working when ban list is off (By ryuk)", - "\n - Fixed Kamikaze causing half-dead players (By ryuk)", - "\n - Fixed Messages not sent to vanilla players (By Drakos)", - "\n - Fixed Zombie Issues (By Drakos)", - "\n - Fixed Punching bag being judged (By Drakos)", - "\n - Fixed bug when kill cooldown not going when press F1/F2/F3/F4 (By NikoCat)", - "\n - Fixed Immediate autostart settings (By NikoCat)", - "\n - Fixed Bait self-reporting (By NikoCat)", - "\n - Fixed Modded client seeing the Medic shield icon when Medic is dead (By D1GQ)", - "\n - Mini can not be duelled, marked, blooded, and sliced (By Lezaiya)", - "\n - Fixed typos, inconsistencies, and mistakes in descriptions, names, etc. (By Moe, TommyXL, Drakos, WaterPanda, Sunnyboi, LezaiYa)", - "\n - Fixed bug when after guessing, Judge, etc. the meeting status was not checked (By TommyXL)", - "\n - Fixed bug when Pelican ended the game when eaten players returned (By TommyXL)", - "\n - Fixed Avenger when they try to kill Necromancer (By TommyXL)", - "\n - Fixed Bodyguard/Crusader when they killed Bodyguard/Crusader, Taskinator and Veteran (By TommyXL)", - "\n - Fixed «Quizmaster.None» (By TommyXL)", - "\n - Fixed missed string «*MayorHideVote» for Vindicator (By TommyXL)", - "\n - Fixed bug when Madmate assign Neutrals (Does not apply to Admirer - By TommyXL)", - "\n - Fixed bug when Camouflage did not disappear after Camouflager was erased (By TommyXL)", - "\n - Probably fixed the bug when Kamikaze killed players during exile (By TommyXL)", - "\n - Probably fixed bug when in-game result displayed randomized nicknames (By TommyXL)", - "\n - Fixed bug when Auto Start always stes ans saved 0 kill cooldown (By TommyXL)", - "\n - Other small fixes that occurred in certain cases (By TommyXL)", - "\n - Swift can no longer get Tricky and vice versa (By TommyXL)", - "\n - Remove unnecessary parenthesis for Lighter (By TommyXL)", - "\n - Fixed bug when Fortune Teller shows «INVALID:NotAssigned» (By Drakos)", - "\n - Fixed broken Auto Start", - "\n - Fixed bug (hopefully) when the host changed his nickname to his own when he was killed by Doppelganger (By TommyXL)", - "\n - Fixed bug when F1 shows role settings (By TommyXL)", - "\n - Fixed bug when Veteran kills Taskinator (By TommyXL)", - "\n - Fixed (hopefully) the last color question for Quizmaster (By TommyXL)", - "\n - Fixed bug when Killing Machine can call a meeting (By TommyXL)", - "\n - Fixed bug when Jailed message not shown (By TommyXL)", - "\n【Known bugs】", - "\n - 1. Servers may be unstable as the protocol requires fixing on Innersloth's side", - "\n - 2. Doppelganger, Swift and Imitator are unstable, but work", - "\n - 3. Modded clients have some problems, so it is recommended to have the mod only on Host", - "\n【Translator Credits】", - "\n - Brazilian (By Dx7405, Pietro)", - "\n - Dutch (By apemv, madmazel_)", - "\n - French (By FuroYT, KevOut, Klaomi, Sansationnelle, Space Monkey)", - "\n - Italian (By alot, Baphojack, Mattix606)", - "\n - Japanese (By Sunnyboi)", - "\n - Latin American (By CreepPower)", - "\n - Russian (By TommyXL, Shoulder Devil, chill_ultimated, Nevermore59)", - "\n - Simplified Chinese (By CrewCyan, LezaiYa, NikoCat)", - "\n - Spanish (By Dawson, Sunnyboi, thewhiskas27, xxSShadow)", - "\n - Traditional Chinese (By FlyFlyTurtle, Hinharrrrr, netherdragontw, Pomelo_)", - "\n Check out all of our translators on our website\r\n", - "\n\n★ Welcome to Town of Host: Enhanced v2.0.0 ★" - ], - "Date": "2024-07-21T12:50:00Z" - }, - { - "Number": "100007", - "Title": "Town of Host: Enhanced v2.1.0", - "Subtitle": "Finally, we're here!", - "Short": "TOH: Enhanced v2.1.0", - "Body": [ - "【Base】", - "\n - Base on TOH: Enhanced v2.0.0", - "\n\r【New Roles/Addons】(5 roles, 6 Add-ons)", - "\n - Yin Yanger (Impostor Killing, idea & coded: Drakos)", - "\n - Possessor (Imposter Ghost Role, idea & coded: D1GQ)", - "\n - Troller (Neutral Chaos, idea: dx7405, coded: TommyXL)", - "\n - Ventguard (Crewmate Support, ported: EHR, coded by: TommyXL)", - "\n - Evader (Addon Helpful, idea: Lime, coded: TommyXL)", - "\n - Rebirth (Addon Helpful, idea & coded: Drakos)", - "\n - Sloth (Harmful Addon, idea & coded: Pyro)", - "\n - Eavesdropper (Addon Helpful, idea by: Crosspost Del Slay, coded: Moe)", - "\n - Spurt (Addon Helpful, idea by: .thediamondstar, coded: Drakos)", - "\n - Prohibited (Addon Harmful, idea by: Crosspost Del Slay, coded: TommyXL)", - "\n - New neutral Team (Faction): Neutral Apocalypse (idea & coded: Marg)", - "\n --- Min/max Neutral Apocalypse can be set", - "\n --- New role: Baker", - "\n --- Berserker and PlagueBearer now moved to Neutral Apocalypse", - "\n --- Soul Collector reworked", - "\n\r【New Settings/Features】", - "\n - Added vent disabling for vanilla (ported from MoreGamemodes by TommyXL & NikoCat)", - "\n --- When a player does not have access to vents, they will never be able to use it", - "\n - More fixes for AntiBlackOut (By TommyXL & Drakos)", - "\n --- Note: This will not completely fix black screen issues, but the more players there are in the game, the less chance of black screen occurrences", - "\n --- To do this, we use revives and base role changes during exile so that dead players will be alive for a couple of seconds but will become dead again", - "\n - Added support role basis changer mid-game (By TommyXL & Drakos)", - "\n --- CopyCat now supports role basis changes", - "\n --- Executioner and Lawyer also change role basis after their target dies", - "\n - TextBoxPatch (Ported: EHR, coded: TommyXL)", - "\n --- Allows you to write any characters into the chat", - "\n - improved Region Menu (coded: D1GQ)", - "\n - Added custom label ID for modded (Ported: EHR, coded: TommyXL)", - "\n - Jester: «Can't Move In Vents» (Setting, coded: TommyXL)", - "\n - Random spawn: Active On Round One (Setting, coded: TommyXL)", - "\n - Added warning message about enabling setting «No Game End»", - "\n --- Warns only the host when he presses the start button", - "\n - Disable Shapeshift menu for some Reject Shapeshift roles (By: Drakos)", - "\n --- For Pitfall, Bomber, Undertaker", - "\n --- It may be used for some more roles", - "\n - Return Ability Votes (By: Drakos)", - "\n --- For Cleanser, Eraser, Fortune teller, Keeper, Oracle, Godfather", - "\n --- First Vote will cancel (Vote Skip) or use the ability; second is regular vote", - "\n - Added «/vote» command (By: Drakos)", - "\n --- Can be disabled in the settings", - "\n - Death reason display improved (ported from EHR).", - "\n - Added role info in setting menu (By: Drakos)", - "\n - Added search bar in settings (By: Drakos)", - "\n - Addon Base (Port From EHR) (By: Drakos)", - "\n --- The settings are now sorted alphabetically", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Jester: Reveal Upon Eject (Setting, by: TheDiamondStar)", - "\n - Executioner: Reveal Target Upon Ejection (Setting, by: TheDiamondStar)", - "\n - Judge: Max trials per game (Setting, by: hinhinarrrrrr)", - "\n - Improved menu for role description in settings", - "\n - Setting: Apocalypse can see each other's Add-ons", - "\n - Settings: «Halloween Decorations» and «Birthday Decoration» (only for modded)", - "\n - Modded players now will see changes in TOHE settings", - "\n - Added custom image «imer» for Mercenary, Bounty Hunter, and Penguin: Thanks @that_one_missing_pixel (Pixel)", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Changed warning message about the API (By: Drakos)", - "\n\r【Bug Fixes/Changes】", - "\n - Phantom Desync: Phantom now plays the invisibility animation instead of teleporting to a random vent for desync roles.", - "\n - Fixed issues with Veteran killing Taskinator, Killing Machine calling meetings, and the Jailed message not showing during the game.", - "\n - Resolved issues with stuck FFA meetings and Fortune Teller showing roles during FFA.", - "\n - Fixed speed bug when Bandit steals the Statue.", - "\n - Resolved Haunt Menu showing «NotAssigned» in Hide & Seek mode.", - "\n - Corrected issues with Doomsayer not using Impostor Vision and various bugs with Psychic.", - "\n - Fixed Taskinator triggering Schrodinger's Cat ability.", - "\n - Corrected Innocent win conditions with Impostor when the setting is enabled.", - "\n - Fixed player spawn issues at the start and after meetings.", - "\n - Resolved full role and add-on display when a player is exiled.", - "\n - Fixed Blackmail not working for non-host modded players.", - "\n - Resolved issues where the Deceiver could kill Serial Killer and where the Deceiver could kill dead players.", - "\n - Corrected several bugs related to Stalker, Enigma, and Madmate Impostor Vision.", - "\n - Fixed issues with Medium messages showing after Medium is dead.", - "\n - Resolved bug where Hangman could kill Nice Mini.", - "\n - Corrected Huntsman minimum kill cooldown.", - "\n - Fixed Bloodmoon not working for modded clients and corrected missing strings for Blackmailer.", - "\n - Fixed issues where the Overseer would show Med Scanner after a meeting.", - "\n - Inhibitor and Saboteur now use sabotage sounds in the intro.", - "\n - Resolved issues where Aware did not work after an Overseer check and Merchant could assign converted add-ons.", - "\n - Fixed bugs with Hater being unable to kill, Crewpostor killing Solsticer, and Impostor Vision not working for Doppelganger.", - "\n - Resolved modded client issues with calling RpcSetName at the end of the game.", - "\n - Fixed win-condition conflicts between terrorists and workaholics.", - "\n - Corrected Necroview interaction with Admired and Madmate roles.", - "\n - Resolved bugs with Judge for modded clients.", - "\n - Gangster and Admirer can no longer get the Egoist role.", - "\n - Fixed bugs with Minus and Plus buttons in settings, ensuring they are always active.", - "\n - Intro Scene optimizations for smoother game start.", - "\n - Fixed numerous typos across roles and settings.", - "\n - Jester can no longer receive the Susceptible role.", - "\n - Added notify message about the game end when RpcEndGame is not received by specific clients.", - "\n - Fixed Baker not showing roles to non-host modded players", - "\n - Fixed mass kicking from lobbies against non-host modded players", - "\n【Translator Credits】", - "\n - Brazilian (By Dx7405, Pietro)", - "\n - Dutch (By apemv, madmazel_)", - "\n - French (By FuroYT, KevOut, Klaomi, Sansationnelle, Space Monkey)", - "\n - Italian (By alot, Baphojack, Mattix606)", - "\n - Japanese (By Sunnyboi)", - "\n - Latin American (By CreepPower)", + "\n- 多くの役割が互換性のないアドオンを受け取ることができなくなります(製作者:TommyXL、ryuk、WaterPanda)", + "\n- バウンティハンターのターゲットリセットの修正 (製作者:TommyXL)", + "\n- ミーティング後のnullエラー(ハゲタカと探求者)とエアシップでの投票後のエラーの修正 (製作者:TommyXL)", + "\n- カスタムボタンの明るさ問題の修正(製作者:TommyXL)", + "\n- ベント能力がない役割がベントしようとしてスタックするバグの修正(製作者:TommyXL)", + "\n- エンジニアに基づく役割のベントアイコン問題の修正(製作者:TommyXL)", + "\n- 役割割り当て中のブラックスクリーンの修正(製作者:TommyXL)", + "\n- デシンク役割の科学者割り当ての修正(製作者:TommyXL)", + "\n- ジャッジ用の3つの設定が使用されていなかったバグの修正(製作者:TommyXL)", + "\n- 推測されたプレイヤーのボタンがアクティブなままの修正(製作者:TommyXL)", + "\n- Guesser UIのいくつかの修正(製作者:TommyXL)", + "\n- ダブルミーティング終了の修正(製作者:TommyXL)", + "\n- ガーディアンエンジェルのシールドアニメーションがバニラで正しく動作しない場合の修正(製作者:TommyXL)", + "\n- ホストのエアシップでのランダムスポーンの修正(製作者:TommyXL)", + "\n- ネクロマンサーがミーティング後に死体を残すバグの修正(製作者:TommyXL)", + "\n- ワーカホリックの誤った勝利状態の修正 (製作者:TommyXL)", + "\n- 市長が使用回数切れの時に会議を招集するバグの修正(製作者:ryuk)", + "\n- 禁止リストがオフの時にEACリストが機能しないバグの修正(製作者:ryuk)", + "\n- ロケットミサイルが半死プレイヤーを引き起こすバグの修正 (製作者:ryuk)", + "\n- バニラプレイヤーにメッセージが送信されないバグの修正(製作者:Drakos)", + "\n- ゾンビの問題の修正(製作者:Drakos)", + "\n- パンチングバッグが判定されるバグの修正(製作者:Drakos)", + "\n- F1/F2/F3/F4を押した際にキルクールダウンが進行しないバグの修正(製作者:NikoCat)", + "\n- 即時自動開始設定の修正(製作者:NikoCat)", + "\n- おとりの自己報告の修正(製作者:NikoCat)", + "\n- モッドクライアントがメディックのシールドアイコンを見るバグの修正(製作者:D1GQ)", + "\n- ミニはデュエル、マーキング、ブラッド、スライスできません(製作者:Lezaiya)", + "\n- 説明、名前などのタイプミス、一貫性、誤りの修正(製作者:Moe、TommyXL、Drakos、WaterPanda、Sunnyboi、LezaiYa)", + "\n【既知のバグ】", + "\n- 1. プロトコルの修正が必要なため、サーバーが不安定になる可能性があります(Innersloth側)", + "\n- 2. ドッペルゲンガー、速い、模倣者、は不安定ですが、動作します", + "\n- 3. モッドクライアントにはいくつかの問題があるため、モッドはホストのみにすることを推奨します", + "\n【翻訳者のクレジット】", + "\n- ブラジル (製作者:Dx7405、Pietro)", + "\n- オランダ語 (製作者:apemv、madmazel_)", + "\n- フランス語 (製作者:FuroYT、KevOut、Klaomi、Sansationnelle、Space Monkey)", + "\n- イタリア語 (製作者:alot、Baphojack、Mattix606)", + "\n- 日本語 (製作者:Sunnyboi)", + "\n- ラテンアメリカ (製作者:CreepPower)", "\n- ロシア語 (製作者:TommyXL、Shoulder Devil、chill_ultimated、Nevermore59)", "\n- 簡体字中国語 (製作者:CrewCyan、LezaiYa、NikoCat)", "\n- スペイン語 (製作者:Dawson、Sunnyboi、thewhiskas27、xxSShadow)", "\n- 繁体字中国語 (製作者:FlyFlyTurtle、Hinharrrrr、netherdragontw、Pomelo_)", "\n当社のウェブサイトで、すべての翻訳者をご覧ください\n", - "\n\n★ Town of Host: Enhanced v2.1.0 へようこそ ★" + "\n\n★ Town of Host: Enhanced v2.0.0 へようこそ ★" ], - "Date": "2024-11-3T12:50:00Z" + "Date": "2024-07-21T12:50:00Z" } ] } diff --git a/Resources/Announcements/modNews-ko_KR.json b/Resources/Announcements/modNews-ko_KR.json index a88211c41..8207ac47c 100644 --- a/Resources/Announcements/modNews-ko_KR.json +++ b/Resources/Announcements/modNews-ko_KR.json @@ -175,9 +175,6 @@ "\n - Masochist renamed to Punching Bag (By WaterPanda)", "\n - Bloodlust renamed to Bloodthirst (By WaterPanda)", "\n - Schizophrenic renamed to Paranoia (By WaterPanda)", - "\n - Changed the logic for disconnecting from the game if the API crashes (By TommyXL)", - "\n - Set 300 CD for Nemesis if they cannot use the kill button (By TommyXL)", - "\n - Changed warning message about Api Error Connection (By Drakos)", "\n\r【Bug Fixes】", "\n - Many roles will no longer be able to receive some add-ons that were incompatible (By TommyXL, ryuk, WaterPanda)", "\n - Fixed Bounty Hunter resetting incorrect targets (By TommyXL)", @@ -207,28 +204,6 @@ "\n - Fixed Modded client seeing the Medic shield icon when Medic is dead (By D1GQ)", "\n - Mini can not be duelled, marked, blooded, and sliced (By Lezaiya)", "\n - Fixed typos, inconsistencies, and mistakes in descriptions, names, etc. (By Moe, TommyXL, Drakos, WaterPanda, Sunnyboi, LezaiYa)", - "\n - Fixed bug when after guessing, Judge, etc. the meeting status was not checked (By TommyXL)", - "\n - Fixed bug when Pelican ended the game when eaten players returned (By TommyXL)", - "\n - Fixed Avenger when they try to kill Necromancer (By TommyXL)", - "\n - Fixed Bodyguard/Crusader when they killed Bodyguard/Crusader, Taskinator and Veteran (By TommyXL)", - "\n - Fixed «Quizmaster.None» (By TommyXL)", - "\n - Fixed missed string «*MayorHideVote» for Vindicator (By TommyXL)", - "\n - Fixed bug when Madmate assign Neutrals (Does not apply to Admirer - By TommyXL)", - "\n - Fixed bug when Camouflage did not disappear after Camouflager was erased (By TommyXL)", - "\n - Probably fixed the bug when Kamikaze killed players during exile (By TommyXL)", - "\n - Probably fixed bug when in-game result displayed randomized nicknames (By TommyXL)", - "\n - Fixed bug when Auto Start always stes ans saved 0 kill cooldown (By TommyXL)", - "\n - Other small fixes that occurred in certain cases (By TommyXL)", - "\n - Swift can no longer get Tricky and vice versa (By TommyXL)", - "\n - Remove unnecessary parenthesis for Lighter (By TommyXL)", - "\n - Fixed bug when Fortune Teller shows «INVALID:NotAssigned» (By Drakos)", - "\n - Fixed broken Auto Start", - "\n - Fixed bug (hopefully) when the host changed his nickname to his own when he was killed by Doppelganger (By TommyXL)", - "\n - Fixed bug when F1 shows role settings (By TommyXL)", - "\n - Fixed bug when Veteran kills Taskinator (By TommyXL)", - "\n - Fixed (hopefully) the last color question for Quizmaster (By TommyXL)", - "\n - Fixed bug when Killing Machine can call a meeting (By TommyXL)", - "\n - Fixed bug when Jailed message not shown (By TommyXL)", "\n【Known bugs】", "\n - 1. Servers may be unstable as the protocol requires fixing on Innersloth's side", "\n - 2. Doppelganger, Swift and Imitator are unstable, but work", @@ -248,122 +223,6 @@ "\n\n★ Welcome to Town of Host: Enhanced v2.0.0 ★" ], "Date": "2024-07-21T12:50:00Z" - }, - { - "Number": "100007", - "Title": "Town of Host: Enhanced v2.1.0", - "Subtitle": "Finally, we're here!", - "Short": "TOH: Enhanced v2.1.0", - "Body": [ - "【Base】", - "\n - Base on TOH: Enhanced v2.0.0", - "\n\r【New Roles/Addons】(5 roles, 6 Add-ons)", - "\n - Yin Yanger (Impostor Killing, idea & coded: Drakos)", - "\n - Possessor (Imposter Ghost Role, idea & coded: D1GQ)", - "\n - Troller (Neutral Chaos, idea: dx7405, coded: TommyXL)", - "\n - Ventguard (Crewmate Support, ported: EHR, coded by: TommyXL)", - "\n - Evader (Addon Helpful, idea: Lime, coded: TommyXL)", - "\n - Rebirth (Addon Helpful, idea & coded: Drakos)", - "\n - Sloth (Harmful Addon, idea & coded: Pyro)", - "\n - Eavesdropper (Addon Helpful, idea by: Crosspost Del Slay, coded: Moe)", - "\n - Spurt (Addon Helpful, idea by: .thediamondstar, coded: Drakos)", - "\n - Prohibited (Addon Harmful, idea by: Crosspost Del Slay, coded: TommyXL)", - "\n - New neutral Team (Faction): Neutral Apocalypse (idea & coded: Marg)", - "\n --- Min/max Neutral Apocalypse can be set", - "\n --- New role: Baker", - "\n --- Berserker and PlagueBearer now moved to Neutral Apocalypse", - "\n --- Soul Collector reworked", - "\n\r【New Settings/Features】", - "\n - Added vent disabling for vanilla (ported from MoreGamemodes by TommyXL & NikoCat)", - "\n --- When a player does not have access to vents, they will never be able to use it", - "\n - More fixes for AntiBlackOut (By TommyXL & Drakos)", - "\n --- Note: This will not completely fix black screen issues, but the more players there are in the game, the less chance of black screen occurrences", - "\n --- To do this, we use revives and base role changes during exile so that dead players will be alive for a couple of seconds but will become dead again", - "\n - Added support role basis changer mid-game (By TommyXL & Drakos)", - "\n --- CopyCat now supports role basis changes", - "\n --- Executioner and Lawyer also change role basis after their target dies", - "\n - TextBoxPatch (Ported: EHR, coded: TommyXL)", - "\n --- Allows you to write any characters into the chat", - "\n - improved Region Menu (coded: D1GQ)", - "\n - Added custom label ID for modded (Ported: EHR, coded: TommyXL)", - "\n - Jester: «Can't Move In Vents» (Setting, coded: TommyXL)", - "\n - Random spawn: Active On Round One (Setting, coded: TommyXL)", - "\n - Added warning message about enabling setting «No Game End»", - "\n --- Warns only the host when he presses the start button", - "\n - Disable Shapeshift menu for some Reject Shapeshift roles (By: Drakos)", - "\n --- For Pitfall, Bomber, Undertaker", - "\n --- It may be used for some more roles", - "\n - Return Ability Votes (By: Drakos)", - "\n --- For Cleanser, Eraser, Fortune teller, Keeper, Oracle, Godfather", - "\n --- First Vote will cancel (Vote Skip) or use the ability; second is regular vote", - "\n - Added «/vote» command (By: Drakos)", - "\n --- Can be disabled in the settings", - "\n - Death reason display improved (ported from EHR).", - "\n - Added role info in setting menu (By: Drakos)", - "\n - Added search bar in settings (By: Drakos)", - "\n - Addon Base (Port From EHR) (By: Drakos)", - "\n --- The settings are now sorted alphabetically", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Jester: Reveal Upon Eject (Setting, by: TheDiamondStar)", - "\n - Executioner: Reveal Target Upon Ejection (Setting, by: TheDiamondStar)", - "\n - Judge: Max trials per game (Setting, by: hinhinarrrrrr)", - "\n - Improved menu for role description in settings", - "\n - Setting: Apocalypse can see each other's Add-ons", - "\n - Settings: «Halloween Decorations» and «Birthday Decoration» (only for modded)", - "\n - Modded players now will see changes in TOHE settings", - "\n - Added custom image «imer» for Mercenary, Bounty Hunter, and Penguin: Thanks @that_one_missing_pixel (Pixel)", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Changed warning message about the API (By: Drakos)", - "\n\r【Bug Fixes/Changes】", - "\n - Phantom Desync: Phantom now plays the invisibility animation instead of teleporting to a random vent for desync roles.", - "\n - Fixed issues with Veteran killing Taskinator, Killing Machine calling meetings, and the Jailed message not showing during the game.", - "\n - Resolved issues with stuck FFA meetings and Fortune Teller showing roles during FFA.", - "\n - Fixed speed bug when Bandit steals the Statue.", - "\n - Resolved Haunt Menu showing «NotAssigned» in Hide & Seek mode.", - "\n - Corrected issues with Doomsayer not using Impostor Vision and various bugs with Psychic.", - "\n - Fixed Taskinator triggering Schrodinger's Cat ability.", - "\n - Corrected Innocent win conditions with Impostor when the setting is enabled.", - "\n - Fixed player spawn issues at the start and after meetings.", - "\n - Resolved full role and add-on display when a player is exiled.", - "\n - Fixed Blackmail not working for non-host modded players.", - "\n - Resolved issues where the Deceiver could kill Serial Killer and where the Deceiver could kill dead players.", - "\n - Corrected several bugs related to Stalker, Enigma, and Madmate Impostor Vision.", - "\n - Fixed issues with Medium messages showing after Medium is dead.", - "\n - Resolved bug where Hangman could kill Nice Mini.", - "\n - Corrected Huntsman minimum kill cooldown.", - "\n - Fixed Bloodmoon not working for modded clients and corrected missing strings for Blackmailer.", - "\n - Fixed issues where the Overseer would show Med Scanner after a meeting.", - "\n - Inhibitor and Saboteur now use sabotage sounds in the intro.", - "\n - Resolved issues where Aware did not work after an Overseer check and Merchant could assign converted add-ons.", - "\n - Fixed bugs with Hater being unable to kill, Crewpostor killing Solsticer, and Impostor Vision not working for Doppelganger.", - "\n - Resolved modded client issues with calling RpcSetName at the end of the game.", - "\n - Fixed win-condition conflicts between terrorists and workaholics.", - "\n - Corrected Necroview interaction with Admired and Madmate roles.", - "\n - Resolved bugs with Judge for modded clients.", - "\n - Gangster and Admirer can no longer get the Egoist role.", - "\n - Fixed bugs with Minus and Plus buttons in settings, ensuring they are always active.", - "\n - Intro Scene optimizations for smoother game start.", - "\n - Fixed numerous typos across roles and settings.", - "\n - Jester can no longer receive the Susceptible role.", - "\n - Added notify message about the game end when RpcEndGame is not received by specific clients.", - "\n - Fixed Baker not showing roles to non-host modded players", - "\n - Fixed mass kicking from lobbies against non-host modded players", - "\n【Translator Credits】", - "\n - Brazilian (By Dx7405, Pietro)", - "\n - Dutch (By apemv, madmazel_)", - "\n - French (By FuroYT, KevOut, Klaomi, Sansationnelle, Space Monkey)", - "\n - Italian (By alot, Baphojack, Mattix606)", - "\n - Japanese (By Sunnyboi)", - "\n - Latin American (By CreepPower)", - "\n - Russian (By TommyXL, Shoulder Devil, chill_ultimated, Nevermore59)", - "\n - Simplified Chinese (By CrewCyan, LezaiYa, NikoCat)", - "\n - Spanish (By Dawson, Sunnyboi, thewhiskas27, xxSShadow)", - "\n - Traditional Chinese (By FlyFlyTurtle, Hinharrrrr, netherdragontw, Pomelo_)", - "\n Check out all of our translators on our website\r\n", - "\n\n★ Welcome to Town of Host: Enhanced v2.1.0 ★" - ], - "Date": "2024-11-3T12:50:00Z" } ] } diff --git a/Resources/Announcements/modNews-nl_NL.json b/Resources/Announcements/modNews-nl_NL.json index 4137b688a..e5379abed 100644 --- a/Resources/Announcements/modNews-nl_NL.json +++ b/Resources/Announcements/modNews-nl_NL.json @@ -175,9 +175,6 @@ "\n - Masochist renamed to Punching Bag (By WaterPanda)", "\n - Bloodlust renamed to Bloodthirst (By WaterPanda)", "\n - Schizophrenic renamed to Paranoia (By WaterPanda)", - "\n - Changed the logic for disconnecting from the game if the API crashes (By TommyXL)", - "\n - Set 300 CD for Nemesis if they cannot use the kill button (By TommyXL)", - "\n - Changed warning message about Api Error Connection (By Drakos)", "\n\r【Bug Fixes】", "\n - Many roles will no longer be able to receive some add-ons that were incompatible (By TommyXL, ryuk, WaterPanda)", "\n - Fixed Bounty Hunter resetting incorrect targets (By TommyXL)", @@ -207,28 +204,6 @@ "\n - Fixed Modded client seeing the Medic shield icon when Medic is dead (By D1GQ)", "\n - Mini can not be duelled, marked, blooded, and sliced (By Lezaiya)", "\n - Fixed typos, inconsistencies, and mistakes in descriptions, names, etc. (By Moe, TommyXL, Drakos, WaterPanda, Sunnyboi, LezaiYa)", - "\n - Fixed bug when after guessing, Judge, etc. the meeting status was not checked (By TommyXL)", - "\n - Fixed bug when Pelican ended the game when eaten players returned (By TommyXL)", - "\n - Fixed Avenger when they try to kill Necromancer (By TommyXL)", - "\n - Fixed Bodyguard/Crusader when they killed Bodyguard/Crusader, Taskinator and Veteran (By TommyXL)", - "\n - Fixed «Quizmaster.None» (By TommyXL)", - "\n - Fixed missed string «*MayorHideVote» for Vindicator (By TommyXL)", - "\n - Fixed bug when Madmate assign Neutrals (Does not apply to Admirer - By TommyXL)", - "\n - Fixed bug when Camouflage did not disappear after Camouflager was erased (By TommyXL)", - "\n - Probably fixed the bug when Kamikaze killed players during exile (By TommyXL)", - "\n - Probably fixed bug when in-game result displayed randomized nicknames (By TommyXL)", - "\n - Fixed bug when Auto Start always stes ans saved 0 kill cooldown (By TommyXL)", - "\n - Other small fixes that occurred in certain cases (By TommyXL)", - "\n - Swift can no longer get Tricky and vice versa (By TommyXL)", - "\n - Remove unnecessary parenthesis for Lighter (By TommyXL)", - "\n - Fixed bug when Fortune Teller shows «INVALID:NotAssigned» (By Drakos)", - "\n - Fixed broken Auto Start", - "\n - Fixed bug (hopefully) when the host changed his nickname to his own when he was killed by Doppelganger (By TommyXL)", - "\n - Fixed bug when F1 shows role settings (By TommyXL)", - "\n - Fixed bug when Veteran kills Taskinator (By TommyXL)", - "\n - Fixed (hopefully) the last color question for Quizmaster (By TommyXL)", - "\n - Fixed bug when Killing Machine can call a meeting (By TommyXL)", - "\n - Fixed bug when Jailed message not shown (By TommyXL)", "\n【Known bugs】", "\n - 1. Servers may be unstable as the protocol requires fixing on Innersloth's side", "\n - 2. Doppelganger, Swift and Imitator are unstable, but work", @@ -248,122 +223,6 @@ "\n\n★ Welcome to Town of Host: Enhanced v2.0.0 ★" ], "Date": "2024-07-21T12:50:00Z" - }, - { - "Number": "100007", - "Title": "Town of Host: Enhanced v2.1.0", - "Subtitle": "Finally, we're here!", - "Short": "TOH: Enhanced v2.1.0", - "Body": [ - "【Base】", - "\n - Base on TOH: Enhanced v2.0.0", - "\n\r【New Roles/Addons】(5 roles, 6 Add-ons)", - "\n - Yin Yanger (Impostor Killing, idea & coded: Drakos)", - "\n - Possessor (Imposter Ghost Role, idea & coded: D1GQ)", - "\n - Troller (Neutral Chaos, idea: dx7405, coded: TommyXL)", - "\n - Ventguard (Crewmate Support, ported: EHR, coded by: TommyXL)", - "\n - Evader (Addon Helpful, idea: Lime, coded: TommyXL)", - "\n - Rebirth (Addon Helpful, idea & coded: Drakos)", - "\n - Sloth (Harmful Addon, idea & coded: Pyro)", - "\n - Eavesdropper (Addon Helpful, idea by: Crosspost Del Slay, coded: Moe)", - "\n - Spurt (Addon Helpful, idea by: .thediamondstar, coded: Drakos)", - "\n - Prohibited (Addon Harmful, idea by: Crosspost Del Slay, coded: TommyXL)", - "\n - New neutral Team (Faction): Neutral Apocalypse (idea & coded: Marg)", - "\n --- Min/max Neutral Apocalypse can be set", - "\n --- New role: Baker", - "\n --- Berserker and PlagueBearer now moved to Neutral Apocalypse", - "\n --- Soul Collector reworked", - "\n\r【New Settings/Features】", - "\n - Added vent disabling for vanilla (ported from MoreGamemodes by TommyXL & NikoCat)", - "\n --- When a player does not have access to vents, they will never be able to use it", - "\n - More fixes for AntiBlackOut (By TommyXL & Drakos)", - "\n --- Note: This will not completely fix black screen issues, but the more players there are in the game, the less chance of black screen occurrences", - "\n --- To do this, we use revives and base role changes during exile so that dead players will be alive for a couple of seconds but will become dead again", - "\n - Added support role basis changer mid-game (By TommyXL & Drakos)", - "\n --- CopyCat now supports role basis changes", - "\n --- Executioner and Lawyer also change role basis after their target dies", - "\n - TextBoxPatch (Ported: EHR, coded: TommyXL)", - "\n --- Allows you to write any characters into the chat", - "\n - improved Region Menu (coded: D1GQ)", - "\n - Added custom label ID for modded (Ported: EHR, coded: TommyXL)", - "\n - Jester: «Can't Move In Vents» (Setting, coded: TommyXL)", - "\n - Random spawn: Active On Round One (Setting, coded: TommyXL)", - "\n - Added warning message about enabling setting «No Game End»", - "\n --- Warns only the host when he presses the start button", - "\n - Disable Shapeshift menu for some Reject Shapeshift roles (By: Drakos)", - "\n --- For Pitfall, Bomber, Undertaker", - "\n --- It may be used for some more roles", - "\n - Return Ability Votes (By: Drakos)", - "\n --- For Cleanser, Eraser, Fortune teller, Keeper, Oracle, Godfather", - "\n --- First Vote will cancel (Vote Skip) or use the ability; second is regular vote", - "\n - Added «/vote» command (By: Drakos)", - "\n --- Can be disabled in the settings", - "\n - Death reason display improved (ported from EHR).", - "\n - Added role info in setting menu (By: Drakos)", - "\n - Added search bar in settings (By: Drakos)", - "\n - Addon Base (Port From EHR) (By: Drakos)", - "\n --- The settings are now sorted alphabetically", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Jester: Reveal Upon Eject (Setting, by: TheDiamondStar)", - "\n - Executioner: Reveal Target Upon Ejection (Setting, by: TheDiamondStar)", - "\n - Judge: Max trials per game (Setting, by: hinhinarrrrrr)", - "\n - Improved menu for role description in settings", - "\n - Setting: Apocalypse can see each other's Add-ons", - "\n - Settings: «Halloween Decorations» and «Birthday Decoration» (only for modded)", - "\n - Modded players now will see changes in TOHE settings", - "\n - Added custom image «imer» for Mercenary, Bounty Hunter, and Penguin: Thanks @that_one_missing_pixel (Pixel)", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Changed warning message about the API (By: Drakos)", - "\n\r【Bug Fixes/Changes】", - "\n - Phantom Desync: Phantom now plays the invisibility animation instead of teleporting to a random vent for desync roles.", - "\n - Fixed issues with Veteran killing Taskinator, Killing Machine calling meetings, and the Jailed message not showing during the game.", - "\n - Resolved issues with stuck FFA meetings and Fortune Teller showing roles during FFA.", - "\n - Fixed speed bug when Bandit steals the Statue.", - "\n - Resolved Haunt Menu showing «NotAssigned» in Hide & Seek mode.", - "\n - Corrected issues with Doomsayer not using Impostor Vision and various bugs with Psychic.", - "\n - Fixed Taskinator triggering Schrodinger's Cat ability.", - "\n - Corrected Innocent win conditions with Impostor when the setting is enabled.", - "\n - Fixed player spawn issues at the start and after meetings.", - "\n - Resolved full role and add-on display when a player is exiled.", - "\n - Fixed Blackmail not working for non-host modded players.", - "\n - Resolved issues where the Deceiver could kill Serial Killer and where the Deceiver could kill dead players.", - "\n - Corrected several bugs related to Stalker, Enigma, and Madmate Impostor Vision.", - "\n - Fixed issues with Medium messages showing after Medium is dead.", - "\n - Resolved bug where Hangman could kill Nice Mini.", - "\n - Corrected Huntsman minimum kill cooldown.", - "\n - Fixed Bloodmoon not working for modded clients and corrected missing strings for Blackmailer.", - "\n - Fixed issues where the Overseer would show Med Scanner after a meeting.", - "\n - Inhibitor and Saboteur now use sabotage sounds in the intro.", - "\n - Resolved issues where Aware did not work after an Overseer check and Merchant could assign converted add-ons.", - "\n - Fixed bugs with Hater being unable to kill, Crewpostor killing Solsticer, and Impostor Vision not working for Doppelganger.", - "\n - Resolved modded client issues with calling RpcSetName at the end of the game.", - "\n - Fixed win-condition conflicts between terrorists and workaholics.", - "\n - Corrected Necroview interaction with Admired and Madmate roles.", - "\n - Resolved bugs with Judge for modded clients.", - "\n - Gangster and Admirer can no longer get the Egoist role.", - "\n - Fixed bugs with Minus and Plus buttons in settings, ensuring they are always active.", - "\n - Intro Scene optimizations for smoother game start.", - "\n - Fixed numerous typos across roles and settings.", - "\n - Jester can no longer receive the Susceptible role.", - "\n - Added notify message about the game end when RpcEndGame is not received by specific clients.", - "\n - Fixed Baker not showing roles to non-host modded players", - "\n - Fixed mass kicking from lobbies against non-host modded players", - "\n【Translator Credits】", - "\n - Brazilian (By Dx7405, Pietro)", - "\n - Dutch (By apemv, madmazel_)", - "\n - French (By FuroYT, KevOut, Klaomi, Sansationnelle, Space Monkey)", - "\n - Italian (By alot, Baphojack, Mattix606)", - "\n - Japanese (By Sunnyboi)", - "\n - Latin American (By CreepPower)", - "\n - Russian (By TommyXL, Shoulder Devil, chill_ultimated, Nevermore59)", - "\n - Simplified Chinese (By CrewCyan, LezaiYa, NikoCat)", - "\n - Spanish (By Dawson, Sunnyboi, thewhiskas27, xxSShadow)", - "\n - Traditional Chinese (By FlyFlyTurtle, Hinharrrrr, netherdragontw, Pomelo_)", - "\n Check out all of our translators on our website\r\n", - "\n\n★ Welcome to Town of Host: Enhanced v2.1.0 ★" - ], - "Date": "2024-11-3T12:50:00Z" } ] } diff --git a/Resources/Announcements/modNews-pt_BR.json b/Resources/Announcements/modNews-pt_BR.json index bb4c5190a..81c75de01 100644 --- a/Resources/Announcements/modNews-pt_BR.json +++ b/Resources/Announcements/modNews-pt_BR.json @@ -175,195 +175,54 @@ "\n - Masochist renomeado para Punching Bag (Por: WaterPanda)", "\n - Bloodlust renomeado para Bloodthirst (Por: WaterPanda)", "\n - Schizophrenic renomeado para Paranoia (Por: WaterPanda)", - "\n - Changed the logic for disconnecting from the game if the API crashes (By TommyXL)", - "\n - Set 300 CD for Nemesis if they cannot use the kill button (By TommyXL)", - "\n - Changed warning message about Api Error Connection (By Drakos)", - "\n\r【Bug Fixes】", - "\n - Many roles will no longer be able to receive some add-ons that were incompatible (By TommyXL, ryuk, WaterPanda)", - "\n - Fixed Bounty Hunter resetting incorrect targets (By TommyXL)", - "\n - Fixed null error post-meeting for Vulture and Seeker and error after votes in Airship (By TommyXL)", - "\n - Fixed custom buttons brightness issues (By TommyXL)", - "\n - Fixed roles without vent ability getting stuck after trying to vent (By TommyXL)", - "\n - Fixed vent icon issues for roles based on Engineer (By TommyXL)", - "\n - Fixed black screens during role assign (By TommyXL)", - "\n - Fixed Scientist assign for desync role (By TommyXL)", - "\n - Fixed bug when 3 settings for Judge was not used (By TommyXL)", - "\n - Fixed buttons are active when the player was guessed (By TommyXL)", - "\n - Some fixes in Guesser UI (By TommyXL)", - "\n - Fixed Double Meeting Ending (By TommyXL)", - "\n - Fixed Guardian Angel Shield Animation sometimes didn't work correctly with Vanilla (By TommyXL)", - "\n - Some fix in random spawn in Airship for the host (By TommyXL)", - "\n - Fixed Necromancer leaving a dead body after the meeting (By TommyXL)", - "\n - Fixed Workaholic incorrect win state (By TommyXL)", - "\n - Fixed Mayor calling meetings even when out of use (By ryuk)", - "\n - Fixed EAC list not working when ban list is off (By ryuk)", - "\n - Fixed Kamikaze causing half-dead players (By ryuk)", - "\n - Fixed Messages not sent to vanilla players (By Drakos)", - "\n - Fixed Zombie Issues (By Drakos)", - "\n - Fixed Punching bag being judged (By Drakos)", - "\n - Fixed bug when kill cooldown not going when press F1/F2/F3/F4 (By NikoCat)", - "\n - Fixed Immediate autostart settings (By NikoCat)", - "\n - Fixed Bait self-reporting (By NikoCat)", - "\n - Fixed Modded client seeing the Medic shield icon when Medic is dead (By D1GQ)", - "\n - Mini can not be duelled, marked, blooded, and sliced (By Lezaiya)", - "\n - Fixed typos, inconsistencies, and mistakes in descriptions, names, etc. (By Moe, TommyXL, Drakos, WaterPanda, Sunnyboi, LezaiYa)", - "\n - Fixed bug when after guessing, Judge, etc. the meeting status was not checked (By TommyXL)", - "\n - Fixed bug when Pelican ended the game when eaten players returned (By TommyXL)", - "\n - Fixed Avenger when they try to kill Necromancer (By TommyXL)", - "\n - Fixed Bodyguard/Crusader when they killed Bodyguard/Crusader, Taskinator and Veteran (By TommyXL)", - "\n - Fixed «Quizmaster.None» (By TommyXL)", - "\n - Fixed missed string «*MayorHideVote» for Vindicator (By TommyXL)", - "\n - Fixed bug when Madmate assign Neutrals (Does not apply to Admirer - By TommyXL)", - "\n - Fixed bug when Camouflage did not disappear after Camouflager was erased (By TommyXL)", - "\n - Probably fixed the bug when Kamikaze killed players during exile (By TommyXL)", - "\n - Probably fixed bug when in-game result displayed randomized nicknames (By TommyXL)", - "\n - Fixed bug when Auto Start always stes ans saved 0 kill cooldown (By TommyXL)", - "\n - Other small fixes that occurred in certain cases (By TommyXL)", - "\n - Swift can no longer get Tricky and vice versa (By TommyXL)", - "\n - Remove unnecessary parenthesis for Lighter (By TommyXL)", - "\n - Fixed bug when Fortune Teller shows «INVALID:NotAssigned» (By Drakos)", - "\n - Fixed broken Auto Start", - "\n - Fixed bug (hopefully) when the host changed his nickname to his own when he was killed by Doppelganger (By TommyXL)", - "\n - Fixed bug when F1 shows role settings (By TommyXL)", - "\n - Fixed bug when Veteran kills Taskinator (By TommyXL)", - "\n - Fixed (hopefully) the last color question for Quizmaster (By TommyXL)", - "\n - Fixed bug when Killing Machine can call a meeting (By TommyXL)", - "\n - Fixed bug when Jailed message not shown (By TommyXL)", - "\n【Known bugs】", - "\n - 1. Servers may be unstable as the protocol requires fixing on Innersloth's side", - "\n - 2. Doppelganger, Swift and Imitator are unstable, but work", - "\n - 3. Modded clients have some problems, so it is recommended to have the mod only on Host", - "\n【Translator Credits】", - "\n - Brazilian (By Dx7405, Pietro)", - "\n - Dutch (By apemv, madmazel_)", - "\n - French (By FuroYT, KevOut, Klaomi, Sansationnelle, Space Monkey)", - "\n - Italian (By alot, Baphojack, Mattix606)", - "\n - Japanese (By Sunnyboi)", - "\n - Latin American (By CreepPower)", - "\n - Russian (By TommyXL, Shoulder Devil, chill_ultimated, Nevermore59)", - "\n - Simplified Chinese (By CrewCyan, LezaiYa, NikoCat)", - "\n - Spanish (By Dawson, Sunnyboi, thewhiskas27, xxSShadow)", - "\n - Traditional Chinese (By FlyFlyTurtle, Hinharrrrr, netherdragontw, Pomelo_)", - "\n Check out all of our translators on our website\r\n", - "\n\n★ Welcome to Town of Host: Enhanced v2.0.0 ★" + "\n\n【Correção de Bugs】", + "\n - Muitas funções não poderão mais receber alguns atributos que eram incompatíveis (Por: TommyXL, ryuk, WaterPanda)", + "\n - Corrigido o problema do Caçador de Recompensas resetando alvos incorretos (Por: TommyXL)", + "\n - Corrigido erro nulo pós-reunião para Canibal e Procurador e erro após votos no Airship (Por: TommyXL)", + "\n - Corrigidos problemas de brilho dos botões personalizados (Por: TommyXL)", + "\n - Corrigida as funções sem habilidade de ventar ficando presas após tentar ventar (Por: TommyXL)", + "\n - Corrigidos problemas com o ícone de duto para funções baseadas no Engenheiro (Por: TommyXL)", + "\n - Corrigida tela preta durante a atribuição de funções (Por: TommyXL)", + "\n - Corrigida atribuição do Cientista para funções desincronizadas (Por: TommyXL)", + "\n - Corrigido bug quando 3 configurações para o Juíz não eram usadas (Por: TommyXL)", + "\n - Corrigido botão ativo quando o jogador era adivinhado (Por: TommyXL)", + "\n - Algumas correções na interface de Adivinhar (Por: TommyXL)", + "\n - Corrigido término de reunião dupla (Por: TommyXL)", + "\n - Corrigida animação do escudo do Anjo Guardião que às vezes não funcionava corretamente com Vanilla (Por: TommyXL)", + "\n - Algumas correções no spawn aleatório no Airship para o anfitrião (Por: TommyXL)", + "\n - Corrigido Necromante deixando um corpo morto após a reunião (Por: TommyXL)", + "\n - Corrigido estado de vitória incorreto do Trabalhador (Por: TommyXL)", + "\n - Corrigido o prefeito podendo convocar reuniões mesmo quando sem usos (Por: ryuk)", + "\n - Corrigida lista EAC não funcionando quando a lista de banimento está desativada (Por: ryuk)", + "\n - Corrigido Kamikaze causando jogadores meio-mortos (Por: ryuk)", + "\n - Corrigidas mensagens não enviadas para jogadores vanilla (Por: Drakos)", + "\n - Corrigidos problemas com a Pestilência (Por: Drakos)", + "\n - Corrigido Masoquista sendo julgado (Por: Drakos)", + "\n - Corrigido bug quando o tempo de recarga para matar não avançava ao pressionar F1/F2/F3/F4 (Por: NikoCat)", + "\n - Corrigidas configurações de início automático imediato (Por: NikoCat)", + "\n - Corrigido Armador podendo se auto-reportar (Por: NikoCat)", + "\n - Corrigido cliente com mod vendo o ícone de escudo do Guardião quando o Guardião está morto (Por: D1GQ)", + "\n - Mini não pode ser desafiado para duelo, marcado, sangrado e cortado (Por: Lezaiya)", + "\n - Corrigidos erros de digitação, inconsistências e erros em descrições, nomes, etc. (Por: Moe, TommyXL, Drakos, WaterPanda, Sunnyboi, LezaiYa)", + "\n【Erros Conhecidos】", + "\n - 1. Os servidores podem estar instáveis, pois o protocolo requer correção do lado da Innersloth", + "\n - 2. Veloz e Sósia estão instáveis, mas funcionam", + "\n - 3. Clientes modificados apresentam alguns problemas, portanto, é recomendável ter o mod apenas no Anfitrião", + "\n【Créditos pela as Traduções】", + "\n - Português (Brasil) (por: Dx7405, Pietro)", + "\n - Holandês (Por: apemv, madmazel_)", + "\n - Francês (Por: FuroYT, KevOut, Klaomi, Sansationnelle, Space Monkey)", + "\n - Italiano (Por: alot, Baphojack, Mattix606)", + "\n - Japonês (Por: Sunnyboi)", + "\n - Latino-Americano (Por: CreepPower)", + "\n - Russo (Por: TommyXL, Shoulder Devil, chill_ultimated, Nevermore59)", + "\n - Chinês simplificado (Por: CrewCyan, LezaiYa, NikoCat223)", + "\n - Espanhol (Por: Dawson, Sunnyboi, thewhiskas27, xxSShadow)", + "\n - Chinês Tradicional (Por: FlyFlyTurtle, Hinharrrrr, netherdragontw, Pomelo_)", + "\n Confira todos os nossos tradutores em nosso site\n", + "\n\n★ Bem-vindo ao Town of Host: Enhanced v2.0.0 ★" ], "Date": "2024-07-21T12:50:00Z" - }, - { - "Number": "100007", - "Title": "Town of Host: Enhanced v2.1.0", - "Subtitle": "Finally, we're here!", - "Short": "TOH: Enhanced v2.1.0", - "Body": [ - "【Base】", - "\n - Base on TOH: Enhanced v2.0.0", - "\n\r【New Roles/Addons】(5 roles, 6 Add-ons)", - "\n - Yin Yanger (Impostor Killing, idea & coded: Drakos)", - "\n - Possessor (Imposter Ghost Role, idea & coded: D1GQ)", - "\n - Troller (Neutral Chaos, idea: dx7405, coded: TommyXL)", - "\n - Ventguard (Crewmate Support, ported: EHR, coded by: TommyXL)", - "\n - Evader (Addon Helpful, idea: Lime, coded: TommyXL)", - "\n - Rebirth (Addon Helpful, idea & coded: Drakos)", - "\n - Sloth (Harmful Addon, idea & coded: Pyro)", - "\n - Eavesdropper (Addon Helpful, idea by: Crosspost Del Slay, coded: Moe)", - "\n - Spurt (Addon Helpful, idea by: .thediamondstar, coded: Drakos)", - "\n - Prohibited (Addon Harmful, idea by: Crosspost Del Slay, coded: TommyXL)", - "\n - New neutral Team (Faction): Neutral Apocalypse (idea & coded: Marg)", - "\n --- Min/max Neutral Apocalypse can be set", - "\n --- New role: Baker", - "\n --- Berserker and PlagueBearer now moved to Neutral Apocalypse", - "\n --- Soul Collector reworked", - "\n\r【New Settings/Features】", - "\n - Added vent disabling for vanilla (ported from MoreGamemodes by TommyXL & NikoCat)", - "\n --- When a player does not have access to vents, they will never be able to use it", - "\n - More fixes for AntiBlackOut (By TommyXL & Drakos)", - "\n --- Note: This will not completely fix black screen issues, but the more players there are in the game, the less chance of black screen occurrences", - "\n --- To do this, we use revives and base role changes during exile so that dead players will be alive for a couple of seconds but will become dead again", - "\n - Added support role basis changer mid-game (By TommyXL & Drakos)", - "\n --- CopyCat now supports role basis changes", - "\n --- Executioner and Lawyer also change role basis after their target dies", - "\n - TextBoxPatch (Ported: EHR, coded: TommyXL)", - "\n --- Allows you to write any characters into the chat", - "\n - improved Region Menu (coded: D1GQ)", - "\n - Added custom label ID for modded (Ported: EHR, coded: TommyXL)", - "\n - Jester: «Can't Move In Vents» (Setting, coded: TommyXL)", - "\n - Random spawn: Active On Round One (Setting, coded: TommyXL)", - "\n - Added warning message about enabling setting «No Game End»", - "\n --- Warns only the host when he presses the start button", - "\n - Disable Shapeshift menu for some Reject Shapeshift roles (By: Drakos)", - "\n --- For Pitfall, Bomber, Undertaker", - "\n --- It may be used for some more roles", - "\n - Return Ability Votes (By: Drakos)", - "\n --- For Cleanser, Eraser, Fortune teller, Keeper, Oracle, Godfather", - "\n --- First Vote will cancel (Vote Skip) or use the ability; second is regular vote", - "\n - Added «/vote» command (By: Drakos)", - "\n --- Can be disabled in the settings", - "\n - Death reason display improved (ported from EHR).", - "\n - Added role info in setting menu (By: Drakos)", - "\n - Added search bar in settings (By: Drakos)", - "\n - Addon Base (Port From EHR) (By: Drakos)", - "\n --- The settings are now sorted alphabetically", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Jester: Reveal Upon Eject (Setting, by: TheDiamondStar)", - "\n - Executioner: Reveal Target Upon Ejection (Setting, by: TheDiamondStar)", - "\n - Judge: Max trials per game (Setting, by: hinhinarrrrrr)", - "\n - Improved menu for role description in settings", - "\n - Setting: Apocalypse can see each other's Add-ons", - "\n - Settings: «Halloween Decorations» and «Birthday Decoration» (only for modded)", - "\n - Modded players now will see changes in TOHE settings", - "\n - Added custom image «imer» for Mercenary, Bounty Hunter, and Penguin: Thanks @that_one_missing_pixel (Pixel)", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Changed warning message about the API (By: Drakos)", - "\n\r【Bug Fixes/Changes】", - "\n - Phantom Desync: Phantom now plays the invisibility animation instead of teleporting to a random vent for desync roles.", - "\n - Fixed issues with Veteran killing Taskinator, Killing Machine calling meetings, and the Jailed message not showing during the game.", - "\n - Resolved issues with stuck FFA meetings and Fortune Teller showing roles during FFA.", - "\n - Fixed speed bug when Bandit steals the Statue.", - "\n - Resolved Haunt Menu showing «NotAssigned» in Hide & Seek mode.", - "\n - Corrected issues with Doomsayer not using Impostor Vision and various bugs with Psychic.", - "\n - Fixed Taskinator triggering Schrodinger's Cat ability.", - "\n - Corrected Innocent win conditions with Impostor when the setting is enabled.", - "\n - Fixed player spawn issues at the start and after meetings.", - "\n - Resolved full role and add-on display when a player is exiled.", - "\n - Fixed Blackmail not working for non-host modded players.", - "\n - Resolved issues where the Deceiver could kill Serial Killer and where the Deceiver could kill dead players.", - "\n - Corrected several bugs related to Stalker, Enigma, and Madmate Impostor Vision.", - "\n - Fixed issues with Medium messages showing after Medium is dead.", - "\n - Resolved bug where Hangman could kill Nice Mini.", - "\n - Corrected Huntsman minimum kill cooldown.", - "\n - Fixed Bloodmoon not working for modded clients and corrected missing strings for Blackmailer.", - "\n - Fixed issues where the Overseer would show Med Scanner after a meeting.", - "\n - Inhibitor and Saboteur now use sabotage sounds in the intro.", - "\n - Resolved issues where Aware did not work after an Overseer check and Merchant could assign converted add-ons.", - "\n - Fixed bugs with Hater being unable to kill, Crewpostor killing Solsticer, and Impostor Vision not working for Doppelganger.", - "\n - Resolved modded client issues with calling RpcSetName at the end of the game.", - "\n - Fixed win-condition conflicts between terrorists and workaholics.", - "\n - Corrected Necroview interaction with Admired and Madmate roles.", - "\n - Resolved bugs with Judge for modded clients.", - "\n - Gangster and Admirer can no longer get the Egoist role.", - "\n - Fixed bugs with Minus and Plus buttons in settings, ensuring they are always active.", - "\n - Intro Scene optimizations for smoother game start.", - "\n - Fixed numerous typos across roles and settings.", - "\n - Jester can no longer receive the Susceptible role.", - "\n - Added notify message about the game end when RpcEndGame is not received by specific clients.", - "\n - Fixed Baker not showing roles to non-host modded players", - "\n - Fixed mass kicking from lobbies against non-host modded players", - "\n【Translator Credits】", - "\n - Brazilian (By Dx7405, Pietro)", - "\n - Dutch (By apemv, madmazel_)", - "\n - French (By FuroYT, KevOut, Klaomi, Sansationnelle, Space Monkey)", - "\n - Italian (By alot, Baphojack, Mattix606)", - "\n - Japanese (By Sunnyboi)", - "\n - Latin American (By CreepPower)", - "\n - Russian (By TommyXL, Shoulder Devil, chill_ultimated, Nevermore59)", - "\n - Simplified Chinese (By CrewCyan, LezaiYa, NikoCat)", - "\n - Spanish (By Dawson, Sunnyboi, thewhiskas27, xxSShadow)", - "\n - Traditional Chinese (By FlyFlyTurtle, Hinharrrrr, netherdragontw, Pomelo_)", - "\n Check out all of our translators on our website\r\n", - "\n\n★ Welcome to Town of Host: Enhanced v2.1.0 ★" - ], - "Date": "2024-11-3T12:50:00Z" } ] } diff --git a/Resources/Announcements/modNews-pt_PT.json b/Resources/Announcements/modNews-pt_PT.json index a88211c41..8207ac47c 100644 --- a/Resources/Announcements/modNews-pt_PT.json +++ b/Resources/Announcements/modNews-pt_PT.json @@ -175,9 +175,6 @@ "\n - Masochist renamed to Punching Bag (By WaterPanda)", "\n - Bloodlust renamed to Bloodthirst (By WaterPanda)", "\n - Schizophrenic renamed to Paranoia (By WaterPanda)", - "\n - Changed the logic for disconnecting from the game if the API crashes (By TommyXL)", - "\n - Set 300 CD for Nemesis if they cannot use the kill button (By TommyXL)", - "\n - Changed warning message about Api Error Connection (By Drakos)", "\n\r【Bug Fixes】", "\n - Many roles will no longer be able to receive some add-ons that were incompatible (By TommyXL, ryuk, WaterPanda)", "\n - Fixed Bounty Hunter resetting incorrect targets (By TommyXL)", @@ -207,28 +204,6 @@ "\n - Fixed Modded client seeing the Medic shield icon when Medic is dead (By D1GQ)", "\n - Mini can not be duelled, marked, blooded, and sliced (By Lezaiya)", "\n - Fixed typos, inconsistencies, and mistakes in descriptions, names, etc. (By Moe, TommyXL, Drakos, WaterPanda, Sunnyboi, LezaiYa)", - "\n - Fixed bug when after guessing, Judge, etc. the meeting status was not checked (By TommyXL)", - "\n - Fixed bug when Pelican ended the game when eaten players returned (By TommyXL)", - "\n - Fixed Avenger when they try to kill Necromancer (By TommyXL)", - "\n - Fixed Bodyguard/Crusader when they killed Bodyguard/Crusader, Taskinator and Veteran (By TommyXL)", - "\n - Fixed «Quizmaster.None» (By TommyXL)", - "\n - Fixed missed string «*MayorHideVote» for Vindicator (By TommyXL)", - "\n - Fixed bug when Madmate assign Neutrals (Does not apply to Admirer - By TommyXL)", - "\n - Fixed bug when Camouflage did not disappear after Camouflager was erased (By TommyXL)", - "\n - Probably fixed the bug when Kamikaze killed players during exile (By TommyXL)", - "\n - Probably fixed bug when in-game result displayed randomized nicknames (By TommyXL)", - "\n - Fixed bug when Auto Start always stes ans saved 0 kill cooldown (By TommyXL)", - "\n - Other small fixes that occurred in certain cases (By TommyXL)", - "\n - Swift can no longer get Tricky and vice versa (By TommyXL)", - "\n - Remove unnecessary parenthesis for Lighter (By TommyXL)", - "\n - Fixed bug when Fortune Teller shows «INVALID:NotAssigned» (By Drakos)", - "\n - Fixed broken Auto Start", - "\n - Fixed bug (hopefully) when the host changed his nickname to his own when he was killed by Doppelganger (By TommyXL)", - "\n - Fixed bug when F1 shows role settings (By TommyXL)", - "\n - Fixed bug when Veteran kills Taskinator (By TommyXL)", - "\n - Fixed (hopefully) the last color question for Quizmaster (By TommyXL)", - "\n - Fixed bug when Killing Machine can call a meeting (By TommyXL)", - "\n - Fixed bug when Jailed message not shown (By TommyXL)", "\n【Known bugs】", "\n - 1. Servers may be unstable as the protocol requires fixing on Innersloth's side", "\n - 2. Doppelganger, Swift and Imitator are unstable, but work", @@ -248,122 +223,6 @@ "\n\n★ Welcome to Town of Host: Enhanced v2.0.0 ★" ], "Date": "2024-07-21T12:50:00Z" - }, - { - "Number": "100007", - "Title": "Town of Host: Enhanced v2.1.0", - "Subtitle": "Finally, we're here!", - "Short": "TOH: Enhanced v2.1.0", - "Body": [ - "【Base】", - "\n - Base on TOH: Enhanced v2.0.0", - "\n\r【New Roles/Addons】(5 roles, 6 Add-ons)", - "\n - Yin Yanger (Impostor Killing, idea & coded: Drakos)", - "\n - Possessor (Imposter Ghost Role, idea & coded: D1GQ)", - "\n - Troller (Neutral Chaos, idea: dx7405, coded: TommyXL)", - "\n - Ventguard (Crewmate Support, ported: EHR, coded by: TommyXL)", - "\n - Evader (Addon Helpful, idea: Lime, coded: TommyXL)", - "\n - Rebirth (Addon Helpful, idea & coded: Drakos)", - "\n - Sloth (Harmful Addon, idea & coded: Pyro)", - "\n - Eavesdropper (Addon Helpful, idea by: Crosspost Del Slay, coded: Moe)", - "\n - Spurt (Addon Helpful, idea by: .thediamondstar, coded: Drakos)", - "\n - Prohibited (Addon Harmful, idea by: Crosspost Del Slay, coded: TommyXL)", - "\n - New neutral Team (Faction): Neutral Apocalypse (idea & coded: Marg)", - "\n --- Min/max Neutral Apocalypse can be set", - "\n --- New role: Baker", - "\n --- Berserker and PlagueBearer now moved to Neutral Apocalypse", - "\n --- Soul Collector reworked", - "\n\r【New Settings/Features】", - "\n - Added vent disabling for vanilla (ported from MoreGamemodes by TommyXL & NikoCat)", - "\n --- When a player does not have access to vents, they will never be able to use it", - "\n - More fixes for AntiBlackOut (By TommyXL & Drakos)", - "\n --- Note: This will not completely fix black screen issues, but the more players there are in the game, the less chance of black screen occurrences", - "\n --- To do this, we use revives and base role changes during exile so that dead players will be alive for a couple of seconds but will become dead again", - "\n - Added support role basis changer mid-game (By TommyXL & Drakos)", - "\n --- CopyCat now supports role basis changes", - "\n --- Executioner and Lawyer also change role basis after their target dies", - "\n - TextBoxPatch (Ported: EHR, coded: TommyXL)", - "\n --- Allows you to write any characters into the chat", - "\n - improved Region Menu (coded: D1GQ)", - "\n - Added custom label ID for modded (Ported: EHR, coded: TommyXL)", - "\n - Jester: «Can't Move In Vents» (Setting, coded: TommyXL)", - "\n - Random spawn: Active On Round One (Setting, coded: TommyXL)", - "\n - Added warning message about enabling setting «No Game End»", - "\n --- Warns only the host when he presses the start button", - "\n - Disable Shapeshift menu for some Reject Shapeshift roles (By: Drakos)", - "\n --- For Pitfall, Bomber, Undertaker", - "\n --- It may be used for some more roles", - "\n - Return Ability Votes (By: Drakos)", - "\n --- For Cleanser, Eraser, Fortune teller, Keeper, Oracle, Godfather", - "\n --- First Vote will cancel (Vote Skip) or use the ability; second is regular vote", - "\n - Added «/vote» command (By: Drakos)", - "\n --- Can be disabled in the settings", - "\n - Death reason display improved (ported from EHR).", - "\n - Added role info in setting menu (By: Drakos)", - "\n - Added search bar in settings (By: Drakos)", - "\n - Addon Base (Port From EHR) (By: Drakos)", - "\n --- The settings are now sorted alphabetically", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Jester: Reveal Upon Eject (Setting, by: TheDiamondStar)", - "\n - Executioner: Reveal Target Upon Ejection (Setting, by: TheDiamondStar)", - "\n - Judge: Max trials per game (Setting, by: hinhinarrrrrr)", - "\n - Improved menu for role description in settings", - "\n - Setting: Apocalypse can see each other's Add-ons", - "\n - Settings: «Halloween Decorations» and «Birthday Decoration» (only for modded)", - "\n - Modded players now will see changes in TOHE settings", - "\n - Added custom image «imer» for Mercenary, Bounty Hunter, and Penguin: Thanks @that_one_missing_pixel (Pixel)", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Changed warning message about the API (By: Drakos)", - "\n\r【Bug Fixes/Changes】", - "\n - Phantom Desync: Phantom now plays the invisibility animation instead of teleporting to a random vent for desync roles.", - "\n - Fixed issues with Veteran killing Taskinator, Killing Machine calling meetings, and the Jailed message not showing during the game.", - "\n - Resolved issues with stuck FFA meetings and Fortune Teller showing roles during FFA.", - "\n - Fixed speed bug when Bandit steals the Statue.", - "\n - Resolved Haunt Menu showing «NotAssigned» in Hide & Seek mode.", - "\n - Corrected issues with Doomsayer not using Impostor Vision and various bugs with Psychic.", - "\n - Fixed Taskinator triggering Schrodinger's Cat ability.", - "\n - Corrected Innocent win conditions with Impostor when the setting is enabled.", - "\n - Fixed player spawn issues at the start and after meetings.", - "\n - Resolved full role and add-on display when a player is exiled.", - "\n - Fixed Blackmail not working for non-host modded players.", - "\n - Resolved issues where the Deceiver could kill Serial Killer and where the Deceiver could kill dead players.", - "\n - Corrected several bugs related to Stalker, Enigma, and Madmate Impostor Vision.", - "\n - Fixed issues with Medium messages showing after Medium is dead.", - "\n - Resolved bug where Hangman could kill Nice Mini.", - "\n - Corrected Huntsman minimum kill cooldown.", - "\n - Fixed Bloodmoon not working for modded clients and corrected missing strings for Blackmailer.", - "\n - Fixed issues where the Overseer would show Med Scanner after a meeting.", - "\n - Inhibitor and Saboteur now use sabotage sounds in the intro.", - "\n - Resolved issues where Aware did not work after an Overseer check and Merchant could assign converted add-ons.", - "\n - Fixed bugs with Hater being unable to kill, Crewpostor killing Solsticer, and Impostor Vision not working for Doppelganger.", - "\n - Resolved modded client issues with calling RpcSetName at the end of the game.", - "\n - Fixed win-condition conflicts between terrorists and workaholics.", - "\n - Corrected Necroview interaction with Admired and Madmate roles.", - "\n - Resolved bugs with Judge for modded clients.", - "\n - Gangster and Admirer can no longer get the Egoist role.", - "\n - Fixed bugs with Minus and Plus buttons in settings, ensuring they are always active.", - "\n - Intro Scene optimizations for smoother game start.", - "\n - Fixed numerous typos across roles and settings.", - "\n - Jester can no longer receive the Susceptible role.", - "\n - Added notify message about the game end when RpcEndGame is not received by specific clients.", - "\n - Fixed Baker not showing roles to non-host modded players", - "\n - Fixed mass kicking from lobbies against non-host modded players", - "\n【Translator Credits】", - "\n - Brazilian (By Dx7405, Pietro)", - "\n - Dutch (By apemv, madmazel_)", - "\n - French (By FuroYT, KevOut, Klaomi, Sansationnelle, Space Monkey)", - "\n - Italian (By alot, Baphojack, Mattix606)", - "\n - Japanese (By Sunnyboi)", - "\n - Latin American (By CreepPower)", - "\n - Russian (By TommyXL, Shoulder Devil, chill_ultimated, Nevermore59)", - "\n - Simplified Chinese (By CrewCyan, LezaiYa, NikoCat)", - "\n - Spanish (By Dawson, Sunnyboi, thewhiskas27, xxSShadow)", - "\n - Traditional Chinese (By FlyFlyTurtle, Hinharrrrr, netherdragontw, Pomelo_)", - "\n Check out all of our translators on our website\r\n", - "\n\n★ Welcome to Town of Host: Enhanced v2.1.0 ★" - ], - "Date": "2024-11-3T12:50:00Z" } ] } diff --git a/Resources/Announcements/modNews-ru_RU.json b/Resources/Announcements/modNews-ru_RU.json index 78baee126..1192f32cc 100644 --- a/Resources/Announcements/modNews-ru_RU.json +++ b/Resources/Announcements/modNews-ru_RU.json @@ -175,9 +175,6 @@ "\n - Masochist renamed to Punching Bag (By WaterPanda)", "\n - Bloodlust renamed to Bloodthirst (By WaterPanda)", "\n - Schizophrenic renamed to Paranoia (By WaterPanda)", - "\n - Changed the logic for disconnecting from the game if the API crashes (By TommyXL)", - "\n - Set 300 CD for Nemesis if they cannot use the kill button (By TommyXL)", - "\n - Changed warning message about Api Error Connection (By Drakos)", "\n\r【Bug Fixes】", "\n - Many roles will no longer be able to receive some add-ons that were incompatible (By TommyXL, ryuk, WaterPanda)", "\n - Fixed Bounty Hunter resetting incorrect targets (By TommyXL)", @@ -206,31 +203,9 @@ "\n - Fixed Bait self-reporting (By NikoCat)", "\n - Fixed Modded client seeing the Medic shield icon when Medic is dead (By D1GQ)", "\n - Mini can not be duelled, marked, blooded, and sliced (By Lezaiya)", - "\n - Fixed typos, inconsistencies, and mistakes in descriptions, names, etc. (By Moe, TommyXL, Drakos, WaterPanda, Sunnyboi, LezaiYa)", - "\n - Fixed bug when after guessing, Judge, etc. the meeting status was not checked (By TommyXL)", - "\n - Fixed bug when Pelican ended the game when eaten players returned (By TommyXL)", - "\n - Fixed Avenger when they try to kill Necromancer (By TommyXL)", - "\n - Fixed Bodyguard/Crusader when they killed Bodyguard/Crusader, Taskinator and Veteran (By TommyXL)", - "\n - Fixed «Quizmaster.None» (By TommyXL)", - "\n - Fixed missed string «*MayorHideVote» for Vindicator (By TommyXL)", - "\n - Fixed bug when Madmate assign Neutrals (Does not apply to Admirer - By TommyXL)", - "\n - Fixed bug when Camouflage did not disappear after Camouflager was erased (By TommyXL)", - "\n - Probably fixed the bug when Kamikaze killed players during exile (By TommyXL)", - "\n - Probably fixed bug when in-game result displayed randomized nicknames (By TommyXL)", - "\n - Fixed bug when Auto Start always stes ans saved 0 kill cooldown (By TommyXL)", - "\n - Other small fixes that occurred in certain cases (By TommyXL)", - "\n - Swift can no longer get Tricky and vice versa (By TommyXL)", - "\n - Remove unnecessary parenthesis for Lighter (By TommyXL)", - "\n - Fixed bug when Fortune Teller shows «INVALID:NotAssigned» (By Drakos)", - "\n - Fixed broken Auto Start", - "\n - Fixed bug (hopefully) when the host changed his nickname to his own when he was killed by Doppelganger (By TommyXL)", - "\n - Fixed bug when F1 shows role settings (By TommyXL)", - "\n - Fixed bug when Veteran kills Taskinator (By TommyXL)", - "\n - Fixed (hopefully) the last color question for Quizmaster (By TommyXL)", - "\n - Fixed bug when Killing Machine can call a meeting (By TommyXL)", - "\n - Fixed bug when Jailed message not shown (By TommyXL)", - "\n【Known bugs】", - "\n - 1. Servers may be unstable as the protocol requires fixing on Innersloth's side", + "\n - Исправлены опечатки, несоответствия и ошибки в описаниях, названиях и т.д. (От Moe, TommyXL, Drakos, WaterPanda, Sunnyboi, LezaiYa)", + "\n【Известные ошибки】", + "\n - 1. Серверы могут работать нестабильно, поскольку протокол требует исправления на стороне Innersloth", "\n - 2. Doppelganger, Swift and Imitator are unstable, but work", "\n - 3. Modded clients have some problems, so it is recommended to have the mod only on Host", "\n【Translator Credits】", @@ -248,122 +223,6 @@ "\n\n★ Welcome to Town of Host: Enhanced v2.0.0 ★" ], "Date": "2024-07-21T12:50:00Z" - }, - { - "Number": "100007", - "Title": "Town of Host: Enhanced v2.1.0", - "Subtitle": "Finally, we're here!", - "Short": "TOH: Enhanced v2.1.0", - "Body": [ - "【Base】", - "\n - Base on TOH: Enhanced v2.0.0", - "\n\r【New Roles/Addons】(5 roles, 6 Add-ons)", - "\n - Yin Yanger (Impostor Killing, idea & coded: Drakos)", - "\n - Possessor (Imposter Ghost Role, idea & coded: D1GQ)", - "\n - Troller (Neutral Chaos, idea: dx7405, coded: TommyXL)", - "\n - Ventguard (Crewmate Support, ported: EHR, coded by: TommyXL)", - "\n - Evader (Addon Helpful, idea: Lime, coded: TommyXL)", - "\n - Rebirth (Addon Helpful, idea & coded: Drakos)", - "\n - Sloth (Harmful Addon, idea & coded: Pyro)", - "\n - Eavesdropper (Addon Helpful, idea by: Crosspost Del Slay, coded: Moe)", - "\n - Spurt (Addon Helpful, idea by: .thediamondstar, coded: Drakos)", - "\n - Prohibited (Addon Harmful, idea by: Crosspost Del Slay, coded: TommyXL)", - "\n - New neutral Team (Faction): Neutral Apocalypse (idea & coded: Marg)", - "\n --- Min/max Neutral Apocalypse can be set", - "\n --- New role: Baker", - "\n --- Berserker and PlagueBearer now moved to Neutral Apocalypse", - "\n --- Soul Collector reworked", - "\n\r【New Settings/Features】", - "\n - Added vent disabling for vanilla (ported from MoreGamemodes by TommyXL & NikoCat)", - "\n --- When a player does not have access to vents, they will never be able to use it", - "\n - More fixes for AntiBlackOut (By TommyXL & Drakos)", - "\n --- Note: This will not completely fix black screen issues, but the more players there are in the game, the less chance of black screen occurrences", - "\n --- To do this, we use revives and base role changes during exile so that dead players will be alive for a couple of seconds but will become dead again", - "\n - Added support role basis changer mid-game (By TommyXL & Drakos)", - "\n --- CopyCat now supports role basis changes", - "\n --- Executioner and Lawyer also change role basis after their target dies", - "\n - TextBoxPatch (Ported: EHR, coded: TommyXL)", - "\n --- Allows you to write any characters into the chat", - "\n - improved Region Menu (coded: D1GQ)", - "\n - Added custom label ID for modded (Ported: EHR, coded: TommyXL)", - "\n - Jester: «Can't Move In Vents» (Setting, coded: TommyXL)", - "\n - Random spawn: Active On Round One (Setting, coded: TommyXL)", - "\n - Added warning message about enabling setting «No Game End»", - "\n --- Warns only the host when he presses the start button", - "\n - Disable Shapeshift menu for some Reject Shapeshift roles (By: Drakos)", - "\n --- For Pitfall, Bomber, Undertaker", - "\n --- It may be used for some more roles", - "\n - Return Ability Votes (By: Drakos)", - "\n --- For Cleanser, Eraser, Fortune teller, Keeper, Oracle, Godfather", - "\n --- First Vote will cancel (Vote Skip) or use the ability; second is regular vote", - "\n - Added «/vote» command (By: Drakos)", - "\n --- Can be disabled in the settings", - "\n - Death reason display improved (ported from EHR).", - "\n - Added role info in setting menu (By: Drakos)", - "\n - Added search bar in settings (By: Drakos)", - "\n - Addon Base (Port From EHR) (By: Drakos)", - "\n --- The settings are now sorted alphabetically", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Jester: Reveal Upon Eject (Setting, by: TheDiamondStar)", - "\n - Executioner: Reveal Target Upon Ejection (Setting, by: TheDiamondStar)", - "\n - Judge: Max trials per game (Setting, by: hinhinarrrrrr)", - "\n - Improved menu for role description in settings", - "\n - Setting: Apocalypse can see each other's Add-ons", - "\n - Settings: «Halloween Decorations» and «Birthday Decoration» (only for modded)", - "\n - Modded players now will see changes in TOHE settings", - "\n - Added custom image «imer» for Mercenary, Bounty Hunter, and Penguin: Thanks @that_one_missing_pixel (Pixel)", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Changed warning message about the API (By: Drakos)", - "\n\r【Bug Fixes/Changes】", - "\n - Phantom Desync: Phantom now plays the invisibility animation instead of teleporting to a random vent for desync roles.", - "\n - Fixed issues with Veteran killing Taskinator, Killing Machine calling meetings, and the Jailed message not showing during the game.", - "\n - Resolved issues with stuck FFA meetings and Fortune Teller showing roles during FFA.", - "\n - Fixed speed bug when Bandit steals the Statue.", - "\n - Resolved Haunt Menu showing «NotAssigned» in Hide & Seek mode.", - "\n - Corrected issues with Doomsayer not using Impostor Vision and various bugs with Psychic.", - "\n - Fixed Taskinator triggering Schrodinger's Cat ability.", - "\n - Corrected Innocent win conditions with Impostor when the setting is enabled.", - "\n - Fixed player spawn issues at the start and after meetings.", - "\n - Resolved full role and add-on display when a player is exiled.", - "\n - Fixed Blackmail not working for non-host modded players.", - "\n - Resolved issues where the Deceiver could kill Serial Killer and where the Deceiver could kill dead players.", - "\n - Corrected several bugs related to Stalker, Enigma, and Madmate Impostor Vision.", - "\n - Fixed issues with Medium messages showing after Medium is dead.", - "\n - Resolved bug where Hangman could kill Nice Mini.", - "\n - Corrected Huntsman minimum kill cooldown.", - "\n - Fixed Bloodmoon not working for modded clients and corrected missing strings for Blackmailer.", - "\n - Fixed issues where the Overseer would show Med Scanner after a meeting.", - "\n - Inhibitor and Saboteur now use sabotage sounds in the intro.", - "\n - Resolved issues where Aware did not work after an Overseer check and Merchant could assign converted add-ons.", - "\n - Fixed bugs with Hater being unable to kill, Crewpostor killing Solsticer, and Impostor Vision not working for Doppelganger.", - "\n - Resolved modded client issues with calling RpcSetName at the end of the game.", - "\n - Fixed win-condition conflicts between terrorists and workaholics.", - "\n - Corrected Necroview interaction with Admired and Madmate roles.", - "\n - Resolved bugs with Judge for modded clients.", - "\n - Gangster and Admirer can no longer get the Egoist role.", - "\n - Fixed bugs with Minus and Plus buttons in settings, ensuring they are always active.", - "\n - Intro Scene optimizations for smoother game start.", - "\n - Fixed numerous typos across roles and settings.", - "\n - Jester can no longer receive the Susceptible role.", - "\n - Added notify message about the game end when RpcEndGame is not received by specific clients.", - "\n - Fixed Baker not showing roles to non-host modded players", - "\n - Fixed mass kicking from lobbies against non-host modded players", - "\n【Translator Credits】", - "\n - Brazilian (By Dx7405, Pietro)", - "\n - Dutch (By apemv, madmazel_)", - "\n - French (By FuroYT, KevOut, Klaomi, Sansationnelle, Space Monkey)", - "\n - Italian (By alot, Baphojack, Mattix606)", - "\n - Japanese (By Sunnyboi)", - "\n - Latin American (By CreepPower)", - "\n - Russian (By TommyXL, Shoulder Devil, chill_ultimated, Nevermore59)", - "\n - Simplified Chinese (By CrewCyan, LezaiYa, NikoCat)", - "\n - Spanish (By Dawson, Sunnyboi, thewhiskas27, xxSShadow)", - "\n - Traditional Chinese (By FlyFlyTurtle, Hinharrrrr, netherdragontw, Pomelo_)", - "\n Check out all of our translators on our website\r\n", - "\n\n★ Welcome to Town of Host: Enhanced v2.1.0 ★" - ], - "Date": "2024-11-3T12:50:00Z" } ] } diff --git a/Resources/Announcements/modNews-zh_CN.json b/Resources/Announcements/modNews-zh_CN.json index ba13f0927..12fa39463 100644 --- a/Resources/Announcements/modNews-zh_CN.json +++ b/Resources/Announcements/modNews-zh_CN.json @@ -175,10 +175,7 @@ "\n - 受虐狂重命名为 Punching Bag «仅限英文» (By: WaterPanda)", "\n - 嗜血者重命名为 Bloodthirst «仅限英文» (By: WaterPanda)", "\n - 双重人格重命名为 Paranoia «仅限英文» (By: WaterPanda)", - "\n - 更改了API崩溃时断开与游戏连接的逻辑 (By TommyXL)", - "\n - 如果黑手党无法使用击杀按钮,则设置为300CD (By TommyXL)", - "\n -更改了关于API连接错误的信息(By Drakos)", - "\n\n【Bug修复】", + "\n\r【Bug修复】(这里只列出了1.6.0中的Bug)", "\n - 许多职业将不再能够获得一些不兼容的附加职业 (By: TommyXL, ryuk, WaterPanda)", "\n - 修复了赏金猎人重置错误目标的Bug (By: TommyXL)", "\n - 修复了会议后秃鹫和探索者的空Bug ,以及在高空飞艇投票后的Bug (By: TommyXL)", @@ -207,32 +204,10 @@ "\n - 修复了模组客户端在医生死亡时看到医生护盾图标的Bug (By: D1GQ)", "\n - 迷你船员不能被决斗、标记、流血和切片 (By: Lezaiya)", "\n - 修复了描述、名称等中的拼写错误、不一致性 (By: Moe, TommyXL, Drakos, WaterPanda, Sunnyboi, LezaiYa)", - "\n -修复了在猜测,正义法官等后未检查会议状态的错误(By TommyXL)", - "\n -修复了被鹈鹕吃掉的玩家返回时结束游戏的错误(By TommyXL)", - "\n -修复了复仇者试图击杀亡灵巫师时的问题(By TommtXL)", - "\n - Fixed Bodyguard/Crusader when they killed Bodyguard/Crusader, Taskinator and Veteran (By TommyXL)", - "\n - Fixed «Quizmaster.None» (By TommyXL)", - "\n - Fixed missed string «*MayorHideVote» for Vindicator (By TommyXL)", - "\n - Fixed bug when Madmate assign Neutrals (Does not apply to Admirer - By TommyXL)", - "\n - Fixed bug when Camouflage did not disappear after Camouflager was erased (By TommyXL)", - "\n - Probably fixed the bug when Kamikaze killed players during exile (By TommyXL)", - "\n - Probably fixed bug when in-game result displayed randomized nicknames (By TommyXL)", - "\n - Fixed bug when Auto Start always stes ans saved 0 kill cooldown (By TommyXL)", - "\n - Other small fixes that occurred in certain cases (By TommyXL)", - "\n - Swift can no longer get Tricky and vice versa (By TommyXL)", - "\n - Remove unnecessary parenthesis for Lighter (By TommyXL)", - "\n - Fixed bug when Fortune Teller shows «INVALID:NotAssigned» (By Drakos)", - "\n - 修复自动开始不起作用的问题", - "\n - Fixed bug (hopefully) when the host changed his nickname to his own when he was killed by Doppelganger (By TommyXL)", - "\n - Fixed bug when F1 shows role settings (By TommyXL)", - "\n - Fixed bug when Veteran kills Taskinator (By TommyXL)", - "\n - Fixed (hopefully) the last color question for Quizmaster (By TommyXL)", - "\n - Fixed bug when Killing Machine can call a meeting (By TommyXL)", - "\n - Fixed bug when Jailed message not shown (By TommyXL)", - "\n【Known bugs】", - "\n - 1. Servers may be unstable as the protocol requires fixing on Innersloth's side", - "\n - 2. Doppelganger, Swift and Imitator are unstable, but work", - "\n - 3. Modded clients have some problems, so it is recommended to have the mod only on Host", + "\n【已知Bug】", + "\n - 1. 服务器可能不稳定,因为协议需要在 Innersloth 的一侧进行修复", + "\n -2.替身者,迅捷和效仿者不稳定,但可以使用", + "\n - 3. 模组客户端有一些问题,所以建议只在房主上使用该模组 (并不清楚这个bug哪来的,Niko觉得挺稳定的)", "\n【翻译鸣谢】", "\n - 巴西语 (By: Dx7405, Pietro)", "\n - 荷兰语 (By: apemv, madmazel_)", @@ -248,122 +223,6 @@ "\n\n★ 欢迎来到 Town of Host: Enhanced v2.0.0 ★" ], "Date": "2024-07-21T12:50:00Z" - }, - { - "Number": "100007", - "Title": "Town of Host: Enhanced v2.1.0", - "Subtitle": "Finally, we're here!", - "Short": "TOH: Enhanced v2.1.0", - "Body": [ - "【Base】", - "\n - Base on TOH: Enhanced v2.0.0", - "\n\r【New Roles/Addons】(5 roles, 6 Add-ons)", - "\n - Yin Yanger (Impostor Killing, idea & coded: Drakos)", - "\n - Possessor (Imposter Ghost Role, idea & coded: D1GQ)", - "\n - Troller (Neutral Chaos, idea: dx7405, coded: TommyXL)", - "\n - Ventguard (Crewmate Support, ported: EHR, coded by: TommyXL)", - "\n - Evader (Addon Helpful, idea: Lime, coded: TommyXL)", - "\n - Rebirth (Addon Helpful, idea & coded: Drakos)", - "\n - Sloth (Harmful Addon, idea & coded: Pyro)", - "\n - Eavesdropper (Addon Helpful, idea by: Crosspost Del Slay, coded: Moe)", - "\n - Spurt (Addon Helpful, idea by: .thediamondstar, coded: Drakos)", - "\n - Prohibited (Addon Harmful, idea by: Crosspost Del Slay, coded: TommyXL)", - "\n - New neutral Team (Faction): Neutral Apocalypse (idea & coded: Marg)", - "\n --- Min/max Neutral Apocalypse can be set", - "\n --- New role: Baker", - "\n --- Berserker and PlagueBearer now moved to Neutral Apocalypse", - "\n --- Soul Collector reworked", - "\n\r【New Settings/Features】", - "\n - Added vent disabling for vanilla (ported from MoreGamemodes by TommyXL & NikoCat)", - "\n --- When a player does not have access to vents, they will never be able to use it", - "\n - More fixes for AntiBlackOut (By TommyXL & Drakos)", - "\n --- Note: This will not completely fix black screen issues, but the more players there are in the game, the less chance of black screen occurrences", - "\n --- To do this, we use revives and base role changes during exile so that dead players will be alive for a couple of seconds but will become dead again", - "\n - Added support role basis changer mid-game (By TommyXL & Drakos)", - "\n --- CopyCat now supports role basis changes", - "\n --- Executioner and Lawyer also change role basis after their target dies", - "\n - TextBoxPatch (Ported: EHR, coded: TommyXL)", - "\n --- Allows you to write any characters into the chat", - "\n - improved Region Menu (coded: D1GQ)", - "\n - Added custom label ID for modded (Ported: EHR, coded: TommyXL)", - "\n - Jester: «Can't Move In Vents» (Setting, coded: TommyXL)", - "\n - Random spawn: Active On Round One (Setting, coded: TommyXL)", - "\n - Added warning message about enabling setting «No Game End»", - "\n --- Warns only the host when he presses the start button", - "\n - Disable Shapeshift menu for some Reject Shapeshift roles (By: Drakos)", - "\n --- For Pitfall, Bomber, Undertaker", - "\n --- It may be used for some more roles", - "\n - Return Ability Votes (By: Drakos)", - "\n --- For Cleanser, Eraser, Fortune teller, Keeper, Oracle, Godfather", - "\n --- First Vote will cancel (Vote Skip) or use the ability; second is regular vote", - "\n - Added «/vote» command (By: Drakos)", - "\n --- Can be disabled in the settings", - "\n - Death reason display improved (ported from EHR).", - "\n - Added role info in setting menu (By: Drakos)", - "\n - Added search bar in settings (By: Drakos)", - "\n - Addon Base (Port From EHR) (By: Drakos)", - "\n --- The settings are now sorted alphabetically", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Jester: Reveal Upon Eject (Setting, by: TheDiamondStar)", - "\n - Executioner: Reveal Target Upon Ejection (Setting, by: TheDiamondStar)", - "\n - Judge: Max trials per game (Setting, by: hinhinarrrrrr)", - "\n - Improved menu for role description in settings", - "\n - Setting: Apocalypse can see each other's Add-ons", - "\n - Settings: «Halloween Decorations» and «Birthday Decoration» (only for modded)", - "\n - Modded players now will see changes in TOHE settings", - "\n - Added custom image «imer» for Mercenary, Bounty Hunter, and Penguin: Thanks @that_one_missing_pixel (Pixel)", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Changed warning message about the API (By: Drakos)", - "\n\r【Bug Fixes/Changes】", - "\n - Phantom Desync: Phantom now plays the invisibility animation instead of teleporting to a random vent for desync roles.", - "\n - Fixed issues with Veteran killing Taskinator, Killing Machine calling meetings, and the Jailed message not showing during the game.", - "\n - Resolved issues with stuck FFA meetings and Fortune Teller showing roles during FFA.", - "\n - Fixed speed bug when Bandit steals the Statue.", - "\n - Resolved Haunt Menu showing «NotAssigned» in Hide & Seek mode.", - "\n - Corrected issues with Doomsayer not using Impostor Vision and various bugs with Psychic.", - "\n - Fixed Taskinator triggering Schrodinger's Cat ability.", - "\n - Corrected Innocent win conditions with Impostor when the setting is enabled.", - "\n - Fixed player spawn issues at the start and after meetings.", - "\n - Resolved full role and add-on display when a player is exiled.", - "\n - Fixed Blackmail not working for non-host modded players.", - "\n - Resolved issues where the Deceiver could kill Serial Killer and where the Deceiver could kill dead players.", - "\n - Corrected several bugs related to Stalker, Enigma, and Madmate Impostor Vision.", - "\n - Fixed issues with Medium messages showing after Medium is dead.", - "\n - Resolved bug where Hangman could kill Nice Mini.", - "\n - Corrected Huntsman minimum kill cooldown.", - "\n - Fixed Bloodmoon not working for modded clients and corrected missing strings for Blackmailer.", - "\n - Fixed issues where the Overseer would show Med Scanner after a meeting.", - "\n - Inhibitor and Saboteur now use sabotage sounds in the intro.", - "\n - Resolved issues where Aware did not work after an Overseer check and Merchant could assign converted add-ons.", - "\n - Fixed bugs with Hater being unable to kill, Crewpostor killing Solsticer, and Impostor Vision not working for Doppelganger.", - "\n - Resolved modded client issues with calling RpcSetName at the end of the game.", - "\n - Fixed win-condition conflicts between terrorists and workaholics.", - "\n - Corrected Necroview interaction with Admired and Madmate roles.", - "\n - Resolved bugs with Judge for modded clients.", - "\n - Gangster and Admirer can no longer get the Egoist role.", - "\n - Fixed bugs with Minus and Plus buttons in settings, ensuring they are always active.", - "\n - Intro Scene optimizations for smoother game start.", - "\n - Fixed numerous typos across roles and settings.", - "\n - Jester can no longer receive the Susceptible role.", - "\n - Added notify message about the game end when RpcEndGame is not received by specific clients.", - "\n - Fixed Baker not showing roles to non-host modded players", - "\n - Fixed mass kicking from lobbies against non-host modded players", - "\n【Translator Credits】", - "\n - Brazilian (By Dx7405, Pietro)", - "\n - Dutch (By apemv, madmazel_)", - "\n - French (By FuroYT, KevOut, Klaomi, Sansationnelle, Space Monkey)", - "\n - Italian (By alot, Baphojack, Mattix606)", - "\n - Japanese (By Sunnyboi)", - "\n - Latin American (By CreepPower)", - "\n - Russian (By TommyXL, Shoulder Devil, chill_ultimated, Nevermore59)", - "\n - 简体中文 (By: 青瀚,乐崽吖,绿色游戏(NikoCat233))", - "\n - Spanish (By Dawson, Sunnyboi, thewhiskas27, xxSShadow)", - "\n - Traditional Chinese (By FlyFlyTurtle, Hinharrrrr, netherdragontw, Pomelo_)", - "\n Check out all of our translators on our website\r\n", - "\n\n★ Welcome to Town of Host: Enhanced v2.1.0 ★" - ], - "Date": "2024-11-3T12:50:00Z" } ] } diff --git a/Resources/Announcements/modNews-zh_TW.json b/Resources/Announcements/modNews-zh_TW.json index 4e7dcd7a2..0e5f537a7 100644 --- a/Resources/Announcements/modNews-zh_TW.json +++ b/Resources/Announcements/modNews-zh_TW.json @@ -175,9 +175,6 @@ "\n - 受虐狂名稱由 Masochist 變為 Punching Bag (By WaterPanda)", "\n - 嗜血的名稱由 Bloodlust 變為 Bloodthirst (By WaterPanda)", "\n - 雙重人格的名稱由 Schizophrenic 變為 Paranoia (By WaterPanda)", - "\n - 更改了API崩潰時斷開與遊戲連接的邏輯 (By TommyXL)", - "\n - 如果黑手黨無法擊殺,則將他的CD設定為300秒 (By TommyXL)", - "\n - 更改了有關Api錯誤連接的警告訊息 (By Drakos)", "\n\n【Bug修復】", "\n - 許多職業將不再能獲得不兼容的附加職業 (By TommyXL, ryuk, WaterPanda)", "\n - 修復了賞金獵人重置錯誤目標的Bug (By TommyXL)", @@ -186,7 +183,7 @@ "\n - 修復了無法使用通風管的職業會在嘗試使用後卡住的Bug (By TommyXL)", "\n - 修復了基於工程師的職業圖標消失的Bug (By TommyXL)", "\n - 修復了職業分配期間的黑屏問題 (By TommyXL)", - "\n - 修復了特定職業的科學家分配 (By TommyXL)", + "\n - 修復了不相關的職業的科學家分配 (By TommyXL)", "\n - 修復了未使用法官的3個設定時的錯誤 (By TommyXL)", "\n - 修復了玩家被賭後按鈕處於活動狀態的Bug (By TommyXL)", "\n - 修復了一些關於賭怪介面的問題 (By TommyXL)", @@ -199,7 +196,7 @@ "\n - 修復了封禁清單關閉時EAC清單不起作用的問題 (By ryuk)", "\n - 修復了神風特攻隊導致玩家半死的問題 (By ryuk)", "\n - 修復了訊息會發送給原版玩家的Bug (By Drakos)", - "\n - 修復殭屍問題 (By Drakos)", + "\n - 修復僵屍問題 (By Drakos)", "\n - 修復了受虐狂會被審判的Bug (By Drakos)", "\n - 修復了當按下F1/F2/F3/F4時,擊殺冷卻停止的Bug (By NikoCat)", "\n - 修復了立刻自動開始設定 (By NikoCat)", @@ -207,163 +204,25 @@ "\n - 修復了模組客戶端在軍醫死亡時會看到護盾碎裂圖標的Bug (By D1GQ)", "\n - 現在迷你船員不能夠被決鬥、標記、流血和切片 (By Lezaiya)", "\n - 修復了描述、名稱等方面的拼字錯誤、不一致和錯誤 (By Moe, TommyXL, Drakos, WaterPanda, Sunnyboi, LezaiYa)", - "\n - 修復了賭博、審判等後未檢查會議狀態的錯誤 (By TommyXL)", - "\n - 修復了當被鵜鶘吃掉的玩家返回時結束遊戲的錯誤 (By TommyXL)", - "\n - 修復了復仇者試圖殺死死靈法師時的問題 (By TommyXL)", - "\n - 修復了保鑣/十字軍殺死保鑣/十字軍、搗蛋鬼和老兵時的問題 (By TommyXL)", - "\n - 修復«Quizmaster.None» (By TommyXL)", - "\n - 修復了衛道士遺失的字串 «*MayorHideVote» (By TommyXL)", - "\n - 修復了叛徒會分配給中立陣營的錯誤 (不適用於仰慕者 - By TommyXL)", - "\n - 修復了隱蔽者被抹除後隱蔽效果沒有消失的錯誤 (By TommyXL)", - "\n - 可能修復了神風特攻隊在被放逐時殺死目標的一些問題 (By TommyXL)", - "\n - 可能修復了遊戲結果顯示隨機暱稱時的錯誤 (By TommyXL)", - "\n - Fixed bug when Auto Start always stes ans saved 0 kill cooldown (By TommyXL)", - "\n - Other small fixes that occurred in certain cases (By TommyXL)", - "\n - Swift can no longer get Tricky and vice versa (By TommyXL)", - "\n - Remove unnecessary parenthesis for Lighter (By TommyXL)", - "\n - Fixed bug when Fortune Teller shows «INVALID:NotAssigned» (By Drakos)", - "\n - 修復自動開始故障的問題", - "\n - Fixed bug (hopefully) when the host changed his nickname to his own when he was killed by Doppelganger (By TommyXL)", - "\n - 修復按下F1顯示職業介紹時的Bug (By TommyXL)", - "\n - 修復老兵殺死搗蛋鬼時的Bug (By TommyXL)", - "\n - Fixed (hopefully) the last color question for Quizmaster (By TommyXL)", - "\n - 修復了殺人機器可以召開會議的Bug (By TommyXL)", - "\n - 修復了監禁訊息未顯示的Bug (By TommyXL)", "\n【已知的Bugs】", "\n - 1. 伺服器可能不穩定,因為協定需要在 Innersloth 方面進行修復", "\n - 2. 分身者、無影和效顰者變得不穩定,但依舊可以工作", "\n - 3. 模組客戶端有一些問題,因此建議只在房主上使用模組", "\n【翻譯貢獻】", "\n - 巴西語 (By Dx7405, Pietro)", - "\n - 荷蘭語 (By apemv, madmazel_)", + "\n- 荷蘭語 (By apemv, madmazel_)", "\n - 法語 (By FuroYT, KevOut, Klaomi, Sansationnelle, Space Monkey)", - "\n - 義大利語 (By alot, Baphojack, Mattix606)", - "\n - 日語 (By Sunnyboi)", - "\n - 拉丁美洲語 (By CreepPower)", - "\n - 俄語 (By TommyXL, Shoulder Devil, chill_ultimated, Nevermore59)", - "\n - 簡體中文 (By CrewCyan, LezaiYa, NikoCat)", - "\n - 西班牙語 (By Dawson, Sunnyboi, thewhiskas27, xxSShadow)", - "\n - 繁體中文 (By FlyFlyTurtle, netherdragontw, Pomelo_)", + "\n- 義大利語 (By alot, Baphojack, Mattix606)", + "\n- 日語 (By Sunnyboi)", + "\n- 拉丁美洲語 (By CreepPower)", + "\n- 俄語 (By TommyXL, Shoulder Devil, chill_ultimated, Nevermore59)", + "\n- 簡體中文 (By CrewCyan, LezaiYa, NikoCat)", + "\n- 西班牙語 (By Dawson, Sunnyboi, thewhiskas27, xxSShadow)", + "\n- 繁體中文 (By FlyFlyTurtle, netherdragontw, Pomelo_)", "\n在我們的官網上查看所有翻譯人員\n", "\n\n★ 歡迎來到 Town of Host: Enhanced v2.0.0 ★" ], "Date": "2024-07-21T12:50:00Z" - }, - { - "Number": "100007", - "Title": "Town of Host: Enhanced v2.1.0", - "Subtitle": "Finally, we're here!", - "Short": "TOH: Enhanced v2.1.0", - "Body": [ - "【基於版本】", - "\n - 基於版本 TOH: Enhanced v2.0.0", - "\n\n【新職業/附加職業】(5個職業、6個附加職業)", - "\n - 陰陽師 (殺戮類偽裝者, 想法&代碼: Drakos)", - "\n - 牽引者 (偽裝者幽靈職業, 想法&代碼: D1GQ)", - "\n - Troller (Neutral Chaos, idea: dx7405, coded: TommyXL)", - "\n - Ventguard (Crewmate Support, ported: EHR, coded by: TommyXL)", - "\n - Evader (Addon Helpful, idea: Lime, coded: TommyXL)", - "\n - Rebirth (Addon Helpful, idea & coded: Drakos)", - "\n - Sloth (Harmful Addon, idea & coded: Pyro)", - "\n - Eavesdropper (Addon Helpful, idea by: Crosspost Del Slay, coded: Moe)", - "\n - Spurt (Addon Helpful, idea by: .thediamondstar, coded: Drakos)", - "\n - Prohibited (Addon Harmful, idea by: Crosspost Del Slay, coded: TommyXL)", - "\n - New neutral Team (Faction): Neutral Apocalypse (idea & coded: Marg)", - "\n --- Min/max Neutral Apocalypse can be set", - "\n --- New role: Baker", - "\n --- Berserker and PlagueBearer now moved to Neutral Apocalypse", - "\n --- Soul Collector reworked", - "\n\r【New Settings/Features】", - "\n - Added vent disabling for vanilla (ported from MoreGamemodes by TommyXL & NikoCat)", - "\n --- When a player does not have access to vents, they will never be able to use it", - "\n - More fixes for AntiBlackOut (By TommyXL & Drakos)", - "\n --- Note: This will not completely fix black screen issues, but the more players there are in the game, the less chance of black screen occurrences", - "\n --- To do this, we use revives and base role changes during exile so that dead players will be alive for a couple of seconds but will become dead again", - "\n - Added support role basis changer mid-game (By TommyXL & Drakos)", - "\n --- CopyCat now supports role basis changes", - "\n --- Executioner and Lawyer also change role basis after their target dies", - "\n - TextBoxPatch (Ported: EHR, coded: TommyXL)", - "\n --- Allows you to write any characters into the chat", - "\n - improved Region Menu (coded: D1GQ)", - "\n - Added custom label ID for modded (Ported: EHR, coded: TommyXL)", - "\n - Jester: «Can't Move In Vents» (Setting, coded: TommyXL)", - "\n - Random spawn: Active On Round One (Setting, coded: TommyXL)", - "\n - Added warning message about enabling setting «No Game End»", - "\n --- Warns only the host when he presses the start button", - "\n - Disable Shapeshift menu for some Reject Shapeshift roles (By: Drakos)", - "\n --- For Pitfall, Bomber, Undertaker", - "\n --- It may be used for some more roles", - "\n - Return Ability Votes (By: Drakos)", - "\n --- For Cleanser, Eraser, Fortune teller, Keeper, Oracle, Godfather", - "\n --- First Vote will cancel (Vote Skip) or use the ability; second is regular vote", - "\n - Added «/vote» command (By: Drakos)", - "\n --- Can be disabled in the settings", - "\n - Death reason display improved (ported from EHR).", - "\n - Added role info in setting menu (By: Drakos)", - "\n - Added search bar in settings (By: Drakos)", - "\n - Addon Base (Port From EHR) (By: Drakos)", - "\n --- The settings are now sorted alphabetically", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Jester: Reveal Upon Eject (Setting, by: TheDiamondStar)", - "\n - Executioner: Reveal Target Upon Ejection (Setting, by: TheDiamondStar)", - "\n - Judge: Max trials per game (Setting, by: hinhinarrrrrr)", - "\n - Improved menu for role description in settings", - "\n - Setting: Apocalypse can see each other's Add-ons", - "\n - Settings: «Halloween Decorations» and «Birthday Decoration» (only for modded)", - "\n - Modded players now will see changes in TOHE settings", - "\n - Added custom image «imer» for Mercenary, Bounty Hunter, and Penguin: Thanks @that_one_missing_pixel (Pixel)", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Changed warning message about the API (By: Drakos)", - "\n\r【Bug Fixes/Changes】", - "\n - Phantom Desync: Phantom now plays the invisibility animation instead of teleporting to a random vent for desync roles.", - "\n - Fixed issues with Veteran killing Taskinator, Killing Machine calling meetings, and the Jailed message not showing during the game.", - "\n - Resolved issues with stuck FFA meetings and Fortune Teller showing roles during FFA.", - "\n - Fixed speed bug when Bandit steals the Statue.", - "\n - Resolved Haunt Menu showing «NotAssigned» in Hide & Seek mode.", - "\n - Corrected issues with Doomsayer not using Impostor Vision and various bugs with Psychic.", - "\n - Fixed Taskinator triggering Schrodinger's Cat ability.", - "\n - Corrected Innocent win conditions with Impostor when the setting is enabled.", - "\n - Fixed player spawn issues at the start and after meetings.", - "\n - Resolved full role and add-on display when a player is exiled.", - "\n - Fixed Blackmail not working for non-host modded players.", - "\n - Resolved issues where the Deceiver could kill Serial Killer and where the Deceiver could kill dead players.", - "\n - Corrected several bugs related to Stalker, Enigma, and Madmate Impostor Vision.", - "\n - Fixed issues with Medium messages showing after Medium is dead.", - "\n - Resolved bug where Hangman could kill Nice Mini.", - "\n - Corrected Huntsman minimum kill cooldown.", - "\n - Fixed Bloodmoon not working for modded clients and corrected missing strings for Blackmailer.", - "\n - Fixed issues where the Overseer would show Med Scanner after a meeting.", - "\n - Inhibitor and Saboteur now use sabotage sounds in the intro.", - "\n - Resolved issues where Aware did not work after an Overseer check and Merchant could assign converted add-ons.", - "\n - Fixed bugs with Hater being unable to kill, Crewpostor killing Solsticer, and Impostor Vision not working for Doppelganger.", - "\n - Resolved modded client issues with calling RpcSetName at the end of the game.", - "\n - Fixed win-condition conflicts between terrorists and workaholics.", - "\n - Corrected Necroview interaction with Admired and Madmate roles.", - "\n - Resolved bugs with Judge for modded clients.", - "\n - Gangster and Admirer can no longer get the Egoist role.", - "\n - Fixed bugs with Minus and Plus buttons in settings, ensuring they are always active.", - "\n - Intro Scene optimizations for smoother game start.", - "\n - Fixed numerous typos across roles and settings.", - "\n - Jester can no longer receive the Susceptible role.", - "\n - Added notify message about the game end when RpcEndGame is not received by specific clients.", - "\n - Fixed Baker not showing roles to non-host modded players", - "\n - Fixed mass kicking from lobbies against non-host modded players", - "\n【Translator Credits】", - "\n - Brazilian (By Dx7405, Pietro)", - "\n - Dutch (By apemv, madmazel_)", - "\n - French (By FuroYT, KevOut, Klaomi, Sansationnelle, Space Monkey)", - "\n - Italian (By alot, Baphojack, Mattix606)", - "\n - Japanese (By Sunnyboi)", - "\n - Latin American (By CreepPower)", - "\n - Russian (By TommyXL, Shoulder Devil, chill_ultimated, Nevermore59)", - "\n - Simplified Chinese (By CrewCyan, LezaiYa, NikoCat)", - "\n - Spanish (By Dawson, Sunnyboi, thewhiskas27, xxSShadow)", - "\n - Traditional Chinese (By FlyFlyTurtle, Hinharrrrr, netherdragontw, Pomelo_)", - "\n Check out all of our translators on our website\r\n", - "\n\n★ Welcome to Town of Host: Enhanced v2.1.0 ★" - ], - "Date": "2024-11-3T12:50:00Z" } ] } diff --git a/Resources/Lang/de_DE.json b/Resources/Lang/de_DE.json index cba988a36..68eefbd41 100644 --- a/Resources/Lang/de_DE.json +++ b/Resources/Lang/de_DE.json @@ -19,8 +19,6 @@ "SubText.Neutral": "Arbeite alleine um zu gewinnen", "SubText.Apocalypse": "Werde mit deinem Team unbesiegbar", "SubText.Madmate": "Hilf den Verrätern", - "SubText.Lovers": "Lebt glücklich zusammen und gewinnt", - "SubText.Egoist": "Gewinne allein", "TypeImpostor": "Verräter", "TypeCrewmate": "Besatzung", "TypeNeutral": "Neutral", @@ -30,9 +28,6 @@ "TeamNeutral": "Neutral", "TeamCrewmate": "Besatzung", "TeamMadmate": "Verräterhelfer", - "TeamLovers": "Liebhaber", - "TeamEgoist": "Egoist", - "TeamApocalypse": "Apokalypser", "YouAreCrewmate": "Du bist Besatzung", "YouAreImpostor": "Du bist Verräter", "YouAreNeutral": "Du bist neutral", @@ -61,13 +56,13 @@ "CrewmatesCanGuess": "Besatzungsmitglieder können guessen", "ImpostorsCanGuess": "Verräter können guessen", "NeutralKillersCanGuess": "Neutrale Killer können guessen", - "NeutralApocalypseCanGuess": "Neutraler Apokalypser kann guessen", + "NeutralApocalypseCanGuess": "Neutral Apocalypse can guess", "PassiveNeutralsCanGuess": "Passive Neutrale können guessen", "CanGuessAddons": "Kann Add-ons guessen", "ShowOnlyEnabledRolesInGuesserUI": "Zeige nur aktivierte Rollen im Guesserbord an", "CrewCanGuessCrew": "Besatzungsmitglieder können Besatzungsmitglieder -Rollen guessen", "ImpCanGuessImp": "Verräter kann andere Verräter guessen", - "ApocCanGuessApoc": "Neutraler Apokalypser Kann Rollen von Neutralem Apokalypser guessen", + "ApocCanGuessApoc": "Neutral Apocalypse Can Guess Neutral Apocalypse Roles", "GuessImmune": "Dieses Ziel kann nicht geguessed werden, tut mir leid!", "GM": "Spielmeister", "Sunnyboy": "Sonniger", @@ -105,7 +100,7 @@ "Witch": "Hexe", "Nemesis": "Nemesis", "Bloodmoon": "Blutmond", - "Possessor": "Besitzer", + "Possessor": "Possessor", "Puppeteer": "Puppenspieler", "Mastermind": "Vordenker", "TimeThief": "Zeitdieb", @@ -144,88 +139,87 @@ "Dazzler": "Dazzler", "YinYanger": "YinYanger", "Deathpact": "Todespaktierer", - "Devourer": "Verschlinger", + "Devourer": "Devourer", "Consigliere": "Konsort", "Morphling": "Morphling", "Twister": "Wirbelstürmer", "Lurker": "Schleicher", - "Visionary": "Visionär", - "Refugee": "Flüchtling", + "Visionary": "Visionary", + "Refugee": "Refugee", "Underdog": "Unterlegener", "Ludopath": "Ludopath", "Godfather": "Patenonkel", - "Chronomancer": "Chronomant", + "Chronomancer": "Chronomancer", "Pitfall": "Fallenleger", "EvilMini": "Böser Mini", "Blackmailer": "Erpresser", - "Instigator": "Anstifter", + "Instigator": "Instigator", "LazyGuy": "Fauler Kerl", "SuperStar": "Superstar", "Celebrity": "Prominenter", "Cleanser": "Reiniger", "Keeper": "Hüter", "Knight": "Ritter", - "Mayor": "Bürgermeister", + "Mayor": "Mayor", "Psychic": "Spiritueller", "Mechanic": "Mechaniker", - "Sheriff": "Sherrif", + "Sheriff": "Sheriff", "Vigilante": "Gewissenhafter", - "Jailer": "Gefängniswärter", + "Jailer": "Jailer", "CopyCat": "Nachäffer", "Snitch": "Spitzel", "Marshall": "Marschall", - "Doctor": "Arzt", - "Dictator": "Diktator", - "Detective": "Detektiv", + "Doctor": "Doctor", + "Dictator": "Dictator", + "Detective": "Detective", "NiceGuesser": "Guter Guesser", "GuessMaster": "Guessmeister", "Transporter": "Transporter", - "TimeManager": "Zeitmanager", + "TimeManager": "Time Manager", "Spurt": "Spurt", "Veteran": "Veteran", - "Bastion": "Bastionär", - "Bodyguard": "Leibwächter", + "Bastion": "Bastion", + "Bodyguard": "Bodyguard", "Deceiver": "Schlitzohr", "Grenadier": "Grenadier", "Medic": "Sanitäter", "FortuneTeller": "Wahrsagerin", - "Judge": "Richter", - "Mortician": "Bestatter", + "Judge": "Judge", + "Mortician": "Mortician", "Medium": "Hellseher", "Pacifist": "Pazifist", "Observer": "Betrachter", "Monarch": "Monarch", "Overseer": "Aufpasser", "Coroner": "Leichenbeschauer", - "Merchant": "Kaufmann", - "President": "Präsident", + "Merchant": "Merchant", + "President": "President", "Hawk": "Falke", "Retributionist": "Vergelter", "Deputy": "Abgeordneter", - "Investigator": "Ermittler", + "Investigator": "Investigator", "Guardian": "Wächter", - "Addict": "Süchtiger", - "Mole": "Maulwurf", + "Addict": "Addict", + "Mole": "Mole", "Alchemist": "Alchemist", "Tracefinder": "Spurensucher", - "Oracle": "Orakel", + "Oracle": "Oracle", "Spiritualist": "Spiritualist", - "Chameleon": "Chamäleon", + "Chameleon": "Chameleon", "Inspector": "Inspektor", "Captain": "Kapitän", - "Admirer": "Bewunderer", - "TimeMaster": "Zeitmeister", - "Crusader": "Kreuzritter", + "Admirer": "Admirer", + "TimeMaster": "Time Master", + "Crusader": "Crusader", "Altruist": "Altruist", "Reverie": "Träumer", - "Lookout": "Ausguck", + "Lookout": "Lookout", "Telecommunication": "Telekommunikator", "Lighter": "Leuchter", "TaskManager": "Aufgabenmanager", - "Witness": "Zeuge", + "Witness": "Witness", "Swapper": "Swapper", - "ChiefOfPolice": "Polizeichef", - "NiceMini": "Guter Mini", + "NiceMini": "Nice Mini", "Mini": "Mini", "Spy": "Spion", "Randomizer": "Zufälliger", @@ -234,10 +228,10 @@ "Arsonist": "Feuerteufel", "Pyromaniac": "Pyromane", "Kamikaze": "Kamikaze", - "Huntsman": "Jäger", + "Huntsman": "Huntsman", "Terrorist": "Terrorist", "Executioner": "Scharfrichter", - "Lawyer": "Anwalt", + "Lawyer": "Lawyer", "Opportunist": "Opportunist", "Vector": "Vector", "Jackal": "Schakal", @@ -253,17 +247,16 @@ "Stalker": "Stalker", "Workaholic": "Fleißige-Arbeiter", "Solsticer": "Sonnenwender", - "Abyssbringer": "Abyssbringer", - "Collector": "Sammler", + "Collector": "Collector", "Provocateur": "Provokateur", "BloodKnight": "Blutritter", - "Apocalypse": "Apokalypser", + "Apocalypse": "Apocalypse", "PlagueBearer": "Pestträger", "Pestilence": "Seuche", "SoulCollector": "Seelensammler", - "Death": "Tod", - "Baker": "Bäcker", - "Famine": "Hungerleider", + "Death": "Death", + "Baker": "Baker", + "Famine": "Famine", "Berserker": "Berserker", "War": "Krieg", "Glitch": "Glitcher", @@ -274,7 +267,7 @@ "Juggernaut": "Tausendsassa", "Infectious": "Ansteckender", "Virus": "Virus", - "Pursuer": "Häscher", + "Pursuer": "Pursuer", "Specter": "Geist-Arbeiter", "Pirate": "Pirat", "Agitater": "Hetzer", @@ -291,21 +284,21 @@ "Amnesiac": "Dementer", "Imitator": "Imitator", "Bandit": "Bandit", - "Doppelganger": "Doppelgänger", - "PunchingBag": "Boxsack", + "Doppelganger": "Doppelganger", + "PunchingBag": "Punching Bag", "Doomsayer": "Unheilsprophet", - "Shroud": "Schleier", - "Werewolf": "Werwolf", + "Shroud": "Shroud", + "Werewolf": "Werewolf", "Shaman": "Schamane", - "Seeker": "Sucher", + "Seeker": "Seeker", "Pixie": "Fee", "Occultist": "Okkultist", "SchrodingersCat": "Schrödingers Katze", - "Romantic": "Romantiker", - "VengefulRomantic": "Rächender Romantiker", - "RuthlessRomantic": "Rücksichtsloser Romantiker", + "Romantic": "Romantic", + "VengefulRomantic": "Vengeful Romantic", + "RuthlessRomantic": "Ruthless Romantic", "Poisoner": "Vergifter", - "HexMaster": "Hexenmeister", + "HexMaster": "Hex Master", "Wraith": "Gespenst", "Jinx": "Jinx", "PotionMaster": "Trankmeister", @@ -313,34 +306,34 @@ "Warden": "Aufseher", "Minion": "Günstling", "Ghastly": "Grausiger", - "LastImpostor": "Letzter Verrräter", - "Overclocked": "Übertakteter", + "LastImpostor": "Last Impostor", + "Overclocked": "Overclocked", "Lovers": "Liebhaber", "Madmate": "Verräterhelfer", "Watcher": "Beobachter", "Flash": "Flitzer", - "Torch": "Fackelträger", - "Seer": "Seher", + "Torch": "Torch", + "Seer": "Seer", "Tiebreaker": "Tiebrecher", - "Oblivious": "Vergesslicher", - "Rebirth": "Wiederbelebender", - "Bewilder": "Verwirrender", - "Workhorse": "Arbeitspferd", + "Oblivious": "Oblivious", + "Rebirth": "Rebirth", + "Bewilder": "Bewilder", + "Workhorse": "Workhorse", "Fool": "Tollpatsch", "Avanger": "Rächer", "Youtuber": "YouTuber", "Egoist": "Egoist", - "Stealer": "Stehler", + "Stealer": "Stealer", "Paranoia": "Schizophrene", "Mimic": "Nachahmer", "Guesser": "Räter", "Necroview": "Nekroansicht", - "Reach": "Reichweite", + "Reach": "Reach", "Charmed": "Bekehrter", - "Cleansed": "Gereinigt", + "Cleansed": "Cleansed", "Bait": "Killköder", "Trapper": "Bärenfalle", - "Infected": "Infiziert", + "Infected": "Infected", "Onbound": "Beständiger", "Rebound": "Abpraller", "Mundane": "Weltlicher", @@ -358,7 +351,7 @@ "Gravestone": "Grabstein", "Lazy": "Fauler", "Autopsy": "Autopsist", - "Loyal": "Treu", + "Loyal": "Loyal", "EvilSpirit": "Böser Geist", "Recruit": "Kumpanrekrut", "Admired": "Bewunderter", @@ -373,8 +366,8 @@ "Mare": "Alpträumer", "Burst": "Platzender", "Sleuth": "Pathologe", - "Clumsy": "Tollpatschig", - "Nimble": "Flink", + "Clumsy": "Clumsy", + "Nimble": "Nimble", "Circumvent": "Gehender", "Cyber": "Cyber", "Hurried": "Beeilter", @@ -388,17 +381,15 @@ "Statue": "Statue", "Evader": "Evader", "DollMaster": "Marionetten-Meister", - "DoubleAgent": "Doppelagent", - "Sloth": "Faultier", - "Prohibited": "Verbotener", + "DoubleAgent": "Double Agent", + "Sloth": "Sloth", + "Prohibited": "Prohibited", "Eavesdropper": "Eavesdropper", - "Shocker": "Schocker", - "Revenant": "Wiederkehrer", "BracketAddons": "Füge Klammern zu Add-ons hinzu", "EngineerTOHEInfo": "Nutze die Schächte, um die Verräter zu erwischen", "ScientistTOHEInfo": "Greife überall auf die tragbare Lebensanzeige zu", "NoisemakerTOHEInfo": "Bei Ermordung wird ein Alarm ausgesendet", - "TrackerTOHEInfo": "Verfolge Spieler mit der Map", + "TrackerTOHEInfo": "Track players with your map", "ShapeshifterTOHEInfo": "Verwandle dich in Besatzungsmitglieder, um den Verdacht auf sie zu werfen", "PhantomTOHEInfo": "Werde unsichtbar", "GuardianAngelTOHEInfo": "Beschütze die Besatzung vor den Verrätern", @@ -421,7 +412,7 @@ "BeforeNemesisInfo": "Du kannst noch nicht killen", "AfterNemesisInfo": "Fang jetzt an zu killen", "BloodmoonInfo": "Richte Verwüstung unter der Besatzung an", - "PossessorInfo": "Kontrolliere und führe Besatzungsmitglieder weg von anderen", + "PossessorInfo": "Possess and lead crewmates away from others", "PuppeteerInfo": "Bring die andere Spieler dazu für dich zu töten", "MastermindInfo": "Bring andere dazu für dich zu töten", "TimeThiefInfo": "Veringere die Besprechungszeit durchs Killen", @@ -442,12 +433,12 @@ "GreedyInfo": "Deine Killwartezeit ändert sich", "CursedWolfInfo": "Du überlebst einige Tötungsversuche", "SoulCatcherInfo": "Du hast den Ort mit deinem Ziel getauscht", - "QuickShooterInfo": "Spare Munition um die Wartezeit zu verkürzen", + "QuickShooterInfo": "Store ammo to offset kill cooldown", "CamouflagerInfo": "Tarne alle für leichte Kills", "EraserInfo": "Lösche die Rolle deines Votes", "ButcherInfo": "Genieße meine wunderschöne Arbeit", - "HangmanInfo": "Ich entscheide, wann dein Leben endet", - "SwooperInfo": "Du wirst vorübergehend unsichtbar", + "HangmanInfo": "I will decide when your life will end", + "SwooperInfo": "Turn invisible temporarily", "CrewpostorInfo": "Kille, indem du Aufgaben erfüllst", "WildlingInfo": "Kille mit Stärke und verkleide dich", "TricksterInfo": "Kille und täusche die Besatzung", @@ -459,7 +450,7 @@ "CouncillorInfo": "Töte Besatzungsmitglieder während Meetings", "DazzlerInfo": "Reduziere die Sicht der Besatzung", "DeathpactInfo": "Lass Spieler einen Todespakt abschließen", - "DevourerInfo": "Konsumiere die Skins der Besatzung", + "DevourerInfo": "Consume the skin of the crew", "ConsigliereInfo": "Finde die Rolle anderer Spieler heraus", "MorphlingInfo": "Du kannst nur als Geformwandelter killen", "TwisterInfo": "Vertausche die Positionen aller Spieler", @@ -480,7 +471,7 @@ "CleanserInfo": "Lösche alle Add-on-Rollen von deinem gevoteten Spieler", "KeeperInfo": "Lehne den Auswurf ab, der Hüter schützt!", "MayorInfo": "Deine Votes zählen mehrfach", - "PsychicInfo": "Einer der roten Namen ist böse", + "PsychicInfo": "One of the red names is evil", "MechanicInfo": "Nutze Vents und behebe die Sabotagen", "SheriffInfo": "Erschieße die Verräter", "VigilanteInfo": "Nicht der Held den wir verdienten, aber den, den wir bräuchten", @@ -489,17 +480,17 @@ "SnitchInfo": "Vollende deine Aufgaben, um die Verräter zu erkennen", "MarshallInfo": "Schließe deine Aufgaben ab, um deine Unschuld zu beweisen", "DoctorInfo": "Und so starben sie...", - "DictatorInfo": "Verurteile jemanden zu Tode", - "DetectiveInfo": "Erhalte zusätzliche Informationen von deinen Leichenmeldungen", - "UndercoverInfo": "Verräter sehen dich als ihren Partner", - "KnightInfo": "Du kannst einen Spieler killen", + "DictatorInfo": "Exile a player based on your judgment", + "DetectiveInfo": "Gain extra info from your body reports", + "UndercoverInfo": "Impostors see you as their partner", + "KnightInfo": "You can kill one player", "NiceGuesserInfo": "Erguesse die Verräter -rollen in den Notfalltreffen, um sie zu killen", "GuessMasterInfo": "Flüstern gehört, jedes geguesste Wort.", "TransporterInfo": "Erledige Aufgaben, um die Positionen von 2 zufälligen Spielern zu tauschen", "TimeManagerInfo": "Erhöhe die Besprechungszeit durchs Aufgabenabschließen", "VeteranInfo": "Begib dich in Bereitschaft, um jeden zu killen, der es an dir versucht", "BastionInfo": "Lege Bomben in Vents", - "YinYangerInfo": "Verbrenne spontan zwei Spieler", + "YinYangerInfo": "Spontaneously combust two players", "BodyguardInfo": "Verhindere nahegelegene Kills", "DeceiverInfo": "Versuche, Spieler zu täuschen", "GrenadierInfo": "Verringere die Sicht der Verräter, indem du dich in die Vents begibst", @@ -510,10 +501,9 @@ "MediumInfo": "Rede mit Geistern", "ObserverInfo": "Du siehst Schild-Animationen", "PacifistInfo": "Vente um die Kill-Wartezeit zurück zu setzten", - "RebirthInfo": "Erstehe wieder auf", + "RebirthInfo": "Arise Again", "MonarchInfo": "Gib der Besatzung mehr Votingmacht!", - "AbyssbringerInfo": "Erstelle schwarze Löcher", - "SpurtInfo": "Spring wie ein Hase!", + "SpurtInfo": "Spring Like A rabbit!", "StealthInfo": "Killen blendet jeden im Raum", "PenguinInfo": "Ziehe deine Opfer", "OverseerInfo": "Finde die Rolle anderer Spieler heraus", @@ -537,7 +527,7 @@ "AdmirerInfo": "Wähle ein Spieler, um ihn auf deine Seite zu bringen", "TimeMasterInfo": "Stelle die Zeit zurück!", "CrusaderInfo": "Kille eines Spieler's Killer", - "AltruistInfo": "Belebe einen Spieler wieder", + "AltruistInfo": "Revive a player", "ReverieInfo": "Mit jedem Kill, wird deine Killwartezeit kürzer", "LookoutInfo": "Blicke durch Tarnungen", "TelecommunicationInfo": "Behalte die Gerätenutzung im Auge", @@ -546,7 +536,6 @@ "WitnessInfo": "Finde heraus, ob jemand vor kurzem gekillt hat", "GhastlyInfo": "Besitze jemanden!", "SwapperInfo": "Tausche die Votes zweier Spieler", - "ChiefOfPoliceInfo": "Stelle einen Sheriff ein, um der Besatzung zu helfen!", "NiceMiniInfo": "Niemand kann dich verletzten bis du Erwachsen bist.", "ArsonistInfo": "Übergieße alle und entfache das Feuer", "PyromaniacInfo": "Verbrenne und kille alle", @@ -573,10 +562,10 @@ "CollectorInfo": "Sammle Votes von Spielern", "ProvocateurInfo": "Gewinne mithilfe deines Ziels", "BloodKnightInfo": "Killen gibt dir kurzzeitig einen Schild", - "PlagueBearerInfo": "Verseuche alle, um zum Pestilence zu werden", + "PlagueBearerInfo": "Plague everyone to turn into Pestilence", "PestilenceInfo": "Lösche alle aus!", - "SoulCollectorInfo": "Sage Tode voraus, um Seelen zu sammeln", - "DeathInfo": "Erlasse Armageddon", + "SoulCollectorInfo": "Predict deaths to collect souls", + "DeathInfo": "Enact Armageddon", "BakerInfo": "Feed Players Bread to become Famine", "FamineInfo": "Starve Everyone", "BerserkerInfo": "Kille um dein Level zu erhöhen", @@ -607,20 +596,20 @@ "AmnesiacInfo": "Merke dir die Rolle der Leiche", "ImitatorInfo": "Ahme die Rolle eines Spielers nach", "BanditInfo": "Klaue eines Spielers Add-on-Rollen", - "DoppelgangerInfo": "Stiehl die Identität deines Ziels", + "DoppelgangerInfo": "Steal your target's identity", "PunchingBagInfo": "Werde einige Male angegriffen um zu gewinnen!", "KamikazeInfo": "Kille Spieler durch eine suizidale Mission", "DoomsayerInfo": "Guesse die Rollen von Spielern, um zu gewinnen", "ShroudInfo": "Hülle Spieler ein, damit sie killen", "WerewolfInfo": "Kille Besatzungsmitglieder in Gruppen", "ShamanInfo": "Leite alle Angriffe auf die Voodoopuppe ab", - "SeekerInfo": "Spiele Verstecken mit deinem Ziel", + "SeekerInfo": "Play Hide and Seek with your target", "PixieInfo": "Markier sie, pack sie ein, und wirf sie raus!", "OccultistInfo": "Kille und verfluche deine Feinde", "SchrodingersCatInfo": "Die Katze ist sowohl lebendig als auch tot, bis sie beobachtet wird.", - "RomanticInfo": "Schütze deinen Partner, um gemeinsam zu gewinnen", - "VengefulRomanticInfo": "Räche deinen Partner, um gemeinsam zu gewinnen", - "RuthlessRomanticInfo": "Töte alle um mit deinem Partner zu gewinnen", + "RomanticInfo": "Protect your partner to win together", + "VengefulRomanticInfo": "Revenge your partner to win together", + "RuthlessRomanticInfo": "Kill everyone to win with your partner", "PoisonerInfo": "Kille jeden mit verzögerten Kills", "HexMasterInfo": "Verhexe Spieler, damit sie im Treffen sterben", "WraithInfo": "Vent to go invisible temporarily", @@ -639,40 +628,40 @@ "SeerInfo": "You are alerted when somebody has died", "TiebreakerInfo": "Brich den Votegleichstand", "ObliviousInfo": "You can't report bodies", - "BewilderInfo": "Eine Wendung der Sicht, ein Netz der Verwirrung", + "BewilderInfo": "A twist of vision, a web of confusion", "WorkhorseInfo": "Sei der Erste, der seine Aufgaben erledigt, um mehr zu erhalten", "FoolInfo": "Du kannst keine Sabotagen beheben", - "AvangerInfo": "Du nimmst jemanden mit in den Tod", - "YoutuberInfo": "Werde zuerst gekillt um zu gewinnen", + "AvangerInfo": "You take someone with you upon death", + "YoutuberInfo": "Get killed first to win", "CelebrityInfo": "Alle wissen es wenn du stirbst", "EgoistInfo": "Gewinne allein", - "StealerInfo": "Gewinne Stimmen mit Kills", + "StealerInfo": "Gain votes with kills", "ParanoiaInfo": "Du bist gleichzeitig tot und lebendig", "MimicInfo": "Offenbare vom Nachahmer gekillte Spieler den Verrätern nach seinem Tod", "GuesserInfo": "Erguesse die Rollen in den Notfalltreffen, um sie zu killen", - "NecroviewInfo": "Sieh das Team der Toten", - "ReachInfo": "Du hast eine größere Killreichweite", + "NecroviewInfo": "See the team of the dead", + "ReachInfo": "You have a longer kill range", "BaitInfo": "Dein Killer meldet deine Leiche sofort", "TrapperInfo": "Mache deinen Killer für ein paar Sekunden bewegungsunfähig", "OnboundInfo": "Du kannst nicht geguessed werden", "ReboundInfo": "Errate mich, und ich ersteche dich!", "MundaneInfo": "Aufgaben erledigt, das Guessen beginnt.", - "UnreportableInfo": "Deine Leiche kann nicht gemeldet werden", - "LuckyInfo": "Weiche Angriffen aus", + "UnreportableInfo": "Your body can't be reported", + "LuckyInfo": "Dodge attackers", "DoubleShotInfo": "Du hast einen zweiten Guessversuch", "RascalInfo": "Du erscheinst manchmal böse", - "SoullessInfo": "Du hast keine Seele", - "GravestoneInfo": "Deine Rolle wird offenbart, wenn du stirbst", + "SoullessInfo": "You have no soul", + "GravestoneInfo": "Your role is revealed when you die", "LazyInfo": "Du bist zu faul", "AutopsyInfo": "Du kannst sehen wie andere starben", - "LoyalInfo": "Du kannst nicht rekrutiert werden", - "EvilSpiritInfo": "Du bist ein böser Geist", + "LoyalInfo": "You cannot be recruited", + "EvilSpiritInfo": "You are an evil Spirit", "RecruitInfo": "Hilf dem Schakal", - "AdmiredInfo": "Der Bewunderer hat dich zu seiner Liebe auserwählt", - "GlowInfo": "Du leuchtest in der Dunkelheit", + "AdmiredInfo": "The Admirer chose you as their love", + "GlowInfo": "You glow in the dark", "RadarInfo": "Nächste Person, Pfeilrichtung!", - "DiseasedInfo": "Erhöhe die Wartezeit des Spielers, der mit dir interagiert", - "AntidoteInfo": "Verringere die Wartezeit des Spielers, der mit dir interagiert", + "DiseasedInfo": "Increase the cooldown of the player who interacts with you", + "AntidoteInfo": "Decrease the cooldown of the player who interacts with you", "StubbornInfo": "Schütze deine Rolle und Add-on-Rolle", "SwiftInfo": "Your kills don't cause a lunge", "UnluckyInfo": "Interagieren kann zum Tod führen", @@ -688,7 +677,7 @@ "NimbleInfo": "Du kannst venten!", "CircumventInfo": "Du kannst nicht mehr venten", "OiiaiInfo": "OIIAIOIIIAI", - "CyberInfo": "Du bist populär!", + "CyberInfo": "You're popular!", "HurriedInfo": "Oh Mann, ich hab zu viel zu tun!", "InfluencedInfo": "You lack decisiveness!", "SilentInfo": "Vote wie ein Geist!", @@ -704,11 +693,9 @@ "RainbowInfo": "Bunte Melodien! Du kennst nicht einmal deine eigene Farbe.", "DollMasterInfo": "Steuere die Aktionen von Spielern!", "DoubleAgentInfo": "Plant bombs on players in meetings", - "SlothInfo": "Du bist langsamer", + "SlothInfo": "You're slower", "ProhibitedInfo": "Certain vents are blocked", "EavesdropperInfo": "Listen in on other roles", - "ShockerInfo": "Shock unsuspecting players", - "RevenantInfo": "Take your killer's role", "EngineerTOHEInfoLong": "(Besatzung):\nAls Ingenieur hast du die Fähigkeit, Vents zu nutzen, solange die Kommunikation nicht sabotiert ist.", "ScientistTOHEInfoLong": "(Crewmates):\nAs the Scientist, you can see vitals at any time, showing you who is alive and dead.", "NoisemakerTOHEInfoLong": "(Crewmates):\nAs the Noisemaker, whenever you die, you will make a noise, and a visual indicator of your death appears on the screen so the Crewmates can run to catch the person who killed you red-handed (even if it’s not Red).", @@ -780,11 +767,11 @@ "LurkerInfoLong": "(Impostors):\nAs the Lurker, you can jump into a vent to reduce your cooldown by a certain number of seconds. After you kill, your cooldown resets to its original value.", "VisionaryInfoLong": "(Verräter):\nAls Visionär siehst du den Aufenthaltsort von lebenden Spielern während einem Treffen.\nFolgende Information wird bei den Spielern angezeigt:\n- Roter Name bedeutet Verräter.\n- Türkiser Name bedeutet Besatzung.\n- Grauer Name bedeutet Neutral.", "PlagueDoctorInfoLong": "(Neutral):\n(Seuchendoktor von TOH)\nAls Seuchendoktor musst du jeden lebenden Spieler infiziert bekommen.\nDu startest mit einem beliebigen Spieler, den du infizierst, wenn wer für kurze Zeit in unmittelbarer Nähe dieses Infizierten verbringt, wird er selbst auch infiziert.\nDer Infizierungsprozess ist kumulative, also er resetet sich nicht nach Distanzierung oder nach Treffen.", - "RefugeeInfoLong": "(Madmates):\nAs the Refugee, you were either:\n -An Amnesiac who remembered an Impostor\n -A killer who killed the Godfather's target.\n -A Romantic whose partner was an Impostor\n -Or an Imitator that imitated an Impostor.\n\nNow your job is to help the Impostors kill the crewmates.", + "RefugeeInfoLong": "(Verräterhelfer):\nAls Flüchtling, warst du entweder ein Dementer welcher sich an ein Verräter erinnerte oder ein Verräter, welcher das Ziel vom Patenonkel killte.\n\nJetzt ist es deine Aufgabe den Verrätern zu helfen, die Besatzung zu killen.", "UnderdogInfoLong": "(Verräter):\nAls Unterlegener kannst du nicht killen bis eine bestimmte Anzahl an lebenden Spieler bleibt.", "ConsigliereInfoLong": "(Verräter):\nAls Konsort kannst du die Rollen der anderen Spieler offenbaren in dem du deinen Killknopf benutzt.\n\nEinzelklick: Rolle offenbaren \nDoppelklick: killen\n\nWen du keine Offenbarungen mehr hast, funktioniert dein Killknopf normal.", "LudopathInfoLong": "(Impostors):\nAs the Ludopath, your kill cooldown is randomized.\n\nMinimum it can be is 1 second, while the maximum is your default kill cooldown.", - "GodfatherInfoLong": "(Impostors):\nAs the Godfather, you vote someone to make them your target.\nIn the next round, if someone kills the target, the killer will turn into a Refugee or Madmate.", + "GodfatherInfoLong": "(Impostors):\nAs the Godfather, you vote someone to make them your target.\nIn the next round, if someone kills the target, the killer will turn into a Refugee.", "ChronomancerInfoLong": "(Impostors):\nAs the Chronomancer, you have a charge bar which indicates when the slaughter is ready. When it is at 100% the next time you kill someone, you go into slaughter mode, meaning you can kill indefinitely until your bar runs out of charge. Otherwise, you have a normal KCD.", "PitfallInfoLong": "(Verräter):\nAls Fallenleger kannst du formwandeln, um den Bereich der Formwandlung als Falle zu markieren. Spieler, die diesen Bereich betreten, werden für kurze Zeit bewegungsunfähig und ihre Sicht wird eingeschränkt.", "EvilMiniInfoLong": "(Impostors):\nAs the Evil Mini, you are unkillable until you grow up and have a very long initial kill cooldown, which gets drastically shortened as you grow up.", @@ -856,7 +843,6 @@ "TaskManagerInfoLong": "(Crewmates):\nYou see the total number of tasks completed (by everyone all together) next to your role name, which updates in real-time.", "WitnessInfoLong": "(Crewmates):\nAs the Witness, when you use your kill button on someone, you will know if they killed in the last X seconds or not. (X depends on the settings).", "SwapperInfoLong": "(Crewmates):\nAs the Swapper, you can swap votes in meetings.\n\nTo swap votes, use '/sw [playerID]' twice.\n\nPlayer IDs are displayed next to player names in meetings, but you can also use /id to get a list of all player IDs.\n\nNote: Depending on the Host's settings, you can exchange your own votes.", - "ChiefOfPoliceInfoLong": "(Crewmates):\nPlayers with swords can be recruited to join the sheriff's team to serve the crew\nNote: only one recruitment opportunity\nDepending on settings, you may recruit non killers or non crews.\nYou may suidice for recruiting wrong target.", "NiceMiniInfoLong": "(Crewmates):\nAs a Nice Mini, your survival is crucial. You can't be killed until you grow up, and if you die or are evicted from the meeting before you grow up, everyone loses. This unique role adds a new dynamic to the game, where your survival is not just for your benefit but for the entire Crew's success.", "SpyInfoLong": "(Crewmates):\nAs the Spy, when someone uses their kill button on you (any ability used through the kill button), you'll see their name in orange for a few seconds.\nNote: If a Crewmate used their ability on you, you'll also see them with an orange name!\nNote: If you cannot use left, you won't see orange names!\nNote: If the kill button interaction is blocked, the player's cooldown will reset to 10s'", "RandomizerInfoLong": "(Besatzung):\nWenn der Zufällige stirbt, führt sein Killer eines davon aus:\n 1. Er meldet selbst die Leiche\n 2. Er bleibt neben der Leiche\n 3. Hat eine Killwartezeit von 600 Sekunden\n 4. Ein zufälliger Spieler rächt sich.", @@ -871,7 +857,7 @@ "LawyerInfoLong": "(Neutral):\nDer Anwalt hat ein Ziel zum Beschützen, welches mit einem Diamanten 「♦」 neben dem Namen angezeigt wird.\nWenn dein Ziel gewinnt, gewinnst du.\nWenn dein Ziel verliert, verlierst du.", "OpportunistInfoLong": "(Neutral):\nWenn der Opportunist bis zum Ende des Spiels überlebt, gewinnt er mit den gewinnenden Spielern.", "VectorInfoLong": "(Neutral):\nAls Vector gewinnst du, wenn du eine bestimmte Anzahl an Vents nutzt.", - "JackalInfoLong": "(Neutrals):\nAs the Jackal, you win if you are the last player alive. Additionally, you may recruit using the kill button. If the target is not one you can recruit, you have run out of uses, or you don't have the option to recruit, then you will kill people normally (i.e., don't use kill buttons in front of others thinking it'll recruit). If the target has a kill button and the option to turn into a Sidekick is on, they will become a Sidekick. Otherwise, they will gain the Recruit add-on if the option to give the Recruit add-on is on.\nDepending on the settings, when Jackal was killed, a Sidekick will be randomly selected as the new Jackal.\nRecruit may be selected if no sidekick is alive.", + "JackalInfoLong": "(Neutral):\nAls Schakal gewinnst du als letzter Überlebender. Zusätzlich kannst du mit dem Killknopf andere rekrutieren. Wenn der getroffene Spieler nicht rekrutiert werden kann, passiert entweder nichts oder du killst ihn (also nicht öffentlich versuchen zu rekrutieren). Wenn der getroffene Spieler einen Killknopf hat und dessen Einstellung, rekrutiert zu werden aktiv ist, wird er zum Kumpan. Andernfalls bekommt er das Rekruten-Add-on, wenn dieses akiviert ist.", "GodInfoLong": "(Neutrals):\nAs the God, you know everyone's role from the beginning. If you live until the end of the game, you steal the win, i.e., everyone else loses, and you win.", "InnocentInfoLong": "(Neutral):\nDer Unschuldige kann den Killknopf dazu benutzen, dass der markierte Spieler ihn killt. Wird der benutzte Spieler im Treffen gevotet, gewinnt der Unschuldige. Hinweis: Narr, Scharfrichter und Unschludiger können gemeinsam gewinnen.", "PelicanInfoLong": "(Neutral):\nAls der Pelikan kannst du den Killknopf drücken um Spieler lebend zu verschlucken, du teleportierst sie außerhalb der Karte aber killst sie noch nicht. Die, welche verschluckt wurden, werden nur sterben, wenn du am Ende der Runde lebst. Wenn du stirbst oder die Runde verlässt werden die Spieler dort auftauchen wo du warst.", @@ -883,7 +869,7 @@ "SolsticerInfoLong": "(Neutral):\nAls Sonnenwender wirst du nicht sterben und du gewinnst indem du all deine Aufgaben in einer Runde erledigst. Nach jedem Treffen setzen sich deine Aufgaben zurück und du musst von vorne anfangen.\nVotes an den Sonnenwender werden automatisch gelöscht.\nKillsversuche an den Sonnenwender teleportieren die Killer aus der Map so wie der Pelikan bis das nächste Treffen beendet ist.\nDie Killwartezeit vom Verräter wirden auf 10 Sekunden zurückgesetzt.\nSonnenwender gelten als nichts im Spiel.", "CollectorInfoLong": "(Neutrals):\nAs the Collector, when you vote for a player, for each other player that voted for them, you gain a point. When you collect the required votes, the game ends, and you win alone, even if you voted a Jester or Executioner's target out.", "GlitchInfoLong": "(Neutral):\nDer Glitcher kann Spieler hacken (Einzelklick) oder normal killen (Doppelklick).\nDerjenige, der gehackt wurde kann nicht killen, venten oder Leichenmelden für die Dauer der Hackzeit.\nZusätzlich, wenn du eine andere Sabotage außer Türen aktiveren willst, funktioniert dies nicht und du verwandelst duch zu einem zufälligen Spieler. Du kannst dich nicht während oder nach einer Sabotage verwandeln.\nUm zu gewinnen, musst du alleine überleben.", - "SidekickInfoLong": "(Neutrals):\nAs the Sidekick, your job is to help the Jackal kill everyone.\nYou and the Jackal win together.\nDepending on the settings, you may turn into Jackal if old Jackal was killed.\nYou may not be able to kill until old Jackal is dead.", + "SidekickInfoLong": "(Neutral):\nAls Kumpan ist es deine Aufgabe dem Schakal beim Killen zu helfen.", "ProvocateurInfoLong": "(Neutral):\nAls Provokateur kannst du jeden killen. Wenn dein Ziel verliert, gewinnst du mit dem Gewinner Team.", "BloodKnightInfoLong": "(Neutral):\nDer Blutritter gewinnt, wenn er der allerletzte Killer ist und die Anzahl der Besatzungsmitglieder niedriger ist, als Blutritter noch leben. Du kannst einen temporären Schild nach jedem Kill bekommen, das macht dich unverwundbar für ein paar Sekunden.", "PlagueBearerInfoLong": "(Neutral):\nAls Pestträger verpeste jeden in dem du dein Killknopf nutzt, um die Seuche zu werden.\nSobald du die Seuche bist, bist du unsterblich und bekommst die Fähigkeit zu killen immer dann wen jemand versucht dich zu Killen.\n\nWenn infizierte Spiele mit nicht infizierten Spielern in Kontakt treten werden diese infiziert.", @@ -910,12 +896,11 @@ "TraitorInfoLong": "(Neutral):\nDer Betrüger wurde von den Verrätern verraten.\nDu weißt wer die Verräter sind aber sie erkennen dich nicht,\nProblem? Sie können dich killen aber du nicht sie.\n\nBeseitige die Verräter auf andere Weise und kille dann alle um zu gewinnen!", "TrollerInfoLong": "(Neutrals):\nAs a Troller, you can complete tasks so that random events can happen to players.\nFor example, changing the speed of all players, teleportation, influencing sabotage, etc.\nAlso you can win with the winning team.", "VultureInfoLong": "(Neutral):\nAls Geier melde Leichen um zu gewinnen!\n\nWenn du eine Leiche meldest und deine Fresswartezeit ist um isst du die Leiche (sie kann nicht mehr gemeldet werden).\nWenn die Fresswartezeit in Wartezeit ist meldest du die Leiche normal.\n\nZustäzlich meldest du Leichen, wenn du die maximale Fressanzahl pro Runde erreicht hast.", - "AbyssbringerInfoLong": "(Impostors):\nAs the Abyssbringer, you can place black holes. Black holes will suck in players and kill them when colliding with them.", "TaskinatorInfoLong": "(Neutrals):\nAs the Taskinator, whenever you finish a task, the task will be bombed. When another player completes the bombed task, the bomb will detonate, and the player will die.\n\nYou win if you survive till the end and Crew doesn't win.\n\n Note: Taskinator bombs ignore all protection.", "BenefactorInfoLong": "(Besatzung):\nImmer wenn du als Gönner eine Aufgabe erledigst, wird diese markiert. Wenn ein anderer Spieler diese Aufgabe erledigt bekommt er ein temporäres Schild.\n\n Hinweis: Schilde schützen nur vor direkten Kills.", "MedusaInfoLong": "(Neutral):\nAls Medusa kannst du Leichen versteinern, so wie eine Leiche zu reinigen.\nVersteinerte Leichen können nicht gemeldet werden.\n\nKill alle um zu gewinnen.", "SpiritcallerInfoLong": "(Neutrals):\nAs the Spiritcaller, your victims become Evil Spirits after they die. These spirits can help you win by freezing other players briefly or blocking their vision. Alternatively, the spirits can give you a shield that protects you briefly from an attempted kill.", - "AmnesiacInfoLong": "(Neutrals):\nAs the Amnesiac, use your report button to remember a target and get its role.\nTo balance the game, you will not be able to vent after remembering your role if you can't vent as Amnesiac.'", + "AmnesiacInfoLong": "(Neutral):\nAls Dementer benutze den Meldeknopf um dir eine Rolle zu merken.\n\nWenn das Ziel ein Verräter war, wirst du zu einem Flüchtling.\nWenn das Ziel ein Besatzungsmitglied war, wirst du, sofern kompatibel, die Zielrolle (andernfalls wirst du Ingenieur).\nWenn das Ziel ein passiver Neutraler oder ein neutraler Killer war, übernehmimmst du die Rolle, die in den Einstellungen definiert ist.\nWenn das Ziel ein neutraler Mörder einiger weniger Auserwählter war, schlüpfst du in die Rolle, die der Spieler war.", "ImitatorInfoLong": "(Neutrals):\nAs the Imitator, use your kill button to imitate a player.\n\nYou'll either become a Sheriff, a Refugee, or some Neutral.", "BanditInfoLong": "(Neutrals):\nAs the Bandit, you can click your kill button one time to steal a player's addon and twice to kill. Depending on the settings, you may instantly steal the addon or after the meeting starts. After the maximum number of steals is reached, you will kill normally. Additionally, if there are no stealable addons on the target or the target is stubborn, you will kill the target.\n\nKill everyone to win.\n\nNote: Cleansed, Last Impostor, and Lovers cannot be stolen.\nNote: If Bandit can vent is on, Nimble will become unstealable.", "DoppelgangerInfoLong": "(Neutrals):\nAs the Doppelganger, use your kill button to steal a player's identity (their name and skin) and then kill your target.\n\nKill everyone to win.\n\nNote: You cannot steal the target's identity when Camouflage is active.", @@ -936,7 +921,6 @@ "JinxInfoLong": "(Neutrals):\nAs the Jinx, whenever you get attacked, you jinx them, resulting in them dying to a jinx.\nThis has limited uses.\n\nKill off everyone to win.", "PotionMasterInfoLong": "(Neutrals):\nAs the Potion Master, you have three different potions assigned to three different actions.\n\nSingle click: Reveal role\nDouble click: Kill\nMap: Sabotage\n\nThe reveal potion has a limit.\nWhen you run out, the kill buttons default to killing.", "NecromancerInfoLong": "(Neutrals):\nAs the Necromancer, you win when you're the last one standing.\nAdditionally when someone tries to kill you, you will block the kill, and you will teleport to a random vent. You will have a limited time to kill your killer. If you succeed in doing so, you live. If the time runs out before you kill your killer, you die permanently. If you try to kill someone else other than your killer, you will die.", - "ShockerInfoLong": "(Neutrals):\nAs the Shocker, you can mark rooms by doing tasks in them, and then vent to Electrocute anyone in those rooms for a set period of time. When you finish all of your tasks, you get new ones. Note: Doing tasks during that period will mark them for the next ability use.", "LastImpostorInfoLong": "(Add-ons):\nThis special effect is given to the last surviving Impostor. It significantly reduces their kill cooldown.", "OverclockedInfoLong": "(Add-ons):\nAs the Overclocked, your kill cooldown is reduced by a percentage.\n\nThis feature is only assigned to roles with a kill button.", "LoversInfoLong": "(Add-ons):\nLovers are a combination of two players. The Lovers win when they are the last ones standing, and their victory is shared. When one of the Lovers wins, the other also wins together. Lovers can see the 「♥」 next to each other's name. If one of the Lovers dies, the other will die in love (may not die in love according to the Host's settings). When one of the Lovers is exiled in the meeting, the other will die and become a dead body that cannot be reported.", @@ -980,7 +964,7 @@ "RebirthInfoLong": "(Add-ons):\nAs the Rebirth, if you're the player about to be ejected, you will swap skins with a random crewmate who voted for you.\nNotice: The host vote never counts\nRebirth will be removed from you if you exhausted all your rebirths.", "LoyalInfoLong": "(Add-on):\nals loyaler kannst du nicht rekrutiert werden vom Schakal oder Kultisten.\n\nKann keinem neutralen zugewiesen werden.", "EvilSpiritInfoLong": "(Add-ons):\nAs Evil Spirit, it's your job to help the Spiritcaller to victory. You can use your Haunt button to freeze players and reduce their vision. Alternatively, you can use your Haunt button to give the Spiritcaller a shield against a kill attempt temporarily.", - "RecruitInfoLong": "(Betrayal Add-ons):\nAs a recruit, you are on the Jackal's team and help out the Jackal and their Sidekicks.\nYou cannot win with your original team.\nDepending on the settings, you may turn into Jackal if old Jackal was killed and no sidekicks is alive.", + "RecruitInfoLong": "(Wirksame Add-ons):\nAls Kumpanrekrut gehörst du dem Schakalteam an und hilfst dem Schakal und seinen Kumpanen.", "AdmiredInfoLong": "(Betrayal Add-ons):\nAs an admired player, you win with the crew and not your original team.\n\nYou can see the Admirer.", "GlowInfoLong": "(Add-ons):\nDuring lights out, you and players nearby you will receive a vision boost.", "RadarInfoLong": "(Add-ons):\nAls Radar hast du immer Pfeile in die Richtung der Person, die dir am nächsten ist.", @@ -1024,7 +1008,6 @@ "ProhibitedInfoLong": "(Add-ons):\nAs the Prohibited, you have specific vents that you can't use.\nHow many vents are disabled depends on the Host's settings.", "EavesdropperInfoLong": "(Add-ons):\nAs the Eavesdropper, you have a chance to read other role/addon information-based messages like Mortician or Sleuth.", "ApocalypseInfoLong": "(Apocalypse):\nApocalypse members are on a separate team that works together and wins together. If there are multiple Apocalypse roles in the game, they can see each other's roles.\nDepending on the Host's settings, Apocalypse roles can guess or be guessed.", - "RevenantInfoLong": "(Neutral):\nAs the Revenant, your goal is to be killed. If you are killed, you will take your killer's role and kill your killer instead. You cannot win before being killed.\nNote that Revenant only works when being directly killed.", "ShowTextOverlay": "Text Overlay", "Overlay.GuesserMode": "Guessermodus", "Overlay.NoGameEnd": "Kein Spielende", @@ -1038,8 +1021,6 @@ "AbilityUseLimit": "Initial Ability Use Limit", "AbilityInUse": "Ability in use", "AbilityExpired": "Ability expired, {0} uses remain", - "RevenantTargeted": "Your role has changed to {0}", - "RevenantCanCopyAddons": "Can Steal Addons", "ShowArrows": "Has Arrows pointing toward bodies", "ArrowDelayMin": "Minimum Arrow show-up delay", "ArrowDelayMax": "Maximum Arrow show-up delay", @@ -1368,8 +1349,6 @@ "ShieldedCanUseKillButton": "Shielded player can use ability / kill button", "PlayerIsShieldedByGame": "Player is protected by the game!", "LegacyNemesis": "Ältere Version verwenden", - "LegacyParasite": "Use Legacy Version", - "LegacyTraitor": "Use Legacy Version", "ArsonistKeepsGameGoing": "Feuerteufel lässt das Spiel weiterlaufen", "ArsonistCanIgniteAnytime": "Kann jederzeit das Feuer entfachen", "ArsonistMinPlayersToIgnite": "Mindestbenötigte Übergießungen um zu Entfachen", @@ -1512,18 +1491,6 @@ "SheriffCanKillSeparately": "Individuelle Einstellungen", "In%team%": "(Team %team%)", "SheriffMisfireKillsTarget": "Fehlschuss tötet Ziel", - "BlackHolePlaceCooldown": "Black Hole Place Cooldown", - "BlackHoleDespawnMode": "Black Hole Despawn Mode", - "BlackHoleDespawnTime": "Time After Black Hole Despawns", - "Abyssbringer.Suffix": "<#00ffa5>Number of players consumed by {0} <#00ffa5>active black holes:\\n{1}", - "Abyssbringer.Suffix.BlackHole": "<#00ffa5>{0}: {1}", - "BlackHoleMovesTowardsNearestPlayer": "Black Hole Moves Towards Nearest Player", - "BlackHoleMoveSpeed": "Black Hole Moving Speed", - "BlackHoleRadius": "Black Hole Consuming Radius", - "AfterTime": "After Time", - "After1PlayerEaten": "After 1 Player Was Eaten", - "AfterMeeting": "After Meeting", - "None": "None", "SheriffShotLimit": "Max Anzahl an Schüssen", "SheriffCanKillAllAlive": "Kann killen wenn keiner tot ist", "SheriffCanKillCharmed": "Kann bekehrte Spieler killen", @@ -1540,15 +1507,12 @@ "RebirthUses": "Amount of Rebirths", "RebirthCountVotes": "Only rebirth to players who voted for them", "RebirthFailed": "Ahh, how unfortunate, you did not find any viable souls to swap bodies with", - "FireworkerCooldown": "Placement Cooldown", "ReverieIncreaseKillCooldown": "Erhöhe Killwartezeit", "ReverieMaxKillCooldown": "Maximale Killwartezeit", "ReverieMisfireSuicide": "Fehlschuss bei maximaler Killwartezeit", "ReverieResetCooldownMeeting": "Setze Killwartezeit nach Treffen zurück", "ConvertedReverieKillAll": "Konvertierter Träumer kann alle killen ohne Auswirkungen", "VigilanteNotify": "Du bist zu dem geworden, das du zerstören wolltest", - "DictatorChangeCommandToExpel": "Dictator use Command to expell instad of vote", - "DictatorExpelSelf": "WAIT WAIT WAIT WAT THE HELLLLLL Bro really just want to expel himself", "DoctorTaskCompletedBatteryCharge": "Batterielaufzeit", "SnitchEnableTargetArrow": "Zeige Pfeile zu den Zielen", "SnitchCanGetArrowColor": "Zeige farbige Pfeile basierend an den Teamfarben", @@ -1629,7 +1593,6 @@ "EvilTrackerTargetMode.OnceInGame": "Einmal pro Spiel", "EvilTrackerTargetMode.EveryMeeting": "Jedes Treffen", "EvilTrackerTargetMode.Always": "Jederzeit", - "ScavengerHasCustomDeathReason": "Enable Custom Death Reason", "EvilHackerCanSeeDeadMark": "Kann die Position von Leichen sehen", "EvilHackerCanSeeImpostorMark": "Kann die Position von Verrätern sehen", "EvilHackerCanSeeKillFlash": "Kann Killblitz sehen", @@ -1862,21 +1825,13 @@ "Jackal_SidekickCountMode_Jackal": "Schakal", "Jackal_SidekickCountMode_Original": "Ursprüngliches Team", "Jackal_SidekickAssignMode": "Kumpan -Zuweisungsmodus", - "Jackal_SidekickAssignMode_SidekickAndRecruit": "Sidekick when failed Recruit", - "Jackal_SidekickAssignMode_Sidekick": "Only Sidekick", - "Jackal_SidekickAssignMode_Recruit": "Only Recruit", + "Jackal_SidekickAssignMode_SidekickAndRecruit": "Kumpan+Rekrutiert", + "Jackal_SidekickAssignMode_Sidekick": "Nur Kumpan", + "Jackal_SidekickAssignMode_Recruit": "Nur Rekrutiert", + "JackalWinWithSidekick": "Schakal kann mit Kumpan -Team gewinnen", "Jackal_SidekickCanKillSidekick": "Kumpane können andere Kumpane killen", "Jackal_SidekickCanKillJackal": "Kumpan kann Schakal killen", - "Jackal_RecruitFailed": "You can not recruit this player!", "JackalCanKillSidekick": "Schakal kann Kumpan killen", - "Jackal_SidekickCanKillWhenJackalAlive": "Sidekick can kill while Jackal is Alive", - "Jackal_SidekickTurnIntoJackal": "Sidekick can turn into Jackal after its death", - "Jackal_RestoreLimitOnNewJackal": "Restore Recruit limit when Sidekick become new Jackal", - "Jackal_OnBecomeNewJackalMeeting": "The old Jackal {0} is dead.\nYou are selected as new Jackal\nWork together and win the game!", - "Jackal_OnNewJackalSelectedMeeting": "The old Jackal {0} is dead.\n{1} is selected as new Jackal!\nWork together and win the game!", - "Jackal_BecomeNewJackal": "Old Jackal Dead, You are now new Jackal!", - "Jackal_OnNewJackalSelected": "Old Jackal Dead, Please help new Jackal {0} for now!", - "Jackal_BossIsDead": "Opps, the Jackal boss is dead!", "CoronerArrowsPointingToDeadBody": "Pfeile zeigen zur Leiche", "CoronerLeaveDeadBodyUnreportable": "Leichen, die der Leichenbeschauer begutachtet hat, können nicht gemeldet werden", "CoronerInformKillerBeingTracked": "Informiere den Killer über seine Verfolgung", @@ -1914,9 +1869,6 @@ "VipTag": "VIP★", "ApplyVipList": "Apply VIP List", "AllowSayCommand": "Erlaube Moderatoren den /say -Befehl zu nutzen", - "AllowStartCommand": "Allow moderators to use /start command", - "StartCommandMinCountdown": "Minimum countdown for /start command", - "StartCommandMaxCountdown": "Maximum countdown for /start command", "KickCommandDisabled": "Der Kick-Befehl ist momentan deaktiviert.", "KickCommandNoAccess": "Du hast keinen Zugriff zum Kick-Befehl.", "KickCommandInvalidID": "Invalid player ID specified.\nPlease use '/kick [playerID] [reason]' to kick a player.\nExample :- /kick 5 not following rules", @@ -1949,11 +1901,6 @@ "WarnCommandNoAccess": "Du hast keinen Zugriff zum Warn-Befehl.", "WarnCommandInvalidID": "Falsche Spieler ID.\nNutze '/warn [Spieler ID] [Grund]' um einen Spieler zu warnen. \nBeispiel :- /warn 5 Lavachatting", "WarnCommandWarnHost": "Du bist nicht berechtigt, den Host zu verwarnen.", - "StartCommandNoAccess": "You do not have access to the start command.", - "StartCommandDisabled": "The start command is currently disabled.", - "StartCommandCountdown": "ERROR\n\nThe game is already starting!", - "StartCommandStarted": "The game has been started by {0}!", - "StartCommandInvalidCountdown": "ERROR\n\nThe countdown must be between {0} and {1}!", "WarnCommandWarnMod": "Du bist nicht berechtigt, andere Moderatoren zu verwarnen.", "WarnCommandWarned": "wurde verwarnt. Es werden keine weiteren Verwarnungen ausgesprochen und angemessene Reaktionen erfolgen \n ", "WarnExample": "Use /warn [id] [reason] in future. \nExample :-\n /warn 5 lava chatting", @@ -1981,7 +1928,6 @@ "DeathReason.Quantization": "Quantization", "DeathReason.Overtired": "Übermüdet", "DeathReason.Ashamed": "Ashamed", - "DeathReason.Consumed": "Consumed", "DeathReason.PissedOff": "Destroyed", "DeathReason.Dismembered": "Dismembered", "DeathReason.LossOfHead": "Strangled", @@ -2005,8 +1951,6 @@ "DeathReason.Starved": "Starved", "DeathReason.Equilibrium": "Equilibrium", "DeathReason.Sacrificed": "Sacrificed", - "DeathReason.Electrocuted": "Electrocuted", - "DeathReason.Scavenged": "Scavenged", "OnlyEnabledDeathReasons": "Only Enabled Death Reasons", "Alive": "Alive", "Disconnected": "Disconnected", @@ -2072,7 +2016,6 @@ "Command.dump": "→ Gib Protokoll auf den Desktop aus", "Command.death": "→ Zeige Informationen, wie du gestorben bist", "Command.icons": "
╳ - Der Spieler wurde vom Blackmailer markiert und kann während dem Treffen nicht reden.
☆ - Wird vom Captain genutzt damit er angezeigt werden kann. Nur Besatzungsmitglieder können den Captain's Stern sehen.
乂 - Dieser Spieler wurde vom Hex Master verhext und stirbt, wenn der Hex Master nicht gekillt wird oder oder das Treffen überlebt.
♦ - Wird von Lawyer, Executioner oder Follower genutzt.
♥ - Wird von Lovers oder Romantic genutzt.
✚ - Wird vom Medic zum Markieren des Zieles genutzt.
⦿ - Dieser Spieler ist im Duell mit dem Pirate.
!? - Dieser Spieler wurde vom Quizmaster und muss die Fragen richtig beantworten, um zu überleben.
☜ - Wird von Schrödinger's cat zum Markieren des Teamkollegen genutzt.
◈ - Dieser Spieler wurde vom Shroud markiert und stirbt, wenn der Shroud nicht gekillt wird oder oder das Treffen überlebt.
⚠ - Dieser Spieler ist ein Snitch oder Solsticer, der dessen Aufgaben erledigt hat.
★ - Wird von Super Star, Cyber oder Marshall genutzt.
† - Dieser Spieler wurde verhext und stirbt, wenn die Witch nicht gekillt wird oder oder das Treffen überlebt.
∇ - Wird vom Kamikaze zum Markieren des Zieles genutzt.
■ - Wird vom Lightning zum Markieren der Quantengeister genutzt.
⊠ - Wird vom Jailer zum Markieren der Gefängnisinsassen genutzt.
● - Wird vom Baker zum Markieren genutzt, wer Brot hat.
♠ - Wird vom Soul Collector zum Markieren für die genutzt, dessen Tod diese vorhersagen.
⦿ - Wird vom Plaguebearer zum Markieren der Verpesteten genutzt.", - "Command.start": "[Seconds] → Start the game", "Command.iconinfo": "→ Zeige Informationen über Treffensymbole", "Command.iconhelp": "→ Zeige öffentlich Informationen über Treffensymbole", "Command.Poll": "→ Start a poll with up-to 5 choices", @@ -2085,7 +2028,6 @@ "ShowMadmatesInLeftCommand": "Show Madmates (including add-ons)", "ShowApocalypseInLeftCommand": "Show Neutral Apocalypse", "SeeEjectedRolesInMeeting": "See ejected roles in meetings", - "ThankYouForUsingTOHE": "Thank you for using TOHE!", "SkillUsedLeft": "You have activated your skill to call a meeting. \nRemaining amount of uses left:", "NemesisDeadMsg": "Der Tod des Nemesis bedeutet der Anfang von der Rache. \nBitte nutze /rv + [Spieler ID] um einen bestimmten Spieler zu killen. \nDu kannst die Spieler IDs vor dem Namen sehen oder schreibe /rv um eine Liste der IDs zu sehen", "NemesisAliveKill": "Die Rache des Nemesis kann nur nach seinem Tod beginnen.", @@ -2105,7 +2047,6 @@ "GuessNotifiedBait": "Bait can't be guessed because it was announced. You thought it would be that easy, right?", "GuessGM": "Du kannst den GM nicht guessen, der ist schon tot... Warum würdest du das dem armen Host antun?", "GuessGuardianTask": "Du kannst den Wächter der seine Aufgaben abgeschlossen hat nicht guessen.", - "GuardianCantKilled": "You can't kill a Guardian who has finished their tasks.", "GuessMarshallTask": "Du kannst den Marschall der seine Aufgaben abgeschlossen hat nicht guessen.", "GuessObviousAddon": "Offenbarte Add-ons können nicht geguessed werden.", "GuessAdtRole": "Die Hosteinstellungen erlauben das Guessen für Add-ons nicht", @@ -2161,7 +2102,6 @@ "BecomeMadmateCuzMadmateMode": "Du bist aufgrund deines Todes zum Verräterhelfer geworden", "CleanerCleanBody": "Die Leiche wurde gereinigt", "QuickShooterStoraging": "Kugel gespeichert", - "QuickShooterFailed": "You are still in cooldown.", "PoisonerTargetDead": "Ziel gekillt", "HexesLookLikeSpells": "Hexes appear as spells", "HexButtonText": "Hex", @@ -2320,7 +2260,6 @@ "Message.YTPlanNotice": "Hinweis: Der [YouTuber Plan] ist aktiviert. Das heißt, der Host kann seine Rolle in der nächsten Runde selbst auswählen, damit es einfacher wird, Videomaterial zu bekommen. Wenn der Host diese Funktion falsch ausnutzt, verlasse das Spiel und melde es.\nAktueller Creatornachweis:", "Message.OnlyCanBeUsedByHost": "FEHLER\n\nDieser Befehl wird nur vom Host genutzt.", "Message.MaxPlayers": "Maximum players set to ", - "Message.MaxPlayersFailByRegion": "Could not set max players: Vanilla regions support a maximum of 15 players.", "Message.GhostRoleInfo": "Ghost Role Info\nHiya! A little about ghost roles...\n\nGhost roles drastically impact the game, so it's not recommended for smaller lobbies if you're unfamiliar. If not explicitly stated otherwise in the description, the Guard button is their ability button ;)\n\nSpawning:\nGhost-roles only spawn after death; the first x people from (team) to die get them.\n\nPS: If your previous role didn't have tasks(e.g., sheriff), your tasks as a ghost-role aren't needed for task-win", "ApocalypseInfoTitle": "Neutral Apocalypse Info:", "Message.ApocalypseInfo": "Every role of the <#ff174f>Apocalypse Team has their own objective to carry out in order to transform.\n<#2B0804>Transformed <#ff174f>Apocalypse members have a drastic change on the game and are immortal (except for being voted), but everyone will be notified that they have transformed.\n\nRoles: <#e5f6b4>Plaguebearer, <#A675A1>Soul Collector, <#bf9f7a>Baker, <#cc0044>Berserker\nTransformed: <#343136>Pestilence, <#644661>Death, <#83461c>Famine, <#2B0804>War\n\nApocalypse members can see eachother's roles and ability icons.\nLike Neutral Killers, Apocalypse members keep the game going as well, have fun!", @@ -2725,9 +2664,8 @@ "DeathMeetingTimeIncrease": "Increased Meeting time when Death exists", "SoulCollectorMeetingDeath": "Your target has died during the meeting. You have gained a soul.", "SoulCollectorKillButtonText": "Predict", - "SoulCollectorHasImpostorVision": "Soul Collector has Impostor vision", "ApocalypseIsNigh": "[ The Apocalypse Is Nigh! ]", - "ApocalypseImmune": "This role is immune!", + "ApocalypseImmune": "This player is immune because they are invincible!", "BakerToFamine": "You have become Famine!!!", "BakerTransform": "The Baker has transformed into Famine, Horseman of the Apocalypse! A famine has begun!", "BakerAlreadyBreaded": "That player already has bread!", @@ -2736,15 +2674,13 @@ "BakerBreadNeededToTransform": "Required number of bread to become Famine", "BakerCantBreadApoc": "You cannot give other Apocalypse members bread!", "BakerKillButtonText": "Bread", - "BakerUnshiftButtonText": "Switch Bread", "BakerRevealBread": "Reveal", "BakerRoleblockBread": "Roleblock", "BakerBarrierBread": "Barrier", "BakerCurrentBread": "Current Bread: ", "BakerSwitchBread": "Bread Switched to: ", - "BakerCanVent": "Baker can Vent", + "BakerCanVent": "Baker can Vent", "BakerBreadGivesEffects": "Bread gives additional effects", - "BakerTransformNoMoreBread": "Baker transforms if they do not have enough bread", "FamineKillButtonText": "Starve", "FamineStarveCooldown": "Famine starve cooldown", "FamineCantStarveApoc": "You cannot starve other Apocalypse members!", @@ -2791,7 +2727,6 @@ "GodfatherTargetCountMode": "Killer turns into", "GodfatherCount_Refugee": "Refugee", "GodfatherCount_Madmate": "Madmate", - "GodfatherRefugeeMsg": "You have been recruited by GodFather!", "MissChance": "Chance To Miss", "IncreaseByOneIfConvert": "Increase The KillCount +1 If a Crew Is Converted", "HawkMissed": "Verfehlt!", @@ -2824,7 +2759,6 @@ "BerserkerToWar": "You have become War!!!", "BerserkerTransform": "The Berserker has transformed into War, Horseman of the Apocalypse! Cry 'Havoc!', and let slip the dogs of war.", "WarKillCooldown": "War kill cooldown", - "BerserkerCanKillTeamate": "Can kill other Neutral Apocalypse", "BlackmailerSkillCooldown": "Erpresser Wartezeit", "BlackmailerMax": "Maximale Anzahl dem Sprechen von erpressten Spieler", "BlackmailerDead": "Achtung!{0} Wurde erpresst vom Erpresser!", @@ -2914,8 +2848,6 @@ "RememberedPursuer": "Du erinnerst dich, dass du ein Häscher bist!", "RememberedFollower": "Du erinnerst dich, dass du ein Folger bist!", "RememberedAmnesiac": "Du hast deine Rolle vergessen.", - "AmnesiacRemembered": "You remembered you were {0}!", - "ReportWhenFailedRemember": "Report Dead Body when failed to remember", "RememberedImitator": "You remembered you were an Imitator.", "RememberedImpostor": "Du erinnerst dich, dass du ein Verräter bist!", "RememberedCrewmate": "Du erinnerst dich, dass du ein Besatzungsmitglied bist!", @@ -3329,12 +3261,9 @@ "PixieTargetAlreadySelected": "Ziel ist bereits ausgewählt", "PixieButtonText": "Markieren", "PlagueBearerCooldown": "Pest Wartezeit", - "PlagueBearerCanVent": "Can vent", - "PlagueBearerHasImpostorVision": "Has Impostor vision", "PestilenceCooldown": "Seuche kill Wartezeit", "PestilenceCanVent": "Seuche kann venten", "PestilenceHasImpostorVision": "Seuche hat Verräter Sichtweite", - "PestilenceKillGuessers": "Kill players who guess Pestilence", "PlagueBearerAlreadyPlagued": "Spieler ist schon verpestet", "PlagueBearerToPestilence": "Du bist die Seuche geworden!!", "GuessPestilence": "Du hast versucht die Seuche zu killen!\n\nDie Seuche killte dich.", @@ -3378,7 +3307,6 @@ "EveryoneCanKnowMini": "Everyone can see the Mini", "CanBeEvil": "Mini can be an Impostor", "EvilMiniSpawnChances": "Probability of Mini being an Impostor", - "EvilMiniCanBeGuessed": "Evil Mini can be guessed before 18", "GuessMini": "Sorry, you can't hurt a kid Mini.", "GrowUpDuration": "Time required to grow (s)", "MajorCooldown": "Kill Cooldown when over 18", @@ -3520,7 +3448,6 @@ "WinnerRoleText.Doppelganger": "Doppelganger Wins!", "WinnerRoleText.Quizmaster": "Quizmaster Wins!", "WinnerRoleText.Agitater": "Hetzer gewinnt!", - "WinnerRoleText.Shocker": "Shocker Wins!", "AdditionalWinnerRoleText.Sidekick": "Kumpan", "AdditionalWinnerRoleText.Taskinator": "Taskinator", "AdditionalWinnerRoleText.Opportunist": "Opportunist", @@ -3606,7 +3533,7 @@ "SolsticerOnMeeting": "Du hast zu viele Tote überlebt! Nächste Runde wirst du {0} weitere kleinere Aufgaben haben!", "SolsticerTitle": "Sonnenwender", "GuessSolsticer": "Du kannst den Sonnenwender nicht guessen!", - "ExpelSolsticer": "Sorry, but you can not expel Solsticer!", + "VoteSolsticer": "Du kannst den Sonnenwender nicht voten!", "SolsticerTasksReset": "Deine Aufgaben werden zurückgesetzt!", "SolsticerMisGuessed": "Du hast dich verguesst! Du kannst daher nicht mehr guessen.", "SolsticerGuessMax": "Weil du dich verguesst hast, kannst du nicht mehr guessen.", @@ -3707,28 +3634,6 @@ "MinionAbilityTime": "Fähigkeitsdauer", "Minion_Blind": "erblindet", "Evader_ChanceNotExiled": "Chance not be exiled", - "ShockerAbilityCooldown": "Ability Cooldown", - "ShockerAbilityDuration": "Ability Duration", - "ShockerAbilityPerRound": "Abilities Per Round", - "ShockerShockInVents": "Shock people in vents", - "ShockerAbilityResetAfterMeeting": "Reset marked rooms after meeting", - "ShockerOutsideRadius": "Radius Of Outside Tasks (not in a room)", - "ShockerCanShockHimself": "Can Shock Himself", - "ShockerImpostorVision": "Shocker has Impostor vision", - "ShockerIsShocking": "You're already shocking!", - "ShockerAbilityActivate": "Begin Shocking!", - "ShockerAbilityDeactivate": "Ability Deactivated", - "ShockerVentButtonText": "Shock", - "ShockerRoomMarked": "Marked Room", "EavesdropperMsgTitle": "You found a secret", - "EavesdropPercentChance": "Chance to eavesdrop", - "ChiefOfPoliceSkillCooldown": "Cooldown for recruiting sheriffs", - "PolicCanImpostorAndNeutarl": "Can recruit Impostor or Neutral", - "SheriffSuccessfullyRecruited": "You recruited a sheriff.", - "BeSheriffByPolice": "You've been recruited by the police chief! Serve the crew!", - "PoliceFailedRecruit": "Failed to recruit target.", - "ChiefOfPoliceKillButtonText": "Recruitment", - "PolicPreventRecruitNonKiller": "Prevent recruit players without kill button", - "PolicSuidiceWhenTargetNotKiller": "Suidices when recruit a non killer or non crewmate", - "PolicPassConverted": "Can pass Converted Addon to Sheriff" -} \ No newline at end of file + "EavesdropPercentChance": "Chance to eavesdrop" +} diff --git a/Resources/Lang/en_US.json b/Resources/Lang/en_US.json index a68077068..a1329a43f 100644 --- a/Resources/Lang/en_US.json +++ b/Resources/Lang/en_US.json @@ -1,1550 +1,1563 @@ { - "LanguageID": "0", - "HostText": "Host", - "HostColor": "#902efd", - "IconColor": "#4bf4ff", - "Icon": "♥", - "NameColor": "#ffc0cb", - - "HideHostText": "Hide 'Host♥' Text", - "HideAllTagsAndText": "Hide All Tags (for «AutoMuteUs»)", - - "SupportUs": "Support Us", - "update": "Update", - "GitHub": "GitHub", - "Discord": "Discord", - "Website": "Website", - "PlayerNameForRoleInfo": "Hi {0}, your role is:- \n", - - "HostIconInMeeting": "HOST: {0}", - - "SubText.GM": "Spectate the chaos!", - "SubText.Crewmate": "Find and exile the Impostors", - "SubText.Impostor": "Sabotage and kill everyone", - "SubText.Neutral": "Work alone to achieve your victory", - "SubText.Apocalypse": "Become unstoppable with your team", - "SubText.Madmate": "Help the Impostors", + "LanguageID": "0", + "HostText": "Host", + "HostColor": "#902efd", + "IconColor": "#4bf4ff", + "Icon": "♥", + "NameColor": "#ffc0cb", + + "HideHostText": "Hide 'Host♥' Text", + "HideAllTagsAndText": "Hide All Tags (for «AutoMuteUs»)", + + "SupportUs": "Support Us", + "update": "Update", + "GitHub": "GitHub", + "Discord": "Discord", + "Website": "Website", + "PlayerNameForRoleInfo": "Hi {0}, your role is:- \n", + + "HostIconInMeeting": "HOST: {0}", + + "SubText.Crewmate": "Find and exile the Impostors", + "SubText.Impostor": "Sabotage and kill everyone", + "SubText.Neutral": "Work alone to achieve your victory", + "SubText.Apocalypse": "Become unstoppable with your team", + "SubText.Madmate": "Help the Impostors", "SubText.Lovers": "Stay alive and win together", "SubText.Egoist": "Win on your own", - "TypeImpostor": "Impostors", - "TypeCrewmate": "Crewmates", - "TypeNeutral": "Neutrals", - "TypeAddon": "Add-ons", - "GuesserMode": "Guesser Mode", + "TypeImpostor": "Impostors", + "TypeCrewmate": "Crewmates", + "TypeNeutral": "Neutrals", + "TypeAddon": "Add-ons", + "GuesserMode": "Guesser Mode", - "TeamImpostor": "Impostor", - "TeamNeutral": "Neutral", - "TeamCrewmate": "Crewmate", - "TeamMadmate": "Madmate", + "TeamImpostor": "Impostor", + "TeamNeutral": "Neutral", + "TeamCrewmate": "Crewmate", + "TeamMadmate": "Madmate", "TeamLovers": "Lovers", "TeamEgoist": "Egoist", "TeamApocalypse": "Apocalypse", - "YouAreCrewmate": "You are a Crewmate", - "YouAreImpostor": "You are an Impostor", - "YouAreNeutral": "You are a Neutral", - "YouAreMadmate": "You are a Madmate", - - - "Role_Crewmate": "Crewmate", - "Role_Jester": "Jester", - "Role_Opportunist": "Opportunist", - "Role_Celebrity": "Celebrity", - "Role_Bodyguard": "Bodyguard", - "Role_Dictator": "Dictator", - "Role_Mayor": "Mayor", - "Role_Doctor": "Doctor", - "Role_Maverick": "Maverick", - "Role_Pursuer": "Pursuer", - "Role_Follower": "Follower", - "Role_Amnesiac": "Amnesiac", - "Role_Imitator": "Imitator", - "Role_Sheriff": "Sheriff", - "Role_Knight": "Knight", - "Role_Deputy": "Deputy", - "Role_AdmiredImpostor": "Admired Impostor", - "Role_Trickster": "Trickster", - "Role_Traitor": "Traitor", - "Role_NoChange": "Don't change the role", - "Role_Random": "Random role from list", - - "CrewmatesCanGuess": "Crewmates can guess", - "ImpostorsCanGuess": "Impostors can guess", - "NeutralKillersCanGuess": "Neutral Killers can guess", - "NeutralApocalypseCanGuess": "Neutral Apocalypse can guess", - "PassiveNeutralsCanGuess": "Passive Neutrals can guess", - - "CanGuessAddons": "Can Guess Add-ons", - "ShowOnlyEnabledRolesInGuesserUI": "Show Only Enabled Roles In Guesser UI", - "CrewCanGuessCrew": "Crewmates Can Guess Crewmate Roles", - "ImpCanGuessImp": "Impostors Can Guess Impostor Roles", - "ApocCanGuessApoc": "Neutral Apocalypse Can Guess Neutral Apocalypse Roles", - "GuessImmune": "Sorry, but target is immune to being guessed!", - - - "GM": "Game Master", - "Sunnyboy": "Sunnyboy", - "Bard": "Bard", - "Crewmate": "Crewmate", - "CrewmateTOHE": "Crewmate", - "Engineer": "Engineer", - "EngineerTOHE": "Engineer", - "Scientist": "Scientist", - "ScientistTOHE": "Scientist", - "Noisemaker": "Noisemaker", - "NoisemakerTOHE": "Noisemaker", - "Tracker": "Tracker", - "TrackerTOHE": "Tracker", - "GuardianAngel": "Guardian Angel", - "GuardianAngelTOHE": "Guardian Angel", - "Impostor": "Impostor", - "ImpostorTOHE": "Impostor", - "Shapeshifter": "Shapeshifter", - "ShapeshifterTOHE": "Shapeshifter", - "Phantom": "Phantom", - "PhantomTOHE": "Phantom", - - "BountyHunter": "Bounty Hunter", - "Fireworker": "Fireworker", - "Mercenary": "Mercenary", - "ShapeMaster": "Shapemaster", - "Vampire": "Vampire", - "Warlock": "Warlock", - "Ninja": "Ninja", - "Zombie": "Zombie", - "Anonymous": "Anonymous", - "Miner": "Miner", - "KillingMachine": "Killing Machine", - "Escapist": "Escapist", - "Witch": "Witch", - "Nemesis": "Nemesis", - "Bloodmoon": "Bloodmoon", - "Possessor": "Possessor", - "Puppeteer": "Puppeteer", - "Mastermind": "Mastermind", - "TimeThief": "Time Thief", - "Sniper": "Sniper", - "Undertaker": "Undertaker", - "RiftMaker": "Rift Maker", - "EvilTracker": "Evil Tracker", - "EvilHacker": "Evil Hacker", - "EvilGuesser": "Evil Guesser", - "AntiAdminer": "Anti Adminer", - "Arrogance": "Arrogance", - "Bomber": "Bomber", - "Scavenger": "Scavenger", - "Trapster": "Trapster", - "Gangster": "Gangster", - "Cleaner": "Cleaner", - "Lightning": "Lightning", - "Greedy": "Greedy", - "CursedWolf": "Cursed Wolf", - "SoulCatcher": "Soul Catcher", - "QuickShooter": "Quick Shooter", - "Camouflager": "Camouflager", - "Eraser": "Eraser", - "Butcher": "Butcher", - "Hangman": "Hangman", - "Swooper": "Swooper", - "Crewpostor": "Crewpostor", - "Wildling": "Wildling", - "Trickster": "Trickster", - "Vindicator": "Vindicator", - "Parasite": "Parasite", - "Disperser": "Disperser", - "Inhibitor": "Inhibitor", - "Saboteur": "Saboteur", - "Councillor": "Councillor", - "Dazzler": "Dazzler", - "YinYanger": "YinYanger", - "Deathpact": "Deathpact", - "Devourer": "Devourer", - "Consigliere": "Consigliere", - "Morphling": "Morphling", - "Twister": "Twister", - "Lurker": "Lurker", - "Visionary": "Visionary", - "Refugee": "Refugee", - "Underdog": "Underdog", - "Ludopath": "Ludopath", - "Godfather": "Godfather", - "Chronomancer": "Chronomancer", - "Pitfall": "Pitfall", - "EvilMini": "Evil Mini", - "Blackmailer": "Blackmailer", - "Instigator": "Instigator", - "LazyGuy": "Lazy Guy", - "SuperStar": "Super Star", - "Celebrity": "Celebrity", - "Cleanser": "Cleanser", - "Keeper": "Keeper", - "Knight": "Knight", - "Mayor": "Mayor", - "Psychic": "Psychic", - "Mechanic": "Mechanic", - "Sheriff": "Sheriff", - "Vigilante": "Vigilante", - "Jailer": "Jailer", - "CopyCat": "Copycat", - "Snitch": "Snitch", - "Marshall": "Marshall", - "Doctor": "Doctor", - "Dictator": "Dictator", - "Detective": "Detective", - "NiceGuesser": "Nice Guesser", - "GuessMaster": "Guess Master", - "Transporter": "Transporter", - "TimeManager": "Time Manager", - "Spurt": "Spurt", - "Veteran": "Veteran", - "Bastion": "Bastion", - "Bodyguard": "Bodyguard", - "Deceiver": "Deceiver", - "Grenadier": "Grenadier", - "Medic": "Medic", - "FortuneTeller": "Fortune Teller", - "Judge": "Judge", - "Mortician": "Mortician", - "Medium": "Medium", - "Pacifist": "Pacifist", - "Observer": "Observer", - "Monarch": "Monarch", - "Overseer": "Overseer", - "Coroner": "Coroner", - "Merchant": "Merchant", - "President": "President", - "Hawk": "Hawk", - "Retributionist": "Retributionist", - "Deputy": "Deputy", - "Investigator": "Investigator", - "Guardian": "Guardian", - "Addict": "Addict", - "Mole": "Mole", - "Alchemist": "Alchemist", - "Tracefinder": "Tracefinder", - "Oracle": "Oracle", - "Spiritualist": "Spiritualist", - "Chameleon": "Chameleon", - "Inspector": "Inspector", - "Captain": "Captain", - "Admirer": "Admirer", - "TimeMaster": "Time Master", - "Crusader": "Crusader", - "Altruist": "Altruist", - "Reverie": "Reverie", - "Lookout": "Lookout", - "Telecommunication": "Telecommunication", - "Lighter": "Lighter", - "TaskManager": "Task Manager", - "Witness": "Witness", - "Swapper": "Swapper", + "YouAreCrewmate": "You are a Crewmate", + "YouAreImpostor": "You are an Impostor", + "YouAreNeutral": "You are a Neutral", + "YouAreMadmate": "You are a Madmate", + + + "Role_Crewmate": "Crewmate", + "Role_Jester": "Jester", + "Role_Opportunist": "Opportunist", + "Role_Celebrity": "Celebrity", + "Role_Bodyguard": "Bodyguard", + "Role_Dictator": "Dictator", + "Role_Mayor": "Mayor", + "Role_Doctor": "Doctor", + "Role_Maverick": "Maverick", + "Role_Pursuer": "Pursuer", + "Role_Follower": "Follower", + "Role_Amnesiac": "Amnesiac", + "Role_Imitator": "Imitator", + "Role_Sheriff": "Sheriff", + "Role_Knight": "Knight", + "Role_Deputy": "Deputy", + "Role_AdmiredImpostor": "Admired Impostor", + "Role_Trickster": "Trickster", + "Role_Traitor": "Traitor", + "Role_NoChange": "Don't change the role", + "Role_Random": "Random role from list", + + "CrewmatesCanGuess": "Crewmates can guess", + "ImpostorsCanGuess": "Impostors can guess", + "NeutralKillersCanGuess": "Neutral Killers can guess", + "NeutralApocalypseCanGuess": "Neutral Apocalypse can guess", + "PassiveNeutralsCanGuess": "Passive Neutrals can guess", + + "CanGuessAddons": "Can Guess Add-ons", + "ShowOnlyEnabledRolesInGuesserUI": "Show Only Enabled Roles In Guesser UI", + "CrewCanGuessCrew": "Crewmates Can Guess Crewmate Roles", + "ImpCanGuessImp": "Impostors Can Guess Impostor Roles", + "ApocCanGuessApoc": "Neutral Apocalypse Can Guess Neutral Apocalypse Roles", + "GuessImmune": "Sorry, but target is immune to being guessed!", + + + "GM": "Game Master", + "Sunnyboy": "Sunnyboy", + "Bard": "Bard", + "Crewmate": "Crewmate", + "CrewmateTOHE": "Crewmate", + "Engineer": "Engineer", + "EngineerTOHE": "Engineer", + "Scientist": "Scientist", + "ScientistTOHE": "Scientist", + "Noisemaker": "Noisemaker", + "NoisemakerTOHE": "Noisemaker", + "Tracker": "Tracker", + "TrackerTOHE": "Tracker", + "GuardianAngel": "Guardian Angel", + "GuardianAngelTOHE": "Guardian Angel", + "Impostor": "Impostor", + "ImpostorTOHE": "Impostor", + "Shapeshifter": "Shapeshifter", + "ShapeshifterTOHE": "Shapeshifter", + "Phantom": "Phantom", + "PhantomTOHE": "Phantom", + + "BountyHunter": "Bounty Hunter", + "Fireworker": "Fireworker", + "Mercenary": "Mercenary", + "ShapeMaster": "Shapemaster", + "Vampire": "Vampire", + "Warlock": "Warlock", + "Ninja": "Ninja", + "Zombie": "Zombie", + "Anonymous": "Anonymous", + "Miner": "Miner", + "KillingMachine": "Killing Machine", + "Escapist": "Escapist", + "Witch": "Witch", + "Nemesis": "Nemesis", + "Bloodmoon": "Bloodmoon", + "Possessor": "Possessor", + "Puppeteer": "Puppeteer", + "Mastermind": "Mastermind", + "TimeThief": "Time Thief", + "Sniper": "Sniper", + "Undertaker": "Undertaker", + "RiftMaker": "Rift Maker", + "EvilTracker": "Evil Tracker", + "EvilHacker": "Evil Hacker", + "EvilGuesser": "Evil Guesser", + "AntiAdminer": "Anti Adminer", + "Arrogance": "Arrogance", + "Bomber": "Bomber", + "Scavenger": "Scavenger", + "Trapster": "Trapster", + "Gangster": "Gangster", + "Cleaner": "Cleaner", + "Lightning": "Lightning", + "Greedy": "Greedy", + "CursedWolf": "Cursed Wolf", + "SoulCatcher": "Soul Catcher", + "QuickShooter": "Quick Shooter", + "Camouflager": "Camouflager", + "Eraser": "Eraser", + "Butcher": "Butcher", + "Hangman": "Hangman", + "Swooper": "Swooper", + "Crewpostor": "Crewpostor", + "Wildling": "Wildling", + "Trickster": "Trickster", + "Vindicator": "Vindicator", + "Parasite": "Parasite", + "Disperser": "Disperser", + "Inhibitor": "Inhibitor", + "Saboteur": "Saboteur", + "Councillor": "Councillor", + "Dazzler": "Dazzler", + "YinYanger": "YinYanger", + "Deathpact": "Deathpact", + "Devourer": "Devourer", + "Consigliere": "Consigliere", + "Morphling": "Morphling", + "Twister": "Twister", + "Lurker": "Lurker", + "Visionary": "Visionary", + "Refugee": "Refugee", + "Underdog": "Underdog", + "Ludopath": "Ludopath", + "Godfather": "Godfather", + "Chronomancer": "Chronomancer", + "Pitfall": "Pitfall", + "EvilMini": "Evil Mini", + "Blackmailer": "Blackmailer", + "Instigator": "Instigator", + "LazyGuy": "Lazy Guy", + "SuperStar": "Super Star", + "Celebrity": "Celebrity", + "Cleanser": "Cleanser", + "Keeper": "Keeper", + "Knight": "Knight", + "Mayor": "Mayor", + "Psychic": "Psychic", + "Mechanic": "Mechanic", + "Sheriff": "Sheriff", + "Vigilante": "Vigilante", + "Jailer": "Jailer", + "CopyCat": "Copycat", + "Snitch": "Snitch", + "Marshall": "Marshall", + "Doctor": "Doctor", + "Dictator": "Dictator", + "Detective": "Detective", + "NiceGuesser": "Nice Guesser", + "GuessMaster": "Guess Master", + "Transporter": "Transporter", + "TimeManager": "Time Manager", + "Spurt": "Spurt", + "Veteran": "Veteran", + "Bastion": "Bastion", + "Bodyguard": "Bodyguard", + "Deceiver": "Deceiver", + "Grenadier": "Grenadier", + "Medic": "Medic", + "FortuneTeller": "Fortune Teller", + "Judge": "Judge", + "Mortician": "Mortician", + "Medium": "Medium", + "Pacifist": "Pacifist", + "Observer": "Observer", + "Monarch": "Monarch", + "Overseer": "Overseer", + "Coroner": "Coroner", + "Merchant": "Merchant", + "President": "President", + "Hawk": "Hawk", + "Retributionist": "Retributionist", + "Deputy": "Deputy", + "Investigator": "Investigator", + "Guardian": "Guardian", + "Addict": "Addict", + "Mole": "Mole", + "Alchemist": "Alchemist", + "Tracefinder": "Tracefinder", + "Oracle": "Oracle", + "Spiritualist": "Spiritualist", + "Chameleon": "Chameleon", + "Inspector": "Inspector", + "Captain": "Captain", + "Admirer": "Admirer", + "TimeMaster": "Time Master", + "Crusader": "Crusader", + "Altruist": "Altruist", + "Reverie": "Reverie", + "Lookout": "Lookout", + "Telecommunication": "Telecommunication", + "Lighter": "Lighter", + "TaskManager": "Task Manager", + "Witness": "Witness", + "Swapper": "Swapper", "ChiefOfPolice": "Chief of Police", - "NiceMini": "Nice Mini", - "Mini": "Mini", - "Spy": "Spy", - "Randomizer": "Randomizer", - "Enigma": "Enigma", - "Jester": "Jester", - "Arsonist": "Arsonist", - "Pyromaniac": "Pyromaniac", - "Kamikaze": "Kamikaze", - "Huntsman": "Huntsman", - "Terrorist": "Terrorist", - "Executioner": "Executioner", - "Lawyer": "Lawyer", - "Opportunist": "Opportunist", - "Vector": "Vector", - "Jackal": "Jackal", - "God": "God", - "Innocent": "Innocent", - "Stealth": "Stealth", - "Penguin": "Penguin", - "Pelican": "Pelican", - "PlagueDoctor": "Plague Scientist", - "Revolutionist": "Revolutionist", - "Hater": "Hater", - "Demon": "Demon", - "Stalker": "Stalker", - "Workaholic": "Workaholic", - "Solsticer": "Solsticer", + "NiceMini": "Nice Mini", + "Mini": "Mini", + "Spy": "Spy", + "Randomizer": "Randomizer", + "Enigma": "Enigma", + "Jester": "Jester", + "Arsonist": "Arsonist", + "Pyromaniac": "Pyromaniac", + "Kamikaze": "Kamikaze", + "Huntsman": "Huntsman", + "Terrorist": "Terrorist", + "Executioner": "Executioner", + "Lawyer": "Lawyer", + "Opportunist": "Opportunist", + "Vector": "Vector", + "Jackal": "Jackal", + "God": "God", + "Innocent": "Innocent", + "Stealth": "Stealth", + "Penguin": "Penguin", + "Pelican": "Pelican", + "PlagueDoctor": "Plague Scientist", + "Revolutionist": "Revolutionist", + "Hater": "Hater", + "Demon": "Demon", + "Stalker": "Stalker", + "Workaholic": "Workaholic", + "LingeringPresence": "Lingering presence", + "FragileSoul": "Fragile soul", + "Evolver": "Evolver", + "FadingLight": "Fading Light", + "Solsticer": "Solsticer", "Abyssbringer": "Abyssbringer", - "Collector": "Collector", - "Provocateur": "Provocateur", - "BloodKnight": "Blood Knight", - "Apocalypse": "Apocalypse", - "PlagueBearer": "Plaguebearer", - "Pestilence": "Pestilence", - "SoulCollector": "Soul Collector", - "Death": "Death", - "Baker": "Baker", - "Famine": "Famine", - "Berserker": "Berserker", - "War": "War", - "Glitch": "Glitch", - "Sidekick": "Sidekick", - "Follower": "Follower", - "Cultist": "Cultist", - "SerialKiller": "Serial Killer", - "Juggernaut": "Juggernaut", - "Infectious": "Infectious", - "Virus": "Virus", - "Pursuer": "Pursuer", - "Specter": "Specter", - "Pirate": "Pirate", - "Agitater": "Agitator", - "Maverick": "Maverick", - "CursedSoul": "Cursed Soul", - "Pickpocket": "Pickpocket", - "Traitor": "Traitor", - "Troller": "Troller", - "Vulture": "Vulture", - "Taskinator": "Taskinator", - "Benefactor": "Benefactor", - "Medusa": "Medusa", - "Spiritcaller": "Spiritcaller", - "Amnesiac": "Amnesiac", - "Imitator": "Imitator", - "Bandit": "Bandit", - "Doppelganger": "Doppelganger", - "PunchingBag": "Punching Bag", - "Doomsayer": "Doomsayer", - "Shroud": "Shroud", - "Werewolf": "Werewolf", - "Shaman": "Shaman", - "Seeker": "Seeker", - "Pixie": "Pixie", - "Occultist": "Occultist", - "SchrodingersCat": "Schrodingers Cat", - "Romantic": "Romantic", - "VengefulRomantic": "Vengeful Romantic", - "RuthlessRomantic": "Ruthless Romantic", - "Poisoner": "Poisoner", - "HexMaster": "Hex Master", - "Wraith": "Wraith", - "Jinx": "Jinx", - "PotionMaster": "Potion Master", - "Necromancer": "Necromancer", - "Warden": "Warden", - "Minion": "Minion", - "Ghastly": "Ghastly", - "LastImpostor": "Last Impostor", - "Overclocked": "Overclocked", - "Lovers": "Lovers", - "Madmate": "Madmate", - "Watcher": "Watcher", - "Flash": "Flash", - "Torch": "Torch", - "Seer": "Seer", - "Tiebreaker": "Tiebreaker", - "Oblivious": "Oblivious", - "Rebirth": "Rebirth", - "Bewilder": "Bewilder", - "Workhorse": "Workhorse", - "Fool": "Fool", - "Avanger": "Avenger", - "Youtuber": "YouTuber", - "Egoist": "Egoist", - "Stealer": "Stealer", - "Paranoia": "Paranoia", - "Mimic": "Mimic", - "Guesser": "Guesser", - "Necroview": "Necroview", - "Reach": "Reach", - "Charmed": "Charmed", - "Cleansed": "Cleansed", - "Bait": "Bait", - "Trapper": "Beartrap", - "Infected": "Infected", - "Onbound": "Onbound", - "Rebound": "Rebound", - "Mundane": "Mundane", - "Knighted": "Knighted", - "Unreportable": "Disregarded", - "Contagious": "Contagious", - "Lucky": "Lucky", - "Unlucky": "Unlucky", - "VoidBallot": "Void Ballot", - "Aware": "Aware", - "Fragile": "Fragile", - "DoubleShot": "Double Shot", - "Rascal": "Rascal", - "Soulless": "Soulless", - "Gravestone": "Gravestone", - "Lazy": "Lazy", - "Autopsy": "Autopsy", - "Loyal": "Loyal", - "EvilSpirit": "Evil Spirit", - "Recruit": "Recruit", - "Admired": "Admired", - "Glow": "Glow", - "Radar": "Radar", - "Diseased": "Diseased", - "Antidote": "Antidote", - "Stubborn": "Stubborn", - "Swift": "Swift", - "Ghoul": "Ghoul", - "Bloodthirst": "Bloodthirst", - "Mare": "Mare", - "Burst": "Burst", - "Sleuth": "Sleuth", - "Clumsy": "Clumsy", - "Nimble": "Nimble", - "Circumvent": "Circumvent", - "Cyber": "Cyber", - "Hurried": "Hurried", - "Oiiai": "OIIAI", - "Influenced": "Influenced", - "Silent": "Silent", - "Susceptible": "Susceptible", - "Tricky": "Tricky", - "Rainbow": "Rainbow", - "Tired": "Tired", - "Statue": "Statue", - "Evader": "Evader", - "DollMaster": "Dollmaster", - "DoubleAgent": "Double Agent", - "Sloth": "Sloth", - "Prohibited": "Prohibited", - "Eavesdropper": "Eavesdropper", + "Collector": "Collector", + "Provocateur": "Provocateur", + "BloodKnight": "Blood Knight", + "Apocalypse": "Apocalypse", + "PlagueBearer": "Plaguebearer", + "Pestilence": "Pestilence", + "SoulCollector": "Soul Collector", + "Summoner": "Summoner", + "Summoned": "Summoned", + "Death": "Death", + "Baker": "Baker", + "Famine": "Famine", + "Berserker": "Berserker", + "War": "War", + "Glitch": "Glitch", + "Sidekick": "Sidekick", + "Follower": "Follower", + "Cultist": "Cultist", + "SerialKiller": "Serial Killer", + "Juggernaut": "Juggernaut", + "Infectious": "Infectious", + "Virus": "Virus", + "Pursuer": "Pursuer", + "Specter": "Specter", + "Pirate": "Pirate", + "Agitater": "Agitator", + "Maverick": "Maverick", + "CursedSoul": "Cursed Soul", + "Pickpocket": "Pickpocket", + "Traitor": "Traitor", + "Troller": "Troller", + "Vulture": "Vulture", + "Taskinator": "Taskinator", + "Benefactor": "Benefactor", + "Medusa": "Medusa", + "Spiritcaller": "Spiritcaller", + "Amnesiac": "Amnesiac", + "Imitator": "Imitator", + "Bandit": "Bandit", + "Doppelganger": "Doppelganger", + "PunchingBag": "Punching Bag", + "Doomsayer": "Doomsayer", + "Allergic": "Allergic", + "Shroud": "Shroud", + "Werewolf": "Werewolf", + "Shaman": "Shaman", + "Seeker": "Seeker", + "Pixie": "Pixie", + "Occultist": "Occultist", + "SchrodingersCat": "Schrodingers Cat", + "Romantic": "Romantic", + "VengefulRomantic": "Vengeful Romantic", + "RuthlessRomantic": "Ruthless Romantic", + "Poisoner": "Poisoner", + "HexMaster": "Hex Master", + "Wraith": "Wraith", + "Jinx": "Jinx", + "PotionMaster": "Potion Master", + "Necromancer": "Necromancer", + "Warden": "Warden", + "Minion": "Minion", + "Ghastly": "Ghastly", + "LastImpostor": "Last Impostor", + "Overclocked": "Overclocked", + "Lovers": "Lovers", + "Madmate": "Madmate", + "Watcher": "Watcher", + "Flash": "Flash", + "Torch": "Torch", + "Seer": "Seer", + "Tiebreaker": "Tiebreaker", + "Oblivious": "Oblivious", + "Rebirth": "Rebirth", + "Bewilder": "Bewilder", + "Workhorse": "Workhorse", + "Fool": "Fool", + "Avanger": "Avenger", + "Youtuber": "YouTuber", + "Egoist": "Egoist", + "Stealer": "Stealer", + "Paranoia": "Paranoia", + "Mimic": "Mimic", + "Guesser": "Guesser", + "Necroview": "Necroview", + "Reach": "Reach", + "Charmed": "Charmed", + "Cleansed": "Cleansed", + "Bait": "Bait", + "Trapper": "Beartrap", + "Infected": "Infected", + "Onbound": "Onbound", + "Rebound": "Rebound", + "Mundane": "Mundane", + "Knighted": "Knighted", + "Unreportable": "Disregarded", + "Contagious": "Contagious", + "Lucky": "Lucky", + "Unlucky": "Unlucky", + "VoidBallot": "Void Ballot", + "Aware": "Aware", + "Fragile": "Fragile", + "DoubleShot": "Double Shot", + "Rascal": "Rascal", + "Soulless": "Soulless", + "Gravestone": "Gravestone", + "Lazy": "Lazy", + "Autopsy": "Autopsy", + "Loyal": "Loyal", + "EvilSpirit": "Evil Spirit", + "Recruit": "Recruit", + "Admired": "Admired", + "Glow": "Glow", + "Radar": "Radar", + "Diseased": "Diseased", + "Antidote": "Antidote", + "Stubborn": "Stubborn", + "Swift": "Swift", + "Ghoul": "Ghoul", + "Bloodthirst": "Bloodthirst", + "Mare": "Mare", + "Burst": "Burst", + "Sleuth": "Sleuth", + "Clumsy": "Clumsy", + "Nimble": "Nimble", + "Circumvent": "Circumvent", + "Cyber": "Cyber", + "Hurried": "Hurried", + "Oiiai": "OIIAI", + "Influenced": "Influenced", + "Silent": "Silent", + "Susceptible": "Susceptible", + "Tricky": "Tricky", + "Rainbow": "Rainbow", + "Tired": "Tired", + "Statue": "Statue", + "Evader": "Evader", + "DollMaster": "Dollmaster", + "DoubleAgent": "Double Agent", + "Sloth": "Sloth", + "Prohibited": "Prohibited", + "Eavesdropper": "Eavesdropper", "Shocker": "Shocker", "Revenant": "Revenant", - "BracketAddons": "Add Brackets To Add-ons", - "EngineerTOHEInfo": "Use the vents to catch the Impostors", - "ScientistTOHEInfo": "Access portable vitals from anywhere", - "NoisemakerTOHEInfo": "Send out an alert when killed", - "TrackerTOHEInfo": "Track players with your map", - "ShapeshifterTOHEInfo": "Disguise as crewmates to frame them", - "PhantomTOHEInfo": "Turn invisible", - "GuardianAngelTOHEInfo": "Protect the crewmates from the Impostors", - "ImpostorTOHEInfo": "Kill and sabotage", - "CrewmateTOHEInfo": "Search for the Impostors", - "BountyHunterInfo": "Eliminate your target", - "FireworkerInfo": "Go out with a BANG", - "MercenaryInfo": "Keep killing, else you suicide", - "ShapeMasterInfo": "Swiftly kill with no shift cooldown", - "VampireInfo": "Your kills are delayed", - "WarlockInfo": "Curse crewmates then shift to make them kill", - "NinjaInfo": "Mark a target, then shift to kill", - "ZombieInfo": "You are very slow", - "AnonymousInfo": "Force a player to report a body", - "MinerInfo": "Warp to your last used vent by shifting", - "KillingMachineInfo": "You can ONLY kill, but low cooldown", - "EscapistInfo": "Shift to mark places and warp back to them", - "WitchInfo": "Spell crewmates to kill them in meetings", - "NemesisInfo": "Kill when you're the last Impostor", - "BeforeNemesisInfo": "You can't kill yet", - "AfterNemesisInfo": "Now start killing", - "BloodmoonInfo": "Seek havoc upon the crewmates", - "PossessorInfo": "Possess and lead crewmates away from others", - "PuppeteerInfo": "Make players kill for you", - "MastermindInfo": "Make others kill for you", - "TimeThiefInfo": "Lower meeting time by killing", - "SniperInfo": "Snipe players from a distance by shifting", - "UndertakerInfo": "Teleport dead body to a marked location", - "RiftMakerInfo": "Two rifts I trace, touch 'em to warp space", - "EvilTrackerInfo": "Track players by shifting", - "EvilHackerInfo": "Hack systems", - "AntiAdminerInfo": "Know when players are near devices", - "ArroganceInfo": "With each kill you make, your cooldown decreases", - "BomberInfo": "Shapeshift to explode", - "TrapsterInfo": "Trap your kills", - "ScavengerInfo": "Your kills are unreportable", - "EvilGuesserInfo": "Guess crew roles in meetings to kill", - "GangsterInfo": "Convert players to your side", - "CleanerInfo": "Report bodies to make them unreportable", - "LightningInfo": "Convert players to Quantum Ghosts", - "GreedyInfo": "Your kill cooldown shifts", - "CursedWolfInfo": "You survive a few kill attempts", - "SoulCatcherInfo": "You swap places with your shift target", - "QuickShooterInfo": "Store ammo to offset kill cooldown", - "CamouflagerInfo": "Camouflage everyone for easy kills", - "EraserInfo": "Erase the role of your vote target", - "ButcherInfo": "Enjoy my beautiful work", - "HangmanInfo": "I will decide when your life will end", - "SwooperInfo": "Turn invisible temporarily", - "CrewpostorInfo": "Kill by completing tasks", - "WildlingInfo": "Kill with strength and disguise", - "TricksterInfo": "Kill and trick the crew", - "VindicatorInfo": "Use your extra votes to kill everyone", - "ParasiteInfo": "Help the Impostors kill the crew", - "DisperserInfo": "Teleport everyone to random vents", - "InhibitorInfo": "You cannot kill during sabotages", - "SaboteurInfo": "You can only kill during sabotages", - "CouncillorInfo": "Kill off crewmates during meetings", - "DazzlerInfo": "Reduce the vision of the crew", - "DeathpactInfo": "Assign players to a death pact", - "DevourerInfo": "Consume the skin of the crew", - "ConsigliereInfo": "Discover the roles of other players", - "MorphlingInfo": "You can only kill while shapeshifted", - "TwisterInfo": "Swap all player positions", - "LurkerInfo": "Reduce your kill cooldown by venting", - "ConvictInfo": "Your target died, now help the Impostors", - "VisionaryInfo": "You see the alignments of the living", - "RefugeeInfo": "Help the Impostors kill off the crew", - "UnderdogInfo": "Start killing on a low player count", - "LudopathInfo": "Your kill cooldown is random", - "GodfatherInfo": "Convert players to Refugees by voting", - "ChronomancerInfo": "Kill in bursts", - "PitfallInfo": "Setup traps around the map", - "EvilMiniInfo": "No one can hurt you until you grow up", - "BlackmailerInfo": "Silence other players", - "InstigatorInfo": "Sow discord among the crewmates", - "LazyGuyInfo": "You're too lazy", - "SuperStarInfo": "Everyone knows you", - "CleanserInfo": "Erase All Add-ons of your vote target", - "KeeperInfo": "Reject the Eject, Keeper Protect!", - "MayorInfo": "Your vote counts multiple times", - "PsychicInfo": "One of the red names is evil", - "MechanicInfo": "Vent around and fix sabotages", - "SheriffInfo": "Shoot the Impostors", - "VigilanteInfo": "Not the hero we deserved but the hero we needed", - "JailerInfo": "Jail suspicious players", - "CopyCatInfo": "Use kill button to copy target's role", - "SnitchInfo": "Finish your tasks to find the Impostors", - "MarshallInfo": "Finish your tasks to prove your innocence", - "DoctorInfo": "Know how each player died", - "DictatorInfo": "Exile a player based on your judgment", - "DetectiveInfo": "Gain extra info from your body reports", - "UndercoverInfo": "Impostors see you as their partner", - "KnightInfo": "You can kill one player", - "NiceGuesserInfo": "Guess Impostor roles in meetings to kill", - "GuessMasterInfo": "Whispers heard, every guessed word.", - "TransporterInfo": "Do tasks to swap two players' locations", - "TimeManagerInfo": "Increase meeting time by doing tasks", - "VeteranInfo": "Alert to kill anyone who interacts with you", - "BastionInfo": "Bomb vents", - "YinYangerInfo": "Spontaneously combust two players", - "BodyguardInfo": "Prevent nearby kills", - "DeceiverInfo": "Try to fool the players", - "GrenadierInfo": "Reduce Impostors' vision by venting", - "MedicInfo": "Cast a shield onto a player", - "FortuneTellerInfo": "Get clues to people's roles", - "JudgeInfo": "Silence in the courtroom!", - "MorticianInfo": "Locate dead bodies", - "MediumInfo": "Talk with ghosts", - "ObserverInfo": "You can see all shield-animations", - "PacifistInfo": "Vent to reset kill cooldowns", - "RebirthInfo": "Arise Again", - "MonarchInfo": "Give your crew extra voting power!", + "BracketAddons": "Add Brackets To Add-ons", + "EngineerTOHEInfo": "Use the vents to catch the Impostors", + "ScientistTOHEInfo": "Access portable vitals from anywhere", + "NoisemakerTOHEInfo": "Send out an alert when killed", + "TrackerTOHEInfo": "Track players with your map", + "ShapeshifterTOHEInfo": "Disguise as crewmates to frame them", + "PhantomTOHEInfo": "Turn invisible", + "GuardianAngelTOHEInfo": "Protect the crewmates from the Impostors", + "ImpostorTOHEInfo": "Kill and sabotage", + "CrewmateTOHEInfo": "Search for the Impostors", + "BountyHunterInfo": "Eliminate your target", + "FireworkerInfo": "Go out with a BANG", + "MercenaryInfo": "Keep killing, else you suicide", + "ShapeMasterInfo": "Swiftly kill with no shift cooldown", + "VampireInfo": "Your kills are delayed", + "WarlockInfo": "Curse crewmates then shift to make them kill", + "NinjaInfo": "Mark a target, then shift to kill", + "ZombieInfo": "You are very slow", + "AnonymousInfo": "Force a player to report a body", + "MinerInfo": "Warp to your last used vent by shifting", + "KillingMachineInfo": "You can ONLY kill, but low cooldown", + "EscapistInfo": "Shift to mark places and warp back to them", + "WitchInfo": "Spell crewmates to kill them in meetings", + "NemesisInfo": "Kill when you're the last Impostor", + "BeforeNemesisInfo": "You can't kill yet", + "AfterNemesisInfo": "Now start killing", + "BloodmoonInfo": "Seek havoc upon the crewmates", + "PossessorInfo": "Possess and lead crewmates away from others", + "PuppeteerInfo": "Make players kill for you", + "MastermindInfo": "Make others kill for you", + "TimeThiefInfo": "Lower meeting time by killing", + "SniperInfo": "Snipe players from a distance by shifting", + "UndertakerInfo": "Teleport dead body to a marked location", + "RiftMakerInfo": "Two rifts I trace, touch 'em to warp space", + "EvilTrackerInfo": "Track players by shifting", + "EvilHackerInfo": "Hack systems", + "AntiAdminerInfo": "Know when players are near devices", + "ArroganceInfo": "With each kill you make, your cooldown decreases", + "BomberInfo": "Shapeshift to explode", + "TrapsterInfo": "Trap your kills", + "ScavengerInfo": "Your kills are unreportable", + "EvilGuesserInfo": "Guess crew roles in meetings to kill", + "GangsterInfo": "Convert players to your side", + "CleanerInfo": "Report bodies to make them unreportable", + "LightningInfo": "Convert players to Quantum Ghosts", + "GreedyInfo": "Your kill cooldown shifts", + "CursedWolfInfo": "You survive a few kill attempts", + "SoulCatcherInfo": "You swap places with your shift target", + "QuickShooterInfo": "Store ammo to offset kill cooldown", + "CamouflagerInfo": "Camouflage everyone for easy kills", + "EraserInfo": "Erase the role of your vote target", + "ButcherInfo": "Enjoy my beautiful work", + "HangmanInfo": "I will decide when your life will end", + "SwooperInfo": "Turn invisible temporarily", + "CrewpostorInfo": "Kill by completing tasks", + "WildlingInfo": "Kill with strength and disguise", + "TricksterInfo": "Kill and trick the crew", + "VindicatorInfo": "Use your extra votes to kill everyone", + "ParasiteInfo": "Help the Impostors kill the crew", + "DisperserInfo": "Teleport everyone to random vents", + "InhibitorInfo": "You cannot kill during sabotages", + "SaboteurInfo": "You can only kill during sabotages", + "CouncillorInfo": "Kill off crewmates during meetings", + "DazzlerInfo": "Reduce the vision of the crew", + "DeathpactInfo": "Assign players to a death pact", + "DevourerInfo": "Consume the skin of the crew", + "ConsigliereInfo": "Discover the roles of other players", + "MorphlingInfo": "You can only kill while shapeshifted", + "TwisterInfo": "Swap all player positions", + "LurkerInfo": "Reduce your kill cooldown by venting", + "ConvictInfo": "Your target died, now help the Impostors", + "VisionaryInfo": "You see the alignments of the living", + "RefugeeInfo": "Help the Impostors kill off the crew", + "UnderdogInfo": "Start killing on a low player count", + "LudopathInfo": "Your kill cooldown is random", + "GodfatherInfo": "Convert players to Refugees by voting", + "ChronomancerInfo": "Kill in bursts", + "PitfallInfo": "Setup traps around the map", + "EvilMiniInfo": "No one can hurt you until you grow up", + "BlackmailerInfo": "Silence other players", + "InstigatorInfo": "Sow discord among the crewmates", + "LazyGuyInfo": "You're too lazy", + "SuperStarInfo": "Everyone knows you", + "CleanserInfo": "Erase All Add-ons of your vote target", + "KeeperInfo": "Reject the Eject, Keeper Protect!", + "MayorInfo": "Your vote counts multiple times", + "PsychicInfo": "One of the red names is evil", + "MechanicInfo": "Vent around and fix sabotages", + "SheriffInfo": "Shoot the Impostors", + "VigilanteInfo": "Not the hero we deserved but the hero we needed", + "JailerInfo": "Jail suspicious players", + "CopyCatInfo": "Use kill button to copy target's role", + "SnitchInfo": "Finish your tasks to find the Impostors", + "MarshallInfo": "Finish your tasks to prove your innocence", + "DoctorInfo": "Know how each player died", + "DictatorInfo": "Exile a player based on your judgment", + "DetectiveInfo": "Gain extra info from your body reports", + "UndercoverInfo": "Impostors see you as their partner", + "KnightInfo": "You can kill one player", + "NiceGuesserInfo": "Guess Impostor roles in meetings to kill", + "GuessMasterInfo": "Whispers heard, every guessed word.", + "TransporterInfo": "Do tasks to swap two players' locations", + "TimeManagerInfo": "Increase meeting time by doing tasks", + "VeteranInfo": "Alert to kill anyone who interacts with you", + "BastionInfo": "Bomb vents", + "YinYangerInfo": "Spontaneously combust two players", + "BodyguardInfo": "Prevent nearby kills", + "DeceiverInfo": "Try to fool the players", + "GrenadierInfo": "Reduce Impostors' vision by venting", + "MedicInfo": "Cast a shield onto a player", + "FortuneTellerInfo": "Get clues to people's roles", + "JudgeInfo": "Silence in the courtroom!", + "MorticianInfo": "Locate dead bodies", + "MediumInfo": "Talk with ghosts", + "ObserverInfo": "You can see all shield-animations", + "PacifistInfo": "Vent to reset kill cooldowns", + "RebirthInfo": "Arise Again", + "MonarchInfo": "Give your crew extra voting power!", "AbyssbringerInfo": "Place Black Holes", - "SpurtInfo": "Spring Like A rabbit!", - "StealthInfo": "Killing Blinds Everyone in the Room", - "PenguinInfo": "Drag your victims", - "OverseerInfo": "Reveal roles of other players", - "CoronerInfo": "Find corpses and their killers", - "PresidentInfo": "You are in charge of the meeting", - "MerchantInfo": "Sell add-ons and bribe killers", - "RetributionistInfo": "Help the crew after you die", - "HawkInfo": "Seek murdering the bad guys!", - "DeputyInfo": "Handcuff killers to increase their cooldowns", - "InvestigatorInfo": "Find potential evils", - "GuardianInfo": "Complete your tasks to become immortal", - "AddictInfo": "Vent to become invulnerable, or you'll die", - "MoleInfo": "Vanish and reappear, the Mole's game is crystal clear!", - "AlchemistInfo": "Brew potions by completing tasks", - "TracefinderInfo": "Sense the location of dead bodies", - "OracleInfo": "Vote a player to see their alignment", - "SpiritualistInfo": "Be guided by the ghostly life", - "ChameleonInfo": "Vent to disguise into your surroundings", - "InspectorInfo": "Validate the alignments of two players", - "CaptainInfo": "Sail with the Captain, lest add-ons be abandoned.", - "AdmirerInfo": "Choose a player to side with you", - "TimeMasterInfo": "Rewind time!", - "CrusaderInfo": "Kill a player's attacker", - "AltruistInfo": "Revive a player", - "ReverieInfo": "With each kill, your cooldown decreases", - "LookoutInfo": "See through disguises", - "TelecommunicationInfo": "Track device usage", - "LighterInfo": "Catch killers with your enhanced vision", - "TaskManagerInfo": "See the total tasks completed in real-time", - "WitnessInfo": "Find out if someone killed recently", - "GhastlyInfo": "Control somebody!", - "SwapperInfo": "Swap the votes of two players", - "ChiefOfPoliceInfo": "Hire Sheriff to Serve the Crews!", - "NiceMiniInfo": "No one can hurt you until you grow up.", - "ArsonistInfo": "Douse everyone and ignite", - "PyromaniacInfo": "Douse and kill everyone", - "HuntsmanInfo": "Kill your targets for a low cooldown", - "SpyInfo": "You know who interacts with you", - "RandomizerInfo": "You're going to be someone's burden when you die?", - "EnigmaInfo": "Get Clues about Killers", - "JesterInfo": "Get voted out", - "OpportunistInfo": "Stay alive until the end", - "TerroristInfo": "Finish your tasks, THEN die", - "ExecutionerInfo": "Get your target voted out", - "LawyerInfo": "Help your target win!", - "VectorInfo": "Jump in! Jump out!", - "JackalInfo": "Murder everyone", - "GodInfo": "Everything is under your control", - "InnocentInfo": "Get someone ejected by making them kill you", - "PelicanInfo": "Eat all players", - "RevolutionistInfo": "Recruit players to win with you", - "HaterInfo": "Kill Lovers and Neptunes", - "DemonInfo": "Consume blood volumes", - "StalkerInfo": "Descend into the darkness, release fear!", - "WorkaholicInfo": "Finish all tasks to win solo!", - "SolsticerInfo": "Speed run all your tasks!", - "CollectorInfo": "Collect votes from players", - "ProvocateurInfo": "Victory with help target", - "BloodKnightInfo": "Killing gives you a temporary shield", - "PlagueBearerInfo": "Plague everyone to turn into Pestilence", - "PestilenceInfo": "Obliterate everyone!", - "SoulCollectorInfo": "Predict deaths to collect souls", - "DeathInfo": "Enact Armageddon", - "BakerInfo": "Feed Players Bread to become Famine", - "FamineInfo": "Starve Everyone", - "BerserkerInfo": "Kill to increase your level", - "WarInfo": "Destroy everything", - "GlitchInfo": "Hack and kill everyone", - "SidekickInfo": "Help the Jackal kill everyone", - "FollowerInfo": "Follow a player and help them", - "CultistInfo": "Charm everyone", - "SerialKillerInfo": "Kill off everyone to win!", - "JuggernautInfo": "With each kill, your cooldown decreases", - "InfectiousInfo": "Infect everyone", - "VirusInfo": "Kill and infect everyone", - "PursuerInfo": "Protect yourself and live to the end!", - "PlagueDoctorInfo": "Spread the infection!", - "SpecterInfo": "Get killed and finish your tasks to win!", - "PirateInfo": "Successfully plunder players to win", - "AgitaterInfo": "Pass a Bomb onto others", - "MaverickInfo": "Kill and survive to the end", - "CursedSoulInfo": "Snatch souls and steal the win", - "PickpocketInfo": "Steal votes from your kills", - "TraitorInfo": "Eliminate the Impostors, then win", - "TrollerInfo": "Make random event by complete task", - "VultureInfo": "Eat bodies by reporting to win", - "TaskinatorInfo": "Silent tasks, deadly blasts", - "BenefactorInfo": "Task complete, shield elite!", - "MedusaInfo": "Stone bodies by reporting them", - "SpiritcallerInfo": "Turn Players into Evil Spirits", - "AmnesiacInfo": "Remember the role of a dead body", - "ImitatorInfo": "Imitate a player's role", - "BanditInfo": "Rob a player's add-on", - "DoppelgangerInfo": "Steal your target's identity", - "PunchingBagInfo": "Get attacked a few times to win!", - "KamikazeInfo": "Kill players with a suicidal mission", - "DoomsayerInfo": "Successfully guess players to win", - "ShroudInfo": "Shroud players to make them kill", - "WerewolfInfo": "Kill crewmates in groups", - "ShamanInfo": "Deflect all the attacks on Voodoo doll", - "SeekerInfo": "Play Hide and Seek with your target", - "PixieInfo": "Tag 'em, Bag 'em, and Eject 'em!", - "OccultistInfo": "Kill and curse your enemies", - "SchrodingersCatInfo": "The cat is both alive and dead until observed.", - "RomanticInfo": "Protect your partner to win together", - "VengefulRomanticInfo": "Revenge your partner to win together", - "RuthlessRomanticInfo": "Kill everyone to win with your partner", - "PoisonerInfo": "Kill everyone with delayed kills", - "HexMasterInfo": "Hex players to kill them in meetings", - "WraithInfo": "Vent to go invisible temporarily", - "JinxInfo": "Reflect attacks onto your attackers", - "PotionMasterInfo": "Use your potions to your advantage", - "NecromancerInfo": "Kill your killer to defy death", - "WardenInfo": "(Ghost) Alert about danger", - "MinionInfo": "(Ghost) Blind enemies", - "LoversInfo": "Stay alive and win together", - "MadmateInfo": "Help the Impostors", - "WatcherInfo": "You see all the colors of votes", - "LastImpostorInfo": "Lower kill cooldown", - "OverclockedInfo": "Lower cooldown", - "FlashInfo": "You're faster", - "TorchInfo": "You have enhanced vision!", - "SeerInfo": "You are alerted when somebody has died", - "TiebreakerInfo": "Break tied votes", - "ObliviousInfo": "You can't report bodies", - "BewilderInfo": "A twist of vision, a web of confusion", - "WorkhorseInfo": "Be the first to complete all tasks and get more", - "FoolInfo": "You can't fix sabotages", - "AvangerInfo": "You take someone with you upon death", - "YoutuberInfo": "Get killed first to win", - "CelebrityInfo": "Everyone knows when you die", - "EgoistInfo": "Win on your own", - "StealerInfo": "Gain votes with kills", - "ParanoiaInfo": "You're dead and alive simultaneously", - "MimicInfo": "Reveal killed players' roles to impostors upon death", - "GuesserInfo": "Guess roles of players in meetings to kill", - "NecroviewInfo": "See the team of the dead", - "ReachInfo": "You have a longer kill range", - "BaitInfo": "Your killer self-reports your body", - "TrapperInfo": "Freeze your killer for a few seconds", - "OnboundInfo": "You can't be guessed", - "ReboundInfo": "Guess me right, and face your plight!", - "MundaneInfo": "Tasks all done, guessing's begun.", - "UnreportableInfo": "Your body can't be reported", - "LuckyInfo": "Dodge attackers", - "DoubleShotInfo": "You have an extra life when guessing", - "RascalInfo": "You appear evil in some cases", - "SoullessInfo": "You have no soul", - "GravestoneInfo": "Your role is revealed when you die", - "LazyInfo": "You're too lazy", - "AutopsyInfo": "You see how others died", - "LoyalInfo": "You cannot be recruited", - "EvilSpiritInfo": "You are an evil Spirit", - "RecruitInfo": "Help the Jackal", - "AdmiredInfo": "The Admirer chose you as their love", - "GlowInfo": "You glow in the dark", - "RadarInfo": "Arrow's hue, closest to you!", - "DiseasedInfo": "Increase the cooldown of the player who interacts with you", - "AntidoteInfo": "Decrease the cooldown of the player who interacts with you", - "StubbornInfo": "Protect your role and add-ons", - "SwiftInfo": "Your kills don't cause a lunge", - "UnluckyInfo": "Doing things has a chance to kill you", - "VoidBallotInfo": "Your vote count is 0", - "AwareInfo": "Know who revealed your role", - "FragileInfo": "Die instantly if someone uses the kill button on you", - "GhoulInfo": "Kill your killer after dying", - "BloodthirstInfo": "Become bloodthirsty and kill", - "MareInfo": "Kill in the darkness", - "BurstInfo": "Make your killer burst!", - "SleuthInfo": "Gain info from dead bodies", - "ClumsyInfo": "You have a chance to miss your kill", - "NimbleInfo": "You can vent!", - "CircumventInfo": "You can no longer vent", - "OiiaiInfo": "OIIAIOIIIAI", - "CyberInfo": "You're popular!", - "HurriedInfo": "God, I got too much stuff!", - "InfluencedInfo": "You lack decisiveness!", - "SilentInfo": "Vote like a Ghost!", - "SusceptibleInfo": "Death-reason lotto!", - "TrickyInfo": "Tricky slays, in mysterious ways.", - "TiredInfo": "Labor makes you sleepy.. Zzz..", - "StatueInfo": "You're still as a rock around people", - "EvaderInfo": "You have a chance not to be exiled!", - "GMInfo": "Spectate the chaos!", - "NotAssignedInfo": "No assigned role", - "SunnyboyInfo": "Shine, shine my sunshine!", - "BardInfo": "Poem's grace, murder's trace, a rhythmic dance in a dark embrace.", - "RainbowInfo": "Colorful melodies! You don't even know your own color.", - "DollMasterInfo": "Take control of players actions!", - "DoubleAgentInfo": "Plant bombs on players in meetings", - "SlothInfo": "You're slower", - "ProhibitedInfo": "Certain vents are blocked", - "EavesdropperInfo": "Listen in on other roles", + "SpurtInfo": "Spring Like A rabbit!", + "StealthInfo": "Killing Blinds Everyone in the Room", + "PenguinInfo": "Drag your victims", + "OverseerInfo": "Reveal roles of other players", + "CoronerInfo": "Find corpses and their killers", + "PresidentInfo": "You are in charge of the meeting", + "MerchantInfo": "Sell add-ons and bribe killers", + "RetributionistInfo": "Help the crew after you die", + "HawkInfo": "Seek murdering the bad guys!", + "DeputyInfo": "Handcuff killers to increase their cooldowns", + "InvestigatorInfo": "Find potential evils", + "GuardianInfo": "Complete your tasks to become immortal", + "AddictInfo": "Vent to become invulnerable, or you'll die", + "MoleInfo": "Vanish and reappear, the Mole's game is crystal clear!", + "AlchemistInfo": "Brew potions by completing tasks", + "TracefinderInfo": "Sense the location of dead bodies", + "OracleInfo": "Vote a player to see their alignment", + "SpiritualistInfo": "Be guided by the ghostly life", + "ChameleonInfo": "Vent to disguise into your surroundings", + "InspectorInfo": "Validate the alignments of two players", + "CaptainInfo": "Sail with the Captain, lest add-ons be abandoned.", + "AdmirerInfo": "Choose a player to side with you", + "TimeMasterInfo": "Rewind time!", + "CrusaderInfo": "Kill a player's attacker", + "AltruistInfo": "Revive a player", + "ReverieInfo": "With each kill, your cooldown decreases", + "LookoutInfo": "See through disguises", + "TelecommunicationInfo": "Track device usage", + "LighterInfo": "Catch killers with your enhanced vision", + "TaskManagerInfo": "See the total tasks completed in real-time", + "WitnessInfo": "Find out if someone killed recently", + "GhastlyInfo": "Control somebody!", + "SwapperInfo": "Swap the votes of two players", + "NiceMiniInfo": "No one can hurt you until you grow up.", + "ArsonistInfo": "Douse everyone and ignite", + "PyromaniacInfo": "Douse and kill everyone", + "HuntsmanInfo": "Kill your targets for a low cooldown", + "SpyInfo": "You know who interacts with you", + "RandomizerInfo": "What are you? Your just random", + "EnigmaInfo": "Get Clues about Killers", + "JesterInfo": "Get voted out", + "OpportunistInfo": "Stay alive until the end", + "TerroristInfo": "Finish your tasks, THEN die", + "ExecutionerInfo": "Get your target voted out", + "LawyerInfo": "Help your target win!", + "VectorInfo": "Jump in! Jump out!", + "JackalInfo": "Murder everyone", + "GodInfo": "Everything is under your control", + "InnocentInfo": "Get someone ejected by making them kill you", + "PelicanInfo": "Eat all players", + "RevolutionistInfo": "Recruit players to win with you", + "HaterInfo": "Kill Lovers and Neptunes", + "DemonInfo": "Consume blood volumes", + "StalkerInfo": "Descend into the darkness, release fear!", + "WorkaholicInfo": "Finish all tasks to win solo!", + "SolsticerInfo": "Speed run all your tasks!", + "CollectorInfo": "Collect votes from players", + "ProvocateurInfo": "Victory with help target", + "BloodKnightInfo": "Killing gives you a temporary shield", + "PlagueBearerInfo": "Plague everyone to turn into Pestilence", + "PestilenceInfo": "Obliterate everyone!", + "SoulCollectorInfo": "Predict deaths to collect souls", + "DeathInfo": "Enact Armageddon", + "BakerInfo": "Feed Players Bread to become Famine", + "FamineInfo": "Starve Everyone", + "BerserkerInfo": "Kill to increase your level", + "WarInfo": "Destroy everything", + "GlitchInfo": "Hack and kill everyone", + "SidekickInfo": "Help the Jackal kill everyone", + "FollowerInfo": "Follow a player and help them", + "CultistInfo": "Charm everyone", + "SerialKillerInfo": "Kill off everyone to win!", + "JuggernautInfo": "With each kill, your cooldown decreases", + "InfectiousInfo": "Infect everyone", + "VirusInfo": "Kill and infect everyone", + "PursuerInfo": "Protect yourself and live to the end!", + "PlagueDoctorInfo": "Spread the infection!", + "SpecterInfo": "Get killed and finish your tasks to win!", + "PirateInfo": "Successfully plunder players to win", + "AgitaterInfo": "Pass a Bomb onto others", + "MaverickInfo": "Kill and survive to the end", + "CursedSoulInfo": "Snatch souls and steal the win", + "PickpocketInfo": "Steal votes from your kills", + "TraitorInfo": "Eliminate the Impostors, then win", + "TrollerInfo": "Make random event by complete task", + "VultureInfo": "Eat bodies by reporting to win", + "TaskinatorInfo": "Silent tasks, deadly blasts", + "BenefactorInfo": "Task complete, shield elite!", + "MedusaInfo": "Stone bodies by reporting them", + "SpiritcallerInfo": "Turn Players into Evil Spirits", + "AmnesiacInfo": "Remember the role of a dead body", + "LingeringPresenceInfo": "Make them remember you", + "FragileSoulInfo": "your soul cant sustain in this world", + "EvolverInfo": "steal points to evolve", + "FadingLightInfo": "Your soul fades", + "ImitatorInfo": "Imitate a player's role", + "BanditInfo": "Rob a player's add-on", + "DoppelgangerInfo": "Steal your target's identity", + "PunchingBagInfo": "Get attacked a few times to win!", + "KamikazeInfo": "Kill players with a suicidal mission", + "DoomsayerInfo": "Successfully guess players to win", + "ShroudInfo": "Shroud players to make them kill", + "WerewolfInfo": "Kill crewmates in groups", + "ShamanInfo": "Deflect all the attacks on Voodoo doll", + "SeekerInfo": "Play Hide and Seek with your target", + "PixieInfo": "Tag 'em, Bag 'em, and Eject 'em!", + "OccultistInfo": "Kill and curse your enemies", + "SchrodingersCatInfo": "The cat is both alive and dead until observed.", + "RomanticInfo": "Protect your partner to win together", + "VengefulRomanticInfo": "Revenge your partner to win together", + "RuthlessRomanticInfo": "Kill everyone to win with your partner", + "PoisonerInfo": "Kill everyone with delayed kills", + "HexMasterInfo": "Hex players to kill them in meetings", + "WraithInfo": "Vent to go invisible temporarily", + "JinxInfo": "Reflect attacks onto your attackers", + "PotionMasterInfo": "Use your potions to your advantage", + "NecromancerInfo": "Kill your killer to defy death", + "WardenInfo": "(Ghost) Alert about danger", + "MinionInfo": "(Ghost) Blind enemies", + "LoversInfo": "Stay alive and win together", + "MadmateInfo": "Help the Impostors", + "WatcherInfo": "You see all the colors of votes", + "LastImpostorInfo": "Lower kill cooldown", + "OverclockedInfo": "Lower cooldown", + "FlashInfo": "You're faster", + "TorchInfo": "You have enhanced vision!", + "SeerInfo": "You are alerted when somebody has died", + "TiebreakerInfo": "Break tied votes", + "ObliviousInfo": "You can't report bodies", + "BewilderInfo": "A twist of vision, a web of confusion", + "WorkhorseInfo": "Be the first to complete all tasks and get more", + "FoolInfo": "You can't fix sabotages", + "AvangerInfo": "You take someone with you upon death", + "YoutuberInfo": "Get killed first to win", + "CelebrityInfo": "Everyone knows when you die", + "EgoistInfo": "Win on your own", + "StealerInfo": "Gain votes with kills", + "ParanoiaInfo": "You're dead and alive simultaneously", + "MimicInfo": "Reveal killed players' roles to impostors upon death", + "GuesserInfo": "Guess roles of players in meetings to kill", + "NecroviewInfo": "See the team of the dead", + "ReachInfo": "You have a longer kill range", + "BaitInfo": "Your killer self-reports your body", + "TrapperInfo": "Freeze your killer for a few seconds", + "OnboundInfo": "You can't be guessed", + "ReboundInfo": "Guess me right, and face your plight!", + "MundaneInfo": "Tasks all done, guessing's begun.", + "UnreportableInfo": "Your body can't be reported", + "LuckyInfo": "Dodge attackers", + "DoubleShotInfo": "You have an extra life when guessing", + "RascalInfo": "You appear evil in some cases", + "SoullessInfo": "You have no soul", + "GravestoneInfo": "Your role is revealed when you die", + "LazyInfo": "You're too lazy", + "AutopsyInfo": "You see how others died", + "LoyalInfo": "You cannot be recruited", + "EvilSpiritInfo": "You are an evil Spirit", + "RecruitInfo": "Help the Jackal", + "AdmiredInfo": "The Admirer chose you as their love", + "GlowInfo": "You glow in the dark", + "RadarInfo": "Arrow's hue, closest to you!", + "DiseasedInfo": "Increase the cooldown of the player who interacts with you", + "AntidoteInfo": "Decrease the cooldown of the player who interacts with you", + "StubbornInfo": "Protect your role and add-ons", + "SwiftInfo": "Your kills don't cause a lunge", + "UnluckyInfo": "Doing things has a chance to kill you", + "VoidBallotInfo": "Your vote count is 0", + "AwareInfo": "Know who revealed your role", + "FragileInfo": "Die instantly if someone uses the kill button on you", + "GhoulInfo": "Kill your killer after dying", + "BloodthirstInfo": "Become bloodthirsty and kill", + "MareInfo": "Kill in the darkness", + "BurstInfo": "Make your killer burst!", + "SleuthInfo": "Gain info from dead bodies", + "ClumsyInfo": "You have a chance to miss your kill", + "NimbleInfo": "You can vent!", + "CircumventInfo": "You can no longer vent", + "OiiaiInfo": "OIIAIOIIIAI", + "CyberInfo": "You're popular!", + "HurriedInfo": "God, I got too much stuff!", + "InfluencedInfo": "You lack decisiveness!", + "SilentInfo": "Vote like a Ghost!", + "SusceptibleInfo": "Death-reason lotto!", + "TrickyInfo": "Tricky slays, in mysterious ways.", + "TiredInfo": "Labor makes you sleepy.. Zzz..", + "StatueInfo": "You're still as a rock around people", + "EvaderInfo": "You have a chance not to be exiled!", + "GMInfo": "Spectate the chaos!", + "NotAssignedInfo": "No assigned role", + "SunnyboyInfo": "Shine, shine my sunshine!", + "BardInfo": "Poem's grace, murder's trace, a rhythmic dance in a dark embrace.", + "RainbowInfo": "Colorful melodies! You don't even know your own color.", + "DollMasterInfo": "Take control of players actions!", + "DoubleAgentInfo": "Plant bombs on players in meetings", + "SlothInfo": "You're slower", + "ProhibitedInfo": "Certain vents are blocked", + "EavesdropperInfo": "Listen in on other roles", "ShockerInfo": "Shock unsuspecting players", "RevenantInfo": "Take your killer's role", - "EngineerTOHEInfoLong": "(Crewmates):\nAs the Engineer, you may access the vents while Comms Sabotaged is inactive.", - "ScientistTOHEInfoLong": "(Crewmates):\nAs the Scientist, you can see vitals at any time, showing you who is alive and dead.", - "NoisemakerTOHEInfoLong": "(Crewmates):\nAs the Noisemaker, whenever you die, you will make a noise, and a visual indicator of your death appears on the screen so the Crewmates can run to catch the person who killed you red-handed (even if it’s not Red).", - "TrackerTOHEInfoLong": "(Crewmates):\nAs the Tracker, press your tracker button on a player to track their location via the map for a limited amount of time.", - "ShapeshifterTOHEInfoLong": "(Impostors):\nAs the Shapeshifter, you can shapeshift into other players. It is obvious when you shapeshift or revert shifting.", - "PhantomTOHEInfoLong": "(Impostors):\nAs the Phantom, you can press your vanish button to go invisible to escape a kill. You can click your appear button if you want to become visible before the timer runs out or not.\nNote: You will make a smoke cloud whenever you go invisible and become visible. So make sure you are in a safe area where no one will see you.", - "GuardianAngelTOHEInfoLong": "(Crewmates):\nAs the Guardian Angel, you are the first crewmate to die and can give Crewmates temporary shields.", - "ImpostorTOHEInfoLong": "(Impostors):\nAs the Impostor, your goal is to simply kill off the crewmates.\nYou can sabotage and vent.", - "CrewmateTOHEInfoLong": "(Crewmates):\nAs the Crewmate, your goal is to find and exile the Impostors.\nCrewmates win by getting rid of all killers or by finishing all their tasks.", - "BountyHunterInfoLong": "(Impostors):\nAs the Bounty Hunter, if you kill your assigned Target (indicated by the arrow if you have one), your next kill cooldown will be shortened.\nIf you kill anyone other than your target, your next kill cooldown will be increased. The Target swaps after a certain amount of time.", - "FireworkerInfoLong": "(Impostors):\nAs the Fireworker, you can Shapeshift to place Fireworks up to the maximum amount the host sets.\nWhen you are the last Impostor and all Fireworks have been placed, shapeshift again to detonate them and kill everyone in their radius, including you.\nIf you kill all players with your Fireworks, it's considered an Impostor victory.", - "MercenaryInfoLong": "(Impostors):\nAs the Mercenary, you must kill within your Deadline, as shown by your Shapeshift cooldown (which you cannot use). If you fail to kill, you die.", - "ShapeMasterInfoLong": "(Impostors):\nAs the Shapemaster, you have no Shapeshift cooldown.", - "VampireInfoLong": "(Impostors):\nAs the Vampire, your kills are delayed. This means that your target still dies even if a meeting is called first. However, if you bite a Bait, you kill normally and report the body. Depending on the settings, you can use double trigger (bite players - single click, kill normally - double click).", - "WarlockInfoLong": "(Impostors):\nAs the Warlock, you can Curse up to one other player at a time.\nWhen you Shapeshift, if you have Cursed a player, they kill the nearest person, which, depending on settings, can include you or other Impostors.\nYou can kill normally while Shapeshifted.", - "ZombieInfoLong": "(Impostors):\nZombie has a short kill cooldown but moves very slowly and has very little vision. Zombie can not be voted out by anyone other than the Dictator, and the movement speed of Zombie will gradually slow down as they make kills or time passes.", - "NinjaInfoLong": "(Impostors):\nAs the Ninja, you can use your kill button to Mark a target (single click) or kill normally (double click). You may then Shapeshift to teleport to the Marked target and kill them.", - "AnonymousInfoLong": "(Impostors):\nAs the Anonymous, you can Shapeshift to force your target to report whoever you killed this round.\nIf you killed nobody that round, the target will report their own dead body as if they had died.\nNote: This does not work on Lazy nor Lazy Guy, and this ability will work regardless of whether the body can normally be reported.", - "MinerInfoLong": "(Impostors):\nAs the Miner, you can shapeshift to teleport back to the last vent you were in.", - "KillingMachineInfoLong": "(Impostors):\nAs the Killing Machine, you have a very short kill cooldown with tiny vision. However, you cannot vent, sabotage, report, nor call emergency meetings.\n\nNote: You will bypass any shields, killing bait and beartrap won't take any effect", - "EscapistInfoLong": "(Impostors):\nAs the Escapist, you can Mark a location by Shapeshifting. Shapeshift again to teleport back to the Marked spot", - "WitchInfoLong": "(Impostors):\nAs the Witch, you can use your kill button to Spell (single click) or kill normally (double click).\nDuring the next meeting, the spelled target(s) will have a 「†」 next to their name visible to everyone. Unless you die by the end of that meeting, all Spelled targets will die.", - "NemesisInfoLong": "(Impostors):\nAs the Nemesis, you can only kill if you are the last Impostor.\nIf you are dead, you can use the command /rv [ID] to kill the player whose ID you typed. Use /id to show the IDs of all players, or look next to their names.", - "BloodmoonInfoLong": "(Impostors [Ghost]):\nAs the Bloodmoon, attack the enemies to make them drip blood, this means they will die in a time set by the host, and will be aware of it.", - "PossessorInfoLong": "(Impostors [Ghost]):\nAs the Possessor, you can possess players when others aren't in the Alert Range. Lead the possessed player as far as possible from other players in the Focus Range. Once the possession duration is up, the possessed player will be killed if others aren't in the Focus Range. If you run into another player in the Alert Range while possessing, the Possessor will immediately unpossess.", - "PuppeteerInfoLong": "(Impostors):\nAs the Puppeteer, you can use your kill button to Puppeteer (single click) or kill normally (double click).\nThose you Puppeteer will kill the next non-Impostor they touch. Depending on options, Puppeteered targets will also die once they kill.", - "MastermindInfoLong": "(Impostors):\nAs the Mastermind, you can use your kill button on a player once to manipulate them. The manipulation does nothing if the target doesn't have a kill button. But if the target does have a kill button, whoever you manipulate will be told after a delay that they got manipulated and must kill someone in a limited time to survive. If the time limit expires or a meeting gets called before killing someone, they die.\nDouble click on someone to kill them normally.", - "YinYangerInfoLong": "(Impostors):\nAs the YinYanger, you can use your kill button one time to pick your Yin and then a second time to choose a Yang. When those two players meet, they'll kill each other. When Yin & Yang have been chosen, you can kill normally.", - "TimeThiefInfoLong": "(Impostors):\nEvery time the Time Thief kills a player, the meeting time will be reduced by a certain amount of time. If the Time Thief dies, the meeting time will return to normal.", - "SniperInfoLong": "(Impostors):\nYou can shoot players from far away.\nYou have to shapeshift twice to make a successful snipe.\nImagine an arrow pointing from your first shapeshift location towards your unshift location.\nThat will be the direction in which the snipe will be made.\nThe snipe kills the first person in its path.\nYou cannot kill people normally until you use up all of your ammo.", - "UndertakerInfoLong": "(Impostors):\nEverytime you Shapeshift, you mark the location. Your kills will then teleport to the marked location.\nAfter every kill and meeting, your marked location will reset.\n\nAfter every teleported kill, you will freeze for a configurable amount of time", - "RiftMakerInfoLong": "(Impostors):\nAs Rift Maker, you can shapeshift to create a rift. You can teleport from one rift to another by touching the area where the rift was created. Trying to vent will kick you out, therefore destroying all the rifts.\n\nNote: Up to two rifts can be placed at a time; if you try to place a third, it removes the first one.", - "EvilTrackerInfoLong": "(Impostors):\nThe Evil Tracker can track other players, and the Evil Tracker can shapeshift into someone to switch the tracking target to the shapeshift target (You will immediately unshift after performing shapeshift). The arrow below the Evil Tracker's name indicates the direction of the target. When the Evil Tracker's teammate kills, the Evil Tracker will see a kill flash.", - "EvilHackerInfoLong": "(Impostors):\nThe Evil Hacker can get the last-minute admin information at the meeting beginning.\nUnoccupied rooms are not shown.\nA '★' marks rooms with impostors.\nRooms with dead bodies are marked with the number of bodies.\nExample: ★Cafeteria: 3 (DEAD×1).", - "EvilGuesserInfoLong": "(Impostors):\nThe Evil Guesser can guess the role of a certain player during the meeting. If correct, the target dies. If wrong, the Evil Guesser dies.\nThe guessing command is: /bt [player id] [role]\nYou can see the player's id before the player's name or use the /id command to view the id of all players.", - "AntiAdminerInfoLong": "(Impostors):\nThe Anti Adminer can at any time find out if there are crewmates or neutrals near Cameras, Admin Table, Vitals, DoorLog, and/or other devices. Note: Anti Adminer does not know if the player uses the device while near it. They only know that someone is near the device.", - "ArroganceInfoLong": "(Impostors):\nThe Arrogance reduces their kill cooldown with each successful kill of theirs.", - "BomberInfoLong": "(Impostors):\nThe Bomber can use the shapeshift button to self-explode, killing players within a certain range. But as a price, the Bomber will also die. Note: All players will see a kill flash when the Bomber explodes.", - "ScavengerInfoLong": "(Impostors):\nScavenger kills do not leave dead bodies behind. In addition, if the victim is a bait, no self-report will be made.", - "TrapsterInfoLong": "(Impostors):\nThe Trapster has a unique method of killing. By initiating a body report, the Trapster can eliminate the player attempting to report the body the Trapster killed.\nNote: If Trapster kills the Bait, the Trapster will die immediately.", - "GangsterInfoLong": "(Impostors):\nThe Gangster, a powerful character, can try to recruit a player to a Madmate by pressing the kill button. If the recruitment is successful, both the Gangster and the target will see the shield animation on each other as a reminder (only visible to each other). The remaining number of available recruits is displayed next to the Gangster's name (the Host sets the max). If the Gangster tries to recruit players who cannot be recruited, such as neutrals or some special crews, they will kill the target normally instead. When the Gangster has no remaining recruitments, they can only make normal kills from that point on.", - "CleanerInfoLong": "(Impostors):\nCleaner can press the Report button to clean up any dead body they come across (including those they kill). If the cleanup is successful, the Cleaner will see a shield animation on their body as a reminder (only visible to himself). The cleaned-up body cannot be reported (including bait).", - "LightningInfoLong": "(Impostors):\nAs the Lightning, you cannot kill normally. Instead, your kill button quantizes targets, which activates after a delay, causing the next person they encounter to kill them. Those who are actively quantized show a「■」next to their name. Additionally, those who have been quantized die if they survive until the end of a meeting. There is a setting to quantize your killer.", - "GreedyInfoLong": "(Impostors):\nGreedy kills with odd and even kills will have different kill cooldowns. Greedy's kill cooldown is reset every meeting, and Greedy's first kill is always odd.", - "CursedWolfInfoLong": "(Impostors):\nWhen the Cursed Wolf is about to be killed, the Cursed Wolf will curse the killer to death. (The Host sets the max of times you can counterattack)", - "SoulCatcherInfoLong": "(Impostors):\nAs the Soul Catcher, you can shapeshift to swap places with your target as long as they are not dead, in a vent, swallowed by pelican, or in a similar odd state.", - "QuickShooterInfoLong": "(Impostors):\nWhen the kill cooldown is over, Quick Shooter can reset the kill cooldown by shapeshift to store a bullet (when the storage is successful, a shield-animation visible only to himself will appear on their body as a reminder). If Quick Shooter has bullets, he can use one to bypass the kill cooldown; he will kill even if it's still on cooldown and use a bullet. At the beginning of each meeting, the quick shooter can only keep a certain number of bullets (The Host sets the number).", - "CamouflagerInfoLong": "(Impostors):\nWhen the Camouflager uses Shapeshift, all players start to look the same. This state ends when the Camouflager reverts its shapeshifting. It's important to note that the skills of communication sabotage camouflage, and the skills of the Camouflager can be superimposed.\nThis skill will be invalid if a meeting is held during the skill activation of the Camouflager.", - "EraserInfoLong": "(Impostors):\nEraser can vote for any crew target at the meeting to erase the target's roles, and the erasure will take effect after the meeting ends. Note: Players with erased skills will always be considered a vanilla role, including the game result page.\nA crew target can only be erased once (include Oiiai)", - "ButcherInfoLong": "(Impostors):\nThe Butcher's kills, including passive ones, leave multiple dead bodies on targets, which can be a bit confusing when reporting. Here's the rule: the killed target must repeatedly display the animation of being killed, which cannot be skipped, and they cannot participate in the meeting normally during this period. And if the Butcher kills the Avenger, the Avenger will revenge everyone in anger.", - "HangmanInfoLong": "(Impostors):\nAs the Hangman, during the shapeshifting, you use a unique killing method-strangling. This method ignores any status of the target, such as the shield of the Medic, the Bodyguard's protection, the Super Star's skills, etc. The strangled player will not leave a dead body, nor will it trigger any of its skills. For example, Veteran kill back (including additional roles), and Seer will not be prompted.", - "SwooperInfoLong": "(Impostors):\nAs the Swooper, you can vent to vanish temporarily. You will still appear visible on your screen. Vent again to become visible.", - "CrewpostorInfoLong": "(Team Impostor):\nYou kill the nearest player whenever you finish a task.", - "WildlingInfoLong": "(Impostors):\nAs the Wildling, you can shapeshift but cannot vent.\nWhen you kill, you temporarily become immune to attacks.", - "TricksterInfoLong": "(Impostors):\nAs the Trickster, you function as a regular Impostor but with one key difference.\nYou appear as a crewmate to crewmate roles.\n\nThe Sheriff cannot kill you.\nPsychic does not see you as evil.\nSnitch cannot find you.", - "VindicatorInfoLong": "(Impostors):\nAs the Vindicator, you have extra votes like a Mayor.", - "StealthInfoLong": "(Impostors):\nWhen the Stealth kills, players in the same room are blinded for a short time.", - "PenguinInfoLong": "(Impostors):\nAs the Penguin, you can restrain the target by pressing the kill button and drag it around.\nWhile dragging, the target dies by pressing the kill button again or after a certain period.\nPress the kill button twice for a direct kill.", - "ParasiteInfoLong": "(Team Impostor):\nAs the Parasite, you are an Impostor that does not know the other Impostors.\n\nYou may kill, vent, sabotage, whatever.\nJust know that you are an Impostor.", - "DisperserInfoLong": "(Impostors):\nDisperser can use Shapeshift to teleport all players to random vents.", - "InhibitorInfoLong": "(Impostors):\nAs the Inhibitor, you can only kill when there is not a critical sabotage active.\n\nIf light or comms sabotage is active, then you can kill.", - "SaboteurInfoLong": "(Impostors):\nAs the Saboteur, you can only kill when there is a critical sabotage active.\n\nIf reactor or O2 sabotage is active, then you can kill.", - "CouncillorInfoLong": "(Impostors):\nAs the Councillor, you can kill players during a meeting like a Judge.\nWhen killing in a meeting, those kills will appear as a trial from a Judge.\n\nThe kill command is /tl [player id]\nYou can see the player's id before the player's name, or use the /id command to view the id of all players.\nDepending on the settings, Councillor will suicide when he judge his teammates.\nConverted Councillor can judge freely.", - "DazzlerInfoLong": "(Impostors):\nAs the Dazzler, you can reduce the vision of the target of your Shapeshift permanently. When you die, their vision will turn back to normal.", - "DeathpactInfoLong": "(Impostors):\nAs the Deathpact, You shapeshift to mark your targets for a deathpact.\nIf you have enough players marked for a death pact, they must meet within a specific period; if they fail to do so, they die.\nIf a marked player dies before the death pact becomes complete, the pact is withdrawn.", - "DevourerInfoLong": "(Impostors):\nAs the Devourer, you use your shapeshift to change the appearance of the target of the shapeshift permanently. Additionally, when each player's appearance changes, you will have your kill cooldown reduced by a defined number of seconds. If the Devourer dies or gets voted out during a meeting, the player's appearance will change back to their normal appearance.", - "MorphlingInfoLong": "(Impostors):\nAs the Morphling, you are a Shapeshifter but cannot kill while not shapeshifted.", - "TwisterInfoLong": "(Impostors):\nAs the Twister, you can use shapeshifting to swap the position of all players randomly. The swap happens twice, once when you start your shapeshift and once when you return to your original appearance.\nThe Twister itself will not swap places with anyone, and players in vents will not teleport.", - "LurkerInfoLong": "(Impostors):\nAs the Lurker, you can jump into a vent to reduce your cooldown by a certain number of seconds. After you kill, your cooldown resets to its original value.", - "VisionaryInfoLong": "(Impostors):\nAs the Visionary, you see the alignments of living players during a meeting.\nThe following information will be displayed on the players:\n- The Red name indicates the Impostors.\n- The Cyan name indicates the Crewmates.\n- The Gray name indicates the Neutrals.", - "PlagueDoctorInfoLong": "(Neutrals):\n(Plague Doctor from TOH)\nThe Plague Scientist's goal is to infect every living player.\nThey start by choosing one player to infect, after which anyone who spends a set amount of time in the range of the infected player becomes infected themselves.\nInfection progress is cumulative and does not reset with distance or after meetings.", + "EngineerTOHEInfoLong": "(Crewmates):\nAs the Engineer, you may access the vents while Comms Sabotaged is inactive.", + "ScientistTOHEInfoLong": "(Crewmates):\nAs the Scientist, you can see vitals at any time, showing you who is alive and dead.", + "NoisemakerTOHEInfoLong": "(Crewmates):\nAs the Noisemaker, whenever you die, you will make a noise, and a visual indicator of your death appears on the screen so the Crewmates can run to catch the person who killed you red-handed (even if it’s not Red).", + "TrackerTOHEInfoLong": "(Crewmates):\nAs the Tracker, press your tracker button on a player to track their location via the map for a limited amount of time.", + "ShapeshifterTOHEInfoLong": "(Impostors):\nAs the Shapeshifter, you can shapeshift into other players. It is obvious when you shapeshift or revert shifting.", + "PhantomTOHEInfoLong": "(Impostors):\nAs the Phantom, you can press your vanish button to go invisible to escape a kill. You can click your appear button if you want to become visible before the timer runs out or not.\nNote: You will make a smoke cloud whenever you go invisible and become visible. So make sure you are in a safe area where no one will see you.", + "GuardianAngelTOHEInfoLong": "(Crewmates):\nAs the Guardian Angel, you are the first crewmate to die and can give Crewmates temporary shields.", + "ImpostorTOHEInfoLong": "(Impostors):\nAs the Impostor, your goal is to simply kill off the crewmates.\nYou can sabotage and vent.", + "CrewmateTOHEInfoLong": "(Crewmates):\nAs the Crewmate, your goal is to find and exile the Impostors.\nCrewmates win by getting rid of all killers or by finishing all their tasks.", + "BountyHunterInfoLong": "(Impostors):\nAs the Bounty Hunter, if you kill your assigned Target (indicated by the arrow if you have one), your next kill cooldown will be shortened.\nIf you kill anyone other than your target, your next kill cooldown will be increased. The Target swaps after a certain amount of time.", + "FireworkerInfoLong": "(Impostors):\nAs the Fireworker, you can Shapeshift to place Fireworks up to the maximum amount the host sets.\nWhen you are the last Impostor and all Fireworks have been placed, shapeshift again to detonate them and kill everyone in their radius, including you.\nIf you kill all players with your Fireworks, it's considered an Impostor victory.", + "MercenaryInfoLong": "(Impostors):\nAs the Mercenary, you must kill within your Deadline, as shown by your Shapeshift cooldown (which you cannot use). If you fail to kill, you die.", + "ShapeMasterInfoLong": "(Impostors):\nAs the Shapemaster, you have no Shapeshift cooldown.", + "VampireInfoLong": "(Impostors):\nAs the Vampire, your kills are delayed. This means that your target still dies even if a meeting is called first. However, if you bite a Bait, you kill normally and report the body. Depending on the settings, you can use double trigger (bite players - single click, kill normally - double click).", + "WarlockInfoLong": "(Impostors):\nAs the Warlock, you can Curse up to one other player at a time.\nWhen you Shapeshift, if you have Cursed a player, they kill the nearest person, which, depending on settings, can include you or other Impostors.\nYou can kill normally while Shapeshifted.", + "ZombieInfoLong": "(Impostors):\nZombie has a short kill cooldown but moves very slowly and has very little vision. Zombie can not be voted out by anyone other than the Dictator, and the movement speed of Zombie will gradually slow down as they make kills or time passes.", + "NinjaInfoLong": "(Impostors):\nAs the Ninja, you can use your kill button to Mark a target (single click) or kill normally (double click). You may then Shapeshift to teleport to the Marked target and kill them.", + "AnonymousInfoLong": "(Impostors):\nAs the Anonymous, you can Shapeshift to force your target to report whoever you killed this round.\nIf you killed nobody that round, the target will report their own dead body as if they had died.\nNote: This does not work on Lazy nor Lazy Guy, and this ability will work regardless of whether the body can normally be reported.", + "MinerInfoLong": "(Impostors):\nAs the Miner, you can shapeshift to teleport back to the last vent you were in.", + "KillingMachineInfoLong": "(Impostors):\nAs the Killing Machine, you have a very short kill cooldown with tiny vision. However, you cannot vent, sabotage, report, nor call emergency meetings.\n\nNote: You will bypass any shields, killing bait and beartrap won't take any effect", + "EscapistInfoLong": "(Impostors):\nAs the Escapist, you can Mark a location by Shapeshifting. Shapeshift again to teleport back to the Marked spot", + "WitchInfoLong": "(Impostors):\nAs the Witch, you can use your kill button to Spell (single click) or kill normally (double click).\nDuring the next meeting, the spelled target(s) will have a 「†」 next to their name visible to everyone. Unless you die by the end of that meeting, all Spelled targets will die.", + "NemesisInfoLong": "(Impostors):\nAs the Nemesis, you can only kill if you are the last Impostor.\nIf you are dead, you can use the command /rv [ID] to kill the player whose ID you typed. Use /id to show the IDs of all players, or look next to their names.", + "BloodmoonInfoLong": "(Impostors [Ghost]):\nAs the Bloodmoon, attack the enemies to make them drip blood, this means they will die in a time set by the host, and will be aware of it.", + "PossessorInfoLong": "(Impostors [Ghost]):\nAs the Possessor, you can possess players when others aren't in the Alert Range. Lead the possessed player as far as possible from other players in the Focus Range. Once the possession duration is up, the possessed player will be killed if others aren't in the Focus Range. If you run into another player in the Alert Range while possessing, the Possessor will immediately unpossess.", + "PuppeteerInfoLong": "(Impostors):\nAs the Puppeteer, you can use your kill button to Puppeteer (single click) or kill normally (double click).\nThose you Puppeteer will kill the next non-Impostor they touch. Depending on options, Puppeteered targets will also die once they kill.", + "MastermindInfoLong": "(Impostors):\nAs the Mastermind, you can use your kill button on a player once to manipulate them. The manipulation does nothing if the target doesn't have a kill button. But if the target does have a kill button, whoever you manipulate will be told after a delay that they got manipulated and must kill someone in a limited time to survive. If the time limit expires or a meeting gets called before killing someone, they die.\nDouble click on someone to kill them normally.", + "YinYangerInfoLong": "(Impostors):\nAs the YinYanger, you can use your kill button one time to pick your Yin and then a second time to choose a Yang. When those two players meet, they'll kill each other. When Yin & Yang have been chosen, you can kill normally.", + "TimeThiefInfoLong": "(Impostors):\nEvery time the Time Thief kills a player, the meeting time will be reduced by a certain amount of time. If the Time Thief dies, the meeting time will return to normal.", + "SniperInfoLong": "(Impostors):\nYou can shoot players from far away.\nYou have to shapeshift twice to make a successful snipe.\nImagine an arrow pointing from your first shapeshift location towards your unshift location.\nThat will be the direction in which the snipe will be made.\nThe snipe kills the first person in its path.\nYou cannot kill people normally until you use up all of your ammo.", + "UndertakerInfoLong": "(Impostors):\nEverytime you Shapeshift, you mark the location. Your kills will then teleport to the marked location.\nAfter every kill and meeting, your marked location will reset.\n\nAfter every teleported kill, you will freeze for a configurable amount of time", + "RiftMakerInfoLong": "(Impostors):\nAs Rift Maker, you can shapeshift to create a rift. You can teleport from one rift to another by touching the area where the rift was created. Trying to vent will kick you out, therefore destroying all the rifts.\n\nNote: Up to two rifts can be placed at a time; if you try to place a third, it removes the first one.", + "EvilTrackerInfoLong": "(Impostors):\nThe Evil Tracker can track other players, and the Evil Tracker can shapeshift into someone to switch the tracking target to the shapeshift target (You will immediately unshift after performing shapeshift). The arrow below the Evil Tracker's name indicates the direction of the target. When the Evil Tracker's teammate kills, the Evil Tracker will see a kill flash.", + "EvilHackerInfoLong": "(Impostors):\nThe Evil Hacker can get the last-minute admin information at the meeting beginning.\nUnoccupied rooms are not shown.\nA '★' marks rooms with impostors.\nRooms with dead bodies are marked with the number of bodies.\nExample: ★Cafeteria: 3 (DEAD×1).", + "EvilGuesserInfoLong": "(Impostors):\nThe Evil Guesser can guess the role of a certain player during the meeting. If correct, the target dies. If wrong, the Evil Guesser dies.\nThe guessing command is: /bt [player id] [role]\nYou can see the player's id before the player's name or use the /id command to view the id of all players.", + "AntiAdminerInfoLong": "(Impostors):\nThe Anti Adminer can at any time find out if there are crewmates or neutrals near Cameras, Admin Table, Vitals, DoorLog, and/or other devices. Note: Anti Adminer does not know if the player uses the device while near it. They only know that someone is near the device.", + "ArroganceInfoLong": "(Impostors):\nThe Arrogance reduces their kill cooldown with each successful kill of theirs.", + "BomberInfoLong": "(Impostors):\nThe Bomber can use the shapeshift button to self-explode, killing players within a certain range. But as a price, the Bomber will also die. Note: All players will see a kill flash when the Bomber explodes.", + "ScavengerInfoLong": "(Impostors):\nScavenger kills do not leave dead bodies behind. In addition, if the victim is a bait, no self-report will be made.", + "TrapsterInfoLong": "(Impostors):\nThe Trapster has a unique method of killing. By initiating a body report, the Trapster can eliminate the player attempting to report the body the Trapster killed.\nNote: If Trapster kills the Bait, the Trapster will die immediately.", + "GangsterInfoLong": "(Impostors):\nThe Gangster, a powerful character, can try to recruit a player to a Madmate by pressing the kill button. If the recruitment is successful, both the Gangster and the target will see the shield animation on each other as a reminder (only visible to each other). The remaining number of available recruits is displayed next to the Gangster's name (the Host sets the max). If the Gangster tries to recruit players who cannot be recruited, such as neutrals or some special crews, they will kill the target normally instead. When the Gangster has no remaining recruitments, they can only make normal kills from that point on.", + "CleanerInfoLong": "(Impostors):\nCleaner can press the Report button to clean up any dead body they come across (including those they kill). If the cleanup is successful, the Cleaner will see a shield animation on their body as a reminder (only visible to himself). The cleaned-up body cannot be reported (including bait).", + "LightningInfoLong": "(Impostors):\nAs the Lightning, you cannot kill normally. Instead, your kill button quantizes targets, which activates after a delay, causing the next person they encounter to kill them. Those who are actively quantized show a「■」next to their name. Additionally, those who have been quantized die if they survive until the end of a meeting. There is a setting to quantize your killer.", + "GreedyInfoLong": "(Impostors):\nGreedy kills with odd and even kills will have different kill cooldowns. Greedy's kill cooldown is reset every meeting, and Greedy's first kill is always odd.", + "CursedWolfInfoLong": "(Impostors):\nWhen the Cursed Wolf is about to be killed, the Cursed Wolf will curse the killer to death. (The Host sets the max of times you can counterattack)", + "SoulCatcherInfoLong": "(Impostors):\nAs the Soul Catcher, you can shapeshift to swap places with your target as long as they are not dead, in a vent, swallowed by pelican, or in a similar odd state.", + "QuickShooterInfoLong": "(Impostors):\nWhen the kill cooldown is over, Quick Shooter can reset the kill cooldown by shapeshift to store a bullet (when the storage is successful, a shield-animation visible only to himself will appear on their body as a reminder). If Quick Shooter has bullets, he can use one to bypass the kill cooldown; he will kill even if it's still on cooldown and use a bullet. At the beginning of each meeting, the quick shooter can only keep a certain number of bullets (The Host sets the number).", + "CamouflagerInfoLong": "(Impostors):\nWhen the Camouflager uses Shapeshift, all players start to look the same. This state ends when the Camouflager reverts its shapeshifting. It's important to note that the skills of communication sabotage camouflage, and the skills of the Camouflager can be superimposed.\nThis skill will be invalid if a meeting is held during the skill activation of the Camouflager.", + "EraserInfoLong": "(Impostors):\nEraser can vote for any crew target at the meeting to erase the target's roles, and the erasure will take effect after the meeting ends. Note: Players with erased skills will always be considered a vanilla role, including the game result page.\nA crew target can only be erased once (include Oiiai)", + "ButcherInfoLong": "(Impostors):\nThe Butcher's kills, including passive ones, leave multiple dead bodies on targets, which can be a bit confusing when reporting. Here's the rule: the killed target must repeatedly display the animation of being killed, which cannot be skipped, and they cannot participate in the meeting normally during this period. And if the Butcher kills the Avenger, the Avenger will revenge everyone in anger.", + "HangmanInfoLong": "(Impostors):\nAs the Hangman, during the shapeshifting, you use a unique killing method-strangling. This method ignores any status of the target, such as the shield of the Medic, the Bodyguard's protection, the Super Star's skills, etc. The strangled player will not leave a dead body, nor will it trigger any of its skills. For example, Veteran kill back (including additional roles), and Seer will not be prompted.", + "SwooperInfoLong": "(Impostors):\nAs the Swooper, you can vent to vanish temporarily. You will still appear visible on your screen. Vent again to become visible.", + "CrewpostorInfoLong": "(Team Impostor):\nYou kill the nearest player whenever you finish a task.", + "LingeringPresenceInfoLong": "Your anger lets you return", + "FragileSoulInfoLong": "your limited life means your soul breaks at the slightest touch", + "FadingLightInfoLong": "a old presence weakens your soul", + "EvolverInfoLong": "you work for only the fittest and those that win must be so.\nSurvive until the end of the game to win.\nBut before you can win you must prove to be as fit as the other winners, and that means you have to evolve.", + "WildlingInfoLong": "(Impostors):\nAs the Wildling, you can shapeshift but cannot vent.\nWhen you kill, you temporarily become immune to attacks.", + "TricksterInfoLong": "(Impostors):\nAs the Trickster, you function as a regular Impostor but with one key difference.\nYou appear as a crewmate to crewmate roles.\n\nThe Sheriff cannot kill you.\nPsychic does not see you as evil.\nSnitch cannot find you.", + "VindicatorInfoLong": "(Impostors):\nAs the Vindicator, you have extra votes like a Mayor.", + "StealthInfoLong": "(Impostors):\nWhen the Stealth kills, players in the same room are blinded for a short time.", + "PenguinInfoLong": "(Impostors):\nAs the Penguin, you can restrain the target by pressing the kill button and drag it around.\nWhile dragging, the target dies by pressing the kill button again or after a certain period.\nPress the kill button twice for a direct kill.", + "ParasiteInfoLong": "(Team Impostor):\nAs the Parasite, you are an Impostor that does not know the other Impostors.\n\nYou may kill, vent, sabotage, whatever.\nJust know that you are an Impostor.", + "DisperserInfoLong": "(Impostors):\nDisperser can use Shapeshift to teleport all players to random vents.", + "InhibitorInfoLong": "(Impostors):\nAs the Inhibitor, you can only kill when there is not a critical sabotage active.\n\nIf light or comms sabotage is active, then you can kill.", + "SaboteurInfoLong": "(Impostors):\nAs the Saboteur, you can only kill when there is a critical sabotage active.\n\nIf reactor or O2 sabotage is active, then you can kill.", + "CouncillorInfoLong": "(Impostors):\nAs the Councillor, you can kill players during a meeting like a Judge.\nWhen killing in a meeting, those kills will appear as a trial from a Judge.\n\nThe kill command is /tl [player id]\nYou can see the player's id before the player's name, or use the /id command to view the id of all players.\nDepending on the settings, Councillor will suicide when he judge his teammates.\nConverted Councillor can judge freely.", + "DazzlerInfoLong": "(Impostors):\nAs the Dazzler, you can reduce the vision of the target of your Shapeshift permanently. When you die, their vision will turn back to normal.", + "DeathpactInfoLong": "(Impostors):\nAs the Deathpact, You shapeshift to mark your targets for a deathpact.\nIf you have enough players marked for a death pact, they must meet within a specific period; if they fail to do so, they die.\nIf a marked player dies before the death pact becomes complete, the pact is withdrawn.", + "DevourerInfoLong": "(Impostors):\nAs the Devourer, you use your shapeshift to change the appearance of the target of the shapeshift permanently. Additionally, when each player's appearance changes, you will have your kill cooldown reduced by a defined number of seconds. If the Devourer dies or gets voted out during a meeting, the player's appearance will change back to their normal appearance.", + "MorphlingInfoLong": "(Impostors):\nAs the Morphling, you are a Shapeshifter but cannot kill while not shapeshifted.", + "TwisterInfoLong": "(Impostors):\nAs the Twister, you can use shapeshifting to swap the position of all players randomly. The swap happens twice, once when you start your shapeshift and once when you return to your original appearance.\nThe Twister itself will not swap places with anyone, and players in vents will not teleport.", + "LurkerInfoLong": "(Impostors):\nAs the Lurker, you can jump into a vent to reduce your cooldown by a certain number of seconds. After you kill, your cooldown resets to its original value.", + "VisionaryInfoLong": "(Impostors):\nAs the Visionary, you see the alignments of living players during a meeting.\nThe following information will be displayed on the players:\n- The Red name indicates the Impostors.\n- The Cyan name indicates the Crewmates.\n- The Gray name indicates the Neutrals.", + "PlagueDoctorInfoLong": "(Neutrals):\n(Plague Doctor from TOH)\nThe Plague Scientist's goal is to infect every living player.\nThey start by choosing one player to infect, after which anyone who spends a set amount of time in the range of the infected player becomes infected themselves.\nInfection progress is cumulative and does not reset with distance or after meetings.", "RefugeeInfoLong": "(Madmates):\nAs the Refugee, you were either:\n -An Amnesiac who remembered an Impostor\n -A killer who killed the Godfather's target.\n -A Romantic whose partner was an Impostor\n -Or an Imitator that imitated an Impostor.\n\nNow your job is to help the Impostors kill the crewmates.", - "UnderdogInfoLong": "(Impostors):\nAs the Underdog, you cannot kill until there's a certain amount of players alive.", - "ConsigliereInfoLong": "(Impostors):\nAs the Consigliere, you can reveal the roles of other players using your kill button.\n\nSingle click: Reveal role\nDouble click: Kill\n\nIf you run out of reveal uses, your kill button functions normally.", - "LudopathInfoLong": "(Impostors):\nAs the Ludopath, your kill cooldown is randomized.\n\nMinimum it can be is 1 second, while the maximum is your default kill cooldown.", + "UnderdogInfoLong": "(Impostors):\nAs the Underdog, you cannot kill until there's a certain amount of players alive.", + "ConsigliereInfoLong": "(Impostors):\nAs the Consigliere, you can reveal the roles of other players using your kill button.\n\nSingle click: Reveal role\nDouble click: Kill\n\nIf you run out of reveal uses, your kill button functions normally.", + "LudopathInfoLong": "(Impostors):\nAs the Ludopath, your kill cooldown is randomized.\n\nMinimum it can be is 1 second, while the maximum is your default kill cooldown.", "GodfatherInfoLong": "(Impostors):\nAs the Godfather, you vote someone to make them your target.\nIn the next round, if someone kills the target, the killer will turn into a Refugee or Madmate.", - "ChronomancerInfoLong": "(Impostors):\nAs the Chronomancer, you have a charge bar which indicates when the slaughter is ready. When it is at 100% the next time you kill someone, you go into slaughter mode, meaning you can kill indefinitely until your bar runs out of charge. Otherwise, you have a normal KCD.", - "PitfallInfoLong": "(Impostors):\nAs the Pitfall, you use your shapeshift to mark the area around the shapeshift as a trap. Players who enter this area will be immobilized quickly, and their vision will be affected.", - "EvilMiniInfoLong": "(Impostors):\nAs the Evil Mini, you are unkillable until you grow up and have a very long initial kill cooldown, which gets drastically shortened as you grow up.", - "BlackmailerInfoLong": "(Impostors):\nAs the Blackmailer, when you shift into a target, you will blackmail that player. This means that during the meetings, they won't be able to speak.\n\nNote: If someone is already blackmailed, blackmailing another person un-blackmails the current person.", - "InstigatorInfoLong": "(Impostors):\nAs the Instigator, it's your job to turn the crewmates against each other. Each time a Crewmate gets voted out in a meeting, if you are alive, an additional Crewmate who voted for the innocent player will die after the meeting. The Host determines the number of additional players dying.", - "LazyGuyInfoLong": "(Crewmates):\nLazy Guy has only one task. In addition, the Impostor's abilities can't affect the Lazy Guy, such as being a scapegoat for Anonymous, being marked by a Warlock or Puppeteer, and more. Lazy Guy will not have any add-ons.", - "SuperStarInfoLong": "(Crewmates):\nThere will be a star logo next to the Super Star's name, so everyone knows who the Super Star is. The Super Star can only die when the murderer is alone with the Super Star (regular kills only). In addition, the Guessers can't guess the Super Star. ", - "CelebrityInfoLong": "(Crewmates):\nAll Crewmates see the kill-flash when the Celebrity dies (same as the Seer sees the kill-flash) and get a notice at the next meeting. The Impostors don't know anything about this.", - "CleanserInfoLong": "(Crewmates):\nAs The Cleanser, you can vote to erase the add-ons of any target at the meeting. This erasure takes effect after the meeting ends. Depending on the settings, the cleansed player may never receive add-ons again.", - "KeeperInfoLong": "(Crewmates):\nAs keeper, you can vote for someone to protect them from being ejected. You can only do this a configurable number of times.", - "MayorInfoLong": "(Crewmates):\nAs the Mayor, you have extra votes. Depending on the settings, players can't see your extra votes, you can vent to call a meeting at any time, or you can have yourself revealed as Mayor upon task completion.", - "PsychicInfoLong": "(Crewmates):\nThe Psychic can see the names of several players highlighted in red during the meeting; at least one of them is evil. The Psychic will correctly see all Neutrals and Killing Crewmates displayed as red names when becoming a Madmate.", - "MechanicInfoLong": "(Crewmates):\nThe Mechanic can use the vent at any time. They can also fix Reactors, O2, and Communications using only one side. You can fix Lights by flicking only one switch. Opening a door will open all doors in the map.", - "SheriffInfoLong": "(Crewmates):\nSheriff has no task. The Sheriff can kill the Impostor (according to the host settings, the Sheriff can also kill neutrals). If the Sheriff tries to kill a crewmate, the Sheriff will kill himself. The Sheriff can kill anyone when he becomes a madmate (also according to the host settings).", - "VigilanteInfoLong": "(Crewmates):\nAs the Vigilante, you are tasked with eliminating potential threats to the Crew, but if they mistakenly kill an innocent crew member, they become a Madmate driven by guilt and remorse.\n\n Note: Gangster cannot convert Vigilante into madmate.", - "JailerInfoLong": "(Crewmates):\nAs the Jailer, use your kill button to lock a player in jail. During the next meeting, the jailed player cannot vote or get voted (the vote count will be 0). The Jailer may choose to execute the prisoner by voting for them. If the Jailer executes an innocent player, the Jailer loses the ability to execute for the rest of the game.\nIf the Jailer is evil, then they can execute anyone.\nThe Jailer has limited executions.\n\nNote: Jailed players cannot be guessed or judged, and jailed players can only guess Jailer.", - "SnitchInfoLong": "(Crewmates):\nAfter the Snitch completes all tasks, they can see the Impostor's names displayed in red on the meeting. When the Snitch has only one task left, the Impostors will see a 「★」 mark next to the name of themselves and the Snitch. When a Snitch becomes a Madmate, the 「★」 mark turns red.", - "MarshallInfoLong": "(Crewmates):\nAs the Marshall, complete your tasks to reveal yourself to the rest of the Crew.\nOther teams will not be able to see you.\nHowever, madmates CAN see you.", - "DoctorInfoLong": "(Crewmates):\nDoctor can see the cause of death for all players. In addition, the Doctor can access vitals wherever you are while he still has battery left.", - "DictatorInfoLong": "(Crewmates):\nWhen the Dictator votes for someone, the meeting will end on the spot, and the player they voted for will be ejected from the meeting. The moment the Dictator votes someone out, the Dictator will also die.", - "DetectiveInfoLong": "(Crewmate):\nAfter the Detective reports the body, they will receive a clue message, which will tell the Detective what the victim's role is. According to the Host's settings, the Detective may know what the murderer's role is. Note: Detective won't be Oblivious.", - "UndercoverInfoLong": "(Crewmates):\nThe Impostors knows who Undercover is and sees him as a teammate, but Undercover himself does not know who the Impostors are.", - "NiceGuesserInfoLong": "(Crewmates):\nThe Nice Guesser can guess the role of a certain player during the meeting. If it is correct, it will kill the target, and if it is wrong, Nice Guesser will suicide.\nThe guessing command is: /bt [player id] [role]\nYou can see the player's id before the player's name or use the /id command to view the id of all players.\nNice Guesser can guess crewmate when become madmate.", - "GuessMasterInfoLong": "(Crewmates):\nAs the Guess Master, you will receive information about every attempted guess made during a meeting. You will be informed about the role the guesser tried to guess, and you will also be notified in case of a misguess.", - "KnightInfoLong": "(Crewmates):\nThe Knight has no tasks. They can kill anyone but only do it once the whole game.", - "TransporterInfoLong": "(Crewmates):\nWhenever the Transporter completes the task, two random players will switch positions, but if there are not enough players left, nothing will happen. Note: Players in the vent will not be selected.", - "TimeManagerInfoLong": "(Crewmates):\nThe more tasks the Time Manager does, the longer the meeting time will be. When the Time Manager dies, the meeting time will return to normal. When the Time Manager becomes a Madmate, the skill changes to reducing the meeting time instead of increasing it.", - "VeteranInfoLong": "(Crewmates):\nAs the Veteran, you can enter the alert state by venting. If a player tries to kill the Veteran in the alert state, the Veteran will kill the murderer instead. Veteran will see a shield animation on their body and a text above their head as a reminder when they enter and exit the alert state.", - "BastionInfoLong": "(Crewmates):\nAs the Bastion, bomb vents to kill off impostors and neutrals.\nBe careful though; crewmates can also be killed with the bombs.", - "CopyCatInfoLong": "(Crewmate):\nAs the Copycat, you can use your kill button to copy the target's role.\n\nYou can only copy some crewmate roles.\nIf you try to copy a madmate or rascal, you become the madmate variation of the target role.\nIf you target an evil with a crewmate variant, you'll become the crewmate variant.\n\nAdditionally, Your role will be set back to Copycat after every meeting.\nNote You can't guess people in meetings.", - "BodyguardInfoLong": "(Crewmates):\nIf a player is about to be killed near the Bodyguard, the Bodyguard will prevent the kill and die with the murderer. The Bodyguard's skills will affect players of any team. When the Bodyguard becomes a Madmate, and the murderer is an Impostor, the Bodyguard will not activate the skill.", - "DeceiverInfoLong": "(Crewmates):\nThe Deceiver can sell the counterfeit to other players through the kill button. If the counterfeit is sold successfully, the Deceiver will see a shield animation on their body as a reminder. The counterfeit will take effect after the end of the next meeting. If the player with no kill ability holds the counterfeit, he will kill himself immediately. If the player with the killing ability has the counterfeit, he will commit suicide when he tries to kill someone next time.", - "GrenadierInfoLong": "(Crewmates):\nAs the Grenadier, you can vent to Flashbang players nearby, causing them to lose vision if they are an Impostor or, depending on settings, a Neutral.", - "MedicInfoLong": "(Crewmates):\nThe Medic can place a shield on the target by pressing the Kill button. The Medic can only give one shield for the whole game. Depending on the settings, the target's shield can or cannot deactivate when the Medic dies. The Medic can also see if someone is trying to break the target's shield.\nDepending on the Host's settings, the Medic or the target can see if the player has a shield (shown as a green circle 「●」 next to the name).", - "FortuneTellerInfoLong": "(Crewmates):\nAs the Fortune Teller, vote for a player in a meeting to get a clue to their role.\nThe clue will relate to their actual role.\n\nWhen the Fortune Teller's tasks are complete, they will obtain the exact role rather than a clue!\n\nNote: If the setting to give random active players as a hint is on, you cannot check the same player multiple times.", - "JudgeInfoLong": "(Crewmates):\nThe Judge can judge a certain player during the meeting. If the target is evil, the target will be killed (whether it is evil or not is set by the Host). If it is wrong, the Judge commits suicide.\nCommand for judgment: /tl [player id]\nYou can see the player's id before the player's name, or use the /id command to view the id of all players.\nJudges can judge all players when they become Madmate.", - "MorticianInfoLong": "(Crewmates):\nThe Mortician can see arrows pointing to all dead bodies, and if the Mortician reports a body, they will know the last player the victim had contact with. Note: Mortician won't be Oblivious or Seer.", - "MediumInfoLong": "(Crewmates):\nThe Medium can establish contact with a dead player after someone reports a dead body. The player who reports doesn't have to be the Medium. The dead player can answer once with a YES or a NO to the Medium's question, which only the Medium will see (the dead player can use /ms yes or /ms no). Note: Medium won't be Oblivious.", - "ObserverInfoLong": "(Crewmates):\nAs the Observer, you can see all shield animations caused by other players after the first meeting. The shied animations typically indicate a role ability, so look out for this.", - "MonarchInfoLong": "(Crewmates):\nAs the Monarch, you can knight players to give them an extra vote.\n\nYou cannot knight someone who already has multiple votes.\n\nKnighted players appear with a golden name.\nIf a knighted player is alive, the Monarch cannot be guessed or killed.", - "PacifistInfoLong": "(Crewmates):\nWhen the Pacifist vents, they will reset the kill cooldown for every player with a kill button. When they become a Madmate, this ability will only work on Crewmates.", - "OverseerInfoLong": "(Crewmates):\nAs The Overseer, you have minimal vision, but you can use your kill button to reveal the role of a nearby player. A 「○」 will be displayed next to the revealed target after you use the kill button on them, and you will also be scanning them (only you can see this). Stay near the target for a defined time to reveal his role; if you move too far away, the reveal will cancel.", - "CoronerInfoLong": "(Crewmates):\nAs a Coroner, you can't report corpses; instead, after trying to report the corpse, you will see an arrow leading you to the killer. If someone calls a meeting, the arrows disappear. Depending on the settings, players can't report the body you found.", - "PresidentInfoLong": "(Crewmates):\nThe President has two abilities: End the meeting and Reveal identity.\n\n+ Ability 1: End the meeting - Type /finish in meetings as President to instantly end the meeting.\n+ Ability 2: Reveal identity - Type /reveal in meetings to reveal yourself. Revealing yourself will make it so every player can see that you are the President, and you will become unguessable after typing the command. However, after the President has revealed themselves, whoever killed the President will have their kill CD greatly reduced on their next kill.", - "MerchantInfoLong": "(Crewmates):\nAs a merchant, you sell a random add-on to a random player for each task you complete. Each add-on sold earns you money. If you have a certain amount of money, you can prevent the next killing attempt against you by bribing the murderer. The bribed player won't be able to kill you, but you don't know who it is. The money used is lost and not available for additional bribes.", - "RetributionistInfoLong": "(Crewmates):\nAs the Retributionist, you can kill a limited amount of players after your death.\n\nUse /ret [playerID] to kill.", - "HawkInfoLong": "(Crewmates [Ghost]):\nAs the Hawk, you can kill a limited amount of players decided by the host, though there's a chance you miss, slicing someone multiple times increases the chances.", - "DeputyInfoLong": "(Crewmates):\nAs the Deputy, use your kill button on a player to reset their kill cooldown.\n\nIf the target does not have a kill button, then the handcuff was a waste.", - "InvestigatorInfoLong": "(Crewmates):\nAs an Investigator, you can use your kill button to investigate someone. When you investigate someone, their name will appear in red if they possess a kill button (impostor/SS basis) or light blue if they lack a kill button (crewmate/engineer/scientist basis). However, please note that the color of the names will return to normal when someone calls a meeting.", - "GuardianInfoLong": "(Crewmates):\nAs the Guardian, you become immortal upon task completion. Guessers can't even guess you in meetings.", - "AddictInfoLong": "(Crewmates):\nAs the Addict, you have a suicide timer. When it expires, you kill yourself.\nThe timer is indicated by the vent cooldown. When the vent cooldown is 0 seconds, you still have a short time to vent.\nIf you don't make it, you die; if you make it, the suicide timer is reset.\nAlso after you vent, no one can interact with you for a defined period.\nAfter; the period is over, and you are immobilized for another defined period, and cannot report any bodies.", - "MoleInfoLong": "(Crewmates):\nAs the Mole, when you vent, you stay in the vent for 1 second. When you exit the vent, you will spawn near a random vent in the map (Except the one you used).", - "AlchemistInfoLong": "(Crewmates):\nAs the Alchemist, you brew potions when you complete tasks. The potion you made will show up under your role name with its corresponding description and instructions. You can get seven different potions, some with harmful or no effects. Vent to use the potion.", - "KamikazeInfoLong": "(Impostors):\nAs the Kamikaze you can single click to mark people. Double-click to kill normally. When you die, all marked also die, with death reason Targeted.", - "TracefinderInfoLong": "(Crewmates):\nAs the Tracefinder, you can access vitals at any time.\nIn addition, you get arrows pointing to dead bodies, with a delay set by the Host.", - "OracleInfoLong": "(Crewmates):\nAs the Oracle, you may vote a player during a meeting.\nYou'll see if they are a Crewmate, Neutral, or Impostor.\nDepending on settings, there can be a chance that your result will be incorrect.", - "SpiritualistInfoLong": "(Crewmates):\nAs the Spiritualist, you get an arrow pointing towards the ghost of the last meeting's victim. There is an option for the arrow to disappear and reappear in intervals. Try to notify the ghost about your ability if you can; if they are on your side, they may lead you to an evil role so you can eject them. Be careful, as evil roles can do the same for Crewmates.", - "ChameleonInfoLong": "(Crewmates):\nAs the Chameleon, you can vent to Vanish temporarily. You will still appear visible on your screen. Vent again to become visible.", - "InspectorInfoLong": "(Crewmates):\nCheck If two players are in the same team or not. You will get an affirmation message if they are on the same team or a denial message if they are not on the same team.\n\nAll neutrals and converted players are counted in the same team. Trickster counts as Crew, and Rascal counts as Impostor.\nChecking command: /cmp [player id 1] [player id 2].", - "CaptainInfoLong": "(Crewmates):\nWith each completed task, the Captain gains the power to slow down a random non-crew role. Crewmates can see ☆besides Captain's name.\n\nIf anyone betrays the Captain's trust by voting Captain out, they will lose an add-on.", - "AdmirerInfoLong": "(Crewmates):\nAs the Admirer, admire a player to make them Crewmate aligned.\nThey'll win with crewmates and not their original team.\n\nYou can only do this once per player.", - "TimeMasterInfoLong": "(Crewmates):\nAs the Time Master, use the vents to mark everyone's position.\nWhen using the ability again, every alive player will rewind to the marked positions.\n\nDuring the ability duration, the Time Master gains a time shield, which protects them from death.", - "CrusaderInfoLong": "(Crewmates):\nAs the Crusader, use your kill button to crusade a player.\nIf that player gets attacked, you'll kill the attacker.", - "AltruistInfoLong": "(Crewmates):\nAs the Altruist, you can sacrifice yourself to revive a dead body using the «Report» button.\nNote: If a dead player has left the game, you report that body normally.\nAlso revived player cannot report self dead body", - "ReverieInfoLong": "(Crewmates):\nAs the Reverie, you can kill, but your cooldown starts high.\n\nIt increases if you kill a crewmate and reduces otherwise.\nDepending on the Host's setting, you may misfire on reaching the max kill cooldown, and your target dies with you. \n\nYou win with other crewmates.", - "LookoutInfoLong": "(Crewmates):\nAs the Lookout, you can see the IDs of every player at all times.\nThis allows you to see through shapeshifts and camouflages.", - "TelecommunicationInfoLong": "(Crewmates):\nAs the Telecommunication, you are notified when anyone uses cameras, vitals, door logs, or admin.", - "LighterInfoLong": "(Crewmate):\nAs the Lighter, you can vent to increase your vision temporarily.\nYou have increased vision both when lights are not out and when lights are out.\nUse this power to catch sneaky killers!", - "TaskManagerInfoLong": "(Crewmates):\nYou see the total number of tasks completed (by everyone all together) next to your role name, which updates in real-time.", - "WitnessInfoLong": "(Crewmates):\nAs the Witness, when you use your kill button on someone, you will know if they killed in the last X seconds or not. (X depends on the settings).", - "SwapperInfoLong": "(Crewmates):\nAs the Swapper, you can swap votes in meetings.\n\nTo swap votes, use '/sw [playerID]' twice.\n\nPlayer IDs are displayed next to player names in meetings, but you can also use /id to get a list of all player IDs.\n\nNote: Depending on the Host's settings, you can exchange your own votes.", + "ChronomancerInfoLong": "(Impostors):\nAs the Chronomancer, you have a charge bar which indicates when the slaughter is ready. When it is at 100% the next time you kill someone, you go into slaughter mode, meaning you can kill indefinitely until your bar runs out of charge. Otherwise, you have a normal KCD.", + "PitfallInfoLong": "(Impostors):\nAs the Pitfall, you use your shapeshift to mark the area around the shapeshift as a trap. Players who enter this area will be immobilized quickly, and their vision will be affected.", + "EvilMiniInfoLong": "(Impostors):\nAs the Evil Mini, you are unkillable until you grow up and have a very long initial kill cooldown, which gets drastically shortened as you grow up.", + "BlackmailerInfoLong": "(Impostors):\nAs the Blackmailer, when you shift into a target, you will blackmail that player. This means that during the meetings, they won't be able to speak.\n\nNote: If someone is already blackmailed, blackmailing another person un-blackmails the current person.", + "InstigatorInfoLong": "(Impostors):\nAs the Instigator, it's your job to turn the crewmates against each other. Each time a Crewmate gets voted out in a meeting, if you are alive, an additional Crewmate who voted for the innocent player will die after the meeting. The Host determines the number of additional players dying.", + "LazyGuyInfoLong": "(Crewmates):\nLazy Guy has only one task. In addition, the Impostor's abilities can't affect the Lazy Guy, such as being a scapegoat for Anonymous, being marked by a Warlock or Puppeteer, and more. Lazy Guy will not have any add-ons.", + "SuperStarInfoLong": "(Crewmates):\nThere will be a star logo next to the Super Star's name, so everyone knows who the Super Star is. The Super Star can only die when the murderer is alone with the Super Star (regular kills only). In addition, the Guessers can't guess the Super Star. ", + "CelebrityInfoLong": "(Crewmates):\nAll Crewmates see the kill-flash when the Celebrity dies (same as the Seer sees the kill-flash) and get a notice at the next meeting. The Impostors don't know anything about this.", + "CleanserInfoLong": "(Crewmates):\nAs The Cleanser, you can vote to erase the add-ons of any target at the meeting. This erasure takes effect after the meeting ends. Depending on the settings, the cleansed player may never receive add-ons again.", + "KeeperInfoLong": "(Crewmates):\nAs keeper, you can vote for someone to protect them from being ejected. You can only do this a configurable number of times.", + "MayorInfoLong": "(Crewmates):\nAs the Mayor, you have extra votes. Depending on the settings, players can't see your extra votes, you can vent to call a meeting at any time, or you can have yourself revealed as Mayor upon task completion.", + "PsychicInfoLong": "(Crewmates):\nThe Psychic can see the names of several players highlighted in red during the meeting; at least one of them is evil. The Psychic will correctly see all Neutrals and Killing Crewmates displayed as red names when becoming a Madmate.", + "MechanicInfoLong": "(Crewmates):\nThe Mechanic can use the vent at any time. They can also fix Reactors, O2, and Communications using only one side. You can fix Lights by flicking only one switch. Opening a door will open all doors in the map.", + "SheriffInfoLong": "(Crewmates):\nSheriff has no task. The Sheriff can kill the Impostor (according to the host settings, the Sheriff can also kill neutrals). If the Sheriff tries to kill a crewmate, the Sheriff will kill himself. The Sheriff can kill anyone when he becomes a madmate (also according to the host settings).", + "VigilanteInfoLong": "(Crewmates):\nAs the Vigilante, you are tasked with eliminating potential threats to the Crew, but if they mistakenly kill an innocent crew member, they become a Madmate driven by guilt and remorse.\n\n Note: Gangster cannot convert Vigilante into madmate.", + "JailerInfoLong": "(Crewmates):\nAs the Jailer, use your kill button to lock a player in jail. During the next meeting, the jailed player cannot vote or get voted (the vote count will be 0). The Jailer may choose to execute the prisoner by voting for them. If the Jailer executes an innocent player, the Jailer loses the ability to execute for the rest of the game.\nIf the Jailer is evil, then they can execute anyone.\nThe Jailer has limited executions.\n\nNote: Jailed players cannot be guessed or judged, and jailed players can only guess Jailer.", + "SnitchInfoLong": "(Crewmates):\nAfter the Snitch completes all tasks, they can see the Impostor's names displayed in red on the meeting. When the Snitch has only one task left, the Impostors will see a 「★」 mark next to the name of themselves and the Snitch. When a Snitch becomes a Madmate, the 「★」 mark turns red.", + "MarshallInfoLong": "(Crewmates):\nAs the Marshall, complete your tasks to reveal yourself to the rest of the Crew.\nOther teams will not be able to see you.\nHowever, madmates CAN see you.", + "DoctorInfoLong": "(Crewmates):\nDoctor can see the cause of death for all players. In addition, the Doctor can access vitals wherever you are while he still has battery left.", + "DictatorInfoLong": "(Crewmates):\nWhen the Dictator votes for someone, the meeting will end on the spot, and the player they voted for will be ejected from the meeting. The moment the Dictator votes someone out, the Dictator will also die.", + "DetectiveInfoLong": "(Crewmate):\nAfter the Detective reports the body, they will receive a clue message, which will tell the Detective what the victim's role is. According to the Host's settings, the Detective may know what the murderer's role is. Note: Detective won't be Oblivious.", + "UndercoverInfoLong": "(Crewmates):\nThe Impostors knows who Undercover is and sees him as a teammate, but Undercover himself does not know who the Impostors are.", + "NiceGuesserInfoLong": "(Crewmates):\nThe Nice Guesser can guess the role of a certain player during the meeting. If it is correct, it will kill the target, and if it is wrong, Nice Guesser will suicide.\nThe guessing command is: /bt [player id] [role]\nYou can see the player's id before the player's name or use the /id command to view the id of all players.\nNice Guesser can guess crewmate when become madmate.", + "GuessMasterInfoLong": "(Crewmates):\nAs the Guess Master, you will receive information about every attempted guess made during a meeting. You will be informed about the role the guesser tried to guess, and you will also be notified in case of a misguess.", + "KnightInfoLong": "(Crewmates):\nThe Knight has no tasks. They can kill anyone but only do it once the whole game.", + "TransporterInfoLong": "(Crewmates):\nWhenever the Transporter completes the task, two random players will switch positions, but if there are not enough players left, nothing will happen. Note: Players in the vent will not be selected.", + "TimeManagerInfoLong": "(Crewmates):\nThe more tasks the Time Manager does, the longer the meeting time will be. When the Time Manager dies, the meeting time will return to normal. When the Time Manager becomes a Madmate, the skill changes to reducing the meeting time instead of increasing it.", + "VeteranInfoLong": "(Crewmates):\nAs the Veteran, you can enter the alert state by venting. If a player tries to kill the Veteran in the alert state, the Veteran will kill the murderer instead. Veteran will see a shield animation on their body and a text above their head as a reminder when they enter and exit the alert state.", + "BastionInfoLong": "(Crewmates):\nAs the Bastion, bomb vents to kill off impostors and neutrals.\nBe careful though; crewmates can also be killed with the bombs.", + "CopyCatInfoLong": "(Crewmate):\nAs the Copycat, you can use your kill button to copy the target's role.\n\nYou can only copy some crewmate roles.\nIf you try to copy a madmate or rascal, you become the madmate variation of the target role.\nIf you target an evil with a crewmate variant, you'll become the crewmate variant.\n\nAdditionally, Your role will be set back to Copycat after every meeting.\nNote You can't guess people in meetings.", + "BodyguardInfoLong": "(Crewmates):\nIf a player is about to be killed near the Bodyguard, the Bodyguard will prevent the kill and die with the murderer. The Bodyguard's skills will affect players of any team. When the Bodyguard becomes a Madmate, and the murderer is an Impostor, the Bodyguard will not activate the skill.", + "DeceiverInfoLong": "(Crewmates):\nThe Deceiver can sell the counterfeit to other players through the kill button. If the counterfeit is sold successfully, the Deceiver will see a shield animation on their body as a reminder. The counterfeit will take effect after the end of the next meeting. If the player with no kill ability holds the counterfeit, he will kill himself immediately. If the player with the killing ability has the counterfeit, he will commit suicide when he tries to kill someone next time.", + "GrenadierInfoLong": "(Crewmates):\nAs the Grenadier, you can vent to Flashbang players nearby, causing them to lose vision if they are an Impostor or, depending on settings, a Neutral.", + "MedicInfoLong": "(Crewmates):\nThe Medic can place a shield on the target by pressing the Kill button. The Medic can only give one shield for the whole game. Depending on the settings, the target's shield can or cannot deactivate when the Medic dies. The Medic can also see if someone is trying to break the target's shield.\nDepending on the Host's settings, the Medic or the target can see if the player has a shield (shown as a green circle 「●」 next to the name).", + "FortuneTellerInfoLong": "(Crewmates):\nAs the Fortune Teller, vote for a player in a meeting to get a clue to their role.\nThe clue will relate to their actual role.\n\nWhen the Fortune Teller's tasks are complete, they will obtain the exact role rather than a clue!\n\nNote: If the setting to give random active players as a hint is on, you cannot check the same player multiple times.", + "JudgeInfoLong": "(Crewmates):\nThe Judge can judge a certain player during the meeting. If the target is evil, the target will be killed (whether it is evil or not is set by the Host). If it is wrong, the Judge commits suicide.\nCommand for judgment: /tl [player id]\nYou can see the player's id before the player's name, or use the /id command to view the id of all players.\nJudges can judge all players when they become Madmate.", + "MorticianInfoLong": "(Crewmates):\nThe Mortician can see arrows pointing to all dead bodies, and if the Mortician reports a body, they will know the last player the victim had contact with. Note: Mortician won't be Oblivious or Seer.", + "MediumInfoLong": "(Crewmates):\nThe Medium can establish contact with a dead player after someone reports a dead body. The player who reports doesn't have to be the Medium. The dead player can answer once with a YES or a NO to the Medium's question, which only the Medium will see (the dead player can use /ms yes or /ms no). Note: Medium won't be Oblivious.", + "ObserverInfoLong": "(Crewmates):\nAs the Observer, you can see all shield animations caused by other players after the first meeting. The shied animations typically indicate a role ability, so look out for this.", + "MonarchInfoLong": "(Crewmates):\nAs the Monarch, you can knight players to give them an extra vote.\n\nYou cannot knight someone who already has multiple votes.\n\nKnighted players appear with a golden name.\nIf a knighted player is alive, the Monarch cannot be guessed or killed.", + "PacifistInfoLong": "(Crewmates):\nWhen the Pacifist vents, they will reset the kill cooldown for every player with a kill button. When they become a Madmate, this ability will only work on Crewmates.", + "OverseerInfoLong": "(Crewmates):\nAs The Overseer, you have minimal vision, but you can use your kill button to reveal the role of a nearby player. A 「○」 will be displayed next to the revealed target after you use the kill button on them, and you will also be scanning them (only you can see this). Stay near the target for a defined time to reveal his role; if you move too far away, the reveal will cancel.", + "CoronerInfoLong": "(Crewmates):\nAs a Coroner, you can't report corpses; instead, after trying to report the corpse, you will see an arrow leading you to the killer. If someone calls a meeting, the arrows disappear. Depending on the settings, players can't report the body you found.", + "PresidentInfoLong": "(Crewmates):\nThe President has two abilities: End the meeting and Reveal identity.\n\n+ Ability 1: End the meeting - Type /finish in meetings as President to instantly end the meeting.\n+ Ability 2: Reveal identity - Type /reveal in meetings to reveal yourself. Revealing yourself will make it so every player can see that you are the President, and you will become unguessable after typing the command. However, after the President has revealed themselves, whoever killed the President will have their kill CD greatly reduced on their next kill.", + "MerchantInfoLong": "(Crewmates):\nAs a merchant, you sell a random add-on to a random player for each task you complete. Each add-on sold earns you money. If you have a certain amount of money, you can prevent the next killing attempt against you by bribing the murderer. The bribed player won't be able to kill you, but you don't know who it is. The money used is lost and not available for additional bribes.", + "RetributionistInfoLong": "(Crewmates):\nAs the Retributionist, you can kill a limited amount of players after your death.\n\nUse /ret [playerID] to kill.", + "HawkInfoLong": "(Crewmates [Ghost]):\nAs the Hawk, you can kill a limited amount of players decided by the host, though there's a chance you miss, slicing someone multiple times increases the chances.", + "DeputyInfoLong": "(Crewmates):\nAs the Deputy, use your kill button on a player to reset their kill cooldown.\n\nIf the target does not have a kill button, then the handcuff was a waste.", + "InvestigatorInfoLong": "(Crewmates):\nAs an Investigator, you can use your kill button to investigate someone. When you investigate someone, their name will appear in red if they possess a kill button (impostor/SS basis) or light blue if they lack a kill button (crewmate/engineer/scientist basis). However, please note that the color of the names will return to normal when someone calls a meeting.", + "GuardianInfoLong": "(Crewmates):\nAs the Guardian, you become immortal upon task completion. Guessers can't even guess you in meetings.", + "AddictInfoLong": "(Crewmates):\nAs the Addict, you have a suicide timer. When it expires, you kill yourself.\nThe timer is indicated by the vent cooldown. When the vent cooldown is 0 seconds, you still have a short time to vent.\nIf you don't make it, you die; if you make it, the suicide timer is reset.\nAlso after you vent, no one can interact with you for a defined period.\nAfter; the period is over, and you are immobilized for another defined period, and cannot report any bodies.", + "MoleInfoLong": "(Crewmates):\nAs the Mole, when you vent, you stay in the vent for 1 second. When you exit the vent, you will spawn near a random vent in the map (Except the one you used).", + "AlchemistInfoLong": "(Crewmates):\nAs the Alchemist, you brew potions when you complete tasks. The potion you made will show up under your role name with its corresponding description and instructions. You can get seven different potions, some with harmful or no effects. Vent to use the potion.", + "KamikazeInfoLong": "(Impostors):\nAs the Kamikaze you can single click to mark people. Double-click to kill normally. When you die, all marked also die, with death reason Targeted.", + "TracefinderInfoLong": "(Crewmates):\nAs the Tracefinder, you can access vitals at any time.\nIn addition, you get arrows pointing to dead bodies, with a delay set by the Host.", + "OracleInfoLong": "(Crewmates):\nAs the Oracle, you may vote a player during a meeting.\nYou'll see if they are a Crewmate, Neutral, or Impostor.\nDepending on settings, there can be a chance that your result will be incorrect.", + "SpiritualistInfoLong": "(Crewmates):\nAs the Spiritualist, you get an arrow pointing towards the ghost of the last meeting's victim. There is an option for the arrow to disappear and reappear in intervals. Try to notify the ghost about your ability if you can; if they are on your side, they may lead you to an evil role so you can eject them. Be careful, as evil roles can do the same for Crewmates.", + "ChameleonInfoLong": "(Crewmates):\nAs the Chameleon, you can vent to Vanish temporarily. You will still appear visible on your screen. Vent again to become visible.", + "InspectorInfoLong": "(Crewmates):\nCheck If two players are in the same team or not. You will get an affirmation message if they are on the same team or a denial message if they are not on the same team.\n\nAll neutrals and converted players are counted in the same team. Trickster counts as Crew, and Rascal counts as Impostor.\nChecking command: /cmp [player id 1] [player id 2].", + "CaptainInfoLong": "(Crewmates):\nWith each completed task, the Captain gains the power to slow down a random non-crew role. Crewmates can see ☆besides Captain's name.\n\nIf anyone betrays the Captain's trust by voting Captain out, they will lose an add-on.", + "AdmirerInfoLong": "(Crewmates):\nAs the Admirer, admire a player to make them Crewmate aligned.\nThey'll win with crewmates and not their original team.\n\nYou can only do this once per player.", + "TimeMasterInfoLong": "(Crewmates):\nAs the Time Master, use the vents to mark everyone's position.\nWhen using the ability again, every alive player will rewind to the marked positions.\n\nDuring the ability duration, the Time Master gains a time shield, which protects them from death.", + "CrusaderInfoLong": "(Crewmates):\nAs the Crusader, use your kill button to crusade a player.\nIf that player gets attacked, you'll kill the attacker.", + "AltruistInfoLong": "(Crewmates):\nAs the Altruist, you can sacrifice yourself to revive a dead body using the «Report» button.\nNote: If a dead player has left the game, you report that body normally.\nAlso revived player cannot report self dead body", + "ReverieInfoLong": "(Crewmates):\nAs the Reverie, you can kill, but your cooldown starts high.\n\nIt increases if you kill a crewmate and reduces otherwise.\nDepending on the Host's setting, you may misfire on reaching the max kill cooldown, and your target dies with you. \n\nYou win with other crewmates.", + "LookoutInfoLong": "(Crewmates):\nAs the Lookout, you can see the IDs of every player at all times.\nThis allows you to see through shapeshifts and camouflages.", + "TelecommunicationInfoLong": "(Crewmates):\nAs the Telecommunication, you are notified when anyone uses cameras, vitals, door logs, or admin.", + "LighterInfoLong": "(Crewmate):\nAs the Lighter, you can vent to increase your vision temporarily.\nYou have increased vision both when lights are not out and when lights are out.\nUse this power to catch sneaky killers!", + "TaskManagerInfoLong": "(Crewmates):\nYou see the total number of tasks completed (by everyone all together) next to your role name, which updates in real-time.", + "WitnessInfoLong": "(Crewmates):\nAs the Witness, when you use your kill button on someone, you will know if they killed in the last X seconds or not. (X depends on the settings).", + "SwapperInfoLong": "(Crewmates):\nAs the Swapper, you can swap votes in meetings.\n\nTo swap votes, use '/sw [playerID]' twice.\n\nPlayer IDs are displayed next to player names in meetings, but you can also use /id to get a list of all player IDs.\n\nNote: Depending on the Host's settings, you can exchange your own votes.", "ChiefOfPoliceInfoLong": "(Crewmates):\nPlayers with swords can be recruited to join the sheriff's team to serve the crew\nNote: only one recruitment opportunity\nDepending on settings, you may recruit non killers or non crews.\nYou may suidice for recruiting wrong target.", - "NiceMiniInfoLong": "(Crewmates):\nAs a Nice Mini, your survival is crucial. You can't be killed until you grow up, and if you die or are evicted from the meeting before you grow up, everyone loses. This unique role adds a new dynamic to the game, where your survival is not just for your benefit but for the entire Crew's success.", - "SpyInfoLong": "(Crewmates):\nAs the Spy, when someone uses their kill button on you (any ability used through the kill button), you'll see their name in orange for a few seconds.\nNote: If a Crewmate used their ability on you, you'll also see them with an orange name!\nNote: If you cannot use left, you won't see orange names!\nNote: If the kill button interaction is blocked, the player's cooldown will reset to 10s'", - "RandomizerInfoLong": "(Crewmates):\nAs this Randomizer, when you die, your killer will do one of the following:\n 1. self-report your body\n 2. stand next to your body\n 3. have their kill cooldown set to 600s\n 4. Randomly avenge a player.", - "ArsonistInfoLong": "(Neutrals):\nThe Arsonist can douse a player by clicking the kill button on the player and following them for a few seconds. When the dousing starts and it's successful, a shield animation will happen as a reminder (only visible to themselves). When the Arsonist has doused all surviving players, the Arsonist can vent to start the fire and win alone.\n\nIf the player name shows 「△」, that means they are being doused;\nif the player name shows 「▲」, it means they have been completely doused.\nDepending on the setting, Arsonist may start the fire anytime. But if he fails to kill everyone, he loses.", - "EnigmaInfoLong": "(Crewmates):\nAs the Enigma, you get a random clue about the killer each meeting. Depending on the settings, you may have to report the body to receive a clue. The more tasks you complete, the more precise the clues get.", - "PyromaniacInfoLong": "(Neutrals):\nAs the Pyromaniac, you can douse players (single click) or kill normally (double click). Dousing players do nothing immediately, but killing a doused player will significantly shorten your kill cooldown. To win, be the last player alive.", - "HuntsmanInfoLong": "(Neutrals):\nAs the Huntsman, you are given a certain number of targets that reset every meeting. If you successfully eliminate one of your targets, your kill cooldown goes down permanently by the set amount. However, if you kill someone not one of your targets, your kill cooldown permanently increases by the set amount. A colored name indicates your targets.", - "MiniInfoLong": "(Crewmate or Impostor):\nThe Mini has two roles. A Nice or Evil Mini is chosen.\n\nUse'/r nice mini' and '/r evil mini' respectively for more details.", - "JesterInfoLong": "(Neutrals):\nIf the Jester gets voted out, the Jester wins the game alone. If the Jester is still alive at the end of the game, the Jester loses. Note: Jester, Executioner, and Innocent can win together.", - "TerroristInfoLong": "(Neutrals):\nIf the Terrorist dies after completing all tasks, the Terrorist wins the game alone. (They can win by either being voted out or killed).", - "ExecutionerInfoLong": "(Neutrals):\nThe Executioner is a role with an execution target, indicated by a diamond symbol「♦」next to their name. If the execution target is killed, the Executioner's role will change to Crewmate, Jester, or Opportunist, depending on the game settings. However, if the execution target is voted out in the meeting, the Executioner wins. Note: Jester, Executioner, and Innocent can win together.", - "LawyerInfoLong": "(Neutrals):\nLawyer has a target to defend, which will be indicated by a diamond 「♦」 next to their name.\nIf your target wins, you win.\nIf they lose, you lose.", - "OpportunistInfoLong": "(Neutrals):\nIf the Opportunist survives at the end of the game, the Opportunist will win with the winning player.", - "VectorInfoLong": "(Neutrals):\nVector will win alone by venting a certain number of times.", + "NiceMiniInfoLong": "(Crewmates):\nAs a Nice Mini, your survival is crucial. You can't be killed until you grow up, and if you die or are evicted from the meeting before you grow up, everyone loses. This unique role adds a new dynamic to the game, where your survival is not just for your benefit but for the entire Crew's success.", + "SpyInfoLong": "(Crewmates):\nAs the Spy, when someone uses their kill button on you (any ability used through the kill button), you'll see their name in orange for a few seconds.\nNote: If a Crewmate used their ability on you, you'll also see them with an orange name!\nNote: If you cannot use left, you won't see orange names!\nNote: If the kill button interaction is blocked, the player's cooldown will reset to 10s'", + "RandomizerInfoLong": "You have no set role as the randomizer, every time a meeting ends your role and add ons will be completely randomized. due to the random nature of this role it doesn't use the win condition of the role it is to avoid victory being entirely luck based. so to prevent that from happening the first role you gain is what dictates your win contition.\nIf you get a crewmate role then you win with the crewmates\nIf you get a Neutral role then you win if you survive till the end of the game\nIf you get a impostor role then you win with the impostor", + "ArsonistInfoLong": "(Neutrals):\nThe Arsonist can douse a player by clicking the kill button on the player and following them for a few seconds. When the dousing starts and it's successful, a shield animation will happen as a reminder (only visible to themselves). When the Arsonist has doused all surviving players, the Arsonist can vent to start the fire and win alone.\n\nIf the player name shows 「△」, that means they are being doused;\nif the player name shows 「▲」, it means they have been completely doused.\nDepending on the setting, Arsonist may start the fire anytime. But if he fails to kill everyone, he loses.", + "EnigmaInfoLong": "(Crewmates):\nAs the Enigma, you get a random clue about the killer each meeting. Depending on the settings, you may have to report the body to receive a clue. The more tasks you complete, the more precise the clues get.", + "PyromaniacInfoLong": "(Neutrals):\nAs the Pyromaniac, you can douse players (single click) or kill normally (double click). Dousing players do nothing immediately, but killing a doused player will significantly shorten your kill cooldown. To win, be the last player alive.", + "HuntsmanInfoLong": "(Neutrals):\nAs the Huntsman, you are given a certain number of targets that reset every meeting. If you successfully eliminate one of your targets, your kill cooldown goes down permanently by the set amount. However, if you kill someone not one of your targets, your kill cooldown permanently increases by the set amount. A colored name indicates your targets.", + "MiniInfoLong": "(Crewmate or Impostor):\nThe Mini has two roles. A Nice or Evil Mini is chosen.\n\nUse'/r nice mini' and '/r evil mini' respectively for more details.", + "JesterInfoLong": "(Neutrals):\nIf the Jester gets voted out, the Jester wins the game alone. If the Jester is still alive at the end of the game, the Jester loses. Note: Jester, Executioner, and Innocent can win together.", + "TerroristInfoLong": "(Neutrals):\nIf the Terrorist dies after completing all tasks, the Terrorist wins the game alone. (They can win by either being voted out or killed).", + "ExecutionerInfoLong": "(Neutrals):\nThe Executioner is a role with an execution target, indicated by a diamond symbol「♦」next to their name. If the execution target is killed, the Executioner's role will change to Crewmate, Jester, or Opportunist, depending on the game settings. However, if the execution target is voted out in the meeting, the Executioner wins. Note: Jester, Executioner, and Innocent can win together.", + "LawyerInfoLong": "(Neutrals):\nLawyer has a target to defend, which will be indicated by a diamond 「♦」 next to their name.\nIf your target wins, you win.\nIf they lose, you lose.", + "OpportunistInfoLong": "(Neutrals):\nIf the Opportunist survives at the end of the game, the Opportunist will win with the winning player.", + "VectorInfoLong": "(Neutrals):\nVector will win alone by venting a certain number of times.", "JackalInfoLong": "(Neutrals):\nAs the Jackal, you win if you are the last player alive. Additionally, you may recruit using the kill button. If the target is not one you can recruit, you have run out of uses, or you don't have the option to recruit, then you will kill people normally (i.e., don't use kill buttons in front of others thinking it'll recruit). If the target has a kill button and the option to turn into a Sidekick is on, they will become a Sidekick. Otherwise, they will gain the Recruit add-on if the option to give the Recruit add-on is on.\nDepending on the settings, when Jackal was killed, a Sidekick will be randomly selected as the new Jackal.\nRecruit may be selected if no sidekick is alive.", - "GodInfoLong": "(Neutrals):\nAs the God, you know everyone's role from the beginning. If you live until the end of the game, you steal the win, i.e., everyone else loses, and you win.", - "InnocentInfoLong": "(Neutrals):\nThe Innocent can use the kill button to plant any player, and the planted target will immediately kill the Innocent. If the target gets voted out in the meeting, the Innocent wins. Note: Jester, Executioner, and Innocent can win together.", - "PelicanInfoLong": "(Neutrals):\nAs the Pelican, you can use the kill button to swallow a player alive, teleporting them off-bounds but not killing them yet. Those swallowed will only die if you're still alive at the end of the round. If you die or leave during the round, all alive swallowed players will spawn into the map where you were.", - "RevolutionistInfoLong": "(Neutrals):\nAs the Revolutionist, you can recruit players by clicking the kill button on the player and following them until the shield animation plays for you. Recruiting has a chance, set by the Host, to kill players (though they are still recruited). When the required number of players are recruited (displayed next to your name), you must vent within the specified time to win the game immediately with all your recruits. If you do not vent in time, you lose and die.", - "HaterInfoLong": "(Neutrals):\nAs the Hater, you have no kill cooldown. However, depending on the settings, you can only kill Lovers and other recruiting roles and add-ons. Killing anyone else will make you suicide. You win at the end of the game with the winning team if none of the killable roles are alive. You will not be Lovers.", - "DemonInfoLong": "(Neutrals):\nAs the Demon, you kill by draining health. You see health in percentage near everyone's name, and every attack you make drains a percentage from that health without the victim knowing. Once you drain your victim's health to 0, they die. You win if you are the last one standing.", - "StalkerInfoLong": "(Neutrals):\nThe Stalker can kill anyone, and every kill will immediately cause a Lights sabotage (if Lights sabotage is already active, nothing will happen). Stalker cannot vent. If the Impostor wins while the Stalker is alive or the Crewmate wins by killing the Impostors (according to the Host's setting, the Stalker may also win when the Crewmate wins by killing the Neutrals), then the Stalker wins alone.", - "WorkaholicInfoLong": "(Neutrals):\nAs the Workaholic, you win alone when you complete all tasks. Depending on the Host's settings, you can only win if you are alive and or revealed to everyone at the beginning (these settings are rarely both on).", - "SolsticerInfoLong": "(Neutrals):\nAs the Solsticer, you won't die, and you win by finishing all your tasks in a single round. After every meeting finishes, your tasks reset, and you need to start all over again.\nVotes on the Solsticer will be directly canceled.\nKill attempts on the Solsticer will teleport it out of the map like Pelican until the meeting is finished.\nThe killer's kill cooldown will be reset to 10 seconds.\nSolsticer is counted as nothing in-game.", - "CollectorInfoLong": "(Neutrals):\nAs the Collector, when you vote for a player, for each other player that voted for them, you gain a point. When you collect the required votes, the game ends, and you win alone, even if you voted a Jester or Executioner's target out.", - "GlitchInfoLong": "(Neutrals):\nAs the Glitch, you can hack players (single click) or kill normally (double click).\nThose who have been hacked cannot kill, vent, or report for the hack duration.\nAdditionally, calling a sabotage other than doors will have no effect and will instead disguise you as a random player. You cannot disguise during or after sabotages.\nTo win, be the last player alive.", + "GodInfoLong": "(Neutrals):\nAs the God, you know everyone's role from the beginning. If you live until the end of the game, you steal the win, i.e., everyone else loses, and you win.", + "InnocentInfoLong": "(Neutrals):\nThe Innocent can use the kill button to plant any player, and the planted target will immediately kill the Innocent. If the target gets voted out in the meeting, the Innocent wins. Note: Jester, Executioner, and Innocent can win together.", + "PelicanInfoLong": "(Neutrals):\nAs the Pelican, you can use the kill button to swallow a player alive, teleporting them off-bounds but not killing them yet. Those swallowed will only die if you're still alive at the end of the round. If you die or leave during the round, all alive swallowed players will spawn into the map where you were.", + "RevolutionistInfoLong": "(Neutrals):\nAs the Revolutionist, you can recruit players by clicking the kill button on the player and following them until the shield animation plays for you. Recruiting has a chance, set by the Host, to kill players (though they are still recruited). When the required number of players are recruited (displayed next to your name), you must vent within the specified time to win the game immediately with all your recruits. If you do not vent in time, you lose and die.", + "HaterInfoLong": "(Neutrals):\nAs the Hater, you have no kill cooldown. However, depending on the settings, you can only kill Lovers and other recruiting roles and add-ons. Killing anyone else will make you suicide. You win at the end of the game with the winning team if none of the killable roles are alive. You will not be Lovers.", + "DemonInfoLong": "(Neutrals):\nAs the Demon, you kill by draining health. You see health in percentage near everyone's name, and every attack you make drains a percentage from that health without the victim knowing. Once you drain your victim's health to 0, they die. You win if you are the last one standing.", + "StalkerInfoLong": "(Neutrals):\nThe Stalker can kill anyone, and every kill will immediately cause a Lights sabotage (if Lights sabotage is already active, nothing will happen). Stalker cannot vent. If the Impostor wins while the Stalker is alive or the Crewmate wins by killing the Impostors (according to the Host's setting, the Stalker may also win when the Crewmate wins by killing the Neutrals), then the Stalker wins alone.", + "WorkaholicInfoLong": "(Neutrals):\nAs the Workaholic, you win alone when you complete all tasks. Depending on the Host's settings, you can only win if you are alive and or revealed to everyone at the beginning (these settings are rarely both on).", + "SolsticerInfoLong": "(Neutrals):\nAs the Solsticer, you won't die, and you win by finishing all your tasks in a single round. After every meeting finishes, your tasks reset, and you need to start all over again.\nVotes on the Solsticer will be directly canceled.\nKill attempts on the Solsticer will teleport it out of the map like Pelican until the meeting is finished.\nThe killer's kill cooldown will be reset to 10 seconds.\nSolsticer is counted as nothing in-game.", + "CollectorInfoLong": "(Neutrals):\nAs the Collector, when you vote for a player, for each other player that voted for them, you gain a point. When you collect the required votes, the game ends, and you win alone, even if you voted a Jester or Executioner's target out.", + "GlitchInfoLong": "(Neutrals):\nAs the Glitch, you can hack players (single click) or kill normally (double click).\nThose who have been hacked cannot kill, vent, or report for the hack duration.\nAdditionally, calling a sabotage other than doors will have no effect and will instead disguise you as a random player. You cannot disguise during or after sabotages.\nTo win, be the last player alive.", "SidekickInfoLong": "(Neutrals):\nAs the Sidekick, your job is to help the Jackal kill everyone.\nYou and the Jackal win together.\nDepending on the settings, you may turn into Jackal if old Jackal was killed.\nYou may not be able to kill until old Jackal is dead.", - "ProvocateurInfoLong": "(Neutrals):\nAs the Provocateur, you can kill any target with the kill button. If the target loses at the end of the game, the Provocateur wins with the winning team.", - "BloodKnightInfoLong": "(Neutrals):\nThe Blood Knight wins when they're the last killing role alive, and the amount of crewmates is lower or equal to the amount of Blood Knights. The Blood Knight gains a temporary shield after every kill, making them immortal for a few seconds.", - "PlagueBearerInfoLong": "(Apocalypse):\nAs the Plaguebearer, plague everyone using your kill button to turn into Pestilence.\nOnce you turn into Pestilence, you will become immortal and gain the ability to kill, and you will kill anyone who tries to kill you.\n\nAlso, when infected players interact with uninfected players, they will also be infected.", - "PestilenceInfoLong": "(Apocalypse):\nAs Pestilence, you're an unstoppable machine.\nAny attack towards you will be reflected towards them.\nIndirect kills don't even kill you.\n\nOnly way to kill Pestilence is by voting them out or the Pestilence misguessing.\nYour presence is announced to everyone at the meeting after you transform.", - "SoulCollectorInfoLong": "(Apocalypse):\nAs Soul Collector, you can use your kill button on a player to predict their death. You will gain a soul if your target dies in the round you select them or the meeting after.\nYour target resets after each meeting or after they die, whichever comes first. \n\nOnce you collect the configurable amount of souls, you become Death. If the gain passive souls setting is enabled, you will gain a soul each meeting.", - "DeathInfoLong": "(Apocalypse):\nOnce the Soul Collector has collected their needed souls, they become Death. Death kills everyone and wins if Death is not ejected by the end of the next meeting.\nA configurable amount of extra meeting time will be given on the meeting Death transforms to have more discussion to find Death.\n\nYou are invincible, and your presence is announced to everyone at the meeting after you transform.", - "BakerInfoLong": "(Apocalypse):\nAs the Baker, you can use your kill button on a player per round to give them bread. \nOnce a set amount of players are alive with bread, you become Famine.\n\nIf the Bread gives additional effects and the setting is on, then you can vent to change the bread that you give out. \nBread Effects:\nReveal: Reveals the target's role to the Baker (stays the whole game)\nRoleblock: Sets the target's kill cooldown to 999 (resets to normal after the meeting)\nBarrier: Gives the target a barrier that is only known to the Baker (barrier is removed after the meeting)", - "FamineInfoLong": "(Apocalypse):\nOnce the Baker has a set amount of people with bread alive, they will become Famine. If the Famine does not get voted out after the meeting, then they will become Famine, and every player without bread will starve (excluding other Apocalypse members).\nAfter this starvation of everyone without bread, Famine can use their kill button to starve any remaining players, which will kill those players right before the next meeting.\n\nYou are invincible, and your presence is announced to everyone at the meeting after you transform.", - "BerserkerInfoLong": "(Apocalypse):\nAs the Berserker, you level up with each kill.\nUpon reaching a certain level defined by the Host, you unlock a new power.\n\nScavenged kills make your kills disappear.\nBombed kills make your kills explode. Be careful when killing, as this can kill your other Apocalypse members if they are near. \nAfter a certain level, you become War.", - "WarInfoLong": "(Apocalypse):\nAs War, you are invincible, have a lower kill cooldown, and can kill anyone with your previous powers.\nYour presence is announced to everyone at the meeting after you transform.", - "FollowerInfoLong": "(Neutrals):\nThe Follower can use their Kill button on someone to start following them and can use the Kill button again to switch the following target. If the Follower's target wins, the Follower will win along with them. Note: The Follower can also win after they die.", - "CultistInfoLong": "(Neutrals):\nAs the Cultist, your kill button is used to Charm others, making them win with you. To win, charm all who pose a threat and gain the majority.\nDepending on settings, you may be able to charm Neutrals, and those you Charm may count as their original team, nothing, or a Cultist to determine when you win due to majority.", - "SerialKillerInfoLong": "(Neutrals):\nAs the Serial Killer, you win if you are the last player alive.", - "JuggernautInfoLong": "(Neutrals):\nAs the Juggernaut, your kill cooldown decreases with each kill you make.\n\nKill everyone to win.", - "InfectiousInfoLong": "(Neutrals):\nAs the Infectious, your job is to infect as many players as you can.\n\nIf you infect all the killers, you can outnumber the Crew and win the game.\n\nIf you die, all the players you've infected will die after the next meeting.\nIf they achieve your win condition before then, you can still win.", - "VirusInfoLong": "(Neutrals):\nThe task of the Virus is to kill or infect all other players. When the Virus murders a crewmate, their corpse is infected with a virus. The Crewmate who reports this corpse is infected joins the virus team or dies at the end of the meeting if the Virus doesn't get voted out, depending on the settings. If more players are on the Virus team than the Crewmate team, the Virus team wins.", - "PursuerInfoLong": "(Neutrals):\nAs the Pursuer, you can use your ability on someone to make them misfire when they try to kill.\n\nTo win, survive to the end of the game.", - "SpecterInfoLong": "(Neutrals):\nAs the Specter, your job is to get killed and finish your tasks.\nYou can do your tasks while alive.\nYou cannot win if you're alive.\nIf you get killed, you win with the winning team if your tasks are completed.", - "PirateInfoLong": "(Neutrals):\nAs the Pirate, use your kill button to select a target every round.\nYou will duel with your target in the next meeting. \nIf both the Pirate and the target choose the same number, the Pirate wins.\nAdditionally, if the Pirate wins the duel or the target doesn't participate in the duel, the Pirate kills the target.\n\nDueling command: /duel X (where X can be 0, 1, or 2)\n\nYou win after winning a certain number of duels set by the Host.\n\nNote: The kill would not count towards pirate victory if the target did not participate in the duel.", - "AgitaterInfoLong": "(Neutrals):\nAs the Agitator, your premise is essentially Hot Potato.\n\nUse your kill button on a player to pass the bomb.\nThis can only be done once per round.\n\nThe player who receives the bomb will be notified when receiving said bomb, in which they need to pass it to another player by getting near a player.\n\nWhen a meeting is called, the player with the bomb dies.\n\nIf trying to pass to Pestilence or a Veteran on alert, the bombed player dies instead.\nOptionally, the Agitator cannot receive the bomb.", - "MaverickInfoLong": "(Neutrals):\nAs the Maverick, you can kill and, depending on options, vent and have impostor vision\nIf you survive until the end of the game, you win with the winning team.\nUse your killing ability to eliminate threats to your life, but don't get voted out.", - "CursedSoulInfoLong": "(Neutrals):\nAs the Cursed Soul, you steal the victory if you survive to the end of the game.\n\nYou can steal the win from a Jester or Executioner.\n\nAdditionally, you can steal the souls of other players.\nSoulless players win with you and count as dead.", - "PickpocketInfoLong": "(Neutrals):\nAs the Pickpocket, you steal votes from your kills.\n\nKill everyone to win.", - "TraitorInfoLong": "(Neutrals):\nAs the Traitor, you were an Impostor that betrayed the Impostors.\nYou know the Impostors, but they don't know you.\nThe twist? They can kill you, but you can't kill them.\n\nEliminate the Impostors by other means, then kill everyone else to win!", - "TrollerInfoLong": "(Neutrals):\nAs a Troller, you can complete tasks so that random events can happen to players.\nFor example, changing the speed of all players, teleportation, influencing sabotage, etc.\nAlso you can win with the winning team.", - "VultureInfoLong": "(Neutrals):\nAs the Vulture, report bodies to win!\n\nWhen you report a body, if your eat cooldown is up, you'll eat the body (makes it unreportable).\nIf your eat ability is still on cooldown, then you'll report the body normally.\n\nAdditionally, you'll report bodies normally if the maximum bodies eaten per round is reached.", + "ProvocateurInfoLong": "(Neutrals):\nAs the Provocateur, you can kill any target with the kill button. If the target loses at the end of the game, the Provocateur wins with the winning team.", + "BloodKnightInfoLong": "(Neutrals):\nThe Blood Knight wins when they're the last killing role alive, and the amount of crewmates is lower or equal to the amount of Blood Knights. The Blood Knight gains a temporary shield after every kill, making them immortal for a few seconds.", + "PlagueBearerInfoLong": "(Apocalypse):\nAs the Plaguebearer, plague everyone using your kill button to turn into Pestilence.\nOnce you turn into Pestilence, you will become immortal and gain the ability to kill, and you will kill anyone who tries to kill you.\n\nAlso, when infected players interact with uninfected players, they will also be infected.", + "PestilenceInfoLong": "(Apocalypse):\nAs Pestilence, you're an unstoppable machine.\nAny attack towards you will be reflected towards them.\nIndirect kills don't even kill you.\n\nOnly way to kill Pestilence is by voting them out or the Pestilence misguessing.\nYour presence is announced to everyone at the meeting after you transform.", + "SoulCollectorInfoLong": "(Apocalypse):\nAs Soul Collector, you can use your kill button on a player to predict their death. You will gain a soul if your target dies in the round you select them or the meeting after.\nYour target resets after each meeting or after they die, whichever comes first. \n\nOnce you collect the configurable amount of souls, you become Death. If the gain passive souls setting is enabled, you will gain a soul each meeting.", + "DeathInfoLong": "(Apocalypse):\nOnce the Soul Collector has collected their needed souls, they become Death. Death kills everyone and wins if Death is not ejected by the end of the next meeting.\nA configurable amount of extra meeting time will be given on the meeting Death transforms to have more discussion to find Death.\n\nYou are invincible, and your presence is announced to everyone at the meeting after you transform.", + "BakerInfoLong": "(Apocalypse):\nAs the Baker, you can use your kill button on a player per round to give them bread. \nOnce a set amount of players are alive with bread, you become Famine.\n\nIf the Bread gives additional effects and the setting is on, then you can vent to change the bread that you give out. \nBread Effects:\nReveal: Reveals the target's role to the Baker (stays the whole game)\nRoleblock: Sets the target's kill cooldown to 999 (resets to normal after the meeting)\nBarrier: Gives the target a barrier that is only known to the Baker (barrier is removed after the meeting)", + "FamineInfoLong": "(Apocalypse):\nOnce the Baker has a set amount of people with bread alive, they will become Famine. If the Famine does not get voted out after the meeting, then they will become Famine, and every player without bread will starve (excluding other Apocalypse members).\nAfter this starvation of everyone without bread, Famine can use their kill button to starve any remaining players, which will kill those players right before the next meeting.\n\nYou are invincible, and your presence is announced to everyone at the meeting after you transform.", + "BerserkerInfoLong": "(Apocalypse):\nAs the Berserker, you level up with each kill.\nUpon reaching a certain level defined by the Host, you unlock a new power.\n\nScavenged kills make your kills disappear.\nBombed kills make your kills explode. Be careful when killing, as this can kill your other Apocalypse members if they are near. \nAfter a certain level, you become War.", + "WarInfoLong": "(Apocalypse):\nAs War, you are invincible, have a lower kill cooldown, and can kill anyone with your previous powers.\nYour presence is announced to everyone at the meeting after you transform.", + "FollowerInfoLong": "(Neutrals):\nThe Follower can use their Kill button on someone to start following them and can use the Kill button again to switch the following target. If the Follower's target wins, the Follower will win along with them. Note: The Follower can also win after they die.", + "CultistInfoLong": "(Neutrals):\nAs the Cultist, your kill button is used to Charm others, making them win with you. To win, charm all who pose a threat and gain the majority.\nDepending on settings, you may be able to charm Neutrals, and those you Charm may count as their original team, nothing, or a Cultist to determine when you win due to majority.", + "SerialKillerInfoLong": "(Neutrals):\nAs the Serial Killer, you win if you are the last player alive.", + "JuggernautInfoLong": "(Neutrals):\nAs the Juggernaut, your kill cooldown decreases with each kill you make.\n\nKill everyone to win.", + "InfectiousInfoLong": "(Neutrals):\nAs the Infectious, your job is to infect as many players as you can.\n\nIf you infect all the killers, you can outnumber the Crew and win the game.\n\nIf you die, all the players you've infected will die after the next meeting.\nIf they achieve your win condition before then, you can still win.", + "VirusInfoLong": "(Neutrals):\nThe task of the Virus is to kill or infect all other players. When the Virus murders a crewmate, their corpse is infected with a virus. The Crewmate who reports this corpse is infected joins the virus team or dies at the end of the meeting if the Virus doesn't get voted out, depending on the settings. If more players are on the Virus team than the Crewmate team, the Virus team wins.", + "PursuerInfoLong": "(Neutrals):\nAs the Pursuer, you can use your ability on someone to make them misfire when they try to kill.\n\nTo win, survive to the end of the game.", + "SpecterInfoLong": "(Neutrals):\nAs the Specter, your job is to get killed and finish your tasks.\nYou can do your tasks while alive.\nYou cannot win if you're alive.\nIf you get killed, you win with the winning team if your tasks are completed.", + "PirateInfoLong": "(Neutrals):\nAs the Pirate, use your kill button to select a target every round.\nYou will duel with your target in the next meeting. \nIf both the Pirate and the target choose the same number, the Pirate wins.\nAdditionally, if the Pirate wins the duel or the target doesn't participate in the duel, the Pirate kills the target.\n\nDueling command: /duel X (where X can be 0, 1, or 2)\n\nYou win after winning a certain number of duels set by the Host.\n\nNote: The kill would not count towards pirate victory if the target did not participate in the duel.", + "AgitaterInfoLong": "(Neutrals):\nAs the Agitator, your premise is essentially Hot Potato.\n\nUse your kill button on a player to pass the bomb.\nThis can only be done once per round.\n\nThe player who receives the bomb will be notified when receiving said bomb, in which they need to pass it to another player by getting near a player.\n\nWhen a meeting is called, the player with the bomb dies.\n\nIf trying to pass to Pestilence or a Veteran on alert, the bombed player dies instead.\nOptionally, the Agitator cannot receive the bomb.", + "MaverickInfoLong": "(Neutrals):\nAs the Maverick, you can kill and, depending on options, vent and have impostor vision\nIf you survive until the end of the game, you win with the winning team.\nUse your killing ability to eliminate threats to your life, but don't get voted out.", + "CursedSoulInfoLong": "(Neutrals):\nAs the Cursed Soul, you steal the victory if you survive to the end of the game.\n\nYou can steal the win from a Jester or Executioner.\n\nAdditionally, you can steal the souls of other players.\nSoulless players win with you and count as dead.", + "PickpocketInfoLong": "(Neutrals):\nAs the Pickpocket, you steal votes from your kills.\n\nKill everyone to win.", + "TraitorInfoLong": "(Neutrals):\nAs the Traitor, you were an Impostor that betrayed the Impostors.\nYou know the Impostors, but they don't know you.\nThe twist? They can kill you, but you can't kill them.\n\nEliminate the Impostors by other means, then kill everyone else to win!", + "TrollerInfoLong": "(Neutrals):\nAs a Troller, you can complete tasks so that random events can happen to players.\nFor example, changing the speed of all players, teleportation, influencing sabotage, etc.\nAlso you can win with the winning team.", + "VultureInfoLong": "(Neutrals):\nAs the Vulture, report bodies to win!\n\nWhen you report a body, if your eat cooldown is up, you'll eat the body (makes it unreportable).\nIf your eat ability is still on cooldown, then you'll report the body normally.\n\nAdditionally, you'll report bodies normally if the maximum bodies eaten per round is reached.", "AbyssbringerInfoLong": "(Impostors):\nAs the Abyssbringer, you can place black holes. Black holes will suck in players and kill them when colliding with them.", - "TaskinatorInfoLong": "(Neutrals):\nAs the Taskinator, whenever you finish a task, the task will be bombed. When another player completes the bombed task, the bomb will detonate, and the player will die.\n\nYou win if you survive till the end and Crew doesn't win.\n\n Note: Taskinator bombs ignore all protection.", - "BenefactorInfoLong": "(Crewmates):\nAs the Benefactor, whenever you finish a task, that task will be marked. When another player completes the marked task, they get a temporary shield.\n\n Note: Shield only protects from direct kill attacks.", - "MedusaInfoLong": "(Neutrals):\nAs the Medusa, you can stone bodies much like cleaning a body.\nStoned bodies cannot be reported.\n\nKill everyone to win.", - "SpiritcallerInfoLong": "(Neutrals):\nAs the Spiritcaller, your victims become Evil Spirits after they die. These spirits can help you win by freezing other players briefly or blocking their vision. Alternatively, the spirits can give you a shield that protects you briefly from an attempted kill.", + "TaskinatorInfoLong": "(Neutrals):\nAs the Taskinator, whenever you finish a task, the task will be bombed. When another player completes the bombed task, the bomb will detonate, and the player will die.\n\nYou win if you survive till the end and Crew doesn't win.\n\n Note: Taskinator bombs ignore all protection.", + "BenefactorInfoLong": "(Crewmates):\nAs the Benefactor, whenever you finish a task, that task will be marked. When another player completes the marked task, they get a temporary shield.\n\n Note: Shield only protects from direct kill attacks.", + "MedusaInfoLong": "(Neutrals):\nAs the Medusa, you can stone bodies much like cleaning a body.\nStoned bodies cannot be reported.\n\nKill everyone to win.", + "SpiritcallerInfoLong": "(Neutrals):\nAs the Spiritcaller, your victims become Evil Spirits after they die. These spirits can help you win by freezing other players briefly or blocking their vision. Alternatively, the spirits can give you a shield that protects you briefly from an attempted kill.", "AmnesiacInfoLong": "(Neutrals):\nAs the Amnesiac, use your report button to remember a target and get its role.\nTo balance the game, you will not be able to vent after remembering your role if you can't vent as Amnesiac.'", - "ImitatorInfoLong": "(Neutrals):\nAs the Imitator, use your kill button to imitate a player.\n\nYou'll either become a Sheriff, a Refugee, or some Neutral.", - "BanditInfoLong": "(Neutrals):\nAs the Bandit, you can click your kill button one time to steal a player's addon and twice to kill. Depending on the settings, you may instantly steal the addon or after the meeting starts. After the maximum number of steals is reached, you will kill normally. Additionally, if there are no stealable addons on the target or the target is stubborn, you will kill the target.\n\nKill everyone to win.\n\nNote: Cleansed, Last Impostor, and Lovers cannot be stolen.\nNote: If Bandit can vent is on, Nimble will become unstealable.", - "DoppelgangerInfoLong": "(Neutrals):\nAs the Doppelganger, use your kill button to steal a player's identity (their name and skin) and then kill your target.\n\nKill everyone to win.\n\nNote: You cannot steal the target's identity when Camouflage is active.", - "PunchingBagInfoLong": "(Neutrals):\nAs the Punching Bag, your goal is to get attacked a few times to win.\n\nYou cannot be guessed, as that adds to your attack count.", - "DoomsayerInfoLong": "(Neutrals):\nThe Doomsayer can guess the role of a certain player during the meeting.\nIf the Doomsayer guesses a certain number of roles (the number depends on the host settings), then he wins.\nThe guessing command is: /bt [player id] [role]\nYou can see the player's id before the player's name, or use the /id command to view the id of all players.", - "ShroudInfoLong": "(Neutrals):\nAs the Shroud, you do not kill normally.\nInstead, use your kill button to shroud a player.\nShrouded players kill others.\nIf the shrouded player doesn't make a kill, they'll kill themselves after a meeting.\n\nShroud sees shrouded players with a 「◈」mark next to their name.\nShrouded players who did not make a kill will also have the 「◈」mark in meetings, where they'll die if the Shroud is alive by the end of the meeting.", - "WerewolfInfoLong": "(Neutrals):\nAs the Werewolf, you can kill much like any killer.\nHowever, when you kill, any nearby players also die.\nAny player who dies to this will have their death reason as Mauled.\n\nTo balance this, you have a higher kill cooldown than anyone else.", - "ShamanInfoLong": "(Neutrals):\nAs the Shaman, you can use your kill button to select a voodoo doll once per round. If the kill button is used on you, the effect will be deflected onto the voodoo doll.\nIf you survive until the end, you win with the winning team.\nNote: If the killer cannot kill the chosen target, murder is canceled, but if the killer rechecks the Shaman, the killer will kill the Shaman.", - "SeekerInfoLong": "(Neutrals):\nAs the seeker, use your kill button to tag the target. If the seeker tags the wrong player, a point is deducted, and if the seeker tags the correct player, a point will be added.\nAdditionally, the seeker will not be able to move for 5 seconds after every meeting and after getting a new target.\n\nThe seeker needs to collect a certain number of points set by the Host to win.", - "PixieInfoLong": "(Neutrals):\nAs the Pixie, Mark up to x amount of targets each round by using the kill button on them. You must have one of the marked targets ejected when the meeting starts. If unsuccessful, you will commit suicide, except if you didn't mark any targets or all the targets are dead. The selected targets reset to 0 after the meeting ends. If you succeed, you will gain a point. You see all your targets in colored names.\n\nYou win with the winning team when you have certain amounts of points set by the Host.", - "SchrodingersCatInfoLong": "(Neutrals):\nAs Schrodingers Cat, if someone attempts to use the kill button on you, you will block the action and join their team. This blocking ability works only once. By default, you don't have a victory condition, meaning you win only after switching teams.\nIn Addition to this, you will be counted as nothing in the game.\n\nNote: If the killing machine attempts to use its kill button on you, the interaction is not blocked, and you will die.", - "RomanticInfoLong": "(Neutrals):\nThe Romantic can pick their lover partner using their kill button (this can be done at any point of the game). Once they've picked their partner, they can use their kill button to give their partner a temporary shield that protects them from attacks. If their lover partner dies, the Romantic's role will change according to the following conditions:\n1. If their partner was an Impostor, the Romantic becomes the Refugee\n2. If their partner was a Neutral Killer, then they become Ruthless Romantic.\n3. If their partner was a Crewmate or a non-killing neutral, the Romantic becomes the Vengeful Romantic. \n\nThe Romantic wins with the winning team if their partner wins.\nNote: If your role changes, your win condition will be changed accordingly", - "RuthlessRomanticInfoLong": "(Neutrals):\nYou change your roles from Romantic if your partner (A neutral killer) is killed. As a Ruthless Romantic, you win if you kill everyone and are the last one standing. If you win, your dead partner will also win with you.", - "VengefulRomanticInfoLong": "(Neutrals):\nYou change your roles from Romantic if your partner (A crew or non-neutral killer) is killed. As a Vengeful Romantic, your goal is to avenge your partner, which means you must kill the killer of your partner. If you succeed, then you and your partner win with the winning team at the end. If you try to kill someone other than your partner's killer, then you will die by misfire.", - "PoisonerInfoLong": "(Neutrals):\nAs the Poisoner, your kills are delayed.\nKill everyone to win.", - "HexMasterInfoLong": "(Neutrals):\nAs the Hex Master, you can hex players or kill them.\nHexing a player works the same as spelling as a Witch.", - "WraithInfoLong": "(Neutrals):\nAs the Wraith, you can vent to Vanish temporarily. You will still appear visible on your screen. Vent again to become visible. You win if you are the last player remaining.", - "JinxInfoLong": "(Neutrals):\nAs the Jinx, whenever you get attacked, you jinx them, resulting in them dying to a jinx.\nThis has limited uses.\n\nKill off everyone to win.", - "PotionMasterInfoLong": "(Neutrals):\nAs the Potion Master, you have three different potions assigned to three different actions.\n\nSingle click: Reveal role\nDouble click: Kill\nMap: Sabotage\n\nThe reveal potion has a limit.\nWhen you run out, the kill buttons default to killing.", - "NecromancerInfoLong": "(Neutrals):\nAs the Necromancer, you win when you're the last one standing.\nAdditionally when someone tries to kill you, you will block the kill, and you will teleport to a random vent. You will have a limited time to kill your killer. If you succeed in doing so, you live. If the time runs out before you kill your killer, you die permanently. If you try to kill someone else other than your killer, you will die.", + "ImitatorInfoLong": "(Neutrals):\nAs the Imitator, use your kill button to imitate a player.\n\nYou'll either become a Sheriff, a Refugee, or some Neutral.", + "BanditInfoLong": "(Neutrals):\nAs the Bandit, you can click your kill button one time to steal a player's addon and twice to kill. Depending on the settings, you may instantly steal the addon or after the meeting starts. After the maximum number of steals is reached, you will kill normally. Additionally, if there are no stealable addons on the target or the target is stubborn, you will kill the target.\n\nKill everyone to win.\n\nNote: Cleansed, Last Impostor, and Lovers cannot be stolen.\nNote: If Bandit can vent is on, Nimble will become unstealable.", + "DoppelgangerInfoLong": "(Neutrals):\nAs the Doppelganger, use your kill button to steal a player's identity (their name and skin) and then kill your target.\n\nKill everyone to win.\n\nNote: You cannot steal the target's identity when Camouflage is active.", + "PunchingBagInfoLong": "(Neutrals):\nAs the Punching Bag, your goal is to get attacked a few times to win.\n\nYou cannot be guessed, as that adds to your attack count.", + "DoomsayerInfoLong": "(Neutrals):\nThe Doomsayer can guess the role of a certain player during the meeting.\nIf the Doomsayer guesses a certain number of roles (the number depends on the host settings), then he wins.\nThe guessing command is: /bt [player id] [role]\nYou can see the player's id before the player's name, or use the /id command to view the id of all players.", + "ShroudInfoLong": "(Neutrals):\nAs the Shroud, you do not kill normally.\nInstead, use your kill button to shroud a player.\nShrouded players kill others.\nIf the shrouded player doesn't make a kill, they'll kill themselves after a meeting.\n\nShroud sees shrouded players with a 「◈」mark next to their name.\nShrouded players who did not make a kill will also have the 「◈」mark in meetings, where they'll die if the Shroud is alive by the end of the meeting.", + "WerewolfInfoLong": "(Neutrals):\nAs the Werewolf, you can kill much like any killer.\nHowever, when you kill, any nearby players also die.\nAny player who dies to this will have their death reason as Mauled.\n\nTo balance this, you have a higher kill cooldown than anyone else.", + "ShamanInfoLong": "(Neutrals):\nAs the Shaman, you can use your kill button to select a voodoo doll once per round. If the kill button is used on you, the effect will be deflected onto the voodoo doll.\nIf you survive until the end, you win with the winning team.\nNote: If the killer cannot kill the chosen target, murder is canceled, but if the killer rechecks the Shaman, the killer will kill the Shaman.", + "SeekerInfoLong": "(Neutrals):\nAs the seeker, use your kill button to tag the target. If the seeker tags the wrong player, a point is deducted, and if the seeker tags the correct player, a point will be added.\nAdditionally, the seeker will not be able to move for 5 seconds after every meeting and after getting a new target.\n\nThe seeker needs to collect a certain number of points set by the Host to win.", + "PixieInfoLong": "(Neutrals):\nAs the Pixie, Mark up to x amount of targets each round by using the kill button on them. You must have one of the marked targets ejected when the meeting starts. If unsuccessful, you will commit suicide, except if you didn't mark any targets or all the targets are dead. The selected targets reset to 0 after the meeting ends. If you succeed, you will gain a point. You see all your targets in colored names.\n\nYou win with the winning team when you have certain amounts of points set by the Host.", + "SchrodingersCatInfoLong": "(Neutrals):\nAs Schrodingers Cat, if someone attempts to use the kill button on you, you will block the action and join their team. This blocking ability works only once. By default, you don't have a victory condition, meaning you win only after switching teams.\nIn Addition to this, you will be counted as nothing in the game.\n\nNote: If the killing machine attempts to use its kill button on you, the interaction is not blocked, and you will die.", + "RomanticInfoLong": "(Neutrals):\nThe Romantic can pick their lover partner using their kill button (this can be done at any point of the game). Once they've picked their partner, they can use their kill button to give their partner a temporary shield that protects them from attacks. If their lover partner dies, the Romantic's role will change according to the following conditions:\n1. If their partner was an Impostor, the Romantic becomes the Refugee\n2. If their partner was a Neutral Killer, then they become Ruthless Romantic.\n3. If their partner was a Crewmate or a non-killing neutral, the Romantic becomes the Vengeful Romantic. \n\nThe Romantic wins with the winning team if their partner wins.\nNote: If your role changes, your win condition will be changed accordingly", + "RuthlessRomanticInfoLong": "(Neutrals):\nYou change your roles from Romantic if your partner (A neutral killer) is killed. As a Ruthless Romantic, you win if you kill everyone and are the last one standing. If you win, your dead partner will also win with you.", + "VengefulRomanticInfoLong": "(Neutrals):\nYou change your roles from Romantic if your partner (A crew or non-neutral killer) is killed. As a Vengeful Romantic, your goal is to avenge your partner, which means you must kill the killer of your partner. If you succeed, then you and your partner win with the winning team at the end. If you try to kill someone other than your partner's killer, then you will die by misfire.", + "PoisonerInfoLong": "(Neutrals):\nAs the Poisoner, your kills are delayed.\nKill everyone to win.", + "HexMasterInfoLong": "(Neutrals):\nAs the Hex Master, you can hex players or kill them.\nHexing a player works the same as spelling as a Witch.", + "WraithInfoLong": "(Neutrals):\nAs the Wraith, you can vent to Vanish temporarily. You will still appear visible on your screen. Vent again to become visible. You win if you are the last player remaining.", + "JinxInfoLong": "(Neutrals):\nAs the Jinx, whenever you get attacked, you jinx them, resulting in them dying to a jinx.\nThis has limited uses.\n\nKill off everyone to win.", + "PotionMasterInfoLong": "(Neutrals):\nAs the Potion Master, you have three different potions assigned to three different actions.\n\nSingle click: Reveal role\nDouble click: Kill\nMap: Sabotage\n\nThe reveal potion has a limit.\nWhen you run out, the kill buttons default to killing.", + "NecromancerInfoLong": "(Neutrals):\nAs the Necromancer, you win when you're the last one standing.\nAdditionally when someone tries to kill you, you will block the kill, and you will teleport to a random vent. You will have a limited time to kill your killer. If you succeed in doing so, you live. If the time runs out before you kill your killer, you die permanently. If you try to kill someone else other than your killer, you will die.", "ShockerInfoLong": "(Neutrals):\nAs the Shocker, you can mark rooms by doing tasks in them, and then vent to Electrocute anyone in those rooms for a set period of time. When you finish all of your tasks, you get new ones. Note: Doing tasks during that period will mark them for the next ability use.", - "LastImpostorInfoLong": "(Add-ons):\nThis special effect is given to the last surviving Impostor. It significantly reduces their kill cooldown.", - "OverclockedInfoLong": "(Add-ons):\nAs the Overclocked, your kill cooldown is reduced by a percentage.\n\nThis feature is only assigned to roles with a kill button.", - "LoversInfoLong": "(Add-ons):\nLovers are a combination of two players. The Lovers win when they are the last ones standing, and their victory is shared. When one of the Lovers wins, the other also wins together. Lovers can see the 「♥」 next to each other's name. If one of the Lovers dies, the other will die in love (may not die in love according to the Host's settings). When one of the Lovers is exiled in the meeting, the other will die and become a dead body that cannot be reported.", - "MadmateInfoLong": "(Add-ons):\nOnly Crewmates can become Madmate. Madmate's task is to help the Impostors win the game. Madmate will lose if all Impostors are killed/ejected. Madmates may know who are Impostors, and Impostors may know who are Madmates (host settings).\n\nLazy Guy, Celebrity can't become Madmate. Sheriff, Snitch, Nice Guesser, Mayor, and Judge may become Madmate (host settings). Skill changes when the following roles are converted into Madmates:\n\nTime Manager => Doing tasks will reduce meeting time.\nBodyguard => Skill won't activate if the killer is an Impostor.\nGrenadier => Flash bomb will work on Crewmates and Neutrals instead of the Impostors.\nSheriff => Can kill anyone, including Impostors (host settings).\nNice Guesser => Can guess Crewmates and Neutrals\nPsychic => All evil Neutrals and Crewmates' names with the ability to kill will be displayed in Red.\nJudge => Can judge anyone\nPacifist => Their ability only works on Crewmates.", - "WatcherInfoLong": "(Add-ons):\nDuring the meeting, Watcher can see everyone's votes.", - "FlashInfoLong": "(Add-ons):\nThe Flash's default movement speed is faster than others. (speed depends on the setting of the Host)", - "TorchInfoLong": "(Add-ons):\nTorch has max vision and is not affected by Lights sabotage.", - "SeerInfoLong": "(Add-ons):\nWhenever a player dies, the Seer will see a kill-flash (a red flash, possibly accompanied by an alarm sound like sabotage).", - "TiebreakerInfoLong": "(Add-ons):\nWhen tie vote, priority will be given to the target voted by the Tiebreaker. Note: If multiple Tiebreakers choose different tie targets simultaneously, the skills of the Tiebreaker will not take effect.", - "ObliviousInfoLong": "(Add-ons):\nDetective and Cleaners won't be Oblivious. The Oblivious cannot report dead bodies. Note: Bait killed by Oblivious will still report automatically, and Oblivious can still be used as a scapegoat for Anonymous.", - "BewilderInfoLong": "(Add-ons):\nBewilder may have a smaller/bigger vision. When the Bewilder has died, the murderer's vision may become the same as the Bewilder's, depending on the settings.", - "WorkhorseInfoLong": "(Add-ons):\nThe first player to complete all the tasks will become Workhorse, and Workhorse will give the player extra tasks. The Host sets the number of additional tasks.", - "FoolInfoLong": "(Add-ons):\nSleuth and Mechanic won't be Fool. Fools can't repair any sabotage.", - "AvangerInfoLong": "(Add-ons):\nHost can set whether the Impostor can become an Avenger. When the Avenger is killed (voted out, and irregular kills will not count), the Avenger will revenge a random player.", - "YoutuberInfoLong": "(Add-ons):\nOnly Crewmate will become YouTuber. When the YouTuber is the first player to die in the game, the YouTuber will win alone. If the YouTuber does not meet the win conditions, the YouTuber will follow the Crewmate to win. Note: Indirect killing methods such as being exiled, being guessed by the Guesser, etc., will not trigger the skills of the YouTuber.", - "EgoistInfoLong": "(Add-ons):\nMadmate and Neutrals won't be Egoist. If the Egoist's team wins, the Egoist wins instead of their team.", - "StealerInfoLong": "(Add-ons):\nEvery time a Stealer kills a person, he gets an additional vote (the Host sets the vote number, and the decimal is rounded down).\nAlso, extra votes from the Stealer are hidden during the meeting depending on the options.", - "ParanoiaInfoLong": "(Add-ons):\nNot assigned to Neutrals nor Madmates.\nAs the Paranoia, you will be considered as two players in the game to determine when the game ends due to killers having the majority. Additionally, this grants you an extra vote, depending on options.", - "MimicInfoLong": "(Add-ons):\nOnly Impostor can become Mimic. When the Mimic is dead, other Impostors will receive a message once a meeting is called. This message will include information on roles which the Mimic killed.", - "GuesserInfoLong": "(Add-ons):\nAs a guesser, guess the roles of players in meetings to kill them.\nGuessing the incorrect role kills you instead.\nThe guessing command is: /bt [player id] [role]\nYou can see the player's id before the player's name or use the /id command to view the id of all players.", - "NecroviewInfoLong": "(Add-ons):\nThe Necroview can see the teams of dead players. The following info will be displayed on the dead player's name while in a meeting:\n- The Red name indicates the Impostors.\n- The Cyan name indicates the Crewmates.\n- The Gray name indicates the Neutrals.", - "ReachInfoLong": "(Add-on)\nOnly roles with a kill button can get this add-on. Unlike everyone else, you have the longest kill range possible in the game.", - "BaitInfoLong": "(Add-ons):\nWhen the Bait dies, the murderer who killed the Bait will self-report the Bait's body. However, this won't happen when a Scavenger, Cleaner, Swooper, Wraith, Medusa, or Killing Machine kills the Bait. The report may have a delay according to the Host's settings.", - "TrapperInfoLong": "(Add-ons):\nWhen Beartrap dies, Beartrap immobilizes killer for a configurable amount of time.", - "CharmedInfoLong": "(Betrayal Add-ons):\nThe Charmed add-on is obtained by being charmed by the Cultist.\nOnce charmed, you are now on the Cultist's team and no longer on your original team.", - "CleansedInfoLong": "(Add-ons):\nCleansed Add-on can only be obtained if cleanser erases all your Add-ons. Depending on the cleanser settings, you may not be able to obtain any more Add-ons in the future.", - "InfectedInfoLong": "(Betrayal Add-ons):\nThe Infected add-on is obtained by being infected by the Infectious.\nOnce infected, you work for the Infectious and do not win with your original team.", - "OnboundInfoLong": "(Add-ons):\nWith the Onbound add-on, you cannot be guessed in meetings.", - "ReboundInfoLong": "(Add-ons):\nWith the Rebound add-on, if a Guesser successfully guessed you or a Judge successfully judged you, they will die instead.\nIf a player with Double Shot guesses you correctly, they will die instantly.", - "MundaneInfoLong": "(Add-ons):\nAs Mundane, you can only guess once you complete all of your tasks.", - "KnightedInfoLong": "(Add-ons):\nWhen a Monarch knights someone, they get an extra vote.", - "UnreportableInfoLong": "(Add-ons):\nWith the Disregarded add-on, your corpse will be unreportable.", - "ContagiousInfoLong": "(Betrayal Add-ons):\nWhen the Virus infects you, you become contagious.\nContagious players are on the Virus team.\n\nWhether or not you die after a meeting depends on the settings for the Virus.", - "LuckyInfoLong": "(Add-ons):\nWith the Lucky add-on, there is a probability for you to evade the kill; the Host sets the specific probability. The killer will see the shield animation when the evasion takes effect, but you will not know anything.", - "DoubleShotInfoLong": "(Add-ons):\nWhen a player with Double Shot guesses a role incorrectly, they will get a second chance to guess, but the next wrong guess will result in suicide.", - "RascalInfoLong": "(Add-ons):\nAs the Rascal, you can die to the Sheriff, and Snitch can find you if Snitch can find madmates.\n\nOnly assigned to Crewmates, cannot be assigned by the Merchant.", - "SoullessInfoLong": "(Add-ons):\nWhen a Cursed Soul steals your soul, you get this add-on.\n\nYou are not counted as alive.", - "GravestoneInfoLong": "(Add-ons):\nAs the Gravestone, your role is revealed to everyone when you die.", - "LazyInfoLong": "(Add-ons):\nAs the Lazy, you are assigned a single short task and are immune to Warlocks, Puppeteers, and Gangsters.", - "AutopsyInfoLong": "(Add-ons):\nAs the Autopsy, you can see how people died.\n\nCannot be assigned to Doctor, Tracefinder, Scientist, or Sunnyboy.", - "RebirthInfoLong": "(Add-ons):\nAs the Rebirth, if you're the player about to be ejected, you will swap skins with a random crewmate who voted for you.\nNotice: The host vote never counts\nRebirth will be removed from you if you exhausted all your rebirths.", - "LoyalInfoLong": "(Add-ons):\nAs the Loyal, you cannot be recruited by roles such as Jackal or Cultist.\n\nCannot be assigned to neutrals.", - "EvilSpiritInfoLong": "(Add-ons):\nAs Evil Spirit, it's your job to help the Spiritcaller to victory. You can use your Haunt button to freeze players and reduce their vision. Alternatively, you can use your Haunt button to give the Spiritcaller a shield against a kill attempt temporarily.", + "LastImpostorInfoLong": "(Add-ons):\nThis special effect is given to the last surviving Impostor. It significantly reduces their kill cooldown.", + "OverclockedInfoLong": "(Add-ons):\nAs the Overclocked, your kill cooldown is reduced by a percentage.\n\nThis feature is only assigned to roles with a kill button.", + "LoversInfoLong": "(Add-ons):\nLovers are a combination of two players. The Lovers win when they are the last ones standing, and their victory is shared. When one of the Lovers wins, the other also wins together. Lovers can see the 「♥」 next to each other's name. If one of the Lovers dies, the other will die in love (may not die in love according to the Host's settings). When one of the Lovers is exiled in the meeting, the other will die and become a dead body that cannot be reported.", + "MadmateInfoLong": "(Add-ons):\nOnly Crewmates can become Madmate. Madmate's task is to help the Impostors win the game. Madmate will lose if all Impostors are killed/ejected. Madmates may know who are Impostors, and Impostors may know who are Madmates (host settings).\n\nLazy Guy, Celebrity can't become Madmate. Sheriff, Snitch, Nice Guesser, Mayor, and Judge may become Madmate (host settings). Skill changes when the following roles are converted into Madmates:\n\nTime Manager => Doing tasks will reduce meeting time.\nBodyguard => Skill won't activate if the killer is an Impostor.\nGrenadier => Flash bomb will work on Crewmates and Neutrals instead of the Impostors.\nSheriff => Can kill anyone, including Impostors (host settings).\nNice Guesser => Can guess Crewmates and Neutrals\nPsychic => All evil Neutrals and Crewmates' names with the ability to kill will be displayed in Red.\nJudge => Can judge anyone\nPacifist => Their ability only works on Crewmates.", + "WatcherInfoLong": "(Add-ons):\nDuring the meeting, Watcher can see everyone's votes.", + "FlashInfoLong": "(Add-ons):\nThe Flash's default movement speed is faster than others. (speed depends on the setting of the Host)", + "TorchInfoLong": "(Add-ons):\nTorch has max vision and is not affected by Lights sabotage.", + "SeerInfoLong": "(Add-ons):\nWhenever a player dies, the Seer will see a kill-flash (a red flash, possibly accompanied by an alarm sound like sabotage).", + "TiebreakerInfoLong": "(Add-ons):\nWhen tie vote, priority will be given to the target voted by the Tiebreaker. Note: If multiple Tiebreakers choose different tie targets simultaneously, the skills of the Tiebreaker will not take effect.", + "ObliviousInfoLong": "(Add-ons):\nDetective and Cleaners won't be Oblivious. The Oblivious cannot report dead bodies. Note: Bait killed by Oblivious will still report automatically, and Oblivious can still be used as a scapegoat for Anonymous.", + "BewilderInfoLong": "(Add-ons):\nBewilder may have a smaller/bigger vision. When the Bewilder has died, the murderer's vision may become the same as the Bewilder's, depending on the settings.", + "WorkhorseInfoLong": "(Add-ons):\nThe first player to complete all the tasks will become Workhorse, and Workhorse will give the player extra tasks. The Host sets the number of additional tasks.", + "FoolInfoLong": "(Add-ons):\nSleuth and Mechanic won't be Fool. Fools can't repair any sabotage.", + "AvangerInfoLong": "(Add-ons):\nHost can set whether the Impostor can become an Avenger. When the Avenger is killed (voted out, and irregular kills will not count), the Avenger will revenge a random player.", + "YoutuberInfoLong": "(Add-ons):\nOnly Crewmate will become YouTuber. When the YouTuber is the first player to die in the game, the YouTuber will win alone. If the YouTuber does not meet the win conditions, the YouTuber will follow the Crewmate to win. Note: Indirect killing methods such as being exiled, being guessed by the Guesser, etc., will not trigger the skills of the YouTuber.", + "EgoistInfoLong": "(Add-ons):\nMadmate and Neutrals won't be Egoist. If the Egoist's team wins, the Egoist wins instead of their team.", + "StealerInfoLong": "(Add-ons):\nEvery time a Stealer kills a person, he gets an additional vote (the Host sets the vote number, and the decimal is rounded down).\nAlso, extra votes from the Stealer are hidden during the meeting depending on the options.", + "ParanoiaInfoLong": "(Add-ons):\nNot assigned to Neutrals nor Madmates.\nAs the Paranoia, you will be considered as two players in the game to determine when the game ends due to killers having the majority. Additionally, this grants you an extra vote, depending on options.", + "MimicInfoLong": "(Add-ons):\nOnly Impostor can become Mimic. When the Mimic is dead, other Impostors will receive a message once a meeting is called. This message will include information on roles which the Mimic killed.", + "GuesserInfoLong": "(Add-ons):\nAs a guesser, guess the roles of players in meetings to kill them.\nGuessing the incorrect role kills you instead.\nThe guessing command is: /bt [player id] [role]\nYou can see the player's id before the player's name or use the /id command to view the id of all players.", + "NecroviewInfoLong": "(Add-ons):\nThe Necroview can see the teams of dead players. The following info will be displayed on the dead player's name while in a meeting:\n- The Red name indicates the Impostors.\n- The Cyan name indicates the Crewmates.\n- The Gray name indicates the Neutrals.", + "ReachInfoLong": "(Add-on)\nOnly roles with a kill button can get this add-on. Unlike everyone else, you have the longest kill range possible in the game.", + "BaitInfoLong": "(Add-ons):\nWhen the Bait dies, the murderer who killed the Bait will self-report the Bait's body. However, this won't happen when a Scavenger, Cleaner, Swooper, Wraith, Medusa, or Killing Machine kills the Bait. The report may have a delay according to the Host's settings.", + "TrapperInfoLong": "(Add-ons):\nWhen Beartrap dies, Beartrap immobilizes killer for a configurable amount of time.", + "CharmedInfoLong": "(Betrayal Add-ons):\nThe Charmed add-on is obtained by being charmed by the Cultist.\nOnce charmed, you are now on the Cultist's team and no longer on your original team.", + "CleansedInfoLong": "(Add-ons):\nCleansed Add-on can only be obtained if cleanser erases all your Add-ons. Depending on the cleanser settings, you may not be able to obtain any more Add-ons in the future.", + "InfectedInfoLong": "(Betrayal Add-ons):\nThe Infected add-on is obtained by being infected by the Infectious.\nOnce infected, you work for the Infectious and do not win with your original team.", + "OnboundInfoLong": "(Add-ons):\nWith the Onbound add-on, you cannot be guessed in meetings.", + "ReboundInfoLong": "(Add-ons):\nWith the Rebound add-on, if a Guesser successfully guessed you or a Judge successfully judged you, they will die instead.\nIf a player with Double Shot guesses you correctly, they will die instantly.", + "MundaneInfoLong": "(Add-ons):\nAs Mundane, you can only guess once you complete all of your tasks.", + "KnightedInfoLong": "(Add-ons):\nWhen a Monarch knights someone, they get an extra vote.", + "UnreportableInfoLong": "(Add-ons):\nWith the Disregarded add-on, your corpse will be unreportable.", + "ContagiousInfoLong": "(Betrayal Add-ons):\nWhen the Virus infects you, you become contagious.\nContagious players are on the Virus team.\n\nWhether or not you die after a meeting depends on the settings for the Virus.", + "LuckyInfoLong": "(Add-ons):\nWith the Lucky add-on, there is a probability for you to evade the kill; the Host sets the specific probability. The killer will see the shield animation when the evasion takes effect, but you will not know anything.", + "DoubleShotInfoLong": "(Add-ons):\nWhen a player with Double Shot guesses a role incorrectly, they will get a second chance to guess, but the next wrong guess will result in suicide.", + "RascalInfoLong": "(Add-ons):\nAs the Rascal, you can die to the Sheriff, and Snitch can find you if Snitch can find madmates.\n\nOnly assigned to Crewmates, cannot be assigned by the Merchant.", + "SoullessInfoLong": "(Add-ons):\nWhen a Cursed Soul steals your soul, you get this add-on.\n\nYou are not counted as alive.", + "GravestoneInfoLong": "(Add-ons):\nAs the Gravestone, your role is revealed to everyone when you die.", + "LazyInfoLong": "(Add-ons):\nAs the Lazy, you are assigned a single short task and are immune to Warlocks, Puppeteers, and Gangsters.", + "AutopsyInfoLong": "(Add-ons):\nAs the Autopsy, you can see how people died.\n\nCannot be assigned to Doctor, Tracefinder, Scientist, or Sunnyboy.", + "RebirthInfoLong": "(Add-ons):\nAs the Rebirth, if you're the player about to be ejected, you will swap skins with a random crewmate who voted for you.\nNotice: The host vote never counts\nRebirth will be removed from you if you exhausted all your rebirths.", + "LoyalInfoLong": "(Add-ons):\nAs the Loyal, you cannot be recruited by roles such as Jackal or Cultist.\n\nCannot be assigned to neutrals.", + "EvilSpiritInfoLong": "(Add-ons):\nAs Evil Spirit, it's your job to help the Spiritcaller to victory. You can use your Haunt button to freeze players and reduce their vision. Alternatively, you can use your Haunt button to give the Spiritcaller a shield against a kill attempt temporarily.", "RecruitInfoLong": "(Betrayal Add-ons):\nAs a recruit, you are on the Jackal's team and help out the Jackal and their Sidekicks.\nYou cannot win with your original team.\nDepending on the settings, you may turn into Jackal if old Jackal was killed and no sidekicks is alive.", - "AdmiredInfoLong": "(Betrayal Add-ons):\nAs an admired player, you win with the crew and not your original team.\n\nYou can see the Admirer.", - "GlowInfoLong": "(Add-ons):\nDuring lights out, you and players nearby you will receive a vision boost.", - "RadarInfoLong": "(Add-ons):\nAs Radar, you have arrows pointing towards the closest person at all times.", - "DiseasedInfoLong": "(Add-ons):\nWhen someone tries to use the kill button on you, their cooldown will be increased by a configurable amount of time.", - "AntidoteInfoLong": "(Add-ons):\nWhen someone tries to use the kill button on you, their cooldown will be decreased by a configurable amount of time.", - "StubbornInfoLong": "(Add-ons):\nWith the Stubborn add-on, Eraser can't erase your role, Cleanser can't cleanse you, Bandit can't steal from you, and Monarch can't knight you.\nAdditionally, you can't gain any new add-ons from the Merchant.", - "SwiftInfoLong": "(Add-ons):\nAs the Swift, you will not make any movement when you kill.\nNote: Swift also ignores Bait", - "UnluckyInfoLong": "(Add-ons):\nAs Unlucky, when you complete tasks, kill, venting, or open door, you have a chance to die.", - "SpurtInfoLong": "(Add-ons):\nWhen you start walking, you gain an enormous speed boost, which swiftly deteriorates, until you have to rest still for a while to rejuvenate your speed.", - "VoidBallotInfoLong": "(Add-ons):\nHolder of this add-on will have 0 vote count.", - "AwareInfoLong": "(Add-ons):\nAs the Aware, you get a notification in the next meeting if a revealing role had interacted with you.", - "FragileInfoLong": "(Add-ons):\nAs Fragile, you will instantly die if someone tries to use the kill button on you (even if the role cannot directly kill).", - "GhoulInfoLong": "(Add-ons):\nAs the Ghoul, one of two outcomes can occur on task completion.\n\nIf alive: Suicide\nIf dead: You kill your killer if they're alive.\n\nThis is only assigned to crewmates, and not crewmates with no tasks or are task-based.", - "BloodthirstInfoLong": "(Add-ons):\nAs the Bloodthirst, doing tasks allows you to become bloodthirsty and kill players.\nWhen you finish a task, the next player you come in contact with dies.\n\nYour Bloodthirst remains after a meeting.\nUpon making a kill, your Bloodthirst clears till the next task you complete.\nBloodthirsts do not stack.\n\nOnly assigned to crewmates with tasks.", - "MareInfoLong": "(Add-ons):\nAs the Mare, you have a low kill cooldown and have higher speed but can only kill during lights.\n\nAdditionally, your name will appear in red during lights.\n\nOnly assigned to Impostors and cannot be guessed.", - "BurstInfoLong": "(Add-ons):\nAs the Burst, your killer explodes if they aren't inside a vent after a set amount of time.", - "SleuthInfoLong": "(Add-ons):\nAs the Sleuth, you gain info from dead bodies.\n\nOptionally, you may also gain the killer's role.\n\nNot assigned to Detective or Mortician.", - "ClumsyInfoLong": "(Add-ons):\nAs the Clumsy, you have a chance to miss your kill.\n\nWhen you miss, your cooldown is reset, and the target remains untouched.\n\nOnly assigned to killers.", - "CircumventInfoLong": "(Add-ons):\nAs the Circumvent, you can't vent.\n\nOnly assigned to Impostors.", - "NimbleInfoLong": "(Add-ons):\nAs the Nimble, you gain access to the vent button.\n\nOnly assigned to certain crewmates.", - "InfluencedInfoLong": "(Add-ons):\nAs the Influenced, your vote will be forced to the player with the most votes.\nInfluenced vote won't be counted while choosing the exiled player'\nNote that your vote skill still functions on the player you voted first\nIf all the alive players are Influenced, then the vote result won't shift\nCollector cannot become influenced.", - "SilentInfoLong": "(Add-ons):\nAs the Silent, your vote icon won't appear on the result screen.\nSo nobody knows who you voted for.", - "SusceptibleInfoLong": "(Add-ons):\nAs the Susceptible, your death reason will be random.", - "TrickyInfoLong": "(Add-ons):\nAs the Tricky, your kills will have a random death reason.", - "TiredInfoLong": "(Add-ons):\nWhenever Tired kills (or uses kill ability on) someone, alternatively whenever they finish a task, they will temporarily get lower vision & lower speed.", - "StatueInfoLong": "(Add-ons):\nWhenever many people are near the Statue, the Statue is completely frozen or slowed down depending on the settings.", - "EvaderInfoLong": "(Add-ons):\nWhen the Evader gets voted out, there is a chance they will not get ejected. (Chance set by the Host.)", - "CyberInfoLong": "(Add-ons):\nAs the Cyber, you cannot die while in a group.\nDepending on the settings, Imposters, Neutrals, and or Crewmates will know if you die.", - "HurriedInfoLong": "(Add-ons):\nAs the hurried, you must finish all your tasks to win with your team! If you fail with your tasks, you lose.\nHurried hurries to his goal, so it won't get madmate, charmed or so.", - "OiiaiInfoLong": "(Add-ons):\nAs the Oiiai, when you die, you will make your killer forget their role.\nAdditionally, you may pass Oiiai on to the killer, depending on settings.", - "RainbowInfoLong": "(Add-ons):\nAs the rainbow, you change your colors like crazy.", - "GMInfoLong": "(None):\nThe Game Master is an observer role.\nTheir presence does not affect the game, and all players know who the Game Master is. The Game Master role will be assigned to the Host, who will automatically become a ghost at the start of the game.", - "SunnyboyInfoLong": "(Neutrals):\nAs the Sunnyboy, you win if you are dead by the end of the game. The game will not end when you are alive due to killers gaining the majority.\nAdditionally, you have access to portable vitals.", - "BardInfoLong": "(Impostors):\nWhen a bard is alive, the exile confirmation will display a sentence composed by the bard. Whenever the bard completes a creation, the bard's kill cooldown will be permanently halved.", - "WardenInfoLong": "(Crewmates [Ghost]):\nAs the Warden, alert someone of nearby danger, additionally giving them a temporary speed boost.", - "GhastlyInfoLong": "(Crewmates [Ghost]):\nAs the Ghastly, possess an unsuspecting person, after that choose a target for them, now they'll only be able to use their kill (or kill ability) on target until you possess someone else or possess time runs out.", - "MinionInfoLong": "(Impostor [Ghost]):\nAs the Minion, you can temporarily blind non-impostors.", - "DollMasterInfoLong": "(Impostor):\nAs the Dollmaster, you can temporarily take control of any player by using the Shapeshift button and to make them do your Deeds!", - "DoubleAgentInfoLong": "(Impostor):\nAs the Double Agent, you cannot access the kill button. However, you can vote for someone in a meeting to pass a bomb onto them, which can only be done one player at a time. Once the meeting has finished, the bomb will activate and explode in a set amount of time.\nNote: when you pass the bomb onto someone in a meeting, you can vote afterward.\n\nAdditionally depending on settings the Double Agent can diffuse Bastion and Agitator bombs when venting.\n\nThe Double Agent can change roles when they are the Last Imposter, depending on the settings the role can be a Admired Impostor, Trickster, Traitor, or stay as the Double Agent.", - "SlothInfoLong": "(Add-ons):\nThe Sloth's default movement speed is slower than others.\n(Speed depends on the setting of the Host)", - "ProhibitedInfoLong": "(Add-ons):\nAs the Prohibited, you have specific vents that you can't use.\nHow many vents are disabled depends on the Host's settings.", - "EavesdropperInfoLong": "(Add-ons):\nAs the Eavesdropper, you have a chance to read other role/addon information-based messages like Mortician or Sleuth.", - "ApocalypseInfoLong": "(Apocalypse):\nApocalypse members are on a separate team that works together and wins together. If there are multiple Apocalypse roles in the game, they can see each other's roles.\nDepending on the Host's settings, Apocalypse roles can guess or be guessed.", + "AdmiredInfoLong": "(Betrayal Add-ons):\nAs an admired player, you win with the crew and not your original team.\n\nYou can see the Admirer.", + "GlowInfoLong": "(Add-ons):\nDuring lights out, you and players nearby you will receive a vision boost.", + "RadarInfoLong": "(Add-ons):\nAs Radar, you have arrows pointing towards the closest person at all times.", + "DiseasedInfoLong": "(Add-ons):\nWhen someone tries to use the kill button on you, their cooldown will be increased by a configurable amount of time.", + "AntidoteInfoLong": "(Add-ons):\nWhen someone tries to use the kill button on you, their cooldown will be decreased by a configurable amount of time.", + "StubbornInfoLong": "(Add-ons):\nWith the Stubborn add-on, Eraser can't erase your role, Cleanser can't cleanse you, Bandit can't steal from you, and Monarch can't knight you.\nAdditionally, you can't gain any new add-ons from the Merchant.", + "SwiftInfoLong": "(Add-ons):\nAs the Swift, you will not make any movement when you kill.\nNote: Swift also ignores Bait", + "UnluckyInfoLong": "(Add-ons):\nAs Unlucky, when you complete tasks, kill, venting, or open door, you have a chance to die.", + "SpurtInfoLong": "(Add-ons):\nWhen you start walking, you gain an enormous speed boost, which swiftly deteriorates, until you have to rest still for a while to rejuvenate your speed.", + "VoidBallotInfoLong": "(Add-ons):\nHolder of this add-on will have 0 vote count.", + "AwareInfoLong": "(Add-ons):\nAs the Aware, you get a notification in the next meeting if a revealing role had interacted with you.", + "FragileInfoLong": "(Add-ons):\nAs Fragile, you will instantly die if someone tries to use the kill button on you (even if the role cannot directly kill).", + "GhoulInfoLong": "(Add-ons):\nAs the Ghoul, one of two outcomes can occur on task completion.\n\nIf alive: Suicide\nIf dead: You kill your killer if they're alive.\n\nThis is only assigned to crewmates, and not crewmates with no tasks or are task-based.", + "BloodthirstInfoLong": "(Add-ons):\nAs the Bloodthirst, doing tasks allows you to become bloodthirsty and kill players.\nWhen you finish a task, the next player you come in contact with dies.\n\nYour Bloodthirst remains after a meeting.\nUpon making a kill, your Bloodthirst clears till the next task you complete.\nBloodthirsts do not stack.\n\nOnly assigned to crewmates with tasks.", + "MareInfoLong": "(Add-ons):\nAs the Mare, you have a low kill cooldown and have higher speed but can only kill during lights.\n\nAdditionally, your name will appear in red during lights.\n\nOnly assigned to Impostors and cannot be guessed.", + "BurstInfoLong": "(Add-ons):\nAs the Burst, your killer explodes if they aren't inside a vent after a set amount of time.", + "SleuthInfoLong": "(Add-ons):\nAs the Sleuth, you gain info from dead bodies.\n\nOptionally, you may also gain the killer's role.\n\nNot assigned to Detective or Mortician.", + "ClumsyInfoLong": "(Add-ons):\nAs the Clumsy, you have a chance to miss your kill.\n\nWhen you miss, your cooldown is reset, and the target remains untouched.\n\nOnly assigned to killers.", + "CircumventInfoLong": "(Add-ons):\nAs the Circumvent, you can't vent.\n\nOnly assigned to Impostors.", + "NimbleInfoLong": "(Add-ons):\nAs the Nimble, you gain access to the vent button.\n\nOnly assigned to certain crewmates.", + "InfluencedInfoLong": "(Add-ons):\nAs the Influenced, your vote will be forced to the player with the most votes.\nInfluenced vote won't be counted while choosing the exiled player'\nNote that your vote skill still functions on the player you voted first\nIf all the alive players are Influenced, then the vote result won't shift\nCollector cannot become influenced.", + "SilentInfoLong": "(Add-ons):\nAs the Silent, your vote icon won't appear on the result screen.\nSo nobody knows who you voted for.", + "SusceptibleInfoLong": "(Add-ons):\nAs the Susceptible, your death reason will be random.", + "TrickyInfoLong": "(Add-ons):\nAs the Tricky, your kills will have a random death reason.", + "TiredInfoLong": "(Add-ons):\nWhenever Tired kills (or uses kill ability on) someone, alternatively whenever they finish a task, they will temporarily get lower vision & lower speed.", + "StatueInfoLong": "(Add-ons):\nWhenever many people are near the Statue, the Statue is completely frozen or slowed down depending on the settings.", + "EvaderInfoLong": "(Add-ons):\nWhen the Evader gets voted out, there is a chance they will not get ejected. (Chance set by the Host.)", + "CyberInfoLong": "(Add-ons):\nAs the Cyber, you cannot die while in a group.\nDepending on the settings, Imposters, Neutrals, and or Crewmates will know if you die.", + "HurriedInfoLong": "(Add-ons):\nAs the hurried, you must finish all your tasks to win with your team! If you fail with your tasks, you lose.\nHurried hurries to his goal, so it won't get madmate, charmed or so.", + "OiiaiInfoLong": "(Add-ons):\nAs the Oiiai, when you die, you will make your killer forget their role.\nAdditionally, you may pass Oiiai on to the killer, depending on settings.", + "RainbowInfoLong": "(Add-ons):\nAs the rainbow, you change your colors like crazy.", + "GMInfoLong": "(None):\nThe Game Master is an observer role.\nTheir presence does not affect the game, and all players know who the Game Master is. The Game Master role will be assigned to the Host, who will automatically become a ghost at the start of the game.", + "SunnyboyInfoLong": "(Neutrals):\nAs the Sunnyboy, you win if you are dead by the end of the game. The game will not end when you are alive due to killers gaining the majority.\nAdditionally, you have access to portable vitals.", + "BardInfoLong": "(Impostors):\nWhen a bard is alive, the exile confirmation will display a sentence composed by the bard. Whenever the bard completes a creation, the bard's kill cooldown will be permanently halved.", + "WardenInfoLong": "(Crewmates [Ghost]):\nAs the Warden, alert someone of nearby danger, additionally giving them a temporary speed boost.", + "GhastlyInfoLong": "(Crewmates [Ghost]):\nAs the Ghastly, possess an unsuspecting person, after that choose a target for them, now they'll only be able to use their kill (or kill ability) on target until you possess someone else or possess time runs out.", + "MinionInfoLong": "(Impostor [Ghost]):\nAs the Minion, you can temporarily blind non-impostors.", + "DollMasterInfoLong": "(Impostor):\nAs the Dollmaster, you can temporarily take control of any player by using the Shapeshift button and to make them do your Deeds!", + "DoubleAgentInfoLong": "(Impostor):\nAs the Double Agent, you cannot access the kill button. However, you can vote for someone in a meeting to pass a bomb onto them, which can only be done one player at a time. Once the meeting has finished, the bomb will activate and explode in a set amount of time.\nNote: when you pass the bomb onto someone in a meeting, you can vote afterward.\n\nAdditionally depending on settings the Double Agent can diffuse Bastion and Agitator bombs when venting.\n\nThe Double Agent can change roles when they are the Last Imposter, depending on the settings the role can be a Admired Impostor, Trickster, Traitor, or stay as the Double Agent.", + "SlothInfoLong": "(Add-ons):\nThe Sloth's default movement speed is slower than others.\n(Speed depends on the setting of the Host)", + "ProhibitedInfoLong": "(Add-ons):\nAs the Prohibited, you have specific vents that you can't use.\nHow many vents are disabled depends on the Host's settings.", + "EavesdropperInfoLong": "(Add-ons):\nAs the Eavesdropper, you have a chance to read other role/addon information-based messages like Mortician or Sleuth.", + "ApocalypseInfoLong": "(Apocalypse):\nApocalypse members are on a separate team that works together and wins together. If there are multiple Apocalypse roles in the game, they can see each other's roles.\nDepending on the Host's settings, Apocalypse roles can guess or be guessed.", "RevenantInfoLong": "(Neutral):\nAs the Revenant, your goal is to be killed. If you are killed, you will take your killer's role and kill your killer instead. You cannot win before being killed.\nNote that Revenant only works when being directly killed.", - "ShowTextOverlay": "Text Overlay", - "Overlay.GuesserMode": "Guesser Mode", - "Overlay.NoGameEnd": "No Game End", - "Overlay.DebugMode": "Debug Mode", - "Overlay.LowLoadMode": "Low Load Mode", - "Overlay.AllowConsole": "Console", - "DisableShieldAnimations": "Disable Unnecessary Shield Animations", - "DisableKillAnimationOnGuess": "Disable Kill Animation on Guesses", - "AbilityUseGainWithEachTaskCompleted": "Amount of Ability Use Gains With Each Task Completed", - "OutOfAbilityUsesDoMoreTasks": "Out of ability uses! Do tasks to get more!", - "AbilityUseLimit": "Initial Ability Use Limit", - "AbilityInUse": "Ability in use", - "AbilityExpired": "Ability expired, {0} uses remain", + "ShowTextOverlay": "Text Overlay", + "Overlay.GuesserMode": "Guesser Mode", + "Overlay.NoGameEnd": "No Game End", + "Overlay.DebugMode": "Debug Mode", + "Overlay.LowLoadMode": "Low Load Mode", + "Overlay.AllowConsole": "Console", + "DisableShieldAnimations": "Disable Unnecessary Shield Animations", + "DisableKillAnimationOnGuess": "Disable Kill Animation on Guesses", + "AbilityUseGainWithEachTaskCompleted": "Amount of Ability Use Gains With Each Task Completed", + "OutOfAbilityUsesDoMoreTasks": "Out of ability uses! Do tasks to get more!", + "AbilityUseLimit": "Initial Ability Use Limit", + "AbilityInUse": "Ability in use", + "AbilityExpired": "Ability expired, {0} uses remain", "RevenantTargeted": "Your role has changed to {0}", "RevenantCanCopyAddons": "Can Steal Addons", - "ShowArrows": "Has Arrows pointing toward bodies", - "ArrowDelayMin": "Minimum Arrow show-up delay", - "ArrowDelayMax": "Maximum Arrow show-up delay", - "SMUsesUsedWhenFixingReactorOrO2": "Uses it takes to fix Reactor/O2", - "SMUsesUsedWhenFixingLightsOrComms": "Uses it takes to fix Lights/Comms", - - "GrenadierSkillMaxOfUseage": "(Initial) Max number of Grenades", - "ShowSpecificRole": "Know specific roles on Task Completion", - "TimeMasterMaxUses": "(Initial) Max Amount of Ability Uses", - "SwooperVentNormallyOnCooldown": "Swooper vents normally when swooping is on cooldown", - "WraithVentNormallyOnCooldown": "Wraith vents normally when invis is on cooldown", - "DisableMeeting": "Disable Meetings", - "DisableCloseDoor": "Disable Doors Sabotage", - "DisableSabotage": "Disable Sabotages", - "NoGameEnd": "No Game End", - "AllowConsole": "BepInEx Console", - "DebugMode": "Debug Mode", - "SyncButtonMode": "Limit Meeting Times", - "RandomMapsMode": "Random Maps Mode", - "SyncedButtonCount": "Max Number of Emergency Meetings per Game", - "HHSuccessKCDDecrease": "Kill cooldown decrease on killing target", - "HHFailureKCDIncrease": "Kill cooldown increase on killing others", - "HHNumOfTargets": "Number of targets", - "Targets": "Targets: ", - "HHMaxKCD": "Maximum kill cooldown", - "HHMinKCD": "Minimum kill cooldown", - "AllAliveMeeting": "Meeting When No One is Dead", - "AllAliveMeetingTime": "Meeting Time When No One is Dead", - "AdditionalEmergencyCooldown": "Additional Emergency Cooldown", - "AdditionalEmergencyCooldownThreshold": "Minimum Living Players to be Applied", - "AdditionalEmergencyCooldownTime": "Additional Cooldown", - "LadderDeath": "Fall From Ladders", - "LadderDeathChance": "Fall To Death Chance", - "EveryoneCanSeeDeathReason": "Everyone Can See Death Reason", - "DisableSwipeCardTask": "Disable Swipe Card Task", - "DisableSubmitScanTask": "Disable Submit Scan Task", - "DisableUnlockSafeTask": "Disable Unlock Safe Task", - "DisableUploadDataTask": "Disable Upload Data Task", - "DisableStartReactorTask": "Disable Start Reactor Task", - "DisableResetBreakerTask": "Disable Reset Breakers Task", - "DisableShortTasks": "Disable Short Tasks", - "DisableCleanVent": "Disable Clean Vent Task", - "DisableCalibrateDistributor": "Disable Calibrate Distributor Task", - "DisableChartCourse": "Disable Chart Course Task", - "DisableStabilizeSteering": "Disable Stabilize Steering Task", - "DisableCleanO2Filter": "Disable Clean O2 Filter Task", - "DisableUnlockManifolds": "Disable Unlock Manifolds Task", - "DisablePrimeShields": "Disable Prime Shields Task", - "DisableMeasureWeather": "Disable Measure Weather", - "DisableBuyBeverage": "Disable Buy Beverage", - "DisableAssembleArtifact": "Disable Assemble Artifact Task", - "DisableSortSamples": "Disable Sort Samples Task", - "DisableProcessData": "Disable Process Data Task", - "DisableRunDiagnostics": "Disable Run Diagnostics Task", - "DisableRepairDrill": "Disable Repair Drill Task", - "DisableAlignTelescope": "Disable Align Telescope Task", - "DisableRecordTemperature": "Disable Record Temperature Task", - "DisableFillCanisters": "Disable Fill Canisters Task", - "DisableMonitorTree": "Disable Monitor Tree Task", - "DisableStoreArtifacts": "Disable Store Artifacts Task", - "DisablePutAwayPistols": "Disable Put Away Pistols Task", - "DisablePutAwayRifles": "Disable Put Away Rifles Task", - "DisableMakeBurger": "Disable Make Burger Task", - "DisableCleanToilet": "Disable Clean Toilet Task", - "DisableDecontaminate": "Disable Decontaminate Task", - "DisableSortRecords": "Disable Sort Records Task", - "DisableFixShower": "Disable Fix Shower Task", - "DisablePickUpTowels": "Disable Pick Up Towels Task", - "DisablePolishRuby": "Disable Polish Ruby Task", - "DisableDressMannequin": "Disable Dress Mannequin Task", - "DisableCommonTasks": "Disable Common Tasks", - "DisableFixWiring": "Disable Fix Wiring Task", - "DisableEnterIdCode": "Disable Enter ID Code Task", - "DisableInsertKeys": "Disable Insert Keys Task", - "DisableScanBoardingPass": "Disable Scan Boarding Pass Task", - "DisableLongTasks": "Disable Long Tasks", - "DisableAlignEngineOutput": "Disable Align Engine Output Task", - "DisableInspectSample": "Disable Inspect Sample Task", - "DisableEmptyChute": "Disable Empty Chute Task", - "DisableClearAsteroids": "Disable Clear Asteroids Task", - "DisableWaterPlants": "Disable Water Plants Task", - "DisableOpenWaterways": "Disable Open Waterways Task", - "DisableReplaceWaterJug": "Disable Replace Water Jug Task", - "DisableRebootWifi": "Disable Reboot Wifi Task", - "DisableDevelopPhotos": "Disable Develop Photos Task", - "DisableRewindTapes": "Disable Rewind Tapes Task", - "DisableStartFans": "Disable Start Fans Task", - "DisableOtherTasks": "Disable Situational Tasks", - "DisableEmptyGarbage": "Disable Empty Garbage Task", - "DisableFuelEngines": "Disable Fuel Engines Task", - "DisableDivertPower": "Disable Divert Power Task", - "DisableActivateWeatherNodes": "Disable Weather Nodes Task", - "DisableRoastMarshmallow": "Disable Roast Marshmallow", - "DisableCollectSamples": "Disable Collect Samples", - "DisableReplaceParts": "Disable Replace Parts", - "DisableCollectVegetables": "Disable Collect Vegetables", - "DisableMineOres": "Disable Mine Ores", - "DisableExtractFuel": "Disable Extract Fuel", - "DisableCatchFish": "Disable Catch Fish", - "DisablePolishGem": "Disable Polish Gem", - "DisableHelpCritter": "Disable Help Critter", - "DisableHoistSupplies": "Disable Hoist Supplies", - "DisableFixAntenna": "Disable Fix Antenna", - "DisableBuildSandcastle": "Disable Build Sandcastle", - "DisableCrankGenerator": "Disable Crank Generator", - "DisableMonitorMushroom": "Disable Monitor Mushroom", - "DisablePlayVideoGame": "Disable Play Video Game", - "DisableFindSignal": "Disable Find Signal", - "DisableThrowFisbee": "Disable Throw Frisbee", - "DisableLiftWeights": "Disable Lift Weights", - "DisableCollectShells": "Disable Collect Shells", - "SuffixMode": "Suffix", - "SuffixMode.None": "None", - "SuffixMode.Version": "Version", - "SuffixMode.Streaming": "Streaming", - "SuffixMode.Recording": "Recording", - "SuffixMode.RoomHost": "Room Host", - "SuffixMode.OriginalName": "Original Name", - "SuffixMode.DoNotKillMe": "Don't kill me", - "SuffixMode.NoAndroidPlz": "No phones", - "SuffixMode.AutoHost": "Auto-Host", - "SuffixModeText.DoNotKillMe": "Don't kill me", - "SuffixModeText.NoAndroidPlz": "No phones please", - "SuffixModeText.AutoHost": "Auto-hosting", - "FormatNameMode": "Player Name Mode", - "FormatNameModes.None": "Disable", - "FormatNameModes.Color": "Color", - "FormatNameModes.Snacks": "Random", - "DisableEmojiName": "Disable Emoji in names", - "FixFirstKillCooldown": "Override Starting Kill Cooldown", - "FixKillCooldownValue": "Starting Kill Cooldown", - "OverclockedReduction": "Kill Cooldown Reduction", - "GhostCanSeeOtherRoles": "Ghosts Can See Other Roles", + "ShowArrows": "Has Arrows pointing toward bodies", + "ArrowDelayMin": "Minimum Arrow show-up delay", + "ArrowDelayMax": "Maximum Arrow show-up delay", + "SMUsesUsedWhenFixingReactorOrO2": "Uses it takes to fix Reactor/O2", + "SMUsesUsedWhenFixingLightsOrComms": "Uses it takes to fix Lights/Comms", + + "GrenadierSkillMaxOfUseage": "(Initial) Max number of Grenades", + "ShowSpecificRole": "Know specific roles on Task Completion", + "TimeMasterMaxUses": "(Initial) Max Amount of Ability Uses", + "SwooperVentNormallyOnCooldown": "Swooper vents normally when swooping is on cooldown", + "WraithVentNormallyOnCooldown": "Wraith vents normally when invis is on cooldown", + "DisableMeeting": "Disable Meetings", + "DisableCloseDoor": "Disable Doors Sabotage", + "DisableSabotage": "Disable Sabotages", + "NoGameEnd": "No Game End", + "AllowConsole": "BepInEx Console", + "DebugMode": "Debug Mode", + "SyncButtonMode": "Limit Meeting Times", + "RandomMapsMode": "Random Maps Mode", + "SyncedButtonCount": "Max Number of Emergency Meetings per Game", + "HHSuccessKCDDecrease": "Kill cooldown decrease on killing target", + "HHFailureKCDIncrease": "Kill cooldown increase on killing others", + "HHNumOfTargets": "Number of targets", + "Targets": "Targets: ", + "HHMaxKCD": "Maximum kill cooldown", + "HHMinKCD": "Minimum kill cooldown", + "AllAliveMeeting": "Meeting When No One is Dead", + "AllAliveMeetingTime": "Meeting Time When No One is Dead", + "AdditionalEmergencyCooldown": "Additional Emergency Cooldown", + "AdditionalEmergencyCooldownThreshold": "Minimum Living Players to be Applied", + "AdditionalEmergencyCooldownTime": "Additional Cooldown", + "LadderDeath": "Fall From Ladders", + "LadderDeathChance": "Fall To Death Chance", + "EveryoneCanSeeDeathReason": "Everyone Can See Death Reason", + "DisableSwipeCardTask": "Disable Swipe Card Task", + "DisableSubmitScanTask": "Disable Submit Scan Task", + "DisableUnlockSafeTask": "Disable Unlock Safe Task", + "DisableUploadDataTask": "Disable Upload Data Task", + "DisableStartReactorTask": "Disable Start Reactor Task", + "DisableResetBreakerTask": "Disable Reset Breakers Task", + "DisableShortTasks": "Disable Short Tasks", + "DisableCleanVent": "Disable Clean Vent Task", + "DisableCalibrateDistributor": "Disable Calibrate Distributor Task", + "DisableChartCourse": "Disable Chart Course Task", + "DisableStabilizeSteering": "Disable Stabilize Steering Task", + "DisableCleanO2Filter": "Disable Clean O2 Filter Task", + "DisableUnlockManifolds": "Disable Unlock Manifolds Task", + "DisablePrimeShields": "Disable Prime Shields Task", + "DisableMeasureWeather": "Disable Measure Weather", + "DisableBuyBeverage": "Disable Buy Beverage", + "DisableAssembleArtifact": "Disable Assemble Artifact Task", + "DisableSortSamples": "Disable Sort Samples Task", + "DisableProcessData": "Disable Process Data Task", + "DisableRunDiagnostics": "Disable Run Diagnostics Task", + "DisableRepairDrill": "Disable Repair Drill Task", + "DisableAlignTelescope": "Disable Align Telescope Task", + "DisableRecordTemperature": "Disable Record Temperature Task", + "DisableFillCanisters": "Disable Fill Canisters Task", + "DisableMonitorTree": "Disable Monitor Tree Task", + "DisableStoreArtifacts": "Disable Store Artifacts Task", + "DisablePutAwayPistols": "Disable Put Away Pistols Task", + "DisablePutAwayRifles": "Disable Put Away Rifles Task", + "DisableMakeBurger": "Disable Make Burger Task", + "DisableCleanToilet": "Disable Clean Toilet Task", + "DisableDecontaminate": "Disable Decontaminate Task", + "DisableSortRecords": "Disable Sort Records Task", + "DisableFixShower": "Disable Fix Shower Task", + "DisablePickUpTowels": "Disable Pick Up Towels Task", + "DisablePolishRuby": "Disable Polish Ruby Task", + "DisableDressMannequin": "Disable Dress Mannequin Task", + "DisableCommonTasks": "Disable Common Tasks", + "DisableFixWiring": "Disable Fix Wiring Task", + "DisableEnterIdCode": "Disable Enter ID Code Task", + "DisableInsertKeys": "Disable Insert Keys Task", + "DisableScanBoardingPass": "Disable Scan Boarding Pass Task", + "DisableLongTasks": "Disable Long Tasks", + "DisableAlignEngineOutput": "Disable Align Engine Output Task", + "DisableInspectSample": "Disable Inspect Sample Task", + "DisableEmptyChute": "Disable Empty Chute Task", + "DisableClearAsteroids": "Disable Clear Asteroids Task", + "DisableWaterPlants": "Disable Water Plants Task", + "DisableOpenWaterways": "Disable Open Waterways Task", + "DisableReplaceWaterJug": "Disable Replace Water Jug Task", + "DisableRebootWifi": "Disable Reboot Wifi Task", + "DisableDevelopPhotos": "Disable Develop Photos Task", + "DisableRewindTapes": "Disable Rewind Tapes Task", + "DisableStartFans": "Disable Start Fans Task", + "DisableOtherTasks": "Disable Situational Tasks", + "DisableEmptyGarbage": "Disable Empty Garbage Task", + "DisableFuelEngines": "Disable Fuel Engines Task", + "DisableDivertPower": "Disable Divert Power Task", + "DisableActivateWeatherNodes": "Disable Weather Nodes Task", + "DisableRoastMarshmallow": "Disable Roast Marshmallow", + "DisableCollectSamples": "Disable Collect Samples", + "DisableReplaceParts": "Disable Replace Parts", + "DisableCollectVegetables": "Disable Collect Vegetables", + "DisableMineOres": "Disable Mine Ores", + "DisableExtractFuel": "Disable Extract Fuel", + "DisableCatchFish": "Disable Catch Fish", + "DisablePolishGem": "Disable Polish Gem", + "DisableHelpCritter": "Disable Help Critter", + "DisableHoistSupplies": "Disable Hoist Supplies", + "DisableFixAntenna": "Disable Fix Antenna", + "DisableBuildSandcastle": "Disable Build Sandcastle", + "DisableCrankGenerator": "Disable Crank Generator", + "DisableMonitorMushroom": "Disable Monitor Mushroom", + "DisablePlayVideoGame": "Disable Play Video Game", + "DisableFindSignal": "Disable Find Signal", + "DisableThrowFisbee": "Disable Throw Frisbee", + "DisableLiftWeights": "Disable Lift Weights", + "DisableCollectShells": "Disable Collect Shells", + "SuffixMode": "Suffix", + "SuffixMode.None": "None", + "SuffixMode.Version": "Version", + "SuffixMode.Streaming": "Streaming", + "SuffixMode.Recording": "Recording", + "SuffixMode.RoomHost": "Room Host", + "SuffixMode.OriginalName": "Original Name", + "SuffixMode.DoNotKillMe": "Don't kill me", + "SuffixMode.NoAndroidPlz": "No phones", + "SuffixMode.AutoHost": "Auto-Host", + "SuffixModeText.DoNotKillMe": "Don't kill me", + "SuffixModeText.NoAndroidPlz": "No phones please", + "SuffixModeText.AutoHost": "Auto-hosting", + "FormatNameMode": "Player Name Mode", + "FormatNameModes.None": "Disable", + "FormatNameModes.Color": "Color", + "FormatNameModes.Snacks": "Random", + "DisableEmojiName": "Disable Emoji in names", + "FixFirstKillCooldown": "Override Starting Kill Cooldown", + "FixKillCooldownValue": "Starting Kill Cooldown", + "OverclockedReduction": "Kill Cooldown Reduction", + "GhostCanSeeOtherRoles": "Ghosts Can See Other Roles", "PreventSeeRolesImmediatelyAfterDeath": "Prevent seeing other's roles immediately after death", - "GhostCanSeeOtherVotes": "Ghosts Can See Vote Colors", - "GhostCanSeeDeathReason": "Ghost Can See Cause Of Death", - "GhostIgnoreTasks": "Ghosts Exempt From Tasks", - "ConvertedCanBeGhostRole": "Converted Players Can Be Any Ghost-Roles", - "NeutralCanBeGhostRole": "Neutral Players Can Be Any Ghost-Roles (Will change team respectively)", - "MaxImpGhostRole": "Max Impostor Ghost-Roles", - "MaxCrewGhostRole": "Max Crewmate Ghost-Roles", - "DefaultAngelCooldown": "Default Ability Cooldown", - "DisableTaskWin": "Disable Task Win", - "DisableTaskWinIfAllCrewsAreDead": "Disable Task Win If All <#8cffff>Crewmates Are Dead", - "DisableTaskWinIfAllCrewsAreConverted": "Disable Task Win If All <#8cffff>Crewmates Are <#ffab1b>Converted", - "HideGameSettings": "Hide Game Settings", - "DIYGameSettings": "Enable only custom /n messages", - "Settings:": "Settings:", - "VoteAbilityUsed": "Used {0} Ability", - "VoteHasReturned": "Your vote has been returned! (Meaning you can cast a vote normally)", - "VoteNotUseAbility": "You chose not to use your ability, and now may choose to skip or vote someone.", - "PlayerCanSetColor": "Players can use the /color command", - "PlayerCanSetName": "Players can use the /rn command", - "PlayerCanUseQuitCommand": "Players can use the /quit command to leave the lobby forever", - "PlayerCanUseTP": "Players can use the /tpin and /tpout command", - "CanPlayMiniGames": "Players can play mini-games", - "KPDCamouflageMode": "Camouflage Appearance", - "RoleOptions": "Role Options", - "DarkTheme": "Enable Dark Theme", - "DisableLobbyMusic": "Disable Lobby Music", - "AutoStart": "Auto start", - "EnableCustomButton": "Enable Custom Button Images", - "EnableCustomSoundEffect": "Enable Custom Sound Effects", - "EnableCustomDecorations": "Enable Custom Map Decorations", - "SwitchVanilla": "Switch Vanilla", - "UnlockFPS": "Unlock FPS", - "ForceOwnLanguage": "Force mod to use your language if possible", - "ForceOwnLanguageRoleName": "Force role names in your language if possible", - "VersionCheat": "Bypass version synchronization check", - "GodMode": "God Mode", - - "AutoDisplayKillLog": "Display Kill-log", - "AutoDisplayLastRoles": "Display Last Roles", - "AutoDisplayLastResult": "Auto Display Last Result", - "RevertOldKillLog": "Revert to old kill-log", - - "HideExileChat": "Hide exile (lava) chat", - "ExileSpamMsg": "Someone is trying to be a smart ass by lava chatting", - - "EnableYTPlan": "Enable Youtuber Plan", - "InvalidPermissionCMD": "INVALID PERMISSION\n\nSorry, you do not have the permission to use this command, check /me for all permissions", - "KickLowLevelPlayer": "Kick players whose level is lower than", - "TempBanLowLevelPlayer": "Temporarily ban low-level players", - "ApplyWhiteList": "Turn on Whitelist to bypass level kick", - "AllowOnlyWhiteList": "Allow only whitelisted players to join", - "AutoKickStart": "Kick players that say start", - "AutoKickStartTimes": "Number of warnings before kick", - "AutoKickStartAsBan": "Block a player after they're kicked", - "AutoKickStopWords": "Kick players who write banned words", - "AutoKickStopWordsTimes": "Number of warnings for banned words", - "AutoKickStopWordsAsBan": "Block a player after they're kicked", - "AutoWarnStopWords": "Warning to those who write banned words", - "TempBanPlayersWhoKeepQuitting": "Temporarily ban players who leave and join repeatedly", - "QuitTimesTillTempBan": "The quit frequency needed for temp ban", - "KickOtherPlatformPlayer": "Kick Non-PC players", - "OptKickAndroidPlayer": "Kick Android players", - "OptKickIphonePlayer": "Kick iOS players", - "OptKickXboxPlayer": "Kick Xbox players", - "OptKickPlayStationPlayer": "Kick PlayStation players", - "OptKickNintendoPlayer": "Kick Nintendo Switch players", - "ShareLobby": "Allow TOHE-Chan Shares Lobby Code To Discord", - "ShareLobbyMinPlayer": "Share Lobby Code When The Number Of Players Reaches", - "DisableVanillaRoles": "Disable Vanilla Roles", - "VoteMode": "Voting Mode", - "WhenSkipVote": "If the Player Skipped", - "WhenSkipVoteIgnoreFirstMeeting": "Ignore the First Meeting", - "WhenSkipVoteIgnoreNoDeadBody": "Ignore When No Dead Body", - "WhenSkipVoteIgnoreEmergency": "Ignore at Emergency Meetings", - "WhenNonVote": "If the Player didn't vote", - "Default": "Default", - "Suicide": "Suicide", - "SelfVote": "Self Vote", - "Skip": "Skip", - "WhenTie": "When Tied Vote", - "TieMode.Default": "Default", - "TieMode.All": "Eject All", - "TieMode.Random": "Eject Random", - "DisableDevices": "Disable Devices", - "DisableSkeldDevices": "Disable Skeld Devices", - "DisableMiraHQDevices": "Disable MIRA HQ Devices", - "DisablePolusDevices": "Disable Polus Devices", - "DisableAirshipDevices": "Disable Airship Devices", - "DisableFungleDevices": "Disable Fungle Devices", - "DisableSkeldAdmin": "Disable Admin", - "DisableMiraHQAdmin": "Disable Admin", - "DisablePolusAdmin": "Disable Admin", - "DisableAirshipCockpitAdmin": "Disable Cockpit Admin", - "DisableAirshipRecordsAdmin": "Disable Records Admin", - "DisableSkeldCamera": "Disable Cameras", - "DisablePolusCamera": "Disable Cameras", - "DisableAirshipCamera": "Disable Cameras", - "DisableMiraHQDoorLog": "Disable DoorLog", - "DisablePolusVital": "Disable Vitals", - "DisableAirshipVital": "Disable Vitals", - "DisableFungleVital": "Disable Vitals", - "DisableFungleBinoculars": "Disable Binoculars (Not work for vanilla)", - "IgnoreConditions": "Ignore Conditions", - "IgnoreImpostors": "Ignore Impostors", - "IgnoreNeutrals": "Ignore Neutrals", - "IgnoreCrewmates": "Ignore Crewmates", - "IgnoreAfterAnyoneDied": "Ignore After First Death", - "LightsOutSpecialSettings": "Fix Lights Special Settings", - "BlockDisturbancesToSwitches": "Block Switches When They Are Up", - "DisableAirshipViewingDeckLightsPanel": "Disable Viewing Deck Lights Panel (Airship)", - "DisableAirshipGapRoomLightsPanel": "Disable Gap Room Lights Panel (Airship)", - "DisableAirshipCargoLightsPanel": "Disable Cargo Lights Panel (Airship)", - "RandomSpawnMode": "Random Spawns Mode", - "RandomSpawn_SpawnInFirstRound": "Active On Round One", - "RandomSpawn_SpawnRandomLocation": "Random Spawns In Locations", - "RandomSpawn_AirshipAdditionalSpawn": "Additional Spawn Locations (Airship)", - "RandomSpawn_SpawnRandomVents": "Random Spawns On Vents", - "CommsCamouflage": "Camouflage during Comms Sabotage", - "DisableOnSomeMaps": "Disable comms camouflage on some maps", - "DisableOnSkeld": "Disable on The Skeld", - "DisableOnMira": "Disable on MIRA HQ", - "DisableOnPolus": "Disable on Polus", - "DisableOnDleks": "Disable on dlekS ehT", - "DisableOnAirship": "Disable on Airship", - "DisableOnFungle": "Disable on The Fungle", - "DisableReportWhenCC": "Disable body reporting while camouflaged", - "EnableDebugMode": "Enable Debug Mode", - "ChangeNameToRoleInfo": "Show Role Info to Unmodded Clients Round 1", - "SendRoleDescriptionFirstMeeting": "Show Role Descriptions to Unmodded Clients at First Meeting", - "RoleAssigningAlgorithm": "Role Assigning Algorithm", - "RoleAssigningAlgorithm.Default": "Default", - "RoleAssigningAlgorithm.NetRandom": ".NET System.Random", - "RoleAssigningAlgorithm.HashRandom": "HashRandom", - "RoleAssigningAlgorithm.Xorshift": "Xorshift", - "RoleAssigningAlgorithm.MersenneTwister": "MersenneTwister", - "MapModification": "Map Modifications", - "DisableAirshipMovingPlatform": "Disable Moving Platform (Airship)", - "AirshipVariableElectrical": "Variable Electrical (Airship)", - "DisableSporeTriggerOnFungle": "Disable Spore Trigger (Fungle)", - "DisableZiplineOnFungle": "Disable Zipline (Fungle)", - "DisableZiplineFromTop": "Disable Use From Top", - "DisableZiplineFromUnder": "Disable Use From Under", - "ResetDoorsEveryTurns": "Reset Doors After Meeting (Airship/Polus/Fungle)", - "DoorsResetMode": "Reset Doors Mode", - "AllOpen": "All Open", - "AllClosed": "All Closed", - "RandomByDoor": "Closed Random", - "ChangeDecontaminationTime": "Change Decontamination Time (MIRA HQ/Polus)", - "DecontaminationTimeOnMiraHQ": "Decontamination Time On MIRA HQ", - "DecontaminationTimeOnPolus": "Decontamination Time On Polus", - "EnableHalloweenDecorations": "Halloween Decorations (The Skeld/MIRA HQ/Dleks)", - "HalloweenDecorationsSkeld": "Enable On The Skeld", - "HalloweenDecorationsMira": "Enable On MIRA HQ", - "HalloweenDecorationsDleks": "Enable On dlekS ehT", - "EnableBirthdayDecorationSkeld": "Birthday Decoration On The Skeld", - "RandomBirthdayAndHalloweenDecorationSkeld": "Set Random Decoration When Birthday And Halloween Is Active On The Skeld", - "ApplyDenyNameList": "Apply DenyName List", - "KickPlayerFriendCodeInvalid": "Kick players with an invalid friend code", - "TempBanPlayerFriendCodeInvalid": "Temp Ban players with an invalid friend code", - "ApplyBanList": "Apply BanList", - "RemovePetsAtDeadPlayers": "Remove pets at dead players", - "KillFlashDuration": "Kill-Flash Duration", - "ConfirmEjectionsMode": "Confirm Ejections Mode", - "ConfirmEjections.None": "None", - "ConfirmEjections.Team": "Team", - "ConfirmEjections.Role": "Role", - "ShowImpRemainOnEject": "Show remaining Impostors on ejects", - "ShowNKRemainOnEject": "Show remaining Neutral Killers on ejects", - "ShowNARemainOnEject": "Show remaining Neutral Apocalypse on ejects", - "ConfirmEgoistOnEject": "Confirm Egoists on ejection", - "ConfirmLoversOnEject": "Confirm Lovers on ejection", - "ConfirmSidekickOnEject": "Confirm Sidekicks on ejection", - "HideBittenRolesOnEject": "Hide roles of bitten players on ejection", - "ShowTeamNextToRoleNameOnEject": "Show what team the ejected player's role is on", - "Ban": "Ban", - "Kick": "Kick", - "NoticeMe": "Notify me", - "NoticeEveryone": "Notify everyone", - "TempBan": "Temporary Ban", - "OnlyCancel": "Only Cancel the cheat actions", - "CheatResponses": "When a cheating player is found", - "NeutralRoleWinTogether": "Neutrals win together", - "NeutralWinTogether": "All Neutrals win together", - "MenuTitle.Disable": "★ Disable ★", - "MenuTitle.MapsSettings": "★ Maps ★", - "MenuTitle.Sabotage": "★ Sabotage ★", - "MenuTitle.Meeting": "★ Meeting ★", - "MenuTitle.Ghost": "★ Ghost ★", - "MenuTitle.Other": "★ Different ★", - "MenuTitle.Ejections": "★ Ejection ★", - "MenuTitle.Settings": "★ Settings ★", - "MenuTitle.TaskSettings": "★ Task Management ★", - "MenuTitle.Guessers": "★ Guesser Mode ★", - - "ShieldPersonDiedFirst": "Shield player who dead first in the last game", - "ShowShieldedPlayerToAll": "Reveal shielded player to all", - "RemoveShieldOnFirstDead": "Remove shield on first death", - "ShieldedCanUseKillButton": "Shielded player can use ability / kill button", - "PlayerIsShieldedByGame": "Player is protected by the game!", - - "LegacyNemesis": "Use Legacy Version", + "GhostCanSeeOtherVotes": "Ghosts Can See Vote Colors", + "GhostCanSeeDeathReason": "Ghost Can See Cause Of Death", + "GhostIgnoreTasks": "Ghosts Exempt From Tasks", + "ConvertedCanBeGhostRole": "Converted Players Can Be Any Ghost-Roles", + "NeutralCanBeGhostRole": "Neutral Players Can Be Any Ghost-Roles (Will change team respectively)", + "MaxImpGhostRole": "Max Impostor Ghost-Roles", + "MaxCrewGhostRole": "Max Crewmate Ghost-Roles", + "DefaultAngelCooldown": "Default Ability Cooldown", + "DisableTaskWin": "Disable Task Win", + "DisableTaskWinIfAllCrewsAreDead": "Disable Task Win If All <#8cffff>Crewmates Are Dead", + "DisableTaskWinIfAllCrewsAreConverted": "Disable Task Win If All <#8cffff>Crewmates Are <#ffab1b>Converted", + "HideGameSettings": "Hide Game Settings", + "DIYGameSettings": "Enable only custom /n messages", + "Settings:": "Settings:", + "VoteAbilityUsed": "Used {0} Ability", + "VoteHasReturned": "Your vote has been returned! (Meaning you can cast a vote normally)", + "VoteNotUseAbility": "You chose not to use your ability, and now may choose to skip or vote someone.", + "PlayerCanSetColor": "Players can use the /color command", + "PlayerCanSetName": "Players can use the /rn command", + "PlayerCanUseQuitCommand": "Players can use the /quit command to leave the lobby forever", + "PlayerCanUseTP": "Players can use the /tpin and /tpout command", + "CanPlayMiniGames": "Players can play mini-games", + "KPDCamouflageMode": "Camouflage Appearance", + "RoleOptions": "Role Options", + "DarkTheme": "Enable Dark Theme", + "DisableLobbyMusic": "Disable Lobby Music", + "AutoStart": "Auto start", + "EnableCustomButton": "Enable Custom Button Images", + "EnableCustomSoundEffect": "Enable Custom Sound Effects", + "EnableCustomDecorations": "Enable Custom Map Decorations", + "SwitchVanilla": "Switch Vanilla", + "UnlockFPS": "Unlock FPS", + "ForceOwnLanguage": "Force mod to use your language if possible", + "ForceOwnLanguageRoleName": "Force role names in your language if possible", + "VersionCheat": "Bypass version synchronization check", + "GodMode": "God Mode", + + "AutoDisplayKillLog": "Display Kill-log", + "AutoDisplayLastRoles": "Display Last Roles", + "AutoDisplayLastResult": "Auto Display Last Result", + "RevertOldKillLog": "Revert to old kill-log", + + "HideExileChat": "Hide exile (lava) chat", + "ExileSpamMsg": "Someone is trying to be a smart ass by lava chatting", + + "EnableYTPlan": "Enable Youtuber Plan", + "InvalidPermissionCMD": "INVALID PERMISSION\n\nSorry, you do not have the permission to use this command, check /me for all permissions", + "KickLowLevelPlayer": "Kick players whose level is lower than", + "TempBanLowLevelPlayer": "Temporarily ban low-level players", + "ApplyWhiteList": "Turn on Whitelist to bypass level kick", + "AllowOnlyWhiteList": "Allow only whitelisted players to join", + "AutoKickStart": "Kick players that say start", + "AutoKickStartTimes": "Number of warnings before kick", + "AutoKickStartAsBan": "Block a player after they're kicked", + "AutoKickStopWords": "Kick players who write banned words", + "AutoKickStopWordsTimes": "Number of warnings for banned words", + "AutoKickStopWordsAsBan": "Block a player after they're kicked", + "AutoWarnStopWords": "Warning to those who write banned words", + "TempBanPlayersWhoKeepQuitting": "Temporarily ban players who leave and join repeatedly", + "QuitTimesTillTempBan": "The quit frequency needed for temp ban", + "KickOtherPlatformPlayer": "Kick Non-PC players", + "OptKickAndroidPlayer": "Kick Android players", + "OptKickIphonePlayer": "Kick iOS players", + "OptKickXboxPlayer": "Kick Xbox players", + "OptKickPlayStationPlayer": "Kick PlayStation players", + "OptKickNintendoPlayer": "Kick Nintendo Switch players", + "ShareLobby": "Allow TOHE-Chan Shares Lobby Code To Discord", + "ShareLobbyMinPlayer": "Share Lobby Code When The Number Of Players Reaches", + "DisableVanillaRoles": "Disable Vanilla Roles", + "VoteMode": "Voting Mode", + "WhenSkipVote": "If the Player Skipped", + "WhenSkipVoteIgnoreFirstMeeting": "Ignore the First Meeting", + "WhenSkipVoteIgnoreNoDeadBody": "Ignore When No Dead Body", + "WhenSkipVoteIgnoreEmergency": "Ignore at Emergency Meetings", + "WhenNonVote": "If the Player didn't vote", + "Default": "Default", + "Suicide": "Suicide", + "SelfVote": "Self Vote", + "Skip": "Skip", + "WhenTie": "When Tied Vote", + "TieMode.Default": "Default", + "TieMode.All": "Eject All", + "TieMode.Random": "Eject Random", + "DisableDevices": "Disable Devices", + "DisableSkeldDevices": "Disable Skeld Devices", + "DisableMiraHQDevices": "Disable MIRA HQ Devices", + "DisablePolusDevices": "Disable Polus Devices", + "DisableAirshipDevices": "Disable Airship Devices", + "DisableFungleDevices": "Disable Fungle Devices", + "DisableSkeldAdmin": "Disable Admin", + "DisableMiraHQAdmin": "Disable Admin", + "DisablePolusAdmin": "Disable Admin", + "DisableAirshipCockpitAdmin": "Disable Cockpit Admin", + "DisableAirshipRecordsAdmin": "Disable Records Admin", + "DisableSkeldCamera": "Disable Cameras", + "DisablePolusCamera": "Disable Cameras", + "DisableAirshipCamera": "Disable Cameras", + "DisableMiraHQDoorLog": "Disable DoorLog", + "DisablePolusVital": "Disable Vitals", + "DisableAirshipVital": "Disable Vitals", + "DisableFungleVital": "Disable Vitals", + "DisableFungleBinoculars": "Disable Binoculars (Not work for vanilla)", + "IgnoreConditions": "Ignore Conditions", + "IgnoreImpostors": "Ignore Impostors", + "IgnoreNeutrals": "Ignore Neutrals", + "IgnoreCrewmates": "Ignore Crewmates", + "IgnoreAfterAnyoneDied": "Ignore After First Death", + "LightsOutSpecialSettings": "Fix Lights Special Settings", + "BlockDisturbancesToSwitches": "Block Switches When They Are Up", + "DisableAirshipViewingDeckLightsPanel": "Disable Viewing Deck Lights Panel (Airship)", + "DisableAirshipGapRoomLightsPanel": "Disable Gap Room Lights Panel (Airship)", + "DisableAirshipCargoLightsPanel": "Disable Cargo Lights Panel (Airship)", + "RandomSpawnMode": "Random Spawns Mode", + "RandomSpawn_SpawnInFirstRound": "Active On Round One", + "RandomSpawn_SpawnRandomLocation": "Random Spawns In Locations", + "RandomSpawn_AirshipAdditionalSpawn": "Additional Spawn Locations (Airship)", + "RandomSpawn_SpawnRandomVents": "Random Spawns On Vents", + "CommsCamouflage": "Camouflage during Comms Sabotage", + "DisableOnSomeMaps": "Disable comms camouflage on some maps", + "DisableOnSkeld": "Disable on The Skeld", + "DisableOnMira": "Disable on MIRA HQ", + "DisableOnPolus": "Disable on Polus", + "DisableOnDleks": "Disable on dlekS ehT", + "DisableOnAirship": "Disable on Airship", + "DisableOnFungle": "Disable on The Fungle", + "DisableReportWhenCC": "Disable body reporting while camouflaged", + "EnableDebugMode": "Enable Debug Mode", + "ChangeNameToRoleInfo": "Show Role Info to Unmodded Clients Round 1", + "SendRoleDescriptionFirstMeeting": "Show Role Descriptions to Unmodded Clients at First Meeting", + "RoleAssigningAlgorithm": "Role Assigning Algorithm", + "RoleAssigningAlgorithm.Default": "Default", + "RoleAssigningAlgorithm.NetRandom": ".NET System.Random", + "RoleAssigningAlgorithm.HashRandom": "HashRandom", + "RoleAssigningAlgorithm.Xorshift": "Xorshift", + "RoleAssigningAlgorithm.MersenneTwister": "MersenneTwister", + "MapModification": "Map Modifications", + "DisableAirshipMovingPlatform": "Disable Moving Platform (Airship)", + "AirshipVariableElectrical": "Variable Electrical (Airship)", + "DisableSporeTriggerOnFungle": "Disable Spore Trigger (Fungle)", + "DisableZiplineOnFungle": "Disable Zipline (Fungle)", + "DisableZiplineFromTop": "Disable Use From Top", + "DisableZiplineFromUnder": "Disable Use From Under", + "ResetDoorsEveryTurns": "Reset Doors After Meeting (Airship/Polus/Fungle)", + "DoorsResetMode": "Reset Doors Mode", + "AllOpen": "All Open", + "AllClosed": "All Closed", + "RandomByDoor": "Closed Random", + "ChangeDecontaminationTime": "Change Decontamination Time (MIRA HQ/Polus)", + "DecontaminationTimeOnMiraHQ": "Decontamination Time On MIRA HQ", + "DecontaminationTimeOnPolus": "Decontamination Time On Polus", + "EnableHalloweenDecorations": "Halloween Decorations (The Skeld/MIRA HQ/Dleks)", + "HalloweenDecorationsSkeld": "Enable On The Skeld", + "HalloweenDecorationsMira": "Enable On MIRA HQ", + "HalloweenDecorationsDleks": "Enable On dlekS ehT", + "EnableBirthdayDecorationSkeld": "Birthday Decoration On The Skeld", + "RandomBirthdayAndHalloweenDecorationSkeld": "Set Random Decoration When Birthday And Halloween Is Active On The Skeld", + "ApplyDenyNameList": "Apply DenyName List", + "KickPlayerFriendCodeInvalid": "Kick players with an invalid friend code", + "TempBanPlayerFriendCodeInvalid": "Temp Ban players with an invalid friend code", + "ApplyBanList": "Apply BanList", + "RemovePetsAtDeadPlayers": "Remove pets at dead players", + "KillFlashDuration": "Kill-Flash Duration", + "ConfirmEjectionsMode": "Confirm Ejections Mode", + "ConfirmEjections.None": "None", + "ConfirmEjections.Team": "Team", + "ConfirmEjections.Role": "Role", + "ShowImpRemainOnEject": "Show remaining Impostors on ejects", + "ShowNKRemainOnEject": "Show remaining Neutral Killers on ejects", + "ShowNARemainOnEject": "Show remaining Neutral Apocalypse on ejects", + "ConfirmEgoistOnEject": "Confirm Egoists on ejection", + "ConfirmLoversOnEject": "Confirm Lovers on ejection", + "ConfirmSidekickOnEject": "Confirm Sidekicks on ejection", + "HideBittenRolesOnEject": "Hide roles of bitten players on ejection", + "ShowTeamNextToRoleNameOnEject": "Show what team the ejected player's role is on", + "Ban": "Ban", + "Kick": "Kick", + "NoticeMe": "Notify me", + "NoticeEveryone": "Notify everyone", + "TempBan": "Temporary Ban", + "OnlyCancel": "Only Cancel the cheat actions", + "CheatResponses": "When a cheating player is found", + "NeutralRoleWinTogether": "Neutrals win together", + "NeutralWinTogether": "All Neutrals win together", + "MenuTitle.Disable": "★ Disable ★", + "MenuTitle.MapsSettings": "★ Maps ★", + "MenuTitle.Sabotage": "★ Sabotage ★", + "MenuTitle.Meeting": "★ Meeting ★", + "MenuTitle.Ghost": "★ Ghost ★", + "MenuTitle.Other": "★ Different ★", + "MenuTitle.Ejections": "★ Ejection ★", + "MenuTitle.Settings": "★ Settings ★", + "MenuTitle.TaskSettings": "★ Task Management ★", + "MenuTitle.Guessers": "★ Guesser Mode ★", + + "ShieldPersonDiedFirst": "Shield player who dead first in the last game", + "ShowShieldedPlayerToAll": "Reveal shielded player to all", + "RemoveShieldOnFirstDead": "Remove shield on first death", + "ShieldedCanUseKillButton": "Shielded player can use ability / kill button", + "PlayerIsShieldedByGame": "Player is protected by the game!", + + "LegacyNemesis": "Use Legacy Version", "LegacyParasite": "Use Legacy Version", "LegacyTraitor": "Use Legacy Version", - "ArsonistKeepsGameGoing": "Arsonist keeps the game going", - "ArsonistCanIgniteAnytime": "Can Ignite Anytime", - "ArsonistMinPlayersToIgnite": "Minimum doused needed for ignite", - "ArsonistMaxPlayersToIgnite": "Maximum doused needed for ignite", - "PuppeteerDoubleKills": "Puppet dies alongside victim", - "DollMasterPossessionCooldown": "Possession Cooldown", - "DollMasterPossessionDuration": "Possession Duration", - "DollMasterCanKillAsMainBody": "Can kill as the main body", - "DollMasterTargetDiesAfterPossession": "Target dies after possession", - - "DoubleAgentCanDiffuseBombs": "Double Agent can diffuse bombs from other roles", - "DoubleAgentClearBombOnMeetingCall": "Diffuse active bomb on meeting call", - "DoubleAgentCanUseAbilityInCalledMeeting": "If diffused can use ability in called meeting", - "DoubleAgentBombExplosionTimer": "Explosion time", - "DoubleAgentExplosionRadius": "Explosion radius", - "DoubleAgent_DiffusedAgitaterBomb": "Agitator bomb successfully diffused", - "DoubleAgent_DiffusedBastionBomb": "Bastion bomb successfully diffused", - "DoubleAgent_BombExplodesIn": "Bomb Explodes In: {0}s", - "DoubleAgent_BombExploded": "Bomb has exploded!", - "DoubleAgentChangeRoleTo": "Change role on last Imposter", - "DoubleAgentRoleChange": "You have become a: ", - - "MastermindCD": "Manipulate Cooldown", - "MastermindTimeLimit": "Time limit to kill someone", - "MastermindDelay": "Manipulation notification delay", - "ManipulateNotify": "Kill someone in {0}s or die!", - "ManipulatedKilled": "{0} has killed someone", - "SurvivedManipulation": "You survived the Mastermind's manipulation!", - "Glitch_HackCooldown": "Hack Cooldown", - "Glitch_HackDuration": "Hack Duration", - "Glitch_MimicCooldown": "Mimic Cooldown", - "Glitch_MimicDuration": "Mimic Duration", - "Glitch_MimicButtonText": "Mimic", - "Glitch_MimicDur": "Mimic Duration: {0}s", - "Glitch_HackCD": "Hack Cooldown: {0}s", - "Glitch_KCD": "Kill Cooldown: {0}s", - "Glitch_MimicCD": "Mimic Cooldown: {0}s", - "HackedByGlitch": "You are hacked by the Glitch, you can't {0}.", - "GlitchKill": "kill", - "GlitchReport": "report", - "GlitchVent": "vent", - "ShowFPS": "Show FPS", - "FPSGame": "FPS: ", - - "ControlCooldown": "Control Cooldown", - "PoisonCooldown": "Poison Cooldown", - "PoisonerKillDelay": "Poison Kill Delay", - "WardenNotifyLimit": "Max number of alerts", - - "BombCooldown": "Bomb Cooldown", - "Warlock_CanKillSelf": "Can Kill Themselves", - "CrewpostorKnowsAllies": "Knows Impostors", - "AlliesKnowCrewpostor": "Known to Impostors", - "CrewpostorLungeKill": "Crewpostor lunges on kill", - "CrewpostorKillAfterTask": "Number of tasks completed to make one kill", - - "NonNeutralKillingRolesMinPlayer": "Minimum amount of Non-Killing Neutrals", - "NonNeutralKillingRolesMaxPlayer": "Maximum amount of Non-Killing Neutrals", - "NeutralKillingRolesMinPlayer": "Minimum amount of Neutral Killers", - "NeutralKillingRolesMaxPlayer": "Maximum amount of Neutral Killers", - "NeutralApocalypseRolesMinPlayer": "Minimum amount of Neutral Apocalypse", - "NeutralApocalypseRolesMaxPlayer": "Maximum amount of Neutral Apocalypse", - "TNACanBeGuessed": "Transformed Neutral Apocalypse Roles can be guessed", - "ApocCanSeeEachOthersAddOns": "Neutral Apocalypse can see each other's Add-ons", - "ImpsCanSeeEachOthersRoles": "Impostors know the roles of other Impostors", - "ImpsCanSeeEachOthersAddOns": "Impostors can see each other's Add-ons", - "ImpKnowWhosMadmate": "Impostors know Madmates", - "MadmateKnowWhosImp": "Madmates know Impostors", - "MadmateKnowWhosMadmate": "Madmates know each other", - "ImpCanKillMadmate": "Impostors can kill Madmates", - "MadmateCanKillImp": "Madmates can kill Impostors", - "MadmateHasImpostorVision": "Madmates Have Impostor Vision", - "MadmateCanFixSabotage": "Madmates Can Fix Sabotages", - "EGCanGuessImp": "Can Guess Impostor Roles", - "GGCanGuessCrew": "Can Guess Crewmate Roles", - "EGCanGuessAdt": "Can Guess Add-Ons", - "EGCanGuessTaskDoneSnitch": "Can guess Snitch with All Tasks Done", - "GGCanGuessAdt": "Can Guess Add-Ons", - "GuesserCanGuessTimes": "Maximum number of guesses", - "GuesserTryHideMsg": "Try to hide the guesser's command", - "GCanGuessImp": "Impostor can guess Impostor roles", - "GCanGuessCrew": "Crewmate can guess Crewmate roles", - "GCanGuessAdt": "Can guess Add-ons", - "GCanGuessTaskDoneSnitch": "Can guess Snitch with All Tasks Done", - "BountyTargetChangeTime": "Time Until Target Swaps", - "BountySuccessKillCooldown": "Kill Cooldown After Killing Bounty", - "BountyFailureKillCooldown": "Kill Cooldown After Killing Others", - "BountyShowTargetArrow": "Show arrow pointing towards the target", - "DefaultShapeshiftCooldown": "Default Shapeshift Cooldown", - "DeadImpCantSabotage": "Impostors can't sabotage after they've died", - "VampireKillDelay": "Bite Kill Delay", - "VampireTargetDead": "Target died", - "VampireActionMode": "Action Mode", - "Vampire_OnlyBites": "Only Bites", - "Youtuber_KillerWinsWithYouTuber": "The Killer Wins With YouTuber", - "Maverick_MinKillsToWin": "Minimum number of kills to win", - - "Cooldown": "Cooldown", - "AbilityCooldown": "Ability Cooldown", - "SkillLimitTimes": "Max Number of Ability Uses", - "CanKill": "Can Kill", - "KillCooldown": "Kill Cooldown", - "CanVent": "Can Vent", - "CantMoveOnVents": "Can't Move On Vents (Unstable in Dleks map)", - "ImpostorVision": "Has Impostor Vision", - "CanUseSabotage": "Can Sabotage", - "CanHaveAccessToVitals": "Can Have Access To Vitals", - "CanKillImpostors": "Can Kill Impostors", - "CanGuess": "Can Guess in Guesser Mode or as Guesser", - "HideVote": "Hide Vote", - "HideAdditionalVotes": "Hide additional vote(s)", - "CanUseMeetingButton": "Can Call Emergency Meetings", - "ModeSwitchAction": "Switch Action via", - "ShowShapeshiftAnimations": "Show Shapeshift animations", - - "ShapeshifterBase_ShapeshiftCooldown": "Shapeshift Cooldown", - "ShapeshifterBase_ShapeshiftDuration": "Shapeshift Duration", - "ShapeshifterBase_LeaveShapeshiftingEvidence": "Leave Shapeshifting Evidence", - "PhantomBase_InvisCooldown": "Invis Cooldown", - "PhantomBase_InvisDuration": "Invis Duration", - "GuardianAngelBase_ProtectCooldown": "Protect Cooldown", - "GuardianAngelBase_ProtectionDuration": "Protection Duration", - "GuardianAngelBase_ImpostorsCanSeeProtect": "Protect Visible To Impostors", - "ScientistBase_BatteryCooldown": "Vitals Display Cooldown", - "ScientistBase_BatteryDuration": "Battery Duration", - "EngineerBase_VentCooldown": "Vent Cooldown", - "EngineerBase_InVentMaxTime": "Max Time In Vents", - "NoisemakerBase_ImpostorAlert": "Impostors Can Get Alert", - "NoisemakerBase_AlertDuration": "Alert Duration", - "TrackerBase_TrackingCooldown": "Tracking Cooldown", - "TrackerBase_TrackingDuration": "Tracking Duration", - "TrackerBase_TrackingDelay": "Tracking Delay", - - "KamikazeControversialSymbol": "Use controversial symbol", - "MareAddSpeedInLightsOut": "Additional Speed During Lights Out", - "MareKillCooldownInLightsOut": "Kill Cooldown During Lights Out", - "MechanicSkillLimit": "Initial repair use limit", - "MechanicFixesDoors": "Can open all doors in the same building", - "MechanicFixesReactors": "Can Fix Both Reactors Alone", - "MechanicFixesOxygens": "Can Fix Both O2 Alone", - "MechanicFixesCommunications": "Can Fix Both Comms Alone In MIRA HQ", - "MechanicFixesElectrical": "Can Fix Lights With One Switch", - - "SheriffShowShotLimit": "Display Shot Limit next to Role Name", - "SheriffCanKill%role%": "Can Kill %role%", - "SheriffCanKillNeutrals": "Can Kill Neutrals", - "SheriffCanKillNeutralsMode": "Neutral Configuration", - "SheriffCanKillAll": "All ON", - "SheriffCanKillSeparately": "Individual Settings", - "In%team%": "(Team %team%)", - "SheriffMisfireKillsTarget": "Misfire Kills Target", + "ArsonistKeepsGameGoing": "Arsonist keeps the game going", + "ArsonistCanIgniteAnytime": "Can Ignite Anytime", + "ArsonistMinPlayersToIgnite": "Minimum doused needed for ignite", + "ArsonistMaxPlayersToIgnite": "Maximum doused needed for ignite", + "PuppeteerDoubleKills": "Puppet dies alongside victim", + "DollMasterPossessionCooldown": "Possession Cooldown", + "DollMasterPossessionDuration": "Possession Duration", + "DollMasterCanKillAsMainBody": "Can kill as the main body", + "DollMasterTargetDiesAfterPossession": "Target dies after possession", + + "DoubleAgentCanDiffuseBombs": "Double Agent can diffuse bombs from other roles", + "DoubleAgentClearBombOnMeetingCall": "Diffuse active bomb on meeting call", + "DoubleAgentCanUseAbilityInCalledMeeting": "If diffused can use ability in called meeting", + "DoubleAgentBombExplosionTimer": "Explosion time", + "DoubleAgentExplosionRadius": "Explosion radius", + "DoubleAgent_DiffusedAgitaterBomb": "Agitator bomb successfully diffused", + "DoubleAgent_DiffusedBastionBomb": "Bastion bomb successfully diffused", + "DoubleAgent_BombExplodesIn": "Bomb Explodes In: {0}s", + "DoubleAgent_BombExploded": "Bomb has exploded!", + "DoubleAgentChangeRoleTo": "Change role on last Imposter", + "DoubleAgentRoleChange": "You have become a: ", + + "MastermindCD": "Manipulate Cooldown", + "MastermindTimeLimit": "Time limit to kill someone", + "MastermindDelay": "Manipulation notification delay", + "ManipulateNotify": "Kill someone in {0}s or die!", + "ManipulatedKilled": "{0} has killed someone", + "SurvivedManipulation": "You survived the Mastermind's manipulation!", + "Glitch_HackCooldown": "Hack Cooldown", + "Glitch_HackDuration": "Hack Duration", + "Glitch_MimicCooldown": "Mimic Cooldown", + "Glitch_MimicDuration": "Mimic Duration", + "Glitch_MimicButtonText": "Mimic", + "Glitch_MimicDur": "Mimic Duration: {0}s", + "Glitch_HackCD": "Hack Cooldown: {0}s", + "Glitch_KCD": "Kill Cooldown: {0}s", + "Glitch_MimicCD": "Mimic Cooldown: {0}s", + "HackedByGlitch": "You are hacked by the Glitch, you can't {0}.", + "GlitchKill": "kill", + "GlitchReport": "report", + "GlitchVent": "vent", + "ShowFPS": "Show FPS", + "FPSGame": "FPS: ", + + "ControlCooldown": "Control Cooldown", + "PoisonCooldown": "Poison Cooldown", + "PoisonerKillDelay": "Poison Kill Delay", + "WardenNotifyLimit": "Max number of alerts", + + "BombCooldown": "Bomb Cooldown", + "Warlock_CanKillSelf": "Can Kill Themselves", + "CrewpostorKnowsAllies": "Knows Impostors", + "AlliesKnowCrewpostor": "Known to Impostors", + "CrewpostorLungeKill": "Crewpostor lunges on kill", + "CrewpostorKillAfterTask": "Number of tasks completed to make one kill", + + "NonNeutralKillingRolesMinPlayer": "Minimum amount of Non-Killing Neutrals", + "NonNeutralKillingRolesMaxPlayer": "Maximum amount of Non-Killing Neutrals", + "NeutralKillingRolesMinPlayer": "Minimum amount of Neutral Killers", + "NeutralKillingRolesMaxPlayer": "Maximum amount of Neutral Killers", + "NeutralApocalypseRolesMinPlayer": "Minimum amount of Neutral Apocalypse", + "NeutralApocalypseRolesMaxPlayer": "Maximum amount of Neutral Apocalypse", + "TNACanBeGuessed": "Transformed Neutral Apocalypse Roles can be guessed", + "ApocCanSeeEachOthersAddOns": "Neutral Apocalypse can see each other's Add-ons", + "ImpsCanSeeEachOthersRoles": "Impostors know the roles of other Impostors", + "ImpsCanSeeEachOthersAddOns": "Impostors can see each other's Add-ons", + "ImpKnowWhosMadmate": "Impostors know Madmates", + "MadmateKnowWhosImp": "Madmates know Impostors", + "MadmateKnowWhosMadmate": "Madmates know each other", + "ImpCanKillMadmate": "Impostors can kill Madmates", + "MadmateCanKillImp": "Madmates can kill Impostors", + "MadmateHasImpostorVision": "Madmates Have Impostor Vision", + "MadmateCanFixSabotage": "Madmates Can Fix Sabotages", + "EGCanGuessImp": "Can Guess Impostor Roles", + "GGCanGuessCrew": "Can Guess Crewmate Roles", + "EGCanGuessAdt": "Can Guess Add-Ons", + "EGCanGuessTaskDoneSnitch": "Can guess Snitch with All Tasks Done", + "GGCanGuessAdt": "Can Guess Add-Ons", + "GuesserCanGuessTimes": "Maximum number of guesses", + "GuesserTryHideMsg": "Try to hide the guesser's command", + "GCanGuessImp": "Impostor can guess Impostor roles", + "GCanGuessCrew": "Crewmate can guess Crewmate roles", + "GCanGuessAdt": "Can guess Add-ons", + "GCanGuessTaskDoneSnitch": "Can guess Snitch with All Tasks Done", + "BountyTargetChangeTime": "Time Until Target Swaps", + "BountySuccessKillCooldown": "Kill Cooldown After Killing Bounty", + "BountyFailureKillCooldown": "Kill Cooldown After Killing Others", + "BountyShowTargetArrow": "Show arrow pointing towards the target", + "DefaultShapeshiftCooldown": "Default Shapeshift Cooldown", + "DeadImpCantSabotage": "Impostors can't sabotage after they've died", + "VampireKillDelay": "Bite Kill Delay", + "VampireTargetDead": "Target died", + "VampireActionMode": "Action Mode", + "Vampire_OnlyBites": "Only Bites", + "Youtuber_KillerWinsWithYouTuber": "The Killer Wins With YouTuber", + "Maverick_MinKillsToWin": "Minimum number of kills to win", + + "Cooldown": "Cooldown", + "AbilityCooldown": "Ability Cooldown", + "SkillLimitTimes": "Max Number of Ability Uses", + "CanKill": "Can Kill", + "KillCooldown": "Kill Cooldown", + "CanVent": "Can Vent", + "CantMoveOnVents": "Can't Move On Vents (Unstable in Dleks map)", + "ImpostorVision": "Has Impostor Vision", + "CanUseSabotage": "Can Sabotage", + "CanHaveAccessToVitals": "Can Have Access To Vitals", + "CanKillImpostors": "Can Kill Impostors", + "CanGuess": "Can Guess in Guesser Mode or as Guesser", + "HideVote": "Hide Vote", + "HideAdditionalVotes": "Hide additional vote(s)", + "CanUseMeetingButton": "Can Call Emergency Meetings", + "ModeSwitchAction": "Switch Action via", + "ShowShapeshiftAnimations": "Show Shapeshift animations", + + "ShapeshifterBase_ShapeshiftCooldown": "Shapeshift Cooldown", + "ShapeshifterBase_ShapeshiftDuration": "Shapeshift Duration", + "ShapeshifterBase_LeaveShapeshiftingEvidence": "Leave Shapeshifting Evidence", + "PhantomBase_InvisCooldown": "Invis Cooldown", + "PhantomBase_InvisDuration": "Invis Duration", + "GuardianAngelBase_ProtectCooldown": "Protect Cooldown", + "GuardianAngelBase_ProtectionDuration": "Protection Duration", + "GuardianAngelBase_ImpostorsCanSeeProtect": "Protect Visible To Impostors", + "ScientistBase_BatteryCooldown": "Vitals Display Cooldown", + "ScientistBase_BatteryDuration": "Battery Duration", + "EngineerBase_VentCooldown": "Vent Cooldown", + "EngineerBase_InVentMaxTime": "Max Time In Vents", + "NoisemakerBase_ImpostorAlert": "Impostors Can Get Alert", + "NoisemakerBase_AlertDuration": "Alert Duration", + "TrackerBase_TrackingCooldown": "Tracking Cooldown", + "TrackerBase_TrackingDuration": "Tracking Duration", + "TrackerBase_TrackingDelay": "Tracking Delay", + + "KamikazeControversialSymbol": "Use controversial symbol", + "MareAddSpeedInLightsOut": "Additional Speed During Lights Out", + "MareKillCooldownInLightsOut": "Kill Cooldown During Lights Out", + "MechanicSkillLimit": "Initial repair use limit", + "MechanicFixesDoors": "Can open all doors in the same building", + "MechanicFixesReactors": "Can Fix Both Reactors Alone", + "MechanicFixesOxygens": "Can Fix Both O2 Alone", + "MechanicFixesCommunications": "Can Fix Both Comms Alone In MIRA HQ", + "MechanicFixesElectrical": "Can Fix Lights With One Switch", + + "SheriffShowShotLimit": "Display Shot Limit next to Role Name", + "SheriffCanKill%role%": "Can Kill %role%", + "SheriffCanKillNeutrals": "Can Kill Neutrals", + "SheriffCanKillNeutralsMode": "Neutral Configuration", + "SheriffCanKillAll": "All ON", + "SheriffCanKillSeparately": "Individual Settings", + "In%team%": "(Team %team%)", + "SheriffMisfireKillsTarget": "Misfire Kills Target", "BlackHolePlaceCooldown": "Black Hole Place Cooldown", "BlackHoleDespawnMode": "Black Hole Despawn Mode", "BlackHoleDespawnTime": "Time After Black Hole Despawns", @@ -1557,368 +1570,368 @@ "After1PlayerEaten": "After 1 Player Was Eaten", "AfterMeeting": "After Meeting", "None": "None", - "SheriffShotLimit": "Max number of Kills", - "SheriffCanKillAllAlive": "Can Kill When No One Is Dead", - "SheriffCanKillCharmed": "Can kill Charmed players", - "SheriffCanKillEgoist": "Can Kill Egoists", - "SheriffCanKillSidekick": "Can Kill Sidekicks", - "SheriffCanKillLovers": "Can Kill Lovers", - "SheriffCanKillMadmate": "Can Kill Madmates", - "SheriffCanKillInfected": "Can Kill Infected players", - "SheriffCanKillContagious": "Can Kill Contagious players", - "SheriffSetMadCanKill": "Non-Crew Sheriff Configuration", - "SheriffMadCanKillImp": "Can kill Impostors", - "SheriffMadCanKillNeutral": "Can kill Neutrals", - "SheriffMadCanKillCrew": "Can kill Crewmates", - - "RebirthUses": "Amount of Rebirths", - "RebirthCountVotes": "Only rebirth to players who voted for them", - "RebirthFailed": "Ahh, how unfortunate, you did not find any viable souls to swap bodies with", + "SheriffShotLimit": "Max number of Kills", + "SheriffCanKillAllAlive": "Can Kill When No One Is Dead", + "SheriffCanKillCharmed": "Can kill Charmed players", + "SheriffCanKillEgoist": "Can Kill Egoists", + "SheriffCanKillSidekick": "Can Kill Sidekicks", + "SheriffCanKillLovers": "Can Kill Lovers", + "SheriffCanKillMadmate": "Can Kill Madmates", + "SheriffCanKillInfected": "Can Kill Infected players", + "SheriffCanKillContagious": "Can Kill Contagious players", + "SheriffSetMadCanKill": "Non-Crew Sheriff Configuration", + "SheriffMadCanKillImp": "Can kill Impostors", + "SheriffMadCanKillNeutral": "Can kill Neutrals", + "SheriffMadCanKillCrew": "Can kill Crewmates", + + "RebirthUses": "Amount of Rebirths", + "RebirthCountVotes": "Only rebirth to players who voted for them", + "RebirthFailed": "Ahh, how unfortunate, you did not find any viable souls to swap bodies with", "FireworkerCooldown": "Placement Cooldown", - "ReverieIncreaseKillCooldown": "Increase kill cooldown", - "ReverieMaxKillCooldown": "Max kill cooldown", - "ReverieMisfireSuicide": "Misfire on reaching max kill cooldown", - "ReverieResetCooldownMeeting": "Reset kill cooldown after meeting", - "ConvertedReverieKillAll": "Converted Reverie can kill anyone without repercussions", + "ReverieIncreaseKillCooldown": "Increase kill cooldown", + "ReverieMaxKillCooldown": "Max kill cooldown", + "ReverieMisfireSuicide": "Misfire on reaching max kill cooldown", + "ReverieResetCooldownMeeting": "Reset kill cooldown after meeting", + "ConvertedReverieKillAll": "Converted Reverie can kill anyone without repercussions", - "VigilanteNotify": "You have become the very thing you swore to destroy", + "VigilanteNotify": "You have become the very thing you swore to destroy", "DictatorChangeCommandToExpel": "Dictator use Command to expell instad of vote", "DictatorExpelSelf": "WAIT WAIT WAIT WAT THE HELLLLLL Bro really just want to expel himself", - "DoctorTaskCompletedBatteryCharge": "Battery Duration", - "SnitchEnableTargetArrow": "See Arrow Towards Target", - "SnitchCanGetArrowColor": "See Colored Arrows based on Team Colors", - "SnitchCanFindNeutralKiller": "Can Find Neutral Killers", - "SnitchCanFindNeutralApoc": "Can Find Neutral Apocalypse", - "SnitchCanFindMadmate": "Can Find Madmates", - "SnitchRemainingTaskFound": "Remaining tasks to be known", - "MayorAdditionalVote": "Additional Votes Count", - "MayorHasPortableButton": "Mayor has a Mobile Emergency Button", - "MayorNumOfUseButton": "Max Number of Mobile Emergency Buttons", - "MeetingsNeededForWin": "Meetings needed to win", - "Jester_RevealUponEject": "Reveal Upon Eject", - "CannotVoteWhenDead": "Cannot cast a vote while dead", - "EnableVote": "Enable /vote command", - "ShouldVoteSpam": "Try to hide /vote command", - "VoteDisabled": "/vote command has been disabled by the host.", - "ExecutionerCanTargetImpostor": "Can Target Impostors", - "ExecutionerCanTargetNeutralKiller": "Can Target Neutral Killing", - "ExecutionerCanTargetNeutralApocalypse": "Can Target Neutral Apocalypse", - "ExecutionerChangeRolesAfterTargetKilled": "When Target Dies, Executioner becomes", - "ExecutionerCanTargetNeutralBenign": "Can Target Neutral Benign", - "ExecutionerCanTargetNeutralEvil": "Can Target Neutral Evil", - "ExecutionerCanTargetNeutralChaos": "Can Target Neutral Chaos", - "Executioner_RevealTargetUponEject": "Reveal Target Upon Ejection", - "SidekickSheriffCanGoBerserk": "Recruited Sheriff Can Go Nuts", - "LawyerCanTargetImpostor": "Can Target Impostors", - "LawyerCanTargetNeutralKiller": "Can Target Neutral Killers", - "LawyerCanTargetNeutralApocalypse": "Can Target Neutral Apocalypse", - "LawyerCanTargetCrewmate": "Can Target Crewmates", - "LawyerCanTargetJester": "Can Target Jester", - "LawyerChangeRolesAfterTargetKilled": "When Target Dies, Lawyer becomes", - "LaywerShouldChangeRoleAfterTargetKilled": "Should Lawyer Change Role when Target Dies", - "LawyerTargetDeadInMeeting": "Your target was killed while meeting.\nYour role may change depending on the settings.", - - "MercenaryLimit": "Time Until Suicide", - "ArsonistDouseTime": "Douse Duration", - "CanTerroristSuicideWin": "Can Win By Suicide", - "FireworkerMaxCount": "Fireworker Count", - "FireworkerRadius": "Firework Explosion Radius", - "SniperCanKill": "Sniper can kill with bullets remaining", - "SniperBulletCount": "Ammo", - "SniperPrecisionShooting": "Precise Shooting", - "SniperAimAssist": "Aim Assist", - "SniperAimAssistOneshot": "One shot Assist", - - "PyroDouseCooldown": "Douse cooldown", - "PyroBurnCooldown": "Kill cooldown after killing a doused player", - - "Prohibited_OverrideBlockedVentsAfterMeeting": "Override Blocked Vents After Meeting", - "Prohibited_CountBlockedVentsInSkeld": "Count Blocked Vents In The Skeld", - "Prohibited_CountBlockedVentsInMira": "Count Blocked Vents In MIRA HQ", - "Prohibited_CountBlockedVentsInPolus": "Count Blocked Vents In Polus", - "Prohibited_CountBlockedVentsInDleks": "Count Blocked Vents In Dleks", - "Prohibited_CountBlockedVentsInAirship": "Count Blocked Vents In Airship", - "Prohibited_CountBlockedVentsInFungle": "Count Blocked Vents In The Fungle", - - "UndertakerFreezeDuration": "Freeze Duration", - "NameDisplayAddons": "Display Add-Ons next to the role name", - "YourAddon": "Your Add-ons:", - "NoLimitAddonsNumMax": "Max Add-ons Per Player", - "LoverSpawnChances": "Spawn Chance of Lovers", - "AdditionRolesSpawnRate": "Spawn Chance", - "TorchVision": "Torch Vision", - "TorchAffectedByLights": "Torch's vision is affected by Lights Sabotage", - "BewilderVision": "Bewilder Vision", - "JesterVision": "Jester Vision", - "LawyerVision": "Lawyer Vision", - "FlashSpeed": "Flash Speed", - "SlothSpeed": "Sloth Speed", - "LoverSuicide": "Lovers die together", - "NumberOfLovers": "Number of Lover Pairs (x2 members)", - "LoverKnowRoles": "Lovers know the roles of each other", - "TrapperBlockMoveTime": "Freeze time", - "BecomeTrapperBlockMoveTime": "Freeze time", - "TimeThiefDecreaseMeetingTime": "Lower Meeting Time by", - "TimeThiefLowerLimitVotingTime": "Minimum Voting Time", - "TimeThiefReturnStolenTimeUponDeath": "Return Stolen Time Upon Death", - "EvilTrackerCanSeeKillFlash": "Can See Kill-Flash", - "EvilTrackerCanSeeLastRoomInMeeting": "Can See Target's Last Room In Meeting", - "EvilTrackerTargetMode": "Can Set Target", - "EvilTrackerTargetMode.Never": "Never", - "EvilTrackerTargetMode.OnceInGame": "Once in-game", - "EvilTrackerTargetMode.EveryMeeting": "Every Meeting", - "EvilTrackerTargetMode.Always": "Any time", + "DoctorTaskCompletedBatteryCharge": "Battery Duration", + "SnitchEnableTargetArrow": "See Arrow Towards Target", + "SnitchCanGetArrowColor": "See Colored Arrows based on Team Colors", + "SnitchCanFindNeutralKiller": "Can Find Neutral Killers", + "SnitchCanFindNeutralApoc": "Can Find Neutral Apocalypse", + "SnitchCanFindMadmate": "Can Find Madmates", + "SnitchRemainingTaskFound": "Remaining tasks to be known", + "MayorAdditionalVote": "Additional Votes Count", + "MayorHasPortableButton": "Mayor has a Mobile Emergency Button", + "MayorNumOfUseButton": "Max Number of Mobile Emergency Buttons", + "MeetingsNeededForWin": "Meetings needed to win", + "Jester_RevealUponEject": "Reveal Upon Eject", + "CannotVoteWhenDead": "Cannot cast a vote while dead", + "EnableVote": "Enable /vote command", + "ShouldVoteSpam": "Try to hide /vote command", + "VoteDisabled": "/vote command has been disabled by the host.", + "ExecutionerCanTargetImpostor": "Can Target Impostors", + "ExecutionerCanTargetNeutralKiller": "Can Target Neutral Killing", + "ExecutionerCanTargetNeutralApocalypse": "Can Target Neutral Apocalypse", + "ExecutionerChangeRolesAfterTargetKilled": "When Target Dies, Executioner becomes", + "ExecutionerCanTargetNeutralBenign": "Can Target Neutral Benign", + "ExecutionerCanTargetNeutralEvil": "Can Target Neutral Evil", + "ExecutionerCanTargetNeutralChaos": "Can Target Neutral Chaos", + "Executioner_RevealTargetUponEject": "Reveal Target Upon Ejection", + "SidekickSheriffCanGoBerserk": "Recruited Sheriff Can Go Nuts", + "LawyerCanTargetImpostor": "Can Target Impostors", + "LawyerCanTargetNeutralKiller": "Can Target Neutral Killers", + "LawyerCanTargetNeutralApocalypse": "Can Target Neutral Apocalypse", + "LawyerCanTargetCrewmate": "Can Target Crewmates", + "LawyerCanTargetJester": "Can Target Jester", + "LawyerChangeRolesAfterTargetKilled": "When Target Dies, Lawyer becomes", + "LaywerShouldChangeRoleAfterTargetKilled": "Should Lawyer Change Role when Target Dies", + "LawyerTargetDeadInMeeting": "Your target was killed while meeting.\nYour role may change depending on the settings.", + + "MercenaryLimit": "Time Until Suicide", + "ArsonistDouseTime": "Douse Duration", + "CanTerroristSuicideWin": "Can Win By Suicide", + "FireworkerMaxCount": "Fireworker Count", + "FireworkerRadius": "Firework Explosion Radius", + "SniperCanKill": "Sniper can kill with bullets remaining", + "SniperBulletCount": "Ammo", + "SniperPrecisionShooting": "Precise Shooting", + "SniperAimAssist": "Aim Assist", + "SniperAimAssistOneshot": "One shot Assist", + + "PyroDouseCooldown": "Douse cooldown", + "PyroBurnCooldown": "Kill cooldown after killing a doused player", + + "Prohibited_OverrideBlockedVentsAfterMeeting": "Override Blocked Vents After Meeting", + "Prohibited_CountBlockedVentsInSkeld": "Count Blocked Vents In The Skeld", + "Prohibited_CountBlockedVentsInMira": "Count Blocked Vents In MIRA HQ", + "Prohibited_CountBlockedVentsInPolus": "Count Blocked Vents In Polus", + "Prohibited_CountBlockedVentsInDleks": "Count Blocked Vents In Dleks", + "Prohibited_CountBlockedVentsInAirship": "Count Blocked Vents In Airship", + "Prohibited_CountBlockedVentsInFungle": "Count Blocked Vents In The Fungle", + + "UndertakerFreezeDuration": "Freeze Duration", + "NameDisplayAddons": "Display Add-Ons next to the role name", + "YourAddon": "Your Add-ons:", + "NoLimitAddonsNumMax": "Max Add-ons Per Player", + "LoverSpawnChances": "Spawn Chance of Lovers", + "AdditionRolesSpawnRate": "Spawn Chance", + "TorchVision": "Torch Vision", + "TorchAffectedByLights": "Torch's vision is affected by Lights Sabotage", + "BewilderVision": "Bewilder Vision", + "JesterVision": "Jester Vision", + "LawyerVision": "Lawyer Vision", + "FlashSpeed": "Flash Speed", + "SlothSpeed": "Sloth Speed", + "LoverSuicide": "Lovers die together", + "NumberOfLovers": "Number of Lover Pairs (x2 members)", + "LoverKnowRoles": "Lovers know the roles of each other", + "TrapperBlockMoveTime": "Freeze time", + "BecomeTrapperBlockMoveTime": "Freeze time", + "TimeThiefDecreaseMeetingTime": "Lower Meeting Time by", + "TimeThiefLowerLimitVotingTime": "Minimum Voting Time", + "TimeThiefReturnStolenTimeUponDeath": "Return Stolen Time Upon Death", + "EvilTrackerCanSeeKillFlash": "Can See Kill-Flash", + "EvilTrackerCanSeeLastRoomInMeeting": "Can See Target's Last Room In Meeting", + "EvilTrackerTargetMode": "Can Set Target", + "EvilTrackerTargetMode.Never": "Never", + "EvilTrackerTargetMode.OnceInGame": "Once in-game", + "EvilTrackerTargetMode.EveryMeeting": "Every Meeting", + "EvilTrackerTargetMode.Always": "Any time", "ScavengerHasCustomDeathReason": "Enable Custom Death Reason", - "EvilHackerCanSeeDeadMark": "Can See The Location of Dead-bodies", - "EvilHackerCanSeeImpostorMark": "Can See The Location of Other Impostors", - "EvilHackerCanSeeKillFlash": "Can See Kill-Flash", - "EvilHackerCanSeeMurderRoom": "Can See The Murder Location", - "EvilHackerMurderNotify": "Murder In", - "EvilHackerLastAdminInfoTitle": "Last-minute admin information", - "EvilHackerDeadbody": "DEAD", - - "Ventguard": "Ventguard", - "VentguardInfo": "Block vents by entering them", - "VentguardInfoLong": "(Crewmates):\nAs the Ventguard, you can enter vents to block them. No one can enter blocked vents, except Crewmates, if the setting is on. Blocked vents can be resets every meeting.", - "VentguardVentButtonText": "Block", - "Ventguard_MaxGuards": "Max number of Vent Blocks", - "Ventguard_BlockVentCooldown": "Block Vent Cooldown", - "Ventguard_BlockDoesNotAffectCrew": "Crewmates can use blocked vents", - "Ventguard_BlocksResetOnMeeting": "Reset Blocked Vents Every Meeting", - "VentIsBlocked": "This Vent Is Now Blocked!", - - "TraitorKnowMadmate": "Traitor Knows Madmates", - "Psychic_NBareRed": "Neutral Benign can be red", - "Psychic_NEareRed": "Neutral Evil can be red", - "Psychic_NCareRed": "Neutral Chaos can be red", - "Psychic_NAareRed": "Neutral Apocalypse can be red", - "Psychic_NKareRed": "Neutral Killers can be red", - "Psychic_CrewKillingRed": "Crewmate Killing can be red", - "PsychicCanSeeNum": "Max number of red names", - "PsychicFresh": "New red names every meeting", - "DetectiveCanknowKiller": "Can find the killer's role", - "EveryOneKnowSuperStar": "Everyone knows the Super Star", - "HackLimit": "Ability Use Count", - "ZombieSpeedReduce": "After a certain time, decrease the speed of Zombie by", - "NemesisCanKillNum": "Max number of revenges", - "ImpKnowCelebrityDead": "Impostors know when the Celebrity dies", - "NeutralKnowCelebrityDead": "Neutrals know when the Celebrity dies", - "VectorVentNumWin": "Number of Vents to win", - "CanCheckCamera": "Can track camera usage", - "DefaultKillCooldown": "Starting kill cooldown", - "ReduceKillCooldown": "Reduce kill cooldown by", - "MinKillCooldown": "Minimum kill cooldown", - "BomberRadius": "Bomb radius (5x is about half a Cafeteria)", - "NotifyGodAlive": "Inform players at meetings that God is still alive", - "TransporterTeleportMax": "Max number of teleports", - "TriggerKill": "Kill", - "TriggerVent": "Vent", - "TriggerDouble": "Double Click", - "TimeManagerIncreaseMeetingTime": "Increase voting time by", - "TimeManagerLimitMeetingTime": "Maximum Length of Meetings", - "MadTimeManagerLimitMeetingTime": "Mad Time Manager - Minimum Voting Time", - "AssignOnlyToCrewmate": "Assign only to Crewmates", - "WorkhorseNumLongTasks": "Additional Long Tasks", - "WorkhorseNumShortTasks": "Additional Short Tasks", - "SnitchCanBeWorkhorse": "Snitch can become Workhorse", - "InnocentCanWinByImp": "If their target was an Impostor then they win with them", - "ImpCanBeParanoia": "Impostors can become Paranoia", - "CrewCanBeParanoia": "Crewmates can become Paranoia", - "DualVotes": "Duplicate votes", - "VeteranSkillCooldown": "Alert Cooldown", - "VeteranSkillDuration": "Alert Duration", - "BodyguardProtectRadius": "Protect Radius", - "ImpCanBeEgoist": "An Impostor can become Egoist", - "CrewCanBeEgoist": "Crewmates can become Egoist", - "ImpEgoistVisibalToAllies": "Impostors Can See Other Egoist Impostors", - "EgoistCountAsConverted": "Egoist count as converted neutral", - "GuessRainbow": "He seems too obvious, doesn't he?", - "RainbowColorChangeCoolDown": "The cooldown for changing colors", - "RainbowInCamouflage": "Rainbow color changes during Camouflage", - "BaitDelayMin": "Minimum Report Delay", - "BaitDelayMax": "Maximum Report Delay", - "BaitDelayNotify": "Warn the killer about the upcoming self-report", - "BecomeBaitDelayNotify": "Warn the killer about the upcoming self-report", - "BaitNotification": "Reveal Bait at the first meeting", - "BaitAdviceAlive": "{0} is the Bait. Whoever kills the Bait will commit self-report.", - "BaitCanBeReportedUnderAllConditions": "Bait Can Be Reported even if a meeting is disabled during comms sabotage", - "DeceiverAbilityLost": "Deceiver loses ability if it deceives player without kill button", - "AddictSuicideTimer": "Time Until Suicide", - "GrenadierSkillCooldown": "Grenade Cooldown", - "GrenadierSkillDuration": "Grenade Duration", - "GrenadierCauseVision": "Lowered vision", - "GrenadierCanAffectNeutral": "Can affect Neutrals", - "TicketsPerKill": "Votes Increase Amount Per Kill", - "GangsterRecruitCooldown": "Recruit cooldown", - "GangsterRecruitLimit": "Recruit limit", - "KamikazeMaxMarked": "Max Marked", - "RevolutionistDrawTime": "Tag Duration", - "RevolutionistCooldown": "Tag Cooldown", - "RevolutionistDrawCount": "Amount of Players needed to Tag", - "RevolutionistKillProbability": "Tagged player sacrifice probability", - "RevolutionistVentCountDown": "Time to Vent", - "PelicanKillCooldown": "Eat Cooldown", - "Pelican.TargetCannotBeEaten": "Target cannot be eaten", - "MadSnitchTasks": "Snitch Tasks", - "MedicWhoCanSeeProtect": "Who can see shield", - "MedicKnowShieldBroken": "Who sees kill attempt", - "Medic_SeeMedicAndTarget": "Medic+Shielded", - "Medic_SeeMedic": "Medic", - "Medic_SeeTarget": "Shielded", - "Medic_SeeNoOne": "Nothing", - "MedicShieldDeactivatesWhenMedicDies": "Shield deactivates when the Medic dies", - "MedicShielDeactivationIsVisible": "Shield deactivation is visible", - "MedicShieldDeactivationIsVisible_Immediately": "Immediately", - "MedicShieldDeactivationIsVisible_AfterMeeting": "After Meeting", - "MedicShieldDeactivationIsVisible_OFF": "OFF", - "MedicResetCooldown": "On kill attempt, reset murderer's cooldown to", - "MedicShieldedCanBeGuessed": "Guessing ignores Medic shield", - "MadmateSpawnMode": "Madmate spawning mode", - "MadmateSpawnMode.Assign": "Assign", - "MadmateSpawnMode.FirstKill": "First Kill", - "MadmateSpawnMode.SelfVote": "Self Vote", - "MadmateCountMode": "Madmates count as", - "MadmateCountMode.None": "Nothing", - "MadmateCountMode.Imp": "Impostors", - "MadmateCountMode.Original": "Original Team", - - "Altruist_RevivedDeadBodyCannotBeReported_Option": "Revived Dead Body Cannot Be Reported", - "Altruist_ImpostorsCanGetsAlert": "Impostors Can Get Alert", - "Altruist_ImpostorsCanGetsArrow": "Impostors Can Get Arrow", - "Altruist_NeutralKillersCanGetsAlert": "Neutral Killers Can Get Alert", - "Altruist_NeutralKillersCanGetsArrow": "Neutral Killers Can Get Arrow", - "AltruistSuffix": "<#00ffa5>Mode: {0}", - "AltruistReviveMode": "Revive", - "AltruistReportMode": "Report", - "Altruist_YouTriedReportRevivedDeadBody": "You Tried Report Revived Dead Body", - "Altruist_DeadPlayerHasBeenRevived": "A Dead Player Has Been Revived!", - "AltruistAbilityButton": "Change Mode", - - "SnatchesWin": "Snatches victory", - "DemonKillCooldown": "Attack Cooldown", - "DemonHealthMax": "Player max health", - "DemonDamage": "Damage ", - "DemonSelfHealthMax": "Demon max health", - "DemonSelfDamage": "Demon damage received", - "LightningConvertTime": "Duration of the transformation to Quantum Ghost", - "LightningKillCooldown": "Lightning Cooldown", - "LightningKillerConvertGhost": "Killer can transform into Quantum Ghost", - "CanCountNeutralKiller": "When Crewmates win by killing a Neutral player, they can snatch the victory", - "GreedyOddKillCooldown": "Odd-Numbered kill cooldown", - "GreedyEvenKillCooldown": "Even-Numbered kill cooldown", - "WorkaholicCannotWinAtDeath": "Can't win after they died", - "WorkaholicVisibleToEveryone": "Everyone knows who the Workaholic is", - "WorkaholicGiveAdviceAlive": "Advice at the first meeting if alive, can win after death, ghost tasks ON", - "DoctorVisibleToEveryone": "Everyone knows who the Doctor is", - "CursedWolfGuardSpellTimes": "Amount of Cursed Shields", - "KillAttackerWhenAbilityRemaining": "Kill attacker when ability is remaining", - "JinxSpellTimes": "Amount of Jinx Spells", - "CollectorCollectAmount": "Required number of votes", - "GlitchCanVote": "Can vote", - "QuickShooterShapeshiftCooldown": "Shapeshift Cooldown", - "MeetingReserved": "Max Bullets reserved for a meeting", - "AccurateCheckMode": "Can know specific role when tasks are not done", - "RandomActiveRoles": "Show random active roles in Fortune Teller hints", - "CamouflageCooldown": "Camouflage Cooldown", - "CamouflageDuration": "Camouflage Duration", - "NinjaMarkCooldown": "Mark Cooldown", - "NinjaAssassinateCooldown": "Assassinate Cooldown", - "NinjaModeDouble": "Double Click = Kill, Single Click = Mark", - "JudgeCanTrialnCrewKilling": "Can trial Crewmate Killing", - "JudgeCanTrialNeutralB": "Can trial Neutral Benign", - "JudgeCanTrialNeutralK": "Can trial Neutral Killing", - "JudgeCanTrialNeutralE": "Can trial Neutral Evil", - "JudgeCanTrialNeutralC": "Can trial Neutral Chaos", - "JudgeCanTrialNeutralA": "Can trial Neutral Apocalypse", - "JudgeCanTrialSidekick": "Can trial Sidekick", - "JudgeCanTrialInfected": "Can trial Infected", - "JudgeCanTrialContagious": "Can trial Contagious", - "JudgeTryHideMsg": "Hide Judge's commands", - "JudgeTrialLimitPerMeeting": "Max Trials per Meeting", - "JudgeTrialLimitPerGame": "Max Trials per Game", - "JudgeCanTrialMadmate": "Can trial Madmates", - "JudgeCanTrialCharmed": "Can trial Charmed players", - "JudgeDead": "Sorry, you can't trial players after death.", - "JudgeTrialMaxMeetingMsg": "\nNo more meeting trials left!", - "JudgeTrialMaxGameMsg": "\nNo more trials left!", - "Judge_LaughToWhoTrialSelf": "God, I didn't think the Judges would be so blind that they wouldn't even see that they had sentenced themselves.", - "Judge_TrialKill": "{0} was judged.", - "Judge_TrialKillTitle": "COURT", - "Judge_TrialHelp": "Command: /tl [player ID]\nYou can see the players' IDs before the players' names.\nOr use /id to view the list of all player IDs.", - "Judge_TrialNull": "Please choose a living player for the trial", - "VeteranSkillMaxOfUseage": "Max number of Alerts", - "SwooperCooldown": "Swoop Cooldown", - "SwooperDuration": "Swoop Duration", - "WraithCooldown": "Vanish Cooldown", - "WraithDuration": "Vanish Duration", - "BastionNotify": "A bomb was set off", - "EnteredBombedVent": "That vent was bombed!", - "BastionVentButtonText": "Bomb", - "BombsClearAfterMeeting": "Bombs clear after meetings", - "BastionMaxBombs": "(Initial) Maximum bombs", - "VentBombSuccess": "Bomb has been planted", - "LowLoadMode": "Low Load Mode", - "ShowLobbyCode": "Show lobby code in Discord status", - "BKProtectDuration": "Protection Duration", - "FollowerMaxBetTimes": "Maximum Number of Follows", - "FollowerBetCooldown": "Follow Cooldown", - "FollowerMaxBetCooldown": "Maximum Follow Cooldown", - "FollowerBetCooldownIncrese": "Increase Cooldown per 1 follow by", - "FollowerKnowTargetRole": "Follower knows their target's role", - "FollowerBetTargetKnowFollower": "Follower target knows who the Follower is", - "FortuneTellerHideVote": "Hide Fortune Teller's Votes", - "CultistCharmCooldown": "Charm Cooldown", - "CultistCharmCooldownIncrese": "Increases Charm Cooldown For Each Charm", - "CultistCharmMax": "Maximum Number Of Charm", - "CultistKnowTargetRole": "Know Charmed Player's Role", - "CultistTargetKnowOtherTarget": "Charmed players know each other", - "CultistCanCharmNeutral": "Neutral Roles can be Charmed", - "InfectiousBiteCooldown": "Infect Cooldown", - "KnowTargetRole": "Knows role of target", - "TargetKnowsLawyer": "Target knows their Lawyer", - "InfectiousBiteMax": "Maximum Infections", - "InfectiousKnowTargetRole": "Know infected player's role", - "InfectiousTargetKnowOtherTarget": "Infected players know each other", - "DoubleClickKill": "Double click to kill the target", - - "VirusInfectMax": "Maximum Number Of Spreads", - "VirusKnowTargetRole": "Know Contagious Player's Role", - "VirusTargetKnowOtherTarget": "Contagious players know each other", - "VirusKillInfectedPlayerAfterMeeting": "Contagious player dies after meeting", - "Virus_ContagiousCountMode": "Contagious players count as", - "Virus_ContagiousCountMode_None": "Nothing", - "Virus_ContagiousCountMode_Virus": "Virus", - "Virus_ContagiousCountMode_Original": "Original Team", - "VirusNoticeTitle": "[ Infected Corpse! ]", - "VirusNoticeMessage": "The body you reported was infected by the Virus! You are now part of Team Virus. Help the Virus win the game.", - "VirusNoticeMessage2": "The body you reported was infected by the Virus! Vote the Virus out during this meeting, or you will die.", - - "Cultist_CharmedCountMode": "Charmed players count as", - "Cultist_CharmedCountMode_None": "Nothing", - "Cultist_CharmedCountMode_Cultist": "Cultist", - "Cultist_CharmedCountMode_Original": "Original Team", - - "JackalCanWinBySabotageWhenNoImpAlive": "When all Impostors are dead, the Jackal wins by sabotage instead", - "JackalResetKillCooldownWhenPlayerGetKilled": "Reset kill cooldown if someone gets killed by another player", - "JackalResetKillCooldownOn": "Kill Cooldown On Reset", - "JackalCanRecruitSidekick": "Can recruit Sidekick", - "JackalSidekickRecruitLimit": "Maximum Number Of Recruits", - "Jackal_SidekickCountMode": "Sidekicks count as", - "Jackal_SidekickCountMode_None": "Nothing", - "Jackal_SidekickCountMode_Jackal": "Jackal", - "Jackal_SidekickCountMode_Original": "Original Team", - "Jackal_SidekickAssignMode": "Sidekick Assign Mode", + "EvilHackerCanSeeDeadMark": "Can See The Location of Dead-bodies", + "EvilHackerCanSeeImpostorMark": "Can See The Location of Other Impostors", + "EvilHackerCanSeeKillFlash": "Can See Kill-Flash", + "EvilHackerCanSeeMurderRoom": "Can See The Murder Location", + "EvilHackerMurderNotify": "Murder In", + "EvilHackerLastAdminInfoTitle": "Last-minute admin information", + "EvilHackerDeadbody": "DEAD", + + "Ventguard": "Ventguard", + "VentguardInfo": "Block vents by entering them", + "VentguardInfoLong": "(Crewmates):\nAs the Ventguard, you can enter vents to block them. No one can enter blocked vents, except Crewmates, if the setting is on. Blocked vents can be resets every meeting.", + "VentguardVentButtonText": "Block", + "Ventguard_MaxGuards": "Max number of Vent Blocks", + "Ventguard_BlockVentCooldown": "Block Vent Cooldown", + "Ventguard_BlockDoesNotAffectCrew": "Crewmates can use blocked vents", + "Ventguard_BlocksResetOnMeeting": "Reset Blocked Vents Every Meeting", + "VentIsBlocked": "This Vent Is Now Blocked!", + + "TraitorKnowMadmate": "Traitor Knows Madmates", + "Psychic_NBareRed": "Neutral Benign can be red", + "Psychic_NEareRed": "Neutral Evil can be red", + "Psychic_NCareRed": "Neutral Chaos can be red", + "Psychic_NAareRed": "Neutral Apocalypse can be red", + "Psychic_NKareRed": "Neutral Killers can be red", + "Psychic_CrewKillingRed": "Crewmate Killing can be red", + "PsychicCanSeeNum": "Max number of red names", + "PsychicFresh": "New red names every meeting", + "DetectiveCanknowKiller": "Can find the killer's role", + "EveryOneKnowSuperStar": "Everyone knows the Super Star", + "HackLimit": "Ability Use Count", + "ZombieSpeedReduce": "After a certain time, decrease the speed of Zombie by", + "NemesisCanKillNum": "Max number of revenges", + "ImpKnowCelebrityDead": "Impostors know when the Celebrity dies", + "NeutralKnowCelebrityDead": "Neutrals know when the Celebrity dies", + "VectorVentNumWin": "Number of Vents to win", + "CanCheckCamera": "Can track camera usage", + "DefaultKillCooldown": "Starting kill cooldown", + "ReduceKillCooldown": "Reduce kill cooldown by", + "MinKillCooldown": "Minimum kill cooldown", + "BomberRadius": "Bomb radius (5x is about half a Cafeteria)", + "NotifyGodAlive": "Inform players at meetings that God is still alive", + "TransporterTeleportMax": "Max number of teleports", + "TriggerKill": "Kill", + "TriggerVent": "Vent", + "TriggerDouble": "Double Click", + "TimeManagerIncreaseMeetingTime": "Increase voting time by", + "TimeManagerLimitMeetingTime": "Maximum Length of Meetings", + "MadTimeManagerLimitMeetingTime": "Mad Time Manager - Minimum Voting Time", + "AssignOnlyToCrewmate": "Assign only to Crewmates", + "WorkhorseNumLongTasks": "Additional Long Tasks", + "WorkhorseNumShortTasks": "Additional Short Tasks", + "SnitchCanBeWorkhorse": "Snitch can become Workhorse", + "InnocentCanWinByImp": "If their target was an Impostor then they win with them", + "ImpCanBeParanoia": "Impostors can become Paranoia", + "CrewCanBeParanoia": "Crewmates can become Paranoia", + "DualVotes": "Duplicate votes", + "VeteranSkillCooldown": "Alert Cooldown", + "VeteranSkillDuration": "Alert Duration", + "BodyguardProtectRadius": "Protect Radius", + "ImpCanBeEgoist": "An Impostor can become Egoist", + "CrewCanBeEgoist": "Crewmates can become Egoist", + "ImpEgoistVisibalToAllies": "Impostors Can See Other Egoist Impostors", + "EgoistCountAsConverted": "Egoist count as converted neutral", + "GuessRainbow": "He seems too obvious, doesn't he?", + "RainbowColorChangeCoolDown": "The cooldown for changing colors", + "RainbowInCamouflage": "Rainbow color changes during Camouflage", + "BaitDelayMin": "Minimum Report Delay", + "BaitDelayMax": "Maximum Report Delay", + "BaitDelayNotify": "Warn the killer about the upcoming self-report", + "BecomeBaitDelayNotify": "Warn the killer about the upcoming self-report", + "BaitNotification": "Reveal Bait at the first meeting", + "BaitAdviceAlive": "{0} is the Bait. Whoever kills the Bait will commit self-report.", + "BaitCanBeReportedUnderAllConditions": "Bait Can Be Reported even if a meeting is disabled during comms sabotage", + "DeceiverAbilityLost": "Deceiver loses ability if it deceives player without kill button", + "AddictSuicideTimer": "Time Until Suicide", + "GrenadierSkillCooldown": "Grenade Cooldown", + "GrenadierSkillDuration": "Grenade Duration", + "GrenadierCauseVision": "Lowered vision", + "GrenadierCanAffectNeutral": "Can affect Neutrals", + "TicketsPerKill": "Votes Increase Amount Per Kill", + "GangsterRecruitCooldown": "Recruit cooldown", + "GangsterRecruitLimit": "Recruit limit", + "KamikazeMaxMarked": "Max Marked", + "RevolutionistDrawTime": "Tag Duration", + "RevolutionistCooldown": "Tag Cooldown", + "RevolutionistDrawCount": "Amount of Players needed to Tag", + "RevolutionistKillProbability": "Tagged player sacrifice probability", + "RevolutionistVentCountDown": "Time to Vent", + "PelicanKillCooldown": "Eat Cooldown", + "Pelican.TargetCannotBeEaten": "Target cannot be eaten", + "MadSnitchTasks": "Snitch Tasks", + "MedicWhoCanSeeProtect": "Who can see shield", + "MedicKnowShieldBroken": "Who sees kill attempt", + "Medic_SeeMedicAndTarget": "Medic+Shielded", + "Medic_SeeMedic": "Medic", + "Medic_SeeTarget": "Shielded", + "Medic_SeeNoOne": "Nothing", + "MedicShieldDeactivatesWhenMedicDies": "Shield deactivates when the Medic dies", + "MedicShielDeactivationIsVisible": "Shield deactivation is visible", + "MedicShieldDeactivationIsVisible_Immediately": "Immediately", + "MedicShieldDeactivationIsVisible_AfterMeeting": "After Meeting", + "MedicShieldDeactivationIsVisible_OFF": "OFF", + "MedicResetCooldown": "On kill attempt, reset murderer's cooldown to", + "MedicShieldedCanBeGuessed": "Guessing ignores Medic shield", + "MadmateSpawnMode": "Madmate spawning mode", + "MadmateSpawnMode.Assign": "Assign", + "MadmateSpawnMode.FirstKill": "First Kill", + "MadmateSpawnMode.SelfVote": "Self Vote", + "MadmateCountMode": "Madmates count as", + "MadmateCountMode.None": "Nothing", + "MadmateCountMode.Imp": "Impostors", + "MadmateCountMode.Original": "Original Team", + + "Altruist_RevivedDeadBodyCannotBeReported_Option": "Revived Dead Body Cannot Be Reported", + "Altruist_ImpostorsCanGetsAlert": "Impostors Can Get Alert", + "Altruist_ImpostorsCanGetsArrow": "Impostors Can Get Arrow", + "Altruist_NeutralKillersCanGetsAlert": "Neutral Killers Can Get Alert", + "Altruist_NeutralKillersCanGetsArrow": "Neutral Killers Can Get Arrow", + "AltruistSuffix": "<#00ffa5>Mode: {0}", + "AltruistReviveMode": "Revive", + "AltruistReportMode": "Report", + "Altruist_YouTriedReportRevivedDeadBody": "You Tried Report Revived Dead Body", + "Altruist_DeadPlayerHasBeenRevived": "A Dead Player Has Been Revived!", + "AltruistAbilityButton": "Change Mode", + + "SnatchesWin": "Snatches victory", + "DemonKillCooldown": "Attack Cooldown", + "DemonHealthMax": "Player max health", + "DemonDamage": "Damage ", + "DemonSelfHealthMax": "Demon max health", + "DemonSelfDamage": "Demon damage received", + "LightningConvertTime": "Duration of the transformation to Quantum Ghost", + "LightningKillCooldown": "Lightning Cooldown", + "LightningKillerConvertGhost": "Killer can transform into Quantum Ghost", + "CanCountNeutralKiller": "When Crewmates win by killing a Neutral player, they can snatch the victory", + "GreedyOddKillCooldown": "Odd-Numbered kill cooldown", + "GreedyEvenKillCooldown": "Even-Numbered kill cooldown", + "WorkaholicCannotWinAtDeath": "Can't win after they died", + "WorkaholicVisibleToEveryone": "Everyone knows who the Workaholic is", + "WorkaholicGiveAdviceAlive": "Advice at the first meeting if alive, can win after death, ghost tasks ON", + "DoctorVisibleToEveryone": "Everyone knows who the Doctor is", + "CursedWolfGuardSpellTimes": "Amount of Cursed Shields", + "KillAttackerWhenAbilityRemaining": "Kill attacker when ability is remaining", + "JinxSpellTimes": "Amount of Jinx Spells", + "CollectorCollectAmount": "Required number of votes", + "GlitchCanVote": "Can vote", + "QuickShooterShapeshiftCooldown": "Shapeshift Cooldown", + "MeetingReserved": "Max Bullets reserved for a meeting", + "AccurateCheckMode": "Can know specific role when tasks are not done", + "RandomActiveRoles": "Show random active roles in Fortune Teller hints", + "CamouflageCooldown": "Camouflage Cooldown", + "CamouflageDuration": "Camouflage Duration", + "NinjaMarkCooldown": "Mark Cooldown", + "NinjaAssassinateCooldown": "Assassinate Cooldown", + "NinjaModeDouble": "Double Click = Kill, Single Click = Mark", + "JudgeCanTrialnCrewKilling": "Can trial Crewmate Killing", + "JudgeCanTrialNeutralB": "Can trial Neutral Benign", + "JudgeCanTrialNeutralK": "Can trial Neutral Killing", + "JudgeCanTrialNeutralE": "Can trial Neutral Evil", + "JudgeCanTrialNeutralC": "Can trial Neutral Chaos", + "JudgeCanTrialNeutralA": "Can trial Neutral Apocalypse", + "JudgeCanTrialSidekick": "Can trial Sidekick", + "JudgeCanTrialInfected": "Can trial Infected", + "JudgeCanTrialContagious": "Can trial Contagious", + "JudgeTryHideMsg": "Hide Judge's commands", + "JudgeTrialLimitPerMeeting": "Max Trials per Meeting", + "JudgeTrialLimitPerGame": "Max Trials per Game", + "JudgeCanTrialMadmate": "Can trial Madmates", + "JudgeCanTrialCharmed": "Can trial Charmed players", + "JudgeDead": "Sorry, you can't trial players after death.", + "JudgeTrialMaxMeetingMsg": "\nNo more meeting trials left!", + "JudgeTrialMaxGameMsg": "\nNo more trials left!", + "Judge_LaughToWhoTrialSelf": "God, I didn't think the Judges would be so blind that they wouldn't even see that they had sentenced themselves.", + "Judge_TrialKill": "{0} was judged.", + "Judge_TrialKillTitle": "COURT", + "Judge_TrialHelp": "Command: /tl [player ID]\nYou can see the players' IDs before the players' names.\nOr use /id to view the list of all player IDs.", + "Judge_TrialNull": "Please choose a living player for the trial", + "VeteranSkillMaxOfUseage": "Max number of Alerts", + "SwooperCooldown": "Swoop Cooldown", + "SwooperDuration": "Swoop Duration", + "WraithCooldown": "Vanish Cooldown", + "WraithDuration": "Vanish Duration", + "BastionNotify": "A bomb was set off", + "EnteredBombedVent": "That vent was bombed!", + "BastionVentButtonText": "Bomb", + "BombsClearAfterMeeting": "Bombs clear after meetings", + "BastionMaxBombs": "(Initial) Maximum bombs", + "VentBombSuccess": "Bomb has been planted", + "LowLoadMode": "Low Load Mode", + "ShowLobbyCode": "Show lobby code in Discord status", + "BKProtectDuration": "Protection Duration", + "FollowerMaxBetTimes": "Maximum Number of Follows", + "FollowerBetCooldown": "Follow Cooldown", + "FollowerMaxBetCooldown": "Maximum Follow Cooldown", + "FollowerBetCooldownIncrese": "Increase Cooldown per 1 follow by", + "FollowerKnowTargetRole": "Follower knows their target's role", + "FollowerBetTargetKnowFollower": "Follower target knows who the Follower is", + "FortuneTellerHideVote": "Hide Fortune Teller's Votes", + "CultistCharmCooldown": "Charm Cooldown", + "CultistCharmCooldownIncrese": "Increases Charm Cooldown For Each Charm", + "CultistCharmMax": "Maximum Number Of Charm", + "CultistKnowTargetRole": "Know Charmed Player's Role", + "CultistTargetKnowOtherTarget": "Charmed players know each other", + "CultistCanCharmNeutral": "Neutral Roles can be Charmed", + "InfectiousBiteCooldown": "Infect Cooldown", + "KnowTargetRole": "Knows role of target", + "TargetKnowsLawyer": "Target knows their Lawyer", + "InfectiousBiteMax": "Maximum Infections", + "InfectiousKnowTargetRole": "Know infected player's role", + "InfectiousTargetKnowOtherTarget": "Infected players know each other", + "DoubleClickKill": "Double click to kill the target", + + "VirusInfectMax": "Maximum Number Of Spreads", + "VirusKnowTargetRole": "Know Contagious Player's Role", + "VirusTargetKnowOtherTarget": "Contagious players know each other", + "VirusKillInfectedPlayerAfterMeeting": "Contagious player dies after meeting", + "Virus_ContagiousCountMode": "Contagious players count as", + "Virus_ContagiousCountMode_None": "Nothing", + "Virus_ContagiousCountMode_Virus": "Virus", + "Virus_ContagiousCountMode_Original": "Original Team", + "VirusNoticeTitle": "[ Infected Corpse! ]", + "VirusNoticeMessage": "The body you reported was infected by the Virus! You are now part of Team Virus. Help the Virus win the game.", + "VirusNoticeMessage2": "The body you reported was infected by the Virus! Vote the Virus out during this meeting, or you will die.", + + "Cultist_CharmedCountMode": "Charmed players count as", + "Cultist_CharmedCountMode_None": "Nothing", + "Cultist_CharmedCountMode_Cultist": "Cultist", + "Cultist_CharmedCountMode_Original": "Original Team", + + "JackalCanWinBySabotageWhenNoImpAlive": "When all Impostors are dead, the Jackal wins by sabotage instead", + "JackalResetKillCooldownWhenPlayerGetKilled": "Reset kill cooldown if someone gets killed by another player", + "JackalResetKillCooldownOn": "Kill Cooldown On Reset", + "JackalCanRecruitSidekick": "Can recruit Sidekick", + "JackalSidekickRecruitLimit": "Maximum Number Of Recruits", + "Jackal_SidekickCountMode": "Sidekicks count as", + "Jackal_SidekickCountMode_None": "Nothing", + "Jackal_SidekickCountMode_Jackal": "Jackal", + "Jackal_SidekickCountMode_Original": "Original Team", + "Jackal_SidekickAssignMode": "Sidekick Assign Mode", "Jackal_SidekickAssignMode_SidekickAndRecruit": "Sidekick when failed Recruit", "Jackal_SidekickAssignMode_Sidekick": "Only Sidekick", "Jackal_SidekickAssignMode_Recruit": "Only Recruit", - "Jackal_SidekickCanKillSidekick": "Sidekicks can kill other Sidekicks", - "Jackal_SidekickCanKillJackal": "Sidekick can kill Jackal", + "Jackal_SidekickCanKillSidekick": "Sidekicks can kill other Sidekicks", + "Jackal_SidekickCanKillJackal": "Sidekick can kill Jackal", "Jackal_RecruitFailed": "You can not recruit this player!", - "JackalCanKillSidekick": "Jackal can kill Sidekick", + "JackalCanKillSidekick": "Jackal can kill Sidekick", "Jackal_SidekickCanKillWhenJackalAlive": "Sidekick can kill while Jackal is Alive", "Jackal_SidekickTurnIntoJackal": "Sidekick can turn into Jackal after its death", "Jackal_RestoreLimitOnNewJackal": "Restore Recruit limit when Sidekick become new Jackal", @@ -1928,1949 +1941,1967 @@ "Jackal_OnNewJackalSelected": "Old Jackal Dead, Please help new Jackal {0} for now!", "Jackal_BossIsDead": "Opps, the Jackal boss is dead!", - "CoronerArrowsPointingToDeadBody": "Arrows pointing to dead bodies", - "CoronerLeaveDeadBodyUnreportable": "Bodies the Coroner uses can't be reported", - "CoronerInformKillerBeingTracked": "Inform the Killer that he gets tracked", - - "PresidentCanBeGuessedAfterRevealing": "President can be guessed after revealing", - "HidePresidentEndCommand": "Hide President's commands", - "NeutralsSeePresident": "Neutrals can see revealed President", - "MadmatesSeePresident": "Madmates can see revealed President", - "ImpsSeePresident": "Impostors can see revealed President", - "PresidentDead": "Sorry, you can't force end the meeting after death.", - "PresidentEndMax": "No more force end meeting uses left!", - "PresidentRevealMax": "You have already revealed yourself...", - "PresidentRevealed": "[{0}] has chosen to reveal themselves as President!", - "GuessPresident": "President has revealed themselves. You can't guess them.", - "PresidentRevealTitle": "PRESIDENT REVEAL", - - "Troller_TrollsPerRound": "Trolls Per Round", - "Troller_CanHaveStartMeetingEvent": "Can Start Meeting By Event", - "Troller_ChangesSpeed": "Troller changed everyone speed!", - "Troller_SpeedOut": "Speed returned back", - "Troller_YouChangedCooldown": "You changed the cooldown of all players", - "Troller_ChangeYourCooldown": "Troller change your cooldown!", - "Troller_NoAddons": "No addons found on the random target", - "Troller_RemoveRandomAddon": "You removed add-on from random player", - "Troller_RemoveYourAddon": "Troller removed your random add-on", - "Troller_YouCausedSabotage": "You caused sabotage", - "Troller_YouFixedSabotage": "You fixed sabotage", - - "LuckyProbability": "Probability of surviving a kill", - "ImpCanBeDoubleShot": "Impostors can have Double Shot", - "CrewCanBeDoubleShot": "Crewmates can have Double Shot", - "NeutralCanBeDoubleShot": "Neutrals can have Double Shot", - "MimicCanSeeDeadRoles": "Mimic can see the roles of dead players", - "DisableReportWhenCamouflageIsActive": "Disable body reporting when camouflage is active", - "CanUseCommsSabotage": "Can use comms sabotage", - "ModTag": "Moderator♥", - "ApplyModeratorList": "Apply Moderator List", - "VipTag": "VIP★", - "ApplyVipList": "Apply VIP List", - "AllowSayCommand": "Allow moderators to use /say command", + "CoronerArrowsPointingToDeadBody": "Arrows pointing to dead bodies", + "CoronerLeaveDeadBodyUnreportable": "Bodies the Coroner uses can't be reported", + "CoronerInformKillerBeingTracked": "Inform the Killer that he gets tracked", + + "PresidentCanBeGuessedAfterRevealing": "President can be guessed after revealing", + "HidePresidentEndCommand": "Hide President's commands", + "NeutralsSeePresident": "Neutrals can see revealed President", + "MadmatesSeePresident": "Madmates can see revealed President", + "ImpsSeePresident": "Impostors can see revealed President", + "PresidentDead": "Sorry, you can't force end the meeting after death.", + "PresidentEndMax": "No more force end meeting uses left!", + "PresidentRevealMax": "You have already revealed yourself...", + "PresidentRevealed": "[{0}] has chosen to reveal themselves as President!", + "GuessPresident": "President has revealed themselves. You can't guess them.", + "PresidentRevealTitle": "PRESIDENT REVEAL", + + "Troller_TrollsPerRound": "Trolls Per Round", + "Troller_CanHaveStartMeetingEvent": "Can Start Meeting By Event", + "Troller_ChangesSpeed": "Troller changed everyone speed!", + "Troller_SpeedOut": "Speed returned back", + "Troller_YouChangedCooldown": "You changed the cooldown of all players", + "Troller_ChangeYourCooldown": "Troller change your cooldown!", + "Troller_NoAddons": "No addons found on the random target", + "Troller_RemoveRandomAddon": "You removed add-on from random player", + "Troller_RemoveYourAddon": "Troller removed your random add-on", + "Troller_YouCausedSabotage": "You caused sabotage", + "Troller_YouFixedSabotage": "You fixed sabotage", + + "LuckyProbability": "Probability of surviving a kill", + "ImpCanBeDoubleShot": "Impostors can have Double Shot", + "CrewCanBeDoubleShot": "Crewmates can have Double Shot", + "NeutralCanBeDoubleShot": "Neutrals can have Double Shot", + "MimicCanSeeDeadRoles": "Mimic can see the roles of dead players", + "DisableReportWhenCamouflageIsActive": "Disable body reporting when camouflage is active", + "CanUseCommsSabotage": "Can use comms sabotage", + "ModTag": "Moderator♥", + "ApplyModeratorList": "Apply Moderator List", + "VipTag": "VIP★", + "ApplyVipList": "Apply VIP List", + "AllowSayCommand": "Allow moderators to use /say command", "AllowStartCommand": "Allow moderators to use /start command", "StartCommandMinCountdown": "Minimum countdown for /start command", "StartCommandMaxCountdown": "Maximum countdown for /start command", - "KickCommandDisabled": "The kick command is currently disabled.", - "KickCommandNoAccess": "You do not have access to the kick command.", - "KickCommandInvalidID": "Invalid player ID specified.\nPlease use '/kick [playerID] [reason]' to kick a player.\nExample :- /kick 5 not following rules", - "KickCommandKickHost": "You are not permitted to kick the host.", - "KickCommandKickMod": "You are not permitted to kick other moderators.", - "KickCommandKicked": "was kicked from the game by ", - "KickCommandKickedRole": "Their role was", - "BanCommandDisabled": "The ban command is currently disabled.", - "BanCommandNoAccess": "You do not have access to the ban command.", - "BanCommandInvalidID": "Invalid player ID specified.\nPlease use '/ban [playerID] [reason]' to ban a player.\nExample :- /ban 5 not following rules ", - "BanCommandBanHost": "You are not permitted to ban the host.", - "BanCommandBanMod": "You are not permitted to ban other moderators.", - "BanCommandBanned": "was banned from the game by ", - "BanCommandBannedRole": "Their role was", - "BanCommandNoReason": "No reason specified.\nPlease use '/ban [playerID] [reason]\nExample :- /ban 5 not following rules", - "ColorCommandDisabled": "The modcolor command is currently disabled.", - "ColorCommandNoAccess": "You do not have access to the modcolor command.", - "ColorCommandNoLobby": "You can only use the command in Lobby when the game hasn't started.", - "ColorInvalidHexCode": "Invalid hexcode specified.\nPlease use '/modcolor [hexcode]' to change the color of MODERATOR♥.\nExample :- /modcolor 33ccff", - "ColorInvalidGradientCode": "Invalid hexcode specified.\nPlease use '/modcolor [hexcode][hexcode]' to change color of MODERATOR♥.\nExample :- /modcolor 33ccff ff99cc", - "VipColorCommandDisabled": "The vipcolor command is currently disabled.", - "VipColorCommandNoAccess": "You do not have access to the vipcolor command.", - "VipColorCommandNoLobby": "You can only use the command in Lobby when the game hasn't started.", - "VipColorInvalidHexCode": "Invalid hexcode specified.\nPlease use '/vipcolor [hexcode]' to change the color of VIP★.\nExample :- /vipcolor 33ccff", - "VipColorInvalidGradientCode": "Invalid hexcode specified.\nPlease use '/vipcolor [hexcode][hexcode]' to change color of VIP★.\nExample :- /vipcolor 33ccff ff99cc", - "TagColorInvalidHexCode": "Invalid hexcode specified.\nPlease use '/tagcolor [hexcode]' to change the color of your tag.\nExample :- /tagcolor ff00ff", - "midCommandDisabled": "The mid command is currently disabled.", - "midCommandNoAccess": "You do not have access to the mid command.", - "WarnCommandDisabled": "The warn command is currently disabled.", - "WarnCommandNoAccess": "You do not have access to the warn command.", - "WarnCommandInvalidID": "Invalid player ID specified.\nPlease use '/warn [playerID] [reason]' to warn a player. \nExample :- /warn 5 lava chatting", - "WarnCommandWarnHost": "You are not permitted to warn the host.", + "KickCommandDisabled": "The kick command is currently disabled.", + "KickCommandNoAccess": "You do not have access to the kick command.", + "KickCommandInvalidID": "Invalid player ID specified.\nPlease use '/kick [playerID] [reason]' to kick a player.\nExample :- /kick 5 not following rules", + "KickCommandKickHost": "You are not permitted to kick the host.", + "KickCommandKickMod": "You are not permitted to kick other moderators.", + "KickCommandKicked": "was kicked from the game by ", + "KickCommandKickedRole": "Their role was", + "BanCommandDisabled": "The ban command is currently disabled.", + "BanCommandNoAccess": "You do not have access to the ban command.", + "BanCommandInvalidID": "Invalid player ID specified.\nPlease use '/ban [playerID] [reason]' to ban a player.\nExample :- /ban 5 not following rules ", + "BanCommandBanHost": "You are not permitted to ban the host.", + "BanCommandBanMod": "You are not permitted to ban other moderators.", + "BanCommandBanned": "was banned from the game by ", + "BanCommandBannedRole": "Their role was", + "BanCommandNoReason": "No reason specified.\nPlease use '/ban [playerID] [reason]\nExample :- /ban 5 not following rules", + "ColorCommandDisabled": "The modcolor command is currently disabled.", + "ColorCommandNoAccess": "You do not have access to the modcolor command.", + "ColorCommandNoLobby": "You can only use the command in Lobby when the game hasn't started.", + "ColorInvalidHexCode": "Invalid hexcode specified.\nPlease use '/modcolor [hexcode]' to change the color of MODERATOR♥.\nExample :- /modcolor 33ccff", + "ColorInvalidGradientCode": "Invalid hexcode specified.\nPlease use '/modcolor [hexcode][hexcode]' to change color of MODERATOR♥.\nExample :- /modcolor 33ccff ff99cc", + "VipColorCommandDisabled": "The vipcolor command is currently disabled.", + "VipColorCommandNoAccess": "You do not have access to the vipcolor command.", + "VipColorCommandNoLobby": "You can only use the command in Lobby when the game hasn't started.", + "VipColorInvalidHexCode": "Invalid hexcode specified.\nPlease use '/vipcolor [hexcode]' to change the color of VIP★.\nExample :- /vipcolor 33ccff", + "VipColorInvalidGradientCode": "Invalid hexcode specified.\nPlease use '/vipcolor [hexcode][hexcode]' to change color of VIP★.\nExample :- /vipcolor 33ccff ff99cc", + "TagColorInvalidHexCode": "Invalid hexcode specified.\nPlease use '/tagcolor [hexcode]' to change the color of your tag.\nExample :- /tagcolor ff00ff", + "midCommandDisabled": "The mid command is currently disabled.", + "midCommandNoAccess": "You do not have access to the mid command.", + "WarnCommandDisabled": "The warn command is currently disabled.", + "WarnCommandNoAccess": "You do not have access to the warn command.", + "WarnCommandInvalidID": "Invalid player ID specified.\nPlease use '/warn [playerID] [reason]' to warn a player. \nExample :- /warn 5 lava chatting", + "WarnCommandWarnHost": "You are not permitted to warn the host.", "StartCommandNoAccess": "You do not have access to the start command.", "StartCommandDisabled": "The start command is currently disabled.", "StartCommandCountdown": "ERROR\n\nThe game is already starting!", "StartCommandStarted": "The game has been started by {0}!", "StartCommandInvalidCountdown": "ERROR\n\nThe countdown must be between {0} and {1}!", - "WarnCommandWarnMod": "You are not permitted to warn other moderators.", - "WarnCommandWarned": "has been warned. There will be no more warnings given and appropriate action will be taken \n ", - "WarnExample": "Use /warn [id] [reason] in future. \nExample :-\n /warn 5 lava chatting", - "SayCommandDisabled": "The say command is currently disabled.", - "MessageFromModerator": "MODERATOR", - "DeathReason.Kill": "Killed", - "DeathReason.Vote": "Ejected", - "DeathReason.Suicide": "Suicide", - "DeathReason.Spell": "Spelled", - "DeathReason.Cursed": "Cursed", - "DeathReason.Hex": "Hexed", - "DeathReason.Bite": "Bitten", - "DeathReason.Poison": "Poisoned", - "DeathReason.Gambled": "Guessed", - "DeathReason.FollowingSuicide": "Heartbroken", - "DeathReason.Bombed": "Exploded", - "DeathReason.Misfire": "Misfire", - "DeathReason.Torched": "Burned", - "DeathReason.Sniped": "Sniped", - "DeathReason.Execution": "Executed", - "DeathReason.Fall": "Fall", - "DeathReason.Revenge": "Revenge", - "DeathReason.Eaten": "Eaten", - "DeathReason.Sacrifice": "Victim", - "DeathReason.Quantization": "Quantization", - "DeathReason.Overtired": "Overtired", - "DeathReason.Ashamed": "Ashamed", - "DeathReason.Consumed": "Consumed", - "DeathReason.PissedOff": "Destroyed", - "DeathReason.Dismembered": "Dismembered", - "DeathReason.LossOfHead": "Strangled", - "DeathReason.Trialed": "Judged", - "DeathReason.Infected": "Infected", - "DeathReason.Jinx": "Jinxed", - "DeathReason.Pirate": "Plundered", - "DeathReason.Shrouded": "Shrouded", - "DeathReason.etc": "Other", - "DeathReason.Mauled": "Mauled", - "DeathReason.Hack": "Hacked", - "DeathReason.Curse": "Cursed", - "DeathReason.Drained": "Drained", - "DeathReason.Shattered": "Shattered", - "DeathReason.Trap": "Trapped", - "DeathReason.Targeted": "Targeted", - "DeathReason.Retribution": "Retribution", - "DeathReason.Slice": "Sliced", - "DeathReason.BloodLet": "Bleed", - "DeathReason.Armageddon": "Armageddon", - "DeathReason.Starved": "Starved", - "DeathReason.Equilibrium": "Equilibrium", - "DeathReason.Sacrificed": "Sacrificed", + "WarnCommandWarnMod": "You are not permitted to warn other moderators.", + "WarnCommandWarned": "has been warned. There will be no more warnings given and appropriate action will be taken \n ", + "WarnExample": "Use /warn [id] [reason] in future. \nExample :-\n /warn 5 lava chatting", + "SayCommandDisabled": "The say command is currently disabled.", + "MessageFromModerator": "MODERATOR", + "DeathReason.Kill": "Killed", + "DeathReason.Vote": "Ejected", + "DeathReason.Suicide": "Suicide", + "DeathReason.Spell": "Spelled", + "DeathReason.Cursed": "Cursed", + "DeathReason.Hex": "Hexed", + "DeathReason.Bite": "Bitten", + "DeathReason.Poison": "Poisoned", + "DeathReason.Gambled": "Guessed", + "DeathReason.FollowingSuicide": "Heartbroken", + "DeathReason.Bombed": "Exploded", + "DeathReason.Misfire": "Misfire", + "DeathReason.Torched": "Burned", + "DeathReason.Sniped": "Sniped", + "DeathReason.Execution": "Executed", + "DeathReason.Fall": "Fall", + "DeathReason.Revenge": "Revenge", + "DeathReason.Eaten": "Eaten", + "DeathReason.Sacrifice": "Victim", + "DeathReason.Quantization": "Quantization", + "DeathReason.Overtired": "Overtired", + "DeathReason.Ashamed": "Ashamed", + "DeathReason.PissedOff": "Destroyed", + "DeathReason.Dismembered": "Dismembered", + "DeathReason.LossOfHead": "Strangled", + "DeathReason.Trialed": "Judged", + "DeathReason.Infected": "Infected", + "DeathReason.Jinx": "Jinxed", + "DeathReason.Pirate": "Plundered", + "DeathReason.Shrouded": "Shrouded", + "DeathReason.etc": "Other", + "DeathReason.Mauled": "Mauled", + "DeathReason.Hack": "Hacked", + "DeathReason.Curse": "Cursed", + "DeathReason.Drained": "Drained", + "DeathReason.Shattered": "Shattered", + "DeathReason.Trap": "Trapped", + "DeathReason.Targeted": "Targeted", + "DeathReason.Retribution": "Retribution", + "DeathReason.Slice": "Sliced", + "DeathReason.AllergicReaction": "Allergic reaction", + "DeathReason.FadedAway": "Faded away", + "DeathReason.BloodLet": "Bleed", + "DeathReason.Armageddon": "Armageddon", + "DeathReason.Starved": "Starved", + "DeathReason.Equilibrium": "Equilibrium", + "DeathReason.Sacrificed": "Sacrificed", "DeathReason.Electrocuted": "Electrocuted", "DeathReason.Scavenged": "Scavenged", - "OnlyEnabledDeathReasons": "Only Enabled Death Reasons", - "Alive": "Alive", - "Disconnected": "Disconnected", - "Win": " Wins!", - - "Last-": "Last ", - "Madmate-": "Madmate ", - "Recruit-": "Recruit ", - "Charmed-": "Charmed ", - "Soulless-": "Soulless ", - "Infected-": "Infected ", - "Contagious-": "Contagious ", - "Admired-": "Admired ", - - "DeputyHandcuffCooldown": "Handcuff Cooldown", - "DeputyHandcuffMax": "Maximum Handcuffs", - "DeputyHandcuffedPlayer": "Handcuffed target", - "HandcuffedByDeputy": "You were handcuffed!", - "DeputyInvalidTarget": "Target cannot be handcuffed", - "DeputyHandcuffText": "Handcuff", - "DeputyHandcuffCDForTarget": "Kill Cooldown for handcuffed player", - - "RejectShapeshift.AbilityWasUsed": "Ability was used", - - "EscapisMtarkedPosition": "You marked self-position", - - "InvestigateCooldown": "Investigate Cooldown", - "InvestigateMax": "Maximum Investigations", - "InvestigateRoundMax": "Maximum Investigations in one round", - - "Color.Red": "Red", - "Color.Green": "Green", - "Color.Gray": "Gray", - "InvestigatorInvestigatedPlayer": "Player Investigated", - "InvestigatorInvalidTarget": "Can not investigate", - "InvestigatorButtonText": "Check", - - "Investigator.Suspicion": "Suspicion", - "Investigator.Role": "Role", - "SabotageCooldownControl": "Sabotage Cooldown Control", - "SabotageCooldown": "Sabotage Cooldown", - "SabotageTimeControl": "Sabotage Duration Control", - "SkeldReactorTimeLimit": "The Skeld Reactor Time Limit", - "SkeldO2TimeLimit": "The Skeld O2 Time Limit", - "MiraReactorTimeLimit": "MIRA HQ Reactor Time Limit", - "MiraO2TimeLimit": "MIRA HQ O2 Time Limit", - "PolusReactorTimeLimit": "Polus Reactor Time Limit", - "AirshipReactorTimeLimit": "Airship Reactor Time Limit", - "FungleReactorTimeLimit": "The Fungle Reactor Time Limit", - "FungleMushroomMixupDuration": "The Fungle Mushroom Mixup Duration", - "CommandList": "★ Command list:", - "Command.now": "→ Display active Settings", - "Command.roles": "[RoleName] → Display Role description", - "Command.myrole": "→ Displays a description of your role", - "Command.lastresult": "→ Display match results", - "Command.winner": "→ Display winners", - "CommandOtherList": "● Other commands:", - "Command.color": "[Color] → Change your color", - "Command.rename": "[Name] → Change Host Name", - "Command.quit": "→ I don't want to enter this lobby anymore", - "CommandHostList": "▲ Host Commands:", - "Command.say": "[Content] → Send message as Host", - "Command.mw": "[Seconds] → Set the message waiting duration", - "Command.solvecover": "→ Fix an issue where role names overlap the messages", - "Command.kill": "[Player ID] → Kill assigned player", - "Command.exe": "[Player ID] → Eject assigned player", - "Command.level": "[Level] → Change your in-game level", - "Command.idlist": "→ Display a list of player IDs", - "Command.qq": "→ Lobby will be posted on QQ website (China only)", - "Command.dump": "→ Output Log to Desktop", - "Command.death": "→ Display info on how you died", - "Command.icons": "
╳ - The Player was marked by the Blackmailer and can't talk during the Meeting
☆ - Used by Captain to display themselves. Only Crewmates can see the Captain's star
乂 - This player was hexed by the Hex Master and will die if the Hex Master isn't killed or ejected by the end of the Meeting.
♦ - Used by Lawyer or Executioner or Follower.
♥ - Used by Lovers or Romantic.
✚ - Used by Medic to mark their target.
⦿ - This player is in a duel with the Pirate.
!? - This player was marked by the Quizmaster and must answer the question correctly to survive.
☜ - Used by Schrödinger's cat to mark their teammate.
◈ - This player marked by the Shroud and will die if the Shroud is not killed or ejected by the end of the meeting.
⚠ - This player is a Snitch or Solsticer who has finished their tasks.
★ - Used by Super Star or Cyber or Marshall.
† - This player was spelled and will die if the Witch is not killed by the end of the meeting.
∇ - Used by Kamikaze to mark their targets.
■ - Used by Lightning to mark their quantum ghosts.
⊠ - Used by Jailer to mark their prisoner.
● - Used by Baker to mark who has Bread.
♠ - Used by Soul Collector to mark who's death they're predicting.
⦿ - Used by Plaguebearer to mark who they have plagued.", + "OnlyEnabledDeathReasons": "Only Enabled Death Reasons", + "Alive": "Alive", + "Disconnected": "Disconnected", + "Win": " Wins!", + + "Last-": "Last ", + "Madmate-": "Madmate ", + "Recruit-": "Recruit ", + "Charmed-": "Charmed ", + "Soulless-": "Soulless ", + "Infected-": "Infected ", + "Contagious-": "Contagious ", + "Admired-": "Admired ", + + "DeputyHandcuffCooldown": "Handcuff Cooldown", + "DeputyHandcuffMax": "Maximum Handcuffs", + "DeputyHandcuffedPlayer": "Handcuffed target", + "HandcuffedByDeputy": "You were handcuffed!", + "DeputyInvalidTarget": "Target cannot be handcuffed", + "DeputyHandcuffText": "Handcuff", + "DeputyHandcuffCDForTarget": "Kill Cooldown for handcuffed player", + + "RejectShapeshift.AbilityWasUsed": "Ability was used", + + "EvolverCatchText": "Catch", + "EvolverCatchSuccess": "Point gained!", + "EvolverCatchFailure": "You failed to catch them", + "EvolverMegaPointGain": "You have found a rare MEGA point!", + "Evolver_MinUpgradesToWin": "Minimum evolutions required to win", + + "EscapisMtarkedPosition": "You marked self-position", + + "InvestigateCooldown": "Investigate Cooldown", + "InvestigateMax": "Maximum Investigations", + "InvestigateRoundMax": "Maximum Investigations in one round", + + "Color.Red": "Red", + "Color.Green": "Green", + "Color.Gray": "Gray", + "InvestigatorInvestigatedPlayer": "Player Investigated", + "InvestigatorInvalidTarget": "Can not investigate", + "InvestigatorButtonText": "Check", + + "Investigator.Suspicion": "Suspicion", + "Investigator.Role": "Role", + "SabotageCooldownControl": "Sabotage Cooldown Control", + "SabotageCooldown": "Sabotage Cooldown", + "SabotageTimeControl": "Sabotage Duration Control", + "SkeldReactorTimeLimit": "The Skeld Reactor Time Limit", + "SkeldO2TimeLimit": "The Skeld O2 Time Limit", + "MiraReactorTimeLimit": "MIRA HQ Reactor Time Limit", + "MiraO2TimeLimit": "MIRA HQ O2 Time Limit", + "PolusReactorTimeLimit": "Polus Reactor Time Limit", + "AirshipReactorTimeLimit": "Airship Reactor Time Limit", + "FungleReactorTimeLimit": "The Fungle Reactor Time Limit", + "FungleMushroomMixupDuration": "The Fungle Mushroom Mixup Duration", + "CommandList": "★ Command list:", + "Command.now": "→ Display active Settings", + "Command.roles": "[RoleName] → Display Role description", + "Command.myrole": "→ Displays a description of your role", + "Command.lastresult": "→ Display match results", + "Command.winner": "→ Display winners", + "CommandOtherList": "● Other commands:", + "Command.color": "[Color] → Change your color", + "Command.rename": "[Name] → Change Host Name", + "Command.quit": "→ I don't want to enter this lobby anymore", + "CommandHostList": "▲ Host Commands:", + "Command.say": "[Content] → Send message as Host", + "Command.mw": "[Seconds] → Set the message waiting duration", + "Command.solvecover": "→ Fix an issue where role names overlap the messages", + "Command.kill": "[Player ID] → Kill assigned player", + "Command.exe": "[Player ID] → Eject assigned player", + "Command.level": "[Level] → Change your in-game level", + "Command.idlist": "→ Display a list of player IDs", + "Command.qq": "→ Lobby will be posted on QQ website (China only)", + "Command.dump": "→ Output Log to Desktop", + "Command.death": "→ Display info on how you died", + "Command.icons": "
╳ - The Player was marked by the Blackmailer and can't talk during the Meeting
☆ - Used by Captain to display themselves. Only Crewmates can see the Captain's star
乂 - This player was hexed by the Hex Master and will die if the Hex Master isn't killed or ejected by the end of the Meeting.
♦ - Used by Lawyer or Executioner or Follower.
♥ - Used by Lovers or Romantic.
✚ - Used by Medic to mark their target.
⦿ - This player is in a duel with the Pirate.
!? - This player was marked by the Quizmaster and must answer the question correctly to survive.
☜ - Used by Schrödinger's cat to mark their teammate.
◈ - This player marked by the Shroud and will die if the Shroud is not killed or ejected by the end of the meeting.
⚠ - This player is a Snitch or Solsticer who has finished their tasks.
★ - Used by Super Star or Cyber or Marshall.
† - This player was spelled and will die if the Witch is not killed by the end of the meeting.
∇ - Used by Kamikaze to mark their targets.
■ - Used by Lightning to mark their quantum ghosts.
⊠ - Used by Jailer to mark their prisoner.
● - Used by Baker to mark who has Bread.
♠ - Used by Soul Collector to mark who's death they're predicting.
⦿ - Used by Plaguebearer to mark who they have plagued.", "Command.start": "[Seconds] → Start the game", - "Command.iconinfo": "→ Display info on in-meeting icons", - "Command.iconhelp": "→ Display info on in-meeting icons to everyone", - "Command.Poll": "→ Start a poll with up-to 5 choices", - "IconsTitle": "Icon Meanings⚠", - "Remaining.ImpostorCount": "Impostors left: {0}", - "Remaining.MadmateCount": "Madmates left: {0}", - "Remaining.NeutralCount": "Neutral Killers left: {0}", - "Remaining.ApocalypseCount": "Neutral Apocalypse left: {0}", - "EnableKillerLeftCommand": "Enable use of /kcount command", - "ShowMadmatesInLeftCommand": "Show Madmates (including add-ons)", - "ShowApocalypseInLeftCommand": "Show Neutral Apocalypse", - "SeeEjectedRolesInMeeting": "See ejected roles in meetings", - "ThankYouForUsingTOHE": "Thank you for using TOHE!", - - "SkillUsedLeft": "You have activated your skill to call a meeting. \nRemaining amount of uses left:", - "NemesisDeadMsg": "The death of the Nemesis means the beginning of the revenge. \nPlease use /rv + [player ID] to kill the specified player \nYou can see player IDs in front of their names. \nOr type /rv to get a list of player IDs", - "NemesisAliveKill": "Revenge for the Nemesis can only begin after their death.", - "NemesisKillDead": "Choose a living player to take revenge", - "NemesisKillSucceed": "[{0}] was killed by the Nemesis!", - "NemesisKillDisable": "Sorry, but according to Host's settings, Nemesis revenge is prohibited in this game", - "NemesisKillMax": "You've reached the maximum amount of kills, you can't kill anymore!", - - "CelebrityDead": "Shock! Celebrity[{0}]has unfortunately been mercilessly killed in the recent period!", - "CyberDead": "Oh no! It appears the Cyber, {0}, has died recently.", - "DetectiveNoticeVictim": "According to your investigation,\nthe victim ([{0}]) had the role [{1}]", - "DetectiveNoticeKiller": "\nThe killer's role is [{0}]", - "DetectiveNoticeKillerNotFound": "The Detective couldn't find evidence leading to a murderer. This death is most likely suicide.", - "GodNoticeAlive": "During the meeting, each player felt a revelation from heaven, and it turned out that God is still alive!", - "WorkaholicAdviceAlive": "It's not recommended to kill or vote [{0}] out. Doing so will help them finish their tasks quicker.", - "GuessDead": "Sorry, but it's impossible to guess roles after your death", - "GuessSuperStar": "The Super Star can't be guessed... you thought it would be that easy, right?", - "GuessNotifiedBait": "Bait can't be guessed because it was announced. You thought it would be that easy, right?", - "GuessGM": "Guessing the GM is impossible because they're already dead.... And why would you do that to the poor Host?", - "GuessGuardianTask": "You can't guess a Guardian who has finished their tasks.", - "GuardianCantKilled": "You can't kill a Guardian who has finished their tasks.", - "GuessMarshallTask": "You can't guess a Marshall who has finished their tasks.", - "GuessObviousAddon": "Sorry, obvious add-ons cannot be guessed.", - "GuessAdtRole": "Unfortunately, the Host's settings do not allow you to guess add-ons", - "GuessImpRole": "Unfortunately, the Host's settings do not allow Impostors to guess Impostor roles.", - "GuessCrewRole": "Unfortunately, the Host's settings do not allow crewmates to guess crewmate roles.", - "GuessApocRole": "Fortunately, the Host's settings does not allow Apocalypse to guess Apocalypse roles.", - "GuessKill": "{0} was guessed", - "GuessNull": "Please select an ID of a living player to guess their role", - "GuessHelp": "Instructions: /bt [Player ID] [Role Name] \nExample: /bt 3 Bait \nYou can see the player IDs before everyone's names \n or use the /id command to list the player IDs", - "GGGuessMax": "You've reached the maximum guess limit. You can't guess anymore!", - "EGGuessMax": "You've reached the maximum guess limit. You can't guess anymore!", - "EGGuessSnitchTaskDone": "You thought you could guess the Snitch when all their tasks are done? Nice try. You're not getting out of this that easily.", - "GuessDoubleShot": "You guessed a role incorrectly, but you have Double Shot, so you get another chance!", - "LaughToWhoGuessSelf": "Tried to guess, who tried to self-guess! It's you! Ahah!", - "GuessDisabled": "Sorry, the host restricted guessing for your role.", - "GuessWorkaholic": "Sorry, you can't guess a revealed Workaholic as that would be unfair.", - "GuessDoctor": "Sorry, you can't guess a revealed Doctor as that would be unfair.", - "GuessMayor": "Sorry, you can't guess a revealed Mayor as that would be unfair.", - "GuessKnighted": "Sorry, Monarchs cannot guess Knighted.", - "GuessMonarch": "There's a knighted player alive, so the Monarch cannot be guessed.", - "GuessShielded": "Sorry, you can't guess the player who the Medic shields", - "MayorRevealWhenDoneTasks": "Mayor is revealed to everyone on task completion", - "MimicDeadMsg": "Mimic's hint: ", - "FortuneTellerCheck": "According to your fortune...", - "FortuneTellerCheckLimit": "Reminder: You have {0} fortunes left", - "FortuneTellerCheckSelfMsg": "Wow, you found yourself... All you see is a reflection.", - "FortuneTellerCheckReachLimit": "You've run out of fortunes.", - "FortuneTellerAlreadyCheckedMsg": "You've already checked the player", - "MorticianGetNoInfo": "According to your inspection, {0} did not seem to have contact with anyone during their lifetime.", - "MorticianGetInfo": "According to your inspection, the last person {0} came into contact with during their lifetime was {1}.", - - "MediumOnlyReceiveMsgFromCrew": "Receive messages only from Crewmates (including Madmates and Charmed Players)", - "MediumTitle": "MEDIUM", - "MediumHelp": "/ms yes to agree\n/ms no to disagree", - "MediumYes": "You thought you heard a quiet voice from another world affirming the answer to your question.", - "MediumNo": "You thought you heard a quiet voice from another world denying the answer to your question.", - "MediumDone": "You successfully responded to the Medium.", - "MediumNotifyTarget": "{0}, the Medium, has established contact with you. Before the end of this meeting, you have a chance to respond to their question. Type one of the following commands to answer:\nConfirm: /ms yes\nDeny: /ms no", - "MediumNotifySelf": "You established contact with {0}. Please ask them questions and wait for them to respond.\n\nRemaining ability uses: {1}", - "MediumKnowPlayerDead": "Someone died somewhere", - - "SpurtMinSpeed": "Min Speed", - "SpurtMaxSpeed": "Max Speed", - "SpurtModule": "Speed Modulator", - "EnableSpurtCharge": "Display The Charge", - "SpurtSuffix": "\n« Spurt: {0}% »", - - "TargetIsAlreadyDead": "Target Is Already Dead", - "ByBard": "by Bard", - "ByBardGetFailed": "Oops, I seem to be out of inspiration.", - "GangsterSuccessfullyRecruited": "You successfully recruited a player", - "GangsterRecruitmentFailure": "Target cannot be recruited", - "BeRecruitedByGangster": "The Gangster has recruited you", - "KamikazeHostage": "Can't hold target hostage", - "StealerGetTicket": "You've got {0} votes", - "BecomeMadmateCuzMadmateMode": "You became a Madmate because you died", - "CleanerCleanBody": "The body has been cleaned", - "QuickShooterStoraging": "Bullets stored successfully", + "Command.iconinfo": "→ Display info on in-meeting icons", + "Command.iconhelp": "→ Display info on in-meeting icons to everyone", + "Command.Poll": "→ Start a poll with up-to 5 choices", + "IconsTitle": "Icon Meanings⚠", + "Remaining.ImpostorCount": "Impostors left: {0}", + "Remaining.MadmateCount": "Madmates left: {0}", + "Remaining.NeutralCount": "Neutral Killers left: {0}", + "Remaining.ApocalypseCount": "Neutral Apocalypse left: {0}", + "EnableKillerLeftCommand": "Enable use of /kcount command", + "ShowMadmatesInLeftCommand": "Show Madmates (including add-ons)", + "ShowApocalypseInLeftCommand": "Show Neutral Apocalypse", + "SeeEjectedRolesInMeeting": "See ejected roles in meetings", + + "SkillUsedLeft": "You have activated your skill to call a meeting. \nRemaining amount of uses left:", + "NemesisDeadMsg": "The death of the Nemesis means the beginning of the revenge. \nPlease use /rv + [player ID] to kill the specified player \nYou can see player IDs in front of their names. \nOr type /rv to get a list of player IDs", + "NemesisAliveKill": "Revenge for the Nemesis can only begin after their death.", + "NemesisKillDead": "Choose a living player to take revenge", + "NemesisKillSucceed": "[{0}] was killed by the Nemesis!", + "NemesisKillDisable": "Sorry, but according to Host's settings, Nemesis revenge is prohibited in this game", + "NemesisKillMax": "You've reached the maximum amount of kills, you can't kill anymore!", + + "CelebrityDead": "Shock! Celebrity[{0}]has unfortunately been mercilessly killed in the recent period!", + "CyberDead": "Oh no! It appears the Cyber, {0}, has died recently.", + "DetectiveNoticeVictim": "According to your investigation,\nthe victim ([{0}]) had the role [{1}]", + "DetectiveNoticeKiller": "\nThe killer's role is [{0}]", + "DetectiveNoticeKillerNotFound": "The Detective couldn't find evidence leading to a murderer. This death is most likely suicide.", + "GodNoticeAlive": "During the meeting, each player felt a revelation from heaven, and it turned out that God is still alive!", + "WorkaholicAdviceAlive": "It's not recommended to kill or vote [{0}] out. Doing so will help them finish their tasks quicker.", + "GuessDead": "Sorry, but it's impossible to guess roles after your death", + "GuessSuperStar": "The Super Star can't be guessed... you thought it would be that easy, right?", + "GuessNotifiedBait": "Bait can't be guessed because it was announced. You thought it would be that easy, right?", + "GuessGM": "Guessing the GM is impossible because they're already dead.... And why would you do that to the poor Host?", + "GuessGuardianTask": "You can't guess a Guardian who has finished their tasks.", + "GuessMarshallTask": "You can't guess a Marshall who has finished their tasks.", + "GuessObviousAddon": "Sorry, obvious add-ons cannot be guessed.", + "GuessAdtRole": "Unfortunately, the Host's settings do not allow you to guess add-ons", + "GuessImpRole": "Unfortunately, the Host's settings do not allow Impostors to guess Impostor roles.", + "GuessCrewRole": "Unfortunately, the Host's settings do not allow crewmates to guess crewmate roles.", + "GuessApocRole": "Fortunately, the Host's settings does not allow Apocalypse to guess Apocalypse roles.", + "GuessKill": "{0} was guessed", + "GuessNull": "Please select an ID of a living player to guess their role", + "GuessHelp": "Instructions: /bt [Player ID] [Role Name] \nExample: /bt 3 Bait \nYou can see the player IDs before everyone's names \n or use the /id command to list the player IDs", + "GGGuessMax": "You've reached the maximum guess limit. You can't guess anymore!", + "EGGuessMax": "You've reached the maximum guess limit. You can't guess anymore!", + "EGGuessSnitchTaskDone": "You thought you could guess the Snitch when all their tasks are done? Nice try. You're not getting out of this that easily.", + "GuessDoubleShot": "You guessed a role incorrectly, but you have Double Shot, so you get another chance!", + "LaughToWhoGuessSelf": "Tried to guess, who tried to self-guess! It's you! Ahah!", + "GuessDisabled": "Sorry, the host restricted guessing for your role.", + "GuessWorkaholic": "Sorry, you can't guess a revealed Workaholic as that would be unfair.", + "GuessDoctor": "Sorry, you can't guess a revealed Doctor as that would be unfair.", + "GuessMayor": "Sorry, you can't guess a revealed Mayor as that would be unfair.", + "GuessKnighted": "Sorry, Monarchs cannot guess Knighted.", + "GuessMonarch": "There's a knighted player alive, so the Monarch cannot be guessed.", + "GuessShielded": "Sorry, you can't guess the player who the Medic shields", + "MayorRevealWhenDoneTasks": "Mayor is revealed to everyone on task completion", + "MimicDeadMsg": "Mimic's hint: ", + "FortuneTellerCheck": "According to your fortune...", + "FortuneTellerCheckLimit": "Reminder: You have {0} fortunes left", + "FortuneTellerCheckSelfMsg": "Wow, you found yourself... All you see is a reflection.", + "FortuneTellerCheckReachLimit": "You've run out of fortunes.", + "FortuneTellerAlreadyCheckedMsg": "You've already checked the player", + "MorticianGetNoInfo": "According to your inspection, {0} did not seem to have contact with anyone during their lifetime.", + "MorticianGetInfo": "According to your inspection, the last person {0} came into contact with during their lifetime was {1}.", + + "MediumOnlyReceiveMsgFromCrew": "Receive messages only from Crewmates (including Madmates and Charmed Players)", + "MediumTitle": "MEDIUM", + "MediumHelp": "/ms yes to agree\n/ms no to disagree", + "MediumYes": "You thought you heard a quiet voice from another world affirming the answer to your question.", + "MediumNo": "You thought you heard a quiet voice from another world denying the answer to your question.", + "MediumDone": "You successfully responded to the Medium.", + "MediumNotifyTarget": "{0}, the Medium, has established contact with you. Before the end of this meeting, you have a chance to respond to their question. Type one of the following commands to answer:\nConfirm: /ms yes\nDeny: /ms no", + "MediumNotifySelf": "You established contact with {0}. Please ask them questions and wait for them to respond.\n\nRemaining ability uses: {1}", + "MediumKnowPlayerDead": "Someone died somewhere", + + "SpurtMinSpeed": "Min Speed", + "SpurtMaxSpeed": "Max Speed", + "SpurtModule": "Speed Modulator", + "EnableSpurtCharge": "Display The Charge", + "SpurtSuffix": "\n« Spurt: {0}% »", + + "TargetIsAlreadyDead": "Target Is Already Dead", + "ByBard": "by Bard", + "ByBardGetFailed": "Oops, I seem to be out of inspiration.", + "GangsterSuccessfullyRecruited": "You successfully recruited a player", + "GangsterRecruitmentFailure": "Target cannot be recruited", + "BeRecruitedByGangster": "The Gangster has recruited you", + "KamikazeHostage": "Can't hold target hostage", + "StealerGetTicket": "You've got {0} votes", + "BecomeMadmateCuzMadmateMode": "You became a Madmate because you died", + "CleanerCleanBody": "The body has been cleaned", + "QuickShooterStoraging": "Bullets stored successfully", "QuickShooterFailed": "You are still in cooldown.", - "PoisonerTargetDead": "Target died", - "HexesLookLikeSpells": "Hexes appear as spells", - "HexButtonText": "Hex", - "BloodthirstAdded": "Your bloodthirst is now active!", - "WarlockNoTarget": "Manipulation failed due to no target", - "WarlockNoTargetYet": "You haven't marked a target.", - "WarlockTargetDead": "Manipulation failed due to target dead", - "WarlockControlKill": "Target died", - "OnCelebrityDead": "Warning: Celebrity death!", - "OnCyberDead": "Warning: Cyber died!", - "TeleportedInRndVentByDisperser": "Everyone was teleported to vents", - "TeleportedByTransporter": "Swapping places with: {0}", - "ErrorTeleport": "Teleport failed", - "EraseLimit": "Max Erases", - "EraserHideVote": "Hide Eraser Votes", - "EraserEraseMsgTitle": "ERASER", - "EraserEraseNotice": "You erased {0}.\nTheir role will be deactivated after the meeting.", - "EraserEraseBaseImpostorOrNeutralRoleNotice": "Oops, your target cannot be erased!", - "EraserEraseSelf": "Unfortunately, you can't erase yourself... Wait, why would you do that in the first place?!", - "EraserTryingGuessErasedPlayer": "You can't guess the role of the player you erased, except add-ons", - "LostRoleByEraser": "You lost your role because of the Eraser", - "KilledByScavenger": "The Scavenger killed you and thus teleported off-map", - "SnitchDoneTasks": "Call a meeting to find the impostors", - "SwooperCanVent": "Vent to turn invisible", - "SwooperInvisState": "You're invisible", - "SwooperInvisStateOut": "You're now visible", - "SwooperInvisInCooldown": "Swoop cooldown isn't up yet. Swooping failed", - "SwooperInvisStateCountdown": "Invisibility will expire after {0}s", - "SwooperInvisCooldownRemain": "Swoop Cooldown: {0}s", - "WraithCanVent": "Vent to turn invisible", - "WraithInvisState": "You are invisible", - "WraithInvisStateOut": "You are visible again", - "WraithInvisInCooldown": "Ability still on cooldown, vanish failed", - "WraithInvisStateCountdown": "Invisibility will expire in {0}s", - "WraithInvisCooldownRemain": "{0}s left in invisibility", - "WerewolfKillButtonText": "Maul", - "BKInProtect": "Currently immortal", - "BKProtectOut": "Shield expired", - "BKSkillTimeRemain": "You're immune for {0} seconds", - "BKSkillNotice": "Kill a player to enter immune status", - "BKOffsetKill": "Someone tried killing you", - "MedicKillerTryBrokenShieldTargetForMedic": "Someone tried killing the player you shielded!", - "MedicKillerTryBrokenShieldTargetForTarget": "Someone tried killing you!", - "FollowerBetPlayer": "You're now following your target", - "FollowerBetOnYou": "The Follower is now following you", - "CultistCharmedPlayer": "You successfully charmed a player", - "CharmedByCultist": "You have been charmed by the Cultist", - "CultistInvalidTarget": "Target cannot be charmed", - "KillBaitNotify": "You'll self-report in {0}s", - "InfectiousInvalidTarget": "Target cannot be infected", - "BittenByInfectious": "The Infectious infected you!", - "InfectiousBittenPlayer": "You successfully infected a player", - "GuessNotAllowed": "Sorry, your role does not have access to guessing.", - "GuessOnbound": "This player has the Onbound add-on, so your guess on them was canceled.", - "GuessSpecter": "You can't guess a Specter. That allows them to win!", - "PacifistOnGuard": "Ability used, {0} uses remain", - "PacifistSkillNotify": "Pacifist reset your kill cooldown", - "BeRecruitedByJackal": "The Jackal has recruited you", - "YinYangerAlreadyMarked": "{0} is already in a state of calm, endowed by a fellow YinYanger", - "CoronerTrackRecorded": "Track recorded", - "CoronerNoTrack": "Nothing to track", - "CoronerIsTrackingYou": "The Coroner is tracking you!", - "CoronerReportButtonText": "Track", - "MerchantAddonDelivered": "Add-on sold", - "MerchantAddonSell": "The Merchant sold you a new Add-on", - "MerchantAddonSellFail": "Could not sell an Add-on", - "BribedByMerchant": "The Merchant bribed you. You can't kill him", - "BribedByMerchant2": "You cannot guess the Merchant after he bribed you.", - "MerchantKillAttemptBribed": "An attempted killing was averted by bribery", - "TrapTrapsterBody": "Trap Trapster's body", - "TrapConsecutiveBodies": "Trap consecutive bodies", - "HauntedByEvilSpirit": "Haunted by an Evil Spirit", - "MonarchKnightCooldown": "Knight Cooldown", - "MonarchKnightMax": "Maximum Knights", - "HideAdditionalVotesForKnighted": "Hide additional vote for Knighted players", - "MonarchKnightedPlayer": "You successfully knighted a player!", - "KnightedByMonarch": "A Monarch has knighted you!", - "MonarchInvalidTarget": "Target cannot be knighted", - "GhostTransformTitle": "Your Role Has Transformed!", - "SpiritcallerNoticeTitle": "YOU TURNED INTO AN EVIL SPIRIT ", - "SpiritcallerNoticeMessage": "The Spiritcaller has killed you and turned you into an Evil Spirit. Your task now is to help the Spiritcaller to victory by using your spook button to hinder other players or to protect the Spiritcaller. Use /m for more information.", - "OverseerRevealCooldown": "Reveal Cooldown", - "OverseerRevealTime": "Reveal Time", - "OverseerVision": "Overseer Vision", - "MerchantMaxSell": "Max number of Add-ons to sell", - "MerchantMoneyPerSell": "Amount of money earned for selling an Add-on", - "MerchantMoneyRequiredToBribe": "Amount of money required to bribe a killer", - "MerchantNotifyBribery": "Inform Merchant when a killer gets bribed", - "MerchantTargetCrew": "Can sell to Crewmates", - "MerchantTargetImpostor": "Can sell to Impostors", - - "MerchantTargetNeutral": "Can sell to Neutrals", - "MerchantSellHelpful": "Can sell Helpful Add-ons", - "MerchantSellHarmful": "Can sell Harmful Add-ons", - "MerchantSellMixed": "Can sell Mixed Add-ons", - "MerchantSellExperimental": "Can sell experimental Add-ons", - "MerchantSellHarmfulToEvil": "Can sell Harmful Add-ons only to Evil", - "MerchantSellHelpfulToCrew": "Can sell Helpful Add-ons only to Crew", - "MerchantSellOnlyEnabledAddons": "Can sell only enabled Add-ons", - - "SpiritcallerSpiritMax": "Maximum number of Evil Spirits", - "SpiritcallerSpiritAbilityCooldown": "Evil Spirit ability cooldown", - "SpiritcallerFreezeTime": "Evil Spirit ability freeze time", - "SpiritcallerProtectTime": "Evil Spirit ability protect time", - "SpiritcallerCauseVision": "Evil Spirit ability caused vision", - "SpiritcallerCauseVisionTime": "Evil Spirit ability caused vision time", - "Message.SetToSeconds": "Set to [{0}] seconds.", - "Message.MessageWaitHelp": "Specify the first argument in seconds.", - "Message.TemplateNotFoundHost": "No templates.txt matching {0} were found", - "Message.TemplateNotFoundClient": "The Host doesn't have a template called {0}", - "Message.SyncButtonLeft": "There are {0} more emergency buttons left", - "Message.Executed": "{0} was executed", - "Message.HideGameSettings": "The host has hidden the game settings.", - "Message.NowOverrideText": "Please enter the root folder of the game.\\Language\\English.dat. Change this text in the dat file \nIf you don't need this feature or want to display regular /n messages. \nPlease disable [Enable only custom /n messages in the settings.]", - "Message.NoDescription": "No description", - "Message.KickedByDenyName": "{0} was kicked because its name matched {1}", - "Message.BannedByBanList": "{0} was banned because they were banned in the past.", - "Message.BannedByEACList": "{0} has been banned because he is in the EAC list of Banned people.", - "Message.DumpfileSaved": "The log file was successfully saved to the desktop, filename: {0}", - "Message.DumpcmdUsed": "{0} used /dump command.", - "Message.KickedByInvalidFriendCode": "{0} was kicked because their friend code is invalid.", - "Message.TempBannedByInvalidFriendCode": "{0} was temporarily banned because their friend code is invalid.", - "Message.AddedPlayerToBanList": "Added {0} to the ban list", - "Message.KickWhoSayStart": "{0} has been kicked by the system. \nThe lobby host doesn't want to see messages where the player asks to start", - "Message.WarnWhoSayStart": "{0} has been warned: {1} times \nThe lobby host doesn't want to see messages where the player asks to start", - "Message.KickStartAfterWarn": "{0} has received {1} warnings, he will be kicked. \nThe lobby host doesn't want to see messages where the player asks to start", - "Message.WarnWhoSayBanWord": "{0}, stop sending banned words!", - "Message.WarnWhoSayBanWordTimes": "{0} has been warned: {1} times \nif you continue you will be kicked", - "Message.KickWhoSayBanWordAfterWarn": "[{0}] received {1} warnings.\nHe was expelled for forbidden words", - "Message.KickedByEAC": "[{0}]Kicked by EAC, reason:{1}", - "Message.BannedByEAC": "[{0}]Banned by EAC, reason:{1}", - "Message.NoticeByEAC": "[{0}]Detected:{1}", - "Message.TempBannedByEAC": "[{0}]Temporary Banned by EAC, reason:{1}", - "Message.TempBannedForSpamQuitting": "{0} was temporary banned because of spamming quits", - "Message.KickedByWhiteList": "{0} kicked because their friendcode was not found in WhiteList.txt", - "Message.SetLevel": "Your game level is set to: {0}", - "Message.SetColor": "Your color is set to: {0}", - "Message.SetName": "Your name is set to: {0}", - "Message.AllowLevelRange": "The game level can be set in the range: 0-100", - "Message.AllowNameLength": "Nickname can be set length: 1-10", - "Message.OnlyCanUseInLobby": "ERROR\n\nSorry, this command can only be used in the lobby", - "Message.CanNotUseInLobby": "ERROR\n\nSorry, this command cannot be used in the lobby", - "Message.CanNotUseByHost": "ERROR\n\nSorry, Host can't use this command", - "Message.TryFixName": "An attempt was made to fix hidden message content due to roles", - "Message.CanNotFindRoleThePlayerEnter": "Could not find the role you searching\nUse command /r to show role list", - "Message.PlayerQuitForever": "{0} decided to leave voluntarily \nSorry for the bad gaming experience \nI really worked hard to make progress", - "Message.MadmateSelfVoteModeNotify": "Please note: The current Madness generation mode is [{0}]\n Voting for yourself means you want to be Madmate. If you meet the conditions to become Madmate and there are still spaces left, you will immediately become Madmate", - "Message.HostLeftGameInGame": "★Warning★ Host left the game, and the game wouldn't start normally next time. Please exit the lobby or wait until the new Host opens a lobby.", - "Message.HostLeftGameInLobby": "★Warning★ Host left the game, and the game wouldn't start normally next time. If the new Host has TOHE, you need to re-enter the lobby to play normally.", - "Message.HostLeftGameNewHostIsMod": "★Warning★ Original Host left the game and {0} become the new Host! \nThe room is still modded, start a game and end it immediately to reset the lobby!", - "Message.HostLeftGameNewHostIsNotMod": "★Warning★ Original Host left the game and {0} become the new Host. \nBut it's not modded. Please exit the lobby or wait until the new Host opens a lobby.", - "Message.LobbyShared": "The lobby has successfully been shared!", - "Message.LobbyShareFailed": "TOHE-Chan does not seem to be online (failed to share lobby)", - "Message.YTPlanDisabled": "ERROR\n\nPlease enable {0} in the Settings", - "Message.YTPlanSelected": "In the next game, your role will be {0}", - "Message.YTPlanSelectFailed": "You cannot be assigned as {0}.\nIt may be because you don't have this role enabled, or this role does not support being assigned.", - "Message.YTPlanCanNotFindRoleThePlayerEnter": "Could not find the role you searching\nUse command /r to show role list", - "Message.YTPlanNotice": "Note: The [YouTuber Plan] is enabled in this lobby, which means the Host can specify their role in the next game to make it easier to get content. If the Host abuses this feature, please exit the game or report it.\nCurrent Creator Credentials:", - "Message.OnlyCanBeUsedByHost": "ERROR\n\nThis command may only be used by the host.", - "Message.MaxPlayers": "Maximum players set to ", + "PoisonerTargetDead": "Target died", + "HexesLookLikeSpells": "Hexes appear as spells", + "HexButtonText": "Hex", + "BloodthirstAdded": "Your bloodthirst is now active!", + "WarlockNoTarget": "Manipulation failed due to no target", + "WarlockNoTargetYet": "You haven't marked a target.", + "WarlockTargetDead": "Manipulation failed due to target dead", + "WarlockControlKill": "Target died", + "OnCelebrityDead": "Warning: Celebrity death!", + "OnCyberDead": "Warning: Cyber died!", + "TeleportedInRndVentByDisperser": "Everyone was teleported to vents", + "TeleportedByTransporter": "Swapping places with: {0}", + "ErrorTeleport": "Teleport failed", + "EraseLimit": "Max Erases", + "EraserHideVote": "Hide Eraser Votes", + "EraserEraseMsgTitle": "ERASER", + "EraserEraseNotice": "You erased {0}.\nTheir role will be deactivated after the meeting.", + "EraserEraseBaseImpostorOrNeutralRoleNotice": "Oops, your target cannot be erased!", + "EraserEraseSelf": "Unfortunately, you can't erase yourself... Wait, why would you do that in the first place?!", + "EraserTryingGuessErasedPlayer": "You can't guess the role of the player you erased, except add-ons", + "LostRoleByEraser": "You lost your role because of the Eraser", + "KilledByScavenger": "The Scavenger killed you and thus teleported off-map", + "SnitchDoneTasks": "Call a meeting to find the impostors", + "SwooperCanVent": "Vent to turn invisible", + "SwooperInvisState": "You're invisible", + "SwooperInvisStateOut": "You're now visible", + "SwooperInvisInCooldown": "Swoop cooldown isn't up yet. Swooping failed", + "SwooperInvisStateCountdown": "Invisibility will expire after {0}s", + "SwooperInvisCooldownRemain": "Swoop Cooldown: {0}s", + "WraithCanVent": "Vent to turn invisible", + "WraithInvisState": "You are invisible", + "WraithInvisStateOut": "You are visible again", + "WraithInvisInCooldown": "Ability still on cooldown, vanish failed", + "WraithInvisStateCountdown": "Invisibility will expire in {0}s", + "WraithInvisCooldownRemain": "{0}s left in invisibility", + "WerewolfKillButtonText": "Maul", + "BKInProtect": "Currently immortal", + "BKProtectOut": "Shield expired", + "BKSkillTimeRemain": "You're immune for {0} seconds", + "BKSkillNotice": "Kill a player to enter immune status", + "BKOffsetKill": "Someone tried killing you", + "MedicKillerTryBrokenShieldTargetForMedic": "Someone tried killing the player you shielded!", + "MedicKillerTryBrokenShieldTargetForTarget": "Someone tried killing you!", + "FollowerBetPlayer": "You're now following your target", + "FollowerBetOnYou": "The Follower is now following you", + "CultistCharmedPlayer": "You successfully charmed a player", + "CharmedByCultist": "You have been charmed by the Cultist", + "CultistInvalidTarget": "Target cannot be charmed", + "KillBaitNotify": "You'll self-report in {0}s", + "InfectiousInvalidTarget": "Target cannot be infected", + "BittenByInfectious": "The Infectious infected you!", + "InfectiousBittenPlayer": "You successfully infected a player", + "GuessNotAllowed": "Sorry, your role does not have access to guessing.", + "GuessOnbound": "This player has the Onbound add-on, so your guess on them was canceled.", + "GuessSpecter": "You can't guess a Specter. That allows them to win!", + "PacifistOnGuard": "Ability used, {0} uses remain", + "PacifistSkillNotify": "Pacifist reset your kill cooldown", + "BeRecruitedByJackal": "The Jackal has recruited you", + "YinYangerAlreadyMarked": "{0} is already in a state of calm, endowed by a fellow YinYanger", + "CoronerTrackRecorded": "Track recorded", + "CoronerNoTrack": "Nothing to track", + "CoronerIsTrackingYou": "The Coroner is tracking you!", + "CoronerReportButtonText": "Track", + "MerchantAddonDelivered": "Add-on sold", + "MerchantAddonSell": "The Merchant sold you a new Add-on", + "MerchantAddonSellFail": "Could not sell an Add-on", + "BribedByMerchant": "The Merchant bribed you. You can't kill him", + "BribedByMerchant2": "You cannot guess the Merchant after he bribed you.", + "MerchantKillAttemptBribed": "An attempted killing was averted by bribery", + "TrapTrapsterBody": "Trap Trapster's body", + "TrapConsecutiveBodies": "Trap consecutive bodies", + "HauntedByEvilSpirit": "Haunted by an Evil Spirit", + "MonarchKnightCooldown": "Knight Cooldown", + "MonarchKnightMax": "Maximum Knights", + "HideAdditionalVotesForKnighted": "Hide additional vote for Knighted players", + "MonarchKnightedPlayer": "You successfully knighted a player!", + "KnightedByMonarch": "A Monarch has knighted you!", + "MonarchInvalidTarget": "Target cannot be knighted", + "GhostTransformTitle": "Your Role Has Transformed!", + "SpiritcallerNoticeTitle": "YOU TURNED INTO AN EVIL SPIRIT ", + "SpiritcallerNoticeMessage": "The Spiritcaller has killed you and turned you into an Evil Spirit. Your task now is to help the Spiritcaller to victory by using your spook button to hinder other players or to protect the Spiritcaller. Use /m for more information.", + "OverseerRevealCooldown": "Reveal Cooldown", + "OverseerRevealTime": "Reveal Time", + "OverseerVision": "Overseer Vision", + "MerchantMaxSell": "Max number of Add-ons to sell", + "MerchantMoneyPerSell": "Amount of money earned for selling an Add-on", + "MerchantMoneyRequiredToBribe": "Amount of money required to bribe a killer", + "MerchantNotifyBribery": "Inform Merchant when a killer gets bribed", + "MerchantTargetCrew": "Can sell to Crewmates", + "MerchantTargetImpostor": "Can sell to Impostors", + + "MerchantTargetNeutral": "Can sell to Neutrals", + "MerchantSellHelpful": "Can sell Helpful Add-ons", + "MerchantSellHarmful": "Can sell Harmful Add-ons", + "MerchantSellMixed": "Can sell Mixed Add-ons", + "MerchantSellExperimental": "Can sell experimental Add-ons", + "MerchantSellHarmfulToEvil": "Can sell Harmful Add-ons only to Evil", + "MerchantSellHelpfulToCrew": "Can sell Helpful Add-ons only to Crew", + "MerchantSellOnlyEnabledAddons": "Can sell only enabled Add-ons", + + "SpiritcallerSpiritMax": "Maximum number of Evil Spirits", + "SpiritcallerSpiritAbilityCooldown": "Evil Spirit ability cooldown", + "SpiritcallerFreezeTime": "Evil Spirit ability freeze time", + "SpiritcallerProtectTime": "Evil Spirit ability protect time", + "SpiritcallerCauseVision": "Evil Spirit ability caused vision", + "SpiritcallerCauseVisionTime": "Evil Spirit ability caused vision time", + "Message.SetToSeconds": "Set to [{0}] seconds.", + "Message.MessageWaitHelp": "Specify the first argument in seconds.", + "Message.TemplateNotFoundHost": "No templates.txt matching {0} were found", + "Message.TemplateNotFoundClient": "The Host doesn't have a template called {0}", + "Message.SyncButtonLeft": "There are {0} more emergency buttons left", + "Message.Executed": "{0} was executed", + "Message.HideGameSettings": "The host has hidden the game settings.", + "Message.NowOverrideText": "Please enter the root folder of the game.\\Language\\English.dat. Change this text in the dat file \nIf you don't need this feature or want to display regular /n messages. \nPlease disable [Enable only custom /n messages in the settings.]", + "Message.NoDescription": "No description", + "Message.KickedByDenyName": "{0} was kicked because its name matched {1}", + "Message.BannedByBanList": "{0} was banned because they were banned in the past.", + "Message.BannedByEACList": "{0} has been banned because he is in the EAC list of Banned people.", + "Message.DumpfileSaved": "The log file was successfully saved to the desktop, filename: {0}", + "Message.DumpcmdUsed": "{0} used /dump command.", + "Message.KickedByInvalidFriendCode": "{0} was kicked because their friend code is invalid.", + "Message.TempBannedByInvalidFriendCode": "{0} was temporarily banned because their friend code is invalid.", + "Message.AddedPlayerToBanList": "Added {0} to the ban list", + "Message.KickWhoSayStart": "{0} has been kicked by the system. \nThe lobby host doesn't want to see messages where the player asks to start", + "Message.WarnWhoSayStart": "{0} has been warned: {1} times \nThe lobby host doesn't want to see messages where the player asks to start", + "Message.KickStartAfterWarn": "{0} has received {1} warnings, he will be kicked. \nThe lobby host doesn't want to see messages where the player asks to start", + "Message.WarnWhoSayBanWord": "{0}, stop sending banned words!", + "Message.WarnWhoSayBanWordTimes": "{0} has been warned: {1} times \nif you continue you will be kicked", + "Message.KickWhoSayBanWordAfterWarn": "[{0}] received {1} warnings.\nHe was expelled for forbidden words", + "Message.KickedByEAC": "[{0}]Kicked by EAC, reason:{1}", + "Message.BannedByEAC": "[{0}]Banned by EAC, reason:{1}", + "Message.NoticeByEAC": "[{0}]Detected:{1}", + "Message.TempBannedByEAC": "[{0}]Temporary Banned by EAC, reason:{1}", + "Message.TempBannedForSpamQuitting": "{0} was temporary banned because of spamming quits", + "Message.KickedByWhiteList": "{0} kicked because their friendcode was not found in WhiteList.txt", + "Message.SetLevel": "Your game level is set to: {0}", + "Message.SetColor": "Your color is set to: {0}", + "Message.SetName": "Your name is set to: {0}", + "Message.AllowLevelRange": "The game level can be set in the range: 0-100", + "Message.AllowNameLength": "Nickname can be set length: 1-10", + "Message.OnlyCanUseInLobby": "ERROR\n\nSorry, this command can only be used in the lobby", + "Message.CanNotUseInLobby": "ERROR\n\nSorry, this command cannot be used in the lobby", + "Message.CanNotUseByHost": "ERROR\n\nSorry, Host can't use this command", + "Message.TryFixName": "An attempt was made to fix hidden message content due to roles", + "Message.CanNotFindRoleThePlayerEnter": "Could not find the role you searching\nUse command /r to show role list", + "Message.PlayerQuitForever": "{0} decided to leave voluntarily \nSorry for the bad gaming experience \nI really worked hard to make progress", + "Message.MadmateSelfVoteModeNotify": "Please note: The current Madness generation mode is [{0}]\n Voting for yourself means you want to be Madmate. If you meet the conditions to become Madmate and there are still spaces left, you will immediately become Madmate", + "Message.HostLeftGameInGame": "★Warning★ Host left the game, and the game wouldn't start normally next time. Please exit the lobby or wait until the new Host opens a lobby.", + "Message.HostLeftGameInLobby": "★Warning★ Host left the game, and the game wouldn't start normally next time. If the new Host has TOHE, you need to re-enter the lobby to play normally.", + "Message.HostLeftGameNewHostIsMod": "★Warning★ Original Host left the game and {0} become the new Host! \nThe room is still modded, start a game and end it immediately to reset the lobby!", + "Message.HostLeftGameNewHostIsNotMod": "★Warning★ Original Host left the game and {0} become the new Host. \nBut it's not modded. Please exit the lobby or wait until the new Host opens a lobby.", + "Message.LobbyShared": "The lobby has successfully been shared!", + "Message.LobbyShareFailed": "TOHE-Chan does not seem to be online (failed to share lobby)", + "Message.YTPlanDisabled": "ERROR\n\nPlease enable {0} in the Settings", + "Message.YTPlanSelected": "In the next game, your role will be {0}", + "Message.YTPlanSelectFailed": "You cannot be assigned as {0}.\nIt may be because you don't have this role enabled, or this role does not support being assigned.", + "Message.YTPlanCanNotFindRoleThePlayerEnter": "Could not find the role you searching\nUse command /r to show role list", + "Message.YTPlanNotice": "Note: The [YouTuber Plan] is enabled in this lobby, which means the Host can specify their role in the next game to make it easier to get content. If the Host abuses this feature, please exit the game or report it.\nCurrent Creator Credentials:", + "Message.OnlyCanBeUsedByHost": "ERROR\n\nThis command may only be used by the host.", + "Message.MaxPlayers": "Maximum players set to ", "Message.MaxPlayersFailByRegion": "Could not set max players: Vanilla regions support a maximum of 15 players.", - "Message.GhostRoleInfo": "Ghost Role Info\nHiya! A little about ghost roles...\n\nGhost roles drastically impact the game, so it's not recommended for smaller lobbies if you're unfamiliar. If not explicitly stated otherwise in the description, the Guard button is their ability button ;)\n\nSpawning:\nGhost-roles only spawn after death; the first x people from (team) to die get them.\n\nPS: If your previous role didn't have tasks(e.g., sheriff), your tasks as a ghost-role aren't needed for task-win", - "ApocalypseInfoTitle": "Neutral Apocalypse Info:", - "Message.ApocalypseInfo": "Every role of the <#ff174f>Apocalypse Team has their own objective to carry out in order to transform.\n<#2B0804>Transformed <#ff174f>Apocalypse members have a drastic change on the game and are immortal (except for being voted), but everyone will be notified that they have transformed.\n\nRoles: <#e5f6b4>Plaguebearer, <#A675A1>Soul Collector, <#bf9f7a>Baker, <#cc0044>Berserker\nTransformed: <#343136>Pestilence, <#644661>Death, <#83461c>Famine, <#2B0804>War\n\nApocalypse members can see eachother's roles and ability icons.\nLike Neutral Killers, Apocalypse members keep the game going as well, have fun!", - "Message.MeCommandInfo": "Hi [{0}] {1} !\n\nfriend-code Hash-Puid Type 
{2} {3} {4}

IsDev HasUp /color-Bypass
{5} {6} {7}

", - "Message.MeCommandTargetInfo": "Selected [{0}] Player {1} ,\n\nTheir friend code is {2}.\n\nTheir hash puid is {3}.\n\nTheir TOHE Discord role is {4}.\n\n", - "Message.MeCommandInvalidID": "The ID you entered seems incorrect. \nPlease use /id to get the player ID of online players", - "Message.MeCommandNoPermission": "You are not allowed to use /me command for others", - - "PollTitle": "〖 Poll 〗", - "PollResultTitle": "Poll Results", - "Poll.Result": "And... The winner was {0} with {1} votes!\n\nRunner ups:", - "Poll.Tied": "Uh oh, The vote was tied between {0}, all having {1} votes.", - "Poll.MissingPlayers": "You can't start a poll with yourself dummy ;3", - - "Poll.Begin": "You may vote using /pv {answer}, ps: a number also works.", - "Poll.TimeInfo": "The results will be final in 2 minutes", - "Poll.OnlyInLobby": "<#ab4f75>Sorry, this command may only be used in lobby", - - "Poll.Inactive": "There isn't any active poll currently.", - "Poll.AlreadyVoted": "You already cast your vote, so it won't be counted.", - - "Poll.VotingInfo": "Use /pv {answer} to vote, answer can be a character or a number.", - "Poll.YouVoted": "You have voted for {0}, which has now {1} votes.", - "PollUsage": "To create a poll type \n/poll {Question}? {Answer A} {Answer B} \n{Answer C (Optional)} {Answer D (Optional)} {Answer E (Optional)}\nIt is important you end the question with a ? \n\nUse /poll Replay to replay the latest poll", - "Replay": "Replay", - - "EnableGadientTags": "Enable Gradient Tags (can cause disconnect issues)", - "Warning.GradientTags": "Warning:\n\nHost has enabled gradient tags. This feature is not recommended to use because it can cause disconnect issues", - "WarningTitle": "Warning!", - "Warning.BrokenVentsInDleksSendInGame": "Warning! The vents on this map are broken", - "Warning.BrokenVentsInDleksMessage": "On the «dlekS ehT» map, the vents are broken, they cannot be fixed in host-only mods, this is a vanilla bug, so any roles using vent as an ability will not spawns on this map", - - "Warning.NoGameEndIsEnabled": "Warning: {0} is enabled!", - - "AntiBlackoutProtectionTitle": "Anti Blackout", - "Warning.AntiBlackoutProtectionMsg": "Warning:\n\rBlack screen protection has been activated, due to the low number of alive Impostors, Crewmates and Neutral Killers\nThe voting screen will show as a tied vote (only affects the visual, not the results voting)\nModded players will see voting screen normally", - "Warning.ShowAntiBlackExiledPlayer": "Last meeting triggered Black Screen Prevention!\nFollowing is the information of the player exiled in the last meeting.\n", - "DisableAntiBlackoutProtects": "Disable AntiBlackout Protects (Recommended for testing)", - - - - "Warning.InvalidRpc": "Kicked {0} because an invalid RPC was received.\nPlease check that no mods other than TOHE are installed.", - "Warning.NoModHost": "TOHE is not installed on the host", - "Warning.MismatchedVersion": "{0} has a different version of {1}", - "Warning.AutoExitAtMismatchedVersion": "The host has no or a different version of {0}\nYou will be kicked in {1}", - "Warning.CanNotUseBepInExConsole": "The use of the console is prohibited\nso your console has been off", - "Error.MeetingException": "Error: {0}\r\nPlease use SHIFT+M+ENTER to end the meeting", - "Error.InvalidRoleAssignment": "Error: Invalid role found for a player during role assignment({0})", - "Error.InvalidColor": "Error: Only default colors are available", - "Error.InvalidColorPreventStart": "Other players are not allowed to use other colors. Otherwise, it will result in a serious error", - "ErrorLevel1": "Bugs may occur.", - "ErrorLevel2": "This may be a bug.", - "ErrorLevel3": "This version shouldn't have been released.", - "TerminateCommand": "Abort Command", - "ERR-000-000-0": "No Error", - "ERR-000-900-0": "Test Error Lv.0", - "ERR-000-910-1": "Test Error Lv.1", - "ERR-000-920-2": "Test Error Lv.2", - "ERR-000-930-3": "Test Error Lv.3", - "ERR-000-804-1": "Sorry, TOHE temporarily not support the Vanilla HnS, so mod unloaded", - "ERR-001-000-3": "Main dictionary has duplicated keys.", - "ERR-002-000-1": "Unsupported Among Us version. Please update Among Us", - "DefaultSystemMessageTitle": "SYSTEM MESSAGE", - "MessageFromTheHost": "HOST MESSAGE", - "MessageFromEAC": "EAC", - "NotifyGameEnding": "This game is ending.\nIf you find yourself stuck in game,\npls just quit and rejoin the room.", - "DetectiveNoticeTitle": "INVESTIGATION", - "SleuthNoticeTitle": "SLEUTH", - "GuessKillTitle": "GUESSING INFO", - "CelebrityNewsTitle": "CELEBRITY", - "CyberNewsTitle": "CYBER", - "GodAliveTitle": "GOD ", - "WorkaholicAliveTitle": "WORKAHOLIC", - "BaitAliveTitle": "BAIT", - "MessageFromKPD": "KARPED1EM ", - "MessageFromSponsor": "SPONSOR MESSAGE ", - "MessageFromDev": "DEVELOPER MESSAGE ", - "FortuneTellerCheckMsgTitle": "FORTUNE TELLER", - "MimicMsgTitle": "MIMIC", - "MorticianCheckTitle": "CORPSE EXAMINATION", - "NemesisRevengeTitle": "NEMESIS", - "RetributionistRevengeTitle": "RETRIBUTIONIST", - "TabVanilla.GameSettings": "Game Settings", - "TabGroup.SystemSettings": "System Settings", - "TabGroup.ModSettings": "Mod Settings", - "TabGroup.ModifierSettings": "Game Modifiers", - "TabGroup.CrewmateRoles": "Crewmate Roles", - "TabGroup.NeutralRoles": "Neutral Roles", - "TabGroup.ImpostorRoles": "Impostor Roles", - "TabGroup.Addons": "Add-Ons", - "TabMenuDescription_General": "Here you can configure the functions that are in the mod", - "TabMenuDescription_Roles&AddOns": "Here you can add, remove and change the settings of all roles or add-ons in the mod", - "Experimental.Roles": "★ Experimental Roles (NOTICE: Use with caution, as these require testing)", - "ActiveRolesList": "Active Roles List", - "ForExample": "Example Use", - "ImpCanBeGuesser": "Impostors can become Guesser", - "CrewCanBeGuesser": "Crewmates can become Guesser", - "NeutralCanBeGuesser": "Neutrals can become Guesser", - "CrewCanBeMundane": "Crewmates can become Mundane", - "NeutralCanBeMundane": "Neutrals can become Mundane", - "GuessedAsMundane": "You're Mundane.\nYou can't guess until you finish all the tasks", - "ObliviousBaitImmune": "Immune to Bait", - "ImpCanBeInLove": "Impostors can be in love", - "CrewCanBeInLove": "Crewmates can be in love", - "NeutralCanBeInLove": "Neutrals can be in love", - "updateButton": "Update", - "updatePleaseWait": "Please Wait...", - "updateManually": "Update failed.\nPlease try again or Update Manually.", - "updateInProgress": "Updating...", - "deletingFiles": "Deleting update files...", - "updateRestart": "Update Finished!\nPlease restart the game.", - "CanNotJoinPublicRoomNoLatest": "You can't join public rooms without the latest version.\nPlease Update.", - "ModBrokenMessage": "The MOD file is damaged.\nPlease reinstall.", - "UnsupportedVersion": "Unsupported Among Us version.\nPlease Update Among Us", - "DisabledByProgram": "The program has disabled public rooms", - "EnterVentToWin": "Enter Vent to Win!!", - "EatenByPelican": "You're swallowed, waiting for the Pelican to die or a meeting", - "FireworkerPutPhase": "{0} Fireworker Left", - "FireworkerWaitPhase": "Wait for it...", - "FireworkerReadyFirePhase": "Fire!", - "EnterVentWinCountDown": "Enter vent within {0} seconds to win!", - "On": "ON", - "Off": "OFF", - "ColoredOn": "ON", - "ColoredOff": "OFF", - "CurrentActiveSettingsHelp": "Current Active Settings Help", - "WitchCurrentMode": "Current Mode", - "WitchModeKill": "Kill", - "WitchModeSpell": "Spell", - "HexMasterModeHex": "Hex", - "HexMasterModeKill": "Kill", - "PoisonerPoisonButtonText": "Poison", - "WitchModeDouble": "Double Click = Kill, Single Click = Spell", - "HexMasterModeDouble": "Double Click = Kill, Single Click = Hex", - "BountyCurrentTarget": "Current Target", - "Roles": "Roles", - "Settings": "Settings", - "Addons": "Add-Ons", - "LastResult": "★ Match Results", - "LastEndReason": "★ End Reason", - "KillLog": "Kill Log", - "Maximum": "Max", - "RoleRate": "ON", - "RoleOn": "ALWAYS", - "RoleOff": "OFF", - "Chance0": "0%", - "Chance5": "5%", - "Chance10": "10%", - "Chance15": "15%", - "Chance20": "20%", - "Chance25": "25%", - "Chance30": "30%", - "Chance35": "35%", - "Chance40": "40%", - "Chance45": "45%", - "Chance50": "50%", - "Chance55": "55%", - "Chance60": "60%", - "Chance65": "65%", - "Chance70": "70%", - "Chance75": "75%", - "Chance80": "80%", - "Chance85": "85%", - "Chance90": "90%", - "Chance95": "95%", - "Chance100": "100%", - "SearchNoResult": "No Results.", - "Preset": "Preset", - "Preset_1": "Preset 1", - "Preset_2": "Preset 2", - "Preset_3": "Preset 3", - "Preset_4": "Preset 4", - "Preset_5": "Preset 5", - "Standard": "Standard", - "HidenSeekTOHE": "Hide And Seek", - "GameMode": "Game Mode", - "PressTabToNextPage": "Press Tab or Number for Next Page...", - "RoleSummaryText": "Role Summary:", - "doOverride": "Override %role%'s Tasks", - "assignCommonTasks": "%role% has Common Tasks", - "roleLongTasksNum": "Amount of Long Tasks for %role%", - "roleShortTasksNum": "Amount of Short Tasks for %role%", - "Format.Players": "{0}", - "Format.Seconds": "{0}s", - "Format.Percent": "{0}%", - "Format.Times": "{0}", - "Format.Multiplier": "{0}x", - "Format.Votes": "{0}", - "Format.Pieces": "{0}", - "Format.Health": "{0}", - "Format.Level": "{0}", - "KillButtonText": "Kill", - "ReportButtonText": "Report", - "VentButtonText": "Vent", - "SabotageButtonText": "Sabotage", - "SniperSnipeButtonText": "Snipe", - "FireworkerExplosionButtonText": "Detonate", - "FireworkerInstallAtionButtonText": "Install", - "MercenarySuicideButtonText": "Suicide Timer", - "WarlockCurseButtonText": "Curse", - "NinjaShapeshiftText": "Kill", - "NinjaMarkButtonText": "Mark", - "WitchSpellButtonText": "Spell", - "VampireBiteButtonText": "Bite", - "MinerTeleButtonText": "Warp", - "ArsonistDouseButtonText": "Douse", - "PuppeteerOperateButtonText": "Manipulate", - "WarlockShapeshiftButtonText": "Spell", - "BountyHunterChangeButtonText": "Swap", - "EvilTrackerChangeButtonText": "Track", + "Message.GhostRoleInfo": "Ghost Role Info\nHiya! A little about ghost roles...\n\nGhost roles drastically impact the game, so it's not recommended for smaller lobbies if you're unfamiliar. If not explicitly stated otherwise in the description, the Guard button is their ability button ;)\n\nSpawning:\nGhost-roles only spawn after death; the first x people from (team) to die get them.\n\nPS: If your previous role didn't have tasks(e.g., sheriff), your tasks as a ghost-role aren't needed for task-win", + "ApocalypseInfoTitle": "Neutral Apocalypse Info:", + "Message.ApocalypseInfo": "Every role of the <#ff174f>Apocalypse Team has their own objective to carry out in order to transform.\n<#2B0804>Transformed <#ff174f>Apocalypse members have a drastic change on the game and are immortal (except for being voted), but everyone will be notified that they have transformed.\n\nRoles: <#e5f6b4>Plaguebearer, <#A675A1>Soul Collector, <#bf9f7a>Baker, <#cc0044>Berserker\nTransformed: <#343136>Pestilence, <#644661>Death, <#83461c>Famine, <#2B0804>War\n\nApocalypse members can see eachother's roles and ability icons.\nLike Neutral Killers, Apocalypse members keep the game going as well, have fun!", + "Message.MeCommandInfo": "Hi [{0}] {1} !\n\nfriend-code Hash-Puid Type 
{2} {3} {4}

IsDev HasUp /color-Bypass
{5} {6} {7}

", + "Message.MeCommandTargetInfo": "Selected [{0}] Player {1} ,\n\nTheir friend code is {2}.\n\nTheir hash puid is {3}.\n\nTheir TOHE Discord role is {4}.\n\n", + "Message.MeCommandInvalidID": "The ID you entered seems incorrect. \nPlease use /id to get the player ID of online players", + "Message.MeCommandNoPermission": "You are not allowed to use /me command for others", + + "PollTitle": "〖 Poll 〗", + "PollResultTitle": "Poll Results", + "Poll.Result": "And... The winner was {0} with {1} votes!\n\nRunner ups:", + "Poll.Tied": "Uh oh, The vote was tied between {0}, all having {1} votes.", + "Poll.MissingPlayers": "You can't start a poll with yourself dummy ;3", + + "Poll.Begin": "You may vote using /pv {answer}, ps: a number also works.", + "Poll.TimeInfo": "The results will be final in 2 minutes", + "Poll.OnlyInLobby": "<#ab4f75>Sorry, this command may only be used in lobby", + + "Poll.Inactive": "There isn't any active poll currently.", + "Poll.AlreadyVoted": "You already cast your vote, so it won't be counted.", + + "Poll.VotingInfo": "Use /pv {answer} to vote, answer can be a character or a number.", + "Poll.YouVoted": "You have voted for {0}, which has now {1} votes.", + "PollUsage": "To create a poll type \n/poll {Question}? {Answer A} {Answer B} \n{Answer C (Optional)} {Answer D (Optional)} {Answer E (Optional)}\nIt is important you end the question with a ? \n\nUse /poll Replay to replay the latest poll", + "Replay": "Replay", + + "EnableGadientTags": "Enable Gradient Tags (can cause disconnect issues)", + "Warning.GradientTags": "Warning:\n\nHost has enabled gradient tags. This feature is not recommended to use because it can cause disconnect issues", + "WarningTitle": "Warning!", + "Warning.BrokenVentsInDleksSendInGame": "Warning! The vents on this map are broken", + "Warning.BrokenVentsInDleksMessage": "On the «dlekS ehT» map, the vents are broken, they cannot be fixed in host-only mods, this is a vanilla bug, so any roles using vent as an ability will not spawns on this map", + + "Warning.NoGameEndIsEnabled": "Warning: {0} is enabled!", + + "AntiBlackoutProtectionTitle": "Anti Blackout", + "Warning.AntiBlackoutProtectionMsg": "Warning:\n\rBlack screen protection has been activated, due to the low number of alive Impostors, Crewmates and Neutral Killers\nThe voting screen will show as a tied vote (only affects the visual, not the results voting)\nModded players will see voting screen normally", + "Warning.ShowAntiBlackExiledPlayer": "Last meeting triggered Black Screen Prevention!\nFollowing is the information of the player exiled in the last meeting.\n", + "DisableAntiBlackoutProtects": "Disable AntiBlackout Protects (Recommended for testing)", + + + + "Warning.InvalidRpc": "Kicked {0} because an invalid RPC was received.\nPlease check that no mods other than TOHE are installed.", + "Warning.NoModHost": "TOHE is not installed on the host", + "Warning.MismatchedVersion": "{0} has a different version of {1}", + "Warning.AutoExitAtMismatchedVersion": "The host has no or a different version of {0}\nYou will be kicked in {1}", + "Warning.CanNotUseBepInExConsole": "The use of the console is prohibited\nso your console has been off", + "Error.MeetingException": "Error: {0}\r\nPlease use SHIFT+M+ENTER to end the meeting", + "Error.InvalidRoleAssignment": "Error: Invalid role found for a player during role assignment({0})", + "Error.InvalidColor": "Error: Only default colors are available", + "Error.InvalidColorPreventStart": "Other players are not allowed to use other colors. Otherwise, it will result in a serious error", + "ErrorLevel1": "Bugs may occur.", + "ErrorLevel2": "This may be a bug.", + "ErrorLevel3": "This version shouldn't have been released.", + "TerminateCommand": "Abort Command", + "ERR-000-000-0": "No Error", + "ERR-000-900-0": "Test Error Lv.0", + "ERR-000-910-1": "Test Error Lv.1", + "ERR-000-920-2": "Test Error Lv.2", + "ERR-000-930-3": "Test Error Lv.3", + "ERR-000-804-1": "Sorry, TOHE temporarily not support the Vanilla HnS, so mod unloaded", + "ERR-001-000-3": "Main dictionary has duplicated keys.", + "ERR-002-000-1": "Unsupported Among Us version. Please update Among Us", + "DefaultSystemMessageTitle": "SYSTEM MESSAGE", + "MessageFromTheHost": "HOST MESSAGE", + "MessageFromEAC": "EAC", + "NotifyGameEnding": "This game is ending.\nIf you find yourself stuck in game,\npls just quit and rejoin the room.", + "DetectiveNoticeTitle": "INVESTIGATION", + "SleuthNoticeTitle": "SLEUTH", + "GuessKillTitle": "GUESSING INFO", + "CelebrityNewsTitle": "CELEBRITY", + "CyberNewsTitle": "CYBER", + "GodAliveTitle": "GOD ", + "WorkaholicAliveTitle": "WORKAHOLIC", + "BaitAliveTitle": "BAIT", + "MessageFromKPD": "KARPED1EM ", + "MessageFromSponsor": "SPONSOR MESSAGE ", + "MessageFromDev": "DEVELOPER MESSAGE ", + "FortuneTellerCheckMsgTitle": "FORTUNE TELLER", + "MimicMsgTitle": "MIMIC", + "MorticianCheckTitle": "CORPSE EXAMINATION", + "NemesisRevengeTitle": "NEMESIS", + "RetributionistRevengeTitle": "RETRIBUTIONIST", + "TabVanilla.GameSettings": "Game Settings", + "TabGroup.SystemSettings": "System Settings", + "TabGroup.ModSettings": "Mod Settings", + "TabGroup.ModifierSettings": "Game Modifiers", + "TabGroup.CrewmateRoles": "Crewmate Roles", + "TabGroup.NeutralRoles": "Neutral Roles", + "TabGroup.ImpostorRoles": "Impostor Roles", + "TabGroup.Addons": "Add-Ons", + "TabMenuDescription_General": "Here you can configure the functions that are in the mod", + "TabMenuDescription_Roles&AddOns": "Here you can add, remove and change the settings of all roles or add-ons in the mod", + "Experimental.Roles": "★ Experimental Roles (NOTICE: Use with caution, as these require testing)", + "ActiveRolesList": "Active Roles List", + "ForExample": "Example Use", + "ImpCanBeGuesser": "Impostors can become Guesser", + "CrewCanBeGuesser": "Crewmates can become Guesser", + "NeutralCanBeGuesser": "Neutrals can become Guesser", + "CrewCanBeMundane": "Crewmates can become Mundane", + "NeutralCanBeMundane": "Neutrals can become Mundane", + "GuessedAsMundane": "You're Mundane.\nYou can't guess until you finish all the tasks", + "ObliviousBaitImmune": "Immune to Bait", + "ImpCanBeInLove": "Impostors can be in love", + "CrewCanBeInLove": "Crewmates can be in love", + "NeutralCanBeInLove": "Neutrals can be in love", + "updateButton": "Update", + "updatePleaseWait": "Please Wait...", + "updateManually": "Update failed.\nPlease try again or Update Manually.", + "updateInProgress": "Updating...", + "deletingFiles": "Deleting update files...", + "updateRestart": "Update Finished!\nPlease restart the game.", + "CanNotJoinPublicRoomNoLatest": "You can't join public rooms without the latest version.\nPlease Update.", + "ModBrokenMessage": "The MOD file is damaged.\nPlease reinstall.", + "UnsupportedVersion": "Unsupported Among Us version.\nPlease Update Among Us", + "DisabledByProgram": "The program has disabled public rooms", + "EnterVentToWin": "Enter Vent to Win!!", + "EatenByPelican": "You're swallowed, waiting for the Pelican to die or a meeting", + "FireworkerPutPhase": "{0} Fireworker Left", + "FireworkerWaitPhase": "Wait for it...", + "FireworkerReadyFirePhase": "Fire!", + "EnterVentWinCountDown": "Enter vent within {0} seconds to win!", + "On": "ON", + "Off": "OFF", + "ColoredOn": "ON", + "ColoredOff": "OFF", + "CurrentActiveSettingsHelp": "Current Active Settings Help", + "WitchCurrentMode": "Current Mode", + "WitchModeKill": "Kill", + "WitchModeSpell": "Spell", + "HexMasterModeHex": "Hex", + "HexMasterModeKill": "Kill", + "PoisonerPoisonButtonText": "Poison", + "WitchModeDouble": "Double Click = Kill, Single Click = Spell", + "HexMasterModeDouble": "Double Click = Kill, Single Click = Hex", + "BountyCurrentTarget": "Current Target", + "Roles": "Roles", + "Settings": "Settings", + "Addons": "Add-Ons", + "LastResult": "★ Match Results", + "LastEndReason": "★ End Reason", + "KillLog": "Kill Log", + "Maximum": "Max", + "RoleRate": "ON", + "RoleOn": "ALWAYS", + "RoleOff": "OFF", + "Chance0": "0%", + "Chance5": "5%", + "Chance10": "10%", + "Chance15": "15%", + "Chance20": "20%", + "Chance25": "25%", + "Chance30": "30%", + "Chance35": "35%", + "Chance40": "40%", + "Chance45": "45%", + "Chance50": "50%", + "Chance55": "55%", + "Chance60": "60%", + "Chance65": "65%", + "Chance70": "70%", + "Chance75": "75%", + "Chance80": "80%", + "Chance85": "85%", + "Chance90": "90%", + "Chance95": "95%", + "Chance100": "100%", + "SearchNoResult": "No Results.", + "Preset": "Preset", + "Preset_1": "Preset 1", + "Preset_2": "Preset 2", + "Preset_3": "Preset 3", + "Preset_4": "Preset 4", + "Preset_5": "Preset 5", + "Standard": "Standard", + "HidenSeekTOHE": "Hide And Seek", + "GameMode": "Game Mode", + "PressTabToNextPage": "Press Tab or Number for Next Page...", + "RoleSummaryText": "Role Summary:", + "doOverride": "Override %role%'s Tasks", + "assignCommonTasks": "%role% has Common Tasks", + "roleLongTasksNum": "Amount of Long Tasks for %role%", + "roleShortTasksNum": "Amount of Short Tasks for %role%", + "Format.Players": "{0}", + "Format.Seconds": "{0}s", + "Format.Percent": "{0}%", + "Format.Times": "{0}", + "Format.Multiplier": "{0}x", + "Format.Votes": "{0}", + "Format.Pieces": "{0}", + "Format.Health": "{0}", + "Format.Level": "{0}", + "KillButtonText": "Kill", + "ReportButtonText": "Report", + "VentButtonText": "Vent", + "SabotageButtonText": "Sabotage", + "SniperSnipeButtonText": "Snipe", + "FireworkerExplosionButtonText": "Detonate", + "FireworkerInstallAtionButtonText": "Install", + "MercenarySuicideButtonText": "Suicide Timer", + "WarlockCurseButtonText": "Curse", + "NinjaShapeshiftText": "Kill", + "NinjaMarkButtonText": "Mark", + "WitchSpellButtonText": "Spell", + "VampireBiteButtonText": "Bite", + "MinerTeleButtonText": "Warp", + "ArsonistDouseButtonText": "Douse", + "PuppeteerOperateButtonText": "Manipulate", + "WarlockShapeshiftButtonText": "Spell", + "BountyHunterChangeButtonText": "Swap", + "EvilTrackerChangeButtonText": "Track", "RiftMakerButtonText": "Create Rift", "AbyssbringerButtonText": "Black Hole", "PitfallButtonText": "Set Trap", - "InnocentButtonText": "Frame", - "PelicanButtonText": "Eat", - "DeceiverButtonText": "Cheat", - "PursuerButtonText": "Trick", - "GangsterButtonText": "Recruit", - "RevolutionistDrawButtonText": "Win over", - "HaterButtonText": "Hatred", - "MedicalerButtonText": "Protect", - "DemonButtonText": "Attack", - "SoulCatcherButtonText": "Teleport", - "LightningButtonText": "Evaporate", - "ProvocateurButtonText": "Greet", - "ButcherButtonText": "Dismember", - "BomberShapeshiftText": "Explode", - "QuickShooterShapeshiftText": "Keep", - "CamouflagerShapeshiftTextBeforeDisguise": "Disguise", - "CamouflagerShapeshiftTextAfterDisguise": "Duration", - "AnonymousShapeshiftText": "Hack", - "DefaultShapeshiftText": "Shift", - "CleanerReportButtonText": "Clean", - "SwooperVentButtonText": "Swoop", - "SwooperRevertVentButtonText": "Expose", - "WraithVentButtonText": "Vanish", - "WraithRevertVentButtonText": "Expose", - "VectorVentButtonText": "Hop", - "VeteranVentButtonText": "Alert", - "GrenadierVentButtonText": "Flash", - "MayorVentButtonText": "Button", - "SheriffKillButtonText": "Shoot", - "UndertakerButtonText": "Mark", - "ArsonistVentButtonText": "Ignite", - "RevolutionistVentButtonText": "Revolution", - "FollowerKillButtonText": "Follow", - "PacifistVentButtonText": "Reset", - "CultistKillButtonText": "Charm", - "InfectiousKillButtonText": "Infect", - "MonarchKillButtonText": "Knight", - "OverseerKillButtonText": "Reveal", - "DisabledBySettings": "Disabled by Settings", - "Disabled": "Disabled", - "FailToTrack": "Failed To Track", - "KillCount": "Kills: {0}", - "CantUse.lastroles": "Unable to use /lastroles during a game.", - "CantUse.killlog": "Unable to use /killlog during a game.", - "CantUse.lastresult": "Unable to use /lastresult during a game.", - "IllegalColor": "Please enter the correct color", - "DisableUseCommand": "The Host's settings do not allow this command to be used.", - "SureUse.quit": "We will kick you and block you from entering this lobby again. This setting is irreversible. If you really want it, please send the command /qt {0}", - "PlayerIdList": "List of player IDs: ", - "CancelStartCountDown": "The starting countdown was canceled", - "RestTOHESetting": "TOHE settings have been restored to default", - "FPSSetTo": "FPS Set To: {0}", - "HostKillSelfByCommand": "The lobby Host decided to commit suicide", - "SyncCustomSettingsRPC": "Synchronized RPC", - "Mode": "Mode", - "Target": "Target", - "PlayerInfo": "Player Info", - "NoInfoExists": "No Info Exists", - "PlayerLeftByAU-Anticheat": "{0} was banned by the Innersloth anti-cheat.", - "PlayerLeftByError": "Game will auto-end to prevent black screens.", - "MsgKickOtherPlatformPlayer": "{0} was kicked due to playing on {1}", - "KickBecauseLowLevel": "{0} was kicked because their level was too low", - "TempBannedBecauseLowLevel": "{0} was temporarily banned because their level was too low", - "KickBecauseDiffrentVersionOrMod": "{0} was kicked because they had a different version of the mod", - - "FFADisplayScore": "Ranking: {0} Score: {1}", - "FFATimeRemain": "Time Remaining: {0} second(s)", - - "GameOver": "Game Over", - "TOHEOptions": "TOHE Options", - "Cancel": "Cancel", - "Back": "Back", - "Yes": "Yes", - "No": "No", - - "AntiBlackOutLoggerSendInGame": "Because of an unknown error, the game will end to prevent a black screen.", - "AntiBlackOutNotifyInLobby": "An error occurred to prevent a black screen. Do a «/dump» and send the logs to the discord server TOHE in «bug-reports» and we will try to fix it.", - - "EndWhenPlayerBug": "End the game when a modded player gets a critical error (While loading)", - "AntiBlackOutRequestHostToForceEnd": "You were the reason for the black screen. The game will end", - "AntiBlackOutHostRejectForceEnd": "You were the reason for the black screen, and the host is not going to end the game\nYou will be disconnected soon", - - "RpcAntiBlackOutNotifyInLobby": "Because of {0}, an unknown error occurred. To prevent a black screen, turn off [{1}] in settings.", - "RpcAntiBlackOutEndGame": "Because of {0}, an unknown error occurred, the game will end to prevent a black screen.", - "RpcAntiBlackOutIgnored": "Because of {0}, an unknown error occurred, but the game will continue without that player due to host settings.", - "RpcAntiBlackOutKicked": "{0} was kicked due to having a blackout error on its side.", - - "NextPage": "Next Page", - "PreviousPage": "Previous Page", - "EAC.CheatDetected.EAC": "Cheating usage detected (Using AUM)", - "PressF1ShowMainRoleDes": "Press F1: Show Role Description", - "PressF2ShowAddRoleDes": "Press F2: Show Add-on Description", - "PressF3ShowRoleSettings": "Press F3: Show Role Settings", - "PressF4ShowAddOnsSettings": "Press F4: Show Add-ons Settings", - "FakeTask": "Fake Tasks:", - "PVP.ATK": "Attack", - "PVP.DF": "Defend", - "PVP.RCO": "Recover", - "SettingsAreLoading": "Loading\nsettings...", - "EAC.CheatDetected.HighLevel": "Warning: EAC detected High Level of cheats.", - "EAC.CheatDetected.LowLevel": "Warning: EAC detected Low Level of cheats. One of the players is hacking.", - "ExiledJester": "You're all fools!\n{0} the {1} laughing out loud tricked you into ejecting them.\nGG!", - "JesterMeetingLoose": "\r\nBut it cannot win until meeting number {0}", - "ExiledExeTarget": "{0} was the {1}.\nBut they were also the Executioner's target!\nGG!", - "ExiledInnocentTargetAddBelow": "\nLooking back at the Innocent counts the money in their hands", - "ExiledInnocentTargetInOneLine": "{0} was the {1}.\nBut looking back, there's the Innocent counting the money in their hands....\nGG!", - "ExiledDeath": "{0} was {1}!\nThe Crew has been saved from Armageddon!", - "ExiledNotDeath": "{0} was the {1}.\nBut they were not Death...\nDeath has claimed the souls of the Crew!", - "IsGood": "{0} was a good guy", - "BelongTo": "{0} belongs to {1}", - "PlayerIsRole": "{0} was The {1}", - "PlayerExiled": "{0} was ejected", - "NoImpRemain": "0 Impostors remain", - "OneImpRemain": "1 Impostor remains", - "TwoImpRemain": "2 Impostors remain", - "ThreeImpRemain": "3 Impostors remain", - "ImpRemain": "{0} Impostors remaining", - "NeutralRemain": "\n{0} Neutral Killers remain", - "OneNeutralRemain": "\n{0} Neutral Killer remains", - "ApocRemain": "\n{0} Neutral Apocalypse remains", - "GameOverReason.HumansByVote": "All Impostors and Neutral Killers were ejected or killed", - "GameOverReason.HumansByTask": "The Crewmates completed all tasks", - "GameOverReason.HumansDisconnect": "Crewmates disconnected", - "GameOverReason.ImpostorByVote": "The Crewmates were ejected", - "GameOverReason.ImpostorByKill": "The Impostors killed everyone", - "GameOverReason.ImpostorBySabotage": "Crewmates failed to fix a critical sabotage", - "GameOverReason.ImpostorDisconnect": "Impostors disconnected", - "FortuneTellerCheck.TaskDone": "[{0}]Role -[{1}]", - "DevAndSpnTitle": "TOHE family", - "FortuneTellerCheck.Null": "{0} is a role that is not listed.\nThis message should not appear normally.", - "FortuneTellerCheck.Result": "{0} is either one of the following roles:\n{1}", - "SunnyboyChance": "Sunnyboy Chance", - "BardChance": "Bard Chance", - "SkeldChance": "Chance that the map is The Skeld", - "MiraChance": "Chance that the map is MIRA HQ", - "PolusChance": "Chance that the map is Polus", - "DleksChance": "Chance that the map is dlekS ehT", - "AirshipChance": "Chance that the map is Airship", - "FungleChance": "Chance that the map is The Fungle", - "UseMoreRandomMapSelection": "Use a more random map selection", - "CamouflageMode.Default": "Default", - "CamouflageMode.Host": "Host", - "CamouflageMode.Random": "Random", - "CamouflageMode.OnlyRandomColor": "Only Random Color", - "CamouflageMode.Karpe": "KARPED1EM", - "CamouflageMode.Lauryn": "Lauryn", - "CamouflageMode.Moe": "Moe", - "CamouflageMode.Pyro": "Pyro", - "CamouflageMode.ryuk": "ryuk", - "CamouflageMode.Gurge44": "Gurge44", - "CamouflageMode.TommyXL": "TommyXL", - "CamouflageMode.Sarha": "Sarha", - "DeathCmd.HeyPlayer": "Hey ", - "DeathCmd.YouAreRole": ", looks like you're the ", - "DeathCmd.NotDead": "You haven't died yet, this can only be used after you die\n\nCheck back again after you've been brutally murdered", - "DeathCmd.KillerName": "You were killed by ", - "DeathCmd.KillerRole": "Their role is ", - "DeathCmd.DeathReason": "Your cause of death was ", - "DeathCmd.YourName": "You are ", - "DeathCmd.YourRole": "Your role is ", - "DeathCmd.Ejected": "You were ejected during a meeting", - "DeathCmd.Misfired": "You misfired.", - "DeathCmd.Shrouded": "You were shrouded by a Shroud and didn't make a kill, so you suicided.", - "DeathCmd.Lovers": "Your lover had died.", - - "RpsCommandInfo": "This Command can only be used when in the lobby or after you die.\n\ntype /rps X to play Rock Paper Scissors with the system. X can be 0 (rock), 1 (paper) or 2 (scissors). \n\nExample :- /rps 0", - "RpsDraw": "I choose {0}\n\nWow, what an intense battle of wits we just had! It's almost as if we're equally matched in this game of sheer luck and randomness.", - "RpsLose": "I choose {0}\n\nWell, well, well, looks like I've managed to outsmart a human again in this highly complex game of Rock, Paper, Scissors. I guess my unbeatable powers strike again! ", - "RpsWin": "I choose {0}\n\nOh, congratulations! You must have a crystal ball hidden behind that screen to beat me at Rock, Paper, Scissors. Or maybe I have the world's worst luck algorithm.", - - "CoinFlipCommandInfo": "This Command can only be used when in the lobby or after you die.", - "CoinFlipResult": "Drumroll, please... After an intense battle of gravity and randomness, the coin has decided to grace us with its presence! And the majestic winner is... (wait for it) ... the one and only... {0}! Who could have seen that coming?! Clearly, a momentous occasion in the history of coin flips.", - - "GNoCommandInfo": "This Command can only be used when in the lobby or after you die.\n\ntype /gno X to play guess a number. X can be a number between 0 and 99 (both included). \n\nYou get maximum of 7 tries to guess the number.\n\n Example:- /gno 10", - "GNoLost": "Oh, you were so close! Just one more guess: you might have deciphered the Da Vinci code! By the way, the secret number was... {0}! But hey, you were only off by a few billion possibilities. Better luck next time, Sherlock! ", - "GNoLow": "Oh, you're really nailing this! It's so low. I almost need a shovel to dig it up!\nYou have {0} guesses left!", - "GNoHigh": "Oh, absolutely! You're getting warmer. In fact, it's so high that I need a telescope to see it from here! \nYou have {0} guesses left!", - "GNoWon": "Oh, how did you ever figure that out? It's almost like you're a mind reader! Congratulations, you're a genius! You found the secret number with {0} guesses left!", - - "RandCommandInfo": "This Command can only be used when in the lobby or after you die.\n\ntype /rand X Y to get a number between X and Y, inclusive. \nX and Y can be any number between 0 and 2147483647, including both numbers.\nX must be less than Y.\n\nExample:- /rand 0 99", - "RandResult": "Congratulations, your random number is {0}! Wasn't that fun?", - - "8BallTitle": "The Magic 8 Ball Reveals...", - "8BallYes": "Yes", - "8BallNo": "No", - "8BallMaybe": "Maybe", - "8BallTryAgainLater": "Ask again later", - "8BallCertain": "It is certain", - "8BallNotLikely": "Outlook not so good", - "8BallLikely": "Outlook good", - "8BallDontCount": "Don't count on it", - "8BallStop": "Stop using an 8Ball in an Among Us mod", - "8BallPossibly": "Possibly", - "8BallProbably": "Probably", - "8BallProbablyNot": "Probably not", - "8BallBetterNotTell": "Better not tell you now", - "8BallCantPredict": "Cannot predict now", - "8BallWithoutDoubt": "Without a doubt", - "8BallWithDoubt": "Very doubtful", - - "ChanceToMiss": "Chance to miss a kill", - - "SoulCollectorPointsToWin": "Required number of souls", - "SoulCollectorTarget": "You have predicted the death of {0}", - "SoulCollectorTitle": "SOUL COLLECTOR", - "SoulCollector_CollectOwnSoulOpt": "Can collect their own soul", - "SoulCollectorSelfVote": "Host settings do not allow you to collect your own soul", - "SoulCollectorToDeath": "You have become Death!!!", - "SoulCollectorTransform": "Now Soul Collector has become Death, Destroyer of Worlds and Horseman of the Apocalypse!

Find them and vote them out before they bring forth Armageddon!", - "GetPassiveSouls": "Gain a passive soul every round", - "PassiveSoulGained": "You have gained a passive soul from the underworld.", - "SoulCollectorTargetUsed": "You've already targeted someone this round!", - "SoulCollectorSoulGained": "Soul gained", - "SoulCollectorCanVent": "Soul Collector can Vent", - "DeathMeetingTimeIncrease": "Increased Meeting time when Death exists", - "SoulCollectorMeetingDeath": "Your target has died during the meeting. You have gained a soul.", - "SoulCollectorKillButtonText": "Predict", - "SoulCollectorHasImpostorVision": "Soul Collector has Impostor vision", - - "ApocalypseIsNigh": "[ The Apocalypse Is Nigh! ]", + "InnocentButtonText": "Frame", + "PelicanButtonText": "Eat", + "DeceiverButtonText": "Cheat", + "PursuerButtonText": "Trick", + "GangsterButtonText": "Recruit", + "RevolutionistDrawButtonText": "Win over", + "HaterButtonText": "Hatred", + "MedicalerButtonText": "Protect", + "DemonButtonText": "Attack", + "SoulCatcherButtonText": "Teleport", + "LightningButtonText": "Evaporate", + "ProvocateurButtonText": "Greet", + "ButcherButtonText": "Dismember", + "BomberShapeshiftText": "Explode", + "QuickShooterShapeshiftText": "Keep", + "CamouflagerShapeshiftTextBeforeDisguise": "Disguise", + "CamouflagerShapeshiftTextAfterDisguise": "Duration", + "AnonymousShapeshiftText": "Hack", + "DefaultShapeshiftText": "Shift", + "CleanerReportButtonText": "Clean", + "SwooperVentButtonText": "Swoop", + "SwooperRevertVentButtonText": "Expose", + "WraithVentButtonText": "Vanish", + "WraithRevertVentButtonText": "Expose", + "VectorVentButtonText": "Hop", + "VeteranVentButtonText": "Alert", + "GrenadierVentButtonText": "Flash", + "MayorVentButtonText": "Button", + "SheriffKillButtonText": "Shoot", + "UndertakerButtonText": "Mark", + "ArsonistVentButtonText": "Ignite", + "RevolutionistVentButtonText": "Revolution", + "FollowerKillButtonText": "Follow", + "PacifistVentButtonText": "Reset", + "CultistKillButtonText": "Charm", + "InfectiousKillButtonText": "Infect", + "MonarchKillButtonText": "Knight", + "OverseerKillButtonText": "Reveal", + "DisabledBySettings": "Disabled by Settings", + "Disabled": "Disabled", + "FailToTrack": "Failed To Track", + "KillCount": "Kills: {0}", + "CantUse.lastroles": "Unable to use /lastroles during a game.", + "CantUse.killlog": "Unable to use /killlog during a game.", + "CantUse.lastresult": "Unable to use /lastresult during a game.", + "IllegalColor": "Please enter the correct color", + "DisableUseCommand": "The Host's settings do not allow this command to be used.", + "SureUse.quit": "We will kick you and block you from entering this lobby again. This setting is irreversible. If you really want it, please send the command /qt {0}", + "PlayerIdList": "List of player IDs: ", + "CancelStartCountDown": "The starting countdown was canceled", + "RestTOHESetting": "TOHE settings have been restored to default", + "FPSSetTo": "FPS Set To: {0}", + "HostKillSelfByCommand": "The lobby Host decided to commit suicide", + "SyncCustomSettingsRPC": "Synchronized RPC", + "Mode": "Mode", + "Target": "Target", + "PlayerInfo": "Player Info", + "NoInfoExists": "No Info Exists", + "PlayerLeftByAU-Anticheat": "{0} was banned by the Innersloth anti-cheat.", + "PlayerLeftByError": "Game will auto-end to prevent black screens.", + "MsgKickOtherPlatformPlayer": "{0} was kicked due to playing on {1}", + "KickBecauseLowLevel": "{0} was kicked because their level was too low", + "TempBannedBecauseLowLevel": "{0} was temporarily banned because their level was too low", + "KickBecauseDiffrentVersionOrMod": "{0} was kicked because they had a different version of the mod", + + "FFADisplayScore": "Ranking: {0} Score: {1}", + "FFATimeRemain": "Time Remaining: {0} second(s)", + + "GameOver": "Game Over", + "TOHEOptions": "TOHE Options", + "Cancel": "Cancel", + "Back": "Back", + "Yes": "Yes", + "No": "No", + + "AntiBlackOutLoggerSendInGame": "Because of an unknown error, the game will end to prevent a black screen.", + "AntiBlackOutNotifyInLobby": "An error occurred to prevent a black screen. Do a «/dump» and send the logs to the discord server TOHE in «bug-reports» and we will try to fix it.", + + "EndWhenPlayerBug": "End the game when a modded player gets a critical error (While loading)", + "AntiBlackOutRequestHostToForceEnd": "You were the reason for the black screen. The game will end", + "AntiBlackOutHostRejectForceEnd": "You were the reason for the black screen, and the host is not going to end the game\nYou will be disconnected soon", + + "RpcAntiBlackOutNotifyInLobby": "Because of {0}, an unknown error occurred. To prevent a black screen, turn off [{1}] in settings.", + "RpcAntiBlackOutEndGame": "Because of {0}, an unknown error occurred, the game will end to prevent a black screen.", + "RpcAntiBlackOutIgnored": "Because of {0}, an unknown error occurred, but the game will continue without that player due to host settings.", + "RpcAntiBlackOutKicked": "{0} was kicked due to having a blackout error on its side.", + + "NextPage": "Next Page", + "PreviousPage": "Previous Page", + "EAC.CheatDetected.EAC": "Cheating usage detected (Using AUM)", + "PressF1ShowMainRoleDes": "Press F1: Show Role Description", + "PressF2ShowAddRoleDes": "Press F2: Show Add-on Description", + "PressF3ShowRoleSettings": "Press F3: Show Role Settings", + "PressF4ShowAddOnsSettings": "Press F4: Show Add-ons Settings", + "FakeTask": "Fake Tasks:", + "PVP.ATK": "Attack", + "PVP.DF": "Defend", + "PVP.RCO": "Recover", + "SettingsAreLoading": "Loading\nsettings...", + "EAC.CheatDetected.HighLevel": "Warning: EAC detected High Level of cheats.", + "EAC.CheatDetected.LowLevel": "Warning: EAC detected Low Level of cheats. One of the players is hacking.", + "ExiledJester": "You're all fools!\n{0} the {1} laughing out loud tricked you into ejecting them.\nGG!", + "JesterMeetingLoose": "\r\nBut it cannot win until meeting number {0}", + "ExiledExeTarget": "{0} was the {1}.\nBut they were also the Executioner's target!\nGG!", + "ExiledInnocentTargetAddBelow": "\nLooking back at the Innocent counts the money in their hands", + "ExiledInnocentTargetInOneLine": "{0} was the {1}.\nBut looking back, there's the Innocent counting the money in their hands....\nGG!", + "ExiledDeath": "{0} was {1}!\nThe Crew has been saved from Armageddon!", + "ExiledNotDeath": "{0} was the {1}.\nBut they were not Death...\nDeath has claimed the souls of the Crew!", + "IsGood": "{0} was a good guy", + "BelongTo": "{0} belongs to {1}", + "PlayerIsRole": "{0} was The {1}", + "PlayerExiled": "{0} was ejected", + "NoImpRemain": "0 Impostors remain", + "OneImpRemain": "1 Impostor remains", + "TwoImpRemain": "2 Impostors remain", + "ThreeImpRemain": "3 Impostors remain", + "ImpRemain": "{0} Impostors remaining", + "NeutralRemain": "\n{0} Neutral Killers remain", + "OneNeutralRemain": "\n{0} Neutral Killer remains", + "ApocRemain": "\n{0} Neutral Apocalypse remains", + "GameOverReason.HumansByVote": "All Impostors and Neutral Killers were ejected or killed", + "GameOverReason.HumansByTask": "The Crewmates completed all tasks", + "GameOverReason.HumansDisconnect": "Crewmates disconnected", + "GameOverReason.ImpostorByVote": "The Crewmates were ejected", + "GameOverReason.ImpostorByKill": "The Impostors killed everyone", + "GameOverReason.ImpostorBySabotage": "Crewmates failed to fix a critical sabotage", + "GameOverReason.ImpostorDisconnect": "Impostors disconnected", + "FortuneTellerCheck.TaskDone": "[{0}]Role -[{1}]", + "DevAndSpnTitle": "TOHE family", + "FortuneTellerCheck.Null": "{0} is a role that is not listed.\nThis message should not appear normally.", + "FortuneTellerCheck.Result": "{0} is either one of the following roles:\n{1}", + "SunnyboyChance": "Sunnyboy Chance", + "BardChance": "Bard Chance", + "SkeldChance": "Chance that the map is The Skeld", + "MiraChance": "Chance that the map is MIRA HQ", + "PolusChance": "Chance that the map is Polus", + "DleksChance": "Chance that the map is dlekS ehT", + "AirshipChance": "Chance that the map is Airship", + "FungleChance": "Chance that the map is The Fungle", + "UseMoreRandomMapSelection": "Use a more random map selection", + "CamouflageMode.Default": "Default", + "CamouflageMode.Host": "Host", + "CamouflageMode.Random": "Random", + "CamouflageMode.OnlyRandomColor": "Only Random Color", + "CamouflageMode.Karpe": "KARPED1EM", + "CamouflageMode.Lauryn": "Lauryn", + "CamouflageMode.Moe": "Moe", + "CamouflageMode.Pyro": "Pyro", + "CamouflageMode.ryuk": "ryuk", + "CamouflageMode.Gurge44": "Gurge44", + "CamouflageMode.TommyXL": "TommyXL", + "CamouflageMode.Sarha": "Sarha", + "DeathCmd.HeyPlayer": "Hey ", + "DeathCmd.YouAreRole": ", looks like you're the ", + "DeathCmd.NotDead": "You haven't died yet, this can only be used after you die\n\nCheck back again after you've been brutally murdered", + "DeathCmd.KillerName": "You were killed by ", + "DeathCmd.KillerRole": "Their role is ", + "DeathCmd.DeathReason": "Your cause of death was ", + "DeathCmd.YourName": "You are ", + "DeathCmd.YourRole": "Your role is ", + "DeathCmd.Ejected": "You were ejected during a meeting", + "DeathCmd.Misfired": "You misfired.", + "DeathCmd.Shrouded": "You were shrouded by a Shroud and didn't make a kill, so you suicided.", + "DeathCmd.Lovers": "Your lover had died.", + + "RpsCommandInfo": "This Command can only be used when in the lobby or after you die.\n\ntype /rps X to play Rock Paper Scissors with the system. X can be 0 (rock), 1 (paper) or 2 (scissors). \n\nExample :- /rps 0", + "RpsDraw": "I choose {0}\n\nWow, what an intense battle of wits we just had! It's almost as if we're equally matched in this game of sheer luck and randomness.", + "RpsLose": "I choose {0}\n\nWell, well, well, looks like I've managed to outsmart a human again in this highly complex game of Rock, Paper, Scissors. I guess my unbeatable powers strike again! ", + "RpsWin": "I choose {0}\n\nOh, congratulations! You must have a crystal ball hidden behind that screen to beat me at Rock, Paper, Scissors. Or maybe I have the world's worst luck algorithm.", + + "CoinFlipCommandInfo": "This Command can only be used when in the lobby or after you die.", + "CoinFlipResult": "Drumroll, please... After an intense battle of gravity and randomness, the coin has decided to grace us with its presence! And the majestic winner is... (wait for it) ... the one and only... {0}! Who could have seen that coming?! Clearly, a momentous occasion in the history of coin flips.", + + "GNoCommandInfo": "This Command can only be used when in the lobby or after you die.\n\ntype /gno X to play guess a number. X can be a number between 0 and 99 (both included). \n\nYou get maximum of 7 tries to guess the number.\n\n Example:- /gno 10", + "GNoLost": "Oh, you were so close! Just one more guess: you might have deciphered the Da Vinci code! By the way, the secret number was... {0}! But hey, you were only off by a few billion possibilities. Better luck next time, Sherlock! ", + "GNoLow": "Oh, you're really nailing this! It's so low. I almost need a shovel to dig it up!\nYou have {0} guesses left!", + "GNoHigh": "Oh, absolutely! You're getting warmer. In fact, it's so high that I need a telescope to see it from here! \nYou have {0} guesses left!", + "GNoWon": "Oh, how did you ever figure that out? It's almost like you're a mind reader! Congratulations, you're a genius! You found the secret number with {0} guesses left!", + + "RandCommandInfo": "This Command can only be used when in the lobby or after you die.\n\ntype /rand X Y to get a number between X and Y, inclusive. \nX and Y can be any number between 0 and 2147483647, including both numbers.\nX must be less than Y.\n\nExample:- /rand 0 99", + "RandResult": "Congratulations, your random number is {0}! Wasn't that fun?", + + "8BallTitle": "The Magic 8 Ball Reveals...", + "8BallYes": "Yes", + "8BallNo": "No", + "8BallMaybe": "Maybe", + "8BallTryAgainLater": "Ask again later", + "8BallCertain": "It is certain", + "8BallNotLikely": "Outlook not so good", + "8BallLikely": "Outlook good", + "8BallDontCount": "Don't count on it", + "8BallStop": "Stop using an 8Ball in an Among Us mod", + "8BallPossibly": "Possibly", + "8BallProbably": "Probably", + "8BallProbablyNot": "Probably not", + "8BallBetterNotTell": "Better not tell you now", + "8BallCantPredict": "Cannot predict now", + "8BallWithoutDoubt": "Without a doubt", + "8BallWithDoubt": "Very doubtful", + + "ChanceToMiss": "Chance to miss a kill", + + "SoulCollectorPointsToWin": "Required number of souls", + "SoulCollectorTarget": "You have predicted the death of {0}", + "SoulCollectorTitle": "SOUL COLLECTOR", + "SoulCollector_CollectOwnSoulOpt": "Can collect their own soul", + "SoulCollectorSelfVote": "Host settings do not allow you to collect your own soul", + "SoulCollectorToDeath": "You have become Death!!!", + "SoulCollectorTransform": "Now Soul Collector has become Death, Destroyer of Worlds and Horseman of the Apocalypse!

Find them and vote them out before they bring forth Armageddon!", + "GetPassiveSouls": "Gain a passive soul every round", + "PassiveSoulGained": "You have gained a passive soul from the underworld.", + "SoulCollectorTargetUsed": "You've already targeted someone this round!", + "SoulCollectorSoulGained": "Soul gained", + "SoulCollectorCanVent": "Soul Collector can Vent", + "DeathMeetingTimeIncrease": "Increased Meeting time when Death exists", + "SoulCollectorMeetingDeath": "Your target has died during the meeting. You have gained a soul.", + "SoulCollectorKillButtonText": "Predict", + + "ApocalypseIsNigh": "[ The Apocalypse Is Nigh! ]", "ApocalypseImmune": "This role is immune!", - "BakerToFamine": "You have become Famine!!!", - "BakerTransform": "The Baker has transformed into Famine, Horseman of the Apocalypse! A famine has begun!", - "BakerAlreadyBreaded": "That player already has bread!", - "BakerBreadUsedAlready": "You've already given a player bread this round!", - "BakerBreaded": "Player given bread", - "BakerBreadNeededToTransform": "Required number of bread to become Famine", - "BakerCantBreadApoc": "You cannot give other Apocalypse members bread!", - "BakerKillButtonText": "Bread", + "BakerToFamine": "You have become Famine!!!", + "BakerTransform": "The Baker has transformed into Famine, Horseman of the Apocalypse! A famine has begun!", + "BakerAlreadyBreaded": "That player already has bread!", + "BakerBreadUsedAlready": "You've already given a player bread this round!", + "BakerBreaded": "Player given bread", + "BakerBreadNeededToTransform": "Required number of bread to become Famine", + "BakerCantBreadApoc": "You cannot give other Apocalypse members bread!", + "BakerKillButtonText": "Bread", "BakerUnshiftButtonText": "Switch Bread", - "BakerRevealBread": "Reveal", - "BakerRoleblockBread": "Roleblock", - "BakerBarrierBread": "Barrier", - "BakerCurrentBread": "Current Bread: ", - "BakerSwitchBread": "Bread Switched to: ", + "BakerRevealBread": "Reveal", + "BakerRoleblockBread": "Roleblock", + "BakerBarrierBread": "Barrier", + "BakerCurrentBread": "Current Bread: ", + "BakerSwitchBread": "Bread Switched to: ", "BakerCanVent": "Baker can Vent", - "BakerBreadGivesEffects": "Bread gives additional effects", + "BakerBreadGivesEffects": "Bread gives additional effects", "BakerTransformNoMoreBread": "Baker transforms if they do not have enough bread", - "FamineKillButtonText": "Starve", - "FamineStarveCooldown": "Famine starve cooldown", - "FamineCantStarveApoc": "You cannot starve other Apocalypse members!", - "FamineAlreadyStarved": "That player has already been starved!", - "FamineStarved": "Player starved", - - "ChronomancerKillCooldown": "Ability Charge Time", - "ChronomancerDecreaseTime": "Slaughter Decrease Time (lower is faster)", - "ChronomancerStartMassacre": "SLAUGHTER: ACTIVATED", - "ChronomancerVisionMassacre": "Vision When In Slaughter", - - "ShamanButtonText": "Voodoo", - "ShamanTargetAlreadySelected": "You have already selected a voodoo doll in this round", - "Shaman_KillerCannotMurderChosenTarget": "The killer cannot murder chosen target", - "VoodooCooldown": "Voodoo Cooldown", - - "AdminWarning": "Admin Table in use!", - "VitalsWarning": "Vitals in use!", - "DoorlogWarning": "Doorlogs in use!", - "CameraWarning": "Cameras in use!", - "MinWaitAutoStart": "Minutes to wait before auto-starting", - "MaxWaitAutoStart": "Force start when Lobby Timer (in minutes) goes below", - "PlayerAutoStart": "Minimum Player Threshold to auto-start", - "AutoStartTimer": "Initial countdown for auto-starting", - "ImmediateAutoStart": "Immediately start the game when reaching certain conditions", - "ImmediateStartTimer": "Initial countdown for Immediate-starting", - "StartWhenPlayersReach": "Immediately Start when we have enough players above", - "StartWhenTimerLowerThan": "Immediately Start when Lobby Timer goes below", - "AutoPlayAgainCountdown": "Delay before re-entering lobby", - "AutoPlayAgain": "Auto Play Again", - "AutoRehost": "Auto Re-Host on Bad Disconnect", - "CountdownText": "Rejoining lobby in {0}s", - "TimeMasterSkillDuration": "Time Shield Duration", - "TimeMasterSkillCooldown": "Time Shield Cooldown", - "TimeMasterOnGuard": "Time Shield is active!", - "TimeMasterSkillStop": "Time Shield has ended!", - "TimeMasterVentButtonText": "Time Shield", - "BodyCannotBeReported": "Body could not be reported", - "BurstKillDelay": "Burst Kill Delay", - "BurstNotify": "That was a Burst! Get in a vent or die.", - "BurstFailed": "Burst failed to bomb you", - "ShroudButtonText": "Shroud", - "ShroudCooldown": "Shroud Cooldown", - "Message.Shrouded": "One or more players were shrouded by a Shroud!\n\nGet rid of the Shroud or all shrouded players will suicide!", - "LudopathRandomKillCD": "Maximum kill cooldown", - "UnderdogMaximumPlayersNeededToKill": "Maximum players needed to start killing", - "GodfatherTargetCountMode": "Killer turns into", - "GodfatherCount_Refugee": "Refugee", - "GodfatherCount_Madmate": "Madmate", + "FamineKillButtonText": "Starve", + "FamineStarveCooldown": "Famine starve cooldown", + "FamineCantStarveApoc": "You cannot starve other Apocalypse members!", + "FamineAlreadyStarved": "That player has already been starved!", + "FamineStarved": "Player starved", + + "ChronomancerKillCooldown": "Ability Charge Time", + "ChronomancerDecreaseTime": "Slaughter Decrease Time (lower is faster)", + "ChronomancerStartMassacre": "SLAUGHTER: ACTIVATED", + "ChronomancerVisionMassacre": "Vision When In Slaughter", + + "ShamanButtonText": "Voodoo", + "ShamanTargetAlreadySelected": "You have already selected a voodoo doll in this round", + "Shaman_KillerCannotMurderChosenTarget": "The killer cannot murder chosen target", + "VoodooCooldown": "Voodoo Cooldown", + + "AdminWarning": "Admin Table in use!", + "VitalsWarning": "Vitals in use!", + "DoorlogWarning": "Doorlogs in use!", + "CameraWarning": "Cameras in use!", + "MinWaitAutoStart": "Minutes to wait before auto-starting", + "MaxWaitAutoStart": "Force start when Lobby Timer (in minutes) goes below", + "PlayerAutoStart": "Minimum Player Threshold to auto-start", + "AutoStartTimer": "Initial countdown for auto-starting", + "ImmediateAutoStart": "Immediately start the game when reaching certain conditions", + "ImmediateStartTimer": "Initial countdown for Immediate-starting", + "StartWhenPlayersReach": "Immediately Start when we have enough players above", + "StartWhenTimerLowerThan": "Immediately Start when Lobby Timer goes below", + "AutoPlayAgainCountdown": "Delay before re-entering lobby", + "AutoPlayAgain": "Auto Play Again", + "AutoRehost": "Auto Re-Host on Bad Disconnect", + "CountdownText": "Rejoining lobby in {0}s", + "TimeMasterSkillDuration": "Time Shield Duration", + "TimeMasterSkillCooldown": "Time Shield Cooldown", + "TimeMasterOnGuard": "Time Shield is active!", + "TimeMasterSkillStop": "Time Shield has ended!", + "TimeMasterVentButtonText": "Time Shield", + "BodyCannotBeReported": "Body could not be reported", + "BurstKillDelay": "Burst Kill Delay", + "BurstNotify": "That was a Burst! Get in a vent or die.", + "BurstFailed": "Burst failed to bomb you", + "ShroudButtonText": "Shroud", + "ShroudCooldown": "Shroud Cooldown", + "Message.Shrouded": "One or more players were shrouded by a Shroud!\n\nGet rid of the Shroud or all shrouded players will suicide!", + "LudopathRandomKillCD": "Maximum kill cooldown", + "UnderdogMaximumPlayersNeededToKill": "Maximum players needed to start killing", + "GodfatherTargetCountMode": "Killer turns into", + "GodfatherCount_Refugee": "Refugee", + "GodfatherCount_Madmate": "Madmate", "GodfatherRefugeeMsg": "You have been recruited by GodFather!", - "MissChance": "Chance To Miss", - "IncreaseByOneIfConvert": "Increase The KillCount +1 If a Crew Is Converted", - "HawkMissed": "Missed!", - "HawkCanKillNum": "Max Slices", - "HawkKillMax": "You've run out of ability uses", - "HawkKillTooManyDead": "Too many people are dead", - "MinimumPlayersAliveToKill": "Minimum Players Alive To Kill", - "BloodMoonCanKillNum": "Max BloodLettings", - "BloodMoonTimeTilDie": "Time Until Death", - "PossessorPossessCooldown": "Possession Cooldown", - "PossessorPossessDuration": "Possession Duration", - "PossessorAlertRange": "Alert Range", - "PossessorFocusRange": "Focus Range", - "DeathTimer": "Death In: {DeathTimer}s", - "BerserkerKillCooldown": "Berserker kill cooldown", - "BerserkerMax": "Max level that Berserker can reach", - "BerserkerHasImpostorVision": "Berserker Has Impostor Vision", - "WarHasImpostorVision": "War Has Impostor Vision", - "BerserkerCanVent": "Berserker Can Vent", - "WarCanVent": "War Can Vent", - "BerserkerOneCanKillCooldown": "Unlock lower kill cooldown", - "BerserkerOneKillCooldown": "Kill cooldown after unlocking", - "BerserkerTwoCanScavenger": "Unlock scavenged kills", - "BerserkerThreeCanBomber": "Unlock bombed kills", - "BerserkerFourCanNotKill": "Become War", - "BerserkerMaxReached": "Maximum level reached!", - "BerserkerLevelChanged": "Increased level to {0}", - "BerserkerLevelRequirement": "Level requirement for unlock", - "KilledByBerserker": "Killed by Berserker", - "BerserkerToWar": "You have become War!!!", - "BerserkerTransform": "The Berserker has transformed into War, Horseman of the Apocalypse! Cry 'Havoc!', and let slip the dogs of war.", - "WarKillCooldown": "War kill cooldown", - "BerserkerCanKillTeamate": "Can kill other Neutral Apocalypse", - - "BlackmailerSkillCooldown": "Blackmail Cooldown", - "BlackmailerMax": "Maximum times blackmailed players may speak", - "BlackmailerDead": "Warning! {0} has been blackmailed by a Blackmailer!", - "BlackmaileKillTitle": "BLACKMAILER", - "UnluckyTaskSuicideChance": "Chance to suicide from doing tasks", - "UnluckyKillSuicideChance": "Chance to suicide from killing", - "UnluckyVentSuicideChance": "Chance to suicide from venting", - "UnluckyReportSuicideChance": "Chance to suicide from reporting bodies", - "UnluckyOpenDoorSuicideChance": "Chance to suicide from opening a door", - "NeutralCanBeAware": "Neutrals can become Aware", - "CrewCanBeAware": "Crewmates can become Aware", - "AwareKnowRole": "Knows the role of the player", - "AwareInteracted": "{0} tried to reveal your role.", - "AwareTitle": "AWARE MESSAGE", - "LighterVentButtonText": "Light", - "LighterSkillCooldown": "Light Cooldown", - "LighterSkillDuration": "Light Duration", - "LighterVisionNormal": "Increased Vision", - "LighterVisionOnLightsOut": "Increased Vision During Lights Out", - "StealthDarkened": "Darkened: {0}", - "StealthExcludeImpostors": "Ignore Impostors when Blinding", - "StealthDarkenDuration": "Blinding Duration", - "PenguinAbductTimerLimit": "Dragging Time", - "PenguinMeetingKill": "Kill the target if a meeting starts during dragging", - "PenguinKillButtonText": "Drag", - "PenguinTimerText": "Drag Timer", - "PenguinTargetOnCheckMurder": "You are grabbed. Try to escape that first!", - "WitnessTime": "Max Time after killing where killer appears red", - "WitnessButtonText": "Examine", - "WitnessFoundInnocent": "✓", - "WitnessFoundKiller": "⚠", - "SwapperMax": "Maximum swaps", - "CanSwapSelfVotes": "Can exchange your own votes.", - "SwapperTrialMax": "You've reached the maximum amount of swaps!\nYou can't swap votes anymore.", - "CantSwapSelf": "Can't exchange of one's own vote", - "SwapVote": "The votes of {0} and {1} were swapped!", - "SwapDead": "Sorry, you can't swap votes after death.", - "SwapNull": "Please choose the ID of a living player to swap votes with. Use 253 to clear swaps", - "SwapHelp": "Command Format: /sw [playerID] to select the target\nYou can see the player IDs next to the player names or use /id to see the player ID list.\nUse /swap 253 to clear your previous swap", - "Swap1": "Swap target 1 selected", - "Swap2": "Swap target 2 selected", - "CancelSwap": "Cleared your previous swap!", - "CancelSwapDueToTarget": "Cleared your previous swap because one or more of your targets is dead.", - "Swap1=Swap2": "The target you input is the same as Swap target 1.\nPls input a different one", - "SwapTitle": "SWAPPER", - "SwapperTryHideMsg": "Try to hide Swapper's command", - "SwapperPreResult": "Currently, you selected to swap votes between {0} and {1}.\nIf you feel unsure, use /swap 253 to clear your selection.", - "ImpCanKillFragile": "Impostors can force kill Fragile", - "NeutralCanKillFragile": "Neutrals can force kill Fragile", - "CrewCanKillFragile": "Crewmates can force kill Fragile", - "FragileKillerLunge": "Killer lunges on kill", - "CrusaderSkillLimit": "Maximum Crusades", - "CrusaderSkillCooldown": "Crusade Cooldown", - "CrusaderKillButtonText": "Crusade", - "JailorKillButtonText": "Jail", - "AgitaterKillButtonText": "Pass", - "HasSerialKillerBuddy": "Has Serial Killer buddy", - "ChanceToSpawn": "Chance to spawn", - "ChanceToSpawnAnother": "Chance to spawn another", - "BloodthirstKillCD": "Bloodthirst Kill Cooldown", - "BloodthirstPlayerCount": "Max players alive for Bloodthirst", - "ReflectHarmfulInteractions": "Reflect harmful interactions", - - "DiseasedCDOpt": "Increase the cooldown by", - "DiseasedCDReset": "Cooldown returns to normal after a meeting", - - "AntidoteCDOpt": "Decrease the cooldown by", - "AntidoteCDReset": "Cooldown returns to normal after a meeting", - - "GlowRadius": "Glow Radius", - "GlowVisionOthers": "Vision Boost for nearby Players", - "GlowVisionSelf": "Vision Boost for Glow", - - "SleuthCanKnowKillerRole": "Can find the role of the killer", - "SleuthNoticeKiller": "\nThe killer's role is {0}.", - "SleuthNoticeVictim": "{0}'s role is {1}.", - "SleuthNoticeKillerNotFound": "\nThe killer could not be identified, this was possibly a suicide.", - "BomberDiesInExplosion": "Bomber dies in their explosion", - "ImpostorsSurviveBombs": "Impostors survive bombs", - - "PunchingBagKillMax": "Amount of attacks needed to win", - "GuessPunchingBag": "You just tried to guess a Punching Bag!\nThey're now one step closer to winning!", - "GuessPunchingBagAgain": "You just tried to guess a Punching Bag again!\n\nIt no longer counts your attacks by guessing", - "PunchingBagKill": "You were attacked!", - "SelfGuessPunchingBag": "You can't self-guess as a Punching Bag, you cheater!", - "GuessPunchingBagBlocked": "Punching Bag cannot guess due to self-guessing.", - "EradicatePunchingBag": "You just tried to terminate punching bag, that is not allowed.", - - "RememberCooldown": "Imitate Cooldown", - "RefugeeKillCD": "Refugee's Kill Cooldown", - "RememberedNeutralKiller": "You remembered you were a neutral killer!", - "RememberedMaverick": "You remembered you were a Maverick!", - "RememberedPursuer": "You remembered you were a Pursuer!", - "RememberedFollower": "You remembered you were a Follower!", - "RememberedAmnesiac": "You failed to remember your role.", + "MissChance": "Chance To Miss", + "IncreaseByOneIfConvert": "Increase The KillCount +1 If a Crew Is Converted", + "HawkMissed": "Missed!", + "HawkCanKillNum": "Max Slices", + "HawkKillMax": "You've run out of ability uses", + "HawkKillTooManyDead": "Too many people are dead", + "MinimumPlayersAliveToKill": "Minimum Players Alive To Kill", + "BloodMoonCanKillNum": "Max BloodLettings", + "BloodMoonTimeTilDie": "Time Until Death", + "PossessorPossessCooldown": "Possession Cooldown", + "PossessorPossessDuration": "Possession Duration", + "PossessorAlertRange": "Alert Range", + "PossessorFocusRange": "Focus Range", + "DeathTimer": "Death In: {DeathTimer}s", + "BerserkerKillCooldown": "Berserker kill cooldown", + "BerserkerMax": "Max level that Berserker can reach", + "BerserkerHasImpostorVision": "Berserker Has Impostor Vision", + "WarHasImpostorVision": "War Has Impostor Vision", + "BerserkerCanVent": "Berserker Can Vent", + "WarCanVent": "War Can Vent", + "BerserkerOneCanKillCooldown": "Unlock lower kill cooldown", + "BerserkerOneKillCooldown": "Kill cooldown after unlocking", + "BerserkerTwoCanScavenger": "Unlock scavenged kills", + "BerserkerThreeCanBomber": "Unlock bombed kills", + "BerserkerFourCanNotKill": "Become War", + "BerserkerMaxReached": "Maximum level reached!", + "BerserkerLevelChanged": "Increased level to {0}", + "BerserkerLevelRequirement": "Level requirement for unlock", + "KilledByBerserker": "Killed by Berserker", + "BerserkerToWar": "You have become War!!!", + "BerserkerTransform": "The Berserker has transformed into War, Horseman of the Apocalypse! Cry 'Havoc!', and let slip the dogs of war.", + "WarKillCooldown": "War kill cooldown", + + "BlackmailerSkillCooldown": "Blackmail Cooldown", + "BlackmailerMax": "Maximum times blackmailed players may speak", + "BlackmailerDead": "Warning! {0} has been blackmailed by a Blackmailer!", + "BlackmaileKillTitle": "BLACKMAILER", + "UnluckyTaskSuicideChance": "Chance to suicide from doing tasks", + "UnluckyKillSuicideChance": "Chance to suicide from killing", + "UnluckyVentSuicideChance": "Chance to suicide from venting", + "UnluckyReportSuicideChance": "Chance to suicide from reporting bodies", + "UnluckyOpenDoorSuicideChance": "Chance to suicide from opening a door", + "NeutralCanBeAware": "Neutrals can become Aware", + "CrewCanBeAware": "Crewmates can become Aware", + "AwareKnowRole": "Knows the role of the player", + "AwareInteracted": "{0} tried to reveal your role.", + "AwareTitle": "AWARE MESSAGE", + "LighterVentButtonText": "Light", + "LighterSkillCooldown": "Light Cooldown", + "LighterSkillDuration": "Light Duration", + "LighterVisionNormal": "Increased Vision", + "LighterVisionOnLightsOut": "Increased Vision During Lights Out", + "StealthDarkened": "Darkened: {0}", + "StealthExcludeImpostors": "Ignore Impostors when Blinding", + "StealthDarkenDuration": "Blinding Duration", + "PenguinAbductTimerLimit": "Dragging Time", + "PenguinMeetingKill": "Kill the target if a meeting starts during dragging", + "PenguinKillButtonText": "Drag", + "PenguinTimerText": "Drag Timer", + "PenguinTargetOnCheckMurder": "You are grabbed. Try to escape that first!", + "WitnessTime": "Max Time after killing where killer appears red", + "WitnessButtonText": "Examine", + "WitnessFoundInnocent": "✓", + "WitnessFoundKiller": "⚠", + "SwapperMax": "Maximum swaps", + "CanSwapSelfVotes": "Can exchange your own votes.", + "SwapperTrialMax": "You've reached the maximum amount of swaps!\nYou can't swap votes anymore.", + "CantSwapSelf": "Can't exchange of one's own vote", + "SwapVote": "The votes of {0} and {1} were swapped!", + "SwapDead": "Sorry, you can't swap votes after death.", + "SwapNull": "Please choose the ID of a living player to swap votes with. Use 253 to clear swaps", + "SwapHelp": "Command Format: /sw [playerID] to select the target\nYou can see the player IDs next to the player names or use /id to see the player ID list.\nUse /swap 253 to clear your previous swap", + "Swap1": "Swap target 1 selected", + "Swap2": "Swap target 2 selected", + "CancelSwap": "Cleared your previous swap!", + "CancelSwapDueToTarget": "Cleared your previous swap because one or more of your targets is dead.", + "Swap1=Swap2": "The target you input is the same as Swap target 1.\nPls input a different one", + "SwapTitle": "SWAPPER", + "SwapperTryHideMsg": "Try to hide Swapper's command", + "SwapperPreResult": "Currently, you selected to swap votes between {0} and {1}.\nIf you feel unsure, use /swap 253 to clear your selection.", + "ImpCanKillFragile": "Impostors can force kill Fragile", + "NeutralCanKillFragile": "Neutrals can force kill Fragile", + "CrewCanKillFragile": "Crewmates can force kill Fragile", + "FragileKillerLunge": "Killer lunges on kill", + "CrusaderSkillLimit": "Maximum Crusades", + "CrusaderSkillCooldown": "Crusade Cooldown", + "CrusaderKillButtonText": "Crusade", + "JailorKillButtonText": "Jail", + "AgitaterKillButtonText": "Pass", + "HasSerialKillerBuddy": "Has Serial Killer buddy", + "ChanceToSpawn": "Chance to spawn", + "ChanceToSpawnAnother": "Chance to spawn another", + "BloodthirstKillCD": "Bloodthirst Kill Cooldown", + "BloodthirstPlayerCount": "Max players alive for Bloodthirst", + "ReflectHarmfulInteractions": "Reflect harmful interactions", + + "DiseasedCDOpt": "Increase the cooldown by", + "DiseasedCDReset": "Cooldown returns to normal after a meeting", + + "AntidoteCDOpt": "Decrease the cooldown by", + "AntidoteCDReset": "Cooldown returns to normal after a meeting", + + "GlowRadius": "Glow Radius", + "GlowVisionOthers": "Vision Boost for nearby Players", + "GlowVisionSelf": "Vision Boost for Glow", + + "SleuthCanKnowKillerRole": "Can find the role of the killer", + "SleuthNoticeKiller": "\nThe killer's role is {0}.", + "SleuthNoticeVictim": "{0}'s role is {1}.", + "SleuthNoticeKillerNotFound": "\nThe killer could not be identified, this was possibly a suicide.", + "BomberDiesInExplosion": "Bomber dies in their explosion", + "ImpostorsSurviveBombs": "Impostors survive bombs", + + "PunchingBagKillMax": "Amount of attacks needed to win", + "GuessPunchingBag": "You just tried to guess a Punching Bag!\nThey're now one step closer to winning!", + "GuessPunchingBagAgain": "You just tried to guess a Punching Bag again!\n\nIt no longer counts your attacks by guessing", + "PunchingBagKill": "You were attacked!", + "SelfGuessPunchingBag": "You can't self-guess as a Punching Bag, you cheater!", + "GuessPunchingBagBlocked": "Punching Bag cannot guess due to self-guessing.", + "EradicatePunchingBag": "You just tried to terminate punching bag, that is not allowed.", + + "RememberCooldown": "Imitate Cooldown", + "RefugeeKillCD": "Refugee's Kill Cooldown", + "RememberedNeutralKiller": "You remembered you were a neutral killer!", + "RememberedMaverick": "You remembered you were a Maverick!", + "RememberedPursuer": "You remembered you were a Pursuer!", + "RememberedFollower": "You remembered you were a Follower!", + "RememberedAmnesiac": "You failed to remember your role.", "AmnesiacRemembered": "You remembered you were {0}!", "ReportWhenFailedRemember": "Report Dead Body when failed to remember", - "RememberedImitator": "You remembered you were an Imitator.", - "RememberedImpostor": "You remembered you were an Impostor!", - "RememberedCrewmate": "You remembered you were a crewmate!", - "ImitatorImitated": "An Imitator imitated your role!", - "ImitatorInvalidTarget": "Imitation failed", - "RememberButtonText": "Remember", - "ImitatorKillButtonText": "Imitate", - "IncompatibleNeutralMode": "If neutral is incompatible, turn into", - "RememberedYourRole": "An Amnesiac remembered your role!", - "YouRememberedRole": "You remembered who you were!", - - "BanditStealMode": "Steal Mode", - "BanditStealMode_OnMeeting": "On Meeting", - "BanditStealMode_Instantly": "Instantly", - "BanditMaxSteals": "Maximum Steals", - "BanditCanStealBetrayalAddon": "Can Steal Betrayal Add-ons", - "BanditCanStealImpOnlyAddon": "Can Steal Impostor Only Addons", - "Bandit_NoStealableAddons": "Could not steal add-on from the player", - "BanditStealCooldown": "Steal cooldown", - - "DoppelMaxSteals": "Maximum Steals", - "DoppelCurrentVictimCanSeeRolesAsDead": "Last victim can see role and add-on info of alive players as a ghost", - - "NecromancerRevengeTime": "Necromancy time", - "NecromancerRevenge": "You have {0}s to kill {1}", - "NecromancerSuccess": "Necromancy complete! You live to see another day.", - "NecromancerHide": "Venting is disabled, hide from the Necromancer!", - "RetributionistDeadMsg": "The death of the Retributionist means the beginning of retribution. \nPlease use /ret + [player ID] to kill the specified player \nYou can see player IDs in front of their names. \nOr type /ret to get a list of player IDs", - "RetributionistAliveKill": "Retribution for the Retributionist may only begin after their death.", - "RetributionistKillMax": "You've reached the maximum amount of kills. You can't kill anymore!", - "RetributionistKillDead": "Choose a living player to kill.", - "RetributionistKillSucceed": "{0} was killed by the Retributionist!", - "RetributionistKillDisable": "You can't retribute until your tasks are done.", - "CanOnlyRetributeWithTasksDone": "Can only retribute on task completion", - "RetributionistCanKillNum": "Max retributions", - "RetributionistKillTooManyDead": "Too many players are dead. You can't retribute.", - "MinimumPlayersAliveToRetri": "Minimum players alive to retribute", - "MinimumNoKillerEjectsToKill": "Minimum meetings passed with no killer ejects to kill", - "ImmuneToAttacksWhenTasksDone": "Immune to attacks on task completion", - - "TwisterCooldown": "Twist Cooldown", - "TwisterButtonText": "Twist", - "TwisterHideTwistedPlayerNames": "Hide who the players swap places with", - "InstigatorAbilityLimit": "Ability Use Count", - "InstigatorKillsPerAbilityUse": "Kills per Ability use", - - "CrewCanFindCaptain": "Crewmates can find Captain", - "MadmateCanFindCaptain": "Madmates can find Captain", - "ReducedSpeed": "Reduced speed", - "ReducedSpeedTime": "Time duration for reduced speed", - "CaptainCanTargetNB": "Captain can target Neutral Benign", - "CaptainCanTargetNE": "Captain can target Neutral Evil", - "CaptainCanTargetNC": "Captain can target Neutral Chaos", - "CaptainCanTargetNA": "Captain can target Neutral Apocalypse", - "CaptainCanTargetNK": "Captain can target Neutral Killer", - "CaptainSpeedReduced": "Captain reduced your speed", - "CaptainRevealTaskRequired": "Number of tasks completed after which Captain is revealed", - "CaptainSlowTaskRequired": "Number of tasks completed after which target speed is reduced", - - "InspectorTryHideMsg": "Hide Inspector's commands", - "MaxInspectCheckLimit": "Max inspections per game", - "InspectCheckLimitPerMeeting": "Max inspections per meeting", - "InspectCheckTargetKnow": "Targets know they were checked by Inspector", - "InspectCheckOtherTargetKnow": "Targets know who they were checked with", - "InspectorDead": "You can not use your power after death", - "InspectCheckMax": "Max inspections per game reached!\nYou can not use your power anymore.", - "InspectCheckRound": "Max inspections per round reached!\nYou can check again in the next round.", - "InspectCheckSelf": "HA!! You thought it would be this easy. You can not check yourself", - "InspectCheckReveal": "HA! You thought it would be this easy. You can not check a role that is revealed", - "InspectCheckTitle": "INSPECTOR ", - "InspectCheckTrue": "{0} and {1} are in the same team!", - "InspectCheckFalse": "{0} and {1} are NOT in the same team!", - "InspectCheckTargetMsg": " were checked by Inspector.", - "InspectCheckHelp": "Instructions: /cmp [Player ID 1] [Player ID 2] \nExample: /cmp 1 5 \nYou can see the player IDs before everyone's names \n or use the /id command to list the player IDs", - "InspectCheckNull": "Please select an ID of a living player to check their team", - "InspectCheckBaitCountMode": "Bait counts as revealing role if Bait reveal on first meeting is on", - "InspectCheckRevealTarget": "When tasks are done, the target knows the team of the other target", - "InspectorTargetReveal": " Looks like {0} is aligned with team {1}", - - "EgoistCountMode.Original": "Original", - "EgoistCountMode.Neutral": "Neutral", - - "JailerJailCooldown": "Jail cooldown", - "JailerMaxExecution": "Maximum executions", - "JailerNBCanBeExe": "Can execute Neutral Benign", - "JailerNCCanBeExe": "Can execute Neutral Chaos", - "JailerNECanBeExe": "Can execute Neutral Evil", - "JailerNKCanBeExe": "Can execute Neutral Killing", - "JailerNACanBeExe": "Can execute Neutral Apocalypse", - "JailerCKCanBeExe": "Can execute Crew Killing", - "JailerTargetAlreadySelected": "You have already selected a target", - "SuccessfullyJailed": "Target successfully jailed", - "CantGuessJailed": "You can not guess the target", - "JailedCanOnlyGuessJailer": "You have been jailed. You can only guess Jailer.", - "CanNotTrialJailed": "You can not trial the target.", - "notifyJailedOnMeeting": "Notify jailed player when a meeting starts", - "JailedNotifyMsg": "The Jailer has jailed you. No one can guess or judge you. You can only guess The Jailer.\n\nIf Jailer votes you, you will be executed after the meeting ends.", - "JailerTitle": "Jailer", - - "CopyCatCopyCooldown": "Copy cooldown", - "CopyCatRoleChange": "Your role has been changed to {0}", - "CopyCatCanNotCopy": "You can not copy the target's role", - "CopyButtonText": "Copy", - "CopyCrewVar": "Can copy evil variants of crew roles", - "CopyTeamChangingAddon": "Can copy team changing add-on", - - "MaxCleanserUses": "Max cleanses", - "CleansedCanGetAddon": "Cleansed player can get Add-on", - "CleanserTitle": "CLEANSER", - "CleanserRemoveSelf": "You can not cleanse yourself", - "CleanserCantRemove": "Oops! the player can not be cleansed.", - "CleanserRemovedRole": "{0} has been cleansed. All their Add-ons will be removed after the meeting.\n\nYour vote has been returned and you can vote for someone.", - "LostAddonByCleanser": "The cleanser removed all your Add-ons", - - "MaxProtections": "Max protections", - "KeeperHideVote": "Hide Keeper's vote", - "KeeperProtect": "You chose to protect {0}, your vote has been returned", - "KeeperTitle": "Keeper", - - "MaulRadius": "Maul Radius", - "ImpKnowCyberDead": "Impostors know if Cyber died", - "CrewKnowCyberDead": "Crewmates know if Cyber died", - "NeutralKnowCyberDead": "Neutrals know if Cyber died", - "CyberKnown": "Everyone can see Cyber", - "KillerGetBewilderVision": "Killer gets Bewilder's vision", - "ImpCanBeOiiai": "Impostors can be OIIAI", - "CrewCanBeOiiai": "Crewmates can be OIIAI", - "NeutralCanBeOiiai": "Neutrals can be OIIAI", - "OiiaiCanPassOn": "OIIAI can pass on to the killer", - "NeutralChangeRolesForOiiai": "Neutrals turns to ", - "LostRoleByOiiai": "You got erased by OIIAI!", - "ImpCanBeLoyal": "Impostors can become Loyal", - "CrewCanBeLoyal": "Crewmates can become Loyal", - "TasklessCrewCanBeLazy": "Crewmates without tasks can be Lazy", - "TaskBasedCrewCanBeLazy": "Task based crewmates can be Lazy", - "SheriffCanBeMadmate": "Sheriff can become Madmate", - "MayorCanBeMadmate": "Mayor can become Madmate", - "NGuesserCanBeMadmate": "Nice Guesser can become Madmate", - "SnitchCanBeMadmate": "Snitch can become Madmate", - "JudgeCanBeMadmate": "Judge can become Madmate", - "MarshallCanBeMadmate": "Marshall can become Madmate", - "GanRetributionistCanBeMadmate": "Retributionist can be converted", - "RetributionistCanBeMadmate": "Retributionist can become Madmate", - "OverseerCanBeMadmate": "Overseer can become Madmate", - "GanSheriffCanBeMadmate": "Sheriff can be converted", - "GanMayorCanBeMadmate": "Mayor can be converted", - "GanNGuesserCanBeMadmate": "Nice Guesser can be converted", - "GanJudgeCanBeMadmate": "Judge can be converted", - "GanMarshallCanBeMadmate": "Marshall can be converted", - "GanOverseerCanBeMadmate": "Overseer can be converted", - "RascalAppearAsMadmate": "Appear As Madmate On Ejection", - - "CouncillorDead": "Sorry, you can't murder from the dead.", - "CouncillorMurderMaxMeeting": "Sorry, you've reached the maximum amount of murders for the meeting.", - "CouncillorMurderMaxGame": "Sorry, you've reached the maximum amount of murders for the game.", - "Councillor_LaughToWhoMurderSelf": "Hahaha, who would've thought someone was stupid enough to murder themselves?\n\nGuess it happens to be... YOU!", - "Councillor_MurderKill": "{0} was murdered.", - "Councillor_MurderHelp": "Command: /tl [player ID]\nYou can see the players' IDs before the players' names.\nOr use /id to view the list of all player IDs.", - "Councillor_MurderNull": "Please choose a living player to murder.", - "Councillor_MurderKillTitle": "WICKED COURT ", - "CouncillorMakeEvilJudgeClear": "Show Trial as Councillor Murder", - "Councillor_CannotMurderImpTeam": "Sorry, you can not murder your teammate.", - "Councillor_SuicideForMurderImps": "You died because you are trying to murder your team members.", - "CouncillorMurderLimitPerMeeting": "Maximum Kills Per Meeting", - "CouncillorMurderLimitPerGame": "Maximum Kills Per Game", - "CouncillorCanMurderMadmate": "Can Murder Madmates", - "CouncillorCanMurderImpostor": "Can Murder Impostors", - "CouncillorSuicideOnJudgeImpTeam": "Suicide when judge Impostors Team Wrongly", - "CouncillorCanMurderTaskDoneSnitch": "Can Murder Snitch with All Tasks Done", - "CouncillorTryHideMsg": "Try to hide Councillor's commands", - - "DazzlerDazzled": "You were dazzled by the Dazzler!", - "DazzlerCauseVision": "Reduced vision", - "DazzlerDazzleLimit": "Max number of players affected by reduced vision", - "DazzlerResetDazzledVisionOnDeath": "Reset vision of dazzled players on death/eject", - "DazzleCooldown": "Dazzle Cooldown", - "DazzleButtonText": "Dazzle", - - "MoleVentButtonText": "Dig", - "MoleVentCooldown": "Dig cooldown", - - "AddictVentButtonText": "Get Fix", - "AddictInvulnerbilityTimeAfterVent": "Invulnerability Time", - "AddictSpeedWhileInvulnerble": "Movement speed while Invulnerable", - - "AddictFreezeTimeAfterInvulnerbility": "Time the Addict gets frozen in place after Invulnerability", - "AlchemistShieldDur": "Resistance Potion Duration", - "AlchemistInvisDur": "Invisibility Potion Duration", - "AlchemistVision": "Night Vision", - "AlchemistVisionOnLightsOut": "Night Vision During Lights Sabotage", - "AlchemistVisionDur": "Night Vision Potion Duration", - "AlchemistSpeed": "Speed Potion Boost", - "AlchemistVentButtonText": "Drink", - "AlchemistGotShieldPotion": "Potion of Resistance: Grants a temporary shield", - "AlchemistGotSightPotion": "Potion of Night Vision: Gives temporary enhanced vision", - "AlchemistGotQFPotion": "Potion of Fixing: Allows you to fix one sabotage instantly", - "AlchemistGotTPPotion": "Potion of Warping: Teleports you to a random player", - "AlchemistGotSuicidePotion": "Potion of Poison: Poisons you", - "AlchemistGotSpeedPotion": "Potion Of Speed: Hastens you", - "AlchemistGotBloodthirstPotion": "Potion of Harming: Kill the next player you touch", - "AlchemistGotInvisibility": "Potion of Invisibility: Become Invisible", - "NoPotion": "You have no potions", - - "StoreShield": "Potion of Resistance", - "StoreSuicide": "Potion of Poison", - "StoreTP": "Potion of Warping", - "StoreSP": "Potion Of Speed", - "StoreQF": "Potion of Fixing", - "StoreBL": "Potion of Harming", - "StoreNS": "Potion of Night Vision", - "StoreINV": "Potion of Invisibility", - "StoreNull": "None", - "PotionStore": "Potion in store: ", - "WaitQFPotion": "\nPotion of Fixing waiting for use", - - "AlchemistShielded": "Potion of Resistance started", - "AlchemistHasVision": "Potion of Night Vision started", - "AlchemistShieldOut": "Potion of Resistance ended", - "AlchemistVisionOut": "Potion of Night Vision ended", - "AlchemistPotionBloodthirst": "You gained bloodthirst", - "AlchemistHasSpeed": "Potion Of Speed started", - "AlchemistSpeedOut": "Potion Of Speed ended", - - "DeathpactDuration": "Death Pact duration", - "DeathPactCooldown": "Death Pact Assign Cooldown", - "DeathpactNumberOfPlayersInPact": "Number of players in Death Pact", - "DeathpactShowArrowsToOtherPlayersInPact": "Show arrows leading to other players in Death Pact", - "DeathpactReduceVisionWhileInPact": "Reduce vision for players in Death Pact", - "DeathpactVisionWhileInPact": "Vision for players in Death Pact", - "DeathpactKillPlayersInDeathpactOnMeeting": "Kill players in Death Pact on meeting", - "DeathpactPlayersInDeathpactCanCallMeeting": "Players in active Death Pact can call meeting", - "DeathpactActiveDeathpact": "Find {0} in {1} seconds.", - "DeathpactCouldNotAddTarget": "Target can't be added to Death Pact.", - "DeathpactComplete": "Death Pact was concluded.", - "DeathpactExecuted": "Death Pact was executed.", - "DeathpactAverted": "Death Pact was averted.", - "DeathpactButtonText": "Assign", - "DevourerHideNameConsumed": "Hide the names of consumed players", - "DevourCooldown": "Devour Cooldown", - "DevourerButtonText": "Devour", - "DollMasterPossessionButtonText": "Possess", - "DollMasterUnPossessionButtonText": "UnPossess", - "DollMaster_PossessedTarget": "Possessed target", - "DollMaster_CannotPossessImpTeammate": "Unable to possess teammate", - "DollMaster_CouldNotSwapWithTarget": "Unable to possess player", - "DollMaster_CanNotSwapWithDeadTarget": "Possesing a dead player isn't possible", - "DollMaster_MainBody": "Main Body", - "DollMaster_Doll": "Doll", - "DollMaster_UnableToUseAbility": "Unable to use your ability on player", - "Doppelganger_RoleInfo": "Spoofed Role: {0}", - "EatenByDevourer": "The Devourer ate your skin", - "DevourerEatenSkin": "Target skin is eaten", - "DevouredName": "Devoured", - "PitfallTrapCooldown": "Trap Cooldown", - "PitfallMaxTrapCount": "Number of Traps that can be set", - "PitfallTrapMaxPlayerCount": "Number of Players that can be caught per Trap", - "PitfallTrapDuration": "Time the Trap remains active", - "PitfallTrapRadius": "Trap Radius", - "PitfallTrapFreezeTime": "Trap freeze time", - "PitfallTrapCauseVision": "Trap caused vision", - "PitfallTrapCauseVisionTime": "Trap caused vision time", - "PitfallTrap": "You have fallen into a trap!", - "ConsigliereDivinationMaxCount": "Maximum Reveals", - "RitualMaxCount": "Maximum Reveals", - "CleanserHideVote": "Hide Cleanser's vote", - "OracleSkillLimit": "Maximum Uses", - "OracleHideVote": "Hide Oracle's vote", - "OracleCheckReachLimit": "You're out of uses!", - "OracleCheckSelfMsg": "You can't even trust yourself, huh?", - "OracleCheckLimit": "Reminder: You have {0} uses left", - "OracleCheckMsgTitle": "ORACLE ", - "OracleCheck.NotCrewmate": "Appears not to be a crewmate", - "OracleCheck.Crewmate": "Appears to be a crewmate", - "OracleCheck.Neutral": "Appears to be a neutral", - "OracleCheck.Impostor": "Appears to be an Impostor", - "OracleCheck": "Target Results:", - "FailChance": "Chance of showing incorrect result", - "OracleCheckAddons": "Oracle checks add-ons", - "ChameleonCanVent": "Vent to disguise", - "ChameleonInvisState": "You are disguising!", - "ChameleonInvisStateOut": "Your disguise ended", - "ChameleonInvisInCooldown": "Ability still on cooldown, disguise failed", - "ChameleonInvisStateCountdown": "Disguise will expire in {0}s", - "ChameleonInvisCooldownRemain": "Disguise Cooldown: {0}s", - "ChameleonCooldown": "Disguise Cooldown", - "ChameleonDuration": "Disguise Duration", - "ChameleonRevertDisguise": "Expose", - "ChameleonDisguise": "Disguise", - "KillCooldownAfterCleaning": "Kill Cooldown On Clean", - "KillCooldownAfterStoneGazing": "Kill Cooldown On Stone Gaze", - "MedusaStoneBody": "Body stoned", - "MedusaReportButtonText": "Stone", - - "CursedSoulCurseCooldown": "Soul Snatch Cooldown", - "CursedSoulCurseCooldownIncrese": "Soul Snatch Cooldown Increase", - "CursedSoulCurseMax": "Maximum Soul Snatches", - "CursedSoulKnowTargetRole": "Know the roles of Soulless players", - "CursedSoulCanCurseNeutral": "Neutral roles have souls", - "CursedSoulKillButtonText": "Snatch", - "SoullessByCursedSoul": "A Cursed Soul snatched your soul", - "CursedSoulSoullessPlayer": "Soul snatched", - "CursedSoulInvalidTarget": "No soul found", - - "AdmireCooldown": "Admire Cooldown", - "AdmirerKnowTargetRole": "Know the roles of Admired players", - "AdmirerSkillLimit": "Skill Limit", - "AdmireButtonText": "Admire", - "AdmirerAdmired": "The Admirer admired you!", - "AdmiredPlayer": "Player admired", - "AdmirerInvalidTarget": "Target cannot be admired", - - "SpiritualistNoticeTitle": "SPIRITUALIST ", - "SpiritualistNoticeMessage": "The Spiritualist has an arrow pointing to you!\nYou can use them to a killer or frame a crewmate", - "SpiritualistShowGhostArrowForSeconds": "Ghost arrow duration", - "SpiritualistShowGhostArrowEverySeconds": "Ghost arrow interval", - "EnigmaClueStage1Tasks": "Number of Tasks to complete to see Stage 1 Clues", - "EnigmaClueStage2Tasks": "Number of Tasks to complete to see Stage 2 Clues", - "EnigmaClueStage3Tasks": "Number of Tasks to complete to see Stage 3 Clues", - "EnigmaClueStage2Probability": "Probability to see Stage 2 Clues", - "EnigmaClueStage3Probability": "Probability to see Stage 3 Clues", - "EnigmaClueGetCluesWithoutReporting": "Enigma can get Clues without reporting a dead body", - "EnigmaClueHat1": "The Killer wears a Hat!", - "EnigmaClueHat2": "The Killer does not wear a Hat!", - "EnigmaClueHat3": "The Killer wears {0} as a Hat!", - "EnigmaClueSkin1": "The Killer wears a Skin!", - "EnigmaClueSkin2": "The Killer does not wear a Skin!", - "EnigmaClueSkin3": "The Killer wears {0} as a Skin!", - "EnigmaClueVisor1": "The Killer wears a Visor!", - "EnigmaClueVisor2": "The Killer does not wear a Visor!", - "EnigmaClueVisor3": "The Killer wears {0} as a Visor!", - "EnigmaCluePet1": "The Killer does have a Pet!", - "EnigmaCluePet2": "The Killer does not have a Pet!", - "EnigmaCluePet3": "The Killer has {0} as a Pet!", - "EnigmaClueName1": "The Name of the Killer contains the letter {0} or the letter {1}!", - "EnigmaClueName2": "The Name of the Killer contains the letter {0}!", - "EnigmaClueName3": "The Name of the Killer contains the letter {0} and the letter {1}!", - "EnigmaClueNameLength1": "The Name of the Killer has a Length between {0} and {1} letters!", - "EnigmaClueNameLength2": "The Name of the Killer has a Length of {0} letters!", - "EnigmaClueColor1": "The Killer has a light color!", - "EnigmaClueColor2": "The Killer has a dark color!", - "EnigmaClueColor3": "The Killer's color is {0}!", - "EnigmaClueLocation": "The Last Room the Killer was in is {0}!", - "EnigmaClueStatus1": "The Killer is currently inside a Vent!", - "EnigmaClueStatus2": "The Killer is currently on a Ladder!", - "EnigmaClueStatus3": "The Killer is already Dead!", - "EnigmaClueStatus4": "The Killer is still Alive!", - "EnigmaClueRole1": "The Killer is an Impostor!", - "EnigmaClueRole2": "The Killer is a Neutral!", - "EnigmaClueRole3": "The Killer is a Crewmate!", - "EnigmaClueRole4": "The Killer's Role is {0}!", - "EnigmaClueLevel1": "The Killer's Level is above 50!", - "EnigmaClueLevel2": "The Killer's Level is below 50!", - "EnigmaClueLevel3": "The Killer's Level is between {0} and {1}!", - "EnigmaClueLevel4": "The Killer's Level is {0}!", - "EnigmaClueFriendCode": "The Killer's Friendcode is {0}!", - "EnigmaClueHatTitle": "Enigma Hat Clue!", - "EnigmaClueVisorTitle": "Enigma Visor Clue!", - "EnigmaClueSkinTitle": "Enigma Skin Clue!", - "EnigmaCluePetTitle": "Enigma Pet Clue!", - "EnigmaClueNameTitle": "Enigma Name Clue!", - "EnigmaClueNameLengthTitle": "Enigma Name Length Clue!", - "EnigmaClueColorTitle": "Enigma Color Clue!", - "EnigmaClueLocationTitle": "Enigma Location Clue!", - "EnigmaClueStatusTitle": "Enigma Status Clue!", - "EnigmaClueRoleTitle": "Enigma Role Clue!", - "EnigmaClueLevelTitle": "Enigma Level Clue!", - "EnigmaClueFriendCodeTitle": "Enigma Friendcode Clue!", - - "ImpCanBeRole": "Impostors can become {role}", - "CrewCanBeRole": "Crewmates can become {role}", - "NeutralCanBeRole": "Neutrals can become {role}", - - "VotesPerKill": "Votes gained for each kill", - "PickpocketGetVote": "You've got {0} votes", - "VultureArrowsPointingToDeadBody": "Arrows pointing to dead bodies", - "VultureNumberOfReportsToWin": "Bodies needed to win", - "VultureReportBody": "Body eaten!", - "VultureEatButtonText": "Consume", - "VultureReportCooldown": "Eat Cooldown", - "VultureMaxEatenInOneRound": "Maximum eaten bodies possible per round", - "VultureCooldownUp": "Eat Cooldown finished", - - "GhastlyPossessCD": "Possess Cooldown", - "GhastlyMaxPossessions": "Max Possessions", - "GhastlyPossessionDuration": "Possession Duration", - "GhastlySpeed": "Ghastly Speed", - "GhastlyKillAllies": "Ghastly cannot possess allies", - "GhastlyCannotPossessTarget": "Couldn't Possess Target", - "GhastlyChooseTarget": "Now: Choose Target", - "GhastlyNoMorePossess": "You've run out of possessions!'", - "GhastlyNotUrTarget": "That is not your target", - "GhastlyYouvePosses": "You've Been Possessed!", - "GhastlyPossessedUser": "You have possessed: {0}", - "GhastlyExpired": "{0} is no longer possessed", - - "TasksMarkPerRound": "Number of tasks that can be marked in one round", - "TaskinatorBombPlanted": "Bomb has been planted", - - "ShieldDuration": "Shield duration", - "ShieldIsOneTimeUse": "Shield breaks after one kill attempt", - "BenefactorTaskMarked": "Task marked successfully", - "BenefactorTargetGotShield": "You got a shield by Benefactor", - - "PirateTryHideMsg": "Hide Pirate's commands", - "SuccessfulDuelsToWin": "Number of successful duels needed to win", - "PirateMeetingMsg": "Duel with your target.\n\nDuel command:\n⦿ /duel 0\n⦿ /duel 1\n⦿ /duel 2\n\nYou win the Duel if you choose the same option as the target", - "PirateTargetMeetingMsg": "The Pirate chose t' duel ye!\nDuel wit' honor or die o' shame.\n\n Duel command:\n⦿ /duel 0\n⦿ /duel 1\n⦿ /duel 2\n\nIf the Pirate chooses the same option as you or you don't participate, you'll die", - "PirateTitle": "PIRATE ", - "PirateTargetAlreadyChosen": "Yarr! Ye've already chosen a target.", - "PirateDead": "Ye be dead. Ye cannot duel anymore.", - "DuelAlreadyDone": "Ye 'ave already chosen an option fer the duel.", - "DuelDone": "Ye 'ave chosen yer option fer the Duel.\nWait fer the meetin' to end to see the result.", - "DuelHelp": "Duel command:\n⦿ /duel 0\n⦿ /duel 1\n⦿ /duel 2\n\nAs Pirate, try to choose the same number as the target.\nAs the target, try to choose a different number than the Pirate", - "PirateDuelButtonText": "Duel", - "DuelCooldown": "Duel Cooldown", - "Rock": "Rock", - "Paper": "Paper", - "Scissors": "Scissors", - "Heads": "Heads", - "Tails": "Tails", - "SpyRedNameDur": "Colored Name Duration", - "SpyInteractionBlocked": "Block kill button interaction", - "AgitaterBombCooldown": "Agitator bomb cooldown", - "AgitaterPassCooldown": "Bomb pass cooldown", - "BombExplodeCooldown": "Bomb explode cooldown", - "AgitaterPassNotify": "Bomb successfully passed", - "AgitaterTargetNotify": "YOU HAVE THE BOMB!! Pass it to someone else", - "AgitaterCanGetBombed": "Agitator can get bomb", - "AgitaterAutoReportBait": "Agitator Auto Report Bait", - - "SeekerPointsToWin": "Number of points required to win", - "SeekerTagCooldown": "Tag Cooldown", - "SeekerNotify": "Your target is {0}", - "SeekerTargetNotify": "You are Seekers target!! Hide before they tag you", - "SeekerKillButtonText": "Tag", - - "PixiePointsToWin": "Number of points required to win", - "MaxTargets": "Maximum number of targets per round", - "MarkCooldown": "Mark cooldown", - "PixieSuicide": "Pixie suicides if the target is not voted out", - "PixieMaxTargetReached": "You have already selected all the targets this round", - "PixieTargetAlreadySelected": "Target is already selected", - "PixieButtonText": "Mark", - - "PlagueBearerCooldown": "Plague cooldown", + "RememberedImitator": "You remembered you were an Imitator.", + "RememberedImpostor": "You remembered you were an Impostor!", + "RememberedCrewmate": "You remembered you were a crewmate!", + "ImitatorImitated": "An Imitator imitated your role!", + "ImitatorInvalidTarget": "Imitation failed", + "RememberButtonText": "Remember", + "ImitatorKillButtonText": "Imitate", + "IncompatibleNeutralMode": "If neutral is incompatible, turn into", + "RememberedYourRole": "An Amnesiac remembered your role!", + "YouRememberedRole": "You remembered who you were!", + + "BanditStealMode": "Steal Mode", + "BanditStealMode_OnMeeting": "On Meeting", + "BanditStealMode_Instantly": "Instantly", + "BanditMaxSteals": "Maximum Steals", + "BanditCanStealBetrayalAddon": "Can Steal Betrayal Add-ons", + "BanditCanStealImpOnlyAddon": "Can Steal Impostor Only Addons", + "Bandit_NoStealableAddons": "Could not steal add-on from the player", + "BanditStealCooldown": "Steal cooldown", + + "DoppelMaxSteals": "Maximum Steals", + "DoppelCurrentVictimCanSeeRolesAsDead": "Last victim can see role and add-on info of alive players as a ghost", + + "NecromancerRevengeTime": "Necromancy time", + "NecromancerRevenge": "You have {0}s to kill {1}", + "NecromancerSuccess": "Necromancy complete! You live to see another day.", + "NecromancerHide": "Venting is disabled, hide from the Necromancer!", + "RetributionistDeadMsg": "The death of the Retributionist means the beginning of retribution. \nPlease use /ret + [player ID] to kill the specified player \nYou can see player IDs in front of their names. \nOr type /ret to get a list of player IDs", + "RetributionistAliveKill": "Retribution for the Retributionist may only begin after their death.", + "RetributionistKillMax": "You've reached the maximum amount of kills. You can't kill anymore!", + "RetributionistKillDead": "Choose a living player to kill.", + "RetributionistKillSucceed": "{0} was killed by the Retributionist!", + "RetributionistKillDisable": "You can't retribute until your tasks are done.", + "CanOnlyRetributeWithTasksDone": "Can only retribute on task completion", + "RetributionistCanKillNum": "Max retributions", + "RetributionistKillTooManyDead": "Too many players are dead. You can't retribute.", + "MinimumPlayersAliveToRetri": "Minimum players alive to retribute", + "MinimumNoKillerEjectsToKill": "Minimum meetings passed with no killer ejects to kill", + "ImmuneToAttacksWhenTasksDone": "Immune to attacks on task completion", + + "TwisterCooldown": "Twist Cooldown", + "TwisterButtonText": "Twist", + "TwisterHideTwistedPlayerNames": "Hide who the players swap places with", + "InstigatorAbilityLimit": "Ability Use Count", + "InstigatorKillsPerAbilityUse": "Kills per Ability use", + + "CrewCanFindCaptain": "Crewmates can find Captain", + "MadmateCanFindCaptain": "Madmates can find Captain", + "ReducedSpeed": "Reduced speed", + "ReducedSpeedTime": "Time duration for reduced speed", + "CaptainCanTargetNB": "Captain can target Neutral Benign", + "CaptainCanTargetNE": "Captain can target Neutral Evil", + "CaptainCanTargetNC": "Captain can target Neutral Chaos", + "CaptainCanTargetNA": "Captain can target Neutral Apocalypse", + "CaptainCanTargetNK": "Captain can target Neutral Killer", + "CaptainSpeedReduced": "Captain reduced your speed", + "CaptainRevealTaskRequired": "Number of tasks completed after which Captain is revealed", + "CaptainSlowTaskRequired": "Number of tasks completed after which target speed is reduced", + + "InspectorTryHideMsg": "Hide Inspector's commands", + "MaxInspectCheckLimit": "Max inspections per game", + "InspectCheckLimitPerMeeting": "Max inspections per meeting", + "InspectCheckTargetKnow": "Targets know they were checked by Inspector", + "InspectCheckOtherTargetKnow": "Targets know who they were checked with", + "InspectorDead": "You can not use your power after death", + "InspectCheckMax": "Max inspections per game reached!\nYou can not use your power anymore.", + "InspectCheckRound": "Max inspections per round reached!\nYou can check again in the next round.", + "InspectCheckSelf": "HA!! You thought it would be this easy. You can not check yourself", + "InspectCheckReveal": "HA! You thought it would be this easy. You can not check a role that is revealed", + "InspectCheckTitle": "INSPECTOR ", + "InspectCheckTrue": "{0} and {1} are in the same team!", + "InspectCheckFalse": "{0} and {1} are NOT in the same team!", + "InspectCheckTargetMsg": " were checked by Inspector.", + "InspectCheckHelp": "Instructions: /cmp [Player ID 1] [Player ID 2] \nExample: /cmp 1 5 \nYou can see the player IDs before everyone's names \n or use the /id command to list the player IDs", + "InspectCheckNull": "Please select an ID of a living player to check their team", + "InspectCheckBaitCountMode": "Bait counts as revealing role if Bait reveal on first meeting is on", + "InspectCheckRevealTarget": "When tasks are done, the target knows the team of the other target", + "InspectorTargetReveal": " Looks like {0} is aligned with team {1}", + + "EgoistCountMode.Original": "Original", + "EgoistCountMode.Neutral": "Neutral", + + "JailerJailCooldown": "Jail cooldown", + "JailerMaxExecution": "Maximum executions", + "JailerNBCanBeExe": "Can execute Neutral Benign", + "JailerNCCanBeExe": "Can execute Neutral Chaos", + "JailerNECanBeExe": "Can execute Neutral Evil", + "JailerNKCanBeExe": "Can execute Neutral Killing", + "JailerNACanBeExe": "Can execute Neutral Apocalypse", + "JailerCKCanBeExe": "Can execute Crew Killing", + "JailerTargetAlreadySelected": "You have already selected a target", + "SuccessfullyJailed": "Target successfully jailed", + "CantGuessJailed": "You can not guess the target", + "JailedCanOnlyGuessJailer": "You have been jailed. You can only guess Jailer.", + "CanNotTrialJailed": "You can not trial the target.", + "notifyJailedOnMeeting": "Notify jailed player when a meeting starts", + "JailedNotifyMsg": "The Jailer has jailed you. No one can guess or judge you. You can only guess The Jailer.\n\nIf Jailer votes you, you will be executed after the meeting ends.", + "JailerTitle": "Jailer", + + "CopyCatCopyCooldown": "Copy cooldown", + "CopyCatRoleChange": "Your role has been changed to {0}", + "CopyCatCanNotCopy": "You can not copy the target's role", + "CopyButtonText": "Copy", + "CopyCrewVar": "Can copy evil variants of crew roles", + "CopyTeamChangingAddon": "Can copy team changing add-on", + + "MaxCleanserUses": "Max cleanses", + "CleansedCanGetAddon": "Cleansed player can get Add-on", + "CleanserTitle": "CLEANSER", + "CleanserRemoveSelf": "You can not cleanse yourself", + "CleanserCantRemove": "Oops! the player can not be cleansed.", + "CleanserRemovedRole": "{0} has been cleansed. All their Add-ons will be removed after the meeting.\n\nYour vote has been returned and you can vote for someone.", + "LostAddonByCleanser": "The cleanser removed all your Add-ons", + + "MaxProtections": "Max protections", + "KeeperHideVote": "Hide Keeper's vote", + "KeeperProtect": "You chose to protect {0}, your vote has been returned", + "KeeperTitle": "Keeper", + + "MaulRadius": "Maul Radius", + "ImpKnowCyberDead": "Impostors know if Cyber died", + "CrewKnowCyberDead": "Crewmates know if Cyber died", + "NeutralKnowCyberDead": "Neutrals know if Cyber died", + "CyberKnown": "Everyone can see Cyber", + "KillerGetBewilderVision": "Killer gets Bewilder's vision", + "ImpCanBeOiiai": "Impostors can be OIIAI", + "CrewCanBeOiiai": "Crewmates can be OIIAI", + "NeutralCanBeOiiai": "Neutrals can be OIIAI", + "OiiaiCanPassOn": "OIIAI can pass on to the killer", + "NeutralChangeRolesForOiiai": "Neutrals turns to ", + "LostRoleByOiiai": "You got erased by OIIAI!", + "ImpCanBeLoyal": "Impostors can become Loyal", + "CrewCanBeLoyal": "Crewmates can become Loyal", + "TasklessCrewCanBeLazy": "Crewmates without tasks can be Lazy", + "TaskBasedCrewCanBeLazy": "Task based crewmates can be Lazy", + "SheriffCanBeMadmate": "Sheriff can become Madmate", + "MayorCanBeMadmate": "Mayor can become Madmate", + "NGuesserCanBeMadmate": "Nice Guesser can become Madmate", + "SnitchCanBeMadmate": "Snitch can become Madmate", + "JudgeCanBeMadmate": "Judge can become Madmate", + "MarshallCanBeMadmate": "Marshall can become Madmate", + "GanRetributionistCanBeMadmate": "Retributionist can be converted", + "RetributionistCanBeMadmate": "Retributionist can become Madmate", + "OverseerCanBeMadmate": "Overseer can become Madmate", + "GanSheriffCanBeMadmate": "Sheriff can be converted", + "GanMayorCanBeMadmate": "Mayor can be converted", + "GanNGuesserCanBeMadmate": "Nice Guesser can be converted", + "GanJudgeCanBeMadmate": "Judge can be converted", + "GanMarshallCanBeMadmate": "Marshall can be converted", + "GanOverseerCanBeMadmate": "Overseer can be converted", + "RascalAppearAsMadmate": "Appear As Madmate On Ejection", + + "CouncillorDead": "Sorry, you can't murder from the dead.", + "CouncillorMurderMaxMeeting": "Sorry, you've reached the maximum amount of murders for the meeting.", + "CouncillorMurderMaxGame": "Sorry, you've reached the maximum amount of murders for the game.", + "Councillor_LaughToWhoMurderSelf": "Hahaha, who would've thought someone was stupid enough to murder themselves?\n\nGuess it happens to be... YOU!", + "Councillor_MurderKill": "{0} was murdered.", + "Councillor_MurderHelp": "Command: /tl [player ID]\nYou can see the players' IDs before the players' names.\nOr use /id to view the list of all player IDs.", + "Councillor_MurderNull": "Please choose a living player to murder.", + "Councillor_MurderKillTitle": "WICKED COURT ", + "CouncillorMakeEvilJudgeClear": "Show Trial as Councillor Murder", + "Councillor_CannotMurderImpTeam": "Sorry, you can not murder your teammate.", + "Councillor_SuicideForMurderImps": "You died because you are trying to murder your team members.", + "CouncillorMurderLimitPerMeeting": "Maximum Kills Per Meeting", + "CouncillorMurderLimitPerGame": "Maximum Kills Per Game", + "CouncillorCanMurderMadmate": "Can Murder Madmates", + "CouncillorCanMurderImpostor": "Can Murder Impostors", + "CouncillorSuicideOnJudgeImpTeam": "Suicide when judge Impostors Team Wrongly", + "CouncillorCanMurderTaskDoneSnitch": "Can Murder Snitch with All Tasks Done", + "CouncillorTryHideMsg": "Try to hide Councillor's commands", + + "DazzlerDazzled": "You were dazzled by the Dazzler!", + "DazzlerCauseVision": "Reduced vision", + "DazzlerDazzleLimit": "Max number of players affected by reduced vision", + "DazzlerResetDazzledVisionOnDeath": "Reset vision of dazzled players on death/eject", + "DazzleCooldown": "Dazzle Cooldown", + "DazzleButtonText": "Dazzle", + + "MoleVentButtonText": "Dig", + "MoleVentCooldown": "Dig cooldown", + + "AddictVentButtonText": "Get Fix", + "AddictInvulnerbilityTimeAfterVent": "Invulnerability Time", + "AddictSpeedWhileInvulnerble": "Movement speed while Invulnerable", + + "AddictFreezeTimeAfterInvulnerbility": "Time the Addict gets frozen in place after Invulnerability", + "AlchemistShieldDur": "Resistance Potion Duration", + "AlchemistInvisDur": "Invisibility Potion Duration", + "AlchemistVision": "Night Vision", + "AlchemistVisionOnLightsOut": "Night Vision During Lights Sabotage", + "AlchemistVisionDur": "Night Vision Potion Duration", + "AlchemistSpeed": "Speed Potion Boost", + "AlchemistVentButtonText": "Drink", + "AlchemistGotShieldPotion": "Potion of Resistance: Grants a temporary shield", + "AlchemistGotSightPotion": "Potion of Night Vision: Gives temporary enhanced vision", + "AlchemistGotQFPotion": "Potion of Fixing: Allows you to fix one sabotage instantly", + "AlchemistGotTPPotion": "Potion of Warping: Teleports you to a random player", + "AlchemistGotSuicidePotion": "Potion of Poison: Poisons you", + "AlchemistGotSpeedPotion": "Potion Of Speed: Hastens you", + "AlchemistGotBloodthirstPotion": "Potion of Harming: Kill the next player you touch", + "AlchemistGotInvisibility": "Potion of Invisibility: Become Invisible", + "NoPotion": "You have no potions", + + "StoreShield": "Potion of Resistance", + "StoreSuicide": "Potion of Poison", + "StoreTP": "Potion of Warping", + "StoreSP": "Potion Of Speed", + "StoreQF": "Potion of Fixing", + "StoreBL": "Potion of Harming", + "StoreNS": "Potion of Night Vision", + "StoreINV": "Potion of Invisibility", + "StoreNull": "None", + "PotionStore": "Potion in store: ", + "WaitQFPotion": "\nPotion of Fixing waiting for use", + + "AlchemistShielded": "Potion of Resistance started", + "AlchemistHasVision": "Potion of Night Vision started", + "AlchemistShieldOut": "Potion of Resistance ended", + "AlchemistVisionOut": "Potion of Night Vision ended", + "AlchemistPotionBloodthirst": "You gained bloodthirst", + "AlchemistHasSpeed": "Potion Of Speed started", + "AlchemistSpeedOut": "Potion Of Speed ended", + + "DeathpactDuration": "Death Pact duration", + "DeathPactCooldown": "Death Pact Assign Cooldown", + "DeathpactNumberOfPlayersInPact": "Number of players in Death Pact", + "DeathpactShowArrowsToOtherPlayersInPact": "Show arrows leading to other players in Death Pact", + "DeathpactReduceVisionWhileInPact": "Reduce vision for players in Death Pact", + "DeathpactVisionWhileInPact": "Vision for players in Death Pact", + "DeathpactKillPlayersInDeathpactOnMeeting": "Kill players in Death Pact on meeting", + "DeathpactPlayersInDeathpactCanCallMeeting": "Players in active Death Pact can call meeting", + "DeathpactActiveDeathpact": "Find {0} in {1} seconds.", + "DeathpactCouldNotAddTarget": "Target can't be added to Death Pact.", + "DeathpactComplete": "Death Pact was concluded.", + "DeathpactExecuted": "Death Pact was executed.", + "DeathpactAverted": "Death Pact was averted.", + "DeathpactButtonText": "Assign", + "DevourerHideNameConsumed": "Hide the names of consumed players", + "DevourCooldown": "Devour Cooldown", + "DevourerButtonText": "Devour", + "DollMasterPossessionButtonText": "Possess", + "DollMasterUnPossessionButtonText": "UnPossess", + "DollMaster_PossessedTarget": "Possessed target", + "DollMaster_CannotPossessImpTeammate": "Unable to possess teammate", + "DollMaster_CouldNotSwapWithTarget": "Unable to possess player", + "DollMaster_CanNotSwapWithDeadTarget": "Possesing a dead player isn't possible", + "DollMaster_MainBody": "Main Body", + "DollMaster_Doll": "Doll", + "DollMaster_UnableToUseAbility": "Unable to use your ability on player", + "Doppelganger_RoleInfo": "Spoofed Role: {0}", + "EatenByDevourer": "The Devourer ate your skin", + "DevourerEatenSkin": "Target skin is eaten", + "DevouredName": "Devoured", + "PitfallTrapCooldown": "Trap Cooldown", + "PitfallMaxTrapCount": "Number of Traps that can be set", + "PitfallTrapMaxPlayerCount": "Number of Players that can be caught per Trap", + "PitfallTrapDuration": "Time the Trap remains active", + "PitfallTrapRadius": "Trap Radius", + "PitfallTrapFreezeTime": "Trap freeze time", + "PitfallTrapCauseVision": "Trap caused vision", + "PitfallTrapCauseVisionTime": "Trap caused vision time", + "PitfallTrap": "You have fallen into a trap!", + "ConsigliereDivinationMaxCount": "Maximum Reveals", + "RitualMaxCount": "Maximum Reveals", + "CleanserHideVote": "Hide Cleanser's vote", + "OracleSkillLimit": "Maximum Uses", + "OracleHideVote": "Hide Oracle's vote", + "OracleCheckReachLimit": "You're out of uses!", + "OracleCheckSelfMsg": "You can't even trust yourself, huh?", + "OracleCheckLimit": "Reminder: You have {0} uses left", + "OracleCheckMsgTitle": "ORACLE ", + "OracleCheck.NotCrewmate": "Appears not to be a crewmate", + "OracleCheck.Crewmate": "Appears to be a crewmate", + "OracleCheck.Neutral": "Appears to be a neutral", + "OracleCheck.Impostor": "Appears to be an Impostor", + "OracleCheck": "Target Results:", + "FailChance": "Chance of showing incorrect result", + "OracleCheckAddons": "Oracle checks add-ons", + "ChameleonCanVent": "Vent to disguise", + "ChameleonInvisState": "You are disguising!", + "ChameleonInvisStateOut": "Your disguise ended", + "ChameleonInvisInCooldown": "Ability still on cooldown, disguise failed", + "ChameleonInvisStateCountdown": "Disguise will expire in {0}s", + "ChameleonInvisCooldownRemain": "Disguise Cooldown: {0}s", + "ChameleonCooldown": "Disguise Cooldown", + "ChameleonDuration": "Disguise Duration", + "ChameleonRevertDisguise": "Expose", + "ChameleonDisguise": "Disguise", + "KillCooldownAfterCleaning": "Kill Cooldown On Clean", + "KillCooldownAfterStoneGazing": "Kill Cooldown On Stone Gaze", + "MedusaStoneBody": "Body stoned", + "MedusaReportButtonText": "Stone", + + "CursedSoulCurseCooldown": "Soul Snatch Cooldown", + "CursedSoulCurseCooldownIncrese": "Soul Snatch Cooldown Increase", + "CursedSoulCurseMax": "Maximum Soul Snatches", + "CursedSoulKnowTargetRole": "Know the roles of Soulless players", + "CursedSoulCanCurseNeutral": "Neutral roles have souls", + "CursedSoulKillButtonText": "Snatch", + "SoullessByCursedSoul": "A Cursed Soul snatched your soul", + "CursedSoulSoullessPlayer": "Soul snatched", + "CursedSoulInvalidTarget": "No soul found", + + "AdmireCooldown": "Admire Cooldown", + "AdmirerKnowTargetRole": "Know the roles of Admired players", + "AdmirerSkillLimit": "Skill Limit", + "AdmireButtonText": "Admire", + "AdmirerAdmired": "The Admirer admired you!", + "AdmiredPlayer": "Player admired", + "AdmirerInvalidTarget": "Target cannot be admired", + + "SpiritualistNoticeTitle": "SPIRITUALIST ", + "SpiritualistNoticeMessage": "The Spiritualist has an arrow pointing to you!\nYou can use them to a killer or frame a crewmate", + "SpiritualistShowGhostArrowForSeconds": "Ghost arrow duration", + "SpiritualistShowGhostArrowEverySeconds": "Ghost arrow interval", + "EnigmaClueStage1Tasks": "Number of Tasks to complete to see Stage 1 Clues", + "EnigmaClueStage2Tasks": "Number of Tasks to complete to see Stage 2 Clues", + "EnigmaClueStage3Tasks": "Number of Tasks to complete to see Stage 3 Clues", + "EnigmaClueStage2Probability": "Probability to see Stage 2 Clues", + "EnigmaClueStage3Probability": "Probability to see Stage 3 Clues", + "EnigmaClueGetCluesWithoutReporting": "Enigma can get Clues without reporting a dead body", + "EnigmaClueHat1": "The Killer wears a Hat!", + "EnigmaClueHat2": "The Killer does not wear a Hat!", + "EnigmaClueHat3": "The Killer wears {0} as a Hat!", + "EnigmaClueSkin1": "The Killer wears a Skin!", + "EnigmaClueSkin2": "The Killer does not wear a Skin!", + "EnigmaClueSkin3": "The Killer wears {0} as a Skin!", + "EnigmaClueVisor1": "The Killer wears a Visor!", + "EnigmaClueVisor2": "The Killer does not wear a Visor!", + "EnigmaClueVisor3": "The Killer wears {0} as a Visor!", + "EnigmaCluePet1": "The Killer does have a Pet!", + "EnigmaCluePet2": "The Killer does not have a Pet!", + "EnigmaCluePet3": "The Killer has {0} as a Pet!", + "EnigmaClueName1": "The Name of the Killer contains the letter {0} or the letter {1}!", + "EnigmaClueName2": "The Name of the Killer contains the letter {0}!", + "EnigmaClueName3": "The Name of the Killer contains the letter {0} and the letter {1}!", + "EnigmaClueNameLength1": "The Name of the Killer has a Length between {0} and {1} letters!", + "EnigmaClueNameLength2": "The Name of the Killer has a Length of {0} letters!", + "EnigmaClueColor1": "The Killer has a light color!", + "EnigmaClueColor2": "The Killer has a dark color!", + "EnigmaClueColor3": "The Killer's color is {0}!", + "EnigmaClueLocation": "The Last Room the Killer was in is {0}!", + "EnigmaClueStatus1": "The Killer is currently inside a Vent!", + "EnigmaClueStatus2": "The Killer is currently on a Ladder!", + "EnigmaClueStatus3": "The Killer is already Dead!", + "EnigmaClueStatus4": "The Killer is still Alive!", + "EnigmaClueRole1": "The Killer is an Impostor!", + "EnigmaClueRole2": "The Killer is a Neutral!", + "EnigmaClueRole3": "The Killer is a Crewmate!", + "EnigmaClueRole4": "The Killer's Role is {0}!", + "EnigmaClueLevel1": "The Killer's Level is above 50!", + "EnigmaClueLevel2": "The Killer's Level is below 50!", + "EnigmaClueLevel3": "The Killer's Level is between {0} and {1}!", + "EnigmaClueLevel4": "The Killer's Level is {0}!", + "EnigmaClueFriendCode": "The Killer's Friendcode is {0}!", + "EnigmaClueHatTitle": "Enigma Hat Clue!", + "EnigmaClueVisorTitle": "Enigma Visor Clue!", + "EnigmaClueSkinTitle": "Enigma Skin Clue!", + "EnigmaCluePetTitle": "Enigma Pet Clue!", + "EnigmaClueNameTitle": "Enigma Name Clue!", + "EnigmaClueNameLengthTitle": "Enigma Name Length Clue!", + "EnigmaClueColorTitle": "Enigma Color Clue!", + "EnigmaClueLocationTitle": "Enigma Location Clue!", + "EnigmaClueStatusTitle": "Enigma Status Clue!", + "EnigmaClueRoleTitle": "Enigma Role Clue!", + "EnigmaClueLevelTitle": "Enigma Level Clue!", + "EnigmaClueFriendCodeTitle": "Enigma Friendcode Clue!", + + "ImpCanBeRole": "Impostors can become {role}", + "CrewCanBeRole": "Crewmates can become {role}", + "NeutralCanBeRole": "Neutrals can become {role}", + + "VotesPerKill": "Votes gained for each kill", + "PickpocketGetVote": "You've got {0} votes", + "VultureArrowsPointingToDeadBody": "Arrows pointing to dead bodies", + "VultureNumberOfReportsToWin": "Bodies needed to win", + "VultureReportBody": "Body eaten!", + "VultureEatButtonText": "Consume", + "VultureReportCooldown": "Eat Cooldown", + "VultureMaxEatenInOneRound": "Maximum eaten bodies possible per round", + "VultureCooldownUp": "Eat Cooldown finished", + + "GhastlyPossessCD": "Possess Cooldown", + "GhastlyMaxPossessions": "Max Possessions", + "GhastlyPossessionDuration": "Possession Duration", + "GhastlySpeed": "Ghastly Speed", + "GhastlyKillAllies": "Ghastly cannot possess allies", + "GhastlyCannotPossessTarget": "Couldn't Possess Target", + "GhastlyChooseTarget": "Now: Choose Target", + "GhastlyNoMorePossess": "You've run out of possessions!'", + "GhastlyNotUrTarget": "That is not your target", + "GhastlyYouvePosses": "You've Been Possessed!", + "GhastlyPossessedUser": "You have possessed: {0}", + "GhastlyExpired": "{0} is no longer possessed", + + "TasksMarkPerRound": "Number of tasks that can be marked in one round", + "TaskinatorBombPlanted": "Bomb has been planted", + + "ShieldDuration": "Shield duration", + "ShieldIsOneTimeUse": "Shield breaks after one kill attempt", + "BenefactorTaskMarked": "Task marked successfully", + "BenefactorTargetGotShield": "You got a shield by Benefactor", + + "PirateTryHideMsg": "Hide Pirate's commands", + "SuccessfulDuelsToWin": "Number of successful duels needed to win", + "PirateMeetingMsg": "Duel with your target.\n\nDuel command:\n⦿ /duel 0\n⦿ /duel 1\n⦿ /duel 2\n\nYou win the Duel if you choose the same option as the target", + "PirateTargetMeetingMsg": "The Pirate chose t' duel ye!\nDuel wit' honor or die o' shame.\n\n Duel command:\n⦿ /duel 0\n⦿ /duel 1\n⦿ /duel 2\n\nIf the Pirate chooses the same option as you or you don't participate, you'll die", + "PirateTitle": "PIRATE ", + "PirateTargetAlreadyChosen": "Yarr! Ye've already chosen a target.", + "PirateDead": "Ye be dead. Ye cannot duel anymore.", + "DuelAlreadyDone": "Ye 'ave already chosen an option fer the duel.", + "DuelDone": "Ye 'ave chosen yer option fer the Duel.\nWait fer the meetin' to end to see the result.", + "DuelHelp": "Duel command:\n⦿ /duel 0\n⦿ /duel 1\n⦿ /duel 2\n\nAs Pirate, try to choose the same number as the target.\nAs the target, try to choose a different number than the Pirate", + "PirateDuelButtonText": "Duel", + "DuelCooldown": "Duel Cooldown", + "Rock": "Rock", + "Paper": "Paper", + "Scissors": "Scissors", + "Heads": "Heads", + "Tails": "Tails", + "SpyRedNameDur": "Colored Name Duration", + "SpyInteractionBlocked": "Block kill button interaction", + "AgitaterBombCooldown": "Agitator bomb cooldown", + "AgitaterPassCooldown": "Bomb pass cooldown", + "BombExplodeCooldown": "Bomb explode cooldown", + "AgitaterPassNotify": "Bomb successfully passed", + "AgitaterTargetNotify": "YOU HAVE THE BOMB!! Pass it to someone else", + "AgitaterCanGetBombed": "Agitator can get bomb", + "AgitaterAutoReportBait": "Agitator Auto Report Bait", + + "SeekerPointsToWin": "Number of points required to win", + "SeekerTagCooldown": "Tag Cooldown", + "SeekerNotify": "Your target is {0}", + "SeekerTargetNotify": "You are Seekers target!! Hide before they tag you", + "SeekerKillButtonText": "Tag", + + "PixiePointsToWin": "Number of points required to win", + "MaxTargets": "Maximum number of targets per round", + "MarkCooldown": "Mark cooldown", + "PixieSuicide": "Pixie suicides if the target is not voted out", + "PixieMaxTargetReached": "You have already selected all the targets this round", + "PixieTargetAlreadySelected": "Target is already selected", + "PixieButtonText": "Mark", + + "PlagueBearerCooldown": "Plague cooldown", "PlagueBearerCanVent": "Can vent", "PlagueBearerHasImpostorVision": "Has Impostor vision", - "PestilenceCooldown": "Pestilence Kill cooldown", - "PestilenceCanVent": "Pestilence Can Vent", - "PestilenceHasImpostorVision": "Pestilence Has Impostor Vision", - "PestilenceKillGuessers": "Kill players who guess Pestilence", - "PlagueBearerAlreadyPlagued": "Player has already been plagued", - "PlagueBearerToPestilence": "You have turned into Pestilence!!", - "GuessPestilence": "You just tried to guess Pestilence!\n\nSorry, Pestilence killed you.", - "PestilenceTransform": "A Plague has consumed the Crew, transforming the Plaguebearer into Pestilence, Horseman of the Apocalypse!", - "RomanticBetCooldown": "Pick Partner Cooldown", - "RomanticProtectCooldown": "Protect Cooldown", - "RomanticBetPlayer": "You picked your partner", - "RomanticBetOnYou": "The Romantic chose you as their Partner!", - "VengefulKCD": "Vengeful Romantic Kill Cooldown", - "VengefulCanVent": "Vengeful Romantic Can Vent", - "RuthlessKCD": "Ruthless Romantic Kill Cooldown", - "RuthlessCanVent": "Ruthless Romantic Can Vent", - "RomanticProtectPartner": "Your partner is under protection", - "RomanticIsProtectingYou": "The Romantic is protecting you", - "ProtectingOver": "Shield expired", - "RomanticProtectDuration": "Protect Duration", - "RomanticKnowTargetRole": "Romantic knows their target's role", - "RomanticBetTargetKnowRomantic": "Target knows who the Romantic is", - "RomanticPartnerButtonText": "Pick Partner", - "RomanticProtectButtonText": "Protect", - - "GuessMasterMisguess": "{0} misguessed", - "GuessMasterTargetRole": "Someone tried to guess {0}", - "GuessMasterTitle": "Guess Master ", - - "DoomsayerAmountOfGuessesToWin": "Amount of Guesses to win", - "DCanGuessImpostors": "Can Guess Impostors", - "DCanGuessCrewmates": "Can Guess Crewmates", - "DCanGuessNeutrals": "Can Guess Neutrals", - "DCanGuessAdt": "Can Guess Add-Ons", - "DoomsayerAdvancedSettings": "Advanced Settings", - "DoomsayerMaxNumberOfGuessesPerMeeting": "Max number of guesses per meeting", - "DoomsayerKillCorrectlyGuessedPlayers": "Kill correctly guessed players", - "DoomsayerDoesNotSuicideWhenMisguessing": "Doomsayer does not suicide when misguessing", - "DoomsayerMisguessRolePrevGuessRoleUntilNextMeeting": "Misguessing role prevents guessing roles until next meeting", - "DoomsayerTryHideMsg": "Hide Doomsayer's commands", - "DoomsayerCantGuess": "Sorry, you can only guess the roles in the next meeting.", - "DoomsayerCorrectlyGuessRole": "You guessed the role correctly!\nBut the player didn't die because the Host settings don't allow them to die", - "DoomsayerNotCorrectlyGuessRole": "You didn't correctly guess the role!\nBut you didn't die because the Host's settings don't allow you to die", - "DoomsayerGuessCountMsg": "You correctly guessed {0} roles", - "DoomsayerGuessCountTitle": "DOOMSAYER", - "DoomsayerGuessSameRoleAgainMsg": "You tried to guess the same role or add-on that you guessed before", - - "EveryoneCanKnowMini": "Everyone can see the Mini", - "CanBeEvil": "Mini can be an Impostor", - "EvilMiniSpawnChances": "Probability of Mini being an Impostor", + "PestilenceCooldown": "Pestilence Kill cooldown", + "PestilenceCanVent": "Pestilence Can Vent", + "PestilenceHasImpostorVision": "Pestilence Has Impostor Vision", + "PlagueBearerAlreadyPlagued": "Player has already been plagued", + "PlagueBearerToPestilence": "You have turned into Pestilence!!", + "GuessPestilence": "You just tried to guess Pestilence!\n\nSorry, Pestilence killed you.", + "PestilenceTransform": "A Plague has consumed the Crew, transforming the Plaguebearer into Pestilence, Horseman of the Apocalypse!", + "RomanticBetCooldown": "Pick Partner Cooldown", + "RomanticProtectCooldown": "Protect Cooldown", + "RomanticBetPlayer": "You picked your partner", + "RomanticBetOnYou": "The Romantic chose you as their Partner!", + "VengefulKCD": "Vengeful Romantic Kill Cooldown", + "VengefulCanVent": "Vengeful Romantic Can Vent", + "RuthlessKCD": "Ruthless Romantic Kill Cooldown", + "RuthlessCanVent": "Ruthless Romantic Can Vent", + "RomanticProtectPartner": "Your partner is under protection", + "RomanticIsProtectingYou": "The Romantic is protecting you", + "ProtectingOver": "Shield expired", + "RomanticProtectDuration": "Protect Duration", + "RomanticKnowTargetRole": "Romantic knows their target's role", + "RomanticBetTargetKnowRomantic": "Target knows who the Romantic is", + "RomanticPartnerButtonText": "Pick Partner", + "RomanticProtectButtonText": "Protect", + + "GuessMasterMisguess": "{0} misguessed", + "GuessMasterTargetRole": "Someone tried to guess {0}", + "GuessMasterTitle": "Guess Master ", + + "DoomsayerAmountOfGuessesToWin": "Amount of Guesses to win", + "DCanGuessImpostors": "Can Guess Impostors", + "DCanGuessCrewmates": "Can Guess Crewmates", + "DCanGuessNeutrals": "Can Guess Neutrals", + "DCanGuessAdt": "Can Guess Add-Ons", + "DoomsayerAdvancedSettings": "Advanced Settings", + "DoomsayerMaxNumberOfGuessesPerMeeting": "Max number of guesses per meeting", + "DoomsayerKillCorrectlyGuessedPlayers": "Kill correctly guessed players", + "DoomsayerDoesNotSuicideWhenMisguessing": "Doomsayer does not suicide when misguessing", + "DoomsayerMisguessRolePrevGuessRoleUntilNextMeeting": "Misguessing role prevents guessing roles until next meeting", + "DoomsayerTryHideMsg": "Hide Doomsayer's commands", + "DoomsayerCantGuess": "Sorry, you can only guess the roles in the next meeting.", + "DoomsayerCorrectlyGuessRole": "You guessed the role correctly!\nBut the player didn't die because the Host settings don't allow them to die", + "DoomsayerNotCorrectlyGuessRole": "You didn't correctly guess the role!\nBut you didn't die because the Host's settings don't allow you to die", + "DoomsayerGuessCountMsg": "You correctly guessed {0} roles", + "DoomsayerGuessCountTitle": "DOOMSAYER", + "DoomsayerGuessSameRoleAgainMsg": "You tried to guess the same role or add-on that you guessed before", + + "EveryoneCanKnowMini": "Everyone can see the Mini", + "CanBeEvil": "Mini can be an Impostor", + "EvilMiniSpawnChances": "Probability of Mini being an Impostor", "EvilMiniCanBeGuessed": "Evil Mini can be guessed before 18", - "GuessMini": "Sorry, you can't hurt a kid Mini.", - "GrowUpDuration": "Time required to grow (s)", - "MajorCooldown": "Kill Cooldown when over 18", - "UpDateAge": "Display age change in real-time", - "Cantkillkid": "You can't kill a Mini that hasn't grown up.", - "CantEat": "You can't eat a Mini that hasn't grown up", - "CantShroud": "You can't control a Mini that hasn't grown up.", - "CantBoom": "You can't blow yourself up with a Mini that hasn't grown up.", - "CantRecruit": "You can't recruit a Mini that hasn't grown up.", - "CantDuel": "You can't duel a Mini that hasn't grown up.", - "CantMark": "You can't mark a Mini that hasn't grown up.", - "CantBlood": "You can't blood a Mini that hasn't grown up.", - "CantPosses": "You can't possess a Mini that hasn't grown up.", - "ExiledNiceMini": "You ejected a Nice Mini before they grew up.\nYou all lose", - "MiniUp": "You're a year older!", - "MiniMisGuessed": "You are supposed to misguess to death!\nHowever you are still a kid, so you are free of guilt while you can no longer guess.\nYou can guess again after you have grown up.", - "MiniGuessMax": "You have misguessed, so you are no longer allowed to guess!", - "CountMeetingTime": "Meeting time can continue to grow", - "YouKillRandomizer1": "You kill Randomizer, Self-report!", - "YouKillRandomizer2": "You kill Randomizer, Cannot move!", - "YouKillRandomizer3": "You kill Randomizer, Kill CD change to 600s!", - "YouKillRandomizer4": "You kill Randomizer, Triggered Random Revenge!", - "MadmateCanBeHurried": "Madmate can be Hurried on game start", - "TaskBasedCrewCanBeHurried": "Task-based Crews can be Hurried", - "HurriedCanBeConverted": "Hurried can be recruited in the game (excludes madmate)", - "Developer": "Developer", - "Sponsor": "Sponsor", - "Booster": "Server Booster", - "Translator": "Translator", - "NoAccess": "Unauthorized Access!\n\n Please open up a ticket in the discord server to know more (discord.gg/tohe)", - "DCNotify.Hacking": "You were banned for hacking.\n\nPlease stop.", - "DCNotify.Banned": "You were banned from this lobby.\n\nContact the host if this was a mistake.", - "DCNotify.Kicked": "You were kicked from this lobby.\n\nYou may still rejoin.", - "DCNotify.DCFromServer": "You disconnected from the server.\r\nThis could be an issue with either the servers or your network.", - "DCNotify.GameNotFound": "This lobby code is invalid.\n\nCheck the code and/or server and try again.", - "DCNotify.GameStarted": "This lobby is currently in-game.\n\nWait for it to end or find a different lobby.", - "DCNotify.GameFull": "This lobby is currently full.\n\nCheck with the host to see if you may join.", - "DCNotify.IncorrectVersion": "This lobby does not support your Among Us version.", - "DCNotify.Inactivity": "The lobby closed due to inactivity.", - "DCNotify.Auth": "You are not authenticated.\n\nYou may need to restart your game.", - "DCNotify.DupeLogin": "An instance of your account is already present in this lobby.", - "DCNotify.InvalidSettings": "Game settings have been detected to be invalid.\n\nEnter local play to reset them, then try again.", - "ModeDescribe.SoloKombat": "Current mode is [Solo PVP]\nNo role assignment. Everyone has HP and can use the kill button to cause damage to other players. The player with the highest number of kills wins at the end of the game.", - "RoleType.VanillaRoles": "★ Vanilla Roles", - "RoleType.ImpKilling": "★ Impostor Killing Roles", - "RoleType.ImpSupport": "★ Impostor Support Roles", - "RoleType.ImpConcealing": "★ Impostor Concealing Roles", - "RoleType.ImpHindering": "★ Impostor Hindering Roles", - "RoleType.ImpGhost": "★ Impostor Ghost Roles /ghostinfo", - "RoleType.Madmate": "★ Madmate Roles", - "RoleType.CrewSupport": "★ Crewmate Support Roles", - "RoleType.CrewInvestigative": "★ Crewmate Investigative Roles", - "RoleType.CrewPower": "★ Crewmate Power Roles", - "RoleType.CrewKilling": "★ Crewmate Killing Roles", - "RoleType.CrewBasic": "★ Crewmate Basic Roles", - "RoleType.CrewGhost": "★ Crewmate Ghost Roles /ghostinfo", - "RoleType.NeutralEvil": "★ Neutral Evil Roles", - "RoleType.NeutralBenign": "★ Neutral Benign Roles", - "RoleType.NeutralChaos": "★ Neutral Chaos Roles", - "RoleType.NeutralKilling": "★ Neutral Killing Roles", - "RoleType.NeutralApocalypse": "★ Neutral Apocalypse Roles /apocalypseinfo", - "RoleType.Harmful": "★ Harmful Add-ons", - "RoleType.Support": "★ Supportive Add-ons", - "RoleType.Helpful": "★ Helpful Add-ons", - "RoleType.Mixed": "★ Mixed Add-ons", - "RoleType.Misc": "★ Miscellaneous Add-ons", - "RoleType.Impostor": "★ Impostor Add-ons", - "RoleType.Guesser": "★ Guesser Add-ons", - "RoleType.Neut": "★ Neutral Add-ons", - "RoleType.Experimental": "★ Experimental Addons (NOTICE: Use with caution, as these require testing)", - "SubType.Impostor": "★ Impostors", - "SubType.Shapeshifter": "★ Shapeshifters", - "SubType.SemiShapeshifter": "★ Semi-Shapeshifters", - "SubType.Madmate": "★ Madmates", - "SubType.CrewmateKilling": "★ Crewmate Killings", - "SubType.Crewmate": "★ Regular Crewmates", - "SubType.New": "★ New!", - "CrewmateRoles": "★ Crewmate Roles ★", - "ImpostorRoles": "★ Impostor Roles ★", - "NeutralRoles": "★ Neutral Roles ★", - "AddonRoles": "★ Add-ons ★", - "WinnerRoleText.Impostor": "Impostors Win!", - "WinnerRoleText.Crewmate": "Crewmates Win!", - "WinnerRoleText.Apocalypse": "Apocalypse Wins!", - "WinnerRoleText.Terrorist": "Terrorist Wins!", - "WinnerRoleText.Jester": "Jester Wins!", - "WinnerRoleText.Lovers": "Lovers Win!", - "WinnerRoleText.Executioner": "Executioner Wins!", - "WinnerRoleText.Arsonist": "Arsonist Wins!", - "WinnerRoleText.Revolutionist": "Revolutionist Wins!", - "WinnerRoleText.Jackal": "Jackals Win!", - "WinnerRoleText.God": "God Wins!", - "WinnerRoleText.Vector": "Vector Wins!", - "WinnerRoleText.Innocent": "Innocent Wins!", - "WinnerRoleText.Pelican": "Pelican Wins!", - "WinnerRoleText.Youtuber": "YouTuber Wins!", - "WinnerRoleText.Necromancer": "Necromancer Wins!", - "WinnerRoleText.Egoist": "Egoist(s) Wins!", - "WinnerRoleText.Demon": "Demon Wins!", - "WinnerRoleText.Stalker": "Stalker Wins!", - "WinnerRoleText.Workaholic": "Workaholic Wins!", - "WinnerRoleText.Collector": "Collector Wins!", - "WinnerRoleText.BloodKnight": "Blood Knight Wins!", - "WinnerRoleText.Poisoner": "Poisoner Wins!", - "WinnerRoleText.Huntsman": "Huntsman Wins!", - "WinnerRoleText.HexMaster": "Hex Master Wins!", - "WinnerRoleText.Cultist": "Cultist Wins!", - "WinnerRoleText.Wraith": "Wraith Wins!", - "WinnerRoleText.SerialKiller": "Serial Killers Win!", - "WinnerRoleText.Juggernaut": "Juggernaut Wins!", - "WinnerRoleText.Infectious": "Infectious Wins!", - "WinnerRoleText.Virus": "Virus Wins!", - "WinnerRoleText.Specter": "Specter Wins!", - "WinnerRoleText.Jinx": "Jinx Wins!", - "WinnerRoleText.CursedSoul": "Cursed Soul Wins!", - "WinnerRoleText.PotionMaster": "Potion Master Wins!", - "WinnerRoleText.Pickpocket": "Pickpocket Wins!", - "WinnerRoleText.Traitor": "Traitor Wins!", - "WinnerRoleText.Vulture": "Vulture Wins!", - "WinnerRoleText.Medusa": "Medusa Wins!", - "WinnerRoleText.Spiritcaller": "Spiritcaller Wins!", - "WinnerRoleText.Glitch": "Glitch Wins!", - "WinnerRoleText.Pestilence": "Pestilence Wins!", - "WinnerRoleText.PlagueBearer": "Plaguebearer Wins!", - "WinnerRoleText.PunchingBag": "Punching Bag Wins!", - "WinnerRoleText.Doomsayer": "Doomsayer Wins!", - "WinnerRoleText.Pirate": "Pirate Wins!", - "WinnerRoleText.Shroud": "Shroud Wins!", - "WinnerRoleText.Werewolf": "Werewolf Wins!", - "WinnerRoleText.Seeker": "Seeker Wins!", - "WinnerRoleText.Occultist": "Occultist Wins!", - "WinnerRoleText.SoulCollector": "Soul Collector Wins!", - "WinnerRoleText.NiceMini": "Nice Mini Wins!", - "WinnerRoleText.Mini": "Nice Mini was killed", - "WinnerRoleText.Bandit": "Bandit Wins!", - "WinnerRoleText.RuthlessRomantic": "Ruthless Romantic Wins!", - "WinnerRoleText.Solsticer": "Solsticer Wins!", - "WinnerRoleText.Pyromaniac": "Pyromaniac Wins!", - "WinnerRoleText.Doppelganger": "Doppelganger Wins!", - "WinnerRoleText.Quizmaster": "Quizmaster Wins!", - "WinnerRoleText.Agitater": "Agitator Wins!", + "GuessMini": "Sorry, you can't hurt a kid Mini.", + "GrowUpDuration": "Time required to grow (s)", + "MajorCooldown": "Kill Cooldown when over 18", + "UpDateAge": "Display age change in real-time", + "Cantkillkid": "You can't kill a Mini that hasn't grown up.", + "CantEat": "You can't eat a Mini that hasn't grown up", + "CantShroud": "You can't control a Mini that hasn't grown up.", + "CantBoom": "You can't blow yourself up with a Mini that hasn't grown up.", + "CantRecruit": "You can't recruit a Mini that hasn't grown up.", + "CantDuel": "You can't duel a Mini that hasn't grown up.", + "CantMark": "You can't mark a Mini that hasn't grown up.", + "CantBlood": "You can't blood a Mini that hasn't grown up.", + "CantPosses": "You can't possess a Mini that hasn't grown up.", + "ExiledNiceMini": "You ejected a Nice Mini before they grew up.\nYou all lose", + "MiniUp": "You're a year older!", + "MiniMisGuessed": "You are supposed to misguess to death!\nHowever you are still a kid, so you are free of guilt while you can no longer guess.\nYou can guess again after you have grown up.", + "MiniGuessMax": "You have misguessed, so you are no longer allowed to guess!", + "CountMeetingTime": "Meeting time can continue to grow", + "YouKillRandomizer1": "You kill Randomizer, Self-report!", + "YouKillRandomizer2": "You kill Randomizer, Cannot move!", + "YouKillRandomizer3": "You kill Randomizer, Kill CD change to 600s!", + "YouKillRandomizer4": "You kill Randomizer, Triggered Random Revenge!", + "MadmateCanBeHurried": "Madmate can be Hurried on game start", + "TaskBasedCrewCanBeHurried": "Task-based Crews can be Hurried", + "HurriedCanBeConverted": "Hurried can be recruited in the game (excludes madmate)", + "Developer": "Developer", + "Sponsor": "Sponsor", + "Booster": "Server Booster", + "Translator": "Translator", + "NoAccess": "Unauthorized Access!\n\n Please open up a ticket in the discord server to know more (discord.gg/tohe)", + "DCNotify.Hacking": "You were banned for hacking.\n\nPlease stop.", + "DCNotify.Banned": "You were banned from this lobby.\n\nContact the host if this was a mistake.", + "DCNotify.Kicked": "You were kicked from this lobby.\n\nYou may still rejoin.", + "DCNotify.DCFromServer": "You disconnected from the server.\r\nThis could be an issue with either the servers or your network.", + "DCNotify.GameNotFound": "This lobby code is invalid.\n\nCheck the code and/or server and try again.", + "DCNotify.GameStarted": "This lobby is currently in-game.\n\nWait for it to end or find a different lobby.", + "DCNotify.GameFull": "This lobby is currently full.\n\nCheck with the host to see if you may join.", + "DCNotify.IncorrectVersion": "This lobby does not support your Among Us version.", + "DCNotify.Inactivity": "The lobby closed due to inactivity.", + "DCNotify.Auth": "You are not authenticated.\n\nYou may need to restart your game.", + "DCNotify.DupeLogin": "An instance of your account is already present in this lobby.", + "DCNotify.InvalidSettings": "Game settings have been detected to be invalid.\n\nEnter local play to reset them, then try again.", + "ModeDescribe.SoloKombat": "Current mode is [Solo PVP]\nNo role assignment. Everyone has HP and can use the kill button to cause damage to other players. The player with the highest number of kills wins at the end of the game.", + "RoleType.VanillaRoles": "★ Vanilla Roles", + "RoleType.ImpKilling": "★ Impostor Killing Roles", + "RoleType.ImpSupport": "★ Impostor Support Roles", + "RoleType.ImpConcealing": "★ Impostor Concealing Roles", + "RoleType.ImpHindering": "★ Impostor Hindering Roles", + "RoleType.ImpGhost": "★ Impostor Ghost Roles /ghostinfo", + "RoleType.Madmate": "★ Madmate Roles", + "RoleType.CrewSupport": "★ Crewmate Support Roles", + "RoleType.CrewInvestigative": "★ Crewmate Investigative Roles", + "RoleType.CrewPower": "★ Crewmate Power Roles", + "RoleType.CrewKilling": "★ Crewmate Killing Roles", + "RoleType.CrewBasic": "★ Crewmate Basic Roles", + "RoleType.CrewGhost": "★ Crewmate Ghost Roles /ghostinfo", + "RoleType.NeutralEvil": "★ Neutral Evil Roles", + "RoleType.NeutralBenign": "★ Neutral Benign Roles", + "RoleType.NeutralChaos": "★ Neutral Chaos Roles", + "RoleType.NeutralKilling": "★ Neutral Killing Roles", + "RoleType.NeutralApocalypse": "★ Neutral Apocalypse Roles /apocalypseinfo", + "RoleType.Harmful": "★ Harmful Add-ons", + "RoleType.Support": "★ Supportive Add-ons", + "RoleType.Helpful": "★ Helpful Add-ons", + "RoleType.Mixed": "★ Mixed Add-ons", + "RoleType.Misc": "★ Miscellaneous Add-ons", + "RoleType.Impostor": "★ Impostor Add-ons", + "RoleType.Guesser": "★ Guesser Add-ons", + "RoleType.Neut": "★ Neutral Add-ons", + "RoleType.Experimental": "★ Experimental Addons (NOTICE: Use with caution, as these require testing)", + "SubType.Impostor": "★ Impostors", + "SubType.Shapeshifter": "★ Shapeshifters", + "SubType.SemiShapeshifter": "★ Semi-Shapeshifters", + "SubType.Madmate": "★ Madmates", + "SubType.CrewmateKilling": "★ Crewmate Killings", + "SubType.Crewmate": "★ Regular Crewmates", + "SubType.New": "★ New!", + "CrewmateRoles": "★ Crewmate Roles ★", + "ImpostorRoles": "★ Impostor Roles ★", + "NeutralRoles": "★ Neutral Roles ★", + "AddonRoles": "★ Add-ons ★", + "WinnerRoleText.Impostor": "Impostors Win!", + "WinnerRoleText.Crewmate": "Crewmates Win!", + "WinnerRoleText.Apocalypse": "Apocalypse Wins!", + "WinnerRoleText.Terrorist": "Terrorist Wins!", + "WinnerRoleText.Jester": "Jester Wins!", + "WinnerRoleText.Lovers": "Lovers Win!", + "WinnerRoleText.Executioner": "Executioner Wins!", + "WinnerRoleText.Arsonist": "Arsonist Wins!", + "WinnerRoleText.Revolutionist": "Revolutionist Wins!", + "WinnerRoleText.Jackal": "Jackals Win!", + "WinnerRoleText.God": "God Wins!", + "WinnerRoleText.Vector": "Vector Wins!", + "WinnerRoleText.Innocent": "Innocent Wins!", + "WinnerRoleText.Pelican": "Pelican Wins!", + "WinnerRoleText.Youtuber": "YouTuber Wins!", + "WinnerRoleText.Necromancer": "Necromancer Wins!", + "WinnerRoleText.Egoist": "Egoist(s) Wins!", + "WinnerRoleText.Demon": "Demon Wins!", + "WinnerRoleText.Stalker": "Stalker Wins!", + "WinnerRoleText.Workaholic": "Workaholic Wins!", + "WinnerRoleText.Collector": "Collector Wins!", + "WinnerRoleText.BloodKnight": "Blood Knight Wins!", + "WinnerRoleText.Poisoner": "Poisoner Wins!", + "WinnerRoleText.Huntsman": "Huntsman Wins!", + "WinnerRoleText.HexMaster": "Hex Master Wins!", + "WinnerRoleText.Cultist": "Cultist Wins!", + "WinnerRoleText.Wraith": "Wraith Wins!", + "WinnerRoleText.SerialKiller": "Serial Killers Win!", + "WinnerRoleText.Juggernaut": "Juggernaut Wins!", + "WinnerRoleText.Infectious": "Infectious Wins!", + "WinnerRoleText.Virus": "Virus Wins!", + "WinnerRoleText.Specter": "Specter Wins!", + "WinnerRoleText.Jinx": "Jinx Wins!", + "WinnerRoleText.CursedSoul": "Cursed Soul Wins!", + "WinnerRoleText.PotionMaster": "Potion Master Wins!", + "WinnerRoleText.Pickpocket": "Pickpocket Wins!", + "WinnerRoleText.Traitor": "Traitor Wins!", + "WinnerRoleText.Vulture": "Vulture Wins!", + "WinnerRoleText.Medusa": "Medusa Wins!", + "WinnerRoleText.Spiritcaller": "Spiritcaller Wins!", + "WinnerRoleText.Glitch": "Glitch Wins!", + "WinnerRoleText.Pestilence": "Pestilence Wins!", + "WinnerRoleText.PlagueBearer": "Plaguebearer Wins!", + "WinnerRoleText.PunchingBag": "Punching Bag Wins!", + "WinnerRoleText.Doomsayer": "Doomsayer Wins!", + "WinnerRoleText.Pirate": "Pirate Wins!", + "WinnerRoleText.Shroud": "Shroud Wins!", + "WinnerRoleText.Werewolf": "Werewolf Wins!", + "WinnerRoleText.Seeker": "Seeker Wins!", + "WinnerRoleText.Occultist": "Occultist Wins!", + "WinnerRoleText.SoulCollector": "Soul Collector Wins!", + "WinnerRoleText.NiceMini": "Nice Mini Wins!", + "WinnerRoleText.Mini": "Nice Mini was killed", + "WinnerRoleText.Bandit": "Bandit Wins!", + "WinnerRoleText.RuthlessRomantic": "Ruthless Romantic Wins!", + "WinnerRoleText.Solsticer": "Solsticer Wins!", + "WinnerRoleText.Pyromaniac": "Pyromaniac Wins!", + "WinnerRoleText.Doppelganger": "Doppelganger Wins!", + "WinnerRoleText.Quizmaster": "Quizmaster Wins!", + "WinnerRoleText.Agitater": "Agitator Wins!", "WinnerRoleText.Shocker": "Shocker Wins!", - "AdditionalWinnerRoleText.Sidekick": "Sidekick", - "AdditionalWinnerRoleText.Taskinator": "Taskinator", - "AdditionalWinnerRoleText.Opportunist": "Opportunist", - "AdditionalWinnerRoleText.Lawyer": "Lawyer", - "AdditionalWinnerRoleText.Hater": "Hater", - "AdditionalWinnerRoleText.Provocateur": "Provocateur", - "AdditionalWinnerRoleText.Sunnyboy": "Sunnyboy", - "AdditionalWinnerRoleText.Follower": "Follower", - "AdditionalWinnerRoleText.Pursuer": "Pursuer", - "AdditionalWinnerRoleText.Jester": "Jester", - "AdditionalWinnerRoleText.Lovers": "Lovers", - "AdditionalWinnerRoleText.Executioner": "Executioner", - "AdditionalWinnerRoleText.Specter": "Specter", - "AdditionalWinnerRoleText.Maverick": "Maverick", - "AdditionalWinnerRoleText.Shaman": "Shaman", - "AdditionalWinnerRoleText.Pixie": "Pixie", - "AdditionalWinnerRoleText.NiceMini": "Nice Mini", - "AdditionalWinnerRoleText.Romantic": "Romantic", - "AdditionalWinnerRoleText.VengefulRomantic": "Vengeful Romantic", - "AdditionalWinnerRoleText.SchrodingersCat": "Schrodingers Cat", - "AdditionalWinnerRoleText.Troller": "Troller", - "ErrorEndText": "An error occurred", - "ErrorEndTextDescription": "To avoid crashing, the game was forcibly ended.", - "ForceEnd": "Aborted", - "EveryoneDied": "Everyone died", - "ForceEndText": "Host has aborted the game", - "NiceMiniDied": "Nice Mini was killed", - "HaterMisFireKillTarget": "Hater kills target when misfiring", - "HaterChooseConverted": "Select add-ons that Hater can kill", - "HaterCanKillMadmate": "Can kill madmate", - "HaterCanKillCharmed": "Can kill charmed", - "HaterCanKillLovers": "Can kill lovers", - "HaterCanKillSidekick": "Can kill jackal team", - "HaterCanKillEgoist": "Can kill egoist", - "HaterCanKillInfected": "Can kill infected team", - "HaterCanKillContagious": "Can kill virus team", - "HaterCanKillAdmired": "Can kill admirer", - "HorseMode": "Enable to become a horse", - "LongMode": "Enable to have a long neck", - "InfluencedChangeVote": "Oops! You are so influenced by others!\nYou can not contain your fear that you change voted {0}!", - - - "FFA": "Free For All", - "ModeFFA": "Gamemode: FFA", - "ModeDescribe.FFA": "In the FFA (Free For All) gamemode, everyone is a killer, and everyone can kill anyone. The last player alive wins!\n\nSome random events make this even more fun in the meantime!", - "KillerInfoLong": "In the FFA (Free For All) game mode, everyone is a killer, and everyone can kill anyone. The last player alive wins!\n\nSome random events make this even more fun in the meantime!", - "FFA_GameTime": "Maximum Game Length", - "FFA_KCD": "Kill Cooldown", - "FFA_DisableVentingWhenTwoPlayersAlive": "Prevent venting when only 2 players are alive", - "FFA_EnableRandomAbilities": "Enable Random Events", - "FFA_ShieldDuration": "Shield Duration", - "FFA_IncreasedSpeed": "Increased Speed", - "FFA_DecreasedSpeed": "Decreased Speed", - "FFA_ModifiedSpeedDuration": "Modified Speed Duration", - "FFA_LowerVision": "Lowered Vision", - "FFA_ModifiedVisionDuration": "Lowered Vision Duration", - "FFA_EnableRandomTwists": "Enable Random Swaps from time to time", - "FFA-Event-GetShield": "You have a temporary shield!", - "FFA-Event-GetIncreasedSpeed": "You have a temporary speed boost!", - "FFA-Event-GetLowKCD": "You got a lower kill cooldown!", - "FFA-Event-GetHighKCD": "You got a higher kill cooldown", - "FFA-Event-GetLowVision": "You have lower vision temporarily", - "FFA-Event-GetDecreasedSpeed": "You have decreased speed temporarily", - "FFA-Event-GetTP": "You got teleported to a random vent!", - "FFA-Event-RandomTP": "Everyone was swapped with someone", - "FFA-NoVentingBecauseTwoPlayers": "There are only 2 players alive, stop hiding in vents!", - "FFA-NoVentingBecauseKCDIsUP": "Your kill cooldown is up, don't hide in vents!", - "FFA_DisableVentingWhenKCDIsUp": "Prevent players whose kill cooldown is up from venting", - "FFA_TargetIsShielded": "The player you tried to kill is shielded!", - "FFA_ShieldIsOneTimeUse": "Shields break after 1 kill attempt", - "FFA_ShieldBroken": "Someone tried to kill you, your shield is now broken!", - "Killer": "FREE FOR ALL", - "KillerInfo": "Kill Everyone to Win", - - "Hide&SeekTOHE": "Hide & Seek", - "MenuTitle.Hide&Seek": "Hide & Seek Settings", - "NumImpostorsHnS": "Num Impostors", - - "EveryOneKnowSolsticer": "Every One Know who is Solsticer", - "SolsticerKnowItsKiller": "Solsticer knows the role of whom used the kill button on it", - "SolsticerSpeed": "Movement speed of Solsticer", - "SolsticerRemainingTaskWarned": "Remaining tasks to be known", - "SAddTasksPreDeadPlayer": "How many extra short tasks Solsticer gets when a player dies", - "SolsticerMurdered": "{0} attempted to murder you!", - "MurderSolsticer": "You stopped Solsticer this round!", - "SolsticerMurderMessage": "{0} used kill button on you last round! Its role is {1}!", - "SolsticerOnMeeting": "You witnessed too many deaths! Next round you will have {0} more short task!", - "SolsticerTitle": "Solsticer", - "GuessSolsticer": "Sorry, but you can not guess Solsticer!", + "AdditionalWinnerRoleText.Sidekick": "Sidekick", + "AdditionalWinnerRoleText.Taskinator": "Taskinator", + "AdditionalWinnerRoleText.Opportunist": "Opportunist", + "AdditionalWinnerRoleText.Lawyer": "Lawyer", + "AdditionalWinnerRoleText.Hater": "Hater", + "AdditionalWinnerRoleText.Provocateur": "Provocateur", + "AdditionalWinnerRoleText.Sunnyboy": "Sunnyboy", + "AdditionalWinnerRoleText.Follower": "Follower", + "AdditionalWinnerRoleText.Pursuer": "Pursuer", + "AdditionalWinnerRoleText.Jester": "Jester", + "AdditionalWinnerRoleText.Lovers": "Lovers", + "AdditionalWinnerRoleText.Executioner": "Executioner", + "AdditionalWinnerRoleText.Specter": "Specter", + "AdditionalWinnerRoleText.Maverick": "Maverick", + "AdditionalWinnerRoleText.Shaman": "Shaman", + "AdditionalWinnerRoleText.Pixie": "Pixie", + "AdditionalWinnerRoleText.NiceMini": "Nice Mini", + "AdditionalWinnerRoleText.Romantic": "Romantic", + "AdditionalWinnerRoleText.VengefulRomantic": "Vengeful Romantic", + "AdditionalWinnerRoleText.SchrodingersCat": "Schrodingers Cat", + "AdditionalWinnerRoleText.Troller": "Troller", + "ErrorEndText": "An error occurred", + "ErrorEndTextDescription": "To avoid crashing, the game was forcibly ended.", + "ForceEnd": "Aborted", + "EveryoneDied": "Everyone died", + "ForceEndText": "Host has aborted the game", + "NiceMiniDied": "Nice Mini was killed", + "HaterMisFireKillTarget": "Hater kills target when misfiring", + "HaterChooseConverted": "Select add-ons that Hater can kill", + "HaterCanKillMadmate": "Can kill madmate", + "HaterCanKillCharmed": "Can kill charmed", + "HaterCanKillLovers": "Can kill lovers", + "HaterCanKillSidekick": "Can kill jackal team", + "HaterCanKillEgoist": "Can kill egoist", + "HaterCanKillInfected": "Can kill infected team", + "HaterCanKillContagious": "Can kill virus team", + "HaterCanKillAdmired": "Can kill admirer", + "HorseMode": "Enable to become a horse", + "LongMode": "Enable to have a long neck", + "InfluencedChangeVote": "Oops! You are so influenced by others!\nYou can not contain your fear that you change voted {0}!", + + + + "ChanceCrew": "Chance that randomizer gets crewmate roles", + "ChanceImpostor": "Chance that randomizer gets impostor roles", + "ChanceNeutral": "Chance that randomizer gets neutral roles", + "AllowGhostRoles": "Randomizer can get ghost roles when dead", + "MinAddOns": "Minimum addons randomizer can get", + "MaxAddOns": "Maximum addons randomizer can get", + + + + + + + + + + "FFA": "Free For All", + "ModeFFA": "Gamemode: FFA", + "ModeDescribe.FFA": "In the FFA (Free For All) gamemode, everyone is a killer, and everyone can kill anyone. The last player alive wins!\n\nSome random events make this even more fun in the meantime!", + "KillerInfoLong": "In the FFA (Free For All) game mode, everyone is a killer, and everyone can kill anyone. The last player alive wins!\n\nSome random events make this even more fun in the meantime!", + "FFA_GameTime": "Maximum Game Length", + "FFA_KCD": "Kill Cooldown", + "FFA_DisableVentingWhenTwoPlayersAlive": "Prevent venting when only 2 players are alive", + "FFA_EnableRandomAbilities": "Enable Random Events", + "FFA_ShieldDuration": "Shield Duration", + "FFA_IncreasedSpeed": "Increased Speed", + "FFA_DecreasedSpeed": "Decreased Speed", + "FFA_ModifiedSpeedDuration": "Modified Speed Duration", + "FFA_LowerVision": "Lowered Vision", + "FFA_ModifiedVisionDuration": "Lowered Vision Duration", + "FFA_EnableRandomTwists": "Enable Random Swaps from time to time", + "FFA-Event-GetShield": "You have a temporary shield!", + "FFA-Event-GetIncreasedSpeed": "You have a temporary speed boost!", + "FFA-Event-GetLowKCD": "You got a lower kill cooldown!", + "FFA-Event-GetHighKCD": "You got a higher kill cooldown", + "FFA-Event-GetLowVision": "You have lower vision temporarily", + "FFA-Event-GetDecreasedSpeed": "You have decreased speed temporarily", + "FFA-Event-GetTP": "You got teleported to a random vent!", + "FFA-Event-RandomTP": "Everyone was swapped with someone", + "FFA-NoVentingBecauseTwoPlayers": "There are only 2 players alive, stop hiding in vents!", + "FFA-NoVentingBecauseKCDIsUP": "Your kill cooldown is up, don't hide in vents!", + "FFA_DisableVentingWhenKCDIsUp": "Prevent players whose kill cooldown is up from venting", + "FFA_TargetIsShielded": "The player you tried to kill is shielded!", + "FFA_ShieldIsOneTimeUse": "Shields break after 1 kill attempt", + "FFA_ShieldBroken": "Someone tried to kill you, your shield is now broken!", + "Killer": "FREE FOR ALL", + "KillerInfo": "Kill Everyone to Win", + + "Hide&SeekTOHE": "Hide & Seek", + "MenuTitle.Hide&Seek": "Hide & Seek Settings", + "NumImpostorsHnS": "Num Impostors", + + "EveryOneKnowSolsticer": "Every One Know who is Solsticer", + "SolsticerKnowItsKiller": "Solsticer knows the role of whom used the kill button on it", + "SolsticerSpeed": "Movement speed of Solsticer", + "SolsticerRemainingTaskWarned": "Remaining tasks to be known", + "SAddTasksPreDeadPlayer": "How many extra short tasks Solsticer gets when a player dies", + "SolsticerMurdered": "{0} attempted to murder you!", + "MurderSolsticer": "You stopped Solsticer this round!", + "SolsticerMurderMessage": "{0} used kill button on you last round! Its role is {1}!", + "SolsticerOnMeeting": "You witnessed too many deaths! Next round you will have {0} more short task!", + "SolsticerTitle": "Solsticer", + "GuessSolsticer": "Sorry, but you can not guess Solsticer!", "ExpelSolsticer": "Sorry, but you can not expel Solsticer!", - "SolsticerTasksReset": "Your tasks get reset!", - "SolsticerMisGuessed": "You just misguessed! You are no longer allowed to guess.", - "SolsticerGuessMax": "Because you already misguessed, you are no longer allowed to guess.", - - "VoteDead": "The player you voted for was exiled before the meeting concluded. Your vote was rescinded.", - - "LastMessageReplay": "Last System Message Replay", - "Contributor": "Contributor", - - "dbConnect.InitFailure": "Error while connecting to TOHE API, please check your network connection and retry login!", - "dbConnect.InitFailurePublic": "Error while connecting to TOHE API, this could be caused by your internet connection. And so Sponsor+ perks are not available, you may continue to play as usual without these.", - "dbConnect.nullFriendCode": "This build of TOHE is not available to users with no friendcode!", - - "Quizmaster": "Quizmaster", - "QuizmasterInfo": "Quiz people to kill them in meetings", - "QuizmasterInfoLong": "(Neutrals):\nAs the Quizmaster, you can mark a player using your kill button. In the next meeting, the marked player will have \"?!\" next to their name. The player will die if they answer the question wrong or doesn't answer. The player will live if the Quizmaster is killed/ejected in the same meeting.\nThe Quizmaster cannot mark multiple people in the same round", - "QuizmasterKillButtonText": "Quiz", - - "QuizmasterChat.MarkedBy": "You've been marked by the Quizmaster\nTo survive you have to answer correct to this question:\n\n{QMQUESTION}", - "QuizmasterChat.MarkedPublic": "{QMTARGET} has been marked by the Quizmaster\nTo survive {QMTARGET} have to answer correct to their question!", - "QuizmasterChat.Answers": "Answers\nA: {QMA}\nB: {QMB}\nC: {QMC}\n\nTo answer just type /answer [answer letter]\n\nIf you need to recheck the answer and questions just do /qmquiz", - "QuizmasterChat.CorrectTarget": "Correct", - "QuizmasterChat.Correct": "{QMTARGET} got the right answer!\nYou can now mark someone else!", - "QuizmasterChat.CorrectPublic": "{QMTARGET} got the Quizmaster's question answer correct and survived!\nBeware of the Quizmaster!", - "QuizmasterChat.WrongTarget": "Wrong\nYour answer was {QMWRONG}\nThe correct answer was {QMRIGHT}\n\nThe Quizmaster was {QM}", - "QuizmasterChat.Wrong": "{QMTARGET} got the wrong answer and died!\nYou can now mark someone else!", - "QuizmasterChat.WrongPublic": "{QMTARGET} got the Quizmaster's question answer wrong and died!\nBeware of the Quizmaster!", - "QuizmasterChat.Marked": "You've marked {QMTARGET}\nIf {QMTARGET} doesn't answer by the end of the meeting or answer wrong {QMTARGET} will die\n\nQuestion for {QMTARGET} => {QMQUESTION}", - "QuizmasterChat.Title": "Quizmaster Information", - "QuizmasterChat.CantAnswer": "As the quizmaster, you can't answer questions", - "QuizmasterChat.AnswerNotValid": "Your answer must be A, B, or C", - "QuizmasterChat.SyntaxNotValid": "Usage:\n/answer [A/B/C]", - - "QuizmasterSettings.QuestionDifficulty": "Question Difficulty", - "QuizmasterSettings.CanVentAfterMark": "Can Vent After Marked Somebody For Quiz", - "QuizmasterSettings.CanKillAfterMark": "Can Kill After Marked Somebody For Quiz", - "QuizmasterSettings.NumOfKillAfterMark": "How Many Kills Per Round", - "QuizmasterSettings.CanGiveQuestionsAboutPastGames": "Can Give Questions About Past Games", - - "Quizmaster.None": "None", - - "QuizmasterSabotages.Lights": "Lights", - "QuizmasterSabotages.Reactor": "Reactor", - "QuizmasterSabotages.Communications": "Communications", - "QuizmasterSabotages.O2": "O2", - "QuizmasterSabotages.MushroomMixup": "Mushroom Mixup", - "QuizmasterAnswers.One": "One", - "QuizmasterAnswers.Two": "Two", - "QuizmasterAnswers.Three": "Three", - "QuizmasterAnswers.Four": "Four", - "QuizmasterAnswers.Five": "Five", - "QuizmasterAnswers.Pacifist": "Pacifist", - "QuizmasterAnswers.Vampire": "Vampire", - "QuizmasterAnswers.Snitch": "Snitch", - "QuizmasterAnswers.Vigilante": "Vigilante", - "QuizmasterAnswers.Jackal": "Jackal", - "QuizmasterAnswers.Mole": "Mole", - "QuizmasterAnswers.Sniper": "Sniper", - "QuizmasterAnswers.Coven": "Coven", - "QuizmasterAnswers.Sabotuer": "Saboteur", - "QuizmasterAnswers.Sorcerers": "Sorcerers", - "QuizmasterAnswers.Killer": "Killer", - "QuizmasterAnswers.Edition": "Edition", - "QuizmasterAnswers.Experimental": "Experimental", - "QuizmasterAnswers.Enhanced": "Enhanced", - "QuizmasterAnswers.Edited": "Edited", - - "QuizmasterQuestions.LastSabotage": "What was the sabotage was called last?", - "QuizmasterQuestions.FirstRoundSabotage": "What was the first sabotage called this round?", - "QuizmasterQuestions.LastEjectedPlayerColor": "What was the color of the player that was last ejected?", - "QuizmasterQuestions.LastReportPlayerColor": "What was the color of the body that was last reported before this meeting?", - "QuizmasterQuestions.LastButtonPressedPlayerColor": "Who called the last meeting before this meeting?", - "QuizmasterQuestions.MeetingPassed": "How many meetings have passed so far?", - "QuizmasterQuestions.HowManyFactions": "How many factions are in the game?", - "QuizmasterQuestions.BasisOfRole": "What's the basis of {QMRole}?", - "QuizmasterQuestions.FactionOfRole": "What's the faction of {QMRole}?", - "QuizmasterQuestions.FactionRemovedName": "What faction used to be in the game but was removed in an update later?", - "QuizmasterQuestions.HowManyDiedFirstRound": "How many people died round one?", - "QuizmasterQuestions.ButtonPressedBefore": "How many people pressed the emergency button before this meeting?", - "QuizmasterQuestions.WhatDoesEOgMeansInName": "What did the E in TOHE originally stand for?", - "QuizmasterQuestions.PlrDieReason": "What was {PLR}'s cause of death?", - "QuizmasterQuestions.PlrDieMethod": "How did {PLR} die?", - "LastAddedRoleForKarped": "What was the last role added to TOHE before KARPED1EM stepped down?", - "QuizmasterQuestions.PlrDieFaction": "What kind of faction killed {PLR}?", - - "DeathReason.WrongAnswer": "Wrong Quiz Answer", - - "TPCooldown": "Teleport Cooldown", - "RiftsTooClose": "Location too close to the first rift", - "RiftCreated": "Rift made successfully", - "RiftsDestroyed": "All rifts Destroyed", - "RiftRadius": "Rift Radius", - - "TiredVision": "Vision When Tired", - "TiredSpeed": "Speed When Tired", - "TiredDur": "Tired Duration", - - "TiredNotify": "Zzz..", - - "PlagueDoctorInfectLimit": "Infect Limit", - "PlagueDoctorInfectWhenKilled": "Infect Killer When Killed", - "PlagueDoctorInfectTime": "Infect Time", - "PlagueDoctorInfectDistance": "Infect Distance", - "PlagueDoctorInfectInactiveTime": "Delay Infection After Start The Game And After Meetings", - "PlagueDoctorCanInfectSelf": "Can Infect Self", - "PlagueDoctorCanInfectVent": "Can Infect While In Vent", - "WinnerRoleText.PlagueDoctor": "Plague Scientist Wins!", - - "StatueSlow": "Statue Slowness", - "StatuePeopleToSlow": "People Needed To Slow", - - "WardenIncreaseSpeed": "Increase Speed By", - "WardenWarn": "DANGER! RUN!", - - "MinionAbilityTime": "Ability Duration", - "Minion_Blind": "blinded", - - "Evader_ChanceNotExiled": "Chance not be exiled", + "SolsticerTasksReset": "Your tasks get reset!", + "SolsticerMisGuessed": "You just misguessed! You are no longer allowed to guess.", + "SolsticerGuessMax": "Because you already misguessed, you are no longer allowed to guess.", + + "VoteDead": "The player you voted for was exiled before the meeting concluded. Your vote was rescinded.", + + "LastMessageReplay": "Last System Message Replay", + "Contributor": "Contributor", + + "dbConnect.InitFailure": "Error while connecting to TOHE API, please check your network connection and retry login!", + "dbConnect.InitFailurePublic": "Error while connecting to TOHE API, this could be caused by your internet connection. And so Sponsor+ perks are not available, you may continue to play as usual without these.", + "dbConnect.nullFriendCode": "This build of TOHE is not available to users with no friendcode!", + + "Quizmaster": "Quizmaster", + "QuizmasterInfo": "Quiz people to kill them in meetings", + "QuizmasterInfoLong": "(Neutrals):\nAs the Quizmaster, you can mark a player using your kill button. In the next meeting, the marked player will have \"?!\" next to their name. The player will die if they answer the question wrong or doesn't answer. The player will live if the Quizmaster is killed/ejected in the same meeting.\nThe Quizmaster cannot mark multiple people in the same round", + "QuizmasterKillButtonText": "Quiz", + + "QuizmasterChat.MarkedBy": "You've been marked by the Quizmaster\nTo survive you have to answer correct to this question:\n\n{QMQUESTION}", + "QuizmasterChat.MarkedPublic": "{QMTARGET} has been marked by the Quizmaster\nTo survive {QMTARGET} have to answer correct to their question!", + "QuizmasterChat.Answers": "Answers\nA: {QMA}\nB: {QMB}\nC: {QMC}\n\nTo answer just type /answer [answer letter]\n\nIf you need to recheck the answer and questions just do /qmquiz", + "QuizmasterChat.CorrectTarget": "Correct", + "QuizmasterChat.Correct": "{QMTARGET} got the right answer!\nYou can now mark someone else!", + "QuizmasterChat.CorrectPublic": "{QMTARGET} got the Quizmaster's question answer correct and survived!\nBeware of the Quizmaster!", + "QuizmasterChat.WrongTarget": "Wrong\nYour answer was {QMWRONG}\nThe correct answer was {QMRIGHT}\n\nThe Quizmaster was {QM}", + "QuizmasterChat.Wrong": "{QMTARGET} got the wrong answer and died!\nYou can now mark someone else!", + "QuizmasterChat.WrongPublic": "{QMTARGET} got the Quizmaster's question answer wrong and died!\nBeware of the Quizmaster!", + "QuizmasterChat.Marked": "You've marked {QMTARGET}\nIf {QMTARGET} doesn't answer by the end of the meeting or answer wrong {QMTARGET} will die\n\nQuestion for {QMTARGET} => {QMQUESTION}", + "QuizmasterChat.Title": "Quizmaster Information", + "QuizmasterChat.CantAnswer": "As the quizmaster, you can't answer questions", + "QuizmasterChat.AnswerNotValid": "Your answer must be A, B, or C", + "QuizmasterChat.SyntaxNotValid": "Usage:\n/answer [A/B/C]", + + "QuizmasterSettings.QuestionDifficulty": "Question Difficulty", + "QuizmasterSettings.CanVentAfterMark": "Can Vent After Marked Somebody For Quiz", + "QuizmasterSettings.CanKillAfterMark": "Can Kill After Marked Somebody For Quiz", + "QuizmasterSettings.NumOfKillAfterMark": "How Many Kills Per Round", + "QuizmasterSettings.CanGiveQuestionsAboutPastGames": "Can Give Questions About Past Games", + + "Quizmaster.None": "None", + + "QuizmasterSabotages.Lights": "Lights", + "QuizmasterSabotages.Reactor": "Reactor", + "QuizmasterSabotages.Communications": "Communications", + "QuizmasterSabotages.O2": "O2", + "QuizmasterSabotages.MushroomMixup": "Mushroom Mixup", + "QuizmasterAnswers.One": "One", + "QuizmasterAnswers.Two": "Two", + "QuizmasterAnswers.Three": "Three", + "QuizmasterAnswers.Four": "Four", + "QuizmasterAnswers.Five": "Five", + "QuizmasterAnswers.Pacifist": "Pacifist", + "QuizmasterAnswers.Vampire": "Vampire", + "QuizmasterAnswers.Snitch": "Snitch", + "QuizmasterAnswers.Vigilante": "Vigilante", + "QuizmasterAnswers.Jackal": "Jackal", + "QuizmasterAnswers.Mole": "Mole", + "QuizmasterAnswers.Sniper": "Sniper", + "QuizmasterAnswers.Coven": "Coven", + "QuizmasterAnswers.Sabotuer": "Saboteur", + "QuizmasterAnswers.Sorcerers": "Sorcerers", + "QuizmasterAnswers.Killer": "Killer", + "QuizmasterAnswers.Edition": "Edition", + "QuizmasterAnswers.Experimental": "Experimental", + "QuizmasterAnswers.Enhanced": "Enhanced", + "QuizmasterAnswers.Edited": "Edited", + + "QuizmasterQuestions.LastSabotage": "What was the sabotage was called last?", + "QuizmasterQuestions.FirstRoundSabotage": "What was the first sabotage called this round?", + "QuizmasterQuestions.LastEjectedPlayerColor": "What was the color of the player that was last ejected?", + "QuizmasterQuestions.LastReportPlayerColor": "What was the color of the body that was last reported before this meeting?", + "QuizmasterQuestions.LastButtonPressedPlayerColor": "Who called the last meeting before this meeting?", + "QuizmasterQuestions.MeetingPassed": "How many meetings have passed so far?", + "QuizmasterQuestions.HowManyFactions": "How many factions are in the game?", + "QuizmasterQuestions.BasisOfRole": "What's the basis of {QMRole}?", + "QuizmasterQuestions.FactionOfRole": "What's the faction of {QMRole}?", + "QuizmasterQuestions.FactionRemovedName": "What faction used to be in the game but was removed in an update later?", + "QuizmasterQuestions.HowManyDiedFirstRound": "How many people died round one?", + "QuizmasterQuestions.ButtonPressedBefore": "How many people pressed the emergency button before this meeting?", + "QuizmasterQuestions.WhatDoesEOgMeansInName": "What did the E in TOHE originally stand for?", + "QuizmasterQuestions.PlrDieReason": "What was {PLR}'s cause of death?", + "QuizmasterQuestions.PlrDieMethod": "How did {PLR} die?", + "LastAddedRoleForKarped": "What was the last role added to TOHE before KARPED1EM stepped down?", + "QuizmasterQuestions.PlrDieFaction": "What kind of faction killed {PLR}?", + + "DeathReason.WrongAnswer": "Wrong Quiz Answer", + + "TPCooldown": "Teleport Cooldown", + "RiftsTooClose": "Location too close to the first rift", + "RiftCreated": "Rift made successfully", + "RiftsDestroyed": "All rifts Destroyed", + "RiftRadius": "Rift Radius", + + "TiredVision": "Vision When Tired", + "TiredSpeed": "Speed When Tired", + "TiredDur": "Tired Duration", + + "TiredNotify": "Zzz..", + + "PlagueDoctorInfectLimit": "Infect Limit", + "PlagueDoctorInfectWhenKilled": "Infect Killer When Killed", + "PlagueDoctorInfectTime": "Infect Time", + "PlagueDoctorInfectDistance": "Infect Distance", + "PlagueDoctorInfectInactiveTime": "Delay Infection After Start The Game And After Meetings", + "PlagueDoctorCanInfectSelf": "Can Infect Self", + "PlagueDoctorCanInfectVent": "Can Infect While In Vent", + "WinnerRoleText.PlagueDoctor": "Plague Scientist Wins!", + + "StatueSlow": "Statue Slowness", + "StatuePeopleToSlow": "People Needed To Slow", + + "WardenIncreaseSpeed": "Increase Speed By", + "WardenWarn": "DANGER! RUN!", + + "MinionAbilityTime": "Ability Duration", + "Minion_Blind": "blinded", + + "Evader_ChanceNotExiled": "Chance not be exiled", "ShockerAbilityCooldown": "Ability Cooldown", "ShockerAbilityDuration": "Ability Duration", @@ -3886,7 +3917,7 @@ "ShockerVentButtonText": "Shock", "ShockerRoomMarked": "Marked Room", - "EavesdropperMsgTitle": "You found a secret", + "EavesdropperMsgTitle": "You found a secret", "EavesdropPercentChance": "Chance to eavesdrop", "PreventSeeRolesBeforeSkillUsedUp": "Prevent seeing others roles before skill used up", diff --git a/Resources/Lang/es_419.json b/Resources/Lang/es_419.json index 3d99839b8..f9407d253 100644 --- a/Resources/Lang/es_419.json +++ b/Resources/Lang/es_419.json @@ -19,8 +19,6 @@ "SubText.Neutral": "Trabaja solo para conseguir tu victoria", "SubText.Apocalypse": "Vuelvete imparable con tu equipo", "SubText.Madmate": "Ayuda a los Impostores", - "SubText.Lovers": "Stay alive and win together", - "SubText.Egoist": "Win on your own", "TypeImpostor": "Impostores", "TypeCrewmate": "Tripulantes", "TypeNeutral": "Neutrales", @@ -30,9 +28,6 @@ "TeamNeutral": "Neutral", "TeamCrewmate": "Tripulante", "TeamMadmate": "Cómplice", - "TeamLovers": "Lovers", - "TeamEgoist": "Egoist", - "TeamApocalypse": "Apocalypse", "YouAreCrewmate": "Eres un Tripulante", "YouAreImpostor": "Eres un Impostor", "YouAreNeutral": "Eres un Neutral", @@ -224,7 +219,6 @@ "TaskManager": "Gestor de Tareas", "Witness": "Testigo", "Swapper": "Intercambiador", - "ChiefOfPolice": "Jefe de Policias", "NiceMini": "Mini Benigno", "Mini": "Mini", "Spy": "Espía", @@ -253,7 +247,6 @@ "Stalker": "Acosador", "Workaholic": "Trabajólico", "Solsticer": "Solicitador", - "Abyssbringer": "Abyssbringer", "Collector": "Coleccionista", "Provocateur": "Provocador", "BloodKnight": "Caballero de Sangre", @@ -391,9 +384,7 @@ "DoubleAgent": "Doble Agente", "Sloth": "Perezoso", "Prohibited": "Prohibido", - "Eavesdropper": "Escuchón", - "Shocker": "Shocker", - "Revenant": "Renacido", + "Eavesdropper": "Eavesdropper", "BracketAddons": "Dar Corchetes a Add-ons", "EngineerTOHEInfo": "Usa los conductos de ventilación para espiar a los Impostores", "ScientistTOHEInfo": "Ve los signos vitales de la tripulación desde cualquier sitio", @@ -512,7 +503,6 @@ "PacifistInfo": "Reinicia el tiempo de espera para matar de todos usando los conductos", "RebirthInfo": "Levántate de nuevo", "MonarchInfo": "¡Da a la tripulación votos extra!", - "AbyssbringerInfo": "Create Black Holes", "SpurtInfo": "Salta como un conejo!", "StealthInfo": "Matando ciega a todos en la habitasion", "PenguinInfo": "Arrastra a tus víctimas", @@ -546,7 +536,6 @@ "WitnessInfo": "Ve si alguien ha asesinado recientemente", "GhastlyInfo": "¡Controla a alguien!", "SwapperInfo": "Intercambia los votos entre dos jugadores", - "ChiefOfPoliceInfo": "¡Contrata al Sheriff para servir a la tripulacion!", "NiceMiniInfo": "Nadie podrá matarte hasta que crezcas.", "ArsonistInfo": "Rocía a todos en gasolina y préndelos fuego", "PyromaniacInfo": "Rocía y mata a todos", @@ -707,25 +696,23 @@ "SlothInfo": "Eres mas despacio", "ProhibitedInfo": "Ciertos conductos están bloqueados", "EavesdropperInfo": "Atentamente escucha las conversaciones de otros roles", - "ShockerInfo": "Impacta a jugadores desprevenidos con descargas eléctricas", - "RevenantInfo": "Toma el rol de tu asesino", "EngineerTOHEInfoLong": "(Tripulantes):\nComo el Ingeniero, podras acceder a los ductos mientras el sabotage las Comunaciones este inactivo.", "ScientistTOHEInfoLong": "(Tripulantes):\nComo el Científico, tienes acceso a los vitales al cualquier momento, muestrandote quién esta vivo o muerto.", - "NoisemakerTOHEInfoLong": "(Tripulación):\nCuando el Ruidoso muere, hará un ruido lo suficientemente fuerte para alertar a la tripulación. La tripulación tendrá un indicador visual hacia tu lugar de muerte para posiblemente atrapar al asesino con las manos en la masa.", - "TrackerTOHEInfoLong": "(Tripulantes):\nEl Rastreador puede usar su botón de Rastrear en otro jugador para poder vigilar su ubicación con el mapa durante un tiempo limitado.", + "NoisemakerTOHEInfoLong": "(Crewmates):\nAs the Noisemaker, whenever you die, you will make a noise, and a visual indicator of your death appears on the screen so the Crewmates can run to catch the person who killed you red-handed (even if it’s not Red).", + "TrackerTOHEInfoLong": "(Crewmates):\nAs the Tracker, press your tracker button on a player to track their location via the map for a limited amount of time.", "ShapeshifterTOHEInfoLong": "(Impostores):\nComo el Cambiaformas, podras transformarte en otros jugadores. Es obvio cuando cambias o te desformas.", - "PhantomTOHEInfoLong": "(Impostores):\nComo el Fantasma, puedes presionar el botón de \"Desaparecer\" para volverte invisible y escapar de la escena del asesinato. Puedes presionar el botón de nuevo para volver a ser visible, si no, volveras a ser visible después de que se agota el cronómetro.", + "PhantomTOHEInfoLong": "(Impostors):\nAs the Phantom, you can press your vanish button to go invisible to escape a kill. You can click your appear button if you want to become visible before the timer runs out or not.\nNote: You will make a smoke cloud whenever you go invisible and become visible. So make sure you are in a safe area where no one will see you.", "GuardianAngelTOHEInfoLong": "(Tripulantes):\nComo el Ángel Guardián, eres el alma del primer tripulante muerto, y puedes dar escudos temporales a la tripulación.", "ImpostorTOHEInfoLong": "(Impostores):\nComo el Impostor, tu objetivo es simplemente matar a los tripulantes.\nPuedes sabotear y usar ductos.", "CrewmateTOHEInfoLong": "(Tripulantes):\nComo un tripulante, tu meta es encontrar y exilar a los Impostores. Los tripulantes ganan deshaciendose de los impostores o terminando sus tareas.", "BountyHunterInfoLong": "(Impostores):\nEl Cazarrecompensas tiene un objetivo (Indicado por la flecha, si tienes una). Al matarlo, tu tiempo de espera para matar será reducido.\nSi matas a otra persona que no erea tu objetivo, tu tiempo de espera será incrementado. Tu objetivo cambia cada cierto tiempo.", - "FireworkerInfoLong": "(Impostores):\nEl Pirotécnico puede cambiar formas para poner Fuegos Artificiales, con el máximo siendo configurado por el Anfitrión.\nCuando seas el último impostor y todos los fuegos artificiales hayan sido colocados, cambia de forma para encenderlos y mata a todos los que estén cerca, incluyendo a ti mismo.\nSi matas a todos los jugadores con tus fuegos artificiales, cuenta como una victoria para los Impostores.", - "MercenaryInfoLong": "(Impostores):\nComo el Mercenario, debes matar dentro de tu plazo, mostrado por el tiempo de enfriamiento de tu Transformación (que no puedes usar). Si no logras matar durante este tiempo, mueres.", + "FireworkerInfoLong": "(Impostors):\nAs the Fireworker, you can Shapeshift to place Fireworks up to the maximum amount the host sets.\nWhen you are the last Impostor and all Fireworks have been placed, shapeshift again to detonate them and kill everyone in their radius, including you.\nIf you kill all players with your Fireworks, it's considered an Impostor victory.", + "MercenaryInfoLong": "(Impostors):\nAs the Mercenary, you must kill within your Deadline, as shown by your Shapeshift cooldown (which you cannot use). If you fail to kill, you die.", "ShapeMasterInfoLong": "(Impostores):\nComo el Cambiaformas Maestro, no tienes Cooldown de Cambiaformas.", - "VampireInfoLong": "(Impostores):\nComo el Vampiro, sus asesinatos seran detrasados. Esto significa que sus objetivo muriran de todas maneras aunque la reunión sea llamada primero.\nSi muerde a la Carnada, matara normalmente y reportara el cuerpo. Dependiendo de la configuración, podrá usar doble gatillo (muerde jugador - un clic, matar normalmente - doble clic).", + "VampireInfoLong": "(Impostors):\nAs the Vampire, your kills are delayed. This means that your target still dies even if a meeting is called first. However, if you bite a Bait, you kill normally and report the body. Depending on the settings, you can use double trigger (bite players - single click, kill normally - double click).", "WarlockInfoLong": "(Impostores):\nComo el Brujo, puedes maldecir a un jugador a la vez.\nAl cambiar de forma, si has maldecido a un jugador, matará a la persona más cercana a él. Según las opciones, esto puede incluir a los otros impostores o a tí, por lo que ten cuidado.\nPodrás matar normalmente si te has transformado en alguien.", - "ZombieInfoLong": "(Impostores):\nComo el Zombi, puedes matar rápidamente, pero seras muy lento y veras muy poco. No podrás ser exiliado por nadie excepto por el dictador, y te volverás más lento con el tiempo o cada vez que mates.", - "NinjaInfoLong": "(Impostors):\nEl Ninja puede usar su boton de matar para marcar un objetivo (un clic) o matar normalmente (doble clic). Despues de eso, podra cambiar de formas para transportarte a ellos y matarlos.", + "ZombieInfoLong": "(Impostors):\nZombie has a short kill cooldown but moves very slowly and has very little vision. Zombie can not be voted out by anyone other than the Dictator, and the movement speed of Zombie will gradually slow down as they make kills or time passes.", + "NinjaInfoLong": "(Impostors):\nAs the Ninja, you can use your kill button to Mark a target (single click) or kill normally (double click). You may then Shapeshift to teleport to the Marked target and kill them.", "AnonymousInfoLong": "(Impostores):\nComo el Anónimo, puedes cambiar de forma para forzar a su objetivo a reportar a quien haya matado en esta ronda.\nSi no mataste a nadie esa ronda, el objetivo reportará su propio cuerpo muerto como si hubiera muerto.\nNota: El Perezoso y el Gandul no serán afectados por esta habilidad, y esta funcionará aún si el cadáver puede ser informado.", "MinerInfoLong": "(Impostores):\nComo el Minero, puedes transformarte para teletransportarte de vuelta al último conducto en el que estuviste.", "KillingMachineInfoLong": "(Impostors):\nAs the Killing Machine, you have a very short kill cooldown with tiny vision. However, you cannot vent, sabotage, report, nor call emergency meetings.\n\nNote: You will bypass any shields, killing bait and beartrap won't take any effect", @@ -780,11 +767,11 @@ "LurkerInfoLong": "(Impostors):\nAs the Lurker, you can jump into a vent to reduce your cooldown by a certain number of seconds. After you kill, your cooldown resets to its original value.", "VisionaryInfoLong": "(Impostors):\nAs the Visionary, you see the alignments of living players during a meeting.\nThe following information will be displayed on the players:\n- The Red name indicates the Impostors.\n- The Cyan name indicates the Crewmates.\n- The Gray name indicates the Neutrals.", "PlagueDoctorInfoLong": "(Neutrals):\n(Plague Doctor from TOH)\nThe Plague Scientist's goal is to infect every living player.\nThey start by choosing one player to infect, after which anyone who spends a set amount of time in the range of the infected player becomes infected themselves.\nInfection progress is cumulative and does not reset with distance or after meetings.", - "RefugeeInfoLong": "(Madmates):\nAs the Refugee, you were either:\n -An Amnesiac who remembered an Impostor\n -A killer who killed the Godfather's target.\n -A Romantic whose partner was an Impostor\n -Or an Imitator that imitated an Impostor.\n\nNow your job is to help the Impostors kill the crewmates.", + "RefugeeInfoLong": "(Madmates):\nAs the Refugee, you were either an Amnesiac who remembered an Impostor or a killer who killed the Godfather's target.\n\nNow your job is to help the Impostors kill the crewmates.", "UnderdogInfoLong": "(Impostores):\nEl Indefenso no puede matar hasta que sólo queden un cierto número de jugadores vivos.", "ConsigliereInfoLong": "(Impostors):\nAs the Consigliere, you can reveal the roles of other players using your kill button.\n\nSingle click: Reveal role\nDouble click: Kill\n\nIf you run out of reveal uses, your kill button functions normally.", "LudopathInfoLong": "(Impostores):\nEl Ludópata tiene un tiempo de espera para matar aleatorio.\n\nEl mínimo es de 1 segundo, el máximo es tu tiempo de espera para matar por defecto.", - "GodfatherInfoLong": "(Impostors):\nAs the Godfather, you vote someone to make them your target.\nIn the next round, if someone kills the target, the killer will turn into a Refugee or Madmate.", + "GodfatherInfoLong": "(Impostors):\nAs the Godfather, you vote someone to make them your target.\nIn the next round, if someone kills the target, the killer will turn into a Refugee.", "ChronomancerInfoLong": "(Impostors):\nAs the Chronomancer, you have a charge bar which indicates when the slaughter is ready. When it is at 100% the next time you kill someone, you go into slaughter mode, meaning you can kill indefinitely until your bar runs out of charge. Otherwise, you have a normal KCD.", "PitfallInfoLong": "(Impostors):\nAs the Pitfall, you use your shapeshift to mark the area around the shapeshift as a trap. Players who enter this area will be immobilized quickly, and their vision will be affected.", "EvilMiniInfoLong": "(Impostors):\nAs the Evil Mini, you are unkillable until you grow up and have a very long initial kill cooldown, which gets drastically shortened as you grow up.", @@ -856,7 +843,6 @@ "TaskManagerInfoLong": "(Crewmates):\nYou see the total number of tasks completed (by everyone all together) next to your role name, which updates in real-time.", "WitnessInfoLong": "(Crewmates):\nAs the Witness, when you use your kill button on someone, you will know if they killed in the last X seconds or not. (X depends on the settings).", "SwapperInfoLong": "(Crewmates):\nAs the Swapper, you can swap votes in meetings.\n\nTo swap votes, use '/sw [playerID]' twice.\n\nPlayer IDs are displayed next to player names in meetings, but you can also use /id to get a list of all player IDs.\n\nNote: Depending on the Host's settings, you can exchange your own votes.", - "ChiefOfPoliceInfoLong": "(Crewmates):\nPlayers with swords can be recruited to join the sheriff's team to serve the crew\nNote: only one recruitment opportunity\nDepending on settings, you may recruit non killers or non crews.\nYou may suidice for recruiting wrong target.", "NiceMiniInfoLong": "(Crewmates):\nAs a Nice Mini, your survival is crucial. You can't be killed until you grow up, and if you die or are evicted from the meeting before you grow up, everyone loses. This unique role adds a new dynamic to the game, where your survival is not just for your benefit but for the entire Crew's success.", "SpyInfoLong": "(Crewmates):\nAs the Spy, when someone uses their kill button on you (any ability used through the kill button), you'll see their name in orange for a few seconds.\nNote: If a Crewmate used their ability on you, you'll also see them with an orange name!\nNote: If you cannot use left, you won't see orange names!\nNote: If the kill button interaction is blocked, the player's cooldown will reset to 10s'", "RandomizerInfoLong": "(Crewmates):\nAs this Randomizer, when you die, your killer will do one of the following:\n 1. self-report your body\n 2. stand next to your body\n 3. have their kill cooldown set to 600s\n 4. Randomly avenge a player.", @@ -871,7 +857,7 @@ "LawyerInfoLong": "(Neutrales):\nEl Abogado tiene un cliente a quien defender, que será indicado con un diamante 「♦」 al lado de su nombre.\nSi tu cliente gana, ganarás.\nSi pierde, perderás.", "OpportunistInfoLong": "(Neutrales):\nSi el Oportunista sobrevive hasta el final, ganará con el equipo ganador.", "VectorInfoLong": "(Neutrals):\nVector will win alone by venting a certain number of times.", - "JackalInfoLong": "(Neutrals):\nAs the Jackal, you win if you are the last player alive. Additionally, you may recruit using the kill button. If the target is not one you can recruit, you have run out of uses, or you don't have the option to recruit, then you will kill people normally (i.e., don't use kill buttons in front of others thinking it'll recruit). If the target has a kill button and the option to turn into a Sidekick is on, they will become a Sidekick. Otherwise, they will gain the Recruit add-on if the option to give the Recruit add-on is on.\nDepending on the settings, when Jackal was killed, a Sidekick will be randomly selected as the new Jackal.\nRecruit may be selected if no sidekick is alive.", + "JackalInfoLong": "(Neutrals):\nAs the Jackal, you win if you are the last player alive. Additionally, you may recruit using the kill button. If the target is not one you can recruit, you have run out of uses, or you don't have the option to recruit, then you will kill people normally (i.e., don't use kill buttons in front of others thinking it'll recruit). If the target has a kill button and the option to turn into a Sidekick is on, they will become a Sidekick. Otherwise, they will gain the Recruit add-on if the option to give the Recruit add-on is on.", "GodInfoLong": "(Neutrals):\nAs the God, you know everyone's role from the beginning. If you live until the end of the game, you steal the win, i.e., everyone else loses, and you win.", "InnocentInfoLong": "(Neutrals):\nThe Innocent can use the kill button to plant any player, and the planted target will immediately kill the Innocent. If the target gets voted out in the meeting, the Innocent wins. Note: Jester, Executioner, and Innocent can win together.", "PelicanInfoLong": "(Neutrals):\nAs the Pelican, you can use the kill button to swallow a player alive, teleporting them off-bounds but not killing them yet. Those swallowed will only die if you're still alive at the end of the round. If you die or leave during the round, all alive swallowed players will spawn into the map where you were.", @@ -883,7 +869,7 @@ "SolsticerInfoLong": "(Neutrals):\nAs the Solsticer, you won't die, and you win by finishing all your tasks in a single round. After every meeting finishes, your tasks reset, and you need to start all over again.\nVotes on the Solsticer will be directly canceled.\nKill attempts on the Solsticer will teleport it out of the map like Pelican until the meeting is finished.\nThe killer's kill cooldown will be reset to 10 seconds.\nSolsticer is counted as nothing in-game.", "CollectorInfoLong": "(Neutrals):\nAs the Collector, when you vote for a player, for each other player that voted for them, you gain a point. When you collect the required votes, the game ends, and you win alone, even if you voted a Jester or Executioner's target out.", "GlitchInfoLong": "(Neutrals):\nAs the Glitch, you can hack players (single click) or kill normally (double click).\nThose who have been hacked cannot kill, vent, or report for the hack duration.\nAdditionally, calling a sabotage other than doors will have no effect and will instead disguise you as a random player. You cannot disguise during or after sabotages.\nTo win, be the last player alive.", - "SidekickInfoLong": "(Neutrals):\nAs the Sidekick, your job is to help the Jackal kill everyone.\nYou and the Jackal win together.\nDepending on the settings, you may turn into Jackal if old Jackal was killed.\nYou may not be able to kill until old Jackal is dead.", + "SidekickInfoLong": "(Neutrales):\nComo el Secuaz, tu trabajo es ayudar el Chacal matar todo.\n\nEl Chacal ganará contigo.", "ProvocateurInfoLong": "(Neutrales):\nEl Provocador puede matar a cualquiera con el botón de matar. Si el objetivo pierde al final del juego, el Provocador gana con los ganadores.", "BloodKnightInfoLong": "(Neutrals):\nThe Blood Knight wins when they're the last killing role alive, and the amount of crewmates is lower or equal to the amount of Blood Knights. The Blood Knight gains a temporary shield after every kill, making them immortal for a few seconds.", "PlagueBearerInfoLong": "(Apocalypse):\nAs the Plaguebearer, plague everyone using your kill button to turn into Pestilence.\nOnce you turn into Pestilence, you will become immortal and gain the ability to kill, and you will kill anyone who tries to kill you.\n\nAlso, when infected players interact with uninfected players, they will also be infected.", @@ -910,12 +896,11 @@ "TraitorInfoLong": "(Neutrals):\nAs the Traitor, you were an Impostor that betrayed the Impostors.\nYou know the Impostors, but they don't know you.\nThe twist? They can kill you, but you can't kill them.\n\nEliminate the Impostors by other means, then kill everyone else to win!", "TrollerInfoLong": "(Neutrals):\nAs a Troller, you can complete tasks so that random events can happen to players.\nFor example, changing the speed of all players, teleportation, influencing sabotage, etc.\nAlso you can win with the winning team.", "VultureInfoLong": "(Neutrales):\nEl Buitre gana reportando cadáveres.\n\nCuando intentes informar de un cadáver, si tu tiempo de espera para comer se haya acabado, te comerás el cadáver, lo que lo hará imposible de reportar.\nSi tu tiempo de espera para comer aún no se acabó o si llegas al límite de cadáveres por ronda, reportarás el cadáver normalmente.", - "AbyssbringerInfoLong": "(Impostors):\nAs the Abyssbringer, you can place black holes. Black holes will suck in players and kill them when colliding with them.", "TaskinatorInfoLong": "(Neutrals):\nAs the Taskinator, whenever you finish a task, the task will be bombed. When another player completes the bombed task, the bomb will detonate, and the player will die.\n\nYou win if you survive till the end and Crew doesn't win.\n\n Note: Taskinator bombs ignore all protection.", "BenefactorInfoLong": "(Crewmates):\nAs the Benefactor, whenever you finish a task, that task will be marked. When another player completes the marked task, they get a temporary shield.\n\n Note: Shield only protects from direct kill attacks.", "MedusaInfoLong": "(Neutrales):\nLa Medusa puede convertir los cadáveres en piedra, similar a si lo limpiaras.\nLos cadáveres convertidos en piedra no pueden ser reportados.\n\nMáta a todos para ganar.", "SpiritcallerInfoLong": "(Neutrals):\nAs the Spiritcaller, your victims become Evil Spirits after they die. These spirits can help you win by freezing other players briefly or blocking their vision. Alternatively, the spirits can give you a shield that protects you briefly from an attempted kill.", - "AmnesiacInfoLong": "(Neutrals):\nAs the Amnesiac, use your report button to remember a target and get its role.\nTo balance the game, you will not be able to vent after remembering your role if you can't vent as Amnesiac.'", + "AmnesiacInfoLong": "(Neutrales):\nEl Amnésico deberá usar el botón de reportar para recordar un rol.\n\nSi el cadáver viene de un Impostor, te transformarás en un Refugiado.\nSi viene de un tripulante, te convertirás en Sheriff.\nSi viene de un neutral pasivo o de un asesino neutral no compatible, te volverás el rol definido en las opciones.\nSi viene de ciertos neutrales asesinos, copiarás su rol.", "ImitatorInfoLong": "(Neutrals):\nAs the Imitator, use your kill button to imitate a player.\n\nYou'll either become a Sheriff, a Refugee, or some Neutral.", "BanditInfoLong": "(Neutrals):\nAs the Bandit, you can click your kill button one time to steal a player's addon and twice to kill. Depending on the settings, you may instantly steal the addon or after the meeting starts. After the maximum number of steals is reached, you will kill normally. Additionally, if there are no stealable addons on the target or the target is stubborn, you will kill the target.\n\nKill everyone to win.\n\nNote: Cleansed, Last Impostor, and Lovers cannot be stolen.\nNote: If Bandit can vent is on, Nimble will become unstealable.", "DoppelgangerInfoLong": "(Neutrals):\nAs the Doppelganger, use your kill button to steal a player's identity (their name and skin) and then kill your target.\n\nKill everyone to win.\n\nNote: You cannot steal the target's identity when Camouflage is active.", @@ -936,7 +921,6 @@ "JinxInfoLong": "(Neutrals):\nAs the Jinx, whenever you get attacked, you jinx them, resulting in them dying to a jinx.\nThis has limited uses.\n\nKill off everyone to win.", "PotionMasterInfoLong": "(Neutrals):\nAs the Potion Master, you have three different potions assigned to three different actions.\n\nSingle click: Reveal role\nDouble click: Kill\nMap: Sabotage\n\nThe reveal potion has a limit.\nWhen you run out, the kill buttons default to killing.", "NecromancerInfoLong": "(Neutrals):\nAs the Necromancer, you win when you're the last one standing.\nAdditionally when someone tries to kill you, you will block the kill, and you will teleport to a random vent. You will have a limited time to kill your killer. If you succeed in doing so, you live. If the time runs out before you kill your killer, you die permanently. If you try to kill someone else other than your killer, you will die.", - "ShockerInfoLong": "(Neutrals):\nAs the Shocker, you can mark rooms by doing tasks in them, and then vent to Electrocute anyone in those rooms for a set period of time. When you finish all of your tasks, you get new ones. Note: Doing tasks during that period will mark them for the next ability use.", "LastImpostorInfoLong": "(Add-ons):\nThis special effect is given to the last surviving Impostor. It significantly reduces their kill cooldown.", "OverclockedInfoLong": "(Add-ons):\nAs the Overclocked, your kill cooldown is reduced by a percentage.\n\nThis feature is only assigned to roles with a kill button.", "LoversInfoLong": "(Add-ons):\nLovers are a combination of two players. The Lovers win when they are the last ones standing, and their victory is shared. When one of the Lovers wins, the other also wins together. Lovers can see the 「♥」 next to each other's name. If one of the Lovers dies, the other will die in love (may not die in love according to the Host's settings). When one of the Lovers is exiled in the meeting, the other will die and become a dead body that cannot be reported.", @@ -959,7 +943,7 @@ "GuesserInfoLong": "(Add-ons):\nAs a guesser, guess the roles of players in meetings to kill them.\nGuessing the incorrect role kills you instead.\nThe guessing command is: /bt [player id] [role]\nYou can see the player's id before the player's name or use the /id command to view the id of all players.", "NecroviewInfoLong": "(Agregados):\nEl Nigrovidente puede ver el equipo de los jugadores muertos. La información se mostrará en el nombre del jugador muerto durante las reuniones.\nEl nombre rojo indica a los impostores.\nEl nombre azul claro indica a la tripulación.\nEl nombre gris indica a los neutros.", "ReachInfoLong": "(Add-on)\nOnly roles with a kill button can get this add-on. Unlike everyone else, you have the longest kill range possible in the game.", - "BaitInfoLong": "(Agregados):\nCuando asesinan a la \"Carnada\", el asesino que mató reportara el cuerpo del jugador con el agregado de \"Carnada\" a fuerzas. Sin embargo, esto no ocurrirá en ciertas situaciones, como cuando es asesinado por el Carroñero, el Limpiador o el Desvanecedor. El reporte puede retrasarse de acuerdo a los ajustes del anfitrión.", + "BaitInfoLong": "(Add-ons):\nWhen the Bait dies, the murderer who killed the Bait will self-report the Bait's body. However, this won't happen when a Scavenger, Cleaner, Swooper, Wraith, Medusa, or Killing Machine kills the Bait. The report may have a delay according to the Host's settings.", "TrapperInfoLong": "(Add-ons):\nWhen Beartrap dies, Beartrap immobilizes killer for a configurable amount of time.", "CharmedInfoLong": "(Agregados):\n Si el Sectario te hechiza, recibirás el complemento Hechizado.\nUna vez hechizado, ahora te unirás al equipo del Sectario y no estarás más en tu equipo original.", "CleansedInfoLong": "(Agregados):\nSólo puedes recibir el complemento Purificado si el Conserje borra todos tus agregados. Dependiendo de las opciones del Purificador, no podrás obtener más agregados en el futuro.", @@ -980,7 +964,7 @@ "RebirthInfoLong": "(Add-ons):\nAs the Rebirth, if you're the player about to be ejected, you will swap skins with a random crewmate who voted for you.\nNotice: The host vote never counts\nRebirth will be removed from you if you exhausted all your rebirths.", "LoyalInfoLong": "(Agregados):\nCon el agregado de \"Leal\", no puedes ser reclutado por roles como el Chacal o el Sectario.\n\nNo se puede asignar a jugadores neutrales.", "EvilSpiritInfoLong": "(Add-ons):\nAs Evil Spirit, it's your job to help the Spiritcaller to victory. You can use your Haunt button to freeze players and reduce their vision. Alternatively, you can use your Haunt button to give the Spiritcaller a shield against a kill attempt temporarily.", - "RecruitInfoLong": "(Betrayal Add-ons):\nAs a recruit, you are on the Jackal's team and help out the Jackal and their Sidekicks.\nYou cannot win with your original team.\nDepending on the settings, you may turn into Jackal if old Jackal was killed and no sidekicks is alive.", + "RecruitInfoLong": "(Agregados):\nCon el agregado de Recluta, eres parte del equipo de Chacales y deberás ayudar al Chacal y a sus Secuaces.\n\nNo puedes ganar con tu equipo original.", "AdmiredInfoLong": "(Agregados):\nCon el agregado de \"Admirado\", ganarás con tu compañero y no con tu equipo original.\n\nPuedes ver quién es el Admirador.", "GlowInfoLong": "(Add-ons):\nDuring lights out, you and players nearby you will receive a vision boost.", "RadarInfoLong": "(Add-ons):\nAs Radar, you have arrows pointing towards the closest person at all times.", @@ -989,7 +973,7 @@ "StubbornInfoLong": "(Add-ons):\nWith the Stubborn add-on, Eraser can't erase your role, Cleanser can't cleanse you, Bandit can't steal from you, and Monarch can't knight you.\nAdditionally, you can't gain any new add-ons from the Merchant.", "SwiftInfoLong": "(Add-ons):\nAs the Swift, you will not make any movement when you kill.\nNote: Swift also ignores Bait", "UnluckyInfoLong": "(Add-ons):\nAs Unlucky, when you complete tasks, kill, venting, or open door, you have a chance to die.", - "SpurtInfoLong": "(Agregos):\nCuando comienzas a caminar, ganas un enorme impulso de velocidad, que rápidamente se deteriorara, hasta que tengas que descansar un rato para recuperar tu velocidad.", + "SpurtInfoLong": "(Add-ons):\nWhen you start walking, you gain an enormous speed boost, which swiftly deteriorates, until you have to rest still for a while to rejuvenate your speed.", "VoidBallotInfoLong": "(Add-ons):\nHolder of this add-on will have 0 vote count.", "AwareInfoLong": "(Add-ons):\nAs the Aware, you get a notification in the next meeting if a revealing role had interacted with you.", "FragileInfoLong": "(Add-ons):\nAs Fragile, you will instantly die if someone tries to use the kill button on you (even if the role cannot directly kill).", @@ -1022,9 +1006,8 @@ "DoubleAgentInfoLong": "(Impostor):\nAs the Double Agent, you cannot access the kill button. However, you can vote for someone in a meeting to pass a bomb onto them, which can only be done one player at a time. Once the meeting has finished, the bomb will activate and explode in a set amount of time.\nNote: when you pass the bomb onto someone in a meeting, you can vote afterward.\n\nAdditionally depending on settings the Double Agent can diffuse Bastion and Agitator bombs when venting.\n\nThe Double Agent can change roles when they are the Last Imposter, depending on the settings the role can be a Admired Impostor, Trickster, Traitor, or stay as the Double Agent.", "SlothInfoLong": "(Add-ons):\nThe Sloth's default movement speed is slower than others.\n(Speed depends on the setting of the Host)", "ProhibitedInfoLong": "(Add-ons):\nAs the Prohibited, you have specific vents that you can't use.\nHow many vents are disabled depends on the Host's settings.", - "EavesdropperInfoLong": "(Agregos):\nComo el Escuchón, tienes la oportunidad de leer otros mensajes basados en roles o complementos como el Funerario o el Sabueso.", + "EavesdropperInfoLong": "(Add-ons):\nAs the Eavesdropper, you have a chance to read other role/addon information-based messages like Mortician or Sleuth.", "ApocalypseInfoLong": "(Apocalypse):\nApocalypse members are on a separate team that works together and wins together. If there are multiple Apocalypse roles in the game, they can see each other's roles.\nDepending on the Host's settings, Apocalypse roles can guess or be guessed.", - "RevenantInfoLong": "(Neutral):\nAs the Revenant, your goal is to be killed. If you are killed, you will take your killer's role and kill your killer instead. You cannot win before being killed.\nNote that Revenant only works when being directly killed.", "ShowTextOverlay": "Superposición de texto", "Overlay.GuesserMode": "Modo de Adivinos", "Overlay.NoGameEnd": "Partida Sin Fin", @@ -1038,8 +1021,6 @@ "AbilityUseLimit": "Límite de uso de habilidades inicial", "AbilityInUse": "Habilidad en uso", "AbilityExpired": "La habilidad se agotó, te quedan {0} usos", - "RevenantTargeted": "Your role has changed to {0}", - "RevenantCanCopyAddons": "Can Steal Addons", "ShowArrows": "Tiene flechas apuntando a cadáveres", "ArrowDelayMin": "Retraso mínimo de aparición de flechas", "ArrowDelayMax": "Retraso máximo de aparición de flechas", @@ -1368,8 +1349,6 @@ "ShieldedCanUseKillButton": "Jugadores protegidos pueden usar boton de habilidad / muerte", "PlayerIsShieldedByGame": "Jugador esta protegido por el juego!", "LegacyNemesis": "Usar Versión Heredada", - "LegacyParasite": "Use Legacy Version", - "LegacyTraitor": "Use Legacy Version", "ArsonistKeepsGameGoing": "El Pirómano hace que la partida continue", "ArsonistCanIgniteAnytime": "Puede prender fuego en cualquier momento", "ArsonistMinPlayersToIgnite": "Mínimo de jugadores a rociar para incendiar", @@ -1481,8 +1460,8 @@ "ShapeshifterBase_ShapeshiftCooldown": "Shapeshift Cooldown", "ShapeshifterBase_ShapeshiftDuration": "Shapeshift Duration", "ShapeshifterBase_LeaveShapeshiftingEvidence": "Leave Shapeshifting Evidence", - "PhantomBase_InvisCooldown": "Tiempo de espera para volverte invisible", - "PhantomBase_InvisDuration": "Duración de invisibilidad", + "PhantomBase_InvisCooldown": "Invis Cooldown", + "PhantomBase_InvisDuration": "Invis Duration", "GuardianAngelBase_ProtectCooldown": "Protect Cooldown", "GuardianAngelBase_ProtectionDuration": "Protection Duration", "GuardianAngelBase_ImpostorsCanSeeProtect": "Protect Visible To Impostors", @@ -1512,18 +1491,6 @@ "SheriffCanKillSeparately": "Opciones individuales", "In%team%": "(Equipo %team%)", "SheriffMisfireKillsTarget": "Un disparo erróneo mata a la víctima", - "BlackHolePlaceCooldown": "Black Hole Place Cooldown", - "BlackHoleDespawnMode": "Black Hole Despawn Mode", - "BlackHoleDespawnTime": "Time After Black Hole Despawns", - "Abyssbringer.Suffix": "<#00ffa5>Number of players consumed by {0} <#00ffa5>active black holes:\\n{1}", - "Abyssbringer.Suffix.BlackHole": "<#00ffa5>{0}: {1}", - "BlackHoleMovesTowardsNearestPlayer": "Black Hole Moves Towards Nearest Player", - "BlackHoleMoveSpeed": "Black Hole Moving Speed", - "BlackHoleRadius": "Black Hole Consuming Radius", - "AfterTime": "After Time", - "After1PlayerEaten": "After 1 Player Was Eaten", - "AfterMeeting": "After Meeting", - "None": "None", "SheriffShotLimit": "Número máximo de asesinatos", "SheriffCanKillAllAlive": "Puede asesinar cuando todo el mundo está vivo", "SheriffCanKillCharmed": "Puede matar a Encantados", @@ -1540,15 +1507,12 @@ "RebirthUses": "Amount of Rebirths", "RebirthCountVotes": "Only rebirth to players who voted for them", "RebirthFailed": "Ahh, how unfortunate, you did not find any viable souls to swap bodies with", - "FireworkerCooldown": "Placement Cooldown", "ReverieIncreaseKillCooldown": "Aumentar el tiempo de espera para matar", "ReverieMaxKillCooldown": "Límite del tiempo de espera para matar", "ReverieMisfireSuicide": "Errar disparo al llegar a tu tiempo de espera máximo para matar", "ReverieResetCooldownMeeting": "Reiniciar tiempo de espera para matar después de una reunión", "ConvertedReverieKillAll": "El ensueño convertido puede matar como le dé la gana si es convertido", "VigilanteNotify": "Te has convertido en lo que juraste destruir", - "DictatorChangeCommandToExpel": "Dictator use Command to expell instad of vote", - "DictatorExpelSelf": "WAIT WAIT WAIT WAT THE HELLLLLL Bro really just want to expel himself", "DoctorTaskCompletedBatteryCharge": "Duración de la batería", "SnitchEnableTargetArrow": "Ve flechas hacia el blanco", "SnitchCanGetArrowColor": "Ve flechas de colores con colores del equipo", @@ -1629,7 +1593,6 @@ "EvilTrackerTargetMode.OnceInGame": "Once in-game", "EvilTrackerTargetMode.EveryMeeting": "Cada reunión", "EvilTrackerTargetMode.Always": "En cualquier momento", - "ScavengerHasCustomDeathReason": "Enable Custom Death Reason", "EvilHackerCanSeeDeadMark": "Puedes ver las ubicaciones de los cadáveres", "EvilHackerCanSeeImpostorMark": "Puedes ver las ubicaciones de los otros impostores", "EvilHackerCanSeeKillFlash": "Puede ver destellos de muertes", @@ -1699,8 +1662,8 @@ "BaitDelayNotify": "Notificar al asesino sobre el auto-informe que va a suceder", "BecomeBaitDelayNotify": "Notificar al asesino sobre el auto-informe que va a suceder", "BaitNotification": "Revelar la Carnada en la primera reunión", - "BaitAdviceAlive": "{0} es la Carnada. Quien lo mate hará un auto-informe.", - "BaitCanBeReportedUnderAllConditions": "La Carnada puede provocar Auto-Informe aún si el sabotaje de comunicaciones desactivan los informes", + "BaitAdviceAlive": "{0} is the Bait. Whoever kills the Bait will commit self-report.", + "BaitCanBeReportedUnderAllConditions": "Bait Can Be Reported even if a meeting is disabled during comms sabotage", "DeceiverAbilityLost": "El Falsificador pierde su habilidad al vender falsificaciones a un jugador inocente", "AddictSuicideTimer": "Tiempo antes del suicidio", "GrenadierSkillCooldown": "Tiempo de espera de la granada", @@ -1862,21 +1825,13 @@ "Jackal_SidekickCountMode_Jackal": "Jackal", "Jackal_SidekickCountMode_Original": "Original Team", "Jackal_SidekickAssignMode": "Sidekick Assign Mode", - "Jackal_SidekickAssignMode_SidekickAndRecruit": "Sidekick when failed Recruit", - "Jackal_SidekickAssignMode_Sidekick": "Only Sidekick", - "Jackal_SidekickAssignMode_Recruit": "Only Recruit", + "Jackal_SidekickAssignMode_SidekickAndRecruit": "Sidekick+Recruit", + "Jackal_SidekickAssignMode_Sidekick": "Sidekick Only", + "Jackal_SidekickAssignMode_Recruit": "Recruit Only", + "JackalWinWithSidekick": "El Chacal puede ganar con sus Secuaces", "Jackal_SidekickCanKillSidekick": "Sidekicks can kill other Sidekicks", "Jackal_SidekickCanKillJackal": "Sidekick can kill Jackal", - "Jackal_RecruitFailed": "You can not recruit this player!", "JackalCanKillSidekick": "El Chacal puede matar a sus Secuaces", - "Jackal_SidekickCanKillWhenJackalAlive": "Sidekick can kill while Jackal is Alive", - "Jackal_SidekickTurnIntoJackal": "Sidekick can turn into Jackal after its death", - "Jackal_RestoreLimitOnNewJackal": "Restore Recruit limit when Sidekick become new Jackal", - "Jackal_OnBecomeNewJackalMeeting": "The old Jackal {0} is dead.\nYou are selected as new Jackal\nWork together and win the game!", - "Jackal_OnNewJackalSelectedMeeting": "The old Jackal {0} is dead.\n{1} is selected as new Jackal!\nWork together and win the game!", - "Jackal_BecomeNewJackal": "Old Jackal Dead, You are now new Jackal!", - "Jackal_OnNewJackalSelected": "Old Jackal Dead, Please help new Jackal {0} for now!", - "Jackal_BossIsDead": "Opps, the Jackal boss is dead!", "CoronerArrowsPointingToDeadBody": "Arrows pointing to dead bodies", "CoronerLeaveDeadBodyUnreportable": "Bodies the Coroner uses can't be reported", "CoronerInformKillerBeingTracked": "Inform the Killer that he gets tracked", @@ -1914,9 +1869,6 @@ "VipTag": "VIP★", "ApplyVipList": "Usar la lista de VIPs", "AllowSayCommand": "Permitir el uso del comando /say", - "AllowStartCommand": "Allow moderators to use /start command", - "StartCommandMinCountdown": "Minimum countdown for /start command", - "StartCommandMaxCountdown": "Maximum countdown for /start command", "KickCommandDisabled": "El comando de expulsión está desactivado.", "KickCommandNoAccess": "No tienes acceso al comando para expulsar.", "KickCommandInvalidID": "Invalid player ID specified.\nPlease use '/kick [playerID] [reason]' to kick a player.\nExample :- /kick 5 not following rules", @@ -1949,11 +1901,6 @@ "WarnCommandNoAccess": "No tienes permiso para usar el comando warn.", "WarnCommandInvalidID": "ID de jugador especificado no válido.\nPor favor, use /warn [ID de jugador] [razón] para advertir a un jugador.\nPor ejemplo, /warn 5 hablar durante la cinemática de exilio", "WarnCommandWarnHost": "No puedes dar advertencias al anfitrión.", - "StartCommandNoAccess": "You do not have access to the start command.", - "StartCommandDisabled": "The start command is currently disabled.", - "StartCommandCountdown": "ERROR\n\nThe game is already starting!", - "StartCommandStarted": "The game has been started by {0}!", - "StartCommandInvalidCountdown": "ERROR\n\nThe countdown must be between {0} and {1}!", "WarnCommandWarnMod": "No puedes dar advertencias a otros moderadores.", "WarnCommandWarned": "ha sido advertido. No habrá más avisos y acciones apropiadas serán tomadas ", "WarnExample": "Usa /warn [id] [razón] en el futuro. \nPor ejemplo:- /warn 5 hablar durante la cinemática de exilio", @@ -1981,7 +1928,6 @@ "DeathReason.Quantization": "Quantificado", "DeathReason.Overtired": "Agotado", "DeathReason.Ashamed": "Avergonzado", - "DeathReason.Consumed": "Consumed", "DeathReason.PissedOff": "Destruido", "DeathReason.Dismembered": "Descuartizado", "DeathReason.LossOfHead": "Estrangulado", @@ -2005,8 +1951,6 @@ "DeathReason.Starved": "Starved", "DeathReason.Equilibrium": "Equilibrium", "DeathReason.Sacrificed": "Sacrificed", - "DeathReason.Electrocuted": "Electrocuted", - "DeathReason.Scavenged": "Scavenged", "OnlyEnabledDeathReasons": "Solo usar Causas de Muerte activadas", "Alive": "Vivo", "Disconnected": "Disconnected", @@ -2072,7 +2016,6 @@ "Command.dump": "→ Poner los Registros en el Escritorio", "Command.death": "→ Muestra información de cómo has muerto", "Command.icons": "
╳ - The Player was marked by the Blackmailer and can't talk during the Meeting
☆ - Used by Captain to display themselves. Only Crewmates can see the Captain's star
乂 - This player was hexed by the Hex Master and will die if the Hex Master isn't killed or ejected by the end of the Meeting.
♦ - Used by Lawyer or Executioner or Follower.
♥ - Used by Lovers or Romantic.
✚ - Used by Medic to mark their target.
⦿ - This player is in a duel with the Pirate.
!? - This player was marked by the Quizmaster and must answer the question correctly to survive.
☜ - Used by Schrödinger's cat to mark their teammate.
◈ - This player marked by the Shroud and will die if the Shroud is not killed or ejected by the end of the meeting.
⚠ - This player is a Snitch or Solsticer who has finished their tasks.
★ - Used by Super Star or Cyber or Marshall.
† - This player was spelled and will die if the Witch is not killed by the end of the meeting.
∇ - Used by Kamikaze to mark their targets.
■ - Used by Lightning to mark their quantum ghosts.
⊠ - Used by Jailer to mark their prisoner.
● - Used by Baker to mark who has Bread.
♠ - Used by Soul Collector to mark who's death they're predicting.
⦿ - Used by Plaguebearer to mark who they have plagued.", - "Command.start": "[Seconds] → Start the game", "Command.iconinfo": "→ Mostrar información sobre los iconos de reuniones", "Command.iconhelp": "→ Mostrar información sobre los iconos de reuniones a todo el mundo", "Command.Poll": "→ Start a poll with up-to 5 choices", @@ -2085,7 +2028,6 @@ "ShowMadmatesInLeftCommand": "Show Madmates (including add-ons)", "ShowApocalypseInLeftCommand": "Show Neutral Apocalypse", "SeeEjectedRolesInMeeting": "Ver los roles de los exiliados en las reuniones", - "ThankYouForUsingTOHE": "Thank you for using TOHE!", "SkillUsedLeft": "Has activado tu habilidad para llamar una reunión. \nUsos restantes:", "NemesisDeadMsg": "The death of the Nemesis means the beginning of the revenge. \nPlease use /rv + [player ID] to kill the specified player \nYou can see player IDs in front of their names. \nOr type /rv to get a list of player IDs", "NemesisAliveKill": "Revenge for the Nemesis can only begin after their death.", @@ -2102,10 +2044,9 @@ "WorkaholicAdviceAlive": "No se recomiende matar o exiliar a [{0}]. Hacerlo conlleva a que pueda terminar sus tareas más rápido.", "GuessDead": "Desafortunadamente, no puedes adivinar otros roles al morir", "GuessSuperStar": "The Super Star can't be guessed... you thought it would be that easy, right?", - "GuessNotifiedBait": "La Carnada no puede ser adivinado porque fue anunciado. Creías que sería tan fácil, ¿verdad?", + "GuessNotifiedBait": "Bait can't be guessed because it was announced. You thought it would be that easy, right?", "GuessGM": "Adivinar al Maestro del Juego es imposible porque ya está muerto... ¿Y por qué le harías eso al pobre Anfitrión?", "GuessGuardianTask": "No puedes adivinar a un Guardian que haya acabado sus tareas.", - "GuardianCantKilled": "You can't kill a Guardian who has finished their tasks.", "GuessMarshallTask": "No puedes adivinar a un Mariscal que haya terminado sus tareas.", "GuessObviousAddon": "Lo sentimos, pero no se puede adivinar ningún agregado obvio.", "GuessAdtRole": "Desgraciadamente, el Anfitrión no te deja adivinar agregados", @@ -2145,9 +2086,9 @@ "MediumNotifyTarget": "{0}, the Medium, has established contact with you. Before the end of this meeting, you have a chance to respond to their question. Type one of the following commands to answer:\nConfirm: /ms yes\nDeny: /ms no", "MediumNotifySelf": "You established contact with {0}. Please ask them questions and wait for them to respond.\n\nRemaining ability uses: {1}", "MediumKnowPlayerDead": "Someone died somewhere", - "SpurtMinSpeed": "Velocidad Mínima", - "SpurtMaxSpeed": "Velocidad Máxima", - "SpurtModule": "Modulador de Velocidad", + "SpurtMinSpeed": "Min Speed", + "SpurtMaxSpeed": "Max Speed", + "SpurtModule": "Speed Modulator", "EnableSpurtCharge": "Muestra la carga", "SpurtSuffix": "\n« Spurt: {0}% »", "TargetIsAlreadyDead": "Target Is Already Dead", @@ -2161,7 +2102,6 @@ "BecomeMadmateCuzMadmateMode": "Te volviste un Cómplice porque has muerto", "CleanerCleanBody": "El cadáver ha sido limpiado", "QuickShooterStoraging": "Balas guardado con éxito", - "QuickShooterFailed": "You are still in cooldown.", "PoisonerTargetDead": "Tu objetivo ha muerto", "HexesLookLikeSpells": "Los Maleficios aparecen como Hechizos", "HexButtonText": "Maleficio", @@ -2320,7 +2260,6 @@ "Message.YTPlanNotice": "Nota: El [Plan de Youtuber] está activado en esta sala. Cual significa que el Anfitrión puede especificar el rol que quiera para la próxima partida para simplificarle la vida en el momento de crear contenido. Si abusa de esta función, sal de la sala o denúncialo.\nCredenciales del Creador:", "Message.OnlyCanBeUsedByHost": "ERROR\n\nEste comando es exclusivo al Anfitrión.", "Message.MaxPlayers": "Máximo de jugadores configurado a ", - "Message.MaxPlayersFailByRegion": "Could not set max players: Vanilla regions support a maximum of 15 players.", "Message.GhostRoleInfo": "Ghost Role Info\nHiya! A little about ghost roles...\n\nGhost roles drastically impact the game, so it's not recommended for smaller lobbies if you're unfamiliar. If not explicitly stated otherwise in the description, the Guard button is their ability button ;)\n\nSpawning:\nGhost-roles only spawn after death; the first x people from (team) to die get them.\n\nPS: If your previous role didn't have tasks(e.g., sheriff), your tasks as a ghost-role aren't needed for task-win", "ApocalypseInfoTitle": "Neutral Apocalypse Info:", "Message.ApocalypseInfo": "Every role of the <#ff174f>Apocalypse Team has their own objective to carry out in order to transform.\n<#2B0804>Transformed <#ff174f>Apocalypse members have a drastic change on the game and are immortal (except for being voted), but everyone will be notified that they have transformed.\n\nRoles: <#e5f6b4>Plaguebearer, <#A675A1>Soul Collector, <#bf9f7a>Baker, <#cc0044>Berserker\nTransformed: <#343136>Pestilence, <#644661>Death, <#83461c>Famine, <#2B0804>War\n\nApocalypse members can see eachother's roles and ability icons.\nLike Neutral Killers, Apocalypse members keep the game going as well, have fun!", @@ -2725,9 +2664,8 @@ "DeathMeetingTimeIncrease": "Increased Meeting time when Death exists", "SoulCollectorMeetingDeath": "Your target has died during the meeting. You have gained a soul.", "SoulCollectorKillButtonText": "Predict", - "SoulCollectorHasImpostorVision": "Soul Collector has Impostor vision", "ApocalypseIsNigh": "[ The Apocalypse Is Nigh! ]", - "ApocalypseImmune": "This role is immune!", + "ApocalypseImmune": "¡Este jugador es inmune porque es invencible!", "BakerToFamine": "¡¡¡¡¡¡Te has convertido en Hambruna!!!", "BakerTransform": "The Baker has transformed into Famine, Horseman of the Apocalypse! A famine has begun!", "BakerAlreadyBreaded": "¡Ese jugador ya tiene pan!", @@ -2736,15 +2674,13 @@ "BakerBreadNeededToTransform": "Número requerido de pan para ser Hambruna", "BakerCantBreadApoc": "¡No puedes matar de hambre a otros miembros del Apocalipsis!", "BakerKillButtonText": "Pan", - "BakerUnshiftButtonText": "Switch Bread", "BakerRevealBread": "Revela", "BakerRoleblockBread": "Bloque de Rol", "BakerBarrierBread": "Barrera", "BakerCurrentBread": "Pan Actual: ", "BakerSwitchBread": "Pan a cambiado a: ", - "BakerCanVent": "Baker can Vent", + "BakerCanVent": "Panadero puede usar los conductos", "BakerBreadGivesEffects": "El pan da efectos adicionales", - "BakerTransformNoMoreBread": "Baker transforms if they do not have enough bread", "FamineKillButtonText": "Hambre", "FamineStarveCooldown": "Tiempo de espera de la Hambruna para matar de hambre", "FamineCantStarveApoc": "¡No puedes matar de hambre a otros miembros del Apocalipsis!", @@ -2791,7 +2727,6 @@ "GodfatherTargetCountMode": "El asesino se convierte en", "GodfatherCount_Refugee": "Refugiado", "GodfatherCount_Madmate": "Loco", - "GodfatherRefugeeMsg": "You have been recruited by GodFather!", "MissChance": "Posibilidad de fracaso", "IncreaseByOneIfConvert": "Increase The KillCount +1 If a Crew Is Converted", "HawkMissed": "Fallastes!", @@ -2824,7 +2759,6 @@ "BerserkerToWar": "¡¡¡Te has convertido en Guerra!!!", "BerserkerTransform": "The Berserker has transformed into War, Horseman of the Apocalypse! Cry 'Havoc!', and let slip the dogs of war.", "WarKillCooldown": "Tiempo de espera para muertes de guerra", - "BerserkerCanKillTeamate": "Can kill other Neutral Apocalypse", "BlackmailerSkillCooldown": "Tiempo de espera para extorsionar", "BlackmailerMax": "Veces máximas en las que jugadores extorsionados podrán hablar", "BlackmailerDead": "¡Aviso! ¡{0} ha sido extorsionado por un Extorsionista! (No podrá hablar durante esta reunión)!", @@ -2914,8 +2848,6 @@ "RememberedPursuer": "¡Has recordado ser un Perseguidor!", "RememberedFollower": "¡Has recordado ser un Seguidor!", "RememberedAmnesiac": "Fallaste al intentar recordar tu rol.", - "AmnesiacRemembered": "You remembered you were {0}!", - "ReportWhenFailedRemember": "Report Dead Body when failed to remember", "RememberedImitator": "Recordaste que eras un Imitador.", "RememberedImpostor": "¡Recordaste que eras un Impostor!", "RememberedCrewmate": "¡Recordaste que eras un Tripulante!", @@ -2985,7 +2917,7 @@ "InspectCheckTargetMsg": " fue revisado por un Inspector.", "InspectCheckHelp": "Instrucciones: /cp [ID de jugador 1] [ID de jugador 2] \nEjemplo: /cmp 1 5 \nPuedes ver las IDs de jugadores al lado del nombre de todos \n o usar el comando /id para ver la lista de todas las IDs de jugadores", "InspectCheckNull": "Por favor, selecciona el ID de un jugador vivo para revisar si están en el mismo equipo", - "InspectCheckBaitCountMode": "Carnada cuenta como un rol que revela si la opción de que Carnada revela a la primera reunión está encendida", + "InspectCheckBaitCountMode": "Carnada cuenta como un rol que revela si la opción de que Carnada revela en primera reunión está encendida", "InspectCheckRevealTarget": "Cuando las tareas sean terminadas, el objetivo sabra el equipo de otro objetivo", "InspectorTargetReveal": " Parece ser que {0} está alineado con el equipo {1}", "EgoistCountMode.Original": "Original", @@ -3329,12 +3261,9 @@ "PixieTargetAlreadySelected": "Ya has elegido a esta persona. Aunque la odies, solo la puedes seleccionar una vez", "PixieButtonText": "Marcar", "PlagueBearerCooldown": "Tiempo de espera para pasar plaga", - "PlagueBearerCanVent": "Can vent", - "PlagueBearerHasImpostorVision": "Has Impostor vision", "PestilenceCooldown": "Tiempo de espera para matar de la Pestilencia", "PestilenceCanVent": "La Pestilencia Puede Usar Ducto", "PestilenceHasImpostorVision": "La Pestilencia Tiene Visión de Impostor", - "PestilenceKillGuessers": "Kill players who guess Pestilence", "PlagueBearerAlreadyPlagued": "El Jugador ya tenía la plaga", "PlagueBearerToPestilence": "¡¡Te has convertido en la Pestilencia!!", "GuessPestilence": "¡Has intentado adivinar la Pestilencia!\n\nLo sentimos, la Pestilencia te mató.", @@ -3378,7 +3307,6 @@ "EveryoneCanKnowMini": "Todos pueden ver al Mini", "CanBeEvil": "El Mini puede ser un Impostor", "EvilMiniSpawnChances": "Probabilidad de que el Mini sea un Impostor", - "EvilMiniCanBeGuessed": "Evil Mini can be guessed before 18", "GuessMini": "Lo sentimos, pero no puedes herir a un Mini.", "GrowUpDuration": "Tiempo requerido para crecer", "MajorCooldown": "Tiempo de espera para matar cuando se tiene más de 18", @@ -3520,7 +3448,6 @@ "WinnerRoleText.Doppelganger": "El Doble Gana!", "WinnerRoleText.Quizmaster": "El Interrogador ha Ganado!", "WinnerRoleText.Agitater": "¡El Agitador ha Ganado!", - "WinnerRoleText.Shocker": "Shocker Wins!", "AdditionalWinnerRoleText.Sidekick": "Secuaz", "AdditionalWinnerRoleText.Taskinator": "Tarearista", "AdditionalWinnerRoleText.Opportunist": "Oportunista", @@ -3563,8 +3490,8 @@ "InfluencedChangeVote": "¡Uy! ¡Fuiste influenciado por los otros!\n¡No pudiste contener tu miedo y tu voto ha cambiado a {0}!", "FFA": "Todos Contra Todos", "ModeFFA": "Modo de Juego: TCT", - "ModeDescribe.FFA": "En el modo de juego TCT (Todos Contra Todos), todos son asesinos y se puede matar a quien sea. El último jugador con vida gana.\n\nAlgunos eventos pondrán hacer que esto sea mucho mas divertido de vez en cuando!", - "KillerInfoLong": "En el modo de juego TCT (Todos Contra Todos), todos son asesinos y se puede matar a quien sea. El último jugador con vida gana.\n\nAlgunos eventos pondrán hacer que esto sea mucho mas divertido de vez en cuando!", + "ModeDescribe.FFA": "In the FFA (Free For All) gamemode, everyone is a killer, and everyone can kill anyone. The last player alive wins!\n\nSome random events make this even more fun in the meantime!", + "KillerInfoLong": "In the FFA (Free For All) game mode, everyone is a killer, and everyone can kill anyone. The last player alive wins!\n\nSome random events make this even more fun in the meantime!", "FFA_GameTime": "Duración Máxima del Juego", "FFA_KCD": "Tiempo de Espera para Matar", "FFA_DisableVentingWhenTwoPlayersAlive": "Prevenir uso de conductos cuando solo dos jugadores estan vivos", @@ -3606,7 +3533,7 @@ "SolsticerOnMeeting": "¡Fuiste testigo de demasiadas muertes! ¡Tendrás {0} tareas cortas más durante la siguiente ronda!", "SolsticerTitle": "Solicitador", "GuessSolsticer": "Lo lamento, pero no puedes adivinar al Solicitador!", - "ExpelSolsticer": "Sorry, but you can not expel Solsticer!", + "VoteSolsticer": "Lo lamento, pero no puedes votar por el Solicitador!", "SolsticerTasksReset": "Tus tareas fueron reiniciadas!", "SolsticerMisGuessed": "Tu intento de adivinar fue errónia. Ya no podrás adivinar.", "SolsticerGuessMax": "Como ya te has ecivocado de adivinar, no seras permetido a adivinar.", @@ -3707,28 +3634,6 @@ "MinionAbilityTime": "Duración del Habilidad", "Minion_Blind": "cegado", "Evader_ChanceNotExiled": "Probabilidad de no ser exiliado", - "ShockerAbilityCooldown": "Ability Cooldown", - "ShockerAbilityDuration": "Ability Duration", - "ShockerAbilityPerRound": "Abilities Per Round", - "ShockerShockInVents": "Shock people in vents", - "ShockerAbilityResetAfterMeeting": "Reset marked rooms after meeting", - "ShockerOutsideRadius": "Radius Of Outside Tasks (not in a room)", - "ShockerCanShockHimself": "Can Shock Himself", - "ShockerImpostorVision": "Shocker has Impostor vision", - "ShockerIsShocking": "You're already shocking!", - "ShockerAbilityActivate": "Begin Shocking!", - "ShockerAbilityDeactivate": "Ability Deactivated", - "ShockerVentButtonText": "Shock", - "ShockerRoomMarked": "Marked Room", "EavesdropperMsgTitle": "Has encontrado un secreto", - "EavesdropPercentChance": "Oportunidad de escuchar", - "ChiefOfPoliceSkillCooldown": "Cooldown for recruiting sheriffs", - "PolicCanImpostorAndNeutarl": "Can recruit Impostor or Neutral", - "SheriffSuccessfullyRecruited": "You recruited a sheriff.", - "BeSheriffByPolice": "You've been recruited by the police chief! Serve the crew!", - "PoliceFailedRecruit": "Failed to recruit target.", - "ChiefOfPoliceKillButtonText": "Recruitment", - "PolicPreventRecruitNonKiller": "Prevent recruit players without kill button", - "PolicSuidiceWhenTargetNotKiller": "Suidices when recruit a non killer or non crewmate", - "PolicPassConverted": "Can pass Converted Addon to Sheriff" -} \ No newline at end of file + "EavesdropPercentChance": "Chance to eavesdrop" +} diff --git a/Resources/Lang/es_ES.json b/Resources/Lang/es_ES.json index 0ecf63c67..89c4569b5 100644 --- a/Resources/Lang/es_ES.json +++ b/Resources/Lang/es_ES.json @@ -19,8 +19,6 @@ "SubText.Neutral": "Trabaja de tu parte para hacerte con la victoria", "SubText.Apocalypse": "Become unstoppable with your team", "SubText.Madmate": "Ayuda a los Impostores", - "SubText.Lovers": "Stay alive and win together", - "SubText.Egoist": "Win on your own", "TypeImpostor": "Impostores", "TypeCrewmate": "Tripulantes", "TypeNeutral": "Neutros", @@ -30,9 +28,6 @@ "TeamNeutral": "Neutro", "TeamCrewmate": "Tripulante", "TeamMadmate": "Loco", - "TeamLovers": "Lovers", - "TeamEgoist": "Egoist", - "TeamApocalypse": "Apocalypse", "YouAreCrewmate": "Eres un Tripulante", "YouAreImpostor": "Eres un Impostor", "YouAreNeutral": "Eres Neutro", @@ -224,7 +219,6 @@ "TaskManager": "Administrador De Tareas", "Witness": "Testigo", "Swapper": "Intercambiador", - "ChiefOfPolice": "Chief of Police", "NiceMini": "Mini Amable", "Mini": "Mini", "Spy": "Espía", @@ -253,7 +247,6 @@ "Stalker": "Acosador", "Workaholic": "Trabajólico", "Solsticer": "Empleado del Mes", - "Abyssbringer": "Abyssbringer", "Collector": "Coleccionista", "Provocateur": "Provocador", "BloodKnight": "Caballero Sanguinario", @@ -392,8 +385,6 @@ "Sloth": "Caminante", "Prohibited": "Prohibited", "Eavesdropper": "Eavesdropper", - "Shocker": "Shocker", - "Revenant": "Revenant", "BracketAddons": "Dar Corchetes a Complementos", "EngineerTOHEInfo": "Desplázate en los conductos de ventilación para espiar a los Impostores", "ScientistTOHEInfo": "Accede a las constantes cuando quieras", @@ -512,7 +503,6 @@ "PacifistInfo": "Resetea el tiempo de espera de todos", "RebirthInfo": "Vuelve a la vida", "MonarchInfo": "Da a la tripulación el poder de votos extra", - "AbyssbringerInfo": "Create Black Holes", "SpurtInfo": "Spring Like A rabbit!", "StealthInfo": "Matar ciega a todos en la habitación", "PenguinInfo": "Arrastra a tus víctimas", @@ -546,7 +536,6 @@ "WitnessInfo": "Ve si alguien ha asesinado recientemente", "GhastlyInfo": "Toma control de otros jugadores", "SwapperInfo": "Intercambia los votos entre dos jugadores", - "ChiefOfPoliceInfo": "Hire Sheriff to Serve the Crews!", "NiceMiniInfo": "Nadie podrá matarte hasta que te vuelvas mayor.", "ArsonistInfo": "Empapa con gasolina a todos y que arda todo", "PyromaniacInfo": "Moja y mátalos a todos", @@ -707,8 +696,6 @@ "SlothInfo": "Vas más despacio", "ProhibitedInfo": "Certain vents are blocked", "EavesdropperInfo": "Listen in on other roles", - "ShockerInfo": "Shock unsuspecting players", - "RevenantInfo": "Take your killer's role", "EngineerTOHEInfoLong": "(Tripulantes):\nEl Ingeniero puede usar los conductos si el Sabotaje de Comunicaciones está inactivo.", "ScientistTOHEInfoLong": "(Tripulantes):\nEl Científico puede ver los constantes en cualquier momento para ver quién está vivo o no.", "NoisemakerTOHEInfoLong": "(Tripulantes):\nEl Alertador hará ruido al morir, y un indicador visual de su muerte aparecerá en la pantalla para que la Tripulación pueda correr hasta el lugar del crimen y atrapar al asesino (Aun si no es Rojo).", @@ -780,11 +767,11 @@ "LurkerInfoLong": "(Impostores):\nEl Acechador puede saltar dentro de un conducto para reducir su tiempo de espera para matar de unos segundos. Después de matar, el tiempo de espera se restablecerá a su valor inicial.", "VisionaryInfoLong": "(Impostores):\nEl Visionario puede ver el equipo de cualquier jugador vivo durante una reunión.\nLa información siguiente se mostrará al jugador.:\n- Los nombres rojos indican a los Impostores.\n- Los nombres en azul claro indican a la Tripulación.\n- Los nombres en gris indican los Neutros.", "PlagueDoctorInfoLong": "(Neutros):\n(Doctor de la Peste de TOH)\nEl objetivo del Científico Plaguista es infectar a todos los jugadores vivos. Comienzan eligiendo a un jugador para infectar, tras lo cual cualquiera que pase una cantidad de tiempo determinada en el rango del jugador infectado se infecta también. El progreso de la infección es acumulativo y no se reinicia con la distancia o después de las reuniones.", - "RefugeeInfoLong": "(Madmates):\nAs the Refugee, you were either:\n -An Amnesiac who remembered an Impostor\n -A killer who killed the Godfather's target.\n -A Romantic whose partner was an Impostor\n -Or an Imitator that imitated an Impostor.\n\nNow your job is to help the Impostors kill the crewmates.", + "RefugeeInfoLong": "(Locos):\nEl rol de Refugiado es dado cuando un Amnésico recuerda a un impostor o cuando un asesino mata al objetivo del Padrino.\n\nSu trabajo ahora es el mismo que el de un impostor normal y corriente: ayudar a los impostores y matar a la tripulación.", "UnderdogInfoLong": "(Impostores):\nEl Indefenso no puede matar hasta que sólo queden un cierto número de jugadores vivos.", "ConsigliereInfoLong": "(Impostores):\nEl Consigliere puede revelar los roles de otros jugadores usando el botón de matar.\n\n- Un clic: Revelar el rol\n- Doble clic: Matar\n\nSi te quedas sin usos de revelar roles, tu botón de matar funcionará normalmente.", "LudopathInfoLong": "(Impostores):\nEl Ludópata tiene un tiempo de espera para matar aleatorio.\n\nEl mínimo es de 1 segundo, el máximo es tu tiempo de espera para matar por defecto.", - "GodfatherInfoLong": "(Impostors):\nAs the Godfather, you vote someone to make them your target.\nIn the next round, if someone kills the target, the killer will turn into a Refugee or Madmate.", + "GodfatherInfoLong": "(Impostores):\nEl Padrino puede votar a alguien para convertirlo en tu objetivo.\nEn la próxima ronda, si alguien lo mata, el asesino se volverá un Refugiado.", "ChronomancerInfoLong": "(Impostors):\nAs the Chronomancer, you have a charge bar which indicates when the slaughter is ready. When it is at 100% the next time you kill someone, you go into slaughter mode, meaning you can kill indefinitely until your bar runs out of charge. Otherwise, you have a normal KCD.", "PitfallInfoLong": "(Impostores):\nLa Trampa puede cambiar de forma para marcar un área alrededor del lugar como una trampa. Cualquier jugador que se acerque a esta área será inmovilizado durante un breve periodo de tiempo y será cegado.", "EvilMiniInfoLong": "(Impostores):\nEl Niño Malvado tendrá un tiempo de espera para matar alto que será reducido drásticamente al convertirse en un adulto. En cambio, mientras que seas un Niño, el resto de la tripulación se siente incapaz de tocarte.", @@ -856,7 +843,6 @@ "TaskManagerInfoLong": "(Tripulantes):\nVes el número total de tareas completas por todos al lado del nombre de tu rol. Se actualiza en tiempo real.", "WitnessInfoLong": "(Tripulantes):\nEl Testigo se dará cuenta si un jugador a asesinado hace X segundos o no usando su botón de matar (X depende de las opciones).", "SwapperInfoLong": "(Crewmates):\nAs the Swapper, you can swap votes in meetings.\n\nTo swap votes, use '/sw [playerID]' twice.\n\nPlayer IDs are displayed next to player names in meetings, but you can also use /id to get a list of all player IDs.\n\nNote: Depending on the Host's settings, you can exchange your own votes.", - "ChiefOfPoliceInfoLong": "(Crewmates):\nPlayers with swords can be recruited to join the sheriff's team to serve the crew\nNote: only one recruitment opportunity\nDepending on settings, you may recruit non killers or non crews.\nYou may suidice for recruiting wrong target.", "NiceMiniInfoLong": "(Crewmates):\nAs a Nice Mini, your survival is crucial. You can't be killed until you grow up, and if you die or are evicted from the meeting before you grow up, everyone loses. This unique role adds a new dynamic to the game, where your survival is not just for your benefit but for the entire Crew's success.", "SpyInfoLong": "(Tripulantes):\nEl Espía sabrá si alguien usó su botón de matar en él (El nombre de quien usó su habilidad tendrá su nombre en naranja durante unos segundos).\nNota: Da igual a qué equipo pertenece quien haya usado su habilidad, verás su nombre en naranja.\nNota 2: Al acabarse los usos de la habilidad, no verás nombres en naranja\nNota 3: Si la interación es bloqueada, el tiempo de espera del jugador será de 10s", "RandomizerInfoLong": "(Tripulantes):\nLa Ruleta Rusa hará que, al morir, gire la ruleta de la fortuna. Tu asesino puede acabar haciendo una de estas cosas:\n 1. Auto-Reporte\n 2. Quedarse de piedra (No podrá moverse)\n 3. Una pausa publicitaria de 10 minutos (Tiempo de espera para matar de 600s durante el resto de la ronda)\n 4. Perder los estribos, tomándola con otra persona en la partida y matándolo.", @@ -871,7 +857,7 @@ "LawyerInfoLong": "(Neutros):\nEl Abogado tiene un cliente a quien defender, que será indicado con un diamante 「♦」 al lado de su nombre.\nSi tu cliente gana, ganarás.\nSi pierde, perderás.", "OpportunistInfoLong": "(Neutros):\nSi el Oportunista sobrevive hasta el final, ganará con el equipo ganador.", "VectorInfoLong": "(Neutros):\nVector ganará solo si usa los conductos un cierto número de veces.", - "JackalInfoLong": "(Neutrals):\nAs the Jackal, you win if you are the last player alive. Additionally, you may recruit using the kill button. If the target is not one you can recruit, you have run out of uses, or you don't have the option to recruit, then you will kill people normally (i.e., don't use kill buttons in front of others thinking it'll recruit). If the target has a kill button and the option to turn into a Sidekick is on, they will become a Sidekick. Otherwise, they will gain the Recruit add-on if the option to give the Recruit add-on is on.\nDepending on the settings, when Jackal was killed, a Sidekick will be randomly selected as the new Jackal.\nRecruit may be selected if no sidekick is alive.", + "JackalInfoLong": "(Neutrals):\nAs the Jackal, you win if you are the last player alive. Additionally, you may recruit using the kill button. If the target is not one you can recruit, you have run out of uses, or you don't have the option to recruit, then you will kill people normally (i.e., don't use kill buttons in front of others thinking it'll recruit). If the target has a kill button and the option to turn into a Sidekick is on, they will become a Sidekick. Otherwise, they will gain the Recruit add-on if the option to give the Recruit add-on is on.", "GodInfoLong": "(Neutros):\nEl Dios conoce el rol de todo el mundo desde el principio. Si sobrevives hasta el final del juego, robarás la victoria. Es decir, todos los demás pierden y tú ganas.", "InnocentInfoLong": "(Neutros):\nEl Inocente puede usar el botón de matar para hacer que otro jugador lo asesine. Si este es votado en cualquier momento de la partida, el Inocente ganará. Nota: El Bufón, el Verdugo y el Inocente pueden ganar juntos.", "PelicanInfoLong": "(Neutros):\nEl Pelícano puede usar el botón de matar para zamparte a un jugador vivo, teletransportándolos fuera del mapa pero sin matarlos directamente. Aquellos que sean tragados morirán sólamente si sigues vivo al final de la ronda. Si mueres o te desconectas durante la ronda, todos los jugadores tragados que sigan vivos aparecerán donde estabas antes de morir o desconectarte.", @@ -883,7 +869,7 @@ "SolsticerInfoLong": "(Neutrals):\nAs the Solsticer, you won't die, and you win by finishing all your tasks in a single round. After every meeting finishes, your tasks reset, and you need to start all over again.\nVotes on the Solsticer will be directly canceled.\nKill attempts on the Solsticer will teleport it out of the map like Pelican until the meeting is finished.\nThe killer's kill cooldown will be reset to 10 seconds.\nSolsticer is counted as nothing in-game.", "CollectorInfoLong": "(Neutros):\nEl Coleccionista puede votar por un jugador. Por cada voto que vaya para ese jugador, ganas un punto. Cuando consigas un cierto número de votos, ganarás, aun si el Bufón o el objetivo del Verdugo fueron exiliados.", "GlitchInfoLong": "(Neutros):\nEl Glitch puede hackear a jugadores (Un clic) o matar normalmente (Doble clic). Aquellos que hayan sido hackeados no pueden matar, usar conductos ni informar durante la duración del hackeo. Además, causar un sabotaje (excluyendo las puertas) no tendrá efecto y, en su lugar, te disfrazará con la apariencia de otro jugador al azar. No puedes disfrazarte en medio de un sabotaje o si ya hubo un sabotaje hace un rato. Para ganar, sé el último jugador en pie.", - "SidekickInfoLong": "(Neutrals):\nAs the Sidekick, your job is to help the Jackal kill everyone.\nYou and the Jackal win together.\nDepending on the settings, you may turn into Jackal if old Jackal was killed.\nYou may not be able to kill until old Jackal is dead.", + "SidekickInfoLong": "(Neutros):\nComo el Secuaz, tu trabajo es ayudar al Chacal a matar a todos.\n\nTú y el Chacal ganáis juntos.", "ProvocateurInfoLong": "(Neutros):\nEl Provocador puede matar a cualquiera con el botón de matar. Si el objetivo pierde al final del juego, el Provocador gana con los ganadores.", "BloodKnightInfoLong": "(Neutros):\nEl Caballero Sanguinario obtiene un escudo temporal después de cada asesinato que lo hace inmortal durante unos segundos.", "PlagueBearerInfoLong": "(Apocalypse):\nAs the Plaguebearer, plague everyone using your kill button to turn into Pestilence.\nOnce you turn into Pestilence, you will become immortal and gain the ability to kill, and you will kill anyone who tries to kill you.\n\nAlso, when infected players interact with uninfected players, they will also be infected.", @@ -910,12 +896,11 @@ "TraitorInfoLong": "(Neutros):\nEl Traidor era un impostor que ha traicionado a los impostores.\nSabes quienes son los impostores, pero ellos no saben quién eres.\n¿Cuál es la traba? Te pueden matar, y no puedes defenderte de ellos.\n\nElimina a los impostores de otro modo, y mata a todos para ganar!", "TrollerInfoLong": "(Neutrals):\nAs a Troller, you can complete tasks so that random events can happen to players.\nFor example, changing the speed of all players, teleportation, influencing sabotage, etc.\nAlso you can win with the winning team.", "VultureInfoLong": "(Neutros):\nEl Buitre gana reportando cadáveres.\n\nCuando intentes informar de un cadáver, si tu tiempo de espera para comer se haya acabado, te comerás el cadáver, lo que lo hará imposible de reportar.\nSi tu tiempo de espera para comer aún no se acabó o si llegas al límite de cadáveres por ronda, reportarás el cadáver normalmente.", - "AbyssbringerInfoLong": "(Impostors):\nAs the Abyssbringer, you can place black holes. Black holes will suck in players and kill them when colliding with them.", "TaskinatorInfoLong": "(Neutros):\nEl Tarea-Ineitor puede poner una bomba en una tarea una vez que la termine. Si otro jugador hace esa tarea, la bomba le explotará en toda la cara, matándolo en el proceso.\n\nGanarás si sobrevives hasta el final y si la Tripulación no gana.\n\n Nota: Las bombas del Tarea-Ineitor ignoran todas las protecciones.", "BenefactorInfoLong": "(Tripulantes):\nAl hacer tareas, el Bienhechor las marcará. Cuando otro tripulante haga esta tarea, recibirá un escudo temporal.\n\n Nota: Los escudos solo protegen contra ataques directos.", "MedusaInfoLong": "(Neutros):\nMedusa puede convertir los cadáveres en piedra, similar a si lo limpiaras.\nLos cadáveres convertidos en piedra no pueden ser reportados.\n\nMáta a todos para ganar.", "SpiritcallerInfoLong": "(Neutros):\nCuando el Capturador de Espíritus mata, sus víctimas se transformarán en Espíritus Malignos al morir. Estos espíritus te ayudarán a alzarte con la victoria congelando a otros jugadores por un tiempo limitado y/o cegándolos. Alternativamente, los espíritus pueden darte un escudo que te proteje brevemente de cualquier intento de asesinato.", - "AmnesiacInfoLong": "(Neutrals):\nAs the Amnesiac, use your report button to remember a target and get its role.\nTo balance the game, you will not be able to vent after remembering your role if you can't vent as Amnesiac.'", + "AmnesiacInfoLong": "(Neutros):\nEl Amnésico deberá usar el botón de informe para recordar un rol.\n\nSi el cadáver viene de un Impostor, te transformarás en un Refugiado.\nSi viene de un tripulante, te convertirás en Sheriff.\nSi viene de un neutro pasivo o de un asesino neutro no compatible, te volverás el rol definido en las opciones.\nSi viene de ciertos neutros asesinos, copiarás su rol.", "ImitatorInfoLong": "(Neutros):\nEl Imitador puede usar su botón de matar para imitar a otra persona.\n\nTe podrás convertir en un Sheriff, Refugiado o en algún Neutro.", "BanditInfoLong": "(Neutrals):\nAs the Bandit, you can click your kill button one time to steal a player's addon and twice to kill. Depending on the settings, you may instantly steal the addon or after the meeting starts. After the maximum number of steals is reached, you will kill normally. Additionally, if there are no stealable addons on the target or the target is stubborn, you will kill the target.\n\nKill everyone to win.\n\nNote: Cleansed, Last Impostor, and Lovers cannot be stolen.\nNote: If Bandit can vent is on, Nimble will become unstealable.", "DoppelgangerInfoLong": "(Neutros):\nEl Doble puede asesinar a otro jugador para robarle su identidad (Su nombre y apariencia).\n\nMátalos a todos para ganar.\n\nNota:- No podrás robar la identidad de tu objetivo si un camuflaje de cualquier tipo está ocurriendo.", @@ -936,7 +921,6 @@ "JinxInfoLong": "(Neutros):\nEl Gafado matará a quien intente atacarte.\nEsto tiene usos limitados.\n\nMata a todos para matar.", "PotionMasterInfoLong": "(Neutros):\nEl Maestro de las Pociones tiene tres pociones, asignadas a tres acciones distintas.\n\nUn clic revela el rol de una persona.\nDos clics matarán al jugador.\nEl mapa permite sabotear.\nLa poción de revelar tiene un límite, y cuando te acabes esa poción, el botón de matar servirá como un botón de matar por defecto.", "NecromancerInfoLong": "(Neutros):\nEl Nigromante ganará si es el único en vida.\nAdemás de esto, si alguien intenta matarte, este intento será bloqueado y serás teletransportado a un conducto al azar. Tendrás un límite de tiempo para vengarte de tu asesino. Si lo consigues, sobrevivirás. Si te quedas sin tiempo antes de poder matar a tu asesino, morirás de verdad. Si intentas matar a otra persona que no sea tu asesino, cometerás suicidio.", - "ShockerInfoLong": "(Neutrals):\nAs the Shocker, you can mark rooms by doing tasks in them, and then vent to Electrocute anyone in those rooms for a set period of time. When you finish all of your tasks, you get new ones. Note: Doing tasks during that period will mark them for the next ability use.", "LastImpostorInfoLong": "(Complementos):\nEste efecto es otorgado al último impostor en vida. Reduce tu tiempo de espera para matar.", "OverclockedInfoLong": "(Complementos):\nEl tiempo de espera para matar del Acelerado será reducido por un porcentaje.\n\nSolo asignable a roles con un botón para matar.", "LoversInfoLong": "(Add-ons):\nLovers are a combination of two players. The Lovers win when they are the last ones standing, and their victory is shared. When one of the Lovers wins, the other also wins together. Lovers can see the 「♥」 next to each other's name. If one of the Lovers dies, the other will die in love (may not die in love according to the Host's settings). When one of the Lovers is exiled in the meeting, the other will die and become a dead body that cannot be reported.", @@ -980,7 +964,7 @@ "RebirthInfoLong": "(Add-ons):\nAs the Rebirth, if you're the player about to be ejected, you will swap skins with a random crewmate who voted for you.\nNotice: The host vote never counts\nRebirth will be removed from you if you exhausted all your rebirths.", "LoyalInfoLong": "(Complementos): \nEl Leal no puedes ser reclutado por roles como el Chacal o el Líder de Secta. No se le puede asignar a los neutros.", "EvilSpiritInfoLong": "(Complementos): \nEl Espíritu Maligno tiene una tarea: Ayudar al Capturador de Espíritus a la victoria. Puedes usar tu botón de atormentar para petrificar a otros jugadores y reducir su visión. Alternativamente, puedes usar tu botón de atormentar para proteger temporalmente al Capturador de Espíritus con un escudo.", - "RecruitInfoLong": "(Betrayal Add-ons):\nAs a recruit, you are on the Jackal's team and help out the Jackal and their Sidekicks.\nYou cannot win with your original team.\nDepending on the settings, you may turn into Jackal if old Jackal was killed and no sidekicks is alive.", + "RecruitInfoLong": "(Complementos de Traición):\nComo Recluta, estás en el equipo del Chacal y ayudas al Chacal y a sus Secuaces.\n\nNo puedes ganar con tu equipo original.", "AdmiredInfoLong": "(Complementos de Traición):\nEl Admirado gana con la tripulación, no con tu equipo original.\n\nPuedes ver quién es el Admirador.", "GlowInfoLong": "(Add-ons):\nDuring lights out, you and players nearby you will receive a vision boost.", "RadarInfoLong": "(Add-ons):\nAs Radar, you have arrows pointing towards the closest person at all times.", @@ -1024,7 +1008,6 @@ "ProhibitedInfoLong": "(Add-ons):\nAs the Prohibited, you have specific vents that you can't use.\nHow many vents are disabled depends on the Host's settings.", "EavesdropperInfoLong": "(Add-ons):\nAs the Eavesdropper, you have a chance to read other role/addon information-based messages like Mortician or Sleuth.", "ApocalypseInfoLong": "(Apocalypse):\nApocalypse members are on a separate team that works together and wins together. If there are multiple Apocalypse roles in the game, they can see each other's roles.\nDepending on the Host's settings, Apocalypse roles can guess or be guessed.", - "RevenantInfoLong": "(Neutral):\nAs the Revenant, your goal is to be killed. If you are killed, you will take your killer's role and kill your killer instead. You cannot win before being killed.\nNote that Revenant only works when being directly killed.", "ShowTextOverlay": "Superposición de texto", "Overlay.GuesserMode": "Modo Adivino", "Overlay.NoGameEnd": "Partida Sin Fin", @@ -1038,8 +1021,6 @@ "AbilityUseLimit": "Límite de uso de abilidades inicial", "AbilityInUse": "Habilidad en uso", "AbilityExpired": "Ability expired, {0} uses remain", - "RevenantTargeted": "Your role has changed to {0}", - "RevenantCanCopyAddons": "Can Steal Addons", "ShowArrows": "Flechas indicando cadáveres", "ArrowDelayMin": "Retraso mínimo de aparición de flechas", "ArrowDelayMax": "Retraso máximo de aparición de flechas", @@ -1368,8 +1349,6 @@ "ShieldedCanUseKillButton": "Shielded player can use ability / kill button", "PlayerIsShieldedByGame": "Player is protected by the game!", "LegacyNemesis": "Versión de Town of Host 1.4.0", - "LegacyParasite": "Use Legacy Version", - "LegacyTraitor": "Use Legacy Version", "ArsonistKeepsGameGoing": "El Incendiario hace que la partida continue", "ArsonistCanIgniteAnytime": "Puede prender fuego en cualquier momento", "ArsonistMinPlayersToIgnite": "Mínimo de jugadores a empapar para prender fuego", @@ -1512,18 +1491,6 @@ "SheriffCanKillSeparately": "Opciones individuales", "In%team%": "(Equipo %team%)", "SheriffMisfireKillsTarget": "Un disparo erróneo mata a la víctima", - "BlackHolePlaceCooldown": "Black Hole Place Cooldown", - "BlackHoleDespawnMode": "Black Hole Despawn Mode", - "BlackHoleDespawnTime": "Time After Black Hole Despawns", - "Abyssbringer.Suffix": "<#00ffa5>Number of players consumed by {0} <#00ffa5>active black holes:\\n{1}", - "Abyssbringer.Suffix.BlackHole": "<#00ffa5>{0}: {1}", - "BlackHoleMovesTowardsNearestPlayer": "Black Hole Moves Towards Nearest Player", - "BlackHoleMoveSpeed": "Black Hole Moving Speed", - "BlackHoleRadius": "Black Hole Consuming Radius", - "AfterTime": "After Time", - "After1PlayerEaten": "After 1 Player Was Eaten", - "AfterMeeting": "After Meeting", - "None": "None", "SheriffShotLimit": "Número máximo de asesinatos", "SheriffCanKillAllAlive": "Puede asesinar cuando todo el mundo está vivo", "SheriffCanKillCharmed": "Puede matar a Hechizados", @@ -1540,15 +1507,12 @@ "RebirthUses": "Número de Renacimientos", "RebirthCountVotes": "Solo renacer jugadores que hayan votado por él", "RebirthFailed": "Desgraciadamente, no encontraste ningún alma con la que puedas intercambiarte", - "FireworkerCooldown": "Placement Cooldown", "ReverieIncreaseKillCooldown": "Aumentar el tiempo de espera para matar", "ReverieMaxKillCooldown": "Tiempo de espera para matar máximo", "ReverieMisfireSuicide": "Fallar disparo al llegar a tu tiempo de espera máximo para matar", "ReverieResetCooldownMeeting": "Reiniciar tiempo de espera para matar después de una reunión", "ConvertedReverieKillAll": "El Ensimismado puede matar como le dé la gana si es convertido", "VigilanteNotify": "Te convertiste en aquello que juraste destruir", - "DictatorChangeCommandToExpel": "Dictator use Command to expell instad of vote", - "DictatorExpelSelf": "WAIT WAIT WAIT WAT THE HELLLLLL Bro really just want to expel himself", "DoctorTaskCompletedBatteryCharge": "Duración de la batería", "SnitchEnableTargetArrow": "Ve flechas hacia el blanco", "SnitchCanGetArrowColor": "Ve flechas de colores con colores del equipo", @@ -1629,7 +1593,6 @@ "EvilTrackerTargetMode.OnceInGame": "Una vez en toda la partida", "EvilTrackerTargetMode.EveryMeeting": "Cada reunión", "EvilTrackerTargetMode.Always": "En cualquier momento", - "ScavengerHasCustomDeathReason": "Enable Custom Death Reason", "EvilHackerCanSeeDeadMark": "Can See The Location of Dead-bodies", "EvilHackerCanSeeImpostorMark": "Can See The Location of Other Impostors", "EvilHackerCanSeeKillFlash": "Puede ver un flash por muertes", @@ -1862,21 +1825,13 @@ "Jackal_SidekickCountMode_Jackal": "Chacal", "Jackal_SidekickCountMode_Original": "Equipo de Origen", "Jackal_SidekickAssignMode": "Modo de asignación de los Secuaces", - "Jackal_SidekickAssignMode_SidekickAndRecruit": "Sidekick when failed Recruit", - "Jackal_SidekickAssignMode_Sidekick": "Only Sidekick", - "Jackal_SidekickAssignMode_Recruit": "Only Recruit", + "Jackal_SidekickAssignMode_SidekickAndRecruit": "Sidekick+Recruit", + "Jackal_SidekickAssignMode_Sidekick": "Sidekick Only", + "Jackal_SidekickAssignMode_Recruit": "Recruit Only", + "JackalWinWithSidekick": "El Chacal puede ganar con sus Secuaces", "Jackal_SidekickCanKillSidekick": "Sidekicks can kill other Sidekicks", "Jackal_SidekickCanKillJackal": "Sidekick can kill Jackal", - "Jackal_RecruitFailed": "You can not recruit this player!", "JackalCanKillSidekick": "El Chacal puede matar a sus Secuaces", - "Jackal_SidekickCanKillWhenJackalAlive": "Sidekick can kill while Jackal is Alive", - "Jackal_SidekickTurnIntoJackal": "Sidekick can turn into Jackal after its death", - "Jackal_RestoreLimitOnNewJackal": "Restore Recruit limit when Sidekick become new Jackal", - "Jackal_OnBecomeNewJackalMeeting": "The old Jackal {0} is dead.\nYou are selected as new Jackal\nWork together and win the game!", - "Jackal_OnNewJackalSelectedMeeting": "The old Jackal {0} is dead.\n{1} is selected as new Jackal!\nWork together and win the game!", - "Jackal_BecomeNewJackal": "Old Jackal Dead, You are now new Jackal!", - "Jackal_OnNewJackalSelected": "Old Jackal Dead, Please help new Jackal {0} for now!", - "Jackal_BossIsDead": "Opps, the Jackal boss is dead!", "CoronerArrowsPointingToDeadBody": "Arrows pointing to dead bodies", "CoronerLeaveDeadBodyUnreportable": "Bodies the Coroner uses can't be reported", "CoronerInformKillerBeingTracked": "Inform the Killer that he gets tracked", @@ -1914,9 +1869,6 @@ "VipTag": "VIP★", "ApplyVipList": "Usar la lista de VIPs", "AllowSayCommand": "Permitir el uso de /s", - "AllowStartCommand": "Allow moderators to use /start command", - "StartCommandMinCountdown": "Minimum countdown for /start command", - "StartCommandMaxCountdown": "Maximum countdown for /start command", "KickCommandDisabled": "El comando de expulsión está desactivado", "KickCommandNoAccess": "No tienes acceso al comando para expulsar", "KickCommandInvalidID": "Invalid player ID specified.\nPlease use '/kick [playerID] [reason]' to kick a player.\nExample :- /kick 5 not following rules", @@ -1949,11 +1901,6 @@ "WarnCommandNoAccess": "No tienes permiso al comando warn", "WarnCommandInvalidID": "ID de jugador especificado no válido.\nPor favor, use /warn [IDjugador] [razón] para advertir a un jugador.\nPor ejemplo, /warn 5 hablar durante la cinemática de exilio", "WarnCommandWarnHost": "No puedes poner advertencias al anfitrión", - "StartCommandNoAccess": "You do not have access to the start command.", - "StartCommandDisabled": "The start command is currently disabled.", - "StartCommandCountdown": "ERROR\n\nThe game is already starting!", - "StartCommandStarted": "The game has been started by {0}!", - "StartCommandInvalidCountdown": "ERROR\n\nThe countdown must be between {0} and {1}!", "WarnCommandWarnMod": "No puedes poner advertencias a otros moderadores", "WarnCommandWarned": "ha sido advertido. No habrá más avisos y acciones apropiadas serán tomadas \n", "WarnExample": "Usa /warn [id] [razón] en el futuro. \nPor ejemplo, /warn 5 hablar durante la cinemática de exilio", @@ -1981,7 +1928,6 @@ "DeathReason.Quantization": "Cuantificado", "DeathReason.Overtired": "Agotado", "DeathReason.Ashamed": "Avergonzado", - "DeathReason.Consumed": "Consumed", "DeathReason.PissedOff": "Destrozado", "DeathReason.Dismembered": "Descuartizado", "DeathReason.LossOfHead": "Estrangulado", @@ -2005,8 +1951,6 @@ "DeathReason.Starved": "Starved", "DeathReason.Equilibrium": "Equilibrium", "DeathReason.Sacrificed": "Sacrificed", - "DeathReason.Electrocuted": "Electrocuted", - "DeathReason.Scavenged": "Scavenged", "OnlyEnabledDeathReasons": "Solo usar Causas de Muerte activadas", "Alive": "Vivo", "Disconnected": "Desconectado", @@ -2072,7 +2016,6 @@ "Command.dump": "→ Enviar los Logs al Escritorio", "Command.death": "→ Muestra información de cómo has muerto", "Command.icons": "
╳ - Este jugador fue mandado a callar por el Chantajista y no puede hablar durante esta reunión
☆ - Usado por el Capitán para demostrarse a sí mismo. Sólo la Tripulación puede ver la estrella del Capitán
乂 - El Hechicero echó un mal de ojo a este jugador. Si no es expulsado o asesinado durante esta reunión, morirá.
♦ - Usado por el Abogado, el Verdugo o el Seguidor.
♥ - Usado por los Amantes o el Romántico.
✚ Usado por el Médico para marcar a su objetivo.
⦿ - Este jugador está en un duelo con el Pirata.
!? - Este jugador fue marcado por el Interrogador y debe responder a la pregunta correctamente para sobrevivir.
☜ - Usado por el Gato de Schrödinger para marcar a su compañero.
◈ - Este jugador fue marcado por la Mortaja y morirá si esta no es asesinada o exiliada antes del final de esta reunión.
∇ - Usado por el Kamikaze para marcar a sus víctimas.
■ - Usado por la Centella para marcar a sus fantasmas cuánticos.
⊠ - Usado por el Carcelero para marcar a su prisionero.
● - Usado por el Panadero para marcar quién tiene Pan.
♠ - Usado por el Collector de Almas para marcar qué muerte va a predecir.
⦿ - Usado por el Transmisor de la Plaga para ver quien ha sido infectado por la Plaga.", - "Command.start": "[Seconds] → Start the game", "Command.iconinfo": "→ Mostrar información sobre los iconos de reuniones", "Command.iconhelp": "→ Mostrar información sobre los iconos de reuniones a todo el mundo", "Command.Poll": "→ Empezar una encuesta con hasta 5 elecciones posibles", @@ -2085,7 +2028,6 @@ "ShowMadmatesInLeftCommand": "Mostrar a los Locos (Incluyendo complementos)", "ShowApocalypseInLeftCommand": "Show Neutral Apocalypse", "SeeEjectedRolesInMeeting": "Ver los roles de los exiliados en las reuniones", - "ThankYouForUsingTOHE": "Thank you for using TOHE!", "SkillUsedLeft": "Has activado tu habilidad para llamar una reunión. \nUsos restantes:", "NemesisDeadMsg": "La muerte del Némesis anuncia el comienzo del reino de la venganza. \nUse /rv + [ID del jugador] para matar al jugador especificado \nPuedes ver el ID de los jugadores al lado de sus nombres. \nO escribe /rv para tener la lista de los IDs de los jugadores.", "NemesisAliveKill": "La venganza del Némesis solo podrá comenzar después de su muerte.", @@ -2105,7 +2047,6 @@ "GuessNotifiedBait": "Bait can't be guessed because it was announced. You thought it would be that easy, right?", "GuessGM": "Hay que ser desagradecido para adivinar al pobre Anfitrión. Y encima de eso, está muerto. ¿Acaso no te has dado cuenta?", "GuessGuardianTask": "No puedes adivinar a un Guardian que haya acabado sus tareas.", - "GuardianCantKilled": "You can't kill a Guardian who has finished their tasks.", "GuessMarshallTask": "No puedes adivinar a un Mariscal que haya terminado sus tareas.", "GuessObviousAddon": "Lo sentimos, pero no se puede adivinar ningún complemento obvio.", "GuessAdtRole": "Desgraciadamente, el Anfitrión no te deja adivinar complementos", @@ -2161,7 +2102,6 @@ "BecomeMadmateCuzMadmateMode": "Te volviste loco porque has muerto", "CleanerCleanBody": "El cadáver ha sido limpiado", "QuickShooterStoraging": "Balas guardadas exitosamente", - "QuickShooterFailed": "You are still in cooldown.", "PoisonerTargetDead": "Tu objetivo ha muerto", "HexesLookLikeSpells": "Los males de ojo aparecen como hechizos", "HexButtonText": "Mal de ojo", @@ -2320,7 +2260,6 @@ "Message.YTPlanNotice": "Nota: El Plan Youtube está activado en esta sala. El Anfitrión podrá especificar el rol que quiera para la próxima partida para simplificarle la vida en el momento de crear contenido. Si abusa de esta función, sal de la sala o denúncialo.\nCredenciales del Creador:", "Message.OnlyCanBeUsedByHost": "ERROR\n\nEste comando es exclusivo al Anfitrión.", "Message.MaxPlayers": "Máximo de jugadores configurado a ", - "Message.MaxPlayersFailByRegion": "Could not set max players: Vanilla regions support a maximum of 15 players.", "Message.GhostRoleInfo": "Información sobre Roles de Fantasma\n¡Hola! Un poco sobre los roles de fantasma...\n\nLos roles de fantasma impactan drásticamente en el juego, por lo que no se recomiendan para lobbies pequeños, si no estás familiarizado.\n\nAparición:\nLos roles de fantasma solo aparecen después de la muerte, las primeras x personas de (equipo) en morir los obtienen.\n\nPD: Si tu rol anterior no tenía tareas (por ejemplo, sheriff), tus tareas como rol de fantasma no son necesarias para ganar por tareas", "ApocalypseInfoTitle": "Neutral Apocalypse Info:", "Message.ApocalypseInfo": "Every role of the <#ff174f>Apocalypse Team has their own objective to carry out in order to transform.\n<#2B0804>Transformed <#ff174f>Apocalypse members have a drastic change on the game and are immortal (except for being voted), but everyone will be notified that they have transformed.\n\nRoles: <#e5f6b4>Plaguebearer, <#A675A1>Soul Collector, <#bf9f7a>Baker, <#cc0044>Berserker\nTransformed: <#343136>Pestilence, <#644661>Death, <#83461c>Famine, <#2B0804>War\n\nApocalypse members can see eachother's roles and ability icons.\nLike Neutral Killers, Apocalypse members keep the game going as well, have fun!", @@ -2725,9 +2664,8 @@ "DeathMeetingTimeIncrease": "Increased Meeting time when Death exists", "SoulCollectorMeetingDeath": "Your target has died during the meeting. You have gained a soul.", "SoulCollectorKillButtonText": "Predict", - "SoulCollectorHasImpostorVision": "Soul Collector has Impostor vision", "ApocalypseIsNigh": "[ The Apocalypse Is Nigh! ]", - "ApocalypseImmune": "This role is immune!", + "ApocalypseImmune": "This player is immune because they are invincible!", "BakerToFamine": "You have become Famine!!!", "BakerTransform": "The Baker has transformed into Famine, Horseman of the Apocalypse! A famine has begun!", "BakerAlreadyBreaded": "That player already has bread!", @@ -2736,15 +2674,13 @@ "BakerBreadNeededToTransform": "Required number of bread to become Famine", "BakerCantBreadApoc": "You cannot give other Apocalypse members bread!", "BakerKillButtonText": "Bread", - "BakerUnshiftButtonText": "Switch Bread", "BakerRevealBread": "Reveal", "BakerRoleblockBread": "Roleblock", "BakerBarrierBread": "Barrier", "BakerCurrentBread": "Current Bread: ", "BakerSwitchBread": "Bread Switched to: ", - "BakerCanVent": "Baker can Vent", + "BakerCanVent": "Baker can Vent", "BakerBreadGivesEffects": "Bread gives additional effects", - "BakerTransformNoMoreBread": "Baker transforms if they do not have enough bread", "FamineKillButtonText": "Starve", "FamineStarveCooldown": "Famine starve cooldown", "FamineCantStarveApoc": "You cannot starve other Apocalypse members!", @@ -2791,7 +2727,6 @@ "GodfatherTargetCountMode": "El Asesino se convierte en", "GodfatherCount_Refugee": "Refugee", "GodfatherCount_Madmate": "Loco", - "GodfatherRefugeeMsg": "You have been recruited by GodFather!", "MissChance": "Chance To Miss", "IncreaseByOneIfConvert": "Increase The KillCount +1 If a Crew Is Converted", "HawkMissed": "Missed!", @@ -2824,7 +2759,6 @@ "BerserkerToWar": "You have become War!!!", "BerserkerTransform": "The Berserker has transformed into War, Horseman of the Apocalypse! Cry 'Havoc!', and let slip the dogs of war.", "WarKillCooldown": "War kill cooldown", - "BerserkerCanKillTeamate": "Can kill other Neutral Apocalypse", "BlackmailerSkillCooldown": "Tiempo de Espera para Chantajear", "BlackmailerMax": "Máximo de veces que los jugadores chantajeados pueden hablar", "BlackmailerDead": "Peligro! El Chantajista hizo chantaje a {0}!", @@ -2914,8 +2848,6 @@ "RememberedPursuer": "Recordaste que te gusta perseguir metas", "RememberedFollower": "Recordaste que te gustaba hacerle la pelota a la gente", "RememberedAmnesiac": "Aun así, no te acuerdas de quien eres", - "AmnesiacRemembered": "You remembered you were {0}!", - "ReportWhenFailedRemember": "Report Dead Body when failed to remember", "RememberedImitator": "Recordaste que te gusta imitar a otras personas.", "RememberedImpostor": "Recordaste que levantabas sospechas. Es verdad, eras un Impostor!", "RememberedCrewmate": "Recordaste el momento en el que la nave despegó. Eres un tripulante!", @@ -3329,12 +3261,9 @@ "PixieTargetAlreadySelected": "Ya has elegido a esta persona. Aunque la odies, solo la puedes seleccionar una vez", "PixieButtonText": "Marcar", "PlagueBearerCooldown": "Tiempo de Espera para pasar la Plaga", - "PlagueBearerCanVent": "Can vent", - "PlagueBearerHasImpostorVision": "Has Impostor vision", "PestilenceCooldown": "Tiempo de Espera para Matar (Pestilencia)", "PestilenceCanVent": "Puede usar conductos (Pestilencia)", "PestilenceHasImpostorVision": "Tiene visión de Impostor (Pestilencia)", - "PestilenceKillGuessers": "Kill players who guess Pestilence", "PlagueBearerAlreadyPlagued": "El jugador ya tiene la plaga", "PlagueBearerToPestilence": "Has evolucionado en Pestilencia!", "GuessPestilence": "Has intentado adivinar a la Pestilencia.\n\nDesgraciadamente, nadie adivina a la Pestilencia. La Pestilencia te adivina a tí.", @@ -3378,7 +3307,6 @@ "EveryoneCanKnowMini": "Todos pueden ver al Niño", "CanBeEvil": "El Niño puede ser Malvado", "EvilMiniSpawnChances": "Probabilidad de que el Niño sea Malvado", - "EvilMiniCanBeGuessed": "Evil Mini can be guessed before 18", "GuessMini": "No está bien intentar adivinar a un Niño indefenso. ¿Qué clase de monstruo eres?", "GrowUpDuration": "Tiempo necesario para volverse mayor (s)", "MajorCooldown": "Tiempo de Espera para matar (Adulto)", @@ -3520,7 +3448,6 @@ "WinnerRoleText.Doppelganger": "¡El Doble ha ganado!", "WinnerRoleText.Quizmaster": "Quizmaster Wins!", "WinnerRoleText.Agitater": "Agitator Wins!", - "WinnerRoleText.Shocker": "Shocker Wins!", "AdditionalWinnerRoleText.Sidekick": "Secuaz", "AdditionalWinnerRoleText.Taskinator": "Tarearista", "AdditionalWinnerRoleText.Opportunist": "Oportunista", @@ -3606,7 +3533,7 @@ "SolsticerOnMeeting": "¡Fuiste testigo de demasiadas muertes! ¡Tendrás {0} tareas cortas más durante la siguiente ronda!", "SolsticerTitle": "Empleado del Mes", "GuessSolsticer": "El Empleado del Mes está demasiado implicado en su trabajo para ser adivinado.", - "ExpelSolsticer": "Sorry, but you can not expel Solsticer!", + "VoteSolsticer": "Votar al Empleado del Mes causaría la bancarrota de la empresa. Vota a otra persona.", "SolsticerTasksReset": "Tus tareas fueron reiniciadas!", "SolsticerMisGuessed": "Tu intento de adivinar fue erróneo. Ya no podrás adivinar.", "SolsticerGuessMax": "Debido a que ya te has equivocado al adivinar, no puedes hacerlo de nuevo.", @@ -3707,28 +3634,6 @@ "MinionAbilityTime": "Duración de la Habilidad", "Minion_Blind": "blinded", "Evader_ChanceNotExiled": "Chance not be exiled", - "ShockerAbilityCooldown": "Ability Cooldown", - "ShockerAbilityDuration": "Ability Duration", - "ShockerAbilityPerRound": "Abilities Per Round", - "ShockerShockInVents": "Shock people in vents", - "ShockerAbilityResetAfterMeeting": "Reset marked rooms after meeting", - "ShockerOutsideRadius": "Radius Of Outside Tasks (not in a room)", - "ShockerCanShockHimself": "Can Shock Himself", - "ShockerImpostorVision": "Shocker has Impostor vision", - "ShockerIsShocking": "You're already shocking!", - "ShockerAbilityActivate": "Begin Shocking!", - "ShockerAbilityDeactivate": "Ability Deactivated", - "ShockerVentButtonText": "Shock", - "ShockerRoomMarked": "Marked Room", "EavesdropperMsgTitle": "You found a secret", - "EavesdropPercentChance": "Chance to eavesdrop", - "ChiefOfPoliceSkillCooldown": "Cooldown for recruiting sheriffs", - "PolicCanImpostorAndNeutarl": "Can recruit Impostor or Neutral", - "SheriffSuccessfullyRecruited": "You recruited a sheriff.", - "BeSheriffByPolice": "You've been recruited by the police chief! Serve the crew!", - "PoliceFailedRecruit": "Failed to recruit target.", - "ChiefOfPoliceKillButtonText": "Recruitment", - "PolicPreventRecruitNonKiller": "Prevent recruit players without kill button", - "PolicSuidiceWhenTargetNotKiller": "Suidices when recruit a non killer or non crewmate", - "PolicPassConverted": "Can pass Converted Addon to Sheriff" -} \ No newline at end of file + "EavesdropPercentChance": "Chance to eavesdrop" +} diff --git a/Resources/Lang/fil_PH.json b/Resources/Lang/fil_PH.json index f9009e7e2..e83f22081 100644 --- a/Resources/Lang/fil_PH.json +++ b/Resources/Lang/fil_PH.json @@ -19,8 +19,6 @@ "SubText.Neutral": "Magtrabaho ng mag-isa upang makamit ang iyong tagumpay", "SubText.Apocalypse": "Become unstoppable with your team", "SubText.Madmate": "Tulungan ang mga Impostors", - "SubText.Lovers": "Stay alive and win together", - "SubText.Egoist": "Win on your own", "TypeImpostor": "Impostors", "TypeCrewmate": "Crewmates", "TypeNeutral": "Neutrals", @@ -30,9 +28,6 @@ "TeamNeutral": "Niyutral", "TeamCrewmate": "Crewmate", "TeamMadmate": "Madmate", - "TeamLovers": "Lovers", - "TeamEgoist": "Egoist", - "TeamApocalypse": "Apocalypse", "YouAreCrewmate": "Ikaw ay isang Crewmate", "YouAreImpostor": "Ikaw ay isang Impostor", "YouAreNeutral": "Ikaw ay isang Niyutral", @@ -224,7 +219,6 @@ "TaskManager": "Task Manager", "Witness": "Witness", "Swapper": "Swapper", - "ChiefOfPolice": "Chief of Police", "NiceMini": "Nice Mini", "Mini": "Mini", "Spy": "Espiya", @@ -253,7 +247,6 @@ "Stalker": "Stalker", "Workaholic": "Workaholic", "Solsticer": "Solsticer", - "Abyssbringer": "Abyssbringer", "Collector": "Collector", "Provocateur": "Provocateur", "BloodKnight": "Blood Knight", @@ -392,8 +385,6 @@ "Sloth": "Sloth", "Prohibited": "Prohibited", "Eavesdropper": "Eavesdropper", - "Shocker": "Shocker", - "Revenant": "Revenant", "BracketAddons": "Add Brackets To Add-ons", "EngineerTOHEInfo": "Use the vents to catch the Impostors", "ScientistTOHEInfo": "Access portable vitals from anywhere", @@ -512,7 +503,6 @@ "PacifistInfo": "Vent to reset kill cooldowns", "RebirthInfo": "Arise Again", "MonarchInfo": "Give your crew extra voting power!", - "AbyssbringerInfo": "Create Black Holes", "SpurtInfo": "Spring Like A rabbit!", "StealthInfo": "Killing Blinds Everyone in the Room", "PenguinInfo": "Drag your victims", @@ -546,7 +536,6 @@ "WitnessInfo": "Find out if someone killed recently", "GhastlyInfo": "Control somebody!", "SwapperInfo": "Swap the votes of two players", - "ChiefOfPoliceInfo": "Hire Sheriff to Serve the Crews!", "NiceMiniInfo": "No one can hurt you until you grow up.", "ArsonistInfo": "Douse everyone and ignite", "PyromaniacInfo": "Douse and kill everyone", @@ -707,8 +696,6 @@ "SlothInfo": "You're slower", "ProhibitedInfo": "Certain vents are blocked", "EavesdropperInfo": "Listen in on other roles", - "ShockerInfo": "Shock unsuspecting players", - "RevenantInfo": "Take your killer's role", "EngineerTOHEInfoLong": "(Crewmates):\nAs the Engineer, you may access the vents while Comms Sabotaged is inactive.", "ScientistTOHEInfoLong": "(Crewmates):\nAs the Scientist, you can see vitals at any time, showing you who is alive and dead.", "NoisemakerTOHEInfoLong": "(Crewmates):\nAs the Noisemaker, whenever you die, you will make a noise, and a visual indicator of your death appears on the screen so the Crewmates can run to catch the person who killed you red-handed (even if it’s not Red).", @@ -780,11 +767,11 @@ "LurkerInfoLong": "(Impostors):\nAs the Lurker, you can jump into a vent to reduce your cooldown by a certain number of seconds. After you kill, your cooldown resets to its original value.", "VisionaryInfoLong": "(Impostors):\nAs the Visionary, you see the alignments of living players during a meeting.\nThe following information will be displayed on the players:\n- The Red name indicates the Impostors.\n- The Cyan name indicates the Crewmates.\n- The Gray name indicates the Neutrals.", "PlagueDoctorInfoLong": "(Neutrals):\n(Plague Doctor from TOH)\nThe Plague Scientist's goal is to infect every living player.\nThey start by choosing one player to infect, after which anyone who spends a set amount of time in the range of the infected player becomes infected themselves.\nInfection progress is cumulative and does not reset with distance or after meetings.", - "RefugeeInfoLong": "(Madmates):\nAs the Refugee, you were either:\n -An Amnesiac who remembered an Impostor\n -A killer who killed the Godfather's target.\n -A Romantic whose partner was an Impostor\n -Or an Imitator that imitated an Impostor.\n\nNow your job is to help the Impostors kill the crewmates.", + "RefugeeInfoLong": "(Madmates):\nAs the Refugee, you were either an Amnesiac who remembered an Impostor or a killer who killed the Godfather's target.\n\nNow your job is to help the Impostors kill the crewmates.", "UnderdogInfoLong": "(Impostors):\nAs the Underdog, you cannot kill until there's a certain amount of players alive.", "ConsigliereInfoLong": "(Impostors):\nAs the Consigliere, you can reveal the roles of other players using your kill button.\n\nSingle click: Reveal role\nDouble click: Kill\n\nIf you run out of reveal uses, your kill button functions normally.", "LudopathInfoLong": "(Impostors):\nAs the Ludopath, your kill cooldown is randomized.\n\nMinimum it can be is 1 second, while the maximum is your default kill cooldown.", - "GodfatherInfoLong": "(Impostors):\nAs the Godfather, you vote someone to make them your target.\nIn the next round, if someone kills the target, the killer will turn into a Refugee or Madmate.", + "GodfatherInfoLong": "(Impostors):\nAs the Godfather, you vote someone to make them your target.\nIn the next round, if someone kills the target, the killer will turn into a Refugee.", "ChronomancerInfoLong": "(Impostors):\nAs the Chronomancer, you have a charge bar which indicates when the slaughter is ready. When it is at 100% the next time you kill someone, you go into slaughter mode, meaning you can kill indefinitely until your bar runs out of charge. Otherwise, you have a normal KCD.", "PitfallInfoLong": "(Impostors):\nAs the Pitfall, you use your shapeshift to mark the area around the shapeshift as a trap. Players who enter this area will be immobilized quickly, and their vision will be affected.", "EvilMiniInfoLong": "(Impostors):\nAs the Evil Mini, you are unkillable until you grow up and have a very long initial kill cooldown, which gets drastically shortened as you grow up.", @@ -856,7 +843,6 @@ "TaskManagerInfoLong": "(Crewmates):\nYou see the total number of tasks completed (by everyone all together) next to your role name, which updates in real-time.", "WitnessInfoLong": "(Crewmates):\nAs the Witness, when you use your kill button on someone, you will know if they killed in the last X seconds or not. (X depends on the settings).", "SwapperInfoLong": "(Crewmates):\nAs the Swapper, you can swap votes in meetings.\n\nTo swap votes, use '/sw [playerID]' twice.\n\nPlayer IDs are displayed next to player names in meetings, but you can also use /id to get a list of all player IDs.\n\nNote: Depending on the Host's settings, you can exchange your own votes.", - "ChiefOfPoliceInfoLong": "(Crewmates):\nPlayers with swords can be recruited to join the sheriff's team to serve the crew\nNote: only one recruitment opportunity\nDepending on settings, you may recruit non killers or non crews.\nYou may suidice for recruiting wrong target.", "NiceMiniInfoLong": "(Crewmates):\nAs a Nice Mini, your survival is crucial. You can't be killed until you grow up, and if you die or are evicted from the meeting before you grow up, everyone loses. This unique role adds a new dynamic to the game, where your survival is not just for your benefit but for the entire Crew's success.", "SpyInfoLong": "(Crewmates):\nAs the Spy, when someone uses their kill button on you (any ability used through the kill button), you'll see their name in orange for a few seconds.\nNote: If a Crewmate used their ability on you, you'll also see them with an orange name!\nNote: If you cannot use left, you won't see orange names!\nNote: If the kill button interaction is blocked, the player's cooldown will reset to 10s'", "RandomizerInfoLong": "(Crewmates):\nAs this Randomizer, when you die, your killer will do one of the following:\n 1. self-report your body\n 2. stand next to your body\n 3. have their kill cooldown set to 600s\n 4. Randomly avenge a player.", @@ -871,7 +857,7 @@ "LawyerInfoLong": "(Neutrals):\nLawyer has a target to defend, which will be indicated by a diamond 「♦」 next to their name.\nIf your target wins, you win.\nIf they lose, you lose.", "OpportunistInfoLong": "(Neutrals):\nIf the Opportunist survives at the end of the game, the Opportunist will win with the winning player.", "VectorInfoLong": "(Neutrals):\nVector will win alone by venting a certain number of times.", - "JackalInfoLong": "(Neutrals):\nAs the Jackal, you win if you are the last player alive. Additionally, you may recruit using the kill button. If the target is not one you can recruit, you have run out of uses, or you don't have the option to recruit, then you will kill people normally (i.e., don't use kill buttons in front of others thinking it'll recruit). If the target has a kill button and the option to turn into a Sidekick is on, they will become a Sidekick. Otherwise, they will gain the Recruit add-on if the option to give the Recruit add-on is on.\nDepending on the settings, when Jackal was killed, a Sidekick will be randomly selected as the new Jackal.\nRecruit may be selected if no sidekick is alive.", + "JackalInfoLong": "(Neutrals):\nAs the Jackal, you win if you are the last player alive. Additionally, you may recruit using the kill button. If the target is not one you can recruit, you have run out of uses, or you don't have the option to recruit, then you will kill people normally (i.e., don't use kill buttons in front of others thinking it'll recruit). If the target has a kill button and the option to turn into a Sidekick is on, they will become a Sidekick. Otherwise, they will gain the Recruit add-on if the option to give the Recruit add-on is on.", "GodInfoLong": "(Neutrals):\nAs the God, you know everyone's role from the beginning. If you live until the end of the game, you steal the win, i.e., everyone else loses, and you win.", "InnocentInfoLong": "(Neutrals):\nThe Innocent can use the kill button to plant any player, and the planted target will immediately kill the Innocent. If the target gets voted out in the meeting, the Innocent wins. Note: Jester, Executioner, and Innocent can win together.", "PelicanInfoLong": "(Neutrals):\nAs the Pelican, you can use the kill button to swallow a player alive, teleporting them off-bounds but not killing them yet. Those swallowed will only die if you're still alive at the end of the round. If you die or leave during the round, all alive swallowed players will spawn into the map where you were.", @@ -883,7 +869,7 @@ "SolsticerInfoLong": "(Neutrals):\nAs the Solsticer, you won't die, and you win by finishing all your tasks in a single round. After every meeting finishes, your tasks reset, and you need to start all over again.\nVotes on the Solsticer will be directly canceled.\nKill attempts on the Solsticer will teleport it out of the map like Pelican until the meeting is finished.\nThe killer's kill cooldown will be reset to 10 seconds.\nSolsticer is counted as nothing in-game.", "CollectorInfoLong": "(Neutrals):\nAs the Collector, when you vote for a player, for each other player that voted for them, you gain a point. When you collect the required votes, the game ends, and you win alone, even if you voted a Jester or Executioner's target out.", "GlitchInfoLong": "(Neutrals):\nAs the Glitch, you can hack players (single click) or kill normally (double click).\nThose who have been hacked cannot kill, vent, or report for the hack duration.\nAdditionally, calling a sabotage other than doors will have no effect and will instead disguise you as a random player. You cannot disguise during or after sabotages.\nTo win, be the last player alive.", - "SidekickInfoLong": "(Neutrals):\nAs the Sidekick, your job is to help the Jackal kill everyone.\nYou and the Jackal win together.\nDepending on the settings, you may turn into Jackal if old Jackal was killed.\nYou may not be able to kill until old Jackal is dead.", + "SidekickInfoLong": "(Neutrals):\nAs the Sidekick, your job is to help the Jackal kill everyone.\n\nYou and the Jackal win together.", "ProvocateurInfoLong": "(Neutrals):\nAs the Provocateur, you can kill any target with the kill button. If the target loses at the end of the game, the Provocateur wins with the winning team.", "BloodKnightInfoLong": "(Neutrals):\nThe Blood Knight wins when they're the last killing role alive, and the amount of crewmates is lower or equal to the amount of Blood Knights. The Blood Knight gains a temporary shield after every kill, making them immortal for a few seconds.", "PlagueBearerInfoLong": "(Apocalypse):\nAs the Plaguebearer, plague everyone using your kill button to turn into Pestilence.\nOnce you turn into Pestilence, you will become immortal and gain the ability to kill, and you will kill anyone who tries to kill you.\n\nAlso, when infected players interact with uninfected players, they will also be infected.", @@ -910,12 +896,11 @@ "TraitorInfoLong": "(Neutrals):\nAs the Traitor, you were an Impostor that betrayed the Impostors.\nYou know the Impostors, but they don't know you.\nThe twist? They can kill you, but you can't kill them.\n\nEliminate the Impostors by other means, then kill everyone else to win!", "TrollerInfoLong": "(Neutrals):\nAs a Troller, you can complete tasks so that random events can happen to players.\nFor example, changing the speed of all players, teleportation, influencing sabotage, etc.\nAlso you can win with the winning team.", "VultureInfoLong": "(Neutrals):\nAs the Vulture, report bodies to win!\n\nWhen you report a body, if your eat cooldown is up, you'll eat the body (makes it unreportable).\nIf your eat ability is still on cooldown, then you'll report the body normally.\n\nAdditionally, you'll report bodies normally if the maximum bodies eaten per round is reached.", - "AbyssbringerInfoLong": "(Impostors):\nAs the Abyssbringer, you can place black holes. Black holes will suck in players and kill them when colliding with them.", "TaskinatorInfoLong": "(Neutrals):\nAs the Taskinator, whenever you finish a task, the task will be bombed. When another player completes the bombed task, the bomb will detonate, and the player will die.\n\nYou win if you survive till the end and Crew doesn't win.\n\n Note: Taskinator bombs ignore all protection.", "BenefactorInfoLong": "(Crewmates):\nAs the Benefactor, whenever you finish a task, that task will be marked. When another player completes the marked task, they get a temporary shield.\n\n Note: Shield only protects from direct kill attacks.", "MedusaInfoLong": "(Neutrals):\nAs the Medusa, you can stone bodies much like cleaning a body.\nStoned bodies cannot be reported.\n\nKill everyone to win.", "SpiritcallerInfoLong": "(Neutrals):\nAs the Spiritcaller, your victims become Evil Spirits after they die. These spirits can help you win by freezing other players briefly or blocking their vision. Alternatively, the spirits can give you a shield that protects you briefly from an attempted kill.", - "AmnesiacInfoLong": "(Neutrals):\nAs the Amnesiac, use your report button to remember a target and get its role.\nTo balance the game, you will not be able to vent after remembering your role if you can't vent as Amnesiac.'", + "AmnesiacInfoLong": "(Neutrals):\nAs the Amnesiac, use your report button to remember a role.\n\nIf the target was an Impostor, you'll become a Refugee.\nIf the target was a crewmate, you'll become the target role if compatible (otherwise you become an Engineer).\nIf the target was a passive neutral or a neutral killer not specified, you'll become the role defined in the settings.\nIf the target was a neutral killer of a select few, you'll become the role they are.", "ImitatorInfoLong": "(Neutrals):\nAs the Imitator, use your kill button to imitate a player.\n\nYou'll either become a Sheriff, a Refugee, or some Neutral.", "BanditInfoLong": "(Neutrals):\nAs the Bandit, you can click your kill button one time to steal a player's addon and twice to kill. Depending on the settings, you may instantly steal the addon or after the meeting starts. After the maximum number of steals is reached, you will kill normally. Additionally, if there are no stealable addons on the target or the target is stubborn, you will kill the target.\n\nKill everyone to win.\n\nNote: Cleansed, Last Impostor, and Lovers cannot be stolen.\nNote: If Bandit can vent is on, Nimble will become unstealable.", "DoppelgangerInfoLong": "(Neutrals):\nAs the Doppelganger, use your kill button to steal a player's identity (their name and skin) and then kill your target.\n\nKill everyone to win.\n\nNote: You cannot steal the target's identity when Camouflage is active.", @@ -936,7 +921,6 @@ "JinxInfoLong": "(Neutrals):\nAs the Jinx, whenever you get attacked, you jinx them, resulting in them dying to a jinx.\nThis has limited uses.\n\nKill off everyone to win.", "PotionMasterInfoLong": "(Neutrals):\nAs the Potion Master, you have three different potions assigned to three different actions.\n\nSingle click: Reveal role\nDouble click: Kill\nMap: Sabotage\n\nThe reveal potion has a limit.\nWhen you run out, the kill buttons default to killing.", "NecromancerInfoLong": "(Neutrals):\nAs the Necromancer, you win when you're the last one standing.\nAdditionally when someone tries to kill you, you will block the kill, and you will teleport to a random vent. You will have a limited time to kill your killer. If you succeed in doing so, you live. If the time runs out before you kill your killer, you die permanently. If you try to kill someone else other than your killer, you will die.", - "ShockerInfoLong": "(Neutrals):\nAs the Shocker, you can mark rooms by doing tasks in them, and then vent to Electrocute anyone in those rooms for a set period of time. When you finish all of your tasks, you get new ones. Note: Doing tasks during that period will mark them for the next ability use.", "LastImpostorInfoLong": "(Add-ons):\nThis special effect is given to the last surviving Impostor. It significantly reduces their kill cooldown.", "OverclockedInfoLong": "(Add-ons):\nAs the Overclocked, your kill cooldown is reduced by a percentage.\n\nThis feature is only assigned to roles with a kill button.", "LoversInfoLong": "(Add-ons):\nLovers are a combination of two players. The Lovers win when they are the last ones standing, and their victory is shared. When one of the Lovers wins, the other also wins together. Lovers can see the 「♥」 next to each other's name. If one of the Lovers dies, the other will die in love (may not die in love according to the Host's settings). When one of the Lovers is exiled in the meeting, the other will die and become a dead body that cannot be reported.", @@ -980,7 +964,7 @@ "RebirthInfoLong": "(Add-ons):\nAs the Rebirth, if you're the player about to be ejected, you will swap skins with a random crewmate who voted for you.\nNotice: The host vote never counts\nRebirth will be removed from you if you exhausted all your rebirths.", "LoyalInfoLong": "(Add-ons):\nAs the Loyal, you cannot be recruited by roles such as Jackal or Cultist.\n\nCannot be assigned to neutrals.", "EvilSpiritInfoLong": "(Add-ons):\nAs Evil Spirit, it's your job to help the Spiritcaller to victory. You can use your Haunt button to freeze players and reduce their vision. Alternatively, you can use your Haunt button to give the Spiritcaller a shield against a kill attempt temporarily.", - "RecruitInfoLong": "(Betrayal Add-ons):\nAs a recruit, you are on the Jackal's team and help out the Jackal and their Sidekicks.\nYou cannot win with your original team.\nDepending on the settings, you may turn into Jackal if old Jackal was killed and no sidekicks is alive.", + "RecruitInfoLong": "(Betrayal Add-ons):\nAs a recruit, you are on the Jackal's team and help out the Jackal and their Sidekicks.\n\nYou cannot win with your original team.", "AdmiredInfoLong": "(Betrayal Add-ons):\nAs an admired player, you win with the crew and not your original team.\n\nYou can see the Admirer.", "GlowInfoLong": "(Add-ons):\nDuring lights out, you and players nearby you will receive a vision boost.", "RadarInfoLong": "(Add-ons):\nAs Radar, you have arrows pointing towards the closest person at all times.", @@ -1024,7 +1008,6 @@ "ProhibitedInfoLong": "(Add-ons):\nAs the Prohibited, you have specific vents that you can't use.\nHow many vents are disabled depends on the Host's settings.", "EavesdropperInfoLong": "(Add-ons):\nAs the Eavesdropper, you have a chance to read other role/addon information-based messages like Mortician or Sleuth.", "ApocalypseInfoLong": "(Apocalypse):\nApocalypse members are on a separate team that works together and wins together. If there are multiple Apocalypse roles in the game, they can see each other's roles.\nDepending on the Host's settings, Apocalypse roles can guess or be guessed.", - "RevenantInfoLong": "(Neutral):\nAs the Revenant, your goal is to be killed. If you are killed, you will take your killer's role and kill your killer instead. You cannot win before being killed.\nNote that Revenant only works when being directly killed.", "ShowTextOverlay": "Text Overlay", "Overlay.GuesserMode": "Guesser Mode", "Overlay.NoGameEnd": "No Game End", @@ -1038,8 +1021,6 @@ "AbilityUseLimit": "Initial Ability Use Limit", "AbilityInUse": "Ability in use", "AbilityExpired": "Ability expired, {0} uses remain", - "RevenantTargeted": "Your role has changed to {0}", - "RevenantCanCopyAddons": "Can Steal Addons", "ShowArrows": "Has Arrows pointing toward bodies", "ArrowDelayMin": "Minimum Arrow show-up delay", "ArrowDelayMax": "Maximum Arrow show-up delay", @@ -1368,8 +1349,6 @@ "ShieldedCanUseKillButton": "Shielded player can use ability / kill button", "PlayerIsShieldedByGame": "Player is protected by the game!", "LegacyNemesis": "Use Legacy Version", - "LegacyParasite": "Use Legacy Version", - "LegacyTraitor": "Use Legacy Version", "ArsonistKeepsGameGoing": "Arsonist keeps the game going", "ArsonistCanIgniteAnytime": "Can Ignite Anytime", "ArsonistMinPlayersToIgnite": "Minimum doused needed for ignite", @@ -1512,18 +1491,6 @@ "SheriffCanKillSeparately": "Individual Settings", "In%team%": "(Team %team%)", "SheriffMisfireKillsTarget": "Misfire Kills Target", - "BlackHolePlaceCooldown": "Black Hole Place Cooldown", - "BlackHoleDespawnMode": "Black Hole Despawn Mode", - "BlackHoleDespawnTime": "Time After Black Hole Despawns", - "Abyssbringer.Suffix": "<#00ffa5>Number of players consumed by {0} <#00ffa5>active black holes:\\n{1}", - "Abyssbringer.Suffix.BlackHole": "<#00ffa5>{0}: {1}", - "BlackHoleMovesTowardsNearestPlayer": "Black Hole Moves Towards Nearest Player", - "BlackHoleMoveSpeed": "Black Hole Moving Speed", - "BlackHoleRadius": "Black Hole Consuming Radius", - "AfterTime": "After Time", - "After1PlayerEaten": "After 1 Player Was Eaten", - "AfterMeeting": "After Meeting", - "None": "None", "SheriffShotLimit": "Max number of Kills", "SheriffCanKillAllAlive": "Can Kill When No One Is Dead", "SheriffCanKillCharmed": "Can kill Charmed players", @@ -1540,15 +1507,12 @@ "RebirthUses": "Amount of Rebirths", "RebirthCountVotes": "Only rebirth to players who voted for them", "RebirthFailed": "Ahh, how unfortunate, you did not find any viable souls to swap bodies with", - "FireworkerCooldown": "Placement Cooldown", "ReverieIncreaseKillCooldown": "Increase kill cooldown", "ReverieMaxKillCooldown": "Max kill cooldown", "ReverieMisfireSuicide": "Misfire on reaching max kill cooldown", "ReverieResetCooldownMeeting": "Reset kill cooldown after meeting", "ConvertedReverieKillAll": "Converted Reverie can kill anyone without repercussions", "VigilanteNotify": "You have become the very thing you swore to destroy", - "DictatorChangeCommandToExpel": "Dictator use Command to expell instad of vote", - "DictatorExpelSelf": "WAIT WAIT WAIT WAT THE HELLLLLL Bro really just want to expel himself", "DoctorTaskCompletedBatteryCharge": "Battery Duration", "SnitchEnableTargetArrow": "See Arrow Towards Target", "SnitchCanGetArrowColor": "See Colored Arrows based on Team Colors", @@ -1629,7 +1593,6 @@ "EvilTrackerTargetMode.OnceInGame": "Once in-game", "EvilTrackerTargetMode.EveryMeeting": "Every Meeting", "EvilTrackerTargetMode.Always": "Any time", - "ScavengerHasCustomDeathReason": "Enable Custom Death Reason", "EvilHackerCanSeeDeadMark": "Can See The Location of Dead-bodies", "EvilHackerCanSeeImpostorMark": "Can See The Location of Other Impostors", "EvilHackerCanSeeKillFlash": "Can See Kill-Flash", @@ -1862,21 +1825,13 @@ "Jackal_SidekickCountMode_Jackal": "Jackal", "Jackal_SidekickCountMode_Original": "Original Team", "Jackal_SidekickAssignMode": "Sidekick Assign Mode", - "Jackal_SidekickAssignMode_SidekickAndRecruit": "Sidekick when failed Recruit", - "Jackal_SidekickAssignMode_Sidekick": "Only Sidekick", - "Jackal_SidekickAssignMode_Recruit": "Only Recruit", + "Jackal_SidekickAssignMode_SidekickAndRecruit": "Sidekick+Recruit", + "Jackal_SidekickAssignMode_Sidekick": "Sidekick Only", + "Jackal_SidekickAssignMode_Recruit": "Recruit Only", + "JackalWinWithSidekick": "Jackal can win with Sidekick's team", "Jackal_SidekickCanKillSidekick": "Sidekicks can kill other Sidekicks", "Jackal_SidekickCanKillJackal": "Sidekick can kill Jackal", - "Jackal_RecruitFailed": "You can not recruit this player!", "JackalCanKillSidekick": "Jackal can kill Sidekick", - "Jackal_SidekickCanKillWhenJackalAlive": "Sidekick can kill while Jackal is Alive", - "Jackal_SidekickTurnIntoJackal": "Sidekick can turn into Jackal after its death", - "Jackal_RestoreLimitOnNewJackal": "Restore Recruit limit when Sidekick become new Jackal", - "Jackal_OnBecomeNewJackalMeeting": "The old Jackal {0} is dead.\nYou are selected as new Jackal\nWork together and win the game!", - "Jackal_OnNewJackalSelectedMeeting": "The old Jackal {0} is dead.\n{1} is selected as new Jackal!\nWork together and win the game!", - "Jackal_BecomeNewJackal": "Old Jackal Dead, You are now new Jackal!", - "Jackal_OnNewJackalSelected": "Old Jackal Dead, Please help new Jackal {0} for now!", - "Jackal_BossIsDead": "Opps, the Jackal boss is dead!", "CoronerArrowsPointingToDeadBody": "Arrows pointing to dead bodies", "CoronerLeaveDeadBodyUnreportable": "Bodies the Coroner uses can't be reported", "CoronerInformKillerBeingTracked": "Inform the Killer that he gets tracked", @@ -1914,9 +1869,6 @@ "VipTag": "VIP★", "ApplyVipList": "Apply VIP List", "AllowSayCommand": "Allow moderators to use /say command", - "AllowStartCommand": "Allow moderators to use /start command", - "StartCommandMinCountdown": "Minimum countdown for /start command", - "StartCommandMaxCountdown": "Maximum countdown for /start command", "KickCommandDisabled": "The kick command is currently disabled.", "KickCommandNoAccess": "You do not have access to the kick command.", "KickCommandInvalidID": "Invalid player ID specified.\nPlease use '/kick [playerID] [reason]' to kick a player.\nExample :- /kick 5 not following rules", @@ -1949,11 +1901,6 @@ "WarnCommandNoAccess": "You do not have access to the warn command.", "WarnCommandInvalidID": "Invalid player ID specified.\nPlease use '/warn [playerID] [reason]' to warn a player. \nExample :- /warn 5 lava chatting", "WarnCommandWarnHost": "You are not permitted to warn the host.", - "StartCommandNoAccess": "You do not have access to the start command.", - "StartCommandDisabled": "The start command is currently disabled.", - "StartCommandCountdown": "ERROR\n\nThe game is already starting!", - "StartCommandStarted": "The game has been started by {0}!", - "StartCommandInvalidCountdown": "ERROR\n\nThe countdown must be between {0} and {1}!", "WarnCommandWarnMod": "You are not permitted to warn other moderators.", "WarnCommandWarned": "has been warned. There will be no more warnings given and appropriate action will be taken \n ", "WarnExample": "Use /warn [id] [reason] in future. \nExample :-\n /warn 5 lava chatting", @@ -1981,7 +1928,6 @@ "DeathReason.Quantization": "Quantization", "DeathReason.Overtired": "Overtired", "DeathReason.Ashamed": "Ashamed", - "DeathReason.Consumed": "Consumed", "DeathReason.PissedOff": "Destroyed", "DeathReason.Dismembered": "Dismembered", "DeathReason.LossOfHead": "Strangled", @@ -2005,8 +1951,6 @@ "DeathReason.Starved": "Starved", "DeathReason.Equilibrium": "Equilibrium", "DeathReason.Sacrificed": "Sacrificed", - "DeathReason.Electrocuted": "Electrocuted", - "DeathReason.Scavenged": "Scavenged", "OnlyEnabledDeathReasons": "Only Enabled Death Reasons", "Alive": "Alive", "Disconnected": "Disconnected", @@ -2072,7 +2016,6 @@ "Command.dump": "→ Output Log to Desktop", "Command.death": "→ Display info on how you died", "Command.icons": "
╳ - The Player was marked by the Blackmailer and can't talk during the Meeting
☆ - Used by Captain to display themselves. Only Crewmates can see the Captain's star
乂 - This player was hexed by the Hex Master and will die if the Hex Master isn't killed or ejected by the end of the Meeting.
♦ - Used by Lawyer or Executioner or Follower.
♥ - Used by Lovers or Romantic.
✚ - Used by Medic to mark their target.
⦿ - This player is in a duel with the Pirate.
!? - This player was marked by the Quizmaster and must answer the question correctly to survive.
☜ - Used by Schrödinger's cat to mark their teammate.
◈ - This player marked by the Shroud and will die if the Shroud is not killed or ejected by the end of the meeting.
⚠ - This player is a Snitch or Solsticer who has finished their tasks.
★ - Used by Super Star or Cyber or Marshall.
† - This player was spelled and will die if the Witch is not killed by the end of the meeting.
∇ - Used by Kamikaze to mark their targets.
■ - Used by Lightning to mark their quantum ghosts.
⊠ - Used by Jailer to mark their prisoner.
● - Used by Baker to mark who has Bread.
♠ - Used by Soul Collector to mark who's death they're predicting.
⦿ - Used by Plaguebearer to mark who they have plagued.", - "Command.start": "[Seconds] → Start the game", "Command.iconinfo": "→ Display info on in-meeting icons", "Command.iconhelp": "→ Display info on in-meeting icons to everyone", "Command.Poll": "→ Start a poll with up-to 5 choices", @@ -2085,7 +2028,6 @@ "ShowMadmatesInLeftCommand": "Show Madmates (including add-ons)", "ShowApocalypseInLeftCommand": "Show Neutral Apocalypse", "SeeEjectedRolesInMeeting": "See ejected roles in meetings", - "ThankYouForUsingTOHE": "Thank you for using TOHE!", "SkillUsedLeft": "You have activated your skill to call a meeting. \nRemaining amount of uses left:", "NemesisDeadMsg": "The death of the Nemesis means the beginning of the revenge. \nPlease use /rv + [player ID] to kill the specified player \nYou can see player IDs in front of their names. \nOr type /rv to get a list of player IDs", "NemesisAliveKill": "Revenge for the Nemesis can only begin after their death.", @@ -2105,7 +2047,6 @@ "GuessNotifiedBait": "Bait can't be guessed because it was announced. You thought it would be that easy, right?", "GuessGM": "Guessing the GM is impossible because they're already dead.... And why would you do that to the poor Host?", "GuessGuardianTask": "You can't guess a Guardian who has finished their tasks.", - "GuardianCantKilled": "You can't kill a Guardian who has finished their tasks.", "GuessMarshallTask": "You can't guess a Marshall who has finished their tasks.", "GuessObviousAddon": "Sorry, obvious add-ons cannot be guessed.", "GuessAdtRole": "Unfortunately, the Host's settings do not allow you to guess add-ons", @@ -2161,7 +2102,6 @@ "BecomeMadmateCuzMadmateMode": "You became a Madmate because you died", "CleanerCleanBody": "The body has been cleaned", "QuickShooterStoraging": "Bullets stored successfully", - "QuickShooterFailed": "You are still in cooldown.", "PoisonerTargetDead": "Target died", "HexesLookLikeSpells": "Hexes appear as spells", "HexButtonText": "Hex", @@ -2320,7 +2260,6 @@ "Message.YTPlanNotice": "Note: The [YouTuber Plan] is enabled in this lobby, which means the Host can specify their role in the next game to make it easier to get content. If the Host abuses this feature, please exit the game or report it.\nCurrent Creator Credentials:", "Message.OnlyCanBeUsedByHost": "ERROR\n\nThis command may only be used by the host.", "Message.MaxPlayers": "Maximum players set to ", - "Message.MaxPlayersFailByRegion": "Could not set max players: Vanilla regions support a maximum of 15 players.", "Message.GhostRoleInfo": "Ghost Role Info\nHiya! A little about ghost roles...\n\nGhost roles drastically impact the game, so it's not recommended for smaller lobbies if you're unfamiliar. If not explicitly stated otherwise in the description, the Guard button is their ability button ;)\n\nSpawning:\nGhost-roles only spawn after death; the first x people from (team) to die get them.\n\nPS: If your previous role didn't have tasks(e.g., sheriff), your tasks as a ghost-role aren't needed for task-win", "ApocalypseInfoTitle": "Neutral Apocalypse Info:", "Message.ApocalypseInfo": "Every role of the <#ff174f>Apocalypse Team has their own objective to carry out in order to transform.\n<#2B0804>Transformed <#ff174f>Apocalypse members have a drastic change on the game and are immortal (except for being voted), but everyone will be notified that they have transformed.\n\nRoles: <#e5f6b4>Plaguebearer, <#A675A1>Soul Collector, <#bf9f7a>Baker, <#cc0044>Berserker\nTransformed: <#343136>Pestilence, <#644661>Death, <#83461c>Famine, <#2B0804>War\n\nApocalypse members can see eachother's roles and ability icons.\nLike Neutral Killers, Apocalypse members keep the game going as well, have fun!", @@ -2725,9 +2664,8 @@ "DeathMeetingTimeIncrease": "Increased Meeting time when Death exists", "SoulCollectorMeetingDeath": "Your target has died during the meeting. You have gained a soul.", "SoulCollectorKillButtonText": "Predict", - "SoulCollectorHasImpostorVision": "Soul Collector has Impostor vision", "ApocalypseIsNigh": "[ The Apocalypse Is Nigh! ]", - "ApocalypseImmune": "This role is immune!", + "ApocalypseImmune": "This player is immune because they are invincible!", "BakerToFamine": "You have become Famine!!!", "BakerTransform": "The Baker has transformed into Famine, Horseman of the Apocalypse! A famine has begun!", "BakerAlreadyBreaded": "That player already has bread!", @@ -2736,15 +2674,13 @@ "BakerBreadNeededToTransform": "Required number of bread to become Famine", "BakerCantBreadApoc": "You cannot give other Apocalypse members bread!", "BakerKillButtonText": "Bread", - "BakerUnshiftButtonText": "Switch Bread", "BakerRevealBread": "Reveal", "BakerRoleblockBread": "Roleblock", "BakerBarrierBread": "Barrier", "BakerCurrentBread": "Current Bread: ", "BakerSwitchBread": "Bread Switched to: ", - "BakerCanVent": "Baker can Vent", + "BakerCanVent": "Baker can Vent", "BakerBreadGivesEffects": "Bread gives additional effects", - "BakerTransformNoMoreBread": "Baker transforms if they do not have enough bread", "FamineKillButtonText": "Starve", "FamineStarveCooldown": "Famine starve cooldown", "FamineCantStarveApoc": "You cannot starve other Apocalypse members!", @@ -2791,7 +2727,6 @@ "GodfatherTargetCountMode": "Killer turns into", "GodfatherCount_Refugee": "Refugee", "GodfatherCount_Madmate": "Madmate", - "GodfatherRefugeeMsg": "You have been recruited by GodFather!", "MissChance": "Chance To Miss", "IncreaseByOneIfConvert": "Increase The KillCount +1 If a Crew Is Converted", "HawkMissed": "Missed!", @@ -2824,7 +2759,6 @@ "BerserkerToWar": "You have become War!!!", "BerserkerTransform": "The Berserker has transformed into War, Horseman of the Apocalypse! Cry 'Havoc!', and let slip the dogs of war.", "WarKillCooldown": "War kill cooldown", - "BerserkerCanKillTeamate": "Can kill other Neutral Apocalypse", "BlackmailerSkillCooldown": "Blackmail Cooldown", "BlackmailerMax": "Maximum times blackmailed players may speak", "BlackmailerDead": "Warning! {0} has been blackmailed by a Blackmailer!", @@ -2914,8 +2848,6 @@ "RememberedPursuer": "You remembered you were a Pursuer!", "RememberedFollower": "You remembered you were a Follower!", "RememberedAmnesiac": "You failed to remember your role.", - "AmnesiacRemembered": "You remembered you were {0}!", - "ReportWhenFailedRemember": "Report Dead Body when failed to remember", "RememberedImitator": "You remembered you were an Imitator.", "RememberedImpostor": "You remembered you were an Impostor!", "RememberedCrewmate": "You remembered you were a crewmate!", @@ -3329,12 +3261,9 @@ "PixieTargetAlreadySelected": "Target is already selected", "PixieButtonText": "Mark", "PlagueBearerCooldown": "Plague cooldown", - "PlagueBearerCanVent": "Can vent", - "PlagueBearerHasImpostorVision": "Has Impostor vision", "PestilenceCooldown": "Pestilence Kill cooldown", "PestilenceCanVent": "Pestilence Can Vent", "PestilenceHasImpostorVision": "Pestilence Has Impostor Vision", - "PestilenceKillGuessers": "Kill players who guess Pestilence", "PlagueBearerAlreadyPlagued": "Player has already been plagued", "PlagueBearerToPestilence": "You have turned into Pestilence!!", "GuessPestilence": "You just tried to guess Pestilence!\n\nSorry, Pestilence killed you.", @@ -3378,7 +3307,6 @@ "EveryoneCanKnowMini": "Everyone can see the Mini", "CanBeEvil": "Mini can be an Impostor", "EvilMiniSpawnChances": "Probability of Mini being an Impostor", - "EvilMiniCanBeGuessed": "Evil Mini can be guessed before 18", "GuessMini": "Sorry, you can't hurt a kid Mini.", "GrowUpDuration": "Time required to grow (s)", "MajorCooldown": "Kill Cooldown when over 18", @@ -3520,7 +3448,6 @@ "WinnerRoleText.Doppelganger": "Doppelganger Wins!", "WinnerRoleText.Quizmaster": "Quizmaster Wins!", "WinnerRoleText.Agitater": "Agitator Wins!", - "WinnerRoleText.Shocker": "Shocker Wins!", "AdditionalWinnerRoleText.Sidekick": "Sidekick", "AdditionalWinnerRoleText.Taskinator": "Taskinator", "AdditionalWinnerRoleText.Opportunist": "Opportunist", @@ -3606,7 +3533,7 @@ "SolsticerOnMeeting": "You witnessed too many deaths! Next round you will have {0} more short task!", "SolsticerTitle": "Solsticer", "GuessSolsticer": "Sorry, but you can not guess Solsticer!", - "ExpelSolsticer": "Sorry, but you can not expel Solsticer!", + "VoteSolsticer": "Sorry, but you can not vote Solsticer!", "SolsticerTasksReset": "Your tasks get reset!", "SolsticerMisGuessed": "You just misguessed! You are no longer allowed to guess.", "SolsticerGuessMax": "Because you already misguessed, you are no longer allowed to guess.", @@ -3707,28 +3634,6 @@ "MinionAbilityTime": "Ability Duration", "Minion_Blind": "blinded", "Evader_ChanceNotExiled": "Chance not be exiled", - "ShockerAbilityCooldown": "Ability Cooldown", - "ShockerAbilityDuration": "Ability Duration", - "ShockerAbilityPerRound": "Abilities Per Round", - "ShockerShockInVents": "Shock people in vents", - "ShockerAbilityResetAfterMeeting": "Reset marked rooms after meeting", - "ShockerOutsideRadius": "Radius Of Outside Tasks (not in a room)", - "ShockerCanShockHimself": "Can Shock Himself", - "ShockerImpostorVision": "Shocker has Impostor vision", - "ShockerIsShocking": "You're already shocking!", - "ShockerAbilityActivate": "Begin Shocking!", - "ShockerAbilityDeactivate": "Ability Deactivated", - "ShockerVentButtonText": "Shock", - "ShockerRoomMarked": "Marked Room", "EavesdropperMsgTitle": "You found a secret", - "EavesdropPercentChance": "Chance to eavesdrop", - "ChiefOfPoliceSkillCooldown": "Cooldown for recruiting sheriffs", - "PolicCanImpostorAndNeutarl": "Can recruit Impostor or Neutral", - "SheriffSuccessfullyRecruited": "You recruited a sheriff.", - "BeSheriffByPolice": "You've been recruited by the police chief! Serve the crew!", - "PoliceFailedRecruit": "Failed to recruit target.", - "ChiefOfPoliceKillButtonText": "Recruitment", - "PolicPreventRecruitNonKiller": "Prevent recruit players without kill button", - "PolicSuidiceWhenTargetNotKiller": "Suidices when recruit a non killer or non crewmate", - "PolicPassConverted": "Can pass Converted Addon to Sheriff" -} \ No newline at end of file + "EavesdropPercentChance": "Chance to eavesdrop" +} diff --git a/Resources/Lang/fr_FR.json b/Resources/Lang/fr_FR.json index 0a32e428b..feeaedc05 100644 --- a/Resources/Lang/fr_FR.json +++ b/Resources/Lang/fr_FR.json @@ -19,8 +19,6 @@ "SubText.Neutral": "Travaille seul pour remporter la Victoire", "SubText.Apocalypse": "Devenez imparable avec votre équipe", "SubText.Madmate": "Aide les Imposteurs", - "SubText.Lovers": "Stay alive and win together", - "SubText.Egoist": "Win on your own", "TypeImpostor": "Imposteurs", "TypeCrewmate": "Coéquipiers", "TypeNeutral": "Neutres", @@ -30,9 +28,6 @@ "TeamNeutral": "Neutre", "TeamCrewmate": "Coéquipier", "TeamMadmate": "Complice", - "TeamLovers": "Lovers", - "TeamEgoist": "Egoist", - "TeamApocalypse": "Apocalypse", "YouAreCrewmate": "Tu es un Coéquipier", "YouAreImpostor": "Tu es un Imposteur", "YouAreNeutral": "Tu es un Neutre", @@ -224,7 +219,6 @@ "TaskManager": "Gestionnaire de Tâches", "Witness": "Témoin", "Swapper": "Échangeur", - "ChiefOfPolice": "Chief of Police", "NiceMini": "Bon Gamin", "Mini": "Gamin", "Spy": "Espion", @@ -253,7 +247,6 @@ "Stalker": "Harceleur", "Workaholic": "Aliéné", "Solsticer": "Solsticien", - "Abyssbringer": "Abyssbringer", "Collector": "Collectionneur", "Provocateur": "Provocateur", "BloodKnight": "Chevalier de Sang", @@ -392,8 +385,6 @@ "Sloth": "Paresseux", "Prohibited": "Interdit", "Eavesdropper": "Eavesdropper", - "Shocker": "Shocker", - "Revenant": "Revenant", "BracketAddons": "Ajouter des parenthèses aux Modifieurs", "EngineerTOHEInfo": "Utilise les Évacuations pour démasquer les Imposteurs", "ScientistTOHEInfo": "Accède aux Signes Vitaux de n'importe où", @@ -512,7 +503,6 @@ "PacifistInfo": "Évacue pour réinitialiser les Rechargements d'Exécution", "RebirthInfo": "Surgir de Nouveau", "MonarchInfo": "Donne à ton Équipe des Votes supplémentaire !", - "AbyssbringerInfo": "Create Black Holes", "SpurtInfo": "Spring Like A rabbit!", "StealthInfo": "Obscurci la Vision de tout le monde dans la pièce en Exécutant", "PenguinInfo": "Fais Glisser tes victimes", @@ -546,7 +536,6 @@ "WitnessInfo": "Découvre si quelqu'un a Exécuté récemment", "GhastlyInfo": "Contrôlez quelqu'un!", "SwapperInfo": "Échange les Votes de deux joueurs", - "ChiefOfPoliceInfo": "Hire Sheriff to Serve the Crews!", "NiceMiniInfo": "Personne ne peut te faire de mal tant que tu n'as pas grandi.", "ArsonistInfo": "Asperge tout le monde et Incendie !", "PyromaniacInfo": "Asperge et Exécute tout le monde", @@ -707,8 +696,6 @@ "SlothInfo": "Vous êtes plus lent", "ProhibitedInfo": "Certains conduits d'aération sont bloqués", "EavesdropperInfo": "Listen in on other roles", - "ShockerInfo": "Shock unsuspecting players", - "RevenantInfo": "Take your killer's role", "EngineerTOHEInfoLong": "(Coéquipiers):\nL'Ingénieur peut accéder aux Évacuations tant qu'il n'y a pas de Sabotage des Communications.", "ScientistTOHEInfoLong": "(Coéquipiers):\nEn tant que Scientifique, vous pouvez voir les Signes Vitaux, à n'importe quel moment, vous montrant qui est en vie et qui est décédé.", "NoisemakerTOHEInfoLong": "(Crewmates):\nAs the Noisemaker, whenever you die, you will make a noise, and a visual indicator of your death appears on the screen so the Crewmates can run to catch the person who killed you red-handed (even if it’s not Red).", @@ -780,11 +767,11 @@ "LurkerInfoLong": "(Imposteurs):\nLe Fureteur peut Sauter dans une Évacuation pour réduire son Rechargement d'un certain nombre de secondes. Après avoir Exécuté, son Rechargement est réinitialisé à sa valeur d'origine.", "VisionaryInfoLong": "(Imposteurs):\nLe Visionnaire voit les Alignements des joueurs Vivants lors d'une Réunion.\nLes Informations suivantes seront Affichées sur le joueur :\n- Le Nom Rouge indique les Imposteurs.\n- Le Nom Cyan indique les Coéquipiers.\n- Le Nom Gris indique les Neutres.", "PlagueDoctorInfoLong": "(Neutres):\n(Plague Doctor de TOH)\nLe Médecin de Peste doit d'Infecter tous les joueurs en Vie.\nIl commence par choisir un joueur à Infecter, après quoi n'importe qui passant un temps défini à poximité du joueur Infecté sera Infecter à son tour.\nLa progression de l'Infection est cumulative et ne se réinitialise pas avec la distance ou après une Réunion.", - "RefugeeInfoLong": "(Madmates):\nAs the Refugee, you were either:\n -An Amnesiac who remembered an Impostor\n -A killer who killed the Godfather's target.\n -A Romantic whose partner was an Impostor\n -Or an Imitator that imitated an Impostor.\n\nNow your job is to help the Impostors kill the crewmates.", + "RefugeeInfoLong": "(Complices):\nLe Réfugié étais soit un Amnésique qui s'est Souvenu être Imposteur, soit l'Exécuteur d'une Cible du Parrain.\n\nMaintenant, son but est d'Aider les Imposteurs à Exécuter les Coéquipiers.", "UnderdogInfoLong": "(Imposteurs):\nLe Postulant ne peut pas Exécuter tant qu'il y a un certain nombre de joueurs en Vie.", "ConsigliereInfoLong": "(Imposteurs):\nL'Éminence Grise peut Révéler le Rôle des autres joueurs en utilisant son Bouton d'Exécution.\n\nUn seul clic : Révéler le Rôle.\nDouble clic : Exécuter.\n\nS'il n'a plus d'utilisation pour Révéler, son Bouton d'Exécution fonctionne normalement.", "LudopathInfoLong": "(Imposteurs):\nLe Ludopathe a un Rechargement d'Exécution Aléatoire.\n\nLe minimum est de 1 seconde, tandis que le maximum est le Rechargement par défaut d'Exécution.", - "GodfatherInfoLong": "(Impostors):\nAs the Godfather, you vote someone to make them your target.\nIn the next round, if someone kills the target, the killer will turn into a Refugee or Madmate.", + "GodfatherInfoLong": "(Imposteurs):\nLe Parrain Vote quelqu'un pour en faire sa Cible.\nÀ prochaine Manche, si quelqu'un Exécute sa Cible, l'Exécuteur se transformera en Réfugié.", "ChronomancerInfoLong": "En tant que Chronomancien, vous avez une barre de recharge qui indique lorsque l'exécution est prête. Lorsqu'elle est à 100% la prochaine fois que vous exécutez quelqu'un, vous irez en mode meurtrier, cela veut dire que vous pouvez tuer constamment jusqu'à ce que votre barre de recharge se vide. Sinon, vous aurez un temps mort d'exécution normal.", "PitfallInfoLong": "(Imposteurs):\nLe Piégeur utilise sa Métamorphose pour Marquer la zone autour de la Métamorphose comme un Piège. Les joueurs qui entrent dans cette zone seront Immobilisés pendant une courte période et leur Vision sera affectée.", "EvilMiniInfoLong": "(Imposteurs):\nLe Mauvais Gamin est inexécutable jusqu'à ce qu'il Grandisse et il a un Rechargement d'Exécution très long, qui sera considérablement réduit quand il Grandira.", @@ -856,7 +843,6 @@ "TaskManagerInfoLong": "(Coéquipiers):\nLe Gestionnaire de Tâches voit le nombre total de Tâches Accomplies (par tout le monde) à côté du nom de son Rôle, qui est Actualisé en temps réel.", "WitnessInfoLong": "(Coéquipiers):\nLe Témoin en utilisant son Bouton d'Exécution sur quelqu'un, saura s'il a Exécuté dans les X dernières secondes ou non. (X dépend des Réglages).", "SwapperInfoLong": "(Crewmates):\nAs the Swapper, you can swap votes in meetings.\n\nTo swap votes, use '/sw [playerID]' twice.\n\nPlayer IDs are displayed next to player names in meetings, but you can also use /id to get a list of all player IDs.\n\nNote: Depending on the Host's settings, you can exchange your own votes.", - "ChiefOfPoliceInfoLong": "(Crewmates):\nPlayers with swords can be recruited to join the sheriff's team to serve the crew\nNote: only one recruitment opportunity\nDepending on settings, you may recruit non killers or non crews.\nYou may suidice for recruiting wrong target.", "NiceMiniInfoLong": "(Crewmates):\nAs a Nice Mini, your survival is crucial. You can't be killed until you grow up, and if you die or are evicted from the meeting before you grow up, everyone loses. This unique role adds a new dynamic to the game, where your survival is not just for your benefit but for the entire Crew's success.", "SpyInfoLong": "(Crewmates):\nAs the Spy, when someone uses their kill button on you (any ability used through the kill button), you'll see their name in orange for a few seconds.\nNote: If a Crewmate used their ability on you, you'll also see them with an orange name!\nNote: If you cannot use left, you won't see orange names!\nNote: If the kill button interaction is blocked, the player's cooldown will reset to 10s'", "RandomizerInfoLong": "(Crewmates):\nAs this Randomizer, when you die, your killer will do one of the following:\n 1. self-report your body\n 2. stand next to your body\n 3. have their kill cooldown set to 600s\n 4. Randomly avenge a player.", @@ -871,7 +857,7 @@ "LawyerInfoLong": "(Neutres):\nL'Avocat a une Cible à Défendre, qui sera indiquée par un Diamant 「♦」 à côté de son Nom.\nSi sa Cible Gagne, Il Gagne.\nSi elle Perd, il Perd.", "OpportunistInfoLong": "(Neutres):\nL'Opportuniste a pour but de Survivre jusqu'à la fin de la Partie. Il Gagne avec l'Équipe gagnante.", "VectorInfoLong": "(Neutres):\nLe Chauffagiste Gagnera seul en Évacuant un certain nombre de fois.", - "JackalInfoLong": "(Neutrals):\nAs the Jackal, you win if you are the last player alive. Additionally, you may recruit using the kill button. If the target is not one you can recruit, you have run out of uses, or you don't have the option to recruit, then you will kill people normally (i.e., don't use kill buttons in front of others thinking it'll recruit). If the target has a kill button and the option to turn into a Sidekick is on, they will become a Sidekick. Otherwise, they will gain the Recruit add-on if the option to give the Recruit add-on is on.\nDepending on the settings, when Jackal was killed, a Sidekick will be randomly selected as the new Jackal.\nRecruit may be selected if no sidekick is alive.", + "JackalInfoLong": "(Neutrals):\nAs the Jackal, you win if you are the last player alive. Additionally, you may recruit using the kill button. If the target is not one you can recruit, you have run out of uses, or you don't have the option to recruit, then you will kill people normally (i.e., don't use kill buttons in front of others thinking it'll recruit). If the target has a kill button and the option to turn into a Sidekick is on, they will become a Sidekick. Otherwise, they will gain the Recruit add-on if the option to give the Recruit add-on is on.", "GodInfoLong": "(Neutrals):\nAs the God, you know everyone's role from the beginning. If you live until the end of the game, you steal the win, i.e., everyone else loses, and you win.", "InnocentInfoLong": "(Neutrals):\nThe Innocent can use the kill button to plant any player, and the planted target will immediately kill the Innocent. If the target gets voted out in the meeting, the Innocent wins. Note: Jester, Executioner, and Innocent can win together.", "PelicanInfoLong": "(Neutrals):\nAs the Pelican, you can use the kill button to swallow a player alive, teleporting them off-bounds but not killing them yet. Those swallowed will only die if you're still alive at the end of the round. If you die or leave during the round, all alive swallowed players will spawn into the map where you were.", @@ -883,7 +869,7 @@ "SolsticerInfoLong": "(Neutrals):\nAs the Solsticer, you won't die, and you win by finishing all your tasks in a single round. After every meeting finishes, your tasks reset, and you need to start all over again.\nVotes on the Solsticer will be directly canceled.\nKill attempts on the Solsticer will teleport it out of the map like Pelican until the meeting is finished.\nThe killer's kill cooldown will be reset to 10 seconds.\nSolsticer is counted as nothing in-game.", "CollectorInfoLong": "(Neutrals):\nAs the Collector, when you vote for a player, for each other player that voted for them, you gain a point. When you collect the required votes, the game ends, and you win alone, even if you voted a Jester or Executioner's target out.", "GlitchInfoLong": "(Neutrals):\nAs the Glitch, you can hack players (single click) or kill normally (double click).\nThose who have been hacked cannot kill, vent, or report for the hack duration.\nAdditionally, calling a sabotage other than doors will have no effect and will instead disguise you as a random player. You cannot disguise during or after sabotages.\nTo win, be the last player alive.", - "SidekickInfoLong": "(Neutrals):\nAs the Sidekick, your job is to help the Jackal kill everyone.\nYou and the Jackal win together.\nDepending on the settings, you may turn into Jackal if old Jackal was killed.\nYou may not be able to kill until old Jackal is dead.", + "SidekickInfoLong": "(Neutres):\nL'Acolyte doit aider le Chacal à Exécuter tout le monde.\n\nLui et le Chacal Gagnent ensemble.", "ProvocateurInfoLong": "(Neutres) :\nLe Provocateur peut Exécuter n'importe quelle Cible avec le Bouton d'Exécution. Si la Cible perd à la fin de la Partie, le Provocateur Gagne avec l'Équipe gagnante.", "BloodKnightInfoLong": "(Neutrals):\nThe Blood Knight wins when they're the last killing role alive, and the amount of crewmates is lower or equal to the amount of Blood Knights. The Blood Knight gains a temporary shield after every kill, making them immortal for a few seconds.", "PlagueBearerInfoLong": "(Apocalypse):\nAs the Plaguebearer, plague everyone using your kill button to turn into Pestilence.\nOnce you turn into Pestilence, you will become immortal and gain the ability to kill, and you will kill anyone who tries to kill you.\n\nAlso, when infected players interact with uninfected players, they will also be infected.", @@ -910,12 +896,11 @@ "TraitorInfoLong": "(Neutrals):\nAs the Traitor, you were an Impostor that betrayed the Impostors.\nYou know the Impostors, but they don't know you.\nThe twist? They can kill you, but you can't kill them.\n\nEliminate the Impostors by other means, then kill everyone else to win!", "TrollerInfoLong": "(Neutrals):\nAs a Troller, you can complete tasks so that random events can happen to players.\nFor example, changing the speed of all players, teleportation, influencing sabotage, etc.\nAlso you can win with the winning team.", "VultureInfoLong": "(Neutres):\nLe Vautour Dévore les Cadavres pour Gagner !\n\nLorsqu'il Signale un Cadavre, si son Rechargement pour Dévorer est écoulé, il Dévore le Cadavre (ce qui le rend non Signalable).\nSi sa Capacité à Dévorer est toujours en Rechargement, il Signale le Cadavre normalement.\nDe plus, il Signale les Cavares normalement si le nombre maximal de Cadavres Dévorés par Manche est atteint.", - "AbyssbringerInfoLong": "(Impostors):\nAs the Abyssbringer, you can place black holes. Black holes will suck in players and kill them when colliding with them.", "TaskinatorInfoLong": "(Neutrals):\nAs the Taskinator, whenever you finish a task, the task will be bombed. When another player completes the bombed task, the bomb will detonate, and the player will die.\n\nYou win if you survive till the end and Crew doesn't win.\n\n Note: Taskinator bombs ignore all protection.", "BenefactorInfoLong": "(Crewmates):\nAs the Benefactor, whenever you finish a task, that task will be marked. When another player completes the marked task, they get a temporary shield.\n\n Note: Shield only protects from direct kill attacks.", "MedusaInfoLong": "(Neutres) :\nLa Méduse peut Pétrifier les Corps de la comme on Nettoie un Cadavre. Les Corps Pétrifiés ne peuvent pas être Signalés.\n\nElle doit Exécuter tout le monde pour Gagner.", "SpiritcallerInfoLong": "(Neutrals):\nAs the Spiritcaller, your victims become Evil Spirits after they die. These spirits can help you win by freezing other players briefly or blocking their vision. Alternatively, the spirits can give you a shield that protects you briefly from an attempted kill.", - "AmnesiacInfoLong": "(Neutrals):\nAs the Amnesiac, use your report button to remember a target and get its role.\nTo balance the game, you will not be able to vent after remembering your role if you can't vent as Amnesiac.'", + "AmnesiacInfoLong": "(Neutres):\nL'Amnésique utilise son Bouton de Signalement pour se Souvenir d'un Rôle.\n\nSi la Cible était un Imposteur, il devient un Réfugié.\nSi la Cible était un Coéquipié, il devient le Rôle de la Cible s'il est compatible (sinon vous deviendrez un Ingénieur).\nSi la Cible était un Neutre Passif ou un Neutre Exécuteur non spécifié, il devient le Rôle défini dans les Réglages.\nSi la Cible était un Neutre Exécuteur, il devient le Rôle qu'il été.", "ImitatorInfoLong": "(Neutrals):\nAs the Imitator, use your kill button to imitate a player.\n\nYou'll either become a Sheriff, a Refugee, or some Neutral.", "BanditInfoLong": "(Neutrals):\nAs the Bandit, you can click your kill button one time to steal a player's addon and twice to kill. Depending on the settings, you may instantly steal the addon or after the meeting starts. After the maximum number of steals is reached, you will kill normally. Additionally, if there are no stealable addons on the target or the target is stubborn, you will kill the target.\n\nKill everyone to win.\n\nNote: Cleansed, Last Impostor, and Lovers cannot be stolen.\nNote: If Bandit can vent is on, Nimble will become unstealable.", "DoppelgangerInfoLong": "(Neutrals):\nAs the Doppelganger, use your kill button to steal a player's identity (their name and skin) and then kill your target.\n\nKill everyone to win.\n\nNote: You cannot steal the target's identity when Camouflage is active.", @@ -936,7 +921,6 @@ "JinxInfoLong": "(Neutrals):\nAs the Jinx, whenever you get attacked, you jinx them, resulting in them dying to a jinx.\nThis has limited uses.\n\nKill off everyone to win.", "PotionMasterInfoLong": "(Neutrals):\nAs the Potion Master, you have three different potions assigned to three different actions.\n\nSingle click: Reveal role\nDouble click: Kill\nMap: Sabotage\n\nThe reveal potion has a limit.\nWhen you run out, the kill buttons default to killing.", "NecromancerInfoLong": "(Neutrals):\nAs the Necromancer, you win when you're the last one standing.\nAdditionally when someone tries to kill you, you will block the kill, and you will teleport to a random vent. You will have a limited time to kill your killer. If you succeed in doing so, you live. If the time runs out before you kill your killer, you die permanently. If you try to kill someone else other than your killer, you will die.", - "ShockerInfoLong": "(Neutrals):\nAs the Shocker, you can mark rooms by doing tasks in them, and then vent to Electrocute anyone in those rooms for a set period of time. When you finish all of your tasks, you get new ones. Note: Doing tasks during that period will mark them for the next ability use.", "LastImpostorInfoLong": "(Add-ons):\nThis special effect is given to the last surviving Impostor. It significantly reduces their kill cooldown.", "OverclockedInfoLong": "(Add-ons):\nAs the Overclocked, your kill cooldown is reduced by a percentage.\n\nThis feature is only assigned to roles with a kill button.", "LoversInfoLong": "(Add-ons):\nLovers are a combination of two players. The Lovers win when they are the last ones standing, and their victory is shared. When one of the Lovers wins, the other also wins together. Lovers can see the 「♥」 next to each other's name. If one of the Lovers dies, the other will die in love (may not die in love according to the Host's settings). When one of the Lovers is exiled in the meeting, the other will die and become a dead body that cannot be reported.", @@ -980,7 +964,7 @@ "RebirthInfoLong": "(Add-ons):\nAs the Rebirth, if you're the player about to be ejected, you will swap skins with a random crewmate who voted for you.\nNotice: The host vote never counts\nRebirth will be removed from you if you exhausted all your rebirths.", "LoyalInfoLong": "(Modifieurs):\nLe Loyal ne peut pas être Recruté par des Rôles tels que le Chacal ou le Gourou.\n\nIl ne peut pas être assigné aux Neutres.", "EvilSpiritInfoLong": "(Add-ons):\nAs Evil Spirit, it's your job to help the Spiritcaller to victory. You can use your Haunt button to freeze players and reduce their vision. Alternatively, you can use your Haunt button to give the Spiritcaller a shield against a kill attempt temporarily.", - "RecruitInfoLong": "(Betrayal Add-ons):\nAs a recruit, you are on the Jackal's team and help out the Jackal and their Sidekicks.\nYou cannot win with your original team.\nDepending on the settings, you may turn into Jackal if old Jackal was killed and no sidekicks is alive.", + "RecruitInfoLong": "(Modifieurs de Trahison):\nLa Recrue fait partie de l'Équipe du Chacal et il aide le Chacal et ses Acolytes.\nIl ne peut pas gagner avec son Équipe d'Origine.", "AdmiredInfoLong": "(Modifieurs de Trahison):\nL'Admiré Gagne avec l'Équipage et non avec son Équipe d'origine.\n\nIl peut voir l'Admirateur.", "GlowInfoLong": "(Modifieurs):\nLe Luisant et les joueurs proches auront leur Vision Augmentée pendant les Sabotages des Lumières.", "RadarInfoLong": "(Modifieurs):\\nEn tant que Sondeur, vous avez une flèche pointant vers la personne la plus proche tout le temps.", @@ -1024,7 +1008,6 @@ "ProhibitedInfoLong": "(Add-ons):\nAs the Prohibited, you have specific vents that you can't use.\nHow many vents are disabled depends on the Host's settings.", "EavesdropperInfoLong": "(Add-ons):\nAs the Eavesdropper, you have a chance to read other role/addon information-based messages like Mortician or Sleuth.", "ApocalypseInfoLong": "(Apocalypse):\nApocalypse members are on a separate team that works together and wins together. If there are multiple Apocalypse roles in the game, they can see each other's roles.\nDepending on the Host's settings, Apocalypse roles can guess or be guessed.", - "RevenantInfoLong": "(Neutral):\nAs the Revenant, your goal is to be killed. If you are killed, you will take your killer's role and kill your killer instead. You cannot win before being killed.\nNote that Revenant only works when being directly killed.", "ShowTextOverlay": "Texte de la Surcouche", "Overlay.GuesserMode": "Mode Devin", "Overlay.NoGameEnd": "Pas de fin de Partie", @@ -1038,8 +1021,6 @@ "AbilityUseLimit": "Limite d'utilisation initiale de la Capacité", "AbilityInUse": "Ability in use", "AbilityExpired": "Ability expired, {0} uses remain", - "RevenantTargeted": "Your role has changed to {0}", - "RevenantCanCopyAddons": "Can Steal Addons", "ShowArrows": "A des Flèches pointant vers les Cadavres", "ArrowDelayMin": "Délai minimal d'Apparition des Flèches", "ArrowDelayMax": "Délai maximal d'Apparition des Flèches", @@ -1368,8 +1349,6 @@ "ShieldedCanUseKillButton": "Shielded player can use ability / kill button", "PlayerIsShieldedByGame": "Player is protected by the game!", "LegacyNemesis": "Utiliser l'Ancienne Version", - "LegacyParasite": "Use Legacy Version", - "LegacyTraitor": "Use Legacy Version", "ArsonistKeepsGameGoing": "L'Incendiaire fait continuer la Partie", "ArsonistCanIgniteAnytime": "Peut Incendier à tout moment", "ArsonistMinPlayersToIgnite": "Nombre minimal d'Aspergés nécessaires pour Incendier", @@ -1512,18 +1491,6 @@ "SheriffCanKillSeparately": "Réglages Individuels", "In%team%": "(Équipe %team%)", "SheriffMisfireKillsTarget": "Un Tir-Raté Exécute la Cible", - "BlackHolePlaceCooldown": "Black Hole Place Cooldown", - "BlackHoleDespawnMode": "Black Hole Despawn Mode", - "BlackHoleDespawnTime": "Time After Black Hole Despawns", - "Abyssbringer.Suffix": "<#00ffa5>Number of players consumed by {0} <#00ffa5>active black holes:\\n{1}", - "Abyssbringer.Suffix.BlackHole": "<#00ffa5>{0}: {1}", - "BlackHoleMovesTowardsNearestPlayer": "Black Hole Moves Towards Nearest Player", - "BlackHoleMoveSpeed": "Black Hole Moving Speed", - "BlackHoleRadius": "Black Hole Consuming Radius", - "AfterTime": "After Time", - "After1PlayerEaten": "After 1 Player Was Eaten", - "AfterMeeting": "After Meeting", - "None": "None", "SheriffShotLimit": "Nombre maximal d'Exécutions", "SheriffCanKillAllAlive": "Peut Exécuter quand personne n'est Mort", "SheriffCanKillCharmed": "Peut Exécuter les joueurs Charmés", @@ -1540,15 +1507,12 @@ "RebirthUses": "Amount of Rebirths", "RebirthCountVotes": "Only rebirth to players who voted for them", "RebirthFailed": "Ahh, how unfortunate, you did not find any viable souls to swap bodies with", - "FireworkerCooldown": "Placement Cooldown", "ReverieIncreaseKillCooldown": "Augmenter le Rechargement d'Exécution", "ReverieMaxKillCooldown": "Rechargement d'Exécution maximal", "ReverieMisfireSuicide": "Tir-Raté en atteignant le Rechargement maximal d'Exécution", "ReverieResetCooldownMeeting": "Réinitialiser le Rechargement d'Exécution après la Réunion", "ConvertedReverieKillAll": "Le Rêveur Recruté peut Exécuter n'importe qui sans répercutions", "VigilanteNotify": "Tu es devenu la chose même que tu as juré de détruire", - "DictatorChangeCommandToExpel": "Dictator use Command to expell instad of vote", - "DictatorExpelSelf": "WAIT WAIT WAIT WAT THE HELLLLLL Bro really just want to expel himself", "DoctorTaskCompletedBatteryCharge": "Durée de la Batterie", "SnitchEnableTargetArrow": "Voir la Flèche vers la Cible", "SnitchCanGetArrowColor": "Voir les Flèches Colorées en fonction des Couleurs de l'Équipe", @@ -1629,7 +1593,6 @@ "EvilTrackerTargetMode.OnceInGame": "Une fois par partie", "EvilTrackerTargetMode.EveryMeeting": "À chaque Réunion", "EvilTrackerTargetMode.Always": "À tout moment", - "ScavengerHasCustomDeathReason": "Enable Custom Death Reason", "EvilHackerCanSeeDeadMark": "Peut voir la localisation des cadavres", "EvilHackerCanSeeImpostorMark": "Peut localiser les autres imposteurs", "EvilHackerCanSeeKillFlash": "Peut voir l'Alerte d'Exécution", @@ -1862,21 +1825,13 @@ "Jackal_SidekickCountMode_Jackal": "Chacal", "Jackal_SidekickCountMode_Original": "Équipe d'Origine", "Jackal_SidekickAssignMode": "Mode d'Assignation des Acolytes", - "Jackal_SidekickAssignMode_SidekickAndRecruit": "Sidekick when failed Recruit", - "Jackal_SidekickAssignMode_Sidekick": "Only Sidekick", - "Jackal_SidekickAssignMode_Recruit": "Only Recruit", + "Jackal_SidekickAssignMode_SidekickAndRecruit": "Acolytes+Recrue", + "Jackal_SidekickAssignMode_Sidekick": "Acolyte Uniquement", + "Jackal_SidekickAssignMode_Recruit": "Recrue Uniquement", + "JackalWinWithSidekick": "Le Chacal peut gagner avec l'équipe de l'Acolyte", "Jackal_SidekickCanKillSidekick": "Les Acolytes peuvent Exécuter d'autres Acolytes", "Jackal_SidekickCanKillJackal": "Les Acolytes peuvent Exécuter le Chacal", - "Jackal_RecruitFailed": "You can not recruit this player!", "JackalCanKillSidekick": "Le Chacal peut Exécuter les Acolytes", - "Jackal_SidekickCanKillWhenJackalAlive": "Sidekick can kill while Jackal is Alive", - "Jackal_SidekickTurnIntoJackal": "Sidekick can turn into Jackal after its death", - "Jackal_RestoreLimitOnNewJackal": "Restore Recruit limit when Sidekick become new Jackal", - "Jackal_OnBecomeNewJackalMeeting": "The old Jackal {0} is dead.\nYou are selected as new Jackal\nWork together and win the game!", - "Jackal_OnNewJackalSelectedMeeting": "The old Jackal {0} is dead.\n{1} is selected as new Jackal!\nWork together and win the game!", - "Jackal_BecomeNewJackal": "Old Jackal Dead, You are now new Jackal!", - "Jackal_OnNewJackalSelected": "Old Jackal Dead, Please help new Jackal {0} for now!", - "Jackal_BossIsDead": "Opps, the Jackal boss is dead!", "CoronerArrowsPointingToDeadBody": "Flèches pointant vers des Cadavres", "CoronerLeaveDeadBodyUnreportable": "Les Cadavres que le Légiste utilise ne peuvent pas être Signalés", "CoronerInformKillerBeingTracked": "Informer l'Exécuteur qu'il est Suivi", @@ -1914,9 +1869,6 @@ "VipTag": "VIP★", "ApplyVipList": "Appliquer la Liste VIP", "AllowSayCommand": "Autoriser les Modérateurs à utiliser la commande /say", - "AllowStartCommand": "Allow moderators to use /start command", - "StartCommandMinCountdown": "Minimum countdown for /start command", - "StartCommandMaxCountdown": "Maximum countdown for /start command", "KickCommandDisabled": "La commande d'Exclusion est actuellement désactivée.", "KickCommandNoAccess": "Tu n'as pas accès à la commande d'Exclusion.", "KickCommandInvalidID": "L'ID du joueur spécifié n'est pas valide.\nS'il te plaît utilise '/kick [ID du Joueur] [raison]' pour Exclure un joueur.\nExemple :- /kick 5 ne respecte pas les règles", @@ -1949,11 +1901,6 @@ "WarnCommandNoAccess": "Tu n'as pas accès à la commande warn.", "WarnCommandInvalidID": "ID du joueur sélectionné Invalide.\nS'il te plaît utilise '/warn [ID du joueur] [Raison]' pour avertir un joueur.\nExemple :- /warn 5 parle pendant l'éjection", "WarnCommandWarnHost": "Tu n'es pas autorisé à avertir l'Hôte.", - "StartCommandNoAccess": "You do not have access to the start command.", - "StartCommandDisabled": "The start command is currently disabled.", - "StartCommandCountdown": "ERROR\n\nThe game is already starting!", - "StartCommandStarted": "The game has been started by {0}!", - "StartCommandInvalidCountdown": "ERROR\n\nThe countdown must be between {0} and {1}!", "WarnCommandWarnMod": "Tu n'es pas autorisé à avertir les autres Modérateurs.", "WarnCommandWarned": "a été averti. Il n'y aura pas d'autres avertissements et des mesures appropriées seront prises \n ", "WarnExample": "Utilise /warn [ID du Joueur] [Raison] à l'avenir.\nExemple :\n/warn 5 parle pendant l'Éjection", @@ -1981,7 +1928,6 @@ "DeathReason.Quantization": "Quantification", "DeathReason.Overtired": "A bout de Nerfs", "DeathReason.Ashamed": "Honteux", - "DeathReason.Consumed": "Consumed", "DeathReason.PissedOff": "Détruit", "DeathReason.Dismembered": "Démembré", "DeathReason.LossOfHead": "Étranglé", @@ -2005,8 +1951,6 @@ "DeathReason.Starved": "Starved", "DeathReason.Equilibrium": "Equilibrium", "DeathReason.Sacrificed": "Sacrificed", - "DeathReason.Electrocuted": "Electrocuted", - "DeathReason.Scavenged": "Scavenged", "OnlyEnabledDeathReasons": "Active uniquement les Raisons de la Mort", "Alive": "Vivant", "Disconnected": "Disconnected", @@ -2072,7 +2016,6 @@ "Command.dump": "→ Inscrit le Journal de Bord sur le Bureau", "Command.death": "→ Affiche l'information sur la façon dont tu es Mort", "Command.icons": "
╳ - The Player was marked by the Blackmailer and can't talk during the Meeting
☆ - Used by Captain to display themselves. Only Crewmates can see the Captain's star
乂 - This player was hexed by the Hex Master and will die if the Hex Master isn't killed or ejected by the end of the Meeting.
♦ - Used by Lawyer or Executioner or Follower.
♥ - Used by Lovers or Romantic.
✚ - Used by Medic to mark their target.
⦿ - This player is in a duel with the Pirate.
!? - This player was marked by the Quizmaster and must answer the question correctly to survive.
☜ - Used by Schrödinger's cat to mark their teammate.
◈ - This player marked by the Shroud and will die if the Shroud is not killed or ejected by the end of the meeting.
⚠ - This player is a Snitch or Solsticer who has finished their tasks.
★ - Used by Super Star or Cyber or Marshall.
† - This player was spelled and will die if the Witch is not killed by the end of the meeting.
∇ - Used by Kamikaze to mark their targets.
■ - Used by Lightning to mark their quantum ghosts.
⊠ - Used by Jailer to mark their prisoner.
● - Used by Baker to mark who has Bread.
♠ - Used by Soul Collector to mark who's death they're predicting.
⦿ - Used by Plaguebearer to mark who they have plagued.", - "Command.start": "[Seconds] → Start the game", "Command.iconinfo": "→ Affiche les informations sur les Icônes de Réunion", "Command.iconhelp": "→ Affiche les informations sur les Icônes de Réunion pour tout le monde", "Command.Poll": "→ Start a poll with up-to 5 choices", @@ -2085,7 +2028,6 @@ "ShowMadmatesInLeftCommand": "Show Madmates (including add-ons)", "ShowApocalypseInLeftCommand": "Show Neutral Apocalypse", "SeeEjectedRolesInMeeting": "Voir les Rôles Éjectés dans les Réunions", - "ThankYouForUsingTOHE": "Thank you for using TOHE!", "SkillUsedLeft": "Tu as activé ta Capacité pour convoquer une Réunion. \nNombre d'utilisations restantes :", "NemesisDeadMsg": "La mort de la Némésis signifie le début de la vengeance. \nS'il te plaît utilise /rv + [ID joueur] pour exécuter le joueur spécifié \nTu peux voir les ID joueurs devant leurs noms. \nOu tape /rv pour obtenir la liste des ID des joueurs", "NemesisAliveKill": "La vengeance de la Némésis ne peut commencer qu'après sa mort.", @@ -2105,7 +2047,6 @@ "GuessNotifiedBait": "Bait can't be guessed because it was announced. You thought it would be that easy, right?", "GuessGM": "Deviner le MJ est impossible car il est déjà Mort.... Et pourquoi faire ça au pauvre Hôte ?", "GuessGuardianTask": "Tu ne peux pas Deviner un Gardien qui a terminé ses Tâches.", - "GuardianCantKilled": "You can't kill a Guardian who has finished their tasks.", "GuessMarshallTask": "Tu ne peux pas Deviner un Maréchal qui a terminé ses Tâches.", "GuessObviousAddon": "Désolé, les Modifieurs évidents ne peuvent pas être Devinés.\nAprès tout, ce serait injuste pour celui que tu allais Deviner !", "GuessAdtRole": "Malheureusement, les Réglages de l'Hôte ne permettent pas de Deviner les Modifieurs.", @@ -2161,7 +2102,6 @@ "BecomeMadmateCuzMadmateMode": "Tu es devenu Complice parce que tu es Mort", "CleanerCleanBody": "Le Cadavre a été Nettoyé", "QuickShooterStoraging": "Les Balles ont bien été Emmagasinées", - "QuickShooterFailed": "You are still in cooldown.", "PoisonerTargetDead": "La Cible est Morte", "HexesLookLikeSpells": "Ensorcèlements apparaissent comme Malédictions", "HexButtonText": "Ensorceler", @@ -2320,7 +2260,6 @@ "Message.YTPlanNotice": "Note: The [YouTuber Plan] is enabled in this lobby, which means the Host can specify their role in the next game to make it easier to get content. If the Host abuses this feature, please exit the game or report it.\nCurrent Creator Credentials:", "Message.OnlyCanBeUsedByHost": "ERREUR\n\nCette commande ne peut être utilisée que par l'Hôte.", "Message.MaxPlayers": "Le nombre maximal de Joueurs est fixé à ", - "Message.MaxPlayersFailByRegion": "Could not set max players: Vanilla regions support a maximum of 15 players.", "Message.GhostRoleInfo": "Ghost Role Info\nHiya! A little about ghost roles...\n\nGhost roles drastically impact the game, so it's not recommended for smaller lobbies if you're unfamiliar. If not explicitly stated otherwise in the description, the Guard button is their ability button ;)\n\nSpawning:\nGhost-roles only spawn after death; the first x people from (team) to die get them.\n\nPS: If your previous role didn't have tasks(e.g., sheriff), your tasks as a ghost-role aren't needed for task-win", "ApocalypseInfoTitle": "Neutral Apocalypse Info:", "Message.ApocalypseInfo": "Every role of the <#ff174f>Apocalypse Team has their own objective to carry out in order to transform.\n<#2B0804>Transformed <#ff174f>Apocalypse members have a drastic change on the game and are immortal (except for being voted), but everyone will be notified that they have transformed.\n\nRoles: <#e5f6b4>Plaguebearer, <#A675A1>Soul Collector, <#bf9f7a>Baker, <#cc0044>Berserker\nTransformed: <#343136>Pestilence, <#644661>Death, <#83461c>Famine, <#2B0804>War\n\nApocalypse members can see eachother's roles and ability icons.\nLike Neutral Killers, Apocalypse members keep the game going as well, have fun!", @@ -2725,9 +2664,8 @@ "DeathMeetingTimeIncrease": "Increased Meeting time when Death exists", "SoulCollectorMeetingDeath": "Your target has died during the meeting. You have gained a soul.", "SoulCollectorKillButtonText": "Predict", - "SoulCollectorHasImpostorVision": "Soul Collector has Impostor vision", "ApocalypseIsNigh": "[ The Apocalypse Is Nigh! ]", - "ApocalypseImmune": "This role is immune!", + "ApocalypseImmune": "This player is immune because they are invincible!", "BakerToFamine": "You have become Famine!!!", "BakerTransform": "The Baker has transformed into Famine, Horseman of the Apocalypse! A famine has begun!", "BakerAlreadyBreaded": "That player already has bread!", @@ -2736,15 +2674,13 @@ "BakerBreadNeededToTransform": "Required number of bread to become Famine", "BakerCantBreadApoc": "You cannot give other Apocalypse members bread!", "BakerKillButtonText": "Bread", - "BakerUnshiftButtonText": "Switch Bread", "BakerRevealBread": "Reveal", "BakerRoleblockBread": "Roleblock", "BakerBarrierBread": "Barrier", "BakerCurrentBread": "Current Bread: ", "BakerSwitchBread": "Bread Switched to: ", - "BakerCanVent": "Baker can Vent", + "BakerCanVent": "Baker can Vent", "BakerBreadGivesEffects": "Bread gives additional effects", - "BakerTransformNoMoreBread": "Baker transforms if they do not have enough bread", "FamineKillButtonText": "Starve", "FamineStarveCooldown": "Famine starve cooldown", "FamineCantStarveApoc": "You cannot starve other Apocalypse members!", @@ -2791,7 +2727,6 @@ "GodfatherTargetCountMode": "L'Exécuteur se transforme en", "GodfatherCount_Refugee": "Réfugié", "GodfatherCount_Madmate": "Complice", - "GodfatherRefugeeMsg": "You have been recruited by GodFather!", "MissChance": "Chance To Miss", "IncreaseByOneIfConvert": "Increase The KillCount +1 If a Crew Is Converted", "HawkMissed": "Raté !", @@ -2824,7 +2759,6 @@ "BerserkerToWar": "You have become War!!!", "BerserkerTransform": "The Berserker has transformed into War, Horseman of the Apocalypse! Cry 'Havoc!', and let slip the dogs of war.", "WarKillCooldown": "War kill cooldown", - "BerserkerCanKillTeamate": "Can kill other Neutral Apocalypse", "BlackmailerSkillCooldown": "Rechargement du Chantage", "BlackmailerMax": "Nombre maximal de fois où les joueurs soumis au Chantage peuvent Parler", "BlackmailerDead": "Attention ! {0} a été victime d'un Chantage de la part d'un Maître Chanteur !", @@ -2914,8 +2848,6 @@ "RememberedPursuer": "Tu t'es Souvenu que tu étais un Poursuivant !", "RememberedFollower": "Tu t'es Souvenu que tu étais un Adulateur !", "RememberedAmnesiac": "Tu n'as pas réussi à te Souvenir de ton Rôle.", - "AmnesiacRemembered": "You remembered you were {0}!", - "ReportWhenFailedRemember": "Report Dead Body when failed to remember", "RememberedImitator": "Tu t'es Souvenu que tu étais un Imitateur.", "RememberedImpostor": "Tu t'es Souvenu que tu étais un Imposteur !", "RememberedCrewmate": "Tu t'es Souvenu que tu étais un Coéquipier !", @@ -3329,12 +3261,9 @@ "PixieTargetAlreadySelected": "La Cible a déjà été choisie", "PixieButtonText": "Marquer", "PlagueBearerCooldown": "Rechargement d'Empestation", - "PlagueBearerCanVent": "Can vent", - "PlagueBearerHasImpostorVision": "Has Impostor vision", "PestilenceCooldown": "Rechargement d'Exécution de la Peste", "PestilenceCanVent": "La Peste peut Évacuer", "PestilenceHasImpostorVision": "La Peste a une Vision d'Imposteur", - "PestilenceKillGuessers": "Kill players who guess Pestilence", "PlagueBearerAlreadyPlagued": "Le joueur est déjà Empesté", "PlagueBearerToPestilence": "Tu t'es transformé en Épidémie !", "GuessPestilence": "Tu viens d'essayer de Deviner la Peste ! Désolé, la Peste t'a Exécuté.", @@ -3378,7 +3307,6 @@ "EveryoneCanKnowMini": "Tout le monde peut voir le Gamin", "CanBeEvil": "Le Gamin peut être Imposteur", "EvilMiniSpawnChances": "Probabilité que le Gamin soit Imposteur", - "EvilMiniCanBeGuessed": "Evil Mini can be guessed before 18", "GuessMini": "Ce n'est pas très sympa de ta part de vouloir buter un Gamin comme ça !", "GrowUpDuration": "Temps nécessaire pour Grandir (s)", "MajorCooldown": "Rechargement d'Exécution pour les plus de 18 ans", @@ -3520,7 +3448,6 @@ "WinnerRoleText.Doppelganger": "L'Alter Ego Gagne !", "WinnerRoleText.Quizmaster": "Quizmaster Wins!", "WinnerRoleText.Agitater": "Agitator Wins!", - "WinnerRoleText.Shocker": "Shocker Wins!", "AdditionalWinnerRoleText.Sidekick": "Acolyte", "AdditionalWinnerRoleText.Taskinator": "Tâcheron", "AdditionalWinnerRoleText.Opportunist": "Opportuniste", @@ -3606,7 +3533,7 @@ "SolsticerOnMeeting": "Tu as été témoin de trop de Morts ! Au prochain tour, tu auras {0} Tâches courtes supplémentaires !", "SolsticerTitle": "Solsticien", "GuessSolsticer": "Désolé, mais tu ne peux pas Deviner le Solsticen !", - "ExpelSolsticer": "Sorry, but you can not expel Solsticer!", + "VoteSolsticer": "Désolé, mais tu ne peux pas Voter le Solsticien !", "SolsticerTasksReset": "Tes Tâches ont été réinitialisées !", "SolsticerMisGuessed": "Tu viens juste de mal Deviner ! Tu n'as plus le droit de Deviner.", "SolsticerGuessMax": "Parce que tu as déjà mal Deviné, tu n’es plus autorisé à Deviner.", @@ -3707,28 +3634,6 @@ "MinionAbilityTime": "Durée de la Capacité", "Minion_Blind": "blinded", "Evader_ChanceNotExiled": "Chance not be exiled", - "ShockerAbilityCooldown": "Ability Cooldown", - "ShockerAbilityDuration": "Ability Duration", - "ShockerAbilityPerRound": "Abilities Per Round", - "ShockerShockInVents": "Shock people in vents", - "ShockerAbilityResetAfterMeeting": "Reset marked rooms after meeting", - "ShockerOutsideRadius": "Radius Of Outside Tasks (not in a room)", - "ShockerCanShockHimself": "Can Shock Himself", - "ShockerImpostorVision": "Shocker has Impostor vision", - "ShockerIsShocking": "You're already shocking!", - "ShockerAbilityActivate": "Begin Shocking!", - "ShockerAbilityDeactivate": "Ability Deactivated", - "ShockerVentButtonText": "Shock", - "ShockerRoomMarked": "Marked Room", "EavesdropperMsgTitle": "You found a secret", - "EavesdropPercentChance": "Chance to eavesdrop", - "ChiefOfPoliceSkillCooldown": "Cooldown for recruiting sheriffs", - "PolicCanImpostorAndNeutarl": "Can recruit Impostor or Neutral", - "SheriffSuccessfullyRecruited": "You recruited a sheriff.", - "BeSheriffByPolice": "You've been recruited by the police chief! Serve the crew!", - "PoliceFailedRecruit": "Failed to recruit target.", - "ChiefOfPoliceKillButtonText": "Recruitment", - "PolicPreventRecruitNonKiller": "Prevent recruit players without kill button", - "PolicSuidiceWhenTargetNotKiller": "Suidices when recruit a non killer or non crewmate", - "PolicPassConverted": "Can pass Converted Addon to Sheriff" -} \ No newline at end of file + "EavesdropPercentChance": "Chance to eavesdrop" +} diff --git a/Resources/Lang/it_IT.json b/Resources/Lang/it_IT.json index 5127a0ffd..fec5208f3 100644 --- a/Resources/Lang/it_IT.json +++ b/Resources/Lang/it_IT.json @@ -19,8 +19,6 @@ "SubText.Neutral": "Lavora da solo per ottenere la tua vittoria", "SubText.Apocalypse": "Diventa inarrestabile con la tua squadra", "SubText.Madmate": "Aiuta gli Impostori", - "SubText.Lovers": "Rimani in vita e vincete insieme", - "SubText.Egoist": "Vinci per conto tuo", "TypeImpostor": "Impostori", "TypeCrewmate": "Astronauti", "TypeNeutral": "Neutrali", @@ -30,9 +28,6 @@ "TeamNeutral": "Neutrale", "TeamCrewmate": "Astronauta", "TeamMadmate": "Follenauta", - "TeamLovers": "Amanti", - "TeamEgoist": "Egoista", - "TeamApocalypse": "Apocalisse", "YouAreCrewmate": "Sei un Astronauta", "YouAreImpostor": "Sei un Impostore", "YouAreNeutral": "Sei un Neutrale", @@ -224,7 +219,6 @@ "TaskManager": "Gestore degli Incarichi", "Witness": "Testimone", "Swapper": "Scambiatore", - "ChiefOfPolice": "Capo della Polizia", "NiceMini": "Mini Buono", "Mini": "Mini", "Spy": "Spia", @@ -253,7 +247,6 @@ "Stalker": "Stalker", "Workaholic": "Stacanovista", "Solsticer": "Impiegato", - "Abyssbringer": "Portatore di abissi", "Collector": "Collezionista", "Provocateur": "Provocatore", "BloodKnight": "Cavaliere del Sangue", @@ -267,7 +260,7 @@ "Berserker": "Berserker", "War": "Guerra", "Glitch": "Glitch", - "Sidekick": "Spalla", + "Sidekick": "Aiutante", "Follower": "Seguace", "Cultist": "Cultista", "SerialKiller": "Serial Killer", @@ -288,7 +281,7 @@ "Benefactor": "Benefattore", "Medusa": "Medusa", "Spiritcaller": "Evocatore", - "Amnesiac": "Amnesiaco", + "Amnesiac": "Amnesico", "Imitator": "Imitatore", "Bandit": "Bandito", "Doppelganger": "Doppelganger", @@ -392,8 +385,6 @@ "Sloth": "Bradipo", "Prohibited": "Proibito", "Eavesdropper": "Origliatore", - "Shocker": "Shocker", - "Revenant": "Revenant", "BracketAddons": "Aggiungi parentesi ai modificatori", "EngineerTOHEInfo": "Usa i condotti per beccare gli Impostori", "ScientistTOHEInfo": "Accedi ai segni vitali quando vuoi", @@ -410,12 +401,12 @@ "ShapeMasterInfo": "Uccidi velocemente senza ricarica mutazione", "VampireInfo": "Le tue uccisioni sono ritardate", "WarlockInfo": "Maledici gli astronauti poi mutati per farli uccidere", - "NinjaInfo": "Segna un bersaglio, poi mutati per ucciderlo", + "NinjaInfo": "Marca un bersaglio, poi mutati per ucciderlo", "ZombieInfo": "Sei molto lento", "AnonymousInfo": "Obbliga un giocatore a segnalare un corpo", "MinerInfo": "Vai all'ultimo condotto utilizzato mutandoti", "KillingMachineInfo": "Puoi SOLO uccidere, ma con ricarica bassa", - "EscapistInfo": "Mutati per Segnare i luoghi e teletrasportati ad essi", + "EscapistInfo": "Mutati per Marcare i luoghi e teletrasportati ad essi", "WitchInfo": "Incanta gli astronauti per ucciderli nelle riunioni", "NemesisInfo": "Uccidi quando sei l'ultimo impostore", "BeforeNemesisInfo": "Non puoi ancora uccidere", @@ -426,7 +417,7 @@ "MastermindInfo": "Costringi gli altri a uccidere per te", "TimeThiefInfo": "Uccidi per ridurre il tempo delle riunioni", "SniperInfo": "Cecchina i giocatori a distanza mutandoti", - "UndertakerInfo": "Teletrasporta un cadavere alla posizione segnata", + "UndertakerInfo": "Teletrasporta un cadavere alla posizione marcata", "RiftMakerInfo": "Traccio due squarci, toccali per deformare lo spazio", "EvilTrackerInfo": "Mutati per tenere traccia dei giocatori", "EvilHackerInfo": "Hackera il sistema", @@ -512,7 +503,6 @@ "PacifistInfo": "Usa i condotti per ripristinare le ricariche uccisione", "RebirthInfo": "Sorgi di Nuovo", "MonarchInfo": "Dai agli astronauti un potere di voto extra!", - "AbyssbringerInfo": "Crea Buchi Neri", "SpurtInfo": "Corri Come Un Coniglio!", "StealthInfo": "Uccidere Acceca Tutti i Presenti nella Stanza", "PenguinInfo": "Trascina le tue vittime", @@ -546,7 +536,6 @@ "WitnessInfo": "Scopri se qualcuno ha ucciso di recente", "GhastlyInfo": "Controlla qualcuno!", "SwapperInfo": "Scambia i voti di due giocatori", - "ChiefOfPoliceInfo": "Assumi lo sceriffo per servire gli equipaggi!", "NiceMiniInfo": "Nessuno può farti del male finché non cresci.", "ArsonistInfo": "Innaffia tutti e infiamma", "PyromaniacInfo": "Innaffia e uccidi tutti", @@ -707,8 +696,6 @@ "SlothInfo": "Sei più lento", "ProhibitedInfo": "Alcuni condotti sono bloccati", "EavesdropperInfo": "Ascolta gli altri ruoli", - "ShockerInfo": "Folgora giocatori ignari", - "RevenantInfo": "Prendi il ruolo del tuo assassino", "EngineerTOHEInfoLong": "(Astronauti):\nCome Ingegnere, potrai accedere ai condotti mentre il sabotaggio delle comunicazioni è disattivato.", "ScientistTOHEInfoLong": "(Astronauti):\nCome scienziato, puoi vedere i segni vitali in qualsiasi momento, mostrandoti chi è vivo e chi è morto.", "NoisemakerTOHEInfoLong": "(Astronauti):\nCome Starnazzatore, Ogni volta che muori, emetti un rumore e sullo schermo appare un indicatore visivo della tua morte, in modo che gli astronauti possano correre a prendere in flagrante la persona che ti ha ucciso (anche se non si tratta di Rosso).", @@ -725,7 +712,7 @@ "VampireInfoLong": "(Impostori):\nCome Vampiro, le tue uccisioni sono ritardate. Ciò significa che il tuo bersaglio muore anche se prima viene convocata una riunione. Tuttavia, Se mordi un'esca, ucciderai normalmente e segnali il cadavere. A seconda delle impostazioni, puoi usare il doppio clic (mordere i giocatori - clic singolo, uccidere normalmente - doppio clic).", "WarlockInfoLong": "(Impostori):\nCome Stregone, puoi maledire fino a un altro giocatore alla volta.\nQuando usi il pulsante Muta, se hai maledetto un giocatore, uccidono la persona più vicina che, a seconda delle impostazioni, può includere te o altri impostori.\nPuoi uccidere normalmente mentre sei Mutato.", "ZombieInfoLong": "(Impostori):\nLo zombi ha una breve ricarica uccisione ma è molto lento e ha un campo visivo davvero basso. Lo Zombi non può essere votato da nessuno tranne che dal dittatore, la velocità dello zombi diminuirà gradualmente quando uccide oppure col tempo che passa.", - "NinjaInfoLong": "(Impostori):\nCome Ninja, puoi usare il pulsante uccidi per segnare il bersaglio (clic singolo) o per ucciderlo normalmente (doppio clic). Potrai poi mutarti per raggiungere il bersaglio segnato e ucciderlo.", + "NinjaInfoLong": "(Impostori):\nCome Ninja, puoi usare il pulsante uccidi per marcare il bersaglio (clic singolo) o per ucciderlo normalmente (doppio clic). Potrai poi mutarti per raggiungere il bersaglio marcato e ucciderlo.", "AnonymousInfoLong": "(Impostori):\nCome Anonimo, puoi mutarti per costringere il tuo bersaglio a segnalare chiunque tu abbia ucciso in questo round.\nSe non hai ucciso nessuno in quel round, il bersaglio segnalerà il proprio cadavere come se fosse morto.\nNota: questo non funziona né sul Pigro né sul Pigrone, e questa abilità funzionerà indipendentemente dal fatto che il corpo possa normalmente essere segnalato.", "MinerInfoLong": "(Impostori):\nCome Minatore, puoi mutarti per teletrasportarti all'ultimo condotto in cui ti trovavi.", "KillingMachineInfoLong": "(Impostori):\nCome Macchina Assassina hai una ricarica uccisione molto breve con un campo visivo basso. Tuttavia, non puoi sabotare, segnalare, chiamare riunioni, né usare i condotti.\n\nNota: Oltrepasserai ogni scudo, uccidere esca e trappola per orsi non avrà alcun effetto", @@ -773,24 +760,24 @@ "SaboteurInfoLong": "(Impostori):\nCome Sabotatore, puoi uccidere solamente quando ci sono sabotaggi critici in corso.\n\nSe il sabotaggio dell'ossigeno o del reattore è attivo, allora puoi uccidere.", "CouncillorInfoLong": "(Impostori):\nCome Assessore, puoi uccidere i giocatori durante le riunioni come un Giudice.\nQuando uccidi in questo modo, quelle uccisioni appariranno come processi da un Giudice.\n\nIl comando per uccidere è /tl [Id del giocatore]\nPuoi vedere l'id dei giocatori di fianco al loro nome, o usare il comando /id per vedere l'id di ogni giocatore.\nA seconda delle impostazioni, L'Assessore si suiciderà quando giudicherà i suoi compagni di squadra.\nL'assessore convertito può giudicare liberamente.", "DazzlerInfoLong": "(Impostori):\nCome Abbagliante, puoi ridurre permanentemente il campo visivo del giocatore in cui ti muti. Quando muori, il loro campo visivo tornerà alla normalità.", - "DeathpactInfoLong": "(Impostori):\nCome Patto Mortale, ti muti per segnare i tuoi bersagli per un patto di morte.\nSe hai abbastanza giocatori segnati per un patto di morte, questi devono incontrarsi entro un determinato periodo; se non ci riescono, muoiono.\nSe un giocatore segnato muore prima che il patto di morte sia completo, il patto viene ritirato.", + "DeathpactInfoLong": "(Impostori):\nCome Patto Mortale, ti muti per marcare i tuoi bersagli per un patto di morte.\nSe hai abbastanza giocatori marcati per un patto di morte, questi devono incontrarsi entro un determinato periodo; se non ci riescono, muoiono.\nSe un giocatore marcato muore prima che il patto di morte sia completo, il patto viene ritirato.", "DevourerInfoLong": "(Impostori):\nCome Divoratore, usi il tuo mutaforma per cambiare l'aspetto del bersaglio del mutaforma permanentemente. Inoltre, per la modifica dell'aspetto di ogni giocatore, la tua ricarica uccisione viene ridotta di un numero definito di secondi. Se il Divoratore muore o viene eliminato durante una riunione, l'aspetto del giocatore tornerà al suo aspetto normale.", "MorphlingInfoLong": "(Impostori):\nCome Mutante, sei un Mutaforma ma non puoi uccidere quando non sei mutato.", "TwisterInfoLong": "(Impostori):\nCome Uragano, puoi usare il mutaforma per scambiare la posizione di tutti i giocatori casualmente. Lo scambio avviene due volte, una volta quando inizi la mutazione e una volta quando ritorni al tuo aspetto originale.\nL'Uragano stesso non si scambierà di posto con nessuno, e i giocatori nei condotti non si teletrasporteranno.", "LurkerInfoLong": "(Impostori):\nCome Predatore, puoi saltare in un condotto per ridurre la ricarica uccisione di un certo numero di secondi, Dopo che hai ucciso, la ricarica uccisione ritorna al suo valore originale.", "VisionaryInfoLong": "(Impostori):\nCome Visionario, vedi gli allineamenti dei giocatori viventi durante un incontro.\nLe seguenti informazioni verranno visualizzate sui giocatori:\n- Il nome Rosso indica gli Impostori.\n- Il nome Ciano indica gli Astronauti.\n- Il nome Grigio indica i Neutrali.", "PlagueDoctorInfoLong": "(Neutrali):\n(Medico della Peste da TOH)\nL'obiettivo dello Scienziato della Peste è infettare ogni giocatore vivente.\nIniziano scegliendo un giocatore da infettare, dopodiché chiunque trascorra un\ndeterminato periodo di tempo nel raggio d'azione del giocatore infetto viene infettato a sua volta.\nL'avanzamento dell'infezione è cumulativo e non si ripristina con la distanza o dopo le riunioni.", - "RefugeeInfoLong": "(Follenauti):\nCome Profugo, eri:\n -Un Amnesico che si è ricordato di essere un Impostore\n -Un assassino che ha ucciso il bersaglio del Padrino.\n -Un Romantico il cui partner era un Impostore\n -O un Imitatore che ha imitato un Impostore.\n\nOra il tuo compito è aiutare gli Impostori a uccidere gli Astronauti.", + "RefugeeInfoLong": "(Follenauta):\nCome Profugo, eri un'Amnesico che si è ricordato di essere un Impostore o un assassino che ha ucciso il bersaglio del Padrino.\n\nOra il tuo lavoro è di aiutare gli Impostori a uccidere gli Astronauti.", "UnderdogInfoLong": "(Impostori):\nCome Sfavorito, non puoi uccidere finché non c'è un certo numero di giocatori vivi.", "ConsigliereInfoLong": "(Impostori):\nCome Consigliere, puoi rivelare i ruoli degli altri giocatori utilizzando il pulsante uccidi.\n\nClic singolo: rivela il ruolo\nDoppio clic: uccidi\n\nSe esaurisci gli usi di rivelazione, il pulsante uccidi funziona normalmente.", "LudopathInfoLong": "(Impostori):\nCome Ludopatico, la tua ricarica uccisione è casuale.\n\nIl minimo può essere 1 secondo, mentre il massimo è la ricarica uccisione normale.", - "GodfatherInfoLong": "(Impostori):\nCome Padrino, voti qualcuno per renderlo il tuo bersaglio.\nNel round successivo, se qualcuno uccide il bersaglio, l'assassino si trasformerà in un Profugo o Follenauta.", + "GodfatherInfoLong": "(Impostori):\nCome Padrino, voti qualcuno per renderlo il tuo bersaglio.\nNel round successivo, se qualcuno uccide il bersaglio, l'assassino si trasformerà in un Profugo.", "ChronomancerInfoLong": "(Impostori):\nCome Cronomante, hai una barra di carica che indica quando il massacro è pronto. Quando è al 100%, la prossima volta che uccidi qualcuno entri in modalità massacro, il che significa che puoi uccidere indefinitamente finché la barra non si esaurisce. Altrimenti hai una normale ricarica uccisione.", - "PitfallInfoLong": "(Impostori):\nCome Fossa, usi la mutazione per segnare l'area attorno alla mutazione come una trappola. I giocatori che entrano in quest'area verranno immobilizzati rapidamente, e la loro vista sarà compromessa.", + "PitfallInfoLong": "(Impostori):\nCome Fossa, usi la mutazione per marcare l'area attorno al mutaforma come una trappola. I giocatori che entrano in quest'area verranno immobilizzati rapidamente, e la loro vista sarà compromessa.", "EvilMiniInfoLong": "(Impostori):\nCome Mini Malvagio, sei immortale finché non cresci e hai una ricarica uccisione iniziale molto lunga, che si riduce drasticamente man mano che cresci.", "BlackmailerInfoLong": "(Impostori):\nCome Ricattatore, quando ti muti in un bersaglio, ricatterai quel giocatore. Ciò significa che durante le riunioni non potrà parlare.\n\nNota: se qualcuno è già stato ricattato, ricattare un'altra persona toglierà il ricatto alla persona attuale.", "InstigatorInfoLong": "(Impostori):\nCome istigatore, il tuo compito è quello di mettere gli astronauti l'uno contro l'altro. Ogni volta che un Astronauta viene eliminato durante una riunione, se sei vivo, un altro Astronauta che ha votato per il giocatore innocente morirà dopo la riunione. L'Host determina Il numero di giocatori aggiuntivi che muoiono.", - "LazyGuyInfoLong": "(Astronauti):\nIl Pigrone ha un solo un incarico. Inoltre, le abilità degli Impostori non possono influenzare il Pigrone, come ad esempio essere un capro espiatorio per Anonimo, essere segnato da uno Stregone o da un Burattinaio e altro ancora. Il Pigrone non avrà alcun Modificatore.", + "LazyGuyInfoLong": "(Astronauti):\nIl Pigrone ha un solo un incarico. Inoltre, le abilità degli Impostori non possono influenzare il Pigrone, come ad esempio essere un capro espiatorio per Anonimo, essere marcato da uno Stregone o da un Burattinaio e altro ancora. Il Pigrone non avrà alcun Modificatore.", "SuperStarInfoLong": "(Astronauti):\nCi sarà il logo di una stella accanto al nome della Super Star, così tutti sapranno chi è la Super Star. La Super Star può essere uccisa solo quando l'assassino è da solo con la Super Star (solo uccisioni regolari). Inoltre, gli indovini non possono indovinare la Super Star. ", "CelebrityInfoLong": "(Astronauti):\nTutti gli Astronauti vedono il flash uccisione quando la Celebrità muore (così come il Veggente vede il flash uccisione) e ricevono un avviso alla riunione successiva. Gli Impostori non ne sapranno nulla.", "CleanserInfoLong": "(Astronauti):\nCome Purificatore, puoi votare per cancellare i modificatori di qualsiasi bersaglio durante la riunione. La cancellazione ha effetto dopo la fine della riunione. A seconda delle impostazioni, il giocatore purificato potrebbe non ricevere più modificatori.", @@ -838,7 +825,7 @@ "AddictInfoLong": "(Astronauti):\nCome Tossicomane, hai un timer per il suicidio. Quando scade, ti uccidi.\nIl timer è indicato dalla ricarica dei condotti. Quando la ricarica dei condotti è a 0 secondi, hai ancora un breve periodo di tempo per usare i condotti.\nSe non ce la fai, muori; se ce la fai, il timer del suicidio si azzera.\nInoltre, dopo che hai usato i condotti, nessuno può interagire con te per un periodo definito.\nDopo, il periodo termina e tu sei immobilizzato per un altro periodo definito e non puoi segnalare alcun corpo.", "MoleInfoLong": "(Astronauti):\nCome la Talpa, quando usi i condotti, rimani nel condotto per 1 secondo. Quando esci dal condotto, apparirai vicino a un condotto casuale nella mappa (tranne quello che hai usato).", "AlchemistInfoLong": "(Astronauti):\nCome Alchimista, prepari pozioni quando completi gli incarichi. La pozione che hai creato verrà visualizzata sotto il nome del tuo ruolo con la descrizione e le istruzioni corrispondenti. Puoi ottenere sette pozioni diverse, alcune con effetti dannosi o senza effetti. Usa i condotti per usare la pozione.", - "KamikazeInfoLong": "(Impostori):\nCome Kamikaze puoi fare clic con un solo clic per contrassegnare le persone. Fare doppio clic per uccidere normalmente. Quando muori, muoiono anche tutti quelli bersagliati, con causa di morte Bersagliato.", + "KamikazeInfoLong": "(Impostori):\nCome Kamikaze puoi fare clic con un solo clic per marcare le persone. Fare doppio clic per uccidere normalmente. Quando muori, muoiono anche tutti quelli bersagliati, con causa di morte Bersagliato.", "TracefinderInfoLong": "(Astronauta):\nCome Tracciatore, puoi accedere ai segni vitali in qualsiasi momento.\nInoltre, ottieni frecce che puntano a cadaveri, con un ritardo impostato dall'Host.", "OracleInfoLong": "(Astronauta):\nCome Oracolo, puoi votare un giocatore durante una riunione.\nVedrai se è un Astronauta, un Neutrale o un Impostore.\nA seconda delle impostazioni, è possibile che il risultato non sia corretto.", "SpiritualistInfoLong": "(Astronauti):\nCome Spiritualista, ottieni una freccia che punta verso il fantasma della vittima dell'ultima riunione. C'è un'opzione per far scomparire e riapparire la freccia a intervalli. Prova a informare il fantasma della tua abilità se puoi; se sono dalla tua parte, potrebbero condurti a un ruolo malvagio in modo da poterli espellere. Fai attenzione, poiché i ruoli malvagi possono fare lo stesso per gli Astronauti.", @@ -846,7 +833,7 @@ "InspectorInfoLong": "(Astronauti):\nControlla se due giocatori fanno parte della stessa squadra oppure no. Riceverai un messaggio di conferma se fanno parte della stessa squadra o un messaggio di rifiuto se non fanno parte della stessa squadra.\n\nTutti i giocatori neutrali e convertiti vengono conteggiati nella stessa squadra. L'Imbroglione conta come Astronauta e il Mascalzone conta come Impostore.\nComando di controllo: /cmp [id giocatore 1] [id giocatore 2].", "CaptainInfoLong": "(Astronauti):\nCon ogni incarico completato, il Capitano acquisisce il potere di rallentare un ruolo casuale non astronauta. Gli astronauti possono vedere ☆ oltre al nome del Capitano.\n\nSe qualcuno tradisce la fiducia del Capitano votandolo, egli perderà un modificatore.", "AdmirerInfoLong": "(Astronauti):\nCome Ammiratore, ammirare un giocatore lo porterà dalla parte degli Astronauti.\nVinceranno con gli Astronauti e non con la loro squadra originale.\n\nPuoi farlo solo una volta per giocatore.", - "TimeMasterInfoLong": "(Astronauti):\nCome Padrone Temporale, usa i condotti per contrassegnare la posizione di tutti.\nQuando si utilizza nuovamente l'abilità, ogni giocatore vivo verrà riavvolto nelle posizioni contrassegnate.\n\nDurante la durata dell'abilità, il Padrone Temporale ottiene uno scudo temporale, che lo protegge dalla morte.", + "TimeMasterInfoLong": "(Astronauti):\nCome Padrone Temporale, usa i condotti per marcare la posizione di tutti.\nQuando si utilizza nuovamente l'abilità, ogni giocatore vivo verrà riavvolto nelle posizioni marcate.\n\nDurante la durata dell'abilità, il Padrone Temporale ottiene uno scudo temporale, che lo protegge dalla morte.", "CrusaderInfoLong": "(Astronauta):\nCome Crociato, usa il pulsante uccidi per fare una crociata a un giocatore.\nSe quel giocatore viene attaccato, ucciderai l'attaccante.", "AltruistInfoLong": "(Astronauti):\nCome Altruista, puoi sacrificarti per far rianimare un cadavere usando il pulsante «Segnala».\nNota: se un giocatore morto ha abbandonato il gioco, quel corpo sarà segnalato normalmente.\nInoltre il giocatore rianimato non può segnalare il proprio cadavere", "ReverieInfoLong": "(Astronauti):\nCome Fantasticheria, puoi uccidere, ma la tua ricarica iniziale sara alta.\n\nAumenta se uccidi un astronauta e si riduce in caso contrario.\nA seconda dell'impostazione dell'Host, puoi fare cilecca quando raggiungi la ricarica uccisione massima, e il tuo bersaglio muore con te. \n\nVinci con altri astronauti.", @@ -856,7 +843,6 @@ "TaskManagerInfoLong": "(Astronauti):\nVedrai il totale degli incarichi completati (da tutti insieme) accanto al nome del tuo ruolo, che si aggiornerà in tempo reale.", "WitnessInfoLong": "(Astronauti):\nCome Testimone, quando usi il pulsante uccidi su qualcuno, saprai se ha ucciso negli ultimi X secondi o meno. (X dipende dalle impostazioni).", "SwapperInfoLong": "(Astronauti):\nIn qualità di Scambiatore, puoi scambiare i voti nelle riunioni.\n\nPer scambiare i voti, usa \"/sw [playerID]\" due volte.\n\nGli ID dei giocatori vengono visualizzati accanto ai nomi dei giocatori nelle riunioni, ma puoi anche utilizzare /id per ottenere un elenco di tutti gli ID dei giocatori.\n\nNota: A seconda delle impostazioni dell'host, puoi scambiare i tuoi voti.", - "ChiefOfPoliceInfoLong": "(Astronauti):\nI giocatori con le spade possono essere reclutati per unirsi alla squadra dello sceriffo per servire l'equipaggio\nNota: solo un'opportunità di reclutamento\nA seconda delle impostazioni, si può reclutare non assassini o non astronauti.\nPotresti suicidarti se reclutassi il bersaglio sbagliato.", "NiceMiniInfoLong": "(Astronauti):\nCome Mini Buono, la tua sopravvivenza è fondamentale. Non puoi essere ucciso finché non cresci e se muori o vieni espulso dalla riunione prima di crescere, tutti perdono. Questo ruolo unico aggiunge una nuova dinamica al gioco, in cui la tua sopravvivenza non è solo per il tuo bene, ma per il successo dell'intero equipaggio.", "SpyInfoLong": "(Astronauti):\nCome Spia, quando qualcuno usa il pulsante uccidi su di te (qualsiasi abilità tramite il pulsante uccidi), vedrai il suo nome in arancione per alcuni secondi.\nNota: se un Astronauta ha usato la sua abilità su di te, vedrai anche loro con un nome arancione!\nNota: se non hai utilizzi rimasti, non vedrai nessun nome arancione!\nNota: se l'interazione con il pulsante uccidi è bloccata, la ricarica del giocatore verrà ripristinato a 10 secondi", "RandomizerInfoLong": "(Astronauti):\nCome Randomizzatore, quando muori, il tuo assassino farà una delle seguenti azioni:\n 1. Auto-segnala Il tuo corpo\n 2. Stai vicino al tuo corpo\n 3. La ricarica delle uccisioni è impostato su 600 secondi\n 4. Vendica casualmente un giocatore.", @@ -871,7 +857,7 @@ "LawyerInfoLong": "(Neutrali):\nL'Avvocato ha un bersaglio da difendere, il quale sarà indicato con un diamante 「♦」 accanto al loro nome.\nSe il bersaglio vince, vinci.\nSe perde, perdi anche tu.", "OpportunistInfoLong": "(Neutrali):\nSe l'Opportunista sopravvive alla fine del gioco, l'Opportunista vince con la squadra vincente.", "VectorInfoLong": "(Neutrali):\nIl Vettore vince da solo usando i condotti un certo numero di volte.", - "JackalInfoLong": "(Neutrali):\nCome Sciacallo, vinci se sei l'ultimo giocatore vivo. Inoltre, puoi reclutare utilizzando il pulsante uccidi. Se il bersaglio non è uno che puoi reclutare, hai esaurito gli usi o non hai la possibilità di reclutare, allora ucciderai le persone normalmente (cioè non usare il pulsanti uccidi davanti agli altri pensando che recluterà).\nSe il bersaglio ha un pulsante uccidi e l'opzione per trasformarsi in una Spalla è attiva, diventerà una Spalla. Altrimenti, otterranno il modificatore Recluta se l'opzione per fornire il modificatore Recluta è attiva.\nA seconda delle impostazioni, quando lo Sciacallo viene ucciso, una Spalla verrà selezionata casualmente come nuovo Sciacallo.\nÈ possibile selezionare una Recluta se ne non ci sono Spalle in vita.", + "JackalInfoLong": "(Neutrali):\nCome Sciacallo, vinci se sei l'ultimo giocatore vivo. Inoltre, puoi reclutare utilizzando il pulsante uccidi. Se il bersaglio non è uno che puoi reclutare, hai esaurito gli usi o non hai la possibilità di reclutare, allora ucciderai le persone normalmente (cioè non usare il pulsanti uccidi davanti agli altri pensando che recluterà).\nSe il bersaglio ha un pulsante uccidi e l'opzione per trasformarsi in un Aiutante è attiva, diventerà un Aiutante. Altrimenti, otterranno il modificatore Recluta se l'opzione per fornire il modificatore Recluta è attiva.", "GodInfoLong": "(Neutrali):\nCome Dio, conosci il ruolo di ognuno fin dall'inizio. Se vivi fino alla fine del gioco, rubi la vittoria, cioè., tutti gli altri perdono, e tu vinci.", "InnocentInfoLong": "(Neutrali):\nL'Innocente può usare il pulsante uccidi per incastrare qualsiasi giocatore e il bersaglio incastrato ucciderà immediatamente l'Innocente. Se il bersaglio viene espulso durante la riunione, l'Innocente vince. Nota: Giullare, Esecutore e Innocente possono vincere insieme.", "PelicanInfoLong": "(Neutrali):\nCome Pellicano, puoi usare il pulsante uccidi per inghiottire un giocatore vivo, teletrasportandolo fuori dalla mappa ma senza ucciderlo. I giocatori inghiottiti moriranno solo se tu sarai ancora vivo alla fine del round. Se muori o te ne vai durante il round, tutti i giocatori vivi inghiottiti appariranno nella mappa in cui ti trovavi.", @@ -883,7 +869,7 @@ "SolsticerInfoLong": "(Neutrali):\nCome Impiegato, non morirai e vincerai completando tutti i tuoi incarichi in un unico round. Al termine di ogni riunione, i tuoi incarichi vengono ripristinati e devi ricominciare tutto da capo.\nOgni voto sull'Impiegato verrà cancellato direttamente.\nI tentativi di uccisione sull'Impiegato lo teletrasporteranno fuori dalla mappa come Pellicano fino al termine dell'incontro.\nLa ricarica uccisione dell'assassino verrà ripristinato a 10 secondi.\nL'Impiegato non viene considerato nulla nel gioco.", "CollectorInfoLong": "(Neutrali):\nCome Collezionista, quando voti per un giocatore, per ogni altro giocatore che lo ha votato, guadagni un punto. Quando raccogli i voti richiesti, il gioco finisce e vinci da solo, anche se hai eliminato un giullare o il bersaglio di un esecutore.", "GlitchInfoLong": "(Neutrali):\nCome Glitch, puoi hackerare i giocatori (clic singolo) o uccidere normalmente (doppio clic).\nColoro che sono stati hackerati non possono uccidere, usare i condotti o segnalare per la durata delle hack.\nInoltre, chiamare un sabotaggio diverso dalle porte non avrà alcun effetto e ti travestirà invece da giocatore casuale. Non puoi mascherarti durante o dopo i sabotaggi.\nPer vincere, sii l'ultimo giocatore vivo.", - "SidekickInfoLong": "(Neutrali):\nCome Spalla, il vostro compito è quello di aiutare lo Sciacallo uccidere tutti.\nTu e lo Sciacallo vincerete insieme.\nA seconda delle impostazioni, puoi trasformarti in Sciacallo se il vecchio Sciacallo è stato ucciso.\nPotresti non essere in grado di uccidere fino a quando il vecchio Sciacallo non è morto.", + "SidekickInfoLong": "(Neutrali):\nCome Aiutante, il tuo compito è aiutare lo Sciacallo a uccidere tutti.\n\nTu e lo Sciacallo vincete insieme.", "ProvocateurInfoLong": "(Neutrali):\nCome Provocatore, puoi uccidere qualsiasi bersaglio con il pulsante uccidi. Se il bersaglio perde alla fine della partita, il Provocatore vince con la squadra vincitrice.", "BloodKnightInfoLong": "(Neutrali):\nIl Cavaliere del Sangue vince quando è l'ultimo ruolo assassino in vita, e il numero di astronauti è inferiore o uguale al numero di Cavalieri del Sangue. Dopo ogni uccisione, il Cavaliere del Sangue ottiene uno scudo temporaneo rendendolo immortale per alcuni secondi.", "PlagueBearerInfoLong": "(Apocalisse):\nCome Untore, infetta tutti usando il pulsante uccidi per trasformarti in Pestilenza.\nUna volta che ti trasformerai in Pestilenza, diventerai immortale e acquisirai la capacità di uccidere, e ucciderai chiunque tenti di ucciderti.\n\nInoltre, quando i giocatori infetti interagiscono con giocatori non infetti, anche loro verranno infettati.", @@ -910,12 +896,11 @@ "TraitorInfoLong": "(Neutrali):\nCome Traditore, eri un impostore che ha tradito gli impostori.\nConosci gli Impostori, ma loro non conoscono te.\nLa svolta? Possono ucciderti ma tu non puoi uccidere loro.\n\nElimina gli impostori con altri mezzi, poi uccidi tutti gli altri per vincere!", "TrollerInfoLong": "(Neutrali):\nCome Troller, puoi completare gli incarichi in modo che possano accadere eventi casuali ai giocatori.\nAd esempio, modificando la velocità di tutti i giocatori, teletrasporto, influenzando il sabotaggio, ecc.\nInoltre puoi vincere con la squadra vincitrice.", "VultureInfoLong": "(Neutrali):\nCome Avvoltoio, segnala i corpi per vincere!\n\nQuando segnali un corpo, se la ricarica di mangiare è scaduto, mangerai il corpo (rendendolo non segnalabile).\nSe la tua abilità di mangiare è ancora in ricarica, riporterai il corpo normalmente.\n\nInoltre, segnalerai i corpi normalmente se viene raggiunto il numero massimo di corpi mangiati per round.", - "AbyssbringerInfoLong": "(Impostori):\nCome Portatore di abissi, puoi piazzare buchi neri. I buchi neri risucchieranno i giocatori e li uccideranno quando entreranno in collisione con loro.", "TaskinatorInfoLong": "(Neutrali):\nCome Incaricator, quando completi un incarico, verrà piazzata una bomba sull'incarico. Quando un altro giocatore completa l'incarico con la bomba, essa esploderà, e il giocatore morirà.\n\nVinci se sopravvivi fino alla fine e se gli Astronauti non vincono.\n\n Nota: Le bombe dell'Incaricator ignora tutte le protezioni.", - "BenefactorInfoLong": "(Astronauti):\nCome Benefattore, ogni volta che completi un incarico, quel incarico verrà contrassegnato. Quando un altro giocatore completa l'incarico contrassegnato, ottiene uno scudo temporaneo.\n\n Nota: lo scudo protegge solo dagli attacchi diretti.", + "BenefactorInfoLong": "(Astronauti):\nCome Benefattore, ogni volta che completi un incarico, quel incarico verrà marcato. Quando un altro giocatore completa l'incarico marcato, ottiene uno scudo temporaneo.\n\n Nota: lo scudo protegge solo dagli attacchi diretti.", "MedusaInfoLong": "(Neutrali):\nCome Medusa, puoi pietrificare i corpi proprio come pulire un corpo.\nI corpi Pietrificati non possono essere segnalati.\n\nUccidi tutti per vincere.", "SpiritcallerInfoLong": "(Neutrali):\nCome Evocatore, le tue vittime si trasformano in Spiriti Malvagi dopo la loro morte. Questi spiriti possono aiutarti a vincere congelando brevemente gli altri giocatori o bloccando la loro vista. In alternativa, gli spiriti possono fornirti uno scudo che ti protegge brevemente da un tentativo di uccisione.", - "AmnesiacInfoLong": "(Neutrali):\nCome Amnesico, usa il tuo pulsante segnala per ricordare un bersaglio e ottenere il suo ruolo.\nPer bilanciare il gioco, non sarai in grado di usare i condotti dopo aver ricordato il tuo ruolo se non puoi usare i condotti come Amnesico.", + "AmnesiacInfoLong": "(Neutrali):\nCome Amnesico, usa il pulsante segnala per ricordare un ruolo.\n\nSe il bersaglio era un impostore, diventerai un Profugo.\nSe il bersaglio era un Astronauta, diventerai il ruolo bersaglio se compatibile (altrimenti diventerai un Ingegnere).\nSe l'obiettivo era un passivo neutrale o un assassino neutrale non specificato, diventerai il ruolo definito nelle impostazioni.\nSe l'obiettivo era un assassino neutrale di pochi selezionati, diventerai il ruolo che ricoprono.", "ImitatorInfoLong": "(Neutrali):\nCome Imitatore, usa il pulsante uccidi per imitare un giocatore.\n\nDiventerai uno Sceriffo, un Profugo, o qualche Neutrale.", "BanditInfoLong": "(Neutrali):\nCome Bandito, puoi cliccare una volta sul tuo pulsante uccidi per rubare il modificatore di un giocatore e due volte per ucciderlo. A seconda delle impostazioni, puoi rubare il modificatore all'istante o dopo l'inizio della riunione. Dopo aver raggiunto il numero massimo di furti, ucciderai normalmente. Inoltre, se non ci sono modificatori rubabili sul bersaglio o se il bersaglio è testardo, ucciderai il bersaglio.\n\nUccidi tutti per vincere.\n\nNota: Purificato, Ultimo impostore e Amanti non possono essere rubati.\nNota: se Bandito può usare i condotti è attivo, Agile non si potrà rubare.", "DoppelgangerInfoLong": "(Neutrali):\nCome Doppelganger, usa il pulsante uccidi per rubare l'identità di un giocatore (il suo nome e la sua skin) e poi uccidi il tuo bersaglio.\n\nUccidi tutti per vincere.\n\nNota: Non puoi rubare l'identità del bersaglio quando il Camuffamento è attivo.", @@ -925,7 +910,7 @@ "WerewolfInfoLong": "(Neutrali):\nCome lupo mannaro, puoi uccidere proprio come qualsiasi assassino.\nTuttavia, quando uccidi, muoiono anche tutti i giocatori vicini.\nQualsiasi giocatore che muore per questo avrà la causa della loro morte come Sbranato.\n\nPer bilanciare questo, hai una ricarica uccisione più alta di chiunque altro.", "ShamanInfoLong": "(Neutrali):\nCome Sciamano, puoi usare il pulsante uccidi per selezionare una bambola vudù una volta per round. Se uno ha usato il pulsante uccidi su di te, l'effetto verrà deviato verso la bambola vudù.\nSe sopravvivi fino alla fine, vinci con la squadra vincente.\nNota: se l'assassino non può uccidere il bersaglio prescelto, l'omicidio viene annullato, ma se l'assassino ricontrolla lo Sciamano, ucciderà lo Sciamano.", "SeekerInfoLong": "(Neutrali):\nCome Cercatore, usa il pulsante uccidi per taggare il bersaglio. Se il Cercatore tagga il giocatore sbagliato, verrà detratto un punto, e se il Cercatore tagga il giocatore corretto, verrà aggiunto un punto.\nInoltre, il Cercatore non sarà in grado di muoversi per 5 secondi dopo ogni riunione e dopo aver ottenuto un nuovo bersaglio\n\nIl cercatore deve raccogliere un determinato numero di punti stabiliti dall'Host per vincere.", - "PixieInfoLong": "(Neutrali):\nCome Folletto, contrassegna fino a un numero x di bersagli per ogni round utilizzando il pulsante uccidi. Devi far espellere uno dei bersagli segnati quando inizia la riunione. Se non ci riesci, ti suiciderai, tranne nel caso in cui non hai segnato alcun bersaglio o tutti i bersagli sono morti. I bersagli selezionati si azzerano al termine della riunione. Se ci riesci, guadagnerai un punto. Puoi vedere tutti i tuoi bersagli con nomi colorati.\n\nVincerai con la squadra vincente quando avrai ottenuto un certo numero di punti stabilito dall'Host.", + "PixieInfoLong": "(Neutrali):\nCome Folletto, marca fino a un numero x di bersagli per ogni round utilizzando il pulsante uccidi. Devi far espellere uno dei bersagli marcati quando inizia la riunione. Se non ci riesci, ti suiciderai, tranne nel caso in cui non hai marcato alcun bersaglio o tutti i bersagli sono morti. I bersagli selezionati si azzerano al termine della riunione. Se ci riesci, guadagnerai un punto. Puoi vedere tutti i tuoi bersagli con nomi colorati.\n\nVincerai con la squadra vincente quando avrai ottenuto un certo numero di punti stabilito dall'Host.", "SchrodingersCatInfoLong": "(Neutrali):\nCome Gatto di Schrödinger, se qualcuno tenta di usare il pulsante uccidi su di te, bloccherai l'azione e ti unirai alla sua squadra. Questa capacità di blocco funziona solo una volta. Di base, non hai una condizione di vittoria, il che significa che vinci solo dopo aver cambiato squadra.\nIn aggiunta a questo, non verrai conteggiato come nulla nel gioco.\n\nNota: se la Macchina Assassina tenta di usare il suo pulsante uccidi su di te, l'interazione non verrà bloccata e morirai.", "RomanticInfoLong": "(Neutrali):\nIl Romantico può scegliere il proprio partner amante usando il pulsante uccidi (questo può essere fatto in qualsiasi momento del gioco). Una volta scelto il partner, possono utilizzare il pulsante uccidi per fornire al proprio partner uno scudo temporaneo che lo protegge dagli attacchi. Se il partner muore, il ruolo del Romantico cambierà in base alle seguenti condizioni:\n1. Se il partner era un Impostore, il romantico diventa Profugo\n2. Se il loro partner era un Assassino Neutrale, allora diventa un Romantico Spietato.\n3. Se il loro partner era un Astronauta o un Neutrale che non uccide, il Romantico diventa il Romantico Vendicativo.\n\nIl Romantico vince con la squadra vincente se vince il suo partner.\nNota: se il tuo ruolo cambia, la tua condizione di vittoria verrà modificata di conseguenza", "RuthlessRomanticInfoLong": "(Neutrali):\nCambi il tuo ruolo da Romantico se il tuo partner (Un assassino neutrale) viene ucciso. Come Romantico Spietato, vinci se uccidi tutti e sei l'ultimo rimasto. Se vinci, anche il tuo partner morto vince con te.", @@ -936,7 +921,6 @@ "JinxInfoLong": "(Neutrale):\nCome lo Iettatore, ogni volta che vieni attaccato, gli porti sfortuna, con il risultato di morire sfortunati.\nQuesto ha degli usi limitati.\n\nUccidi chiunque per vincere.", "PotionMasterInfoLong": "(Neutrali):\nCome Maestro delle Pozioni, hai tre diverse pozioni assegnate a tre diverse azioni.\n\nClic singolo: Rivela il ruolo\nDoppio clic: Uccidi\nMappa: Sabotaggio\n\nLa pozione di rivelazione ha un limite.\nQuando le finisci, il pulsante uccidi si imposta automaticamente sull'uccisione.", "NecromancerInfoLong": "(Neutrali):\nCome Necromante, vinci quando sei l'ultimo rimasto.\nInoltre, quando qualcuno tenta di ucciderti, bloccherai l'uccisione e ti teletrasporterai in un condotto casuale. Avrai un tempo limitato per uccidere il tuo assassino. Se ci riesci, sei vivo. Se il tempo scade prima che tu abbia ucciso il tuo assassino, morirai in modo permanente. Se provi a uccidere qualcun altro oltre al tuo assassino, morirai.", - "ShockerInfoLong": "(Neutrali):\nCome Shocker, puoi contrassegnare le stanze eseguendo degli incarichi in esse, e poi usare i condotti per Elettrificare chiunque si trovi in ​​quelle stanze per un periodo di tempo stabilito. Quando hai completato tutti i tuoi incarichi, ne ottieni di nuovi. Nota: eseguire degli incarichi durante quel periodo le contrassegnerà per il prossimo utilizzo dell'abilità.", "LastImpostorInfoLong": "(Modificatori):\nQuesto effetto speciale è dato all'Ultimo Impostore sopravvissuto. Riduce significativamente la loro ricarica uccisione.", "OverclockedInfoLong": "(Modificatori):\nCome Sovraccaricato, la sua ricarica uccisione sarà ridotta di una percentuale.\n\nQuesta funzione è assegnata solo ai ruoli con un pulsante uccidi.", "LoversInfoLong": "(Modificatori):\nGli Amanti sono una combinazione di due giocatori. Gli Amanti vincono quando sono gli ultimi rimasti e la loro vittoria viene condivisa. Quando uno degli Amanti vince, anche l'altro vince insieme. Gli Amanti possono vedere il simbolo 「♥」 accanto al nome dell'altro. Se uno degli Amanti muore, l'altro morirà affranto (potrebbe non morire affranto a seconda delle impostazioni dell'Host). Se uno degli Amanti viene esiliato durante la riunione, l'altro morirà e diventerà un cadavere che non potrà essere segnalato.", @@ -980,7 +964,7 @@ "RebirthInfoLong": "(Modificatori):\nCome Rinascita, se sei il giocatore che sta per essere espulso, scambierai la skin con un Astronauta casuale che ha votato per te.\nNota: il voto dell'host non conta mai\nRinascita ti verrà rimosso se hai esaurito tutte le tue rinascite.", "LoyalInfoLong": "(Modificatori):\nIn quanto Leale, non puoi essere reclutato da ruoli come Sciacallo o Cultista.\n\nNon può essere assegnato ai neutrali.", "EvilSpiritInfoLong": "(Modificatori):\nCome Spirito maligno, il tuo compito è aiutare l'Evocatore a raggiungere la vittoria. Puoi usare il pulsante Tormenta per Immobilizzare i giocatori e ridurne il campo visivo. In alternativa, puoi usare il pulsante Tormenta per fornire all'Evocatore uno scudo contro un tentativo di uccisione temporaneamente.", - "RecruitInfoLong": "(Modificatori Traditori):\nCome recluta, sei nella squadra dello Sciacallo e aiuti lo Sciacallo e le sue Spalle.\nNon puoi vincere con la tua squadra originale.\nA seconda delle impostazioni, potresti trasformarti in Sciacallo se il vecchio Sciacallo è stato ucciso e non ci sono più Spalle in vita.", + "RecruitInfoLong": "(Modificatori tradimento):\nCome recluta, fai parte della squadra dello Sciacallo e aiuti lo Sciacallo e i suoi aiutanti.\n\nNon puoi vincere con la tua squadra originale.", "AdmiredInfoLong": "(Modificatori tradimento):\nIn quanto giocatore ammirato, vinci con gli astronauti e non con la tua squadra originale.\n\nPuoi vedere l'Ammiratore.", "GlowInfoLong": "(Modificatori):\nDurante Luci Spente, tu e i giocatori nelle vicinanze riceverete una visione potenziata.", "RadarInfoLong": "(Modificatori):\nCome Radar, hai delle frecce che puntano alla persona più vicina per tutto il tempo.", @@ -1023,11 +1007,10 @@ "SlothInfoLong": "(Modificatori):\nLa velocità di movimento predefinita del Bradipo è più lenta rispetto alle altre.\n(La velocità dipende dalle impostazioni dell'host)", "ProhibitedInfoLong": "(Modificatori):\nCome Proibito, hai dei condotti specifici che non puoi usare.\nQuanti condotti sono disabilitati dipende dalle impostazioni dell'Host.", "EavesdropperInfoLong": "(Modificatori):\nCome Origliatore, hai la possibilità di leggere messaggi basati su informazioni relative ad altri ruoli/modificatori, come Imbalsamatore o Indagatore.", - "ApocalypseInfoLong": "(Apocalisse):\nI membri dell'Apocalisse sono in una squadra separata che lavora insieme e vince insieme. Se ci sono più ruoli dell'Apocalisse nel gioco, possono vedere i ruoli degli altri.\nA seconda delle impostazioni dell'host, i ruoli dell'Apocalisse possono indovinare o essere indovinati.", - "RevenantInfoLong": "(Neutrale):\nCome Revenant, il tuo obiettivo è di essere ucciso. Se sei ucciso, prenderai il ruolo del tuo assassino e ucciderai il tuo assassino. Non puoi vincere prima di essere ucciso.\nNota che Revenant funziona solo quando viene ucciso direttamente.", + "ApocalypseInfoLong": "(Apocalypse):\nApocalypse members are on a separate team that works together and wins together. If there are multiple Apocalypse roles in the game, they can see each other's roles.\nDepending on the Host's settings, Apocalypse roles can guess or be guessed.", "ShowTextOverlay": "Sovrapposizione Testo", "Overlay.GuesserMode": "Modalità Indovino", - "Overlay.NoGameEnd": "Nessuna Fine del Gioco", + "Overlay.NoGameEnd": "Gioco senza fine", "Overlay.DebugMode": "Modalità Debug", "Overlay.LowLoadMode": "Modalità Leggera", "Overlay.AllowConsole": "Console", @@ -1038,8 +1021,6 @@ "AbilityUseLimit": "Limite iniziale di utilizzo delle abilità", "AbilityInUse": "Abilità in uso", "AbilityExpired": "Abilità scaduta, {0} usi rimanenti", - "RevenantTargeted": "Il tuo ruolo è cambiato in {0}", - "RevenantCanCopyAddons": "Puoi Rubare i Modificatori", "ShowArrows": "Ha frecce che puntano verso i cadaveri", "ArrowDelayMin": "Ritardo Minimo di visualizzazione della Freccia", "ArrowDelayMax": "Ritardo Massimo di visualizzazione della Freccia", @@ -1053,7 +1034,7 @@ "DisableMeeting": "Disabilita le Riunioni", "DisableCloseDoor": "Disabilita il Sabotaggio delle Porte", "DisableSabotage": "Disabilita i Sabotaggi", - "NoGameEnd": "Nessuna Fine del Gioco", + "NoGameEnd": "Gioco Senza Fine", "AllowConsole": "Console BepInEx", "DebugMode": "Modalità di Debug", "SyncButtonMode": "Limite Utilizzi Riunioni", @@ -1340,7 +1321,7 @@ "ShowNARemainOnEject": "Mostra Neutrali dell'Apocalisse rimasti nelle espulsioni", "ConfirmEgoistOnEject": "Conferma Egoista all'espulsione", "ConfirmLoversOnEject": "Conferma Amanti all'espulsione", - "ConfirmSidekickOnEject": "Conferma Spalle all'espulsione", + "ConfirmSidekickOnEject": "Conferma Aiutanti all'espulsione", "HideBittenRolesOnEject": "Nascondi ruoli dei giocatori morsi all'espulsione", "ShowTeamNextToRoleNameOnEject": "Mostra a quale squadra apparteneva il ruolo del giocatore espulso", "Ban": "Ban", @@ -1368,8 +1349,6 @@ "ShieldedCanUseKillButton": "Il giocatore protetto può usare il pulsante abilità / uccidi", "PlayerIsShieldedByGame": "Il giocatore è protetto dal gioco!", "LegacyNemesis": "Utilizza la versione precedente", - "LegacyParasite": "Utilizza la versione precedente", - "LegacyTraitor": "Utilizza la versione precedente", "ArsonistKeepsGameGoing": "L' Incendiario fa continuare il gioco", "ArsonistCanIgniteAnytime": "Può dare Fuoco in qualsiasi momento", "ArsonistMinPlayersToIgnite": "Minimo Innaffiati per dare fuoco", @@ -1512,23 +1491,11 @@ "SheriffCanKillSeparately": "Impostazioni Individuali", "In%team%": "(Squadra %team%)", "SheriffMisfireKillsTarget": "Cilecca Uccide il Bersaglio", - "BlackHolePlaceCooldown": "Ricarica Piazzamento Buco Nero", - "BlackHoleDespawnMode": "Modalità Scomparsa Buco Nero", - "BlackHoleDespawnTime": "Tempo dopo la scomparsa del buco nero", - "Abyssbringer.Suffix": "Numero di giocatori consumati da {0} buchi neri attivi:\\n{1}", - "Abyssbringer.Suffix.BlackHole": "{0}: {1}", - "BlackHoleMovesTowardsNearestPlayer": "Il buco nero si muove verso il giocatore più vicino", - "BlackHoleMoveSpeed": "Velocità Di Movimento Buco Nero", - "BlackHoleRadius": "Raggio di consumo del buco nero", - "AfterTime": "Dopo il tempo", - "After1PlayerEaten": "Dopo che 1 giocatore è stato mangiato", - "AfterMeeting": "Dopo la riunione", - "None": "Nessuno", "SheriffShotLimit": "Massimo Numero di Uccisioni", "SheriffCanKillAllAlive": "Può Uccidere Quando Nessuno è Morto", "SheriffCanKillCharmed": "Può uccidere i giocatori Affascinati", "SheriffCanKillEgoist": "Può Uccidere gli Egoisti", - "SheriffCanKillSidekick": "Può Uccidere le Spalle", + "SheriffCanKillSidekick": "Può Uccidere gli Aiutanti", "SheriffCanKillLovers": "Può Uccidere gli Amanti", "SheriffCanKillMadmate": "Può Uccidere i Follenauti", "SheriffCanKillInfected": "Può Uccidere i giocatori Infettati", @@ -1540,15 +1507,12 @@ "RebirthUses": "Quantità di Rinascite", "RebirthCountVotes": "Rinascita solo in giocatori che lo hanno votato", "RebirthFailed": "Ahh, che sfortuna, non hai trovato nessuna anima vitale con cui scambiare i corpi", - "FireworkerCooldown": "Ricarica Piazzamento", "ReverieIncreaseKillCooldown": "Incrementa Ricarica Uccisione", "ReverieMaxKillCooldown": "Ricarica uccisione Massimo", "ReverieMisfireSuicide": "Cilecca raggiungendo la ricarica uccisione massima", "ReverieResetCooldownMeeting": "Ripristina ricarica uccisione dopo le riunioni", "ConvertedReverieKillAll": "Il Capriccioso convertito può uccidere chiunque senza ripercussioni", "VigilanteNotify": "Sei diventato la cosa che hai giurato di distruggere", - "DictatorChangeCommandToExpel": "Dittatore usa il comando per espellere invece di votare", - "DictatorExpelSelf": "ASPE ASPE ASPE MA CHE DIAVOLO il Bro vuole solo espellere se stesso", "DoctorTaskCompletedBatteryCharge": "Durata Batteria", "SnitchEnableTargetArrow": "Vede Freccia Verso il Bersaglio", "SnitchCanGetArrowColor": "Vede Frecce Colorate basate sui Colori della Squadra", @@ -1629,7 +1593,6 @@ "EvilTrackerTargetMode.OnceInGame": "Una volta a partita", "EvilTrackerTargetMode.EveryMeeting": "Ogni Riunione", "EvilTrackerTargetMode.Always": "Quando vuoi", - "ScavengerHasCustomDeathReason": "Abilita Causa Di Morte Personalizzata", "EvilHackerCanSeeDeadMark": "Può Vedere La Posizione dei Cadaveri", "EvilHackerCanSeeImpostorMark": "Può Vedere La Posizione degli Altri Impostori", "EvilHackerCanSeeKillFlash": "Può vedere il Flash Uccisione", @@ -1710,7 +1673,7 @@ "TicketsPerKill": "Aumento Numero Voti per Uccisione", "GangsterRecruitCooldown": "Ricarica Reclutamento", "GangsterRecruitLimit": "Limite Reclute", - "KamikazeMaxMarked": "Massimo di Bersagli", + "KamikazeMaxMarked": "Massimo di Marcati", "RevolutionistDrawTime": "Durata del Marchio", "RevolutionistCooldown": "Ricarica del Marchio", "RevolutionistDrawCount": "Quantità di Giocatori necessari da Taggare", @@ -1778,16 +1741,16 @@ "RandomActiveRoles": "Mostra ruoli attivi casuali nei suggerimenti del Chiromante", "CamouflageCooldown": "Ricarica Camuffamento", "CamouflageDuration": "Durata del Camuffamento", - "NinjaMarkCooldown": "Ricarica Contrassegno", + "NinjaMarkCooldown": "Ricarica Marca", "NinjaAssassinateCooldown": "Ricarica Assassinio", - "NinjaModeDouble": "Doppio Clic = Uccidi, Clic Singolo = Segna", + "NinjaModeDouble": "Doppio Clic = Uccidi, Clic Singolo = Marca", "JudgeCanTrialnCrewKilling": "Può processare gli Astronauti Uccisori", "JudgeCanTrialNeutralB": "Può processare i Neutrali Benigni", "JudgeCanTrialNeutralK": "Può processare i Neutrali Assassini", "JudgeCanTrialNeutralE": "Può processare i Neutrali Maligni", "JudgeCanTrialNeutralC": "Può processare i Neutrali Caotici", "JudgeCanTrialNeutralA": "Può processare i Neutrali dell'Apocalisse", - "JudgeCanTrialSidekick": "Può processare le Spalle", + "JudgeCanTrialSidekick": "Può processare gli Aiutanti", "JudgeCanTrialInfected": "Può processare gli Infetti", "JudgeCanTrialContagious": "Può processare i Contagiosi", "JudgeTryHideMsg": "Nascondi il comando del Giudice", @@ -1855,28 +1818,20 @@ "JackalCanWinBySabotageWhenNoImpAlive": "Quando tutti gli Impostori sono morti, lo Sciacallo vince invece con il sabotaggio", "JackalResetKillCooldownWhenPlayerGetKilled": "Azzera ricarica uccisione se qualcuno viene ucciso da un altro giocatore", "JackalResetKillCooldownOn": "Ricarica Uccisione al Ripristino", - "JackalCanRecruitSidekick": "Può reclutare Spalle", - "JackalSidekickRecruitLimit": "Numero Massimo Di Reclutamenti", - "Jackal_SidekickCountMode": "Le Spalle contano come", + "JackalCanRecruitSidekick": "Può reclutare Aiutanti", + "JackalSidekickRecruitLimit": "Numero massimo di Reclute", + "Jackal_SidekickCountMode": "Gli Aiutanti contano come", "Jackal_SidekickCountMode_None": "Nulla", "Jackal_SidekickCountMode_Jackal": "Sciacallo", "Jackal_SidekickCountMode_Original": "Squadra Originale", - "Jackal_SidekickAssignMode": "Modalità Assegnazione Spalle", - "Jackal_SidekickAssignMode_SidekickAndRecruit": "Sidekick when failed Recruit", - "Jackal_SidekickAssignMode_Sidekick": "Solo Spalla", + "Jackal_SidekickAssignMode": "Modalità Assegnazione Aiutante", + "Jackal_SidekickAssignMode_SidekickAndRecruit": "Aiutante+Recluta", + "Jackal_SidekickAssignMode_Sidekick": "Solo Aiutante", "Jackal_SidekickAssignMode_Recruit": "Solo Recluta", - "Jackal_SidekickCanKillSidekick": "Le Spalle possono uccidere altre Spalle", - "Jackal_SidekickCanKillJackal": "Spalla può uccidere Sciacallo", - "Jackal_RecruitFailed": "Non puoi reclutare questo giocatore!", - "JackalCanKillSidekick": "Lo Sciacallo può uccidere la Spalla", - "Jackal_SidekickCanKillWhenJackalAlive": "Spalla può uccidere quando Sciacallo è vivo", - "Jackal_SidekickTurnIntoJackal": "Spalla può trasformarsi in Sciacallo dopo la sua morte", - "Jackal_RestoreLimitOnNewJackal": "Ripristina il limite di Reclutamento quando Spalla diventa nuovo Sciacallo", - "Jackal_OnBecomeNewJackalMeeting": "Il vecchio Sciacallo {0} è morto.\nSei stato selezionato come nuovo Sciacallo\nLavorate insieme e vinci la partita!", - "Jackal_OnNewJackalSelectedMeeting": "Il vecchio Sciacallo {0} è morto.\n{1} è selezionato come nuovo Sciacallo!\nLavorate insieme e vinci la partita!", - "Jackal_BecomeNewJackal": "Vecchio Sciacallo Morto, Ora sei il nuovo Sciacallo!", - "Jackal_OnNewJackalSelected": "Vecchio sciacallo morto, per favore aiuta il nuovo sciacallo {0} per ora!", - "Jackal_BossIsDead": "Ops, il capo Sciacallo è morto!", + "JackalWinWithSidekick": "Lo Sciacallo può vincere con il team dell' Aiutante", + "Jackal_SidekickCanKillSidekick": "Gli Aiutanti possono uccidere altri Aiutanti", + "Jackal_SidekickCanKillJackal": "Aiutante può uccidere Sciacallo", + "JackalCanKillSidekick": "Lo Sciacallo può uccidere l'Aiutante", "CoronerArrowsPointingToDeadBody": "Ha frecce che puntano sui cadaveri", "CoronerLeaveDeadBodyUnreportable": "I corpi che il Medico Legale utilizza non sono segnalabili", "CoronerInformKillerBeingTracked": "Informa all'assassino di essere localizzato", @@ -1914,9 +1869,6 @@ "VipTag": "VIP★", "ApplyVipList": "Applica Lista VIP", "AllowSayCommand": "Permetti ai moderatori di usare il comando /say", - "AllowStartCommand": "Permetti ai moderatori di usare il comando /start", - "StartCommandMinCountdown": "Conto alla rovescia minimo per il comando /start", - "StartCommandMaxCountdown": "Conto alla rovescia massimo per il comando /start", "KickCommandDisabled": "Il comando per cacciare è attualmente disabilitato.", "KickCommandNoAccess": "Non hai accesso al comando per cacciare.", "KickCommandInvalidID": "ID giocatore specificato non valido.\nPer favore usa '/kick [playerID] [reason]' per cacciare un giocatore.\nEsempio:- /kick 5 not following rules", @@ -1949,11 +1901,6 @@ "WarnCommandNoAccess": "Non hai accesso al comando per gli avvertimenti.", "WarnCommandInvalidID": "ID giocatore specificato non valido.\nPer favore usa '/warn [playerID] [reason]' per avvertire un giocatore. \nEsempio:- /warn 5 lava chatting", "WarnCommandWarnHost": "Non sei permesso ad avvertire l'host.", - "StartCommandNoAccess": "Non hai accesso al comando start.", - "StartCommandDisabled": "Il comando start è attualmente disabilitato.", - "StartCommandCountdown": "ERRORE\n\nIl gioco sta già iniziando!", - "StartCommandStarted": "La partita è stata avviata da {0}!", - "StartCommandInvalidCountdown": "ERRORE\n\nIl conto alla rovescia deve essere tra {0} e {1}!", "WarnCommandWarnMod": "Non sei permesso ad avvertire gli altri moderatori.", "WarnCommandWarned": "è stato avvertito. Non verranno più forniti avvisi e verranno intraprese le azioni appropriate \n ", "WarnExample": "Usa /warn [id] [reason] in futuro. \nEsempio :-\n /warn 5 lava chatting", @@ -1981,7 +1928,6 @@ "DeathReason.Quantization": "Quantizzazione", "DeathReason.Overtired": "Esausto", "DeathReason.Ashamed": "Imbarazzato", - "DeathReason.Consumed": "Consumato", "DeathReason.PissedOff": "Distrutto", "DeathReason.Dismembered": "Smembrato", "DeathReason.LossOfHead": "Strangolato", @@ -2005,8 +1951,6 @@ "DeathReason.Starved": "Affamato", "DeathReason.Equilibrium": "Equilibrio", "DeathReason.Sacrificed": "Sacrificato", - "DeathReason.Electrocuted": "Elettrificato", - "DeathReason.Scavenged": "Spazzato", "OnlyEnabledDeathReasons": "Solo Cause di Morte Attive", "Alive": "Vivo", "Disconnected": "Disconnesso", @@ -2071,8 +2015,7 @@ "Command.qq": "→ La lobby sarà pubblicata sul sito web di QQ (solo Cina)", "Command.dump": "→ Registro di Produzione sul Desktop", "Command.death": "→ Mostra informazioni su come sei morto", - "Command.icons": "
╳ - Il Giocatore è stato contrassegnato dal Ricattatore e non può parlare durante la riunione
☆ - Utilizzato dal Capitano per mettersi in mostra. Solo gli Astronauti possono vedere la stella del Capitano
乂 - Questo giocatore è stato stregato dal Fattuchiere e morirà se il Fattuchiere non verrà ucciso o espulso entro la fine della riunione.
♦ - Utilizzato da Avvocato o Esecutore o Seguace.
♥ - Utilizzato da Amanti o Romantico.
✚ - Utilizzato da Medico per contrassegnare il bersaglio.
⦿ - Questo giocatore è in un duello con il Pirata.
!? - Questo giocatore è stato contrassegnato dal Maestro dei Quiz e deve rispondere correttamente alla domanda per sopravvivere.
☜ - Utilizzato dal Gatto di Schrödinger per contrassegnare il compagno di squadra.
◈ - Questo giocatore è stato contrassegnato dalla Sindone e morirà se la Sindone non verrà uccisa o espulsa entro la fine della Riunione.
⚠ - Questo giocatore è un'Informatore o un Impiegato che ha completato i propri incarichi.
★ - Utilizzato da Super Star o Cyber o Maresciallo.
† - Questo giocatore è stato incantato e morirà se la Strega non verrà uccisa entro la fine della riunione.
∇ - Utilizzato dai Kamikaze per contrassegnare i propri bersagli.
■ - Utilizzato dal Fulmine per contrassegnare i propri fantasmi quantici.
⊠ - Utilizzato dal Carceriere per contrassegnare i propri prigionieri.
● - Utilizzato dal Fornaio per contrassegnare chi ha il pane.
♠ - Utilizzato dal Collezionista di Anime per marcare la morte di chi sta prevedendo.
⦿ - Utilizzato dall'Untore per contrassegnare chi ha afflitto.", - "Command.start": "[Secondi] → Inizia il gioco", + "Command.icons": "
╳ - Il Giocatore è stato marcato dal Ricattatore e non può parlare durante la riunione
☆ - Utilizzato dal Capitano per mettersi in mostra. Solo gli Astronauti possono vedere la stella del Capitano
乂 - Questo giocatore è stato stregato dal Fattuchiere e morirà se il Fattuchiere non verrà ucciso o espulso entro la fine della riunione.
♦ - Utilizzato da Avvocato o Esecutore o Seguace.
♥ - Utilizzato da Amanti o Romantico.
✚ - Utilizzato da Medico per marcare il bersaglio.
⦿ - Questo giocatore è in un duello con il Pirata.
!? - Questo giocatore è stato marcato dal Maestro dei Quiz e deve rispondere correttamente alla domanda per sopravvivere.
☜ - Utilizzato dal Gatto di Schrödinger per marcare il compagno di squadra.
◈ - Questo giocatore è stato marcato dalla Sindone e morirà se la Sindone non verrà uccisa o espulsa entro la fine della Riunione.
⚠ - Questo giocatore è un'Informatore o un Impiegato che ha completato i propri incarichi.
★ - Utilizzato da Super Star o Cyber o Maresciallo.
† - Questo giocatore è stato incantato e morirà se la Strega non verrà uccisa entro la fine della riunione.
∇ - Utilizzato dai Kamikaze per marcare i propri bersagli.
■ - Utilizzato dal Fulmine per marcare i propri fantasmi quantici.
⊠ - Utilizzato dal Carceriere per marcare i propri prigionieri.
● - Utilizzato dal Fornaio per marcare chi ha il pane.
♠ - Utilizzato dal Collezionista di Anime per marcare la morte di chi sta prevedendo.
⦿ - Utilizzato dall'Untore per marcare chi ha afflitto.", "Command.iconinfo": "→ Mostra informazioni sulle icone nei meeting", "Command.iconhelp": "→ Mostra informazioni sulle icone nei meeting a tutti", "Command.Poll": "→ Avvia un sondaggio con un massimo di 5 scelte", @@ -2085,7 +2028,6 @@ "ShowMadmatesInLeftCommand": "Mostra Follenauti (Inclusi modificatori)", "ShowApocalypseInLeftCommand": "Mostra Neutrali dell'Apocalisse", "SeeEjectedRolesInMeeting": "Vedi i ruoli degli espulsi", - "ThankYouForUsingTOHE": "Grazie per aver usato TOHE!", "SkillUsedLeft": "Hai attivato la tua abilità per convocare una riunione. \nQuantità rimanente di usi rimasti:", "NemesisDeadMsg": "La morte della Nemesi significa l'inizio della vendetta. \nPer favore usa /rv + [ID giocatore] per uccidere quel specifico giocatore \nPuoi vedere gli ID dei giocatori di fronte ai loro nomi. \nO scrivi /rv per avere gli ID dei giocatori", "NemesisAliveKill": "La vendetta per la Nemesi può iniziare solo dopo la loro morte.", @@ -2105,7 +2047,6 @@ "GuessNotifiedBait": "L'Esca non può essere indovinata perché è stata annunciata. Pensavi che sarebbe stato così facile, vero?", "GuessGM": "Indovinare il GM è impossibile perché è già morto.... E perché vorresti fare questo al povero Host?", "GuessGuardianTask": "Non puoi indovinare un Guardiano che ha finito i suoi incarichi.", - "GuardianCantKilled": "Non puoi uccidere un Guardiano che ha finito i suoi incarichi.", "GuessMarshallTask": "Non puoi indovinare un Maresciallo che ha finito i suoi incarichi.", "GuessObviousAddon": "Spiacenti, i modificatori ovvi non possono essere indovinati.", "GuessAdtRole": "Sfortunatamente, le impostazioni dell'host non ti permettono d'indovinare i modificatori", @@ -2161,13 +2102,12 @@ "BecomeMadmateCuzMadmateMode": "Sei diventato un Follenauta perché sei morto", "CleanerCleanBody": "Il corpo è stato ripulito", "QuickShooterStoraging": "Proiettili riservati con successo", - "QuickShooterFailed": "Stai ancora ricaricando.", "PoisonerTargetDead": "L'obiettivo è morto", "HexesLookLikeSpells": "I malefici appaiono come incantesimi", "HexButtonText": "Maleficio", "BloodthirstAdded": "La tua sete di sangue è ora attiva!", "WarlockNoTarget": "Manipolazione fallita non c'e un bersaglio", - "WarlockNoTargetYet": "Non hai segnato un bersaglio.", + "WarlockNoTargetYet": "Non hai marcato un bersaglio.", "WarlockTargetDead": "Manipolazione fallita a causa del bersaglio morto", "WarlockControlKill": "L'obiettivo è morto", "OnCelebrityDead": "Attenzione: Celebrità morta!", @@ -2220,7 +2160,7 @@ "PacifistOnGuard": "Abilità usata, {0} usi rimasti", "PacifistSkillNotify": "Il Pacifista ha azzerato la tua ricarica uccisione", "BeRecruitedByJackal": "Lo Sciacallo ti ha reclutato", - "YinYangerAlreadyMarked": "{0} è già in uno stato di calma, grazie a un compagno YinYanger", + "YinYangerAlreadyMarked": "{0} è già in uno stato di calma, dotato di un compagno YinYanger", "CoronerTrackRecorded": "Rintracciamento registrato", "CoronerNoTrack": "Niente da rintracciare", "CoronerIsTrackingYou": "Il Medico Legale ti sta rintracciando!", @@ -2320,7 +2260,6 @@ "Message.YTPlanNotice": "Nota che: Il [Piano dello YouTuber] è attivato in questa lobby, ciò vuol dire che l'host può specificare il suo ruolo la prossima partita per rendere più facile ottenere il contenuto. Se l'host abusa di questa funzionalità, esci dal gioco o segnalalo.\nCredenziali dell'attuale Creatore:", "Message.OnlyCanBeUsedByHost": "ERRORE\n\nQuesto comando può essere usato solo dall'host.", "Message.MaxPlayers": "Numero massimo di giocatori impostato a ", - "Message.MaxPlayersFailByRegion": "Impossibile impostare un massimo di giocatori: Le regioni vanilla supportano un massimo di 15 giocatori.", "Message.GhostRoleInfo": "Informazioni sui ruoli fantasma\nEhilà! Riguardante ai ruoli fantasma...\n\nI ruoli fantasma hanno un impatto drastico sul gioco, quindi non sono consigliati per lobby più piccole se non hai familiarità. Se non diversamente specificato nella descrizione, il pulsante Proteggi è il pulsante della loro abilità ;)\n\nGenerazione:\nI ruoli fantasma si generano solo dopo la morte; le prime x persone di (squadra) a morire li ottengono.\n\nPS: se il tuo ruolo precedente non aveva incarichi (ad esempio., sceriffo), i tuoi incarichi come ruolo fantasma non sono necessari per vincere di incarichi", "ApocalypseInfoTitle": "Informazioni Neutrali dell'Apocalisse:", "Message.ApocalypseInfo": "Ogni ruolo del team Apocalisse ha un proprio obiettivo da raggiungere per trasformarsi.\n\nI membri dell'Apocalisse Trasformati hanno un drastico cambiamento nel gioco e sono immortali (tranne per essere stati votati), ma tutti saranno avvisati della loro trasformazione.\n\nRuoli: Untore, Collezionista di anime, Fornaio, Berserker\nTrasformati: Pestilenza, Morte, Carestia, Guerra\n\nI membri dell'Apocalisse possono vedere i ruoli e le icone delle abilità degli altri.\nCome gli Assassini Neutrali, anche i membri dell'Apocalisse continuano a far andare avanti il ​​gioco, divertitevi!", @@ -2512,7 +2451,7 @@ "MercenarySuicideButtonText": "Timer Suicidio", "WarlockCurseButtonText": "Maledici", "NinjaShapeshiftText": "Uccidi", - "NinjaMarkButtonText": "Segna", + "NinjaMarkButtonText": "Marca", "WitchSpellButtonText": "Incantesimo", "VampireBiteButtonText": "Mordi", "MinerTeleButtonText": "Teletrasporto", @@ -2550,7 +2489,7 @@ "GrenadierVentButtonText": "Flash", "MayorVentButtonText": "Pulsante", "SheriffKillButtonText": "Spara", - "UndertakerButtonText": "Segna", + "UndertakerButtonText": "Marca", "ArsonistVentButtonText": "Dai Fuoco", "RevolutionistVentButtonText": "Rivoluzione", "FollowerKillButtonText": "Segui", @@ -2725,9 +2664,8 @@ "DeathMeetingTimeIncrease": "Tempo di riunione aumentato quando esiste la Morte", "SoulCollectorMeetingDeath": "Il tuo bersaglio è morto durante la riunione. Hai guadagnato un'anima.", "SoulCollectorKillButtonText": "Predici", - "SoulCollectorHasImpostorVision": "Collezionista di Anime ha il campo visivo impostore", "ApocalypseIsNigh": "[ L'Apocalisse è vicina! ]", - "ApocalypseImmune": "Questo ruolo è immune!", + "ApocalypseImmune": "Questo giocatore è immune perché è invincibile!", "BakerToFamine": "Sei diventato Carestia!!!", "BakerTransform": "Il Fornaio si è trasformato in Carestia, Cavaliere dell'Apocalisse! Una carestia è iniziata!", "BakerAlreadyBreaded": "Quel giocatore ha già il pane!", @@ -2736,15 +2674,13 @@ "BakerBreadNeededToTransform": "Numero di pane necessario per diventare Carestia", "BakerCantBreadApoc": "Non puoi dare pane agli altri membri dell'Apocalisse!", "BakerKillButtonText": "Pane", - "BakerUnshiftButtonText": "Cambia Pane", "BakerRevealBread": "Rivela", "BakerRoleblockBread": "Bloccaruolo", "BakerBarrierBread": "Barriera", "BakerCurrentBread": "Pane Attuale: ", "BakerSwitchBread": "Pane Cambiato in: ", - "BakerCanVent": "Fornaio può usare i condotti", + "BakerCanVent": "Fornaio può usare i condotti", "BakerBreadGivesEffects": "Il pane dà effetti aggiuntivi", - "BakerTransformNoMoreBread": "Il fornaio si trasforma se non ha abbastanza pane", "FamineKillButtonText": "Affamare", "FamineStarveCooldown": "Carestia ricarica affamare", "FamineCantStarveApoc": "Non puoi affamare gli altri membri dell'Apocalisse!", @@ -2791,7 +2727,6 @@ "GodfatherTargetCountMode": "L'assassino si trasforma in", "GodfatherCount_Refugee": "Profugo", "GodfatherCount_Madmate": "Follenauta", - "GodfatherRefugeeMsg": "Sei stato reclutato dal Padrino!", "MissChance": "Possibilità di mancare", "IncreaseByOneIfConvert": "Aumenta il ConteggioUccisioni +1 se un astronauta è stato convertito", "HawkMissed": "Mancato!", @@ -2824,7 +2759,6 @@ "BerserkerToWar": "Sei diventato Guerra!!!", "BerserkerTransform": "Il Berserker si è trasformato in Guerra, Cavaliere dell'Apocalisse! Grida \"Devastazione!\" e scatena i cani da guerra.", "WarKillCooldown": "Guerra ricarica uccisione", - "BerserkerCanKillTeamate": "Può uccidere altri Neutrali Dell'Apocalisse", "BlackmailerSkillCooldown": "Ricarica Ricatto", "BlackmailerMax": "Massimo di volte in cui i giocatori ricattati possono parlare", "BlackmailerDead": "Attenzione! {0} è stato ricattato da un Ricattatore!", @@ -2914,8 +2848,6 @@ "RememberedPursuer": "Ti sei ricordato che eri un Persecutore!", "RememberedFollower": "Ti sei ricordato che eri un Seguace!", "RememberedAmnesiac": "Hai fallito di ricordare il tuo ruolo.", - "AmnesiacRemembered": "Ti sei ricordato che eri {0}!", - "ReportWhenFailedRemember": "Segnala Cadavere quando non è riuscito a ricordare", "RememberedImitator": "Ti sei ricordato che eri un Imitatore.", "RememberedImpostor": "Ti sei ricordato che eri un Impostore!", "RememberedCrewmate": "Ti sei ricordato che eri un Astronauta!", @@ -3284,11 +3216,11 @@ "GhastlyYouvePosses": "Sei Stato Posseduto!", "GhastlyPossessedUser": "Hai posseduto: {0}", "GhastlyExpired": "{0} non è più posseduto", - "TasksMarkPerRound": "Numero d'incarichi che possono essere contrassegnati in un round", + "TasksMarkPerRound": "Numero d'incarichi che possono essere marcati in un round", "TaskinatorBombPlanted": "La Bomba è stata piazzata", "ShieldDuration": "Durata Scudo", "ShieldIsOneTimeUse": "Lo scudo si rompe dopo un tentativo di uccisione", - "BenefactorTaskMarked": "Incarico segnato con successo", + "BenefactorTaskMarked": "Incarico marcato con successo", "BenefactorTargetGotShield": "Hai avuto uno scudo dal Benefattore", "PirateTryHideMsg": "Nascondi il comando del Pirata", "SuccessfulDuelsToWin": "Numero di duelli vinti necessari per vincere", @@ -3323,18 +3255,15 @@ "SeekerKillButtonText": "Tagga", "PixiePointsToWin": "Numero di punti necessari per vincere", "MaxTargets": "Massimo numero di bersagli per round", - "MarkCooldown": "Ricarica Segna", + "MarkCooldown": "Ricarica Marca", "PixieSuicide": "Il Folletto si suicida se il bersaglio non viene espulso", "PixieMaxTargetReached": "Hai già selezionato tutti i bersagli per questo round", "PixieTargetAlreadySelected": "Il Bersaglio è già stato selezionato", - "PixieButtonText": "Segna", + "PixieButtonText": "Marca", "PlagueBearerCooldown": "Ricarica Infetta", - "PlagueBearerCanVent": "Può usare i condotti", - "PlagueBearerHasImpostorVision": "Ha il campo visivo impostore", "PestilenceCooldown": "Ricarica uccisione della Pestilenza", "PestilenceCanVent": "La Pestilenza può usare i condotti", "PestilenceHasImpostorVision": "La Pestilenza Ha il campo visivo Impostore", - "PestilenceKillGuessers": "Uccidi i giocatori che indovinano Pestilenza", "PlagueBearerAlreadyPlagued": "Il Giocatore è stato già Infettato", "PlagueBearerToPestilence": "Ti sei trasformato in Pestilenza!!", "GuessPestilence": "Hai appena provato a indovinare la Pestilenza!\n\nSpiacenti, la Pestilenza ti ha ucciso.", @@ -3378,7 +3307,6 @@ "EveryoneCanKnowMini": "Tutti possono vedere il Mini", "CanBeEvil": "Il Mini può essere un Impostore", "EvilMiniSpawnChances": "Probabilità che il Mini sia un Impostore", - "EvilMiniCanBeGuessed": "Mini Malvagio può essere indovinato prima dei 18", "GuessMini": "Spiacenti, non puoi fare del male a un Mini bambino.", "GrowUpDuration": "Tempo richiesto per crescere (s)", "MajorCooldown": "Ricarica Uccisione quando sopra 18 anni", @@ -3389,7 +3317,7 @@ "CantBoom": "Non puoi esplodere con un Mini che non è ancora cresciuto.", "CantRecruit": "Non puoi reclutare un Mini che non è ancora cresciuto.", "CantDuel": "Non puoi duellare un Mini che non è ancora cresciuto.", - "CantMark": "Non puoi segnare un Mini che non è ancora cresciuto.", + "CantMark": "Non puoi marcare un Mini che non è ancora cresciuto.", "CantBlood": "Non puoi Insanguinare un Mini che non è ancora cresciuto.", "CantPosses": "Non puoi possedere un Mini che non è ancora cresciuto.", "ExiledNiceMini": "È stato espulso un Mini Buono prima che crescesse.\nAvete perso tutti", @@ -3520,8 +3448,7 @@ "WinnerRoleText.Doppelganger": "Doppelganger Vince!", "WinnerRoleText.Quizmaster": "Maestro dei quiz Vince!", "WinnerRoleText.Agitater": "Agitatore Vince!", - "WinnerRoleText.Shocker": "Shocker Vince!", - "AdditionalWinnerRoleText.Sidekick": "Spalla", + "AdditionalWinnerRoleText.Sidekick": "Aiutante", "AdditionalWinnerRoleText.Taskinator": "Incaricator", "AdditionalWinnerRoleText.Opportunist": "Opportunista", "AdditionalWinnerRoleText.Lawyer": "Avvocato", @@ -3606,7 +3533,7 @@ "SolsticerOnMeeting": "Hai assistito a troppe morti! Nel prossimo round avrai altri {0} incarichi brevi!", "SolsticerTitle": "Impiegato", "GuessSolsticer": "Spiacenti, ma non puoi indovinare l'Impiegato!", - "ExpelSolsticer": "Spiacenti, ma non puoi espellere l'Impiegato!", + "VoteSolsticer": "Spiacenti, ma non puoi votare l'Impiegato!", "SolsticerTasksReset": "I tuoi incarichi sono ripristinati!", "SolsticerMisGuessed": "Hai semplicemente sbagliato a indovinare! Non ti è più consentito indovinare.", "SolsticerGuessMax": "Siccome hai già sbagliato a indovinare! Non ti è più permesso indovinare.", @@ -3618,18 +3545,18 @@ "dbConnect.nullFriendCode": "Questa versione di TOHE non è disponibile per gli utenti senza codice amico!", "Quizmaster": "Maestro dei quiz", "QuizmasterInfo": "Fai domande ai giocatori per ucciderli nelle riunioni", - "QuizmasterInfoLong": "(Neutrali):\nCome Maestro dei Quiz, puoi contrassegnare un giocatore utilizzando il pulsante uccidi. Nella riunione successiva, il giocatore contrassegnare avrà \"?!\" accanto al suo nome. Il giocatore morirà se risponderà male alla domanda o non risponderà. Il giocatore vivrà se il Maestro dei Quiz viene ucciso/espulso nella stessa riunione.\nIl Maestro dei Quiz non può contrassegnare più persone nello stesso turno", + "QuizmasterInfoLong": "(Neutrali):\nCome Maestro dei Quiz, puoi marcare un giocatore utilizzando il pulsante uccidi. Nella riunione successiva, il giocatore marcato avrà \"?!\" accanto al suo nome. Il giocatore morirà se risponderà male alla domanda o non risponderà. Il giocatore vivrà se il Maestro dei Quiz viene ucciso/espulso nella stessa riunione.\nIl Maestro dei Quiz non può marcare più persone nello stesso turno", "QuizmasterKillButtonText": "Quiz", - "QuizmasterChat.MarkedBy": "Sei stato contrassegnato dal Maestro dei Quiz\nPer sopravvivere devi rispondere correttamente a questa domanda:\n\n{QMQUESTION}", - "QuizmasterChat.MarkedPublic": "{QMTARGET} è stato contrassegnato dal Maestro dei Quiz\nPer sopravvivere {QMTARGET} deve rispondere correttamente alla loro domanda!", + "QuizmasterChat.MarkedBy": "Sei stato marcato dal Maestro dei Quiz\nPer sopravvivere devi rispondere correttamente a questa domanda:\n\n{QMQUESTION}", + "QuizmasterChat.MarkedPublic": "{QMTARGET} è stato marcato dal Maestro dei Quiz\nPer sopravvivere {QMTARGET} deve rispondere correttamente alla loro domanda!", "QuizmasterChat.Answers": "Risposte\nA:{QMA}\nB:{QMB}\nC:{QMC}\n\nPer rispondere basta digitare /answer [answer letter]\n\nSe hai bisogno di ricontrollare la risposta e le domande basta usare /qmquiz", "QuizmasterChat.CorrectTarget": "Corretto", - "QuizmasterChat.Correct": "{QMTARGET} ha dato la risposta giusta!\nOra puoi contrassegnare qualcun altro!", + "QuizmasterChat.Correct": "{QMTARGET} ha dato la risposta giusta!\nOra puoi marcare qualcun altro!", "QuizmasterChat.CorrectPublic": "{QMTARGET} ha risposto correttamente alla domanda del Maestro dei Quiz ed è sopravvissuto!\nAttenzione al Maestro dei Quiz!", "QuizmasterChat.WrongTarget": "Sbagliato\nLa tua risposta era {QMWRONG}\nLa risposta corretta era {QMRIGHT}\n\nIl Maestro dei Quiz era {QM}", - "QuizmasterChat.Wrong": "{QMTARGET} ha dato la risposta sbagliata ed è morto!\nOra puoi contrassegnare qualcun altro!", + "QuizmasterChat.Wrong": "{QMTARGET} ha dato la risposta sbagliata ed è morto!\nOra puoi marcare qualcun altro!", "QuizmasterChat.WrongPublic": "{QMTARGET} ha risposto erroneamente alla domanda del Maestro dei Quiz ed è morto!\nAttenzione al Maestro dei Quiz!", - "QuizmasterChat.Marked": "Hai contrassegnato {QMTARGET}\nse {QMTARGET} non risponde alla fine della riunione oppure risponde erroneamente {QMTARGET} morirà\n\nDomanda per {QMTARGET} => {QMQUESTION}", + "QuizmasterChat.Marked": "Hai marcato {QMTARGET}\nse {QMTARGET} non risponde alla fine della riunione oppure risponde erroneamente {QMTARGET} morirà\n\nDomanda per {QMTARGET} => {QMQUESTION}", "QuizmasterChat.Title": "Informazioni sul Maestro dei Quiz", "QuizmasterChat.CantAnswer": "Come Maestro dei Quiz, non puoi rispondere alle domande", "QuizmasterChat.AnswerNotValid": "La tua risposta deve essere A, B, o C", @@ -3707,28 +3634,6 @@ "MinionAbilityTime": "Durata Abilità", "Minion_Blind": "accecato", "Evader_ChanceNotExiled": "Possibilità di non essere espulso", - "ShockerAbilityCooldown": "Ricarica Abilità", - "ShockerAbilityDuration": "Durata Abilità", - "ShockerAbilityPerRound": "Abilità Per Round", - "ShockerShockInVents": "Elettrifica persone nei condotti", - "ShockerAbilityResetAfterMeeting": "Reimposta le stanze contrassegnate dopo la riunione", - "ShockerOutsideRadius": "Raggio d'incarichi esterni (non in una stanza)", - "ShockerCanShockHimself": "Può Elettrificare Stesso", - "ShockerImpostorVision": "Shocker ha il campo visivo impostore", - "ShockerIsShocking": "Stai già elettrificando!", - "ShockerAbilityActivate": "Comincia l'Elettrificazione!", - "ShockerAbilityDeactivate": "Abilità Disattivata", - "ShockerVentButtonText": "Scossa", - "ShockerRoomMarked": "Stanza Contrassegnata", "EavesdropperMsgTitle": "Hai trovato un segreto", - "EavesdropPercentChance": "Possibilità di origliare", - "ChiefOfPoliceSkillCooldown": "Ricarica per reclutare sceriffi", - "PolicCanImpostorAndNeutarl": "Puoi reclutare Impostori o Neutrali", - "SheriffSuccessfullyRecruited": "Hai reclutato uno Sceriffo.", - "BeSheriffByPolice": "Sei stato reclutato dal capo della polizia! Servi l'equipaggio!", - "PoliceFailedRecruit": "Impossibile reclutare il bersaglio.", - "ChiefOfPoliceKillButtonText": "Reclutamento", - "PolicPreventRecruitNonKiller": "Impedisci di reclutare giocatori senza pulsante uccidi", - "PolicSuidiceWhenTargetNotKiller": "Si suicida quando reclutano un non assassino o non astronauta", - "PolicPassConverted": "Puo passare Modificatore Convertito a Sceriffo" -} \ No newline at end of file + "EavesdropPercentChance": "Possibilità di origliare" +} diff --git a/Resources/Lang/ja_JP.json b/Resources/Lang/ja_JP.json index 92c50b3d4..d58788329 100644 --- a/Resources/Lang/ja_JP.json +++ b/Resources/Lang/ja_JP.json @@ -19,8 +19,6 @@ "SubText.Neutral": "勝利を達成するために一人で働く", "SubText.Apocalypse": "チームと共に止められない存在になろう", "SubText.Madmate": " インポスターを助ける", - "SubText.Lovers": "生き延びて一緒に勝利を掴もう", - "SubText.Egoist": "自分だけで勝利を目指せ", "TypeImpostor": "インポスター", "TypeCrewmate": "クルーメイト", "TypeNeutral": "ニュートラル", @@ -30,9 +28,6 @@ "TeamNeutral": "ニュートラル", "TeamCrewmate": "クルーメイト", "TeamMadmate": "マッドメイト", - "TeamLovers": "恋人たち", - "TeamEgoist": "エゴイスト", - "TeamApocalypse": "黙示録", "YouAreCrewmate": "あなたはクルーメイトです", "YouAreImpostor": "あなたはインポスターです", "YouAreNeutral": "あなたはニュートラルです", @@ -224,7 +219,6 @@ "TaskManager": "タスクマネージャー", "Witness": "証人", "Swapper": "スワッパー", - "ChiefOfPolice": "警察署長", "NiceMini": "ナイスミニ", "Mini": "ミニ", "Spy": "スパイ", @@ -253,7 +247,6 @@ "Stalker": "ストーカー", "Workaholic": "ワーカホリック", "Solsticer": "ソルスティス", - "Abyssbringer": "深淵をもたらす者", "Collector": "コレクター", "Provocateur": "プロヴォカトゥール", "BloodKnight": "血の騎士", @@ -315,7 +308,7 @@ "Ghastly": "ゴース", "LastImpostor": "最後のインポスター", "Overclocked": "オーバークロック", - "Lovers": "恋人たち", + "Lovers": "恋人", "Madmate": "マッドメイト", "Watcher": "見守り人", "Flash": "閃光", @@ -392,8 +385,6 @@ "Sloth": "怠け者", "Prohibited": "禁止された者", "Eavesdropper": "立ち聞き", - "Shocker": "ショッカー", - "Revenant": "レヴナント(亡霊)", "BracketAddons": "アドオンに括弧を追加", "EngineerTOHEInfo": "通気口を使って インポスター を捕まえる", "ScientistTOHEInfo": "どこからでも携帯用バイタルにアクセス", @@ -512,7 +503,6 @@ "PacifistInfo": "キルのクールダウンをリセットするために通気口を使用", "RebirthInfo": "再び蘇る", "MonarchInfo": "クルーに追加の投票権を与える!", - "AbyssbringerInfo": "ブラックホールを創造する", "SpurtInfo": "ウサギのように跳ねる!", "StealthInfo": "部屋の中の全員がキルで目が見えなくなる", "PenguinInfo": "犠牲者を引きずる", @@ -546,7 +536,6 @@ "WitnessInfo": "最近誰かが殺人を犯したかを突き止める", "GhastlyInfo": "誰かを支配して!", "SwapperInfo": "2人のプレイヤーの投票を入れ替える", - "ChiefOfPoliceInfo": "保安官を雇い、クルーを守らせよう!", "NiceMiniInfo": "成長するまで誰もあなたに害を与えることはできません。", "ArsonistInfo": "誰もを浸す、そして点火する", "PyromaniacInfo": "誰もを浸して、誰もを殺す", @@ -707,8 +696,6 @@ "SlothInfo": "あなたは遅くなっています", "ProhibitedInfo": "特定のベントが封鎖されています", "EavesdropperInfo": "他の役割を盗み聞きする", - "ShockerInfo": "不意を突いてプレイヤーを驚かせる", - "RevenantInfo": "キラーの役割を奪え", "EngineerTOHEInfoLong": "(クルーメイト):\nエンジニアとして、通信妨害が非アクティブの間はベントを使用できます。", "ScientistTOHEInfoLong": "(クルーメイト):\nサイエンティストとして、いつでもバイタルを見ることができ、誰が生きていて誰が死んでいるかを確認できます。", "NoisemakerTOHEInfoLong": "(クルーメイト):\nノイズメーカーとして、あなたが死ぬたびに音が鳴り、あなたの死のビジュアルインジケーターが画面に表示されます。これにより、クルーメイトはあなたを殺した人を現行犯で捕まえるために走ってくるでしょう (たとえその人が赤でなくても)。", @@ -780,14 +767,14 @@ "LurkerInfoLong": "(インポスター):\n潜伏者として、クールダウンを一定の秒数短縮するためにベントに入ることができます。キルした後、クールダウンは元の値にリセットされます。", "VisionaryInfoLong": "(インポスター):\nビジョナリーとして、会議中に生存プレイヤーの陣営を見ることができます。以下の情報がプレイヤーに表示されます:\n\n- 赤い名前はインポスターを示します。\n- シアンの名前はクルーメイトを示します。\n- グレーの名前はニュートラルを示します。", "PlagueDoctorInfoLong": "(中立):\n(TOHのペスト医師)\nペストドクターの目標は、生きているすべてのプレイヤーを感染させることです。\n彼らは最初に一人のプレイヤーを感染させることから始め、その後、感染したプレイヤーの範囲内で設定された時間を過ごした人は誰でも自身が感染します。\n感染の進行は累積的であり、距離が離れたり会議後でもリセットされません。", - "RefugeeInfoLong": "(マッドメイツ):\n難民として、あなたは次のいずれかでした:\n -インポスターを思い出した記憶喪失者\n -ゴッドファーザーのターゲットを殺した殺人者\n -パートナーがインポスターだったロマンティック\n -インポスターを模倣した模倣者\n\n今、あなたの役割はインポスターを助けてクルーメイトを排除することです。", + "RefugeeInfoLong": "(マッドメイツ):\n避難民として、あなたは記憶喪失者であり、偽装者を思い出したか、またはゴッドファーザーの標的を殺害した殺人者でした。\n今はあなたの仕事はインポスターがクルーメイトを殺すのを手伝うことです。", "UnderdogInfoLong": "(インポスター):\nアンダードッグとして、一定数のプレイヤーが生存するまでキルできません。", "ConsigliereInfoLong": "(インポスター):\nコンシリエーレとして、キルボタンを使用して他のプレイヤーの役割を明らかにすることができます。\n\n1回クリック:役割を明らかにする\n2回クリック:キル\n\n明らかにする回数が尽きた場合、キルボタンは通常通り機能します。", "LudopathInfoLong": "(インポスター):\nルードパスとして、キルのクールダウンはランダム化されます。\n\n最小値は1秒で、最大値はデフォルトのキルクールダウンです。", - "GodfatherInfoLong": "(インポスター):\nゴッドファーザーとして、誰かをターゲットにするために投票します。\n次のラウンドで、もしそのターゲットが誰かに殺された場合、殺した人物は難民またはマッドメイツに変わります。", + "GodfatherInfoLong": "(インポスター):\nゴッドファーザーとして、誰かを選んで彼らをあなたのターゲットにします。次のラウンドで誰かがそのターゲットをキルした場合、キラーは難民に変わります。", "ChronomancerInfoLong": "(インポスター):\n時間魔術師として、虐殺の準備が整うときに示すチャージバーがあります。それが100%になると、次に誰かをキルしたときに虐殺モードに入ります。これにより、チャージがなくなるまで無限にキルすることができます。そうでない場合、通常のキルクールダウンがあります。", "PitfallInfoLong": "(インポスター):\nピットフォールとして、シェイプシフトを使用してシェイプシフトの周りのエリアをトラップとしてマークします。このエリアに入るプレイヤーは一時的に動けなくなり、視界も影響を受けます。", - "EvilMiniInfoLong": "(インポスター):\nイービルミニとして(邪悪な子供)、成長するまで不死身で、非常に長い初期キルのクールダウンがあります。成長するにつれてクールダウンが大幅に短縮されます。", + "EvilMiniInfoLong": "(インポスター):\nイービルミニとして、成長するまで不死身で、非常に長い初期キルのクールダウンがあります。成長するにつれてクールダウンが大幅に短縮されます。", "BlackmailerInfoLong": "(インポスター):\n恐喝者として、ターゲットに変身するとそのプレイヤーを脅迫します。これは、会議中にそのプレイヤーが話せなくなることを意味します。\n\n注意: すでに誰かが脅迫されている場合、別の人を脅迫すると現在の脅迫が解除されます。", "InstigatorInfoLong": "(インポスター):\n煽動者として、あなたの役割はクルーメイト同士を対立させることです。会議でクルーメイトが投票によって追放されるたびに、あなたが生きている限り、無実のプレイヤーに投票した追加のクルーメイトが会議後に死亡します。追加で死亡するプレイヤーの数はホストが決定します。", "LazyGuyInfoLong": "(クルーメイト):\n怠け者は1つのタスクしか持っていません。さらに、インポスターの能力は怠け者に影響を与えません。例えば、アノニマスのスケープゴートになること、ウォーロックやパペティアーによってマークされることなどはできません。怠け者にはアドオンはありません。", @@ -856,7 +843,6 @@ "TaskManagerInfoLong": "(クルーメイト):\nあなたの役職名の横に、すべての人が合わせて完了したタスク(の総数が表示され)、リアルタイムで更新されます。", "WitnessInfoLong": "(クルーメイト):\n証人として、誰かにキルボタンを使用すると、彼らが過去X秒以内にキルしたかどうかを知ることができます (Xは設定に依存します) 。", "SwapperInfoLong": "(クルーメイト):\nスワッパーとして、会議での投票を交換できます。\n\n投票を交換するには、'/sw [playerID]' を2回使用します。\n\nプレイヤーのIDは会議でプレイヤー名の横に表示されますが、/idを使用してすべてのプレイヤーIDのリストを取得することもできます。\n\n注意:自分自身を交換することはできません", - "ChiefOfPoliceInfoLong": "(クルーメイト):\n剣を持つプレイヤーは、保安官チームにリクルートされ、クルーのために働くことができます。\n注意:リクルートのチャンスは一度だけです。\n設定によっては、非殺人者または非クルーをリクルートできる場合があります。\n誤ったターゲットをリクルートすると、自殺する可能性があります。", "NiceMiniInfoLong": "(クルーメイト):\nナイスミニとして、あなたの生存は非常に重要です。成長するまでは殺されることはなく、成長する前に死んだり会議で追放されたりすると、全員が負けます。このユニークな役割は、あなたの生存が自分自身だけでなく、クルー全体の成功に繋がるという新たなダイナミクスをゲームにもたらします。", "SpyInfoLong": "(クルーメイト):\nスパイとして、誰かがキルボタンを使用して (キルボタンを介して使用されるすべてのアビリティ) 、あなたは数秒間その名前がオレンジ色で表示されます。\n注意:クルーメイトがあなたにアビリティを使用した場合、彼らもオレンジ色の名前で表示されます!\n注意:アビリティの使用回数が残っていない場合、オレンジ色の名前は一切表示されません!\n注意:キルボタンの相互作用がブロックされた場合、プレイヤーのクールダウンは10秒にリセットされます。", "RandomizerInfoLong": "(クルーメイト):\nこのランダマイザーとして、死亡時にあなたの殺害者は以下のいずれかの行動を行います:\n 1. あなたの遺体を自己報告します。\n 2. あなたの遺体の隣に立ちます。\n 3. 彼らのキルクールダウンが600秒に設定されます。\n 4. ランダムにプレイヤーを復讐します。", @@ -871,7 +857,7 @@ "LawyerInfoLong": "(中立):\n弁護士は守るべき対象がおり、その対象は名前の横にダイヤモンド「♦」で表示されます。\n対象が勝利すれば、あなたも勝利します。\n彼らが負けると、あなたも負けます。", "OpportunistInfoLong": "(中立):\nもしオポチュニストがゲームの最後まで生き残れば、オポチュニストは勝利したプレイヤーと共に勝利します。", "VectorInfoLong": "(中立):\nマリオは一定回数吐き出すと単独で勝利します。", - "JackalInfoLong": "(中立):\nジャッカルとして、最後の生存者になれば勝利します。さらに、殺害ボタンを使ってリクルートすることが可能です。\nただし、ターゲットがリクルート不可能な場合、使用回数を使い果たしている場合、またはリクルートオプションがない場合は、通常通りに殺害します(リクルートできると思って他人の前で殺害ボタンを押さないでください) 。\nターゲットが殺害ボタンを持ち、サイドキックに変わるオプションがオンの場合、ターゲットはサイドキックになります。それ以外の場合、リクルートアドオンを与えるオプションがオンなら、ターゲットはリクルートアドオンを獲得します。\n設定によっては、ジャッカルが殺された場合、ランダムにサイドキックが新たなジャッカルとして選ばれます。サイドキックがいない場合、リクルートが選ばれる場合があります。", + "JackalInfoLong": "(中立):\nジャッカルとして、最後の生存者になると勝利します。さらに、殺害ボタンを使用してリクルートすることができます。ターゲットがリクルート可能ではない場合、リクルートの使用回数を使い果たしている場合、またはリクルートオプションがない場合は、通常通りに殺害します (つまり、リクルートすると思って他人の前で殺害ボタンを使用しないでください)。ターゲットに殺害ボタンがあり、サイドキックに変わるオプションがオンの場合は、サイドキックになります。それ以外の場合は、リクルートアドオンを与えるオプションがオンの場合はリクルートアドオンを獲得します。", "GodInfoLong": "(中立):\n神として、最初から全員の役割を知っています。ゲームの最後まで生き残れば、勝利を手に入れます。つまり、他の全員が負けてあなたが勝ちます。", "InnocentInfoLong": "(中立):\nイノセントはキルボタンを使用して任意のプレイヤーを植え付けることができ、植え付けられた対象は即座にイノセントを殺害します。対象が会議で投票により追放されると、イノセントが勝利します。注:道化師、執行者、およびイノセントは一緒に勝利することができます。", "PelicanInfoLong": "(中立):\nペリカンとして、キルボタンを使用してプレイヤーを生きたまま飲み込み、マップ外にテレポートしますが、すぐには殺害しません。飲み込まれたプレイヤーは、ラウンドの終わりにあなたがまだ生きている場合のみ死亡します。ラウンド中に死亡したり離れたりすると、生存している飲み込まれたプレイヤーはあなたがいた場所にマップ内で再出現します。", @@ -883,7 +869,7 @@ "SolsticerInfoLong": "(中立):\nソルスティスとして、あなたは死ぬことはありません。一回のラウンドで全てのタスクを完了させることで勝利します。会議が終わるたびに、タスクはリセットされ、最初からやり直さなければなりません。\nソルスティスに対する投票は直接キャンセルされます。\nソルスティスに対する殺害試みは、会議が終了するまでペリカンのようにマップ外へテレポートさせます。\nキラーのキルクールダウンは10秒にリセットされます。", "CollectorInfoLong": "(中立):\nコレクターとして、プレイヤーに投票すると、そのプレイヤーに投票した他のプレイヤー1人につき1ポイントを獲得します。必要な投票数を集めると、ジェスターやエグゼキューショナーのターゲットを追放しても、ゲームが終了し、あなたは単独で勝利します。", "GlitchInfoLong": "(中立):\nグリッチとして、プレイヤーをハックする (シングルクリック) か通常通り殺害する (ダブルクリック) ことができます。ハックされたプレイヤーは、ハックの期間中、殺害、ベント、報告をすることができません。さらに、ドア以外の妨害を呼び出すと効果がなく、ランダムなプレイヤーに変装します。妨害中または後に変装することはできません。勝利するためには、最後の生存プレイヤーである必要があります。", - "SidekickInfoLong": "(中立):\nサイドキックとして、あなたの役割はジャッカルを助けて全員を排除することです。\nあなたとジャッカルは一緒に勝利します。\n設定によっては、元のジャッカルが殺された場合に新しいジャッカルになることがあります。\n元のジャッカルが死ぬまで、殺害ができない場合もあります。", + "SidekickInfoLong": "(中立):\nサイドキックとして、あなたの仕事はジャッカルが誰もを殺すのを手伝うことです。\n\nあなたとジャッカルは一緒に勝利します。", "ProvocateurInfoLong": "(中立):\nプロヴォケーターはキルボタンで任意のターゲットを殺すことができます。ゲームの最後にターゲットが負けると、プロヴォケーターは勝利チームと一緒に勝利します。", "BloodKnightInfoLong": "(中立):\n血の騎士は、最後のキル役が生き残り、クルーメイトの数がブラッドナイトの数以下または同じ場合に勝利します。ブラッドナイトは、各キルの後に一時的なシールドを獲得し、数秒間不死身になります", "PlagueBearerInfoLong": "(黙示録):\nプレイグベアラーとして、キルボタンを使用して誰もがペスティレンスに変身するために皆を感染させます。\nペスティレンスに変身したら、不死でキルの能力を獲得します。\nさらに、ペスティレンスに変身した後、あなたを殺そうとする誰もがあなたを殺します。\nまた、感染したプレイヤーが未感染のプレイヤーと接触すると、そのプレイヤーも感染します。", @@ -910,12 +896,11 @@ "TraitorInfoLong": "(中立):\n裏切り者として、私は詐欺師を裏切った詐欺師でした。\nあなたは詐欺師のことを知っていますが、彼らはあなたのことを知りません。\nでもトリック? 彼らはあなたを殺すことができますが、あなたは彼らを殺すことはできません。\n他の手段で詐欺師を排除し、他の全員を倒して勝利してください!", "TrollerInfoLong": "(中立):\nトローラーとして、タスクを完了させることで、プレイヤーにランダムなイベントを発生させることができます。例えば、全プレイヤーのスピードを変えたり、テレポートさせたり、サボタージュに影響を与えたりすることができます。また、勝利チームと共に勝利することができます。", "VultureInfoLong": "(中立):\nハゲタカとして、死体を通報して勝ちましょう!\n死体を報告すると、食べるクールダウンがリセットされていれば、その死体を食べることができるようになります (その後は報告できなくなります)。\n食べる能力がクールダウン中の場合は、通常どおり死体を報告します。\nまた、ラウンドあたりの食事の最大数に達した場合、死体は通常通り報告されます。", - "AbyssbringerInfoLong": "(インポスター):\n深淵をもたらす者として、ブラックホールを設置することができます。\nブラックホールはプレイヤーを吸い込み、接触すると殺害します。", "TaskinatorInfoLong": "(中立):\nタスキネーターとして、タスクを完了するたびにそのタスクは爆弾を設置されます。別のプレイヤーが爆弾付きのタスクを完了した時、爆弾が爆発してそのプレイヤーは死亡します。\n\nクルーが勝利しない状況で最後まで生き残れば勝ちです。\n\n 注意:タスキネーターの爆弾はあらゆる保護を無視します。", "BenefactorInfoLong": "(クルーメイト):\n恩人として、タスクを完了すると、そのタスクはマークされます。別のプレイヤーがマークされたタスクを完了すると、一時的な盾が得られます。\n\n注:盾は直接の攻撃からのみ保護します。", "MedusaInfoLong": "(中立):\nメデューサとして、あなたは死体を石化することができます。あなたは死体を掃除するのと同じように死体を石化させます。石化した死体は報告できません。\n全員を倒して勝ちます。", "SpiritcallerInfoLong": "(中立):\n精霊召喚師として、あなたの犠牲者は死後、悪霊になります。これらの悪霊は、他のプレイヤーを一時的に凍らせたり、視界を遮ったりして攻撃することができます。また、殺人未遂からあなたを守る一時的な盾を与えることもできます。", - "AmnesiacInfoLong": "(中立):\n記憶喪失者として、リポートボタンを使用してターゲットを記憶し、その役割を引き継ぐことができます。\nゲームバランスを保つため、記憶した役割がベントを使用できない場合、記憶喪失者としてもベントを使用することはできません。", + "AmnesiacInfoLong": "(中立):\n記憶ボタンを使用して役職を思い出すアムネジアックとして行動します。\n対象がインポスターだった場合、難民になります。\n対象がクルーだった場合、互換性があれば対象の役職になります (それ以外の場合はエンジニアになります) 。\n対象が受動的な中立か特定されていない中立キラーだった場合、設定で定義された役職になります。\n対象が選ばれた中立キラーだった場合、彼らの役職になります。", "ImitatorInfoLong": "(中立): \n模倣者として、あなたのキルボタンを使用してプレイヤーを模倣してください。\n\nあなたはシェリフ、難民、またはいくつかのニュートラルになるでしょう。", "BanditInfoLong": "(中立):\n山賊として、キルボタンを1回クリックするとプレイヤーのアドオンを盗み、2回クリックするとキルが可能です。設定に応じて、アドオンは即座に盗むか、会議開始後に盗むかが決まります。最大の盗み回数に達した後は、通常通りキルが行われます。また、ターゲットに盗めるアドオンがない場合やターゲットが頑固な場合、ターゲットをキルします。\n\n全員を倒して勝ちます。\n\n注: 浄化されたプレイヤー、ラストインポスター、およびラヴァーズのアドオンは盗むことができません。\n注:「バンディットがベントを使える」が有効な場合、器用なプレイヤーから盗むのがより困難になります。", "DoppelgangerInfoLong": "(中立):\nドッペルゲンガーとして、キルボタンを使用してプレイヤーのアイデンティティ (名前とスキン) を奪い、ターゲットを殺します。\n\n全員を倒して勝ちます。\n\n注: 迷彩が有効な場合、ターゲットのアイデンティティを奪うことはできません。", @@ -936,7 +921,6 @@ "JinxInfoLong": "(中立):\nジンクスとして、攻撃されるたびに相手を呪い、呪いで相手を死に至らしめます。これには使用回数が限られています。全員を倒すと勝利します。", "PotionMasterInfoLong": "(中立):\nポーションマスターとして、あなたは 3 つのポーションを持っており、彼は 3 つの異なるアクションに割り当てます。\nシングルクリック: プレーヤーの役割を表示\nダブルクリック: プレイヤーをキルします\nマップ: サボタージュ\nショープレイヤーの役割ポーションには制限があります。 ポーションが完成すると、キルボタンはデフォルトでキルに切り替わります。", "NecromancerInfoLong": "(中立):\nネクロマンサーとして、最後の生存者になることで勝利します。また、誰かがあなたを殺そうとした場合、その殺害はブロックされ、あなたはランダムな通気口にテレポートされます。キラーを倒すには時間制限があります。はい。 成功すれば生き残ります。殺す前に時間がなくなったら、永久に死にます。殺人者以外の誰かを殺そうとすると、あなたは死にます。", - "ShockerInfoLong": "(中立): \nショッカーとして、部屋でタスクを行うことでその部屋をマークすることができます。その後、ベントを使用して一定時間内にその部屋にいる人々を感電させることができます。\n全てのタスクを完了すると、新しいタスクが与えられます。\n注意:その期間中にタスクを行うと、次回の能力使用時にそのタスクがマークされます。", "LastImpostorInfoLong": "(アドオン):\nこの効果は最後に生き残った詐欺師に与えられます。キルのクールダウンが減少します。", "OverclockedInfoLong": "(アドオン):\nオーバークロックすると、キルのクールダウンが一定の割合で減少します。キル ボタンのあるロールにのみ適用されます。", "LoversInfoLong": "(アドオン):\nラバーズは2人のプレイヤーの組み合わせです。ラバーズは、ラバーズだけが残れば勝ちです。ラバーズのどちらかが勝つと、もう一方も一緒に勝ちます。ラバーズはお互いの名前の横に「♥」マークが表示されます。 恋人が死亡すると、恋人が勝ち、もう一方は恋に死ぬ (ホストの設定によっては恋に落ちない) ことになり、恋人のどちらかが会議で追放されると、もう一方は死んで報告できない死体となります。", @@ -980,7 +964,7 @@ "RebirthInfoLong": "(アドオン):\n再生として、あなたが追放される際、あなたに投票したランダムなクルーメイトとスキンを交換します。\n注意: ホストの投票はカウントされません。\n再生をすべて使い果たした場合、再生の能力は失われます。", "LoyalInfoLong": "(アドオン): \n忠実な役割として、あなたはジャッカルやカルトなどの役割に勧誘されません。中立役には割り当てられません。", "EvilSpiritInfoLong": "(アドオン):\n邪悪なスピリットとして、あなたの仕事はスピリットコーラーを勝利に導くことです。ハントボタンを使用してプレイヤーを凍結させ、視界を制限することができます。また、ハントボタンを使用してスピリットコーラーがキルの試みに対するシールドを一時的に得ることもできます。", - "RecruitInfoLong": "(裏切りアドオン):\nリクルートとして、あなたはジャッカルのチームに所属し、ジャッカルとそのサイドキックを支援します。\n元のチームと一緒に勝利することはできません。\n設定によっては、元のジャッカルが殺されてサイドキックがいない場合、新たなジャッカルになることがあります。", + "RecruitInfoLong": "(裏切りのアドオン):\nリクルートとして、あなたはジャッカルのチームに所属し、ジャッカルとそのサイドキックを支援します。\n元のチームでは勝てません。", "AdmiredInfoLong": "(裏切りのアドオン):\n賞賛されたプレイヤーとして、クルーと一緒に勝利し、元のチームでは勝利できません。\n\nファンを見ることができます。", "GlowInfoLong": "(アドオン):\n停電中、あなたと近くにいるプレイヤーは視界が広がります。", "RadarInfoLong": "(アドオン):\nレーダーとして、常に最も近くにいる人を指す矢印が表示されます。", @@ -1021,10 +1005,9 @@ "DollMasterInfoLong": "(インポスター):\nドールマスターとして、シェイプシフトボタンを使って任意のプレイヤーを一時的に操作し、あなたの行為を行わせることができます!", "DoubleAgentInfoLong": "(インポスター):\n二重スパイとして、キルボタンにはアクセスできません。しかし、会議で誰かに投票することで、そのプレイヤーに爆弾を渡すことができ、一度に1人にしか渡せません。会議が終了すると、爆弾は一定時間後に作動し、爆発します。\n注: 会議中に誰かに爆弾を渡した後、さらに投票することができます。\n\nまた、設定に応じて、二重スパイはベント中にバスティオンやアジテーターの爆弾を解除できることがあります。\n\n二重スパイは、最後のインポスターとなったときに役割を変更することができ、設定に応じて、役割が尊敬されるインポスター、いたずら者、裏切り者、または二重スパイのままになることがあります。", "SlothInfoLong": "(アドオン):\n怠け者のデフォルト移動速度は他のプレイヤーよりも遅いです (速度はホストの設定に依存します)。", - "ProhibitedInfoLong": "(アドオン):\n禁止された者として、使用できない特定のベントがあります。\n無効化されるベントの数はホストの設定によって決まります。", - "EavesdropperInfoLong": "(アドオン):\n立ち聞きとして、葬儀屋や探偵のように、他の役職やアドオンに基づく情報メッセージを読むチャンスがあります。", - "ApocalypseInfoLong": "(黙示録):\n黙示録のメンバーは、独自のチームに所属し、一緒に行動して勝利を目指します。\nゲーム内に複数の黙示録役職がある場合、互いの役職を確認することができます。\nホストの設定によっては、黙示録役職が推測を行ったり、推測されることが可能です。", - "RevenantInfoLong": "(中立):\nレヴナント(亡霊)として、あなたの目標は殺されることです。\nもし殺されると、あなたは殺した相手の役職を奪い、その相手を逆に殺害します。\n殺される前に勝利することはできません。\nなお、レヴナント(亡霊)の能力は直接殺される場合のみ有効です。", + "ProhibitedInfoLong": "(アドオン)\n妨害者 使用できない特定のベントがあります.\nいくつのベントが使用不可になるかは, ホストの設定によります.", + "EavesdropperInfoLong": "(アドオン):\n盗聴者, 他の役を読むチャンスがありますか/アドオン\n情報化メッセージ, ような 葬儀屋和探偵.", + "ApocalypseInfoLong": "(Apocalypse):\nApocalypse members are on a separate team that works together and wins together. If there are multiple Apocalypse roles in the game, they can see each other's roles.\nDepending on the Host's settings, Apocalypse roles can guess or be guessed.", "ShowTextOverlay": "テキストオーバーレイ", "Overlay.GuesserMode": "ゲッサーモード", "Overlay.NoGameEnd": "ゲーム終了なし", @@ -1038,8 +1021,6 @@ "AbilityUseLimit": "初期の能力使用制限", "AbilityInUse": "能力が使用中", "AbilityExpired": "アビリティの期限切れ、{0} 回使用可能", - "RevenantTargeted": "役職が{0}に変更されました", - "RevenantCanCopyAddons": "アドオンを盗むことができます", "ShowArrows": "ボディを指し示す矢印があります", "ArrowDelayMin": "最小の矢印表示遅延", "ArrowDelayMax": "最大の矢印表示遅延", @@ -1368,8 +1349,6 @@ "ShieldedCanUseKillButton": "シールドされたプレイヤーは能力/キルボタンを使用できる", "PlayerIsShieldedByGame": "プレイヤーはゲームによって守られています!", "LegacyNemesis": "レガシーバージョンを使用", - "LegacyParasite": "レガシーバージョンを使用", - "LegacyTraitor": "レガシーバージョンを使用", "ArsonistKeepsGameGoing": "アーソニスト がゲームを続けます", "ArsonistCanIgniteAnytime": "いつでも点火できる", "ArsonistMinPlayersToIgnite": "点火に必要な最小投与量", @@ -1379,13 +1358,13 @@ "DollMasterPossessionDuration": "支配の持続時間", "DollMasterCanKillAsMainBody": "本体として殺すことができる", "DollMasterTargetDiesAfterPossession": "憑依後に対象が死亡", - "DoubleAgentCanDiffuseBombs": "ダブルエージェントは他の役職の爆弾を解除できます", + "DoubleAgentCanDiffuseBombs": "Double Agent can diffuse bombs from other roles", "DoubleAgentClearBombOnMeetingCall": "会議が召集されるときにアクティブな爆弾を解除する", "DoubleAgentCanUseAbilityInCalledMeeting": "解除に成功すると、召集された会議で能力を使用できる", "DoubleAgentBombExplosionTimer": "爆発の時間", "DoubleAgentExplosionRadius": "爆発の半径", - "DoubleAgent_DiffusedAgitaterBomb": "アジテーターの爆弾を成功裏に解除しました", - "DoubleAgent_DiffusedBastionBomb": "バスティオンの爆弾を成功裏に解除しました", + "DoubleAgent_DiffusedAgitaterBomb": "Agitator bomb successfully diffused", + "DoubleAgent_DiffusedBastionBomb": "Bastion bomb successfully diffused", "DoubleAgent_BombExplodesIn": "爆弾が爆発するまで: {0}秒", "DoubleAgent_BombExploded": "爆弾が爆発しました!", "DoubleAgentChangeRoleTo": "最後のインポスターで役割を変更", @@ -1512,18 +1491,6 @@ "SheriffCanKillSeparately": "個別の設定", "In%team%": "(チーム%team%)", "SheriffMisfireKillsTarget": "誤射でターゲットを倒す", - "BlackHolePlaceCooldown": "ブラックホール設置のクールダウン", - "BlackHoleDespawnMode": "ブラックホール消滅モード", - "BlackHoleDespawnTime": "ブラックホール消滅後の時間", - "Abyssbringer.Suffix": "<#00ffa5>現在のブラックホールによって飲み込まれたプレイヤー数: {0} <#00ffa5>アクティブなブラックホール:\\n{1}", - "Abyssbringer.Suffix.BlackHole": "<#00ffa5>{0}: {1}", - "BlackHoleMovesTowardsNearestPlayer": "ブラックホールが最も近いプレイヤーに向かって移動します", - "BlackHoleMoveSpeed": "ブラックホールの移動速度", - "BlackHoleRadius": "ブラックホールの吸引半径", - "AfterTime": "時間経過後", - "After1PlayerEaten": "1人が飲み込まれた後", - "AfterMeeting": "会議後", - "None": "なし", "SheriffShotLimit": "最大キル数", "SheriffCanKillAllAlive": "誰も死んでいなければ、誰かを殺すことができます。", "SheriffCanKillCharmed": "魅了 されたプレイヤーを殺すことができます", @@ -1540,15 +1507,12 @@ "RebirthUses": "再生の回数", "RebirthCountVotes": "自分に投票したプレイヤーにのみ再生する", "RebirthFailed": "ああ、残念。入れ替えるための適切な魂が見つかりませんでした。", - "FireworkerCooldown": "設置クールダウン", "ReverieIncreaseKillCooldown": "キルクールダウンを増加", "ReverieMaxKillCooldown": "最大キルクールダウン", "ReverieMisfireSuicide": "最大キルクールダウンに達した際の誤射", "ReverieResetCooldownMeeting": "会議後にキルクールダウンをリセット", "ConvertedReverieKillAll": "変換された夢想は、報復を受けることなく誰でも殺害できます。", "VigilanteNotify": "君は滅ぼすことを誓ったものそのものになった", - "DictatorChangeCommandToExpel": "ディクテーター は投票ではなくコマンドを使って追放する", - "DictatorExpelSelf": "待て待て待て、何が起きてるんだ?!マジで自分を追放しようとしてる…", "DoctorTaskCompletedBatteryCharge": "バッテリーの持続時間", "SnitchEnableTargetArrow": "ターゲットへの矢印を見る", "SnitchCanGetArrowColor": "チームカラーに基づいて色分けされた矢印を見る", @@ -1629,7 +1593,6 @@ "EvilTrackerTargetMode.OnceInGame": "ゲーム内で1回", "EvilTrackerTargetMode.EveryMeeting": "すべての会議で", "EvilTrackerTargetMode.Always": "いつでも", - "ScavengerHasCustomDeathReason": "カスタム死亡理由を有効化", "EvilHackerCanSeeDeadMark": "死体の位置を感知", "EvilHackerCanSeeImpostorMark": "他のインポスターの位置が見える", "EvilHackerCanSeeKillFlash": "キルフラッシュを見ることができる", @@ -1637,9 +1600,9 @@ "EvilHackerMurderNotify": "での殺害", "EvilHackerLastAdminInfoTitle": "直前の管理情報", "EvilHackerDeadbody": "死亡", - "Ventguard": "ベントガード", + "Ventguard": "Ventguard", "VentguardInfo": "通気口に入ることでブロック", - "VentguardInfoLong": "(クルーメイト):\nベントガードとして、ベントに入ってそれをブロックすることができます。\nブロックされたベントには誰も入ることができませんが、設定によってはクルーメイトのみが入れる場合があります。\nブロックされたベントは会議ごとにリセットされます。", + "VentguardInfoLong": "(Crewmates):\nAs the Ventguard, you can enter vents to block them. No one can enter blocked vents, except Crewmates, if the setting is on. Blocked vents can be resets every meeting.", "VentguardVentButtonText": "ブロック", "Ventguard_MaxGuards": "最大通気口ブロック数", "Ventguard_BlockVentCooldown": "通気口ブロックのクールダウン", @@ -1862,21 +1825,13 @@ "Jackal_SidekickCountMode_Jackal": "ジャッカル", "Jackal_SidekickCountMode_Original": "オリジナルのチーム", "Jackal_SidekickAssignMode": "サイドキック 割り当てモード", - "Jackal_SidekickAssignMode_SidekickAndRecruit": "サイドキック は リクルート に失敗した場合", + "Jackal_SidekickAssignMode_SidekickAndRecruit": "サイドキック+リクルート", "Jackal_SidekickAssignMode_Sidekick": "サイドキック のみ", - "Jackal_SidekickAssignMode_Recruit": "リクルート のみ", + "Jackal_SidekickAssignMode_Recruit": "リクルートのみ", + "JackalWinWithSidekick": "ジャッカル はサイドキック のチームと一緒に勝つことができます", "Jackal_SidekickCanKillSidekick": "サイドキック たちは他のサイドキック を殺すことができます", "Jackal_SidekickCanKillJackal": "サイドキック は ジャッカル を殺すことができます", - "Jackal_RecruitFailed": "このプレイヤーをリクルートすることはできません!", "JackalCanKillSidekick": "ジャッカル は サイドキック を殺せます", - "Jackal_SidekickCanKillWhenJackalAlive": "サイドキック は \nジャッカル が生存している間でも殺害できます", - "Jackal_SidekickTurnIntoJackal": "サイドキック は ジャッカル の死後、ジャッカルに昇格できます", - "Jackal_RestoreLimitOnNewJackal": "サイドキック が新しい ジャッカル になったとき、リクルート制限をリセットします", - "Jackal_OnBecomeNewJackalMeeting": "古い ジャッカル {0} は死にました。\nあなたが新しい ジャッカル に選ばれました!\n協力してゲームに勝利しましょう!", - "Jackal_OnNewJackalSelectedMeeting": "古い ジャッカル {0} は死にました。\n{1} が新しい ジャッカル に選ばれました!\n協力してゲームに勝利しましょう!", - "Jackal_BecomeNewJackal": "古いジャッカルが死亡、あなたが新しいジャッカルです!", - "Jackal_OnNewJackalSelected": "古いジャッカルが死亡、しばらくの間新しいジャッカル {0} を助けてください!", - "Jackal_BossIsDead": "おっと、ジャッカルのボスが死にました!", "CoronerArrowsPointingToDeadBody": "ボディを指し示す矢印があります", "CoronerLeaveDeadBodyUnreportable": "死体解剖医が使用した死体は報告できません", "CoronerInformKillerBeingTracked": "追跡されていることをキラー・プレーヤーに知らせる", @@ -1914,9 +1869,6 @@ "VipTag": "VIP★", "ApplyVipList": "VIPリストを適用", "AllowSayCommand": "モデレーターが/sayコマンドを使用できるようにする", - "AllowStartCommand": "モデレーターが /start コマンドを使用できるようにする", - "StartCommandMinCountdown": "/start コマンドの最小カウントダウン", - "StartCommandMaxCountdown": "/start コマンドの最大カウントダウン", "KickCommandDisabled": "キックコマンドは現在無効です。", "KickCommandNoAccess": "キックコマンドにアクセスできません。", "KickCommandInvalidID": "無効なプレイヤーIDが指定されました。プレイヤーをキックするには '/kick [playerID] [reseaon] ' を使用してください。例:- /kick 5 ルールに従わない", @@ -1949,11 +1901,6 @@ "WarnCommandNoAccess": "Warn コマンドに対する権限がありません", "WarnCommandInvalidID": "無効なプレイヤーIDが指定されました。プレイヤーに警告を出すには '/warn [playerID] [reason]' を使用してください。例:- /warn 5 ラヴァのチャット", "WarnCommandWarnHost": "ホストに警告する権限はありません。", - "StartCommandNoAccess": "/start コマンドにアクセスする権限がありません。", - "StartCommandDisabled": "スタートコマンドは現在無効です。", - "StartCommandCountdown": "エラー\n\nゲームはすでに開始しています!", - "StartCommandStarted": "{0} によってゲームが開始されました!", - "StartCommandInvalidCountdown": "エラー\n\nカウントダウンは {0} ~ {1} の間でなければなりません!", "WarnCommandWarnMod": "他のモデレーターに警告する権限はありません。", "WarnCommandWarned": "に警告されました。これ以上の警告はありません。適切な対処が取られます。 ", "WarnExample": "将来的には /warn [id] [reason] を使用してください。例:- /warn 5 ラヴァのチャット", @@ -1981,7 +1928,6 @@ "DeathReason.Quantization": "量子化", "DeathReason.Overtired": "過労", "DeathReason.Ashamed": "羞恥心", - "DeathReason.Consumed": "消費済み", "DeathReason.PissedOff": "滅ぼす", "DeathReason.Dismembered": "体がバラバラになる", "DeathReason.LossOfHead": "絞める", @@ -2005,8 +1951,6 @@ "DeathReason.Starved": "飢えさせられた", "DeathReason.Equilibrium": "均衡", "DeathReason.Sacrificed": "犠牲にされた", - "DeathReason.Electrocuted": "感電", - "DeathReason.Scavenged": "回収済み", "OnlyEnabledDeathReasons": "有効な死因のみ", "Alive": "生存中", "Disconnected": "断絶。", @@ -2071,8 +2015,7 @@ "Command.qq": "→ ロビーはQQウェブサイトに掲載されます (中国のみ)", "Command.dump": "→ デスクトップにログを出力", "Command.death": "→ あなたの死因に関する情報を表示", - "Command.icons": "
╳ - このプレイヤーは恐喝者によってマークされ、会議中に話すことができません
☆ - せんちょうが自身を表示するために使用します。この星はクルーメイトにのみ見えます
乂 - このプレイヤーはヘックスマスターによって呪われており、ヘックスマスターが会議終了時までに殺されるか追放されない限り死にます
♦ - 弁護士、死刑執行人、またはフォロワーによって使用されます
♥ - 恋人たちまたはロマンティックによって使用されます
✚ - メディックがターゲットをマークするために使用します
⦿ - このプレイヤーは海賊との決闘中です
!? - このプレイヤーはクイズ監督者によってマークされ、正しく答えなければ生き残れません
☜ - シュレーディンガーの猫がチームメイトをマークするために使用します
◈ - このプレイヤーは覆いによってマークされており、覆いが会議終了時までに殺されるか追放されない限り死にます
⚠ - このプレイヤーは密告者またはソルスティスであり、タスクを完了しています
★ - スーパースター、サイバー、または指揮官によって使用されます
† - このプレイヤーは呪文をかけられており、魔女が会議終了時までに殺されない限り死にます
∇ - ロケットミサイルがターゲットをマークするために使用します
■ - 稲妻が量子幽霊をマークするために使用します
⊠ - 看守が囚人をマークするために使用します
● - パン職人がパンを持っている人をマークするために使用します
♠ - 魂の収集者が予測する死をマークするために使用します
⦿ - 疫病媒介者が感染させた相手をマークするために使用します。", - "Command.start": "[秒数] → ゲームを開始", + "Command.icons": "
╳ - The Player was marked by the Blackmailer and can't talk during the Meeting
☆ - Used by Captain to display themselves. Only Crewmates can see the Captain's star
乂 - This player was hexed by the Hex Master and will die if the Hex Master isn't killed or ejected by the end of the Meeting.
♦ - Used by Lawyer or Executioner or Follower.
♥ - Used by Lovers or Romantic.
✚ - Used by Medic to mark their target.
⦿ - This player is in a duel with the Pirate.
!? - This player was marked by the Quizmaster and must answer the question correctly to survive.
☜ - Used by Schrödinger's cat to mark their teammate.
◈ - This player marked by the Shroud and will die if the Shroud is not killed or ejected by the end of the meeting.
⚠ - This player is a Snitch or Solsticer who has finished their tasks.
★ - Used by Super Star or Cyber or Marshall.
† - This player was spelled and will die if the Witch is not killed by the end of the meeting.
∇ - Used by Kamikaze to mark their targets.
■ - Used by Lightning to mark their quantum ghosts.
⊠ - Used by Jailer to mark their prisoner.
● - Used by Baker to mark who has Bread.
♠ - Used by Soul Collector to mark who's death they're predicting.
⦿ - Used by Plaguebearer to mark who they have plagued.", "Command.iconinfo": "→ 会議中のアイコンに関する情報を表示", "Command.iconhelp": "→ 会議中のアイコンに関する情報をすべてに表示", "Command.Poll": "→ 最大5つの選択肢で投票を開始する", @@ -2085,7 +2028,6 @@ "ShowMadmatesInLeftCommand": "マッドメイツ を表示 (アドオンを含む)", "ShowApocalypseInLeftCommand": "中立黙示録を表示", "SeeEjectedRolesInMeeting": "ミーティングで排除された役割を見る", - "ThankYouForUsingTOHE": "TOHEをご利用いただきありがとうございます!", "SkillUsedLeft": "会議を呼び出すスキルを発動しました。\n残りの使用回数:", "NemesisDeadMsg": "ネメシスの死は復讐の始まりを告げる。\n指定したプレイヤーを殺すには、/rv + [プレイヤー ID] を使用してください。プレイヤーの名前の前にプレイヤー ID が表示されます。または、/rv を入力してプレイヤー ID のリストを取得します。", "NemesisAliveKill": "ネメシスの復讐は、彼らの死後にのみ始まることができます。", @@ -2105,7 +2047,6 @@ "GuessNotifiedBait": "おとりは発表されたため、推測できません、簡単だと思いましたか?", "GuessGM": "GMを推測することは不可能です、なぜなら彼らはすでに死んでいます... そして、なぜ可哀想なホストにそんなことをするのでしょうか?", "GuessGuardianTask": "タスクを終えたガーディアンを推測することはできません。", - "GuardianCantKilled": "タスクを完了したガーディアンを殺すことはできません。", "GuessMarshallTask": "任務を完了した指揮官は、推測することはできません。", "GuessObviousAddon": "申し訳ありませんが、明らかなアドオンを使用しているプレイヤーを推測することはできません。", "GuessAdtRole": "残念ながら、ホストの設定ではアドオンを推測することはできません", @@ -2161,7 +2102,6 @@ "BecomeMadmateCuzMadmateMode": "死んだので、あなたはマッドメイトになりました", "CleanerCleanBody": "遺体はきれいにされました", "QuickShooterStoraging": "弾丸が成功裏に格納されました", - "QuickShooterFailed": "まだクールダウン中です。", "PoisonerTargetDead": "対象が死亡しました", "HexesLookLikeSpells": "ヘックス は 呪文 として表示されます", "HexButtonText": "呪い", @@ -2320,7 +2260,6 @@ "Message.YTPlanNotice": "注意:このロビーでは「YouTuberプラン」が有効になっており、ホストは次のゲームで役割を指定してコンテンツを作成しやすくすることができます。ホストがこの機能を乱用した場合、ゲームを終了するか、報告してください。\n現在の作成者の資格:", "Message.OnlyCanBeUsedByHost": "エラー\nこのコマンドはホストのみ使用できます。", "Message.MaxPlayers": "最大プレイヤー数が設定されました ", - "Message.MaxPlayersFailByRegion": "最大プレイヤー数を設定できませんでした:バニラリージョンでは最大15人まで対応可能です。", "Message.GhostRoleInfo": "ゴーストロール情報\nこんにちは!ゴーストロールについて少し…\n\nゴーストロールはゲームに大きな影響を与えるため、あまり詳しくない場合や小さなロビーではお勧めしません。説明に特に記載がない限り、ガードボタンが彼らの能力ボタンです ;) \n\nスポーンについて:\nゴーストロールは死後にのみスポーンします。死亡した最初のx人の (チーム) メンバーがそれらを得ます。\n\nPS:以前のロールにタスクがなかった場合 (例:シェリフ) 、ゴーストロールとしてのタスクはタスク勝利には必要ありません", "ApocalypseInfoTitle": "中立黙示録情報:", "Message.ApocalypseInfo": "黙示録チームの各役割には、変身を遂げるための独自の目標があります。\n変身後の 黙示録メンバーはゲームに大きな変化をもたらし、不死身になります (投票でのみ排除可能) が、変身したことは全員に通知されます。\n\n役割: 疫病媒介者, 魂の収集者, パン職人, 狂戦士\n変身後: ペスティレンス, 死, 飢饉, 戦争\n\n黙示録のメンバーはお互いの役割や能力アイコンを見ることができます。\n中立のキラーと同様に、黙示録のメンバーもゲームを続ける存在です。楽しんでください!", @@ -2725,9 +2664,8 @@ "DeathMeetingTimeIncrease": "死が存在する場合、会議時間が増加", "SoulCollectorMeetingDeath": "ターゲットが会議中に死亡しました。ソウルを獲得しました。", "SoulCollectorKillButtonText": "予測する", - "SoulCollectorHasImpostorVision": "魂の収集者 はインポスターの視界を持っています", "ApocalypseIsNigh": "「終末が迫っています!」", - "ApocalypseImmune": "この役職は無効化されません!", + "ApocalypseImmune": "このプレイヤーは無敵なので免疫があります!", "BakerToFamine": "あなたは飢饉になりました!!!", "BakerTransform": "パン職人飢饉に変身し、黙示録の騎士となった!飢饉が始まった!", "BakerAlreadyBreaded": "そのプレイヤーにはすでにパンが与えられています!", @@ -2736,15 +2674,13 @@ "BakerBreadNeededToTransform": "飢饉になるために必要なパンの数", "BakerCantBreadApoc": "他のアポカリプスメンバーにはパンを与えることはできません!", "BakerKillButtonText": "パン", - "BakerUnshiftButtonText": "パンの種類を切り替える", "BakerRevealBread": "公開する", "BakerRoleblockBread": "役割をブロックする", "BakerBarrierBread": "バリア", "BakerCurrentBread": "現在のパン数: ", "BakerSwitchBread": "パンが切り替えられました: ", - "BakerCanVent": "パン職人はベントを使用できます", + "BakerCanVent": "パン職人は通気口を使用できます", "BakerBreadGivesEffects": "パンが追加効果を与える", - "BakerTransformNoMoreBread": "パン職人はパンが不足すると変身します", "FamineKillButtonText": "飢えさせる", "FamineStarveCooldown": "飢饉の飢えクールダウン", "FamineCantStarveApoc": "他のアポカリプスメンバーを飢えさせることはできません!", @@ -2791,7 +2727,6 @@ "GodfatherTargetCountMode": "キラーが変身します", "GodfatherCount_Refugee": "難民", "GodfatherCount_Madmate": "マッドメイツ", - "GodfatherRefugeeMsg": "あなたはゴッドファーザーにリクルートされました!", "MissChance": "失敗する確率", "IncreaseByOneIfConvert": "クルーが変換された場合、キルカウントを+1増やす", "HawkMissed": "失敗!", @@ -2824,7 +2759,6 @@ "BerserkerToWar": "戦争に変身!!!", "BerserkerTransform": "狂戦士戦争に変身し、黙示録の騎士となった!「ハヴォック!」と叫び、戦の犬を解き放て。", "WarKillCooldown": "戦争のキルクールダウン", - "BerserkerCanKillTeamate": "他の中立黙示録を殺すことができます", "BlackmailerSkillCooldown": "脅迫のクールダウン", "BlackmailerMax": "脅迫されたプレイヤーが発言できる最大回数", "BlackmailerDead": "警告! {0}ブラックメイラー によって脅迫されています!", @@ -2914,8 +2848,6 @@ "RememberedPursuer": "あなたは自分が追跡者であることを思い出しました!", "RememberedFollower": "あなたはフォロワーであることを思い出しました!", "RememberedAmnesiac": "役職を思い出すことができませんでした。", - "AmnesiacRemembered": "あなたは {0} だったことを思い出しました!", - "ReportWhenFailedRemember": "思い出しに失敗した場合は死体を報告してください", "RememberedImitator": "あなたは自分が模倣者であることを思い出しました。", "RememberedImpostor": "あなたはインポスターであることを思い出しました!", "RememberedCrewmate": "あなたはクルーメイトであることを思い出しました!", @@ -3329,12 +3261,9 @@ "PixieTargetAlreadySelected": "ターゲットはすでに選択されています。", "PixieButtonText": "マーク", "PlagueBearerCooldown": "疫病のクールダウン", - "PlagueBearerCanVent": "ベント可能", - "PlagueBearerHasImpostorVision": "インポスターの視界を持っています", "PestilenceCooldown": "ペスティレンスのキルクールダウン", "PestilenceCanVent": "ペスティレンスはベントを使える", "PestilenceHasImpostorVision": "ペスティレンスにはインポスターの視界がある", - "PestilenceKillGuessers": "ペスティレンス を推測したプレイヤーを殺す", "PlagueBearerAlreadyPlagued": "プレイヤーはすでに疫病にかかっています", "PlagueBearerToPestilence": "あなたはペスティレンスになりました!!", "GuessPestilence": "あなたはペスティレンスを予想しようとしました!\n\nごめんなさい、ペスティレンスによって殺されました。", @@ -3378,7 +3307,6 @@ "EveryoneCanKnowMini": "みんながミニを見ることができます", "CanBeEvil": "ミニはインポスターになり得る", "EvilMiniSpawnChances": "ミニがインポスターである確率", - "EvilMiniCanBeGuessed": "イービルミニは18歳未満でも推測可能", "GuessMini": "ごめんなさい、子供のミニには攻撃できません。", "GrowUpDuration": "成長に必要な時間 (秒)", "MajorCooldown": "18歳以上の場合のキルクールダウン", @@ -3520,7 +3448,6 @@ "WinnerRoleText.Doppelganger": "ドッペルゲンガーの勝利!", "WinnerRoleText.Quizmaster": "クイズ監督者の勝利!", "WinnerRoleText.Agitater": "アジテーターの勝利!", - "WinnerRoleText.Shocker": "ショッカーの勝利!", "AdditionalWinnerRoleText.Sidekick": "相棒", "AdditionalWinnerRoleText.Taskinator": "タスキネーター", "AdditionalWinnerRoleText.Opportunist": "オポチュニスト", @@ -3606,7 +3533,7 @@ "SolsticerOnMeeting": "死をあまりにも多く目撃しました!次のラウンドではさらに{0} つの短いタスクが増えます!", "SolsticerTitle": "ソルスティス", "GuessSolsticer": "申し訳ありませんが、ソルスティスを推測することはできません!", - "ExpelSolsticer": "申し訳ありませんが、ソルスティスを追放することはできません!", + "VoteSolsticer": "申し訳ありませんが、ソルスティスに投票することはできません!", "SolsticerTasksReset": "あなたのタスクがリセットされた!", "SolsticerMisGuessed": "あなたは推測を誤りました!もう推測することはできません。", "SolsticerGuessMax": "あなたはすでに誤った推測をしたため、もう推測することは許可されていません。", @@ -3707,28 +3634,6 @@ "MinionAbilityTime": "能力の持続時間", "Minion_Blind": "盲目的", "Evader_ChanceNotExiled": "追放されない可能性", - "ShockerAbilityCooldown": "能力のクールダウン", - "ShockerAbilityDuration": "能力の持続時間", - "ShockerAbilityPerRound": "ラウンドごとの能力回数", - "ShockerShockInVents": "ベント内の人々を感電させる", - "ShockerAbilityResetAfterMeeting": "会議後にマークされた部屋をリセットする", - "ShockerOutsideRadius": "部屋外タスクの半径 (部屋内ではない場合)", - "ShockerCanShockHimself": "自分自身を感電させることができる", - "ShockerImpostorVision": "ショッカーはインポスターの視界を持っています", - "ShockerIsShocking": "すでに感電中です!", - "ShockerAbilityActivate": "感電を開始!", - "ShockerAbilityDeactivate": "能力が無効化されました", - "ShockerVentButtonText": "感電", - "ShockerRoomMarked": "マークされた部屋", "EavesdropperMsgTitle": "秘密を見つけた", - "EavesdropPercentChance": "盗み聞きするチャンス", - "ChiefOfPoliceSkillCooldown": "保安官をリクルートするためのクールダウン", - "PolicCanImpostorAndNeutarl": "インポスター または 中立 をリクルート可能", - "SheriffSuccessfullyRecruited": "保安官をリクルートしました。", - "BeSheriffByPolice": "あなたは警察署長にリクルートされました!クルーを守りましょう!", - "PoliceFailedRecruit": "ターゲットのリクルートに失敗しました。", - "ChiefOfPoliceKillButtonText": "リクルート", - "PolicPreventRecruitNonKiller": "キルボタンを持たないプレイヤーをリクルートすることを防止する", - "PolicSuidiceWhenTargetNotKiller": "非キラーまたは非クルーメイトをリクルートすると自殺します", - "PolicPassConverted": "変換されたアドオンを保安官に渡すことができる" -} \ No newline at end of file + "EavesdropPercentChance": "盗み聞きするチャンス" +} diff --git a/Resources/Lang/ko_KR.json b/Resources/Lang/ko_KR.json index 538cc0346..4122081da 100644 --- a/Resources/Lang/ko_KR.json +++ b/Resources/Lang/ko_KR.json @@ -19,8 +19,6 @@ "SubText.Neutral": "Work alone to achieve your victory", "SubText.Apocalypse": "Become unstoppable with your team", "SubText.Madmate": "Help the Impostors", - "SubText.Lovers": "Stay alive and win together", - "SubText.Egoist": "Win on your own", "TypeImpostor": "Impostors", "TypeCrewmate": "Crewmates", "TypeNeutral": "Neutrals", @@ -30,9 +28,6 @@ "TeamNeutral": "Neutral", "TeamCrewmate": "Crewmate", "TeamMadmate": "Madmate", - "TeamLovers": "Lovers", - "TeamEgoist": "Egoist", - "TeamApocalypse": "Apocalypse", "YouAreCrewmate": "You are a Crewmate", "YouAreImpostor": "You are an Impostor", "YouAreNeutral": "You are a Neutral", @@ -224,7 +219,6 @@ "TaskManager": "Task Manager", "Witness": "Witness", "Swapper": "Swapper", - "ChiefOfPolice": "Chief of Police", "NiceMini": "Nice Mini", "Mini": "Mini", "Spy": "Spy", @@ -253,7 +247,6 @@ "Stalker": "Stalker", "Workaholic": "Workaholic", "Solsticer": "Solsticer", - "Abyssbringer": "Abyssbringer", "Collector": "Collector", "Provocateur": "Provocateur", "BloodKnight": "Blood Knight", @@ -392,8 +385,6 @@ "Sloth": "Sloth", "Prohibited": "Prohibited", "Eavesdropper": "Eavesdropper", - "Shocker": "Shocker", - "Revenant": "Revenant", "BracketAddons": "Add Brackets To Add-ons", "EngineerTOHEInfo": "Use the vents to catch the Impostors", "ScientistTOHEInfo": "Access portable vitals from anywhere", @@ -512,7 +503,6 @@ "PacifistInfo": "Vent to reset kill cooldowns", "RebirthInfo": "Arise Again", "MonarchInfo": "Give your crew extra voting power!", - "AbyssbringerInfo": "Create Black Holes", "SpurtInfo": "Spring Like A rabbit!", "StealthInfo": "Killing Blinds Everyone in the Room", "PenguinInfo": "Drag your victims", @@ -546,7 +536,6 @@ "WitnessInfo": "Find out if someone killed recently", "GhastlyInfo": "Control somebody!", "SwapperInfo": "Swap the votes of two players", - "ChiefOfPoliceInfo": "Hire Sheriff to Serve the Crews!", "NiceMiniInfo": "No one can hurt you until you grow up.", "ArsonistInfo": "Douse everyone and ignite", "PyromaniacInfo": "Douse and kill everyone", @@ -707,8 +696,6 @@ "SlothInfo": "You're slower", "ProhibitedInfo": "Certain vents are blocked", "EavesdropperInfo": "Listen in on other roles", - "ShockerInfo": "Shock unsuspecting players", - "RevenantInfo": "Take your killer's role", "EngineerTOHEInfoLong": "(Crewmates):\nAs the Engineer, you may access the vents while Comms Sabotaged is inactive.", "ScientistTOHEInfoLong": "(Crewmates):\nAs the Scientist, you can see vitals at any time, showing you who is alive and dead.", "NoisemakerTOHEInfoLong": "(Crewmates):\nAs the Noisemaker, whenever you die, you will make a noise, and a visual indicator of your death appears on the screen so the Crewmates can run to catch the person who killed you red-handed (even if it’s not Red).", @@ -780,11 +767,11 @@ "LurkerInfoLong": "(Impostors):\nAs the Lurker, you can jump into a vent to reduce your cooldown by a certain number of seconds. After you kill, your cooldown resets to its original value.", "VisionaryInfoLong": "(Impostors):\nAs the Visionary, you see the alignments of living players during a meeting.\nThe following information will be displayed on the players:\n- The Red name indicates the Impostors.\n- The Cyan name indicates the Crewmates.\n- The Gray name indicates the Neutrals.", "PlagueDoctorInfoLong": "(Neutrals):\n(Plague Doctor from TOH)\nThe Plague Scientist's goal is to infect every living player.\nThey start by choosing one player to infect, after which anyone who spends a set amount of time in the range of the infected player becomes infected themselves.\nInfection progress is cumulative and does not reset with distance or after meetings.", - "RefugeeInfoLong": "(Madmates):\nAs the Refugee, you were either:\n -An Amnesiac who remembered an Impostor\n -A killer who killed the Godfather's target.\n -A Romantic whose partner was an Impostor\n -Or an Imitator that imitated an Impostor.\n\nNow your job is to help the Impostors kill the crewmates.", + "RefugeeInfoLong": "(Madmates):\nAs the Refugee, you were either an Amnesiac who remembered an Impostor or a killer who killed the Godfather's target.\n\nNow your job is to help the Impostors kill the crewmates.", "UnderdogInfoLong": "(Impostors):\nAs the Underdog, you cannot kill until there's a certain amount of players alive.", "ConsigliereInfoLong": "(Impostors):\nAs the Consigliere, you can reveal the roles of other players using your kill button.\n\nSingle click: Reveal role\nDouble click: Kill\n\nIf you run out of reveal uses, your kill button functions normally.", "LudopathInfoLong": "(Impostors):\nAs the Ludopath, your kill cooldown is randomized.\n\nMinimum it can be is 1 second, while the maximum is your default kill cooldown.", - "GodfatherInfoLong": "(Impostors):\nAs the Godfather, you vote someone to make them your target.\nIn the next round, if someone kills the target, the killer will turn into a Refugee or Madmate.", + "GodfatherInfoLong": "(Impostors):\nAs the Godfather, you vote someone to make them your target.\nIn the next round, if someone kills the target, the killer will turn into a Refugee.", "ChronomancerInfoLong": "(Impostors):\nAs the Chronomancer, you have a charge bar which indicates when the slaughter is ready. When it is at 100% the next time you kill someone, you go into slaughter mode, meaning you can kill indefinitely until your bar runs out of charge. Otherwise, you have a normal KCD.", "PitfallInfoLong": "(Impostors):\nAs the Pitfall, you use your shapeshift to mark the area around the shapeshift as a trap. Players who enter this area will be immobilized quickly, and their vision will be affected.", "EvilMiniInfoLong": "(Impostors):\nAs the Evil Mini, you are unkillable until you grow up and have a very long initial kill cooldown, which gets drastically shortened as you grow up.", @@ -856,7 +843,6 @@ "TaskManagerInfoLong": "(Crewmates):\nYou see the total number of tasks completed (by everyone all together) next to your role name, which updates in real-time.", "WitnessInfoLong": "(Crewmates):\nAs the Witness, when you use your kill button on someone, you will know if they killed in the last X seconds or not. (X depends on the settings).", "SwapperInfoLong": "(Crewmates):\nAs the Swapper, you can swap votes in meetings.\n\nTo swap votes, use '/sw [playerID]' twice.\n\nPlayer IDs are displayed next to player names in meetings, but you can also use /id to get a list of all player IDs.\n\nNote: Depending on the Host's settings, you can exchange your own votes.", - "ChiefOfPoliceInfoLong": "(Crewmates):\nPlayers with swords can be recruited to join the sheriff's team to serve the crew\nNote: only one recruitment opportunity\nDepending on settings, you may recruit non killers or non crews.\nYou may suidice for recruiting wrong target.", "NiceMiniInfoLong": "(Crewmates):\nAs a Nice Mini, your survival is crucial. You can't be killed until you grow up, and if you die or are evicted from the meeting before you grow up, everyone loses. This unique role adds a new dynamic to the game, where your survival is not just for your benefit but for the entire Crew's success.", "SpyInfoLong": "(Crewmates):\nAs the Spy, when someone uses their kill button on you (any ability used through the kill button), you'll see their name in orange for a few seconds.\nNote: If a Crewmate used their ability on you, you'll also see them with an orange name!\nNote: If you cannot use left, you won't see orange names!\nNote: If the kill button interaction is blocked, the player's cooldown will reset to 10s'", "RandomizerInfoLong": "(Crewmates):\nAs this Randomizer, when you die, your killer will do one of the following:\n 1. self-report your body\n 2. stand next to your body\n 3. have their kill cooldown set to 600s\n 4. Randomly avenge a player.", @@ -871,7 +857,7 @@ "LawyerInfoLong": "(Neutrals):\nLawyer has a target to defend, which will be indicated by a diamond 「♦」 next to their name.\nIf your target wins, you win.\nIf they lose, you lose.", "OpportunistInfoLong": "(Neutrals):\nIf the Opportunist survives at the end of the game, the Opportunist will win with the winning player.", "VectorInfoLong": "(Neutrals):\nVector will win alone by venting a certain number of times.", - "JackalInfoLong": "(Neutrals):\nAs the Jackal, you win if you are the last player alive. Additionally, you may recruit using the kill button. If the target is not one you can recruit, you have run out of uses, or you don't have the option to recruit, then you will kill people normally (i.e., don't use kill buttons in front of others thinking it'll recruit). If the target has a kill button and the option to turn into a Sidekick is on, they will become a Sidekick. Otherwise, they will gain the Recruit add-on if the option to give the Recruit add-on is on.\nDepending on the settings, when Jackal was killed, a Sidekick will be randomly selected as the new Jackal.\nRecruit may be selected if no sidekick is alive.", + "JackalInfoLong": "(Neutrals):\nAs the Jackal, you win if you are the last player alive. Additionally, you may recruit using the kill button. If the target is not one you can recruit, you have run out of uses, or you don't have the option to recruit, then you will kill people normally (i.e., don't use kill buttons in front of others thinking it'll recruit). If the target has a kill button and the option to turn into a Sidekick is on, they will become a Sidekick. Otherwise, they will gain the Recruit add-on if the option to give the Recruit add-on is on.", "GodInfoLong": "(Neutrals):\nAs the God, you know everyone's role from the beginning. If you live until the end of the game, you steal the win, i.e., everyone else loses, and you win.", "InnocentInfoLong": "(Neutrals):\nThe Innocent can use the kill button to plant any player, and the planted target will immediately kill the Innocent. If the target gets voted out in the meeting, the Innocent wins. Note: Jester, Executioner, and Innocent can win together.", "PelicanInfoLong": "(Neutrals):\nAs the Pelican, you can use the kill button to swallow a player alive, teleporting them off-bounds but not killing them yet. Those swallowed will only die if you're still alive at the end of the round. If you die or leave during the round, all alive swallowed players will spawn into the map where you were.", @@ -883,7 +869,7 @@ "SolsticerInfoLong": "(Neutrals):\nAs the Solsticer, you won't die, and you win by finishing all your tasks in a single round. After every meeting finishes, your tasks reset, and you need to start all over again.\nVotes on the Solsticer will be directly canceled.\nKill attempts on the Solsticer will teleport it out of the map like Pelican until the meeting is finished.\nThe killer's kill cooldown will be reset to 10 seconds.\nSolsticer is counted as nothing in-game.", "CollectorInfoLong": "(Neutrals):\nAs the Collector, when you vote for a player, for each other player that voted for them, you gain a point. When you collect the required votes, the game ends, and you win alone, even if you voted a Jester or Executioner's target out.", "GlitchInfoLong": "(Neutrals):\nAs the Glitch, you can hack players (single click) or kill normally (double click).\nThose who have been hacked cannot kill, vent, or report for the hack duration.\nAdditionally, calling a sabotage other than doors will have no effect and will instead disguise you as a random player. You cannot disguise during or after sabotages.\nTo win, be the last player alive.", - "SidekickInfoLong": "(Neutrals):\nAs the Sidekick, your job is to help the Jackal kill everyone.\nYou and the Jackal win together.\nDepending on the settings, you may turn into Jackal if old Jackal was killed.\nYou may not be able to kill until old Jackal is dead.", + "SidekickInfoLong": "(Neutrals):\nAs the Sidekick, your job is to help the Jackal kill everyone.\n\nYou and the Jackal win together.", "ProvocateurInfoLong": "(Neutrals):\nAs the Provocateur, you can kill any target with the kill button. If the target loses at the end of the game, the Provocateur wins with the winning team.", "BloodKnightInfoLong": "(Neutrals):\nThe Blood Knight wins when they're the last killing role alive, and the amount of crewmates is lower or equal to the amount of Blood Knights. The Blood Knight gains a temporary shield after every kill, making them immortal for a few seconds.", "PlagueBearerInfoLong": "(Apocalypse):\nAs the Plaguebearer, plague everyone using your kill button to turn into Pestilence.\nOnce you turn into Pestilence, you will become immortal and gain the ability to kill, and you will kill anyone who tries to kill you.\n\nAlso, when infected players interact with uninfected players, they will also be infected.", @@ -910,12 +896,11 @@ "TraitorInfoLong": "(Neutrals):\nAs the Traitor, you were an Impostor that betrayed the Impostors.\nYou know the Impostors, but they don't know you.\nThe twist? They can kill you, but you can't kill them.\n\nEliminate the Impostors by other means, then kill everyone else to win!", "TrollerInfoLong": "(Neutrals):\nAs a Troller, you can complete tasks so that random events can happen to players.\nFor example, changing the speed of all players, teleportation, influencing sabotage, etc.\nAlso you can win with the winning team.", "VultureInfoLong": "(Neutrals):\nAs the Vulture, report bodies to win!\n\nWhen you report a body, if your eat cooldown is up, you'll eat the body (makes it unreportable).\nIf your eat ability is still on cooldown, then you'll report the body normally.\n\nAdditionally, you'll report bodies normally if the maximum bodies eaten per round is reached.", - "AbyssbringerInfoLong": "(Impostors):\nAs the Abyssbringer, you can place black holes. Black holes will suck in players and kill them when colliding with them.", "TaskinatorInfoLong": "(Neutrals):\nAs the Taskinator, whenever you finish a task, the task will be bombed. When another player completes the bombed task, the bomb will detonate, and the player will die.\n\nYou win if you survive till the end and Crew doesn't win.\n\n Note: Taskinator bombs ignore all protection.", "BenefactorInfoLong": "(Crewmates):\nAs the Benefactor, whenever you finish a task, that task will be marked. When another player completes the marked task, they get a temporary shield.\n\n Note: Shield only protects from direct kill attacks.", "MedusaInfoLong": "(Neutrals):\nAs the Medusa, you can stone bodies much like cleaning a body.\nStoned bodies cannot be reported.\n\nKill everyone to win.", "SpiritcallerInfoLong": "(Neutrals):\nAs the Spiritcaller, your victims become Evil Spirits after they die. These spirits can help you win by freezing other players briefly or blocking their vision. Alternatively, the spirits can give you a shield that protects you briefly from an attempted kill.", - "AmnesiacInfoLong": "(Neutrals):\nAs the Amnesiac, use your report button to remember a target and get its role.\nTo balance the game, you will not be able to vent after remembering your role if you can't vent as Amnesiac.'", + "AmnesiacInfoLong": "(Neutrals):\nAs the Amnesiac, use your report button to remember a role.\n\nIf the target was an Impostor, you'll become a Refugee.\nIf the target was a crewmate, you'll become the target role if compatible (otherwise you become an Engineer).\nIf the target was a passive neutral or a neutral killer not specified, you'll become the role defined in the settings.\nIf the target was a neutral killer of a select few, you'll become the role they are.", "ImitatorInfoLong": "(Neutrals):\nAs the Imitator, use your kill button to imitate a player.\n\nYou'll either become a Sheriff, a Refugee, or some Neutral.", "BanditInfoLong": "(Neutrals):\nAs the Bandit, you can click your kill button one time to steal a player's addon and twice to kill. Depending on the settings, you may instantly steal the addon or after the meeting starts. After the maximum number of steals is reached, you will kill normally. Additionally, if there are no stealable addons on the target or the target is stubborn, you will kill the target.\n\nKill everyone to win.\n\nNote: Cleansed, Last Impostor, and Lovers cannot be stolen.\nNote: If Bandit can vent is on, Nimble will become unstealable.", "DoppelgangerInfoLong": "(Neutrals):\nAs the Doppelganger, use your kill button to steal a player's identity (their name and skin) and then kill your target.\n\nKill everyone to win.\n\nNote: You cannot steal the target's identity when Camouflage is active.", @@ -936,7 +921,6 @@ "JinxInfoLong": "(Neutrals):\nAs the Jinx, whenever you get attacked, you jinx them, resulting in them dying to a jinx.\nThis has limited uses.\n\nKill off everyone to win.", "PotionMasterInfoLong": "(Neutrals):\nAs the Potion Master, you have three different potions assigned to three different actions.\n\nSingle click: Reveal role\nDouble click: Kill\nMap: Sabotage\n\nThe reveal potion has a limit.\nWhen you run out, the kill buttons default to killing.", "NecromancerInfoLong": "(Neutrals):\nAs the Necromancer, you win when you're the last one standing.\nAdditionally when someone tries to kill you, you will block the kill, and you will teleport to a random vent. You will have a limited time to kill your killer. If you succeed in doing so, you live. If the time runs out before you kill your killer, you die permanently. If you try to kill someone else other than your killer, you will die.", - "ShockerInfoLong": "(Neutrals):\nAs the Shocker, you can mark rooms by doing tasks in them, and then vent to Electrocute anyone in those rooms for a set period of time. When you finish all of your tasks, you get new ones. Note: Doing tasks during that period will mark them for the next ability use.", "LastImpostorInfoLong": "(Add-ons):\nThis special effect is given to the last surviving Impostor. It significantly reduces their kill cooldown.", "OverclockedInfoLong": "(Add-ons):\nAs the Overclocked, your kill cooldown is reduced by a percentage.\n\nThis feature is only assigned to roles with a kill button.", "LoversInfoLong": "(Add-ons):\nLovers are a combination of two players. The Lovers win when they are the last ones standing, and their victory is shared. When one of the Lovers wins, the other also wins together. Lovers can see the 「♥」 next to each other's name. If one of the Lovers dies, the other will die in love (may not die in love according to the Host's settings). When one of the Lovers is exiled in the meeting, the other will die and become a dead body that cannot be reported.", @@ -980,7 +964,7 @@ "RebirthInfoLong": "(Add-ons):\nAs the Rebirth, if you're the player about to be ejected, you will swap skins with a random crewmate who voted for you.\nNotice: The host vote never counts\nRebirth will be removed from you if you exhausted all your rebirths.", "LoyalInfoLong": "(Add-ons):\nAs the Loyal, you cannot be recruited by roles such as Jackal or Cultist.\n\nCannot be assigned to neutrals.", "EvilSpiritInfoLong": "(Add-ons):\nAs Evil Spirit, it's your job to help the Spiritcaller to victory. You can use your Haunt button to freeze players and reduce their vision. Alternatively, you can use your Haunt button to give the Spiritcaller a shield against a kill attempt temporarily.", - "RecruitInfoLong": "(Betrayal Add-ons):\nAs a recruit, you are on the Jackal's team and help out the Jackal and their Sidekicks.\nYou cannot win with your original team.\nDepending on the settings, you may turn into Jackal if old Jackal was killed and no sidekicks is alive.", + "RecruitInfoLong": "(Betrayal Add-ons):\nAs a recruit, you are on the Jackal's team and help out the Jackal and their Sidekicks.\n\nYou cannot win with your original team.", "AdmiredInfoLong": "(Betrayal Add-ons):\nAs an admired player, you win with the crew and not your original team.\n\nYou can see the Admirer.", "GlowInfoLong": "(Add-ons):\nDuring lights out, you and players nearby you will receive a vision boost.", "RadarInfoLong": "(Add-ons):\nAs Radar, you have arrows pointing towards the closest person at all times.", @@ -1024,7 +1008,6 @@ "ProhibitedInfoLong": "(Add-ons):\nAs the Prohibited, you have specific vents that you can't use.\nHow many vents are disabled depends on the Host's settings.", "EavesdropperInfoLong": "(Add-ons):\nAs the Eavesdropper, you have a chance to read other role/addon information-based messages like Mortician or Sleuth.", "ApocalypseInfoLong": "(Apocalypse):\nApocalypse members are on a separate team that works together and wins together. If there are multiple Apocalypse roles in the game, they can see each other's roles.\nDepending on the Host's settings, Apocalypse roles can guess or be guessed.", - "RevenantInfoLong": "(Neutral):\nAs the Revenant, your goal is to be killed. If you are killed, you will take your killer's role and kill your killer instead. You cannot win before being killed.\nNote that Revenant only works when being directly killed.", "ShowTextOverlay": "Text Overlay", "Overlay.GuesserMode": "Guesser Mode", "Overlay.NoGameEnd": "No Game End", @@ -1038,8 +1021,6 @@ "AbilityUseLimit": "Initial Ability Use Limit", "AbilityInUse": "Ability in use", "AbilityExpired": "Ability expired, {0} uses remain", - "RevenantTargeted": "Your role has changed to {0}", - "RevenantCanCopyAddons": "Can Steal Addons", "ShowArrows": "Has Arrows pointing toward bodies", "ArrowDelayMin": "Minimum Arrow show-up delay", "ArrowDelayMax": "Maximum Arrow show-up delay", @@ -1368,8 +1349,6 @@ "ShieldedCanUseKillButton": "Shielded player can use ability / kill button", "PlayerIsShieldedByGame": "Player is protected by the game!", "LegacyNemesis": "Use Legacy Version", - "LegacyParasite": "Use Legacy Version", - "LegacyTraitor": "Use Legacy Version", "ArsonistKeepsGameGoing": "Arsonist keeps the game going", "ArsonistCanIgniteAnytime": "Can Ignite Anytime", "ArsonistMinPlayersToIgnite": "Minimum doused needed for ignite", @@ -1512,18 +1491,6 @@ "SheriffCanKillSeparately": "Individual Settings", "In%team%": "(Team %team%)", "SheriffMisfireKillsTarget": "Misfire Kills Target", - "BlackHolePlaceCooldown": "Black Hole Place Cooldown", - "BlackHoleDespawnMode": "Black Hole Despawn Mode", - "BlackHoleDespawnTime": "Time After Black Hole Despawns", - "Abyssbringer.Suffix": "<#00ffa5>Number of players consumed by {0} <#00ffa5>active black holes:\\n{1}", - "Abyssbringer.Suffix.BlackHole": "<#00ffa5>{0}: {1}", - "BlackHoleMovesTowardsNearestPlayer": "Black Hole Moves Towards Nearest Player", - "BlackHoleMoveSpeed": "Black Hole Moving Speed", - "BlackHoleRadius": "Black Hole Consuming Radius", - "AfterTime": "After Time", - "After1PlayerEaten": "After 1 Player Was Eaten", - "AfterMeeting": "After Meeting", - "None": "None", "SheriffShotLimit": "Max number of Kills", "SheriffCanKillAllAlive": "Can Kill When No One Is Dead", "SheriffCanKillCharmed": "Can kill Charmed players", @@ -1540,15 +1507,12 @@ "RebirthUses": "Amount of Rebirths", "RebirthCountVotes": "Only rebirth to players who voted for them", "RebirthFailed": "Ahh, how unfortunate, you did not find any viable souls to swap bodies with", - "FireworkerCooldown": "Placement Cooldown", "ReverieIncreaseKillCooldown": "Increase kill cooldown", "ReverieMaxKillCooldown": "Max kill cooldown", "ReverieMisfireSuicide": "Misfire on reaching max kill cooldown", "ReverieResetCooldownMeeting": "Reset kill cooldown after meeting", "ConvertedReverieKillAll": "Converted Reverie can kill anyone without repercussions", "VigilanteNotify": "You have become the very thing you swore to destroy", - "DictatorChangeCommandToExpel": "Dictator use Command to expell instad of vote", - "DictatorExpelSelf": "WAIT WAIT WAIT WAT THE HELLLLLL Bro really just want to expel himself", "DoctorTaskCompletedBatteryCharge": "Battery Duration", "SnitchEnableTargetArrow": "See Arrow Towards Target", "SnitchCanGetArrowColor": "See Colored Arrows based on Team Colors", @@ -1629,7 +1593,6 @@ "EvilTrackerTargetMode.OnceInGame": "Once in-game", "EvilTrackerTargetMode.EveryMeeting": "Every Meeting", "EvilTrackerTargetMode.Always": "Any time", - "ScavengerHasCustomDeathReason": "Enable Custom Death Reason", "EvilHackerCanSeeDeadMark": "Can See The Location of Dead-bodies", "EvilHackerCanSeeImpostorMark": "Can See The Location of Other Impostors", "EvilHackerCanSeeKillFlash": "Can See Kill-Flash", @@ -1862,21 +1825,13 @@ "Jackal_SidekickCountMode_Jackal": "Jackal", "Jackal_SidekickCountMode_Original": "Original Team", "Jackal_SidekickAssignMode": "Sidekick Assign Mode", - "Jackal_SidekickAssignMode_SidekickAndRecruit": "Sidekick when failed Recruit", - "Jackal_SidekickAssignMode_Sidekick": "Only Sidekick", - "Jackal_SidekickAssignMode_Recruit": "Only Recruit", + "Jackal_SidekickAssignMode_SidekickAndRecruit": "Sidekick+Recruit", + "Jackal_SidekickAssignMode_Sidekick": "Sidekick Only", + "Jackal_SidekickAssignMode_Recruit": "Recruit Only", + "JackalWinWithSidekick": "Jackal can win with Sidekick's team", "Jackal_SidekickCanKillSidekick": "Sidekicks can kill other Sidekicks", "Jackal_SidekickCanKillJackal": "Sidekick can kill Jackal", - "Jackal_RecruitFailed": "You can not recruit this player!", "JackalCanKillSidekick": "Jackal can kill Sidekick", - "Jackal_SidekickCanKillWhenJackalAlive": "Sidekick can kill while Jackal is Alive", - "Jackal_SidekickTurnIntoJackal": "Sidekick can turn into Jackal after its death", - "Jackal_RestoreLimitOnNewJackal": "Restore Recruit limit when Sidekick become new Jackal", - "Jackal_OnBecomeNewJackalMeeting": "The old Jackal {0} is dead.\nYou are selected as new Jackal\nWork together and win the game!", - "Jackal_OnNewJackalSelectedMeeting": "The old Jackal {0} is dead.\n{1} is selected as new Jackal!\nWork together and win the game!", - "Jackal_BecomeNewJackal": "Old Jackal Dead, You are now new Jackal!", - "Jackal_OnNewJackalSelected": "Old Jackal Dead, Please help new Jackal {0} for now!", - "Jackal_BossIsDead": "Opps, the Jackal boss is dead!", "CoronerArrowsPointingToDeadBody": "Arrows pointing to dead bodies", "CoronerLeaveDeadBodyUnreportable": "Bodies the Coroner uses can't be reported", "CoronerInformKillerBeingTracked": "Inform the Killer that he gets tracked", @@ -1914,9 +1869,6 @@ "VipTag": "VIP★", "ApplyVipList": "Apply VIP List", "AllowSayCommand": "Allow moderators to use /say command", - "AllowStartCommand": "Allow moderators to use /start command", - "StartCommandMinCountdown": "Minimum countdown for /start command", - "StartCommandMaxCountdown": "Maximum countdown for /start command", "KickCommandDisabled": "The kick command is currently disabled.", "KickCommandNoAccess": "You do not have access to the kick command.", "KickCommandInvalidID": "Invalid player ID specified.\nPlease use '/kick [playerID] [reason]' to kick a player.\nExample :- /kick 5 not following rules", @@ -1949,11 +1901,6 @@ "WarnCommandNoAccess": "You do not have access to the warn command.", "WarnCommandInvalidID": "Invalid player ID specified.\nPlease use '/warn [playerID] [reason]' to warn a player. \nExample :- /warn 5 lava chatting", "WarnCommandWarnHost": "You are not permitted to warn the host.", - "StartCommandNoAccess": "You do not have access to the start command.", - "StartCommandDisabled": "The start command is currently disabled.", - "StartCommandCountdown": "ERROR\n\nThe game is already starting!", - "StartCommandStarted": "The game has been started by {0}!", - "StartCommandInvalidCountdown": "ERROR\n\nThe countdown must be between {0} and {1}!", "WarnCommandWarnMod": "You are not permitted to warn other moderators.", "WarnCommandWarned": "has been warned. There will be no more warnings given and appropriate action will be taken \n ", "WarnExample": "Use /warn [id] [reason] in future. \nExample :-\n /warn 5 lava chatting", @@ -1981,7 +1928,6 @@ "DeathReason.Quantization": "Quantization", "DeathReason.Overtired": "Overtired", "DeathReason.Ashamed": "Ashamed", - "DeathReason.Consumed": "Consumed", "DeathReason.PissedOff": "Destroyed", "DeathReason.Dismembered": "Dismembered", "DeathReason.LossOfHead": "Strangled", @@ -2005,8 +1951,6 @@ "DeathReason.Starved": "Starved", "DeathReason.Equilibrium": "Equilibrium", "DeathReason.Sacrificed": "Sacrificed", - "DeathReason.Electrocuted": "Electrocuted", - "DeathReason.Scavenged": "Scavenged", "OnlyEnabledDeathReasons": "Only Enabled Death Reasons", "Alive": "Alive", "Disconnected": "Disconnected", @@ -2072,7 +2016,6 @@ "Command.dump": "→ Output Log to Desktop", "Command.death": "→ Display info on how you died", "Command.icons": "
╳ - The Player was marked by the Blackmailer and can't talk during the Meeting
☆ - Used by Captain to display themselves. Only Crewmates can see the Captain's star
乂 - This player was hexed by the Hex Master and will die if the Hex Master isn't killed or ejected by the end of the Meeting.
♦ - Used by Lawyer or Executioner or Follower.
♥ - Used by Lovers or Romantic.
✚ - Used by Medic to mark their target.
⦿ - This player is in a duel with the Pirate.
!? - This player was marked by the Quizmaster and must answer the question correctly to survive.
☜ - Used by Schrödinger's cat to mark their teammate.
◈ - This player marked by the Shroud and will die if the Shroud is not killed or ejected by the end of the meeting.
⚠ - This player is a Snitch or Solsticer who has finished their tasks.
★ - Used by Super Star or Cyber or Marshall.
† - This player was spelled and will die if the Witch is not killed by the end of the meeting.
∇ - Used by Kamikaze to mark their targets.
■ - Used by Lightning to mark their quantum ghosts.
⊠ - Used by Jailer to mark their prisoner.
● - Used by Baker to mark who has Bread.
♠ - Used by Soul Collector to mark who's death they're predicting.
⦿ - Used by Plaguebearer to mark who they have plagued.", - "Command.start": "[Seconds] → Start the game", "Command.iconinfo": "→ Display info on in-meeting icons", "Command.iconhelp": "→ Display info on in-meeting icons to everyone", "Command.Poll": "→ Start a poll with up-to 5 choices", @@ -2085,7 +2028,6 @@ "ShowMadmatesInLeftCommand": "Show Madmates (including add-ons)", "ShowApocalypseInLeftCommand": "Show Neutral Apocalypse", "SeeEjectedRolesInMeeting": "See ejected roles in meetings", - "ThankYouForUsingTOHE": "Thank you for using TOHE!", "SkillUsedLeft": "You have activated your skill to call a meeting. \nRemaining amount of uses left:", "NemesisDeadMsg": "The death of the Nemesis means the beginning of the revenge. \nPlease use /rv + [player ID] to kill the specified player \nYou can see player IDs in front of their names. \nOr type /rv to get a list of player IDs", "NemesisAliveKill": "Revenge for the Nemesis can only begin after their death.", @@ -2105,7 +2047,6 @@ "GuessNotifiedBait": "Bait can't be guessed because it was announced. You thought it would be that easy, right?", "GuessGM": "Guessing the GM is impossible because they're already dead.... And why would you do that to the poor Host?", "GuessGuardianTask": "You can't guess a Guardian who has finished their tasks.", - "GuardianCantKilled": "You can't kill a Guardian who has finished their tasks.", "GuessMarshallTask": "You can't guess a Marshall who has finished their tasks.", "GuessObviousAddon": "Sorry, obvious add-ons cannot be guessed.", "GuessAdtRole": "Unfortunately, the Host's settings do not allow you to guess add-ons", @@ -2161,7 +2102,6 @@ "BecomeMadmateCuzMadmateMode": "You became a Madmate because you died", "CleanerCleanBody": "The body has been cleaned", "QuickShooterStoraging": "Bullets stored successfully", - "QuickShooterFailed": "You are still in cooldown.", "PoisonerTargetDead": "Target died", "HexesLookLikeSpells": "Hexes appear as spells", "HexButtonText": "Hex", @@ -2320,7 +2260,6 @@ "Message.YTPlanNotice": "Note: The [YouTuber Plan] is enabled in this lobby, which means the Host can specify their role in the next game to make it easier to get content. If the Host abuses this feature, please exit the game or report it.\nCurrent Creator Credentials:", "Message.OnlyCanBeUsedByHost": "ERROR\n\nThis command may only be used by the host.", "Message.MaxPlayers": "Maximum players set to ", - "Message.MaxPlayersFailByRegion": "Could not set max players: Vanilla regions support a maximum of 15 players.", "Message.GhostRoleInfo": "Ghost Role Info\nHiya! A little about ghost roles...\n\nGhost roles drastically impact the game, so it's not recommended for smaller lobbies if you're unfamiliar. If not explicitly stated otherwise in the description, the Guard button is their ability button ;)\n\nSpawning:\nGhost-roles only spawn after death; the first x people from (team) to die get them.\n\nPS: If your previous role didn't have tasks(e.g., sheriff), your tasks as a ghost-role aren't needed for task-win", "ApocalypseInfoTitle": "Neutral Apocalypse Info:", "Message.ApocalypseInfo": "Every role of the <#ff174f>Apocalypse Team has their own objective to carry out in order to transform.\n<#2B0804>Transformed <#ff174f>Apocalypse members have a drastic change on the game and are immortal (except for being voted), but everyone will be notified that they have transformed.\n\nRoles: <#e5f6b4>Plaguebearer, <#A675A1>Soul Collector, <#bf9f7a>Baker, <#cc0044>Berserker\nTransformed: <#343136>Pestilence, <#644661>Death, <#83461c>Famine, <#2B0804>War\n\nApocalypse members can see eachother's roles and ability icons.\nLike Neutral Killers, Apocalypse members keep the game going as well, have fun!", @@ -2725,9 +2664,8 @@ "DeathMeetingTimeIncrease": "Increased Meeting time when Death exists", "SoulCollectorMeetingDeath": "Your target has died during the meeting. You have gained a soul.", "SoulCollectorKillButtonText": "Predict", - "SoulCollectorHasImpostorVision": "Soul Collector has Impostor vision", "ApocalypseIsNigh": "[ The Apocalypse Is Nigh! ]", - "ApocalypseImmune": "This role is immune!", + "ApocalypseImmune": "This player is immune because they are invincible!", "BakerToFamine": "You have become Famine!!!", "BakerTransform": "The Baker has transformed into Famine, Horseman of the Apocalypse! A famine has begun!", "BakerAlreadyBreaded": "That player already has bread!", @@ -2736,15 +2674,13 @@ "BakerBreadNeededToTransform": "Required number of bread to become Famine", "BakerCantBreadApoc": "You cannot give other Apocalypse members bread!", "BakerKillButtonText": "Bread", - "BakerUnshiftButtonText": "Switch Bread", "BakerRevealBread": "Reveal", "BakerRoleblockBread": "Roleblock", "BakerBarrierBread": "Barrier", "BakerCurrentBread": "Current Bread: ", "BakerSwitchBread": "Bread Switched to: ", - "BakerCanVent": "Baker can Vent", + "BakerCanVent": "Baker can Vent", "BakerBreadGivesEffects": "Bread gives additional effects", - "BakerTransformNoMoreBread": "Baker transforms if they do not have enough bread", "FamineKillButtonText": "Starve", "FamineStarveCooldown": "Famine starve cooldown", "FamineCantStarveApoc": "You cannot starve other Apocalypse members!", @@ -2791,7 +2727,6 @@ "GodfatherTargetCountMode": "Killer turns into", "GodfatherCount_Refugee": "Refugee", "GodfatherCount_Madmate": "Madmate", - "GodfatherRefugeeMsg": "You have been recruited by GodFather!", "MissChance": "Chance To Miss", "IncreaseByOneIfConvert": "Increase The KillCount +1 If a Crew Is Converted", "HawkMissed": "Missed!", @@ -2824,7 +2759,6 @@ "BerserkerToWar": "You have become War!!!", "BerserkerTransform": "The Berserker has transformed into War, Horseman of the Apocalypse! Cry 'Havoc!', and let slip the dogs of war.", "WarKillCooldown": "War kill cooldown", - "BerserkerCanKillTeamate": "Can kill other Neutral Apocalypse", "BlackmailerSkillCooldown": "Blackmail Cooldown", "BlackmailerMax": "Maximum times blackmailed players may speak", "BlackmailerDead": "Warning! {0} has been blackmailed by a Blackmailer!", @@ -2914,8 +2848,6 @@ "RememberedPursuer": "You remembered you were a Pursuer!", "RememberedFollower": "You remembered you were a Follower!", "RememberedAmnesiac": "You failed to remember your role.", - "AmnesiacRemembered": "You remembered you were {0}!", - "ReportWhenFailedRemember": "Report Dead Body when failed to remember", "RememberedImitator": "You remembered you were an Imitator.", "RememberedImpostor": "You remembered you were an Impostor!", "RememberedCrewmate": "You remembered you were a crewmate!", @@ -3329,12 +3261,9 @@ "PixieTargetAlreadySelected": "Target is already selected", "PixieButtonText": "Mark", "PlagueBearerCooldown": "Plague cooldown", - "PlagueBearerCanVent": "Can vent", - "PlagueBearerHasImpostorVision": "Has Impostor vision", "PestilenceCooldown": "Pestilence Kill cooldown", "PestilenceCanVent": "Pestilence Can Vent", "PestilenceHasImpostorVision": "Pestilence Has Impostor Vision", - "PestilenceKillGuessers": "Kill players who guess Pestilence", "PlagueBearerAlreadyPlagued": "Player has already been plagued", "PlagueBearerToPestilence": "You have turned into Pestilence!!", "GuessPestilence": "You just tried to guess Pestilence!\n\nSorry, Pestilence killed you.", @@ -3378,7 +3307,6 @@ "EveryoneCanKnowMini": "Everyone can see the Mini", "CanBeEvil": "Mini can be an Impostor", "EvilMiniSpawnChances": "Probability of Mini being an Impostor", - "EvilMiniCanBeGuessed": "Evil Mini can be guessed before 18", "GuessMini": "Sorry, you can't hurt a kid Mini.", "GrowUpDuration": "Time required to grow (s)", "MajorCooldown": "Kill Cooldown when over 18", @@ -3520,7 +3448,6 @@ "WinnerRoleText.Doppelganger": "Doppelganger Wins!", "WinnerRoleText.Quizmaster": "Quizmaster Wins!", "WinnerRoleText.Agitater": "Agitator Wins!", - "WinnerRoleText.Shocker": "Shocker Wins!", "AdditionalWinnerRoleText.Sidekick": "Sidekick", "AdditionalWinnerRoleText.Taskinator": "Taskinator", "AdditionalWinnerRoleText.Opportunist": "Opportunist", @@ -3606,7 +3533,7 @@ "SolsticerOnMeeting": "You witnessed too many deaths! Next round you will have {0} more short task!", "SolsticerTitle": "Solsticer", "GuessSolsticer": "Sorry, but you can not guess Solsticer!", - "ExpelSolsticer": "Sorry, but you can not expel Solsticer!", + "VoteSolsticer": "Sorry, but you can not vote Solsticer!", "SolsticerTasksReset": "Your tasks get reset!", "SolsticerMisGuessed": "You just misguessed! You are no longer allowed to guess.", "SolsticerGuessMax": "Because you already misguessed, you are no longer allowed to guess.", @@ -3707,28 +3634,6 @@ "MinionAbilityTime": "Ability Duration", "Minion_Blind": "blinded", "Evader_ChanceNotExiled": "Chance not be exiled", - "ShockerAbilityCooldown": "Ability Cooldown", - "ShockerAbilityDuration": "Ability Duration", - "ShockerAbilityPerRound": "Abilities Per Round", - "ShockerShockInVents": "Shock people in vents", - "ShockerAbilityResetAfterMeeting": "Reset marked rooms after meeting", - "ShockerOutsideRadius": "Radius Of Outside Tasks (not in a room)", - "ShockerCanShockHimself": "Can Shock Himself", - "ShockerImpostorVision": "Shocker has Impostor vision", - "ShockerIsShocking": "You're already shocking!", - "ShockerAbilityActivate": "Begin Shocking!", - "ShockerAbilityDeactivate": "Ability Deactivated", - "ShockerVentButtonText": "Shock", - "ShockerRoomMarked": "Marked Room", "EavesdropperMsgTitle": "You found a secret", - "EavesdropPercentChance": "Chance to eavesdrop", - "ChiefOfPoliceSkillCooldown": "Cooldown for recruiting sheriffs", - "PolicCanImpostorAndNeutarl": "Can recruit Impostor or Neutral", - "SheriffSuccessfullyRecruited": "You recruited a sheriff.", - "BeSheriffByPolice": "You've been recruited by the police chief! Serve the crew!", - "PoliceFailedRecruit": "Failed to recruit target.", - "ChiefOfPoliceKillButtonText": "Recruitment", - "PolicPreventRecruitNonKiller": "Prevent recruit players without kill button", - "PolicSuidiceWhenTargetNotKiller": "Suidices when recruit a non killer or non crewmate", - "PolicPassConverted": "Can pass Converted Addon to Sheriff" -} \ No newline at end of file + "EavesdropPercentChance": "Chance to eavesdrop" +} diff --git a/Resources/Lang/nl_NL.json b/Resources/Lang/nl_NL.json index 5ce90c3af..0e18b9ec3 100644 --- a/Resources/Lang/nl_NL.json +++ b/Resources/Lang/nl_NL.json @@ -19,8 +19,6 @@ "SubText.Neutral": "Werk alleen om je overwinning te behalen", "SubText.Apocalypse": "Become unstoppable with your team", "SubText.Madmate": "Help de Bedriegers", - "SubText.Lovers": "Stay alive and win together", - "SubText.Egoist": "Win on your own", "TypeImpostor": "Bedriegers", "TypeCrewmate": "Bemanningsleden", "TypeNeutral": "Neutralen", @@ -30,9 +28,6 @@ "TeamNeutral": "Neutraal", "TeamCrewmate": "Bemanningslid", "TeamMadmate": "Gekke", - "TeamLovers": "Lovers", - "TeamEgoist": "Egoist", - "TeamApocalypse": "Apocalypse", "YouAreCrewmate": "Je bent een Bemanningslid", "YouAreImpostor": "Je bent een Bedrieger", "YouAreNeutral": "Je bent een Neutraal", @@ -224,7 +219,6 @@ "TaskManager": "Taakmanager", "Witness": "Getuige", "Swapper": "Swapper", - "ChiefOfPolice": "Chief of Police", "NiceMini": "Goeie Mini", "Mini": "Goeie Mini", "Spy": "Spion", @@ -253,7 +247,6 @@ "Stalker": "Stalker", "Workaholic": "Werkverslaafde", "Solsticer": "Zonnewende", - "Abyssbringer": "Abyssbringer", "Collector": "Verzamelaar", "Provocateur": "Provocateur", "BloodKnight": "Bloedsridder", @@ -392,8 +385,6 @@ "Sloth": "Sloth", "Prohibited": "Prohibited", "Eavesdropper": "Eavesdropper", - "Shocker": "Shocker", - "Revenant": "Revenant", "BracketAddons": "Voeg brackets toe aan toevoegingen", "EngineerTOHEInfo": "Gebruik de vents om de Bedriegers te vinden", "ScientistTOHEInfo": "Heb overal toegang tot draagbare vitale functies", @@ -512,7 +503,6 @@ "PacifistInfo": "Vent to reset kill cooldowns", "RebirthInfo": "Arise Again", "MonarchInfo": "Geef de bemanning extra stemkracht!", - "AbyssbringerInfo": "Create Black Holes", "SpurtInfo": "Spring Like A rabbit!", "StealthInfo": "Als je blinden doodt, wordt iedereen in de kamer gedood", "PenguinInfo": "Sleep je slachtoffers", @@ -546,7 +536,6 @@ "WitnessInfo": "Kom erachter of iemand recent een ander heeft vermoord", "GhastlyInfo": "Control somebody!", "SwapperInfo": "Verwissel de stemmen van twee spelers", - "ChiefOfPoliceInfo": "Hire Sheriff to Serve the Crews!", "NiceMiniInfo": "Niemand kan je pijn doen totdat je gegroeid bent.", "ArsonistInfo": "Blus iedereen en verbrand", "PyromaniacInfo": "Blus en dood iedereen", @@ -707,8 +696,6 @@ "SlothInfo": "You're slower", "ProhibitedInfo": "Certain vents are blocked", "EavesdropperInfo": "Listen in on other roles", - "ShockerInfo": "Shock unsuspecting players", - "RevenantInfo": "Take your killer's role", "EngineerTOHEInfoLong": "(Bemanningslid):\nAls de werktuigkunde heb je toegang tot de vents terwijl een Comms Sabotage inactief is.", "ScientistTOHEInfoLong": "(Crewmates):\nAs the Scientist, you can see vitals at any time, showing you who is alive and dead.", "NoisemakerTOHEInfoLong": "(Crewmates):\nAs the Noisemaker, whenever you die, you will make a noise, and a visual indicator of your death appears on the screen so the Crewmates can run to catch the person who killed you red-handed (even if it’s not Red).", @@ -780,11 +767,11 @@ "LurkerInfoLong": "(Impostors):\nAs the Lurker, you can jump into a vent to reduce your cooldown by a certain number of seconds. After you kill, your cooldown resets to its original value.", "VisionaryInfoLong": "(Impostors):\nAs the Visionary, you see the alignments of living players during a meeting.\nThe following information will be displayed on the players:\n- The Red name indicates the Impostors.\n- The Cyan name indicates the Crewmates.\n- The Gray name indicates the Neutrals.", "PlagueDoctorInfoLong": "(Neutrals):\n(Plague Doctor from TOH)\nThe Plague Scientist's goal is to infect every living player.\nThey start by choosing one player to infect, after which anyone who spends a set amount of time in the range of the infected player becomes infected themselves.\nInfection progress is cumulative and does not reset with distance or after meetings.", - "RefugeeInfoLong": "(Madmates):\nAs the Refugee, you were either:\n -An Amnesiac who remembered an Impostor\n -A killer who killed the Godfather's target.\n -A Romantic whose partner was an Impostor\n -Or an Imitator that imitated an Impostor.\n\nNow your job is to help the Impostors kill the crewmates.", + "RefugeeInfoLong": "(Madmates):\nAs the Refugee, you were either an Amnesiac who remembered an Impostor or a killer who killed the Godfather's target.\n\nNow your job is to help the Impostors kill the crewmates.", "UnderdogInfoLong": "(Bedriegers):\nAls Underdog kun je niet doden totdat er een bepaald aantal spelers in leven is.", "ConsigliereInfoLong": "(Impostors):\nAs the Consigliere, you can reveal the roles of other players using your kill button.\n\nSingle click: Reveal role\nDouble click: Kill\n\nIf you run out of reveal uses, your kill button functions normally.", "LudopathInfoLong": "(Bedriegers):\nDe Ludopaat zijn kill cooldown is willekeurig.\nDit is minimaal 1 seconde en maximaal je normale kill cooldown.", - "GodfatherInfoLong": "(Impostors):\nAs the Godfather, you vote someone to make them your target.\nIn the next round, if someone kills the target, the killer will turn into a Refugee or Madmate.", + "GodfatherInfoLong": "(Impostors):\nAs the Godfather, you vote someone to make them your target.\nIn the next round, if someone kills the target, the killer will turn into a Refugee.", "ChronomancerInfoLong": "(Impostors):\nAs the Chronomancer, you have a charge bar which indicates when the slaughter is ready. When it is at 100% the next time you kill someone, you go into slaughter mode, meaning you can kill indefinitely until your bar runs out of charge. Otherwise, you have a normal KCD.", "PitfallInfoLong": "(Impostors):\nAs the Pitfall, you use your shapeshift to mark the area around the shapeshift as a trap. Players who enter this area will be immobilized quickly, and their vision will be affected.", "EvilMiniInfoLong": "(Impostors):\nAs the Evil Mini, you are unkillable until you grow up and have a very long initial kill cooldown, which gets drastically shortened as you grow up.", @@ -856,7 +843,6 @@ "TaskManagerInfoLong": "(Crewmates):\nYou see the total number of tasks completed (by everyone all together) next to your role name, which updates in real-time.", "WitnessInfoLong": "(Crewmates):\nAs the Witness, when you use your kill button on someone, you will know if they killed in the last X seconds or not. (X depends on the settings).", "SwapperInfoLong": "(Crewmates):\nAs the Swapper, you can swap votes in meetings.\n\nTo swap votes, use '/sw [playerID]' twice.\n\nPlayer IDs are displayed next to player names in meetings, but you can also use /id to get a list of all player IDs.\n\nNote: Depending on the Host's settings, you can exchange your own votes.", - "ChiefOfPoliceInfoLong": "(Crewmates):\nPlayers with swords can be recruited to join the sheriff's team to serve the crew\nNote: only one recruitment opportunity\nDepending on settings, you may recruit non killers or non crews.\nYou may suidice for recruiting wrong target.", "NiceMiniInfoLong": "(Crewmates):\nAs a Nice Mini, your survival is crucial. You can't be killed until you grow up, and if you die or are evicted from the meeting before you grow up, everyone loses. This unique role adds a new dynamic to the game, where your survival is not just for your benefit but for the entire Crew's success.", "SpyInfoLong": "(Crewmates):\nAs the Spy, when someone uses their kill button on you (any ability used through the kill button), you'll see their name in orange for a few seconds.\nNote: If a Crewmate used their ability on you, you'll also see them with an orange name!\nNote: If you cannot use left, you won't see orange names!\nNote: If the kill button interaction is blocked, the player's cooldown will reset to 10s'", "RandomizerInfoLong": "(Crewmates):\nAs this Randomizer, when you die, your killer will do one of the following:\n 1. self-report your body\n 2. stand next to your body\n 3. have their kill cooldown set to 600s\n 4. Randomly avenge a player.", @@ -871,7 +857,7 @@ "LawyerInfoLong": "(Neutralen):\nDe Advocaat heeft een doelwit die ze moeten verdedigen. Dit doelwit wordt aangegeven met een diamant 「♦」 naast hun naam.\nAls je doelwit wint, win jij ook. \nAls die verliest, verlies jij ook.", "OpportunistInfoLong": "(Neutralen):\nAls de Opportunist aan het einde van het spel overleeft, wint de Opportunist met de winnende speler.", "VectorInfoLong": "(Neutrals):\nVector will win alone by venting a certain number of times.", - "JackalInfoLong": "(Neutrals):\nAs the Jackal, you win if you are the last player alive. Additionally, you may recruit using the kill button. If the target is not one you can recruit, you have run out of uses, or you don't have the option to recruit, then you will kill people normally (i.e., don't use kill buttons in front of others thinking it'll recruit). If the target has a kill button and the option to turn into a Sidekick is on, they will become a Sidekick. Otherwise, they will gain the Recruit add-on if the option to give the Recruit add-on is on.\nDepending on the settings, when Jackal was killed, a Sidekick will be randomly selected as the new Jackal.\nRecruit may be selected if no sidekick is alive.", + "JackalInfoLong": "(Neutrals):\nAs the Jackal, you win if you are the last player alive. Additionally, you may recruit using the kill button. If the target is not one you can recruit, you have run out of uses, or you don't have the option to recruit, then you will kill people normally (i.e., don't use kill buttons in front of others thinking it'll recruit). If the target has a kill button and the option to turn into a Sidekick is on, they will become a Sidekick. Otherwise, they will gain the Recruit add-on if the option to give the Recruit add-on is on.", "GodInfoLong": "(Neutrals):\nAs the God, you know everyone's role from the beginning. If you live until the end of the game, you steal the win, i.e., everyone else loses, and you win.", "InnocentInfoLong": "(Neutrals):\nThe Innocent can use the kill button to plant any player, and the planted target will immediately kill the Innocent. If the target gets voted out in the meeting, the Innocent wins. Note: Jester, Executioner, and Innocent can win together.", "PelicanInfoLong": "(Neutrals):\nAs the Pelican, you can use the kill button to swallow a player alive, teleporting them off-bounds but not killing them yet. Those swallowed will only die if you're still alive at the end of the round. If you die or leave during the round, all alive swallowed players will spawn into the map where you were.", @@ -883,7 +869,7 @@ "SolsticerInfoLong": "(Neutrals):\nAs the Solsticer, you won't die, and you win by finishing all your tasks in a single round. After every meeting finishes, your tasks reset, and you need to start all over again.\nVotes on the Solsticer will be directly canceled.\nKill attempts on the Solsticer will teleport it out of the map like Pelican until the meeting is finished.\nThe killer's kill cooldown will be reset to 10 seconds.\nSolsticer is counted as nothing in-game.", "CollectorInfoLong": "(Neutrals):\nAs the Collector, when you vote for a player, for each other player that voted for them, you gain a point. When you collect the required votes, the game ends, and you win alone, even if you voted a Jester or Executioner's target out.", "GlitchInfoLong": "(Neutrals):\nAs the Glitch, you can hack players (single click) or kill normally (double click).\nThose who have been hacked cannot kill, vent, or report for the hack duration.\nAdditionally, calling a sabotage other than doors will have no effect and will instead disguise you as a random player. You cannot disguise during or after sabotages.\nTo win, be the last player alive.", - "SidekickInfoLong": "(Neutrals):\nAs the Sidekick, your job is to help the Jackal kill everyone.\nYou and the Jackal win together.\nDepending on the settings, you may turn into Jackal if old Jackal was killed.\nYou may not be able to kill until old Jackal is dead.", + "SidekickInfoLong": "(Neutralen):\nAls het Hulpje is het jouw taak om de Jakhals te helpen met iedereen te vermoorden. \n\nJij en de Jakhals winnen samen.", "ProvocateurInfoLong": "(Neutralen):\nAls Provocateur kun je een keer iemand doden met de kill knop. Als het doelwit aan het einde van het spel verliest, wint de Provocateur met het winnende team.", "BloodKnightInfoLong": "(Neutrals):\nThe Blood Knight wins when they're the last killing role alive, and the amount of crewmates is lower or equal to the amount of Blood Knights. The Blood Knight gains a temporary shield after every kill, making them immortal for a few seconds.", "PlagueBearerInfoLong": "(Apocalypse):\nAs the Plaguebearer, plague everyone using your kill button to turn into Pestilence.\nOnce you turn into Pestilence, you will become immortal and gain the ability to kill, and you will kill anyone who tries to kill you.\n\nAlso, when infected players interact with uninfected players, they will also be infected.", @@ -910,12 +896,11 @@ "TraitorInfoLong": "(Neutrals):\nAs the Traitor, you were an Impostor that betrayed the Impostors.\nYou know the Impostors, but they don't know you.\nThe twist? They can kill you, but you can't kill them.\n\nEliminate the Impostors by other means, then kill everyone else to win!", "TrollerInfoLong": "(Neutrals):\nAs a Troller, you can complete tasks so that random events can happen to players.\nFor example, changing the speed of all players, teleportation, influencing sabotage, etc.\nAlso you can win with the winning team.", "VultureInfoLong": "(Neutralen):\nMeld als de Gier lichamen om te winnen!\n\nAls je een lichaam rapporteert en de cooldown voor eten is verstreken, eet je het lichaam op (waardoor het niet meer kan worden gerapporteerd).\nAls jouw vaardigheid nog steeds cooldown heeft, rapporteer je het lichaam als normaal.", - "AbyssbringerInfoLong": "(Impostors):\nAs the Abyssbringer, you can place black holes. Black holes will suck in players and kill them when colliding with them.", "TaskinatorInfoLong": "(Neutrals):\nAs the Taskinator, whenever you finish a task, the task will be bombed. When another player completes the bombed task, the bomb will detonate, and the player will die.\n\nYou win if you survive till the end and Crew doesn't win.\n\n Note: Taskinator bombs ignore all protection.", "BenefactorInfoLong": "(Crewmates):\nAs the Benefactor, whenever you finish a task, that task will be marked. When another player completes the marked task, they get a temporary shield.\n\n Note: Shield only protects from direct kill attacks.", "MedusaInfoLong": "(Neutralen):\nAls Medusa kun je lichamen verstenen, net zoals je een lichaam schoonmaakt.\nVersteende lichamen kunnen niet worden gerapporteerd.\n\nDood iedereen om te winnen.", "SpiritcallerInfoLong": "(Neutrals):\nAs the Spiritcaller, your victims become Evil Spirits after they die. These spirits can help you win by freezing other players briefly or blocking their vision. Alternatively, the spirits can give you a shield that protects you briefly from an attempted kill.", - "AmnesiacInfoLong": "(Neutrals):\nAs the Amnesiac, use your report button to remember a target and get its role.\nTo balance the game, you will not be able to vent after remembering your role if you can't vent as Amnesiac.'", + "AmnesiacInfoLong": "(Neutralen)\nAls Vergeetachtige kan je de rapporteer knop gebruiken om een rol te herinneren\n\nAls jouw lijk een Bedrieger was, wordt je een Vluchteling\nAls jouw lijk een Bemanningslid was, wordt je hetzelfde rol als dat mogelijk is\nAls jouw lijk een passieve neutraal was of onbekende neutrale moordenaar, krijg je een willekeurige rol afhankelijk van instellingen\nAls jouw lijk een neutrale moordenaar was, wordt jij dezelfde rol.", "ImitatorInfoLong": "(Neutrals):\nAs the Imitator, use your kill button to imitate a player.\n\nYou'll either become a Sheriff, a Refugee, or some Neutral.", "BanditInfoLong": "(Neutrals):\nAs the Bandit, you can click your kill button one time to steal a player's addon and twice to kill. Depending on the settings, you may instantly steal the addon or after the meeting starts. After the maximum number of steals is reached, you will kill normally. Additionally, if there are no stealable addons on the target or the target is stubborn, you will kill the target.\n\nKill everyone to win.\n\nNote: Cleansed, Last Impostor, and Lovers cannot be stolen.\nNote: If Bandit can vent is on, Nimble will become unstealable.", "DoppelgangerInfoLong": "(Neutrals):\nAs the Doppelganger, use your kill button to steal a player's identity (their name and skin) and then kill your target.\n\nKill everyone to win.\n\nNote: You cannot steal the target's identity when Camouflage is active.", @@ -936,7 +921,6 @@ "JinxInfoLong": "(Neutrals):\nAs the Jinx, whenever you get attacked, you jinx them, resulting in them dying to a jinx.\nThis has limited uses.\n\nKill off everyone to win.", "PotionMasterInfoLong": "(Neutrals):\nAs the Potion Master, you have three different potions assigned to three different actions.\n\nSingle click: Reveal role\nDouble click: Kill\nMap: Sabotage\n\nThe reveal potion has a limit.\nWhen you run out, the kill buttons default to killing.", "NecromancerInfoLong": "(Neutrals):\nAs the Necromancer, you win when you're the last one standing.\nAdditionally when someone tries to kill you, you will block the kill, and you will teleport to a random vent. You will have a limited time to kill your killer. If you succeed in doing so, you live. If the time runs out before you kill your killer, you die permanently. If you try to kill someone else other than your killer, you will die.", - "ShockerInfoLong": "(Neutrals):\nAs the Shocker, you can mark rooms by doing tasks in them, and then vent to Electrocute anyone in those rooms for a set period of time. When you finish all of your tasks, you get new ones. Note: Doing tasks during that period will mark them for the next ability use.", "LastImpostorInfoLong": "(Add-ons):\nThis special effect is given to the last surviving Impostor. It significantly reduces their kill cooldown.", "OverclockedInfoLong": "(Add-ons):\nAs the Overclocked, your kill cooldown is reduced by a percentage.\n\nThis feature is only assigned to roles with a kill button.", "LoversInfoLong": "(Add-ons):\nLovers are a combination of two players. The Lovers win when they are the last ones standing, and their victory is shared. When one of the Lovers wins, the other also wins together. Lovers can see the 「♥」 next to each other's name. If one of the Lovers dies, the other will die in love (may not die in love according to the Host's settings). When one of the Lovers is exiled in the meeting, the other will die and become a dead body that cannot be reported.", @@ -980,7 +964,7 @@ "RebirthInfoLong": "(Add-ons):\nAs the Rebirth, if you're the player about to be ejected, you will swap skins with a random crewmate who voted for you.\nNotice: The host vote never counts\nRebirth will be removed from you if you exhausted all your rebirths.", "LoyalInfoLong": "(Add-ons):\nAs the Loyal, you cannot be recruited by roles such as Jackal or Cultist.\n\nCannot be assigned to neutrals.", "EvilSpiritInfoLong": "(Add-ons):\nAs Evil Spirit, it's your job to help the Spiritcaller to victory. You can use your Haunt button to freeze players and reduce their vision. Alternatively, you can use your Haunt button to give the Spiritcaller a shield against a kill attempt temporarily.", - "RecruitInfoLong": "(Betrayal Add-ons):\nAs a recruit, you are on the Jackal's team and help out the Jackal and their Sidekicks.\nYou cannot win with your original team.\nDepending on the settings, you may turn into Jackal if old Jackal was killed and no sidekicks is alive.", + "RecruitInfoLong": "(Betrayal Add-ons):\nAs a recruit, you are on the Jackal's team and help out the Jackal and their Sidekicks.\n\nYou cannot win with your original team.", "AdmiredInfoLong": "(Betrayal Add-ons):\nAs an admired player, you win with the crew and not your original team.\n\nYou can see the Admirer.", "GlowInfoLong": "(Add-ons):\nDuring lights out, you and players nearby you will receive a vision boost.", "RadarInfoLong": "(Add-ons):\nAs Radar, you have arrows pointing towards the closest person at all times.", @@ -1024,7 +1008,6 @@ "ProhibitedInfoLong": "(Add-ons):\nAs the Prohibited, you have specific vents that you can't use.\nHow many vents are disabled depends on the Host's settings.", "EavesdropperInfoLong": "(Add-ons):\nAs the Eavesdropper, you have a chance to read other role/addon information-based messages like Mortician or Sleuth.", "ApocalypseInfoLong": "(Apocalypse):\nApocalypse members are on a separate team that works together and wins together. If there are multiple Apocalypse roles in the game, they can see each other's roles.\nDepending on the Host's settings, Apocalypse roles can guess or be guessed.", - "RevenantInfoLong": "(Neutral):\nAs the Revenant, your goal is to be killed. If you are killed, you will take your killer's role and kill your killer instead. You cannot win before being killed.\nNote that Revenant only works when being directly killed.", "ShowTextOverlay": "Tekst Overlay", "Overlay.GuesserMode": "Gokker Modus", "Overlay.NoGameEnd": "No Game End", @@ -1038,8 +1021,6 @@ "AbilityUseLimit": "Initiële ability gebruikslimiet", "AbilityInUse": "Ability in use", "AbilityExpired": "Ability expired, {0} uses remain", - "RevenantTargeted": "Your role has changed to {0}", - "RevenantCanCopyAddons": "Can Steal Addons", "ShowArrows": "Heeft wijzende pijlen naar dode lichamen", "ArrowDelayMin": "Minimale pijl verschijning vertraging", "ArrowDelayMax": "Maximale pijl verschijning vertraging", @@ -1368,8 +1349,6 @@ "ShieldedCanUseKillButton": "Shielded player can use ability / kill button", "PlayerIsShieldedByGame": "Player is protected by the game!", "LegacyNemesis": "Use Legacy Version", - "LegacyParasite": "Use Legacy Version", - "LegacyTraitor": "Use Legacy Version", "ArsonistKeepsGameGoing": "Brandstichter houdt het spel gaande", "ArsonistCanIgniteAnytime": "Kan vuur altijd aansteken", "ArsonistMinPlayersToIgnite": "Minimum doused needed for ignite", @@ -1512,18 +1491,6 @@ "SheriffCanKillSeparately": "Individuele Instellingen", "In%team%": "(Team %team%)", "SheriffMisfireKillsTarget": "Misfire Kills Target", - "BlackHolePlaceCooldown": "Black Hole Place Cooldown", - "BlackHoleDespawnMode": "Black Hole Despawn Mode", - "BlackHoleDespawnTime": "Time After Black Hole Despawns", - "Abyssbringer.Suffix": "<#00ffa5>Number of players consumed by {0} <#00ffa5>active black holes:\\n{1}", - "Abyssbringer.Suffix.BlackHole": "<#00ffa5>{0}: {1}", - "BlackHoleMovesTowardsNearestPlayer": "Black Hole Moves Towards Nearest Player", - "BlackHoleMoveSpeed": "Black Hole Moving Speed", - "BlackHoleRadius": "Black Hole Consuming Radius", - "AfterTime": "After Time", - "After1PlayerEaten": "After 1 Player Was Eaten", - "AfterMeeting": "After Meeting", - "None": "None", "SheriffShotLimit": "Max number of Kills", "SheriffCanKillAllAlive": "Can Kill When No One Is Dead", "SheriffCanKillCharmed": "Kan Gecharmeerde spelers doden", @@ -1540,15 +1507,12 @@ "RebirthUses": "Amount of Rebirths", "RebirthCountVotes": "Only rebirth to players who voted for them", "RebirthFailed": "Ahh, how unfortunate, you did not find any viable souls to swap bodies with", - "FireworkerCooldown": "Placement Cooldown", "ReverieIncreaseKillCooldown": "Verhoging kill cooldown", "ReverieMaxKillCooldown": "Maximale kill cooldown", "ReverieMisfireSuicide": "Misfire on reaching max kill cooldown", "ReverieResetCooldownMeeting": "Herstart kill cooldown na vergadering", "ConvertedReverieKillAll": "Converted Reverie can kill anyone without repercussions", "VigilanteNotify": "Je bent precies datgene geworden waarvan je hebt gezworen het te vernietigen", - "DictatorChangeCommandToExpel": "Dictator use Command to expell instad of vote", - "DictatorExpelSelf": "WAIT WAIT WAIT WAT THE HELLLLLL Bro really just want to expel himself", "DoctorTaskCompletedBatteryCharge": "Batterij Tijdsduur", "SnitchEnableTargetArrow": "See Arrow Towards Target", "SnitchCanGetArrowColor": "See Colored Arrows based on Team Colors", @@ -1629,7 +1593,6 @@ "EvilTrackerTargetMode.OnceInGame": "Once in-game", "EvilTrackerTargetMode.EveryMeeting": "Elke vergadering", "EvilTrackerTargetMode.Always": "Any time", - "ScavengerHasCustomDeathReason": "Enable Custom Death Reason", "EvilHackerCanSeeDeadMark": "Can See The Location of Dead-bodies", "EvilHackerCanSeeImpostorMark": "Can See The Location of Other Impostors", "EvilHackerCanSeeKillFlash": "Can See Kill-Flash", @@ -1862,21 +1825,13 @@ "Jackal_SidekickCountMode_Jackal": "Jackal", "Jackal_SidekickCountMode_Original": "Original Team", "Jackal_SidekickAssignMode": "Sidekick Assign Mode", - "Jackal_SidekickAssignMode_SidekickAndRecruit": "Sidekick when failed Recruit", - "Jackal_SidekickAssignMode_Sidekick": "Only Sidekick", - "Jackal_SidekickAssignMode_Recruit": "Only Recruit", + "Jackal_SidekickAssignMode_SidekickAndRecruit": "Sidekick+Recruit", + "Jackal_SidekickAssignMode_Sidekick": "Sidekick Only", + "Jackal_SidekickAssignMode_Recruit": "Recruit Only", + "JackalWinWithSidekick": "Jakhals kan winnen met Hulpje's team", "Jackal_SidekickCanKillSidekick": "Sidekicks can kill other Sidekicks", "Jackal_SidekickCanKillJackal": "Sidekick can kill Jackal", - "Jackal_RecruitFailed": "You can not recruit this player!", "JackalCanKillSidekick": "Jakhals kan Hulpje doden", - "Jackal_SidekickCanKillWhenJackalAlive": "Sidekick can kill while Jackal is Alive", - "Jackal_SidekickTurnIntoJackal": "Sidekick can turn into Jackal after its death", - "Jackal_RestoreLimitOnNewJackal": "Restore Recruit limit when Sidekick become new Jackal", - "Jackal_OnBecomeNewJackalMeeting": "The old Jackal {0} is dead.\nYou are selected as new Jackal\nWork together and win the game!", - "Jackal_OnNewJackalSelectedMeeting": "The old Jackal {0} is dead.\n{1} is selected as new Jackal!\nWork together and win the game!", - "Jackal_BecomeNewJackal": "Old Jackal Dead, You are now new Jackal!", - "Jackal_OnNewJackalSelected": "Old Jackal Dead, Please help new Jackal {0} for now!", - "Jackal_BossIsDead": "Opps, the Jackal boss is dead!", "CoronerArrowsPointingToDeadBody": "Arrows pointing to dead bodies", "CoronerLeaveDeadBodyUnreportable": "Bodies the Coroner uses can't be reported", "CoronerInformKillerBeingTracked": "Inform the Killer that he gets tracked", @@ -1914,9 +1869,6 @@ "VipTag": "VIP★", "ApplyVipList": "Apply VIP List", "AllowSayCommand": "Allow moderators to use /say command", - "AllowStartCommand": "Allow moderators to use /start command", - "StartCommandMinCountdown": "Minimum countdown for /start command", - "StartCommandMaxCountdown": "Maximum countdown for /start command", "KickCommandDisabled": "The kick command is currently disabled.", "KickCommandNoAccess": "You do not have access to the kick command.", "KickCommandInvalidID": "Invalid player ID specified.\nPlease use '/kick [playerID] [reason]' to kick a player.\nExample :- /kick 5 not following rules", @@ -1949,11 +1901,6 @@ "WarnCommandNoAccess": "You do not have access to the warn command.", "WarnCommandInvalidID": "Invalid player ID specified.\nPlease use '/warn [playerID] [reason]' to warn a player. \nExample :- /warn 5 lava chatting", "WarnCommandWarnHost": "You are not permitted to warn the host.", - "StartCommandNoAccess": "You do not have access to the start command.", - "StartCommandDisabled": "The start command is currently disabled.", - "StartCommandCountdown": "ERROR\n\nThe game is already starting!", - "StartCommandStarted": "The game has been started by {0}!", - "StartCommandInvalidCountdown": "ERROR\n\nThe countdown must be between {0} and {1}!", "WarnCommandWarnMod": "You are not permitted to warn other moderators.", "WarnCommandWarned": "has been warned. There will be no more warnings given and appropriate action will be taken \n ", "WarnExample": "Use /warn [id] [reason] in future. \nExample :-\n /warn 5 lava chatting", @@ -1981,7 +1928,6 @@ "DeathReason.Quantization": "Quantization", "DeathReason.Overtired": "Uitgeput", "DeathReason.Ashamed": "Beschaamd", - "DeathReason.Consumed": "Consumed", "DeathReason.PissedOff": "Vernietigd", "DeathReason.Dismembered": "Dismembered", "DeathReason.LossOfHead": "Gewurgd", @@ -2005,8 +1951,6 @@ "DeathReason.Starved": "Starved", "DeathReason.Equilibrium": "Equilibrium", "DeathReason.Sacrificed": "Sacrificed", - "DeathReason.Electrocuted": "Electrocuted", - "DeathReason.Scavenged": "Scavenged", "OnlyEnabledDeathReasons": "Only Enabled Death Reasons", "Alive": "In Leven", "Disconnected": "Disconnected", @@ -2072,7 +2016,6 @@ "Command.dump": "→ Output Log to Desktop", "Command.death": "→ Display info on how you died", "Command.icons": "
╳ - The Player was marked by the Blackmailer and can't talk during the Meeting
☆ - Used by Captain to display themselves. Only Crewmates can see the Captain's star
乂 - This player was hexed by the Hex Master and will die if the Hex Master isn't killed or ejected by the end of the Meeting.
♦ - Used by Lawyer or Executioner or Follower.
♥ - Used by Lovers or Romantic.
✚ - Used by Medic to mark their target.
⦿ - This player is in a duel with the Pirate.
!? - This player was marked by the Quizmaster and must answer the question correctly to survive.
☜ - Used by Schrödinger's cat to mark their teammate.
◈ - This player marked by the Shroud and will die if the Shroud is not killed or ejected by the end of the meeting.
⚠ - This player is a Snitch or Solsticer who has finished their tasks.
★ - Used by Super Star or Cyber or Marshall.
† - This player was spelled and will die if the Witch is not killed by the end of the meeting.
∇ - Used by Kamikaze to mark their targets.
■ - Used by Lightning to mark their quantum ghosts.
⊠ - Used by Jailer to mark their prisoner.
● - Used by Baker to mark who has Bread.
♠ - Used by Soul Collector to mark who's death they're predicting.
⦿ - Used by Plaguebearer to mark who they have plagued.", - "Command.start": "[Seconds] → Start the game", "Command.iconinfo": "→ Display info on in-meeting icons", "Command.iconhelp": "→ Display info on in-meeting icons to everyone", "Command.Poll": "→ Start a poll with up-to 5 choices", @@ -2085,7 +2028,6 @@ "ShowMadmatesInLeftCommand": "Show Madmates (including add-ons)", "ShowApocalypseInLeftCommand": "Show Neutral Apocalypse", "SeeEjectedRolesInMeeting": "See ejected roles in meetings", - "ThankYouForUsingTOHE": "Thank you for using TOHE!", "SkillUsedLeft": "You have activated your skill to call a meeting. \nRemaining amount of uses left:", "NemesisDeadMsg": "The death of the Nemesis means the beginning of the revenge. \nPlease use /rv + [player ID] to kill the specified player \nYou can see player IDs in front of their names. \nOr type /rv to get a list of player IDs", "NemesisAliveKill": "Revenge for the Nemesis can only begin after their death.", @@ -2105,7 +2047,6 @@ "GuessNotifiedBait": "Bait can't be guessed because it was announced. You thought it would be that easy, right?", "GuessGM": "Guessing the GM is impossible because they're already dead.... And why would you do that to the poor Host?", "GuessGuardianTask": "You can't guess a Guardian who has finished their tasks.", - "GuardianCantKilled": "You can't kill a Guardian who has finished their tasks.", "GuessMarshallTask": "You can't guess a Marshall who has finished their tasks.", "GuessObviousAddon": "Sorry, obvious add-ons cannot be guessed.", "GuessAdtRole": "Unfortunately, the Host's settings do not allow you to guess add-ons", @@ -2161,7 +2102,6 @@ "BecomeMadmateCuzMadmateMode": "Je bent een Gekke geworden omdat je stierf", "CleanerCleanBody": "The body has been cleaned", "QuickShooterStoraging": "Bullets stored successfully", - "QuickShooterFailed": "You are still in cooldown.", "PoisonerTargetDead": "Doelwit gestorven", "HexesLookLikeSpells": "Hexes appear as spells", "HexButtonText": "Hex", @@ -2320,7 +2260,6 @@ "Message.YTPlanNotice": "Note: The [YouTuber Plan] is enabled in this lobby, which means the Host can specify their role in the next game to make it easier to get content. If the Host abuses this feature, please exit the game or report it.\nCurrent Creator Credentials:", "Message.OnlyCanBeUsedByHost": "ERROR\n\nThis command may only be used by the host.", "Message.MaxPlayers": "Maximum players set to ", - "Message.MaxPlayersFailByRegion": "Could not set max players: Vanilla regions support a maximum of 15 players.", "Message.GhostRoleInfo": "Ghost Role Info\nHiya! A little about ghost roles...\n\nGhost roles drastically impact the game, so it's not recommended for smaller lobbies if you're unfamiliar. If not explicitly stated otherwise in the description, the Guard button is their ability button ;)\n\nSpawning:\nGhost-roles only spawn after death; the first x people from (team) to die get them.\n\nPS: If your previous role didn't have tasks(e.g., sheriff), your tasks as a ghost-role aren't needed for task-win", "ApocalypseInfoTitle": "Neutral Apocalypse Info:", "Message.ApocalypseInfo": "Every role of the <#ff174f>Apocalypse Team has their own objective to carry out in order to transform.\n<#2B0804>Transformed <#ff174f>Apocalypse members have a drastic change on the game and are immortal (except for being voted), but everyone will be notified that they have transformed.\n\nRoles: <#e5f6b4>Plaguebearer, <#A675A1>Soul Collector, <#bf9f7a>Baker, <#cc0044>Berserker\nTransformed: <#343136>Pestilence, <#644661>Death, <#83461c>Famine, <#2B0804>War\n\nApocalypse members can see eachother's roles and ability icons.\nLike Neutral Killers, Apocalypse members keep the game going as well, have fun!", @@ -2725,9 +2664,8 @@ "DeathMeetingTimeIncrease": "Increased Meeting time when Death exists", "SoulCollectorMeetingDeath": "Your target has died during the meeting. You have gained a soul.", "SoulCollectorKillButtonText": "Predict", - "SoulCollectorHasImpostorVision": "Soul Collector has Impostor vision", "ApocalypseIsNigh": "[ The Apocalypse Is Nigh! ]", - "ApocalypseImmune": "This role is immune!", + "ApocalypseImmune": "This player is immune because they are invincible!", "BakerToFamine": "You have become Famine!!!", "BakerTransform": "The Baker has transformed into Famine, Horseman of the Apocalypse! A famine has begun!", "BakerAlreadyBreaded": "That player already has bread!", @@ -2736,15 +2674,13 @@ "BakerBreadNeededToTransform": "Required number of bread to become Famine", "BakerCantBreadApoc": "You cannot give other Apocalypse members bread!", "BakerKillButtonText": "Bread", - "BakerUnshiftButtonText": "Switch Bread", "BakerRevealBread": "Reveal", "BakerRoleblockBread": "Roleblock", "BakerBarrierBread": "Barrier", "BakerCurrentBread": "Current Bread: ", "BakerSwitchBread": "Bread Switched to: ", - "BakerCanVent": "Baker can Vent", + "BakerCanVent": "Baker can Vent", "BakerBreadGivesEffects": "Bread gives additional effects", - "BakerTransformNoMoreBread": "Baker transforms if they do not have enough bread", "FamineKillButtonText": "Starve", "FamineStarveCooldown": "Famine starve cooldown", "FamineCantStarveApoc": "You cannot starve other Apocalypse members!", @@ -2791,7 +2727,6 @@ "GodfatherTargetCountMode": "Moordenaars veranderen in", "GodfatherCount_Refugee": "Refugee", "GodfatherCount_Madmate": "Madmate", - "GodfatherRefugeeMsg": "You have been recruited by GodFather!", "MissChance": "Chance To Miss", "IncreaseByOneIfConvert": "Increase The KillCount +1 If a Crew Is Converted", "HawkMissed": "Missed!", @@ -2824,7 +2759,6 @@ "BerserkerToWar": "You have become War!!!", "BerserkerTransform": "The Berserker has transformed into War, Horseman of the Apocalypse! Cry 'Havoc!', and let slip the dogs of war.", "WarKillCooldown": "War kill cooldown", - "BerserkerCanKillTeamate": "Can kill other Neutral Apocalypse", "BlackmailerSkillCooldown": "Blackmail Cooldown", "BlackmailerMax": "Maximum times blackmailed players may speak", "BlackmailerDead": "Warning! {0} has been blackmailed by a Blackmailer!", @@ -2914,8 +2848,6 @@ "RememberedPursuer": "Je herinnerde je dat je een Achtervolger was!", "RememberedFollower": "Je herinnerde je dat je een Volger was!", "RememberedAmnesiac": "Het lukte je niet je rol te herinneren.", - "AmnesiacRemembered": "You remembered you were {0}!", - "ReportWhenFailedRemember": "Report Dead Body when failed to remember", "RememberedImitator": "You remembered you were an Imitator.", "RememberedImpostor": "Je herinnerde je dat je een Verrader was!", "RememberedCrewmate": "Je herinnerde je dat je een Bemanningslid was!", @@ -3329,12 +3261,9 @@ "PixieTargetAlreadySelected": "Doelwit al geselecteerd", "PixieButtonText": "Mark", "PlagueBearerCooldown": "Plague cooldown", - "PlagueBearerCanVent": "Can vent", - "PlagueBearerHasImpostorVision": "Has Impostor vision", "PestilenceCooldown": "Pestilence Kill cooldown", "PestilenceCanVent": "Pestilence Can Vent", "PestilenceHasImpostorVision": "Pestilence Has Impostor Vision", - "PestilenceKillGuessers": "Kill players who guess Pestilence", "PlagueBearerAlreadyPlagued": "Player has already been plagued", "PlagueBearerToPestilence": "You have turned into Pestilence!!", "GuessPestilence": "You just tried to guess Pestilence!\n\nSorry, Pestilence killed you.", @@ -3378,7 +3307,6 @@ "EveryoneCanKnowMini": "Iedereen kan zien wie de Mini is", "CanBeEvil": "Mini can be an Impostor", "EvilMiniSpawnChances": "Waarschijnlijkheid dat Mini een Bedrieger is", - "EvilMiniCanBeGuessed": "Evil Mini can be guessed before 18", "GuessMini": "Sorry, je kan een jonge Mini geen pijn doen.", "GrowUpDuration": "Tijd nodig om te groeien (s)", "MajorCooldown": "Kill Cooldown when over 18", @@ -3520,7 +3448,6 @@ "WinnerRoleText.Doppelganger": "Doppelganger Wins!", "WinnerRoleText.Quizmaster": "Quizmaster Wins!", "WinnerRoleText.Agitater": "Agitator Wins!", - "WinnerRoleText.Shocker": "Shocker Wins!", "AdditionalWinnerRoleText.Sidekick": "Hulpje", "AdditionalWinnerRoleText.Taskinator": "Taakinator", "AdditionalWinnerRoleText.Opportunist": "Opportunist", @@ -3606,7 +3533,7 @@ "SolsticerOnMeeting": "You witnessed too many deaths! Next round you will have {0} more short task!", "SolsticerTitle": "Solsticer", "GuessSolsticer": "Sorry, but you can not guess Solsticer!", - "ExpelSolsticer": "Sorry, but you can not expel Solsticer!", + "VoteSolsticer": "Sorry, but you can not vote Solsticer!", "SolsticerTasksReset": "Your tasks get reset!", "SolsticerMisGuessed": "You just misguessed! You are no longer allowed to guess.", "SolsticerGuessMax": "Because you already misguessed, you are no longer allowed to guess.", @@ -3707,28 +3634,6 @@ "MinionAbilityTime": "Ability Duration", "Minion_Blind": "blinded", "Evader_ChanceNotExiled": "Chance not be exiled", - "ShockerAbilityCooldown": "Ability Cooldown", - "ShockerAbilityDuration": "Ability Duration", - "ShockerAbilityPerRound": "Abilities Per Round", - "ShockerShockInVents": "Shock people in vents", - "ShockerAbilityResetAfterMeeting": "Reset marked rooms after meeting", - "ShockerOutsideRadius": "Radius Of Outside Tasks (not in a room)", - "ShockerCanShockHimself": "Can Shock Himself", - "ShockerImpostorVision": "Shocker has Impostor vision", - "ShockerIsShocking": "You're already shocking!", - "ShockerAbilityActivate": "Begin Shocking!", - "ShockerAbilityDeactivate": "Ability Deactivated", - "ShockerVentButtonText": "Shock", - "ShockerRoomMarked": "Marked Room", "EavesdropperMsgTitle": "You found a secret", - "EavesdropPercentChance": "Chance to eavesdrop", - "ChiefOfPoliceSkillCooldown": "Cooldown for recruiting sheriffs", - "PolicCanImpostorAndNeutarl": "Can recruit Impostor or Neutral", - "SheriffSuccessfullyRecruited": "You recruited a sheriff.", - "BeSheriffByPolice": "You've been recruited by the police chief! Serve the crew!", - "PoliceFailedRecruit": "Failed to recruit target.", - "ChiefOfPoliceKillButtonText": "Recruitment", - "PolicPreventRecruitNonKiller": "Prevent recruit players without kill button", - "PolicSuidiceWhenTargetNotKiller": "Suidices when recruit a non killer or non crewmate", - "PolicPassConverted": "Can pass Converted Addon to Sheriff" -} \ No newline at end of file + "EavesdropPercentChance": "Chance to eavesdrop" +} diff --git a/Resources/Lang/pt_BR.json b/Resources/Lang/pt_BR.json index 5144105c9..9b251bd19 100644 --- a/Resources/Lang/pt_BR.json +++ b/Resources/Lang/pt_BR.json @@ -19,8 +19,6 @@ "SubText.Neutral": "Trabalhe sozinho para alcançar a vitória", "SubText.Apocalypse": "Torne-se imparável com a sua equipe", "SubText.Madmate": "Ajude os Impostores", - "SubText.Lovers": "Stay alive and win together", - "SubText.Egoist": "Win on your own", "TypeImpostor": "Impostores", "TypeCrewmate": "Tripulantes", "TypeNeutral": "Neutros", @@ -30,9 +28,6 @@ "TeamNeutral": "Neutro", "TeamCrewmate": "Tripulante", "TeamMadmate": "Cúmplice", - "TeamLovers": "Lovers", - "TeamEgoist": "Egoist", - "TeamApocalypse": "Apocalypse", "YouAreCrewmate": "Você é um Tripulante", "YouAreImpostor": "Você é um Impostor", "YouAreNeutral": "Você é um Neutro", @@ -224,7 +219,6 @@ "TaskManager": "Gerenciador de Tarefas", "Witness": "Detector", "Swapper": "Trocador", - "ChiefOfPolice": "Chefe da Polícia", "NiceMini": "Mini do Bem", "Mini": "Mini", "Spy": "Espião", @@ -253,7 +247,6 @@ "Stalker": "Stalker", "Workaholic": "Trabalhador", "Solsticer": "Speedrunner", - "Abyssbringer": "Abyssbringer", "Collector": "Coletor", "Provocateur": "Provocador", "BloodKnight": "Cavaleiro Sangrento", @@ -392,8 +385,6 @@ "Sloth": "Preguiçoso", "Prohibited": "Proibido", "Eavesdropper": "Interceptador", - "Shocker": "Chocador", - "Revenant": "Assombração", "BracketAddons": "Adicionar parênteses para Atributos", "EngineerTOHEInfo": "Use ventilações para encontrar os Impostores", "ScientistTOHEInfo": "Acesse vitais portáveis de qualquer lugar", @@ -512,7 +503,6 @@ "PacifistInfo": "Use dutos para resetar todas as recargas de abate", "RebirthInfo": "Levante-se novamente", "MonarchInfo": "Dê à sua tripulação um poder extra de voto!", - "AbyssbringerInfo": "Create Black Holes", "SpurtInfo": "Salte como um coelho!", "StealthInfo": "Matar cega todos na sala", "PenguinInfo": "Arraste suas vítimas", @@ -546,7 +536,6 @@ "WitnessInfo": "Descubra se o seu alvo matou recentemente", "GhastlyInfo": "Controle alguém!", "SwapperInfo": "Troque os Votos de Jogadores", - "ChiefOfPoliceInfo": "Contrate Xerife para Servir as Tripulações!", "NiceMiniInfo": "Ninguém pode machucá-lo até que você cresça!", "ArsonistInfo": "Mergulhe todos na gasolina e acenda!", "PyromaniacInfo": "Mergulhe todos na gasolina e acenda!", @@ -707,8 +696,6 @@ "SlothInfo": "Você é lento", "ProhibitedInfo": "Certos dutos estão bloqueados", "EavesdropperInfo": "Escute outras funções", - "ShockerInfo": "Eletrocutar jogadores desavisados", - "RevenantInfo": "Assuma a função de assassino", "EngineerTOHEInfoLong": "(Tripulantes):\n★Como um Engenheiro, você pode acessar as tubulações enquanto as comunicações não são sabotadas.", "ScientistTOHEInfoLong": "(Tripulantes):\nComo um Cientista, você tem um tablet portátil com os dados vitais da Tripulação.\nUse-o da maneira que quiser.", "NoisemakerTOHEInfoLong": "(Tripulantes):\nComo o Sirene, sempre que você morrer você fará um barulho, e um indicador visual de sua morte aparecerá na tela para que os tripulantes possam correr para pegar a pessoa que o matou em flagrante (mesmo que não seja Vermelho).", @@ -769,8 +756,8 @@ "PenguinInfoLong": "(Impostores):\nComo o Pinguim, você pode arrastar um jogador pressionando o botão de matar e o movendo por aí.\nAo arrastar, o jogador pode morrer pressionando o botão de matar novamente ou após um determinado período.\nPressione o botão de matar duas vezes para matar diretamente.", "ParasiteInfoLong": "(Time Impostor):\n★O Parasita é um Impostor que não sabe quem são os outros Impostores. \n★Você deverá matar, usar o duto, sabotar, etc.\n★Só saiba que você é Impostor.", "DisperserInfoLong": "(Impostores):\nO Dispersor pode se Transformar para teletransportar todos os jogadores para dutos aleatórios.", - "InhibitorInfoLong": "(Impostores):\n★O Inibidor não pode matar quando uma sabotagem crítica está ativa.\n★Se uma sabotagem crítica for ativa (por exemplo Luzes ou Reator), você não poderá matar.", - "SaboteurInfoLong": "(Impostores):\n★O Sabotador só pode matar quando uma sabotagem crítica estiver ativa.\n★Se uma sabotagem crítica estiver ativa (por exemplo, Comms ou O2), você pode matar.", + "InhibitorInfoLong": "(Impostors):\nAs the Inhibitor, you can only kill when there is not a critical sabotage active.\n\nIf light or comms sabotage is active, then you can kill.", + "SaboteurInfoLong": "(Impostors):\nAs the Saboteur, you can only kill when there is a critical sabotage active.\n\nIf reactor or O2 sabotage is active, then you can kill.", "CouncillorInfoLong": "(Impostores):\nComo o Conselheiro, você pode matar jogadores durante uma reunião como um Juiz.\nQuando você matar em uma reunião, essas mortes aparecerão como um julgamento de um Juiz.\n\nO comando para matar é /tl [Id do jogador]\nVocê pode ver o Id dos jogadores antes do nome do jogador ou usar o comando /id para ver o Id de todos os jogadores.\nDependendo das configurações, o Conselheiro cometerá suicídio se julgar alguém de sua equipe.\nConselheiros convertidos podem julgar livremente.", "DazzlerInfoLong": "(Impostores):\n★O Cegador pode reduzir permanentemente a visão do alvo de sua metamorfose. Quando o Cegador morrer, a visão dos jogadores voltará ao normal.", "DeathpactInfoLong": "(Impostores):\nComo o Pacto da Morte, você se transforma para marcar seus alvos para um pacto da morte.\nSe você tiver jogadores suficientemente marcados para um pacto da morte, eles devem se encontrar dentro de um período específico; se falharem em fazer isso, eles morrem.\nSe um jogador marcado morrer antes que o pacto da morte seja concluído, o pacto é retirado.", @@ -780,7 +767,7 @@ "LurkerInfoLong": "(Impostores):\nO Espreitador pode entrar em uma ventilação para diminuir sua recarga de abate. Depois de você matar, sua recarga de abate vai voltar ao normal.", "VisionaryInfoLong": "(Impostores):\nO Visionário pode ver as facções dos jogadores vivos atualmente, porém apenas consegue ver durante as reuniões. \nA seguinte informação será mostrada no jogador: \n- Nome vermelho indica Impostor. \n- Nome ciano indica Tripulante. \n- Nome cinza indica Neutro.", "PlagueDoctorInfoLong": "(Neutros):\n(Doutor da Praga de TOH)\nO objetivo da Maldição é Infectar todos.\nEle começa escolhendo um jogador para infectar, após isso qualquer jogador que passe um certo tempo no alcançe desse jogador infectado será infectado tambem.\nO Progresso da infecção é cumulativo, e não é redefinido com a distancia ou após reuniões.", - "RefugeeInfoLong": "(Tripulantes Loucos):\nComo Refugiado, você era:\n -Um amnésico que se lembrava de um impostor\n -Um assassino que matou o alvo do Chefão.\n -Um romântico cujo parceiro era um Impostor\n -ou um imitador que imitava um impostor.\n\nAgora seu trabalho é ajudar os Impostores a matar os colegas de tripulação.", + "RefugeeInfoLong": "(Cúmplices):\nComo Refugiado, ou você foi relembrado pelo Amnésico ou você matou o alvo do Rei do Crime.\n\nAgora seu trabalho é ajudar os Impostores a matar os Tripulantes.", "UnderdogInfoLong": "(Impostores):\n★Como Azarão, você não pode matar enquanto tiver uma certa quantidade de jogadores vivos.", "ConsigliereInfoLong": "(Impostores):\nComo Consultor, você pode revelar as funções de outros jogadores usando o botão de matar.\n\nClique único: Revelar função\nClique duplo: Matar normalmente\n\nSe você ficar sem usos de revelação, seu botão de matar funcionará normalmente.", "LudopathInfoLong": "(Impostores):\n★Como Ludopata, seu tempo de recarga é aleatório \n★O minimo é de 1 segundo, enquanto o máximo é o seu tempo de recarga normal definido.", @@ -824,7 +811,7 @@ "MorticianInfoLong": "(Tripulantes):\nO Funerário pode ver setas apontando para todos os cadáveres, e se o Funerário reportar o cadáver, ele vai saber o último jogador que teve contado com a vítima.", "MediumInfoLong": "(Tripulantes):\nO Médium pode estabelecer contato com os mortos depois de seu corpo ser reportado. \nO jogador que reportar não precisa ser o Médium. \nO jogador morto pode responder apenas SIM ou NÃO para a pergunta do Médium qual apenas o Médium vai poder ver.", "ObserverInfoLong": "(Tripulantes):\nO Observador pode ver todas as animações de escudo causado por outros jogadores depois da primeira reunião.", - "MonarchInfoLong": "(Tripulantes):\nComo Monarca, você pode dar aos jogadores um voto extra.\n\nVocê não pode dar um voto extra a alguém que já tem votos extras.\n\nOs jogadores que receberem os votos apareceram com o nome dourado.\nSe um jogador que você deu um voto extra estiver vivo, o Monarca não poderá ser adivinhado ou ejetado.", + "MonarchInfoLong": "(Crewmates):\nAs the Monarch, you can knight players to give them an extra vote.\n\nYou cannot knight someone who already has multiple votes.\n\nKnighted players appear with a golden name.\nIf a knighted player is alive, the Monarch cannot be guessed or killed.", "PacifistInfoLong": "(Tripulantes):\n★Quando Pacifista usa a ventilação, ele resetará o tempo de abate para todos os jogadores com botão de matar. \n★ Quando ele se torna um Cúmplice, essa habilidade vai apenas funcionar em Tripulantes.", "OverseerInfoLong": "(Tripulantes): \nComo o Profeta, você tem visão mínima, mas pode usar seu botão de matar para revelar a função de um jogador próximo. Um 「○」 será exibido ao lado do alvo revelado após você usar o botão de matar nele, e você também estará escaneando-o (somente você pode ver isso). Fique perto do alvo por um tempo definido para revelar sua função; se você se afastar demais, a revelação será cancelada.", "CoronerInfoLong": "(Tripulantes):\nComo Detetive você não pode reportar cadáveres, assim que você tentar reportar você verá uma seta apontando para o assassino do cadáver. \nSe a reunião for chamada, as setas somem.", @@ -856,7 +843,6 @@ "TaskManagerInfoLong": "(Tripulantes):\nVocê vê o total de números de tarefas completadas em tempo real.", "WitnessInfoLong": "(Tripulantes):\nO Detector pode usar seu botão de matar em alguém, você saberá se a pessoa matou alguém em X segundos atrás ou não matou. (X depende das configurações).", "SwapperInfoLong": "(Tripulantes):\nComo Trocador, você pode trocar votos nas reuniões.\n\nPara trocar votos, use '/sw [playerID]' duas vezes.\n\nOs IDs dos jogadores são exibidos ao lado dos nomes dos jogadores nas reuniões, mas você também pode usar /id para obter uma lista de todos os IDs dos jogadores.\n\nNota: Dependendo das configurações do Anfitrião, você pode trocar os seus próprios votos.", - "ChiefOfPoliceInfoLong": "(tripulantes):\nJogadores com espadas podem ser recrutados para se juntar à equipe do Xerífe para servir à tripulação\nNota: Apenas uma oportunidade de recrutamento\nDependendo das configurações, você pode recrutar não assassinos ou não tripulantes.\nVocê pode suicidar-se por recrutar o alvo errado.", "NiceMiniInfoLong": "(Tripulantes):\nComo Mini do Bem, sua sobrevivência é crucial. Você não pode ser morto até crescer, e se morrer ou for expulso da reunião antes de crescer, todos perdem. Esta função única adiciona uma nova dinâmica ao jogo, onde a sua sobrevivência não é apenas para seu benefício, mas para o sucesso de toda a tripulação.", "SpyInfoLong": "(Tripulantes):\nComo Espião, quando alguém usar seu botão de abate em você (qualquer habilidade usada através do botão de abate), você verá o nome do jogador em laranja por alguns poucos segundos.\nNota: Se um Tripulante usar a habilidade dele em você, você também verá o nome dele laranja!\nNota: Se você não tiver mais usos de habilidade restantes, você não verá os nomes laranjas", "RandomizerInfoLong": "(Tripulantes):\nQuando você morrer, seu assassino fará uma das seguintes ações:\n 1. Reportar seu corpo\n 2. Ficar ao lado do seu corpo\n 3. Ter o tempo de recarga definido como 600s\n 4. Vingar aleatoriamente um jogador.", @@ -871,7 +857,7 @@ "LawyerInfoLong": "(Neutros):\n★O Advogado tem um alvo para defender, o alvo será indicado por um diamante 「♦」 perto de seu nome.\n★ Se o alvo do Advogado vencer, ele vence.\n★ Se o alvo do Advogado perder, ele perde.", "OpportunistInfoLong": "(Neutros):\n★Se o Oportunista sobreviver até o final do jogo, o Oportunista ganha junto com o jogador que venceu", "VectorInfoLong": "(Neutros):\n★O Mario vence sozinho após entrar na ventilação um determinado número de vezes.", - "JackalInfoLong": "(Neutros):\nComo Jackal, você vence se for o último jogador vivo. Além disso, você pode recrutar usando o botão de matar. Se o alvo não for um que você possa recrutar, se você ficar sem uso ou não tiver a opção de recrutar, então você matará normalmente (ou seja, não use a habilidade de recrutar na frente de outras pessoas pensando que vai recrutar). Se o alvo tiver um botão de matar e a opção de se transformar em Recruta estiver ativada, ele se tornará um Recruta. Caso contrário, eles ganharão o complemento Recruta se a opção de fornecer o complemento Recruta estiver ativada.", + "JackalInfoLong": "(Neutros):\nComo Chacal, você vence se for o último jogador vivo. Além disso, você pode recrutar usando o botão de matar. Se o alvo não for um que você possa recrutar, se você ficar sem uso ou não tiver a opção de recrutar, então você matará normalmente (ou seja, não use a habilidade de recrutar na frente de outras pessoas pensando que vai recrutar). Se o alvo tiver um botão de matar e a opção de se transformar em Recruta estiver ativada, ele se tornará um Recruta. Caso contrário, eles ganharão o complemento Recruta se a opção de fornecer o complemento Recruta estiver ativada.", "GodInfoLong": "(Neutros):\nComo o Deus, você conhece a função de todos desde o início. Se você sobreviver até o final do jogo, você rouba a vitória, ou seja, todos os outros perdem e você vence.", "InnocentInfoLong": "(Neutros):\nO Inocente pode usar o botão de matar para fazer qualquer jogador mata-lo. Se o alvo for votado na reunião, o Inocente vence. Nota: Palhaço, Executor e Inocente podem ganhar juntos.", "PelicanInfoLong": "(Neutros):\nComo Glutão, você pode usar o botão de matar para engolir um jogador vivo, teletransportando-o para fora do mapa, mas sem matá-lo ainda. Aqueles engolidos só morrerão se você ainda estiver vivo no final da rodada. Se você morrer ou sair durante a rodada, todos os jogadores engolidos vivos aparecerão no mapa onde você estava.", @@ -883,7 +869,7 @@ "SolsticerInfoLong": "(Neutros):\nComo Speedrunner, você será imortal, e vencerá ao terminar todas as suas tarefas em uma única rodada. Após o término de cada reunião, suas tarefas são redefinidas e você precisa começar tudo de novo.\nOs votos no Speedrunner serão cancelados.\nTentativas de matar o Speedrunner irão teletransportá-lo para fora do mapa como o Glutão até que a reunião termine.\nO tempo de espera para matar do assassino será redefinido para 10 segundos.", "CollectorInfoLong": "(Neutros):\nQuando o Coletor coletar um número específico de votos, ele vence. Nota: A vitória do Coletor tem precedência dos jogadores exilados.", "GlitchInfoLong": "(Neutros):\nO Glitch é um erro da nave e tem que matar todo mundo \nVocê pode hackear os jogadores, o que os impede de matar, usar dutos e reportar cadáveres por algum tempo. \nVocê precisa matar todo mundo para vencer. \nClique Único = Hackear \nClique Duplo = Matar \nVocê pode usar dutos.\nVocê Pode se transformar usando o botão sabotagem, não as portas mas os botões clássicos de sabotagem, Elétrica, O2 e Reator. \nDevido a problemas técnicos não é possível se transformar quando a sabotagem está ativa.", - "SidekickInfoLong": "Neutrais):\nComo Assistente, seu trabalho é ajudar o Jackal a matar todos.\nVocê e o Jackal ganham juntos.\nDependendo das configurações, você pode se transformar em Jackal se o Jackal antigo foi morto.\nTalvez você não seja capaz de matar até que o antigo Jackal esteja morto.", + "SidekickInfoLong": "(Neutros):\n★O Ajudante ajuda o Chacal a matar todos.\n★ O Ajudante e o Chacal vencem juntos.", "ProvocateurInfoLong": "(Neutros):\n★O Provocador pode matar seu alvo com o botão de matar. Se o alvo perder ao final do jogo, o Provocador vence com quem vencer.", "BloodKnightInfoLong": "(Neutros):\nO Cavaleiro Sangrento vence quando é a única função que mata viva e a quantidade de Tripulantes for menor ou igual a de Cavaleiros Sangrentos. Após todo abate, o Cavaleiro Sangrento ganha um escudo temporário que faz ele se tornar Imortal por alguns segundos.", "PlagueBearerInfoLong": "(Apocalipse):\nComo o Porta-Pragas, contamine todos usando seu botão de matar para se transformar na Peste. Uma vez que você se transforme na Peste, você se tornará imortal e ganhará a capacidade de matar, e você matará qualquer um que tentar matá-lo.\n\nAlém disso, quando jogadores infectados interagem com jogadores não infectados, eles também serão infectados.", @@ -910,12 +896,11 @@ "TraitorInfoLong": "(Neutros):\nO Traidor é um Impostor que traiu os Impostores.\nO Traidor saberá quem são os impostores, mas os impostores não saberão quem é o traidor.\nOs Impostores podem matar o Traidor, mas o Traidor não pode matar os Impostores.\n\nO Traidor precisa encontrar outra forma de eliminar os Impostores, então matar todos e vencer!", "TrollerInfoLong": "(Neutros):\nComo Trollador, você pode completar tarefas para que eventos aleatórios aconteçam com os jogadores. Por exemplo, mudar a velocidade de todos os jogadores, teleportação, influenciar sabotagens, etc.\nAlém disso, você pode vencer com a equipe vencedora.", "VultureInfoLong": "(Neutros):\n★O Canibal não reporta corpos normalmente.\n★ O Canibal come o corpo clicando em reportar, fazendo com que não seja mais possível reportar o corpo.\n★ Coma a maioria dos corpos para vencer!", - "AbyssbringerInfoLong": "(Impostors):\nAs the Abyssbringer, you can place black holes. Black holes will suck in players and kill them when colliding with them.", "TaskinatorInfoLong": "(Neutros):\nComo Sabota-Tarefas, sempre que você concluir uma tarefa, ela será bombardeada. Quando outro jogador concluir a tarefa bombardeada, a bomba será detonada e o jogador morrerá.\n\nVocê vence se sobreviver até o fim e a equipe não vencer.\n\n Observação: as bombas do Sabota-Tarefas ignoram qualquer tipo de proteção.", "BenefactorInfoLong": "(Tripulantes):\nComo Benfeitor, sempre que você completar uma tarefa, a tarefa será marcada. Quando outro jogador for completar a tarefa marcada, ele receberá um escudo temporário.\n\n Nota: O escudo protege apenas contra ataques diretos.", "MedusaInfoLong": "(Neutros):\n★A Medusa pode transformar os corpos em pedra, como se tivesse limpado eles.\n★ Corpos transformados em pedras não podem ser reportados.\n★ Mate todos para vencer.", "SpiritcallerInfoLong": "(Neutros):\nO Caçador de Almas tem o poder de transformar suas vítimas em Espírtos Malvados depois de morrerem. \nEsses espíritos podem ajudar você a ganhar congelando outros jogadores por um curto tempo, além dos espíritos poderem bloquear sua visão. \nAdicionalmente, os espíritos podem te dar um escudo que te protege de uma tentativa de abate.", - "AmnesiacInfoLong": "Neutrais):\nComo Amnesiac, use o botão de relatório para lembrar um alvo e obter seu papel.\nPara equilibrar o jogo, você não será capaz de evitar depois de lembrar o seu papel se não puder evitar como Amnesiac.'", + "AmnesiacInfoLong": "(Neutros):\n★O Amnésico pode usar seu botão de reportar para relembrar uma função. \n★Se o alvo for um Impostor, você se tornará um Refugiado. \n★Se o alvo era um tripulante, você se tornará um Xerife. \n★Se o alvo era um neutro passivo ou um neutro assassino não especificado, você se tornará o que está definido nas configurações. \n★Se o alvo era um neutro assassino dos poucos, você se tornará a função que ele é. \n★Se o alvo for um membro do Coventículo, você se tornará a Alma Penada", "ImitatorInfoLong": "(Neutros):\nComo o Imitador, use o botão de matar para imitar um jogador.\n\nVocê se tornará um xerife, um refugiado ou algum neutro.", "BanditInfoLong": "(Neutros):\nComo Bandido, você pode clicar no botão de matar uma vez para roubar o atributo de um jogador. Dependendo das configurações, você pode roubar o atributo instantaneamente ou após o início da reunião. Depois que o número máximo de roubos for atingido, você matará normalmente. Além disso, se não houver atributos roubáveis presentes no alvo ou se o alvo tiver o atributo Protegido, você o matará direto.\n\nClique Único: Roubar o Atributo\nClique Duplo: Matar\n\nMate todos para vencer.\n\nNota:- Limpo, Último Impostor e Amantes não podem ser roubados.\nNota:- Se a opção pro Bandido poder usar os dutos estiver ativado, o atributo Ágil se tornará inroubável", "DoppelgangerInfoLong": "(Neutros):\nComo Sósia, use o botão de matar para roubar a identidade de um jogador (nome e skin) e, em seguida, mate seu alvo.\n\nMate todos para vencer.\n\nObservação: Você não pode roubar a identidade do alvo quando a Camuflagem estiver ativa.", @@ -936,7 +921,6 @@ "JinxInfoLong": "(Neutros):\nComo a Jinx, sempre que você é atacado, você amaldiçoa o atacante, resultando na morte deles por uma maldição.\nIsso tem usos limitados.\n\nMate todos para vencer.", "PotionMasterInfoLong": "(Neutros):\nComo o Mestre das Poções, você tem três poções diferentes atribuídas a três ações diferentes.\n\nUm clique simples: Revelar função\nDuplo clique: Matar\nMapa: Sabotar\n\nA poção de revelação tem um limite.\nQuando você acabar, os botões de matar voltam ao padrão de matar.", "NecromancerInfoLong": "(Neutros):\nComo o Necromante, você vence se for o último sobrevivente.\nAlém disso, quando alguém tentar matá-lo, a morte será bloqueada e você será teletransportado para uma ventilação aleatória. Você terá um tempo limitado para matar seu assassino. Se você conseguir fazer isso, você viverá. Se o tempo acabar antes de você matar seu assassino, você morrerá permanentemente. Se você tentar matar outra pessoa que não seja o seu assassino, você morrerá.", - "ShockerInfoLong": "Neutrais):\nComo o Chocador, você pode marcar cômodos fazendo tarefas neles, e, em seguida, evite eletrocutar qualquer um desses quartos por um período de tempo definido. Quando você terminar todas as suas tarefas, você obterá novas. Nota: realizar tarefas durante esse período irá marcá-las para o próximo uso da habilidade.", "LastImpostorInfoLong": "(Atributos):\nEste efeito especial é dado ao último Impostor sobrevivente. Ele reduz significativamente o tempo de recarga para matar deles.", "OverclockedInfoLong": "(Atributos):\nComo Ansioso, sua recarga para matar é reduzida em uma porcentagem.\n\nSó é atribuído a funções com um botão de matar.", "LoversInfoLong": "(Atributos):\nOs Amantes são uma combinação de dois jogadores. Os Amantes vencem quando são os últimos sobreviventes, e sua vitória é compartilhada. Quando um dos Amantes vence, o outro também vence junto. Os Amantes podem ver o símbolo 「♥」 ao lado do nome um do outro. Se um dos Amantes morre, o outro morrerá de amor (talvez não morra de amor de acordo com as configurações do Anfitrião). Quando um dos Amantes é exilado na reunião, o outro morrerá e se tornará um corpo morto que não pode ser reportado.", @@ -977,10 +961,10 @@ "GravestoneInfoLong": "(Atributos):\n★Como uma Lápide, a sua função é revelada a todos quando você morre.", "LazyInfoLong": "(Atributos):\nComo o Preguiçoso, você recebe uma única tarefa curta e é imune ao Controlador de Mentes, Marionetista e Gangster.", "AutopsyInfoLong": "(Atributo)\n★Como um Autópsia, você pode ver como as pessoas morreram.\n\nNão pode ser atribuído ao Médico, Super Detetive, Cientista ou Sunnyboy.", - "RebirthInfoLong": "(Atributos):\nComo o Renascido, se você for o jogador que vai ser ejetado, você trocará de skins com alguém e renascerá mais uma vez.\n\nAviso: O Renascido será removido de você se você usar todos os seus renascimentos.", + "RebirthInfoLong": "(Add-ons):\nAs the Rebirth, if you're the player about to be ejected, you will swap skins with a random crewmate who voted for you.\nNotice: The host vote never counts\nRebirth will be removed from you if you exhausted all your rebirths.", "LoyalInfoLong": "(Atributos):\n★Como um Leal, você não pode ser recrutado por funções como Chacal ou Cultista.\n\nNão pode ser atribuído a neutros.", "EvilSpiritInfoLong": "(Atributos):\nComo um Espírito Maligno, seu objetivo é ajudar o Caçador de Almas a vencer. Você pode usar seu botão Assombrar para congelar jogadores e reduzir sua visão. Alternativamente, você pode usar seu botão Assombrar para dar temporariamente ao Caçador de Almas um escudo contra uma tentativa de abate.", - "RecruitInfoLong": "(Betrayal Add-ons):\nComo recruta, você faz parte da equipe do Jackal e ajuda o Jackal e seus Assistente.\nNão é possível vencer com sua equipe original.\nDependendo das configurações, você pode se transformar em Jackal se o antigo Jackal tiver sido morto e nenhum Assistente estiver vivo.", + "RecruitInfoLong": "(Atributos de Traição):\n★O Recruto é do time do Chacal e precisa ajudar o Chacal e seus AjudantesAs. \n★Você não pode ganhar com seu time original.", "AdmiredInfoLong": "(Atributos de Traição): \n★Você foi admirado pelo Admirador e agora ganha com a tripulação e não com seu time original. \n★Você pode ver o Admirador.", "GlowInfoLong": "(Atributos):\nDurante o apagamento das luzes, você e os jogadores próximos receberão um aumento de visão.", "RadarInfoLong": "(Atributos):\nComo Radar, você sempre terá setas apontando para a pessoa mais próxima.", @@ -1023,8 +1007,7 @@ "SlothInfoLong": "(Atributos):\nA velocidade de movimento padrão do Preguiçoso é mais lenta que outras.\n(a velocidade depende da configuração do Anfitrião)", "ProhibitedInfoLong": "(Atributos):\nComo Proibido, você tem dutos específicos que você não pode usar.\nQuantos dutos estão desativados dependerá das configurações do Anfitrião.", "EavesdropperInfoLong": "(Atributos):\nComo Interceptador, você tem a chance de ler mensagens baseadas em informações de outras funções/atributos, como Funerário ou Cão de Caça.", - "ApocalypseInfoLong": "(Apocalypse):\nOs membros do Apocalypse fazem parte de uma equipe separada que trabalha e vence em conjunto. Se houver vários jogadores do Apocalypse no jogo, eles poderão ver as funções uns dos outros.\nDependendo das configurações do Host, as funções do Apocalypse podem ser adivinhadas ou não.", - "RevenantInfoLong": "Neutro):\nSendo a Assombração, seu objetivo é ser morto. Se você for morto, tomará o papel de seu assassino e, em vez disso, matará o assassino. Você não pode vencer antes de ser morto.\nNote que a Assombração só funciona quando é morto.", + "ApocalypseInfoLong": "(Apocalypse):\nApocalypse members are on a separate team that works together and wins together. If there are multiple Apocalypse roles in the game, they can see each other's roles.\nDepending on the Host's settings, Apocalypse roles can guess or be guessed.", "ShowTextOverlay": "Sobrepor Texto", "Overlay.GuesserMode": "Modo Adivinhador", "Overlay.NoGameEnd": "Sem Fim de Jogo", @@ -1038,8 +1021,6 @@ "AbilityUseLimit": "Limite de Uso de Habilidade Inicial", "AbilityInUse": "Habilidade em uso", "AbilityExpired": "A habilidade expirou, {0} usos restantes", - "RevenantTargeted": "Sua função mudou para {0}", - "RevenantCanCopyAddons": "Pode Roubar Addons", "ShowArrows": "Tem setas apontando para corpos", "ArrowDelayMin": "Atraso Mínimo de Exibição da Seta", "ArrowDelayMax": "Atraso Máximo de Exibição da Seta", @@ -1368,8 +1349,6 @@ "ShieldedCanUseKillButton": "Jogador com escudo pode usar a sua habilidade / botão de matar", "PlayerIsShieldedByGame": "Esse jogador está protegido pelo o jogo!", "LegacyNemesis": "Usar Versão Legado", - "LegacyParasite": "Use Legacy Version", - "LegacyTraitor": "Use Legacy Version", "ArsonistKeepsGameGoing": "Pirômano mantém o jogo em andamento", "ArsonistCanIgniteAnytime": "Pode incendiar a qualquer momento", "ArsonistMinPlayersToIgnite": "Mínimo de jogadores molhados necessários para Incendiar", @@ -1512,18 +1491,6 @@ "SheriffCanKillSeparately": "Configurações Individuais", "In%team%": "(Facção %team%)", "SheriffMisfireKillsTarget": "Disparo acidental mata o alvo", - "BlackHolePlaceCooldown": "Black Hole Place Cooldown", - "BlackHoleDespawnMode": "Black Hole Despawn Mode", - "BlackHoleDespawnTime": "Time After Black Hole Despawns", - "Abyssbringer.Suffix": "<#00ffa5>Number of players consumed by {0} <#00ffa5>active black holes:\\n{1}", - "Abyssbringer.Suffix.BlackHole": "<#00ffa5>{0}: {1}", - "BlackHoleMovesTowardsNearestPlayer": "Black Hole Moves Towards Nearest Player", - "BlackHoleMoveSpeed": "Black Hole Moving Speed", - "BlackHoleRadius": "Black Hole Consuming Radius", - "AfterTime": "After Time", - "After1PlayerEaten": "After 1 Player Was Eaten", - "AfterMeeting": "After Meeting", - "None": "None", "SheriffShotLimit": "Número máximo de abates", "SheriffCanKillAllAlive": "Pode abater quando todos estão vivos", "SheriffCanKillCharmed": "Pode abater jogadores Servos", @@ -1540,15 +1507,12 @@ "RebirthUses": "Quantidade de Renascimentos", "RebirthCountVotes": "Apenas renasça pessoas quem votou nele", "RebirthFailed": "Ah, que pena, você não encontrou almas viáveis para trocar de corpo", - "FireworkerCooldown": "Placement Cooldown", "ReverieIncreaseKillCooldown": "Aumentar a recarga de abate", "ReverieMaxKillCooldown": "Máximo de recarga de abate", "ReverieMisfireSuicide": "Falha no disparo ao atingir o tempo máximo de recarga", "ReverieResetCooldownMeeting": "Redefinir tempo de recarga depois da reunião", "ConvertedReverieKillAll": "O Devaneio convertido pode matar qualquer pessoa sem consequências", "VigilanteNotify": "Você se tornou exatamente aquilo que jurou eliminar", - "DictatorChangeCommandToExpel": "Dictator use Command to expell instad of vote", - "DictatorExpelSelf": "PAPAPAPARAPARAPAROOOOOO O cara realmente quer se expulsar", "DoctorTaskCompletedBatteryCharge": "Duração da Bateria", "SnitchEnableTargetArrow": "Ver seta em direção ao alvo", "SnitchCanGetArrowColor": "Ver setas coloridas com base nas cores das facções", @@ -1560,7 +1524,7 @@ "MayorHasPortableButton": "Prefeito tem um Botão de Emergência Móvel", "MayorNumOfUseButton": "Número Máximo de Botões de Emergência Móveis", "MeetingsNeededForWin": "Reuniões necessárias para vitória", - "Jester_RevealUponEject": "Revelar na Ejeção ", + "Jester_RevealUponEject": "Reveal Upon Eject", "CannotVoteWhenDead": "Não é possível votar enquanto estiver morto", "EnableVote": "Habilitar comando /vote", "ShouldVoteSpam": "Tentar esconder o comando /vote", @@ -1572,7 +1536,7 @@ "ExecutionerCanTargetNeutralBenign": "Pode Julgar Neutros Passivos", "ExecutionerCanTargetNeutralEvil": "Pode Julgar Neutros Passivos", "ExecutionerCanTargetNeutralChaos": "Pode Julgar Neutros do Caos", - "Executioner_RevealTargetUponEject": "Revelar Alvo na Ejeção", + "Executioner_RevealTargetUponEject": "Reveal Target Upon Ejection", "SidekickSheriffCanGoBerserk": "Xerife Recrutado pode enlouquecer", "LawyerCanTargetImpostor": "O seu cliente pode ser um Impostor", "LawyerCanTargetNeutralKiller": "O seu alvo pode ser um Neutro Assassino", @@ -1629,7 +1593,6 @@ "EvilTrackerTargetMode.OnceInGame": "Uma vez no jogo", "EvilTrackerTargetMode.EveryMeeting": "Cada reunião", "EvilTrackerTargetMode.Always": "A qualquer momento", - "ScavengerHasCustomDeathReason": "Habilitar Razão de Morte Personalizada", "EvilHackerCanSeeDeadMark": "Pode ver a localização de corpos mortos", "EvilHackerCanSeeImpostorMark": "Pode ver a localização de outros impostores", "EvilHackerCanSeeKillFlash": "Pode ver o Flash de Abate", @@ -1862,21 +1825,13 @@ "Jackal_SidekickCountMode_Jackal": "Jackal", "Jackal_SidekickCountMode_Original": "Time Original", "Jackal_SidekickAssignMode": "Modo de Atribuição de Ajudante", - "Jackal_SidekickAssignMode_SidekickAndRecruit": "Sidekick when failed Recruit", - "Jackal_SidekickAssignMode_Sidekick": "Only Sidekick", - "Jackal_SidekickAssignMode_Recruit": "Only Recruit", + "Jackal_SidekickAssignMode_SidekickAndRecruit": "Ajudante+Recruta", + "Jackal_SidekickAssignMode_Sidekick": "Apenas Ajudante", + "Jackal_SidekickAssignMode_Recruit": "Apenas Recruta", + "JackalWinWithSidekick": "Chacal pode vencer com a facção do Ajudante", "Jackal_SidekickCanKillSidekick": "Ajudantes podem matar outros Ajudantes", "Jackal_SidekickCanKillJackal": "Ajudantes podem matar Jackal", - "Jackal_RecruitFailed": "Você não pode recrutar este jogador!", "JackalCanKillSidekick": "Chacal pode assassinar Ajudantes", - "Jackal_SidekickCanKillWhenJackalAlive": "Sidekick can kill while Jackal is Alive", - "Jackal_SidekickTurnIntoJackal": "Sidekick can turn into Jackal after its death", - "Jackal_RestoreLimitOnNewJackal": "Restore Recruit limit when Sidekick become new Jackal", - "Jackal_OnBecomeNewJackalMeeting": "The old Jackal {0} is dead.\nYou are selected as new Jackal\nWork together and win the game!", - "Jackal_OnNewJackalSelectedMeeting": "O velho Jackal {0} está morto.\n{1} está selecionado como novo Jackal!\nTrabalhem juntos e vença o jogo!", - "Jackal_BecomeNewJackal": "O Jackal Antigo está morto, você agora é o novo Jackal!", - "Jackal_OnNewJackalSelected": "O Jackal Antigo está morto, por favor ajude o novo Jackal {0} agora!", - "Jackal_BossIsDead": "Ops, o chefe de Jackal está morto!", "CoronerArrowsPointingToDeadBody": "Setas apontando para os corpos", "CoronerLeaveDeadBodyUnreportable": "Os corpos usados ​​pelo Detetive não podem ser repotados", "CoronerInformKillerBeingTracked": "Informar ao assassino que ele está sendo rastreado", @@ -1914,9 +1869,6 @@ "VipTag": "VIP★", "ApplyVipList": "Aplicar Lista VIP", "AllowSayCommand": "Permitir que moderadores usem o comando /say", - "AllowStartCommand": "Permitir que moderadores usem o comando /start", - "StartCommandMinCountdown": "Contagem regressiva mínima para o comando /start", - "StartCommandMaxCountdown": "Contagem regressiva máxima para o comando /start", "KickCommandDisabled": "O comando de expulsar está atualmente desativado.", "KickCommandNoAccess": "Você não tem acesso ao comando de expulsar.", "KickCommandInvalidID": "ID de Jogador Inválido.\nPor favor, use '/kick [ID jogador] [motivo]' para expulsar um jogador.\nExemplo: - /kick 5 fã do erik carr", @@ -1949,11 +1901,6 @@ "WarnCommandNoAccess": "Você não tem acesso ao comando de alertar.", "WarnCommandInvalidID": "ID de Jogador Inválido.\nPor favor, use '/warn [ID jogador] [motivo]' para alertar um jogador. \nExemplo: - /warn 5 super cringe", "WarnCommandWarnHost": "Você não pode alertar o anfitrião.", - "StartCommandNoAccess": "Você não tem acesso ao comando start.", - "StartCommandDisabled": "The start command is currently disabled.", - "StartCommandCountdown": "ERROR\n\nThe game is already starting!", - "StartCommandStarted": "The game has been started by {0}!", - "StartCommandInvalidCountdown": "ERROR\n\nThe countdown must be between {0} and {1}!", "WarnCommandWarnMod": "Você não tem permissão para alertar outros moderadores.", "WarnCommandWarned": "foi alertado. Não haverá mais avisos e ações apropriadas serão tomadas \n ", "WarnExample": "Use /warn [ID] [motivo] no futuro. \nExemplo:-\n /warn 5 super cringe", @@ -1981,7 +1928,6 @@ "DeathReason.Quantization": "Quantização", "DeathReason.Overtired": "Cansado Demais", "DeathReason.Ashamed": "Envergonhado", - "DeathReason.Consumed": "Consumed", "DeathReason.PissedOff": "Destruído", "DeathReason.Dismembered": "Desmembrado", "DeathReason.LossOfHead": "Estrangulado", @@ -2005,8 +1951,6 @@ "DeathReason.Starved": "Fome", "DeathReason.Equilibrium": "Equilíbrio", "DeathReason.Sacrificed": "Sacrificado", - "DeathReason.Electrocuted": "Electrocuted", - "DeathReason.Scavenged": "Scavenged", "OnlyEnabledDeathReasons": "Apenas motivos de morte habilitados", "Alive": "Vivo", "Disconnected": "Desconectado", @@ -2072,7 +2016,6 @@ "Command.dump": "→ Salvar o Registro de Saída na Área de Trabalho", "Command.death": "→ Exibir informações de como você morreu", "Command.icons": "
╳ - O Jogador foi marcado pelo Prevaricador e não pode falar durante a Reunião.
☆ - Usado pelo Capitão para se exibir. Apenas os Tripulantes podem ver a estrela do Capitão.
乂 - Este jogador foi amaldiçoado pelo Mestre das Maldições e morrerá se o Mestre das Maldições não for morto ou expulso até o final da Reunião.
♦ - Usado pelo Advogado, Executor ou Seguidor.
♥ - Usado pelos Amantes ou Romântico.
✚ - Usado pelo Médico para marcar seu alvo.
⦿ - Este jogador está em um duelo com o Pirata.
!? - Este jogador foi marcado pelo Professor de Perguntas e deve responder a pergunta corretamente para sobreviver.
☜ - Usado pelo Gato de Schrödinger para marcar seu companheiro de equipe.
◈ - Este jogador foi marcado pelo Véu e morrerá se o Véu não for morto ou expulso até o final da reunião.
⚠ - Este jogador é um Informante ou Solstício que concluiu suas tarefas.
★ - Usado pelo Super Estrela, Cibernético ou Marshall.
† - Este jogador foi enfeitiçado e morrerá se a Feiticeira não for morta até o final da reunião.
∇ - Usado pelo Kamikaze para marcar seus alvos.
■ - Usado pelo Relâmpago para marcar seus fantasmas quânticos.
⊠ - Usado pelo Carcereiro para marcar seu prisioneiro.
● - Usado pelo Padaria para marcar quem tem Pão.
♠ - Usado pelo Coletor de Almas para marcar quem é a morte que eles estão prevendo.
⦿ - Usado pelo Portador da Peste para marcar quem eles infectaram.", - "Command.start": "[Seconds] → Start the game", "Command.iconinfo": "→ Exibir Informações em Ícones da Reunião", "Command.iconhelp": "→ Exibir Informações Sobre Ícones da Reunião para Todos", "Command.Poll": "\"→ Inicie uma enquete com até 5 opções\"", @@ -2085,7 +2028,6 @@ "ShowMadmatesInLeftCommand": "Mostrar Cúmplices (incluindo atributos)", "ShowApocalypseInLeftCommand": "Mostrar Neutros do Apocalipse", "SeeEjectedRolesInMeeting": "Ver Funções Ejetadas em Reuniões", - "ThankYouForUsingTOHE": "Thank you for using TOHE!", "SkillUsedLeft": "Você ativou sua habilidade para convocar uma reunião. \nQuantidade restante de usos disponíveis::", "NemesisDeadMsg": "A morte do Mafioso significa o início da Vingança! \nPor favor, use /rv + [ID do jogador] para matar o jogador especificado. \nVocê pode ver os IDs dos jogadores na frente de seus nomes. \nOu digite /rv para obter uma lista de IDs dos jogadores", "NemesisAliveKill": "A Vingança pelo Mafioso só pode começar após sua morte.", @@ -2105,7 +2047,6 @@ "GuessNotifiedBait": "O Armador não pode ser adivinhado porque foi anunciado, você pensou que seria fácil, não é?", "GuessGM": "Adivinhar o Espectador é impossível porque ele já está morto... E também... por que você faria isso com o pobre anfitrião?", "GuessGuardianTask": "Você não pode adivinhar um Anjo Guardião que já completou suas tarefas.", - "GuardianCantKilled": "You can't kill a Guardian who has finished their tasks.", "GuessMarshallTask": "Você não pode adivinhar um Marechal que já completou suas tarefas.", "GuessObviousAddon": "Desculpe, mas Atributos óbvios não podem ser adivinhados.", "GuessAdtRole": "Infelizmente, as configurações do anfitrião não permitem que você adivinhe Atributos.", @@ -2161,7 +2102,6 @@ "BecomeMadmateCuzMadmateMode": "Você se tornou um Cúmplice porque morreu", "CleanerCleanBody": "O corpo foi limpo!", "QuickShooterStoraging": "Marcadores armazenados com sucesso", - "QuickShooterFailed": "You are still in cooldown.", "PoisonerTargetDead": "O alvo foi morto!", "HexesLookLikeSpells": "Mestres Feiticeiros aparecem como magia", "HexButtonText": "Feitiço", @@ -2320,7 +2260,6 @@ "Message.YTPlanNotice": "Observação: o [Plano YouTuber] está habilitado neste lobby, o que significa que o anfitrião pode especificar sua função no próximo jogo para facilitar a obtenção de conteúdo. Caso o anfitrião abuse deste recurso, saia do jogo ou denuncie.\nJogador:", "Message.OnlyCanBeUsedByHost": "ERRO\n\nEste comando só pode ser usado pelo anfitrião.", "Message.MaxPlayers": "Máximo de jogadores definido para ", - "Message.MaxPlayersFailByRegion": "Could not set max players: Vanilla regions support a maximum of 15 players.", "Message.GhostRoleInfo": "Informações sobre as Funções de Fantasma\nOlá! Um pouco sobre as funções de fantasma...\n\nAs funções de fantasma impactam drasticamente o jogo, por isso não são recomendadas em salas com poucas pessoas, se você não estiver familiarizado.\n\nAparecerá:\nAs funções de fantasma só aparecem após a morte, as primeiras x pessoas da (equipe) a morrer as pegam.\n\nPS: Se sua função anterior não tinha tarefas (por exemplo, xerife), suas tarefas como função fantasma não são necessárias para vencer por tarefas", "ApocalypseInfoTitle": "Informações sobre Neutros do Apocalipse:", "Message.ApocalypseInfo": "Cada função da Equipe <#ff174f>Apocalipse tem seu próprio objetivo a ser cumprido para se transformar.\nMembros <#2B0804>Transformados <#ff174f>do Apocalipse têm uma mudança drástica no jogo e são imortais (exceto por serem votados), mas todos serão notificados de que eles se transformaram.\n\nFunções: <#e5f6b4>Porta-Pragas, <#A675A1>Coletor de Almas, <#bf9f7a>Padeiro, <#cc0044>Aprimorador \nTransformados: <#343136>Peste, <#644661>Morte, <#83461c>Faminto, <#2B0804>Guerra\n\nMembros do Apocalipse podem ver as funções e os ícones de habilidades uns dos outros. Assim como os Neutros Assassinos, os membros do Apocalipse também mantêm o jogo em andamento, divirta-se!", @@ -2725,9 +2664,8 @@ "DeathMeetingTimeIncrease": "Aumentar o tempo de reunião quando a Morte existe", "SoulCollectorMeetingDeath": "Seu alvo morreu durante a reunião. Você ganhou uma alma.", "SoulCollectorKillButtonText": "Preditar", - "SoulCollectorHasImpostorVision": "Soul Collector has Impostor vision", "ApocalypseIsNigh": "[ O Apocalipse Está Próximo! ]", - "ApocalypseImmune": "This role is immune!", + "ApocalypseImmune": "Esse jogador é imune por causa que ele é invéncivel!", "BakerToFamine": "Você virou o Faminto!!!", "BakerTransform": "O Padeiro se transformou no Faminto, Cavaleiro do Apocalipse! Uma fome começou!", "BakerAlreadyBreaded": "Esse jogador ja está com um pão!", @@ -2736,15 +2674,13 @@ "BakerBreadNeededToTransform": "Número de pães requeridos para se tornar o Faminto", "BakerCantBreadApoc": "Você não pode dar um pão a outros Membros do Apocalipse!", "BakerKillButtonText": "Alimentar", - "BakerUnshiftButtonText": "Switch Bread", "BakerRevealBread": "Revelar", "BakerRoleblockBread": "Bloquear", "BakerBarrierBread": "Barreira", "BakerCurrentBread": "Pão Atual: ", "BakerSwitchBread": "Pão Trocado para: ", - "BakerCanVent": "Baker can Vent", + "BakerCanVent": "Padeiro pode usar os dutos", "BakerBreadGivesEffects": "O Pão da efeitos adicionais", - "BakerTransformNoMoreBread": "Baker transforms if they do not have enough bread", "FamineKillButtonText": "Fome", "FamineStarveCooldown": "Tempo para morrer de fome do Faminto", "FamineCantStarveApoc": "Você não pode fazer outros Membros do Apocalipse morrerem de fome!", @@ -2791,7 +2727,6 @@ "GodfatherTargetCountMode": "Assassino se torna", "GodfatherCount_Refugee": "Refugiado", "GodfatherCount_Madmate": "Trimpostor", - "GodfatherRefugeeMsg": "You have been recruited by GodFather!", "MissChance": "Chance de errar", "IncreaseByOneIfConvert": "Aumentar a contagem de mortes +1 se um tripulante for convertido", "HawkMissed": "Errou Bichão!", @@ -2824,7 +2759,6 @@ "BerserkerToWar": "Você virou o Guerreiro!!!", "BerserkerTransform": "O Aprimorador se transformou no Guerreiro, Cavaleiro do Apocalipse! Grite 'Desordem!' e solte os cães da guerra.", "WarKillCooldown": "Recarga para matar do Guerreiro", - "BerserkerCanKillTeamate": "Can kill other Neutral Apocalypse", "BlackmailerSkillCooldown": "Recarga para Silenciar", "BlackmailerMax": "Máximo de vezes que os jogadores silenciados podem falar", "BlackmailerDead": "Aviso: {0} foi silenciado por um Silenciador.", @@ -2914,8 +2848,6 @@ "RememberedPursuer": "Você relembrou que era um Perseguidor!", "RememberedFollower": "Você relembrou que era um Seguidor!", "RememberedAmnesiac": "Você falhou ao lembrar sua função.", - "AmnesiacRemembered": "You remembered you were {0}!", - "ReportWhenFailedRemember": "Report Dead Body when failed to remember", "RememberedImitator": "Você se lembrou que você era um Imitador.", "RememberedImpostor": "Você relembrou que era um Impostor!", "RememberedCrewmate": "Você relembrou que era um Tripulante!", @@ -3329,12 +3261,9 @@ "PixieTargetAlreadySelected": "O alvo já foi selecionado", "PixieButtonText": "Marcar", "PlagueBearerCooldown": "Recarga para passar a praga", - "PlagueBearerCanVent": "Can vent", - "PlagueBearerHasImpostorVision": "Has Impostor vision", "PestilenceCooldown": "Recarga de ataque da Peste", "PestilenceCanVent": "A Peste Can Vent", "PestilenceHasImpostorVision": "A Peste tem Visão de Impostor", - "PestilenceKillGuessers": "Kill players who guess Pestilence", "PlagueBearerAlreadyPlagued": "O Jogador já está infectado", "PlagueBearerToPestilence": "Você se tornou a Peste!!", "GuessPestilence": "Você tentou matar a Peste!\n\n★ A Peste te matou.", @@ -3378,7 +3307,6 @@ "EveryoneCanKnowMini": "Todos podem ver o Mini", "CanBeEvil": "O Mini pode ser um Impostor", "EvilMiniSpawnChances": "Probabilidade de o Mini ser um Impostor", - "EvilMiniCanBeGuessed": "Evil Mini can be guessed before 18", "GuessMini": "Desculpe, mas você pode não fazer mal a uma criança Mini.", "GrowUpDuration": "Tempo necessário para crescer", "MajorCooldown": "Tempo de recarga quando tiver mais de 18 anos", @@ -3520,7 +3448,6 @@ "WinnerRoleText.Doppelganger": "Vitória do Sósia!", "WinnerRoleText.Quizmaster": "Vitória do Mestre das Charadas!", "WinnerRoleText.Agitater": "Vitória do Demolidor!", - "WinnerRoleText.Shocker": "Shocker Wins!", "AdditionalWinnerRoleText.Sidekick": "Ajudante", "AdditionalWinnerRoleText.Taskinator": "Sabota-Tarefas", "AdditionalWinnerRoleText.Opportunist": "Oportunista", @@ -3606,7 +3533,7 @@ "SolsticerOnMeeting": "Você testemunhou muitas mortes! Na próxima rodada você terá mais {0} tarefas curtas!", "SolsticerTitle": "Speedrunner", "GuessSolsticer": "Desculpe, mas você não pode adivinhar o Speedrunner!", - "ExpelSolsticer": "Sorry, but you can not expel Solsticer!", + "VoteSolsticer": "Desculpe, mas você não pode votar no Speedrunner!", "SolsticerTasksReset": "Suas tarefas foram redefinidas!", "SolsticerMisGuessed": "Você adivinhou errado! Então você não irá mais poder adivinhar.", "SolsticerGuessMax": "Você adivinhou errado na sua adivinhação anterior, você não tem mais permissão para adivinhar.", @@ -3707,28 +3634,6 @@ "MinionAbilityTime": "Duração da Habilidade", "Minion_Blind": "cegado", "Evader_ChanceNotExiled": "Chance de não ser expulso", - "ShockerAbilityCooldown": "Ability Cooldown", - "ShockerAbilityDuration": "Ability Duration", - "ShockerAbilityPerRound": "Abilities Per Round", - "ShockerShockInVents": "Shock people in vents", - "ShockerAbilityResetAfterMeeting": "Reset marked rooms after meeting", - "ShockerOutsideRadius": "Radius Of Outside Tasks (not in a room)", - "ShockerCanShockHimself": "Can Shock Himself", - "ShockerImpostorVision": "Shocker has Impostor vision", - "ShockerIsShocking": "You're already shocking!", - "ShockerAbilityActivate": "Begin Shocking!", - "ShockerAbilityDeactivate": "Ability Deactivated", - "ShockerVentButtonText": "Shock", - "ShockerRoomMarked": "Marked Room", "EavesdropperMsgTitle": "Você encontrou um segredo", - "EavesdropPercentChance": "Chance de Interceptar", - "ChiefOfPoliceSkillCooldown": "Cooldown for recruiting sheriffs", - "PolicCanImpostorAndNeutarl": "Can recruit Impostor or Neutral", - "SheriffSuccessfullyRecruited": "You recruited a sheriff.", - "BeSheriffByPolice": "You've been recruited by the police chief! Serve the crew!", - "PoliceFailedRecruit": "Failed to recruit target.", - "ChiefOfPoliceKillButtonText": "Recruitment", - "PolicPreventRecruitNonKiller": "Prevent recruit players without kill button", - "PolicSuidiceWhenTargetNotKiller": "Suidices when recruit a non killer or non crewmate", - "PolicPassConverted": "Can pass Converted Addon to Sheriff" -} \ No newline at end of file + "EavesdropPercentChance": "Chance de Interceptar" +} diff --git a/Resources/Lang/pt_PT.json b/Resources/Lang/pt_PT.json index 3c56b7f60..2df2cf0bd 100644 --- a/Resources/Lang/pt_PT.json +++ b/Resources/Lang/pt_PT.json @@ -19,8 +19,6 @@ "SubText.Neutral": "Trabalhe sozinho para alcançar a sua vitória", "SubText.Apocalypse": "Become unstoppable with your team", "SubText.Madmate": "Ajuda os Impostores", - "SubText.Lovers": "Stay alive and win together", - "SubText.Egoist": "Win on your own", "TypeImpostor": "Impostores", "TypeCrewmate": "Tripulantes", "TypeNeutral": "Neutros", @@ -30,9 +28,6 @@ "TeamNeutral": "Neutro", "TeamCrewmate": "Tripulante", "TeamMadmate": "Traidor", - "TeamLovers": "Lovers", - "TeamEgoist": "Egoist", - "TeamApocalypse": "Apocalypse", "YouAreCrewmate": "Tu és um Tripulante", "YouAreImpostor": "Tu és um Impostor", "YouAreNeutral": "Tu és um Neutro", @@ -224,7 +219,6 @@ "TaskManager": "Regulador de Tarefas", "Witness": "Testemunha", "Swapper": "Trocador", - "ChiefOfPolice": "Chief of Police", "NiceMini": "Mini Bondoso", "Mini": "Mini", "Spy": "Espião", @@ -253,7 +247,6 @@ "Stalker": "Stalker", "Workaholic": "Workaholic", "Solsticer": "Solsticer", - "Abyssbringer": "Abyssbringer", "Collector": "Collector", "Provocateur": "Provocateur", "BloodKnight": "Blood Knight", @@ -392,8 +385,6 @@ "Sloth": "Sloth", "Prohibited": "Prohibited", "Eavesdropper": "Eavesdropper", - "Shocker": "Shocker", - "Revenant": "Revenant", "BracketAddons": "Add Brackets To Add-ons", "EngineerTOHEInfo": "Use the vents to catch the Impostors", "ScientistTOHEInfo": "Access portable vitals from anywhere", @@ -512,7 +503,6 @@ "PacifistInfo": "Vent to reset kill cooldowns", "RebirthInfo": "Arise Again", "MonarchInfo": "Give your crew extra voting power!", - "AbyssbringerInfo": "Create Black Holes", "SpurtInfo": "Spring Like A rabbit!", "StealthInfo": "Killing Blinds Everyone in the Room", "PenguinInfo": "Drag your victims", @@ -546,7 +536,6 @@ "WitnessInfo": "Find out if someone killed recently", "GhastlyInfo": "Control somebody!", "SwapperInfo": "Swap the votes of two players", - "ChiefOfPoliceInfo": "Hire Sheriff to Serve the Crews!", "NiceMiniInfo": "No one can hurt you until you grow up.", "ArsonistInfo": "Douse everyone and ignite", "PyromaniacInfo": "Douse and kill everyone", @@ -707,8 +696,6 @@ "SlothInfo": "You're slower", "ProhibitedInfo": "Certain vents are blocked", "EavesdropperInfo": "Listen in on other roles", - "ShockerInfo": "Shock unsuspecting players", - "RevenantInfo": "Take your killer's role", "EngineerTOHEInfoLong": "(Crewmates):\nAs the Engineer, you may access the vents while Comms Sabotaged is inactive.", "ScientistTOHEInfoLong": "(Crewmates):\nAs the Scientist, you can see vitals at any time, showing you who is alive and dead.", "NoisemakerTOHEInfoLong": "(Crewmates):\nAs the Noisemaker, whenever you die, you will make a noise, and a visual indicator of your death appears on the screen so the Crewmates can run to catch the person who killed you red-handed (even if it’s not Red).", @@ -780,11 +767,11 @@ "LurkerInfoLong": "(Impostors):\nAs the Lurker, you can jump into a vent to reduce your cooldown by a certain number of seconds. After you kill, your cooldown resets to its original value.", "VisionaryInfoLong": "(Impostors):\nAs the Visionary, you see the alignments of living players during a meeting.\nThe following information will be displayed on the players:\n- The Red name indicates the Impostors.\n- The Cyan name indicates the Crewmates.\n- The Gray name indicates the Neutrals.", "PlagueDoctorInfoLong": "(Neutrals):\n(Plague Doctor from TOH)\nThe Plague Scientist's goal is to infect every living player.\nThey start by choosing one player to infect, after which anyone who spends a set amount of time in the range of the infected player becomes infected themselves.\nInfection progress is cumulative and does not reset with distance or after meetings.", - "RefugeeInfoLong": "(Madmates):\nAs the Refugee, you were either:\n -An Amnesiac who remembered an Impostor\n -A killer who killed the Godfather's target.\n -A Romantic whose partner was an Impostor\n -Or an Imitator that imitated an Impostor.\n\nNow your job is to help the Impostors kill the crewmates.", + "RefugeeInfoLong": "(Madmates):\nAs the Refugee, you were either an Amnesiac who remembered an Impostor or a killer who killed the Godfather's target.\n\nNow your job is to help the Impostors kill the crewmates.", "UnderdogInfoLong": "(Impostors):\nAs the Underdog, you cannot kill until there's a certain amount of players alive.", "ConsigliereInfoLong": "(Impostors):\nAs the Consigliere, you can reveal the roles of other players using your kill button.\n\nSingle click: Reveal role\nDouble click: Kill\n\nIf you run out of reveal uses, your kill button functions normally.", "LudopathInfoLong": "(Impostors):\nAs the Ludopath, your kill cooldown is randomized.\n\nMinimum it can be is 1 second, while the maximum is your default kill cooldown.", - "GodfatherInfoLong": "(Impostors):\nAs the Godfather, you vote someone to make them your target.\nIn the next round, if someone kills the target, the killer will turn into a Refugee or Madmate.", + "GodfatherInfoLong": "(Impostors):\nAs the Godfather, you vote someone to make them your target.\nIn the next round, if someone kills the target, the killer will turn into a Refugee.", "ChronomancerInfoLong": "(Impostors):\nAs the Chronomancer, you have a charge bar which indicates when the slaughter is ready. When it is at 100% the next time you kill someone, you go into slaughter mode, meaning you can kill indefinitely until your bar runs out of charge. Otherwise, you have a normal KCD.", "PitfallInfoLong": "(Impostors):\nAs the Pitfall, you use your shapeshift to mark the area around the shapeshift as a trap. Players who enter this area will be immobilized quickly, and their vision will be affected.", "EvilMiniInfoLong": "(Impostors):\nAs the Evil Mini, you are unkillable until you grow up and have a very long initial kill cooldown, which gets drastically shortened as you grow up.", @@ -856,7 +843,6 @@ "TaskManagerInfoLong": "(Crewmates):\nYou see the total number of tasks completed (by everyone all together) next to your role name, which updates in real-time.", "WitnessInfoLong": "(Crewmates):\nAs the Witness, when you use your kill button on someone, you will know if they killed in the last X seconds or not. (X depends on the settings).", "SwapperInfoLong": "(Crewmates):\nAs the Swapper, you can swap votes in meetings.\n\nTo swap votes, use '/sw [playerID]' twice.\n\nPlayer IDs are displayed next to player names in meetings, but you can also use /id to get a list of all player IDs.\n\nNote: Depending on the Host's settings, you can exchange your own votes.", - "ChiefOfPoliceInfoLong": "(Crewmates):\nPlayers with swords can be recruited to join the sheriff's team to serve the crew\nNote: only one recruitment opportunity\nDepending on settings, you may recruit non killers or non crews.\nYou may suidice for recruiting wrong target.", "NiceMiniInfoLong": "(Crewmates):\nAs a Nice Mini, your survival is crucial. You can't be killed until you grow up, and if you die or are evicted from the meeting before you grow up, everyone loses. This unique role adds a new dynamic to the game, where your survival is not just for your benefit but for the entire Crew's success.", "SpyInfoLong": "(Crewmates):\nAs the Spy, when someone uses their kill button on you (any ability used through the kill button), you'll see their name in orange for a few seconds.\nNote: If a Crewmate used their ability on you, you'll also see them with an orange name!\nNote: If you cannot use left, you won't see orange names!\nNote: If the kill button interaction is blocked, the player's cooldown will reset to 10s'", "RandomizerInfoLong": "(Crewmates):\nAs this Randomizer, when you die, your killer will do one of the following:\n 1. self-report your body\n 2. stand next to your body\n 3. have their kill cooldown set to 600s\n 4. Randomly avenge a player.", @@ -871,7 +857,7 @@ "LawyerInfoLong": "(Neutrals):\nLawyer has a target to defend, which will be indicated by a diamond 「♦」 next to their name.\nIf your target wins, you win.\nIf they lose, you lose.", "OpportunistInfoLong": "(Neutrals):\nIf the Opportunist survives at the end of the game, the Opportunist will win with the winning player.", "VectorInfoLong": "(Neutrals):\nVector will win alone by venting a certain number of times.", - "JackalInfoLong": "(Neutrals):\nAs the Jackal, you win if you are the last player alive. Additionally, you may recruit using the kill button. If the target is not one you can recruit, you have run out of uses, or you don't have the option to recruit, then you will kill people normally (i.e., don't use kill buttons in front of others thinking it'll recruit). If the target has a kill button and the option to turn into a Sidekick is on, they will become a Sidekick. Otherwise, they will gain the Recruit add-on if the option to give the Recruit add-on is on.\nDepending on the settings, when Jackal was killed, a Sidekick will be randomly selected as the new Jackal.\nRecruit may be selected if no sidekick is alive.", + "JackalInfoLong": "(Neutrals):\nAs the Jackal, you win if you are the last player alive. Additionally, you may recruit using the kill button. If the target is not one you can recruit, you have run out of uses, or you don't have the option to recruit, then you will kill people normally (i.e., don't use kill buttons in front of others thinking it'll recruit). If the target has a kill button and the option to turn into a Sidekick is on, they will become a Sidekick. Otherwise, they will gain the Recruit add-on if the option to give the Recruit add-on is on.", "GodInfoLong": "(Neutrals):\nAs the God, you know everyone's role from the beginning. If you live until the end of the game, you steal the win, i.e., everyone else loses, and you win.", "InnocentInfoLong": "(Neutrals):\nThe Innocent can use the kill button to plant any player, and the planted target will immediately kill the Innocent. If the target gets voted out in the meeting, the Innocent wins. Note: Jester, Executioner, and Innocent can win together.", "PelicanInfoLong": "(Neutrals):\nAs the Pelican, you can use the kill button to swallow a player alive, teleporting them off-bounds but not killing them yet. Those swallowed will only die if you're still alive at the end of the round. If you die or leave during the round, all alive swallowed players will spawn into the map where you were.", @@ -883,7 +869,7 @@ "SolsticerInfoLong": "(Neutrals):\nAs the Solsticer, you won't die, and you win by finishing all your tasks in a single round. After every meeting finishes, your tasks reset, and you need to start all over again.\nVotes on the Solsticer will be directly canceled.\nKill attempts on the Solsticer will teleport it out of the map like Pelican until the meeting is finished.\nThe killer's kill cooldown will be reset to 10 seconds.\nSolsticer is counted as nothing in-game.", "CollectorInfoLong": "(Neutrals):\nAs the Collector, when you vote for a player, for each other player that voted for them, you gain a point. When you collect the required votes, the game ends, and you win alone, even if you voted a Jester or Executioner's target out.", "GlitchInfoLong": "(Neutrals):\nAs the Glitch, you can hack players (single click) or kill normally (double click).\nThose who have been hacked cannot kill, vent, or report for the hack duration.\nAdditionally, calling a sabotage other than doors will have no effect and will instead disguise you as a random player. You cannot disguise during or after sabotages.\nTo win, be the last player alive.", - "SidekickInfoLong": "(Neutrals):\nAs the Sidekick, your job is to help the Jackal kill everyone.\nYou and the Jackal win together.\nDepending on the settings, you may turn into Jackal if old Jackal was killed.\nYou may not be able to kill until old Jackal is dead.", + "SidekickInfoLong": "(Neutrals):\nAs the Sidekick, your job is to help the Jackal kill everyone.\n\nYou and the Jackal win together.", "ProvocateurInfoLong": "(Neutrals):\nAs the Provocateur, you can kill any target with the kill button. If the target loses at the end of the game, the Provocateur wins with the winning team.", "BloodKnightInfoLong": "(Neutrals):\nThe Blood Knight wins when they're the last killing role alive, and the amount of crewmates is lower or equal to the amount of Blood Knights. The Blood Knight gains a temporary shield after every kill, making them immortal for a few seconds.", "PlagueBearerInfoLong": "(Apocalypse):\nAs the Plaguebearer, plague everyone using your kill button to turn into Pestilence.\nOnce you turn into Pestilence, you will become immortal and gain the ability to kill, and you will kill anyone who tries to kill you.\n\nAlso, when infected players interact with uninfected players, they will also be infected.", @@ -910,12 +896,11 @@ "TraitorInfoLong": "(Neutrals):\nAs the Traitor, you were an Impostor that betrayed the Impostors.\nYou know the Impostors, but they don't know you.\nThe twist? They can kill you, but you can't kill them.\n\nEliminate the Impostors by other means, then kill everyone else to win!", "TrollerInfoLong": "(Neutrals):\nAs a Troller, you can complete tasks so that random events can happen to players.\nFor example, changing the speed of all players, teleportation, influencing sabotage, etc.\nAlso you can win with the winning team.", "VultureInfoLong": "(Neutrals):\nAs the Vulture, report bodies to win!\n\nWhen you report a body, if your eat cooldown is up, you'll eat the body (makes it unreportable).\nIf your eat ability is still on cooldown, then you'll report the body normally.\n\nAdditionally, you'll report bodies normally if the maximum bodies eaten per round is reached.", - "AbyssbringerInfoLong": "(Impostors):\nAs the Abyssbringer, you can place black holes. Black holes will suck in players and kill them when colliding with them.", "TaskinatorInfoLong": "(Neutrals):\nAs the Taskinator, whenever you finish a task, the task will be bombed. When another player completes the bombed task, the bomb will detonate, and the player will die.\n\nYou win if you survive till the end and Crew doesn't win.\n\n Note: Taskinator bombs ignore all protection.", "BenefactorInfoLong": "(Crewmates):\nAs the Benefactor, whenever you finish a task, that task will be marked. When another player completes the marked task, they get a temporary shield.\n\n Note: Shield only protects from direct kill attacks.", "MedusaInfoLong": "(Neutrals):\nAs the Medusa, you can stone bodies much like cleaning a body.\nStoned bodies cannot be reported.\n\nKill everyone to win.", "SpiritcallerInfoLong": "(Neutrals):\nAs the Spiritcaller, your victims become Evil Spirits after they die. These spirits can help you win by freezing other players briefly or blocking their vision. Alternatively, the spirits can give you a shield that protects you briefly from an attempted kill.", - "AmnesiacInfoLong": "(Neutrals):\nAs the Amnesiac, use your report button to remember a target and get its role.\nTo balance the game, you will not be able to vent after remembering your role if you can't vent as Amnesiac.'", + "AmnesiacInfoLong": "(Neutrals):\nAs the Amnesiac, use your report button to remember a role.\n\nIf the target was an Impostor, you'll become a Refugee.\nIf the target was a crewmate, you'll become the target role if compatible (otherwise you become an Engineer).\nIf the target was a passive neutral or a neutral killer not specified, you'll become the role defined in the settings.\nIf the target was a neutral killer of a select few, you'll become the role they are.", "ImitatorInfoLong": "(Neutrals):\nAs the Imitator, use your kill button to imitate a player.\n\nYou'll either become a Sheriff, a Refugee, or some Neutral.", "BanditInfoLong": "(Neutrals):\nAs the Bandit, you can click your kill button one time to steal a player's addon and twice to kill. Depending on the settings, you may instantly steal the addon or after the meeting starts. After the maximum number of steals is reached, you will kill normally. Additionally, if there are no stealable addons on the target or the target is stubborn, you will kill the target.\n\nKill everyone to win.\n\nNote: Cleansed, Last Impostor, and Lovers cannot be stolen.\nNote: If Bandit can vent is on, Nimble will become unstealable.", "DoppelgangerInfoLong": "(Neutrals):\nAs the Doppelganger, use your kill button to steal a player's identity (their name and skin) and then kill your target.\n\nKill everyone to win.\n\nNote: You cannot steal the target's identity when Camouflage is active.", @@ -936,7 +921,6 @@ "JinxInfoLong": "(Neutrals):\nAs the Jinx, whenever you get attacked, you jinx them, resulting in them dying to a jinx.\nThis has limited uses.\n\nKill off everyone to win.", "PotionMasterInfoLong": "(Neutrals):\nAs the Potion Master, you have three different potions assigned to three different actions.\n\nSingle click: Reveal role\nDouble click: Kill\nMap: Sabotage\n\nThe reveal potion has a limit.\nWhen you run out, the kill buttons default to killing.", "NecromancerInfoLong": "(Neutrals):\nAs the Necromancer, you win when you're the last one standing.\nAdditionally when someone tries to kill you, you will block the kill, and you will teleport to a random vent. You will have a limited time to kill your killer. If you succeed in doing so, you live. If the time runs out before you kill your killer, you die permanently. If you try to kill someone else other than your killer, you will die.", - "ShockerInfoLong": "(Neutrals):\nAs the Shocker, you can mark rooms by doing tasks in them, and then vent to Electrocute anyone in those rooms for a set period of time. When you finish all of your tasks, you get new ones. Note: Doing tasks during that period will mark them for the next ability use.", "LastImpostorInfoLong": "(Add-ons):\nThis special effect is given to the last surviving Impostor. It significantly reduces their kill cooldown.", "OverclockedInfoLong": "(Add-ons):\nAs the Overclocked, your kill cooldown is reduced by a percentage.\n\nThis feature is only assigned to roles with a kill button.", "LoversInfoLong": "(Add-ons):\nLovers are a combination of two players. The Lovers win when they are the last ones standing, and their victory is shared. When one of the Lovers wins, the other also wins together. Lovers can see the 「♥」 next to each other's name. If one of the Lovers dies, the other will die in love (may not die in love according to the Host's settings). When one of the Lovers is exiled in the meeting, the other will die and become a dead body that cannot be reported.", @@ -980,7 +964,7 @@ "RebirthInfoLong": "(Add-ons):\nAs the Rebirth, if you're the player about to be ejected, you will swap skins with a random crewmate who voted for you.\nNotice: The host vote never counts\nRebirth will be removed from you if you exhausted all your rebirths.", "LoyalInfoLong": "(Add-ons):\nAs the Loyal, you cannot be recruited by roles such as Jackal or Cultist.\n\nCannot be assigned to neutrals.", "EvilSpiritInfoLong": "(Add-ons):\nAs Evil Spirit, it's your job to help the Spiritcaller to victory. You can use your Haunt button to freeze players and reduce their vision. Alternatively, you can use your Haunt button to give the Spiritcaller a shield against a kill attempt temporarily.", - "RecruitInfoLong": "(Betrayal Add-ons):\nAs a recruit, you are on the Jackal's team and help out the Jackal and their Sidekicks.\nYou cannot win with your original team.\nDepending on the settings, you may turn into Jackal if old Jackal was killed and no sidekicks is alive.", + "RecruitInfoLong": "(Betrayal Add-ons):\nAs a recruit, you are on the Jackal's team and help out the Jackal and their Sidekicks.\n\nYou cannot win with your original team.", "AdmiredInfoLong": "(Betrayal Add-ons):\nAs an admired player, you win with the crew and not your original team.\n\nYou can see the Admirer.", "GlowInfoLong": "(Add-ons):\nDuring lights out, you and players nearby you will receive a vision boost.", "RadarInfoLong": "(Add-ons):\nAs Radar, you have arrows pointing towards the closest person at all times.", @@ -1024,7 +1008,6 @@ "ProhibitedInfoLong": "(Add-ons):\nAs the Prohibited, you have specific vents that you can't use.\nHow many vents are disabled depends on the Host's settings.", "EavesdropperInfoLong": "(Add-ons):\nAs the Eavesdropper, you have a chance to read other role/addon information-based messages like Mortician or Sleuth.", "ApocalypseInfoLong": "(Apocalypse):\nApocalypse members are on a separate team that works together and wins together. If there are multiple Apocalypse roles in the game, they can see each other's roles.\nDepending on the Host's settings, Apocalypse roles can guess or be guessed.", - "RevenantInfoLong": "(Neutral):\nAs the Revenant, your goal is to be killed. If you are killed, you will take your killer's role and kill your killer instead. You cannot win before being killed.\nNote that Revenant only works when being directly killed.", "ShowTextOverlay": "Text Overlay", "Overlay.GuesserMode": "Guesser Mode", "Overlay.NoGameEnd": "No Game End", @@ -1038,8 +1021,6 @@ "AbilityUseLimit": "Initial Ability Use Limit", "AbilityInUse": "Ability in use", "AbilityExpired": "Ability expired, {0} uses remain", - "RevenantTargeted": "Your role has changed to {0}", - "RevenantCanCopyAddons": "Can Steal Addons", "ShowArrows": "Has Arrows pointing toward bodies", "ArrowDelayMin": "Minimum Arrow show-up delay", "ArrowDelayMax": "Maximum Arrow show-up delay", @@ -1368,8 +1349,6 @@ "ShieldedCanUseKillButton": "Shielded player can use ability / kill button", "PlayerIsShieldedByGame": "Player is protected by the game!", "LegacyNemesis": "Use Legacy Version", - "LegacyParasite": "Use Legacy Version", - "LegacyTraitor": "Use Legacy Version", "ArsonistKeepsGameGoing": "Arsonist keeps the game going", "ArsonistCanIgniteAnytime": "Can Ignite Anytime", "ArsonistMinPlayersToIgnite": "Minimum doused needed for ignite", @@ -1512,18 +1491,6 @@ "SheriffCanKillSeparately": "Individual Settings", "In%team%": "(Team %team%)", "SheriffMisfireKillsTarget": "Misfire Kills Target", - "BlackHolePlaceCooldown": "Black Hole Place Cooldown", - "BlackHoleDespawnMode": "Black Hole Despawn Mode", - "BlackHoleDespawnTime": "Time After Black Hole Despawns", - "Abyssbringer.Suffix": "<#00ffa5>Number of players consumed by {0} <#00ffa5>active black holes:\\n{1}", - "Abyssbringer.Suffix.BlackHole": "<#00ffa5>{0}: {1}", - "BlackHoleMovesTowardsNearestPlayer": "Black Hole Moves Towards Nearest Player", - "BlackHoleMoveSpeed": "Black Hole Moving Speed", - "BlackHoleRadius": "Black Hole Consuming Radius", - "AfterTime": "After Time", - "After1PlayerEaten": "After 1 Player Was Eaten", - "AfterMeeting": "After Meeting", - "None": "None", "SheriffShotLimit": "Max number of Kills", "SheriffCanKillAllAlive": "Can Kill When No One Is Dead", "SheriffCanKillCharmed": "Can kill Charmed players", @@ -1540,15 +1507,12 @@ "RebirthUses": "Amount of Rebirths", "RebirthCountVotes": "Only rebirth to players who voted for them", "RebirthFailed": "Ahh, how unfortunate, you did not find any viable souls to swap bodies with", - "FireworkerCooldown": "Placement Cooldown", "ReverieIncreaseKillCooldown": "Increase kill cooldown", "ReverieMaxKillCooldown": "Max kill cooldown", "ReverieMisfireSuicide": "Misfire on reaching max kill cooldown", "ReverieResetCooldownMeeting": "Reset kill cooldown after meeting", "ConvertedReverieKillAll": "Converted Reverie can kill anyone without repercussions", "VigilanteNotify": "You have become the very thing you swore to destroy", - "DictatorChangeCommandToExpel": "Dictator use Command to expell instad of vote", - "DictatorExpelSelf": "WAIT WAIT WAIT WAT THE HELLLLLL Bro really just want to expel himself", "DoctorTaskCompletedBatteryCharge": "Battery Duration", "SnitchEnableTargetArrow": "See Arrow Towards Target", "SnitchCanGetArrowColor": "See Colored Arrows based on Team Colors", @@ -1629,7 +1593,6 @@ "EvilTrackerTargetMode.OnceInGame": "Once in-game", "EvilTrackerTargetMode.EveryMeeting": "Every Meeting", "EvilTrackerTargetMode.Always": "Any time", - "ScavengerHasCustomDeathReason": "Enable Custom Death Reason", "EvilHackerCanSeeDeadMark": "Can See The Location of Dead-bodies", "EvilHackerCanSeeImpostorMark": "Can See The Location of Other Impostors", "EvilHackerCanSeeKillFlash": "Can See Kill-Flash", @@ -1862,21 +1825,13 @@ "Jackal_SidekickCountMode_Jackal": "Jackal", "Jackal_SidekickCountMode_Original": "Original Team", "Jackal_SidekickAssignMode": "Sidekick Assign Mode", - "Jackal_SidekickAssignMode_SidekickAndRecruit": "Sidekick when failed Recruit", - "Jackal_SidekickAssignMode_Sidekick": "Only Sidekick", - "Jackal_SidekickAssignMode_Recruit": "Only Recruit", + "Jackal_SidekickAssignMode_SidekickAndRecruit": "Sidekick+Recruit", + "Jackal_SidekickAssignMode_Sidekick": "Sidekick Only", + "Jackal_SidekickAssignMode_Recruit": "Recruit Only", + "JackalWinWithSidekick": "Jackal can win with Sidekick's team", "Jackal_SidekickCanKillSidekick": "Sidekicks can kill other Sidekicks", "Jackal_SidekickCanKillJackal": "Sidekick can kill Jackal", - "Jackal_RecruitFailed": "You can not recruit this player!", "JackalCanKillSidekick": "Jackal can kill Sidekick", - "Jackal_SidekickCanKillWhenJackalAlive": "Sidekick can kill while Jackal is Alive", - "Jackal_SidekickTurnIntoJackal": "Sidekick can turn into Jackal after its death", - "Jackal_RestoreLimitOnNewJackal": "Restore Recruit limit when Sidekick become new Jackal", - "Jackal_OnBecomeNewJackalMeeting": "The old Jackal {0} is dead.\nYou are selected as new Jackal\nWork together and win the game!", - "Jackal_OnNewJackalSelectedMeeting": "The old Jackal {0} is dead.\n{1} is selected as new Jackal!\nWork together and win the game!", - "Jackal_BecomeNewJackal": "Old Jackal Dead, You are now new Jackal!", - "Jackal_OnNewJackalSelected": "Old Jackal Dead, Please help new Jackal {0} for now!", - "Jackal_BossIsDead": "Opps, the Jackal boss is dead!", "CoronerArrowsPointingToDeadBody": "Arrows pointing to dead bodies", "CoronerLeaveDeadBodyUnreportable": "Bodies the Coroner uses can't be reported", "CoronerInformKillerBeingTracked": "Inform the Killer that he gets tracked", @@ -1914,9 +1869,6 @@ "VipTag": "VIP★", "ApplyVipList": "Apply VIP List", "AllowSayCommand": "Allow moderators to use /say command", - "AllowStartCommand": "Allow moderators to use /start command", - "StartCommandMinCountdown": "Minimum countdown for /start command", - "StartCommandMaxCountdown": "Maximum countdown for /start command", "KickCommandDisabled": "The kick command is currently disabled.", "KickCommandNoAccess": "You do not have access to the kick command.", "KickCommandInvalidID": "Invalid player ID specified.\nPlease use '/kick [playerID] [reason]' to kick a player.\nExample :- /kick 5 not following rules", @@ -1949,11 +1901,6 @@ "WarnCommandNoAccess": "You do not have access to the warn command.", "WarnCommandInvalidID": "Invalid player ID specified.\nPlease use '/warn [playerID] [reason]' to warn a player. \nExample :- /warn 5 lava chatting", "WarnCommandWarnHost": "You are not permitted to warn the host.", - "StartCommandNoAccess": "You do not have access to the start command.", - "StartCommandDisabled": "The start command is currently disabled.", - "StartCommandCountdown": "ERROR\n\nThe game is already starting!", - "StartCommandStarted": "The game has been started by {0}!", - "StartCommandInvalidCountdown": "ERROR\n\nThe countdown must be between {0} and {1}!", "WarnCommandWarnMod": "You are not permitted to warn other moderators.", "WarnCommandWarned": "has been warned. There will be no more warnings given and appropriate action will be taken \n ", "WarnExample": "Use /warn [id] [reason] in future. \nExample :-\n /warn 5 lava chatting", @@ -1981,7 +1928,6 @@ "DeathReason.Quantization": "Quantization", "DeathReason.Overtired": "Overtired", "DeathReason.Ashamed": "Ashamed", - "DeathReason.Consumed": "Consumed", "DeathReason.PissedOff": "Destroyed", "DeathReason.Dismembered": "Dismembered", "DeathReason.LossOfHead": "Strangled", @@ -2005,8 +1951,6 @@ "DeathReason.Starved": "Starved", "DeathReason.Equilibrium": "Equilibrium", "DeathReason.Sacrificed": "Sacrificed", - "DeathReason.Electrocuted": "Electrocuted", - "DeathReason.Scavenged": "Scavenged", "OnlyEnabledDeathReasons": "Only Enabled Death Reasons", "Alive": "Alive", "Disconnected": "Disconnected", @@ -2072,7 +2016,6 @@ "Command.dump": "→ Output Log to Desktop", "Command.death": "→ Display info on how you died", "Command.icons": "
╳ - The Player was marked by the Blackmailer and can't talk during the Meeting
☆ - Used by Captain to display themselves. Only Crewmates can see the Captain's star
乂 - This player was hexed by the Hex Master and will die if the Hex Master isn't killed or ejected by the end of the Meeting.
♦ - Used by Lawyer or Executioner or Follower.
♥ - Used by Lovers or Romantic.
✚ - Used by Medic to mark their target.
⦿ - This player is in a duel with the Pirate.
!? - This player was marked by the Quizmaster and must answer the question correctly to survive.
☜ - Used by Schrödinger's cat to mark their teammate.
◈ - This player marked by the Shroud and will die if the Shroud is not killed or ejected by the end of the meeting.
⚠ - This player is a Snitch or Solsticer who has finished their tasks.
★ - Used by Super Star or Cyber or Marshall.
† - This player was spelled and will die if the Witch is not killed by the end of the meeting.
∇ - Used by Kamikaze to mark their targets.
■ - Used by Lightning to mark their quantum ghosts.
⊠ - Used by Jailer to mark their prisoner.
● - Used by Baker to mark who has Bread.
♠ - Used by Soul Collector to mark who's death they're predicting.
⦿ - Used by Plaguebearer to mark who they have plagued.", - "Command.start": "[Seconds] → Start the game", "Command.iconinfo": "→ Display info on in-meeting icons", "Command.iconhelp": "→ Display info on in-meeting icons to everyone", "Command.Poll": "→ Start a poll with up-to 5 choices", @@ -2085,7 +2028,6 @@ "ShowMadmatesInLeftCommand": "Show Madmates (including add-ons)", "ShowApocalypseInLeftCommand": "Show Neutral Apocalypse", "SeeEjectedRolesInMeeting": "See ejected roles in meetings", - "ThankYouForUsingTOHE": "Thank you for using TOHE!", "SkillUsedLeft": "You have activated your skill to call a meeting. \nRemaining amount of uses left:", "NemesisDeadMsg": "The death of the Nemesis means the beginning of the revenge. \nPlease use /rv + [player ID] to kill the specified player \nYou can see player IDs in front of their names. \nOr type /rv to get a list of player IDs", "NemesisAliveKill": "Revenge for the Nemesis can only begin after their death.", @@ -2105,7 +2047,6 @@ "GuessNotifiedBait": "Bait can't be guessed because it was announced. You thought it would be that easy, right?", "GuessGM": "Guessing the GM is impossible because they're already dead.... And why would you do that to the poor Host?", "GuessGuardianTask": "You can't guess a Guardian who has finished their tasks.", - "GuardianCantKilled": "You can't kill a Guardian who has finished their tasks.", "GuessMarshallTask": "You can't guess a Marshall who has finished their tasks.", "GuessObviousAddon": "Sorry, obvious add-ons cannot be guessed.", "GuessAdtRole": "Unfortunately, the Host's settings do not allow you to guess add-ons", @@ -2161,7 +2102,6 @@ "BecomeMadmateCuzMadmateMode": "You became a Madmate because you died", "CleanerCleanBody": "The body has been cleaned", "QuickShooterStoraging": "Bullets stored successfully", - "QuickShooterFailed": "You are still in cooldown.", "PoisonerTargetDead": "Target died", "HexesLookLikeSpells": "Hexes appear as spells", "HexButtonText": "Hex", @@ -2320,7 +2260,6 @@ "Message.YTPlanNotice": "Note: The [YouTuber Plan] is enabled in this lobby, which means the Host can specify their role in the next game to make it easier to get content. If the Host abuses this feature, please exit the game or report it.\nCurrent Creator Credentials:", "Message.OnlyCanBeUsedByHost": "ERROR\n\nThis command may only be used by the host.", "Message.MaxPlayers": "Maximum players set to ", - "Message.MaxPlayersFailByRegion": "Could not set max players: Vanilla regions support a maximum of 15 players.", "Message.GhostRoleInfo": "Ghost Role Info\nHiya! A little about ghost roles...\n\nGhost roles drastically impact the game, so it's not recommended for smaller lobbies if you're unfamiliar. If not explicitly stated otherwise in the description, the Guard button is their ability button ;)\n\nSpawning:\nGhost-roles only spawn after death; the first x people from (team) to die get them.\n\nPS: If your previous role didn't have tasks(e.g., sheriff), your tasks as a ghost-role aren't needed for task-win", "ApocalypseInfoTitle": "Neutral Apocalypse Info:", "Message.ApocalypseInfo": "Every role of the <#ff174f>Apocalypse Team has their own objective to carry out in order to transform.\n<#2B0804>Transformed <#ff174f>Apocalypse members have a drastic change on the game and are immortal (except for being voted), but everyone will be notified that they have transformed.\n\nRoles: <#e5f6b4>Plaguebearer, <#A675A1>Soul Collector, <#bf9f7a>Baker, <#cc0044>Berserker\nTransformed: <#343136>Pestilence, <#644661>Death, <#83461c>Famine, <#2B0804>War\n\nApocalypse members can see eachother's roles and ability icons.\nLike Neutral Killers, Apocalypse members keep the game going as well, have fun!", @@ -2725,9 +2664,8 @@ "DeathMeetingTimeIncrease": "Increased Meeting time when Death exists", "SoulCollectorMeetingDeath": "Your target has died during the meeting. You have gained a soul.", "SoulCollectorKillButtonText": "Predict", - "SoulCollectorHasImpostorVision": "Soul Collector has Impostor vision", "ApocalypseIsNigh": "[ The Apocalypse Is Nigh! ]", - "ApocalypseImmune": "This role is immune!", + "ApocalypseImmune": "This player is immune because they are invincible!", "BakerToFamine": "You have become Famine!!!", "BakerTransform": "The Baker has transformed into Famine, Horseman of the Apocalypse! A famine has begun!", "BakerAlreadyBreaded": "That player already has bread!", @@ -2736,15 +2674,13 @@ "BakerBreadNeededToTransform": "Required number of bread to become Famine", "BakerCantBreadApoc": "You cannot give other Apocalypse members bread!", "BakerKillButtonText": "Bread", - "BakerUnshiftButtonText": "Switch Bread", "BakerRevealBread": "Reveal", "BakerRoleblockBread": "Roleblock", "BakerBarrierBread": "Barrier", "BakerCurrentBread": "Current Bread: ", "BakerSwitchBread": "Bread Switched to: ", - "BakerCanVent": "Baker can Vent", + "BakerCanVent": "Baker can Vent", "BakerBreadGivesEffects": "Bread gives additional effects", - "BakerTransformNoMoreBread": "Baker transforms if they do not have enough bread", "FamineKillButtonText": "Starve", "FamineStarveCooldown": "Famine starve cooldown", "FamineCantStarveApoc": "You cannot starve other Apocalypse members!", @@ -2791,7 +2727,6 @@ "GodfatherTargetCountMode": "Killer turns into", "GodfatherCount_Refugee": "Refugee", "GodfatherCount_Madmate": "Madmate", - "GodfatherRefugeeMsg": "You have been recruited by GodFather!", "MissChance": "Chance To Miss", "IncreaseByOneIfConvert": "Increase The KillCount +1 If a Crew Is Converted", "HawkMissed": "Missed!", @@ -2824,7 +2759,6 @@ "BerserkerToWar": "You have become War!!!", "BerserkerTransform": "The Berserker has transformed into War, Horseman of the Apocalypse! Cry 'Havoc!', and let slip the dogs of war.", "WarKillCooldown": "War kill cooldown", - "BerserkerCanKillTeamate": "Can kill other Neutral Apocalypse", "BlackmailerSkillCooldown": "Blackmail Cooldown", "BlackmailerMax": "Maximum times blackmailed players may speak", "BlackmailerDead": "Warning! {0} has been blackmailed by a Blackmailer!", @@ -2914,8 +2848,6 @@ "RememberedPursuer": "You remembered you were a Pursuer!", "RememberedFollower": "You remembered you were a Follower!", "RememberedAmnesiac": "You failed to remember your role.", - "AmnesiacRemembered": "You remembered you were {0}!", - "ReportWhenFailedRemember": "Report Dead Body when failed to remember", "RememberedImitator": "You remembered you were an Imitator.", "RememberedImpostor": "You remembered you were an Impostor!", "RememberedCrewmate": "You remembered you were a crewmate!", @@ -3329,12 +3261,9 @@ "PixieTargetAlreadySelected": "Target is already selected", "PixieButtonText": "Mark", "PlagueBearerCooldown": "Plague cooldown", - "PlagueBearerCanVent": "Can vent", - "PlagueBearerHasImpostorVision": "Has Impostor vision", "PestilenceCooldown": "Pestilence Kill cooldown", "PestilenceCanVent": "Pestilence Can Vent", "PestilenceHasImpostorVision": "Pestilence Has Impostor Vision", - "PestilenceKillGuessers": "Kill players who guess Pestilence", "PlagueBearerAlreadyPlagued": "Player has already been plagued", "PlagueBearerToPestilence": "You have turned into Pestilence!!", "GuessPestilence": "You just tried to guess Pestilence!\n\nSorry, Pestilence killed you.", @@ -3378,7 +3307,6 @@ "EveryoneCanKnowMini": "Everyone can see the Mini", "CanBeEvil": "Mini can be an Impostor", "EvilMiniSpawnChances": "Probability of Mini being an Impostor", - "EvilMiniCanBeGuessed": "Evil Mini can be guessed before 18", "GuessMini": "Sorry, you can't hurt a kid Mini.", "GrowUpDuration": "Time required to grow (s)", "MajorCooldown": "Kill Cooldown when over 18", @@ -3520,7 +3448,6 @@ "WinnerRoleText.Doppelganger": "Doppelganger Wins!", "WinnerRoleText.Quizmaster": "Quizmaster Wins!", "WinnerRoleText.Agitater": "Agitator Wins!", - "WinnerRoleText.Shocker": "Shocker Wins!", "AdditionalWinnerRoleText.Sidekick": "Sidekick", "AdditionalWinnerRoleText.Taskinator": "Taskinator", "AdditionalWinnerRoleText.Opportunist": "Opportunist", @@ -3606,7 +3533,7 @@ "SolsticerOnMeeting": "You witnessed too many deaths! Next round you will have {0} more short task!", "SolsticerTitle": "Solsticer", "GuessSolsticer": "Sorry, but you can not guess Solsticer!", - "ExpelSolsticer": "Sorry, but you can not expel Solsticer!", + "VoteSolsticer": "Sorry, but you can not vote Solsticer!", "SolsticerTasksReset": "Your tasks get reset!", "SolsticerMisGuessed": "You just misguessed! You are no longer allowed to guess.", "SolsticerGuessMax": "Because you already misguessed, you are no longer allowed to guess.", @@ -3707,28 +3634,6 @@ "MinionAbilityTime": "Ability Duration", "Minion_Blind": "blinded", "Evader_ChanceNotExiled": "Chance not be exiled", - "ShockerAbilityCooldown": "Ability Cooldown", - "ShockerAbilityDuration": "Ability Duration", - "ShockerAbilityPerRound": "Abilities Per Round", - "ShockerShockInVents": "Shock people in vents", - "ShockerAbilityResetAfterMeeting": "Reset marked rooms after meeting", - "ShockerOutsideRadius": "Radius Of Outside Tasks (not in a room)", - "ShockerCanShockHimself": "Can Shock Himself", - "ShockerImpostorVision": "Shocker has Impostor vision", - "ShockerIsShocking": "You're already shocking!", - "ShockerAbilityActivate": "Begin Shocking!", - "ShockerAbilityDeactivate": "Ability Deactivated", - "ShockerVentButtonText": "Shock", - "ShockerRoomMarked": "Marked Room", "EavesdropperMsgTitle": "You found a secret", - "EavesdropPercentChance": "Chance to eavesdrop", - "ChiefOfPoliceSkillCooldown": "Cooldown for recruiting sheriffs", - "PolicCanImpostorAndNeutarl": "Can recruit Impostor or Neutral", - "SheriffSuccessfullyRecruited": "You recruited a sheriff.", - "BeSheriffByPolice": "You've been recruited by the police chief! Serve the crew!", - "PoliceFailedRecruit": "Failed to recruit target.", - "ChiefOfPoliceKillButtonText": "Recruitment", - "PolicPreventRecruitNonKiller": "Prevent recruit players without kill button", - "PolicSuidiceWhenTargetNotKiller": "Suidices when recruit a non killer or non crewmate", - "PolicPassConverted": "Can pass Converted Addon to Sheriff" -} \ No newline at end of file + "EavesdropPercentChance": "Chance to eavesdrop" +} diff --git a/Resources/Lang/ru_RU.json b/Resources/Lang/ru_RU.json index fca17e653..9b7ba94ba 100644 --- a/Resources/Lang/ru_RU.json +++ b/Resources/Lang/ru_RU.json @@ -19,8 +19,6 @@ "SubText.Neutral": "Играйте в одиночку, чтобы добиться своей цели", "SubText.Apocalypse": "Станьте непобедимым вместе со своей командой", "SubText.Madmate": "Помогите своим Предателям", - "SubText.Lovers": "Stay alive and win together", - "SubText.Egoist": "Win on your own", "TypeImpostor": "Предатели", "TypeCrewmate": "Члены Экипажа", "TypeNeutral": "Нейтралы", @@ -30,9 +28,6 @@ "TeamNeutral": "Нейтрал", "TeamCrewmate": "Член Экипажа", "TeamMadmate": "Безумец", - "TeamLovers": "Lovers", - "TeamEgoist": "Egoist", - "TeamApocalypse": "Apocalypse", "YouAreCrewmate": "Ты - Член Экипажа", "YouAreImpostor": "Ты - Предатель", "YouAreNeutral": "Ты - Нейтрал", @@ -224,7 +219,6 @@ "TaskManager": "Мастер Задач", "Witness": "Свидетель", "Swapper": "Обменник", - "ChiefOfPolice": "Chief of Police", "NiceMini": "Добрый Мини", "Mini": "Мини", "Spy": "Шпион", @@ -253,7 +247,6 @@ "Stalker": "Сталкер", "Workaholic": "Трудоголик", "Solsticer": "Солнечный", - "Abyssbringer": "Abyssbringer", "Collector": "Коллектор", "Provocateur": "Провокатор", "BloodKnight": "Кровный Рыцарь", @@ -392,8 +385,6 @@ "Sloth": "Ленивец", "Prohibited": "Ограниченный", "Eavesdropper": "Подслушиватель", - "Shocker": "Shocker", - "Revenant": "Revenant", "BracketAddons": "Добавить скобки к Атрибутам", "EngineerTOHEInfo": "Используйте вентиляцию, чтобы поймать Предателей", "ScientistTOHEInfo": "У вас есть доступ к портативным пульсам", @@ -512,7 +503,6 @@ "PacifistInfo": "Используйте вентиляцию, чтобы сбросить откаты убийства", "RebirthInfo": "Восстань снова", "MonarchInfo": "Дайте игрокам дополнительные голоса!", - "AbyssbringerInfo": "Create Black Holes", "SpurtInfo": "Ваша скорость меняется!", "StealthInfo": "Ваше убийство ослепляет всех в комнате", "PenguinInfo": "Перетаскивайте своих жертв", @@ -546,7 +536,6 @@ "WitnessInfo": "Узнайте, убивал ли кто-то в недавно", "GhastlyInfo": "Поиграй с ними!", "SwapperInfo": "Обменяй голоса игроков", - "ChiefOfPoliceInfo": "Hire Sheriff to Serve the Crews!", "NiceMiniInfo": "Никто не причинит тебе вред, пока ты не вырастешь.", "ArsonistInfo": "Облейте всех и подожгите", "PyromaniacInfo": "Облейте всех игроков", @@ -707,8 +696,6 @@ "SlothInfo": "Вы очень медленный", "ProhibitedInfo": "Некоторые вентиляции заблокированы", "EavesdropperInfo": "Слушайте другие роли", - "ShockerInfo": "Shock unsuspecting players", - "RevenantInfo": "Take your killer's role", "EngineerTOHEInfoLong": "(Член Экипажа):\nИнженер может вентоваться, пока «Саботаж связи» неактивен.", "ScientistTOHEInfoLong": "(Член Экипажа):\nУчёный может в любое время использовать пульсы, которые покажут ему, кто жив, а кто мёртв.", "NoisemakerTOHEInfoLong": "(Член Экипажа):\nВсякий раз когда Паникёр умирает, он издает шум, и на экране появляется визуальный индикатор его смерти который указывает его местоположение, чтобы Члены Экипажа могли найти его труп.", @@ -780,11 +767,11 @@ "LurkerInfoLong": "(Предатель):\nСкрытень может прыгнуть в вентиляцию, чтобы сократить откат убийства на определенное количество секунд. После того как он убьёт, откат сбрасывается до исходного значения.", "VisionaryInfoLong": "(Предатель):\nВизионер видит мировоззрение живых игроков во время встречи.\nНа игроке будет отображаться следующая информация.:\n– Красное имя указывает на Предателей.\n– Голубое имя указывает на Членов Экипажа.\n– Имя Серых указывает на Нейтралов.", "PlagueDoctorInfoLong": "(Злой Нейтрал):\nЦель Чумного Доктора — заразить каждого живого игрока.\nОн начинает с выбора одного игрока для заражения, после чего любой, кто проводит определенное количество времени в радиусе действия зараженного игрока, он заражается вместе с ним.\nПрогресс заражения суммируется и не сбрасывается при изгнии или после встречи.", - "RefugeeInfoLong": "(Madmates):\nAs the Refugee, you were either:\n -An Amnesiac who remembered an Impostor\n -A killer who killed the Godfather's target.\n -A Romantic whose partner was an Impostor\n -Or an Imitator that imitated an Impostor.\n\nNow your job is to help the Impostors kill the crewmates.", + "RefugeeInfoLong": "(Безумец):\nБеженец был Амнезияком который, вспомнил роль Предателя.\n\nПомогите Предателям убить Членов Экипажа.", "UnderdogInfoLong": "(Предатель):\nКак Аутсайдер, ты не можешь убивать пока определённое количество игроков живо.", "ConsigliereInfoLong": "(Предатель):\nСоветник может раскрыть роль других игроков с помощью кнопки убийства.\n\nОдин щелчок: раскрыть роль игрока\nДвойной щелчок: убить игрока\n\nЕсли количество раскрытий закончится, то кнопка убийства будет работать как обычно.", "LudopathInfoLong": "(Предатель):\nУ Людопата случайный откат убийства.\n\nМинимальное значение может составлять 1 секунду, а максимальное - это откат убийства установленный по умолчанию.", - "GodfatherInfoLong": "(Impostors):\nAs the Godfather, you vote someone to make them your target.\nIn the next round, if someone kills the target, the killer will turn into a Refugee or Madmate.", + "GodfatherInfoLong": "(Предатель):\nКогда Крестный голосует за кого-то, он делает игрока своей целью.\nВ следующем раунде, если кто-то убьет его цель, убийца превратится в Беженца.", "ChronomancerInfoLong": "(Предатель):\nКак Хрономант, ты имеешь индикатор заряда, который показывает, когда режим ярости будет готов. При 100% заряде, после убийства, ярость будет включена - ты можешь убивать без отката пока заряд не закончится. В другом случае, у тебя нормальный откат убийства.", "PitfallInfoLong": "(Предатели):\nЛовушка, может использовать Морф, чтобы пометить область вокруг него как ловушку.\nИгроки, попавшие в эту зону, будут обездвижены на короткий период времени, а их зрение будет нарушено.", "EvilMiniInfoLong": "(Предатель):\nЗлой Мини не убиваем, пока не вырастет и у него очень долгий начальный откат убийства, которое сокращается по мере взросления.", @@ -856,7 +843,6 @@ "TaskManagerInfoLong": "(Член Экипажа):\nОн может видеть общее количество выполненных заданий рядом ролью, которое обновляется в режиме реального времени.", "WitnessInfoLong": "(Член Экипажа):\nКогда Свидетель нажимает на кого-то кнопкой «Убить», он будет знать, убили ли они за последние 'X' секунд или нет. (X секунд зависит от настроек).", "SwapperInfoLong": "(Член Экипажа):\nОбменщик может обменять голоса любых двух игроков, во время встречи. С помощью команды он может выбрать первого игрока, а затем после повторного использования команды он может выбрать второго игрока, а затем поменять местами голоса\nКоманда для обмена голосов: '/sw [номер игрока]'\nВы можете увидеть номер игрока перед именем игрока или вы можете использовать команду /id, чтобы увидеть номера всех игроков\nПримечание. В зависимости от настроек Хоста вы можете обмениваться собственными голосами.", - "ChiefOfPoliceInfoLong": "(Crewmates):\nPlayers with swords can be recruited to join the sheriff's team to serve the crew\nNote: only one recruitment opportunity\nDepending on settings, you may recruit non killers or non crews.\nYou may suidice for recruiting wrong target.", "NiceMiniInfoLong": "(Член Экипажа):\nДоброго Мини нельзя убить, пока он не вырастет, но если он умрет или он будет изгнан до того как вырастет, он выиграет в одиночку.", "SpyInfoLong": "(Член Экипажа):\nКогда на Шпионе кто-то использует кнопку убийства (любую способность, которая используется с помощью кнопки убийства), он увидет его никнейм оранжевым цветом в течение нескольких секунд.\nПримечание: если Член Экипажа применил на вас свою способность, вы вы также увидите их с оранжевым именем!\nЕсли у него закончатся способности, он не сможет увидить оранжевых никнеймов", "RandomizerInfoLong": "(Член Экипажа):\nКогда Рандомайзер умрет, его убийца сделает одно из следующих действий:\n 1. Моментально зарепортит труп\n 2. Будет заморожен на несколько секунд\n 3. Установит свой откат убийства на 600 секунд\n 4. Убьёт случайного игрока.", @@ -871,7 +857,7 @@ "LawyerInfoLong": "(Злой - Нейтрал):\nУ Адвоката есть цель для защиты, которая будет отмечена ромбом 「♦」 рядом с его никнеймом.\nЕсли ваша цель выиграет, он тоже победит.\nЕсли цель проиграет, то Адвокат соответственно тоже проиграет.", "OpportunistInfoLong": "(Добрый - Нейтрал):\nВыживший выигрывает игру вместе с любыми другими ролями, но только если он выжил.", "VectorInfoLong": "(Злой - Нейтрал):\nЕсли Вектор прыгнет в вентиляцию определенное количество раз, то победит в одиночку.", - "JackalInfoLong": "(Neutrals):\nAs the Jackal, you win if you are the last player alive. Additionally, you may recruit using the kill button. If the target is not one you can recruit, you have run out of uses, or you don't have the option to recruit, then you will kill people normally (i.e., don't use kill buttons in front of others thinking it'll recruit). If the target has a kill button and the option to turn into a Sidekick is on, they will become a Sidekick. Otherwise, they will gain the Recruit add-on if the option to give the Recruit add-on is on.\nDepending on the settings, when Jackal was killed, a Sidekick will be randomly selected as the new Jackal.\nRecruit may be selected if no sidekick is alive.", + "JackalInfoLong": "(Нейтрал):\nШакал побеждаем в том случае, если остаётся последним в живых. Также, вы можете завербовывать, используя кнопку убийства. Если вы не можете завербовать цель, у вас кончились использования или эта возможность недоступна, тогда вы просто убьёте (не используйте кнопку убийства перед всеми, думая, что вы завербуете вашу цель). Если у вашей цели есть кнопка убийства и возможность появления Помощников включена, то цель станет Помощником. В другом случае они получат атрибут \"Завербованный\", если этот атрибут включен.", "GodInfoLong": "(Нейтрал):\nБог знает роль каждого игрока в начале игры. Если он доживет до конца игры, он победит.", "InnocentInfoLong": "(Злой - Нейтрал):\nОбвинитель может использовать кнопку ''Убить'', чтобы пометить любого игрока.\nПомеченная цель немедленно убьёт Обвинителя.\nЕсли помеченная цель будет изгнана во время встречи, то Обвинитель одержит победу.\nПримечание: Шут, Палач и Обвинитель могут победить вместе.", "PelicanInfoLong": "(Нейтрал):\nПеликан может использовать кнопку убийства, чтобы съесть живого игрока, телепортируя его за пределы карты, но при этом не убивая. Те, кого вы съели, будут убиты только в том случае, если вы остались в живых в конце раунда. Если вы были убиты или вышли из игры во время раунда, все живые съеденные игроки будут заспавнены в том месте, где сейчас стоите вы.", @@ -883,7 +869,7 @@ "SolsticerInfoLong": "(Злой Нейтрал):\nСолнечный не умрет и выиграет, выполнив все свои задания за один раунд. После завершения каждой встречи его задачи сбрасываются, и ему нужно начинать все заново.\nГолос по Солнечному будет напрямую отменено.\nПри попытки убить Солнечного игрока телепортируют его за пределы карты, как Пеликана, до тех пор, пока встреча не завершится.\nОткат убийства у убийцы будет сброшено до 10 секунд.\nСолнечный не считается никем.", "CollectorInfoLong": "(Злой Нейтрал):\nКогда Коллектор голосует за игрока, и если у этого игрока есть другие голоса то он получает очки (количество зависит от количества голосов).\nКогда он наберет необходимое количество голосов, игра закончится, и он выиграет, даже если он проголосовал за Шута или Палача.", "GlitchInfoLong": "(Злой Нейтрал):\nГлич может взламывать игроков (одиним нажатием на кнопку убийства) или убивать обычным способом (двойным нажатием на кнопку убийства).\nТе, кого взломали, не могут убивать, вентоваться или репортить трупы в течение периода взлома.\nКроме того, вызов саботажа замаскирует Глича под случайного игрока.\nЧтобы победить, станьте последним выжившим игроком.", - "SidekickInfoLong": "(Neutrals):\nAs the Sidekick, your job is to help the Jackal kill everyone.\nYou and the Jackal win together.\nDepending on the settings, you may turn into Jackal if old Jackal was killed.\nYou may not be able to kill until old Jackal is dead.", + "SidekickInfoLong": "(Злой - Нейтрал):\nСоюзник должен — помочь Шакалу.\n\nСоюзник и Шакал победят вместе, но они также могут достичь своего обычного условия победы.", "ProvocateurInfoLong": "(Злой - Нейтрал)\nПровокатор может использовать кнопку убийства, чтобы погибнуть вместе с любой целью. Если цель проиграет в конце игры, Провокатор выиграет вместе с командой-победителем.", "BloodKnightInfoLong": "(Злой - Нейтрал):\nКровный Рыцарь побеждает, когда он остается последним живым убийцей, а количество Членов Экипажа меньше или равно количеству Кровных Рыцарей.\nПосле каждого своего убийства он получает временный щит, который делает его бессмертным от прямых атак на несколько секунд.", "PlagueBearerInfoLong": "(Апокалипсис):\nЗаразите всех, чтобы превратиться в Чуму.\nКак только вы превратитесь в Чуму, вы станете бессмертным и получите способность убивать.\nВы убьете любого, кто попытается убить вас.\n\nКроме того, когда зараженные игроки взаимодействуют с незараженными игроками, они также будут заражены.", @@ -910,12 +896,11 @@ "TraitorInfoLong": "(Злой - Нейтрал):\nТрейтор был Предателем, который предал команду Предателей.\nОн знает кто является Предателем, но они не знают кто является Трейтором.\nОни могут убить вас, но вы не сможете убить их.\n\nУбейте Предателей другими возможными способами, а затем убейте всех остальных игроков, чтобы победить!", "TrollerInfoLong": "(Нейтрал):\nБудучи Троллем, вы можете выполнять задания, чтобы с игроками могли происходить случайные события.\nНапример, изменение скорости всех игроков, телепортация, влияние на саботаж и т. д.\nТакже вы можете выиграть вместе с командой победителем.", "VultureInfoLong": "(Злой - Нейтрал):\nСтервятник может репортить трупы для победы!\n\nКогда он репортит труп, если откат съедения истек, он съест труп.\n(Обратите внимение что после съедения трупа, труп не может исчезнуть из-за технических ограничений, его просто нельзя будет зарепортить)\nЕсли его способность есть все еще в откате, он зарепортит труп как обычно.\n\nКроме того, он будет репортить трупы в обычном режиме, если будет достигнуто максимальное количество тел, съеденных за раунд.", - "AbyssbringerInfoLong": "(Impostors):\nAs the Abyssbringer, you can place black holes. Black holes will suck in players and kill them when colliding with them.", "TaskinatorInfoLong": "(Нейтрал):\nВсякий раз когда Таскинатор выполняет задание, задание будет заложено бомбой.\nКогда другой игрок выполнит задание которая была заложена, бомба моментально взорвется, и этот игрок умрет.\n\nВы выиграете, если доживете до конца.\n\nПримечание: Все бомбы Таскинатора игнорируют все защиты.", "BenefactorInfoLong": "(Член Экипажа):\nКаждый раз когда Благодетель выполняет задание, оно будет отмечено. Когда другой игрок выполняет отмеченное задание, он получает временный щит.\n\n Примечание. Щит защищает только от прямых убийств.", "MedusaInfoLong": "(Злой - Нейтрал):\nМедуза может нажать кнопку репорта и превратить труп в камень.\nЭтот труп нельзя будет зарепортить.\nУбейте всех, чтобы победить.", "SpiritcallerInfoLong": "(Злой - Нейтрал):\nКогда Призыватель убивает игроков, они становятся Злыми Духами. Эти духи могут помочь ему победить, заморозив других игроков на короткое время и/или уменьшить их дальность обзора. Кроме того, Злые Духи могут дать ему щит, который ненадолго защитит его от попытки убийства.", - "AmnesiacInfoLong": "(Neutrals):\nAs the Amnesiac, use your report button to remember a target and get its role.\nTo balance the game, you will not be able to vent after remembering your role if you can't vent as Amnesiac.'", + "AmnesiacInfoLong": "(Нейтрал):\nАмнезияк использует кнопку ''Репорт'', чтобы запомнить роль трупа.\n\nЕсли целью был Предатель, он станет Беженцем.\nЕсли цель был Членом Экипажа, вы заберёте его роль если он был совместим (в противном случае вы станете обычным Инженером).\nЕсли цель был Пассивным Нейтралом или Нейтральным Убийцей, он станет ролью которая определена в настройках", "ImitatorInfoLong": "(Нейтрал):\nИмитатор использует кнопку убийства, чтобы подражать ролями игроков.\n\nВы станете Шерифом, Беженцем или Нейтралом.", "BanditInfoLong": "(Нейтрал):\nБандит может нажать кнопку убийства один раз, чтобы украсть атрибут у игрока\nДвойное нажатие убьёт игрока.\nВ зависимости от настроек вы можете украсть атрибут сразу или после начала встречи.\nПосле достижения максимального количества краж вы будете убивать как обычно.\nКроме того, если на цели нет украденных атрибутов вы убьете цель.\n\nУбейте всех, чтобы победить.\n\nПримечание: - Очищенный, Последний Предатель и Любовники не могут быть украдены.\nЕсли он может использовать вентиляцию, Шустрый станет недоступным для кражи.", "DoppelgangerInfoLong": "(Нейтрал):\nДвойник использует кнопку убийства, чтобы украсть личность игрока (его ник и скин), а затем убивает свою цель.\n\nПримечание: Вы не можете украсть личность цели, находясь в камуфляже (если он активен).", @@ -936,7 +921,6 @@ "JinxInfoLong": "(Злой - Нейтрал):\nВсякий раз когда Джинкс подвергается нападению, он накладывает на них порчу, в результате чего они умирают от проклятия.\nЭта способность имеет ограниченное применение.\n\nУбейте всех, чтобы победить.", "PotionMasterInfoLong": "(Злой - Нейтрал):\nРитуальщик может раскрыть роли других игроков, используя кнопку убийства.\n\nОдин щелчок: раскрыть роль игрока\nДвойной щелчок: убить игрока\n\nЕсли количество раскрытий закончится, то кнопка убийства будет работать как обычно.", "NecromancerInfoLong": "(Злой - Нейтрал):\nНекромант побеждает, если останется последним выжившим.\nКогда кто-то попытается его убить, убийство будет заблокировано, и он будете телепортирован в случайную вентиляцию. У него будет ограниченное время, чтобы убить своего убийцу. Если он убьёт свою убийцу, он выживет. Если время истечет до того, как он убьет своего убийцу, он умрёт. Если он попытается убить кого-то еще, кроме своего убийцы, он умрет.", - "ShockerInfoLong": "(Neutrals):\nAs the Shocker, you can mark rooms by doing tasks in them, and then vent to Electrocute anyone in those rooms for a set period of time. When you finish all of your tasks, you get new ones. Note: Doing tasks during that period will mark them for the next ability use.", "LastImpostorInfoLong": "(Атрибут):\nАтрибут, присваивается последнему Предателю. \nВремя отката убийства становится меньше, чем обычно. \nНе назначается Охотнику за головами, Серийному убийце или Вампиру.", "OverclockedInfoLong": "(Атрибут):\nУ Разгонного откат убийства уменьшается на процент указанный в настройках.\n\nНазначается только ролям с кнопкой убийства.", "LoversInfoLong": "(Атрибут):\nДополнительно с какой-либо ролью Любовники назначаются двум случайным игрокам.\nЕсли оба любовника останутся живы, то они выиграют. \nКогда умрёт хотя бы один любовник, то моментально умрёт и второй.\nОни проиграют когда Члены Экипажа выполнят все задания.", @@ -980,7 +964,7 @@ "RebirthInfoLong": "(Атрибут):\nЕсли игрока у которого есть атрибут Перерождённого собираются изгнать, он поменяется скинами со случайным Членом Экипажа который голосовал за вас.\nПримечание. Голос хоста никогда не учитывается.\nПерерождённый будет удален, если он исчерпает все свои перерождения.", "LoyalInfoLong": "(Атрибут):\nЛояльного нельзя завербовать такими ролями, как Шакал или Суккубом.\n\nНе может быть назначен Нейтралам.", "EvilSpiritInfoLong": "(Злой - Нейтрал):\nУ Злого Духа есть задача помочь Призывателю победить. Вы можете использовать кнопку «Защитить», чтобы заморозить игроков и уменьшить их дальность обзора или дать Призывателю временный щит.", - "RecruitInfoLong": "(Betrayal Add-ons):\nAs a recruit, you are on the Jackal's team and help out the Jackal and their Sidekicks.\nYou cannot win with your original team.\nDepending on the settings, you may turn into Jackal if old Jackal was killed and no sidekicks is alive.", + "RecruitInfoLong": "(Предательский Атрибут):\nКак Завербованный, вы больше не сможете победить с вашей первоначальной командой. Взамен, вы должны помочь Шакалу и победить.", "AdmiredInfoLong": "(Предательский Атрибут):\nКак человек, которому признался в любви Поклонник, вы побеждаете с Членами Экипажа.\n\nВы видите Поклонника.", "GlowInfoLong": "(Атрибут):\nВо время отключения света, вы и игроки рядом с вами получите усиление обзора.", "RadarInfoLong": "(Атрибут):\nУ Радара всегда есть стрелка, которая указывает на ближайшего к нему игрока.", @@ -1024,7 +1008,6 @@ "ProhibitedInfoLong": "(Атрибут):\nКак Ограниченный, вы не можете использовать определенные вентиляции\nКоличество отключенных вентиляций зависит от настроек хоста.", "EavesdropperInfoLong": "(Add-ons):\nУ Подслушиваетеля есть возможность читать сообщения, которые были отправленные другим ролям/атрибутам, например, «Гробовщик» или «Сыщик».", "ApocalypseInfoLong": "(Apocalypse):\nApocalypse members are on a separate team that works together and wins together. If there are multiple Apocalypse roles in the game, they can see each other's roles.\nDepending on the Host's settings, Apocalypse roles can guess or be guessed.", - "RevenantInfoLong": "(Neutral):\nAs the Revenant, your goal is to be killed. If you are killed, you will take your killer's role and kill your killer instead. You cannot win before being killed.\nNote that Revenant only works when being directly killed.", "ShowTextOverlay": "Наложение текста", "Overlay.GuesserMode": "Режим Угадывателей", "Overlay.NoGameEnd": "Игра Не Закончится", @@ -1038,8 +1021,6 @@ "AbilityUseLimit": "Первоначальный лимит на использование способности", "AbilityInUse": "Способность использована", "AbilityExpired": "Способность окончена, осталось {0}", - "RevenantTargeted": "Your role has changed to {0}", - "RevenantCanCopyAddons": "Can Steal Addons", "ShowArrows": "Может видеть стрелки ведущие к трупам", "ArrowDelayMin": "Минимальная задержка показа стрелок", "ArrowDelayMax": "Максимальная задержка показа стрелок", @@ -1368,8 +1349,6 @@ "ShieldedCanUseKillButton": "Защищенный игрок может использовать кнопку способности/убийства", "PlayerIsShieldedByGame": "Игрок защищен игрой!", "LegacyNemesis": "Использовать устаревшую версию", - "LegacyParasite": "Use Legacy Version", - "LegacyTraitor": "Use Legacy Version", "ArsonistKeepsGameGoing": "Поджигатель продолжает игру", "ArsonistCanIgniteAnytime": "Может жечь в любое время", "ArsonistMinPlayersToIgnite": "Минимум обливаний, необходимых для поджигания", @@ -1512,18 +1491,6 @@ "SheriffCanKillSeparately": "Выбрать кого", "In%team%": "(Команда %team%)", "SheriffMisfireKillsTarget": "Шериф убивает цель вместе с собой", - "BlackHolePlaceCooldown": "Black Hole Place Cooldown", - "BlackHoleDespawnMode": "Black Hole Despawn Mode", - "BlackHoleDespawnTime": "Time After Black Hole Despawns", - "Abyssbringer.Suffix": "<#00ffa5>Number of players consumed by {0} <#00ffa5>active black holes:\\n{1}", - "Abyssbringer.Suffix.BlackHole": "<#00ffa5>{0}: {1}", - "BlackHoleMovesTowardsNearestPlayer": "Black Hole Moves Towards Nearest Player", - "BlackHoleMoveSpeed": "Black Hole Moving Speed", - "BlackHoleRadius": "Black Hole Consuming Radius", - "AfterTime": "After Time", - "After1PlayerEaten": "After 1 Player Was Eaten", - "AfterMeeting": "After Meeting", - "None": "None", "SheriffShotLimit": "Количество выстрелов", "SheriffCanKillAllAlive": "Может убивать когда никто не умер", "SheriffCanKillCharmed": "Может убить Зачарованных игроков", @@ -1540,15 +1507,12 @@ "RebirthUses": "Количество перерождений", "RebirthCountVotes": "Действует только на тех игроках, которые проголосовали за него", "RebirthFailed": "Вы не нашли живых игроков с которыми можно было бы поменяться телами", - "FireworkerCooldown": "Placement Cooldown", "ReverieIncreaseKillCooldown": "Увеличить откат убийства", "ReverieMaxKillCooldown": "Максимальный откат убийства", "ReverieMisfireSuicide": "Убивается если откат убийства дойдёт до максимума", "ReverieResetCooldownMeeting": "Сбросить откат убийства после встречи", "ConvertedReverieKillAll": "Преобразованный Мечтатель может убить кого угодно без каких-либо последствий", "VigilanteNotify": "Ты стал тем, что поклялся уничтожить", - "DictatorChangeCommandToExpel": "Dictator use Command to expell instad of vote", - "DictatorExpelSelf": "WAIT WAIT WAIT WAT THE HELLLLLL Bro really just want to expel himself", "DoctorTaskCompletedBatteryCharge": "Длительность батарейки", "SnitchEnableTargetArrow": "Может видеть стрелку цели", "SnitchCanGetArrowColor": "Может видеть цвета стрелок", @@ -1629,7 +1593,6 @@ "EvilTrackerTargetMode.OnceInGame": "В каждой игре", "EvilTrackerTargetMode.EveryMeeting": "На каждом собрании", "EvilTrackerTargetMode.Always": "Всегда", - "ScavengerHasCustomDeathReason": "Enable Custom Death Reason", "EvilHackerCanSeeDeadMark": "Может видеть местонахождение трупов", "EvilHackerCanSeeImpostorMark": "Может видеть местонахождение других предателей", "EvilHackerCanSeeKillFlash": "Может видеть Вспышку-Убийства", @@ -1862,21 +1825,13 @@ "Jackal_SidekickCountMode_Jackal": "Шакал", "Jackal_SidekickCountMode_Original": "Первоначальная команда", "Jackal_SidekickAssignMode": "Режим назначения Союзников", - "Jackal_SidekickAssignMode_SidekickAndRecruit": "Sidekick when failed Recruit", - "Jackal_SidekickAssignMode_Sidekick": "Only Sidekick", - "Jackal_SidekickAssignMode_Recruit": "Only Recruit", + "Jackal_SidekickAssignMode_SidekickAndRecruit": "Союзник+Завербованный", + "Jackal_SidekickAssignMode_Sidekick": "Союзник", + "Jackal_SidekickAssignMode_Recruit": "Завербованный", + "JackalWinWithSidekick": "Шакал может победить с командой Союзника", "Jackal_SidekickCanKillSidekick": "Союзники могут убить других Союзников", "Jackal_SidekickCanKillJackal": "Союзники могут убить Шакала", - "Jackal_RecruitFailed": "You can not recruit this player!", "JackalCanKillSidekick": "Шакал может убить Союзника", - "Jackal_SidekickCanKillWhenJackalAlive": "Sidekick can kill while Jackal is Alive", - "Jackal_SidekickTurnIntoJackal": "Sidekick can turn into Jackal after its death", - "Jackal_RestoreLimitOnNewJackal": "Restore Recruit limit when Sidekick become new Jackal", - "Jackal_OnBecomeNewJackalMeeting": "The old Jackal {0} is dead.\nYou are selected as new Jackal\nWork together and win the game!", - "Jackal_OnNewJackalSelectedMeeting": "The old Jackal {0} is dead.\n{1} is selected as new Jackal!\nWork together and win the game!", - "Jackal_BecomeNewJackal": "Old Jackal Dead, You are now new Jackal!", - "Jackal_OnNewJackalSelected": "Old Jackal Dead, Please help new Jackal {0} for now!", - "Jackal_BossIsDead": "Opps, the Jackal boss is dead!", "CoronerArrowsPointingToDeadBody": "Стрелки указывающие на трупы", "CoronerLeaveDeadBodyUnreportable": "Трупы, с которыми взаимодействовал Коронер нельзя будет зарепортить", "CoronerInformKillerBeingTracked": "Сообщать убийце что его отслеживают", @@ -1914,9 +1869,6 @@ "VipTag": "VIP★", "ApplyVipList": "Применить VIP список", "AllowSayCommand": "Разрешить модераторам использовать команду /say", - "AllowStartCommand": "Allow moderators to use /start command", - "StartCommandMinCountdown": "Minimum countdown for /start command", - "StartCommandMaxCountdown": "Maximum countdown for /start command", "KickCommandDisabled": "Команда кика в настоящее время отключена.", "KickCommandNoAccess": "У вас нет доступа к команде кика.", "KickCommandInvalidID": "Указан неверный идентификатор игрока.\nИспользуйте «/kick [playerID] [причина]», чтобы кикнуть игрока.\nПример:- /kick 5 не соблюдает правила", @@ -1949,11 +1901,6 @@ "WarnCommandNoAccess": "У вас нет доступа к команде предупреждения.", "WarnCommandInvalidID": "Указан неверный идентификатор игрока.\nИспользуйте «/warn [идентификатор игрока] [причина]», чтобы предупредить игрока. \nПример: - /warn 5 пишет в чат во время изгнания", "WarnCommandWarnHost": "Вам не разрешено предупреждать Хоста.", - "StartCommandNoAccess": "You do not have access to the start command.", - "StartCommandDisabled": "The start command is currently disabled.", - "StartCommandCountdown": "ERROR\n\nThe game is already starting!", - "StartCommandStarted": "The game has been started by {0}!", - "StartCommandInvalidCountdown": "ERROR\n\nThe countdown must be between {0} and {1}!", "WarnCommandWarnMod": "Вы не имеете права предупреждать других модераторов.", "WarnCommandWarned": "был предупрежден. Предупреждений больше не будет, и будут предприняты соответствующие действия \n ", "WarnExample": "Используйте /warn [Айди] [Причина] в будущем. \nПример:-\n /warn 5 пишет в чат во время изгнания", @@ -1981,7 +1928,6 @@ "DeathReason.Quantization": "Квантование", "DeathReason.Overtired": "Переработал", "DeathReason.Ashamed": "Пристыженный", - "DeathReason.Consumed": "Consumed", "DeathReason.PissedOff": "Уничтожен", "DeathReason.Dismembered": "Расчленен", "DeathReason.LossOfHead": "Задушен", @@ -2005,8 +1951,6 @@ "DeathReason.Starved": "Голод", "DeathReason.Equilibrium": "Равновесие", "DeathReason.Sacrificed": "Пожертвовал", - "DeathReason.Electrocuted": "Electrocuted", - "DeathReason.Scavenged": "Scavenged", "OnlyEnabledDeathReasons": "Только активные причины смерти", "Alive": "Выжил", "Disconnected": "Вышел", @@ -2072,7 +2016,6 @@ "Command.dump": "→ Вывод журнала на Рабочий Стол", "Command.death": "→ Показать информацию о том, как вы умерли", "Command.icons": "
╳ - Игрок был отмечен Шантажистом и не может говорить во время Собрания
☆ - Используется Капитаном для обозначения себя. Только Члены экипажа могут видеть звезду Капитана
乂 - Этот игрок был заколдован Мастером Проклятий и умрёт, если Мастер Проклятий не будет убит или изгнан до конца Собрания.
♦️ - Используется Адвокатом или Палачом или Последователем.
♥️ - Используется Любовниками или Романтиками.
✚ - Используется Медиком для обозначения своей цели.
⦿ - Этот игрок находится в дуэли с Пиратом.
!? - Этот игрок был отмечен Мастером Викторины и должен правильно ответить на вопрос, чтобы выжить.
☜ - Используется Котом Шрёдингера для обозначения своего напарника.
◈ - Этот игрок был отмечен Покровом и умрёт, если Покров не будет убит или изгнан до конца Собрания.
⚠️ - Этот игрок является Стукачом или Солнечным, который завершил свои задачи.
★ - Используется Суперзвездой, Знаменитым или Маршалом.
† - Этот игрок был заколдован и умрёт, если Ведьма не будет убита до конца Собрания.
∇ - Используется Камикадзе для обозначения своих целей.
■ - Используется Молнией для обозначения своих квантовых призраков.
⊠ - Используется Тюремщиком для обозначения своего заключенного.
● - Используется Пекарь отметить, у кого есть Хлеб.
♠ - Используется Коллектор Душ чтобы отметить, чью смерть они предсказывают.
⦿ - Используется Носитель Чумы чтобы отметить, кого они заразили.", - "Command.start": "[Seconds] → Start the game", "Command.iconinfo": "→ Показывать информацию на иконках собрания", "Command.iconhelp": "→ Показывать информацию на иконках собрания для всех", "Command.Poll": "→ Начать опрос, выбрав до 5 вариантов", @@ -2085,7 +2028,6 @@ "ShowMadmatesInLeftCommand": "Показывать Безумцев (включая атрибут)", "ShowApocalypseInLeftCommand": "Может видеть Нейтральный Апокалипсис", "SeeEjectedRolesInMeeting": "Видеть роли изгнанных во время встречи", - "ThankYouForUsingTOHE": "Thank you for using TOHE!", "SkillUsedLeft": "Вы активировали навык для проведения собрания. \nОставшееся количество использование вашего навыка:", "NemesisDeadMsg": "Смерть Немезиса означает начало мести. \nПожалуйста, используйте /rv + [номер игрока], чтобы убить указанного игрока \nВы можете увидеть номер игрока перед его именем. \nИли введите команду /rv, чтобы получить список номеров игроков", "NemesisAliveKill": "Месть за Немезиса может начаться только после его смерти.", @@ -2105,7 +2047,6 @@ "GuessNotifiedBait": "Супер Звезда не может быть угадана, ты думал что всё так просто, да?", "GuessGM": "Угадать GM невозможно, потому что он уже и так мертв... И зачем так поступать с бедным Хостом?", "GuessGuardianTask": "Вы не можете угадать Стража, который выполнил все свои задания.", - "GuardianCantKilled": "You can't kill a Guardian who has finished their tasks.", "GuessMarshallTask": "Вы не можете угадать маршала, который выполнил все свои задания.", "GuessObviousAddon": "Извините, очевидные атрибуты не угадываются.", "GuessAdtRole": "К сожалению, настройки Хоста не позволяют угадывать Атрибуты", @@ -2161,7 +2102,6 @@ "BecomeMadmateCuzMadmateMode": "Вы стали Безумцем из-за своей смерти", "CleanerCleanBody": "Труп был очищен", "QuickShooterStoraging": "Пули сохранены успешно", - "QuickShooterFailed": "You are still in cooldown.", "PoisonerTargetDead": "Ваша цель умерла", "HexesLookLikeSpells": "Мастер Проклятий выглядят как Заклинатель", "HexButtonText": "Порча", @@ -2320,7 +2260,6 @@ "Message.YTPlanNotice": "Внимание: в этой комнате включен [режим Ютуб Ролика], владелец может поставить отдельные роли игрокам.\n Эта функция может использоваться только для создания видео роликов, если создатель комнаты нарушает это правило, выйдите или сообщите о нём.\n Текущие настройки:", "Message.OnlyCanBeUsedByHost": "ОШИБКА\n\nЭту команду может использовать только хост лобби", "Message.MaxPlayers": "Максимальное количество игроков установлено на ", - "Message.MaxPlayersFailByRegion": "Could not set max players: Vanilla regions support a maximum of 15 players.", "Message.GhostRoleInfo": "Информация о роли призрака\nПривет! Немного о ролях-призраках...\n\nРоли призраков сильно влияют на игру, поэтому не рекомендуется использовать их в небольших лобби.\nЕсли в описании явно не указано иное, кнопка «Охрана» является кнопкой их способностей ;)\n\nПоявление:\nРоли-призраки появляются только после смерти, их получают первые X игроков из (команды), которые умрут.\n\nПримечание: Если у изначальной роли не было задач (например у шерифа), ваши задачи в роли призрака не нужны для победы с помощью выполнения всех задач.", "ApocalypseInfoTitle": "Нейтральный Апокалипсис инфо:", "Message.ApocalypseInfo": "У каждой роли команды <#ff174f>Апокалипсиса есть своя цель, которую нужно выполнить, чтобы трансформироваться.\nУчастники <#2B0804>Трансформированного <#ff174f>Апокалипсиса кардинально меняют игру и становятся бессмертными (за исключением голосования), но все будут уведомлены о том, что они трансформировались.\n\nРоли: <#e5f6b4>Носитель Чумы, <#A675A1>Коллектор Душ, <#bf9f7a>Пекарь,<#cc0044>Берсерк.\nТрансформированные: <#343136>Чума, <#644661>Смерть, <#83461c>Голод, <#2B0804>Война.\n\nАпокалипсис может видеть роли и иконки способностей друг друга.\nКак и нейтральные убийцы, участники Апокалипсиса продолжают игру, веселитесь!", @@ -2725,9 +2664,8 @@ "DeathMeetingTimeIncrease": "Увеличено время встречи при наличии Смерти", "SoulCollectorMeetingDeath": "Ваша цель умерла во время встречи. Вы обрели душу.", "SoulCollectorKillButtonText": "Прогноз", - "SoulCollectorHasImpostorVision": "Soul Collector has Impostor vision", "ApocalypseIsNigh": "[ Апокалипсис близок! ]", - "ApocalypseImmune": "This role is immune!", + "ApocalypseImmune": "Этот игрок имеет иммунитет потому что он непобедим!", "BakerToFamine": "Ты стал Голодом!!!", "BakerTransform": "Пекарь стал Голодом, Всадником Апокалипсиса! Начался голод!", "BakerAlreadyBreaded": "Игрок уже имеет хлеб!", @@ -2736,15 +2674,13 @@ "BakerBreadNeededToTransform": "Количество хлеба для того, чтобы стать Голодом", "BakerCantBreadApoc": "Ты не можешь давать хлеб другим Апокалипсисам!", "BakerKillButtonText": "ХЛЕБ", - "BakerUnshiftButtonText": "Switch Bread", "BakerRevealBread": "РАСКРЫТЬ", "BakerRoleblockBread": "ЗАБЛОКИРОВАТЬ", "BakerBarrierBread": "БАРЬЕР", "BakerCurrentBread": "Количество хлеба: ", "BakerSwitchBread": "Хлеб переключен на: ", - "BakerCanVent": "Baker can Vent", + "BakerCanVent": "Пекарь может использовать вентиляцию", "BakerBreadGivesEffects": "Хлеб даёт дополнительные эффекты", - "BakerTransformNoMoreBread": "Baker transforms if they do not have enough bread", "FamineKillButtonText": "ГОЛОДАТЬ", "FamineStarveCooldown": "Откат голода (Голод)", "FamineCantStarveApoc": "Ты не можешь голодать других Апокалипсисов!", @@ -2791,7 +2727,6 @@ "GodfatherTargetCountMode": "Убийца превращается в", "GodfatherCount_Refugee": "Беженец", "GodfatherCount_Madmate": "Безумец", - "GodfatherRefugeeMsg": "You have been recruited by GodFather!", "MissChance": "Шанс промазать", "IncreaseByOneIfConvert": "Увеличить количество убийств на +1, если экипаж был преобразован", "HawkMissed": "Промах!", @@ -2824,7 +2759,6 @@ "BerserkerToWar": "Вы стали Войной!!!", "BerserkerTransform": "Берсерк превратился в Войну,\nВсадник Апокалипсиса! Крикните «Хаос!» и выпустите псов войны.", "WarKillCooldown": "Откат убийства у Войны", - "BerserkerCanKillTeamate": "Can kill other Neutral Apocalypse", "BlackmailerSkillCooldown": "Откат Шантажа", "BlackmailerMax": "Максимальное количество раз, когда шантажированный игрок может говорить", "BlackmailerDead": "Внимание! {0} был Шантажирован!", @@ -2914,8 +2848,6 @@ "RememberedPursuer": "Ты вспомнил что ты Преследователь!", "RememberedFollower": "Ты вспомнил что ты Последователь!", "RememberedAmnesiac": "Тебе не удалось вспомнить свою роль.", - "AmnesiacRemembered": "You remembered you were {0}!", - "ReportWhenFailedRemember": "Report Dead Body when failed to remember", "RememberedImitator": "Вы вспомнили, что вы Имитатор.", "RememberedImpostor": "Ты вспомнил что ты Предатель!", "RememberedCrewmate": "Ты вспомнил что ты Член Экипажа!", @@ -3329,12 +3261,9 @@ "PixieTargetAlreadySelected": "Цель уже выбрана", "PixieButtonText": "Пометить", "PlagueBearerCooldown": "Откат заражения", - "PlagueBearerCanVent": "Can vent", - "PlagueBearerHasImpostorVision": "Has Impostor vision", "PestilenceCooldown": "Откат убийства Чумы", "PestilenceCanVent": "Чума может использовать вентиляцию", "PestilenceHasImpostorVision": "Чума имеет обзор Предателей", - "PestilenceKillGuessers": "Kill players who guess Pestilence", "PlagueBearerAlreadyPlagued": "Игрок уже заражён", "PlagueBearerToPestilence": "Вы превратились в Чуму!!", "GuessPestilence": "Вы только что попытались угадать Чуму!\n\nВ подарок, Чума убила вас.", @@ -3378,7 +3307,6 @@ "EveryoneCanKnowMini": "Все могут видеть Мини", "CanBeEvil": "Может стать Злым Мини", "EvilMiniSpawnChances": "Вероятность что Мини окажется Злым Мини", - "EvilMiniCanBeGuessed": "Evil Mini can be guessed before 18", "GuessMini": "Извините, вы не можете угадать Мини пока он не вырастет.", "GrowUpDuration": "Секунды необходимое для роста", "MajorCooldown": "Откат убийства когда ему больше 18 лет", @@ -3520,7 +3448,6 @@ "WinnerRoleText.Doppelganger": "Двойник Победил!", "WinnerRoleText.Quizmaster": "Мастер Викторины Победил!", "WinnerRoleText.Agitater": "Агитатор Победил!", - "WinnerRoleText.Shocker": "Shocker Wins!", "AdditionalWinnerRoleText.Sidekick": "Союзник", "AdditionalWinnerRoleText.Taskinator": "Таскинатор", "AdditionalWinnerRoleText.Opportunist": "Выжившие", @@ -3606,7 +3533,7 @@ "SolsticerOnMeeting": "Вы стали свидетелем слишком большого количества смертей! В следующем раунде у вас будет еще {0} короткое задание!", "SolsticerTitle": "СОЛНЕЧНЫЙ", "GuessSolsticer": "Извините, но вы не можете угадать Солнечного!", - "ExpelSolsticer": "Sorry, but you can not expel Solsticer!", + "VoteSolsticer": "Извините, но вы не можете голосовать за Солнечного!", "SolsticerTasksReset": "Ваши задания были сброшены!", "SolsticerMisGuessed": "Вы неправильно угадали! Теперь вы не можете гадать.", "SolsticerGuessMax": "По скольку вы уже неправильно угадали, вы больше не можете гадать.", @@ -3707,28 +3634,6 @@ "MinionAbilityTime": "Продолжительность способности", "Minion_Blind": "ослеплён", "Evader_ChanceNotExiled": "Шанс не быть выкинутым", - "ShockerAbilityCooldown": "Ability Cooldown", - "ShockerAbilityDuration": "Ability Duration", - "ShockerAbilityPerRound": "Abilities Per Round", - "ShockerShockInVents": "Shock people in vents", - "ShockerAbilityResetAfterMeeting": "Reset marked rooms after meeting", - "ShockerOutsideRadius": "Radius Of Outside Tasks (not in a room)", - "ShockerCanShockHimself": "Can Shock Himself", - "ShockerImpostorVision": "Shocker has Impostor vision", - "ShockerIsShocking": "You're already shocking!", - "ShockerAbilityActivate": "Begin Shocking!", - "ShockerAbilityDeactivate": "Ability Deactivated", - "ShockerVentButtonText": "Shock", - "ShockerRoomMarked": "Marked Room", "EavesdropperMsgTitle": "Вы нашли секрет", - "EavesdropPercentChance": "Шанс подслушать", - "ChiefOfPoliceSkillCooldown": "Cooldown for recruiting sheriffs", - "PolicCanImpostorAndNeutarl": "Can recruit Impostor or Neutral", - "SheriffSuccessfullyRecruited": "You recruited a sheriff.", - "BeSheriffByPolice": "You've been recruited by the police chief! Serve the crew!", - "PoliceFailedRecruit": "Failed to recruit target.", - "ChiefOfPoliceKillButtonText": "Recruitment", - "PolicPreventRecruitNonKiller": "Prevent recruit players without kill button", - "PolicSuidiceWhenTargetNotKiller": "Suidices when recruit a non killer or non crewmate", - "PolicPassConverted": "Can pass Converted Addon to Sheriff" -} \ No newline at end of file + "EavesdropPercentChance": "Шанс подслушать" +} diff --git a/Resources/Lang/zh_CN.json b/Resources/Lang/zh_CN.json index 1a5735d5b..3febdbe70 100644 --- a/Resources/Lang/zh_CN.json +++ b/Resources/Lang/zh_CN.json @@ -19,8 +19,6 @@ "SubText.Neutral": "不属于其他阵营的独立阵营", "SubText.Apocalypse": "与你的队伍一起变得势不可挡", "SubText.Madmate": "不要给内鬼帮倒忙了哦", - "SubText.Lovers": "最重要的是,记得照顾好你的另一半", - "SubText.Egoist": "什么叫做一波三折?", "TypeImpostor": "内鬼阵营", "TypeCrewmate": "船员阵营", "TypeNeutral": "中立阵营", @@ -30,9 +28,6 @@ "TeamNeutral": "中立阵营", "TeamCrewmate": "船员阵营", "TeamMadmate": "叛徒阵营", - "TeamLovers": "恋人", - "TeamEgoist": "利己主义者", - "TeamApocalypse": "灾厄职业", "YouAreCrewmate": "你是一名船员", "YouAreImpostor": "你是一名内鬼", "YouAreNeutral": "你是一名中立", @@ -224,7 +219,6 @@ "TaskManager": "任务管理者", "Witness": "目击者", "Swapper": "换票师", - "ChiefOfPolice": "警局局长", "NiceMini": "好迷你船员", "Mini": "迷你船员", "Spy": "间谍", @@ -253,7 +247,6 @@ "Stalker": "潜藏者", "Workaholic": "工作狂", "Solsticer": "至日者", - "Abyssbringer": "深渊使者", "Collector": "集票者", "Provocateur": "自爆卡车", "BloodKnight": "嗜血骑士", @@ -392,8 +385,6 @@ "Sloth": "树懒", "Prohibited": "受限者", "Eavesdropper": "窃听者", - "Shocker": "震击者", - "Revenant": "荒野猎人", "BracketAddons": "将附加职业以括号的形式显示", "EngineerTOHEInfo": "敌明我暗,邪恶无处遁形", "ScientistTOHEInfo": "随时使用生命体征器,生死拿捏于股掌", @@ -512,7 +503,6 @@ "PacifistInfo": "何必打打杀杀呢?", "RebirthInfo": "再次崛起", "MonarchInfo": "我今日封你为骑士,至此你无论如何都要效忠于我", - "AbyssbringerInfo": "创造黑洞", "SpurtInfo": "敏捷如兔,跃入春日!", "StealthInfo": "你似乎不该看到什么,闭上眼睛", "PenguinInfo": "你充Q币吗?不充?拖走!", @@ -546,7 +536,6 @@ "WitnessInfo": "我似乎目击到了什么", "GhastlyInfo": "你的附身具有强迫", "SwapperInfo": "打出极限翻盘的操作吧", - "ChiefOfPoliceInfo": "雇佣警长为船员服务!", "NiceMiniInfo": "长大前没人能伤害你", "ArsonistInfo": "燃烧吧!燃烧吧!我要让你们尸骨无存!!", "PyromaniacInfo": "让我把你的火浇灭吧", @@ -707,8 +696,6 @@ "SlothInfo": "见证树懒修BUG的速度", "ProhibitedInfo": "有的管道你注定钻不了", "EavesdropperInfo": "我能听到你在干什么", - "ShockerInfo": "震击毫无戒心的玩家", - "RevenantInfo": "担任带刀职业", "EngineerTOHEInfoLong": "(船员阵营):\n工程师可以在通讯被破坏情况下进入通风口", "ScientistTOHEInfoLong": "(船员阵营):\n科学家可以随时查看生命体征,了解谁还活着,谁已经死亡", "NoisemakerTOHEInfoLong": "(船员阵营):\n大嗓门每当死亡时都会发出声音,屏幕上也会出现大嗓门死亡的直观提示", @@ -780,11 +767,11 @@ "LurkerInfoLong": "(内鬼阵营):\n潜伏者可以通过钻洞减少一定的击杀CD。在完成击杀后,潜伏者的冷却时间会被重置为默认值", "VisionaryInfoLong": "(内鬼阵营):\n幻想家可以在会议上看见每个玩家的阵营:\n- 红色名表示内鬼阵营\n- 青色名表示船员阵营\n -灰色名表示中立阵营", "PlagueDoctorInfoLong": "(中立阵营)「来自TOH的瘟疫医生」:\n瘟疫学家选择一名玩家进行感染。任何在被感染玩家范围内停留一定时间的玩家都会被感染。感染进度是累积性的,不会随着距离或会议后重置", - "RefugeeInfoLong": "(叛徒阵营):\n逃亡者可能是:\n -通过回忆得知自己是一名内鬼\n -击杀了教父目标的带刀玩家\n -其恋人是内鬼的浪漫者\n -效仿了内鬼的效仿者\n\n现在你的职责是帮助内鬼阵营击杀船员阵营", + "RefugeeInfoLong": "(叛徒阵营):\n逃亡者通过回忆或者被教父洗脑获得这个职业。逃亡者相当于普通内鬼", "UnderdogInfoLong": "(内鬼阵营):\n失败者只能在在场存活人数小于房主设置的人数时才能进行击杀", "ConsigliereInfoLong": "(内鬼阵营):\n军师可以对一位玩家使用击杀键来得知目标的职业。当显示职业次数用完时,击杀为正常击杀\n- 单击显示身份\n- 双击正常击杀", "LudopathInfoLong": "(内鬼阵营):\n速度者的击杀冷却时间是随机的。击杀冷却最小值为1秒,而最大值是房主设置的默认击杀冷却时间", - "GodfatherInfoLong": "(内鬼阵营):\n教父投票给某人,让他们成为教父的目标。在下一轮中,如果有人击杀了目标,凶手将变成逃亡者或者叛徒", + "GodfatherInfoLong": "(内鬼阵营):\n教父投票给某人,让他们成为教父的目标。在下一轮中,如果有人击杀了目标,凶手将变成逃亡者", "ChronomancerInfoLong": "(内鬼阵营):\n天文学家有一个电量条,显示屠杀准备就绪的时间。 当电量达到「100%」时,下一次击杀时天文学家就会进入屠杀模式,天文学家就可以展现杀戮光环,直到电量耗尽。其他情况下,天文学家的击杀冷却是正常的", "PitfallInfoLong": "(内鬼阵营):\n设陷者使用变形可以将变形周围的区域标记为陷阱。进入该区域的玩家会在短时间内无法动弹,视野也会受到影响", "EvilMiniInfoLong": "(内鬼阵营):\n坏迷你船员在长大之前不可被击杀和被招募,且初始击杀冷却非常长,当坏迷你船员长大后击杀冷却会大幅缩短", @@ -848,7 +835,7 @@ "AdmirerInfoLong": "(船员阵营):\n仰慕者可以仰慕一名玩家,使他们加入船员阵营。被仰慕的玩家会跟随船员阵营获胜。\n仰慕者只能仰慕一次玩家。即使之后被仰慕的玩家的阵营发生改变,仰慕的玩家也不能再仰慕他。", "TimeMasterInfoLong": "(船员阵营):\n时间之主可以使用通风口标记每个人的位置。再次使用该技能时,每个活着的玩家都会被倒回标记的位置。在该技能持续时间内,时间之主获得一个时间盾,保护他们免于死亡", "CrusaderInfoLong": "(船员阵营):\n十字军可以使用击杀键来给予玩家护盾。若护盾生效期间该玩家受到了攻击,则十字军会反杀攻击者", - "AltruistInfoLong": "(船员阵营):\n殉道者可以牺牲自己复活它人。通过报告尸体来使用技能。\n注意:如果被报告的人死了且退出游戏,殉道者会直接报告,不触发技能。\n被复活的玩家也不能报告自己的尸体", + "AltruistInfoLong": "(船员阵营):\n殉道者可以牺牲自己复活它人。通过报告尸体来使用技能。\n注意:如果被报告的人死了且退出游戏,利他主义者会直接报告,不触发技能。\n被复活的玩家也不能报告自己的尸体", "ReverieInfoLong": "(船员阵营):\n遐想者可以击杀,但开始时击杀冷却时间较长。如果击杀了一名船员,冷却时间会延长,反之则会缩短。根据房主设置,遐想者可能会在达到最大击杀冷却时间时误杀,导致目标与遐想者同归于尽。", "LookoutInfoLong": "(船员阵营):\n瞭望者可以随时看到每个玩家的ID。变形者的id显示为本体的id,这可以让瞭望者看到变形和伪装。", "TelecommunicationInfoLong": "(船员阵营):\n当有人使用监控、生命体征、日志或管理室的定位地图时,通信员会收到通知", @@ -856,7 +843,6 @@ "TaskManagerInfoLong": "(船员阵营):\n任务管理者可以看到自己身份名称旁边的已完成任务总数(所有人共同完成的),并会实时更新", "WitnessInfoLong": "(船员阵营):\n目击者对某人使用击杀按钮时,目击者会知道他是否在最后X秒内被击杀。(X取决于设置)。如果该玩家没使用击杀,会显示「√」。相反,使用击杀的玩家会显示「⚠」", "SwapperInfoLong": "(船员阵营):\n换票师可以在会议时交换任意2人的票数,使用换票指令可以选择第一位玩家,再次使用换票指令可以选择第二位玩家,然后进行换票。\n换票指令:/sw [玩家编号]\n你可以在玩家名字前看到该玩家的编号,或者使用/id指令查看所有玩家的编号\n根据房主设置,换票师可以交换自己的票数", - "ChiefOfPoliceInfoLong": "(船员阵营):\n可以将带刀船员招募到警长的队伍来为船员服务\n注:只有一个招募机会\n根据设置,您可以招募非带刀玩家或非船员。\n你可能会因为招募了错误的目标而自杀。", "NiceMiniInfoLong": "(船员阵营):\n好迷你船员的生存至关重要。在你长大之前,你不会被杀死,如果你在长大之前死亡或被驱逐出会议,那么所有人都会输掉游戏。这个独特的角色为游戏增添了新的活力,你的生存不仅是为了自己的利益,也是为了整个团队的成功。", "SpyInfoLong": "(船员阵营):\n当有人对间谍使用击杀/技能时,间谍会在几秒钟内看到该玩家的名字是橙色的\n注意:如果带刀船员对间谍使用了技能,间谍会看到带刀船员的名字是橙色的\n注意:如果间谍已经没有技能次数了,就看不到橙色的名字\n注意:如果击杀阻止,带刀玩家的冷却时间将重置为10秒", "RandomizerInfoLong": "(船员阵营):\n萧暮被击杀时,会给击杀萧暮的玩家执行以下操作之一:\n1. 强制报告尸体\n2. 暂时无法移动\n3. 将其击杀冷却时间设置为 600 秒\n4. 随机为一名玩家复仇.", @@ -871,7 +857,7 @@ "LawyerInfoLong": "(中立阵营):\n游戏开始时律师会被分配到一个目标,并在其昵称旁用菱形「♦」表示。若律师目标胜利,则律师一起胜利。若律师的目标死亡,将依据房主设置变换。\n注意:律师死亡后也可以胜利", "OpportunistInfoLong": "(中立阵营):\n若投机者在游戏结束时存活,则投机者跟随获胜玩家一同获得胜利", "VectorInfoLong": "(中立阵营):\n马里奥跳管达到一定次数就会单独获得胜利", - "JackalInfoLong": "(中立阵营):\n豺狼可以使用击杀按钮进行招募。如果目标不是可以招募的,要么招募次数已经用完了,要么房主没开招募的选项,那么豺狼将正常击杀(也就是说,不要在其他人面前使用击杀按钮,以为这样就能招募)。如果目标有击杀按钮,并且开启了招募跟班的选项,那么他们就会变成跟班。根据设置,当豺狼被击杀时,会随机选择一个跟班作为新的豺狼。\n如果没有跟班活着,可以选择招募。", + "JackalInfoLong": "(中立阵营):\n豺狼可以使用击杀按钮进行招募。如果目标不是可以招募的,要么招募次数已经用完了,要么房主没开招募的选项,那么豺狼将正常击杀(也就是说,不要在其他人面前使用击杀按钮,以为这样就能招募)。如果目标有击杀按钮,并且开启了招募跟班的选项,那么他们就会变成跟班", "GodInfoLong": "(中立阵营):\n神从一开始就知道所有人的身份,而神只要活到最后就会抢走胜利", "InnocentInfoLong": "(中立阵营):\n冤罪师可以用击杀键栽赃任意一位玩家,被栽赃的目标会立刻击杀冤罪师,若目标在会议上被驱逐则冤罪师获胜", "PelicanInfoLong": "(中立阵营):\n仅剩鹈鹕阵营与船员阵营且鹈鹕阵营人数大于船员人数,鹈鹕获得胜利。鹈鹕可以使用击杀键活吞一位玩家(被活吞的玩家将被传送到地图外且无法与游戏互动),活吞成功后鹈鹕将看到自己身上出现盾牌破碎的动画作为提示。紧急会议或报告尸体会导致鹈鹕吞下的所有玩家立刻死亡。若鹈鹕死亡或掉线,则被吞下的所有玩家立刻回到鹈鹕死亡的位置。\n请注意:鹈鹕吞人不是正常击杀方式,因此保镖、老兵等职业技能不会生效。", @@ -883,7 +869,7 @@ "SolsticerInfoLong": "(中立阵营):\n至日者无法死亡的,只要做完任务就朝圣成功获胜了,但是每一轮会议后至日者的任务都会被重置。\n注意:试图击杀至日者会让至日者像被鹈鹕吞掉一样传送到地图外,击杀者的CD被重置为10秒\n注意:根据设定,至日者可能知道试图击杀他的人的职业。在至日者将要完成任务时,带刀玩家会得到指向至日者的箭头。\n至日者在游戏中为无阵营", "CollectorInfoLong": "(中立阵营):\n集票者投票给一名玩家后,可以收集到本次会议该玩家被投的所有票数。当集票者收集到指定数量的票后,则集票者单独胜利。请注意:集票者的胜利优先于驱逐玩家。", "GlitchInfoLong": "(中立阵营):\n缺点者可以入侵玩家(单击)或正常击杀(双击)。缺点者可以黑进玩家,让他们在一段时间内无法击杀、使用通风管和报告尸体。此外,除门以外的破坏行为不会产生任何效果。", - "SidekickInfoLong": "(中立阵营):\n跟班的职责是帮助豺狼击杀所有人。\n你和豺狼同赢共败。\n根据设置,如果老豺狼被杀,你可能会变成新的豺狼。\n在老豺狼死之前,你可能无法进行击杀。", + "SidekickInfoLong": "(中立阵营):\n仅剩豺狼阵营与船员阵营且豺狼阵营人数大于船员人数,豺狼阵营获得胜利。跟班属于豺狼阵营。", "ProvocateurInfoLong": "(中立阵营):\n自爆卡车可以用击杀键与任意目标同归于尽。若游戏结束时目标输了,则自爆卡车与胜利阵营一起胜利。", "BloodKnightInfoLong": "(中立阵营):\n仅剩嗜血骑士阵营与船员阵营且嗜血骑士阵营人数大于船员人数,嗜血骑士获得胜利。嗜血骑士每次击杀后都可以获得一定时间的护盾,护盾可以抵消所有常规击杀,直到护盾超时失效。", "PlagueBearerInfoLong": "(灾厄职业):\n瘟疫使者可以使用击杀按钮将其他玩家变成瘟疫。一旦变成瘟疫,瘟疫使者将拥有不死之身!并获击杀能力。且瘟疫使者将击杀任何试图击杀瘟疫使者的玩家。\n此外,当受感染瘟疫的玩家与未受感染瘟疫的玩家互动时,也会受到瘟疫感染", @@ -910,12 +896,11 @@ "TraitorInfoLong": "(中立阵营):\n背叛者知道内鬼,但内鬼不知道背叛者。内鬼可以击杀背叛者,但背叛者不能击杀内鬼。通过其他方式击杀内鬼,然后击杀其他人获胜", "TrollerInfoLong": "(中立阵营):\n暴君可以通过完成任务,让随机事件发生在玩家身上。例如,改变所有玩家的速度、传送、影响破坏等\n暴君与获胜的阵营一起获胜", "VultureInfoLong": "(中立阵营):\n秃鹫报告一具尸体时,且秃鹫的进食冷却时间到了,秃鹫可以吃掉尸体。如果秃鹫的进食技能仍然处于冷却状态,那么秃鹫会正常报告尸体。此外,如果达到每轮吃掉的最大尸体数,秃鹫将正常报告尸体", - "AbyssbringerInfoLong": "(内鬼阵营):\n深渊使者可以放置黑洞。黑洞将玩家吸入并在与他们碰撞时击杀他们。", "TaskinatorInfoLong": "(中立阵营):\n任务执行者完成任务时,任务就会被轰炸。 当其他玩家完成被炸任务时,炸弹就会爆炸,玩家就会死亡\n注意:任务执行者放置的炸弹忽略所有保护\n例如:医生的护盾", "BenefactorInfoLong": "(船员阵营):\n恩人每当完成一项任务,该任务就会被标记。当其他玩家完成被恩人标记的任务时,将获得一个临时护盾\n注意:护盾只能抵御直接击杀", "MedusaInfoLong": "(中立阵营):\n美杜莎可以像清理尸体一样石化尸体。无法报告被石化的尸体", "SpiritcallerInfoLong": "(中立阵营):\n灵魂召唤者可以把玩家被击杀后变成恶灵。这些恶灵可以通过短时间冻结其他玩家。或者阻挡他们的视线来帮助灵魂召唤者获胜。再或者,恶灵可以给灵魂召唤者一个护盾,短暂地保护灵魂召唤者免受被击杀", - "AmnesiacInfoLong": "(中立阵营):\n失忆者使用自己的报告按钮记住并获得目标的职业\n为了游戏平衡,当你的职业是失忆者的时候就不能使用通风口,即使你回忆起了自己的职业,你仍然无法使用通风口", + "AmnesiacInfoLong": "(中立阵营):\n失忆者使用的报告按钮来记住玩家的身份。如果目标是内鬼,失忆者将成为逃亡者。如果目标是一名船员,且符合条件,失忆者将成为目标的身份(否则失忆者将成为一名工程师)。如果目标是被动中立或未指定的带刀中立,失忆者将成为设置的中立身份。如果目标是少数人中的带刀中立,失忆者就会成为他们的身份", "ImitatorInfoLong": "(中立阵营):\n效仿者使用击杀按钮效仿一名玩家。效仿者会成为警长、逃亡者或中立.", "BanditInfoLong": "(中立阵营):\n强盗可以使用击杀按钮偷取玩家的附加职业。根据设置,强盗可以立即或在会议开始后偷取附加职业。达到最大偷取次数后,只能正常击杀。此外,如果目标身上没有可偷取的附加职业,就会击杀目标\n注意:- 干净的、仅存内鬼和恋人不能被偷取", "DoppelgangerInfoLong": "(中立阵营):\n替身者使用击杀按钮偷取玩家的身份(他们的名字和皮肤),然后击杀目标玩家。\n注意:- 隐蔽激活时,无法偷取目标身份", @@ -936,7 +921,6 @@ "JinxInfoLong": "(中立阵营):\n每当扫把星受到攻击时,扫把星都会诅咒他们,导致他们死于厄运。这种用途有限。", "PotionMasterInfoLong": "(中立阵营):\n药剂师有三种药水,分别用于三种不同的行动: 揭示身份、双击击杀、地图破坏\n提示:揭示药水是有上限的。当你的药水用完时,会转变为击杀按钮。", "NecromancerInfoLong": "(中立阵营):\n当亡灵巫师试图被杀时,就会被阻挡击杀,并被传送到一个随机的通风口。将在有限的时间内杀死击杀亡灵巫师的玩家。如果成功击杀,就能活下去。如果在杀死击杀亡灵巫师的玩家之前时间耗尽,将永久死亡。如果试图杀死击杀亡灵巫师的玩家以外的其他人,也会死亡", - "ShockerInfoLong": "(中立阵营):\n震击者可以通过在房间里完成任务来标记这些房间,然后在设定的时间段内对房间内的任何人使用震击。当你完成所有任务后,你会获得新的任务。注意:在此期间内完成的任务,将会被标记以供下一次技能使用。", "LastImpostorInfoLong": "(附加职业):\n这个效果在内鬼仅剩一人时赋予该内鬼。使其击杀冷却缩短", "OverclockedInfoLong": "(附加职业):\n超频波的冷却时间将减少设定时间。只分配给带刀职业", "LoversInfoLong": "(附加职业):\n恋人为两名玩家的组合。场上仅剩恋人时恋人获胜。恋人其中一人胜利时另一人也一起胜利。恋人可以看到对方名字旁有「♥」标志。恋人其中一人死亡则另一人殉情(根据房主设置可能不会殉情)。恋人其中一人在会议中被放逐时,另一人将死亡并变为不可以被报告的尸体。", @@ -980,7 +964,7 @@ "RebirthInfoLong": "(附加职业):\n重生者是即将被驱逐的玩家,将与他人交换皮肤,并再次茁壮成长\n警告:如果你耗尽了所有的重生次数,重生就会从你身上消失", "LoyalInfoLong": "(附加职业):\n忠诚不能被豺狼或邪教等身份招募。不能分配给中立", "EvilSpiritInfoLong": "(附加职业):\n恶灵的工作是帮助灵魂召唤者取得胜利。恶灵可以使用闹鬼技能来冻结玩家并减少他们的视野。或者,恶灵可以使用你的闹鬼技能暂时为灵魂召唤者提供一个防御击杀的盾牌", - "RecruitInfoLong": "(附加职业):\n当你被招募时,你加入了豺狼的团队,帮助豺狼和他们的跟班。\n你不能和你原来的阵营一起获胜。\n根据设置,如果老豺狼被杀,且没有跟班活着,你可能会变成豺狼。", + "RecruitInfoLong": "(附加职业):\n帮助豺狼。无法与原阵营一起获胜", "AdmiredInfoLong": "(附加职业):\n你的目的是帮助船员阵营,而不是你原来的阵营", "GlowInfoLong": "(附加职业):\n熄灯期间,「光辉」和「光辉附近的玩家」都会获得视野提升", "RadarInfoLong": "(附加职业):\n雷达的箭头始终指向最近的人", @@ -1024,7 +1008,6 @@ "ProhibitedInfoLong": "(附加职业):\n受限者可以禁用通风口", "EavesdropperInfoLong": "(附加职业):\n窃听者可以阅读其他「职业/附加职业」相关的消息,比如入殓师或侦探", "ApocalypseInfoLong": "(灾厄职业):\n灾厄职业的成员是一个单独的团队,他们一起工作并获胜。 如果游戏中有多个灾厄职业的玩家,他们可以看到彼此的职业。\n取决于房主的设置,灾厄职业可以赌人或被赌。", - "RevenantInfoLong": "(中立阵营):\n荒野猎人的目标是被杀。如果你被杀,你将夺走该带刀玩家的职业并杀掉这个带刀玩家。在你被杀之前,你无法获胜。\n\n注意,荒野猎人的能力只有在被直接击杀时才会生效。", "ShowTextOverlay": "文本覆盖(小字显示)", "Overlay.GuesserMode": "猜测模式", "Overlay.NoGameEnd": "测试模式", @@ -1038,8 +1021,6 @@ "AbilityUseLimit": "初始技能数量", "AbilityInUse": "技能已生效", "AbilityExpired": "技能已结束,剩余{0}次技能", - "RevenantTargeted": "你的身份已模仿为{0}", - "RevenantCanCopyAddons": "可以窃取附加职业", "ShowArrows": "指向尸体的箭头", "ArrowDelayMin": "箭头显示最短延迟时间", "ArrowDelayMax": "箭头显示最长延迟时间", @@ -1368,8 +1349,6 @@ "ShieldedCanUseKillButton": "受保护玩家可以使用能力/击杀按钮", "PlayerIsShieldedByGame": "玩家受到游戏的保护!", "LegacyNemesis": "使用旧版本", - "LegacyParasite": "使用旧版本", - "LegacyTraitor": "使用旧版本", "ArsonistKeepsGameGoing": "当纵火犯在场时,游戏不会结束", "ArsonistCanIgniteAnytime": "可随时点燃", "ArsonistMinPlayersToIgnite": "点火所需的最小浇油量", @@ -1512,18 +1491,6 @@ "SheriffCanKillSeparately": "单独设定", "In%team%": "(%team%阵营)", "SheriffMisfireKillsTarget": "误杀好人的同时击杀目标", - "BlackHolePlaceCooldown": "黑洞放置冷却时间", - "BlackHoleDespawnMode": "黑洞消失模式", - "BlackHoleDespawnTime": "黑洞消失后的时间", - "Abyssbringer.Suffix": "<#00ffa5> {0} 吞噬的玩家数量<#00ffa5>活跃的黑洞:\\n{1}", - "Abyssbringer.Suffix.BlackHole": "<#00ffa5>{0}: {1}", - "BlackHoleMovesTowardsNearestPlayer": "黑洞向最近的玩家移动", - "BlackHoleMoveSpeed": "黑洞移速", - "BlackHoleRadius": "黑洞范围半径", - "AfterTime": "一段时间后", - "After1PlayerEaten": "1名玩家被吞噬后", - "AfterMeeting": "会议之后", - "None": "无", "SheriffShotLimit": "执法次数上限", "SheriffCanKillAllAlive": "全员存活时可以执法", "SheriffCanKillCharmed": "可以执法被魅惑的玩家", @@ -1540,15 +1507,12 @@ "RebirthUses": "重生次数", "RebirthCountVotes": "只有投票给他们的玩家才能重生", "RebirthFailed": "啊,真不幸,你们没有找到可以交换身体的灵魂", - "FireworkerCooldown": "放置黑洞冷却时间", "ReverieIncreaseKillCooldown": "增加击杀冷却时间", "ReverieMaxKillCooldown": "最大击杀冷却时间", "ReverieMisfireSuicide": "在达到最大击杀冷却时间时误杀", "ReverieResetCooldownMeeting": "会议后重置击杀冷却时间", "ConvertedReverieKillAll": "非船员阵营的遐想者可以随意击杀并不受影响", "VigilanteNotify": "你变成了你发誓要摧毁的东西", - "DictatorChangeCommandToExpel": "独裁者使用指令驱逐玩家,而不是投票", - "DictatorExpelSelf": "我嘞个骚刚啊!不是,哥们,你真的想自我驱逐吗?", "DoctorTaskCompletedBatteryCharge": "完成任务增加的设备充能数", "SnitchEnableTargetArrow": "完成任务后显示箭头指向所有目标", "SnitchCanGetArrowColor": "对不同阵营的目标显示不同颜色的箭头", @@ -1629,7 +1593,6 @@ "EvilTrackerTargetMode.OnceInGame": "仅限一次", "EvilTrackerTargetMode.EveryMeeting": "每次会议", "EvilTrackerTargetMode.Always": "永久显示", - "ScavengerHasCustomDeathReason": "启用自定义死因", "EvilHackerCanSeeDeadMark": "可以看到尸体的位置", "EvilHackerCanSeeImpostorMark": "可以看到其他内鬼的位置", "EvilHackerCanSeeKillFlash": "内鬼阵营进行击杀时可见击杀闪光", @@ -1862,21 +1825,13 @@ "Jackal_SidekickCountMode_Jackal": "豺狼", "Jackal_SidekickCountMode_Original": "原始阵营", "Jackal_SidekickAssignMode": "跟班分配模式", - "Jackal_SidekickAssignMode_SidekickAndRecruit": "当选择跟班失败时选择招募", + "Jackal_SidekickAssignMode_SidekickAndRecruit": "跟班+招募的", "Jackal_SidekickAssignMode_Sidekick": "只有跟班", - "Jackal_SidekickAssignMode_Recruit": "只有招募", + "Jackal_SidekickAssignMode_Recruit": "只有招募的", + "JackalWinWithSidekick": "豺狼可以和跟班一起获胜", "Jackal_SidekickCanKillSidekick": "跟班可以击杀其他跟班", "Jackal_SidekickCanKillJackal": "跟班可以击杀豺狼", - "Jackal_RecruitFailed": "您不能招募这位玩家!", "JackalCanKillSidekick": "豺狼可以杀死跟班", - "Jackal_SidekickCanKillWhenJackalAlive": "跟班可以在豺狼存活时进行击杀", - "Jackal_SidekickTurnIntoJackal": "跟班会在豺狼死后变成新豺狼", - "Jackal_RestoreLimitOnNewJackal": "当跟班成为新豺狼时,重置招募次数限制", - "Jackal_OnBecomeNewJackalMeeting": "老豺狼 {0}已经逝去\n你被选为新豺狼\n齐心协力,共赴胜局!", - "Jackal_OnNewJackalSelectedMeeting": "老豺狼 {0}已经逝去\n{1}被选为新豺狼\n齐心协力,共赴胜局!", - "Jackal_BecomeNewJackal": "老豺狼已经逝去,你成为了新豺狼!", - "Jackal_OnNewJackalSelected": "老豺狼已经逝去,请帮助新豺狼{0}!", - "Jackal_BossIsDead": "哦,不!豺狼老大死了!", "CoronerArrowsPointingToDeadBody": "指向尸体的箭头", "CoronerLeaveDeadBodyUnreportable": "验尸官无法报告尸体", "CoronerInformKillerBeingTracked": "通知带刀玩家被跟踪了", @@ -1914,9 +1869,6 @@ "VipTag": "VIP ★", "ApplyVipList": "申请VIP名单", "AllowSayCommand": "允许协管使用/say指令", - "AllowStartCommand": "允许协管使用/start指令", - "StartCommandMinCountdown": "/start 指令的最小倒计时", - "StartCommandMaxCountdown": "/start 指令的最大倒计时", "KickCommandDisabled": "踢出指令已禁用", "KickCommandNoAccess": "你无法使用踢出指令\n因为你没有权限", "KickCommandInvalidID": "指定的玩家ID无效\n请使用“/kick [玩家编号] [理由] 踢出该玩家”\n例子:- /kick 5 不遵守规则", @@ -1949,11 +1901,6 @@ "WarnCommandNoAccess": "你无法使用警告指令\n因为你没有权限", "WarnCommandInvalidID": "指定的玩家ID无效\n请使用“/warn [玩家编号] [理由] 警告该玩家”\n例子:- /warn 5 在驱逐时对话", "WarnCommandWarnHost": "你不能警告房主", - "StartCommandNoAccess": "你无法使用开始指令\n因为你没有权限", - "StartCommandDisabled": "开始指令已禁用", - "StartCommandCountdown": "错误\n\n游戏已经开始!", - "StartCommandStarted": "游戏已由 {0} 开始 !", - "StartCommandInvalidCountdown": "错误\n\n倒计时必须在 {0} 和 {1}之间!", "WarnCommandWarnMod": "你不能警告其他协管玩家", "WarnCommandWarned": "已被警告。我们不会再发出警告,继续犯规会被惩罚。\n ", "WarnExample": "请使用 “/warn [玩家编号] [理由] 警告该玩家”\n例子:-\n /warn 5 在驱逐时对话", @@ -1981,7 +1928,6 @@ "DeathReason.Quantization": "量子化", "DeathReason.Overtired": "猝死", "DeathReason.Ashamed": "卷死", - "DeathReason.Consumed": "吞噬", "DeathReason.PissedOff": "气死", "DeathReason.Dismembered": "肢解", "DeathReason.LossOfHead": "绞杀", @@ -2005,8 +1951,6 @@ "DeathReason.Starved": "饥饿", "DeathReason.Equilibrium": "平衡", "DeathReason.Sacrificed": "献身", - "DeathReason.Electrocuted": "触电", - "DeathReason.Scavenged": "已抹除", "OnlyEnabledDeathReasons": "仅启用死亡原因", "Alive": "存活", "Disconnected": "断连", @@ -2072,7 +2016,6 @@ "Command.dump": "→ 将游戏运行日志输出到桌面", "Command.death": "→ 显示你的死亡信息", "Command.icons": "
╳ - 玩家被勒索者标记,会议期间无法发言。\n
☆ - 被舰长用来标记他们自己。只有船员阵营能看到舰长的星星。\n
乂 - 该玩家被巫师施邪咒,如果巫师在会议结束前没有被击杀或驱逐,该玩家将死亡。\n
♦ - 由律师、刽子手或赌徒使用。\n
♥ - 由恋人或浪漫主义者使用。\n
✚ - 医生用来标记他们的目标。\n
⦿ - 该玩家与决斗者正在进行决斗。\n
!? - 该玩家被测验长标记,必须正确回答问题才能活下去。\n
☜ - 由薛定谔的猫用来标记他们的队友。\n
◈ - 该玩家被裹尸布标记,如果裹尸布在会议结束前没有被击杀或驱逐,该玩家将死亡。\n
⚠ - 该玩家是已完成任务的告密者或至日者。\n
★ - 由大明星、网络员或展现者使用。\n
† - 该玩家被咒杀,如果女巫在会议结束前没有被杀死,该玩家将死亡。\n
∇ - 由神风特攻队用来标记他们的目标。\n
■ - 由球形闪电用来量子轰炸。\n
⊠ - 由狱卒使用来标记被监禁的玩家。\n
● - 由面包师使用来标记谁有面包。\n
♠ - 由灵魂收集者使用来标记他们正在预测谁的死亡。\n
⦿ - 由瘟疫使者使用来标记他们已经使谁染上了瘟疫。", - "Command.start": "[Seconds] → 开始游戏", "Command.iconinfo": "→ 显示会议中图标的信息", "Command.iconhelp": "→ 向每个人显示会议中图标的信息", "Command.Poll": "→ 发起投票,最多5个选项", @@ -2085,7 +2028,6 @@ "ShowMadmatesInLeftCommand": "显示剩余叛徒阵营人数(包括附加职业)", "ShowApocalypseInLeftCommand": "显示<#ff174f>灾厄中立", "SeeEjectedRolesInMeeting": "查看驱逐时的会议身份", - "ThankYouForUsingTOHE": "感谢您使用 TOHE!", "SkillUsedLeft": "你发动技能召开了会议。\n你的技能剩余使用次数:", "NemesisDeadMsg": "黑手党的死亡,意味着复仇的开始\n请使用/rv + [玩家编号] 以击杀指定玩家\n你可以在玩家名字前看到该玩家的编号\n或输入/rv获取玩家编号列表", "NemesisAliveKill": "黑手党的复仇只能在死亡后发动", @@ -2105,7 +2047,6 @@ "GuessNotifiedBait": "大明星才不会和你赌博,选个别的目标吧?", "GuessGM": "能想出这个也是把你闲的", "GuessGuardianTask": "你无法赌死已经完成了任务的守护者", - "GuardianCantKilled": "你无法击杀已经完成了任务的守护者", "GuessMarshallTask": "你无法赌死已经完成了任务的展现者", "GuessObviousAddon": "抱歉,无法猜测明显的附加职业", "GuessAdtRole": "很抱歉,该房设置不允许猜测附加职业", @@ -2161,7 +2102,6 @@ "BecomeMadmateCuzMadmateMode": "你因死亡成为叛徒", "CleanerCleanBody": "目标的尸体已被清理", "QuickShooterStoraging": "子弹储存成功", - "QuickShooterFailed": "您仍处于冷却状态。", "PoisonerTargetDead": "目标已死亡", "HexesLookLikeSpells": "妖术显示为符咒", "HexButtonText": "妖术", @@ -2320,7 +2260,6 @@ "Message.YTPlanNotice": "提示:该房间启用了「创作者素材保护计划」,房主可以指定自己的职业。\n该功能仅允许创作者用于获取视频素材,如遇滥用情况,请退出游戏或举报。\n当前创作者认证:", "Message.OnlyCanBeUsedByHost": "错误\n该指令只能由房主使用", "Message.MaxPlayers": "最大玩家数量设置为", - "Message.MaxPlayersFailByRegion": "无法设置最大玩家数量:原版服务器最多支持15位玩家", "Message.GhostRoleInfo": "幽灵职业信息\n关于幽灵职业的一些信息…\n幽灵职业会对游戏产生巨大影响,因此如果您不熟悉幽灵职业,不建议在少人房间中使用。如果描述中没有明确说明,守护按钮就是幽灵的技能按钮 :)\n出现:\n幽灵职业只有在死亡后才会出现,阵营中最先死亡的人会获得幽灵职业(除中立阵营)\n注:如果您之前的职业没有任务(如警长),则变成幽灵职业的您不需要为任务胜利而去做任务(前提是你没任务)", "ApocalypseInfoTitle": "灾厄中立的信息:", "Message.ApocalypseInfo": "<#ff174f>灾厄阵营中每个职业都有其自己的目标,以实现转变\n<#2B0804>转变后的<#ff174f>灾厄职业将对游戏产生巨大影响,并且它们将不会死亡(除了被投票淘汰外),但所有人都会被通知到它们已经发生了转变。\n职业:<#e5f6b4>瘟疫使者,<#A675A1>灵魂收集者,<#bf9f7a>面包师,<#cc0044>狂战士\n转变后:<#343136>瘟疫,<#644661>死亡,<#83461c>饥荒,<#2B0804>战争者\n灾厄阵营玩家可以看到彼此的职业和技能图标。\n就像带刀中立一样,灾厄玩家也会让游戏继续下去,玩得开心!", @@ -2725,9 +2664,8 @@ "DeathMeetingTimeIncrease": "当死亡存在时,会议时间延长", "SoulCollectorMeetingDeath": "你的目标在会议中死亡。你获得了一个灵魂。", "SoulCollectorKillButtonText": "预言", - "SoulCollectorHasImpostorVision": "灵魂收集者拥有内鬼视野", "ApocalypseIsNigh": "【 ★ 末日即将来临 ★ 】", - "ApocalypseImmune": "该职业免疫!", + "ApocalypseImmune": "这个玩家免疫,因为它们是无敌的!", "BakerToFamine": "你成为了饥荒!!!!", "BakerTransform": "面包师转变成了饥荒,灾厄的骑士,饥荒开始了!", "BakerAlreadyBreaded": "那个玩家已经有面包了!", @@ -2736,15 +2674,13 @@ "BakerBreadNeededToTransform": "饥荒所需的面包数量", "BakerCantBreadApoc": "你不能给其他灾厄成员面包!", "BakerKillButtonText": "面包", - "BakerUnshiftButtonText": "切换面包", "BakerRevealBread": "揭示", "BakerRoleblockBread": "职业封锁", "BakerBarrierBread": "屏障", "BakerCurrentBread": "当前面包: ", "BakerSwitchBread": "面包切换到: ", - "BakerCanVent": "面包师可以使用通风口", + "BakerCanVent": "面包师可以使用通风口", "BakerBreadGivesEffects": "面包具有额外的效果", - "BakerTransformNoMoreBread": "面包师在没有足够的面包时转变", "FamineKillButtonText": "饥饿", "FamineStarveCooldown": "饥荒的饥饿冷却", "FamineCantStarveApoc": "你不能饿死其他灾厄成员!", @@ -2791,7 +2727,6 @@ "GodfatherTargetCountMode": "带刀玩家变成", "GodfatherCount_Refugee": "逃亡者", "GodfatherCount_Madmate": "叛徒", - "GodfatherRefugeeMsg": "你已被教父招募!", "MissChance": "错失概率", "IncreaseByOneIfConvert": "如果船员被更改,最大击杀数会增加+1", "HawkMissed": "你的欧气似乎不太行呢,LOL", @@ -2824,7 +2759,6 @@ "BerserkerToWar": "你成为了战争者!!!!", "BerserkerTransform": "狂战士变成了战争者,灾厄的骑士,大喊大叫,放出战争的猛犬!!!!!!", "WarKillCooldown": "战争者的击杀冷却时间", - "BerserkerCanKillTeamate": "可以击杀其他灾厄中立成员", "BlackmailerSkillCooldown": "勒索冷却时间", "BlackmailerMax": "目标最大说话次数", "BlackmailerDead": "警告!玩家{0}被勒索者勒索了!", @@ -2914,8 +2848,6 @@ "RememberedPursuer": "你记得你是一个起诉人!", "RememberedFollower": "你记得你是一个赌徒!", "RememberedAmnesiac": "你没有记住自己的身份lol", - "AmnesiacRemembered": "你记得你是个{0}!", - "ReportWhenFailedRemember": "当回忆失败时报告尸体", "RememberedImitator": "你记得自己是个效仿者", "RememberedImpostor": "你记得你是个内鬼!", "RememberedCrewmate": "你记得你是个船员", @@ -3329,12 +3261,9 @@ "PixieTargetAlreadySelected": "目标已选定", "PixieButtonText": "标记", "PlagueBearerCooldown": "瘟疫使者冷却时间", - "PlagueBearerCanVent": "可以使用通风口", - "PlagueBearerHasImpostorVision": "拥有内鬼视野", "PestilenceCooldown": "瘟疫击杀冷却", "PestilenceCanVent": "瘟疫可以使用通风口", "PestilenceHasImpostorVision": "瘟疫有内鬼视野", - "PestilenceKillGuessers": "击杀试图猜测瘟疫的玩家", "PlagueBearerAlreadyPlagued": "玩家已经受到瘟疫使者攻击", "PlagueBearerToPestilence": "你变成了瘟疫使者!!", "GuessPestilence": "你只是想猜测瘟疫!\n抱歉,瘟疫杀死了你", @@ -3378,7 +3307,6 @@ "EveryoneCanKnowMini": "所有人都能看到迷你船员", "CanBeEvil": "可以成为坏迷你船员", "EvilMiniSpawnChances": "坏迷你船员的出现概率", - "EvilMiniCanBeGuessed": "坏迷你船员可以在18岁之前被赌", "GuessMini": "球球你放过孩子吧", "GrowUpDuration": "长大所需要的时间(秒)", "MajorCooldown": "长大后的击杀冷却时间", @@ -3520,7 +3448,6 @@ "WinnerRoleText.Doppelganger": "替身者胜利!", "WinnerRoleText.Quizmaster": "测验长胜利", "WinnerRoleText.Agitater": "煽动者胜利!", - "WinnerRoleText.Shocker": "震击者胜利!", "AdditionalWinnerRoleText.Sidekick": "跟班", "AdditionalWinnerRoleText.Taskinator": "任务执行者胜利!", "AdditionalWinnerRoleText.Opportunist": "投机者", @@ -3606,7 +3533,7 @@ "SolsticerOnMeeting": "因为太多人嗝屁了,你感到身上的负担更重了。\n下一轮你将额外获得{0}个短任务", "SolsticerTitle": "至日者", "GuessSolsticer": "你不能猜测神的信徒!", - "ExpelSolsticer": "你不能驱逐神的信徒!", + "VoteSolsticer": "你不能票出神的信徒!", "SolsticerTasksReset": "你的任务惨遭重置了", "SolsticerMisGuessed": "你刚刚猜错了!所以你不能再猜了", "SolsticerGuessMax": "因为你已经猜错了,所以你不能再猜了", @@ -3707,28 +3634,6 @@ "MinionAbilityTime": "技能持续时间", "Minion_Blind": "失明", "Evader_ChanceNotExiled": "概率不被驱逐", - "ShockerAbilityCooldown": "技能冷却时间", - "ShockerAbilityDuration": "技能持续时间", - "ShockerAbilityPerRound": "每轮的技能", - "ShockerShockInVents": "震击通风口内的人", - "ShockerAbilityResetAfterMeeting": "会议后重置标记的房间", - "ShockerOutsideRadius": "外部任务震击半径(不在房间内)", - "ShockerCanShockHimself": "可以震击自己", - "ShockerImpostorVision": "震击者有内鬼视野", - "ShockerIsShocking": "你已经准备好震击了!", - "ShockerAbilityActivate": "震击开始!", - "ShockerAbilityDeactivate": "技能失效", - "ShockerVentButtonText": "震击", - "ShockerRoomMarked": "标记房间", "EavesdropperMsgTitle": "你发现了一个秘密", - "EavesdropPercentChance": "概率偷听", - "ChiefOfPoliceSkillCooldown": "招募警长的冷却时间", - "PolicCanImpostorAndNeutarl": "可以招募内鬼阵营或中立阵营", - "SheriffSuccessfullyRecruited": "你招募了一名警长", - "BeSheriffByPolice": "你被警局局长招募了!为船员效力吧!", - "PoliceFailedRecruit": "招募目标失败", - "ChiefOfPoliceKillButtonText": "招募", - "PolicPreventRecruitNonKiller": "防止招募没有击杀按钮的玩家", - "PolicSuidiceWhenTargetNotKiller": "招募非带刀玩家或非船员时自杀", - "PolicPassConverted": "可以将已转换的附加职业转移给警长" -} \ No newline at end of file + "EavesdropPercentChance": "概率偷听" +} diff --git a/Resources/Lang/zh_TW.json b/Resources/Lang/zh_TW.json index e08e41b33..4a35e53f7 100644 --- a/Resources/Lang/zh_TW.json +++ b/Resources/Lang/zh_TW.json @@ -19,8 +19,6 @@ "SubText.Neutral": "不屬於其他陣營的獨立陣營", "SubText.Apocalypse": "與你的團隊一起變得勢不可擋", "SubText.Madmate": "幫助偽裝者陣營", - "SubText.Lovers": "你墜入了愛河", - "SubText.Egoist": "搶走你的陣營的勝利", "TypeImpostor": "偽裝者", "TypeCrewmate": "船員", "TypeNeutral": "中立", @@ -30,9 +28,6 @@ "TeamNeutral": "中立陣營", "TeamCrewmate": "船員陣營", "TeamMadmate": "叛徒陣營", - "TeamLovers": "戀人陣營", - "TeamEgoist": "利己主義陣營", - "TeamApocalypse": "災厄陣營", "YouAreCrewmate": "你是船員", "YouAreImpostor": "你是偽裝者", "YouAreNeutral": "你是中立", @@ -224,7 +219,6 @@ "TaskManager": "任務管理員", "Witness": "目擊者", "Swapper": "換票師", - "ChiefOfPolice": "警察局長", "NiceMini": "好迷你船員", "Mini": "迷你船員", "Spy": "間諜", @@ -253,7 +247,6 @@ "Stalker": "潛藏者", "Workaholic": "工作狂", "Solsticer": "至聖者", - "Abyssbringer": "深淵使者", "Collector": "集票者", "Provocateur": "挑釁者", "BloodKnight": "嗜血騎士", @@ -360,7 +353,7 @@ "Autopsy": "驗屍", "Loyal": "忠誠", "EvilSpirit": "惡靈", - "Recruit": "被招募", + "Recruit": "狼化", "Admired": "被仰慕", "Glow": "發光", "Radar": "雷達", @@ -392,8 +385,6 @@ "Sloth": "樹懶", "Prohibited": "受限者", "Eavesdropper": "竊聽者", - "Shocker": "電擊者", - "Revenant": "返生者", "BracketAddons": "附加職業使用括弧顯示", "EngineerTOHEInfo": "使用通風管來抓到偽裝者", "ScientistTOHEInfo": "隨時隨地存取心電圖", @@ -512,7 +503,6 @@ "PacifistInfo": "何必打打殺殺呢?", "RebirthInfo": "重獲新生", "MonarchInfo": "給予你的騎士額外的票數!", - "AbyssbringerInfo": "創造黑洞", "SpurtInfo": "像隻兔子般敏捷", "StealthInfo": "在黑暗中殺人", "PenguinInfo": "把他們通通綁起來!", @@ -546,7 +536,6 @@ "WitnessInfo": "我好像目擊了什麼", "GhastlyInfo": "陰魂不散的操控別人!", "SwapperInfo": "交換兩名玩家的票數", - "ChiefOfPoliceInfo": "雇傭警長來為船員服務!", "NiceMiniInfo": "在你長大之前沒有人能傷害你", "ArsonistInfo": "燒吧,燒吧,燃燒吧", "PyromaniacInfo": "澆油並殺光所有人", @@ -707,8 +696,6 @@ "SlothInfo": "跟某家遊戲公司一點關係都沒有", "ProhibitedInfo": "你無法進入某些通風口", "EavesdropperInfo": "隔牆有耳", - "ShockerInfo": "用雷霆為船員降下審判!", - "RevenantInfo": "偷走殺了你的兇手的職業", "EngineerTOHEInfoLong": "(船員陣營):\n工程師可以在通訊未被破壞時使用通風口。", "ScientistTOHEInfoLong": "(船員陣營):\n科學家擁有隨身心電圖,有助於辨識是否為自行舉報,屍體死了多久等等...", "NoisemakerTOHEInfoLong": "(船員陣營):\n警示者死亡時會發出聲音以及提示,這樣船員們就可以當場抓獲擊殺你的人。", @@ -780,11 +767,11 @@ "LurkerInfoLong": "(偽裝者陣營):\n策畫者可以通過跳管道來減少殺人冷卻數秒,當他殺人時,他的冷卻將回復至預設值。", "VisionaryInfoLong": "(偽裝者陣營):\n幻想家可以在會議上看到存活玩家的陣營:\n- 紅色的名字代表偽裝者陣營\n- 藍色的名字代表船員陣營\n- 灰色的名字代表中立陣營", "PlagueDoctorInfoLong": "(中立陣營):\n疫醫的目標是讓所有活著的玩家被感染。\n疫醫可以選擇一名玩家作為感染源,之後任何靠近感染源範圍內一段時間的人也會受到感染並成為感染源。\n感染進度是累積的,不會在遠離後或者會議後重置。", - "RefugeeInfoLong": "(叛徒陣營):\n逃亡者可能為:\n -記起了偽裝者或叛徒的失憶者\n -殺死了懸賞者的懸賞目標的兇手\n -偽裝者伴侶死亡的暗戀者\n -效顰了偽裝者的效顰者\n\n現在你的任務是幫助偽裝者殺死所有船員。", + "RefugeeInfoLong": "(叛徒陣營):\n逃亡者原本可能為失憶者報告了偽裝者的屍體,或是殺死了懸賞者的目標的兇手\n如果你符合以上條件兩者之一,你就會加入偽裝者陣營並跟隨他們獲勝。", "UnderdogInfoLong": "(偽裝者陣營):\n潛伏者只能在場上剩下一定數量的玩家之後才可以開始殺人。", "ConsigliereInfoLong": "(偽裝者陣營):\n軍師可以嘗試對一名玩家使用殺人鍵來揭示他的身分。\n如果揭示技能用完,殺人為正常殺人。\n\n點一下: 揭示身分&點兩下: 殺人", "LudopathInfoLong": "(偽裝者陣營):\n賭博者的殺人冷卻是隨機的,最小為1秒,最大為預設殺人冷卻。", - "GodfatherInfoLong": "(偽裝者陣營):\n懸賞者可以在會議上投給一名玩家作為目標,在下一輪中,如果目標被殺,則兇手變為逃亡者或叛徒。", + "GodfatherInfoLong": "(偽裝者陣營):\n懸賞者可以在會議上投給一名玩家作為目標,在下一輪中,如果目標被殺,則兇手變為逃亡者。", "ChronomancerInfoLong": "(偽裝者陣營):\n天文學家有一個充電進度條,當電量到達100%後,就會在下次擊殺時進入大屠殺模式,此時可以不斷地進行擊殺直到電量耗盡。在其他情況下,你的擊殺冷卻是正常的。", "PitfallInfoLong": "(偽裝者陣營):\n設陷者可以通過變形來將一定區域內設下陷阱,當有玩家進入此區域會在短時間內無法移動,並且視野受到影響。", "EvilMiniInfoLong": "(偽裝者陣營):\n壞迷你船員在成年前免疫所有攻擊,並且殺人冷卻很長,當壞迷你船員成年後,殺人冷卻會變的極低。", @@ -856,7 +843,6 @@ "TaskManagerInfoLong": "(船員陣營):\n任務管理員可以在名字旁看到所有人已完成的任務總數,並且會實時更新。", "WitnessInfoLong": "(船員陣營):\n目擊者可以嘗試對某位玩家使用殺人鍵來知道他們是否在最後數秒內是否殺過人。基於房主設定,這個秒數有可能被更改。", "SwapperInfoLong": "(船員陣營):\n換票師可以在會議期間交換兩名玩家的票數,使用換票指令可以選擇一位玩家,再次使用即可選擇第二位玩家。\n\n換票指令為: /sw [playerID]\n您可以在玩家名字前看到該玩家的ID,或使用/id來查詢所有玩家的編號。\n\n請注意: 根據房主設定你可能可以交換自己的選票", - "ChiefOfPoliceInfoLong": "(船員陣營):\n可以將帶刀船員招募為警長來為船員服務\n請注意: 你只有一次招募機會\n根據設置,你可能可以招募非帶刀玩家或非船員陣營玩家,並且你可能會因為招募錯誤的目標而自殺。", "NiceMiniInfoLong": "(船員陣營):\n好迷你船員在成年前免疫所有攻擊,並且如果好迷你船員在成年前死亡或在會議中被逐出,則好迷你船員獨自獲勝。", "SpyInfoLong": "(船員陣營):\n當間諜被嘗試使用殺人鍵時(即使該動作不是嘗試殺害間諜),間諜會看到他們的名字轉變為橘色數秒。\n\n請注意:\n1. 如果船員嘗試對你使用需要殺人鍵觸發的技能,同樣會看到他變為橘色名字\n2. 如果你已經沒有技能次數了,就不會看到名字變為橘色\n3. 如果殺人按鈕的互動被阻止,帶刀玩家的冷卻時間將被重置為 10 秒。", "RandomizerInfoLong": "(船員陣營):\n隨機者被殺時,兇手會隨機做出下列其中的一個行為:\n 1: 自行報告屍體\n 2: 站在屍體旁邊\n 3: 殺人冷卻被設定為600秒\n 4: 隨機復仇一位玩家。", @@ -871,7 +857,7 @@ "LawyerInfoLong": "(中立陣營):\n遊戲開始時律師會被分配一個目標,並在他的名字旁用「♦」標示,若目標活到最後並獲勝,則律師一同獲勝,如果目標死亡,將依據房主設定變為船員,小丑,投機主義者。\n\n請注意: 律師死亡後仍可獲勝。", "OpportunistInfoLong": "(中立陣營)\n若投機主義者活到遊戲結束時,那麼投機主義者會跟勝利方玩家一同獲勝。", "VectorInfoLong": "(中立陣營):\n當瑪利歐跳管道達到一定次數就會單獨獲勝。", - "JackalInfoLong": "(中立陣營):\n豺狼可以嘗試對一名玩家使用殺人鍵來招募跟班。 如果目標不是你可以招募的目標,要麼你的招募次數已經達到上限,或者房主不允許招募,那麼你將殺害該玩家(所以不要輕易在別人面前招募) 。 如果目標有殺人鍵並且可以招募跟班的選項為啟用,那麼他們將成為跟班。否則,如果提供跟班附加職業的選項處於開啟狀態,他們將獲得跟班附加職業。當豺狼陣營人數大於場上存活陣營的玩家數,則豺狼陣營獲勝。\n根據設定,當豺狼死亡後跟班可能會成為新的豺狼\n如果沒有跟班存活,則可能會讓被招募的玩家成為新豺狼", + "JackalInfoLong": "(中立陣營):\n豺狼可以嘗試對一名玩家使用殺人鍵來招募跟班。 如果目標不是你可以招募的目標,要麼你的招募次數已經達到上限,或者房主不允許招募,那麼你將殺害該玩家(所以不要輕易在別人面前招募) 。 如果目標有殺人鍵並且可以招募跟班的選項為啟用,那麼他們將成為跟班。否則,如果提供跟班附加職業的選項處於開啟狀態,他們將獲得跟班附加職業。當豺狼陣營人數大於場上存活陣營的玩家數,則豺狼陣營獲勝。", "GodInfoLong": "(中立陣營):\n神在開始時已經會知道所有人的職業。如果神在結束時還在場上,神會竊取勝利(其他人都會輸,只有神獲勝)", "InnocentInfoLong": "(中立陣營):\n冤罪師可以對某位玩家使用殺人鍵來栽贓他,被栽贓的目標將會立刻殺死冤罪師,如果目標在會議中被逐出(這個動作可以跨輪執行),則冤罪師獲勝。\n請注意: 小丑、暴民、冤罪師可以一同獲勝", "PelicanInfoLong": "(中立陣營):\n鵜鶘可以對某一位玩家使用殺人鍵來活吞該玩家,被活吞的玩家將會被傳送到地圖外並且無法與遊戲互動,活吞成功後鵜鶘將會看到自己身上出現盾牌破碎的效果作為提示。進入會議時將導致所有被鵜鶘吞下的玩家立刻死亡,若鵜鶘死亡或斷線,則被鵜鶘吞下的玩家將會立刻傳送到鵜鶘死亡的位置並可以再次與遊戲互動。當只剩下鵜鶘與船員陣營且鵜鶘陣營人數大於船員陣營人數,則鵜鶘獲得勝利。\n請注意: 鵜鶘活吞玩家不是正常的殺人方式,因此老兵、保鑣等技能不會生效。", @@ -883,7 +869,7 @@ "SolsticerInfoLong": "(中立陣營):\n至聖者為無敵狀態,並且需要在一輪遊戲中完成所有的任務以獲勝,否則當會議結束時,至聖者的任務將被重置。\n\n請注意:\n1. 嘗試投給至聖者的票數會被強制取消\n2. 玩家嘗試殺害至聖者時,兇手的冷卻會重置為 10 秒至,且至聖者會被傳送至地圖外直到進入會議。\n3. 依據房主設定,至聖者可能可以知道兇手的職業\n4. 至聖者在計算人數時會被算作死亡", "CollectorInfoLong": "(中立陣營):\n當集票者在會議上投票給一名玩家時,將會收集到本次會議上該玩家被投的所有票數。當集票者收集到指定票數之後,集票者將獨立獲勝\n請注意: 集票者的勝利優先於被逐出玩家的勝利(例如小丑、暴民、冤罪師等)。", "GlitchInfoLong": "(中立陣營):\n故障者可以駭入玩家,玩家在被駭入期間無法殺人,使用通風口,和舉報屍體。\n\n單點殺人鍵駭入&雙點殺人鍵殺人。\n此外,故障者可以使用破壞(除了門之外的所有破壞,例如關燈) 來在一定時間內變形成一個隨機的玩家(破壞並不會真正發生,並且由於技術限制,你無法在破壞時或破壞後變形)。\n\n殺光所有人來獲勝。", - "SidekickInfoLong": "(中立陣營):\n跟班需要幫助豺狼殺死所有人\n你會跟著豺狼一起獲勝\n根據設定,你可能會在豺狼死後成為新的豺狼\n並且你可能無法在老豺狼死亡前殺人", + "SidekickInfoLong": "(中立陣營):\n跟班的目標是幫忙豺狼殺光所有人,你與豺狼共享勝利。", "ProvocateurInfoLong": "(中立陣營):\n挑釁者可以使用殺人鍵與任何玩家同歸於盡。若遊戲結束時目標輸了,則挑釁者與獲勝方一同獲勝。", "BloodKnightInfoLong": "(中立陣營):\n嗜血騎士每次殺人後都可以獲得一定時間的護盾,護盾可以抵擋掉所有正常殺人的舉動,直到護盾時間結束並失效。當只剩下嗜血騎士陣營與船員陣營且嗜血騎士陣營人數大於船員陣營,則嗜血騎士方獲勝", "PlagueBearerInfoLong": "(災厄陣營):\n瘟疫之源可以嘗試對玩家使用殺人鍵將其感染,當所有人都被感染時,瘟疫之源將轉化為萬疫之神,萬疫之神免疫所有攻擊並且可以殺人,如果有人嘗試殺死萬疫之神,則萬疫之神將反殺兇手。\n\n此外,當受感染的玩家與未感染的玩家進行互動後,未受感染的玩家也會受到感染", @@ -910,12 +896,11 @@ "TraitorInfoLong": "(中立陣營):\n背叛者知道偽裝者,但偽裝者不知道背叛者,偽裝者可以殺死背叛者,但背叛者無法直接殺了偽裝者,通過其他方式消滅偽裝者,然後殺死其他人獲勝!", "TrollerInfoLong": "(中立陣營):\n搗亂者可以透過做任務來觸發一些隨機事件。\n例如改變所有玩家速度、傳送、影響破壞等事件。\n搗亂者只要存活到最後就能獲勝。", "VultureInfoLong": "(中立陣營):\n禿鷲報告屍體時,如果他的進食冷卻結束,則禿鷲即可吃下該具屍體(將其變為無法報告),如果冷卻未結束,禿鷲將正常報告此屍體,如果禿鷲達到每回合最大進食限制,則禿鷲也正常報告此屍體。依據房主設定,每回合最大進食限制的數值可以被調整。", - "AbyssbringerInfoLong": "(偽裝者陣營):\n深淵使者可以使用變形來放置黑洞,黑洞將在玩家靠近時將其吸入並殺死他們。", "TaskinatorInfoLong": "(中立陣營):\n作為搗蛋鬼,每當你完成一個任務,該任務就會被裝上炸彈。當其他玩家完成有炸彈的任務時,炸彈就會爆炸,玩家就會死亡。\n\n當搗蛋鬼活到最後,並且船員陣營失敗,則搗蛋鬼跟隨獲勝陣營獲勝。\n\n 請注意: 搗蛋鬼的炸彈無視所有保護(例如軍醫護盾)", "BenefactorInfoLong": "(船員陣營):\n當慈善家做完一項任務時,該任務會被標記。而當其他玩家完成了被標記的任務時,將會獲得護盾。\n\n請注意:護盾僅能防禦直接性擊殺", "MedusaInfoLong": "(中立陣營):\n美杜莎可以石化屍體,被石化的屍體將無法被報告,殺光所有人獲勝!", "SpiritcallerInfoLong": "(中立陣營):\n靈魂召喚者可以把玩家被殺害後變成惡靈,惡靈透過作祟按鈕暫時凍結其他玩家,或暫時阻擋他們的視野,在或者,惡靈可以給予靈魂召喚者一個護盾,短暫的保護靈魂召喚者不受殺害。", - "AmnesiacInfoLong": "(中立陣營):\n失憶者可以使用報告按鈕來回憶並獲取屍體的職業\n為了平衡遊戲,如果失憶者的設定為無法使用通風口,則你回憶職業後也不能夠使用通風口。", + "AmnesiacInfoLong": "(中立陣營):\n失憶者可以通過報告屍體來回想起一個職業\n\n如果屍體是偽裝者的,則失憶者將變為逃亡者。\n如果屍體是船員的,且符合條件,則失憶者將變為他的職業(否則你將會變成工程師)。\n如果屍體是不帶刀中立或是未指定的帶刀中立的,你將變為特定的中立職業(具體依據房主設定)。\n如果屍體是少數的帶刀中立的,則你將會變為他們的職業。", "ImitatorInfoLong": "(中立陣營):\n效顰者可以嘗試對一名玩家使用殺人鍵來效仿該玩家的職業。\n如果你效仿了船員,你會變成警長。\n如果你效仿了偽裝者,你會變成逃亡者。\n如果你效仿了中立玩家,你會變成某些中立職業。", "BanditInfoLong": "(中立陣營):\n強盜可以嘗試對一名玩家使用殺人鍵來偷走該名玩家的附加職業,雙擊來正常殺人。如果該名玩家沒有可偷取的附加職業,則正常殺死該玩家,基於房主設定,強盜可能可以立刻偷走附加職業,或在進入會議時偷走附加職業,當達到最大偷取次數時,你將可以正常殺人,殺光所有人來獲勝。\n\n請注意:\n1. 乾淨,絕境者,戀人無法被偷取。\n2. 如果強盜可以使用通風口,則敏捷無法被偷取。", "DoppelgangerInfoLong": "(中立陣營):\n分身者在殺死玩家時將會偷走他們的名字與外觀,殺光所有人來獲勝。\n\n請注意: 你無法在隱蔽效果期間偷取目標的特徵。", @@ -936,7 +921,6 @@ "JinxInfoLong": "(中立陣營):\n每當掃把星受到攻擊時,掃把星都會詛咒他們,導致他們死於厄運。該技能有使用次數限制。", "PotionMasterInfoLong": "(中立陣營):\n魔藥師擁有三瓶藥水,分別有不同的作用\n\n對玩家按一下殺人鍵: 揭示身分\n按兩下殺人鍵: 殺人\n地圖: 破壞\n\n請注意: 揭示的藥水具有上限,當用完時,就會轉變為正常的殺人鍵。", "NecromancerInfoLong": "(中立陣營):\n當有人嘗試殺死死靈法師時,殺人行動會被阻擋並且死靈法師會傳送到隨機的通風口中,並且必須在倒數計時時間內殺死兇手,如果成功殺死,則存活,反之,如果倒數計時結束時你沒有殺死兇手,或是殺錯人,你會永久死亡。遊戲結束時,如果死靈法師活到最後,則死靈法師獨自獲勝。", - "ShockerInfoLong": "(中立陣營):\n電擊者可以透過在房間中執行任務來標記此房間,在一段時間(根據房主設定) 內跳進管道,你將電擊該房間內的所有人。當你完成所有任務後,你會得到新的任務。請注意: 在未電擊期間內完成任務將為下一次能力使用標記它們。", "LastImpostorInfoLong": "(附加職業):\n這個效果只在偽裝者陣營只剩下一人時賦予該玩家,被賦予效果的玩家殺人冷卻將會縮短。", "OverclockedInfoLong": "(附加職業):\n超頻的冷卻時間會被減少至設定的百分比(%) 數(依據房主設定),該附加職業只會給予帶刀玩家。", "LoversInfoLong": "(附加職業):\n戀人為兩名玩家的組合。戀人可以看到對方名字旁有「♥」圖標作為提示,當戀人其中一人死亡時則另一人殉情(根據房主設定可能不會殉情)。戀人其中一人在會議中被逐出時,另一人也將死亡並變成不可報告的屍體。當場上只剩下戀人時戀人將獨自獲勝,戀人其中一人獲勝時另一人也一起獲勝。", @@ -980,7 +964,7 @@ "RebirthInfoLong": "(附加職業):\n重生者在即將被逐出時會隨機跟一名投給自己的玩家交換裝扮與名字,並且他將代替重生者被逐出。\n請注意: 房主的投票不會被計入\n如果重生者用盡了所有重生次數,則不會觸發效果", "LoyalInfoLong": "(附加職業):\n持有忠誠附加職業的玩家無法被招募,該職業無法分配給中立陣營。", "EvilSpiritInfoLong": "(附加職業):\n惡靈的任務為幫助靈魂召喚者獲勝,你可以使用你的作祟按鈕來讓某名玩家無法移動並且視野被縮小,如果你在靈魂召喚者上使用作祟按鈕,則你會給予靈魂召喚者短暫的護盾。", - "RecruitInfoLong": "(背叛的附加職業):\n當你獲得了被招募的附加職業,代表你已被豺狼招募並加入了豺狼陣營,需要幫助豺狼及跟班獲勝。\n你不能和原來的陣營一起獲勝。\n根據設置,如果老豺狼被殺死並且沒有跟班活著,你可能會變成豺狼。", + "RecruitInfoLong": "(背叛的附加職業):\n被授予狼化附加職業代表你被豺狼招募,當你持有此附加職業時,你將會加入豺狼陣營並無法與原先的陣營獲勝。", "AdmiredInfoLong": "(背叛的附加職業):\n被授予被仰慕附加職業代表你被仰慕者仰慕,當你持有此附加職業時,你將會與船員獲勝,你可以看見仰慕者。", "GlowInfoLong": "(附加職業):\n關燈期間,發光和發光周圍的玩家都會獲得視野提升", "RadarInfoLong": "(附加職業):\n擁有雷達的玩家將有一個指向最近玩家的箭頭", @@ -1024,7 +1008,6 @@ "ProhibitedInfoLong": "(附加職業):\n受限者無法使用某些特定的通風口。\n不能使用的管道數根據房主設定而不同。", "EavesdropperInfoLong": "(附加職業):\n竊聽者有一定機率能夠在會議上看到其他人的職業/附加職業的信息,比如殯葬師或偵探。", "ApocalypseInfoLong": "(災厄陣營):\n災厄陣營是一個獨立的陣營,災厄成員會共同獲勝,且可以看到彼此的職業。\n根據房主設置,災厄陣營的玩家可以賭人或是被賭", - "RevenantInfoLong": "(中立陣營):\n返生者的目標就是被殺死,如果你被殺死,你會奪走兇手的職業並將其擊殺。你在被殺之前沒有任何方法獲勝。\n請注意: 返生者的技能只有被直接性擊殺時會生效", "ShowTextOverlay": "文字覆蓋(小字顯示)", "Overlay.GuesserMode": "賭怪模式", "Overlay.NoGameEnd": "測試模式(遊戲不結束)", @@ -1038,8 +1021,6 @@ "AbilityUseLimit": "初始技能數量", "AbilityInUse": "技能生效中", "AbilityExpired": "技能已失效,剩餘{0} 次使用次數", - "RevenantTargeted": "你的職業變成了{0}", - "RevenantCanCopyAddons": "可以奪走附加職業", "ShowArrows": "指向屍體的箭頭", "ArrowDelayMin": "箭頭最短延遲時間", "ArrowDelayMax": "箭頭最長延遲時間", @@ -1056,7 +1037,7 @@ "NoGameEnd": "測試模式(遊戲不結束)", "AllowConsole": "開啟控制台(可能會被用於作弊)", "DebugMode": "偵錯模式", - "SyncButtonMode": "限制會議次數", + "SyncButtonMode": "限制會議時間", "RandomMapsMode": "隨機地圖模式", "SyncedButtonCount": "可用緊急會議次數", "HHSuccessKCDDecrease": "殺死目標減少的冷卻時間", @@ -1350,7 +1331,7 @@ "TempBan": "暫時封禁", "OnlyCancel": "只取消作弊行為", "CheatResponses": "檢測到外掛時", - "NeutralRoleWinTogether": "中立陣營玩家共同獲勝", + "NeutralRoleWinTogether": "同種職業的中立玩家共同獲勝", "NeutralWinTogether": "全體中立陣營玩家共同獲勝", "MenuTitle.Disable": "★ 禁用相關設定", "MenuTitle.MapsSettings": "★ 地圖 ★", @@ -1368,8 +1349,6 @@ "ShieldedCanUseKillButton": "受保護玩家可以使用能力/擊殺按鈕", "PlayerIsShieldedByGame": "該玩家受到了遊戲的保護!", "LegacyNemesis": "使用舊版本", - "LegacyParasite": "使用舊版本", - "LegacyTraitor": "使用舊版本", "ArsonistKeepsGameGoing": "當縱火犯在場時遊戲不會結束", "ArsonistCanIgniteAnytime": "可以在任何時候點燃", "ArsonistMinPlayersToIgnite": "點燃所需的最小澆油數", @@ -1512,18 +1491,6 @@ "SheriffCanKillSeparately": "單獨設定", "In%team%": "(%team%陣營)", "SheriffMisfireKillsTarget": "當誤殺好人時同時殺死目標", - "BlackHolePlaceCooldown": "放置黑洞冷卻時間", - "BlackHoleDespawnMode": "黑洞消失模式", - "BlackHoleDespawnTime": "黑洞消失後的時間", - "Abyssbringer.Suffix": "<#00ffa5>被吞噬的玩家數量 {0} <#00ffa5>活躍的黑洞:\\n{1}", - "Abyssbringer.Suffix.BlackHole": "<#00ffa5>{0}: {1}", - "BlackHoleMovesTowardsNearestPlayer": "黑洞向最近的玩家移動", - "BlackHoleMoveSpeed": "黑洞移動速度", - "BlackHoleRadius": "黑洞吞噬範圍半徑", - "AfterTime": "一段時間後", - "After1PlayerEaten": "1名玩家被吞噬後", - "AfterMeeting": "會議後", - "None": "無", "SheriffShotLimit": "執法次數上限", "SheriffCanKillAllAlive": "全員存活時可以執法", "SheriffCanKillCharmed": "可以執法被魅惑的玩家", @@ -1540,15 +1507,12 @@ "RebirthUses": "重生次數上限", "RebirthCountVotes": "重生目標僅從投給自己的玩家中選擇", "RebirthFailed": "沒有找到能與你交換身體的靈魂。", - "FireworkerCooldown": "放置黑洞冷卻時間", "ReverieIncreaseKillCooldown": "增加殺人冷卻時間", "ReverieMaxKillCooldown": "最大殺人冷卻", "ReverieMisfireSuicide": "到達最大殺人冷卻時可能會誤殺", "ReverieResetCooldownMeeting": "會議後重設殺人冷卻時間", "ConvertedReverieKillAll": "非船員陣營的遐想者可以殺死任何人並且不受冷卻增加影響", "VigilanteNotify": "你變成了你發誓要摧毀的東西", - "DictatorChangeCommandToExpel": "獨裁主義者使用指令逐出玩家而不是透過投票", - "DictatorExpelSelf": "等等等等等等什麼鬼? Bro真的只是想驅逐自己", "DoctorTaskCompletedBatteryCharge": "完成任務增加的心電圖電量", "SnitchEnableTargetArrow": "完成任務後箭頭指向所有目標", "SnitchCanGetArrowColor": "對不同陣營的目標顯示不同顏色的箭頭", @@ -1629,7 +1593,6 @@ "EvilTrackerTargetMode.OnceInGame": "僅限一次", "EvilTrackerTargetMode.EveryMeeting": "每次會議", "EvilTrackerTargetMode.Always": "隨時隨地", - "ScavengerHasCustomDeathReason": "啟用自訂死亡原因", "EvilHackerCanSeeDeadMark": "可以看到屍體的位置", "EvilHackerCanSeeImpostorMark": "可以看到其他偽裝者的位置", "EvilHackerCanSeeKillFlash": "可以看到殺人閃光", @@ -1781,12 +1744,12 @@ "NinjaMarkCooldown": "標記冷卻時間", "NinjaAssassinateCooldown": "刺殺冷卻時間", "NinjaModeDouble": "按一下標記&按兩下殺人", - "JudgeCanTrialnCrewKilling": "可以審判帶刀 船員", - "JudgeCanTrialNeutralB": "可以審判友善 中立", - "JudgeCanTrialNeutralK": "可以審判帶刀 中立", - "JudgeCanTrialNeutralE": "可以審判邪惡 中立", - "JudgeCanTrialNeutralC": "可以審判混亂 中立", - "JudgeCanTrialNeutralA": "可以審判災厄 中立", + "JudgeCanTrialnCrewKilling": "可以審判帶刀船員", + "JudgeCanTrialNeutralB": "可以審判無刀中立", + "JudgeCanTrialNeutralK": "可以審判帶刀中立", + "JudgeCanTrialNeutralE": "可以審判邪惡中立", + "JudgeCanTrialNeutralC": "可以審判混亂中立", + "JudgeCanTrialNeutralA": "可以審判災厄中立", "JudgeCanTrialSidekick": "可以審判跟班", "JudgeCanTrialInfected": "可以審判被感染的玩家", "JudgeCanTrialContagious": "可以審判被傳染的玩家", @@ -1862,21 +1825,13 @@ "Jackal_SidekickCountMode_Jackal": "豺狼", "Jackal_SidekickCountMode_Original": "原陣營", "Jackal_SidekickAssignMode": "跟班生成模式", - "Jackal_SidekickAssignMode_SidekickAndRecruit": "當選擇跟班失敗時選擇被招募的", - "Jackal_SidekickAssignMode_Sidekick": "只選擇 跟班", - "Jackal_SidekickAssignMode_Recruit": "只選擇 被招募的", + "Jackal_SidekickAssignMode_SidekickAndRecruit": "跟班+狼化", + "Jackal_SidekickAssignMode_Sidekick": "僅限跟班", + "Jackal_SidekickAssignMode_Recruit": "僅限狼化", + "JackalWinWithSidekick": "豺狼可以與跟班所在的陣營獲勝", "Jackal_SidekickCanKillSidekick": "跟班可以互相殺害", "Jackal_SidekickCanKillJackal": "跟班可以擊殺豺狼", - "Jackal_RecruitFailed": "你無法招募該玩家!", "JackalCanKillSidekick": "豺狼可以殺死跟班", - "Jackal_SidekickCanKillWhenJackalAlive": "跟班可以在豺狼存活時擊殺", - "Jackal_SidekickTurnIntoJackal": "跟班會在豺狼死後變成新的豺狼", - "Jackal_RestoreLimitOnNewJackal": "當跟班變成新豺狼後可以再次招募跟班", - "Jackal_OnBecomeNewJackalMeeting": "舊的 豺狼 {0} 已經死了。\n你被選為了新的 豺狼\n齊心協力,贏得遊戲!", - "Jackal_OnNewJackalSelectedMeeting": "舊的 豺狼 {0} 已經死了。\n{1} 已被選為新的 豺狼!\n齊心協力,贏得遊戲!", - "Jackal_BecomeNewJackal": "舊的豺狼死了,你成為了新的豺狼!", - "Jackal_OnNewJackalSelected": "舊的豺狼死了,現在請幫助新的豺狼 {0}!", - "Jackal_BossIsDead": "哎呀,豺狼老大死了!", "CoronerArrowsPointingToDeadBody": "有指向屍體的箭頭", "CoronerLeaveDeadBodyUnreportable": "驗屍官報告過的屍體無法再次被報告", "CoronerInformKillerBeingTracked": "告知兇手已被追蹤", @@ -1914,9 +1869,6 @@ "VipTag": "VIP★", "ApplyVipList": "套用VIP列表", "AllowSayCommand": "允許管理員使用/say指令", - "AllowStartCommand": "允許管理員使用/start指令", - "StartCommandMinCountdown": "/start 指令的最小倒數計時", - "StartCommandMaxCountdown": "/start 指令的最大倒數計時", "KickCommandDisabled": "踢出指令目前已被禁用", "KickCommandNoAccess": "你沒有權限使用踢出指令", "KickCommandInvalidID": "無效的玩家ID\n請使用 /kick [玩家ID] [原因] 來踢出玩家\n範例: /kick 5 不遵守規則", @@ -1949,11 +1901,6 @@ "WarnCommandNoAccess": "你沒有權限使用警告指令", "WarnCommandInvalidID": "無效的玩家ID\n請使用 /warn [玩家ID] [原因] 來封禁玩家\n範例: /warn 5 在逐出畫面時討論", "WarnCommandWarnHost": "你無法警告房主", - "StartCommandNoAccess": "你沒有權限使用開始指令", - "StartCommandDisabled": "開始指令目前已被禁用", - "StartCommandCountdown": "錯誤\n\n遊戲已經開始了!", - "StartCommandStarted": "遊戲將於 {0} 開始!", - "StartCommandInvalidCountdown": "錯誤\n\n開始倒數應在 {0} 和 {1} 中間!", "WarnCommandWarnMod": "你不能警告其他管理員", "WarnCommandWarned": "已被警告,我們將不會再繼續發出警告,繼續犯規將會被懲罰。 \n ", "WarnExample": "使用 /warn [玩家ID] [原因] 來警告玩家。\n範例:\n /warn 5 在逐出畫面時討論", @@ -1981,7 +1928,6 @@ "DeathReason.Quantization": "量子化", "DeathReason.Overtired": "猝死", "DeathReason.Ashamed": "卷死", - "DeathReason.Consumed": "吞噬", "DeathReason.PissedOff": "氣死", "DeathReason.Dismembered": "肢解", "DeathReason.LossOfHead": "絞殺", @@ -2005,8 +1951,6 @@ "DeathReason.Starved": "餓死", "DeathReason.Equilibrium": "平衡", "DeathReason.Sacrificed": "獻身", - "DeathReason.Electrocuted": "電擊", - "DeathReason.Scavenged": "清理", "OnlyEnabledDeathReasons": "只顯示已開啟的死亡原因", "Alive": "存活", "Disconnected": "斷線", @@ -2072,7 +2016,6 @@ "Command.dump": "→ 將遊戲運行紀錄輸出到桌面", "Command.death": "→ 顯示你的死因", "Command.icons": "
╳ - 該玩家被勒索者勒索,並且無法在會議上發言。
☆ - 船長的特殊標記,只有船員能看見船長名字後的星星
乂 - 該玩家被妖術師施展妖術了,若代碼工程師沒有在會議結束時死亡或被放逐,該玩家將死亡
♦ - 該玩家是律師、暴民或追隨者的目標
♥ - 用來標記戀人或暗戀者
✚ - 用來標記軍醫的目標
⦿ - 該玩家是挑戰者挑戰目標
!? - 該玩家是測驗者的目標,需要回答問題才能存活
☜ - 用來為薛丁格的貓標記他們的隊友
◈ - 該玩家被裹屍布蓋住了,若裹屍布沒有在會議結束時死亡或被放逐,該玩家將死亡
⚠ - 該玩家是即將完成任務的告密者或至聖者
★ - 該玩家是大明星或名人或展現者
† - 該玩家被女巫詛咒了,若女巫沒有在會議結束時死亡或被放逐,該玩家將死亡
∇ - 用來為神風特攻隊標記目標
■ - 該玩家被球狀閃電汽化為量子幽靈
⊠ - 用來為監禁者標記他們的目標
● - 用來為麵包師標記已獲得麵包的玩家
♠ - 用來標記靈魂收割者的目標
⦿ - 用來為瘟疫之源顯示已感染的玩家", - "Command.start": "[Seconds] → 遊戲開始前的倒數計時", "Command.iconinfo": "→ 顯示會議圖標代表的意思", "Command.iconhelp": "→ 給所有人顯示會議圖標代表的意思", "Command.Poll": "→ 發起投票,最多可以有5個選項", @@ -2085,7 +2028,6 @@ "ShowMadmatesInLeftCommand": "顯示叛徒 (包括附加職業)", "ShowApocalypseInLeftCommand": "顯示災厄中立", "SeeEjectedRolesInMeeting": "會議中看見被逐出的玩家的職業", - "ThankYouForUsingTOHE": "感謝你使用 TOHE!", "SkillUsedLeft": "您發動了技能召開了會議。\n您的技能剩餘使用次數:", "NemesisDeadMsg": "黑手黨的死亡,意味著復仇的開始\n請使用/rv + [玩家ID] 以殺死指定玩家\n您可以在玩家名字前看到該玩家的ID\n或輸入/rv獲得玩家ID列表", "NemesisAliveKill": "黑手黨的復仇技能只能在死亡後發動", @@ -2105,7 +2047,6 @@ "GuessNotifiedBait": "因為誘餌已經被公告出來了,所以無法被猜測,你覺得這會很簡單,對吧?", "GuessGM": "你會什麼會想要讓一個剛開局就死的人在死一次", "GuessGuardianTask": "很抱歉,你無法猜測已完成任務的守護者", - "GuardianCantKilled": "你不能擊殺已經完成任務的守護者", "GuessMarshallTask": "很抱歉,你無法猜測已經完成任務的展現者", "GuessObviousAddon": "很抱歉,你無法猜測過於明顯的附加職業", "GuessAdtRole": "很抱歉,根據該房設定不允許猜測附加職業", @@ -2161,7 +2102,6 @@ "BecomeMadmateCuzMadmateMode": "您因死亡而成為叛徒", "CleanerCleanBody": "目標的屍體已被清理", "QuickShooterStoraging": "子彈儲存成功", - "QuickShooterFailed": "你處於冷卻時間。", "PoisonerTargetDead": "您的目標已死亡", "HexesLookLikeSpells": "妖術 看起來像詛咒", "HexButtonText": "妖術", @@ -2220,7 +2160,7 @@ "PacifistOnGuard": "和平技能已生效,剩餘{0} 次", "PacifistSkillNotify": "和平之鴿重置了您的殺人/技能冷卻", "BeRecruitedByJackal": "你被豺狼招募成跟班了!", - "YinYangerAlreadyMarked": "{0} 已處於平靜狀態,並得到一位陰陽師的幫助", + "YinYangerAlreadyMarked": "{0} is already in a state of calm, endowed by a fellow YinYanger", "CoronerTrackRecorded": "追蹤已被錄製", "CoronerNoTrack": "沒有追蹤紀錄", "CoronerIsTrackingYou": "驗屍官正在追蹤你!", @@ -2320,7 +2260,6 @@ "Message.YTPlanNotice": "提醒: 該房間已啟用【創作者素材保護計畫】,房主可以指定自己的職業。\n該功能只允許創作者錄製影片素材,如有濫用情況,請退出遊戲或舉報。\n目前創作者認證:", "Message.OnlyCanBeUsedByHost": "錯誤\n該指令只能由房主使用", "Message.MaxPlayers": "最大玩家數量已設定為 ", - "Message.MaxPlayersFailByRegion": "無法設定最大玩家人數: 原版伺服器最多支援 15 名玩家。", "Message.GhostRoleInfo": "關於幽靈職業\n你好!這裡是有關於幽靈職業的一些介紹\n\n請注意: 幽靈職業會對遊戲產生極大的影響,因此如果您不熟悉幽靈職業,不建議在小型房間中使用。\n如果沒有明確的說明,幽靈職業的技能按鈕就是守護按鍵。\n\n幽靈職業的生成:\n幽靈職業只有在死亡後才會出現,一個陣營中最先死亡的玩家將會獲得幽靈職業。\n\n注意:如果您以前的職業沒有任務(例如: 警長),則您作為幽靈職業的任務不需要用於任務勝利
", "ApocalypseInfoTitle": "中立災厄陣營簡介:", "Message.ApocalypseInfo": "災厄陣營的每個職業都有自己的目標轉變職業。\n轉變的 災厄成員將在遊戲中發生巨大的變化並且處於無敵狀態(除了投票之外),但每個人都會被通知他們已經轉變。\n\n職業:瘟疫之源、靈魂收割者、麵包師、狂戰士\n轉變目標職業:萬疫之神、死亡使者、飢餓之神、戰神\n\n災厄成員可以看到彼此的職業和能力圖示。\n與帶刀中立一樣,災厄成員也讓遊戲繼續進行,玩得開心!", @@ -2391,7 +2330,7 @@ "FortuneTellerCheckMsgTitle": "【 ★ 水晶球 ★ 】", "MimicMsgTitle": "【 ★ 保險箱 ★ 】", "MorticianCheckTitle": "【 ★ 屍體檢查 ★ 】", - "NemesisRevengeTitle": "【 ★ 特供情報 ★ 】", + "NemesisRevengeTitle": "【 ★ 特供情报 ★ 】", "RetributionistRevengeTitle": "【 ★ 報應者 ★ 】", "TabVanilla.GameSettings": "遊戲設定", "TabGroup.SystemSettings": "系統設定", @@ -2648,7 +2587,7 @@ "FortuneTellerCheck.Result": "【{0}】可以是以下職業:\n{1}", "SunnyboyChance": "成為陽光開朗大男孩的機率", "BardChance": "成為吟遊詩人的機率", - "SkeldChance": "地圖為The Skeld的機率", + "SkeldChance": "地圖是 The Skeld的機率", "MiraChance": "地圖為MIRA HQ的機率", "PolusChance": "地圖為Polus的機率", "DleksChance": "地圖是dlekS ehT的機率", @@ -2725,9 +2664,8 @@ "DeathMeetingTimeIncrease": "當死亡使者存在時,會議時間延長", "SoulCollectorMeetingDeath": "你的目標在會議中死亡,你收割了他的靈魂。", "SoulCollectorKillButtonText": "預測", - "SoulCollectorHasImpostorVision": "靈魂收割者 擁有偽裝者視野", "ApocalypseIsNigh": "【末日即將來臨 !】", - "ApocalypseImmune": "該職業免疫!", + "ApocalypseImmune": "該玩家免疫了你的攻擊,因為他處於無敵狀態!", "BakerToFamine": "你變成了飢餓之神!!!", "BakerTransform": "麵包師已經變成了飢餓之神! 飢荒就要到來了!", "BakerAlreadyBreaded": "該玩家已經擁有麵包", @@ -2736,15 +2674,13 @@ "BakerBreadNeededToTransform": "成為飢餓之神需要發放的麵包數量", "BakerCantBreadApoc": "你不能給其他災厄成員發放麵包", "BakerKillButtonText": "發放麵包", - "BakerUnshiftButtonText": "切換", "BakerRevealBread": "揭示", "BakerRoleblockBread": "職業封鎖", "BakerBarrierBread": "屏障", "BakerCurrentBread": "當前麵包種類: ", "BakerSwitchBread": "麵包種類切換至: ", - "BakerCanVent": "麵包師可以使用通風口", + "BakerCanVent": "麵包師可以使用通風口", "BakerBreadGivesEffects": "麵包具有額外效果", - "BakerTransformNoMoreBread": "麵包師在沒有足夠的麵包時轉變", "FamineKillButtonText": "飢餓", "FamineStarveCooldown": "飢餓之神的飢荒冷卻時間", "FamineCantStarveApoc": "你不能餓死其他災厄成員", @@ -2791,7 +2727,6 @@ "GodfatherTargetCountMode": "兇手職業將轉變成", "GodfatherCount_Refugee": "逃亡者", "GodfatherCount_Madmate": "叛徒", - "GodfatherRefugeeMsg": "你已被懸賞者招募!", "MissChance": "失誤的機率", "IncreaseByOneIfConvert": "如果船員的陣營被轉換則最大擊殺數+1", "HawkMissed": "失誤了!", @@ -2824,7 +2759,6 @@ "BerserkerToWar": "你變成了戰神!!!", "BerserkerTransform": "狂戰士已經變成了戰神! 這將是一場浩劫", "WarKillCooldown": "戰神的殺人冷卻", - "BerserkerCanKillTeamate": "可以殺死其他災厄陣營的成員", "BlackmailerSkillCooldown": "勒索冷卻時間", "BlackmailerMax": "目標最大說話次數", "BlackmailerDead": "警告!玩家 {0} 被勒索者勒索了!", @@ -2914,8 +2848,6 @@ "RememberedPursuer": "你回想起了你是一個起訴人!", "RememberedFollower": "你回想起了你是一個追隨者", "RememberedAmnesiac": "你沒有成功地記住自己的職業", - "AmnesiacRemembered": "你回想起了你是一個{0}!", - "ReportWhenFailedRemember": "回憶失敗時報告屍體", "RememberedImitator": "你回想起了你是一個效顰者", "RememberedImpostor": "你回想起了你是一個偽裝者!", "RememberedCrewmate": "你回想起了你是一個船員!", @@ -3329,12 +3261,9 @@ "PixieTargetAlreadySelected": "目標已選定", "PixieButtonText": "標記", "PlagueBearerCooldown": "瘟疫之源冷卻時間", - "PlagueBearerCanVent": "可以使用通風管", - "PlagueBearerHasImpostorVision": "擁有偽裝者視野", "PestilenceCooldown": "萬疫之神殺人冷卻", "PestilenceCanVent": "萬疫之神可以使用通風口", "PestilenceHasImpostorVision": "萬疫之神有偽裝者視野", - "PestilenceKillGuessers": "殺死試圖猜測萬疫之神的玩家", "PlagueBearerAlreadyPlagued": "玩家已被感染", "PlagueBearerToPestilence": "你成為了萬疫之神!!", "GuessPestilence": "你試圖猜測萬疫之神!\n\n但抱歉,萬疫之神殺死了你。", @@ -3372,13 +3301,12 @@ "DoomsayerCantGuess": "抱歉,你只能在下次會議進行猜測", "DoomsayerCorrectlyGuessRole": "你猜對了職業!\n但很抱歉,該玩家並沒有死亡,因為房主設定不允許玩家死亡", "DoomsayerNotCorrectlyGuessRole": "你沒有猜對該玩家的職業!\n但你沒有死亡,因為房主設定不允許你死亡", - "DoomsayerGuessCountMsg": "你已猜對了{0}個職業", + "DoomsayerGuessCountMsg": "你已猜對了{0}個身份", "DoomsayerGuessCountTitle": "【 ★ 賭神 ★ 】", "DoomsayerGuessSameRoleAgainMsg": "你試著猜測與之前一樣的職業/附加職業", "EveryoneCanKnowMini": "所有人都能知道迷你船員是誰", "CanBeEvil": "迷你船員可以是偽裝者", "EvilMiniSpawnChances": "迷你船員成為偽裝者的機率", - "EvilMiniCanBeGuessed": "壞迷你船員可以在18歲前被賭", "GuessMini": "很抱歉,你無法傷害迷你船員", "GrowUpDuration": "長大所需要的時間(秒)", "MajorCooldown": "成年後的殺人冷卻時間", @@ -3409,9 +3337,9 @@ "Booster": "Discord伺服器加成", "Translator": "翻譯支援", "NoAccess": "未經授權的存取!\n你是否使用了被洩漏的版本或是自行構建dll?\n請於Discord群組開啟一張支援票以了解更多資訊(discord.gg/tohe)", - "DCNotify.Hacking": "你因為使用外掛而被封禁\n\n請停止", - "DCNotify.Banned": "您被該房間封禁\n\n若這是一個錯誤請告知房主", - "DCNotify.Kicked": "您被該房間踢出\n\n你可以嘗試重新加入", + "DCNotify.Hacking": "您被Innersloth的反作弊系統踢出了\r\n(Innersloth還在持續發瘋)", + "DCNotify.Banned": "您被該房間封禁", + "DCNotify.Kicked": "您被該房間踢出", "DCNotify.DCFromServer": "您與伺服器的連接已中斷\r\n這可能是因為您的網路不穩定\r\n也可能是因為伺服器不穩定或拒絕了您的存取", "DCNotify.GameNotFound": "未找到指定房間,可能是房間已經解散\r\n或檢查您是否選擇了與該房間不同的伺服器", "DCNotify.GameStarted": "該房間正在遊戲中,請等待遊戲結束後加入", @@ -3520,7 +3448,6 @@ "WinnerRoleText.Doppelganger": "分身者獲勝!", "WinnerRoleText.Quizmaster": "測驗者獲勝!", "WinnerRoleText.Agitater": "炸彈王獲勝!", - "WinnerRoleText.Shocker": "電擊者獲勝!", "AdditionalWinnerRoleText.Sidekick": "跟班", "AdditionalWinnerRoleText.Taskinator": "搗蛋鬼", "AdditionalWinnerRoleText.Opportunist": "投機主義者", @@ -3606,7 +3533,7 @@ "SolsticerOnMeeting": "過多的犧牲使你感到不安,下一輪你將額外獲得 {0} 個短任務!", "SolsticerTitle": "【 ★ 至聖者 ★ 】", "GuessSolsticer": "很抱歉,至聖者是至高無上的,為此你畏懼於與他賭博的後果", - "ExpelSolsticer": "很抱歉,至聖者是至高無上的,為此你畏懼於將其放逐的後果", + "VoteSolsticer": "很抱歉,至聖者是至高無上的,為此你畏懼於與他作對的後果", "SolsticerTasksReset": "你的任務重置了!", "SolsticerMisGuessed": "很抱歉,你因為猜測錯誤而失去猜測的能力", "SolsticerGuessMax": "很抱歉,您先前因猜測錯誤而無法繼續猜測", @@ -3707,28 +3634,6 @@ "MinionAbilityTime": "技能持續時間", "Minion_Blind": "致盲", "Evader_ChanceNotExiled": "逃過逐出的機率", - "ShockerAbilityCooldown": "技能冷卻時間", - "ShockerAbilityDuration": "技能持續時間", - "ShockerAbilityPerRound": "一回合可以使用的技能次數", - "ShockerShockInVents": "可以電擊在管道內的玩家", - "ShockerAbilityResetAfterMeeting": "會議後重置被標記的房間", - "ShockerOutsideRadius": "外部任務的電擊半徑 (房間內以外的區域)", - "ShockerCanShockHimself": "可以電擊自己", - "ShockerImpostorVision": "電擊者擁有偽裝者視野", - "ShockerIsShocking": "你已準備好電擊了!", - "ShockerAbilityActivate": "電擊已開始!", - "ShockerAbilityDeactivate": "能力已失效", - "ShockerVentButtonText": "電擊", - "ShockerRoomMarked": "標記房間", "EavesdropperMsgTitle": "你竊聽到了一個秘密", - "EavesdropPercentChance": "成功竊聽的機率", - "ChiefOfPoliceSkillCooldown": "招募警長的冷卻時間", - "PolicCanImpostorAndNeutarl": "可以招募 偽裝者 或 中立", - "SheriffSuccessfullyRecruited": "你已招募了一名警長", - "BeSheriffByPolice": "你被警察局長招募了! 幫助船員吧!", - "PoliceFailedRecruit": "招募目標失敗", - "ChiefOfPoliceKillButtonText": "招募", - "PolicPreventRecruitNonKiller": "防止招募沒有擊殺按鈕的玩家", - "PolicSuidiceWhenTargetNotKiller": "當招募到非船員或非帶刀玩家時自殺", - "PolicPassConverted": "可以傳遞被招募的附加職業給警長" -} \ No newline at end of file + "EavesdropPercentChance": "成功竊聽的機率" +} diff --git a/Resources/roleColor.json b/Resources/roleColor.json index 92684cb17..a8d7a312a 100644 --- a/Resources/roleColor.json +++ b/Resources/roleColor.json @@ -1,251 +1,253 @@ { - "Crewmate": "#8cffff", - "Engineer": "#FF6A00", - "Scientist": "#8ee98e", - "GuardianAngel": "#77e6d1", - "Noisemaker": "#9100E3", - "Tracker": "#1BB313", - "CrewmateTOHE": "#8cffff", - "EngineerTOHE": "#FF6A00", - "ScientistTOHE": "#8ee98e", - "GuardianAngelTOHE": "#77e6d1", - "NoisemakerTOHE": "#9100E3", - "TrackerTOHE": "#1BB313", - "EvilMini": "#FF1919", - "NiceMini": "#edc240", - "Mini": "#dddddd", - "President": "#00ffac", - "LazyGuy": "#a4dffe", - "Mechanic": "#3333ff", - "Snitch": "#b8fb4f", - "Marshall": "#5573aa", - "Mayor": "#204d42", - "Bastion": "#696969", - "Psychic": "#6F698C", - "Cleanser": "#98FF98", - "Sheriff": "#ffb347", - "Vigilante": "#9900CC", - "CopyCat": "#ffb2ab", - "SuperStar": "#f6f657", - "Celebrity": "#ee4a55", - "SpeedBooster": "#00ffff", - "Doctor": "#80ffdd", - "Dictator": "#df9b00", - "Detective": "#7160e8", - "NiceGuesser": "#f0e68c", - "Knight": "#7a7a7a", - "Transporter": "#42D1FF", - "TimeManager": "#6495ed", - "Veteran": "#a77738", - "Altruist": "#9b0202", - "Bodyguard": "#185abd", - "Deceiver": "#BE29EC", - "Witness": "#e70052", - "Grenadier": "#3c4a16", - "Lighter": "#eee5be", - "TaskManager": "#00ffa5", - "Medic": "#00ff97", - "FortuneTeller": "#882c83", - "Glitch": "#39FF14", - "Judge": "#f8d85a", - "Lookout": "#2a52be", - "Mortician": "#333c49", - "Medium": "#a200ff", - "Observer": "#a8e0fa", - "Pacifist": "#007FFF", - "Monarch": "#FFA500", - "Coroner": "#8B0000", - "Merchant": "#D27D2D", - "Retributionist": "#228B22", - "Alchemist": "#a058bf", - "Deputy": "#df9026", - "Investigator": "#007FFF", - "Jailer": "#aa900d", - "Guardian": "#2E8B57", - "Addict": "#008000", - "Mole": "#3E2723", - "Tracefinder": "#0066CC", - "Oracle": "#6666FF", - "Spiritualist": "#669999", - "Chameleon": "#01C834", - "Inspector": "#0D57AF", - "Admirer": "#ee43c3", - "TimeMaster": "#44baff", - "Crusader": "#C65C39", - "Reverie": "#00BFFF", - "Telecommunication": "#7223DA", - "Swapper": "#66E666", - "ChiefOfPolice": "#f8cd46", - "Spy": "#34495E", - "Randomizer": "#FFA500", - "Enigma": "#676798", - "Arsonist": "#ff6633", - "Pyromaniac": "#fc8a4c", - "Ventguard": "#ffa5ff", - "Agitater": "#F3A359", - "Bandit": "#8B008B", - "Apocalypse": "#ff174f", - "PlagueBearer": "#e5f6b4", - "Pestilence": "#343136", - "SoulCollector": "#A675A1", - "Death": "#644661", - "Baker": "#bf9f7a", - "Famine": "#83461c", - "Berserker": "#cc0044", - "War": "#2B0804", - "Jester": "#ec62a5", - "Terrorist": "#00e600", - "Executioner": "#c0c0c0", - "Lawyer": "#008080", - "God": "#f96464", - "Opportunist": "#4dff4d", - "Shaman": "#50c878", - "Vector": "#ff6201", - "Jackal": "#00b4eb", - "Sidekick": "#00b4eb", - "Innocent": "#8f815e", - "Pelican": "#34C849", - "Revolutionist": "#ba4d06", - "Hater": "#414b66", - "Prohibited": "#6a8f8f", - "Demon": "#68bc71", - "Stalker": "#483d8b", - "Workaholic": "#008b8b", - "Solsticer": "#fbfa83", - "Collector": "#9d8892", - "Provocateur": "#74ba43", - "Sunnyboy": "#ff9902", - "Poisoner": "#478800", - "Huntsman": "#ad8739", - "Necromancer": "#9C87AB", - "Follower": "#ff9409", - "Romantic": "#FF1493", - "VengefulRomantic": "#8B0000", - "RuthlessRomantic": "#D2691E", - "Cultist": "#cf6acd", - "HexMaster": "#ff00ff", - "Wraith": "#4B0082", - "SerialKiller": "#233fcc", - "BloodKnight": "#630000", - "Juggernaut": "#A41342", - "Parasite": "#ff1919", - "Crewpostor": "#ff1919", - "Refugee": "#ff1919", - "Infectious": "#7B8968", - "Virus": "#2E8B57", - "Overseer": "#BA55D3", - "Pursuer": "#617218", - "Specter": "#662962", - "Jinx": "#ed2f91", - "Troller": "#006994", - "Maverick": "#781717", - "CursedSoul": "#531269", - "PotionMaster": "#663399", - "Pickpocket": "#47008B", - "Traitor": "#BA2E05", - "Vulture": "#556B2F", - "Taskinator": "#4737ae", - "Medusa": "#9900CC", - "Spiritcaller": "#003366", - "EvilSpirit": "#003366", - "Evader": "#9beb34", - "Amnesiac": "#7FBFFF", - "Doomsayer": "#14f786", - "PunchingBag": "#684405", - "Pirate": "#EDC240", - "Shroud": "#6697FF", - "Werewolf": "#191970", - "Seeker": "#ffaa00", - "Pixie": "#00FF00", - "Imitator": "#B3D94C", - "Doppelganger": "#f6f4a3", - "GM": "#ff5b70", - "NotAssigned": "#ffffff", - "LastImpostor": "#ff1919", - "Lovers": "#ff9ace", - "Madmate": "#ff1919", - "Watcher": "#800080", - "Flash": "#ff8400", - "Torch": "#eee5be", - "Seer": "#61b26c", - "Tiebreaker": "#1447af", - "Oblivious": "#424242", - "Bewilder": "#c894f5", - "Workhorse": "#00ffff", - "Fool": "#e6e7ff", - "Avanger": "#ffab1c", - "Youtuber": "#fb749b", - "Egoist": "#5600ff", - "Stealer": "#ff1919", - "Paranoia": "#3a648f", - "Mimic": "#ff1919", - "Guesser": "#f8cd46", - "Necroview": "#663399", - "Reach": "#74ba43", - "Charmed": "#cf6acd", - "Cleansed": "#98FF98", - "Bait": "#00f7ff", - "Trapper": "#5a8fd0", - "Infected": "#7B8968", - "Onbound": "#BAAAE9", - "Rebound": "#56b5ff", - "Knighted": "#FFA500", - "Contagious": "#2E8B57", - "Unreportable": "#FF6347", - "Lucky": "#b8d7a3", - "Unlucky": "#d7a3a3", - "DoubleShot": "#19fa8d", - "Rascal": "#990000", - "Soulless": "#531269", - "Gravestone": "#2EA8E7", - "Lazy": "#a4dffe", - "Autopsy": "#80ffdd", - "Loyal": "#B71556", - "Visionary": "#ff1919", - "Recruit": "#00b4eb", - "Admired": "#ee43c3", - "Diseased": "#AAAAAA", - "Antidote": "#FF9876", - "VoidBallot": "#FF3399", - "Aware": "#4B0082", - "Stubborn": "#FF5733", - "Fragile": "#D3D3D3", - "Burst": "#B619B9", - "Bloodthirst": "#691a2e", - "Overclocked": "#C4AD2C", - "Swift": "#ff1919", - "Mare": "#ff1919", - "Ghoul": "#B22222", - "Sleuth": "#803333", - "Clumsy": "#ff1919", - "Circumvent": "#ff1919", - "Tricky": "#ff1919", - "Nimble": "#FFFAA6", - "Cyber": "#F46F4E", - "Hurried": "#136cf0", - "Oiiai": "#2bdb2b", - "Influenced": "#b0006a", - "Captain": "#4682B4", - "Benefactor": "#27ae60", - "Silent": "#9da9cf", - "Susceptible": "#2DFA04", - "Keeper": "#9ed9c8", - "Mundane": "#E69B4C", - "GuessMaster": "#FFD700", - "Killer": "#00ffff", - "Quizmaster": "#8666bd", - "Tired": "#9cdff0", - "SchrodingersCat": "#404040", - "PlagueDoctor": "#ff6633", - "Rainbow": "#55FFCB", - "Statue": "#7E9C8A", - "Warden": "#588733", - "Hawk": "#606c80", - "Spurt": "#c9e8f5", - "Ghastly": "#9ad6d4", - "Glow": "#E2F147", - "Radar": "#1eff1e", - "Rebirth": "#f08c22", - "Sloth": "#376db8", - "Eavesdropper": "#ffe6bf" + "Crewmate": "#8cffff", + "Engineer": "#FF6A00", + "Scientist": "#8ee98e", + "GuardianAngel": "#77e6d1", + "Noisemaker": "#9100E3", + "Tracker": "#1BB313", + "CrewmateTOHE": "#8cffff", + "EngineerTOHE": "#FF6A00", + "ScientistTOHE": "#8ee98e", + "GuardianAngelTOHE": "#77e6d1", + "NoisemakerTOHE": "#9100E3", + "TrackerTOHE": "#1BB313", + "EvilMini": "#FF1919", + "NiceMini": "#edc240", + "Mini": "#dddddd", + "President": "#00ffac", + "LazyGuy": "#a4dffe", + "Mechanic": "#3333ff", + "Snitch": "#b8fb4f", + "Marshall": "#5573aa", + "Mayor": "#204d42", + "Bastion": "#696969", + "Psychic": "#6F698C", + "Cleanser": "#98FF98", + "Sheriff": "#ffb347", + "Vigilante": "#9900CC", + "CopyCat": "#ffb2ab", + "SuperStar": "#f6f657", + "Celebrity": "#ee4a55", + "SpeedBooster": "#00ffff", + "Doctor": "#80ffdd", + "Dictator": "#df9b00", + "Detective": "#7160e8", + "NiceGuesser": "#f0e68c", + "Knight": "#7a7a7a", + "Transporter": "#42D1FF", + "TimeManager": "#6495ed", + "Veteran": "#a77738", + "Altruist": "#9b0202", + "Bodyguard": "#185abd", + "Deceiver": "#BE29EC", + "Witness": "#e70052", + "Grenadier": "#3c4a16", + "Lighter": "#eee5be", + "TaskManager": "#00ffa5", + "Medic": "#00ff97", + "FortuneTeller": "#882c83", + "Glitch": "#39FF14", + "Judge": "#f8d85a", + "Lookout": "#2a52be", + "Evolver": "#6dd85e", + "Mortician": "#333c49", + "Medium": "#a200ff", + "Observer": "#a8e0fa", + "Pacifist": "#007FFF", + "Monarch": "#FFA500", + "Coroner": "#8B0000", + "Merchant": "#D27D2D", + "Retributionist": "#228B22", + "Alchemist": "#a058bf", + "Deputy": "#df9026", + "Investigator": "#007FFF", + "Jailer": "#aa900d", + "Guardian": "#2E8B57", + "Addict": "#008000", + "Mole": "#3E2723", + "Tracefinder": "#0066CC", + "Oracle": "#6666FF", + "Spiritualist": "#669999", + "Chameleon": "#01C834", + "Inspector": "#0D57AF", + "Admirer": "#ee43c3", + "TimeMaster": "#44baff", + "Crusader": "#C65C39", + "Reverie": "#00BFFF", + "Telecommunication": "#7223DA", + "Swapper": "#66E666", + "ChiefOfPolice": "#f8cd46", + "Spy": "#34495E", + "Randomizer": "#FFFFFF", + "Enigma": "#676798", + "Arsonist": "#ff6633", + "Pyromaniac": "#fc8a4c", + "Ventguard": "#ffa5ff", + "Agitater": "#F3A359", + "Bandit": "#8B008B", + "Apocalypse": "#ff174f", + "PlagueBearer": "#e5f6b4", + "Pestilence": "#343136", + "SoulCollector": "#A675A1", + "Death": "#644661", + "Baker": "#bf9f7a", + "Famine": "#83461c", + "Berserker": "#cc0044", + "War": "#2B0804", + "Jester": "#ec62a5", + "Terrorist": "#00e600", + "Executioner": "#c0c0c0", + "Lawyer": "#008080", + "God": "#f96464", + "Opportunist": "#4dff4d", + "Shaman": "#50c878", + "Vector": "#ff6201", + "Jackal": "#00b4eb", + "Sidekick": "#00b4eb", + "Innocent": "#8f815e", + "Pelican": "#34C849", + "Revolutionist": "#ba4d06", + "Hater": "#414b66", + "Prohibited": "#6a8f8f", + "Demon": "#68bc71", + "Stalker": "#483d8b", + "Workaholic": "#008b8b", + "Solsticer": "#fbfa83", + "Collector": "#9d8892", + "Provocateur": "#74ba43", + "Sunnyboy": "#ff9902", + "Poisoner": "#478800", + "Huntsman": "#ad8739", + "Necromancer": "#9C87AB", + "Follower": "#ff9409", + "Romantic": "#FF1493", + "VengefulRomantic": "#8B0000", + "RuthlessRomantic": "#D2691E", + "Cultist": "#cf6acd", + "HexMaster": "#ff00ff", + "Wraith": "#4B0082", + "SerialKiller": "#233fcc", + "BloodKnight": "#630000", + "Juggernaut": "#A41342", + "Parasite": "#ff1919", + "Crewpostor": "#ff1919", + "Refugee": "#ff1919", + "Infectious": "#7B8968", + "Virus": "#2E8B57", + "Overseer": "#BA55D3", + "Pursuer": "#617218", + "Specter": "#662962", + "Jinx": "#ed2f91", + "Troller": "#006994", + "Maverick": "#781717", + "CursedSoul": "#531269", + "PotionMaster": "#663399", + "Pickpocket": "#47008B", + "Traitor": "#BA2E05", + "Vulture": "#556B2F", + "Taskinator": "#4737ae", + "Medusa": "#9900CC", + "Spiritcaller": "#003366", + "EvilSpirit": "#003366", + "Evader": "#9beb34", + "Amnesiac": "#7FBFFF", + "Doomsayer": "#14f786", + "PunchingBag": "#684405", + "Pirate": "#EDC240", + "Shroud": "#6697FF", + "Werewolf": "#191970", + "Seeker": "#ffaa00", + "Pixie": "#00FF00", + "Imitator": "#B3D94C", + "Doppelganger": "#f6f4a3", + "GM": "#ff5b70", + "NotAssigned": "#ffffff", + "LastImpostor": "#ff1919", + "Lovers": "#ff9ace", + "Madmate": "#ff1919", + "Watcher": "#800080", + "Flash": "#ff8400", + "Torch": "#eee5be", + "Seer": "#61b26c", + "Tiebreaker": "#1447af", + "Oblivious": "#424242", + "Bewilder": "#c894f5", + "Workhorse": "#00ffff", + "Fool": "#e6e7ff", + "Avanger": "#ffab1c", + "Youtuber": "#fb749b", + "Egoist": "#5600ff", + "Stealer": "#ff1919", + "Paranoia": "#3a648f", + "Mimic": "#ff1919", + "Guesser": "#f8cd46", + "Necroview": "#663399", + "Reach": "#74ba43", + "Charmed": "#cf6acd", + "Cleansed": "#98FF98", + "Bait": "#00f7ff", + "Trapper": "#5a8fd0", + "Infected": "#7B8968", + "Onbound": "#BAAAE9", + "Rebound": "#56b5ff", + "Knighted": "#FFA500", + "Contagious": "#2E8B57", + "Unreportable": "#FF6347", + "Lucky": "#b8d7a3", + "Unlucky": "#d7a3a3", + "DoubleShot": "#19fa8d", + "Rascal": "#990000", + "Soulless": "#531269", + "Gravestone": "#2EA8E7", + "Lazy": "#a4dffe", + "Autopsy": "#80ffdd", + "Loyal": "#B71556", + "Visionary": "#ff1919", + "Recruit": "#00b4eb", + "Admired": "#ee43c3", + "Diseased": "#AAAAAA", + "Antidote": "#FF9876", + "VoidBallot": "#FF3399", + "Aware": "#4B0082", + "Stubborn": "#FF5733", + "Fragile": "#D3D3D3", + "Burst": "#B619B9", + "Bloodthirst": "#691a2e", + "Overclocked": "#C4AD2C", + "Swift": "#ff1919", + "Mare": "#ff1919", + "Ghoul": "#B22222", + "Sleuth": "#803333", + "Clumsy": "#ff1919", + "Circumvent": "#ff1919", + "Tricky": "#ff1919", + "Nimble": "#FFFAA6", + "Cyber": "#F46F4E", + "Hurried": "#136cf0", + "Oiiai": "#2bdb2b", + "Influenced": "#b0006a", + "Captain": "#4682B4", + "Benefactor": "#27ae60", + "Silent": "#9da9cf", + "Susceptible": "#2DFA04", + "Keeper": "#9ed9c8", + "Mundane": "#E69B4C", + "GuessMaster": "#FFD700", + "Killer": "#00ffff", + "Quizmaster": "#8666bd", + "Tired": "#9cdff0", + "SchrodingersCat": "#404040", + "PlagueDoctor": "#ff6633", + "Rainbow": "#55FFCB", + "Statue": "#7E9C8A", + "Warden": "#588733", + "Hawk": "#606c80", + "Allergic": "#f2b542", + "Spurt": "#c9e8f5", + "Ghastly": "#9ad6d4", + "Glow": "#E2F147", + "Radar": "#1eff1e", + "Rebirth": "#f08c22", + "Sloth": "#376db8", + "Eavesdropper": "#ffe6bf" } diff --git a/Roles/(Ghosts)/Impostor/Possessor.cs b/Roles/(Ghosts)/Impostor/Possessor.cs index 0faf30a4d..5ef7042b4 100644 --- a/Roles/(Ghosts)/Impostor/Possessor.cs +++ b/Roles/(Ghosts)/Impostor/Possessor.cs @@ -130,8 +130,16 @@ public override bool OnCheckProtect(PlayerControl killer, PlayerControl target) { if (target.GetCustomRole().IsImpostorTeam()) { + var killerState = Main.PlayerStates[killer.PlayerId]; + + // Allow Randomizer to bypass the check + if (killerState.IsRandomizer) + { + Logger.Info($"Randomizer {killer.name} is attempting to use the ability on {target.name}. Bypassing impostor restriction.", "GhostRole"); + return true; // Allow the ability to proceed + } killer.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Possessor), GetString("DollMaster_CannotPossessImpTeammate"))); - return false; + return true; } if (!controllingPlayer) diff --git a/Roles/AddOns/Common/FragileSoul.cs b/Roles/AddOns/Common/FragileSoul.cs new file mode 100644 index 000000000..5f282702b --- /dev/null +++ b/Roles/AddOns/Common/FragileSoul.cs @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Roles/AddOns/Common/Tired.cs b/Roles/AddOns/Common/Tired.cs index d656b900b..ea42337f7 100644 --- a/Roles/AddOns/Common/Tired.cs +++ b/Roles/AddOns/Common/Tired.cs @@ -10,8 +10,8 @@ public class Tired : IAddon public AddonTypes Type => AddonTypes.Harmful; private static readonly Dictionary playerIdList = []; // Target Action player for Vision - private static OptionItem SetVision; - private static OptionItem SetSpeed; + public static OptionItem SetSpeed; + public static OptionItem SetVision; private static OptionItem TiredDuration; public void SetupCustomOption() diff --git a/Roles/AddOns/Common/allergic.cs b/Roles/AddOns/Common/allergic.cs new file mode 100644 index 000000000..98bfb3075 --- /dev/null +++ b/Roles/AddOns/Common/allergic.cs @@ -0,0 +1,143 @@ +using Hazel; +using TOHE.Roles.Core; +using UnityEngine; +using static TOHE.Options; +namespace TOHE.Roles.AddOns.Common +{ + public class Allergic : IAddon + { + private const int Id = 220000; + public AddonTypes Type => AddonTypes.Harmful; + + private static OptionItem AllergicDistance; + private static OptionItem AllergicTime; + + private static Dictionary allergicTargets = new(); + private Dictionary proximityTimers = new Dictionary(); + + public void SetupCustomOption() + { + SetupAdtRoleOptions(Id, CustomRoles.Allergic, canSetNum: true, teamSpawnOptions: true); + + AllergicDistance = FloatOptionItem.Create(Id + 10, "AllergicDistance", new(1.0f, 5.0f, 0.1f), 2.0f, TabGroup.Addons, false) + .SetParent(CustomRoleSpawnChances[CustomRoles.Allergic]) + .SetValueFormat(OptionFormat.Multiplier); + + AllergicTime = FloatOptionItem.Create(Id + 11, "AllergicTime", new(1.0f, 10.0f, 0.5f), 3.0f, TabGroup.Addons, false) + .SetParent(CustomRoleSpawnChances[CustomRoles.Allergic]) + .SetValueFormat(OptionFormat.Seconds); + } + + public void Init() => allergicTargets.Clear(); + + public void Add(byte playerId, bool gameIsLoading = true) + { + var allergicPlayer = PlayerControl.LocalPlayer; + if (AmongUsClient.Instance.AmHost && allergicPlayer.IsAlive()) + { + var eligibleTargets = new List(); + foreach (var p in PlayerControl.AllPlayerControls) + { + if (p.PlayerId != playerId && !p.Data.IsDead) + { + eligibleTargets.Add(p); + } + } + + + if (eligibleTargets.Count > 0) + { + var selectedTarget = eligibleTargets[UnityEngine.Random.Range(0, eligibleTargets.Count)]; + allergicTargets[allergicPlayer.PlayerId] = selectedTarget.PlayerId; + proximityTimers[allergicPlayer.PlayerId] = 0f; + + SendRPC(allergicPlayer.PlayerId, selectedTarget.PlayerId, true); + Logger.Info($"{allergicPlayer.GetNameWithRole()} is now allergic to {selectedTarget.GetNameWithRole()}", "Allergic"); + } + else + { + Logger.Info($"{allergicPlayer.GetNameWithRole()} has no valid targets to be allergic to.", "Allergic"); + } + } + } + + private void OnFixedUpdate(PlayerControl player, bool lowLoad, long nowTime) + { + if (!player.Is(CustomRoles.Allergic) || player.Data.IsDead) return; + + if (!allergicTargets.TryGetValue(player.PlayerId, out byte targetId)) + { + Logger.Info("No valid target for allergic player.", "Allergic"); + return; + } + + PlayerControl targetPlayer = null; + foreach (var p in PlayerControl.AllPlayerControls) + { + if (p.PlayerId == targetId) + { + targetPlayer = p; + break; + } + } + + + if (targetPlayer == null || targetPlayer.Data.IsDead) return; + + var distance = Vector3.Distance(player.transform.position, targetPlayer.transform.position); + + if (distance <= AllergicDistance.GetFloat()) + { + proximityTimers[player.PlayerId] += Time.deltaTime; + + if (proximityTimers[player.PlayerId] >= AllergicTime.GetFloat()) + { + KillAllergic(player); + proximityTimers[player.PlayerId] = 0f; + } + } + else + { + proximityTimers[player.PlayerId] = 0f; + } + } + + private void KillAllergic(PlayerControl player) + { + Logger.Info($"{player.GetNameWithRole()} has died due to allergic reaction proximity.", "Allergic"); + + player.SetDeathReason(PlayerState.DeathReason.Suicide); + player.RpcMurderPlayer(player); // Broadcasts the player's death to all clients + } + + public void Remove(byte playerId) + { + if (allergicTargets.ContainsKey(playerId)) + { + allergicTargets.Remove(playerId); + Logger.Info($"Removed Allergic target for player {playerId}", "Allergic"); + } + } + + private static void SendRPC(byte allergicPlayerId, byte targetId, bool setTarget) + { + MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately( + PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.SyncRoleSkill, SendOption.Reliable); + + writer.Write(setTarget); + writer.Write(allergicPlayerId); + writer.Write(targetId); + + AmongUsClient.Instance.FinishRpcImmediately(writer); + } + + public static string GetMarkOthers(PlayerControl seer, PlayerControl target, bool isForMeeting = false) + { + if (allergicTargets.TryGetValue(seer.PlayerId, out byte targetId) && target.PlayerId == targetId) + { + return Utils.ColorString(Utils.GetRoleColor(CustomRoles.Allergic), "⚠"); + } + return string.Empty; + } + } +} diff --git a/Roles/Core/AssignManager/GhostRoleAssign.cs b/Roles/Core/AssignManager/GhostRoleAssign.cs index 51e0ae25d..9eda1efd5 100644 --- a/Roles/Core/AssignManager/GhostRoleAssign.cs +++ b/Roles/Core/AssignManager/GhostRoleAssign.cs @@ -26,6 +26,8 @@ public static void GhostAssignPatch(PlayerControl player) || player.Data.Disconnected || GhostGetPreviousRole.ContainsKey(player.PlayerId)) return; + + if (forceRole.TryGetValue(player.PlayerId, out CustomRoles forcerole)) { Logger.Info($" Debug set {player.GetRealName()}'s role to {forcerole}", "GhostAssignPatch"); diff --git a/Roles/Core/CustomRoleManager.cs b/Roles/Core/CustomRoleManager.cs index 883652964..6458d4a14 100644 --- a/Roles/Core/CustomRoleManager.cs +++ b/Roles/Core/CustomRoleManager.cs @@ -161,6 +161,7 @@ public static bool OnCheckMurder(ref PlayerControl killer, ref PlayerControl tar { if (killer == target) return true; + // Check if the target is Fragile if (target != null && target.Is(CustomRoles.Fragile)) { if (Fragile.KillFragile(killer, target)) @@ -169,7 +170,20 @@ public static bool OnCheckMurder(ref PlayerControl killer, ref PlayerControl tar return false; } } - var canceled = false; + + // Check if the target is Lingering Presence + if (target != null && target.Is(CustomRoles.LingeringPresence)) + { + if (LingeringPresence.KillLingeringPresence(killer, target)) + { + Logger.Info("Lingering Presence killed in OnCheckMurder, returning false", "LingeringPresence"); + return false; + } + } + + + + var canceled = false; var cancelbutkill = false; var killerRoleClass = killer.GetRoleClass(); @@ -352,6 +366,8 @@ public static void OnMurderPlayer(PlayerControl killer, PlayerControl target, bo case CustomRoles.Spurt: Spurt.DeathTask(target); break; + + } } @@ -460,6 +476,8 @@ public static string GetLowerTextOthers(PlayerControl seer, PlayerControl seen, return sb.ToString(); } + + private static HashSet> SuffixOthers = []; ///
diff --git a/Roles/Core/RoleBase.cs b/Roles/Core/RoleBase.cs index 67600c9e1..f945e6424 100644 --- a/Roles/Core/RoleBase.cs +++ b/Roles/Core/RoleBase.cs @@ -13,7 +13,7 @@ public abstract class RoleBase public PlayerControl _Player => _state != null ? Utils.GetPlayerById(_state.PlayerId) ?? null : null; public List _playerIdList => Main.PlayerStates.Values.Where(x => x.MainRole == _state.MainRole).Select(x => x.PlayerId).Cast().ToList(); #pragma warning restore IDE1006 - + private static readonly Dictionary RoleTypeOverrides = new(); public float AbilityLimit { get; set; } = -100; public virtual bool IsEnable { get; set; } = false; public bool HasVoted = false; @@ -53,6 +53,16 @@ public void OnRemove(byte playerId) Remove(playerId); IsEnable = false; } + public static void OverrideRoleType(CustomRoles role, Custom_RoleType newType) + { + RoleTypeOverrides[role] = newType; + Logger.Info($"Role type for {role} overridden to {newType}.", "Randomizer"); + } + + public static Custom_RoleType GetEffectiveRoleType(CustomRoles role) + { + return RoleTypeOverrides.TryGetValue(role, out var overriddenType) ? overriddenType : role.GetStaticRoleClass().ThisRoleType; + } /// /// Variable resets when the game starts. diff --git a/Roles/Crewmate/Altruist.cs b/Roles/Crewmate/Altruist.cs index 47592aff0..b7f3ae126 100644 --- a/Roles/Crewmate/Altruist.cs +++ b/Roles/Crewmate/Altruist.cs @@ -45,6 +45,7 @@ public override void Init() RevivedPlayerId = byte.MaxValue; //AllRevivedPlayerId.Clear(); IsRevivingMode = true; + } public override void ApplyGameOptions(IGameOptions opt, byte playerId) diff --git a/Roles/Crewmate/Randomizer.cs b/Roles/Crewmate/Randomizer.cs index b0dbdb7b6..7492b9676 100644 --- a/Roles/Crewmate/Randomizer.cs +++ b/Roles/Crewmate/Randomizer.cs @@ -1,139 +1,897 @@ -using System; -using TOHE.Modules; -using TOHE.Roles.AddOns.Common; +using AmongUs.GameOptions; +using Il2CppSystem.Configuration; +using MS.Internal.Xml.XPath; +using TOHE; +using TOHE.Roles.Core; +using UnityEngine; using static TOHE.Options; -using static TOHE.Translator; +using static UnityEngine.GraphicsBuffer; -namespace TOHE.Roles.Crewmate; -internal class Randomizer : RoleBase +namespace TOHE.Roles.Neutral { - //===========================SETUP================================\\ - private const int Id = 7500; - private static readonly HashSet playerIdList = []; - public static bool HasEnabled => playerIdList.Any(); - - public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; - public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateBasic; - //==================================================================\\ + internal class Randomizer : RoleBase + { + //===========================SETUP================================\\ + private const int Id = 82000; // Unique ID for Randomizer + public static readonly HashSet playerIdList = new(); + public static bool HasEnabled => playerIdList.Any(); + public override bool IsDesyncRole => true; - public static OptionItem BecomeBaitDelayNotify; - public static OptionItem BecomeBaitDelayMin; - public static OptionItem BecomeBaitDelayMax; - public static OptionItem BecomeTrapperBlockMoveTime; + public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; // Base role remains Neutral + public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralChaos; + //================================================================\\ - public override void SetupCustomOption() - { - SetupRoleOptions(Id, TabGroup.CrewmateRoles, CustomRoles.Randomizer); - BecomeBaitDelayNotify = BooleanOptionItem.Create(Id + 10, "BecomeBaitDelayNotify", false, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Randomizer]); - BecomeBaitDelayMin = FloatOptionItem.Create(Id + 11, "BaitDelayMin", new(0f, 5f, 1f), 0f, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Randomizer]) - .SetValueFormat(OptionFormat.Seconds); - BecomeBaitDelayMax = FloatOptionItem.Create(Id +12, "BaitDelayMax", new(0f, 10f, 1f), 0f, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Randomizer]) - .SetValueFormat(OptionFormat.Seconds); - BecomeTrapperBlockMoveTime = FloatOptionItem.Create(Id + 13, "BecomeTrapperBlockMoveTime", new(1f, 180f, 1f), 5f, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Randomizer]) - .SetValueFormat(OptionFormat.Seconds); - } - public override void Init() - { - playerIdList.Clear(); - } - public override void Add(byte playerId) - { - playerIdList.Add(playerId); - } - public override void OnMurderPlayerAsTarget(PlayerControl killer, PlayerControl target, bool inMeeting, bool isSuicide) - { - if (inMeeting || isSuicide) return; + private static readonly Dictionary RoleAvailabilityOptions = new(); + + + private static OptionItem ChanceCrew; + private static OptionItem ChanceImpostor; + private static OptionItem ChanceNeutral; + + private static OptionItem AllowGhostRoles; + private static OptionItem MinAddOns; + private static OptionItem MaxAddOns; + + + + + + + public override void SetupCustomOption() + { + Options.SetupRoleOptions(Id, TabGroup.NeutralRoles, CustomRoles.Randomizer); + + // Add Chance Crew Option + ChanceCrew = IntegerOptionItem.Create(Id + 10, "ChanceCrew", new(0, 100, 5), 40, TabGroup.NeutralRoles, false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Randomizer]) + .SetValueFormat(OptionFormat.Percent); + + + // Add Chance Impostor Option + ChanceImpostor = IntegerOptionItem.Create(Id + 11, "ChanceImpostor", new(0, 100, 5), 40, TabGroup.NeutralRoles, false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Randomizer]) + .SetValueFormat(OptionFormat.Percent); + + + // Add Chance Neutral Option + ChanceNeutral = IntegerOptionItem.Create(Id + 12, "ChanceNeutral", new(0, 100, 5), 20, TabGroup.NeutralRoles, false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Randomizer]) + .SetValueFormat(OptionFormat.Percent); + + + AllowGhostRoles = BooleanOptionItem.Create(Id + 20, "AllowGhostRoles", false, TabGroup.NeutralRoles, false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Randomizer]); + + + MinAddOns = IntegerOptionItem.Create(Id + 30, "MinAddOns", new(0, 10, 1), 0, TabGroup.NeutralRoles, false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Randomizer]); + + MaxAddOns = IntegerOptionItem.Create(Id + 31, "MaxAddOns", new(0, 10, 1), 3, TabGroup.NeutralRoles, false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Randomizer]); + } - var Fg = IRandom.Instance; - int Randomizer = Fg.Next(1, 5); - if (Randomizer == 1) + + + + + + + + + + public override void Init() { - if (isSuicide) + playerIdList.Clear(); + + int crewChance = ChanceCrew.GetInt(); + int impostorChance = ChanceImpostor.GetInt(); + int neutralChance = ChanceNeutral.GetInt(); + + int totalChance = crewChance + impostorChance + neutralChance; + + // Check if total chances exceed 100% + if (totalChance > 100) { - if (target.GetRealKiller() != null) - { - if (!target.GetRealKiller().IsAlive()) return; - killer = target.GetRealKiller(); - } + Logger.Warn("Total team chances exceed 100%. Overlap resolution will be applied during role assignment.", "Randomizer"); + } + else if (totalChance == 0) + { + Logger.Warn("All team chances are set to 0. Using default equal distribution.", "Randomizer"); } - if (killer.PlayerId == target.PlayerId) return; + Logger.Info($"Initialized Randomizer with team chances - Crewmate: {crewChance}%, Impostor: {impostorChance}%, Neutral: {neutralChance}%.", "Randomizer"); + } + - if (killer.Is(CustomRoles.KillingMachine) - || (killer.Is(CustomRoles.Oblivious) && Oblivious.ObliviousBaitImmune.GetBool())) - return; - if (!isSuicide || (target.GetRealKiller()?.GetCustomRole() is CustomRoles.Swooper or CustomRoles.Wraith) || !killer.Is(CustomRoles.KillingMachine) || !killer.Is(CustomRoles.Oblivious) || (killer.Is(CustomRoles.Oblivious) && !Oblivious.ObliviousBaitImmune.GetBool())) + + + + + public override void Add(byte playerId) + { + if (playerIdList.Contains(playerId)) return; // Avoid duplicates + + playerIdList.Add(playerId); + + + + var pc = Utils.GetPlayerById(playerId); + if (pc == null) return; + + // Set Randomizer role + var playerState = Main.PlayerStates[playerId]; + playerState.SetMainRole(CustomRoles.Randomizer); + playerState.IsRandomizer = true; + + if (pc.GetCustomRole() != CustomRoles.Randomizer) { - killer.RPCPlayCustomSound("Congrats"); - target.RPCPlayCustomSound("Congrats"); + pc.RpcChangeRoleBasis(CustomRoles.Crewmate); + pc.RpcSetCustomRole(CustomRoles.Randomizer); + } + + // Notify player + pc.Notify($"You are the Randomizer! Your role will change after each meeting."); + } + + + private void AssignRandomRole(byte playerId) + { + var pc = Utils.GetPlayerById(playerId); + if (pc == null) return; + + // Reset subroles before assigning a new role + ResetSubRoles(playerId); + + // Get the player's state + var playerState = Main.PlayerStates[playerId]; + if (playerState == null) return; - float delay; - if (BecomeBaitDelayMax.GetFloat() < BecomeBaitDelayMin.GetFloat()) + // Determine team lock if not already applied + if (!playerState.TeamLockApplied) + { + CustomRoles randomRole = GetRandomRoleAcrossAllTeams(playerId); + + // Lock the team based on the role + if (randomRole.IsCrewmate()) { - delay = 0f; + playerState.IsCrewmateTeam = true; + playerState.LockedRoleType = Custom_RoleType.CrewmateBasic; // Lock to Crewmate type + Logger.Info($"Randomizer locked to Crewmate team.", "Randomizer"); } - else + else if (randomRole.IsImpostorTeam()) { - delay = IRandom.Instance.Next((int)BecomeBaitDelayMin.GetFloat(), (int)BecomeBaitDelayMax.GetFloat() + 1); + playerState.IsImpostorTeam = true; + playerState.LockedRoleType = Custom_RoleType.ImpostorVanilla; // Lock to Impostor type + Logger.Info($"Randomizer locked to Impostor team.", "Randomizer"); } - delay = Math.Max(delay, 0.15f); - if (delay > 0.15f && BecomeBaitDelayNotify.GetBool()) + else if (randomRole.IsNeutral()) { - killer.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Bait), string.Format(GetString("KillBaitNotify"), (int)delay)), delay); + playerState.IsNeutralTeam = true; + playerState.LockedRoleType = Custom_RoleType.NeutralChaos; // Lock to Neutral type + Logger.Info($"Randomizer locked to Neutral team.", "Randomizer"); } - Logger.Info($"{killer.GetNameWithRole()} 击杀了萧暮触发自动报告 => {target.GetNameWithRole()}", "Randomizer"); + // Apply the role + pc.RpcChangeRoleBasis(randomRole); // Update basis to match the new role + pc.RpcSetCustomRole(randomRole); // Set the random role + pc.GetRoleClass()?.OnAdd(playerId); // Initialize the new role logic + pc.SyncSettings(); // Ensures the player's UI reflects the changes + + // Initialize tasks and abilities + playerState.InitTask(pc); + + Logger.Info($"Randomizer assigned initial role {randomRole} to player {pc.name}", "Randomizer"); + } + else + { + // If team is already locked, get a new random role + CustomRoles randomRole = GetRandomRoleAcrossAllTeams(playerId); + + // Apply the new role while maintaining the locked team + pc.RpcChangeRoleBasis(randomRole); // Update basis to match the new role + pc.RpcSetCustomRole(randomRole); // Set the random role + pc.GetRoleClass()?.OnAdd(playerId); // Initialize the new role logic + pc.SyncSettings(); // Ensures the player's UI reflects the changes + + // Initialize tasks and abilities + playerState.InitTask(pc); + + Logger.Info($"Randomizer assigned new role {randomRole} to player {pc.name} (team locked to {playerState.LockedRoleType})", "Randomizer"); + } + } + + + public static void RandomizerWinCondition(PlayerControl pc) + { + if (pc == null) return; + + var playerState = Main.PlayerStates[pc.PlayerId]; + if (!playerState.IsRandomizer || !playerState.TeamLockApplied) + { + Logger.Warn($"Randomizer {pc.name} has no team lock applied or is not a Randomizer. Skipping win condition check.", "Randomizer"); + return; + } + + // Alive players' win conditions + switch (playerState.RandomizerWinCondition) + { + case Custom_Team.Crewmate: + if (CustomWinnerHolder.WinnerTeam == CustomWinner.Crewmate && pc.IsAlive()) + { + CustomWinnerHolder.WinnerIds.Add(pc.PlayerId); + CustomWinnerHolder.AdditionalWinnerTeams.Add(AdditionalWinners.Randomizer); + Logger.Info($"Randomizer {pc.name} (alive) wins with the Crewmate team.", "Randomizer"); + } + break; + + case Custom_Team.Impostor: + if (CustomWinnerHolder.WinnerTeam == CustomWinner.Impostor && pc.IsAlive()) + { + CustomWinnerHolder.WinnerIds.Add(pc.PlayerId); + CustomWinnerHolder.AdditionalWinnerTeams.Add(AdditionalWinners.Randomizer); + Logger.Info($"Randomizer {pc.name} (alive) wins with the Impostor team.", "Randomizer"); + } + break; - killer.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Randomizer), GetString("YouKillRandomizer1"))); + case Custom_Team.Neutral: + if (pc.IsAlive()) + { + CustomWinnerHolder.WinnerIds.Add(pc.PlayerId); + CustomWinnerHolder.AdditionalWinnerTeams.Add(AdditionalWinners.Randomizer); + Logger.Info($"Randomizer {pc.name} wins as a Neutral player (alive).", "Randomizer"); + } + break; - _ = new LateTask(() => + default: + Logger.Warn($"Randomizer {pc.name} has an unknown or invalid win condition: {playerState.RandomizerWinCondition}.", "Randomizer"); + break; + } + + // Dead players' win conditions + if (!pc.IsAlive()) + { + if (playerState.LockedTeam == Custom_Team.Crewmate && CustomWinnerHolder.WinnerTeam == CustomWinner.Crewmate) + { + CustomWinnerHolder.WinnerIds.Add(pc.PlayerId); + CustomWinnerHolder.AdditionalWinnerTeams.Add(AdditionalWinners.Randomizer); + Logger.Info($"Randomizer {pc.name} (dead) wins with the Crewmate team.", "Randomizer"); + } + else if (playerState.LockedTeam == Custom_Team.Impostor && CustomWinnerHolder.WinnerTeam == CustomWinner.Impostor) { - if (GameStates.IsInTask) killer.CmdReportDeadBody(target.Data); - }, delay, "Bait Self Report"); + CustomWinnerHolder.WinnerIds.Add(pc.PlayerId); + CustomWinnerHolder.AdditionalWinnerTeams.Add(AdditionalWinners.Randomizer); + Logger.Info($"Randomizer {pc.name} (dead) wins with the Impostor team.", "Randomizer"); + } } } - else if (Randomizer == 2) + + + + + + + + + + + private static Custom_Team DetermineTeam() { - Logger.Info($"{killer.GetNameWithRole()} 击杀了萧暮触发暂时无法移动 => {target.GetNameWithRole()}", "Randomizer"); + int crewChance = ChanceCrew.GetInt(); + int impostorChance = ChanceImpostor.GetInt(); + int neutralChance = ChanceNeutral.GetInt(); + + int totalChance = crewChance + impostorChance + neutralChance; + + // Handle all chances set to 0 or if total chance is 0 + if (totalChance == 0) + { + Logger.Warn("All team chances are set to 0. Running default overlap with equal chances.", "DetermineTeam"); + return ResolveOverlap(new[] { Custom_Team.Crewmate, Custom_Team.Impostor, Custom_Team.Neutral }); + } + + int roll = UnityEngine.Random.Range(0, totalChance); - killer.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Randomizer), GetString("YouKillRandomizer2"))); - var tmpSpeed = Main.AllPlayerSpeed[killer.PlayerId]; - Main.AllPlayerSpeed[killer.PlayerId] = Main.MinSpeed; - ReportDeadBodyPatch.CanReport[killer.PlayerId] = false; - killer.MarkDirtySettings(); + // Check for overlapping chances + List overlappingTeams = new(); - _ = new LateTask(() => + if (roll < crewChance) overlappingTeams.Add(Custom_Team.Crewmate); + if (roll < crewChance + impostorChance && roll >= crewChance) overlappingTeams.Add(Custom_Team.Impostor); + if (roll >= crewChance + impostorChance) overlappingTeams.Add(Custom_Team.Neutral); + + // Handle overlap dynamically + if (overlappingTeams.Count > 1) { - Main.AllPlayerSpeed[killer.PlayerId] = Main.AllPlayerSpeed[killer.PlayerId] - Main.MinSpeed + tmpSpeed; - ReportDeadBodyPatch.CanReport[killer.PlayerId] = true; - killer.MarkDirtySettings(); - RPC.PlaySoundRPC(killer.PlayerId, Sounds.TaskComplete); - }, BecomeTrapperBlockMoveTime.GetFloat(), "Trapper BlockMove"); + Logger.Warn($"Chance overlap detected for teams: {string.Join(", ", overlappingTeams)}. Resolving overlap...", "DetermineTeam"); + return ResolveOverlap(overlappingTeams); + } + + // Return the determined team if no overlap + if (roll < crewChance) return Custom_Team.Crewmate; + if (roll < crewChance + impostorChance) return Custom_Team.Impostor; + return Custom_Team.Neutral; } - else if (Randomizer == 3) + private static Custom_Team ResolveOverlap(IEnumerable overlappingTeams) { - Logger.Info($"{killer.GetNameWithRole()} 击杀了萧暮触发凶手CD变成600 => {target.GetNameWithRole()}", "Randomizer"); - killer.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Randomizer), GetString("YouKillRandomizer3"))); - Main.AllPlayerKillCooldown[killer.PlayerId] = 600f; - killer.SyncSettings(); + var teams = overlappingTeams.ToList(); + int roll = UnityEngine.Random.Range(0, teams.Count); + + Logger.Info($"Resolved overlap. Selected team: {teams[roll]}", "ResolveOverlap"); + return teams[roll]; } - else if (Randomizer == 4) + + private static void NotifyRoleChange(PlayerControl pc, CustomRoles newRole) { - Logger.Info($"{killer.GetNameWithRole()} 击杀了萧暮触发随机复仇 => {target.GetNameWithRole()}", "Randomizer"); - killer.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Randomizer), GetString("YouKillRandomizer4"))); + var playerState = Main.PlayerStates[pc.PlayerId]; + + // Get a list of add-ons for the player + var addOns = string.Join(", ", playerState.SubRoles.Select(addOn => Utils.GetRoleName(addOn))); + + // Notify Randomizer about its role and add-ons + string message = $"You are still the Randomizer! Your current role is {Utils.GetRoleName(newRole)}"; + if (!string.IsNullOrEmpty(addOns)) { - var pcList = Main.AllAlivePlayerControls.Where(x => x.PlayerId != target.PlayerId && target.RpcCheckAndMurder(x, true)).ToList(); - var pc = pcList[IRandom.Instance.Next(0, pcList.Count)]; - if (!pc.IsTransformedNeutralApocalypse()) + message += $" with the following add-ons: {addOns}."; + } + + pc.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Randomizer), message)); + } + private static bool IsRoleEnabled(CustomRoles role) + { + if (RoleAvailabilityOptions.TryGetValue(role, out var option)) + { + return option.GetBool(); + } + return true; // Default to enabled if not explicitly configured + } + private static CustomRoles GetGhostRole(byte playerId) + { + if (!GhostRolesList.Any()) + { + Logger.Warn("No ghost roles available. Defaulting to a fallback role.", "Randomizer"); + return CustomRoles.CrewmateTOHE; // Default fallback if the list is empty + } + + // Select a random ghost role + CustomRoles selectedRole = GhostRolesList[UnityEngine.Random.Range(0, GhostRolesList.Count)]; + Logger.Info($"Assigned ghost role {selectedRole} to player ID {playerId}.", "Randomizer"); + return selectedRole; + } + + + + + + + private static CustomRoles GetRandomRoleAcrossAllTeams(byte playerId) + { + var pc = Utils.GetPlayerById(playerId); + if (pc == null) return CustomRoles.CrewmateTOHE; // Default fallback + + var playerState = Main.PlayerStates[playerId]; + + // Determine team based on percentage chances + var team = DetermineTeam(); + + List availableRoles = team switch + { + Custom_Team.Crewmate => GetAllCrewmateRoles(), + Custom_Team.Impostor => GetAllImpostorRoles(), + Custom_Team.Neutral => GetAllNeutralRoles(), + _ => new List() // Default empty list + }; + + if (!availableRoles.Any()) + { + Logger.Error("Available roles list is empty for the determined team. Defaulting to Crewmate.", "Randomizer"); + return CustomRoles.CrewmateTOHE; // Fallback role + } + + // Select a random role from the available roles + var selectedRole = availableRoles[UnityEngine.Random.Range(0, availableRoles.Count)]; + + // Lock the team if not already locked + if (!playerState.TeamLockApplied) + { + playerState.TeamLockApplied = true; + playerState.IsCrewmateTeam = team == Custom_Team.Crewmate; + playerState.IsImpostorTeam = team == Custom_Team.Impostor; + playerState.IsNeutralTeam = team == Custom_Team.Neutral; + + Logger.Info($"Randomizer locked to {team} team.", "Randomizer"); + } + + Logger.Info($"Randomizer assigned role: {selectedRole}", "Randomizer"); + return selectedRole; + } + public override bool OnCheckMurderAsTarget(PlayerControl killer, PlayerControl target) + { + + var playerState = Main.PlayerStates[target.PlayerId]; + var isRandomizer = playerState.IsRandomizer; + + if (!isRandomizer) + { + Logger.Info($"Player {target.name} is not Randomizer. Skipping ghost role assignment.", "Randomizer"); + return false; // Continue with default behavior + } + + Logger.Info($"Randomizer {target.name} is being killed by {killer.name}. Checking ghost role settings...", "Randomizer"); + + // Check if ghost roles are allowed + if (AllowGhostRoles.GetBool()) + { + Logger.Info($"Ghost roles are enabled. Assigning GuardianAngel base to {target.name}.", "Randomizer"); + + // Assign GuardianAngel base and link the role + var newGhostRole = GetGhostRole(target.PlayerId); + target.RpcChangeRoleBasis(CustomRoles.GuardianAngel); // Change to GuardianAngel base + target.RpcSetCustomRole(newGhostRole); // Assign the selected ghost role + target.GetRoleClass()?.OnAdd(target.PlayerId); // Initialize the role class + target.SyncSettings(); // Sync role settings + playerState.IsDead = true; // Ensure the player is marked as a ghost + + Logger.Info($"Assigned ghost role {newGhostRole} to Randomizer {target.name}.", "Randomizer"); + return true; // Prevent further processing of the murder + } + else + { + Logger.Info($"Ghost roles are disabled. Keeping Randomizer {target.name} as a standard dead player.", "Randomizer"); + return true; // Allow the murder to proceed without ghost role assignment + } + } + + + public static void RandomizerGhost(PlayerControl pc) + { + var playerState = Main.PlayerStates[pc.PlayerId]; + + + + Logger.Info($"Applying RandomizerGhost logic to {pc.name}.", "Randomizer"); + + // Teleport player outside the map + pc.RpcTeleport(ExtendedPlayerControl.GetBlackRoomPosition()); + + // Schedule a task to "kill" the player + _ = new LateTask( + () => { - pc.SetDeathReason(PlayerState.DeathReason.Revenge); + // Kill the player pc.RpcMurderPlayer(pc); - pc.SetRealKiller(target); + playerState.IsDead = true; + + // Sync death information + pc.SetRealKiller(pc); // Set self as killer (or null if unnecessary) + Logger.Info($"{pc.name} has been killed and marked as a ghost Randomizer.", "Randomizer"); + + // Teleport back to spawn + _ = new LateTask( + () => + { + Vector3 spawnPosition = new Vector3(0, 0, 0); + pc.RpcTeleport(spawnPosition); + Logger.Info($"{pc.name} teleported back to spawn as a ghost Randomizer.", "Randomizer"); + }, + 1f, // Delay to ensure smooth transition + "TeleportBackToSpawn" + ); + }, + 0.5f, // Delay before killing + "RandomizerKillTask" + ); + } + + + public static void AfterMeetingTasks() + { + foreach (var playerId in playerIdList.ToList()) + { + var pc = Utils.GetPlayerById(playerId); + if (pc == null) continue; + + // Reset subroles + Main.PlayerStates[playerId].ResetSubRoles(); + pc.GetRoleClass()?.OnRemove(pc.PlayerId); + + // Determine role assignment based on player's alive status + CustomRoles newRole; + if (!pc.IsAlive()) + { + if (AllowGhostRoles.GetBool()) // Ghost roles are enabled + { + Logger.Info($"Randomizer {pc.name} is dead. Assigning a new ghost role.", "Randomizer"); + + // Assign ghost role + newRole = GetGhostRole(pc.PlayerId); + pc.RpcChangeRoleBasis(CustomRoles.GuardianAngel); // Set base role + pc.RpcSetCustomRole(newRole); // Set the custom ghost role + pc.GetRoleClass()?.OnAdd(pc.PlayerId); // Initialize role + pc.SyncSettings(); // Sync the role settings + RandomizerGhost(pc); + // Explicitly set dead state + Main.PlayerStates[pc.PlayerId].IsDead = true; // Mark as dead + + + Logger.Info($"Randomizer {pc.name} has been marked as dead and assigned the ghost role: {newRole}.", "Randomizer"); + } + + + else + { + // Ghost roles are disabled, do nothing to avoid reviving + Logger.Info($"Randomizer {pc.name} is dead. Ghost roles are disabled. No role changes applied.", "Randomizer"); + continue; + } + } + else if (pc.IsAlive()) // Player is alive, assign a normal role + { + Logger.Info($"Randomizer {pc.name} is alive. Assigning a normal role.", "Randomizer"); + newRole = GetRandomRoleAcrossAllTeams(playerId); // Assign from the normal role pool + } + else + { + Logger.Warn($"Randomizer {pc.name} could not be assigned a role. Defaulting to Crewmate.", "Randomizer"); + newRole = CustomRoles.CrewmateTOHE; // Fallback in case of unexpected condition + } + + Logger.Info($"Assigning role {newRole} to player {pc.name}", "Randomizer"); + + // Update the player's role + pc.RpcChangeRoleBasis(newRole); // Update the role basis + pc.RpcSetCustomRole(newRole); // Set the actual role + + // Preserve Randomizer flag + var playerState = Main.PlayerStates[playerId]; + playerState.IsRandomizer = true; + + // Notify the player after the role is finalized + NotifyRoleChange(pc, newRole); + + // Assign random add-ons (only for alive players) + if (pc.IsAlive()) + { + // Retrieve the min and max add-on settings + int minAddOns = MinAddOns.GetInt(); + int maxAddOns = MaxAddOns.GetInt(); + + // Ensure maxAddOns is not less than minAddOns + if (maxAddOns < minAddOns) + { + Logger.Warn($"Max Add-Ons ({maxAddOns}) is less than Min Add-Ons ({minAddOns}). Using Min Add-Ons.", "Randomizer"); + maxAddOns = minAddOns; + } + + // Randomly determine the number of add-ons to assign + int addOnCount = UnityEngine.Random.Range(minAddOns, maxAddOns + 1); + List selectedAddOns = GetAvailableAddOns() + .OrderBy(_ => UnityEngine.Random.value) + .Take(addOnCount) + .ToList(); + + foreach (var addOn in selectedAddOns) + { + playerState.SetSubRole(addOn, pc); + Logger.Info($"Assigned Add-on {addOn} to {pc.name}", "Randomizer"); + } } + + // Sync settings and tasks + pc.SyncSettings(); + playerState.InitTask(pc); + pc.GetRoleClass()?.OnAdd(pc.PlayerId); } } + + + + + + + + + private void ResetSubRoles(byte playerId) + { + var playerState = Main.PlayerStates[playerId]; + if (playerState == null) return; + + foreach (var subRole in playerState.SubRoles.ToList()) // Use ToList() to avoid modification during enumeration + { + playerState.RemoveSubRole(subRole); + } + + playerState.SubRoles.Clear(); // Ensure the SubRoles list is empty + } + public override void Remove(byte playerId) + { + var playerState = Main.PlayerStates[playerId]; + if (playerState != null) + playerState.IsRandomizer = false; // Clear Randomizer flag + playerState.TeamLockApplied = false; // Reset team lock + playerState.IsCrewmateTeam = false; + playerState.IsImpostorTeam = false; + playerState.IsNeutralTeam = false; + } + + // Define role lists inside the Randomizer class + private static List GetAllCrewmateRoles() + { + return new List + { + CustomRoles.Addict, + CustomRoles.Alchemist, + CustomRoles.Bastion, + CustomRoles.Benefactor, + CustomRoles.Bodyguard, + CustomRoles.Captain, + CustomRoles.Celebrity, + CustomRoles.Cleanser, + CustomRoles.Coroner, + CustomRoles.Crusader, + CustomRoles.Deceiver, + CustomRoles.Deputy, + CustomRoles.Detective, + CustomRoles.Dictator, + CustomRoles.Enigma, + CustomRoles.FortuneTeller, + CustomRoles.Grenadier, + CustomRoles.Guardian, + CustomRoles.GuessMaster, + CustomRoles.Inspector, + CustomRoles.Investigator, + CustomRoles.Jailer, + CustomRoles.Judge, + CustomRoles.Keeper, + CustomRoles.Knight, + CustomRoles.LazyGuy, + CustomRoles.Lighter, + CustomRoles.Lookout, + CustomRoles.Marshall, + CustomRoles.Mayor, + CustomRoles.Mechanic, + CustomRoles.Medium, + CustomRoles.Merchant, + CustomRoles.Mole, + CustomRoles.Mortician, + CustomRoles.NiceGuesser, + CustomRoles.Observer, + CustomRoles.Oracle, + CustomRoles.Overseer, + CustomRoles.Pacifist, + CustomRoles.Psychic, + CustomRoles.Reverie, + CustomRoles.Sheriff, + CustomRoles.Snitch, + CustomRoles.Spiritualist, + CustomRoles.Spy, + CustomRoles.Swapper, + CustomRoles.TaskManager, + CustomRoles.Telecommunication, + CustomRoles.TimeManager, + CustomRoles.TimeMaster, + CustomRoles.Tracefinder, + CustomRoles.Transporter, + CustomRoles.Ventguard, + CustomRoles.Veteran, + CustomRoles.Vigilante, + CustomRoles.Witness, + // Add other Crewmate roles here + }; + } + + private static List GetAllNeutralRoles() + { + return new List + { + CustomRoles.Arsonist, + CustomRoles.Arsonist, + CustomRoles.Bandit, + + CustomRoles.BloodKnight, + CustomRoles.Collector, + CustomRoles.Demon, + CustomRoles.Doomsayer, + CustomRoles.Executioner, + CustomRoles.Evolver, + CustomRoles.Follower, + CustomRoles.Glitch, + CustomRoles.God, + CustomRoles.Hater, + CustomRoles.HexMaster, + CustomRoles.Huntsman, + CustomRoles.Jester, + CustomRoles.Jinx, + CustomRoles.Juggernaut, + CustomRoles.Maverick, + CustomRoles.Medusa, + CustomRoles.Necromancer, + CustomRoles.Opportunist, + CustomRoles.Pelican, + CustomRoles.Pickpocket, + CustomRoles.Pirate, + CustomRoles.Pixie, + CustomRoles.PlagueDoctor, + CustomRoles.Poisoner, + CustomRoles.PotionMaster, + CustomRoles.PunchingBag, + CustomRoles.Pursuer, + CustomRoles.Pyromaniac, + CustomRoles.Quizmaster, + CustomRoles.Revolutionist, + CustomRoles.RuthlessRomantic, + CustomRoles.SchrodingersCat, + CustomRoles.Seeker, + CustomRoles.SerialKiller, + CustomRoles.Shaman, + CustomRoles.Shroud, + CustomRoles.Sidekick, + CustomRoles.Solsticer, + CustomRoles.Stalker, + CustomRoles.Sunnyboy, + CustomRoles.Taskinator, + CustomRoles.Terrorist, + CustomRoles.Traitor, + CustomRoles.Troller, + CustomRoles.Vector, + CustomRoles.VengefulRomantic, + CustomRoles.Vulture, + CustomRoles.Werewolf, + CustomRoles.Workaholic, + + // Add other Neutral roles here + }; + } + + private static List GetAllImpostorRoles() + { + return new List + { + CustomRoles.Consigliere, + CustomRoles.Crewpostor, + CustomRoles.Cleaner, + CustomRoles.Anonymous, + CustomRoles.AntiAdminer, + CustomRoles.Arrogance, + CustomRoles.Bard, + CustomRoles.Blackmailer, + CustomRoles.Bomber, + CustomRoles.BountyHunter, + CustomRoles.Butcher, + CustomRoles.Camouflager, + CustomRoles.Chronomancer, + CustomRoles.Councillor, + CustomRoles.CursedWolf, + CustomRoles.Dazzler, + CustomRoles.Deathpact, + CustomRoles.Disperser, + CustomRoles.DoubleAgent, + CustomRoles.Eraser, + CustomRoles.Escapist, + CustomRoles.EvilGuesser, + CustomRoles.EvilHacker, + CustomRoles.EvilTracker, + CustomRoles.Fireworker, + CustomRoles.Greedy, + CustomRoles.Hangman, + CustomRoles.Inhibitor, + CustomRoles.Kamikaze, + CustomRoles.KillingMachine, + CustomRoles.Lightning, + CustomRoles.Ludopath, + CustomRoles.Lurker, + CustomRoles.Mastermind, + CustomRoles.Miner, + CustomRoles.Morphling, + CustomRoles.Ninja, + CustomRoles.Parasite, + CustomRoles.Penguin, + CustomRoles.Pitfall, + CustomRoles.Puppeteer, + CustomRoles.QuickShooter, + CustomRoles.Refugee, + CustomRoles.RiftMaker, + CustomRoles.Saboteur, + CustomRoles.Scavenger, + CustomRoles.ShapeMaster, + CustomRoles.Sniper, + CustomRoles.SoulCatcher, + CustomRoles.Stealth, + CustomRoles.YinYanger, + CustomRoles.Swooper, + CustomRoles.Trapster, + CustomRoles.Trickster, + CustomRoles.Twister, + CustomRoles.Undertaker, + CustomRoles.Vampire, + CustomRoles.Vindicator, + CustomRoles.Visionary, + CustomRoles.Warlock, + CustomRoles.Wildling, + CustomRoles.Witch, + CustomRoles.Zombie, + // Add other existing impostor roles here + }; + } + + + private static List GetAvailableAddOns() + { + return new List + { + + CustomRoles.Antidote, + CustomRoles.Autopsy, + CustomRoles.Avanger, + CustomRoles.Aware, + CustomRoles.Bait, + CustomRoles.Bewilder, + CustomRoles.Bloodthirst, + CustomRoles.Burst, + CustomRoles.Circumvent, + CustomRoles.Cleansed, + CustomRoles.Clumsy, + CustomRoles.Cyber, + CustomRoles.Diseased, + CustomRoles.DoubleShot, + CustomRoles.Eavesdropper, + CustomRoles.Evader, + CustomRoles.Flash, + CustomRoles.Fool, + CustomRoles.Fragile, + CustomRoles.Ghoul, + CustomRoles.Glow, + CustomRoles.Gravestone, + CustomRoles.Guesser, + CustomRoles.Influenced, + CustomRoles.LastImpostor, + CustomRoles.Lazy, + CustomRoles.Loyal, + CustomRoles.Lucky, + CustomRoles.Mare, + CustomRoles.Rebirth, + CustomRoles.Mimic, + CustomRoles.Mundane, + CustomRoles.Necroview, + CustomRoles.Nimble, + CustomRoles.Oblivious, + CustomRoles.Onbound, + CustomRoles.Overclocked, + CustomRoles.Paranoia, + CustomRoles.Prohibited, + CustomRoles.Radar, + CustomRoles.Rainbow, + CustomRoles.Rascal, + CustomRoles.Reach, + CustomRoles.Rebound, + CustomRoles.Spurt, + CustomRoles.Seer, + CustomRoles.Silent, + CustomRoles.Sleuth, + CustomRoles.Sloth, + CustomRoles.Statue, + CustomRoles.Stubborn, + CustomRoles.Susceptible, + CustomRoles.Swift, + CustomRoles.Tiebreaker, + CustomRoles.Stealer, + CustomRoles.Torch, + CustomRoles.Trapper, + CustomRoles.Tricky, + CustomRoles.Tired, + CustomRoles.Unlucky, + CustomRoles.VoidBallot, + CustomRoles.Watcher, + CustomRoles.Workhorse, + + }; + + + } + + private static readonly List GhostRolesList = new() +{ + CustomRoles.Bloodmoon, + CustomRoles.Minion, + CustomRoles.Possessor, + CustomRoles.Ghastly, + CustomRoles.Hawk, + CustomRoles.Warden +}; } } diff --git a/Roles/Crewmate/Sheriff.cs b/Roles/Crewmate/Sheriff.cs index 81b31c093..062f6c550 100644 --- a/Roles/Crewmate/Sheriff.cs +++ b/Roles/Crewmate/Sheriff.cs @@ -132,6 +132,7 @@ public static bool CanBeKilledBySheriff(PlayerControl player) var cRole = player.GetCustomRole(); var subRole = player.GetCustomSubRoles(); bool CanKill = false; + foreach (var SubRoleTarget in subRole) { if (SubRoleTarget == CustomRoles.Madmate) @@ -154,7 +155,6 @@ public static bool CanBeKilledBySheriff(PlayerControl player) CanKill = false; } - return cRole switch { CustomRoles.Trickster => false, @@ -167,6 +167,7 @@ var r when cRole.IsTNA() => false, } }; } + public override void SetAbilityButtonText(HudManager hud, byte id) { hud.KillButton.OverrideText(GetString("SheriffKillButtonText")); diff --git a/Roles/Impostor/Anonymous.cs b/Roles/Impostor/Anonymous.cs index a5643c2c6..73bbfb7e8 100644 --- a/Roles/Impostor/Anonymous.cs +++ b/Roles/Impostor/Anonymous.cs @@ -17,8 +17,9 @@ internal class Anonymous : RoleBase //==================================================================\\ public override Sprite GetAbilityButtonSprite(PlayerControl player, bool shapeshifting) => CustomButton.Get("Hack"); - private static OptionItem HackLimitOpt; - private static OptionItem KillCooldown; + public static OptionItem HackLimitOpt; + public static OptionItem KillCooldown; + private static readonly List DeadBodyList = []; @@ -37,6 +38,12 @@ public override void Init() public override void Add(byte playerId) { AbilityLimit = HackLimitOpt.GetInt(); + if (Main.PlayerStates[playerId].IsRandomizer) + { + + } + + base.Add(playerId); } public override void SetKillCooldown(byte id) => Main.AllPlayerKillCooldown[id] = KillCooldown.GetFloat(); public override void ApplyGameOptions(IGameOptions opt, byte playerId) diff --git a/Roles/Impostor/AntiAdminer.cs b/Roles/Impostor/AntiAdminer.cs index 21ddf7f60..228db6101 100644 --- a/Roles/Impostor/AntiAdminer.cs +++ b/Roles/Impostor/AntiAdminer.cs @@ -19,7 +19,7 @@ internal class AntiAdminer : RoleBase public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorSupport; //==================================================================\\ - private static OptionItem CanCheckCamera; + public static OptionItem CanCheckCamera; private static bool IsAdminWatch; private static bool IsVitalWatch; diff --git a/Roles/Impostor/Arrogance.cs b/Roles/Impostor/Arrogance.cs index 32a5dcce7..aacb2b0d8 100644 --- a/Roles/Impostor/Arrogance.cs +++ b/Roles/Impostor/Arrogance.cs @@ -14,9 +14,9 @@ internal class Arrogance : RoleBase public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorKilling; //==================================================================\\ - private static OptionItem DefaultKillCooldown; - private static OptionItem ReduceKillCooldown; - private static OptionItem MinKillCooldown; + public static OptionItem DefaultKillCooldown; + public static OptionItem ReduceKillCooldown; + public static OptionItem MinKillCooldown; public static OptionItem BardChance; private static readonly Dictionary NowCooldown = []; diff --git a/Roles/Impostor/Blackmailer.cs b/Roles/Impostor/Blackmailer.cs index 8c01154f9..67bba3ca5 100644 --- a/Roles/Impostor/Blackmailer.cs +++ b/Roles/Impostor/Blackmailer.cs @@ -17,10 +17,10 @@ internal class Blackmailer : RoleBase public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorSupport; //==================================================================\\ - private static OptionItem SkillCooldown; - private static OptionItem ShowShapeshiftAnimationsOpt; + public static OptionItem SkillCooldown; + public static OptionItem ShowShapeshiftAnimationsOpt; - private static readonly HashSet ForBlackmailer = []; + public static readonly HashSet ForBlackmailer = []; public override void SetupCustomOption() { diff --git a/Roles/Impostor/Bomber.cs b/Roles/Impostor/Bomber.cs index 5a3e0cced..6d82c18ad 100644 --- a/Roles/Impostor/Bomber.cs +++ b/Roles/Impostor/Bomber.cs @@ -9,7 +9,7 @@ internal class Bomber : RoleBase { //===========================SETUP================================\\ private const int Id = 700; - private static readonly HashSet Playerids = []; + public static readonly HashSet Playerids = []; public static bool HasEnabled => Playerids.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Shapeshifter; diff --git a/Roles/Impostor/BountyHunter.cs b/Roles/Impostor/BountyHunter.cs index 522191846..c4534ec5a 100644 --- a/Roles/Impostor/BountyHunter.cs +++ b/Roles/Impostor/BountyHunter.cs @@ -11,24 +11,24 @@ internal class BountyHunter : RoleBase { //===========================SETUP================================\\ private const int Id = 800; - private static readonly HashSet playerIdList = []; + public static readonly HashSet playerIdList = []; public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Shapeshifter; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorKilling; //==================================================================\\ - private static OptionItem OptionTargetChangeTime; - private static OptionItem OptionSuccessKillCooldown; - private static OptionItem OptionFailureKillCooldown; - private static OptionItem OptionShowTargetArrow; + public static OptionItem OptionTargetChangeTime; + public static OptionItem OptionSuccessKillCooldown; + public static OptionItem OptionFailureKillCooldown; + public static OptionItem OptionShowTargetArrow; - private static float TargetChangeTime; - private static float SuccessKillCooldown; - private static float FailureKillCooldown; - private static bool ShowTargetArrow; + public static float TargetChangeTime; + public static float SuccessKillCooldown; + public static float FailureKillCooldown; + public static bool ShowTargetArrow; - private static Dictionary Targets = []; + public static Dictionary Targets = []; public static readonly Dictionary ChangeTimer = []; public override void SetupCustomOption() @@ -97,7 +97,9 @@ public override bool OnCheckShapeshift(PlayerControl shapeshifter, PlayerControl return false; } - public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) +#pragma warning disable CS0114 // Member hides inherited member; missing override keyword + public static bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) +#pragma warning restore CS0114 // Member hides inherited member; missing override keyword { if (GetTarget(killer) == target.PlayerId) { @@ -116,7 +118,9 @@ public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl t return true; } public override void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo target) => ChangeTimer.Clear(); - public override void OnFixedUpdate(PlayerControl player, bool lowLoad, long nowTime) +#pragma warning disable CS0114 // Member hides inherited member; missing override keyword + public static void OnFixedUpdate(PlayerControl player, bool lowLoad, long nowTime) +#pragma warning restore CS0114 // Member hides inherited member; missing override keyword { if (!ChangeTimer.TryGetValue(player.PlayerId, out var timer)) return; @@ -157,7 +161,7 @@ public static PlayerControl GetTargetPC(PlayerControl player) var targetId = GetTarget(player); return targetId == 0xff ? null : Utils.GetPlayerById(targetId); } - private static bool PotentialTarget(PlayerControl player, PlayerControl target) + public static bool PotentialTarget(PlayerControl player, PlayerControl target) { if (target == null || player == null) return false; @@ -193,7 +197,7 @@ private static bool PotentialTarget(PlayerControl player, PlayerControl target) return true; } - private static byte ResetTarget(PlayerControl player) + public static byte ResetTarget(PlayerControl player) { if (!AmongUsClient.Instance.AmHost) return 0xff; @@ -227,7 +231,9 @@ private static byte ResetTarget(PlayerControl player) return targetId; } public override void SetAbilityButtonText(HudManager hud, byte playerId) => hud.AbilityButton.OverrideText(GetString("BountyHunterChangeButtonText")); - public override void AfterMeetingTasks() +#pragma warning disable CS0114 // Member hides inherited member; missing override keyword + public static void AfterMeetingTasks() +#pragma warning restore CS0114 // Member hides inherited member; missing override keyword { foreach (var id in playerIdList.ToArray()) { @@ -238,14 +244,18 @@ public override void AfterMeetingTasks() } } } - public override string GetLowerText(PlayerControl seer, PlayerControl seen = null, bool isForMeeting = false, bool isForHud = false) +#pragma warning disable CS0114 // Member hides inherited member; missing override keyword + public static string GetLowerText(PlayerControl seer, PlayerControl seen = null, bool isForMeeting = false, bool isForHud = false) +#pragma warning restore CS0114 // Member hides inherited member; missing override keyword { if (isForMeeting) return string.Empty; var targetId = GetTarget(seer); return targetId != 0xff ? $"{(isForHud ? GetString("BountyCurrentTarget") : GetString("Target"))}: {Main.AllPlayerNames[targetId].RemoveHtmlTags().Replace("\r\n", string.Empty)}" : string.Empty; } - public override string GetSuffix(PlayerControl seer, PlayerControl seen = null, bool isForMeeting = false) +#pragma warning disable CS0114 // Member hides inherited member; missing override keyword + public static string GetSuffix(PlayerControl seer, PlayerControl seen = null, bool isForMeeting = false) +#pragma warning restore CS0114 // Member hides inherited member; missing override keyword { if (!ShowTargetArrow || isForMeeting || seer.PlayerId != seen.PlayerId) return string.Empty; diff --git a/Roles/Impostor/Butcher.cs b/Roles/Impostor/Butcher.cs index c610e97b2..6866d65e0 100644 --- a/Roles/Impostor/Butcher.cs +++ b/Roles/Impostor/Butcher.cs @@ -9,14 +9,14 @@ internal class Butcher : RoleBase { //===========================SETUP================================\\ private const int Id = 24300; - private static readonly HashSet PlayerIds = []; + public static readonly HashSet PlayerIds = []; public static bool HasEnabled => PlayerIds.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorKilling; //==================================================================\\ - private static Dictionary MurderTargetLateTask = []; + public static Dictionary MurderTargetLateTask = []; public override void SetupCustomOption() { SetupRoleOptions(Id, TabGroup.ImpostorRoles, CustomRoles.Butcher); @@ -38,7 +38,9 @@ public override void Add(byte playerId) public override void SetAbilityButtonText(HudManager hud, byte playerId) => hud.KillButton.OverrideText(Translator.GetString("ButcherButtonText")); - public override void OnMurderPlayerAsKiller(PlayerControl killer, PlayerControl target, bool inMeeting, bool isSuicide) +#pragma warning disable CS0114 // Member hides inherited member; missing override keyword + public static void OnMurderPlayerAsKiller(PlayerControl killer, PlayerControl target, bool inMeeting, bool isSuicide) +#pragma warning restore CS0114 // Member hides inherited member; missing override keyword { if (inMeeting || isSuicide) return; if (target == null) return; diff --git a/Roles/Impostor/Chronomancer.cs b/Roles/Impostor/Chronomancer.cs index a1d221dbe..490f3bd95 100644 --- a/Roles/Impostor/Chronomancer.cs +++ b/Roles/Impostor/Chronomancer.cs @@ -17,26 +17,26 @@ internal class Chronomancer : RoleBase public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorKilling; //==================================================================\\ - private int ChargedTime = 0; + public int ChargedTime = 0; long now = Utils.GetTimeStamp(); - private int FullCharge = 0; - private bool IsInMassacre; + public int FullCharge = 0; + public bool IsInMassacre; public float realcooldown; - private float LastNowF = 0; - private float countnowF = 0; + public float LastNowF = 0; + public float countnowF = 0; - private string LastCD; + public string LastCD; - private static Color32 OrangeColor = new(255, 190, 92, 255); // The lest color - private static Color32 GreenColor = new(0, 128, 0, 255); // The final color + public static Color32 OrangeColor = new(255, 190, 92, 255); // The lest color + public static Color32 GreenColor = new(0, 128, 0, 255); // The final color - private static int Charges; + public static int Charges; - private static OptionItem KillCooldown; - private static OptionItem Dtime; - private static OptionItem ReduceVision; + public static OptionItem KillCooldown; + public static OptionItem Dtime; + public static OptionItem ReduceVision; public override void SetupCustomOption() { diff --git a/Roles/Impostor/Consigliere.cs b/Roles/Impostor/Consigliere.cs index 875ca9c65..e9718b0c8 100644 --- a/Roles/Impostor/Consigliere.cs +++ b/Roles/Impostor/Consigliere.cs @@ -18,7 +18,7 @@ internal class Consigliere : RoleBase private static OptionItem KillCooldown; private static OptionItem DivinationMaxCount; - private static readonly Dictionary DivinationCount = []; + public static readonly Dictionary DivinationCount = []; private static readonly Dictionary> DivinationTarget = []; public override void SetupCustomOption() diff --git a/Roles/Impostor/Crewpostor.cs b/Roles/Impostor/Crewpostor.cs index 2ce6bfc34..58041a34e 100644 --- a/Roles/Impostor/Crewpostor.cs +++ b/Roles/Impostor/Crewpostor.cs @@ -21,7 +21,7 @@ internal class Crewpostor : RoleBase private static OptionItem LungeKill; private static OptionItem KillAfterTask; - private static Dictionary TasksDone = []; + public static Dictionary TasksDone = []; public override void SetupCustomOption() { diff --git a/Roles/Impostor/CursedWolf.cs b/Roles/Impostor/CursedWolf.cs index 5f9f12a5b..7a03fd7f1 100644 --- a/Roles/Impostor/CursedWolf.cs +++ b/Roles/Impostor/CursedWolf.cs @@ -15,6 +15,7 @@ internal class CursedWolf : RoleBase private static OptionItem GuardSpellTimes; private static OptionItem KillAttacker; + public override void SetupCustomOption() { diff --git a/Roles/Impostor/DoubleAgent.cs b/Roles/Impostor/DoubleAgent.cs index 7388bb475..eeef38bf9 100644 --- a/Roles/Impostor/DoubleAgent.cs +++ b/Roles/Impostor/DoubleAgent.cs @@ -326,8 +326,10 @@ public static void CreatePlantBombButton(MeetingHud __instance) targetBox.name = "PlantBombButton"; targetBox.transform.localPosition = new Vector3(-0.35f, 0.03f, -1.31f); createdButtonsList.Add(targetBox); + SpriteRenderer renderer = targetBox.GetComponent(); renderer.sprite = CustomButton.Get("DoubleAgentPocketBomb"); + PassiveButton button = targetBox.GetComponent(); button.OnClick.RemoveAllListeners(); button.OnClick.AddListener((UnityEngine.Events.UnityAction)(() => DestroyButtons(targetBox))); diff --git a/Roles/Impostor/Visionary.cs b/Roles/Impostor/Visionary.cs index b1644b8e4..4a2431639 100644 --- a/Roles/Impostor/Visionary.cs +++ b/Roles/Impostor/Visionary.cs @@ -42,7 +42,10 @@ or CustomRoles.Refugee or CustomRoles.Admired) return Main.roleColors[CustomRoles.Knight]; } - + if (Main.PlayerStates[target.PlayerId].IsRandomizer) + { + return Main.roleColors[CustomRoles.Crewmate]; + } if (customRole.IsImpostorTeamV2() || customRole.IsMadmate()) { return Main.roleColors[CustomRoles.Impostor]; diff --git a/Roles/Neutral/Baker.cs b/Roles/Neutral/Baker.cs index 153a12612..a805941e8 100644 --- a/Roles/Neutral/Baker.cs +++ b/Roles/Neutral/Baker.cs @@ -78,34 +78,21 @@ private static (int, int) BreadedPlayerCount(byte playerId) return (breaded, all); } public static byte CurrentBread() => BreadID; - private static void SendRPC(byte typeId, PlayerControl player, PlayerControl target) + private static void SendRPC(PlayerControl player, PlayerControl target) { - if (!player.IsNonHostModdedClient()) return; MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.SyncRoleSkill, SendOption.Reliable); writer.WriteNetObject(player); - writer.Write(typeId); writer.Write(player.PlayerId); writer.Write(target.PlayerId); AmongUsClient.Instance.FinishRpcImmediately(writer); } public override void ReceiveRPC(MessageReader reader, PlayerControl NaN) { - byte typeId = reader.ReadByte(); byte BakerId = reader.ReadByte(); byte BreadHolderId = reader.ReadByte(); - switch (typeId) - { - case 0: - BreadList[BakerId].Add(BreadHolderId); - break; - case 1: - RevealList[BakerId].Add(BreadHolderId); - break; - case 2: - BarrierList[BakerId].Add(BreadHolderId); - break; - } + BreadList[BakerId].Add(BreadHolderId); + BarrierList[BakerId].Add(BreadHolderId); } public override string GetProgressText(byte playerId, bool comms) => ColorString(GetRoleColor(CustomRoles.Baker).ShadeColor(0.25f), $"({BreadedPlayerCount(playerId).Item1}/{BreadedPlayerCount(playerId).Item2})"); public override bool OthersKnowTargetRoleColor(PlayerControl seer, PlayerControl target) => KnowRoleTarget(seer, target); @@ -227,7 +214,6 @@ public override bool ForcedCheckMurderAsKiller(PlayerControl killer, PlayerContr else { BreadList[killer.PlayerId].Add(target.PlayerId); - SendRPC(0, killer, target); NotifyRoles(SpecifySeer: killer); killer.Notify(GetString("BakerBreaded")); @@ -241,17 +227,16 @@ public override bool ForcedCheckMurderAsKiller(PlayerControl killer, PlayerContr { case 0: // Reveal RevealList[killer.PlayerId].Add(target.PlayerId); - SendRPC(1, killer, target); break; case 1: // Roleblock target.SetKillCooldownV3(999f); break; case 2: // Barrier BarrierList[killer.PlayerId].Add(target.PlayerId); - SendRPC(2, killer, target); break; } } + SendRPC(killer, target); } return false; } diff --git a/Roles/Neutral/LingeringPresence.cs b/Roles/Neutral/LingeringPresence.cs new file mode 100644 index 000000000..0ab6b8c28 --- /dev/null +++ b/Roles/Neutral/LingeringPresence.cs @@ -0,0 +1,718 @@ +using Hazel; +using Il2CppInterop.Runtime.InteropTypes.Arrays; +using InnerNet; +using System; +using TOHE.Roles.Core; +using UnityEngine; +using UnityEngine.Playables; +using static TOHE.Options; + + +namespace TOHE.Roles.Neutral +{ + internal class LingeringPresence : RoleBase + { + //===========================SETUP================================\\ + private const int Id = 63500; + public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.LingeringPresence); + + public override bool IsExperimental => true; + public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; + public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralBenign; + //==================================================================\\ + + private static OptionItem SoulDrainRange; + private static OptionItem SoulDrainSpeed; + private static OptionItem TaskRechargeAmount; + private static OptionItem KillRechargeAmount; + private static OptionItem WinConditionOption; + public static OptionItem LingeringPresenceShortTasks; + public static OptionItem LingeringPresenceLongTasks; + + + private static CustomWinner SelectedWinCondition; + + private static readonly Dictionary SoulMeters = new(); + private static readonly Dictionary LastUpdateTimes = new(); + private static readonly Dictionary TeamDescriptions = new() +{ + { 0, "Crewmates" }, + { 1, "Neutral" }, + { 2, "Imposter" }, + { 3, "Random" } +}; + + // Method to retrieve the descriptive name + public static string GetWinConditionDescription(int optionValue) + { + return TeamDescriptions.TryGetValue(optionValue, out var description) ? description : "Unknown"; + } +#pragma warning disable IDE0052 // Remove unread private members + private static bool taskResetPatched = false; +#pragma warning restore IDE0052 // Remove unread private members +#pragma warning disable IDE0052 // Remove unread private members + private static string deathReasonMessage = string.Empty; +#pragma warning restore IDE0052 // Remove unread private members + private static bool patched = false; + private static OptionItem SoulDrainTickRate; +#pragma warning disable IDE0052 // Remove unread private members + private static bool IsReviving = false; +#pragma warning restore IDE0052 // Remove unread private members + private byte lingeringPlayerId; + private Dictionary TimeSinceLastTick = new(); + + public override bool HasTasks(NetworkedPlayerInfo player, CustomRoles role, bool ForRecompute) => !ForRecompute; + + public override void SetupCustomOption() + { + SetupRoleOptions(Id, TabGroup.NeutralRoles, CustomRoles.LingeringPresence); + + SoulDrainRange = FloatOptionItem.Create(Id + 10, "SoulDrainRange", new(1f, 10f, 0.5f), 5f, TabGroup.NeutralRoles, false) + .SetParent(CustomRoleSpawnChances[CustomRoles.LingeringPresence]) + .SetValueFormat(OptionFormat.Multiplier); + SoulDrainSpeed = FloatOptionItem.Create(Id + 11, "SoulDrainSpeed", new(1f, 10f, 0.5f), 2f, TabGroup.NeutralRoles, false) + .SetParent(CustomRoleSpawnChances[CustomRoles.LingeringPresence]) + .SetValueFormat(OptionFormat.Seconds); + TaskRechargeAmount = FloatOptionItem.Create(Id + 12, "TaskRechargeAmount", new(1f, 100f, 1f), 25f, TabGroup.NeutralRoles, false) + .SetParent(CustomRoleSpawnChances[CustomRoles.LingeringPresence]) + .SetValueFormat(OptionFormat.Health); + KillRechargeAmount = FloatOptionItem.Create(Id + 13, "KillRechargeAmount", new(1f, 100f, 1f), 50f, TabGroup.NeutralRoles, false) + .SetParent(CustomRoleSpawnChances[CustomRoles.LingeringPresence]) + .SetValueFormat(OptionFormat.Health); + WinConditionOption = StringOptionItem.Create(Id + 20, "Lingering Presence Win Condition", new[] { "Crewmates", "Neutral", "Impostor", "Random" }, 0, TabGroup.NeutralRoles, false) + .SetParent(CustomRoleSpawnChances[CustomRoles.LingeringPresence]); + + + SoulDrainTickRate = FloatOptionItem.Create(Id + 14, "SoulDrainTickRate", new(0.1f, 5f, 0.1f), 1f, TabGroup.NeutralRoles, false) + .SetParent(CustomRoleSpawnChances[CustomRoles.LingeringPresence]) + .SetValueFormat(OptionFormat.Seconds); + OverrideTasksData.Create(Id + 15, TabGroup.NeutralRoles, CustomRoles.LingeringPresence); + + + } + public override void Init() + { + + SoulMeters.Clear(); + LastUpdateTimes.Clear(); + IsReviving = false; + lingeringPlayerId = byte.MaxValue; + taskResetPatched = false; + deathReasonMessage = string.Empty; + SelectedWinCondition = (CustomWinner)WinConditionOption.GetInt(); + if (SelectedWinCondition == CustomWinner.Random) + { + SelectedWinCondition = AssignRandomTeam(); + Logger.Info($"Lingering Presence assigned random team: {SelectedWinCondition}", "LingeringPresence"); + } + + + foreach (var player in PlayerControl.AllPlayerControls) + { + if (player.Is(CustomRoles.LingeringPresence)) + { + KillLingeringPresence(player, player); + } + } + } + + +#pragma warning disable IDE0044 // Add readonly modifier + private Custom_RoleType selectedTeam; +#pragma warning restore IDE0044 // Add readonly modifier + + + public enum TeamOption + { + Crewmates = 0, + Neutral = 1, + Imposter = 2, + Random = 3 + } + private CustomWinner AssignRandomTeam() + { + CustomWinner[] possibleTeams = { CustomWinner.Crewmate, CustomWinner.Impostor, CustomWinner.Neutrals }; + var selectedTeam = possibleTeams[UnityEngine.Random.Range(0, possibleTeams.Length)]; + Logger.Info($"[LingeringPresence] Random team assigned: {selectedTeam}"); + return selectedTeam; + } + + + + + + + + + public static void LingeringPresenceWinCondition(PlayerControl player) + { + var playerState = Main.PlayerStates[player.PlayerId]; + if (!playerState.IsLingeringPresence) + { + Logger.Warn($"[LingeringPresence] {player.GetNameWithRole()} is not Lingering Presence. Skipping win condition check."); + return; + } + + var winCondition = (CustomWinner)WinConditionOption.GetInt(); + + switch (winCondition) + { + case CustomWinner.Crewmate: + if (CustomWinnerHolder.WinnerTeam == CustomWinner.Crewmate) + { + CustomWinnerHolder.WinnerIds.Add(player.PlayerId); + Logger.Info($"[LingeringPresence] {player.GetNameWithRole()} wins with the Crewmate team."); + } + break; + + case CustomWinner.Impostor: + if (CustomWinnerHolder.WinnerTeam == CustomWinner.Impostor) + { + CustomWinnerHolder.WinnerIds.Add(player.PlayerId); + Logger.Info($"[LingeringPresence] {player.GetNameWithRole()} wins with the Impostor team."); + } + break; + + case CustomWinner.Neutrals: + if (IsWinningWithNeutral(player)) + { + CustomWinnerHolder.WinnerIds.Add(player.PlayerId); + Logger.Info($"[LingeringPresence] {player.GetNameWithRole()} wins with the Neutral team."); + } + else + { + Logger.Warn($"[LingeringPresence] {player.GetNameWithRole()} does not meet Neutral win condition."); + } + break; + + + default: + Logger.Warn($"[LingeringPresence] {player.GetNameWithRole()} does not meet any win condition."); + break; + } + } + + + + + + + + public static void OnMeetingCalled() + { + foreach (var player in PlayerControl.AllPlayerControls) + { + if (player.Is(CustomRoles.LingeringPresence) && player.IsAlive()) + { + // Trigger Lingering Presence's custom death mechanics during meetings + if (KillLingeringPresence(PlayerControl.LocalPlayer, player)) + { + // Schedule ResetTasks to be called shortly after death handling completes + new LateTask(() => LingeringPresence.Instance?.ResetTasks(player), 0.5f, "LingeringPresence ResetTasks After Death"); + } + } + } + } + + + + + public override void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo bodyInfo) + { + foreach (var player in PlayerControl.AllPlayerControls) + { + if (player.Is(CustomRoles.LingeringPresence) && player.IsAlive()) + { + // Trigger Lingering Presence's custom death mechanics when a body is reported + KillLingeringPresence(PlayerControl.LocalPlayer, player); + } + } + } + + + public override bool OnCheckMurderAsTarget(PlayerControl killer, PlayerControl target) + { + if (target.Is(CustomRoles.LingeringPresence)) + { + // Ignore protection checks for Lingering Presence + return KillLingeringPresence(killer, target); + } + + return true; // For other roles, proceed with default behavior + } + + + public static bool KillLingeringPresence(PlayerControl killer, PlayerControl target) + { + try + { + if (killer == null || target == null || !target.IsAlive()) return false; + + // Set custom death properties specific to Lingering Presence + target.SetDeathReason(PlayerState.DeathReason.FadedAway); // Customize death reason + target.RpcExileV2(); // Exile without leaving a body + + if (Main.PlayerStates.ContainsKey(target.PlayerId)) + { + Main.PlayerStates[target.PlayerId].SetDead(); + } + + target.Data.IsDead = true; + target.SetRealKiller(killer); + killer.ResetKillCooldown(); + + Logger.Info($"{target.GetNameWithRole()} was killed by {killer?.GetNameWithRole()} due to Lingering Presence mechanics (no body)", "LingeringPresence"); + + // Successfully handled death; return true + return true; + } + catch (Exception ex) + { + Logger.Error($"Error in KillLingeringPresence: {ex.Message}", "LingeringPresence"); + } + + return false; + } + + + + public static void SyncRoleSkillReader(MessageReader reader) + { + try + { + var pc = reader.ReadNetObject(); + + if (pc != null) + { + // Read task-related data directly + pc.GetRoleClass()?.ReceiveRPC(reader, pc); + } + } + catch (Exception error) + { + Logger.Error($"Error in SyncRoleSkillReader RPC: {error}", "SyncRoleSkillReader"); + } + } + + + + + + + + + private string GetWinConditionMessage(CustomWinner winCondition) + { + switch (winCondition) + { + case CustomWinner.Crewmate: return "You win with the Crewmates!"; + case CustomWinner.Impostor: return "You win with the Impostors!"; + case CustomWinner.Neutrals: return "You win with Neutral roles!"; + default: return "Your team will be randomly assigned!"; + } + } + + public override void Add(byte playerId) + { + // Notify Lingering Presence of their team at game start + string teamMessage = GetWinConditionMessage((CustomWinner)WinConditionOption.GetInt()); + Utils.SendMessage(teamMessage, playerId); + + PlayerControl player = null; + + // Locate the PlayerControl object for the given playerId + foreach (var pc in PlayerControl.AllPlayerControls) + { + if (pc.PlayerId == playerId) + { + player = pc; + break; + } + } + + if (player == null) + { + Logger.Error($"Player with ID {playerId} not found for Lingering Presence role.", "LingeringPresence"); + return; + } + + + + // Initialize soul meters for other players + foreach (var pc in PlayerControl.AllPlayerControls) + { + if (!pc.Is(CustomRoles.LingeringPresence)) + { + SoulMeters[pc.PlayerId] = 100f; + } + + + // Reset camera list if necessary + if (!Main.ResetCamPlayerList.Contains(playerId)) + { + Main.ResetCamPlayerList.Add(playerId); + } + + // Only apply OnFixedUpdate for the host + if (AmongUsClient.Instance.AmHost) + { + CustomRoleManager.OnFixedUpdateOthers.Add(OnFixedUpdate); + } + } + } + + + public override bool OnTaskComplete(PlayerControl player, int completedTaskCount, int totalTaskCount) + { + if (player == null) + + // Sync task data for modded clients + SendRPC(); + + if (patched) + { + ResetTasks(player); + patched = false; // Reset patched to prevent repeated task resets + } + // Check if tasks are complete + var taskState = player.GetPlayerTaskState(); + if (taskState.IsTaskFinished && player.Data.IsDead) + { + Logger.Info("Revival conditions met. Attempting to revive Lingering Presence.", "LingeringPresence"); + ReviveLingeringPresence(player); + new LateTask(() => ResetTasks(player), 0.5f, "LingeringPresence ResetTasks"); + + } + + return true; + } + + + + + // Sync task status across clients + private void SendRPC() + { + MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.SyncRoleSkill, SendOption.Reliable, -1); + var player = Utils.GetPlayerById(lingeringPlayerId); + var taskState = player?.GetPlayerTaskState(); + writer.WriteNetObject(player); + writer.Write(taskState?.AllTasksCount ?? 0); + writer.Write(taskState?.CompletedTasksCount ?? 0); + writer.Write(lingeringPlayerId); + + AmongUsClient.Instance.FinishRpcImmediately(writer); + } + + + + + + public override void ReceiveRPC(MessageReader reader, PlayerControl pc) + { + int allTasksCount = reader.ReadInt32(); + int completedTasksCount = reader.ReadInt32(); + byte playerId = reader.ReadByte(); + + var taskState = Utils.GetPlayerById(playerId)?.GetPlayerTaskState(); + if (taskState != null) + { + taskState.AllTasksCount = allTasksCount; + taskState.CompletedTasksCount = completedTasksCount; + } + + Logger.Info($"Lingering Presence tasks synced for player {playerId}: {completedTasksCount}/{allTasksCount} completed.", "LingeringPresence"); + } + + + + + + + + private static void ReviveLingeringPresence(PlayerControl player) + { + if (!player.Data.IsDead) return; + + IsReviving = true; + + // Teleport the player to the spawn position + Vector3 spawnPosition = new Vector3(0, 0, 0); + player.RpcTeleport(spawnPosition); + + // Set the player's role back to LingeringPresence and revive + player.RpcSetRole((AmongUs.GameOptions.RoleTypes)CustomRoles.LingeringPresence); + player.RpcRevive(); + + Logger.Info($"{player.GetNameWithRole()} has been revived at spawn.", "LingeringPresence"); + + + + IsReviving = false; + } + + + + + + public static LingeringPresence Instance { get; private set; } + + public LingeringPresence() + { + Instance = this; + } + private void SetShortTasksToAdd() + { + + } + + // Reset tasks for LingeringPresence upon revival + public void ResetTasks(PlayerControl player) + { + // Ensure additional task-related variables are reset, even if no extra tasks are added + SetShortTasksToAdd(); // Placeholder for consistency; adjust as needed + + var taskState = player.GetPlayerTaskState(); + player.Data.RpcSetTasks(new Il2CppStructArray(0)); // Clear task list to allow reassignment + taskState.CompletedTasksCount = 0; + + // Call necessary functions for resetting visuals and states + player.RpcGuardAndKill(); + player.Notify("Your tasks have been reset!"); + + Logger.Info($"{player.GetRealName()}'s tasks reset.", "LingeringPresence"); + + // Remove any visual indicators + Main.AllPlayerControls.Do(x => TargetArrow.Remove(x.PlayerId, player.PlayerId)); + + // Reset any flags or variables that track state for task warnings or notifications + + + // Sync updated task state across clients, especially for the host + SendRPC(); + } + + + + + + + + + + + private void OnFixedUpdate(PlayerControl player, bool lowLoad, long nowTime) + + { + if (!player.Is(CustomRoles.LingeringPresence) || player.Data.IsDead) return; + + foreach (var target in PlayerControl.AllPlayerControls) + { + if (player.PlayerId == target.PlayerId || target.Data.IsDead) continue; + + var distance = Vector3.Distance(player.transform.position, target.transform.position); + + if (distance <= SoulDrainRange.GetFloat()) + { + DrainSoul(player, target); + } + else + { + ResetSoulDamage(target.PlayerId); + } + } + } + + + + + + private void DrainSoul(PlayerControl presence, PlayerControl target) + { + var currentTime = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); + + if (!LastUpdateTimes.TryGetValue(target.PlayerId, out var lastUpdateTime)) + { + lastUpdateTime = currentTime; + } + + var deltaTime = currentTime - lastUpdateTime; + var drainAmount = SoulDrainSpeed.GetFloat() * deltaTime; + + SoulMeters[target.PlayerId] = Mathf.Clamp(SoulMeters[target.PlayerId] - drainAmount, 0f, 100f); + + ApplyFadingLight(target); + + if (SoulMeters[target.PlayerId] <= 0) + { + target.SetDeathReason(PlayerState.DeathReason.FadedAway); + target.RpcMurderPlayer(target); + } + + LastUpdateTimes[target.PlayerId] = currentTime; + } + + private void ApplyFadingLight(PlayerControl target) + { + Logger.Info($"Updating FadingLight to {target.GetNameWithRole().RemoveHtmlTags()}", "Lingering Presence"); + + target.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.FadingLight), $"Your soul is at {Mathf.RoundToInt(SoulMeters[target.PlayerId])}%")); + target.RpcSetCustomRole(CustomRoles.FadingLight); + } + + private void ResetSoulDamage(byte playerId) + { + LastUpdateTimes.Remove(playerId); + } + + + + public override string GetMarkOthers(PlayerControl seer, PlayerControl target = null, bool isForMeeting = false) + { + if (!seer.Is(CustomRoles.LingeringPresence)) return string.Empty; + + target ??= seer; + + if (SoulMeters.TryGetValue(target.PlayerId, out var soulMeter)) + { + return Utils.ColorString(Color.white, $"Soul: {Mathf.RoundToInt(soulMeter)}%"); + } + + return string.Empty; + } + public override void AfterMeetingTasks() + { + foreach (var player in PlayerControl.AllPlayerControls) + { + if (player.Is(CustomRoles.LingeringPresence) && player.IsAlive()) + { + // Delay the reset to give time for the meeting phase to end completely + new LateTask(() => ResetTasks(player), 0.5f, "LingeringPresence ResetTasks After Meeting"); + } + } + } + + public static void OnOthersTaskComplete(PlayerControl player) + { + // Check if the player has the Fading Light add-on + if (player.HasSpecificSubRole(CustomRoles.FadingLight)) + { + // Get the host-set task recharge amount + float rechargeAmount = TaskRechargeAmount.GetFloat(); + + // Increase soul level and clamp it to a maximum of 100% + SoulMeters[player.PlayerId] = Mathf.Clamp(SoulMeters[player.PlayerId] + rechargeAmount, 0f, 100f); + + // Optionally notify the player of their updated soul level + player.Notify($"Completing a task has increased your soul to {Mathf.RoundToInt(SoulMeters[player.PlayerId])}%."); + } + } + public override bool CheckMurderOnOthersTarget(PlayerControl killer, PlayerControl target) + { + if (killer.HasSpecificSubRole(CustomRoles.FadingLight)) + { + // Retrieve the host-set kill recharge amount + float rechargeAmount = KillRechargeAmount.GetFloat(); + + // Increase the soul level for the killer, capping it at 100% + SoulMeters[killer.PlayerId] = Mathf.Clamp(SoulMeters[killer.PlayerId] + rechargeAmount, 0f, 100f); + + // Optionally notify the killer of their updated soul level + killer.Notify($"Killing a player has increased your soul to {Mathf.RoundToInt(SoulMeters[killer.PlayerId])}%."); + } + + // Proceed with the usual behavior for CheckMurderOnOthersTarget + return base.CheckMurderOnOthersTarget(killer, target); + } + + + + + + + + + + + public override void Remove(byte playerId) + { + SoulMeters.Remove(playerId); + LastUpdateTimes.Remove(playerId); + CustomRoleManager.OnFixedUpdateOthers.Remove(OnFixedUpdate); + } + + + + private static bool IsWinningWithNeutral(PlayerControl player) + { + // Define viable Neutral roles + var viableNeutralRoles = new[] + { + CustomRoles.Agitater, + CustomRoles.Arsonist, + CustomRoles.Baker, + CustomRoles.Bandit, + CustomRoles.Berserker, + CustomRoles. BloodKnight, + CustomRoles.Collector, + CustomRoles.Cultist, + CustomRoles.CursedSoul, + CustomRoles.Death, + CustomRoles.Demon, + CustomRoles.Doomsayer, + CustomRoles.Doppelganger, + CustomRoles.Executioner, + CustomRoles.Famine, + CustomRoles.Glitch, + CustomRoles.God, + CustomRoles.HexMaster, + CustomRoles.Huntsman, + CustomRoles.Infectious, + CustomRoles.Innocent, + CustomRoles.Jackal, + CustomRoles.Jester, + CustomRoles.Jinx, + CustomRoles.Juggernaut, + CustomRoles.Medusa, + CustomRoles.Necromancer, + CustomRoles.Pelican, + CustomRoles.Pestilence, + CustomRoles.Pickpocket, + CustomRoles.Pirate, + CustomRoles.PlagueBearer, + CustomRoles.PlagueDoctor, + CustomRoles.Poisoner, + CustomRoles.PotionMaster, + CustomRoles.Provocateur, + CustomRoles.PunchingBag, + CustomRoles.Pyromaniac, + CustomRoles.Quizmaster, + CustomRoles.Revolutionist, + CustomRoles.RuthlessRomantic, + CustomRoles.Seeker, + CustomRoles.SerialKiller, + CustomRoles.Shroud, + CustomRoles.Sidekick, + CustomRoles.Solsticer, + CustomRoles.SoulCollector, + CustomRoles.Spiritcaller, + CustomRoles.Stalker, + CustomRoles.Terrorist, + CustomRoles.Traitor, + CustomRoles.Troller, + CustomRoles.Vector, + CustomRoles.VengefulRomantic, + CustomRoles.Virus, + CustomRoles.Vulture, + CustomRoles.War, + CustomRoles.Werewolf, + CustomRoles.Workaholic, + CustomRoles.Wraith, + }; + + // Check if the winning team is Neutral and contains a viable role + return CustomWinnerHolder.WinnerTeam == CustomWinner.Neutrals && + CustomWinnerHolder.WinnerRoles.Any(role => viableNeutralRoles.Contains(role)); + } + } +} \ No newline at end of file diff --git a/Roles/Neutral/Quizmaster.cs b/Roles/Neutral/Quizmaster.cs index ee7129bb5..5e8dbac1f 100644 --- a/Roles/Neutral/Quizmaster.cs +++ b/Roles/Neutral/Quizmaster.cs @@ -226,35 +226,38 @@ private void DoQuestion() Player = _Player; if (MarkedPlayer != byte.MaxValue) { + // Get random roles CustomRoles randomRole = GetRandomRole([.. CustomRolesHelper.AllRoles], false); CustomRoles randomRoleWithAddon = GetRandomRole([.. CustomRolesHelper.AllRoles], false); List Questions = [ new SabotageQuestion { Stage = 1, Question = "LastSabotage",/* JSON ENTRIES */ QuizmasterQuestionType = QuizmasterQuestionType.LatestSabotageQuestion }, - new SabotageQuestion { Stage = 1, Question = "FirstRoundSabotage", QuizmasterQuestionType = QuizmasterQuestionType.FirstRoundSabotageQuestion }, - new PlrColorQuestion { Stage = 1, Question = "LastEjectedPlayerColor", QuizmasterQuestionType = QuizmasterQuestionType.EjectionColorQuestion }, - new PlrColorQuestion { Stage = 1, Question = "LastReportPlayerColor", QuizmasterQuestionType = QuizmasterQuestionType.ReportColorQuestion }, - new PlrColorQuestion { Stage = 1, Question = "LastButtonPressedPlayerColor", QuizmasterQuestionType = QuizmasterQuestionType.LastMeetingColorQuestion }, + new SabotageQuestion { Stage = 1, Question = "FirstRoundSabotage", QuizmasterQuestionType = QuizmasterQuestionType.FirstRoundSabotageQuestion }, + new PlrColorQuestion { Stage = 1, Question = "LastEjectedPlayerColor", QuizmasterQuestionType = QuizmasterQuestionType.EjectionColorQuestion }, + new PlrColorQuestion { Stage = 1, Question = "LastReportPlayerColor", QuizmasterQuestionType = QuizmasterQuestionType.ReportColorQuestion }, + new PlrColorQuestion { Stage = 1, Question = "LastButtonPressedPlayerColor", QuizmasterQuestionType = QuizmasterQuestionType.LastMeetingColorQuestion }, - new CountQuestion { Stage = 2, Question = "MeetingPassed", QuizmasterQuestionType = QuizmasterQuestionType.MeetingCountQuestion }, + new CountQuestion { Stage = 2, Question = "MeetingPassed", QuizmasterQuestionType = QuizmasterQuestionType.MeetingCountQuestion }, new SetAnswersQuestion { Stage = 2, Question = "HowManyFactions", Answer = "Three", PossibleAnswers = { "One", "Two", "Three", "Four", "Five" }, QuizmasterQuestionType = QuizmasterQuestionType.FactionQuestion }, new SetAnswersQuestion { Stage = 2, Question = GetString("QuizmasterQuestions.BasisOfRole").Replace("{QMROLE}", randomRoleWithAddon.ToString()), HasQuestionTranslation = false, Answer = CustomRolesHelper.GetCustomRoleTeam(randomRoleWithAddon).ToString(), PossibleAnswers = { "Crewmate", "Impostor", "Neutral", "Addon" }, QuizmasterQuestionType = QuizmasterQuestionType.RoleBasisQuestion }, new SetAnswersQuestion { Stage = 2, Question = GetString("QuizmasterQuestions.FactionOfRole").Replace("{QMROLE}", randomRole.ToString()), HasQuestionTranslation = false, Answer = CustomRolesHelper.GetRoleTypes(randomRole).ToString(), PossibleAnswers = { "Crewmate", "Impostor", "Neutral" }, QuizmasterQuestionType = QuizmasterQuestionType.RoleFactionQuestion }, - new SetAnswersQuestion { Stage = 3, Question = "FactionRemovedName", Answer = "Coven", PossibleAnswers = { "Sabotuer", "Sorcerers", "Coven", "Killer" }, QuizmasterQuestionType = QuizmasterQuestionType.RemovedFactionQuestion }, - new SetAnswersQuestion { Stage = 3, Question = "WhatDoesEOgMeansInName", Answer = "Edited", PossibleAnswers = { "Edition", "Experimental", "Enhanced", "Edited" }, QuizmasterQuestionType = QuizmasterQuestionType.NameOriginQuestion }, - new CountQuestion { Stage = 3, Question = "HowManyDiedFirstRound", QuizmasterQuestionType = QuizmasterQuestionType.DiedFirstRoundCountQuestion }, - new CountQuestion { Stage = 3, Question = "ButtonPressedBefore", QuizmasterQuestionType = QuizmasterQuestionType.ButtonPressedBeforeThisQuestion }, + new SetAnswersQuestion { Stage = 3, Question = "FactionRemovedName", Answer = "Coven", PossibleAnswers = { "Sabotuer", "Sorcerers", "Coven", "Killer" }, QuizmasterQuestionType = QuizmasterQuestionType.RemovedFactionQuestion }, + new SetAnswersQuestion { Stage = 3, Question = "WhatDoesEOgMeansInName", Answer = "Edited", PossibleAnswers = { "Edition", "Experimental", "Enhanced", "Edited" }, QuizmasterQuestionType = QuizmasterQuestionType.NameOriginQuestion }, + new CountQuestion { Stage = 3, Question = "HowManyDiedFirstRound", QuizmasterQuestionType = QuizmasterQuestionType.DiedFirstRoundCountQuestion }, + new CountQuestion { Stage = 3, Question = "ButtonPressedBefore", QuizmasterQuestionType = QuizmasterQuestionType.ButtonPressedBeforeThisQuestion }, new DeathReasonQuestion { Stage = 4, Question = "PlrDieReason", QuizmasterQuestionType = QuizmasterQuestionType.PlrDeathReasonQuestion}, new DeathReasonQuestion { Stage = 4, Question = "PlrDieMethod", QuizmasterQuestionType = QuizmasterQuestionType.PlrDeathMethodQuestion}, - new SetAnswersQuestion { Stage = 4, Question = "LastAddedRoleForKarped", Answer = "Pacifist", PossibleAnswers = { "Pacifist", "Vampire", "Snitch", "Vigilante", "Jackal", "Mole", "Sniper" }, QuizmasterQuestionType = QuizmasterQuestionType.RoleAddedQuestion }, + new SetAnswersQuestion { Stage = 4, Question = "LastAddedRoleForKarped", Answer = "Pacifist", PossibleAnswers = { "Pacifist", "Vampire", "Snitch", "Vigilante", "Jackal", "Mole", "Sniper" }, QuizmasterQuestionType = QuizmasterQuestionType.RoleAddedQuestion }, new DeathReasonQuestion { Stage = 4, Question = "PlrDieFaction", QuizmasterQuestionType = QuizmasterQuestionType.PlrDeathKillerFactionQuestion}, ]; - + + // Randomize the question Question = GetRandomQuestion(Questions); } } + public override void OnMeetingHudStart(PlayerControl pc) { if (Player == null) return; diff --git a/Roles/Neutral/Traitor.cs b/Roles/Neutral/Traitor.cs index 22a14605d..a2b6a0b35 100644 --- a/Roles/Neutral/Traitor.cs +++ b/Roles/Neutral/Traitor.cs @@ -54,6 +54,7 @@ public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl t public override string PlayerKnowTargetColor(PlayerControl seer, PlayerControl target) { + if (Main.PlayerStates[seer.PlayerId].IsRandomizer || Main.PlayerStates[target.PlayerId].IsRandomizer) return string.Empty; if (target.Is(Custom_Team.Impostor)) { return Main.roleColors[CustomRoles.Impostor]; diff --git a/Roles/Neutral/evolver.cs b/Roles/Neutral/evolver.cs new file mode 100644 index 000000000..75cdae049 --- /dev/null +++ b/Roles/Neutral/evolver.cs @@ -0,0 +1,721 @@ +using Hazel; +using InnerNet; +using System.Text.RegularExpressions; +using static TOHE.Options; +using static TOHE.Translator; +using TOHE.Roles.Core; +using UnityEngine; +using System; + +namespace TOHE.Roles.Neutral +{ + internal class Evolver : RoleBase + { + //===========================SETUP================================\\ + private const int Id = 64000; + public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Evolver); + public override bool IsExperimental => true; + public override CustomRoles ThisRoleBase => CustomRoles.Impostor; + public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralBenign; + //==================================================================\\ + + + public static OptionItem MinEvolutionsForWin; + private static readonly Dictionary PurchaseDone = new(); + + private static readonly Dictionary evolverCache = new(); + private static int evolverPoints = 0; + private int purchasedUpgrades = 0; + private bool hasNewMegaPoint = false; + private float catchCooldown = 0.0f; + public int EvolverPoints = new(); + private int voteLevel = 0; + private static PlayerControl evolverPlayer; + private int cooldownLevel = 0; + private int voteUpgradeLevel = 0; // Starting level + private int megaPoints = 0; + private static int requiredPoints; + private float baseCatchChance = 0.5f; // 50% base chance + private bool isImmortalityActive = false; + private const float MEGA_POINT_CHANCE = 0.05f; + private const float IMMORTALITY_CATCH_CHANCE_DEBUFF = 0.5f; + private const float IMMORTALITY_CATCH_COOLDOWN_MULTIPLIER = 1.5f; + private float baseCatchCooldown = 20f; + private int basePointsPerCatch = 1; // 1 point per successful catch + private readonly int maxVoteLevel = 4; // Upgrade level variables for Evolver's perks + private int catchChanceLevel = 0; // Tracks the level of the catch chance upgrade + private int cooldownReductionLevel = 0; // Tracks the level of the cooldown reduction upgrade + private int pointsOnCatchLevel = 0; // Tracks the level of points gained per catch + private readonly int[] catchChanceUpgradeCosts = { 2, 4, 6, 9, 12 }; + private readonly int[] pointsOnCatchUpgradeCosts = { 3, 6, 10, 20 }; + private readonly int[] cooldownReductionUpgradeCosts = { 1, 5, 9, 14 }; + private readonly int[] voteUpgradeCosts = { 4, 9, 12, 17 }; + + + + + // These methods retrieve modified values based on upgrades + private float GetCatchChance() + { + float catchChanceIncrease = catchChanceLevel * 0.1f; + float cooldownReductionPenalty = cooldownReductionLevel * 0.05f; + + // Apply immortality catch chance debuff if active + float adjustedCatchChance = baseCatchChance + catchChanceIncrease - cooldownReductionPenalty; + if (isImmortalityActive) + { + adjustedCatchChance *= IMMORTALITY_CATCH_CHANCE_DEBUFF; + } + + return Mathf.Clamp(adjustedCatchChance, 0.1f, 1f); // Clamps the value between 0.1 and 1 + } + public void AddEvolutionPoint() + { + EvolverPoints++; + Logger.Info($"Evolver Points Updated: {EvolverPoints}", "Evolver"); + } + public override string GetProgressText(byte playerId, bool comms) + { + int minUpgrades = MinEvolutionsForWin.GetInt(); + if (minUpgrades == 0) return string.Empty; + + if (Main.PlayerStates[playerId].RoleClass is not Evolver ev) return string.Empty; + int upgrades = ev.purchasedUpgrades; + Color color = upgrades >= minUpgrades ? Color.green : Color.red; + return Utils.ColorString(color, $"({upgrades}/{minUpgrades})"); + + } + public int GetPurchasedUpgrades() // Public method to access the value + { + return purchasedUpgrades; + } + + private float GetCooldownReduction() + { + float baseCooldown = 25f; // 25 seconds base cooldown + float cooldownReductionPerLevel = 2f; // 2 seconds per level + return baseCooldown - (cooldownReductionLevel * cooldownReductionPerLevel); + } + + private int GetPointsPerCatch() + { + return basePointsPerCatch + pointsOnCatchLevel; + } + private float GetCatchCooldown() + { + float cooldownIncrease = catchChanceLevel * 5f; + float cooldownReduction = cooldownReductionLevel * 10f; + + // Apply immortality cooldown multiplier if active + float adjustedCooldown = baseCatchCooldown + cooldownIncrease - cooldownReduction; + if (isImmortalityActive) + { + adjustedCooldown *= IMMORTALITY_CATCH_COOLDOWN_MULTIPLIER; + } + + return Mathf.Max(adjustedCooldown, 5f); // Ensures a minimum cooldown of 5 seconds + } + public void UpgradeCooldownReduction() + { + cooldownReductionLevel++; + // Notify the player of the new cooldown only when they purchase an upgrade + Utils.SendMessage("Cooldown reduction upgraded! New cooldown: {GetCatchCooldown():F1} seconds", PlayerControl.LocalPlayer.PlayerId); + + + + + } + public int GetEvolverPoints() + { + return evolverPoints; + } + public static void Reset() + { + evolverCache.Clear(); + foreach (var pc in Main.AllPlayerControls) + { + if (pc.GetCustomRole() == CustomRoles.Evolver) + { + var points = Evolver.evolverPoints; + } + } + } + + + // Options for evolver role + public override void SetupCustomOption() + { + SetupSingleRoleOptions(Id, TabGroup.NeutralRoles, CustomRoles.Evolver, 1, zeroOne: false); + + // Minimum upgrades required to win + MinEvolutionsForWin = IntegerOptionItem.Create(Id + 10, "Evolver_MinUpgradesToWin", new(0, 15, 1), 3, + TabGroup.NeutralRoles, false) + .SetParent(CustomRoleSpawnChances[CustomRoles.Evolver]); + + } + + + + + public override bool CanUseKillButton(PlayerControl pc) => true; + + public override void SetKillCooldown(byte id) + { + Main.AllPlayerKillCooldown[id] = GetCatchCooldown(); // Sets the Evolver's cooldown using their current upgraded cooldown + } + + + + public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) + { + + + // Run the catch attempt if the target is valid + if (target != _Player) + { + + SendSkillRPC(); // Sync ability usage if necessary + + AttemptCatch(killer, target); // Run the catch mechanic + + killer.SetKillCooldown(); // Resets the cooldown for the Evolver (the one who used the ability) + + return false; // Prevent the actual kill + + } + + killer.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Evolver), GetString("EvolverInvalidTarget"))); + return false; // Always return false to block unintended kills + } + + + public override void SetAbilityButtonText(HudManager hud, byte id) + { + hud.KillButton.OverrideText(GetString("EvolverCatchText")); + } + + public override void Init() + { + + + if (MinEvolutionsForWin == null) + { + Logger.Error("MinEvolutionsForWin is not initialized.", "Evolver"); + return; // Prevent further initialization to avoid crashing. + } + PurchaseDone.Clear(); + evolverPoints = 0; + + + } + + public override void Add(byte playerId) + { + PurchaseDone[playerId] = false; + + } + + + //===========================COMMANDS==============================\\ + public static bool EvolverCheckMsg(PlayerControl pc, string msg, bool isUI = false, bool isSystemMessage = false) + { + if (isSystemMessage || !AmongUsClient.Instance.AmHost) return false; // Skip if system message or not host + + // Skip messages tagged as "" to prevent reprocessing + if (msg.StartsWith("")) return false; + + var originMsg = msg; + Logger.Info($"Received command: {msg} from {pc.PlayerId}, Host: {AmongUsClient.Instance.AmHost}", "Evolver"); + + if (!GameStates.IsMeeting || pc == null || GameStates.IsExilling) return false; + if (!pc.Is(CustomRoles.Evolver) || !(pc.GetRoleClass() is Evolver evolverInstance)) return false; + + msg = msg.ToLower().Trim(); + bool isShop = false, isBuy = false; + string error = string.Empty; + + // Check for "/shop" or "/buy" commands + if (CheckCommand(ref msg, "shop")) isShop = true; + else if (CheckCommand(ref msg, "buy")) isBuy = true; + else return false; + + if (!pc.IsAlive()) + { + pc.ShowInfoMessage(isUI, "You cannot use commands when dead!"); + Logger.Info("Command failed: Player is dead.", "Evolver"); + return true; + } + + if (isShop) + { + Evolver.ShowShopOptions(pc); + Logger.Info("Showing shop options and exiting.", "Evolver"); + return true; + } + + if (isBuy && MsgToPlayerAndRole(msg, pc, out int effectId, out error)) + { + evolverInstance.PurchaseUpgrade(pc, effectId); + SendRPC(1, effectId); + Logger.Info($"Processed buy command: effectId {effectId}", "Evolver"); + return true; + } + + // Send error message if something went wrong + Utils.SendMessage(error, pc.PlayerId); + Logger.Info("Invalid option or error message sent.", "Evolver"); + return true; + } + + + + public static void SendMessage(string message, byte playerId, bool isSystemMessage = false) + { + // Use the isSystemMessage flag to tag the message or handle it in a way that avoids re-parsing + if (isSystemMessage) + { + message = "" + message; // Prefix or otherwise tag as a system message + } + + // Rest of the message sending code + } + + public void SetCatchCooldown(float cooldown, PlayerControl player, int cooldownLevel) + { + // Apply cooldown logic here + // Example: Main.AllPlayerKillCooldown[player.PlayerId] = cooldown; + Utils.SendMessage($"Catch cooldown set to {cooldown} seconds.", player.PlayerId); + } + private void AttemptCatch(PlayerControl killer, PlayerControl target) + { + bool isCatchSuccessful = UnityEngine.Random.value < GetCatchChance(); + + if (isCatchSuccessful) + { + int pointsGained = GetPointsPerCatch(); + evolverPoints += pointsGained; + + // Regular success message with current total points after catch + var variables = new Dictionary + { + { "points", pointsGained.ToString() }, + { "totalPoints", evolverPoints.ToString() } + }; + + string successMessage = GetString("EvolverCatchSuccess", variables) + $" You now have {evolverPoints} points."; + killer.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Evolver), successMessage)); + + // Separate check for MEGA evolution point chance to avoid overlap + if (UnityEngine.Random.value <= MEGA_POINT_CHANCE) + { + megaPoints++; + hasNewMegaPoint = true; // Set flag to true + + string megaPointMessage = GetString("EvolverMegaPointGain"); + killer.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Evolver), megaPointMessage)); + } + } + else + { + + + string failureMessage = GetString("EvolverCatchFailure"); + killer.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Evolver), failureMessage)); + } + + // Trigger shield animation without killing and set cooldown + if (!DisableShieldAnimations.GetBool()) + { + killer.RpcGuardAndKill(target); + } + } + + + + + private float GetUpgradeCatchChance() + { + // Example: +10% per upgrade level + return catchChanceLevel * 0.1f; + } + + private float GetUpgradeCooldownReduction() + { + // Example: -2 seconds per upgrade level + return cooldownReductionLevel * 2f; + } + + private int GetUpgradePointsOnCatch() + { + // Example: +1 point per upgrade level + return pointsOnCatchLevel; + } + + // Inside ShowShopOptions method + private static void ShowShopOptions(PlayerControl player) + { + Evolver evolverInstance = player.GetRoleClass() as Evolver; + if (evolverInstance == null) return; + + string shopMenu = "" + + " \n/buy 1: Increase catch chance (" + + $"{evolverInstance.catchChanceLevel}/{evolverInstance.catchChanceUpgradeCosts.Length}) " + + $"[{evolverInstance.catchChanceUpgradeCosts[Mathf.Min(evolverInstance.catchChanceLevel, evolverInstance.catchChanceUpgradeCosts.Length - 1)]} points]\n" + + "/buy 2: Increase points on catch (" + + $"{evolverInstance.pointsOnCatchLevel}/{evolverInstance.pointsOnCatchUpgradeCosts.Length}) " + + $"[{evolverInstance.pointsOnCatchUpgradeCosts[Mathf.Min(evolverInstance.pointsOnCatchLevel, evolverInstance.pointsOnCatchUpgradeCosts.Length - 1)]} points]\n" + + "/buy 3: Decrease catch cooldown (" + + $"{evolverInstance.cooldownReductionLevel}/{evolverInstance.cooldownReductionUpgradeCosts.Length}) " + + $"[{evolverInstance.cooldownReductionUpgradeCosts[Mathf.Min(evolverInstance.cooldownReductionLevel, evolverInstance.cooldownReductionUpgradeCosts.Length - 1)]} points]\n" + + "/buy 4: Increase votes (" + + $"{evolverInstance.voteLevel}/{evolverInstance.maxVoteLevel}) " + + $"[{evolverInstance.voteUpgradeCosts[Mathf.Min(evolverInstance.voteLevel, evolverInstance.maxVoteLevel - 1)]} points]\n"; + + if (!evolverInstance.isImmortalityActive) + { + shopMenu += "/buy 5: Immortality Shield (0/1) [20 points]\n"; + } + else + { + shopMenu += "/buy 5: Immortality Shield (1/1) [Purchased]\n"; + } + + + int evolverPoints = GetEvolverPoints(player.PlayerId); + shopMenu += $"\nYou currently have {evolverPoints} points."; + + Utils.SendMessage(shopMenu, player.PlayerId); + } + + + + + //===========================RPC METHODS==============================\\ + public static void SendRPC(int operate, int effectId = -1) + { + MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.SyncRoleSkill, SendOption.Reliable, -1); + writer.WriteNetObject(PlayerControl.LocalPlayer); + writer.Write(operate); + if (operate == 1) writer.Write(effectId); // Send effect ID if it's a purchase + AmongUsClient.Instance.FinishRpcImmediately(writer); + } + + public override void ReceiveRPC(MessageReader reader, PlayerControl pc) + { + int operate = reader.ReadInt32(); + if (operate == 1) + { + int effectId = reader.ReadInt32(); + ApplyEffect(pc, effectId); // Apply the upgrade effect to the Evolver player + } + } + + //===========================HELPER METHODS==============================\\ + private static bool MsgToPlayerAndRole(string msg, PlayerControl player, out int effectId, out string error) + { + if (msg.StartsWith("/")) + msg = msg.Replace("/", string.Empty); + + Regex r = new("\\d+"); + MatchCollection mc = r.Matches(msg); + string result = string.Empty; + for (int i = 0; i < mc.Count; i++) + result += mc[i]; + + if (int.TryParse(result, out int num)) + { + if (num < 1 || num > 6) + { + effectId = -1; + error = "/buy 1: Increase catch chance\n" + + "/buy 2: Increase points on catch\n" + + "/buy 3: Health increase\n" + + "/buy 4: Increase votes\n" + + "/buy 5: Decrease catch cooldown\n" + + "/buy 6: Immortality\n" + + $"\nYou currently have {evolverPoints} points."; + + return false; + } + effectId = num; + error = string.Empty; + return true; + } + else + { + effectId = -1; + + // Build the shop options message with current points + int evolverPoints = GetEvolverPoints(player.PlayerId); + error = "/buy 1: Increase catch chance\n" + + "/buy 2: Increase points on catch\n" + + "/buy 3: Health increase\n" + + "/buy 4: Increase votes\n" + + "/buy 5: Decrease catch cooldown\n" + + "/buy 6: Immortality\n" + + $"\nYou currently have {evolverPoints} points."; + + return false; + } + + } + + public static bool CheckCommand(ref string msg, string command) + { + var comList = command.Split('|'); + for (int i = 0; i < comList.Length; i++) + { + if (msg.StartsWith("/" + comList[i])) + { + msg = msg.Replace("/" + comList[i], string.Empty).Trim(); + return true; + } + } + return false; + } + public override int AddRealVotesNum(PlayerVoteArea ps) + { + return voteUpgradeLevel; // Each level grants an additional vote + } + + public override void AddVisualVotes(PlayerVoteArea votedPlayer, ref List statesList) + { + var additionalVotes = voteUpgradeLevel; + + for (var i = 0; i < additionalVotes; i++) + { + statesList.Add(new MeetingHud.VoterState() + { + VoterId = votedPlayer.TargetPlayerId, + VotedForId = votedPlayer.VotedFor + }); + } + } + + public void BuyImmortality(PlayerControl player) + { + // Check if ability is already bought + if (isImmortalityActive) return; + + // Activate immortality shield + isImmortalityActive = true; + + Utils.SendMessage("You have gained an immortality shield, but your abilities have been weakened!", player.PlayerId); + } + + + // Method to get the adjusted catch chance based on immortality status + + + public override bool OnCheckMurderAsTarget(PlayerControl killer, PlayerControl target) + { + // Check if target is Evolver and has shield active + if (target.Is(CustomRoles.Evolver) && isImmortalityActive) + { + // Block the attack and notify the player + Utils.SendMessage("Your immortality shield protected you from an attack!", target.PlayerId); + return false; // Cancels the kill + } + + + // Standard behavior if no shield or reflection is active + return base.OnCheckMurderAsTarget(killer, target); + } + + + + + + + + + public void PurchaseUpgrade(PlayerControl player, int effectId) + { + int currentPoints = GetEvolverPoints(player.PlayerId); + + switch (effectId) + { + case 1: // Increase Catch Chance + Logger.Info($"Attempting to upgrade Catch Chance: current level = {catchChanceLevel}, max level = {catchChanceUpgradeCosts.Length}", "Evolver", false, 0, "", false); + if (catchChanceLevel < catchChanceUpgradeCosts.Length && + currentPoints >= catchChanceUpgradeCosts[catchChanceLevel]) + { + DeductPoints(player.PlayerId, catchChanceUpgradeCosts[catchChanceLevel]); + catchChanceLevel++; + purchasedUpgrades++; + Utils.SendMessage($"Catch chance upgraded to {GetCatchChance() * 100}%! Cooldown is now {GetCatchCooldown()} seconds.", player.PlayerId); + } + else + { + Utils.SendMessage("Not enough points or max level reached for catch chance upgrade.", player.PlayerId); + } + break; + + case 2: // Increase Points on Catch + Logger.Info($"Attempting to upgrade Points on Catch: current level = {pointsOnCatchLevel}, max level = {pointsOnCatchUpgradeCosts.Length}", "Evolver", false, 0, "", false); + if (pointsOnCatchLevel < pointsOnCatchUpgradeCosts.Length && + currentPoints >= pointsOnCatchUpgradeCosts[pointsOnCatchLevel]) + { + DeductPoints(player.PlayerId, pointsOnCatchUpgradeCosts[pointsOnCatchLevel]); + pointsOnCatchLevel++; + purchasedUpgrades++; + Utils.SendMessage($"Points on catch upgraded to {GetPointsPerCatch()} points.", player.PlayerId); + } + else + { + Utils.SendMessage("Not enough points or max level reached for points on catch upgrade.", player.PlayerId); + } + break; + + case 3: // Decrease Catch Cooldown + Logger.Info($"Attempting to upgrade Catch Cooldown: current level = {cooldownReductionLevel}, max level = {cooldownReductionUpgradeCosts.Length}", "Evolver", false, 0, "", false); + if (cooldownReductionLevel < cooldownReductionUpgradeCosts.Length && + currentPoints >= cooldownReductionUpgradeCosts[cooldownReductionLevel]) + { + DeductPoints(player.PlayerId, cooldownReductionUpgradeCosts[cooldownReductionLevel]); + cooldownReductionLevel++; + purchasedUpgrades++; + Utils.SendMessage($"Catch cooldown reduced to {GetCatchCooldown()} seconds. Current catch chance is {GetCatchChance() * 100}%.", player.PlayerId); + } + else + { + Utils.SendMessage("Not enough points or max level reached for cooldown reduction upgrade.", player.PlayerId); + } + break; + + case 4: // Increase Votes + Logger.Info($"Attempting to upgrade Votes: current level = {voteUpgradeLevel}, max level = {voteUpgradeCosts.Length}", "Evolver", false, 0, "", false); + + if (voteUpgradeLevel < voteUpgradeCosts.Length && + currentPoints >= voteUpgradeCosts[voteUpgradeLevel]) + { + DeductPoints(player.PlayerId, voteUpgradeCosts[voteUpgradeLevel]); + voteUpgradeLevel++; + purchasedUpgrades++; + Utils.SendMessage($"Vote count increased to {GetVoteCount()}!", player.PlayerId); + } + else + { + Utils.SendMessage("Not enough points or max level reached for vote count upgrade.", player.PlayerId); + } + break; + + case 5: // Immortality Shield + Logger.Info("Attempting to purchase Immortality Shield", "Evolver", false, 0, "", false); + if (!isImmortalityActive && currentPoints >= 20) + { + DeductPoints(player.PlayerId, 20); + BuyImmortality(player); // Pass the player object here + purchasedUpgrades++; + Utils.SendMessage("Immortality shield purchased! You are now shielded from attacks, but catch chance and cooldown are affected.", player.PlayerId); + } + else + { + Utils.SendMessage("Not enough points or Immortality Shield already purchased.", player.PlayerId); + } + break; + + + + + + + default: + Utils.SendMessage("Invalid upgrade option.", player.PlayerId); + break; + } + } + + private int GetVoteCount() + { + // Base vote count is 1, and each level adds an additional vote + return 1 + voteUpgradeLevel; // Assuming 0 upgrades means 1 vote, level 4 means 5 votes + } + + + + + + // Other methods like EnableReflectionAbility() and EnableReflexiveCooldownReduction() will follow a similar structure + + private static void ApplyEffect(PlayerControl player, int effectId) + { + switch (effectId) + { + case 1: + Utils.SendMessage("Increased catch chance applied!", player.PlayerId); + // Apply catch chance increase logic + break; + case 2: + Utils.SendMessage("Increased points on catch applied!", player.PlayerId); + // Apply points increase logic + break; + case 3: + Utils.SendMessage("Health increase applied!", player.PlayerId); + // Apply health increase logic + break; + case 4: + Utils.SendMessage("Increased votes applied!", player.PlayerId); + // Apply vote increase logic + break; + case 5: + Utils.SendMessage("Decreased catch cooldown applied!", player.PlayerId); + // Apply cooldown reduction logic + break; + case 6: + Utils.SendMessage("Immortality applied!", player.PlayerId); + // Apply immortality logic + break; + } + } + + + private static int GetUpgradeCost(int effectId) => 1; // Example cost, can vary per upgrade + private static int GetEvolverPoints(byte playerId) => evolverPoints; + private static void DeductPoints(byte playerId, int cost) => evolverPoints -= cost; + + //===========================MEGA upgrades===========================================================================================================================================================================================================================================\\ + public void AttemptMegaPointGain(PlayerControl player) + { + if (megaPoints >= 1) return; // Limit to 1 MEGA point for simplicity + + if (UnityEngine.Random.value <= MEGA_POINT_CHANCE) + { + megaPoints++; + Utils.SendMessage("You earned a MEGA evolution point! It will be automatically converted to normal points in the next meeting.", player.PlayerId); + hasNewMegaPoint = true; // Set flag to notify during meeting + } + } + + public override void OnMeetingHudStart(PlayerControl pc) + { + if (hasNewMegaPoint) + { + hasNewMegaPoint = false; // Reset the flag after notifying + + if (megaPoints > 0) + { + // Convert MEGA points to normal points + int pointsToAdd = megaPoints * 5; // Conversion rate: 1 MEGA point = 5 normal points + AddNormalPoints(pc.PlayerId, pointsToAdd); + megaPoints = 0; // Clear MEGA points after conversion + + Utils.SendMessage($"Your MEGA evolution point has been converted to {pointsToAdd} normal points!", pc.PlayerId); + } + } + } + + private void AddNormalPoints(byte playerId, int points) + { + evolverPoints += points; + Utils.SendMessage($"You have been awarded {points} normal points!", playerId); + } + + public static void ClearEvolverCache() + { + evolverCache.Clear(); + } + + + } +} diff --git a/Summoned.cs b/Summoned.cs new file mode 100644 index 000000000..5f282702b --- /dev/null +++ b/Summoned.cs @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/TOHE - Backup.csproj b/TOHE - Backup.csproj new file mode 100644 index 000000000..0d335c27e --- /dev/null +++ b/TOHE - Backup.csproj @@ -0,0 +1,50 @@ + + + net6.0 + false + false + false + Town Of Host Enhanced + Moe + preview + + Debug;Release;Canary + true + True + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + runtime; compile; build; native; contentfiles; analyzers; buildtransitive + all + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + + + \ No newline at end of file diff --git a/TOHE.csproj b/TOHE.csproj index 262b4a005..4f7e965ef 100644 --- a/TOHE.csproj +++ b/TOHE.csproj @@ -15,7 +15,6 @@ - @@ -39,8 +38,8 @@ - - + + diff --git a/main.cs b/main.cs index 7d1222977..3d22e8f57 100644 --- a/main.cs +++ b/main.cs @@ -42,14 +42,14 @@ public class Main : BasePlugin public static ConfigEntry DebugKeyInput { get; private set; } public const string PluginGuid = "com.0xdrmoe.townofhostenhanced"; - public const string PluginVersion = "2024.1103.211.9999"; // YEAR.MMDD.VERSION.CANARYDEV - public const string PluginDisplayVersion = "2.1.1"; + public const string PluginVersion = "2024.1102.210.9999"; // YEAR.MMDD.VERSION.CANARYDEV + public const string PluginDisplayVersion = "2.1.0"; public const string SupportedVersionAU = "2024.8.13"; // Also 2024.9.4 and 2024.10.29 /******************* Change one of the three variables to true before making a release. *******************/ public static readonly bool devRelease = false; // Latest: V2.1.0 Alpha 16 Hotfix 1 public static readonly bool canaryRelease = false; // Latest: V2.1.0 Beta 3 - public static readonly bool fullRelease = true; // Latest: V2.1.1 + public static readonly bool fullRelease = true; // Latest: V2.1.0 public static bool hasAccess = true; @@ -136,6 +136,7 @@ public class Main : BasePlugin public static bool IsFixedCooldown => CustomRoles.Vampire.IsEnable() || CustomRoles.Poisoner.IsEnable(); public static float RefixCooldownDelay = 0f; public static NetworkedPlayerInfo LastVotedPlayerInfo; + public static readonly HashSet ResetCamPlayerList = []; public static string LastVotedPlayer; public static readonly HashSet winnerList = []; public static readonly HashSet winnerNameList = []; @@ -357,6 +358,7 @@ public static void LoadRoleColors() break; } } + if (!Directory.Exists(LANGUAGE_FOLDER_NAME)) Directory.CreateDirectory(LANGUAGE_FOLDER_NAME); CreateTemplateRoleColorFile(); if (File.Exists(@$"./{LANGUAGE_FOLDER_NAME}/RoleColor.dat")) @@ -597,6 +599,7 @@ public override void Load() TOHE.Logger.Msg("========= TOHE loaded! =========", "Plugin Load"); } } + public enum CustomRoles { // Crewmate(Vanilla) @@ -705,6 +708,8 @@ public enum CustomRoles Witch, Zombie, + + //Crewmate Ghost Ghastly, Hawk, @@ -800,8 +805,10 @@ public enum CustomRoles Doomsayer, Doppelganger, Executioner, + Evolver, Famine, Follower, + LingeringPresence, Glitch, God, Hater, @@ -839,6 +846,7 @@ public enum CustomRoles SchrodingersCat, Seeker, SerialKiller, + Summoner, Shaman, Shroud, Sidekick, @@ -875,6 +883,7 @@ public enum CustomRoles // Add-ons Admired, + Allergic, Antidote, Autopsy, Avanger, @@ -898,6 +907,7 @@ public enum CustomRoles Flash, Fool, Fragile, + FadingLight, Ghoul, Glow, Gravestone, @@ -937,6 +947,7 @@ public enum CustomRoles Sloth, Soulless, Statue, + Summoned, Stubborn, Susceptible, Swift, @@ -951,7 +962,8 @@ public enum CustomRoles VoidBallot, Watcher, Workhorse, - Youtuber + Youtuber, + } //WinData public enum CustomWinner @@ -1019,12 +1031,15 @@ public enum CustomWinner Doppelganger = CustomRoles.Doppelganger, Solsticer = CustomRoles.Solsticer, Apocalypse = CustomRoles.Apocalypse, + Random = 581, } public enum AdditionalWinners { None = -1, Lovers = CustomRoles.Lovers, Opportunist = CustomRoles.Opportunist, + Randomizer = CustomRoles.Randomizer, + Evolver = CustomRoles.Evolver, Executioner = CustomRoles.Executioner, Lawyer = CustomRoles.Lawyer, Hater = CustomRoles.Hater, diff --git a/summoner.cs b/summoner.cs new file mode 100644 index 000000000..9155fe5a6 --- /dev/null +++ b/summoner.cs @@ -0,0 +1,465 @@ +using TOHE.Roles.Core; +using UnityEngine; +using UnityEngine.Playables; +using static TOHE.Options; +using static TOHE.Utils; + +namespace TOHE.Roles.Neutral; + +internal class Summoner : RoleBase +{ + //===========================SETUP================================\\ + private const int Id = 92000; + private static readonly HashSet playerIdList = new(); // Initialize properly + public static bool HasEnabled => playerIdList.Any(); + public override bool IsDesyncRole => true; + public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; + public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralChaos; + //================================================================\\ + + private static OptionItem ReviveDelayOption; + private static OptionItem DeathTimerOption; + private static OptionItem KnowSummonedRoles; + private static OptionItem KillCooldownOption; + private static readonly Dictionary originalAddOns)> SavedStates = new(); + private static readonly Dictionary SummonedTimers = new(); + private static readonly Dictionary SummonedHealth = new(); + private static List<(PlayerControl, float)> PendingRevives = new(); + private static readonly Dictionary LastUpdateTimes = new(); + + private bool HasSummonedThisMeeting = false; + + public override void SetupCustomOption() + { + SetupRoleOptions(Id, TabGroup.NeutralRoles, CustomRoles.Summoner); + + // Revive Delay + ReviveDelayOption = FloatOptionItem.Create(Id + 10, "Revive Delay", new(1f, 30f, 1f), 5f, TabGroup.NeutralRoles, false) + .SetParent(CustomRoleSpawnChances[CustomRoles.Summoner]) + .SetValueFormat(OptionFormat.Seconds); + + // Death Timer + DeathTimerOption = FloatOptionItem.Create(Id + 11, "Summoned Player Duration", new(5f, 120f, 5f), 30f, TabGroup.NeutralRoles, false) + .SetParent(CustomRoleSpawnChances[CustomRoles.Summoner]) + .SetValueFormat(OptionFormat.Seconds); + + // Kill Cooldown + KillCooldownOption = FloatOptionItem.Create(Id + 12, "Summoned Player Kill Cooldown", new(5f, 60f, 1f), 15f, TabGroup.NeutralRoles, false) + .SetParent(CustomRoleSpawnChances[CustomRoles.Summoner]) + .SetValueFormat(OptionFormat.Seconds); + + KnowSummonedRoles = BooleanOptionItem.Create(Id + 13, "Know Summoner/Summoned Roles", true, TabGroup.NeutralRoles, false) + .SetParent(CustomRoleSpawnChances[CustomRoles.Summoner]); + } + + public override void Add(byte playerId) + { + base.Add(playerId); + CustomRoleManager.OnFixedUpdateOthers.Add(OnFixedUpdate); + var playerState = Main.PlayerStates[playerId]; + playerState.SetMainRole(CustomRoles.Summoner); + playerState.IsSummoner = true; + } + + public override void Init() + { + SummonedHealth.Clear(); + LastUpdateTimes.Clear(); + } + + public static bool SummonerCheckMsg(PlayerControl pc, string msg, bool isUI = false, bool isSystemMessage = false) + { + if (isSystemMessage || pc == null || !AmongUsClient.Instance.AmHost) return false; // Skip if system message or not host + if (!GameStates.IsMeeting || pc == null || GameStates.IsExilling) return false; // Only during meetings + if (!pc.Is(CustomRoles.Summoner) || !(pc.GetRoleClass() is Summoner summonerInstance)) return false; + + msg = msg.ToLower().Trim(); + Logger.Info($"Received command: {msg} from {pc.PlayerId}, Host: {AmongUsClient.Instance.AmHost}", "Summoner"); + + if (!CheckCommand(ref msg, "summon")) return false; + + if (!pc.IsAlive()) + { + Logger.Warn("Summoner is dead and cannot use commands.", "Summoner"); + return true; + } + + if (!byte.TryParse(msg, out var targetId)) + { + Logger.Warn("Invalid target ID for /summon command.", "Summoner"); + pc.Notify("Invalid target ID! Use /summon "); + return true; + } + + PlayerControl targetPlayer = null; + foreach (var player in PlayerControl.AllPlayerControls) + { + if (player.PlayerId == targetId) + { + targetPlayer = player; + break; // Exit the loop once the player is found + } + } + + if (targetPlayer == null || targetPlayer.IsAlive()) + { + Logger.Warn("Target player is invalid or alive.", "Summoner"); + pc.Notify("Target is invalid or not dead."); + return true; + } + + if (summonerInstance.HasSummonedThisMeeting) + { + Logger.Warn("Summoner has already summoned a player this meeting.", "Summoner"); + pc.Notify("You can only summon one player per meeting."); + return true; + } + + summonerInstance.RevivePlayer(targetPlayer); + summonerInstance.HasSummonedThisMeeting = true; + + Logger.Info($"Summoner {pc.PlayerId} has summoned player {targetPlayer.PlayerId}.", "Summoner"); + + return true; // Indicate the command was handled and suppress the message + } + + + public static bool CheckCommand(ref string msg, string command) + { + var comList = command.Split('|'); + for (int i = 0; i < comList.Length; i++) + { + if (msg.StartsWith("/" + comList[i])) + { + msg = msg.Replace("/" + comList[i], string.Empty).Trim(); + return true; + } + } + return false; + } + + public void RevivePlayer(PlayerControl targetPlayer) + { + if (targetPlayer == null || targetPlayer.Data == null || !targetPlayer.Data.IsDead) + { + Logger.Warn($"RevivePlayer: Invalid target or player is not dead.", "Summoner"); + return; + } + + float reviveDelay = ReviveDelayOption?.GetFloat() ?? 5f; + + new LateTask(() => + { + if (targetPlayer.IsAlive()) + { + Logger.Info($"Player {targetPlayer.PlayerId} is already alive. Revive skipped.", "Summoner"); + return; + } + + // Handle players already in the Summoned role + if (targetPlayer.Is(CustomRoles.Summoned)) + { + Summoned.RefreshTimer(targetPlayer.PlayerId); + Logger.Info($"Player {targetPlayer.PlayerId} re-summoned with a refreshed timer.", "Summoner"); + return; + } + + // Save current role and add-ons + SaveRoleAndAddons(targetPlayer); + + // Reset sub-roles and assign Summoned role + targetPlayer.ResetSubRoles(); // Clear all sub-roles and add-ons + targetPlayer.RpcSetCustomRole(CustomRoles.Summoned); + + Logger.Info($"Player {targetPlayer.PlayerId} summoned and their role was saved.", "Summoner"); + + }, reviveDelay, "SummonerRevive"); + } + + private void SaveRoleAndAddons(PlayerControl player) + { + var originalRole = player.GetCustomRole(); + var originalAddons = player.GetAddOns(); + SavedStates[player.PlayerId] = (originalRole, originalAddons); + Logger.Info($"Player {player.PlayerId}'s role and add-ons saved.", "Summoner"); + } + + private void RestoreRoleAndAddons(PlayerControl player) + { + if (SavedStates.TryGetValue(player.PlayerId, out var state)) + { + // Use RpcSetRole to restore the role + player.RpcSetRole((AmongUs.GameOptions.RoleTypes)state.originalRole); + + // Restore saved add-ons + foreach (var addon in state.originalAddOns) + { + player.AddAddOn(addon); + } + + SavedStates.Remove(player.PlayerId); + Logger.Info($"Player {player.PlayerId} restored to their original role and add-ons.", "Summoner"); + } + } + + public void OnRoleRemove(byte playerId) + { + foreach (var summonedId in SavedStates.Keys.ToList()) + { + var summonedPlayer = PlayerControl.GetPlayerById(summonedId); + if (summonedPlayer != null && summonedPlayer.IsAlive()) + { + summonedPlayer.RpcExileV2(); // Kill the summoned player + RestoreRoleAndAddons(summonedPlayer); // Restore original role and add-ons + } + } + + base.OnRoleRemove(playerId); + } +} + + public static bool CheckSummoned(PlayerControl player) + { + return player.Is(CustomRoles.Summoned); // Replace with your Summoned role check logic + } + + public override void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo bodyInfo) + { + foreach (var player in PlayerControl.AllPlayerControls) + { + if (player.HasSpecificSubRole(CustomRoles.Summoned) && player.IsAlive()) + { + + + // Trigger Summoned's custom death mechanics + KillSummonedPlayer(player); + } + } + } + + + + + + private void PerformRevive(PlayerControl targetPlayer, float reviveDelay) + { + if (targetPlayer.IsAlive()) return; + + new LateTask(() => + { + if (targetPlayer.IsAlive()) return; + + // Handle players already in the Summoned role + if (targetPlayer.Is(CustomRoles.Summoned)) + { + Summoned.RefreshTimer(targetPlayer.PlayerId); + Logger.Info($"Player {targetPlayer.PlayerId} re-summoned with a refreshed timer.", "Summoner"); + return; + } + + // Save the player's current role and replace with Summoned + SaveRoleAndAddons(targetPlayer); + targetPlayer.RpcSetCustomRole(CustomRoles.Summoned); + Logger.Info($"Player {targetPlayer.PlayerId} summoned and original role saved.", "Summoner"); + }, reviveDelay, "SummonerRevive"); + } + + + + + + + + + private void NotifySummonerAndSummoned(string message) + { + foreach (var player in PlayerControl.AllPlayerControls) + { + if (player.Is(CustomRoles.Summoner) || player.HasSpecificSubRole(CustomRoles.Summoned)) + { + Utils.SendMessage(message, player.PlayerId); + } + } + } + + private void StartDeathTimer(PlayerControl targetPlayer) + { + int deathTimer = Mathf.CeilToInt(DeathTimerOption.GetFloat()); + SummonedHealth[targetPlayer.PlayerId] = deathTimer; + LastUpdateTimes[targetPlayer.PlayerId] = Utils.GetTimeStamp(); + + Logger.Info($"Player {targetPlayer.GetRealName()} has been given a death timer of {deathTimer} seconds.", "Summoner"); + + // Notify the summoned player + NotifySummonedHealth(targetPlayer); + } + + + private void OnFixedUpdate(PlayerControl player, bool lowLoad, long nowTime) + { + if (lowLoad || GameStates.IsMeeting) return; + + foreach (var (playerId, health) in SummonedHealth.ToList()) // Avoid modification issues during iteration + { + PlayerControl targetPlayer = null; + + // Find the player with the given playerId + foreach (var p in PlayerControl.AllPlayerControls) + { + if (p.PlayerId == playerId) + { + targetPlayer = p; + break; + } + } + + if (targetPlayer == null) + { + ResetHealth(playerId); // Clean up invalid players + continue; + } + + // Skip timer updates if the player is dead + if (targetPlayer.Data.IsDead) + { + Logger.Info($"Skipping timer update for dead summoned player {playerId}.", "Summoner"); + continue; + } + + // Get the current time + var currentTime = (long)(System.DateTime.UtcNow - new System.DateTime(1970, 1, 1, 0, 0, 0, System.DateTimeKind.Utc)).TotalSeconds; + + if (!LastUpdateTimes.TryGetValue(playerId, out var lastUpdateTime)) + { + lastUpdateTime = currentTime; + } + + // Calculate time difference and update health + var deltaTime = currentTime - lastUpdateTime; + SummonedHealth[playerId] = Mathf.Clamp(SummonedHealth[playerId] - deltaTime, 0f, DeathTimerOption.GetFloat()); + + // Apply visual updates for health + NotifySummonedHealth(targetPlayer); + + if (SummonedHealth[playerId] <= 0) + { + KillSummonedPlayer(targetPlayer); + SummonedHealth.Remove(playerId); + LastUpdateTimes.Remove(playerId); + } + + // Update the last timestamp + LastUpdateTimes[playerId] = currentTime; + } + } + + public static bool KnowRole(PlayerControl player, PlayerControl target) + { + // Summoner can see Summoned, Summoned can see Summoner + if (player.Is(CustomRoles.Summoner) && target.HasSpecificSubRole(CustomRoles.Summoned)) return true; + if (player.HasSpecificSubRole(CustomRoles.Summoned) && target.Is(CustomRoles.Summoner)) return true; + + // Summoned can see other Summoned players if enabled + if (KnowSummonedRoles.GetBool() && + player.HasSpecificSubRole(CustomRoles.Summoned) && + target.HasSpecificSubRole(CustomRoles.Summoned)) + return true; + + return false; + } + + + private void NotifySummonedHealth(PlayerControl player) + { + if (player.Is(CustomRoles.Summoner) || player.HasSpecificSubRole(CustomRoles.Summoned)) + { + // Notify only Summoner and Summoned players + var health = Mathf.RoundToInt(SummonedHealth[player.PlayerId]); + player.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Summoned), $"Time Remaining: {health}s")); + } + } + + private static void KillSummonedPlayer(PlayerControl target) + { + target.SetDeathReason(PlayerState.DeathReason.SummonedExpired); + target.RpcExileV2(); // Kill the player without leaving a body + Logger.Info($"{target.GetRealName()} has died because their timer ran out.", "Summoner"); + } + + private void ResetHealth(byte playerId) + { + SummonedHealth.Remove(playerId); + LastUpdateTimes.Remove(playerId); + } + + + public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) + { + if (killer.Is(CustomRoles.Summoned) && (target.Is(CustomRoles.Summoner) || target.HasSpecificSubRole(CustomRoles.Summoned))) + { + string errorMessage = "You cannot kill the Summoner or other summoned players!"; + killer.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Summoner), errorMessage)); + return false; // Cancel the kill + } + + return true; // Allow other kills + } + + public override void AfterMeetingTasks() + { + base.AfterMeetingTasks(); + + // Reset Summoning flag to allow reviving in the next meeting + HasSummonedThisMeeting = false; + + // Handle pending revives queued during the meeting + if (PendingRevives.Count > 0) + { + foreach (var (player, delay) in PendingRevives.ToList()) + { + PerformRevive(player, delay); + } + PendingRevives.Clear(); + } + + // Process Summoned players + foreach (var player in PlayerControl.AllPlayerControls) + { + if (SummonedTimers.TryGetValue(player.PlayerId, out var remainingTime)) + { + if (player.Data.IsDead) + { + Logger.Info($"Player {player.GetRealName()} with remaining time will not automatically revive. Summoner must manually summon them again.", "Summoner"); + SummonedTimers.Remove(player.PlayerId); // Remove the expired timer + } + else + { + Logger.Warn($"Player {player.GetRealName()} is alive but had a timer. Timer will continue.", "Summoner"); + } + } + } + } + + + + + + public override string GetLowerTextOthers(PlayerControl seer, PlayerControl target = null, bool isForMeeting = false, bool isForHud = false) + { + if (target == null || !isForHud) return string.Empty; + + // Check if roles should be visible + if (KnowRole(seer, target)) + { + if (target.Is(CustomRoles.Summoner)) + return ColorString(GetRoleColor(CustomRoles.Summoner), "Summoner"); + if (target.HasSpecificSubRole(CustomRoles.Summoned)) + return ColorString(GetRoleColor(CustomRoles.Summoned), "Summoned"); + } + + // Default behavior + return string.Empty; + } +} + + From 4287bf183f87db7994fc4d4400374ddca6d90178 Mon Sep 17 00:00:00 2001 From: frisk11123 Date: Thu, 2 Jan 2025 17:52:03 -0500 Subject: [PATCH 02/11] Update DevManager.cs --- Modules/DevManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/DevManager.cs b/Modules/DevManager.cs index 0e6516bb9..af8022f3c 100644 --- a/Modules/DevManager.cs +++ b/Modules/DevManager.cs @@ -96,7 +96,7 @@ public static void Init() DevUserList.Add(new(code: "icingposh#6469", color: "#9e2424", userType: "s_cr", tag: "discord.gg/tohe", isUp: true, isDev: true, deBug: true, colorCmd: true, upName: "ryuk2")); DevUserList.Add(new(code: "bestanswer#3360", color: "#00ff1d", tag: "绿色游戏", userType: "s_cr", isUp: true, isDev: true, deBug: true, colorCmd: true, upName: null)); //NikoCat233's alt DevUserList.Add(new(code: "happypride#3747", color: "#00ff1d", tag: "绿色游戏", userType: "s_cr", isUp: true, isDev: true, deBug: true, colorCmd: true, upName: null)); //NikoCat233's alt 2 - DevUserList.Add(new(code: "meetquest#2619", color: "#00ff1d", tag: "null", userType: "s_cr", isUp: true, isDev: true, deBug: true, colorCmd: true, upName: null)); //frisk debug for randomizer (remove latter) + //// pt-BR Translators //DevUserList.Add(new(code: "modelpad#5195", color: "null", tag: "Tradutor", isUp: true, isDev: false, deBug: false, colorCmd: false, upName: "Reginaldoo")); // and content creator //DevUserList.Add(new(code: "mimerecord#9638", color: "null", tag: "Tradutor", isUp: false, isDev: false, deBug: false, colorCmd: false, upName: "Arc")); From 3cff8f2d031d97289935b6cd493370c9a0d6d5bb Mon Sep 17 00:00:00 2001 From: Moe <32988634+0xDrMoe@users.noreply.github.com> Date: Fri, 3 Jan 2025 18:33:43 -0500 Subject: [PATCH 03/11] New translations en_us.json (Italian) --- Resources/Lang/it_IT.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Resources/Lang/it_IT.json b/Resources/Lang/it_IT.json index 19d2b673b..62edd268e 100644 --- a/Resources/Lang/it_IT.json +++ b/Resources/Lang/it_IT.json @@ -603,7 +603,7 @@ "VultureInfo": "Mangia i cadaveri segnalandoli per vincere", "TaskinatorInfo": "Incarichi silenziosi, esplosioni mortali", "BenefactorInfo": "Incarico completato, scudo élite!", - "MedusaInfo": "Stone bodies by reporting them", + "MedusaInfo": "Tramuta i corpi in pietra segnalandoli", "SpiritcallerInfo": "Trasforma i giocatori in Spiriti Malvagi", "AmnesiacInfo": "Ricorda il ruolo di un cadavere", "ImitatorInfo": "Imita il ruolo di un giocatore", @@ -625,9 +625,9 @@ "PoisonerInfo": "Kill everyone with delayed kills", "HexMasterInfo": "Strega i giocatori per ucciderli nelle riunioni", "WraithInfo": "Usa i condotti per essere temporaneamente invisibile", - "JinxInfo": "Reflect attacks onto your attackers", + "JinxInfo": "Rifletti gli attacchi sui tuoi attaccanti", "PotionMasterInfo": "Usa le tue pozioni a tuo vantaggio", - "NecromancerInfo": "Kill your killer to defy death", + "NecromancerInfo": "Uccidi il tuo assassino per sfidare la morte", "WardenInfo": "(Fantasma) Avvisa del pericolo", "MinionInfo": "(Fantasma) Acceca i nemici", "LoversInfo": "Rimanete in vita e vincete insieme", @@ -932,9 +932,9 @@ "RuthlessRomanticInfoLong": "(Neutrali):\nCambi il tuo ruolo da Romantico se il tuo partner (Un assassino neutrale) viene ucciso. Come Romantico Spietato, vinci se uccidi tutti e sei l'ultimo rimasto. Se vinci, anche il tuo partner morto vince con te.", "VengefulRomanticInfoLong": "(Neutrali):\nCambi il tuo ruolo da Romantico se il tuo partner (un astronauta o un neutrale non assassino) viene ucciso. In quanto Romantico Vendicativo, il tuo obiettivo è vendicare il tuo partner, il che significa che devi uccidere l'assassino del tuo partner. Se ci riesci, sia tu che il tuo partner vincerete con la squadra vincitrice alla fine. Se provi a uccidere qualcuno che non sia l'assassino del tuo partner, morirai per cilecca.", "PoisonerInfoLong": "(Neutrals):\nAs the Poisoner, your kills are delayed.\nKill everyone to win.", - "HexMasterInfoLong": "(Neutrals):\nAs the Hex Master, you can hex players or kill them.\nHexing a player works the same as spelling as a Witch.", + "HexMasterInfoLong": "(Neutrali):\nCome Fattucchiere, puoi maledire i giocatori o ucciderli.\nLanciare un maleficio a un giocatore funziona allo stesso modo dell'incantesimo di una Strega.", "WraithInfoLong": "(Neutrali):\nCome Spirito, puoi usare i condotti per svanire temporaneamente. Apparirai comunque visibile sullo schermo. Usa i condotti nuovamente per diventare visibile. Vinci se sei l'ultimo giocatore rimasto.", - "JinxInfoLong": "(Neutrals):\nAs the Jinx, whenever you get attacked, you jinx them, resulting in them dying to a jinx.\nThis has limited uses.\n\nKill off everyone to win.", + "JinxInfoLong": "(Neutrale):\nCome lo Iettatore, ogni volta che vieni attaccato, gli porti sfortuna, con il risultato di morire sfortunati.\nQuesto ha degli usi limitati.\n\nUccidi chiunque per vincere.", "PotionMasterInfoLong": "(Neutrals):\nAs the Potion Master, you have three different potions assigned to three different actions.\n\nSingle click: Reveal role\nDouble click: Kill\nMap: Sabotage\n\nThe reveal potion has a limit.\nWhen you run out, the kill buttons default to killing.", "NecromancerInfoLong": "(Neutrals):\nAs the Necromancer, you win when you're the last one standing.\nAdditionally when someone tries to kill you, you will block the kill, and you will teleport to a random vent. You will have a limited time to kill your killer. If you succeed in doing so, you live. If the time runs out before you kill your killer, you die permanently. If you try to kill someone else other than your killer, you will die.", "ShockerInfoLong": "(Neutrali):\nCome Shocker, puoi contrassegnare le stanze eseguendo degli incarichi in esse, e poi usare i condotti per Elettrificare chiunque si trovi in ​​quelle stanze per un periodo di tempo stabilito. Quando hai completato tutti i tuoi incarichi, ne ottieni di nuovi. Nota: eseguire degli incarichi durante quel periodo le contrassegnerà per il prossimo utilizzo dell'abilità.", From a61fda29ef269aca1a7b12dee2d494f81e4fb254 Mon Sep 17 00:00:00 2001 From: Niko233 <139348239+NikoCat233@users.noreply.github.com> Date: Mon, 6 Jan 2025 14:33:12 +0800 Subject: [PATCH 04/11] Merge Translations from dev-2.2.0 --- Resources/Lang/en_US.json | 1051 +++++++++++++++++++------------------ 1 file changed, 526 insertions(+), 525 deletions(-) diff --git a/Resources/Lang/en_US.json b/Resources/Lang/en_US.json index 595c42fa4..a8bfd1d5c 100644 --- a/Resources/Lang/en_US.json +++ b/Resources/Lang/en_US.json @@ -17,6 +17,7 @@ "PlayerNameForRoleInfo": "Hi {0}, your role is:- \n", "HostIconInMeeting": "HOST: {0}", + "ModdedClient": "Modded Client", "SubText.GM": "Spectate the chaos!", "SubText.Crewmate": "Find and exile the Impostors", @@ -411,53 +412,53 @@ "Revenant": "Revenant", "BracketAddons": "Add Brackets To Add-ons", "EngineerTOHEInfo": "Use the vents to catch the Impostors", - "ScientistTOHEInfo": "Access portable vitals from anywhere", + "ScientistTOHEInfo": "Access portable Vitals from anywhere", "NoisemakerTOHEInfo": "Send out an alert when killed", "TrackerTOHEInfo": "Track players with your map", - "ShapeshifterTOHEInfo": "Disguise as crewmates to frame them", + "ShapeshifterTOHEInfo": "Disguise as Crewmates to frame them", "PhantomTOHEInfo": "Turn invisible", - "GuardianAngelTOHEInfo": "Protect the crewmates from the Impostors", - "ImpostorTOHEInfo": "Kill and sabotage", + "GuardianAngelTOHEInfo": "Protect the Crewmates from the Impostors", + "ImpostorTOHEInfo": "Kill and Sabotage", "CrewmateTOHEInfo": "Search for the Impostors", "BountyHunterInfo": "Eliminate your target", "FireworkerInfo": "Go out with a BANG", "MercenaryInfo": "Keep killing, else you suicide", - "ShapeMasterInfo": "Swiftly kill with no shift cooldown", + "ShapeMasterInfo": "Swiftly kill with no Shapeshift Cooldown", "VampireInfo": "Your kills are delayed", - "WarlockInfo": "Curse crewmates then shift to make them kill", - "NinjaInfo": "Mark a target, then shift to kill", + "WarlockInfo": "Curse Crewmates then Shift to make them kill", + "NinjaInfo": "Mark a target, then Shift to kill", "ZombieInfo": "You are very slow", "AnonymousInfo": "Force a player to report a body", - "MinerInfo": "Warp to your last used vent by shifting", - "KillingMachineInfo": "You can ONLY kill, but low cooldown", + "MinerInfo": "Warp to your last used Vent by Shifting", + "KillingMachineInfo": "You can ONLY kill, but low Cooldown", "EscapistInfo": "Shift to mark places and warp back to them", - "WitchInfo": "Spell crewmates to kill them in meetings", + "WitchInfo": "Spell Crewmates to kill them in meetings", "NemesisInfo": "Kill when you're the last Impostor", "BeforeNemesisInfo": "You can't kill yet", "AfterNemesisInfo": "Now start killing", - "BloodmoonInfo": "Seek havoc upon the crewmates", - "PossessorInfo": "Possess and lead crewmates away from others", + "BloodmoonInfo": "Seek havoc upon the Crewmates", + "PossessorInfo": "Possess and lead Crewmates away from others", "PuppeteerInfo": "Make players kill for you", "MastermindInfo": "Make others kill for you", "TimeThiefInfo": "Lower meeting time by killing", - "SniperInfo": "Snipe players from a distance by shifting", + "SniperInfo": "Snipe players from a distance by Shifting", "UndertakerInfo": "Teleport dead body to a marked location", "RiftMakerInfo": "Two rifts I trace, touch 'em to warp space", - "EvilTrackerInfo": "Track players by shifting", + "EvilTrackerInfo": "Track players by Shifting", "EvilHackerInfo": "Hack systems", "AntiAdminerInfo": "Know when players are near devices", - "ArroganceInfo": "With each kill you make, your cooldown decreases", + "ArroganceInfo": "With each kill you make, your Cooldown decreases", "BomberInfo": "Shapeshift to explode", "TrapsterInfo": "Trap your kills", "ScavengerInfo": "Your kills are unreportable", - "EvilGuesserInfo": "Guess crew roles in meetings to kill", + "EvilGuesserInfo": "Guess Crewmate roles in meetings to kill", "GangsterInfo": "Convert players to your side", "CleanerInfo": "Report bodies to make them unreportable", "LightningInfo": "Convert players to Quantum Ghosts", - "GreedyInfo": "Your kill cooldown shifts", + "GreedyInfo": "Your Kill Cooldown shifts", "CursedWolfInfo": "You survive a few kill attempts", - "SoulCatcherInfo": "You swap places with your shift target", - "QuickShooterInfo": "Store ammo to offset kill cooldown", + "SoulCatcherInfo": "You swap places with your Shift target", + "QuickShooterInfo": "Store ammo to offset Kill Cooldown", "CamouflagerInfo": "Camouflage everyone for easy kills", "EraserInfo": "Erase the role of your vote target", "ButcherInfo": "Enjoy my beautiful work", @@ -465,42 +466,42 @@ "SwooperInfo": "Turn invisible temporarily", "CrewpostorInfo": "Kill by completing tasks", "WildlingInfo": "Kill with strength and disguise", - "TricksterInfo": "Kill and trick the crew", + "TricksterInfo": "Kill and trick the Crew", "VindicatorInfo": "Use your extra votes to kill everyone", - "ParasiteInfo": "Help the Impostors kill the crew", + "ParasiteInfo": "Help the Impostors kill the Crew", "DisperserInfo": "Teleport everyone to random vents", - "InhibitorInfo": "You cannot kill during sabotages", - "SaboteurInfo": "You can only kill during sabotages", - "CouncillorInfo": "Kill off crewmates during meetings", - "DazzlerInfo": "Reduce the vision of the crew", - "DeathpactInfo": "Assign players to a death pact", - "DevourerInfo": "Consume the skin of the crew", + "InhibitorInfo": "You cannot kill during Sabotages", + "SaboteurInfo": "You can only kill during Sabotages", + "CouncillorInfo": "Kill off Crewmates during meetings", + "DazzlerInfo": "Reduce the vision of the Crew", + "DeathpactInfo": "Assign players to a deathpact", + "DevourerInfo": "Consume the skin of the Crew", "ConsigliereInfo": "Discover the roles of other players", - "MorphlingInfo": "You can only kill while shapeshifted", + "MorphlingInfo": "You can only kill while Shapeshifted", "TwisterInfo": "Swap all player positions", - "LurkerInfo": "Reduce your kill cooldown by venting", + "LurkerInfo": "Reduce your Kill Cooldown by venting", "ConvictInfo": "Your target died, now help the Impostors", "VisionaryInfo": "You see the alignments of the living", - "RefugeeInfo": "Help the Impostors kill off the crew", + "RefugeeInfo": "Help the Impostors kill off the Crew", "UnderdogInfo": "Start killing on a low player count", - "LudopathInfo": "Your kill cooldown is random", + "LudopathInfo": "Your kill Cooldown is random", "GodfatherInfo": "Convert players to Refugees by voting", "ChronomancerInfo": "Kill in bursts", "PitfallInfo": "Setup traps around the map", "EvilMiniInfo": "No one can hurt you until you grow up", "BlackmailerInfo": "Silence other players", - "InstigatorInfo": "Sow discord among the crewmates", + "InstigatorInfo": "Sow discord among the Crewmates", "LazyGuyInfo": "You're too lazy", "SuperStarInfo": "Everyone knows you", - "CleanserInfo": "Erase All Add-ons of your vote target", - "KeeperInfo": "Reject the Eject, Keeper Protect!", + "CleanserInfo": "Erase all Add-ons of your vote target", + "KeeperInfo": "Reject the eject, Keeper protect!", "MayorInfo": "Your vote counts multiple times", "PsychicInfo": "One of the red names is evil", - "MechanicInfo": "Vent around and fix sabotages", + "MechanicInfo": "Vent around and fix Sabotages", "SheriffInfo": "Shoot the Impostors", "VigilanteInfo": "Not the hero we deserved but the hero we needed", "JailerInfo": "Jail suspicious players", - "CopyCatInfo": "Use kill button to copy target's role", + "CopyCatInfo": "Use your Kill button to copy a target's role", "SnitchInfo": "Finish your tasks to find the Impostors", "MarshallInfo": "Finish your tasks to prove your innocence", "DoctorInfo": "Know how each player died", @@ -523,21 +524,21 @@ "JudgeInfo": "Silence in the courtroom!", "MorticianInfo": "Locate dead bodies", "MediumInfo": "Talk with ghosts", - "ObserverInfo": "You can see all shield-animations", - "PacifistInfo": "Vent to reset kill cooldowns", + "ObserverInfo": "You can see all Shield Animations", + "PacifistInfo": "Vent to reset Kill Cooldowns", "RebirthInfo": "Arise Again", - "MonarchInfo": "Give your crew extra voting power!", + "MonarchInfo": "Give your Crew extra voting power!", "AbyssbringerInfo": "Place Black Holes", - "SpurtInfo": "Spring Like A rabbit!", - "StealthInfo": "Killing Blinds Everyone in the Room", + "SpurtInfo": "Spring like a rabbit!", + "StealthInfo": "Killing blinds everyone in the room", "PenguinInfo": "Drag your victims", "OverseerInfo": "Reveal roles of other players", "CoronerInfo": "Find corpses and their killers", "PresidentInfo": "You are in charge of the meeting", - "MerchantInfo": "Sell add-ons and bribe killers", - "RetributionistInfo": "Help the crew after you die", + "MerchantInfo": "Sell Add-ons and bribe killers", + "RetributionistInfo": "Help the Crew after you die", "HawkInfo": "Seek murdering the bad guys!", - "DeputyInfo": "Handcuff killers to increase their cooldowns", + "DeputyInfo": "Handcuff killers to increase their Cooldowns", "InvestigatorInfo": "Find potential evils", "GuardianInfo": "Complete your tasks to become immortal", "AddictInfo": "Vent to become invulnerable, or you'll die", @@ -548,12 +549,12 @@ "SpiritualistInfo": "Be guided by the ghostly life", "ChameleonInfo": "Vent to disguise into your surroundings", "InspectorInfo": "Validate the alignments of two players", - "CaptainInfo": "Sail with the Captain, lest add-ons be abandoned.", + "CaptainInfo": "Sail with the Captain, lest Add-ons be abandoned.", "AdmirerInfo": "Choose a player to side with you", "TimeMasterInfo": "Rewind time!", "CrusaderInfo": "Kill a player's attacker", "AltruistInfo": "Revive a player\nVent to change between Revive and Report", - "ReverieInfo": "With each kill, your cooldown decreases", + "ReverieInfo": "With each kill, your Cooldown decreases", "LookoutInfo": "See through disguises", "TelecommunicationInfo": "Track device usage", "LighterInfo": "Catch killers with your enhanced vision", @@ -561,14 +562,14 @@ "WitnessInfo": "Find out if someone killed recently", "GhastlyInfo": "Control somebody!", "SwapperInfo": "Swap the votes of two players", - "ChiefOfPoliceInfo": "Hire Sheriff to Serve the Crews!", + "ChiefOfPoliceInfo": "Hire Sheriffs to serve the Crewmates!", "NiceMiniInfo": "No one can hurt you until you grow up.", "ArsonistInfo": "Douse everyone and ignite", "PyromaniacInfo": "Douse and kill everyone", - "HuntsmanInfo": "Kill your targets for a low cooldown", + "HuntsmanInfo": "Kill your targets for a low Cooldown", "SpyInfo": "You know who interacts with you", "RandomizerInfo": "You're going to be someone's burden when you die?", - "EnigmaInfo": "Get Clues about Killers", + "EnigmaInfo": "Get clues about killers", "JesterInfo": "Get voted out", "OpportunistInfo": "Stay alive until the end", "TerroristInfo": "Finish your tasks, THEN die", @@ -590,10 +591,10 @@ "BloodKnightInfo": "Killing gives you a temporary shield", "PlagueBearerInfo": "Plague everyone to turn into Pestilence", "PestilenceInfo": "Obliterate everyone!", - "SoulCollectorInfo": "Predict deaths to collect souls", + "SoulCollectorInfo": "Predict deaths to collect Souls", "DeathInfo": "Enact Armageddon", - "BakerInfo": "Feed Players Bread to become Famine", - "FamineInfo": "Starve Everyone", + "BakerInfo": "Feed players bread to become Famine", + "FamineInfo": "Starve everyone", "BerserkerInfo": "Kill to increase your level", "WarInfo": "Destroy everything", "GlitchInfo": "Hack and kill everyone", @@ -601,7 +602,7 @@ "FollowerInfo": "Follow a player and help them", "CultistInfo": "Charm everyone", "SerialKillerInfo": "Kill off everyone to win!", - "JuggernautInfo": "With each kill, your cooldown decreases", + "JuggernautInfo": "With each kill, your Cooldown decreases", "InfectiousInfo": "Infect everyone", "VirusInfo": "Kill and infect everyone", "PursuerInfo": "Protect yourself and live to the end!", @@ -621,18 +622,18 @@ "SpiritcallerInfo": "Turn Players into Evil Spirits", "AmnesiacInfo": "Remember the role of a dead body", "ImitatorInfo": "Imitate a player's role", - "BanditInfo": "Rob a player's add-on", + "BanditInfo": "Rob a player's Add-on", "DoppelgangerInfo": "Steal your target's identity", "PunchingBagInfo": "Get attacked a few times to win!", "KamikazeInfo": "Kill players with a suicidal mission", "DoomsayerInfo": "Successfully guess players to win", "ShroudInfo": "Shroud players to make them kill", - "WerewolfInfo": "Kill crewmates in groups", + "WerewolfInfo": "Kill Crewmates in groups", "ShamanInfo": "Deflect all the attacks on Voodoo doll", - "SeekerInfo": "Play Hide and Seek with your target\nYour target has a ★ mark.", + "SeekerInfo": "Play Hide & Seek with your target\nYour target has a ★ mark.", "PixieInfo": "Tag 'em, Bag 'em, and Eject 'em!", "OccultistInfo": "Kill and curse your enemies", - "SchrodingersCatInfo": "The cat is both alive and dead until observed.", + "SchrodingersCatInfo": "The Cat is both alive and dead until observed.", "RomanticInfo": "Protect your partner to win together", "VengefulRomanticInfo": "Revenge your partner to win together", "RuthlessRomanticInfo": "Kill everyone to win with your partner", @@ -647,8 +648,8 @@ "LoversInfo": "Stay alive and win together", "MadmateInfo": "Help the Impostors", "WatcherInfo": "You see all the colors of votes", - "LastImpostorInfo": "Lower kill cooldown", - "OverclockedInfo": "Lower cooldown", + "LastImpostorInfo": "Lower Kill Cooldown", + "OverclockedInfo": "Lower Cooldown", "FlashInfo": "You're faster", "TorchInfo": "You have enhanced vision!", "SeerInfo": "You are alerted when somebody has died", @@ -656,14 +657,14 @@ "ObliviousInfo": "You can't report bodies", "BewilderInfo": "A twist of vision, a web of confusion", "WorkhorseInfo": "Be the first to complete all tasks and get more", - "FoolInfo": "You can't fix sabotages", + "FoolInfo": "You can't fix Sabotages", "AvangerInfo": "You take someone with you upon death", "YoutuberInfo": "Get killed first to win", "CelebrityInfo": "Everyone knows when you die", "EgoistInfo": "Win on your own", "StealerInfo": "Gain votes with kills", "ParanoiaInfo": "You're dead and alive simultaneously", - "MimicInfo": "Reveal killed players' roles to impostors upon death", + "MimicInfo": "Reveal killed players' roles to Impostors upon death", "GuesserInfo": "Guess roles of players in meetings to kill", "NecroviewInfo": "See the team of the dead", "ReachInfo": "You have a longer kill range", @@ -676,32 +677,32 @@ "LuckyInfo": "Dodge attackers", "DoubleShotInfo": "You have an extra life when guessing", "RascalInfo": "You appear evil in some cases", - "SoullessInfo": "You have no soul", + "SoullessInfo": "You have no Soul", "GravestoneInfo": "Your role is revealed when you die", "LazyInfo": "You're too lazy", "AutopsyInfo": "You see how others died", "LoyalInfo": "You cannot be recruited", - "EvilSpiritInfo": "You are an evil Spirit", + "EvilSpiritInfo": "You are an Evil Spirit", "RecruitInfo": "Help the Jackal", "AdmiredInfo": "The Admirer chose you as their love", "GlowInfo": "You glow in the dark", "RadarInfo": "Arrow's hue, closest to you!", - "DiseasedInfo": "Increase the cooldown of the player who interacts with you", - "AntidoteInfo": "Decrease the cooldown of the player who interacts with you", - "StubbornInfo": "Protect your role and add-ons", + "DiseasedInfo": "Increase the Cooldown of the player who interacts with you", + "AntidoteInfo": "Decrease the Cooldown of the player who interacts with you", + "StubbornInfo": "Protect your Role and Add-ons", "SwiftInfo": "Your kills don't cause a lunge", "UnluckyInfo": "Doing things has a chance to kill you", "VoidBallotInfo": "Your vote count is 0", "AwareInfo": "Know who revealed your role", - "FragileInfo": "Die instantly if someone uses the kill button on you", + "FragileInfo": "Die instantly if someone uses the Kill button on you", "GhoulInfo": "Kill your killer after dying", "BloodthirstInfo": "Become bloodthirsty and kill", "MareInfo": "Kill in the darkness", "BurstInfo": "Make your killer burst!", "SleuthInfo": "Gain info from dead bodies", "ClumsyInfo": "You have a chance to miss your kill", - "NimbleInfo": "You can vent!", - "CircumventInfo": "You can no longer vent", + "NimbleInfo": "You can Vent!", + "CircumventInfo": "You can no longer Vent", "OiiaiInfo": "OIIAIOIIIAI", "CyberInfo": "You're popular!", "HurriedInfo": "God, I got too much stuff!", @@ -720,251 +721,251 @@ "DollMasterInfo": "Take control of players actions!", "DoubleAgentInfo": "Plant bombs on players in meetings", "SlothInfo": "You're slower", - "ProhibitedInfo": "Certain vents are blocked", + "ProhibitedInfo": "Certain Vents are blocked", "EavesdropperInfo": "Listen in on other roles", "ShockerInfo": "Shock unsuspecting players", "RevenantInfo": "Take your killer's role", - "EngineerTOHEInfoLong": "(Crewmates):\nAs the Engineer, you may access the vents while Comms Sabotaged is inactive.", - "ScientistTOHEInfoLong": "(Crewmates):\nAs the Scientist, you can see vitals at any time, showing you who is alive and dead.", - "NoisemakerTOHEInfoLong": "(Crewmates):\nAs the Noisemaker, whenever you die, you will make a noise, and a visual indicator of your death appears on the screen so the Crewmates can run to catch the person who killed you red-handed (even if it’s not Red).", - "TrackerTOHEInfoLong": "(Crewmates):\nAs the Tracker, press your tracker button on a player to track their location via the map for a limited amount of time.", - "ShapeshifterTOHEInfoLong": "(Impostors):\nAs the Shapeshifter, you can shapeshift into other players. It is obvious when you shapeshift or revert shifting.", - "PhantomTOHEInfoLong": "(Impostors):\nAs the Phantom, you can press your vanish button to go invisible to escape a kill. You can click your appear button if you want to become visible before the timer runs out or not.\nNote: You will make a smoke cloud whenever you go invisible and become visible. So make sure you are in a safe area where no one will see you.", - "GuardianAngelTOHEInfoLong": "(Crewmates):\nAs the Guardian Angel, you are the first crewmate to die and can give Crewmates temporary shields.", - "ImpostorTOHEInfoLong": "(Impostors):\nAs the Impostor, your goal is to simply kill off the crewmates.\nYou can sabotage and vent.", + "EngineerTOHEInfoLong": "(Crewmates):\nAs the Engineer, you may access the Vents while Comms Sabotaged is inactive.", + "ScientistTOHEInfoLong": "(Crewmates):\nAs the Scientist, you can see Vitals at any time, showing you who is alive and dead.", + "NoisemakerTOHEInfoLong": "(Crewmates):\nAs the Noisemaker, whenever you die, you will make a noise, and a visual indicator of your death appears on the screen so the Crewmates can run to catch the person who killed you red-handed (even if it’s not red).", + "TrackerTOHEInfoLong": "(Crewmates):\nAs the Tracker, press your Tracker button on a player to track their location via the map for a limited amount of time.", + "ShapeshifterTOHEInfoLong": "(Impostors):\nAs the Shapeshifter, you can Shapeshift into other players. It is obvious when you Shapeshift or revert Shifting.", + "PhantomTOHEInfoLong": "(Impostors):\nAs the Phantom, you can press your Vanish button to go invisible to escape a kill. You can click your Appear button if you want to become visible before the timer runs out or not.\nNote: You will make a smoke cloud whenever you go invisible and become visible. So make sure you are in a safe area where no one will see you.", + "GuardianAngelTOHEInfoLong": "(Crewmates):\nAs the Guardian Angel, you are the first Crewmate to die and can give Crewmates temporary shields.", + "ImpostorTOHEInfoLong": "(Impostors):\nAs the Impostor, your goal is to simply kill off the Crewmates.\nYou can Sabotage and Vent.", "CrewmateTOHEInfoLong": "(Crewmates):\nAs the Crewmate, your goal is to find and exile the Impostors.\nCrewmates win by getting rid of all killers or by finishing all their tasks.", - "BountyHunterInfoLong": "(Impostors):\nAs the Bounty Hunter, if you kill your assigned Target (indicated by the arrow if you have one), your next kill cooldown will be shortened.\nIf you kill anyone other than your target, your next kill cooldown will be increased. The Target swaps after a certain amount of time.", - "FireworkerInfoLong": "(Impostors):\nAs the Fireworker, you can Shapeshift to place Fireworks up to the maximum amount the host sets.\nWhen you are the last Impostor and all Fireworks have been placed, shapeshift again to detonate them and kill everyone in their radius, including you.\nIf you kill all players with your Fireworks, it's considered an Impostor victory.", - "MercenaryInfoLong": "(Impostors):\nAs the Mercenary, you must kill within your Deadline, as shown by your Shapeshift cooldown (which you cannot use). If you fail to kill, you die.", - "ShapeMasterInfoLong": "(Impostors):\nAs the Shapemaster, you have no Shapeshift cooldown.", + "BountyHunterInfoLong": "(Impostors):\nAs the Bounty Hunter, if you kill your assigned target (indicated by the arrow if you have one), your next Kill Cooldown will be shortened.\nIf you kill anyone other than your target, your next Kill Cooldown will be increased. The target swaps after a certain amount of time.", + "FireworkerInfoLong": "(Impostors):\nAs the Fireworker, you can Shapeshift to place Fireworks up to the maximum amount the Host sets.\nWhen you are the last Impostor and all Fireworks have been placed, Shapeshift again to detonate them and kill everyone in their radius, including you.\nIf you kill all players with your Fireworks, it's considered an Impostor victory.", + "MercenaryInfoLong": "(Impostors):\nAs the Mercenary, you must kill within your Deadline, as shown by your Shapeshift Cooldown (which you cannot use). If you fail to kill, you die.", + "ShapeMasterInfoLong": "(Impostors):\nAs the Shapemaster, you have no Shapeshift Cooldown.", "VampireInfoLong": "(Impostors):\nAs the Vampire, your kills are delayed. This means that your target still dies even if a meeting is called first. However, if you bite a Bait, you kill normally and report the body. Depending on the settings, you can use double trigger (bite players - single click, kill normally - double click).", "WarlockInfoLong": "(Impostors):\nAs the Warlock, you can Curse up to one other player at a time.\nWhen you Shapeshift, if you have Cursed a player, they kill the nearest person, which, depending on settings, can include you or other Impostors.\nYou can kill normally while Shapeshifted.", - "ZombieInfoLong": "(Impostors):\nZombie has a short kill cooldown but moves very slowly and has very little vision. Zombie can not be voted out by anyone other than the Dictator, and the movement speed of Zombie will gradually slow down as they make kills or time passes.", - "NinjaInfoLong": "(Impostors):\nAs the Ninja, you can use your kill button to Mark a target (single click) or kill normally (double click). You may then Shapeshift to teleport to the Marked target and kill them.", + "ZombieInfoLong": "(Impostors):\nZombie has a short Kill Cooldown but moves very slowly and has very little vision. Zombie can not be voted out by anyone other than the Dictator, and the movement speed of Zombie will gradually slow down as they make kills or time passes.", + "NinjaInfoLong": "(Impostors):\nAs the Ninja, you can use your Kill button to mark a target (single click) or kill normally (double click). You may then Shapeshift to teleport to the marked target and kill them.", "AnonymousInfoLong": "(Impostors):\nAs the Anonymous, you can Shapeshift to force your target to report whoever you killed this round.\nIf you killed nobody that round, the target will report their own dead body as if they had died.\nNote: This does not work on Lazy nor Lazy Guy, and this ability will work regardless of whether the body can normally be reported.", - "MinerInfoLong": "(Impostors):\nAs the Miner, you can shapeshift to teleport back to the last vent you were in.", - "KillingMachineInfoLong": "(Impostors):\nAs the Killing Machine, you have a very short kill cooldown with tiny vision. However, you cannot vent, sabotage, report, nor call emergency meetings.\n\nNote: You will bypass any shields, killing bait and beartrap won't take any effect", - "EscapistInfoLong": "(Impostors):\nAs the Escapist, you can Mark a location by Shapeshifting. Shapeshift again to teleport back to the Marked spot", - "WitchInfoLong": "(Impostors):\nAs the Witch, you can use your kill button to Spell (single click) or kill normally (double click).\nDuring the next meeting, the spelled target(s) will have a 「†」 next to their name visible to everyone. Unless you die by the end of that meeting, all Spelled targets will die.", - "NemesisInfoLong": "(Impostors):\nAs the Nemesis, you can only kill if you are the last Impostor.\nIf you are dead, you can use the command /rv [ID] to kill the player whose ID you typed. Use /id to show the IDs of all players, or look next to their names.", - "BloodmoonInfoLong": "(Impostors [Ghost]):\nAs the Bloodmoon, attack the enemies to make them drip blood, this means they will die in a time set by the host, and will be aware of it.", + "MinerInfoLong": "(Impostors):\nAs the Miner, you can Shapeshift to teleport back to the last vent you were in.", + "KillingMachineInfoLong": "(Impostors):\nAs the Killing Machine, you have a very short Kill Cooldown with tiny vision. However, you cannot Vent, Sabotage, Report, nor call Emergency Meetings.\n\nNote: You will bypass any shields, killing bait and beartrap won't take any effect", + "EscapistInfoLong": "(Impostors):\nAs the Escapist, you can mark a location by Shapeshifting. Shapeshift again to teleport back to the marked spot", + "WitchInfoLong": "(Impostors):\nAs the Witch, you can use your Kill button to Spell (single click) or Kill normally (double click).\nDuring the next meeting, the spelled target(s) will have a 「†」 next to their name visible to everyone. Unless you die by the end of that meeting, all Spelled targets will die.", + "NemesisInfoLong": "(Impostors):\nAs the Nemesis, you can only kill if you are the last Impostor.\nIf you are dead, you can use the command /rv [ID] to kill the player whose ID you typed. Use /id to show the ID's of all players, or look next to their names.", + "BloodmoonInfoLong": "(Impostors [Ghost]):\nAs the Bloodmoon, attack the enemies to make them drip blood, this means they will die in a time set by the Host, and will be aware of it.", "PossessorInfoLong": "(Impostors [Ghost]):\nAs the Possessor, you can possess players when others aren't in the Alert Range. Lead the possessed player as far as possible from other players in the Focus Range. Once the possession duration is up, the possessed player will be killed if others aren't in the Focus Range. If you run into another player in the Alert Range while possessing, the Possessor will immediately unpossess.", - "PuppeteerInfoLong": "(Impostors):\nAs the Puppeteer, you can use your kill button to Puppeteer (single click) or kill normally (double click).\nThose you Puppeteer will kill the next non-Impostor they touch. Depending on options, Puppeteered targets will also die once they kill.", - "MastermindInfoLong": "(Impostors):\nAs the Mastermind, you can use your kill button on a player once to manipulate them. The manipulation does nothing if the target doesn't have a kill button. But if the target does have a kill button, whoever you manipulate will be told after a delay that they got manipulated and must kill someone in a limited time to survive. If the time limit expires or a meeting gets called before killing someone, they die.\nDouble click on someone to kill them normally.", - "YinYangerInfoLong": "(Impostors):\nAs the YinYanger, you can use your kill button one time to pick your Yin and then a second time to choose a Yang. When those two players meet, they'll kill each other. When Yin & Yang have been chosen, you can kill normally.", + "PuppeteerInfoLong": "(Impostors):\nAs the Puppeteer, you can use your Kill button to Puppeteer (single click) or kill normally (double click).\nThose you Puppeteer will kill the next non-Impostor they touch. Depending on options, Puppeteered targets will also die once they kill.", + "MastermindInfoLong": "(Impostors):\nAs the Mastermind, you can use your Kill button on a player once to manipulate them. The manipulation does nothing if the target doesn't have a Kill button. But if the target does have a Kill button, whoever you manipulate will be told after a delay that they got manipulated and must kill someone in a limited time to survive. If the time limit expires or a meeting gets called before killing someone, they die.\nDouble click on someone to kill them normally.", + "YinYangerInfoLong": "(Impostors):\nAs the YinYanger, you can use your Kill button one time to pick your Yin and then a second time to choose a Yang. When those two players meet, they'll kill each other. When Yin & Yang have been chosen, you can kill normally.", "TimeThiefInfoLong": "(Impostors):\nEvery time the Time Thief kills a player, the meeting time will be reduced by a certain amount of time. If the Time Thief dies, the meeting time will return to normal.", - "SniperInfoLong": "(Impostors):\nYou can shoot players from far away.\nYou have to shapeshift twice to make a successful snipe.\nImagine an arrow pointing from your first shapeshift location towards your unshift location.\nThat will be the direction in which the snipe will be made.\nThe snipe kills the first person in its path.\nYou cannot kill people normally until you use up all of your ammo.", + "SniperInfoLong": "(Impostors):\nYou can shoot players from far away.\nYou have to Shapeshift twice to make a successful snipe.\nImagine an arrow pointing from your first Shapeshift location towards your Unshift location.\nThat will be the direction in which the snipe will be made.\nThe snipe kills the first person in its path.\nYou cannot kill people normally until you use up all of your ammo.", "UndertakerInfoLong": "(Impostors):\nEverytime you Shapeshift, you mark the location. Your kills will then teleport to the marked location.\nAfter every kill and meeting, your marked location will reset.\n\nAfter every teleported kill, you will freeze for a configurable amount of time", - "RiftMakerInfoLong": "(Impostors):\nAs Rift Maker, you can shapeshift to create a rift. You can teleport from one rift to another by touching the area where the rift was created. Trying to vent will kick you out, therefore destroying all the rifts.\n\nNote: Up to two rifts can be placed at a time; if you try to place a third, it removes the first one.", - "EvilTrackerInfoLong": "(Impostors):\nThe Evil Tracker can track other players, and the Evil Tracker can shapeshift into someone to switch the tracking target to the shapeshift target (You will immediately unshift after performing shapeshift). The arrow below the Evil Tracker's name indicates the direction of the target. When the Evil Tracker's teammate kills, the Evil Tracker will see a kill flash.", - "EvilHackerInfoLong": "(Impostors):\nThe Evil Hacker can get the last-minute admin information at the meeting beginning.\nUnoccupied rooms are not shown.\nA '★' marks rooms with impostors.\nRooms with dead bodies are marked with the number of bodies.\nExample: ★Cafeteria: 3 (DEAD×1).", + "RiftMakerInfoLong": "(Impostors):\nAs Rift Maker, you can Shapeshift to create a rift. You can teleport from one rift to another by touching the area where the rift was created. Trying to vent will kick you out, therefore destroying all the rifts.\n\nNote: Up to two rifts can be placed at a time; if you try to place a third, it removes the first one.", + "EvilTrackerInfoLong": "(Impostors):\nThe Evil Tracker can track other players, and the Evil Tracker can Shapeshift into someone to switch the tracking target to the Shapeshift target (You will immediately unshift after performing Shapeshift). The arrow below the Evil Tracker's name indicates the direction of the target. When the Evil Tracker's teammate kills, the Evil Tracker will see a kill flash.", + "EvilHackerInfoLong": "(Impostors):\nThe Evil Hacker can get the last-minute admin information at the meeting beginning.\nUnoccupied rooms are not shown.\nA '★' marks rooms with Impostors.\nRooms with dead bodies are marked with the number of bodies.\nExample: ★Cafeteria: 3 (DEAD×1).", "EvilGuesserInfoLong": "(Impostors):\nThe Evil Guesser can guess the role of a certain player during the meeting. If correct, the target dies. If wrong, the Evil Guesser dies.\nThe guessing command is: /bt [player id] [role]\nYou can see the player's id before the player's name or use the /id command to view the id of all players.", - "AntiAdminerInfoLong": "(Impostors):\nThe Anti Adminer can at any time find out if there are crewmates or neutrals near Cameras, Admin Table, Vitals, DoorLog, and/or other devices. Note: Anti Adminer does not know if the player uses the device while near it. They only know that someone is near the device.", - "ArroganceInfoLong": "(Impostors):\nThe Arrogance reduces their kill cooldown with each successful kill of theirs.", - "BomberInfoLong": "(Impostors):\nThe Bomber can use the shapeshift button to self-explode, killing players within a certain range. But as a price, the Bomber will also die. Note: All players will see a kill flash when the Bomber explodes.", - "ScavengerInfoLong": "(Impostors):\nScavenger kills do not leave dead bodies behind. In addition, if the victim is a bait, no self-report will be made.", + "AntiAdminerInfoLong": "(Impostors):\nThe Anti Adminer can at any time find out if there are Crewmates or Neutrals near Cameras, Admin Table, Vitals, DoorLog, and/or other devices. Note: Anti Adminer does not know if the player uses the device while near it. They only know that someone is near the device.", + "ArroganceInfoLong": "(Impostors):\nThe Arrogance reduces their Kill Cooldown with each successful kill of theirs.", + "BomberInfoLong": "(Impostors):\nThe Bomber can use the Shapeshift button to self-explode, killing players within a certain range. But as a price, the Bomber will also die. Note: All players will see a kill flash when the Bomber explodes.", + "ScavengerInfoLong": "(Impostors):\nScavenger kills do not leave dead bodies behind. In addition, if the victim is a Bait, no self-report will be made.", "TrapsterInfoLong": "(Impostors):\nThe Trapster has a unique method of killing. By initiating a body report, the Trapster can eliminate the player attempting to report the body the Trapster killed.\nNote: If Trapster kills the Bait, the Trapster will die immediately.", - "GangsterInfoLong": "(Impostors):\nThe Gangster, a powerful character, can try to recruit a player to a Madmate by pressing the kill button. If the recruitment is successful, both the Gangster and the target will see the shield animation on each other as a reminder (only visible to each other). The remaining number of available recruits is displayed next to the Gangster's name (the Host sets the max). If the Gangster tries to recruit players who cannot be recruited, such as neutrals or some special crews, they will kill the target normally instead. When the Gangster has no remaining recruitments, they can only make normal kills from that point on.", - "CleanerInfoLong": "(Impostors):\nCleaner can press the Report button to clean up any dead body they come across (including those they kill). If the cleanup is successful, the Cleaner will see a shield animation on their body as a reminder (only visible to himself). The cleaned-up body cannot be reported (including bait).", - "LightningInfoLong": "(Impostors):\nAs the Lightning, you cannot kill normally. Instead, your kill button quantizes targets, which activates after a delay, causing the next person they encounter to kill them. Those who are actively quantized show a「■」next to their name. Additionally, those who have been quantized die if they survive until the end of a meeting. There is a setting to quantize your killer.", - "GreedyInfoLong": "(Impostors):\nGreedy kills with odd and even kills will have different kill cooldowns. Greedy's kill cooldown is reset every meeting, and Greedy's first kill is always odd.", - "CursedWolfInfoLong": "(Impostors):\nWhen the Cursed Wolf is about to be killed, the Cursed Wolf will curse the killer to death. (The Host sets the max of times you can counterattack)", - "SoulCatcherInfoLong": "(Impostors):\nAs the Soul Catcher, you can shapeshift to swap places with your target as long as they are not dead, in a vent, swallowed by pelican, or in a similar odd state.", - "QuickShooterInfoLong": "(Impostors):\nWhen the kill cooldown is over, Quick Shooter can reset the kill cooldown by shapeshift to store a bullet (when the storage is successful, a shield-animation visible only to himself will appear on their body as a reminder). If Quick Shooter has bullets, he can use one to bypass the kill cooldown; he will kill even if it's still on cooldown and use a bullet. At the beginning of each meeting, the quick shooter can only keep a certain number of bullets (The Host sets the number).", - "CamouflagerInfoLong": "(Impostors):\nWhen the Camouflager uses Shapeshift, all players start to look the same. This state ends when the Camouflager reverts its shapeshifting. It's important to note that the skills of communication sabotage camouflage, and the skills of the Camouflager can be superimposed.\nThis skill will be invalid if a meeting is held during the skill activation of the Camouflager.", - "EraserInfoLong": "(Impostors):\nEraser can vote for any crew target at the meeting to erase the target's roles, and the erasure will take effect after the meeting ends. Note: Players with erased skills will always be considered a vanilla role, including the game result page.\nA crew target can only be erased once (include Oiiai)", + "GangsterInfoLong": "(Impostors):\nThe Gangster, a powerful character, can try to recruit a player to a Madmate by pressing the Kill button. If the recruitment is successful, both the Gangster and the target will see the Shield Animation on each other as a reminder (only visible to each other). The remaining number of available recruits is displayed next to the Gangster's name (the Host sets the maximum). If the Gangster tries to recruit players who cannot be recruited, such as Neutrals or some special Crewmates, they will kill the target normally instead. When the Gangster has no remaining recruitments, they can only make normal kills from that point on.", + "CleanerInfoLong": "(Impostors):\nCleaner can press the Report button to clean up any dead body they come across (including those they kill). If the cleanup is successful, the Cleaner will see a Shield Animation on their body as a reminder (only visible to himself). The cleaned-up body cannot be reported (including Bait).", + "LightningInfoLong": "(Impostors):\nAs the Lightning, you cannot kill normally. Instead, your Kill button quantizes targets, which activates after a delay, causing the next person they encounter to kill them. Those who are actively quantized show a「■」next to their name. Additionally, those who have been quantized die if they survive until the end of a meeting. There is a setting to quantize your killer.", + "GreedyInfoLong": "(Impostors):\nGreedy kills with odd and even kills will have different Kill Cooldowns. Greedy's Kill Cooldown is reset every meeting, and Greedy's first kill is always odd.", + "CursedWolfInfoLong": "(Impostors):\nWhen the Cursed Wolf is about to be killed, the Cursed Wolf will curse the killer to death. (The Host sets the maximum of times you can counterattack)", + "SoulCatcherInfoLong": "(Impostors):\nAs the Soul Catcher, you can Shapeshift to swap places with your target as long as they are not dead, in a Vent, swallowed by Pelican, or in a similar odd state.", + "QuickShooterInfoLong": "(Impostors):\nWhen the Kill Cooldown is over, Quick Shooter can reset the Kill Cooldown by Shapeshift to store a bullet (when the storage is successful, a Shield Animation visible only to himself will appear on their body as a reminder). If Quick Shooter has bullets, he can use one to bypass the Kill Cooldown; he will kill even if it's still on Cooldown and use a bullet. At the beginning of each meeting, the quick shooter can only keep a certain number of bullets (The Host sets the number).", + "CamouflagerInfoLong": "(Impostors):\nWhen the Camouflager uses Shapeshift, all players start to look the same. This state ends when the Camouflager reverts its Shapeshifting. It's important to note that the skills of Communication Sabotage Camouflage, and the skills of the Camouflager can be superimposed.\nThis skill will be invalid if a meeting is held during the skill activation of the Camouflager.", + "EraserInfoLong": "(Impostors):\nEraser can vote for any target at the meeting to erase the target's roles, and the erasure will take effect after the meeting ends. Note: Players with erased skills will always be considered a vanilla role, including the game result page.\nA target can only be erased once (including OIIAI)", "ButcherInfoLong": "(Impostors):\nThe Butcher's kills, including passive ones, leave multiple dead bodies on targets, which can be a bit confusing when reporting. Here's the rule: the killed target must repeatedly display the animation of being killed, which cannot be skipped, and they cannot participate in the meeting normally during this period. And if the Butcher kills the Avenger, the Avenger will revenge everyone in anger.", - "HangmanInfoLong": "(Impostors):\nAs the Hangman, during the shapeshifting, you use a unique killing method-strangling. This method ignores any status of the target, such as the shield of the Medic, the Bodyguard's protection, the Super Star's skills, etc. The strangled player will not leave a dead body, nor will it trigger any of its skills. For example, Veteran kill back (including additional roles), and Seer will not be prompted.", - "SwooperInfoLong": "(Impostors):\nAs the Swooper, you can vent to vanish temporarily. You will still appear visible on your screen. Vent again to become visible.", + "HangmanInfoLong": "(Impostors):\nAs the Hangman, during the Shapeshifting, you use a unique killing method-strangling. This method ignores any status of the target, such as the shield of the Medic, the Bodyguard's protection, the Super Star's skills, etc. The strangled player will not leave a dead body, nor will it trigger any of its skills. For example, Veteran kill back (including additional roles), and Seer will not be prompted.", + "SwooperInfoLong": "(Impostors):\nAs the Swooper, you can Vent to Vanish temporarily. You will still appear visible on your screen. Vent again to become visible.", "CrewpostorInfoLong": "(Team Impostor):\nYou kill the nearest player whenever you finish a task.", - "WildlingInfoLong": "(Impostors):\nAs the Wildling, you can shapeshift but cannot vent.\nWhen you kill, you temporarily become immune to attacks.", - "TricksterInfoLong": "(Impostors):\nAs the Trickster, you function as a regular Impostor but with one key difference.\nYou appear as a crewmate to crewmate roles.\n\nThe Sheriff cannot kill you.\nPsychic does not see you as evil.\nSnitch cannot find you.", + "WildlingInfoLong": "(Impostors):\nAs the Wildling, you can Shapeshift but cannot Vent.\nWhen you kill, you temporarily become immune to attacks.", + "TricksterInfoLong": "(Impostors):\nAs the Trickster, you function as a regular Impostor but with one key difference.\nYou appear as a Crewmate to Crewmate roles.\n\nThe Sheriff cannot kill you.\nPsychic does not see you as evil.\nSnitch cannot find you.", "VindicatorInfoLong": "(Impostors):\nAs the Vindicator, you have extra votes like a Mayor.", "StealthInfoLong": "(Impostors):\nWhen the Stealth kills, players in the same room are blinded for a short time.", - "PenguinInfoLong": "(Impostors):\nAs the Penguin, you can restrain the target by pressing the kill button and drag it around.\nWhile dragging, the target dies by pressing the kill button again or after a certain period.\nPress the kill button twice for a direct kill.", - "ParasiteInfoLong": "(Team Impostor):\nAs the Parasite, you are an Impostor that does not know the other Impostors.\n\nYou may kill, vent, sabotage, whatever.\nJust know that you are an Impostor.", - "DisperserInfoLong": "(Impostors):\nDisperser can use Shapeshift to teleport all players to random vents.", - "InhibitorInfoLong": "(Impostors):\nAs the Inhibitor, you can only kill when there is not a critical sabotage active.\n\nIf light or comms sabotage is active, then you can kill.", - "SaboteurInfoLong": "(Impostors):\nAs the Saboteur, you can only kill when there is a critical sabotage active.\n\nIf reactor or O2 sabotage is active, then you can kill.", + "PenguinInfoLong": "(Impostors):\nAs the Penguin, you can restrain the target by pressing the Kill button and drag it around.\nWhile dragging, the target dies by pressing the Kill button again or after a certain period.\nPress the Kill button twice for a direct kill.", + "ParasiteInfoLong": "(Team Impostor):\nAs the Parasite, you are an Impostor that does not know the other Impostors.\n\nYou may Kill, Vent, Sabotage, whatever.\nJust know that you are an Impostor.", + "DisperserInfoLong": "(Impostors):\nDisperser can use Shapeshift to teleport all players to random Vents.", + "InhibitorInfoLong": "(Impostors):\nAs the Inhibitor, you can only kill when there is not a Critical Sabotage active.\n\nIf Light or Comms Sabotage is active, then you can kill.", + "SaboteurInfoLong": "(Impostors):\nAs the Saboteur, you can only kill when there is a Critical sabotage active.\n\nIf Reactor or O2 Sabotage is active, then you can kill.", "CouncillorInfoLong": "(Impostors):\nAs the Councillor, you can kill players during a meeting like a Judge.\nWhen killing in a meeting, those kills will appear as a trial from a Judge.\n\nThe kill command is /tl [player id]\nYou can see the player's id before the player's name, or use the /id command to view the id of all players.\nDepending on the settings, Councillor will suicide when he judge his teammates.\nConverted Councillor can judge freely.", "DazzlerInfoLong": "(Impostors):\nAs the Dazzler, you can reduce the vision of the target of your Shapeshift permanently. When you die, their vision will turn back to normal.", - "DeathpactInfoLong": "(Impostors):\nAs the Deathpact, You shapeshift to mark your targets for a deathpact.\nIf you have enough players marked for a death pact, they must meet within a specific period; if they fail to do so, they die.\nIf a marked player dies before the death pact becomes complete, the pact is withdrawn.", - "DevourerInfoLong": "(Impostors):\nAs the Devourer, you use your shapeshift to change the appearance of the target of the shapeshift permanently. Additionally, when each player's appearance changes, you will have your kill cooldown reduced by a defined number of seconds. If the Devourer dies or gets voted out during a meeting, the player's appearance will change back to their normal appearance.", - "MorphlingInfoLong": "(Impostors):\nAs the Morphling, you are a Shapeshifter but cannot kill while not shapeshifted.", - "TwisterInfoLong": "(Impostors):\nAs the Twister, you can use shapeshifting to swap the position of all players randomly. The swap happens twice, once when you start your shapeshift and once when you return to your original appearance.\nThe Twister itself will not swap places with anyone, and players in vents will not teleport.", - "LurkerInfoLong": "(Impostors):\nAs the Lurker, you can jump into a vent to reduce your cooldown by a certain number of seconds. After you kill, your cooldown resets to its original value.", + "DeathpactInfoLong": "(Impostors):\nAs the Deathpact, You Shapeshift to mark your targets for a deathpact.\nIf you have enough players marked for a deathpact, they must meet within a specific period; if they fail to do so, they die.\nIf a marked player dies before the deathpact becomes complete, the pact is withdrawn.", + "DevourerInfoLong": "(Impostors):\nAs the Devourer, you use your Shapeshift to change the appearance of the target of the Shapeshift permanently. Additionally, when each player's appearance changes, you will have your Kill Cooldown reduced by a defined number of seconds. If the Devourer dies or gets voted out during a meeting, the player's appearance will change back to their normal appearance.", + "MorphlingInfoLong": "(Impostors):\nAs the Morphling, you are a Shapeshifter but cannot kill while not Shapeshifted.", + "TwisterInfoLong": "(Impostors):\nAs the Twister, you can use Shapeshifting to swap the position of all players randomly. The swap happens twice, once when you start your Shapeshift and once when you return to your original appearance.\nThe Twister itself will not swap places with anyone, and players in vents will not teleport.", + "LurkerInfoLong": "(Impostors):\nAs the Lurker, you can jump into a Vent to reduce your Cooldown by a certain number of seconds. After you kill, your Cooldown resets to its original value.", "VisionaryInfoLong": "(Impostors):\nAs the Visionary, you see the alignments of living players during a meeting.\nThe following information will be displayed on the players:\n- The Red name indicates the Impostors.\n- The Cyan name indicates the Crewmates.\n- The Gray name indicates the Neutrals.", "PlagueDoctorInfoLong": "(Neutrals):\n(Plague Doctor from TOH)\nThe Plague Scientist's goal is to infect every living player.\nThey start by choosing one player to infect, after which anyone who spends a set amount of time in the range of the infected player becomes infected themselves.\nInfection progress is cumulative and does not reset with distance or after meetings.", - "RefugeeInfoLong": "(Madmates):\nAs the Refugee, you were either:\n -An Amnesiac who remembered an Impostor\n -A killer who killed the Godfather's target.\n -A Romantic whose partner was an Impostor\n -Or an Imitator that imitated an Impostor.\n\nNow your job is to help the Impostors kill the crewmates.", + "RefugeeInfoLong": "(Madmates):\nAs the Refugee, you were either:\n -An Amnesiac who remembered an Impostor\n -A killer who killed the Godfather's target.\n -A Romantic whose partner was an Impostor\n -Or an Imitator that imitated an Impostor.\n\nNow your job is to help the Impostors kill the Crewmates.", "UnderdogInfoLong": "(Impostors):\nAs the Underdog, you cannot kill until there's a certain amount of players alive.", - "ConsigliereInfoLong": "(Impostors):\nAs the Consigliere, you can reveal the roles of other players using your kill button.\n\nSingle click: Reveal role\nDouble click: Kill\n\nIf you run out of reveal uses, your kill button functions normally.", - "LudopathInfoLong": "(Impostors):\nAs the Ludopath, your kill cooldown is randomized.\n\nMinimum it can be is 1 second, while the maximum is your default kill cooldown.", + "ConsigliereInfoLong": "(Impostors):\nAs the Consigliere, you can reveal the roles of other players using your Kill button.\n\nSingle click: Reveal role\nDouble click: Kill\n\nIf you run out of reveal uses, your Kill button functions normally.", + "LudopathInfoLong": "(Impostors):\nAs the Ludopath, your Kill Cooldown is randomized.\n\nMinimum it can be is 1 second, while the maximum is your default Kill Cooldown.", "GodfatherInfoLong": "(Impostors):\nAs the Godfather, you vote someone to make them your target.\nIn the next round, if someone kills the target, the killer will turn into a Refugee or Madmate.", "ChronomancerInfoLong": "(Impostors):\nAs the Chronomancer, you have a charge bar which indicates when the slaughter is ready. When it is at 100% the next time you kill someone, you go into slaughter mode, meaning you can kill indefinitely until your bar runs out of charge. Otherwise, you have a normal KCD.", - "PitfallInfoLong": "(Impostors):\nAs the Pitfall, you use your shapeshift to mark the area around the shapeshift as a trap. Players who enter this area will be immobilized quickly, and their vision will be affected.", - "EvilMiniInfoLong": "(Impostors):\nAs the Evil Mini, you are unkillable until you grow up and have a very long initial kill cooldown, which gets drastically shortened as you grow up.", - "BlackmailerInfoLong": "(Impostors):\nAs the Blackmailer, when you shift into a target, you will blackmail that player. This means that during the meetings, they won't be able to speak.\n\nNote: If someone is already blackmailed, blackmailing another person un-blackmails the current person.", - "InstigatorInfoLong": "(Impostors):\nAs the Instigator, it's your job to turn the crewmates against each other. Each time a Crewmate gets voted out in a meeting, if you are alive, an additional Crewmate who voted for the innocent player will die after the meeting. The Host determines the number of additional players dying.", - "LazyGuyInfoLong": "(Crewmates):\nLazy Guy has only one task. In addition, the Impostor's abilities can't affect the Lazy Guy, such as being a scapegoat for Anonymous, being marked by a Warlock or Puppeteer, and more. Lazy Guy will not have any add-ons.", + "PitfallInfoLong": "(Impostors):\nAs the Pitfall, you use your Shapeshift to mark the area around the Shapeshift as a trap. Players who enter this area will be immobilized quickly, and their vision will be affected.", + "EvilMiniInfoLong": "(Impostors):\nAs the Evil Mini, you are unkillable until you grow up and have a very long initial Kill Cooldown, which gets drastically shortened as you grow up.", + "BlackmailerInfoLong": "(Impostors):\nAs the Blackmailer, when you Shift into a target, you will blackmail that player. This means that during the meetings, they won't be able to speak.\n\nNote: If someone is already blackmailed, blackmailing another person un-blackmails the current person.", + "InstigatorInfoLong": "(Impostors):\nAs the Instigator, it's your job to turn the Crewmates against each other. Each time a Crewmate gets voted out in a meeting, if you are alive, an additional Crewmate who voted for the innocent player will die after the meeting. The Host determines the number of additional players dying.", + "LazyGuyInfoLong": "(Crewmates):\nLazy Guy has only one task. In addition, the Impostor's abilities can't affect the Lazy Guy, such as being a scapegoat for Anonymous, being marked by a Warlock or Puppeteer, and more. Lazy Guy will not have any Add-ons.", "SuperStarInfoLong": "(Crewmates):\nThere will be a star logo next to the Super Star's name, so everyone knows who the Super Star is. The Super Star can only die when the murderer is alone with the Super Star (regular kills only). In addition, the Guessers can't guess the Super Star. ", "CelebrityInfoLong": "(Crewmates):\nAll Crewmates see the kill-flash when the Celebrity dies (same as the Seer sees the kill-flash) and get a notice at the next meeting. The Impostors don't know anything about this.", - "CleanserInfoLong": "(Crewmates):\nAs The Cleanser, you can vote to erase the add-ons of any target at the meeting. This erasure takes effect after the meeting ends. Depending on the settings, the cleansed player may never receive add-ons again.", + "CleanserInfoLong": "(Crewmates):\nAs The Cleanser, you can vote to erase the Add-ons of any target at the meeting. This erasure takes effect after the meeting ends. Depending on the settings, the cleansed player may never receive Add-ons again.", "KeeperInfoLong": "(Crewmates):\nAs keeper, you can vote for someone to protect them from being ejected. You can only do this a configurable number of times.", - "MayorInfoLong": "(Crewmates):\nAs the Mayor, you have extra votes. Depending on the settings, players can't see your extra votes, you can vent to call a meeting at any time, or you can have yourself revealed as Mayor upon task completion.", + "MayorInfoLong": "(Crewmates):\nAs the Mayor, you have extra votes. Depending on the settings, players can't see your extra votes, you can Vent to call a meeting at any time, or you can have yourself revealed as Mayor upon task completion.", "PsychicInfoLong": "(Crewmates):\nThe Psychic can see the names of several players highlighted in red during the meeting; at least one of them is evil. The Psychic will correctly see all Neutrals and Killing Crewmates displayed as red names when becoming a Madmate.", - "MechanicInfoLong": "(Crewmates):\nThe Mechanic can use the vent at any time. They can also fix Reactors, O2, and Communications using only one side. You can fix Lights by flicking only one switch. Opening a door will open all doors in the map.", - "SheriffInfoLong": "(Crewmates):\nSheriff has no task. The Sheriff can kill the Impostor (according to the host settings, the Sheriff can also kill neutrals). If the Sheriff tries to kill a crewmate, the Sheriff will kill himself. The Sheriff can kill anyone when he becomes a madmate (also according to the host settings).", - "VigilanteInfoLong": "(Crewmates):\nAs the Vigilante, you are tasked with eliminating potential threats to the Crew, but if they mistakenly kill an innocent crew member, they become a Madmate driven by guilt and remorse.\n\n Note: Gangster cannot convert Vigilante into madmate.", - "JailerInfoLong": "(Crewmates):\nAs the Jailer, use your kill button to lock a player in jail. During the next meeting, the jailed player cannot vote or get voted (the vote count will be 0). The Jailer may choose to execute the prisoner by voting for them. If the Jailer executes an innocent player, the Jailer loses the ability to execute for the rest of the game.\nIf the Jailer is evil, then they can execute anyone.\nThe Jailer has limited executions.\n\nNote: Jailed players cannot be guessed or judged, and jailed players can only guess Jailer.", + "MechanicInfoLong": "(Crewmates):\nThe Mechanic can use Vents at any time. They can also fix Reactors, O2, and Communications using only one side. You can fix Lights by flicking only one switch. Opening a door will open all doors in the map.", + "SheriffInfoLong": "(Crewmates):\nSheriff has no task. The Sheriff can kill the Impostor (according to the Host settings, the Sheriff can also kill Neutrals). If the Sheriff tries to kill a Crewmate, the Sheriff will kill himself. The Sheriff can kill anyone when he becomes a Madmate (also according to the Host settings).", + "VigilanteInfoLong": "(Crewmates):\nAs the Vigilante, you are tasked with eliminating potential threats to the Crewmates, but if they mistakenly kill an innocent Crew member, they become a Madmate driven by guilt and remorse.\n\n Note: Gangster cannot convert Vigilante into Madmate.", + "JailerInfoLong": "(Crewmates):\nAs the Jailer, use your Kill button to lock a player in jail. During the next meeting, the jailed player cannot vote or get voted (the vote count will be 0). The Jailer may choose to execute the prisoner by voting for them. If the Jailer executes an innocent player, the Jailer loses the ability to execute for the rest of the game.\nIf the Jailer is evil, then they can execute anyone.\nThe Jailer has limited executions.\n\nNote: Jailed players cannot be guessed or judged, and jailed players can only guess Jailer.", "SnitchInfoLong": "(Crewmates):\nAfter the Snitch completes all tasks, they can see the Impostor's names displayed in red on the meeting. When the Snitch has only one task left, the Impostors will see a 「★」 mark next to the name of themselves and the Snitch. When a Snitch becomes a Madmate, the 「★」 mark turns red.", - "MarshallInfoLong": "(Crewmates):\nAs the Marshall, complete your tasks to reveal yourself to the rest of the Crew.\nOther teams will not be able to see you.\nHowever, madmates CAN see you.", - "DoctorInfoLong": "(Crewmates):\nDoctor can see the cause of death for all players. In addition, the Doctor can access vitals wherever you are while he still has battery left.", + "MarshallInfoLong": "(Crewmates):\nAs the Marshall, complete your tasks to reveal yourself to the rest of the Crewmates.\nOther teams will not be able to see you.\nHowever, Madmates CAN see you.", + "DoctorInfoLong": "(Crewmates):\nDoctor can see the cause of death for all players. In addition, the Doctor can access Vitals wherever you are while he still has battery left.", "DictatorInfoLong": "(Crewmates):\nWhen the Dictator votes for someone, the meeting will end on the spot, and the player they voted for will be ejected from the meeting. The moment the Dictator votes someone out, the Dictator will also die.", "DetectiveInfoLong": "(Crewmate):\nAfter the Detective reports the body, they will receive a clue message, which will tell the Detective what the victim's role is. According to the Host's settings, the Detective may know what the murderer's role is. Note: Detective won't be Oblivious.", "UndercoverInfoLong": "(Crewmates):\nThe Impostors knows who Undercover is and sees him as a teammate, but Undercover himself does not know who the Impostors are.", - "NiceGuesserInfoLong": "(Crewmates):\nThe Nice Guesser can guess the role of a certain player during the meeting. If it is correct, it will kill the target, and if it is wrong, Nice Guesser will suicide.\nThe guessing command is: /bt [player id] [role]\nYou can see the player's id before the player's name or use the /id command to view the id of all players.\nNice Guesser can guess crewmate when become madmate.", - "GuessMasterInfoLong": "(Crewmates):\nAs the Guess Master, you will receive information about every attempted guess made during a meeting. You will be informed about the role the guesser tried to guess, and you will also be notified in case of a misguess.", + "NiceGuesserInfoLong": "(Crewmates):\nThe Nice Guesser can guess the role of a certain player during the meeting. If it is correct, it will kill the target, and if it is wrong, Nice Guesser will suicide.\nThe guessing command is: /bt [player id] [role]\nYou can see the player's id before the player's name or use the /id command to view the id of all players.\nNice Guesser can guess Crewmate when become Madmate.", + "GuessMasterInfoLong": "(Crewmates):\nAs the Guess Master, you will receive information about every attempted guess made during a meeting. You will be informed about the role the Guesser tried to guess, and you will also be notified in case of a misguess.", "KnightInfoLong": "(Crewmates):\nThe Knight has no tasks. They can kill anyone but only do it once the whole game.", - "TransporterInfoLong": "(Crewmates):\nWhenever the Transporter completes the task, two random players will switch positions, but if there are not enough players left, nothing will happen. Note: Players in the vent will not be selected.", + "TransporterInfoLong": "(Crewmates):\nWhenever the Transporter completes the task, two random players will switch positions, but if there are not enough players left, nothing will happen. Note: Players in a Vent will not be selected.", "TimeManagerInfoLong": "(Crewmates):\nThe more tasks the Time Manager does, the longer the meeting time will be. When the Time Manager dies, the meeting time will return to normal. When the Time Manager becomes a Madmate, the skill changes to reducing the meeting time instead of increasing it.", - "VeteranInfoLong": "(Crewmates):\nAs the Veteran, you can enter the alert state by venting. If a player tries to kill the Veteran in the alert state, the Veteran will kill the murderer instead. Veteran will see a shield animation on their body and a text above their head as a reminder when they enter and exit the alert state.", - "BastionInfoLong": "(Crewmates):\nAs the Bastion, bomb vents to kill off impostors and neutrals.\nBe careful though; crewmates can also be killed with the bombs.", - "CopyCatInfoLong": "(Crewmate):\nAs the Copycat, you can use your kill button to copy the target's role.\n\nYou can only copy some crewmate roles.\nIf you try to copy a madmate or rascal, you become the madmate variation of the target role.\nIf you target an evil with a crewmate variant, you'll become the crewmate variant.\n\nAdditionally, Your role will be set back to Copycat after every meeting.\nNote You can't guess people in meetings.", + "VeteranInfoLong": "(Crewmates):\nAs the Veteran, you can enter the alert state by Venting. If a player tries to kill the Veteran in the alert state, the Veteran will kill the murderer instead. Veteran will see a Shield Animation on their body and a text above their head as a reminder when they enter and exit the alert state.", + "BastionInfoLong": "(Crewmates):\nAs the Bastion, bomb Vents to kill off Impostors and Neutrals.\nBe careful though; Crewmates can also be killed with the bombs.", + "CopyCatInfoLong": "(Crewmate):\nAs the Copycat, you can use your Kill button to copy the target's role.\n\nYou can only copy some Crewmate roles.\nIf you try to copy a Madmate or Rascal, you become the Madmate variation of the target role.\nIf you target an evil with a Crewmate variant, you'll become the Crewmate variant.\n\nAdditionally, Your role will be set back to Copycat after every meeting.\nNote You can't guess people in meetings.", "BodyguardInfoLong": "(Crewmates):\nIf a player is about to be killed near the Bodyguard, the Bodyguard will prevent the kill and die with the murderer. The Bodyguard's skills will affect players of any team. When the Bodyguard becomes a Madmate, and the murderer is an Impostor, the Bodyguard will not activate the skill.", - "DeceiverInfoLong": "(Crewmates):\nThe Deceiver can sell the counterfeit to other players through the kill button. If the counterfeit is sold successfully, the Deceiver will see a shield animation on their body as a reminder. The counterfeit will take effect after the end of the next meeting. If the player with no kill ability holds the counterfeit, he will kill himself immediately. If the player with the killing ability has the counterfeit, he will commit suicide when he tries to kill someone next time.", - "GrenadierInfoLong": "(Crewmates):\nAs the Grenadier, you can vent to Flashbang players nearby, causing them to lose vision if they are an Impostor or, depending on settings, a Neutral.", + "DeceiverInfoLong": "(Crewmates):\nThe Deceiver can sell the counterfeit to other players through the Kill button. If the counterfeit is sold successfully, the Deceiver will see a Shield Animation on their body as a reminder. The counterfeit will take effect after the end of the next meeting. If the player with no kill ability holds the counterfeit, he will kill himself immediately. If the player with the killing ability has the counterfeit, he will commit suicide when he tries to kill someone next time.", + "GrenadierInfoLong": "(Crewmates):\nAs the Grenadier, you can Vent to Flashbang players nearby, causing them to lose vision if they are an Impostor or, depending on settings, a Neutral.", "MedicInfoLong": "(Crewmates):\nThe Medic can place a shield on the target by pressing the Kill button. The Medic can only give one shield for the whole game. Depending on the settings, the target's shield can or cannot deactivate when the Medic dies. The Medic can also see if someone is trying to break the target's shield.\nDepending on the Host's settings, the Medic or the target can see if the player has a shield (shown as a green circle 「●」 next to the name).", "FortuneTellerInfoLong": "(Crewmates):\nAs the Fortune Teller, vote for a player in a meeting to get a clue to their role.\nThe clue will relate to their actual role.\n\nWhen the Fortune Teller's tasks are complete, they will obtain the exact role rather than a clue!\n\nNote: If the setting to give random active players as a hint is on, you cannot check the same player multiple times.", "JudgeInfoLong": "(Crewmates):\nThe Judge can judge a certain player during the meeting. If the target is evil, the target will be killed (whether it is evil or not is set by the Host). If it is wrong, the Judge commits suicide.\nCommand for judgment: /tl [player id]\nYou can see the player's id before the player's name, or use the /id command to view the id of all players.\nJudges can judge all players when they become Madmate.\nIn meeting the ability count shows how many trails you have in this meeting. Out of meeting the ability counts shows how many trails you have for the whole game.", "MorticianInfoLong": "(Crewmates):\nThe Mortician can see arrows pointing to all dead bodies, and if the Mortician reports a body, they will know the last player the victim had contact with. Note: Mortician won't be Oblivious or Seer.", "MediumInfoLong": "(Crewmates):\nThe Medium can establish contact with a dead player after someone reports a dead body. The player who reports doesn't have to be the Medium. The dead player can answer once with a YES or a NO to the Medium's question, which only the Medium will see (the dead player can use /ms yes or /ms no). Note: Medium won't be Oblivious.", - "ObserverInfoLong": "(Crewmates):\nAs the Observer, you can see all shield animations caused by other players after the first meeting. The shied animations typically indicate a role ability, so look out for this.", + "ObserverInfoLong": "(Crewmates):\nAs the Observer, you can see all Shield Animations caused by other players after the first meeting. The shied animations typically indicate a role ability, so look out for this.", "MonarchInfoLong": "(Crewmates):\nAs the Monarch, you can knight players to give them an extra vote.\n\nYou cannot knight someone who already has multiple votes.\n\nKnighted players appear with a golden name.\nIf a knighted player is alive, the Monarch cannot be guessed or killed.", - "PacifistInfoLong": "(Crewmates):\nWhen the Pacifist vents, they will reset the kill cooldown for every player with a kill button. When they become a Madmate, this ability will only work on Crewmates.", - "OverseerInfoLong": "(Crewmates):\nAs The Overseer, you have minimal vision, but you can use your kill button to reveal the role of a nearby player. A 「○」 will be displayed next to the revealed target after you use the kill button on them, and you will also be scanning them (only you can see this). Stay near the target for a defined time to reveal his role; if you move too far away, the reveal will cancel.", + "PacifistInfoLong": "(Crewmates):\nWhen the Pacifist Vents, they will reset the Kill Cooldown for every player with a Kill button. When they become a Madmate, this ability will only work on Crewmates.", + "OverseerInfoLong": "(Crewmates):\nAs The Overseer, you have minimal vision, but you can use your Kill button to reveal the role of a nearby player. A 「○」 will be displayed next to the revealed target after you use the Kill button on them, and you will also be scanning them (only you can see this). Stay near the target for a defined time to reveal his role; if you move too far away, the reveal will cancel.", "CoronerInfoLong": "(Crewmates):\nAs a Coroner, you can't report corpses; instead, after trying to report the corpse, you will see an arrow leading you to the killer. If someone calls a meeting, the arrows disappear. Depending on the settings, players can't report the body you found.", "PresidentInfoLong": "(Crewmates):\nThe President has two abilities: End the meeting and Reveal identity.\n\n+ Ability 1: End the meeting - Type /finish in meetings as President to instantly end the meeting.\n+ Ability 2: Reveal identity - Type /reveal in meetings to reveal yourself. Revealing yourself will make it so every player can see that you are the President, and you will become unguessable after typing the command. However, after the President has revealed themselves, whoever killed the President will have their kill CD greatly reduced on their next kill.", - "MerchantInfoLong": "(Crewmates):\nAs a merchant, you sell a random add-on to a random player for each task you complete. Each add-on sold earns you money. If you have a certain amount of money, you can prevent the next killing attempt against you by bribing the murderer. The bribed player won't be able to kill you, but you don't know who it is. The money used is lost and not available for additional bribes.", + "MerchantInfoLong": "(Crewmates):\nAs a merchant, you sell a random Add-on to a random player for each task you complete. Each Add-on sold earns you money. If you have a certain amount of money, you can prevent the next killing attempt against you by bribing the murderer. The bribed player won't be able to kill you, but you don't know who it is. The money used is lost and not available for additional bribes.", "RetributionistInfoLong": "(Crewmates):\nAs the Retributionist, you can kill a limited amount of players after your death.\n\nUse /ret [playerID] to kill.", - "HawkInfoLong": "(Crewmates [Ghost]):\nAs the Hawk, you can kill a limited amount of players decided by the host, though there's a chance you miss, slicing someone multiple times increases the chances.", - "DeputyInfoLong": "(Crewmates):\nAs the Deputy, use your kill button to handcuff a player.\nThe player who is handcuffed will have their next kill attempt treated as a handcuff break, and the kill cooldown will be reset.\n\nIf the target does not have a kill button, then the handcuff was a waste.", - "InvestigatorInfoLong": "(Crewmates):\nAs an Investigator, you can use your kill button to investigate someone. When you investigate someone, their name will appear in red if they possess a kill button (impostor/SS basis) or light blue if they lack a kill button (crewmate/engineer/scientist basis). However, please note that the color of the names will return to normal when someone calls a meeting.", + "HawkInfoLong": "(Crewmates [Ghost]):\nAs the Hawk, you can kill a limited amount of players decided by the Host, though there's a chance you miss, slicing someone multiple times increases the chances.", + "DeputyInfoLong": "(Crewmates):\nAs the Deputy, use your Kill button to handcuff a player.\nThe player who is handcuffed will have their next kill attempt treated as a handcuff break, and the Kill Cooldown will be reset.\n\nIf the target does not have a Kill button, then the handcuff was a waste.", + "InvestigatorInfoLong": "(Crewmates):\nAs an Investigator, you can use your Kill button to investigate someone. When you investigate someone, their name will appear in red if they possess a Kill button (impostor/Shapeshifter basis) or light blue if they lack a Kill button (Crewmate/Engineer/Scientist basis). However, please note that the color of the names will return to normal when someone calls a meeting.", "GuardianInfoLong": "(Crewmates):\nAs the Guardian, you become immortal upon task completion. Guessers can't even guess you in meetings.", - "AddictInfoLong": "(Crewmates):\nAs the Addict, you have a suicide timer. When it expires, you kill yourself.\nThe timer is indicated by the vent cooldown. When the vent cooldown is 0 seconds, you still have a short time to vent.\nIf you don't make it, you die; if you make it, the suicide timer is reset.\nAlso after you vent, no one can interact with you for a defined period.\nAfter; the period is over, and you are immobilized for another defined period, and cannot report any bodies.", - "MoleInfoLong": "(Crewmates):\nAs the Mole, when you vent, you stay in the vent for 1 second. When you exit the vent, you will spawn near a random vent in the map (Except the one you used).", + "AddictInfoLong": "(Crewmates):\nAs the Addict, you have a suicide timer. When it expires, you kill yourself.\nThe timer is indicated by the Vent Cooldown. When the Vent Cooldown is 0 seconds, you still have a short time to Vent.\nIf you don't make it, you die; if you make it, the Suicide Timer is reset.\nAlso after you Vent, no one can interact with you for a defined period.\nAfter; the period is over, and you are immobilized for another defined period, and cannot Report any bodies.", + "MoleInfoLong": "(Crewmates):\nAs the Mole, when you Vent, you stay in the Vent for 1 second. When you exit the Vent, you will spawn near a random Vent in the map (Except the one you used).", "AlchemistInfoLong": "(Crewmates):\nAs the Alchemist, you brew potions when you complete tasks. The potion you made will show up under your role name with its corresponding description and instructions. You can get seven different potions, some with harmful or no effects. Vent to use the potion.", - "KamikazeInfoLong": "(Impostors):\nAs the Kamikaze you can single click to mark people. Double-click to kill normally. When you die, all marked also die, with death reason Targeted.", - "TracefinderInfoLong": "(Crewmates):\nAs the Tracefinder, you can access vitals at any time.\nIn addition, you get arrows pointing to dead bodies, with a delay set by the Host.", + "KamikazeInfoLong": "(Impostors):\nAs the Kamikaze you can single click to mark players. Double-click to kill normally. When you die, all marked also die, with death reason Targeted.", + "TracefinderInfoLong": "(Crewmates):\nAs the Tracefinder, you can access Vitals at any time.\nIn addition, you get arrows pointing to dead bodies, with a delay set by the Host.", "OracleInfoLong": "(Crewmates):\nAs the Oracle, you may vote a player during a meeting.\nYou'll see if they are a Crewmate, Neutral, or Impostor.\nDepending on settings, there can be a chance that your result will be incorrect.", "SpiritualistInfoLong": "(Crewmates):\nAs the Spiritualist, you get an arrow pointing towards the ghost of the last meeting's victim. There is an option for the arrow to disappear and reappear in intervals. Try to notify the ghost about your ability if you can; if they are on your side, they may lead you to an evil role so you can eject them. Be careful, as evil roles can do the same for Crewmates.", - "ChameleonInfoLong": "(Crewmates):\nAs the Chameleon, you can vent to Vanish temporarily. You will still appear visible on your screen. Vent again to become visible.", - "InspectorInfoLong": "(Crewmates):\nCheck If two players are in the same team or not. You will get an affirmation message if they are on the same team or a denial message if they are not on the same team.\n\nAll neutrals and converted players are counted in the same team. Trickster counts as Crew, and Rascal counts as Impostor.\nChecking command: /cmp [player id 1] [player id 2].", - "CaptainInfoLong": "(Crewmates):\nWith each completed task, the Captain gains the power to slow down a random non-crew role. Crewmates can see ☆besides Captain's name.\n\nIf anyone betrays the Captain's trust by voting Captain out, they will lose an add-on.", - "AdmirerInfoLong": "(Crewmates):\nAs the Admirer, admire a player to make them Crewmate aligned.\nThey'll win with crewmates and not their original team.\n\nYou can only do this once per player.", - "TimeMasterInfoLong": "(Crewmates):\nAs the Time Master, use the vents to mark everyone's position.\nWhen using the ability again, every alive player will rewind to the marked positions.\n\nDuring the ability duration, the Time Master gains a time shield, which protects them from death.", - "CrusaderInfoLong": "(Crewmates):\nAs the Crusader, use your kill button to crusade a player.\nIf that player gets attacked, you'll kill the attacker.", - "AltruistInfoLong": "(Crewmates):\nAs the Altruist, you can sacrifice yourself to revive a dead body using the «Report» button.\nNote: If a dead player has left the game, you report that body normally.\nAlso revived player cannot report self dead body\nUse vent button to change between Report & Revive.", - "ReverieInfoLong": "(Crewmates):\nAs the Reverie, you can kill, but your cooldown starts high.\n\nIt increases if you kill a crewmate and reduces otherwise.\nDepending on the Host's setting, you may misfire on reaching the max kill cooldown, and your target dies with you. \n\nYou win with other crewmates.", - "LookoutInfoLong": "(Crewmates):\nAs the Lookout, you can see the IDs of every player at all times.\nThis allows you to see through shapeshifts and camouflages.", - "TelecommunicationInfoLong": "(Crewmates):\nAs the Telecommunication, you are notified when anyone uses cameras, vitals, door logs, or admin.", - "LighterInfoLong": "(Crewmate):\nAs the Lighter, you can vent to increase your vision temporarily.\nYou have increased vision both when lights are not out and when lights are out.\nUse this power to catch sneaky killers!", + "ChameleonInfoLong": "(Crewmates):\nAs the Chameleon, you can Vent to Vanish temporarily. You will still appear visible on your screen. Vent again to become visible.", + "InspectorInfoLong": "(Crewmates):\nCheck If two players are in the same team or not. You will get an affirmation message if they are on the same team or a denial message if they are not on the same team.\n\nAll Neutrals and converted players are counted in the same team. Trickster counts as Crewmate, and Rascal counts as Impostor.\nChecking command: /cmp [player id 1] [player id 2].", + "CaptainInfoLong": "(Crewmates):\nWith each completed task, the Captain gains the power to slow down a random non-Crewmate role. Crewmates can see ☆besides Captain's name.\n\nIf anyone betrays the Captain's trust by voting Captain out, they will lose an Add-on.", + "AdmirerInfoLong": "(Crewmates):\nAs the Admirer, admire a player to make them Crewmate aligned.\nThey'll win with Crewmates and not their original team.\n\nYou can only do this once per player.", + "TimeMasterInfoLong": "(Crewmates):\nAs the Time Master, use the Vents to mark everyone's position.\nWhen using the ability again, every alive player will rewind to the marked positions.\n\nDuring the ability duration, the Time Master gains a time shield, which protects them from death.", + "CrusaderInfoLong": "(Crewmates):\nAs the Crusader, use your Kill button to crusade a player.\nIf that player gets attacked, you'll kill the attacker.", + "AltruistInfoLong": "(Crewmates):\nAs the Altruist, you can sacrifice yourself to revive a dead body using the «Report» button.\nNote: If a dead player has left the game, you report that body normally.\nAlso revived player cannot report self dead body\nUse the Vent button to change between Report & Revive.", + "ReverieInfoLong": "(Crewmates):\nAs the Reverie, you can kill, but your Cooldown starts high.\n\nIt increases if you kill a Crewmate and reduces otherwise.\nDepending on the Host's setting, you may misfire on reaching the maximum Kill Cooldown, and your target dies with you. \n\nYou win with other Crewmates.", + "LookoutInfoLong": "(Crewmates):\nAs the Lookout, you can see the ID's of every player at all times.\nThis allows you to see through Shapeshifts and Camouflages.", + "TelecommunicationInfoLong": "(Crewmates):\nAs the Telecommunication, you are notified when anyone uses Cameras, Vitals, Door Logs, or Admin.", + "LighterInfoLong": "(Crewmate):\nAs the Lighter, you can Vent to increase your vision temporarily.\nYou have increased vision both when lights are not out and when lights are out.\nUse this power to catch sneaky killers!", "TaskManagerInfoLong": "(Crewmates):\nYou see the total number of tasks completed (by everyone all together) next to your role name, which updates in real-time.", - "WitnessInfoLong": "(Crewmates):\nAs the Witness, when you use your kill button on someone, you will know if they killed in the last X seconds or not. (X depends on the settings).", - "SwapperInfoLong": "(Crewmates):\nAs the Swapper, you can swap votes in meetings.\n\nTo swap votes, use '/sw [playerID]' twice.\n\nPlayer IDs are displayed next to player names in meetings, but you can also use /id to get a list of all player IDs.\n\nNote: Depending on the Host's settings, you can exchange your own votes.", - "ChiefOfPoliceInfoLong": "(Crewmates):\nAs the Chief of Police,you can recruit a player to be a Sheriff(only once per game).\nDepending on the settings,you may recruit non-Crewmates or players without a kill button.\nYou may die when you recruit a wrong player.", + "WitnessInfoLong": "(Crewmates):\nAs the Witness, when you use your Kill button on someone, you will know if they killed in the last X seconds or not. (X depends on the settings).", + "SwapperInfoLong": "(Crewmates):\nAs the Swapper, you can swap votes in meetings.\n\nTo swap votes, use '/sw [playerID]' twice.\n\nPlayer ID's are displayed next to player names in meetings, but you can also use /id to get a list of all player ID's.\n\nNote: Depending on the Host's settings, you can exchange your own votes.", + "ChiefOfPoliceInfoLong": "(Crewmates):\nAs the Chief of Police, you can recruit a player to be a Sheriff(only once per game).\nDepending on the settings, you may recruit non-Crewmates or players without a Kill button.\nYou may suicide when you recruit a wrong player.", "NiceMiniInfoLong": "(Crewmates):\nAs a Nice Mini, your survival is crucial. You can't be killed until you grow up, and if you die or are evicted from the meeting before you grow up, everyone loses. This unique role adds a new dynamic to the game, where your survival is not just for your benefit but for the entire Crew's success.", - "SpyInfoLong": "(Crewmates):\nAs the Spy, when someone uses their kill button on you (any ability used through the kill button), you'll see their name in orange for a few seconds.\nNote: If a Crewmate used their ability on you, you'll also see them with an orange name!\nNote: If you cannot use left, you won't see orange names!\nNote: If the kill button interaction is blocked, the player's cooldown will reset to 10s'", - "RandomizerInfoLong": "(Crewmates):\nAs this Randomizer, when you die, your killer will do one of the following:\n 1. self-report your body\n 2. stand next to your body\n 3. have their kill cooldown set to 600s\n 4. Randomly avenge a player.", - "ArsonistInfoLong": "(Neutrals):\nThe Arsonist can douse a player by clicking the kill button on the player and following them for a few seconds. When the dousing starts and it's successful, a shield animation will happen as a reminder (only visible to themselves). When the Arsonist has doused all surviving players, the Arsonist can vent to start the fire and win alone.\n\nIf the player name shows 「△」, that means they are being doused;\nif the player name shows 「▲」, it means they have been completely doused.\nDepending on the setting, Arsonist may start the fire anytime. But if he fails to kill everyone, he loses.", + "SpyInfoLong": "(Crewmates):\nAs the Spy, when someone uses their Kill button on you (any ability used through the Kill button), you'll see their name in orange for a few seconds.\nNote: If a Crewmate used their ability on you, you'll also see them with an orange name!\nNote: If you cannot use left, you won't see orange names!\nNote: If the Kill button interaction is blocked, the player's Cooldown will reset to 10s'", + "RandomizerInfoLong": "(Crewmates):\nAs this Randomizer, when you die, your killer will do one of the following:\n 1. self-report your body\n 2. stand next to your body\n 3. have their Kill Cooldown set to 600s\n 4. Randomly avenge a player.", + "ArsonistInfoLong": "(Neutrals):\nThe Arsonist can douse a player by clicking the Kill button on the player and following them for a few seconds. When the dousing starts and it's successful, a Shield Animation will happen as a reminder (only visible to themselves). When the Arsonist has doused all surviving players, the Arsonist can Vent to start the fire and win alone.\n\nIf the player name shows 「△」, that means they are being doused;\nif the player name shows 「▲」, it means they have been completely doused.\nDepending on the setting, Arsonist may start the fire anytime. But if he fails to kill everyone, he loses.", "EnigmaInfoLong": "(Crewmates):\nAs the Enigma, you get a random clue about the killer each meeting. Depending on the settings, you may have to report the body to receive a clue. The more tasks you complete, the more precise the clues get.", - "PyromaniacInfoLong": "(Neutrals):\nAs the Pyromaniac, you can douse players (single click) or kill normally (double click). Dousing players do nothing immediately, but killing a doused player will significantly shorten your kill cooldown. To win, be the last player alive.", - "HuntsmanInfoLong": "(Neutrals):\nAs the Huntsman, you are given a certain number of targets that reset every meeting. If you successfully eliminate one of your targets, your kill cooldown goes down permanently by the set amount. However, if you kill someone not one of your targets, your kill cooldown permanently increases by the set amount. A colored name indicates your targets.", + "PyromaniacInfoLong": "(Neutrals):\nAs the Pyromaniac, you can douse players (single click) or kill normally (double click). Dousing players do nothing immediately, but killing a doused player will significantly shorten your Kill Cooldown. To win, be the last player alive.", + "HuntsmanInfoLong": "(Neutrals):\nAs the Huntsman, you are given a certain number of targets that reset every meeting. If you successfully eliminate one of your targets, your Kill Cooldown goes down permanently by the set amount. However, if you kill someone not one of your targets, your Kill Cooldown permanently increases by the set amount. A colored name indicates your targets.", "MiniInfoLong": "(Crewmate or Impostor):\nThe Mini has two roles. A Nice or Evil Mini is chosen.\n\nUse'/r nice mini' and '/r evil mini' respectively for more details.", "JesterInfoLong": "(Neutrals):\nIf the Jester gets voted out, the Jester wins the game alone. If the Jester is still alive at the end of the game, the Jester loses. Note: Jester, Executioner, and Innocent can win together.", "TerroristInfoLong": "(Neutrals):\nIf the Terrorist dies after completing all tasks, the Terrorist wins the game alone. (They can win by either being voted out or killed).", "ExecutionerInfoLong": "(Neutrals):\nThe Executioner is a role with an execution target, indicated by a diamond symbol「♦」next to their name. If the execution target is killed, the Executioner's role will change to Crewmate, Jester, or Opportunist, depending on the game settings. However, if the execution target is voted out in the meeting, the Executioner wins. Note: Jester, Executioner, and Innocent can win together.", "LawyerInfoLong": "(Neutrals):\nLawyer has a target to defend, which will be indicated by a diamond 「♦」 next to their name.\nIf your target wins, you win.\nIf they lose, you lose.", "OpportunistInfoLong": "(Neutrals):\nIf the Opportunist survives at the end of the game, the Opportunist will win with the winning player.", - "VectorInfoLong": "(Neutrals):\nVector will win alone by venting a certain number of times.", - "JackalInfoLong": "(Neutrals):\nAs the Jackal, you win if you are the last player alive. Additionally, you may recruit using the kill button. If the target is not one you can recruit, you have run out of uses, or you don't have the option to recruit, then you will kill people normally (i.e., don't use kill buttons in front of others thinking it'll recruit). If the target has a kill button and the option to turn into a Sidekick is on, they will become a Sidekick. Otherwise, they will gain the Recruit add-on if the option to give the Recruit add-on is on.\nDepending on the settings, when Jackal was killed, a Sidekick will be randomly selected as the new Jackal.\nRecruit may be selected if no sidekick is alive.", + "VectorInfoLong": "(Neutrals):\nVector will win alone by Venting a certain number of times.", + "JackalInfoLong": "(Neutrals):\nAs the Jackal, you win if you are the last player alive. Additionally, you may recruit using the Kill button. If the target is not one you can recruit, you have run out of uses, or you don't have the option to recruit, then you will kill people normally (i.e., don't use Kill buttons in front of others thinking it'll recruit). If the target has a Kill button and the option to turn into a Sidekick is on, they will become a Sidekick. Otherwise, they will gain the Recruit Add-on if the option to give the Recruit Add-on is on.\nDepending on the settings, when Jackal was killed, a Sidekick will be randomly selected as the new Jackal.\nRecruit may be selected if no Sidekick is alive.", "GodInfoLong": "(Neutrals):\nAs the God, you know everyone's role from the beginning. If you live until the end of the game, you steal the win, i.e., everyone else loses, and you win.", - "InnocentInfoLong": "(Neutrals):\nThe Innocent can use the kill button to plant any player, and the planted target will immediately kill the Innocent. If the target gets voted out in the meeting, the Innocent wins. Note: Jester, Executioner, and Innocent can win together.", - "PelicanInfoLong": "(Neutrals):\nAs the Pelican, you can use the kill button to swallow a player alive, teleporting them off-bounds but not killing them yet. Those swallowed will only die if you're still alive at the end of the round. If you die or leave during the round, all alive swallowed players will spawn into the map where you were.", - "RevolutionistInfoLong": "(Neutrals):\nAs the Revolutionist, you can recruit players by clicking the kill button on the player and following them until the shield animation plays for you. Recruiting has a chance, set by the Host, to kill players (though they are still recruited). When the required number of players are recruited (displayed next to your name), you must vent within the specified time to win the game immediately with all your recruits. If you do not vent in time, you lose and die.", - "HaterInfoLong": "(Neutrals):\nAs the Hater, you have no kill cooldown. However, depending on the settings, you can only kill Lovers and other recruiting roles and add-ons. Killing anyone else will make you suicide. You win at the end of the game with the winning team if none of the killable roles are alive. You will not be Lovers.", + "InnocentInfoLong": "(Neutrals):\nThe Innocent can use the Kill button to plant any player, and the planted target will immediately kill the Innocent. If the target gets voted out in the meeting, the Innocent wins. Note: Jester, Executioner, and Innocent can win together.", + "PelicanInfoLong": "(Neutrals):\nAs the Pelican, you can use the Kill button to swallow a player alive, teleporting them off-bounds but not killing them yet. Those swallowed will only die if you're still alive at the end of the round. If you die or leave during the round, all alive swallowed players will spawn into the map where you were.", + "RevolutionistInfoLong": "(Neutrals):\nAs the Revolutionist, you can recruit players by clicking the Kill button on the player and following them until the Shield Animation plays for you. Recruiting has a chance, set by the Host, to kill players (though they are still recruited). When the required number of players are recruited (displayed next to your name), you must Vent within the specified time to win the game immediately with all your recruits. If you do not Vent in time, you lose and die.", + "HaterInfoLong": "(Neutrals):\nAs the Hater, you have no Kill Cooldown. However, depending on the settings, you can only kill Lovers and other Recruiting Roles and Add-ons. Killing anyone else will make you suicide. You win at the end of the game with the winning team if none of the killable roles are alive. You will not be Lovers.", "DemonInfoLong": "(Neutrals):\nAs the Demon, you kill by draining health. You see health in percentage near everyone's name, and every attack you make drains a percentage from that health without the victim knowing. Once you drain your victim's health to 0, they die. You win if you are the last one standing.", - "StalkerInfoLong": "(Neutrals):\nThe Stalker can kill anyone, and every kill will immediately cause a Lights sabotage (if Lights sabotage is already active, nothing will happen). Stalker cannot vent. If the Impostor wins while the Stalker is alive or the Crewmate wins by killing the Impostors (according to the Host's setting, the Stalker may also win when the Crewmate wins by killing the Neutrals), then the Stalker wins alone.", + "StalkerInfoLong": "(Neutrals):\nThe Stalker can kill anyone, and every kill will immediately cause a Lights Sabotage (if Lights Sabotage is already active, nothing will happen). Stalker cannot Vent. If the Impostor wins while the Stalker is alive or the Crewmate wins by killing the Impostors (according to the Host's setting, the Stalker may also win when the Crewmate wins by killing the Neutrals), then the Stalker wins alone.", "WorkaholicInfoLong": "(Neutrals):\nAs the Workaholic, you win alone when you complete all tasks. Depending on the Host's settings, you can only win if you are alive and or revealed to everyone at the beginning (these settings are rarely both on).", - "SolsticerInfoLong": "(Neutrals):\nAs the Solsticer, you won't die, and you win by finishing all your tasks in a single round. After every meeting finishes, your tasks reset, and you need to start all over again.\nVotes on the Solsticer will be directly canceled.\nKill attempts on the Solsticer will teleport it out of the map like Pelican until the meeting is finished.\nThe killer's kill cooldown will be reset to 10 seconds.\nSolsticer is counted as nothing in-game.", + "SolsticerInfoLong": "(Neutrals):\nAs the Solsticer, you won't die, and you win by finishing all your tasks in a single round. After every meeting finishes, your tasks reset, and you need to start all over again.\nVotes on the Solsticer will be directly canceled.\nKill attempts on the Solsticer will teleport it out of the map like Pelican until the meeting is finished.\nThe killer's Kill Cooldown will be reset to 10 seconds.\nSolsticer is counted as nothing in-game.", "CollectorInfoLong": "(Neutrals):\nAs the Collector, when you vote for a player, for each other player that voted for them, you gain a point. When you collect the required votes, the game ends, and you win alone, even if you voted a Jester or Executioner's target out.", - "GlitchInfoLong": "(Neutrals):\nAs the Glitch, you can hack players (single click) or kill normally (double click).\nThose who have been hacked cannot kill, vent, or report for the hack duration.\nAdditionally, calling a sabotage other than doors will have no effect and will instead disguise you as a random player. You cannot disguise during or after sabotages.\nTo win, be the last player alive.", + "GlitchInfoLong": "(Neutrals):\nAs the Glitch, you can hack players (single click) or kill normally (double click).\nThose who have been hacked cannot kill, Vent, or report for the hack duration.\nAdditionally, calling a Sabotage other than doors will have no effect and will instead disguise you as a random player. You cannot disguise during or after Sabotages.\nTo win, be the last player alive.", "SidekickInfoLong": "(Neutrals):\nAs the Sidekick, your job is to help the Jackal kill everyone.\nYou and the Jackal win together.\nDepending on the settings, you may turn into Jackal if old Jackal was killed.\nYou may not be able to kill until old Jackal is dead.", - "ProvocateurInfoLong": "(Neutrals):\nAs the Provocateur, you can kill any target with the kill button. If the target loses at the end of the game, the Provocateur wins with the winning team.", - "BloodKnightInfoLong": "(Neutrals):\nThe Blood Knight wins when they're the last killing role alive, and the amount of crewmates is lower or equal to the amount of Blood Knights. The Blood Knight gains a temporary shield after every kill, making them immortal for a few seconds.", - "PlagueBearerInfoLong": "(Apocalypse):\nAs the Plaguebearer, plague everyone using your kill button to turn into Pestilence.\nOnce you turn into Pestilence, you will become immortal and gain the ability to kill, and you will kill anyone who tries to kill you.\n\nAlso, when infected players interact with uninfected players, they will also be infected.", + "ProvocateurInfoLong": "(Neutrals):\nAs the Provocateur, you can kill any target with the Kill button. If the target loses at the end of the game, the Provocateur wins with the winning team.", + "BloodKnightInfoLong": "(Neutrals):\nThe Blood Knight wins when they're the last killing role alive, and the amount of Crewmates is lower or equal to the amount of Blood Knights. The Blood Knight gains a temporary shield after every kill, making them immortal for a few seconds.", + "PlagueBearerInfoLong": "(Apocalypse):\nAs the Plaguebearer, plague everyone using your Kill button to turn into Pestilence.\nOnce you turn into Pestilence, you will become immortal and gain the ability to kill, and you will kill anyone who tries to kill you.\n\nAlso, when infected players interact with uninfected players, they will also be infected.", "PestilenceInfoLong": "(Apocalypse):\nAs Pestilence, you're an unstoppable machine.\nAny attack towards you will be reflected towards them.\nIndirect kills don't even kill you.\n\nOnly way to kill Pestilence is by voting them out or the Pestilence misguessing.\nYour presence is announced to everyone at the meeting after you transform.", - "SoulCollectorInfoLong": "(Apocalypse):\nAs Soul Collector, you can use your kill button on a player to predict their death. You will gain a soul if your target dies in the round you select them or the meeting after.\nYour target resets after each meeting or after they die, whichever comes first. \n\nOnce you collect the configurable amount of souls, you become Death. If the gain passive souls setting is enabled, you will gain a soul each meeting.", + "SoulCollectorInfoLong": "(Apocalypse):\nAs Soul Collector, you can use your Kill button on a player to predict their death. You will gain a Soul if your target dies in the round you select them or the meeting after.\nYour target resets after each meeting or after they die, whichever comes first. \n\nOnce you collect the configurable amount of Souls, you become Death. If the gain passive Souls setting is enabled, you will gain a Soul each meeting.", "DeathInfoLong": "(Apocalypse):\nOnce the Soul Collector has collected their needed souls, they become Death. Death kills everyone and wins if Death is not ejected by the end of the next meeting.\nA configurable amount of extra meeting time will be given on the meeting Death transforms to have more discussion to find Death.\n\nYou are invincible, and your presence is announced to everyone at the meeting after you transform.", - "BakerInfoLong": "(Apocalypse):\nAs the Baker, you can use your kill button on a player per round to give them bread. \nOnce a set amount of players are alive with bread, you become Famine.\n\nIf the Bread gives additional effects and the setting is on, then you can vent to change the bread that you give out. \nBread Effects:\nReveal: Reveals the target's role to the Baker (stays the whole game)\nRoleblock: Resets the target's kill cooldown when they try to use their kill button\nBarrier: Gives the target a barrier that is only known to the Baker (barrier is removed after the meeting)", - "FamineInfoLong": "(Apocalypse):\nOnce the Baker has a set amount of people with bread alive, they will become Famine. If the Famine does not get voted out after the meeting, then they will become Famine, and every player without bread will starve (excluding other Apocalypse members).\nAfter this starvation of everyone without bread, Famine can use their kill button to starve any remaining players, which will kill those players right before the next meeting.\n\nYou are invincible, and your presence is announced to everyone at the meeting after you transform.", + "BakerInfoLong": "(Apocalypse):\nAs the Baker, you can use your Kill Button on a player per round to give them bread. \nOnce a set amount of players are alive with bread, you become Famine.\n\nIf the Bread gives additional effects and the setting is on, then you can Vent to change the bread that you give out. \nBread Effects:\nReveal: Reveals the target's role to the Baker (stays the whole game)\nRoleblock: Resets the target's Kill Cooldown when they try to use their Kill Button\nBarrier: Gives the target a Barrier that is only known to the Baker (Barrier is removed after the meeting)", + "FamineInfoLong": "(Apocalypse):\nOnce the Baker has a set amount of people with bread alive, they will become Famine. If the Famine does not get voted out after the meeting, then they will become Famine, and every player without bread will starve (excluding other Apocalypse members).\nAfter this starvation of everyone without bread, Famine can use their Kill Button to starve any remaining players, which will kill those players right before the next meeting.\n\nYou are invincible, and your presence is announced to everyone at the meeting after you transform.", "BerserkerInfoLong": "(Apocalypse):\nAs the Berserker, you level up with each kill.\nUpon reaching a certain level defined by the Host, you unlock a new power.\n\nScavenged kills make your kills disappear.\nBombed kills make your kills explode. Be careful when killing, as this can kill your other Apocalypse members if they are near. \nAfter a certain level, you become War.", - "WarInfoLong": "(Apocalypse):\nAs War, you are invincible, have a lower kill cooldown, and can kill anyone with your previous powers.\nYour presence is announced to everyone at the meeting after you transform.", - "FollowerInfoLong": "(Neutrals):\nThe Follower can use their Kill button on someone to start following them and can use the Kill button again to switch the following target. If the Follower's target wins, the Follower will win along with them. Note: The Follower can also win after they die.", - "CultistInfoLong": "(Neutrals):\nAs the Cultist, your kill button is used to Charm others, making them win with you. To win, charm all who pose a threat and gain the majority.\nDepending on settings, you may be able to charm Neutrals, and those you Charm may count as their original team, nothing, or a Cultist to determine when you win due to majority.", + "WarInfoLong": "(Apocalypse):\nAs War, you are invincible, have a lower Kill Cooldown, and can kill anyone with your previous powers.\nYour presence is announced to everyone at the meeting after you transform.", + "FollowerInfoLong": "(Neutrals):\nThe Follower can use their Kill Button on someone to start following them and can use the Kill Button again to switch the following target. If the Follower's target wins, the Follower will win along with them. Note: The Follower can also win after they die.", + "CultistInfoLong": "(Neutrals):\nAs the Cultist, your Kill Button is used to Charm others, making them win with you. To win, charm all who pose a threat and gain the majority.\nDepending on settings, you may be able to charm Neutrals, and those you Charm may count as their original team, nothing, or a Cultist to determine when you win due to majority.", "SerialKillerInfoLong": "(Neutrals):\nAs the Serial Killer, you win if you are the last player alive.", - "JuggernautInfoLong": "(Neutrals):\nAs the Juggernaut, your kill cooldown decreases with each kill you make.\n\nKill everyone to win.", + "JuggernautInfoLong": "(Neutrals):\nAs the Juggernaut, your Kill Cooldown decreases with each kill you make.\n\nKill everyone to win.", "InfectiousInfoLong": "(Neutrals):\nAs the Infectious, your job is to infect as many players as you can.\n\nIf you infect all the killers, you can outnumber the Crew and win the game.\n\nIf you die, all the players you've infected will die after the next meeting.\nIf they achieve your win condition before then, you can still win.", - "VirusInfoLong": "(Neutrals):\nThe task of the Virus is to kill or infect all other players. When the Virus murders a crewmate, their corpse is infected with a virus. The Crewmate who reports this corpse is infected joins the virus team or dies at the end of the meeting if the Virus doesn't get voted out, depending on the settings. If more players are on the Virus team than the Crewmate team, the Virus team wins.", + "VirusInfoLong": "(Neutrals):\nThe task of the Virus is to kill or infect all other players. When the Virus murders a Crewmate, their corpse is infected with a virus. The Crewmate who reports this corpse is infected joins the virus team or dies at the end of the meeting if the Virus doesn't get voted out, depending on the settings. If more players are on the Virus team than the Crewmate team, the Virus team wins.", "PursuerInfoLong": "(Neutrals):\nAs the Pursuer, you can use your ability on someone to make them misfire when they try to kill.\n\nTo win, survive to the end of the game.", "SpecterInfoLong": "(Neutrals):\nAs the Specter, your job is to get killed and finish your tasks.\nYou can do your tasks while alive.\nYou cannot win if you're alive.\nIf you get killed, you win with the winning team if your tasks are completed.", - "PirateInfoLong": "(Neutrals):\nAs the Pirate, use your kill button to select a target every round.\nYou will duel with your target in the next meeting. \nIf both the Pirate and the target choose the same number, the Pirate wins.\nAdditionally, if the Pirate wins the duel or the target doesn't participate in the duel, the Pirate kills the target.\n\nDueling command: /duel X (where X can be 0, 1, or 2)\n\nYou win after winning a certain number of duels set by the Host.\n\nNote: The kill would not count towards pirate victory if the target did not participate in the duel.", - "AgitaterInfoLong": "(Neutrals):\nAs the Agitator, your premise is essentially Hot Potato.\n\nUse your kill button on a player to pass the bomb.\nThis can only be done once per round.\n\nThe player who receives the bomb will be notified when receiving said bomb, in which they need to pass it to another player by getting near a player.\n\nWhen a meeting is called, the player with the bomb dies.\n\nIf trying to pass to Pestilence or a Veteran on alert, the bombed player dies instead.\nOptionally, the Agitator cannot receive the bomb.", - "MaverickInfoLong": "(Neutrals):\nAs the Maverick, you can kill and, depending on options, vent and have impostor vision\nIf you survive until the end of the game, you win with the winning team.\nUse your killing ability to eliminate threats to your life, but don't get voted out.", - "CursedSoulInfoLong": "(Neutrals):\nAs the Cursed Soul, you steal the victory if you survive to the end of the game.\n\nYou can steal the win from a Jester or Executioner.\n\nAdditionally, you can steal the souls of other players.\nSoulless players win with you and count as dead.", + "PirateInfoLong": "(Neutrals):\nAs the Pirate, use your Kill Button to select a target every round.\nYou will duel with your target in the next meeting. \nIf both the Pirate and the target choose the same number, the Pirate wins.\nAdditionally, if the Pirate wins the duel or the target doesn't participate in the duel, the Pirate kills the target.\n\nDueling command: /duel X (where X can be 0, 1, or 2)\n\nYou win after winning a certain number of duels set by the Host.\n\nNote: The kill would not count towards pirate victory if the target did not participate in the duel.", + "AgitaterInfoLong": "(Neutrals):\nAs the Agitator, your premise is essentially Hot Potato.\n\nUse your Kill Button on a player to pass the bomb.\nThis can only be done once per round.\n\nThe player who receives the bomb will be notified when receiving said bomb, in which they need to pass it to another player by getting near a player.\n\nWhen a meeting is called, the player with the bomb dies.\n\nIf trying to pass to Pestilence or a Veteran on alert, the bombed player dies instead.\nOptionally, the Agitator cannot receive the bomb.", + "MaverickInfoLong": "(Neutrals):\nAs the Maverick, you can kill and, depending on options, Vent and have Impostor vision\nIf you survive until the end of the game, you win with the winning team.\nUse your killing ability to eliminate threats to your life, but don't get voted out.", + "CursedSoulInfoLong": "(Neutrals):\nAs the Cursed Soul, you steal the victory if you survive to the end of the game.\n\nYou can steal the win from a Jester or Executioner.\n\nAdditionally, you can steal the Souls of other players.\nSoulless players win with you and count as dead.", "PickpocketInfoLong": "(Neutrals):\nAs the Pickpocket, you steal votes from your kills.\n\nKill everyone to win.", "TraitorInfoLong": "(Neutrals):\nAs the Traitor, you were an Impostor that betrayed the Impostors.\nYou know the Impostors, but they don't know you.\nThe twist? They can kill you, but you can't kill them.\n\nEliminate the Impostors by other means, then kill everyone else to win!", - "TrollerInfoLong": "(Neutrals):\nAs a Troller, you can complete tasks so that random events can happen to players.\nFor example, changing the speed of all players, teleportation, influencing sabotage, etc.\nAlso you can win with the winning team.", - "VultureInfoLong": "(Neutrals):\nAs the Vulture, report bodies to win!\n\nWhen you report a body, if your eat cooldown is up, you'll eat the body (makes it unreportable).\nIf your eat ability is still on cooldown, then you'll report the body normally.\n\nAdditionally, you'll report bodies normally if the maximum bodies eaten per round is reached.", + "TrollerInfoLong": "(Neutrals):\nAs a Troller, you can complete tasks so that random events can happen to players.\nFor example, changing the speed of all players, teleportation, influencing Sabotage, etc.\nAlso you can win with the winning team.", + "VultureInfoLong": "(Neutrals):\nAs the Vulture, report bodies to win!\n\nWhen you report a body, if your Eat Cooldown is up, you'll eat the body (makes it unreportable).\nIf your eat ability is still on Cooldown, then you'll report the body normally.\n\nAdditionally, you'll report bodies normally if the maximum bodies eaten per round is reached.", "AbyssbringerInfoLong": "(Impostors):\nAs the Abyssbringer, you can place black holes. Black holes will suck in players and kill them when colliding with them.", - "TaskinatorInfoLong": "(Neutrals):\nAs the Taskinator, whenever you finish a task, the task will be bombed. When another player completes the bombed task, the bomb will detonate, and the player will die.\n\nYou win if you survive till the end and Crew doesn't win.\n\n Note: Taskinator bombs ignore all protection.", + "TaskinatorInfoLong": "(Neutrals):\nAs the Taskinator, whenever you finish a task, the task will be bombed. When another player completes the bombed task, the bomb will detonate, and the player will die.\n\nYou win if you survive till the end and Crewmates don't win.\n\n Note: Taskinator bombs ignore all protection.", "BenefactorInfoLong": "(Crewmates):\nAs the Benefactor, whenever you finish a task, that task will be marked. When another player completes the marked task, they get a temporary shield.\n\n Note: Shield only protects from direct kill attacks.", "MedusaInfoLong": "(Neutrals):\nAs the Medusa, you can stone bodies much like cleaning a body.\nStoned bodies cannot be reported.\n\nKill everyone to win.", "SpiritcallerInfoLong": "(Neutrals):\nAs the Spiritcaller, your victims become Evil Spirits after they die. These spirits can help you win by freezing other players briefly or blocking their vision. Alternatively, the spirits can give you a shield that protects you briefly from an attempted kill.", - "AmnesiacInfoLong": "(Neutrals):\nAs the Amnesiac, use your report button to remember a target and get its role.\nTo balance the game, you will not be able to vent after remembering your role if you can't vent as Amnesiac.'", - "ImitatorInfoLong": "(Neutrals):\nAs the Imitator, use your kill button to imitate a player.\n\nYou'll either become a Sheriff, a Refugee, or some Neutral.", - "BanditInfoLong": "(Neutrals):\nAs the Bandit, you can click your kill button one time to steal a player's addon and twice to kill. Depending on the settings, you may instantly steal the addon or after the meeting starts. After the maximum number of steals is reached, you will kill normally. Additionally, if there are no stealable addons on the target or the target is stubborn, you will kill the target.\n\nKill everyone to win.\n\nNote: Cleansed, Last Impostor, and Lovers cannot be stolen.\nNote: If Bandit can vent is on, Nimble will become unstealable.", - "DoppelgangerInfoLong": "(Neutrals):\nAs the Doppelganger, use your kill button to steal a player's identity (their name and skin) and then kill your target.\n\nKill everyone to win.\n\nNote: You cannot steal the target's identity when Camouflage is active.", + "AmnesiacInfoLong": "(Neutrals):\nAs the Amnesiac, use your report button to remember a target and get its role.\nTo balance the game, you will not be able to Vent after remembering your role if you can't Vent as Amnesiac.'", + "ImitatorInfoLong": "(Neutrals):\nAs the Imitator, use your Kill button to imitate a player.\n\nYou'll either become a Sheriff, a Refugee, or some Neutral.", + "BanditInfoLong": "(Neutrals):\nAs the Bandit, you can click your Kill button one time to steal a player's Add-on and twice to kill. Depending on the settings, you may instantly steal the Add-on or after the meeting starts. After the maximum number of steals is reached, you will kill normally. Additionally, if there are no stealable Add-ons on the target or the target is Stubborn, you will kill the target.\n\nKill everyone to win.\n\nNote: Cleansed, Last Impostor, and Lovers cannot be stolen.\nNote: If Bandit can Vent is on, Nimble will become unstealable.", + "DoppelgangerInfoLong": "(Neutrals):\nAs the Doppelganger, use your Kill button to steal a player's identity (their name and skin) and then kill your target.\n\nKill everyone to win.\n\nNote: You cannot steal the target's identity when Camouflage is active.", "PunchingBagInfoLong": "(Neutrals):\nAs the Punching Bag, your goal is to get attacked a few times to win.\n\nYou cannot be guessed, as that adds to your attack count.", - "DoomsayerInfoLong": "(Neutrals):\nThe Doomsayer can guess the role of a certain player during the meeting.\nIf the Doomsayer guesses a certain number of roles (the number depends on the host settings), then he wins.\nThe guessing command is: /bt [player id] [role]\nYou can see the player's id before the player's name, or use the /id command to view the id of all players.", - "ShroudInfoLong": "(Neutrals):\nAs the Shroud, you do not kill normally.\nInstead, use your kill button to shroud a player.\nShrouded players kill others.\nIf the shrouded player doesn't make a kill, they'll kill themselves after a meeting.\n\nShroud sees shrouded players with a 「◈」mark next to their name.\nShrouded players who did not make a kill will also have the 「◈」mark in meetings, where they'll die if the Shroud is alive by the end of the meeting.", - "WerewolfInfoLong": "(Neutrals):\nAs the Werewolf, you can kill much like any killer.\nHowever, when you kill, any nearby players also die.\nAny player who dies to this will have their death reason as Mauled.\n\nTo balance this, you have a higher kill cooldown than anyone else.", - "ShamanInfoLong": "(Neutrals):\nAs the Shaman, you can use your kill button to select a voodoo doll once per round. If the kill button is used on you, the effect will be deflected onto the voodoo doll.\nIf you survive until the end, you win with the winning team.\nNote: If the killer cannot kill the chosen target, murder is canceled, but if the killer rechecks the Shaman, the killer will kill the Shaman.", - "SeekerInfoLong": "(Neutrals):\nAs the seeker, use your kill button to tag the target. If the seeker tags the wrong player, a point is deducted, and if the seeker tags the correct player, a point will be added.\nAdditionally, the seeker will not be able to move for 5 seconds after every meeting and after getting a new target.\n\nThe seeker needs to collect a certain number of points set by the Host to win.\nSeeker will see a ★ mark on target's name.", - "PixieInfoLong": "(Neutrals):\nAs the Pixie, Mark up to x amount of targets each round by using the kill button on them. You must have one of the marked targets ejected when the meeting starts. If unsuccessful, you will commit suicide, except if you didn't mark any targets or all the targets are dead. The selected targets reset to 0 after the meeting ends. If you succeed, you will gain a point. You see all your targets in colored names.\n\nYou win with the winning team when you have certain amounts of points set by the Host.", - "SchrodingersCatInfoLong": "(Neutrals):\nAs Schrodingers Cat, if someone attempts to use the kill button on you, you will block the action and join their team. This blocking ability works only once. By default, you don't have a victory condition, meaning you win only after switching teams.\nIn Addition to this, you will be counted as nothing in the game.\n\nNote: If the killing machine attempts to use its kill button on you, the interaction is not blocked, and you will die.", - "RomanticInfoLong": "(Neutrals):\nThe Romantic can pick their lover partner using their kill button (this can be done at any point of the game). Once they've picked their partner, they can use their kill button to give their partner a temporary shield that protects them from attacks. If their lover partner dies, the Romantic's role will change according to the following conditions:\n1. If their partner was an Impostor, the Romantic becomes the Refugee\n2. If their partner was a Neutral Killer, then they become Ruthless Romantic.\n3. If their partner was a Crewmate or a non-killing neutral, the Romantic becomes the Vengeful Romantic. \n\nThe Romantic wins with the winning team if their partner wins.\nNote: If your role changes, your win condition will be changed accordingly", - "RuthlessRomanticInfoLong": "(Neutrals):\nYou change your roles from Romantic if your partner (A neutral killer) is killed. As a Ruthless Romantic, you win if you kill everyone and are the last one standing. If you win, your dead partner will also win with you.", - "VengefulRomanticInfoLong": "(Neutrals):\nYou change your roles from Romantic if your partner (A crew or non-neutral killer) is killed. As a Vengeful Romantic, your goal is to avenge your partner, which means you must kill the killer of your partner. If you succeed, then you and your partner win with the winning team at the end. If you try to kill someone other than your partner's killer, then you will die by misfire.", + "DoomsayerInfoLong": "(Neutrals):\nThe Doomsayer can guess the role of a certain player during the meeting.\nIf the Doomsayer guesses a certain number of roles (the number depends on the Host settings), then he wins.\nThe guessing command is: /bt [player id] [role]\nYou can see the player's id before the player's name, or use the /id command to view the id of all players.", + "ShroudInfoLong": "(Neutrals):\nAs the Shroud, you do not kill normally.\nInstead, use your Kill button to shroud a player.\nShrouded players kill others.\nIf the shrouded player doesn't make a kill, they'll kill themselves after a meeting.\n\nShroud sees shrouded players with a 「◈」mark next to their name.\nShrouded players who did not make a kill will also have the 「◈」mark in meetings, where they'll die if the Shroud is alive by the end of the meeting.", + "WerewolfInfoLong": "(Neutrals):\nAs the Werewolf, you can kill much like any killer.\nHowever, when you kill, any nearby players also die.\nAny player who dies to this will have their death reason as Mauled.\n\nTo balance this, you have a higher Kill Cooldown than anyone else.", + "ShamanInfoLong": "(Neutrals):\nAs the Shaman, you can use your Kill button to select a voodoo doll once per round. If the Kill button is used on you, the effect will be deflected onto the voodoo doll.\nIf you survive until the end, you win with the winning team.\nNote: If the killer cannot kill the chosen target, murder is canceled, but if the killer rechecks the Shaman, the killer will kill the Shaman.", + "SeekerInfoLong": "(Neutrals):\nAs the Seeker, use your Kill button to tag the target. If the Seeker tags the wrong player, a point is deducted, and if the Seeker tags the correct player, a point will be added.\nAdditionally, the Seeker will not be able to move for 5 seconds after every meeting and after getting a new target.\n\nThe Seeker needs to collect a certain number of points set by the Host to win.\nSeeker will see a ★ mark on target's name.", + "PixieInfoLong": "(Neutrals):\nAs the Pixie, Mark up to x amount of targets each round by using the Kill button on them. You must have one of the marked targets ejected when the meeting starts. If unsuccessful, you will commit suicide, except if you didn't mark any targets or all the targets are dead. The selected targets reset to 0 after the meeting ends. If you succeed, you will gain a point. You see all your targets in colored names.\n\nYou win with the winning team when you have certain amounts of points set by the Host.", + "SchrodingersCatInfoLong": "(Neutrals):\nAs Schrodingers Cat, if someone attempts to use the Kill button on you, you will block the action and join their team. This blocking ability works only once. By default, you don't have a victory condition, meaning you win only after switching teams.\nIn Addition to this, you will be counted as nothing in the game.\n\nNote: If the Killing Machine attempts to use their Kill button on you, the interaction is not blocked, and you will die.", + "RomanticInfoLong": "(Neutrals):\nThe Romantic can pick their lover partner using their Kill button (this can be done at any point of the game). Once they've picked their partner, they can use their Kill button to give their partner a temporary shield that protects them from attacks. If their lover partner dies, the Romantic's role will change according to the following conditions:\n1. If their partner was an Impostor, the Romantic becomes the Refugee\n2. If their partner was a Neutral Killer, then they become Ruthless Romantic.\n3. If their partner was a Crewmate or a non-killing Neutral, the Romantic becomes the Vengeful Romantic. \n\nThe Romantic wins with the winning team if their partner wins.\nNote: If your role changes, your win condition will be changed accordingly", + "RuthlessRomanticInfoLong": "(Neutrals):\nYou change your roles from Romantic if your partner (A Neutral killer) is killed. As a Ruthless Romantic, you win if you kill everyone and are the last one standing. If you win, your dead partner will also win with you.", + "VengefulRomanticInfoLong": "(Neutrals):\nYou change your roles from Romantic if your partner (A Crewmate or non-Neutral killer) is killed. As a Vengeful Romantic, your goal is to avenge your partner, which means you must kill the killer of your partner. If you succeed, then you and your partner win with the winning team at the end. If you try to kill someone other than your partner's killer, then you will die by misfire.", "PoisonerInfoLong": "(Neutrals):\nAs the Poisoner, your kills are delayed.\nKill everyone to win.", "HexMasterInfoLong": "(Neutrals):\nAs the Hex Master, you can hex players or kill them.\nHexing a player works the same as spelling as a Witch.", - "WraithInfoLong": "(Neutrals):\nAs the Wraith, you can vent to Vanish temporarily. You will still appear visible on your screen. Vent again to become visible. You win if you are the last player remaining.", + "WraithInfoLong": "(Neutrals):\nAs the Wraith, you can Vent to Vanish temporarily. You will still appear visible on your screen. Vent again to become visible. You win if you are the last player remaining.", "JinxInfoLong": "(Neutrals):\nAs the Jinx, whenever you get attacked, you jinx them, resulting in them dying to a jinx.\nThis has limited uses.\n\nKill off everyone to win.", - "PotionMasterInfoLong": "(Neutrals):\nAs the Potion Master, you have three different potions assigned to three different actions.\n\nSingle click: Reveal role\nDouble click: Kill\nMap: Sabotage\n\nThe reveal potion has a limit.\nWhen you run out, the kill buttons default to killing.", - "NecromancerInfoLong": "(Neutrals):\nAs the Necromancer, you win when you're the last one standing.\nAdditionally when someone tries to kill you, you will block the kill, and you will teleport to a random vent. You will have a limited time to kill your killer. If you succeed in doing so, you live. If the time runs out before you kill your killer, you die permanently. If you try to kill someone else other than your killer, you will die.", - "ShockerInfoLong": "(Neutrals):\nAs the Shocker, you can mark rooms by doing tasks in them, and then vent to Electrocute anyone in those rooms for a set period of time. When you finish all of your tasks, you get new ones. Note: Doing tasks during that period will mark them for the next ability use.", - "LastImpostorInfoLong": "(Add-ons):\nThis special effect is given to the last surviving Impostor. It significantly reduces their kill cooldown.", - "OverclockedInfoLong": "(Add-ons):\nAs the Overclocked, your kill cooldown is reduced by a percentage.\n\nThis feature is only assigned to roles with a kill button.", + "PotionMasterInfoLong": "(Neutrals):\nAs the Potion Master, you have three different potions assigned to three different actions.\n\nSingle click: Reveal role\nDouble click: Kill\nMap: Sabotage\n\nThe reveal potion has a limit.\nWhen you run out, the Kill buttons default to killing.", + "NecromancerInfoLong": "(Neutrals):\nAs the Necromancer, you win when you're the last one standing.\nAdditionally when someone tries to kill you, you will block the kill, and you will teleport to a random Vent. You will have a limited time to kill your killer. If you succeed in doing so, you live. If the time runs out before you kill your killer, you die permanently. If you try to kill someone else other than your killer, you will die.", + "ShockerInfoLong": "(Neutrals):\nAs the Shocker, you can mark rooms by doing tasks in them, and then Vent to Electrocute anyone in those rooms for a set period of time. When you finish all of your tasks, you get new ones. Note: Doing tasks during that period will mark them for the next ability use.", + "LastImpostorInfoLong": "(Add-ons):\nThis special effect is given to the last surviving Impostor. It significantly reduces their Kill Cooldown.", + "OverclockedInfoLong": "(Add-ons):\nAs the Overclocked, your Kill Cooldown is reduced by a percentage.\n\nThis feature is only assigned to roles with a Kill button.", "LoversInfoLong": "(Add-ons):\nLovers are a combination of two players. The Lovers win when they are the last ones standing, and their victory is shared. When one of the Lovers wins, the other also wins together. Lovers can see the 「♥」 next to each other's name. If one of the Lovers dies, the other will die in love (may not die in love according to the Host's settings). When one of the Lovers is exiled in the meeting, the other will die and become a dead body that cannot be reported.", - "MadmateInfoLong": "(Add-ons):\nOnly Crewmates can become Madmate. Madmate's task is to help the Impostors win the game. Madmate will lose if all Impostors are killed/ejected. Madmates may know who are Impostors, and Impostors may know who are Madmates (host settings).\n\nLazy Guy, Celebrity can't become Madmate. Sheriff, Snitch, Nice Guesser, Mayor, and Judge may become Madmate (host settings). Skill changes when the following roles are converted into Madmates:\n\nTime Manager => Doing tasks will reduce meeting time.\nBodyguard => Skill won't activate if the killer is an Impostor.\nGrenadier => Flash bomb will work on Crewmates and Neutrals instead of the Impostors.\nSheriff => Can kill anyone, including Impostors (host settings).\nNice Guesser => Can guess Crewmates and Neutrals\nPsychic => All evil Neutrals and Crewmates' names with the ability to kill will be displayed in Red.\nJudge => Can judge anyone\nPacifist => Their ability only works on Crewmates.", + "MadmateInfoLong": "(Add-ons):\nOnly Crewmates can become Madmate. Madmate's task is to help the Impostors win the game. Madmate will lose if all Impostors are killed/ejected. Madmates may know who are Impostors, and Impostors may know who are Madmates (Host settings).\n\nLazy Guy, Celebrity can't become Madmate. Sheriff, Snitch, Nice Guesser, Mayor, and Judge may become Madmate (Host settings). Skill changes when the following roles are converted into Madmates:\n\nTime Manager => Doing tasks will reduce meeting time.\nBodyguard => Skill won't activate if the killer is an Impostor.\nGrenadier => Flash bomb will work on Crewmates and Neutrals instead of the Impostors.\nSheriff => Can kill anyone, including Impostors (Host settings).\nNice Guesser => Can guess Crewmates and Neutrals\nPsychic => All evil Neutrals and Crewmates' names with the ability to kill will be displayed in Red.\nJudge => Can judge anyone\nPacifist => Their ability only works on Crewmates.", "WatcherInfoLong": "(Add-ons):\nDuring the meeting, Watcher can see everyone's votes.", "FlashInfoLong": "(Add-ons):\nThe Flash's default movement speed is faster than others. (speed depends on the setting of the Host)", - "TorchInfoLong": "(Add-ons):\nTorch has max vision and is not affected by Lights sabotage.", - "SeerInfoLong": "(Add-ons):\nWhenever a player dies, the Seer will see a kill-flash (a red flash, possibly accompanied by an alarm sound like sabotage).", + "TorchInfoLong": "(Add-ons):\nTorch has maximum vision and is not affected by Lights Sabotage.", + "SeerInfoLong": "(Add-ons):\nWhenever a player dies, the Seer will see a kill-flash (a red flash, possibly accompanied by an alarm sound like Sabotage).", "TiebreakerInfoLong": "(Add-ons):\nWhen tie vote, priority will be given to the target voted by the Tiebreaker. Note: If multiple Tiebreakers choose different tie targets simultaneously, the skills of the Tiebreaker will not take effect.", "ObliviousInfoLong": "(Add-ons):\nDetective and Cleaners won't be Oblivious. The Oblivious cannot report dead bodies. Note: Bait killed by Oblivious will still report automatically, and Oblivious can still be used as a scapegoat for Anonymous.", "BewilderInfoLong": "(Add-ons):\nBewilder may have a smaller/bigger vision. When the Bewilder has died, the murderer's vision may become the same as the Bewilder's, depending on the settings.", "WorkhorseInfoLong": "(Add-ons):\nThe first player to complete all the tasks will become Workhorse, and Workhorse will give the player extra tasks. The Host sets the number of additional tasks.", - "FoolInfoLong": "(Add-ons):\nSleuth and Mechanic won't be Fool. Fools can't repair any sabotage.", + "FoolInfoLong": "(Add-ons):\nSleuth and Mechanic won't be Fool. Fools can't repair any Sabotage.", "AvangerInfoLong": "(Add-ons):\nHost can set whether the Impostor can become an Avenger. When the Avenger is killed (voted out, and irregular kills will not count), the Avenger will revenge a random player.", "YoutuberInfoLong": "(Add-ons):\nOnly Crewmate will become YouTuber. When the YouTuber is the first player to die in the game, the YouTuber will win alone. If the YouTuber does not meet the win conditions, the YouTuber will follow the Crewmate to win. Note: Indirect killing methods such as being exiled, being guessed by the Guesser, etc., will not trigger the skills of the YouTuber.", "EgoistInfoLong": "(Add-ons):\nMadmate and Neutrals won't be Egoist. If the Egoist's team wins, the Egoist wins instead of their team.", @@ -973,71 +974,71 @@ "MimicInfoLong": "(Add-ons):\nOnly Impostor can become Mimic. When the Mimic is dead, other Impostors will receive a message once a meeting is called. This message will include information on roles which the Mimic killed.", "GuesserInfoLong": "(Add-ons):\nAs a guesser, guess the roles of players in meetings to kill them.\nGuessing the incorrect role kills you instead.\nThe guessing command is: /bt [player id] [role]\nYou can see the player's id before the player's name or use the /id command to view the id of all players.", "NecroviewInfoLong": "(Add-ons):\nThe Necroview can see the teams of dead players. The following info will be displayed on the dead player's name while in a meeting:\n- The Red name indicates the Impostors.\n- The Cyan name indicates the Crewmates.\n- The Gray name indicates the Neutrals.", - "ReachInfoLong": "(Add-on)\nOnly roles with a kill button can get this add-on. Unlike everyone else, you have the longest kill range possible in the game.", + "ReachInfoLong": "(Add-on)\nOnly roles with a Kill button can get this Add-on. Unlike everyone else, you have the longest kill range possible in the game.", "BaitInfoLong": "(Add-ons):\nWhen the Bait dies, the murderer who killed the Bait will self-report the Bait's body. However, this won't happen when a Scavenger, Cleaner, Swooper, Wraith, Medusa, or Killing Machine kills the Bait. The report may have a delay according to the Host's settings.", "TrapperInfoLong": "(Add-ons):\nWhen Beartrap dies, Beartrap immobilizes killer for a configurable amount of time.", - "CharmedInfoLong": "(Betrayal Add-ons):\nThe Charmed add-on is obtained by being charmed by the Cultist.\nOnce charmed, you are now on the Cultist's team and no longer on your original team.", + "CharmedInfoLong": "(Betrayal Add-ons):\nThe Charmed Add-on is obtained by being charmed by the Cultist.\nOnce charmed, you are now on the Cultist's team and no longer on your original team.", "CleansedInfoLong": "(Add-ons):\nCleansed Add-on can only be obtained if cleanser erases all your Add-ons. Depending on the cleanser settings, you may not be able to obtain any more Add-ons in the future.", - "InfectedInfoLong": "(Betrayal Add-ons):\nThe Infected add-on is obtained by being infected by the Infectious.\nOnce infected, you work for the Infectious and do not win with your original team.", - "OnboundInfoLong": "(Add-ons):\nWith the Onbound add-on, you cannot be guessed in meetings.", - "ReboundInfoLong": "(Add-ons):\nWith the Rebound add-on, if a Guesser successfully guessed you or a Judge successfully judged you, they will die instead.\nIf a player with Double Shot guesses you correctly, they will die instantly.", + "InfectedInfoLong": "(Betrayal Add-ons):\nThe Infected Add-on is obtained by being infected by the Infectious.\nOnce infected, you work for the Infectious and do not win with your original team.", + "OnboundInfoLong": "(Add-ons):\nWith the Onbound Add-on, you cannot be guessed in meetings.", + "ReboundInfoLong": "(Add-ons):\nWith the Rebound Add-on, if a Guesser successfully guessed you or a Judge successfully judged you, they will die instead.\nIf a player with Double Shot guesses you correctly, they will die instantly.", "MundaneInfoLong": "(Add-ons):\nAs Mundane, you can only guess once you complete all of your tasks.", "KnightedInfoLong": "(Add-ons):\nWhen a Monarch knights someone, they get an extra vote.", - "UnreportableInfoLong": "(Add-ons):\nWith the Disregarded add-on, your corpse will be unreportable.", + "UnreportableInfoLong": "(Add-ons):\nWith the Disregarded Add-on, your corpse will be unreportable.", "ContagiousInfoLong": "(Betrayal Add-ons):\nWhen the Virus infects you, you become contagious.\nContagious players are on the Virus team.\n\nWhether or not you die after a meeting depends on the settings for the Virus.", - "LuckyInfoLong": "(Add-ons):\nWith the Lucky add-on, there is a probability for you to evade the kill; the Host sets the specific probability. The killer will see the shield animation when the evasion takes effect, but you will not know anything.", + "LuckyInfoLong": "(Add-ons):\nWith the Lucky Add-on, there is a probability for you to evade the kill; the Host sets the specific probability. The killer will see a Shield Animation when the evasion takes effect, but you will not know anything.", "DoubleShotInfoLong": "(Add-ons):\nWhen a player with Double Shot guesses a role incorrectly, they will get a second chance to guess, but the next wrong guess will result in suicide.", - "RascalInfoLong": "(Add-ons):\nAs the Rascal, you can die to the Sheriff, and Snitch can find you if Snitch can find madmates.\n\nOnly assigned to Crewmates, cannot be assigned by the Merchant.", - "SoullessInfoLong": "(Add-ons):\nWhen a Cursed Soul steals your soul, you get this add-on.\n\nYou are not counted as alive.", + "RascalInfoLong": "(Add-ons):\nAs the Rascal, you can die to the Sheriff, and Snitch can find you if Snitch can find Madmates.\n\nOnly assigned to Crewmates, cannot be assigned by the Merchant.", + "SoullessInfoLong": "(Add-ons):\nWhen a Cursed Soul steals your soul, you get this Add-on.\n\nYou are not counted as alive.", "GravestoneInfoLong": "(Add-ons):\nAs the Gravestone, your role is revealed to everyone when you die.", "LazyInfoLong": "(Add-ons):\nAs the Lazy, you are assigned a single short task and are immune to Warlocks, Puppeteers, and Gangsters.", "AutopsyInfoLong": "(Add-ons):\nAs the Autopsy, you can see how people died.\n\nCannot be assigned to Doctor, Tracefinder, Scientist, or Sunnyboy.", - "RebirthInfoLong": "(Add-ons):\nAs the Rebirth, if you're the player about to be ejected, you will swap skins with a random crewmate who voted for you.\nNotice: The host vote never counts\nRebirth will be removed from you if you exhausted all your rebirths.", - "LoyalInfoLong": "(Add-ons):\nAs the Loyal, you cannot be recruited by roles such as Jackal or Cultist.\n\nCannot be assigned to neutrals.", + "RebirthInfoLong": "(Add-ons):\nAs the Rebirth, if you're the player about to be ejected, you will swap skins with a random Crewmate who voted for you.\nNotice: The Host vote never counts\nRebirth will be removed from you if you exhausted all your rebirths.", + "LoyalInfoLong": "(Add-ons):\nAs the Loyal, you cannot be recruited by roles such as Jackal or Cultist.\n\nCannot be assigned to Neutrals.", "EvilSpiritInfoLong": "(Add-ons):\nAs Evil Spirit, it's your job to help the Spiritcaller to victory. You can use your Haunt button to freeze players and reduce their vision. Alternatively, you can use your Haunt button to give the Spiritcaller a shield against a kill attempt temporarily.", - "RecruitInfoLong": "(Betrayal Add-ons):\nAs a recruit, you are on the Jackal's team and help out the Jackal and their Sidekicks.\nYou cannot win with your original team.\nDepending on the settings, you may turn into Jackal if old Jackal was killed and no sidekicks is alive.", - "AdmiredInfoLong": "(Betrayal Add-ons):\nAs an admired player, you win with the crew and not your original team.\n\nYou can see the Admirer.", + "RecruitInfoLong": "(Betrayal Add-ons):\nAs a recruit, you are on the Jackal's team and help out the Jackal and their Sidekicks.\nYou cannot win with your original team.\nDepending on the settings, you may turn into Jackal if old Jackal was killed and no Sidekicks is alive.", + "AdmiredInfoLong": "(Betrayal Add-ons):\nAs an Admired player, you win with the Crewmates and not your original team.\n\nYou can see the Admirer.", "GlowInfoLong": "(Add-ons):\nDuring lights out, you and players nearby you will receive a vision boost.", "RadarInfoLong": "(Add-ons):\nAs Radar, you have arrows pointing towards the closest person at all times.", - "DiseasedInfoLong": "(Add-ons):\nWhen someone tries to use the kill button on you, their cooldown will be increased by a configurable amount of time.", - "AntidoteInfoLong": "(Add-ons):\nWhen someone tries to use the kill button on you, their cooldown will be decreased by a configurable amount of time.", - "StubbornInfoLong": "(Add-ons):\nWith the Stubborn add-on, Eraser can't erase your role, Cleanser can't cleanse you, Bandit can't steal from you, and Monarch can't knight you.\nAdditionally, you can't gain any new add-ons from the Merchant.", + "DiseasedInfoLong": "(Add-ons):\nWhen someone tries to use the Kill button on you, their Cooldown will be increased by a configurable amount of time.", + "AntidoteInfoLong": "(Add-ons):\nWhen someone tries to use the Kill button on you, their Cooldown will be decreased by a configurable amount of time.", + "StubbornInfoLong": "(Add-ons):\nWith the Stubborn Add-on, Eraser can't erase your role, Cleanser can't cleanse you, Bandit can't steal from you, and Monarch can't knight you.\nAdditionally, you can't gain any new Add-ons from the Merchant.", "SwiftInfoLong": "(Add-ons):\nAs the Swift, you will not make any movement when you kill.\nNote: Swift also ignores Bait", - "UnluckyInfoLong": "(Add-ons):\nAs Unlucky, when you complete tasks, kill, venting, or open door, you have a chance to die.", + "UnluckyInfoLong": "(Add-ons):\nAs Unlucky, when you Complete Tasks, Kill, Venting, or open a Door, you have a chance to die.", "SpurtInfoLong": "(Add-ons):\nWhen you start walking, you gain an enormous speed boost, which swiftly deteriorates, until you have to rest still for a while to rejuvenate your speed.", - "VoidBallotInfoLong": "(Add-ons):\nHolder of this add-on will have 0 vote count.", + "VoidBallotInfoLong": "(Add-ons):\nHolder of this Add-on will have 0 vote count.", "AwareInfoLong": "(Add-ons):\nAs the Aware, you get a notification in the next meeting if a revealing role had interacted with you.", - "FragileInfoLong": "(Add-ons):\nAs Fragile, you will instantly die if someone tries to use the kill button on you (even if the role cannot directly kill).", - "GhoulInfoLong": "(Add-ons):\nAs the Ghoul, one of two outcomes can occur on task completion.\n\nIf alive: Suicide\nIf dead: You kill your killer if they're alive.\n\nThis is only assigned to crewmates, and not crewmates with no tasks or are task-based.", - "BloodthirstInfoLong": "(Add-ons):\nAs the Bloodthirst, doing tasks allows you to become bloodthirsty and kill players.\nWhen you finish a task, the next player you come in contact with dies.\n\nYour Bloodthirst remains after a meeting.\nUpon making a kill, your Bloodthirst clears till the next task you complete.\nBloodthirsts do not stack.\n\nOnly assigned to crewmates with tasks.", - "MareInfoLong": "(Add-ons):\nAs the Mare, you have a low kill cooldown and have higher speed but can only kill during lights.\n\nAdditionally, your name will appear in red during lights.\n\nOnly assigned to Impostors and cannot be guessed.", - "BurstInfoLong": "(Add-ons):\nAs the Burst, your killer explodes if they aren't inside a vent after a set amount of time.", + "FragileInfoLong": "(Add-ons):\nAs Fragile, you will instantly die if someone tries to use the Kill button on you (even if the role cannot directly kill).", + "GhoulInfoLong": "(Add-ons):\nAs the Ghoul, one of two outcomes can occur on task completion.\n\nIf alive: Suicide\nIf dead: You kill your killer if they're alive.\n\nThis is only assigned to Crewmates, and not Crewmates with no tasks or are task-based.", + "BloodthirstInfoLong": "(Add-ons):\nAs the Bloodthirst, doing tasks allows you to become bloodthirsty and kill players.\nWhen you finish a task, the next player you come in contact with dies.\n\nYour Bloodthirst remains after a meeting.\nUpon making a kill, your Bloodthirst clears till the next task you complete.\nBloodthirsts do not stack.\n\nOnly assigned to Crewmates with tasks.", + "MareInfoLong": "(Add-ons):\nAs the Mare, you have a low Kill Cooldown and have higher speed but can only kill during lights.\n\nAdditionally, your name will appear in red during lights.\n\nOnly assigned to Impostors and cannot be guessed.", + "BurstInfoLong": "(Add-ons):\nAs the Burst, your killer explodes if they aren't inside a Vent after a set amount of time.", "SleuthInfoLong": "(Add-ons):\nAs the Sleuth, you gain info from dead bodies.\n\nOptionally, you may also gain the killer's role.\n\nNot assigned to Detective or Mortician.", - "ClumsyInfoLong": "(Add-ons):\nAs the Clumsy, you have a chance to miss your kill.\n\nWhen you miss, your cooldown is reset, and the target remains untouched.\n\nOnly assigned to killers.", - "CircumventInfoLong": "(Add-ons):\nAs the Circumvent, you can't vent.\n\nOnly assigned to Impostors.", - "NimbleInfoLong": "(Add-ons):\nAs the Nimble, you gain access to the vent button.\n\nOnly assigned to certain crewmates.", - "InfluencedInfoLong": "(Add-ons):\nAs the Influenced, your vote will be forced to the player with the most votes.\nInfluenced vote won't be counted while choosing the exiled player'\nNote that your vote skill still functions on the player you voted first\nIf all the alive players are Influenced, then the vote result won't shift\nCollector cannot become influenced.", + "ClumsyInfoLong": "(Add-ons):\nAs the Clumsy, you have a chance to miss your kill.\n\nWhen you miss, your Cooldown is reset, and the target remains untouched.\n\nOnly assigned to killers.", + "CircumventInfoLong": "(Add-ons):\nAs the Circumvent, you can't Vent.\n\nOnly assigned to Impostors.", + "NimbleInfoLong": "(Add-ons):\nAs the Nimble, you gain access to the Vent button.\n\nOnly assigned to certain Crewmates.", + "InfluencedInfoLong": "(Add-ons):\nAs the Influenced, your vote will be forced to the player with the most votes.\nInfluenced vote won't be counted while choosing the exiled player'\nNote that your vote skill still functions on the player you voted first\nIf all the alive players are Influenced, then the vote result won't shift\nCollector cannot become Influenced.", "SilentInfoLong": "(Add-ons):\nAs the Silent, your vote icon won't appear on the result screen.\nSo nobody knows who you voted for.", "SusceptibleInfoLong": "(Add-ons):\nAs the Susceptible, your death reason will be random.", "TrickyInfoLong": "(Add-ons):\nAs the Tricky, your kills will have a random death reason.", "TiredInfoLong": "(Add-ons):\nWhenever Tired kills (or uses kill ability on) someone, alternatively whenever they finish a task, they will temporarily get lower vision & lower speed.", "StatueInfoLong": "(Add-ons):\nWhenever many people are near the Statue, the Statue is completely frozen or slowed down depending on the settings.", "EvaderInfoLong": "(Add-ons):\nWhen the Evader gets voted out, there is a chance they will not get ejected. (Chance set by the Host.)", - "CyberInfoLong": "(Add-ons):\nAs the Cyber, you cannot die while in a group.\nDepending on the settings, Imposters, Neutrals, and or Crewmates will know if you die.", - "HurriedInfoLong": "(Add-ons):\nAs the hurried, you must finish all your tasks to win with your team! If you fail with your tasks, you lose.\nHurried hurries to his goal, so it won't get madmate, charmed or so.", - "OiiaiInfoLong": "(Add-ons):\nAs the Oiiai, when you die, you will make your killer forget their role.\nAdditionally, you may pass Oiiai on to the killer, depending on settings.", + "CyberInfoLong": "(Add-ons):\nAs the Cyber, you cannot die while in a group.\nDepending on the settings, Impostors, Neutrals, and or Crewmates will know if you die.", + "HurriedInfoLong": "(Add-ons):\nAs the hurried, you must finish all your tasks to win with your team! If you fail with your tasks, you lose.\nHurried hurries to his goal, so it won't get Madmate, Charmed or so.", + "OiiaiInfoLong": "(Add-ons):\nAs the OIIAI, when you die, you will make your killer forget their role.\nAdditionally, you may pass OIIAI on to the killer, depending on settings.", "RainbowInfoLong": "(Add-ons):\nAs the rainbow, you change your colors like crazy.", "GMInfoLong": "(None):\nThe Game Master is an observer role.\nTheir presence does not affect the game, and all players know who the Game Master is. The Game Master role will be assigned to the Host, who will automatically become a ghost at the start of the game.", - "SunnyboyInfoLong": "(Neutrals):\nAs the Sunnyboy, you win if you are dead by the end of the game. The game will not end when you are alive due to killers gaining the majority.\nAdditionally, you have access to portable vitals.", - "BardInfoLong": "(Impostors):\nWhen a bard is alive, the exile confirmation will display a sentence composed by the bard. Whenever the bard completes a creation, the bard's kill cooldown will be permanently halved.", + "SunnyboyInfoLong": "(Neutrals):\nAs the Sunnyboy, you win if you are dead by the end of the game. The game will not end when you are alive due to killers gaining the majority.\nAdditionally, you have access to portable Vitals.", + "BardInfoLong": "(Impostors):\nWhen a bard is alive, the exile confirmation will display a sentence composed by the bard. Whenever the bard completes a creation, the bard's Kill Cooldown will be permanently halved.", "WardenInfoLong": "(Crewmates [Ghost]):\nAs the Warden, alert someone of nearby danger, additionally giving them a temporary speed boost.", "GhastlyInfoLong": "(Crewmates [Ghost]):\nAs the Ghastly, possess an unsuspecting person, after that choose a target for them, now they'll only be able to use their kill (or kill ability) on target until you possess someone else or possess time runs out.", - "MinionInfoLong": "(Impostor [Ghost]):\nAs the Minion, you can temporarily blind non-impostors.", - "DollMasterInfoLong": "(Impostor):\nAs the Dollmaster, you can temporarily take control of any player by using the Shapeshift button and to make them do your Deeds!", - "DoubleAgentInfoLong": "(Impostor):\nAs the Double Agent, you cannot access the kill button. However, you can vote for someone in a meeting to pass a bomb onto them, which can only be done one player at a time. Once the meeting has finished, the bomb will activate and explode in a set amount of time.\nNote: when you pass the bomb onto someone in a meeting, you can vote afterward.\n\nAdditionally depending on settings the Double Agent can diffuse Bastion and Agitator bombs when venting.\n\nThe Double Agent can change roles when they are the Last Imposter, depending on the settings the role can be a Admired Impostor, Trickster, Traitor, or stay as the Double Agent.", + "MinionInfoLong": "(Impostor [Ghost]):\nAs the Minion, you can temporarily blind non-Impostors.", + "DollMasterInfoLong": "(Impostor):\nAs the Dollmaster, you can temporarily take control of any player by using the Shapeshift button and to make them do your deeds!", + "DoubleAgentInfoLong": "(Impostor):\nAs the Double Agent, you cannot access the Kill button. However, you can vote for someone in a meeting to pass a bomb onto them, which can only be done one player at a time. Once the meeting has finished, the bomb will activate and explode in a set amount of time.\nNote: when you pass the bomb onto someone in a meeting, you can vote afterward.\n\nAdditionally depending on settings the Double Agent can diffuse Bastion and Agitator bombs when Venting.\n\nThe Double Agent can change roles when they are the Last Impostor, depending on the settings the role can be a Admired Impostor, Trickster, Traitor, or stay as the Double Agent.", "SlothInfoLong": "(Add-ons):\nThe Sloth's default movement speed is slower than others.\n(Speed depends on the setting of the Host)", - "ProhibitedInfoLong": "(Add-ons):\nAs the Prohibited, you have specific vents that you can't use.\nHow many vents are disabled depends on the Host's settings.", - "EavesdropperInfoLong": "(Add-ons):\nAs the Eavesdropper, you have a chance to read other role/addon information-based messages like Mortician or Sleuth.", + "ProhibitedInfoLong": "(Add-ons):\nAs the Prohibited, you have specific Vents that you can't use.\nHow many Vents are disabled depends on the Host's settings.", + "EavesdropperInfoLong": "(Add-ons):\nAs the Eavesdropper, you have a chance to read other Role/Add-on information-based messages like Mortician or Sleuth.", "ApocalypseInfoLong": "(Apocalypse):\nApocalypse members are on a separate team that works together and wins together. If there are multiple Apocalypse roles in the game, they can see each other's roles.\nDepending on the Host's settings, Apocalypse roles can guess or be guessed.", "RevenantInfoLong": "(Neutral):\nAs the Revenant, your goal is to be killed. If you are killed, you will take your killer's role and kill your killer instead. You cannot win before being killed.\nNote that Revenant only works when being directly killed.", "ShowTextOverlay": "Text Overlay", @@ -1055,7 +1056,7 @@ "AbilityExpired": "Ability expired, {0} uses remain", "RevenantTargeted": "Your role has changed to {0}", - "RevenantCanCopyAddons": "Can Steal Addons", + "RevenantCanCopyAddons": "Can Steal Add-ons", "ShowArrows": "Has Arrows pointing toward bodies", "ArrowDelayMin": "Minimum Arrow show-up delay", @@ -1063,11 +1064,11 @@ "SMUsesUsedWhenFixingReactorOrO2": "Uses it takes to fix Reactor/O2", "SMUsesUsedWhenFixingLightsOrComms": "Uses it takes to fix Lights/Comms", - "GrenadierSkillMaxOfUseage": "(Initial) Max number of Grenades", + "GrenadierSkillMaxOfUseage": "(Initial) Maximum number of Grenades", "ShowSpecificRole": "Know specific roles on Task Completion", - "TimeMasterMaxUses": "(Initial) Max Amount of Ability Uses", - "SwooperVentNormallyOnCooldown": "Swooper vents normally when swooping is on cooldown", - "WraithVentNormallyOnCooldown": "Wraith vents normally when invis is on cooldown", + "TimeMasterMaxUses": "(Initial) Maximum Amount of Ability Uses", + "SwooperVentNormallyOnCooldown": "Swooper Vents normally when Swooping is on Cooldown", + "WraithVentNormallyOnCooldown": "Wraith Vents normally when Invisibility is on Cooldown", "DisableMeeting": "Disable Meetings", "DisableCloseDoor": "Disable Doors Sabotage", "DisableSabotage": "Disable Sabotages", @@ -1076,13 +1077,13 @@ "DebugMode": "Debug Mode", "SyncButtonMode": "Limit Meeting Times", "RandomMapsMode": "Random Maps Mode", - "SyncedButtonCount": "Max Number of Emergency Meetings per Game", - "HHSuccessKCDDecrease": "Kill cooldown decrease on killing target", - "HHFailureKCDIncrease": "Kill cooldown increase on killing others", + "SyncedButtonCount": "Maximum Number of Emergency Meetings per Game", + "HHSuccessKCDDecrease": "Kill Cooldown decrease on killing target", + "HHFailureKCDIncrease": "Kill Cooldown increase on killing others", "HHNumOfTargets": "Number of targets", "Targets": "Targets: ", - "HHMaxKCD": "Maximum kill cooldown", - "HHMinKCD": "Minimum kill cooldown", + "HHMaxKCD": "Maximum Kill Cooldown", + "HHMinKCD": "Minimum Kill Cooldown", "AllAliveMeeting": "Meeting When No One is Dead", "AllAliveMeetingTime": "Meeting Time When No One is Dead", "AdditionalEmergencyCooldown": "Additional Emergency Cooldown", @@ -1196,8 +1197,8 @@ "GhostIgnoreTasks": "Ghosts Exempt From Tasks", "ConvertedCanBeGhostRole": "Converted Players Can Be Any Ghost-Roles", "NeutralCanBeGhostRole": "Neutral Players Can Be Any Ghost-Roles (Will change team respectively)", - "MaxImpGhostRole": "Max Impostor Ghost-Roles", - "MaxCrewGhostRole": "Max Crewmate Ghost-Roles", + "MaxImpGhostRole": "Maximum Impostor Ghost-Roles", + "MaxCrewGhostRole": "Maximum Crewmate Ghost-Roles", "DefaultAngelCooldown": "Default Ability Cooldown", "DisableTaskWin": "Disable Task Win", "DisableTaskWinIfAllCrewsAreDead": "Disable Task Win If All <#8cffff>Crewmates Are Dead", @@ -1217,7 +1218,7 @@ "RoleOptions": "Role Options", "DarkTheme": "Enable Dark Theme", "DisableLobbyMusic": "Disable Lobby Music", - "AutoStart": "Auto start", + "AutoStart": "Auto Start", "EnableCustomButton": "Enable Custom Button Images", "EnableCustomSoundEffect": "Enable Custom Sound Effects", "EnableCustomDecorations": "Enable Custom Map Decorations", @@ -1309,7 +1310,7 @@ "RandomSpawn_AirshipAdditionalSpawn": "Additional Spawn Locations (Airship)", "RandomSpawn_SpawnRandomVents": "Random Spawns On Vents", "CommsCamouflage": "Camouflage during Comms Sabotage", - "DisableOnSomeMaps": "Disable comms camouflage on some maps", + "DisableOnSomeMaps": "Disable Comms Camouflage on some maps", "DisableOnSkeld": "Disable on The Skeld", "DisableOnMira": "Disable on MIRA HQ", "DisableOnPolus": "Disable on Polus", @@ -1388,7 +1389,7 @@ "ShieldPersonDiedFirst": "Shield player who dead first in the last game", "ShowShieldedPlayerToAll": "Reveal shielded player to all", "RemoveShieldOnFirstDead": "Remove shield on first death", - "ShieldedCanUseKillButton": "Shielded player can use ability / kill button", + "ShieldedCanUseKillButton": "Shielded player can use ability/Kill button", "PlayerIsShieldedByGame": "Player is protected by the game!", "LegacyNemesis": "Use Legacy Version", @@ -1413,7 +1414,7 @@ "DoubleAgent_DiffusedBastionBomb": "Bastion bomb successfully diffused", "DoubleAgent_BombExplodesIn": "Bomb Explodes In: {0}s", "DoubleAgent_BombExploded": "Bomb has exploded!", - "DoubleAgentChangeRoleTo": "Change role on last Imposter", + "DoubleAgentChangeRoleTo": "Change role on last Impostor", "DoubleAgentRoleChange": "You have become a: ", "MastermindCD": "Manipulate Cooldown", @@ -1432,16 +1433,16 @@ "Glitch_KCD": "Kill Cooldown: {0}s", "Glitch_MimicCD": "Mimic Cooldown: {0}s", "HackedByGlitch": "You are hacked by the Glitch, you can't {0}.", - "GlitchKill": "kill", - "GlitchReport": "report", - "GlitchVent": "vent", + "GlitchKill": "Kill", + "GlitchReport": "Report", + "GlitchVent": "Vent", "ShowFPS": "Show FPS", "FPSGame": "FPS: ", "ControlCooldown": "Control Cooldown", "PoisonCooldown": "Poison Cooldown", "PoisonerKillDelay": "Poison Kill Delay", - "WardenNotifyLimit": "Max number of alerts", + "WardenNotifyLimit": "Maximum number of alerts", "BombCooldown": "Bomb Cooldown", "Warlock_CanKillSelf": "Can Kill Themselves", @@ -1473,7 +1474,7 @@ "EGCanGuessTaskDoneSnitch": "Can guess Snitch with All Tasks Done", "GGCanGuessAdt": "Can Guess Add-Ons", "GuesserCanGuessTimes": "Maximum number of guesses", - "GuesserTryHideMsg": "Try to hide the guesser's command", + "GuesserTryHideMsg": "Try to hide the Guesser's command", "GCanGuessImp": "Impostor can guess Impostor roles", "GCanGuessCrew": "Crewmate can guess Crewmate roles", "GCanGuessAdt": "Can guess Add-ons", @@ -1483,7 +1484,7 @@ "BountyFailureKillCooldown": "Kill Cooldown After Killing Others", "BountyShowTargetArrow": "Show arrow pointing towards the target", "DefaultShapeshiftCooldown": "Default Shapeshift Cooldown", - "DeadImpCantSabotage": "Impostors can't sabotage after they've died", + "DeadImpCantSabotage": "Impostors can't Sabotage after they've died", "VampireKillDelay": "Bite Kill Delay", "VampireTargetDead": "Target died", "VampireActionMode": "Action Mode", @@ -1493,7 +1494,7 @@ "Cooldown": "Cooldown", "AbilityCooldown": "Ability Cooldown", - "SkillLimitTimes": "Max Number of Ability Uses", + "SkillLimitTimes": "Maximum Number of Ability Uses", "CanKill": "Can Kill", "KillCooldown": "Kill Cooldown", "CanVent": "Can Vent", @@ -1512,16 +1513,16 @@ "ShapeshifterBase_ShapeshiftCooldown": "Shapeshift Cooldown", "ShapeshifterBase_ShapeshiftDuration": "Shapeshift Duration", "ShapeshifterBase_LeaveShapeshiftingEvidence": "Leave Shapeshifting Evidence", - "PhantomBase_InvisCooldown": "Invis Cooldown", - "PhantomBase_InvisDuration": "Invis Duration", + "PhantomBase_InvisCooldown": "Invisibility Cooldown", + "PhantomBase_InvisDuration": "Invisibility Duration", "GuardianAngelBase_ProtectCooldown": "Protect Cooldown", "GuardianAngelBase_ProtectionDuration": "Protection Duration", - "GuardianAngelBase_ImpostorsCanSeeProtect": "Protect Visible To Impostors", + "GuardianAngelBase_ImpostorsCanSeeProtect": "Protect Visible to Impostors", "ScientistBase_BatteryCooldown": "Vitals Display Cooldown", "ScientistBase_BatteryDuration": "Battery Duration", "EngineerBase_VentCooldown": "Vent Cooldown", - "EngineerBase_InVentMaxTime": "Max Time In Vents", - "NoisemakerBase_ImpostorAlert": "Impostors Can Get Alert", + "EngineerBase_InVentMaxTime": "Maximum Time in Vents", + "NoisemakerBase_ImpostorAlert": "Impostors can get Alert", "NoisemakerBase_AlertDuration": "Alert Duration", "TrackerBase_TrackingCooldown": "Tracking Cooldown", "TrackerBase_TrackingDuration": "Tracking Duration", @@ -1557,7 +1558,7 @@ "After1PlayerEaten": "After 1 Player Was Eaten", "AfterMeeting": "After Meeting", "None": "None", - "SheriffShotLimit": "Max number of Kills", + "SheriffShotLimit": "Maximum number of Kills", "SheriffCanKillAllAlive": "Can Kill When No One Is Dead", "SheriffCanKillCharmed": "Can kill Charmed players", "SheriffCanKillEgoist": "Can Kill Egoists", @@ -1566,7 +1567,7 @@ "SheriffCanKillMadmate": "Can Kill Madmates", "SheriffCanKillInfected": "Can Kill Infected players", "SheriffCanKillContagious": "Can Kill Contagious players", - "SheriffSetMadCanKill": "Non-Crew Sheriff Configuration", + "SheriffSetMadCanKill": "Non-Crewmate Sheriff Configuration", "SheriffMadCanKillImp": "Can kill Impostors", "SheriffMadCanKillNeutral": "Can kill Neutrals", "SheriffMadCanKillCrew": "Can kill Crewmates", @@ -1576,10 +1577,10 @@ "RebirthFailed": "Ahh, how unfortunate, you did not find any viable souls to swap bodies with", "FireworkerCooldown": "Placement Cooldown", - "ReverieIncreaseKillCooldown": "Increase kill cooldown", - "ReverieMaxKillCooldown": "Max kill cooldown", - "ReverieMisfireSuicide": "Misfire on reaching max kill cooldown", - "ReverieResetCooldownMeeting": "Reset kill cooldown after meeting", + "ReverieIncreaseKillCooldown": "Increase Kill Cooldown", + "ReverieMaxKillCooldown": "Maximum Kill Cooldown", + "ReverieMisfireSuicide": "Misfire on reaching maximum Kill Cooldown", + "ReverieResetCooldownMeeting": "Reset Kill Cooldown after meeting", "ConvertedReverieKillAll": "Converted Reverie can kill anyone without repercussions", "VigilanteNotify": "You have become the very thing you swore to destroy", @@ -1595,13 +1596,13 @@ "SnitchRemainingTaskFound": "Remaining tasks to be known", "MayorAdditionalVote": "Additional Votes Count", "MayorHasPortableButton": "Mayor has a Mobile Emergency Button", - "MayorNumOfUseButton": "Max Number of Mobile Emergency Buttons", + "MayorNumOfUseButton": "Maximum Number of Mobile Emergency Buttons", "MeetingsNeededForWin": "Meetings needed to win", "Jester_RevealUponEject": "Reveal Upon Eject", "CannotVoteWhenDead": "Cannot cast a vote while dead", "EnableVote": "Enable /vote command", "ShouldVoteSpam": "Try to hide /vote command", - "VoteDisabled": "/vote command has been disabled by the host.", + "VoteDisabled": "/vote command has been disabled by the Host.", "ExecutionerCanTargetImpostor": "Can Target Impostors", "ExecutionerCanTargetNeutralKiller": "Can Target Neutral Killing", "ExecutionerCanTargetNeutralApocalypse": "Can Target Neutral Apocalypse", @@ -1631,8 +1632,8 @@ "SniperAimAssist": "Aim Assist", "SniperAimAssistOneshot": "One shot Assist", - "PyroDouseCooldown": "Douse cooldown", - "PyroBurnCooldown": "Kill cooldown after killing a doused player", + "PyroDouseCooldown": "Douse Cooldown", + "PyroBurnCooldown": "Kill Cooldown after killing a doused player", "Prohibited_OverrideBlockedVentsAfterMeeting": "Override Blocked Vents After Meeting", "Prohibited_CountBlockedVentsInSkeld": "Count Blocked Vents In The Skeld", @@ -1645,7 +1646,7 @@ "UndertakerFreezeDuration": "Freeze Duration", "NameDisplayAddons": "Display Add-Ons next to the role name", "YourAddon": "Your Add-ons:", - "NoLimitAddonsNumMax": "Max Add-ons Per Player", + "NoLimitAddonsNumMax": "Maximum Add-ons Per Player", "LoverSpawnChances": "Spawn Chance of Lovers", "AdditionRolesSpawnRate": "Spawn Chance", "TorchVision": "Torch Vision", @@ -1683,12 +1684,12 @@ "EvilHackerDeadbody": "DEAD", "Ventguard": "Ventguard", - "VentguardInfo": "Block vents by entering them", - "VentguardInfoLong": "(Crewmates):\nAs the Ventguard, you can enter vents to block them. No one can enter blocked vents, except Crewmates, if the setting is on. Blocked vents can be resets every meeting.", + "VentguardInfo": "Block Vents by entering them", + "VentguardInfoLong": "(Crewmates):\nAs the Ventguard, you can enter Vents to block them. No one can enter blocked Vents, except Crewmates, if the setting is on. Blocked Vents can be resets every meeting.", "VentguardVentButtonText": "Block", - "Ventguard_MaxGuards": "Max number of Vent Blocks", + "Ventguard_MaxGuards": "Maximum number of Vent Blocks", "Ventguard_BlockVentCooldown": "Block Vent Cooldown", - "Ventguard_BlockDoesNotAffectCrew": "Crewmates can use blocked vents", + "Ventguard_BlockDoesNotAffectCrew": "Crewmates can use blocked Vents", "Ventguard_BlocksResetOnMeeting": "Reset Blocked Vents Every Meeting", "VentIsBlocked": "This Vent Is Now Blocked!", @@ -1699,23 +1700,23 @@ "Psychic_NAareRed": "Neutral Apocalypse can be red", "Psychic_NKareRed": "Neutral Killers can be red", "Psychic_CrewKillingRed": "Crewmate Killing can be red", - "PsychicCanSeeNum": "Max number of red names", + "PsychicCanSeeNum": "Maximum number of red names", "PsychicFresh": "New red names every meeting", "DetectiveCanknowKiller": "Can find the killer's role", "EveryOneKnowSuperStar": "Everyone knows the Super Star", "HackLimit": "Ability Use Count", "ZombieSpeedReduce": "After a certain time, decrease the speed of Zombie by", - "NemesisCanKillNum": "Max number of revenges", + "NemesisCanKillNum": "Maximum number of revenges", "ImpKnowCelebrityDead": "Impostors know when the Celebrity dies", "NeutralKnowCelebrityDead": "Neutrals know when the Celebrity dies", "VectorVentNumWin": "Number of Vents to win", "CanCheckCamera": "Can track camera usage", - "DefaultKillCooldown": "Starting kill cooldown", - "ReduceKillCooldown": "Reduce kill cooldown by", - "MinKillCooldown": "Minimum kill cooldown", + "DefaultKillCooldown": "Starting Kill Cooldown", + "ReduceKillCooldown": "Reduce Kill Cooldown by", + "MinKillCooldown": "Minimum Kill Cooldown", "BomberRadius": "Bomb radius (5x is about half a Cafeteria)", "NotifyGodAlive": "Inform players at meetings that God is still alive", - "TransporterTeleportMax": "Max number of teleports", + "TransporterTeleportMax": "Maximum number of teleports", "TriggerKill": "Kill", "TriggerVent": "Vent", "TriggerDouble": "Double Click", @@ -1736,9 +1737,9 @@ "ImpCanBeEgoist": "An Impostor can become Egoist", "CrewCanBeEgoist": "Crewmates can become Egoist", "ImpEgoistVisibalToAllies": "Impostors Can See Other Egoist Impostors", - "EgoistCountAsConverted": "Egoist count as converted neutral", + "EgoistCountAsConverted": "Egoist count as converted Neutral", "GuessRainbow": "He seems too obvious, doesn't he?", - "RainbowColorChangeCoolDown": "The cooldown for changing colors", + "RainbowColorChangeCoolDown": "The Cooldown for changing colors", "RainbowInCamouflage": "Rainbow color changes during Camouflage", "BaitDelayMin": "Minimum Report Delay", "BaitDelayMax": "Maximum Report Delay", @@ -1746,17 +1747,17 @@ "BecomeBaitDelayNotify": "Warn the killer about the upcoming self-report", "BaitNotification": "Reveal Bait at the first meeting", "BaitAdviceAlive": "{0} is the Bait. Whoever kills the Bait will commit self-report.", - "BaitCanBeReportedUnderAllConditions": "Bait Can Be Reported even if a meeting is disabled during comms sabotage", - "DeceiverAbilityLost": "Deceiver loses ability if it deceives player without kill button", + "BaitCanBeReportedUnderAllConditions": "Bait Can Be Reported even if a meeting is disabled during Comms Sabotage", + "DeceiverAbilityLost": "Deceiver loses ability if it deceives player without Kill button", "AddictSuicideTimer": "Time Until Suicide", "GrenadierSkillCooldown": "Grenade Cooldown", "GrenadierSkillDuration": "Grenade Duration", "GrenadierCauseVision": "Lowered vision", "GrenadierCanAffectNeutral": "Can affect Neutrals", "TicketsPerKill": "Votes Increase Amount Per Kill", - "GangsterRecruitCooldown": "Recruit cooldown", + "GangsterRecruitCooldown": "Recruit Cooldown", "GangsterRecruitLimit": "Recruit limit", - "KamikazeMaxMarked": "Max Marked", + "KamikazeMaxMarked": "Maximum Marked", "RevolutionistDrawTime": "Tag Duration", "RevolutionistCooldown": "Tag Cooldown", "RevolutionistDrawCount": "Amount of Players needed to Tag", @@ -1776,7 +1777,7 @@ "MedicShieldDeactivationIsVisible_Immediately": "Immediately", "MedicShieldDeactivationIsVisible_AfterMeeting": "After Meeting", "MedicShieldDeactivationIsVisible_OFF": "OFF", - "MedicResetCooldown": "On kill attempt, reset murderer's cooldown to", + "MedicResetCooldown": "On kill attempt, reset murderer's Cooldown to", "MedicShieldedCanBeGuessed": "Guessing ignores Medic shield", "MadmateSpawnMode": "Madmate spawning mode", "MadmateSpawnMode.Assign": "Assign", @@ -1801,16 +1802,16 @@ "SnatchesWin": "Snatches victory", "DemonKillCooldown": "Attack Cooldown", - "DemonHealthMax": "Player max health", + "DemonHealthMax": "Player maximum health", "DemonDamage": "Damage ", - "DemonSelfHealthMax": "Demon max health", + "DemonSelfHealthMax": "Demon maximum health", "DemonSelfDamage": "Demon damage received", "LightningConvertTime": "Duration of the transformation to Quantum Ghost", "LightningKillCooldown": "Lightning Cooldown", "LightningKillerConvertGhost": "Killer can transform into Quantum Ghost", "CanCountNeutralKiller": "When Crewmates win by killing a Neutral player, they can snatch the victory", - "GreedyOddKillCooldown": "Odd-Numbered kill cooldown", - "GreedyEvenKillCooldown": "Even-Numbered kill cooldown", + "GreedyOddKillCooldown": "Odd-Numbered Kill Cooldown", + "GreedyEvenKillCooldown": "Even-Numbered Kill Cooldown", "WorkaholicCannotWinAtDeath": "Can't win after they died", "WorkaholicVisibleToEveryone": "Everyone knows who the Workaholic is", "WorkaholicGiveAdviceAlive": "Advice at the first meeting if alive, can win after death, ghost tasks ON", @@ -1821,7 +1822,7 @@ "CollectorCollectAmount": "Required number of votes", "GlitchCanVote": "Can vote", "QuickShooterShapeshiftCooldown": "Shapeshift Cooldown", - "MeetingReserved": "Max Bullets reserved for a meeting", + "MeetingReserved": "Maximum Bullets reserved for a meeting", "AccurateCheckMode": "Can know specific role when tasks are not done", "RandomActiveRoles": "Show random active roles in Fortune Teller hints", "CamouflageCooldown": "Camouflage Cooldown", @@ -1839,8 +1840,8 @@ "JudgeCanTrialInfected": "Can trial Infected", "JudgeCanTrialContagious": "Can trial Contagious", "JudgeTryHideMsg": "Hide Judge's commands", - "JudgeTrialLimitPerMeeting": "Max Trials per Meeting", - "JudgeTrialLimitPerGame": "Max Trials per Game", + "JudgeTrialLimitPerMeeting": "Maximum Trials per Meeting", + "JudgeTrialLimitPerGame": "Maximum Trials per Game", "JudgeCanTrialMadmate": "Can trial Madmates", "JudgeCanTrialCharmed": "Can trial Charmed players", "JudgeDead": "Sorry, you can't trial players after death.", @@ -1849,15 +1850,15 @@ "Judge_LaughToWhoTrialSelf": "God, I didn't think the Judges would be so blind that they wouldn't even see that they had sentenced themselves.", "Judge_TrialKill": "{0} was judged.", "Judge_TrialKillTitle": "COURT", - "Judge_TrialHelp": "Command: /tl [player ID]\nYou can see the players' IDs before the players' names.\nOr use /id to view the list of all player IDs.", + "Judge_TrialHelp": "Command: /tl [player ID]\nYou can see the players' ID's before the players' names.\nOr use /id to view the list of all player ID's.", "Judge_TrialNull": "Please choose a living player for the trial", - "VeteranSkillMaxOfUseage": "Max number of Alerts", + "VeteranSkillMaxOfUseage": "Maximum number of Alerts", "SwooperCooldown": "Swoop Cooldown", "SwooperDuration": "Swoop Duration", "WraithCooldown": "Vanish Cooldown", "WraithDuration": "Vanish Duration", "BastionNotify": "A bomb was set off", - "EnteredBombedVent": "That vent was bombed!", + "EnteredBombedVent": "That Vent was bombed!", "BastionVentButtonText": "Bomb", "BombsClearAfterMeeting": "Bombs clear after meetings", "BastionMaxBombs": "(Initial) Maximum bombs", @@ -1903,8 +1904,8 @@ "Cultist_CharmedCountMode_Cultist": "Cultist", "Cultist_CharmedCountMode_Original": "Original Team", - "JackalCanWinBySabotageWhenNoImpAlive": "When all Impostors are dead, the Jackal wins by sabotage instead", - "JackalResetKillCooldownWhenPlayerGetKilled": "Reset kill cooldown if someone gets killed by another player", + "JackalCanWinBySabotageWhenNoImpAlive": "When all Impostors are dead, the Jackal wins by Sabotage instead", + "JackalResetKillCooldownWhenPlayerGetKilled": "Reset Kill Cooldown if someone gets killed by another player", "JackalResetKillCooldownOn": "Kill Cooldown On Reset", "JackalCanRecruitSidekick": "Can recruit Sidekick", "JackalSidekickRecruitLimit": "Maximum Number Of Recruits", @@ -1949,13 +1950,13 @@ "Troller_CanHaveStartMeetingEvent": "Can Start Meeting By Event", "Troller_ChangesSpeed": "Troller changed everyone speed!", "Troller_SpeedOut": "Speed returned back", - "Troller_YouChangedCooldown": "You changed the cooldown of all players", - "Troller_ChangeYourCooldown": "Troller change your cooldown!", - "Troller_NoAddons": "No addons found on the random target", - "Troller_RemoveRandomAddon": "You removed add-on from random player", - "Troller_RemoveYourAddon": "Troller removed your random add-on", - "Troller_YouCausedSabotage": "You caused sabotage", - "Troller_YouFixedSabotage": "You fixed sabotage", + "Troller_YouChangedCooldown": "You changed the Cooldown of all players", + "Troller_ChangeYourCooldown": "Troller change your Cooldown!", + "Troller_NoAddons": "No Add-ons found on the random target", + "Troller_RemoveRandomAddon": "You removed Add-on from random player", + "Troller_RemoveYourAddon": "Troller removed your random Add-on", + "Troller_YouCausedSabotage": "You caused Sabotage", + "Troller_YouFixedSabotage": "You fixed Sabotage", "LuckyProbability": "Probability of surviving a kill", "ImpCanBeDoubleShot": "Impostors can have Double Shot", @@ -1963,27 +1964,27 @@ "NeutralCanBeDoubleShot": "Neutrals can have Double Shot", "MimicCanSeeDeadRoles": "Mimic can see the roles of dead players", "DisableReportWhenCamouflageIsActive": "Disable body reporting when camouflage is active", - "CanUseCommsSabotage": "Can use comms sabotage", + "CanUseCommsSabotage": "Can use Comms Sabotage", "ModTag": "Moderator♥", "ApplyModeratorList": "Apply Moderator List", "VipTag": "VIP★", "ApplyVipList": "Apply VIP List", - "AllowSayCommand": "Allow moderators to use /say command", - "AllowStartCommand": "Allow moderators to use /start command", + "AllowSayCommand": "Allow Moderators to use /say command", + "AllowStartCommand": "Allow Moderators to use /start command", "StartCommandMinCountdown": "Minimum countdown for /start command", "StartCommandMaxCountdown": "Maximum countdown for /start command", "KickCommandDisabled": "The kick command is currently disabled.", "KickCommandNoAccess": "You do not have access to the kick command.", "KickCommandInvalidID": "Invalid player ID specified.\nPlease use '/kick [playerID] [reason]' to kick a player.\nExample :- /kick 5 not following rules", - "KickCommandKickHost": "You are not permitted to kick the host.", - "KickCommandKickMod": "You are not permitted to kick other moderators.", + "KickCommandKickHost": "You are not permitted to kick the Host.", + "KickCommandKickMod": "You are not permitted to kick other Moderators.", "KickCommandKicked": "was kicked from the game by ", "KickCommandKickedRole": "Their role was", "BanCommandDisabled": "The ban command is currently disabled.", "BanCommandNoAccess": "You do not have access to the ban command.", "BanCommandInvalidID": "Invalid player ID specified.\nPlease use '/ban [playerID] [reason]' to ban a player.\nExample :- /ban 5 not following rules ", - "BanCommandBanHost": "You are not permitted to ban the host.", - "BanCommandBanMod": "You are not permitted to ban other moderators.", + "BanCommandBanHost": "You are not permitted to ban the Host.", + "BanCommandBanMod": "You are not permitted to ban other Moderators.", "BanCommandBanned": "was banned from the game by ", "BanCommandBannedRole": "Their role was", "BanCommandNoReason": "No reason specified.\nPlease use '/ban [playerID] [reason]\nExample :- /ban 5 not following rules", @@ -2003,14 +2004,14 @@ "WarnCommandDisabled": "The warn command is currently disabled.", "WarnCommandNoAccess": "You do not have access to the warn command.", "WarnCommandInvalidID": "Invalid player ID specified.\nPlease use '/warn [playerID] [reason]' to warn a player. \nExample :- /warn 5 lava chatting", - "WarnCommandWarnHost": "You are not permitted to warn the host.", + "WarnCommandWarnHost": "You are not permitted to warn the Host.", "StartCommandNoAccess": "You do not have access to the start command.", "StartCommandDisabled": "The start command is currently disabled.", "StartCommandCountdown": "ERROR\n\nThe game is already starting!", "StartCommandStarted": "The game has been started by {0}!", "StartCommandInvalidCountdown": "ERROR\n\nThe countdown must be between {0} and {1}!", - "WarnCommandWarnMod": "You are not permitted to warn other moderators.", + "WarnCommandWarnMod": "You are not permitted to warn other Moderators.", "WarnCommandWarned": "has been warned. There will be no more warnings given and appropriate action will be taken \n ", "WarnExample": "Use /warn [id] [reason] in future. \nExample :-\n /warn 5 lava chatting", "SayCommandDisabled": "The say command is currently disabled.", @@ -2131,11 +2132,11 @@ "Command.kill": "[Player ID] → Kill assigned player", "Command.exe": "[Player ID] → Eject assigned player", "Command.level": "[Level] → Change your in-game level", - "Command.idlist": "→ Display a list of player IDs", + "Command.idlist": "→ Display a list of player ID's", "Command.qq": "→ Lobby will be posted on QQ website (China only)", "Command.dump": "→ Output Log to Desktop", "Command.death": "→ Display info on how you died", - "Command.icons": "
╳ - The Player was marked by the Blackmailer and can't talk during the Meeting
☆ - Used by Captain to display themselves. Only Crewmates can see the Captain's star
乂 - This player was hexed by the Hex Master and will die if the Hex Master isn't killed or ejected by the end of the Meeting.
♦ - Used by Lawyer or Executioner or Follower.
♥ - Used by Lovers or Romantic.
✚ - Used by Medic to mark their target.
⦿ - This player is in a duel with the Pirate.
!? - This player was marked by the Quizmaster and must answer the question correctly to survive.
☜ - Used by Schrödinger's cat to mark their teammate.
◈ - This player marked by the Shroud and will die if the Shroud is not killed or ejected by the end of the meeting.
⚠ - This player is a Snitch or Solsticer who has finished their tasks.
★ - Used by Super Star or Cyber or Marshall.
† - This player was spelled and will die if the Witch is not killed by the end of the meeting.
∇ - Used by Kamikaze to mark their targets.
■ - Used by Lightning to mark their quantum ghosts.
⊠ - Used by Jailer to mark their prisoner.
● - Used by Baker to mark who has Bread.
♠ - Used by Soul Collector to mark who's death they're predicting.
⦿ - Used by Plaguebearer to mark who they have plagued.", + "Command.icons": "
╳ - The player was marked by the Blackmailer and can't talk during the meeting
☆ - Used by Captain to display themselves. Only Crewmates can see the Captain's star
乂 - This player was hexed by the Hex Master and will die if the Hex Master isn't killed or ejected by the end of the meeting.
♦ - Used by Lawyer or Executioner or Follower.
♥ - Used by Lovers or Romantic.
✚ - Used by Medic to mark their target.
⦿ - This player is in a duel with the Pirate.
!? - This player was marked by the Quizmaster and must answer the question correctly to survive.
☜ - Used by Schrödinger's cat to mark their teammate.
◈ - This player marked by the Shroud and will die if the Shroud is not killed or ejected by the end of the meeting.
⚠ - This player is a Snitch or Solsticer who has finished their tasks.
★ - Used by Super Star or Cyber or Marshall.
† - This player was spelled and will die if the Witch is not killed by the end of the Meeting.
∇ - Used by Kamikaze to mark their targets.
■ - Used by Lightning to mark their Quantum Ghosts.
⊠ - Used by Jailer to mark their prisoner.
● - Used by Baker to mark who has Bread.
♠ - Used by Soul Collector to mark who's death they're predicting.
⦿ - Used by Plaguebearer to mark who they have plagued.", "Command.start": "[Seconds] → Start the game", "Command.iconinfo": "→ Display info on in-meeting icons", @@ -2147,13 +2148,13 @@ "Remaining.NeutralCount": "Neutral Killers left: {0}", "Remaining.ApocalypseCount": "Neutral Apocalypse left: {0}", "EnableKillerLeftCommand": "Enable use of /kcount command", - "ShowMadmatesInLeftCommand": "Show Madmates (including add-ons)", + "ShowMadmatesInLeftCommand": "Show Madmates (including Add-ons)", "ShowApocalypseInLeftCommand": "Show Neutral Apocalypse", "SeeEjectedRolesInMeeting": "See ejected roles in meetings", "ThankYouForUsingTOHE": "Thank you for using TOHE!", "SkillUsedLeft": "You have activated your skill to call a meeting. \nRemaining amount of uses left:", - "NemesisDeadMsg": "The death of the Nemesis means the beginning of the revenge. \nPlease use /rv + [player ID] to kill the specified player \nYou can see player IDs in front of their names. \nOr type /rv to get a list of player IDs", + "NemesisDeadMsg": "The death of the Nemesis means the beginning of the revenge. \nPlease use /rv + [player ID] to kill the specified player \nYou can see player ID's in front of their names. \nOr type /rv to get a list of player ID's", "NemesisAliveKill": "Revenge for the Nemesis can only begin after their death.", "NemesisKillDead": "Choose a living player to take revenge", "NemesisKillSucceed": "[{0}] was killed by the Nemesis!", @@ -2174,14 +2175,14 @@ "GuessGuardianTask": "You can't guess a Guardian who has finished their tasks.", "GuardianCantKilled": "You can't kill a Guardian who has finished their tasks.", "GuessMarshallTask": "You can't guess a Marshall who has finished their tasks.", - "GuessObviousAddon": "Sorry, obvious add-ons cannot be guessed.", - "GuessAdtRole": "Unfortunately, the Host's settings do not allow you to guess add-ons", + "GuessObviousAddon": "Sorry, obvious Add-ons cannot be guessed.", + "GuessAdtRole": "Unfortunately, the Host's settings do not allow you to guess Add-ons", "GuessImpRole": "Unfortunately, the Host's settings do not allow Impostors to guess Impostor roles.", - "GuessCrewRole": "Unfortunately, the Host's settings do not allow crewmates to guess crewmate roles.", + "GuessCrewRole": "Unfortunately, the Host's settings do not allow Crewmates to guess Crewmate roles.", "GuessApocRole": "Fortunately, the Host's settings does not allow Apocalypse to guess Apocalypse roles.", "GuessKill": "{0} was guessed", "GuessNull": "Please select an ID of a living player to guess their role", - "GuessHelp": "Instructions: /bt [Player ID] [Role Name] \nExample: /bt 3 Bait \nYou can see the player IDs before everyone's names \n or use the /id command to list the player IDs", + "GuessHelp": "Instructions: /bt [Player ID] [Role Name] \nExample: /bt 3 Bait \nYou can see the player ID's before everyone's names \n or use the /id command to list the player ID's", "GGGuessMax": "You've reached the maximum guess limit. You can't guess anymore!", "EGGuessMax": "You've reached the maximum guess limit. You can't guess anymore!", "EGGuessSnitchTaskDone": "You thought you could guess the Snitch when all their tasks are done? Nice try. You're not getting out of this that easily.", @@ -2214,8 +2215,8 @@ "MediumNotifySelf": "You established contact with {0}. Please ask them questions and wait for them to respond.\n\nRemaining ability uses: {1}", "MediumKnowPlayerDead": "Someone died somewhere", - "SpurtMinSpeed": "Min Speed", - "SpurtMaxSpeed": "Max Speed", + "SpurtMinSpeed": "Minimum Speed", + "SpurtMaxSpeed": "Maximum Speed", "SpurtModule": "Speed Modulator", "EnableSpurtCharge": "Display The Charge", "SpurtSuffix": "\n« Spurt: {0}% »", @@ -2231,7 +2232,7 @@ "BecomeMadmateCuzMadmateMode": "You became a Madmate because you died", "CleanerCleanBody": "The body has been cleaned", "QuickShooterStoraging": "Bullets stored successfully", - "QuickShooterFailed": "You are still in cooldown.", + "QuickShooterFailed": "You are still in Cooldown.", "PoisonerTargetDead": "Target died", "HexesLookLikeSpells": "Hexes appear as spells", "HexButtonText": "Hex", @@ -2242,29 +2243,29 @@ "WarlockControlKill": "Target died", "OnCelebrityDead": "Warning: Celebrity death!", "OnCyberDead": "Warning: Cyber died!", - "TeleportedInRndVentByDisperser": "Everyone was teleported to vents", + "TeleportedInRndVentByDisperser": "Everyone was teleported to Vents", "TeleportedByTransporter": "Swapping places with: {0}", "ErrorTeleport": "Teleport failed", - "EraseLimit": "Max Erases", + "EraseLimit": "Maximum Erases", "EraserHideVote": "Hide Eraser Votes", "EraserEraseMsgTitle": "ERASER", "EraserEraseNotice": "You erased {0}.\nTheir role will be deactivated after the meeting.", "EraserEraseBaseImpostorOrNeutralRoleNotice": "Oops, your target cannot be erased!", "EraserEraseSelf": "Unfortunately, you can't erase yourself... Wait, why would you do that in the first place?!", - "EraserTryingGuessErasedPlayer": "You can't guess the role of the player you erased, except add-ons", + "EraserTryingGuessErasedPlayer": "You can't guess the role of the player you erased, except Add-ons", "LostRoleByEraser": "You lost your role because of the Eraser", "KilledByScavenger": "The Scavenger killed you and thus teleported off-map", - "SnitchDoneTasks": "Call a meeting to find the impostors", + "SnitchDoneTasks": "Call a meeting to find the Impostors", "SwooperCanVent": "Vent to turn invisible", "SwooperInvisState": "You're invisible", "SwooperInvisStateOut": "You're now visible", - "SwooperInvisInCooldown": "Swoop cooldown isn't up yet. Swooping failed", + "SwooperInvisInCooldown": "Swoop Cooldown isn't up yet. Swooping failed", "SwooperInvisStateCountdown": "Invisibility will expire after {0}s", "SwooperInvisCooldownRemain": "Swoop Cooldown: {0}s", "WraithCanVent": "Vent to turn invisible", "WraithInvisState": "You are invisible", "WraithInvisStateOut": "You are visible again", - "WraithInvisInCooldown": "Ability still on cooldown, vanish failed", + "WraithInvisInCooldown": "Ability still on Cooldown, Vanish failed", "WraithInvisStateCountdown": "Invisibility will expire in {0}s", "WraithInvisCooldownRemain": "{0}s left in invisibility", "WerewolfKillButtonText": "Maul", @@ -2285,10 +2286,10 @@ "BittenByInfectious": "The Infectious infected you!", "InfectiousBittenPlayer": "You successfully infected a player", "GuessNotAllowed": "Sorry, your role does not have access to guessing.", - "GuessOnbound": "This player has the Onbound add-on, so your guess on them was canceled.", + "GuessOnbound": "This player has the Onbound Add-on, so your guess on them was canceled.", "GuessSpecter": "You can't guess a Specter. That allows them to win!", "PacifistOnGuard": "Ability used, {0} uses remain", - "PacifistSkillNotify": "Pacifist reset your kill cooldown", + "PacifistSkillNotify": "Pacifist reset your Kill Cooldown", "BeRecruitedByJackal": "The Jackal has recruited you", "YinYangerAlreadyMarked": "{0} is already in a state of calm, endowed by a fellow YinYanger", "CoronerTrackRecorded": "Track recorded", @@ -2312,11 +2313,11 @@ "MonarchInvalidTarget": "Target cannot be knighted", "GhostTransformTitle": "Your Role Has Transformed!", "SpiritcallerNoticeTitle": "YOU TURNED INTO AN EVIL SPIRIT ", - "SpiritcallerNoticeMessage": "The Spiritcaller has killed you and turned you into an Evil Spirit. Your task now is to help the Spiritcaller to victory by using your spook button to hinder other players or to protect the Spiritcaller. Use /m for more information.", + "SpiritcallerNoticeMessage": "The Spiritcaller has killed you and turned you into an Evil Spirit. Your task now is to help the Spiritcaller to victory by using your Spook button to hinder other players or to protect the Spiritcaller. Use /m for more information.", "OverseerRevealCooldown": "Reveal Cooldown", "OverseerRevealTime": "Reveal Time", "OverseerVision": "Overseer Vision", - "MerchantMaxSell": "Max number of Add-ons to sell", + "MerchantMaxSell": "Maximum number of Add-ons to sell", "MerchantMoneyPerSell": "Amount of money earned for selling an Add-on", "MerchantMoneyRequiredToBribe": "Amount of money required to bribe a killer", "MerchantNotifyBribery": "Inform Merchant when a killer gets bribed", @@ -2327,13 +2328,13 @@ "MerchantSellHelpful": "Can sell Helpful Add-ons", "MerchantSellHarmful": "Can sell Harmful Add-ons", "MerchantSellMixed": "Can sell Mixed Add-ons", - "MerchantSellExperimental": "Can sell experimental Add-ons", + "MerchantSellExperimental": "Can sell Experimental Add-ons", "MerchantSellHarmfulToEvil": "Can sell Harmful Add-ons only to Evil", - "MerchantSellHelpfulToCrew": "Can sell Helpful Add-ons only to Crew", + "MerchantSellHelpfulToCrew": "Can sell Helpful Add-ons only to Crewmates", "MerchantSellOnlyEnabledAddons": "Can sell only enabled Add-ons", "SpiritcallerSpiritMax": "Maximum number of Evil Spirits", - "SpiritcallerSpiritAbilityCooldown": "Evil Spirit ability cooldown", + "SpiritcallerSpiritAbilityCooldown": "Evil Spirit Ability Cooldown", "SpiritcallerFreezeTime": "Evil Spirit ability freeze time", "SpiritcallerProtectTime": "Evil Spirit ability protect time", "SpiritcallerCauseVision": "Evil Spirit ability caused vision", @@ -2342,9 +2343,9 @@ "Message.MessageWaitHelp": "Specify the first argument in seconds.", "Message.TemplateNotFoundHost": "No templates.txt matching {0} were found", "Message.TemplateNotFoundClient": "The Host doesn't have a template called {0}", - "Message.SyncButtonLeft": "There are {0} more emergency buttons left", + "Message.SyncButtonLeft": "There are {0} more Emergency buttons left", "Message.Executed": "{0} was executed", - "Message.HideGameSettings": "The host has hidden the game settings.", + "Message.HideGameSettings": "The Host has hidden the game settings.", "Message.NowOverrideText": "Please enter the root folder of the game.\\Language\\English.dat. Change this text in the dat file \nIf you don't need this feature or want to display regular /n messages. \nPlease disable [Enable only custom /n messages in the settings.]", "Message.NoDescription": "No description", "Message.KickedByDenyName": "{0} was kicked because its name matched {1}", @@ -2355,9 +2356,9 @@ "Message.KickedByInvalidFriendCode": "{0} was kicked because their friend code is invalid.", "Message.TempBannedByInvalidFriendCode": "{0} was temporarily banned because their friend code is invalid.", "Message.AddedPlayerToBanList": "Added {0} to the ban list", - "Message.KickWhoSayStart": "{0} has been kicked by the system. \nThe lobby host doesn't want to see messages where the player asks to start", - "Message.WarnWhoSayStart": "{0} has been warned: {1} times \nThe lobby host doesn't want to see messages where the player asks to start", - "Message.KickStartAfterWarn": "{0} has received {1} warnings, he will be kicked. \nThe lobby host doesn't want to see messages where the player asks to start", + "Message.KickWhoSayStart": "{0} has been kicked by the system. \nThe lobby Host doesn't want to see messages where the player asks to start", + "Message.WarnWhoSayStart": "{0} has been warned: {1} times \nThe lobby Host doesn't want to see messages where the player asks to start", + "Message.KickStartAfterWarn": "{0} has received {1} warnings, he will be kicked. \nThe lobby Host doesn't want to see messages where the player asks to start", "Message.WarnWhoSayBanWord": "{0}, stop sending banned words!", "Message.WarnWhoSayBanWordTimes": "{0} has been warned: {1} times \nif you continue you will be kicked", "Message.KickWhoSayBanWordAfterWarn": "[{0}] received {1} warnings.\nHe was expelled for forbidden words", @@ -2390,9 +2391,9 @@ "Message.YTPlanSelectFailed": "You cannot be assigned as {0}.\nIt may be because you don't have this role enabled, or this role does not support being assigned.", "Message.YTPlanCanNotFindRoleThePlayerEnter": "Could not find the role you searching\nUse command /r to show role list", "Message.YTPlanNotice": "Note: The [YouTuber Plan] is enabled in this lobby, which means the Host can specify their role in the next game to make it easier to get content. If the Host abuses this feature, please exit the game or report it.\nCurrent Creator Credentials:", - "Message.OnlyCanBeUsedByHost": "ERROR\n\nThis command may only be used by the host.", + "Message.OnlyCanBeUsedByHost": "ERROR\n\nThis command may only be used by the Host.", "Message.MaxPlayers": "Maximum players set to ", - "Message.MaxPlayersFailByRegion": "Could not set max players: Vanilla regions support a maximum of 15 players.", + "Message.MaxPlayersFailByRegion": "Could not set maximum players: Vanilla regions support a maximum of 15 players.", "Message.GhostRoleInfo": "Ghost Role Info\nHiya! A little about ghost roles...\n\nGhost roles drastically impact the game, so it's not recommended for smaller lobbies if you're unfamiliar. If not explicitly stated otherwise in the description, the Guard button is their ability button ;)\n\nSpawning:\nGhost-roles only spawn after death; the first x people from (team) to die get them.\n\nPS: If your previous role didn't have tasks(e.g., sheriff), your tasks as a ghost-role aren't needed for task-win", "ApocalypseInfoTitle": "Neutral Apocalypse Info:", "Message.ApocalypseInfo": "Every role of the <#ff174f>Apocalypse Team has their own objective to carry out in order to transform.\n<#2B0804>Transformed <#ff174f>Apocalypse members have a drastic change on the game and are immortal (except for being voted), but everyone will be notified that they have transformed.\n\nRoles: <#e5f6b4>Plaguebearer, <#A675A1>Soul Collector, <#bf9f7a>Baker, <#cc0044>Berserker\nTransformed: <#343136>Pestilence, <#644661>Death, <#83461c>Famine, <#2B0804>War\n\nApocalypse members can see eachother's roles and ability icons.\nLike Neutral Killers, Apocalypse members keep the game going as well, have fun!", @@ -2422,8 +2423,8 @@ "EnableGadientTags": "Enable Gradient Tags (can cause disconnect issues)", "Warning.GradientTags": "Warning:\n\nHost has enabled gradient tags. This feature is not recommended to use because it can cause disconnect issues", "WarningTitle": "Warning!", - "Warning.BrokenVentsInDleksSendInGame": "Warning! The vents on this map are broken", - "Warning.BrokenVentsInDleksMessage": "On the «dlekS ehT» map, the vents are broken, they cannot be fixed in host-only mods, this is a vanilla bug, so any roles using vent as an ability will not spawns on this map", + "Warning.BrokenVentsInDleksSendInGame": "Warning! The Vents on this map are broken", + "Warning.BrokenVentsInDleksMessage": "On the «dlekS ehT» map, the Vents are broken, they cannot be fixed in Host-Only Mods, this is a vanilla bug, so any roles using a Vent as an ability will not spawns on this map", "Warning.NoGameEndIsEnabled": "Warning: {0} is enabled!", @@ -2435,9 +2436,9 @@ "Warning.InvalidRpc": "Kicked {0} because an invalid RPC was received.\nPlease check that no mods other than TOHE are installed.", - "Warning.NoModHost": "TOHE is not installed on the host", + "Warning.NoModHost": "TOHE is not installed on the Host", "Warning.MismatchedVersion": "{0} has a different version of {1}", - "Warning.AutoExitAtMismatchedVersion": "The host has no or a different version of {0}\nYou will be kicked in {1}", + "Warning.AutoExitAtMismatchedVersion": "The Host has no or a different version of {0}\nYou will be kicked in {1}", "Warning.CanNotUseBepInExConsole": "The use of the console is prohibited\nso your console has been off", "Error.MeetingException": "Error: {0}\r\nPlease use SHIFT+M+ENTER to end the meeting", "Error.InvalidRoleAssignment": "Error: Invalid role found for a player during role assignment({0})", @@ -2483,8 +2484,8 @@ "TabGroup.NeutralRoles": "Neutral Roles", "TabGroup.ImpostorRoles": "Impostor Roles", "TabGroup.Addons": "Add-Ons", - "TabMenuDescription_General": "Here you can configure the functions that are in the mod", - "TabMenuDescription_Roles&AddOns": "Here you can add, remove and change the settings of all roles or add-ons in the mod", + "TabMenuDescription_General": "Here you can configure the functions that are in the Mod", + "TabMenuDescription_Roles&AddOns": "Here you can add, remove and change the settings of all Roles or Add-ons in the Mod", "Experimental.Roles": "★ Experimental Roles (NOTICE: Use with caution, as these require testing)", "ActiveRolesList": "Active Roles List", "ForExample": "Example Use", @@ -2508,12 +2509,12 @@ "ModBrokenMessage": "The MOD file is damaged.\nPlease reinstall.", "UnsupportedVersion": "Unsupported Among Us version.\nPlease Update Among Us", "DisabledByProgram": "The program has disabled public rooms", - "EnterVentToWin": "Enter Vent to Win!!", + "EnterVentToWin": "Enter a Vent to Win!!", "EatenByPelican": "You're swallowed, waiting for the Pelican to die or a meeting", "FireworkerPutPhase": "{0} Fireworker Left", "FireworkerWaitPhase": "Wait for it...", "FireworkerReadyFirePhase": "Fire!", - "EnterVentWinCountDown": "Enter vent within {0} seconds to win!", + "EnterVentWinCountDown": "Enter a Vent within {0} seconds to win!", "On": "ON", "Off": "OFF", "ColoredOn": "ON", @@ -2535,7 +2536,7 @@ "LastEndReason": "★ End Reason", "KillLog": "Kill Log", "MainRoleLog": "Role Convert Log", - "Maximum": "Max", + "Maximum": "Maximum", "RoleRate": "ON", "RoleOn": "ALWAYS", "RoleOff": "OFF", @@ -2568,7 +2569,7 @@ "Preset_4": "Preset 4", "Preset_5": "Preset 5", "Standard": "Standard", - "HidenSeekTOHE": "Hide And Seek", + "HidenSeekTOHE": "Hide & Seek", "GameMode": "Game Mode", "PressTabToNextPage": "Press Tab or Number for Next Page...", "RoleSummaryText": "Role Summary:", @@ -2655,7 +2656,7 @@ "IllegalColor": "Please enter the correct color", "DisableUseCommand": "The Host's settings do not allow this command to be used.", "SureUse.quit": "We will kick you and block you from entering this lobby again. This setting is irreversible. If you really want it, please send the command /qt {0}", - "PlayerIdList": "List of player IDs: ", + "PlayerIdList": "List of player ID's: ", "CancelStartCountDown": "The starting countdown was canceled", "RestTOHESetting": "TOHE settings have been restored to default", "FPSSetTo": "FPS Set To: {0}", @@ -2687,11 +2688,11 @@ "EndWhenPlayerBug": "End the game when a modded player gets a critical error (While loading)", "AntiBlackOutRequestHostToForceEnd": "You were the reason for the black screen. The game will end", - "AntiBlackOutHostRejectForceEnd": "You were the reason for the black screen, and the host is not going to end the game\nYou will be disconnected soon", + "AntiBlackOutHostRejectForceEnd": "You were the reason for the black screen, and the Host is not going to end the game\nYou will be disconnected soon", "RpcAntiBlackOutNotifyInLobby": "Because of {0}, an unknown error occurred. To prevent a black screen, turn off [{1}] in settings.", "RpcAntiBlackOutEndGame": "Because of {0}, an unknown error occurred, the game will end to prevent a black screen.", - "RpcAntiBlackOutIgnored": "Because of {0}, an unknown error occurred, but the game will continue without that player due to host settings.", + "RpcAntiBlackOutIgnored": "Because of {0}, an unknown error occurred, but the game will continue without that player due to Host settings.", "RpcAntiBlackOutKicked": "{0} was kicked due to having a blackout error on its side.", "NextPage": "Next Page", @@ -2732,10 +2733,10 @@ "GameOverReason.HumansDisconnect": "Crewmates disconnected", "GameOverReason.ImpostorByVote": "The Crewmates were ejected", "GameOverReason.ImpostorByKill": "The Impostors killed everyone", - "GameOverReason.ImpostorBySabotage": "Crewmates failed to fix a critical sabotage", + "GameOverReason.ImpostorBySabotage": "Crewmates failed to fix a Critical Sabotage", "GameOverReason.ImpostorDisconnect": "Impostors disconnected", "FortuneTellerCheck.TaskDone": "[{0}]Role -[{1}]", - "DevAndSpnTitle": "TOHE family", + "DevAndSpnTitle": "TOHE Family", "FortuneTellerCheck.Null": "{0} is a role that is not listed.\nThis message should not appear normally.", "FortuneTellerCheck.Result": "{0} is either one of the following roles:\n{1}", "SunnyboyChance": "Sunnyboy Chance", @@ -2798,7 +2799,7 @@ "8BallNotLikely": "Outlook not so good", "8BallLikely": "Outlook good", "8BallDontCount": "Don't count on it", - "8BallStop": "Stop using an 8Ball in an Among Us mod", + "8BallStop": "Stop using an 8Ball in an Among Us Mod", "8BallPossibly": "Possibly", "8BallProbably": "Probably", "8BallProbablyNot": "Probably not", @@ -2809,20 +2810,20 @@ "ChanceToMiss": "Chance to miss a kill", - "SoulCollectorPointsToWin": "Required number of souls", + "SoulCollectorPointsToWin": "Required number of Souls", "SoulCollectorTarget": "You have predicted the death of {0}", "SoulCollectorTitle": "SOUL COLLECTOR", - "SoulCollector_CollectOwnSoulOpt": "Can collect their own soul", - "SoulCollectorSelfVote": "Host settings do not allow you to collect your own soul", + "SoulCollector_CollectOwnSoulOpt": "Can collect their own Soul", + "SoulCollectorSelfVote": "Host settings do not allow you to collect your own Soul", "SoulCollectorToDeath": "You have become Death!!!", "SoulCollectorTransform": "Now Soul Collector has become Death, Destroyer of Worlds and Horseman of the Apocalypse!

Find them and vote them out before they bring forth Armageddon!", - "GetPassiveSouls": "Gain a passive soul every round", - "PassiveSoulGained": "You have gained a passive soul from the underworld.", + "GetPassiveSouls": "Gain a passive Soul every round", + "PassiveSoulGained": "You have gained a passive Soul from the underworld.", "SoulCollectorTargetUsed": "You've already targeted someone this round!", "SoulCollectorSoulGained": "Soul gained", "SoulCollectorCanVent": "Soul Collector can Vent", "DeathMeetingTimeIncrease": "Increased Meeting time when Death exists", - "SoulCollectorMeetingDeath": "Your target has died during the meeting. You have gained a soul.", + "SoulCollectorMeetingDeath": "Your target has died during the meeting. You have gained a Soul.", "SoulCollectorKillButtonText": "Predict", "SoulCollectorHasImpostorVision": "Soul Collector has Impostor vision", @@ -2846,7 +2847,7 @@ "BakerBreadGivesEffects": "Bread gives additional effects", "BakerTransformNoMoreBread": "Baker transforms if they do not have enough bread", "FamineKillButtonText": "Starve", - "FamineStarveCooldown": "Famine starve cooldown", + "FamineStarveCooldown": "Famine Starve Cooldown", "FamineCantStarveApoc": "You cannot starve other Apocalypse members!", "FamineAlreadyStarved": "That player has already been starved!", "FamineStarved": "Player starved", @@ -2884,39 +2885,39 @@ "TimeMasterVentButtonText": "Time Shield", "BodyCannotBeReported": "Body could not be reported", "BurstKillDelay": "Burst Kill Delay", - "BurstNotify": "That was a Burst! Get in a vent or die.", + "BurstNotify": "That was a Burst! Get in a Vent or die.", "BurstFailed": "Burst failed to bomb you", "ShroudButtonText": "Shroud", "ShroudCooldown": "Shroud Cooldown", "Message.Shrouded": "One or more players were shrouded by a Shroud!\n\nGet rid of the Shroud or all shrouded players will suicide!", - "LudopathRandomKillCD": "Maximum kill cooldown", + "LudopathRandomKillCD": "Maximum Kill Cooldown", "UnderdogMaximumPlayersNeededToKill": "Maximum players needed to start killing", "GodfatherTargetCountMode": "Killer turns into", "GodfatherCount_Refugee": "Refugee", "GodfatherCount_Madmate": "Madmate", "GodfatherRefugeeMsg": "You have been recruited by GodFather!", - "MissChance": "Chance To Miss", - "IncreaseByOneIfConvert": "Increase The KillCount +1 If a Crew Is Converted", + "MissChance": "Chance to Miss", + "IncreaseByOneIfConvert": "Increase the KillCount +1 if a Crewmate is Converted", "HawkMissed": "Missed!", - "HawkCanKillNum": "Max Slices", + "HawkCanKillNum": "Maximum Slices", "HawkKillMax": "You've run out of ability uses", "HawkKillTooManyDead": "Too many people are dead", - "MinimumPlayersAliveToKill": "Minimum Players Alive To Kill", - "BloodMoonCanKillNum": "Max BloodLettings", + "MinimumPlayersAliveToKill": "Minimum Players Alive to Kill", + "BloodMoonCanKillNum": "Maximum BloodLettings", "BloodMoonTimeTilDie": "Time Until Death", "PossessorPossessCooldown": "Possession Cooldown", "PossessorPossessDuration": "Possession Duration", "PossessorAlertRange": "Alert Range", "PossessorFocusRange": "Focus Range", "DeathTimer": "Death In: {DeathTimer}s", - "BerserkerKillCooldown": "Berserker kill cooldown", - "BerserkerMax": "Max level that Berserker can reach", + "BerserkerKillCooldown": "Berserker Kill Cooldown", + "BerserkerMax": "Maximum level that Berserker can reach", "BerserkerHasImpostorVision": "Berserker Has Impostor Vision", "WarHasImpostorVision": "War Has Impostor Vision", "BerserkerCanVent": "Berserker Can Vent", "WarCanVent": "War Can Vent", - "BerserkerOneCanKillCooldown": "Unlock lower kill cooldown", - "BerserkerOneKillCooldown": "Kill cooldown after unlocking", + "BerserkerOneCanKillCooldown": "Unlock lower Kill Cooldown", + "BerserkerOneKillCooldown": "Kill Cooldown after unlocking", "BerserkerTwoCanScavenger": "Unlock scavenged kills", "BerserkerThreeCanBomber": "Unlock bombed kills", "BerserkerFourCanNotKill": "Become War", @@ -2926,7 +2927,7 @@ "KilledByBerserker": "Killed by Berserker", "BerserkerToWar": "You have become War!!!", "BerserkerTransform": "The Berserker has transformed into War, Horseman of the Apocalypse! Cry 'Havoc!', and let slip the dogs of war.", - "WarKillCooldown": "War kill cooldown", + "WarKillCooldown": "War Kill Cooldown", "BerserkerCanKillTeamate": "Can kill other Neutral Apocalypse", "BlackmailerSkillCooldown": "Blackmail Cooldown", @@ -2935,7 +2936,7 @@ "BlackmaileKillTitle": "BLACKMAILER", "UnluckyTaskSuicideChance": "Chance to suicide from doing tasks", "UnluckyKillSuicideChance": "Chance to suicide from killing", - "UnluckyVentSuicideChance": "Chance to suicide from venting", + "UnluckyVentSuicideChance": "Chance to suicide from Venting", "UnluckyReportSuicideChance": "Chance to suicide from reporting bodies", "UnluckyOpenDoorSuicideChance": "Chance to suicide from opening a door", "NeutralCanBeAware": "Neutrals can become Aware", @@ -2956,7 +2957,7 @@ "PenguinKillButtonText": "Drag", "PenguinTimerText": "Drag Timer", "PenguinTargetOnCheckMurder": "You are grabbed. Try to escape that first!", - "WitnessTime": "Max Time after killing where killer appears red", + "WitnessTime": "Maximum Time after killing where killer appears red", "WitnessButtonText": "Examine", "WitnessFoundInnocent": "✓", "WitnessFoundKiller": "⚠", @@ -2967,7 +2968,7 @@ "SwapVote": "The votes of {0} and {1} were swapped!", "SwapDead": "Sorry, you can't swap votes after death.", "SwapNull": "Please choose the ID of a living player to swap votes with. Use 253 to clear swaps", - "SwapHelp": "Command Format: /sw [playerID] to select the target\nYou can see the player IDs next to the player names or use /id to see the player ID list.\nUse /swap 253 to clear your previous swap", + "SwapHelp": "Command Format: /sw [playerID] to select the target\nYou can see the player ID's next to the player names or use /id to see the player ID list.\nUse /swap 253 to clear your previous swap", "Swap1": "Swap target 1 selected", "Swap2": "Swap target 2 selected", "CancelSwap": "Cleared your previous swap!", @@ -2989,13 +2990,13 @@ "ChanceToSpawn": "Chance to spawn", "ChanceToSpawnAnother": "Chance to spawn another", "BloodthirstKillCD": "Bloodthirst Kill Cooldown", - "BloodthirstPlayerCount": "Max players alive for Bloodthirst", + "BloodthirstPlayerCount": "Maximum players alive for Bloodthirst", "ReflectHarmfulInteractions": "Reflect harmful interactions", - "DiseasedCDOpt": "Increase the cooldown by", + "DiseasedCDOpt": "Increase the Cooldown by", "DiseasedCDReset": "Cooldown returns to normal after a meeting", - "AntidoteCDOpt": "Decrease the cooldown by", + "AntidoteCDOpt": "Decrease the Cooldown by", "AntidoteCDReset": "Cooldown returns to normal after a meeting", "GlowRadius": "Glow Radius", @@ -3019,7 +3020,7 @@ "RememberCooldown": "Imitate Cooldown", "RefugeeKillCD": "Refugee's Kill Cooldown", - "RememberedNeutralKiller": "You remembered you were a neutral killer!", + "RememberedNeutralKiller": "You remembered you were a Neutral killer!", "RememberedMaverick": "You remembered you were a Maverick!", "RememberedPursuer": "You remembered you were a Pursuer!", "RememberedFollower": "You remembered you were a Follower!", @@ -3028,12 +3029,12 @@ "ReportWhenFailedRemember": "Report Dead Body when failed to remember", "RememberedImitator": "You remembered you were an Imitator.", "RememberedImpostor": "You remembered you were an Impostor!", - "RememberedCrewmate": "You remembered you were a crewmate!", + "RememberedCrewmate": "You remembered you were a Crewmate!", "ImitatorImitated": "An Imitator imitated your role!", "ImitatorInvalidTarget": "Imitation failed", "RememberButtonText": "Remember", "ImitatorKillButtonText": "Imitate", - "IncompatibleNeutralMode": "If neutral is incompatible, turn into", + "IncompatibleNeutralMode": "If Neutral is incompatible, turn into", "RememberedYourRole": "An Amnesiac remembered your role!", "YouRememberedRole": "You remembered who you were!", @@ -3042,25 +3043,25 @@ "BanditStealMode_Instantly": "Instantly", "BanditMaxSteals": "Maximum Steals", "BanditCanStealBetrayalAddon": "Can Steal Betrayal Add-ons", - "BanditCanStealImpOnlyAddon": "Can Steal Impostor Only Addons", - "Bandit_NoStealableAddons": "Could not steal add-on from the player", - "BanditStealCooldown": "Steal cooldown", + "BanditCanStealImpOnlyAddon": "Can Steal Impostor Only Add-ons", + "Bandit_NoStealableAddons": "Could not steal Add-on from the player", + "BanditStealCooldown": "Steal Cooldown", "DoppelMaxSteals": "Maximum Steals", - "DoppelCurrentVictimCanSeeRolesAsDead": "Last victim can see role and add-on info of alive players as a ghost", + "DoppelCurrentVictimCanSeeRolesAsDead": "Last victim can see Role and Add-on info of alive players as a ghost", - "NecromancerRevengeTime": "Necromancy time", + "NecromancerRevengeTime": "Necromancy Time", "NecromancerRevenge": "You have {0}s to kill {1}", "NecromancerSuccess": "Necromancy complete! You live to see another day.", "NecromancerHide": "Venting is disabled, hide from the Necromancer!", - "RetributionistDeadMsg": "The death of the Retributionist means the beginning of retribution. \nPlease use /ret + [player ID] to kill the specified player \nYou can see player IDs in front of their names. \nOr type /ret to get a list of player IDs", + "RetributionistDeadMsg": "The death of the Retributionist means the beginning of retribution. \nPlease use /ret + [player ID] to kill the specified player \nYou can see player ID's in front of their names. \nOr type /ret to get a list of player ID's", "RetributionistAliveKill": "Retribution for the Retributionist may only begin after their death.", "RetributionistKillMax": "You've reached the maximum amount of kills. You can't kill anymore!", "RetributionistKillDead": "Choose a living player to kill.", "RetributionistKillSucceed": "{0} was killed by the Retributionist!", "RetributionistKillDisable": "You can't retribute until your tasks are done.", "CanOnlyRetributeWithTasksDone": "Can only retribute on task completion", - "RetributionistCanKillNum": "Max retributions", + "RetributionistCanKillNum": "Maximum retributions", "RetributionistKillTooManyDead": "Too many players are dead. You can't retribute.", "MinimumPlayersAliveToRetri": "Minimum players alive to retribute", "MinimumNoKillerEjectsToKill": "Minimum meetings passed with no killer ejects to kill", @@ -3086,20 +3087,20 @@ "CaptainSlowTaskRequired": "Number of tasks completed after which target speed is reduced", "InspectorTryHideMsg": "Hide Inspector's commands", - "MaxInspectCheckLimit": "Max inspections per game", - "InspectCheckLimitPerMeeting": "Max inspections per meeting", + "MaxInspectCheckLimit": "Maximum inspections per game", + "InspectCheckLimitPerMeeting": "Maximum inspections per meeting", "InspectCheckTargetKnow": "Targets know they were checked by Inspector", "InspectCheckOtherTargetKnow": "Targets know who they were checked with", "InspectorDead": "You can not use your power after death", - "InspectCheckMax": "Max inspections per game reached!\nYou can not use your power anymore.", - "InspectCheckRound": "Max inspections per round reached!\nYou can check again in the next round.", + "InspectCheckMax": "Maximum inspections per game reached!\nYou can not use your power anymore.", + "InspectCheckRound": "Maximum inspections per round reached!\nYou can check again in the next round.", "InspectCheckSelf": "HA!! You thought it would be this easy. You can not check yourself", "InspectCheckReveal": "HA! You thought it would be this easy. You can not check a role that is revealed", "InspectCheckTitle": "INSPECTOR ", "InspectCheckTrue": "{0} and {1} are in the same team!", "InspectCheckFalse": "{0} and {1} are NOT in the same team!", "InspectCheckTargetMsg": " were checked by Inspector.", - "InspectCheckHelp": "Instructions: /cmp [Player ID 1] [Player ID 2] \nExample: /cmp 1 5 \nYou can see the player IDs before everyone's names \n or use the /id command to list the player IDs", + "InspectCheckHelp": "Instructions: /cmp [Player ID 1] [Player ID 2] \nExample: /cmp 1 5 \nYou can see the player ID's before everyone's names \n or use the /id command to list the player ID's", "InspectCheckNull": "Please select an ID of a living player to check their team", "InspectCheckBaitCountMode": "Bait counts as revealing role if Bait reveal on first meeting is on", "InspectCheckRevealTarget": "When tasks are done, the target knows the team of the other target", @@ -3108,7 +3109,7 @@ "EgoistCountMode.Original": "Original", "EgoistCountMode.Neutral": "Neutral", - "JailerJailCooldown": "Jail cooldown", + "JailerJailCooldown": "Jail Cooldown", "JailerMaxExecution": "Maximum executions", "JailerNBCanBeExe": "Can execute Neutral Benign", "JailerNCCanBeExe": "Can execute Neutral Chaos", @@ -3123,27 +3124,27 @@ "CanNotTrialJailed": "You can not trial the target.", "notifyJailedOnMeeting": "Notify jailed player when a meeting starts", "JailedNotifyMsg": "The Jailer has jailed you. No one can guess or judge you. You can only guess The Jailer.\n\nIf Jailer votes you, you will be executed after the meeting ends.", - "JailerTitle": "Jailer", + "JailerTitle": "JAILER", - "CopyCatCopyCooldown": "Copy cooldown", + "CopyCatCopyCooldown": "Copy Cooldown", "CopyCatRoleChange": "Your role has been changed to {0}", "CopyCatCanNotCopy": "You can not copy the target's role", "CopyButtonText": "Copy", - "CopyCrewVar": "Can copy evil variants of crew roles", - "CopyTeamChangingAddon": "Can copy team changing add-on", + "CopyCrewVar": "Can copy evil variants of Crewmate roles", + "CopyTeamChangingAddon": "Can copy team changing Add-on", - "MaxCleanserUses": "Max cleanses", + "MaxCleanserUses": "Maximum Cleanses", "CleansedCanGetAddon": "Cleansed player can get Add-on", "CleanserTitle": "CLEANSER", "CleanserRemoveSelf": "You can not cleanse yourself", - "CleanserCantRemove": "Oops! the player can not be cleansed.", + "CleanserCantRemove": "Oops! the player can not be Cleansed.", "CleanserRemovedRole": "{0} has been cleansed. All their Add-ons will be removed after the meeting.\n\nYour vote has been returned and you can vote for someone.", - "LostAddonByCleanser": "The cleanser removed all your Add-ons", + "LostAddonByCleanser": "The Cleanser removed all your Add-ons", - "MaxProtections": "Max protections", + "MaxProtections": "Maximum Protections", "KeeperHideVote": "Hide Keeper's vote", "KeeperProtect": "You chose to protect {0}, your vote has been returned", - "KeeperTitle": "Keeper", + "KeeperTitle": "KEEPER", "MaulRadius": "Maul Radius", "ImpKnowCyberDead": "Impostors know if Cyber died", @@ -3160,7 +3161,7 @@ "ImpCanBeLoyal": "Impostors can become Loyal", "CrewCanBeLoyal": "Crewmates can become Loyal", "TasklessCrewCanBeLazy": "Crewmates without tasks can be Lazy", - "TaskBasedCrewCanBeLazy": "Task based crewmates can be Lazy", + "TaskBasedCrewCanBeLazy": "Task based Crewmates can be Lazy", "SheriffCanBeMadmate": "Sheriff can become Madmate", "MayorCanBeMadmate": "Mayor can become Madmate", "NGuesserCanBeMadmate": "Nice Guesser can become Madmate", @@ -3183,7 +3184,7 @@ "CouncillorMurderMaxGame": "Sorry, you've reached the maximum amount of murders for the game.", "Councillor_LaughToWhoMurderSelf": "Hahaha, who would've thought someone was stupid enough to murder themselves?\n\nGuess it happens to be... YOU!", "Councillor_MurderKill": "{0} was murdered.", - "Councillor_MurderHelp": "Command: /tl [player ID]\nYou can see the players' IDs before the players' names.\nOr use /id to view the list of all player IDs.", + "Councillor_MurderHelp": "Command: /tl [player ID]\nYou can see the players' ID's before the players' names.\nOr use /id to view the list of all player ID's.", "Councillor_MurderNull": "Please choose a living player to murder.", "Councillor_MurderKillTitle": "WICKED COURT ", "CouncillorMakeEvilJudgeClear": "Show Trial as Councillor Murder", @@ -3199,13 +3200,13 @@ "DazzlerDazzled": "You were dazzled by the Dazzler!", "DazzlerCauseVision": "Reduced vision", - "DazzlerDazzleLimit": "Max number of players affected by reduced vision", + "DazzlerDazzleLimit": "Maximum number of players affected by reduced vision", "DazzlerResetDazzledVisionOnDeath": "Reset vision of dazzled players on death/eject", "DazzleCooldown": "Dazzle Cooldown", "DazzleButtonText": "Dazzle", "MoleVentButtonText": "Dig", - "MoleVentCooldown": "Dig cooldown", + "MoleVentCooldown": "Dig Cooldown", "AddictVentButtonText": "Get Fix", "AddictInvulnerbilityTimeAfterVent": "Invulnerability Time", @@ -3221,7 +3222,7 @@ "AlchemistVentButtonText": "Drink", "AlchemistGotShieldPotion": "Potion of Resistance: Grants a temporary shield", "AlchemistGotSightPotion": "Potion of Night Vision: Gives temporary enhanced vision", - "AlchemistGotQFPotion": "Potion of Fixing: Allows you to fix one sabotage instantly", + "AlchemistGotQFPotion": "Potion of Fixing: Allows you to fix one Sabotage instantly", "AlchemistGotTPPotion": "Potion of Warping: Teleports you to a random player", "AlchemistGotSuicidePotion": "Potion of Poison: Poisons you", "AlchemistGotSpeedPotion": "Potion Of Speed: Hastens you", @@ -3249,19 +3250,19 @@ "AlchemistHasSpeed": "Potion Of Speed started", "AlchemistSpeedOut": "Potion Of Speed ended", - "DeathpactDuration": "Death Pact duration", - "DeathPactCooldown": "Death Pact Assign Cooldown", - "DeathpactNumberOfPlayersInPact": "Number of players in Death Pact", - "DeathpactShowArrowsToOtherPlayersInPact": "Show arrows leading to other players in Death Pact", - "DeathpactReduceVisionWhileInPact": "Reduce vision for players in Death Pact", - "DeathpactVisionWhileInPact": "Vision for players in Death Pact", - "DeathpactKillPlayersInDeathpactOnMeeting": "Kill players in Death Pact on meeting", - "DeathpactPlayersInDeathpactCanCallMeeting": "Players in active Death Pact can call meeting", + "DeathpactDuration": "Deathpact Duration", + "DeathPactCooldown": "Deathpact Assign Cooldown", + "DeathpactNumberOfPlayersInPact": "Number of players in Deathpact", + "DeathpactShowArrowsToOtherPlayersInPact": "Show arrows leading to other players in Deathpact", + "DeathpactReduceVisionWhileInPact": "Reduce vision for players in Deathpact", + "DeathpactVisionWhileInPact": "Vision for players in Deathpact", + "DeathpactKillPlayersInDeathpactOnMeeting": "Kill players in Deathpact on meeting", + "DeathpactPlayersInDeathpactCanCallMeeting": "Players in active Deathpact can call meeting", "DeathpactActiveDeathpact": "Find {0} in {1} seconds.", - "DeathpactCouldNotAddTarget": "Target can't be added to Death Pact.", - "DeathpactComplete": "Death Pact was concluded.", - "DeathpactExecuted": "Death Pact was executed.", - "DeathpactAverted": "Death Pact was averted.", + "DeathpactCouldNotAddTarget": "Target can't be added to Deathpact.", + "DeathpactComplete": "Deathpact was concluded.", + "DeathpactExecuted": "Deathpact was executed.", + "DeathpactAverted": "Deathpact was averted.", "DeathpactButtonText": "Assign", "DevourerHideNameConsumed": "Hide the names of consumed players", "DevourCooldown": "Devour Cooldown", @@ -3297,17 +3298,17 @@ "OracleCheckSelfMsg": "You can't even trust yourself, huh?", "OracleCheckLimit": "Reminder: You have {0} uses left", "OracleCheckMsgTitle": "ORACLE ", - "OracleCheck.NotCrewmate": "Appears not to be a crewmate", - "OracleCheck.Crewmate": "Appears to be a crewmate", - "OracleCheck.Neutral": "Appears to be a neutral", + "OracleCheck.NotCrewmate": "Appears not to be a Crewmate", + "OracleCheck.Crewmate": "Appears to be a Crewmate", + "OracleCheck.Neutral": "Appears to be a Neutral", "OracleCheck.Impostor": "Appears to be an Impostor", "OracleCheck": "Target Results:", "FailChance": "Chance of showing incorrect result", - "OracleCheckAddons": "Oracle checks add-ons", + "OracleCheckAddons": "Oracle checks Add-ons", "ChameleonCanVent": "Vent to disguise", "ChameleonInvisState": "You are disguising!", "ChameleonInvisStateOut": "Your disguise ended", - "ChameleonInvisInCooldown": "Ability still on cooldown, disguise failed", + "ChameleonInvisInCooldown": "Ability still on Cooldown, disguise failed", "ChameleonInvisStateCountdown": "Disguise will expire in {0}s", "ChameleonInvisCooldownRemain": "Disguise Cooldown: {0}s", "ChameleonCooldown": "Disguise Cooldown", @@ -3338,7 +3339,7 @@ "AdmirerInvalidTarget": "Target cannot be admired", "SpiritualistNoticeTitle": "SPIRITUALIST ", - "SpiritualistNoticeMessage": "The Spiritualist has an arrow pointing to you!\nYou can use them to a killer or frame a crewmate", + "SpiritualistNoticeMessage": "The Spiritualist has an arrow pointing to you!\nYou can use them to a killer or frame a Crewmate", "SpiritualistShowGhostArrowForSeconds": "Ghost arrow duration", "SpiritualistShowGhostArrowEverySeconds": "Ghost arrow interval", "EnigmaClueStage1Tasks": "Number of Tasks to complete to see Stage 1 Clues", @@ -3409,7 +3410,7 @@ "VultureCooldownUp": "Eat Cooldown finished", "GhastlyPossessCD": "Possess Cooldown", - "GhastlyMaxPossessions": "Max Possessions", + "GhastlyMaxPossessions": "Maximum Possessions", "GhastlyPossessionDuration": "Possession Duration", "GhastlySpeed": "Ghastly Speed", "GhastlyKillAllies": "Ghastly cannot possess allies", @@ -3424,7 +3425,7 @@ "TasksMarkPerRound": "Number of tasks that can be marked in one round", "TaskinatorBombPlanted": "Bomb has been planted", - "ShieldDuration": "Shield duration", + "ShieldDuration": "Shield Duration", "ShieldIsOneTimeUse": "Shield breaks after one kill attempt", "BenefactorTaskMarked": "Task marked successfully", "BenefactorTargetGotShield": "You got a shield by Benefactor", @@ -3447,14 +3448,14 @@ "Heads": "Heads", "Tails": "Tails", "SpyRedNameDur": "Colored Name Duration", - "SpyInteractionBlocked": "Block kill button interaction", - "AgitaterBombCooldown": "Agitator bomb cooldown", - "AgitaterPassCooldown": "Bomb pass cooldown", - "BombExplodeCooldown": "Bomb explode cooldown", + "SpyInteractionBlocked": "Block Kill button interaction", + "AgitaterBombCooldown": "Agitator Bomb Cooldown", + "AgitaterPassCooldown": "Bomb Pass Cooldown", + "BombExplodeCooldown": "Bomb Explode Cooldown", "AgitaterPassNotify": "Bomb successfully passed", "AgitaterTargetNotify": "YOU HAVE THE BOMB!! Pass it to someone else", "AgitaterCanGetBombed": "Agitator can get bomb", - "AgitaterAutoReportBait": "Agitator Auto Report Bait", + "AgitaterAutoReportBait": "Agitator can Auto Report Bait", "SeekerPointsToWin": "Number of points required to win", "SeekerTagCooldown": "Tag Cooldown", @@ -3464,16 +3465,16 @@ "PixiePointsToWin": "Number of points required to win", "MaxTargets": "Maximum number of targets per round", - "MarkCooldown": "Mark cooldown", + "MarkCooldown": "Mark Cooldown", "PixieSuicide": "Pixie suicides if the target is not voted out", "PixieMaxTargetReached": "You have already selected all the targets this round", "PixieTargetAlreadySelected": "Target is already selected", "PixieButtonText": "Mark", - "PlagueBearerCooldown": "Plague cooldown", - "PlagueBearerCanVent": "Can vent", + "PlagueBearerCooldown": "Plague Cooldown", + "PlagueBearerCanVent": "Can Vent", "PlagueBearerHasImpostorVision": "Has Impostor vision", - "PestilenceCooldown": "Pestilence Kill cooldown", + "PestilenceCooldown": "Pestilence Kill Cooldown", "PestilenceCanVent": "Pestilence Can Vent", "PestilenceHasImpostorVision": "Pestilence Has Impostor Vision", "PestilenceKillGuessers": "Kill players who guess Pestilence", @@ -3500,7 +3501,7 @@ "GuessMasterMisguess": "{0} misguessed", "GuessMasterTargetRole": "Someone tried to guess {0}", - "GuessMasterTitle": "Guess Master ", + "GuessMasterTitle": "GUESS MASTER ", "DoomsayerAmountOfGuessesToWin": "Amount of Guesses to win", "DCanGuessImpostors": "Can Guess Impostors", @@ -3508,17 +3509,17 @@ "DCanGuessNeutrals": "Can Guess Neutrals", "DCanGuessAdt": "Can Guess Add-Ons", "DoomsayerAdvancedSettings": "Advanced Settings", - "DoomsayerMaxNumberOfGuessesPerMeeting": "Max number of guesses per meeting", + "DoomsayerMaxNumberOfGuessesPerMeeting": "Maximum number of guesses per meeting", "DoomsayerKillCorrectlyGuessedPlayers": "Kill correctly guessed players", "DoomsayerDoesNotSuicideWhenMisguessing": "Doomsayer does not suicide when misguessing", "DoomsayerMisguessRolePrevGuessRoleUntilNextMeeting": "Misguessing role prevents guessing roles until next meeting", "DoomsayerTryHideMsg": "Hide Doomsayer's commands", "DoomsayerCantGuess": "Sorry, you can only guess the roles in the next meeting.", "DoomsayerCorrectlyGuessRole": "You guessed the role correctly!\nBut the player didn't die because the Host settings don't allow them to die", - "DoomsayerNotCorrectlyGuessRole": "You didn't correctly guess the role!\nBut you didn't die because the Host's settings don't allow you to die", - "DoomsayerGuessCountMsg": "You correctly guessed {0} roles", + "DoomsayerNotCorrectlyGuessRole": "You didn't correctly guess the Role!\nBut you didn't die because the Host's settings don't allow you to die", + "DoomsayerGuessCountMsg": "You correctly guessed {0} Roles", "DoomsayerGuessCountTitle": "DOOMSAYER", - "DoomsayerGuessSameRoleAgainMsg": "You tried to guess the same role or add-on that you guessed before", + "DoomsayerGuessSameRoleAgainMsg": "You tried to guess the same Role or Add-on that you guessed before", "EveryoneCanKnowMini": "Everyone can see the Mini", "CanBeEvil": "Mini can be an Impostor", @@ -3547,26 +3548,26 @@ "YouKillRandomizer3": "You kill Randomizer, Kill CD change to 600s!", "YouKillRandomizer4": "You kill Randomizer, Triggered Random Revenge!", "MadmateCanBeHurried": "Madmate can be Hurried on game start", - "TaskBasedCrewCanBeHurried": "Task-based Crews can be Hurried", - "HurriedCanBeConverted": "Hurried can be recruited in the game (excludes madmate)", + "TaskBasedCrewCanBeHurried": "Task-based Crewmates can be Hurried", + "HurriedCanBeConverted": "Hurried can be recruited in the game (excludes Madmate)", "Developer": "Developer", "Sponsor": "Sponsor", "Booster": "Server Booster", "Translator": "Translator", "NoAccess": "Unauthorized Access!\n\n Please open up a ticket in the discord server to know more (discord.gg/tohe)", "DCNotify.Hacking": "You were banned for hacking.\n\nPlease stop.", - "DCNotify.Banned": "You were banned from this lobby.\n\nContact the host if this was a mistake.", + "DCNotify.Banned": "You were banned from this lobby.\n\nContact the Host if this was a mistake.", "DCNotify.Kicked": "You were kicked from this lobby.\n\nYou may still rejoin.", "DCNotify.DCFromServer": "You disconnected from the server.\r\nThis could be an issue with either the servers or your network.", "DCNotify.GameNotFound": "This lobby code is invalid.\n\nCheck the code and/or server and try again.", "DCNotify.GameStarted": "This lobby is currently in-game.\n\nWait for it to end or find a different lobby.", - "DCNotify.GameFull": "This lobby is currently full.\n\nCheck with the host to see if you may join.", + "DCNotify.GameFull": "This lobby is currently full.\n\nCheck with the Host to see if you may join.", "DCNotify.IncorrectVersion": "This lobby does not support your Among Us version.", "DCNotify.Inactivity": "The lobby closed due to inactivity.", "DCNotify.Auth": "You are not authenticated.\n\nYou may need to restart your game.", "DCNotify.DupeLogin": "An instance of your account is already present in this lobby.", "DCNotify.InvalidSettings": "Game settings have been detected to be invalid.\n\nEnter local play to reset them, then try again.", - "ModeDescribe.SoloKombat": "Current mode is [Solo PVP]\nNo role assignment. Everyone has HP and can use the kill button to cause damage to other players. The player with the highest number of kills wins at the end of the game.", + "ModeDescribe.SoloKombat": "Current Gamemode is [Solo PVP]\nNo role assignment. Everyone has HP and can use the Kill button to cause damage to other players. The player with the highest number of kills wins at the end of the game.", "RoleType.VanillaRoles": "★ Vanilla Roles", "RoleType.ImpKilling": "★ Impostor Killing Roles", "RoleType.ImpSupport": "★ Impostor Support Roles", @@ -3593,7 +3594,7 @@ "RoleType.Impostor": "★ Impostor Add-ons", "RoleType.Guesser": "★ Guesser Add-ons", "RoleType.Neut": "★ Neutral Add-ons", - "RoleType.Experimental": "★ Experimental Addons (NOTICE: Use with caution, as these require testing)", + "RoleType.Experimental": "★ Experimental Add-ons (NOTICE: Use with caution, as these require testing)", "SubType.Impostor": "★ Impostors", "SubType.Shapeshifter": "★ Shapeshifters", "SubType.SemiShapeshifter": "★ Semi-Shapeshifters", @@ -3694,15 +3695,15 @@ "ForceEndText": "Host has aborted the game", "NiceMiniDied": "Nice Mini was killed", "HaterMisFireKillTarget": "Hater kills target when misfiring", - "HaterChooseConverted": "Select add-ons that Hater can kill", - "HaterCanKillMadmate": "Can kill madmate", - "HaterCanKillCharmed": "Can kill charmed", - "HaterCanKillLovers": "Can kill lovers", - "HaterCanKillSidekick": "Can kill jackal team", - "HaterCanKillEgoist": "Can kill egoist", - "HaterCanKillInfected": "Can kill infected team", - "HaterCanKillContagious": "Can kill virus team", - "HaterCanKillAdmired": "Can kill admirer", + "HaterChooseConverted": "Select Add-ons that Hater can kill", + "HaterCanKillMadmate": "Can kill Madmate", + "HaterCanKillCharmed": "Can kill Charmed", + "HaterCanKillLovers": "Can kill Lovers", + "HaterCanKillSidekick": "Can kill Jackal team", + "HaterCanKillEgoist": "Can kill Egoist", + "HaterCanKillInfected": "Can kill Infected team", + "HaterCanKillContagious": "Can kill Virus team", + "HaterCanKillAdmired": "Can kill Admirer", "HorseMode": "Enable to become a horse", "LongMode": "Enable to have a long neck", "InfluencedChangeVote": "Oops! You are so influenced by others!\nYou can not contain your fear that you change voted {0}!", @@ -3710,11 +3711,11 @@ "FFA": "Free For All", "ModeFFA": "Gamemode: FFA", - "ModeDescribe.FFA": "In the FFA (Free For All) gamemode, everyone is a killer, and everyone can kill anyone. The last player alive wins!\n\nSome random events make this even more fun in the meantime!", - "KillerInfoLong": "In the FFA (Free For All) game mode, everyone is a killer, and everyone can kill anyone. The last player alive wins!\n\nSome random events make this even more fun in the meantime!", + "ModeDescribe.FFA": "In the FFA (Free For All) Gamemode, everyone is a killer, and everyone can kill anyone. The last player alive wins!\n\nSome random events make this even more fun in the meantime!", + "KillerInfoLong": "In the FFA (Free For All) Gamemode, everyone is a killer, and everyone can kill anyone. The last player alive wins!\n\nSome random events make this even more fun in the meantime!", "FFA_GameTime": "Maximum Game Length", "FFA_KCD": "Kill Cooldown", - "FFA_DisableVentingWhenTwoPlayersAlive": "Prevent venting when only 2 players are alive", + "FFA_DisableVentingWhenTwoPlayersAlive": "Prevent Venting when only 2 players are alive", "FFA_EnableRandomAbilities": "Enable Random Events", "FFA_ShieldDuration": "Shield Duration", "FFA_IncreasedSpeed": "Increased Speed", @@ -3725,15 +3726,15 @@ "FFA_EnableRandomTwists": "Enable Random Swaps from time to time", "FFA-Event-GetShield": "You have a temporary shield!", "FFA-Event-GetIncreasedSpeed": "You have a temporary speed boost!", - "FFA-Event-GetLowKCD": "You got a lower kill cooldown!", - "FFA-Event-GetHighKCD": "You got a higher kill cooldown", + "FFA-Event-GetLowKCD": "You got a lower Kill Cooldown!", + "FFA-Event-GetHighKCD": "You got a higher Kill Cooldown", "FFA-Event-GetLowVision": "You have lower vision temporarily", "FFA-Event-GetDecreasedSpeed": "You have decreased speed temporarily", - "FFA-Event-GetTP": "You got teleported to a random vent!", + "FFA-Event-GetTP": "You got teleported to a random Vent!", "FFA-Event-RandomTP": "Everyone was swapped with someone", - "FFA-NoVentingBecauseTwoPlayers": "There are only 2 players alive, stop hiding in vents!", - "FFA-NoVentingBecauseKCDIsUP": "Your kill cooldown is up, don't hide in vents!", - "FFA_DisableVentingWhenKCDIsUp": "Prevent players whose kill cooldown is up from venting", + "FFA-NoVentingBecauseTwoPlayers": "There are only 2 players alive, stop hiding in Vents!", + "FFA-NoVentingBecauseKCDIsUP": "Your kill Cooldown is up, don't hide in Vents!", + "FFA_DisableVentingWhenKCDIsUp": "Prevent players whose Kill Cooldown is up from Venting", "FFA_TargetIsShielded": "The player you tried to kill is shielded!", "FFA_ShieldIsOneTimeUse": "Shields break after 1 kill attempt", "FFA_ShieldBroken": "Someone tried to kill you, your shield is now broken!", @@ -3745,15 +3746,15 @@ "NumImpostorsHnS": "Num Impostors", "EveryOneKnowSolsticer": "Every One Know who is Solsticer", - "SolsticerKnowItsKiller": "Solsticer knows the role of whom used the kill button on it", + "SolsticerKnowItsKiller": "Solsticer knows the role of whom used the Kill button on it", "SolsticerSpeed": "Movement speed of Solsticer", "SolsticerRemainingTaskWarned": "Remaining tasks to be known", "SAddTasksPreDeadPlayer": "How many extra short tasks Solsticer gets when a player dies", "SolsticerMurdered": "{0} attempted to murder you!", "MurderSolsticer": "You stopped Solsticer this round!", - "SolsticerMurderMessage": "{0} used kill button on you last round! Its role is {1}!", + "SolsticerMurderMessage": "{0} used Kill button on you last round! Its role is {1}!", "SolsticerOnMeeting": "You witnessed too many deaths! Next round you will have {0} more short task!", - "SolsticerTitle": "Solsticer", + "SolsticerTitle": "SOLSTICER", "GuessSolsticer": "Sorry, but you can not guess Solsticer!", "ExpelSolsticer": "Sorry, but you can not expel Solsticer!", "SolsticerTasksReset": "Your tasks get reset!", @@ -3771,7 +3772,7 @@ "Quizmaster": "Quizmaster", "QuizmasterInfo": "Quiz people to kill them in meetings", - "QuizmasterInfoLong": "(Neutrals):\nAs the Quizmaster, you can mark a player using your kill button. In the next meeting, the marked player will have \"?!\" next to their name. The player will die if they answer the question wrong or doesn't answer. The player will live if the Quizmaster is killed/ejected in the same meeting.\nThe Quizmaster cannot mark multiple people in the same round", + "QuizmasterInfoLong": "(Neutrals):\nAs the Quizmaster, you can mark a player using your Kill button. In the next meeting, the marked player will have \"?!\" next to their name. The player will die if they answer the question wrong or doesn't answer. The player will live if the Quizmaster is killed/ejected in the same meeting.\nThe Quizmaster cannot mark multiple people in the same round", "QuizmasterKillButtonText": "Quiz", "QuizmasterChat.MarkedBy": "You've been marked by the Quizmaster\nTo survive you have to answer correct to this question:\n\n{QMQUESTION}", @@ -3785,7 +3786,7 @@ "QuizmasterChat.WrongPublic": "{QMTARGET} got the Quizmaster's question answer wrong and died!\nBeware of the Quizmaster!", "QuizmasterChat.Marked": "You've marked {QMTARGET}\nIf {QMTARGET} doesn't answer by the end of the meeting or answer wrong {QMTARGET} will die\n\nQuestion for {QMTARGET} => {QMQUESTION}", "QuizmasterChat.Title": "Quizmaster Information", - "QuizmasterChat.CantAnswer": "As the quizmaster, you can't answer questions", + "QuizmasterChat.CantAnswer": "As the Quizmaster, you can't answer questions", "QuizmasterChat.AnswerNotValid": "Your answer must be A, B, or C", "QuizmasterChat.SyntaxNotValid": "Usage:\n/answer [A/B/C]", @@ -3823,8 +3824,8 @@ "QuizmasterAnswers.Enhanced": "Enhanced", "QuizmasterAnswers.Edited": "Edited", - "QuizmasterQuestions.LastSabotage": "What was the sabotage was called last?", - "QuizmasterQuestions.FirstRoundSabotage": "What was the first sabotage called this round?", + "QuizmasterQuestions.LastSabotage": "What was the Sabotage was called last?", + "QuizmasterQuestions.FirstRoundSabotage": "What was the first Sabotage called this round?", "QuizmasterQuestions.LastEjectedPlayerColor": "What was the color of the player that was last ejected?", "QuizmasterQuestions.LastReportPlayerColor": "What was the color of the body that was last reported before this meeting?", "QuizmasterQuestions.LastButtonPressedPlayerColor": "Who called the last meeting before this meeting?", @@ -3834,7 +3835,7 @@ "QuizmasterQuestions.FactionOfRole": "What's the faction of {QMRole}?", "QuizmasterQuestions.FactionRemovedName": "What faction used to be in the game but was removed in an update later?", "QuizmasterQuestions.HowManyDiedFirstRound": "How many people died round one?", - "QuizmasterQuestions.ButtonPressedBefore": "How many people pressed the emergency button before this meeting?", + "QuizmasterQuestions.ButtonPressedBefore": "How many people pressed the Emergency button before this meeting?", "QuizmasterQuestions.WhatDoesEOgMeansInName": "What did the E in TOHE originally stand for?", "QuizmasterQuestions.PlrDieReason": "What was {PLR}'s cause of death?", "QuizmasterQuestions.PlrDieMethod": "How did {PLR} die?", @@ -3878,7 +3879,7 @@ "ShockerAbilityCooldown": "Ability Cooldown", "ShockerAbilityDuration": "Ability Duration", "ShockerAbilityPerRound": "Abilities Per Round", - "ShockerShockInVents": "Shock people in vents", + "ShockerShockInVents": "Shock people in Vents", "ShockerAbilityResetAfterMeeting": "Reset marked rooms after meeting", "ShockerOutsideRadius": "Radius Of Outside Tasks (not in a room)", "ShockerCanShockHimself": "Can Shock Himself", @@ -3894,13 +3895,13 @@ "PreventSeeRolesBeforeSkillUsedUp": "Prevent seeing others roles before skill used up", - "ChiefOfPoliceSkillCooldown": "Cooldown for recruiting sheriffs", + "ChiefOfPoliceSkillCooldown": "Cooldown for recruiting Sheriffs", "PolicCanImpostorAndNeutarl": "Can recruit Impostor or Neutral", - "SheriffSuccessfullyRecruited": "You recruited a sheriff.", - "BeSheriffByPolice": "You've been recruited by the police chief! Serve the crew!", + "SheriffSuccessfullyRecruited": "You recruited a Sheriff.", + "BeSheriffByPolice": "You've been recruited by the Police Chief! Serve the Crewmates!", "PoliceFailedRecruit": "Failed to recruit target.", "ChiefOfPoliceKillButtonText": "Recruitment", - "PolicPreventRecruitNonKiller": "Prevent recruit players without kill button", - "PolicSuidiceWhenTargetNotKiller": "Suicides when recruit a non killer or non crewmate", - "PolicPassConverted": "Can pass Converted Addon to Sheriff" + "PolicPreventRecruitNonKiller": "Prevent recruit players without Kill button", + "PolicSuidiceWhenTargetNotKiller": "Suicides when recruit a non-Killer or non-Crewmate", + "PolicPassConverted": "Can pass Converted Add-on to Sheriff" } From 939a889ff597ee67d2e13bba4fd39fd27f3fbd72 Mon Sep 17 00:00:00 2001 From: frisk Date: Mon, 6 Jan 2025 08:26:26 -0500 Subject: [PATCH 05/11] randomizer --- .editorconfig | 164 +- .github/workflows/clearlogs.yml | 31 + .gitignore | 1 - GameModes/FFAManager.cs | 2 +- GlobalUsings.cs | 3 +- Modules/AntiBlackout.cs | 34 +- Modules/BanManager.cs | 14 +- Modules/ChatManager.cs | 17 +- Modules/Cloud.cs | 1 + Modules/CustomRolesHelper.cs | 208 +- Modules/CustomRpcSender.cs | 2 +- Modules/CustomSounds.cs | 1 + Modules/CustomWinnerHolder.cs | 10 +- Modules/Debugger.cs | 10 + Modules/DelayNetworkedData.cs | 5 +- Modules/DevManager.cs | 1 + Modules/DisableDevice.cs | 28 +- Modules/DoorsReset.cs | 2 +- Modules/EAC.cs | 37 +- Modules/ErrorText.cs | 4 +- Modules/ExtendedPlayerControl.cs | 160 +- Modules/GameState.cs | 170 +- Modules/GuessManager.cs | 25 +- Modules/HazelExtensions.cs | 2 +- Modules/LateTask.cs | 5 +- Modules/LocateArrow.cs | 2 +- Modules/MeetingTimeManager.cs | 2 +- Modules/ModUpdater.cs | 116 +- Modules/NameColorManager.cs | 186 +- Modules/NameNotifyManager.cs | 6 +- Modules/OptionBackup/OptionBackupData.cs | 4 +- Modules/OptionHolder.cs | 33 +- Modules/OptionItem/BooleanOptionItem.cs | 4 +- Modules/OptionItem/FloatOptionItem.cs | 4 +- Modules/OptionItem/IntegerOptionItem.cs | 2 +- Modules/OptionItem/OptionItem.cs | 9 +- Modules/OptionItem/PresetOptionItem.cs | 5 +- Modules/OptionItem/StringOptionItem.cs | 11 +- Modules/OptionItem/TextOptionItem.cs | 4 +- Modules/OptionSaver.cs | 3 - Modules/OptionShower.cs | 2 +- Modules/OutfitManager.cs | 6 +- Modules/RPC.cs | 200 +- Modules/RehostManager.cs | 4 +- Modules/SpamManager.cs | 2 +- Modules/TemplateManager.cs | 7 +- Modules/Translator.cs | 8 +- Modules/Utils.cs | 278 +- Modules/VersionChecker.cs | 2 +- Modules/Zoom.cs | 2 +- Modules/dbConnect.cs | 193 +- Patches/AnnouncementPatch.cs | 88 +- Patches/AprilFoolsModePatch.cs | 14 +- Patches/ChatBubblePatch.cs | 34 +- Patches/ChatCommandPatch.cs | 168 +- Patches/ChatControlPatch.cs | 5 +- Patches/CheckGameEndPatch.cs | 141 +- Patches/ClientOptionsPatch.cs | 32 +- Patches/ControlPatch.cs | 22 +- Patches/CredentialsPatch.cs | 6 +- Patches/DeconSystemPatch.cs | 2 +- Patches/DisconnectPenaltyPatch.cs | 3 +- Patches/DleksPatch.cs | 5 +- Patches/EndGameManagerPatch.cs | 4 +- Patches/ExilePatch.cs | 22 +- Patches/GameOptionsMenuPatch.cs | 47 +- Patches/GameSettingMenuPatch.cs | 26 +- Patches/GameStartManagerPatch.cs | 4 +- Patches/HauntMenuMinigamePatch.cs | 23 +- Patches/HideNSeek/PlayerControlPatchHnS.cs | 2 +- Patches/HudPatch.cs | 8 +- Patches/InnerNetClientPatch.cs | 7 +- Patches/IntroPatch.cs | 413 +- Patches/MainMenuManagerPatch.cs | 132 +- Patches/MapPickerMenuPatch.cs | 4 +- Patches/MeetingHudPatch.cs | 64 +- Patches/OneWayShadowsPatch.cs | 2 +- Patches/OutroPatch.cs | 56 +- Patches/PhantomRolePatch.cs | 4 +- Patches/PlayerControlPatch.cs | 140 +- Patches/PlayerJoinAndLeftPatch.cs | 37 +- Patches/RandomSpawnPatch.cs | 133 +- Patches/SabotageSystemPatch.cs | 380 +- Patches/ShipStatusPatch.cs | 11 +- Patches/TaskAssignPatch.cs | 223 +- Patches/VentSystemPatch.cs | 16 +- Patches/onGameStartedPatch.cs | 22 +- README.md | 4 - Resources/Announcements/modNews-de_DE.json | 171 +- Resources/Announcements/modNews-en_US.json | 141 - Resources/Announcements/modNews-es_419.json | 163 +- Resources/Announcements/modNews-es_ES.json | 233 +- Resources/Announcements/modNews-fil_PH.json | 141 - Resources/Announcements/modNews-fr_FR.json | 233 +- Resources/Announcements/modNews-it_IT.json | 151 +- Resources/Announcements/modNews-ja_JP.json | 223 +- Resources/Announcements/modNews-ko_KR.json | 141 - Resources/Announcements/modNews-nl_NL.json | 141 - Resources/Announcements/modNews-pt_BR.json | 233 +- Resources/Announcements/modNews-pt_PT.json | 141 - Resources/Announcements/modNews-ru_RU.json | 147 +- Resources/Announcements/modNews-zh_CN.json | 151 +- Resources/Announcements/modNews-zh_TW.json | 161 +- Resources/Lang/de_DE.json | 393 +- Resources/Lang/en_US.json | 7585 +++++++++--------- Resources/Lang/es_419.json | 206 +- Resources/Lang/es_ES.json | 159 +- Resources/Lang/fil_PH.json | 139 +- Resources/Lang/fr_FR.json | 161 +- Resources/Lang/it_IT.json | 253 +- Resources/Lang/ja_JP.json | 177 +- Resources/Lang/ko_KR.json | 139 +- Resources/Lang/nl_NL.json | 151 +- Resources/Lang/pt_BR.json | 171 +- Resources/Lang/pt_PT.json | 139 +- Resources/Lang/ru_RU.json | 159 +- Resources/Lang/zh_CN.json | 156 +- Resources/Lang/zh_TW.json | 179 +- Resources/roleColor.json | 502 +- Roles/(Ghosts)/Crewmate/Ghastly.cs | 51 +- Roles/(Ghosts)/Crewmate/GuardianAngelTOHE.cs | 7 +- Roles/(Ghosts)/Crewmate/Hawk.cs | 5 +- Roles/(Ghosts)/Crewmate/Warden.cs | 7 +- Roles/(Ghosts)/Impostor/Bloodmoon.cs | 5 +- Roles/(Ghosts)/Impostor/Minion.cs | 15 +- Roles/(Ghosts)/Impostor/Possessor.cs | 11 +- Roles/AddOns/Common/Antidote.cs | 2 - Roles/AddOns/Common/Autopsy.cs | 3 +- Roles/AddOns/Common/Avanger.cs | 3 +- Roles/AddOns/Common/Aware.cs | 7 +- Roles/AddOns/Common/Bait.cs | 7 +- Roles/AddOns/Common/Beartrap.cs | 1 - Roles/AddOns/Common/Bewilder.cs | 11 +- Roles/AddOns/Common/Burst.cs | 3 +- Roles/AddOns/Common/Cyber.cs | 3 +- Roles/AddOns/Common/Diseased.cs | 7 +- Roles/AddOns/Common/DoubleShot.cs | 3 +- Roles/AddOns/Common/Eavesdropper.cs | 3 +- Roles/AddOns/Common/Egoist.cs | 3 +- Roles/AddOns/Common/Evader.cs | 1 - Roles/AddOns/Common/Flash.cs | 3 +- Roles/AddOns/Common/Fool.cs | 1 - Roles/AddOns/Common/Fragile.cs | 1 - Roles/AddOns/Common/FragileSoul.cs | 1 + Roles/AddOns/Common/Glow.cs | 16 +- Roles/AddOns/Common/Gravestone.cs | 1 - Roles/AddOns/Common/Guesser.cs | 7 +- Roles/AddOns/Common/Influenced.cs | 15 +- Roles/AddOns/Common/Loyal.cs | 3 +- Roles/AddOns/Common/Lucky.cs | 5 +- Roles/AddOns/Common/Mundane.cs | 3 +- Roles/AddOns/Common/Necroview.cs | 1 - Roles/AddOns/Common/Oblivious.cs | 3 +- Roles/AddOns/Common/Oiiai.cs | 19 +- Roles/AddOns/Common/Onbound.cs | 1 - Roles/AddOns/Common/Overlocked.cs | 1 - Roles/AddOns/Common/Paranoia.cs | 1 - Roles/AddOns/Common/Prohibited.cs | 1 - Roles/AddOns/Common/Radar.cs | 3 +- Roles/AddOns/Common/Rainbow.cs | 1 - Roles/AddOns/Common/Reach.cs | 5 +- Roles/AddOns/Common/Rebirth.cs | 17 +- Roles/AddOns/Common/Rebound.cs | 3 +- Roles/AddOns/Common/Seer.cs | 1 - Roles/AddOns/Common/Silent.cs | 1 - Roles/AddOns/Common/Sleuth.cs | 7 +- Roles/AddOns/Common/Sloth.cs | 5 +- Roles/AddOns/Common/Spurt.cs | 10 +- Roles/AddOns/Common/Statue.cs | 9 +- Roles/AddOns/Common/Stubborn.cs | 1 - Roles/AddOns/Common/Susceptible.cs | 1 - Roles/AddOns/Common/Tiebreaker.cs | 3 +- Roles/AddOns/Common/Tired.cs | 7 +- Roles/AddOns/Common/Unlucky.cs | 2 - Roles/AddOns/Common/Unreportable.cs | 3 +- Roles/AddOns/Common/Voidballot.cs | 3 +- Roles/AddOns/Common/Watcher.cs | 1 - Roles/AddOns/Common/Youtuber.cs | 1 - Roles/AddOns/Common/allergic.cs | 143 + Roles/AddOns/Crewmate/Bloodthirst.cs | 1 - Roles/AddOns/Crewmate/Ghoul.cs | 3 +- Roles/AddOns/Crewmate/Hurried.cs | 1 - Roles/AddOns/Crewmate/Lazy.cs | 9 +- Roles/AddOns/Crewmate/Nimble.cs | 3 +- Roles/AddOns/Crewmate/Rascal.cs | 3 +- Roles/AddOns/Crewmate/Torch.cs | 9 +- Roles/AddOns/Crewmate/Workhorse.cs | 6 +- Roles/AddOns/IAddon.cs | 2 - Roles/AddOns/Impostor/Circumvent.cs | 3 +- Roles/AddOns/Impostor/Clumsy.cs | 3 +- Roles/AddOns/Impostor/LastImpostor.cs | 7 +- Roles/AddOns/Impostor/Madmate.cs | 3 +- Roles/AddOns/Impostor/Mare.cs | 8 +- Roles/AddOns/Impostor/Mimic.cs | 3 +- Roles/AddOns/Impostor/Stealer.cs | 5 +- Roles/AddOns/Impostor/Swift.cs | 5 +- Roles/AddOns/Impostor/Tricky.cs | 5 +- Roles/Core/AssignManager/GhostRoleAssign.cs | 31 +- Roles/Core/AssignManager/RoleAssign.cs | 1 - Roles/Core/CustomRoleManager.cs | 58 +- Roles/Core/RoleBase.cs | 37 +- Roles/Crewmate/Addict.cs | 10 +- Roles/Crewmate/Admirer.cs | 17 +- Roles/Crewmate/Alchemist.cs | 19 +- Roles/Crewmate/Altruist.cs | 6 +- Roles/Crewmate/Bastion.cs | 13 +- Roles/Crewmate/Benefactor.cs | 19 +- Roles/Crewmate/Bodyguard.cs | 1 - Roles/Crewmate/Captain.cs | 16 +- Roles/Crewmate/Celebrity.cs | 15 +- Roles/Crewmate/Chameleon.cs | 17 +- Roles/Crewmate/ChiefOfPolice.cs | 212 +- Roles/Crewmate/Cleanser.cs | 5 +- Roles/Crewmate/CopyCat.cs | 28 +- Roles/Crewmate/Coroner.cs | 5 +- Roles/Crewmate/Crusader.cs | 11 +- Roles/Crewmate/Deceiver.cs | 3 +- Roles/Crewmate/Deputy.cs | 3 +- Roles/Crewmate/Detective.cs | 9 +- Roles/Crewmate/Dictator.cs | 197 +- Roles/Crewmate/Doctor.cs | 15 +- Roles/Crewmate/Enigma.cs | 23 +- Roles/Crewmate/FortuneTeller.cs | 1 - Roles/Crewmate/Grenadier.cs | 12 +- Roles/Crewmate/Guardian.cs | 21 +- Roles/Crewmate/GuessMaster.cs | 8 +- Roles/Crewmate/Inspector.cs | 9 +- Roles/Crewmate/Investigator.cs | 8 +- Roles/Crewmate/Jailer.cs | 8 +- Roles/Crewmate/Judge.cs | 15 +- Roles/Crewmate/Keeper.cs | 18 +- Roles/Crewmate/Knight.cs | 5 +- Roles/Crewmate/LazyGuy.cs | 12 +- Roles/Crewmate/Lighter.cs | 48 +- Roles/Crewmate/Lookout.cs | 13 +- Roles/Crewmate/Marshall.cs | 17 +- Roles/Crewmate/Mayor.cs | 11 +- Roles/Crewmate/Mechanic.cs | 9 +- Roles/Crewmate/Medic.cs | 8 +- Roles/Crewmate/Medium.cs | 9 +- Roles/Crewmate/Merchant.cs | 19 +- Roles/Crewmate/Mole.cs | 13 +- Roles/Crewmate/Monarch.cs | 3 +- Roles/Crewmate/Mortician.cs | 31 +- Roles/Crewmate/NiceGuesser.cs | 16 +- Roles/Crewmate/Observer.cs | 10 +- Roles/Crewmate/Oracle.cs | 13 +- Roles/Crewmate/Overseer.cs | 10 +- Roles/Crewmate/Pacifist.cs | 22 +- Roles/Crewmate/President.cs | 13 +- Roles/Crewmate/Psychic.cs | 3 +- Roles/Crewmate/Randomizer.cs | 940 ++- Roles/Crewmate/Retributionist.cs | 26 +- Roles/Crewmate/Reverie.cs | 17 +- Roles/Crewmate/Sheriff.cs | 9 +- Roles/Crewmate/Snitch.cs | 17 +- Roles/Crewmate/Spiritualist.cs | 72 +- Roles/Crewmate/Spy.cs | 53 +- Roles/Crewmate/SuperStar.cs | 14 +- Roles/Crewmate/Swapper.cs | 16 +- Roles/Crewmate/TaskManager.cs | 14 +- Roles/Crewmate/Telecommunication.cs | 23 +- Roles/Crewmate/TimeManager.cs | 8 +- Roles/Crewmate/TimeMaster.cs | 8 +- Roles/Crewmate/Tracefinder.cs | 34 +- Roles/Crewmate/Transporter.cs | 12 +- Roles/Crewmate/Ventguard.cs | 18 +- Roles/Crewmate/Veteran.cs | 10 +- Roles/Crewmate/Vigilante.cs | 15 +- Roles/Crewmate/Witness.cs | 9 +- Roles/Double/Mini.cs | 10 +- Roles/Impostor/Anonymous.cs | 14 +- Roles/Impostor/AntiAdminer.cs | 25 +- Roles/Impostor/Arrogance.cs | 15 +- Roles/Impostor/Bard.cs | 14 +- Roles/Impostor/Blackmailer.cs | 49 +- Roles/Impostor/Bomber.cs | 17 +- Roles/Impostor/BountyHunter.cs | 59 +- Roles/Impostor/Butcher.cs | 25 +- Roles/Impostor/Camouflager.cs | 6 +- Roles/Impostor/Chronomancer.cs | 35 +- Roles/Impostor/Cleaner.cs | 12 +- Roles/Impostor/Consigliere.cs | 27 +- Roles/Impostor/Councillor.cs | 46 +- Roles/Impostor/Crewpostor.cs | 22 +- Roles/Impostor/CursedWolf.cs | 2 +- Roles/Impostor/Dazzler.cs | 9 +- Roles/Impostor/Deathpact.cs | 14 +- Roles/Impostor/Devourer.cs | 9 +- Roles/Impostor/Disperser.cs | 16 +- Roles/Impostor/DollMaster.cs | 9 +- Roles/Impostor/DoubleAgent.cs | 20 +- Roles/Impostor/Eraser.cs | 4 - Roles/Impostor/Escapist.cs | 10 +- Roles/Impostor/EvilGuesser.cs | 13 +- Roles/Impostor/EvilHacker.cs | 6 +- Roles/Impostor/EvilTracker.cs | 15 +- Roles/Impostor/Fireworker.cs | 26 +- Roles/Impostor/Gangster.cs | 9 +- Roles/Impostor/Godfather.cs | 35 +- Roles/Impostor/Greedy.cs | 10 +- Roles/Impostor/Hangman.cs | 5 +- Roles/Impostor/Inhibitor.cs | 14 +- Roles/Impostor/Instigator.cs | 11 +- Roles/Impostor/Kamikaze.cs | 48 +- Roles/Impostor/KillingMachine.cs | 14 +- Roles/Impostor/Lightning.cs | 16 +- Roles/Impostor/Ludopath.cs | 14 +- Roles/Impostor/Lurker.cs | 16 +- Roles/Impostor/Mastermind.cs | 16 +- Roles/Impostor/Mercenary.cs | 14 +- Roles/Impostor/Miner.cs | 13 +- Roles/Impostor/Morphling.cs | 14 +- Roles/Impostor/Nemesis.cs | 28 +- Roles/Impostor/Ninja.cs | 17 +- Roles/Impostor/Parasite.cs | 36 +- Roles/Impostor/Penguin.cs | 13 +- Roles/Impostor/Pitfall.cs | 9 +- Roles/Impostor/Puppeteer.cs | 30 +- Roles/Impostor/QuickShooter.cs | 47 +- Roles/Impostor/Refugee.cs | 12 +- Roles/Impostor/RiftMaker.cs | 117 +- Roles/Impostor/Saboteur.cs | 14 +- Roles/Impostor/Scavenger.cs | 19 +- Roles/Impostor/ShapeMaster.cs | 12 +- Roles/Impostor/Sniper.cs | 8 +- Roles/Impostor/SoulCatcher.cs | 13 +- Roles/Impostor/Stealth.cs | 3 +- Roles/Impostor/Swooper.cs | 9 +- Roles/Impostor/TimeThief.cs | 14 +- Roles/Impostor/Trapster.cs | 14 +- Roles/Impostor/Trickster.cs | 12 +- Roles/Impostor/Twister.cs | 3 +- Roles/Impostor/Underdog.cs | 12 +- Roles/Impostor/Undertaker.cs | 16 +- Roles/Impostor/Vampire.cs | 14 +- Roles/Impostor/Vindicator.cs | 13 +- Roles/Impostor/Visionary.cs | 17 +- Roles/Impostor/Warlock.cs | 18 +- Roles/Impostor/Wildling.cs | 3 +- Roles/Impostor/Witch.cs | 20 +- Roles/Impostor/YinYanger.cs | 5 +- Roles/Impostor/Zombie.cs | 14 +- Roles/Neutral/Agitater.cs | 14 +- Roles/Neutral/Amnesiac.cs | 181 +- Roles/Neutral/Arsonist.cs | 40 +- Roles/Neutral/Baker.cs | 68 +- Roles/Neutral/Bandit.cs | 14 +- Roles/Neutral/Berserker.cs | 84 +- Roles/Neutral/BloodKnight.cs | 5 +- Roles/Neutral/Collector.cs | 1 - Roles/Neutral/Cultist.cs | 14 +- Roles/Neutral/CursedSoul.cs | 19 +- Roles/Neutral/Demon.cs | 5 +- Roles/Neutral/Doomsayer.cs | 22 +- Roles/Neutral/Doppelganger.cs | 3 +- Roles/Neutral/Executioner.cs | 15 +- Roles/Neutral/Follower.cs | 9 +- Roles/Neutral/Glitch.cs | 11 +- Roles/Neutral/God.cs | 12 +- Roles/Neutral/Hater.cs | 10 +- Roles/Neutral/HexMaster.cs | 27 +- Roles/Neutral/Huntsman.cs | 1 - Roles/Neutral/Imitator.cs | 4 +- Roles/Neutral/Infectious.cs | 25 +- Roles/Neutral/Innocent.cs | 7 +- Roles/Neutral/Jackal.cs | 298 +- Roles/Neutral/Jester.cs | 43 +- Roles/Neutral/Jinx.cs | 11 +- Roles/Neutral/Juggernaut.cs | 7 +- Roles/Neutral/Lawyer.cs | 7 +- Roles/Neutral/LingeringPresence.cs | 718 ++ Roles/Neutral/Maverick.cs | 1 - Roles/Neutral/Medusa.cs | 13 +- Roles/Neutral/Necromancer.cs | 19 +- Roles/Neutral/Opportunist.cs | 36 +- Roles/Neutral/Pelican.cs | 9 +- Roles/Neutral/Pickpocket.cs | 3 +- Roles/Neutral/Pirate.cs | 5 +- Roles/Neutral/Pixie.cs | 3 +- Roles/Neutral/PlagueBearer.cs | 36 +- Roles/Neutral/PlagueDoctor.cs | 3 +- Roles/Neutral/Poisoner.cs | 12 +- Roles/Neutral/PotionMaster.cs | 7 +- Roles/Neutral/Provocateur.cs | 9 +- Roles/Neutral/PunchingBag.cs | 16 +- Roles/Neutral/Pursuer.cs | 19 +- Roles/Neutral/Pyromaniac.cs | 10 +- Roles/Neutral/Quizmaster.cs | 46 +- Roles/Neutral/Revolutionist.cs | 23 +- Roles/Neutral/Romantic.cs | 17 +- Roles/Neutral/SchrodingersCat.cs | 1 - Roles/Neutral/Seeker.cs | 7 +- Roles/Neutral/SerialKiller.cs | 12 +- Roles/Neutral/Shaman.cs | 7 +- Roles/Neutral/Shroud.cs | 1 - Roles/Neutral/Sidekick.cs | 41 + Roles/Neutral/Solsticer.cs | 13 +- Roles/Neutral/SoulCollector.cs | 29 +- Roles/Neutral/Specter.cs | 12 +- Roles/Neutral/Spiritcaller.cs | 3 +- Roles/Neutral/Stalker.cs | 5 +- Roles/Neutral/Sunnyboy.cs | 6 +- Roles/Neutral/Taskinator.cs | 19 +- Roles/Neutral/Terrorist.cs | 13 +- Roles/Neutral/Traitor.cs | 35 +- Roles/Neutral/Troller.cs | 4 +- Roles/Neutral/Vector.cs | 37 +- Roles/Neutral/Virus.cs | 20 +- Roles/Neutral/Vulture.cs | 17 +- Roles/Neutral/Werewolf.cs | 14 +- Roles/Neutral/Workaholic.cs | 15 +- Roles/Neutral/Wraith.cs | 5 +- Roles/Neutral/evolver.cs | 721 ++ Roles/Vanilla/CrewmateTOHE.cs | 14 +- Roles/Vanilla/DefaultSetup.cs | 11 +- Roles/Vanilla/EngineerTOHE.cs | 13 +- Roles/Vanilla/ImpostorTOHE.cs | 13 +- Roles/Vanilla/NoisemakerTOHE.cs | 1 - Roles/Vanilla/PhantomTOHE.cs | 13 +- Roles/Vanilla/ScientistTOHE.cs | 13 +- Roles/Vanilla/ShapeshifterTOHE.cs | 13 +- Roles/Vanilla/TrackerTOHE.cs | 13 +- Summoned.cs | 1 + TOHE - Backup.csproj | 50 + TOHE.csproj | 8 +- main.cs | 133 +- summoner.cs | 465 ++ 428 files changed, 12546 insertions(+), 13148 deletions(-) create mode 100644 .github/workflows/clearlogs.yml create mode 100644 Roles/AddOns/Common/FragileSoul.cs create mode 100644 Roles/AddOns/Common/allergic.cs create mode 100644 Roles/Neutral/LingeringPresence.cs create mode 100644 Roles/Neutral/Sidekick.cs create mode 100644 Roles/Neutral/evolver.cs create mode 100644 Summoned.cs create mode 100644 TOHE - Backup.csproj create mode 100644 summoner.cs diff --git a/.editorconfig b/.editorconfig index e885361a0..08a0260a4 100644 --- a/.editorconfig +++ b/.editorconfig @@ -2,11 +2,29 @@ # CA2211: Non-constant fields should not be visible dotnet_diagnostic.CA2211.severity = none +csharp_using_directive_placement = outside_namespace:silent +csharp_prefer_simple_using_statement = true:suggestion +csharp_prefer_braces = true:silent +csharp_style_namespace_declarations = block_scoped:silent +csharp_style_prefer_method_group_conversion = true:silent +csharp_style_prefer_top_level_statements = true:silent +csharp_style_prefer_primary_constructors = true:suggestion +csharp_prefer_system_threading_lock = true:suggestion +csharp_style_expression_bodied_methods = false:silent +csharp_style_expression_bodied_constructors = false:silent +csharp_style_expression_bodied_operators = false:silent +csharp_style_expression_bodied_properties = true:silent +csharp_style_expression_bodied_indexers = true:silent +csharp_style_expression_bodied_accessors = true:silent +csharp_style_expression_bodied_lambdas = true:silent +csharp_style_expression_bodied_local_functions = false:silent +csharp_indent_labels = one_less_than_current +csharp_space_around_binary_operators = before_and_after -[*.cs] -#### 命名样式 #### +[*.{cs,vb}] +#### Naming styles #### -# 命名规则 +# Naming rules dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface @@ -20,7 +38,7 @@ dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case -# 符号规范 +# Symbol specifications dotnet_naming_symbols.interface.applicable_kinds = interface dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected @@ -34,7 +52,7 @@ dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, meth dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected dotnet_naming_symbols.non_field_members.required_modifiers = -# 命名样式 +# Naming styles dotnet_naming_style.begins_with_i.required_prefix = I dotnet_naming_style.begins_with_i.required_suffix = @@ -50,139 +68,11 @@ dotnet_naming_style.pascal_case.required_prefix = dotnet_naming_style.pascal_case.required_suffix = dotnet_naming_style.pascal_case.word_separator = dotnet_naming_style.pascal_case.capitalization = pascal_case -csharp_space_around_binary_operators = before_and_after -csharp_using_directive_placement = outside_namespace:silent -csharp_style_expression_bodied_methods = false:silent -csharp_style_expression_bodied_constructors = false:silent -csharp_style_expression_bodied_operators = false:silent -csharp_style_expression_bodied_properties = true:silent -csharp_style_expression_bodied_indexers = true:silent -csharp_style_expression_bodied_accessors = true:silent -csharp_style_expression_bodied_lambdas = true:silent -csharp_style_expression_bodied_local_functions = false:silent -csharp_style_conditional_delegate_call = true:suggestion -csharp_style_var_for_built_in_types = false:silent -csharp_style_var_when_type_is_apparent = false:silent -csharp_style_var_elsewhere = false:silent -csharp_prefer_simple_using_statement = true:suggestion -csharp_prefer_braces = true:silent -csharp_style_namespace_declarations = block_scoped:silent -csharp_style_prefer_method_group_conversion = true:silent -csharp_style_prefer_top_level_statements = true:silent -csharp_style_prefer_primary_constructors = true:suggestion -csharp_prefer_static_local_function = true:suggestion -csharp_prefer_static_anonymous_function = true:suggestion -csharp_style_prefer_readonly_struct = true:suggestion -csharp_style_prefer_readonly_struct_member = true:suggestion -csharp_indent_labels = one_less_than_current -csharp_style_allow_blank_lines_between_consecutive_braces_experimental = false:silent -csharp_style_allow_embedded_statements_on_same_line_experimental = true:silent -csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = true:silent -csharp_style_allow_blank_line_after_token_in_conditional_expression_experimental = true:silent -csharp_style_allow_blank_line_after_token_in_arrow_expression_clause_experimental = true:silent -csharp_style_prefer_switch_expression = true:suggestion -csharp_style_prefer_pattern_matching = true:silent -csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion -csharp_style_pattern_matching_over_as_with_null_check = true:suggestion -csharp_style_prefer_not_pattern = true:suggestion -csharp_style_prefer_extended_property_pattern = true:suggestion -csharp_style_prefer_utf8_string_literals = true:silent -csharp_style_throw_expression = true:suggestion -csharp_style_prefer_null_check_over_type_check = true:suggestion -csharp_prefer_simple_default_expression = true:suggestion -csharp_style_prefer_local_over_anonymous_function = true:suggestion -csharp_style_prefer_index_operator = true:suggestion -csharp_style_prefer_range_operator = true:suggestion -csharp_style_implicit_object_creation_when_type_is_apparent = true:suggestion -csharp_style_prefer_tuple_swap = true:suggestion -csharp_style_inlined_variable_declaration = true:suggestion -csharp_style_deconstructed_variable_declaration = true:suggestion -csharp_style_unused_value_assignment_preference = discard_variable:suggestion -csharp_style_unused_value_expression_statement_preference = discard_variable:silent - -[*.vb] -#### 命名样式 #### - -# 命名规则 - -dotnet_naming_rule.interface_should_be_以_i_开始.severity = suggestion -dotnet_naming_rule.interface_should_be_以_i_开始.symbols = interface -dotnet_naming_rule.interface_should_be_以_i_开始.style = 以_i_开始 - -dotnet_naming_rule.类型_should_be_帕斯卡拼写法.severity = suggestion -dotnet_naming_rule.类型_should_be_帕斯卡拼写法.symbols = 类型 -dotnet_naming_rule.类型_should_be_帕斯卡拼写法.style = 帕斯卡拼写法 - -dotnet_naming_rule.非字段成员_should_be_帕斯卡拼写法.severity = suggestion -dotnet_naming_rule.非字段成员_should_be_帕斯卡拼写法.symbols = 非字段成员 -dotnet_naming_rule.非字段成员_should_be_帕斯卡拼写法.style = 帕斯卡拼写法 - -# 符号规范 - -dotnet_naming_symbols.interface.applicable_kinds = interface -dotnet_naming_symbols.interface.applicable_accessibilities = public, friend, private, protected, protected_friend, private_protected -dotnet_naming_symbols.interface.required_modifiers = - -dotnet_naming_symbols.类型.applicable_kinds = class, struct, interface, enum -dotnet_naming_symbols.类型.applicable_accessibilities = public, friend, private, protected, protected_friend, private_protected -dotnet_naming_symbols.类型.required_modifiers = - -dotnet_naming_symbols.非字段成员.applicable_kinds = property, event, method -dotnet_naming_symbols.非字段成员.applicable_accessibilities = public, friend, private, protected, protected_friend, private_protected -dotnet_naming_symbols.非字段成员.required_modifiers = - -# 命名样式 - -dotnet_naming_style.以_i_开始.required_prefix = I -dotnet_naming_style.以_i_开始.required_suffix = -dotnet_naming_style.以_i_开始.word_separator = -dotnet_naming_style.以_i_开始.capitalization = pascal_case - -dotnet_naming_style.帕斯卡拼写法.required_prefix = -dotnet_naming_style.帕斯卡拼写法.required_suffix = -dotnet_naming_style.帕斯卡拼写法.word_separator = -dotnet_naming_style.帕斯卡拼写法.capitalization = pascal_case - -dotnet_naming_style.帕斯卡拼写法.required_prefix = -dotnet_naming_style.帕斯卡拼写法.required_suffix = -dotnet_naming_style.帕斯卡拼写法.word_separator = -dotnet_naming_style.帕斯卡拼写法.capitalization = pascal_case - -[*.{cs,vb}] -end_of_line = crlf -tab_width = 4 -indent_size = 4 -dotnet_style_qualification_for_field = false:silent -dotnet_style_qualification_for_property = false:silent -dotnet_style_qualification_for_method = false:silent -dotnet_style_qualification_for_event = false:silent -dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent -dotnet_code_quality_unused_parameters = all:suggestion -dotnet_style_readonly_field = true:suggestion -dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent -dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent -dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent -dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent -insert_final_newline = true -dotnet_style_operator_placement_when_wrapping = beginning_of_line -indent_style = space -dotnet_style_allow_multiple_blank_lines_experimental = true:silent -dotnet_style_allow_statement_immediately_after_block_experimental = true:silent dotnet_style_coalesce_expression = true:suggestion -dotnet_style_prefer_conditional_expression_over_assignment = true:silent -dotnet_style_prefer_conditional_expression_over_return = true:silent dotnet_style_null_propagation = true:suggestion dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion dotnet_style_prefer_auto_properties = true:silent -dotnet_style_object_initializer = true:suggestion -dotnet_style_collection_initializer = true:suggestion -dotnet_style_prefer_simplified_boolean_expressions = true:suggestion -dotnet_style_explicit_tuple_names = true:suggestion -dotnet_style_prefer_inferred_tuple_names = true:suggestion -dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion -dotnet_style_prefer_compound_assignment = true:suggestion -dotnet_style_prefer_simplified_interpolation = true:suggestion -dotnet_style_prefer_collection_expression = when_types_loosely_match:suggestion -dotnet_style_namespace_match_folder = true:suggestion -dotnet_style_predefined_type_for_locals_parameters_members = true:silent -dotnet_style_predefined_type_for_member_access = true:silent \ No newline at end of file +dotnet_style_operator_placement_when_wrapping = beginning_of_line +tab_width = 4 +indent_size = 4 +end_of_line = crlf diff --git a/.github/workflows/clearlogs.yml b/.github/workflows/clearlogs.yml new file mode 100644 index 000000000..2bcfeb5f2 --- /dev/null +++ b/.github/workflows/clearlogs.yml @@ -0,0 +1,31 @@ +name: Delete old workflow runs + +on: + schedule: + - cron: '0 0 */14 * *' # Run every 14 days at 00:00 + workflow_dispatch: # Allow manual execution + +jobs: + del_succeed_runs: + runs-on: ubuntu-latest + permissions: + actions: write + contents: read + steps: + - name: Delete Succeeded workflow runs + uses: Mattraks/delete-workflow-runs@v2 + with: + token: ${{ github.token }} + repository: ${{ github.repository }} + retain_days: 7 + keep_minimum_runs: 6 + delete_run_by_conclusion_pattern: 'success' + check_pullrequest_exist: true + - name: Delete Cancelled workflow runs + uses: Mattraks/delete-workflow-runs@v2 + with: + token: ${{ github.token }} + repository: ${{ github.repository }} + retain_days: 0 + keep_minimum_runs: 0 + delete_run_by_conclusion_pattern: 'cancelled,skipped' diff --git a/.gitignore b/.gitignore index 4cf326006..5ff9c8794 100644 --- a/.gitignore +++ b/.gitignore @@ -10,4 +10,3 @@ FodyWeavers.xsd TOHE.sln .vscode/settings.json /token.env -token.env diff --git a/GameModes/FFAManager.cs b/GameModes/FFAManager.cs index 6d02edf53..a3959a58e 100644 --- a/GameModes/FFAManager.cs +++ b/GameModes/FFAManager.cs @@ -102,7 +102,7 @@ public static void Init() public static void SetData() { if (Options.CurrentGameMode != CustomGameMode.FFA) return; - + RoundTime = FFA_GameTime.GetInt() + 8; var now = Utils.GetTimeStamp() + 8; foreach (PlayerControl pc in Main.AllAlivePlayerControls) diff --git a/GlobalUsings.cs b/GlobalUsings.cs index 411fada1b..f4b7651a1 100644 --- a/GlobalUsings.cs +++ b/GlobalUsings.cs @@ -4,6 +4,5 @@ // it is recommended to add only those that are used most often global using HarmonyLib; -global using System.Collections.Generic; global using System.Linq; -global using System.Reflection; +global using System.Collections.Generic; \ No newline at end of file diff --git a/Modules/AntiBlackout.cs b/Modules/AntiBlackout.cs index fdc8d3ddc..fd4a23294 100644 --- a/Modules/AntiBlackout.cs +++ b/Modules/AntiBlackout.cs @@ -34,11 +34,11 @@ public static bool CheckBlackOut() if (lastExiled != null && pc.PlayerId == lastExiled.PlayerId) continue; // Impostors - if (pc.Is(Custom_Team.Impostor)) + if (pc.Is(Custom_Team.Impostor) && !Main.PlayerStates[pc.PlayerId].IsRandomizer) Impostors.Add(pc.PlayerId); // Only Neutral killers - else if (pc.IsNeutralKiller() || pc.IsNeutralApocalypse()) + else if (pc.IsNeutralKiller() || pc.IsNeutralApocalypse() && !Main.PlayerStates[pc.PlayerId].IsRandomizer) NeutralKillers.Add(pc.PlayerId); // Crewmate @@ -100,13 +100,7 @@ private static void RevivePlayersAndSetDummyImp() if (CustomWinnerHolder.WinnerTeam != CustomWinner.Default) return; PlayerControl dummyImp = Main.AllAlivePlayerControls.FirstOrDefault(x => x.PlayerId != ExilePlayerId); - - if (dummyImp == null) - { - Logger.Warn("Cant find a alive dummy Imp, AntiBlackout may break?", "AntiBlackout.RevivePlayersAndSetDummyImp"); - Logger.SendInGame("Cant find a alive dummy Imp, AntiBlackout may break?"); - return; - } + if (dummyImp == null) return; foreach (var seer in Main.AllPlayerControls) { @@ -133,25 +127,7 @@ public static void RestoreIsDead(bool doSend = true, [CallerMemberName] string c } isDeadCache.Clear(); IsCached = false; - if (doSend) - { - SendGameData(); - _ = new LateTask(() => RestoreIsDeadByExile(), 0.3f, "AntiBlackOut_RestoreIsDeadByExile"); - } - } - - private static void RestoreIsDeadByExile() - { - var sender = CustomRpcSender.Create("AntiBlackout RestoreIsDeadByExile", SendOption.Reliable); - foreach (var player in Main.AllPlayerControls) - { - if (player.Data.IsDead && !player.Data.Disconnected) - { - sender.AutoStartRpc(player.NetId, (byte)RpcCalls.Exiled); - sender.EndRpc(); - } - } - sender.SendMessage(); + if (doSend) SendGameData(); } public static void SendGameData([CallerMemberName] string callerMethodName = "") @@ -250,7 +226,7 @@ public static void SetRealPlayerRoles() { // skip host if (seerId == 0) continue; - + var seer = seerId.GetPlayer(); var target = targetId.GetPlayer(); diff --git a/Modules/BanManager.cs b/Modules/BanManager.cs index a3e8a2c5d..f2f382e63 100644 --- a/Modules/BanManager.cs +++ b/Modules/BanManager.cs @@ -1,6 +1,7 @@ using InnerNet; using System; using System.IO; +using System.Reflection; using System.Security.Cryptography; using System.Text; using System.Text.RegularExpressions; @@ -79,12 +80,8 @@ public static string GetHashedPuid(this ClientData player) { if (player == null) return ""; string puid = player.ProductUserId; - return GetHashedPuid(puid); - } - public static string GetHashedPuid(string puid) - { using SHA256 sha256 = SHA256.Create(); - + // get sha-256 hash byte[] sha256Bytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(puid)); string sha256Hash = BitConverter.ToString(sha256Bytes).Replace("-", "").ToLower(); @@ -92,7 +89,6 @@ public static string GetHashedPuid(string puid) // pick front 5 and last 4 return string.Concat(sha256Hash.AsSpan(0, 5), sha256Hash.AsSpan(sha256Hash.Length - 4)); } - public static void AddBanPlayer(ClientData player) { if (!AmongUsClient.Instance.AmHost || player == null) return; @@ -108,7 +104,7 @@ public static void AddBanPlayer(ClientData player) else Logger.Info($"Failed to add player {player?.PlayerName.RemoveHtmlTags()}/{player?.FriendCode}/{player?.GetHashedPuid()} to ban list!", "AddBanPlayer"); } } - + public static bool CheckDenyNamePlayer(PlayerControl player, string name) { if (!AmongUsClient.Instance.AmHost || !Options.ApplyDenyNameList.GetBool()) return false; @@ -229,9 +225,9 @@ public static bool CheckEACList(string code, string hashedPuid) var splitUser = user["friendcode"].ToString().Split('#')[0].ToLower().Trim(); if ((!string.IsNullOrEmpty(splitCode) && (splitCode == splitUser)) - || !hashedPuid.IsNullOrWhiteSpace() && (user["hashPUID"].ToString().ToLower().Trim() == hashedPuid.ToLower().Trim())) + || (user["hashPUID"].ToString().ToLower().Trim() == hashedPuid.ToLower().Trim())) { - Logger.Warn($"friendcode : {code}, hashedPUID : {hashedPuid} banned by EAC reason : {user["friendcode"]} {user["reason"]}", "CheckEACList"); + Logger.Warn($"friendcode : {code}, hashedPUID : {hashedPuid} banned by EAC reason : {user["reason"]}", "CheckEACList"); return true; } } diff --git a/Modules/ChatManager.cs b/Modules/ChatManager.cs index f9ed65791..aa707b6eb 100644 --- a/Modules/ChatManager.cs +++ b/Modules/ChatManager.cs @@ -3,6 +3,7 @@ using System.Security.Cryptography; using System.Text; using TOHE.Roles.Impostor; +using TOHE.Roles.Neutral; using static TOHE.Translator; namespace TOHE.Modules.ChatManager @@ -93,6 +94,10 @@ public static void AddToHostMessage(string text) } public static void SendMessage(PlayerControl player, string message) { + if (player == null || string.IsNullOrWhiteSpace(message)) return; + + + int operate = 0; // 1:ID 2:猜测 string msg = message; string playername = player.GetNameWithRole(); @@ -103,6 +108,9 @@ public static void SendMessage(PlayerControl player, string message) else if (CheckCommond(ref msg, "shoot|guess|bet|st|gs|bt|猜|赌|賭|sp|jj|tl|trial|审判|判|审|審判|審|compare|cmp|比较|比較|duel|sw|swap|st|换票|换|換票|換|finish|结束|结束会议|結束|結束會議|reveal|展示", false)) operate = 2; else if (ChatSentBySystem.Contains(GetTextHash(msg))) operate = 5; + + + // Handle Blackmailer blocking if ((operate == 1 || Blackmailer.CheckBlackmaile(player)) && player.IsAlive()) { Logger.Info($"包含特殊信息,不记录", "ChatManager"); @@ -139,12 +147,12 @@ public static void SendMessage(PlayerControl player, string message) return; } if (!player.IsAlive()) return; + message = msg; - //Logger.Warn($"Logging msg : {message}","Checking Exile"); Dictionary newChatEntry = new() - { - { player.PlayerId, message } - }; + { + { player.PlayerId, message } + }; chatHistory.Add(newChatEntry); if (chatHistory.Count > maxHistorySize) @@ -155,6 +163,7 @@ public static void SendMessage(PlayerControl player, string message) } } + public static void SendPreviousMessagesToAll() { if (!AmongUsClient.Instance.AmHost || !GameStates.IsModHost) return; diff --git a/Modules/Cloud.cs b/Modules/Cloud.cs index eb02362e1..73b7ce5fc 100644 --- a/Modules/Cloud.cs +++ b/Modules/Cloud.cs @@ -1,6 +1,7 @@ using System; using System.IO; using System.Net.Sockets; +using System.Reflection; using System.Text; namespace TOHE; diff --git a/Modules/CustomRolesHelper.cs b/Modules/CustomRolesHelper.cs index 3ad10f27c..655ded2da 100644 --- a/Modules/CustomRolesHelper.cs +++ b/Modules/CustomRolesHelper.cs @@ -2,11 +2,11 @@ using System; using TOHE.Roles.AddOns.Common; using TOHE.Roles.AddOns.Crewmate; -using TOHE.Roles.AddOns.Impostor; -using TOHE.Roles.Core; using TOHE.Roles.Crewmate; using TOHE.Roles.Impostor; using TOHE.Roles.Neutral; +using TOHE.Roles.AddOns.Impostor; +using TOHE.Roles.Core; using static TOHE.Roles.Core.CustomRoleManager; namespace TOHE; @@ -48,7 +48,6 @@ public static RoleTypes GetDYRole(this CustomRoles role) // Role has a kill butt public static bool HasImpKillButton(this PlayerControl player, bool considerVanillaShift = false) { - /* if (player == null) return false; var customRole = player.GetCustomRole(); bool ModSideHasKillButton = customRole.GetDYRole() == RoleTypes.Impostor || customRole.GetVNRole() is CustomRoles.Impostor or CustomRoles.Shapeshifter or CustomRoles.Phantom; @@ -60,14 +59,6 @@ public static bool HasImpKillButton(this PlayerControl player, bool considerVani (OriginalRole.GetDYRole() is RoleTypes.Impostor or RoleTypes.Shapeshifter || OriginalRole.GetVNRole() is CustomRoles.Impostor or CustomRoles.Shapeshifter or CustomRoles.Phantom) : ModSideHasKillButton; return vanillaSideHasKillButton; - */ - - // Due to the fact that change role basis is widely used in mod - // this function now always uses current mod role to decide kill button access? - - if (player == null) return false; - var customRole = player.GetCustomRole(); - return customRole.GetDYRole() == RoleTypes.Impostor || customRole.GetVNRole() is CustomRoles.Impostor or CustomRoles.Shapeshifter or CustomRoles.Phantom; } //This is a overall check for vanilla clients to see if they are imp basis public static bool IsGhostRole(this CustomRoles role) @@ -140,7 +131,7 @@ CustomRoles.Stalker or CustomRoles.Doomsayer or CustomRoles.SoulCollector or CustomRoles.Death or - CustomRoles.Berserker or + CustomRoles.Berserker or CustomRoles.War or CustomRoles.Baker or CustomRoles.Famine or @@ -159,7 +150,6 @@ public static bool IsAmneCrew(this PlayerControl target) return target.IsCrewVenter() || target.GetCustomRole() is CustomRoles.Sheriff or - CustomRoles.ChiefOfPolice or CustomRoles.LazyGuy or CustomRoles.SuperStar or CustomRoles.Celebrity or @@ -321,7 +311,6 @@ public static bool IsMadmate(this CustomRoles role) /// /// Role Changes the Crewmates Team, Including changing to Impostor. /// - public static bool IsConverted(this CustomRoles role) => (role is CustomRoles.Egoist && Egoist.EgoistCountAsConverted.GetBool()) || role is CustomRoles.Charmed or @@ -393,7 +382,7 @@ public static bool CheckAddonConfilct(CustomRoles role, PlayerControl pc, bool c // Only add-ons if (!role.IsAdditionRole() || pc == null) return false; - if (Options.AddonCanBeSettings.TryGetValue(role, out var o) && ((!o.Imp.GetBool() && pc.GetCustomRole().IsImpostor()) || (!o.Neutral.GetBool() && pc.GetCustomRole().IsNeutral()) || (!o.Crew.GetBool() && pc.GetCustomRole().IsCrewmate()))) + if (Options.AddonCanBeSettings.TryGetValue(role, out var o) && ((!o.Imp.GetBool() && pc.GetCustomRole().IsImpostor()) || (!o.Neutral.GetBool() && pc.GetCustomRole().IsNeutral()) || (!o.Crew.GetBool() && pc.GetCustomRole().IsCrewmate()))) return false; // if player already has this addon @@ -542,7 +531,7 @@ public static bool CheckAddonConfilct(CustomRoles role, PlayerControl pc, bool c return false; - if (pc.Is(CustomRoles.CopyCat) + if (pc.Is(CustomRoles.CopyCat) || pc.Is(CustomRoles.Workaholic) && !Workaholic.WorkaholicCanGuess.GetBool() || (pc.Is(CustomRoles.Terrorist) && (!Terrorist.TerroristCanGuess.GetBool() || Terrorist.CanTerroristSuicideWin.GetBool()) || (pc.Is(CustomRoles.Specter) && !Specter.CanGuess.GetBool())) @@ -575,8 +564,6 @@ public static bool CheckAddonConfilct(CustomRoles role, PlayerControl pc, bool c case CustomRoles.Overclocked: if (!pc.CanUseKillButton()) return false; - if (pc.Is(CustomRoles.Reverie)) - return false; break; case CustomRoles.Lazy: @@ -760,9 +747,9 @@ public static bool CheckAddonConfilct(CustomRoles role, PlayerControl pc, bool c break; case CustomRoles.Rebirth: - if (pc.Is(CustomRoles.Doppelganger) + if (pc.Is(CustomRoles.Doppelganger) || pc.Is(CustomRoles.Jester) - || pc.Is(CustomRoles.Zombie) + || pc.Is(CustomRoles.Zombie) || pc.Is(CustomRoles.Solsticer) || pc.IsNeutralApocalypse()) return false; break; @@ -803,8 +790,7 @@ public static bool CheckAddonConfilct(CustomRoles role, PlayerControl pc, bool c case CustomRoles.Rascal: if (pc.Is(CustomRoles.SuperStar) || pc.Is(CustomRoles.NiceMini) - || pc.Is(CustomRoles.Madmate) - || pc.Is(CustomRoles.ChiefOfPolice)) + || pc.Is(CustomRoles.Madmate)) return false; if (!pc.GetCustomRole().IsCrewmate()) return false; @@ -1026,7 +1012,7 @@ public static bool CheckAddonConfilct(CustomRoles role, PlayerControl pc, bool c break; case CustomRoles.Oiiai: - if (pc.Is(CustomRoles.Loyal) + if (pc.Is(CustomRoles.Loyal) || pc.Is(CustomRoles.Solsticer) || pc.Is(CustomRoles.Innocent) || pc.Is(CustomRoles.PunchingBag)) @@ -1079,14 +1065,14 @@ public static bool CheckAddonConfilct(CustomRoles role, PlayerControl pc, bool c || pc.Is(CustomRoles.Sloth)) return false; break; - - case CustomRoles.Susceptible: + + case CustomRoles.Susceptible: if (pc.Is(CustomRoles.Jester)) return false; break; case CustomRoles.Sloth: - if (pc.Is(CustomRoles.Swooper) + if (pc.Is(CustomRoles.Swooper) || pc.Is(CustomRoles.Solsticer) || pc.Is(CustomRoles.Tired) || pc.Is(CustomRoles.Statue) @@ -1101,7 +1087,7 @@ public static bool CheckAddonConfilct(CustomRoles role, PlayerControl pc, bool c break; case CustomRoles.Evader: if (pc.IsNeutralApocalypse()) - return false; + return false; break; } @@ -1161,16 +1147,59 @@ CustomRoles.Phantom or } public static Custom_Team GetCustomRoleTeam(this CustomRoles role) { + // Default team is Crewmate Custom_Team team = Custom_Team.Crewmate; + + // Look up the associated player control + foreach (var pc in PlayerControl.AllPlayerControls) + { + if (pc.GetCustomRole() == role) + { + var playerState = Main.PlayerStates[pc.PlayerId]; + if (playerState != null && playerState.IsRandomizer) + { + if (playerState.IsImpostorTeam) return Custom_Team.Impostor; + if (playerState.IsCrewmateTeam) return Custom_Team.Crewmate; + if (playerState.IsNeutralTeam) return Custom_Team.Neutral; + } + } + } + + // Assign team based on role attributes if (role.IsImpostor()) team = Custom_Team.Impostor; if (role.IsNeutral()) team = Custom_Team.Neutral; if (role.IsAdditionRole()) team = Custom_Team.Addon; + return team; } - public static Custom_RoleType GetCustomRoleType(this CustomRoles role) + + + public static Custom_RoleType GetCustomRoleType(this CustomRoles role, byte playerId) { + var playerState = Main.PlayerStates[playerId]; + + if (playerState.IsRandomizer) + { + // Check the locked team and assign the corresponding Custom_RoleType + if (playerState.IsCrewmateTeam) + return Custom_RoleType.CrewmateBasic; + if (playerState.IsNeutralTeam) + return Custom_RoleType.NeutralBenign; + if (playerState.IsImpostorTeam) + return Custom_RoleType.ImpostorKilling; + + // Default fallback for unexpected cases + return Custom_RoleType.CrewmateBasic; + } + + // Fallback to the static role type for non-Randomizer roles return role.GetStaticRoleClass().ThisRoleType; } + + + + + public static bool RoleExist(this CustomRoles role, bool countDead = false) => Main.AllPlayerControls.Any(x => x.Is(role) && (x.IsAlive() || countDead)); public static int GetCount(this CustomRoles role) { @@ -1222,58 +1251,60 @@ public static float GetChance(this CustomRoles role) } public static bool IsEnable(this CustomRoles role) => role.GetCount() > 0; public static CountTypes GetCountTypes(this CustomRoles role) - => role switch - { - CustomRoles.GM => CountTypes.OutOfGame, - CustomRoles.Jackal => CountTypes.Jackal, - CustomRoles.Sidekick => CountTypes.Jackal, - CustomRoles.Doppelganger => CountTypes.Doppelganger, - CustomRoles.Bandit => CountTypes.Bandit, - CustomRoles.Poisoner => CountTypes.Poisoner, - CustomRoles.Pelican => CountTypes.Pelican, - CustomRoles.Minion => CountTypes.Impostor, - CustomRoles.Bloodmoon => CountTypes.Impostor, - CustomRoles.Possessor => CountTypes.Impostor, - CustomRoles.Demon => CountTypes.Demon, - CustomRoles.BloodKnight => CountTypes.BloodKnight, - CustomRoles.Cultist => CountTypes.Cultist, - CustomRoles.HexMaster => CountTypes.HexMaster, - CustomRoles.Necromancer => CountTypes.Necromancer, - CustomRoles.Stalker => Stalker.SnatchesWins ? CountTypes.Crew : CountTypes.Stalker, - CustomRoles.Arsonist => Arsonist.CanIgniteAnytime() ? CountTypes.Arsonist : CountTypes.Crew, - CustomRoles.Shroud => CountTypes.Shroud, - CustomRoles.Werewolf => CountTypes.Werewolf, - CustomRoles.Wraith => CountTypes.Wraith, - var r when r.IsNA() => CountTypes.Apocalypse, - CustomRoles.Agitater => CountTypes.Agitater, - CustomRoles.Parasite => CountTypes.Impostor, - CustomRoles.SerialKiller => CountTypes.SerialKiller, - CustomRoles.Quizmaster => CountTypes.Quizmaster, - CustomRoles.Juggernaut => CountTypes.Juggernaut, - CustomRoles.Jinx => CountTypes.Jinx, - CustomRoles.Infectious or CustomRoles.Infected => CountTypes.Infectious, - CustomRoles.Crewpostor => CountTypes.Impostor, - CustomRoles.Pyromaniac => CountTypes.Pyromaniac, - CustomRoles.PlagueDoctor => CountTypes.PlagueDoctor, - CustomRoles.Virus => CountTypes.Virus, - CustomRoles.PotionMaster => CountTypes.PotionMaster, - CustomRoles.Pickpocket => CountTypes.Pickpocket, - CustomRoles.Traitor => CountTypes.Traitor, - CustomRoles.Medusa => CountTypes.Medusa, - CustomRoles.Refugee => CountTypes.Impostor, - CustomRoles.Huntsman => CountTypes.Huntsman, - CustomRoles.Glitch => CountTypes.Glitch, - CustomRoles.Spiritcaller => CountTypes.Spiritcaller, - CustomRoles.RuthlessRomantic => CountTypes.RuthlessRomantic, - CustomRoles.Shocker => CountTypes.Shocker, - CustomRoles.SchrodingersCat => CountTypes.None, - CustomRoles.Solsticer => CountTypes.None, - CustomRoles.Revenant => CountTypes.None, - _ => role.IsImpostorTeam() ? CountTypes.Impostor : CountTypes.Crew, - - // CustomRoles.Phantom => CountTypes.OutOfGame, - // CustomRoles.CursedSoul => CountTypes.OutOfGame, // if they count as OutOfGame, it prevents them from winning lmao - }; + { + + + // Default logic for other roles + return role switch + { + CustomRoles.GM => CountTypes.OutOfGame, + CustomRoles.Randomizer => CountTypes.None, + CustomRoles.Jackal => CountTypes.Jackal, + CustomRoles.Sidekick => CountTypes.Jackal, + CustomRoles.Doppelganger => CountTypes.Doppelganger, + CustomRoles.Bandit => CountTypes.Bandit, + CustomRoles.Poisoner => CountTypes.Poisoner, + CustomRoles.Pelican => CountTypes.Pelican, + CustomRoles.Minion => CountTypes.Impostor, + CustomRoles.Bloodmoon => CountTypes.Impostor, + CustomRoles.Possessor => CountTypes.Impostor, + CustomRoles.Demon => CountTypes.Demon, + CustomRoles.BloodKnight => CountTypes.BloodKnight, + CustomRoles.Cultist => CountTypes.Cultist, + CustomRoles.HexMaster => CountTypes.HexMaster, + CustomRoles.Necromancer => CountTypes.Necromancer, + CustomRoles.Stalker => Stalker.SnatchesWins ? CountTypes.Crew : CountTypes.Stalker, + CustomRoles.Arsonist => Arsonist.CanIgniteAnytime() ? CountTypes.Arsonist : CountTypes.Crew, + CustomRoles.Shroud => CountTypes.Shroud, + CustomRoles.Werewolf => CountTypes.Werewolf, + CustomRoles.Wraith => CountTypes.Wraith, + var r when r.IsNA() => CountTypes.Apocalypse, + CustomRoles.Agitater => CountTypes.Agitater, + CustomRoles.Parasite => CountTypes.Impostor, + CustomRoles.SerialKiller => CountTypes.SerialKiller, + CustomRoles.Quizmaster => CountTypes.Quizmaster, + CustomRoles.Juggernaut => CountTypes.Juggernaut, + CustomRoles.Jinx => CountTypes.Jinx, + CustomRoles.Infectious or CustomRoles.Infected => CountTypes.Infectious, + CustomRoles.Crewpostor => CountTypes.Impostor, + CustomRoles.Pyromaniac => CountTypes.Pyromaniac, + CustomRoles.PlagueDoctor => CountTypes.PlagueDoctor, + CustomRoles.Virus => CountTypes.Virus, + CustomRoles.PotionMaster => CountTypes.PotionMaster, + CustomRoles.Pickpocket => CountTypes.Pickpocket, + CustomRoles.Traitor => CountTypes.Traitor, + CustomRoles.Medusa => CountTypes.Medusa, + CustomRoles.Refugee => CountTypes.Impostor, + CustomRoles.Huntsman => CountTypes.Huntsman, + CustomRoles.Glitch => CountTypes.Glitch, + CustomRoles.Spiritcaller => CountTypes.Spiritcaller, + CustomRoles.RuthlessRomantic => CountTypes.RuthlessRomantic, + CustomRoles.SchrodingersCat => CountTypes.None, + CustomRoles.Solsticer => CountTypes.None, + _ => role.IsImpostorTeam() ? CountTypes.Impostor : CountTypes.Crew, + }; + } + public static CustomWinner GetNeutralCustomWinnerFromRole(this CustomRoles role) // only to be used for Neutrals => role switch { @@ -1332,7 +1363,6 @@ var r when r.IsNA() => CountTypes.Apocalypse, CustomRoles.RuthlessRomantic => CustomWinner.RuthlessRomantic, CustomRoles.Mini => CustomWinner.NiceMini, CustomRoles.Doppelganger => CustomWinner.Doppelganger, - CustomRoles.Shocker => CustomWinner.Shocker, _ => throw new NotImplementedException() }; @@ -1372,12 +1402,14 @@ var r when r.IsNA() => CountTypes.Apocalypse, CountTypes.Spiritcaller => CustomRoles.Spiritcaller, CountTypes.Arsonist => CustomRoles.Arsonist, CountTypes.RuthlessRomantic => CustomRoles.RuthlessRomantic, - CountTypes.Shocker => CustomRoles.Shocker, _ => throw new NotImplementedException() }; public static bool HasSubRole(this PlayerControl pc) => Main.PlayerStates[pc.PlayerId].SubRoles.Any(); + public static bool HasSpecificSubRole(this PlayerControl pc, CustomRoles role) + { + return Main.PlayerStates[pc.PlayerId].SubRoles.Contains(role); + } } -[Obfuscation(Exclude = true)] public enum Custom_Team { Crewmate, @@ -1385,7 +1417,6 @@ public enum Custom_Team Neutral, Addon, } -[Obfuscation(Exclude = true)] public enum Custom_RoleType { // Impostors @@ -1395,8 +1426,11 @@ public enum Custom_RoleType ImpostorConcealing, ImpostorHindering, ImpostorGhosts, + Madmate, + + // Crewmate CrewmateVanilla, CrewmateVanillaGhosts, @@ -1412,10 +1446,9 @@ public enum Custom_RoleType NeutralChaos, NeutralKilling, NeutralApocalypse, - + None } -[Obfuscation(Exclude = true)] public enum CountTypes { OutOfGame, @@ -1455,6 +1488,5 @@ public enum CountTypes Werewolf, Agitater, RuthlessRomantic, - Necromancer, - Shocker + Necromancer } diff --git a/Modules/CustomRpcSender.cs b/Modules/CustomRpcSender.cs index 532408023..5329e1c09 100644 --- a/Modules/CustomRpcSender.cs +++ b/Modules/CustomRpcSender.cs @@ -218,7 +218,7 @@ private CustomRpcSender Write(Action action) return this; } - [Obfuscation(Exclude = true)] + public enum State { BeforeInit = 0, //初期化前 何もできない diff --git a/Modules/CustomSounds.cs b/Modules/CustomSounds.cs index 390f09536..334487c78 100644 --- a/Modules/CustomSounds.cs +++ b/Modules/CustomSounds.cs @@ -1,6 +1,7 @@ using Hazel; using System; using System.IO; +using System.Reflection; using System.Runtime.InteropServices; namespace TOHE.Modules; diff --git a/Modules/CustomWinnerHolder.cs b/Modules/CustomWinnerHolder.cs index 8f43fc640..e594da0bd 100644 --- a/Modules/CustomWinnerHolder.cs +++ b/Modules/CustomWinnerHolder.cs @@ -60,19 +60,19 @@ public static bool CheckForConvertedWinner(byte playerId) ResetAndSetWinner(CustomWinner.Crewmate); return true; case CustomRoles.Madmate: - ResetAndSetWinner(CustomWinner.Impostor); + ResetAndSetWinner(CustomWinner.Impostor); return true; case CustomRoles.Recruit: - ResetAndSetWinner(CustomWinner.Jackal); + ResetAndSetWinner(CustomWinner.Jackal); return true; case CustomRoles.Charmed: - ResetAndSetWinner(CustomWinner.Cultist); + ResetAndSetWinner(CustomWinner.Cultist); return true; case CustomRoles.Infectious: - ResetAndSetWinner(CustomWinner.Infectious); + ResetAndSetWinner(CustomWinner.Infectious); return true; case CustomRoles.Contagious: - ResetAndSetWinner(CustomWinner.Virus); + ResetAndSetWinner(CustomWinner.Virus); return true; } } diff --git a/Modules/Debugger.cs b/Modules/Debugger.cs index 77ec9b49f..615565468 100644 --- a/Modules/Debugger.cs +++ b/Modules/Debugger.cs @@ -142,4 +142,14 @@ public static void CurrentMethod([CallerLineNumber] int lineNumber = 0, [CallerF public static LogHandler Handler(string tag) => new(tag); + + internal static void Info(string v) + { + throw new NotImplementedException(); + } + + internal static void Warn(string v) + { + throw new NotImplementedException(); + } } \ No newline at end of file diff --git a/Modules/DelayNetworkedData.cs b/Modules/DelayNetworkedData.cs index 30839da01..fbb9dfae2 100644 --- a/Modules/DelayNetworkedData.cs +++ b/Modules/DelayNetworkedData.cs @@ -65,7 +65,7 @@ private static void DelaySpawnPlayerInfo(InnerNetClient __instance, int clientId foreach (var player in batch) { - if (messageWriter.Length > 500) break; + if (messageWriter.Length > 1600) break; if (player != null && player.ClientId != clientId && !player.Disconnected) { __instance.WriteSpawnMessage(player, player.OwnerId, player.SpawnFlags, messageWriter); @@ -239,7 +239,6 @@ public static void FixedUpdatePostfix(InnerNetClient __instance) } } } - [Obfuscation(Exclude = true)] [HarmonyPatch(typeof(InnerNetClient), nameof(InnerNetClient.SendOrDisconnect)), HarmonyPrefix] public static void SendOrDisconnectPatch(InnerNetClient __instance, MessageWriter msg) { @@ -264,4 +263,4 @@ public static bool Prefix() { return false; } -} +} \ No newline at end of file diff --git a/Modules/DevManager.cs b/Modules/DevManager.cs index f7627fad9..af8022f3c 100644 --- a/Modules/DevManager.cs +++ b/Modules/DevManager.cs @@ -96,6 +96,7 @@ public static void Init() DevUserList.Add(new(code: "icingposh#6469", color: "#9e2424", userType: "s_cr", tag: "discord.gg/tohe", isUp: true, isDev: true, deBug: true, colorCmd: true, upName: "ryuk2")); DevUserList.Add(new(code: "bestanswer#3360", color: "#00ff1d", tag: "绿色游戏", userType: "s_cr", isUp: true, isDev: true, deBug: true, colorCmd: true, upName: null)); //NikoCat233's alt DevUserList.Add(new(code: "happypride#3747", color: "#00ff1d", tag: "绿色游戏", userType: "s_cr", isUp: true, isDev: true, deBug: true, colorCmd: true, upName: null)); //NikoCat233's alt 2 + //// pt-BR Translators //DevUserList.Add(new(code: "modelpad#5195", color: "null", tag: "Tradutor", isUp: true, isDev: false, deBug: false, colorCmd: false, upName: "Reginaldoo")); // and content creator //DevUserList.Add(new(code: "mimerecord#9638", color: "null", tag: "Tradutor", isUp: false, isDev: false, deBug: false, colorCmd: false, upName: "Arc")); diff --git a/Modules/DisableDevice.cs b/Modules/DisableDevice.cs index ca2eaad19..d2ad437e3 100644 --- a/Modules/DisableDevice.cs +++ b/Modules/DisableDevice.cs @@ -12,20 +12,20 @@ class DisableDevice private static int frame = 0; public static readonly Dictionary DevicePos = new() { - ["SkeldAdmin"] = new Vector2(3.48f, -8.62f), - ["SkeldCamera"] = new Vector2(-13.06f, -2.45f), - ["MiraHQAdmin"] = new Vector2(21.02f, 19.09f), - ["MiraHQDoorLog"] = new Vector2(16.22f, 5.82f), - ["PolusLeftAdmin"] = new Vector2(22.80f, -21.52f), - ["PolusRightAdmin"] = new Vector2(24.66f, -21.52f), - ["PolusCamera"] = new Vector2(2.96f, -12.74f), - ["PolusVital"] = new Vector2(26.70f, -15.94f), - ["DleksAdmin"] = new Vector2(-3.48f, -8.62f), - ["DleksCamera"] = new Vector2(13.06f, -2.45f), - ["AirshipCockpitAdmin"] = new Vector2(-22.32f, 0.91f), - ["AirshipRecordsAdmin"] = new Vector2(19.89f, 12.60f), - ["AirshipCamera"] = new Vector2(8.10f, -9.63f), - ["AirshipVital"] = new Vector2(25.24f, -7.94f), + ["SkeldAdmin"] = new Vector2 (3.48f, -8.62f), + ["SkeldCamera"] = new Vector2 (-13.06f, -2.45f), + ["MiraHQAdmin"] = new Vector2 (21.02f, 19.09f), + ["MiraHQDoorLog"] = new Vector2 (16.22f, 5.82f), + ["PolusLeftAdmin"] = new Vector2 (22.80f, -21.52f), + ["PolusRightAdmin"] = new Vector2 (24.66f, -21.52f), + ["PolusCamera"] = new Vector2 (2.96f, -12.74f), + ["PolusVital"] = new Vector2 (26.70f, -15.94f), + ["DleksAdmin"] = new Vector2 (-3.48f, -8.62f), + ["DleksCamera"] = new Vector2 (13.06f, -2.45f), + ["AirshipCockpitAdmin"] = new Vector2 (-22.32f, 0.91f), + ["AirshipRecordsAdmin"] = new Vector2 (19.89f, 12.60f), + ["AirshipCamera"] = new Vector2 (8.10f, -9.63f), + ["AirshipVital"] = new Vector2 (25.24f, -7.94f), ["FungleCamera"] = new Vector2(6.20f, 0.10f), ["FungleVital"] = new Vector2(-2.50f, -9.80f) }; diff --git a/Modules/DoorsReset.cs b/Modules/DoorsReset.cs index 698ccbd7e..2d292b77d 100644 --- a/Modules/DoorsReset.cs +++ b/Modules/DoorsReset.cs @@ -88,6 +88,6 @@ private static bool IsValidDoor(OpenableDoor door) // Airship lounge toilets and Polus decontamination room doors are not closed return door.Room is not (SystemTypes.Lounge or SystemTypes.Decontamination); } - [Obfuscation(Exclude = true)] + public enum ResetModeList { AllOpen, AllClosed, RandomByDoor, } } diff --git a/Modules/EAC.cs b/Modules/EAC.cs index f5d3e8482..790678b09 100644 --- a/Modules/EAC.cs +++ b/Modules/EAC.cs @@ -1,6 +1,6 @@ using Hazel; -using InnerNet; using System; +using InnerNet; using static TOHE.Translator; namespace TOHE; @@ -252,37 +252,6 @@ public static bool PlayerControlReceiveRpc(PlayerControl pc, byte callId, Messag // Do nothing } break; - case 119: // KN Chat - try - { - var firstString = sr.ReadString(); - var secondString = sr.ReadString(); - sr.ReadInt32(); - - var flag = string.IsNullOrEmpty(firstString) && string.IsNullOrEmpty(secondString); - - if (!flag) - { - Report(pc, "KN Chat RPC"); - HandleCheat(pc, "KN Chat RPC"); - Logger.Fatal($"玩家【{pc.GetClientId()}:{pc.GetRealName()}】发送KN聊天,已驳回", "EAC"); - return true; - } - } - catch - { - // Do nothing - } - break; - case 250: // KN - if (sr.BytesRemaining == 0) - { - Report(pc, "KN RPC"); - HandleCheat(pc, "KN RPC"); - Logger.Fatal($"玩家【{pc.GetClientId()}:{pc.GetRealName()}】发送KN RPC,已驳回", "EAC"); - return true; - } - break; case unchecked((byte)420): // 164 Sicko if (sr.BytesRemaining == 0) { @@ -490,8 +459,8 @@ public static bool RpcReportDeadBodyCheck(PlayerControl player, NetworkedPlayerI if (!GameStates.IsInGame) { WarnHost(); - Report(player, "Report body out of game C"); - HandleCheat(player, "Report body out of game C"); + Report(player, "Report body out of game"); + HandleCheat(player, "Report body out of game"); Logger.Fatal($"玩家【{player.GetClientId()}:{player.GetRealName()}】非游戏内开会,已驳回", "EAC"); return true; } diff --git a/Modules/ErrorText.cs b/Modules/ErrorText.cs index 95b7ac7e3..e98ea8576 100644 --- a/Modules/ErrorText.cs +++ b/Modules/ErrorText.cs @@ -3,7 +3,6 @@ namespace TOHE; -[Obfuscation(Exclude = true, ApplyToMembers = true)] public class ErrorText : MonoBehaviour { #region Singleton @@ -146,7 +145,6 @@ public override string ToString() public bool CheatDetected; public bool SBDetected; } -[Obfuscation(Exclude = true)] public enum ErrorCode { //xxxyyyz: ERR-xxx-yyy-z @@ -172,4 +170,4 @@ public enum ErrorCode HnsUnload = 000_804_1, // 000-804-1 Unloaded By HnS CheatDetected = 000_666_2, // 000-666-2 疑似存在作弊玩家 SBDetected = 000_666_1, // 000-666-1 傻逼外挂司马东西 -} +} \ No newline at end of file diff --git a/Modules/ExtendedPlayerControl.cs b/Modules/ExtendedPlayerControl.cs index 8d781a082..913878997 100644 --- a/Modules/ExtendedPlayerControl.cs +++ b/Modules/ExtendedPlayerControl.cs @@ -12,6 +12,7 @@ using TOHE.Roles.Impostor; using TOHE.Roles.Neutral; using UnityEngine; +using UnityEngine.SocialPlatforms; using static TOHE.Translator; namespace TOHE; @@ -23,8 +24,6 @@ public static void RpcSetCustomRole(this PlayerControl player, CustomRoles role) if (role < CustomRoles.NotAssigned) { Main.PlayerStates[player.PlayerId].SetMainRole(role); - // player.GetRoleClass()?.OnAdd(player.PlayerId); - // Remember to manually add OnAdd if you are setting role mid game } else if (role >= CustomRoles.NotAssigned) //500:NoSubRole 501~:SubRole { @@ -276,7 +275,7 @@ public static void RpcSetPetDesync(this PlayerControl player, string petId, Play public static void RpcExile(this PlayerControl player) { player.Exiled(); - MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(player.NetId, (byte)RpcCalls.Exiled, SendOption.Reliable, -1); + MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(player.NetId, (byte)RpcCalls.Exiled, SendOption.None, -1); AmongUsClient.Instance.FinishRpcImmediately(writer); } public static void RpcExileDesync(this PlayerControl player, PlayerControl seer) @@ -485,7 +484,7 @@ public static void SetKillCooldown(this PlayerControl player, float time = -1f, if (!player.HasImpKillButton(considerVanillaShift: true)) return; if (player.HasImpKillButton(false) && !player.CanUseKillButton()) return; - + player.SetKillTimer(CD: time); if (target == null) target = player; if (time >= 0f) Main.AllPlayerKillCooldown[player.PlayerId] = time * 2; @@ -602,7 +601,7 @@ public static Vent GetClosestVent(this PlayerControl player) var pos = player.GetCustomPosition(); return ShipStatus.Instance.AllVents.Where(x => x != null).MinBy(x => Vector2.Distance(pos, x.transform.position)); } - + public static List GetVentsFromClosest(this PlayerControl player) { Vector2 playerpos = player.transform.position; @@ -838,12 +837,6 @@ public static void RpcTeleport(this PlayerControl player, Vector2 position, bool netTransform.SetDirtyBit(uint.MaxValue); } - if (!AmongUsClient.Instance.AmHost && !netTransform.AmOwner) - { - Logger.Error($"Canceled RpcTeleport bcz I am not host and not the owner of {player.PlayerId}'s netTransform.", "RpcTeleport"); - return; - } - ushort newSid = (ushort)(netTransform.lastSequenceId + 8); MessageWriter messageWriter = AmongUsClient.Instance.StartRpcImmediately(netTransform.NetId, (byte)RpcCalls.SnapTo, SendOption.Reliable); NetHelpers.WriteVector2(position, messageWriter); @@ -965,7 +958,7 @@ public static string GetSubRoleName(this PlayerControl player, bool forUser = fa return sb.ToString(); } public static string GetAllRoleName(this PlayerControl player, bool forUser = true) - { + { if (!player) return null; var text = Utils.GetRoleName(player.GetCustomRole(), forUser); text += player.GetSubRoleName(forUser); @@ -1063,14 +1056,14 @@ public static bool HasKillButton(this PlayerControl pc) { if (pc == null) return false; if (!pc.IsAlive() || pc.Data.Role.Role == RoleTypes.GuardianAngel || Pelican.IsEaten(pc.PlayerId)) return false; - + var role = pc.GetCustomRole(); if (!role.IsImpostor()) { return role.GetDYRole() is RoleTypes.Impostor or RoleTypes.Shapeshifter; } return role.GetVNRole() switch - { + { CustomRoles.Impostor => true, CustomRoles.Shapeshifter => true, CustomRoles.Phantom => true, @@ -1166,7 +1159,7 @@ public static bool IsNonCrewSheriff(this PlayerControl sheriff) } public static bool ShouldBeDisplayed(this CustomRoles subRole) { - return subRole is not + return subRole is not CustomRoles.LastImpostor and not CustomRoles.Madmate and not CustomRoles.Charmed and not @@ -1202,7 +1195,7 @@ public static bool RpcCheckAndMurder(this PlayerControl killer, PlayerControl ta } public static bool CheckForInvalidMurdering(this PlayerControl killer, PlayerControl target, bool checkCanUseKillButton = false) => CheckMurderPatch.CheckForInvalidMurdering(killer, target, checkCanUseKillButton); public static void NoCheckStartMeeting(this PlayerControl reporter, NetworkedPlayerInfo target, bool force = false) - { + { //Method that can cause a meeting to occur regardless of whether it is in sabotage. //If target is null, it becomes a button. if (Options.DisableMeeting.GetBool() && !force) return; @@ -1265,108 +1258,99 @@ public static bool KnowLivingTeam(this PlayerControl seer, PlayerControl target) => (seer.Is(CustomRoles.Visionary)) && !target.Data.IsDead; - private readonly static LogHandler logger = Logger.Handler("KnowRoleTarget"); + public static bool KnowRoleTarget(PlayerControl seer, PlayerControl target) { + var seerState = Main.PlayerStates[seer.PlayerId]; + var targetState = Main.PlayerStates[target.PlayerId]; + + // Always allow visibility in specific cases if (Options.CurrentGameMode == CustomGameMode.FFA || GameEndCheckerForNormal.GameIsEnded) return true; - else if (seer.Is(CustomRoles.GM) || target.Is(CustomRoles.GM) || (PlayerControl.LocalPlayer.PlayerId == seer.PlayerId && Main.GodMode.Value)) return true; - else if (Options.SeeEjectedRolesInMeeting.GetBool() && Main.PlayerStates[target.PlayerId].deathReason == PlayerState.DeathReason.Vote) return true; - else if (Altruist.HasEnabled && seer.IsMurderedThisRound()) return false; - else if (seer.GetCustomRole() == target.GetCustomRole() && seer.GetCustomRole().IsNK()) return true; - else if (Options.LoverKnowRoles.GetBool() && seer.Is(CustomRoles.Lovers) && target.Is(CustomRoles.Lovers)) return true; - else if (Options.ImpsCanSeeEachOthersRoles.GetBool() && seer.Is(Custom_Team.Impostor) && target.Is(Custom_Team.Impostor)) return true; - else if (Madmate.MadmateKnowWhosImp.GetBool() && seer.Is(CustomRoles.Madmate) && target.Is(Custom_Team.Impostor)) return true; - else if (Madmate.ImpKnowWhosMadmate.GetBool() && target.Is(CustomRoles.Madmate) && seer.Is(Custom_Team.Impostor)) return true; - else if (seer.Is(Custom_Team.Impostor) && target.GetCustomRole().IsGhostRole() && target.GetCustomRole().IsImpostor()) return true; - else if (target.GetRoleClass().KnowRoleTarget(seer, target)) return true; - else if (seer.GetRoleClass().KnowRoleTarget(seer, target)) return true; - else if (Solsticer.OtherKnowSolsticer(target)) return true; - else if (Overseer.IsRevealedPlayer(seer, target) && !target.Is(CustomRoles.Trickster)) return true; - else if (Gravestone.EveryoneKnowRole(target)) return true; - else if (Mimic.CanSeeDeadRoles(seer, target)) return true; - else if (Workaholic.OthersKnowWorka(target)) return true; - else if (Jackal.JackalKnowRole(seer, target)) return true; - else if (Cultist.KnowRole(seer, target)) return true; - else if (Infectious.KnowRole(seer, target)) return true; - else if (Virus.KnowRole(seer, target)) return true; - else if (Main.VisibleTasksCount && !seer.IsAlive()) - { - if (Nemesis.PreventKnowRole(seer)) return false; - if (Retributionist.PreventKnowRole(seer)) return false; - - if (!Options.GhostCanSeeOtherRoles.GetBool()) - return false; - else if (Options.PreventSeeRolesImmediatelyAfterDeath.GetBool() && !Main.DeadPassedMeetingPlayers.Contains(seer.PlayerId)) - return false; - return true; - } + if (seer.Is(CustomRoles.GM) || target.Is(CustomRoles.GM) || (PlayerControl.LocalPlayer.PlayerId == seer.PlayerId && Main.GodMode.Value)) return true; + if (Options.SeeEjectedRolesInMeeting.GetBool() && targetState.deathReason == PlayerState.DeathReason.Vote) return true; + if (Altruist.HasEnabled && seer.IsMurderedThisRound()) return false; + if (Main.VisibleTasksCount && !seer.IsAlive() && Options.GhostCanSeeOtherRoles.GetBool()) return true; + + + // Other visibility logic + if (seer.GetCustomRole() == target.GetCustomRole() && seer.GetCustomRole().IsNK()) return true; + if (Options.LoverKnowRoles.GetBool() && seer.Is(CustomRoles.Lovers) && target.Is(CustomRoles.Lovers)) return true; + if (Options.ImpsCanSeeEachOthersRoles.GetBool() && seer.Is(Custom_Team.Impostor) && target.Is(Custom_Team.Impostor) && !Main.PlayerStates[seer.PlayerId].IsRandomizer && !Main.PlayerStates[target.PlayerId].IsRandomizer) return true; + if (Madmate.MadmateKnowWhosImp.GetBool() && seer.Is(CustomRoles.Madmate) && target.Is(Custom_Team.Impostor) && !Main.PlayerStates[seer.PlayerId].IsRandomizer && !Main.PlayerStates[target.PlayerId].IsRandomizer) return true; + if (Madmate.ImpKnowWhosMadmate.GetBool() && target.Is(CustomRoles.Madmate) && seer.Is(Custom_Team.Impostor) && !Main.PlayerStates[seer.PlayerId].IsRandomizer && !Main.PlayerStates[target.PlayerId].IsRandomizer) return true; + if (seer.Is(Custom_Team.Impostor) && target.GetCustomRole().IsGhostRole() && target.GetCustomRole().IsImpostor() && !Main.PlayerStates[seer.PlayerId].IsRandomizer && !Main.PlayerStates[target.PlayerId].IsRandomizer) return true; + if (target.GetRoleClass().KnowRoleTarget(seer, target) && !Main.PlayerStates[seer.PlayerId].IsRandomizer && !Main.PlayerStates[target.PlayerId].IsRandomizer) return true; + if (seer.GetRoleClass().KnowRoleTarget(seer, target) && !Main.PlayerStates[seer.PlayerId].IsRandomizer && !Main.PlayerStates[target.PlayerId].IsRandomizer) return true; + + // Visibility for other custom roles + if (Solsticer.OtherKnowSolsticer(target)) return true; + if (Overseer.IsRevealedPlayer(seer, target) && !target.Is(CustomRoles.Trickster)) return true; + if (Gravestone.EveryoneKnowRole(target)) return true; + if (Mimic.CanSeeDeadRoles(seer, target)) return true; + if (Workaholic.OthersKnowWorka(target)) return true; + if (Jackal.JackalKnowRole(seer, target)) return true; + if (Cultist.KnowRole(seer, target)) return true; + if (Summoner.KnowRole(seer, target)) return true; + if (Infectious.KnowRole(seer, target)) return true; + if (Virus.KnowRole(seer, target)) return true; - else return false; + return false; } + public static bool ShowSubRoleTarget(this PlayerControl seer, PlayerControl target, CustomRoles subRole = CustomRoles.NotAssigned) { if (seer == null) return false; if (target == null) target = seer; if (seer.PlayerId == target.PlayerId) return true; - else if (seer.Is(CustomRoles.GM) || target.Is(CustomRoles.GM) || seer.Is(CustomRoles.God) || (seer.IsHost() && Main.GodMode.Value)) return true; - else if (Options.ImpsCanSeeEachOthersAddOns.GetBool() && seer.Is(Custom_Team.Impostor) && target.Is(Custom_Team.Impostor) && !subRole.IsBetrayalAddon()) return true; - else if (Options.ApocCanSeeEachOthersAddOns.GetBool() && seer.IsNeutralApocalypse() && target.IsNeutralApocalypse() && !subRole.IsBetrayalAddon()) return true; - - else if ((subRole is CustomRoles.Madmate - or CustomRoles.Sidekick - or CustomRoles.Recruit - or CustomRoles.Admired - or CustomRoles.Charmed - or CustomRoles.Infected - or CustomRoles.Contagious - or CustomRoles.Egoist) - && KnowSubRoleTarget(seer, target)) - return true; - else if (Main.VisibleTasksCount && !seer.IsAlive()) - { - if (Nemesis.PreventKnowRole(seer)) return false; - if (Retributionist.PreventKnowRole(seer)) return false; - if (!Options.GhostCanSeeOtherRoles.GetBool()) - return false; - else if (Options.PreventSeeRolesImmediatelyAfterDeath.GetBool() && !Main.DeadPassedMeetingPlayers.Contains(seer.PlayerId)) - return false; + // Isolation for Randomizer + if (Main.PlayerStates[seer.PlayerId].IsRandomizer && target.Is(Custom_Team.Impostor)) return false; + if (seer.Is(Custom_Team.Impostor) && Main.PlayerStates[target.PlayerId].IsRandomizer) return false; + + // Visibility in general cases + if (seer.Is(CustomRoles.GM) || target.Is(CustomRoles.GM) || seer.Is(CustomRoles.God) || (seer.IsHost() && Main.GodMode.Value)) return true; + if (Main.VisibleTasksCount && !seer.IsAlive() && Options.GhostCanSeeOtherRoles.GetBool()) return true; + if (Options.ImpsCanSeeEachOthersAddOns.GetBool() && seer.Is(Custom_Team.Impostor) && target.Is(Custom_Team.Impostor) && !subRole.IsBetrayalAddon()) return true; + if (Options.ApocCanSeeEachOthersAddOns.GetBool() && seer.IsNeutralApocalypse() && target.IsNeutralApocalypse() && !subRole.IsBetrayalAddon()) return true; + + if ((subRole is CustomRoles.Madmate or CustomRoles.Sidekick or CustomRoles.Recruit or CustomRoles.Admired or CustomRoles.Charmed or CustomRoles.Infected or CustomRoles.Contagious or CustomRoles.Egoist or CustomRoles.Summoned) + && KnowSubRoleTarget(seer, target)) return true; - } return false; } + public static bool KnowSubRoleTarget(PlayerControl seer, PlayerControl target) { - //if (seer.GetRoleClass().KnowRoleTarget(seer, target)) return true; - if (seer.Is(Custom_Team.Impostor)) { // Imp know Madmate - if (target.Is(CustomRoles.Madmate) && Madmate.ImpKnowWhosMadmate.GetBool()) - return true; + if (target.Is(CustomRoles.Madmate) && Madmate.ImpKnowWhosMadmate.GetBool()) return true; + if (Main.PlayerStates[target.PlayerId].IsRandomizer) return false; // Ego-Imp know other Ego-Imp - else if (seer.Is(CustomRoles.Egoist) && target.Is(CustomRoles.Egoist) && Egoist.ImpEgoistVisibalToAllies.GetBool()) - return true; + if (seer.Is(CustomRoles.Egoist) && target.Is(CustomRoles.Egoist) && Egoist.ImpEgoistVisibalToAllies.GetBool()) return true; } - else if (Admirer.HasEnabled && Admirer.CheckKnowRoleTarget(seer, target)) return true; - else if (Cultist.HasEnabled && Cultist.KnowRole(seer, target)) return true; - else if (Infectious.HasEnabled && Infectious.KnowRole(seer, target)) return true; - else if (Virus.HasEnabled && Virus.KnowRole(seer, target)) return true; - else if (Jackal.HasEnabled) + if (Main.PlayerStates[seer.PlayerId].IsRandomizer) return false; + + if (Admirer.HasEnabled && Admirer.CheckKnowRoleTarget(seer, target)) return true; + if (Cultist.HasEnabled && Cultist.KnowRole(seer, target)) return true; + if (Summoner.HasEnabled && Summoner.KnowRole(seer, target)) return true; + if (Infectious.HasEnabled && Infectious.KnowRole(seer, target)) return true; + if (Virus.HasEnabled && Virus.KnowRole(seer, target)) return true; + if (Jackal.HasEnabled) { if (seer.Is(CustomRoles.Jackal) || seer.Is(CustomRoles.Recruit)) return target.Is(CustomRoles.Sidekick) || target.Is(CustomRoles.Recruit); - - else if (seer.Is(CustomRoles.Sidekick)) + if (seer.Is(CustomRoles.Sidekick)) return target.Is(CustomRoles.Recruit) || target.Is(CustomRoles.Sidekick); } return false; } + public static bool CanBeTeleported(this PlayerControl player) { if (player.Data == null // Check if PlayerData is not null @@ -1419,7 +1403,7 @@ public static string GetRoleInfo(this PlayerControl player, bool InfoLong = fals var Prefix = ""; if (!InfoLong && role == CustomRoles.Nemesis) Prefix = Nemesis.CheckCanUseKillButton() ? "After" : "Before"; - + var Info = (role.IsVanilla() ? "Blurb" : "Info"); return !InfoLong ? GetString($"{Prefix}{text}{Info}") : role.GetInfoLong(); } @@ -1476,7 +1460,9 @@ public static void SetDeathReason(this byte targetId, PlayerState.DeathReason re public static bool Is(this PlayerControl target, CustomRoles role) => role > CustomRoles.NotAssigned ? target.GetCustomSubRoles().Contains(role) : target.GetCustomRole() == role; + public static bool Is(this PlayerControl target, Custom_Team type) { return target.GetCustomRole().GetCustomRoleTeam() == type; } + public static bool Is(this PlayerControl target, RoleTypes type) { return target.GetCustomRole().GetRoleTypes() == type; } public static bool Is(this PlayerControl target, CountTypes type) { return target.GetCountTypes() == type; } public static bool IsAnySubRole(this PlayerControl target, Func predicate) => target != null && target.GetCustomSubRoles().Any() && target.GetCustomSubRoles().Any(predicate); @@ -1515,7 +1501,7 @@ public static bool IsDisconnected(this PlayerControl target) } public static bool IsExiled(this PlayerControl target) { - return GameStates.IsInGame || (target != null && (Main.PlayerStates[target.PlayerId].deathReason == PlayerState.DeathReason.Vote)); + return GameStates.InGame || (target != null && (Main.PlayerStates[target.PlayerId].deathReason == PlayerState.DeathReason.Vote)); } ///Is the player currently protected public static bool IsProtected(this PlayerControl self) => self.protectedByGuardianId > -1; diff --git a/Modules/GameState.cs b/Modules/GameState.cs index b1d732941..8be16313e 100644 --- a/Modules/GameState.cs +++ b/Modules/GameState.cs @@ -1,13 +1,13 @@ -using AmongUs.GameOptions; -using Hazel; using Il2CppInterop.Runtime.InteropTypes.Arrays; +using AmongUs.GameOptions; using System; -using TOHE.Roles.AddOns.Impostor; +using UnityEngine; using TOHE.Roles.Core; using TOHE.Roles.Impostor; using TOHE.Roles.Neutral; -using UnityEngine; +using TOHE.Roles.AddOns.Impostor; using static TOHE.Utils; +using Hazel; namespace TOHE; @@ -34,8 +34,6 @@ public class PlayerState(byte playerId) public void SetMainRole(CustomRoles role) { - CustomRoles preMainRole = MainRole; - MainRole = role; countTypes = role.GetCountTypes(); RoleClass = role.CreateRoleClass(); @@ -43,6 +41,23 @@ public void SetMainRole(CustomRoles role) var pc = PlayerId.GetPlayer(); if (pc == null) return; + if (role == CustomRoles.Opportunist) + { + if (AmongUsClient.Instance.AmHost) + { + if (!pc.HasImpKillButton(considerVanillaShift: true)) + { + var taskstate = pc.GetPlayerTaskState(); + if (taskstate != null) + { + pc.Data.RpcSetTasks(new Il2CppStructArray(0)); + taskstate.CompletedTasksCount = 0; + taskstate.AllTasksCount = pc.Data.Tasks.Count; + taskstate.hasTasks = true; + } + } + } + } // check for role addon if (pc.Is(CustomRoles.Madmate)) { @@ -54,6 +69,17 @@ public void SetMainRole(CustomRoles role) _ => throw new NotImplementedException() }; } + if (Main.PlayerStates[pc.PlayerId].IsRandomizer) + { + countTypes = Main.PlayerStates[pc.PlayerId].LockedTeam switch + { + Custom_Team.Crewmate => CountTypes.None, + Custom_Team.Impostor => CountTypes.None, + Custom_Team.Neutral => CountTypes.None, + _ => CountTypes.None // Default fallback if team is unknown + }; + } + if (pc.Is(CustomRoles.Charmed)) { countTypes = Cultist.CharmedCountMode.GetInt() switch @@ -96,36 +122,120 @@ public void SetMainRole(CustomRoles role) { countTypes = CountTypes.OutOfGame; } + // check for role addon + + +} + public bool IsSummoner { get; set; } = false; + public bool IsSummoned { get; set; } = false; + public CustomWinner LingeringPresenceAssignedTeam { get; set; } = CustomWinner.None; - if (GameStates.IsInGame && preMainRole != CustomRoles.NotAssigned) + public void ResetSubRoles() + { + foreach (var subRole in SubRoles.ToArray()) // Use ToArray() to avoid modification during iteration { - // Role got assigned mid game. - // Since role basis may change, we need to re assign tasks? + RemoveSubRole(subRole); // Ensure this method exists and removes a subrole correctly + } + SubRoles.Clear(); // Clear the SubRoles list after removal + } - //Some role may be bugged for this, need further testing. - Logger.Info($"{pc.GetNameWithRole()} previously was {GetRoleName(preMainRole)}, reassign tasks!", "PlayerState.SetMainRole"); - pc.Data.RpcSetTasks(new Il2CppStructArray(0)); - InitTask(pc); + public bool IsRandomizer { get; set; } = false; // Flag indicating if the player is a Randomizer + public Custom_Team LockedTeam { get; set; } - if (pc.GetRoleClass() != null && pc.GetRoleClass().ThisRoleBase == CustomRoles.Shapeshifter && Utils.IsMethodOverridden(pc.GetRoleClass(), "UnShapeShiftButton")) + + + + // Team flags for Randomizer + private bool isCrewmateTeam; + private bool isNeutralTeam; + private bool isImpostorTeam; + + public bool TeamLockApplied { get; set; } = false; // Flag to lock the team once set + + public Custom_RoleType? LockedRoleType { get; set; } // Role type enforced after lock + public Custom_Team RandomizerWinCondition { get; set; } = Custom_Team.Neutral; + + public bool IsCrewmateTeam + { + get => IsRandomizer && isCrewmateTeam; + set + { + if (IsRandomizer && !TeamLockApplied) { - Main.UnShapeShifter.Add(pc.PlayerId); - Logger.Info($"Added {pc.GetNameWithRole()} to UnShapeShifter list mid game", "PlayerState.SetMainRole"); + isCrewmateTeam = value; + isNeutralTeam = false; // Reset others + isImpostorTeam = false; + TeamLockApplied = true; // Lock the team + LockedTeam = Custom_Team.Crewmate; // Lock to Crewmate team + LockedRoleType = Custom_RoleType.CrewmateBasic; // Enforce role type + RandomizerWinCondition = Custom_Team.Crewmate; // Set win condition } } } - public void SetSubRole(CustomRoles role, PlayerControl pc = null) + + public bool IsNeutralTeam { - if (role == CustomRoles.Cleansed) + get => IsRandomizer && isNeutralTeam; + set { - if (pc != null) countTypes = pc.GetCustomRole().GetCountTypes(); + if (IsRandomizer && !TeamLockApplied) + { + isNeutralTeam = value; + isCrewmateTeam = false; // Reset others + isImpostorTeam = false; + TeamLockApplied = true; // Lock the team + LockedTeam = Custom_Team.Neutral; // Lock to Neutral team + LockedRoleType = Custom_RoleType.NeutralChaos; // Enforce role type + RandomizerWinCondition = Custom_Team.Neutral; // Set win condition + } + } + } - // Remove lovers on Cleansed - if (pc.Is(CustomRoles.Lovers)) + public bool IsImpostorTeam + { + get => IsRandomizer && isImpostorTeam; + set + { + if (IsRandomizer && !TeamLockApplied) { - var lover = Main.PlayerStates.Values.FirstOrDefault(x => x.PlayerId != pc.PlayerId && x.SubRoles.Contains(CustomRoles.Lovers)); - lover?.RemoveSubRole(CustomRoles.Lovers); + isImpostorTeam = value; + isCrewmateTeam = false; // Reset others + isNeutralTeam = false; + TeamLockApplied = true; // Lock the team + LockedTeam = Custom_Team.Impostor; // Lock to Impostor team + LockedRoleType = Custom_RoleType.ImpostorVanilla; // Enforce role type + RandomizerWinCondition = Custom_Team.Impostor; // Set win condition } + } + } + + + /// + /// Resets team lock and related properties. Should be used cautiously. + /// + + + /// + /// Gets the effective role type for the player based on the Randomizer logic. + /// + /// The enforced role type if the player is Randomizer; otherwise, the default. + /// + public CustomRoles GetCustomRole() + { + return (CustomRoles)(Main.PlayerStates[this.PlayerId]?.MainRole); + } + + + + + + + + public void SetSubRole(CustomRoles role, PlayerControl pc = null) + { + if (role == CustomRoles.Cleansed) + { + if (pc != null) countTypes = pc.GetCustomRole().GetCountTypes(); foreach (var subRole in SubRoles.ToArray()) { @@ -263,10 +373,12 @@ public void SetDead() } public bool IsSuicide => deathReason == DeathReason.Suicide; public TaskState TaskState => taskState; + + public bool IsLingeringPresence { get; internal set; } + public void InitTask(PlayerControl player) => taskState.Init(player); public void UpdateTask(PlayerControl player) => taskState.Update(player); - [Obfuscation(Exclude = true)] public enum DeathReason { Kill, @@ -285,6 +397,9 @@ public enum DeathReason Revenge, Execution, Fall, + FadedAway, + SummonedExpired, + AllergicReaction, // TOHE Gambled, @@ -296,7 +411,6 @@ public enum DeathReason PissedOff, Dismembered, LossOfHead, - Consumed, Trialed, Infected, Jinx, @@ -316,8 +430,6 @@ public enum DeathReason Starved, Armageddon, Sacrificed, - Electrocuted, - Scavenged, //Please add all new roles with deathreason & new deathreason in Utils.DeathReasonIsEnable(); etc = -1, @@ -405,6 +517,7 @@ public void Update(PlayerControl player) //Solsticer task state is updated by host rpc if (player.Is(CustomRoles.Solsticer) && !AmongUsClient.Instance.AmHost) return; + if (player.Is(CustomRoles.LingeringPresence) && !AmongUsClient.Instance.AmHost) return; CompletedTasksCount++; @@ -454,7 +567,8 @@ public static bool IsVanillaServer { get { - if (IsLocalGame && !IsNotJoined) return true; + if (!IsOnlineGame) return false; + const string Domain = "among.us"; // From Reactor.gg diff --git a/Modules/GuessManager.cs b/Modules/GuessManager.cs index a41a29095..119ae87fc 100644 --- a/Modules/GuessManager.cs +++ b/Modules/GuessManager.cs @@ -1,4 +1,4 @@ -using Hazel; +using Hazel; using System; using System.Text.RegularExpressions; using TMPro; @@ -195,8 +195,7 @@ public static bool GuesserMsg(PlayerControl pc, string msg, bool isUI = false) if (pc.GetRoleClass().GuessCheck(isUI, pc, target, role, ref guesserSuicide)) return true; if (target.GetRoleClass().OnRoleGuess(isUI, target, pc, role, ref guesserSuicide)) return true; - // Used to be a exploit. Guess may be canceled even misguessed - // You need to manually check whether guessed correct and then perform role abilities + if (CopyCat.playerIdList.Contains(pc.PlayerId)) { @@ -252,7 +251,7 @@ public static bool GuesserMsg(PlayerControl pc, string msg, bool isUI = false) return true; } - if (role.IsTNA() && role != CustomRoles.Pestilence && !Options.TransformedNeutralApocalypseCanBeGuessed.GetBool() || role == CustomRoles.Pestilence && !PlagueBearer.PestilenceKillsGuessers.GetBool()) + if (role.IsTNA() && role != CustomRoles.Pestilence && !Options.TransformedNeutralApocalypseCanBeGuessed.GetBool()) { pc.ShowInfoMessage(isUI, GetString("GuessImmune")); return true; @@ -970,6 +969,7 @@ void ClickEvent() if (role is CustomRoles.GM or CustomRoles.SpeedBooster or CustomRoles.Oblivious + or CustomRoles.ChiefOfPolice or CustomRoles.Flash or CustomRoles.NotAssigned or CustomRoles.SuperStar @@ -986,13 +986,14 @@ or CustomRoles.Sloth or CustomRoles.Apocalypse || (role.IsTNA() && !Options.TransformedNeutralApocalypseCanBeGuessed.GetBool())) continue; - if (role is CustomRoles.NiceMini && Mini.Age < 18) continue; - if (role is CustomRoles.EvilMini && Mini.Age < 18 && !Mini.CanGuessEvil.GetBool()) continue; - CreateRole(role); } void CreateRole(CustomRoles role) { + var tempMini = Mini.IsEvilMini; + if (role is CustomRoles.EvilMini) Mini.IsEvilMini = true; + else if (role is CustomRoles.NiceMini) Mini.IsEvilMini = false; + if (40 <= info[(int)role.GetCustomRoleTeam()]) info[(int)role.GetCustomRoleTeam()] = 0; Transform buttonParent = new GameObject().transform; buttonParent.SetParent(container); @@ -1017,6 +1018,8 @@ void CreateRole(CustomRoles role) label.transform.localPosition = new Vector3(0, 0, label.transform.localPosition.z); label.transform.localScale *= 1.6f; label.autoSizeTextContainer = true; + + //int copiedIndex = info[(int)role.GetCustomRoleTeam()]; button.GetComponent().OnClick.RemoveAllListeners(); @@ -1049,6 +1052,8 @@ void CreateRole(CustomRoles role) })); info[(int)role.GetCustomRoleTeam()]++; ind++; + + Mini.IsEvilMini = tempMini; } container.transform.localScale *= 0.75f; GuesserSelectRole(Custom_Team.Crewmate); @@ -1062,7 +1067,11 @@ void CreateRole(CustomRoles role) PlayerControl.LocalPlayer.RPCPlayCustomSound("Gunload"); - } + } + + + + [HarmonyPatch(typeof(MeetingHud), nameof(MeetingHud.OnDestroy))] class MeetingHudOnDestroyGuesserUIClose diff --git a/Modules/HazelExtensions.cs b/Modules/HazelExtensions.cs index f1caaa3bb..114ce6739 100644 --- a/Modules/HazelExtensions.cs +++ b/Modules/HazelExtensions.cs @@ -46,4 +46,4 @@ public static Color ReadColor(this MessageReader reader) return new(r, g, b, a); } } -} +} \ No newline at end of file diff --git a/Modules/LateTask.cs b/Modules/LateTask.cs index 75ee8bca8..67b88a5ff 100644 --- a/Modules/LateTask.cs +++ b/Modules/LateTask.cs @@ -25,11 +25,10 @@ public LateTask(Action action, float time, string name = "No Name Task", bool sh this.timer = time; this.name = name; this.shouldLog = shoudLog; - Tasks.Add(this); if (name != "") if (shoudLog) - Logger.Info("\"" + name + "\" is created", "LateTask"); + Logger.Info("\"" + name + "\" is created", "LateTask"); } public static void Update(float deltaTime) { @@ -54,4 +53,4 @@ public static void Update(float deltaTime) } TasksToRemove.ForEach(task => Tasks.Remove(task)); } -} +} \ No newline at end of file diff --git a/Modules/LocateArrow.cs b/Modules/LocateArrow.cs index a4ef79e82..84418fcff 100644 --- a/Modules/LocateArrow.cs +++ b/Modules/LocateArrow.cs @@ -1,6 +1,6 @@ using Hazel; -using TOHE.Modules; using UnityEngine; +using TOHE.Modules; namespace TOHE; diff --git a/Modules/MeetingTimeManager.cs b/Modules/MeetingTimeManager.cs index 07fcd3654..be865d17f 100644 --- a/Modules/MeetingTimeManager.cs +++ b/Modules/MeetingTimeManager.cs @@ -62,7 +62,7 @@ public static void OnReportDeadBody() BonusMeetingTime += SoulCollector.DeathMeetingTimeIncrease.GetInt(); } int TotalMeetingTime = DiscussionTime + VotingTime; - + if (TimeManager.HasEnabled) BonusMeetingTime = Math.Clamp(TotalMeetingTime + BonusMeetingTime, MeetingTimeMinTimeManager, MeetingTimeMax) - TotalMeetingTime; if (TimeThief.HasEnabled) BonusMeetingTime = Math.Clamp(TotalMeetingTime + BonusMeetingTime, MeetingTimeMinTimeThief, MeetingTimeMax) - TotalMeetingTime; if (!TimeManager.HasEnabled && !TimeThief.HasEnabled) BonusMeetingTime = Math.Clamp(TotalMeetingTime + BonusMeetingTime, MeetingTimeMinTimeThief, MeetingTimeMax) - TotalMeetingTime; diff --git a/Modules/ModUpdater.cs b/Modules/ModUpdater.cs index 3fb07edf2..7b9e724f6 100644 --- a/Modules/ModUpdater.cs +++ b/Modules/ModUpdater.cs @@ -1,15 +1,13 @@ -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; using System; using System.IO; using System.Net.Http; +using System.Reflection; using UnityEngine; -using UnityEngine.Networking; using static TOHE.Translator; +using UnityEngine.Networking; using IEnumerator = System.Collections.IEnumerator; -using TOHE.Modules; -using System.Threading.Tasks; -using System.Threading; +using Newtonsoft.Json.Linq; +using Newtonsoft.Json; namespace TOHE; @@ -31,7 +29,6 @@ public class ModUpdater public static string notice = null; public static GenericPopup InfoPopup; public static PassiveButton updateButton; - private static CancellationTokenSource downloadCancellationTokenSource = new(); [HarmonyPatch(typeof(MainMenuManager), nameof(MainMenuManager.Start)), HarmonyPostfix, HarmonyPriority(Priority.VeryLow)] public static void Start_Postfix(/*MainMenuManager __instance*/) @@ -174,7 +171,7 @@ public static IEnumerator CheckReleaseFromGithub(bool beta = false) public static void StartUpdate(string url) { ShowPopup(GetString("updatePleaseWait"), StringNames.Cancel, false); - Task.Run(() => DownloadDLLAsync(url)); + Main.Instance.StartCoroutine(DownloadDLL(url)); return; } public static bool NewVersionCheck() @@ -198,21 +195,18 @@ public static bool NewVersionCheck() } public static void StopDownload() { - lock (downloadLock) - { - downloadCancellationTokenSource?.Cancel(); - - cachedfileStream?.Dispose(); - cachedfileStream = null; - } + cachedfileStream.Dispose(); + Main.Instance.StopAllCoroutines(); + Main.Instance.StartCoroutine(DeleteFilesAfterCancel()); } public static IEnumerator DeleteFilesAfterCancel() { - ShowPopupAsync(GetString("deletingFiles"), StringNames.None, false); + ShowPopup(GetString("deletingFiles"), StringNames.None, false); yield return new WaitForSeconds(2f); InfoPopup.Close(); yield return new WaitForSeconds(0.3f); DeleteOldFiles(); + Application.targetFrameRate = Main.UnlockFPS.Value ? 165 : 60; yield break; } public static void DeleteOldFiles() @@ -239,92 +233,64 @@ public static void DeleteOldFiles() private static readonly object downloadLock = new(); private static FileStream cachedfileStream; - private static async Task DownloadDLLAsync(string url) + private static IEnumerator DownloadDLL(string url) { var savePath = "BepInEx/plugins/TOHE.dll.temp"; + Application.targetFrameRate = -1; // Delete the temporary file if it exists DeleteOldFiles(); - try + UnityWebRequest request = UnityWebRequest.Get(url); + request.timeout = 10; + request.SetRequestHeader("Connection", "Keep-Alive"); + request.SetRequestHeader("User-Agent", "Mozilla/5.0"); + request.chunkedTransfer = false; + yield return request.SendWebRequest(); + + if (request.result != UnityWebRequest.Result.Success) { - downloadCancellationTokenSource = new CancellationTokenSource(); - CancellationToken token = downloadCancellationTokenSource.Token; + Logger.Error($"File retrieval failed with status code: {request.responseCode}", "DownloadDLL", false); + ShowPopup(GetString("updateManually"), StringNames.Close, true, InfoPopup.Close); + Application.targetFrameRate = Main.UnlockFPS.Value ? 165 : 60; + yield break; + } - using (HttpClient client = new()) + var total = request.downloadedBytes; + using (var stream = new MemoryStream(request.downloadHandler.data)) + { + using (var fileStream = new FileStream(savePath, FileMode.Create, FileAccess.Write, FileShare.None, bufferSize: 4096, useAsync: true)) { - client.Timeout = TimeSpan.FromSeconds(10); - client.DefaultRequestHeaders.Connection.Add("Keep-Alive"); - client.DefaultRequestHeaders.UserAgent.ParseAdd("Mozilla/5.0"); - - using HttpResponseMessage response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead, token); - - if (!response.IsSuccessStatusCode) - { - Logger.Error($"File retrieval failed with status code: {response.StatusCode}", "DownloadDLL", false); - ShowPopupAsync(GetString("updateManually"), StringNames.Close, true, InfoPopup.Close); - return; - } - - var total = response.Content.Headers.ContentLength ?? -1L; - using var stream = await response.Content.ReadAsStreamAsync(token); - using var fileStream = new FileStream(savePath, FileMode.Create, FileAccess.Write, FileShare.None, bufferSize: 4096, useAsync: true); - cachedfileStream = fileStream; byte[] buffer = new byte[1024]; long readLength = 0; int length; - while ((length = await stream.ReadAsync(buffer, token)) > 0) + while ((length = stream.Read(buffer, 0, buffer.Length)) > 0) { - await fileStream.WriteAsync(buffer.AsMemory(0, length), token); + yield return null; + + fileStream.Write(buffer, 0, length); readLength += length; - double progress = total > 0 ? Math.Round((double)readLength / total * 100, 2, MidpointRounding.ToZero) : 0; + double? progress = Math.Round((double)readLength / total * 100, 2, MidpointRounding.ToZero); lock (downloadLock) { - DownloadCallBack(total, readLength, progress); + DownloadCallBack(total, readLength, progress ?? 0); // Call back with progress info } } - - await fileStream.DisposeAsync(); } - - var fileName = Assembly.GetExecutingAssembly().Location; - File.Move(fileName, fileName + ".bak"); - File.Move(savePath, fileName); - ShowPopupAsync(GetString("updateRestart"), StringNames.Close, true, Application.Quit); - } - catch (OperationCanceledException) - { - Logger.Warn("Download operation was canceled.", "DownloadDLL"); - Main.Instance.StartCoroutine(DeleteFilesAfterCancel()); } - catch (Exception ex) - { - Logger.Error($"An error occurred during the download: {ex.Message}", "DownloadDLL", false); - ShowPopupAsync(GetString("updateManually"), StringNames.Close, true, InfoPopup.Close); - } - finally - { - cachedfileStream?.Dispose(); - cachedfileStream = null; - downloadCancellationTokenSource?.Dispose(); - downloadCancellationTokenSource = null; - } + var fileName = Assembly.GetExecutingAssembly().Location; + File.Move(fileName, fileName + ".bak"); + File.Move(savePath, fileName); + ShowPopup(GetString("updateRestart"), StringNames.Close, true, Application.Quit); } - private static void DownloadCallBack(long total, long downloaded, double progress) + private static void DownloadCallBack(ulong total, long downloaded, double progress) { - ShowPopupAsync($"{GetString("updateInProgress")}\n{downloaded / (1024f * 1024f):F2}/{total / (1024f * 1024f):F2} MB ({progress}%)", StringNames.Cancel, true, StopDownload); - } - private static void ShowPopupAsync(string message, StringNames buttonText, bool showButton = false, Action onClick = null) - { - Dispatcher.Dispatch(() => - { - ShowPopup(message, buttonText, showButton, onClick); - }); + ShowPopup($"{GetString("updateInProgress")}\n{downloaded / (1024f * 1024f):F2}/{total / (1024f * 1024f):F2} MB ({progress}%)", StringNames.Cancel, true, StopDownload); } private static void ShowPopup(string message, StringNames buttonText, bool showButton = false, Action onClick = null) { diff --git a/Modules/NameColorManager.cs b/Modules/NameColorManager.cs index e64832c5e..d6e8ef6eb 100644 --- a/Modules/NameColorManager.cs +++ b/Modules/NameColorManager.cs @@ -12,23 +12,56 @@ public static class NameColorManager { public static string ApplyNameColorData(this string name, PlayerControl seer, PlayerControl target, bool isMeeting) { - if (!AmongUsClient.Instance.IsGameStarted) return name; + // Ensure game is started + if (AmongUsClient.Instance == null || !AmongUsClient.Instance.IsGameStarted) + { + return name; // Return unformatted name + } - if (!TryGetData(seer, target, out var colorCode)) + // Ensure seer and target are valid + if (seer == null || target == null) { - if (KnowTargetRoleColor(seer, target, isMeeting, out var color)) - colorCode = color == "" ? target.GetRoleColorCode() : color; + return name; // Return unformatted name } - string openTag = "", closeTag = ""; - if (colorCode != "") + + + + string colorCode = ""; + + // Try to get color from data or role + if (!TryGetData(seer, target, out colorCode)) { - if (!colorCode.StartsWith('#')) - colorCode = "#" + colorCode; - openTag = $""; - closeTag = ""; + // Check if the seer or target is a Randomizer + + if (Main.PlayerStates[seer.PlayerId].IsRandomizer || Main.PlayerStates[target.PlayerId].IsRandomizer) + { + // Assign default color (e.g., white for Randomizer) + colorCode = "#FFFFFF"; // White color code + } + else if (KnowTargetRoleColor(seer, target, isMeeting, out var color)) + { + colorCode = string.IsNullOrEmpty(color) ? target.GetRoleColorCode() : color; + } } + + // Fallback if colorCode is still null or empty + if (string.IsNullOrEmpty(colorCode)) + { + return name; // No color code available, return unformatted name + } + + + // Ensure the color code starts with "#" + if (!colorCode.StartsWith("#")) + { + colorCode = "#" + colorCode; + } + + string openTag = $""; + string closeTag = ""; return openTag + name + closeTag; } + private static bool KnowTargetRoleColor(PlayerControl seer, PlayerControl target, bool isMeeting, out string color) { if (Altruist.HasEnabled && seer.IsMurderedThisRound()) @@ -38,89 +71,88 @@ private static bool KnowTargetRoleColor(PlayerControl seer, PlayerControl target } if (seer != target) - target = DollMaster.SwapPlayerInfo(target); // If a player is possessed by the Dollmaster swap each other's controllers. - - color = seer.GetRoleClass()?.PlayerKnowTargetColor(seer, target); // returns "" unless overriden - - // Impostor & Madmate - if (seer.Is(Custom_Team.Impostor) && target.Is(Custom_Team.Impostor)) color = (seer.Is(CustomRoles.Egoist) && target.Is(CustomRoles.Egoist) && Egoist.ImpEgoistVisibalToAllies.GetBool() && seer != target) ? Main.roleColors[CustomRoles.Egoist] : Main.roleColors[CustomRoles.Impostor]; - if (seer.Is(CustomRoles.Madmate) && target.Is(Custom_Team.Impostor) && Madmate.MadmateKnowWhosImp.GetBool()) color = Main.roleColors[CustomRoles.Impostor]; - if (seer.Is(Custom_Team.Impostor) && target.Is(CustomRoles.Madmate) && Madmate.ImpKnowWhosMadmate.GetBool()) color = Main.roleColors[CustomRoles.Madmate]; - if (seer.Is(Custom_Team.Impostor) && target.GetCustomRole().IsGhostRole() && target.GetCustomRole().IsImpostor()) color = Main.roleColors[CustomRoles.Madmate]; - if (seer.Is(CustomRoles.Madmate) && target.Is(CustomRoles.Madmate) && Madmate.MadmateKnowWhosMadmate.GetBool()) color = Main.roleColors[CustomRoles.Madmate]; + target = DollMaster.SwapPlayerInfo(target); // If a player is possessed by the Dollmaster, swap controllers. - // Cultist - if (Cultist.NameRoleColor(seer, target)) color = Main.roleColors[CustomRoles.Cultist]; + // Default color assignment logic + color = seer.GetRoleClass()?.PlayerKnowTargetColor(seer, target); // Returns "" unless overridden. - // Admirer - if (seer.Is(CustomRoles.Admirer) && target.Is(CustomRoles.Admired)) color = Main.roleColors[CustomRoles.Admirer]; - if (seer.Is(CustomRoles.Admired) && target.Is(CustomRoles.Admirer)) color = Main.roleColors[CustomRoles.Admirer]; - - // Bounties - if (seer.Is(CustomRoles.BountyHunter) && BountyHunter.GetTarget(seer) == target.PlayerId) color = "bf1313"; - - // Amnesiac - if (seer.GetCustomRole() == target.GetCustomRole() && seer.GetCustomRole().IsNK()) color = Main.roleColors[seer.GetCustomRole()]; - - if (seer.Is(CustomRoles.Refugee) && (target.Is(Custom_Team.Impostor))) color = Main.roleColors[CustomRoles.ImpostorTOHE]; - if (seer.Is(Custom_Team.Impostor) && (target.Is(CustomRoles.Refugee))) color = Main.roleColors[CustomRoles.Refugee]; - - // Infectious - if (Infectious.InfectedKnowColorOthersInfected(seer, target)) color = Main.roleColors[CustomRoles.Infectious]; - - // Cyber - if (!seer.Is(CustomRoles.Visionary) && target.Is(CustomRoles.Cyber) && Cyber.CyberKnown.GetBool()) color = Main.roleColors[CustomRoles.Cyber]; - - // Necroview - if (seer.Is(CustomRoles.Necroview) && seer.IsAlive()) + // Randomizer team color logic + if (seer.Is(CustomRoles.Randomizer) || target.Is(CustomRoles.Randomizer)) { - if (target.Data.IsDead && !target.IsAlive()) - { - color = Necroview.NameColorOptions(target); - } + color = Main.roleColors[CustomRoles.Randomizer]; + return true; // Skip further checks and directly apply Randomizer color } - // Jackal recruit - if (Jackal.JackalKnowRole(seer, target)) color = Main.roleColors[CustomRoles.Jackal]; - if (target.Is(CustomRoles.Mare) && Utils.IsActive(SystemTypes.Electrical) && !isMeeting) color = Main.roleColors[CustomRoles.Mare]; + // Impostor & Madmate logic + if (seer.Is(Custom_Team.Impostor) && target.Is(Custom_Team.Impostor) && !Main.PlayerStates[seer.PlayerId].IsRandomizer && !Main.PlayerStates[target.PlayerId].IsRandomizer) + color = (seer.Is(CustomRoles.Egoist) && target.Is(CustomRoles.Egoist) && Egoist.ImpEgoistVisibalToAllies.GetBool() && seer != target) + ? Main.roleColors[CustomRoles.Egoist] + : Main.roleColors[CustomRoles.Impostor]; + if (seer.Is(CustomRoles.Madmate) && target.Is(Custom_Team.Impostor) && Madmate.MadmateKnowWhosImp.GetBool() && !Main.PlayerStates[seer.PlayerId].IsRandomizer && !Main.PlayerStates[target.PlayerId].IsRandomizer) + color = Main.roleColors[CustomRoles.Impostor]; + if (seer.Is(Custom_Team.Impostor) && target.Is(CustomRoles.Madmate) && Madmate.ImpKnowWhosMadmate.GetBool() && !Main.PlayerStates[seer.PlayerId].IsRandomizer && !Main.PlayerStates[target.PlayerId].IsRandomizer) + color = Main.roleColors[CustomRoles.Madmate]; + if (seer.Is(Custom_Team.Impostor) && target.GetCustomRole().IsGhostRole() && target.GetCustomRole().IsImpostor() && !Main.PlayerStates[seer.PlayerId].IsRandomizer && !Main.PlayerStates[target.PlayerId].IsRandomizer) + color = Main.roleColors[CustomRoles.Impostor]; + if (seer.Is(CustomRoles.Madmate) && target.Is(CustomRoles.Madmate) && Madmate.MadmateKnowWhosMadmate.GetBool() && !Main.PlayerStates[seer.PlayerId].IsRandomizer && !Main.PlayerStates[target.PlayerId].IsRandomizer) + color = Main.roleColors[CustomRoles.Madmate]; + + // Cultist logic + if (Cultist.NameRoleColor(seer, target)) + color = Main.roleColors[CustomRoles.Cultist]; - //Virus - if (Virus.KnowRoleColor(seer, target) != "") color = Virus.KnowRoleColor(seer, target); - if (color != "" && color != string.Empty) return true; - else return seer == target + // Admirer logic + if (seer.Is(CustomRoles.Admirer) && !Main.PlayerStates[seer.PlayerId].IsRandomizer && target.Is(CustomRoles.Admired)) color = Main.roleColors[CustomRoles.Admirer]; + if (seer.Is(CustomRoles.Admired) && target.Is(CustomRoles.Admirer) && !Main.PlayerStates[target.PlayerId].IsRandomizer) color = Main.roleColors[CustomRoles.Admirer]; + + // Bounties + if (seer.Is(CustomRoles.BountyHunter) && BountyHunter.GetTarget(seer) == target.PlayerId) + color = "bf1313"; + + // Amnesiac and Neutral Killer logic + if (seer.GetCustomRole() == target.GetCustomRole() && seer.GetCustomRole().IsNK()) + color = Main.roleColors[seer.GetCustomRole()]; + + // Refugee + if (seer.Is(CustomRoles.Refugee) && (target.Is(Custom_Team.Impostor)) && !Main.PlayerStates[seer.PlayerId].IsRandomizer && !Main.PlayerStates[target.PlayerId].IsRandomizer) color = Main.roleColors[CustomRoles.ImpostorTOHE]; + if (seer.Is(Custom_Team.Impostor) && (target.Is(CustomRoles.Refugee)) && !Main.PlayerStates[seer.PlayerId].IsRandomizer && !Main.PlayerStates[target.PlayerId].IsRandomizer) color = Main.roleColors[CustomRoles.Refugee]; + + // Other roles + if (Infectious.InfectedKnowColorOthersInfected(seer, target)) + color = Main.roleColors[CustomRoles.Infectious]; + if (!seer.Is(CustomRoles.Visionary) && target.Is(CustomRoles.Cyber) && Cyber.CyberKnown.GetBool()) + color = Main.roleColors[CustomRoles.Cyber]; + if (seer.Is(CustomRoles.Necroview) && seer.IsAlive() && target.Data.IsDead && !target.IsAlive()) + color = Necroview.NameColorOptions(target); + if (Jackal.JackalKnowRole(seer, target)) + color = Main.roleColors[CustomRoles.Jackal]; + if (target.Is(CustomRoles.Mare) && Utils.IsActive(SystemTypes.Electrical) && !isMeeting) + color = Main.roleColors[CustomRoles.Mare]; + if (Virus.KnowRoleColor(seer, target) != "") + color = Virus.KnowRoleColor(seer, target); + + // Default visibility checks + return color != "" && color != string.Empty + || seer == target || (Main.GodMode.Value && seer.IsHost()) - || (Options.CurrentGameMode == CustomGameMode.FFA) + || Options.CurrentGameMode == CustomGameMode.FFA || seer.Is(CustomRoles.GM) || target.Is(CustomRoles.GM) + || (Main.VisibleTasksCount && Main.PlayerStates[seer.Data.PlayerId].IsDead && seer.Data.IsDead && !seer.IsAlive() && Options.GhostCanSeeOtherRoles.GetBool()) || target.GetRoleClass().OthersKnowTargetRoleColor(seer, target) || Mimic.CanSeeDeadRoles(seer, target) - || (seer.Is(Custom_Team.Impostor) && target.Is(Custom_Team.Impostor)) - || (seer.Is(CustomRoles.Madmate) && target.Is(Custom_Team.Impostor) && Madmate.MadmateKnowWhosImp.GetBool()) - || (seer.Is(Custom_Team.Impostor) && target.Is(CustomRoles.Madmate) && Madmate.ImpKnowWhosMadmate.GetBool()) - || (seer.Is(CustomRoles.Madmate) && target.Is(CustomRoles.Madmate) && Madmate.MadmateKnowWhosMadmate.GetBool()) + || (seer.Is(Custom_Team.Impostor) && target.Is(Custom_Team.Impostor) && !Main.PlayerStates[seer.PlayerId].IsRandomizer && !Main.PlayerStates[target.PlayerId].IsRandomizer) + || (seer.Is(CustomRoles.Madmate) && target.Is(Custom_Team.Impostor) && Madmate.MadmateKnowWhosImp.GetBool() && !Main.PlayerStates[seer.PlayerId].IsRandomizer && !Main.PlayerStates[target.PlayerId].IsRandomizer) + || (seer.Is(Custom_Team.Impostor) && target.Is(CustomRoles.Madmate) && Madmate.ImpKnowWhosMadmate.GetBool() && !Main.PlayerStates[seer.PlayerId].IsRandomizer && !Main.PlayerStates[target.PlayerId].IsRandomizer) + || (seer.Is(CustomRoles.Madmate) && target.Is(CustomRoles.Madmate) && Madmate.MadmateKnowWhosMadmate.GetBool() && !Main.PlayerStates[seer.PlayerId].IsRandomizer && !Main.PlayerStates[target.PlayerId].IsRandomizer) || Workaholic.OthersKnowWorka(target) || (target.Is(CustomRoles.Gravestone) && Main.PlayerStates[target.Data.PlayerId].IsDead) - || Mare.KnowTargetRoleColor(target, isMeeting) - || DeadKnowRole(seer, target); - - static bool DeadKnowRole(PlayerControl seer, PlayerControl target) - { - if (Main.VisibleTasksCount && !seer.IsAlive()) - { - if (Nemesis.PreventKnowRole(seer)) return false; - if (Retributionist.PreventKnowRole(seer)) return false; - - if (!Options.GhostCanSeeOtherRoles.GetBool()) - return false; - else if (Options.PreventSeeRolesImmediatelyAfterDeath.GetBool() && !Main.DeadPassedMeetingPlayers.Contains(seer.PlayerId)) - return false; - return true; - } - return false; - } + || Mare.KnowTargetRoleColor(target, isMeeting); } + + public static bool TryGetData(PlayerControl seer, PlayerControl target, out string colorCode) { colorCode = ""; diff --git a/Modules/NameNotifyManager.cs b/Modules/NameNotifyManager.cs index 322dfdeea..993a290df 100644 --- a/Modules/NameNotifyManager.cs +++ b/Modules/NameNotifyManager.cs @@ -14,13 +14,13 @@ public static void Notify(this PlayerControl pc, string text, float time = 5f, b if (!GameStates.IsInTask) return; if (!text.Contains("")) text = Utils.ColorString(Color.white, text); if (!text.Contains("{text}"; - + Notice.Remove(pc.PlayerId); Notice.Add(pc.PlayerId, new(text, Utils.TimeStamp + (long)time)); - + SendRPC(pc.PlayerId); Utils.NotifyRoles(SpecifySeer: pc, SpecifyTarget: pc); - + if (sendInLog) Logger.Info($"New name notify for {pc.GetNameWithRole().RemoveHtmlTags()}: {text} ({time}s)", "Name Notify"); } public static void OnFixedUpdate(PlayerControl player) diff --git a/Modules/OptionBackup/OptionBackupData.cs b/Modules/OptionBackup/OptionBackupData.cs index a048301d9..887e56bde 100644 --- a/Modules/OptionBackup/OptionBackupData.cs +++ b/Modules/OptionBackup/OptionBackupData.cs @@ -34,10 +34,10 @@ public OptionBackupData(IGameOptions option) if (option.TryGetInt(name, out var value)) AllValues.Add(new IntOptionBackupValue(name, value)); } - + // [Vanilla bug] Only the number of people in the room cannot be obtained with GetInt, so obtain it separately. AllValues.Add(new IntOptionBackupValue(Int32OptionNames.MaxPlayers, option.MaxPlayers)); - + // TryGetUInt is not implemented, so get it separately AllValues.Add(new UIntOptionBackupValue(UInt32OptionNames.Keywords, (uint)option.Keywords)); diff --git a/Modules/OptionHolder.cs b/Modules/OptionHolder.cs index 6d21f723f..dd53e6052 100644 --- a/Modules/OptionHolder.cs +++ b/Modules/OptionHolder.cs @@ -1,13 +1,13 @@ using System; +using System.Reflection; using TOHE.Modules; -using TOHE.Roles.AddOns; using TOHE.Roles.AddOns.Impostor; -using TOHE.Roles.Core; using UnityEngine; +using TOHE.Roles.Core; +using TOHE.Roles.AddOns; namespace TOHE; -[Obfuscation(Exclude = true)] [Flags] public enum CustomGameMode { @@ -36,7 +36,6 @@ public static void OptionsLoadStart_Postfix() } // Presets - [Obfuscation(Exclude = true)] private static readonly string[] presets = [ Main.Preset1.Value, Main.Preset2.Value, Main.Preset3.Value, @@ -52,6 +51,7 @@ public static CustomGameMode CurrentGameMode 2 => CustomGameMode.HidenSeekTOHE, // HidenSeekTOHE must be after other game modes _ => CustomGameMode.Standard }; + public static readonly string[] gameModes = [ "Standard", @@ -72,7 +72,6 @@ public static CustomGameMode CurrentGameMode public static Dictionary CustomAdtRoleSpawnRate; public static readonly Dictionary AddonCanBeSettings = []; - [Obfuscation(Exclude = true)] public enum SpawnChance { Chance0, @@ -97,7 +96,6 @@ public enum SpawnChance Chance95, Chance100, } - [Obfuscation(Exclude = true)] private enum RatesZeroOne { RoleOff, @@ -171,9 +169,6 @@ private enum RatesZeroOne public static OptionItem ApplyBanList; public static OptionItem ApplyModeratorList; public static OptionItem AllowSayCommand; - public static OptionItem AllowStartCommand; - public static OptionItem StartCommandMinCountdown; - public static OptionItem StartCommandMaxCountdown; //public static OptionItem ApplyReminderMsg; //public static OptionItem TimeForReminder; @@ -386,7 +381,6 @@ private enum RatesZeroOne // Ghost public static OptionItem GhostIgnoreTasks; public static OptionItem GhostCanSeeOtherRoles; - public static OptionItem PreventSeeRolesImmediatelyAfterDeath; public static OptionItem GhostCanSeeOtherVotes; public static OptionItem GhostCanSeeDeathReason; public static OptionItem ConvertedCanBecomeGhost; @@ -592,7 +586,7 @@ private static void GroupAddons() .Select(x => (IAddon)Activator.CreateInstance(x)) .Where(x => x != null) .GroupBy(x => x.Type) - .ToDictionary(x => x.Key, x => x.Select(y => y.Role).ToList()); + .ToDictionary(x => x.Key, x => x.Select(y => Enum.Parse(y.GetType().Name, true)).ToList()); } @@ -639,7 +633,7 @@ public static float GetRoleChance(CustomRoles role) private static System.Collections.IEnumerator CoLoadOptions() { //####################################### - // 31000 last id for roles/add-ons (Next use 31100) + // 30100 last id for roles/add-ons (Next use 30200) // Limit id for roles/add-ons --- "59999" //####################################### @@ -1054,15 +1048,6 @@ private static System.Collections.IEnumerator CoLoadOptions() ApplyModeratorList = BooleanOptionItem.Create(60120, "ApplyModeratorList", false, TabGroup.SystemSettings, false); AllowSayCommand = BooleanOptionItem.Create(60121, "AllowSayCommand", false, TabGroup.SystemSettings, false) .SetParent(ApplyModeratorList); - AllowStartCommand = BooleanOptionItem.Create(60122, "AllowStartCommand", false, TabGroup.SystemSettings, false) - .SetParent(ApplyModeratorList); - StartCommandMinCountdown = IntegerOptionItem.Create(60123, "StartCommandMinCountdown", new(0, 99, 1), 0, TabGroup.SystemSettings, false) - .SetParent(AllowStartCommand) - .SetValueFormat(OptionFormat.Seconds); - StartCommandMaxCountdown = IntegerOptionItem.Create(60124, "StartCommandMaxCountdown", new(0, 99, 1), 15, TabGroup.SystemSettings, false) - .SetParent(AllowStartCommand) - .SetValueFormat(OptionFormat.Seconds); - //ApplyReminderMsg = BooleanOptionItem.Create(60130, "ApplyReminderMsg", false, TabGroup.SystemSettings, false); /*TimeForReminder = IntegerOptionItem.Create(60131, "TimeForReminder", new(0, 99, 1), 3, TabGroup.SystemSettings, false) .SetParent(TimeForReminder) @@ -1834,6 +1819,8 @@ private static System.Collections.IEnumerator CoLoadOptions() EveryoneCanSeeDeathReason = BooleanOptionItem.Create(60781, "EveryoneCanSeeDeathReason", false, TabGroup.ModSettings, false) .SetGameMode(CustomGameMode.Standard) .SetColor(new Color32(193, 255, 209, byte.MaxValue)); + + // 杀戮闪烁持续 KillFlashDuration = FloatOptionItem.Create(60790, "KillFlashDuration", new(0.1f, 0.45f, 0.05f), 0.3f, TabGroup.ModSettings, false) @@ -1852,10 +1839,6 @@ private static System.Collections.IEnumerator CoLoadOptions() GhostCanSeeOtherRoles = BooleanOptionItem.Create(60810, "GhostCanSeeOtherRoles", true, TabGroup.ModSettings, false) .SetGameMode(CustomGameMode.Standard) .SetColor(new Color32(217, 218, 255, byte.MaxValue)); - PreventSeeRolesImmediatelyAfterDeath = BooleanOptionItem.Create(60821, "PreventSeeRolesImmediatelyAfterDeath", true, TabGroup.ModSettings, false) - .SetParent(GhostCanSeeOtherRoles) - .SetGameMode(CustomGameMode.Standard) - .SetColor(new Color32(217, 218, 255, byte.MaxValue)); GhostCanSeeOtherVotes = BooleanOptionItem.Create(60820, "GhostCanSeeOtherVotes", true, TabGroup.ModSettings, false) .SetGameMode(CustomGameMode.Standard) .SetColor(new Color32(217, 218, 255, byte.MaxValue)); diff --git a/Modules/OptionItem/BooleanOptionItem.cs b/Modules/OptionItem/BooleanOptionItem.cs index 9866bdaf4..97a7e373a 100644 --- a/Modules/OptionItem/BooleanOptionItem.cs +++ b/Modules/OptionItem/BooleanOptionItem.cs @@ -2,7 +2,7 @@ namespace TOHE; -public class BooleanOptionItem(int id, string name, bool defaultValue, TabGroup tab, bool isSingleValue, bool vanilla) : OptionItem(id, name, defaultValue ? 1 : 0, tab, isSingleValue, vanillaStr: vanilla) +public class BooleanOptionItem(int id, string name, bool defaultValue, TabGroup tab, bool isSingleValue, bool vanilla) : OptionItem(id, name, defaultValue ? 1 : 0, tab, isSingleValue, vanillaStr:vanilla) { public const string TEXT_true = "ColoredOn"; public const string TEXT_false = "ColoredOff"; @@ -27,4 +27,4 @@ public override void SetValue(int value, bool doSync = true) { base.SetValue(value % 2 == 0 ? 0 : 1, doSync); } -} +} \ No newline at end of file diff --git a/Modules/OptionItem/FloatOptionItem.cs b/Modules/OptionItem/FloatOptionItem.cs index f35106137..ff6d3f1eb 100644 --- a/Modules/OptionItem/FloatOptionItem.cs +++ b/Modules/OptionItem/FloatOptionItem.cs @@ -2,7 +2,7 @@ namespace TOHE; -public class FloatOptionItem(int id, string name, float defaultValue, TabGroup tab, bool isSingleValue, FloatValueRule rule, bool vanilla) : OptionItem(id, name, rule.GetNearestIndex(defaultValue), tab, isSingleValue, vanillaStr: vanilla) +public class FloatOptionItem(int id, string name, float defaultValue, TabGroup tab, bool isSingleValue, FloatValueRule rule, bool vanilla) : OptionItem(id, name, rule.GetNearestIndex(defaultValue), tab, isSingleValue, vanillaStr:vanilla) { public FloatValueRule Rule = rule; @@ -30,4 +30,4 @@ public override void SetValue(int value, bool doSync = true) { base.SetValue(Rule.RepeatIndex(value), doSync); } -} +} \ No newline at end of file diff --git a/Modules/OptionItem/IntegerOptionItem.cs b/Modules/OptionItem/IntegerOptionItem.cs index 3ac32cd8f..bc70802c3 100644 --- a/Modules/OptionItem/IntegerOptionItem.cs +++ b/Modules/OptionItem/IntegerOptionItem.cs @@ -31,4 +31,4 @@ public override void SetValue(int value, bool doSync = true) { base.SetValue(Rule.RepeatIndex(value), doSync); } -} +} \ No newline at end of file diff --git a/Modules/OptionItem/OptionItem.cs b/Modules/OptionItem/OptionItem.cs index 66fdbb4b4..08de987b4 100644 --- a/Modules/OptionItem/OptionItem.cs +++ b/Modules/OptionItem/OptionItem.cs @@ -54,6 +54,8 @@ public int CurrentValue // Parent and Child Info public OptionItem Parent { get; private set; } + + public List Children; public OptionBehaviour OptionBehaviour; @@ -195,11 +197,11 @@ public virtual void Refresh() { if (IsVanillaText == true) { - opt.TitleText.text = GetNameVanilla(); + opt.TitleText.text = GetNameVanilla(); } else { - opt.TitleText.text = GetName(); + opt.TitleText.text = GetName(); } opt.ValueText.text = GetString(); opt.oldValue = opt.Value = CurrentValue; @@ -297,7 +299,7 @@ public class UpdateValueEventArgs(int beforeValue, int currentValue) : EventArgs public const int NumPresets = 5; public const int PresetId = 0; } -[Obfuscation(Exclude = true)] + public enum TabGroup { SystemSettings, @@ -308,7 +310,6 @@ public enum TabGroup NeutralRoles, Addons } -[Obfuscation(Exclude = true)] public enum OptionFormat { None, diff --git a/Modules/OptionItem/PresetOptionItem.cs b/Modules/OptionItem/PresetOptionItem.cs index 27695100d..3c97e9237 100644 --- a/Modules/OptionItem/PresetOptionItem.cs +++ b/Modules/OptionItem/PresetOptionItem.cs @@ -1,7 +1,6 @@ namespace TOHE; -[Obfuscation(Exclude = true, ApplyToMembers = true)] -public class PresetOptionItem(int defaultValue, TabGroup tab, bool vanilla) : OptionItem(0, "Preset", defaultValue, tab, true, vanillaStr: vanilla) +public class PresetOptionItem(int defaultValue, TabGroup tab, bool vanilla) : OptionItem(0, "Preset", defaultValue, tab, true, vanillaStr:vanilla) { public IntegerValueRule Rule = (0, NumPresets - 1, 1); public int ValuePresets = NumPresets; @@ -40,4 +39,4 @@ public override void SetValue(int afterValue, bool doSave, bool doSync = true) base.SetValue(Rule.RepeatIndex(afterValue), doSave, doSync); SwitchPreset(Rule.RepeatIndex(afterValue)); } -} +} \ No newline at end of file diff --git a/Modules/OptionItem/StringOptionItem.cs b/Modules/OptionItem/StringOptionItem.cs index 0044749f1..9be3823de 100644 --- a/Modules/OptionItem/StringOptionItem.cs +++ b/Modules/OptionItem/StringOptionItem.cs @@ -2,7 +2,7 @@ namespace TOHE; -public class StringOptionItem(int id, string name, int defaultValue, TabGroup tab, bool isSingleValue, string[] selections, bool vanilla) : OptionItem(id, name, defaultValue, tab, isSingleValue, vanillaStr: vanilla) +public class StringOptionItem(int id, string name, int defaultValue, TabGroup tab, bool isSingleValue, string[] selections, bool vanilla) : OptionItem(id, name, defaultValue, tab, isSingleValue, vanillaStr:vanilla) { public IntegerValueRule Rule = (0, selections.Length - 1, 1); public string[] Selections = selections; @@ -11,7 +11,7 @@ public static StringOptionItem Create(int id, string name, string[] selections, { return new StringOptionItem(id, name, defaultIndex, tab, isSingleValue, selections, vanillaText); } - public static StringOptionItem Create(int id, Enum name, string[] selections, int defaultIndex, TabGroup tab, bool isSingleValue, bool vanillaText = false) + public static StringOptionItem Create(int id,Enum name, string[] selections, int defaultIndex, TabGroup tab, bool isSingleValue, bool vanillaText = false) { return new StringOptionItem(id, name.ToString(), defaultIndex, tab, isSingleValue, selections, vanillaText); } @@ -45,4 +45,9 @@ public override void SetValue(int value, bool doSync = true) { base.SetValue(Rule.RepeatIndex(value), doSync); } -} + + internal static object Create(int v1, string v2, string[] strings, int[] ints, TabGroup neutralRoles, bool v3) + { + throw new NotImplementedException(); + } +} \ No newline at end of file diff --git a/Modules/OptionItem/TextOptionItem.cs b/Modules/OptionItem/TextOptionItem.cs index 3c2e4a1b8..3f1e6665d 100644 --- a/Modules/OptionItem/TextOptionItem.cs +++ b/Modules/OptionItem/TextOptionItem.cs @@ -7,7 +7,7 @@ public class TextOptionItem : OptionItem // コンストラクタ public TextOptionItem(int id, string name, int defaultValue, TabGroup tab, bool isSingleValue, bool vanilla) - : base(id, name, defaultValue, tab, isSingleValue, vanillaStr: vanilla) + : base(id, name, defaultValue, tab, isSingleValue, vanillaStr:vanilla) { IsText = true; IsHeader = true; @@ -28,4 +28,4 @@ public override string GetString() { return Translator.GetString(Name); } -} +} \ No newline at end of file diff --git a/Modules/OptionSaver.cs b/Modules/OptionSaver.cs index 35e04780a..83b7008ff 100644 --- a/Modules/OptionSaver.cs +++ b/Modules/OptionSaver.cs @@ -6,9 +6,7 @@ namespace TOHE.Modules; // https://github.com/tukasa0001/TownOfHost/blob/main/Modules/OptionSaver.cs public static class OptionSaver { - [Obfuscation(Exclude = true)] private static readonly DirectoryInfo SaveDataDirectoryInfo = new("./TOHE-DATA/SaveData/"); - [Obfuscation(Exclude = true)] private static readonly FileInfo OptionSaverFileInfo = new($"{SaveDataDirectoryInfo.FullName}/Options.json"); public static void Initialize() @@ -109,7 +107,6 @@ public static void Load() LoadOptionsData(JsonSerializer.Deserialize(jsonString)); } - [Obfuscation(Exclude = true, ApplyToMembers = true)] /// Optional data suitable for json storage public class SerializableOptionsData { diff --git a/Modules/OptionShower.cs b/Modules/OptionShower.cs index c433ac7ed..bd77676e0 100644 --- a/Modules/OptionShower.cs +++ b/Modules/OptionShower.cs @@ -65,7 +65,7 @@ public static string GetText() mode = Utils.GetChance(Options.CustomAdtRoleSpawnRate[kvp.Key].GetFloat()); } - sb.Append($"{Utils.ColorString(Utils.GetRoleColor(kvp.Key), Utils.GetRoleName(kvp.Key))}: {mode}×{kvp.Key.GetCount()}\n"); + sb.Append($"{Utils.ColorString(Utils.GetRoleColor(kvp.Key), Utils.GetRoleName(kvp.Key))}: {mode}×{kvp.Key.GetCount()}\n"); } pages.Add(sb.ToString() + "\n\n"); sb.Clear(); diff --git a/Modules/OutfitManager.cs b/Modules/OutfitManager.cs index bbb972af5..b7db36043 100644 --- a/Modules/OutfitManager.cs +++ b/Modules/OutfitManager.cs @@ -80,7 +80,11 @@ void Setoutfit() player.Data.SetOutfit(OutfitTypeSet, Outfit); - player.Data.MarkDirty(); + //Used instead of GameData.Instance.DirtyAllData(); + foreach (var innerNetObject in GameData.Instance.AllPlayers) + { + innerNetObject.SetDirtyBit(uint.MaxValue); + } } if (player.CheckCamoflague() && !force) { diff --git a/Modules/RPC.cs b/Modules/RPC.cs index b14ebf45e..14dabeea6 100644 --- a/Modules/RPC.cs +++ b/Modules/RPC.cs @@ -4,6 +4,7 @@ using System; using System.Threading.Tasks; using TOHE.Modules; +using TOHE.Modules.ChatManager; using TOHE.Patches; using TOHE.Roles.AddOns.Impostor; using TOHE.Roles.Core; @@ -14,14 +15,10 @@ namespace TOHE; -[Obfuscation(Exclude = true)] -public enum CustomRPC : byte // 185/255 USED +enum CustomRPC : byte // 185/255 USED { // RpcCalls can increase with each AU version // On version 2024.6.18 the last id in RpcCalls: 65 - - // Adding Role rpcs that overrides TOHE section and changing BetterCheck will be rejected - // Sync Role Skill can be used under most cases so you should not make a new rpc unless it's necessary VersionCheck = 80, RequestRetryVersionCheck = 81, SyncCustomSettings = 100, // AUM use 101 rpc @@ -41,10 +38,11 @@ public enum CustomRPC : byte // 185/255 USED KillFlash, DumpLog, SyncRoleSkill, + SendChatMessage = 186, + MuteChat = 187, SetNameColorData, GuessKill, Judge, - KNChat = 119, // Kill network chat, may conflicts with judge and guess calls Guess, CouncillorJudge, NemesisRevenge, @@ -55,12 +53,10 @@ public enum CustomRPC : byte // 185/255 USED ShowChat, SyncShieldPersonDiedFirst, RemoveSubRole, - FixModdedClientCNO, SyncGeneralOptions, SyncSpeedPlayer, Arrow, NotificationPopper, - SyncDeadPassedMeetingList, //Roles SetBountyTarget, @@ -77,13 +73,14 @@ public enum CustomRPC : byte // 185/255 USED SetLoversPlayers, SendFireworkerState, SetCurrentDousingTarget, + SetEvilTrackerTarget, + SetDrawPlayer, + SetCrewpostorTasksDone, + UpdateSoulMeter, // BetterAmongUs (BAU) RPC, This is sent to allow other BAU users know who's using BAU! BetterCheck = 150, - SetEvilTrackerTarget, - SetDrawPlayer, - SetCrewpostorTasksDone, SetCurrentDrawTarget, RpcPassBomb, SyncRomanticTarget, @@ -94,6 +91,7 @@ public enum CustomRPC : byte // 185/255 USED KeeperRPC, SetAlchemistTimer, UndertakerLocationSync, + RiftMakerSyncData, LightningSetGhostPlayer, SetDarkHiderKillCount, SetConsigliere, @@ -110,16 +108,16 @@ public enum CustomRPC : byte // 185/255 USED SetOverseerRevealedPlayer, SetOverseerTimer, SyncVultureBodyAmount, + SpyRedNameSync, + SpyRedNameRemove, SetChameleonTimer, SyncAdmiredList, SyncAdmiredAbility, SetImitateLimit, - DictatorRPC, //FFA SyncFFAPlayer, SyncFFANameNotify, } -[Obfuscation(Exclude = true)] public enum Sounds { KillSound, @@ -162,8 +160,7 @@ or CustomRPC.PresidentEnd or CustomRPC.SetSwapperVotes or CustomRPC.DumpLog or CustomRPC.SetFriendCode - or CustomRPC.BetterCheck - or CustomRPC.DictatorRPC; + or CustomRPC.BetterCheck; public static bool Prefix(PlayerControl __instance, [HarmonyArgument(0)] byte callId, [HarmonyArgument(1)] MessageReader reader) { var rpcType = (RpcCalls)callId; @@ -214,6 +211,9 @@ public static bool Prefix(PlayerControl __instance, [HarmonyArgument(0)] byte ca } return true; } + + + public static void Postfix(PlayerControl __instance, [HarmonyArgument(0)] byte callId, [HarmonyArgument(1)] MessageReader reader) { // Process nothing but CustomRPC @@ -223,7 +223,85 @@ public static void Postfix(PlayerControl __instance, [HarmonyArgument(0)] byte c switch (rpcType) { case CustomRPC.AntiBlackout: - CriticalErrorManager.ReadRpc(__instance, reader); + Logger.Fatal($"{__instance?.Data?.PlayerName}({__instance.PlayerId}): Error: {reader.ReadString()} - end the game according to the setting", "Anti-black"); + + if (GameStates.IsShip || !GameStates.IsLobby || GameStates.IsCoStartGame) + { + //CoStartGame is running, we are fucked. + ChatUpdatePatch.DoBlockChat = true; + Main.OverrideWelcomeMsg = string.Format(GetString("RpcAntiBlackOutNotifyInLobby"), __instance?.Data?.PlayerName, GetString("EndWhenPlayerBug")); + + if (Options.EndWhenPlayerBug.GetBool()) + { + _ = new LateTask(() => + { + Logger.SendInGame(string.Format(GetString("RpcAntiBlackOutEndGame"), __instance?.Data?.PlayerName)); + }, 3f, "RPC Anti-Black Msg SendInGame Error During Loading"); + + if (AmongUsClient.Instance.AmHost) + { + if (GameStates.IsInGame && !GameStates.IsCoStartGame) + { + CustomWinnerHolder.ResetAndSetWinner(CustomWinner.Error); + GameManager.Instance.LogicFlow.CheckEndCriteria(); + RPC.ForceEndGame(CustomWinner.Error); + } + else + { + _ = new LateTask(() => + { + CustomWinnerHolder.ResetAndSetWinner(CustomWinner.Error); + GameManager.Instance.LogicFlow.CheckEndCriteria(); + RPC.ForceEndGame(CustomWinner.Error); + }, 5.5f, "RPC Anti-Black End Game As Critical Error"); + } + } + } + else + { + _ = new LateTask(() => + { + Logger.SendInGame(string.Format(GetString("RpcAntiBlackOutIgnored"), __instance?.Data?.PlayerName)); + }, 3f, "RPC Anti-Black Msg SendInGame Out Ignored"); + + if (AmongUsClient.Instance.AmHost && __instance != null) + { + if (GameStates.IsInGame && !GameStates.IsCoStartGame) + { + AmongUsClient.Instance.KickPlayer(__instance.GetClientId(), false); + Logger.SendInGame(string.Format(GetString("RpcAntiBlackOutKicked"), __instance?.Data?.PlayerName)); + } + else + { + _ = new LateTask(() => + { + AmongUsClient.Instance.KickPlayer(__instance.GetClientId(), false); + Logger.SendInGame(string.Format(GetString("RpcAntiBlackOutKicked"), __instance?.Data?.PlayerName)); + }, 5.5f, "RPC Anti-Black Kicked As Critical Error"); + } + + ChatUpdatePatch.DoBlockChat = false; + } + } + } + else if (GameStartManager.Instance != null) + { + // We imagine rpc is received when starting game in lobby, not fucked yet + if (AmongUsClient.Instance.AmHost) + { + GameStartManager.Instance.ResetStartState(); + if (__instance != null) + { + AmongUsClient.Instance.KickPlayer(__instance.GetClientId(), false); + } + } + Logger.SendInGame(string.Format(GetString("RpcAntiBlackOutKicked"), __instance?.Data?.PlayerName)); + } + else + { + Logger.SendInGame("[Critical Error] Your client is in a unknow state while receiving AntiBlackOut rpcs from others."); + Logger.Fatal($"Client is in a unknow state while receiving AntiBlackOut rpcs from others.", "Anti-black"); + } break; case CustomRPC.VersionCheck: @@ -422,6 +500,9 @@ public static void Postfix(PlayerControl __instance, [HarmonyArgument(0)] byte c case CustomRPC.UndertakerLocationSync: Undertaker.ReceiveRPC(reader); break; + case CustomRPC.RiftMakerSyncData: + RiftMaker.ReceiveRPC(reader); + break; case CustomRPC.SetLoversPlayers: Main.LoversPlayers.Clear(); int count = reader.ReadInt32(); @@ -481,6 +562,9 @@ public static void Postfix(PlayerControl __instance, [HarmonyArgument(0)] byte c case CustomRPC.SetJailerTarget: Jailer.ReceiveRPC(reader, setTarget: true); break; + case CustomRPC.SendChatMessage: + HandleSendChatMessage(reader); + break; case CustomRPC.SetCrewpostorTasksDone: Crewpostor.ReceiveRPC(reader); break; @@ -616,14 +700,18 @@ public static void Postfix(PlayerControl __instance, [HarmonyArgument(0)] byte c Logger.Info($"Player {target.GetNameWithRole()} used /dump", "RPC_DumpLogger"); } break; - case CustomRPC.FixModdedClientCNO: - var CNO = reader.ReadNetObject(); - bool active = reader.ReadBoolean(); - CNO?.transform.FindChild("Names").FindChild("NameText_TMP").gameObject.SetActive(active); - break; case CustomRPC.SyncVultureBodyAmount: Vulture.ReceiveBodyRPC(reader); break; + case CustomRPC.SpyRedNameSync: + Spy.ReceiveRPC(reader); + break; + case CustomRPC.SpyRedNameRemove: + Spy.ReceiveRPC(reader, isRemove: true); + break; + //case CustomRPC.SetCleanserCleanLimit: + // Cleanser.ReceiveRPC(reader); + // break; case CustomRPC.SetInspectorLimit: Inspector.ReceiveRPC(reader); break; @@ -633,22 +721,59 @@ public static void Postfix(PlayerControl __instance, [HarmonyArgument(0)] byte c case CustomRPC.SetSwapperVotes: Swapper.ReceiveSwapRPC(reader, __instance); break; - case CustomRPC.DictatorRPC: - Dictator.OnReceiveDictatorRPC(reader, __instance); - break; case CustomRPC.SyncShieldPersonDiedFirst: Main.FirstDied = reader.ReadString(); Main.FirstDiedPrevious = reader.ReadString(); break; - case CustomRPC.SyncDeadPassedMeetingList: - Main.DeadPassedMeetingPlayers.Clear(); - var pnum = reader.ReadPackedInt32(); - for (int i = 0; i < pnum; i++) - Main.DeadPassedMeetingPlayers.Add(reader.ReadByte()); + } + } + + private static void HandleSendChatMessage(MessageReader reader) + { + string message = reader.ReadString(); + byte targetPlayerId = reader.ReadByte(); + + PlayerControl target = null; + foreach (var player in PlayerControl.AllPlayerControls) + { + if (player.PlayerId == targetPlayerId) + { + target = player; break; + } } + + if (target != null && target.AmOwner) + { + // Send the private message to the summoner + Utils.SendMessage($"SYSTEM MESSAGE: {message}", target.PlayerId); + Logger.Info($"Sent SYSTEM MESSAGE to {target.GetRealName()}", "ChatManager"); + ChatManager.cancel = true; // Prevent normal chat behavior + } + } + + + + + private static void SendChatMessage(PlayerControl recipient, string message) + { + MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately( + PlayerControl.LocalPlayer.NetId, + (byte)CustomRPC.SendChatMessage, + SendOption.Reliable + ); + + // Write the recipient's PlayerId and the message + writer.Write(recipient.PlayerId); + writer.Write(message); + + AmongUsClient.Instance.FinishRpcImmediately(writer); + + Logger.Info($"Sent private message to {recipient.GetRealName()}: {message}", "ChatManager"); } + + private static bool IsVersionMatch(int ClientId) { if (Main.VersionCheat.Value) return true; @@ -886,7 +1011,7 @@ public static void ForceEndGame(CustomWinner win) { ShipStatus.Instance.enabled = false; Utils.NotifyGameEnding(); - + try { GameManager.Instance.LogicFlow.CheckEndCriteria(); } catch { } try { GameManager.Instance.RpcEndGame(GameOverReason.ImpostorDisconnect, false); } @@ -982,17 +1107,6 @@ public static void SyncLoversPlayers() } AmongUsClient.Instance.FinishRpcImmediately(writer); } - public static void SyncDeadPassedMeetingList() - { - if (!AmongUsClient.Instance.AmHost) return; - var writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.SyncDeadPassedMeetingList, SendOption.Reliable, -1); - writer.WritePacked(Main.DeadPassedMeetingPlayers.Count); - foreach (var dead in Main.DeadPassedMeetingPlayers) - { - writer.Write(dead); - } - AmongUsClient.Instance.FinishRpcImmediately(writer); - } public static void SendRpcLogger(uint targetNetId, byte callId, int targetClientId = -1) { if (!DebugModeManager.AmDebugger) return; @@ -1005,7 +1119,6 @@ public static void SendRpcLogger(uint targetNetId, byte callId, int targetClient from = Main.AllPlayerControls.FirstOrDefault(c => c.NetId == targetNetId)?.Data?.PlayerName; } catch { } - Logger.Info($"FromNetID:{targetNetId}({from}) TargetClientID:{targetClientId}({target}) CallID:{callId}({rpcName})", "SendRPC"); } public static string GetRpcName(byte callId) @@ -1016,6 +1129,9 @@ public static string GetRpcName(byte callId) else rpcName = callId.ToString(); return rpcName; } + + + public static void SetRealKiller(byte targetId, byte killerId) { var state = Main.PlayerStates[targetId]; diff --git a/Modules/RehostManager.cs b/Modules/RehostManager.cs index 3f7528740..fb35186e4 100644 --- a/Modules/RehostManager.cs +++ b/Modules/RehostManager.cs @@ -1,5 +1,5 @@ -using AmongUs.GameOptions; -using InnerNet; +using InnerNet; +using AmongUs.GameOptions; using TMPro; using UnityEngine; using static TOHE.Translator; diff --git a/Modules/SpamManager.cs b/Modules/SpamManager.cs index 212fc67ca..826cbd14a 100644 --- a/Modules/SpamManager.cs +++ b/Modules/SpamManager.cs @@ -205,7 +205,7 @@ private static bool ContainsStart(string text) if (text == "C O M E Ç A") return true; if (text == "I N I C I A R") return true; - + if (text == "Го") return true; if (text == "гО") return true; if (text == "го") return true; diff --git a/Modules/TemplateManager.cs b/Modules/TemplateManager.cs index 0d63fbac2..58249a7a5 100644 --- a/Modules/TemplateManager.cs +++ b/Modules/TemplateManager.cs @@ -2,6 +2,7 @@ using System; using System.Globalization; using System.IO; +using System.Reflection; using System.Text; using System.Text.RegularExpressions; using static TOHE.Translator; @@ -75,7 +76,7 @@ public static class TemplateManager return string.Empty; } } - }; +}; public static void Init() { @@ -153,7 +154,7 @@ public static void SendTemplate(string str = "", byte playerId = 0xff, bool noEr Func playerName = () => ""; if (playerId != 0xff) { - playerName = () => Main.AllPlayerNames[playerId]; + playerName = () => Main.AllPlayerNames[playerId]; } _replaceDictionaryNormalOptions["PlayerName"] = playerName; @@ -228,7 +229,7 @@ private static string TryGetTitle(string Text, out bool Contains) title = Text.Substring(start, end); title = title.Replace("", ""); title = title.Replace("", ""); - + } diff --git a/Modules/Translator.cs b/Modules/Translator.cs index 0915a2e8f..194da1b10 100644 --- a/Modules/Translator.cs +++ b/Modules/Translator.cs @@ -41,11 +41,11 @@ public static void LoadLangs() { // Read the JSON file content using Stream resourceStream = assembly.GetManifestResourceStream(jsonFileName); - + if (resourceStream != null) { using StreamReader reader = new(resourceStream); - + string jsonContent = reader.ReadToEnd(); // Deserialize the JSON into a dictionary Dictionary jsonDictionary = JsonSerializer.Deserialize>(jsonContent); @@ -214,7 +214,7 @@ public static string GetString(string s, Dictionary replacementD } return str; } - public static bool TryGetStrings(string strItem, out string[] s) + public static bool TryGetStrings(string strItem, out string[] s) { // Basically if you wanna let the user infinitely expand a function to their liking // I need to test if this shit works lol, I plan a usecase for it in 2.1.0 (see: https://discord.com/channels/1094344790910455908/1251264307052675134) @@ -318,7 +318,7 @@ static void UpdateCustomTranslation(string filename/*, SupportedLangs lang*/) { List textStrings = []; using (StreamReader reader = new(path, Encoding.GetEncoding("UTF-8"))) - { + { string line; while ((line = reader.ReadLine()) != null) { diff --git a/Modules/Utils.cs b/Modules/Utils.cs index 3d3a3518b..b8381cbe0 100644 --- a/Modules/Utils.cs +++ b/Modules/Utils.cs @@ -1,39 +1,106 @@ using AmongUs.Data; using AmongUs.GameOptions; using Hazel; -using Il2CppInterop.Generator.Extensions; using InnerNet; using System; using System.Data; -using System.Diagnostics; using System.IO; -using System.Runtime.CompilerServices; +using System.Reflection; using System.Text; +using System.Runtime.CompilerServices; using System.Text.RegularExpressions; using System.Threading.Tasks; +using System.Diagnostics; +using UnityEngine; using TOHE.Modules; using TOHE.Modules.ChatManager; -using TOHE.Patches; using TOHE.Roles.AddOns.Common; using TOHE.Roles.AddOns.Crewmate; using TOHE.Roles.AddOns.Impostor; -using TOHE.Roles.Core; using TOHE.Roles.Crewmate; using TOHE.Roles.Impostor; using TOHE.Roles.Neutral; -using UnityEngine; +using TOHE.Roles.Core; using static TOHE.Translator; +using TOHE.Patches; namespace TOHE; -[Obfuscation(Exclude = true, Feature = "renaming", ApplyToMembers = true)] public static class Utils { private static readonly DateTime timeStampStartTime = new(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); public static long TimeStamp => (long)(DateTime.Now.ToUniversalTime() - timeStampStartTime).TotalSeconds; public static long GetTimeStamp(DateTime? dateTime = null) => (long)((dateTime ?? DateTime.Now).ToUniversalTime() - timeStampStartTime).TotalSeconds; + public static void ErrorEnd(string text) + { + if (AmongUsClient.Instance.AmHost) + { + Logger.Fatal($"Error: {text} - triggering critical error", "Anti-black"); + ChatUpdatePatch.DoBlockChat = true; + Main.OverrideWelcomeMsg = GetString("AntiBlackOutNotifyInLobby"); + + _ = new LateTask(() => + { + Logger.SendInGame(GetString("AntiBlackOutLoggerSendInGame")); + }, 8f, "Anti-Black Msg SendInGame Error During Loading"); + + if (GameStates.IsShip || !GameStates.IsLobby || GameStates.IsCoStartGame) + { + _ = new LateTask(() => + { + CustomWinnerHolder.ResetAndSetWinner(CustomWinner.Error); + GameManager.Instance.LogicFlow.CheckEndCriteria(); + RPC.ForceEndGame(CustomWinner.Error); + }, 11f, "Anti-Black End Game As Critical Error"); + } + else if (GameStartManager.Instance != null) + { + GameStartManager.Instance.ResetStartState(); + AmongUsClient.Instance.RemoveUnownedObjects(); + Logger.SendInGame(GetString("AntiBlackOutLoggerSendInGame")); + } + else + { + Logger.SendInGame("Host in a unknow antiblack bugged state."); + Logger.Fatal($"Host in a unknow antiblack bugged state.", "Anti-black"); + } + } + else + { + MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.AntiBlackout, SendOption.Reliable); + writer.Write(text); + AmongUsClient.Instance.FinishRpcImmediately(writer); + + Logger.Fatal($"Error: {text} - I'm triggering critical error", "Anti-black"); + + if (Options.EndWhenPlayerBug.GetBool()) + { + _ = new LateTask(() => + { + Logger.SendInGame(GetString("AntiBlackOutRequestHostToForceEnd")); + }, 8f, "Anti-Black Msg SendInGame Non-Host Modded Has Error During Loading"); + } + else + { + _ = new LateTask(() => + { + Logger.SendInGame(GetString("AntiBlackOutHostRejectForceEnd")); + }, 8f, "Anti-Black Msg SendInGame Host Reject Force End"); + + _ = new LateTask(() => + { + if (AmongUsClient.Instance.AmConnected) + { + AmongUsClient.Instance.ExitGame(DisconnectReasons.Custom); + Logger.Fatal($"Error: {text} - Disconnected from the game due critical error", "Anti-black"); + } + }, 13f, "Anti-Black Exit Game Due Critical Error"); + } + } + } + // Should happen before EndGame messages is sent public static void NotifyGameEnding() { @@ -315,59 +382,6 @@ public static string GetRoleMode(CustomRoles role, bool parentheses = true) return parentheses ? $"({mode})" : mode; } - public static void SendRPC(CustomRPC rpc, params object[] data) - { - var w = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)rpc, SendOption.Reliable); - foreach (var o in data) - { - switch (o) - { - case byte b: - w.Write(b); - break; - case int i: - w.WritePacked(i); - break; - case float f: - w.Write(f); - break; - case string s: - w.Write(s); - break; - case bool b: - w.Write(b); - break; - case long l: - w.Write(l.ToString()); - break; - case char c: - w.Write(c.ToString()); - break; - case Vector2 v: - w.Write(v); - break; - case Vector3 v: - w.Write(v); - break; - case PlayerControl pc: - w.WriteNetObject(pc); - break; - default: - try - { - if (o != null && Enum.TryParse(o.GetType(), o.ToString(), out var e) && e != null) - w.WritePacked((int)e); - } - catch (InvalidCastException e) - { - ThrowException(e); - } - break; - } - } - - AmongUsClient.Instance.FinishRpcImmediately(w); - } public static string GetChance(float percent) { return percent switch @@ -452,6 +466,10 @@ public static Color GetTeamColor(PlayerControl player) break; } + + + + _ = ColorUtility.TryParseHtmlString(hexColor, out Color c); return c; } @@ -467,7 +485,7 @@ public static (string, Color) GetRoleAndSubText(byte seerId, byte targetId, bool var targetMainRole = Main.PlayerStates[targetId].MainRole; var targetSubRoles = Main.PlayerStates[targetId].SubRoles; - + // If a player is possessed by the Dollmaster swap each other's role and add-ons for display for every other client other than Dollmaster and target. if (DollMaster.IsControllingPlayer) { @@ -501,11 +519,10 @@ public static (string, Color) GetRoleAndSubText(byte seerId, byte targetId, bool var seerPlatform = seer.GetClient()?.PlatformData.Platform; var addBracketsToAddons = Options.AddBracketsToAddons.GetBool(); - static bool Checkif(string str) - { + static bool Checkif(string str) { string[] strings = ["*Prefix", "INVALID"]; - return strings.Any(str.Contains); + return strings.Any(str.Contains); } static string Getname(string str) => !Checkif(GetString($"Prefix.{str}")) ? GetString($"Prefix.{str}") : GetString($"{str}"); @@ -679,7 +696,7 @@ public static string GetProgressText(byte playerId, bool comms = false) if (!Main.playerVersion.ContainsKey(AmongUsClient.Instance.HostId)) return string.Empty; var ProgressText = new StringBuilder(); var role = Main.PlayerStates[playerId].MainRole; - + if (Options.CurrentGameMode == CustomGameMode.FFA && role == CustomRoles.Killer) { ProgressText.Append(FFAManager.GetDisplayScore(playerId)); @@ -733,7 +750,7 @@ public static void ShowActiveSettingsHelp(byte PlayerId = byte.MaxValue) if (Options.SabotageTimeControl.GetBool()) { SendMessage(GetString("SabotageTimeControlInfo"), PlayerId); } if (Options.RandomMapsMode.GetBool()) { SendMessage(GetString("RandomMapsModeInfo"), PlayerId); } if (Main.EnableGM.Value) { SendMessage(GetRoleName(CustomRoles.GM) + GetString("GMInfoLong"), PlayerId); } - + foreach (var role in CustomRolesHelper.AllRoles) { if (role.IsEnable() && !role.IsVanilla()) SendMessage(GetRoleName(role) + GetRoleMode(role) + GetString(Enum.GetName(typeof(CustomRoles), role) + "InfoLong"), PlayerId); @@ -769,7 +786,7 @@ public static void ShowActiveSettings(byte PlayerId = byte.MaxValue) SendMessage(sb.ToString(), PlayerId); } - + public static void ShowAllActiveSettings(byte PlayerId = byte.MaxValue) { if (Options.HideGameSettings.GetBool() && PlayerId != byte.MaxValue) @@ -870,7 +887,7 @@ public static void ShowActiveRoles(byte PlayerId = byte.MaxValue) crewsb.Sort(); neutralsb.Sort(); addonsb.Sort(); - + SendMessage(string.Join("\n", impsb), PlayerId, ColorString(GetRoleColor(CustomRoles.Impostor), GetString("ImpostorRoles")), ShouldSplit: true); SendMessage(string.Join("\n", crewsb), PlayerId, ColorString(GetRoleColor(CustomRoles.Crewmate), GetString("CrewmateRoles")), ShouldSplit: true); SendMessage(string.Join("\n", neutralsb), PlayerId, GetString("NeutralRoles"), ShouldSplit: true); @@ -943,7 +960,7 @@ public static void ShowLastRoles(byte PlayerId = byte.MaxValue, bool sendMessage if (EndGamePatch.SummaryText[id].Contains("")) continue; sb.Append($"\n  ").Append(EndGamePatch.SummaryText[id]); - + } break; } @@ -968,11 +985,11 @@ public static void ShowKillLog(byte PlayerId = byte.MaxValue) SendMessage(GetString("CantUse.killlog"), PlayerId); return; } - if (EndGamePatch.KillLog != "") + if (EndGamePatch.KillLog != "") { string kl = EndGamePatch.KillLog; kl = Options.OldKillLog.GetBool() ? kl.RemoveHtmlTags() : kl.Replace(" 18 ? byte.MaxValue : Convert.ToByte(color); @@ -1402,7 +1419,6 @@ public static void ShowHelp(byte ID) + $"\n ○ /id {GetString("Command.idlist")}" + $"\n ○ /qq {GetString("Command.qq")}" + $"\n ○ /dump {GetString("Command.dump")}" - + $"\n ○ /start {GetString("Command.start")}" // + $"\n ○ /iconhelp {GetString("Command.iconhelp")}" , ID); } @@ -1438,25 +1454,25 @@ public static string[] SplitMessage(this string LongMsg) return [.. result]; } private static string TryRemove(this string text) => text.Length >= 1200 ? text.Remove(0, 1200) : string.Empty; - - - public static void SendSpesificMessage(string text, byte sendTo = byte.MaxValue, string title = "") + + + public static void SendSpesificMessage(string text, byte sendTo = byte.MaxValue, string title = "") { // Always splits it, this is incase you want to very heavily modify msg and use the splitmsg functionality. bool isfirst = true; if (text.Length > 1200 && !GetPlayerById(sendTo).IsModded()) { - foreach (var txt in text.SplitMessage()) + foreach(var txt in text.SplitMessage()) { var titleW = isfirst ? title : "."; var m = Regex.Replace(txt, "^", ""); // replaces the first instance of voffset, if any. m += $"."; // fix text clipping OOB - if (m.IndexOf("\n") <= 4) m = m[(m.IndexOf("\n") + 1)..m.Length]; + if (m.IndexOf("\n") <= 4) m = m[(m.IndexOf("\n")+1)..m.Length]; SendMessage(m, sendTo, titleW); isfirst = false; } } - else + else { text += $"."; if (text.IndexOf("\n") <= 4) text = text[(text.IndexOf("\n") + 1)..text.Length]; @@ -1482,7 +1498,7 @@ public static void SendMessage(string text, byte sendTo = byte.MaxValue, string { if (ShouldSplit && text.Length > 1200) { - text.SplitMessage().Do(x => SendMessage(x, sendTo, title, logforChatManager, noReplay, false)); + text.SplitMessage().Do(x => SendMessage(x, sendTo, title)); return; } //else if (text.Length > 1200 && (!GetPlayerById(sendTo).IsModClient())) @@ -1739,7 +1755,7 @@ void SetRealName() if (name != player.name && player.CurrentOutfitType == PlayerOutfitType.Default) player.RpcSetName(name); } - public static bool CheckCamoflague(this PlayerControl PC) => Camouflage.IsCamouflage || Camouflager.AbilityActivated || Utils.IsActive(SystemTypes.MushroomMixupSabotage) + public static bool CheckCamoflague(this PlayerControl PC) => Camouflage.IsCamouflage || Camouflager.AbilityActivated || Utils.IsActive(SystemTypes.MushroomMixupSabotage) || (Main.CheckShapeshift.TryGetValue(PC.PlayerId, out bool isShapeshifitng) && isShapeshifitng); public static PlayerControl GetPlayerById(int PlayerId) { @@ -1757,6 +1773,7 @@ public static List GetPlayerListByRole(this CustomRoles role) public static bool IsSameTeammate(this PlayerControl player, PlayerControl target, out Custom_Team team) { team = default; + if (player.IsAnySubRole(x => x.IsConverted())) { var Compare = player.GetCustomSubRoles().First(x => x.IsConverted()); @@ -1770,10 +1787,14 @@ public static bool IsSameTeammate(this PlayerControl player, PlayerControl targe return target.Is(team); } - return false; } - public static IEnumerable GetRoleBasesByType() where t : RoleBase + + + + + + public static IEnumerable GetRoleBasesByType () where t : RoleBase { try { @@ -1810,7 +1831,7 @@ public static void SetCustomIntro(this PlayerControl player) { if (!SetUpRoleTextPatch.IsInIntro || player == null || player.IsModded()) return; - //Get role info font size based on the length of the role info + // Get role info font size based on the length of the role info static int GetInfoSize(string RoleInfo) { RoleInfo = Regex.Replace(RoleInfo, "<[^>]*>", ""); @@ -1832,6 +1853,8 @@ static int GetInfoSize(string RoleInfo) string SelfSubRolesName = string.Empty; string RoleInfo = $"\n{Font}{ColorString(player.GetRoleColor(), player.GetRoleInfo())}"; string RoleNameUp = "\n\n"; + + if (!player.HasDesyncRole()) { @@ -1907,8 +1930,8 @@ public static Task DoNotifyRoles(PlayerControl SpecifySeer = null, PlayerControl HudManagerPatch.NowCallNotifyRolesCount++; HudManagerPatch.LastSetNameDesyncCount = 0; - PlayerControl[] seerList = SpecifySeer != null - ? ([SpecifySeer]) + PlayerControl[] seerList = SpecifySeer != null + ? ([SpecifySeer]) : Main.AllPlayerControls; PlayerControl[] targetList = SpecifyTarget != null @@ -1928,10 +1951,10 @@ public static Task DoNotifyRoles(PlayerControl SpecifySeer = null, PlayerControl { // Do nothing when the seer is not present in the game if (seer == null) continue; - + // Only non-modded players or player left if (seer.IsModded() || seer.PlayerId == OnPlayerLeftPatch.LeftPlayerId || seer.Data.Disconnected) continue; - + // Size of player roles string fontSize = isForMeeting ? "1.6" : "1.8"; string fontSizeDeathReason = "1.6"; @@ -1943,7 +1966,7 @@ public static Task DoNotifyRoles(PlayerControl SpecifySeer = null, PlayerControl var seerRoleClass = seer.GetRoleClass(); // Hide player names in during Mushroom Mixup if seer is alive and desync impostor - if (!CamouflageIsForMeeting && MushroomMixupIsActive && seer.IsAlive() && !seer.Is(Custom_Team.Impostor) && seer.HasDesyncRole()) + if (!CamouflageIsForMeeting && MushroomMixupIsActive && seer.IsAlive() && (!seer.Is(Custom_Team.Impostor) || Main.PlayerStates[seer.PlayerId].IsRandomizer) && seer.HasDesyncRole()) { seer.RpcSetNamePrivate("", force: NoCache); } @@ -2092,7 +2115,7 @@ public static Task DoNotifyRoles(PlayerControl SpecifySeer = null, PlayerControl //logger.Info("NotifyRoles-Loop2-" + target.GetNameWithRole() + ":START"); // Hide player names in during Mushroom Mixup if seer is alive and desync impostor - if (!CamouflageIsForMeeting && MushroomMixupIsActive && target.IsAlive() && !seer.Is(Custom_Team.Impostor) && seer.HasDesyncRole()) + if (!CamouflageIsForMeeting && MushroomMixupIsActive && target.IsAlive() && (!seer.Is(Custom_Team.Impostor) || Main.PlayerStates[seer.PlayerId].IsRandomizer) && seer.HasDesyncRole()) { realTarget.RpcSetNamePrivate("", seer, force: NoCache); } @@ -2123,7 +2146,7 @@ public static Task DoNotifyRoles(PlayerControl SpecifySeer = null, PlayerControl // ====== Seer know target role ====== bool KnowRoleTarget = ExtendedPlayerControl.KnowRoleTarget(seer, target); - + string TargetRoleText = KnowRoleTarget ? $"{seer.GetDisplayRoleAndSubName(target, false)}{GetProgressText(target)}\r\n" : ""; @@ -2298,9 +2321,9 @@ public static bool DeathReasonIsEnable(this PlayerState.DeathReason reason, bool { static bool BannedReason(PlayerState.DeathReason rso) { - return rso is PlayerState.DeathReason.Overtired + return rso is PlayerState.DeathReason.Overtired or PlayerState.DeathReason.etc - or PlayerState.DeathReason.Vote + or PlayerState.DeathReason.Vote or PlayerState.DeathReason.Gambled or PlayerState.DeathReason.Armageddon; } @@ -2308,6 +2331,8 @@ or PlayerState.DeathReason.Gambled return checkbanned ? !BannedReason(reason) : reason switch { PlayerState.DeathReason.Eaten => (CustomRoles.Pelican.IsEnable()), + PlayerState.DeathReason.FadedAway => (CustomRoles.LingeringPresence.IsEnable()), + PlayerState.DeathReason.AllergicReaction => (CustomRoles.Allergic.IsEnable()), PlayerState.DeathReason.Spell => (CustomRoles.Witch.IsEnable()), PlayerState.DeathReason.Hex => (CustomRoles.HexMaster.IsEnable()), PlayerState.DeathReason.Curse => (CustomRoles.CursedWolf.IsEnable()), @@ -2355,8 +2380,6 @@ var Breason when BannedReason(Breason) => false, PlayerState.DeathReason.BloodLet => CustomRoles.Bloodmoon.IsEnable(), PlayerState.DeathReason.Starved => CustomRoles.Baker.IsEnable(), PlayerState.DeathReason.Sacrificed => CustomRoles.Altruist.IsEnable(), - PlayerState.DeathReason.Electrocuted => CustomRoles.Shocker.IsEnable(), - PlayerState.DeathReason.Scavenged => CustomRoles.Scavenger.IsEnable(), PlayerState.DeathReason.Kill => true, _ => true, }; @@ -2397,16 +2420,16 @@ public static void AfterMeetingTasks() if (Burst.IsEnable) Burst.AfterMeetingTasks(); if (CustomRoles.CopyCat.HasEnabled()) CopyCat.UnAfterMeetingTasks(); // All crew hast to be before this + if (CustomRoles.Randomizer.HasEnabled()) Randomizer.AfterMeetingTasks(); } catch (Exception error) { Logger.Error($"Error after meeting: {error}", "AfterMeetingTasks"); } - + if (Options.AirshipVariableElectrical.GetBool()) AirshipElectricalDoors.Initialize(); - RPC.SyncDeadPassedMeetingList(); DoorsReset.ResetDoors(); // Empty Deden bug support Empty vent after meeting @@ -2415,7 +2438,6 @@ public static void AfterMeetingTasks() { ventilationSystem.PlayersInsideVents.Clear(); ventilationSystem.IsDirty = true; - // Will be synced by ShipStatus patch, SetAllVentInteractions } } public static string ToColoredString(this CustomRoles role) => Utils.ColorString(Utils.GetRoleColor(role), Translator.GetString($"{role}")); @@ -2427,10 +2449,27 @@ public static void ChangeInt(ref int ChangeTo, int input, int max) } public static void CountAlivePlayers(bool sendLog = false, bool checkGameEnd = false) { - int AliveImpostorCount = Main.AllAlivePlayerControls.Count(pc => pc.Is(Custom_Team.Impostor)); + // Adjusted Impostor Count Logic (Include Randomizer if LockedTeam is Impostor) + int AliveImpostorCount = Main.AllAlivePlayerControls.Count(pc => + { + var playerState = Main.PlayerStates[pc.PlayerId]; + return pc.Is(Custom_Team.Impostor) || + (playerState.IsRandomizer && playerState.LockedTeam == Custom_Team.Impostor); + }); + + // Adjusted Crewmate Count Logic (Include Randomizer based on LockedTeam) + int AliveCrewmateCount = Main.AllAlivePlayerControls.Count(pc => + { + var playerState = Main.PlayerStates[pc.PlayerId]; + return pc.Is(Custom_Team.Crewmate) || + (playerState.IsRandomizer && + (playerState.LockedTeam == Custom_Team.Crewmate || playerState.LockedTeam == Custom_Team.Neutral)); + }); + + // Log Impostor Count Changes if (Main.AliveImpostorCount != AliveImpostorCount) { - Logger.Info("Number Impostor left: " + AliveImpostorCount, "CountAliveImpostors"); + Logger.Info("Number of Impostors left: " + AliveImpostorCount, "CountAliveImpostors"); Main.AliveImpostorCount = AliveImpostorCount; LastImpostor.SetSubRole(); } @@ -2447,13 +2486,15 @@ public static void CountAlivePlayers(bool sendLog = false, bool checkGameEnd = f sb.Append($"{countTypes}:{AlivePlayersCount(countTypes)}/{playersCount}, "); } } - sb.Append($"All:{AllAlivePlayersCount}/{AllPlayersCount}"); + sb.Append($"Crewmates:{AliveCrewmateCount}, Impostors:{AliveImpostorCount}, All:{AllAlivePlayersCount}/{AllPlayersCount}"); Logger.Info(sb.ToString(), "CountAlivePlayers"); } if (AmongUsClient.Instance.AmHost && checkGameEnd) GameEndCheckerForNormal.Prefix(); } + + public static string GetVoteName(byte num) { // HasNotVoted = 255; @@ -2495,31 +2536,17 @@ public static void DumpLog() ProcessStartInfo psi = new("Explorer.exe") { Arguments = "/e,/select," + @filename.Replace("/", "\\") }; Process.Start(psi); } - - + + public static string SummaryTexts(byte id, bool disableColor = true, bool check = false) { - string name; - try - { - if (id == PlayerControl.LocalPlayer.PlayerId) name = DataManager.player.Customization.Name; - else name = Main.AllClientRealNames[GameData.Instance.GetPlayerById(id).ClientId]; - } - catch - { - Logger.Error("Failed to get name for {id} by real client names, try assign with AllPlayerNames", "Utils.SummaryTexts"); - name = Main.AllPlayerNames[id].RemoveHtmlTags().Replace("\r\n", string.Empty) ?? "ERROR"; - } - + var name = Main.AllPlayerNames[id].RemoveHtmlTags().Replace("\r\n", string.Empty); + if (id == PlayerControl.LocalPlayer.PlayerId) name = DataManager.player.Customization.Name; + else name = GetPlayerById(id)?.Data.PlayerName ?? name; var taskState = Main.PlayerStates?[id].TaskState; - // Impossible to output summarytexts for a player without playerState - if (!Main.PlayerStates.TryGetValue(id, out var playerState)) - { - Logger.Error("playerState for {id} not found", "Utils.SummaryTexts"); - return $"[{id}]" + name + " : ERROR"; - } + Main.PlayerStates.TryGetValue(id, out var playerState); string TaskCount; @@ -2630,7 +2657,7 @@ public static Color ShadeColor(this Color color, float Darkness = 0) public static void SetChatVisibleForEveryone() { if (!GameStates.IsInGame || !AmongUsClient.Instance.AmHost) return; - + MeetingHud.Instance = UnityEngine.Object.Instantiate(HudManager.Instance.MeetingPrefab); MeetingHud.Instance.ServerStart(PlayerControl.LocalPlayer.PlayerId); AmongUsClient.Instance.Spawn(MeetingHud.Instance, -2, SpawnFlags.None); @@ -2694,4 +2721,9 @@ public static void SetChatVisibleSpecific(this PlayerControl player) public static bool IsAllAlive => Main.PlayerStates.Values.All(state => state.countTypes == CountTypes.OutOfGame || !state.IsDead); public static int PlayersCount(CountTypes countTypes) => Main.PlayerStates.Values.Count(state => state.countTypes == countTypes); public static int AlivePlayersCount(CountTypes countTypes) => Main.AllAlivePlayerControls.Count(pc => pc.Is(countTypes)); + + internal static void SendMessage(string v, object playerId) + { + throw new NotImplementedException(); + } } diff --git a/Modules/VersionChecker.cs b/Modules/VersionChecker.cs index 538fe468f..74eaa2522 100644 --- a/Modules/VersionChecker.cs +++ b/Modules/VersionChecker.cs @@ -12,7 +12,7 @@ public static class VersionChecker public static void Check() { if (Ischecked) return; - + var amongUsVersion = Version.Parse(Application.version); Logger.Info($" {amongUsVersion}", "Among Us Version Check"); diff --git a/Modules/Zoom.cs b/Modules/Zoom.cs index 8ca5056f8..acbc64762 100644 --- a/Modules/Zoom.cs +++ b/Modules/Zoom.cs @@ -64,7 +64,7 @@ private static void SetZoomSize(bool times = false, bool reset = false) HudManager.Instance.UICamera.orthographicSize *= size; } DestroyableSingleton.Instance?.ShadowQuad?.gameObject?.SetActive((reset || Camera.main.orthographicSize == 3.0f) && PlayerControl.LocalPlayer.IsAlive()); - + if (ResetButtons) { ResolutionManager.ResolutionChanged.Invoke((float)Screen.width / Screen.height, Screen.width, Screen.height, Screen.fullScreen); diff --git a/Modules/dbConnect.cs b/Modules/dbConnect.cs index 7dd4177d6..a964db84d 100644 --- a/Modules/dbConnect.cs +++ b/Modules/dbConnect.cs @@ -1,10 +1,11 @@ -using AmongUs.Data; -using System; -using System.IO; +using System; using System.Text.Json; -using UnityEngine.Networking; +using System.IO; +using System.Reflection; using static TOHE.Translator; +using AmongUs.Data; using IEnumerator = System.Collections.IEnumerator; +using UnityEngine.Networking; namespace TOHE; @@ -14,7 +15,6 @@ public class dbConnect private static Dictionary UserType = []; private const string ApiUrl = "https://api.weareten.ca"; - private const string FallBackUrl = "https://tohe.niko233.me"; // Mirror of Enhanced Api public static IEnumerator Init() { @@ -90,7 +90,7 @@ private static void HandleFailure(FailedConnectReason errorReason) shouldDisconnect = false; // Show waring message - if (GameStates.IsLobby || GameStates.IsInGame) + if (GameStates.IsLobby || GameStates.InGame) { DestroyableSingleton.Instance.ShowPopUp(GetString("dbConnect.InitFailurePublic")); } @@ -104,7 +104,7 @@ private static void HandleFailure(FailedConnectReason errorReason) // Build not found shouldDisconnect = true; } - + if (shouldDisconnect) { if (AmongUsClient.Instance.mode != InnerNet.MatchMakerModes.None) @@ -116,12 +116,8 @@ private static void HandleFailure(FailedConnectReason errorReason) } } - private static string decidedApiToken = ""; private static string GetToken() { - if (decidedApiToken != "") - return decidedApiToken; - string apiToken = ""; Assembly assembly = Assembly.GetExecutingAssembly(); @@ -144,29 +140,13 @@ private static string GetToken() // Process the content as needed apiToken = content.Replace("API_TOKEN=", string.Empty).Trim(); } - } - - // Check if the token contains spaces or is empty - if (string.IsNullOrWhiteSpace(apiToken) || apiToken.Contains(' ')) - { - Logger.Info("No api token provided in token.env", "db.Connect"); - if (!string.IsNullOrEmpty(Main.FileHash) && Main.FileHash.Length >= 16) - { - string prefix = Main.FileHash.Substring(0, 8); - string suffix = Main.FileHash.Substring(Main.FileHash.Length - 8, 8); - apiToken = $"hash{prefix}{suffix}"; - } - else + if (stream == null || apiToken == "") { - Logger.Info("Main.FileHash is not valid for generating token.", "db.Connect"); - return ""; + Logger.Warn("Embedded resource not found.", "apiToken.error"); } } - - decidedApiToken = apiToken; return apiToken; } - private static IEnumerator GetRoleTable() { var tempUserType = new Dictionary(); // Create a temporary dictionary @@ -177,74 +157,54 @@ private static IEnumerator GetRoleTable() yield return null; } - string[] apiUrls = [ApiUrl, FallBackUrl]; - int maxAttempts = !InitOnce ? 4 : 2; - int attempt = 0; - bool success = false; + string apiUrl = ApiUrl; + string endpoint = $"{apiUrl}/userInfo?token={apiToken}"; - while (attempt < maxAttempts && !success) - { - string apiUrl = apiUrls[attempt % 2]; - string endpoint = $"{apiUrl}/userInfo?token={apiToken}"; + UnityWebRequest webRequest = UnityWebRequest.Get(endpoint); - UnityWebRequest webRequest = UnityWebRequest.Get(endpoint); - Logger.Info($"Fetching UserInfo from {apiUrls[attempt % 2]}", "GetRoleTable"); + yield return webRequest.SendWebRequest(); - yield return webRequest.SendWebRequest(); + if (webRequest.result != UnityWebRequest.Result.Success) + { + Logger.Error($"Error in fetching the User List: {webRequest.error}", "GetRoleTable.error"); + yield return null; + } - if (webRequest.result == UnityWebRequest.Result.Success) + try + { + var userList = JsonSerializer.Deserialize>>(webRequest.downloadHandler.text); + foreach (var user in userList) { - try - { - var userList = JsonSerializer.Deserialize>>(webRequest.downloadHandler.text); - foreach (var user in userList) - { - var userData = user; - if (!DevManager.IsDevUser(userData["friendcode"].ToString())) - { - DevManager.DevUserList.Add(new( - code: userData["friendcode"].ToString(), - color: userData["color"].ToString(), - tag: ToAutoTranslate(userData["overhead_tag"]), - userType: userData["type"].ToString(), - isUp: userData["isUP"].GetInt32() == 1, - isDev: userData["isDev"].GetInt32() == 1, - deBug: userData["debug"].GetInt32() == 1, - colorCmd: userData["colorCmd"].GetInt32() == 1, - upName: userData["name"].ToString())); - } - tempUserType[userData["friendcode"].ToString()] = userData["type"].ToString(); // Store the data in the temporary dictionary - } - if (tempUserType.Count > 1) - { - UserType = tempUserType; // Replace userType with the temporary dictionary - success = true; - } - else if (!InitOnce) - { - Logger.Error($"Incoming RoleTable is null, cannot init!", "GetRoleTable.error"); - } - } - catch (Exception ex) + var userData = user; + if (!DevManager.IsDevUser(userData["friendcode"].ToString())) { - Logger.Error($"Error processing response: {ex.Message}", "GetRoleTable.error"); - } - finally - { - webRequest.Dispose(); + DevManager.DevUserList.Add(new( + code: userData["friendcode"].ToString(), + color: userData["color"].ToString(), + tag: ToAutoTranslate(userData["overhead_tag"]), + userType: userData["type"].ToString(), + isUp: userData["isUP"].GetInt32() == 1, + isDev: userData["isDev"].GetInt32() == 1, + deBug: userData["debug"].GetInt32() == 1, + colorCmd: userData["colorCmd"].GetInt32() == 1, + upName: userData["name"].ToString())); } + tempUserType[userData["friendcode"].ToString()] = userData["type"].ToString(); // Store the data in the temporary dictionary } - else + if (tempUserType.Count > 1) + UserType = tempUserType; // Replace userType with the temporary dictionary + else if (!InitOnce) { - Logger.Error($"Error in fetching the User List: {webRequest.error}", "GetRoleTable.error"); + Logger.Error($"Incoming RoleTable is null, cannot init!", "GetRoleTable.error"); } - - attempt++; } - - if (!success) + catch (Exception ex) + { + Logger.Error($"Error processing response: {ex.Message}", "GetRoleTable.error"); + } + finally { - Logger.Error("Failed to fetch User List from both primary and fallback URLs.", "GetRoleTable.error"); + webRequest.Dispose(); } } @@ -282,52 +242,34 @@ private static IEnumerator GetEACList() yield break; } - string[] apiUrls = { ApiUrl, FallBackUrl }; - int maxAttempts = !InitOnce ? 4 : 2; - int attempt = 0; - bool success = false; - - while (attempt < maxAttempts && !success) - { - string apiUrl = apiUrls[attempt % 2]; - string endpoint = $"{apiUrl}/eac?token={apiToken}"; - - Logger.Info($"Fetching EAC List from {apiUrls[attempt % 2]}", "GetEACList"); - UnityWebRequest webRequest = UnityWebRequest.Get(endpoint); + string apiUrl = ApiUrl; + string endpoint = $"{apiUrl}/eac?token={apiToken}"; - // Send the request - yield return webRequest.SendWebRequest(); + UnityWebRequest webRequest = UnityWebRequest.Get(endpoint); - // Check for errors - if (webRequest.result == UnityWebRequest.Result.Success) - { - try - { - var tempEACDict = JsonSerializer.Deserialize>>(webRequest.downloadHandler.text); - BanManager.EACDict = [.. BanManager.EACDict, .. tempEACDict]; // Merge the temporary list with BanManager.EACDict - success = true; - } - catch (JsonException jsonEx) - { - // If deserialization fails - Logger.Error($"Error deserializing JSON: {jsonEx.Message}", "GetEACList.error"); - } - finally - { - webRequest.Dispose(); - } - } - else - { - Logger.Error($"Error in fetching the EAC List: {webRequest.error}", "GetEACList.error"); - } + // Send the request + yield return webRequest.SendWebRequest(); - attempt++; + // Check for errors + if (webRequest.result != UnityWebRequest.Result.Success) + { + Logger.Error($"Error in fetching the EAC List: {webRequest.error}", "GetEACList.error"); + yield break; } - if (!success) + try + { + var tempEACDict = JsonSerializer.Deserialize>>(webRequest.downloadHandler.text); + BanManager.EACDict = [.. BanManager.EACDict, .. tempEACDict]; // Merge the temporary list with BanManager.EACDict + } + catch (JsonException jsonEx) + { + // If deserialization fails + Logger.Error($"Error deserializing JSON: {jsonEx.Message}", "GetEACList.error"); + } + finally { - Logger.Error("Failed to fetch EAC List from both primary and fallback URLs.", "GetEACList.error"); + webRequest.Dispose(); } } @@ -347,7 +289,6 @@ private static bool CanAccessDev(string friendCode) return true; } - [Obfuscation(Exclude = true)] private enum FailedConnectReason { Build_Not_Specified, diff --git a/Patches/AnnouncementPatch.cs b/Patches/AnnouncementPatch.cs index d883965af..c0497fc00 100644 --- a/Patches/AnnouncementPatch.cs +++ b/Patches/AnnouncementPatch.cs @@ -1,15 +1,14 @@ -using AmongUs.Data; +using System; +using System.Collections; +using AmongUs.Data; using AmongUs.Data.Player; using Assets.InnerNet; -using BepInEx.Unity.IL2CPP.Utils.Collections; using Il2CppInterop.Runtime.InteropTypes.Arrays; -using LibCpp2IL; -using System; -using System.Collections; -using System.IO; +using BepInEx.Unity.IL2CPP.Utils.Collections; using System.Text.Json; using UnityEngine; using UnityEngine.Networking; +using LibCpp2IL; namespace TOHE; @@ -42,7 +41,7 @@ public Announcement ToAnnouncement() return result; } public static List AllModNews = []; - public static string ModNewsURL = "https://raw.githubusercontent.com/EnhancedNetwork/TownofHost-Enhanced/refs/heads/main/Resources/Announcements/modNews-"; + public static string ModNewsURL = "https://github.com/EnhancedNetwork/TownofHost-Enhanced/blob/main/Resources/Announcements/modNews-"; static bool downloaded = false; public ModNews(int Number, string Title, string SubTitle, string ShortTitle, string Text, string Date) { @@ -87,77 +86,28 @@ static IEnumerator FetchBlacklist() if (request.isNetworkError || request.isHttpError) { downloaded = false; - Logger.Error("ModNews Error Fetch:" + request.responseCode.ToString(), "ModNews"); - LoadModNewsFromResources(); + Logger.Info("ModNews Error Fetch:" + request.responseCode.ToString(), "ModNews"); yield break; } - try - { - using var jsonDocument = JsonDocument.Parse(request.downloadHandler.text); - var newsArray = jsonDocument.RootElement.GetProperty("News"); - - foreach (var newsElement in newsArray.EnumerateArray()) - { - var number = int.Parse(newsElement.GetProperty("Number").GetString()); - var title = newsElement.GetProperty("Title").GetString(); - var subTitle = newsElement.GetProperty("Subtitle").GetString(); - var shortTitle = newsElement.GetProperty("Short").GetString(); - var body = newsElement.GetProperty("Body").EnumerateArray().ToStringEnumerable().ToString(); - var dateString = newsElement.GetProperty("Date").GetString(); - // Create ModNews object - ModNews _ = new(number, title, subTitle, shortTitle, body, dateString); - } - } - catch (Exception ex) + var jsonDocument = JsonDocument.Parse(request.downloadHandler.text); + var newsArray = jsonDocument.RootElement.GetProperty("News"); + + foreach (var newsElement in newsArray.EnumerateArray()) { - Logger.Exception(ex, "ModNews"); - Logger.Error("Failed to load mod info from github, load from local instead", "ModNews"); - // Use local Mod news instead - LoadModNewsFromResources(); + var number = int.Parse(newsElement.GetProperty("Number").GetString()); + var title = newsElement.GetProperty("Title").GetString(); + var subTitle = newsElement.GetProperty("Subtitle").GetString(); + var shortTitle = newsElement.GetProperty("Short").GetString(); + var body = newsElement.GetProperty("Body").EnumerateArray().ToStringEnumerable().ToString(); + var dateString = newsElement.GetProperty("Date").GetString(); + // Create ModNews object + ModNews _ = new(number, title, subTitle, shortTitle, body, dateString); } } __result = Effects.Sequence(FetchBlacklist().WrapToIl2Cpp(), __result); } - private static void LoadModNewsFromResources() - { - string filename = TranslationController.Instance.currentLanguage.languageID switch - { - SupportedLangs.German => "de_DE.json", - SupportedLangs.Latam => "es_419.json", - SupportedLangs.Spanish => "es_ES.json", - SupportedLangs.Filipino => "fil_PH.json", - SupportedLangs.French => "fr_FR.json", - SupportedLangs.Italian => "it_IT.json", - SupportedLangs.Japanese => "ja_JP.json", - SupportedLangs.Korean => "ko_KR.json", - SupportedLangs.Dutch => "nl_NL.json", - SupportedLangs.Brazilian => "pt_BR.json", - SupportedLangs.Russian => "ru_RU.json", - SupportedLangs.SChinese => "zh_CN.json", - SupportedLangs.TChinese => "zh_TW.json", - _ => "en_US.json", //English and any other unsupported language - }; - - var assembly = System.Reflection.Assembly.GetExecutingAssembly(); - using Stream resourceStream = assembly.GetManifestResourceStream("TOHE.Resources.Announcements.modNews-" + filename); - using StreamReader reader = new(resourceStream); - using var jsonDocument = JsonDocument.Parse(reader.ReadToEnd()); - var newsArray = jsonDocument.RootElement.GetProperty("News"); - - foreach (var newsElement in newsArray.EnumerateArray()) - { - var number = int.Parse(newsElement.GetProperty("Number").GetString()); - var title = newsElement.GetProperty("Title").GetString(); - var subTitle = newsElement.GetProperty("Subtitle").GetString(); - var shortTitle = newsElement.GetProperty("Short").GetString(); - var body = newsElement.GetProperty("Body").EnumerateArray().ToStringEnumerable().ToString(); - var dateString = newsElement.GetProperty("Date").GetString(); - // Create ModNews object - ModNews _ = new(number, title, subTitle, shortTitle, body, dateString); - } - } [HarmonyPatch(typeof(PlayerAnnouncementData), nameof(PlayerAnnouncementData.SetAnnouncements)), HarmonyPrefix] public static bool SetModAnnouncements_Prefix(PlayerAnnouncementData __instance, [HarmonyArgument(0)] ref Il2CppReferenceArray aRange) diff --git a/Patches/AprilFoolsModePatch.cs b/Patches/AprilFoolsModePatch.cs index 6fcdab288..75d5686c4 100644 --- a/Patches/AprilFoolsModePatch.cs +++ b/Patches/AprilFoolsModePatch.cs @@ -8,7 +8,7 @@ public static class ShouldShowTogglePatch { public static void Postfix(ref bool __result) { - __result = false; + __result = true; } } #region GameManager Patches @@ -22,7 +22,7 @@ public static void Postfix(ref PlayerBodyTypes __result) __result = PlayerBodyTypes.Horse; return; } - if (Main.LongMode.Value) + if (AprilFoolsMode.ShouldLongAround()) { __result = PlayerBodyTypes.Long; return; @@ -43,7 +43,7 @@ public static void Postfix(ref PlayerBodyTypes __result, [HarmonyArgument(0)] Pl __result = PlayerBodyTypes.Horse; return; } - if (Main.LongMode.Value) + if (AprilFoolsMode.ShouldLongAround()) { __result = PlayerBodyTypes.Long; return; @@ -61,7 +61,7 @@ public static void Postfix(ref PlayerBodyTypes __result, [HarmonyArgument(0)] Pl __result = PlayerBodyTypes.Horse; return; } - else if (Main.LongMode.Value) + else if (AprilFoolsMode.ShouldLongAround()) { if (player.Data.Role.IsImpostor) { @@ -142,9 +142,9 @@ public static bool LongBoyNeckSize_Prefix(LongBoiPlayerBody __instance, ref floa [HarmonyPrefix] public static bool CheckLongMode_Prefix(out bool __result, ref string cosmeticID) { - if (AprilFoolsMode.ShouldHorseAround()) + if (Main.HorseMode.Value) { - __result = true; + __result = false; return false; } @@ -159,4 +159,4 @@ public static bool CheckLongMode_Prefix(out bool __result, ref string cosmeticID return false; } } -#endregion +#endregion \ No newline at end of file diff --git a/Patches/ChatBubblePatch.cs b/Patches/ChatBubblePatch.cs index 91b1a3f97..d6c859332 100644 --- a/Patches/ChatBubblePatch.cs +++ b/Patches/ChatBubblePatch.cs @@ -17,34 +17,34 @@ class ChatBubbleSetNamePatch { public static void Postfix(ChatBubble __instance, [HarmonyArgument(1)] bool isDead, [HarmonyArgument(2)] bool voted) { - if (Main.DarkTheme.Value) - { - if (isDead) - __instance.Background.color = new(0.1f, 0.1f, 0.1f, 0.6f); - else - __instance.Background.color = new(0.1f, 0.1f, 0.1f, 1f); - - __instance.TextArea.color = Color.white; - } - - if (!GameStates.IsInGame) return; - var seer = PlayerControl.LocalPlayer; var target = __instance.playerInfo.Object; - if (seer.PlayerId == target.PlayerId) - { + if (GameStates.IsInGame && !voted && seer.PlayerId == target.PlayerId) __instance.NameText.color = seer.GetRoleColor(); - return; - } - // Dog shit var seerRoleClass = seer.GetRoleClass(); + // if based role is Shapeshifter and is Desync Shapeshifter if (seerRoleClass?.ThisRoleBase.GetRoleTypes() == RoleTypes.Shapeshifter && seer.HasDesyncRole()) { + // When target is impostor, set name color as white + __instance.NameText.color = Color.white; + } + if (Main.PlayerStates[seer.PlayerId].IsRandomizer || Main.PlayerStates[target.PlayerId].IsRandomizer) + { + // When target is impostor, set name color as white __instance.NameText.color = Color.white; } + if (Main.DarkTheme.Value) + { + if (isDead) + __instance.Background.color = new(0.1f, 0.1f, 0.1f, 0.6f); + else + __instance.Background.color = new(0.1f, 0.1f, 0.1f, 1f); + + __instance.TextArea.color = Color.white; + } } } diff --git a/Patches/ChatCommandPatch.cs b/Patches/ChatCommandPatch.cs index b26ee0a83..9651787ce 100644 --- a/Patches/ChatCommandPatch.cs +++ b/Patches/ChatCommandPatch.cs @@ -11,6 +11,7 @@ using TOHE.Roles.Crewmate; using TOHE.Roles.Impostor; using TOHE.Roles.Neutral; +using Il2CppSystem.Linq; using UnityEngine; using static TOHE.Translator; @@ -44,7 +45,7 @@ public static bool Prefix(ChatController __instance) var text = __instance.freeChatField.textArea.text; if (ChatHistory.Count == 0 || ChatHistory[^1] != text) ChatHistory.Add(text); ChatControllerUpdatePatch.CurrentHistorySelection = ChatHistory.Count; - string[] args = text.Trim().Split(' '); + string[] args = text.Split(' '); string subArgs = ""; string subArgs2 = ""; var canceled = false; @@ -63,12 +64,13 @@ public static bool Prefix(ChatController __instance) if (President.EndMsg(PlayerControl.LocalPlayer, text)) goto Canceled; if (Inspector.InspectCheckMsg(PlayerControl.LocalPlayer, text)) goto Canceled; if (Pirate.DuelCheckMsg(PlayerControl.LocalPlayer, text)) goto Canceled; + if (Evolver.EvolverCheckMsg(PlayerControl.LocalPlayer, text)) goto Canceled; + if (Summoner.SummonerCheckMsg(PlayerControl.LocalPlayer, text)) goto Canceled; if (PlayerControl.LocalPlayer.GetRoleClass() is Councillor cl && cl.MurderMsg(PlayerControl.LocalPlayer, text)) goto Canceled; if (Nemesis.NemesisMsgCheck(PlayerControl.LocalPlayer, text)) goto Canceled; if (Retributionist.RetributionistMsgCheck(PlayerControl.LocalPlayer, text)) goto Canceled; if (Medium.MsMsg(PlayerControl.LocalPlayer, text)) goto Canceled; if (PlayerControl.LocalPlayer.GetRoleClass() is Swapper sw && sw.SwapMsg(PlayerControl.LocalPlayer, text)) goto Canceled; - if (PlayerControl.LocalPlayer.GetRoleClass() is Dictator dt && dt.ExilePlayer(PlayerControl.LocalPlayer, text)) goto Canceled; Directory.CreateDirectory(modTagsFiles); Directory.CreateDirectory(vipTagsFiles); Directory.CreateDirectory(sponsorTagsFiles); @@ -228,18 +230,12 @@ public static bool Prefix(ChatController __instance) case "/命名为": canceled = true; if (args.Length < 1) break; - if (args.Skip(1).Join(delimiter: " ").Length is > 10 or < 1) - { + if (args.Skip(1).Join(delimiter: " ").Length is > 10 or < 1) { Utils.SendMessage(GetString("Message.AllowNameLength"), PlayerControl.LocalPlayer.PlayerId); break; } - else - { - var temp = args.Skip(1).Join(delimiter: " "); - Main.HostRealName = temp; - Main.AllPlayerNames[PlayerControl.LocalPlayer.PlayerId] = temp; - Utils.SendMessage(string.Format(GetString("Message.SetName"), temp), PlayerControl.LocalPlayer.PlayerId); - } + else Main.HostRealName = args.Skip(1).Join(delimiter: " "); + Utils.SendMessage(string.Format(GetString("Message.SetName"), args.Skip(1).Join(delimiter: " ")), PlayerControl.LocalPlayer.PlayerId); break; case "/hn": @@ -353,8 +349,7 @@ public static bool Prefix(ChatController __instance) case "/成为": canceled = true; subArgs = text.Remove(0, 3); - if (!PlayerControl.LocalPlayer.FriendCode.GetDevUser().IsUp) - { + if (!PlayerControl.LocalPlayer.FriendCode.GetDevUser().IsUp) { Utils.SendMessage($"{GetString("InvalidPermissionCMD")}", PlayerControl.LocalPlayer.PlayerId); break; } @@ -391,13 +386,8 @@ public static bool Prefix(ChatController __instance) case "/玩家": canceled = true; subArgs = args.Length < 2 ? "" : args[1]; + Utils.SendMessage(GetString("Message.MaxPlayers") + subArgs); var numbereer = Convert.ToByte(subArgs); - if (numbereer > 15 && GameStates.IsVanillaServer) - { - Utils.SendMessage(GetString("Message.MaxPlayersFailByRegion")); - break; - } - Utils.SendMessage(GetString("Message.MaxPlayers") + numbereer); if (GameStates.IsNormalGame) GameOptionsManager.Instance.currentNormalGameOptions.MaxPlayers = numbereer; @@ -1073,7 +1063,7 @@ public static bool Prefix(ChatController __instance) if (!(DebugModeManager.AmDebugger && GameStates.IsInGame)) break; if (GameStates.IsOnlineGame && !PlayerControl.LocalPlayer.FriendCode.GetDevUser().DeBug) break; subArgs = text.Remove(0, 11); - var setRole = FixRoleNameInput(subArgs).ToLower().Trim().Replace(" ", string.Empty); + var setRole = FixRoleNameInput(subArgs).ToLower().Trim().Replace(" ", string.Empty); Logger.Info(setRole, "changerole Input"); foreach (var rl in CustomRolesHelper.AllRoles) { @@ -1083,7 +1073,7 @@ public static bool Prefix(ChatController __instance) if (setRole == roleName) { PlayerControl.LocalPlayer.GetRoleClass()?.OnRemove(PlayerControl.LocalPlayer.PlayerId); - PlayerControl.LocalPlayer.RpcChangeRoleBasis(rl); + PlayerControl.LocalPlayer.RpcSetRole(rl.GetRoleTypes(), true); PlayerControl.LocalPlayer.RpcSetCustomRole(rl); PlayerControl.LocalPlayer.GetRoleClass().OnAdd(PlayerControl.LocalPlayer.PlayerId); Utils.SendMessage(string.Format("Debug Set your role to {0}", rl.ToString()), PlayerControl.LocalPlayer.PlayerId); @@ -1244,7 +1234,7 @@ static void DetermineResults() for (int i = 0; i < (tied.Count() - 1); i++) { - msg += "\n" + tied.ElementAt(i).Key + PollQuestions[tied.ElementAt(i).Key] + " & "; + msg += "\n" + tied.ElementAt(i).Key + PollQuestions[tied.ElementAt(i).Key] + " & "; } msg += "\n" + tied.Last().Key + PollQuestions[tied.Last().Key]; @@ -1301,7 +1291,7 @@ static void DetermineResults() Logger.Info($"Poll message: {msg}", "MEssapoll"); - Utils.SendMessage(msg, title: !Longtitle ? tytul : altTitle); + Utils.SendMessage(msg, title: !Longtitle ? tytul: altTitle); Main.Instance.StartCoroutine(StartPollCountdown()); @@ -1385,7 +1375,7 @@ static Color32 RndCLR() var rand = IRandom.Instance; int botChoice = rand.Next(1, 101); var coinSide = (botChoice < 51) ? GetString("Heads") : GetString("Tails"); - Utils.SendMessage(string.Format(GetString("CoinFlipResult"), coinSide), PlayerControl.LocalPlayer.PlayerId); + Utils.SendMessage(string.Format(GetString("CoinFlipResult"),coinSide), PlayerControl.LocalPlayer.PlayerId); break; } case "/gno": @@ -1546,39 +1536,6 @@ static Color32 RndCLR() } Utils.SendMessage("" + str + "", PlayerControl.LocalPlayer.PlayerId, Utils.ColorString(Utils.GetRoleColor(CustomRoles.Medium), GetString("8BallTitle"))); break; - case "/start": - case "/开始": - case "/старт": - canceled = true; - if (!GameStates.IsLobby) - { - Utils.SendMessage(GetString("Message.OnlyCanUseInLobby"), PlayerControl.LocalPlayer.PlayerId); - break; - } - if (GameStates.IsCountDown) - { - Utils.SendMessage(GetString("StartCommandCountdown"), PlayerControl.LocalPlayer.PlayerId); - break; - } - subArgs = args.Length < 2 ? "" : args[1]; - if (string.IsNullOrEmpty(subArgs) || !int.TryParse(subArgs, out int countdown)) - { - countdown = 5; - } - else - { - countdown = int.Parse(subArgs); - } - if (countdown < 0 || countdown > 99) - { - Utils.SendMessage(string.Format(GetString("StartCommandInvalidCountdown"), 0, 99), PlayerControl.LocalPlayer.PlayerId); - break; - } - GameStartManager.Instance.BeginGame(); - GameStartManager.Instance.countDownTimer = countdown; - Utils.SendMessage(string.Format(GetString("StartCommandStarted"), PlayerControl.LocalPlayer.name)); - Logger.Info("Game Starting", "ChatCommand"); - break; default: Main.isChatCommand = false; @@ -2018,12 +1975,12 @@ public static void SendRolesInfo(string role, byte playerId, bool isDev = false, if (rl.IsGhostRole() && !rl.IsAdditionRole() && isDev && (rl.GetCount() >= 1 && rl.GetMode() > 0)) { byte pid = playerId == 255 ? (byte)0 : playerId; - CustomRoles setrole = rl.GetCustomRoleTeam() switch + CustomRoles setrole = rl.GetCustomRoleTeam() switch { Custom_Team.Impostor => CustomRoles.ImpostorTOHE, _ => CustomRoles.CrewmateTOHE - }; + RoleAssign.SetRoles.Remove(pid); RoleAssign.SetRoles.Add(pid, setrole); GhostRoleAssign.forceRole[pid] = rl; @@ -2031,6 +1988,7 @@ public static void SendRolesInfo(string role, byte playerId, bool isDev = false, devMark = "▲"; } + if (isUp) return; } var Des = rl.GetInfoLong(); @@ -2064,14 +2022,16 @@ public static void OnReceiveChat(PlayerControl player, string text, out bool can if (!Blackmailer.CheckBlackmaile(player)) ChatManager.SendMessage(player, text); + + + if (text.StartsWith("\n")) text = text[1..]; //if (!text.StartsWith("/")) return; string[] args = text.Split(' '); string subArgs = ""; string subArgs2 = ""; - //if (text.Length >= 3) if (text[..2] == "/r" && text[..3] != "/rn") args[0] = "/r"; - // if (SpamManager.CheckSpam(player, text)) return; + // Role-specific message handling if (GuessManager.GuesserMsg(player, text)) { canceled = true; Logger.Info($"Is Guesser command", "OnReceiveChat"); return; } if (player.GetRoleClass() is Judge jd && jd.TrialMsg(player, text)) { canceled = true; Logger.Info($"Is Judge command", "OnReceiveChat"); return; } if (President.EndMsg(player, text)) { canceled = true; Logger.Info($"Is President command", "OnReceiveChat"); return; } @@ -2082,12 +2042,17 @@ public static void OnReceiveChat(PlayerControl player, string text, out bool can if (Medium.MsMsg(player, text)) { Logger.Info($"Is Medium command", "OnReceiveChat"); return; } if (Nemesis.NemesisMsgCheck(player, text)) { Logger.Info($"Is Nemesis Revenge command", "OnReceiveChat"); return; } if (Retributionist.RetributionistMsgCheck(player, text)) { Logger.Info($"Is Retributionist Revenge command", "OnReceiveChat"); return; } - if (player.GetRoleClass() is Dictator dt && dt.ExilePlayer(player, text)) { canceled = true; Logger.Info($"Is Dictator command", "OnReceiveChat"); return; } + if (Evolver.EvolverCheckMsg(player, text)) { canceled = true; Logger.Info($"Is Evolver command", "OnReceiveChat"); return; } + if (Summoner.SummonerCheckMsg(player, text)) { canceled = true; Logger.Info($"Command handled for Summoner {player.PlayerId}.", "OnReceiveChat"); return;} + + + // Create directories for chat logs if necessary Directory.CreateDirectory(modTagsFiles); Directory.CreateDirectory(vipTagsFiles); Directory.CreateDirectory(sponsorTagsFiles); + if (Blackmailer.CheckBlackmaile(player) && player.IsAlive() && !player.IsHost()) { Logger.Info($"This player (id {player.PlayerId}) was Blackmailed", "OnReceiveChat"); @@ -2096,6 +2061,7 @@ public static void OnReceiveChat(PlayerControl player, string text, out bool can canceled = true; return; } + // Summoner-Specific Message Blocking and Forwarding switch (args[0]) { @@ -2126,7 +2092,7 @@ public static void OnReceiveChat(PlayerControl player, string text, out bool can { var Des = player.GetRoleInfo(true); var title = $"" + role.GetRoleTitle() + "\n"; - var Conf = new StringBuilder(); + var Conf = new StringBuilder(); var Sub = new StringBuilder(); var rlHex = Utils.GetRoleColorCode(role); var SubTitle = $"" + GetString("YourAddon") + "\n"; @@ -2145,7 +2111,7 @@ public static void OnReceiveChat(PlayerControl player, string text, out bool can if (Sub.ToString() != string.Empty) { var ACleared = Sub.ToString().Remove(0, 2); - ACleared = ACleared.Length > 1200 ? $"" + ACleared.RemoveHtmlTags() + "" : ACleared; + ACleared = ACleared.Length > 1200 ? $"" + ACleared.RemoveHtmlTags() + "": ACleared; Sub.Clear().Append(ACleared); } @@ -2794,7 +2760,7 @@ public static void OnReceiveChat(PlayerControl player, string text, out bool can Utils.SendMessage(GetString("ColorCommandNoLobby"), player.PlayerId); break; } - if (!Options.GradientTagsOpt.GetBool()) + if (!Options.GradientTagsOpt.GetBool()) { subArgs = args.Length != 2 ? "" : args[1]; if (string.IsNullOrEmpty(subArgs) || !Utils.CheckColorHex(subArgs)) @@ -2853,8 +2819,8 @@ public static void OnReceiveChat(PlayerControl player, string text, out bool can Utils.SendMessage(GetString("VipColorCommandNoLobby"), player.PlayerId); break; } - if (!Options.GradientTagsOpt.GetBool()) - { + if (!Options.GradientTagsOpt.GetBool()) + { subArgs = args.Length != 2 ? "" : args[1]; if (string.IsNullOrEmpty(subArgs) || !Utils.CheckColorHex(subArgs)) { @@ -2868,7 +2834,7 @@ public static void OnReceiveChat(PlayerControl player, string text, out bool can Logger.Warn($"File Not exist, creating file at {vipTagsFiles}/{player.FriendCode}.txt", "vipcolor"); File.Create(colorFilePathh).Close(); } - + File.WriteAllText(colorFilePathh, $"{subArgs}"); break; } @@ -2981,7 +2947,7 @@ public static void OnReceiveChat(PlayerControl player, string text, out bool can break; } - + if (!Options.EnableVoteCommand.GetBool()) { Utils.SendMessage(GetString("VoteDisabled"), player.PlayerId); @@ -3114,7 +3080,7 @@ public static void OnReceiveChat(PlayerControl player, string text, out bool can else { var rand = IRandom.Instance; - int botChoice = rand.Next(1, 101); + int botChoice = rand.Next(1,101); var coinSide = (botChoice < 51) ? GetString("Heads") : GetString("Tails"); Utils.SendMessage(string.Format(GetString("CoinFlipResult"), coinSide), player.PlayerId); break; @@ -3295,7 +3261,7 @@ public static void OnReceiveChat(PlayerControl player, string text, out bool can break; } - + if (byte.TryParse(subArgs, out byte meid)) { @@ -3323,51 +3289,6 @@ public static void OnReceiveChat(PlayerControl player, string text, out bool can } break; - case "/start": - case "/开始": - case "/старт": - if (!GameStates.IsLobby) - { - Utils.SendMessage(GetString("Message.OnlyCanUseInLobby"), player.PlayerId); - break; - } - - if (!Utils.IsPlayerModerator(player.FriendCode)) - { - Utils.SendMessage(GetString("StartCommandNoAccess"), player.PlayerId); - - break; - - } - if (Options.ApplyModeratorList.GetValue() == 0 || Options.AllowStartCommand.GetBool() == false) - { - Utils.SendMessage(GetString("StartCommandDisabled"), player.PlayerId); - break; - } - if (GameStates.IsCountDown) - { - Utils.SendMessage(GetString("StartCommandCountdown"), player.PlayerId); - break; - } - subArgs = args.Length < 2 ? "" : args[1]; - if (string.IsNullOrEmpty(subArgs) || !int.TryParse(subArgs, out int countdown)) - { - countdown = 5; - } - else - { - countdown = int.Parse(subArgs); - } - if (countdown < Options.StartCommandMinCountdown.CurrentValue || countdown > Options.StartCommandMaxCountdown.CurrentValue) - { - Utils.SendMessage(string.Format(GetString("StartCommandInvalidCountdown"), Options.StartCommandMinCountdown.CurrentValue, Options.StartCommandMaxCountdown.CurrentValue), player.PlayerId); - break; - } - GameStartManager.Instance.BeginGame(); - GameStartManager.Instance.countDownTimer = countdown; - Utils.SendMessage(string.Format(GetString("StartCommandStarted"), player.name)); - break; - default: if (SpamManager.CheckSpam(player, text)) return; @@ -3438,13 +3359,6 @@ public static void Postfix(ChatController __instance) player.SetName(name); } - if (clientId == AmongUsClient.Instance.ClientId || sendTo == PlayerControl.LocalPlayer.PlayerId) - { - player.SetName(title); - DestroyableSingleton.Instance.Chat.AddChat(player, msg, false); - player.SetName(name); - return; - } var writer = CustomRpcSender.Create("MessagesToSend", SendOption.None); writer.StartMessage(clientId); @@ -3465,18 +3379,16 @@ public static void Postfix(ChatController __instance) __instance.timeSinceLastMessage = 0f; } } - [HarmonyPatch(typeof(FreeChatInputField), nameof(FreeChatInputField.UpdateCharCount))] internal class UpdateCharCountPatch { public static void Postfix(FreeChatInputField __instance) { int length = __instance.textArea.text.Length; - __instance.charCountText.SetText(length <= 0 ? GetString("ThankYouForUsingTOHE") : $"{length}/{__instance.textArea.characterLimit}"); - __instance.charCountText.enableWordWrapping = false; - if (length < (AmongUsClient.Instance.AmHost ? 888 : 444)) + __instance.charCountText.SetText($"{length}/{__instance.textArea.characterLimit}"); + if (length < (AmongUsClient.Instance.AmHost ? 888 : 250)) __instance.charCountText.color = Color.black; - else if (length < (AmongUsClient.Instance.AmHost ? 1111 : 777)) + else if (length < (AmongUsClient.Instance.AmHost ? 999 : 300)) __instance.charCountText.color = new Color(1f, 1f, 0f, 1f); else __instance.charCountText.color = Color.red; diff --git a/Patches/ChatControlPatch.cs b/Patches/ChatControlPatch.cs index 1ca3d4b00..a6296833d 100644 --- a/Patches/ChatControlPatch.cs +++ b/Patches/ChatControlPatch.cs @@ -36,8 +36,7 @@ public static void Postfix(ChatController __instance) if (!__instance.freeChatField.textArea.hasFocus) return; if (!GameStates.IsModHost) return; - __instance.freeChatField.textArea.characterLimit = AmongUsClient.Instance.AmHost ? 2000 : 1200; - + __instance.freeChatField.textArea.characterLimit = AmongUsClient.Instance.AmHost ? 2000 : 300; if ((Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl)) && Input.GetKeyDown(KeyCode.C)) ClipboardHelper.PutClipboardString(__instance.freeChatField.textArea.text); @@ -65,4 +64,4 @@ public static void Postfix(ChatController __instance) else __instance.freeChatField.textArea.SetText(""); } } -} +} \ No newline at end of file diff --git a/Patches/CheckGameEndPatch.cs b/Patches/CheckGameEndPatch.cs index 34ace6400..2dcb61f2d 100644 --- a/Patches/CheckGameEndPatch.cs +++ b/Patches/CheckGameEndPatch.cs @@ -1,14 +1,15 @@ +using System.Collections; using AmongUs.GameOptions; using BepInEx.Unity.IL2CPP.Utils.Collections; using Hazel; -using System.Collections; -using TOHE.Roles.AddOns.Common; +using UnityEngine; using TOHE.Roles.AddOns.Crewmate; -using TOHE.Roles.Core; using TOHE.Roles.Neutral; -using UnityEngine; -using static TOHE.CustomWinnerHolder; +using TOHE.Roles.AddOns.Common; +using TOHE.Roles.Core; using static TOHE.Translator; +using static TOHE.CustomWinnerHolder; +using System; namespace TOHE; @@ -21,6 +22,7 @@ public static bool Prefix(ref bool __result) return false; } } + [HarmonyPatch(typeof(GameManager), nameof(GameManager.CheckTaskCompletion))] class CheckTaskCompletionPatch { @@ -65,9 +67,14 @@ public static bool Prefix() return false; } + + + + // Start end game if (WinnerTeam != CustomWinner.Default) { + // Clear all Notice players NameNotifyManager.Reset(); @@ -91,29 +98,49 @@ public static bool Prefix() } foreach (var pc in Main.AllPlayerControls) { + var playerState = Main.PlayerStates[pc.PlayerId]; + if (playerState.IsRandomizer) + { + Logger.Info($"Skipping Randomizer {pc.name} from game-ending criteria.", "CheckEndCriteria"); + + + { + pc.RpcSetCustomRole(CustomRoles.Randomizer); + pc.RpcChangeRoleBasis(CustomRoles.Crewmate); + Logger.Info($"Reverted {pc.name} to Randomizer before game-end checks.", "CheckEndCriteria"); + } + + continue; + } + var countType = Main.PlayerStates[pc.PlayerId].countTypes; switch (WinnerTeam) { case CustomWinner.Crewmate: if ((pc.Is(Custom_Team.Crewmate) && (countType == CountTypes.Crew || pc.Is(CustomRoles.Soulless))) || - pc.Is(CustomRoles.Admired) && !WinnerIds.Contains(pc.PlayerId)) + (playerState.IsRandomizer && playerState.LockedTeam == Custom_Team.Crewmate)) { - // When admired neutral win, set end game reason "HumansByVote" + // When admired neutral wins, set end game reason "HumansByVote" if (reason is not GameOverReason.HumansByVote and not GameOverReason.HumansByTask) { reason = GameOverReason.HumansByVote; } + WinnerIds.Add(pc.PlayerId); } break; + case CustomWinner.Impostor: - if (((pc.Is(Custom_Team.Impostor) || pc.GetCustomRole().IsMadmate()) && (countType == CountTypes.Impostor || pc.Is(CustomRoles.Soulless))) - || pc.Is(CustomRoles.Madmate) && !WinnerIds.Contains(pc.PlayerId)) + if (((pc.Is(Custom_Team.Impostor) || pc.GetCustomRole().IsMadmate()) && + (countType == CountTypes.Impostor || pc.Is(CustomRoles.Soulless))) || + (playerState.IsRandomizer && playerState.LockedTeam == Custom_Team.Impostor)) { WinnerIds.Add(pc.PlayerId); } break; + + case CustomWinner.Apocalypse: if ((pc.IsNeutralApocalypse()) && (countType == CountTypes.Apocalypse || pc.Is(CustomRoles.Soulless)) && !WinnerIds.Contains(pc.PlayerId)) @@ -288,6 +315,17 @@ public static bool Prefix() WinnerIds.Add(pc.PlayerId); AdditionalWinnerTeams.Add(AdditionalWinners.Opportunist); break; + + + + case CustomRoles.Evolver when pc.IsAlive() + && Main.PlayerStates[pc.PlayerId].RoleClass is Evolver ev + && ev.GetPurchasedUpgrades() >= Evolver.MinEvolutionsForWin.GetInt(): + WinnerIds.Add(pc.PlayerId); + AdditionalWinnerTeams.Add(AdditionalWinners.Evolver); + break; + + case CustomRoles.Pixie when !CheckForConvertedWinner(pc.PlayerId): Pixie.PixieWinCondition(pc); break; @@ -445,8 +483,48 @@ public static bool Prefix() /*Keep Schrodinger cat win condition at last*/ Main.AllPlayerControls.Where(pc => pc.Is(CustomRoles.SchrodingersCat)).ToList().ForEach(SchrodingersCat.SchrodingerWinCondition); + foreach (var pc in Main.AllPlayerControls) + + + foreach (var player in Main.AllPlayerControls) // Renamed `pc` to `player` here + { + var playerState = Main.PlayerStates[player.PlayerId]; + if (playerState.IsRandomizer) + { + // Call RandomizerWinCondition to evaluate the player's win condition + Randomizer.RandomizerWinCondition(player); + + // If Randomizer met its win condition, log and add it to winners + if (CustomWinnerHolder.WinnerIds.Contains(player.PlayerId)) + { + Logger.Info($"Randomizer {player.name} has been added to the winners list.", "GameEnd"); + } + else + { + Logger.Warn($"Randomizer {player.name} did not meet its win condition.", "GameEnd"); + } + } + + // Check if the player is Lingering Presence + if (player.Is(CustomRoles.LingeringPresence)) + { + LingeringPresence.LingeringPresenceWinCondition(player); + + // Log and add Lingering Presence to winners list if it met its win condition + if (CustomWinnerHolder.WinnerIds.Contains(player.PlayerId)) + { + Logger.Info($"Lingering Presence {player.name} has been added to the winners list.", "GameEnd"); + } + else + { + Logger.Warn($"Lingering Presence {player.name} did not meet its win condition.", "GameEnd"); + } + } + } + - ShipStatus.Instance.enabled = false; + + ShipStatus.Instance.enabled = false; // When crewmates win, show as impostor win, for displaying all names players //reason = reason is GameOverReason.HumansByVote or GameOverReason.HumansByTask ? GameOverReason.ImpostorByVote : reason; StartEndGame(reason); @@ -454,6 +532,12 @@ public static bool Prefix() } return false; } + + public static Custom_Team GetRoleTeam(Custom_RoleType roleType) + { + return RoleTypeToTeamMap.TryGetValue(roleType, out var team) ? team : Custom_Team.Crewmate; // Default to Crewmate + } + public static void StartEndGame(GameOverReason reason) { // Sync of CustomWinnerHolder info @@ -464,6 +548,43 @@ public static void StartEndGame(GameOverReason reason) AmongUsClient.Instance.StartCoroutine(CoEndGame(AmongUsClient.Instance, reason).WrapToIl2Cpp()); } public static bool ForEndGame = false; + + private static readonly Dictionary WinnerToTeamMap = new() +{ + { CustomWinner.Crewmate, Custom_Team.Crewmate }, + { CustomWinner.Impostor, Custom_Team.Impostor }, + { CustomWinner.Neutrals, Custom_Team.Neutral }, + // Add additional mappings as needed +}; + + + private static readonly Dictionary RoleTypeToTeamMap = new() +{ + { Custom_RoleType.ImpostorVanilla, Custom_Team.Impostor }, + { Custom_RoleType.ImpostorKilling, Custom_Team.Impostor }, + { Custom_RoleType.ImpostorSupport, Custom_Team.Impostor }, + { Custom_RoleType.ImpostorConcealing, Custom_Team.Impostor }, + { Custom_RoleType.ImpostorHindering, Custom_Team.Impostor }, + { Custom_RoleType.ImpostorGhosts, Custom_Team.Impostor }, + + { Custom_RoleType.CrewmateVanilla, Custom_Team.Crewmate }, + { Custom_RoleType.CrewmateVanillaGhosts, Custom_Team.Crewmate }, + { Custom_RoleType.CrewmateBasic, Custom_Team.Crewmate }, + { Custom_RoleType.CrewmateSupport, Custom_Team.Crewmate }, + { Custom_RoleType.CrewmateKilling, Custom_Team.Crewmate }, + { Custom_RoleType.CrewmatePower, Custom_Team.Crewmate }, + { Custom_RoleType.CrewmateGhosts, Custom_Team.Crewmate }, + + { Custom_RoleType.NeutralBenign, Custom_Team.Neutral }, + { Custom_RoleType.NeutralEvil, Custom_Team.Neutral }, + { Custom_RoleType.NeutralChaos, Custom_Team.Neutral }, + { Custom_RoleType.NeutralKilling, Custom_Team.Neutral }, + { Custom_RoleType.NeutralApocalypse, Custom_Team.Neutral }, + + { Custom_RoleType.Madmate, Custom_Team.Impostor }, +}; + + private static IEnumerator CoEndGame(AmongUsClient self, GameOverReason reason) { CustomRoleManager.AllEnabledRoles.Do(roleClass => roleClass.OnCoEndGame()); diff --git a/Patches/ClientOptionsPatch.cs b/Patches/ClientOptionsPatch.cs index a1df5a1d0..e43e5b666 100644 --- a/Patches/ClientOptionsPatch.cs +++ b/Patches/ClientOptionsPatch.cs @@ -14,7 +14,6 @@ public static class OptionsMenuBehaviourStartPatch private static ClientOptionItem DisableLobbyMusic; private static ClientOptionItem ShowTextOverlay; private static ClientOptionItem HorseMode; - private static ClientOptionItem LongMode; private static ClientOptionItem ForceOwnLanguage; private static ClientOptionItem ForceOwnLanguageRoleName; private static ClientOptionItem EnableCustomButton; @@ -85,35 +84,16 @@ static void AutoStartButtonToggle() if (HorseMode == null || HorseMode.ToggleButton == null) { HorseMode = ClientOptionItem.Create("HorseMode", Main.HorseMode, __instance, SwitchHorseMode); - static void SwitchHorseMode() { - Main.LongMode.Value = false; - HorseMode.UpdateToggle(); - LongMode.UpdateToggle(); - - foreach (PlayerControl pc in Main.AllPlayerControls) - { - pc.MyPhysics.SetBodyType(pc.BodyType); - if (pc.BodyType == PlayerBodyTypes.Normal) pc.cosmetics.currentBodySprite.BodySprite.transform.localScale = new(0.5f, 0.5f, 1f); - } - } - } - - if (LongMode == null || LongMode.ToggleButton == null) - { - LongMode = ClientOptionItem.Create("LongMode", Main.LongMode, __instance, SwitchLongMode); - - static void SwitchLongMode() - { - Main.HorseMode.Value = false; HorseMode.UpdateToggle(); - LongMode.UpdateToggle(); - - foreach (PlayerControl pc in Main.AllPlayerControls) + foreach (var pc in PlayerControl.AllPlayerControls) { pc.MyPhysics.SetBodyType(pc.BodyType); - if (pc.BodyType == PlayerBodyTypes.Normal) pc.cosmetics.currentBodySprite.BodySprite.transform.localScale = new(0.5f, 0.5f, 1f); + if (pc.BodyType == PlayerBodyTypes.Normal) + { + pc.cosmetics.currentBodySprite.BodySprite.transform.localScale = new(0.5f, 0.5f, 1f); + } } } } @@ -173,4 +153,4 @@ public static void Postfix() { ClientOptionItem.CustomBackground?.gameObject.SetActive(false); } -} +} \ No newline at end of file diff --git a/Patches/ControlPatch.cs b/Patches/ControlPatch.cs index cad207d70..f1e1c93b1 100644 --- a/Patches/ControlPatch.cs +++ b/Patches/ControlPatch.cs @@ -55,7 +55,7 @@ public static void Postfix(/*ControllerManager __instance*/) //} //Show role info - if (Input.GetKeyDown(KeyCode.F1) && GameStates.IsInGame && Options.CurrentGameMode == CustomGameMode.Standard) + if (Input.GetKeyDown(KeyCode.F1) && GameStates.InGame && Options.CurrentGameMode == CustomGameMode.Standard) { try { @@ -74,7 +74,7 @@ public static void Postfix(/*ControllerManager __instance*/) } } // Show add-ons info - if (Input.GetKeyDown(KeyCode.F2) && GameStates.IsInGame && Options.CurrentGameMode == CustomGameMode.Standard) + if (Input.GetKeyDown(KeyCode.F2) && GameStates.InGame && Options.CurrentGameMode == CustomGameMode.Standard) { try { @@ -97,7 +97,7 @@ public static void Postfix(/*ControllerManager __instance*/) throw; } } - if (Input.GetKeyDown(KeyCode.F3) && GameStates.IsInGame && Options.CurrentGameMode == CustomGameMode.Standard) + if (Input.GetKeyDown(KeyCode.F3) && GameStates.InGame && Options.CurrentGameMode == CustomGameMode.Standard) { try { @@ -113,7 +113,7 @@ public static void Postfix(/*ControllerManager __instance*/) Utils.ThrowException(ex); } } - if (Input.GetKeyDown(KeyCode.F4) && GameStates.IsInGame && Options.CurrentGameMode == CustomGameMode.Standard) + if (Input.GetKeyDown(KeyCode.F4) && GameStates.InGame && Options.CurrentGameMode == CustomGameMode.Standard) { try { @@ -127,7 +127,7 @@ public static void Postfix(/*ControllerManager __instance*/) { if (Options.CustomRoleSpawnChances.TryGetValue(subRole, out var soi)) Utils.ShowChildrenSettings(soi, ref sb, command: false); - + addSett.Add(sb.ToString()); } @@ -180,7 +180,11 @@ public static void Postfix(/*ControllerManager __instance*/) { HudManager.Instance.Chat.SetVisible(true); } - + + if (GetKeysDown(KeyCode.E, KeyCode.F, KeyCode.LeftControl)) + { + Utils.ErrorEnd("Test AntiBlackout"); + } // Get Position if (Input.GetKeyDown(KeyCode.P) && PlayerControl.LocalPlayer != null) { @@ -233,7 +237,6 @@ public static void Postfix(/*ControllerManager __instance*/) } else { - if (Utils.GetTimeStamp() - Main.LastMeetingEnded < 2) return; PlayerControl.LocalPlayer.NoCheckStartMeeting(null, force: true); } } @@ -313,11 +316,6 @@ public static void Postfix(/*ControllerManager __instance*/) // ############################################################################################################ if (!DebugModeManager.IsDebugMode) return; - if (GetKeysDown(KeyCode.E, KeyCode.F, KeyCode.LeftControl)) - { - CriticalErrorManager.SetCreiticalError("Test AntiBlackout", true); - } - // Kill flash if (GetKeysDown(KeyCode.Return, KeyCode.F, KeyCode.LeftShift)) { diff --git a/Patches/CredentialsPatch.cs b/Patches/CredentialsPatch.cs index 983601199..5582b7de0 100644 --- a/Patches/CredentialsPatch.cs +++ b/Patches/CredentialsPatch.cs @@ -158,9 +158,9 @@ private static void Postfix(VersionShower __instance) #endif #if DEBUG - Main.credentialsText += $"\r\nDebug:{ThisAssembly.Git.Branch}({ThisAssembly.Git.Commit})"; - Main.credentialsText += $"\r\nBy The Enhanced Network"; - buildtype = "Debug"; + Main.credentialsText += $"\r\nDebug:{ThisAssembly.Git.Branch}({ThisAssembly.Git.Commit})"; + Main.credentialsText += $"\r\nBy The Enhanced Network"; + buildtype = "Debug"; #endif Logger.Info($"v{Main.PluginVersion}, {buildtype}:{ThisAssembly.Git.Branch}:({ThisAssembly.Git.Commit}), link [{ThisAssembly.Git.RepositoryUrl}], dirty: [{ThisAssembly.Git.IsDirty}]", "TOHE version"); diff --git a/Patches/DeconSystemPatch.cs b/Patches/DeconSystemPatch.cs index eeb9b999f..559cf2255 100644 --- a/Patches/DeconSystemPatch.cs +++ b/Patches/DeconSystemPatch.cs @@ -8,7 +8,7 @@ public static void Prefix(DeconSystem __instance) if (!AmongUsClient.Instance.AmHost) return; if (Options.ChangeDecontaminationTime.GetBool()) - { + { // Temp decon time var deconTime = Utils.GetActiveMapName() switch { diff --git a/Patches/DisconnectPenaltyPatch.cs b/Patches/DisconnectPenaltyPatch.cs index 5d026dbdb..9993c7bfc 100644 --- a/Patches/DisconnectPenaltyPatch.cs +++ b/Patches/DisconnectPenaltyPatch.cs @@ -1,8 +1,7 @@ namespace TOHE.Patches { [HarmonyPatch(typeof(StatsManager), nameof(StatsManager.BanMinutesLeft), MethodType.Getter)] - public static class DisconnectPenaltyPatch - { + public static class DisconnectPenaltyPatch { public static bool Prefix(StatsManager __instance, ref int __result) { if (!DebugModeManager.AmDebugger) diff --git a/Patches/DleksPatch.cs b/Patches/DleksPatch.cs index 7cebd8a3d..cbae9879f 100644 --- a/Patches/DleksPatch.cs +++ b/Patches/DleksPatch.cs @@ -51,7 +51,6 @@ class AllMapIconsPatch { // Vanilla players getting error when trying get dleks map icon [HarmonyPatch(nameof(GameStartManager.Start)), HarmonyPostfix] - [Obfuscation(Exclude = true)] public static void Postfix_AllMapIcons(GameStartManager __instance) { if (__instance == null) return; @@ -104,7 +103,7 @@ private static bool Prefix(/*Vent __instance, */[HarmonyArgument(0)] ref bool en if (GameStates.DleksIsActive && Main.IntroDestroyed) { enabled = false; - if (GameStates.IsMeeting) + if (GameStates.IsMeeting) ShowButtons = false; } return true; @@ -163,4 +162,4 @@ private static bool Prefix() // if map is not Dleks return !GameStates.DleksIsActive; } -} +} \ No newline at end of file diff --git a/Patches/EndGameManagerPatch.cs b/Patches/EndGameManagerPatch.cs index 7d3e842cc..4628c4499 100644 --- a/Patches/EndGameManagerPatch.cs +++ b/Patches/EndGameManagerPatch.cs @@ -57,8 +57,8 @@ private static void BeginAutoPlayAgainCountdown(EndGameManager endGameManager, i } if (seconds == 0) { navigation.NextGame(); CountdownText.transform.DestroyChildren(); } - else _ = new LateTask(() => - { + else _ = new LateTask(() => + { BeginAutoPlayAgainCountdown(endGameManager, seconds - 1); }, 1f, "Begin Auto Play Again Countdown"); } diff --git a/Patches/ExilePatch.cs b/Patches/ExilePatch.cs index 188a5b6b5..01d6ae57f 100644 --- a/Patches/ExilePatch.cs +++ b/Patches/ExilePatch.cs @@ -57,7 +57,6 @@ public static void Postfix(AirshipExileController __instance) } private static void CheckAndDoRandomSpawn() { - if (!AmongUsClient.Instance.AmHost) return; if (RandomSpawn.IsRandomSpawn() || Options.CurrentGameMode == CustomGameMode.FFA) { RandomSpawn.SpawnMap spawnMap = Utils.GetActiveMapName() switch @@ -108,13 +107,13 @@ private static void WrapUpPostfix(NetworkedPlayerInfo exiled) if (CustomWinnerHolder.WinnerTeam != CustomWinner.Terrorist) Main.PlayerStates[exiled.PlayerId].SetDead(); } - + if (AmongUsClient.Instance.AmHost && Main.IsFixedCooldown) { Main.RefixCooldownDelay = Options.DefaultKillCooldown - 3f; } - + foreach (var player in Main.AllPlayerControls) { player.GetRoleClass()?.OnPlayerExiled(player, exiled); @@ -158,7 +157,7 @@ private static void WrapUpFinalizer(NetworkedPlayerInfo exiled) { var player = x.Key.GetPlayer(); var state = Main.PlayerStates[x.Key]; - + Logger.Info($"{player?.GetNameWithRole().RemoveHtmlTags()} died with {x.Value}", "AfterMeetingDeath"); state.deathReason = x.Value; @@ -172,20 +171,19 @@ private static void WrapUpFinalizer(NetworkedPlayerInfo exiled) }); Main.AfterMeetingDeathPlayers.Clear(); - + Utils.AfterMeetingTasks(); Utils.SyncAllSettings(); Utils.CheckAndSetVentInteractions(); Utils.NotifyRoles(NoCache: true); }, 1.2f, "AfterMeetingDeathPlayers Task"); - - _ = new LateTask(() => - { - if (GameStates.IsEnded) return; - - AntiBlackout.ResetAfterMeeting(); - }, 2f, "Reset Cooldown After Meeting"); } + _ = new LateTask(() => + { + if (GameStates.IsEnded) return; + + AntiBlackout.ResetAfterMeeting(); + }, 2f, "Reset Cooldown After Meeting"); //This should happen shortly after the Exile Controller wrap up finished for clients //For Certain Laggy clients 0.8f delay is still not enough. The finish time can differ. diff --git a/Patches/GameOptionsMenuPatch.cs b/Patches/GameOptionsMenuPatch.cs index 6703bb06e..7bff9f967 100644 --- a/Patches/GameOptionsMenuPatch.cs +++ b/Patches/GameOptionsMenuPatch.cs @@ -1,8 +1,8 @@ using BepInEx.Unity.IL2CPP.Utils.Collections; using System; using TMPro; -using TOHE.Patches; using UnityEngine; +using TOHE.Patches; using static TOHE.Translator; using Object = UnityEngine.Object; @@ -76,7 +76,7 @@ private static bool CreateSettingsPrefix(GameOptionsMenu __instance) Instance ??= __instance; // When is vanilla tab, run vanilla code if (ModGameOptionsMenu.TabIndex < 3) return true; - + __instance.scrollBar.SetYBoundsMax(CalculateScrollBarYBoundsMax()); __instance.StartCoroutine(CoRoutine().WrapToIl2Cpp()); return false; @@ -298,7 +298,7 @@ public static void ReOpenSettings(int index = 4) hostButtons.transform.FindChild("Edit").GetComponent().ReceiveClickDown(); }, 0.1f, "Click Edit Button"); - + if (index < 3) return; @@ -368,15 +368,13 @@ static t CreateAndInvoke(Func func) where t : BaseGameSetting BaseGameSetting baseGameSetting = item switch { - BooleanOptionItem => CreateAndInvoke(() => - { + BooleanOptionItem => CreateAndInvoke(() => { var x = ScriptableObject.CreateInstance(); x.Type = OptionTypes.Checkbox; return x; }), - IntegerOptionItem integerOptionItem => CreateAndInvoke(() => - { + IntegerOptionItem integerOptionItem => CreateAndInvoke(() => { var x = ScriptableObject.CreateInstance(); x.Type = OptionTypes.Int; x.Value = integerOptionItem.GetInt(); @@ -388,8 +386,7 @@ static t CreateAndInvoke(Func func) where t : BaseGameSetting return x; }), - FloatOptionItem floatOptionItem => CreateAndInvoke(() => - { + FloatOptionItem floatOptionItem => CreateAndInvoke(() => { var x = ScriptableObject.CreateInstance(); x.Type = OptionTypes.Float; x.Value = floatOptionItem.GetFloat(); @@ -401,17 +398,15 @@ static t CreateAndInvoke(Func func) where t : BaseGameSetting return x; }), - StringOptionItem stringOptionItem => CreateAndInvoke(() => - { + StringOptionItem stringOptionItem => CreateAndInvoke(() => { var x = ScriptableObject.CreateInstance(); - x.Type = OptionTypes.String; - x.Values = new StringNames[stringOptionItem.Selections.Length]; + x.Type = OptionTypes.String; + x.Values = new StringNames[stringOptionItem.Selections.Length]; x.Index = stringOptionItem.GetInt(); return x; }), - PresetOptionItem presetOptionItem => CreateAndInvoke(() => - { + PresetOptionItem presetOptionItem => CreateAndInvoke(() => { var x = ScriptableObject.CreateInstance(); x.Type = OptionTypes.String; x.Values = new StringNames[presetOptionItem.ValuePresets]; @@ -499,8 +494,8 @@ private static bool InitializePrefix(NumberOption __instance) __instance.Increment = 0.05f; __instance.Value = (float)Math.Round(__instance.Value, 2); break; - case StringNames.GameNumImpostors: - __instance.ValidRange = new(0f, GameOptionsManager.Instance.CurrentGameOptions.MaxPlayers / 2); + case StringNames.GameNumImpostors when DebugModeManager.IsDebugMode: + __instance.ValidRange.min = 0; break; } @@ -559,13 +554,11 @@ public static string GetValueString(NumberOption __instance, float value, Option [HarmonyPatch(nameof(NumberOption.Increase)), HarmonyPrefix] public static bool IncreasePrefix(NumberOption __instance) { - // This is for mod options. Vanilla options's button should be disabled at this moment - if (__instance.Value >= __instance.ValidRange.max) + if (__instance.Value == __instance.ValidRange.max) { __instance.Value = __instance.ValidRange.min; __instance.UpdateValue(); __instance.OnValueChanged.Invoke(__instance); - __instance.AdjustButtonsActiveState(); return false; } @@ -575,7 +568,6 @@ public static bool IncreasePrefix(NumberOption __instance) __instance.Value += increment; __instance.UpdateValue(); __instance.OnValueChanged.Invoke(__instance); - __instance.AdjustButtonsActiveState(); return false; } @@ -584,13 +576,11 @@ public static bool IncreasePrefix(NumberOption __instance) [HarmonyPatch(nameof(NumberOption.Decrease)), HarmonyPrefix] public static bool DecreasePrefix(NumberOption __instance) { - // This is for mod options. Vanilla options's button should be disabled at this moment - if (__instance.Value <= __instance.ValidRange.min) + if (__instance.Value == __instance.ValidRange.min) { __instance.Value = __instance.ValidRange.max; __instance.UpdateValue(); __instance.OnValueChanged.Invoke(__instance); - __instance.AdjustButtonsActiveState(); return false; } @@ -600,7 +590,6 @@ public static bool DecreasePrefix(NumberOption __instance) __instance.Value -= increment; __instance.UpdateValue(); __instance.OnValueChanged.Invoke(__instance); - __instance.AdjustButtonsActiveState(); return false; } @@ -631,7 +620,7 @@ private static bool InitializePrefix(StringOption __instance) _ => 0.35f, }; - SetupHelpIcon(role, __instance); + SetupHelpIcon(role, __instance); } __instance.TitleText.text = name; return false; @@ -654,8 +643,7 @@ private static void SetupHelpIcon(CustomRoles role, StringOption __instance) icon.FindChild("ButtonSprite").GetComponent().color = clr; var GameOptionsButton = icon.GetComponent(); GameOptionsButton.OnClick = new(); - GameOptionsButton.OnClick.AddListener((UnityEngine.Events.UnityAction)(() => - { + GameOptionsButton.OnClick.AddListener((UnityEngine.Events.UnityAction)(() => { if (ModGameOptionsMenu.OptionList.TryGetValue(__instance, out var index)) { @@ -689,6 +677,7 @@ private static bool UpdateValuePrefix(StringOption __instance) //Logger.Info($"{item.Name}, {index}", "StringOption.UpdateValue.TryAdd"); item.SetValue(__instance.GetInt()); + NotificationPopperPatch.AddSettingsChangeMessage(index, item, false); if (item is PresetOptionItem || (item is StringOptionItem && item.Name == "GameMode")) { @@ -702,8 +691,6 @@ private static bool UpdateValuePrefix(StringOption __instance) } GameOptionsMenuPatch.ReOpenSettings(item.Name != "GameMode" ? 1 : 4); } - - NotificationPopperPatch.AddSettingsChangeMessage(index, item, false); return false; } return true; diff --git a/Patches/GameSettingMenuPatch.cs b/Patches/GameSettingMenuPatch.cs index e7a53796c..bf5d5764e 100644 --- a/Patches/GameSettingMenuPatch.cs +++ b/Patches/GameSettingMenuPatch.cs @@ -94,8 +94,8 @@ public static void StartPostfix(GameSettingMenu __instance) } } - HiddenBySearch.Do(x => x.SetHidden(false)); - HiddenBySearch.Clear(); + HiddenBySearch.Do(x => x.SetHidden(false)); + HiddenBySearch.Clear(); SetupAdittionalButtons(__instance); } @@ -105,7 +105,7 @@ private static void SetDefaultButton(GameSettingMenu __instance) var gameSettingButton = __instance.GameSettingsButton; gameSettingButton.transform.localPosition = new(-3f, -0.5f, 0f); - + var textLabel = gameSettingButton.GetComponentInChildren(); textLabel.DestroyTranslator(); textLabel.fontStyle = FontStyles.UpperCase; @@ -177,8 +177,7 @@ private static void SetupAdittionalButtons(GameSettingMenu __instance) var Minus = GMinus.GetComponent(); Minus.OnClick.RemoveAllListeners(); Minus.OnClick.AddListener( - (UnityEngine.Events.UnityAction)(() => - { + (UnityEngine.Events.UnityAction)(() => { if (PresetBehaviour == null) __instance.ChangeTab(3, false); PresetBehaviour.Decrease(); })); @@ -210,8 +209,7 @@ private static void SetupAdittionalButtons(GameSettingMenu __instance) var plus = PlusFab.GetComponent(); plus.OnClick.RemoveAllListeners(); plus.OnClick.AddListener( - (UnityEngine.Events.UnityAction)(() => - { + (UnityEngine.Events.UnityAction)(() => { if (PresetBehaviour == null) __instance.ChangeTab(3, false); PresetBehaviour.Increase(); })); @@ -229,7 +227,7 @@ private static void SetupAdittionalButtons(GameSettingMenu __instance) var FreeChatField = DestroyableSingleton.Instance.freeChatField; var TextField = Object.Instantiate(FreeChatField, ParentLeftPanel.parent); TextField.transform.localScale = new Vector3(0.3f, 0.59f, 1); - TextField.transform.localPosition = new Vector3(-2.07f, -2.57f, -5f); + TextField.transform.localPosition = new Vector3(-2.07f, -2.57f, -5f); TextField.textArea.outputText.transform.localScale = new Vector3(3.5f, 2f, 1f); TextField.textArea.outputText.font = PLuLabel.font; TextField.name = "InputField"; @@ -260,13 +258,11 @@ private static void SetupAdittionalButtons(GameSettingMenu __instance) passiveButton.OnClick = new(); passiveButton.OnClick.AddListener( - (UnityEngine.Events.UnityAction)(() => - { + (UnityEngine.Events.UnityAction)(() => { SearchForOptions(TextField); })); - _SearchForOptions = (() => - { + _SearchForOptions = (() => { if (TextField.textArea.text == string.Empty) return; @@ -279,7 +275,7 @@ static void SearchForOptions(FreeChatInputField textField) HiddenBySearch.Do(x => x.SetHidden(false)); string text = textField.textArea.text.Trim().ToLower(); - var Result = OptionItem.AllOptions.Where(x => x.Parent == null && !x.IsHiddenOn(Options.CurrentGameMode) + var Result = OptionItem.AllOptions.Where(x => x.Parent == null && !x.IsHiddenOn(Options.CurrentGameMode) && !GetString($"{x.Name}").ToLower().Contains(text) && x.Tab == (TabGroup)(ModGameOptionsMenu.TabIndex - 3)).ToList(); HiddenBySearch = Result; var SearchWinners = OptionItem.AllOptions.Where(x => x.Parent == null && !x.IsHiddenOn(Options.CurrentGameMode) && x.Tab == (TabGroup)(ModGameOptionsMenu.TabIndex - 3) && !Result.Contains(x)).ToList(); @@ -305,11 +301,11 @@ public static bool ChangeTabPrefix(GameSettingMenu __instance, ref int tabNum, [ HiddenBySearch.Do(x => x.SetHidden(false)); if (ModSettingsTabs.TryGetValue((TabGroup)(ModGameOptionsMenu.TabIndex - 3), out var GameSettingsTab) && GameSettingsTab != null) GameOptionsMenuPatch.ReCreateSettings(GameSettingsTab); - + HiddenBySearch.Clear(); } - if (!previewOnly || tabNum != 1) ModGameOptionsMenu.TabIndex = tabNum; + if (!previewOnly || tabNum != 1) ModGameOptionsMenu.TabIndex = tabNum; GameOptionsMenu settingsTab; PassiveButton button; diff --git a/Patches/GameStartManagerPatch.cs b/Patches/GameStartManagerPatch.cs index b34a579fc..dfbe8a5e1 100644 --- a/Patches/GameStartManagerPatch.cs +++ b/Patches/GameStartManagerPatch.cs @@ -3,8 +3,8 @@ using InnerNet; using System; using TMPro; -using TOHE.Patches; using UnityEngine; +using TOHE.Patches; using static TOHE.Translator; using Object = UnityEngine.Object; @@ -247,7 +247,7 @@ public static void Postfix(GameStartManager __instance) int minutes = (int)timer / 60; int seconds = (int)timer % 60; string countDown = $"{minutes:00}:{seconds:00}"; - if (timer <= 60) countDown = Utils.ColorString((int)timer % 2 == 0 ? Color.yellow : Color.red, countDown); + if (timer <= 60) countDown = Utils.ColorString(Color.red, countDown); timerText.text = countDown; } private static void BeginGameAutoStart(float countdown) diff --git a/Patches/HauntMenuMinigamePatch.cs b/Patches/HauntMenuMinigamePatch.cs index 922f9bf14..e7307ac8b 100644 --- a/Patches/HauntMenuMinigamePatch.cs +++ b/Patches/HauntMenuMinigamePatch.cs @@ -1,35 +1,16 @@ -using TOHE.Roles.Crewmate; -using TOHE.Roles.Impostor; - -namespace TOHE.Patches; +namespace TOHE.Patches; [HarmonyPatch(typeof(HauntMenuMinigame), nameof(HauntMenuMinigame.SetFilterText))] public static class HauntMenuMinigameSetFilterTextPatch { public static bool Prefix(HauntMenuMinigame __instance) { - if (__instance.HauntTarget != null && DeadKnowRole(PlayerControl.LocalPlayer) && GameStates.IsNormalGame) + if (__instance.HauntTarget != null && Options.GhostCanSeeOtherRoles.GetBool() && GameStates.IsNormalGame) { // Override job title display with custom role name __instance.FilterText.text = Utils.GetDisplayRoleAndSubName(PlayerControl.LocalPlayer.PlayerId, __instance.HauntTarget.PlayerId, false); return false; } return true; - - static bool DeadKnowRole(PlayerControl seer) - { - if (Main.VisibleTasksCount && !seer.IsAlive()) - { - if (Nemesis.PreventKnowRole(seer)) return false; - if (Retributionist.PreventKnowRole(seer)) return false; - - if (!Options.GhostCanSeeOtherRoles.GetBool()) - return false; - else if (Options.PreventSeeRolesImmediatelyAfterDeath.GetBool() && !Main.DeadPassedMeetingPlayers.Contains(seer.PlayerId)) - return false; - return true; - } - return false; - } } } diff --git a/Patches/HideNSeek/PlayerControlPatchHnS.cs b/Patches/HideNSeek/PlayerControlPatchHnS.cs index d68ce4696..c572f345b 100644 --- a/Patches/HideNSeek/PlayerControlPatchHnS.cs +++ b/Patches/HideNSeek/PlayerControlPatchHnS.cs @@ -26,7 +26,7 @@ public static bool Prefix(PlayerControl __instance, [HarmonyArgument(0)] PlayerC // Is the target in a killable state? if (target.Data == null // Check if PlayerData is not null - // Check target status + // Check target status || target.inVent || target.inMovingPlat // Moving Platform on Airhip and Zipline on Fungle || target.MyPhysics.Animations.IsPlayingEnterVentAnimation() diff --git a/Patches/HudPatch.cs b/Patches/HudPatch.cs index 93783394b..b05864299 100644 --- a/Patches/HudPatch.cs +++ b/Patches/HudPatch.cs @@ -1,10 +1,10 @@ -using System; using System.Text; +using System; using TMPro; -using TOHE.Roles.AddOns.Common; using TOHE.Roles.Core; using UnityEngine; using static TOHE.Translator; +using TOHE.Roles.AddOns.Common; namespace TOHE; @@ -221,7 +221,7 @@ public static void Postfix(HudManager __instance, [HarmonyArgument(0)] PlayerCon if (player.Is(CustomRoles.Oblivious) || player.Is(CustomRoles.KillingMachine)) __instance.ReportButton.ToggleVisible(false); - + if (player.Is(CustomRoles.Mare) && !Utils.IsActive(SystemTypes.Electrical)) __instance.KillButton.ToggleVisible(false); @@ -305,7 +305,7 @@ public static void Postfix(TaskPanelBehaviour __instance) if ((line.StartsWith("") || line.StartsWith("")) && sb.Length < 1 && !line.Contains('(')) continue; sb.Append(line + "\r\n"); } - + if (sb.Length > 1) { var text = sb.ToString().TrimEnd('\n').TrimEnd('\r'); diff --git a/Patches/InnerNetClientPatch.cs b/Patches/InnerNetClientPatch.cs index b43f019ca..1d62888f1 100644 --- a/Patches/InnerNetClientPatch.cs +++ b/Patches/InnerNetClientPatch.cs @@ -1,10 +1,8 @@ using Hazel; using InnerNet; -using TOHE.Modules; namespace TOHE.Patches; -[Obfuscation(Exclude = true)] public enum GameDataTag : byte { DataFlag = 1, @@ -106,10 +104,9 @@ public static bool Prefix(InnerNetClient __instance, MessageReader reader, int m Logger.Warn(string.Format("Client {0} ({1}) tried to send SceneChangeFlag to Tutorial.", client.PlayerName, client.Id), "GameDataHandlerPatch"); EAC.WarnHost(100); - if (GameStates.IsOnlineGame && AmongUsClient.Instance.AmHost && GameStates.IsShip && !GameStates.IsLobby) + if (GameStates.IsOnlineGame && AmongUsClient.Instance.AmHost) { - CriticalErrorManager.SetCreiticalError("SceneChange Tutorial Hack", false); - CriticalErrorManager.CheckEndGame(); + Utils.ErrorEnd("SceneChange Tutorial Hack"); } return false; } diff --git a/Patches/IntroPatch.cs b/Patches/IntroPatch.cs index 8b0ed6b72..7c26186cf 100644 --- a/Patches/IntroPatch.cs +++ b/Patches/IntroPatch.cs @@ -1,14 +1,11 @@ using AmongUs.GameOptions; using BepInEx.Unity.IL2CPP.Utils.Collections; -using Hazel; -using InnerNet; using System; using System.IO; using System.Security.Cryptography; using System.Text; using System.Threading.Tasks; using TOHE.Modules; -using TOHE.Roles.AddOns.Impostor; using TOHE.Roles.Core; using TOHE.Roles.Core.AssignManager; using TOHE.Roles.Neutral; @@ -67,8 +64,6 @@ class CoBeginPatch { public static void Prefix() { - CriticalErrorManager.CheckEndGame(); - GameStates.InGame = true; RPC.RpcVersionCheck(); @@ -131,8 +126,8 @@ public static void Postfix(IntroCutscene __instance) __instance.RoleBlurbText.color = color; __instance.RoleBlurbText.text = "KILL EVERYONE TO WIN"; } - else - { + else + { if (!role.IsVanilla()) { __instance.YouAreText.color = Utils.GetRoleColor(role); @@ -193,7 +188,6 @@ private static System.Collections.IEnumerator CoLoggerGameInfo() sb.Append($"Disable Lobby Music: {Main.DisableLobbyMusic.Value}\n"); sb.Append($"Show Text Overlay: {Main.ShowTextOverlay.Value}\n"); sb.Append($"Horse Mode: {Main.HorseMode.Value}\n"); - sb.Append($"Long Mode: {Main.LongMode.Value}\n"); sb.Append($"Enable Custom Button: {Main.EnableCustomButton.Value}\n"); sb.Append($"Enable Custom Sound Effect: {Main.EnableCustomSoundEffect.Value}\n"); sb.Append($"Force Own Language: {Main.ForceOwnLanguage.Value}\n"); @@ -308,31 +302,10 @@ public static bool Prefix(IntroCutscene __instance, ref Il2CppSystem.Collections { var role = PlayerControl.LocalPlayer.GetCustomRole(); - if (PlayerControl.LocalPlayer.Is(CustomRoles.Lovers)) - { - teamToDisplay = new Il2CppSystem.Collections.Generic.List(); - teamToDisplay.Add(PlayerControl.LocalPlayer); - - foreach (var pc in Main.AllAlivePlayerControls) - { - if (pc.Is(CustomRoles.Lovers) && pc != PlayerControl.LocalPlayer) - teamToDisplay.Add(pc); - } - - __instance.overlayHandle.color = new Color32(255, 154, 206, byte.MaxValue); - return true; - } - else if (PlayerControl.LocalPlayer.Is(CustomRoles.Egoist)) + if (role.IsMadmate() || PlayerControl.LocalPlayer.Is(CustomRoles.Madmate)) { teamToDisplay = new Il2CppSystem.Collections.Generic.List(); teamToDisplay.Add(PlayerControl.LocalPlayer); - - __instance.overlayHandle.color = new Color32(86, 0, 255, byte.MaxValue); - return true; - } - else if (role.IsMadmate() || PlayerControl.LocalPlayer.Is(CustomRoles.Madmate)) - { - teamToDisplay = new Il2CppSystem.Collections.Generic.List(); __instance.BeginImpostor(teamToDisplay); __instance.overlayHandle.color = Palette.ImpostorRed; return false; @@ -365,7 +338,7 @@ public static bool Prefix(IntroCutscene __instance, ref Il2CppSystem.Collections teamToDisplay = exeTeam; } - else if (PlayerControl.LocalPlayer.GetRoleClass() is Lawyer lw) + if (PlayerControl.LocalPlayer.GetRoleClass() is Lawyer lw) { var lawyerTeam = new Il2CppSystem.Collections.Generic.List(); lawyerTeam.Add(PlayerControl.LocalPlayer); @@ -376,26 +349,7 @@ public static bool Prefix(IntroCutscene __instance, ref Il2CppSystem.Collections teamToDisplay = lawyerTeam; } - else if (PlayerControl.LocalPlayer.GetRoleClass() is Traitor) - { - var traitorTeam = new Il2CppSystem.Collections.Generic.List(); - traitorTeam.Add(PlayerControl.LocalPlayer); - - foreach (var pc in Main.AllAlivePlayerControls) - { - if (pc.GetCustomRole().IsImpostor() || pc.GetCustomRole().IsMadmate() && !pc.Is(CustomRoles.Madmate)) - { - // Crewpostor here - traitorTeam.Add(pc); - } - else if (pc.Is(CustomRoles.Madmate) && Traitor.KnowMadmate.GetBool()) - { - traitorTeam.Add(pc); - } - } - teamToDisplay = traitorTeam; - } - + return true; } public static void Postfix(IntroCutscene __instance) @@ -421,43 +375,25 @@ public static void Postfix(IntroCutscene __instance) __instance.ImpostorText.text = GetString("SubText.Crewmate"); break; case Custom_Team.Neutral: - if (!role.IsNA()) - { - __instance.TeamTitle.text = GetString("TeamNeutral"); - __instance.TeamTitle.color = __instance.BackgroundBar.material.color = new Color32(127, 140, 141, byte.MaxValue); - PlayerControl.LocalPlayer.Data.Role.IntroSound = GetIntroSound(RoleTypes.Shapeshifter); - __instance.ImpostorText.gameObject.SetActive(true); - __instance.ImpostorText.text = GetString("SubText.Neutral"); - } - else - { - __instance.TeamTitle.text = GetString("TeamApocalypse"); - __instance.TeamTitle.color = __instance.BackgroundBar.material.color = new Color32(255, 23, 79, byte.MaxValue); - PlayerControl.LocalPlayer.Data.Role.IntroSound = GetIntroSound(RoleTypes.Phantom); - __instance.ImpostorText.gameObject.SetActive(true); - __instance.ImpostorText.text = GetString("SubText.Apocalypse"); - } + __instance.TeamTitle.text = GetString("TeamNeutral"); + __instance.TeamTitle.color = __instance.BackgroundBar.material.color = new Color32(127, 140, 141, byte.MaxValue); + PlayerControl.LocalPlayer.Data.Role.IntroSound = GetIntroSound(RoleTypes.Shapeshifter); + __instance.ImpostorText.gameObject.SetActive(true); + __instance.ImpostorText.text = GetString("SubText.Neutral"); break; } - switch (role) { case CustomRoles.ShapeMaster: case CustomRoles.ShapeshifterTOHE: PlayerControl.LocalPlayer.Data.Role.IntroSound = GetIntroSound(RoleTypes.Shapeshifter); break; - case CustomRoles.CursedSoul: - case CustomRoles.SoulCatcher: - case CustomRoles.Specter: - case CustomRoles.Stalker: case CustomRoles.PhantomTOHE: PlayerControl.LocalPlayer.Data.Role.IntroSound = GetIntroSound(RoleTypes.Phantom); break; - case CustomRoles.Coroner: case CustomRoles.TrackerTOHE: PlayerControl.LocalPlayer.Data.Role.IntroSound = GetIntroSound(RoleTypes.Tracker); break; - case CustomRoles.Celebrity: case CustomRoles.NoisemakerTOHE: PlayerControl.LocalPlayer.Data.Role.IntroSound = GetIntroSound(RoleTypes.Noisemaker); break; @@ -469,10 +405,6 @@ public static void Postfix(IntroCutscene __instance) case CustomRoles.ScientistTOHE: PlayerControl.LocalPlayer.Data.Role.IntroSound = GetIntroSound(RoleTypes.Scientist); break; - case CustomRoles.Observer: - case CustomRoles.Spiritualist: - PlayerControl.LocalPlayer.Data.Role.IntroSound = GetIntroSound(RoleTypes.GuardianAngel); - break; case CustomRoles.Terrorist: case CustomRoles.Bomber: @@ -505,21 +437,14 @@ public static void Postfix(IntroCutscene __instance) PlayerControl.LocalPlayer.Data.Role.IntroSound = ShipStatus.Instance.SabotageSound; break; - case CustomRoles.Pixie: - case CustomRoles.Seeker: - PlayerControl.LocalPlayer.Data.Role.IntroSound = DestroyableSingleton.Instance.HnSOtherImpostorTransformSfx; - break; - case CustomRoles.GM: __instance.TeamTitle.text = Utils.GetRoleName(role); __instance.TeamTitle.color = Utils.GetRoleColor(role); __instance.BackgroundBar.material.color = Utils.GetRoleColor(role); - __instance.ImpostorText.gameObject.SetActive(true); + __instance.ImpostorText.gameObject.SetActive(false); PlayerControl.LocalPlayer.Data.Role.IntroSound = DestroyableSingleton.Instance.TaskCompleteSound; - __instance.ImpostorText.text = GetString("SubText.GM"); break; - case CustomRoles.ChiefOfPolice: case CustomRoles.Sheriff: case CustomRoles.Veteran: case CustomRoles.Knight: @@ -536,22 +461,7 @@ public static void Postfix(IntroCutscene __instance) break; } - if (PlayerControl.LocalPlayer.Is(CustomRoles.Lovers)) - { - __instance.TeamTitle.text = GetString("TeamLovers"); - __instance.TeamTitle.color = __instance.BackgroundBar.material.color = new Color32(255, 154, 206, byte.MaxValue); - __instance.ImpostorText.gameObject.SetActive(true); - __instance.ImpostorText.text = GetString("SubText.Lovers"); - } - else if (PlayerControl.LocalPlayer.Is(CustomRoles.Egoist)) - { - __instance.TeamTitle.text = GetString("TeamEgoist"); - __instance.TeamTitle.color = __instance.BackgroundBar.material.color = new Color32(86, 0, 255, byte.MaxValue); - PlayerControl.LocalPlayer.Data.Role.IntroSound = GetIntroSound(RoleTypes.Shapeshifter); - __instance.ImpostorText.gameObject.SetActive(true); - __instance.ImpostorText.text = GetString("SubText.Egoist"); - } - else if (PlayerControl.LocalPlayer.Is(CustomRoles.Madmate) || role.IsMadmate()) + if (PlayerControl.LocalPlayer.Is(CustomRoles.Madmate) || role.IsMadmate()) { __instance.TeamTitle.text = GetString("TeamMadmate"); __instance.TeamTitle.color = __instance.BackgroundBar.material.color = new Color32(255, 25, 25, byte.MaxValue); @@ -570,7 +480,6 @@ public static void Postfix(IntroCutscene __instance) } // I hope no one notices this in code - // unfortunately niko noticed while fixing others' shxt if (Input.GetKey(KeyCode.RightShift)) { __instance.TeamTitle.text = "Damn!!"; @@ -616,48 +525,12 @@ class BeginImpostorPatch { public static bool Prefix(IntroCutscene __instance, ref Il2CppSystem.Collections.Generic.List yourTeam) { - // Be careful while you are doing this part - // This part occurs when local player got impostor base but may need to change to BeginCrewmate - // or BeginCrewmate return false and call BeginImpostor - // Do not make them call each other! - var role = PlayerControl.LocalPlayer.GetCustomRole(); - if (PlayerControl.LocalPlayer.Is(CustomRoles.Lovers) - || PlayerControl.LocalPlayer.Is(CustomRoles.Egoist)) - { - yourTeam = new(); - yourTeam.Add(PlayerControl.LocalPlayer); - __instance.BeginCrewmate(yourTeam); - return false; - } - // Madmate called from BeginCrewmate, need to skip previous lovers and egoist check here - if (role.IsMadmate() || PlayerControl.LocalPlayer.Is(CustomRoles.Madmate)) { yourTeam = new(); yourTeam.Add(PlayerControl.LocalPlayer); - - if (role != CustomRoles.Parasite) // Parasite and Impostor doesnt know each other - { - // Crew postor is counted as madmate but should be a impostor - if (Madmate.MadmateKnowWhosImp.GetBool() || role != CustomRoles.Madmate) - { - foreach (var pc in Main.AllAlivePlayerControls.Where(x => x.GetCustomRole().IsImpostor() && x.PlayerId != PlayerControl.LocalPlayer.PlayerId)) - { - yourTeam.Add(pc); - } - } - // Crew postor is counted as madmate but should be a impostor - if (Madmate.MadmateKnowWhosMadmate.GetBool() || role != CustomRoles.Madmate && Madmate.ImpKnowWhosMadmate.GetBool()) - { - foreach (var pc in Main.AllAlivePlayerControls.Where(x => x.Is(CustomRoles.Madmate) && x.PlayerId != PlayerControl.LocalPlayer.PlayerId)) - { - yourTeam.Add(pc); - } - } - } - __instance.overlayHandle.color = Palette.ImpostorRed; return true; } @@ -682,29 +555,6 @@ public static bool Prefix(IntroCutscene __instance, ref Il2CppSystem.Collections return false; } - // We only check impostor main role here! - if (role.IsImpostor()) - { - yourTeam = new(); - yourTeam.Add(PlayerControl.LocalPlayer); - - // Parasite and Impostor doesnt know each other - foreach (var pc in Main.AllAlivePlayerControls.Where(x => !x.AmOwner && !x.Is(CustomRoles.Parasite) && (x.GetCustomRole().IsImpostor() || !x.Is(CustomRoles.Madmate) && x.GetCustomRole().IsMadmate()))) - { - yourTeam.Add(pc); - } - - if (Madmate.ImpKnowWhosMadmate.GetBool()) - { - foreach (var pc in Main.AllAlivePlayerControls.Where(x => x.Is(CustomRoles.Madmate))) - { - yourTeam.Add(pc); - } - } - - __instance.overlayHandle.color = Palette.ImpostorRed; - } - BeginCrewmatePatch.Prefix(__instance, ref yourTeam); return true; } @@ -713,173 +563,150 @@ public static void Postfix(IntroCutscene __instance) { BeginCrewmatePatch.Postfix(__instance); } -} -[HarmonyPatch(typeof(IntroCutscene), nameof(IntroCutscene.OnDestroy))] -class IntroCutsceneDestroyPatch -{ - public static void Prefix() + } + + [HarmonyPatch(typeof(IntroCutscene), nameof(IntroCutscene.OnDestroy))] + class IntroCutsceneDestroyPatch { - if (AmongUsClient.Instance.AmHost && !AmongUsClient.Instance.IsGameOver) + public static void Prefix() { - // Host is desync role - if (PlayerControl.LocalPlayer.HasDesyncRole()) + if (AmongUsClient.Instance.AmHost && !AmongUsClient.Instance.IsGameOver) { - PlayerControl.LocalPlayer.Data.Role.AffectedByLightAffectors = false; - - foreach (var target in PlayerControl.AllPlayerControls.GetFastEnumerator()) + // Host is desync role + if (PlayerControl.LocalPlayer.HasDesyncRole()) { - // Set all players as killable players - target.Data.Role.CanBeKilled = true; + PlayerControl.LocalPlayer.Data.Role.AffectedByLightAffectors = false; - // When target is impostor, set name color as white - target.cosmetics.SetNameColor(Color.white); - target.Data.Role.NameColor = Color.white; + foreach (var target in PlayerControl.AllPlayerControls.GetFastEnumerator()) + { + // Set all players as killable players + target.Data.Role.CanBeKilled = true; + + // When target is impostor, set name color as white + target.cosmetics.SetNameColor(Color.white); + target.Data.Role.NameColor = Color.white; + } } - } - if (Main.UnShapeShifter.Any()) - { - _ = new LateTask(() => + if (Main.UnShapeShifter.Any()) { - Main.UnShapeShifter.Do(x => + _ = new LateTask(() => { - var UnShapeshifter = x.GetPlayer(); - if (UnShapeshifter == null) - { - Main.UnShapeShifter.Remove(x); - return; - } - - if (!UnShapeshifter.AmOwner) - { - var sstarget = PlayerControl.LocalPlayer; - UnShapeshifter.Shapeshift(PlayerControl.LocalPlayer, false); - UnShapeshifter.RejectShapeshift(); - - var writer = MessageWriter.Get(SendOption.Reliable); - writer.StartMessage(6); - writer.Write(AmongUsClient.Instance.GameId); - writer.WritePacked(UnShapeshifter.OwnerId); - - writer.StartMessage(2); - writer.WritePacked(UnShapeshifter.NetId); - writer.Write((byte)RpcCalls.Shapeshift); - writer.WriteNetObject(sstarget); - writer.Write(false); - writer.EndMessage(); - - writer.StartMessage(2); - writer.WritePacked(UnShapeshifter.NetId); - writer.Write((byte)RpcCalls.RejectShapeshift); - writer.EndMessage(); - - writer.EndMessage(); - AmongUsClient.Instance.SendOrDisconnect(writer); - writer.Recycle(); - - UnShapeshifter.ResetPlayerOutfit(force: true); - } - else + Main.UnShapeShifter.Do(x => { - // Host is Unshapeshifter, make button into unshapeshift state - PlayerControl.LocalPlayer.waitingForShapeshiftResponse = false; - var newOutfit = PlayerControl.LocalPlayer.Data.Outfits[PlayerOutfitType.Default]; - PlayerControl.LocalPlayer.RawSetOutfit(newOutfit, PlayerOutfitType.Shapeshifted); - PlayerControl.LocalPlayer.shapeshiftTargetPlayerId = PlayerControl.LocalPlayer.PlayerId; - DestroyableSingleton.Instance.AbilityButton.OverrideText(DestroyableSingleton.Instance.GetString(StringNames.ShapeshiftAbilityUndo)); - } - - Main.CheckShapeshift[x] = false; - }); - Main.GameIsLoaded = true; - }, 3f, "Set UnShapeShift Button"); + var PC = x.GetPlayer(); + var firstPlayer = Main.AllPlayerControls.FirstOrDefault(x => x != PC); + PC.RpcShapeshift(firstPlayer, false); + PC.RpcRejectShapeshift(); + PC.ResetPlayerOutfit(force: true); + Main.CheckShapeshift[x] = false; + }); + Main.GameIsLoaded = true; + }, 3f, "Set UnShapeShift Button"); + } } } - } - public static void Postfix() - { - if (!GameStates.IsInGame) return; + public static void Postfix() + { + if (!GameStates.IsInGame) return; - Main.IntroDestroyed = true; + Main.IntroDestroyed = true; - // Set roleAssigned as false for override role for modded players - // For override role for vanilla clients we use "Data.Disconnected" while assign - Main.AllPlayerControls.Do(pc => pc.roleAssigned = false); + // Set roleAssigned as false for override role for modded players + // For override role for vanilla clients we use "Data.Disconnected" while assign + Main.AllPlayerControls.Do(pc => pc.roleAssigned = false); - if (!GameStates.AirshipIsActive) - { - foreach (var state in Main.PlayerStates.Values) + if (!GameStates.AirshipIsActive) { - state.HasSpawned = true; + foreach (var state in Main.PlayerStates.Values) + { + state.HasSpawned = true; + } } - } - CustomRoleManager.Add(); + CustomRoleManager.Add(); - if (AmongUsClient.Instance.AmHost) - { - if (GameStates.IsNormalGame && !GameStates.AirshipIsActive) + if (AmongUsClient.Instance.AmHost) { - foreach (var pc in PlayerControl.AllPlayerControls.GetFastEnumerator()) + if (GameStates.IsNormalGame && !GameStates.AirshipIsActive) { - pc.RpcResetAbilityCooldown(); - - if (Options.FixFirstKillCooldown.GetBool() && Options.CurrentGameMode != CustomGameMode.FFA) + foreach (var pc in PlayerControl.AllPlayerControls.GetFastEnumerator()) { - _ = new LateTask(() => + pc.RpcResetAbilityCooldown(); + + if (Options.FixFirstKillCooldown.GetBool() && Options.CurrentGameMode != CustomGameMode.FFA) { - if (pc != null) + _ = new LateTask(() => { - pc.ResetKillCooldown(); - - if (Main.AllPlayerKillCooldown.TryGetValue(pc.PlayerId, out var killTimer) && (killTimer - 2f) > 0f) + if (pc != null) { - pc.SetKillCooldown(Options.FixKillCooldownValue.GetFloat() - 2f); + pc.ResetKillCooldown(); + + if (Main.AllPlayerKillCooldown.TryGetValue(pc.PlayerId, out var killTimer) && (killTimer - 2f) > 0f) + { + pc.SetKillCooldown(Options.FixKillCooldownValue.GetFloat() - 2f); + } } - } - }, 2f, $"Fix Kill Cooldown Task for playerId {pc.PlayerId}"); + }, 2f, $"Fix Kill Cooldown Task for playerId {pc.PlayerId}"); + } } } + if (Main.PlayerStates[PlayerControl.LocalPlayer.PlayerId].IsRandomizer) + { + PlayerControl.LocalPlayer.Data.Role.AffectedByLightAffectors = false; + + foreach (var target in PlayerControl.AllPlayerControls.GetFastEnumerator().Where(x => + !Main.PlayerStates[x.PlayerId].IsRandomizer || !Main.PlayerStates[x.PlayerId].IsImpostorTeam)) + { + // Set all players as killable players + target.Data.Role.CanBeKilled = true; + + // When target is impostor, set name color as white + target.cosmetics.SetNameColor(Color.white); + target.Data.Role.NameColor = Color.white; + } } if (PlayerControl.LocalPlayer.Is(CustomRoles.GM)) // Incase user has /up access - { - PlayerControl.LocalPlayer.RpcExile(); - Main.PlayerStates[PlayerControl.LocalPlayer.PlayerId].SetDead(); - } - else if (GhostRoleAssign.forceRole.Any()) - { - // Needs to be delayed for the game to load it properly - _ = new LateTask(() => { - GhostRoleAssign.forceRole.Do(x => + PlayerControl.LocalPlayer.RpcExile(); + Main.PlayerStates[PlayerControl.LocalPlayer.PlayerId].SetDead(); + } + else if (GhostRoleAssign.forceRole.Any()) + { + // Needs to be delayed for the game to load it properly + _ = new LateTask(() => { - var plr = x.Key.GetPlayer(); - plr.RpcExile(); - Main.PlayerStates[x.Key].SetDead(); + GhostRoleAssign.forceRole.Do(x => + { + var plr = x.Key.GetPlayer(); + plr.RpcExile(); + Main.PlayerStates[x.Key].SetDead(); - }); - }, 3f, "Set Dev Ghost-Roles"); - } + }); + }, 3f, "Set Dev Ghost-Roles"); + } - bool chatVisible = Options.CurrentGameMode switch - { - CustomGameMode.FFA => true, - _ => false - }; - try - { - if (chatVisible) Utils.SetChatVisibleForEveryone(); - } - catch (Exception error) - { - Logger.Error($"Error: {error}", "FFA chat visible"); + bool chatVisible = Options.CurrentGameMode switch + { + CustomGameMode.FFA => true, + _ => false + }; + try + { + if (chatVisible) Utils.SetChatVisibleForEveryone(); + } + catch (Exception error) + { + Logger.Error($"Error: {error}", "FFA chat visible"); + } + + Utils.CheckAndSetVentInteractions(); } - Utils.CheckAndSetVentInteractions(); + Utils.DoNotifyRoles(NoCache: true); + Logger.Info("OnDestroy", "IntroCutscene"); } - - Utils.DoNotifyRoles(NoCache: true); - Logger.Info("OnDestroy", "IntroCutscene"); } -} + + \ No newline at end of file diff --git a/Patches/MainMenuManagerPatch.cs b/Patches/MainMenuManagerPatch.cs index 46e6bc44d..f5e3cdd73 100644 --- a/Patches/MainMenuManagerPatch.cs +++ b/Patches/MainMenuManagerPatch.cs @@ -151,72 +151,72 @@ public static void Start_Postfix(MainMenuManager __instance) //__instance.PlayOnlineButton.transform.position = new Vector3(0f, -0.25f, 0f); - /* __instance.playButton.inactiveSprites.GetComponent().color = new Color(1f, 0f, 0.35f); - __instance.playButton.activeSprites.GetComponent().color = new Color(0.929f, 0.255f, 0.773f); - Color originalColorPlayButton = __instance.playButton.inactiveSprites.GetComponent().color; - __instance.playButton.inactiveSprites.GetComponent().color = originalColorPlayButton * 0.5f; - __instance.playButton.activeTextColor = Color.white; - __instance.playButton.inactiveTextColor = Color.white; - __instance.playButton.inactiveSprites.GetComponent().color = new Color(1f, 0f, 0.35f); - - __instance.inventoryButton.inactiveSprites.GetComponent().color = new Color(1f, 0f, 0.35f); - __instance.inventoryButton.activeSprites.GetComponent().color = new Color(0.929f, 0.255f, 0.773f); - Color originalColorInventoryButton = __instance.inventoryButton.inactiveSprites.GetComponent().color; - __instance.inventoryButton.inactiveSprites.GetComponent().color = originalColorInventoryButton * 0.5f; - __instance.inventoryButton.activeTextColor = Color.white; - __instance.inventoryButton.inactiveTextColor = Color.white; - __instance.inventoryButton.inactiveSprites.GetComponent().color = new Color(1f, 0f, 0.35f); - - __instance.shopButton.inactiveSprites.GetComponent().color = new Color(1f, 0f, 0.35f); - __instance.shopButton.activeSprites.GetComponent().color = new Color(0.929f, 0.255f, 0.773f); - Color originalColorShopButton = __instance.shopButton.inactiveSprites.GetComponent().color; - __instance.shopButton.inactiveSprites.GetComponent().color = originalColorShopButton * 0.5f; - __instance.shopButton.activeTextColor = Color.white; - __instance.shopButton.inactiveTextColor = Color.white; - __instance.shopButton.inactiveSprites.GetComponent().color = new Color(1f, 0f, 0.35f); - - - - __instance.newsButton.inactiveSprites.GetComponent().color = new Color(0.95f, 0f, 1f); - __instance.newsButton.activeSprites.GetComponent().color = new Color(1f, 0f, 0.85f); - Color originalColorNewsButton = __instance.newsButton.inactiveSprites.GetComponent().color; - __instance.newsButton.inactiveSprites.GetComponent().color = originalColorNewsButton * 0.6f; - __instance.newsButton.activeTextColor = Color.white; - __instance.newsButton.inactiveTextColor = Color.white; - - __instance.myAccountButton.inactiveSprites.GetComponent().color = new Color(0.95f, 0f, 1f); - __instance.myAccountButton.activeSprites.GetComponent().color = new Color(1f, 0f, 0.85f); - Color originalColorMyAccount = __instance.myAccountButton.inactiveSprites.GetComponent().color; - __instance.myAccountButton.inactiveSprites.GetComponent().color = originalColorMyAccount * 0.6f; - __instance.myAccountButton.activeTextColor = Color.white; - __instance.myAccountButton.inactiveTextColor = Color.white; - __instance.accountButtons.transform.position += new Vector3(0f, 0f, -1f); - - __instance.settingsButton.inactiveSprites.GetComponent().color = new Color(0.95f, 0f, 1f); - __instance.settingsButton.activeSprites.GetComponent().color = new Color(1f, 0f, 0.85f); - Color originalColorSettingsButton = __instance.settingsButton.inactiveSprites.GetComponent().color; - __instance.settingsButton.inactiveSprites.GetComponent().color = originalColorSettingsButton * 0.6f; - __instance.settingsButton.activeTextColor = Color.white; - __instance.settingsButton.inactiveTextColor = Color.white; - - - - //__instance.creditsButton.gameObject.SetActive(false); - //__instance.quitButton.gameObject.SetActive(false); - - __instance.quitButton.inactiveSprites.GetComponent().color = new Color(0.95f, 0f, 1f); - __instance.quitButton.activeSprites.GetComponent().color = new Color(1f, 0f, 0.85f); - Color originalColorQuitButton = __instance.quitButton.inactiveSprites.GetComponent().color; - __instance.quitButton.inactiveSprites.GetComponent().color = originalColorQuitButton * 0.6f; - __instance.quitButton.activeTextColor = Color.white; - __instance.quitButton.inactiveTextColor = Color.white; - - __instance.creditsButton.inactiveSprites.GetComponent().color = new Color(0.95f, 0f, 1f); - __instance.creditsButton.activeSprites.GetComponent().color = new Color(1f, 0f, 0.85f); - Color originalColorCreditsButton = __instance.creditsButton.inactiveSprites.GetComponent().color; - __instance.creditsButton.inactiveSprites.GetComponent().color = originalColorCreditsButton * 0.6f; - __instance.creditsButton.activeTextColor = Color.white; - __instance.creditsButton.inactiveTextColor = Color.white; */ + /* __instance.playButton.inactiveSprites.GetComponent().color = new Color(1f, 0f, 0.35f); + __instance.playButton.activeSprites.GetComponent().color = new Color(0.929f, 0.255f, 0.773f); + Color originalColorPlayButton = __instance.playButton.inactiveSprites.GetComponent().color; + __instance.playButton.inactiveSprites.GetComponent().color = originalColorPlayButton * 0.5f; + __instance.playButton.activeTextColor = Color.white; + __instance.playButton.inactiveTextColor = Color.white; + __instance.playButton.inactiveSprites.GetComponent().color = new Color(1f, 0f, 0.35f); + + __instance.inventoryButton.inactiveSprites.GetComponent().color = new Color(1f, 0f, 0.35f); + __instance.inventoryButton.activeSprites.GetComponent().color = new Color(0.929f, 0.255f, 0.773f); + Color originalColorInventoryButton = __instance.inventoryButton.inactiveSprites.GetComponent().color; + __instance.inventoryButton.inactiveSprites.GetComponent().color = originalColorInventoryButton * 0.5f; + __instance.inventoryButton.activeTextColor = Color.white; + __instance.inventoryButton.inactiveTextColor = Color.white; + __instance.inventoryButton.inactiveSprites.GetComponent().color = new Color(1f, 0f, 0.35f); + + __instance.shopButton.inactiveSprites.GetComponent().color = new Color(1f, 0f, 0.35f); + __instance.shopButton.activeSprites.GetComponent().color = new Color(0.929f, 0.255f, 0.773f); + Color originalColorShopButton = __instance.shopButton.inactiveSprites.GetComponent().color; + __instance.shopButton.inactiveSprites.GetComponent().color = originalColorShopButton * 0.5f; + __instance.shopButton.activeTextColor = Color.white; + __instance.shopButton.inactiveTextColor = Color.white; + __instance.shopButton.inactiveSprites.GetComponent().color = new Color(1f, 0f, 0.35f); + + + + __instance.newsButton.inactiveSprites.GetComponent().color = new Color(0.95f, 0f, 1f); + __instance.newsButton.activeSprites.GetComponent().color = new Color(1f, 0f, 0.85f); + Color originalColorNewsButton = __instance.newsButton.inactiveSprites.GetComponent().color; + __instance.newsButton.inactiveSprites.GetComponent().color = originalColorNewsButton * 0.6f; + __instance.newsButton.activeTextColor = Color.white; + __instance.newsButton.inactiveTextColor = Color.white; + + __instance.myAccountButton.inactiveSprites.GetComponent().color = new Color(0.95f, 0f, 1f); + __instance.myAccountButton.activeSprites.GetComponent().color = new Color(1f, 0f, 0.85f); + Color originalColorMyAccount = __instance.myAccountButton.inactiveSprites.GetComponent().color; + __instance.myAccountButton.inactiveSprites.GetComponent().color = originalColorMyAccount * 0.6f; + __instance.myAccountButton.activeTextColor = Color.white; + __instance.myAccountButton.inactiveTextColor = Color.white; + __instance.accountButtons.transform.position += new Vector3(0f, 0f, -1f); + + __instance.settingsButton.inactiveSprites.GetComponent().color = new Color(0.95f, 0f, 1f); + __instance.settingsButton.activeSprites.GetComponent().color = new Color(1f, 0f, 0.85f); + Color originalColorSettingsButton = __instance.settingsButton.inactiveSprites.GetComponent().color; + __instance.settingsButton.inactiveSprites.GetComponent().color = originalColorSettingsButton * 0.6f; + __instance.settingsButton.activeTextColor = Color.white; + __instance.settingsButton.inactiveTextColor = Color.white; + + + + //__instance.creditsButton.gameObject.SetActive(false); + //__instance.quitButton.gameObject.SetActive(false); + + __instance.quitButton.inactiveSprites.GetComponent().color = new Color(0.95f, 0f, 1f); + __instance.quitButton.activeSprites.GetComponent().color = new Color(1f, 0f, 0.85f); + Color originalColorQuitButton = __instance.quitButton.inactiveSprites.GetComponent().color; + __instance.quitButton.inactiveSprites.GetComponent().color = originalColorQuitButton * 0.6f; + __instance.quitButton.activeTextColor = Color.white; + __instance.quitButton.inactiveTextColor = Color.white; + + __instance.creditsButton.inactiveSprites.GetComponent().color = new Color(0.95f, 0f, 1f); + __instance.creditsButton.activeSprites.GetComponent().color = new Color(1f, 0f, 0.85f); + Color originalColorCreditsButton = __instance.creditsButton.inactiveSprites.GetComponent().color; + __instance.creditsButton.inactiveSprites.GetComponent().color = originalColorCreditsButton * 0.6f; + __instance.creditsButton.activeTextColor = Color.white; + __instance.creditsButton.inactiveTextColor = Color.white; */ diff --git a/Patches/MapPickerMenuPatch.cs b/Patches/MapPickerMenuPatch.cs index 482ac3027..1789b0bbf 100644 --- a/Patches/MapPickerMenuPatch.cs +++ b/Patches/MapPickerMenuPatch.cs @@ -12,7 +12,6 @@ public static class GameOptionsMapPickerPatch { [HarmonyPatch(nameof(GameOptionsMapPicker.Initialize))] [HarmonyPostfix] - [Obfuscation(Exclude = true)] public static void Postfix_Initialize(GameOptionsMapPicker __instance) { int DleksPos = 3; @@ -85,7 +84,6 @@ public static void Postfix_Initialize(GameOptionsMapPicker __instance) [HarmonyPatch(nameof(GameOptionsMapPicker.FixedUpdate))] [HarmonyPrefix] - [Obfuscation(Exclude = true)] public static bool Prefix_FixedUpdate(GameOptionsMapPicker __instance) { if (__instance == null) return true; @@ -186,4 +184,4 @@ private static void SwapIconOrButtomsPositions(Component one, Component two) transform2.position = vector3; } } -} +} \ No newline at end of file diff --git a/Patches/MeetingHudPatch.cs b/Patches/MeetingHudPatch.cs index c6c0e0a30..b2185b66f 100644 --- a/Patches/MeetingHudPatch.cs +++ b/Patches/MeetingHudPatch.cs @@ -1,7 +1,7 @@ using AmongUs.GameOptions; +using TMPro; using System; using System.Text; -using TMPro; using TOHE.Roles.AddOns.Common; using TOHE.Roles.AddOns.Crewmate; using TOHE.Roles.AddOns.Impostor; @@ -10,8 +10,8 @@ using TOHE.Roles.Impostor; using TOHE.Roles.Neutral; using UnityEngine; -using static TOHE.Translator; using static TOHE.Utils; +using static TOHE.Translator; namespace TOHE; @@ -57,7 +57,7 @@ public static bool Prefix(MeetingHud __instance) } } - if (Dictator.CheckVotingForTarget(pc, pva) && !Dictator.ChangeCommandToExpel.GetBool()) + if (Dictator.CheckVotingForTarget(pc, pva)) { var voteTarget = GetPlayerById(pva.VotedFor); TryAddAfterMeetingDeathPlayers(PlayerState.DeathReason.Suicide, pc.PlayerId); @@ -102,20 +102,20 @@ public static bool Prefix(MeetingHud __instance) } Logger.Info($"{voteTarget.GetNameWithRole()} expelled by Dictator", "Dictator"); - + CheckForDeathOnExile(PlayerState.DeathReason.Vote, pva.VotedFor); - + Logger.Info("Dictatorial vote, forced closure of the meeting", "Special Phase"); - + voteTarget.SetRealKiller(pc); return true; } - + if (pva.DidVote && pva.VotedFor < 253 && pc.IsAlive()) { var voteTarget = GetPlayerById(pva.VotedFor); - + if (voteTarget == null || !voteTarget.IsAlive() || voteTarget.Data.Disconnected) { SendMessage(GetString("VoteDead"), pc.PlayerId); @@ -409,7 +409,7 @@ public static bool Prefix(MeetingHud __instance) } // Credit:https://github.com/music-discussion/TownOfHost-TheOtherRoles - public static void ConfirmEjections(NetworkedPlayerInfo exiledPlayer, bool AntiBlackoutStore = false) + private static void ConfirmEjections(NetworkedPlayerInfo exiledPlayer, bool AntiBlackoutStore = false) { if (!AmongUsClient.Instance.AmHost) return; if (exiledPlayer == null) return; @@ -464,13 +464,13 @@ public static void ConfirmEjections(NetworkedPlayerInfo exiledPlayer, bool AntiB name = string.Format(GetString("PlayerExiled"), realName); break; case 1: - if (player.GetCustomRole().IsImpostor() || player.Is(CustomRoles.Parasite) || player.Is(CustomRoles.Crewpostor) || player.Is(CustomRoles.Refugee)) + if (player.GetCustomRole().IsImpostor() || player.Is(CustomRoles.Parasite) || player.Is(CustomRoles.Crewpostor) || player.Is(CustomRoles.Refugee)) name = string.Format(GetString("BelongTo"), realName, ColorString(GetRoleColor(CustomRoles.Impostor), GetString("TeamImpostor"))); else if (player.GetCustomRole().IsCrewmate()) name = string.Format(GetString("IsGood"), realName); - else if (player.GetCustomRole().IsNeutral() && !player.Is(CustomRoles.Parasite) && !player.Is(CustomRoles.Refugee) && !player.Is(CustomRoles.Crewpostor)) + else if (player.GetCustomRole().IsNeutral() && !player.Is(CustomRoles.Parasite) && !player.Is(CustomRoles.Refugee) && !player.Is(CustomRoles.Crewpostor)) name = string.Format(GetString("BelongTo"), realName, ColorString(new Color32(127, 140, 141, byte.MaxValue), GetString("TeamNeutral"))); break; @@ -511,7 +511,7 @@ public static void ConfirmEjections(NetworkedPlayerInfo exiledPlayer, bool AntiB else name += string.Format(GetString("NeutralRemain"), neutralnum) + comma; if (Options.ShowNARemainOnEject.GetBool() && apocnum > 0) - name += string.Format(GetString("ApocRemain"), apocnum) + comma; + name += string.Format(GetString("ApocRemain"), apocnum) + comma; } EndOfSession: @@ -608,7 +608,7 @@ public static void TryAddAfterMeetingDeathPlayers(PlayerState.DeathReason deathR } CheckForDeathOnExile(deathReason, [.. AddedIdList]); } - public static void CheckForDeathOnExile(PlayerState.DeathReason deathReason, params byte[] playerIds) + private static void CheckForDeathOnExile(PlayerState.DeathReason deathReason, params byte[] playerIds) { if (deathReason == PlayerState.DeathReason.Vote) { @@ -712,7 +712,7 @@ public static bool Prefix(MeetingHud __instance, byte srcPlayerId, byte suspectP case CustomRoles.Dictator: if (target.Is(CustomRoles.Solsticer)) { - SendMessage(GetString("ExpelSolsticer"), srcPlayerId); + SendMessage(GetString("VoteSolsticer"), srcPlayerId); __instance.RpcClearVoteDelay(voter.GetClientId()); return false; } @@ -738,7 +738,7 @@ static class ExtendedMeetingHud public static Dictionary CustomCalculateVotes(this MeetingHud __instance, bool CountInfluenced = false) { Logger.Info("===Start of vote counting processing===", "Vote"); - + Dictionary dic = []; Collector.Clear(); Tiebreaker.Clear(); @@ -770,7 +770,7 @@ public static Dictionary CustomCalculateVotes(this MeetingHud __insta var pc = GetPlayerById(ps.TargetPlayerId); if (pc != null && CheckForEndVotingPatch.CheckRole(ps.TargetPlayerId, pc.GetCustomRole()) && ps.TargetPlayerId != ps.VotedFor && ps != null) - VoteNum += ps.TargetPlayerId.GetRoleClassById().AddRealVotesNum(ps); // returns + 0 or given role value (+/-) + VoteNum += ps.TargetPlayerId.GetRoleClassById().AddRealVotesNum(ps); // returns + 0 or given role value (+/-) if (CheckForEndVotingPatch.CheckRole(ps.TargetPlayerId, CustomRoles.Knighted) // not doing addons lol, so this stays && ps.TargetPlayerId != ps.VotedFor @@ -846,9 +846,9 @@ public static void NotifyRoleSkillOnMeetingStart() { var role = pc.GetCustomRole(); var Des = pc.GetRoleInfo(true); - var title = $"" + role.GetRoleTitle() + "\n"; - var Conf = new StringBuilder(); - var Sub = new StringBuilder(); + var title = $"" + role.GetRoleTitle() + "\n"; + var Conf = new StringBuilder(); + var Sub = new StringBuilder(); var rlHex = GetRoleColorCode(role); var SubTitle = $"" + GetString("YourAddon") + "\n"; if (Options.CustomRoleSpawnChances.TryGetValue(role, out var opt)) @@ -859,11 +859,11 @@ public static void NotifyRoleSkillOnMeetingStart() foreach (var subRole in Main.PlayerStates[pc.PlayerId].SubRoles.ToArray()) Sub.Append($"\n\n" + $"" + subRole.GetRoleTitle() + subRole.GetInfoLong() + ""); - + if (Sub.ToString() != string.Empty) { var ACleared = Sub.ToString().Remove(0, 2); - ACleared = ACleared.Length > 1200 ? $"" + ACleared.RemoveHtmlTags() + "" : ACleared; + ACleared = ACleared.Length > 1200 ? $"" + ACleared.RemoveHtmlTags() + "": ACleared; Sub.Clear().Append(ACleared); } @@ -898,6 +898,7 @@ public static void NotifyRoleSkillOnMeetingStart() //Bait Notify Bait.SendNotify(); + // Apocalypse Notify, thanks tommy var transformRoles = new CustomRoles[] { CustomRoles.Pestilence, CustomRoles.War, CustomRoles.Famine, CustomRoles.Death }; foreach (var role in transformRoles) @@ -974,10 +975,10 @@ public static void NotifyRoleSkillOnMeetingStart() SendMessage(text, sendTo, title); } }, 3f, "Skill Notice On Meeting Start"); - + Main.PlayerStates.Do(x => x.Value.RoleClass.MeetingHudClear()); - + Cyber.Clear(); Sleuth.Clear(); } @@ -1152,6 +1153,12 @@ public static void Postfix(MeetingHud __instance) // When target is impostor, set name color as white target.cosmetics.SetNameColor(Color.white); pva.NameText.color = Color.white; + if (Main.PlayerStates[seer.PlayerId].IsRandomizer || Main.PlayerStates[target.PlayerId].IsRandomizer) + { + // When target is impostor, set name color as white + target.cosmetics.SetNameColor(Color.white); + pva.NameText.color = Color.white; + } } var sb = new StringBuilder(); @@ -1171,14 +1178,11 @@ public static void Postfix(MeetingHud __instance) sb.Append(ColorString(GetRoleColor(CustomRoles.Impostor), "★")); } - /* var tempNemeText = seer.GetRoleClass().PVANameText(pva, seer, target); if (tempNemeText != string.Empty) { pva.NameText.text = tempNemeText; } - */ - // Due to the fact that playerid is shown with level to mod clients, this function is disabled. //foreach (var SeerSubRole in seer.GetCustomSubRoles().ToArray()) //{ @@ -1213,8 +1217,6 @@ public static void Postfix(MeetingHud __instance) pva.NameText.text += sb.ToString(); pva.ColorBlindName.transform.localPosition -= new Vector3(1.35f, 0f, 0f); } - - __instance.SortButtons(); } } [HarmonyPatch(typeof(MeetingHud), nameof(MeetingHud.Update))] @@ -1226,8 +1228,6 @@ private static void ClearShootButton(MeetingHud __instance, bool forceAll = fals public static void Postfix(MeetingHud __instance) { - if (__instance == null || !GameStates.IsInGame) return; - //Meeting Skip with vote counting on keystroke (m + delete) if (AmongUsClient.Instance.AmHost && Input.GetKeyDown(KeyCode.F6)) { @@ -1270,7 +1270,7 @@ public static void Postfix(MeetingHud __instance) if (myRole is CustomRoles.NiceGuesser or CustomRoles.EvilGuesser or CustomRoles.Doomsayer or CustomRoles.Judge or CustomRoles.Councillor or CustomRoles.Guesser or CustomRoles.Swapper && !PlayerControl.LocalPlayer.IsAlive()) ClearShootButton(__instance, true); - + if (myRole is CustomRoles.Nemesis && !PlayerControl.LocalPlayer.IsAlive() && GameObject.Find("ShootButton") == null) Nemesis.CreateJudgeButton(__instance); if (myRole is CustomRoles.Retributionist && !PlayerControl.LocalPlayer.IsAlive() && GameObject.Find("ShootButton") == null) @@ -1307,4 +1307,4 @@ public static void Postfix() EAC.ReportTimes = []; } } -} +} \ No newline at end of file diff --git a/Patches/OneWayShadowsPatch.cs b/Patches/OneWayShadowsPatch.cs index c67fc59ef..4abe70114 100644 --- a/Patches/OneWayShadowsPatch.cs +++ b/Patches/OneWayShadowsPatch.cs @@ -7,7 +7,7 @@ public static class OneWayShadowsIsIgnoredPatch { public static bool Prefix(OneWayShadows __instance, ref bool __result) { - var amDesyncImpostor = PlayerControl.LocalPlayer.HasDesyncRole(); + var amDesyncImpostor = PlayerControl.LocalPlayer.HasDesyncRole() || Main.PlayerStates[PlayerControl.LocalPlayer.PlayerId].IsRandomizer; if (__instance.IgnoreImpostor && amDesyncImpostor) { diff --git a/Patches/OutroPatch.cs b/Patches/OutroPatch.cs index ec24e69c8..77eae47ef 100644 --- a/Patches/OutroPatch.cs +++ b/Patches/OutroPatch.cs @@ -1,16 +1,16 @@ using Hazel; +using TMPro; using System; using System.Text; -using TMPro; using TOHE.Modules; using TOHE.Modules.ChatManager; -using TOHE.Roles.Core; using TOHE.Roles.Core.AssignManager; -using TOHE.Roles.Crewmate; using TOHE.Roles.Impostor; using TOHE.Roles.Neutral; using UnityEngine; using static TOHE.Translator; +using TOHE.Roles.Crewmate; +using TOHE.Roles.Core; namespace TOHE; @@ -32,22 +32,43 @@ public static void Postfix(AmongUsClient __instance, [HarmonyArgument(0)] ref En { if (AmongUsClient.Instance.AmHost) { - foreach (var pvc in GhostRoleAssign.GhostGetPreviousRole.Keys) // Sets role back to original so it shows up in /l results. + foreach (var pvc in GhostRoleAssign.GhostGetPreviousRole.Keys) { - if (!Main.PlayerStates.TryGetValue(pvc, out var state) || !state.MainRole.IsGhostRole()) continue; + if (!Main.PlayerStates.TryGetValue(pvc, out var state)) continue; + + if (state.IsRandomizer) + { + // Ensure Randomizer role persists + state.MainRole = CustomRoles.Randomizer; + + MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.SyncPlayerSetting, SendOption.Reliable, -1); + writer.Write(pvc); + writer.WritePacked((int)CustomRoles.Randomizer); + AmongUsClient.Instance.FinishRpcImmediately(writer); + + Logger.Info($"Player {Utils.GetPlayerById(pvc).GetRealName()} is Randomizer. Ensuring role reverts to Randomizer.", "OutroPatch"); + continue; + } + + // Handle normal ghost role reversion + if (!state.MainRole.IsGhostRole()) continue; if (!GhostRoleAssign.GhostGetPreviousRole.TryGetValue(pvc, out CustomRoles prevrole)) continue; - Main.PlayerStates[pvc].MainRole = prevrole; + state.MainRole = prevrole; - MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.SyncPlayerSetting, SendOption.Reliable, -1); - writer.Write(pvc); - writer.WritePacked((int)prevrole); - AmongUsClient.Instance.FinishRpcImmediately(writer); + MessageWriter writerNormal = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.SyncPlayerSetting, SendOption.Reliable, -1); + writerNormal.Write(pvc); + writerNormal.WritePacked((int)prevrole); + AmongUsClient.Instance.FinishRpcImmediately(writerNormal); } - if (GhostRoleAssign.GhostGetPreviousRole.Any()) Logger.Info(string.Join(", ", GhostRoleAssign.GhostGetPreviousRole.Select(x => $"{Utils.GetPlayerById(x.Key).GetRealName()}/{x.Value}")), "OutroPatch.GhostGetPreviousRole"); + if (GhostRoleAssign.GhostGetPreviousRole.Any()) + { + Logger.Info(string.Join(", ", GhostRoleAssign.GhostGetPreviousRole.Select(x => $"{Utils.GetPlayerById(x.Key).GetRealName()}/{x.Value}")), "OutroPatch.GhostGetPreviousRole"); + } } + } catch (Exception e) { @@ -74,7 +95,6 @@ public static void Postfix(AmongUsClient __instance, [HarmonyArgument(0)] ref En } CustomRoleManager.RoleClass.Values.Where(x => x.IsEnable).Do(x => x.IsEnable = false); - CustomNetObject.Reset(); var sb = new StringBuilder(GetString("KillLog") + ":"); if (Options.OldKillLog.GetBool()) @@ -102,14 +122,14 @@ public static void Postfix(AmongUsClient __instance, [HarmonyArgument(0)] ref En if (killerId != byte.MaxValue && killerId != targetId) sb.Append($"
\t⇐ {Main.AllPlayerNames[killerId]}({(Options.CurrentGameMode == CustomGameMode.FFA ? string.Empty : Utils.GetDisplayRoleAndSubName(killerId, killerId, true))}{(Options.CurrentGameMode == CustomGameMode.FFA ? string.Empty : Utils.GetSubRolesText(killerId, summary: true))})"); } - + } KillLog = sb.ToString(); if (!KillLog.Contains('\n')) KillLog = ""; if (GameStates.IsNormalGame) Main.NormalOptions.KillCooldown = Options.DefaultKillCooldown; - + //winnerListリセット EndGameResult.CachedWinners = new Il2CppSystem.Collections.Generic.List(); var winner = new List(); @@ -200,7 +220,7 @@ public static void Postfix(EndGameManager __instance) { CustomWinnerText = GetWinnerRoleName(winnerRole); CustomWinnerColor = Utils.GetRoleColorCode(winnerRole); - // __instance.WinText.color = Utils.GetRoleColor(winnerRole); + // __instance.WinText.color = Utils.GetRoleColor(winnerRole); __instance.BackgroundBar.material.color = Utils.GetRoleColor(winnerRole); if (winnerRole.IsNeutral()) { @@ -211,7 +231,7 @@ public static void Postfix(EndGameManager __instance) { __instance.WinText.text = GetString("GameOver"); __instance.WinText.color = Utils.GetRoleColor(CustomRoles.GM); - __instance.BackgroundBar.material.color = Utils.GetRoleColor(winnerRole); + __instance.BackgroundBar.material.color = Utils.GetRoleColor(winnerRole); } switch (CustomWinnerHolder.WinnerTeam) { @@ -241,9 +261,9 @@ public static void Postfix(EndGameManager __instance) WinnerText.color = Color.gray; break; case CustomWinner.NiceMini: - // __instance.WinText.color = Utils.GetRoleColor(CustomRoles.Mini); + // __instance.WinText.color = Utils.GetRoleColor(CustomRoles.Mini); __instance.BackgroundBar.material.color = Utils.GetRoleColor(CustomRoles.NiceMini); - // WinnerText.text = GetString("NiceMiniDied"); + // WinnerText.text = GetString("NiceMiniDied"); WinnerText.color = Utils.GetRoleColor(CustomRoles.NiceMini); break; case CustomWinner.Neutrals: diff --git a/Patches/PhantomRolePatch.cs b/Patches/PhantomRolePatch.cs index 083d61f7b..802652dbf 100644 --- a/Patches/PhantomRolePatch.cs +++ b/Patches/PhantomRolePatch.cs @@ -1,5 +1,5 @@ -using AmongUs.GameOptions; -using Hazel; +using Hazel; +using AmongUs.GameOptions; using Il2CppInterop.Runtime.InteropTypes.Arrays; using TOHE.Roles.Core; using UnityEngine; diff --git a/Patches/PlayerControlPatch.cs b/Patches/PlayerControlPatch.cs index 43466097c..985e40a5c 100644 --- a/Patches/PlayerControlPatch.cs +++ b/Patches/PlayerControlPatch.cs @@ -3,20 +3,20 @@ using InnerNet; using System; using System.Text; -using System.Text.RegularExpressions; using System.Threading.Tasks; +using System.Text.RegularExpressions; +using UnityEngine; using TOHE.Modules; using TOHE.Patches; using TOHE.Roles.AddOns.Common; using TOHE.Roles.AddOns.Crewmate; -using TOHE.Roles.AddOns.Impostor; -using TOHE.Roles.Core; using TOHE.Roles.Core.AssignManager; +using TOHE.Roles.AddOns.Impostor; using TOHE.Roles.Crewmate; using TOHE.Roles.Double; using TOHE.Roles.Impostor; using TOHE.Roles.Neutral; -using UnityEngine; +using TOHE.Roles.Core; using static TOHE.Translator; namespace TOHE; @@ -27,7 +27,7 @@ class CheckProtectPatch public static bool Prefix(PlayerControl __instance, PlayerControl target) { if (!AmongUsClient.Instance.AmHost || GameStates.IsHideNSeek) return false; - Logger.Info($"{__instance.GetNameWithRole()} => {target.GetNameWithRole()}", "CheckProtect"); + Logger.Info($"{ __instance.GetNameWithRole()} => {target.GetNameWithRole()}", "CheckProtect"); var angel = __instance; if (AntiBlackout.SkipTasks) @@ -285,7 +285,14 @@ public static bool RpcCheckAndMurder(PlayerControl killer, PlayerControl target, { return false; } + if (killer.Is(CustomRoles.Summoned) && (target.Is(CustomRoles.Summoner) || target.Is(CustomRoles.Summoned))) + { + string errorMessage = "You cannot kill the Summoner or other summoned players!"; + killer.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Summoner), errorMessage)); + return false; // Cancel the kill + } + Logger.Info($"Start", "TargetSubRoles"); if (targetSubRoles.Any()) @@ -304,16 +311,18 @@ public static bool RpcCheckAndMurder(PlayerControl killer, PlayerControl target, case CustomRoles.Susceptible: Susceptible.CallEnabledAndChange(target); break; - + //case CustomRoles.Fragile: // if (Fragile.KillFragile(killer, target)) // return false; // break; - + case CustomRoles.LingeringPresence: + if (LingeringPresence.KillLingeringPresence(killer, target)) + return false; // Stop further checks if kill is successful + break; case CustomRoles.Aware: Aware.OnCheckMurder(killerRole, target); break; - case CustomRoles.Lucky: if (!Lucky.OnCheckMurder(killer, target)) return false; @@ -866,22 +875,6 @@ public static void AfterReportTasks(PlayerControl player, NetworkedPlayerInfo ta try { playerStates.RoleClass?.OnReportDeadBody(player, target); - if (playerStates.RoleClass?.BlockMoveInVent(playerStates.RoleClass._Player) ?? false) - { - foreach (var ventId in player.GetRoleClass().LastBlockedMoveInVentVents) - { - CustomRoleManager.BlockedVentsList[player.PlayerId].Remove(ventId); - } - player.GetRoleClass().LastBlockedMoveInVentVents.Clear(); - } - - if (playerStates.IsDead) - { - if (!Main.DeadPassedMeetingPlayers.Contains(playerStates.PlayerId)) - { - Main.DeadPassedMeetingPlayers.Add(playerStates.PlayerId); - } - } } catch (Exception error) { @@ -935,7 +928,6 @@ public static void AfterReportTasks(PlayerControl player, NetworkedPlayerInfo ta Logger.Info($"Player {pc?.Data?.PlayerName}: Id {pc.PlayerId} - is alive: {pc.IsAlive()}", "CheckIsAlive"); } - RPC.SyncDeadPassedMeetingList(); // Set meeting time MeetingTimeManager.OnReportDeadBody(); @@ -961,7 +953,7 @@ public static async void Postfix(PlayerControl __instance) { if (GameStates.IsHideNSeek) return; if (!GameStates.IsModHost) return; - if (__instance == null || __instance.PlayerId == 255) return; + if (__instance == null) return; byte id = __instance.PlayerId; if (AmongUsClient.Instance.AmHost && GameStates.IsInTask && ReportDeadBodyPatch.CanReport[id] && ReportDeadBodyPatch.WaitReport[id].Any()) @@ -997,7 +989,6 @@ public static Task DoPostfix(PlayerControl __instance) // For example: 15 players will called 450 times every 1 second var player = __instance; - bool localplayer = __instance.PlayerId == PlayerControl.LocalPlayer.PlayerId; // The code is called once every 1 second (by one player) bool lowLoad = false; @@ -1116,11 +1107,6 @@ public static Task DoPostfix(PlayerControl __instance) } } } - else // We are not in lobby - { - if (localplayer) - CustomNetObject.FixedUpdate(); - } DoubleTrigger.OnFixedUpdate(player); KillTimerManager.FixedUpdate(player); @@ -1145,6 +1131,19 @@ public static Task DoPostfix(PlayerControl __instance) player.OnFixedAddonUpdate(lowLoad); + if (Main.AllPlayerSpeed.ContainsKey(player.PlayerId) && !lowLoad) + { + if (!Main.LastAllPlayerSpeed.ContainsKey(player.PlayerId)) + { + Main.LastAllPlayerSpeed[player.PlayerId] = Main.AllPlayerSpeed[player.PlayerId]; + } + else if (!Main.LastAllPlayerSpeed[player.PlayerId].Equals(Main.AllPlayerSpeed[player.PlayerId])) + { + Main.LastAllPlayerSpeed[player.PlayerId] = Main.AllPlayerSpeed[player.PlayerId]; + player.SyncSpeed(); + } + } + if (Main.LateOutfits.TryGetValue(player.PlayerId, out var Method) && !player.CheckCamoflague()) { Method(); @@ -1181,46 +1180,10 @@ public static Task DoPostfix(PlayerControl __instance) } if (UnShapeshifter.CurrentOutfitType == PlayerOutfitType.Shapeshifted) continue; - - if (!UnShapeshifter.AmOwner) - { - var sstarget = PlayerControl.LocalPlayer; - UnShapeshifter.Shapeshift(PlayerControl.LocalPlayer, false); - UnShapeshifter.RejectShapeshift(); - - var writer = MessageWriter.Get(SendOption.Reliable); - writer.StartMessage(6); - writer.Write(AmongUsClient.Instance.GameId); - writer.WritePacked(UnShapeshifter.OwnerId); - - writer.StartMessage(2); - writer.WritePacked(UnShapeshifter.NetId); - writer.Write((byte)RpcCalls.Shapeshift); - writer.WriteNetObject(sstarget); - writer.Write(false); - writer.EndMessage(); - - writer.StartMessage(2); - writer.WritePacked(UnShapeshifter.NetId); - writer.Write((byte)RpcCalls.RejectShapeshift); - writer.EndMessage(); - - writer.EndMessage(); - AmongUsClient.Instance.SendOrDisconnect(writer); - writer.Recycle(); - - UnShapeshifter.ResetPlayerOutfit(setNamePlate: true); - } - else - { - // Host is Unshapeshifter, make button into unshapeshift state - PlayerControl.LocalPlayer.waitingForShapeshiftResponse = false; - var newOutfit = PlayerControl.LocalPlayer.Data.Outfits[PlayerOutfitType.Default]; - PlayerControl.LocalPlayer.RawSetOutfit(newOutfit, PlayerOutfitType.Shapeshifted); - PlayerControl.LocalPlayer.shapeshiftTargetPlayerId = PlayerControl.LocalPlayer.PlayerId; - DestroyableSingleton.Instance.AbilityButton.OverrideText(DestroyableSingleton.Instance.GetString(StringNames.ShapeshiftAbilityUndo)); - } - + var randomPlayer = Main.AllPlayerControls.FirstOrDefault(x => x != UnShapeshifter); + UnShapeshifter.RpcShapeshift(randomPlayer, false); + UnShapeshifter.RpcRejectShapeshift(); + UnShapeshifter.ResetPlayerOutfit(setNamePlate: true); Utils.NotifyRoles(SpecifyTarget: UnShapeshifter); Logger.Info($"Revert to shapeshifting state for: {player.GetRealName()}", "UnShapeShifer_FixedUpdate"); } @@ -1229,7 +1192,6 @@ public static Task DoPostfix(PlayerControl __instance) } } - if (!lowLoad) { if (!Main.DoBlockNameChange) @@ -1243,7 +1205,6 @@ public static Task DoPostfix(PlayerControl __instance) if (pc.Is(CustomRoles.Poisoner)) Main.AllPlayerKillCooldown[pc.PlayerId] = Poisoner.KillCooldown.GetFloat() * 2; - } } } @@ -1560,21 +1521,6 @@ public static bool Prefix(PlayerPhysics __instance, [HarmonyArgument(0)] int id) } playerRoleClass?.OnCoEnterVent(__instance, id); - - if (playerRoleClass?.BlockMoveInVent(__instance.myPlayer) ?? false) - { - playerRoleClass.LastBlockedMoveInVentVents.Clear(); - var vent = ShipStatus.Instance.AllVents.First(v => v.Id == id); - foreach (var nextvent in vent.NearbyVents.ToList()) - { - if (nextvent == null) continue; - // Skip current vent or ventid 5 in Dleks to prevent stuck - if (nextvent.Id == id || (GameStates.DleksIsActive && id is 5 && nextvent.Id is 6)) continue; - CustomRoleManager.BlockedVentsList[__instance.myPlayer.PlayerId].Add(nextvent.Id); - playerRoleClass.LastBlockedMoveInVentVents.Add(nextvent.Id); - } - __instance.myPlayer.RpcSetVentInteraction(); - } return true; } public static void Postfix() @@ -1622,14 +1568,6 @@ public static void Postfix(PlayerPhysics __instance, [HarmonyArgument(0)] int id if (!AmongUsClient.Instance.AmHost) return; player.GetRoleClass()?.OnExitVent(player, id); - if (player.GetRoleClass()?.BlockMoveInVent(player) ?? false) - { - foreach (var ventId in player.GetRoleClass().LastBlockedMoveInVentVents) - { - CustomRoleManager.BlockedVentsList[player.PlayerId].Remove(ventId); - } - player.GetRoleClass().LastBlockedMoveInVentVents.Clear(); - } _ = new LateTask(() => { player?.RpcSetVentInteraction(); }, 0.8f, $"Set vent interaction after exit vent {player?.PlayerId}", shoudLog: false); } @@ -1688,9 +1626,11 @@ public static bool Prefix(PlayerControl __instance, uint idx) case CustomRoles.Ghoul when taskState.CompletedTasksCount >= taskState.AllTasksCount: Ghoul.OnTaskComplete(player); break; + + case CustomRoles.Madmate when taskState.IsTaskFinished && player.Is(CustomRoles.Snitch): - foreach (var impostor in Main.AllAlivePlayerControls.Where(pc => pc.Is(Custom_Team.Impostor)).ToArray()) + foreach (var impostor in Main.AllAlivePlayerControls.Where(pc => pc.Is(Custom_Team.Impostor) || !Main.PlayerStates[pc.PlayerId].IsRandomizer).ToArray()) { NameColorManager.Add(impostor.PlayerId, player.PlayerId, "#ff1919"); } @@ -1818,7 +1758,9 @@ public static void Postfix(PlayerControl __instance) } // if player is Desync Impostor and the vanilla sees player as Imposter, the vanilla process does not hide your name, so the other person's name is hidden - if (!PlayerControl.LocalPlayer.Is(Custom_Team.Impostor) && // Not an Impostor + if ((!PlayerControl.LocalPlayer.Is(Custom_Team.Impostor) // Not an Impostor + || Main.PlayerStates[PlayerControl.LocalPlayer.PlayerId].IsRandomizer // Necromancer + ) && // Not an Impostor PlayerControl.LocalPlayer.HasDesyncRole()) // Desync Impostor { // Hide names diff --git a/Patches/PlayerJoinAndLeftPatch.cs b/Patches/PlayerJoinAndLeftPatch.cs index 885514918..3ee65b4bf 100644 --- a/Patches/PlayerJoinAndLeftPatch.cs +++ b/Patches/PlayerJoinAndLeftPatch.cs @@ -6,8 +6,8 @@ using System.Text.RegularExpressions; using TOHE.Modules; using TOHE.Patches; -using TOHE.Roles.Core.AssignManager; using TOHE.Roles.Crewmate; +using TOHE.Roles.Core.AssignManager; using static TOHE.Translator; namespace TOHE; @@ -112,7 +112,7 @@ public static void Postfix(AmongUsClient __instance) if (!GameStates.IsOnlineGame) return; if (!GameStates.IsModHost) RPC.RpcRequestRetryVersionCheck(); - if (BanManager.CheckEACList(EOSManager.Instance.FriendCode, BanManager.GetHashedPuid(EOSManager.Instance.ProductUserId)) && GameStates.IsOnlineGame) + if (BanManager.CheckEACList(PlayerControl.LocalPlayer.FriendCode, PlayerControl.LocalPlayer.GetClient().GetHashedPuid()) && GameStates.IsOnlineGame) { AmongUsClient.Instance.ExitGame(DisconnectReasons.Banned); SceneChanger.ChangeScene("MainMenu"); @@ -154,7 +154,6 @@ class DisconnectInternalPatch { public static void Prefix(InnerNetClient __instance, DisconnectReasons reason, string stringReason) { - GameStates.InGame = false; Logger.Info($"Disconnect (Reason:{reason}:{stringReason}, ping:{__instance.Ping})", "Reason Disconnect"); RehostManager.OnDisconnectInternal(reason); } @@ -247,7 +246,7 @@ public static void Postfix(/*AmongUsClient __instance,*/ [HarmonyArgument(0)] Cl } } - if (AmongUsClient.Instance.AmHost && Options.AllowOnlyWhiteList.GetBool() && !BanManager.CheckAllowList(client?.FriendCode) && !GameStates.IsLocalGame) + if (Options.AllowOnlyWhiteList.GetBool() && !BanManager.CheckAllowList(client?.FriendCode) && !GameStates.IsLocalGame) { AmongUsClient.Instance.KickPlayer(client.Id, false); Logger.SendInGame(string.Format(GetString("Message.KickedByWhiteList"), client.PlayerName)); @@ -328,10 +327,7 @@ static void Prefix([HarmonyArgument(0)] ClientData data) } if (GameStates.IsNormalGame && GameStates.IsInGame) - { - if (data.Character != null) CustomNetObject.DespawnOnQuit(data.Character.PlayerId); MurderPlayerPatch.AfterPlayerDeathTasks(data?.Character, data?.Character, GameStates.IsMeeting); - } if (AmongUsClient.Instance.AmHost && data.Character != null) { @@ -376,7 +372,7 @@ public static void Postfix(AmongUsClient __instance, [HarmonyArgument(0)] Client } } - Spiritualist.RemoveTarget(data.Character.PlayerId); + if (Spiritualist.HasEnabled) Spiritualist.RemoveTarget(data.Character.PlayerId); var state = Main.PlayerStates[data.Character.PlayerId]; state.Disconnected = true; @@ -415,8 +411,7 @@ public static void Postfix(AmongUsClient __instance, [HarmonyArgument(0)] Client var msg = ""; if (GameStates.IsInGame) { - CriticalErrorManager.SetCreiticalError("Host exits the game", false); - CriticalErrorManager.CheckEndGame(); + Utils.ErrorEnd("Host exits the game"); msg = GetString("Message.HostLeftGameInGame"); } else if (GameStates.IsLobby) @@ -491,19 +486,18 @@ public static void Postfix(AmongUsClient __instance, [HarmonyArgument(0)] Client // End the game when a player exits game during assigning roles (AntiBlackOut Protect) if (Main.AssignRolesIsStarted) { - CriticalErrorManager.SetCreiticalError("The player left the game during assigning roles", true); + Utils.ErrorEnd("The player left the game during assigning roles"); } if (data != null) - { Main.playerVersion.Remove(data.Id); - Main.SayStartTimes.Remove(data.Id); - Main.SayBanwordsTimes.Remove(data.Id); - } if (AmongUsClient.Instance.AmHost) { + Main.SayStartTimes.Remove(__instance.ClientId); + Main.SayBanwordsTimes.Remove(__instance.ClientId); + if (GameStates.IsLobby && !GameStates.IsLocalGame) { if (data?.GetHashedPuid() != "" && Options.TempBanPlayersWhoKeepQuitting.GetBool() @@ -531,19 +525,6 @@ public static void Postfix(AmongUsClient __instance, [HarmonyArgument(0)] Client MeetingHud.Instance.CheckForEndVoting(); } } - - if (GameStates.IsInGame) - { - if (data != null) - { - var networkedPlayerInfo = GameData.Instance.GetPlayerByClient(data); - if (networkedPlayerInfo != null) - { - networkedPlayerInfo.PlayerName = Main.AllClientRealNames[networkedPlayerInfo.ClientId]; - networkedPlayerInfo.MarkDirty(); - } - } - } } } catch (Exception error) diff --git a/Patches/RandomSpawnPatch.cs b/Patches/RandomSpawnPatch.cs index 8bb60d0f3..c9779ff62 100644 --- a/Patches/RandomSpawnPatch.cs +++ b/Patches/RandomSpawnPatch.cs @@ -16,7 +16,7 @@ public class SnapToPatch public static void Prefix(CustomNetworkTransform __instance, [HarmonyArgument(1)] ushort minSid) { if (AmongUsClient.Instance.AmHost) return; - if (__instance.myPlayer.PlayerId == 255) return; + Logger.Info($"Player Id {__instance.myPlayer.PlayerId} - old sequence {__instance.lastSequenceId} - new sequence {minSid}", "SnapToPatch"); } } @@ -26,7 +26,7 @@ public class CustomNetworkTransformHandleRpcPatch public static bool Prefix(CustomNetworkTransform __instance, [HarmonyArgument(0)] byte callId, [HarmonyArgument(1)] MessageReader reader) { if (!AmongUsClient.Instance.AmHost) return true; - + if (!__instance.isActiveAndEnabled) { return false; @@ -159,7 +159,6 @@ public static void AirshipSpawn(PlayerControl player) public static bool IsRandomSpawn() => RandomSpawnMode.GetBool(); public static bool CanSpawnInFirstRound() => SpawnInFirstRound.GetBool(); - [Obfuscation(Exclude = true)] private enum RandomSpawnOpt { RandomSpawnMode, @@ -240,7 +239,7 @@ public Vector2 GetLocation(bool first = false) if (first) return locations[0].Value; var location = locations.ToArray().OrderBy(_ => Guid.NewGuid()).Take(1).FirstOrDefault(); - + if (GameStates.AirshipIsActive && !AirshipAdditionalSpawn.GetBool()) location = locations.ToArray()[0..6].OrderBy(_ => Guid.NewGuid()).Take(1).FirstOrDefault(); @@ -252,61 +251,61 @@ public class SkeldSpawnMap : SpawnMap { public override Dictionary Positions { get; } = new() { - ["Cafeteria"] = new Vector2(-1.0f, 3.0f), - ["Weapons"] = new Vector2(9.3f, 1.0f), - ["O2"] = new Vector2(6.5f, -3.8f), - ["Navigation"] = new Vector2(16.5f, -4.8f), - ["Shields"] = new Vector2(9.3f, -12.3f), - ["Communications"] = new Vector2(4.0f, -15.5f), - ["Storage"] = new Vector2(-1.5f, -15.5f), - ["Admin"] = new Vector2(4.5f, -7.9f), - ["Electrical"] = new Vector2(-7.5f, -8.8f), - ["LowerEngine"] = new Vector2(-17.0f, -13.5f), - ["UpperEngine"] = new Vector2(-17.0f, -1.3f), - ["Security"] = new Vector2(-13.5f, -5.5f), - ["Reactor"] = new Vector2(-20.5f, -5.5f), - ["MedBay"] = new Vector2(-9.0f, -4.0f) + ["Cafeteria"] = new Vector2 (-1.0f, 3.0f), + ["Weapons"] = new Vector2 (9.3f, 1.0f), + ["O2"] = new Vector2 (6.5f, -3.8f), + ["Navigation"] = new Vector2 (16.5f, -4.8f), + ["Shields"] = new Vector2 (9.3f, -12.3f), + ["Communications"] = new Vector2 (4.0f, -15.5f), + ["Storage"] = new Vector2 (-1.5f, -15.5f), + ["Admin"] = new Vector2 (4.5f, -7.9f), + ["Electrical"] = new Vector2 (-7.5f, -8.8f), + ["LowerEngine"] = new Vector2 (-17.0f, -13.5f), + ["UpperEngine"] = new Vector2 (-17.0f, -1.3f), + ["Security"] = new Vector2 (-13.5f, -5.5f), + ["Reactor"] = new Vector2 (-20.5f, -5.5f), + ["MedBay"] = new Vector2 (-9.0f, -4.0f) }; } public class MiraHQSpawnMap : SpawnMap { public override Dictionary Positions { get; } = new() { - ["Cafeteria"] = new Vector2(25.5f, 2.0f), - ["Balcony"] = new Vector2(24.0f, -2.0f), - ["Storage"] = new Vector2(19.5f, 4.0f), - ["ThreeWay"] = new Vector2(17.8f, 11.5f), - ["Communications"] = new Vector2(15.3f, 3.8f), - ["MedBay"] = new Vector2(15.5f, -0.5f), - ["LockerRoom"] = new Vector2(9.0f, 1.0f), - ["Decontamination"] = new Vector2(6.1f, 6.0f), - ["Laboratory"] = new Vector2(9.5f, 12.0f), - ["Reactor"] = new Vector2(2.5f, 10.5f), - ["Launchpad"] = new Vector2(-4.5f, 2.0f), - ["Admin"] = new Vector2(21.0f, 17.5f), - ["Office"] = new Vector2(15.0f, 19.0f), - ["Greenhouse"] = new Vector2(17.8f, 23.0f) + ["Cafeteria"] = new Vector2 (25.5f, 2.0f), + ["Balcony"] = new Vector2 (24.0f, -2.0f), + ["Storage"] = new Vector2 (19.5f, 4.0f), + ["ThreeWay"] = new Vector2 (17.8f, 11.5f), + ["Communications"] = new Vector2 (15.3f, 3.8f), + ["MedBay"] = new Vector2 (15.5f, -0.5f), + ["LockerRoom"] = new Vector2 (9.0f, 1.0f), + ["Decontamination"] = new Vector2 (6.1f, 6.0f), + ["Laboratory"] = new Vector2 (9.5f, 12.0f), + ["Reactor"] = new Vector2 (2.5f, 10.5f), + ["Launchpad"] = new Vector2 (-4.5f, 2.0f), + ["Admin"] = new Vector2 (21.0f, 17.5f), + ["Office"] = new Vector2 (15.0f, 19.0f), + ["Greenhouse"] = new Vector2 (17.8f, 23.0f) }; } public class PolusSpawnMap : SpawnMap { public override Dictionary Positions { get; } = new() { - ["OfficeLeft"] = new Vector2(19.5f, -18.0f), - ["OfficeRight"] = new Vector2(26.0f, -17.0f), - ["Admin"] = new Vector2(24.0f, -22.5f), - ["Communications"] = new Vector2(12.5f, -16.0f), - ["Weapons"] = new Vector2(12.0f, -23.5f), - ["BoilerRoom"] = new Vector2(2.3f, -24.0f), - ["O2"] = new Vector2(2.0f, -17.5f), - ["Electrical"] = new Vector2(9.5f, -12.5f), - ["Security"] = new Vector2(3.0f, -12.0f), - ["Dropship"] = new Vector2(16.7f, -3.0f), - ["Storage"] = new Vector2(20.5f, -12.0f), - ["Rocket"] = new Vector2(26.7f, -8.5f), - ["Laboratory"] = new Vector2(36.5f, -7.5f), - ["Toilet"] = new Vector2(34.0f, -10.0f), - ["SpecimenRoom"] = new Vector2(36.5f, -22.0f) + ["OfficeLeft"] = new Vector2 (19.5f, -18.0f), + ["OfficeRight"] = new Vector2 (26.0f, -17.0f), + ["Admin"] = new Vector2 (24.0f, -22.5f), + ["Communications"] = new Vector2 (12.5f, -16.0f), + ["Weapons"] = new Vector2 (12.0f, -23.5f), + ["BoilerRoom"] = new Vector2 (2.3f, -24.0f), + ["O2"] = new Vector2 (2.0f, -17.5f), + ["Electrical"] = new Vector2 (9.5f, -12.5f), + ["Security"] = new Vector2 (3.0f, -12.0f), + ["Dropship"] = new Vector2 (16.7f, -3.0f), + ["Storage"] = new Vector2 (20.5f, -12.0f), + ["Rocket"] = new Vector2 (26.7f, -8.5f), + ["Laboratory"] = new Vector2 (36.5f, -7.5f), + ["Toilet"] = new Vector2 (34.0f, -10.0f), + ["SpecimenRoom"] = new Vector2 (36.5f, -22.0f) }; } @@ -321,25 +320,25 @@ public class AirshipSpawnMap : SpawnMap { public override Dictionary Positions { get; } = new() { - ["Brig"] = new Vector2(-0.7f, 8.5f), - ["Engine"] = new Vector2(-0.7f, -1.0f), - ["Kitchen"] = new Vector2(-7.0f, -11.5f), - ["CargoBay"] = new Vector2(33.5f, -1.5f), - ["Records"] = new Vector2(20.0f, 10.5f), - ["MainHall"] = new Vector2(15.5f, 0.0f), - ["NapRoom"] = new Vector2(6.3f, 2.5f), - ["MeetingRoom"] = new Vector2(17.1f, 14.9f), - ["GapRoom"] = new Vector2(12.0f, 8.5f), - ["Vault"] = new Vector2(-8.9f, 12.2f), - ["Communications"] = new Vector2(-13.3f, 1.3f), - ["Cockpit"] = new Vector2(-23.5f, -1.6f), - ["Armory"] = new Vector2(-10.3f, -5.9f), - ["ViewingDeck"] = new Vector2(-13.7f, -12.6f), - ["Security"] = new Vector2(5.8f, -10.8f), - ["Electrical"] = new Vector2(16.3f, -8.8f), - ["Medical"] = new Vector2(29.0f, -6.2f), - ["Toilet"] = new Vector2(30.9f, 6.8f), - ["Showers"] = new Vector2(21.2f, -0.8f) + ["Brig"] = new Vector2 (-0.7f, 8.5f), + ["Engine"] = new Vector2 (-0.7f, -1.0f), + ["Kitchen"] = new Vector2 (-7.0f, -11.5f), + ["CargoBay"] = new Vector2 (33.5f, -1.5f), + ["Records"] = new Vector2 (20.0f, 10.5f), + ["MainHall"] = new Vector2 (15.5f, 0.0f), + ["NapRoom"] = new Vector2 (6.3f, 2.5f), + ["MeetingRoom"] = new Vector2 (17.1f, 14.9f), + ["GapRoom"] = new Vector2 (12.0f, 8.5f), + ["Vault"] = new Vector2 (-8.9f, 12.2f), + ["Communications"] = new Vector2 (-13.3f, 1.3f), + ["Cockpit"] = new Vector2 (-23.5f, -1.6f), + ["Armory"] = new Vector2 (-10.3f, -5.9f), + ["ViewingDeck"] = new Vector2 (-13.7f, -12.6f), + ["Security"] = new Vector2 (5.8f, -10.8f), + ["Electrical"] = new Vector2 (16.3f, -8.8f), + ["Medical"] = new Vector2 (29.0f, -6.2f), + ["Toilet"] = new Vector2 (30.9f, 6.8f), + ["Showers"] = new Vector2 (21.2f, -0.8f) }; } public class FungleSpawnMap : SpawnMap @@ -366,4 +365,4 @@ public class FungleSpawnMap : SpawnMap ["Communications"] = new Vector2(22.2f, 13.7f) }; } -} +} \ No newline at end of file diff --git a/Patches/SabotageSystemPatch.cs b/Patches/SabotageSystemPatch.cs index 6db11ec7b..5801aeef4 100644 --- a/Patches/SabotageSystemPatch.cs +++ b/Patches/SabotageSystemPatch.cs @@ -128,223 +128,253 @@ public static void Postfix() foreach (var pc in Main.AllAlivePlayerControls) { - if (!pc.Is(Custom_Team.Impostor) && pc.HasDesyncRole()) - { - // Need for hiding player names if player is desync Impostor - Utils.NotifyRoles(SpecifySeer: pc, ForceLoop: true, MushroomMixupIsActive: true); + if ((!pc.Is(Custom_Team.Impostor) || Main.PlayerStates[pc.PlayerId].IsRandomizer) && pc.HasDesyncRole()) + + { + // Need for hiding player names if player is desync Impostor + Utils.NotifyRoles(SpecifySeer: pc, ForceLoop: true, MushroomMixupIsActive: true); + } } } } - } - [HarmonyPatch(typeof(MushroomMixupSabotageSystem), nameof(MushroomMixupSabotageSystem.Deteriorate))] - private static class MushroomMixupSabotageSystemPatch - { - private static void Prefix(MushroomMixupSabotageSystem __instance, ref bool __state) + [HarmonyPatch(typeof(MushroomMixupSabotageSystem), nameof(MushroomMixupSabotageSystem.Deteriorate))] + private static class MushroomMixupSabotageSystemPatch { - __state = __instance.IsActive; + private static void Prefix(MushroomMixupSabotageSystem __instance, ref bool __state) + { + __state = __instance.IsActive; - if (!Options.SabotageTimeControl.GetBool()) return; - if (!GameStates.FungleIsActive) return; + if (!Options.SabotageTimeControl.GetBool()) return; + if (!GameStates.FungleIsActive) return; - // If Mushroom Mixup sabotage is end - if (!__instance.IsActive || !SetDurationMushroomMixupSabotage) - { - if (!SetDurationMushroomMixupSabotage && !__instance.IsActive) + // If Mushroom Mixup sabotage is end + if (!__instance.IsActive || !SetDurationMushroomMixupSabotage) { - SetDurationMushroomMixupSabotage = true; + if (!SetDurationMushroomMixupSabotage && !__instance.IsActive) + { + SetDurationMushroomMixupSabotage = true; + } + return; } - return; - } - - Logger.Info($" {ShipStatus.Instance.Type}", "MushroomMixupSabotageSystem - ShipStatus.Instance.Type"); - Logger.Info($" {SetDurationMushroomMixupSabotage}", "MushroomMixupSabotageSystem - SetDurationCriticalSabotage"); - SetDurationMushroomMixupSabotage = false; - // Set duration Mushroom Mixup (The Fungle) - __instance.currentSecondsUntilHeal = Options.FungleMushroomMixupDuration.GetFloat(); - } - public static void Postfix(MushroomMixupSabotageSystem __instance, bool __state) - { - if (GameStates.IsHideNSeek) return; + Logger.Info($" {ShipStatus.Instance.Type}", "MushroomMixupSabotageSystem - ShipStatus.Instance.Type"); + Logger.Info($" {SetDurationMushroomMixupSabotage}", "MushroomMixupSabotageSystem - SetDurationCriticalSabotage"); + SetDurationMushroomMixupSabotage = false; - // if Mushroom Mixup Sabotage is end - if (__instance.IsActive != __state && !Main.MeetingIsStarted) + // Set duration Mushroom Mixup (The Fungle) + __instance.currentSecondsUntilHeal = Options.FungleMushroomMixupDuration.GetFloat(); + } + public static void Postfix(MushroomMixupSabotageSystem __instance, bool __state) { - Logger.Info($" IsEnd", "MushroomMixupSabotageSystem.Deteriorate.Postfix"); + if (GameStates.IsHideNSeek) return; - if (AmongUsClient.Instance.AmHost) + // if Mushroom Mixup Sabotage is end + if (__instance.IsActive != __state && !Main.MeetingIsStarted) { - _ = new LateTask(() => + Logger.Info($" IsEnd", "MushroomMixupSabotageSystem.Deteriorate.Postfix"); + + if (AmongUsClient.Instance.AmHost) { - // After MushroomMixup sabotage, shapeshift cooldown sets to 0 - foreach (var pc in Main.AllAlivePlayerControls) + _ = new LateTask(() => { - // Reset Ability Cooldown To Default For Alive Players - pc.RpcResetAbilityCooldown(); - } - }, 1.2f, "Reset Ability Cooldown Arter Mushroom Mixup"); + // After MushroomMixup sabotage, shapeshift cooldown sets to 0 + foreach (var pc in Main.AllAlivePlayerControls) + { + // Reset Ability Cooldown To Default For Alive Players + pc.RpcResetAbilityCooldown(); + } + }, 1.2f, "Reset Ability Cooldown Arter Mushroom Mixup"); - foreach (var pc in Main.AllAlivePlayerControls) - { - if (!pc.Is(Custom_Team.Impostor) && pc.HasDesyncRole()) + foreach (var pc in Main.AllAlivePlayerControls) { - // Need for display player names if player is desync Impostor - Utils.NotifyRoles(SpecifySeer: pc, ForceLoop: true); + if ((!pc.Is(Custom_Team.Impostor) || Main.PlayerStates[pc.PlayerId].IsRandomizer) && pc.HasDesyncRole()) + + { + // Need for display player names if player is desync Impostor + Utils.NotifyRoles(SpecifySeer: pc, ForceLoop: true); + } } } } } } - } - [HarmonyPatch(typeof(SwitchSystem), nameof(SwitchSystem.UpdateSystem))] - private static class SwitchSystemUpdatePatch - { - private static bool Prefix(SwitchSystem __instance, [HarmonyArgument(0)] PlayerControl player, [HarmonyArgument(1)] MessageReader msgReader) + [HarmonyPatch(typeof(SwitchSystem), nameof(SwitchSystem.UpdateSystem))] + private static class SwitchSystemUpdatePatch { - if (GameStates.IsHideNSeek) return false; - - byte amount; + private static bool Prefix(SwitchSystem __instance, [HarmonyArgument(0)] PlayerControl player, [HarmonyArgument(1)] MessageReader msgReader) { - var newReader = MessageReader.Get(msgReader); - amount = newReader.ReadByte(); - newReader.Recycle(); - } + if (GameStates.IsHideNSeek) return false; - if (!AmongUsClient.Instance.AmHost) - { - return true; - } + byte amount; + { + var newReader = MessageReader.Get(msgReader); + amount = newReader.ReadByte(); + newReader.Recycle(); + } - // No matter if the blackout sabotage is sounded (beware of misdirection as it flies under the host's name) - if (amount.HasBit(SwitchSystem.DamageSystem)) - { - return true; - } + if (!AmongUsClient.Instance.AmHost) + { + return true; + } - // Cancel if player can't fix a specific outage on Airship - if (GameStates.AirshipIsActive) - { - var truePosition = player.GetCustomPosition(); - if (Options.DisableAirshipViewingDeckLightsPanel.GetBool() && Utils.GetDistance(truePosition, new(-12.93f, -11.28f)) <= 2f) return false; - if (Options.DisableAirshipGapRoomLightsPanel.GetBool() && Utils.GetDistance(truePosition, new(13.92f, 6.43f)) <= 2f) return false; - if (Options.DisableAirshipCargoLightsPanel.GetBool() && Utils.GetDistance(truePosition, new(30.56f, 2.12f)) <= 2f) return false; - } + // No matter if the blackout sabotage is sounded (beware of misdirection as it flies under the host's name) + if (amount.HasBit(SwitchSystem.DamageSystem)) + { + return true; + } - if (Fool.IsEnable && player.Is(CustomRoles.Fool)) - { - return false; - } + // Cancel if player can't fix a specific outage on Airship + if (GameStates.AirshipIsActive) + { + var truePosition = player.GetCustomPosition(); + if (Options.DisableAirshipViewingDeckLightsPanel.GetBool() && Utils.GetDistance(truePosition, new(-12.93f, -11.28f)) <= 2f) return false; + if (Options.DisableAirshipGapRoomLightsPanel.GetBool() && Utils.GetDistance(truePosition, new(13.92f, 6.43f)) <= 2f) return false; + if (Options.DisableAirshipCargoLightsPanel.GetBool() && Utils.GetDistance(truePosition, new(30.56f, 2.12f)) <= 2f) return false; + } - if (Options.BlockDisturbancesToSwitches.GetBool()) - { - // Shift 1 to the left by amount - // Each digit corresponds to each switch - // Far left switch - (amount: 0) 00001 - // Far right switch - (amount: 4) 10000 - // ref: SwitchSystem.RepairDamage, SwitchMinigame.FixedUpdate - var switchedKnob = (byte)(0b_00001 << amount); - - // ExpectedSwitches: Up and down state of switches when all are on - // ActualSwitches: Actual up/down state of switch - // if Expected and Actual are the same for the operated knob, the knob is already fixed - if ((__instance.ActualSwitches & switchedKnob) == (__instance.ExpectedSwitches & switchedKnob)) + if (Fool.IsEnable && player.Is(CustomRoles.Fool)) { return false; } - } - return true; + if (Options.BlockDisturbancesToSwitches.GetBool()) + { + // Shift 1 to the left by amount + // Each digit corresponds to each switch + // Far left switch - (amount: 0) 00001 + // Far right switch - (amount: 4) 10000 + // ref: SwitchSystem.RepairDamage, SwitchMinigame.FixedUpdate + var switchedKnob = (byte)(0b_00001 << amount); + + // ExpectedSwitches: Up and down state of switches when all are on + // ActualSwitches: Actual up/down state of switch + // if Expected and Actual are the same for the operated knob, the knob is already fixed + if ((__instance.ActualSwitches & switchedKnob) == (__instance.ExpectedSwitches & switchedKnob)) + { + return false; + } + } + + return true; + } } - } - [HarmonyPatch(typeof(ElectricTask), nameof(ElectricTask.Initialize))] - public static class ElectricTaskInitializePatch - { - public static void Postfix() + [HarmonyPatch(typeof(ElectricTask), nameof(ElectricTask.Initialize))] + public static class ElectricTaskInitializePatch { - Utils.MarkEveryoneDirtySettings(); - if (!GameStates.IsMeeting) - Utils.NotifyRoles(ForceLoop: true); - } - } - [HarmonyPatch(typeof(ElectricTask), nameof(ElectricTask.Complete))] - public static class ElectricTaskCompletePatch - { - public static void Postfix() - { - Utils.MarkEveryoneDirtySettings(); - if (!GameStates.IsMeeting) - Utils.NotifyRoles(ForceLoop: true); + public static void Postfix() + { + Utils.MarkEveryoneDirtySettings(); + if (!GameStates.IsMeeting) + Utils.NotifyRoles(ForceLoop: true); + } } - } - // https://github.com/tukasa0001/TownOfHost/blob/357f7b5523e4bdd0bb58cda1e0ff6cceaa84813d/Patches/SabotageSystemPatch.cs - // Method called when sabotage occurs - [HarmonyPatch(typeof(SabotageSystemType), nameof(SabotageSystemType.UpdateSystem))] // SetInitialSabotageCooldown - set sabotage cooldown in start game - public static class SabotageSystemTypeRepairDamagePatch - { - private static bool isCooldownModificationEnabled; - private static float modifiedCooldownSec; - - public static void Initialize() + [HarmonyPatch(typeof(ElectricTask), nameof(ElectricTask.Complete))] + public static class ElectricTaskCompletePatch { - isCooldownModificationEnabled = Options.SabotageCooldownControl.GetBool(); - modifiedCooldownSec = Options.SabotageCooldown.GetFloat(); + public static void Postfix() + { + Utils.MarkEveryoneDirtySettings(); + if (!GameStates.IsMeeting) + Utils.NotifyRoles(ForceLoop: true); + } } - - private static bool Prefix([HarmonyArgument(0)] PlayerControl player, [HarmonyArgument(1)] MessageReader msgReader) + // https://github.com/tukasa0001/TownOfHost/blob/357f7b5523e4bdd0bb58cda1e0ff6cceaa84813d/Patches/SabotageSystemPatch.cs + // Method called when sabotage occurs + [HarmonyPatch(typeof(SabotageSystemType), nameof(SabotageSystemType.UpdateSystem))] // SetInitialSabotageCooldown - set sabotage cooldown in start game + public static class SabotageSystemTypeRepairDamagePatch { - if (GameStates.IsHideNSeek) return false; + private static bool isCooldownModificationEnabled; + private static float modifiedCooldownSec; - byte amount; + public static void Initialize() { - var newReader = MessageReader.Get(msgReader); - amount = newReader.ReadByte(); - newReader.Recycle(); + isCooldownModificationEnabled = Options.SabotageCooldownControl.GetBool(); + modifiedCooldownSec = Options.SabotageCooldown.GetFloat(); } - var nextSabotage = (SystemTypes)amount; - if (Options.DisableSabotage.GetBool()) + private static bool Prefix([HarmonyArgument(0)] PlayerControl player, [HarmonyArgument(1)] MessageReader msgReader) { - return false; - } + if (GameStates.IsHideNSeek) return false; - Logger.Info($"PlayerName: {player.GetNameWithRole()}, SabotageType: {nextSabotage}, amount {amount}", "SabotageSystemType.UpdateSystem"); + byte amount; + { + var newReader = MessageReader.Get(msgReader); + amount = newReader.ReadByte(); + newReader.Recycle(); + } + var nextSabotage = (SystemTypes)amount; - return CanSabotage(player, nextSabotage); - } - private static bool CanSabotage(PlayerControl player, SystemTypes systemType) - { - if (systemType is SystemTypes.Comms) + if (Options.DisableSabotage.GetBool()) + { + return false; + } + + Logger.Info($"PlayerName: {player.GetNameWithRole()}, SabotageType: {nextSabotage}, amount {amount}", "SabotageSystemType.UpdateSystem"); + + return CanSabotage(player, nextSabotage); + } + private static bool CanSabotage(PlayerControl player, SystemTypes systemType) { - if (Camouflager.CantPressCommsSabotageButton(player)) + if (systemType is SystemTypes.Comms) + { + if (Camouflager.CantPressCommsSabotageButton(player)) + return false; + } + + if (player.GetRoleClass() is Glitch gc) + { + gc.Mimic(player); return false; + } + + return player.CanUseSabotage(); } - if (player.GetRoleClass() is Glitch gc) + public static void Postfix(SabotageSystemType __instance, bool __runOriginal) { - gc.Mimic(player); - return false; - } + // __runOriginal - the result that was returned from Prefix + if (!AmongUsClient.Instance.AmHost || GameStates.IsHideNSeek || !__runOriginal || !isCooldownModificationEnabled) + { + return; + } - return player.CanUseSabotage(); - } + // Set cooldown sabotages + __instance.Timer = modifiedCooldownSec; + __instance.IsDirty = true; + } - public static void Postfix(SabotageSystemType __instance, bool __runOriginal) - { - // __runOriginal - the result that was returned from Prefix - if (!AmongUsClient.Instance.AmHost || GameStates.IsHideNSeek || !__runOriginal || !isCooldownModificationEnabled) + [HarmonyPatch(typeof(SecurityCameraSystemType), nameof(SecurityCameraSystemType.UpdateSystem))] + private static class SecurityCameraSystemTypeUpdateSystemPatch { - return; - } + private static bool Prefix([HarmonyArgument(1)] MessageReader msgReader) + { + byte amount; + { + var newReader = MessageReader.Get(msgReader); + amount = newReader.ReadByte(); + newReader.Recycle(); + } - // Set cooldown sabotages - __instance.Timer = modifiedCooldownSec; - __instance.IsDirty = true; + // When the camera is disabled, the vanilla player opens the camera so it does not blink. + if (amount == SecurityCameraSystemType.IncrementOp) + { + var camerasDisabled = Utils.GetActiveMapName() switch + { + MapNames.Skeld or MapNames.Dleks => Options.DisableSkeldCamera.GetBool(), + MapNames.Polus => Options.DisablePolusCamera.GetBool(), + MapNames.Airship => Options.DisableAirshipCamera.GetBool(), + _ => false, + }; + return !camerasDisabled; + } + return true; + } + } } - - [HarmonyPatch(typeof(SecurityCameraSystemType), nameof(SecurityCameraSystemType.UpdateSystem))] - private static class SecurityCameraSystemTypeUpdateSystemPatch + [HarmonyPatch(typeof(DoorsSystemType), nameof(DoorsSystemType.UpdateSystem))] + public static class DoorsSystemTypePatch { - private static bool Prefix([HarmonyArgument(1)] MessageReader msgReader) + public static void Prefix(/*DoorsSystemType __instance,*/ PlayerControl player, MessageReader msgReader) { byte amount; { @@ -353,35 +383,7 @@ private static bool Prefix([HarmonyArgument(1)] MessageReader msgReader) newReader.Recycle(); } - // When the camera is disabled, the vanilla player opens the camera so it does not blink. - if (amount == SecurityCameraSystemType.IncrementOp) - { - var camerasDisabled = Utils.GetActiveMapName() switch - { - MapNames.Skeld or MapNames.Dleks => Options.DisableSkeldCamera.GetBool(), - MapNames.Polus => Options.DisablePolusCamera.GetBool(), - MapNames.Airship => Options.DisableAirshipCamera.GetBool(), - _ => false, - }; - return !camerasDisabled; - } - return true; + Logger.Info($"Door is opened by {player?.Data?.PlayerName}, amount: {amount}", "DoorsSystemType.UpdateSystem"); } } } - [HarmonyPatch(typeof(DoorsSystemType), nameof(DoorsSystemType.UpdateSystem))] - public static class DoorsSystemTypePatch - { - public static void Prefix(/*DoorsSystemType __instance,*/ PlayerControl player, MessageReader msgReader) - { - byte amount; - { - var newReader = MessageReader.Get(msgReader); - amount = newReader.ReadByte(); - newReader.Recycle(); - } - - Logger.Info($"Door is opened by {player?.Data?.PlayerName}, amount: {amount}", "DoorsSystemType.UpdateSystem"); - } - } -} \ No newline at end of file diff --git a/Patches/ShipStatusPatch.cs b/Patches/ShipStatusPatch.cs index 26bf54971..5080a306d 100644 --- a/Patches/ShipStatusPatch.cs +++ b/Patches/ShipStatusPatch.cs @@ -1,10 +1,10 @@ using Hazel; using System; +using UnityEngine; using TOHE.Patches; -using TOHE.Roles.AddOns.Common; using TOHE.Roles.Core; using TOHE.Roles.Neutral; -using UnityEngine; +using TOHE.Roles.AddOns.Common; using static TOHE.Translator; namespace TOHE; @@ -266,10 +266,6 @@ public static void Postfix() [HarmonyPatch(typeof(ShipStatus), nameof(ShipStatus.Begin))] class ShipStatusBeginPatch { - public static void Prefix() - { - RpcSetTasksPatch.decidedCommonTasks.Clear(); - } public static void Postfix() { Logger.CurrentMethod(); @@ -359,12 +355,11 @@ public static bool Prefix(ShipStatus __instance, [HarmonyArgument(0)] MessageWri if (GameStates.IsInGame) { - foreach (var pc in Main.AllAlivePlayerControls) + foreach (var pc in PlayerControl.AllPlayerControls) { if (pc.BlockVentInteraction()) { customVentilation = true; - break; } } } diff --git a/Patches/TaskAssignPatch.cs b/Patches/TaskAssignPatch.cs index 434325616..855500e5f 100644 --- a/Patches/TaskAssignPatch.cs +++ b/Patches/TaskAssignPatch.cs @@ -16,7 +16,7 @@ public static void Prefix(ShipStatus __instance, if (!AmongUsClient.Instance.AmHost || __instance == null) return; if (!Options.DisableShortTasks.GetBool() && !Options.DisableCommonTasks.GetBool() && !Options.DisableLongTasks.GetBool() && !Options.DisableOtherTasks.GetBool()) return; - + List disabledTasks = []; foreach (var task in unusedTasks.GetFastEnumerator()) @@ -112,28 +112,21 @@ class RpcSetTasksPatch { // Patch to overwrite the task just before the process of allocating the task and sending the RPC is performed // Does not interfere with the vanilla task allocation process itself - - /* TO DO: - * Try to make players get different tasks from each other - * InnerSloth uses task pool to achieve this. - */ - - public static List decidedCommonTasks = []; - public static bool Prefix(NetworkedPlayerInfo __instance) + public static void Prefix(NetworkedPlayerInfo __instance, [HarmonyArgument(0)] ref Il2CppStructArray taskTypeIds) { - if (!AmongUsClient.Instance.AmHost) return false; - if (GameStates.IsHideNSeek) return true; + if (!AmongUsClient.Instance.AmHost) return; + if (GameStates.IsHideNSeek) return; // null measure if (Main.RealOptionsData == null) { Logger.Warn("Warning: RealOptionsData is null", "RpcSetTasksPatch"); - return true; + return; } var pc = __instance.Object; CustomRoles? RoleNullable = pc?.GetCustomRole(); - if (RoleNullable == null) return true; + if (RoleNullable == null) return; CustomRoles role = RoleNullable.Value; // Default number of tasks @@ -172,7 +165,7 @@ public static bool Prefix(NetworkedPlayerInfo __instance) if (pc.Is(CustomRoles.Workhorse)) { (hasCommonTasks, NumLongTasks, NumShortTasks) = Workhorse.TaskData; - } + } if (pc.Is(CustomRoles.Solsticer)) { @@ -182,149 +175,79 @@ public static bool Prefix(NetworkedPlayerInfo __instance) taskState.AllTasksCount = NumShortTasks + NumLongTasks; hasCommonTasks = false; } + - // Above is override task num - /* --------------------------------------------------------------*/ - //Below is assign tasks - - // We completely igonre the tasks decided by ShipStatus and assign our own. - List commonTasks = ShipStatus.Instance.CommonTasks.Shuffle().ToList(); - List shortTasks = ShipStatus.Instance.ShortTasks.Shuffle().ToList(); - List longTasks = ShipStatus.Instance.LongTasks.Shuffle().ToList(); - - if (!GameManager.Instance.LogicOptions.GetVisualTasks()) - { - shortTasks.RemoveAll(x => x.TaskType == TaskTypes.SubmitScan); - longTasks.RemoveAll(x => x.TaskType == TaskTypes.SubmitScan); - // Niko admits this is shit. - } - List usedTaskTypes = []; - - int defaultcommoncount = Main.RealOptionsData.GetInt(Int32OptionNames.NumCommonTasks); - int commonTasksNum = System.Math.Min(commonTasks.Count, defaultcommoncount); - - // Setting task num to 0 will make role description disappear from task panel for vanilla players and mod crews - if (!hasCommonTasks && NumShortTasks + NumLongTasks < 1) - { - NumShortTasks = 1; - } - - if (decidedCommonTasks.Count < 1) - { - for (int i = 0; i < commonTasksNum; i++) - { - decidedCommonTasks.Add((byte)commonTasks[i].Index); - } - } + if (taskTypeIds.Count == 0) hasCommonTasks = false; //Common to 0 when redistributing tasks + if (!hasCommonTasks && NumLongTasks == 0 && NumShortTasks == 0) NumShortTasks = 1; //Task 0 Measures + if (hasCommonTasks && NumLongTasks == Main.NormalOptions.NumLongTasks && NumShortTasks == Main.NormalOptions.NumShortTasks) return; //If there are no changes + // A list containing the IDs of tasks that can be assigned + // Clone of the second argument of the original RpcSetTasks Il2CppSystem.Collections.Generic.List TasksList = new(); - - if (hasCommonTasks) + foreach (var num in taskTypeIds) + TasksList.Add(num); + + // Reference:ShipStatus.Begin + // Deleting unnecessary allocated tasks + // Deleting tasks other than common tasks if common tasks are assigned + // Empty the list if common tasks are not allocated + int defaultCommonTasksNum = Main.RealOptionsData.GetInt(Int32OptionNames.NumCommonTasks); + if (hasCommonTasks) TasksList.RemoveRange(defaultCommonTasksNum, TasksList.Count - defaultCommonTasksNum); + else TasksList.Clear(); + TasksList = Shuffle(TasksList); + + // A HashSet into which allocated tasks can be placed + // Prevents multiple assignments of the same task + Il2CppSystem.Collections.Generic.HashSet usedTaskTypes = new(); + int start2 = 0; + int start3 = 0; + + // List of long tasks that can be assigned + Il2CppSystem.Collections.Generic.List LongTasks = new(); + foreach (var task in ShipStatus.Instance.LongTasks) + LongTasks.Add(task); + LongTasks = Shuffle(LongTasks); + + // List of short tasks that can be assigned + Il2CppSystem.Collections.Generic.List ShortTasks = new(); + foreach (var task in ShipStatus.Instance.ShortTasks) + ShortTasks.Add(task); + ShortTasks = Shuffle(ShortTasks); + + // Use the function to assign tasks that are actually used on the Among Us side + ShipStatus.Instance.AddTasksFromList( + ref start2, + NumLongTasks, + TasksList, + usedTaskTypes, + LongTasks + ); + ShipStatus.Instance.AddTasksFromList( + ref start3, + NumShortTasks, + TasksList, + usedTaskTypes, + ShortTasks + ); + + // Converts a list of tasks into an array (Il2CppStructArray) + taskTypeIds = new Il2CppStructArray(TasksList.Count); + for (int i = 0; i < TasksList.Count; i++) { - if (__instance.Object != null) - { - if (__instance.Object.GetCustomRole().IsCrewmateTeamV2() && !__instance.Object.GetCustomSubRoles().Any(x => !x.IsCrewmateTeamV2())) - { - foreach (var id in decidedCommonTasks) - TasksList.Add(id); - } - else - { - for (int i = 0; i < commonTasksNum; i++) - { - TasksList.Add((byte)commonTasks[i].Index); - } - } - } - else - { - for (int i = 0; i < commonTasksNum; i++) - { - TasksList.Add((byte)commonTasks[i].Index); - } - } + taskTypeIds[i] = TasksList[i]; } - byte list = 0; byte assigned = 0; - while (assigned < System.Math.Min(longTasks.Count, NumLongTasks)) - { - if (!TasksList.Contains((byte)longTasks[list].Index)) - { - if (usedTaskTypes.Contains(longTasks[list].TaskType)) - { - list++; - } - else - { - usedTaskTypes.Add(longTasks[list].TaskType); - TasksList.Add((byte)longTasks[list].Index); - assigned++; - list++; - } - } - else - { - list++; - } - - if (list >= longTasks.Count - 1) - { - list = 0; - longTasks = longTasks.Shuffle().ToList(); - usedTaskTypes.Clear(); - } - } - - list = 0; assigned = 0; - - usedTaskTypes.Clear(); - foreach (var task in longTasks) - { - if (TasksList.Contains((byte)task.Index)) - { - if (!usedTaskTypes.Contains(task.TaskType)) - usedTaskTypes.Add(task.TaskType); - } - } - - while (assigned < System.Math.Min(shortTasks.Count, NumShortTasks)) - { - if (!TasksList.Contains((byte)shortTasks[list].Index)) - { - if (usedTaskTypes.Contains(shortTasks[list].TaskType)) - { - list++; - } - else - { - usedTaskTypes.Add(shortTasks[list].TaskType); - TasksList.Add((byte)shortTasks[list].Index); - assigned++; - list++; - } - } - else - { - list++; - } - - if (list >= shortTasks.Count - 1) - { - list = 0; - shortTasks = shortTasks.Shuffle().ToList(); - usedTaskTypes.Clear(); - } - } - - if (AmongUsClient.Instance.AmClient) + } + public static Il2CppSystem.Collections.Generic.List Shuffle(Il2CppSystem.Collections.Generic.List list) + { + int listCount = list.Count; + while (listCount > 1) { - __instance.SetTasks((Il2CppStructArray)TasksList.ToArray()); + listCount--; + int k = IRandom.Instance.Next(listCount + 1); + (list[listCount], list[k]) = (list[k], list[listCount]); } - - MessageWriter messageWriter = AmongUsClient.Instance.StartRpc(__instance.NetId, 29, SendOption.Reliable); - messageWriter.WriteBytesAndSize((Il2CppStructArray)TasksList.ToArray()); - messageWriter.EndMessage(); - return false; + return list; } } @@ -338,7 +261,7 @@ public static bool Prefix(NetworkedPlayerInfo __instance, [HarmonyArgument(0)] b if (AmongUsClient.Instance.AmHost) { - Logger.Error($"Received Rpc {(RpcCalls)callId} for {__instance.Object.GetRealName()}({__instance.PlayerId}), which is impossible.", "NetworkedPlayerInfo"); + Logger.Error($"Received Rpc {(RpcCalls)callId} for {__instance.Object.GetRealName()}({__instance.PlayerId}), which is impossible.", "TaskAssignPatch"); EAC.WarnHost(); return false; diff --git a/Patches/VentSystemPatch.cs b/Patches/VentSystemPatch.cs index 9cda8ccec..c8bab2bb8 100644 --- a/Patches/VentSystemPatch.cs +++ b/Patches/VentSystemPatch.cs @@ -43,12 +43,14 @@ public static void Postfix(VentilationSystem __instance) if (ForceUpadate || (nowTime != LastUpadate)) { LastUpadate = nowTime; - foreach (var pc in Main.AllAlivePlayerControls) + foreach (var pc in PlayerControl.AllPlayerControls.GetFastEnumerator()) { - LastClosestVent[pc.PlayerId] = pc.GetVentsFromClosest()[0].Id; + if (pc.BlockVentInteraction()) + { + LastClosestVent[pc.PlayerId] = pc.GetVentsFromClosest()[0].Id; + pc.RpcCloseVent(__instance); + } } - - ShipStatus.Instance.Systems[SystemTypes.Ventilation].Cast().IsDirty = true; } } ///
@@ -65,10 +67,10 @@ public static bool BlockVentInteraction(this PlayerControl pc) public static void SerializeV2(VentilationSystem __instance, PlayerControl player = null) { - foreach (var pc in Main.AllAlivePlayerControls) + foreach (var pc in PlayerControl.AllPlayerControls.GetFastEnumerator()) { if (pc.AmOwner || (player != null && pc != player)) continue; - + if (pc.BlockVentInteraction()) { pc.RpcCloseVent(__instance); @@ -174,4 +176,4 @@ public static bool Prefix([HarmonyArgument(0)] int id, ref bool __result) // Run original code if host not have bloked vent return true; } -} +} \ No newline at end of file diff --git a/Patches/onGameStartedPatch.cs b/Patches/onGameStartedPatch.cs index 80b4fc7ca..5ece156be 100644 --- a/Patches/onGameStartedPatch.cs +++ b/Patches/onGameStartedPatch.cs @@ -1,15 +1,15 @@ using AmongUs.GameOptions; -using BepInEx.Unity.IL2CPP.Utils.Collections; using Hazel; -using InnerNet; using System; +using InnerNet; using System.Text; +using UnityEngine; +using TOHE.Patches; using TOHE.Modules; using TOHE.Modules.ChatManager; -using TOHE.Patches; using TOHE.Roles.Core; using TOHE.Roles.Core.AssignManager; -using UnityEngine; +using BepInEx.Unity.IL2CPP.Utils.Collections; using static TOHE.Translator; namespace TOHE; @@ -72,7 +72,6 @@ public static void Postfix(AmongUsClient __instance) Main.AllKillers.Clear(); Main.OverDeadPlayerList.Clear(); Main.UnShapeShifter.Clear(); - Main.DeadPassedMeetingPlayers.Clear(); Main.OvverideOutfit.Clear(); Main.GameIsLoaded = false; @@ -134,7 +133,7 @@ public static void Postfix(AmongUsClient __instance) sb.Append($" {string.Join(", ", invalidColor.Where(pc => pc != null).Select(p => $"{Main.AllPlayerNames.GetValueOrDefault(p.PlayerId, "PlayerNotFound")}"))}"); var msg = sb.ToString(); Utils.SendMessage(msg); - CriticalErrorManager.SetCreiticalError("Player Have Invalid Color", true); + Utils.ErrorEnd("Player Have Invalid Color"); Logger.Error(msg, "CoStartGame"); } } @@ -174,7 +173,7 @@ public static void Postfix(AmongUsClient __instance) Main.PlayerStates[pc.PlayerId] = new(pc.PlayerId) { - NormalOutfit = new NetworkedPlayerInfo.PlayerOutfit().Set(currentName, pc.Data.Outfits[PlayerOutfitType.Default].ColorId, pc.Data.Outfits[PlayerOutfitType.Default].HatId, pc.Data.Outfits[PlayerOutfitType.Default].SkinId, pc.Data.Outfits[PlayerOutfitType.Default].VisorId, pc.Data.Outfits[PlayerOutfitType.Default].PetId, pc.Data.Outfits[PlayerOutfitType.Default].NamePlateId), + NormalOutfit = new NetworkedPlayerInfo.PlayerOutfit().Set(currentName, pc.CurrentOutfit.ColorId, pc.CurrentOutfit.HatId, pc.CurrentOutfit.SkinId, pc.CurrentOutfit.VisorId, pc.CurrentOutfit.PetId, pc.CurrentOutfit.NamePlateId), }; if (GameStates.IsNormalGame) @@ -184,7 +183,7 @@ public static void Postfix(AmongUsClient __instance) ReportDeadBodyPatch.CanReport[pc.PlayerId] = true; ReportDeadBodyPatch.WaitReport[pc.PlayerId] = []; - + VentSystemDeterioratePatch.LastClosestVent[pc.PlayerId] = 0; CustomRoleManager.BlockedVentsList[pc.PlayerId] = []; CustomRoleManager.DoNotUnlockVentsList[pc.PlayerId] = []; @@ -226,7 +225,6 @@ public static void Postfix(AmongUsClient __instance) CustomWinnerHolder.Reset(); AntiBlackout.Reset(); NameNotifyManager.Reset(); - CustomNetObject.Reset(); SabotageSystemPatch.SabotageSystemTypeRepairDamagePatch.Initialize(); DoorsReset.Initialize(); @@ -243,7 +241,7 @@ public static void Postfix(AmongUsClient __instance) } catch (Exception ex) { - CriticalErrorManager.SetCreiticalError("Change Role Setting Postfix", true, ex.ToString()); + Utils.ErrorEnd("Change Role Setting Postfix"); Utils.ThrowException(ex); } } @@ -511,7 +509,7 @@ public static System.Collections.IEnumerator AssignRoles() } catch (Exception ex) { - CriticalErrorManager.SetCreiticalError("Select Role Prefix", true, ex.ToString()); + Utils.ErrorEnd("Select Role Prefix"); Utils.ThrowException(ex); yield break; } @@ -808,4 +806,4 @@ public static void EndReplace() OverriddenSenderList = null; StoragedData = null; } -} +} \ No newline at end of file diff --git a/README.md b/README.md index a03ecafa3..4e71d440c 100644 --- a/README.md +++ b/README.md @@ -104,15 +104,11 @@ > - Host icon during the meeting ### :star: [MoreGamemodes](https://github.com/Rabek009/MoreGamemodes) > -> - CustomNetObjects (CustomNetObjects.cs) > - Changer Role Basis (RoleBasisChanger.cs) > - Disable use vent for vanilla players (VentSystemPatch.cs) ### :star: [Reactor](https://github.com/NuclearPowered/Reactor) > > - Reference: Disable the 5s timeout on custom servers -### :star: [CrowdedMod](https://github.com/CrowdedMods/CrowdedMod) -> -> - We included CrowdedMod in our Mod --- # Legal License Notice diff --git a/Resources/Announcements/modNews-de_DE.json b/Resources/Announcements/modNews-de_DE.json index c92e64d06..ed9f878da 100644 --- a/Resources/Announcements/modNews-de_DE.json +++ b/Resources/Announcements/modNews-de_DE.json @@ -175,9 +175,6 @@ "\n - Masochist renamed to Punching Bag (By WaterPanda)", "\n - Bloodlust renamed to Bloodthirst (By WaterPanda)", "\n - Schizophrenic renamed to Paranoia (By WaterPanda)", - "\n - Changed the logic for disconnecting from the game if the API crashes (By TommyXL)", - "\n - Set 300 CD for Nemesis if they cannot use the kill button (By TommyXL)", - "\n - Changed warning message about Api Error Connection (By Drakos)", "\n\n【Fehlerbehebungen】", "\n - Many roles will no longer be able to receive some add-ons that were incompatible (By TommyXL, ryuk, WaterPanda)", "\n - Fixed Bounty Hunter resetting incorrect targets (By TommyXL)", @@ -207,163 +204,25 @@ "\n - Fixed Modded client seeing the Medic shield icon when Medic is dead (By D1GQ)", "\n - Mini can not be duelled, marked, blooded, and sliced (By Lezaiya)", "\n - Fixed typos, inconsistencies, and mistakes in descriptions, names, etc. (By Moe, TommyXL, Drakos, WaterPanda, Sunnyboi, LezaiYa)", - "\n - Fixed bug when after guessing, Judge, etc. the meeting status was not checked (By TommyXL)", - "\n - Fixed bug when Pelican ended the game when eaten players returned (By TommyXL)", - "\n - Fixed Avenger when they try to kill Necromancer (By TommyXL)", - "\n - Fixed Bodyguard/Crusader when they killed Bodyguard/Crusader, Taskinator and Veteran (By TommyXL)", - "\n - Fixed «Quizmaster.None» (By TommyXL)", - "\n - Fixed missed string «*MayorHideVote» for Vindicator (By TommyXL)", - "\n - Fixed bug when Madmate assign Neutrals (Does not apply to Admirer - By TommyXL)", - "\n - Fixed bug when Camouflage did not disappear after Camouflager was erased (By TommyXL)", - "\n - Probably fixed the bug when Kamikaze killed players during exile (By TommyXL)", - "\n - Probably fixed bug when in-game result displayed randomized nicknames (By TommyXL)", - "\n - Fixed bug when Auto Start always stes ans saved 0 kill cooldown (By TommyXL)", - "\n - Other small fixes that occurred in certain cases (By TommyXL)", - "\n - Swift can no longer get Tricky and vice versa (By TommyXL)", - "\n - Remove unnecessary parenthesis for Lighter (By TommyXL)", - "\n - Fixed bug when Fortune Teller shows «INVALID:NotAssigned» (By Drakos)", - "\n - Fehler beim Autostart behoben", - "\n - Fixed bug (hopefully) when the host changed his nickname to his own when he was killed by Doppelganger (By TommyXL)", - "\n - Fixed bug when F1 shows role settings (By TommyXL)", - "\n - Fixed bug when Veteran kills Taskinator (By TommyXL)", - "\n - Fixed (hopefully) the last color question for Quizmaster (By TommyXL)", - "\n - Fixed bug when Killing Machine can call a meeting (By TommyXL)", - "\n - Fixed bug when Jailed message not shown (By TommyXL)", "\n【Bekannte Fehler】", - "\n - 1. Server können instabil sein, da das Protokoll auf Innersloths Seite repariert werden muss", - "\n - 2. Doppelgänger, Swift und Imitator sind instabil aber funktionieren", + "\n - 1. Servers may be unstable as the protocol requires fixing on Innersloth's side", + "\n - 2. Doppelganger, Swift and Imitator are unstable, but work", "\n - 3. Modded clients have some problems, so it is recommended to have the mod only on Host", - "\n【Übersetzer】", - "\n - Brasilianisch (Von Dx7405, Pietro)", - "\n - Niederländisch (Von apemv, madmazel_)", - "\n -Französisch (Von FuroYt, KevOut, Klaomi, Sansationnelle, Space Monkey)", - "\n - Italienisch (Von alot, Baphojack, Mattix606)", - "\n - Japanisch (Von Sunnyboi)", - "\n - Lateinamerikanisch (Von CreepPower)", - "\n - Russisch (Von TommyXL, Shoulder Devil, chill_ultimated, Nevermore59)", - "\n - Standard Chinesisch (Von CrewCyan, LezaiYa, NikoCat223)", - "\n - Spanisch (Von Dawson, Sunnyboi, thewhiskas27, xxSShadow)", - "\n - Traditionelles Chinesisch (Von FlyFlyTurtle, Hinharrrrr, netherdragontw, Pomelo_)", - "\n Schaut euch die Übersetzerliste auf unserer Webseite an\n", - "\n\n★ Willkommen bei Town of Host: Enhanced v2.0.0 ★" + "\n【Translator Credits】", + "\n - Brazilian (By Dx7405, Pietro)", + "\n - Dutch (By apemv, madmazel_)", + "\n - French (By FuroYT, KevOut, Klaomi, Sansationnelle, Space Monkey)", + "\n - Italian (By alot, Baphojack, Mattix606)", + "\n - Japanese (By Sunnyboi)", + "\n - Latin American (By CreepPower)", + "\n - Russian (By TommyXL, Shoulder Devil, chill_ultimated, Nevermore59)", + "\n - Simplified Chinese (By CrewCyan, LezaiYa, NikoCat)", + "\n - Spanish (By Dawson, Sunnyboi, thewhiskas27, xxSShadow)", + "\n - Traditional Chinese (By FlyFlyTurtle, Hinharrrrr, netherdragontw, Pomelo_)", + "\n Check out all of our translators on our website\r\n", + "\n\n★ Welcome to Town of Host: Enhanced v2.0.0 ★" ], "Date": "2024-07-21T12:50:00Z" - }, - { - "Number": "100007", - "Title": "Town of Host: Enhanced v2.1.0", - "Subtitle": "Endlich sind wir hier!", - "Short": "TOH: Enhanced v2.1.0", - "Body": [ - "【Basis】", - "\n - Basis von TOH: Enhanced v2.0.0", - "\n\n【Neue Rollen/Addons】(5 Rollen, 6 Add-ons)", - "\n - Yin Yanger (Impostor Killing, idea & coded: Drakos)", - "\n - Possessor (Imposter Ghost Role, idea & coded: D1GQ)", - "\n - Troller (Neutral Chaos, idea: dx7405, coded: TommyXL)", - "\n - Ventguard (Crewmate Support, ported: EHR, coded by: TommyXL)", - "\n - Evader (Addon Helpful, idea: Lime, coded: TommyXL)", - "\n - Rebirth (Addon Helpful, idea & coded: Drakos)", - "\n - Sloth (Harmful Addon, idea & coded: Pyro)", - "\n - Eavesdropper (Addon Helpful, idea by: Crosspost Del Slay, coded: Moe)", - "\n - Spurt (Addon Helpful, idea by: .thediamondstar, coded: Drakos)", - "\n - Prohibited (Addon Harmful, idea by: Crosspost Del Slay, coded: TommyXL)", - "\n - New neutral Team (Faction): Neutral Apocalypse (idea & coded: Marg)", - "\n --- Min/max Neutral Apocalypse can be set", - "\n --- Neue Rolle: Bäcker", - "\n --- Berserker and PlagueBearer now moved to Neutral Apocalypse", - "\n --- Soul Collector reworked", - "\n\n【Neue Einstellungen/Funktionen】", - "\n - Added vent disabling for vanilla (ported from MoreGamemodes by TommyXL & NikoCat)", - "\n --- Wenn ein Spieler keinen Zugang zu Vent hat, wird er ihn niemals benutzen können", - "\n - More fixes for AntiBlackOut (By TommyXL & Drakos)", - "\n --- Note: This will not completely fix black screen issues, but the more players there are in the game, the less chance of black screen occurrences", - "\n --- To do this, we use revives and base role changes during exile so that dead players will be alive for a couple of seconds but will become dead again", - "\n - Added support role basis changer mid-game (By TommyXL & Drakos)", - "\n --- CopyCat now supports role basis changes", - "\n --- Executioner and Lawyer also change role basis after their target dies", - "\n - TextBoxPatch (Ported: EHR, coded: TommyXL)", - "\n --- Allows you to write any characters into the chat", - "\n - improved Region Menu (coded: D1GQ)", - "\n - Added custom label ID for modded (Ported: EHR, coded: TommyXL)", - "\n - Jester: «Can't Move In Vents» (Setting, coded: TommyXL)", - "\n - Random spawn: Active On Round One (Setting, coded: TommyXL)", - "\n - Added warning message about enabling setting «No Game End»", - "\n --- Warns only the host when he presses the start button", - "\n - Disable Shapeshift menu for some Reject Shapeshift roles (By: Drakos)", - "\n --- For Pitfall, Bomber, Undertaker", - "\n --- It may be used for some more roles", - "\n - Return Ability Votes (By: Drakos)", - "\n --- For Cleanser, Eraser, Fortune teller, Keeper, Oracle, Godfather", - "\n --- First Vote will cancel (Vote Skip) or use the ability; second is regular vote", - "\n - Added «/vote» command (By: Drakos)", - "\n --- Can be disabled in the settings", - "\n - Death reason display improved (ported from EHR).", - "\n - Added role info in setting menu (By: Drakos)", - "\n - Added search bar in settings (By: Drakos)", - "\n - Addon Base (Port From EHR) (By: Drakos)", - "\n --- The settings are now sorted alphabetically", - "\n - Geänderte Warnung über die API (By: Drakos)", - "\n - Jester: Reveal Upon Eject (Setting, by: TheDiamondStar)", - "\n - Executioner: Reveal Target Upon Ejection (Setting, by: TheDiamondStar)", - "\n - Judge: Max trials per game (Setting, by: hinhinarrrrrr)", - "\n - Verbessertes Menü für Rollenbeschreibung in den Einstellungen", - "\n - Setting: Apocalypse can see each other's Add-ons", - "\n - Settings: «Halloween Decorations» and «Birthday Decoration» (only for modded)", - "\n - Modded players now will see changes in TOHE settings", - "\n - Added custom image «imer» for Mercenary, Bounty Hunter, and Penguin: Thanks @that_one_missing_pixel (Pixel)", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Changed warning message about the API (By: Drakos)", - "\n\n【Fehlerbehebungen/Änderungen】", - "\n - Phantom Desync: Phantom now plays the invisibility animation instead of teleporting to a random vent for desync roles.", - "\n - Fixed issues with Veteran killing Taskinator, Killing Machine calling meetings, and the Jailed message not showing during the game.", - "\n - Resolved issues with stuck FFA meetings and Fortune Teller showing roles during FFA.", - "\n - Fixed speed bug when Bandit steals the Statue.", - "\n - Resolved Haunt Menu showing «NotAssigned» in Hide & Seek mode.", - "\n - Corrected issues with Doomsayer not using Impostor Vision and various bugs with Psychic.", - "\n - Fixed Taskinator triggering Schrodinger's Cat ability.", - "\n - Corrected Innocent win conditions with Impostor when the setting is enabled.", - "\n - Fixed player spawn issues at the start and after meetings.", - "\n - Resolved full role and add-on display when a player is exiled.", - "\n - Fixed Blackmail not working for non-host modded players.", - "\n - Resolved issues where the Deceiver could kill Serial Killer and where the Deceiver could kill dead players.", - "\n - Corrected several bugs related to Stalker, Enigma, and Madmate Impostor Vision.", - "\n - Fixed issues with Medium messages showing after Medium is dead.", - "\n - Resolved bug where Hangman could kill Nice Mini.", - "\n - Corrected Huntsman minimum kill cooldown.", - "\n - Fixed Bloodmoon not working for modded clients and corrected missing strings for Blackmailer.", - "\n - Fixed issues where the Overseer would show Med Scanner after a meeting.", - "\n - Inhibitor and Saboteur now use sabotage sounds in the intro.", - "\n - Resolved issues where Aware did not work after an Overseer check and Merchant could assign converted add-ons.", - "\n - Fixed bugs with Hater being unable to kill, Crewpostor killing Solsticer, and Impostor Vision not working for Doppelganger.", - "\n - Resolved modded client issues with calling RpcSetName at the end of the game.", - "\n - Fixed win-condition conflicts between terrorists and workaholics.", - "\n - Corrected Necroview interaction with Admired and Madmate roles.", - "\n - Resolved bugs with Judge for modded clients.", - "\n - Gangster and Admirer can no longer get the Egoist role.", - "\n - Fixed bugs with Minus and Plus buttons in settings, ensuring they are always active.", - "\n - Intro Scene optimizations for smoother game start.", - "\n - Fixed numerous typos across roles and settings.", - "\n - Jester can no longer receive the Susceptible role.", - "\n - Added notify message about the game end when RpcEndGame is not received by specific clients.", - "\n - Fixed Baker not showing roles to non-host modded players", - "\n - Fixed mass kicking from lobbies against non-host modded players", - "\n【Übersetzer】", - "\n - Brasilianisch (Von Dx7405, Pietro)", - "\n - Niederländisch (Von apemv, madmazel_)", - "\n -Französisch (Von FuroYt, KevOut, Klaomi, Sansationnelle, Space Monkey)", - "\n - Italienisch (Von alot, Baphojack, Mattix606)", - "\n - Japanisch (Von Sunnyboi)", - "\n - Lateinamerikanisch (Von CreepPower)", - "\n - Russisch (Von TommyXL, Shoulder Devil, chill_ultimated, Nevermore59)", - "\n - Standard Chinesisch (Von CrewCyan, LezaiYa, NikoCat223)", - "\n - Spanisch (Von Dawson, Sunnyboi, thewhiskas27, xxSShadow)", - "\n - Traditionelles Chinesisch (Von FlyFlyTurtle, Hinharrrrr, netherdragontw, Pomelo_)", - "\n Schaut euch die Übersetzerliste auf unserer Webseite an\n", - "\n\n★ Willkommen bei Town of Host: Enhanced v2.1.0 ★" - ], - "Date": "2024-11-3T12:50:00Z" } ] } diff --git a/Resources/Announcements/modNews-en_US.json b/Resources/Announcements/modNews-en_US.json index 6e5c74b82..6ea67e4ce 100644 --- a/Resources/Announcements/modNews-en_US.json +++ b/Resources/Announcements/modNews-en_US.json @@ -173,9 +173,6 @@ "\n - Masochist renamed to Punching Bag (By WaterPanda)", "\n - Bloodlust renamed to Bloodthirst (By WaterPanda)", "\n - Schizophrenic renamed to Paranoia (By WaterPanda)", - "\n - Changed the logic for disconnecting from the game if the API crashes (By TommyXL)", - "\n - Set 300 CD for Nemesis if they cannot use the kill button (By TommyXL)", - "\n - Changed warning message about Api Error Connection (By Drakos)", "\n\r【Bug Fixes】", "\n - Many roles will no longer be able to receive some add-ons that were incompatible (By TommyXL, ryuk, WaterPanda)", "\n - Fixed Bounty Hunter resetting incorrect targets (By TommyXL)", @@ -205,28 +202,6 @@ "\n - Fixed Modded client seeing the Medic shield icon when Medic is dead (By D1GQ)", "\n - Mini can not be duelled, marked, blooded, and sliced (By Lezaiya)", "\n - Fixed typos, inconsistencies, and mistakes in descriptions, names, etc. (By Moe, TommyXL, Drakos, WaterPanda, Sunnyboi, LezaiYa)", - "\n - Fixed bug when after guessing, Judge, etc. the meeting status was not checked (By TommyXL)", - "\n - Fixed bug when Pelican ended the game when eaten players returned (By TommyXL)", - "\n - Fixed Avenger when they try to kill Necromancer (By TommyXL)", - "\n - Fixed Bodyguard/Crusader when they killed Bodyguard/Crusader, Taskinator and Veteran (By TommyXL)", - "\n - Fixed «Quizmaster.None» (By TommyXL)", - "\n - Fixed missed string «*MayorHideVote» for Vindicator (By TommyXL)", - "\n - Fixed bug when Madmate assign Neutrals (Does not apply to Admirer - By TommyXL)", - "\n - Fixed bug when Camouflage did not disappear after Camouflager was erased (By TommyXL)", - "\n - Probably fixed the bug when Kamikaze killed players during exile (By TommyXL)", - "\n - Probably fixed bug when in-game result displayed randomized nicknames (By TommyXL)", - "\n - Fixed bug when Auto Start always stes ans saved 0 kill cooldown (By TommyXL)", - "\n - Other small fixes that occurred in certain cases (By TommyXL)", - "\n - Swift can no longer get Tricky and vice versa (By TommyXL)", - "\n - Remove unnecessary parenthesis for Lighter (By TommyXL)", - "\n - Fixed bug when Fortune Teller shows «INVALID:NotAssigned» (By Drakos)", - "\n - Fixed broken Auto Start", - "\n - Fixed bug (hopefully) when the host changed his nickname to his own when he was killed by Doppelganger (By TommyXL)", - "\n - Fixed bug when F1 shows role settings (By TommyXL)", - "\n - Fixed bug when Veteran kills Taskinator (By TommyXL)", - "\n - Fixed (hopefully) the last color question for Quizmaster (By TommyXL)", - "\n - Fixed bug when Killing Machine can call a meeting (By TommyXL)", - "\n - Fixed bug when Jailed message not shown (By TommyXL)", "\n【Known bugs】", "\n - 1. Servers may be unstable as the protocol requires fixing on Innersloth's side", "\n - 2. Doppelganger, Swift and Imitator are unstable, but work", @@ -246,122 +221,6 @@ "\n\n★ Welcome to Town of Host: Enhanced v2.0.0 ★" ], "Date": "2024-07-21T12:50:00Z" - }, - { - "Number": "100007", - "Title": "Town of Host: Enhanced v2.1.0", - "Subtitle": "Finally, we're here!", - "Short": "TOH: Enhanced v2.1.0", - "Body": [ - "【Base】", - "\n - Base on TOH: Enhanced v2.0.0", - "\n\r【New Roles/Addons】(5 roles, 6 Add-ons)", - "\n - Yin Yanger (Impostor Killing, idea & coded: Drakos)", - "\n - Possessor (Imposter Ghost Role, idea & coded: D1GQ)", - "\n - Troller (Neutral Chaos, idea: dx7405, coded: TommyXL)", - "\n - Ventguard (Crewmate Support, ported: EHR, coded by: TommyXL)", - "\n - Evader (Addon Helpful, idea: Lime, coded: TommyXL)", - "\n - Rebirth (Addon Helpful, idea & coded: Drakos)", - "\n - Sloth (Harmful Addon, idea & coded: Pyro)", - "\n - Eavesdropper (Addon Helpful, idea by: Crosspost Del Slay, coded: Moe)", - "\n - Spurt (Addon Helpful, idea by: .thediamondstar, coded: Drakos)", - "\n - Prohibited (Addon Harmful, idea by: Crosspost Del Slay, coded: TommyXL)", - "\n - New neutral Team (Faction): Neutral Apocalypse (idea & coded: Marg)", - "\n --- Min/max Neutral Apocalypse can be set", - "\n --- New role: Baker", - "\n --- Berserker and PlagueBearer now moved to Neutral Apocalypse", - "\n --- Soul Collector reworked", - "\n\r【New Settings/Features】", - "\n - Added vent disabling for vanilla (ported from MoreGamemodes by TommyXL & NikoCat)", - "\n --- When a player does not have access to vents, they will never be able to use it", - "\n - More fixes for AntiBlackOut (By TommyXL & Drakos)", - "\n --- Note: This will not completely fix black screen issues, but the more players there are in the game, the less chance of black screen occurrences", - "\n --- To do this, we use revives and base role changes during exile so that dead players will be alive for a couple of seconds but will become dead again", - "\n - Added support role basis changer mid-game (By TommyXL & Drakos)", - "\n --- CopyCat now supports role basis changes", - "\n --- Executioner and Lawyer also change role basis after their target dies", - "\n - TextBoxPatch (Ported: EHR, coded: TommyXL)", - "\n --- Allows you to write any characters into the chat", - "\n - improved Region Menu (coded: D1GQ)", - "\n - Added custom label ID for modded (Ported: EHR, coded: TommyXL)", - "\n - Jester: «Can't Move In Vents» (Setting, coded: TommyXL)", - "\n - Random spawn: Active On Round One (Setting, coded: TommyXL)", - "\n - Added warning message about enabling setting «No Game End»", - "\n --- Warns only the host when he presses the start button", - "\n - Disable Shapeshift menu for some Reject Shapeshift roles (By: Drakos)", - "\n --- For Pitfall, Bomber, Undertaker", - "\n --- It may be used for some more roles", - "\n - Return Ability Votes (By: Drakos)", - "\n --- For Cleanser, Eraser, Fortune teller, Keeper, Oracle, Godfather", - "\n --- First Vote will cancel (Vote Skip) or use the ability; second is regular vote", - "\n - Added «/vote» command (By: Drakos)", - "\n --- Can be disabled in the settings", - "\n - Death reason display improved (ported from EHR).", - "\n - Added role info in setting menu (By: Drakos)", - "\n - Added search bar in settings (By: Drakos)", - "\n - Addon Base (Port From EHR) (By: Drakos)", - "\n --- The settings are now sorted alphabetically", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Jester: Reveal Upon Eject (Setting, by: TheDiamondStar)", - "\n - Executioner: Reveal Target Upon Ejection (Setting, by: TheDiamondStar)", - "\n - Judge: Max trials per game (Setting, by: hinhinarrrrrr)", - "\n - Improved menu for role description in settings", - "\n - Setting: Apocalypse can see each other's Add-ons", - "\n - Settings: «Halloween Decorations» and «Birthday Decoration» (only for modded)", - "\n - Modded players now will see changes in TOHE settings", - "\n - Added custom image «imer» for Mercenary, Bounty Hunter, and Penguin: Thanks @that_one_missing_pixel (Pixel)", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Changed warning message about the API (By: Drakos)", - "\n\r【Bug Fixes/Changes】", - "\n - Phantom Desync: Phantom now plays the invisibility animation instead of teleporting to a random vent for desync roles.", - "\n - Fixed issues with Veteran killing Taskinator, Killing Machine calling meetings, and the Jailed message not showing during the game.", - "\n - Resolved issues with stuck FFA meetings and Fortune Teller showing roles during FFA.", - "\n - Fixed speed bug when Bandit steals the Statue.", - "\n - Resolved Haunt Menu showing «NotAssigned» in Hide & Seek mode.", - "\n - Corrected issues with Doomsayer not using Impostor Vision and various bugs with Psychic.", - "\n - Fixed Taskinator triggering Schrodinger's Cat ability.", - "\n - Corrected Innocent win conditions with Impostor when the setting is enabled.", - "\n - Fixed player spawn issues at the start and after meetings.", - "\n - Resolved full role and add-on display when a player is exiled.", - "\n - Fixed Blackmail not working for non-host modded players.", - "\n - Resolved issues where the Deceiver could kill Serial Killer and where the Deceiver could kill dead players.", - "\n - Corrected several bugs related to Stalker, Enigma, and Madmate Impostor Vision.", - "\n - Fixed issues with Medium messages showing after Medium is dead.", - "\n - Resolved bug where Hangman could kill Nice Mini.", - "\n - Corrected Huntsman minimum kill cooldown.", - "\n - Fixed Bloodmoon not working for modded clients and corrected missing strings for Blackmailer.", - "\n - Fixed issues where the Overseer would show Med Scanner after a meeting.", - "\n - Inhibitor and Saboteur now use sabotage sounds in the intro.", - "\n - Resolved issues where Aware did not work after an Overseer check and Merchant could assign converted add-ons.", - "\n - Fixed bugs with Hater being unable to kill, Crewpostor killing Solsticer, and Impostor Vision not working for Doppelganger.", - "\n - Resolved modded client issues with calling RpcSetName at the end of the game.", - "\n - Fixed win-condition conflicts between terrorists and workaholics.", - "\n - Corrected Necroview interaction with Admired and Madmate roles.", - "\n - Resolved bugs with Judge for modded clients.", - "\n - Gangster and Admirer can no longer get the Egoist role.", - "\n - Fixed bugs with Minus and Plus buttons in settings, ensuring they are always active.", - "\n - Intro Scene optimizations for smoother game start.", - "\n - Fixed numerous typos across roles and settings.", - "\n - Jester can no longer receive the Susceptible role.", - "\n - Added notify message about the game end when RpcEndGame is not received by specific clients.", - "\n - Fixed Baker not showing roles to non-host modded players", - "\n - Fixed mass kicking from lobbies against non-host modded players", - "\n【Translator Credits】", - "\n - Brazilian (By Dx7405, Pietro)", - "\n - Dutch (By apemv, madmazel_)", - "\n - French (By FuroYT, KevOut, Klaomi, Sansationnelle, Space Monkey)", - "\n - Italian (By alot, Baphojack, Mattix606)", - "\n - Japanese (By Sunnyboi)", - "\n - Latin American (By CreepPower)", - "\n - Russian (By TommyXL, Shoulder Devil, chill_ultimated, Nevermore59)", - "\n - Simplified Chinese (By CrewCyan, LezaiYa, NikoCat)", - "\n - Spanish (By Dawson, Sunnyboi, thewhiskas27, xxSShadow)", - "\n - Traditional Chinese (By FlyFlyTurtle, Hinharrrrr, netherdragontw, Pomelo_)", - "\n Check out all of our translators on our website\r\n", - "\n\n★ Welcome to Town of Host: Enhanced v2.1.0 ★" - ], - "Date": "2024-11-3T12:50:00Z" } ] } diff --git a/Resources/Announcements/modNews-es_419.json b/Resources/Announcements/modNews-es_419.json index 2db1d44af..fef51bc3b 100644 --- a/Resources/Announcements/modNews-es_419.json +++ b/Resources/Announcements/modNews-es_419.json @@ -175,20 +175,17 @@ "\n - Masochist renamed to Punching Bag (By WaterPanda)", "\n - Bloodlust renamed to Bloodthirst (By WaterPanda)", "\n- Esquizofrénico renombrado a Paranoia (Por WaterPanda)", - "\n - Changed the logic for disconnecting from the game if the API crashes (By TommyXL)", - "\n - Set 300 CD for Nemesis if they cannot use the kill button (By TommyXL)", - "\n - Changed warning message about Api Error Connection (By Drakos)", - "\n\r【Bug Fixes】", - "\n - Many roles will no longer be able to receive some add-ons that were incompatible (By TommyXL, ryuk, WaterPanda)", - "\n - Fixed Bounty Hunter resetting incorrect targets (By TommyXL)", - "\n - Fixed null error post-meeting for Vulture and Seeker and error after votes in Airship (By TommyXL)", - "\n - Fixed custom buttons brightness issues (By TommyXL)", - "\n - Fixed roles without vent ability getting stuck after trying to vent (By TommyXL)", - "\n - Fixed vent icon issues for roles based on Engineer (By TommyXL)", - "\n - Fixed black screens during role assign (By TommyXL)", - "\n - Fixed Scientist assign for desync role (By TommyXL)", - "\n - Fixed bug when 3 settings for Judge was not used (By TommyXL)", - "\n - Fixed buttons are active when the player was guessed (By TommyXL)", + "\n\n【Correcciones de Errores】", + "\n - Muchos roles ya no podrán recibir algunos complementos que eran incompatibles (Por TommyXL, ryuk, WaterPanda)", + "\n - Arreglo del Cazador de Recompensas establece objetivos incorrectos", + "\n- Arreglo del error nulo posterior a la reunión para Buitre, Vidente y error después de votos en Airship (Por TommyXL)", + "\n - Arreglos de problemas del brillo de botones personalizados (Por TommyXL)", + "\n- Arreglo de roles sin habilidad de ventilación que se quedaban atascados después de intentar usar ventilación (Por TommyXL)", + "\n - Arreglos de problemas cin los imagenes de las ventilaciónes para roles basados en Ingeniero (Por TommyXL)", + "\n- Arreglos de pantallas negras durante la asignación de roles (Por TommyXL)", + "\n- Asignación de Científico arreglado para rol desincronizado (Por TommyXL)", + "\n - Arreglo del error cuando 3 configuraciones para Juez no se usaban (Por TommyXL)", + "\n - Arreglos de botones activos cuando el jugador era adivinado (Por TommyXL)", "\n - Some fixes in Guesser UI (By TommyXL)", "\n - Fixed Double Meeting Ending (By TommyXL)", "\n - Fixed Guardian Angel Shield Animation sometimes didn't work correctly with Vanilla (By TommyXL)", @@ -207,28 +204,6 @@ "\n - Fixed Modded client seeing the Medic shield icon when Medic is dead (By D1GQ)", "\n - Mini can not be duelled, marked, blooded, and sliced (By Lezaiya)", "\n - Fixed typos, inconsistencies, and mistakes in descriptions, names, etc. (By Moe, TommyXL, Drakos, WaterPanda, Sunnyboi, LezaiYa)", - "\n - Fixed bug when after guessing, Judge, etc. the meeting status was not checked (By TommyXL)", - "\n - Fixed bug when Pelican ended the game when eaten players returned (By TommyXL)", - "\n - Fixed Avenger when they try to kill Necromancer (By TommyXL)", - "\n - Fixed Bodyguard/Crusader when they killed Bodyguard/Crusader, Taskinator and Veteran (By TommyXL)", - "\n - Fixed «Quizmaster.None» (By TommyXL)", - "\n - Fixed missed string «*MayorHideVote» for Vindicator (By TommyXL)", - "\n - Fixed bug when Madmate assign Neutrals (Does not apply to Admirer - By TommyXL)", - "\n - Fixed bug when Camouflage did not disappear after Camouflager was erased (By TommyXL)", - "\n - Probably fixed the bug when Kamikaze killed players during exile (By TommyXL)", - "\n - Probably fixed bug when in-game result displayed randomized nicknames (By TommyXL)", - "\n - Fixed bug when Auto Start always stes ans saved 0 kill cooldown (By TommyXL)", - "\n - Other small fixes that occurred in certain cases (By TommyXL)", - "\n - Swift can no longer get Tricky and vice versa (By TommyXL)", - "\n - Remove unnecessary parenthesis for Lighter (By TommyXL)", - "\n - Fixed bug when Fortune Teller shows «INVALID:NotAssigned» (By Drakos)", - "\n - Fixed broken Auto Start", - "\n - Fixed bug (hopefully) when the host changed his nickname to his own when he was killed by Doppelganger (By TommyXL)", - "\n - Fixed bug when F1 shows role settings (By TommyXL)", - "\n - Fixed bug when Veteran kills Taskinator (By TommyXL)", - "\n - Fixed (hopefully) the last color question for Quizmaster (By TommyXL)", - "\n - Fixed bug when Killing Machine can call a meeting (By TommyXL)", - "\n - Fixed bug when Jailed message not shown (By TommyXL)", "\n【Known bugs】", "\n - 1. Servers may be unstable as the protocol requires fixing on Innersloth's side", "\n - 2. Doppelganger, Swift and Imitator are unstable, but work", @@ -248,122 +223,6 @@ "\n\n★ Welcome to Town of Host: Enhanced v2.0.0 ★" ], "Date": "2024-07-21T12:50:00Z" - }, - { - "Number": "100007", - "Title": "Town of Host: Enhanced v2.1.0", - "Subtitle": "Finally, we're here!", - "Short": "TOH: Enhanced v2.1.0", - "Body": [ - "【Base】", - "\n - Base on TOH: Enhanced v2.0.0", - "\n\r【New Roles/Addons】(5 roles, 6 Add-ons)", - "\n - Yin Yanger (Impostor Killing, idea & coded: Drakos)", - "\n - Possessor (Imposter Ghost Role, idea & coded: D1GQ)", - "\n - Troller (Neutral Chaos, idea: dx7405, coded: TommyXL)", - "\n - Ventguard (Crewmate Support, ported: EHR, coded by: TommyXL)", - "\n - Evader (Addon Helpful, idea: Lime, coded: TommyXL)", - "\n - Rebirth (Addon Helpful, idea & coded: Drakos)", - "\n - Sloth (Harmful Addon, idea & coded: Pyro)", - "\n - Eavesdropper (Addon Helpful, idea by: Crosspost Del Slay, coded: Moe)", - "\n - Spurt (Addon Helpful, idea by: .thediamondstar, coded: Drakos)", - "\n - Prohibited (Addon Harmful, idea by: Crosspost Del Slay, coded: TommyXL)", - "\n - New neutral Team (Faction): Neutral Apocalypse (idea & coded: Marg)", - "\n --- Min/max Neutral Apocalypse can be set", - "\n --- New role: Baker", - "\n --- Berserker and PlagueBearer now moved to Neutral Apocalypse", - "\n --- Soul Collector reworked", - "\n\r【New Settings/Features】", - "\n - Added vent disabling for vanilla (ported from MoreGamemodes by TommyXL & NikoCat)", - "\n --- When a player does not have access to vents, they will never be able to use it", - "\n - More fixes for AntiBlackOut (By TommyXL & Drakos)", - "\n --- Note: This will not completely fix black screen issues, but the more players there are in the game, the less chance of black screen occurrences", - "\n --- To do this, we use revives and base role changes during exile so that dead players will be alive for a couple of seconds but will become dead again", - "\n - Added support role basis changer mid-game (By TommyXL & Drakos)", - "\n --- CopyCat now supports role basis changes", - "\n --- Executioner and Lawyer also change role basis after their target dies", - "\n - TextBoxPatch (Ported: EHR, coded: TommyXL)", - "\n --- Allows you to write any characters into the chat", - "\n - improved Region Menu (coded: D1GQ)", - "\n - Added custom label ID for modded (Ported: EHR, coded: TommyXL)", - "\n - Jester: «Can't Move In Vents» (Setting, coded: TommyXL)", - "\n - Random spawn: Active On Round One (Setting, coded: TommyXL)", - "\n - Added warning message about enabling setting «No Game End»", - "\n --- Warns only the host when he presses the start button", - "\n - Disable Shapeshift menu for some Reject Shapeshift roles (By: Drakos)", - "\n --- For Pitfall, Bomber, Undertaker", - "\n --- It may be used for some more roles", - "\n - Return Ability Votes (By: Drakos)", - "\n --- For Cleanser, Eraser, Fortune teller, Keeper, Oracle, Godfather", - "\n --- First Vote will cancel (Vote Skip) or use the ability; second is regular vote", - "\n - Added «/vote» command (By: Drakos)", - "\n --- Can be disabled in the settings", - "\n - Death reason display improved (ported from EHR).", - "\n - Added role info in setting menu (By: Drakos)", - "\n - Added search bar in settings (By: Drakos)", - "\n - Addon Base (Port From EHR) (By: Drakos)", - "\n --- The settings are now sorted alphabetically", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Jester: Reveal Upon Eject (Setting, by: TheDiamondStar)", - "\n - Executioner: Reveal Target Upon Ejection (Setting, by: TheDiamondStar)", - "\n - Judge: Max trials per game (Setting, by: hinhinarrrrrr)", - "\n - Improved menu for role description in settings", - "\n - Setting: Apocalypse can see each other's Add-ons", - "\n - Settings: «Halloween Decorations» and «Birthday Decoration» (only for modded)", - "\n - Modded players now will see changes in TOHE settings", - "\n - Added custom image «imer» for Mercenary, Bounty Hunter, and Penguin: Thanks @that_one_missing_pixel (Pixel)", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Changed warning message about the API (By: Drakos)", - "\n\r【Bug Fixes/Changes】", - "\n - Phantom Desync: Phantom now plays the invisibility animation instead of teleporting to a random vent for desync roles.", - "\n - Fixed issues with Veteran killing Taskinator, Killing Machine calling meetings, and the Jailed message not showing during the game.", - "\n - Resolved issues with stuck FFA meetings and Fortune Teller showing roles during FFA.", - "\n - Fixed speed bug when Bandit steals the Statue.", - "\n - Resolved Haunt Menu showing «NotAssigned» in Hide & Seek mode.", - "\n - Corrected issues with Doomsayer not using Impostor Vision and various bugs with Psychic.", - "\n - Fixed Taskinator triggering Schrodinger's Cat ability.", - "\n - Corrected Innocent win conditions with Impostor when the setting is enabled.", - "\n - Fixed player spawn issues at the start and after meetings.", - "\n - Resolved full role and add-on display when a player is exiled.", - "\n - Fixed Blackmail not working for non-host modded players.", - "\n - Resolved issues where the Deceiver could kill Serial Killer and where the Deceiver could kill dead players.", - "\n - Corrected several bugs related to Stalker, Enigma, and Madmate Impostor Vision.", - "\n - Fixed issues with Medium messages showing after Medium is dead.", - "\n - Resolved bug where Hangman could kill Nice Mini.", - "\n - Corrected Huntsman minimum kill cooldown.", - "\n - Fixed Bloodmoon not working for modded clients and corrected missing strings for Blackmailer.", - "\n - Fixed issues where the Overseer would show Med Scanner after a meeting.", - "\n - Inhibitor and Saboteur now use sabotage sounds in the intro.", - "\n - Resolved issues where Aware did not work after an Overseer check and Merchant could assign converted add-ons.", - "\n - Fixed bugs with Hater being unable to kill, Crewpostor killing Solsticer, and Impostor Vision not working for Doppelganger.", - "\n - Resolved modded client issues with calling RpcSetName at the end of the game.", - "\n - Fixed win-condition conflicts between terrorists and workaholics.", - "\n - Corrected Necroview interaction with Admired and Madmate roles.", - "\n - Resolved bugs with Judge for modded clients.", - "\n - Gangster and Admirer can no longer get the Egoist role.", - "\n - Fixed bugs with Minus and Plus buttons in settings, ensuring they are always active.", - "\n - Intro Scene optimizations for smoother game start.", - "\n - Fixed numerous typos across roles and settings.", - "\n - Jester can no longer receive the Susceptible role.", - "\n - Added notify message about the game end when RpcEndGame is not received by specific clients.", - "\n - Fixed Baker not showing roles to non-host modded players", - "\n - Fixed mass kicking from lobbies against non-host modded players", - "\n【Translator Credits】", - "\n - Brazilian (By Dx7405, Pietro)", - "\n - Dutch (By apemv, madmazel_)", - "\n - French (By FuroYT, KevOut, Klaomi, Sansationnelle, Space Monkey)", - "\n - Italian (By alot, Baphojack, Mattix606)", - "\n - Japanese (By Sunnyboi)", - "\n - Latin American (By CreepPower)", - "\n - Russian (By TommyXL, Shoulder Devil, chill_ultimated, Nevermore59)", - "\n - Simplified Chinese (By CrewCyan, LezaiYa, NikoCat)", - "\n - Spanish (By Dawson, Sunnyboi, thewhiskas27, xxSShadow)", - "\n - Traditional Chinese (By FlyFlyTurtle, Hinharrrrr, netherdragontw, Pomelo_)", - "\n Check out all of our translators on our website\r\n", - "\n\n★ Welcome to Town of Host: Enhanced v2.1.0 ★" - ], - "Date": "2024-11-3T12:50:00Z" } ] } diff --git a/Resources/Announcements/modNews-es_ES.json b/Resources/Announcements/modNews-es_ES.json index 8bcb70434..db998820e 100644 --- a/Resources/Announcements/modNews-es_ES.json +++ b/Resources/Announcements/modNews-es_ES.json @@ -175,195 +175,54 @@ "\n- Masoquista renombrado a Saco de Boxeo (Por WaterPanda)", "\n- Sed de Sangre renombrado a Sed de Sangre (Por WaterPanda)", "\n- Esquizofrénico renombrado a Paranoia (Por WaterPanda)", - "\n - Changed the logic for disconnecting from the game if the API crashes (By TommyXL)", - "\n - Set 300 CD for Nemesis if they cannot use the kill button (By TommyXL)", - "\n - Changed warning message about Api Error Connection (By Drakos)", - "\n\r【Bug Fixes】", - "\n - Many roles will no longer be able to receive some add-ons that were incompatible (By TommyXL, ryuk, WaterPanda)", - "\n - Fixed Bounty Hunter resetting incorrect targets (By TommyXL)", - "\n - Fixed null error post-meeting for Vulture and Seeker and error after votes in Airship (By TommyXL)", - "\n - Fixed custom buttons brightness issues (By TommyXL)", - "\n - Fixed roles without vent ability getting stuck after trying to vent (By TommyXL)", - "\n - Fixed vent icon issues for roles based on Engineer (By TommyXL)", - "\n - Fixed black screens during role assign (By TommyXL)", - "\n - Fixed Scientist assign for desync role (By TommyXL)", - "\n - Fixed bug when 3 settings for Judge was not used (By TommyXL)", - "\n - Fixed buttons are active when the player was guessed (By TommyXL)", - "\n - Some fixes in Guesser UI (By TommyXL)", - "\n - Fixed Double Meeting Ending (By TommyXL)", - "\n - Fixed Guardian Angel Shield Animation sometimes didn't work correctly with Vanilla (By TommyXL)", - "\n - Some fix in random spawn in Airship for the host (By TommyXL)", - "\n - Fixed Necromancer leaving a dead body after the meeting (By TommyXL)", - "\n - Fixed Workaholic incorrect win state (By TommyXL)", - "\n - Fixed Mayor calling meetings even when out of use (By ryuk)", - "\n - Fixed EAC list not working when ban list is off (By ryuk)", - "\n - Fixed Kamikaze causing half-dead players (By ryuk)", - "\n - Fixed Messages not sent to vanilla players (By Drakos)", - "\n - Fixed Zombie Issues (By Drakos)", - "\n - Fixed Punching bag being judged (By Drakos)", - "\n - Fixed bug when kill cooldown not going when press F1/F2/F3/F4 (By NikoCat)", - "\n - Fixed Immediate autostart settings (By NikoCat)", - "\n - Fixed Bait self-reporting (By NikoCat)", - "\n - Fixed Modded client seeing the Medic shield icon when Medic is dead (By D1GQ)", - "\n - Mini can not be duelled, marked, blooded, and sliced (By Lezaiya)", - "\n - Fixed typos, inconsistencies, and mistakes in descriptions, names, etc. (By Moe, TommyXL, Drakos, WaterPanda, Sunnyboi, LezaiYa)", - "\n - Fixed bug when after guessing, Judge, etc. the meeting status was not checked (By TommyXL)", - "\n - Fixed bug when Pelican ended the game when eaten players returned (By TommyXL)", - "\n - Fixed Avenger when they try to kill Necromancer (By TommyXL)", - "\n - Fixed Bodyguard/Crusader when they killed Bodyguard/Crusader, Taskinator and Veteran (By TommyXL)", - "\n - Fixed «Quizmaster.None» (By TommyXL)", - "\n - Fixed missed string «*MayorHideVote» for Vindicator (By TommyXL)", - "\n - Fixed bug when Madmate assign Neutrals (Does not apply to Admirer - By TommyXL)", - "\n - Fixed bug when Camouflage did not disappear after Camouflager was erased (By TommyXL)", - "\n - Probably fixed the bug when Kamikaze killed players during exile (By TommyXL)", - "\n - Probably fixed bug when in-game result displayed randomized nicknames (By TommyXL)", - "\n - Fixed bug when Auto Start always stes ans saved 0 kill cooldown (By TommyXL)", - "\n - Other small fixes that occurred in certain cases (By TommyXL)", - "\n - Swift can no longer get Tricky and vice versa (By TommyXL)", - "\n - Remove unnecessary parenthesis for Lighter (By TommyXL)", - "\n - Fixed bug when Fortune Teller shows «INVALID:NotAssigned» (By Drakos)", - "\n - Fixed broken Auto Start", - "\n - Fixed bug (hopefully) when the host changed his nickname to his own when he was killed by Doppelganger (By TommyXL)", - "\n - Fixed bug when F1 shows role settings (By TommyXL)", - "\n - Fixed bug when Veteran kills Taskinator (By TommyXL)", - "\n - Fixed (hopefully) the last color question for Quizmaster (By TommyXL)", - "\n - Fixed bug when Killing Machine can call a meeting (By TommyXL)", - "\n - Fixed bug when Jailed message not shown (By TommyXL)", - "\n【Known bugs】", - "\n - 1. Servers may be unstable as the protocol requires fixing on Innersloth's side", - "\n - 2. Doppelganger, Swift and Imitator are unstable, but work", - "\n - 3. Modded clients have some problems, so it is recommended to have the mod only on Host", - "\n【Translator Credits】", - "\n - Brazilian (By Dx7405, Pietro)", - "\n - Dutch (By apemv, madmazel_)", - "\n - French (By FuroYT, KevOut, Klaomi, Sansationnelle, Space Monkey)", - "\n - Italian (By alot, Baphojack, Mattix606)", - "\n - Japanese (By Sunnyboi)", - "\n - Latin American (By CreepPower)", - "\n - Russian (By TommyXL, Shoulder Devil, chill_ultimated, Nevermore59)", - "\n - Simplified Chinese (By CrewCyan, LezaiYa, NikoCat)", - "\n - Spanish (By Dawson, Sunnyboi, thewhiskas27, xxSShadow)", - "\n - Traditional Chinese (By FlyFlyTurtle, Hinharrrrr, netherdragontw, Pomelo_)", - "\n Check out all of our translators on our website\r\n", - "\n\n★ Welcome to Town of Host: Enhanced v2.0.0 ★" + "\n\n【Correcciones de Errores】", + "\n- Muchos roles ya no podrán recibir algunos complementos que eran incompatibles (Por TommyXL, ryuk, WaterPanda)", + "\n- Arreglado el Cazador de Recompensas reiniciando objetivos incorrectos (Por TommyXL)", + "\n- Arreglado error nulo post-reunión para Buitre y Vidente y error después de votos en Airship (Por TommyXL)", + "\n- Arreglados problemas de brillo de botones personalizados (Por TommyXL)", + "\n- Arreglados roles sin habilidad de ventilación que se quedaban atascados después de intentar usar ventilación (Por TommyXL)", + "\n- Arreglados problemas de íconos de ventilación para roles basados en Ingeniero (Por TommyXL)", + "\n- Arregladas pantallas negras durante la asignación de roles (Por TommyXL)", + "\n- Asignación de Científico arreglada para rol desincronizado (Por TommyXL)", + "\n- Arreglado error cuando 3 configuraciones para Juez no se usaban (Por TommyXL)", + "\n- Arreglados botones activos cuando el jugador era adivinado (Por TommyXL)", + "\n- Algunas correcciones en la interfaz de Adivinador (Por TommyXL)", + "\n- Arreglado Doble Finalización de Reunión (Por TommyXL)", + "\n- Arreglada animación de escudo del Ángel Guardián a veces no funcionaba correctamente con Vanilla (Por TommyXL)", + "\n- Algunas correcciones en el spawn aleatorio en Airship para el anfitrión (Por TommyXL)", + "\n- Arreglado Nigromante dejando un cadáver después de la reunión (Por TommyXL)", + "\n- Arreglado Estado de Victoria incorrecto del Adicto al Trabajo (Por TommyXL)", + "\n- Arreglado Alcalde llamando reuniones incluso sin usos disponibles (Por ryuk)", + "\n- Arreglada lista de EAC que no funcionaba cuando la lista de baneos estaba desactivada (Por ryuk)", + "\n- Arreglado Kamikaze causando jugadores medio-muertos (Por ryuk)", + "\n- Arreglados Mensajes no enviados a jugadores vanilla (Por Drakos)", + "\n- Arreglados Problemas de Zombie (Por Drakos)", + "\n- Arreglado Saco de Boxeo siendo juzgado (Por Drakos)", + "\n- Arreglado error cuando el enfriamiento de asesinato no iba al presionar F1/F2/F3/F4 (Por NikoCat)", + "\n- Arregladas configuraciones de inicio automático inmediato (Por NikoCat)", + "\n- Arreglado Cebo auto-reportándose (Por NikoCat)", + "\n- Arreglado cliente modificado viendo el ícono de escudo del Médico cuando el Médico está muerto (Por D1GQ)", + "\n- El Mini no puede ser desafiado, marcado, ensangrentado, y cortado (Por Lezaiya)", + "\n-Arreglados errores tipográficos, inconsistencias y errores en descripciones, nombres, etc. (Por Moe, TommyXL, Drakos, WaterPanda, Sunnyboi, LezaiYa)", + "\n【Errores Conocidos】", + "\n- 1. Los servidores pueden ser inestables ya que el protocolo requiere arreglo por parte de Innersloth", + "\n- 2. El Doble, Raudo y el Imitador pueden ser inestables, pero funcionan", + "\n- 3. Los clientes con el mod tienen algunos problemas, por lo que es mejor tener el mod exclusivamente si eres el Anfitrión", + "\n【Créditos de Traducción】", + "\n- Brasileño (Por Dx7405, Pietro)", + "\n- Holandés (Por apemv, madmazel_)", + "\n- Francés (Por FuroYT, KevOut, Klaomi, Sansationnelle, Space Monkey)", + "\n- Italiano (Por alot, Baphojack, Mattix606)", + "\n- Japonés (Por Sunnyboi)", + "\n- Latinoamericano (Por CreepPower)", + "\n- Ruso (Por TommyXL, Shoulder Devil, chill_ultimated, Nevermore59)", + "\n- Chino Simplificado (Por CrewCyan, LezaiYa, NikoCat)", + "\n- Español (España): thewhiskas27, Sunnyboi, xxSShadow, Dawson", + "\n- Chino Tradicional (Por FlyFlyTurtle, Hinharrrrr, netherdragontw, Pomelo_)", + "\n Échale un vistazo a todos los que han ayudado a traducir este mod en nuestra página web\n", + "\n\n★ Bienvenido a Town of Host: Enhanced v2.0.0 ★" ], "Date": "2024-07-21T12:50:00Z" - }, - { - "Number": "100007", - "Title": "Town of Host: Enhanced v2.1.0", - "Subtitle": "Finally, we're here!", - "Short": "TOH: Enhanced v2.1.0", - "Body": [ - "【Base】", - "\n - Base on TOH: Enhanced v2.0.0", - "\n\r【New Roles/Addons】(5 roles, 6 Add-ons)", - "\n - Yin Yanger (Impostor Killing, idea & coded: Drakos)", - "\n - Possessor (Imposter Ghost Role, idea & coded: D1GQ)", - "\n - Troller (Neutral Chaos, idea: dx7405, coded: TommyXL)", - "\n - Ventguard (Crewmate Support, ported: EHR, coded by: TommyXL)", - "\n - Evader (Addon Helpful, idea: Lime, coded: TommyXL)", - "\n - Rebirth (Addon Helpful, idea & coded: Drakos)", - "\n - Sloth (Harmful Addon, idea & coded: Pyro)", - "\n - Eavesdropper (Addon Helpful, idea by: Crosspost Del Slay, coded: Moe)", - "\n - Spurt (Addon Helpful, idea by: .thediamondstar, coded: Drakos)", - "\n - Prohibited (Addon Harmful, idea by: Crosspost Del Slay, coded: TommyXL)", - "\n - New neutral Team (Faction): Neutral Apocalypse (idea & coded: Marg)", - "\n --- Min/max Neutral Apocalypse can be set", - "\n --- New role: Baker", - "\n --- Berserker and PlagueBearer now moved to Neutral Apocalypse", - "\n --- Soul Collector reworked", - "\n\r【New Settings/Features】", - "\n - Added vent disabling for vanilla (ported from MoreGamemodes by TommyXL & NikoCat)", - "\n --- When a player does not have access to vents, they will never be able to use it", - "\n - More fixes for AntiBlackOut (By TommyXL & Drakos)", - "\n --- Note: This will not completely fix black screen issues, but the more players there are in the game, the less chance of black screen occurrences", - "\n --- To do this, we use revives and base role changes during exile so that dead players will be alive for a couple of seconds but will become dead again", - "\n - Added support role basis changer mid-game (By TommyXL & Drakos)", - "\n --- CopyCat now supports role basis changes", - "\n --- Executioner and Lawyer also change role basis after their target dies", - "\n - TextBoxPatch (Ported: EHR, coded: TommyXL)", - "\n --- Allows you to write any characters into the chat", - "\n - improved Region Menu (coded: D1GQ)", - "\n - Added custom label ID for modded (Ported: EHR, coded: TommyXL)", - "\n - Jester: «Can't Move In Vents» (Setting, coded: TommyXL)", - "\n - Random spawn: Active On Round One (Setting, coded: TommyXL)", - "\n - Added warning message about enabling setting «No Game End»", - "\n --- Warns only the host when he presses the start button", - "\n - Disable Shapeshift menu for some Reject Shapeshift roles (By: Drakos)", - "\n --- For Pitfall, Bomber, Undertaker", - "\n --- It may be used for some more roles", - "\n - Return Ability Votes (By: Drakos)", - "\n --- For Cleanser, Eraser, Fortune teller, Keeper, Oracle, Godfather", - "\n --- First Vote will cancel (Vote Skip) or use the ability; second is regular vote", - "\n - Added «/vote» command (By: Drakos)", - "\n --- Can be disabled in the settings", - "\n - Death reason display improved (ported from EHR).", - "\n - Added role info in setting menu (By: Drakos)", - "\n - Added search bar in settings (By: Drakos)", - "\n - Addon Base (Port From EHR) (By: Drakos)", - "\n --- The settings are now sorted alphabetically", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Jester: Reveal Upon Eject (Setting, by: TheDiamondStar)", - "\n - Executioner: Reveal Target Upon Ejection (Setting, by: TheDiamondStar)", - "\n - Judge: Max trials per game (Setting, by: hinhinarrrrrr)", - "\n - Improved menu for role description in settings", - "\n - Setting: Apocalypse can see each other's Add-ons", - "\n - Settings: «Halloween Decorations» and «Birthday Decoration» (only for modded)", - "\n - Modded players now will see changes in TOHE settings", - "\n - Added custom image «imer» for Mercenary, Bounty Hunter, and Penguin: Thanks @that_one_missing_pixel (Pixel)", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Changed warning message about the API (By: Drakos)", - "\n\r【Bug Fixes/Changes】", - "\n - Phantom Desync: Phantom now plays the invisibility animation instead of teleporting to a random vent for desync roles.", - "\n - Fixed issues with Veteran killing Taskinator, Killing Machine calling meetings, and the Jailed message not showing during the game.", - "\n - Resolved issues with stuck FFA meetings and Fortune Teller showing roles during FFA.", - "\n - Fixed speed bug when Bandit steals the Statue.", - "\n - Resolved Haunt Menu showing «NotAssigned» in Hide & Seek mode.", - "\n - Corrected issues with Doomsayer not using Impostor Vision and various bugs with Psychic.", - "\n - Fixed Taskinator triggering Schrodinger's Cat ability.", - "\n - Corrected Innocent win conditions with Impostor when the setting is enabled.", - "\n - Fixed player spawn issues at the start and after meetings.", - "\n - Resolved full role and add-on display when a player is exiled.", - "\n - Fixed Blackmail not working for non-host modded players.", - "\n - Resolved issues where the Deceiver could kill Serial Killer and where the Deceiver could kill dead players.", - "\n - Corrected several bugs related to Stalker, Enigma, and Madmate Impostor Vision.", - "\n - Fixed issues with Medium messages showing after Medium is dead.", - "\n - Resolved bug where Hangman could kill Nice Mini.", - "\n - Corrected Huntsman minimum kill cooldown.", - "\n - Fixed Bloodmoon not working for modded clients and corrected missing strings for Blackmailer.", - "\n - Fixed issues where the Overseer would show Med Scanner after a meeting.", - "\n - Inhibitor and Saboteur now use sabotage sounds in the intro.", - "\n - Resolved issues where Aware did not work after an Overseer check and Merchant could assign converted add-ons.", - "\n - Fixed bugs with Hater being unable to kill, Crewpostor killing Solsticer, and Impostor Vision not working for Doppelganger.", - "\n - Resolved modded client issues with calling RpcSetName at the end of the game.", - "\n - Fixed win-condition conflicts between terrorists and workaholics.", - "\n - Corrected Necroview interaction with Admired and Madmate roles.", - "\n - Resolved bugs with Judge for modded clients.", - "\n - Gangster and Admirer can no longer get the Egoist role.", - "\n - Fixed bugs with Minus and Plus buttons in settings, ensuring they are always active.", - "\n - Intro Scene optimizations for smoother game start.", - "\n - Fixed numerous typos across roles and settings.", - "\n - Jester can no longer receive the Susceptible role.", - "\n - Added notify message about the game end when RpcEndGame is not received by specific clients.", - "\n - Fixed Baker not showing roles to non-host modded players", - "\n - Fixed mass kicking from lobbies against non-host modded players", - "\n【Translator Credits】", - "\n - Brazilian (By Dx7405, Pietro)", - "\n - Dutch (By apemv, madmazel_)", - "\n - French (By FuroYT, KevOut, Klaomi, Sansationnelle, Space Monkey)", - "\n - Italian (By alot, Baphojack, Mattix606)", - "\n - Japanese (By Sunnyboi)", - "\n - Latin American (By CreepPower)", - "\n - Russian (By TommyXL, Shoulder Devil, chill_ultimated, Nevermore59)", - "\n - Simplified Chinese (By CrewCyan, LezaiYa, NikoCat)", - "\n - Spanish (By Dawson, Sunnyboi, thewhiskas27, xxSShadow)", - "\n - Traditional Chinese (By FlyFlyTurtle, Hinharrrrr, netherdragontw, Pomelo_)", - "\n Check out all of our translators on our website\r\n", - "\n\n★ Welcome to Town of Host: Enhanced v2.1.0 ★" - ], - "Date": "2024-11-3T12:50:00Z" } ] } diff --git a/Resources/Announcements/modNews-fil_PH.json b/Resources/Announcements/modNews-fil_PH.json index a88211c41..8207ac47c 100644 --- a/Resources/Announcements/modNews-fil_PH.json +++ b/Resources/Announcements/modNews-fil_PH.json @@ -175,9 +175,6 @@ "\n - Masochist renamed to Punching Bag (By WaterPanda)", "\n - Bloodlust renamed to Bloodthirst (By WaterPanda)", "\n - Schizophrenic renamed to Paranoia (By WaterPanda)", - "\n - Changed the logic for disconnecting from the game if the API crashes (By TommyXL)", - "\n - Set 300 CD for Nemesis if they cannot use the kill button (By TommyXL)", - "\n - Changed warning message about Api Error Connection (By Drakos)", "\n\r【Bug Fixes】", "\n - Many roles will no longer be able to receive some add-ons that were incompatible (By TommyXL, ryuk, WaterPanda)", "\n - Fixed Bounty Hunter resetting incorrect targets (By TommyXL)", @@ -207,28 +204,6 @@ "\n - Fixed Modded client seeing the Medic shield icon when Medic is dead (By D1GQ)", "\n - Mini can not be duelled, marked, blooded, and sliced (By Lezaiya)", "\n - Fixed typos, inconsistencies, and mistakes in descriptions, names, etc. (By Moe, TommyXL, Drakos, WaterPanda, Sunnyboi, LezaiYa)", - "\n - Fixed bug when after guessing, Judge, etc. the meeting status was not checked (By TommyXL)", - "\n - Fixed bug when Pelican ended the game when eaten players returned (By TommyXL)", - "\n - Fixed Avenger when they try to kill Necromancer (By TommyXL)", - "\n - Fixed Bodyguard/Crusader when they killed Bodyguard/Crusader, Taskinator and Veteran (By TommyXL)", - "\n - Fixed «Quizmaster.None» (By TommyXL)", - "\n - Fixed missed string «*MayorHideVote» for Vindicator (By TommyXL)", - "\n - Fixed bug when Madmate assign Neutrals (Does not apply to Admirer - By TommyXL)", - "\n - Fixed bug when Camouflage did not disappear after Camouflager was erased (By TommyXL)", - "\n - Probably fixed the bug when Kamikaze killed players during exile (By TommyXL)", - "\n - Probably fixed bug when in-game result displayed randomized nicknames (By TommyXL)", - "\n - Fixed bug when Auto Start always stes ans saved 0 kill cooldown (By TommyXL)", - "\n - Other small fixes that occurred in certain cases (By TommyXL)", - "\n - Swift can no longer get Tricky and vice versa (By TommyXL)", - "\n - Remove unnecessary parenthesis for Lighter (By TommyXL)", - "\n - Fixed bug when Fortune Teller shows «INVALID:NotAssigned» (By Drakos)", - "\n - Fixed broken Auto Start", - "\n - Fixed bug (hopefully) when the host changed his nickname to his own when he was killed by Doppelganger (By TommyXL)", - "\n - Fixed bug when F1 shows role settings (By TommyXL)", - "\n - Fixed bug when Veteran kills Taskinator (By TommyXL)", - "\n - Fixed (hopefully) the last color question for Quizmaster (By TommyXL)", - "\n - Fixed bug when Killing Machine can call a meeting (By TommyXL)", - "\n - Fixed bug when Jailed message not shown (By TommyXL)", "\n【Known bugs】", "\n - 1. Servers may be unstable as the protocol requires fixing on Innersloth's side", "\n - 2. Doppelganger, Swift and Imitator are unstable, but work", @@ -248,122 +223,6 @@ "\n\n★ Welcome to Town of Host: Enhanced v2.0.0 ★" ], "Date": "2024-07-21T12:50:00Z" - }, - { - "Number": "100007", - "Title": "Town of Host: Enhanced v2.1.0", - "Subtitle": "Finally, we're here!", - "Short": "TOH: Enhanced v2.1.0", - "Body": [ - "【Base】", - "\n - Base on TOH: Enhanced v2.0.0", - "\n\r【New Roles/Addons】(5 roles, 6 Add-ons)", - "\n - Yin Yanger (Impostor Killing, idea & coded: Drakos)", - "\n - Possessor (Imposter Ghost Role, idea & coded: D1GQ)", - "\n - Troller (Neutral Chaos, idea: dx7405, coded: TommyXL)", - "\n - Ventguard (Crewmate Support, ported: EHR, coded by: TommyXL)", - "\n - Evader (Addon Helpful, idea: Lime, coded: TommyXL)", - "\n - Rebirth (Addon Helpful, idea & coded: Drakos)", - "\n - Sloth (Harmful Addon, idea & coded: Pyro)", - "\n - Eavesdropper (Addon Helpful, idea by: Crosspost Del Slay, coded: Moe)", - "\n - Spurt (Addon Helpful, idea by: .thediamondstar, coded: Drakos)", - "\n - Prohibited (Addon Harmful, idea by: Crosspost Del Slay, coded: TommyXL)", - "\n - New neutral Team (Faction): Neutral Apocalypse (idea & coded: Marg)", - "\n --- Min/max Neutral Apocalypse can be set", - "\n --- New role: Baker", - "\n --- Berserker and PlagueBearer now moved to Neutral Apocalypse", - "\n --- Soul Collector reworked", - "\n\r【New Settings/Features】", - "\n - Added vent disabling for vanilla (ported from MoreGamemodes by TommyXL & NikoCat)", - "\n --- When a player does not have access to vents, they will never be able to use it", - "\n - More fixes for AntiBlackOut (By TommyXL & Drakos)", - "\n --- Note: This will not completely fix black screen issues, but the more players there are in the game, the less chance of black screen occurrences", - "\n --- To do this, we use revives and base role changes during exile so that dead players will be alive for a couple of seconds but will become dead again", - "\n - Added support role basis changer mid-game (By TommyXL & Drakos)", - "\n --- CopyCat now supports role basis changes", - "\n --- Executioner and Lawyer also change role basis after their target dies", - "\n - TextBoxPatch (Ported: EHR, coded: TommyXL)", - "\n --- Allows you to write any characters into the chat", - "\n - improved Region Menu (coded: D1GQ)", - "\n - Added custom label ID for modded (Ported: EHR, coded: TommyXL)", - "\n - Jester: «Can't Move In Vents» (Setting, coded: TommyXL)", - "\n - Random spawn: Active On Round One (Setting, coded: TommyXL)", - "\n - Added warning message about enabling setting «No Game End»", - "\n --- Warns only the host when he presses the start button", - "\n - Disable Shapeshift menu for some Reject Shapeshift roles (By: Drakos)", - "\n --- For Pitfall, Bomber, Undertaker", - "\n --- It may be used for some more roles", - "\n - Return Ability Votes (By: Drakos)", - "\n --- For Cleanser, Eraser, Fortune teller, Keeper, Oracle, Godfather", - "\n --- First Vote will cancel (Vote Skip) or use the ability; second is regular vote", - "\n - Added «/vote» command (By: Drakos)", - "\n --- Can be disabled in the settings", - "\n - Death reason display improved (ported from EHR).", - "\n - Added role info in setting menu (By: Drakos)", - "\n - Added search bar in settings (By: Drakos)", - "\n - Addon Base (Port From EHR) (By: Drakos)", - "\n --- The settings are now sorted alphabetically", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Jester: Reveal Upon Eject (Setting, by: TheDiamondStar)", - "\n - Executioner: Reveal Target Upon Ejection (Setting, by: TheDiamondStar)", - "\n - Judge: Max trials per game (Setting, by: hinhinarrrrrr)", - "\n - Improved menu for role description in settings", - "\n - Setting: Apocalypse can see each other's Add-ons", - "\n - Settings: «Halloween Decorations» and «Birthday Decoration» (only for modded)", - "\n - Modded players now will see changes in TOHE settings", - "\n - Added custom image «imer» for Mercenary, Bounty Hunter, and Penguin: Thanks @that_one_missing_pixel (Pixel)", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Changed warning message about the API (By: Drakos)", - "\n\r【Bug Fixes/Changes】", - "\n - Phantom Desync: Phantom now plays the invisibility animation instead of teleporting to a random vent for desync roles.", - "\n - Fixed issues with Veteran killing Taskinator, Killing Machine calling meetings, and the Jailed message not showing during the game.", - "\n - Resolved issues with stuck FFA meetings and Fortune Teller showing roles during FFA.", - "\n - Fixed speed bug when Bandit steals the Statue.", - "\n - Resolved Haunt Menu showing «NotAssigned» in Hide & Seek mode.", - "\n - Corrected issues with Doomsayer not using Impostor Vision and various bugs with Psychic.", - "\n - Fixed Taskinator triggering Schrodinger's Cat ability.", - "\n - Corrected Innocent win conditions with Impostor when the setting is enabled.", - "\n - Fixed player spawn issues at the start and after meetings.", - "\n - Resolved full role and add-on display when a player is exiled.", - "\n - Fixed Blackmail not working for non-host modded players.", - "\n - Resolved issues where the Deceiver could kill Serial Killer and where the Deceiver could kill dead players.", - "\n - Corrected several bugs related to Stalker, Enigma, and Madmate Impostor Vision.", - "\n - Fixed issues with Medium messages showing after Medium is dead.", - "\n - Resolved bug where Hangman could kill Nice Mini.", - "\n - Corrected Huntsman minimum kill cooldown.", - "\n - Fixed Bloodmoon not working for modded clients and corrected missing strings for Blackmailer.", - "\n - Fixed issues where the Overseer would show Med Scanner after a meeting.", - "\n - Inhibitor and Saboteur now use sabotage sounds in the intro.", - "\n - Resolved issues where Aware did not work after an Overseer check and Merchant could assign converted add-ons.", - "\n - Fixed bugs with Hater being unable to kill, Crewpostor killing Solsticer, and Impostor Vision not working for Doppelganger.", - "\n - Resolved modded client issues with calling RpcSetName at the end of the game.", - "\n - Fixed win-condition conflicts between terrorists and workaholics.", - "\n - Corrected Necroview interaction with Admired and Madmate roles.", - "\n - Resolved bugs with Judge for modded clients.", - "\n - Gangster and Admirer can no longer get the Egoist role.", - "\n - Fixed bugs with Minus and Plus buttons in settings, ensuring they are always active.", - "\n - Intro Scene optimizations for smoother game start.", - "\n - Fixed numerous typos across roles and settings.", - "\n - Jester can no longer receive the Susceptible role.", - "\n - Added notify message about the game end when RpcEndGame is not received by specific clients.", - "\n - Fixed Baker not showing roles to non-host modded players", - "\n - Fixed mass kicking from lobbies against non-host modded players", - "\n【Translator Credits】", - "\n - Brazilian (By Dx7405, Pietro)", - "\n - Dutch (By apemv, madmazel_)", - "\n - French (By FuroYT, KevOut, Klaomi, Sansationnelle, Space Monkey)", - "\n - Italian (By alot, Baphojack, Mattix606)", - "\n - Japanese (By Sunnyboi)", - "\n - Latin American (By CreepPower)", - "\n - Russian (By TommyXL, Shoulder Devil, chill_ultimated, Nevermore59)", - "\n - Simplified Chinese (By CrewCyan, LezaiYa, NikoCat)", - "\n - Spanish (By Dawson, Sunnyboi, thewhiskas27, xxSShadow)", - "\n - Traditional Chinese (By FlyFlyTurtle, Hinharrrrr, netherdragontw, Pomelo_)", - "\n Check out all of our translators on our website\r\n", - "\n\n★ Welcome to Town of Host: Enhanced v2.1.0 ★" - ], - "Date": "2024-11-3T12:50:00Z" } ] } diff --git a/Resources/Announcements/modNews-fr_FR.json b/Resources/Announcements/modNews-fr_FR.json index 04eeae8ed..3e76859af 100644 --- a/Resources/Announcements/modNews-fr_FR.json +++ b/Resources/Announcements/modNews-fr_FR.json @@ -175,195 +175,54 @@ "\nMasochiste Renommé en Sac de Boxe (Par WaterPanda)", "\nDésire Sanguinaire renommé en Soif Sanguinaire (Par WaterPanda)", "\nSchizophrène renommée en Paranoïa (Par WaterPanda)", - "\n - Changed the logic for disconnecting from the game if the API crashes (By TommyXL)", - "\n - Set 300 CD for Nemesis if they cannot use the kill button (By TommyXL)", - "\n - Changed warning message about Api Error Connection (By Drakos)", - "\n\r【Bug Fixes】", - "\n - Many roles will no longer be able to receive some add-ons that were incompatible (By TommyXL, ryuk, WaterPanda)", - "\n - Fixed Bounty Hunter resetting incorrect targets (By TommyXL)", - "\n - Fixed null error post-meeting for Vulture and Seeker and error after votes in Airship (By TommyXL)", - "\n - Fixed custom buttons brightness issues (By TommyXL)", - "\n - Fixed roles without vent ability getting stuck after trying to vent (By TommyXL)", - "\n - Fixed vent icon issues for roles based on Engineer (By TommyXL)", - "\n - Fixed black screens during role assign (By TommyXL)", - "\n - Fixed Scientist assign for desync role (By TommyXL)", - "\n - Fixed bug when 3 settings for Judge was not used (By TommyXL)", - "\n - Fixed buttons are active when the player was guessed (By TommyXL)", - "\n - Some fixes in Guesser UI (By TommyXL)", - "\n - Fixed Double Meeting Ending (By TommyXL)", - "\n - Fixed Guardian Angel Shield Animation sometimes didn't work correctly with Vanilla (By TommyXL)", - "\n - Some fix in random spawn in Airship for the host (By TommyXL)", - "\n - Fixed Necromancer leaving a dead body after the meeting (By TommyXL)", - "\n - Fixed Workaholic incorrect win state (By TommyXL)", - "\n - Fixed Mayor calling meetings even when out of use (By ryuk)", - "\n - Fixed EAC list not working when ban list is off (By ryuk)", - "\n - Fixed Kamikaze causing half-dead players (By ryuk)", - "\n - Fixed Messages not sent to vanilla players (By Drakos)", - "\n - Fixed Zombie Issues (By Drakos)", - "\n - Fixed Punching bag being judged (By Drakos)", - "\n - Fixed bug when kill cooldown not going when press F1/F2/F3/F4 (By NikoCat)", - "\n - Fixed Immediate autostart settings (By NikoCat)", - "\n - Fixed Bait self-reporting (By NikoCat)", - "\n - Fixed Modded client seeing the Medic shield icon when Medic is dead (By D1GQ)", - "\n - Mini can not be duelled, marked, blooded, and sliced (By Lezaiya)", - "\n - Fixed typos, inconsistencies, and mistakes in descriptions, names, etc. (By Moe, TommyXL, Drakos, WaterPanda, Sunnyboi, LezaiYa)", - "\n - Fixed bug when after guessing, Judge, etc. the meeting status was not checked (By TommyXL)", - "\n - Fixed bug when Pelican ended the game when eaten players returned (By TommyXL)", - "\n - Fixed Avenger when they try to kill Necromancer (By TommyXL)", - "\n - Fixed Bodyguard/Crusader when they killed Bodyguard/Crusader, Taskinator and Veteran (By TommyXL)", - "\n - Fixed «Quizmaster.None» (By TommyXL)", - "\n - Fixed missed string «*MayorHideVote» for Vindicator (By TommyXL)", - "\n - Fixed bug when Madmate assign Neutrals (Does not apply to Admirer - By TommyXL)", - "\n - Fixed bug when Camouflage did not disappear after Camouflager was erased (By TommyXL)", - "\n - Probably fixed the bug when Kamikaze killed players during exile (By TommyXL)", - "\n - Probably fixed bug when in-game result displayed randomized nicknames (By TommyXL)", - "\n - Fixed bug when Auto Start always stes ans saved 0 kill cooldown (By TommyXL)", - "\n - Other small fixes that occurred in certain cases (By TommyXL)", - "\n - Swift can no longer get Tricky and vice versa (By TommyXL)", - "\n - Remove unnecessary parenthesis for Lighter (By TommyXL)", - "\n - Fixed bug when Fortune Teller shows «INVALID:NotAssigned» (By Drakos)", - "\n - Fixed broken Auto Start", - "\n - Fixed bug (hopefully) when the host changed his nickname to his own when he was killed by Doppelganger (By TommyXL)", - "\n - Fixed bug when F1 shows role settings (By TommyXL)", - "\n - Fixed bug when Veteran kills Taskinator (By TommyXL)", - "\n - Fixed (hopefully) the last color question for Quizmaster (By TommyXL)", - "\n - Fixed bug when Killing Machine can call a meeting (By TommyXL)", - "\n - Fixed bug when Jailed message not shown (By TommyXL)", - "\n【Known bugs】", - "\n - 1. Servers may be unstable as the protocol requires fixing on Innersloth's side", - "\n - 2. Doppelganger, Swift and Imitator are unstable, but work", - "\n - 3. Modded clients have some problems, so it is recommended to have the mod only on Host", - "\n【Translator Credits】", - "\n - Brazilian (By Dx7405, Pietro)", - "\n - Dutch (By apemv, madmazel_)", - "\n - French (By FuroYT, KevOut, Klaomi, Sansationnelle, Space Monkey)", - "\n - Italian (By alot, Baphojack, Mattix606)", - "\n - Japanese (By Sunnyboi)", - "\n - Latin American (By CreepPower)", - "\n - Russian (By TommyXL, Shoulder Devil, chill_ultimated, Nevermore59)", - "\n - Simplified Chinese (By CrewCyan, LezaiYa, NikoCat)", - "\n - Spanish (By Dawson, Sunnyboi, thewhiskas27, xxSShadow)", - "\n - Traditional Chinese (By FlyFlyTurtle, Hinharrrrr, netherdragontw, Pomelo_)", - "\n Check out all of our translators on our website\r\n", - "\n\n★ Welcome to Town of Host: Enhanced v2.0.0 ★" + "\n\n【Corrections des Bugs】", + "\nPlusieurs rôles ne vont plus être capable de recevoir certains Attributs qui étaient incompatibles (Par TommyXL, ryuk, WaterPanda)", + "\nRéparé Le Chasseur de Primes Réinitialisant les mauvaises cibles (Par TommyXL)", + "\nRéparé l'erreur Nulle durant les réunions pour le Vautour et le Chercheur et l'erreur d'après votes dans Airship (Par TommyXL)", + "\nRéparé le problème de luminosité des boutons personnalisés (Par TommyXL)", + "\nRéparé les rôles sans la capacité d'utiliser les conduits d'être coincés après avoir essayé d'en utiliser un (Par TommyXL)", + "\nRéparé le problème d'icône de conduit pour les rôles basés sur L'Ingénieur (Par TommyXL)", + "\nRéparé les écrans noirs durant l'attribution des rôles (Par TommyXL)", + "\nRéparé l'attribution du scientifique pour le rôle désync (Par TommyXL)", + "\nRéparé le bug où 3 paramètres du Juge n'étaient pas utilisés (Par TommyXL)", + "\nRéparé les boutons étant active lorsque le joueur fût deviné (Par TommyXL)", + "\nQuelques réparations dans l'UI du Devin (Par TommyXL)", + "\nRéparé Double Fin de Réunion (Par TommyXL)", + "\nRéparé l'animation du bouclier de l'Ange Gardien qui ne marchait pas quelques fois correctement avec Vanille (Par TommyXL)", + "\nQuelques réparations dans l'apparition aléatoire dans Airship pour l'hôte (Par TommyXL)", + "\nRéparé le fait que le Nécromancien laisse un corps après une réunion (Par TommyXL)", + "\nRéparé l'état de victoire incorrecte du Bourreau de Travail (Par TommyXL)", + "\nRéparé le maire appelant des réunions même lorsqu'elles sont hors d'usage (Par ryuk)", + "\nRéparé la liste EAC qui ne marchait pas lorsque la liste des ban est désactivé (Par ryuk)", + "\nRéparé le Kamikaze causant des joueurs à moitié morts (Par ryuk)", + "\nRéparé les messages non envoyés aux joueurs Vanille (Par Drakos)", + "\nRéparé des problèmes du Zombie (Par Drakos)", + "\nRéparé le Sac à Box étant Jugé (Par Drakos)", + "\nRéparé le bug où le temps mort d'exécution ne baisse pas lorsque l'on presse F1/F2/F3/F4 (Par NikoCat)", + "\nRéparé les paramètres du démarrage automatique immédiat (Par NikoCat)", + "\nRéparé l'appât s'auto-signaler (Par NikoCat)", + "\nRéparé le client Modded voyant l'icône du bouclier Médical lorsqu'il est mort (Par D1GQ)", + "\nMini ne peut être ni en duel, ni marqué, ni ensanglanté et ni découpé en tranches (Par Lezaiya)", + "\nRéparé les fautes de frappe, incohérences, et erreurs dans les descriptions, noms, etc. (Par Moe, TommyXL Drakos, WaterPanda, Sunnyboi, LezaiYa)", + "\n【Bugs Connus】", + "\n1. Les serveurs peuvent être instables car le protocole nécessite une fixation de la part d'Innersloth", + "\n2. Sosie, Agile et Imitateur sont instables, mais marchent", + "\n3. Des clients Modded ont quelques problèmes, donc il est recommandé d'avoir le mode seulement pour l'hôte", + "\n【Credits de la Traduction】", + "\n - Brésilien (Par Dx7405, Pietro)", + "\nNéerlandais (Par apemv, madmazel_)", + "\n - Français (Par FuroYT, KevOut, Klaomi, Sansationnelle, Space Monkey)", + "\n - Italien (Par alot, Baphojack, Mattix606)", + "\n - Japonais (Par Sunnyboi)", + "\n - Latino-Américain (Par CreepPower)", + "\n - Russe (Par TommyXL, Shoulder Devil, chill_ultimated, Nevermore59)", + "\n - Chinois Simplifié (Par CrewCyan, LezaiYa, NikoCat)", + "\n - Espagnol (Par Dawson, Sunnyboi, thewhiskas27, xxSShadow)", + "\n - Chinois Traditionel (Par FlyFlyTurtle, Hinharrrrr, netherdragontw, Pomelo_)", + "\n Découvre toutes les personnes qui ont traduit sur notre Site Internet\n", + "\n\n★ Bienvenue dans Town of Host: Enhanced v2.0.0 ★" ], "Date": "2024-07-21T12:50:00Z" - }, - { - "Number": "100007", - "Title": "Town of Host: Enhanced v2.1.0", - "Subtitle": "Finally, we're here!", - "Short": "TOH: Enhanced v2.1.0", - "Body": [ - "【Base】", - "\n - Base on TOH: Enhanced v2.0.0", - "\n\r【New Roles/Addons】(5 roles, 6 Add-ons)", - "\n - Yin Yanger (Impostor Killing, idea & coded: Drakos)", - "\n - Possessor (Imposter Ghost Role, idea & coded: D1GQ)", - "\n - Troller (Neutral Chaos, idea: dx7405, coded: TommyXL)", - "\n - Ventguard (Crewmate Support, ported: EHR, coded by: TommyXL)", - "\n - Evader (Addon Helpful, idea: Lime, coded: TommyXL)", - "\n - Rebirth (Addon Helpful, idea & coded: Drakos)", - "\n - Sloth (Harmful Addon, idea & coded: Pyro)", - "\n - Eavesdropper (Addon Helpful, idea by: Crosspost Del Slay, coded: Moe)", - "\n - Spurt (Addon Helpful, idea by: .thediamondstar, coded: Drakos)", - "\n - Prohibited (Addon Harmful, idea by: Crosspost Del Slay, coded: TommyXL)", - "\n - New neutral Team (Faction): Neutral Apocalypse (idea & coded: Marg)", - "\n --- Min/max Neutral Apocalypse can be set", - "\n --- New role: Baker", - "\n --- Berserker and PlagueBearer now moved to Neutral Apocalypse", - "\n --- Soul Collector reworked", - "\n\r【New Settings/Features】", - "\n - Added vent disabling for vanilla (ported from MoreGamemodes by TommyXL & NikoCat)", - "\n --- When a player does not have access to vents, they will never be able to use it", - "\n - More fixes for AntiBlackOut (By TommyXL & Drakos)", - "\n --- Note: This will not completely fix black screen issues, but the more players there are in the game, the less chance of black screen occurrences", - "\n --- To do this, we use revives and base role changes during exile so that dead players will be alive for a couple of seconds but will become dead again", - "\n - Added support role basis changer mid-game (By TommyXL & Drakos)", - "\n --- CopyCat now supports role basis changes", - "\n --- Executioner and Lawyer also change role basis after their target dies", - "\n - TextBoxPatch (Ported: EHR, coded: TommyXL)", - "\n --- Allows you to write any characters into the chat", - "\n - improved Region Menu (coded: D1GQ)", - "\n - Added custom label ID for modded (Ported: EHR, coded: TommyXL)", - "\n - Jester: «Can't Move In Vents» (Setting, coded: TommyXL)", - "\n - Random spawn: Active On Round One (Setting, coded: TommyXL)", - "\n - Added warning message about enabling setting «No Game End»", - "\n --- Warns only the host when he presses the start button", - "\n - Disable Shapeshift menu for some Reject Shapeshift roles (By: Drakos)", - "\n --- For Pitfall, Bomber, Undertaker", - "\n --- It may be used for some more roles", - "\n - Return Ability Votes (By: Drakos)", - "\n --- For Cleanser, Eraser, Fortune teller, Keeper, Oracle, Godfather", - "\n --- First Vote will cancel (Vote Skip) or use the ability; second is regular vote", - "\n - Added «/vote» command (By: Drakos)", - "\n --- Can be disabled in the settings", - "\n - Death reason display improved (ported from EHR).", - "\n - Added role info in setting menu (By: Drakos)", - "\n - Added search bar in settings (By: Drakos)", - "\n - Addon Base (Port From EHR) (By: Drakos)", - "\n --- The settings are now sorted alphabetically", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Jester: Reveal Upon Eject (Setting, by: TheDiamondStar)", - "\n - Executioner: Reveal Target Upon Ejection (Setting, by: TheDiamondStar)", - "\n - Judge: Max trials per game (Setting, by: hinhinarrrrrr)", - "\n - Improved menu for role description in settings", - "\n - Setting: Apocalypse can see each other's Add-ons", - "\n - Settings: «Halloween Decorations» and «Birthday Decoration» (only for modded)", - "\n - Modded players now will see changes in TOHE settings", - "\n - Added custom image «imer» for Mercenary, Bounty Hunter, and Penguin: Thanks @that_one_missing_pixel (Pixel)", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Changed warning message about the API (By: Drakos)", - "\n\r【Bug Fixes/Changes】", - "\n - Phantom Desync: Phantom now plays the invisibility animation instead of teleporting to a random vent for desync roles.", - "\n - Fixed issues with Veteran killing Taskinator, Killing Machine calling meetings, and the Jailed message not showing during the game.", - "\n - Resolved issues with stuck FFA meetings and Fortune Teller showing roles during FFA.", - "\n - Fixed speed bug when Bandit steals the Statue.", - "\n - Resolved Haunt Menu showing «NotAssigned» in Hide & Seek mode.", - "\n - Corrected issues with Doomsayer not using Impostor Vision and various bugs with Psychic.", - "\n - Fixed Taskinator triggering Schrodinger's Cat ability.", - "\n - Corrected Innocent win conditions with Impostor when the setting is enabled.", - "\n - Fixed player spawn issues at the start and after meetings.", - "\n - Resolved full role and add-on display when a player is exiled.", - "\n - Fixed Blackmail not working for non-host modded players.", - "\n - Resolved issues where the Deceiver could kill Serial Killer and where the Deceiver could kill dead players.", - "\n - Corrected several bugs related to Stalker, Enigma, and Madmate Impostor Vision.", - "\n - Fixed issues with Medium messages showing after Medium is dead.", - "\n - Resolved bug where Hangman could kill Nice Mini.", - "\n - Corrected Huntsman minimum kill cooldown.", - "\n - Fixed Bloodmoon not working for modded clients and corrected missing strings for Blackmailer.", - "\n - Fixed issues where the Overseer would show Med Scanner after a meeting.", - "\n - Inhibitor and Saboteur now use sabotage sounds in the intro.", - "\n - Resolved issues where Aware did not work after an Overseer check and Merchant could assign converted add-ons.", - "\n - Fixed bugs with Hater being unable to kill, Crewpostor killing Solsticer, and Impostor Vision not working for Doppelganger.", - "\n - Resolved modded client issues with calling RpcSetName at the end of the game.", - "\n - Fixed win-condition conflicts between terrorists and workaholics.", - "\n - Corrected Necroview interaction with Admired and Madmate roles.", - "\n - Resolved bugs with Judge for modded clients.", - "\n - Gangster and Admirer can no longer get the Egoist role.", - "\n - Fixed bugs with Minus and Plus buttons in settings, ensuring they are always active.", - "\n - Intro Scene optimizations for smoother game start.", - "\n - Fixed numerous typos across roles and settings.", - "\n - Jester can no longer receive the Susceptible role.", - "\n - Added notify message about the game end when RpcEndGame is not received by specific clients.", - "\n - Fixed Baker not showing roles to non-host modded players", - "\n - Fixed mass kicking from lobbies against non-host modded players", - "\n【Translator Credits】", - "\n - Brazilian (By Dx7405, Pietro)", - "\n - Dutch (By apemv, madmazel_)", - "\n - French (By FuroYT, KevOut, Klaomi, Sansationnelle, Space Monkey)", - "\n - Italian (By alot, Baphojack, Mattix606)", - "\n - Japanese (By Sunnyboi)", - "\n - Latin American (By CreepPower)", - "\n - Russian (By TommyXL, Shoulder Devil, chill_ultimated, Nevermore59)", - "\n - Simplified Chinese (By CrewCyan, LezaiYa, NikoCat)", - "\n - Spanish (By Dawson, Sunnyboi, thewhiskas27, xxSShadow)", - "\n - Traditional Chinese (By FlyFlyTurtle, Hinharrrrr, netherdragontw, Pomelo_)", - "\n Check out all of our translators on our website\r\n", - "\n\n★ Welcome to Town of Host: Enhanced v2.1.0 ★" - ], - "Date": "2024-11-3T12:50:00Z" } ] } diff --git a/Resources/Announcements/modNews-it_IT.json b/Resources/Announcements/modNews-it_IT.json index 320704bf4..04481caf0 100644 --- a/Resources/Announcements/modNews-it_IT.json +++ b/Resources/Announcements/modNews-it_IT.json @@ -50,7 +50,7 @@ "\n - Ora i ruoli Base e Amnesico verranno sempre mostrati nell'interfaccia utente dell'indovino (di: TommyXL)", "\n\n【Correzioni di Bug】", "\n - Risolto l'Aggiornamento della Mod (da: Pietro e NikoCat223)", - "\n - Corretto il testo di avanzamento e il contrassegno del bersaglio per il Pirata (Da: ryuk)", + "\n - Corretto il testo di avanzamento e il marchio del bersaglio per il Pirata (Da: ryuk)", "\n - Rimosso Esausto dalla lista dei modificatori attivi (Da: ryuk)", "\n - Boia Mutato ignora il Veterano allarmato (Da: ryuk)", "\n - Bug risolto quando «FixedUpdate» per i ruoli funzionanti nella lobby (Da: TommyXL)", @@ -175,62 +175,59 @@ "\n - Masochista rinominato in Sacco da Boxe (Da WaterPanda)", "\n - Assetato di sangue rinominato in Sanguinario (Da WaterPanda)", "\n - Schizofrenico rinominato in Paranoia (Da WaterPanda)", - "\n - Cambiata la logica per la disconnessione dal gioco se l'API si blocca (Da TommyXL)", - "\n - Imposta 300 di ricarica per Nemesi se non possono usare il pulsante uccidi (Da TommyXL)", - "\n - Modificato messaggio di avvertimento sulla connessione di errore Api (Da Drakos)", "\n\n【Correzioni di Bug】", - "\n - Molti ruoli non saranno più in grado di ricevere alcuni modificatori che erano incompatibili (Da TommyXL, ryuk, WaterPanda)", - "\n - Risolto il cacciatore di taglie che reimpostava i bersagli errati (Da TommyXL)", - "\n - Risolto l'errore nullo post-riunione per Avvoltoio e Cercatore e l'errore dopo i voti in Airship (Da TommyXL)", - "\n - Sistemata la luminosità dei pulsanti personalizzati (Da TommyXL)", - "\n - Sistemati i ruoli senza abilità di usare i condotti che rimanevano bloccati dopo aver provato ad usarli (Da TommyXL)", - "\n - Sistemata l'icona Condotto per i ruoli con la base dell'Ingegnere (Da TommyXL)", - "\n - Sistemato schermo nero durante l'assegnazione dei ruoli (Da TommyXL)", - "\n - Corretta l'assegnazione dello scienziato per il ruolo di desincronizzazione (Da TommyXL)", - "\n - Risolto bug quando non venivano utilizzate 3 impostazioni per il Giudice (Da TommyXL)", - "\n - Sistemati i pulsanti attivi quando il giocatore veniva indovinato (Da TommyXL)", - "\n - Alcune correzioni nell'interfaccia dell'Indovino (Da TommyXL)", - "\n - Risolta la fine doppia della riunione (Da TommyXL)", - "\n - Sistemata l'animazione dello scudo dell'Angelo Custode che a volte non funzionava correttamente in Vanilla (Da TommyXL)", - "\n - Alcune correzioni nella generazione casuale in Airship per l'host (Da TommyXL)", - "\n - Risolto il problema con il Necromante che lasciava un cadavere dopo la riunione (Da TommyXL)", - "\n - Risolto lo stato di vittoria errato dello Stacanovista (Da TommyXL)", - "\n - Risolto il Sindaco che convocava riunioni anche quando era esaurito (Da ryuk)", - "\n - Risolto l'elenco EAC che non funzionava quando l'elenco dei ban era disattivato (Da ryuk)", - "\n - Risolto Kamikaze che causava giocatori mezzi morti (Da ryuk)", - "\n - Risolti i messaggi non inviati ai giocatori Vanilla (Da Drakos)", - "\n - Corretti errori dello Zombi (Da Drakos)", - "\n - Sistemato il Sacco da Boxe che veniva giudicato (Da Drakos)", - "\n - Risolto un bug per cui la ricarica uccisione non funzionava quando si premeva F1/F2/F3/F4 (Da NikoCat)", - "\n - Risolte le impostazioni di auto inizio immediato (Da NikoCat)", - "\n - Risolta l'autosegnalazione dell'esca (Da NikoCat)", - "\n - Risolto errore con il client moddato che vedeva l'icona dello scudo del Medico quando il Medico era morto (Da D1GQ)", + "\n - Many roles will no longer be able to receive some add-ons that were incompatible (By TommyXL, ryuk, WaterPanda)", + "\n - Fixed Bounty Hunter resetting incorrect targets (By TommyXL)", + "\n - Fixed null error post-meeting for Vulture and Seeker and error after votes in Airship (By TommyXL)", + "\n - Fixed custom buttons brightness issues (By TommyXL)", + "\n - Fixed roles without vent ability getting stuck after trying to vent (By TommyXL)", + "\n - Fixed vent icon issues for roles based on Engineer (By TommyXL)", + "\n - Fixed black screens during role assign (By TommyXL)", + "\n - Fixed Scientist assign for desync role (By TommyXL)", + "\n - Fixed bug when 3 settings for Judge was not used (By TommyXL)", + "\n - Fixed buttons are active when the player was guessed (By TommyXL)", + "\n - Some fixes in Guesser UI (By TommyXL)", + "\n - Fixed Double Meeting Ending (By TommyXL)", + "\n - Fixed Guardian Angel Shield Animation sometimes didn't work correctly with Vanilla (By TommyXL)", + "\n - Some fix in random spawn in Airship for the host (By TommyXL)", + "\n - Fixed Necromancer leaving a dead body after the meeting (By TommyXL)", + "\n - Fixed Workaholic incorrect win state (By TommyXL)", + "\n - Fixed Mayor calling meetings even when out of use (By ryuk)", + "\n - Fixed EAC list not working when ban list is off (By ryuk)", + "\n - Fixed Kamikaze causing half-dead players (By ryuk)", + "\n - Fixed Messages not sent to vanilla players (By Drakos)", + "\n - Fixed Zombie Issues (By Drakos)", + "\n - Fixed Punching bag being judged (By Drakos)", + "\n - Fixed bug when kill cooldown not going when press F1/F2/F3/F4 (By NikoCat)", + "\n - Fixed Immediate autostart settings (By NikoCat)", + "\n - Fixed Bait self-reporting (By NikoCat)", + "\n - Fixed Modded client seeing the Medic shield icon when Medic is dead (By D1GQ)", "\n - Mini non può essere duellato, contrassegnato, insanguinato e affettato (Da Lezaiya)", - "\n - Risolti errori di battitura, incoerenze ed errori nelle descrizioni, nei nomi, ecc. (Da Moe, TommyXL, Drakos, WaterPanda, Sunnyboi, LezaiYa)", - "\n - Risolto bug quando dopo aver indovinato, giudicato, ecc. lo stato della riunione non veniva controllato (da TommyXL)", - "\n - Risolto il bug quando Pellicano terminava la partita quando i giocatori mangiati tornavano (da TommyXL)", - "\n - Risolto il problema con Vendicativo quando cercava di uccidere Necromante (Da TommyXL)", - "\n - Risolto il problema con Guardia del Corpo/Crociato quando uccidevano Guardia del Corpo/Crociato, Incaricator e Veterano (Da TommyXL)", - "\n - Sistemato «Quizmaster.None» (Da TommyXL)", - "\n - Corretta stringa mancante «*MayorHideVote» per Vendicatore (Da TommyXL)", - "\n - Corretto bug quando Follenauta veniva assegnato ai Neutrali (Non si applica ad Ammiratore - Da TommyXL)", - "\n - Risolto bug quando il Camuffamento non è scomparso dopo che Camuffatore è stato cancellato (da TommyXL)", - "\n - Probabilmente risolto il bug quando Kamikaze uccise giocatori durante l'espulsione (da TommyXL)", - "\n - Probabilmente risolto il bug quando il risultato del gioco visualizza i soprannomi randomizzati (da TommyXL)", - "\n - Risolto il bug quando l'avvio automatico impostava sempre e salvava 0 ricarica uccisione (da TommyXL)", - "\n - Altre piccole correzioni che si sono verificate in alcuni casi (Da TommyXL)", - "\n - Rapido non può più ottenere Scaltro e viceversa (Da TommyXL)", - "\n - Rimosse le parentesi non necessarie per Illuminatore (da TommyXL)", - "\n - Corretto bug quando Chiromante mostra «INVALIDO:NotAssegnato» (da Drakos)", - "\n - Risolto avvio automatico rotto", + "\n - Fixed typos, inconsistencies, and mistakes in descriptions, names, etc. (By Moe, TommyXL, Drakos, WaterPanda, Sunnyboi, LezaiYa)", + "\n - Fixed bug when after guessing, Judge, etc. the meeting status was not checked (By TommyXL)", + "\n - Fixed bug when Pelican ended the game when eaten players returned (By TommyXL)", + "\n - Fixed Avenger when they try to kill Necromancer (By TommyXL)", + "\n - Fixed Bodyguard/Crusader when they killed Bodyguard/Crusader, Taskinator and Veteran (By TommyXL)", + "\n - Fixed «Quizmaster.None» (By TommyXL)", + "\n - Fixed missed string «*MayorHideVote» for Vindicator (By TommyXL)", + "\n - Fixed bug when Madmate assign Neutrals (Does not apply to Admirer - By TommyXL)", + "\n - Fixed bug when Camouflage did not disappear after Camouflager was erased (By TommyXL)", + "\n - Probably fixed the bug when Kamikaze killed players during exile (By TommyXL)", + "\n - Probably fixed bug when in-game result displayed randomized nicknames (By TommyXL)", + "\n - Fixed bug when Auto Start always stes ans saved 0 kill cooldown (By TommyXL)", + "\n - Other small fixes that occurred in certain cases (By TommyXL)", + "\n - Swift can no longer get Tricky and vice versa (By TommyXL)", + "\n - Remove unnecessary parenthesis for Lighter (By TommyXL)", + "\n - Fixed bug when Fortune Teller shows «INVALID:NotAssigned» (By Drakos)", + "\n - Fixed broken Auto Start", "\n - Corretto bug (si spera) quando l'host ha cambiato il suo soprannome quando è stato ucciso da Doppelganger (Da TommyXL)", - "\n - Corretto bug quando F1 mostra le impostazioni dei ruoli (Da TommyXL)", - "\n - Corretto bug quando Veterano uccide Incaricator (Da TommyXL)", - "\n - Risolto (si spera) l'ultima domanda sul colore per Maestro dei Quiz (Da TommyXL)", - "\n - Risolto bug quando Macchina Assassina può chiamare una riunione (Da TommyXL)", - "\n - Risolto il bug quando il messaggio Jailed non veniva visualizzato (da TommyXL)", - "\n【Bug noti】", - "\n - 1. I server potrebbero essere instabili poiché il protocollo richiede una correzione da parte di Innersloth", + "\n - Fixed bug when F1 shows role settings (By TommyXL)", + "\n - Fixed bug when Veteran kills Taskinator (By TommyXL)", + "\n - Fixed (hopefully) the last color question for Quizmaster (By TommyXL)", + "\n - Fixed bug when Killing Machine can call a meeting (By TommyXL)", + "\n - Fixed bug when Jailed message not shown (By TommyXL)", + "\n【Known bugs】", + "\n - 1. Servers may be unstable as the protocol requires fixing on Innersloth's side", "\n - 2. Doppelganger, Rapido e Imitatore sono instabili, ma funzionano", "\n - 3. I Client Moddati hanno alcuni problemi, quindi si consiglia di far avere la mod solo al host", "\n【Crediti dei Traduttori】", @@ -252,13 +249,13 @@ { "Number": "100007", "Title": "Town of Host: Enhanced v2.1.0", - "Subtitle": "Finalmente ci siamo!", + "Subtitle": "Finally, we're here!", "Short": "TOH: Enhanced v2.1.0", "Body": [ "【Base】", - "\n - In base a TOH: Enhanced v2.0.0", - "\n\n【Nuovi Ruoli/Modificatori】(5 Ruoli, 6 Modificatori)", - "\n - Yin Yanger (Impostor Assassini, ideato e codificato: Drakos)", + "\n - Base on TOH: Enhanced v2.0.0", + "\n\r【New Roles/Addons】(5 roles, 6 Add-ons)", + "\n - Yin Yanger (Impostor Killing, idea & coded: Drakos)", "\n - Possessor (Imposter Ghost Role, idea & coded: D1GQ)", "\n - Troller (Neutral Chaos, idea: dx7405, coded: TommyXL)", "\n - Ventguard (Crewmate Support, ported: EHR, coded by: TommyXL)", @@ -273,7 +270,7 @@ "\n --- New role: Baker", "\n --- Berserker and PlagueBearer now moved to Neutral Apocalypse", "\n --- Soul Collector reworked", - "\n\n【Nuove Impostazioni/Funzioni】", + "\n\r【New Settings/Features】", "\n - Added vent disabling for vanilla (ported from MoreGamemodes by TommyXL & NikoCat)", "\n --- When a player does not have access to vents, they will never be able to use it", "\n - More fixes for AntiBlackOut (By TommyXL & Drakos)", @@ -294,7 +291,7 @@ "\n --- For Pitfall, Bomber, Undertaker", "\n --- It may be used for some more roles", "\n - Return Ability Votes (By: Drakos)", - "\n --- Per Purificatore, Cancellatore, Chiromante, Custode, Oracolo, Padrino", + "\n --- For Cleanser, Eraser, Fortune teller, Keeper, Oracle, Godfather", "\n --- First Vote will cancel (Vote Skip) or use the ability; second is regular vote", "\n - Added «/vote» command (By: Drakos)", "\n --- Can be disabled in the settings", @@ -315,10 +312,10 @@ "\n - Changed warning message about the API (By: Drakos)", "\n - Changed warning message about the API (By: Drakos)", "\n - Changed warning message about the API (By: Drakos)", - "\n\n【Correzioni di Bug/Cambiamenti】", + "\n\r【Bug Fixes/Changes】", "\n - Phantom Desync: Phantom now plays the invisibility animation instead of teleporting to a random vent for desync roles.", "\n - Fixed issues with Veteran killing Taskinator, Killing Machine calling meetings, and the Jailed message not showing during the game.", - "\n - Risolti i problemi con TCT in riunioni bloccate e Chiromante che mostrano i ruoli durante TCT.", + "\n - Resolved issues with stuck FFA meetings and Fortune Teller showing roles during FFA.", "\n - Fixed speed bug when Bandit steals the Statue.", "\n - Resolved Haunt Menu showing «NotAssigned» in Hide & Seek mode.", "\n - Corretti i problemi con Catastrofista che non usano il campo visivo impostore e vari bug col Psichico.", @@ -341,27 +338,27 @@ "\n - Fixed win-condition conflicts between terrorists and workaholics.", "\n - Corrected Necroview interaction with Admired and Madmate roles.", "\n - Resolved bugs with Judge for modded clients.", - "\n - Gangster e Ammiratore non possono più ottenere il ruolo Egoista.", + "\n - Gangster and Admirer can no longer get the Egoist role.", "\n - Fixed bugs with Minus and Plus buttons in settings, ensuring they are always active.", "\n - Intro Scene optimizations for smoother game start.", "\n - Fixed numerous typos across roles and settings.", - "\n - Giullare non può più ricevere il ruolo Suscettibile.", + "\n - Jester can no longer receive the Susceptible role.", "\n - Aggiunto messaggio di notifica sulla fine del gioco quando RpcEndGame non è ricevuto da client specifici.", "\n - Fixed Baker not showing roles to non-host modded players", "\n - Fixed mass kicking from lobbies against non-host modded players", - "\n【Crediti dei Traduttori】", - "\n - Brasiliano (Da Dx7405, Pietro)", - "\n - Olandese (Da apemv, madmazel_)", - "\n - Francese (Da FuroYT, KevOut, Klaomi, Sansationnelle, Space Monkey)", - "\n - Italiano (Da alot, Baphojack, Mattix606)", - "\n - Giapponese (Da Sunnyboi)", - "\n - Latinoamericano (Da CreepPower)", - "\n - Russo (Da TommyXL, Shoulder Devil, chill_ultimated, Nevermore59)", - "\n - Cinese Semplificato (Da CrewCyan, LezaiYa, NikoCat)", - "\n - Spagnolo (Da Dawson, Sunnyboi, thewhiskas27, xxSShadow)", - "\n - Cinese Tradizionale (Da FlyFlyTurtle, Hinharrrrr, netherdragontw, Pomelo_)", - "\n Scopri tutti i nostri traduttori sul nostro sito web\n", - "\n\n★ Benvenuto a Town of Host: Enhanced v2.1.0 ★" + "\n【Translator Credits】", + "\n - Brazilian (By Dx7405, Pietro)", + "\n - Dutch (By apemv, madmazel_)", + "\n - French (By FuroYT, KevOut, Klaomi, Sansationnelle, Space Monkey)", + "\n - Italian (By alot, Baphojack, Mattix606)", + "\n - Japanese (By Sunnyboi)", + "\n - Latin American (By CreepPower)", + "\n - Russian (By TommyXL, Shoulder Devil, chill_ultimated, Nevermore59)", + "\n - Simplified Chinese (By CrewCyan, LezaiYa, NikoCat)", + "\n - Spanish (By Dawson, Sunnyboi, thewhiskas27, xxSShadow)", + "\n - Traditional Chinese (By FlyFlyTurtle, Hinharrrrr, netherdragontw, Pomelo_)", + "\n Check out all of our translators on our website\r\n", + "\n\n★ Welcome to Town of Host: Enhanced v2.1.0 ★" ], "Date": "2024-11-3T12:50:00Z" } diff --git a/Resources/Announcements/modNews-ja_JP.json b/Resources/Announcements/modNews-ja_JP.json index 96923dc90..f7de25f88 100644 --- a/Resources/Announcements/modNews-ja_JP.json +++ b/Resources/Announcements/modNews-ja_JP.json @@ -175,195 +175,54 @@ "\n- マゾヒストをパンチングバッグに改名(製作者:WaterPanda)", "\n- ブラッドラストを血に飢えたに改名 (製作者:WaterPanda)", "\n- シゾフレニックをパラノイアに改名(製作者:WaterPanda)", - "\n - Changed the logic for disconnecting from the game if the API crashes (By TommyXL)", - "\n - Set 300 CD for Nemesis if they cannot use the kill button (By TommyXL)", - "\n - Changed warning message about Api Error Connection (By Drakos)", "\n\n【バグ修正】", - "\n - Many roles will no longer be able to receive some add-ons that were incompatible (By TommyXL, ryuk, WaterPanda)", - "\n - Fixed Bounty Hunter resetting incorrect targets (By TommyXL)", - "\n - Fixed null error post-meeting for Vulture and Seeker and error after votes in Airship (By TommyXL)", - "\n - Fixed custom buttons brightness issues (By TommyXL)", - "\n - Fixed roles without vent ability getting stuck after trying to vent (By TommyXL)", - "\n - Fixed vent icon issues for roles based on Engineer (By TommyXL)", - "\n - Fixed black screens during role assign (By TommyXL)", - "\n - Fixed Scientist assign for desync role (By TommyXL)", - "\n - Fixed bug when 3 settings for Judge was not used (By TommyXL)", - "\n - Fixed buttons are active when the player was guessed (By TommyXL)", - "\n - Some fixes in Guesser UI (By TommyXL)", - "\n - Fixed Double Meeting Ending (By TommyXL)", - "\n - Fixed Guardian Angel Shield Animation sometimes didn't work correctly with Vanilla (By TommyXL)", - "\n - Some fix in random spawn in Airship for the host (By TommyXL)", - "\n - Fixed Necromancer leaving a dead body after the meeting (By TommyXL)", - "\n - Fixed Workaholic incorrect win state (By TommyXL)", - "\n - Fixed Mayor calling meetings even when out of use (By ryuk)", - "\n - Fixed EAC list not working when ban list is off (By ryuk)", - "\n - Fixed Kamikaze causing half-dead players (By ryuk)", - "\n - Fixed Messages not sent to vanilla players (By Drakos)", - "\n - Fixed Zombie Issues (By Drakos)", - "\n - Fixed Punching bag being judged (By Drakos)", - "\n - Fixed bug when kill cooldown not going when press F1/F2/F3/F4 (By NikoCat)", - "\n - Fixed Immediate autostart settings (By NikoCat)", - "\n - Fixed Bait self-reporting (By NikoCat)", - "\n - Fixed Modded client seeing the Medic shield icon when Medic is dead (By D1GQ)", - "\n - Mini can not be duelled, marked, blooded, and sliced (By Lezaiya)", - "\n - Fixed typos, inconsistencies, and mistakes in descriptions, names, etc. (By Moe, TommyXL, Drakos, WaterPanda, Sunnyboi, LezaiYa)", - "\n - Fixed bug when after guessing, Judge, etc. the meeting status was not checked (By TommyXL)", - "\n - Fixed bug when Pelican ended the game when eaten players returned (By TommyXL)", - "\n - Fixed Avenger when they try to kill Necromancer (By TommyXL)", - "\n - Fixed Bodyguard/Crusader when they killed Bodyguard/Crusader, Taskinator and Veteran (By TommyXL)", - "\n - Fixed «Quizmaster.None» (By TommyXL)", - "\n - Fixed missed string «*MayorHideVote» for Vindicator (By TommyXL)", - "\n - Fixed bug when Madmate assign Neutrals (Does not apply to Admirer - By TommyXL)", - "\n - Fixed bug when Camouflage did not disappear after Camouflager was erased (By TommyXL)", - "\n - Probably fixed the bug when Kamikaze killed players during exile (By TommyXL)", - "\n - Probably fixed bug when in-game result displayed randomized nicknames (By TommyXL)", - "\n - Fixed bug when Auto Start always stes ans saved 0 kill cooldown (By TommyXL)", - "\n - Other small fixes that occurred in certain cases (By TommyXL)", - "\n - Swift can no longer get Tricky and vice versa (By TommyXL)", - "\n - Remove unnecessary parenthesis for Lighter (By TommyXL)", - "\n - Fixed bug when Fortune Teller shows «INVALID:NotAssigned» (By Drakos)", - "\n - Fixed broken Auto Start", - "\n - Fixed bug (hopefully) when the host changed his nickname to his own when he was killed by Doppelganger (By TommyXL)", - "\n - Fixed bug when F1 shows role settings (By TommyXL)", - "\n - Fixed bug when Veteran kills Taskinator (By TommyXL)", - "\n - Fixed (hopefully) the last color question for Quizmaster (By TommyXL)", - "\n - Fixed bug when Killing Machine can call a meeting (By TommyXL)", - "\n - Fixed bug when Jailed message not shown (By TommyXL)", - "\n【Known bugs】", - "\n - 1. Servers may be unstable as the protocol requires fixing on Innersloth's side", - "\n - 2. Doppelganger, Swift and Imitator are unstable, but work", - "\n - 3. Modded clients have some problems, so it is recommended to have the mod only on Host", - "\n【Translator Credits】", - "\n - Brazilian (By Dx7405, Pietro)", - "\n - Dutch (By apemv, madmazel_)", - "\n - French (By FuroYT, KevOut, Klaomi, Sansationnelle, Space Monkey)", - "\n - Italian (By alot, Baphojack, Mattix606)", - "\n - Japanese (By Sunnyboi)", - "\n - Latin American (By CreepPower)", - "\n - Russian (By TommyXL, Shoulder Devil, chill_ultimated, Nevermore59)", - "\n - Simplified Chinese (By CrewCyan, LezaiYa, NikoCat)", - "\n - Spanish (By Dawson, Sunnyboi, thewhiskas27, xxSShadow)", - "\n - Traditional Chinese (By FlyFlyTurtle, Hinharrrrr, netherdragontw, Pomelo_)", - "\n Check out all of our translators on our website\r\n", - "\n\n★ Welcome to Town of Host: Enhanced v2.0.0 ★" - ], - "Date": "2024-07-21T12:50:00Z" - }, - { - "Number": "100007", - "Title": "Town of Host: Enhanced v2.1.0", - "Subtitle": "Finally, we're here!", - "Short": "TOH: Enhanced v2.1.0", - "Body": [ - "【Base】", - "\n - Base on TOH: Enhanced v2.0.0", - "\n\r【New Roles/Addons】(5 roles, 6 Add-ons)", - "\n - Yin Yanger (Impostor Killing, idea & coded: Drakos)", - "\n - Possessor (Imposter Ghost Role, idea & coded: D1GQ)", - "\n - Troller (Neutral Chaos, idea: dx7405, coded: TommyXL)", - "\n - Ventguard (Crewmate Support, ported: EHR, coded by: TommyXL)", - "\n - Evader (Addon Helpful, idea: Lime, coded: TommyXL)", - "\n - Rebirth (Addon Helpful, idea & coded: Drakos)", - "\n - Sloth (Harmful Addon, idea & coded: Pyro)", - "\n - Eavesdropper (Addon Helpful, idea by: Crosspost Del Slay, coded: Moe)", - "\n - Spurt (Addon Helpful, idea by: .thediamondstar, coded: Drakos)", - "\n - Prohibited (Addon Harmful, idea by: Crosspost Del Slay, coded: TommyXL)", - "\n - New neutral Team (Faction): Neutral Apocalypse (idea & coded: Marg)", - "\n --- Min/max Neutral Apocalypse can be set", - "\n --- New role: Baker", - "\n --- Berserker and PlagueBearer now moved to Neutral Apocalypse", - "\n --- Soul Collector reworked", - "\n\r【New Settings/Features】", - "\n - Added vent disabling for vanilla (ported from MoreGamemodes by TommyXL & NikoCat)", - "\n --- When a player does not have access to vents, they will never be able to use it", - "\n - More fixes for AntiBlackOut (By TommyXL & Drakos)", - "\n --- Note: This will not completely fix black screen issues, but the more players there are in the game, the less chance of black screen occurrences", - "\n --- To do this, we use revives and base role changes during exile so that dead players will be alive for a couple of seconds but will become dead again", - "\n - Added support role basis changer mid-game (By TommyXL & Drakos)", - "\n --- CopyCat now supports role basis changes", - "\n --- Executioner and Lawyer also change role basis after their target dies", - "\n - TextBoxPatch (Ported: EHR, coded: TommyXL)", - "\n --- Allows you to write any characters into the chat", - "\n - improved Region Menu (coded: D1GQ)", - "\n - Added custom label ID for modded (Ported: EHR, coded: TommyXL)", - "\n - Jester: «Can't Move In Vents» (Setting, coded: TommyXL)", - "\n - Random spawn: Active On Round One (Setting, coded: TommyXL)", - "\n - Added warning message about enabling setting «No Game End»", - "\n --- Warns only the host when he presses the start button", - "\n - Disable Shapeshift menu for some Reject Shapeshift roles (By: Drakos)", - "\n --- For Pitfall, Bomber, Undertaker", - "\n --- It may be used for some more roles", - "\n - Return Ability Votes (By: Drakos)", - "\n --- For Cleanser, Eraser, Fortune teller, Keeper, Oracle, Godfather", - "\n --- First Vote will cancel (Vote Skip) or use the ability; second is regular vote", - "\n - Added «/vote» command (By: Drakos)", - "\n --- Can be disabled in the settings", - "\n - Death reason display improved (ported from EHR).", - "\n - Added role info in setting menu (By: Drakos)", - "\n - Added search bar in settings (By: Drakos)", - "\n - Addon Base (Port From EHR) (By: Drakos)", - "\n --- The settings are now sorted alphabetically", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Jester: Reveal Upon Eject (Setting, by: TheDiamondStar)", - "\n - Executioner: Reveal Target Upon Ejection (Setting, by: TheDiamondStar)", - "\n - Judge: Max trials per game (Setting, by: hinhinarrrrrr)", - "\n - Improved menu for role description in settings", - "\n - Setting: Apocalypse can see each other's Add-ons", - "\n - Settings: «Halloween Decorations» and «Birthday Decoration» (only for modded)", - "\n - Modded players now will see changes in TOHE settings", - "\n - Added custom image «imer» for Mercenary, Bounty Hunter, and Penguin: Thanks @that_one_missing_pixel (Pixel)", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Changed warning message about the API (By: Drakos)", - "\n\r【Bug Fixes/Changes】", - "\n - Phantom Desync: Phantom now plays the invisibility animation instead of teleporting to a random vent for desync roles.", - "\n - Fixed issues with Veteran killing Taskinator, Killing Machine calling meetings, and the Jailed message not showing during the game.", - "\n - Resolved issues with stuck FFA meetings and Fortune Teller showing roles during FFA.", - "\n - Fixed speed bug when Bandit steals the Statue.", - "\n - Resolved Haunt Menu showing «NotAssigned» in Hide & Seek mode.", - "\n - Corrected issues with Doomsayer not using Impostor Vision and various bugs with Psychic.", - "\n - Fixed Taskinator triggering Schrodinger's Cat ability.", - "\n - Corrected Innocent win conditions with Impostor when the setting is enabled.", - "\n - Fixed player spawn issues at the start and after meetings.", - "\n - Resolved full role and add-on display when a player is exiled.", - "\n - Fixed Blackmail not working for non-host modded players.", - "\n - Resolved issues where the Deceiver could kill Serial Killer and where the Deceiver could kill dead players.", - "\n - Corrected several bugs related to Stalker, Enigma, and Madmate Impostor Vision.", - "\n - Fixed issues with Medium messages showing after Medium is dead.", - "\n - Resolved bug where Hangman could kill Nice Mini.", - "\n - Corrected Huntsman minimum kill cooldown.", - "\n - Fixed Bloodmoon not working for modded clients and corrected missing strings for Blackmailer.", - "\n - Fixed issues where the Overseer would show Med Scanner after a meeting.", - "\n - Inhibitor and Saboteur now use sabotage sounds in the intro.", - "\n - Resolved issues where Aware did not work after an Overseer check and Merchant could assign converted add-ons.", - "\n - Fixed bugs with Hater being unable to kill, Crewpostor killing Solsticer, and Impostor Vision not working for Doppelganger.", - "\n - Resolved modded client issues with calling RpcSetName at the end of the game.", - "\n - Fixed win-condition conflicts between terrorists and workaholics.", - "\n - Corrected Necroview interaction with Admired and Madmate roles.", - "\n - Resolved bugs with Judge for modded clients.", - "\n - Gangster and Admirer can no longer get the Egoist role.", - "\n - Fixed bugs with Minus and Plus buttons in settings, ensuring they are always active.", - "\n - Intro Scene optimizations for smoother game start.", - "\n - Fixed numerous typos across roles and settings.", - "\n - Jester can no longer receive the Susceptible role.", - "\n - Added notify message about the game end when RpcEndGame is not received by specific clients.", - "\n - Fixed Baker not showing roles to non-host modded players", - "\n - Fixed mass kicking from lobbies against non-host modded players", - "\n【Translator Credits】", - "\n - Brazilian (By Dx7405, Pietro)", - "\n - Dutch (By apemv, madmazel_)", - "\n - French (By FuroYT, KevOut, Klaomi, Sansationnelle, Space Monkey)", - "\n - Italian (By alot, Baphojack, Mattix606)", - "\n - Japanese (By Sunnyboi)", - "\n - Latin American (By CreepPower)", + "\n- 多くの役割が互換性のないアドオンを受け取ることができなくなります(製作者:TommyXL、ryuk、WaterPanda)", + "\n- バウンティハンターのターゲットリセットの修正 (製作者:TommyXL)", + "\n- ミーティング後のnullエラー(ハゲタカと探求者)とエアシップでの投票後のエラーの修正 (製作者:TommyXL)", + "\n- カスタムボタンの明るさ問題の修正(製作者:TommyXL)", + "\n- ベント能力がない役割がベントしようとしてスタックするバグの修正(製作者:TommyXL)", + "\n- エンジニアに基づく役割のベントアイコン問題の修正(製作者:TommyXL)", + "\n- 役割割り当て中のブラックスクリーンの修正(製作者:TommyXL)", + "\n- デシンク役割の科学者割り当ての修正(製作者:TommyXL)", + "\n- ジャッジ用の3つの設定が使用されていなかったバグの修正(製作者:TommyXL)", + "\n- 推測されたプレイヤーのボタンがアクティブなままの修正(製作者:TommyXL)", + "\n- Guesser UIのいくつかの修正(製作者:TommyXL)", + "\n- ダブルミーティング終了の修正(製作者:TommyXL)", + "\n- ガーディアンエンジェルのシールドアニメーションがバニラで正しく動作しない場合の修正(製作者:TommyXL)", + "\n- ホストのエアシップでのランダムスポーンの修正(製作者:TommyXL)", + "\n- ネクロマンサーがミーティング後に死体を残すバグの修正(製作者:TommyXL)", + "\n- ワーカホリックの誤った勝利状態の修正 (製作者:TommyXL)", + "\n- 市長が使用回数切れの時に会議を招集するバグの修正(製作者:ryuk)", + "\n- 禁止リストがオフの時にEACリストが機能しないバグの修正(製作者:ryuk)", + "\n- ロケットミサイルが半死プレイヤーを引き起こすバグの修正 (製作者:ryuk)", + "\n- バニラプレイヤーにメッセージが送信されないバグの修正(製作者:Drakos)", + "\n- ゾンビの問題の修正(製作者:Drakos)", + "\n- パンチングバッグが判定されるバグの修正(製作者:Drakos)", + "\n- F1/F2/F3/F4を押した際にキルクールダウンが進行しないバグの修正(製作者:NikoCat)", + "\n- 即時自動開始設定の修正(製作者:NikoCat)", + "\n- おとりの自己報告の修正(製作者:NikoCat)", + "\n- モッドクライアントがメディックのシールドアイコンを見るバグの修正(製作者:D1GQ)", + "\n- ミニはデュエル、マーキング、ブラッド、スライスできません(製作者:Lezaiya)", + "\n- 説明、名前などのタイプミス、一貫性、誤りの修正(製作者:Moe、TommyXL、Drakos、WaterPanda、Sunnyboi、LezaiYa)", + "\n【既知のバグ】", + "\n- 1. プロトコルの修正が必要なため、サーバーが不安定になる可能性があります(Innersloth側)", + "\n- 2. ドッペルゲンガー、速い、模倣者、は不安定ですが、動作します", + "\n- 3. モッドクライアントにはいくつかの問題があるため、モッドはホストのみにすることを推奨します", + "\n【翻訳者のクレジット】", + "\n- ブラジル (製作者:Dx7405、Pietro)", + "\n- オランダ語 (製作者:apemv、madmazel_)", + "\n- フランス語 (製作者:FuroYT、KevOut、Klaomi、Sansationnelle、Space Monkey)", + "\n- イタリア語 (製作者:alot、Baphojack、Mattix606)", + "\n- 日本語 (製作者:Sunnyboi)", + "\n- ラテンアメリカ (製作者:CreepPower)", "\n- ロシア語 (製作者:TommyXL、Shoulder Devil、chill_ultimated、Nevermore59)", "\n- 簡体字中国語 (製作者:CrewCyan、LezaiYa、NikoCat)", "\n- スペイン語 (製作者:Dawson、Sunnyboi、thewhiskas27、xxSShadow)", "\n- 繁体字中国語 (製作者:FlyFlyTurtle、Hinharrrrr、netherdragontw、Pomelo_)", "\n当社のウェブサイトで、すべての翻訳者をご覧ください\n", - "\n\n★ Town of Host: Enhanced v2.1.0 へようこそ ★" + "\n\n★ Town of Host: Enhanced v2.0.0 へようこそ ★" ], - "Date": "2024-11-3T12:50:00Z" + "Date": "2024-07-21T12:50:00Z" } ] } diff --git a/Resources/Announcements/modNews-ko_KR.json b/Resources/Announcements/modNews-ko_KR.json index a88211c41..8207ac47c 100644 --- a/Resources/Announcements/modNews-ko_KR.json +++ b/Resources/Announcements/modNews-ko_KR.json @@ -175,9 +175,6 @@ "\n - Masochist renamed to Punching Bag (By WaterPanda)", "\n - Bloodlust renamed to Bloodthirst (By WaterPanda)", "\n - Schizophrenic renamed to Paranoia (By WaterPanda)", - "\n - Changed the logic for disconnecting from the game if the API crashes (By TommyXL)", - "\n - Set 300 CD for Nemesis if they cannot use the kill button (By TommyXL)", - "\n - Changed warning message about Api Error Connection (By Drakos)", "\n\r【Bug Fixes】", "\n - Many roles will no longer be able to receive some add-ons that were incompatible (By TommyXL, ryuk, WaterPanda)", "\n - Fixed Bounty Hunter resetting incorrect targets (By TommyXL)", @@ -207,28 +204,6 @@ "\n - Fixed Modded client seeing the Medic shield icon when Medic is dead (By D1GQ)", "\n - Mini can not be duelled, marked, blooded, and sliced (By Lezaiya)", "\n - Fixed typos, inconsistencies, and mistakes in descriptions, names, etc. (By Moe, TommyXL, Drakos, WaterPanda, Sunnyboi, LezaiYa)", - "\n - Fixed bug when after guessing, Judge, etc. the meeting status was not checked (By TommyXL)", - "\n - Fixed bug when Pelican ended the game when eaten players returned (By TommyXL)", - "\n - Fixed Avenger when they try to kill Necromancer (By TommyXL)", - "\n - Fixed Bodyguard/Crusader when they killed Bodyguard/Crusader, Taskinator and Veteran (By TommyXL)", - "\n - Fixed «Quizmaster.None» (By TommyXL)", - "\n - Fixed missed string «*MayorHideVote» for Vindicator (By TommyXL)", - "\n - Fixed bug when Madmate assign Neutrals (Does not apply to Admirer - By TommyXL)", - "\n - Fixed bug when Camouflage did not disappear after Camouflager was erased (By TommyXL)", - "\n - Probably fixed the bug when Kamikaze killed players during exile (By TommyXL)", - "\n - Probably fixed bug when in-game result displayed randomized nicknames (By TommyXL)", - "\n - Fixed bug when Auto Start always stes ans saved 0 kill cooldown (By TommyXL)", - "\n - Other small fixes that occurred in certain cases (By TommyXL)", - "\n - Swift can no longer get Tricky and vice versa (By TommyXL)", - "\n - Remove unnecessary parenthesis for Lighter (By TommyXL)", - "\n - Fixed bug when Fortune Teller shows «INVALID:NotAssigned» (By Drakos)", - "\n - Fixed broken Auto Start", - "\n - Fixed bug (hopefully) when the host changed his nickname to his own when he was killed by Doppelganger (By TommyXL)", - "\n - Fixed bug when F1 shows role settings (By TommyXL)", - "\n - Fixed bug when Veteran kills Taskinator (By TommyXL)", - "\n - Fixed (hopefully) the last color question for Quizmaster (By TommyXL)", - "\n - Fixed bug when Killing Machine can call a meeting (By TommyXL)", - "\n - Fixed bug when Jailed message not shown (By TommyXL)", "\n【Known bugs】", "\n - 1. Servers may be unstable as the protocol requires fixing on Innersloth's side", "\n - 2. Doppelganger, Swift and Imitator are unstable, but work", @@ -248,122 +223,6 @@ "\n\n★ Welcome to Town of Host: Enhanced v2.0.0 ★" ], "Date": "2024-07-21T12:50:00Z" - }, - { - "Number": "100007", - "Title": "Town of Host: Enhanced v2.1.0", - "Subtitle": "Finally, we're here!", - "Short": "TOH: Enhanced v2.1.0", - "Body": [ - "【Base】", - "\n - Base on TOH: Enhanced v2.0.0", - "\n\r【New Roles/Addons】(5 roles, 6 Add-ons)", - "\n - Yin Yanger (Impostor Killing, idea & coded: Drakos)", - "\n - Possessor (Imposter Ghost Role, idea & coded: D1GQ)", - "\n - Troller (Neutral Chaos, idea: dx7405, coded: TommyXL)", - "\n - Ventguard (Crewmate Support, ported: EHR, coded by: TommyXL)", - "\n - Evader (Addon Helpful, idea: Lime, coded: TommyXL)", - "\n - Rebirth (Addon Helpful, idea & coded: Drakos)", - "\n - Sloth (Harmful Addon, idea & coded: Pyro)", - "\n - Eavesdropper (Addon Helpful, idea by: Crosspost Del Slay, coded: Moe)", - "\n - Spurt (Addon Helpful, idea by: .thediamondstar, coded: Drakos)", - "\n - Prohibited (Addon Harmful, idea by: Crosspost Del Slay, coded: TommyXL)", - "\n - New neutral Team (Faction): Neutral Apocalypse (idea & coded: Marg)", - "\n --- Min/max Neutral Apocalypse can be set", - "\n --- New role: Baker", - "\n --- Berserker and PlagueBearer now moved to Neutral Apocalypse", - "\n --- Soul Collector reworked", - "\n\r【New Settings/Features】", - "\n - Added vent disabling for vanilla (ported from MoreGamemodes by TommyXL & NikoCat)", - "\n --- When a player does not have access to vents, they will never be able to use it", - "\n - More fixes for AntiBlackOut (By TommyXL & Drakos)", - "\n --- Note: This will not completely fix black screen issues, but the more players there are in the game, the less chance of black screen occurrences", - "\n --- To do this, we use revives and base role changes during exile so that dead players will be alive for a couple of seconds but will become dead again", - "\n - Added support role basis changer mid-game (By TommyXL & Drakos)", - "\n --- CopyCat now supports role basis changes", - "\n --- Executioner and Lawyer also change role basis after their target dies", - "\n - TextBoxPatch (Ported: EHR, coded: TommyXL)", - "\n --- Allows you to write any characters into the chat", - "\n - improved Region Menu (coded: D1GQ)", - "\n - Added custom label ID for modded (Ported: EHR, coded: TommyXL)", - "\n - Jester: «Can't Move In Vents» (Setting, coded: TommyXL)", - "\n - Random spawn: Active On Round One (Setting, coded: TommyXL)", - "\n - Added warning message about enabling setting «No Game End»", - "\n --- Warns only the host when he presses the start button", - "\n - Disable Shapeshift menu for some Reject Shapeshift roles (By: Drakos)", - "\n --- For Pitfall, Bomber, Undertaker", - "\n --- It may be used for some more roles", - "\n - Return Ability Votes (By: Drakos)", - "\n --- For Cleanser, Eraser, Fortune teller, Keeper, Oracle, Godfather", - "\n --- First Vote will cancel (Vote Skip) or use the ability; second is regular vote", - "\n - Added «/vote» command (By: Drakos)", - "\n --- Can be disabled in the settings", - "\n - Death reason display improved (ported from EHR).", - "\n - Added role info in setting menu (By: Drakos)", - "\n - Added search bar in settings (By: Drakos)", - "\n - Addon Base (Port From EHR) (By: Drakos)", - "\n --- The settings are now sorted alphabetically", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Jester: Reveal Upon Eject (Setting, by: TheDiamondStar)", - "\n - Executioner: Reveal Target Upon Ejection (Setting, by: TheDiamondStar)", - "\n - Judge: Max trials per game (Setting, by: hinhinarrrrrr)", - "\n - Improved menu for role description in settings", - "\n - Setting: Apocalypse can see each other's Add-ons", - "\n - Settings: «Halloween Decorations» and «Birthday Decoration» (only for modded)", - "\n - Modded players now will see changes in TOHE settings", - "\n - Added custom image «imer» for Mercenary, Bounty Hunter, and Penguin: Thanks @that_one_missing_pixel (Pixel)", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Changed warning message about the API (By: Drakos)", - "\n\r【Bug Fixes/Changes】", - "\n - Phantom Desync: Phantom now plays the invisibility animation instead of teleporting to a random vent for desync roles.", - "\n - Fixed issues with Veteran killing Taskinator, Killing Machine calling meetings, and the Jailed message not showing during the game.", - "\n - Resolved issues with stuck FFA meetings and Fortune Teller showing roles during FFA.", - "\n - Fixed speed bug when Bandit steals the Statue.", - "\n - Resolved Haunt Menu showing «NotAssigned» in Hide & Seek mode.", - "\n - Corrected issues with Doomsayer not using Impostor Vision and various bugs with Psychic.", - "\n - Fixed Taskinator triggering Schrodinger's Cat ability.", - "\n - Corrected Innocent win conditions with Impostor when the setting is enabled.", - "\n - Fixed player spawn issues at the start and after meetings.", - "\n - Resolved full role and add-on display when a player is exiled.", - "\n - Fixed Blackmail not working for non-host modded players.", - "\n - Resolved issues where the Deceiver could kill Serial Killer and where the Deceiver could kill dead players.", - "\n - Corrected several bugs related to Stalker, Enigma, and Madmate Impostor Vision.", - "\n - Fixed issues with Medium messages showing after Medium is dead.", - "\n - Resolved bug where Hangman could kill Nice Mini.", - "\n - Corrected Huntsman minimum kill cooldown.", - "\n - Fixed Bloodmoon not working for modded clients and corrected missing strings for Blackmailer.", - "\n - Fixed issues where the Overseer would show Med Scanner after a meeting.", - "\n - Inhibitor and Saboteur now use sabotage sounds in the intro.", - "\n - Resolved issues where Aware did not work after an Overseer check and Merchant could assign converted add-ons.", - "\n - Fixed bugs with Hater being unable to kill, Crewpostor killing Solsticer, and Impostor Vision not working for Doppelganger.", - "\n - Resolved modded client issues with calling RpcSetName at the end of the game.", - "\n - Fixed win-condition conflicts between terrorists and workaholics.", - "\n - Corrected Necroview interaction with Admired and Madmate roles.", - "\n - Resolved bugs with Judge for modded clients.", - "\n - Gangster and Admirer can no longer get the Egoist role.", - "\n - Fixed bugs with Minus and Plus buttons in settings, ensuring they are always active.", - "\n - Intro Scene optimizations for smoother game start.", - "\n - Fixed numerous typos across roles and settings.", - "\n - Jester can no longer receive the Susceptible role.", - "\n - Added notify message about the game end when RpcEndGame is not received by specific clients.", - "\n - Fixed Baker not showing roles to non-host modded players", - "\n - Fixed mass kicking from lobbies against non-host modded players", - "\n【Translator Credits】", - "\n - Brazilian (By Dx7405, Pietro)", - "\n - Dutch (By apemv, madmazel_)", - "\n - French (By FuroYT, KevOut, Klaomi, Sansationnelle, Space Monkey)", - "\n - Italian (By alot, Baphojack, Mattix606)", - "\n - Japanese (By Sunnyboi)", - "\n - Latin American (By CreepPower)", - "\n - Russian (By TommyXL, Shoulder Devil, chill_ultimated, Nevermore59)", - "\n - Simplified Chinese (By CrewCyan, LezaiYa, NikoCat)", - "\n - Spanish (By Dawson, Sunnyboi, thewhiskas27, xxSShadow)", - "\n - Traditional Chinese (By FlyFlyTurtle, Hinharrrrr, netherdragontw, Pomelo_)", - "\n Check out all of our translators on our website\r\n", - "\n\n★ Welcome to Town of Host: Enhanced v2.1.0 ★" - ], - "Date": "2024-11-3T12:50:00Z" } ] } diff --git a/Resources/Announcements/modNews-nl_NL.json b/Resources/Announcements/modNews-nl_NL.json index 4137b688a..e5379abed 100644 --- a/Resources/Announcements/modNews-nl_NL.json +++ b/Resources/Announcements/modNews-nl_NL.json @@ -175,9 +175,6 @@ "\n - Masochist renamed to Punching Bag (By WaterPanda)", "\n - Bloodlust renamed to Bloodthirst (By WaterPanda)", "\n - Schizophrenic renamed to Paranoia (By WaterPanda)", - "\n - Changed the logic for disconnecting from the game if the API crashes (By TommyXL)", - "\n - Set 300 CD for Nemesis if they cannot use the kill button (By TommyXL)", - "\n - Changed warning message about Api Error Connection (By Drakos)", "\n\r【Bug Fixes】", "\n - Many roles will no longer be able to receive some add-ons that were incompatible (By TommyXL, ryuk, WaterPanda)", "\n - Fixed Bounty Hunter resetting incorrect targets (By TommyXL)", @@ -207,28 +204,6 @@ "\n - Fixed Modded client seeing the Medic shield icon when Medic is dead (By D1GQ)", "\n - Mini can not be duelled, marked, blooded, and sliced (By Lezaiya)", "\n - Fixed typos, inconsistencies, and mistakes in descriptions, names, etc. (By Moe, TommyXL, Drakos, WaterPanda, Sunnyboi, LezaiYa)", - "\n - Fixed bug when after guessing, Judge, etc. the meeting status was not checked (By TommyXL)", - "\n - Fixed bug when Pelican ended the game when eaten players returned (By TommyXL)", - "\n - Fixed Avenger when they try to kill Necromancer (By TommyXL)", - "\n - Fixed Bodyguard/Crusader when they killed Bodyguard/Crusader, Taskinator and Veteran (By TommyXL)", - "\n - Fixed «Quizmaster.None» (By TommyXL)", - "\n - Fixed missed string «*MayorHideVote» for Vindicator (By TommyXL)", - "\n - Fixed bug when Madmate assign Neutrals (Does not apply to Admirer - By TommyXL)", - "\n - Fixed bug when Camouflage did not disappear after Camouflager was erased (By TommyXL)", - "\n - Probably fixed the bug when Kamikaze killed players during exile (By TommyXL)", - "\n - Probably fixed bug when in-game result displayed randomized nicknames (By TommyXL)", - "\n - Fixed bug when Auto Start always stes ans saved 0 kill cooldown (By TommyXL)", - "\n - Other small fixes that occurred in certain cases (By TommyXL)", - "\n - Swift can no longer get Tricky and vice versa (By TommyXL)", - "\n - Remove unnecessary parenthesis for Lighter (By TommyXL)", - "\n - Fixed bug when Fortune Teller shows «INVALID:NotAssigned» (By Drakos)", - "\n - Fixed broken Auto Start", - "\n - Fixed bug (hopefully) when the host changed his nickname to his own when he was killed by Doppelganger (By TommyXL)", - "\n - Fixed bug when F1 shows role settings (By TommyXL)", - "\n - Fixed bug when Veteran kills Taskinator (By TommyXL)", - "\n - Fixed (hopefully) the last color question for Quizmaster (By TommyXL)", - "\n - Fixed bug when Killing Machine can call a meeting (By TommyXL)", - "\n - Fixed bug when Jailed message not shown (By TommyXL)", "\n【Known bugs】", "\n - 1. Servers may be unstable as the protocol requires fixing on Innersloth's side", "\n - 2. Doppelganger, Swift and Imitator are unstable, but work", @@ -248,122 +223,6 @@ "\n\n★ Welcome to Town of Host: Enhanced v2.0.0 ★" ], "Date": "2024-07-21T12:50:00Z" - }, - { - "Number": "100007", - "Title": "Town of Host: Enhanced v2.1.0", - "Subtitle": "Finally, we're here!", - "Short": "TOH: Enhanced v2.1.0", - "Body": [ - "【Base】", - "\n - Base on TOH: Enhanced v2.0.0", - "\n\r【New Roles/Addons】(5 roles, 6 Add-ons)", - "\n - Yin Yanger (Impostor Killing, idea & coded: Drakos)", - "\n - Possessor (Imposter Ghost Role, idea & coded: D1GQ)", - "\n - Troller (Neutral Chaos, idea: dx7405, coded: TommyXL)", - "\n - Ventguard (Crewmate Support, ported: EHR, coded by: TommyXL)", - "\n - Evader (Addon Helpful, idea: Lime, coded: TommyXL)", - "\n - Rebirth (Addon Helpful, idea & coded: Drakos)", - "\n - Sloth (Harmful Addon, idea & coded: Pyro)", - "\n - Eavesdropper (Addon Helpful, idea by: Crosspost Del Slay, coded: Moe)", - "\n - Spurt (Addon Helpful, idea by: .thediamondstar, coded: Drakos)", - "\n - Prohibited (Addon Harmful, idea by: Crosspost Del Slay, coded: TommyXL)", - "\n - New neutral Team (Faction): Neutral Apocalypse (idea & coded: Marg)", - "\n --- Min/max Neutral Apocalypse can be set", - "\n --- New role: Baker", - "\n --- Berserker and PlagueBearer now moved to Neutral Apocalypse", - "\n --- Soul Collector reworked", - "\n\r【New Settings/Features】", - "\n - Added vent disabling for vanilla (ported from MoreGamemodes by TommyXL & NikoCat)", - "\n --- When a player does not have access to vents, they will never be able to use it", - "\n - More fixes for AntiBlackOut (By TommyXL & Drakos)", - "\n --- Note: This will not completely fix black screen issues, but the more players there are in the game, the less chance of black screen occurrences", - "\n --- To do this, we use revives and base role changes during exile so that dead players will be alive for a couple of seconds but will become dead again", - "\n - Added support role basis changer mid-game (By TommyXL & Drakos)", - "\n --- CopyCat now supports role basis changes", - "\n --- Executioner and Lawyer also change role basis after their target dies", - "\n - TextBoxPatch (Ported: EHR, coded: TommyXL)", - "\n --- Allows you to write any characters into the chat", - "\n - improved Region Menu (coded: D1GQ)", - "\n - Added custom label ID for modded (Ported: EHR, coded: TommyXL)", - "\n - Jester: «Can't Move In Vents» (Setting, coded: TommyXL)", - "\n - Random spawn: Active On Round One (Setting, coded: TommyXL)", - "\n - Added warning message about enabling setting «No Game End»", - "\n --- Warns only the host when he presses the start button", - "\n - Disable Shapeshift menu for some Reject Shapeshift roles (By: Drakos)", - "\n --- For Pitfall, Bomber, Undertaker", - "\n --- It may be used for some more roles", - "\n - Return Ability Votes (By: Drakos)", - "\n --- For Cleanser, Eraser, Fortune teller, Keeper, Oracle, Godfather", - "\n --- First Vote will cancel (Vote Skip) or use the ability; second is regular vote", - "\n - Added «/vote» command (By: Drakos)", - "\n --- Can be disabled in the settings", - "\n - Death reason display improved (ported from EHR).", - "\n - Added role info in setting menu (By: Drakos)", - "\n - Added search bar in settings (By: Drakos)", - "\n - Addon Base (Port From EHR) (By: Drakos)", - "\n --- The settings are now sorted alphabetically", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Jester: Reveal Upon Eject (Setting, by: TheDiamondStar)", - "\n - Executioner: Reveal Target Upon Ejection (Setting, by: TheDiamondStar)", - "\n - Judge: Max trials per game (Setting, by: hinhinarrrrrr)", - "\n - Improved menu for role description in settings", - "\n - Setting: Apocalypse can see each other's Add-ons", - "\n - Settings: «Halloween Decorations» and «Birthday Decoration» (only for modded)", - "\n - Modded players now will see changes in TOHE settings", - "\n - Added custom image «imer» for Mercenary, Bounty Hunter, and Penguin: Thanks @that_one_missing_pixel (Pixel)", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Changed warning message about the API (By: Drakos)", - "\n\r【Bug Fixes/Changes】", - "\n - Phantom Desync: Phantom now plays the invisibility animation instead of teleporting to a random vent for desync roles.", - "\n - Fixed issues with Veteran killing Taskinator, Killing Machine calling meetings, and the Jailed message not showing during the game.", - "\n - Resolved issues with stuck FFA meetings and Fortune Teller showing roles during FFA.", - "\n - Fixed speed bug when Bandit steals the Statue.", - "\n - Resolved Haunt Menu showing «NotAssigned» in Hide & Seek mode.", - "\n - Corrected issues with Doomsayer not using Impostor Vision and various bugs with Psychic.", - "\n - Fixed Taskinator triggering Schrodinger's Cat ability.", - "\n - Corrected Innocent win conditions with Impostor when the setting is enabled.", - "\n - Fixed player spawn issues at the start and after meetings.", - "\n - Resolved full role and add-on display when a player is exiled.", - "\n - Fixed Blackmail not working for non-host modded players.", - "\n - Resolved issues where the Deceiver could kill Serial Killer and where the Deceiver could kill dead players.", - "\n - Corrected several bugs related to Stalker, Enigma, and Madmate Impostor Vision.", - "\n - Fixed issues with Medium messages showing after Medium is dead.", - "\n - Resolved bug where Hangman could kill Nice Mini.", - "\n - Corrected Huntsman minimum kill cooldown.", - "\n - Fixed Bloodmoon not working for modded clients and corrected missing strings for Blackmailer.", - "\n - Fixed issues where the Overseer would show Med Scanner after a meeting.", - "\n - Inhibitor and Saboteur now use sabotage sounds in the intro.", - "\n - Resolved issues where Aware did not work after an Overseer check and Merchant could assign converted add-ons.", - "\n - Fixed bugs with Hater being unable to kill, Crewpostor killing Solsticer, and Impostor Vision not working for Doppelganger.", - "\n - Resolved modded client issues with calling RpcSetName at the end of the game.", - "\n - Fixed win-condition conflicts between terrorists and workaholics.", - "\n - Corrected Necroview interaction with Admired and Madmate roles.", - "\n - Resolved bugs with Judge for modded clients.", - "\n - Gangster and Admirer can no longer get the Egoist role.", - "\n - Fixed bugs with Minus and Plus buttons in settings, ensuring they are always active.", - "\n - Intro Scene optimizations for smoother game start.", - "\n - Fixed numerous typos across roles and settings.", - "\n - Jester can no longer receive the Susceptible role.", - "\n - Added notify message about the game end when RpcEndGame is not received by specific clients.", - "\n - Fixed Baker not showing roles to non-host modded players", - "\n - Fixed mass kicking from lobbies against non-host modded players", - "\n【Translator Credits】", - "\n - Brazilian (By Dx7405, Pietro)", - "\n - Dutch (By apemv, madmazel_)", - "\n - French (By FuroYT, KevOut, Klaomi, Sansationnelle, Space Monkey)", - "\n - Italian (By alot, Baphojack, Mattix606)", - "\n - Japanese (By Sunnyboi)", - "\n - Latin American (By CreepPower)", - "\n - Russian (By TommyXL, Shoulder Devil, chill_ultimated, Nevermore59)", - "\n - Simplified Chinese (By CrewCyan, LezaiYa, NikoCat)", - "\n - Spanish (By Dawson, Sunnyboi, thewhiskas27, xxSShadow)", - "\n - Traditional Chinese (By FlyFlyTurtle, Hinharrrrr, netherdragontw, Pomelo_)", - "\n Check out all of our translators on our website\r\n", - "\n\n★ Welcome to Town of Host: Enhanced v2.1.0 ★" - ], - "Date": "2024-11-3T12:50:00Z" } ] } diff --git a/Resources/Announcements/modNews-pt_BR.json b/Resources/Announcements/modNews-pt_BR.json index bb4c5190a..81c75de01 100644 --- a/Resources/Announcements/modNews-pt_BR.json +++ b/Resources/Announcements/modNews-pt_BR.json @@ -175,195 +175,54 @@ "\n - Masochist renomeado para Punching Bag (Por: WaterPanda)", "\n - Bloodlust renomeado para Bloodthirst (Por: WaterPanda)", "\n - Schizophrenic renomeado para Paranoia (Por: WaterPanda)", - "\n - Changed the logic for disconnecting from the game if the API crashes (By TommyXL)", - "\n - Set 300 CD for Nemesis if they cannot use the kill button (By TommyXL)", - "\n - Changed warning message about Api Error Connection (By Drakos)", - "\n\r【Bug Fixes】", - "\n - Many roles will no longer be able to receive some add-ons that were incompatible (By TommyXL, ryuk, WaterPanda)", - "\n - Fixed Bounty Hunter resetting incorrect targets (By TommyXL)", - "\n - Fixed null error post-meeting for Vulture and Seeker and error after votes in Airship (By TommyXL)", - "\n - Fixed custom buttons brightness issues (By TommyXL)", - "\n - Fixed roles without vent ability getting stuck after trying to vent (By TommyXL)", - "\n - Fixed vent icon issues for roles based on Engineer (By TommyXL)", - "\n - Fixed black screens during role assign (By TommyXL)", - "\n - Fixed Scientist assign for desync role (By TommyXL)", - "\n - Fixed bug when 3 settings for Judge was not used (By TommyXL)", - "\n - Fixed buttons are active when the player was guessed (By TommyXL)", - "\n - Some fixes in Guesser UI (By TommyXL)", - "\n - Fixed Double Meeting Ending (By TommyXL)", - "\n - Fixed Guardian Angel Shield Animation sometimes didn't work correctly with Vanilla (By TommyXL)", - "\n - Some fix in random spawn in Airship for the host (By TommyXL)", - "\n - Fixed Necromancer leaving a dead body after the meeting (By TommyXL)", - "\n - Fixed Workaholic incorrect win state (By TommyXL)", - "\n - Fixed Mayor calling meetings even when out of use (By ryuk)", - "\n - Fixed EAC list not working when ban list is off (By ryuk)", - "\n - Fixed Kamikaze causing half-dead players (By ryuk)", - "\n - Fixed Messages not sent to vanilla players (By Drakos)", - "\n - Fixed Zombie Issues (By Drakos)", - "\n - Fixed Punching bag being judged (By Drakos)", - "\n - Fixed bug when kill cooldown not going when press F1/F2/F3/F4 (By NikoCat)", - "\n - Fixed Immediate autostart settings (By NikoCat)", - "\n - Fixed Bait self-reporting (By NikoCat)", - "\n - Fixed Modded client seeing the Medic shield icon when Medic is dead (By D1GQ)", - "\n - Mini can not be duelled, marked, blooded, and sliced (By Lezaiya)", - "\n - Fixed typos, inconsistencies, and mistakes in descriptions, names, etc. (By Moe, TommyXL, Drakos, WaterPanda, Sunnyboi, LezaiYa)", - "\n - Fixed bug when after guessing, Judge, etc. the meeting status was not checked (By TommyXL)", - "\n - Fixed bug when Pelican ended the game when eaten players returned (By TommyXL)", - "\n - Fixed Avenger when they try to kill Necromancer (By TommyXL)", - "\n - Fixed Bodyguard/Crusader when they killed Bodyguard/Crusader, Taskinator and Veteran (By TommyXL)", - "\n - Fixed «Quizmaster.None» (By TommyXL)", - "\n - Fixed missed string «*MayorHideVote» for Vindicator (By TommyXL)", - "\n - Fixed bug when Madmate assign Neutrals (Does not apply to Admirer - By TommyXL)", - "\n - Fixed bug when Camouflage did not disappear after Camouflager was erased (By TommyXL)", - "\n - Probably fixed the bug when Kamikaze killed players during exile (By TommyXL)", - "\n - Probably fixed bug when in-game result displayed randomized nicknames (By TommyXL)", - "\n - Fixed bug when Auto Start always stes ans saved 0 kill cooldown (By TommyXL)", - "\n - Other small fixes that occurred in certain cases (By TommyXL)", - "\n - Swift can no longer get Tricky and vice versa (By TommyXL)", - "\n - Remove unnecessary parenthesis for Lighter (By TommyXL)", - "\n - Fixed bug when Fortune Teller shows «INVALID:NotAssigned» (By Drakos)", - "\n - Fixed broken Auto Start", - "\n - Fixed bug (hopefully) when the host changed his nickname to his own when he was killed by Doppelganger (By TommyXL)", - "\n - Fixed bug when F1 shows role settings (By TommyXL)", - "\n - Fixed bug when Veteran kills Taskinator (By TommyXL)", - "\n - Fixed (hopefully) the last color question for Quizmaster (By TommyXL)", - "\n - Fixed bug when Killing Machine can call a meeting (By TommyXL)", - "\n - Fixed bug when Jailed message not shown (By TommyXL)", - "\n【Known bugs】", - "\n - 1. Servers may be unstable as the protocol requires fixing on Innersloth's side", - "\n - 2. Doppelganger, Swift and Imitator are unstable, but work", - "\n - 3. Modded clients have some problems, so it is recommended to have the mod only on Host", - "\n【Translator Credits】", - "\n - Brazilian (By Dx7405, Pietro)", - "\n - Dutch (By apemv, madmazel_)", - "\n - French (By FuroYT, KevOut, Klaomi, Sansationnelle, Space Monkey)", - "\n - Italian (By alot, Baphojack, Mattix606)", - "\n - Japanese (By Sunnyboi)", - "\n - Latin American (By CreepPower)", - "\n - Russian (By TommyXL, Shoulder Devil, chill_ultimated, Nevermore59)", - "\n - Simplified Chinese (By CrewCyan, LezaiYa, NikoCat)", - "\n - Spanish (By Dawson, Sunnyboi, thewhiskas27, xxSShadow)", - "\n - Traditional Chinese (By FlyFlyTurtle, Hinharrrrr, netherdragontw, Pomelo_)", - "\n Check out all of our translators on our website\r\n", - "\n\n★ Welcome to Town of Host: Enhanced v2.0.0 ★" + "\n\n【Correção de Bugs】", + "\n - Muitas funções não poderão mais receber alguns atributos que eram incompatíveis (Por: TommyXL, ryuk, WaterPanda)", + "\n - Corrigido o problema do Caçador de Recompensas resetando alvos incorretos (Por: TommyXL)", + "\n - Corrigido erro nulo pós-reunião para Canibal e Procurador e erro após votos no Airship (Por: TommyXL)", + "\n - Corrigidos problemas de brilho dos botões personalizados (Por: TommyXL)", + "\n - Corrigida as funções sem habilidade de ventar ficando presas após tentar ventar (Por: TommyXL)", + "\n - Corrigidos problemas com o ícone de duto para funções baseadas no Engenheiro (Por: TommyXL)", + "\n - Corrigida tela preta durante a atribuição de funções (Por: TommyXL)", + "\n - Corrigida atribuição do Cientista para funções desincronizadas (Por: TommyXL)", + "\n - Corrigido bug quando 3 configurações para o Juíz não eram usadas (Por: TommyXL)", + "\n - Corrigido botão ativo quando o jogador era adivinhado (Por: TommyXL)", + "\n - Algumas correções na interface de Adivinhar (Por: TommyXL)", + "\n - Corrigido término de reunião dupla (Por: TommyXL)", + "\n - Corrigida animação do escudo do Anjo Guardião que às vezes não funcionava corretamente com Vanilla (Por: TommyXL)", + "\n - Algumas correções no spawn aleatório no Airship para o anfitrião (Por: TommyXL)", + "\n - Corrigido Necromante deixando um corpo morto após a reunião (Por: TommyXL)", + "\n - Corrigido estado de vitória incorreto do Trabalhador (Por: TommyXL)", + "\n - Corrigido o prefeito podendo convocar reuniões mesmo quando sem usos (Por: ryuk)", + "\n - Corrigida lista EAC não funcionando quando a lista de banimento está desativada (Por: ryuk)", + "\n - Corrigido Kamikaze causando jogadores meio-mortos (Por: ryuk)", + "\n - Corrigidas mensagens não enviadas para jogadores vanilla (Por: Drakos)", + "\n - Corrigidos problemas com a Pestilência (Por: Drakos)", + "\n - Corrigido Masoquista sendo julgado (Por: Drakos)", + "\n - Corrigido bug quando o tempo de recarga para matar não avançava ao pressionar F1/F2/F3/F4 (Por: NikoCat)", + "\n - Corrigidas configurações de início automático imediato (Por: NikoCat)", + "\n - Corrigido Armador podendo se auto-reportar (Por: NikoCat)", + "\n - Corrigido cliente com mod vendo o ícone de escudo do Guardião quando o Guardião está morto (Por: D1GQ)", + "\n - Mini não pode ser desafiado para duelo, marcado, sangrado e cortado (Por: Lezaiya)", + "\n - Corrigidos erros de digitação, inconsistências e erros em descrições, nomes, etc. (Por: Moe, TommyXL, Drakos, WaterPanda, Sunnyboi, LezaiYa)", + "\n【Erros Conhecidos】", + "\n - 1. Os servidores podem estar instáveis, pois o protocolo requer correção do lado da Innersloth", + "\n - 2. Veloz e Sósia estão instáveis, mas funcionam", + "\n - 3. Clientes modificados apresentam alguns problemas, portanto, é recomendável ter o mod apenas no Anfitrião", + "\n【Créditos pela as Traduções】", + "\n - Português (Brasil) (por: Dx7405, Pietro)", + "\n - Holandês (Por: apemv, madmazel_)", + "\n - Francês (Por: FuroYT, KevOut, Klaomi, Sansationnelle, Space Monkey)", + "\n - Italiano (Por: alot, Baphojack, Mattix606)", + "\n - Japonês (Por: Sunnyboi)", + "\n - Latino-Americano (Por: CreepPower)", + "\n - Russo (Por: TommyXL, Shoulder Devil, chill_ultimated, Nevermore59)", + "\n - Chinês simplificado (Por: CrewCyan, LezaiYa, NikoCat223)", + "\n - Espanhol (Por: Dawson, Sunnyboi, thewhiskas27, xxSShadow)", + "\n - Chinês Tradicional (Por: FlyFlyTurtle, Hinharrrrr, netherdragontw, Pomelo_)", + "\n Confira todos os nossos tradutores em nosso site\n", + "\n\n★ Bem-vindo ao Town of Host: Enhanced v2.0.0 ★" ], "Date": "2024-07-21T12:50:00Z" - }, - { - "Number": "100007", - "Title": "Town of Host: Enhanced v2.1.0", - "Subtitle": "Finally, we're here!", - "Short": "TOH: Enhanced v2.1.0", - "Body": [ - "【Base】", - "\n - Base on TOH: Enhanced v2.0.0", - "\n\r【New Roles/Addons】(5 roles, 6 Add-ons)", - "\n - Yin Yanger (Impostor Killing, idea & coded: Drakos)", - "\n - Possessor (Imposter Ghost Role, idea & coded: D1GQ)", - "\n - Troller (Neutral Chaos, idea: dx7405, coded: TommyXL)", - "\n - Ventguard (Crewmate Support, ported: EHR, coded by: TommyXL)", - "\n - Evader (Addon Helpful, idea: Lime, coded: TommyXL)", - "\n - Rebirth (Addon Helpful, idea & coded: Drakos)", - "\n - Sloth (Harmful Addon, idea & coded: Pyro)", - "\n - Eavesdropper (Addon Helpful, idea by: Crosspost Del Slay, coded: Moe)", - "\n - Spurt (Addon Helpful, idea by: .thediamondstar, coded: Drakos)", - "\n - Prohibited (Addon Harmful, idea by: Crosspost Del Slay, coded: TommyXL)", - "\n - New neutral Team (Faction): Neutral Apocalypse (idea & coded: Marg)", - "\n --- Min/max Neutral Apocalypse can be set", - "\n --- New role: Baker", - "\n --- Berserker and PlagueBearer now moved to Neutral Apocalypse", - "\n --- Soul Collector reworked", - "\n\r【New Settings/Features】", - "\n - Added vent disabling for vanilla (ported from MoreGamemodes by TommyXL & NikoCat)", - "\n --- When a player does not have access to vents, they will never be able to use it", - "\n - More fixes for AntiBlackOut (By TommyXL & Drakos)", - "\n --- Note: This will not completely fix black screen issues, but the more players there are in the game, the less chance of black screen occurrences", - "\n --- To do this, we use revives and base role changes during exile so that dead players will be alive for a couple of seconds but will become dead again", - "\n - Added support role basis changer mid-game (By TommyXL & Drakos)", - "\n --- CopyCat now supports role basis changes", - "\n --- Executioner and Lawyer also change role basis after their target dies", - "\n - TextBoxPatch (Ported: EHR, coded: TommyXL)", - "\n --- Allows you to write any characters into the chat", - "\n - improved Region Menu (coded: D1GQ)", - "\n - Added custom label ID for modded (Ported: EHR, coded: TommyXL)", - "\n - Jester: «Can't Move In Vents» (Setting, coded: TommyXL)", - "\n - Random spawn: Active On Round One (Setting, coded: TommyXL)", - "\n - Added warning message about enabling setting «No Game End»", - "\n --- Warns only the host when he presses the start button", - "\n - Disable Shapeshift menu for some Reject Shapeshift roles (By: Drakos)", - "\n --- For Pitfall, Bomber, Undertaker", - "\n --- It may be used for some more roles", - "\n - Return Ability Votes (By: Drakos)", - "\n --- For Cleanser, Eraser, Fortune teller, Keeper, Oracle, Godfather", - "\n --- First Vote will cancel (Vote Skip) or use the ability; second is regular vote", - "\n - Added «/vote» command (By: Drakos)", - "\n --- Can be disabled in the settings", - "\n - Death reason display improved (ported from EHR).", - "\n - Added role info in setting menu (By: Drakos)", - "\n - Added search bar in settings (By: Drakos)", - "\n - Addon Base (Port From EHR) (By: Drakos)", - "\n --- The settings are now sorted alphabetically", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Jester: Reveal Upon Eject (Setting, by: TheDiamondStar)", - "\n - Executioner: Reveal Target Upon Ejection (Setting, by: TheDiamondStar)", - "\n - Judge: Max trials per game (Setting, by: hinhinarrrrrr)", - "\n - Improved menu for role description in settings", - "\n - Setting: Apocalypse can see each other's Add-ons", - "\n - Settings: «Halloween Decorations» and «Birthday Decoration» (only for modded)", - "\n - Modded players now will see changes in TOHE settings", - "\n - Added custom image «imer» for Mercenary, Bounty Hunter, and Penguin: Thanks @that_one_missing_pixel (Pixel)", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Changed warning message about the API (By: Drakos)", - "\n\r【Bug Fixes/Changes】", - "\n - Phantom Desync: Phantom now plays the invisibility animation instead of teleporting to a random vent for desync roles.", - "\n - Fixed issues with Veteran killing Taskinator, Killing Machine calling meetings, and the Jailed message not showing during the game.", - "\n - Resolved issues with stuck FFA meetings and Fortune Teller showing roles during FFA.", - "\n - Fixed speed bug when Bandit steals the Statue.", - "\n - Resolved Haunt Menu showing «NotAssigned» in Hide & Seek mode.", - "\n - Corrected issues with Doomsayer not using Impostor Vision and various bugs with Psychic.", - "\n - Fixed Taskinator triggering Schrodinger's Cat ability.", - "\n - Corrected Innocent win conditions with Impostor when the setting is enabled.", - "\n - Fixed player spawn issues at the start and after meetings.", - "\n - Resolved full role and add-on display when a player is exiled.", - "\n - Fixed Blackmail not working for non-host modded players.", - "\n - Resolved issues where the Deceiver could kill Serial Killer and where the Deceiver could kill dead players.", - "\n - Corrected several bugs related to Stalker, Enigma, and Madmate Impostor Vision.", - "\n - Fixed issues with Medium messages showing after Medium is dead.", - "\n - Resolved bug where Hangman could kill Nice Mini.", - "\n - Corrected Huntsman minimum kill cooldown.", - "\n - Fixed Bloodmoon not working for modded clients and corrected missing strings for Blackmailer.", - "\n - Fixed issues where the Overseer would show Med Scanner after a meeting.", - "\n - Inhibitor and Saboteur now use sabotage sounds in the intro.", - "\n - Resolved issues where Aware did not work after an Overseer check and Merchant could assign converted add-ons.", - "\n - Fixed bugs with Hater being unable to kill, Crewpostor killing Solsticer, and Impostor Vision not working for Doppelganger.", - "\n - Resolved modded client issues with calling RpcSetName at the end of the game.", - "\n - Fixed win-condition conflicts between terrorists and workaholics.", - "\n - Corrected Necroview interaction with Admired and Madmate roles.", - "\n - Resolved bugs with Judge for modded clients.", - "\n - Gangster and Admirer can no longer get the Egoist role.", - "\n - Fixed bugs with Minus and Plus buttons in settings, ensuring they are always active.", - "\n - Intro Scene optimizations for smoother game start.", - "\n - Fixed numerous typos across roles and settings.", - "\n - Jester can no longer receive the Susceptible role.", - "\n - Added notify message about the game end when RpcEndGame is not received by specific clients.", - "\n - Fixed Baker not showing roles to non-host modded players", - "\n - Fixed mass kicking from lobbies against non-host modded players", - "\n【Translator Credits】", - "\n - Brazilian (By Dx7405, Pietro)", - "\n - Dutch (By apemv, madmazel_)", - "\n - French (By FuroYT, KevOut, Klaomi, Sansationnelle, Space Monkey)", - "\n - Italian (By alot, Baphojack, Mattix606)", - "\n - Japanese (By Sunnyboi)", - "\n - Latin American (By CreepPower)", - "\n - Russian (By TommyXL, Shoulder Devil, chill_ultimated, Nevermore59)", - "\n - Simplified Chinese (By CrewCyan, LezaiYa, NikoCat)", - "\n - Spanish (By Dawson, Sunnyboi, thewhiskas27, xxSShadow)", - "\n - Traditional Chinese (By FlyFlyTurtle, Hinharrrrr, netherdragontw, Pomelo_)", - "\n Check out all of our translators on our website\r\n", - "\n\n★ Welcome to Town of Host: Enhanced v2.1.0 ★" - ], - "Date": "2024-11-3T12:50:00Z" } ] } diff --git a/Resources/Announcements/modNews-pt_PT.json b/Resources/Announcements/modNews-pt_PT.json index a88211c41..8207ac47c 100644 --- a/Resources/Announcements/modNews-pt_PT.json +++ b/Resources/Announcements/modNews-pt_PT.json @@ -175,9 +175,6 @@ "\n - Masochist renamed to Punching Bag (By WaterPanda)", "\n - Bloodlust renamed to Bloodthirst (By WaterPanda)", "\n - Schizophrenic renamed to Paranoia (By WaterPanda)", - "\n - Changed the logic for disconnecting from the game if the API crashes (By TommyXL)", - "\n - Set 300 CD for Nemesis if they cannot use the kill button (By TommyXL)", - "\n - Changed warning message about Api Error Connection (By Drakos)", "\n\r【Bug Fixes】", "\n - Many roles will no longer be able to receive some add-ons that were incompatible (By TommyXL, ryuk, WaterPanda)", "\n - Fixed Bounty Hunter resetting incorrect targets (By TommyXL)", @@ -207,28 +204,6 @@ "\n - Fixed Modded client seeing the Medic shield icon when Medic is dead (By D1GQ)", "\n - Mini can not be duelled, marked, blooded, and sliced (By Lezaiya)", "\n - Fixed typos, inconsistencies, and mistakes in descriptions, names, etc. (By Moe, TommyXL, Drakos, WaterPanda, Sunnyboi, LezaiYa)", - "\n - Fixed bug when after guessing, Judge, etc. the meeting status was not checked (By TommyXL)", - "\n - Fixed bug when Pelican ended the game when eaten players returned (By TommyXL)", - "\n - Fixed Avenger when they try to kill Necromancer (By TommyXL)", - "\n - Fixed Bodyguard/Crusader when they killed Bodyguard/Crusader, Taskinator and Veteran (By TommyXL)", - "\n - Fixed «Quizmaster.None» (By TommyXL)", - "\n - Fixed missed string «*MayorHideVote» for Vindicator (By TommyXL)", - "\n - Fixed bug when Madmate assign Neutrals (Does not apply to Admirer - By TommyXL)", - "\n - Fixed bug when Camouflage did not disappear after Camouflager was erased (By TommyXL)", - "\n - Probably fixed the bug when Kamikaze killed players during exile (By TommyXL)", - "\n - Probably fixed bug when in-game result displayed randomized nicknames (By TommyXL)", - "\n - Fixed bug when Auto Start always stes ans saved 0 kill cooldown (By TommyXL)", - "\n - Other small fixes that occurred in certain cases (By TommyXL)", - "\n - Swift can no longer get Tricky and vice versa (By TommyXL)", - "\n - Remove unnecessary parenthesis for Lighter (By TommyXL)", - "\n - Fixed bug when Fortune Teller shows «INVALID:NotAssigned» (By Drakos)", - "\n - Fixed broken Auto Start", - "\n - Fixed bug (hopefully) when the host changed his nickname to his own when he was killed by Doppelganger (By TommyXL)", - "\n - Fixed bug when F1 shows role settings (By TommyXL)", - "\n - Fixed bug when Veteran kills Taskinator (By TommyXL)", - "\n - Fixed (hopefully) the last color question for Quizmaster (By TommyXL)", - "\n - Fixed bug when Killing Machine can call a meeting (By TommyXL)", - "\n - Fixed bug when Jailed message not shown (By TommyXL)", "\n【Known bugs】", "\n - 1. Servers may be unstable as the protocol requires fixing on Innersloth's side", "\n - 2. Doppelganger, Swift and Imitator are unstable, but work", @@ -248,122 +223,6 @@ "\n\n★ Welcome to Town of Host: Enhanced v2.0.0 ★" ], "Date": "2024-07-21T12:50:00Z" - }, - { - "Number": "100007", - "Title": "Town of Host: Enhanced v2.1.0", - "Subtitle": "Finally, we're here!", - "Short": "TOH: Enhanced v2.1.0", - "Body": [ - "【Base】", - "\n - Base on TOH: Enhanced v2.0.0", - "\n\r【New Roles/Addons】(5 roles, 6 Add-ons)", - "\n - Yin Yanger (Impostor Killing, idea & coded: Drakos)", - "\n - Possessor (Imposter Ghost Role, idea & coded: D1GQ)", - "\n - Troller (Neutral Chaos, idea: dx7405, coded: TommyXL)", - "\n - Ventguard (Crewmate Support, ported: EHR, coded by: TommyXL)", - "\n - Evader (Addon Helpful, idea: Lime, coded: TommyXL)", - "\n - Rebirth (Addon Helpful, idea & coded: Drakos)", - "\n - Sloth (Harmful Addon, idea & coded: Pyro)", - "\n - Eavesdropper (Addon Helpful, idea by: Crosspost Del Slay, coded: Moe)", - "\n - Spurt (Addon Helpful, idea by: .thediamondstar, coded: Drakos)", - "\n - Prohibited (Addon Harmful, idea by: Crosspost Del Slay, coded: TommyXL)", - "\n - New neutral Team (Faction): Neutral Apocalypse (idea & coded: Marg)", - "\n --- Min/max Neutral Apocalypse can be set", - "\n --- New role: Baker", - "\n --- Berserker and PlagueBearer now moved to Neutral Apocalypse", - "\n --- Soul Collector reworked", - "\n\r【New Settings/Features】", - "\n - Added vent disabling for vanilla (ported from MoreGamemodes by TommyXL & NikoCat)", - "\n --- When a player does not have access to vents, they will never be able to use it", - "\n - More fixes for AntiBlackOut (By TommyXL & Drakos)", - "\n --- Note: This will not completely fix black screen issues, but the more players there are in the game, the less chance of black screen occurrences", - "\n --- To do this, we use revives and base role changes during exile so that dead players will be alive for a couple of seconds but will become dead again", - "\n - Added support role basis changer mid-game (By TommyXL & Drakos)", - "\n --- CopyCat now supports role basis changes", - "\n --- Executioner and Lawyer also change role basis after their target dies", - "\n - TextBoxPatch (Ported: EHR, coded: TommyXL)", - "\n --- Allows you to write any characters into the chat", - "\n - improved Region Menu (coded: D1GQ)", - "\n - Added custom label ID for modded (Ported: EHR, coded: TommyXL)", - "\n - Jester: «Can't Move In Vents» (Setting, coded: TommyXL)", - "\n - Random spawn: Active On Round One (Setting, coded: TommyXL)", - "\n - Added warning message about enabling setting «No Game End»", - "\n --- Warns only the host when he presses the start button", - "\n - Disable Shapeshift menu for some Reject Shapeshift roles (By: Drakos)", - "\n --- For Pitfall, Bomber, Undertaker", - "\n --- It may be used for some more roles", - "\n - Return Ability Votes (By: Drakos)", - "\n --- For Cleanser, Eraser, Fortune teller, Keeper, Oracle, Godfather", - "\n --- First Vote will cancel (Vote Skip) or use the ability; second is regular vote", - "\n - Added «/vote» command (By: Drakos)", - "\n --- Can be disabled in the settings", - "\n - Death reason display improved (ported from EHR).", - "\n - Added role info in setting menu (By: Drakos)", - "\n - Added search bar in settings (By: Drakos)", - "\n - Addon Base (Port From EHR) (By: Drakos)", - "\n --- The settings are now sorted alphabetically", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Jester: Reveal Upon Eject (Setting, by: TheDiamondStar)", - "\n - Executioner: Reveal Target Upon Ejection (Setting, by: TheDiamondStar)", - "\n - Judge: Max trials per game (Setting, by: hinhinarrrrrr)", - "\n - Improved menu for role description in settings", - "\n - Setting: Apocalypse can see each other's Add-ons", - "\n - Settings: «Halloween Decorations» and «Birthday Decoration» (only for modded)", - "\n - Modded players now will see changes in TOHE settings", - "\n - Added custom image «imer» for Mercenary, Bounty Hunter, and Penguin: Thanks @that_one_missing_pixel (Pixel)", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Changed warning message about the API (By: Drakos)", - "\n\r【Bug Fixes/Changes】", - "\n - Phantom Desync: Phantom now plays the invisibility animation instead of teleporting to a random vent for desync roles.", - "\n - Fixed issues with Veteran killing Taskinator, Killing Machine calling meetings, and the Jailed message not showing during the game.", - "\n - Resolved issues with stuck FFA meetings and Fortune Teller showing roles during FFA.", - "\n - Fixed speed bug when Bandit steals the Statue.", - "\n - Resolved Haunt Menu showing «NotAssigned» in Hide & Seek mode.", - "\n - Corrected issues with Doomsayer not using Impostor Vision and various bugs with Psychic.", - "\n - Fixed Taskinator triggering Schrodinger's Cat ability.", - "\n - Corrected Innocent win conditions with Impostor when the setting is enabled.", - "\n - Fixed player spawn issues at the start and after meetings.", - "\n - Resolved full role and add-on display when a player is exiled.", - "\n - Fixed Blackmail not working for non-host modded players.", - "\n - Resolved issues where the Deceiver could kill Serial Killer and where the Deceiver could kill dead players.", - "\n - Corrected several bugs related to Stalker, Enigma, and Madmate Impostor Vision.", - "\n - Fixed issues with Medium messages showing after Medium is dead.", - "\n - Resolved bug where Hangman could kill Nice Mini.", - "\n - Corrected Huntsman minimum kill cooldown.", - "\n - Fixed Bloodmoon not working for modded clients and corrected missing strings for Blackmailer.", - "\n - Fixed issues where the Overseer would show Med Scanner after a meeting.", - "\n - Inhibitor and Saboteur now use sabotage sounds in the intro.", - "\n - Resolved issues where Aware did not work after an Overseer check and Merchant could assign converted add-ons.", - "\n - Fixed bugs with Hater being unable to kill, Crewpostor killing Solsticer, and Impostor Vision not working for Doppelganger.", - "\n - Resolved modded client issues with calling RpcSetName at the end of the game.", - "\n - Fixed win-condition conflicts between terrorists and workaholics.", - "\n - Corrected Necroview interaction with Admired and Madmate roles.", - "\n - Resolved bugs with Judge for modded clients.", - "\n - Gangster and Admirer can no longer get the Egoist role.", - "\n - Fixed bugs with Minus and Plus buttons in settings, ensuring they are always active.", - "\n - Intro Scene optimizations for smoother game start.", - "\n - Fixed numerous typos across roles and settings.", - "\n - Jester can no longer receive the Susceptible role.", - "\n - Added notify message about the game end when RpcEndGame is not received by specific clients.", - "\n - Fixed Baker not showing roles to non-host modded players", - "\n - Fixed mass kicking from lobbies against non-host modded players", - "\n【Translator Credits】", - "\n - Brazilian (By Dx7405, Pietro)", - "\n - Dutch (By apemv, madmazel_)", - "\n - French (By FuroYT, KevOut, Klaomi, Sansationnelle, Space Monkey)", - "\n - Italian (By alot, Baphojack, Mattix606)", - "\n - Japanese (By Sunnyboi)", - "\n - Latin American (By CreepPower)", - "\n - Russian (By TommyXL, Shoulder Devil, chill_ultimated, Nevermore59)", - "\n - Simplified Chinese (By CrewCyan, LezaiYa, NikoCat)", - "\n - Spanish (By Dawson, Sunnyboi, thewhiskas27, xxSShadow)", - "\n - Traditional Chinese (By FlyFlyTurtle, Hinharrrrr, netherdragontw, Pomelo_)", - "\n Check out all of our translators on our website\r\n", - "\n\n★ Welcome to Town of Host: Enhanced v2.1.0 ★" - ], - "Date": "2024-11-3T12:50:00Z" } ] } diff --git a/Resources/Announcements/modNews-ru_RU.json b/Resources/Announcements/modNews-ru_RU.json index 78baee126..1192f32cc 100644 --- a/Resources/Announcements/modNews-ru_RU.json +++ b/Resources/Announcements/modNews-ru_RU.json @@ -175,9 +175,6 @@ "\n - Masochist renamed to Punching Bag (By WaterPanda)", "\n - Bloodlust renamed to Bloodthirst (By WaterPanda)", "\n - Schizophrenic renamed to Paranoia (By WaterPanda)", - "\n - Changed the logic for disconnecting from the game if the API crashes (By TommyXL)", - "\n - Set 300 CD for Nemesis if they cannot use the kill button (By TommyXL)", - "\n - Changed warning message about Api Error Connection (By Drakos)", "\n\r【Bug Fixes】", "\n - Many roles will no longer be able to receive some add-ons that were incompatible (By TommyXL, ryuk, WaterPanda)", "\n - Fixed Bounty Hunter resetting incorrect targets (By TommyXL)", @@ -206,31 +203,9 @@ "\n - Fixed Bait self-reporting (By NikoCat)", "\n - Fixed Modded client seeing the Medic shield icon when Medic is dead (By D1GQ)", "\n - Mini can not be duelled, marked, blooded, and sliced (By Lezaiya)", - "\n - Fixed typos, inconsistencies, and mistakes in descriptions, names, etc. (By Moe, TommyXL, Drakos, WaterPanda, Sunnyboi, LezaiYa)", - "\n - Fixed bug when after guessing, Judge, etc. the meeting status was not checked (By TommyXL)", - "\n - Fixed bug when Pelican ended the game when eaten players returned (By TommyXL)", - "\n - Fixed Avenger when they try to kill Necromancer (By TommyXL)", - "\n - Fixed Bodyguard/Crusader when they killed Bodyguard/Crusader, Taskinator and Veteran (By TommyXL)", - "\n - Fixed «Quizmaster.None» (By TommyXL)", - "\n - Fixed missed string «*MayorHideVote» for Vindicator (By TommyXL)", - "\n - Fixed bug when Madmate assign Neutrals (Does not apply to Admirer - By TommyXL)", - "\n - Fixed bug when Camouflage did not disappear after Camouflager was erased (By TommyXL)", - "\n - Probably fixed the bug when Kamikaze killed players during exile (By TommyXL)", - "\n - Probably fixed bug when in-game result displayed randomized nicknames (By TommyXL)", - "\n - Fixed bug when Auto Start always stes ans saved 0 kill cooldown (By TommyXL)", - "\n - Other small fixes that occurred in certain cases (By TommyXL)", - "\n - Swift can no longer get Tricky and vice versa (By TommyXL)", - "\n - Remove unnecessary parenthesis for Lighter (By TommyXL)", - "\n - Fixed bug when Fortune Teller shows «INVALID:NotAssigned» (By Drakos)", - "\n - Fixed broken Auto Start", - "\n - Fixed bug (hopefully) when the host changed his nickname to his own when he was killed by Doppelganger (By TommyXL)", - "\n - Fixed bug when F1 shows role settings (By TommyXL)", - "\n - Fixed bug when Veteran kills Taskinator (By TommyXL)", - "\n - Fixed (hopefully) the last color question for Quizmaster (By TommyXL)", - "\n - Fixed bug when Killing Machine can call a meeting (By TommyXL)", - "\n - Fixed bug when Jailed message not shown (By TommyXL)", - "\n【Known bugs】", - "\n - 1. Servers may be unstable as the protocol requires fixing on Innersloth's side", + "\n - Исправлены опечатки, несоответствия и ошибки в описаниях, названиях и т.д. (От Moe, TommyXL, Drakos, WaterPanda, Sunnyboi, LezaiYa)", + "\n【Известные ошибки】", + "\n - 1. Серверы могут работать нестабильно, поскольку протокол требует исправления на стороне Innersloth", "\n - 2. Doppelganger, Swift and Imitator are unstable, but work", "\n - 3. Modded clients have some problems, so it is recommended to have the mod only on Host", "\n【Translator Credits】", @@ -248,122 +223,6 @@ "\n\n★ Welcome to Town of Host: Enhanced v2.0.0 ★" ], "Date": "2024-07-21T12:50:00Z" - }, - { - "Number": "100007", - "Title": "Town of Host: Enhanced v2.1.0", - "Subtitle": "Finally, we're here!", - "Short": "TOH: Enhanced v2.1.0", - "Body": [ - "【Base】", - "\n - Base on TOH: Enhanced v2.0.0", - "\n\r【New Roles/Addons】(5 roles, 6 Add-ons)", - "\n - Yin Yanger (Impostor Killing, idea & coded: Drakos)", - "\n - Possessor (Imposter Ghost Role, idea & coded: D1GQ)", - "\n - Troller (Neutral Chaos, idea: dx7405, coded: TommyXL)", - "\n - Ventguard (Crewmate Support, ported: EHR, coded by: TommyXL)", - "\n - Evader (Addon Helpful, idea: Lime, coded: TommyXL)", - "\n - Rebirth (Addon Helpful, idea & coded: Drakos)", - "\n - Sloth (Harmful Addon, idea & coded: Pyro)", - "\n - Eavesdropper (Addon Helpful, idea by: Crosspost Del Slay, coded: Moe)", - "\n - Spurt (Addon Helpful, idea by: .thediamondstar, coded: Drakos)", - "\n - Prohibited (Addon Harmful, idea by: Crosspost Del Slay, coded: TommyXL)", - "\n - New neutral Team (Faction): Neutral Apocalypse (idea & coded: Marg)", - "\n --- Min/max Neutral Apocalypse can be set", - "\n --- New role: Baker", - "\n --- Berserker and PlagueBearer now moved to Neutral Apocalypse", - "\n --- Soul Collector reworked", - "\n\r【New Settings/Features】", - "\n - Added vent disabling for vanilla (ported from MoreGamemodes by TommyXL & NikoCat)", - "\n --- When a player does not have access to vents, they will never be able to use it", - "\n - More fixes for AntiBlackOut (By TommyXL & Drakos)", - "\n --- Note: This will not completely fix black screen issues, but the more players there are in the game, the less chance of black screen occurrences", - "\n --- To do this, we use revives and base role changes during exile so that dead players will be alive for a couple of seconds but will become dead again", - "\n - Added support role basis changer mid-game (By TommyXL & Drakos)", - "\n --- CopyCat now supports role basis changes", - "\n --- Executioner and Lawyer also change role basis after their target dies", - "\n - TextBoxPatch (Ported: EHR, coded: TommyXL)", - "\n --- Allows you to write any characters into the chat", - "\n - improved Region Menu (coded: D1GQ)", - "\n - Added custom label ID for modded (Ported: EHR, coded: TommyXL)", - "\n - Jester: «Can't Move In Vents» (Setting, coded: TommyXL)", - "\n - Random spawn: Active On Round One (Setting, coded: TommyXL)", - "\n - Added warning message about enabling setting «No Game End»", - "\n --- Warns only the host when he presses the start button", - "\n - Disable Shapeshift menu for some Reject Shapeshift roles (By: Drakos)", - "\n --- For Pitfall, Bomber, Undertaker", - "\n --- It may be used for some more roles", - "\n - Return Ability Votes (By: Drakos)", - "\n --- For Cleanser, Eraser, Fortune teller, Keeper, Oracle, Godfather", - "\n --- First Vote will cancel (Vote Skip) or use the ability; second is regular vote", - "\n - Added «/vote» command (By: Drakos)", - "\n --- Can be disabled in the settings", - "\n - Death reason display improved (ported from EHR).", - "\n - Added role info in setting menu (By: Drakos)", - "\n - Added search bar in settings (By: Drakos)", - "\n - Addon Base (Port From EHR) (By: Drakos)", - "\n --- The settings are now sorted alphabetically", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Jester: Reveal Upon Eject (Setting, by: TheDiamondStar)", - "\n - Executioner: Reveal Target Upon Ejection (Setting, by: TheDiamondStar)", - "\n - Judge: Max trials per game (Setting, by: hinhinarrrrrr)", - "\n - Improved menu for role description in settings", - "\n - Setting: Apocalypse can see each other's Add-ons", - "\n - Settings: «Halloween Decorations» and «Birthday Decoration» (only for modded)", - "\n - Modded players now will see changes in TOHE settings", - "\n - Added custom image «imer» for Mercenary, Bounty Hunter, and Penguin: Thanks @that_one_missing_pixel (Pixel)", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Changed warning message about the API (By: Drakos)", - "\n\r【Bug Fixes/Changes】", - "\n - Phantom Desync: Phantom now plays the invisibility animation instead of teleporting to a random vent for desync roles.", - "\n - Fixed issues with Veteran killing Taskinator, Killing Machine calling meetings, and the Jailed message not showing during the game.", - "\n - Resolved issues with stuck FFA meetings and Fortune Teller showing roles during FFA.", - "\n - Fixed speed bug when Bandit steals the Statue.", - "\n - Resolved Haunt Menu showing «NotAssigned» in Hide & Seek mode.", - "\n - Corrected issues with Doomsayer not using Impostor Vision and various bugs with Psychic.", - "\n - Fixed Taskinator triggering Schrodinger's Cat ability.", - "\n - Corrected Innocent win conditions with Impostor when the setting is enabled.", - "\n - Fixed player spawn issues at the start and after meetings.", - "\n - Resolved full role and add-on display when a player is exiled.", - "\n - Fixed Blackmail not working for non-host modded players.", - "\n - Resolved issues where the Deceiver could kill Serial Killer and where the Deceiver could kill dead players.", - "\n - Corrected several bugs related to Stalker, Enigma, and Madmate Impostor Vision.", - "\n - Fixed issues with Medium messages showing after Medium is dead.", - "\n - Resolved bug where Hangman could kill Nice Mini.", - "\n - Corrected Huntsman minimum kill cooldown.", - "\n - Fixed Bloodmoon not working for modded clients and corrected missing strings for Blackmailer.", - "\n - Fixed issues where the Overseer would show Med Scanner after a meeting.", - "\n - Inhibitor and Saboteur now use sabotage sounds in the intro.", - "\n - Resolved issues where Aware did not work after an Overseer check and Merchant could assign converted add-ons.", - "\n - Fixed bugs with Hater being unable to kill, Crewpostor killing Solsticer, and Impostor Vision not working for Doppelganger.", - "\n - Resolved modded client issues with calling RpcSetName at the end of the game.", - "\n - Fixed win-condition conflicts between terrorists and workaholics.", - "\n - Corrected Necroview interaction with Admired and Madmate roles.", - "\n - Resolved bugs with Judge for modded clients.", - "\n - Gangster and Admirer can no longer get the Egoist role.", - "\n - Fixed bugs with Minus and Plus buttons in settings, ensuring they are always active.", - "\n - Intro Scene optimizations for smoother game start.", - "\n - Fixed numerous typos across roles and settings.", - "\n - Jester can no longer receive the Susceptible role.", - "\n - Added notify message about the game end when RpcEndGame is not received by specific clients.", - "\n - Fixed Baker not showing roles to non-host modded players", - "\n - Fixed mass kicking from lobbies against non-host modded players", - "\n【Translator Credits】", - "\n - Brazilian (By Dx7405, Pietro)", - "\n - Dutch (By apemv, madmazel_)", - "\n - French (By FuroYT, KevOut, Klaomi, Sansationnelle, Space Monkey)", - "\n - Italian (By alot, Baphojack, Mattix606)", - "\n - Japanese (By Sunnyboi)", - "\n - Latin American (By CreepPower)", - "\n - Russian (By TommyXL, Shoulder Devil, chill_ultimated, Nevermore59)", - "\n - Simplified Chinese (By CrewCyan, LezaiYa, NikoCat)", - "\n - Spanish (By Dawson, Sunnyboi, thewhiskas27, xxSShadow)", - "\n - Traditional Chinese (By FlyFlyTurtle, Hinharrrrr, netherdragontw, Pomelo_)", - "\n Check out all of our translators on our website\r\n", - "\n\n★ Welcome to Town of Host: Enhanced v2.1.0 ★" - ], - "Date": "2024-11-3T12:50:00Z" } ] } diff --git a/Resources/Announcements/modNews-zh_CN.json b/Resources/Announcements/modNews-zh_CN.json index ba13f0927..12fa39463 100644 --- a/Resources/Announcements/modNews-zh_CN.json +++ b/Resources/Announcements/modNews-zh_CN.json @@ -175,10 +175,7 @@ "\n - 受虐狂重命名为 Punching Bag «仅限英文» (By: WaterPanda)", "\n - 嗜血者重命名为 Bloodthirst «仅限英文» (By: WaterPanda)", "\n - 双重人格重命名为 Paranoia «仅限英文» (By: WaterPanda)", - "\n - 更改了API崩溃时断开与游戏连接的逻辑 (By TommyXL)", - "\n - 如果黑手党无法使用击杀按钮,则设置为300CD (By TommyXL)", - "\n -更改了关于API连接错误的信息(By Drakos)", - "\n\n【Bug修复】", + "\n\r【Bug修复】(这里只列出了1.6.0中的Bug)", "\n - 许多职业将不再能够获得一些不兼容的附加职业 (By: TommyXL, ryuk, WaterPanda)", "\n - 修复了赏金猎人重置错误目标的Bug (By: TommyXL)", "\n - 修复了会议后秃鹫和探索者的空Bug ,以及在高空飞艇投票后的Bug (By: TommyXL)", @@ -207,32 +204,10 @@ "\n - 修复了模组客户端在医生死亡时看到医生护盾图标的Bug (By: D1GQ)", "\n - 迷你船员不能被决斗、标记、流血和切片 (By: Lezaiya)", "\n - 修复了描述、名称等中的拼写错误、不一致性 (By: Moe, TommyXL, Drakos, WaterPanda, Sunnyboi, LezaiYa)", - "\n -修复了在猜测,正义法官等后未检查会议状态的错误(By TommyXL)", - "\n -修复了被鹈鹕吃掉的玩家返回时结束游戏的错误(By TommyXL)", - "\n -修复了复仇者试图击杀亡灵巫师时的问题(By TommtXL)", - "\n - Fixed Bodyguard/Crusader when they killed Bodyguard/Crusader, Taskinator and Veteran (By TommyXL)", - "\n - Fixed «Quizmaster.None» (By TommyXL)", - "\n - Fixed missed string «*MayorHideVote» for Vindicator (By TommyXL)", - "\n - Fixed bug when Madmate assign Neutrals (Does not apply to Admirer - By TommyXL)", - "\n - Fixed bug when Camouflage did not disappear after Camouflager was erased (By TommyXL)", - "\n - Probably fixed the bug when Kamikaze killed players during exile (By TommyXL)", - "\n - Probably fixed bug when in-game result displayed randomized nicknames (By TommyXL)", - "\n - Fixed bug when Auto Start always stes ans saved 0 kill cooldown (By TommyXL)", - "\n - Other small fixes that occurred in certain cases (By TommyXL)", - "\n - Swift can no longer get Tricky and vice versa (By TommyXL)", - "\n - Remove unnecessary parenthesis for Lighter (By TommyXL)", - "\n - Fixed bug when Fortune Teller shows «INVALID:NotAssigned» (By Drakos)", - "\n - 修复自动开始不起作用的问题", - "\n - Fixed bug (hopefully) when the host changed his nickname to his own when he was killed by Doppelganger (By TommyXL)", - "\n - Fixed bug when F1 shows role settings (By TommyXL)", - "\n - Fixed bug when Veteran kills Taskinator (By TommyXL)", - "\n - Fixed (hopefully) the last color question for Quizmaster (By TommyXL)", - "\n - Fixed bug when Killing Machine can call a meeting (By TommyXL)", - "\n - Fixed bug when Jailed message not shown (By TommyXL)", - "\n【Known bugs】", - "\n - 1. Servers may be unstable as the protocol requires fixing on Innersloth's side", - "\n - 2. Doppelganger, Swift and Imitator are unstable, but work", - "\n - 3. Modded clients have some problems, so it is recommended to have the mod only on Host", + "\n【已知Bug】", + "\n - 1. 服务器可能不稳定,因为协议需要在 Innersloth 的一侧进行修复", + "\n -2.替身者,迅捷和效仿者不稳定,但可以使用", + "\n - 3. 模组客户端有一些问题,所以建议只在房主上使用该模组 (并不清楚这个bug哪来的,Niko觉得挺稳定的)", "\n【翻译鸣谢】", "\n - 巴西语 (By: Dx7405, Pietro)", "\n - 荷兰语 (By: apemv, madmazel_)", @@ -248,122 +223,6 @@ "\n\n★ 欢迎来到 Town of Host: Enhanced v2.0.0 ★" ], "Date": "2024-07-21T12:50:00Z" - }, - { - "Number": "100007", - "Title": "Town of Host: Enhanced v2.1.0", - "Subtitle": "Finally, we're here!", - "Short": "TOH: Enhanced v2.1.0", - "Body": [ - "【Base】", - "\n - Base on TOH: Enhanced v2.0.0", - "\n\r【New Roles/Addons】(5 roles, 6 Add-ons)", - "\n - Yin Yanger (Impostor Killing, idea & coded: Drakos)", - "\n - Possessor (Imposter Ghost Role, idea & coded: D1GQ)", - "\n - Troller (Neutral Chaos, idea: dx7405, coded: TommyXL)", - "\n - Ventguard (Crewmate Support, ported: EHR, coded by: TommyXL)", - "\n - Evader (Addon Helpful, idea: Lime, coded: TommyXL)", - "\n - Rebirth (Addon Helpful, idea & coded: Drakos)", - "\n - Sloth (Harmful Addon, idea & coded: Pyro)", - "\n - Eavesdropper (Addon Helpful, idea by: Crosspost Del Slay, coded: Moe)", - "\n - Spurt (Addon Helpful, idea by: .thediamondstar, coded: Drakos)", - "\n - Prohibited (Addon Harmful, idea by: Crosspost Del Slay, coded: TommyXL)", - "\n - New neutral Team (Faction): Neutral Apocalypse (idea & coded: Marg)", - "\n --- Min/max Neutral Apocalypse can be set", - "\n --- New role: Baker", - "\n --- Berserker and PlagueBearer now moved to Neutral Apocalypse", - "\n --- Soul Collector reworked", - "\n\r【New Settings/Features】", - "\n - Added vent disabling for vanilla (ported from MoreGamemodes by TommyXL & NikoCat)", - "\n --- When a player does not have access to vents, they will never be able to use it", - "\n - More fixes for AntiBlackOut (By TommyXL & Drakos)", - "\n --- Note: This will not completely fix black screen issues, but the more players there are in the game, the less chance of black screen occurrences", - "\n --- To do this, we use revives and base role changes during exile so that dead players will be alive for a couple of seconds but will become dead again", - "\n - Added support role basis changer mid-game (By TommyXL & Drakos)", - "\n --- CopyCat now supports role basis changes", - "\n --- Executioner and Lawyer also change role basis after their target dies", - "\n - TextBoxPatch (Ported: EHR, coded: TommyXL)", - "\n --- Allows you to write any characters into the chat", - "\n - improved Region Menu (coded: D1GQ)", - "\n - Added custom label ID for modded (Ported: EHR, coded: TommyXL)", - "\n - Jester: «Can't Move In Vents» (Setting, coded: TommyXL)", - "\n - Random spawn: Active On Round One (Setting, coded: TommyXL)", - "\n - Added warning message about enabling setting «No Game End»", - "\n --- Warns only the host when he presses the start button", - "\n - Disable Shapeshift menu for some Reject Shapeshift roles (By: Drakos)", - "\n --- For Pitfall, Bomber, Undertaker", - "\n --- It may be used for some more roles", - "\n - Return Ability Votes (By: Drakos)", - "\n --- For Cleanser, Eraser, Fortune teller, Keeper, Oracle, Godfather", - "\n --- First Vote will cancel (Vote Skip) or use the ability; second is regular vote", - "\n - Added «/vote» command (By: Drakos)", - "\n --- Can be disabled in the settings", - "\n - Death reason display improved (ported from EHR).", - "\n - Added role info in setting menu (By: Drakos)", - "\n - Added search bar in settings (By: Drakos)", - "\n - Addon Base (Port From EHR) (By: Drakos)", - "\n --- The settings are now sorted alphabetically", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Jester: Reveal Upon Eject (Setting, by: TheDiamondStar)", - "\n - Executioner: Reveal Target Upon Ejection (Setting, by: TheDiamondStar)", - "\n - Judge: Max trials per game (Setting, by: hinhinarrrrrr)", - "\n - Improved menu for role description in settings", - "\n - Setting: Apocalypse can see each other's Add-ons", - "\n - Settings: «Halloween Decorations» and «Birthday Decoration» (only for modded)", - "\n - Modded players now will see changes in TOHE settings", - "\n - Added custom image «imer» for Mercenary, Bounty Hunter, and Penguin: Thanks @that_one_missing_pixel (Pixel)", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Changed warning message about the API (By: Drakos)", - "\n\r【Bug Fixes/Changes】", - "\n - Phantom Desync: Phantom now plays the invisibility animation instead of teleporting to a random vent for desync roles.", - "\n - Fixed issues with Veteran killing Taskinator, Killing Machine calling meetings, and the Jailed message not showing during the game.", - "\n - Resolved issues with stuck FFA meetings and Fortune Teller showing roles during FFA.", - "\n - Fixed speed bug when Bandit steals the Statue.", - "\n - Resolved Haunt Menu showing «NotAssigned» in Hide & Seek mode.", - "\n - Corrected issues with Doomsayer not using Impostor Vision and various bugs with Psychic.", - "\n - Fixed Taskinator triggering Schrodinger's Cat ability.", - "\n - Corrected Innocent win conditions with Impostor when the setting is enabled.", - "\n - Fixed player spawn issues at the start and after meetings.", - "\n - Resolved full role and add-on display when a player is exiled.", - "\n - Fixed Blackmail not working for non-host modded players.", - "\n - Resolved issues where the Deceiver could kill Serial Killer and where the Deceiver could kill dead players.", - "\n - Corrected several bugs related to Stalker, Enigma, and Madmate Impostor Vision.", - "\n - Fixed issues with Medium messages showing after Medium is dead.", - "\n - Resolved bug where Hangman could kill Nice Mini.", - "\n - Corrected Huntsman minimum kill cooldown.", - "\n - Fixed Bloodmoon not working for modded clients and corrected missing strings for Blackmailer.", - "\n - Fixed issues where the Overseer would show Med Scanner after a meeting.", - "\n - Inhibitor and Saboteur now use sabotage sounds in the intro.", - "\n - Resolved issues where Aware did not work after an Overseer check and Merchant could assign converted add-ons.", - "\n - Fixed bugs with Hater being unable to kill, Crewpostor killing Solsticer, and Impostor Vision not working for Doppelganger.", - "\n - Resolved modded client issues with calling RpcSetName at the end of the game.", - "\n - Fixed win-condition conflicts between terrorists and workaholics.", - "\n - Corrected Necroview interaction with Admired and Madmate roles.", - "\n - Resolved bugs with Judge for modded clients.", - "\n - Gangster and Admirer can no longer get the Egoist role.", - "\n - Fixed bugs with Minus and Plus buttons in settings, ensuring they are always active.", - "\n - Intro Scene optimizations for smoother game start.", - "\n - Fixed numerous typos across roles and settings.", - "\n - Jester can no longer receive the Susceptible role.", - "\n - Added notify message about the game end when RpcEndGame is not received by specific clients.", - "\n - Fixed Baker not showing roles to non-host modded players", - "\n - Fixed mass kicking from lobbies against non-host modded players", - "\n【Translator Credits】", - "\n - Brazilian (By Dx7405, Pietro)", - "\n - Dutch (By apemv, madmazel_)", - "\n - French (By FuroYT, KevOut, Klaomi, Sansationnelle, Space Monkey)", - "\n - Italian (By alot, Baphojack, Mattix606)", - "\n - Japanese (By Sunnyboi)", - "\n - Latin American (By CreepPower)", - "\n - Russian (By TommyXL, Shoulder Devil, chill_ultimated, Nevermore59)", - "\n - 简体中文 (By: 青瀚,乐崽吖,绿色游戏(NikoCat233))", - "\n - Spanish (By Dawson, Sunnyboi, thewhiskas27, xxSShadow)", - "\n - Traditional Chinese (By FlyFlyTurtle, Hinharrrrr, netherdragontw, Pomelo_)", - "\n Check out all of our translators on our website\r\n", - "\n\n★ Welcome to Town of Host: Enhanced v2.1.0 ★" - ], - "Date": "2024-11-3T12:50:00Z" } ] } diff --git a/Resources/Announcements/modNews-zh_TW.json b/Resources/Announcements/modNews-zh_TW.json index 4e7dcd7a2..0e5f537a7 100644 --- a/Resources/Announcements/modNews-zh_TW.json +++ b/Resources/Announcements/modNews-zh_TW.json @@ -175,9 +175,6 @@ "\n - 受虐狂名稱由 Masochist 變為 Punching Bag (By WaterPanda)", "\n - 嗜血的名稱由 Bloodlust 變為 Bloodthirst (By WaterPanda)", "\n - 雙重人格的名稱由 Schizophrenic 變為 Paranoia (By WaterPanda)", - "\n - 更改了API崩潰時斷開與遊戲連接的邏輯 (By TommyXL)", - "\n - 如果黑手黨無法擊殺,則將他的CD設定為300秒 (By TommyXL)", - "\n - 更改了有關Api錯誤連接的警告訊息 (By Drakos)", "\n\n【Bug修復】", "\n - 許多職業將不再能獲得不兼容的附加職業 (By TommyXL, ryuk, WaterPanda)", "\n - 修復了賞金獵人重置錯誤目標的Bug (By TommyXL)", @@ -186,7 +183,7 @@ "\n - 修復了無法使用通風管的職業會在嘗試使用後卡住的Bug (By TommyXL)", "\n - 修復了基於工程師的職業圖標消失的Bug (By TommyXL)", "\n - 修復了職業分配期間的黑屏問題 (By TommyXL)", - "\n - 修復了特定職業的科學家分配 (By TommyXL)", + "\n - 修復了不相關的職業的科學家分配 (By TommyXL)", "\n - 修復了未使用法官的3個設定時的錯誤 (By TommyXL)", "\n - 修復了玩家被賭後按鈕處於活動狀態的Bug (By TommyXL)", "\n - 修復了一些關於賭怪介面的問題 (By TommyXL)", @@ -199,7 +196,7 @@ "\n - 修復了封禁清單關閉時EAC清單不起作用的問題 (By ryuk)", "\n - 修復了神風特攻隊導致玩家半死的問題 (By ryuk)", "\n - 修復了訊息會發送給原版玩家的Bug (By Drakos)", - "\n - 修復殭屍問題 (By Drakos)", + "\n - 修復僵屍問題 (By Drakos)", "\n - 修復了受虐狂會被審判的Bug (By Drakos)", "\n - 修復了當按下F1/F2/F3/F4時,擊殺冷卻停止的Bug (By NikoCat)", "\n - 修復了立刻自動開始設定 (By NikoCat)", @@ -207,163 +204,25 @@ "\n - 修復了模組客戶端在軍醫死亡時會看到護盾碎裂圖標的Bug (By D1GQ)", "\n - 現在迷你船員不能夠被決鬥、標記、流血和切片 (By Lezaiya)", "\n - 修復了描述、名稱等方面的拼字錯誤、不一致和錯誤 (By Moe, TommyXL, Drakos, WaterPanda, Sunnyboi, LezaiYa)", - "\n - 修復了賭博、審判等後未檢查會議狀態的錯誤 (By TommyXL)", - "\n - 修復了當被鵜鶘吃掉的玩家返回時結束遊戲的錯誤 (By TommyXL)", - "\n - 修復了復仇者試圖殺死死靈法師時的問題 (By TommyXL)", - "\n - 修復了保鑣/十字軍殺死保鑣/十字軍、搗蛋鬼和老兵時的問題 (By TommyXL)", - "\n - 修復«Quizmaster.None» (By TommyXL)", - "\n - 修復了衛道士遺失的字串 «*MayorHideVote» (By TommyXL)", - "\n - 修復了叛徒會分配給中立陣營的錯誤 (不適用於仰慕者 - By TommyXL)", - "\n - 修復了隱蔽者被抹除後隱蔽效果沒有消失的錯誤 (By TommyXL)", - "\n - 可能修復了神風特攻隊在被放逐時殺死目標的一些問題 (By TommyXL)", - "\n - 可能修復了遊戲結果顯示隨機暱稱時的錯誤 (By TommyXL)", - "\n - Fixed bug when Auto Start always stes ans saved 0 kill cooldown (By TommyXL)", - "\n - Other small fixes that occurred in certain cases (By TommyXL)", - "\n - Swift can no longer get Tricky and vice versa (By TommyXL)", - "\n - Remove unnecessary parenthesis for Lighter (By TommyXL)", - "\n - Fixed bug when Fortune Teller shows «INVALID:NotAssigned» (By Drakos)", - "\n - 修復自動開始故障的問題", - "\n - Fixed bug (hopefully) when the host changed his nickname to his own when he was killed by Doppelganger (By TommyXL)", - "\n - 修復按下F1顯示職業介紹時的Bug (By TommyXL)", - "\n - 修復老兵殺死搗蛋鬼時的Bug (By TommyXL)", - "\n - Fixed (hopefully) the last color question for Quizmaster (By TommyXL)", - "\n - 修復了殺人機器可以召開會議的Bug (By TommyXL)", - "\n - 修復了監禁訊息未顯示的Bug (By TommyXL)", "\n【已知的Bugs】", "\n - 1. 伺服器可能不穩定,因為協定需要在 Innersloth 方面進行修復", "\n - 2. 分身者、無影和效顰者變得不穩定,但依舊可以工作", "\n - 3. 模組客戶端有一些問題,因此建議只在房主上使用模組", "\n【翻譯貢獻】", "\n - 巴西語 (By Dx7405, Pietro)", - "\n - 荷蘭語 (By apemv, madmazel_)", + "\n- 荷蘭語 (By apemv, madmazel_)", "\n - 法語 (By FuroYT, KevOut, Klaomi, Sansationnelle, Space Monkey)", - "\n - 義大利語 (By alot, Baphojack, Mattix606)", - "\n - 日語 (By Sunnyboi)", - "\n - 拉丁美洲語 (By CreepPower)", - "\n - 俄語 (By TommyXL, Shoulder Devil, chill_ultimated, Nevermore59)", - "\n - 簡體中文 (By CrewCyan, LezaiYa, NikoCat)", - "\n - 西班牙語 (By Dawson, Sunnyboi, thewhiskas27, xxSShadow)", - "\n - 繁體中文 (By FlyFlyTurtle, netherdragontw, Pomelo_)", + "\n- 義大利語 (By alot, Baphojack, Mattix606)", + "\n- 日語 (By Sunnyboi)", + "\n- 拉丁美洲語 (By CreepPower)", + "\n- 俄語 (By TommyXL, Shoulder Devil, chill_ultimated, Nevermore59)", + "\n- 簡體中文 (By CrewCyan, LezaiYa, NikoCat)", + "\n- 西班牙語 (By Dawson, Sunnyboi, thewhiskas27, xxSShadow)", + "\n- 繁體中文 (By FlyFlyTurtle, netherdragontw, Pomelo_)", "\n在我們的官網上查看所有翻譯人員\n", "\n\n★ 歡迎來到 Town of Host: Enhanced v2.0.0 ★" ], "Date": "2024-07-21T12:50:00Z" - }, - { - "Number": "100007", - "Title": "Town of Host: Enhanced v2.1.0", - "Subtitle": "Finally, we're here!", - "Short": "TOH: Enhanced v2.1.0", - "Body": [ - "【基於版本】", - "\n - 基於版本 TOH: Enhanced v2.0.0", - "\n\n【新職業/附加職業】(5個職業、6個附加職業)", - "\n - 陰陽師 (殺戮類偽裝者, 想法&代碼: Drakos)", - "\n - 牽引者 (偽裝者幽靈職業, 想法&代碼: D1GQ)", - "\n - Troller (Neutral Chaos, idea: dx7405, coded: TommyXL)", - "\n - Ventguard (Crewmate Support, ported: EHR, coded by: TommyXL)", - "\n - Evader (Addon Helpful, idea: Lime, coded: TommyXL)", - "\n - Rebirth (Addon Helpful, idea & coded: Drakos)", - "\n - Sloth (Harmful Addon, idea & coded: Pyro)", - "\n - Eavesdropper (Addon Helpful, idea by: Crosspost Del Slay, coded: Moe)", - "\n - Spurt (Addon Helpful, idea by: .thediamondstar, coded: Drakos)", - "\n - Prohibited (Addon Harmful, idea by: Crosspost Del Slay, coded: TommyXL)", - "\n - New neutral Team (Faction): Neutral Apocalypse (idea & coded: Marg)", - "\n --- Min/max Neutral Apocalypse can be set", - "\n --- New role: Baker", - "\n --- Berserker and PlagueBearer now moved to Neutral Apocalypse", - "\n --- Soul Collector reworked", - "\n\r【New Settings/Features】", - "\n - Added vent disabling for vanilla (ported from MoreGamemodes by TommyXL & NikoCat)", - "\n --- When a player does not have access to vents, they will never be able to use it", - "\n - More fixes for AntiBlackOut (By TommyXL & Drakos)", - "\n --- Note: This will not completely fix black screen issues, but the more players there are in the game, the less chance of black screen occurrences", - "\n --- To do this, we use revives and base role changes during exile so that dead players will be alive for a couple of seconds but will become dead again", - "\n - Added support role basis changer mid-game (By TommyXL & Drakos)", - "\n --- CopyCat now supports role basis changes", - "\n --- Executioner and Lawyer also change role basis after their target dies", - "\n - TextBoxPatch (Ported: EHR, coded: TommyXL)", - "\n --- Allows you to write any characters into the chat", - "\n - improved Region Menu (coded: D1GQ)", - "\n - Added custom label ID for modded (Ported: EHR, coded: TommyXL)", - "\n - Jester: «Can't Move In Vents» (Setting, coded: TommyXL)", - "\n - Random spawn: Active On Round One (Setting, coded: TommyXL)", - "\n - Added warning message about enabling setting «No Game End»", - "\n --- Warns only the host when he presses the start button", - "\n - Disable Shapeshift menu for some Reject Shapeshift roles (By: Drakos)", - "\n --- For Pitfall, Bomber, Undertaker", - "\n --- It may be used for some more roles", - "\n - Return Ability Votes (By: Drakos)", - "\n --- For Cleanser, Eraser, Fortune teller, Keeper, Oracle, Godfather", - "\n --- First Vote will cancel (Vote Skip) or use the ability; second is regular vote", - "\n - Added «/vote» command (By: Drakos)", - "\n --- Can be disabled in the settings", - "\n - Death reason display improved (ported from EHR).", - "\n - Added role info in setting menu (By: Drakos)", - "\n - Added search bar in settings (By: Drakos)", - "\n - Addon Base (Port From EHR) (By: Drakos)", - "\n --- The settings are now sorted alphabetically", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Jester: Reveal Upon Eject (Setting, by: TheDiamondStar)", - "\n - Executioner: Reveal Target Upon Ejection (Setting, by: TheDiamondStar)", - "\n - Judge: Max trials per game (Setting, by: hinhinarrrrrr)", - "\n - Improved menu for role description in settings", - "\n - Setting: Apocalypse can see each other's Add-ons", - "\n - Settings: «Halloween Decorations» and «Birthday Decoration» (only for modded)", - "\n - Modded players now will see changes in TOHE settings", - "\n - Added custom image «imer» for Mercenary, Bounty Hunter, and Penguin: Thanks @that_one_missing_pixel (Pixel)", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Changed warning message about the API (By: Drakos)", - "\n - Changed warning message about the API (By: Drakos)", - "\n\r【Bug Fixes/Changes】", - "\n - Phantom Desync: Phantom now plays the invisibility animation instead of teleporting to a random vent for desync roles.", - "\n - Fixed issues with Veteran killing Taskinator, Killing Machine calling meetings, and the Jailed message not showing during the game.", - "\n - Resolved issues with stuck FFA meetings and Fortune Teller showing roles during FFA.", - "\n - Fixed speed bug when Bandit steals the Statue.", - "\n - Resolved Haunt Menu showing «NotAssigned» in Hide & Seek mode.", - "\n - Corrected issues with Doomsayer not using Impostor Vision and various bugs with Psychic.", - "\n - Fixed Taskinator triggering Schrodinger's Cat ability.", - "\n - Corrected Innocent win conditions with Impostor when the setting is enabled.", - "\n - Fixed player spawn issues at the start and after meetings.", - "\n - Resolved full role and add-on display when a player is exiled.", - "\n - Fixed Blackmail not working for non-host modded players.", - "\n - Resolved issues where the Deceiver could kill Serial Killer and where the Deceiver could kill dead players.", - "\n - Corrected several bugs related to Stalker, Enigma, and Madmate Impostor Vision.", - "\n - Fixed issues with Medium messages showing after Medium is dead.", - "\n - Resolved bug where Hangman could kill Nice Mini.", - "\n - Corrected Huntsman minimum kill cooldown.", - "\n - Fixed Bloodmoon not working for modded clients and corrected missing strings for Blackmailer.", - "\n - Fixed issues where the Overseer would show Med Scanner after a meeting.", - "\n - Inhibitor and Saboteur now use sabotage sounds in the intro.", - "\n - Resolved issues where Aware did not work after an Overseer check and Merchant could assign converted add-ons.", - "\n - Fixed bugs with Hater being unable to kill, Crewpostor killing Solsticer, and Impostor Vision not working for Doppelganger.", - "\n - Resolved modded client issues with calling RpcSetName at the end of the game.", - "\n - Fixed win-condition conflicts between terrorists and workaholics.", - "\n - Corrected Necroview interaction with Admired and Madmate roles.", - "\n - Resolved bugs with Judge for modded clients.", - "\n - Gangster and Admirer can no longer get the Egoist role.", - "\n - Fixed bugs with Minus and Plus buttons in settings, ensuring they are always active.", - "\n - Intro Scene optimizations for smoother game start.", - "\n - Fixed numerous typos across roles and settings.", - "\n - Jester can no longer receive the Susceptible role.", - "\n - Added notify message about the game end when RpcEndGame is not received by specific clients.", - "\n - Fixed Baker not showing roles to non-host modded players", - "\n - Fixed mass kicking from lobbies against non-host modded players", - "\n【Translator Credits】", - "\n - Brazilian (By Dx7405, Pietro)", - "\n - Dutch (By apemv, madmazel_)", - "\n - French (By FuroYT, KevOut, Klaomi, Sansationnelle, Space Monkey)", - "\n - Italian (By alot, Baphojack, Mattix606)", - "\n - Japanese (By Sunnyboi)", - "\n - Latin American (By CreepPower)", - "\n - Russian (By TommyXL, Shoulder Devil, chill_ultimated, Nevermore59)", - "\n - Simplified Chinese (By CrewCyan, LezaiYa, NikoCat)", - "\n - Spanish (By Dawson, Sunnyboi, thewhiskas27, xxSShadow)", - "\n - Traditional Chinese (By FlyFlyTurtle, Hinharrrrr, netherdragontw, Pomelo_)", - "\n Check out all of our translators on our website\r\n", - "\n\n★ Welcome to Town of Host: Enhanced v2.1.0 ★" - ], - "Date": "2024-11-3T12:50:00Z" } ] } diff --git a/Resources/Lang/de_DE.json b/Resources/Lang/de_DE.json index 67270a695..b60d6ccf4 100644 --- a/Resources/Lang/de_DE.json +++ b/Resources/Lang/de_DE.json @@ -20,8 +20,6 @@ "SubText.Neutral": "Arbeite alleine um zu gewinnen", "SubText.Apocalypse": "Werde mit deinem Team unbesiegbar", "SubText.Madmate": "Hilf den Verrätern", - "SubText.Lovers": "Lebt glücklich zusammen und gewinnt", - "SubText.Egoist": "Gewinne allein", "TypeImpostor": "Verräter", "TypeCrewmate": "Besatzung", "TypeNeutral": "Neutral", @@ -31,9 +29,6 @@ "TeamNeutral": "Neutral", "TeamCrewmate": "Besatzung", "TeamMadmate": "Verräterhelfer", - "TeamLovers": "Liebhaber", - "TeamEgoist": "Egoist", - "TeamApocalypse": "Apokalypser", "YouAreCrewmate": "Du bist Besatzung", "YouAreImpostor": "Du bist Verräter", "YouAreNeutral": "Du bist neutral", @@ -62,13 +57,13 @@ "CrewmatesCanGuess": "Besatzungsmitglieder können guessen", "ImpostorsCanGuess": "Verräter können guessen", "NeutralKillersCanGuess": "Neutrale Killer können guessen", - "NeutralApocalypseCanGuess": "Neutraler Apokalypser kann guessen", + "NeutralApocalypseCanGuess": "Neutral Apocalypse can guess", "PassiveNeutralsCanGuess": "Passive Neutrale können guessen", "CanGuessAddons": "Kann Add-ons guessen", "ShowOnlyEnabledRolesInGuesserUI": "Zeige nur aktivierte Rollen im Guesserbord an", "CrewCanGuessCrew": "Besatzungsmitglieder können Besatzungsmitglieder -Rollen guessen", "ImpCanGuessImp": "Verräter kann andere Verräter guessen", - "ApocCanGuessApoc": "Neutraler Apokalypser Kann Rollen von Neutralem Apokalypser guessen", + "ApocCanGuessApoc": "Neutral Apocalypse Can Guess Neutral Apocalypse Roles", "GuessImmune": "Dieses Ziel kann nicht geguessed werden, tut mir leid!", "GM": "Spielmeister", "Sunnyboy": "Sonniger", @@ -106,7 +101,7 @@ "Witch": "Hexe", "Nemesis": "Nemesis", "Bloodmoon": "Blutmond", - "Possessor": "Besitzer", + "Possessor": "Possessor", "Puppeteer": "Puppenspieler", "Mastermind": "Vordenker", "TimeThief": "Zeitdieb", @@ -145,88 +140,87 @@ "Dazzler": "Dazzler", "YinYanger": "YinYanger", "Deathpact": "Todespaktierer", - "Devourer": "Verschlinger", + "Devourer": "Devourer", "Consigliere": "Konsort", "Morphling": "Morphling", "Twister": "Wirbelstürmer", "Lurker": "Schleicher", - "Visionary": "Visionär", - "Refugee": "Flüchtling", + "Visionary": "Visionary", + "Refugee": "Refugee", "Underdog": "Unterlegener", "Ludopath": "Ludopath", "Godfather": "Patenonkel", - "Chronomancer": "Chronomant", + "Chronomancer": "Chronomancer", "Pitfall": "Fallenleger", "EvilMini": "Böser Mini", "Blackmailer": "Erpresser", - "Instigator": "Anstifter", + "Instigator": "Instigator", "LazyGuy": "Fauler Kerl", "SuperStar": "Superstar", "Celebrity": "Prominenter", "Cleanser": "Reiniger", "Keeper": "Hüter", "Knight": "Ritter", - "Mayor": "Bürgermeister", + "Mayor": "Mayor", "Psychic": "Spiritueller", "Mechanic": "Mechaniker", - "Sheriff": "Sherrif", + "Sheriff": "Sheriff", "Vigilante": "Gewissenhafter", - "Jailer": "Gefängniswärter", + "Jailer": "Jailer", "CopyCat": "Nachäffer", "Snitch": "Spitzel", "Marshall": "Marschall", - "Doctor": "Arzt", - "Dictator": "Diktator", - "Detective": "Detektiv", + "Doctor": "Doctor", + "Dictator": "Dictator", + "Detective": "Detective", "NiceGuesser": "Guter Guesser", "GuessMaster": "Guessmeister", "Transporter": "Transporter", - "TimeManager": "Zeitmanager", + "TimeManager": "Time Manager", "Spurt": "Spurt", "Veteran": "Veteran", - "Bastion": "Bastionär", - "Bodyguard": "Leibwächter", + "Bastion": "Bastion", + "Bodyguard": "Bodyguard", "Deceiver": "Schlitzohr", "Grenadier": "Grenadier", "Medic": "Sanitäter", "FortuneTeller": "Wahrsagerin", - "Judge": "Richter", - "Mortician": "Bestatter", + "Judge": "Judge", + "Mortician": "Mortician", "Medium": "Hellseher", "Pacifist": "Pazifist", "Observer": "Betrachter", "Monarch": "Monarch", "Overseer": "Aufpasser", "Coroner": "Leichenbeschauer", - "Merchant": "Kaufmann", - "President": "Präsident", + "Merchant": "Merchant", + "President": "President", "Hawk": "Falke", "Retributionist": "Vergelter", "Deputy": "Abgeordneter", - "Investigator": "Ermittler", + "Investigator": "Investigator", "Guardian": "Wächter", - "Addict": "Süchtiger", - "Mole": "Maulwurf", + "Addict": "Addict", + "Mole": "Mole", "Alchemist": "Alchemist", "Tracefinder": "Spurensucher", - "Oracle": "Orakel", + "Oracle": "Oracle", "Spiritualist": "Spiritualist", - "Chameleon": "Chamäleon", + "Chameleon": "Chameleon", "Inspector": "Inspektor", "Captain": "Kapitän", - "Admirer": "Bewunderer", - "TimeMaster": "Zeitmeister", - "Crusader": "Kreuzritter", + "Admirer": "Admirer", + "TimeMaster": "Time Master", + "Crusader": "Crusader", "Altruist": "Altruist", "Reverie": "Träumer", - "Lookout": "Ausguck", + "Lookout": "Lookout", "Telecommunication": "Telekommunikator", "Lighter": "Leuchter", "TaskManager": "Aufgabenmanager", - "Witness": "Zeuge", + "Witness": "Witness", "Swapper": "Swapper", - "ChiefOfPolice": "Polizeichef", - "NiceMini": "Guter Mini", + "NiceMini": "Nice Mini", "Mini": "Mini", "Spy": "Spion", "Randomizer": "Zufälliger", @@ -235,10 +229,10 @@ "Arsonist": "Feuerteufel", "Pyromaniac": "Pyromane", "Kamikaze": "Kamikaze", - "Huntsman": "Jäger", + "Huntsman": "Huntsman", "Terrorist": "Terrorist", "Executioner": "Scharfrichter", - "Lawyer": "Anwalt", + "Lawyer": "Lawyer", "Opportunist": "Opportunist", "Vector": "Vector", "Jackal": "Schakal", @@ -254,17 +248,16 @@ "Stalker": "Stalker", "Workaholic": "Fleißige-Arbeiter", "Solsticer": "Sonnenwender", - "Abyssbringer": "Abyssbringer", - "Collector": "Sammler", + "Collector": "Collector", "Provocateur": "Provokateur", "BloodKnight": "Blutritter", - "Apocalypse": "Apokalypser", + "Apocalypse": "Apocalypse", "PlagueBearer": "Pestträger", "Pestilence": "Seuche", "SoulCollector": "Seelensammler", - "Death": "Tod", - "Baker": "Bäcker", - "Famine": "Hungerleider", + "Death": "Death", + "Baker": "Baker", + "Famine": "Famine", "Berserker": "Berserker", "War": "Krieg", "Glitch": "Glitcher", @@ -275,7 +268,7 @@ "Juggernaut": "Tausendsassa", "Infectious": "Ansteckender", "Virus": "Virus", - "Pursuer": "Häscher", + "Pursuer": "Pursuer", "Specter": "Geist-Arbeiter", "Pirate": "Pirat", "Agitater": "Hetzer", @@ -292,13 +285,13 @@ "Amnesiac": "Dementer", "Imitator": "Imitator", "Bandit": "Bandit", - "Doppelganger": "Doppelgänger", - "PunchingBag": "Boxsack", + "Doppelganger": "Doppelganger", + "PunchingBag": "Punching Bag", "Doomsayer": "Unheilsprophet", - "Shroud": "Schleier", - "Werewolf": "Werwolf", + "Shroud": "Shroud", + "Werewolf": "Werewolf", "Shaman": "Schamane", - "Seeker": "Sucher", + "Seeker": "Seeker", "Pixie": "Fee", "Occultist": "Okkultist", "SchrodingersCat": "Schrödingers Katze", @@ -306,7 +299,7 @@ "VengefulRomantic": "Rächender Romantiker", "RuthlessRomantic": "Rücksichtsloser Romantiker", "Poisoner": "Vergifter", - "HexMaster": "Hexenmeister", + "HexMaster": "Hex Master", "Wraith": "Gespenst", "Jinx": "Jinx", "PotionMaster": "Trankmeister", @@ -314,34 +307,34 @@ "Warden": "Aufseher", "Minion": "Günstling", "Ghastly": "Grausiger", - "LastImpostor": "Letzter Verrräter", - "Overclocked": "Übertakteter", + "LastImpostor": "Last Impostor", + "Overclocked": "Overclocked", "Lovers": "Liebhaber", "Madmate": "Verräterhelfer", "Watcher": "Beobachter", "Flash": "Flitzer", - "Torch": "Fackelträger", - "Seer": "Seher", + "Torch": "Torch", + "Seer": "Seer", "Tiebreaker": "Tiebrecher", - "Oblivious": "Vergesslicher", - "Rebirth": "Wiederbelebender", - "Bewilder": "Verwirrender", - "Workhorse": "Arbeitspferd", + "Oblivious": "Oblivious", + "Rebirth": "Rebirth", + "Bewilder": "Bewilder", + "Workhorse": "Workhorse", "Fool": "Tollpatsch", "Avanger": "Rächer", "Youtuber": "YouTuber", "Egoist": "Egoist", - "Stealer": "Stehler", + "Stealer": "Stealer", "Paranoia": "Schizophrene", "Mimic": "Nachahmer", "Guesser": "Räter", "Necroview": "Nekroansicht", - "Reach": "Reichweite", + "Reach": "Reach", "Charmed": "Bekehrter", - "Cleansed": "Gereinigt", + "Cleansed": "Cleansed", "Bait": "Killköder", "Trapper": "Bärenfalle", - "Infected": "Infiziert", + "Infected": "Infected", "Onbound": "Beständiger", "Rebound": "Abpraller", "Mundane": "Weltlicher", @@ -359,7 +352,7 @@ "Gravestone": "Grabstein", "Lazy": "Fauler", "Autopsy": "Autopsist", - "Loyal": "Treu", + "Loyal": "Loyal", "EvilSpirit": "Böser Geist", "Recruit": "Kumpanrekrut", "Admired": "Bewunderter", @@ -374,8 +367,8 @@ "Mare": "Alpträumer", "Burst": "Platzender", "Sleuth": "Pathologe", - "Clumsy": "Tollpatschig", - "Nimble": "Flink", + "Clumsy": "Clumsy", + "Nimble": "Nimble", "Circumvent": "Gehender", "Cyber": "Cyber", "Hurried": "Beeilter", @@ -389,17 +382,15 @@ "Statue": "Statue", "Evader": "Evader", "DollMaster": "Marionetten-Meister", - "DoubleAgent": "Doppelagent", - "Sloth": "Faultier", - "Prohibited": "Verbotener", + "DoubleAgent": "Double Agent", + "Sloth": "Sloth", + "Prohibited": "Prohibited", "Eavesdropper": "Eavesdropper", - "Shocker": "Schocker", - "Revenant": "Wiederkehrer", "BracketAddons": "Füge Klammern zu Add-ons hinzu", "EngineerTOHEInfo": "Nutze die Schächte, um die Verräter zu erwischen", "ScientistTOHEInfo": "Greife überall auf die tragbare Lebensanzeige zu", "NoisemakerTOHEInfo": "Bei Ermordung wird ein Alarm ausgesendet", - "TrackerTOHEInfo": "Verfolge Spieler mit der Map", + "TrackerTOHEInfo": "Track players with your map", "ShapeshifterTOHEInfo": "Verwandle dich in Besatzungsmitglieder, um den Verdacht auf sie zu werfen", "PhantomTOHEInfo": "Werde unsichtbar", "GuardianAngelTOHEInfo": "Beschütze die Besatzung vor den Verrätern", @@ -422,7 +413,7 @@ "BeforeNemesisInfo": "Du kannst noch nicht killen", "AfterNemesisInfo": "Fang jetzt an zu killen", "BloodmoonInfo": "Richte Verwüstung unter der Besatzung an", - "PossessorInfo": "Kontrolliere und führe Besatzungsmitglieder weg von anderen", + "PossessorInfo": "Possess and lead crewmates away from others", "PuppeteerInfo": "Bring die andere Spieler dazu für dich zu töten", "MastermindInfo": "Bring andere dazu für dich zu töten", "TimeThiefInfo": "Veringere die Besprechungszeit durchs Killen", @@ -443,12 +434,12 @@ "GreedyInfo": "Deine Killwartezeit ändert sich", "CursedWolfInfo": "Du überlebst einige Tötungsversuche", "SoulCatcherInfo": "Du hast den Ort mit deinem Ziel getauscht", - "QuickShooterInfo": "Spare Munition um die Wartezeit zu verkürzen", + "QuickShooterInfo": "Store ammo to offset kill cooldown", "CamouflagerInfo": "Tarne alle für leichte Kills", "EraserInfo": "Lösche die Rolle deines Votes", "ButcherInfo": "Genieße meine wunderschöne Arbeit", - "HangmanInfo": "Ich entscheide, wann dein Leben endet", - "SwooperInfo": "Du wirst vorübergehend unsichtbar", + "HangmanInfo": "I will decide when your life will end", + "SwooperInfo": "Turn invisible temporarily", "CrewpostorInfo": "Kille, indem du Aufgaben erfüllst", "WildlingInfo": "Kille mit Stärke und verkleide dich", "TricksterInfo": "Kille und täusche die Besatzung", @@ -460,7 +451,7 @@ "CouncillorInfo": "Töte Besatzungsmitglieder während Meetings", "DazzlerInfo": "Reduziere die Sicht der Besatzung", "DeathpactInfo": "Lass Spieler einen Todespakt abschließen", - "DevourerInfo": "Konsumiere die Skins der Besatzung", + "DevourerInfo": "Consume the skin of the crew", "ConsigliereInfo": "Finde die Rolle anderer Spieler heraus", "MorphlingInfo": "Du kannst nur als Geformwandelter killen", "TwisterInfo": "Vertausche die Positionen aller Spieler", @@ -481,7 +472,7 @@ "CleanserInfo": "Lösche alle Add-on-Rollen von deinem gevoteten Spieler", "KeeperInfo": "Lehne den Auswurf ab, der Hüter schützt!", "MayorInfo": "Deine Votes zählen mehrfach", - "PsychicInfo": "Einer der roten Namen ist böse", + "PsychicInfo": "One of the red names is evil", "MechanicInfo": "Nutze Vents und behebe die Sabotagen", "SheriffInfo": "Erschieße die Verräter", "VigilanteInfo": "Nicht der Held den wir verdienten, aber den, den wir bräuchten", @@ -490,17 +481,17 @@ "SnitchInfo": "Vollende deine Aufgaben, um die Verräter zu erkennen", "MarshallInfo": "Schließe deine Aufgaben ab, um deine Unschuld zu beweisen", "DoctorInfo": "Und so starben sie...", - "DictatorInfo": "Verurteile jemanden zu Tode", - "DetectiveInfo": "Erhalte zusätzliche Informationen von deinen Leichenmeldungen", - "UndercoverInfo": "Verräter sehen dich als ihren Partner", - "KnightInfo": "Du kannst einen Spieler killen", + "DictatorInfo": "Exile a player based on your judgment", + "DetectiveInfo": "Gain extra info from your body reports", + "UndercoverInfo": "Impostors see you as their partner", + "KnightInfo": "You can kill one player", "NiceGuesserInfo": "Erguesse die Verräter -rollen in den Notfalltreffen, um sie zu killen", "GuessMasterInfo": "Flüstern gehört, jedes geguesste Wort.", "TransporterInfo": "Erledige Aufgaben, um die Positionen von 2 zufälligen Spielern zu tauschen", "TimeManagerInfo": "Erhöhe die Besprechungszeit durchs Aufgabenabschließen", "VeteranInfo": "Begib dich in Bereitschaft, um jeden zu killen, der es an dir versucht", "BastionInfo": "Lege Bomben in Vents", - "YinYangerInfo": "Verbrenne spontan zwei Spieler", + "YinYangerInfo": "Spontaneously combust two players", "BodyguardInfo": "Verhindere nahegelegene Kills", "DeceiverInfo": "Versuche, Spieler zu täuschen", "GrenadierInfo": "Verringere die Sicht der Verräter, indem du dich in die Vents begibst", @@ -511,9 +502,9 @@ "MediumInfo": "Rede mit Geistern", "ObserverInfo": "Du siehst Schild-Animationen", "PacifistInfo": "Vente um die Kill-Wartezeit zurück zu setzten", - "RebirthInfo": "Erstehe wieder auf", + "RebirthInfo": "Arise Again", "MonarchInfo": "Gib der Besatzung mehr Votingmacht!", - "AbyssbringerInfo": "Platziere schwarze Löcher", + "AbyssbringerInfo": "Erstelle schwarze Löcher", "SpurtInfo": "Spring wie ein Hase!", "StealthInfo": "Killen blendet jeden im Raum", "PenguinInfo": "Ziehe deine Opfer", @@ -547,7 +538,6 @@ "WitnessInfo": "Finde heraus, ob jemand vor kurzem gekillt hat", "GhastlyInfo": "Besitze jemanden!", "SwapperInfo": "Tausche die Votes zweier Spieler", - "ChiefOfPoliceInfo": "Stelle einen Sheriff ein, um der Besatzung zu helfen!", "NiceMiniInfo": "Niemand kann dich verletzten bis du Erwachsen bist.", "ArsonistInfo": "Übergieße alle und entfache das Feuer", "PyromaniacInfo": "Verbrenne und kille alle", @@ -574,12 +564,12 @@ "CollectorInfo": "Sammle Votes von Spielern", "ProvocateurInfo": "Gewinne mithilfe deines Ziels", "BloodKnightInfo": "Killen gibt dir kurzzeitig einen Schild", - "PlagueBearerInfo": "Verseuche alle, um zum Pestilence zu werden", + "PlagueBearerInfo": "Plague everyone to turn into Pestilence", "PestilenceInfo": "Lösche alle aus!", "SoulCollectorInfo": "Sage Tode voraus, um Seelen zu sammeln", "DeathInfo": "Erlasse Armageddon", "BakerInfo": "Feed Players Bread to become Famine", - "FamineInfo": "Bring alle zum verhungern", + "FamineInfo": "Starve Everyone", "BerserkerInfo": "Kille um dein Level zu erhöhen", "WarInfo": "Zerstöre alles", "GlitchInfo": "Hacke und lege jeden um", @@ -603,12 +593,12 @@ "VultureInfo": "Iss Leichen durchs melden um zu gewinnen", "TaskinatorInfo": "Stille Aufgaben, tödliche Explosionen", "BenefactorInfo": "Aufgabe erledigt, Schildelite!", - "MedusaInfo": "Versteinere Leichen, indem du sie meldest", + "MedusaInfo": "Stone bodies by reporting them", "SpiritcallerInfo": "Verwandle Spieler zu bösen Geistern", "AmnesiacInfo": "Merke dir die Rolle der Leiche", "ImitatorInfo": "Ahme die Rolle eines Spielers nach", "BanditInfo": "Klaue eines Spielers Add-on-Rollen", - "DoppelgangerInfo": "Stiehl die Identität deines Ziels", + "DoppelgangerInfo": "Steal your target's identity", "PunchingBagInfo": "Werde einige Male angegriffen um zu gewinnen!", "KamikazeInfo": "Kille Spieler durch eine suizidale Mission", "DoomsayerInfo": "Guesse die Rollen von Spielern, um zu gewinnen", @@ -625,9 +615,9 @@ "PoisonerInfo": "Kille jeden mit verzögerten Kills", "HexMasterInfo": "Verhexe Spieler, damit sie im Treffen sterben", "WraithInfo": "Vente, um vorübergehend unsichtbar werden", - "JinxInfo": "Reflektiere Attacken auf deine Angreifer", + "JinxInfo": "Reflect attacks onto your attackers", "PotionMasterInfo": "Nutze Tränke zu deinem Vorteil", - "NecromancerInfo": "Kille deinen Killer, um dem Tod zu trotzen", + "NecromancerInfo": "Kill your killer to defy death", "WardenInfo": "(Geist) Warne vor Gefahren", "MinionInfo": "(Geist) Blende deine Feinde", "LoversInfo": "Lebt glücklich zusammen und gewinnt", @@ -639,41 +629,41 @@ "TorchInfo": "Du hast erweiterte Sicht!", "SeerInfo": "Du wirst alarmiert, wenn jemanden stirbt", "TiebreakerInfo": "Brich den Votegleichstand", - "ObliviousInfo": "Du kannst keine Leichen melden", + "ObliviousInfo": "You can't report bodies", "BewilderInfo": "Eine Wendung der Sicht, ein Netz der Verwirrung", "WorkhorseInfo": "Sei der Erste, der seine Aufgaben erledigt, um mehr zu erhalten", "FoolInfo": "Du kannst keine Sabotagen beheben", - "AvangerInfo": "Du nimmst jemanden mit in den Tod", - "YoutuberInfo": "Werde zuerst gekillt um zu gewinnen", + "AvangerInfo": "You take someone with you upon death", + "YoutuberInfo": "Get killed first to win", "CelebrityInfo": "Alle wissen es wenn du stirbst", "EgoistInfo": "Gewinne allein", - "StealerInfo": "Gewinne Stimmen mit Kills", + "StealerInfo": "Gain votes with kills", "ParanoiaInfo": "Du bist gleichzeitig tot und lebendig", "MimicInfo": "Offenbare vom Nachahmer gekillte Spieler den Verrätern nach seinem Tod", "GuesserInfo": "Erguesse die Rollen in den Notfalltreffen, um sie zu killen", - "NecroviewInfo": "Sieh das Team der Toten", - "ReachInfo": "Du hast eine größere Killreichweite", + "NecroviewInfo": "See the team of the dead", + "ReachInfo": "You have a longer kill range", "BaitInfo": "Dein Killer meldet deine Leiche sofort", "TrapperInfo": "Mache deinen Killer für ein paar Sekunden bewegungsunfähig", "OnboundInfo": "Du kannst nicht geguessed werden", "ReboundInfo": "Errate mich, und ich ersteche dich!", "MundaneInfo": "Aufgaben erledigt, das Guessen beginnt.", - "UnreportableInfo": "Deine Leiche kann nicht gemeldet werden", - "LuckyInfo": "Weiche Angriffen aus", + "UnreportableInfo": "Your body can't be reported", + "LuckyInfo": "Dodge attackers", "DoubleShotInfo": "Du hast einen zweiten Guessversuch", "RascalInfo": "Du erscheinst manchmal böse", - "SoullessInfo": "Du hast keine Seele", - "GravestoneInfo": "Deine Rolle wird offenbart, wenn du stirbst", + "SoullessInfo": "You have no soul", + "GravestoneInfo": "Your role is revealed when you die", "LazyInfo": "Du bist zu faul", "AutopsyInfo": "Du kannst sehen wie andere starben", - "LoyalInfo": "Du kannst nicht rekrutiert werden", - "EvilSpiritInfo": "Du bist ein böser Geist", + "LoyalInfo": "You cannot be recruited", + "EvilSpiritInfo": "You are an evil Spirit", "RecruitInfo": "Hilf dem Schakal", - "AdmiredInfo": "Der Bewunderer hat dich zu seiner Liebe auserwählt", - "GlowInfo": "Du leuchtest in der Dunkelheit", + "AdmiredInfo": "The Admirer chose you as their love", + "GlowInfo": "You glow in the dark", "RadarInfo": "Nächste Person, Pfeilrichtung!", - "DiseasedInfo": "Erhöhe die Wartezeit des Spielers, der mit dir interagiert", - "AntidoteInfo": "Verringere die Wartezeit des Spielers, der mit dir interagiert", + "DiseasedInfo": "Increase the cooldown of the player who interacts with you", + "AntidoteInfo": "Decrease the cooldown of the player who interacts with you", "StubbornInfo": "Schütze deine Rolle und Add-on-Rolle", "SwiftInfo": "Deine Kills verursachen keine Teleportation auf die Leiche", "UnluckyInfo": "Interagieren kann zum Tod führen", @@ -689,7 +679,7 @@ "NimbleInfo": "Du kannst venten!", "CircumventInfo": "Du kannst nicht mehr venten", "OiiaiInfo": "OIIAIOIIIAI", - "CyberInfo": "Du bist populär!", + "CyberInfo": "You're popular!", "HurriedInfo": "Oh Mann, ich hab zu viel zu tun!", "InfluencedInfo": "Es fehlt dir an Entschlossenheit!", "SilentInfo": "Vote wie ein Geist!", @@ -704,12 +694,12 @@ "BardInfo": "Die Anmut des Gedichts, die Spur des Mordes, ein rhythmischer Tanz in einer dunklen Umarmung.", "RainbowInfo": "Bunte Melodien! Du kennst nicht einmal deine eigene Farbe.", "DollMasterInfo": "Steuere die Aktionen von Spielern!", - "DoubleAgentInfo": "Platziere Bomben an Spielern während dem Treffen", + "DoubleAgentInfo": "Plant bombs on players in meetings", "SlothInfo": "Du bist langsamer", - "ProhibitedInfo": "Bestimmte Vents sind blockiert", - "EavesdropperInfo": "Höre bei anderen Rollen mit", - "ShockerInfo": "Schocke ahnungslose Spieler", - "RevenantInfo": "Nimm die Rolle deines Killers", + "ProhibitedInfo": "Certain vents are blocked", + "EavesdropperInfo": "Listen in on other roles", + "ShockerInfo": "Shock unsuspecting players", + "RevenantInfo": "Take your killer's role", "EngineerTOHEInfoLong": "(Besatzung):\nAls Ingenieur hast du die Fähigkeit, Vents zu nutzen, solange die Kommunikation nicht sabotiert ist.", "ScientistTOHEInfoLong": "(Crewmates):\nAs the Scientist, you can see vitals at any time, showing you who is alive and dead.", "NoisemakerTOHEInfoLong": "(Crewmates):\nAs the Noisemaker, whenever you die, you will make a noise, and a visual indicator of your death appears on the screen so the Crewmates can run to catch the person who killed you red-handed (even if it’s not Red).", @@ -781,11 +771,11 @@ "LurkerInfoLong": "(Impostors):\nAs the Lurker, you can jump into a vent to reduce your cooldown by a certain number of seconds. After you kill, your cooldown resets to its original value.", "VisionaryInfoLong": "(Verräter):\nAls Visionär siehst du den Aufenthaltsort von lebenden Spielern während einem Treffen.\nFolgende Information wird bei den Spielern angezeigt:\n- Roter Name bedeutet Verräter.\n- Türkiser Name bedeutet Besatzung.\n- Grauer Name bedeutet Neutral.", "PlagueDoctorInfoLong": "(Neutral):\n(Seuchendoktor von TOH)\nAls Seuchendoktor musst du jeden lebenden Spieler infiziert bekommen.\nDu startest mit einem beliebigen Spieler, den du infizierst, wenn wer für kurze Zeit in unmittelbarer Nähe dieses Infizierten verbringt, wird er selbst auch infiziert.\nDer Infizierungsprozess ist kumulative, also er resetet sich nicht nach Distanzierung oder nach Treffen.", - "RefugeeInfoLong": "(Madmates):\nAs the Refugee, you were either:\n -An Amnesiac who remembered an Impostor\n -A killer who killed the Godfather's target.\n -A Romantic whose partner was an Impostor\n -Or an Imitator that imitated an Impostor.\n\nNow your job is to help the Impostors kill the crewmates.", + "RefugeeInfoLong": "(Verräterhelfer):\nAls Flüchtling, warst du entweder ein Dementer welcher sich an ein Verräter erinnerte oder ein Verräter, welcher das Ziel vom Patenonkel killte.\n\nJetzt ist es deine Aufgabe den Verrätern zu helfen, die Besatzung zu killen.", "UnderdogInfoLong": "(Verräter):\nAls Unterlegener kannst du nicht killen bis eine bestimmte Anzahl an lebenden Spieler bleibt.", "ConsigliereInfoLong": "(Verräter):\nAls Konsort kannst du die Rollen der anderen Spieler offenbaren in dem du deinen Killknopf benutzt.\n\nEinzelklick: Rolle offenbaren \nDoppelklick: killen\n\nWen du keine Offenbarungen mehr hast, funktioniert dein Killknopf normal.", "LudopathInfoLong": "(Impostors):\nAs the Ludopath, your kill cooldown is randomized.\n\nMinimum it can be is 1 second, while the maximum is your default kill cooldown.", - "GodfatherInfoLong": "(Impostors):\nAs the Godfather, you vote someone to make them your target.\nIn the next round, if someone kills the target, the killer will turn into a Refugee or Madmate.", + "GodfatherInfoLong": "(Impostors):\nAs the Godfather, you vote someone to make them your target.\nIn the next round, if someone kills the target, the killer will turn into a Refugee.", "ChronomancerInfoLong": "(Impostors):\nAs the Chronomancer, you have a charge bar which indicates when the slaughter is ready. When it is at 100% the next time you kill someone, you go into slaughter mode, meaning you can kill indefinitely until your bar runs out of charge. Otherwise, you have a normal KCD.", "PitfallInfoLong": "(Verräter):\nAls Fallenleger kannst du formwandeln, um den Bereich der Formwandlung als Falle zu markieren. Spieler, die diesen Bereich betreten, werden für kurze Zeit bewegungsunfähig und ihre Sicht wird eingeschränkt.", "EvilMiniInfoLong": "(Impostors):\nAs the Evil Mini, you are unkillable until you grow up and have a very long initial kill cooldown, which gets drastically shortened as you grow up.", @@ -821,7 +811,7 @@ "GrenadierInfoLong": "(Besatzung):\nWenn der Grenadier ventet verursacht er in seiner Nähe einen Granatenknall, der Verrätern und je nach Einstellung auch Neutralen die Sicht einschränkt.", "MedicInfoLong": "(Besatzung):\nDer Sanitäter kann mit dem Killknopf jemanden einen Schild für das ganze Spiel geben. Wenn der Sanitäter stirbt verliert das Ziel diesen Schild, wenn wer das Ziel anschießt, bekommt der Sanitäter auch Bescheid über den Killversuch.\nJe nach Hosteinstellungen sieht der Sanitäter oder das Ziel einen grünen Kreis「●」 neben dem geschützten Spielernamen.", "FortuneTellerInfoLong": "(Besatzung):\nWenn die Wahrsagerin für einen Spieler votet bekommt sie einen Hinweis zu seiner aktuellen Rolle.\n\nWenn du alle Aufgaben erledigt hast bekommst du die exakte Rolle anstatt einem Hinweis!\n\nHinweis: Wenn die Einstellung aktiv ist, einen Hinweis von einem zufälligen Spieler zu bekommen, bist du nicht berechtigt einen Spieler öfters abzuchecken.", - "JudgeInfoLong": "(Besatzung):\nDer Richter kann im Treffen einen bestimmten Spieler verurteilen. Wenn dieser böse ist, stirbt der Verurteilte (Ob wer böse ist, hängt von den Hosteinstellungen ab), wenn nicht begehst du Selbstmord.\nDer Urteilsbefehl ist: /tl [Spieler-ID]\nDu kannst die Spieler-IDs neben jedem Namen der Spieler sehen, oder benutze den Befehl /id um dir alle Spieler-IDs anzeigen zu lassen.\nAls Verräterhelfer-Richter kannst du alle Spieler verurteilen.", + "JudgeInfoLong": "(Crewmates):\nThe Judge can judge a certain player during the meeting. If the target is evil, the target will be killed (whether it is evil or not is set by the Host). If it is wrong, the Judge commits suicide.\nCommand for judgment: /tl [player id]\nYou can see the player's id before the player's name, or use the /id command to view the id of all players.\nJudges can judge all players when they become Madmate.\nIn meeting the ability count shows how many trails you have in this meeting. Out of meeting the ability counts shows how many trails you have for the whole game.", "MorticianInfoLong": "(Besatzung):\nAls Leichenbestatter werden dir Pfeile angezeigt die in Richtung einer Leiche zeigen und wen er diese meldet, wird er erfahren wer als Letztes in Kontakt mit ihm war.\nHinweis: Leichenbestatter werden keine Seher oder Vergessliche.", "MediumInfoLong": "(Besatzung):\nDer Hellseher kann in Kontakt mit den Geistern treten, nachdem jemand eine Leiche gemeldet hat. Der Spieler, der eine Leiche gemeldet hat, muss kein Hellseher sein. Der tote Spieler kann nur mit JA oder NEIN auf die Frage des Hellsehers antworten, welche nur vom Hellseher gesehen werden kann. (Der tote Spieler kann mit /ms yes oder /ms no antworten). Hinweis: Hellseher können keine Vergesslichen sein.", "ObserverInfoLong": "(Besatzung):\nAls Betrachter kannst du die Schild-Animation von anderen Spielern nach dem ersten Treffen sehen, das weist auf eine bestimmte Fähigkeit der Rolle auf. Also schau dich gut um.", @@ -833,7 +823,7 @@ "MerchantInfoLong": "(Besatzung):\\Der Handelsmann verkauft zufällige Add-ons an zufällige Spieler wenn er eine Aufgabe abgeschlossen hat. Jeder Add-onverkauf bringt Geld ein, mit dem du ab einer gewissen Anzahl einen versuchten Kill mit einer Bestechung an den Killer abwehren kannst. Der Bestochene kann dich nicht killen, aber du bekommst keine Nachricht wer es war. Das benutzte Bestechungsgeld geht verloren und kann nicht mehr genutzt werden.", "RetributionistInfoLong": "(Crewmates):\nAs the Retributionist, you can kill a limited amount of players after your death.\n\nUse /ret [playerID] to kill.", "HawkInfoLong": "(Besatzung [Geist]):\nAls Falke kannst du eine vom Host festgelegte begrenzte Anzahl an Spielern killen. Es besteht jedoch die Möglichkeit, dass du es verfehlst. Wenn du jemanden mehrmals in Stücke schneidest, erhöht sich die Wahrscheinlichkeit.", - "DeputyInfoLong": "(Besatzung):\nDer Abgeordnete kann seinen Killknopf dazu benutzen jemandes Killwartezeit zurückzusetzen.\n\nWenn das Ziel keinen Killknopf hat waren diese Handschellen für die Fische.", + "DeputyInfoLong": "(Crewmates):\nAs the Deputy, use your kill button to handcuff a player.\nThe player who is handcuffed will have their next kill attempt treated as a handcuff break, and the kill cooldown will be reset.\n\nIf the target does not have a kill button, then the handcuff was a waste.", "InvestigatorInfoLong": "(Crewmates):\nAs an Investigator, you can use your kill button to investigate someone. When you investigate someone, their name will appear in red if they possess a kill button (impostor/SS basis) or light blue if they lack a kill button (crewmate/engineer/scientist basis). However, please note that the color of the names will return to normal when someone calls a meeting.", "GuardianInfoLong": "(Besatzung):\nAls der Wächter wirst du unbesiegbar, nachdem du deine Aufgaben beendet hast. Sogar Guesser können dich dann nicht mehr in Treffen guessen.", "AddictInfoLong": "(Besatzung):\nDer Süchtige hat einen Selbstmordtimer, dieser wird als Ventwartezeit angezeigt, wenn dieser abläuft stirbst du.\nWenn die Ventwartezeit abgelaufen ist, hast du noch kurz Zeit zu venten.\nWenn du es nicht machst, begehst du Selbstmord, wenn schon wird der Selbstmordtimer zurückgesetzt.\nNach dem Venten bist du für eine bestimmte Zeit vor jeder Interaktion sicher. Danach aber bist du für eine andere bestimmte Zeit bewegungsunfähig und kannst auch keine Leichen melden.", @@ -849,7 +839,7 @@ "AdmirerInfoLong": "(Crewmates):\nAs the Admirer, admire a player to make them Crewmate aligned.\nThey'll win with crewmates and not their original team.\n\nYou can only do this once per player.", "TimeMasterInfoLong": "(Besatzung):\nAls Zeitmeister kannst du durchs Venten jedermanns Position markieren.\nWenn du ernuet ventest, setzt du jeden lebenden Spieler auf diese Position zurück.\n\nWährend der Fähigkeitsnutzung hast du ein Zeitschild welches dich vor dem Tod schützt.", "CrusaderInfoLong": "(Besatzung):\nAls Kreuzritter nutze deinen Killknopf um einen andere Spieler zu missionieren.\nSollte der missionierte Spieler angeschossen werden, killst du den Killer.", - "AltruistInfoLong": "(Crewmates):\nAs the Altruist, you can sacrifice yourself to revive a dead body using the «Report» button.\nNote: If a dead player has left the game, you report that body normally.\nAlso revived player cannot report self dead body", + "AltruistInfoLong": "(Crewmates):\nAs the Altruist, you can sacrifice yourself to revive a dead body using the «Report» button.\nNote: If a dead player has left the game, you report that body normally.\nAlso revived player cannot report self dead body\nUse vent button to change between Report & Revive.", "ReverieInfoLong": "(Besatzung):\nAls Träumer kannst du killen, aber deine Killwartezeit beginnt sehr hoch.\n\nWenn du ein Besatzungsmitglied killst, erhöht sich die Killwartezeit, ansonsten wird sie kleiner.\nJe nach Hosteinstellungen begehst du einen Fehlschuss wenn die maximal Killwartezeit erreicht ist und stirbst mit dem Opfer. \n\nDu gewinnst mit der Besatzung.", "LookoutInfoLong": "(Besatzung):\nAls Ausblicker siehst du die Spieler-IDs von allen jederzeit.\nDas verschafft dir den Vorteil bei Formwandlern und Camouflagge.", "TelecommunicationInfoLong": "(Besatzung):\nAls Telekommunikator bekommst du über die Nutzung aller Sicherheitssysteme wie Kameras, Lebensanzeige, Türlogs oder Adminpanel Bescheid.", @@ -891,7 +881,7 @@ "PestilenceInfoLong": "(Apocalypse):\nAs Pestilence, you're an unstoppable machine.\nAny attack towards you will be reflected towards them.\nIndirect kills don't even kill you.\n\nOnly way to kill Pestilence is by voting them out or the Pestilence misguessing.\nYour presence is announced to everyone at the meeting after you transform.", "SoulCollectorInfoLong": "(Apocalypse):\nAs Soul Collector, you can use your kill button on a player to predict their death. You will gain a soul if your target dies in the round you select them or the meeting after.\nYour target resets after each meeting or after they die, whichever comes first. \n\nOnce you collect the configurable amount of souls, you become Death. If the gain passive souls setting is enabled, you will gain a soul each meeting.", "DeathInfoLong": "(Apocalypse):\nOnce the Soul Collector has collected their needed souls, they become Death. Death kills everyone and wins if Death is not ejected by the end of the next meeting.\nA configurable amount of extra meeting time will be given on the meeting Death transforms to have more discussion to find Death.\n\nYou are invincible, and your presence is announced to everyone at the meeting after you transform.", - "BakerInfoLong": "(Apocalypse):\nAs the Baker, you can use your kill button on a player per round to give them bread. \nOnce a set amount of players are alive with bread, you become Famine.\n\nIf the Bread gives additional effects and the setting is on, then you can vent to change the bread that you give out. \nBread Effects:\nReveal: Reveals the target's role to the Baker (stays the whole game)\nRoleblock: Sets the target's kill cooldown to 999 (resets to normal after the meeting)\nBarrier: Gives the target a barrier that is only known to the Baker (barrier is removed after the meeting)", + "BakerInfoLong": "(Apocalypse):\nAs the Baker, you can use your kill button on a player per round to give them bread. \nOnce a set amount of players are alive with bread, you become Famine.\n\nIf the Bread gives additional effects and the setting is on, then you can vent to change the bread that you give out. \nBread Effects:\nReveal: Reveals the target's role to the Baker (stays the whole game)\nRoleblock: Resets the target's kill cooldown when they try to use their kill button\nBarrier: Gives the target a barrier that is only known to the Baker (barrier is removed after the meeting)", "FamineInfoLong": "(Apocalypse):\nOnce the Baker has a set amount of people with bread alive, they will become Famine. If the Famine does not get voted out after the meeting, then they will become Famine, and every player without bread will starve (excluding other Apocalypse members).\nAfter this starvation of everyone without bread, Famine can use their kill button to starve any remaining players, which will kill those players right before the next meeting.\n\nYou are invincible, and your presence is announced to everyone at the meeting after you transform.", "BerserkerInfoLong": "(Apocalypse):\nAs the Berserker, you level up with each kill.\nUpon reaching a certain level defined by the Host, you unlock a new power.\n\nScavenged kills make your kills disappear.\nBombed kills make your kills explode. Be careful when killing, as this can kill your other Apocalypse members if they are near. \nAfter a certain level, you become War.", "WarInfoLong": "(Apocalypse):\nAs War, you are invincible, have a lower kill cooldown, and can kill anyone with your previous powers.\nYour presence is announced to everyone at the meeting after you transform.", @@ -911,12 +901,11 @@ "TraitorInfoLong": "(Neutral):\nDer Betrüger wurde von den Verrätern verraten.\nDu weißt wer die Verräter sind aber sie erkennen dich nicht,\nProblem? Sie können dich killen aber du nicht sie.\n\nBeseitige die Verräter auf andere Weise und kille dann alle um zu gewinnen!", "TrollerInfoLong": "(Neutrals):\nAs a Troller, you can complete tasks so that random events can happen to players.\nFor example, changing the speed of all players, teleportation, influencing sabotage, etc.\nAlso you can win with the winning team.", "VultureInfoLong": "(Neutral):\nAls Geier melde Leichen um zu gewinnen!\n\nWenn du eine Leiche meldest und deine Fresswartezeit ist um isst du die Leiche (sie kann nicht mehr gemeldet werden).\nWenn die Fresswartezeit in Wartezeit ist meldest du die Leiche normal.\n\nZustäzlich meldest du Leichen, wenn du die maximale Fressanzahl pro Runde erreicht hast.", - "AbyssbringerInfoLong": "(Impostors):\nAs the Abyssbringer, you can place black holes. Black holes will suck in players and kill them when colliding with them.", "TaskinatorInfoLong": "(Neutrals):\nAs the Taskinator, whenever you finish a task, the task will be bombed. When another player completes the bombed task, the bomb will detonate, and the player will die.\n\nYou win if you survive till the end and Crew doesn't win.\n\n Note: Taskinator bombs ignore all protection.", "BenefactorInfoLong": "(Besatzung):\nImmer wenn du als Gönner eine Aufgabe erledigst, wird diese markiert. Wenn ein anderer Spieler diese Aufgabe erledigt bekommt er ein temporäres Schild.\n\n Hinweis: Schilde schützen nur vor direkten Kills.", - "MedusaInfoLong": "(Neutral):\nAls Medusa kannst du Leichen versteinern, so wie eine Leiche zu reinigen.\nVersteinerte Leichen können nicht gemeldet werden.\n\nKill alle um zu gewinnen.", + "MedusaInfoLong": "(Neutrals):\nAs the Medusa, you can stone bodies much like cleaning a body.\nStoned bodies cannot be reported.\n\nKill everyone to win.", "SpiritcallerInfoLong": "(Neutrals):\nAs the Spiritcaller, your victims become Evil Spirits after they die. These spirits can help you win by freezing other players briefly or blocking their vision. Alternatively, the spirits can give you a shield that protects you briefly from an attempted kill.", - "AmnesiacInfoLong": "(Neutrals):\nAs the Amnesiac, use your report button to remember a target and get its role.\nTo balance the game, you will not be able to vent after remembering your role if you can't vent as Amnesiac.'", + "AmnesiacInfoLong": "(Neutral):\nAls Dementer benutze den Meldeknopf um dir eine Rolle zu merken.\n\nWenn das Ziel ein Verräter war, wirst du zu einem Flüchtling.\nWenn das Ziel ein Besatzungsmitglied war, wirst du, sofern kompatibel, die Zielrolle (andernfalls wirst du Ingenieur).\nWenn das Ziel ein passiver Neutraler oder ein neutraler Killer war, übernehmimmst du die Rolle, die in den Einstellungen definiert ist.\nWenn das Ziel ein neutraler Mörder einiger weniger Auserwählter war, schlüpfst du in die Rolle, die der Spieler war.", "ImitatorInfoLong": "(Neutrals):\nAs the Imitator, use your kill button to imitate a player.\n\nYou'll either become a Sheriff, a Refugee, or some Neutral.", "BanditInfoLong": "(Neutrals):\nAs the Bandit, you can click your kill button one time to steal a player's addon and twice to kill. Depending on the settings, you may instantly steal the addon or after the meeting starts. After the maximum number of steals is reached, you will kill normally. Additionally, if there are no stealable addons on the target or the target is stubborn, you will kill the target.\n\nKill everyone to win.\n\nNote: Cleansed, Last Impostor, and Lovers cannot be stolen.\nNote: If Bandit can vent is on, Nimble will become unstealable.", "DoppelgangerInfoLong": "(Neutrals):\nAs the Doppelganger, use your kill button to steal a player's identity (their name and skin) and then kill your target.\n\nKill everyone to win.\n\nNote: You cannot steal the target's identity when Camouflage is active.", @@ -925,19 +914,18 @@ "ShroudInfoLong": "(Neutrals):\nAs the Shroud, you do not kill normally.\nInstead, use your kill button to shroud a player.\nShrouded players kill others.\nIf the shrouded player doesn't make a kill, they'll kill themselves after a meeting.\n\nShroud sees shrouded players with a 「◈」mark next to their name.\nShrouded players who did not make a kill will also have the 「◈」mark in meetings, where they'll die if the Shroud is alive by the end of the meeting.", "WerewolfInfoLong": "(Neutral):\nAls der Werwolf kannst du wie andere Killer killen. \nJedoch sterben Spieler in der Nähe wenn du killst.\nJeder Spieler der stirbt hat die Todesursache zerfleischt.\n\nUm das auszugleichen hast du eine höhere Killwartezeit als jeder andere.", "ShamanInfoLong": "(Neutral):\nAls der Schaman kannst du deinen Kill Knopf einmal pro Runde benutzen, um eine Voodoopuppe auszuwählen. Wenn der Kill Knopf an dir benutzt wird, wird der Effekt auf die Voodoopuppe abgeleitet.\nWenn du bis zum Ende überlebst, wirst du mit dem Siegerteam gewinnen.\nAnmerkung: Wenn der Killer das gewählte Ziel nicht töten kann, wird der Mord abgebrochen, doch wenn der Killer den Schamanen nochmal überprüft, wird er den Schamanen töten.", - "SeekerInfoLong": "(Neutrals):\nAs the seeker, use your kill button to tag the target. If the seeker tags the wrong player, a point is deducted, and if the seeker tags the correct player, a point will be added.\nAdditionally, the seeker will not be able to move for 5 seconds after every meeting and after getting a new target.\n\nThe seeker needs to collect a certain number of points set by the Host to win.", + "SeekerInfoLong": "(Neutrals):\nAs the seeker, use your kill button to tag the target. If the seeker tags the wrong player, a point is deducted, and if the seeker tags the correct player, a point will be added.\nAdditionally, the seeker will not be able to move for 5 seconds after every meeting and after getting a new target.\n\nThe seeker needs to collect a certain number of points set by the Host to win.\nSeeker will see a ★ mark on target's name.", "PixieInfoLong": "(Neutral):\nAls Pixie musst du in jeder Runde bis zu x Ziele markieren, indem du sie mit dem Killknopf ausschaltest. Wenn das Treffen beginnt, ist es deine Aufgabe, eines der markierten Ziele auszuschalten. Gelingt dir das nicht, begehst du Selbstmord, es sei denn, du hast keine Ziele markiert oder alle Ziele sind tot. Die ausgewählten Ziele werden nach dem Ende des Treffens auf 0 zurückgesetzt. Wenn du erfolgreich bist, erhältst du einen Punkt. Du siehst alle deine Ziele mit farbigen Namen.\n\nDu gewinnst mit dem Gewinnerteam, wenn du eine bestimmte, vom Host festgelegte Punktzahl erreicht hast.", "SchrodingersCatInfoLong": "(Neutral):\nAls Schrödingers Katze wirst du, wenn jemand versucht den Killknopf an dir zu verwenden, die Aktion blockieren und seinem Team beitreten. Normal hast du keine Siegesbedingung, heißt du kannst erst gewinnen, nachdem du einem Team beigetreten bist. Darüber hinaus wirst als nichts im Spiel gelten.\n\nNotiz: Wenn die Tötungsmaschine versucht dich zu killen, wirst du sterben und die Aktion wird nicht blockiert.", - "RomanticInfoLong": "(Neutrals):\nThe Romantic can pick their lover partner using their kill button (this can be done at any point of the game). Once they've picked their partner, they can use their kill button to give their partner a temporary shield that protects them from attacks. If their lover partner dies, the Romantic's role will change according to the following conditions:\n1. If their partner was an Impostor, the Romantic becomes the Refugee\n2. If their partner was a Neutral Killer, then they become Ruthless Romantic.\n3. If their partner was a Crewmate or a non-killing neutral, the Romantic becomes the Vengeful Romantic. \n\nThe Romantic wins with the winning team if their partner wins.\nNote: If your role changes, your win condition will be changed accordingly", - "RuthlessRomanticInfoLong": "(Neutrals):\nYou change your roles from Romantic if your partner (A neutral killer) is killed. As a Ruthless Romantic, you win if you kill everyone and are the last one standing. If you win, your dead partner will also win with you.", - "VengefulRomanticInfoLong": "(Neutrals):\nYou change your roles from Romantic if your partner (A crew or non-neutral killer) is killed. As a Vengeful Romantic, your goal is to avenge your partner, which means you must kill the killer of your partner. If you succeed, then you and your partner win with the winning team at the end. If you try to kill someone other than your partner's killer, then you will die by misfire.", - "PoisonerInfoLong": "(Neutral):\nAls Vergifter sind deine Kills verzögert.\nKill jeden um zu gewinnen.", - "HexMasterInfoLong": "(Neutral):\nAls der Hexenmeister kannst du Spieler verhexen oder killen.\nEinen Spieler zu verhexen funktioniert genauso wie bei der Hexe.", + "RomanticInfoLong": "(Neutral):\nDer Romantiker kann seinen Liebhaberpartner mit dem Killknopf auswählen (jederzeit während dem Spiel möglich). Danach könnt ihr euch noch einen temporären Schild gegen Angriffe geben. Wenn der Liebhaberpartner stirbt, ändert sich deine Rolle je nach Umstand:\n1. Wenn der Partner ein Verräter war, wirst du zum Flüchtling\n2. Wenn der Partner ein killender Neutraler war, wirst du zum skrupellosen Romantiker.\n3. Wenn der Partner ein Besatzungsmitglied oder nicht-killender Neutraler war, wirst du zum rachsüchtigen Romantiker. \n\nDer Romantiker gewinnt mit dem gewinnenden Team, wenn dein Partner gewinnt.\nHinweis: Wenn deine Rolle wechselt ändert sich auch die Gewinnvoraussetzung", + "RuthlessRomanticInfoLong": "(Neutral):\nDu wirst vom Romantiker zum rücksichtslosen Romantiker, wenn dein Partner (ein killender Neutraler) gestorben ist. Dein Ziel ist es jetzt alle umzulegen, um mit deinem Partner zu gewinnen.", + "VengefulRomanticInfoLong": "(Neutral):\nDu wirst vom Romantiker zum rachsüchtigen Romantiker, wenn dein Partner (ein Besatzungsmitglied oder nicht-killender Neutraler) gestorben ist. Als rachsüchtiger Romantiker musst du jetzt deinen Partner rächen, also den Killer von deinem Partner killen. Wenn du erfolgreich bist gewinnst du mit dem gewinnenden Team. Wenn du den Falschen erwischt erschießt du dich selbst.", + "PoisonerInfoLong": "(Neutrals):\nAs the Poisoner, your kills are delayed.\nKill everyone to win.", + "HexMasterInfoLong": "(Neutrals):\nAs the Hex Master, you can hex players or kill them.\nHexing a player works the same as spelling as a Witch.", "WraithInfoLong": "(Neutral):\nAls das Gespenst kannst du venten um vorübergehend unsichtbar zu werden.\nDu wirst auf deinem Bildschirm sichtbar bleiben. Vente erneut um sichtbar zu werden. Du gewinnst wenn du der letzte lebende Spieler bist.", "JinxInfoLong": "(Neutrals):\nAs the Jinx, whenever you get attacked, you jinx them, resulting in them dying to a jinx.\nThis has limited uses.\n\nKill off everyone to win.", "PotionMasterInfoLong": "(Neutrals):\nAs the Potion Master, you have three different potions assigned to three different actions.\n\nSingle click: Reveal role\nDouble click: Kill\nMap: Sabotage\n\nThe reveal potion has a limit.\nWhen you run out, the kill buttons default to killing.", "NecromancerInfoLong": "(Neutrals):\nAs the Necromancer, you win when you're the last one standing.\nAdditionally when someone tries to kill you, you will block the kill, and you will teleport to a random vent. You will have a limited time to kill your killer. If you succeed in doing so, you live. If the time runs out before you kill your killer, you die permanently. If you try to kill someone else other than your killer, you will die.", - "ShockerInfoLong": "(Neutrals):\nAs the Shocker, you can mark rooms by doing tasks in them, and then vent to Electrocute anyone in those rooms for a set period of time. When you finish all of your tasks, you get new ones. Note: Doing tasks during that period will mark them for the next ability use.", "LastImpostorInfoLong": "(Add-ons):\nThis special effect is given to the last surviving Impostor. It significantly reduces their kill cooldown.", "OverclockedInfoLong": "(Add-ons):\nAs the Overclocked, your kill cooldown is reduced by a percentage.\n\nThis feature is only assigned to roles with a kill button.", "LoversInfoLong": "(Add-ons):\nLovers are a combination of two players. The Lovers win when they are the last ones standing, and their victory is shared. When one of the Lovers wins, the other also wins together. Lovers can see the 「♥」 next to each other's name. If one of the Lovers dies, the other will die in love (may not die in love according to the Host's settings). When one of the Lovers is exiled in the meeting, the other will die and become a dead body that cannot be reported.", @@ -958,7 +946,7 @@ "ParanoiaInfoLong": "(Add-ons):\nTrifft nicht auf Neutrale oder Verräterhelfer zu.\nAls schizophrener, wirst du im Spiel, als 2 Personen betrachtet um darüber zu bestimmen, wann das Spiel endet, weil die Verräter die Mehrheit brauchen. Je nach Einstellungen, hast du ein weiteren vote.", "MimicInfoLong": "(Add-ons):\nNur Verräter können Nachahmer werden. Wenn der Nachahmer stirbt bekommen die anderen Verräter beim nächsten Treffen eine Nachricht, in der die Rollen aufgelistet sind, die der Nachahmer gekillt hat.", "GuesserInfoLong": "(Add-ons):\nAls Guesser kannst du die Rolle von bestimmten Spieler im Notfalltreffen guessen um sie zu killen. Wenn der Guessversuch falsch war, stirbt du sofort.\nDer Befehl zum Guessen ist: /bt [Spieler-ID] [Rolle]\nDu kannst die Spieler-IDs neben jedem Namen der Spieler sehen, oder benutze den Befehl /id um dir alle Spieler-IDs anzeigen zu lassen.", - "NecroviewInfoLong": "(Verräter):\nAls Visionär siehst du den Aufenthaltsort von lebenden Spielern während einem Treffen.\nFolgende Information wird bei den Spielern angezeigt:\n- Roter Name bedeutet Verräter.\n- Türkiser Name bedeutet Besatzung.\n- Grauer Name bedeutet Neutral.", + "NecroviewInfoLong": "(Add-ons):\nThe Necroview can see the teams of dead players. The following info will be displayed on the dead player's name while in a meeting:\n- The Red name indicates the Impostors.\n- The Cyan name indicates the Crewmates.\n- The Gray name indicates the Neutrals.", "ReachInfoLong": "(Add-on)\nOnly roles with a kill button can get this add-on. Unlike everyone else, you have the longest kill range possible in the game.", "BaitInfoLong": "(Erweiterungen):\nWenn der Köder getötet wird, löst der Mörder eine (Selbst)Meldung aus. Jedoch wird das nicht passieren, wenn der Mörder Aasgeier oder Reiniger ist. Die Selbstmeldung kann verzögert auftreten, je nach den Einstellungen des Gastgebers.", "TrapperInfoLong": "(Add-ons):\nWhen Beartrap dies, Beartrap immobilizes killer for a configurable amount of time.", @@ -979,7 +967,7 @@ "LazyInfoLong": "(Add-ons):\nAls Fauler erhältst du nur eine kurze Aufgabe, und du bist immun gegen Hexenmeister, Puppenspieler und Gangster.", "AutopsyInfoLong": "(Add-on):\nAls Autopsie kannst du sehen woran jemand starb.\n\nWird keinem Arzt, Spurensucher, Wissenschaftler, oder Sonniger gegeben werden.", "RebirthInfoLong": "(Add-ons):\nAs the Rebirth, if you're the player about to be ejected, you will swap skins with a random crewmate who voted for you.\nNotice: The host vote never counts\nRebirth will be removed from you if you exhausted all your rebirths.", - "LoyalInfoLong": "(Add-on):\nals loyaler kannst du nicht rekrutiert werden vom Schakal oder Kultisten.\n\nKann keinem neutralen zugewiesen werden.", + "LoyalInfoLong": "(Add-on):\nAls Loyaler kannst du nicht rekrutiert werden vom Schakal oder Kultisten.\n\nKann keinem Neutralen zugewiesen werden.", "EvilSpiritInfoLong": "(Add-ons):\nAs Evil Spirit, it's your job to help the Spiritcaller to victory. You can use your Haunt button to freeze players and reduce their vision. Alternatively, you can use your Haunt button to give the Spiritcaller a shield against a kill attempt temporarily.", "RecruitInfoLong": "(Betrayal Add-ons):\nAs a recruit, you are on the Jackal's team and help out the Jackal and their Sidekicks.\nYou cannot win with your original team.\nDepending on the settings, you may turn into Jackal if old Jackal was killed and no sidekicks is alive.", "AdmiredInfoLong": "(Betrayal Add-ons):\nAs an admired player, you win with the crew and not your original team.\n\nYou can see the Admirer.", @@ -1020,12 +1008,11 @@ "GhastlyInfoLong": "(Besatzung [Geist]): \nNimm als Grausiger eine ahnungslose Person in Besitz und suche dann anschließend ein Opfer für sie aus. Jetzt kann sie den Kill (oder die Killfähigkeit) nur auf das Opfer anwenden, bis du jemand anderen in Besitz nimmst oder die Zeit für die Besessenheit abläuft.", "MinionInfoLong": "(Verräter [Geist]):\nAls Günstling, kannst du Nicht-Verräter für einen Moment erblinden.", "DollMasterInfoLong": "(Verräter):\nDer Marionetten-Meister kann für eine kurze Zeit andere Spieler steuern, indem er den Formwandlungs Knopf drückt und sie seine Schandtaten machen lässt!", - "DoubleAgentInfoLong": "(Impostor):\nAs the Double Agent, you cannot access the kill button. However, you can vote for someone in a meeting to pass a bomb onto them, which can only be done one player at a time. Once the meeting has finished, the bomb will activate and explode in a set amount of time.\nNote: when you pass the bomb onto someone in a meeting, you can vote afterward.\n\nAdditionally depending on settings the Double Agent can diffuse Bastion and Agitator bombs when venting.\n\nThe Double Agent can change roles when they are the Last Imposter, depending on the settings the role can be a Admired Impostor, Trickster, Traitor, or stay as the Double Agent.", + "DoubleAgentInfoLong": "(Verräter):\nDer Doppelagent kann den Killknopf nicht benutzen. Dafür aber kannst du jemanden einmal pro Meeting wählen, um ihm eine Bombe zu geben. Nach dem Meeting wird die Bombe aktiviert und explodiert nach einer gewissen Zeit.\nHinweis: Wenn du die Bombe jemandem verpasst hast, kannst du erneut wie gewohnt abstimmen.\n\nJe nach Einstellungen kannst du zusätzlich die Bomben von Bastion und Agitator durch Venten weitergeben.\n\nDer Doppelagent wird zu einer anderen Rolle, wenn er der letzte Verräter wird, je nach Einstellungen wird er zum Bewunderten Verräter, Gauner, Betrüger oder bleibt Doppelagent.", "SlothInfoLong": "(Add-ons):\nThe Sloth's default movement speed is slower than others.\n(Speed depends on the setting of the Host)", "ProhibitedInfoLong": "(Add-ons):\nAs the Prohibited, you have specific vents that you can't use.\nHow many vents are disabled depends on the Host's settings.", "EavesdropperInfoLong": "(Add-ons):\nAs the Eavesdropper, you have a chance to read other role/addon information-based messages like Mortician or Sleuth.", "ApocalypseInfoLong": "(Apocalypse):\nApocalypse members are on a separate team that works together and wins together. If there are multiple Apocalypse roles in the game, they can see each other's roles.\nDepending on the Host's settings, Apocalypse roles can guess or be guessed.", - "RevenantInfoLong": "(Neutral):\nAs the Revenant, your goal is to be killed. If you are killed, you will take your killer's role and kill your killer instead. You cannot win before being killed.\nNote that Revenant only works when being directly killed.", "ShowTextOverlay": "Text Overlay", "Overlay.GuesserMode": "Guessermodus", "Overlay.NoGameEnd": "Kein Spielende", @@ -1040,7 +1027,7 @@ "AbilityInUse": "Fähigkeit wird genutzt", "AbilityExpired": "Ability expired, {0} uses remain", "RevenantTargeted": "Your role has changed to {0}", - "RevenantCanCopyAddons": "Kann Add-ons stehlen", + "RevenantCanCopyAddons": "Can Steal Addons", "ShowArrows": "Has Arrows pointing toward bodies", "ArrowDelayMin": "Minimum Arrow show-up delay", "ArrowDelayMax": "Maximum Arrow show-up delay", @@ -1370,8 +1357,6 @@ "ShieldedCanUseKillButton": "Shielded player can use ability / kill button", "PlayerIsShieldedByGame": "Player is protected by the game!", "LegacyNemesis": "Ältere Version verwenden", - "LegacyParasite": "Use Legacy Version", - "LegacyTraitor": "Use Legacy Version", "ArsonistKeepsGameGoing": "Feuerteufel lässt das Spiel weiterlaufen", "ArsonistCanIgniteAnytime": "Kann jederzeit das Feuer entfachen", "ArsonistMinPlayersToIgnite": "Mindestbenötigte Übergießungen um zu Entfachen", @@ -1381,17 +1366,17 @@ "DollMasterPossessionDuration": "Steuerungs-Dauer", "DollMasterCanKillAsMainBody": "Can kill as the main body", "DollMasterTargetDiesAfterPossession": "Marionette stirbt nach dem Steuern", - "DoubleAgentCanDiffuseBombs": "Double Agent can diffuse bombs from other roles", - "DoubleAgentClearBombOnMeetingCall": "Diffuse active bomb on meeting call", - "DoubleAgentCanUseAbilityInCalledMeeting": "If diffused can use ability in called meeting", + "DoubleAgentCanDiffuseBombs": "Doppelaggent kann Bomben von anderen Rollen weiterverteilen", + "DoubleAgentClearBombOnMeetingCall": "Aktive Bombe bei Besprechung verteilen", + "DoubleAgentCanUseAbilityInCalledMeeting": "Wenn weitergegeben kann Fähigkeit in gerufener Besprechung nutzen", "DoubleAgentBombExplosionTimer": "Explosionszeit", "DoubleAgentExplosionRadius": "Explosionsradius", "DoubleAgent_DiffusedAgitaterBomb": "Hetzer Bombe erfolgreich verteilt", - "DoubleAgent_DiffusedBastionBomb": "Bastion bomb successfully diffused", - "DoubleAgent_BombExplodesIn": "Bomb Explodes In: {0}s", - "DoubleAgent_BombExploded": "Bomb has exploded!", - "DoubleAgentChangeRoleTo": "Change role on last Imposter", - "DoubleAgentRoleChange": "You have become a: ", + "DoubleAgent_DiffusedBastionBomb": "Bastion-Bombe erfolgreich weitergegeben", + "DoubleAgent_BombExplodesIn": "Bombe explodiert in: {0}s", + "DoubleAgent_BombExploded": "Bombe ist explodiert!", + "DoubleAgentChangeRoleTo": "Wechsle Rolle beim letzten Verräter", + "DoubleAgentRoleChange": "Du wurdest zum: ", "MastermindCD": "Manipulationswartezeit", "MastermindTimeLimit": "Zeitlimit um jemanden zu killen", "MastermindDelay": "Manipulationsbenachrichtigungsverzögerung", @@ -1522,10 +1507,10 @@ "BlackHoleMovesTowardsNearestPlayer": "Black Hole Moves Towards Nearest Player", "BlackHoleMoveSpeed": "Black Hole Moving Speed", "BlackHoleRadius": "Black Hole Consuming Radius", - "AfterTime": "Nach Zeit", + "AfterTime": "After Time", "After1PlayerEaten": "After 1 Player Was Eaten", - "AfterMeeting": "Nach Treffen", - "None": "Keine", + "AfterMeeting": "After Meeting", + "None": "None", "SheriffShotLimit": "Max Anzahl an Schüssen", "SheriffCanKillAllAlive": "Kann killen wenn keiner tot ist", "SheriffCanKillCharmed": "Kann bekehrte Spieler killen", @@ -1542,15 +1527,12 @@ "RebirthUses": "Amount of Rebirths", "RebirthCountVotes": "Only rebirth to players who voted for them", "RebirthFailed": "Ahh, how unfortunate, you did not find any viable souls to swap bodies with", - "FireworkerCooldown": "Placement Cooldown", "ReverieIncreaseKillCooldown": "Erhöhe Killwartezeit", "ReverieMaxKillCooldown": "Maximale Killwartezeit", "ReverieMisfireSuicide": "Fehlschuss bei maximaler Killwartezeit", "ReverieResetCooldownMeeting": "Setze Killwartezeit nach Treffen zurück", "ConvertedReverieKillAll": "Konvertierter Träumer kann alle killen ohne Auswirkungen", "VigilanteNotify": "Du bist zu dem geworden, das du zerstören wolltest", - "DictatorChangeCommandToExpel": "Dictator use Command to expell instad of vote", - "DictatorExpelSelf": "WAIT WAIT WAIT WAT THE HELLLLLL Bro really just want to expel himself", "DoctorTaskCompletedBatteryCharge": "Batterielaufzeit", "SnitchEnableTargetArrow": "Zeige Pfeile zu den Zielen", "SnitchCanGetArrowColor": "Zeige farbige Pfeile basierend an den Teamfarben", @@ -1624,6 +1606,7 @@ "TimeThiefDecreaseMeetingTime": "Weniger Besprechungszeit um", "TimeThiefLowerLimitVotingTime": "Mindest Votingzeit", "TimeThiefReturnStolenTimeUponDeath": "Gestohlene Zeit nach dem Tod zurücksetzen", + "TimeThiefMaxTimeOnAdmired": "Maximum Meeting Time if Time Thief Is Admired", "EvilTrackerCanSeeKillFlash": "Kann Killblitz sehen", "EvilTrackerCanSeeLastRoomInMeeting": "Kann letzten Aufenthaltsraum vom Ziel im Treffen sehen", "EvilTrackerTargetMode": "Kann Ziel sehen", @@ -1631,7 +1614,6 @@ "EvilTrackerTargetMode.OnceInGame": "Einmal pro Spiel", "EvilTrackerTargetMode.EveryMeeting": "Jedes Treffen", "EvilTrackerTargetMode.Always": "Jederzeit", - "ScavengerHasCustomDeathReason": "Enable Custom Death Reason", "EvilHackerCanSeeDeadMark": "Kann die Position von Leichen sehen", "EvilHackerCanSeeImpostorMark": "Kann die Position von Verrätern sehen", "EvilHackerCanSeeKillFlash": "Kann Killblitz sehen", @@ -1869,7 +1851,6 @@ "Jackal_SidekickAssignMode_Recruit": "Only Recruit", "Jackal_SidekickCanKillSidekick": "Kumpane können andere Kumpane killen", "Jackal_SidekickCanKillJackal": "Kumpan kann Schakal killen", - "Jackal_RecruitFailed": "You can not recruit this player!", "JackalCanKillSidekick": "Schakal kann Kumpan killen", "Jackal_SidekickCanKillWhenJackalAlive": "Sidekick can kill while Jackal is Alive", "Jackal_SidekickTurnIntoJackal": "Sidekick can turn into Jackal after its death", @@ -1916,9 +1897,6 @@ "VipTag": "VIP★", "ApplyVipList": "Apply VIP List", "AllowSayCommand": "Erlaube Moderatoren den /say -Befehl zu nutzen", - "AllowStartCommand": "Allow moderators to use /start command", - "StartCommandMinCountdown": "Minimum countdown for /start command", - "StartCommandMaxCountdown": "Maximum countdown for /start command", "KickCommandDisabled": "Der Kick-Befehl ist momentan deaktiviert.", "KickCommandNoAccess": "Du hast keinen Zugriff zum Kick-Befehl.", "KickCommandInvalidID": "Invalid player ID specified.\nPlease use '/kick [playerID] [reason]' to kick a player.\nExample :- /kick 5 not following rules", @@ -1951,11 +1929,6 @@ "WarnCommandNoAccess": "Du hast keinen Zugriff zum Warn-Befehl.", "WarnCommandInvalidID": "Falsche Spieler ID.\nNutze '/warn [Spieler ID] [Grund]' um einen Spieler zu warnen. \nBeispiel :- /warn 5 Lavachatting", "WarnCommandWarnHost": "Du bist nicht berechtigt, den Host zu verwarnen.", - "StartCommandNoAccess": "You do not have access to the start command.", - "StartCommandDisabled": "The start command is currently disabled.", - "StartCommandCountdown": "ERROR\n\nThe game is already starting!", - "StartCommandStarted": "The game has been started by {0}!", - "StartCommandInvalidCountdown": "ERROR\n\nThe countdown must be between {0} and {1}!", "WarnCommandWarnMod": "Du bist nicht berechtigt, andere Moderatoren zu verwarnen.", "WarnCommandWarned": "wurde verwarnt. Es werden keine weiteren Verwarnungen ausgesprochen und angemessene Reaktionen erfolgen \n ", "WarnExample": "Use /warn [id] [reason] in future. \nExample :-\n /warn 5 lava chatting", @@ -1982,9 +1955,9 @@ "DeathReason.Sacrifice": "Geopftert", "DeathReason.Quantization": "Quantization", "DeathReason.Overtired": "Übermüdet", - "DeathReason.Ashamed": "Beschämt", - "DeathReason.Consumed": "Verbraucht", - "DeathReason.PissedOff": "Zerstört", + "DeathReason.Ashamed": "Ashamed", + "DeathReason.Consumed": "Consumed", + "DeathReason.PissedOff": "Destroyed", "DeathReason.Dismembered": "Dismembered", "DeathReason.LossOfHead": "Strangled", "DeathReason.Trialed": "Verurteilt", @@ -2008,7 +1981,7 @@ "DeathReason.Equilibrium": "Equilibrium", "DeathReason.Sacrificed": "Sacrificed", "DeathReason.Electrocuted": "Electrocuted", - "DeathReason.Scavenged": "Gefressen", + "DeathReason.Scavenged": "Scavenged", "OnlyEnabledDeathReasons": "Only Enabled Death Reasons", "Alive": "Lebendig", "Disconnected": "Disconnected", @@ -2024,10 +1997,11 @@ "DeputyHandcuffCooldown": "Handschellenwartezeit", "DeputyHandcuffMax": "Maximale Handschellen", "DeputyHandcuffedPlayer": "Ziel gefesselt", - "HandcuffedByDeputy": "Du wurdest gefesselt!", - "DeputyInvalidTarget": "Ziel kann nicht gefesselt werden", + "HandcuffedByDeputy": "You were handcuffed!\nNow you have broken your handcuff and can kill again.", + "DeputyInvalidTarget": "Target is already handcuffed", + "HandcuffBrokenAfterMeeting": "Remove all handcuffs after meeting", "DeputyHandcuffText": "Handschellen", - "DeputyHandcuffCDForTarget": "Killwartezeit für gefesselten Spieler", + "DeputyHandcuffCDForTarget": "Next Kill Cooldown for handcuffed player", "RejectShapeshift.AbilityWasUsed": "Fähigkeit bereits genutzt", "EscapisMtarkedPosition": "You marked self-position", "InvestigateCooldown": "Investigate Cooldown", @@ -2087,7 +2061,6 @@ "ShowMadmatesInLeftCommand": "Show Madmates (including add-ons)", "ShowApocalypseInLeftCommand": "Show Neutral Apocalypse", "SeeEjectedRolesInMeeting": "See ejected roles in meetings", - "ThankYouForUsingTOHE": "Thank you for using TOHE!", "SkillUsedLeft": "You have activated your skill to call a meeting. \nRemaining amount of uses left:", "NemesisDeadMsg": "Der Tod des Nemesis bedeutet der Anfang von der Rache. \nBitte nutze /rv + [Spieler ID] um einen bestimmten Spieler zu killen. \nDu kannst die Spieler IDs vor dem Namen sehen oder schreibe /rv um eine Liste der IDs zu sehen", "NemesisAliveKill": "Die Rache des Nemesis kann nur nach seinem Tod beginnen.", @@ -2107,7 +2080,6 @@ "GuessNotifiedBait": "Bait can't be guessed because it was announced. You thought it would be that easy, right?", "GuessGM": "Du kannst den GM nicht guessen, der ist schon tot... Warum würdest du das dem armen Host antun?", "GuessGuardianTask": "Du kannst den Wächter der seine Aufgaben abgeschlossen hat nicht guessen.", - "GuardianCantKilled": "You can't kill a Guardian who has finished their tasks.", "GuessMarshallTask": "Du kannst den Marschall der seine Aufgaben abgeschlossen hat nicht guessen.", "GuessObviousAddon": "Offenbarte Add-ons können nicht geguessed werden.", "GuessAdtRole": "Die Hosteinstellungen erlauben das Guessen für Add-ons nicht", @@ -2163,7 +2135,6 @@ "BecomeMadmateCuzMadmateMode": "Du bist aufgrund deines Todes zum Verräterhelfer geworden", "CleanerCleanBody": "Die Leiche wurde gereinigt", "QuickShooterStoraging": "Kugel gespeichert", - "QuickShooterFailed": "You are still in cooldown.", "PoisonerTargetDead": "Ziel gekillt", "HexesLookLikeSpells": "Hexes appear as spells", "HexButtonText": "Verhexen", @@ -2308,7 +2279,7 @@ "Message.TryFixName": "An attempt was made to fix hidden message content due to roles", "Message.CanNotFindRoleThePlayerEnter": "Konnte die Rolle nicht finden\nNutze den /r -Befehl um eine Rollenliste anzuzeigen", "Message.PlayerQuitForever": "{0} decided to leave voluntarily \nSorry for the bad gaming experience \nI really worked hard to make progress", - "Message.MadmateSelfVoteModeNotify": "Please note: The current Madness generation mode is [{0}]\n Voting for yourself means you want to be Madmate. If you meet the conditions to become Madmate and there are still spaces left, you will immediately become Madmate", + "Message.MadmateSelfVoteModeNotify": "Hinweis: Der aktuelle Verräterhelfergenerierungsmodus ist [{0}]\n Selbstabstimmung heißt, dass du Verräterhelfer werden willst. Wenn du die Voraussetzungen erfüllst und genug Plätze übrig sind, wirst du sofort Verräterhelfer", "Message.HostLeftGameInGame": "★Warning★ Host left the game, and the game wouldn't start normally next time. Please exit the lobby or wait until the new Host opens a lobby.", "Message.HostLeftGameInLobby": "★Warning★ Host left the game, and the game wouldn't start normally next time. If the new Host has TOHE, you need to re-enter the lobby to play normally.", "Message.HostLeftGameNewHostIsMod": "★Warning★ Original Host left the game and {0} become the new Host! \nThe room is still modded, start a game and end it immediately to reset the lobby!", @@ -2322,7 +2293,6 @@ "Message.YTPlanNotice": "Hinweis: Der [YouTuber Plan] ist aktiviert. Das heißt, der Host kann seine Rolle in der nächsten Runde selbst auswählen, damit es einfacher wird, Videomaterial zu bekommen. Wenn der Host diese Funktion falsch ausnutzt, verlasse das Spiel und melde es.\nAktueller Creatornachweis:", "Message.OnlyCanBeUsedByHost": "FEHLER\n\nDieser Befehl wird nur vom Host genutzt.", "Message.MaxPlayers": "Maximum players set to ", - "Message.MaxPlayersFailByRegion": "Could not set max players: Vanilla regions support a maximum of 15 players.", "Message.GhostRoleInfo": "Ghost Role Info\nHiya! A little about ghost roles...\n\nGhost roles drastically impact the game, so it's not recommended for smaller lobbies if you're unfamiliar. If not explicitly stated otherwise in the description, the Guard button is their ability button ;)\n\nSpawning:\nGhost-roles only spawn after death; the first x people from (team) to die get them.\n\nPS: If your previous role didn't have tasks(e.g., sheriff), your tasks as a ghost-role aren't needed for task-win", "ApocalypseInfoTitle": "Neutral Apocalypse Info:", "Message.ApocalypseInfo": "Every role of the <#ff174f>Apocalypse Team has their own objective to carry out in order to transform.\n<#2B0804>Transformed <#ff174f>Apocalypse members have a drastic change on the game and are immortal (except for being voted), but everyone will be notified that they have transformed.\n\nRoles: <#e5f6b4>Plaguebearer, <#A675A1>Soul Collector, <#bf9f7a>Baker, <#cc0044>Berserker\nTransformed: <#343136>Pestilence, <#644661>Death, <#83461c>Famine, <#2B0804>War\n\nApocalypse members can see eachother's roles and ability icons.\nLike Neutral Killers, Apocalypse members keep the game going as well, have fun!", @@ -2412,7 +2382,7 @@ "CrewCanBeGuesser": "Besatzungsmitglieder können zu Guessern werden", "NeutralCanBeGuesser": "Neutrale können zu Guessern werden", "CrewCanBeMundane": "Besatzung kann Weltlicher werden", - "NeutralCanBeMundane": "Neutral kann Weltlicher werden", + "NeutralCanBeMundane": "Neutrale können Weltliche(r) werden", "GuessedAsMundane": "You're Mundane.\nYou can't guess until you finish all the tasks", "ObliviousBaitImmune": "Immun zur Fähigkeit vom Killköder", "ImpCanBeInLove": "Verräter können verliebt sein", @@ -2454,6 +2424,7 @@ "LastResult": "★ Spielergebnisse", "LastEndReason": "★ Grundende", "KillLog": "Killprotokoll", + "MainRoleLog": "Role Convert Log", "Maximum": "Max", "RoleRate": "EIN", "RoleOn": "ALWAYS", @@ -2640,7 +2611,7 @@ "NeutralRemain": "\n{0} Neutral Killers remain", "OneNeutralRemain": "\n{0} Neutral Killer remains", "ApocRemain": "\n{0} Neutral Apocalypse remains", - "GameOverReason.HumansByVote": "Alle Verräter und neutralen Killer wurden rausgeworfen der gekillt", + "GameOverReason.HumansByVote": "All Impostors and Neutral Killers were ejected or killed", "GameOverReason.HumansByTask": "Die Besatzungsmitglieder haben alle Aufgaben erledigt", "GameOverReason.HumansDisconnect": "Besatzungsmitglieder getrennt", "GameOverReason.ImpostorByVote": "Die Besatzungsmitglieder wurden rausgeworfen", @@ -2729,10 +2700,10 @@ "SoulCollectorCanVent": "Soul Collector can Vent", "DeathMeetingTimeIncrease": "Increased Meeting time when Death exists", "SoulCollectorMeetingDeath": "Your target has died during the meeting. You have gained a soul.", - "SoulCollectorKillButtonText": "Vorhersagen", + "SoulCollectorKillButtonText": "Predict", "SoulCollectorHasImpostorVision": "Soul Collector has Impostor vision", "ApocalypseIsNigh": "[ The Apocalypse Is Nigh! ]", - "ApocalypseImmune": "This role is immune!", + "ApocalypseImmune": "This player is immune because they are invincible!", "BakerToFamine": "You have become Famine!!!", "BakerTransform": "The Baker has transformed into Famine, Horseman of the Apocalypse! A famine has begun!", "BakerAlreadyBreaded": "That player already has bread!", @@ -2740,17 +2711,17 @@ "BakerBreaded": "Player given bread", "BakerBreadNeededToTransform": "Required number of bread to become Famine", "BakerCantBreadApoc": "You cannot give other Apocalypse members bread!", - "BakerKillButtonText": "Brot", - "BakerUnshiftButtonText": "Brot wechseln", - "BakerRevealBread": "Aufdecken", - "BakerRoleblockBread": "Rollenblock", - "BakerBarrierBread": "Barriere", + "BakerKillButtonText": "Bread", + "BakerUnshiftButtonText": "Switch Bread", + "BakerRevealBread": "Reveal", + "BakerRoleblockBread": "Roleblock", + "BakerBarrierBread": "Barrier", "BakerCurrentBread": "Current Bread: ", "BakerSwitchBread": "Bread Switched to: ", - "BakerCanVent": "Baker can Vent", + "BakerCanVent": "Baker can Vent", "BakerBreadGivesEffects": "Bread gives additional effects", "BakerTransformNoMoreBread": "Baker transforms if they do not have enough bread", - "FamineKillButtonText": "Hungern", + "FamineKillButtonText": "Starve", "FamineStarveCooldown": "Famine starve cooldown", "FamineCantStarveApoc": "You cannot starve other Apocalypse members!", "FamineAlreadyStarved": "That player has already been starved!", @@ -2796,7 +2767,6 @@ "GodfatherTargetCountMode": "Killer turns into", "GodfatherCount_Refugee": "Refugee", "GodfatherCount_Madmate": "Madmate", - "GodfatherRefugeeMsg": "You have been recruited by GodFather!", "MissChance": "Chance To Miss", "IncreaseByOneIfConvert": "Increase The KillCount +1 If a Crew Is Converted", "HawkMissed": "Verfehlt!", @@ -2829,7 +2799,6 @@ "BerserkerToWar": "You have become War!!!", "BerserkerTransform": "The Berserker has transformed into War, Horseman of the Apocalypse! Cry 'Havoc!', and let slip the dogs of war.", "WarKillCooldown": "War kill cooldown", - "BerserkerCanKillTeamate": "Can kill other Neutral Apocalypse", "BlackmailerSkillCooldown": "Erpresser Wartezeit", "BlackmailerMax": "Maximale Anzahl dem Sprechen von erpressten Spieler", "BlackmailerDead": "Achtung!{0} Wurde erpresst vom Erpresser!", @@ -2919,8 +2888,6 @@ "RememberedPursuer": "Du erinnerst dich, dass du ein Häscher bist!", "RememberedFollower": "Du erinnerst dich, dass du ein Folger bist!", "RememberedAmnesiac": "Du hast deine Rolle vergessen.", - "AmnesiacRemembered": "You remembered you were {0}!", - "ReportWhenFailedRemember": "Report Dead Body when failed to remember", "RememberedImitator": "You remembered you were an Imitator.", "RememberedImpostor": "Du erinnerst dich, dass du ein Verräter bist!", "RememberedCrewmate": "Du erinnerst dich, dass du ein Besatzungsmitglied bist!", @@ -3031,7 +2998,7 @@ "MaulRadius": "Maul Radius", "ImpKnowCyberDead": "Impostors know if Cyber died", "CrewKnowCyberDead": "Crewmates know if Cyber died", - "NeutralKnowCyberDead": "Neutrals know if Cyber died", + "NeutralKnowCyberDead": "Neutrale wissen wenn Cyber gestorben ist", "CyberKnown": "Everyone can see Cyber", "KillerGetBewilderVision": "Killer gets Bewilder's vision", "ImpCanBeOiiai": "Verräter können OIIAI sein", @@ -3040,7 +3007,7 @@ "OiiaiCanPassOn": "OIIAI an den Killer weitergeben", "NeutralChangeRolesForOiiai": "Neutrale werden zu ", "LostRoleByOiiai": "Deine Rolle wurde vom OIIAI ausradiert!", - "ImpCanBeLoyal": "Impostors can become Loyal", + "ImpCanBeLoyal": "Verräter können Loyaler werden", "CrewCanBeLoyal": "Crewmates can become Loyal", "TasklessCrewCanBeLazy": "Besatzungsmitglieder ohne Aufgaben können Fauler werden", "TaskBasedCrewCanBeLazy": "Aufgabenbasierte Besatzungsmitglieder können Fauler werden", @@ -3146,7 +3113,7 @@ "DollMaster_PossessedTarget": "Steuernde Marionette", "DollMaster_CannotPossessImpTeammate": "Du kannst den Verräter-Kollegen nicht steuern", "DollMaster_CouldNotSwapWithTarget": "Du kannst diesen Spieler nicht steuern", - "DollMaster_CanNotSwapWithDeadTarget": "Du kannst einen toten Spieler nicht steuern", + "DollMaster_CanNotSwapWithDeadTarget": "Possessing a dead player isn't possible", "DollMaster_MainBody": "Hauptkörper", "DollMaster_Doll": "Marionette", "DollMaster_UnableToUseAbility": "Du kannst deine Fähigkeit an diesem Spieler nicht nutzen", @@ -3334,30 +3301,29 @@ "PixieTargetAlreadySelected": "Ziel ist bereits ausgewählt", "PixieButtonText": "Markieren", "PlagueBearerCooldown": "Pest Wartezeit", - "PlagueBearerCanVent": "Kann venten", + "PlagueBearerCanVent": "Can vent", "PlagueBearerHasImpostorVision": "Has Impostor vision", "PestilenceCooldown": "Seuche kill Wartezeit", "PestilenceCanVent": "Seuche kann venten", "PestilenceHasImpostorVision": "Seuche hat Verräter Sichtweite", - "PestilenceKillGuessers": "Kill players who guess Pestilence", "PlagueBearerAlreadyPlagued": "Spieler ist schon verpestet", "PlagueBearerToPestilence": "Du bist die Seuche geworden!!", "GuessPestilence": "Du hast versucht die Seuche zu killen!\n\nDie Seuche killte dich.", "PestilenceTransform": "A Plague has consumed the Crew, transforming the Plaguebearer into Pestilence, Horseman of the Apocalypse!", - "RomanticBetCooldown": "Pick Partner Cooldown", + "RomanticBetCooldown": "Partnerwahl-Wartezeit", "RomanticProtectCooldown": "Schutzwartezeit", - "RomanticBetPlayer": "You picked your partner", - "RomanticBetOnYou": "The Romantic chose you as their Partner!", - "VengefulKCD": "Vengeful Romantic Kill Cooldown", - "VengefulCanVent": "Vengeful Romantic Can Vent", - "RuthlessKCD": "Ruthless Romantic Kill Cooldown", - "RuthlessCanVent": "Ruthless Romantic Can Vent", - "RomanticProtectPartner": "Your partner is under protection", - "RomanticIsProtectingYou": "The Romantic is protecting you", + "RomanticBetPlayer": "Du hast deinen Partner ausgewählt", + "RomanticBetOnYou": "Der Romantiker hat dich zu deinem Partner erwählt!", + "VengefulKCD": "rachsüchtiger Romantiker Killwartezeit", + "VengefulCanVent": "rachsüchtiger Romantiker Kann venten", + "RuthlessKCD": "rücksichtsloser Romantiker Killwartezeit", + "RuthlessCanVent": "rücksichtsloser Romantiker Kann venten", + "RomanticProtectPartner": "Dein Partner ist geschützt", + "RomanticIsProtectingYou": "Der Romantiker beschützt dich", "ProtectingOver": "Shield expired", "RomanticProtectDuration": "Schutzdauer", - "RomanticKnowTargetRole": "Romantic knows their target's role", - "RomanticBetTargetKnowRomantic": "Target knows who the Romantic is", + "RomanticKnowTargetRole": "Romantiker weiß die Rolle seines Zieles", + "RomanticBetTargetKnowRomantic": "Ziel weiß, wer der Romantiker ist", "RomanticPartnerButtonText": "Partner auswählen", "RomanticProtectButtonText": "Schützen", "GuessMasterMisguess": "{0} hat sich verguessed", @@ -3383,7 +3349,6 @@ "EveryoneCanKnowMini": "Everyone can see the Mini", "CanBeEvil": "Mini kann Verräter sein", "EvilMiniSpawnChances": "Probability of Mini being an Impostor", - "EvilMiniCanBeGuessed": "Evil Mini can be guessed before 18", "GuessMini": "Sorry, you can't hurt a kid Mini.", "GrowUpDuration": "Time required to grow (s)", "MajorCooldown": "Kill Cooldown when over 18", @@ -3519,13 +3484,13 @@ "WinnerRoleText.NiceMini": "Guter Mini gewinnt!", "WinnerRoleText.Mini": "Nice Mini was killed", "WinnerRoleText.Bandit": "Bandit gewinnt!", - "WinnerRoleText.RuthlessRomantic": "Ruthless Romantic Wins!", + "WinnerRoleText.RuthlessRomantic": "Rücksichtsloser Romantiker gewinnt!", "WinnerRoleText.Solsticer": "Sonnenwender gewinnt!", "WinnerRoleText.Pyromaniac": "Pyromane gewinnt!", "WinnerRoleText.Doppelganger": "Doppelganger Wins!", "WinnerRoleText.Quizmaster": "Quizmaster Wins!", "WinnerRoleText.Agitater": "Hetzer gewinnt!", - "WinnerRoleText.Shocker": "Schocker gewinnt!", + "WinnerRoleText.Shocker": "Shocker Wins!", "AdditionalWinnerRoleText.Sidekick": "Kumpan", "AdditionalWinnerRoleText.Taskinator": "Taskinator", "AdditionalWinnerRoleText.Opportunist": "Opportunist", @@ -3544,7 +3509,7 @@ "AdditionalWinnerRoleText.Pixie": "Fee", "AdditionalWinnerRoleText.NiceMini": "Guter Mini", "AdditionalWinnerRoleText.Romantic": "Romantiker", - "AdditionalWinnerRoleText.VengefulRomantic": "Vengeful Romantic", + "AdditionalWinnerRoleText.VengefulRomantic": "Rachsüchtiger Romantiker", "AdditionalWinnerRoleText.SchrodingersCat": "Schrödingers Katze", "AdditionalWinnerRoleText.Troller": "Troller", "ErrorEndText": "Ein Fehler ist aufgetreten", @@ -3611,7 +3576,7 @@ "SolsticerOnMeeting": "Du hast zu viele Tote überlebt! Nächste Runde wirst du {0} weitere kleinere Aufgaben haben!", "SolsticerTitle": "Sonnenwender", "GuessSolsticer": "Du kannst den Sonnenwender nicht guessen!", - "ExpelSolsticer": "Sorry, but you can not expel Solsticer!", + "VoteSolsticer": "Du kannst den Sonnenwender nicht voten!", "SolsticerTasksReset": "Deine Aufgaben werden zurückgesetzt!", "SolsticerMisGuessed": "Du hast dich verguesst! Du kannst daher nicht mehr guessen.", "SolsticerGuessMax": "Weil du dich verguesst hast, kannst du nicht mehr guessen.", @@ -3721,9 +3686,9 @@ "ShockerCanShockHimself": "Can Shock Himself", "ShockerImpostorVision": "Shocker has Impostor vision", "ShockerIsShocking": "You're already shocking!", - "ShockerAbilityActivate": "Beginne Schock!", + "ShockerAbilityActivate": "Begin Shocking!", "ShockerAbilityDeactivate": "Ability Deactivated", - "ShockerVentButtonText": "Elektrisieren", + "ShockerVentButtonText": "Shock", "ShockerRoomMarked": "Marked Room", "EavesdropperMsgTitle": "You found a secret", "EavesdropPercentChance": "Chance to eavesdrop", @@ -3736,4 +3701,4 @@ "PolicPreventRecruitNonKiller": "Prevent recruit players without kill button", "PolicSuidiceWhenTargetNotKiller": "Suidices when recruit a non killer or non crewmate", "PolicPassConverted": "Can pass Converted Addon to Sheriff" -} +} \ No newline at end of file diff --git a/Resources/Lang/en_US.json b/Resources/Lang/en_US.json index a68077068..a1329a43f 100644 --- a/Resources/Lang/en_US.json +++ b/Resources/Lang/en_US.json @@ -1,1550 +1,1563 @@ { - "LanguageID": "0", - "HostText": "Host", - "HostColor": "#902efd", - "IconColor": "#4bf4ff", - "Icon": "♥", - "NameColor": "#ffc0cb", - - "HideHostText": "Hide 'Host♥' Text", - "HideAllTagsAndText": "Hide All Tags (for «AutoMuteUs»)", - - "SupportUs": "Support Us", - "update": "Update", - "GitHub": "GitHub", - "Discord": "Discord", - "Website": "Website", - "PlayerNameForRoleInfo": "Hi {0}, your role is:- \n", - - "HostIconInMeeting": "HOST: {0}", - - "SubText.GM": "Spectate the chaos!", - "SubText.Crewmate": "Find and exile the Impostors", - "SubText.Impostor": "Sabotage and kill everyone", - "SubText.Neutral": "Work alone to achieve your victory", - "SubText.Apocalypse": "Become unstoppable with your team", - "SubText.Madmate": "Help the Impostors", + "LanguageID": "0", + "HostText": "Host", + "HostColor": "#902efd", + "IconColor": "#4bf4ff", + "Icon": "♥", + "NameColor": "#ffc0cb", + + "HideHostText": "Hide 'Host♥' Text", + "HideAllTagsAndText": "Hide All Tags (for «AutoMuteUs»)", + + "SupportUs": "Support Us", + "update": "Update", + "GitHub": "GitHub", + "Discord": "Discord", + "Website": "Website", + "PlayerNameForRoleInfo": "Hi {0}, your role is:- \n", + + "HostIconInMeeting": "HOST: {0}", + + "SubText.Crewmate": "Find and exile the Impostors", + "SubText.Impostor": "Sabotage and kill everyone", + "SubText.Neutral": "Work alone to achieve your victory", + "SubText.Apocalypse": "Become unstoppable with your team", + "SubText.Madmate": "Help the Impostors", "SubText.Lovers": "Stay alive and win together", "SubText.Egoist": "Win on your own", - "TypeImpostor": "Impostors", - "TypeCrewmate": "Crewmates", - "TypeNeutral": "Neutrals", - "TypeAddon": "Add-ons", - "GuesserMode": "Guesser Mode", + "TypeImpostor": "Impostors", + "TypeCrewmate": "Crewmates", + "TypeNeutral": "Neutrals", + "TypeAddon": "Add-ons", + "GuesserMode": "Guesser Mode", - "TeamImpostor": "Impostor", - "TeamNeutral": "Neutral", - "TeamCrewmate": "Crewmate", - "TeamMadmate": "Madmate", + "TeamImpostor": "Impostor", + "TeamNeutral": "Neutral", + "TeamCrewmate": "Crewmate", + "TeamMadmate": "Madmate", "TeamLovers": "Lovers", "TeamEgoist": "Egoist", "TeamApocalypse": "Apocalypse", - "YouAreCrewmate": "You are a Crewmate", - "YouAreImpostor": "You are an Impostor", - "YouAreNeutral": "You are a Neutral", - "YouAreMadmate": "You are a Madmate", - - - "Role_Crewmate": "Crewmate", - "Role_Jester": "Jester", - "Role_Opportunist": "Opportunist", - "Role_Celebrity": "Celebrity", - "Role_Bodyguard": "Bodyguard", - "Role_Dictator": "Dictator", - "Role_Mayor": "Mayor", - "Role_Doctor": "Doctor", - "Role_Maverick": "Maverick", - "Role_Pursuer": "Pursuer", - "Role_Follower": "Follower", - "Role_Amnesiac": "Amnesiac", - "Role_Imitator": "Imitator", - "Role_Sheriff": "Sheriff", - "Role_Knight": "Knight", - "Role_Deputy": "Deputy", - "Role_AdmiredImpostor": "Admired Impostor", - "Role_Trickster": "Trickster", - "Role_Traitor": "Traitor", - "Role_NoChange": "Don't change the role", - "Role_Random": "Random role from list", - - "CrewmatesCanGuess": "Crewmates can guess", - "ImpostorsCanGuess": "Impostors can guess", - "NeutralKillersCanGuess": "Neutral Killers can guess", - "NeutralApocalypseCanGuess": "Neutral Apocalypse can guess", - "PassiveNeutralsCanGuess": "Passive Neutrals can guess", - - "CanGuessAddons": "Can Guess Add-ons", - "ShowOnlyEnabledRolesInGuesserUI": "Show Only Enabled Roles In Guesser UI", - "CrewCanGuessCrew": "Crewmates Can Guess Crewmate Roles", - "ImpCanGuessImp": "Impostors Can Guess Impostor Roles", - "ApocCanGuessApoc": "Neutral Apocalypse Can Guess Neutral Apocalypse Roles", - "GuessImmune": "Sorry, but target is immune to being guessed!", - - - "GM": "Game Master", - "Sunnyboy": "Sunnyboy", - "Bard": "Bard", - "Crewmate": "Crewmate", - "CrewmateTOHE": "Crewmate", - "Engineer": "Engineer", - "EngineerTOHE": "Engineer", - "Scientist": "Scientist", - "ScientistTOHE": "Scientist", - "Noisemaker": "Noisemaker", - "NoisemakerTOHE": "Noisemaker", - "Tracker": "Tracker", - "TrackerTOHE": "Tracker", - "GuardianAngel": "Guardian Angel", - "GuardianAngelTOHE": "Guardian Angel", - "Impostor": "Impostor", - "ImpostorTOHE": "Impostor", - "Shapeshifter": "Shapeshifter", - "ShapeshifterTOHE": "Shapeshifter", - "Phantom": "Phantom", - "PhantomTOHE": "Phantom", - - "BountyHunter": "Bounty Hunter", - "Fireworker": "Fireworker", - "Mercenary": "Mercenary", - "ShapeMaster": "Shapemaster", - "Vampire": "Vampire", - "Warlock": "Warlock", - "Ninja": "Ninja", - "Zombie": "Zombie", - "Anonymous": "Anonymous", - "Miner": "Miner", - "KillingMachine": "Killing Machine", - "Escapist": "Escapist", - "Witch": "Witch", - "Nemesis": "Nemesis", - "Bloodmoon": "Bloodmoon", - "Possessor": "Possessor", - "Puppeteer": "Puppeteer", - "Mastermind": "Mastermind", - "TimeThief": "Time Thief", - "Sniper": "Sniper", - "Undertaker": "Undertaker", - "RiftMaker": "Rift Maker", - "EvilTracker": "Evil Tracker", - "EvilHacker": "Evil Hacker", - "EvilGuesser": "Evil Guesser", - "AntiAdminer": "Anti Adminer", - "Arrogance": "Arrogance", - "Bomber": "Bomber", - "Scavenger": "Scavenger", - "Trapster": "Trapster", - "Gangster": "Gangster", - "Cleaner": "Cleaner", - "Lightning": "Lightning", - "Greedy": "Greedy", - "CursedWolf": "Cursed Wolf", - "SoulCatcher": "Soul Catcher", - "QuickShooter": "Quick Shooter", - "Camouflager": "Camouflager", - "Eraser": "Eraser", - "Butcher": "Butcher", - "Hangman": "Hangman", - "Swooper": "Swooper", - "Crewpostor": "Crewpostor", - "Wildling": "Wildling", - "Trickster": "Trickster", - "Vindicator": "Vindicator", - "Parasite": "Parasite", - "Disperser": "Disperser", - "Inhibitor": "Inhibitor", - "Saboteur": "Saboteur", - "Councillor": "Councillor", - "Dazzler": "Dazzler", - "YinYanger": "YinYanger", - "Deathpact": "Deathpact", - "Devourer": "Devourer", - "Consigliere": "Consigliere", - "Morphling": "Morphling", - "Twister": "Twister", - "Lurker": "Lurker", - "Visionary": "Visionary", - "Refugee": "Refugee", - "Underdog": "Underdog", - "Ludopath": "Ludopath", - "Godfather": "Godfather", - "Chronomancer": "Chronomancer", - "Pitfall": "Pitfall", - "EvilMini": "Evil Mini", - "Blackmailer": "Blackmailer", - "Instigator": "Instigator", - "LazyGuy": "Lazy Guy", - "SuperStar": "Super Star", - "Celebrity": "Celebrity", - "Cleanser": "Cleanser", - "Keeper": "Keeper", - "Knight": "Knight", - "Mayor": "Mayor", - "Psychic": "Psychic", - "Mechanic": "Mechanic", - "Sheriff": "Sheriff", - "Vigilante": "Vigilante", - "Jailer": "Jailer", - "CopyCat": "Copycat", - "Snitch": "Snitch", - "Marshall": "Marshall", - "Doctor": "Doctor", - "Dictator": "Dictator", - "Detective": "Detective", - "NiceGuesser": "Nice Guesser", - "GuessMaster": "Guess Master", - "Transporter": "Transporter", - "TimeManager": "Time Manager", - "Spurt": "Spurt", - "Veteran": "Veteran", - "Bastion": "Bastion", - "Bodyguard": "Bodyguard", - "Deceiver": "Deceiver", - "Grenadier": "Grenadier", - "Medic": "Medic", - "FortuneTeller": "Fortune Teller", - "Judge": "Judge", - "Mortician": "Mortician", - "Medium": "Medium", - "Pacifist": "Pacifist", - "Observer": "Observer", - "Monarch": "Monarch", - "Overseer": "Overseer", - "Coroner": "Coroner", - "Merchant": "Merchant", - "President": "President", - "Hawk": "Hawk", - "Retributionist": "Retributionist", - "Deputy": "Deputy", - "Investigator": "Investigator", - "Guardian": "Guardian", - "Addict": "Addict", - "Mole": "Mole", - "Alchemist": "Alchemist", - "Tracefinder": "Tracefinder", - "Oracle": "Oracle", - "Spiritualist": "Spiritualist", - "Chameleon": "Chameleon", - "Inspector": "Inspector", - "Captain": "Captain", - "Admirer": "Admirer", - "TimeMaster": "Time Master", - "Crusader": "Crusader", - "Altruist": "Altruist", - "Reverie": "Reverie", - "Lookout": "Lookout", - "Telecommunication": "Telecommunication", - "Lighter": "Lighter", - "TaskManager": "Task Manager", - "Witness": "Witness", - "Swapper": "Swapper", + "YouAreCrewmate": "You are a Crewmate", + "YouAreImpostor": "You are an Impostor", + "YouAreNeutral": "You are a Neutral", + "YouAreMadmate": "You are a Madmate", + + + "Role_Crewmate": "Crewmate", + "Role_Jester": "Jester", + "Role_Opportunist": "Opportunist", + "Role_Celebrity": "Celebrity", + "Role_Bodyguard": "Bodyguard", + "Role_Dictator": "Dictator", + "Role_Mayor": "Mayor", + "Role_Doctor": "Doctor", + "Role_Maverick": "Maverick", + "Role_Pursuer": "Pursuer", + "Role_Follower": "Follower", + "Role_Amnesiac": "Amnesiac", + "Role_Imitator": "Imitator", + "Role_Sheriff": "Sheriff", + "Role_Knight": "Knight", + "Role_Deputy": "Deputy", + "Role_AdmiredImpostor": "Admired Impostor", + "Role_Trickster": "Trickster", + "Role_Traitor": "Traitor", + "Role_NoChange": "Don't change the role", + "Role_Random": "Random role from list", + + "CrewmatesCanGuess": "Crewmates can guess", + "ImpostorsCanGuess": "Impostors can guess", + "NeutralKillersCanGuess": "Neutral Killers can guess", + "NeutralApocalypseCanGuess": "Neutral Apocalypse can guess", + "PassiveNeutralsCanGuess": "Passive Neutrals can guess", + + "CanGuessAddons": "Can Guess Add-ons", + "ShowOnlyEnabledRolesInGuesserUI": "Show Only Enabled Roles In Guesser UI", + "CrewCanGuessCrew": "Crewmates Can Guess Crewmate Roles", + "ImpCanGuessImp": "Impostors Can Guess Impostor Roles", + "ApocCanGuessApoc": "Neutral Apocalypse Can Guess Neutral Apocalypse Roles", + "GuessImmune": "Sorry, but target is immune to being guessed!", + + + "GM": "Game Master", + "Sunnyboy": "Sunnyboy", + "Bard": "Bard", + "Crewmate": "Crewmate", + "CrewmateTOHE": "Crewmate", + "Engineer": "Engineer", + "EngineerTOHE": "Engineer", + "Scientist": "Scientist", + "ScientistTOHE": "Scientist", + "Noisemaker": "Noisemaker", + "NoisemakerTOHE": "Noisemaker", + "Tracker": "Tracker", + "TrackerTOHE": "Tracker", + "GuardianAngel": "Guardian Angel", + "GuardianAngelTOHE": "Guardian Angel", + "Impostor": "Impostor", + "ImpostorTOHE": "Impostor", + "Shapeshifter": "Shapeshifter", + "ShapeshifterTOHE": "Shapeshifter", + "Phantom": "Phantom", + "PhantomTOHE": "Phantom", + + "BountyHunter": "Bounty Hunter", + "Fireworker": "Fireworker", + "Mercenary": "Mercenary", + "ShapeMaster": "Shapemaster", + "Vampire": "Vampire", + "Warlock": "Warlock", + "Ninja": "Ninja", + "Zombie": "Zombie", + "Anonymous": "Anonymous", + "Miner": "Miner", + "KillingMachine": "Killing Machine", + "Escapist": "Escapist", + "Witch": "Witch", + "Nemesis": "Nemesis", + "Bloodmoon": "Bloodmoon", + "Possessor": "Possessor", + "Puppeteer": "Puppeteer", + "Mastermind": "Mastermind", + "TimeThief": "Time Thief", + "Sniper": "Sniper", + "Undertaker": "Undertaker", + "RiftMaker": "Rift Maker", + "EvilTracker": "Evil Tracker", + "EvilHacker": "Evil Hacker", + "EvilGuesser": "Evil Guesser", + "AntiAdminer": "Anti Adminer", + "Arrogance": "Arrogance", + "Bomber": "Bomber", + "Scavenger": "Scavenger", + "Trapster": "Trapster", + "Gangster": "Gangster", + "Cleaner": "Cleaner", + "Lightning": "Lightning", + "Greedy": "Greedy", + "CursedWolf": "Cursed Wolf", + "SoulCatcher": "Soul Catcher", + "QuickShooter": "Quick Shooter", + "Camouflager": "Camouflager", + "Eraser": "Eraser", + "Butcher": "Butcher", + "Hangman": "Hangman", + "Swooper": "Swooper", + "Crewpostor": "Crewpostor", + "Wildling": "Wildling", + "Trickster": "Trickster", + "Vindicator": "Vindicator", + "Parasite": "Parasite", + "Disperser": "Disperser", + "Inhibitor": "Inhibitor", + "Saboteur": "Saboteur", + "Councillor": "Councillor", + "Dazzler": "Dazzler", + "YinYanger": "YinYanger", + "Deathpact": "Deathpact", + "Devourer": "Devourer", + "Consigliere": "Consigliere", + "Morphling": "Morphling", + "Twister": "Twister", + "Lurker": "Lurker", + "Visionary": "Visionary", + "Refugee": "Refugee", + "Underdog": "Underdog", + "Ludopath": "Ludopath", + "Godfather": "Godfather", + "Chronomancer": "Chronomancer", + "Pitfall": "Pitfall", + "EvilMini": "Evil Mini", + "Blackmailer": "Blackmailer", + "Instigator": "Instigator", + "LazyGuy": "Lazy Guy", + "SuperStar": "Super Star", + "Celebrity": "Celebrity", + "Cleanser": "Cleanser", + "Keeper": "Keeper", + "Knight": "Knight", + "Mayor": "Mayor", + "Psychic": "Psychic", + "Mechanic": "Mechanic", + "Sheriff": "Sheriff", + "Vigilante": "Vigilante", + "Jailer": "Jailer", + "CopyCat": "Copycat", + "Snitch": "Snitch", + "Marshall": "Marshall", + "Doctor": "Doctor", + "Dictator": "Dictator", + "Detective": "Detective", + "NiceGuesser": "Nice Guesser", + "GuessMaster": "Guess Master", + "Transporter": "Transporter", + "TimeManager": "Time Manager", + "Spurt": "Spurt", + "Veteran": "Veteran", + "Bastion": "Bastion", + "Bodyguard": "Bodyguard", + "Deceiver": "Deceiver", + "Grenadier": "Grenadier", + "Medic": "Medic", + "FortuneTeller": "Fortune Teller", + "Judge": "Judge", + "Mortician": "Mortician", + "Medium": "Medium", + "Pacifist": "Pacifist", + "Observer": "Observer", + "Monarch": "Monarch", + "Overseer": "Overseer", + "Coroner": "Coroner", + "Merchant": "Merchant", + "President": "President", + "Hawk": "Hawk", + "Retributionist": "Retributionist", + "Deputy": "Deputy", + "Investigator": "Investigator", + "Guardian": "Guardian", + "Addict": "Addict", + "Mole": "Mole", + "Alchemist": "Alchemist", + "Tracefinder": "Tracefinder", + "Oracle": "Oracle", + "Spiritualist": "Spiritualist", + "Chameleon": "Chameleon", + "Inspector": "Inspector", + "Captain": "Captain", + "Admirer": "Admirer", + "TimeMaster": "Time Master", + "Crusader": "Crusader", + "Altruist": "Altruist", + "Reverie": "Reverie", + "Lookout": "Lookout", + "Telecommunication": "Telecommunication", + "Lighter": "Lighter", + "TaskManager": "Task Manager", + "Witness": "Witness", + "Swapper": "Swapper", "ChiefOfPolice": "Chief of Police", - "NiceMini": "Nice Mini", - "Mini": "Mini", - "Spy": "Spy", - "Randomizer": "Randomizer", - "Enigma": "Enigma", - "Jester": "Jester", - "Arsonist": "Arsonist", - "Pyromaniac": "Pyromaniac", - "Kamikaze": "Kamikaze", - "Huntsman": "Huntsman", - "Terrorist": "Terrorist", - "Executioner": "Executioner", - "Lawyer": "Lawyer", - "Opportunist": "Opportunist", - "Vector": "Vector", - "Jackal": "Jackal", - "God": "God", - "Innocent": "Innocent", - "Stealth": "Stealth", - "Penguin": "Penguin", - "Pelican": "Pelican", - "PlagueDoctor": "Plague Scientist", - "Revolutionist": "Revolutionist", - "Hater": "Hater", - "Demon": "Demon", - "Stalker": "Stalker", - "Workaholic": "Workaholic", - "Solsticer": "Solsticer", + "NiceMini": "Nice Mini", + "Mini": "Mini", + "Spy": "Spy", + "Randomizer": "Randomizer", + "Enigma": "Enigma", + "Jester": "Jester", + "Arsonist": "Arsonist", + "Pyromaniac": "Pyromaniac", + "Kamikaze": "Kamikaze", + "Huntsman": "Huntsman", + "Terrorist": "Terrorist", + "Executioner": "Executioner", + "Lawyer": "Lawyer", + "Opportunist": "Opportunist", + "Vector": "Vector", + "Jackal": "Jackal", + "God": "God", + "Innocent": "Innocent", + "Stealth": "Stealth", + "Penguin": "Penguin", + "Pelican": "Pelican", + "PlagueDoctor": "Plague Scientist", + "Revolutionist": "Revolutionist", + "Hater": "Hater", + "Demon": "Demon", + "Stalker": "Stalker", + "Workaholic": "Workaholic", + "LingeringPresence": "Lingering presence", + "FragileSoul": "Fragile soul", + "Evolver": "Evolver", + "FadingLight": "Fading Light", + "Solsticer": "Solsticer", "Abyssbringer": "Abyssbringer", - "Collector": "Collector", - "Provocateur": "Provocateur", - "BloodKnight": "Blood Knight", - "Apocalypse": "Apocalypse", - "PlagueBearer": "Plaguebearer", - "Pestilence": "Pestilence", - "SoulCollector": "Soul Collector", - "Death": "Death", - "Baker": "Baker", - "Famine": "Famine", - "Berserker": "Berserker", - "War": "War", - "Glitch": "Glitch", - "Sidekick": "Sidekick", - "Follower": "Follower", - "Cultist": "Cultist", - "SerialKiller": "Serial Killer", - "Juggernaut": "Juggernaut", - "Infectious": "Infectious", - "Virus": "Virus", - "Pursuer": "Pursuer", - "Specter": "Specter", - "Pirate": "Pirate", - "Agitater": "Agitator", - "Maverick": "Maverick", - "CursedSoul": "Cursed Soul", - "Pickpocket": "Pickpocket", - "Traitor": "Traitor", - "Troller": "Troller", - "Vulture": "Vulture", - "Taskinator": "Taskinator", - "Benefactor": "Benefactor", - "Medusa": "Medusa", - "Spiritcaller": "Spiritcaller", - "Amnesiac": "Amnesiac", - "Imitator": "Imitator", - "Bandit": "Bandit", - "Doppelganger": "Doppelganger", - "PunchingBag": "Punching Bag", - "Doomsayer": "Doomsayer", - "Shroud": "Shroud", - "Werewolf": "Werewolf", - "Shaman": "Shaman", - "Seeker": "Seeker", - "Pixie": "Pixie", - "Occultist": "Occultist", - "SchrodingersCat": "Schrodingers Cat", - "Romantic": "Romantic", - "VengefulRomantic": "Vengeful Romantic", - "RuthlessRomantic": "Ruthless Romantic", - "Poisoner": "Poisoner", - "HexMaster": "Hex Master", - "Wraith": "Wraith", - "Jinx": "Jinx", - "PotionMaster": "Potion Master", - "Necromancer": "Necromancer", - "Warden": "Warden", - "Minion": "Minion", - "Ghastly": "Ghastly", - "LastImpostor": "Last Impostor", - "Overclocked": "Overclocked", - "Lovers": "Lovers", - "Madmate": "Madmate", - "Watcher": "Watcher", - "Flash": "Flash", - "Torch": "Torch", - "Seer": "Seer", - "Tiebreaker": "Tiebreaker", - "Oblivious": "Oblivious", - "Rebirth": "Rebirth", - "Bewilder": "Bewilder", - "Workhorse": "Workhorse", - "Fool": "Fool", - "Avanger": "Avenger", - "Youtuber": "YouTuber", - "Egoist": "Egoist", - "Stealer": "Stealer", - "Paranoia": "Paranoia", - "Mimic": "Mimic", - "Guesser": "Guesser", - "Necroview": "Necroview", - "Reach": "Reach", - "Charmed": "Charmed", - "Cleansed": "Cleansed", - "Bait": "Bait", - "Trapper": "Beartrap", - "Infected": "Infected", - "Onbound": "Onbound", - "Rebound": "Rebound", - "Mundane": "Mundane", - "Knighted": "Knighted", - "Unreportable": "Disregarded", - "Contagious": "Contagious", - "Lucky": "Lucky", - "Unlucky": "Unlucky", - "VoidBallot": "Void Ballot", - "Aware": "Aware", - "Fragile": "Fragile", - "DoubleShot": "Double Shot", - "Rascal": "Rascal", - "Soulless": "Soulless", - "Gravestone": "Gravestone", - "Lazy": "Lazy", - "Autopsy": "Autopsy", - "Loyal": "Loyal", - "EvilSpirit": "Evil Spirit", - "Recruit": "Recruit", - "Admired": "Admired", - "Glow": "Glow", - "Radar": "Radar", - "Diseased": "Diseased", - "Antidote": "Antidote", - "Stubborn": "Stubborn", - "Swift": "Swift", - "Ghoul": "Ghoul", - "Bloodthirst": "Bloodthirst", - "Mare": "Mare", - "Burst": "Burst", - "Sleuth": "Sleuth", - "Clumsy": "Clumsy", - "Nimble": "Nimble", - "Circumvent": "Circumvent", - "Cyber": "Cyber", - "Hurried": "Hurried", - "Oiiai": "OIIAI", - "Influenced": "Influenced", - "Silent": "Silent", - "Susceptible": "Susceptible", - "Tricky": "Tricky", - "Rainbow": "Rainbow", - "Tired": "Tired", - "Statue": "Statue", - "Evader": "Evader", - "DollMaster": "Dollmaster", - "DoubleAgent": "Double Agent", - "Sloth": "Sloth", - "Prohibited": "Prohibited", - "Eavesdropper": "Eavesdropper", + "Collector": "Collector", + "Provocateur": "Provocateur", + "BloodKnight": "Blood Knight", + "Apocalypse": "Apocalypse", + "PlagueBearer": "Plaguebearer", + "Pestilence": "Pestilence", + "SoulCollector": "Soul Collector", + "Summoner": "Summoner", + "Summoned": "Summoned", + "Death": "Death", + "Baker": "Baker", + "Famine": "Famine", + "Berserker": "Berserker", + "War": "War", + "Glitch": "Glitch", + "Sidekick": "Sidekick", + "Follower": "Follower", + "Cultist": "Cultist", + "SerialKiller": "Serial Killer", + "Juggernaut": "Juggernaut", + "Infectious": "Infectious", + "Virus": "Virus", + "Pursuer": "Pursuer", + "Specter": "Specter", + "Pirate": "Pirate", + "Agitater": "Agitator", + "Maverick": "Maverick", + "CursedSoul": "Cursed Soul", + "Pickpocket": "Pickpocket", + "Traitor": "Traitor", + "Troller": "Troller", + "Vulture": "Vulture", + "Taskinator": "Taskinator", + "Benefactor": "Benefactor", + "Medusa": "Medusa", + "Spiritcaller": "Spiritcaller", + "Amnesiac": "Amnesiac", + "Imitator": "Imitator", + "Bandit": "Bandit", + "Doppelganger": "Doppelganger", + "PunchingBag": "Punching Bag", + "Doomsayer": "Doomsayer", + "Allergic": "Allergic", + "Shroud": "Shroud", + "Werewolf": "Werewolf", + "Shaman": "Shaman", + "Seeker": "Seeker", + "Pixie": "Pixie", + "Occultist": "Occultist", + "SchrodingersCat": "Schrodingers Cat", + "Romantic": "Romantic", + "VengefulRomantic": "Vengeful Romantic", + "RuthlessRomantic": "Ruthless Romantic", + "Poisoner": "Poisoner", + "HexMaster": "Hex Master", + "Wraith": "Wraith", + "Jinx": "Jinx", + "PotionMaster": "Potion Master", + "Necromancer": "Necromancer", + "Warden": "Warden", + "Minion": "Minion", + "Ghastly": "Ghastly", + "LastImpostor": "Last Impostor", + "Overclocked": "Overclocked", + "Lovers": "Lovers", + "Madmate": "Madmate", + "Watcher": "Watcher", + "Flash": "Flash", + "Torch": "Torch", + "Seer": "Seer", + "Tiebreaker": "Tiebreaker", + "Oblivious": "Oblivious", + "Rebirth": "Rebirth", + "Bewilder": "Bewilder", + "Workhorse": "Workhorse", + "Fool": "Fool", + "Avanger": "Avenger", + "Youtuber": "YouTuber", + "Egoist": "Egoist", + "Stealer": "Stealer", + "Paranoia": "Paranoia", + "Mimic": "Mimic", + "Guesser": "Guesser", + "Necroview": "Necroview", + "Reach": "Reach", + "Charmed": "Charmed", + "Cleansed": "Cleansed", + "Bait": "Bait", + "Trapper": "Beartrap", + "Infected": "Infected", + "Onbound": "Onbound", + "Rebound": "Rebound", + "Mundane": "Mundane", + "Knighted": "Knighted", + "Unreportable": "Disregarded", + "Contagious": "Contagious", + "Lucky": "Lucky", + "Unlucky": "Unlucky", + "VoidBallot": "Void Ballot", + "Aware": "Aware", + "Fragile": "Fragile", + "DoubleShot": "Double Shot", + "Rascal": "Rascal", + "Soulless": "Soulless", + "Gravestone": "Gravestone", + "Lazy": "Lazy", + "Autopsy": "Autopsy", + "Loyal": "Loyal", + "EvilSpirit": "Evil Spirit", + "Recruit": "Recruit", + "Admired": "Admired", + "Glow": "Glow", + "Radar": "Radar", + "Diseased": "Diseased", + "Antidote": "Antidote", + "Stubborn": "Stubborn", + "Swift": "Swift", + "Ghoul": "Ghoul", + "Bloodthirst": "Bloodthirst", + "Mare": "Mare", + "Burst": "Burst", + "Sleuth": "Sleuth", + "Clumsy": "Clumsy", + "Nimble": "Nimble", + "Circumvent": "Circumvent", + "Cyber": "Cyber", + "Hurried": "Hurried", + "Oiiai": "OIIAI", + "Influenced": "Influenced", + "Silent": "Silent", + "Susceptible": "Susceptible", + "Tricky": "Tricky", + "Rainbow": "Rainbow", + "Tired": "Tired", + "Statue": "Statue", + "Evader": "Evader", + "DollMaster": "Dollmaster", + "DoubleAgent": "Double Agent", + "Sloth": "Sloth", + "Prohibited": "Prohibited", + "Eavesdropper": "Eavesdropper", "Shocker": "Shocker", "Revenant": "Revenant", - "BracketAddons": "Add Brackets To Add-ons", - "EngineerTOHEInfo": "Use the vents to catch the Impostors", - "ScientistTOHEInfo": "Access portable vitals from anywhere", - "NoisemakerTOHEInfo": "Send out an alert when killed", - "TrackerTOHEInfo": "Track players with your map", - "ShapeshifterTOHEInfo": "Disguise as crewmates to frame them", - "PhantomTOHEInfo": "Turn invisible", - "GuardianAngelTOHEInfo": "Protect the crewmates from the Impostors", - "ImpostorTOHEInfo": "Kill and sabotage", - "CrewmateTOHEInfo": "Search for the Impostors", - "BountyHunterInfo": "Eliminate your target", - "FireworkerInfo": "Go out with a BANG", - "MercenaryInfo": "Keep killing, else you suicide", - "ShapeMasterInfo": "Swiftly kill with no shift cooldown", - "VampireInfo": "Your kills are delayed", - "WarlockInfo": "Curse crewmates then shift to make them kill", - "NinjaInfo": "Mark a target, then shift to kill", - "ZombieInfo": "You are very slow", - "AnonymousInfo": "Force a player to report a body", - "MinerInfo": "Warp to your last used vent by shifting", - "KillingMachineInfo": "You can ONLY kill, but low cooldown", - "EscapistInfo": "Shift to mark places and warp back to them", - "WitchInfo": "Spell crewmates to kill them in meetings", - "NemesisInfo": "Kill when you're the last Impostor", - "BeforeNemesisInfo": "You can't kill yet", - "AfterNemesisInfo": "Now start killing", - "BloodmoonInfo": "Seek havoc upon the crewmates", - "PossessorInfo": "Possess and lead crewmates away from others", - "PuppeteerInfo": "Make players kill for you", - "MastermindInfo": "Make others kill for you", - "TimeThiefInfo": "Lower meeting time by killing", - "SniperInfo": "Snipe players from a distance by shifting", - "UndertakerInfo": "Teleport dead body to a marked location", - "RiftMakerInfo": "Two rifts I trace, touch 'em to warp space", - "EvilTrackerInfo": "Track players by shifting", - "EvilHackerInfo": "Hack systems", - "AntiAdminerInfo": "Know when players are near devices", - "ArroganceInfo": "With each kill you make, your cooldown decreases", - "BomberInfo": "Shapeshift to explode", - "TrapsterInfo": "Trap your kills", - "ScavengerInfo": "Your kills are unreportable", - "EvilGuesserInfo": "Guess crew roles in meetings to kill", - "GangsterInfo": "Convert players to your side", - "CleanerInfo": "Report bodies to make them unreportable", - "LightningInfo": "Convert players to Quantum Ghosts", - "GreedyInfo": "Your kill cooldown shifts", - "CursedWolfInfo": "You survive a few kill attempts", - "SoulCatcherInfo": "You swap places with your shift target", - "QuickShooterInfo": "Store ammo to offset kill cooldown", - "CamouflagerInfo": "Camouflage everyone for easy kills", - "EraserInfo": "Erase the role of your vote target", - "ButcherInfo": "Enjoy my beautiful work", - "HangmanInfo": "I will decide when your life will end", - "SwooperInfo": "Turn invisible temporarily", - "CrewpostorInfo": "Kill by completing tasks", - "WildlingInfo": "Kill with strength and disguise", - "TricksterInfo": "Kill and trick the crew", - "VindicatorInfo": "Use your extra votes to kill everyone", - "ParasiteInfo": "Help the Impostors kill the crew", - "DisperserInfo": "Teleport everyone to random vents", - "InhibitorInfo": "You cannot kill during sabotages", - "SaboteurInfo": "You can only kill during sabotages", - "CouncillorInfo": "Kill off crewmates during meetings", - "DazzlerInfo": "Reduce the vision of the crew", - "DeathpactInfo": "Assign players to a death pact", - "DevourerInfo": "Consume the skin of the crew", - "ConsigliereInfo": "Discover the roles of other players", - "MorphlingInfo": "You can only kill while shapeshifted", - "TwisterInfo": "Swap all player positions", - "LurkerInfo": "Reduce your kill cooldown by venting", - "ConvictInfo": "Your target died, now help the Impostors", - "VisionaryInfo": "You see the alignments of the living", - "RefugeeInfo": "Help the Impostors kill off the crew", - "UnderdogInfo": "Start killing on a low player count", - "LudopathInfo": "Your kill cooldown is random", - "GodfatherInfo": "Convert players to Refugees by voting", - "ChronomancerInfo": "Kill in bursts", - "PitfallInfo": "Setup traps around the map", - "EvilMiniInfo": "No one can hurt you until you grow up", - "BlackmailerInfo": "Silence other players", - "InstigatorInfo": "Sow discord among the crewmates", - "LazyGuyInfo": "You're too lazy", - "SuperStarInfo": "Everyone knows you", - "CleanserInfo": "Erase All Add-ons of your vote target", - "KeeperInfo": "Reject the Eject, Keeper Protect!", - "MayorInfo": "Your vote counts multiple times", - "PsychicInfo": "One of the red names is evil", - "MechanicInfo": "Vent around and fix sabotages", - "SheriffInfo": "Shoot the Impostors", - "VigilanteInfo": "Not the hero we deserved but the hero we needed", - "JailerInfo": "Jail suspicious players", - "CopyCatInfo": "Use kill button to copy target's role", - "SnitchInfo": "Finish your tasks to find the Impostors", - "MarshallInfo": "Finish your tasks to prove your innocence", - "DoctorInfo": "Know how each player died", - "DictatorInfo": "Exile a player based on your judgment", - "DetectiveInfo": "Gain extra info from your body reports", - "UndercoverInfo": "Impostors see you as their partner", - "KnightInfo": "You can kill one player", - "NiceGuesserInfo": "Guess Impostor roles in meetings to kill", - "GuessMasterInfo": "Whispers heard, every guessed word.", - "TransporterInfo": "Do tasks to swap two players' locations", - "TimeManagerInfo": "Increase meeting time by doing tasks", - "VeteranInfo": "Alert to kill anyone who interacts with you", - "BastionInfo": "Bomb vents", - "YinYangerInfo": "Spontaneously combust two players", - "BodyguardInfo": "Prevent nearby kills", - "DeceiverInfo": "Try to fool the players", - "GrenadierInfo": "Reduce Impostors' vision by venting", - "MedicInfo": "Cast a shield onto a player", - "FortuneTellerInfo": "Get clues to people's roles", - "JudgeInfo": "Silence in the courtroom!", - "MorticianInfo": "Locate dead bodies", - "MediumInfo": "Talk with ghosts", - "ObserverInfo": "You can see all shield-animations", - "PacifistInfo": "Vent to reset kill cooldowns", - "RebirthInfo": "Arise Again", - "MonarchInfo": "Give your crew extra voting power!", + "BracketAddons": "Add Brackets To Add-ons", + "EngineerTOHEInfo": "Use the vents to catch the Impostors", + "ScientistTOHEInfo": "Access portable vitals from anywhere", + "NoisemakerTOHEInfo": "Send out an alert when killed", + "TrackerTOHEInfo": "Track players with your map", + "ShapeshifterTOHEInfo": "Disguise as crewmates to frame them", + "PhantomTOHEInfo": "Turn invisible", + "GuardianAngelTOHEInfo": "Protect the crewmates from the Impostors", + "ImpostorTOHEInfo": "Kill and sabotage", + "CrewmateTOHEInfo": "Search for the Impostors", + "BountyHunterInfo": "Eliminate your target", + "FireworkerInfo": "Go out with a BANG", + "MercenaryInfo": "Keep killing, else you suicide", + "ShapeMasterInfo": "Swiftly kill with no shift cooldown", + "VampireInfo": "Your kills are delayed", + "WarlockInfo": "Curse crewmates then shift to make them kill", + "NinjaInfo": "Mark a target, then shift to kill", + "ZombieInfo": "You are very slow", + "AnonymousInfo": "Force a player to report a body", + "MinerInfo": "Warp to your last used vent by shifting", + "KillingMachineInfo": "You can ONLY kill, but low cooldown", + "EscapistInfo": "Shift to mark places and warp back to them", + "WitchInfo": "Spell crewmates to kill them in meetings", + "NemesisInfo": "Kill when you're the last Impostor", + "BeforeNemesisInfo": "You can't kill yet", + "AfterNemesisInfo": "Now start killing", + "BloodmoonInfo": "Seek havoc upon the crewmates", + "PossessorInfo": "Possess and lead crewmates away from others", + "PuppeteerInfo": "Make players kill for you", + "MastermindInfo": "Make others kill for you", + "TimeThiefInfo": "Lower meeting time by killing", + "SniperInfo": "Snipe players from a distance by shifting", + "UndertakerInfo": "Teleport dead body to a marked location", + "RiftMakerInfo": "Two rifts I trace, touch 'em to warp space", + "EvilTrackerInfo": "Track players by shifting", + "EvilHackerInfo": "Hack systems", + "AntiAdminerInfo": "Know when players are near devices", + "ArroganceInfo": "With each kill you make, your cooldown decreases", + "BomberInfo": "Shapeshift to explode", + "TrapsterInfo": "Trap your kills", + "ScavengerInfo": "Your kills are unreportable", + "EvilGuesserInfo": "Guess crew roles in meetings to kill", + "GangsterInfo": "Convert players to your side", + "CleanerInfo": "Report bodies to make them unreportable", + "LightningInfo": "Convert players to Quantum Ghosts", + "GreedyInfo": "Your kill cooldown shifts", + "CursedWolfInfo": "You survive a few kill attempts", + "SoulCatcherInfo": "You swap places with your shift target", + "QuickShooterInfo": "Store ammo to offset kill cooldown", + "CamouflagerInfo": "Camouflage everyone for easy kills", + "EraserInfo": "Erase the role of your vote target", + "ButcherInfo": "Enjoy my beautiful work", + "HangmanInfo": "I will decide when your life will end", + "SwooperInfo": "Turn invisible temporarily", + "CrewpostorInfo": "Kill by completing tasks", + "WildlingInfo": "Kill with strength and disguise", + "TricksterInfo": "Kill and trick the crew", + "VindicatorInfo": "Use your extra votes to kill everyone", + "ParasiteInfo": "Help the Impostors kill the crew", + "DisperserInfo": "Teleport everyone to random vents", + "InhibitorInfo": "You cannot kill during sabotages", + "SaboteurInfo": "You can only kill during sabotages", + "CouncillorInfo": "Kill off crewmates during meetings", + "DazzlerInfo": "Reduce the vision of the crew", + "DeathpactInfo": "Assign players to a death pact", + "DevourerInfo": "Consume the skin of the crew", + "ConsigliereInfo": "Discover the roles of other players", + "MorphlingInfo": "You can only kill while shapeshifted", + "TwisterInfo": "Swap all player positions", + "LurkerInfo": "Reduce your kill cooldown by venting", + "ConvictInfo": "Your target died, now help the Impostors", + "VisionaryInfo": "You see the alignments of the living", + "RefugeeInfo": "Help the Impostors kill off the crew", + "UnderdogInfo": "Start killing on a low player count", + "LudopathInfo": "Your kill cooldown is random", + "GodfatherInfo": "Convert players to Refugees by voting", + "ChronomancerInfo": "Kill in bursts", + "PitfallInfo": "Setup traps around the map", + "EvilMiniInfo": "No one can hurt you until you grow up", + "BlackmailerInfo": "Silence other players", + "InstigatorInfo": "Sow discord among the crewmates", + "LazyGuyInfo": "You're too lazy", + "SuperStarInfo": "Everyone knows you", + "CleanserInfo": "Erase All Add-ons of your vote target", + "KeeperInfo": "Reject the Eject, Keeper Protect!", + "MayorInfo": "Your vote counts multiple times", + "PsychicInfo": "One of the red names is evil", + "MechanicInfo": "Vent around and fix sabotages", + "SheriffInfo": "Shoot the Impostors", + "VigilanteInfo": "Not the hero we deserved but the hero we needed", + "JailerInfo": "Jail suspicious players", + "CopyCatInfo": "Use kill button to copy target's role", + "SnitchInfo": "Finish your tasks to find the Impostors", + "MarshallInfo": "Finish your tasks to prove your innocence", + "DoctorInfo": "Know how each player died", + "DictatorInfo": "Exile a player based on your judgment", + "DetectiveInfo": "Gain extra info from your body reports", + "UndercoverInfo": "Impostors see you as their partner", + "KnightInfo": "You can kill one player", + "NiceGuesserInfo": "Guess Impostor roles in meetings to kill", + "GuessMasterInfo": "Whispers heard, every guessed word.", + "TransporterInfo": "Do tasks to swap two players' locations", + "TimeManagerInfo": "Increase meeting time by doing tasks", + "VeteranInfo": "Alert to kill anyone who interacts with you", + "BastionInfo": "Bomb vents", + "YinYangerInfo": "Spontaneously combust two players", + "BodyguardInfo": "Prevent nearby kills", + "DeceiverInfo": "Try to fool the players", + "GrenadierInfo": "Reduce Impostors' vision by venting", + "MedicInfo": "Cast a shield onto a player", + "FortuneTellerInfo": "Get clues to people's roles", + "JudgeInfo": "Silence in the courtroom!", + "MorticianInfo": "Locate dead bodies", + "MediumInfo": "Talk with ghosts", + "ObserverInfo": "You can see all shield-animations", + "PacifistInfo": "Vent to reset kill cooldowns", + "RebirthInfo": "Arise Again", + "MonarchInfo": "Give your crew extra voting power!", "AbyssbringerInfo": "Place Black Holes", - "SpurtInfo": "Spring Like A rabbit!", - "StealthInfo": "Killing Blinds Everyone in the Room", - "PenguinInfo": "Drag your victims", - "OverseerInfo": "Reveal roles of other players", - "CoronerInfo": "Find corpses and their killers", - "PresidentInfo": "You are in charge of the meeting", - "MerchantInfo": "Sell add-ons and bribe killers", - "RetributionistInfo": "Help the crew after you die", - "HawkInfo": "Seek murdering the bad guys!", - "DeputyInfo": "Handcuff killers to increase their cooldowns", - "InvestigatorInfo": "Find potential evils", - "GuardianInfo": "Complete your tasks to become immortal", - "AddictInfo": "Vent to become invulnerable, or you'll die", - "MoleInfo": "Vanish and reappear, the Mole's game is crystal clear!", - "AlchemistInfo": "Brew potions by completing tasks", - "TracefinderInfo": "Sense the location of dead bodies", - "OracleInfo": "Vote a player to see their alignment", - "SpiritualistInfo": "Be guided by the ghostly life", - "ChameleonInfo": "Vent to disguise into your surroundings", - "InspectorInfo": "Validate the alignments of two players", - "CaptainInfo": "Sail with the Captain, lest add-ons be abandoned.", - "AdmirerInfo": "Choose a player to side with you", - "TimeMasterInfo": "Rewind time!", - "CrusaderInfo": "Kill a player's attacker", - "AltruistInfo": "Revive a player", - "ReverieInfo": "With each kill, your cooldown decreases", - "LookoutInfo": "See through disguises", - "TelecommunicationInfo": "Track device usage", - "LighterInfo": "Catch killers with your enhanced vision", - "TaskManagerInfo": "See the total tasks completed in real-time", - "WitnessInfo": "Find out if someone killed recently", - "GhastlyInfo": "Control somebody!", - "SwapperInfo": "Swap the votes of two players", - "ChiefOfPoliceInfo": "Hire Sheriff to Serve the Crews!", - "NiceMiniInfo": "No one can hurt you until you grow up.", - "ArsonistInfo": "Douse everyone and ignite", - "PyromaniacInfo": "Douse and kill everyone", - "HuntsmanInfo": "Kill your targets for a low cooldown", - "SpyInfo": "You know who interacts with you", - "RandomizerInfo": "You're going to be someone's burden when you die?", - "EnigmaInfo": "Get Clues about Killers", - "JesterInfo": "Get voted out", - "OpportunistInfo": "Stay alive until the end", - "TerroristInfo": "Finish your tasks, THEN die", - "ExecutionerInfo": "Get your target voted out", - "LawyerInfo": "Help your target win!", - "VectorInfo": "Jump in! Jump out!", - "JackalInfo": "Murder everyone", - "GodInfo": "Everything is under your control", - "InnocentInfo": "Get someone ejected by making them kill you", - "PelicanInfo": "Eat all players", - "RevolutionistInfo": "Recruit players to win with you", - "HaterInfo": "Kill Lovers and Neptunes", - "DemonInfo": "Consume blood volumes", - "StalkerInfo": "Descend into the darkness, release fear!", - "WorkaholicInfo": "Finish all tasks to win solo!", - "SolsticerInfo": "Speed run all your tasks!", - "CollectorInfo": "Collect votes from players", - "ProvocateurInfo": "Victory with help target", - "BloodKnightInfo": "Killing gives you a temporary shield", - "PlagueBearerInfo": "Plague everyone to turn into Pestilence", - "PestilenceInfo": "Obliterate everyone!", - "SoulCollectorInfo": "Predict deaths to collect souls", - "DeathInfo": "Enact Armageddon", - "BakerInfo": "Feed Players Bread to become Famine", - "FamineInfo": "Starve Everyone", - "BerserkerInfo": "Kill to increase your level", - "WarInfo": "Destroy everything", - "GlitchInfo": "Hack and kill everyone", - "SidekickInfo": "Help the Jackal kill everyone", - "FollowerInfo": "Follow a player and help them", - "CultistInfo": "Charm everyone", - "SerialKillerInfo": "Kill off everyone to win!", - "JuggernautInfo": "With each kill, your cooldown decreases", - "InfectiousInfo": "Infect everyone", - "VirusInfo": "Kill and infect everyone", - "PursuerInfo": "Protect yourself and live to the end!", - "PlagueDoctorInfo": "Spread the infection!", - "SpecterInfo": "Get killed and finish your tasks to win!", - "PirateInfo": "Successfully plunder players to win", - "AgitaterInfo": "Pass a Bomb onto others", - "MaverickInfo": "Kill and survive to the end", - "CursedSoulInfo": "Snatch souls and steal the win", - "PickpocketInfo": "Steal votes from your kills", - "TraitorInfo": "Eliminate the Impostors, then win", - "TrollerInfo": "Make random event by complete task", - "VultureInfo": "Eat bodies by reporting to win", - "TaskinatorInfo": "Silent tasks, deadly blasts", - "BenefactorInfo": "Task complete, shield elite!", - "MedusaInfo": "Stone bodies by reporting them", - "SpiritcallerInfo": "Turn Players into Evil Spirits", - "AmnesiacInfo": "Remember the role of a dead body", - "ImitatorInfo": "Imitate a player's role", - "BanditInfo": "Rob a player's add-on", - "DoppelgangerInfo": "Steal your target's identity", - "PunchingBagInfo": "Get attacked a few times to win!", - "KamikazeInfo": "Kill players with a suicidal mission", - "DoomsayerInfo": "Successfully guess players to win", - "ShroudInfo": "Shroud players to make them kill", - "WerewolfInfo": "Kill crewmates in groups", - "ShamanInfo": "Deflect all the attacks on Voodoo doll", - "SeekerInfo": "Play Hide and Seek with your target", - "PixieInfo": "Tag 'em, Bag 'em, and Eject 'em!", - "OccultistInfo": "Kill and curse your enemies", - "SchrodingersCatInfo": "The cat is both alive and dead until observed.", - "RomanticInfo": "Protect your partner to win together", - "VengefulRomanticInfo": "Revenge your partner to win together", - "RuthlessRomanticInfo": "Kill everyone to win with your partner", - "PoisonerInfo": "Kill everyone with delayed kills", - "HexMasterInfo": "Hex players to kill them in meetings", - "WraithInfo": "Vent to go invisible temporarily", - "JinxInfo": "Reflect attacks onto your attackers", - "PotionMasterInfo": "Use your potions to your advantage", - "NecromancerInfo": "Kill your killer to defy death", - "WardenInfo": "(Ghost) Alert about danger", - "MinionInfo": "(Ghost) Blind enemies", - "LoversInfo": "Stay alive and win together", - "MadmateInfo": "Help the Impostors", - "WatcherInfo": "You see all the colors of votes", - "LastImpostorInfo": "Lower kill cooldown", - "OverclockedInfo": "Lower cooldown", - "FlashInfo": "You're faster", - "TorchInfo": "You have enhanced vision!", - "SeerInfo": "You are alerted when somebody has died", - "TiebreakerInfo": "Break tied votes", - "ObliviousInfo": "You can't report bodies", - "BewilderInfo": "A twist of vision, a web of confusion", - "WorkhorseInfo": "Be the first to complete all tasks and get more", - "FoolInfo": "You can't fix sabotages", - "AvangerInfo": "You take someone with you upon death", - "YoutuberInfo": "Get killed first to win", - "CelebrityInfo": "Everyone knows when you die", - "EgoistInfo": "Win on your own", - "StealerInfo": "Gain votes with kills", - "ParanoiaInfo": "You're dead and alive simultaneously", - "MimicInfo": "Reveal killed players' roles to impostors upon death", - "GuesserInfo": "Guess roles of players in meetings to kill", - "NecroviewInfo": "See the team of the dead", - "ReachInfo": "You have a longer kill range", - "BaitInfo": "Your killer self-reports your body", - "TrapperInfo": "Freeze your killer for a few seconds", - "OnboundInfo": "You can't be guessed", - "ReboundInfo": "Guess me right, and face your plight!", - "MundaneInfo": "Tasks all done, guessing's begun.", - "UnreportableInfo": "Your body can't be reported", - "LuckyInfo": "Dodge attackers", - "DoubleShotInfo": "You have an extra life when guessing", - "RascalInfo": "You appear evil in some cases", - "SoullessInfo": "You have no soul", - "GravestoneInfo": "Your role is revealed when you die", - "LazyInfo": "You're too lazy", - "AutopsyInfo": "You see how others died", - "LoyalInfo": "You cannot be recruited", - "EvilSpiritInfo": "You are an evil Spirit", - "RecruitInfo": "Help the Jackal", - "AdmiredInfo": "The Admirer chose you as their love", - "GlowInfo": "You glow in the dark", - "RadarInfo": "Arrow's hue, closest to you!", - "DiseasedInfo": "Increase the cooldown of the player who interacts with you", - "AntidoteInfo": "Decrease the cooldown of the player who interacts with you", - "StubbornInfo": "Protect your role and add-ons", - "SwiftInfo": "Your kills don't cause a lunge", - "UnluckyInfo": "Doing things has a chance to kill you", - "VoidBallotInfo": "Your vote count is 0", - "AwareInfo": "Know who revealed your role", - "FragileInfo": "Die instantly if someone uses the kill button on you", - "GhoulInfo": "Kill your killer after dying", - "BloodthirstInfo": "Become bloodthirsty and kill", - "MareInfo": "Kill in the darkness", - "BurstInfo": "Make your killer burst!", - "SleuthInfo": "Gain info from dead bodies", - "ClumsyInfo": "You have a chance to miss your kill", - "NimbleInfo": "You can vent!", - "CircumventInfo": "You can no longer vent", - "OiiaiInfo": "OIIAIOIIIAI", - "CyberInfo": "You're popular!", - "HurriedInfo": "God, I got too much stuff!", - "InfluencedInfo": "You lack decisiveness!", - "SilentInfo": "Vote like a Ghost!", - "SusceptibleInfo": "Death-reason lotto!", - "TrickyInfo": "Tricky slays, in mysterious ways.", - "TiredInfo": "Labor makes you sleepy.. Zzz..", - "StatueInfo": "You're still as a rock around people", - "EvaderInfo": "You have a chance not to be exiled!", - "GMInfo": "Spectate the chaos!", - "NotAssignedInfo": "No assigned role", - "SunnyboyInfo": "Shine, shine my sunshine!", - "BardInfo": "Poem's grace, murder's trace, a rhythmic dance in a dark embrace.", - "RainbowInfo": "Colorful melodies! You don't even know your own color.", - "DollMasterInfo": "Take control of players actions!", - "DoubleAgentInfo": "Plant bombs on players in meetings", - "SlothInfo": "You're slower", - "ProhibitedInfo": "Certain vents are blocked", - "EavesdropperInfo": "Listen in on other roles", + "SpurtInfo": "Spring Like A rabbit!", + "StealthInfo": "Killing Blinds Everyone in the Room", + "PenguinInfo": "Drag your victims", + "OverseerInfo": "Reveal roles of other players", + "CoronerInfo": "Find corpses and their killers", + "PresidentInfo": "You are in charge of the meeting", + "MerchantInfo": "Sell add-ons and bribe killers", + "RetributionistInfo": "Help the crew after you die", + "HawkInfo": "Seek murdering the bad guys!", + "DeputyInfo": "Handcuff killers to increase their cooldowns", + "InvestigatorInfo": "Find potential evils", + "GuardianInfo": "Complete your tasks to become immortal", + "AddictInfo": "Vent to become invulnerable, or you'll die", + "MoleInfo": "Vanish and reappear, the Mole's game is crystal clear!", + "AlchemistInfo": "Brew potions by completing tasks", + "TracefinderInfo": "Sense the location of dead bodies", + "OracleInfo": "Vote a player to see their alignment", + "SpiritualistInfo": "Be guided by the ghostly life", + "ChameleonInfo": "Vent to disguise into your surroundings", + "InspectorInfo": "Validate the alignments of two players", + "CaptainInfo": "Sail with the Captain, lest add-ons be abandoned.", + "AdmirerInfo": "Choose a player to side with you", + "TimeMasterInfo": "Rewind time!", + "CrusaderInfo": "Kill a player's attacker", + "AltruistInfo": "Revive a player", + "ReverieInfo": "With each kill, your cooldown decreases", + "LookoutInfo": "See through disguises", + "TelecommunicationInfo": "Track device usage", + "LighterInfo": "Catch killers with your enhanced vision", + "TaskManagerInfo": "See the total tasks completed in real-time", + "WitnessInfo": "Find out if someone killed recently", + "GhastlyInfo": "Control somebody!", + "SwapperInfo": "Swap the votes of two players", + "NiceMiniInfo": "No one can hurt you until you grow up.", + "ArsonistInfo": "Douse everyone and ignite", + "PyromaniacInfo": "Douse and kill everyone", + "HuntsmanInfo": "Kill your targets for a low cooldown", + "SpyInfo": "You know who interacts with you", + "RandomizerInfo": "What are you? Your just random", + "EnigmaInfo": "Get Clues about Killers", + "JesterInfo": "Get voted out", + "OpportunistInfo": "Stay alive until the end", + "TerroristInfo": "Finish your tasks, THEN die", + "ExecutionerInfo": "Get your target voted out", + "LawyerInfo": "Help your target win!", + "VectorInfo": "Jump in! Jump out!", + "JackalInfo": "Murder everyone", + "GodInfo": "Everything is under your control", + "InnocentInfo": "Get someone ejected by making them kill you", + "PelicanInfo": "Eat all players", + "RevolutionistInfo": "Recruit players to win with you", + "HaterInfo": "Kill Lovers and Neptunes", + "DemonInfo": "Consume blood volumes", + "StalkerInfo": "Descend into the darkness, release fear!", + "WorkaholicInfo": "Finish all tasks to win solo!", + "SolsticerInfo": "Speed run all your tasks!", + "CollectorInfo": "Collect votes from players", + "ProvocateurInfo": "Victory with help target", + "BloodKnightInfo": "Killing gives you a temporary shield", + "PlagueBearerInfo": "Plague everyone to turn into Pestilence", + "PestilenceInfo": "Obliterate everyone!", + "SoulCollectorInfo": "Predict deaths to collect souls", + "DeathInfo": "Enact Armageddon", + "BakerInfo": "Feed Players Bread to become Famine", + "FamineInfo": "Starve Everyone", + "BerserkerInfo": "Kill to increase your level", + "WarInfo": "Destroy everything", + "GlitchInfo": "Hack and kill everyone", + "SidekickInfo": "Help the Jackal kill everyone", + "FollowerInfo": "Follow a player and help them", + "CultistInfo": "Charm everyone", + "SerialKillerInfo": "Kill off everyone to win!", + "JuggernautInfo": "With each kill, your cooldown decreases", + "InfectiousInfo": "Infect everyone", + "VirusInfo": "Kill and infect everyone", + "PursuerInfo": "Protect yourself and live to the end!", + "PlagueDoctorInfo": "Spread the infection!", + "SpecterInfo": "Get killed and finish your tasks to win!", + "PirateInfo": "Successfully plunder players to win", + "AgitaterInfo": "Pass a Bomb onto others", + "MaverickInfo": "Kill and survive to the end", + "CursedSoulInfo": "Snatch souls and steal the win", + "PickpocketInfo": "Steal votes from your kills", + "TraitorInfo": "Eliminate the Impostors, then win", + "TrollerInfo": "Make random event by complete task", + "VultureInfo": "Eat bodies by reporting to win", + "TaskinatorInfo": "Silent tasks, deadly blasts", + "BenefactorInfo": "Task complete, shield elite!", + "MedusaInfo": "Stone bodies by reporting them", + "SpiritcallerInfo": "Turn Players into Evil Spirits", + "AmnesiacInfo": "Remember the role of a dead body", + "LingeringPresenceInfo": "Make them remember you", + "FragileSoulInfo": "your soul cant sustain in this world", + "EvolverInfo": "steal points to evolve", + "FadingLightInfo": "Your soul fades", + "ImitatorInfo": "Imitate a player's role", + "BanditInfo": "Rob a player's add-on", + "DoppelgangerInfo": "Steal your target's identity", + "PunchingBagInfo": "Get attacked a few times to win!", + "KamikazeInfo": "Kill players with a suicidal mission", + "DoomsayerInfo": "Successfully guess players to win", + "ShroudInfo": "Shroud players to make them kill", + "WerewolfInfo": "Kill crewmates in groups", + "ShamanInfo": "Deflect all the attacks on Voodoo doll", + "SeekerInfo": "Play Hide and Seek with your target", + "PixieInfo": "Tag 'em, Bag 'em, and Eject 'em!", + "OccultistInfo": "Kill and curse your enemies", + "SchrodingersCatInfo": "The cat is both alive and dead until observed.", + "RomanticInfo": "Protect your partner to win together", + "VengefulRomanticInfo": "Revenge your partner to win together", + "RuthlessRomanticInfo": "Kill everyone to win with your partner", + "PoisonerInfo": "Kill everyone with delayed kills", + "HexMasterInfo": "Hex players to kill them in meetings", + "WraithInfo": "Vent to go invisible temporarily", + "JinxInfo": "Reflect attacks onto your attackers", + "PotionMasterInfo": "Use your potions to your advantage", + "NecromancerInfo": "Kill your killer to defy death", + "WardenInfo": "(Ghost) Alert about danger", + "MinionInfo": "(Ghost) Blind enemies", + "LoversInfo": "Stay alive and win together", + "MadmateInfo": "Help the Impostors", + "WatcherInfo": "You see all the colors of votes", + "LastImpostorInfo": "Lower kill cooldown", + "OverclockedInfo": "Lower cooldown", + "FlashInfo": "You're faster", + "TorchInfo": "You have enhanced vision!", + "SeerInfo": "You are alerted when somebody has died", + "TiebreakerInfo": "Break tied votes", + "ObliviousInfo": "You can't report bodies", + "BewilderInfo": "A twist of vision, a web of confusion", + "WorkhorseInfo": "Be the first to complete all tasks and get more", + "FoolInfo": "You can't fix sabotages", + "AvangerInfo": "You take someone with you upon death", + "YoutuberInfo": "Get killed first to win", + "CelebrityInfo": "Everyone knows when you die", + "EgoistInfo": "Win on your own", + "StealerInfo": "Gain votes with kills", + "ParanoiaInfo": "You're dead and alive simultaneously", + "MimicInfo": "Reveal killed players' roles to impostors upon death", + "GuesserInfo": "Guess roles of players in meetings to kill", + "NecroviewInfo": "See the team of the dead", + "ReachInfo": "You have a longer kill range", + "BaitInfo": "Your killer self-reports your body", + "TrapperInfo": "Freeze your killer for a few seconds", + "OnboundInfo": "You can't be guessed", + "ReboundInfo": "Guess me right, and face your plight!", + "MundaneInfo": "Tasks all done, guessing's begun.", + "UnreportableInfo": "Your body can't be reported", + "LuckyInfo": "Dodge attackers", + "DoubleShotInfo": "You have an extra life when guessing", + "RascalInfo": "You appear evil in some cases", + "SoullessInfo": "You have no soul", + "GravestoneInfo": "Your role is revealed when you die", + "LazyInfo": "You're too lazy", + "AutopsyInfo": "You see how others died", + "LoyalInfo": "You cannot be recruited", + "EvilSpiritInfo": "You are an evil Spirit", + "RecruitInfo": "Help the Jackal", + "AdmiredInfo": "The Admirer chose you as their love", + "GlowInfo": "You glow in the dark", + "RadarInfo": "Arrow's hue, closest to you!", + "DiseasedInfo": "Increase the cooldown of the player who interacts with you", + "AntidoteInfo": "Decrease the cooldown of the player who interacts with you", + "StubbornInfo": "Protect your role and add-ons", + "SwiftInfo": "Your kills don't cause a lunge", + "UnluckyInfo": "Doing things has a chance to kill you", + "VoidBallotInfo": "Your vote count is 0", + "AwareInfo": "Know who revealed your role", + "FragileInfo": "Die instantly if someone uses the kill button on you", + "GhoulInfo": "Kill your killer after dying", + "BloodthirstInfo": "Become bloodthirsty and kill", + "MareInfo": "Kill in the darkness", + "BurstInfo": "Make your killer burst!", + "SleuthInfo": "Gain info from dead bodies", + "ClumsyInfo": "You have a chance to miss your kill", + "NimbleInfo": "You can vent!", + "CircumventInfo": "You can no longer vent", + "OiiaiInfo": "OIIAIOIIIAI", + "CyberInfo": "You're popular!", + "HurriedInfo": "God, I got too much stuff!", + "InfluencedInfo": "You lack decisiveness!", + "SilentInfo": "Vote like a Ghost!", + "SusceptibleInfo": "Death-reason lotto!", + "TrickyInfo": "Tricky slays, in mysterious ways.", + "TiredInfo": "Labor makes you sleepy.. Zzz..", + "StatueInfo": "You're still as a rock around people", + "EvaderInfo": "You have a chance not to be exiled!", + "GMInfo": "Spectate the chaos!", + "NotAssignedInfo": "No assigned role", + "SunnyboyInfo": "Shine, shine my sunshine!", + "BardInfo": "Poem's grace, murder's trace, a rhythmic dance in a dark embrace.", + "RainbowInfo": "Colorful melodies! You don't even know your own color.", + "DollMasterInfo": "Take control of players actions!", + "DoubleAgentInfo": "Plant bombs on players in meetings", + "SlothInfo": "You're slower", + "ProhibitedInfo": "Certain vents are blocked", + "EavesdropperInfo": "Listen in on other roles", "ShockerInfo": "Shock unsuspecting players", "RevenantInfo": "Take your killer's role", - "EngineerTOHEInfoLong": "(Crewmates):\nAs the Engineer, you may access the vents while Comms Sabotaged is inactive.", - "ScientistTOHEInfoLong": "(Crewmates):\nAs the Scientist, you can see vitals at any time, showing you who is alive and dead.", - "NoisemakerTOHEInfoLong": "(Crewmates):\nAs the Noisemaker, whenever you die, you will make a noise, and a visual indicator of your death appears on the screen so the Crewmates can run to catch the person who killed you red-handed (even if it’s not Red).", - "TrackerTOHEInfoLong": "(Crewmates):\nAs the Tracker, press your tracker button on a player to track their location via the map for a limited amount of time.", - "ShapeshifterTOHEInfoLong": "(Impostors):\nAs the Shapeshifter, you can shapeshift into other players. It is obvious when you shapeshift or revert shifting.", - "PhantomTOHEInfoLong": "(Impostors):\nAs the Phantom, you can press your vanish button to go invisible to escape a kill. You can click your appear button if you want to become visible before the timer runs out or not.\nNote: You will make a smoke cloud whenever you go invisible and become visible. So make sure you are in a safe area where no one will see you.", - "GuardianAngelTOHEInfoLong": "(Crewmates):\nAs the Guardian Angel, you are the first crewmate to die and can give Crewmates temporary shields.", - "ImpostorTOHEInfoLong": "(Impostors):\nAs the Impostor, your goal is to simply kill off the crewmates.\nYou can sabotage and vent.", - "CrewmateTOHEInfoLong": "(Crewmates):\nAs the Crewmate, your goal is to find and exile the Impostors.\nCrewmates win by getting rid of all killers or by finishing all their tasks.", - "BountyHunterInfoLong": "(Impostors):\nAs the Bounty Hunter, if you kill your assigned Target (indicated by the arrow if you have one), your next kill cooldown will be shortened.\nIf you kill anyone other than your target, your next kill cooldown will be increased. The Target swaps after a certain amount of time.", - "FireworkerInfoLong": "(Impostors):\nAs the Fireworker, you can Shapeshift to place Fireworks up to the maximum amount the host sets.\nWhen you are the last Impostor and all Fireworks have been placed, shapeshift again to detonate them and kill everyone in their radius, including you.\nIf you kill all players with your Fireworks, it's considered an Impostor victory.", - "MercenaryInfoLong": "(Impostors):\nAs the Mercenary, you must kill within your Deadline, as shown by your Shapeshift cooldown (which you cannot use). If you fail to kill, you die.", - "ShapeMasterInfoLong": "(Impostors):\nAs the Shapemaster, you have no Shapeshift cooldown.", - "VampireInfoLong": "(Impostors):\nAs the Vampire, your kills are delayed. This means that your target still dies even if a meeting is called first. However, if you bite a Bait, you kill normally and report the body. Depending on the settings, you can use double trigger (bite players - single click, kill normally - double click).", - "WarlockInfoLong": "(Impostors):\nAs the Warlock, you can Curse up to one other player at a time.\nWhen you Shapeshift, if you have Cursed a player, they kill the nearest person, which, depending on settings, can include you or other Impostors.\nYou can kill normally while Shapeshifted.", - "ZombieInfoLong": "(Impostors):\nZombie has a short kill cooldown but moves very slowly and has very little vision. Zombie can not be voted out by anyone other than the Dictator, and the movement speed of Zombie will gradually slow down as they make kills or time passes.", - "NinjaInfoLong": "(Impostors):\nAs the Ninja, you can use your kill button to Mark a target (single click) or kill normally (double click). You may then Shapeshift to teleport to the Marked target and kill them.", - "AnonymousInfoLong": "(Impostors):\nAs the Anonymous, you can Shapeshift to force your target to report whoever you killed this round.\nIf you killed nobody that round, the target will report their own dead body as if they had died.\nNote: This does not work on Lazy nor Lazy Guy, and this ability will work regardless of whether the body can normally be reported.", - "MinerInfoLong": "(Impostors):\nAs the Miner, you can shapeshift to teleport back to the last vent you were in.", - "KillingMachineInfoLong": "(Impostors):\nAs the Killing Machine, you have a very short kill cooldown with tiny vision. However, you cannot vent, sabotage, report, nor call emergency meetings.\n\nNote: You will bypass any shields, killing bait and beartrap won't take any effect", - "EscapistInfoLong": "(Impostors):\nAs the Escapist, you can Mark a location by Shapeshifting. Shapeshift again to teleport back to the Marked spot", - "WitchInfoLong": "(Impostors):\nAs the Witch, you can use your kill button to Spell (single click) or kill normally (double click).\nDuring the next meeting, the spelled target(s) will have a 「†」 next to their name visible to everyone. Unless you die by the end of that meeting, all Spelled targets will die.", - "NemesisInfoLong": "(Impostors):\nAs the Nemesis, you can only kill if you are the last Impostor.\nIf you are dead, you can use the command /rv [ID] to kill the player whose ID you typed. Use /id to show the IDs of all players, or look next to their names.", - "BloodmoonInfoLong": "(Impostors [Ghost]):\nAs the Bloodmoon, attack the enemies to make them drip blood, this means they will die in a time set by the host, and will be aware of it.", - "PossessorInfoLong": "(Impostors [Ghost]):\nAs the Possessor, you can possess players when others aren't in the Alert Range. Lead the possessed player as far as possible from other players in the Focus Range. Once the possession duration is up, the possessed player will be killed if others aren't in the Focus Range. If you run into another player in the Alert Range while possessing, the Possessor will immediately unpossess.", - "PuppeteerInfoLong": "(Impostors):\nAs the Puppeteer, you can use your kill button to Puppeteer (single click) or kill normally (double click).\nThose you Puppeteer will kill the next non-Impostor they touch. Depending on options, Puppeteered targets will also die once they kill.", - "MastermindInfoLong": "(Impostors):\nAs the Mastermind, you can use your kill button on a player once to manipulate them. The manipulation does nothing if the target doesn't have a kill button. But if the target does have a kill button, whoever you manipulate will be told after a delay that they got manipulated and must kill someone in a limited time to survive. If the time limit expires or a meeting gets called before killing someone, they die.\nDouble click on someone to kill them normally.", - "YinYangerInfoLong": "(Impostors):\nAs the YinYanger, you can use your kill button one time to pick your Yin and then a second time to choose a Yang. When those two players meet, they'll kill each other. When Yin & Yang have been chosen, you can kill normally.", - "TimeThiefInfoLong": "(Impostors):\nEvery time the Time Thief kills a player, the meeting time will be reduced by a certain amount of time. If the Time Thief dies, the meeting time will return to normal.", - "SniperInfoLong": "(Impostors):\nYou can shoot players from far away.\nYou have to shapeshift twice to make a successful snipe.\nImagine an arrow pointing from your first shapeshift location towards your unshift location.\nThat will be the direction in which the snipe will be made.\nThe snipe kills the first person in its path.\nYou cannot kill people normally until you use up all of your ammo.", - "UndertakerInfoLong": "(Impostors):\nEverytime you Shapeshift, you mark the location. Your kills will then teleport to the marked location.\nAfter every kill and meeting, your marked location will reset.\n\nAfter every teleported kill, you will freeze for a configurable amount of time", - "RiftMakerInfoLong": "(Impostors):\nAs Rift Maker, you can shapeshift to create a rift. You can teleport from one rift to another by touching the area where the rift was created. Trying to vent will kick you out, therefore destroying all the rifts.\n\nNote: Up to two rifts can be placed at a time; if you try to place a third, it removes the first one.", - "EvilTrackerInfoLong": "(Impostors):\nThe Evil Tracker can track other players, and the Evil Tracker can shapeshift into someone to switch the tracking target to the shapeshift target (You will immediately unshift after performing shapeshift). The arrow below the Evil Tracker's name indicates the direction of the target. When the Evil Tracker's teammate kills, the Evil Tracker will see a kill flash.", - "EvilHackerInfoLong": "(Impostors):\nThe Evil Hacker can get the last-minute admin information at the meeting beginning.\nUnoccupied rooms are not shown.\nA '★' marks rooms with impostors.\nRooms with dead bodies are marked with the number of bodies.\nExample: ★Cafeteria: 3 (DEAD×1).", - "EvilGuesserInfoLong": "(Impostors):\nThe Evil Guesser can guess the role of a certain player during the meeting. If correct, the target dies. If wrong, the Evil Guesser dies.\nThe guessing command is: /bt [player id] [role]\nYou can see the player's id before the player's name or use the /id command to view the id of all players.", - "AntiAdminerInfoLong": "(Impostors):\nThe Anti Adminer can at any time find out if there are crewmates or neutrals near Cameras, Admin Table, Vitals, DoorLog, and/or other devices. Note: Anti Adminer does not know if the player uses the device while near it. They only know that someone is near the device.", - "ArroganceInfoLong": "(Impostors):\nThe Arrogance reduces their kill cooldown with each successful kill of theirs.", - "BomberInfoLong": "(Impostors):\nThe Bomber can use the shapeshift button to self-explode, killing players within a certain range. But as a price, the Bomber will also die. Note: All players will see a kill flash when the Bomber explodes.", - "ScavengerInfoLong": "(Impostors):\nScavenger kills do not leave dead bodies behind. In addition, if the victim is a bait, no self-report will be made.", - "TrapsterInfoLong": "(Impostors):\nThe Trapster has a unique method of killing. By initiating a body report, the Trapster can eliminate the player attempting to report the body the Trapster killed.\nNote: If Trapster kills the Bait, the Trapster will die immediately.", - "GangsterInfoLong": "(Impostors):\nThe Gangster, a powerful character, can try to recruit a player to a Madmate by pressing the kill button. If the recruitment is successful, both the Gangster and the target will see the shield animation on each other as a reminder (only visible to each other). The remaining number of available recruits is displayed next to the Gangster's name (the Host sets the max). If the Gangster tries to recruit players who cannot be recruited, such as neutrals or some special crews, they will kill the target normally instead. When the Gangster has no remaining recruitments, they can only make normal kills from that point on.", - "CleanerInfoLong": "(Impostors):\nCleaner can press the Report button to clean up any dead body they come across (including those they kill). If the cleanup is successful, the Cleaner will see a shield animation on their body as a reminder (only visible to himself). The cleaned-up body cannot be reported (including bait).", - "LightningInfoLong": "(Impostors):\nAs the Lightning, you cannot kill normally. Instead, your kill button quantizes targets, which activates after a delay, causing the next person they encounter to kill them. Those who are actively quantized show a「■」next to their name. Additionally, those who have been quantized die if they survive until the end of a meeting. There is a setting to quantize your killer.", - "GreedyInfoLong": "(Impostors):\nGreedy kills with odd and even kills will have different kill cooldowns. Greedy's kill cooldown is reset every meeting, and Greedy's first kill is always odd.", - "CursedWolfInfoLong": "(Impostors):\nWhen the Cursed Wolf is about to be killed, the Cursed Wolf will curse the killer to death. (The Host sets the max of times you can counterattack)", - "SoulCatcherInfoLong": "(Impostors):\nAs the Soul Catcher, you can shapeshift to swap places with your target as long as they are not dead, in a vent, swallowed by pelican, or in a similar odd state.", - "QuickShooterInfoLong": "(Impostors):\nWhen the kill cooldown is over, Quick Shooter can reset the kill cooldown by shapeshift to store a bullet (when the storage is successful, a shield-animation visible only to himself will appear on their body as a reminder). If Quick Shooter has bullets, he can use one to bypass the kill cooldown; he will kill even if it's still on cooldown and use a bullet. At the beginning of each meeting, the quick shooter can only keep a certain number of bullets (The Host sets the number).", - "CamouflagerInfoLong": "(Impostors):\nWhen the Camouflager uses Shapeshift, all players start to look the same. This state ends when the Camouflager reverts its shapeshifting. It's important to note that the skills of communication sabotage camouflage, and the skills of the Camouflager can be superimposed.\nThis skill will be invalid if a meeting is held during the skill activation of the Camouflager.", - "EraserInfoLong": "(Impostors):\nEraser can vote for any crew target at the meeting to erase the target's roles, and the erasure will take effect after the meeting ends. Note: Players with erased skills will always be considered a vanilla role, including the game result page.\nA crew target can only be erased once (include Oiiai)", - "ButcherInfoLong": "(Impostors):\nThe Butcher's kills, including passive ones, leave multiple dead bodies on targets, which can be a bit confusing when reporting. Here's the rule: the killed target must repeatedly display the animation of being killed, which cannot be skipped, and they cannot participate in the meeting normally during this period. And if the Butcher kills the Avenger, the Avenger will revenge everyone in anger.", - "HangmanInfoLong": "(Impostors):\nAs the Hangman, during the shapeshifting, you use a unique killing method-strangling. This method ignores any status of the target, such as the shield of the Medic, the Bodyguard's protection, the Super Star's skills, etc. The strangled player will not leave a dead body, nor will it trigger any of its skills. For example, Veteran kill back (including additional roles), and Seer will not be prompted.", - "SwooperInfoLong": "(Impostors):\nAs the Swooper, you can vent to vanish temporarily. You will still appear visible on your screen. Vent again to become visible.", - "CrewpostorInfoLong": "(Team Impostor):\nYou kill the nearest player whenever you finish a task.", - "WildlingInfoLong": "(Impostors):\nAs the Wildling, you can shapeshift but cannot vent.\nWhen you kill, you temporarily become immune to attacks.", - "TricksterInfoLong": "(Impostors):\nAs the Trickster, you function as a regular Impostor but with one key difference.\nYou appear as a crewmate to crewmate roles.\n\nThe Sheriff cannot kill you.\nPsychic does not see you as evil.\nSnitch cannot find you.", - "VindicatorInfoLong": "(Impostors):\nAs the Vindicator, you have extra votes like a Mayor.", - "StealthInfoLong": "(Impostors):\nWhen the Stealth kills, players in the same room are blinded for a short time.", - "PenguinInfoLong": "(Impostors):\nAs the Penguin, you can restrain the target by pressing the kill button and drag it around.\nWhile dragging, the target dies by pressing the kill button again or after a certain period.\nPress the kill button twice for a direct kill.", - "ParasiteInfoLong": "(Team Impostor):\nAs the Parasite, you are an Impostor that does not know the other Impostors.\n\nYou may kill, vent, sabotage, whatever.\nJust know that you are an Impostor.", - "DisperserInfoLong": "(Impostors):\nDisperser can use Shapeshift to teleport all players to random vents.", - "InhibitorInfoLong": "(Impostors):\nAs the Inhibitor, you can only kill when there is not a critical sabotage active.\n\nIf light or comms sabotage is active, then you can kill.", - "SaboteurInfoLong": "(Impostors):\nAs the Saboteur, you can only kill when there is a critical sabotage active.\n\nIf reactor or O2 sabotage is active, then you can kill.", - "CouncillorInfoLong": "(Impostors):\nAs the Councillor, you can kill players during a meeting like a Judge.\nWhen killing in a meeting, those kills will appear as a trial from a Judge.\n\nThe kill command is /tl [player id]\nYou can see the player's id before the player's name, or use the /id command to view the id of all players.\nDepending on the settings, Councillor will suicide when he judge his teammates.\nConverted Councillor can judge freely.", - "DazzlerInfoLong": "(Impostors):\nAs the Dazzler, you can reduce the vision of the target of your Shapeshift permanently. When you die, their vision will turn back to normal.", - "DeathpactInfoLong": "(Impostors):\nAs the Deathpact, You shapeshift to mark your targets for a deathpact.\nIf you have enough players marked for a death pact, they must meet within a specific period; if they fail to do so, they die.\nIf a marked player dies before the death pact becomes complete, the pact is withdrawn.", - "DevourerInfoLong": "(Impostors):\nAs the Devourer, you use your shapeshift to change the appearance of the target of the shapeshift permanently. Additionally, when each player's appearance changes, you will have your kill cooldown reduced by a defined number of seconds. If the Devourer dies or gets voted out during a meeting, the player's appearance will change back to their normal appearance.", - "MorphlingInfoLong": "(Impostors):\nAs the Morphling, you are a Shapeshifter but cannot kill while not shapeshifted.", - "TwisterInfoLong": "(Impostors):\nAs the Twister, you can use shapeshifting to swap the position of all players randomly. The swap happens twice, once when you start your shapeshift and once when you return to your original appearance.\nThe Twister itself will not swap places with anyone, and players in vents will not teleport.", - "LurkerInfoLong": "(Impostors):\nAs the Lurker, you can jump into a vent to reduce your cooldown by a certain number of seconds. After you kill, your cooldown resets to its original value.", - "VisionaryInfoLong": "(Impostors):\nAs the Visionary, you see the alignments of living players during a meeting.\nThe following information will be displayed on the players:\n- The Red name indicates the Impostors.\n- The Cyan name indicates the Crewmates.\n- The Gray name indicates the Neutrals.", - "PlagueDoctorInfoLong": "(Neutrals):\n(Plague Doctor from TOH)\nThe Plague Scientist's goal is to infect every living player.\nThey start by choosing one player to infect, after which anyone who spends a set amount of time in the range of the infected player becomes infected themselves.\nInfection progress is cumulative and does not reset with distance or after meetings.", + "EngineerTOHEInfoLong": "(Crewmates):\nAs the Engineer, you may access the vents while Comms Sabotaged is inactive.", + "ScientistTOHEInfoLong": "(Crewmates):\nAs the Scientist, you can see vitals at any time, showing you who is alive and dead.", + "NoisemakerTOHEInfoLong": "(Crewmates):\nAs the Noisemaker, whenever you die, you will make a noise, and a visual indicator of your death appears on the screen so the Crewmates can run to catch the person who killed you red-handed (even if it’s not Red).", + "TrackerTOHEInfoLong": "(Crewmates):\nAs the Tracker, press your tracker button on a player to track their location via the map for a limited amount of time.", + "ShapeshifterTOHEInfoLong": "(Impostors):\nAs the Shapeshifter, you can shapeshift into other players. It is obvious when you shapeshift or revert shifting.", + "PhantomTOHEInfoLong": "(Impostors):\nAs the Phantom, you can press your vanish button to go invisible to escape a kill. You can click your appear button if you want to become visible before the timer runs out or not.\nNote: You will make a smoke cloud whenever you go invisible and become visible. So make sure you are in a safe area where no one will see you.", + "GuardianAngelTOHEInfoLong": "(Crewmates):\nAs the Guardian Angel, you are the first crewmate to die and can give Crewmates temporary shields.", + "ImpostorTOHEInfoLong": "(Impostors):\nAs the Impostor, your goal is to simply kill off the crewmates.\nYou can sabotage and vent.", + "CrewmateTOHEInfoLong": "(Crewmates):\nAs the Crewmate, your goal is to find and exile the Impostors.\nCrewmates win by getting rid of all killers or by finishing all their tasks.", + "BountyHunterInfoLong": "(Impostors):\nAs the Bounty Hunter, if you kill your assigned Target (indicated by the arrow if you have one), your next kill cooldown will be shortened.\nIf you kill anyone other than your target, your next kill cooldown will be increased. The Target swaps after a certain amount of time.", + "FireworkerInfoLong": "(Impostors):\nAs the Fireworker, you can Shapeshift to place Fireworks up to the maximum amount the host sets.\nWhen you are the last Impostor and all Fireworks have been placed, shapeshift again to detonate them and kill everyone in their radius, including you.\nIf you kill all players with your Fireworks, it's considered an Impostor victory.", + "MercenaryInfoLong": "(Impostors):\nAs the Mercenary, you must kill within your Deadline, as shown by your Shapeshift cooldown (which you cannot use). If you fail to kill, you die.", + "ShapeMasterInfoLong": "(Impostors):\nAs the Shapemaster, you have no Shapeshift cooldown.", + "VampireInfoLong": "(Impostors):\nAs the Vampire, your kills are delayed. This means that your target still dies even if a meeting is called first. However, if you bite a Bait, you kill normally and report the body. Depending on the settings, you can use double trigger (bite players - single click, kill normally - double click).", + "WarlockInfoLong": "(Impostors):\nAs the Warlock, you can Curse up to one other player at a time.\nWhen you Shapeshift, if you have Cursed a player, they kill the nearest person, which, depending on settings, can include you or other Impostors.\nYou can kill normally while Shapeshifted.", + "ZombieInfoLong": "(Impostors):\nZombie has a short kill cooldown but moves very slowly and has very little vision. Zombie can not be voted out by anyone other than the Dictator, and the movement speed of Zombie will gradually slow down as they make kills or time passes.", + "NinjaInfoLong": "(Impostors):\nAs the Ninja, you can use your kill button to Mark a target (single click) or kill normally (double click). You may then Shapeshift to teleport to the Marked target and kill them.", + "AnonymousInfoLong": "(Impostors):\nAs the Anonymous, you can Shapeshift to force your target to report whoever you killed this round.\nIf you killed nobody that round, the target will report their own dead body as if they had died.\nNote: This does not work on Lazy nor Lazy Guy, and this ability will work regardless of whether the body can normally be reported.", + "MinerInfoLong": "(Impostors):\nAs the Miner, you can shapeshift to teleport back to the last vent you were in.", + "KillingMachineInfoLong": "(Impostors):\nAs the Killing Machine, you have a very short kill cooldown with tiny vision. However, you cannot vent, sabotage, report, nor call emergency meetings.\n\nNote: You will bypass any shields, killing bait and beartrap won't take any effect", + "EscapistInfoLong": "(Impostors):\nAs the Escapist, you can Mark a location by Shapeshifting. Shapeshift again to teleport back to the Marked spot", + "WitchInfoLong": "(Impostors):\nAs the Witch, you can use your kill button to Spell (single click) or kill normally (double click).\nDuring the next meeting, the spelled target(s) will have a 「†」 next to their name visible to everyone. Unless you die by the end of that meeting, all Spelled targets will die.", + "NemesisInfoLong": "(Impostors):\nAs the Nemesis, you can only kill if you are the last Impostor.\nIf you are dead, you can use the command /rv [ID] to kill the player whose ID you typed. Use /id to show the IDs of all players, or look next to their names.", + "BloodmoonInfoLong": "(Impostors [Ghost]):\nAs the Bloodmoon, attack the enemies to make them drip blood, this means they will die in a time set by the host, and will be aware of it.", + "PossessorInfoLong": "(Impostors [Ghost]):\nAs the Possessor, you can possess players when others aren't in the Alert Range. Lead the possessed player as far as possible from other players in the Focus Range. Once the possession duration is up, the possessed player will be killed if others aren't in the Focus Range. If you run into another player in the Alert Range while possessing, the Possessor will immediately unpossess.", + "PuppeteerInfoLong": "(Impostors):\nAs the Puppeteer, you can use your kill button to Puppeteer (single click) or kill normally (double click).\nThose you Puppeteer will kill the next non-Impostor they touch. Depending on options, Puppeteered targets will also die once they kill.", + "MastermindInfoLong": "(Impostors):\nAs the Mastermind, you can use your kill button on a player once to manipulate them. The manipulation does nothing if the target doesn't have a kill button. But if the target does have a kill button, whoever you manipulate will be told after a delay that they got manipulated and must kill someone in a limited time to survive. If the time limit expires or a meeting gets called before killing someone, they die.\nDouble click on someone to kill them normally.", + "YinYangerInfoLong": "(Impostors):\nAs the YinYanger, you can use your kill button one time to pick your Yin and then a second time to choose a Yang. When those two players meet, they'll kill each other. When Yin & Yang have been chosen, you can kill normally.", + "TimeThiefInfoLong": "(Impostors):\nEvery time the Time Thief kills a player, the meeting time will be reduced by a certain amount of time. If the Time Thief dies, the meeting time will return to normal.", + "SniperInfoLong": "(Impostors):\nYou can shoot players from far away.\nYou have to shapeshift twice to make a successful snipe.\nImagine an arrow pointing from your first shapeshift location towards your unshift location.\nThat will be the direction in which the snipe will be made.\nThe snipe kills the first person in its path.\nYou cannot kill people normally until you use up all of your ammo.", + "UndertakerInfoLong": "(Impostors):\nEverytime you Shapeshift, you mark the location. Your kills will then teleport to the marked location.\nAfter every kill and meeting, your marked location will reset.\n\nAfter every teleported kill, you will freeze for a configurable amount of time", + "RiftMakerInfoLong": "(Impostors):\nAs Rift Maker, you can shapeshift to create a rift. You can teleport from one rift to another by touching the area where the rift was created. Trying to vent will kick you out, therefore destroying all the rifts.\n\nNote: Up to two rifts can be placed at a time; if you try to place a third, it removes the first one.", + "EvilTrackerInfoLong": "(Impostors):\nThe Evil Tracker can track other players, and the Evil Tracker can shapeshift into someone to switch the tracking target to the shapeshift target (You will immediately unshift after performing shapeshift). The arrow below the Evil Tracker's name indicates the direction of the target. When the Evil Tracker's teammate kills, the Evil Tracker will see a kill flash.", + "EvilHackerInfoLong": "(Impostors):\nThe Evil Hacker can get the last-minute admin information at the meeting beginning.\nUnoccupied rooms are not shown.\nA '★' marks rooms with impostors.\nRooms with dead bodies are marked with the number of bodies.\nExample: ★Cafeteria: 3 (DEAD×1).", + "EvilGuesserInfoLong": "(Impostors):\nThe Evil Guesser can guess the role of a certain player during the meeting. If correct, the target dies. If wrong, the Evil Guesser dies.\nThe guessing command is: /bt [player id] [role]\nYou can see the player's id before the player's name or use the /id command to view the id of all players.", + "AntiAdminerInfoLong": "(Impostors):\nThe Anti Adminer can at any time find out if there are crewmates or neutrals near Cameras, Admin Table, Vitals, DoorLog, and/or other devices. Note: Anti Adminer does not know if the player uses the device while near it. They only know that someone is near the device.", + "ArroganceInfoLong": "(Impostors):\nThe Arrogance reduces their kill cooldown with each successful kill of theirs.", + "BomberInfoLong": "(Impostors):\nThe Bomber can use the shapeshift button to self-explode, killing players within a certain range. But as a price, the Bomber will also die. Note: All players will see a kill flash when the Bomber explodes.", + "ScavengerInfoLong": "(Impostors):\nScavenger kills do not leave dead bodies behind. In addition, if the victim is a bait, no self-report will be made.", + "TrapsterInfoLong": "(Impostors):\nThe Trapster has a unique method of killing. By initiating a body report, the Trapster can eliminate the player attempting to report the body the Trapster killed.\nNote: If Trapster kills the Bait, the Trapster will die immediately.", + "GangsterInfoLong": "(Impostors):\nThe Gangster, a powerful character, can try to recruit a player to a Madmate by pressing the kill button. If the recruitment is successful, both the Gangster and the target will see the shield animation on each other as a reminder (only visible to each other). The remaining number of available recruits is displayed next to the Gangster's name (the Host sets the max). If the Gangster tries to recruit players who cannot be recruited, such as neutrals or some special crews, they will kill the target normally instead. When the Gangster has no remaining recruitments, they can only make normal kills from that point on.", + "CleanerInfoLong": "(Impostors):\nCleaner can press the Report button to clean up any dead body they come across (including those they kill). If the cleanup is successful, the Cleaner will see a shield animation on their body as a reminder (only visible to himself). The cleaned-up body cannot be reported (including bait).", + "LightningInfoLong": "(Impostors):\nAs the Lightning, you cannot kill normally. Instead, your kill button quantizes targets, which activates after a delay, causing the next person they encounter to kill them. Those who are actively quantized show a「■」next to their name. Additionally, those who have been quantized die if they survive until the end of a meeting. There is a setting to quantize your killer.", + "GreedyInfoLong": "(Impostors):\nGreedy kills with odd and even kills will have different kill cooldowns. Greedy's kill cooldown is reset every meeting, and Greedy's first kill is always odd.", + "CursedWolfInfoLong": "(Impostors):\nWhen the Cursed Wolf is about to be killed, the Cursed Wolf will curse the killer to death. (The Host sets the max of times you can counterattack)", + "SoulCatcherInfoLong": "(Impostors):\nAs the Soul Catcher, you can shapeshift to swap places with your target as long as they are not dead, in a vent, swallowed by pelican, or in a similar odd state.", + "QuickShooterInfoLong": "(Impostors):\nWhen the kill cooldown is over, Quick Shooter can reset the kill cooldown by shapeshift to store a bullet (when the storage is successful, a shield-animation visible only to himself will appear on their body as a reminder). If Quick Shooter has bullets, he can use one to bypass the kill cooldown; he will kill even if it's still on cooldown and use a bullet. At the beginning of each meeting, the quick shooter can only keep a certain number of bullets (The Host sets the number).", + "CamouflagerInfoLong": "(Impostors):\nWhen the Camouflager uses Shapeshift, all players start to look the same. This state ends when the Camouflager reverts its shapeshifting. It's important to note that the skills of communication sabotage camouflage, and the skills of the Camouflager can be superimposed.\nThis skill will be invalid if a meeting is held during the skill activation of the Camouflager.", + "EraserInfoLong": "(Impostors):\nEraser can vote for any crew target at the meeting to erase the target's roles, and the erasure will take effect after the meeting ends. Note: Players with erased skills will always be considered a vanilla role, including the game result page.\nA crew target can only be erased once (include Oiiai)", + "ButcherInfoLong": "(Impostors):\nThe Butcher's kills, including passive ones, leave multiple dead bodies on targets, which can be a bit confusing when reporting. Here's the rule: the killed target must repeatedly display the animation of being killed, which cannot be skipped, and they cannot participate in the meeting normally during this period. And if the Butcher kills the Avenger, the Avenger will revenge everyone in anger.", + "HangmanInfoLong": "(Impostors):\nAs the Hangman, during the shapeshifting, you use a unique killing method-strangling. This method ignores any status of the target, such as the shield of the Medic, the Bodyguard's protection, the Super Star's skills, etc. The strangled player will not leave a dead body, nor will it trigger any of its skills. For example, Veteran kill back (including additional roles), and Seer will not be prompted.", + "SwooperInfoLong": "(Impostors):\nAs the Swooper, you can vent to vanish temporarily. You will still appear visible on your screen. Vent again to become visible.", + "CrewpostorInfoLong": "(Team Impostor):\nYou kill the nearest player whenever you finish a task.", + "LingeringPresenceInfoLong": "Your anger lets you return", + "FragileSoulInfoLong": "your limited life means your soul breaks at the slightest touch", + "FadingLightInfoLong": "a old presence weakens your soul", + "EvolverInfoLong": "you work for only the fittest and those that win must be so.\nSurvive until the end of the game to win.\nBut before you can win you must prove to be as fit as the other winners, and that means you have to evolve.", + "WildlingInfoLong": "(Impostors):\nAs the Wildling, you can shapeshift but cannot vent.\nWhen you kill, you temporarily become immune to attacks.", + "TricksterInfoLong": "(Impostors):\nAs the Trickster, you function as a regular Impostor but with one key difference.\nYou appear as a crewmate to crewmate roles.\n\nThe Sheriff cannot kill you.\nPsychic does not see you as evil.\nSnitch cannot find you.", + "VindicatorInfoLong": "(Impostors):\nAs the Vindicator, you have extra votes like a Mayor.", + "StealthInfoLong": "(Impostors):\nWhen the Stealth kills, players in the same room are blinded for a short time.", + "PenguinInfoLong": "(Impostors):\nAs the Penguin, you can restrain the target by pressing the kill button and drag it around.\nWhile dragging, the target dies by pressing the kill button again or after a certain period.\nPress the kill button twice for a direct kill.", + "ParasiteInfoLong": "(Team Impostor):\nAs the Parasite, you are an Impostor that does not know the other Impostors.\n\nYou may kill, vent, sabotage, whatever.\nJust know that you are an Impostor.", + "DisperserInfoLong": "(Impostors):\nDisperser can use Shapeshift to teleport all players to random vents.", + "InhibitorInfoLong": "(Impostors):\nAs the Inhibitor, you can only kill when there is not a critical sabotage active.\n\nIf light or comms sabotage is active, then you can kill.", + "SaboteurInfoLong": "(Impostors):\nAs the Saboteur, you can only kill when there is a critical sabotage active.\n\nIf reactor or O2 sabotage is active, then you can kill.", + "CouncillorInfoLong": "(Impostors):\nAs the Councillor, you can kill players during a meeting like a Judge.\nWhen killing in a meeting, those kills will appear as a trial from a Judge.\n\nThe kill command is /tl [player id]\nYou can see the player's id before the player's name, or use the /id command to view the id of all players.\nDepending on the settings, Councillor will suicide when he judge his teammates.\nConverted Councillor can judge freely.", + "DazzlerInfoLong": "(Impostors):\nAs the Dazzler, you can reduce the vision of the target of your Shapeshift permanently. When you die, their vision will turn back to normal.", + "DeathpactInfoLong": "(Impostors):\nAs the Deathpact, You shapeshift to mark your targets for a deathpact.\nIf you have enough players marked for a death pact, they must meet within a specific period; if they fail to do so, they die.\nIf a marked player dies before the death pact becomes complete, the pact is withdrawn.", + "DevourerInfoLong": "(Impostors):\nAs the Devourer, you use your shapeshift to change the appearance of the target of the shapeshift permanently. Additionally, when each player's appearance changes, you will have your kill cooldown reduced by a defined number of seconds. If the Devourer dies or gets voted out during a meeting, the player's appearance will change back to their normal appearance.", + "MorphlingInfoLong": "(Impostors):\nAs the Morphling, you are a Shapeshifter but cannot kill while not shapeshifted.", + "TwisterInfoLong": "(Impostors):\nAs the Twister, you can use shapeshifting to swap the position of all players randomly. The swap happens twice, once when you start your shapeshift and once when you return to your original appearance.\nThe Twister itself will not swap places with anyone, and players in vents will not teleport.", + "LurkerInfoLong": "(Impostors):\nAs the Lurker, you can jump into a vent to reduce your cooldown by a certain number of seconds. After you kill, your cooldown resets to its original value.", + "VisionaryInfoLong": "(Impostors):\nAs the Visionary, you see the alignments of living players during a meeting.\nThe following information will be displayed on the players:\n- The Red name indicates the Impostors.\n- The Cyan name indicates the Crewmates.\n- The Gray name indicates the Neutrals.", + "PlagueDoctorInfoLong": "(Neutrals):\n(Plague Doctor from TOH)\nThe Plague Scientist's goal is to infect every living player.\nThey start by choosing one player to infect, after which anyone who spends a set amount of time in the range of the infected player becomes infected themselves.\nInfection progress is cumulative and does not reset with distance or after meetings.", "RefugeeInfoLong": "(Madmates):\nAs the Refugee, you were either:\n -An Amnesiac who remembered an Impostor\n -A killer who killed the Godfather's target.\n -A Romantic whose partner was an Impostor\n -Or an Imitator that imitated an Impostor.\n\nNow your job is to help the Impostors kill the crewmates.", - "UnderdogInfoLong": "(Impostors):\nAs the Underdog, you cannot kill until there's a certain amount of players alive.", - "ConsigliereInfoLong": "(Impostors):\nAs the Consigliere, you can reveal the roles of other players using your kill button.\n\nSingle click: Reveal role\nDouble click: Kill\n\nIf you run out of reveal uses, your kill button functions normally.", - "LudopathInfoLong": "(Impostors):\nAs the Ludopath, your kill cooldown is randomized.\n\nMinimum it can be is 1 second, while the maximum is your default kill cooldown.", + "UnderdogInfoLong": "(Impostors):\nAs the Underdog, you cannot kill until there's a certain amount of players alive.", + "ConsigliereInfoLong": "(Impostors):\nAs the Consigliere, you can reveal the roles of other players using your kill button.\n\nSingle click: Reveal role\nDouble click: Kill\n\nIf you run out of reveal uses, your kill button functions normally.", + "LudopathInfoLong": "(Impostors):\nAs the Ludopath, your kill cooldown is randomized.\n\nMinimum it can be is 1 second, while the maximum is your default kill cooldown.", "GodfatherInfoLong": "(Impostors):\nAs the Godfather, you vote someone to make them your target.\nIn the next round, if someone kills the target, the killer will turn into a Refugee or Madmate.", - "ChronomancerInfoLong": "(Impostors):\nAs the Chronomancer, you have a charge bar which indicates when the slaughter is ready. When it is at 100% the next time you kill someone, you go into slaughter mode, meaning you can kill indefinitely until your bar runs out of charge. Otherwise, you have a normal KCD.", - "PitfallInfoLong": "(Impostors):\nAs the Pitfall, you use your shapeshift to mark the area around the shapeshift as a trap. Players who enter this area will be immobilized quickly, and their vision will be affected.", - "EvilMiniInfoLong": "(Impostors):\nAs the Evil Mini, you are unkillable until you grow up and have a very long initial kill cooldown, which gets drastically shortened as you grow up.", - "BlackmailerInfoLong": "(Impostors):\nAs the Blackmailer, when you shift into a target, you will blackmail that player. This means that during the meetings, they won't be able to speak.\n\nNote: If someone is already blackmailed, blackmailing another person un-blackmails the current person.", - "InstigatorInfoLong": "(Impostors):\nAs the Instigator, it's your job to turn the crewmates against each other. Each time a Crewmate gets voted out in a meeting, if you are alive, an additional Crewmate who voted for the innocent player will die after the meeting. The Host determines the number of additional players dying.", - "LazyGuyInfoLong": "(Crewmates):\nLazy Guy has only one task. In addition, the Impostor's abilities can't affect the Lazy Guy, such as being a scapegoat for Anonymous, being marked by a Warlock or Puppeteer, and more. Lazy Guy will not have any add-ons.", - "SuperStarInfoLong": "(Crewmates):\nThere will be a star logo next to the Super Star's name, so everyone knows who the Super Star is. The Super Star can only die when the murderer is alone with the Super Star (regular kills only). In addition, the Guessers can't guess the Super Star. ", - "CelebrityInfoLong": "(Crewmates):\nAll Crewmates see the kill-flash when the Celebrity dies (same as the Seer sees the kill-flash) and get a notice at the next meeting. The Impostors don't know anything about this.", - "CleanserInfoLong": "(Crewmates):\nAs The Cleanser, you can vote to erase the add-ons of any target at the meeting. This erasure takes effect after the meeting ends. Depending on the settings, the cleansed player may never receive add-ons again.", - "KeeperInfoLong": "(Crewmates):\nAs keeper, you can vote for someone to protect them from being ejected. You can only do this a configurable number of times.", - "MayorInfoLong": "(Crewmates):\nAs the Mayor, you have extra votes. Depending on the settings, players can't see your extra votes, you can vent to call a meeting at any time, or you can have yourself revealed as Mayor upon task completion.", - "PsychicInfoLong": "(Crewmates):\nThe Psychic can see the names of several players highlighted in red during the meeting; at least one of them is evil. The Psychic will correctly see all Neutrals and Killing Crewmates displayed as red names when becoming a Madmate.", - "MechanicInfoLong": "(Crewmates):\nThe Mechanic can use the vent at any time. They can also fix Reactors, O2, and Communications using only one side. You can fix Lights by flicking only one switch. Opening a door will open all doors in the map.", - "SheriffInfoLong": "(Crewmates):\nSheriff has no task. The Sheriff can kill the Impostor (according to the host settings, the Sheriff can also kill neutrals). If the Sheriff tries to kill a crewmate, the Sheriff will kill himself. The Sheriff can kill anyone when he becomes a madmate (also according to the host settings).", - "VigilanteInfoLong": "(Crewmates):\nAs the Vigilante, you are tasked with eliminating potential threats to the Crew, but if they mistakenly kill an innocent crew member, they become a Madmate driven by guilt and remorse.\n\n Note: Gangster cannot convert Vigilante into madmate.", - "JailerInfoLong": "(Crewmates):\nAs the Jailer, use your kill button to lock a player in jail. During the next meeting, the jailed player cannot vote or get voted (the vote count will be 0). The Jailer may choose to execute the prisoner by voting for them. If the Jailer executes an innocent player, the Jailer loses the ability to execute for the rest of the game.\nIf the Jailer is evil, then they can execute anyone.\nThe Jailer has limited executions.\n\nNote: Jailed players cannot be guessed or judged, and jailed players can only guess Jailer.", - "SnitchInfoLong": "(Crewmates):\nAfter the Snitch completes all tasks, they can see the Impostor's names displayed in red on the meeting. When the Snitch has only one task left, the Impostors will see a 「★」 mark next to the name of themselves and the Snitch. When a Snitch becomes a Madmate, the 「★」 mark turns red.", - "MarshallInfoLong": "(Crewmates):\nAs the Marshall, complete your tasks to reveal yourself to the rest of the Crew.\nOther teams will not be able to see you.\nHowever, madmates CAN see you.", - "DoctorInfoLong": "(Crewmates):\nDoctor can see the cause of death for all players. In addition, the Doctor can access vitals wherever you are while he still has battery left.", - "DictatorInfoLong": "(Crewmates):\nWhen the Dictator votes for someone, the meeting will end on the spot, and the player they voted for will be ejected from the meeting. The moment the Dictator votes someone out, the Dictator will also die.", - "DetectiveInfoLong": "(Crewmate):\nAfter the Detective reports the body, they will receive a clue message, which will tell the Detective what the victim's role is. According to the Host's settings, the Detective may know what the murderer's role is. Note: Detective won't be Oblivious.", - "UndercoverInfoLong": "(Crewmates):\nThe Impostors knows who Undercover is and sees him as a teammate, but Undercover himself does not know who the Impostors are.", - "NiceGuesserInfoLong": "(Crewmates):\nThe Nice Guesser can guess the role of a certain player during the meeting. If it is correct, it will kill the target, and if it is wrong, Nice Guesser will suicide.\nThe guessing command is: /bt [player id] [role]\nYou can see the player's id before the player's name or use the /id command to view the id of all players.\nNice Guesser can guess crewmate when become madmate.", - "GuessMasterInfoLong": "(Crewmates):\nAs the Guess Master, you will receive information about every attempted guess made during a meeting. You will be informed about the role the guesser tried to guess, and you will also be notified in case of a misguess.", - "KnightInfoLong": "(Crewmates):\nThe Knight has no tasks. They can kill anyone but only do it once the whole game.", - "TransporterInfoLong": "(Crewmates):\nWhenever the Transporter completes the task, two random players will switch positions, but if there are not enough players left, nothing will happen. Note: Players in the vent will not be selected.", - "TimeManagerInfoLong": "(Crewmates):\nThe more tasks the Time Manager does, the longer the meeting time will be. When the Time Manager dies, the meeting time will return to normal. When the Time Manager becomes a Madmate, the skill changes to reducing the meeting time instead of increasing it.", - "VeteranInfoLong": "(Crewmates):\nAs the Veteran, you can enter the alert state by venting. If a player tries to kill the Veteran in the alert state, the Veteran will kill the murderer instead. Veteran will see a shield animation on their body and a text above their head as a reminder when they enter and exit the alert state.", - "BastionInfoLong": "(Crewmates):\nAs the Bastion, bomb vents to kill off impostors and neutrals.\nBe careful though; crewmates can also be killed with the bombs.", - "CopyCatInfoLong": "(Crewmate):\nAs the Copycat, you can use your kill button to copy the target's role.\n\nYou can only copy some crewmate roles.\nIf you try to copy a madmate or rascal, you become the madmate variation of the target role.\nIf you target an evil with a crewmate variant, you'll become the crewmate variant.\n\nAdditionally, Your role will be set back to Copycat after every meeting.\nNote You can't guess people in meetings.", - "BodyguardInfoLong": "(Crewmates):\nIf a player is about to be killed near the Bodyguard, the Bodyguard will prevent the kill and die with the murderer. The Bodyguard's skills will affect players of any team. When the Bodyguard becomes a Madmate, and the murderer is an Impostor, the Bodyguard will not activate the skill.", - "DeceiverInfoLong": "(Crewmates):\nThe Deceiver can sell the counterfeit to other players through the kill button. If the counterfeit is sold successfully, the Deceiver will see a shield animation on their body as a reminder. The counterfeit will take effect after the end of the next meeting. If the player with no kill ability holds the counterfeit, he will kill himself immediately. If the player with the killing ability has the counterfeit, he will commit suicide when he tries to kill someone next time.", - "GrenadierInfoLong": "(Crewmates):\nAs the Grenadier, you can vent to Flashbang players nearby, causing them to lose vision if they are an Impostor or, depending on settings, a Neutral.", - "MedicInfoLong": "(Crewmates):\nThe Medic can place a shield on the target by pressing the Kill button. The Medic can only give one shield for the whole game. Depending on the settings, the target's shield can or cannot deactivate when the Medic dies. The Medic can also see if someone is trying to break the target's shield.\nDepending on the Host's settings, the Medic or the target can see if the player has a shield (shown as a green circle 「●」 next to the name).", - "FortuneTellerInfoLong": "(Crewmates):\nAs the Fortune Teller, vote for a player in a meeting to get a clue to their role.\nThe clue will relate to their actual role.\n\nWhen the Fortune Teller's tasks are complete, they will obtain the exact role rather than a clue!\n\nNote: If the setting to give random active players as a hint is on, you cannot check the same player multiple times.", - "JudgeInfoLong": "(Crewmates):\nThe Judge can judge a certain player during the meeting. If the target is evil, the target will be killed (whether it is evil or not is set by the Host). If it is wrong, the Judge commits suicide.\nCommand for judgment: /tl [player id]\nYou can see the player's id before the player's name, or use the /id command to view the id of all players.\nJudges can judge all players when they become Madmate.", - "MorticianInfoLong": "(Crewmates):\nThe Mortician can see arrows pointing to all dead bodies, and if the Mortician reports a body, they will know the last player the victim had contact with. Note: Mortician won't be Oblivious or Seer.", - "MediumInfoLong": "(Crewmates):\nThe Medium can establish contact with a dead player after someone reports a dead body. The player who reports doesn't have to be the Medium. The dead player can answer once with a YES or a NO to the Medium's question, which only the Medium will see (the dead player can use /ms yes or /ms no). Note: Medium won't be Oblivious.", - "ObserverInfoLong": "(Crewmates):\nAs the Observer, you can see all shield animations caused by other players after the first meeting. The shied animations typically indicate a role ability, so look out for this.", - "MonarchInfoLong": "(Crewmates):\nAs the Monarch, you can knight players to give them an extra vote.\n\nYou cannot knight someone who already has multiple votes.\n\nKnighted players appear with a golden name.\nIf a knighted player is alive, the Monarch cannot be guessed or killed.", - "PacifistInfoLong": "(Crewmates):\nWhen the Pacifist vents, they will reset the kill cooldown for every player with a kill button. When they become a Madmate, this ability will only work on Crewmates.", - "OverseerInfoLong": "(Crewmates):\nAs The Overseer, you have minimal vision, but you can use your kill button to reveal the role of a nearby player. A 「○」 will be displayed next to the revealed target after you use the kill button on them, and you will also be scanning them (only you can see this). Stay near the target for a defined time to reveal his role; if you move too far away, the reveal will cancel.", - "CoronerInfoLong": "(Crewmates):\nAs a Coroner, you can't report corpses; instead, after trying to report the corpse, you will see an arrow leading you to the killer. If someone calls a meeting, the arrows disappear. Depending on the settings, players can't report the body you found.", - "PresidentInfoLong": "(Crewmates):\nThe President has two abilities: End the meeting and Reveal identity.\n\n+ Ability 1: End the meeting - Type /finish in meetings as President to instantly end the meeting.\n+ Ability 2: Reveal identity - Type /reveal in meetings to reveal yourself. Revealing yourself will make it so every player can see that you are the President, and you will become unguessable after typing the command. However, after the President has revealed themselves, whoever killed the President will have their kill CD greatly reduced on their next kill.", - "MerchantInfoLong": "(Crewmates):\nAs a merchant, you sell a random add-on to a random player for each task you complete. Each add-on sold earns you money. If you have a certain amount of money, you can prevent the next killing attempt against you by bribing the murderer. The bribed player won't be able to kill you, but you don't know who it is. The money used is lost and not available for additional bribes.", - "RetributionistInfoLong": "(Crewmates):\nAs the Retributionist, you can kill a limited amount of players after your death.\n\nUse /ret [playerID] to kill.", - "HawkInfoLong": "(Crewmates [Ghost]):\nAs the Hawk, you can kill a limited amount of players decided by the host, though there's a chance you miss, slicing someone multiple times increases the chances.", - "DeputyInfoLong": "(Crewmates):\nAs the Deputy, use your kill button on a player to reset their kill cooldown.\n\nIf the target does not have a kill button, then the handcuff was a waste.", - "InvestigatorInfoLong": "(Crewmates):\nAs an Investigator, you can use your kill button to investigate someone. When you investigate someone, their name will appear in red if they possess a kill button (impostor/SS basis) or light blue if they lack a kill button (crewmate/engineer/scientist basis). However, please note that the color of the names will return to normal when someone calls a meeting.", - "GuardianInfoLong": "(Crewmates):\nAs the Guardian, you become immortal upon task completion. Guessers can't even guess you in meetings.", - "AddictInfoLong": "(Crewmates):\nAs the Addict, you have a suicide timer. When it expires, you kill yourself.\nThe timer is indicated by the vent cooldown. When the vent cooldown is 0 seconds, you still have a short time to vent.\nIf you don't make it, you die; if you make it, the suicide timer is reset.\nAlso after you vent, no one can interact with you for a defined period.\nAfter; the period is over, and you are immobilized for another defined period, and cannot report any bodies.", - "MoleInfoLong": "(Crewmates):\nAs the Mole, when you vent, you stay in the vent for 1 second. When you exit the vent, you will spawn near a random vent in the map (Except the one you used).", - "AlchemistInfoLong": "(Crewmates):\nAs the Alchemist, you brew potions when you complete tasks. The potion you made will show up under your role name with its corresponding description and instructions. You can get seven different potions, some with harmful or no effects. Vent to use the potion.", - "KamikazeInfoLong": "(Impostors):\nAs the Kamikaze you can single click to mark people. Double-click to kill normally. When you die, all marked also die, with death reason Targeted.", - "TracefinderInfoLong": "(Crewmates):\nAs the Tracefinder, you can access vitals at any time.\nIn addition, you get arrows pointing to dead bodies, with a delay set by the Host.", - "OracleInfoLong": "(Crewmates):\nAs the Oracle, you may vote a player during a meeting.\nYou'll see if they are a Crewmate, Neutral, or Impostor.\nDepending on settings, there can be a chance that your result will be incorrect.", - "SpiritualistInfoLong": "(Crewmates):\nAs the Spiritualist, you get an arrow pointing towards the ghost of the last meeting's victim. There is an option for the arrow to disappear and reappear in intervals. Try to notify the ghost about your ability if you can; if they are on your side, they may lead you to an evil role so you can eject them. Be careful, as evil roles can do the same for Crewmates.", - "ChameleonInfoLong": "(Crewmates):\nAs the Chameleon, you can vent to Vanish temporarily. You will still appear visible on your screen. Vent again to become visible.", - "InspectorInfoLong": "(Crewmates):\nCheck If two players are in the same team or not. You will get an affirmation message if they are on the same team or a denial message if they are not on the same team.\n\nAll neutrals and converted players are counted in the same team. Trickster counts as Crew, and Rascal counts as Impostor.\nChecking command: /cmp [player id 1] [player id 2].", - "CaptainInfoLong": "(Crewmates):\nWith each completed task, the Captain gains the power to slow down a random non-crew role. Crewmates can see ☆besides Captain's name.\n\nIf anyone betrays the Captain's trust by voting Captain out, they will lose an add-on.", - "AdmirerInfoLong": "(Crewmates):\nAs the Admirer, admire a player to make them Crewmate aligned.\nThey'll win with crewmates and not their original team.\n\nYou can only do this once per player.", - "TimeMasterInfoLong": "(Crewmates):\nAs the Time Master, use the vents to mark everyone's position.\nWhen using the ability again, every alive player will rewind to the marked positions.\n\nDuring the ability duration, the Time Master gains a time shield, which protects them from death.", - "CrusaderInfoLong": "(Crewmates):\nAs the Crusader, use your kill button to crusade a player.\nIf that player gets attacked, you'll kill the attacker.", - "AltruistInfoLong": "(Crewmates):\nAs the Altruist, you can sacrifice yourself to revive a dead body using the «Report» button.\nNote: If a dead player has left the game, you report that body normally.\nAlso revived player cannot report self dead body", - "ReverieInfoLong": "(Crewmates):\nAs the Reverie, you can kill, but your cooldown starts high.\n\nIt increases if you kill a crewmate and reduces otherwise.\nDepending on the Host's setting, you may misfire on reaching the max kill cooldown, and your target dies with you. \n\nYou win with other crewmates.", - "LookoutInfoLong": "(Crewmates):\nAs the Lookout, you can see the IDs of every player at all times.\nThis allows you to see through shapeshifts and camouflages.", - "TelecommunicationInfoLong": "(Crewmates):\nAs the Telecommunication, you are notified when anyone uses cameras, vitals, door logs, or admin.", - "LighterInfoLong": "(Crewmate):\nAs the Lighter, you can vent to increase your vision temporarily.\nYou have increased vision both when lights are not out and when lights are out.\nUse this power to catch sneaky killers!", - "TaskManagerInfoLong": "(Crewmates):\nYou see the total number of tasks completed (by everyone all together) next to your role name, which updates in real-time.", - "WitnessInfoLong": "(Crewmates):\nAs the Witness, when you use your kill button on someone, you will know if they killed in the last X seconds or not. (X depends on the settings).", - "SwapperInfoLong": "(Crewmates):\nAs the Swapper, you can swap votes in meetings.\n\nTo swap votes, use '/sw [playerID]' twice.\n\nPlayer IDs are displayed next to player names in meetings, but you can also use /id to get a list of all player IDs.\n\nNote: Depending on the Host's settings, you can exchange your own votes.", + "ChronomancerInfoLong": "(Impostors):\nAs the Chronomancer, you have a charge bar which indicates when the slaughter is ready. When it is at 100% the next time you kill someone, you go into slaughter mode, meaning you can kill indefinitely until your bar runs out of charge. Otherwise, you have a normal KCD.", + "PitfallInfoLong": "(Impostors):\nAs the Pitfall, you use your shapeshift to mark the area around the shapeshift as a trap. Players who enter this area will be immobilized quickly, and their vision will be affected.", + "EvilMiniInfoLong": "(Impostors):\nAs the Evil Mini, you are unkillable until you grow up and have a very long initial kill cooldown, which gets drastically shortened as you grow up.", + "BlackmailerInfoLong": "(Impostors):\nAs the Blackmailer, when you shift into a target, you will blackmail that player. This means that during the meetings, they won't be able to speak.\n\nNote: If someone is already blackmailed, blackmailing another person un-blackmails the current person.", + "InstigatorInfoLong": "(Impostors):\nAs the Instigator, it's your job to turn the crewmates against each other. Each time a Crewmate gets voted out in a meeting, if you are alive, an additional Crewmate who voted for the innocent player will die after the meeting. The Host determines the number of additional players dying.", + "LazyGuyInfoLong": "(Crewmates):\nLazy Guy has only one task. In addition, the Impostor's abilities can't affect the Lazy Guy, such as being a scapegoat for Anonymous, being marked by a Warlock or Puppeteer, and more. Lazy Guy will not have any add-ons.", + "SuperStarInfoLong": "(Crewmates):\nThere will be a star logo next to the Super Star's name, so everyone knows who the Super Star is. The Super Star can only die when the murderer is alone with the Super Star (regular kills only). In addition, the Guessers can't guess the Super Star. ", + "CelebrityInfoLong": "(Crewmates):\nAll Crewmates see the kill-flash when the Celebrity dies (same as the Seer sees the kill-flash) and get a notice at the next meeting. The Impostors don't know anything about this.", + "CleanserInfoLong": "(Crewmates):\nAs The Cleanser, you can vote to erase the add-ons of any target at the meeting. This erasure takes effect after the meeting ends. Depending on the settings, the cleansed player may never receive add-ons again.", + "KeeperInfoLong": "(Crewmates):\nAs keeper, you can vote for someone to protect them from being ejected. You can only do this a configurable number of times.", + "MayorInfoLong": "(Crewmates):\nAs the Mayor, you have extra votes. Depending on the settings, players can't see your extra votes, you can vent to call a meeting at any time, or you can have yourself revealed as Mayor upon task completion.", + "PsychicInfoLong": "(Crewmates):\nThe Psychic can see the names of several players highlighted in red during the meeting; at least one of them is evil. The Psychic will correctly see all Neutrals and Killing Crewmates displayed as red names when becoming a Madmate.", + "MechanicInfoLong": "(Crewmates):\nThe Mechanic can use the vent at any time. They can also fix Reactors, O2, and Communications using only one side. You can fix Lights by flicking only one switch. Opening a door will open all doors in the map.", + "SheriffInfoLong": "(Crewmates):\nSheriff has no task. The Sheriff can kill the Impostor (according to the host settings, the Sheriff can also kill neutrals). If the Sheriff tries to kill a crewmate, the Sheriff will kill himself. The Sheriff can kill anyone when he becomes a madmate (also according to the host settings).", + "VigilanteInfoLong": "(Crewmates):\nAs the Vigilante, you are tasked with eliminating potential threats to the Crew, but if they mistakenly kill an innocent crew member, they become a Madmate driven by guilt and remorse.\n\n Note: Gangster cannot convert Vigilante into madmate.", + "JailerInfoLong": "(Crewmates):\nAs the Jailer, use your kill button to lock a player in jail. During the next meeting, the jailed player cannot vote or get voted (the vote count will be 0). The Jailer may choose to execute the prisoner by voting for them. If the Jailer executes an innocent player, the Jailer loses the ability to execute for the rest of the game.\nIf the Jailer is evil, then they can execute anyone.\nThe Jailer has limited executions.\n\nNote: Jailed players cannot be guessed or judged, and jailed players can only guess Jailer.", + "SnitchInfoLong": "(Crewmates):\nAfter the Snitch completes all tasks, they can see the Impostor's names displayed in red on the meeting. When the Snitch has only one task left, the Impostors will see a 「★」 mark next to the name of themselves and the Snitch. When a Snitch becomes a Madmate, the 「★」 mark turns red.", + "MarshallInfoLong": "(Crewmates):\nAs the Marshall, complete your tasks to reveal yourself to the rest of the Crew.\nOther teams will not be able to see you.\nHowever, madmates CAN see you.", + "DoctorInfoLong": "(Crewmates):\nDoctor can see the cause of death for all players. In addition, the Doctor can access vitals wherever you are while he still has battery left.", + "DictatorInfoLong": "(Crewmates):\nWhen the Dictator votes for someone, the meeting will end on the spot, and the player they voted for will be ejected from the meeting. The moment the Dictator votes someone out, the Dictator will also die.", + "DetectiveInfoLong": "(Crewmate):\nAfter the Detective reports the body, they will receive a clue message, which will tell the Detective what the victim's role is. According to the Host's settings, the Detective may know what the murderer's role is. Note: Detective won't be Oblivious.", + "UndercoverInfoLong": "(Crewmates):\nThe Impostors knows who Undercover is and sees him as a teammate, but Undercover himself does not know who the Impostors are.", + "NiceGuesserInfoLong": "(Crewmates):\nThe Nice Guesser can guess the role of a certain player during the meeting. If it is correct, it will kill the target, and if it is wrong, Nice Guesser will suicide.\nThe guessing command is: /bt [player id] [role]\nYou can see the player's id before the player's name or use the /id command to view the id of all players.\nNice Guesser can guess crewmate when become madmate.", + "GuessMasterInfoLong": "(Crewmates):\nAs the Guess Master, you will receive information about every attempted guess made during a meeting. You will be informed about the role the guesser tried to guess, and you will also be notified in case of a misguess.", + "KnightInfoLong": "(Crewmates):\nThe Knight has no tasks. They can kill anyone but only do it once the whole game.", + "TransporterInfoLong": "(Crewmates):\nWhenever the Transporter completes the task, two random players will switch positions, but if there are not enough players left, nothing will happen. Note: Players in the vent will not be selected.", + "TimeManagerInfoLong": "(Crewmates):\nThe more tasks the Time Manager does, the longer the meeting time will be. When the Time Manager dies, the meeting time will return to normal. When the Time Manager becomes a Madmate, the skill changes to reducing the meeting time instead of increasing it.", + "VeteranInfoLong": "(Crewmates):\nAs the Veteran, you can enter the alert state by venting. If a player tries to kill the Veteran in the alert state, the Veteran will kill the murderer instead. Veteran will see a shield animation on their body and a text above their head as a reminder when they enter and exit the alert state.", + "BastionInfoLong": "(Crewmates):\nAs the Bastion, bomb vents to kill off impostors and neutrals.\nBe careful though; crewmates can also be killed with the bombs.", + "CopyCatInfoLong": "(Crewmate):\nAs the Copycat, you can use your kill button to copy the target's role.\n\nYou can only copy some crewmate roles.\nIf you try to copy a madmate or rascal, you become the madmate variation of the target role.\nIf you target an evil with a crewmate variant, you'll become the crewmate variant.\n\nAdditionally, Your role will be set back to Copycat after every meeting.\nNote You can't guess people in meetings.", + "BodyguardInfoLong": "(Crewmates):\nIf a player is about to be killed near the Bodyguard, the Bodyguard will prevent the kill and die with the murderer. The Bodyguard's skills will affect players of any team. When the Bodyguard becomes a Madmate, and the murderer is an Impostor, the Bodyguard will not activate the skill.", + "DeceiverInfoLong": "(Crewmates):\nThe Deceiver can sell the counterfeit to other players through the kill button. If the counterfeit is sold successfully, the Deceiver will see a shield animation on their body as a reminder. The counterfeit will take effect after the end of the next meeting. If the player with no kill ability holds the counterfeit, he will kill himself immediately. If the player with the killing ability has the counterfeit, he will commit suicide when he tries to kill someone next time.", + "GrenadierInfoLong": "(Crewmates):\nAs the Grenadier, you can vent to Flashbang players nearby, causing them to lose vision if they are an Impostor or, depending on settings, a Neutral.", + "MedicInfoLong": "(Crewmates):\nThe Medic can place a shield on the target by pressing the Kill button. The Medic can only give one shield for the whole game. Depending on the settings, the target's shield can or cannot deactivate when the Medic dies. The Medic can also see if someone is trying to break the target's shield.\nDepending on the Host's settings, the Medic or the target can see if the player has a shield (shown as a green circle 「●」 next to the name).", + "FortuneTellerInfoLong": "(Crewmates):\nAs the Fortune Teller, vote for a player in a meeting to get a clue to their role.\nThe clue will relate to their actual role.\n\nWhen the Fortune Teller's tasks are complete, they will obtain the exact role rather than a clue!\n\nNote: If the setting to give random active players as a hint is on, you cannot check the same player multiple times.", + "JudgeInfoLong": "(Crewmates):\nThe Judge can judge a certain player during the meeting. If the target is evil, the target will be killed (whether it is evil or not is set by the Host). If it is wrong, the Judge commits suicide.\nCommand for judgment: /tl [player id]\nYou can see the player's id before the player's name, or use the /id command to view the id of all players.\nJudges can judge all players when they become Madmate.", + "MorticianInfoLong": "(Crewmates):\nThe Mortician can see arrows pointing to all dead bodies, and if the Mortician reports a body, they will know the last player the victim had contact with. Note: Mortician won't be Oblivious or Seer.", + "MediumInfoLong": "(Crewmates):\nThe Medium can establish contact with a dead player after someone reports a dead body. The player who reports doesn't have to be the Medium. The dead player can answer once with a YES or a NO to the Medium's question, which only the Medium will see (the dead player can use /ms yes or /ms no). Note: Medium won't be Oblivious.", + "ObserverInfoLong": "(Crewmates):\nAs the Observer, you can see all shield animations caused by other players after the first meeting. The shied animations typically indicate a role ability, so look out for this.", + "MonarchInfoLong": "(Crewmates):\nAs the Monarch, you can knight players to give them an extra vote.\n\nYou cannot knight someone who already has multiple votes.\n\nKnighted players appear with a golden name.\nIf a knighted player is alive, the Monarch cannot be guessed or killed.", + "PacifistInfoLong": "(Crewmates):\nWhen the Pacifist vents, they will reset the kill cooldown for every player with a kill button. When they become a Madmate, this ability will only work on Crewmates.", + "OverseerInfoLong": "(Crewmates):\nAs The Overseer, you have minimal vision, but you can use your kill button to reveal the role of a nearby player. A 「○」 will be displayed next to the revealed target after you use the kill button on them, and you will also be scanning them (only you can see this). Stay near the target for a defined time to reveal his role; if you move too far away, the reveal will cancel.", + "CoronerInfoLong": "(Crewmates):\nAs a Coroner, you can't report corpses; instead, after trying to report the corpse, you will see an arrow leading you to the killer. If someone calls a meeting, the arrows disappear. Depending on the settings, players can't report the body you found.", + "PresidentInfoLong": "(Crewmates):\nThe President has two abilities: End the meeting and Reveal identity.\n\n+ Ability 1: End the meeting - Type /finish in meetings as President to instantly end the meeting.\n+ Ability 2: Reveal identity - Type /reveal in meetings to reveal yourself. Revealing yourself will make it so every player can see that you are the President, and you will become unguessable after typing the command. However, after the President has revealed themselves, whoever killed the President will have their kill CD greatly reduced on their next kill.", + "MerchantInfoLong": "(Crewmates):\nAs a merchant, you sell a random add-on to a random player for each task you complete. Each add-on sold earns you money. If you have a certain amount of money, you can prevent the next killing attempt against you by bribing the murderer. The bribed player won't be able to kill you, but you don't know who it is. The money used is lost and not available for additional bribes.", + "RetributionistInfoLong": "(Crewmates):\nAs the Retributionist, you can kill a limited amount of players after your death.\n\nUse /ret [playerID] to kill.", + "HawkInfoLong": "(Crewmates [Ghost]):\nAs the Hawk, you can kill a limited amount of players decided by the host, though there's a chance you miss, slicing someone multiple times increases the chances.", + "DeputyInfoLong": "(Crewmates):\nAs the Deputy, use your kill button on a player to reset their kill cooldown.\n\nIf the target does not have a kill button, then the handcuff was a waste.", + "InvestigatorInfoLong": "(Crewmates):\nAs an Investigator, you can use your kill button to investigate someone. When you investigate someone, their name will appear in red if they possess a kill button (impostor/SS basis) or light blue if they lack a kill button (crewmate/engineer/scientist basis). However, please note that the color of the names will return to normal when someone calls a meeting.", + "GuardianInfoLong": "(Crewmates):\nAs the Guardian, you become immortal upon task completion. Guessers can't even guess you in meetings.", + "AddictInfoLong": "(Crewmates):\nAs the Addict, you have a suicide timer. When it expires, you kill yourself.\nThe timer is indicated by the vent cooldown. When the vent cooldown is 0 seconds, you still have a short time to vent.\nIf you don't make it, you die; if you make it, the suicide timer is reset.\nAlso after you vent, no one can interact with you for a defined period.\nAfter; the period is over, and you are immobilized for another defined period, and cannot report any bodies.", + "MoleInfoLong": "(Crewmates):\nAs the Mole, when you vent, you stay in the vent for 1 second. When you exit the vent, you will spawn near a random vent in the map (Except the one you used).", + "AlchemistInfoLong": "(Crewmates):\nAs the Alchemist, you brew potions when you complete tasks. The potion you made will show up under your role name with its corresponding description and instructions. You can get seven different potions, some with harmful or no effects. Vent to use the potion.", + "KamikazeInfoLong": "(Impostors):\nAs the Kamikaze you can single click to mark people. Double-click to kill normally. When you die, all marked also die, with death reason Targeted.", + "TracefinderInfoLong": "(Crewmates):\nAs the Tracefinder, you can access vitals at any time.\nIn addition, you get arrows pointing to dead bodies, with a delay set by the Host.", + "OracleInfoLong": "(Crewmates):\nAs the Oracle, you may vote a player during a meeting.\nYou'll see if they are a Crewmate, Neutral, or Impostor.\nDepending on settings, there can be a chance that your result will be incorrect.", + "SpiritualistInfoLong": "(Crewmates):\nAs the Spiritualist, you get an arrow pointing towards the ghost of the last meeting's victim. There is an option for the arrow to disappear and reappear in intervals. Try to notify the ghost about your ability if you can; if they are on your side, they may lead you to an evil role so you can eject them. Be careful, as evil roles can do the same for Crewmates.", + "ChameleonInfoLong": "(Crewmates):\nAs the Chameleon, you can vent to Vanish temporarily. You will still appear visible on your screen. Vent again to become visible.", + "InspectorInfoLong": "(Crewmates):\nCheck If two players are in the same team or not. You will get an affirmation message if they are on the same team or a denial message if they are not on the same team.\n\nAll neutrals and converted players are counted in the same team. Trickster counts as Crew, and Rascal counts as Impostor.\nChecking command: /cmp [player id 1] [player id 2].", + "CaptainInfoLong": "(Crewmates):\nWith each completed task, the Captain gains the power to slow down a random non-crew role. Crewmates can see ☆besides Captain's name.\n\nIf anyone betrays the Captain's trust by voting Captain out, they will lose an add-on.", + "AdmirerInfoLong": "(Crewmates):\nAs the Admirer, admire a player to make them Crewmate aligned.\nThey'll win with crewmates and not their original team.\n\nYou can only do this once per player.", + "TimeMasterInfoLong": "(Crewmates):\nAs the Time Master, use the vents to mark everyone's position.\nWhen using the ability again, every alive player will rewind to the marked positions.\n\nDuring the ability duration, the Time Master gains a time shield, which protects them from death.", + "CrusaderInfoLong": "(Crewmates):\nAs the Crusader, use your kill button to crusade a player.\nIf that player gets attacked, you'll kill the attacker.", + "AltruistInfoLong": "(Crewmates):\nAs the Altruist, you can sacrifice yourself to revive a dead body using the «Report» button.\nNote: If a dead player has left the game, you report that body normally.\nAlso revived player cannot report self dead body", + "ReverieInfoLong": "(Crewmates):\nAs the Reverie, you can kill, but your cooldown starts high.\n\nIt increases if you kill a crewmate and reduces otherwise.\nDepending on the Host's setting, you may misfire on reaching the max kill cooldown, and your target dies with you. \n\nYou win with other crewmates.", + "LookoutInfoLong": "(Crewmates):\nAs the Lookout, you can see the IDs of every player at all times.\nThis allows you to see through shapeshifts and camouflages.", + "TelecommunicationInfoLong": "(Crewmates):\nAs the Telecommunication, you are notified when anyone uses cameras, vitals, door logs, or admin.", + "LighterInfoLong": "(Crewmate):\nAs the Lighter, you can vent to increase your vision temporarily.\nYou have increased vision both when lights are not out and when lights are out.\nUse this power to catch sneaky killers!", + "TaskManagerInfoLong": "(Crewmates):\nYou see the total number of tasks completed (by everyone all together) next to your role name, which updates in real-time.", + "WitnessInfoLong": "(Crewmates):\nAs the Witness, when you use your kill button on someone, you will know if they killed in the last X seconds or not. (X depends on the settings).", + "SwapperInfoLong": "(Crewmates):\nAs the Swapper, you can swap votes in meetings.\n\nTo swap votes, use '/sw [playerID]' twice.\n\nPlayer IDs are displayed next to player names in meetings, but you can also use /id to get a list of all player IDs.\n\nNote: Depending on the Host's settings, you can exchange your own votes.", "ChiefOfPoliceInfoLong": "(Crewmates):\nPlayers with swords can be recruited to join the sheriff's team to serve the crew\nNote: only one recruitment opportunity\nDepending on settings, you may recruit non killers or non crews.\nYou may suidice for recruiting wrong target.", - "NiceMiniInfoLong": "(Crewmates):\nAs a Nice Mini, your survival is crucial. You can't be killed until you grow up, and if you die or are evicted from the meeting before you grow up, everyone loses. This unique role adds a new dynamic to the game, where your survival is not just for your benefit but for the entire Crew's success.", - "SpyInfoLong": "(Crewmates):\nAs the Spy, when someone uses their kill button on you (any ability used through the kill button), you'll see their name in orange for a few seconds.\nNote: If a Crewmate used their ability on you, you'll also see them with an orange name!\nNote: If you cannot use left, you won't see orange names!\nNote: If the kill button interaction is blocked, the player's cooldown will reset to 10s'", - "RandomizerInfoLong": "(Crewmates):\nAs this Randomizer, when you die, your killer will do one of the following:\n 1. self-report your body\n 2. stand next to your body\n 3. have their kill cooldown set to 600s\n 4. Randomly avenge a player.", - "ArsonistInfoLong": "(Neutrals):\nThe Arsonist can douse a player by clicking the kill button on the player and following them for a few seconds. When the dousing starts and it's successful, a shield animation will happen as a reminder (only visible to themselves). When the Arsonist has doused all surviving players, the Arsonist can vent to start the fire and win alone.\n\nIf the player name shows 「△」, that means they are being doused;\nif the player name shows 「▲」, it means they have been completely doused.\nDepending on the setting, Arsonist may start the fire anytime. But if he fails to kill everyone, he loses.", - "EnigmaInfoLong": "(Crewmates):\nAs the Enigma, you get a random clue about the killer each meeting. Depending on the settings, you may have to report the body to receive a clue. The more tasks you complete, the more precise the clues get.", - "PyromaniacInfoLong": "(Neutrals):\nAs the Pyromaniac, you can douse players (single click) or kill normally (double click). Dousing players do nothing immediately, but killing a doused player will significantly shorten your kill cooldown. To win, be the last player alive.", - "HuntsmanInfoLong": "(Neutrals):\nAs the Huntsman, you are given a certain number of targets that reset every meeting. If you successfully eliminate one of your targets, your kill cooldown goes down permanently by the set amount. However, if you kill someone not one of your targets, your kill cooldown permanently increases by the set amount. A colored name indicates your targets.", - "MiniInfoLong": "(Crewmate or Impostor):\nThe Mini has two roles. A Nice or Evil Mini is chosen.\n\nUse'/r nice mini' and '/r evil mini' respectively for more details.", - "JesterInfoLong": "(Neutrals):\nIf the Jester gets voted out, the Jester wins the game alone. If the Jester is still alive at the end of the game, the Jester loses. Note: Jester, Executioner, and Innocent can win together.", - "TerroristInfoLong": "(Neutrals):\nIf the Terrorist dies after completing all tasks, the Terrorist wins the game alone. (They can win by either being voted out or killed).", - "ExecutionerInfoLong": "(Neutrals):\nThe Executioner is a role with an execution target, indicated by a diamond symbol「♦」next to their name. If the execution target is killed, the Executioner's role will change to Crewmate, Jester, or Opportunist, depending on the game settings. However, if the execution target is voted out in the meeting, the Executioner wins. Note: Jester, Executioner, and Innocent can win together.", - "LawyerInfoLong": "(Neutrals):\nLawyer has a target to defend, which will be indicated by a diamond 「♦」 next to their name.\nIf your target wins, you win.\nIf they lose, you lose.", - "OpportunistInfoLong": "(Neutrals):\nIf the Opportunist survives at the end of the game, the Opportunist will win with the winning player.", - "VectorInfoLong": "(Neutrals):\nVector will win alone by venting a certain number of times.", + "NiceMiniInfoLong": "(Crewmates):\nAs a Nice Mini, your survival is crucial. You can't be killed until you grow up, and if you die or are evicted from the meeting before you grow up, everyone loses. This unique role adds a new dynamic to the game, where your survival is not just for your benefit but for the entire Crew's success.", + "SpyInfoLong": "(Crewmates):\nAs the Spy, when someone uses their kill button on you (any ability used through the kill button), you'll see their name in orange for a few seconds.\nNote: If a Crewmate used their ability on you, you'll also see them with an orange name!\nNote: If you cannot use left, you won't see orange names!\nNote: If the kill button interaction is blocked, the player's cooldown will reset to 10s'", + "RandomizerInfoLong": "You have no set role as the randomizer, every time a meeting ends your role and add ons will be completely randomized. due to the random nature of this role it doesn't use the win condition of the role it is to avoid victory being entirely luck based. so to prevent that from happening the first role you gain is what dictates your win contition.\nIf you get a crewmate role then you win with the crewmates\nIf you get a Neutral role then you win if you survive till the end of the game\nIf you get a impostor role then you win with the impostor", + "ArsonistInfoLong": "(Neutrals):\nThe Arsonist can douse a player by clicking the kill button on the player and following them for a few seconds. When the dousing starts and it's successful, a shield animation will happen as a reminder (only visible to themselves). When the Arsonist has doused all surviving players, the Arsonist can vent to start the fire and win alone.\n\nIf the player name shows 「△」, that means they are being doused;\nif the player name shows 「▲」, it means they have been completely doused.\nDepending on the setting, Arsonist may start the fire anytime. But if he fails to kill everyone, he loses.", + "EnigmaInfoLong": "(Crewmates):\nAs the Enigma, you get a random clue about the killer each meeting. Depending on the settings, you may have to report the body to receive a clue. The more tasks you complete, the more precise the clues get.", + "PyromaniacInfoLong": "(Neutrals):\nAs the Pyromaniac, you can douse players (single click) or kill normally (double click). Dousing players do nothing immediately, but killing a doused player will significantly shorten your kill cooldown. To win, be the last player alive.", + "HuntsmanInfoLong": "(Neutrals):\nAs the Huntsman, you are given a certain number of targets that reset every meeting. If you successfully eliminate one of your targets, your kill cooldown goes down permanently by the set amount. However, if you kill someone not one of your targets, your kill cooldown permanently increases by the set amount. A colored name indicates your targets.", + "MiniInfoLong": "(Crewmate or Impostor):\nThe Mini has two roles. A Nice or Evil Mini is chosen.\n\nUse'/r nice mini' and '/r evil mini' respectively for more details.", + "JesterInfoLong": "(Neutrals):\nIf the Jester gets voted out, the Jester wins the game alone. If the Jester is still alive at the end of the game, the Jester loses. Note: Jester, Executioner, and Innocent can win together.", + "TerroristInfoLong": "(Neutrals):\nIf the Terrorist dies after completing all tasks, the Terrorist wins the game alone. (They can win by either being voted out or killed).", + "ExecutionerInfoLong": "(Neutrals):\nThe Executioner is a role with an execution target, indicated by a diamond symbol「♦」next to their name. If the execution target is killed, the Executioner's role will change to Crewmate, Jester, or Opportunist, depending on the game settings. However, if the execution target is voted out in the meeting, the Executioner wins. Note: Jester, Executioner, and Innocent can win together.", + "LawyerInfoLong": "(Neutrals):\nLawyer has a target to defend, which will be indicated by a diamond 「♦」 next to their name.\nIf your target wins, you win.\nIf they lose, you lose.", + "OpportunistInfoLong": "(Neutrals):\nIf the Opportunist survives at the end of the game, the Opportunist will win with the winning player.", + "VectorInfoLong": "(Neutrals):\nVector will win alone by venting a certain number of times.", "JackalInfoLong": "(Neutrals):\nAs the Jackal, you win if you are the last player alive. Additionally, you may recruit using the kill button. If the target is not one you can recruit, you have run out of uses, or you don't have the option to recruit, then you will kill people normally (i.e., don't use kill buttons in front of others thinking it'll recruit). If the target has a kill button and the option to turn into a Sidekick is on, they will become a Sidekick. Otherwise, they will gain the Recruit add-on if the option to give the Recruit add-on is on.\nDepending on the settings, when Jackal was killed, a Sidekick will be randomly selected as the new Jackal.\nRecruit may be selected if no sidekick is alive.", - "GodInfoLong": "(Neutrals):\nAs the God, you know everyone's role from the beginning. If you live until the end of the game, you steal the win, i.e., everyone else loses, and you win.", - "InnocentInfoLong": "(Neutrals):\nThe Innocent can use the kill button to plant any player, and the planted target will immediately kill the Innocent. If the target gets voted out in the meeting, the Innocent wins. Note: Jester, Executioner, and Innocent can win together.", - "PelicanInfoLong": "(Neutrals):\nAs the Pelican, you can use the kill button to swallow a player alive, teleporting them off-bounds but not killing them yet. Those swallowed will only die if you're still alive at the end of the round. If you die or leave during the round, all alive swallowed players will spawn into the map where you were.", - "RevolutionistInfoLong": "(Neutrals):\nAs the Revolutionist, you can recruit players by clicking the kill button on the player and following them until the shield animation plays for you. Recruiting has a chance, set by the Host, to kill players (though they are still recruited). When the required number of players are recruited (displayed next to your name), you must vent within the specified time to win the game immediately with all your recruits. If you do not vent in time, you lose and die.", - "HaterInfoLong": "(Neutrals):\nAs the Hater, you have no kill cooldown. However, depending on the settings, you can only kill Lovers and other recruiting roles and add-ons. Killing anyone else will make you suicide. You win at the end of the game with the winning team if none of the killable roles are alive. You will not be Lovers.", - "DemonInfoLong": "(Neutrals):\nAs the Demon, you kill by draining health. You see health in percentage near everyone's name, and every attack you make drains a percentage from that health without the victim knowing. Once you drain your victim's health to 0, they die. You win if you are the last one standing.", - "StalkerInfoLong": "(Neutrals):\nThe Stalker can kill anyone, and every kill will immediately cause a Lights sabotage (if Lights sabotage is already active, nothing will happen). Stalker cannot vent. If the Impostor wins while the Stalker is alive or the Crewmate wins by killing the Impostors (according to the Host's setting, the Stalker may also win when the Crewmate wins by killing the Neutrals), then the Stalker wins alone.", - "WorkaholicInfoLong": "(Neutrals):\nAs the Workaholic, you win alone when you complete all tasks. Depending on the Host's settings, you can only win if you are alive and or revealed to everyone at the beginning (these settings are rarely both on).", - "SolsticerInfoLong": "(Neutrals):\nAs the Solsticer, you won't die, and you win by finishing all your tasks in a single round. After every meeting finishes, your tasks reset, and you need to start all over again.\nVotes on the Solsticer will be directly canceled.\nKill attempts on the Solsticer will teleport it out of the map like Pelican until the meeting is finished.\nThe killer's kill cooldown will be reset to 10 seconds.\nSolsticer is counted as nothing in-game.", - "CollectorInfoLong": "(Neutrals):\nAs the Collector, when you vote for a player, for each other player that voted for them, you gain a point. When you collect the required votes, the game ends, and you win alone, even if you voted a Jester or Executioner's target out.", - "GlitchInfoLong": "(Neutrals):\nAs the Glitch, you can hack players (single click) or kill normally (double click).\nThose who have been hacked cannot kill, vent, or report for the hack duration.\nAdditionally, calling a sabotage other than doors will have no effect and will instead disguise you as a random player. You cannot disguise during or after sabotages.\nTo win, be the last player alive.", + "GodInfoLong": "(Neutrals):\nAs the God, you know everyone's role from the beginning. If you live until the end of the game, you steal the win, i.e., everyone else loses, and you win.", + "InnocentInfoLong": "(Neutrals):\nThe Innocent can use the kill button to plant any player, and the planted target will immediately kill the Innocent. If the target gets voted out in the meeting, the Innocent wins. Note: Jester, Executioner, and Innocent can win together.", + "PelicanInfoLong": "(Neutrals):\nAs the Pelican, you can use the kill button to swallow a player alive, teleporting them off-bounds but not killing them yet. Those swallowed will only die if you're still alive at the end of the round. If you die or leave during the round, all alive swallowed players will spawn into the map where you were.", + "RevolutionistInfoLong": "(Neutrals):\nAs the Revolutionist, you can recruit players by clicking the kill button on the player and following them until the shield animation plays for you. Recruiting has a chance, set by the Host, to kill players (though they are still recruited). When the required number of players are recruited (displayed next to your name), you must vent within the specified time to win the game immediately with all your recruits. If you do not vent in time, you lose and die.", + "HaterInfoLong": "(Neutrals):\nAs the Hater, you have no kill cooldown. However, depending on the settings, you can only kill Lovers and other recruiting roles and add-ons. Killing anyone else will make you suicide. You win at the end of the game with the winning team if none of the killable roles are alive. You will not be Lovers.", + "DemonInfoLong": "(Neutrals):\nAs the Demon, you kill by draining health. You see health in percentage near everyone's name, and every attack you make drains a percentage from that health without the victim knowing. Once you drain your victim's health to 0, they die. You win if you are the last one standing.", + "StalkerInfoLong": "(Neutrals):\nThe Stalker can kill anyone, and every kill will immediately cause a Lights sabotage (if Lights sabotage is already active, nothing will happen). Stalker cannot vent. If the Impostor wins while the Stalker is alive or the Crewmate wins by killing the Impostors (according to the Host's setting, the Stalker may also win when the Crewmate wins by killing the Neutrals), then the Stalker wins alone.", + "WorkaholicInfoLong": "(Neutrals):\nAs the Workaholic, you win alone when you complete all tasks. Depending on the Host's settings, you can only win if you are alive and or revealed to everyone at the beginning (these settings are rarely both on).", + "SolsticerInfoLong": "(Neutrals):\nAs the Solsticer, you won't die, and you win by finishing all your tasks in a single round. After every meeting finishes, your tasks reset, and you need to start all over again.\nVotes on the Solsticer will be directly canceled.\nKill attempts on the Solsticer will teleport it out of the map like Pelican until the meeting is finished.\nThe killer's kill cooldown will be reset to 10 seconds.\nSolsticer is counted as nothing in-game.", + "CollectorInfoLong": "(Neutrals):\nAs the Collector, when you vote for a player, for each other player that voted for them, you gain a point. When you collect the required votes, the game ends, and you win alone, even if you voted a Jester or Executioner's target out.", + "GlitchInfoLong": "(Neutrals):\nAs the Glitch, you can hack players (single click) or kill normally (double click).\nThose who have been hacked cannot kill, vent, or report for the hack duration.\nAdditionally, calling a sabotage other than doors will have no effect and will instead disguise you as a random player. You cannot disguise during or after sabotages.\nTo win, be the last player alive.", "SidekickInfoLong": "(Neutrals):\nAs the Sidekick, your job is to help the Jackal kill everyone.\nYou and the Jackal win together.\nDepending on the settings, you may turn into Jackal if old Jackal was killed.\nYou may not be able to kill until old Jackal is dead.", - "ProvocateurInfoLong": "(Neutrals):\nAs the Provocateur, you can kill any target with the kill button. If the target loses at the end of the game, the Provocateur wins with the winning team.", - "BloodKnightInfoLong": "(Neutrals):\nThe Blood Knight wins when they're the last killing role alive, and the amount of crewmates is lower or equal to the amount of Blood Knights. The Blood Knight gains a temporary shield after every kill, making them immortal for a few seconds.", - "PlagueBearerInfoLong": "(Apocalypse):\nAs the Plaguebearer, plague everyone using your kill button to turn into Pestilence.\nOnce you turn into Pestilence, you will become immortal and gain the ability to kill, and you will kill anyone who tries to kill you.\n\nAlso, when infected players interact with uninfected players, they will also be infected.", - "PestilenceInfoLong": "(Apocalypse):\nAs Pestilence, you're an unstoppable machine.\nAny attack towards you will be reflected towards them.\nIndirect kills don't even kill you.\n\nOnly way to kill Pestilence is by voting them out or the Pestilence misguessing.\nYour presence is announced to everyone at the meeting after you transform.", - "SoulCollectorInfoLong": "(Apocalypse):\nAs Soul Collector, you can use your kill button on a player to predict their death. You will gain a soul if your target dies in the round you select them or the meeting after.\nYour target resets after each meeting or after they die, whichever comes first. \n\nOnce you collect the configurable amount of souls, you become Death. If the gain passive souls setting is enabled, you will gain a soul each meeting.", - "DeathInfoLong": "(Apocalypse):\nOnce the Soul Collector has collected their needed souls, they become Death. Death kills everyone and wins if Death is not ejected by the end of the next meeting.\nA configurable amount of extra meeting time will be given on the meeting Death transforms to have more discussion to find Death.\n\nYou are invincible, and your presence is announced to everyone at the meeting after you transform.", - "BakerInfoLong": "(Apocalypse):\nAs the Baker, you can use your kill button on a player per round to give them bread. \nOnce a set amount of players are alive with bread, you become Famine.\n\nIf the Bread gives additional effects and the setting is on, then you can vent to change the bread that you give out. \nBread Effects:\nReveal: Reveals the target's role to the Baker (stays the whole game)\nRoleblock: Sets the target's kill cooldown to 999 (resets to normal after the meeting)\nBarrier: Gives the target a barrier that is only known to the Baker (barrier is removed after the meeting)", - "FamineInfoLong": "(Apocalypse):\nOnce the Baker has a set amount of people with bread alive, they will become Famine. If the Famine does not get voted out after the meeting, then they will become Famine, and every player without bread will starve (excluding other Apocalypse members).\nAfter this starvation of everyone without bread, Famine can use their kill button to starve any remaining players, which will kill those players right before the next meeting.\n\nYou are invincible, and your presence is announced to everyone at the meeting after you transform.", - "BerserkerInfoLong": "(Apocalypse):\nAs the Berserker, you level up with each kill.\nUpon reaching a certain level defined by the Host, you unlock a new power.\n\nScavenged kills make your kills disappear.\nBombed kills make your kills explode. Be careful when killing, as this can kill your other Apocalypse members if they are near. \nAfter a certain level, you become War.", - "WarInfoLong": "(Apocalypse):\nAs War, you are invincible, have a lower kill cooldown, and can kill anyone with your previous powers.\nYour presence is announced to everyone at the meeting after you transform.", - "FollowerInfoLong": "(Neutrals):\nThe Follower can use their Kill button on someone to start following them and can use the Kill button again to switch the following target. If the Follower's target wins, the Follower will win along with them. Note: The Follower can also win after they die.", - "CultistInfoLong": "(Neutrals):\nAs the Cultist, your kill button is used to Charm others, making them win with you. To win, charm all who pose a threat and gain the majority.\nDepending on settings, you may be able to charm Neutrals, and those you Charm may count as their original team, nothing, or a Cultist to determine when you win due to majority.", - "SerialKillerInfoLong": "(Neutrals):\nAs the Serial Killer, you win if you are the last player alive.", - "JuggernautInfoLong": "(Neutrals):\nAs the Juggernaut, your kill cooldown decreases with each kill you make.\n\nKill everyone to win.", - "InfectiousInfoLong": "(Neutrals):\nAs the Infectious, your job is to infect as many players as you can.\n\nIf you infect all the killers, you can outnumber the Crew and win the game.\n\nIf you die, all the players you've infected will die after the next meeting.\nIf they achieve your win condition before then, you can still win.", - "VirusInfoLong": "(Neutrals):\nThe task of the Virus is to kill or infect all other players. When the Virus murders a crewmate, their corpse is infected with a virus. The Crewmate who reports this corpse is infected joins the virus team or dies at the end of the meeting if the Virus doesn't get voted out, depending on the settings. If more players are on the Virus team than the Crewmate team, the Virus team wins.", - "PursuerInfoLong": "(Neutrals):\nAs the Pursuer, you can use your ability on someone to make them misfire when they try to kill.\n\nTo win, survive to the end of the game.", - "SpecterInfoLong": "(Neutrals):\nAs the Specter, your job is to get killed and finish your tasks.\nYou can do your tasks while alive.\nYou cannot win if you're alive.\nIf you get killed, you win with the winning team if your tasks are completed.", - "PirateInfoLong": "(Neutrals):\nAs the Pirate, use your kill button to select a target every round.\nYou will duel with your target in the next meeting. \nIf both the Pirate and the target choose the same number, the Pirate wins.\nAdditionally, if the Pirate wins the duel or the target doesn't participate in the duel, the Pirate kills the target.\n\nDueling command: /duel X (where X can be 0, 1, or 2)\n\nYou win after winning a certain number of duels set by the Host.\n\nNote: The kill would not count towards pirate victory if the target did not participate in the duel.", - "AgitaterInfoLong": "(Neutrals):\nAs the Agitator, your premise is essentially Hot Potato.\n\nUse your kill button on a player to pass the bomb.\nThis can only be done once per round.\n\nThe player who receives the bomb will be notified when receiving said bomb, in which they need to pass it to another player by getting near a player.\n\nWhen a meeting is called, the player with the bomb dies.\n\nIf trying to pass to Pestilence or a Veteran on alert, the bombed player dies instead.\nOptionally, the Agitator cannot receive the bomb.", - "MaverickInfoLong": "(Neutrals):\nAs the Maverick, you can kill and, depending on options, vent and have impostor vision\nIf you survive until the end of the game, you win with the winning team.\nUse your killing ability to eliminate threats to your life, but don't get voted out.", - "CursedSoulInfoLong": "(Neutrals):\nAs the Cursed Soul, you steal the victory if you survive to the end of the game.\n\nYou can steal the win from a Jester or Executioner.\n\nAdditionally, you can steal the souls of other players.\nSoulless players win with you and count as dead.", - "PickpocketInfoLong": "(Neutrals):\nAs the Pickpocket, you steal votes from your kills.\n\nKill everyone to win.", - "TraitorInfoLong": "(Neutrals):\nAs the Traitor, you were an Impostor that betrayed the Impostors.\nYou know the Impostors, but they don't know you.\nThe twist? They can kill you, but you can't kill them.\n\nEliminate the Impostors by other means, then kill everyone else to win!", - "TrollerInfoLong": "(Neutrals):\nAs a Troller, you can complete tasks so that random events can happen to players.\nFor example, changing the speed of all players, teleportation, influencing sabotage, etc.\nAlso you can win with the winning team.", - "VultureInfoLong": "(Neutrals):\nAs the Vulture, report bodies to win!\n\nWhen you report a body, if your eat cooldown is up, you'll eat the body (makes it unreportable).\nIf your eat ability is still on cooldown, then you'll report the body normally.\n\nAdditionally, you'll report bodies normally if the maximum bodies eaten per round is reached.", + "ProvocateurInfoLong": "(Neutrals):\nAs the Provocateur, you can kill any target with the kill button. If the target loses at the end of the game, the Provocateur wins with the winning team.", + "BloodKnightInfoLong": "(Neutrals):\nThe Blood Knight wins when they're the last killing role alive, and the amount of crewmates is lower or equal to the amount of Blood Knights. The Blood Knight gains a temporary shield after every kill, making them immortal for a few seconds.", + "PlagueBearerInfoLong": "(Apocalypse):\nAs the Plaguebearer, plague everyone using your kill button to turn into Pestilence.\nOnce you turn into Pestilence, you will become immortal and gain the ability to kill, and you will kill anyone who tries to kill you.\n\nAlso, when infected players interact with uninfected players, they will also be infected.", + "PestilenceInfoLong": "(Apocalypse):\nAs Pestilence, you're an unstoppable machine.\nAny attack towards you will be reflected towards them.\nIndirect kills don't even kill you.\n\nOnly way to kill Pestilence is by voting them out or the Pestilence misguessing.\nYour presence is announced to everyone at the meeting after you transform.", + "SoulCollectorInfoLong": "(Apocalypse):\nAs Soul Collector, you can use your kill button on a player to predict their death. You will gain a soul if your target dies in the round you select them or the meeting after.\nYour target resets after each meeting or after they die, whichever comes first. \n\nOnce you collect the configurable amount of souls, you become Death. If the gain passive souls setting is enabled, you will gain a soul each meeting.", + "DeathInfoLong": "(Apocalypse):\nOnce the Soul Collector has collected their needed souls, they become Death. Death kills everyone and wins if Death is not ejected by the end of the next meeting.\nA configurable amount of extra meeting time will be given on the meeting Death transforms to have more discussion to find Death.\n\nYou are invincible, and your presence is announced to everyone at the meeting after you transform.", + "BakerInfoLong": "(Apocalypse):\nAs the Baker, you can use your kill button on a player per round to give them bread. \nOnce a set amount of players are alive with bread, you become Famine.\n\nIf the Bread gives additional effects and the setting is on, then you can vent to change the bread that you give out. \nBread Effects:\nReveal: Reveals the target's role to the Baker (stays the whole game)\nRoleblock: Sets the target's kill cooldown to 999 (resets to normal after the meeting)\nBarrier: Gives the target a barrier that is only known to the Baker (barrier is removed after the meeting)", + "FamineInfoLong": "(Apocalypse):\nOnce the Baker has a set amount of people with bread alive, they will become Famine. If the Famine does not get voted out after the meeting, then they will become Famine, and every player without bread will starve (excluding other Apocalypse members).\nAfter this starvation of everyone without bread, Famine can use their kill button to starve any remaining players, which will kill those players right before the next meeting.\n\nYou are invincible, and your presence is announced to everyone at the meeting after you transform.", + "BerserkerInfoLong": "(Apocalypse):\nAs the Berserker, you level up with each kill.\nUpon reaching a certain level defined by the Host, you unlock a new power.\n\nScavenged kills make your kills disappear.\nBombed kills make your kills explode. Be careful when killing, as this can kill your other Apocalypse members if they are near. \nAfter a certain level, you become War.", + "WarInfoLong": "(Apocalypse):\nAs War, you are invincible, have a lower kill cooldown, and can kill anyone with your previous powers.\nYour presence is announced to everyone at the meeting after you transform.", + "FollowerInfoLong": "(Neutrals):\nThe Follower can use their Kill button on someone to start following them and can use the Kill button again to switch the following target. If the Follower's target wins, the Follower will win along with them. Note: The Follower can also win after they die.", + "CultistInfoLong": "(Neutrals):\nAs the Cultist, your kill button is used to Charm others, making them win with you. To win, charm all who pose a threat and gain the majority.\nDepending on settings, you may be able to charm Neutrals, and those you Charm may count as their original team, nothing, or a Cultist to determine when you win due to majority.", + "SerialKillerInfoLong": "(Neutrals):\nAs the Serial Killer, you win if you are the last player alive.", + "JuggernautInfoLong": "(Neutrals):\nAs the Juggernaut, your kill cooldown decreases with each kill you make.\n\nKill everyone to win.", + "InfectiousInfoLong": "(Neutrals):\nAs the Infectious, your job is to infect as many players as you can.\n\nIf you infect all the killers, you can outnumber the Crew and win the game.\n\nIf you die, all the players you've infected will die after the next meeting.\nIf they achieve your win condition before then, you can still win.", + "VirusInfoLong": "(Neutrals):\nThe task of the Virus is to kill or infect all other players. When the Virus murders a crewmate, their corpse is infected with a virus. The Crewmate who reports this corpse is infected joins the virus team or dies at the end of the meeting if the Virus doesn't get voted out, depending on the settings. If more players are on the Virus team than the Crewmate team, the Virus team wins.", + "PursuerInfoLong": "(Neutrals):\nAs the Pursuer, you can use your ability on someone to make them misfire when they try to kill.\n\nTo win, survive to the end of the game.", + "SpecterInfoLong": "(Neutrals):\nAs the Specter, your job is to get killed and finish your tasks.\nYou can do your tasks while alive.\nYou cannot win if you're alive.\nIf you get killed, you win with the winning team if your tasks are completed.", + "PirateInfoLong": "(Neutrals):\nAs the Pirate, use your kill button to select a target every round.\nYou will duel with your target in the next meeting. \nIf both the Pirate and the target choose the same number, the Pirate wins.\nAdditionally, if the Pirate wins the duel or the target doesn't participate in the duel, the Pirate kills the target.\n\nDueling command: /duel X (where X can be 0, 1, or 2)\n\nYou win after winning a certain number of duels set by the Host.\n\nNote: The kill would not count towards pirate victory if the target did not participate in the duel.", + "AgitaterInfoLong": "(Neutrals):\nAs the Agitator, your premise is essentially Hot Potato.\n\nUse your kill button on a player to pass the bomb.\nThis can only be done once per round.\n\nThe player who receives the bomb will be notified when receiving said bomb, in which they need to pass it to another player by getting near a player.\n\nWhen a meeting is called, the player with the bomb dies.\n\nIf trying to pass to Pestilence or a Veteran on alert, the bombed player dies instead.\nOptionally, the Agitator cannot receive the bomb.", + "MaverickInfoLong": "(Neutrals):\nAs the Maverick, you can kill and, depending on options, vent and have impostor vision\nIf you survive until the end of the game, you win with the winning team.\nUse your killing ability to eliminate threats to your life, but don't get voted out.", + "CursedSoulInfoLong": "(Neutrals):\nAs the Cursed Soul, you steal the victory if you survive to the end of the game.\n\nYou can steal the win from a Jester or Executioner.\n\nAdditionally, you can steal the souls of other players.\nSoulless players win with you and count as dead.", + "PickpocketInfoLong": "(Neutrals):\nAs the Pickpocket, you steal votes from your kills.\n\nKill everyone to win.", + "TraitorInfoLong": "(Neutrals):\nAs the Traitor, you were an Impostor that betrayed the Impostors.\nYou know the Impostors, but they don't know you.\nThe twist? They can kill you, but you can't kill them.\n\nEliminate the Impostors by other means, then kill everyone else to win!", + "TrollerInfoLong": "(Neutrals):\nAs a Troller, you can complete tasks so that random events can happen to players.\nFor example, changing the speed of all players, teleportation, influencing sabotage, etc.\nAlso you can win with the winning team.", + "VultureInfoLong": "(Neutrals):\nAs the Vulture, report bodies to win!\n\nWhen you report a body, if your eat cooldown is up, you'll eat the body (makes it unreportable).\nIf your eat ability is still on cooldown, then you'll report the body normally.\n\nAdditionally, you'll report bodies normally if the maximum bodies eaten per round is reached.", "AbyssbringerInfoLong": "(Impostors):\nAs the Abyssbringer, you can place black holes. Black holes will suck in players and kill them when colliding with them.", - "TaskinatorInfoLong": "(Neutrals):\nAs the Taskinator, whenever you finish a task, the task will be bombed. When another player completes the bombed task, the bomb will detonate, and the player will die.\n\nYou win if you survive till the end and Crew doesn't win.\n\n Note: Taskinator bombs ignore all protection.", - "BenefactorInfoLong": "(Crewmates):\nAs the Benefactor, whenever you finish a task, that task will be marked. When another player completes the marked task, they get a temporary shield.\n\n Note: Shield only protects from direct kill attacks.", - "MedusaInfoLong": "(Neutrals):\nAs the Medusa, you can stone bodies much like cleaning a body.\nStoned bodies cannot be reported.\n\nKill everyone to win.", - "SpiritcallerInfoLong": "(Neutrals):\nAs the Spiritcaller, your victims become Evil Spirits after they die. These spirits can help you win by freezing other players briefly or blocking their vision. Alternatively, the spirits can give you a shield that protects you briefly from an attempted kill.", + "TaskinatorInfoLong": "(Neutrals):\nAs the Taskinator, whenever you finish a task, the task will be bombed. When another player completes the bombed task, the bomb will detonate, and the player will die.\n\nYou win if you survive till the end and Crew doesn't win.\n\n Note: Taskinator bombs ignore all protection.", + "BenefactorInfoLong": "(Crewmates):\nAs the Benefactor, whenever you finish a task, that task will be marked. When another player completes the marked task, they get a temporary shield.\n\n Note: Shield only protects from direct kill attacks.", + "MedusaInfoLong": "(Neutrals):\nAs the Medusa, you can stone bodies much like cleaning a body.\nStoned bodies cannot be reported.\n\nKill everyone to win.", + "SpiritcallerInfoLong": "(Neutrals):\nAs the Spiritcaller, your victims become Evil Spirits after they die. These spirits can help you win by freezing other players briefly or blocking their vision. Alternatively, the spirits can give you a shield that protects you briefly from an attempted kill.", "AmnesiacInfoLong": "(Neutrals):\nAs the Amnesiac, use your report button to remember a target and get its role.\nTo balance the game, you will not be able to vent after remembering your role if you can't vent as Amnesiac.'", - "ImitatorInfoLong": "(Neutrals):\nAs the Imitator, use your kill button to imitate a player.\n\nYou'll either become a Sheriff, a Refugee, or some Neutral.", - "BanditInfoLong": "(Neutrals):\nAs the Bandit, you can click your kill button one time to steal a player's addon and twice to kill. Depending on the settings, you may instantly steal the addon or after the meeting starts. After the maximum number of steals is reached, you will kill normally. Additionally, if there are no stealable addons on the target or the target is stubborn, you will kill the target.\n\nKill everyone to win.\n\nNote: Cleansed, Last Impostor, and Lovers cannot be stolen.\nNote: If Bandit can vent is on, Nimble will become unstealable.", - "DoppelgangerInfoLong": "(Neutrals):\nAs the Doppelganger, use your kill button to steal a player's identity (their name and skin) and then kill your target.\n\nKill everyone to win.\n\nNote: You cannot steal the target's identity when Camouflage is active.", - "PunchingBagInfoLong": "(Neutrals):\nAs the Punching Bag, your goal is to get attacked a few times to win.\n\nYou cannot be guessed, as that adds to your attack count.", - "DoomsayerInfoLong": "(Neutrals):\nThe Doomsayer can guess the role of a certain player during the meeting.\nIf the Doomsayer guesses a certain number of roles (the number depends on the host settings), then he wins.\nThe guessing command is: /bt [player id] [role]\nYou can see the player's id before the player's name, or use the /id command to view the id of all players.", - "ShroudInfoLong": "(Neutrals):\nAs the Shroud, you do not kill normally.\nInstead, use your kill button to shroud a player.\nShrouded players kill others.\nIf the shrouded player doesn't make a kill, they'll kill themselves after a meeting.\n\nShroud sees shrouded players with a 「◈」mark next to their name.\nShrouded players who did not make a kill will also have the 「◈」mark in meetings, where they'll die if the Shroud is alive by the end of the meeting.", - "WerewolfInfoLong": "(Neutrals):\nAs the Werewolf, you can kill much like any killer.\nHowever, when you kill, any nearby players also die.\nAny player who dies to this will have their death reason as Mauled.\n\nTo balance this, you have a higher kill cooldown than anyone else.", - "ShamanInfoLong": "(Neutrals):\nAs the Shaman, you can use your kill button to select a voodoo doll once per round. If the kill button is used on you, the effect will be deflected onto the voodoo doll.\nIf you survive until the end, you win with the winning team.\nNote: If the killer cannot kill the chosen target, murder is canceled, but if the killer rechecks the Shaman, the killer will kill the Shaman.", - "SeekerInfoLong": "(Neutrals):\nAs the seeker, use your kill button to tag the target. If the seeker tags the wrong player, a point is deducted, and if the seeker tags the correct player, a point will be added.\nAdditionally, the seeker will not be able to move for 5 seconds after every meeting and after getting a new target.\n\nThe seeker needs to collect a certain number of points set by the Host to win.", - "PixieInfoLong": "(Neutrals):\nAs the Pixie, Mark up to x amount of targets each round by using the kill button on them. You must have one of the marked targets ejected when the meeting starts. If unsuccessful, you will commit suicide, except if you didn't mark any targets or all the targets are dead. The selected targets reset to 0 after the meeting ends. If you succeed, you will gain a point. You see all your targets in colored names.\n\nYou win with the winning team when you have certain amounts of points set by the Host.", - "SchrodingersCatInfoLong": "(Neutrals):\nAs Schrodingers Cat, if someone attempts to use the kill button on you, you will block the action and join their team. This blocking ability works only once. By default, you don't have a victory condition, meaning you win only after switching teams.\nIn Addition to this, you will be counted as nothing in the game.\n\nNote: If the killing machine attempts to use its kill button on you, the interaction is not blocked, and you will die.", - "RomanticInfoLong": "(Neutrals):\nThe Romantic can pick their lover partner using their kill button (this can be done at any point of the game). Once they've picked their partner, they can use their kill button to give their partner a temporary shield that protects them from attacks. If their lover partner dies, the Romantic's role will change according to the following conditions:\n1. If their partner was an Impostor, the Romantic becomes the Refugee\n2. If their partner was a Neutral Killer, then they become Ruthless Romantic.\n3. If their partner was a Crewmate or a non-killing neutral, the Romantic becomes the Vengeful Romantic. \n\nThe Romantic wins with the winning team if their partner wins.\nNote: If your role changes, your win condition will be changed accordingly", - "RuthlessRomanticInfoLong": "(Neutrals):\nYou change your roles from Romantic if your partner (A neutral killer) is killed. As a Ruthless Romantic, you win if you kill everyone and are the last one standing. If you win, your dead partner will also win with you.", - "VengefulRomanticInfoLong": "(Neutrals):\nYou change your roles from Romantic if your partner (A crew or non-neutral killer) is killed. As a Vengeful Romantic, your goal is to avenge your partner, which means you must kill the killer of your partner. If you succeed, then you and your partner win with the winning team at the end. If you try to kill someone other than your partner's killer, then you will die by misfire.", - "PoisonerInfoLong": "(Neutrals):\nAs the Poisoner, your kills are delayed.\nKill everyone to win.", - "HexMasterInfoLong": "(Neutrals):\nAs the Hex Master, you can hex players or kill them.\nHexing a player works the same as spelling as a Witch.", - "WraithInfoLong": "(Neutrals):\nAs the Wraith, you can vent to Vanish temporarily. You will still appear visible on your screen. Vent again to become visible. You win if you are the last player remaining.", - "JinxInfoLong": "(Neutrals):\nAs the Jinx, whenever you get attacked, you jinx them, resulting in them dying to a jinx.\nThis has limited uses.\n\nKill off everyone to win.", - "PotionMasterInfoLong": "(Neutrals):\nAs the Potion Master, you have three different potions assigned to three different actions.\n\nSingle click: Reveal role\nDouble click: Kill\nMap: Sabotage\n\nThe reveal potion has a limit.\nWhen you run out, the kill buttons default to killing.", - "NecromancerInfoLong": "(Neutrals):\nAs the Necromancer, you win when you're the last one standing.\nAdditionally when someone tries to kill you, you will block the kill, and you will teleport to a random vent. You will have a limited time to kill your killer. If you succeed in doing so, you live. If the time runs out before you kill your killer, you die permanently. If you try to kill someone else other than your killer, you will die.", + "ImitatorInfoLong": "(Neutrals):\nAs the Imitator, use your kill button to imitate a player.\n\nYou'll either become a Sheriff, a Refugee, or some Neutral.", + "BanditInfoLong": "(Neutrals):\nAs the Bandit, you can click your kill button one time to steal a player's addon and twice to kill. Depending on the settings, you may instantly steal the addon or after the meeting starts. After the maximum number of steals is reached, you will kill normally. Additionally, if there are no stealable addons on the target or the target is stubborn, you will kill the target.\n\nKill everyone to win.\n\nNote: Cleansed, Last Impostor, and Lovers cannot be stolen.\nNote: If Bandit can vent is on, Nimble will become unstealable.", + "DoppelgangerInfoLong": "(Neutrals):\nAs the Doppelganger, use your kill button to steal a player's identity (their name and skin) and then kill your target.\n\nKill everyone to win.\n\nNote: You cannot steal the target's identity when Camouflage is active.", + "PunchingBagInfoLong": "(Neutrals):\nAs the Punching Bag, your goal is to get attacked a few times to win.\n\nYou cannot be guessed, as that adds to your attack count.", + "DoomsayerInfoLong": "(Neutrals):\nThe Doomsayer can guess the role of a certain player during the meeting.\nIf the Doomsayer guesses a certain number of roles (the number depends on the host settings), then he wins.\nThe guessing command is: /bt [player id] [role]\nYou can see the player's id before the player's name, or use the /id command to view the id of all players.", + "ShroudInfoLong": "(Neutrals):\nAs the Shroud, you do not kill normally.\nInstead, use your kill button to shroud a player.\nShrouded players kill others.\nIf the shrouded player doesn't make a kill, they'll kill themselves after a meeting.\n\nShroud sees shrouded players with a 「◈」mark next to their name.\nShrouded players who did not make a kill will also have the 「◈」mark in meetings, where they'll die if the Shroud is alive by the end of the meeting.", + "WerewolfInfoLong": "(Neutrals):\nAs the Werewolf, you can kill much like any killer.\nHowever, when you kill, any nearby players also die.\nAny player who dies to this will have their death reason as Mauled.\n\nTo balance this, you have a higher kill cooldown than anyone else.", + "ShamanInfoLong": "(Neutrals):\nAs the Shaman, you can use your kill button to select a voodoo doll once per round. If the kill button is used on you, the effect will be deflected onto the voodoo doll.\nIf you survive until the end, you win with the winning team.\nNote: If the killer cannot kill the chosen target, murder is canceled, but if the killer rechecks the Shaman, the killer will kill the Shaman.", + "SeekerInfoLong": "(Neutrals):\nAs the seeker, use your kill button to tag the target. If the seeker tags the wrong player, a point is deducted, and if the seeker tags the correct player, a point will be added.\nAdditionally, the seeker will not be able to move for 5 seconds after every meeting and after getting a new target.\n\nThe seeker needs to collect a certain number of points set by the Host to win.", + "PixieInfoLong": "(Neutrals):\nAs the Pixie, Mark up to x amount of targets each round by using the kill button on them. You must have one of the marked targets ejected when the meeting starts. If unsuccessful, you will commit suicide, except if you didn't mark any targets or all the targets are dead. The selected targets reset to 0 after the meeting ends. If you succeed, you will gain a point. You see all your targets in colored names.\n\nYou win with the winning team when you have certain amounts of points set by the Host.", + "SchrodingersCatInfoLong": "(Neutrals):\nAs Schrodingers Cat, if someone attempts to use the kill button on you, you will block the action and join their team. This blocking ability works only once. By default, you don't have a victory condition, meaning you win only after switching teams.\nIn Addition to this, you will be counted as nothing in the game.\n\nNote: If the killing machine attempts to use its kill button on you, the interaction is not blocked, and you will die.", + "RomanticInfoLong": "(Neutrals):\nThe Romantic can pick their lover partner using their kill button (this can be done at any point of the game). Once they've picked their partner, they can use their kill button to give their partner a temporary shield that protects them from attacks. If their lover partner dies, the Romantic's role will change according to the following conditions:\n1. If their partner was an Impostor, the Romantic becomes the Refugee\n2. If their partner was a Neutral Killer, then they become Ruthless Romantic.\n3. If their partner was a Crewmate or a non-killing neutral, the Romantic becomes the Vengeful Romantic. \n\nThe Romantic wins with the winning team if their partner wins.\nNote: If your role changes, your win condition will be changed accordingly", + "RuthlessRomanticInfoLong": "(Neutrals):\nYou change your roles from Romantic if your partner (A neutral killer) is killed. As a Ruthless Romantic, you win if you kill everyone and are the last one standing. If you win, your dead partner will also win with you.", + "VengefulRomanticInfoLong": "(Neutrals):\nYou change your roles from Romantic if your partner (A crew or non-neutral killer) is killed. As a Vengeful Romantic, your goal is to avenge your partner, which means you must kill the killer of your partner. If you succeed, then you and your partner win with the winning team at the end. If you try to kill someone other than your partner's killer, then you will die by misfire.", + "PoisonerInfoLong": "(Neutrals):\nAs the Poisoner, your kills are delayed.\nKill everyone to win.", + "HexMasterInfoLong": "(Neutrals):\nAs the Hex Master, you can hex players or kill them.\nHexing a player works the same as spelling as a Witch.", + "WraithInfoLong": "(Neutrals):\nAs the Wraith, you can vent to Vanish temporarily. You will still appear visible on your screen. Vent again to become visible. You win if you are the last player remaining.", + "JinxInfoLong": "(Neutrals):\nAs the Jinx, whenever you get attacked, you jinx them, resulting in them dying to a jinx.\nThis has limited uses.\n\nKill off everyone to win.", + "PotionMasterInfoLong": "(Neutrals):\nAs the Potion Master, you have three different potions assigned to three different actions.\n\nSingle click: Reveal role\nDouble click: Kill\nMap: Sabotage\n\nThe reveal potion has a limit.\nWhen you run out, the kill buttons default to killing.", + "NecromancerInfoLong": "(Neutrals):\nAs the Necromancer, you win when you're the last one standing.\nAdditionally when someone tries to kill you, you will block the kill, and you will teleport to a random vent. You will have a limited time to kill your killer. If you succeed in doing so, you live. If the time runs out before you kill your killer, you die permanently. If you try to kill someone else other than your killer, you will die.", "ShockerInfoLong": "(Neutrals):\nAs the Shocker, you can mark rooms by doing tasks in them, and then vent to Electrocute anyone in those rooms for a set period of time. When you finish all of your tasks, you get new ones. Note: Doing tasks during that period will mark them for the next ability use.", - "LastImpostorInfoLong": "(Add-ons):\nThis special effect is given to the last surviving Impostor. It significantly reduces their kill cooldown.", - "OverclockedInfoLong": "(Add-ons):\nAs the Overclocked, your kill cooldown is reduced by a percentage.\n\nThis feature is only assigned to roles with a kill button.", - "LoversInfoLong": "(Add-ons):\nLovers are a combination of two players. The Lovers win when they are the last ones standing, and their victory is shared. When one of the Lovers wins, the other also wins together. Lovers can see the 「♥」 next to each other's name. If one of the Lovers dies, the other will die in love (may not die in love according to the Host's settings). When one of the Lovers is exiled in the meeting, the other will die and become a dead body that cannot be reported.", - "MadmateInfoLong": "(Add-ons):\nOnly Crewmates can become Madmate. Madmate's task is to help the Impostors win the game. Madmate will lose if all Impostors are killed/ejected. Madmates may know who are Impostors, and Impostors may know who are Madmates (host settings).\n\nLazy Guy, Celebrity can't become Madmate. Sheriff, Snitch, Nice Guesser, Mayor, and Judge may become Madmate (host settings). Skill changes when the following roles are converted into Madmates:\n\nTime Manager => Doing tasks will reduce meeting time.\nBodyguard => Skill won't activate if the killer is an Impostor.\nGrenadier => Flash bomb will work on Crewmates and Neutrals instead of the Impostors.\nSheriff => Can kill anyone, including Impostors (host settings).\nNice Guesser => Can guess Crewmates and Neutrals\nPsychic => All evil Neutrals and Crewmates' names with the ability to kill will be displayed in Red.\nJudge => Can judge anyone\nPacifist => Their ability only works on Crewmates.", - "WatcherInfoLong": "(Add-ons):\nDuring the meeting, Watcher can see everyone's votes.", - "FlashInfoLong": "(Add-ons):\nThe Flash's default movement speed is faster than others. (speed depends on the setting of the Host)", - "TorchInfoLong": "(Add-ons):\nTorch has max vision and is not affected by Lights sabotage.", - "SeerInfoLong": "(Add-ons):\nWhenever a player dies, the Seer will see a kill-flash (a red flash, possibly accompanied by an alarm sound like sabotage).", - "TiebreakerInfoLong": "(Add-ons):\nWhen tie vote, priority will be given to the target voted by the Tiebreaker. Note: If multiple Tiebreakers choose different tie targets simultaneously, the skills of the Tiebreaker will not take effect.", - "ObliviousInfoLong": "(Add-ons):\nDetective and Cleaners won't be Oblivious. The Oblivious cannot report dead bodies. Note: Bait killed by Oblivious will still report automatically, and Oblivious can still be used as a scapegoat for Anonymous.", - "BewilderInfoLong": "(Add-ons):\nBewilder may have a smaller/bigger vision. When the Bewilder has died, the murderer's vision may become the same as the Bewilder's, depending on the settings.", - "WorkhorseInfoLong": "(Add-ons):\nThe first player to complete all the tasks will become Workhorse, and Workhorse will give the player extra tasks. The Host sets the number of additional tasks.", - "FoolInfoLong": "(Add-ons):\nSleuth and Mechanic won't be Fool. Fools can't repair any sabotage.", - "AvangerInfoLong": "(Add-ons):\nHost can set whether the Impostor can become an Avenger. When the Avenger is killed (voted out, and irregular kills will not count), the Avenger will revenge a random player.", - "YoutuberInfoLong": "(Add-ons):\nOnly Crewmate will become YouTuber. When the YouTuber is the first player to die in the game, the YouTuber will win alone. If the YouTuber does not meet the win conditions, the YouTuber will follow the Crewmate to win. Note: Indirect killing methods such as being exiled, being guessed by the Guesser, etc., will not trigger the skills of the YouTuber.", - "EgoistInfoLong": "(Add-ons):\nMadmate and Neutrals won't be Egoist. If the Egoist's team wins, the Egoist wins instead of their team.", - "StealerInfoLong": "(Add-ons):\nEvery time a Stealer kills a person, he gets an additional vote (the Host sets the vote number, and the decimal is rounded down).\nAlso, extra votes from the Stealer are hidden during the meeting depending on the options.", - "ParanoiaInfoLong": "(Add-ons):\nNot assigned to Neutrals nor Madmates.\nAs the Paranoia, you will be considered as two players in the game to determine when the game ends due to killers having the majority. Additionally, this grants you an extra vote, depending on options.", - "MimicInfoLong": "(Add-ons):\nOnly Impostor can become Mimic. When the Mimic is dead, other Impostors will receive a message once a meeting is called. This message will include information on roles which the Mimic killed.", - "GuesserInfoLong": "(Add-ons):\nAs a guesser, guess the roles of players in meetings to kill them.\nGuessing the incorrect role kills you instead.\nThe guessing command is: /bt [player id] [role]\nYou can see the player's id before the player's name or use the /id command to view the id of all players.", - "NecroviewInfoLong": "(Add-ons):\nThe Necroview can see the teams of dead players. The following info will be displayed on the dead player's name while in a meeting:\n- The Red name indicates the Impostors.\n- The Cyan name indicates the Crewmates.\n- The Gray name indicates the Neutrals.", - "ReachInfoLong": "(Add-on)\nOnly roles with a kill button can get this add-on. Unlike everyone else, you have the longest kill range possible in the game.", - "BaitInfoLong": "(Add-ons):\nWhen the Bait dies, the murderer who killed the Bait will self-report the Bait's body. However, this won't happen when a Scavenger, Cleaner, Swooper, Wraith, Medusa, or Killing Machine kills the Bait. The report may have a delay according to the Host's settings.", - "TrapperInfoLong": "(Add-ons):\nWhen Beartrap dies, Beartrap immobilizes killer for a configurable amount of time.", - "CharmedInfoLong": "(Betrayal Add-ons):\nThe Charmed add-on is obtained by being charmed by the Cultist.\nOnce charmed, you are now on the Cultist's team and no longer on your original team.", - "CleansedInfoLong": "(Add-ons):\nCleansed Add-on can only be obtained if cleanser erases all your Add-ons. Depending on the cleanser settings, you may not be able to obtain any more Add-ons in the future.", - "InfectedInfoLong": "(Betrayal Add-ons):\nThe Infected add-on is obtained by being infected by the Infectious.\nOnce infected, you work for the Infectious and do not win with your original team.", - "OnboundInfoLong": "(Add-ons):\nWith the Onbound add-on, you cannot be guessed in meetings.", - "ReboundInfoLong": "(Add-ons):\nWith the Rebound add-on, if a Guesser successfully guessed you or a Judge successfully judged you, they will die instead.\nIf a player with Double Shot guesses you correctly, they will die instantly.", - "MundaneInfoLong": "(Add-ons):\nAs Mundane, you can only guess once you complete all of your tasks.", - "KnightedInfoLong": "(Add-ons):\nWhen a Monarch knights someone, they get an extra vote.", - "UnreportableInfoLong": "(Add-ons):\nWith the Disregarded add-on, your corpse will be unreportable.", - "ContagiousInfoLong": "(Betrayal Add-ons):\nWhen the Virus infects you, you become contagious.\nContagious players are on the Virus team.\n\nWhether or not you die after a meeting depends on the settings for the Virus.", - "LuckyInfoLong": "(Add-ons):\nWith the Lucky add-on, there is a probability for you to evade the kill; the Host sets the specific probability. The killer will see the shield animation when the evasion takes effect, but you will not know anything.", - "DoubleShotInfoLong": "(Add-ons):\nWhen a player with Double Shot guesses a role incorrectly, they will get a second chance to guess, but the next wrong guess will result in suicide.", - "RascalInfoLong": "(Add-ons):\nAs the Rascal, you can die to the Sheriff, and Snitch can find you if Snitch can find madmates.\n\nOnly assigned to Crewmates, cannot be assigned by the Merchant.", - "SoullessInfoLong": "(Add-ons):\nWhen a Cursed Soul steals your soul, you get this add-on.\n\nYou are not counted as alive.", - "GravestoneInfoLong": "(Add-ons):\nAs the Gravestone, your role is revealed to everyone when you die.", - "LazyInfoLong": "(Add-ons):\nAs the Lazy, you are assigned a single short task and are immune to Warlocks, Puppeteers, and Gangsters.", - "AutopsyInfoLong": "(Add-ons):\nAs the Autopsy, you can see how people died.\n\nCannot be assigned to Doctor, Tracefinder, Scientist, or Sunnyboy.", - "RebirthInfoLong": "(Add-ons):\nAs the Rebirth, if you're the player about to be ejected, you will swap skins with a random crewmate who voted for you.\nNotice: The host vote never counts\nRebirth will be removed from you if you exhausted all your rebirths.", - "LoyalInfoLong": "(Add-ons):\nAs the Loyal, you cannot be recruited by roles such as Jackal or Cultist.\n\nCannot be assigned to neutrals.", - "EvilSpiritInfoLong": "(Add-ons):\nAs Evil Spirit, it's your job to help the Spiritcaller to victory. You can use your Haunt button to freeze players and reduce their vision. Alternatively, you can use your Haunt button to give the Spiritcaller a shield against a kill attempt temporarily.", + "LastImpostorInfoLong": "(Add-ons):\nThis special effect is given to the last surviving Impostor. It significantly reduces their kill cooldown.", + "OverclockedInfoLong": "(Add-ons):\nAs the Overclocked, your kill cooldown is reduced by a percentage.\n\nThis feature is only assigned to roles with a kill button.", + "LoversInfoLong": "(Add-ons):\nLovers are a combination of two players. The Lovers win when they are the last ones standing, and their victory is shared. When one of the Lovers wins, the other also wins together. Lovers can see the 「♥」 next to each other's name. If one of the Lovers dies, the other will die in love (may not die in love according to the Host's settings). When one of the Lovers is exiled in the meeting, the other will die and become a dead body that cannot be reported.", + "MadmateInfoLong": "(Add-ons):\nOnly Crewmates can become Madmate. Madmate's task is to help the Impostors win the game. Madmate will lose if all Impostors are killed/ejected. Madmates may know who are Impostors, and Impostors may know who are Madmates (host settings).\n\nLazy Guy, Celebrity can't become Madmate. Sheriff, Snitch, Nice Guesser, Mayor, and Judge may become Madmate (host settings). Skill changes when the following roles are converted into Madmates:\n\nTime Manager => Doing tasks will reduce meeting time.\nBodyguard => Skill won't activate if the killer is an Impostor.\nGrenadier => Flash bomb will work on Crewmates and Neutrals instead of the Impostors.\nSheriff => Can kill anyone, including Impostors (host settings).\nNice Guesser => Can guess Crewmates and Neutrals\nPsychic => All evil Neutrals and Crewmates' names with the ability to kill will be displayed in Red.\nJudge => Can judge anyone\nPacifist => Their ability only works on Crewmates.", + "WatcherInfoLong": "(Add-ons):\nDuring the meeting, Watcher can see everyone's votes.", + "FlashInfoLong": "(Add-ons):\nThe Flash's default movement speed is faster than others. (speed depends on the setting of the Host)", + "TorchInfoLong": "(Add-ons):\nTorch has max vision and is not affected by Lights sabotage.", + "SeerInfoLong": "(Add-ons):\nWhenever a player dies, the Seer will see a kill-flash (a red flash, possibly accompanied by an alarm sound like sabotage).", + "TiebreakerInfoLong": "(Add-ons):\nWhen tie vote, priority will be given to the target voted by the Tiebreaker. Note: If multiple Tiebreakers choose different tie targets simultaneously, the skills of the Tiebreaker will not take effect.", + "ObliviousInfoLong": "(Add-ons):\nDetective and Cleaners won't be Oblivious. The Oblivious cannot report dead bodies. Note: Bait killed by Oblivious will still report automatically, and Oblivious can still be used as a scapegoat for Anonymous.", + "BewilderInfoLong": "(Add-ons):\nBewilder may have a smaller/bigger vision. When the Bewilder has died, the murderer's vision may become the same as the Bewilder's, depending on the settings.", + "WorkhorseInfoLong": "(Add-ons):\nThe first player to complete all the tasks will become Workhorse, and Workhorse will give the player extra tasks. The Host sets the number of additional tasks.", + "FoolInfoLong": "(Add-ons):\nSleuth and Mechanic won't be Fool. Fools can't repair any sabotage.", + "AvangerInfoLong": "(Add-ons):\nHost can set whether the Impostor can become an Avenger. When the Avenger is killed (voted out, and irregular kills will not count), the Avenger will revenge a random player.", + "YoutuberInfoLong": "(Add-ons):\nOnly Crewmate will become YouTuber. When the YouTuber is the first player to die in the game, the YouTuber will win alone. If the YouTuber does not meet the win conditions, the YouTuber will follow the Crewmate to win. Note: Indirect killing methods such as being exiled, being guessed by the Guesser, etc., will not trigger the skills of the YouTuber.", + "EgoistInfoLong": "(Add-ons):\nMadmate and Neutrals won't be Egoist. If the Egoist's team wins, the Egoist wins instead of their team.", + "StealerInfoLong": "(Add-ons):\nEvery time a Stealer kills a person, he gets an additional vote (the Host sets the vote number, and the decimal is rounded down).\nAlso, extra votes from the Stealer are hidden during the meeting depending on the options.", + "ParanoiaInfoLong": "(Add-ons):\nNot assigned to Neutrals nor Madmates.\nAs the Paranoia, you will be considered as two players in the game to determine when the game ends due to killers having the majority. Additionally, this grants you an extra vote, depending on options.", + "MimicInfoLong": "(Add-ons):\nOnly Impostor can become Mimic. When the Mimic is dead, other Impostors will receive a message once a meeting is called. This message will include information on roles which the Mimic killed.", + "GuesserInfoLong": "(Add-ons):\nAs a guesser, guess the roles of players in meetings to kill them.\nGuessing the incorrect role kills you instead.\nThe guessing command is: /bt [player id] [role]\nYou can see the player's id before the player's name or use the /id command to view the id of all players.", + "NecroviewInfoLong": "(Add-ons):\nThe Necroview can see the teams of dead players. The following info will be displayed on the dead player's name while in a meeting:\n- The Red name indicates the Impostors.\n- The Cyan name indicates the Crewmates.\n- The Gray name indicates the Neutrals.", + "ReachInfoLong": "(Add-on)\nOnly roles with a kill button can get this add-on. Unlike everyone else, you have the longest kill range possible in the game.", + "BaitInfoLong": "(Add-ons):\nWhen the Bait dies, the murderer who killed the Bait will self-report the Bait's body. However, this won't happen when a Scavenger, Cleaner, Swooper, Wraith, Medusa, or Killing Machine kills the Bait. The report may have a delay according to the Host's settings.", + "TrapperInfoLong": "(Add-ons):\nWhen Beartrap dies, Beartrap immobilizes killer for a configurable amount of time.", + "CharmedInfoLong": "(Betrayal Add-ons):\nThe Charmed add-on is obtained by being charmed by the Cultist.\nOnce charmed, you are now on the Cultist's team and no longer on your original team.", + "CleansedInfoLong": "(Add-ons):\nCleansed Add-on can only be obtained if cleanser erases all your Add-ons. Depending on the cleanser settings, you may not be able to obtain any more Add-ons in the future.", + "InfectedInfoLong": "(Betrayal Add-ons):\nThe Infected add-on is obtained by being infected by the Infectious.\nOnce infected, you work for the Infectious and do not win with your original team.", + "OnboundInfoLong": "(Add-ons):\nWith the Onbound add-on, you cannot be guessed in meetings.", + "ReboundInfoLong": "(Add-ons):\nWith the Rebound add-on, if a Guesser successfully guessed you or a Judge successfully judged you, they will die instead.\nIf a player with Double Shot guesses you correctly, they will die instantly.", + "MundaneInfoLong": "(Add-ons):\nAs Mundane, you can only guess once you complete all of your tasks.", + "KnightedInfoLong": "(Add-ons):\nWhen a Monarch knights someone, they get an extra vote.", + "UnreportableInfoLong": "(Add-ons):\nWith the Disregarded add-on, your corpse will be unreportable.", + "ContagiousInfoLong": "(Betrayal Add-ons):\nWhen the Virus infects you, you become contagious.\nContagious players are on the Virus team.\n\nWhether or not you die after a meeting depends on the settings for the Virus.", + "LuckyInfoLong": "(Add-ons):\nWith the Lucky add-on, there is a probability for you to evade the kill; the Host sets the specific probability. The killer will see the shield animation when the evasion takes effect, but you will not know anything.", + "DoubleShotInfoLong": "(Add-ons):\nWhen a player with Double Shot guesses a role incorrectly, they will get a second chance to guess, but the next wrong guess will result in suicide.", + "RascalInfoLong": "(Add-ons):\nAs the Rascal, you can die to the Sheriff, and Snitch can find you if Snitch can find madmates.\n\nOnly assigned to Crewmates, cannot be assigned by the Merchant.", + "SoullessInfoLong": "(Add-ons):\nWhen a Cursed Soul steals your soul, you get this add-on.\n\nYou are not counted as alive.", + "GravestoneInfoLong": "(Add-ons):\nAs the Gravestone, your role is revealed to everyone when you die.", + "LazyInfoLong": "(Add-ons):\nAs the Lazy, you are assigned a single short task and are immune to Warlocks, Puppeteers, and Gangsters.", + "AutopsyInfoLong": "(Add-ons):\nAs the Autopsy, you can see how people died.\n\nCannot be assigned to Doctor, Tracefinder, Scientist, or Sunnyboy.", + "RebirthInfoLong": "(Add-ons):\nAs the Rebirth, if you're the player about to be ejected, you will swap skins with a random crewmate who voted for you.\nNotice: The host vote never counts\nRebirth will be removed from you if you exhausted all your rebirths.", + "LoyalInfoLong": "(Add-ons):\nAs the Loyal, you cannot be recruited by roles such as Jackal or Cultist.\n\nCannot be assigned to neutrals.", + "EvilSpiritInfoLong": "(Add-ons):\nAs Evil Spirit, it's your job to help the Spiritcaller to victory. You can use your Haunt button to freeze players and reduce their vision. Alternatively, you can use your Haunt button to give the Spiritcaller a shield against a kill attempt temporarily.", "RecruitInfoLong": "(Betrayal Add-ons):\nAs a recruit, you are on the Jackal's team and help out the Jackal and their Sidekicks.\nYou cannot win with your original team.\nDepending on the settings, you may turn into Jackal if old Jackal was killed and no sidekicks is alive.", - "AdmiredInfoLong": "(Betrayal Add-ons):\nAs an admired player, you win with the crew and not your original team.\n\nYou can see the Admirer.", - "GlowInfoLong": "(Add-ons):\nDuring lights out, you and players nearby you will receive a vision boost.", - "RadarInfoLong": "(Add-ons):\nAs Radar, you have arrows pointing towards the closest person at all times.", - "DiseasedInfoLong": "(Add-ons):\nWhen someone tries to use the kill button on you, their cooldown will be increased by a configurable amount of time.", - "AntidoteInfoLong": "(Add-ons):\nWhen someone tries to use the kill button on you, their cooldown will be decreased by a configurable amount of time.", - "StubbornInfoLong": "(Add-ons):\nWith the Stubborn add-on, Eraser can't erase your role, Cleanser can't cleanse you, Bandit can't steal from you, and Monarch can't knight you.\nAdditionally, you can't gain any new add-ons from the Merchant.", - "SwiftInfoLong": "(Add-ons):\nAs the Swift, you will not make any movement when you kill.\nNote: Swift also ignores Bait", - "UnluckyInfoLong": "(Add-ons):\nAs Unlucky, when you complete tasks, kill, venting, or open door, you have a chance to die.", - "SpurtInfoLong": "(Add-ons):\nWhen you start walking, you gain an enormous speed boost, which swiftly deteriorates, until you have to rest still for a while to rejuvenate your speed.", - "VoidBallotInfoLong": "(Add-ons):\nHolder of this add-on will have 0 vote count.", - "AwareInfoLong": "(Add-ons):\nAs the Aware, you get a notification in the next meeting if a revealing role had interacted with you.", - "FragileInfoLong": "(Add-ons):\nAs Fragile, you will instantly die if someone tries to use the kill button on you (even if the role cannot directly kill).", - "GhoulInfoLong": "(Add-ons):\nAs the Ghoul, one of two outcomes can occur on task completion.\n\nIf alive: Suicide\nIf dead: You kill your killer if they're alive.\n\nThis is only assigned to crewmates, and not crewmates with no tasks or are task-based.", - "BloodthirstInfoLong": "(Add-ons):\nAs the Bloodthirst, doing tasks allows you to become bloodthirsty and kill players.\nWhen you finish a task, the next player you come in contact with dies.\n\nYour Bloodthirst remains after a meeting.\nUpon making a kill, your Bloodthirst clears till the next task you complete.\nBloodthirsts do not stack.\n\nOnly assigned to crewmates with tasks.", - "MareInfoLong": "(Add-ons):\nAs the Mare, you have a low kill cooldown and have higher speed but can only kill during lights.\n\nAdditionally, your name will appear in red during lights.\n\nOnly assigned to Impostors and cannot be guessed.", - "BurstInfoLong": "(Add-ons):\nAs the Burst, your killer explodes if they aren't inside a vent after a set amount of time.", - "SleuthInfoLong": "(Add-ons):\nAs the Sleuth, you gain info from dead bodies.\n\nOptionally, you may also gain the killer's role.\n\nNot assigned to Detective or Mortician.", - "ClumsyInfoLong": "(Add-ons):\nAs the Clumsy, you have a chance to miss your kill.\n\nWhen you miss, your cooldown is reset, and the target remains untouched.\n\nOnly assigned to killers.", - "CircumventInfoLong": "(Add-ons):\nAs the Circumvent, you can't vent.\n\nOnly assigned to Impostors.", - "NimbleInfoLong": "(Add-ons):\nAs the Nimble, you gain access to the vent button.\n\nOnly assigned to certain crewmates.", - "InfluencedInfoLong": "(Add-ons):\nAs the Influenced, your vote will be forced to the player with the most votes.\nInfluenced vote won't be counted while choosing the exiled player'\nNote that your vote skill still functions on the player you voted first\nIf all the alive players are Influenced, then the vote result won't shift\nCollector cannot become influenced.", - "SilentInfoLong": "(Add-ons):\nAs the Silent, your vote icon won't appear on the result screen.\nSo nobody knows who you voted for.", - "SusceptibleInfoLong": "(Add-ons):\nAs the Susceptible, your death reason will be random.", - "TrickyInfoLong": "(Add-ons):\nAs the Tricky, your kills will have a random death reason.", - "TiredInfoLong": "(Add-ons):\nWhenever Tired kills (or uses kill ability on) someone, alternatively whenever they finish a task, they will temporarily get lower vision & lower speed.", - "StatueInfoLong": "(Add-ons):\nWhenever many people are near the Statue, the Statue is completely frozen or slowed down depending on the settings.", - "EvaderInfoLong": "(Add-ons):\nWhen the Evader gets voted out, there is a chance they will not get ejected. (Chance set by the Host.)", - "CyberInfoLong": "(Add-ons):\nAs the Cyber, you cannot die while in a group.\nDepending on the settings, Imposters, Neutrals, and or Crewmates will know if you die.", - "HurriedInfoLong": "(Add-ons):\nAs the hurried, you must finish all your tasks to win with your team! If you fail with your tasks, you lose.\nHurried hurries to his goal, so it won't get madmate, charmed or so.", - "OiiaiInfoLong": "(Add-ons):\nAs the Oiiai, when you die, you will make your killer forget their role.\nAdditionally, you may pass Oiiai on to the killer, depending on settings.", - "RainbowInfoLong": "(Add-ons):\nAs the rainbow, you change your colors like crazy.", - "GMInfoLong": "(None):\nThe Game Master is an observer role.\nTheir presence does not affect the game, and all players know who the Game Master is. The Game Master role will be assigned to the Host, who will automatically become a ghost at the start of the game.", - "SunnyboyInfoLong": "(Neutrals):\nAs the Sunnyboy, you win if you are dead by the end of the game. The game will not end when you are alive due to killers gaining the majority.\nAdditionally, you have access to portable vitals.", - "BardInfoLong": "(Impostors):\nWhen a bard is alive, the exile confirmation will display a sentence composed by the bard. Whenever the bard completes a creation, the bard's kill cooldown will be permanently halved.", - "WardenInfoLong": "(Crewmates [Ghost]):\nAs the Warden, alert someone of nearby danger, additionally giving them a temporary speed boost.", - "GhastlyInfoLong": "(Crewmates [Ghost]):\nAs the Ghastly, possess an unsuspecting person, after that choose a target for them, now they'll only be able to use their kill (or kill ability) on target until you possess someone else or possess time runs out.", - "MinionInfoLong": "(Impostor [Ghost]):\nAs the Minion, you can temporarily blind non-impostors.", - "DollMasterInfoLong": "(Impostor):\nAs the Dollmaster, you can temporarily take control of any player by using the Shapeshift button and to make them do your Deeds!", - "DoubleAgentInfoLong": "(Impostor):\nAs the Double Agent, you cannot access the kill button. However, you can vote for someone in a meeting to pass a bomb onto them, which can only be done one player at a time. Once the meeting has finished, the bomb will activate and explode in a set amount of time.\nNote: when you pass the bomb onto someone in a meeting, you can vote afterward.\n\nAdditionally depending on settings the Double Agent can diffuse Bastion and Agitator bombs when venting.\n\nThe Double Agent can change roles when they are the Last Imposter, depending on the settings the role can be a Admired Impostor, Trickster, Traitor, or stay as the Double Agent.", - "SlothInfoLong": "(Add-ons):\nThe Sloth's default movement speed is slower than others.\n(Speed depends on the setting of the Host)", - "ProhibitedInfoLong": "(Add-ons):\nAs the Prohibited, you have specific vents that you can't use.\nHow many vents are disabled depends on the Host's settings.", - "EavesdropperInfoLong": "(Add-ons):\nAs the Eavesdropper, you have a chance to read other role/addon information-based messages like Mortician or Sleuth.", - "ApocalypseInfoLong": "(Apocalypse):\nApocalypse members are on a separate team that works together and wins together. If there are multiple Apocalypse roles in the game, they can see each other's roles.\nDepending on the Host's settings, Apocalypse roles can guess or be guessed.", + "AdmiredInfoLong": "(Betrayal Add-ons):\nAs an admired player, you win with the crew and not your original team.\n\nYou can see the Admirer.", + "GlowInfoLong": "(Add-ons):\nDuring lights out, you and players nearby you will receive a vision boost.", + "RadarInfoLong": "(Add-ons):\nAs Radar, you have arrows pointing towards the closest person at all times.", + "DiseasedInfoLong": "(Add-ons):\nWhen someone tries to use the kill button on you, their cooldown will be increased by a configurable amount of time.", + "AntidoteInfoLong": "(Add-ons):\nWhen someone tries to use the kill button on you, their cooldown will be decreased by a configurable amount of time.", + "StubbornInfoLong": "(Add-ons):\nWith the Stubborn add-on, Eraser can't erase your role, Cleanser can't cleanse you, Bandit can't steal from you, and Monarch can't knight you.\nAdditionally, you can't gain any new add-ons from the Merchant.", + "SwiftInfoLong": "(Add-ons):\nAs the Swift, you will not make any movement when you kill.\nNote: Swift also ignores Bait", + "UnluckyInfoLong": "(Add-ons):\nAs Unlucky, when you complete tasks, kill, venting, or open door, you have a chance to die.", + "SpurtInfoLong": "(Add-ons):\nWhen you start walking, you gain an enormous speed boost, which swiftly deteriorates, until you have to rest still for a while to rejuvenate your speed.", + "VoidBallotInfoLong": "(Add-ons):\nHolder of this add-on will have 0 vote count.", + "AwareInfoLong": "(Add-ons):\nAs the Aware, you get a notification in the next meeting if a revealing role had interacted with you.", + "FragileInfoLong": "(Add-ons):\nAs Fragile, you will instantly die if someone tries to use the kill button on you (even if the role cannot directly kill).", + "GhoulInfoLong": "(Add-ons):\nAs the Ghoul, one of two outcomes can occur on task completion.\n\nIf alive: Suicide\nIf dead: You kill your killer if they're alive.\n\nThis is only assigned to crewmates, and not crewmates with no tasks or are task-based.", + "BloodthirstInfoLong": "(Add-ons):\nAs the Bloodthirst, doing tasks allows you to become bloodthirsty and kill players.\nWhen you finish a task, the next player you come in contact with dies.\n\nYour Bloodthirst remains after a meeting.\nUpon making a kill, your Bloodthirst clears till the next task you complete.\nBloodthirsts do not stack.\n\nOnly assigned to crewmates with tasks.", + "MareInfoLong": "(Add-ons):\nAs the Mare, you have a low kill cooldown and have higher speed but can only kill during lights.\n\nAdditionally, your name will appear in red during lights.\n\nOnly assigned to Impostors and cannot be guessed.", + "BurstInfoLong": "(Add-ons):\nAs the Burst, your killer explodes if they aren't inside a vent after a set amount of time.", + "SleuthInfoLong": "(Add-ons):\nAs the Sleuth, you gain info from dead bodies.\n\nOptionally, you may also gain the killer's role.\n\nNot assigned to Detective or Mortician.", + "ClumsyInfoLong": "(Add-ons):\nAs the Clumsy, you have a chance to miss your kill.\n\nWhen you miss, your cooldown is reset, and the target remains untouched.\n\nOnly assigned to killers.", + "CircumventInfoLong": "(Add-ons):\nAs the Circumvent, you can't vent.\n\nOnly assigned to Impostors.", + "NimbleInfoLong": "(Add-ons):\nAs the Nimble, you gain access to the vent button.\n\nOnly assigned to certain crewmates.", + "InfluencedInfoLong": "(Add-ons):\nAs the Influenced, your vote will be forced to the player with the most votes.\nInfluenced vote won't be counted while choosing the exiled player'\nNote that your vote skill still functions on the player you voted first\nIf all the alive players are Influenced, then the vote result won't shift\nCollector cannot become influenced.", + "SilentInfoLong": "(Add-ons):\nAs the Silent, your vote icon won't appear on the result screen.\nSo nobody knows who you voted for.", + "SusceptibleInfoLong": "(Add-ons):\nAs the Susceptible, your death reason will be random.", + "TrickyInfoLong": "(Add-ons):\nAs the Tricky, your kills will have a random death reason.", + "TiredInfoLong": "(Add-ons):\nWhenever Tired kills (or uses kill ability on) someone, alternatively whenever they finish a task, they will temporarily get lower vision & lower speed.", + "StatueInfoLong": "(Add-ons):\nWhenever many people are near the Statue, the Statue is completely frozen or slowed down depending on the settings.", + "EvaderInfoLong": "(Add-ons):\nWhen the Evader gets voted out, there is a chance they will not get ejected. (Chance set by the Host.)", + "CyberInfoLong": "(Add-ons):\nAs the Cyber, you cannot die while in a group.\nDepending on the settings, Imposters, Neutrals, and or Crewmates will know if you die.", + "HurriedInfoLong": "(Add-ons):\nAs the hurried, you must finish all your tasks to win with your team! If you fail with your tasks, you lose.\nHurried hurries to his goal, so it won't get madmate, charmed or so.", + "OiiaiInfoLong": "(Add-ons):\nAs the Oiiai, when you die, you will make your killer forget their role.\nAdditionally, you may pass Oiiai on to the killer, depending on settings.", + "RainbowInfoLong": "(Add-ons):\nAs the rainbow, you change your colors like crazy.", + "GMInfoLong": "(None):\nThe Game Master is an observer role.\nTheir presence does not affect the game, and all players know who the Game Master is. The Game Master role will be assigned to the Host, who will automatically become a ghost at the start of the game.", + "SunnyboyInfoLong": "(Neutrals):\nAs the Sunnyboy, you win if you are dead by the end of the game. The game will not end when you are alive due to killers gaining the majority.\nAdditionally, you have access to portable vitals.", + "BardInfoLong": "(Impostors):\nWhen a bard is alive, the exile confirmation will display a sentence composed by the bard. Whenever the bard completes a creation, the bard's kill cooldown will be permanently halved.", + "WardenInfoLong": "(Crewmates [Ghost]):\nAs the Warden, alert someone of nearby danger, additionally giving them a temporary speed boost.", + "GhastlyInfoLong": "(Crewmates [Ghost]):\nAs the Ghastly, possess an unsuspecting person, after that choose a target for them, now they'll only be able to use their kill (or kill ability) on target until you possess someone else or possess time runs out.", + "MinionInfoLong": "(Impostor [Ghost]):\nAs the Minion, you can temporarily blind non-impostors.", + "DollMasterInfoLong": "(Impostor):\nAs the Dollmaster, you can temporarily take control of any player by using the Shapeshift button and to make them do your Deeds!", + "DoubleAgentInfoLong": "(Impostor):\nAs the Double Agent, you cannot access the kill button. However, you can vote for someone in a meeting to pass a bomb onto them, which can only be done one player at a time. Once the meeting has finished, the bomb will activate and explode in a set amount of time.\nNote: when you pass the bomb onto someone in a meeting, you can vote afterward.\n\nAdditionally depending on settings the Double Agent can diffuse Bastion and Agitator bombs when venting.\n\nThe Double Agent can change roles when they are the Last Imposter, depending on the settings the role can be a Admired Impostor, Trickster, Traitor, or stay as the Double Agent.", + "SlothInfoLong": "(Add-ons):\nThe Sloth's default movement speed is slower than others.\n(Speed depends on the setting of the Host)", + "ProhibitedInfoLong": "(Add-ons):\nAs the Prohibited, you have specific vents that you can't use.\nHow many vents are disabled depends on the Host's settings.", + "EavesdropperInfoLong": "(Add-ons):\nAs the Eavesdropper, you have a chance to read other role/addon information-based messages like Mortician or Sleuth.", + "ApocalypseInfoLong": "(Apocalypse):\nApocalypse members are on a separate team that works together and wins together. If there are multiple Apocalypse roles in the game, they can see each other's roles.\nDepending on the Host's settings, Apocalypse roles can guess or be guessed.", "RevenantInfoLong": "(Neutral):\nAs the Revenant, your goal is to be killed. If you are killed, you will take your killer's role and kill your killer instead. You cannot win before being killed.\nNote that Revenant only works when being directly killed.", - "ShowTextOverlay": "Text Overlay", - "Overlay.GuesserMode": "Guesser Mode", - "Overlay.NoGameEnd": "No Game End", - "Overlay.DebugMode": "Debug Mode", - "Overlay.LowLoadMode": "Low Load Mode", - "Overlay.AllowConsole": "Console", - "DisableShieldAnimations": "Disable Unnecessary Shield Animations", - "DisableKillAnimationOnGuess": "Disable Kill Animation on Guesses", - "AbilityUseGainWithEachTaskCompleted": "Amount of Ability Use Gains With Each Task Completed", - "OutOfAbilityUsesDoMoreTasks": "Out of ability uses! Do tasks to get more!", - "AbilityUseLimit": "Initial Ability Use Limit", - "AbilityInUse": "Ability in use", - "AbilityExpired": "Ability expired, {0} uses remain", + "ShowTextOverlay": "Text Overlay", + "Overlay.GuesserMode": "Guesser Mode", + "Overlay.NoGameEnd": "No Game End", + "Overlay.DebugMode": "Debug Mode", + "Overlay.LowLoadMode": "Low Load Mode", + "Overlay.AllowConsole": "Console", + "DisableShieldAnimations": "Disable Unnecessary Shield Animations", + "DisableKillAnimationOnGuess": "Disable Kill Animation on Guesses", + "AbilityUseGainWithEachTaskCompleted": "Amount of Ability Use Gains With Each Task Completed", + "OutOfAbilityUsesDoMoreTasks": "Out of ability uses! Do tasks to get more!", + "AbilityUseLimit": "Initial Ability Use Limit", + "AbilityInUse": "Ability in use", + "AbilityExpired": "Ability expired, {0} uses remain", "RevenantTargeted": "Your role has changed to {0}", "RevenantCanCopyAddons": "Can Steal Addons", - "ShowArrows": "Has Arrows pointing toward bodies", - "ArrowDelayMin": "Minimum Arrow show-up delay", - "ArrowDelayMax": "Maximum Arrow show-up delay", - "SMUsesUsedWhenFixingReactorOrO2": "Uses it takes to fix Reactor/O2", - "SMUsesUsedWhenFixingLightsOrComms": "Uses it takes to fix Lights/Comms", - - "GrenadierSkillMaxOfUseage": "(Initial) Max number of Grenades", - "ShowSpecificRole": "Know specific roles on Task Completion", - "TimeMasterMaxUses": "(Initial) Max Amount of Ability Uses", - "SwooperVentNormallyOnCooldown": "Swooper vents normally when swooping is on cooldown", - "WraithVentNormallyOnCooldown": "Wraith vents normally when invis is on cooldown", - "DisableMeeting": "Disable Meetings", - "DisableCloseDoor": "Disable Doors Sabotage", - "DisableSabotage": "Disable Sabotages", - "NoGameEnd": "No Game End", - "AllowConsole": "BepInEx Console", - "DebugMode": "Debug Mode", - "SyncButtonMode": "Limit Meeting Times", - "RandomMapsMode": "Random Maps Mode", - "SyncedButtonCount": "Max Number of Emergency Meetings per Game", - "HHSuccessKCDDecrease": "Kill cooldown decrease on killing target", - "HHFailureKCDIncrease": "Kill cooldown increase on killing others", - "HHNumOfTargets": "Number of targets", - "Targets": "Targets: ", - "HHMaxKCD": "Maximum kill cooldown", - "HHMinKCD": "Minimum kill cooldown", - "AllAliveMeeting": "Meeting When No One is Dead", - "AllAliveMeetingTime": "Meeting Time When No One is Dead", - "AdditionalEmergencyCooldown": "Additional Emergency Cooldown", - "AdditionalEmergencyCooldownThreshold": "Minimum Living Players to be Applied", - "AdditionalEmergencyCooldownTime": "Additional Cooldown", - "LadderDeath": "Fall From Ladders", - "LadderDeathChance": "Fall To Death Chance", - "EveryoneCanSeeDeathReason": "Everyone Can See Death Reason", - "DisableSwipeCardTask": "Disable Swipe Card Task", - "DisableSubmitScanTask": "Disable Submit Scan Task", - "DisableUnlockSafeTask": "Disable Unlock Safe Task", - "DisableUploadDataTask": "Disable Upload Data Task", - "DisableStartReactorTask": "Disable Start Reactor Task", - "DisableResetBreakerTask": "Disable Reset Breakers Task", - "DisableShortTasks": "Disable Short Tasks", - "DisableCleanVent": "Disable Clean Vent Task", - "DisableCalibrateDistributor": "Disable Calibrate Distributor Task", - "DisableChartCourse": "Disable Chart Course Task", - "DisableStabilizeSteering": "Disable Stabilize Steering Task", - "DisableCleanO2Filter": "Disable Clean O2 Filter Task", - "DisableUnlockManifolds": "Disable Unlock Manifolds Task", - "DisablePrimeShields": "Disable Prime Shields Task", - "DisableMeasureWeather": "Disable Measure Weather", - "DisableBuyBeverage": "Disable Buy Beverage", - "DisableAssembleArtifact": "Disable Assemble Artifact Task", - "DisableSortSamples": "Disable Sort Samples Task", - "DisableProcessData": "Disable Process Data Task", - "DisableRunDiagnostics": "Disable Run Diagnostics Task", - "DisableRepairDrill": "Disable Repair Drill Task", - "DisableAlignTelescope": "Disable Align Telescope Task", - "DisableRecordTemperature": "Disable Record Temperature Task", - "DisableFillCanisters": "Disable Fill Canisters Task", - "DisableMonitorTree": "Disable Monitor Tree Task", - "DisableStoreArtifacts": "Disable Store Artifacts Task", - "DisablePutAwayPistols": "Disable Put Away Pistols Task", - "DisablePutAwayRifles": "Disable Put Away Rifles Task", - "DisableMakeBurger": "Disable Make Burger Task", - "DisableCleanToilet": "Disable Clean Toilet Task", - "DisableDecontaminate": "Disable Decontaminate Task", - "DisableSortRecords": "Disable Sort Records Task", - "DisableFixShower": "Disable Fix Shower Task", - "DisablePickUpTowels": "Disable Pick Up Towels Task", - "DisablePolishRuby": "Disable Polish Ruby Task", - "DisableDressMannequin": "Disable Dress Mannequin Task", - "DisableCommonTasks": "Disable Common Tasks", - "DisableFixWiring": "Disable Fix Wiring Task", - "DisableEnterIdCode": "Disable Enter ID Code Task", - "DisableInsertKeys": "Disable Insert Keys Task", - "DisableScanBoardingPass": "Disable Scan Boarding Pass Task", - "DisableLongTasks": "Disable Long Tasks", - "DisableAlignEngineOutput": "Disable Align Engine Output Task", - "DisableInspectSample": "Disable Inspect Sample Task", - "DisableEmptyChute": "Disable Empty Chute Task", - "DisableClearAsteroids": "Disable Clear Asteroids Task", - "DisableWaterPlants": "Disable Water Plants Task", - "DisableOpenWaterways": "Disable Open Waterways Task", - "DisableReplaceWaterJug": "Disable Replace Water Jug Task", - "DisableRebootWifi": "Disable Reboot Wifi Task", - "DisableDevelopPhotos": "Disable Develop Photos Task", - "DisableRewindTapes": "Disable Rewind Tapes Task", - "DisableStartFans": "Disable Start Fans Task", - "DisableOtherTasks": "Disable Situational Tasks", - "DisableEmptyGarbage": "Disable Empty Garbage Task", - "DisableFuelEngines": "Disable Fuel Engines Task", - "DisableDivertPower": "Disable Divert Power Task", - "DisableActivateWeatherNodes": "Disable Weather Nodes Task", - "DisableRoastMarshmallow": "Disable Roast Marshmallow", - "DisableCollectSamples": "Disable Collect Samples", - "DisableReplaceParts": "Disable Replace Parts", - "DisableCollectVegetables": "Disable Collect Vegetables", - "DisableMineOres": "Disable Mine Ores", - "DisableExtractFuel": "Disable Extract Fuel", - "DisableCatchFish": "Disable Catch Fish", - "DisablePolishGem": "Disable Polish Gem", - "DisableHelpCritter": "Disable Help Critter", - "DisableHoistSupplies": "Disable Hoist Supplies", - "DisableFixAntenna": "Disable Fix Antenna", - "DisableBuildSandcastle": "Disable Build Sandcastle", - "DisableCrankGenerator": "Disable Crank Generator", - "DisableMonitorMushroom": "Disable Monitor Mushroom", - "DisablePlayVideoGame": "Disable Play Video Game", - "DisableFindSignal": "Disable Find Signal", - "DisableThrowFisbee": "Disable Throw Frisbee", - "DisableLiftWeights": "Disable Lift Weights", - "DisableCollectShells": "Disable Collect Shells", - "SuffixMode": "Suffix", - "SuffixMode.None": "None", - "SuffixMode.Version": "Version", - "SuffixMode.Streaming": "Streaming", - "SuffixMode.Recording": "Recording", - "SuffixMode.RoomHost": "Room Host", - "SuffixMode.OriginalName": "Original Name", - "SuffixMode.DoNotKillMe": "Don't kill me", - "SuffixMode.NoAndroidPlz": "No phones", - "SuffixMode.AutoHost": "Auto-Host", - "SuffixModeText.DoNotKillMe": "Don't kill me", - "SuffixModeText.NoAndroidPlz": "No phones please", - "SuffixModeText.AutoHost": "Auto-hosting", - "FormatNameMode": "Player Name Mode", - "FormatNameModes.None": "Disable", - "FormatNameModes.Color": "Color", - "FormatNameModes.Snacks": "Random", - "DisableEmojiName": "Disable Emoji in names", - "FixFirstKillCooldown": "Override Starting Kill Cooldown", - "FixKillCooldownValue": "Starting Kill Cooldown", - "OverclockedReduction": "Kill Cooldown Reduction", - "GhostCanSeeOtherRoles": "Ghosts Can See Other Roles", + "ShowArrows": "Has Arrows pointing toward bodies", + "ArrowDelayMin": "Minimum Arrow show-up delay", + "ArrowDelayMax": "Maximum Arrow show-up delay", + "SMUsesUsedWhenFixingReactorOrO2": "Uses it takes to fix Reactor/O2", + "SMUsesUsedWhenFixingLightsOrComms": "Uses it takes to fix Lights/Comms", + + "GrenadierSkillMaxOfUseage": "(Initial) Max number of Grenades", + "ShowSpecificRole": "Know specific roles on Task Completion", + "TimeMasterMaxUses": "(Initial) Max Amount of Ability Uses", + "SwooperVentNormallyOnCooldown": "Swooper vents normally when swooping is on cooldown", + "WraithVentNormallyOnCooldown": "Wraith vents normally when invis is on cooldown", + "DisableMeeting": "Disable Meetings", + "DisableCloseDoor": "Disable Doors Sabotage", + "DisableSabotage": "Disable Sabotages", + "NoGameEnd": "No Game End", + "AllowConsole": "BepInEx Console", + "DebugMode": "Debug Mode", + "SyncButtonMode": "Limit Meeting Times", + "RandomMapsMode": "Random Maps Mode", + "SyncedButtonCount": "Max Number of Emergency Meetings per Game", + "HHSuccessKCDDecrease": "Kill cooldown decrease on killing target", + "HHFailureKCDIncrease": "Kill cooldown increase on killing others", + "HHNumOfTargets": "Number of targets", + "Targets": "Targets: ", + "HHMaxKCD": "Maximum kill cooldown", + "HHMinKCD": "Minimum kill cooldown", + "AllAliveMeeting": "Meeting When No One is Dead", + "AllAliveMeetingTime": "Meeting Time When No One is Dead", + "AdditionalEmergencyCooldown": "Additional Emergency Cooldown", + "AdditionalEmergencyCooldownThreshold": "Minimum Living Players to be Applied", + "AdditionalEmergencyCooldownTime": "Additional Cooldown", + "LadderDeath": "Fall From Ladders", + "LadderDeathChance": "Fall To Death Chance", + "EveryoneCanSeeDeathReason": "Everyone Can See Death Reason", + "DisableSwipeCardTask": "Disable Swipe Card Task", + "DisableSubmitScanTask": "Disable Submit Scan Task", + "DisableUnlockSafeTask": "Disable Unlock Safe Task", + "DisableUploadDataTask": "Disable Upload Data Task", + "DisableStartReactorTask": "Disable Start Reactor Task", + "DisableResetBreakerTask": "Disable Reset Breakers Task", + "DisableShortTasks": "Disable Short Tasks", + "DisableCleanVent": "Disable Clean Vent Task", + "DisableCalibrateDistributor": "Disable Calibrate Distributor Task", + "DisableChartCourse": "Disable Chart Course Task", + "DisableStabilizeSteering": "Disable Stabilize Steering Task", + "DisableCleanO2Filter": "Disable Clean O2 Filter Task", + "DisableUnlockManifolds": "Disable Unlock Manifolds Task", + "DisablePrimeShields": "Disable Prime Shields Task", + "DisableMeasureWeather": "Disable Measure Weather", + "DisableBuyBeverage": "Disable Buy Beverage", + "DisableAssembleArtifact": "Disable Assemble Artifact Task", + "DisableSortSamples": "Disable Sort Samples Task", + "DisableProcessData": "Disable Process Data Task", + "DisableRunDiagnostics": "Disable Run Diagnostics Task", + "DisableRepairDrill": "Disable Repair Drill Task", + "DisableAlignTelescope": "Disable Align Telescope Task", + "DisableRecordTemperature": "Disable Record Temperature Task", + "DisableFillCanisters": "Disable Fill Canisters Task", + "DisableMonitorTree": "Disable Monitor Tree Task", + "DisableStoreArtifacts": "Disable Store Artifacts Task", + "DisablePutAwayPistols": "Disable Put Away Pistols Task", + "DisablePutAwayRifles": "Disable Put Away Rifles Task", + "DisableMakeBurger": "Disable Make Burger Task", + "DisableCleanToilet": "Disable Clean Toilet Task", + "DisableDecontaminate": "Disable Decontaminate Task", + "DisableSortRecords": "Disable Sort Records Task", + "DisableFixShower": "Disable Fix Shower Task", + "DisablePickUpTowels": "Disable Pick Up Towels Task", + "DisablePolishRuby": "Disable Polish Ruby Task", + "DisableDressMannequin": "Disable Dress Mannequin Task", + "DisableCommonTasks": "Disable Common Tasks", + "DisableFixWiring": "Disable Fix Wiring Task", + "DisableEnterIdCode": "Disable Enter ID Code Task", + "DisableInsertKeys": "Disable Insert Keys Task", + "DisableScanBoardingPass": "Disable Scan Boarding Pass Task", + "DisableLongTasks": "Disable Long Tasks", + "DisableAlignEngineOutput": "Disable Align Engine Output Task", + "DisableInspectSample": "Disable Inspect Sample Task", + "DisableEmptyChute": "Disable Empty Chute Task", + "DisableClearAsteroids": "Disable Clear Asteroids Task", + "DisableWaterPlants": "Disable Water Plants Task", + "DisableOpenWaterways": "Disable Open Waterways Task", + "DisableReplaceWaterJug": "Disable Replace Water Jug Task", + "DisableRebootWifi": "Disable Reboot Wifi Task", + "DisableDevelopPhotos": "Disable Develop Photos Task", + "DisableRewindTapes": "Disable Rewind Tapes Task", + "DisableStartFans": "Disable Start Fans Task", + "DisableOtherTasks": "Disable Situational Tasks", + "DisableEmptyGarbage": "Disable Empty Garbage Task", + "DisableFuelEngines": "Disable Fuel Engines Task", + "DisableDivertPower": "Disable Divert Power Task", + "DisableActivateWeatherNodes": "Disable Weather Nodes Task", + "DisableRoastMarshmallow": "Disable Roast Marshmallow", + "DisableCollectSamples": "Disable Collect Samples", + "DisableReplaceParts": "Disable Replace Parts", + "DisableCollectVegetables": "Disable Collect Vegetables", + "DisableMineOres": "Disable Mine Ores", + "DisableExtractFuel": "Disable Extract Fuel", + "DisableCatchFish": "Disable Catch Fish", + "DisablePolishGem": "Disable Polish Gem", + "DisableHelpCritter": "Disable Help Critter", + "DisableHoistSupplies": "Disable Hoist Supplies", + "DisableFixAntenna": "Disable Fix Antenna", + "DisableBuildSandcastle": "Disable Build Sandcastle", + "DisableCrankGenerator": "Disable Crank Generator", + "DisableMonitorMushroom": "Disable Monitor Mushroom", + "DisablePlayVideoGame": "Disable Play Video Game", + "DisableFindSignal": "Disable Find Signal", + "DisableThrowFisbee": "Disable Throw Frisbee", + "DisableLiftWeights": "Disable Lift Weights", + "DisableCollectShells": "Disable Collect Shells", + "SuffixMode": "Suffix", + "SuffixMode.None": "None", + "SuffixMode.Version": "Version", + "SuffixMode.Streaming": "Streaming", + "SuffixMode.Recording": "Recording", + "SuffixMode.RoomHost": "Room Host", + "SuffixMode.OriginalName": "Original Name", + "SuffixMode.DoNotKillMe": "Don't kill me", + "SuffixMode.NoAndroidPlz": "No phones", + "SuffixMode.AutoHost": "Auto-Host", + "SuffixModeText.DoNotKillMe": "Don't kill me", + "SuffixModeText.NoAndroidPlz": "No phones please", + "SuffixModeText.AutoHost": "Auto-hosting", + "FormatNameMode": "Player Name Mode", + "FormatNameModes.None": "Disable", + "FormatNameModes.Color": "Color", + "FormatNameModes.Snacks": "Random", + "DisableEmojiName": "Disable Emoji in names", + "FixFirstKillCooldown": "Override Starting Kill Cooldown", + "FixKillCooldownValue": "Starting Kill Cooldown", + "OverclockedReduction": "Kill Cooldown Reduction", + "GhostCanSeeOtherRoles": "Ghosts Can See Other Roles", "PreventSeeRolesImmediatelyAfterDeath": "Prevent seeing other's roles immediately after death", - "GhostCanSeeOtherVotes": "Ghosts Can See Vote Colors", - "GhostCanSeeDeathReason": "Ghost Can See Cause Of Death", - "GhostIgnoreTasks": "Ghosts Exempt From Tasks", - "ConvertedCanBeGhostRole": "Converted Players Can Be Any Ghost-Roles", - "NeutralCanBeGhostRole": "Neutral Players Can Be Any Ghost-Roles (Will change team respectively)", - "MaxImpGhostRole": "Max Impostor Ghost-Roles", - "MaxCrewGhostRole": "Max Crewmate Ghost-Roles", - "DefaultAngelCooldown": "Default Ability Cooldown", - "DisableTaskWin": "Disable Task Win", - "DisableTaskWinIfAllCrewsAreDead": "Disable Task Win If All <#8cffff>Crewmates Are Dead", - "DisableTaskWinIfAllCrewsAreConverted": "Disable Task Win If All <#8cffff>Crewmates Are <#ffab1b>Converted", - "HideGameSettings": "Hide Game Settings", - "DIYGameSettings": "Enable only custom /n messages", - "Settings:": "Settings:", - "VoteAbilityUsed": "Used {0} Ability", - "VoteHasReturned": "Your vote has been returned! (Meaning you can cast a vote normally)", - "VoteNotUseAbility": "You chose not to use your ability, and now may choose to skip or vote someone.", - "PlayerCanSetColor": "Players can use the /color command", - "PlayerCanSetName": "Players can use the /rn command", - "PlayerCanUseQuitCommand": "Players can use the /quit command to leave the lobby forever", - "PlayerCanUseTP": "Players can use the /tpin and /tpout command", - "CanPlayMiniGames": "Players can play mini-games", - "KPDCamouflageMode": "Camouflage Appearance", - "RoleOptions": "Role Options", - "DarkTheme": "Enable Dark Theme", - "DisableLobbyMusic": "Disable Lobby Music", - "AutoStart": "Auto start", - "EnableCustomButton": "Enable Custom Button Images", - "EnableCustomSoundEffect": "Enable Custom Sound Effects", - "EnableCustomDecorations": "Enable Custom Map Decorations", - "SwitchVanilla": "Switch Vanilla", - "UnlockFPS": "Unlock FPS", - "ForceOwnLanguage": "Force mod to use your language if possible", - "ForceOwnLanguageRoleName": "Force role names in your language if possible", - "VersionCheat": "Bypass version synchronization check", - "GodMode": "God Mode", - - "AutoDisplayKillLog": "Display Kill-log", - "AutoDisplayLastRoles": "Display Last Roles", - "AutoDisplayLastResult": "Auto Display Last Result", - "RevertOldKillLog": "Revert to old kill-log", - - "HideExileChat": "Hide exile (lava) chat", - "ExileSpamMsg": "Someone is trying to be a smart ass by lava chatting", - - "EnableYTPlan": "Enable Youtuber Plan", - "InvalidPermissionCMD": "INVALID PERMISSION\n\nSorry, you do not have the permission to use this command, check /me for all permissions", - "KickLowLevelPlayer": "Kick players whose level is lower than", - "TempBanLowLevelPlayer": "Temporarily ban low-level players", - "ApplyWhiteList": "Turn on Whitelist to bypass level kick", - "AllowOnlyWhiteList": "Allow only whitelisted players to join", - "AutoKickStart": "Kick players that say start", - "AutoKickStartTimes": "Number of warnings before kick", - "AutoKickStartAsBan": "Block a player after they're kicked", - "AutoKickStopWords": "Kick players who write banned words", - "AutoKickStopWordsTimes": "Number of warnings for banned words", - "AutoKickStopWordsAsBan": "Block a player after they're kicked", - "AutoWarnStopWords": "Warning to those who write banned words", - "TempBanPlayersWhoKeepQuitting": "Temporarily ban players who leave and join repeatedly", - "QuitTimesTillTempBan": "The quit frequency needed for temp ban", - "KickOtherPlatformPlayer": "Kick Non-PC players", - "OptKickAndroidPlayer": "Kick Android players", - "OptKickIphonePlayer": "Kick iOS players", - "OptKickXboxPlayer": "Kick Xbox players", - "OptKickPlayStationPlayer": "Kick PlayStation players", - "OptKickNintendoPlayer": "Kick Nintendo Switch players", - "ShareLobby": "Allow TOHE-Chan Shares Lobby Code To Discord", - "ShareLobbyMinPlayer": "Share Lobby Code When The Number Of Players Reaches", - "DisableVanillaRoles": "Disable Vanilla Roles", - "VoteMode": "Voting Mode", - "WhenSkipVote": "If the Player Skipped", - "WhenSkipVoteIgnoreFirstMeeting": "Ignore the First Meeting", - "WhenSkipVoteIgnoreNoDeadBody": "Ignore When No Dead Body", - "WhenSkipVoteIgnoreEmergency": "Ignore at Emergency Meetings", - "WhenNonVote": "If the Player didn't vote", - "Default": "Default", - "Suicide": "Suicide", - "SelfVote": "Self Vote", - "Skip": "Skip", - "WhenTie": "When Tied Vote", - "TieMode.Default": "Default", - "TieMode.All": "Eject All", - "TieMode.Random": "Eject Random", - "DisableDevices": "Disable Devices", - "DisableSkeldDevices": "Disable Skeld Devices", - "DisableMiraHQDevices": "Disable MIRA HQ Devices", - "DisablePolusDevices": "Disable Polus Devices", - "DisableAirshipDevices": "Disable Airship Devices", - "DisableFungleDevices": "Disable Fungle Devices", - "DisableSkeldAdmin": "Disable Admin", - "DisableMiraHQAdmin": "Disable Admin", - "DisablePolusAdmin": "Disable Admin", - "DisableAirshipCockpitAdmin": "Disable Cockpit Admin", - "DisableAirshipRecordsAdmin": "Disable Records Admin", - "DisableSkeldCamera": "Disable Cameras", - "DisablePolusCamera": "Disable Cameras", - "DisableAirshipCamera": "Disable Cameras", - "DisableMiraHQDoorLog": "Disable DoorLog", - "DisablePolusVital": "Disable Vitals", - "DisableAirshipVital": "Disable Vitals", - "DisableFungleVital": "Disable Vitals", - "DisableFungleBinoculars": "Disable Binoculars (Not work for vanilla)", - "IgnoreConditions": "Ignore Conditions", - "IgnoreImpostors": "Ignore Impostors", - "IgnoreNeutrals": "Ignore Neutrals", - "IgnoreCrewmates": "Ignore Crewmates", - "IgnoreAfterAnyoneDied": "Ignore After First Death", - "LightsOutSpecialSettings": "Fix Lights Special Settings", - "BlockDisturbancesToSwitches": "Block Switches When They Are Up", - "DisableAirshipViewingDeckLightsPanel": "Disable Viewing Deck Lights Panel (Airship)", - "DisableAirshipGapRoomLightsPanel": "Disable Gap Room Lights Panel (Airship)", - "DisableAirshipCargoLightsPanel": "Disable Cargo Lights Panel (Airship)", - "RandomSpawnMode": "Random Spawns Mode", - "RandomSpawn_SpawnInFirstRound": "Active On Round One", - "RandomSpawn_SpawnRandomLocation": "Random Spawns In Locations", - "RandomSpawn_AirshipAdditionalSpawn": "Additional Spawn Locations (Airship)", - "RandomSpawn_SpawnRandomVents": "Random Spawns On Vents", - "CommsCamouflage": "Camouflage during Comms Sabotage", - "DisableOnSomeMaps": "Disable comms camouflage on some maps", - "DisableOnSkeld": "Disable on The Skeld", - "DisableOnMira": "Disable on MIRA HQ", - "DisableOnPolus": "Disable on Polus", - "DisableOnDleks": "Disable on dlekS ehT", - "DisableOnAirship": "Disable on Airship", - "DisableOnFungle": "Disable on The Fungle", - "DisableReportWhenCC": "Disable body reporting while camouflaged", - "EnableDebugMode": "Enable Debug Mode", - "ChangeNameToRoleInfo": "Show Role Info to Unmodded Clients Round 1", - "SendRoleDescriptionFirstMeeting": "Show Role Descriptions to Unmodded Clients at First Meeting", - "RoleAssigningAlgorithm": "Role Assigning Algorithm", - "RoleAssigningAlgorithm.Default": "Default", - "RoleAssigningAlgorithm.NetRandom": ".NET System.Random", - "RoleAssigningAlgorithm.HashRandom": "HashRandom", - "RoleAssigningAlgorithm.Xorshift": "Xorshift", - "RoleAssigningAlgorithm.MersenneTwister": "MersenneTwister", - "MapModification": "Map Modifications", - "DisableAirshipMovingPlatform": "Disable Moving Platform (Airship)", - "AirshipVariableElectrical": "Variable Electrical (Airship)", - "DisableSporeTriggerOnFungle": "Disable Spore Trigger (Fungle)", - "DisableZiplineOnFungle": "Disable Zipline (Fungle)", - "DisableZiplineFromTop": "Disable Use From Top", - "DisableZiplineFromUnder": "Disable Use From Under", - "ResetDoorsEveryTurns": "Reset Doors After Meeting (Airship/Polus/Fungle)", - "DoorsResetMode": "Reset Doors Mode", - "AllOpen": "All Open", - "AllClosed": "All Closed", - "RandomByDoor": "Closed Random", - "ChangeDecontaminationTime": "Change Decontamination Time (MIRA HQ/Polus)", - "DecontaminationTimeOnMiraHQ": "Decontamination Time On MIRA HQ", - "DecontaminationTimeOnPolus": "Decontamination Time On Polus", - "EnableHalloweenDecorations": "Halloween Decorations (The Skeld/MIRA HQ/Dleks)", - "HalloweenDecorationsSkeld": "Enable On The Skeld", - "HalloweenDecorationsMira": "Enable On MIRA HQ", - "HalloweenDecorationsDleks": "Enable On dlekS ehT", - "EnableBirthdayDecorationSkeld": "Birthday Decoration On The Skeld", - "RandomBirthdayAndHalloweenDecorationSkeld": "Set Random Decoration When Birthday And Halloween Is Active On The Skeld", - "ApplyDenyNameList": "Apply DenyName List", - "KickPlayerFriendCodeInvalid": "Kick players with an invalid friend code", - "TempBanPlayerFriendCodeInvalid": "Temp Ban players with an invalid friend code", - "ApplyBanList": "Apply BanList", - "RemovePetsAtDeadPlayers": "Remove pets at dead players", - "KillFlashDuration": "Kill-Flash Duration", - "ConfirmEjectionsMode": "Confirm Ejections Mode", - "ConfirmEjections.None": "None", - "ConfirmEjections.Team": "Team", - "ConfirmEjections.Role": "Role", - "ShowImpRemainOnEject": "Show remaining Impostors on ejects", - "ShowNKRemainOnEject": "Show remaining Neutral Killers on ejects", - "ShowNARemainOnEject": "Show remaining Neutral Apocalypse on ejects", - "ConfirmEgoistOnEject": "Confirm Egoists on ejection", - "ConfirmLoversOnEject": "Confirm Lovers on ejection", - "ConfirmSidekickOnEject": "Confirm Sidekicks on ejection", - "HideBittenRolesOnEject": "Hide roles of bitten players on ejection", - "ShowTeamNextToRoleNameOnEject": "Show what team the ejected player's role is on", - "Ban": "Ban", - "Kick": "Kick", - "NoticeMe": "Notify me", - "NoticeEveryone": "Notify everyone", - "TempBan": "Temporary Ban", - "OnlyCancel": "Only Cancel the cheat actions", - "CheatResponses": "When a cheating player is found", - "NeutralRoleWinTogether": "Neutrals win together", - "NeutralWinTogether": "All Neutrals win together", - "MenuTitle.Disable": "★ Disable ★", - "MenuTitle.MapsSettings": "★ Maps ★", - "MenuTitle.Sabotage": "★ Sabotage ★", - "MenuTitle.Meeting": "★ Meeting ★", - "MenuTitle.Ghost": "★ Ghost ★", - "MenuTitle.Other": "★ Different ★", - "MenuTitle.Ejections": "★ Ejection ★", - "MenuTitle.Settings": "★ Settings ★", - "MenuTitle.TaskSettings": "★ Task Management ★", - "MenuTitle.Guessers": "★ Guesser Mode ★", - - "ShieldPersonDiedFirst": "Shield player who dead first in the last game", - "ShowShieldedPlayerToAll": "Reveal shielded player to all", - "RemoveShieldOnFirstDead": "Remove shield on first death", - "ShieldedCanUseKillButton": "Shielded player can use ability / kill button", - "PlayerIsShieldedByGame": "Player is protected by the game!", - - "LegacyNemesis": "Use Legacy Version", + "GhostCanSeeOtherVotes": "Ghosts Can See Vote Colors", + "GhostCanSeeDeathReason": "Ghost Can See Cause Of Death", + "GhostIgnoreTasks": "Ghosts Exempt From Tasks", + "ConvertedCanBeGhostRole": "Converted Players Can Be Any Ghost-Roles", + "NeutralCanBeGhostRole": "Neutral Players Can Be Any Ghost-Roles (Will change team respectively)", + "MaxImpGhostRole": "Max Impostor Ghost-Roles", + "MaxCrewGhostRole": "Max Crewmate Ghost-Roles", + "DefaultAngelCooldown": "Default Ability Cooldown", + "DisableTaskWin": "Disable Task Win", + "DisableTaskWinIfAllCrewsAreDead": "Disable Task Win If All <#8cffff>Crewmates Are Dead", + "DisableTaskWinIfAllCrewsAreConverted": "Disable Task Win If All <#8cffff>Crewmates Are <#ffab1b>Converted", + "HideGameSettings": "Hide Game Settings", + "DIYGameSettings": "Enable only custom /n messages", + "Settings:": "Settings:", + "VoteAbilityUsed": "Used {0} Ability", + "VoteHasReturned": "Your vote has been returned! (Meaning you can cast a vote normally)", + "VoteNotUseAbility": "You chose not to use your ability, and now may choose to skip or vote someone.", + "PlayerCanSetColor": "Players can use the /color command", + "PlayerCanSetName": "Players can use the /rn command", + "PlayerCanUseQuitCommand": "Players can use the /quit command to leave the lobby forever", + "PlayerCanUseTP": "Players can use the /tpin and /tpout command", + "CanPlayMiniGames": "Players can play mini-games", + "KPDCamouflageMode": "Camouflage Appearance", + "RoleOptions": "Role Options", + "DarkTheme": "Enable Dark Theme", + "DisableLobbyMusic": "Disable Lobby Music", + "AutoStart": "Auto start", + "EnableCustomButton": "Enable Custom Button Images", + "EnableCustomSoundEffect": "Enable Custom Sound Effects", + "EnableCustomDecorations": "Enable Custom Map Decorations", + "SwitchVanilla": "Switch Vanilla", + "UnlockFPS": "Unlock FPS", + "ForceOwnLanguage": "Force mod to use your language if possible", + "ForceOwnLanguageRoleName": "Force role names in your language if possible", + "VersionCheat": "Bypass version synchronization check", + "GodMode": "God Mode", + + "AutoDisplayKillLog": "Display Kill-log", + "AutoDisplayLastRoles": "Display Last Roles", + "AutoDisplayLastResult": "Auto Display Last Result", + "RevertOldKillLog": "Revert to old kill-log", + + "HideExileChat": "Hide exile (lava) chat", + "ExileSpamMsg": "Someone is trying to be a smart ass by lava chatting", + + "EnableYTPlan": "Enable Youtuber Plan", + "InvalidPermissionCMD": "INVALID PERMISSION\n\nSorry, you do not have the permission to use this command, check /me for all permissions", + "KickLowLevelPlayer": "Kick players whose level is lower than", + "TempBanLowLevelPlayer": "Temporarily ban low-level players", + "ApplyWhiteList": "Turn on Whitelist to bypass level kick", + "AllowOnlyWhiteList": "Allow only whitelisted players to join", + "AutoKickStart": "Kick players that say start", + "AutoKickStartTimes": "Number of warnings before kick", + "AutoKickStartAsBan": "Block a player after they're kicked", + "AutoKickStopWords": "Kick players who write banned words", + "AutoKickStopWordsTimes": "Number of warnings for banned words", + "AutoKickStopWordsAsBan": "Block a player after they're kicked", + "AutoWarnStopWords": "Warning to those who write banned words", + "TempBanPlayersWhoKeepQuitting": "Temporarily ban players who leave and join repeatedly", + "QuitTimesTillTempBan": "The quit frequency needed for temp ban", + "KickOtherPlatformPlayer": "Kick Non-PC players", + "OptKickAndroidPlayer": "Kick Android players", + "OptKickIphonePlayer": "Kick iOS players", + "OptKickXboxPlayer": "Kick Xbox players", + "OptKickPlayStationPlayer": "Kick PlayStation players", + "OptKickNintendoPlayer": "Kick Nintendo Switch players", + "ShareLobby": "Allow TOHE-Chan Shares Lobby Code To Discord", + "ShareLobbyMinPlayer": "Share Lobby Code When The Number Of Players Reaches", + "DisableVanillaRoles": "Disable Vanilla Roles", + "VoteMode": "Voting Mode", + "WhenSkipVote": "If the Player Skipped", + "WhenSkipVoteIgnoreFirstMeeting": "Ignore the First Meeting", + "WhenSkipVoteIgnoreNoDeadBody": "Ignore When No Dead Body", + "WhenSkipVoteIgnoreEmergency": "Ignore at Emergency Meetings", + "WhenNonVote": "If the Player didn't vote", + "Default": "Default", + "Suicide": "Suicide", + "SelfVote": "Self Vote", + "Skip": "Skip", + "WhenTie": "When Tied Vote", + "TieMode.Default": "Default", + "TieMode.All": "Eject All", + "TieMode.Random": "Eject Random", + "DisableDevices": "Disable Devices", + "DisableSkeldDevices": "Disable Skeld Devices", + "DisableMiraHQDevices": "Disable MIRA HQ Devices", + "DisablePolusDevices": "Disable Polus Devices", + "DisableAirshipDevices": "Disable Airship Devices", + "DisableFungleDevices": "Disable Fungle Devices", + "DisableSkeldAdmin": "Disable Admin", + "DisableMiraHQAdmin": "Disable Admin", + "DisablePolusAdmin": "Disable Admin", + "DisableAirshipCockpitAdmin": "Disable Cockpit Admin", + "DisableAirshipRecordsAdmin": "Disable Records Admin", + "DisableSkeldCamera": "Disable Cameras", + "DisablePolusCamera": "Disable Cameras", + "DisableAirshipCamera": "Disable Cameras", + "DisableMiraHQDoorLog": "Disable DoorLog", + "DisablePolusVital": "Disable Vitals", + "DisableAirshipVital": "Disable Vitals", + "DisableFungleVital": "Disable Vitals", + "DisableFungleBinoculars": "Disable Binoculars (Not work for vanilla)", + "IgnoreConditions": "Ignore Conditions", + "IgnoreImpostors": "Ignore Impostors", + "IgnoreNeutrals": "Ignore Neutrals", + "IgnoreCrewmates": "Ignore Crewmates", + "IgnoreAfterAnyoneDied": "Ignore After First Death", + "LightsOutSpecialSettings": "Fix Lights Special Settings", + "BlockDisturbancesToSwitches": "Block Switches When They Are Up", + "DisableAirshipViewingDeckLightsPanel": "Disable Viewing Deck Lights Panel (Airship)", + "DisableAirshipGapRoomLightsPanel": "Disable Gap Room Lights Panel (Airship)", + "DisableAirshipCargoLightsPanel": "Disable Cargo Lights Panel (Airship)", + "RandomSpawnMode": "Random Spawns Mode", + "RandomSpawn_SpawnInFirstRound": "Active On Round One", + "RandomSpawn_SpawnRandomLocation": "Random Spawns In Locations", + "RandomSpawn_AirshipAdditionalSpawn": "Additional Spawn Locations (Airship)", + "RandomSpawn_SpawnRandomVents": "Random Spawns On Vents", + "CommsCamouflage": "Camouflage during Comms Sabotage", + "DisableOnSomeMaps": "Disable comms camouflage on some maps", + "DisableOnSkeld": "Disable on The Skeld", + "DisableOnMira": "Disable on MIRA HQ", + "DisableOnPolus": "Disable on Polus", + "DisableOnDleks": "Disable on dlekS ehT", + "DisableOnAirship": "Disable on Airship", + "DisableOnFungle": "Disable on The Fungle", + "DisableReportWhenCC": "Disable body reporting while camouflaged", + "EnableDebugMode": "Enable Debug Mode", + "ChangeNameToRoleInfo": "Show Role Info to Unmodded Clients Round 1", + "SendRoleDescriptionFirstMeeting": "Show Role Descriptions to Unmodded Clients at First Meeting", + "RoleAssigningAlgorithm": "Role Assigning Algorithm", + "RoleAssigningAlgorithm.Default": "Default", + "RoleAssigningAlgorithm.NetRandom": ".NET System.Random", + "RoleAssigningAlgorithm.HashRandom": "HashRandom", + "RoleAssigningAlgorithm.Xorshift": "Xorshift", + "RoleAssigningAlgorithm.MersenneTwister": "MersenneTwister", + "MapModification": "Map Modifications", + "DisableAirshipMovingPlatform": "Disable Moving Platform (Airship)", + "AirshipVariableElectrical": "Variable Electrical (Airship)", + "DisableSporeTriggerOnFungle": "Disable Spore Trigger (Fungle)", + "DisableZiplineOnFungle": "Disable Zipline (Fungle)", + "DisableZiplineFromTop": "Disable Use From Top", + "DisableZiplineFromUnder": "Disable Use From Under", + "ResetDoorsEveryTurns": "Reset Doors After Meeting (Airship/Polus/Fungle)", + "DoorsResetMode": "Reset Doors Mode", + "AllOpen": "All Open", + "AllClosed": "All Closed", + "RandomByDoor": "Closed Random", + "ChangeDecontaminationTime": "Change Decontamination Time (MIRA HQ/Polus)", + "DecontaminationTimeOnMiraHQ": "Decontamination Time On MIRA HQ", + "DecontaminationTimeOnPolus": "Decontamination Time On Polus", + "EnableHalloweenDecorations": "Halloween Decorations (The Skeld/MIRA HQ/Dleks)", + "HalloweenDecorationsSkeld": "Enable On The Skeld", + "HalloweenDecorationsMira": "Enable On MIRA HQ", + "HalloweenDecorationsDleks": "Enable On dlekS ehT", + "EnableBirthdayDecorationSkeld": "Birthday Decoration On The Skeld", + "RandomBirthdayAndHalloweenDecorationSkeld": "Set Random Decoration When Birthday And Halloween Is Active On The Skeld", + "ApplyDenyNameList": "Apply DenyName List", + "KickPlayerFriendCodeInvalid": "Kick players with an invalid friend code", + "TempBanPlayerFriendCodeInvalid": "Temp Ban players with an invalid friend code", + "ApplyBanList": "Apply BanList", + "RemovePetsAtDeadPlayers": "Remove pets at dead players", + "KillFlashDuration": "Kill-Flash Duration", + "ConfirmEjectionsMode": "Confirm Ejections Mode", + "ConfirmEjections.None": "None", + "ConfirmEjections.Team": "Team", + "ConfirmEjections.Role": "Role", + "ShowImpRemainOnEject": "Show remaining Impostors on ejects", + "ShowNKRemainOnEject": "Show remaining Neutral Killers on ejects", + "ShowNARemainOnEject": "Show remaining Neutral Apocalypse on ejects", + "ConfirmEgoistOnEject": "Confirm Egoists on ejection", + "ConfirmLoversOnEject": "Confirm Lovers on ejection", + "ConfirmSidekickOnEject": "Confirm Sidekicks on ejection", + "HideBittenRolesOnEject": "Hide roles of bitten players on ejection", + "ShowTeamNextToRoleNameOnEject": "Show what team the ejected player's role is on", + "Ban": "Ban", + "Kick": "Kick", + "NoticeMe": "Notify me", + "NoticeEveryone": "Notify everyone", + "TempBan": "Temporary Ban", + "OnlyCancel": "Only Cancel the cheat actions", + "CheatResponses": "When a cheating player is found", + "NeutralRoleWinTogether": "Neutrals win together", + "NeutralWinTogether": "All Neutrals win together", + "MenuTitle.Disable": "★ Disable ★", + "MenuTitle.MapsSettings": "★ Maps ★", + "MenuTitle.Sabotage": "★ Sabotage ★", + "MenuTitle.Meeting": "★ Meeting ★", + "MenuTitle.Ghost": "★ Ghost ★", + "MenuTitle.Other": "★ Different ★", + "MenuTitle.Ejections": "★ Ejection ★", + "MenuTitle.Settings": "★ Settings ★", + "MenuTitle.TaskSettings": "★ Task Management ★", + "MenuTitle.Guessers": "★ Guesser Mode ★", + + "ShieldPersonDiedFirst": "Shield player who dead first in the last game", + "ShowShieldedPlayerToAll": "Reveal shielded player to all", + "RemoveShieldOnFirstDead": "Remove shield on first death", + "ShieldedCanUseKillButton": "Shielded player can use ability / kill button", + "PlayerIsShieldedByGame": "Player is protected by the game!", + + "LegacyNemesis": "Use Legacy Version", "LegacyParasite": "Use Legacy Version", "LegacyTraitor": "Use Legacy Version", - "ArsonistKeepsGameGoing": "Arsonist keeps the game going", - "ArsonistCanIgniteAnytime": "Can Ignite Anytime", - "ArsonistMinPlayersToIgnite": "Minimum doused needed for ignite", - "ArsonistMaxPlayersToIgnite": "Maximum doused needed for ignite", - "PuppeteerDoubleKills": "Puppet dies alongside victim", - "DollMasterPossessionCooldown": "Possession Cooldown", - "DollMasterPossessionDuration": "Possession Duration", - "DollMasterCanKillAsMainBody": "Can kill as the main body", - "DollMasterTargetDiesAfterPossession": "Target dies after possession", - - "DoubleAgentCanDiffuseBombs": "Double Agent can diffuse bombs from other roles", - "DoubleAgentClearBombOnMeetingCall": "Diffuse active bomb on meeting call", - "DoubleAgentCanUseAbilityInCalledMeeting": "If diffused can use ability in called meeting", - "DoubleAgentBombExplosionTimer": "Explosion time", - "DoubleAgentExplosionRadius": "Explosion radius", - "DoubleAgent_DiffusedAgitaterBomb": "Agitator bomb successfully diffused", - "DoubleAgent_DiffusedBastionBomb": "Bastion bomb successfully diffused", - "DoubleAgent_BombExplodesIn": "Bomb Explodes In: {0}s", - "DoubleAgent_BombExploded": "Bomb has exploded!", - "DoubleAgentChangeRoleTo": "Change role on last Imposter", - "DoubleAgentRoleChange": "You have become a: ", - - "MastermindCD": "Manipulate Cooldown", - "MastermindTimeLimit": "Time limit to kill someone", - "MastermindDelay": "Manipulation notification delay", - "ManipulateNotify": "Kill someone in {0}s or die!", - "ManipulatedKilled": "{0} has killed someone", - "SurvivedManipulation": "You survived the Mastermind's manipulation!", - "Glitch_HackCooldown": "Hack Cooldown", - "Glitch_HackDuration": "Hack Duration", - "Glitch_MimicCooldown": "Mimic Cooldown", - "Glitch_MimicDuration": "Mimic Duration", - "Glitch_MimicButtonText": "Mimic", - "Glitch_MimicDur": "Mimic Duration: {0}s", - "Glitch_HackCD": "Hack Cooldown: {0}s", - "Glitch_KCD": "Kill Cooldown: {0}s", - "Glitch_MimicCD": "Mimic Cooldown: {0}s", - "HackedByGlitch": "You are hacked by the Glitch, you can't {0}.", - "GlitchKill": "kill", - "GlitchReport": "report", - "GlitchVent": "vent", - "ShowFPS": "Show FPS", - "FPSGame": "FPS: ", - - "ControlCooldown": "Control Cooldown", - "PoisonCooldown": "Poison Cooldown", - "PoisonerKillDelay": "Poison Kill Delay", - "WardenNotifyLimit": "Max number of alerts", - - "BombCooldown": "Bomb Cooldown", - "Warlock_CanKillSelf": "Can Kill Themselves", - "CrewpostorKnowsAllies": "Knows Impostors", - "AlliesKnowCrewpostor": "Known to Impostors", - "CrewpostorLungeKill": "Crewpostor lunges on kill", - "CrewpostorKillAfterTask": "Number of tasks completed to make one kill", - - "NonNeutralKillingRolesMinPlayer": "Minimum amount of Non-Killing Neutrals", - "NonNeutralKillingRolesMaxPlayer": "Maximum amount of Non-Killing Neutrals", - "NeutralKillingRolesMinPlayer": "Minimum amount of Neutral Killers", - "NeutralKillingRolesMaxPlayer": "Maximum amount of Neutral Killers", - "NeutralApocalypseRolesMinPlayer": "Minimum amount of Neutral Apocalypse", - "NeutralApocalypseRolesMaxPlayer": "Maximum amount of Neutral Apocalypse", - "TNACanBeGuessed": "Transformed Neutral Apocalypse Roles can be guessed", - "ApocCanSeeEachOthersAddOns": "Neutral Apocalypse can see each other's Add-ons", - "ImpsCanSeeEachOthersRoles": "Impostors know the roles of other Impostors", - "ImpsCanSeeEachOthersAddOns": "Impostors can see each other's Add-ons", - "ImpKnowWhosMadmate": "Impostors know Madmates", - "MadmateKnowWhosImp": "Madmates know Impostors", - "MadmateKnowWhosMadmate": "Madmates know each other", - "ImpCanKillMadmate": "Impostors can kill Madmates", - "MadmateCanKillImp": "Madmates can kill Impostors", - "MadmateHasImpostorVision": "Madmates Have Impostor Vision", - "MadmateCanFixSabotage": "Madmates Can Fix Sabotages", - "EGCanGuessImp": "Can Guess Impostor Roles", - "GGCanGuessCrew": "Can Guess Crewmate Roles", - "EGCanGuessAdt": "Can Guess Add-Ons", - "EGCanGuessTaskDoneSnitch": "Can guess Snitch with All Tasks Done", - "GGCanGuessAdt": "Can Guess Add-Ons", - "GuesserCanGuessTimes": "Maximum number of guesses", - "GuesserTryHideMsg": "Try to hide the guesser's command", - "GCanGuessImp": "Impostor can guess Impostor roles", - "GCanGuessCrew": "Crewmate can guess Crewmate roles", - "GCanGuessAdt": "Can guess Add-ons", - "GCanGuessTaskDoneSnitch": "Can guess Snitch with All Tasks Done", - "BountyTargetChangeTime": "Time Until Target Swaps", - "BountySuccessKillCooldown": "Kill Cooldown After Killing Bounty", - "BountyFailureKillCooldown": "Kill Cooldown After Killing Others", - "BountyShowTargetArrow": "Show arrow pointing towards the target", - "DefaultShapeshiftCooldown": "Default Shapeshift Cooldown", - "DeadImpCantSabotage": "Impostors can't sabotage after they've died", - "VampireKillDelay": "Bite Kill Delay", - "VampireTargetDead": "Target died", - "VampireActionMode": "Action Mode", - "Vampire_OnlyBites": "Only Bites", - "Youtuber_KillerWinsWithYouTuber": "The Killer Wins With YouTuber", - "Maverick_MinKillsToWin": "Minimum number of kills to win", - - "Cooldown": "Cooldown", - "AbilityCooldown": "Ability Cooldown", - "SkillLimitTimes": "Max Number of Ability Uses", - "CanKill": "Can Kill", - "KillCooldown": "Kill Cooldown", - "CanVent": "Can Vent", - "CantMoveOnVents": "Can't Move On Vents (Unstable in Dleks map)", - "ImpostorVision": "Has Impostor Vision", - "CanUseSabotage": "Can Sabotage", - "CanHaveAccessToVitals": "Can Have Access To Vitals", - "CanKillImpostors": "Can Kill Impostors", - "CanGuess": "Can Guess in Guesser Mode or as Guesser", - "HideVote": "Hide Vote", - "HideAdditionalVotes": "Hide additional vote(s)", - "CanUseMeetingButton": "Can Call Emergency Meetings", - "ModeSwitchAction": "Switch Action via", - "ShowShapeshiftAnimations": "Show Shapeshift animations", - - "ShapeshifterBase_ShapeshiftCooldown": "Shapeshift Cooldown", - "ShapeshifterBase_ShapeshiftDuration": "Shapeshift Duration", - "ShapeshifterBase_LeaveShapeshiftingEvidence": "Leave Shapeshifting Evidence", - "PhantomBase_InvisCooldown": "Invis Cooldown", - "PhantomBase_InvisDuration": "Invis Duration", - "GuardianAngelBase_ProtectCooldown": "Protect Cooldown", - "GuardianAngelBase_ProtectionDuration": "Protection Duration", - "GuardianAngelBase_ImpostorsCanSeeProtect": "Protect Visible To Impostors", - "ScientistBase_BatteryCooldown": "Vitals Display Cooldown", - "ScientistBase_BatteryDuration": "Battery Duration", - "EngineerBase_VentCooldown": "Vent Cooldown", - "EngineerBase_InVentMaxTime": "Max Time In Vents", - "NoisemakerBase_ImpostorAlert": "Impostors Can Get Alert", - "NoisemakerBase_AlertDuration": "Alert Duration", - "TrackerBase_TrackingCooldown": "Tracking Cooldown", - "TrackerBase_TrackingDuration": "Tracking Duration", - "TrackerBase_TrackingDelay": "Tracking Delay", - - "KamikazeControversialSymbol": "Use controversial symbol", - "MareAddSpeedInLightsOut": "Additional Speed During Lights Out", - "MareKillCooldownInLightsOut": "Kill Cooldown During Lights Out", - "MechanicSkillLimit": "Initial repair use limit", - "MechanicFixesDoors": "Can open all doors in the same building", - "MechanicFixesReactors": "Can Fix Both Reactors Alone", - "MechanicFixesOxygens": "Can Fix Both O2 Alone", - "MechanicFixesCommunications": "Can Fix Both Comms Alone In MIRA HQ", - "MechanicFixesElectrical": "Can Fix Lights With One Switch", - - "SheriffShowShotLimit": "Display Shot Limit next to Role Name", - "SheriffCanKill%role%": "Can Kill %role%", - "SheriffCanKillNeutrals": "Can Kill Neutrals", - "SheriffCanKillNeutralsMode": "Neutral Configuration", - "SheriffCanKillAll": "All ON", - "SheriffCanKillSeparately": "Individual Settings", - "In%team%": "(Team %team%)", - "SheriffMisfireKillsTarget": "Misfire Kills Target", + "ArsonistKeepsGameGoing": "Arsonist keeps the game going", + "ArsonistCanIgniteAnytime": "Can Ignite Anytime", + "ArsonistMinPlayersToIgnite": "Minimum doused needed for ignite", + "ArsonistMaxPlayersToIgnite": "Maximum doused needed for ignite", + "PuppeteerDoubleKills": "Puppet dies alongside victim", + "DollMasterPossessionCooldown": "Possession Cooldown", + "DollMasterPossessionDuration": "Possession Duration", + "DollMasterCanKillAsMainBody": "Can kill as the main body", + "DollMasterTargetDiesAfterPossession": "Target dies after possession", + + "DoubleAgentCanDiffuseBombs": "Double Agent can diffuse bombs from other roles", + "DoubleAgentClearBombOnMeetingCall": "Diffuse active bomb on meeting call", + "DoubleAgentCanUseAbilityInCalledMeeting": "If diffused can use ability in called meeting", + "DoubleAgentBombExplosionTimer": "Explosion time", + "DoubleAgentExplosionRadius": "Explosion radius", + "DoubleAgent_DiffusedAgitaterBomb": "Agitator bomb successfully diffused", + "DoubleAgent_DiffusedBastionBomb": "Bastion bomb successfully diffused", + "DoubleAgent_BombExplodesIn": "Bomb Explodes In: {0}s", + "DoubleAgent_BombExploded": "Bomb has exploded!", + "DoubleAgentChangeRoleTo": "Change role on last Imposter", + "DoubleAgentRoleChange": "You have become a: ", + + "MastermindCD": "Manipulate Cooldown", + "MastermindTimeLimit": "Time limit to kill someone", + "MastermindDelay": "Manipulation notification delay", + "ManipulateNotify": "Kill someone in {0}s or die!", + "ManipulatedKilled": "{0} has killed someone", + "SurvivedManipulation": "You survived the Mastermind's manipulation!", + "Glitch_HackCooldown": "Hack Cooldown", + "Glitch_HackDuration": "Hack Duration", + "Glitch_MimicCooldown": "Mimic Cooldown", + "Glitch_MimicDuration": "Mimic Duration", + "Glitch_MimicButtonText": "Mimic", + "Glitch_MimicDur": "Mimic Duration: {0}s", + "Glitch_HackCD": "Hack Cooldown: {0}s", + "Glitch_KCD": "Kill Cooldown: {0}s", + "Glitch_MimicCD": "Mimic Cooldown: {0}s", + "HackedByGlitch": "You are hacked by the Glitch, you can't {0}.", + "GlitchKill": "kill", + "GlitchReport": "report", + "GlitchVent": "vent", + "ShowFPS": "Show FPS", + "FPSGame": "FPS: ", + + "ControlCooldown": "Control Cooldown", + "PoisonCooldown": "Poison Cooldown", + "PoisonerKillDelay": "Poison Kill Delay", + "WardenNotifyLimit": "Max number of alerts", + + "BombCooldown": "Bomb Cooldown", + "Warlock_CanKillSelf": "Can Kill Themselves", + "CrewpostorKnowsAllies": "Knows Impostors", + "AlliesKnowCrewpostor": "Known to Impostors", + "CrewpostorLungeKill": "Crewpostor lunges on kill", + "CrewpostorKillAfterTask": "Number of tasks completed to make one kill", + + "NonNeutralKillingRolesMinPlayer": "Minimum amount of Non-Killing Neutrals", + "NonNeutralKillingRolesMaxPlayer": "Maximum amount of Non-Killing Neutrals", + "NeutralKillingRolesMinPlayer": "Minimum amount of Neutral Killers", + "NeutralKillingRolesMaxPlayer": "Maximum amount of Neutral Killers", + "NeutralApocalypseRolesMinPlayer": "Minimum amount of Neutral Apocalypse", + "NeutralApocalypseRolesMaxPlayer": "Maximum amount of Neutral Apocalypse", + "TNACanBeGuessed": "Transformed Neutral Apocalypse Roles can be guessed", + "ApocCanSeeEachOthersAddOns": "Neutral Apocalypse can see each other's Add-ons", + "ImpsCanSeeEachOthersRoles": "Impostors know the roles of other Impostors", + "ImpsCanSeeEachOthersAddOns": "Impostors can see each other's Add-ons", + "ImpKnowWhosMadmate": "Impostors know Madmates", + "MadmateKnowWhosImp": "Madmates know Impostors", + "MadmateKnowWhosMadmate": "Madmates know each other", + "ImpCanKillMadmate": "Impostors can kill Madmates", + "MadmateCanKillImp": "Madmates can kill Impostors", + "MadmateHasImpostorVision": "Madmates Have Impostor Vision", + "MadmateCanFixSabotage": "Madmates Can Fix Sabotages", + "EGCanGuessImp": "Can Guess Impostor Roles", + "GGCanGuessCrew": "Can Guess Crewmate Roles", + "EGCanGuessAdt": "Can Guess Add-Ons", + "EGCanGuessTaskDoneSnitch": "Can guess Snitch with All Tasks Done", + "GGCanGuessAdt": "Can Guess Add-Ons", + "GuesserCanGuessTimes": "Maximum number of guesses", + "GuesserTryHideMsg": "Try to hide the guesser's command", + "GCanGuessImp": "Impostor can guess Impostor roles", + "GCanGuessCrew": "Crewmate can guess Crewmate roles", + "GCanGuessAdt": "Can guess Add-ons", + "GCanGuessTaskDoneSnitch": "Can guess Snitch with All Tasks Done", + "BountyTargetChangeTime": "Time Until Target Swaps", + "BountySuccessKillCooldown": "Kill Cooldown After Killing Bounty", + "BountyFailureKillCooldown": "Kill Cooldown After Killing Others", + "BountyShowTargetArrow": "Show arrow pointing towards the target", + "DefaultShapeshiftCooldown": "Default Shapeshift Cooldown", + "DeadImpCantSabotage": "Impostors can't sabotage after they've died", + "VampireKillDelay": "Bite Kill Delay", + "VampireTargetDead": "Target died", + "VampireActionMode": "Action Mode", + "Vampire_OnlyBites": "Only Bites", + "Youtuber_KillerWinsWithYouTuber": "The Killer Wins With YouTuber", + "Maverick_MinKillsToWin": "Minimum number of kills to win", + + "Cooldown": "Cooldown", + "AbilityCooldown": "Ability Cooldown", + "SkillLimitTimes": "Max Number of Ability Uses", + "CanKill": "Can Kill", + "KillCooldown": "Kill Cooldown", + "CanVent": "Can Vent", + "CantMoveOnVents": "Can't Move On Vents (Unstable in Dleks map)", + "ImpostorVision": "Has Impostor Vision", + "CanUseSabotage": "Can Sabotage", + "CanHaveAccessToVitals": "Can Have Access To Vitals", + "CanKillImpostors": "Can Kill Impostors", + "CanGuess": "Can Guess in Guesser Mode or as Guesser", + "HideVote": "Hide Vote", + "HideAdditionalVotes": "Hide additional vote(s)", + "CanUseMeetingButton": "Can Call Emergency Meetings", + "ModeSwitchAction": "Switch Action via", + "ShowShapeshiftAnimations": "Show Shapeshift animations", + + "ShapeshifterBase_ShapeshiftCooldown": "Shapeshift Cooldown", + "ShapeshifterBase_ShapeshiftDuration": "Shapeshift Duration", + "ShapeshifterBase_LeaveShapeshiftingEvidence": "Leave Shapeshifting Evidence", + "PhantomBase_InvisCooldown": "Invis Cooldown", + "PhantomBase_InvisDuration": "Invis Duration", + "GuardianAngelBase_ProtectCooldown": "Protect Cooldown", + "GuardianAngelBase_ProtectionDuration": "Protection Duration", + "GuardianAngelBase_ImpostorsCanSeeProtect": "Protect Visible To Impostors", + "ScientistBase_BatteryCooldown": "Vitals Display Cooldown", + "ScientistBase_BatteryDuration": "Battery Duration", + "EngineerBase_VentCooldown": "Vent Cooldown", + "EngineerBase_InVentMaxTime": "Max Time In Vents", + "NoisemakerBase_ImpostorAlert": "Impostors Can Get Alert", + "NoisemakerBase_AlertDuration": "Alert Duration", + "TrackerBase_TrackingCooldown": "Tracking Cooldown", + "TrackerBase_TrackingDuration": "Tracking Duration", + "TrackerBase_TrackingDelay": "Tracking Delay", + + "KamikazeControversialSymbol": "Use controversial symbol", + "MareAddSpeedInLightsOut": "Additional Speed During Lights Out", + "MareKillCooldownInLightsOut": "Kill Cooldown During Lights Out", + "MechanicSkillLimit": "Initial repair use limit", + "MechanicFixesDoors": "Can open all doors in the same building", + "MechanicFixesReactors": "Can Fix Both Reactors Alone", + "MechanicFixesOxygens": "Can Fix Both O2 Alone", + "MechanicFixesCommunications": "Can Fix Both Comms Alone In MIRA HQ", + "MechanicFixesElectrical": "Can Fix Lights With One Switch", + + "SheriffShowShotLimit": "Display Shot Limit next to Role Name", + "SheriffCanKill%role%": "Can Kill %role%", + "SheriffCanKillNeutrals": "Can Kill Neutrals", + "SheriffCanKillNeutralsMode": "Neutral Configuration", + "SheriffCanKillAll": "All ON", + "SheriffCanKillSeparately": "Individual Settings", + "In%team%": "(Team %team%)", + "SheriffMisfireKillsTarget": "Misfire Kills Target", "BlackHolePlaceCooldown": "Black Hole Place Cooldown", "BlackHoleDespawnMode": "Black Hole Despawn Mode", "BlackHoleDespawnTime": "Time After Black Hole Despawns", @@ -1557,368 +1570,368 @@ "After1PlayerEaten": "After 1 Player Was Eaten", "AfterMeeting": "After Meeting", "None": "None", - "SheriffShotLimit": "Max number of Kills", - "SheriffCanKillAllAlive": "Can Kill When No One Is Dead", - "SheriffCanKillCharmed": "Can kill Charmed players", - "SheriffCanKillEgoist": "Can Kill Egoists", - "SheriffCanKillSidekick": "Can Kill Sidekicks", - "SheriffCanKillLovers": "Can Kill Lovers", - "SheriffCanKillMadmate": "Can Kill Madmates", - "SheriffCanKillInfected": "Can Kill Infected players", - "SheriffCanKillContagious": "Can Kill Contagious players", - "SheriffSetMadCanKill": "Non-Crew Sheriff Configuration", - "SheriffMadCanKillImp": "Can kill Impostors", - "SheriffMadCanKillNeutral": "Can kill Neutrals", - "SheriffMadCanKillCrew": "Can kill Crewmates", - - "RebirthUses": "Amount of Rebirths", - "RebirthCountVotes": "Only rebirth to players who voted for them", - "RebirthFailed": "Ahh, how unfortunate, you did not find any viable souls to swap bodies with", + "SheriffShotLimit": "Max number of Kills", + "SheriffCanKillAllAlive": "Can Kill When No One Is Dead", + "SheriffCanKillCharmed": "Can kill Charmed players", + "SheriffCanKillEgoist": "Can Kill Egoists", + "SheriffCanKillSidekick": "Can Kill Sidekicks", + "SheriffCanKillLovers": "Can Kill Lovers", + "SheriffCanKillMadmate": "Can Kill Madmates", + "SheriffCanKillInfected": "Can Kill Infected players", + "SheriffCanKillContagious": "Can Kill Contagious players", + "SheriffSetMadCanKill": "Non-Crew Sheriff Configuration", + "SheriffMadCanKillImp": "Can kill Impostors", + "SheriffMadCanKillNeutral": "Can kill Neutrals", + "SheriffMadCanKillCrew": "Can kill Crewmates", + + "RebirthUses": "Amount of Rebirths", + "RebirthCountVotes": "Only rebirth to players who voted for them", + "RebirthFailed": "Ahh, how unfortunate, you did not find any viable souls to swap bodies with", "FireworkerCooldown": "Placement Cooldown", - "ReverieIncreaseKillCooldown": "Increase kill cooldown", - "ReverieMaxKillCooldown": "Max kill cooldown", - "ReverieMisfireSuicide": "Misfire on reaching max kill cooldown", - "ReverieResetCooldownMeeting": "Reset kill cooldown after meeting", - "ConvertedReverieKillAll": "Converted Reverie can kill anyone without repercussions", + "ReverieIncreaseKillCooldown": "Increase kill cooldown", + "ReverieMaxKillCooldown": "Max kill cooldown", + "ReverieMisfireSuicide": "Misfire on reaching max kill cooldown", + "ReverieResetCooldownMeeting": "Reset kill cooldown after meeting", + "ConvertedReverieKillAll": "Converted Reverie can kill anyone without repercussions", - "VigilanteNotify": "You have become the very thing you swore to destroy", + "VigilanteNotify": "You have become the very thing you swore to destroy", "DictatorChangeCommandToExpel": "Dictator use Command to expell instad of vote", "DictatorExpelSelf": "WAIT WAIT WAIT WAT THE HELLLLLL Bro really just want to expel himself", - "DoctorTaskCompletedBatteryCharge": "Battery Duration", - "SnitchEnableTargetArrow": "See Arrow Towards Target", - "SnitchCanGetArrowColor": "See Colored Arrows based on Team Colors", - "SnitchCanFindNeutralKiller": "Can Find Neutral Killers", - "SnitchCanFindNeutralApoc": "Can Find Neutral Apocalypse", - "SnitchCanFindMadmate": "Can Find Madmates", - "SnitchRemainingTaskFound": "Remaining tasks to be known", - "MayorAdditionalVote": "Additional Votes Count", - "MayorHasPortableButton": "Mayor has a Mobile Emergency Button", - "MayorNumOfUseButton": "Max Number of Mobile Emergency Buttons", - "MeetingsNeededForWin": "Meetings needed to win", - "Jester_RevealUponEject": "Reveal Upon Eject", - "CannotVoteWhenDead": "Cannot cast a vote while dead", - "EnableVote": "Enable /vote command", - "ShouldVoteSpam": "Try to hide /vote command", - "VoteDisabled": "/vote command has been disabled by the host.", - "ExecutionerCanTargetImpostor": "Can Target Impostors", - "ExecutionerCanTargetNeutralKiller": "Can Target Neutral Killing", - "ExecutionerCanTargetNeutralApocalypse": "Can Target Neutral Apocalypse", - "ExecutionerChangeRolesAfterTargetKilled": "When Target Dies, Executioner becomes", - "ExecutionerCanTargetNeutralBenign": "Can Target Neutral Benign", - "ExecutionerCanTargetNeutralEvil": "Can Target Neutral Evil", - "ExecutionerCanTargetNeutralChaos": "Can Target Neutral Chaos", - "Executioner_RevealTargetUponEject": "Reveal Target Upon Ejection", - "SidekickSheriffCanGoBerserk": "Recruited Sheriff Can Go Nuts", - "LawyerCanTargetImpostor": "Can Target Impostors", - "LawyerCanTargetNeutralKiller": "Can Target Neutral Killers", - "LawyerCanTargetNeutralApocalypse": "Can Target Neutral Apocalypse", - "LawyerCanTargetCrewmate": "Can Target Crewmates", - "LawyerCanTargetJester": "Can Target Jester", - "LawyerChangeRolesAfterTargetKilled": "When Target Dies, Lawyer becomes", - "LaywerShouldChangeRoleAfterTargetKilled": "Should Lawyer Change Role when Target Dies", - "LawyerTargetDeadInMeeting": "Your target was killed while meeting.\nYour role may change depending on the settings.", - - "MercenaryLimit": "Time Until Suicide", - "ArsonistDouseTime": "Douse Duration", - "CanTerroristSuicideWin": "Can Win By Suicide", - "FireworkerMaxCount": "Fireworker Count", - "FireworkerRadius": "Firework Explosion Radius", - "SniperCanKill": "Sniper can kill with bullets remaining", - "SniperBulletCount": "Ammo", - "SniperPrecisionShooting": "Precise Shooting", - "SniperAimAssist": "Aim Assist", - "SniperAimAssistOneshot": "One shot Assist", - - "PyroDouseCooldown": "Douse cooldown", - "PyroBurnCooldown": "Kill cooldown after killing a doused player", - - "Prohibited_OverrideBlockedVentsAfterMeeting": "Override Blocked Vents After Meeting", - "Prohibited_CountBlockedVentsInSkeld": "Count Blocked Vents In The Skeld", - "Prohibited_CountBlockedVentsInMira": "Count Blocked Vents In MIRA HQ", - "Prohibited_CountBlockedVentsInPolus": "Count Blocked Vents In Polus", - "Prohibited_CountBlockedVentsInDleks": "Count Blocked Vents In Dleks", - "Prohibited_CountBlockedVentsInAirship": "Count Blocked Vents In Airship", - "Prohibited_CountBlockedVentsInFungle": "Count Blocked Vents In The Fungle", - - "UndertakerFreezeDuration": "Freeze Duration", - "NameDisplayAddons": "Display Add-Ons next to the role name", - "YourAddon": "Your Add-ons:", - "NoLimitAddonsNumMax": "Max Add-ons Per Player", - "LoverSpawnChances": "Spawn Chance of Lovers", - "AdditionRolesSpawnRate": "Spawn Chance", - "TorchVision": "Torch Vision", - "TorchAffectedByLights": "Torch's vision is affected by Lights Sabotage", - "BewilderVision": "Bewilder Vision", - "JesterVision": "Jester Vision", - "LawyerVision": "Lawyer Vision", - "FlashSpeed": "Flash Speed", - "SlothSpeed": "Sloth Speed", - "LoverSuicide": "Lovers die together", - "NumberOfLovers": "Number of Lover Pairs (x2 members)", - "LoverKnowRoles": "Lovers know the roles of each other", - "TrapperBlockMoveTime": "Freeze time", - "BecomeTrapperBlockMoveTime": "Freeze time", - "TimeThiefDecreaseMeetingTime": "Lower Meeting Time by", - "TimeThiefLowerLimitVotingTime": "Minimum Voting Time", - "TimeThiefReturnStolenTimeUponDeath": "Return Stolen Time Upon Death", - "EvilTrackerCanSeeKillFlash": "Can See Kill-Flash", - "EvilTrackerCanSeeLastRoomInMeeting": "Can See Target's Last Room In Meeting", - "EvilTrackerTargetMode": "Can Set Target", - "EvilTrackerTargetMode.Never": "Never", - "EvilTrackerTargetMode.OnceInGame": "Once in-game", - "EvilTrackerTargetMode.EveryMeeting": "Every Meeting", - "EvilTrackerTargetMode.Always": "Any time", + "DoctorTaskCompletedBatteryCharge": "Battery Duration", + "SnitchEnableTargetArrow": "See Arrow Towards Target", + "SnitchCanGetArrowColor": "See Colored Arrows based on Team Colors", + "SnitchCanFindNeutralKiller": "Can Find Neutral Killers", + "SnitchCanFindNeutralApoc": "Can Find Neutral Apocalypse", + "SnitchCanFindMadmate": "Can Find Madmates", + "SnitchRemainingTaskFound": "Remaining tasks to be known", + "MayorAdditionalVote": "Additional Votes Count", + "MayorHasPortableButton": "Mayor has a Mobile Emergency Button", + "MayorNumOfUseButton": "Max Number of Mobile Emergency Buttons", + "MeetingsNeededForWin": "Meetings needed to win", + "Jester_RevealUponEject": "Reveal Upon Eject", + "CannotVoteWhenDead": "Cannot cast a vote while dead", + "EnableVote": "Enable /vote command", + "ShouldVoteSpam": "Try to hide /vote command", + "VoteDisabled": "/vote command has been disabled by the host.", + "ExecutionerCanTargetImpostor": "Can Target Impostors", + "ExecutionerCanTargetNeutralKiller": "Can Target Neutral Killing", + "ExecutionerCanTargetNeutralApocalypse": "Can Target Neutral Apocalypse", + "ExecutionerChangeRolesAfterTargetKilled": "When Target Dies, Executioner becomes", + "ExecutionerCanTargetNeutralBenign": "Can Target Neutral Benign", + "ExecutionerCanTargetNeutralEvil": "Can Target Neutral Evil", + "ExecutionerCanTargetNeutralChaos": "Can Target Neutral Chaos", + "Executioner_RevealTargetUponEject": "Reveal Target Upon Ejection", + "SidekickSheriffCanGoBerserk": "Recruited Sheriff Can Go Nuts", + "LawyerCanTargetImpostor": "Can Target Impostors", + "LawyerCanTargetNeutralKiller": "Can Target Neutral Killers", + "LawyerCanTargetNeutralApocalypse": "Can Target Neutral Apocalypse", + "LawyerCanTargetCrewmate": "Can Target Crewmates", + "LawyerCanTargetJester": "Can Target Jester", + "LawyerChangeRolesAfterTargetKilled": "When Target Dies, Lawyer becomes", + "LaywerShouldChangeRoleAfterTargetKilled": "Should Lawyer Change Role when Target Dies", + "LawyerTargetDeadInMeeting": "Your target was killed while meeting.\nYour role may change depending on the settings.", + + "MercenaryLimit": "Time Until Suicide", + "ArsonistDouseTime": "Douse Duration", + "CanTerroristSuicideWin": "Can Win By Suicide", + "FireworkerMaxCount": "Fireworker Count", + "FireworkerRadius": "Firework Explosion Radius", + "SniperCanKill": "Sniper can kill with bullets remaining", + "SniperBulletCount": "Ammo", + "SniperPrecisionShooting": "Precise Shooting", + "SniperAimAssist": "Aim Assist", + "SniperAimAssistOneshot": "One shot Assist", + + "PyroDouseCooldown": "Douse cooldown", + "PyroBurnCooldown": "Kill cooldown after killing a doused player", + + "Prohibited_OverrideBlockedVentsAfterMeeting": "Override Blocked Vents After Meeting", + "Prohibited_CountBlockedVentsInSkeld": "Count Blocked Vents In The Skeld", + "Prohibited_CountBlockedVentsInMira": "Count Blocked Vents In MIRA HQ", + "Prohibited_CountBlockedVentsInPolus": "Count Blocked Vents In Polus", + "Prohibited_CountBlockedVentsInDleks": "Count Blocked Vents In Dleks", + "Prohibited_CountBlockedVentsInAirship": "Count Blocked Vents In Airship", + "Prohibited_CountBlockedVentsInFungle": "Count Blocked Vents In The Fungle", + + "UndertakerFreezeDuration": "Freeze Duration", + "NameDisplayAddons": "Display Add-Ons next to the role name", + "YourAddon": "Your Add-ons:", + "NoLimitAddonsNumMax": "Max Add-ons Per Player", + "LoverSpawnChances": "Spawn Chance of Lovers", + "AdditionRolesSpawnRate": "Spawn Chance", + "TorchVision": "Torch Vision", + "TorchAffectedByLights": "Torch's vision is affected by Lights Sabotage", + "BewilderVision": "Bewilder Vision", + "JesterVision": "Jester Vision", + "LawyerVision": "Lawyer Vision", + "FlashSpeed": "Flash Speed", + "SlothSpeed": "Sloth Speed", + "LoverSuicide": "Lovers die together", + "NumberOfLovers": "Number of Lover Pairs (x2 members)", + "LoverKnowRoles": "Lovers know the roles of each other", + "TrapperBlockMoveTime": "Freeze time", + "BecomeTrapperBlockMoveTime": "Freeze time", + "TimeThiefDecreaseMeetingTime": "Lower Meeting Time by", + "TimeThiefLowerLimitVotingTime": "Minimum Voting Time", + "TimeThiefReturnStolenTimeUponDeath": "Return Stolen Time Upon Death", + "EvilTrackerCanSeeKillFlash": "Can See Kill-Flash", + "EvilTrackerCanSeeLastRoomInMeeting": "Can See Target's Last Room In Meeting", + "EvilTrackerTargetMode": "Can Set Target", + "EvilTrackerTargetMode.Never": "Never", + "EvilTrackerTargetMode.OnceInGame": "Once in-game", + "EvilTrackerTargetMode.EveryMeeting": "Every Meeting", + "EvilTrackerTargetMode.Always": "Any time", "ScavengerHasCustomDeathReason": "Enable Custom Death Reason", - "EvilHackerCanSeeDeadMark": "Can See The Location of Dead-bodies", - "EvilHackerCanSeeImpostorMark": "Can See The Location of Other Impostors", - "EvilHackerCanSeeKillFlash": "Can See Kill-Flash", - "EvilHackerCanSeeMurderRoom": "Can See The Murder Location", - "EvilHackerMurderNotify": "Murder In", - "EvilHackerLastAdminInfoTitle": "Last-minute admin information", - "EvilHackerDeadbody": "DEAD", - - "Ventguard": "Ventguard", - "VentguardInfo": "Block vents by entering them", - "VentguardInfoLong": "(Crewmates):\nAs the Ventguard, you can enter vents to block them. No one can enter blocked vents, except Crewmates, if the setting is on. Blocked vents can be resets every meeting.", - "VentguardVentButtonText": "Block", - "Ventguard_MaxGuards": "Max number of Vent Blocks", - "Ventguard_BlockVentCooldown": "Block Vent Cooldown", - "Ventguard_BlockDoesNotAffectCrew": "Crewmates can use blocked vents", - "Ventguard_BlocksResetOnMeeting": "Reset Blocked Vents Every Meeting", - "VentIsBlocked": "This Vent Is Now Blocked!", - - "TraitorKnowMadmate": "Traitor Knows Madmates", - "Psychic_NBareRed": "Neutral Benign can be red", - "Psychic_NEareRed": "Neutral Evil can be red", - "Psychic_NCareRed": "Neutral Chaos can be red", - "Psychic_NAareRed": "Neutral Apocalypse can be red", - "Psychic_NKareRed": "Neutral Killers can be red", - "Psychic_CrewKillingRed": "Crewmate Killing can be red", - "PsychicCanSeeNum": "Max number of red names", - "PsychicFresh": "New red names every meeting", - "DetectiveCanknowKiller": "Can find the killer's role", - "EveryOneKnowSuperStar": "Everyone knows the Super Star", - "HackLimit": "Ability Use Count", - "ZombieSpeedReduce": "After a certain time, decrease the speed of Zombie by", - "NemesisCanKillNum": "Max number of revenges", - "ImpKnowCelebrityDead": "Impostors know when the Celebrity dies", - "NeutralKnowCelebrityDead": "Neutrals know when the Celebrity dies", - "VectorVentNumWin": "Number of Vents to win", - "CanCheckCamera": "Can track camera usage", - "DefaultKillCooldown": "Starting kill cooldown", - "ReduceKillCooldown": "Reduce kill cooldown by", - "MinKillCooldown": "Minimum kill cooldown", - "BomberRadius": "Bomb radius (5x is about half a Cafeteria)", - "NotifyGodAlive": "Inform players at meetings that God is still alive", - "TransporterTeleportMax": "Max number of teleports", - "TriggerKill": "Kill", - "TriggerVent": "Vent", - "TriggerDouble": "Double Click", - "TimeManagerIncreaseMeetingTime": "Increase voting time by", - "TimeManagerLimitMeetingTime": "Maximum Length of Meetings", - "MadTimeManagerLimitMeetingTime": "Mad Time Manager - Minimum Voting Time", - "AssignOnlyToCrewmate": "Assign only to Crewmates", - "WorkhorseNumLongTasks": "Additional Long Tasks", - "WorkhorseNumShortTasks": "Additional Short Tasks", - "SnitchCanBeWorkhorse": "Snitch can become Workhorse", - "InnocentCanWinByImp": "If their target was an Impostor then they win with them", - "ImpCanBeParanoia": "Impostors can become Paranoia", - "CrewCanBeParanoia": "Crewmates can become Paranoia", - "DualVotes": "Duplicate votes", - "VeteranSkillCooldown": "Alert Cooldown", - "VeteranSkillDuration": "Alert Duration", - "BodyguardProtectRadius": "Protect Radius", - "ImpCanBeEgoist": "An Impostor can become Egoist", - "CrewCanBeEgoist": "Crewmates can become Egoist", - "ImpEgoistVisibalToAllies": "Impostors Can See Other Egoist Impostors", - "EgoistCountAsConverted": "Egoist count as converted neutral", - "GuessRainbow": "He seems too obvious, doesn't he?", - "RainbowColorChangeCoolDown": "The cooldown for changing colors", - "RainbowInCamouflage": "Rainbow color changes during Camouflage", - "BaitDelayMin": "Minimum Report Delay", - "BaitDelayMax": "Maximum Report Delay", - "BaitDelayNotify": "Warn the killer about the upcoming self-report", - "BecomeBaitDelayNotify": "Warn the killer about the upcoming self-report", - "BaitNotification": "Reveal Bait at the first meeting", - "BaitAdviceAlive": "{0} is the Bait. Whoever kills the Bait will commit self-report.", - "BaitCanBeReportedUnderAllConditions": "Bait Can Be Reported even if a meeting is disabled during comms sabotage", - "DeceiverAbilityLost": "Deceiver loses ability if it deceives player without kill button", - "AddictSuicideTimer": "Time Until Suicide", - "GrenadierSkillCooldown": "Grenade Cooldown", - "GrenadierSkillDuration": "Grenade Duration", - "GrenadierCauseVision": "Lowered vision", - "GrenadierCanAffectNeutral": "Can affect Neutrals", - "TicketsPerKill": "Votes Increase Amount Per Kill", - "GangsterRecruitCooldown": "Recruit cooldown", - "GangsterRecruitLimit": "Recruit limit", - "KamikazeMaxMarked": "Max Marked", - "RevolutionistDrawTime": "Tag Duration", - "RevolutionistCooldown": "Tag Cooldown", - "RevolutionistDrawCount": "Amount of Players needed to Tag", - "RevolutionistKillProbability": "Tagged player sacrifice probability", - "RevolutionistVentCountDown": "Time to Vent", - "PelicanKillCooldown": "Eat Cooldown", - "Pelican.TargetCannotBeEaten": "Target cannot be eaten", - "MadSnitchTasks": "Snitch Tasks", - "MedicWhoCanSeeProtect": "Who can see shield", - "MedicKnowShieldBroken": "Who sees kill attempt", - "Medic_SeeMedicAndTarget": "Medic+Shielded", - "Medic_SeeMedic": "Medic", - "Medic_SeeTarget": "Shielded", - "Medic_SeeNoOne": "Nothing", - "MedicShieldDeactivatesWhenMedicDies": "Shield deactivates when the Medic dies", - "MedicShielDeactivationIsVisible": "Shield deactivation is visible", - "MedicShieldDeactivationIsVisible_Immediately": "Immediately", - "MedicShieldDeactivationIsVisible_AfterMeeting": "After Meeting", - "MedicShieldDeactivationIsVisible_OFF": "OFF", - "MedicResetCooldown": "On kill attempt, reset murderer's cooldown to", - "MedicShieldedCanBeGuessed": "Guessing ignores Medic shield", - "MadmateSpawnMode": "Madmate spawning mode", - "MadmateSpawnMode.Assign": "Assign", - "MadmateSpawnMode.FirstKill": "First Kill", - "MadmateSpawnMode.SelfVote": "Self Vote", - "MadmateCountMode": "Madmates count as", - "MadmateCountMode.None": "Nothing", - "MadmateCountMode.Imp": "Impostors", - "MadmateCountMode.Original": "Original Team", - - "Altruist_RevivedDeadBodyCannotBeReported_Option": "Revived Dead Body Cannot Be Reported", - "Altruist_ImpostorsCanGetsAlert": "Impostors Can Get Alert", - "Altruist_ImpostorsCanGetsArrow": "Impostors Can Get Arrow", - "Altruist_NeutralKillersCanGetsAlert": "Neutral Killers Can Get Alert", - "Altruist_NeutralKillersCanGetsArrow": "Neutral Killers Can Get Arrow", - "AltruistSuffix": "<#00ffa5>Mode: {0}", - "AltruistReviveMode": "Revive", - "AltruistReportMode": "Report", - "Altruist_YouTriedReportRevivedDeadBody": "You Tried Report Revived Dead Body", - "Altruist_DeadPlayerHasBeenRevived": "A Dead Player Has Been Revived!", - "AltruistAbilityButton": "Change Mode", - - "SnatchesWin": "Snatches victory", - "DemonKillCooldown": "Attack Cooldown", - "DemonHealthMax": "Player max health", - "DemonDamage": "Damage ", - "DemonSelfHealthMax": "Demon max health", - "DemonSelfDamage": "Demon damage received", - "LightningConvertTime": "Duration of the transformation to Quantum Ghost", - "LightningKillCooldown": "Lightning Cooldown", - "LightningKillerConvertGhost": "Killer can transform into Quantum Ghost", - "CanCountNeutralKiller": "When Crewmates win by killing a Neutral player, they can snatch the victory", - "GreedyOddKillCooldown": "Odd-Numbered kill cooldown", - "GreedyEvenKillCooldown": "Even-Numbered kill cooldown", - "WorkaholicCannotWinAtDeath": "Can't win after they died", - "WorkaholicVisibleToEveryone": "Everyone knows who the Workaholic is", - "WorkaholicGiveAdviceAlive": "Advice at the first meeting if alive, can win after death, ghost tasks ON", - "DoctorVisibleToEveryone": "Everyone knows who the Doctor is", - "CursedWolfGuardSpellTimes": "Amount of Cursed Shields", - "KillAttackerWhenAbilityRemaining": "Kill attacker when ability is remaining", - "JinxSpellTimes": "Amount of Jinx Spells", - "CollectorCollectAmount": "Required number of votes", - "GlitchCanVote": "Can vote", - "QuickShooterShapeshiftCooldown": "Shapeshift Cooldown", - "MeetingReserved": "Max Bullets reserved for a meeting", - "AccurateCheckMode": "Can know specific role when tasks are not done", - "RandomActiveRoles": "Show random active roles in Fortune Teller hints", - "CamouflageCooldown": "Camouflage Cooldown", - "CamouflageDuration": "Camouflage Duration", - "NinjaMarkCooldown": "Mark Cooldown", - "NinjaAssassinateCooldown": "Assassinate Cooldown", - "NinjaModeDouble": "Double Click = Kill, Single Click = Mark", - "JudgeCanTrialnCrewKilling": "Can trial Crewmate Killing", - "JudgeCanTrialNeutralB": "Can trial Neutral Benign", - "JudgeCanTrialNeutralK": "Can trial Neutral Killing", - "JudgeCanTrialNeutralE": "Can trial Neutral Evil", - "JudgeCanTrialNeutralC": "Can trial Neutral Chaos", - "JudgeCanTrialNeutralA": "Can trial Neutral Apocalypse", - "JudgeCanTrialSidekick": "Can trial Sidekick", - "JudgeCanTrialInfected": "Can trial Infected", - "JudgeCanTrialContagious": "Can trial Contagious", - "JudgeTryHideMsg": "Hide Judge's commands", - "JudgeTrialLimitPerMeeting": "Max Trials per Meeting", - "JudgeTrialLimitPerGame": "Max Trials per Game", - "JudgeCanTrialMadmate": "Can trial Madmates", - "JudgeCanTrialCharmed": "Can trial Charmed players", - "JudgeDead": "Sorry, you can't trial players after death.", - "JudgeTrialMaxMeetingMsg": "\nNo more meeting trials left!", - "JudgeTrialMaxGameMsg": "\nNo more trials left!", - "Judge_LaughToWhoTrialSelf": "God, I didn't think the Judges would be so blind that they wouldn't even see that they had sentenced themselves.", - "Judge_TrialKill": "{0} was judged.", - "Judge_TrialKillTitle": "COURT", - "Judge_TrialHelp": "Command: /tl [player ID]\nYou can see the players' IDs before the players' names.\nOr use /id to view the list of all player IDs.", - "Judge_TrialNull": "Please choose a living player for the trial", - "VeteranSkillMaxOfUseage": "Max number of Alerts", - "SwooperCooldown": "Swoop Cooldown", - "SwooperDuration": "Swoop Duration", - "WraithCooldown": "Vanish Cooldown", - "WraithDuration": "Vanish Duration", - "BastionNotify": "A bomb was set off", - "EnteredBombedVent": "That vent was bombed!", - "BastionVentButtonText": "Bomb", - "BombsClearAfterMeeting": "Bombs clear after meetings", - "BastionMaxBombs": "(Initial) Maximum bombs", - "VentBombSuccess": "Bomb has been planted", - "LowLoadMode": "Low Load Mode", - "ShowLobbyCode": "Show lobby code in Discord status", - "BKProtectDuration": "Protection Duration", - "FollowerMaxBetTimes": "Maximum Number of Follows", - "FollowerBetCooldown": "Follow Cooldown", - "FollowerMaxBetCooldown": "Maximum Follow Cooldown", - "FollowerBetCooldownIncrese": "Increase Cooldown per 1 follow by", - "FollowerKnowTargetRole": "Follower knows their target's role", - "FollowerBetTargetKnowFollower": "Follower target knows who the Follower is", - "FortuneTellerHideVote": "Hide Fortune Teller's Votes", - "CultistCharmCooldown": "Charm Cooldown", - "CultistCharmCooldownIncrese": "Increases Charm Cooldown For Each Charm", - "CultistCharmMax": "Maximum Number Of Charm", - "CultistKnowTargetRole": "Know Charmed Player's Role", - "CultistTargetKnowOtherTarget": "Charmed players know each other", - "CultistCanCharmNeutral": "Neutral Roles can be Charmed", - "InfectiousBiteCooldown": "Infect Cooldown", - "KnowTargetRole": "Knows role of target", - "TargetKnowsLawyer": "Target knows their Lawyer", - "InfectiousBiteMax": "Maximum Infections", - "InfectiousKnowTargetRole": "Know infected player's role", - "InfectiousTargetKnowOtherTarget": "Infected players know each other", - "DoubleClickKill": "Double click to kill the target", - - "VirusInfectMax": "Maximum Number Of Spreads", - "VirusKnowTargetRole": "Know Contagious Player's Role", - "VirusTargetKnowOtherTarget": "Contagious players know each other", - "VirusKillInfectedPlayerAfterMeeting": "Contagious player dies after meeting", - "Virus_ContagiousCountMode": "Contagious players count as", - "Virus_ContagiousCountMode_None": "Nothing", - "Virus_ContagiousCountMode_Virus": "Virus", - "Virus_ContagiousCountMode_Original": "Original Team", - "VirusNoticeTitle": "[ Infected Corpse! ]", - "VirusNoticeMessage": "The body you reported was infected by the Virus! You are now part of Team Virus. Help the Virus win the game.", - "VirusNoticeMessage2": "The body you reported was infected by the Virus! Vote the Virus out during this meeting, or you will die.", - - "Cultist_CharmedCountMode": "Charmed players count as", - "Cultist_CharmedCountMode_None": "Nothing", - "Cultist_CharmedCountMode_Cultist": "Cultist", - "Cultist_CharmedCountMode_Original": "Original Team", - - "JackalCanWinBySabotageWhenNoImpAlive": "When all Impostors are dead, the Jackal wins by sabotage instead", - "JackalResetKillCooldownWhenPlayerGetKilled": "Reset kill cooldown if someone gets killed by another player", - "JackalResetKillCooldownOn": "Kill Cooldown On Reset", - "JackalCanRecruitSidekick": "Can recruit Sidekick", - "JackalSidekickRecruitLimit": "Maximum Number Of Recruits", - "Jackal_SidekickCountMode": "Sidekicks count as", - "Jackal_SidekickCountMode_None": "Nothing", - "Jackal_SidekickCountMode_Jackal": "Jackal", - "Jackal_SidekickCountMode_Original": "Original Team", - "Jackal_SidekickAssignMode": "Sidekick Assign Mode", + "EvilHackerCanSeeDeadMark": "Can See The Location of Dead-bodies", + "EvilHackerCanSeeImpostorMark": "Can See The Location of Other Impostors", + "EvilHackerCanSeeKillFlash": "Can See Kill-Flash", + "EvilHackerCanSeeMurderRoom": "Can See The Murder Location", + "EvilHackerMurderNotify": "Murder In", + "EvilHackerLastAdminInfoTitle": "Last-minute admin information", + "EvilHackerDeadbody": "DEAD", + + "Ventguard": "Ventguard", + "VentguardInfo": "Block vents by entering them", + "VentguardInfoLong": "(Crewmates):\nAs the Ventguard, you can enter vents to block them. No one can enter blocked vents, except Crewmates, if the setting is on. Blocked vents can be resets every meeting.", + "VentguardVentButtonText": "Block", + "Ventguard_MaxGuards": "Max number of Vent Blocks", + "Ventguard_BlockVentCooldown": "Block Vent Cooldown", + "Ventguard_BlockDoesNotAffectCrew": "Crewmates can use blocked vents", + "Ventguard_BlocksResetOnMeeting": "Reset Blocked Vents Every Meeting", + "VentIsBlocked": "This Vent Is Now Blocked!", + + "TraitorKnowMadmate": "Traitor Knows Madmates", + "Psychic_NBareRed": "Neutral Benign can be red", + "Psychic_NEareRed": "Neutral Evil can be red", + "Psychic_NCareRed": "Neutral Chaos can be red", + "Psychic_NAareRed": "Neutral Apocalypse can be red", + "Psychic_NKareRed": "Neutral Killers can be red", + "Psychic_CrewKillingRed": "Crewmate Killing can be red", + "PsychicCanSeeNum": "Max number of red names", + "PsychicFresh": "New red names every meeting", + "DetectiveCanknowKiller": "Can find the killer's role", + "EveryOneKnowSuperStar": "Everyone knows the Super Star", + "HackLimit": "Ability Use Count", + "ZombieSpeedReduce": "After a certain time, decrease the speed of Zombie by", + "NemesisCanKillNum": "Max number of revenges", + "ImpKnowCelebrityDead": "Impostors know when the Celebrity dies", + "NeutralKnowCelebrityDead": "Neutrals know when the Celebrity dies", + "VectorVentNumWin": "Number of Vents to win", + "CanCheckCamera": "Can track camera usage", + "DefaultKillCooldown": "Starting kill cooldown", + "ReduceKillCooldown": "Reduce kill cooldown by", + "MinKillCooldown": "Minimum kill cooldown", + "BomberRadius": "Bomb radius (5x is about half a Cafeteria)", + "NotifyGodAlive": "Inform players at meetings that God is still alive", + "TransporterTeleportMax": "Max number of teleports", + "TriggerKill": "Kill", + "TriggerVent": "Vent", + "TriggerDouble": "Double Click", + "TimeManagerIncreaseMeetingTime": "Increase voting time by", + "TimeManagerLimitMeetingTime": "Maximum Length of Meetings", + "MadTimeManagerLimitMeetingTime": "Mad Time Manager - Minimum Voting Time", + "AssignOnlyToCrewmate": "Assign only to Crewmates", + "WorkhorseNumLongTasks": "Additional Long Tasks", + "WorkhorseNumShortTasks": "Additional Short Tasks", + "SnitchCanBeWorkhorse": "Snitch can become Workhorse", + "InnocentCanWinByImp": "If their target was an Impostor then they win with them", + "ImpCanBeParanoia": "Impostors can become Paranoia", + "CrewCanBeParanoia": "Crewmates can become Paranoia", + "DualVotes": "Duplicate votes", + "VeteranSkillCooldown": "Alert Cooldown", + "VeteranSkillDuration": "Alert Duration", + "BodyguardProtectRadius": "Protect Radius", + "ImpCanBeEgoist": "An Impostor can become Egoist", + "CrewCanBeEgoist": "Crewmates can become Egoist", + "ImpEgoistVisibalToAllies": "Impostors Can See Other Egoist Impostors", + "EgoistCountAsConverted": "Egoist count as converted neutral", + "GuessRainbow": "He seems too obvious, doesn't he?", + "RainbowColorChangeCoolDown": "The cooldown for changing colors", + "RainbowInCamouflage": "Rainbow color changes during Camouflage", + "BaitDelayMin": "Minimum Report Delay", + "BaitDelayMax": "Maximum Report Delay", + "BaitDelayNotify": "Warn the killer about the upcoming self-report", + "BecomeBaitDelayNotify": "Warn the killer about the upcoming self-report", + "BaitNotification": "Reveal Bait at the first meeting", + "BaitAdviceAlive": "{0} is the Bait. Whoever kills the Bait will commit self-report.", + "BaitCanBeReportedUnderAllConditions": "Bait Can Be Reported even if a meeting is disabled during comms sabotage", + "DeceiverAbilityLost": "Deceiver loses ability if it deceives player without kill button", + "AddictSuicideTimer": "Time Until Suicide", + "GrenadierSkillCooldown": "Grenade Cooldown", + "GrenadierSkillDuration": "Grenade Duration", + "GrenadierCauseVision": "Lowered vision", + "GrenadierCanAffectNeutral": "Can affect Neutrals", + "TicketsPerKill": "Votes Increase Amount Per Kill", + "GangsterRecruitCooldown": "Recruit cooldown", + "GangsterRecruitLimit": "Recruit limit", + "KamikazeMaxMarked": "Max Marked", + "RevolutionistDrawTime": "Tag Duration", + "RevolutionistCooldown": "Tag Cooldown", + "RevolutionistDrawCount": "Amount of Players needed to Tag", + "RevolutionistKillProbability": "Tagged player sacrifice probability", + "RevolutionistVentCountDown": "Time to Vent", + "PelicanKillCooldown": "Eat Cooldown", + "Pelican.TargetCannotBeEaten": "Target cannot be eaten", + "MadSnitchTasks": "Snitch Tasks", + "MedicWhoCanSeeProtect": "Who can see shield", + "MedicKnowShieldBroken": "Who sees kill attempt", + "Medic_SeeMedicAndTarget": "Medic+Shielded", + "Medic_SeeMedic": "Medic", + "Medic_SeeTarget": "Shielded", + "Medic_SeeNoOne": "Nothing", + "MedicShieldDeactivatesWhenMedicDies": "Shield deactivates when the Medic dies", + "MedicShielDeactivationIsVisible": "Shield deactivation is visible", + "MedicShieldDeactivationIsVisible_Immediately": "Immediately", + "MedicShieldDeactivationIsVisible_AfterMeeting": "After Meeting", + "MedicShieldDeactivationIsVisible_OFF": "OFF", + "MedicResetCooldown": "On kill attempt, reset murderer's cooldown to", + "MedicShieldedCanBeGuessed": "Guessing ignores Medic shield", + "MadmateSpawnMode": "Madmate spawning mode", + "MadmateSpawnMode.Assign": "Assign", + "MadmateSpawnMode.FirstKill": "First Kill", + "MadmateSpawnMode.SelfVote": "Self Vote", + "MadmateCountMode": "Madmates count as", + "MadmateCountMode.None": "Nothing", + "MadmateCountMode.Imp": "Impostors", + "MadmateCountMode.Original": "Original Team", + + "Altruist_RevivedDeadBodyCannotBeReported_Option": "Revived Dead Body Cannot Be Reported", + "Altruist_ImpostorsCanGetsAlert": "Impostors Can Get Alert", + "Altruist_ImpostorsCanGetsArrow": "Impostors Can Get Arrow", + "Altruist_NeutralKillersCanGetsAlert": "Neutral Killers Can Get Alert", + "Altruist_NeutralKillersCanGetsArrow": "Neutral Killers Can Get Arrow", + "AltruistSuffix": "<#00ffa5>Mode: {0}", + "AltruistReviveMode": "Revive", + "AltruistReportMode": "Report", + "Altruist_YouTriedReportRevivedDeadBody": "You Tried Report Revived Dead Body", + "Altruist_DeadPlayerHasBeenRevived": "A Dead Player Has Been Revived!", + "AltruistAbilityButton": "Change Mode", + + "SnatchesWin": "Snatches victory", + "DemonKillCooldown": "Attack Cooldown", + "DemonHealthMax": "Player max health", + "DemonDamage": "Damage ", + "DemonSelfHealthMax": "Demon max health", + "DemonSelfDamage": "Demon damage received", + "LightningConvertTime": "Duration of the transformation to Quantum Ghost", + "LightningKillCooldown": "Lightning Cooldown", + "LightningKillerConvertGhost": "Killer can transform into Quantum Ghost", + "CanCountNeutralKiller": "When Crewmates win by killing a Neutral player, they can snatch the victory", + "GreedyOddKillCooldown": "Odd-Numbered kill cooldown", + "GreedyEvenKillCooldown": "Even-Numbered kill cooldown", + "WorkaholicCannotWinAtDeath": "Can't win after they died", + "WorkaholicVisibleToEveryone": "Everyone knows who the Workaholic is", + "WorkaholicGiveAdviceAlive": "Advice at the first meeting if alive, can win after death, ghost tasks ON", + "DoctorVisibleToEveryone": "Everyone knows who the Doctor is", + "CursedWolfGuardSpellTimes": "Amount of Cursed Shields", + "KillAttackerWhenAbilityRemaining": "Kill attacker when ability is remaining", + "JinxSpellTimes": "Amount of Jinx Spells", + "CollectorCollectAmount": "Required number of votes", + "GlitchCanVote": "Can vote", + "QuickShooterShapeshiftCooldown": "Shapeshift Cooldown", + "MeetingReserved": "Max Bullets reserved for a meeting", + "AccurateCheckMode": "Can know specific role when tasks are not done", + "RandomActiveRoles": "Show random active roles in Fortune Teller hints", + "CamouflageCooldown": "Camouflage Cooldown", + "CamouflageDuration": "Camouflage Duration", + "NinjaMarkCooldown": "Mark Cooldown", + "NinjaAssassinateCooldown": "Assassinate Cooldown", + "NinjaModeDouble": "Double Click = Kill, Single Click = Mark", + "JudgeCanTrialnCrewKilling": "Can trial Crewmate Killing", + "JudgeCanTrialNeutralB": "Can trial Neutral Benign", + "JudgeCanTrialNeutralK": "Can trial Neutral Killing", + "JudgeCanTrialNeutralE": "Can trial Neutral Evil", + "JudgeCanTrialNeutralC": "Can trial Neutral Chaos", + "JudgeCanTrialNeutralA": "Can trial Neutral Apocalypse", + "JudgeCanTrialSidekick": "Can trial Sidekick", + "JudgeCanTrialInfected": "Can trial Infected", + "JudgeCanTrialContagious": "Can trial Contagious", + "JudgeTryHideMsg": "Hide Judge's commands", + "JudgeTrialLimitPerMeeting": "Max Trials per Meeting", + "JudgeTrialLimitPerGame": "Max Trials per Game", + "JudgeCanTrialMadmate": "Can trial Madmates", + "JudgeCanTrialCharmed": "Can trial Charmed players", + "JudgeDead": "Sorry, you can't trial players after death.", + "JudgeTrialMaxMeetingMsg": "\nNo more meeting trials left!", + "JudgeTrialMaxGameMsg": "\nNo more trials left!", + "Judge_LaughToWhoTrialSelf": "God, I didn't think the Judges would be so blind that they wouldn't even see that they had sentenced themselves.", + "Judge_TrialKill": "{0} was judged.", + "Judge_TrialKillTitle": "COURT", + "Judge_TrialHelp": "Command: /tl [player ID]\nYou can see the players' IDs before the players' names.\nOr use /id to view the list of all player IDs.", + "Judge_TrialNull": "Please choose a living player for the trial", + "VeteranSkillMaxOfUseage": "Max number of Alerts", + "SwooperCooldown": "Swoop Cooldown", + "SwooperDuration": "Swoop Duration", + "WraithCooldown": "Vanish Cooldown", + "WraithDuration": "Vanish Duration", + "BastionNotify": "A bomb was set off", + "EnteredBombedVent": "That vent was bombed!", + "BastionVentButtonText": "Bomb", + "BombsClearAfterMeeting": "Bombs clear after meetings", + "BastionMaxBombs": "(Initial) Maximum bombs", + "VentBombSuccess": "Bomb has been planted", + "LowLoadMode": "Low Load Mode", + "ShowLobbyCode": "Show lobby code in Discord status", + "BKProtectDuration": "Protection Duration", + "FollowerMaxBetTimes": "Maximum Number of Follows", + "FollowerBetCooldown": "Follow Cooldown", + "FollowerMaxBetCooldown": "Maximum Follow Cooldown", + "FollowerBetCooldownIncrese": "Increase Cooldown per 1 follow by", + "FollowerKnowTargetRole": "Follower knows their target's role", + "FollowerBetTargetKnowFollower": "Follower target knows who the Follower is", + "FortuneTellerHideVote": "Hide Fortune Teller's Votes", + "CultistCharmCooldown": "Charm Cooldown", + "CultistCharmCooldownIncrese": "Increases Charm Cooldown For Each Charm", + "CultistCharmMax": "Maximum Number Of Charm", + "CultistKnowTargetRole": "Know Charmed Player's Role", + "CultistTargetKnowOtherTarget": "Charmed players know each other", + "CultistCanCharmNeutral": "Neutral Roles can be Charmed", + "InfectiousBiteCooldown": "Infect Cooldown", + "KnowTargetRole": "Knows role of target", + "TargetKnowsLawyer": "Target knows their Lawyer", + "InfectiousBiteMax": "Maximum Infections", + "InfectiousKnowTargetRole": "Know infected player's role", + "InfectiousTargetKnowOtherTarget": "Infected players know each other", + "DoubleClickKill": "Double click to kill the target", + + "VirusInfectMax": "Maximum Number Of Spreads", + "VirusKnowTargetRole": "Know Contagious Player's Role", + "VirusTargetKnowOtherTarget": "Contagious players know each other", + "VirusKillInfectedPlayerAfterMeeting": "Contagious player dies after meeting", + "Virus_ContagiousCountMode": "Contagious players count as", + "Virus_ContagiousCountMode_None": "Nothing", + "Virus_ContagiousCountMode_Virus": "Virus", + "Virus_ContagiousCountMode_Original": "Original Team", + "VirusNoticeTitle": "[ Infected Corpse! ]", + "VirusNoticeMessage": "The body you reported was infected by the Virus! You are now part of Team Virus. Help the Virus win the game.", + "VirusNoticeMessage2": "The body you reported was infected by the Virus! Vote the Virus out during this meeting, or you will die.", + + "Cultist_CharmedCountMode": "Charmed players count as", + "Cultist_CharmedCountMode_None": "Nothing", + "Cultist_CharmedCountMode_Cultist": "Cultist", + "Cultist_CharmedCountMode_Original": "Original Team", + + "JackalCanWinBySabotageWhenNoImpAlive": "When all Impostors are dead, the Jackal wins by sabotage instead", + "JackalResetKillCooldownWhenPlayerGetKilled": "Reset kill cooldown if someone gets killed by another player", + "JackalResetKillCooldownOn": "Kill Cooldown On Reset", + "JackalCanRecruitSidekick": "Can recruit Sidekick", + "JackalSidekickRecruitLimit": "Maximum Number Of Recruits", + "Jackal_SidekickCountMode": "Sidekicks count as", + "Jackal_SidekickCountMode_None": "Nothing", + "Jackal_SidekickCountMode_Jackal": "Jackal", + "Jackal_SidekickCountMode_Original": "Original Team", + "Jackal_SidekickAssignMode": "Sidekick Assign Mode", "Jackal_SidekickAssignMode_SidekickAndRecruit": "Sidekick when failed Recruit", "Jackal_SidekickAssignMode_Sidekick": "Only Sidekick", "Jackal_SidekickAssignMode_Recruit": "Only Recruit", - "Jackal_SidekickCanKillSidekick": "Sidekicks can kill other Sidekicks", - "Jackal_SidekickCanKillJackal": "Sidekick can kill Jackal", + "Jackal_SidekickCanKillSidekick": "Sidekicks can kill other Sidekicks", + "Jackal_SidekickCanKillJackal": "Sidekick can kill Jackal", "Jackal_RecruitFailed": "You can not recruit this player!", - "JackalCanKillSidekick": "Jackal can kill Sidekick", + "JackalCanKillSidekick": "Jackal can kill Sidekick", "Jackal_SidekickCanKillWhenJackalAlive": "Sidekick can kill while Jackal is Alive", "Jackal_SidekickTurnIntoJackal": "Sidekick can turn into Jackal after its death", "Jackal_RestoreLimitOnNewJackal": "Restore Recruit limit when Sidekick become new Jackal", @@ -1928,1949 +1941,1967 @@ "Jackal_OnNewJackalSelected": "Old Jackal Dead, Please help new Jackal {0} for now!", "Jackal_BossIsDead": "Opps, the Jackal boss is dead!", - "CoronerArrowsPointingToDeadBody": "Arrows pointing to dead bodies", - "CoronerLeaveDeadBodyUnreportable": "Bodies the Coroner uses can't be reported", - "CoronerInformKillerBeingTracked": "Inform the Killer that he gets tracked", - - "PresidentCanBeGuessedAfterRevealing": "President can be guessed after revealing", - "HidePresidentEndCommand": "Hide President's commands", - "NeutralsSeePresident": "Neutrals can see revealed President", - "MadmatesSeePresident": "Madmates can see revealed President", - "ImpsSeePresident": "Impostors can see revealed President", - "PresidentDead": "Sorry, you can't force end the meeting after death.", - "PresidentEndMax": "No more force end meeting uses left!", - "PresidentRevealMax": "You have already revealed yourself...", - "PresidentRevealed": "[{0}] has chosen to reveal themselves as President!", - "GuessPresident": "President has revealed themselves. You can't guess them.", - "PresidentRevealTitle": "PRESIDENT REVEAL", - - "Troller_TrollsPerRound": "Trolls Per Round", - "Troller_CanHaveStartMeetingEvent": "Can Start Meeting By Event", - "Troller_ChangesSpeed": "Troller changed everyone speed!", - "Troller_SpeedOut": "Speed returned back", - "Troller_YouChangedCooldown": "You changed the cooldown of all players", - "Troller_ChangeYourCooldown": "Troller change your cooldown!", - "Troller_NoAddons": "No addons found on the random target", - "Troller_RemoveRandomAddon": "You removed add-on from random player", - "Troller_RemoveYourAddon": "Troller removed your random add-on", - "Troller_YouCausedSabotage": "You caused sabotage", - "Troller_YouFixedSabotage": "You fixed sabotage", - - "LuckyProbability": "Probability of surviving a kill", - "ImpCanBeDoubleShot": "Impostors can have Double Shot", - "CrewCanBeDoubleShot": "Crewmates can have Double Shot", - "NeutralCanBeDoubleShot": "Neutrals can have Double Shot", - "MimicCanSeeDeadRoles": "Mimic can see the roles of dead players", - "DisableReportWhenCamouflageIsActive": "Disable body reporting when camouflage is active", - "CanUseCommsSabotage": "Can use comms sabotage", - "ModTag": "Moderator♥", - "ApplyModeratorList": "Apply Moderator List", - "VipTag": "VIP★", - "ApplyVipList": "Apply VIP List", - "AllowSayCommand": "Allow moderators to use /say command", + "CoronerArrowsPointingToDeadBody": "Arrows pointing to dead bodies", + "CoronerLeaveDeadBodyUnreportable": "Bodies the Coroner uses can't be reported", + "CoronerInformKillerBeingTracked": "Inform the Killer that he gets tracked", + + "PresidentCanBeGuessedAfterRevealing": "President can be guessed after revealing", + "HidePresidentEndCommand": "Hide President's commands", + "NeutralsSeePresident": "Neutrals can see revealed President", + "MadmatesSeePresident": "Madmates can see revealed President", + "ImpsSeePresident": "Impostors can see revealed President", + "PresidentDead": "Sorry, you can't force end the meeting after death.", + "PresidentEndMax": "No more force end meeting uses left!", + "PresidentRevealMax": "You have already revealed yourself...", + "PresidentRevealed": "[{0}] has chosen to reveal themselves as President!", + "GuessPresident": "President has revealed themselves. You can't guess them.", + "PresidentRevealTitle": "PRESIDENT REVEAL", + + "Troller_TrollsPerRound": "Trolls Per Round", + "Troller_CanHaveStartMeetingEvent": "Can Start Meeting By Event", + "Troller_ChangesSpeed": "Troller changed everyone speed!", + "Troller_SpeedOut": "Speed returned back", + "Troller_YouChangedCooldown": "You changed the cooldown of all players", + "Troller_ChangeYourCooldown": "Troller change your cooldown!", + "Troller_NoAddons": "No addons found on the random target", + "Troller_RemoveRandomAddon": "You removed add-on from random player", + "Troller_RemoveYourAddon": "Troller removed your random add-on", + "Troller_YouCausedSabotage": "You caused sabotage", + "Troller_YouFixedSabotage": "You fixed sabotage", + + "LuckyProbability": "Probability of surviving a kill", + "ImpCanBeDoubleShot": "Impostors can have Double Shot", + "CrewCanBeDoubleShot": "Crewmates can have Double Shot", + "NeutralCanBeDoubleShot": "Neutrals can have Double Shot", + "MimicCanSeeDeadRoles": "Mimic can see the roles of dead players", + "DisableReportWhenCamouflageIsActive": "Disable body reporting when camouflage is active", + "CanUseCommsSabotage": "Can use comms sabotage", + "ModTag": "Moderator♥", + "ApplyModeratorList": "Apply Moderator List", + "VipTag": "VIP★", + "ApplyVipList": "Apply VIP List", + "AllowSayCommand": "Allow moderators to use /say command", "AllowStartCommand": "Allow moderators to use /start command", "StartCommandMinCountdown": "Minimum countdown for /start command", "StartCommandMaxCountdown": "Maximum countdown for /start command", - "KickCommandDisabled": "The kick command is currently disabled.", - "KickCommandNoAccess": "You do not have access to the kick command.", - "KickCommandInvalidID": "Invalid player ID specified.\nPlease use '/kick [playerID] [reason]' to kick a player.\nExample :- /kick 5 not following rules", - "KickCommandKickHost": "You are not permitted to kick the host.", - "KickCommandKickMod": "You are not permitted to kick other moderators.", - "KickCommandKicked": "was kicked from the game by ", - "KickCommandKickedRole": "Their role was", - "BanCommandDisabled": "The ban command is currently disabled.", - "BanCommandNoAccess": "You do not have access to the ban command.", - "BanCommandInvalidID": "Invalid player ID specified.\nPlease use '/ban [playerID] [reason]' to ban a player.\nExample :- /ban 5 not following rules ", - "BanCommandBanHost": "You are not permitted to ban the host.", - "BanCommandBanMod": "You are not permitted to ban other moderators.", - "BanCommandBanned": "was banned from the game by ", - "BanCommandBannedRole": "Their role was", - "BanCommandNoReason": "No reason specified.\nPlease use '/ban [playerID] [reason]\nExample :- /ban 5 not following rules", - "ColorCommandDisabled": "The modcolor command is currently disabled.", - "ColorCommandNoAccess": "You do not have access to the modcolor command.", - "ColorCommandNoLobby": "You can only use the command in Lobby when the game hasn't started.", - "ColorInvalidHexCode": "Invalid hexcode specified.\nPlease use '/modcolor [hexcode]' to change the color of MODERATOR♥.\nExample :- /modcolor 33ccff", - "ColorInvalidGradientCode": "Invalid hexcode specified.\nPlease use '/modcolor [hexcode][hexcode]' to change color of MODERATOR♥.\nExample :- /modcolor 33ccff ff99cc", - "VipColorCommandDisabled": "The vipcolor command is currently disabled.", - "VipColorCommandNoAccess": "You do not have access to the vipcolor command.", - "VipColorCommandNoLobby": "You can only use the command in Lobby when the game hasn't started.", - "VipColorInvalidHexCode": "Invalid hexcode specified.\nPlease use '/vipcolor [hexcode]' to change the color of VIP★.\nExample :- /vipcolor 33ccff", - "VipColorInvalidGradientCode": "Invalid hexcode specified.\nPlease use '/vipcolor [hexcode][hexcode]' to change color of VIP★.\nExample :- /vipcolor 33ccff ff99cc", - "TagColorInvalidHexCode": "Invalid hexcode specified.\nPlease use '/tagcolor [hexcode]' to change the color of your tag.\nExample :- /tagcolor ff00ff", - "midCommandDisabled": "The mid command is currently disabled.", - "midCommandNoAccess": "You do not have access to the mid command.", - "WarnCommandDisabled": "The warn command is currently disabled.", - "WarnCommandNoAccess": "You do not have access to the warn command.", - "WarnCommandInvalidID": "Invalid player ID specified.\nPlease use '/warn [playerID] [reason]' to warn a player. \nExample :- /warn 5 lava chatting", - "WarnCommandWarnHost": "You are not permitted to warn the host.", + "KickCommandDisabled": "The kick command is currently disabled.", + "KickCommandNoAccess": "You do not have access to the kick command.", + "KickCommandInvalidID": "Invalid player ID specified.\nPlease use '/kick [playerID] [reason]' to kick a player.\nExample :- /kick 5 not following rules", + "KickCommandKickHost": "You are not permitted to kick the host.", + "KickCommandKickMod": "You are not permitted to kick other moderators.", + "KickCommandKicked": "was kicked from the game by ", + "KickCommandKickedRole": "Their role was", + "BanCommandDisabled": "The ban command is currently disabled.", + "BanCommandNoAccess": "You do not have access to the ban command.", + "BanCommandInvalidID": "Invalid player ID specified.\nPlease use '/ban [playerID] [reason]' to ban a player.\nExample :- /ban 5 not following rules ", + "BanCommandBanHost": "You are not permitted to ban the host.", + "BanCommandBanMod": "You are not permitted to ban other moderators.", + "BanCommandBanned": "was banned from the game by ", + "BanCommandBannedRole": "Their role was", + "BanCommandNoReason": "No reason specified.\nPlease use '/ban [playerID] [reason]\nExample :- /ban 5 not following rules", + "ColorCommandDisabled": "The modcolor command is currently disabled.", + "ColorCommandNoAccess": "You do not have access to the modcolor command.", + "ColorCommandNoLobby": "You can only use the command in Lobby when the game hasn't started.", + "ColorInvalidHexCode": "Invalid hexcode specified.\nPlease use '/modcolor [hexcode]' to change the color of MODERATOR♥.\nExample :- /modcolor 33ccff", + "ColorInvalidGradientCode": "Invalid hexcode specified.\nPlease use '/modcolor [hexcode][hexcode]' to change color of MODERATOR♥.\nExample :- /modcolor 33ccff ff99cc", + "VipColorCommandDisabled": "The vipcolor command is currently disabled.", + "VipColorCommandNoAccess": "You do not have access to the vipcolor command.", + "VipColorCommandNoLobby": "You can only use the command in Lobby when the game hasn't started.", + "VipColorInvalidHexCode": "Invalid hexcode specified.\nPlease use '/vipcolor [hexcode]' to change the color of VIP★.\nExample :- /vipcolor 33ccff", + "VipColorInvalidGradientCode": "Invalid hexcode specified.\nPlease use '/vipcolor [hexcode][hexcode]' to change color of VIP★.\nExample :- /vipcolor 33ccff ff99cc", + "TagColorInvalidHexCode": "Invalid hexcode specified.\nPlease use '/tagcolor [hexcode]' to change the color of your tag.\nExample :- /tagcolor ff00ff", + "midCommandDisabled": "The mid command is currently disabled.", + "midCommandNoAccess": "You do not have access to the mid command.", + "WarnCommandDisabled": "The warn command is currently disabled.", + "WarnCommandNoAccess": "You do not have access to the warn command.", + "WarnCommandInvalidID": "Invalid player ID specified.\nPlease use '/warn [playerID] [reason]' to warn a player. \nExample :- /warn 5 lava chatting", + "WarnCommandWarnHost": "You are not permitted to warn the host.", "StartCommandNoAccess": "You do not have access to the start command.", "StartCommandDisabled": "The start command is currently disabled.", "StartCommandCountdown": "ERROR\n\nThe game is already starting!", "StartCommandStarted": "The game has been started by {0}!", "StartCommandInvalidCountdown": "ERROR\n\nThe countdown must be between {0} and {1}!", - "WarnCommandWarnMod": "You are not permitted to warn other moderators.", - "WarnCommandWarned": "has been warned. There will be no more warnings given and appropriate action will be taken \n ", - "WarnExample": "Use /warn [id] [reason] in future. \nExample :-\n /warn 5 lava chatting", - "SayCommandDisabled": "The say command is currently disabled.", - "MessageFromModerator": "MODERATOR", - "DeathReason.Kill": "Killed", - "DeathReason.Vote": "Ejected", - "DeathReason.Suicide": "Suicide", - "DeathReason.Spell": "Spelled", - "DeathReason.Cursed": "Cursed", - "DeathReason.Hex": "Hexed", - "DeathReason.Bite": "Bitten", - "DeathReason.Poison": "Poisoned", - "DeathReason.Gambled": "Guessed", - "DeathReason.FollowingSuicide": "Heartbroken", - "DeathReason.Bombed": "Exploded", - "DeathReason.Misfire": "Misfire", - "DeathReason.Torched": "Burned", - "DeathReason.Sniped": "Sniped", - "DeathReason.Execution": "Executed", - "DeathReason.Fall": "Fall", - "DeathReason.Revenge": "Revenge", - "DeathReason.Eaten": "Eaten", - "DeathReason.Sacrifice": "Victim", - "DeathReason.Quantization": "Quantization", - "DeathReason.Overtired": "Overtired", - "DeathReason.Ashamed": "Ashamed", - "DeathReason.Consumed": "Consumed", - "DeathReason.PissedOff": "Destroyed", - "DeathReason.Dismembered": "Dismembered", - "DeathReason.LossOfHead": "Strangled", - "DeathReason.Trialed": "Judged", - "DeathReason.Infected": "Infected", - "DeathReason.Jinx": "Jinxed", - "DeathReason.Pirate": "Plundered", - "DeathReason.Shrouded": "Shrouded", - "DeathReason.etc": "Other", - "DeathReason.Mauled": "Mauled", - "DeathReason.Hack": "Hacked", - "DeathReason.Curse": "Cursed", - "DeathReason.Drained": "Drained", - "DeathReason.Shattered": "Shattered", - "DeathReason.Trap": "Trapped", - "DeathReason.Targeted": "Targeted", - "DeathReason.Retribution": "Retribution", - "DeathReason.Slice": "Sliced", - "DeathReason.BloodLet": "Bleed", - "DeathReason.Armageddon": "Armageddon", - "DeathReason.Starved": "Starved", - "DeathReason.Equilibrium": "Equilibrium", - "DeathReason.Sacrificed": "Sacrificed", + "WarnCommandWarnMod": "You are not permitted to warn other moderators.", + "WarnCommandWarned": "has been warned. There will be no more warnings given and appropriate action will be taken \n ", + "WarnExample": "Use /warn [id] [reason] in future. \nExample :-\n /warn 5 lava chatting", + "SayCommandDisabled": "The say command is currently disabled.", + "MessageFromModerator": "MODERATOR", + "DeathReason.Kill": "Killed", + "DeathReason.Vote": "Ejected", + "DeathReason.Suicide": "Suicide", + "DeathReason.Spell": "Spelled", + "DeathReason.Cursed": "Cursed", + "DeathReason.Hex": "Hexed", + "DeathReason.Bite": "Bitten", + "DeathReason.Poison": "Poisoned", + "DeathReason.Gambled": "Guessed", + "DeathReason.FollowingSuicide": "Heartbroken", + "DeathReason.Bombed": "Exploded", + "DeathReason.Misfire": "Misfire", + "DeathReason.Torched": "Burned", + "DeathReason.Sniped": "Sniped", + "DeathReason.Execution": "Executed", + "DeathReason.Fall": "Fall", + "DeathReason.Revenge": "Revenge", + "DeathReason.Eaten": "Eaten", + "DeathReason.Sacrifice": "Victim", + "DeathReason.Quantization": "Quantization", + "DeathReason.Overtired": "Overtired", + "DeathReason.Ashamed": "Ashamed", + "DeathReason.PissedOff": "Destroyed", + "DeathReason.Dismembered": "Dismembered", + "DeathReason.LossOfHead": "Strangled", + "DeathReason.Trialed": "Judged", + "DeathReason.Infected": "Infected", + "DeathReason.Jinx": "Jinxed", + "DeathReason.Pirate": "Plundered", + "DeathReason.Shrouded": "Shrouded", + "DeathReason.etc": "Other", + "DeathReason.Mauled": "Mauled", + "DeathReason.Hack": "Hacked", + "DeathReason.Curse": "Cursed", + "DeathReason.Drained": "Drained", + "DeathReason.Shattered": "Shattered", + "DeathReason.Trap": "Trapped", + "DeathReason.Targeted": "Targeted", + "DeathReason.Retribution": "Retribution", + "DeathReason.Slice": "Sliced", + "DeathReason.AllergicReaction": "Allergic reaction", + "DeathReason.FadedAway": "Faded away", + "DeathReason.BloodLet": "Bleed", + "DeathReason.Armageddon": "Armageddon", + "DeathReason.Starved": "Starved", + "DeathReason.Equilibrium": "Equilibrium", + "DeathReason.Sacrificed": "Sacrificed", "DeathReason.Electrocuted": "Electrocuted", "DeathReason.Scavenged": "Scavenged", - "OnlyEnabledDeathReasons": "Only Enabled Death Reasons", - "Alive": "Alive", - "Disconnected": "Disconnected", - "Win": " Wins!", - - "Last-": "Last ", - "Madmate-": "Madmate ", - "Recruit-": "Recruit ", - "Charmed-": "Charmed ", - "Soulless-": "Soulless ", - "Infected-": "Infected ", - "Contagious-": "Contagious ", - "Admired-": "Admired ", - - "DeputyHandcuffCooldown": "Handcuff Cooldown", - "DeputyHandcuffMax": "Maximum Handcuffs", - "DeputyHandcuffedPlayer": "Handcuffed target", - "HandcuffedByDeputy": "You were handcuffed!", - "DeputyInvalidTarget": "Target cannot be handcuffed", - "DeputyHandcuffText": "Handcuff", - "DeputyHandcuffCDForTarget": "Kill Cooldown for handcuffed player", - - "RejectShapeshift.AbilityWasUsed": "Ability was used", - - "EscapisMtarkedPosition": "You marked self-position", - - "InvestigateCooldown": "Investigate Cooldown", - "InvestigateMax": "Maximum Investigations", - "InvestigateRoundMax": "Maximum Investigations in one round", - - "Color.Red": "Red", - "Color.Green": "Green", - "Color.Gray": "Gray", - "InvestigatorInvestigatedPlayer": "Player Investigated", - "InvestigatorInvalidTarget": "Can not investigate", - "InvestigatorButtonText": "Check", - - "Investigator.Suspicion": "Suspicion", - "Investigator.Role": "Role", - "SabotageCooldownControl": "Sabotage Cooldown Control", - "SabotageCooldown": "Sabotage Cooldown", - "SabotageTimeControl": "Sabotage Duration Control", - "SkeldReactorTimeLimit": "The Skeld Reactor Time Limit", - "SkeldO2TimeLimit": "The Skeld O2 Time Limit", - "MiraReactorTimeLimit": "MIRA HQ Reactor Time Limit", - "MiraO2TimeLimit": "MIRA HQ O2 Time Limit", - "PolusReactorTimeLimit": "Polus Reactor Time Limit", - "AirshipReactorTimeLimit": "Airship Reactor Time Limit", - "FungleReactorTimeLimit": "The Fungle Reactor Time Limit", - "FungleMushroomMixupDuration": "The Fungle Mushroom Mixup Duration", - "CommandList": "★ Command list:", - "Command.now": "→ Display active Settings", - "Command.roles": "[RoleName] → Display Role description", - "Command.myrole": "→ Displays a description of your role", - "Command.lastresult": "→ Display match results", - "Command.winner": "→ Display winners", - "CommandOtherList": "● Other commands:", - "Command.color": "[Color] → Change your color", - "Command.rename": "[Name] → Change Host Name", - "Command.quit": "→ I don't want to enter this lobby anymore", - "CommandHostList": "▲ Host Commands:", - "Command.say": "[Content] → Send message as Host", - "Command.mw": "[Seconds] → Set the message waiting duration", - "Command.solvecover": "→ Fix an issue where role names overlap the messages", - "Command.kill": "[Player ID] → Kill assigned player", - "Command.exe": "[Player ID] → Eject assigned player", - "Command.level": "[Level] → Change your in-game level", - "Command.idlist": "→ Display a list of player IDs", - "Command.qq": "→ Lobby will be posted on QQ website (China only)", - "Command.dump": "→ Output Log to Desktop", - "Command.death": "→ Display info on how you died", - "Command.icons": "
╳ - The Player was marked by the Blackmailer and can't talk during the Meeting
☆ - Used by Captain to display themselves. Only Crewmates can see the Captain's star
乂 - This player was hexed by the Hex Master and will die if the Hex Master isn't killed or ejected by the end of the Meeting.
♦ - Used by Lawyer or Executioner or Follower.
♥ - Used by Lovers or Romantic.
✚ - Used by Medic to mark their target.
⦿ - This player is in a duel with the Pirate.
!? - This player was marked by the Quizmaster and must answer the question correctly to survive.
☜ - Used by Schrödinger's cat to mark their teammate.
◈ - This player marked by the Shroud and will die if the Shroud is not killed or ejected by the end of the meeting.
⚠ - This player is a Snitch or Solsticer who has finished their tasks.
★ - Used by Super Star or Cyber or Marshall.
† - This player was spelled and will die if the Witch is not killed by the end of the meeting.
∇ - Used by Kamikaze to mark their targets.
■ - Used by Lightning to mark their quantum ghosts.
⊠ - Used by Jailer to mark their prisoner.
● - Used by Baker to mark who has Bread.
♠ - Used by Soul Collector to mark who's death they're predicting.
⦿ - Used by Plaguebearer to mark who they have plagued.", + "OnlyEnabledDeathReasons": "Only Enabled Death Reasons", + "Alive": "Alive", + "Disconnected": "Disconnected", + "Win": " Wins!", + + "Last-": "Last ", + "Madmate-": "Madmate ", + "Recruit-": "Recruit ", + "Charmed-": "Charmed ", + "Soulless-": "Soulless ", + "Infected-": "Infected ", + "Contagious-": "Contagious ", + "Admired-": "Admired ", + + "DeputyHandcuffCooldown": "Handcuff Cooldown", + "DeputyHandcuffMax": "Maximum Handcuffs", + "DeputyHandcuffedPlayer": "Handcuffed target", + "HandcuffedByDeputy": "You were handcuffed!", + "DeputyInvalidTarget": "Target cannot be handcuffed", + "DeputyHandcuffText": "Handcuff", + "DeputyHandcuffCDForTarget": "Kill Cooldown for handcuffed player", + + "RejectShapeshift.AbilityWasUsed": "Ability was used", + + "EvolverCatchText": "Catch", + "EvolverCatchSuccess": "Point gained!", + "EvolverCatchFailure": "You failed to catch them", + "EvolverMegaPointGain": "You have found a rare MEGA point!", + "Evolver_MinUpgradesToWin": "Minimum evolutions required to win", + + "EscapisMtarkedPosition": "You marked self-position", + + "InvestigateCooldown": "Investigate Cooldown", + "InvestigateMax": "Maximum Investigations", + "InvestigateRoundMax": "Maximum Investigations in one round", + + "Color.Red": "Red", + "Color.Green": "Green", + "Color.Gray": "Gray", + "InvestigatorInvestigatedPlayer": "Player Investigated", + "InvestigatorInvalidTarget": "Can not investigate", + "InvestigatorButtonText": "Check", + + "Investigator.Suspicion": "Suspicion", + "Investigator.Role": "Role", + "SabotageCooldownControl": "Sabotage Cooldown Control", + "SabotageCooldown": "Sabotage Cooldown", + "SabotageTimeControl": "Sabotage Duration Control", + "SkeldReactorTimeLimit": "The Skeld Reactor Time Limit", + "SkeldO2TimeLimit": "The Skeld O2 Time Limit", + "MiraReactorTimeLimit": "MIRA HQ Reactor Time Limit", + "MiraO2TimeLimit": "MIRA HQ O2 Time Limit", + "PolusReactorTimeLimit": "Polus Reactor Time Limit", + "AirshipReactorTimeLimit": "Airship Reactor Time Limit", + "FungleReactorTimeLimit": "The Fungle Reactor Time Limit", + "FungleMushroomMixupDuration": "The Fungle Mushroom Mixup Duration", + "CommandList": "★ Command list:", + "Command.now": "→ Display active Settings", + "Command.roles": "[RoleName] → Display Role description", + "Command.myrole": "→ Displays a description of your role", + "Command.lastresult": "→ Display match results", + "Command.winner": "→ Display winners", + "CommandOtherList": "● Other commands:", + "Command.color": "[Color] → Change your color", + "Command.rename": "[Name] → Change Host Name", + "Command.quit": "→ I don't want to enter this lobby anymore", + "CommandHostList": "▲ Host Commands:", + "Command.say": "[Content] → Send message as Host", + "Command.mw": "[Seconds] → Set the message waiting duration", + "Command.solvecover": "→ Fix an issue where role names overlap the messages", + "Command.kill": "[Player ID] → Kill assigned player", + "Command.exe": "[Player ID] → Eject assigned player", + "Command.level": "[Level] → Change your in-game level", + "Command.idlist": "→ Display a list of player IDs", + "Command.qq": "→ Lobby will be posted on QQ website (China only)", + "Command.dump": "→ Output Log to Desktop", + "Command.death": "→ Display info on how you died", + "Command.icons": "
╳ - The Player was marked by the Blackmailer and can't talk during the Meeting
☆ - Used by Captain to display themselves. Only Crewmates can see the Captain's star
乂 - This player was hexed by the Hex Master and will die if the Hex Master isn't killed or ejected by the end of the Meeting.
♦ - Used by Lawyer or Executioner or Follower.
♥ - Used by Lovers or Romantic.
✚ - Used by Medic to mark their target.
⦿ - This player is in a duel with the Pirate.
!? - This player was marked by the Quizmaster and must answer the question correctly to survive.
☜ - Used by Schrödinger's cat to mark their teammate.
◈ - This player marked by the Shroud and will die if the Shroud is not killed or ejected by the end of the meeting.
⚠ - This player is a Snitch or Solsticer who has finished their tasks.
★ - Used by Super Star or Cyber or Marshall.
† - This player was spelled and will die if the Witch is not killed by the end of the meeting.
∇ - Used by Kamikaze to mark their targets.
■ - Used by Lightning to mark their quantum ghosts.
⊠ - Used by Jailer to mark their prisoner.
● - Used by Baker to mark who has Bread.
♠ - Used by Soul Collector to mark who's death they're predicting.
⦿ - Used by Plaguebearer to mark who they have plagued.", "Command.start": "[Seconds] → Start the game", - "Command.iconinfo": "→ Display info on in-meeting icons", - "Command.iconhelp": "→ Display info on in-meeting icons to everyone", - "Command.Poll": "→ Start a poll with up-to 5 choices", - "IconsTitle": "Icon Meanings⚠", - "Remaining.ImpostorCount": "Impostors left: {0}", - "Remaining.MadmateCount": "Madmates left: {0}", - "Remaining.NeutralCount": "Neutral Killers left: {0}", - "Remaining.ApocalypseCount": "Neutral Apocalypse left: {0}", - "EnableKillerLeftCommand": "Enable use of /kcount command", - "ShowMadmatesInLeftCommand": "Show Madmates (including add-ons)", - "ShowApocalypseInLeftCommand": "Show Neutral Apocalypse", - "SeeEjectedRolesInMeeting": "See ejected roles in meetings", - "ThankYouForUsingTOHE": "Thank you for using TOHE!", - - "SkillUsedLeft": "You have activated your skill to call a meeting. \nRemaining amount of uses left:", - "NemesisDeadMsg": "The death of the Nemesis means the beginning of the revenge. \nPlease use /rv + [player ID] to kill the specified player \nYou can see player IDs in front of their names. \nOr type /rv to get a list of player IDs", - "NemesisAliveKill": "Revenge for the Nemesis can only begin after their death.", - "NemesisKillDead": "Choose a living player to take revenge", - "NemesisKillSucceed": "[{0}] was killed by the Nemesis!", - "NemesisKillDisable": "Sorry, but according to Host's settings, Nemesis revenge is prohibited in this game", - "NemesisKillMax": "You've reached the maximum amount of kills, you can't kill anymore!", - - "CelebrityDead": "Shock! Celebrity[{0}]has unfortunately been mercilessly killed in the recent period!", - "CyberDead": "Oh no! It appears the Cyber, {0}, has died recently.", - "DetectiveNoticeVictim": "According to your investigation,\nthe victim ([{0}]) had the role [{1}]", - "DetectiveNoticeKiller": "\nThe killer's role is [{0}]", - "DetectiveNoticeKillerNotFound": "The Detective couldn't find evidence leading to a murderer. This death is most likely suicide.", - "GodNoticeAlive": "During the meeting, each player felt a revelation from heaven, and it turned out that God is still alive!", - "WorkaholicAdviceAlive": "It's not recommended to kill or vote [{0}] out. Doing so will help them finish their tasks quicker.", - "GuessDead": "Sorry, but it's impossible to guess roles after your death", - "GuessSuperStar": "The Super Star can't be guessed... you thought it would be that easy, right?", - "GuessNotifiedBait": "Bait can't be guessed because it was announced. You thought it would be that easy, right?", - "GuessGM": "Guessing the GM is impossible because they're already dead.... And why would you do that to the poor Host?", - "GuessGuardianTask": "You can't guess a Guardian who has finished their tasks.", - "GuardianCantKilled": "You can't kill a Guardian who has finished their tasks.", - "GuessMarshallTask": "You can't guess a Marshall who has finished their tasks.", - "GuessObviousAddon": "Sorry, obvious add-ons cannot be guessed.", - "GuessAdtRole": "Unfortunately, the Host's settings do not allow you to guess add-ons", - "GuessImpRole": "Unfortunately, the Host's settings do not allow Impostors to guess Impostor roles.", - "GuessCrewRole": "Unfortunately, the Host's settings do not allow crewmates to guess crewmate roles.", - "GuessApocRole": "Fortunately, the Host's settings does not allow Apocalypse to guess Apocalypse roles.", - "GuessKill": "{0} was guessed", - "GuessNull": "Please select an ID of a living player to guess their role", - "GuessHelp": "Instructions: /bt [Player ID] [Role Name] \nExample: /bt 3 Bait \nYou can see the player IDs before everyone's names \n or use the /id command to list the player IDs", - "GGGuessMax": "You've reached the maximum guess limit. You can't guess anymore!", - "EGGuessMax": "You've reached the maximum guess limit. You can't guess anymore!", - "EGGuessSnitchTaskDone": "You thought you could guess the Snitch when all their tasks are done? Nice try. You're not getting out of this that easily.", - "GuessDoubleShot": "You guessed a role incorrectly, but you have Double Shot, so you get another chance!", - "LaughToWhoGuessSelf": "Tried to guess, who tried to self-guess! It's you! Ahah!", - "GuessDisabled": "Sorry, the host restricted guessing for your role.", - "GuessWorkaholic": "Sorry, you can't guess a revealed Workaholic as that would be unfair.", - "GuessDoctor": "Sorry, you can't guess a revealed Doctor as that would be unfair.", - "GuessMayor": "Sorry, you can't guess a revealed Mayor as that would be unfair.", - "GuessKnighted": "Sorry, Monarchs cannot guess Knighted.", - "GuessMonarch": "There's a knighted player alive, so the Monarch cannot be guessed.", - "GuessShielded": "Sorry, you can't guess the player who the Medic shields", - "MayorRevealWhenDoneTasks": "Mayor is revealed to everyone on task completion", - "MimicDeadMsg": "Mimic's hint: ", - "FortuneTellerCheck": "According to your fortune...", - "FortuneTellerCheckLimit": "Reminder: You have {0} fortunes left", - "FortuneTellerCheckSelfMsg": "Wow, you found yourself... All you see is a reflection.", - "FortuneTellerCheckReachLimit": "You've run out of fortunes.", - "FortuneTellerAlreadyCheckedMsg": "You've already checked the player", - "MorticianGetNoInfo": "According to your inspection, {0} did not seem to have contact with anyone during their lifetime.", - "MorticianGetInfo": "According to your inspection, the last person {0} came into contact with during their lifetime was {1}.", - - "MediumOnlyReceiveMsgFromCrew": "Receive messages only from Crewmates (including Madmates and Charmed Players)", - "MediumTitle": "MEDIUM", - "MediumHelp": "/ms yes to agree\n/ms no to disagree", - "MediumYes": "You thought you heard a quiet voice from another world affirming the answer to your question.", - "MediumNo": "You thought you heard a quiet voice from another world denying the answer to your question.", - "MediumDone": "You successfully responded to the Medium.", - "MediumNotifyTarget": "{0}, the Medium, has established contact with you. Before the end of this meeting, you have a chance to respond to their question. Type one of the following commands to answer:\nConfirm: /ms yes\nDeny: /ms no", - "MediumNotifySelf": "You established contact with {0}. Please ask them questions and wait for them to respond.\n\nRemaining ability uses: {1}", - "MediumKnowPlayerDead": "Someone died somewhere", - - "SpurtMinSpeed": "Min Speed", - "SpurtMaxSpeed": "Max Speed", - "SpurtModule": "Speed Modulator", - "EnableSpurtCharge": "Display The Charge", - "SpurtSuffix": "\n« Spurt: {0}% »", - - "TargetIsAlreadyDead": "Target Is Already Dead", - "ByBard": "by Bard", - "ByBardGetFailed": "Oops, I seem to be out of inspiration.", - "GangsterSuccessfullyRecruited": "You successfully recruited a player", - "GangsterRecruitmentFailure": "Target cannot be recruited", - "BeRecruitedByGangster": "The Gangster has recruited you", - "KamikazeHostage": "Can't hold target hostage", - "StealerGetTicket": "You've got {0} votes", - "BecomeMadmateCuzMadmateMode": "You became a Madmate because you died", - "CleanerCleanBody": "The body has been cleaned", - "QuickShooterStoraging": "Bullets stored successfully", + "Command.iconinfo": "→ Display info on in-meeting icons", + "Command.iconhelp": "→ Display info on in-meeting icons to everyone", + "Command.Poll": "→ Start a poll with up-to 5 choices", + "IconsTitle": "Icon Meanings⚠", + "Remaining.ImpostorCount": "Impostors left: {0}", + "Remaining.MadmateCount": "Madmates left: {0}", + "Remaining.NeutralCount": "Neutral Killers left: {0}", + "Remaining.ApocalypseCount": "Neutral Apocalypse left: {0}", + "EnableKillerLeftCommand": "Enable use of /kcount command", + "ShowMadmatesInLeftCommand": "Show Madmates (including add-ons)", + "ShowApocalypseInLeftCommand": "Show Neutral Apocalypse", + "SeeEjectedRolesInMeeting": "See ejected roles in meetings", + + "SkillUsedLeft": "You have activated your skill to call a meeting. \nRemaining amount of uses left:", + "NemesisDeadMsg": "The death of the Nemesis means the beginning of the revenge. \nPlease use /rv + [player ID] to kill the specified player \nYou can see player IDs in front of their names. \nOr type /rv to get a list of player IDs", + "NemesisAliveKill": "Revenge for the Nemesis can only begin after their death.", + "NemesisKillDead": "Choose a living player to take revenge", + "NemesisKillSucceed": "[{0}] was killed by the Nemesis!", + "NemesisKillDisable": "Sorry, but according to Host's settings, Nemesis revenge is prohibited in this game", + "NemesisKillMax": "You've reached the maximum amount of kills, you can't kill anymore!", + + "CelebrityDead": "Shock! Celebrity[{0}]has unfortunately been mercilessly killed in the recent period!", + "CyberDead": "Oh no! It appears the Cyber, {0}, has died recently.", + "DetectiveNoticeVictim": "According to your investigation,\nthe victim ([{0}]) had the role [{1}]", + "DetectiveNoticeKiller": "\nThe killer's role is [{0}]", + "DetectiveNoticeKillerNotFound": "The Detective couldn't find evidence leading to a murderer. This death is most likely suicide.", + "GodNoticeAlive": "During the meeting, each player felt a revelation from heaven, and it turned out that God is still alive!", + "WorkaholicAdviceAlive": "It's not recommended to kill or vote [{0}] out. Doing so will help them finish their tasks quicker.", + "GuessDead": "Sorry, but it's impossible to guess roles after your death", + "GuessSuperStar": "The Super Star can't be guessed... you thought it would be that easy, right?", + "GuessNotifiedBait": "Bait can't be guessed because it was announced. You thought it would be that easy, right?", + "GuessGM": "Guessing the GM is impossible because they're already dead.... And why would you do that to the poor Host?", + "GuessGuardianTask": "You can't guess a Guardian who has finished their tasks.", + "GuessMarshallTask": "You can't guess a Marshall who has finished their tasks.", + "GuessObviousAddon": "Sorry, obvious add-ons cannot be guessed.", + "GuessAdtRole": "Unfortunately, the Host's settings do not allow you to guess add-ons", + "GuessImpRole": "Unfortunately, the Host's settings do not allow Impostors to guess Impostor roles.", + "GuessCrewRole": "Unfortunately, the Host's settings do not allow crewmates to guess crewmate roles.", + "GuessApocRole": "Fortunately, the Host's settings does not allow Apocalypse to guess Apocalypse roles.", + "GuessKill": "{0} was guessed", + "GuessNull": "Please select an ID of a living player to guess their role", + "GuessHelp": "Instructions: /bt [Player ID] [Role Name] \nExample: /bt 3 Bait \nYou can see the player IDs before everyone's names \n or use the /id command to list the player IDs", + "GGGuessMax": "You've reached the maximum guess limit. You can't guess anymore!", + "EGGuessMax": "You've reached the maximum guess limit. You can't guess anymore!", + "EGGuessSnitchTaskDone": "You thought you could guess the Snitch when all their tasks are done? Nice try. You're not getting out of this that easily.", + "GuessDoubleShot": "You guessed a role incorrectly, but you have Double Shot, so you get another chance!", + "LaughToWhoGuessSelf": "Tried to guess, who tried to self-guess! It's you! Ahah!", + "GuessDisabled": "Sorry, the host restricted guessing for your role.", + "GuessWorkaholic": "Sorry, you can't guess a revealed Workaholic as that would be unfair.", + "GuessDoctor": "Sorry, you can't guess a revealed Doctor as that would be unfair.", + "GuessMayor": "Sorry, you can't guess a revealed Mayor as that would be unfair.", + "GuessKnighted": "Sorry, Monarchs cannot guess Knighted.", + "GuessMonarch": "There's a knighted player alive, so the Monarch cannot be guessed.", + "GuessShielded": "Sorry, you can't guess the player who the Medic shields", + "MayorRevealWhenDoneTasks": "Mayor is revealed to everyone on task completion", + "MimicDeadMsg": "Mimic's hint: ", + "FortuneTellerCheck": "According to your fortune...", + "FortuneTellerCheckLimit": "Reminder: You have {0} fortunes left", + "FortuneTellerCheckSelfMsg": "Wow, you found yourself... All you see is a reflection.", + "FortuneTellerCheckReachLimit": "You've run out of fortunes.", + "FortuneTellerAlreadyCheckedMsg": "You've already checked the player", + "MorticianGetNoInfo": "According to your inspection, {0} did not seem to have contact with anyone during their lifetime.", + "MorticianGetInfo": "According to your inspection, the last person {0} came into contact with during their lifetime was {1}.", + + "MediumOnlyReceiveMsgFromCrew": "Receive messages only from Crewmates (including Madmates and Charmed Players)", + "MediumTitle": "MEDIUM", + "MediumHelp": "/ms yes to agree\n/ms no to disagree", + "MediumYes": "You thought you heard a quiet voice from another world affirming the answer to your question.", + "MediumNo": "You thought you heard a quiet voice from another world denying the answer to your question.", + "MediumDone": "You successfully responded to the Medium.", + "MediumNotifyTarget": "{0}, the Medium, has established contact with you. Before the end of this meeting, you have a chance to respond to their question. Type one of the following commands to answer:\nConfirm: /ms yes\nDeny: /ms no", + "MediumNotifySelf": "You established contact with {0}. Please ask them questions and wait for them to respond.\n\nRemaining ability uses: {1}", + "MediumKnowPlayerDead": "Someone died somewhere", + + "SpurtMinSpeed": "Min Speed", + "SpurtMaxSpeed": "Max Speed", + "SpurtModule": "Speed Modulator", + "EnableSpurtCharge": "Display The Charge", + "SpurtSuffix": "\n« Spurt: {0}% »", + + "TargetIsAlreadyDead": "Target Is Already Dead", + "ByBard": "by Bard", + "ByBardGetFailed": "Oops, I seem to be out of inspiration.", + "GangsterSuccessfullyRecruited": "You successfully recruited a player", + "GangsterRecruitmentFailure": "Target cannot be recruited", + "BeRecruitedByGangster": "The Gangster has recruited you", + "KamikazeHostage": "Can't hold target hostage", + "StealerGetTicket": "You've got {0} votes", + "BecomeMadmateCuzMadmateMode": "You became a Madmate because you died", + "CleanerCleanBody": "The body has been cleaned", + "QuickShooterStoraging": "Bullets stored successfully", "QuickShooterFailed": "You are still in cooldown.", - "PoisonerTargetDead": "Target died", - "HexesLookLikeSpells": "Hexes appear as spells", - "HexButtonText": "Hex", - "BloodthirstAdded": "Your bloodthirst is now active!", - "WarlockNoTarget": "Manipulation failed due to no target", - "WarlockNoTargetYet": "You haven't marked a target.", - "WarlockTargetDead": "Manipulation failed due to target dead", - "WarlockControlKill": "Target died", - "OnCelebrityDead": "Warning: Celebrity death!", - "OnCyberDead": "Warning: Cyber died!", - "TeleportedInRndVentByDisperser": "Everyone was teleported to vents", - "TeleportedByTransporter": "Swapping places with: {0}", - "ErrorTeleport": "Teleport failed", - "EraseLimit": "Max Erases", - "EraserHideVote": "Hide Eraser Votes", - "EraserEraseMsgTitle": "ERASER", - "EraserEraseNotice": "You erased {0}.\nTheir role will be deactivated after the meeting.", - "EraserEraseBaseImpostorOrNeutralRoleNotice": "Oops, your target cannot be erased!", - "EraserEraseSelf": "Unfortunately, you can't erase yourself... Wait, why would you do that in the first place?!", - "EraserTryingGuessErasedPlayer": "You can't guess the role of the player you erased, except add-ons", - "LostRoleByEraser": "You lost your role because of the Eraser", - "KilledByScavenger": "The Scavenger killed you and thus teleported off-map", - "SnitchDoneTasks": "Call a meeting to find the impostors", - "SwooperCanVent": "Vent to turn invisible", - "SwooperInvisState": "You're invisible", - "SwooperInvisStateOut": "You're now visible", - "SwooperInvisInCooldown": "Swoop cooldown isn't up yet. Swooping failed", - "SwooperInvisStateCountdown": "Invisibility will expire after {0}s", - "SwooperInvisCooldownRemain": "Swoop Cooldown: {0}s", - "WraithCanVent": "Vent to turn invisible", - "WraithInvisState": "You are invisible", - "WraithInvisStateOut": "You are visible again", - "WraithInvisInCooldown": "Ability still on cooldown, vanish failed", - "WraithInvisStateCountdown": "Invisibility will expire in {0}s", - "WraithInvisCooldownRemain": "{0}s left in invisibility", - "WerewolfKillButtonText": "Maul", - "BKInProtect": "Currently immortal", - "BKProtectOut": "Shield expired", - "BKSkillTimeRemain": "You're immune for {0} seconds", - "BKSkillNotice": "Kill a player to enter immune status", - "BKOffsetKill": "Someone tried killing you", - "MedicKillerTryBrokenShieldTargetForMedic": "Someone tried killing the player you shielded!", - "MedicKillerTryBrokenShieldTargetForTarget": "Someone tried killing you!", - "FollowerBetPlayer": "You're now following your target", - "FollowerBetOnYou": "The Follower is now following you", - "CultistCharmedPlayer": "You successfully charmed a player", - "CharmedByCultist": "You have been charmed by the Cultist", - "CultistInvalidTarget": "Target cannot be charmed", - "KillBaitNotify": "You'll self-report in {0}s", - "InfectiousInvalidTarget": "Target cannot be infected", - "BittenByInfectious": "The Infectious infected you!", - "InfectiousBittenPlayer": "You successfully infected a player", - "GuessNotAllowed": "Sorry, your role does not have access to guessing.", - "GuessOnbound": "This player has the Onbound add-on, so your guess on them was canceled.", - "GuessSpecter": "You can't guess a Specter. That allows them to win!", - "PacifistOnGuard": "Ability used, {0} uses remain", - "PacifistSkillNotify": "Pacifist reset your kill cooldown", - "BeRecruitedByJackal": "The Jackal has recruited you", - "YinYangerAlreadyMarked": "{0} is already in a state of calm, endowed by a fellow YinYanger", - "CoronerTrackRecorded": "Track recorded", - "CoronerNoTrack": "Nothing to track", - "CoronerIsTrackingYou": "The Coroner is tracking you!", - "CoronerReportButtonText": "Track", - "MerchantAddonDelivered": "Add-on sold", - "MerchantAddonSell": "The Merchant sold you a new Add-on", - "MerchantAddonSellFail": "Could not sell an Add-on", - "BribedByMerchant": "The Merchant bribed you. You can't kill him", - "BribedByMerchant2": "You cannot guess the Merchant after he bribed you.", - "MerchantKillAttemptBribed": "An attempted killing was averted by bribery", - "TrapTrapsterBody": "Trap Trapster's body", - "TrapConsecutiveBodies": "Trap consecutive bodies", - "HauntedByEvilSpirit": "Haunted by an Evil Spirit", - "MonarchKnightCooldown": "Knight Cooldown", - "MonarchKnightMax": "Maximum Knights", - "HideAdditionalVotesForKnighted": "Hide additional vote for Knighted players", - "MonarchKnightedPlayer": "You successfully knighted a player!", - "KnightedByMonarch": "A Monarch has knighted you!", - "MonarchInvalidTarget": "Target cannot be knighted", - "GhostTransformTitle": "Your Role Has Transformed!", - "SpiritcallerNoticeTitle": "YOU TURNED INTO AN EVIL SPIRIT ", - "SpiritcallerNoticeMessage": "The Spiritcaller has killed you and turned you into an Evil Spirit. Your task now is to help the Spiritcaller to victory by using your spook button to hinder other players or to protect the Spiritcaller. Use /m for more information.", - "OverseerRevealCooldown": "Reveal Cooldown", - "OverseerRevealTime": "Reveal Time", - "OverseerVision": "Overseer Vision", - "MerchantMaxSell": "Max number of Add-ons to sell", - "MerchantMoneyPerSell": "Amount of money earned for selling an Add-on", - "MerchantMoneyRequiredToBribe": "Amount of money required to bribe a killer", - "MerchantNotifyBribery": "Inform Merchant when a killer gets bribed", - "MerchantTargetCrew": "Can sell to Crewmates", - "MerchantTargetImpostor": "Can sell to Impostors", - - "MerchantTargetNeutral": "Can sell to Neutrals", - "MerchantSellHelpful": "Can sell Helpful Add-ons", - "MerchantSellHarmful": "Can sell Harmful Add-ons", - "MerchantSellMixed": "Can sell Mixed Add-ons", - "MerchantSellExperimental": "Can sell experimental Add-ons", - "MerchantSellHarmfulToEvil": "Can sell Harmful Add-ons only to Evil", - "MerchantSellHelpfulToCrew": "Can sell Helpful Add-ons only to Crew", - "MerchantSellOnlyEnabledAddons": "Can sell only enabled Add-ons", - - "SpiritcallerSpiritMax": "Maximum number of Evil Spirits", - "SpiritcallerSpiritAbilityCooldown": "Evil Spirit ability cooldown", - "SpiritcallerFreezeTime": "Evil Spirit ability freeze time", - "SpiritcallerProtectTime": "Evil Spirit ability protect time", - "SpiritcallerCauseVision": "Evil Spirit ability caused vision", - "SpiritcallerCauseVisionTime": "Evil Spirit ability caused vision time", - "Message.SetToSeconds": "Set to [{0}] seconds.", - "Message.MessageWaitHelp": "Specify the first argument in seconds.", - "Message.TemplateNotFoundHost": "No templates.txt matching {0} were found", - "Message.TemplateNotFoundClient": "The Host doesn't have a template called {0}", - "Message.SyncButtonLeft": "There are {0} more emergency buttons left", - "Message.Executed": "{0} was executed", - "Message.HideGameSettings": "The host has hidden the game settings.", - "Message.NowOverrideText": "Please enter the root folder of the game.\\Language\\English.dat. Change this text in the dat file \nIf you don't need this feature or want to display regular /n messages. \nPlease disable [Enable only custom /n messages in the settings.]", - "Message.NoDescription": "No description", - "Message.KickedByDenyName": "{0} was kicked because its name matched {1}", - "Message.BannedByBanList": "{0} was banned because they were banned in the past.", - "Message.BannedByEACList": "{0} has been banned because he is in the EAC list of Banned people.", - "Message.DumpfileSaved": "The log file was successfully saved to the desktop, filename: {0}", - "Message.DumpcmdUsed": "{0} used /dump command.", - "Message.KickedByInvalidFriendCode": "{0} was kicked because their friend code is invalid.", - "Message.TempBannedByInvalidFriendCode": "{0} was temporarily banned because their friend code is invalid.", - "Message.AddedPlayerToBanList": "Added {0} to the ban list", - "Message.KickWhoSayStart": "{0} has been kicked by the system. \nThe lobby host doesn't want to see messages where the player asks to start", - "Message.WarnWhoSayStart": "{0} has been warned: {1} times \nThe lobby host doesn't want to see messages where the player asks to start", - "Message.KickStartAfterWarn": "{0} has received {1} warnings, he will be kicked. \nThe lobby host doesn't want to see messages where the player asks to start", - "Message.WarnWhoSayBanWord": "{0}, stop sending banned words!", - "Message.WarnWhoSayBanWordTimes": "{0} has been warned: {1} times \nif you continue you will be kicked", - "Message.KickWhoSayBanWordAfterWarn": "[{0}] received {1} warnings.\nHe was expelled for forbidden words", - "Message.KickedByEAC": "[{0}]Kicked by EAC, reason:{1}", - "Message.BannedByEAC": "[{0}]Banned by EAC, reason:{1}", - "Message.NoticeByEAC": "[{0}]Detected:{1}", - "Message.TempBannedByEAC": "[{0}]Temporary Banned by EAC, reason:{1}", - "Message.TempBannedForSpamQuitting": "{0} was temporary banned because of spamming quits", - "Message.KickedByWhiteList": "{0} kicked because their friendcode was not found in WhiteList.txt", - "Message.SetLevel": "Your game level is set to: {0}", - "Message.SetColor": "Your color is set to: {0}", - "Message.SetName": "Your name is set to: {0}", - "Message.AllowLevelRange": "The game level can be set in the range: 0-100", - "Message.AllowNameLength": "Nickname can be set length: 1-10", - "Message.OnlyCanUseInLobby": "ERROR\n\nSorry, this command can only be used in the lobby", - "Message.CanNotUseInLobby": "ERROR\n\nSorry, this command cannot be used in the lobby", - "Message.CanNotUseByHost": "ERROR\n\nSorry, Host can't use this command", - "Message.TryFixName": "An attempt was made to fix hidden message content due to roles", - "Message.CanNotFindRoleThePlayerEnter": "Could not find the role you searching\nUse command /r to show role list", - "Message.PlayerQuitForever": "{0} decided to leave voluntarily \nSorry for the bad gaming experience \nI really worked hard to make progress", - "Message.MadmateSelfVoteModeNotify": "Please note: The current Madness generation mode is [{0}]\n Voting for yourself means you want to be Madmate. If you meet the conditions to become Madmate and there are still spaces left, you will immediately become Madmate", - "Message.HostLeftGameInGame": "★Warning★ Host left the game, and the game wouldn't start normally next time. Please exit the lobby or wait until the new Host opens a lobby.", - "Message.HostLeftGameInLobby": "★Warning★ Host left the game, and the game wouldn't start normally next time. If the new Host has TOHE, you need to re-enter the lobby to play normally.", - "Message.HostLeftGameNewHostIsMod": "★Warning★ Original Host left the game and {0} become the new Host! \nThe room is still modded, start a game and end it immediately to reset the lobby!", - "Message.HostLeftGameNewHostIsNotMod": "★Warning★ Original Host left the game and {0} become the new Host. \nBut it's not modded. Please exit the lobby or wait until the new Host opens a lobby.", - "Message.LobbyShared": "The lobby has successfully been shared!", - "Message.LobbyShareFailed": "TOHE-Chan does not seem to be online (failed to share lobby)", - "Message.YTPlanDisabled": "ERROR\n\nPlease enable {0} in the Settings", - "Message.YTPlanSelected": "In the next game, your role will be {0}", - "Message.YTPlanSelectFailed": "You cannot be assigned as {0}.\nIt may be because you don't have this role enabled, or this role does not support being assigned.", - "Message.YTPlanCanNotFindRoleThePlayerEnter": "Could not find the role you searching\nUse command /r to show role list", - "Message.YTPlanNotice": "Note: The [YouTuber Plan] is enabled in this lobby, which means the Host can specify their role in the next game to make it easier to get content. If the Host abuses this feature, please exit the game or report it.\nCurrent Creator Credentials:", - "Message.OnlyCanBeUsedByHost": "ERROR\n\nThis command may only be used by the host.", - "Message.MaxPlayers": "Maximum players set to ", + "PoisonerTargetDead": "Target died", + "HexesLookLikeSpells": "Hexes appear as spells", + "HexButtonText": "Hex", + "BloodthirstAdded": "Your bloodthirst is now active!", + "WarlockNoTarget": "Manipulation failed due to no target", + "WarlockNoTargetYet": "You haven't marked a target.", + "WarlockTargetDead": "Manipulation failed due to target dead", + "WarlockControlKill": "Target died", + "OnCelebrityDead": "Warning: Celebrity death!", + "OnCyberDead": "Warning: Cyber died!", + "TeleportedInRndVentByDisperser": "Everyone was teleported to vents", + "TeleportedByTransporter": "Swapping places with: {0}", + "ErrorTeleport": "Teleport failed", + "EraseLimit": "Max Erases", + "EraserHideVote": "Hide Eraser Votes", + "EraserEraseMsgTitle": "ERASER", + "EraserEraseNotice": "You erased {0}.\nTheir role will be deactivated after the meeting.", + "EraserEraseBaseImpostorOrNeutralRoleNotice": "Oops, your target cannot be erased!", + "EraserEraseSelf": "Unfortunately, you can't erase yourself... Wait, why would you do that in the first place?!", + "EraserTryingGuessErasedPlayer": "You can't guess the role of the player you erased, except add-ons", + "LostRoleByEraser": "You lost your role because of the Eraser", + "KilledByScavenger": "The Scavenger killed you and thus teleported off-map", + "SnitchDoneTasks": "Call a meeting to find the impostors", + "SwooperCanVent": "Vent to turn invisible", + "SwooperInvisState": "You're invisible", + "SwooperInvisStateOut": "You're now visible", + "SwooperInvisInCooldown": "Swoop cooldown isn't up yet. Swooping failed", + "SwooperInvisStateCountdown": "Invisibility will expire after {0}s", + "SwooperInvisCooldownRemain": "Swoop Cooldown: {0}s", + "WraithCanVent": "Vent to turn invisible", + "WraithInvisState": "You are invisible", + "WraithInvisStateOut": "You are visible again", + "WraithInvisInCooldown": "Ability still on cooldown, vanish failed", + "WraithInvisStateCountdown": "Invisibility will expire in {0}s", + "WraithInvisCooldownRemain": "{0}s left in invisibility", + "WerewolfKillButtonText": "Maul", + "BKInProtect": "Currently immortal", + "BKProtectOut": "Shield expired", + "BKSkillTimeRemain": "You're immune for {0} seconds", + "BKSkillNotice": "Kill a player to enter immune status", + "BKOffsetKill": "Someone tried killing you", + "MedicKillerTryBrokenShieldTargetForMedic": "Someone tried killing the player you shielded!", + "MedicKillerTryBrokenShieldTargetForTarget": "Someone tried killing you!", + "FollowerBetPlayer": "You're now following your target", + "FollowerBetOnYou": "The Follower is now following you", + "CultistCharmedPlayer": "You successfully charmed a player", + "CharmedByCultist": "You have been charmed by the Cultist", + "CultistInvalidTarget": "Target cannot be charmed", + "KillBaitNotify": "You'll self-report in {0}s", + "InfectiousInvalidTarget": "Target cannot be infected", + "BittenByInfectious": "The Infectious infected you!", + "InfectiousBittenPlayer": "You successfully infected a player", + "GuessNotAllowed": "Sorry, your role does not have access to guessing.", + "GuessOnbound": "This player has the Onbound add-on, so your guess on them was canceled.", + "GuessSpecter": "You can't guess a Specter. That allows them to win!", + "PacifistOnGuard": "Ability used, {0} uses remain", + "PacifistSkillNotify": "Pacifist reset your kill cooldown", + "BeRecruitedByJackal": "The Jackal has recruited you", + "YinYangerAlreadyMarked": "{0} is already in a state of calm, endowed by a fellow YinYanger", + "CoronerTrackRecorded": "Track recorded", + "CoronerNoTrack": "Nothing to track", + "CoronerIsTrackingYou": "The Coroner is tracking you!", + "CoronerReportButtonText": "Track", + "MerchantAddonDelivered": "Add-on sold", + "MerchantAddonSell": "The Merchant sold you a new Add-on", + "MerchantAddonSellFail": "Could not sell an Add-on", + "BribedByMerchant": "The Merchant bribed you. You can't kill him", + "BribedByMerchant2": "You cannot guess the Merchant after he bribed you.", + "MerchantKillAttemptBribed": "An attempted killing was averted by bribery", + "TrapTrapsterBody": "Trap Trapster's body", + "TrapConsecutiveBodies": "Trap consecutive bodies", + "HauntedByEvilSpirit": "Haunted by an Evil Spirit", + "MonarchKnightCooldown": "Knight Cooldown", + "MonarchKnightMax": "Maximum Knights", + "HideAdditionalVotesForKnighted": "Hide additional vote for Knighted players", + "MonarchKnightedPlayer": "You successfully knighted a player!", + "KnightedByMonarch": "A Monarch has knighted you!", + "MonarchInvalidTarget": "Target cannot be knighted", + "GhostTransformTitle": "Your Role Has Transformed!", + "SpiritcallerNoticeTitle": "YOU TURNED INTO AN EVIL SPIRIT ", + "SpiritcallerNoticeMessage": "The Spiritcaller has killed you and turned you into an Evil Spirit. Your task now is to help the Spiritcaller to victory by using your spook button to hinder other players or to protect the Spiritcaller. Use /m for more information.", + "OverseerRevealCooldown": "Reveal Cooldown", + "OverseerRevealTime": "Reveal Time", + "OverseerVision": "Overseer Vision", + "MerchantMaxSell": "Max number of Add-ons to sell", + "MerchantMoneyPerSell": "Amount of money earned for selling an Add-on", + "MerchantMoneyRequiredToBribe": "Amount of money required to bribe a killer", + "MerchantNotifyBribery": "Inform Merchant when a killer gets bribed", + "MerchantTargetCrew": "Can sell to Crewmates", + "MerchantTargetImpostor": "Can sell to Impostors", + + "MerchantTargetNeutral": "Can sell to Neutrals", + "MerchantSellHelpful": "Can sell Helpful Add-ons", + "MerchantSellHarmful": "Can sell Harmful Add-ons", + "MerchantSellMixed": "Can sell Mixed Add-ons", + "MerchantSellExperimental": "Can sell experimental Add-ons", + "MerchantSellHarmfulToEvil": "Can sell Harmful Add-ons only to Evil", + "MerchantSellHelpfulToCrew": "Can sell Helpful Add-ons only to Crew", + "MerchantSellOnlyEnabledAddons": "Can sell only enabled Add-ons", + + "SpiritcallerSpiritMax": "Maximum number of Evil Spirits", + "SpiritcallerSpiritAbilityCooldown": "Evil Spirit ability cooldown", + "SpiritcallerFreezeTime": "Evil Spirit ability freeze time", + "SpiritcallerProtectTime": "Evil Spirit ability protect time", + "SpiritcallerCauseVision": "Evil Spirit ability caused vision", + "SpiritcallerCauseVisionTime": "Evil Spirit ability caused vision time", + "Message.SetToSeconds": "Set to [{0}] seconds.", + "Message.MessageWaitHelp": "Specify the first argument in seconds.", + "Message.TemplateNotFoundHost": "No templates.txt matching {0} were found", + "Message.TemplateNotFoundClient": "The Host doesn't have a template called {0}", + "Message.SyncButtonLeft": "There are {0} more emergency buttons left", + "Message.Executed": "{0} was executed", + "Message.HideGameSettings": "The host has hidden the game settings.", + "Message.NowOverrideText": "Please enter the root folder of the game.\\Language\\English.dat. Change this text in the dat file \nIf you don't need this feature or want to display regular /n messages. \nPlease disable [Enable only custom /n messages in the settings.]", + "Message.NoDescription": "No description", + "Message.KickedByDenyName": "{0} was kicked because its name matched {1}", + "Message.BannedByBanList": "{0} was banned because they were banned in the past.", + "Message.BannedByEACList": "{0} has been banned because he is in the EAC list of Banned people.", + "Message.DumpfileSaved": "The log file was successfully saved to the desktop, filename: {0}", + "Message.DumpcmdUsed": "{0} used /dump command.", + "Message.KickedByInvalidFriendCode": "{0} was kicked because their friend code is invalid.", + "Message.TempBannedByInvalidFriendCode": "{0} was temporarily banned because their friend code is invalid.", + "Message.AddedPlayerToBanList": "Added {0} to the ban list", + "Message.KickWhoSayStart": "{0} has been kicked by the system. \nThe lobby host doesn't want to see messages where the player asks to start", + "Message.WarnWhoSayStart": "{0} has been warned: {1} times \nThe lobby host doesn't want to see messages where the player asks to start", + "Message.KickStartAfterWarn": "{0} has received {1} warnings, he will be kicked. \nThe lobby host doesn't want to see messages where the player asks to start", + "Message.WarnWhoSayBanWord": "{0}, stop sending banned words!", + "Message.WarnWhoSayBanWordTimes": "{0} has been warned: {1} times \nif you continue you will be kicked", + "Message.KickWhoSayBanWordAfterWarn": "[{0}] received {1} warnings.\nHe was expelled for forbidden words", + "Message.KickedByEAC": "[{0}]Kicked by EAC, reason:{1}", + "Message.BannedByEAC": "[{0}]Banned by EAC, reason:{1}", + "Message.NoticeByEAC": "[{0}]Detected:{1}", + "Message.TempBannedByEAC": "[{0}]Temporary Banned by EAC, reason:{1}", + "Message.TempBannedForSpamQuitting": "{0} was temporary banned because of spamming quits", + "Message.KickedByWhiteList": "{0} kicked because their friendcode was not found in WhiteList.txt", + "Message.SetLevel": "Your game level is set to: {0}", + "Message.SetColor": "Your color is set to: {0}", + "Message.SetName": "Your name is set to: {0}", + "Message.AllowLevelRange": "The game level can be set in the range: 0-100", + "Message.AllowNameLength": "Nickname can be set length: 1-10", + "Message.OnlyCanUseInLobby": "ERROR\n\nSorry, this command can only be used in the lobby", + "Message.CanNotUseInLobby": "ERROR\n\nSorry, this command cannot be used in the lobby", + "Message.CanNotUseByHost": "ERROR\n\nSorry, Host can't use this command", + "Message.TryFixName": "An attempt was made to fix hidden message content due to roles", + "Message.CanNotFindRoleThePlayerEnter": "Could not find the role you searching\nUse command /r to show role list", + "Message.PlayerQuitForever": "{0} decided to leave voluntarily \nSorry for the bad gaming experience \nI really worked hard to make progress", + "Message.MadmateSelfVoteModeNotify": "Please note: The current Madness generation mode is [{0}]\n Voting for yourself means you want to be Madmate. If you meet the conditions to become Madmate and there are still spaces left, you will immediately become Madmate", + "Message.HostLeftGameInGame": "★Warning★ Host left the game, and the game wouldn't start normally next time. Please exit the lobby or wait until the new Host opens a lobby.", + "Message.HostLeftGameInLobby": "★Warning★ Host left the game, and the game wouldn't start normally next time. If the new Host has TOHE, you need to re-enter the lobby to play normally.", + "Message.HostLeftGameNewHostIsMod": "★Warning★ Original Host left the game and {0} become the new Host! \nThe room is still modded, start a game and end it immediately to reset the lobby!", + "Message.HostLeftGameNewHostIsNotMod": "★Warning★ Original Host left the game and {0} become the new Host. \nBut it's not modded. Please exit the lobby or wait until the new Host opens a lobby.", + "Message.LobbyShared": "The lobby has successfully been shared!", + "Message.LobbyShareFailed": "TOHE-Chan does not seem to be online (failed to share lobby)", + "Message.YTPlanDisabled": "ERROR\n\nPlease enable {0} in the Settings", + "Message.YTPlanSelected": "In the next game, your role will be {0}", + "Message.YTPlanSelectFailed": "You cannot be assigned as {0}.\nIt may be because you don't have this role enabled, or this role does not support being assigned.", + "Message.YTPlanCanNotFindRoleThePlayerEnter": "Could not find the role you searching\nUse command /r to show role list", + "Message.YTPlanNotice": "Note: The [YouTuber Plan] is enabled in this lobby, which means the Host can specify their role in the next game to make it easier to get content. If the Host abuses this feature, please exit the game or report it.\nCurrent Creator Credentials:", + "Message.OnlyCanBeUsedByHost": "ERROR\n\nThis command may only be used by the host.", + "Message.MaxPlayers": "Maximum players set to ", "Message.MaxPlayersFailByRegion": "Could not set max players: Vanilla regions support a maximum of 15 players.", - "Message.GhostRoleInfo": "Ghost Role Info\nHiya! A little about ghost roles...\n\nGhost roles drastically impact the game, so it's not recommended for smaller lobbies if you're unfamiliar. If not explicitly stated otherwise in the description, the Guard button is their ability button ;)\n\nSpawning:\nGhost-roles only spawn after death; the first x people from (team) to die get them.\n\nPS: If your previous role didn't have tasks(e.g., sheriff), your tasks as a ghost-role aren't needed for task-win", - "ApocalypseInfoTitle": "Neutral Apocalypse Info:", - "Message.ApocalypseInfo": "Every role of the <#ff174f>Apocalypse Team has their own objective to carry out in order to transform.\n<#2B0804>Transformed <#ff174f>Apocalypse members have a drastic change on the game and are immortal (except for being voted), but everyone will be notified that they have transformed.\n\nRoles: <#e5f6b4>Plaguebearer, <#A675A1>Soul Collector, <#bf9f7a>Baker, <#cc0044>Berserker\nTransformed: <#343136>Pestilence, <#644661>Death, <#83461c>Famine, <#2B0804>War\n\nApocalypse members can see eachother's roles and ability icons.\nLike Neutral Killers, Apocalypse members keep the game going as well, have fun!", - "Message.MeCommandInfo": "Hi [{0}] {1} !\n\nfriend-code Hash-Puid Type 
{2} {3} {4}

IsDev HasUp /color-Bypass
{5} {6} {7}

", - "Message.MeCommandTargetInfo": "Selected [{0}] Player {1} ,\n\nTheir friend code is {2}.\n\nTheir hash puid is {3}.\n\nTheir TOHE Discord role is {4}.\n\n", - "Message.MeCommandInvalidID": "The ID you entered seems incorrect. \nPlease use /id to get the player ID of online players", - "Message.MeCommandNoPermission": "You are not allowed to use /me command for others", - - "PollTitle": "〖 Poll 〗", - "PollResultTitle": "Poll Results", - "Poll.Result": "And... The winner was {0} with {1} votes!\n\nRunner ups:", - "Poll.Tied": "Uh oh, The vote was tied between {0}, all having {1} votes.", - "Poll.MissingPlayers": "You can't start a poll with yourself dummy ;3", - - "Poll.Begin": "You may vote using /pv {answer}, ps: a number also works.", - "Poll.TimeInfo": "The results will be final in 2 minutes", - "Poll.OnlyInLobby": "<#ab4f75>Sorry, this command may only be used in lobby", - - "Poll.Inactive": "There isn't any active poll currently.", - "Poll.AlreadyVoted": "You already cast your vote, so it won't be counted.", - - "Poll.VotingInfo": "Use /pv {answer} to vote, answer can be a character or a number.", - "Poll.YouVoted": "You have voted for {0}, which has now {1} votes.", - "PollUsage": "To create a poll type \n/poll {Question}? {Answer A} {Answer B} \n{Answer C (Optional)} {Answer D (Optional)} {Answer E (Optional)}\nIt is important you end the question with a ? \n\nUse /poll Replay to replay the latest poll", - "Replay": "Replay", - - "EnableGadientTags": "Enable Gradient Tags (can cause disconnect issues)", - "Warning.GradientTags": "Warning:\n\nHost has enabled gradient tags. This feature is not recommended to use because it can cause disconnect issues", - "WarningTitle": "Warning!", - "Warning.BrokenVentsInDleksSendInGame": "Warning! The vents on this map are broken", - "Warning.BrokenVentsInDleksMessage": "On the «dlekS ehT» map, the vents are broken, they cannot be fixed in host-only mods, this is a vanilla bug, so any roles using vent as an ability will not spawns on this map", - - "Warning.NoGameEndIsEnabled": "Warning: {0} is enabled!", - - "AntiBlackoutProtectionTitle": "Anti Blackout", - "Warning.AntiBlackoutProtectionMsg": "Warning:\n\rBlack screen protection has been activated, due to the low number of alive Impostors, Crewmates and Neutral Killers\nThe voting screen will show as a tied vote (only affects the visual, not the results voting)\nModded players will see voting screen normally", - "Warning.ShowAntiBlackExiledPlayer": "Last meeting triggered Black Screen Prevention!\nFollowing is the information of the player exiled in the last meeting.\n", - "DisableAntiBlackoutProtects": "Disable AntiBlackout Protects (Recommended for testing)", - - - - "Warning.InvalidRpc": "Kicked {0} because an invalid RPC was received.\nPlease check that no mods other than TOHE are installed.", - "Warning.NoModHost": "TOHE is not installed on the host", - "Warning.MismatchedVersion": "{0} has a different version of {1}", - "Warning.AutoExitAtMismatchedVersion": "The host has no or a different version of {0}\nYou will be kicked in {1}", - "Warning.CanNotUseBepInExConsole": "The use of the console is prohibited\nso your console has been off", - "Error.MeetingException": "Error: {0}\r\nPlease use SHIFT+M+ENTER to end the meeting", - "Error.InvalidRoleAssignment": "Error: Invalid role found for a player during role assignment({0})", - "Error.InvalidColor": "Error: Only default colors are available", - "Error.InvalidColorPreventStart": "Other players are not allowed to use other colors. Otherwise, it will result in a serious error", - "ErrorLevel1": "Bugs may occur.", - "ErrorLevel2": "This may be a bug.", - "ErrorLevel3": "This version shouldn't have been released.", - "TerminateCommand": "Abort Command", - "ERR-000-000-0": "No Error", - "ERR-000-900-0": "Test Error Lv.0", - "ERR-000-910-1": "Test Error Lv.1", - "ERR-000-920-2": "Test Error Lv.2", - "ERR-000-930-3": "Test Error Lv.3", - "ERR-000-804-1": "Sorry, TOHE temporarily not support the Vanilla HnS, so mod unloaded", - "ERR-001-000-3": "Main dictionary has duplicated keys.", - "ERR-002-000-1": "Unsupported Among Us version. Please update Among Us", - "DefaultSystemMessageTitle": "SYSTEM MESSAGE", - "MessageFromTheHost": "HOST MESSAGE", - "MessageFromEAC": "EAC", - "NotifyGameEnding": "This game is ending.\nIf you find yourself stuck in game,\npls just quit and rejoin the room.", - "DetectiveNoticeTitle": "INVESTIGATION", - "SleuthNoticeTitle": "SLEUTH", - "GuessKillTitle": "GUESSING INFO", - "CelebrityNewsTitle": "CELEBRITY", - "CyberNewsTitle": "CYBER", - "GodAliveTitle": "GOD ", - "WorkaholicAliveTitle": "WORKAHOLIC", - "BaitAliveTitle": "BAIT", - "MessageFromKPD": "KARPED1EM ", - "MessageFromSponsor": "SPONSOR MESSAGE ", - "MessageFromDev": "DEVELOPER MESSAGE ", - "FortuneTellerCheckMsgTitle": "FORTUNE TELLER", - "MimicMsgTitle": "MIMIC", - "MorticianCheckTitle": "CORPSE EXAMINATION", - "NemesisRevengeTitle": "NEMESIS", - "RetributionistRevengeTitle": "RETRIBUTIONIST", - "TabVanilla.GameSettings": "Game Settings", - "TabGroup.SystemSettings": "System Settings", - "TabGroup.ModSettings": "Mod Settings", - "TabGroup.ModifierSettings": "Game Modifiers", - "TabGroup.CrewmateRoles": "Crewmate Roles", - "TabGroup.NeutralRoles": "Neutral Roles", - "TabGroup.ImpostorRoles": "Impostor Roles", - "TabGroup.Addons": "Add-Ons", - "TabMenuDescription_General": "Here you can configure the functions that are in the mod", - "TabMenuDescription_Roles&AddOns": "Here you can add, remove and change the settings of all roles or add-ons in the mod", - "Experimental.Roles": "★ Experimental Roles (NOTICE: Use with caution, as these require testing)", - "ActiveRolesList": "Active Roles List", - "ForExample": "Example Use", - "ImpCanBeGuesser": "Impostors can become Guesser", - "CrewCanBeGuesser": "Crewmates can become Guesser", - "NeutralCanBeGuesser": "Neutrals can become Guesser", - "CrewCanBeMundane": "Crewmates can become Mundane", - "NeutralCanBeMundane": "Neutrals can become Mundane", - "GuessedAsMundane": "You're Mundane.\nYou can't guess until you finish all the tasks", - "ObliviousBaitImmune": "Immune to Bait", - "ImpCanBeInLove": "Impostors can be in love", - "CrewCanBeInLove": "Crewmates can be in love", - "NeutralCanBeInLove": "Neutrals can be in love", - "updateButton": "Update", - "updatePleaseWait": "Please Wait...", - "updateManually": "Update failed.\nPlease try again or Update Manually.", - "updateInProgress": "Updating...", - "deletingFiles": "Deleting update files...", - "updateRestart": "Update Finished!\nPlease restart the game.", - "CanNotJoinPublicRoomNoLatest": "You can't join public rooms without the latest version.\nPlease Update.", - "ModBrokenMessage": "The MOD file is damaged.\nPlease reinstall.", - "UnsupportedVersion": "Unsupported Among Us version.\nPlease Update Among Us", - "DisabledByProgram": "The program has disabled public rooms", - "EnterVentToWin": "Enter Vent to Win!!", - "EatenByPelican": "You're swallowed, waiting for the Pelican to die or a meeting", - "FireworkerPutPhase": "{0} Fireworker Left", - "FireworkerWaitPhase": "Wait for it...", - "FireworkerReadyFirePhase": "Fire!", - "EnterVentWinCountDown": "Enter vent within {0} seconds to win!", - "On": "ON", - "Off": "OFF", - "ColoredOn": "ON", - "ColoredOff": "OFF", - "CurrentActiveSettingsHelp": "Current Active Settings Help", - "WitchCurrentMode": "Current Mode", - "WitchModeKill": "Kill", - "WitchModeSpell": "Spell", - "HexMasterModeHex": "Hex", - "HexMasterModeKill": "Kill", - "PoisonerPoisonButtonText": "Poison", - "WitchModeDouble": "Double Click = Kill, Single Click = Spell", - "HexMasterModeDouble": "Double Click = Kill, Single Click = Hex", - "BountyCurrentTarget": "Current Target", - "Roles": "Roles", - "Settings": "Settings", - "Addons": "Add-Ons", - "LastResult": "★ Match Results", - "LastEndReason": "★ End Reason", - "KillLog": "Kill Log", - "Maximum": "Max", - "RoleRate": "ON", - "RoleOn": "ALWAYS", - "RoleOff": "OFF", - "Chance0": "0%", - "Chance5": "5%", - "Chance10": "10%", - "Chance15": "15%", - "Chance20": "20%", - "Chance25": "25%", - "Chance30": "30%", - "Chance35": "35%", - "Chance40": "40%", - "Chance45": "45%", - "Chance50": "50%", - "Chance55": "55%", - "Chance60": "60%", - "Chance65": "65%", - "Chance70": "70%", - "Chance75": "75%", - "Chance80": "80%", - "Chance85": "85%", - "Chance90": "90%", - "Chance95": "95%", - "Chance100": "100%", - "SearchNoResult": "No Results.", - "Preset": "Preset", - "Preset_1": "Preset 1", - "Preset_2": "Preset 2", - "Preset_3": "Preset 3", - "Preset_4": "Preset 4", - "Preset_5": "Preset 5", - "Standard": "Standard", - "HidenSeekTOHE": "Hide And Seek", - "GameMode": "Game Mode", - "PressTabToNextPage": "Press Tab or Number for Next Page...", - "RoleSummaryText": "Role Summary:", - "doOverride": "Override %role%'s Tasks", - "assignCommonTasks": "%role% has Common Tasks", - "roleLongTasksNum": "Amount of Long Tasks for %role%", - "roleShortTasksNum": "Amount of Short Tasks for %role%", - "Format.Players": "{0}", - "Format.Seconds": "{0}s", - "Format.Percent": "{0}%", - "Format.Times": "{0}", - "Format.Multiplier": "{0}x", - "Format.Votes": "{0}", - "Format.Pieces": "{0}", - "Format.Health": "{0}", - "Format.Level": "{0}", - "KillButtonText": "Kill", - "ReportButtonText": "Report", - "VentButtonText": "Vent", - "SabotageButtonText": "Sabotage", - "SniperSnipeButtonText": "Snipe", - "FireworkerExplosionButtonText": "Detonate", - "FireworkerInstallAtionButtonText": "Install", - "MercenarySuicideButtonText": "Suicide Timer", - "WarlockCurseButtonText": "Curse", - "NinjaShapeshiftText": "Kill", - "NinjaMarkButtonText": "Mark", - "WitchSpellButtonText": "Spell", - "VampireBiteButtonText": "Bite", - "MinerTeleButtonText": "Warp", - "ArsonistDouseButtonText": "Douse", - "PuppeteerOperateButtonText": "Manipulate", - "WarlockShapeshiftButtonText": "Spell", - "BountyHunterChangeButtonText": "Swap", - "EvilTrackerChangeButtonText": "Track", + "Message.GhostRoleInfo": "Ghost Role Info\nHiya! A little about ghost roles...\n\nGhost roles drastically impact the game, so it's not recommended for smaller lobbies if you're unfamiliar. If not explicitly stated otherwise in the description, the Guard button is their ability button ;)\n\nSpawning:\nGhost-roles only spawn after death; the first x people from (team) to die get them.\n\nPS: If your previous role didn't have tasks(e.g., sheriff), your tasks as a ghost-role aren't needed for task-win", + "ApocalypseInfoTitle": "Neutral Apocalypse Info:", + "Message.ApocalypseInfo": "Every role of the <#ff174f>Apocalypse Team has their own objective to carry out in order to transform.\n<#2B0804>Transformed <#ff174f>Apocalypse members have a drastic change on the game and are immortal (except for being voted), but everyone will be notified that they have transformed.\n\nRoles: <#e5f6b4>Plaguebearer, <#A675A1>Soul Collector, <#bf9f7a>Baker, <#cc0044>Berserker\nTransformed: <#343136>Pestilence, <#644661>Death, <#83461c>Famine, <#2B0804>War\n\nApocalypse members can see eachother's roles and ability icons.\nLike Neutral Killers, Apocalypse members keep the game going as well, have fun!", + "Message.MeCommandInfo": "Hi [{0}] {1} !\n\nfriend-code Hash-Puid Type 
{2} {3} {4}

IsDev HasUp /color-Bypass
{5} {6} {7}

", + "Message.MeCommandTargetInfo": "Selected [{0}] Player {1} ,\n\nTheir friend code is {2}.\n\nTheir hash puid is {3}.\n\nTheir TOHE Discord role is {4}.\n\n", + "Message.MeCommandInvalidID": "The ID you entered seems incorrect. \nPlease use /id to get the player ID of online players", + "Message.MeCommandNoPermission": "You are not allowed to use /me command for others", + + "PollTitle": "〖 Poll 〗", + "PollResultTitle": "Poll Results", + "Poll.Result": "And... The winner was {0} with {1} votes!\n\nRunner ups:", + "Poll.Tied": "Uh oh, The vote was tied between {0}, all having {1} votes.", + "Poll.MissingPlayers": "You can't start a poll with yourself dummy ;3", + + "Poll.Begin": "You may vote using /pv {answer}, ps: a number also works.", + "Poll.TimeInfo": "The results will be final in 2 minutes", + "Poll.OnlyInLobby": "<#ab4f75>Sorry, this command may only be used in lobby", + + "Poll.Inactive": "There isn't any active poll currently.", + "Poll.AlreadyVoted": "You already cast your vote, so it won't be counted.", + + "Poll.VotingInfo": "Use /pv {answer} to vote, answer can be a character or a number.", + "Poll.YouVoted": "You have voted for {0}, which has now {1} votes.", + "PollUsage": "To create a poll type \n/poll {Question}? {Answer A} {Answer B} \n{Answer C (Optional)} {Answer D (Optional)} {Answer E (Optional)}\nIt is important you end the question with a ? \n\nUse /poll Replay to replay the latest poll", + "Replay": "Replay", + + "EnableGadientTags": "Enable Gradient Tags (can cause disconnect issues)", + "Warning.GradientTags": "Warning:\n\nHost has enabled gradient tags. This feature is not recommended to use because it can cause disconnect issues", + "WarningTitle": "Warning!", + "Warning.BrokenVentsInDleksSendInGame": "Warning! The vents on this map are broken", + "Warning.BrokenVentsInDleksMessage": "On the «dlekS ehT» map, the vents are broken, they cannot be fixed in host-only mods, this is a vanilla bug, so any roles using vent as an ability will not spawns on this map", + + "Warning.NoGameEndIsEnabled": "Warning: {0} is enabled!", + + "AntiBlackoutProtectionTitle": "Anti Blackout", + "Warning.AntiBlackoutProtectionMsg": "Warning:\n\rBlack screen protection has been activated, due to the low number of alive Impostors, Crewmates and Neutral Killers\nThe voting screen will show as a tied vote (only affects the visual, not the results voting)\nModded players will see voting screen normally", + "Warning.ShowAntiBlackExiledPlayer": "Last meeting triggered Black Screen Prevention!\nFollowing is the information of the player exiled in the last meeting.\n", + "DisableAntiBlackoutProtects": "Disable AntiBlackout Protects (Recommended for testing)", + + + + "Warning.InvalidRpc": "Kicked {0} because an invalid RPC was received.\nPlease check that no mods other than TOHE are installed.", + "Warning.NoModHost": "TOHE is not installed on the host", + "Warning.MismatchedVersion": "{0} has a different version of {1}", + "Warning.AutoExitAtMismatchedVersion": "The host has no or a different version of {0}\nYou will be kicked in {1}", + "Warning.CanNotUseBepInExConsole": "The use of the console is prohibited\nso your console has been off", + "Error.MeetingException": "Error: {0}\r\nPlease use SHIFT+M+ENTER to end the meeting", + "Error.InvalidRoleAssignment": "Error: Invalid role found for a player during role assignment({0})", + "Error.InvalidColor": "Error: Only default colors are available", + "Error.InvalidColorPreventStart": "Other players are not allowed to use other colors. Otherwise, it will result in a serious error", + "ErrorLevel1": "Bugs may occur.", + "ErrorLevel2": "This may be a bug.", + "ErrorLevel3": "This version shouldn't have been released.", + "TerminateCommand": "Abort Command", + "ERR-000-000-0": "No Error", + "ERR-000-900-0": "Test Error Lv.0", + "ERR-000-910-1": "Test Error Lv.1", + "ERR-000-920-2": "Test Error Lv.2", + "ERR-000-930-3": "Test Error Lv.3", + "ERR-000-804-1": "Sorry, TOHE temporarily not support the Vanilla HnS, so mod unloaded", + "ERR-001-000-3": "Main dictionary has duplicated keys.", + "ERR-002-000-1": "Unsupported Among Us version. Please update Among Us", + "DefaultSystemMessageTitle": "SYSTEM MESSAGE", + "MessageFromTheHost": "HOST MESSAGE", + "MessageFromEAC": "EAC", + "NotifyGameEnding": "This game is ending.\nIf you find yourself stuck in game,\npls just quit and rejoin the room.", + "DetectiveNoticeTitle": "INVESTIGATION", + "SleuthNoticeTitle": "SLEUTH", + "GuessKillTitle": "GUESSING INFO", + "CelebrityNewsTitle": "CELEBRITY", + "CyberNewsTitle": "CYBER", + "GodAliveTitle": "GOD ", + "WorkaholicAliveTitle": "WORKAHOLIC", + "BaitAliveTitle": "BAIT", + "MessageFromKPD": "KARPED1EM ", + "MessageFromSponsor": "SPONSOR MESSAGE ", + "MessageFromDev": "DEVELOPER MESSAGE ", + "FortuneTellerCheckMsgTitle": "FORTUNE TELLER", + "MimicMsgTitle": "MIMIC", + "MorticianCheckTitle": "CORPSE EXAMINATION", + "NemesisRevengeTitle": "NEMESIS", + "RetributionistRevengeTitle": "RETRIBUTIONIST", + "TabVanilla.GameSettings": "Game Settings", + "TabGroup.SystemSettings": "System Settings", + "TabGroup.ModSettings": "Mod Settings", + "TabGroup.ModifierSettings": "Game Modifiers", + "TabGroup.CrewmateRoles": "Crewmate Roles", + "TabGroup.NeutralRoles": "Neutral Roles", + "TabGroup.ImpostorRoles": "Impostor Roles", + "TabGroup.Addons": "Add-Ons", + "TabMenuDescription_General": "Here you can configure the functions that are in the mod", + "TabMenuDescription_Roles&AddOns": "Here you can add, remove and change the settings of all roles or add-ons in the mod", + "Experimental.Roles": "★ Experimental Roles (NOTICE: Use with caution, as these require testing)", + "ActiveRolesList": "Active Roles List", + "ForExample": "Example Use", + "ImpCanBeGuesser": "Impostors can become Guesser", + "CrewCanBeGuesser": "Crewmates can become Guesser", + "NeutralCanBeGuesser": "Neutrals can become Guesser", + "CrewCanBeMundane": "Crewmates can become Mundane", + "NeutralCanBeMundane": "Neutrals can become Mundane", + "GuessedAsMundane": "You're Mundane.\nYou can't guess until you finish all the tasks", + "ObliviousBaitImmune": "Immune to Bait", + "ImpCanBeInLove": "Impostors can be in love", + "CrewCanBeInLove": "Crewmates can be in love", + "NeutralCanBeInLove": "Neutrals can be in love", + "updateButton": "Update", + "updatePleaseWait": "Please Wait...", + "updateManually": "Update failed.\nPlease try again or Update Manually.", + "updateInProgress": "Updating...", + "deletingFiles": "Deleting update files...", + "updateRestart": "Update Finished!\nPlease restart the game.", + "CanNotJoinPublicRoomNoLatest": "You can't join public rooms without the latest version.\nPlease Update.", + "ModBrokenMessage": "The MOD file is damaged.\nPlease reinstall.", + "UnsupportedVersion": "Unsupported Among Us version.\nPlease Update Among Us", + "DisabledByProgram": "The program has disabled public rooms", + "EnterVentToWin": "Enter Vent to Win!!", + "EatenByPelican": "You're swallowed, waiting for the Pelican to die or a meeting", + "FireworkerPutPhase": "{0} Fireworker Left", + "FireworkerWaitPhase": "Wait for it...", + "FireworkerReadyFirePhase": "Fire!", + "EnterVentWinCountDown": "Enter vent within {0} seconds to win!", + "On": "ON", + "Off": "OFF", + "ColoredOn": "ON", + "ColoredOff": "OFF", + "CurrentActiveSettingsHelp": "Current Active Settings Help", + "WitchCurrentMode": "Current Mode", + "WitchModeKill": "Kill", + "WitchModeSpell": "Spell", + "HexMasterModeHex": "Hex", + "HexMasterModeKill": "Kill", + "PoisonerPoisonButtonText": "Poison", + "WitchModeDouble": "Double Click = Kill, Single Click = Spell", + "HexMasterModeDouble": "Double Click = Kill, Single Click = Hex", + "BountyCurrentTarget": "Current Target", + "Roles": "Roles", + "Settings": "Settings", + "Addons": "Add-Ons", + "LastResult": "★ Match Results", + "LastEndReason": "★ End Reason", + "KillLog": "Kill Log", + "Maximum": "Max", + "RoleRate": "ON", + "RoleOn": "ALWAYS", + "RoleOff": "OFF", + "Chance0": "0%", + "Chance5": "5%", + "Chance10": "10%", + "Chance15": "15%", + "Chance20": "20%", + "Chance25": "25%", + "Chance30": "30%", + "Chance35": "35%", + "Chance40": "40%", + "Chance45": "45%", + "Chance50": "50%", + "Chance55": "55%", + "Chance60": "60%", + "Chance65": "65%", + "Chance70": "70%", + "Chance75": "75%", + "Chance80": "80%", + "Chance85": "85%", + "Chance90": "90%", + "Chance95": "95%", + "Chance100": "100%", + "SearchNoResult": "No Results.", + "Preset": "Preset", + "Preset_1": "Preset 1", + "Preset_2": "Preset 2", + "Preset_3": "Preset 3", + "Preset_4": "Preset 4", + "Preset_5": "Preset 5", + "Standard": "Standard", + "HidenSeekTOHE": "Hide And Seek", + "GameMode": "Game Mode", + "PressTabToNextPage": "Press Tab or Number for Next Page...", + "RoleSummaryText": "Role Summary:", + "doOverride": "Override %role%'s Tasks", + "assignCommonTasks": "%role% has Common Tasks", + "roleLongTasksNum": "Amount of Long Tasks for %role%", + "roleShortTasksNum": "Amount of Short Tasks for %role%", + "Format.Players": "{0}", + "Format.Seconds": "{0}s", + "Format.Percent": "{0}%", + "Format.Times": "{0}", + "Format.Multiplier": "{0}x", + "Format.Votes": "{0}", + "Format.Pieces": "{0}", + "Format.Health": "{0}", + "Format.Level": "{0}", + "KillButtonText": "Kill", + "ReportButtonText": "Report", + "VentButtonText": "Vent", + "SabotageButtonText": "Sabotage", + "SniperSnipeButtonText": "Snipe", + "FireworkerExplosionButtonText": "Detonate", + "FireworkerInstallAtionButtonText": "Install", + "MercenarySuicideButtonText": "Suicide Timer", + "WarlockCurseButtonText": "Curse", + "NinjaShapeshiftText": "Kill", + "NinjaMarkButtonText": "Mark", + "WitchSpellButtonText": "Spell", + "VampireBiteButtonText": "Bite", + "MinerTeleButtonText": "Warp", + "ArsonistDouseButtonText": "Douse", + "PuppeteerOperateButtonText": "Manipulate", + "WarlockShapeshiftButtonText": "Spell", + "BountyHunterChangeButtonText": "Swap", + "EvilTrackerChangeButtonText": "Track", "RiftMakerButtonText": "Create Rift", "AbyssbringerButtonText": "Black Hole", "PitfallButtonText": "Set Trap", - "InnocentButtonText": "Frame", - "PelicanButtonText": "Eat", - "DeceiverButtonText": "Cheat", - "PursuerButtonText": "Trick", - "GangsterButtonText": "Recruit", - "RevolutionistDrawButtonText": "Win over", - "HaterButtonText": "Hatred", - "MedicalerButtonText": "Protect", - "DemonButtonText": "Attack", - "SoulCatcherButtonText": "Teleport", - "LightningButtonText": "Evaporate", - "ProvocateurButtonText": "Greet", - "ButcherButtonText": "Dismember", - "BomberShapeshiftText": "Explode", - "QuickShooterShapeshiftText": "Keep", - "CamouflagerShapeshiftTextBeforeDisguise": "Disguise", - "CamouflagerShapeshiftTextAfterDisguise": "Duration", - "AnonymousShapeshiftText": "Hack", - "DefaultShapeshiftText": "Shift", - "CleanerReportButtonText": "Clean", - "SwooperVentButtonText": "Swoop", - "SwooperRevertVentButtonText": "Expose", - "WraithVentButtonText": "Vanish", - "WraithRevertVentButtonText": "Expose", - "VectorVentButtonText": "Hop", - "VeteranVentButtonText": "Alert", - "GrenadierVentButtonText": "Flash", - "MayorVentButtonText": "Button", - "SheriffKillButtonText": "Shoot", - "UndertakerButtonText": "Mark", - "ArsonistVentButtonText": "Ignite", - "RevolutionistVentButtonText": "Revolution", - "FollowerKillButtonText": "Follow", - "PacifistVentButtonText": "Reset", - "CultistKillButtonText": "Charm", - "InfectiousKillButtonText": "Infect", - "MonarchKillButtonText": "Knight", - "OverseerKillButtonText": "Reveal", - "DisabledBySettings": "Disabled by Settings", - "Disabled": "Disabled", - "FailToTrack": "Failed To Track", - "KillCount": "Kills: {0}", - "CantUse.lastroles": "Unable to use /lastroles during a game.", - "CantUse.killlog": "Unable to use /killlog during a game.", - "CantUse.lastresult": "Unable to use /lastresult during a game.", - "IllegalColor": "Please enter the correct color", - "DisableUseCommand": "The Host's settings do not allow this command to be used.", - "SureUse.quit": "We will kick you and block you from entering this lobby again. This setting is irreversible. If you really want it, please send the command /qt {0}", - "PlayerIdList": "List of player IDs: ", - "CancelStartCountDown": "The starting countdown was canceled", - "RestTOHESetting": "TOHE settings have been restored to default", - "FPSSetTo": "FPS Set To: {0}", - "HostKillSelfByCommand": "The lobby Host decided to commit suicide", - "SyncCustomSettingsRPC": "Synchronized RPC", - "Mode": "Mode", - "Target": "Target", - "PlayerInfo": "Player Info", - "NoInfoExists": "No Info Exists", - "PlayerLeftByAU-Anticheat": "{0} was banned by the Innersloth anti-cheat.", - "PlayerLeftByError": "Game will auto-end to prevent black screens.", - "MsgKickOtherPlatformPlayer": "{0} was kicked due to playing on {1}", - "KickBecauseLowLevel": "{0} was kicked because their level was too low", - "TempBannedBecauseLowLevel": "{0} was temporarily banned because their level was too low", - "KickBecauseDiffrentVersionOrMod": "{0} was kicked because they had a different version of the mod", - - "FFADisplayScore": "Ranking: {0} Score: {1}", - "FFATimeRemain": "Time Remaining: {0} second(s)", - - "GameOver": "Game Over", - "TOHEOptions": "TOHE Options", - "Cancel": "Cancel", - "Back": "Back", - "Yes": "Yes", - "No": "No", - - "AntiBlackOutLoggerSendInGame": "Because of an unknown error, the game will end to prevent a black screen.", - "AntiBlackOutNotifyInLobby": "An error occurred to prevent a black screen. Do a «/dump» and send the logs to the discord server TOHE in «bug-reports» and we will try to fix it.", - - "EndWhenPlayerBug": "End the game when a modded player gets a critical error (While loading)", - "AntiBlackOutRequestHostToForceEnd": "You were the reason for the black screen. The game will end", - "AntiBlackOutHostRejectForceEnd": "You were the reason for the black screen, and the host is not going to end the game\nYou will be disconnected soon", - - "RpcAntiBlackOutNotifyInLobby": "Because of {0}, an unknown error occurred. To prevent a black screen, turn off [{1}] in settings.", - "RpcAntiBlackOutEndGame": "Because of {0}, an unknown error occurred, the game will end to prevent a black screen.", - "RpcAntiBlackOutIgnored": "Because of {0}, an unknown error occurred, but the game will continue without that player due to host settings.", - "RpcAntiBlackOutKicked": "{0} was kicked due to having a blackout error on its side.", - - "NextPage": "Next Page", - "PreviousPage": "Previous Page", - "EAC.CheatDetected.EAC": "Cheating usage detected (Using AUM)", - "PressF1ShowMainRoleDes": "Press F1: Show Role Description", - "PressF2ShowAddRoleDes": "Press F2: Show Add-on Description", - "PressF3ShowRoleSettings": "Press F3: Show Role Settings", - "PressF4ShowAddOnsSettings": "Press F4: Show Add-ons Settings", - "FakeTask": "Fake Tasks:", - "PVP.ATK": "Attack", - "PVP.DF": "Defend", - "PVP.RCO": "Recover", - "SettingsAreLoading": "Loading\nsettings...", - "EAC.CheatDetected.HighLevel": "Warning: EAC detected High Level of cheats.", - "EAC.CheatDetected.LowLevel": "Warning: EAC detected Low Level of cheats. One of the players is hacking.", - "ExiledJester": "You're all fools!\n{0} the {1} laughing out loud tricked you into ejecting them.\nGG!", - "JesterMeetingLoose": "\r\nBut it cannot win until meeting number {0}", - "ExiledExeTarget": "{0} was the {1}.\nBut they were also the Executioner's target!\nGG!", - "ExiledInnocentTargetAddBelow": "\nLooking back at the Innocent counts the money in their hands", - "ExiledInnocentTargetInOneLine": "{0} was the {1}.\nBut looking back, there's the Innocent counting the money in their hands....\nGG!", - "ExiledDeath": "{0} was {1}!\nThe Crew has been saved from Armageddon!", - "ExiledNotDeath": "{0} was the {1}.\nBut they were not Death...\nDeath has claimed the souls of the Crew!", - "IsGood": "{0} was a good guy", - "BelongTo": "{0} belongs to {1}", - "PlayerIsRole": "{0} was The {1}", - "PlayerExiled": "{0} was ejected", - "NoImpRemain": "0 Impostors remain", - "OneImpRemain": "1 Impostor remains", - "TwoImpRemain": "2 Impostors remain", - "ThreeImpRemain": "3 Impostors remain", - "ImpRemain": "{0} Impostors remaining", - "NeutralRemain": "\n{0} Neutral Killers remain", - "OneNeutralRemain": "\n{0} Neutral Killer remains", - "ApocRemain": "\n{0} Neutral Apocalypse remains", - "GameOverReason.HumansByVote": "All Impostors and Neutral Killers were ejected or killed", - "GameOverReason.HumansByTask": "The Crewmates completed all tasks", - "GameOverReason.HumansDisconnect": "Crewmates disconnected", - "GameOverReason.ImpostorByVote": "The Crewmates were ejected", - "GameOverReason.ImpostorByKill": "The Impostors killed everyone", - "GameOverReason.ImpostorBySabotage": "Crewmates failed to fix a critical sabotage", - "GameOverReason.ImpostorDisconnect": "Impostors disconnected", - "FortuneTellerCheck.TaskDone": "[{0}]Role -[{1}]", - "DevAndSpnTitle": "TOHE family", - "FortuneTellerCheck.Null": "{0} is a role that is not listed.\nThis message should not appear normally.", - "FortuneTellerCheck.Result": "{0} is either one of the following roles:\n{1}", - "SunnyboyChance": "Sunnyboy Chance", - "BardChance": "Bard Chance", - "SkeldChance": "Chance that the map is The Skeld", - "MiraChance": "Chance that the map is MIRA HQ", - "PolusChance": "Chance that the map is Polus", - "DleksChance": "Chance that the map is dlekS ehT", - "AirshipChance": "Chance that the map is Airship", - "FungleChance": "Chance that the map is The Fungle", - "UseMoreRandomMapSelection": "Use a more random map selection", - "CamouflageMode.Default": "Default", - "CamouflageMode.Host": "Host", - "CamouflageMode.Random": "Random", - "CamouflageMode.OnlyRandomColor": "Only Random Color", - "CamouflageMode.Karpe": "KARPED1EM", - "CamouflageMode.Lauryn": "Lauryn", - "CamouflageMode.Moe": "Moe", - "CamouflageMode.Pyro": "Pyro", - "CamouflageMode.ryuk": "ryuk", - "CamouflageMode.Gurge44": "Gurge44", - "CamouflageMode.TommyXL": "TommyXL", - "CamouflageMode.Sarha": "Sarha", - "DeathCmd.HeyPlayer": "Hey ", - "DeathCmd.YouAreRole": ", looks like you're the ", - "DeathCmd.NotDead": "You haven't died yet, this can only be used after you die\n\nCheck back again after you've been brutally murdered", - "DeathCmd.KillerName": "You were killed by ", - "DeathCmd.KillerRole": "Their role is ", - "DeathCmd.DeathReason": "Your cause of death was ", - "DeathCmd.YourName": "You are ", - "DeathCmd.YourRole": "Your role is ", - "DeathCmd.Ejected": "You were ejected during a meeting", - "DeathCmd.Misfired": "You misfired.", - "DeathCmd.Shrouded": "You were shrouded by a Shroud and didn't make a kill, so you suicided.", - "DeathCmd.Lovers": "Your lover had died.", - - "RpsCommandInfo": "This Command can only be used when in the lobby or after you die.\n\ntype /rps X to play Rock Paper Scissors with the system. X can be 0 (rock), 1 (paper) or 2 (scissors). \n\nExample :- /rps 0", - "RpsDraw": "I choose {0}\n\nWow, what an intense battle of wits we just had! It's almost as if we're equally matched in this game of sheer luck and randomness.", - "RpsLose": "I choose {0}\n\nWell, well, well, looks like I've managed to outsmart a human again in this highly complex game of Rock, Paper, Scissors. I guess my unbeatable powers strike again! ", - "RpsWin": "I choose {0}\n\nOh, congratulations! You must have a crystal ball hidden behind that screen to beat me at Rock, Paper, Scissors. Or maybe I have the world's worst luck algorithm.", - - "CoinFlipCommandInfo": "This Command can only be used when in the lobby or after you die.", - "CoinFlipResult": "Drumroll, please... After an intense battle of gravity and randomness, the coin has decided to grace us with its presence! And the majestic winner is... (wait for it) ... the one and only... {0}! Who could have seen that coming?! Clearly, a momentous occasion in the history of coin flips.", - - "GNoCommandInfo": "This Command can only be used when in the lobby or after you die.\n\ntype /gno X to play guess a number. X can be a number between 0 and 99 (both included). \n\nYou get maximum of 7 tries to guess the number.\n\n Example:- /gno 10", - "GNoLost": "Oh, you were so close! Just one more guess: you might have deciphered the Da Vinci code! By the way, the secret number was... {0}! But hey, you were only off by a few billion possibilities. Better luck next time, Sherlock! ", - "GNoLow": "Oh, you're really nailing this! It's so low. I almost need a shovel to dig it up!\nYou have {0} guesses left!", - "GNoHigh": "Oh, absolutely! You're getting warmer. In fact, it's so high that I need a telescope to see it from here! \nYou have {0} guesses left!", - "GNoWon": "Oh, how did you ever figure that out? It's almost like you're a mind reader! Congratulations, you're a genius! You found the secret number with {0} guesses left!", - - "RandCommandInfo": "This Command can only be used when in the lobby or after you die.\n\ntype /rand X Y to get a number between X and Y, inclusive. \nX and Y can be any number between 0 and 2147483647, including both numbers.\nX must be less than Y.\n\nExample:- /rand 0 99", - "RandResult": "Congratulations, your random number is {0}! Wasn't that fun?", - - "8BallTitle": "The Magic 8 Ball Reveals...", - "8BallYes": "Yes", - "8BallNo": "No", - "8BallMaybe": "Maybe", - "8BallTryAgainLater": "Ask again later", - "8BallCertain": "It is certain", - "8BallNotLikely": "Outlook not so good", - "8BallLikely": "Outlook good", - "8BallDontCount": "Don't count on it", - "8BallStop": "Stop using an 8Ball in an Among Us mod", - "8BallPossibly": "Possibly", - "8BallProbably": "Probably", - "8BallProbablyNot": "Probably not", - "8BallBetterNotTell": "Better not tell you now", - "8BallCantPredict": "Cannot predict now", - "8BallWithoutDoubt": "Without a doubt", - "8BallWithDoubt": "Very doubtful", - - "ChanceToMiss": "Chance to miss a kill", - - "SoulCollectorPointsToWin": "Required number of souls", - "SoulCollectorTarget": "You have predicted the death of {0}", - "SoulCollectorTitle": "SOUL COLLECTOR", - "SoulCollector_CollectOwnSoulOpt": "Can collect their own soul", - "SoulCollectorSelfVote": "Host settings do not allow you to collect your own soul", - "SoulCollectorToDeath": "You have become Death!!!", - "SoulCollectorTransform": "Now Soul Collector has become Death, Destroyer of Worlds and Horseman of the Apocalypse!

Find them and vote them out before they bring forth Armageddon!", - "GetPassiveSouls": "Gain a passive soul every round", - "PassiveSoulGained": "You have gained a passive soul from the underworld.", - "SoulCollectorTargetUsed": "You've already targeted someone this round!", - "SoulCollectorSoulGained": "Soul gained", - "SoulCollectorCanVent": "Soul Collector can Vent", - "DeathMeetingTimeIncrease": "Increased Meeting time when Death exists", - "SoulCollectorMeetingDeath": "Your target has died during the meeting. You have gained a soul.", - "SoulCollectorKillButtonText": "Predict", - "SoulCollectorHasImpostorVision": "Soul Collector has Impostor vision", - - "ApocalypseIsNigh": "[ The Apocalypse Is Nigh! ]", + "InnocentButtonText": "Frame", + "PelicanButtonText": "Eat", + "DeceiverButtonText": "Cheat", + "PursuerButtonText": "Trick", + "GangsterButtonText": "Recruit", + "RevolutionistDrawButtonText": "Win over", + "HaterButtonText": "Hatred", + "MedicalerButtonText": "Protect", + "DemonButtonText": "Attack", + "SoulCatcherButtonText": "Teleport", + "LightningButtonText": "Evaporate", + "ProvocateurButtonText": "Greet", + "ButcherButtonText": "Dismember", + "BomberShapeshiftText": "Explode", + "QuickShooterShapeshiftText": "Keep", + "CamouflagerShapeshiftTextBeforeDisguise": "Disguise", + "CamouflagerShapeshiftTextAfterDisguise": "Duration", + "AnonymousShapeshiftText": "Hack", + "DefaultShapeshiftText": "Shift", + "CleanerReportButtonText": "Clean", + "SwooperVentButtonText": "Swoop", + "SwooperRevertVentButtonText": "Expose", + "WraithVentButtonText": "Vanish", + "WraithRevertVentButtonText": "Expose", + "VectorVentButtonText": "Hop", + "VeteranVentButtonText": "Alert", + "GrenadierVentButtonText": "Flash", + "MayorVentButtonText": "Button", + "SheriffKillButtonText": "Shoot", + "UndertakerButtonText": "Mark", + "ArsonistVentButtonText": "Ignite", + "RevolutionistVentButtonText": "Revolution", + "FollowerKillButtonText": "Follow", + "PacifistVentButtonText": "Reset", + "CultistKillButtonText": "Charm", + "InfectiousKillButtonText": "Infect", + "MonarchKillButtonText": "Knight", + "OverseerKillButtonText": "Reveal", + "DisabledBySettings": "Disabled by Settings", + "Disabled": "Disabled", + "FailToTrack": "Failed To Track", + "KillCount": "Kills: {0}", + "CantUse.lastroles": "Unable to use /lastroles during a game.", + "CantUse.killlog": "Unable to use /killlog during a game.", + "CantUse.lastresult": "Unable to use /lastresult during a game.", + "IllegalColor": "Please enter the correct color", + "DisableUseCommand": "The Host's settings do not allow this command to be used.", + "SureUse.quit": "We will kick you and block you from entering this lobby again. This setting is irreversible. If you really want it, please send the command /qt {0}", + "PlayerIdList": "List of player IDs: ", + "CancelStartCountDown": "The starting countdown was canceled", + "RestTOHESetting": "TOHE settings have been restored to default", + "FPSSetTo": "FPS Set To: {0}", + "HostKillSelfByCommand": "The lobby Host decided to commit suicide", + "SyncCustomSettingsRPC": "Synchronized RPC", + "Mode": "Mode", + "Target": "Target", + "PlayerInfo": "Player Info", + "NoInfoExists": "No Info Exists", + "PlayerLeftByAU-Anticheat": "{0} was banned by the Innersloth anti-cheat.", + "PlayerLeftByError": "Game will auto-end to prevent black screens.", + "MsgKickOtherPlatformPlayer": "{0} was kicked due to playing on {1}", + "KickBecauseLowLevel": "{0} was kicked because their level was too low", + "TempBannedBecauseLowLevel": "{0} was temporarily banned because their level was too low", + "KickBecauseDiffrentVersionOrMod": "{0} was kicked because they had a different version of the mod", + + "FFADisplayScore": "Ranking: {0} Score: {1}", + "FFATimeRemain": "Time Remaining: {0} second(s)", + + "GameOver": "Game Over", + "TOHEOptions": "TOHE Options", + "Cancel": "Cancel", + "Back": "Back", + "Yes": "Yes", + "No": "No", + + "AntiBlackOutLoggerSendInGame": "Because of an unknown error, the game will end to prevent a black screen.", + "AntiBlackOutNotifyInLobby": "An error occurred to prevent a black screen. Do a «/dump» and send the logs to the discord server TOHE in «bug-reports» and we will try to fix it.", + + "EndWhenPlayerBug": "End the game when a modded player gets a critical error (While loading)", + "AntiBlackOutRequestHostToForceEnd": "You were the reason for the black screen. The game will end", + "AntiBlackOutHostRejectForceEnd": "You were the reason for the black screen, and the host is not going to end the game\nYou will be disconnected soon", + + "RpcAntiBlackOutNotifyInLobby": "Because of {0}, an unknown error occurred. To prevent a black screen, turn off [{1}] in settings.", + "RpcAntiBlackOutEndGame": "Because of {0}, an unknown error occurred, the game will end to prevent a black screen.", + "RpcAntiBlackOutIgnored": "Because of {0}, an unknown error occurred, but the game will continue without that player due to host settings.", + "RpcAntiBlackOutKicked": "{0} was kicked due to having a blackout error on its side.", + + "NextPage": "Next Page", + "PreviousPage": "Previous Page", + "EAC.CheatDetected.EAC": "Cheating usage detected (Using AUM)", + "PressF1ShowMainRoleDes": "Press F1: Show Role Description", + "PressF2ShowAddRoleDes": "Press F2: Show Add-on Description", + "PressF3ShowRoleSettings": "Press F3: Show Role Settings", + "PressF4ShowAddOnsSettings": "Press F4: Show Add-ons Settings", + "FakeTask": "Fake Tasks:", + "PVP.ATK": "Attack", + "PVP.DF": "Defend", + "PVP.RCO": "Recover", + "SettingsAreLoading": "Loading\nsettings...", + "EAC.CheatDetected.HighLevel": "Warning: EAC detected High Level of cheats.", + "EAC.CheatDetected.LowLevel": "Warning: EAC detected Low Level of cheats. One of the players is hacking.", + "ExiledJester": "You're all fools!\n{0} the {1} laughing out loud tricked you into ejecting them.\nGG!", + "JesterMeetingLoose": "\r\nBut it cannot win until meeting number {0}", + "ExiledExeTarget": "{0} was the {1}.\nBut they were also the Executioner's target!\nGG!", + "ExiledInnocentTargetAddBelow": "\nLooking back at the Innocent counts the money in their hands", + "ExiledInnocentTargetInOneLine": "{0} was the {1}.\nBut looking back, there's the Innocent counting the money in their hands....\nGG!", + "ExiledDeath": "{0} was {1}!\nThe Crew has been saved from Armageddon!", + "ExiledNotDeath": "{0} was the {1}.\nBut they were not Death...\nDeath has claimed the souls of the Crew!", + "IsGood": "{0} was a good guy", + "BelongTo": "{0} belongs to {1}", + "PlayerIsRole": "{0} was The {1}", + "PlayerExiled": "{0} was ejected", + "NoImpRemain": "0 Impostors remain", + "OneImpRemain": "1 Impostor remains", + "TwoImpRemain": "2 Impostors remain", + "ThreeImpRemain": "3 Impostors remain", + "ImpRemain": "{0} Impostors remaining", + "NeutralRemain": "\n{0} Neutral Killers remain", + "OneNeutralRemain": "\n{0} Neutral Killer remains", + "ApocRemain": "\n{0} Neutral Apocalypse remains", + "GameOverReason.HumansByVote": "All Impostors and Neutral Killers were ejected or killed", + "GameOverReason.HumansByTask": "The Crewmates completed all tasks", + "GameOverReason.HumansDisconnect": "Crewmates disconnected", + "GameOverReason.ImpostorByVote": "The Crewmates were ejected", + "GameOverReason.ImpostorByKill": "The Impostors killed everyone", + "GameOverReason.ImpostorBySabotage": "Crewmates failed to fix a critical sabotage", + "GameOverReason.ImpostorDisconnect": "Impostors disconnected", + "FortuneTellerCheck.TaskDone": "[{0}]Role -[{1}]", + "DevAndSpnTitle": "TOHE family", + "FortuneTellerCheck.Null": "{0} is a role that is not listed.\nThis message should not appear normally.", + "FortuneTellerCheck.Result": "{0} is either one of the following roles:\n{1}", + "SunnyboyChance": "Sunnyboy Chance", + "BardChance": "Bard Chance", + "SkeldChance": "Chance that the map is The Skeld", + "MiraChance": "Chance that the map is MIRA HQ", + "PolusChance": "Chance that the map is Polus", + "DleksChance": "Chance that the map is dlekS ehT", + "AirshipChance": "Chance that the map is Airship", + "FungleChance": "Chance that the map is The Fungle", + "UseMoreRandomMapSelection": "Use a more random map selection", + "CamouflageMode.Default": "Default", + "CamouflageMode.Host": "Host", + "CamouflageMode.Random": "Random", + "CamouflageMode.OnlyRandomColor": "Only Random Color", + "CamouflageMode.Karpe": "KARPED1EM", + "CamouflageMode.Lauryn": "Lauryn", + "CamouflageMode.Moe": "Moe", + "CamouflageMode.Pyro": "Pyro", + "CamouflageMode.ryuk": "ryuk", + "CamouflageMode.Gurge44": "Gurge44", + "CamouflageMode.TommyXL": "TommyXL", + "CamouflageMode.Sarha": "Sarha", + "DeathCmd.HeyPlayer": "Hey ", + "DeathCmd.YouAreRole": ", looks like you're the ", + "DeathCmd.NotDead": "You haven't died yet, this can only be used after you die\n\nCheck back again after you've been brutally murdered", + "DeathCmd.KillerName": "You were killed by ", + "DeathCmd.KillerRole": "Their role is ", + "DeathCmd.DeathReason": "Your cause of death was ", + "DeathCmd.YourName": "You are ", + "DeathCmd.YourRole": "Your role is ", + "DeathCmd.Ejected": "You were ejected during a meeting", + "DeathCmd.Misfired": "You misfired.", + "DeathCmd.Shrouded": "You were shrouded by a Shroud and didn't make a kill, so you suicided.", + "DeathCmd.Lovers": "Your lover had died.", + + "RpsCommandInfo": "This Command can only be used when in the lobby or after you die.\n\ntype /rps X to play Rock Paper Scissors with the system. X can be 0 (rock), 1 (paper) or 2 (scissors). \n\nExample :- /rps 0", + "RpsDraw": "I choose {0}\n\nWow, what an intense battle of wits we just had! It's almost as if we're equally matched in this game of sheer luck and randomness.", + "RpsLose": "I choose {0}\n\nWell, well, well, looks like I've managed to outsmart a human again in this highly complex game of Rock, Paper, Scissors. I guess my unbeatable powers strike again! ", + "RpsWin": "I choose {0}\n\nOh, congratulations! You must have a crystal ball hidden behind that screen to beat me at Rock, Paper, Scissors. Or maybe I have the world's worst luck algorithm.", + + "CoinFlipCommandInfo": "This Command can only be used when in the lobby or after you die.", + "CoinFlipResult": "Drumroll, please... After an intense battle of gravity and randomness, the coin has decided to grace us with its presence! And the majestic winner is... (wait for it) ... the one and only... {0}! Who could have seen that coming?! Clearly, a momentous occasion in the history of coin flips.", + + "GNoCommandInfo": "This Command can only be used when in the lobby or after you die.\n\ntype /gno X to play guess a number. X can be a number between 0 and 99 (both included). \n\nYou get maximum of 7 tries to guess the number.\n\n Example:- /gno 10", + "GNoLost": "Oh, you were so close! Just one more guess: you might have deciphered the Da Vinci code! By the way, the secret number was... {0}! But hey, you were only off by a few billion possibilities. Better luck next time, Sherlock! ", + "GNoLow": "Oh, you're really nailing this! It's so low. I almost need a shovel to dig it up!\nYou have {0} guesses left!", + "GNoHigh": "Oh, absolutely! You're getting warmer. In fact, it's so high that I need a telescope to see it from here! \nYou have {0} guesses left!", + "GNoWon": "Oh, how did you ever figure that out? It's almost like you're a mind reader! Congratulations, you're a genius! You found the secret number with {0} guesses left!", + + "RandCommandInfo": "This Command can only be used when in the lobby or after you die.\n\ntype /rand X Y to get a number between X and Y, inclusive. \nX and Y can be any number between 0 and 2147483647, including both numbers.\nX must be less than Y.\n\nExample:- /rand 0 99", + "RandResult": "Congratulations, your random number is {0}! Wasn't that fun?", + + "8BallTitle": "The Magic 8 Ball Reveals...", + "8BallYes": "Yes", + "8BallNo": "No", + "8BallMaybe": "Maybe", + "8BallTryAgainLater": "Ask again later", + "8BallCertain": "It is certain", + "8BallNotLikely": "Outlook not so good", + "8BallLikely": "Outlook good", + "8BallDontCount": "Don't count on it", + "8BallStop": "Stop using an 8Ball in an Among Us mod", + "8BallPossibly": "Possibly", + "8BallProbably": "Probably", + "8BallProbablyNot": "Probably not", + "8BallBetterNotTell": "Better not tell you now", + "8BallCantPredict": "Cannot predict now", + "8BallWithoutDoubt": "Without a doubt", + "8BallWithDoubt": "Very doubtful", + + "ChanceToMiss": "Chance to miss a kill", + + "SoulCollectorPointsToWin": "Required number of souls", + "SoulCollectorTarget": "You have predicted the death of {0}", + "SoulCollectorTitle": "SOUL COLLECTOR", + "SoulCollector_CollectOwnSoulOpt": "Can collect their own soul", + "SoulCollectorSelfVote": "Host settings do not allow you to collect your own soul", + "SoulCollectorToDeath": "You have become Death!!!", + "SoulCollectorTransform": "Now Soul Collector has become Death, Destroyer of Worlds and Horseman of the Apocalypse!

Find them and vote them out before they bring forth Armageddon!", + "GetPassiveSouls": "Gain a passive soul every round", + "PassiveSoulGained": "You have gained a passive soul from the underworld.", + "SoulCollectorTargetUsed": "You've already targeted someone this round!", + "SoulCollectorSoulGained": "Soul gained", + "SoulCollectorCanVent": "Soul Collector can Vent", + "DeathMeetingTimeIncrease": "Increased Meeting time when Death exists", + "SoulCollectorMeetingDeath": "Your target has died during the meeting. You have gained a soul.", + "SoulCollectorKillButtonText": "Predict", + + "ApocalypseIsNigh": "[ The Apocalypse Is Nigh! ]", "ApocalypseImmune": "This role is immune!", - "BakerToFamine": "You have become Famine!!!", - "BakerTransform": "The Baker has transformed into Famine, Horseman of the Apocalypse! A famine has begun!", - "BakerAlreadyBreaded": "That player already has bread!", - "BakerBreadUsedAlready": "You've already given a player bread this round!", - "BakerBreaded": "Player given bread", - "BakerBreadNeededToTransform": "Required number of bread to become Famine", - "BakerCantBreadApoc": "You cannot give other Apocalypse members bread!", - "BakerKillButtonText": "Bread", + "BakerToFamine": "You have become Famine!!!", + "BakerTransform": "The Baker has transformed into Famine, Horseman of the Apocalypse! A famine has begun!", + "BakerAlreadyBreaded": "That player already has bread!", + "BakerBreadUsedAlready": "You've already given a player bread this round!", + "BakerBreaded": "Player given bread", + "BakerBreadNeededToTransform": "Required number of bread to become Famine", + "BakerCantBreadApoc": "You cannot give other Apocalypse members bread!", + "BakerKillButtonText": "Bread", "BakerUnshiftButtonText": "Switch Bread", - "BakerRevealBread": "Reveal", - "BakerRoleblockBread": "Roleblock", - "BakerBarrierBread": "Barrier", - "BakerCurrentBread": "Current Bread: ", - "BakerSwitchBread": "Bread Switched to: ", + "BakerRevealBread": "Reveal", + "BakerRoleblockBread": "Roleblock", + "BakerBarrierBread": "Barrier", + "BakerCurrentBread": "Current Bread: ", + "BakerSwitchBread": "Bread Switched to: ", "BakerCanVent": "Baker can Vent", - "BakerBreadGivesEffects": "Bread gives additional effects", + "BakerBreadGivesEffects": "Bread gives additional effects", "BakerTransformNoMoreBread": "Baker transforms if they do not have enough bread", - "FamineKillButtonText": "Starve", - "FamineStarveCooldown": "Famine starve cooldown", - "FamineCantStarveApoc": "You cannot starve other Apocalypse members!", - "FamineAlreadyStarved": "That player has already been starved!", - "FamineStarved": "Player starved", - - "ChronomancerKillCooldown": "Ability Charge Time", - "ChronomancerDecreaseTime": "Slaughter Decrease Time (lower is faster)", - "ChronomancerStartMassacre": "SLAUGHTER: ACTIVATED", - "ChronomancerVisionMassacre": "Vision When In Slaughter", - - "ShamanButtonText": "Voodoo", - "ShamanTargetAlreadySelected": "You have already selected a voodoo doll in this round", - "Shaman_KillerCannotMurderChosenTarget": "The killer cannot murder chosen target", - "VoodooCooldown": "Voodoo Cooldown", - - "AdminWarning": "Admin Table in use!", - "VitalsWarning": "Vitals in use!", - "DoorlogWarning": "Doorlogs in use!", - "CameraWarning": "Cameras in use!", - "MinWaitAutoStart": "Minutes to wait before auto-starting", - "MaxWaitAutoStart": "Force start when Lobby Timer (in minutes) goes below", - "PlayerAutoStart": "Minimum Player Threshold to auto-start", - "AutoStartTimer": "Initial countdown for auto-starting", - "ImmediateAutoStart": "Immediately start the game when reaching certain conditions", - "ImmediateStartTimer": "Initial countdown for Immediate-starting", - "StartWhenPlayersReach": "Immediately Start when we have enough players above", - "StartWhenTimerLowerThan": "Immediately Start when Lobby Timer goes below", - "AutoPlayAgainCountdown": "Delay before re-entering lobby", - "AutoPlayAgain": "Auto Play Again", - "AutoRehost": "Auto Re-Host on Bad Disconnect", - "CountdownText": "Rejoining lobby in {0}s", - "TimeMasterSkillDuration": "Time Shield Duration", - "TimeMasterSkillCooldown": "Time Shield Cooldown", - "TimeMasterOnGuard": "Time Shield is active!", - "TimeMasterSkillStop": "Time Shield has ended!", - "TimeMasterVentButtonText": "Time Shield", - "BodyCannotBeReported": "Body could not be reported", - "BurstKillDelay": "Burst Kill Delay", - "BurstNotify": "That was a Burst! Get in a vent or die.", - "BurstFailed": "Burst failed to bomb you", - "ShroudButtonText": "Shroud", - "ShroudCooldown": "Shroud Cooldown", - "Message.Shrouded": "One or more players were shrouded by a Shroud!\n\nGet rid of the Shroud or all shrouded players will suicide!", - "LudopathRandomKillCD": "Maximum kill cooldown", - "UnderdogMaximumPlayersNeededToKill": "Maximum players needed to start killing", - "GodfatherTargetCountMode": "Killer turns into", - "GodfatherCount_Refugee": "Refugee", - "GodfatherCount_Madmate": "Madmate", + "FamineKillButtonText": "Starve", + "FamineStarveCooldown": "Famine starve cooldown", + "FamineCantStarveApoc": "You cannot starve other Apocalypse members!", + "FamineAlreadyStarved": "That player has already been starved!", + "FamineStarved": "Player starved", + + "ChronomancerKillCooldown": "Ability Charge Time", + "ChronomancerDecreaseTime": "Slaughter Decrease Time (lower is faster)", + "ChronomancerStartMassacre": "SLAUGHTER: ACTIVATED", + "ChronomancerVisionMassacre": "Vision When In Slaughter", + + "ShamanButtonText": "Voodoo", + "ShamanTargetAlreadySelected": "You have already selected a voodoo doll in this round", + "Shaman_KillerCannotMurderChosenTarget": "The killer cannot murder chosen target", + "VoodooCooldown": "Voodoo Cooldown", + + "AdminWarning": "Admin Table in use!", + "VitalsWarning": "Vitals in use!", + "DoorlogWarning": "Doorlogs in use!", + "CameraWarning": "Cameras in use!", + "MinWaitAutoStart": "Minutes to wait before auto-starting", + "MaxWaitAutoStart": "Force start when Lobby Timer (in minutes) goes below", + "PlayerAutoStart": "Minimum Player Threshold to auto-start", + "AutoStartTimer": "Initial countdown for auto-starting", + "ImmediateAutoStart": "Immediately start the game when reaching certain conditions", + "ImmediateStartTimer": "Initial countdown for Immediate-starting", + "StartWhenPlayersReach": "Immediately Start when we have enough players above", + "StartWhenTimerLowerThan": "Immediately Start when Lobby Timer goes below", + "AutoPlayAgainCountdown": "Delay before re-entering lobby", + "AutoPlayAgain": "Auto Play Again", + "AutoRehost": "Auto Re-Host on Bad Disconnect", + "CountdownText": "Rejoining lobby in {0}s", + "TimeMasterSkillDuration": "Time Shield Duration", + "TimeMasterSkillCooldown": "Time Shield Cooldown", + "TimeMasterOnGuard": "Time Shield is active!", + "TimeMasterSkillStop": "Time Shield has ended!", + "TimeMasterVentButtonText": "Time Shield", + "BodyCannotBeReported": "Body could not be reported", + "BurstKillDelay": "Burst Kill Delay", + "BurstNotify": "That was a Burst! Get in a vent or die.", + "BurstFailed": "Burst failed to bomb you", + "ShroudButtonText": "Shroud", + "ShroudCooldown": "Shroud Cooldown", + "Message.Shrouded": "One or more players were shrouded by a Shroud!\n\nGet rid of the Shroud or all shrouded players will suicide!", + "LudopathRandomKillCD": "Maximum kill cooldown", + "UnderdogMaximumPlayersNeededToKill": "Maximum players needed to start killing", + "GodfatherTargetCountMode": "Killer turns into", + "GodfatherCount_Refugee": "Refugee", + "GodfatherCount_Madmate": "Madmate", "GodfatherRefugeeMsg": "You have been recruited by GodFather!", - "MissChance": "Chance To Miss", - "IncreaseByOneIfConvert": "Increase The KillCount +1 If a Crew Is Converted", - "HawkMissed": "Missed!", - "HawkCanKillNum": "Max Slices", - "HawkKillMax": "You've run out of ability uses", - "HawkKillTooManyDead": "Too many people are dead", - "MinimumPlayersAliveToKill": "Minimum Players Alive To Kill", - "BloodMoonCanKillNum": "Max BloodLettings", - "BloodMoonTimeTilDie": "Time Until Death", - "PossessorPossessCooldown": "Possession Cooldown", - "PossessorPossessDuration": "Possession Duration", - "PossessorAlertRange": "Alert Range", - "PossessorFocusRange": "Focus Range", - "DeathTimer": "Death In: {DeathTimer}s", - "BerserkerKillCooldown": "Berserker kill cooldown", - "BerserkerMax": "Max level that Berserker can reach", - "BerserkerHasImpostorVision": "Berserker Has Impostor Vision", - "WarHasImpostorVision": "War Has Impostor Vision", - "BerserkerCanVent": "Berserker Can Vent", - "WarCanVent": "War Can Vent", - "BerserkerOneCanKillCooldown": "Unlock lower kill cooldown", - "BerserkerOneKillCooldown": "Kill cooldown after unlocking", - "BerserkerTwoCanScavenger": "Unlock scavenged kills", - "BerserkerThreeCanBomber": "Unlock bombed kills", - "BerserkerFourCanNotKill": "Become War", - "BerserkerMaxReached": "Maximum level reached!", - "BerserkerLevelChanged": "Increased level to {0}", - "BerserkerLevelRequirement": "Level requirement for unlock", - "KilledByBerserker": "Killed by Berserker", - "BerserkerToWar": "You have become War!!!", - "BerserkerTransform": "The Berserker has transformed into War, Horseman of the Apocalypse! Cry 'Havoc!', and let slip the dogs of war.", - "WarKillCooldown": "War kill cooldown", - "BerserkerCanKillTeamate": "Can kill other Neutral Apocalypse", - - "BlackmailerSkillCooldown": "Blackmail Cooldown", - "BlackmailerMax": "Maximum times blackmailed players may speak", - "BlackmailerDead": "Warning! {0} has been blackmailed by a Blackmailer!", - "BlackmaileKillTitle": "BLACKMAILER", - "UnluckyTaskSuicideChance": "Chance to suicide from doing tasks", - "UnluckyKillSuicideChance": "Chance to suicide from killing", - "UnluckyVentSuicideChance": "Chance to suicide from venting", - "UnluckyReportSuicideChance": "Chance to suicide from reporting bodies", - "UnluckyOpenDoorSuicideChance": "Chance to suicide from opening a door", - "NeutralCanBeAware": "Neutrals can become Aware", - "CrewCanBeAware": "Crewmates can become Aware", - "AwareKnowRole": "Knows the role of the player", - "AwareInteracted": "{0} tried to reveal your role.", - "AwareTitle": "AWARE MESSAGE", - "LighterVentButtonText": "Light", - "LighterSkillCooldown": "Light Cooldown", - "LighterSkillDuration": "Light Duration", - "LighterVisionNormal": "Increased Vision", - "LighterVisionOnLightsOut": "Increased Vision During Lights Out", - "StealthDarkened": "Darkened: {0}", - "StealthExcludeImpostors": "Ignore Impostors when Blinding", - "StealthDarkenDuration": "Blinding Duration", - "PenguinAbductTimerLimit": "Dragging Time", - "PenguinMeetingKill": "Kill the target if a meeting starts during dragging", - "PenguinKillButtonText": "Drag", - "PenguinTimerText": "Drag Timer", - "PenguinTargetOnCheckMurder": "You are grabbed. Try to escape that first!", - "WitnessTime": "Max Time after killing where killer appears red", - "WitnessButtonText": "Examine", - "WitnessFoundInnocent": "✓", - "WitnessFoundKiller": "⚠", - "SwapperMax": "Maximum swaps", - "CanSwapSelfVotes": "Can exchange your own votes.", - "SwapperTrialMax": "You've reached the maximum amount of swaps!\nYou can't swap votes anymore.", - "CantSwapSelf": "Can't exchange of one's own vote", - "SwapVote": "The votes of {0} and {1} were swapped!", - "SwapDead": "Sorry, you can't swap votes after death.", - "SwapNull": "Please choose the ID of a living player to swap votes with. Use 253 to clear swaps", - "SwapHelp": "Command Format: /sw [playerID] to select the target\nYou can see the player IDs next to the player names or use /id to see the player ID list.\nUse /swap 253 to clear your previous swap", - "Swap1": "Swap target 1 selected", - "Swap2": "Swap target 2 selected", - "CancelSwap": "Cleared your previous swap!", - "CancelSwapDueToTarget": "Cleared your previous swap because one or more of your targets is dead.", - "Swap1=Swap2": "The target you input is the same as Swap target 1.\nPls input a different one", - "SwapTitle": "SWAPPER", - "SwapperTryHideMsg": "Try to hide Swapper's command", - "SwapperPreResult": "Currently, you selected to swap votes between {0} and {1}.\nIf you feel unsure, use /swap 253 to clear your selection.", - "ImpCanKillFragile": "Impostors can force kill Fragile", - "NeutralCanKillFragile": "Neutrals can force kill Fragile", - "CrewCanKillFragile": "Crewmates can force kill Fragile", - "FragileKillerLunge": "Killer lunges on kill", - "CrusaderSkillLimit": "Maximum Crusades", - "CrusaderSkillCooldown": "Crusade Cooldown", - "CrusaderKillButtonText": "Crusade", - "JailorKillButtonText": "Jail", - "AgitaterKillButtonText": "Pass", - "HasSerialKillerBuddy": "Has Serial Killer buddy", - "ChanceToSpawn": "Chance to spawn", - "ChanceToSpawnAnother": "Chance to spawn another", - "BloodthirstKillCD": "Bloodthirst Kill Cooldown", - "BloodthirstPlayerCount": "Max players alive for Bloodthirst", - "ReflectHarmfulInteractions": "Reflect harmful interactions", - - "DiseasedCDOpt": "Increase the cooldown by", - "DiseasedCDReset": "Cooldown returns to normal after a meeting", - - "AntidoteCDOpt": "Decrease the cooldown by", - "AntidoteCDReset": "Cooldown returns to normal after a meeting", - - "GlowRadius": "Glow Radius", - "GlowVisionOthers": "Vision Boost for nearby Players", - "GlowVisionSelf": "Vision Boost for Glow", - - "SleuthCanKnowKillerRole": "Can find the role of the killer", - "SleuthNoticeKiller": "\nThe killer's role is {0}.", - "SleuthNoticeVictim": "{0}'s role is {1}.", - "SleuthNoticeKillerNotFound": "\nThe killer could not be identified, this was possibly a suicide.", - "BomberDiesInExplosion": "Bomber dies in their explosion", - "ImpostorsSurviveBombs": "Impostors survive bombs", - - "PunchingBagKillMax": "Amount of attacks needed to win", - "GuessPunchingBag": "You just tried to guess a Punching Bag!\nThey're now one step closer to winning!", - "GuessPunchingBagAgain": "You just tried to guess a Punching Bag again!\n\nIt no longer counts your attacks by guessing", - "PunchingBagKill": "You were attacked!", - "SelfGuessPunchingBag": "You can't self-guess as a Punching Bag, you cheater!", - "GuessPunchingBagBlocked": "Punching Bag cannot guess due to self-guessing.", - "EradicatePunchingBag": "You just tried to terminate punching bag, that is not allowed.", - - "RememberCooldown": "Imitate Cooldown", - "RefugeeKillCD": "Refugee's Kill Cooldown", - "RememberedNeutralKiller": "You remembered you were a neutral killer!", - "RememberedMaverick": "You remembered you were a Maverick!", - "RememberedPursuer": "You remembered you were a Pursuer!", - "RememberedFollower": "You remembered you were a Follower!", - "RememberedAmnesiac": "You failed to remember your role.", + "MissChance": "Chance To Miss", + "IncreaseByOneIfConvert": "Increase The KillCount +1 If a Crew Is Converted", + "HawkMissed": "Missed!", + "HawkCanKillNum": "Max Slices", + "HawkKillMax": "You've run out of ability uses", + "HawkKillTooManyDead": "Too many people are dead", + "MinimumPlayersAliveToKill": "Minimum Players Alive To Kill", + "BloodMoonCanKillNum": "Max BloodLettings", + "BloodMoonTimeTilDie": "Time Until Death", + "PossessorPossessCooldown": "Possession Cooldown", + "PossessorPossessDuration": "Possession Duration", + "PossessorAlertRange": "Alert Range", + "PossessorFocusRange": "Focus Range", + "DeathTimer": "Death In: {DeathTimer}s", + "BerserkerKillCooldown": "Berserker kill cooldown", + "BerserkerMax": "Max level that Berserker can reach", + "BerserkerHasImpostorVision": "Berserker Has Impostor Vision", + "WarHasImpostorVision": "War Has Impostor Vision", + "BerserkerCanVent": "Berserker Can Vent", + "WarCanVent": "War Can Vent", + "BerserkerOneCanKillCooldown": "Unlock lower kill cooldown", + "BerserkerOneKillCooldown": "Kill cooldown after unlocking", + "BerserkerTwoCanScavenger": "Unlock scavenged kills", + "BerserkerThreeCanBomber": "Unlock bombed kills", + "BerserkerFourCanNotKill": "Become War", + "BerserkerMaxReached": "Maximum level reached!", + "BerserkerLevelChanged": "Increased level to {0}", + "BerserkerLevelRequirement": "Level requirement for unlock", + "KilledByBerserker": "Killed by Berserker", + "BerserkerToWar": "You have become War!!!", + "BerserkerTransform": "The Berserker has transformed into War, Horseman of the Apocalypse! Cry 'Havoc!', and let slip the dogs of war.", + "WarKillCooldown": "War kill cooldown", + + "BlackmailerSkillCooldown": "Blackmail Cooldown", + "BlackmailerMax": "Maximum times blackmailed players may speak", + "BlackmailerDead": "Warning! {0} has been blackmailed by a Blackmailer!", + "BlackmaileKillTitle": "BLACKMAILER", + "UnluckyTaskSuicideChance": "Chance to suicide from doing tasks", + "UnluckyKillSuicideChance": "Chance to suicide from killing", + "UnluckyVentSuicideChance": "Chance to suicide from venting", + "UnluckyReportSuicideChance": "Chance to suicide from reporting bodies", + "UnluckyOpenDoorSuicideChance": "Chance to suicide from opening a door", + "NeutralCanBeAware": "Neutrals can become Aware", + "CrewCanBeAware": "Crewmates can become Aware", + "AwareKnowRole": "Knows the role of the player", + "AwareInteracted": "{0} tried to reveal your role.", + "AwareTitle": "AWARE MESSAGE", + "LighterVentButtonText": "Light", + "LighterSkillCooldown": "Light Cooldown", + "LighterSkillDuration": "Light Duration", + "LighterVisionNormal": "Increased Vision", + "LighterVisionOnLightsOut": "Increased Vision During Lights Out", + "StealthDarkened": "Darkened: {0}", + "StealthExcludeImpostors": "Ignore Impostors when Blinding", + "StealthDarkenDuration": "Blinding Duration", + "PenguinAbductTimerLimit": "Dragging Time", + "PenguinMeetingKill": "Kill the target if a meeting starts during dragging", + "PenguinKillButtonText": "Drag", + "PenguinTimerText": "Drag Timer", + "PenguinTargetOnCheckMurder": "You are grabbed. Try to escape that first!", + "WitnessTime": "Max Time after killing where killer appears red", + "WitnessButtonText": "Examine", + "WitnessFoundInnocent": "✓", + "WitnessFoundKiller": "⚠", + "SwapperMax": "Maximum swaps", + "CanSwapSelfVotes": "Can exchange your own votes.", + "SwapperTrialMax": "You've reached the maximum amount of swaps!\nYou can't swap votes anymore.", + "CantSwapSelf": "Can't exchange of one's own vote", + "SwapVote": "The votes of {0} and {1} were swapped!", + "SwapDead": "Sorry, you can't swap votes after death.", + "SwapNull": "Please choose the ID of a living player to swap votes with. Use 253 to clear swaps", + "SwapHelp": "Command Format: /sw [playerID] to select the target\nYou can see the player IDs next to the player names or use /id to see the player ID list.\nUse /swap 253 to clear your previous swap", + "Swap1": "Swap target 1 selected", + "Swap2": "Swap target 2 selected", + "CancelSwap": "Cleared your previous swap!", + "CancelSwapDueToTarget": "Cleared your previous swap because one or more of your targets is dead.", + "Swap1=Swap2": "The target you input is the same as Swap target 1.\nPls input a different one", + "SwapTitle": "SWAPPER", + "SwapperTryHideMsg": "Try to hide Swapper's command", + "SwapperPreResult": "Currently, you selected to swap votes between {0} and {1}.\nIf you feel unsure, use /swap 253 to clear your selection.", + "ImpCanKillFragile": "Impostors can force kill Fragile", + "NeutralCanKillFragile": "Neutrals can force kill Fragile", + "CrewCanKillFragile": "Crewmates can force kill Fragile", + "FragileKillerLunge": "Killer lunges on kill", + "CrusaderSkillLimit": "Maximum Crusades", + "CrusaderSkillCooldown": "Crusade Cooldown", + "CrusaderKillButtonText": "Crusade", + "JailorKillButtonText": "Jail", + "AgitaterKillButtonText": "Pass", + "HasSerialKillerBuddy": "Has Serial Killer buddy", + "ChanceToSpawn": "Chance to spawn", + "ChanceToSpawnAnother": "Chance to spawn another", + "BloodthirstKillCD": "Bloodthirst Kill Cooldown", + "BloodthirstPlayerCount": "Max players alive for Bloodthirst", + "ReflectHarmfulInteractions": "Reflect harmful interactions", + + "DiseasedCDOpt": "Increase the cooldown by", + "DiseasedCDReset": "Cooldown returns to normal after a meeting", + + "AntidoteCDOpt": "Decrease the cooldown by", + "AntidoteCDReset": "Cooldown returns to normal after a meeting", + + "GlowRadius": "Glow Radius", + "GlowVisionOthers": "Vision Boost for nearby Players", + "GlowVisionSelf": "Vision Boost for Glow", + + "SleuthCanKnowKillerRole": "Can find the role of the killer", + "SleuthNoticeKiller": "\nThe killer's role is {0}.", + "SleuthNoticeVictim": "{0}'s role is {1}.", + "SleuthNoticeKillerNotFound": "\nThe killer could not be identified, this was possibly a suicide.", + "BomberDiesInExplosion": "Bomber dies in their explosion", + "ImpostorsSurviveBombs": "Impostors survive bombs", + + "PunchingBagKillMax": "Amount of attacks needed to win", + "GuessPunchingBag": "You just tried to guess a Punching Bag!\nThey're now one step closer to winning!", + "GuessPunchingBagAgain": "You just tried to guess a Punching Bag again!\n\nIt no longer counts your attacks by guessing", + "PunchingBagKill": "You were attacked!", + "SelfGuessPunchingBag": "You can't self-guess as a Punching Bag, you cheater!", + "GuessPunchingBagBlocked": "Punching Bag cannot guess due to self-guessing.", + "EradicatePunchingBag": "You just tried to terminate punching bag, that is not allowed.", + + "RememberCooldown": "Imitate Cooldown", + "RefugeeKillCD": "Refugee's Kill Cooldown", + "RememberedNeutralKiller": "You remembered you were a neutral killer!", + "RememberedMaverick": "You remembered you were a Maverick!", + "RememberedPursuer": "You remembered you were a Pursuer!", + "RememberedFollower": "You remembered you were a Follower!", + "RememberedAmnesiac": "You failed to remember your role.", "AmnesiacRemembered": "You remembered you were {0}!", "ReportWhenFailedRemember": "Report Dead Body when failed to remember", - "RememberedImitator": "You remembered you were an Imitator.", - "RememberedImpostor": "You remembered you were an Impostor!", - "RememberedCrewmate": "You remembered you were a crewmate!", - "ImitatorImitated": "An Imitator imitated your role!", - "ImitatorInvalidTarget": "Imitation failed", - "RememberButtonText": "Remember", - "ImitatorKillButtonText": "Imitate", - "IncompatibleNeutralMode": "If neutral is incompatible, turn into", - "RememberedYourRole": "An Amnesiac remembered your role!", - "YouRememberedRole": "You remembered who you were!", - - "BanditStealMode": "Steal Mode", - "BanditStealMode_OnMeeting": "On Meeting", - "BanditStealMode_Instantly": "Instantly", - "BanditMaxSteals": "Maximum Steals", - "BanditCanStealBetrayalAddon": "Can Steal Betrayal Add-ons", - "BanditCanStealImpOnlyAddon": "Can Steal Impostor Only Addons", - "Bandit_NoStealableAddons": "Could not steal add-on from the player", - "BanditStealCooldown": "Steal cooldown", - - "DoppelMaxSteals": "Maximum Steals", - "DoppelCurrentVictimCanSeeRolesAsDead": "Last victim can see role and add-on info of alive players as a ghost", - - "NecromancerRevengeTime": "Necromancy time", - "NecromancerRevenge": "You have {0}s to kill {1}", - "NecromancerSuccess": "Necromancy complete! You live to see another day.", - "NecromancerHide": "Venting is disabled, hide from the Necromancer!", - "RetributionistDeadMsg": "The death of the Retributionist means the beginning of retribution. \nPlease use /ret + [player ID] to kill the specified player \nYou can see player IDs in front of their names. \nOr type /ret to get a list of player IDs", - "RetributionistAliveKill": "Retribution for the Retributionist may only begin after their death.", - "RetributionistKillMax": "You've reached the maximum amount of kills. You can't kill anymore!", - "RetributionistKillDead": "Choose a living player to kill.", - "RetributionistKillSucceed": "{0} was killed by the Retributionist!", - "RetributionistKillDisable": "You can't retribute until your tasks are done.", - "CanOnlyRetributeWithTasksDone": "Can only retribute on task completion", - "RetributionistCanKillNum": "Max retributions", - "RetributionistKillTooManyDead": "Too many players are dead. You can't retribute.", - "MinimumPlayersAliveToRetri": "Minimum players alive to retribute", - "MinimumNoKillerEjectsToKill": "Minimum meetings passed with no killer ejects to kill", - "ImmuneToAttacksWhenTasksDone": "Immune to attacks on task completion", - - "TwisterCooldown": "Twist Cooldown", - "TwisterButtonText": "Twist", - "TwisterHideTwistedPlayerNames": "Hide who the players swap places with", - "InstigatorAbilityLimit": "Ability Use Count", - "InstigatorKillsPerAbilityUse": "Kills per Ability use", - - "CrewCanFindCaptain": "Crewmates can find Captain", - "MadmateCanFindCaptain": "Madmates can find Captain", - "ReducedSpeed": "Reduced speed", - "ReducedSpeedTime": "Time duration for reduced speed", - "CaptainCanTargetNB": "Captain can target Neutral Benign", - "CaptainCanTargetNE": "Captain can target Neutral Evil", - "CaptainCanTargetNC": "Captain can target Neutral Chaos", - "CaptainCanTargetNA": "Captain can target Neutral Apocalypse", - "CaptainCanTargetNK": "Captain can target Neutral Killer", - "CaptainSpeedReduced": "Captain reduced your speed", - "CaptainRevealTaskRequired": "Number of tasks completed after which Captain is revealed", - "CaptainSlowTaskRequired": "Number of tasks completed after which target speed is reduced", - - "InspectorTryHideMsg": "Hide Inspector's commands", - "MaxInspectCheckLimit": "Max inspections per game", - "InspectCheckLimitPerMeeting": "Max inspections per meeting", - "InspectCheckTargetKnow": "Targets know they were checked by Inspector", - "InspectCheckOtherTargetKnow": "Targets know who they were checked with", - "InspectorDead": "You can not use your power after death", - "InspectCheckMax": "Max inspections per game reached!\nYou can not use your power anymore.", - "InspectCheckRound": "Max inspections per round reached!\nYou can check again in the next round.", - "InspectCheckSelf": "HA!! You thought it would be this easy. You can not check yourself", - "InspectCheckReveal": "HA! You thought it would be this easy. You can not check a role that is revealed", - "InspectCheckTitle": "INSPECTOR ", - "InspectCheckTrue": "{0} and {1} are in the same team!", - "InspectCheckFalse": "{0} and {1} are NOT in the same team!", - "InspectCheckTargetMsg": " were checked by Inspector.", - "InspectCheckHelp": "Instructions: /cmp [Player ID 1] [Player ID 2] \nExample: /cmp 1 5 \nYou can see the player IDs before everyone's names \n or use the /id command to list the player IDs", - "InspectCheckNull": "Please select an ID of a living player to check their team", - "InspectCheckBaitCountMode": "Bait counts as revealing role if Bait reveal on first meeting is on", - "InspectCheckRevealTarget": "When tasks are done, the target knows the team of the other target", - "InspectorTargetReveal": " Looks like {0} is aligned with team {1}", - - "EgoistCountMode.Original": "Original", - "EgoistCountMode.Neutral": "Neutral", - - "JailerJailCooldown": "Jail cooldown", - "JailerMaxExecution": "Maximum executions", - "JailerNBCanBeExe": "Can execute Neutral Benign", - "JailerNCCanBeExe": "Can execute Neutral Chaos", - "JailerNECanBeExe": "Can execute Neutral Evil", - "JailerNKCanBeExe": "Can execute Neutral Killing", - "JailerNACanBeExe": "Can execute Neutral Apocalypse", - "JailerCKCanBeExe": "Can execute Crew Killing", - "JailerTargetAlreadySelected": "You have already selected a target", - "SuccessfullyJailed": "Target successfully jailed", - "CantGuessJailed": "You can not guess the target", - "JailedCanOnlyGuessJailer": "You have been jailed. You can only guess Jailer.", - "CanNotTrialJailed": "You can not trial the target.", - "notifyJailedOnMeeting": "Notify jailed player when a meeting starts", - "JailedNotifyMsg": "The Jailer has jailed you. No one can guess or judge you. You can only guess The Jailer.\n\nIf Jailer votes you, you will be executed after the meeting ends.", - "JailerTitle": "Jailer", - - "CopyCatCopyCooldown": "Copy cooldown", - "CopyCatRoleChange": "Your role has been changed to {0}", - "CopyCatCanNotCopy": "You can not copy the target's role", - "CopyButtonText": "Copy", - "CopyCrewVar": "Can copy evil variants of crew roles", - "CopyTeamChangingAddon": "Can copy team changing add-on", - - "MaxCleanserUses": "Max cleanses", - "CleansedCanGetAddon": "Cleansed player can get Add-on", - "CleanserTitle": "CLEANSER", - "CleanserRemoveSelf": "You can not cleanse yourself", - "CleanserCantRemove": "Oops! the player can not be cleansed.", - "CleanserRemovedRole": "{0} has been cleansed. All their Add-ons will be removed after the meeting.\n\nYour vote has been returned and you can vote for someone.", - "LostAddonByCleanser": "The cleanser removed all your Add-ons", - - "MaxProtections": "Max protections", - "KeeperHideVote": "Hide Keeper's vote", - "KeeperProtect": "You chose to protect {0}, your vote has been returned", - "KeeperTitle": "Keeper", - - "MaulRadius": "Maul Radius", - "ImpKnowCyberDead": "Impostors know if Cyber died", - "CrewKnowCyberDead": "Crewmates know if Cyber died", - "NeutralKnowCyberDead": "Neutrals know if Cyber died", - "CyberKnown": "Everyone can see Cyber", - "KillerGetBewilderVision": "Killer gets Bewilder's vision", - "ImpCanBeOiiai": "Impostors can be OIIAI", - "CrewCanBeOiiai": "Crewmates can be OIIAI", - "NeutralCanBeOiiai": "Neutrals can be OIIAI", - "OiiaiCanPassOn": "OIIAI can pass on to the killer", - "NeutralChangeRolesForOiiai": "Neutrals turns to ", - "LostRoleByOiiai": "You got erased by OIIAI!", - "ImpCanBeLoyal": "Impostors can become Loyal", - "CrewCanBeLoyal": "Crewmates can become Loyal", - "TasklessCrewCanBeLazy": "Crewmates without tasks can be Lazy", - "TaskBasedCrewCanBeLazy": "Task based crewmates can be Lazy", - "SheriffCanBeMadmate": "Sheriff can become Madmate", - "MayorCanBeMadmate": "Mayor can become Madmate", - "NGuesserCanBeMadmate": "Nice Guesser can become Madmate", - "SnitchCanBeMadmate": "Snitch can become Madmate", - "JudgeCanBeMadmate": "Judge can become Madmate", - "MarshallCanBeMadmate": "Marshall can become Madmate", - "GanRetributionistCanBeMadmate": "Retributionist can be converted", - "RetributionistCanBeMadmate": "Retributionist can become Madmate", - "OverseerCanBeMadmate": "Overseer can become Madmate", - "GanSheriffCanBeMadmate": "Sheriff can be converted", - "GanMayorCanBeMadmate": "Mayor can be converted", - "GanNGuesserCanBeMadmate": "Nice Guesser can be converted", - "GanJudgeCanBeMadmate": "Judge can be converted", - "GanMarshallCanBeMadmate": "Marshall can be converted", - "GanOverseerCanBeMadmate": "Overseer can be converted", - "RascalAppearAsMadmate": "Appear As Madmate On Ejection", - - "CouncillorDead": "Sorry, you can't murder from the dead.", - "CouncillorMurderMaxMeeting": "Sorry, you've reached the maximum amount of murders for the meeting.", - "CouncillorMurderMaxGame": "Sorry, you've reached the maximum amount of murders for the game.", - "Councillor_LaughToWhoMurderSelf": "Hahaha, who would've thought someone was stupid enough to murder themselves?\n\nGuess it happens to be... YOU!", - "Councillor_MurderKill": "{0} was murdered.", - "Councillor_MurderHelp": "Command: /tl [player ID]\nYou can see the players' IDs before the players' names.\nOr use /id to view the list of all player IDs.", - "Councillor_MurderNull": "Please choose a living player to murder.", - "Councillor_MurderKillTitle": "WICKED COURT ", - "CouncillorMakeEvilJudgeClear": "Show Trial as Councillor Murder", - "Councillor_CannotMurderImpTeam": "Sorry, you can not murder your teammate.", - "Councillor_SuicideForMurderImps": "You died because you are trying to murder your team members.", - "CouncillorMurderLimitPerMeeting": "Maximum Kills Per Meeting", - "CouncillorMurderLimitPerGame": "Maximum Kills Per Game", - "CouncillorCanMurderMadmate": "Can Murder Madmates", - "CouncillorCanMurderImpostor": "Can Murder Impostors", - "CouncillorSuicideOnJudgeImpTeam": "Suicide when judge Impostors Team Wrongly", - "CouncillorCanMurderTaskDoneSnitch": "Can Murder Snitch with All Tasks Done", - "CouncillorTryHideMsg": "Try to hide Councillor's commands", - - "DazzlerDazzled": "You were dazzled by the Dazzler!", - "DazzlerCauseVision": "Reduced vision", - "DazzlerDazzleLimit": "Max number of players affected by reduced vision", - "DazzlerResetDazzledVisionOnDeath": "Reset vision of dazzled players on death/eject", - "DazzleCooldown": "Dazzle Cooldown", - "DazzleButtonText": "Dazzle", - - "MoleVentButtonText": "Dig", - "MoleVentCooldown": "Dig cooldown", - - "AddictVentButtonText": "Get Fix", - "AddictInvulnerbilityTimeAfterVent": "Invulnerability Time", - "AddictSpeedWhileInvulnerble": "Movement speed while Invulnerable", - - "AddictFreezeTimeAfterInvulnerbility": "Time the Addict gets frozen in place after Invulnerability", - "AlchemistShieldDur": "Resistance Potion Duration", - "AlchemistInvisDur": "Invisibility Potion Duration", - "AlchemistVision": "Night Vision", - "AlchemistVisionOnLightsOut": "Night Vision During Lights Sabotage", - "AlchemistVisionDur": "Night Vision Potion Duration", - "AlchemistSpeed": "Speed Potion Boost", - "AlchemistVentButtonText": "Drink", - "AlchemistGotShieldPotion": "Potion of Resistance: Grants a temporary shield", - "AlchemistGotSightPotion": "Potion of Night Vision: Gives temporary enhanced vision", - "AlchemistGotQFPotion": "Potion of Fixing: Allows you to fix one sabotage instantly", - "AlchemistGotTPPotion": "Potion of Warping: Teleports you to a random player", - "AlchemistGotSuicidePotion": "Potion of Poison: Poisons you", - "AlchemistGotSpeedPotion": "Potion Of Speed: Hastens you", - "AlchemistGotBloodthirstPotion": "Potion of Harming: Kill the next player you touch", - "AlchemistGotInvisibility": "Potion of Invisibility: Become Invisible", - "NoPotion": "You have no potions", - - "StoreShield": "Potion of Resistance", - "StoreSuicide": "Potion of Poison", - "StoreTP": "Potion of Warping", - "StoreSP": "Potion Of Speed", - "StoreQF": "Potion of Fixing", - "StoreBL": "Potion of Harming", - "StoreNS": "Potion of Night Vision", - "StoreINV": "Potion of Invisibility", - "StoreNull": "None", - "PotionStore": "Potion in store: ", - "WaitQFPotion": "\nPotion of Fixing waiting for use", - - "AlchemistShielded": "Potion of Resistance started", - "AlchemistHasVision": "Potion of Night Vision started", - "AlchemistShieldOut": "Potion of Resistance ended", - "AlchemistVisionOut": "Potion of Night Vision ended", - "AlchemistPotionBloodthirst": "You gained bloodthirst", - "AlchemistHasSpeed": "Potion Of Speed started", - "AlchemistSpeedOut": "Potion Of Speed ended", - - "DeathpactDuration": "Death Pact duration", - "DeathPactCooldown": "Death Pact Assign Cooldown", - "DeathpactNumberOfPlayersInPact": "Number of players in Death Pact", - "DeathpactShowArrowsToOtherPlayersInPact": "Show arrows leading to other players in Death Pact", - "DeathpactReduceVisionWhileInPact": "Reduce vision for players in Death Pact", - "DeathpactVisionWhileInPact": "Vision for players in Death Pact", - "DeathpactKillPlayersInDeathpactOnMeeting": "Kill players in Death Pact on meeting", - "DeathpactPlayersInDeathpactCanCallMeeting": "Players in active Death Pact can call meeting", - "DeathpactActiveDeathpact": "Find {0} in {1} seconds.", - "DeathpactCouldNotAddTarget": "Target can't be added to Death Pact.", - "DeathpactComplete": "Death Pact was concluded.", - "DeathpactExecuted": "Death Pact was executed.", - "DeathpactAverted": "Death Pact was averted.", - "DeathpactButtonText": "Assign", - "DevourerHideNameConsumed": "Hide the names of consumed players", - "DevourCooldown": "Devour Cooldown", - "DevourerButtonText": "Devour", - "DollMasterPossessionButtonText": "Possess", - "DollMasterUnPossessionButtonText": "UnPossess", - "DollMaster_PossessedTarget": "Possessed target", - "DollMaster_CannotPossessImpTeammate": "Unable to possess teammate", - "DollMaster_CouldNotSwapWithTarget": "Unable to possess player", - "DollMaster_CanNotSwapWithDeadTarget": "Possesing a dead player isn't possible", - "DollMaster_MainBody": "Main Body", - "DollMaster_Doll": "Doll", - "DollMaster_UnableToUseAbility": "Unable to use your ability on player", - "Doppelganger_RoleInfo": "Spoofed Role: {0}", - "EatenByDevourer": "The Devourer ate your skin", - "DevourerEatenSkin": "Target skin is eaten", - "DevouredName": "Devoured", - "PitfallTrapCooldown": "Trap Cooldown", - "PitfallMaxTrapCount": "Number of Traps that can be set", - "PitfallTrapMaxPlayerCount": "Number of Players that can be caught per Trap", - "PitfallTrapDuration": "Time the Trap remains active", - "PitfallTrapRadius": "Trap Radius", - "PitfallTrapFreezeTime": "Trap freeze time", - "PitfallTrapCauseVision": "Trap caused vision", - "PitfallTrapCauseVisionTime": "Trap caused vision time", - "PitfallTrap": "You have fallen into a trap!", - "ConsigliereDivinationMaxCount": "Maximum Reveals", - "RitualMaxCount": "Maximum Reveals", - "CleanserHideVote": "Hide Cleanser's vote", - "OracleSkillLimit": "Maximum Uses", - "OracleHideVote": "Hide Oracle's vote", - "OracleCheckReachLimit": "You're out of uses!", - "OracleCheckSelfMsg": "You can't even trust yourself, huh?", - "OracleCheckLimit": "Reminder: You have {0} uses left", - "OracleCheckMsgTitle": "ORACLE ", - "OracleCheck.NotCrewmate": "Appears not to be a crewmate", - "OracleCheck.Crewmate": "Appears to be a crewmate", - "OracleCheck.Neutral": "Appears to be a neutral", - "OracleCheck.Impostor": "Appears to be an Impostor", - "OracleCheck": "Target Results:", - "FailChance": "Chance of showing incorrect result", - "OracleCheckAddons": "Oracle checks add-ons", - "ChameleonCanVent": "Vent to disguise", - "ChameleonInvisState": "You are disguising!", - "ChameleonInvisStateOut": "Your disguise ended", - "ChameleonInvisInCooldown": "Ability still on cooldown, disguise failed", - "ChameleonInvisStateCountdown": "Disguise will expire in {0}s", - "ChameleonInvisCooldownRemain": "Disguise Cooldown: {0}s", - "ChameleonCooldown": "Disguise Cooldown", - "ChameleonDuration": "Disguise Duration", - "ChameleonRevertDisguise": "Expose", - "ChameleonDisguise": "Disguise", - "KillCooldownAfterCleaning": "Kill Cooldown On Clean", - "KillCooldownAfterStoneGazing": "Kill Cooldown On Stone Gaze", - "MedusaStoneBody": "Body stoned", - "MedusaReportButtonText": "Stone", - - "CursedSoulCurseCooldown": "Soul Snatch Cooldown", - "CursedSoulCurseCooldownIncrese": "Soul Snatch Cooldown Increase", - "CursedSoulCurseMax": "Maximum Soul Snatches", - "CursedSoulKnowTargetRole": "Know the roles of Soulless players", - "CursedSoulCanCurseNeutral": "Neutral roles have souls", - "CursedSoulKillButtonText": "Snatch", - "SoullessByCursedSoul": "A Cursed Soul snatched your soul", - "CursedSoulSoullessPlayer": "Soul snatched", - "CursedSoulInvalidTarget": "No soul found", - - "AdmireCooldown": "Admire Cooldown", - "AdmirerKnowTargetRole": "Know the roles of Admired players", - "AdmirerSkillLimit": "Skill Limit", - "AdmireButtonText": "Admire", - "AdmirerAdmired": "The Admirer admired you!", - "AdmiredPlayer": "Player admired", - "AdmirerInvalidTarget": "Target cannot be admired", - - "SpiritualistNoticeTitle": "SPIRITUALIST ", - "SpiritualistNoticeMessage": "The Spiritualist has an arrow pointing to you!\nYou can use them to a killer or frame a crewmate", - "SpiritualistShowGhostArrowForSeconds": "Ghost arrow duration", - "SpiritualistShowGhostArrowEverySeconds": "Ghost arrow interval", - "EnigmaClueStage1Tasks": "Number of Tasks to complete to see Stage 1 Clues", - "EnigmaClueStage2Tasks": "Number of Tasks to complete to see Stage 2 Clues", - "EnigmaClueStage3Tasks": "Number of Tasks to complete to see Stage 3 Clues", - "EnigmaClueStage2Probability": "Probability to see Stage 2 Clues", - "EnigmaClueStage3Probability": "Probability to see Stage 3 Clues", - "EnigmaClueGetCluesWithoutReporting": "Enigma can get Clues without reporting a dead body", - "EnigmaClueHat1": "The Killer wears a Hat!", - "EnigmaClueHat2": "The Killer does not wear a Hat!", - "EnigmaClueHat3": "The Killer wears {0} as a Hat!", - "EnigmaClueSkin1": "The Killer wears a Skin!", - "EnigmaClueSkin2": "The Killer does not wear a Skin!", - "EnigmaClueSkin3": "The Killer wears {0} as a Skin!", - "EnigmaClueVisor1": "The Killer wears a Visor!", - "EnigmaClueVisor2": "The Killer does not wear a Visor!", - "EnigmaClueVisor3": "The Killer wears {0} as a Visor!", - "EnigmaCluePet1": "The Killer does have a Pet!", - "EnigmaCluePet2": "The Killer does not have a Pet!", - "EnigmaCluePet3": "The Killer has {0} as a Pet!", - "EnigmaClueName1": "The Name of the Killer contains the letter {0} or the letter {1}!", - "EnigmaClueName2": "The Name of the Killer contains the letter {0}!", - "EnigmaClueName3": "The Name of the Killer contains the letter {0} and the letter {1}!", - "EnigmaClueNameLength1": "The Name of the Killer has a Length between {0} and {1} letters!", - "EnigmaClueNameLength2": "The Name of the Killer has a Length of {0} letters!", - "EnigmaClueColor1": "The Killer has a light color!", - "EnigmaClueColor2": "The Killer has a dark color!", - "EnigmaClueColor3": "The Killer's color is {0}!", - "EnigmaClueLocation": "The Last Room the Killer was in is {0}!", - "EnigmaClueStatus1": "The Killer is currently inside a Vent!", - "EnigmaClueStatus2": "The Killer is currently on a Ladder!", - "EnigmaClueStatus3": "The Killer is already Dead!", - "EnigmaClueStatus4": "The Killer is still Alive!", - "EnigmaClueRole1": "The Killer is an Impostor!", - "EnigmaClueRole2": "The Killer is a Neutral!", - "EnigmaClueRole3": "The Killer is a Crewmate!", - "EnigmaClueRole4": "The Killer's Role is {0}!", - "EnigmaClueLevel1": "The Killer's Level is above 50!", - "EnigmaClueLevel2": "The Killer's Level is below 50!", - "EnigmaClueLevel3": "The Killer's Level is between {0} and {1}!", - "EnigmaClueLevel4": "The Killer's Level is {0}!", - "EnigmaClueFriendCode": "The Killer's Friendcode is {0}!", - "EnigmaClueHatTitle": "Enigma Hat Clue!", - "EnigmaClueVisorTitle": "Enigma Visor Clue!", - "EnigmaClueSkinTitle": "Enigma Skin Clue!", - "EnigmaCluePetTitle": "Enigma Pet Clue!", - "EnigmaClueNameTitle": "Enigma Name Clue!", - "EnigmaClueNameLengthTitle": "Enigma Name Length Clue!", - "EnigmaClueColorTitle": "Enigma Color Clue!", - "EnigmaClueLocationTitle": "Enigma Location Clue!", - "EnigmaClueStatusTitle": "Enigma Status Clue!", - "EnigmaClueRoleTitle": "Enigma Role Clue!", - "EnigmaClueLevelTitle": "Enigma Level Clue!", - "EnigmaClueFriendCodeTitle": "Enigma Friendcode Clue!", - - "ImpCanBeRole": "Impostors can become {role}", - "CrewCanBeRole": "Crewmates can become {role}", - "NeutralCanBeRole": "Neutrals can become {role}", - - "VotesPerKill": "Votes gained for each kill", - "PickpocketGetVote": "You've got {0} votes", - "VultureArrowsPointingToDeadBody": "Arrows pointing to dead bodies", - "VultureNumberOfReportsToWin": "Bodies needed to win", - "VultureReportBody": "Body eaten!", - "VultureEatButtonText": "Consume", - "VultureReportCooldown": "Eat Cooldown", - "VultureMaxEatenInOneRound": "Maximum eaten bodies possible per round", - "VultureCooldownUp": "Eat Cooldown finished", - - "GhastlyPossessCD": "Possess Cooldown", - "GhastlyMaxPossessions": "Max Possessions", - "GhastlyPossessionDuration": "Possession Duration", - "GhastlySpeed": "Ghastly Speed", - "GhastlyKillAllies": "Ghastly cannot possess allies", - "GhastlyCannotPossessTarget": "Couldn't Possess Target", - "GhastlyChooseTarget": "Now: Choose Target", - "GhastlyNoMorePossess": "You've run out of possessions!'", - "GhastlyNotUrTarget": "That is not your target", - "GhastlyYouvePosses": "You've Been Possessed!", - "GhastlyPossessedUser": "You have possessed: {0}", - "GhastlyExpired": "{0} is no longer possessed", - - "TasksMarkPerRound": "Number of tasks that can be marked in one round", - "TaskinatorBombPlanted": "Bomb has been planted", - - "ShieldDuration": "Shield duration", - "ShieldIsOneTimeUse": "Shield breaks after one kill attempt", - "BenefactorTaskMarked": "Task marked successfully", - "BenefactorTargetGotShield": "You got a shield by Benefactor", - - "PirateTryHideMsg": "Hide Pirate's commands", - "SuccessfulDuelsToWin": "Number of successful duels needed to win", - "PirateMeetingMsg": "Duel with your target.\n\nDuel command:\n⦿ /duel 0\n⦿ /duel 1\n⦿ /duel 2\n\nYou win the Duel if you choose the same option as the target", - "PirateTargetMeetingMsg": "The Pirate chose t' duel ye!\nDuel wit' honor or die o' shame.\n\n Duel command:\n⦿ /duel 0\n⦿ /duel 1\n⦿ /duel 2\n\nIf the Pirate chooses the same option as you or you don't participate, you'll die", - "PirateTitle": "PIRATE ", - "PirateTargetAlreadyChosen": "Yarr! Ye've already chosen a target.", - "PirateDead": "Ye be dead. Ye cannot duel anymore.", - "DuelAlreadyDone": "Ye 'ave already chosen an option fer the duel.", - "DuelDone": "Ye 'ave chosen yer option fer the Duel.\nWait fer the meetin' to end to see the result.", - "DuelHelp": "Duel command:\n⦿ /duel 0\n⦿ /duel 1\n⦿ /duel 2\n\nAs Pirate, try to choose the same number as the target.\nAs the target, try to choose a different number than the Pirate", - "PirateDuelButtonText": "Duel", - "DuelCooldown": "Duel Cooldown", - "Rock": "Rock", - "Paper": "Paper", - "Scissors": "Scissors", - "Heads": "Heads", - "Tails": "Tails", - "SpyRedNameDur": "Colored Name Duration", - "SpyInteractionBlocked": "Block kill button interaction", - "AgitaterBombCooldown": "Agitator bomb cooldown", - "AgitaterPassCooldown": "Bomb pass cooldown", - "BombExplodeCooldown": "Bomb explode cooldown", - "AgitaterPassNotify": "Bomb successfully passed", - "AgitaterTargetNotify": "YOU HAVE THE BOMB!! Pass it to someone else", - "AgitaterCanGetBombed": "Agitator can get bomb", - "AgitaterAutoReportBait": "Agitator Auto Report Bait", - - "SeekerPointsToWin": "Number of points required to win", - "SeekerTagCooldown": "Tag Cooldown", - "SeekerNotify": "Your target is {0}", - "SeekerTargetNotify": "You are Seekers target!! Hide before they tag you", - "SeekerKillButtonText": "Tag", - - "PixiePointsToWin": "Number of points required to win", - "MaxTargets": "Maximum number of targets per round", - "MarkCooldown": "Mark cooldown", - "PixieSuicide": "Pixie suicides if the target is not voted out", - "PixieMaxTargetReached": "You have already selected all the targets this round", - "PixieTargetAlreadySelected": "Target is already selected", - "PixieButtonText": "Mark", - - "PlagueBearerCooldown": "Plague cooldown", + "RememberedImitator": "You remembered you were an Imitator.", + "RememberedImpostor": "You remembered you were an Impostor!", + "RememberedCrewmate": "You remembered you were a crewmate!", + "ImitatorImitated": "An Imitator imitated your role!", + "ImitatorInvalidTarget": "Imitation failed", + "RememberButtonText": "Remember", + "ImitatorKillButtonText": "Imitate", + "IncompatibleNeutralMode": "If neutral is incompatible, turn into", + "RememberedYourRole": "An Amnesiac remembered your role!", + "YouRememberedRole": "You remembered who you were!", + + "BanditStealMode": "Steal Mode", + "BanditStealMode_OnMeeting": "On Meeting", + "BanditStealMode_Instantly": "Instantly", + "BanditMaxSteals": "Maximum Steals", + "BanditCanStealBetrayalAddon": "Can Steal Betrayal Add-ons", + "BanditCanStealImpOnlyAddon": "Can Steal Impostor Only Addons", + "Bandit_NoStealableAddons": "Could not steal add-on from the player", + "BanditStealCooldown": "Steal cooldown", + + "DoppelMaxSteals": "Maximum Steals", + "DoppelCurrentVictimCanSeeRolesAsDead": "Last victim can see role and add-on info of alive players as a ghost", + + "NecromancerRevengeTime": "Necromancy time", + "NecromancerRevenge": "You have {0}s to kill {1}", + "NecromancerSuccess": "Necromancy complete! You live to see another day.", + "NecromancerHide": "Venting is disabled, hide from the Necromancer!", + "RetributionistDeadMsg": "The death of the Retributionist means the beginning of retribution. \nPlease use /ret + [player ID] to kill the specified player \nYou can see player IDs in front of their names. \nOr type /ret to get a list of player IDs", + "RetributionistAliveKill": "Retribution for the Retributionist may only begin after their death.", + "RetributionistKillMax": "You've reached the maximum amount of kills. You can't kill anymore!", + "RetributionistKillDead": "Choose a living player to kill.", + "RetributionistKillSucceed": "{0} was killed by the Retributionist!", + "RetributionistKillDisable": "You can't retribute until your tasks are done.", + "CanOnlyRetributeWithTasksDone": "Can only retribute on task completion", + "RetributionistCanKillNum": "Max retributions", + "RetributionistKillTooManyDead": "Too many players are dead. You can't retribute.", + "MinimumPlayersAliveToRetri": "Minimum players alive to retribute", + "MinimumNoKillerEjectsToKill": "Minimum meetings passed with no killer ejects to kill", + "ImmuneToAttacksWhenTasksDone": "Immune to attacks on task completion", + + "TwisterCooldown": "Twist Cooldown", + "TwisterButtonText": "Twist", + "TwisterHideTwistedPlayerNames": "Hide who the players swap places with", + "InstigatorAbilityLimit": "Ability Use Count", + "InstigatorKillsPerAbilityUse": "Kills per Ability use", + + "CrewCanFindCaptain": "Crewmates can find Captain", + "MadmateCanFindCaptain": "Madmates can find Captain", + "ReducedSpeed": "Reduced speed", + "ReducedSpeedTime": "Time duration for reduced speed", + "CaptainCanTargetNB": "Captain can target Neutral Benign", + "CaptainCanTargetNE": "Captain can target Neutral Evil", + "CaptainCanTargetNC": "Captain can target Neutral Chaos", + "CaptainCanTargetNA": "Captain can target Neutral Apocalypse", + "CaptainCanTargetNK": "Captain can target Neutral Killer", + "CaptainSpeedReduced": "Captain reduced your speed", + "CaptainRevealTaskRequired": "Number of tasks completed after which Captain is revealed", + "CaptainSlowTaskRequired": "Number of tasks completed after which target speed is reduced", + + "InspectorTryHideMsg": "Hide Inspector's commands", + "MaxInspectCheckLimit": "Max inspections per game", + "InspectCheckLimitPerMeeting": "Max inspections per meeting", + "InspectCheckTargetKnow": "Targets know they were checked by Inspector", + "InspectCheckOtherTargetKnow": "Targets know who they were checked with", + "InspectorDead": "You can not use your power after death", + "InspectCheckMax": "Max inspections per game reached!\nYou can not use your power anymore.", + "InspectCheckRound": "Max inspections per round reached!\nYou can check again in the next round.", + "InspectCheckSelf": "HA!! You thought it would be this easy. You can not check yourself", + "InspectCheckReveal": "HA! You thought it would be this easy. You can not check a role that is revealed", + "InspectCheckTitle": "INSPECTOR ", + "InspectCheckTrue": "{0} and {1} are in the same team!", + "InspectCheckFalse": "{0} and {1} are NOT in the same team!", + "InspectCheckTargetMsg": " were checked by Inspector.", + "InspectCheckHelp": "Instructions: /cmp [Player ID 1] [Player ID 2] \nExample: /cmp 1 5 \nYou can see the player IDs before everyone's names \n or use the /id command to list the player IDs", + "InspectCheckNull": "Please select an ID of a living player to check their team", + "InspectCheckBaitCountMode": "Bait counts as revealing role if Bait reveal on first meeting is on", + "InspectCheckRevealTarget": "When tasks are done, the target knows the team of the other target", + "InspectorTargetReveal": " Looks like {0} is aligned with team {1}", + + "EgoistCountMode.Original": "Original", + "EgoistCountMode.Neutral": "Neutral", + + "JailerJailCooldown": "Jail cooldown", + "JailerMaxExecution": "Maximum executions", + "JailerNBCanBeExe": "Can execute Neutral Benign", + "JailerNCCanBeExe": "Can execute Neutral Chaos", + "JailerNECanBeExe": "Can execute Neutral Evil", + "JailerNKCanBeExe": "Can execute Neutral Killing", + "JailerNACanBeExe": "Can execute Neutral Apocalypse", + "JailerCKCanBeExe": "Can execute Crew Killing", + "JailerTargetAlreadySelected": "You have already selected a target", + "SuccessfullyJailed": "Target successfully jailed", + "CantGuessJailed": "You can not guess the target", + "JailedCanOnlyGuessJailer": "You have been jailed. You can only guess Jailer.", + "CanNotTrialJailed": "You can not trial the target.", + "notifyJailedOnMeeting": "Notify jailed player when a meeting starts", + "JailedNotifyMsg": "The Jailer has jailed you. No one can guess or judge you. You can only guess The Jailer.\n\nIf Jailer votes you, you will be executed after the meeting ends.", + "JailerTitle": "Jailer", + + "CopyCatCopyCooldown": "Copy cooldown", + "CopyCatRoleChange": "Your role has been changed to {0}", + "CopyCatCanNotCopy": "You can not copy the target's role", + "CopyButtonText": "Copy", + "CopyCrewVar": "Can copy evil variants of crew roles", + "CopyTeamChangingAddon": "Can copy team changing add-on", + + "MaxCleanserUses": "Max cleanses", + "CleansedCanGetAddon": "Cleansed player can get Add-on", + "CleanserTitle": "CLEANSER", + "CleanserRemoveSelf": "You can not cleanse yourself", + "CleanserCantRemove": "Oops! the player can not be cleansed.", + "CleanserRemovedRole": "{0} has been cleansed. All their Add-ons will be removed after the meeting.\n\nYour vote has been returned and you can vote for someone.", + "LostAddonByCleanser": "The cleanser removed all your Add-ons", + + "MaxProtections": "Max protections", + "KeeperHideVote": "Hide Keeper's vote", + "KeeperProtect": "You chose to protect {0}, your vote has been returned", + "KeeperTitle": "Keeper", + + "MaulRadius": "Maul Radius", + "ImpKnowCyberDead": "Impostors know if Cyber died", + "CrewKnowCyberDead": "Crewmates know if Cyber died", + "NeutralKnowCyberDead": "Neutrals know if Cyber died", + "CyberKnown": "Everyone can see Cyber", + "KillerGetBewilderVision": "Killer gets Bewilder's vision", + "ImpCanBeOiiai": "Impostors can be OIIAI", + "CrewCanBeOiiai": "Crewmates can be OIIAI", + "NeutralCanBeOiiai": "Neutrals can be OIIAI", + "OiiaiCanPassOn": "OIIAI can pass on to the killer", + "NeutralChangeRolesForOiiai": "Neutrals turns to ", + "LostRoleByOiiai": "You got erased by OIIAI!", + "ImpCanBeLoyal": "Impostors can become Loyal", + "CrewCanBeLoyal": "Crewmates can become Loyal", + "TasklessCrewCanBeLazy": "Crewmates without tasks can be Lazy", + "TaskBasedCrewCanBeLazy": "Task based crewmates can be Lazy", + "SheriffCanBeMadmate": "Sheriff can become Madmate", + "MayorCanBeMadmate": "Mayor can become Madmate", + "NGuesserCanBeMadmate": "Nice Guesser can become Madmate", + "SnitchCanBeMadmate": "Snitch can become Madmate", + "JudgeCanBeMadmate": "Judge can become Madmate", + "MarshallCanBeMadmate": "Marshall can become Madmate", + "GanRetributionistCanBeMadmate": "Retributionist can be converted", + "RetributionistCanBeMadmate": "Retributionist can become Madmate", + "OverseerCanBeMadmate": "Overseer can become Madmate", + "GanSheriffCanBeMadmate": "Sheriff can be converted", + "GanMayorCanBeMadmate": "Mayor can be converted", + "GanNGuesserCanBeMadmate": "Nice Guesser can be converted", + "GanJudgeCanBeMadmate": "Judge can be converted", + "GanMarshallCanBeMadmate": "Marshall can be converted", + "GanOverseerCanBeMadmate": "Overseer can be converted", + "RascalAppearAsMadmate": "Appear As Madmate On Ejection", + + "CouncillorDead": "Sorry, you can't murder from the dead.", + "CouncillorMurderMaxMeeting": "Sorry, you've reached the maximum amount of murders for the meeting.", + "CouncillorMurderMaxGame": "Sorry, you've reached the maximum amount of murders for the game.", + "Councillor_LaughToWhoMurderSelf": "Hahaha, who would've thought someone was stupid enough to murder themselves?\n\nGuess it happens to be... YOU!", + "Councillor_MurderKill": "{0} was murdered.", + "Councillor_MurderHelp": "Command: /tl [player ID]\nYou can see the players' IDs before the players' names.\nOr use /id to view the list of all player IDs.", + "Councillor_MurderNull": "Please choose a living player to murder.", + "Councillor_MurderKillTitle": "WICKED COURT ", + "CouncillorMakeEvilJudgeClear": "Show Trial as Councillor Murder", + "Councillor_CannotMurderImpTeam": "Sorry, you can not murder your teammate.", + "Councillor_SuicideForMurderImps": "You died because you are trying to murder your team members.", + "CouncillorMurderLimitPerMeeting": "Maximum Kills Per Meeting", + "CouncillorMurderLimitPerGame": "Maximum Kills Per Game", + "CouncillorCanMurderMadmate": "Can Murder Madmates", + "CouncillorCanMurderImpostor": "Can Murder Impostors", + "CouncillorSuicideOnJudgeImpTeam": "Suicide when judge Impostors Team Wrongly", + "CouncillorCanMurderTaskDoneSnitch": "Can Murder Snitch with All Tasks Done", + "CouncillorTryHideMsg": "Try to hide Councillor's commands", + + "DazzlerDazzled": "You were dazzled by the Dazzler!", + "DazzlerCauseVision": "Reduced vision", + "DazzlerDazzleLimit": "Max number of players affected by reduced vision", + "DazzlerResetDazzledVisionOnDeath": "Reset vision of dazzled players on death/eject", + "DazzleCooldown": "Dazzle Cooldown", + "DazzleButtonText": "Dazzle", + + "MoleVentButtonText": "Dig", + "MoleVentCooldown": "Dig cooldown", + + "AddictVentButtonText": "Get Fix", + "AddictInvulnerbilityTimeAfterVent": "Invulnerability Time", + "AddictSpeedWhileInvulnerble": "Movement speed while Invulnerable", + + "AddictFreezeTimeAfterInvulnerbility": "Time the Addict gets frozen in place after Invulnerability", + "AlchemistShieldDur": "Resistance Potion Duration", + "AlchemistInvisDur": "Invisibility Potion Duration", + "AlchemistVision": "Night Vision", + "AlchemistVisionOnLightsOut": "Night Vision During Lights Sabotage", + "AlchemistVisionDur": "Night Vision Potion Duration", + "AlchemistSpeed": "Speed Potion Boost", + "AlchemistVentButtonText": "Drink", + "AlchemistGotShieldPotion": "Potion of Resistance: Grants a temporary shield", + "AlchemistGotSightPotion": "Potion of Night Vision: Gives temporary enhanced vision", + "AlchemistGotQFPotion": "Potion of Fixing: Allows you to fix one sabotage instantly", + "AlchemistGotTPPotion": "Potion of Warping: Teleports you to a random player", + "AlchemistGotSuicidePotion": "Potion of Poison: Poisons you", + "AlchemistGotSpeedPotion": "Potion Of Speed: Hastens you", + "AlchemistGotBloodthirstPotion": "Potion of Harming: Kill the next player you touch", + "AlchemistGotInvisibility": "Potion of Invisibility: Become Invisible", + "NoPotion": "You have no potions", + + "StoreShield": "Potion of Resistance", + "StoreSuicide": "Potion of Poison", + "StoreTP": "Potion of Warping", + "StoreSP": "Potion Of Speed", + "StoreQF": "Potion of Fixing", + "StoreBL": "Potion of Harming", + "StoreNS": "Potion of Night Vision", + "StoreINV": "Potion of Invisibility", + "StoreNull": "None", + "PotionStore": "Potion in store: ", + "WaitQFPotion": "\nPotion of Fixing waiting for use", + + "AlchemistShielded": "Potion of Resistance started", + "AlchemistHasVision": "Potion of Night Vision started", + "AlchemistShieldOut": "Potion of Resistance ended", + "AlchemistVisionOut": "Potion of Night Vision ended", + "AlchemistPotionBloodthirst": "You gained bloodthirst", + "AlchemistHasSpeed": "Potion Of Speed started", + "AlchemistSpeedOut": "Potion Of Speed ended", + + "DeathpactDuration": "Death Pact duration", + "DeathPactCooldown": "Death Pact Assign Cooldown", + "DeathpactNumberOfPlayersInPact": "Number of players in Death Pact", + "DeathpactShowArrowsToOtherPlayersInPact": "Show arrows leading to other players in Death Pact", + "DeathpactReduceVisionWhileInPact": "Reduce vision for players in Death Pact", + "DeathpactVisionWhileInPact": "Vision for players in Death Pact", + "DeathpactKillPlayersInDeathpactOnMeeting": "Kill players in Death Pact on meeting", + "DeathpactPlayersInDeathpactCanCallMeeting": "Players in active Death Pact can call meeting", + "DeathpactActiveDeathpact": "Find {0} in {1} seconds.", + "DeathpactCouldNotAddTarget": "Target can't be added to Death Pact.", + "DeathpactComplete": "Death Pact was concluded.", + "DeathpactExecuted": "Death Pact was executed.", + "DeathpactAverted": "Death Pact was averted.", + "DeathpactButtonText": "Assign", + "DevourerHideNameConsumed": "Hide the names of consumed players", + "DevourCooldown": "Devour Cooldown", + "DevourerButtonText": "Devour", + "DollMasterPossessionButtonText": "Possess", + "DollMasterUnPossessionButtonText": "UnPossess", + "DollMaster_PossessedTarget": "Possessed target", + "DollMaster_CannotPossessImpTeammate": "Unable to possess teammate", + "DollMaster_CouldNotSwapWithTarget": "Unable to possess player", + "DollMaster_CanNotSwapWithDeadTarget": "Possesing a dead player isn't possible", + "DollMaster_MainBody": "Main Body", + "DollMaster_Doll": "Doll", + "DollMaster_UnableToUseAbility": "Unable to use your ability on player", + "Doppelganger_RoleInfo": "Spoofed Role: {0}", + "EatenByDevourer": "The Devourer ate your skin", + "DevourerEatenSkin": "Target skin is eaten", + "DevouredName": "Devoured", + "PitfallTrapCooldown": "Trap Cooldown", + "PitfallMaxTrapCount": "Number of Traps that can be set", + "PitfallTrapMaxPlayerCount": "Number of Players that can be caught per Trap", + "PitfallTrapDuration": "Time the Trap remains active", + "PitfallTrapRadius": "Trap Radius", + "PitfallTrapFreezeTime": "Trap freeze time", + "PitfallTrapCauseVision": "Trap caused vision", + "PitfallTrapCauseVisionTime": "Trap caused vision time", + "PitfallTrap": "You have fallen into a trap!", + "ConsigliereDivinationMaxCount": "Maximum Reveals", + "RitualMaxCount": "Maximum Reveals", + "CleanserHideVote": "Hide Cleanser's vote", + "OracleSkillLimit": "Maximum Uses", + "OracleHideVote": "Hide Oracle's vote", + "OracleCheckReachLimit": "You're out of uses!", + "OracleCheckSelfMsg": "You can't even trust yourself, huh?", + "OracleCheckLimit": "Reminder: You have {0} uses left", + "OracleCheckMsgTitle": "ORACLE ", + "OracleCheck.NotCrewmate": "Appears not to be a crewmate", + "OracleCheck.Crewmate": "Appears to be a crewmate", + "OracleCheck.Neutral": "Appears to be a neutral", + "OracleCheck.Impostor": "Appears to be an Impostor", + "OracleCheck": "Target Results:", + "FailChance": "Chance of showing incorrect result", + "OracleCheckAddons": "Oracle checks add-ons", + "ChameleonCanVent": "Vent to disguise", + "ChameleonInvisState": "You are disguising!", + "ChameleonInvisStateOut": "Your disguise ended", + "ChameleonInvisInCooldown": "Ability still on cooldown, disguise failed", + "ChameleonInvisStateCountdown": "Disguise will expire in {0}s", + "ChameleonInvisCooldownRemain": "Disguise Cooldown: {0}s", + "ChameleonCooldown": "Disguise Cooldown", + "ChameleonDuration": "Disguise Duration", + "ChameleonRevertDisguise": "Expose", + "ChameleonDisguise": "Disguise", + "KillCooldownAfterCleaning": "Kill Cooldown On Clean", + "KillCooldownAfterStoneGazing": "Kill Cooldown On Stone Gaze", + "MedusaStoneBody": "Body stoned", + "MedusaReportButtonText": "Stone", + + "CursedSoulCurseCooldown": "Soul Snatch Cooldown", + "CursedSoulCurseCooldownIncrese": "Soul Snatch Cooldown Increase", + "CursedSoulCurseMax": "Maximum Soul Snatches", + "CursedSoulKnowTargetRole": "Know the roles of Soulless players", + "CursedSoulCanCurseNeutral": "Neutral roles have souls", + "CursedSoulKillButtonText": "Snatch", + "SoullessByCursedSoul": "A Cursed Soul snatched your soul", + "CursedSoulSoullessPlayer": "Soul snatched", + "CursedSoulInvalidTarget": "No soul found", + + "AdmireCooldown": "Admire Cooldown", + "AdmirerKnowTargetRole": "Know the roles of Admired players", + "AdmirerSkillLimit": "Skill Limit", + "AdmireButtonText": "Admire", + "AdmirerAdmired": "The Admirer admired you!", + "AdmiredPlayer": "Player admired", + "AdmirerInvalidTarget": "Target cannot be admired", + + "SpiritualistNoticeTitle": "SPIRITUALIST ", + "SpiritualistNoticeMessage": "The Spiritualist has an arrow pointing to you!\nYou can use them to a killer or frame a crewmate", + "SpiritualistShowGhostArrowForSeconds": "Ghost arrow duration", + "SpiritualistShowGhostArrowEverySeconds": "Ghost arrow interval", + "EnigmaClueStage1Tasks": "Number of Tasks to complete to see Stage 1 Clues", + "EnigmaClueStage2Tasks": "Number of Tasks to complete to see Stage 2 Clues", + "EnigmaClueStage3Tasks": "Number of Tasks to complete to see Stage 3 Clues", + "EnigmaClueStage2Probability": "Probability to see Stage 2 Clues", + "EnigmaClueStage3Probability": "Probability to see Stage 3 Clues", + "EnigmaClueGetCluesWithoutReporting": "Enigma can get Clues without reporting a dead body", + "EnigmaClueHat1": "The Killer wears a Hat!", + "EnigmaClueHat2": "The Killer does not wear a Hat!", + "EnigmaClueHat3": "The Killer wears {0} as a Hat!", + "EnigmaClueSkin1": "The Killer wears a Skin!", + "EnigmaClueSkin2": "The Killer does not wear a Skin!", + "EnigmaClueSkin3": "The Killer wears {0} as a Skin!", + "EnigmaClueVisor1": "The Killer wears a Visor!", + "EnigmaClueVisor2": "The Killer does not wear a Visor!", + "EnigmaClueVisor3": "The Killer wears {0} as a Visor!", + "EnigmaCluePet1": "The Killer does have a Pet!", + "EnigmaCluePet2": "The Killer does not have a Pet!", + "EnigmaCluePet3": "The Killer has {0} as a Pet!", + "EnigmaClueName1": "The Name of the Killer contains the letter {0} or the letter {1}!", + "EnigmaClueName2": "The Name of the Killer contains the letter {0}!", + "EnigmaClueName3": "The Name of the Killer contains the letter {0} and the letter {1}!", + "EnigmaClueNameLength1": "The Name of the Killer has a Length between {0} and {1} letters!", + "EnigmaClueNameLength2": "The Name of the Killer has a Length of {0} letters!", + "EnigmaClueColor1": "The Killer has a light color!", + "EnigmaClueColor2": "The Killer has a dark color!", + "EnigmaClueColor3": "The Killer's color is {0}!", + "EnigmaClueLocation": "The Last Room the Killer was in is {0}!", + "EnigmaClueStatus1": "The Killer is currently inside a Vent!", + "EnigmaClueStatus2": "The Killer is currently on a Ladder!", + "EnigmaClueStatus3": "The Killer is already Dead!", + "EnigmaClueStatus4": "The Killer is still Alive!", + "EnigmaClueRole1": "The Killer is an Impostor!", + "EnigmaClueRole2": "The Killer is a Neutral!", + "EnigmaClueRole3": "The Killer is a Crewmate!", + "EnigmaClueRole4": "The Killer's Role is {0}!", + "EnigmaClueLevel1": "The Killer's Level is above 50!", + "EnigmaClueLevel2": "The Killer's Level is below 50!", + "EnigmaClueLevel3": "The Killer's Level is between {0} and {1}!", + "EnigmaClueLevel4": "The Killer's Level is {0}!", + "EnigmaClueFriendCode": "The Killer's Friendcode is {0}!", + "EnigmaClueHatTitle": "Enigma Hat Clue!", + "EnigmaClueVisorTitle": "Enigma Visor Clue!", + "EnigmaClueSkinTitle": "Enigma Skin Clue!", + "EnigmaCluePetTitle": "Enigma Pet Clue!", + "EnigmaClueNameTitle": "Enigma Name Clue!", + "EnigmaClueNameLengthTitle": "Enigma Name Length Clue!", + "EnigmaClueColorTitle": "Enigma Color Clue!", + "EnigmaClueLocationTitle": "Enigma Location Clue!", + "EnigmaClueStatusTitle": "Enigma Status Clue!", + "EnigmaClueRoleTitle": "Enigma Role Clue!", + "EnigmaClueLevelTitle": "Enigma Level Clue!", + "EnigmaClueFriendCodeTitle": "Enigma Friendcode Clue!", + + "ImpCanBeRole": "Impostors can become {role}", + "CrewCanBeRole": "Crewmates can become {role}", + "NeutralCanBeRole": "Neutrals can become {role}", + + "VotesPerKill": "Votes gained for each kill", + "PickpocketGetVote": "You've got {0} votes", + "VultureArrowsPointingToDeadBody": "Arrows pointing to dead bodies", + "VultureNumberOfReportsToWin": "Bodies needed to win", + "VultureReportBody": "Body eaten!", + "VultureEatButtonText": "Consume", + "VultureReportCooldown": "Eat Cooldown", + "VultureMaxEatenInOneRound": "Maximum eaten bodies possible per round", + "VultureCooldownUp": "Eat Cooldown finished", + + "GhastlyPossessCD": "Possess Cooldown", + "GhastlyMaxPossessions": "Max Possessions", + "GhastlyPossessionDuration": "Possession Duration", + "GhastlySpeed": "Ghastly Speed", + "GhastlyKillAllies": "Ghastly cannot possess allies", + "GhastlyCannotPossessTarget": "Couldn't Possess Target", + "GhastlyChooseTarget": "Now: Choose Target", + "GhastlyNoMorePossess": "You've run out of possessions!'", + "GhastlyNotUrTarget": "That is not your target", + "GhastlyYouvePosses": "You've Been Possessed!", + "GhastlyPossessedUser": "You have possessed: {0}", + "GhastlyExpired": "{0} is no longer possessed", + + "TasksMarkPerRound": "Number of tasks that can be marked in one round", + "TaskinatorBombPlanted": "Bomb has been planted", + + "ShieldDuration": "Shield duration", + "ShieldIsOneTimeUse": "Shield breaks after one kill attempt", + "BenefactorTaskMarked": "Task marked successfully", + "BenefactorTargetGotShield": "You got a shield by Benefactor", + + "PirateTryHideMsg": "Hide Pirate's commands", + "SuccessfulDuelsToWin": "Number of successful duels needed to win", + "PirateMeetingMsg": "Duel with your target.\n\nDuel command:\n⦿ /duel 0\n⦿ /duel 1\n⦿ /duel 2\n\nYou win the Duel if you choose the same option as the target", + "PirateTargetMeetingMsg": "The Pirate chose t' duel ye!\nDuel wit' honor or die o' shame.\n\n Duel command:\n⦿ /duel 0\n⦿ /duel 1\n⦿ /duel 2\n\nIf the Pirate chooses the same option as you or you don't participate, you'll die", + "PirateTitle": "PIRATE ", + "PirateTargetAlreadyChosen": "Yarr! Ye've already chosen a target.", + "PirateDead": "Ye be dead. Ye cannot duel anymore.", + "DuelAlreadyDone": "Ye 'ave already chosen an option fer the duel.", + "DuelDone": "Ye 'ave chosen yer option fer the Duel.\nWait fer the meetin' to end to see the result.", + "DuelHelp": "Duel command:\n⦿ /duel 0\n⦿ /duel 1\n⦿ /duel 2\n\nAs Pirate, try to choose the same number as the target.\nAs the target, try to choose a different number than the Pirate", + "PirateDuelButtonText": "Duel", + "DuelCooldown": "Duel Cooldown", + "Rock": "Rock", + "Paper": "Paper", + "Scissors": "Scissors", + "Heads": "Heads", + "Tails": "Tails", + "SpyRedNameDur": "Colored Name Duration", + "SpyInteractionBlocked": "Block kill button interaction", + "AgitaterBombCooldown": "Agitator bomb cooldown", + "AgitaterPassCooldown": "Bomb pass cooldown", + "BombExplodeCooldown": "Bomb explode cooldown", + "AgitaterPassNotify": "Bomb successfully passed", + "AgitaterTargetNotify": "YOU HAVE THE BOMB!! Pass it to someone else", + "AgitaterCanGetBombed": "Agitator can get bomb", + "AgitaterAutoReportBait": "Agitator Auto Report Bait", + + "SeekerPointsToWin": "Number of points required to win", + "SeekerTagCooldown": "Tag Cooldown", + "SeekerNotify": "Your target is {0}", + "SeekerTargetNotify": "You are Seekers target!! Hide before they tag you", + "SeekerKillButtonText": "Tag", + + "PixiePointsToWin": "Number of points required to win", + "MaxTargets": "Maximum number of targets per round", + "MarkCooldown": "Mark cooldown", + "PixieSuicide": "Pixie suicides if the target is not voted out", + "PixieMaxTargetReached": "You have already selected all the targets this round", + "PixieTargetAlreadySelected": "Target is already selected", + "PixieButtonText": "Mark", + + "PlagueBearerCooldown": "Plague cooldown", "PlagueBearerCanVent": "Can vent", "PlagueBearerHasImpostorVision": "Has Impostor vision", - "PestilenceCooldown": "Pestilence Kill cooldown", - "PestilenceCanVent": "Pestilence Can Vent", - "PestilenceHasImpostorVision": "Pestilence Has Impostor Vision", - "PestilenceKillGuessers": "Kill players who guess Pestilence", - "PlagueBearerAlreadyPlagued": "Player has already been plagued", - "PlagueBearerToPestilence": "You have turned into Pestilence!!", - "GuessPestilence": "You just tried to guess Pestilence!\n\nSorry, Pestilence killed you.", - "PestilenceTransform": "A Plague has consumed the Crew, transforming the Plaguebearer into Pestilence, Horseman of the Apocalypse!", - "RomanticBetCooldown": "Pick Partner Cooldown", - "RomanticProtectCooldown": "Protect Cooldown", - "RomanticBetPlayer": "You picked your partner", - "RomanticBetOnYou": "The Romantic chose you as their Partner!", - "VengefulKCD": "Vengeful Romantic Kill Cooldown", - "VengefulCanVent": "Vengeful Romantic Can Vent", - "RuthlessKCD": "Ruthless Romantic Kill Cooldown", - "RuthlessCanVent": "Ruthless Romantic Can Vent", - "RomanticProtectPartner": "Your partner is under protection", - "RomanticIsProtectingYou": "The Romantic is protecting you", - "ProtectingOver": "Shield expired", - "RomanticProtectDuration": "Protect Duration", - "RomanticKnowTargetRole": "Romantic knows their target's role", - "RomanticBetTargetKnowRomantic": "Target knows who the Romantic is", - "RomanticPartnerButtonText": "Pick Partner", - "RomanticProtectButtonText": "Protect", - - "GuessMasterMisguess": "{0} misguessed", - "GuessMasterTargetRole": "Someone tried to guess {0}", - "GuessMasterTitle": "Guess Master ", - - "DoomsayerAmountOfGuessesToWin": "Amount of Guesses to win", - "DCanGuessImpostors": "Can Guess Impostors", - "DCanGuessCrewmates": "Can Guess Crewmates", - "DCanGuessNeutrals": "Can Guess Neutrals", - "DCanGuessAdt": "Can Guess Add-Ons", - "DoomsayerAdvancedSettings": "Advanced Settings", - "DoomsayerMaxNumberOfGuessesPerMeeting": "Max number of guesses per meeting", - "DoomsayerKillCorrectlyGuessedPlayers": "Kill correctly guessed players", - "DoomsayerDoesNotSuicideWhenMisguessing": "Doomsayer does not suicide when misguessing", - "DoomsayerMisguessRolePrevGuessRoleUntilNextMeeting": "Misguessing role prevents guessing roles until next meeting", - "DoomsayerTryHideMsg": "Hide Doomsayer's commands", - "DoomsayerCantGuess": "Sorry, you can only guess the roles in the next meeting.", - "DoomsayerCorrectlyGuessRole": "You guessed the role correctly!\nBut the player didn't die because the Host settings don't allow them to die", - "DoomsayerNotCorrectlyGuessRole": "You didn't correctly guess the role!\nBut you didn't die because the Host's settings don't allow you to die", - "DoomsayerGuessCountMsg": "You correctly guessed {0} roles", - "DoomsayerGuessCountTitle": "DOOMSAYER", - "DoomsayerGuessSameRoleAgainMsg": "You tried to guess the same role or add-on that you guessed before", - - "EveryoneCanKnowMini": "Everyone can see the Mini", - "CanBeEvil": "Mini can be an Impostor", - "EvilMiniSpawnChances": "Probability of Mini being an Impostor", + "PestilenceCooldown": "Pestilence Kill cooldown", + "PestilenceCanVent": "Pestilence Can Vent", + "PestilenceHasImpostorVision": "Pestilence Has Impostor Vision", + "PlagueBearerAlreadyPlagued": "Player has already been plagued", + "PlagueBearerToPestilence": "You have turned into Pestilence!!", + "GuessPestilence": "You just tried to guess Pestilence!\n\nSorry, Pestilence killed you.", + "PestilenceTransform": "A Plague has consumed the Crew, transforming the Plaguebearer into Pestilence, Horseman of the Apocalypse!", + "RomanticBetCooldown": "Pick Partner Cooldown", + "RomanticProtectCooldown": "Protect Cooldown", + "RomanticBetPlayer": "You picked your partner", + "RomanticBetOnYou": "The Romantic chose you as their Partner!", + "VengefulKCD": "Vengeful Romantic Kill Cooldown", + "VengefulCanVent": "Vengeful Romantic Can Vent", + "RuthlessKCD": "Ruthless Romantic Kill Cooldown", + "RuthlessCanVent": "Ruthless Romantic Can Vent", + "RomanticProtectPartner": "Your partner is under protection", + "RomanticIsProtectingYou": "The Romantic is protecting you", + "ProtectingOver": "Shield expired", + "RomanticProtectDuration": "Protect Duration", + "RomanticKnowTargetRole": "Romantic knows their target's role", + "RomanticBetTargetKnowRomantic": "Target knows who the Romantic is", + "RomanticPartnerButtonText": "Pick Partner", + "RomanticProtectButtonText": "Protect", + + "GuessMasterMisguess": "{0} misguessed", + "GuessMasterTargetRole": "Someone tried to guess {0}", + "GuessMasterTitle": "Guess Master ", + + "DoomsayerAmountOfGuessesToWin": "Amount of Guesses to win", + "DCanGuessImpostors": "Can Guess Impostors", + "DCanGuessCrewmates": "Can Guess Crewmates", + "DCanGuessNeutrals": "Can Guess Neutrals", + "DCanGuessAdt": "Can Guess Add-Ons", + "DoomsayerAdvancedSettings": "Advanced Settings", + "DoomsayerMaxNumberOfGuessesPerMeeting": "Max number of guesses per meeting", + "DoomsayerKillCorrectlyGuessedPlayers": "Kill correctly guessed players", + "DoomsayerDoesNotSuicideWhenMisguessing": "Doomsayer does not suicide when misguessing", + "DoomsayerMisguessRolePrevGuessRoleUntilNextMeeting": "Misguessing role prevents guessing roles until next meeting", + "DoomsayerTryHideMsg": "Hide Doomsayer's commands", + "DoomsayerCantGuess": "Sorry, you can only guess the roles in the next meeting.", + "DoomsayerCorrectlyGuessRole": "You guessed the role correctly!\nBut the player didn't die because the Host settings don't allow them to die", + "DoomsayerNotCorrectlyGuessRole": "You didn't correctly guess the role!\nBut you didn't die because the Host's settings don't allow you to die", + "DoomsayerGuessCountMsg": "You correctly guessed {0} roles", + "DoomsayerGuessCountTitle": "DOOMSAYER", + "DoomsayerGuessSameRoleAgainMsg": "You tried to guess the same role or add-on that you guessed before", + + "EveryoneCanKnowMini": "Everyone can see the Mini", + "CanBeEvil": "Mini can be an Impostor", + "EvilMiniSpawnChances": "Probability of Mini being an Impostor", "EvilMiniCanBeGuessed": "Evil Mini can be guessed before 18", - "GuessMini": "Sorry, you can't hurt a kid Mini.", - "GrowUpDuration": "Time required to grow (s)", - "MajorCooldown": "Kill Cooldown when over 18", - "UpDateAge": "Display age change in real-time", - "Cantkillkid": "You can't kill a Mini that hasn't grown up.", - "CantEat": "You can't eat a Mini that hasn't grown up", - "CantShroud": "You can't control a Mini that hasn't grown up.", - "CantBoom": "You can't blow yourself up with a Mini that hasn't grown up.", - "CantRecruit": "You can't recruit a Mini that hasn't grown up.", - "CantDuel": "You can't duel a Mini that hasn't grown up.", - "CantMark": "You can't mark a Mini that hasn't grown up.", - "CantBlood": "You can't blood a Mini that hasn't grown up.", - "CantPosses": "You can't possess a Mini that hasn't grown up.", - "ExiledNiceMini": "You ejected a Nice Mini before they grew up.\nYou all lose", - "MiniUp": "You're a year older!", - "MiniMisGuessed": "You are supposed to misguess to death!\nHowever you are still a kid, so you are free of guilt while you can no longer guess.\nYou can guess again after you have grown up.", - "MiniGuessMax": "You have misguessed, so you are no longer allowed to guess!", - "CountMeetingTime": "Meeting time can continue to grow", - "YouKillRandomizer1": "You kill Randomizer, Self-report!", - "YouKillRandomizer2": "You kill Randomizer, Cannot move!", - "YouKillRandomizer3": "You kill Randomizer, Kill CD change to 600s!", - "YouKillRandomizer4": "You kill Randomizer, Triggered Random Revenge!", - "MadmateCanBeHurried": "Madmate can be Hurried on game start", - "TaskBasedCrewCanBeHurried": "Task-based Crews can be Hurried", - "HurriedCanBeConverted": "Hurried can be recruited in the game (excludes madmate)", - "Developer": "Developer", - "Sponsor": "Sponsor", - "Booster": "Server Booster", - "Translator": "Translator", - "NoAccess": "Unauthorized Access!\n\n Please open up a ticket in the discord server to know more (discord.gg/tohe)", - "DCNotify.Hacking": "You were banned for hacking.\n\nPlease stop.", - "DCNotify.Banned": "You were banned from this lobby.\n\nContact the host if this was a mistake.", - "DCNotify.Kicked": "You were kicked from this lobby.\n\nYou may still rejoin.", - "DCNotify.DCFromServer": "You disconnected from the server.\r\nThis could be an issue with either the servers or your network.", - "DCNotify.GameNotFound": "This lobby code is invalid.\n\nCheck the code and/or server and try again.", - "DCNotify.GameStarted": "This lobby is currently in-game.\n\nWait for it to end or find a different lobby.", - "DCNotify.GameFull": "This lobby is currently full.\n\nCheck with the host to see if you may join.", - "DCNotify.IncorrectVersion": "This lobby does not support your Among Us version.", - "DCNotify.Inactivity": "The lobby closed due to inactivity.", - "DCNotify.Auth": "You are not authenticated.\n\nYou may need to restart your game.", - "DCNotify.DupeLogin": "An instance of your account is already present in this lobby.", - "DCNotify.InvalidSettings": "Game settings have been detected to be invalid.\n\nEnter local play to reset them, then try again.", - "ModeDescribe.SoloKombat": "Current mode is [Solo PVP]\nNo role assignment. Everyone has HP and can use the kill button to cause damage to other players. The player with the highest number of kills wins at the end of the game.", - "RoleType.VanillaRoles": "★ Vanilla Roles", - "RoleType.ImpKilling": "★ Impostor Killing Roles", - "RoleType.ImpSupport": "★ Impostor Support Roles", - "RoleType.ImpConcealing": "★ Impostor Concealing Roles", - "RoleType.ImpHindering": "★ Impostor Hindering Roles", - "RoleType.ImpGhost": "★ Impostor Ghost Roles /ghostinfo", - "RoleType.Madmate": "★ Madmate Roles", - "RoleType.CrewSupport": "★ Crewmate Support Roles", - "RoleType.CrewInvestigative": "★ Crewmate Investigative Roles", - "RoleType.CrewPower": "★ Crewmate Power Roles", - "RoleType.CrewKilling": "★ Crewmate Killing Roles", - "RoleType.CrewBasic": "★ Crewmate Basic Roles", - "RoleType.CrewGhost": "★ Crewmate Ghost Roles /ghostinfo", - "RoleType.NeutralEvil": "★ Neutral Evil Roles", - "RoleType.NeutralBenign": "★ Neutral Benign Roles", - "RoleType.NeutralChaos": "★ Neutral Chaos Roles", - "RoleType.NeutralKilling": "★ Neutral Killing Roles", - "RoleType.NeutralApocalypse": "★ Neutral Apocalypse Roles /apocalypseinfo", - "RoleType.Harmful": "★ Harmful Add-ons", - "RoleType.Support": "★ Supportive Add-ons", - "RoleType.Helpful": "★ Helpful Add-ons", - "RoleType.Mixed": "★ Mixed Add-ons", - "RoleType.Misc": "★ Miscellaneous Add-ons", - "RoleType.Impostor": "★ Impostor Add-ons", - "RoleType.Guesser": "★ Guesser Add-ons", - "RoleType.Neut": "★ Neutral Add-ons", - "RoleType.Experimental": "★ Experimental Addons (NOTICE: Use with caution, as these require testing)", - "SubType.Impostor": "★ Impostors", - "SubType.Shapeshifter": "★ Shapeshifters", - "SubType.SemiShapeshifter": "★ Semi-Shapeshifters", - "SubType.Madmate": "★ Madmates", - "SubType.CrewmateKilling": "★ Crewmate Killings", - "SubType.Crewmate": "★ Regular Crewmates", - "SubType.New": "★ New!", - "CrewmateRoles": "★ Crewmate Roles ★", - "ImpostorRoles": "★ Impostor Roles ★", - "NeutralRoles": "★ Neutral Roles ★", - "AddonRoles": "★ Add-ons ★", - "WinnerRoleText.Impostor": "Impostors Win!", - "WinnerRoleText.Crewmate": "Crewmates Win!", - "WinnerRoleText.Apocalypse": "Apocalypse Wins!", - "WinnerRoleText.Terrorist": "Terrorist Wins!", - "WinnerRoleText.Jester": "Jester Wins!", - "WinnerRoleText.Lovers": "Lovers Win!", - "WinnerRoleText.Executioner": "Executioner Wins!", - "WinnerRoleText.Arsonist": "Arsonist Wins!", - "WinnerRoleText.Revolutionist": "Revolutionist Wins!", - "WinnerRoleText.Jackal": "Jackals Win!", - "WinnerRoleText.God": "God Wins!", - "WinnerRoleText.Vector": "Vector Wins!", - "WinnerRoleText.Innocent": "Innocent Wins!", - "WinnerRoleText.Pelican": "Pelican Wins!", - "WinnerRoleText.Youtuber": "YouTuber Wins!", - "WinnerRoleText.Necromancer": "Necromancer Wins!", - "WinnerRoleText.Egoist": "Egoist(s) Wins!", - "WinnerRoleText.Demon": "Demon Wins!", - "WinnerRoleText.Stalker": "Stalker Wins!", - "WinnerRoleText.Workaholic": "Workaholic Wins!", - "WinnerRoleText.Collector": "Collector Wins!", - "WinnerRoleText.BloodKnight": "Blood Knight Wins!", - "WinnerRoleText.Poisoner": "Poisoner Wins!", - "WinnerRoleText.Huntsman": "Huntsman Wins!", - "WinnerRoleText.HexMaster": "Hex Master Wins!", - "WinnerRoleText.Cultist": "Cultist Wins!", - "WinnerRoleText.Wraith": "Wraith Wins!", - "WinnerRoleText.SerialKiller": "Serial Killers Win!", - "WinnerRoleText.Juggernaut": "Juggernaut Wins!", - "WinnerRoleText.Infectious": "Infectious Wins!", - "WinnerRoleText.Virus": "Virus Wins!", - "WinnerRoleText.Specter": "Specter Wins!", - "WinnerRoleText.Jinx": "Jinx Wins!", - "WinnerRoleText.CursedSoul": "Cursed Soul Wins!", - "WinnerRoleText.PotionMaster": "Potion Master Wins!", - "WinnerRoleText.Pickpocket": "Pickpocket Wins!", - "WinnerRoleText.Traitor": "Traitor Wins!", - "WinnerRoleText.Vulture": "Vulture Wins!", - "WinnerRoleText.Medusa": "Medusa Wins!", - "WinnerRoleText.Spiritcaller": "Spiritcaller Wins!", - "WinnerRoleText.Glitch": "Glitch Wins!", - "WinnerRoleText.Pestilence": "Pestilence Wins!", - "WinnerRoleText.PlagueBearer": "Plaguebearer Wins!", - "WinnerRoleText.PunchingBag": "Punching Bag Wins!", - "WinnerRoleText.Doomsayer": "Doomsayer Wins!", - "WinnerRoleText.Pirate": "Pirate Wins!", - "WinnerRoleText.Shroud": "Shroud Wins!", - "WinnerRoleText.Werewolf": "Werewolf Wins!", - "WinnerRoleText.Seeker": "Seeker Wins!", - "WinnerRoleText.Occultist": "Occultist Wins!", - "WinnerRoleText.SoulCollector": "Soul Collector Wins!", - "WinnerRoleText.NiceMini": "Nice Mini Wins!", - "WinnerRoleText.Mini": "Nice Mini was killed", - "WinnerRoleText.Bandit": "Bandit Wins!", - "WinnerRoleText.RuthlessRomantic": "Ruthless Romantic Wins!", - "WinnerRoleText.Solsticer": "Solsticer Wins!", - "WinnerRoleText.Pyromaniac": "Pyromaniac Wins!", - "WinnerRoleText.Doppelganger": "Doppelganger Wins!", - "WinnerRoleText.Quizmaster": "Quizmaster Wins!", - "WinnerRoleText.Agitater": "Agitator Wins!", + "GuessMini": "Sorry, you can't hurt a kid Mini.", + "GrowUpDuration": "Time required to grow (s)", + "MajorCooldown": "Kill Cooldown when over 18", + "UpDateAge": "Display age change in real-time", + "Cantkillkid": "You can't kill a Mini that hasn't grown up.", + "CantEat": "You can't eat a Mini that hasn't grown up", + "CantShroud": "You can't control a Mini that hasn't grown up.", + "CantBoom": "You can't blow yourself up with a Mini that hasn't grown up.", + "CantRecruit": "You can't recruit a Mini that hasn't grown up.", + "CantDuel": "You can't duel a Mini that hasn't grown up.", + "CantMark": "You can't mark a Mini that hasn't grown up.", + "CantBlood": "You can't blood a Mini that hasn't grown up.", + "CantPosses": "You can't possess a Mini that hasn't grown up.", + "ExiledNiceMini": "You ejected a Nice Mini before they grew up.\nYou all lose", + "MiniUp": "You're a year older!", + "MiniMisGuessed": "You are supposed to misguess to death!\nHowever you are still a kid, so you are free of guilt while you can no longer guess.\nYou can guess again after you have grown up.", + "MiniGuessMax": "You have misguessed, so you are no longer allowed to guess!", + "CountMeetingTime": "Meeting time can continue to grow", + "YouKillRandomizer1": "You kill Randomizer, Self-report!", + "YouKillRandomizer2": "You kill Randomizer, Cannot move!", + "YouKillRandomizer3": "You kill Randomizer, Kill CD change to 600s!", + "YouKillRandomizer4": "You kill Randomizer, Triggered Random Revenge!", + "MadmateCanBeHurried": "Madmate can be Hurried on game start", + "TaskBasedCrewCanBeHurried": "Task-based Crews can be Hurried", + "HurriedCanBeConverted": "Hurried can be recruited in the game (excludes madmate)", + "Developer": "Developer", + "Sponsor": "Sponsor", + "Booster": "Server Booster", + "Translator": "Translator", + "NoAccess": "Unauthorized Access!\n\n Please open up a ticket in the discord server to know more (discord.gg/tohe)", + "DCNotify.Hacking": "You were banned for hacking.\n\nPlease stop.", + "DCNotify.Banned": "You were banned from this lobby.\n\nContact the host if this was a mistake.", + "DCNotify.Kicked": "You were kicked from this lobby.\n\nYou may still rejoin.", + "DCNotify.DCFromServer": "You disconnected from the server.\r\nThis could be an issue with either the servers or your network.", + "DCNotify.GameNotFound": "This lobby code is invalid.\n\nCheck the code and/or server and try again.", + "DCNotify.GameStarted": "This lobby is currently in-game.\n\nWait for it to end or find a different lobby.", + "DCNotify.GameFull": "This lobby is currently full.\n\nCheck with the host to see if you may join.", + "DCNotify.IncorrectVersion": "This lobby does not support your Among Us version.", + "DCNotify.Inactivity": "The lobby closed due to inactivity.", + "DCNotify.Auth": "You are not authenticated.\n\nYou may need to restart your game.", + "DCNotify.DupeLogin": "An instance of your account is already present in this lobby.", + "DCNotify.InvalidSettings": "Game settings have been detected to be invalid.\n\nEnter local play to reset them, then try again.", + "ModeDescribe.SoloKombat": "Current mode is [Solo PVP]\nNo role assignment. Everyone has HP and can use the kill button to cause damage to other players. The player with the highest number of kills wins at the end of the game.", + "RoleType.VanillaRoles": "★ Vanilla Roles", + "RoleType.ImpKilling": "★ Impostor Killing Roles", + "RoleType.ImpSupport": "★ Impostor Support Roles", + "RoleType.ImpConcealing": "★ Impostor Concealing Roles", + "RoleType.ImpHindering": "★ Impostor Hindering Roles", + "RoleType.ImpGhost": "★ Impostor Ghost Roles /ghostinfo", + "RoleType.Madmate": "★ Madmate Roles", + "RoleType.CrewSupport": "★ Crewmate Support Roles", + "RoleType.CrewInvestigative": "★ Crewmate Investigative Roles", + "RoleType.CrewPower": "★ Crewmate Power Roles", + "RoleType.CrewKilling": "★ Crewmate Killing Roles", + "RoleType.CrewBasic": "★ Crewmate Basic Roles", + "RoleType.CrewGhost": "★ Crewmate Ghost Roles /ghostinfo", + "RoleType.NeutralEvil": "★ Neutral Evil Roles", + "RoleType.NeutralBenign": "★ Neutral Benign Roles", + "RoleType.NeutralChaos": "★ Neutral Chaos Roles", + "RoleType.NeutralKilling": "★ Neutral Killing Roles", + "RoleType.NeutralApocalypse": "★ Neutral Apocalypse Roles /apocalypseinfo", + "RoleType.Harmful": "★ Harmful Add-ons", + "RoleType.Support": "★ Supportive Add-ons", + "RoleType.Helpful": "★ Helpful Add-ons", + "RoleType.Mixed": "★ Mixed Add-ons", + "RoleType.Misc": "★ Miscellaneous Add-ons", + "RoleType.Impostor": "★ Impostor Add-ons", + "RoleType.Guesser": "★ Guesser Add-ons", + "RoleType.Neut": "★ Neutral Add-ons", + "RoleType.Experimental": "★ Experimental Addons (NOTICE: Use with caution, as these require testing)", + "SubType.Impostor": "★ Impostors", + "SubType.Shapeshifter": "★ Shapeshifters", + "SubType.SemiShapeshifter": "★ Semi-Shapeshifters", + "SubType.Madmate": "★ Madmates", + "SubType.CrewmateKilling": "★ Crewmate Killings", + "SubType.Crewmate": "★ Regular Crewmates", + "SubType.New": "★ New!", + "CrewmateRoles": "★ Crewmate Roles ★", + "ImpostorRoles": "★ Impostor Roles ★", + "NeutralRoles": "★ Neutral Roles ★", + "AddonRoles": "★ Add-ons ★", + "WinnerRoleText.Impostor": "Impostors Win!", + "WinnerRoleText.Crewmate": "Crewmates Win!", + "WinnerRoleText.Apocalypse": "Apocalypse Wins!", + "WinnerRoleText.Terrorist": "Terrorist Wins!", + "WinnerRoleText.Jester": "Jester Wins!", + "WinnerRoleText.Lovers": "Lovers Win!", + "WinnerRoleText.Executioner": "Executioner Wins!", + "WinnerRoleText.Arsonist": "Arsonist Wins!", + "WinnerRoleText.Revolutionist": "Revolutionist Wins!", + "WinnerRoleText.Jackal": "Jackals Win!", + "WinnerRoleText.God": "God Wins!", + "WinnerRoleText.Vector": "Vector Wins!", + "WinnerRoleText.Innocent": "Innocent Wins!", + "WinnerRoleText.Pelican": "Pelican Wins!", + "WinnerRoleText.Youtuber": "YouTuber Wins!", + "WinnerRoleText.Necromancer": "Necromancer Wins!", + "WinnerRoleText.Egoist": "Egoist(s) Wins!", + "WinnerRoleText.Demon": "Demon Wins!", + "WinnerRoleText.Stalker": "Stalker Wins!", + "WinnerRoleText.Workaholic": "Workaholic Wins!", + "WinnerRoleText.Collector": "Collector Wins!", + "WinnerRoleText.BloodKnight": "Blood Knight Wins!", + "WinnerRoleText.Poisoner": "Poisoner Wins!", + "WinnerRoleText.Huntsman": "Huntsman Wins!", + "WinnerRoleText.HexMaster": "Hex Master Wins!", + "WinnerRoleText.Cultist": "Cultist Wins!", + "WinnerRoleText.Wraith": "Wraith Wins!", + "WinnerRoleText.SerialKiller": "Serial Killers Win!", + "WinnerRoleText.Juggernaut": "Juggernaut Wins!", + "WinnerRoleText.Infectious": "Infectious Wins!", + "WinnerRoleText.Virus": "Virus Wins!", + "WinnerRoleText.Specter": "Specter Wins!", + "WinnerRoleText.Jinx": "Jinx Wins!", + "WinnerRoleText.CursedSoul": "Cursed Soul Wins!", + "WinnerRoleText.PotionMaster": "Potion Master Wins!", + "WinnerRoleText.Pickpocket": "Pickpocket Wins!", + "WinnerRoleText.Traitor": "Traitor Wins!", + "WinnerRoleText.Vulture": "Vulture Wins!", + "WinnerRoleText.Medusa": "Medusa Wins!", + "WinnerRoleText.Spiritcaller": "Spiritcaller Wins!", + "WinnerRoleText.Glitch": "Glitch Wins!", + "WinnerRoleText.Pestilence": "Pestilence Wins!", + "WinnerRoleText.PlagueBearer": "Plaguebearer Wins!", + "WinnerRoleText.PunchingBag": "Punching Bag Wins!", + "WinnerRoleText.Doomsayer": "Doomsayer Wins!", + "WinnerRoleText.Pirate": "Pirate Wins!", + "WinnerRoleText.Shroud": "Shroud Wins!", + "WinnerRoleText.Werewolf": "Werewolf Wins!", + "WinnerRoleText.Seeker": "Seeker Wins!", + "WinnerRoleText.Occultist": "Occultist Wins!", + "WinnerRoleText.SoulCollector": "Soul Collector Wins!", + "WinnerRoleText.NiceMini": "Nice Mini Wins!", + "WinnerRoleText.Mini": "Nice Mini was killed", + "WinnerRoleText.Bandit": "Bandit Wins!", + "WinnerRoleText.RuthlessRomantic": "Ruthless Romantic Wins!", + "WinnerRoleText.Solsticer": "Solsticer Wins!", + "WinnerRoleText.Pyromaniac": "Pyromaniac Wins!", + "WinnerRoleText.Doppelganger": "Doppelganger Wins!", + "WinnerRoleText.Quizmaster": "Quizmaster Wins!", + "WinnerRoleText.Agitater": "Agitator Wins!", "WinnerRoleText.Shocker": "Shocker Wins!", - "AdditionalWinnerRoleText.Sidekick": "Sidekick", - "AdditionalWinnerRoleText.Taskinator": "Taskinator", - "AdditionalWinnerRoleText.Opportunist": "Opportunist", - "AdditionalWinnerRoleText.Lawyer": "Lawyer", - "AdditionalWinnerRoleText.Hater": "Hater", - "AdditionalWinnerRoleText.Provocateur": "Provocateur", - "AdditionalWinnerRoleText.Sunnyboy": "Sunnyboy", - "AdditionalWinnerRoleText.Follower": "Follower", - "AdditionalWinnerRoleText.Pursuer": "Pursuer", - "AdditionalWinnerRoleText.Jester": "Jester", - "AdditionalWinnerRoleText.Lovers": "Lovers", - "AdditionalWinnerRoleText.Executioner": "Executioner", - "AdditionalWinnerRoleText.Specter": "Specter", - "AdditionalWinnerRoleText.Maverick": "Maverick", - "AdditionalWinnerRoleText.Shaman": "Shaman", - "AdditionalWinnerRoleText.Pixie": "Pixie", - "AdditionalWinnerRoleText.NiceMini": "Nice Mini", - "AdditionalWinnerRoleText.Romantic": "Romantic", - "AdditionalWinnerRoleText.VengefulRomantic": "Vengeful Romantic", - "AdditionalWinnerRoleText.SchrodingersCat": "Schrodingers Cat", - "AdditionalWinnerRoleText.Troller": "Troller", - "ErrorEndText": "An error occurred", - "ErrorEndTextDescription": "To avoid crashing, the game was forcibly ended.", - "ForceEnd": "Aborted", - "EveryoneDied": "Everyone died", - "ForceEndText": "Host has aborted the game", - "NiceMiniDied": "Nice Mini was killed", - "HaterMisFireKillTarget": "Hater kills target when misfiring", - "HaterChooseConverted": "Select add-ons that Hater can kill", - "HaterCanKillMadmate": "Can kill madmate", - "HaterCanKillCharmed": "Can kill charmed", - "HaterCanKillLovers": "Can kill lovers", - "HaterCanKillSidekick": "Can kill jackal team", - "HaterCanKillEgoist": "Can kill egoist", - "HaterCanKillInfected": "Can kill infected team", - "HaterCanKillContagious": "Can kill virus team", - "HaterCanKillAdmired": "Can kill admirer", - "HorseMode": "Enable to become a horse", - "LongMode": "Enable to have a long neck", - "InfluencedChangeVote": "Oops! You are so influenced by others!\nYou can not contain your fear that you change voted {0}!", - - - "FFA": "Free For All", - "ModeFFA": "Gamemode: FFA", - "ModeDescribe.FFA": "In the FFA (Free For All) gamemode, everyone is a killer, and everyone can kill anyone. The last player alive wins!\n\nSome random events make this even more fun in the meantime!", - "KillerInfoLong": "In the FFA (Free For All) game mode, everyone is a killer, and everyone can kill anyone. The last player alive wins!\n\nSome random events make this even more fun in the meantime!", - "FFA_GameTime": "Maximum Game Length", - "FFA_KCD": "Kill Cooldown", - "FFA_DisableVentingWhenTwoPlayersAlive": "Prevent venting when only 2 players are alive", - "FFA_EnableRandomAbilities": "Enable Random Events", - "FFA_ShieldDuration": "Shield Duration", - "FFA_IncreasedSpeed": "Increased Speed", - "FFA_DecreasedSpeed": "Decreased Speed", - "FFA_ModifiedSpeedDuration": "Modified Speed Duration", - "FFA_LowerVision": "Lowered Vision", - "FFA_ModifiedVisionDuration": "Lowered Vision Duration", - "FFA_EnableRandomTwists": "Enable Random Swaps from time to time", - "FFA-Event-GetShield": "You have a temporary shield!", - "FFA-Event-GetIncreasedSpeed": "You have a temporary speed boost!", - "FFA-Event-GetLowKCD": "You got a lower kill cooldown!", - "FFA-Event-GetHighKCD": "You got a higher kill cooldown", - "FFA-Event-GetLowVision": "You have lower vision temporarily", - "FFA-Event-GetDecreasedSpeed": "You have decreased speed temporarily", - "FFA-Event-GetTP": "You got teleported to a random vent!", - "FFA-Event-RandomTP": "Everyone was swapped with someone", - "FFA-NoVentingBecauseTwoPlayers": "There are only 2 players alive, stop hiding in vents!", - "FFA-NoVentingBecauseKCDIsUP": "Your kill cooldown is up, don't hide in vents!", - "FFA_DisableVentingWhenKCDIsUp": "Prevent players whose kill cooldown is up from venting", - "FFA_TargetIsShielded": "The player you tried to kill is shielded!", - "FFA_ShieldIsOneTimeUse": "Shields break after 1 kill attempt", - "FFA_ShieldBroken": "Someone tried to kill you, your shield is now broken!", - "Killer": "FREE FOR ALL", - "KillerInfo": "Kill Everyone to Win", - - "Hide&SeekTOHE": "Hide & Seek", - "MenuTitle.Hide&Seek": "Hide & Seek Settings", - "NumImpostorsHnS": "Num Impostors", - - "EveryOneKnowSolsticer": "Every One Know who is Solsticer", - "SolsticerKnowItsKiller": "Solsticer knows the role of whom used the kill button on it", - "SolsticerSpeed": "Movement speed of Solsticer", - "SolsticerRemainingTaskWarned": "Remaining tasks to be known", - "SAddTasksPreDeadPlayer": "How many extra short tasks Solsticer gets when a player dies", - "SolsticerMurdered": "{0} attempted to murder you!", - "MurderSolsticer": "You stopped Solsticer this round!", - "SolsticerMurderMessage": "{0} used kill button on you last round! Its role is {1}!", - "SolsticerOnMeeting": "You witnessed too many deaths! Next round you will have {0} more short task!", - "SolsticerTitle": "Solsticer", - "GuessSolsticer": "Sorry, but you can not guess Solsticer!", + "AdditionalWinnerRoleText.Sidekick": "Sidekick", + "AdditionalWinnerRoleText.Taskinator": "Taskinator", + "AdditionalWinnerRoleText.Opportunist": "Opportunist", + "AdditionalWinnerRoleText.Lawyer": "Lawyer", + "AdditionalWinnerRoleText.Hater": "Hater", + "AdditionalWinnerRoleText.Provocateur": "Provocateur", + "AdditionalWinnerRoleText.Sunnyboy": "Sunnyboy", + "AdditionalWinnerRoleText.Follower": "Follower", + "AdditionalWinnerRoleText.Pursuer": "Pursuer", + "AdditionalWinnerRoleText.Jester": "Jester", + "AdditionalWinnerRoleText.Lovers": "Lovers", + "AdditionalWinnerRoleText.Executioner": "Executioner", + "AdditionalWinnerRoleText.Specter": "Specter", + "AdditionalWinnerRoleText.Maverick": "Maverick", + "AdditionalWinnerRoleText.Shaman": "Shaman", + "AdditionalWinnerRoleText.Pixie": "Pixie", + "AdditionalWinnerRoleText.NiceMini": "Nice Mini", + "AdditionalWinnerRoleText.Romantic": "Romantic", + "AdditionalWinnerRoleText.VengefulRomantic": "Vengeful Romantic", + "AdditionalWinnerRoleText.SchrodingersCat": "Schrodingers Cat", + "AdditionalWinnerRoleText.Troller": "Troller", + "ErrorEndText": "An error occurred", + "ErrorEndTextDescription": "To avoid crashing, the game was forcibly ended.", + "ForceEnd": "Aborted", + "EveryoneDied": "Everyone died", + "ForceEndText": "Host has aborted the game", + "NiceMiniDied": "Nice Mini was killed", + "HaterMisFireKillTarget": "Hater kills target when misfiring", + "HaterChooseConverted": "Select add-ons that Hater can kill", + "HaterCanKillMadmate": "Can kill madmate", + "HaterCanKillCharmed": "Can kill charmed", + "HaterCanKillLovers": "Can kill lovers", + "HaterCanKillSidekick": "Can kill jackal team", + "HaterCanKillEgoist": "Can kill egoist", + "HaterCanKillInfected": "Can kill infected team", + "HaterCanKillContagious": "Can kill virus team", + "HaterCanKillAdmired": "Can kill admirer", + "HorseMode": "Enable to become a horse", + "LongMode": "Enable to have a long neck", + "InfluencedChangeVote": "Oops! You are so influenced by others!\nYou can not contain your fear that you change voted {0}!", + + + + "ChanceCrew": "Chance that randomizer gets crewmate roles", + "ChanceImpostor": "Chance that randomizer gets impostor roles", + "ChanceNeutral": "Chance that randomizer gets neutral roles", + "AllowGhostRoles": "Randomizer can get ghost roles when dead", + "MinAddOns": "Minimum addons randomizer can get", + "MaxAddOns": "Maximum addons randomizer can get", + + + + + + + + + + "FFA": "Free For All", + "ModeFFA": "Gamemode: FFA", + "ModeDescribe.FFA": "In the FFA (Free For All) gamemode, everyone is a killer, and everyone can kill anyone. The last player alive wins!\n\nSome random events make this even more fun in the meantime!", + "KillerInfoLong": "In the FFA (Free For All) game mode, everyone is a killer, and everyone can kill anyone. The last player alive wins!\n\nSome random events make this even more fun in the meantime!", + "FFA_GameTime": "Maximum Game Length", + "FFA_KCD": "Kill Cooldown", + "FFA_DisableVentingWhenTwoPlayersAlive": "Prevent venting when only 2 players are alive", + "FFA_EnableRandomAbilities": "Enable Random Events", + "FFA_ShieldDuration": "Shield Duration", + "FFA_IncreasedSpeed": "Increased Speed", + "FFA_DecreasedSpeed": "Decreased Speed", + "FFA_ModifiedSpeedDuration": "Modified Speed Duration", + "FFA_LowerVision": "Lowered Vision", + "FFA_ModifiedVisionDuration": "Lowered Vision Duration", + "FFA_EnableRandomTwists": "Enable Random Swaps from time to time", + "FFA-Event-GetShield": "You have a temporary shield!", + "FFA-Event-GetIncreasedSpeed": "You have a temporary speed boost!", + "FFA-Event-GetLowKCD": "You got a lower kill cooldown!", + "FFA-Event-GetHighKCD": "You got a higher kill cooldown", + "FFA-Event-GetLowVision": "You have lower vision temporarily", + "FFA-Event-GetDecreasedSpeed": "You have decreased speed temporarily", + "FFA-Event-GetTP": "You got teleported to a random vent!", + "FFA-Event-RandomTP": "Everyone was swapped with someone", + "FFA-NoVentingBecauseTwoPlayers": "There are only 2 players alive, stop hiding in vents!", + "FFA-NoVentingBecauseKCDIsUP": "Your kill cooldown is up, don't hide in vents!", + "FFA_DisableVentingWhenKCDIsUp": "Prevent players whose kill cooldown is up from venting", + "FFA_TargetIsShielded": "The player you tried to kill is shielded!", + "FFA_ShieldIsOneTimeUse": "Shields break after 1 kill attempt", + "FFA_ShieldBroken": "Someone tried to kill you, your shield is now broken!", + "Killer": "FREE FOR ALL", + "KillerInfo": "Kill Everyone to Win", + + "Hide&SeekTOHE": "Hide & Seek", + "MenuTitle.Hide&Seek": "Hide & Seek Settings", + "NumImpostorsHnS": "Num Impostors", + + "EveryOneKnowSolsticer": "Every One Know who is Solsticer", + "SolsticerKnowItsKiller": "Solsticer knows the role of whom used the kill button on it", + "SolsticerSpeed": "Movement speed of Solsticer", + "SolsticerRemainingTaskWarned": "Remaining tasks to be known", + "SAddTasksPreDeadPlayer": "How many extra short tasks Solsticer gets when a player dies", + "SolsticerMurdered": "{0} attempted to murder you!", + "MurderSolsticer": "You stopped Solsticer this round!", + "SolsticerMurderMessage": "{0} used kill button on you last round! Its role is {1}!", + "SolsticerOnMeeting": "You witnessed too many deaths! Next round you will have {0} more short task!", + "SolsticerTitle": "Solsticer", + "GuessSolsticer": "Sorry, but you can not guess Solsticer!", "ExpelSolsticer": "Sorry, but you can not expel Solsticer!", - "SolsticerTasksReset": "Your tasks get reset!", - "SolsticerMisGuessed": "You just misguessed! You are no longer allowed to guess.", - "SolsticerGuessMax": "Because you already misguessed, you are no longer allowed to guess.", - - "VoteDead": "The player you voted for was exiled before the meeting concluded. Your vote was rescinded.", - - "LastMessageReplay": "Last System Message Replay", - "Contributor": "Contributor", - - "dbConnect.InitFailure": "Error while connecting to TOHE API, please check your network connection and retry login!", - "dbConnect.InitFailurePublic": "Error while connecting to TOHE API, this could be caused by your internet connection. And so Sponsor+ perks are not available, you may continue to play as usual without these.", - "dbConnect.nullFriendCode": "This build of TOHE is not available to users with no friendcode!", - - "Quizmaster": "Quizmaster", - "QuizmasterInfo": "Quiz people to kill them in meetings", - "QuizmasterInfoLong": "(Neutrals):\nAs the Quizmaster, you can mark a player using your kill button. In the next meeting, the marked player will have \"?!\" next to their name. The player will die if they answer the question wrong or doesn't answer. The player will live if the Quizmaster is killed/ejected in the same meeting.\nThe Quizmaster cannot mark multiple people in the same round", - "QuizmasterKillButtonText": "Quiz", - - "QuizmasterChat.MarkedBy": "You've been marked by the Quizmaster\nTo survive you have to answer correct to this question:\n\n{QMQUESTION}", - "QuizmasterChat.MarkedPublic": "{QMTARGET} has been marked by the Quizmaster\nTo survive {QMTARGET} have to answer correct to their question!", - "QuizmasterChat.Answers": "Answers\nA: {QMA}\nB: {QMB}\nC: {QMC}\n\nTo answer just type /answer [answer letter]\n\nIf you need to recheck the answer and questions just do /qmquiz", - "QuizmasterChat.CorrectTarget": "Correct", - "QuizmasterChat.Correct": "{QMTARGET} got the right answer!\nYou can now mark someone else!", - "QuizmasterChat.CorrectPublic": "{QMTARGET} got the Quizmaster's question answer correct and survived!\nBeware of the Quizmaster!", - "QuizmasterChat.WrongTarget": "Wrong\nYour answer was {QMWRONG}\nThe correct answer was {QMRIGHT}\n\nThe Quizmaster was {QM}", - "QuizmasterChat.Wrong": "{QMTARGET} got the wrong answer and died!\nYou can now mark someone else!", - "QuizmasterChat.WrongPublic": "{QMTARGET} got the Quizmaster's question answer wrong and died!\nBeware of the Quizmaster!", - "QuizmasterChat.Marked": "You've marked {QMTARGET}\nIf {QMTARGET} doesn't answer by the end of the meeting or answer wrong {QMTARGET} will die\n\nQuestion for {QMTARGET} => {QMQUESTION}", - "QuizmasterChat.Title": "Quizmaster Information", - "QuizmasterChat.CantAnswer": "As the quizmaster, you can't answer questions", - "QuizmasterChat.AnswerNotValid": "Your answer must be A, B, or C", - "QuizmasterChat.SyntaxNotValid": "Usage:\n/answer [A/B/C]", - - "QuizmasterSettings.QuestionDifficulty": "Question Difficulty", - "QuizmasterSettings.CanVentAfterMark": "Can Vent After Marked Somebody For Quiz", - "QuizmasterSettings.CanKillAfterMark": "Can Kill After Marked Somebody For Quiz", - "QuizmasterSettings.NumOfKillAfterMark": "How Many Kills Per Round", - "QuizmasterSettings.CanGiveQuestionsAboutPastGames": "Can Give Questions About Past Games", - - "Quizmaster.None": "None", - - "QuizmasterSabotages.Lights": "Lights", - "QuizmasterSabotages.Reactor": "Reactor", - "QuizmasterSabotages.Communications": "Communications", - "QuizmasterSabotages.O2": "O2", - "QuizmasterSabotages.MushroomMixup": "Mushroom Mixup", - "QuizmasterAnswers.One": "One", - "QuizmasterAnswers.Two": "Two", - "QuizmasterAnswers.Three": "Three", - "QuizmasterAnswers.Four": "Four", - "QuizmasterAnswers.Five": "Five", - "QuizmasterAnswers.Pacifist": "Pacifist", - "QuizmasterAnswers.Vampire": "Vampire", - "QuizmasterAnswers.Snitch": "Snitch", - "QuizmasterAnswers.Vigilante": "Vigilante", - "QuizmasterAnswers.Jackal": "Jackal", - "QuizmasterAnswers.Mole": "Mole", - "QuizmasterAnswers.Sniper": "Sniper", - "QuizmasterAnswers.Coven": "Coven", - "QuizmasterAnswers.Sabotuer": "Saboteur", - "QuizmasterAnswers.Sorcerers": "Sorcerers", - "QuizmasterAnswers.Killer": "Killer", - "QuizmasterAnswers.Edition": "Edition", - "QuizmasterAnswers.Experimental": "Experimental", - "QuizmasterAnswers.Enhanced": "Enhanced", - "QuizmasterAnswers.Edited": "Edited", - - "QuizmasterQuestions.LastSabotage": "What was the sabotage was called last?", - "QuizmasterQuestions.FirstRoundSabotage": "What was the first sabotage called this round?", - "QuizmasterQuestions.LastEjectedPlayerColor": "What was the color of the player that was last ejected?", - "QuizmasterQuestions.LastReportPlayerColor": "What was the color of the body that was last reported before this meeting?", - "QuizmasterQuestions.LastButtonPressedPlayerColor": "Who called the last meeting before this meeting?", - "QuizmasterQuestions.MeetingPassed": "How many meetings have passed so far?", - "QuizmasterQuestions.HowManyFactions": "How many factions are in the game?", - "QuizmasterQuestions.BasisOfRole": "What's the basis of {QMRole}?", - "QuizmasterQuestions.FactionOfRole": "What's the faction of {QMRole}?", - "QuizmasterQuestions.FactionRemovedName": "What faction used to be in the game but was removed in an update later?", - "QuizmasterQuestions.HowManyDiedFirstRound": "How many people died round one?", - "QuizmasterQuestions.ButtonPressedBefore": "How many people pressed the emergency button before this meeting?", - "QuizmasterQuestions.WhatDoesEOgMeansInName": "What did the E in TOHE originally stand for?", - "QuizmasterQuestions.PlrDieReason": "What was {PLR}'s cause of death?", - "QuizmasterQuestions.PlrDieMethod": "How did {PLR} die?", - "LastAddedRoleForKarped": "What was the last role added to TOHE before KARPED1EM stepped down?", - "QuizmasterQuestions.PlrDieFaction": "What kind of faction killed {PLR}?", - - "DeathReason.WrongAnswer": "Wrong Quiz Answer", - - "TPCooldown": "Teleport Cooldown", - "RiftsTooClose": "Location too close to the first rift", - "RiftCreated": "Rift made successfully", - "RiftsDestroyed": "All rifts Destroyed", - "RiftRadius": "Rift Radius", - - "TiredVision": "Vision When Tired", - "TiredSpeed": "Speed When Tired", - "TiredDur": "Tired Duration", - - "TiredNotify": "Zzz..", - - "PlagueDoctorInfectLimit": "Infect Limit", - "PlagueDoctorInfectWhenKilled": "Infect Killer When Killed", - "PlagueDoctorInfectTime": "Infect Time", - "PlagueDoctorInfectDistance": "Infect Distance", - "PlagueDoctorInfectInactiveTime": "Delay Infection After Start The Game And After Meetings", - "PlagueDoctorCanInfectSelf": "Can Infect Self", - "PlagueDoctorCanInfectVent": "Can Infect While In Vent", - "WinnerRoleText.PlagueDoctor": "Plague Scientist Wins!", - - "StatueSlow": "Statue Slowness", - "StatuePeopleToSlow": "People Needed To Slow", - - "WardenIncreaseSpeed": "Increase Speed By", - "WardenWarn": "DANGER! RUN!", - - "MinionAbilityTime": "Ability Duration", - "Minion_Blind": "blinded", - - "Evader_ChanceNotExiled": "Chance not be exiled", + "SolsticerTasksReset": "Your tasks get reset!", + "SolsticerMisGuessed": "You just misguessed! You are no longer allowed to guess.", + "SolsticerGuessMax": "Because you already misguessed, you are no longer allowed to guess.", + + "VoteDead": "The player you voted for was exiled before the meeting concluded. Your vote was rescinded.", + + "LastMessageReplay": "Last System Message Replay", + "Contributor": "Contributor", + + "dbConnect.InitFailure": "Error while connecting to TOHE API, please check your network connection and retry login!", + "dbConnect.InitFailurePublic": "Error while connecting to TOHE API, this could be caused by your internet connection. And so Sponsor+ perks are not available, you may continue to play as usual without these.", + "dbConnect.nullFriendCode": "This build of TOHE is not available to users with no friendcode!", + + "Quizmaster": "Quizmaster", + "QuizmasterInfo": "Quiz people to kill them in meetings", + "QuizmasterInfoLong": "(Neutrals):\nAs the Quizmaster, you can mark a player using your kill button. In the next meeting, the marked player will have \"?!\" next to their name. The player will die if they answer the question wrong or doesn't answer. The player will live if the Quizmaster is killed/ejected in the same meeting.\nThe Quizmaster cannot mark multiple people in the same round", + "QuizmasterKillButtonText": "Quiz", + + "QuizmasterChat.MarkedBy": "You've been marked by the Quizmaster\nTo survive you have to answer correct to this question:\n\n{QMQUESTION}", + "QuizmasterChat.MarkedPublic": "{QMTARGET} has been marked by the Quizmaster\nTo survive {QMTARGET} have to answer correct to their question!", + "QuizmasterChat.Answers": "Answers\nA: {QMA}\nB: {QMB}\nC: {QMC}\n\nTo answer just type /answer [answer letter]\n\nIf you need to recheck the answer and questions just do /qmquiz", + "QuizmasterChat.CorrectTarget": "Correct", + "QuizmasterChat.Correct": "{QMTARGET} got the right answer!\nYou can now mark someone else!", + "QuizmasterChat.CorrectPublic": "{QMTARGET} got the Quizmaster's question answer correct and survived!\nBeware of the Quizmaster!", + "QuizmasterChat.WrongTarget": "Wrong\nYour answer was {QMWRONG}\nThe correct answer was {QMRIGHT}\n\nThe Quizmaster was {QM}", + "QuizmasterChat.Wrong": "{QMTARGET} got the wrong answer and died!\nYou can now mark someone else!", + "QuizmasterChat.WrongPublic": "{QMTARGET} got the Quizmaster's question answer wrong and died!\nBeware of the Quizmaster!", + "QuizmasterChat.Marked": "You've marked {QMTARGET}\nIf {QMTARGET} doesn't answer by the end of the meeting or answer wrong {QMTARGET} will die\n\nQuestion for {QMTARGET} => {QMQUESTION}", + "QuizmasterChat.Title": "Quizmaster Information", + "QuizmasterChat.CantAnswer": "As the quizmaster, you can't answer questions", + "QuizmasterChat.AnswerNotValid": "Your answer must be A, B, or C", + "QuizmasterChat.SyntaxNotValid": "Usage:\n/answer [A/B/C]", + + "QuizmasterSettings.QuestionDifficulty": "Question Difficulty", + "QuizmasterSettings.CanVentAfterMark": "Can Vent After Marked Somebody For Quiz", + "QuizmasterSettings.CanKillAfterMark": "Can Kill After Marked Somebody For Quiz", + "QuizmasterSettings.NumOfKillAfterMark": "How Many Kills Per Round", + "QuizmasterSettings.CanGiveQuestionsAboutPastGames": "Can Give Questions About Past Games", + + "Quizmaster.None": "None", + + "QuizmasterSabotages.Lights": "Lights", + "QuizmasterSabotages.Reactor": "Reactor", + "QuizmasterSabotages.Communications": "Communications", + "QuizmasterSabotages.O2": "O2", + "QuizmasterSabotages.MushroomMixup": "Mushroom Mixup", + "QuizmasterAnswers.One": "One", + "QuizmasterAnswers.Two": "Two", + "QuizmasterAnswers.Three": "Three", + "QuizmasterAnswers.Four": "Four", + "QuizmasterAnswers.Five": "Five", + "QuizmasterAnswers.Pacifist": "Pacifist", + "QuizmasterAnswers.Vampire": "Vampire", + "QuizmasterAnswers.Snitch": "Snitch", + "QuizmasterAnswers.Vigilante": "Vigilante", + "QuizmasterAnswers.Jackal": "Jackal", + "QuizmasterAnswers.Mole": "Mole", + "QuizmasterAnswers.Sniper": "Sniper", + "QuizmasterAnswers.Coven": "Coven", + "QuizmasterAnswers.Sabotuer": "Saboteur", + "QuizmasterAnswers.Sorcerers": "Sorcerers", + "QuizmasterAnswers.Killer": "Killer", + "QuizmasterAnswers.Edition": "Edition", + "QuizmasterAnswers.Experimental": "Experimental", + "QuizmasterAnswers.Enhanced": "Enhanced", + "QuizmasterAnswers.Edited": "Edited", + + "QuizmasterQuestions.LastSabotage": "What was the sabotage was called last?", + "QuizmasterQuestions.FirstRoundSabotage": "What was the first sabotage called this round?", + "QuizmasterQuestions.LastEjectedPlayerColor": "What was the color of the player that was last ejected?", + "QuizmasterQuestions.LastReportPlayerColor": "What was the color of the body that was last reported before this meeting?", + "QuizmasterQuestions.LastButtonPressedPlayerColor": "Who called the last meeting before this meeting?", + "QuizmasterQuestions.MeetingPassed": "How many meetings have passed so far?", + "QuizmasterQuestions.HowManyFactions": "How many factions are in the game?", + "QuizmasterQuestions.BasisOfRole": "What's the basis of {QMRole}?", + "QuizmasterQuestions.FactionOfRole": "What's the faction of {QMRole}?", + "QuizmasterQuestions.FactionRemovedName": "What faction used to be in the game but was removed in an update later?", + "QuizmasterQuestions.HowManyDiedFirstRound": "How many people died round one?", + "QuizmasterQuestions.ButtonPressedBefore": "How many people pressed the emergency button before this meeting?", + "QuizmasterQuestions.WhatDoesEOgMeansInName": "What did the E in TOHE originally stand for?", + "QuizmasterQuestions.PlrDieReason": "What was {PLR}'s cause of death?", + "QuizmasterQuestions.PlrDieMethod": "How did {PLR} die?", + "LastAddedRoleForKarped": "What was the last role added to TOHE before KARPED1EM stepped down?", + "QuizmasterQuestions.PlrDieFaction": "What kind of faction killed {PLR}?", + + "DeathReason.WrongAnswer": "Wrong Quiz Answer", + + "TPCooldown": "Teleport Cooldown", + "RiftsTooClose": "Location too close to the first rift", + "RiftCreated": "Rift made successfully", + "RiftsDestroyed": "All rifts Destroyed", + "RiftRadius": "Rift Radius", + + "TiredVision": "Vision When Tired", + "TiredSpeed": "Speed When Tired", + "TiredDur": "Tired Duration", + + "TiredNotify": "Zzz..", + + "PlagueDoctorInfectLimit": "Infect Limit", + "PlagueDoctorInfectWhenKilled": "Infect Killer When Killed", + "PlagueDoctorInfectTime": "Infect Time", + "PlagueDoctorInfectDistance": "Infect Distance", + "PlagueDoctorInfectInactiveTime": "Delay Infection After Start The Game And After Meetings", + "PlagueDoctorCanInfectSelf": "Can Infect Self", + "PlagueDoctorCanInfectVent": "Can Infect While In Vent", + "WinnerRoleText.PlagueDoctor": "Plague Scientist Wins!", + + "StatueSlow": "Statue Slowness", + "StatuePeopleToSlow": "People Needed To Slow", + + "WardenIncreaseSpeed": "Increase Speed By", + "WardenWarn": "DANGER! RUN!", + + "MinionAbilityTime": "Ability Duration", + "Minion_Blind": "blinded", + + "Evader_ChanceNotExiled": "Chance not be exiled", "ShockerAbilityCooldown": "Ability Cooldown", "ShockerAbilityDuration": "Ability Duration", @@ -3886,7 +3917,7 @@ "ShockerVentButtonText": "Shock", "ShockerRoomMarked": "Marked Room", - "EavesdropperMsgTitle": "You found a secret", + "EavesdropperMsgTitle": "You found a secret", "EavesdropPercentChance": "Chance to eavesdrop", "PreventSeeRolesBeforeSkillUsedUp": "Prevent seeing others roles before skill used up", diff --git a/Resources/Lang/es_419.json b/Resources/Lang/es_419.json index 2921031a5..f147d01cc 100644 --- a/Resources/Lang/es_419.json +++ b/Resources/Lang/es_419.json @@ -20,8 +20,6 @@ "SubText.Neutral": "Trabaja solo para conseguir tu victoria", "SubText.Apocalypse": "Vuelvete imparable con tu equipo", "SubText.Madmate": "Ayuda a los Impostores", - "SubText.Lovers": "Manténgase vivos y ganen juntos", - "SubText.Egoist": "Gana por tu propia cuenta", "TypeImpostor": "Impostores", "TypeCrewmate": "Tripulantes", "TypeNeutral": "Neutrales", @@ -31,9 +29,6 @@ "TeamNeutral": "Neutral", "TeamCrewmate": "Tripulante", "TeamMadmate": "Cómplice", - "TeamLovers": "Amantes", - "TeamEgoist": "Egoísta", - "TeamApocalypse": "Apocalipsis", "YouAreCrewmate": "Eres un Tripulante", "YouAreImpostor": "Eres un Impostor", "YouAreNeutral": "Eres un Neutral", @@ -225,7 +220,6 @@ "TaskManager": "Gestor de Tareas", "Witness": "Testigo", "Swapper": "Intercambiador", - "ChiefOfPolice": "Jefe de Policias", "NiceMini": "Mini Benigno", "Mini": "Mini", "Spy": "Espía", @@ -254,7 +248,6 @@ "Stalker": "Acosador", "Workaholic": "Trabajólico", "Solsticer": "Solicitador", - "Abyssbringer": "Portador de Abismo", "Collector": "Coleccionista", "Provocateur": "Provocador", "BloodKnight": "Caballero de Sangre", @@ -392,9 +385,7 @@ "DoubleAgent": "Doble Agente", "Sloth": "Perezoso", "Prohibited": "Prohibido", - "Eavesdropper": "Escuchón", - "Shocker": "Electro-Descargador", - "Revenant": "Renacido", + "Eavesdropper": "Eavesdropper", "BracketAddons": "Dar Corchetes a Add-ons", "EngineerTOHEInfo": "Usa los conductos de ventilación para espiar a los Impostores", "ScientistTOHEInfo": "Ve los signos vitales de la tripulación desde cualquier sitio", @@ -513,7 +504,6 @@ "PacifistInfo": "Reinicia el tiempo de espera para matar de todos usando los conductos", "RebirthInfo": "Levántate de nuevo", "MonarchInfo": "¡Da a la tripulación votos extra!", - "AbyssbringerInfo": "Coloca agujeros negros", "SpurtInfo": "Salta como un conejo!", "StealthInfo": "Matando ciega a todos en la habitasion", "PenguinInfo": "Arrastra a tus víctimas", @@ -538,7 +528,7 @@ "AdmirerInfo": "Elije a un jugador para que esté de tu parte", "TimeMasterInfo": "¡Retrocede el tiempo!", "CrusaderInfo": "Mata el atacante de un jugador", - "AltruistInfo": "Revive a un jugador", + "AltruistInfo": "Revive a player\nVent to change between Revive and Report", "ReverieInfo": "Con cada asesinato, matas más rápido", "LookoutInfo": "Ve a través del disfraz", "TelecommunicationInfo": "Vigila el uso de dispositivos", @@ -547,7 +537,6 @@ "WitnessInfo": "Ve si alguien ha asesinado recientemente", "GhastlyInfo": "¡Controla a alguien!", "SwapperInfo": "Intercambia los votos entre dos jugadores", - "ChiefOfPoliceInfo": "¡Contrata al Sheriff para servir a la tripulacion!", "NiceMiniInfo": "Nadie podrá matarte hasta que crezcas.", "ArsonistInfo": "Rocía a todos en gasolina y préndelos fuego", "PyromaniacInfo": "Rocía y mata a todos", @@ -603,7 +592,7 @@ "VultureInfo": "Cóme cadáveres para ganar", "TaskinatorInfo": "Tareas silenciosas, explosiones mortales", "BenefactorInfo": "¡Tareas completas, tripulación recompensada!", - "MedusaInfo": "Reporta para convertir cadáveres en piedra", + "MedusaInfo": "Stone bodies by reporting them", "SpiritcallerInfo": "Transforma a los jugadores en espíritus malignos", "AmnesiacInfo": "Recuerda el rol de un cadáver", "ImitatorInfo": "Imita el rol de un jugador", @@ -615,19 +604,19 @@ "ShroudInfo": "Cubre a otros para hacerlos asesinar por ti", "WerewolfInfo": "Mata tripulantes en grupos", "ShamanInfo": "Desvía todos los ataques al muñeco vudú", - "SeekerInfo": "Juega Escondidas con tu objetivo", + "SeekerInfo": "Play Hide and Seek with your target\nYour target has a ★ mark.", "PixieInfo": "¡Etiquétalos, embolsalos y expúlsalos!", "OccultistInfo": "Mata y maldice a tus enemigos", "SchrodingersCatInfo": "El gato está vivo y muerto al mismo tiempo hasta que lo observan.", "RomanticInfo": "Proteje a tu compañero para ganar juntos", "VengefulRomanticInfo": "Venga a tu compañero para ganar juntos", "RuthlessRomanticInfo": "Mata a todos para ganar con tu compañero", - "PoisonerInfo": "Mata a todos con asesinatos retrasados", + "PoisonerInfo": "Kill everyone with delayed kills", "HexMasterInfo": "Hechiza a la tripulación y mátalos en las reuniones", "WraithInfo": "Usa un conducto para volverte invisible temporalmente", - "JinxInfo": "Desvía ataques a tus atacantes", + "JinxInfo": "Reflect attacks onto your attackers", "PotionMasterInfo": "Usa tus pociones como ventaja", - "NecromancerInfo": "Mata a tu asesino para vencer a la muerte", + "NecromancerInfo": "Kill your killer to defy death", "WardenInfo": "(Fantasma) Alerta sobre peligro", "MinionInfo": "(Fantasmas) Ciega enemigos", "LoversInfo": "Mantente vivo y gana juntos", @@ -708,25 +697,23 @@ "SlothInfo": "Eres mas despacio", "ProhibitedInfo": "Ciertos conductos están bloqueados", "EavesdropperInfo": "Atentamente escucha las conversaciones de otros roles", - "ShockerInfo": "Impacta a jugadores desprevenidos con descargas eléctricas", - "RevenantInfo": "Toma el rol de tu asesino", "EngineerTOHEInfoLong": "(Tripulantes):\nComo el Ingeniero, podras acceder a los ductos mientras el sabotage las Comunaciones este inactivo.", "ScientistTOHEInfoLong": "(Tripulantes):\nComo el Científico, tienes acceso a los vitales al cualquier momento, muestrandote quién esta vivo o muerto.", - "NoisemakerTOHEInfoLong": "(Tripulación):\nCuando el Ruidoso muere, hará un ruido lo suficientemente fuerte para alertar a la tripulación. La tripulación tendrá un indicador visual hacia tu lugar de muerte para posiblemente atrapar al asesino con las manos en la masa.", - "TrackerTOHEInfoLong": "(Tripulantes):\nEl Rastreador puede usar su botón de Rastrear en otro jugador para poder vigilar su ubicación con el mapa durante un tiempo limitado.", + "NoisemakerTOHEInfoLong": "(Crewmates):\nAs the Noisemaker, whenever you die, you will make a noise, and a visual indicator of your death appears on the screen so the Crewmates can run to catch the person who killed you red-handed (even if it’s not Red).", + "TrackerTOHEInfoLong": "(Crewmates):\nAs the Tracker, press your tracker button on a player to track their location via the map for a limited amount of time.", "ShapeshifterTOHEInfoLong": "(Impostores):\nComo el Cambiaformas, podras transformarte en otros jugadores. Es obvio cuando cambias o te desformas.", - "PhantomTOHEInfoLong": "(Impostores):\nComo el Fantasma, puedes presionar el botón de \"Desaparecer\" para volverte invisible y escapar de la escena del asesinato. Puedes presionar el botón de nuevo para volver a ser visible, si no, volveras a ser visible después de que se agota el cronómetro.", + "PhantomTOHEInfoLong": "(Impostors):\nAs the Phantom, you can press your vanish button to go invisible to escape a kill. You can click your appear button if you want to become visible before the timer runs out or not.\nNote: You will make a smoke cloud whenever you go invisible and become visible. So make sure you are in a safe area where no one will see you.", "GuardianAngelTOHEInfoLong": "(Tripulantes):\nComo el Ángel Guardián, eres el alma del primer tripulante muerto, y puedes dar escudos temporales a la tripulación.", "ImpostorTOHEInfoLong": "(Impostores):\nComo el Impostor, tu objetivo es simplemente matar a los tripulantes.\nPuedes sabotear y usar ductos.", "CrewmateTOHEInfoLong": "(Tripulantes):\nComo un tripulante, tu meta es encontrar y exilar a los Impostores. Los tripulantes ganan deshaciendose de los impostores o terminando sus tareas.", "BountyHunterInfoLong": "(Impostores):\nEl Cazarrecompensas tiene un objetivo (Indicado por la flecha, si tienes una). Al matarlo, tu tiempo de espera para matar será reducido.\nSi matas a otra persona que no erea tu objetivo, tu tiempo de espera será incrementado. Tu objetivo cambia cada cierto tiempo.", - "FireworkerInfoLong": "(Impostores):\nEl Pirotécnico puede cambiar formas para poner Fuegos Artificiales, con el máximo siendo configurado por el Anfitrión.\nCuando seas el último impostor y todos los fuegos artificiales hayan sido colocados, cambia de forma para encenderlos y mata a todos los que estén cerca, incluyendo a ti mismo.\nSi matas a todos los jugadores con tus fuegos artificiales, cuenta como una victoria para los Impostores.", - "MercenaryInfoLong": "(Impostores):\nComo el Mercenario, debes matar dentro de tu plazo, mostrado por el tiempo de enfriamiento de tu Transformación (que no puedes usar). Si no logras matar durante este tiempo, mueres.", + "FireworkerInfoLong": "(Impostors):\nAs the Fireworker, you can Shapeshift to place Fireworks up to the maximum amount the host sets.\nWhen you are the last Impostor and all Fireworks have been placed, shapeshift again to detonate them and kill everyone in their radius, including you.\nIf you kill all players with your Fireworks, it's considered an Impostor victory.", + "MercenaryInfoLong": "(Impostors):\nAs the Mercenary, you must kill within your Deadline, as shown by your Shapeshift cooldown (which you cannot use). If you fail to kill, you die.", "ShapeMasterInfoLong": "(Impostores):\nComo el Cambiaformas Maestro, no tienes Cooldown de Cambiaformas.", - "VampireInfoLong": "(Impostores):\nComo el Vampiro, sus asesinatos seran detrasados. Esto significa que sus objetivo muriran de todas maneras aunque la reunión sea llamada primero.\nSi muerde a la Carnada, matara normalmente y reportara el cuerpo. Dependiendo de la configuración, podrá usar doble gatillo (muerde jugador - un clic, matar normalmente - doble clic).", + "VampireInfoLong": "(Impostors):\nAs the Vampire, your kills are delayed. This means that your target still dies even if a meeting is called first. However, if you bite a Bait, you kill normally and report the body. Depending on the settings, you can use double trigger (bite players - single click, kill normally - double click).", "WarlockInfoLong": "(Impostores):\nComo el Brujo, puedes maldecir a un jugador a la vez.\nAl cambiar de forma, si has maldecido a un jugador, matará a la persona más cercana a él. Según las opciones, esto puede incluir a los otros impostores o a tí, por lo que ten cuidado.\nPodrás matar normalmente si te has transformado en alguien.", - "ZombieInfoLong": "(Impostores):\nComo el Zombi, puedes matar rápidamente, pero seras muy lento y veras muy poco. No podrás ser exiliado por nadie excepto por el dictador, y te volverás más lento con el tiempo o cada vez que mates.", - "NinjaInfoLong": "(Impostors):\nEl Ninja puede usar su boton de matar para marcar un objetivo (un clic) o matar normalmente (doble clic). Despues de eso, podra cambiar de formas para transportarte a ellos y matarlos.", + "ZombieInfoLong": "(Impostors):\nZombie has a short kill cooldown but moves very slowly and has very little vision. Zombie can not be voted out by anyone other than the Dictator, and the movement speed of Zombie will gradually slow down as they make kills or time passes.", + "NinjaInfoLong": "(Impostors):\nAs the Ninja, you can use your kill button to Mark a target (single click) or kill normally (double click). You may then Shapeshift to teleport to the Marked target and kill them.", "AnonymousInfoLong": "(Impostores):\nComo el Anónimo, puedes cambiar de forma para forzar a su objetivo a reportar a quien haya matado en esta ronda.\nSi no mataste a nadie esa ronda, el objetivo reportará su propio cuerpo muerto como si hubiera muerto.\nNota: El Perezoso y el Gandul no serán afectados por esta habilidad, y esta funcionará aún si el cadáver puede ser informado.", "MinerInfoLong": "(Impostores):\nComo el Minero, puedes transformarte para teletransportarte de vuelta al último conducto en el que estuviste.", "KillingMachineInfoLong": "(Impostors):\nAs the Killing Machine, you have a very short kill cooldown with tiny vision. However, you cannot vent, sabotage, report, nor call emergency meetings.\n\nNote: You will bypass any shields, killing bait and beartrap won't take any effect", @@ -781,11 +768,11 @@ "LurkerInfoLong": "(Impostors):\nAs the Lurker, you can jump into a vent to reduce your cooldown by a certain number of seconds. After you kill, your cooldown resets to its original value.", "VisionaryInfoLong": "(Impostors):\nAs the Visionary, you see the alignments of living players during a meeting.\nThe following information will be displayed on the players:\n- The Red name indicates the Impostors.\n- The Cyan name indicates the Crewmates.\n- The Gray name indicates the Neutrals.", "PlagueDoctorInfoLong": "(Neutrals):\n(Plague Doctor from TOH)\nThe Plague Scientist's goal is to infect every living player.\nThey start by choosing one player to infect, after which anyone who spends a set amount of time in the range of the infected player becomes infected themselves.\nInfection progress is cumulative and does not reset with distance or after meetings.", - "RefugeeInfoLong": "(Madmates):\nAs the Refugee, you were either:\n -An Amnesiac who remembered an Impostor\n -A killer who killed the Godfather's target.\n -A Romantic whose partner was an Impostor\n -Or an Imitator that imitated an Impostor.\n\nNow your job is to help the Impostors kill the crewmates.", + "RefugeeInfoLong": "(Madmates):\nAs the Refugee, you were either an Amnesiac who remembered an Impostor or a killer who killed the Godfather's target.\n\nNow your job is to help the Impostors kill the crewmates.", "UnderdogInfoLong": "(Impostores):\nEl Indefenso no puede matar hasta que sólo queden un cierto número de jugadores vivos.", "ConsigliereInfoLong": "(Impostors):\nAs the Consigliere, you can reveal the roles of other players using your kill button.\n\nSingle click: Reveal role\nDouble click: Kill\n\nIf you run out of reveal uses, your kill button functions normally.", "LudopathInfoLong": "(Impostores):\nEl Ludópata tiene un tiempo de espera para matar aleatorio.\n\nEl mínimo es de 1 segundo, el máximo es tu tiempo de espera para matar por defecto.", - "GodfatherInfoLong": "(Impostors):\nAs the Godfather, you vote someone to make them your target.\nIn the next round, if someone kills the target, the killer will turn into a Refugee or Madmate.", + "GodfatherInfoLong": "(Impostors):\nAs the Godfather, you vote someone to make them your target.\nIn the next round, if someone kills the target, the killer will turn into a Refugee.", "ChronomancerInfoLong": "(Impostors):\nAs the Chronomancer, you have a charge bar which indicates when the slaughter is ready. When it is at 100% the next time you kill someone, you go into slaughter mode, meaning you can kill indefinitely until your bar runs out of charge. Otherwise, you have a normal KCD.", "PitfallInfoLong": "(Impostors):\nAs the Pitfall, you use your shapeshift to mark the area around the shapeshift as a trap. Players who enter this area will be immobilized quickly, and their vision will be affected.", "EvilMiniInfoLong": "(Impostors):\nAs the Evil Mini, you are unkillable until you grow up and have a very long initial kill cooldown, which gets drastically shortened as you grow up.", @@ -821,7 +808,7 @@ "GrenadierInfoLong": "(Tripulantes):\nEl Granadero puede usar los conductos para lanzar una Granada de Luz a otros jugadores cercanos, lo que les hace perder la visión si son Impostores o, según la configuración, Neutrales.", "MedicInfoLong": "(Crewmates):\nThe Medic can place a shield on the target by pressing the Kill button. The Medic can only give one shield for the whole game. Depending on the settings, the target's shield can or cannot deactivate when the Medic dies. The Medic can also see if someone is trying to break the target's shield.\nDepending on the Host's settings, the Medic or the target can see if the player has a shield (shown as a green circle 「●」 next to the name).", "FortuneTellerInfoLong": "(Crewmates):\nAs the Fortune Teller, vote for a player in a meeting to get a clue to their role.\nThe clue will relate to their actual role.\n\nWhen the Fortune Teller's tasks are complete, they will obtain the exact role rather than a clue!\n\nNote: If the setting to give random active players as a hint is on, you cannot check the same player multiple times.", - "JudgeInfoLong": "(Crewmates):\nThe Judge can judge a certain player during the meeting. If the target is evil, the target will be killed (whether it is evil or not is set by the Host). If it is wrong, the Judge commits suicide.\nCommand for judgment: /tl [player id]\nYou can see the player's id before the player's name, or use the /id command to view the id of all players.\nJudges can judge all players when they become Madmate.", + "JudgeInfoLong": "(Crewmates):\nThe Judge can judge a certain player during the meeting. If the target is evil, the target will be killed (whether it is evil or not is set by the Host). If it is wrong, the Judge commits suicide.\nCommand for judgment: /tl [player id]\nYou can see the player's id before the player's name, or use the /id command to view the id of all players.\nJudges can judge all players when they become Madmate.\nIn meeting the ability count shows how many trails you have in this meeting. Out of meeting the ability counts shows how many trails you have for the whole game.", "MorticianInfoLong": "(Crewmates):\nThe Mortician can see arrows pointing to all dead bodies, and if the Mortician reports a body, they will know the last player the victim had contact with. Note: Mortician won't be Oblivious or Seer.", "MediumInfoLong": "(Crewmates):\nThe Medium can establish contact with a dead player after someone reports a dead body. The player who reports doesn't have to be the Medium. The dead player can answer once with a YES or a NO to the Medium's question, which only the Medium will see (the dead player can use /ms yes or /ms no). Note: Medium won't be Oblivious.", "ObserverInfoLong": "(Crewmates):\nAs the Observer, you can see all shield animations caused by other players after the first meeting. The shied animations typically indicate a role ability, so look out for this.", @@ -833,7 +820,7 @@ "MerchantInfoLong": "(Crewmates):\nAs a merchant, you sell a random add-on to a random player for each task you complete. Each add-on sold earns you money. If you have a certain amount of money, you can prevent the next killing attempt against you by bribing the murderer. The bribed player won't be able to kill you, but you don't know who it is. The money used is lost and not available for additional bribes.", "RetributionistInfoLong": "(Crewmates):\nAs the Retributionist, you can kill a limited amount of players after your death.\n\nUse /ret [playerID] to kill.", "HawkInfoLong": "(Crewmates [Ghost]):\nAs the Hawk, you can kill a limited amount of players decided by the host, though there's a chance you miss, slicing someone multiple times increases the chances.", - "DeputyInfoLong": "(Tripulantes):\nComo el Comisario, usa tu botón de matar en alguien para restaurar su tiempo de recuperación de matar.\n\nSi el objetivo no tiene un botón de matar, entonces las esposas fueron un desperdicio.", + "DeputyInfoLong": "(Crewmates):\nAs the Deputy, use your kill button to handcuff a player.\nThe player who is handcuffed will have their next kill attempt treated as a handcuff break, and the kill cooldown will be reset.\n\nIf the target does not have a kill button, then the handcuff was a waste.", "InvestigatorInfoLong": "(Crewmates):\nAs an Investigator, you can use your kill button to investigate someone. When you investigate someone, their name will appear in red if they possess a kill button (impostor/SS basis) or light blue if they lack a kill button (crewmate/engineer/scientist basis). However, please note that the color of the names will return to normal when someone calls a meeting.", "GuardianInfoLong": "(Crewmates):\nAs the Guardian, you become immortal upon task completion. Guessers can't even guess you in meetings.", "AddictInfoLong": "(Crewmates):\nAs the Addict, you have a suicide timer. When it expires, you kill yourself.\nThe timer is indicated by the vent cooldown. When the vent cooldown is 0 seconds, you still have a short time to vent.\nIf you don't make it, you die; if you make it, the suicide timer is reset.\nAlso after you vent, no one can interact with you for a defined period.\nAfter; the period is over, and you are immobilized for another defined period, and cannot report any bodies.", @@ -849,7 +836,7 @@ "AdmirerInfoLong": "(Crewmates):\nAs the Admirer, admire a player to make them Crewmate aligned.\nThey'll win with crewmates and not their original team.\n\nYou can only do this once per player.", "TimeMasterInfoLong": "(Crewmates):\nAs the Time Master, use the vents to mark everyone's position.\nWhen using the ability again, every alive player will rewind to the marked positions.\n\nDuring the ability duration, the Time Master gains a time shield, which protects them from death.", "CrusaderInfoLong": "(Tripulantes):\nComo el Defensor, usa su botón de matar para defender a un jugador.\nSi este jugador es atacado, matarás al atacante.", - "AltruistInfoLong": "(Crewmates):\nAs the Altruist, you can sacrifice yourself to revive a dead body using the «Report» button.\nNote: If a dead player has left the game, you report that body normally.\nAlso revived player cannot report self dead body", + "AltruistInfoLong": "(Crewmates):\nAs the Altruist, you can sacrifice yourself to revive a dead body using the «Report» button.\nNote: If a dead player has left the game, you report that body normally.\nAlso revived player cannot report self dead body\nUse vent button to change between Report & Revive.", "ReverieInfoLong": "(Crewmates):\nAs the Reverie, you can kill, but your cooldown starts high.\n\nIt increases if you kill a crewmate and reduces otherwise.\nDepending on the Host's setting, you may misfire on reaching the max kill cooldown, and your target dies with you. \n\nYou win with other crewmates.", "LookoutInfoLong": "(Tripulantes)\nComo el Vigía, puedes ver los IDs de cada jugador todo el tiempo.\nTe deja ver a través de cambios de forma y camuflajes.", "TelecommunicationInfoLong": "(Crewmates):\nAs the Telecommunication, you are notified when anyone uses cameras, vitals, door logs, or admin.", @@ -872,7 +859,7 @@ "LawyerInfoLong": "(Neutrales):\nEl Abogado tiene un cliente a quien defender, que será indicado con un diamante 「♦」 al lado de su nombre.\nSi tu cliente gana, ganarás.\nSi pierde, perderás.", "OpportunistInfoLong": "(Neutrales):\nSi el Oportunista sobrevive hasta el final, ganará con el equipo ganador.", "VectorInfoLong": "(Neutrals):\nVector will win alone by venting a certain number of times.", - "JackalInfoLong": "(Neutrals):\nAs the Jackal, you win if you are the last player alive. Additionally, you may recruit using the kill button. If the target is not one you can recruit, you have run out of uses, or you don't have the option to recruit, then you will kill people normally (i.e., don't use kill buttons in front of others thinking it'll recruit). If the target has a kill button and the option to turn into a Sidekick is on, they will become a Sidekick. Otherwise, they will gain the Recruit add-on if the option to give the Recruit add-on is on.\nDepending on the settings, when Jackal was killed, a Sidekick will be randomly selected as the new Jackal.\nRecruit may be selected if no sidekick is alive.", + "JackalInfoLong": "(Neutrals):\nAs the Jackal, you win if you are the last player alive. Additionally, you may recruit using the kill button. If the target is not one you can recruit, you have run out of uses, or you don't have the option to recruit, then you will kill people normally (i.e., don't use kill buttons in front of others thinking it'll recruit). If the target has a kill button and the option to turn into a Sidekick is on, they will become a Sidekick. Otherwise, they will gain the Recruit add-on if the option to give the Recruit add-on is on.", "GodInfoLong": "(Neutrals):\nAs the God, you know everyone's role from the beginning. If you live until the end of the game, you steal the win, i.e., everyone else loses, and you win.", "InnocentInfoLong": "(Neutrals):\nThe Innocent can use the kill button to plant any player, and the planted target will immediately kill the Innocent. If the target gets voted out in the meeting, the Innocent wins. Note: Jester, Executioner, and Innocent can win together.", "PelicanInfoLong": "(Neutrals):\nAs the Pelican, you can use the kill button to swallow a player alive, teleporting them off-bounds but not killing them yet. Those swallowed will only die if you're still alive at the end of the round. If you die or leave during the round, all alive swallowed players will spawn into the map where you were.", @@ -884,14 +871,14 @@ "SolsticerInfoLong": "(Neutrals):\nAs the Solsticer, you won't die, and you win by finishing all your tasks in a single round. After every meeting finishes, your tasks reset, and you need to start all over again.\nVotes on the Solsticer will be directly canceled.\nKill attempts on the Solsticer will teleport it out of the map like Pelican until the meeting is finished.\nThe killer's kill cooldown will be reset to 10 seconds.\nSolsticer is counted as nothing in-game.", "CollectorInfoLong": "(Neutrals):\nAs the Collector, when you vote for a player, for each other player that voted for them, you gain a point. When you collect the required votes, the game ends, and you win alone, even if you voted a Jester or Executioner's target out.", "GlitchInfoLong": "(Neutrals):\nAs the Glitch, you can hack players (single click) or kill normally (double click).\nThose who have been hacked cannot kill, vent, or report for the hack duration.\nAdditionally, calling a sabotage other than doors will have no effect and will instead disguise you as a random player. You cannot disguise during or after sabotages.\nTo win, be the last player alive.", - "SidekickInfoLong": "(Neutrals):\nAs the Sidekick, your job is to help the Jackal kill everyone.\nYou and the Jackal win together.\nDepending on the settings, you may turn into Jackal if old Jackal was killed.\nYou may not be able to kill until old Jackal is dead.", + "SidekickInfoLong": "(Neutrales):\nComo el Secuaz, tu trabajo es ayudar el Chacal matar todo.\n\nEl Chacal ganará contigo.", "ProvocateurInfoLong": "(Neutrales):\nEl Provocador puede matar a cualquiera con el botón de matar. Si el objetivo pierde al final del juego, el Provocador gana con los ganadores.", "BloodKnightInfoLong": "(Neutrals):\nThe Blood Knight wins when they're the last killing role alive, and the amount of crewmates is lower or equal to the amount of Blood Knights. The Blood Knight gains a temporary shield after every kill, making them immortal for a few seconds.", "PlagueBearerInfoLong": "(Apocalypse):\nAs the Plaguebearer, plague everyone using your kill button to turn into Pestilence.\nOnce you turn into Pestilence, you will become immortal and gain the ability to kill, and you will kill anyone who tries to kill you.\n\nAlso, when infected players interact with uninfected players, they will also be infected.", "PestilenceInfoLong": "(Apocalypse):\nAs Pestilence, you're an unstoppable machine.\nAny attack towards you will be reflected towards them.\nIndirect kills don't even kill you.\n\nOnly way to kill Pestilence is by voting them out or the Pestilence misguessing.\nYour presence is announced to everyone at the meeting after you transform.", "SoulCollectorInfoLong": "(Apocalypse):\nAs Soul Collector, you can use your kill button on a player to predict their death. You will gain a soul if your target dies in the round you select them or the meeting after.\nYour target resets after each meeting or after they die, whichever comes first. \n\nOnce you collect the configurable amount of souls, you become Death. If the gain passive souls setting is enabled, you will gain a soul each meeting.", "DeathInfoLong": "(Apocalypse):\nOnce the Soul Collector has collected their needed souls, they become Death. Death kills everyone and wins if Death is not ejected by the end of the next meeting.\nA configurable amount of extra meeting time will be given on the meeting Death transforms to have more discussion to find Death.\n\nYou are invincible, and your presence is announced to everyone at the meeting after you transform.", - "BakerInfoLong": "(Apocalypse):\nAs the Baker, you can use your kill button on a player per round to give them bread. \nOnce a set amount of players are alive with bread, you become Famine.\n\nIf the Bread gives additional effects and the setting is on, then you can vent to change the bread that you give out. \nBread Effects:\nReveal: Reveals the target's role to the Baker (stays the whole game)\nRoleblock: Sets the target's kill cooldown to 999 (resets to normal after the meeting)\nBarrier: Gives the target a barrier that is only known to the Baker (barrier is removed after the meeting)", + "BakerInfoLong": "(Apocalypse):\nAs the Baker, you can use your kill button on a player per round to give them bread. \nOnce a set amount of players are alive with bread, you become Famine.\n\nIf the Bread gives additional effects and the setting is on, then you can vent to change the bread that you give out. \nBread Effects:\nReveal: Reveals the target's role to the Baker (stays the whole game)\nRoleblock: Resets the target's kill cooldown when they try to use their kill button\nBarrier: Gives the target a barrier that is only known to the Baker (barrier is removed after the meeting)", "FamineInfoLong": "(Apocalypse):\nOnce the Baker has a set amount of people with bread alive, they will become Famine. If the Famine does not get voted out after the meeting, then they will become Famine, and every player without bread will starve (excluding other Apocalypse members).\nAfter this starvation of everyone without bread, Famine can use their kill button to starve any remaining players, which will kill those players right before the next meeting.\n\nYou are invincible, and your presence is announced to everyone at the meeting after you transform.", "BerserkerInfoLong": "(Apocalypse):\nAs the Berserker, you level up with each kill.\nUpon reaching a certain level defined by the Host, you unlock a new power.\n\nScavenged kills make your kills disappear.\nBombed kills make your kills explode. Be careful when killing, as this can kill your other Apocalypse members if they are near. \nAfter a certain level, you become War.", "WarInfoLong": "(Apocalypse):\nAs War, you are invincible, have a lower kill cooldown, and can kill anyone with your previous powers.\nYour presence is announced to everyone at the meeting after you transform.", @@ -911,12 +898,11 @@ "TraitorInfoLong": "(Neutrals):\nAs the Traitor, you were an Impostor that betrayed the Impostors.\nYou know the Impostors, but they don't know you.\nThe twist? They can kill you, but you can't kill them.\n\nEliminate the Impostors by other means, then kill everyone else to win!", "TrollerInfoLong": "(Neutrals):\nAs a Troller, you can complete tasks so that random events can happen to players.\nFor example, changing the speed of all players, teleportation, influencing sabotage, etc.\nAlso you can win with the winning team.", "VultureInfoLong": "(Neutrales):\nEl Buitre gana reportando cadáveres.\n\nCuando intentes informar de un cadáver, si tu tiempo de espera para comer se haya acabado, te comerás el cadáver, lo que lo hará imposible de reportar.\nSi tu tiempo de espera para comer aún no se acabó o si llegas al límite de cadáveres por ronda, reportarás el cadáver normalmente.", - "AbyssbringerInfoLong": "(Impostors):\nAs the Abyssbringer, you can place black holes. Black holes will suck in players and kill them when colliding with them.", "TaskinatorInfoLong": "(Neutrals):\nAs the Taskinator, whenever you finish a task, the task will be bombed. When another player completes the bombed task, the bomb will detonate, and the player will die.\n\nYou win if you survive till the end and Crew doesn't win.\n\n Note: Taskinator bombs ignore all protection.", "BenefactorInfoLong": "(Crewmates):\nAs the Benefactor, whenever you finish a task, that task will be marked. When another player completes the marked task, they get a temporary shield.\n\n Note: Shield only protects from direct kill attacks.", - "MedusaInfoLong": "(Neutrales):\nLa Medusa puede convertir los cadáveres en piedra, similar a si lo limpiaras.\nLos cadáveres convertidos en piedra no pueden ser reportados.\n\nMáta a todos para ganar.", + "MedusaInfoLong": "(Neutrals):\nAs the Medusa, you can stone bodies much like cleaning a body.\nStoned bodies cannot be reported.\n\nKill everyone to win.", "SpiritcallerInfoLong": "(Neutrals):\nAs the Spiritcaller, your victims become Evil Spirits after they die. These spirits can help you win by freezing other players briefly or blocking their vision. Alternatively, the spirits can give you a shield that protects you briefly from an attempted kill.", - "AmnesiacInfoLong": "(Neutrals):\nAs the Amnesiac, use your report button to remember a target and get its role.\nTo balance the game, you will not be able to vent after remembering your role if you can't vent as Amnesiac.'", + "AmnesiacInfoLong": "(Neutrales):\nEl Amnésico deberá usar el botón de reportar para recordar un rol.\n\nSi el cadáver viene de un Impostor, te transformarás en un Refugiado.\nSi viene de un tripulante, te convertirás en Sheriff.\nSi viene de un neutral pasivo o de un asesino neutral no compatible, te volverás el rol definido en las opciones.\nSi viene de ciertos neutrales asesinos, copiarás su rol.", "ImitatorInfoLong": "(Neutrals):\nAs the Imitator, use your kill button to imitate a player.\n\nYou'll either become a Sheriff, a Refugee, or some Neutral.", "BanditInfoLong": "(Neutrals):\nAs the Bandit, you can click your kill button one time to steal a player's addon and twice to kill. Depending on the settings, you may instantly steal the addon or after the meeting starts. After the maximum number of steals is reached, you will kill normally. Additionally, if there are no stealable addons on the target or the target is stubborn, you will kill the target.\n\nKill everyone to win.\n\nNote: Cleansed, Last Impostor, and Lovers cannot be stolen.\nNote: If Bandit can vent is on, Nimble will become unstealable.", "DoppelgangerInfoLong": "(Neutrals):\nAs the Doppelganger, use your kill button to steal a player's identity (their name and skin) and then kill your target.\n\nKill everyone to win.\n\nNote: You cannot steal the target's identity when Camouflage is active.", @@ -925,19 +911,18 @@ "ShroudInfoLong": "(Neutrals):\nAs the Shroud, you do not kill normally.\nInstead, use your kill button to shroud a player.\nShrouded players kill others.\nIf the shrouded player doesn't make a kill, they'll kill themselves after a meeting.\n\nShroud sees shrouded players with a 「◈」mark next to their name.\nShrouded players who did not make a kill will also have the 「◈」mark in meetings, where they'll die if the Shroud is alive by the end of the meeting.", "WerewolfInfoLong": "(Neutrales):\nEl Hombre Lobo es un asesino que solo puede matar cuando las luces se apaguen.\nEl Hombre Lobo puede sabotear exclusivamente las luces para empezar su racha.\nTendrás un tiempo de espera para matar corto y no te abalanzarás sobre tus víctimas.\n\nLa razón de muerte de tus asesinatos será 'Acometido'.", "ShamanInfoLong": "(Neutrals):\nAs the Shaman, you can use your kill button to select a voodoo doll once per round. If the kill button is used on you, the effect will be deflected onto the voodoo doll.\nIf you survive until the end, you win with the winning team.\nNote: If the killer cannot kill the chosen target, murder is canceled, but if the killer rechecks the Shaman, the killer will kill the Shaman.", - "SeekerInfoLong": "(Neutrals):\nAs the seeker, use your kill button to tag the target. If the seeker tags the wrong player, a point is deducted, and if the seeker tags the correct player, a point will be added.\nAdditionally, the seeker will not be able to move for 5 seconds after every meeting and after getting a new target.\n\nThe seeker needs to collect a certain number of points set by the Host to win.", + "SeekerInfoLong": "(Neutrals):\nAs the seeker, use your kill button to tag the target. If the seeker tags the wrong player, a point is deducted, and if the seeker tags the correct player, a point will be added.\nAdditionally, the seeker will not be able to move for 5 seconds after every meeting and after getting a new target.\n\nThe seeker needs to collect a certain number of points set by the Host to win.\nSeeker will see a ★ mark on target's name.", "PixieInfoLong": "(Neutrals):\nAs the Pixie, Mark up to x amount of targets each round by using the kill button on them. You must have one of the marked targets ejected when the meeting starts. If unsuccessful, you will commit suicide, except if you didn't mark any targets or all the targets are dead. The selected targets reset to 0 after the meeting ends. If you succeed, you will gain a point. You see all your targets in colored names.\n\nYou win with the winning team when you have certain amounts of points set by the Host.", "SchrodingersCatInfoLong": "(Neutrals):\nAs Schrodingers Cat, if someone attempts to use the kill button on you, you will block the action and join their team. This blocking ability works only once. By default, you don't have a victory condition, meaning you win only after switching teams.\nIn Addition to this, you will be counted as nothing in the game.\n\nNote: If the killing machine attempts to use its kill button on you, the interaction is not blocked, and you will die.", "RomanticInfoLong": "(Neutrals):\nThe Romantic can pick their lover partner using their kill button (this can be done at any point of the game). Once they've picked their partner, they can use their kill button to give their partner a temporary shield that protects them from attacks. If their lover partner dies, the Romantic's role will change according to the following conditions:\n1. If their partner was an Impostor, the Romantic becomes the Refugee\n2. If their partner was a Neutral Killer, then they become Ruthless Romantic.\n3. If their partner was a Crewmate or a non-killing neutral, the Romantic becomes the Vengeful Romantic. \n\nThe Romantic wins with the winning team if their partner wins.\nNote: If your role changes, your win condition will be changed accordingly", "RuthlessRomanticInfoLong": "(Neutrals):\nYou change your roles from Romantic if your partner (A neutral killer) is killed. As a Ruthless Romantic, you win if you kill everyone and are the last one standing. If you win, your dead partner will also win with you.", "VengefulRomanticInfoLong": "(Neutrals):\nYou change your roles from Romantic if your partner (A crew or non-neutral killer) is killed. As a Vengeful Romantic, your goal is to avenge your partner, which means you must kill the killer of your partner. If you succeed, then you and your partner win with the winning team at the end. If you try to kill someone other than your partner's killer, then you will die by misfire.", - "PoisonerInfoLong": "(Neutrales):\nEl Envenenador tendrá sus asesinatos retrasados.\nMata a todos para ganar.", - "HexMasterInfoLong": "(Neutrales):\nEl Hechicero puede matar a otros jugadores o hechisarlos.\nHechisando un jugador funciona igual a la Bruja.", + "PoisonerInfoLong": "(Neutrals):\nAs the Poisoner, your kills are delayed.\nKill everyone to win.", + "HexMasterInfoLong": "(Neutrals):\nAs the Hex Master, you can hex players or kill them.\nHexing a player works the same as spelling as a Witch.", "WraithInfoLong": "(Neutrals):\nAs the Wraith, you can vent to Vanish temporarily. You will still appear visible on your screen. Vent again to become visible. You win if you are the last player remaining.", "JinxInfoLong": "(Neutrals):\nAs the Jinx, whenever you get attacked, you jinx them, resulting in them dying to a jinx.\nThis has limited uses.\n\nKill off everyone to win.", "PotionMasterInfoLong": "(Neutrals):\nAs the Potion Master, you have three different potions assigned to three different actions.\n\nSingle click: Reveal role\nDouble click: Kill\nMap: Sabotage\n\nThe reveal potion has a limit.\nWhen you run out, the kill buttons default to killing.", "NecromancerInfoLong": "(Neutrals):\nAs the Necromancer, you win when you're the last one standing.\nAdditionally when someone tries to kill you, you will block the kill, and you will teleport to a random vent. You will have a limited time to kill your killer. If you succeed in doing so, you live. If the time runs out before you kill your killer, you die permanently. If you try to kill someone else other than your killer, you will die.", - "ShockerInfoLong": "(Neutrals):\nAs the Shocker, you can mark rooms by doing tasks in them, and then vent to Electrocute anyone in those rooms for a set period of time. When you finish all of your tasks, you get new ones. Note: Doing tasks during that period will mark them for the next ability use.", "LastImpostorInfoLong": "(Add-ons):\nThis special effect is given to the last surviving Impostor. It significantly reduces their kill cooldown.", "OverclockedInfoLong": "(Add-ons):\nAs the Overclocked, your kill cooldown is reduced by a percentage.\n\nThis feature is only assigned to roles with a kill button.", "LoversInfoLong": "(Add-ons):\nLovers are a combination of two players. The Lovers win when they are the last ones standing, and their victory is shared. When one of the Lovers wins, the other also wins together. Lovers can see the 「♥」 next to each other's name. If one of the Lovers dies, the other will die in love (may not die in love according to the Host's settings). When one of the Lovers is exiled in the meeting, the other will die and become a dead body that cannot be reported.", @@ -958,9 +943,9 @@ "ParanoiaInfoLong": "(Add-ons):\nNot assigned to Neutrals nor Madmates.\nAs the Paranoia, you will be considered as two players in the game to determine when the game ends due to killers having the majority. Additionally, this grants you an extra vote, depending on options.", "MimicInfoLong": "(Add-ons):\nOnly Impostor can become Mimic. When the Mimic is dead, other Impostors will receive a message once a meeting is called. This message will include information on roles which the Mimic killed.", "GuesserInfoLong": "(Add-ons):\nAs a guesser, guess the roles of players in meetings to kill them.\nGuessing the incorrect role kills you instead.\nThe guessing command is: /bt [player id] [role]\nYou can see the player's id before the player's name or use the /id command to view the id of all players.", - "NecroviewInfoLong": "(Agregados):\nEl Nigrovidente puede ver el equipo de los jugadores muertos. La información se mostrará en el nombre del jugador muerto durante las reuniones.\nEl nombre rojo indica a los impostores.\nEl nombre azul claro indica a la tripulación.\nEl nombre gris indica a los neutros.", + "NecroviewInfoLong": "(Add-ons):\nThe Necroview can see the teams of dead players. The following info will be displayed on the dead player's name while in a meeting:\n- The Red name indicates the Impostors.\n- The Cyan name indicates the Crewmates.\n- The Gray name indicates the Neutrals.", "ReachInfoLong": "(Add-on)\nOnly roles with a kill button can get this add-on. Unlike everyone else, you have the longest kill range possible in the game.", - "BaitInfoLong": "(Agregados):\nCuando asesinan a la \"Carnada\", el asesino que mató reportara el cuerpo del jugador con el agregado de \"Carnada\" a fuerzas. Sin embargo, esto no ocurrirá en ciertas situaciones, como cuando es asesinado por el Carroñero, el Limpiador o el Desvanecedor. El reporte puede retrasarse de acuerdo a los ajustes del anfitrión.", + "BaitInfoLong": "(Add-ons):\nWhen the Bait dies, the murderer who killed the Bait will self-report the Bait's body. However, this won't happen when a Scavenger, Cleaner, Swooper, Wraith, Medusa, or Killing Machine kills the Bait. The report may have a delay according to the Host's settings.", "TrapperInfoLong": "(Add-ons):\nWhen Beartrap dies, Beartrap immobilizes killer for a configurable amount of time.", "CharmedInfoLong": "(Agregados):\n Si el Sectario te hechiza, recibirás el complemento Hechizado.\nUna vez hechizado, ahora te unirás al equipo del Sectario y no estarás más en tu equipo original.", "CleansedInfoLong": "(Agregados):\nSólo puedes recibir el complemento Purificado si el Conserje borra todos tus agregados. Dependiendo de las opciones del Purificador, no podrás obtener más agregados en el futuro.", @@ -981,7 +966,7 @@ "RebirthInfoLong": "(Add-ons):\nAs the Rebirth, if you're the player about to be ejected, you will swap skins with a random crewmate who voted for you.\nNotice: The host vote never counts\nRebirth will be removed from you if you exhausted all your rebirths.", "LoyalInfoLong": "(Agregados):\nCon el agregado de \"Leal\", no puedes ser reclutado por roles como el Chacal o el Sectario.\n\nNo se puede asignar a jugadores neutrales.", "EvilSpiritInfoLong": "(Add-ons):\nAs Evil Spirit, it's your job to help the Spiritcaller to victory. You can use your Haunt button to freeze players and reduce their vision. Alternatively, you can use your Haunt button to give the Spiritcaller a shield against a kill attempt temporarily.", - "RecruitInfoLong": "(Betrayal Add-ons):\nAs a recruit, you are on the Jackal's team and help out the Jackal and their Sidekicks.\nYou cannot win with your original team.\nDepending on the settings, you may turn into Jackal if old Jackal was killed and no sidekicks is alive.", + "RecruitInfoLong": "(Agregados):\nCon el agregado de Recluta, eres parte del equipo de Chacales y deberás ayudar al Chacal y a sus Secuaces.\n\nNo puedes ganar con tu equipo original.", "AdmiredInfoLong": "(Agregados):\nCon el agregado de \"Admirado\", ganarás con tu compañero y no con tu equipo original.\n\nPuedes ver quién es el Admirador.", "GlowInfoLong": "(Add-ons):\nDuring lights out, you and players nearby you will receive a vision boost.", "RadarInfoLong": "(Add-ons):\nAs Radar, you have arrows pointing towards the closest person at all times.", @@ -990,7 +975,7 @@ "StubbornInfoLong": "(Add-ons):\nWith the Stubborn add-on, Eraser can't erase your role, Cleanser can't cleanse you, Bandit can't steal from you, and Monarch can't knight you.\nAdditionally, you can't gain any new add-ons from the Merchant.", "SwiftInfoLong": "(Add-ons):\nAs the Swift, you will not make any movement when you kill.\nNote: Swift also ignores Bait", "UnluckyInfoLong": "(Add-ons):\nAs Unlucky, when you complete tasks, kill, venting, or open door, you have a chance to die.", - "SpurtInfoLong": "(Agregos):\nCuando comienzas a caminar, ganas un enorme impulso de velocidad, que rápidamente se deteriorara, hasta que tengas que descansar un rato para recuperar tu velocidad.", + "SpurtInfoLong": "(Add-ons):\nWhen you start walking, you gain an enormous speed boost, which swiftly deteriorates, until you have to rest still for a while to rejuvenate your speed.", "VoidBallotInfoLong": "(Add-ons):\nHolder of this add-on will have 0 vote count.", "AwareInfoLong": "(Add-ons):\nAs the Aware, you get a notification in the next meeting if a revealing role had interacted with you.", "FragileInfoLong": "(Add-ons):\nAs Fragile, you will instantly die if someone tries to use the kill button on you (even if the role cannot directly kill).", @@ -1023,9 +1008,8 @@ "DoubleAgentInfoLong": "(Impostor):\nAs the Double Agent, you cannot access the kill button. However, you can vote for someone in a meeting to pass a bomb onto them, which can only be done one player at a time. Once the meeting has finished, the bomb will activate and explode in a set amount of time.\nNote: when you pass the bomb onto someone in a meeting, you can vote afterward.\n\nAdditionally depending on settings the Double Agent can diffuse Bastion and Agitator bombs when venting.\n\nThe Double Agent can change roles when they are the Last Imposter, depending on the settings the role can be a Admired Impostor, Trickster, Traitor, or stay as the Double Agent.", "SlothInfoLong": "(Add-ons):\nThe Sloth's default movement speed is slower than others.\n(Speed depends on the setting of the Host)", "ProhibitedInfoLong": "(Add-ons):\nAs the Prohibited, you have specific vents that you can't use.\nHow many vents are disabled depends on the Host's settings.", - "EavesdropperInfoLong": "(Agregos):\nComo el Escuchón, tienes la oportunidad de leer otros mensajes basados en roles o complementos como el Funerario o el Sabueso.", + "EavesdropperInfoLong": "(Add-ons):\nAs the Eavesdropper, you have a chance to read other role/addon information-based messages like Mortician or Sleuth.", "ApocalypseInfoLong": "(Apocalypse):\nApocalypse members are on a separate team that works together and wins together. If there are multiple Apocalypse roles in the game, they can see each other's roles.\nDepending on the Host's settings, Apocalypse roles can guess or be guessed.", - "RevenantInfoLong": "(Neutral):\nAs the Revenant, your goal is to be killed. If you are killed, you will take your killer's role and kill your killer instead. You cannot win before being killed.\nNote that Revenant only works when being directly killed.", "ShowTextOverlay": "Superposición de texto", "Overlay.GuesserMode": "Modo de Adivinos", "Overlay.NoGameEnd": "Partida Sin Fin", @@ -1039,8 +1023,6 @@ "AbilityUseLimit": "Límite de uso de habilidades inicial", "AbilityInUse": "Habilidad en uso", "AbilityExpired": "La habilidad se agotó, te quedan {0} usos", - "RevenantTargeted": "Your role has changed to {0}", - "RevenantCanCopyAddons": "Can Steal Addons", "ShowArrows": "Tiene flechas apuntando a cadáveres", "ArrowDelayMin": "Retraso mínimo de aparición de flechas", "ArrowDelayMax": "Retraso máximo de aparición de flechas", @@ -1370,8 +1352,6 @@ "ShieldedCanUseKillButton": "Jugadores protegidos pueden usar boton de habilidad / muerte", "PlayerIsShieldedByGame": "Jugador esta protegido por el juego!", "LegacyNemesis": "Usar Versión Heredada", - "LegacyParasite": "Use Legacy Version", - "LegacyTraitor": "Use Legacy Version", "ArsonistKeepsGameGoing": "El Pirómano hace que la partida continue", "ArsonistCanIgniteAnytime": "Puede prender fuego en cualquier momento", "ArsonistMinPlayersToIgnite": "Mínimo de jugadores a rociar para incendiar", @@ -1483,8 +1463,8 @@ "ShapeshifterBase_ShapeshiftCooldown": "Shapeshift Cooldown", "ShapeshifterBase_ShapeshiftDuration": "Shapeshift Duration", "ShapeshifterBase_LeaveShapeshiftingEvidence": "Leave Shapeshifting Evidence", - "PhantomBase_InvisCooldown": "Tiempo de espera para volverte invisible", - "PhantomBase_InvisDuration": "Duración de invisibilidad", + "PhantomBase_InvisCooldown": "Invis Cooldown", + "PhantomBase_InvisDuration": "Invis Duration", "GuardianAngelBase_ProtectCooldown": "Protect Cooldown", "GuardianAngelBase_ProtectionDuration": "Protection Duration", "GuardianAngelBase_ImpostorsCanSeeProtect": "Protect Visible To Impostors", @@ -1514,18 +1494,6 @@ "SheriffCanKillSeparately": "Opciones individuales", "In%team%": "(Equipo %team%)", "SheriffMisfireKillsTarget": "Un disparo erróneo mata a la víctima", - "BlackHolePlaceCooldown": "Black Hole Place Cooldown", - "BlackHoleDespawnMode": "Black Hole Despawn Mode", - "BlackHoleDespawnTime": "Time After Black Hole Despawns", - "Abyssbringer.Suffix": "<#00ffa5>Number of players consumed by {0} <#00ffa5>active black holes:\\n{1}", - "Abyssbringer.Suffix.BlackHole": "<#00ffa5>{0}: {1}", - "BlackHoleMovesTowardsNearestPlayer": "Black Hole Moves Towards Nearest Player", - "BlackHoleMoveSpeed": "Black Hole Moving Speed", - "BlackHoleRadius": "Black Hole Consuming Radius", - "AfterTime": "After Time", - "After1PlayerEaten": "After 1 Player Was Eaten", - "AfterMeeting": "After Meeting", - "None": "None", "SheriffShotLimit": "Número máximo de asesinatos", "SheriffCanKillAllAlive": "Puede asesinar cuando todo el mundo está vivo", "SheriffCanKillCharmed": "Puede matar a Encantados", @@ -1542,15 +1510,12 @@ "RebirthUses": "Amount of Rebirths", "RebirthCountVotes": "Only rebirth to players who voted for them", "RebirthFailed": "Ahh, how unfortunate, you did not find any viable souls to swap bodies with", - "FireworkerCooldown": "Placement Cooldown", "ReverieIncreaseKillCooldown": "Aumentar el tiempo de espera para matar", "ReverieMaxKillCooldown": "Límite del tiempo de espera para matar", "ReverieMisfireSuicide": "Errar disparo al llegar a tu tiempo de espera máximo para matar", "ReverieResetCooldownMeeting": "Reiniciar tiempo de espera para matar después de una reunión", "ConvertedReverieKillAll": "El ensueño convertido puede matar como le dé la gana si es convertido", "VigilanteNotify": "Te has convertido en lo que juraste destruir", - "DictatorChangeCommandToExpel": "Dictator use Command to expell instad of vote", - "DictatorExpelSelf": "WAIT WAIT WAIT WAT THE HELLLLLL Bro really just want to expel himself", "DoctorTaskCompletedBatteryCharge": "Duración de la batería", "SnitchEnableTargetArrow": "Ve flechas hacia el blanco", "SnitchCanGetArrowColor": "Ve flechas de colores con colores del equipo", @@ -1624,6 +1589,7 @@ "TimeThiefDecreaseMeetingTime": "Reducir el tiempo de la reunión por", "TimeThiefLowerLimitVotingTime": "Tiempo de reunión mínimo", "TimeThiefReturnStolenTimeUponDeath": "Devolver el tiempo robado después de morir", + "TimeThiefMaxTimeOnAdmired": "Maximum Meeting Time if Time Thief Is Admired", "EvilTrackerCanSeeKillFlash": "Puede ver un flash por muertes", "EvilTrackerCanSeeLastRoomInMeeting": "Puede ver la última sala visitada por su objetivo", "EvilTrackerTargetMode": "Puede elejir a su objetivo", @@ -1631,7 +1597,6 @@ "EvilTrackerTargetMode.OnceInGame": "Once in-game", "EvilTrackerTargetMode.EveryMeeting": "Cada reunión", "EvilTrackerTargetMode.Always": "En cualquier momento", - "ScavengerHasCustomDeathReason": "Enable Custom Death Reason", "EvilHackerCanSeeDeadMark": "Puedes ver las ubicaciones de los cadáveres", "EvilHackerCanSeeImpostorMark": "Puedes ver las ubicaciones de los otros impostores", "EvilHackerCanSeeKillFlash": "Puede ver destellos de muertes", @@ -1701,8 +1666,8 @@ "BaitDelayNotify": "Notificar al asesino sobre el auto-informe que va a suceder", "BecomeBaitDelayNotify": "Notificar al asesino sobre el auto-informe que va a suceder", "BaitNotification": "Revelar la Carnada en la primera reunión", - "BaitAdviceAlive": "{0} es la Carnada. Quien lo mate hará un auto-informe.", - "BaitCanBeReportedUnderAllConditions": "La Carnada puede provocar Auto-Informe aún si el sabotaje de comunicaciones desactivan los informes", + "BaitAdviceAlive": "{0} is the Bait. Whoever kills the Bait will commit self-report.", + "BaitCanBeReportedUnderAllConditions": "Bait Can Be Reported even if a meeting is disabled during comms sabotage", "DeceiverAbilityLost": "El Falsificador pierde su habilidad al vender falsificaciones a un jugador inocente", "AddictSuicideTimer": "Tiempo antes del suicidio", "GrenadierSkillCooldown": "Tiempo de espera de la granada", @@ -1864,21 +1829,13 @@ "Jackal_SidekickCountMode_Jackal": "Jackal", "Jackal_SidekickCountMode_Original": "Original Team", "Jackal_SidekickAssignMode": "Sidekick Assign Mode", - "Jackal_SidekickAssignMode_SidekickAndRecruit": "Sidekick when failed Recruit", - "Jackal_SidekickAssignMode_Sidekick": "Only Sidekick", - "Jackal_SidekickAssignMode_Recruit": "Only Recruit", + "Jackal_SidekickAssignMode_SidekickAndRecruit": "Sidekick+Recruit", + "Jackal_SidekickAssignMode_Sidekick": "Sidekick Only", + "Jackal_SidekickAssignMode_Recruit": "Recruit Only", + "JackalWinWithSidekick": "El Chacal puede ganar con sus Secuaces", "Jackal_SidekickCanKillSidekick": "Sidekicks can kill other Sidekicks", "Jackal_SidekickCanKillJackal": "Sidekick can kill Jackal", - "Jackal_RecruitFailed": "You can not recruit this player!", "JackalCanKillSidekick": "El Chacal puede matar a sus Secuaces", - "Jackal_SidekickCanKillWhenJackalAlive": "Sidekick can kill while Jackal is Alive", - "Jackal_SidekickTurnIntoJackal": "Sidekick can turn into Jackal after its death", - "Jackal_RestoreLimitOnNewJackal": "Restore Recruit limit when Sidekick become new Jackal", - "Jackal_OnBecomeNewJackalMeeting": "The old Jackal {0} is dead.\nYou are selected as new Jackal\nWork together and win the game!", - "Jackal_OnNewJackalSelectedMeeting": "The old Jackal {0} is dead.\n{1} is selected as new Jackal!\nWork together and win the game!", - "Jackal_BecomeNewJackal": "Old Jackal Dead, You are now new Jackal!", - "Jackal_OnNewJackalSelected": "Old Jackal Dead, Please help new Jackal {0} for now!", - "Jackal_BossIsDead": "Opps, the Jackal boss is dead!", "CoronerArrowsPointingToDeadBody": "Arrows pointing to dead bodies", "CoronerLeaveDeadBodyUnreportable": "Bodies the Coroner uses can't be reported", "CoronerInformKillerBeingTracked": "Inform the Killer that he gets tracked", @@ -1916,9 +1873,6 @@ "VipTag": "VIP★", "ApplyVipList": "Usar la lista de VIPs", "AllowSayCommand": "Permitir el uso del comando /say", - "AllowStartCommand": "Allow moderators to use /start command", - "StartCommandMinCountdown": "Minimum countdown for /start command", - "StartCommandMaxCountdown": "Maximum countdown for /start command", "KickCommandDisabled": "El comando de expulsión está desactivado.", "KickCommandNoAccess": "No tienes acceso al comando para expulsar.", "KickCommandInvalidID": "Invalid player ID specified.\nPlease use '/kick [playerID] [reason]' to kick a player.\nExample :- /kick 5 not following rules", @@ -1951,11 +1905,6 @@ "WarnCommandNoAccess": "No tienes permiso para usar el comando warn.", "WarnCommandInvalidID": "ID de jugador especificado no válido.\nPor favor, use /warn [ID de jugador] [razón] para advertir a un jugador.\nPor ejemplo, /warn 5 hablar durante la cinemática de exilio", "WarnCommandWarnHost": "No puedes dar advertencias al anfitrión.", - "StartCommandNoAccess": "You do not have access to the start command.", - "StartCommandDisabled": "The start command is currently disabled.", - "StartCommandCountdown": "ERROR\n\nThe game is already starting!", - "StartCommandStarted": "The game has been started by {0}!", - "StartCommandInvalidCountdown": "ERROR\n\nThe countdown must be between {0} and {1}!", "WarnCommandWarnMod": "No puedes dar advertencias a otros moderadores.", "WarnCommandWarned": "ha sido advertido. No habrá más avisos y acciones apropiadas serán tomadas ", "WarnExample": "Usa /warn [id] [razón] en el futuro. \nPor ejemplo:- /warn 5 hablar durante la cinemática de exilio", @@ -1983,7 +1932,6 @@ "DeathReason.Quantization": "Quantificado", "DeathReason.Overtired": "Agotado", "DeathReason.Ashamed": "Avergonzado", - "DeathReason.Consumed": "Consumed", "DeathReason.PissedOff": "Destruido", "DeathReason.Dismembered": "Descuartizado", "DeathReason.LossOfHead": "Estrangulado", @@ -2007,8 +1955,6 @@ "DeathReason.Starved": "Starved", "DeathReason.Equilibrium": "Equilibrium", "DeathReason.Sacrificed": "Sacrificed", - "DeathReason.Electrocuted": "Electrocuted", - "DeathReason.Scavenged": "Scavenged", "OnlyEnabledDeathReasons": "Solo usar Causas de Muerte activadas", "Alive": "Vivo", "Disconnected": "Disconnected", @@ -2024,10 +1970,11 @@ "DeputyHandcuffCooldown": "Tiempo de espera para esposar", "DeputyHandcuffMax": "Número de esposas", "DeputyHandcuffedPlayer": "Objetivo esposado", - "HandcuffedByDeputy": "¡Has sido esposado!", - "DeputyInvalidTarget": "El objetivo no puede ser esposado", + "HandcuffedByDeputy": "You were handcuffed!\nNow you have broken your handcuff and can kill again.", + "DeputyInvalidTarget": "Target is already handcuffed", + "HandcuffBrokenAfterMeeting": "Remove all handcuffs after meeting", "DeputyHandcuffText": "Esposas", - "DeputyHandcuffCDForTarget": "Tiempo de espera para el jugador esposado", + "DeputyHandcuffCDForTarget": "Next Kill Cooldown for handcuffed player", "RejectShapeshift.AbilityWasUsed": "Habilidad fue usado", "EscapisMtarkedPosition": "You marked self-position", "InvestigateCooldown": "Tiempo de espera para investigar", @@ -2074,7 +2021,6 @@ "Command.dump": "→ Poner los Registros en el Escritorio", "Command.death": "→ Muestra información de cómo has muerto", "Command.icons": "
╳ - The Player was marked by the Blackmailer and can't talk during the Meeting
☆ - Used by Captain to display themselves. Only Crewmates can see the Captain's star
乂 - This player was hexed by the Hex Master and will die if the Hex Master isn't killed or ejected by the end of the Meeting.
♦ - Used by Lawyer or Executioner or Follower.
♥ - Used by Lovers or Romantic.
✚ - Used by Medic to mark their target.
⦿ - This player is in a duel with the Pirate.
!? - This player was marked by the Quizmaster and must answer the question correctly to survive.
☜ - Used by Schrödinger's cat to mark their teammate.
◈ - This player marked by the Shroud and will die if the Shroud is not killed or ejected by the end of the meeting.
⚠ - This player is a Snitch or Solsticer who has finished their tasks.
★ - Used by Super Star or Cyber or Marshall.
† - This player was spelled and will die if the Witch is not killed by the end of the meeting.
∇ - Used by Kamikaze to mark their targets.
■ - Used by Lightning to mark their quantum ghosts.
⊠ - Used by Jailer to mark their prisoner.
● - Used by Baker to mark who has Bread.
♠ - Used by Soul Collector to mark who's death they're predicting.
⦿ - Used by Plaguebearer to mark who they have plagued.", - "Command.start": "[Seconds] → Start the game", "Command.iconinfo": "→ Mostrar información sobre los iconos de reuniones", "Command.iconhelp": "→ Mostrar información sobre los iconos de reuniones a todo el mundo", "Command.Poll": "→ Start a poll with up-to 5 choices", @@ -2087,7 +2033,6 @@ "ShowMadmatesInLeftCommand": "Show Madmates (including add-ons)", "ShowApocalypseInLeftCommand": "Show Neutral Apocalypse", "SeeEjectedRolesInMeeting": "Ver los roles de los exiliados en las reuniones", - "ThankYouForUsingTOHE": "Thank you for using TOHE!", "SkillUsedLeft": "Has activado tu habilidad para llamar una reunión. \nUsos restantes:", "NemesisDeadMsg": "The death of the Nemesis means the beginning of the revenge. \nPlease use /rv + [player ID] to kill the specified player \nYou can see player IDs in front of their names. \nOr type /rv to get a list of player IDs", "NemesisAliveKill": "Revenge for the Nemesis can only begin after their death.", @@ -2104,10 +2049,9 @@ "WorkaholicAdviceAlive": "No se recomiende matar o exiliar a [{0}]. Hacerlo conlleva a que pueda terminar sus tareas más rápido.", "GuessDead": "Desafortunadamente, no puedes adivinar otros roles al morir", "GuessSuperStar": "The Super Star can't be guessed... you thought it would be that easy, right?", - "GuessNotifiedBait": "La Carnada no puede ser adivinado porque fue anunciado. Creías que sería tan fácil, ¿verdad?", + "GuessNotifiedBait": "Bait can't be guessed because it was announced. You thought it would be that easy, right?", "GuessGM": "Adivinar al Maestro del Juego es imposible porque ya está muerto... ¿Y por qué le harías eso al pobre Anfitrión?", "GuessGuardianTask": "No puedes adivinar a un Guardian que haya acabado sus tareas.", - "GuardianCantKilled": "You can't kill a Guardian who has finished their tasks.", "GuessMarshallTask": "No puedes adivinar a un Mariscal que haya terminado sus tareas.", "GuessObviousAddon": "Lo sentimos, pero no se puede adivinar ningún agregado obvio.", "GuessAdtRole": "Desgraciadamente, el Anfitrión no te deja adivinar agregados", @@ -2147,9 +2091,9 @@ "MediumNotifyTarget": "{0}, the Medium, has established contact with you. Before the end of this meeting, you have a chance to respond to their question. Type one of the following commands to answer:\nConfirm: /ms yes\nDeny: /ms no", "MediumNotifySelf": "You established contact with {0}. Please ask them questions and wait for them to respond.\n\nRemaining ability uses: {1}", "MediumKnowPlayerDead": "Someone died somewhere", - "SpurtMinSpeed": "Velocidad Mínima", - "SpurtMaxSpeed": "Velocidad Máxima", - "SpurtModule": "Modulador de Velocidad", + "SpurtMinSpeed": "Min Speed", + "SpurtMaxSpeed": "Max Speed", + "SpurtModule": "Speed Modulator", "EnableSpurtCharge": "Muestra la carga", "SpurtSuffix": "\n« Spurt: {0}% »", "TargetIsAlreadyDead": "Target Is Already Dead", @@ -2163,7 +2107,6 @@ "BecomeMadmateCuzMadmateMode": "Te volviste un Cómplice porque has muerto", "CleanerCleanBody": "El cadáver ha sido limpiado", "QuickShooterStoraging": "Balas guardado con éxito", - "QuickShooterFailed": "You are still in cooldown.", "PoisonerTargetDead": "Tu objetivo ha muerto", "HexesLookLikeSpells": "Los Maleficios aparecen como Hechizos", "HexButtonText": "Maleficio", @@ -2322,7 +2265,6 @@ "Message.YTPlanNotice": "Nota: El [Plan de Youtuber] está activado en esta sala. Cual significa que el Anfitrión puede especificar el rol que quiera para la próxima partida para simplificarle la vida en el momento de crear contenido. Si abusa de esta función, sal de la sala o denúncialo.\nCredenciales del Creador:", "Message.OnlyCanBeUsedByHost": "ERROR\n\nEste comando es exclusivo al Anfitrión.", "Message.MaxPlayers": "Máximo de jugadores configurado a ", - "Message.MaxPlayersFailByRegion": "Could not set max players: Vanilla regions support a maximum of 15 players.", "Message.GhostRoleInfo": "Ghost Role Info\nHiya! A little about ghost roles...\n\nGhost roles drastically impact the game, so it's not recommended for smaller lobbies if you're unfamiliar. If not explicitly stated otherwise in the description, the Guard button is their ability button ;)\n\nSpawning:\nGhost-roles only spawn after death; the first x people from (team) to die get them.\n\nPS: If your previous role didn't have tasks(e.g., sheriff), your tasks as a ghost-role aren't needed for task-win", "ApocalypseInfoTitle": "Neutral Apocalypse Info:", "Message.ApocalypseInfo": "Every role of the <#ff174f>Apocalypse Team has their own objective to carry out in order to transform.\n<#2B0804>Transformed <#ff174f>Apocalypse members have a drastic change on the game and are immortal (except for being voted), but everyone will be notified that they have transformed.\n\nRoles: <#e5f6b4>Plaguebearer, <#A675A1>Soul Collector, <#bf9f7a>Baker, <#cc0044>Berserker\nTransformed: <#343136>Pestilence, <#644661>Death, <#83461c>Famine, <#2B0804>War\n\nApocalypse members can see eachother's roles and ability icons.\nLike Neutral Killers, Apocalypse members keep the game going as well, have fun!", @@ -2454,6 +2396,7 @@ "LastResult": "★ Resultados de la Partida", "LastEndReason": "★ Razón del Desenlace", "KillLog": "Registro de Asesinatos", + "MainRoleLog": "Role Convert Log", "Maximum": "Máximo", "RoleRate": "ENCENDER", "RoleOn": "SIEMPRES", @@ -2640,7 +2583,7 @@ "NeutralRemain": "\n{0} Asesinos Neutrales restantes", "OneNeutralRemain": "\n{0} Asesino Neutro restante", "ApocRemain": "\n{0} Neutral Apocalypse remains", - "GameOverReason.HumansByVote": "Todos los Impostores y Asesinos Neutrales fueron exiliados o asesinados", + "GameOverReason.HumansByVote": "All Impostors and Neutral Killers were ejected or killed", "GameOverReason.HumansByTask": "Los Tripulantes completaron sus tareas", "GameOverReason.HumansDisconnect": "Los Tripulantes se desconectaron", "GameOverReason.ImpostorByVote": "Los Tripulantes fueron exiliados", @@ -2730,9 +2673,8 @@ "DeathMeetingTimeIncrease": "Increased Meeting time when Death exists", "SoulCollectorMeetingDeath": "Your target has died during the meeting. You have gained a soul.", "SoulCollectorKillButtonText": "Predict", - "SoulCollectorHasImpostorVision": "Soul Collector has Impostor vision", "ApocalypseIsNigh": "[ The Apocalypse Is Nigh! ]", - "ApocalypseImmune": "This role is immune!", + "ApocalypseImmune": "¡Este jugador es inmune porque es invencible!", "BakerToFamine": "¡¡¡¡¡¡Te has convertido en Hambruna!!!", "BakerTransform": "The Baker has transformed into Famine, Horseman of the Apocalypse! A famine has begun!", "BakerAlreadyBreaded": "¡Ese jugador ya tiene pan!", @@ -2741,15 +2683,13 @@ "BakerBreadNeededToTransform": "Número requerido de pan para ser Hambruna", "BakerCantBreadApoc": "¡No puedes matar de hambre a otros miembros del Apocalipsis!", "BakerKillButtonText": "Pan", - "BakerUnshiftButtonText": "Switch Bread", "BakerRevealBread": "Revela", "BakerRoleblockBread": "Bloque de Rol", "BakerBarrierBread": "Barrera", "BakerCurrentBread": "Pan Actual: ", "BakerSwitchBread": "Pan a cambiado a: ", - "BakerCanVent": "Baker can Vent", + "BakerCanVent": "Panadero puede usar los conductos", "BakerBreadGivesEffects": "El pan da efectos adicionales", - "BakerTransformNoMoreBread": "Baker transforms if they do not have enough bread", "FamineKillButtonText": "Hambre", "FamineStarveCooldown": "Tiempo de espera de la Hambruna para matar de hambre", "FamineCantStarveApoc": "¡No puedes matar de hambre a otros miembros del Apocalipsis!", @@ -2796,7 +2736,6 @@ "GodfatherTargetCountMode": "El asesino se convierte en", "GodfatherCount_Refugee": "Refugiado", "GodfatherCount_Madmate": "Loco", - "GodfatherRefugeeMsg": "You have been recruited by GodFather!", "MissChance": "Posibilidad de fracaso", "IncreaseByOneIfConvert": "Increase The KillCount +1 If a Crew Is Converted", "HawkMissed": "Fallastes!", @@ -2829,7 +2768,6 @@ "BerserkerToWar": "¡¡¡Te has convertido en Guerra!!!", "BerserkerTransform": "The Berserker has transformed into War, Horseman of the Apocalypse! Cry 'Havoc!', and let slip the dogs of war.", "WarKillCooldown": "Tiempo de espera para muertes de guerra", - "BerserkerCanKillTeamate": "Can kill other Neutral Apocalypse", "BlackmailerSkillCooldown": "Tiempo de espera para extorsionar", "BlackmailerMax": "Veces máximas en las que jugadores extorsionados podrán hablar", "BlackmailerDead": "¡Aviso! ¡{0} ha sido extorsionado por un Extorsionista! (No podrá hablar durante esta reunión)!", @@ -2919,8 +2857,6 @@ "RememberedPursuer": "¡Has recordado ser un Perseguidor!", "RememberedFollower": "¡Has recordado ser un Seguidor!", "RememberedAmnesiac": "Fallaste al intentar recordar tu rol.", - "AmnesiacRemembered": "You remembered you were {0}!", - "ReportWhenFailedRemember": "Report Dead Body when failed to remember", "RememberedImitator": "Recordaste que eras un Imitador.", "RememberedImpostor": "¡Recordaste que eras un Impostor!", "RememberedCrewmate": "¡Recordaste que eras un Tripulante!", @@ -2941,7 +2877,7 @@ "BanditStealCooldown": "Tiempo de espera para robar", "DoppelMaxSteals": "Robos Máximos", "DoppelCurrentVictimCanSeeRolesAsDead": "La última víctima puede ver los roles de los jugadores vivos y la información adicional como un fantasma", - "NecromancerRevengeTime": "Tiempo de la Necromancia", + "NecromancerRevengeTime": "Necromancy time", "NecromancerRevenge": "Tienes {0} segundos para matar a {1}", "NecromancerSuccess": "¡Necromancia completa! Vives para ver otro día.", "NecromancerHide": "¡Usar ducto está deshabilitado, escóndete del Nigromante!", @@ -2990,7 +2926,7 @@ "InspectCheckTargetMsg": " fue revisado por un Inspector.", "InspectCheckHelp": "Instrucciones: /cp [ID de jugador 1] [ID de jugador 2] \nEjemplo: /cmp 1 5 \nPuedes ver las IDs de jugadores al lado del nombre de todos \n o usar el comando /id para ver la lista de todas las IDs de jugadores", "InspectCheckNull": "Por favor, selecciona el ID de un jugador vivo para revisar si están en el mismo equipo", - "InspectCheckBaitCountMode": "Carnada cuenta como un rol que revela si la opción de que Carnada revela a la primera reunión está encendida", + "InspectCheckBaitCountMode": "Carnada cuenta como un rol que revela si la opción de que Carnada revela en primera reunión está encendida", "InspectCheckRevealTarget": "Cuando las tareas sean terminadas, el objetivo sabra el equipo de otro objetivo", "InspectorTargetReveal": " Parece ser que {0} está alineado con el equipo {1}", "EgoistCountMode.Original": "Original", @@ -3146,7 +3082,7 @@ "DollMaster_PossessedTarget": "Objetivo Poseido", "DollMaster_CannotPossessImpTeammate": "No es posible poseer el cuerpo tu compañero de equipo", "DollMaster_CouldNotSwapWithTarget": "No es posible poseer el jugador", - "DollMaster_CanNotSwapWithDeadTarget": "Poseer a un jugador muerto no es posible", + "DollMaster_CanNotSwapWithDeadTarget": "Possessing a dead player isn't possible", "DollMaster_MainBody": "Cuerpo Original", "DollMaster_Doll": "Muñeco", "DollMaster_UnableToUseAbility": "Incapaz de usar tu habilidad sobre el jugador", @@ -3164,7 +3100,7 @@ "PitfallTrapCauseVisionTime": "Tiempo de visión reducida por una trampa", "PitfallTrap": "¡Has caído en una trampa!", "ConsigliereDivinationMaxCount": "Revelaciones máximas", - "RitualMaxCount": "Revelaciones Máximas", + "RitualMaxCount": "Maximum Reveals", "CleanserHideVote": "Esconder el voto del Conserje", "OracleSkillLimit": "Usos Máximos", "OracleHideVote": "Esconder el voto del Oráculo", @@ -3334,12 +3270,9 @@ "PixieTargetAlreadySelected": "Ya has elegido a esta persona. Aunque la odies, solo la puedes seleccionar una vez", "PixieButtonText": "Marcar", "PlagueBearerCooldown": "Tiempo de espera para pasar plaga", - "PlagueBearerCanVent": "Can vent", - "PlagueBearerHasImpostorVision": "Has Impostor vision", "PestilenceCooldown": "Tiempo de espera para matar de la Pestilencia", "PestilenceCanVent": "La Pestilencia Puede Usar Ducto", "PestilenceHasImpostorVision": "La Pestilencia Tiene Visión de Impostor", - "PestilenceKillGuessers": "Kill players who guess Pestilence", "PlagueBearerAlreadyPlagued": "El Jugador ya tenía la plaga", "PlagueBearerToPestilence": "¡¡Te has convertido en la Pestilencia!!", "GuessPestilence": "¡Has intentado adivinar la Pestilencia!\n\nLo sentimos, la Pestilencia te mató.", @@ -3383,7 +3316,6 @@ "EveryoneCanKnowMini": "Todos pueden ver al Mini", "CanBeEvil": "El Mini puede ser un Impostor", "EvilMiniSpawnChances": "Probabilidad de que el Mini sea un Impostor", - "EvilMiniCanBeGuessed": "Evil Mini can be guessed before 18", "GuessMini": "Lo sentimos, pero no puedes herir a un Mini.", "GrowUpDuration": "Tiempo requerido para crecer", "MajorCooldown": "Tiempo de espera para matar cuando se tiene más de 18", @@ -3525,7 +3457,6 @@ "WinnerRoleText.Doppelganger": "El Doble Gana!", "WinnerRoleText.Quizmaster": "El Interrogador ha Ganado!", "WinnerRoleText.Agitater": "¡El Agitador ha Ganado!", - "WinnerRoleText.Shocker": "Shocker Wins!", "AdditionalWinnerRoleText.Sidekick": "Secuaz", "AdditionalWinnerRoleText.Taskinator": "Tarearista", "AdditionalWinnerRoleText.Opportunist": "Oportunista", @@ -3568,8 +3499,8 @@ "InfluencedChangeVote": "¡Uy! ¡Fuiste influenciado por los otros!\n¡No pudiste contener tu miedo y tu voto ha cambiado a {0}!", "FFA": "Todos Contra Todos", "ModeFFA": "Modo de Juego: TCT", - "ModeDescribe.FFA": "En el modo de juego TCT (Todos Contra Todos), todos son asesinos y se puede matar a quien sea. El último jugador con vida gana.\n\nAlgunos eventos pondrán hacer que esto sea mucho mas divertido de vez en cuando!", - "KillerInfoLong": "En el modo de juego TCT (Todos Contra Todos), todos son asesinos y se puede matar a quien sea. El último jugador con vida gana.\n\nAlgunos eventos pondrán hacer que esto sea mucho mas divertido de vez en cuando!", + "ModeDescribe.FFA": "In the FFA (Free For All) gamemode, everyone is a killer, and everyone can kill anyone. The last player alive wins!\n\nSome random events make this even more fun in the meantime!", + "KillerInfoLong": "In the FFA (Free For All) game mode, everyone is a killer, and everyone can kill anyone. The last player alive wins!\n\nSome random events make this even more fun in the meantime!", "FFA_GameTime": "Duración Máxima del Juego", "FFA_KCD": "Tiempo de Espera para Matar", "FFA_DisableVentingWhenTwoPlayersAlive": "Prevenir uso de conductos cuando solo dos jugadores estan vivos", @@ -3611,7 +3542,7 @@ "SolsticerOnMeeting": "¡Fuiste testigo de demasiadas muertes! ¡Tendrás {0} tareas cortas más durante la siguiente ronda!", "SolsticerTitle": "Solicitador", "GuessSolsticer": "Lo lamento, pero no puedes adivinar al Solicitador!", - "ExpelSolsticer": "Sorry, but you can not expel Solsticer!", + "VoteSolsticer": "Lo lamento, pero no puedes votar por el Solicitador!", "SolsticerTasksReset": "Tus tareas fueron reiniciadas!", "SolsticerMisGuessed": "Tu intento de adivinar fue errónia. Ya no podrás adivinar.", "SolsticerGuessMax": "Como ya te has ecivocado de adivinar, no seras permetido a adivinar.", @@ -3712,19 +3643,6 @@ "MinionAbilityTime": "Duración del Habilidad", "Minion_Blind": "cegado", "Evader_ChanceNotExiled": "Probabilidad de no ser exiliado", - "ShockerAbilityCooldown": "Ability Cooldown", - "ShockerAbilityDuration": "Ability Duration", - "ShockerAbilityPerRound": "Abilities Per Round", - "ShockerShockInVents": "Shock people in vents", - "ShockerAbilityResetAfterMeeting": "Reset marked rooms after meeting", - "ShockerOutsideRadius": "Radius Of Outside Tasks (not in a room)", - "ShockerCanShockHimself": "Can Shock Himself", - "ShockerImpostorVision": "Shocker has Impostor vision", - "ShockerIsShocking": "You're already shocking!", - "ShockerAbilityActivate": "Begin Shocking!", - "ShockerAbilityDeactivate": "Ability Deactivated", - "ShockerVentButtonText": "Shock", - "ShockerRoomMarked": "Marked Room", "EavesdropperMsgTitle": "Has encontrado un secreto", "EavesdropPercentChance": "Oportunidad de escuchar", "ChiefOfPoliceSkillCooldown": "Cooldown for recruiting sheriffs", @@ -3736,4 +3654,4 @@ "PolicPreventRecruitNonKiller": "Prevent recruit players without kill button", "PolicSuidiceWhenTargetNotKiller": "Suidices when recruit a non killer or non crewmate", "PolicPassConverted": "Can pass Converted Addon to Sheriff" -} +} \ No newline at end of file diff --git a/Resources/Lang/es_ES.json b/Resources/Lang/es_ES.json index e0bee41b1..e495ea057 100644 --- a/Resources/Lang/es_ES.json +++ b/Resources/Lang/es_ES.json @@ -20,8 +20,6 @@ "SubText.Neutral": "Trabaja de tu parte para hacerte con la victoria", "SubText.Apocalypse": "Become unstoppable with your team", "SubText.Madmate": "Ayuda a los Impostores", - "SubText.Lovers": "Stay alive and win together", - "SubText.Egoist": "Win on your own", "TypeImpostor": "Impostores", "TypeCrewmate": "Tripulantes", "TypeNeutral": "Neutros", @@ -31,9 +29,6 @@ "TeamNeutral": "Neutro", "TeamCrewmate": "Tripulante", "TeamMadmate": "Loco", - "TeamLovers": "Lovers", - "TeamEgoist": "Egoist", - "TeamApocalypse": "Apocalypse", "YouAreCrewmate": "Eres un Tripulante", "YouAreImpostor": "Eres un Impostor", "YouAreNeutral": "Eres Neutro", @@ -225,7 +220,6 @@ "TaskManager": "Administrador De Tareas", "Witness": "Testigo", "Swapper": "Intercambiador", - "ChiefOfPolice": "Chief of Police", "NiceMini": "Mini Amable", "Mini": "Mini", "Spy": "Espía", @@ -254,7 +248,6 @@ "Stalker": "Acosador", "Workaholic": "Trabajólico", "Solsticer": "Empleado del Mes", - "Abyssbringer": "Abyssbringer", "Collector": "Coleccionista", "Provocateur": "Provocador", "BloodKnight": "Caballero Sanguinario", @@ -393,8 +386,6 @@ "Sloth": "Caminante", "Prohibited": "Prohibited", "Eavesdropper": "Eavesdropper", - "Shocker": "Shocker", - "Revenant": "Revenant", "BracketAddons": "Dar Corchetes a Complementos", "EngineerTOHEInfo": "Desplázate en los conductos de ventilación para espiar a los Impostores", "ScientistTOHEInfo": "Accede a las constantes cuando quieras", @@ -513,7 +504,7 @@ "PacifistInfo": "Resetea el tiempo de espera de todos", "RebirthInfo": "Vuelve a la vida", "MonarchInfo": "Da a la tripulación el poder de votos extra", - "AbyssbringerInfo": "Place Black Holes", + "AbyssbringerInfo": "Create Black Holes", "SpurtInfo": "Spring Like A rabbit!", "StealthInfo": "Matar ciega a todos en la habitación", "PenguinInfo": "Arrastra a tus víctimas", @@ -538,7 +529,7 @@ "AdmirerInfo": "Elije a un jugador para que esté de tu parte", "TimeMasterInfo": "ZA WARUDO!", "CrusaderInfo": "Mata a cualquiera que se atreva a tocar a un jugador", - "AltruistInfo": "Da tu vida por otra persona", + "AltruistInfo": "Revive a player\nVent to change between Revive and Report", "ReverieInfo": "Con cada asesinato, matas más rápido", "LookoutInfo": "Ve a través del disfraz", "TelecommunicationInfo": "Vigila el uso de aparatos", @@ -547,7 +538,6 @@ "WitnessInfo": "Ve si alguien ha asesinado recientemente", "GhastlyInfo": "Toma control de otros jugadores", "SwapperInfo": "Intercambia los votos entre dos jugadores", - "ChiefOfPoliceInfo": "Hire Sheriff to Serve the Crews!", "NiceMiniInfo": "Nadie podrá matarte hasta que te vuelvas mayor.", "ArsonistInfo": "Empapa con gasolina a todos y que arda todo", "PyromaniacInfo": "Moja y mátalos a todos", @@ -603,7 +593,7 @@ "VultureInfo": "Cóme cadáveres para ganar", "TaskinatorInfo": "Tareas silenciosas, explosiones mortales", "BenefactorInfo": "¡Completa tus tareas y recompensa a la tripulación!", - "MedusaInfo": "Reporta para convertir cadáveres en piedra", + "MedusaInfo": "Stone bodies by reporting them", "SpiritcallerInfo": "Transforma a tus víctimas en espíritus malignos", "AmnesiacInfo": "Recuerdas el rol de un cadáver", "ImitatorInfo": "Imita el rol de un jugador", @@ -615,19 +605,19 @@ "ShroudInfo": "Cubre a otros para hacerlos asesinar", "WerewolfInfo": "Ahuya y siembra la oscuridad", "ShamanInfo": "Usa vudú para sobrevivir", - "SeekerInfo": "Juegas al escondite con tu blanco", + "SeekerInfo": "Play Hide and Seek with your target\nYour target has a ★ mark.", "PixieInfo": "¡Márcalos y deshazte de ellos!", "OccultistInfo": "Mata y hechiza a tus enemigos", "SchrodingersCatInfo": "El gato está en un estado de estar tanto vivo como muerto hasta que se le observe.", "RomanticInfo": "Proteje a tu compañero para ganar juntos", "VengefulRomanticInfo": "Venga a tu compañero para ganar juntos", "RuthlessRomanticInfo": "Mata a todos para ganar con tu compañero", - "PoisonerInfo": "Mata a todos con retraso", + "PoisonerInfo": "Kill everyone with delayed kills", "HexMasterInfo": "Mata en medio de reuniones maldiciendo a otros", "WraithInfo": "Usa los conductos para desaparecer", - "JinxInfo": "Devuelve el ataque a quien te toque", + "JinxInfo": "Reflect attacks onto your attackers", "PotionMasterInfo": "Usa pociones para ganar", - "NecromancerInfo": "Mata a la tripulación usando demonios nigrófagos", + "NecromancerInfo": "Kill your killer to defy death", "WardenInfo": "(Fantasma) Alerta sobre peligro", "MinionInfo": "(Fantasma) Ciega a los enemigos", "LoversInfo": "Sobrevive y gana juntos", @@ -708,8 +698,6 @@ "SlothInfo": "Vas más despacio", "ProhibitedInfo": "Certain vents are blocked", "EavesdropperInfo": "Listen in on other roles", - "ShockerInfo": "Shock unsuspecting players", - "RevenantInfo": "Take your killer's role", "EngineerTOHEInfoLong": "(Tripulantes):\nEl Ingeniero puede usar los conductos si el Sabotaje de Comunicaciones está inactivo.", "ScientistTOHEInfoLong": "(Tripulantes):\nEl Científico puede ver los constantes en cualquier momento para ver quién está vivo o no.", "NoisemakerTOHEInfoLong": "(Tripulantes):\nEl Alertador hará ruido al morir, y un indicador visual de su muerte aparecerá en la pantalla para que la Tripulación pueda correr hasta el lugar del crimen y atrapar al asesino (Aun si no es Rojo).", @@ -781,11 +769,11 @@ "LurkerInfoLong": "(Impostores):\nEl Acechador puede saltar dentro de un conducto para reducir su tiempo de espera para matar de unos segundos. Después de matar, el tiempo de espera se restablecerá a su valor inicial.", "VisionaryInfoLong": "(Impostores):\nEl Visionario puede ver el equipo de cualquier jugador vivo durante una reunión.\nLa información siguiente se mostrará al jugador.:\n- Los nombres rojos indican a los Impostores.\n- Los nombres en azul claro indican a la Tripulación.\n- Los nombres en gris indican los Neutros.", "PlagueDoctorInfoLong": "(Neutros):\n(Doctor de la Peste de TOH)\nEl objetivo del Científico Plaguista es infectar a todos los jugadores vivos. Comienzan eligiendo a un jugador para infectar, tras lo cual cualquiera que pase una cantidad de tiempo determinada en el rango del jugador infectado se infecta también. El progreso de la infección es acumulativo y no se reinicia con la distancia o después de las reuniones.", - "RefugeeInfoLong": "(Madmates):\nAs the Refugee, you were either:\n -An Amnesiac who remembered an Impostor\n -A killer who killed the Godfather's target.\n -A Romantic whose partner was an Impostor\n -Or an Imitator that imitated an Impostor.\n\nNow your job is to help the Impostors kill the crewmates.", + "RefugeeInfoLong": "(Locos):\nEl rol de Refugiado es dado cuando un Amnésico recuerda a un impostor o cuando un asesino mata al objetivo del Padrino.\n\nSu trabajo ahora es el mismo que el de un impostor normal y corriente: ayudar a los impostores y matar a la tripulación.", "UnderdogInfoLong": "(Impostores):\nEl Indefenso no puede matar hasta que sólo queden un cierto número de jugadores vivos.", "ConsigliereInfoLong": "(Impostores):\nEl Consigliere puede revelar los roles de otros jugadores usando el botón de matar.\n\n- Un clic: Revelar el rol\n- Doble clic: Matar\n\nSi te quedas sin usos de revelar roles, tu botón de matar funcionará normalmente.", "LudopathInfoLong": "(Impostores):\nEl Ludópata tiene un tiempo de espera para matar aleatorio.\n\nEl mínimo es de 1 segundo, el máximo es tu tiempo de espera para matar por defecto.", - "GodfatherInfoLong": "(Impostors):\nAs the Godfather, you vote someone to make them your target.\nIn the next round, if someone kills the target, the killer will turn into a Refugee or Madmate.", + "GodfatherInfoLong": "(Impostores):\nEl Padrino puede votar a alguien para convertirlo en tu objetivo.\nEn la próxima ronda, si alguien lo mata, el asesino se volverá un Refugiado.", "ChronomancerInfoLong": "(Impostors):\nAs the Chronomancer, you have a charge bar which indicates when the slaughter is ready. When it is at 100% the next time you kill someone, you go into slaughter mode, meaning you can kill indefinitely until your bar runs out of charge. Otherwise, you have a normal KCD.", "PitfallInfoLong": "(Impostores):\nLa Trampa puede cambiar de forma para marcar un área alrededor del lugar como una trampa. Cualquier jugador que se acerque a esta área será inmovilizado durante un breve periodo de tiempo y será cegado.", "EvilMiniInfoLong": "(Impostores):\nEl Niño Malvado tendrá un tiempo de espera para matar alto que será reducido drásticamente al convertirse en un adulto. En cambio, mientras que seas un Niño, el resto de la tripulación se siente incapaz de tocarte.", @@ -821,7 +809,7 @@ "GrenadierInfoLong": "(Tripulantes):\nEl Granadero puede usar los conductos para lanzar una Granada de Luz a otros jugadores cercanos, lo que les hace perder la visión si son Impostores o, según la configuración, Neutros.", "MedicInfoLong": "(Tripulantes):\nEl Médico puede darle un escudo a un jugador usando el botón de matar. Solo puede dar un escudo durante todo el juego, y cuando el Médico muere, el escudo del objetivo desaparecerá. El Médico también puede ver si alguien trata de romper el escudo del objetivo. Dependiendo de la configuración del anfitrión, el Médico o el objetivo pueden ver si el jugador tiene un escudo (demostrado con un círculo verde「●」al lado del nombre).", "FortuneTellerInfoLong": "(Tripulantes):\nComo el Vidente, vota por un jugador en una reunión para obtener una pista sobre su rol. \nLa pista estará relacionada con su rol real. \n\nCuando hayas completado las tareas del Vidente, obtendrás el rol exacto en lugar de una pista. \n\nNota:: Si la opción de dar pistas aleatorias de jugadores activos está habilitada, no podrás investigar al mismo jugador varias veces.", - "JudgeInfoLong": "(Tripulantes):\nEl Juez puede juzgar a un jugador durante las reuniones. Si el objetivo es malvado, será sentenciado a muerte (el anfitrión decide si es bueno o malo), y si no, el juez se suicidará.\nEl comando para juzgar es: /tl [Id del jugador]\nEl número al lado del nombre del jugador es su Id, pero puede usar el comando /id para ver la lista de jugadores en el chat.\nUn Juez loco puede juzgar a quien le de la gana.", + "JudgeInfoLong": "(Crewmates):\nThe Judge can judge a certain player during the meeting. If the target is evil, the target will be killed (whether it is evil or not is set by the Host). If it is wrong, the Judge commits suicide.\nCommand for judgment: /tl [player id]\nYou can see the player's id before the player's name, or use the /id command to view the id of all players.\nJudges can judge all players when they become Madmate.\nIn meeting the ability count shows how many trails you have in this meeting. Out of meeting the ability counts shows how many trails you have for the whole game.", "MorticianInfoLong": "(Tripulantes):\nEl Director de Funeraria tendrá flechas que apuntan hacia todos los cadáveres, y si un Funerario informa un cadáver, conocerán a la última persona que estuvo con ellos. Nota: Funerario no será Inconsciente o Vigilante.", "MediumInfoLong": "(Tripulantes):\nEl Médium puede establecer contacto con un jugador muerto. El jugador que informe no tiene que ser el Médium. El jugador muerto puede responder solo una vez diciendo si o no a la pregunta del Médium, cual recibirá la respuesta (El jugador muerto puede usar /ms si o /ms no). Nota: El Médium no puede ser Inconsciente.", "ObserverInfoLong": "(Tripulantes):\nEl Espectador puede ver todas las animaciones de escudo causado por otros jugadores una vez la primera reunión tenga lugar. Esto puede indicar el uso de la habilidad de un rol, por lo que estate atento.", @@ -833,7 +821,7 @@ "MerchantInfoLong": "(Tripulantes):\nEl Mercader vende complementos al azar a otros jugadores por cada tarea que completas. Cada complemento te hará ganar dinero, y si consigues suficiente dinero, puedes evitar que te maten sobornando el asesino.", "RetributionistInfoLong": "(Tripulantes):\nEl Castigador puede matar un número limitado de jugadores después de tu muerte.\n\nUsa /ret [playerID] para matar.", "HawkInfoLong": "(Crewmates [Ghost]):\nAs the Hawk, you can kill a limited amount of players decided by the host, though there's a chance you miss, slicing someone multiple times increases the chances.", - "DeputyInfoLong": "(Tripulantes):\nEl Comisario puede usar su botón de matar en alguien para restaurar su tiempo de recuperación de matar.\n\nSi el blanco no tiene un botón de matar, entonces las esposas fueron un desperdicio.", + "DeputyInfoLong": "(Crewmates):\nAs the Deputy, use your kill button to handcuff a player.\nThe player who is handcuffed will have their next kill attempt treated as a handcuff break, and the kill cooldown will be reset.\n\nIf the target does not have a kill button, then the handcuff was a waste.", "InvestigatorInfoLong": "(Tripulantes):\nComo Investigador, puedes emplear tu botón de investigación para examinar a alguien. Cuando investigues a una persona, su nombre aparecerá en rojo si tienen un botón de asesinato (basado en impostores/SS) o en azul claro si carecen de un botón de asesinato (basado en tripulantes/ingenieros/científicos). No obstante, ten en cuenta que el color de los nombres volverá a la normalidad cuando se convoque una reunión.", "GuardianInfoLong": "(Tripulantes):\nEl Guardián se vuelve inmortal al completar sus tareas. Ni siquiera puedes ser adivinado en las reuniones.", "AddictInfoLong": "(Tripulantes):\nEl Adicto tiene un temporizador. Cuando expira, se suicida.\nEl tiempo de espera para usar un conducto indica su tiempo. Cuando llega a 0, aún tiene un breve período para entrar en un conducto.\nSi no llegas, mueres. Si lo haces, se reinicia el temporizador.\nDespués de entrar en un conducto, nadie puede interactuar contigo durante un tiempo configurable.\nDespués de que este tiempo termine, estarás inmovilizado por otro intervalo de tiempo configurable y no puedes informar ningún cadáver.", @@ -849,7 +837,7 @@ "AdmirerInfoLong": "(Crewmates):\nAs the Admirer, admire a player to make them Crewmate aligned.\nThey'll win with crewmates and not their original team.\n\nYou can only do this once per player.", "TimeMasterInfoLong": "(Tripulantes):\nComo el Maestro del Tiempo, usa los conductos para marcar la posición de todo.\nCuando usas la habilidad de nuevo, cada jugador vivo volverá a las posiciones marcadas.\n\nDurante la duración de la habilidad, el Maestro del Tiempo obtiene un nuevo Escudo de Tiempo que te protege a morir.", "CrusaderInfoLong": "(Tripulantes):\nComo el Defensor, usa su botón de matar para hacer cruzada.\nSi este jugador es asaltada, matará al asaltador.", - "AltruistInfoLong": "(Tripulantes):\nEl Altruista puede sacrificar su vida para revivir a otro jugador usando el botón de informe.\nNOTA: Si el jugador asesinado se ha desconectado, informarás el cadáver normalmente.\nAdemás, el jugador revivido no podrá informar su propio cadáver", + "AltruistInfoLong": "(Crewmates):\nAs the Altruist, you can sacrifice yourself to revive a dead body using the «Report» button.\nNote: If a dead player has left the game, you report that body normally.\nAlso revived player cannot report self dead body\nUse vent button to change between Report & Revive.", "ReverieInfoLong": "(Tripulantes):\nEl ensimismado puede matar, pero tendrá un tiempo de espera bastante grande.\n\nSi matas a un tripulante, aumentará, si no, se reducirá.\nDependiendo de las opciones del Anfitrión, morirás si alcanzas tu tiempo de espera máximo junto con tu víctima.\n\nGanas con los tripulantes.", "LookoutInfoLong": "(Tripulantes)\nEl Centinela puede ver los IDs de cada jugador en cualquier momento.\nEsto permite ver a través de cambios de forma y camuflajes.", "TelecommunicationInfoLong": "(Tripulantes):\nEl Transmisor ve cuando alguien esté echando un vistazo a las cámaras, constantes, registro de puertas, o la mesa de administración.", @@ -872,7 +860,7 @@ "LawyerInfoLong": "(Neutros):\nEl Abogado tiene un cliente a quien defender, que será indicado con un diamante 「♦」 al lado de su nombre.\nSi tu cliente gana, ganarás.\nSi pierde, perderás.", "OpportunistInfoLong": "(Neutros):\nSi el Oportunista sobrevive hasta el final, ganará con el equipo ganador.", "VectorInfoLong": "(Neutros):\nVector ganará solo si usa los conductos un cierto número de veces.", - "JackalInfoLong": "(Neutrals):\nAs the Jackal, you win if you are the last player alive. Additionally, you may recruit using the kill button. If the target is not one you can recruit, you have run out of uses, or you don't have the option to recruit, then you will kill people normally (i.e., don't use kill buttons in front of others thinking it'll recruit). If the target has a kill button and the option to turn into a Sidekick is on, they will become a Sidekick. Otherwise, they will gain the Recruit add-on if the option to give the Recruit add-on is on.\nDepending on the settings, when Jackal was killed, a Sidekick will be randomly selected as the new Jackal.\nRecruit may be selected if no sidekick is alive.", + "JackalInfoLong": "(Neutrals):\nAs the Jackal, you win if you are the last player alive. Additionally, you may recruit using the kill button. If the target is not one you can recruit, you have run out of uses, or you don't have the option to recruit, then you will kill people normally (i.e., don't use kill buttons in front of others thinking it'll recruit). If the target has a kill button and the option to turn into a Sidekick is on, they will become a Sidekick. Otherwise, they will gain the Recruit add-on if the option to give the Recruit add-on is on.", "GodInfoLong": "(Neutros):\nEl Dios conoce el rol de todo el mundo desde el principio. Si sobrevives hasta el final del juego, robarás la victoria. Es decir, todos los demás pierden y tú ganas.", "InnocentInfoLong": "(Neutros):\nEl Inocente puede usar el botón de matar para hacer que otro jugador lo asesine. Si este es votado en cualquier momento de la partida, el Inocente ganará. Nota: El Bufón, el Verdugo y el Inocente pueden ganar juntos.", "PelicanInfoLong": "(Neutros):\nEl Pelícano puede usar el botón de matar para zamparte a un jugador vivo, teletransportándolos fuera del mapa pero sin matarlos directamente. Aquellos que sean tragados morirán sólamente si sigues vivo al final de la ronda. Si mueres o te desconectas durante la ronda, todos los jugadores tragados que sigan vivos aparecerán donde estabas antes de morir o desconectarte.", @@ -884,14 +872,14 @@ "SolsticerInfoLong": "(Neutrals):\nAs the Solsticer, you won't die, and you win by finishing all your tasks in a single round. After every meeting finishes, your tasks reset, and you need to start all over again.\nVotes on the Solsticer will be directly canceled.\nKill attempts on the Solsticer will teleport it out of the map like Pelican until the meeting is finished.\nThe killer's kill cooldown will be reset to 10 seconds.\nSolsticer is counted as nothing in-game.", "CollectorInfoLong": "(Neutros):\nEl Coleccionista puede votar por un jugador. Por cada voto que vaya para ese jugador, ganas un punto. Cuando consigas un cierto número de votos, ganarás, aun si el Bufón o el objetivo del Verdugo fueron exiliados.", "GlitchInfoLong": "(Neutros):\nEl Glitch puede hackear a jugadores (Un clic) o matar normalmente (Doble clic). Aquellos que hayan sido hackeados no pueden matar, usar conductos ni informar durante la duración del hackeo. Además, causar un sabotaje (excluyendo las puertas) no tendrá efecto y, en su lugar, te disfrazará con la apariencia de otro jugador al azar. No puedes disfrazarte en medio de un sabotaje o si ya hubo un sabotaje hace un rato. Para ganar, sé el último jugador en pie.", - "SidekickInfoLong": "(Neutrals):\nAs the Sidekick, your job is to help the Jackal kill everyone.\nYou and the Jackal win together.\nDepending on the settings, you may turn into Jackal if old Jackal was killed.\nYou may not be able to kill until old Jackal is dead.", + "SidekickInfoLong": "(Neutros):\nComo el Secuaz, tu trabajo es ayudar al Chacal a matar a todos.\n\nTú y el Chacal ganáis juntos.", "ProvocateurInfoLong": "(Neutros):\nEl Provocador puede matar a cualquiera con el botón de matar. Si el objetivo pierde al final del juego, el Provocador gana con los ganadores.", "BloodKnightInfoLong": "(Neutros):\nEl Caballero Sanguinario obtiene un escudo temporal después de cada asesinato que lo hace inmortal durante unos segundos.", "PlagueBearerInfoLong": "(Apocalypse):\nAs the Plaguebearer, plague everyone using your kill button to turn into Pestilence.\nOnce you turn into Pestilence, you will become immortal and gain the ability to kill, and you will kill anyone who tries to kill you.\n\nAlso, when infected players interact with uninfected players, they will also be infected.", "PestilenceInfoLong": "(Apocalypse):\nAs Pestilence, you're an unstoppable machine.\nAny attack towards you will be reflected towards them.\nIndirect kills don't even kill you.\n\nOnly way to kill Pestilence is by voting them out or the Pestilence misguessing.\nYour presence is announced to everyone at the meeting after you transform.", "SoulCollectorInfoLong": "(Apocalypse):\nAs Soul Collector, you can use your kill button on a player to predict their death. You will gain a soul if your target dies in the round you select them or the meeting after.\nYour target resets after each meeting or after they die, whichever comes first. \n\nOnce you collect the configurable amount of souls, you become Death. If the gain passive souls setting is enabled, you will gain a soul each meeting.", "DeathInfoLong": "(Apocalypse):\nOnce the Soul Collector has collected their needed souls, they become Death. Death kills everyone and wins if Death is not ejected by the end of the next meeting.\nA configurable amount of extra meeting time will be given on the meeting Death transforms to have more discussion to find Death.\n\nYou are invincible, and your presence is announced to everyone at the meeting after you transform.", - "BakerInfoLong": "(Apocalypse):\nAs the Baker, you can use your kill button on a player per round to give them bread. \nOnce a set amount of players are alive with bread, you become Famine.\n\nIf the Bread gives additional effects and the setting is on, then you can vent to change the bread that you give out. \nBread Effects:\nReveal: Reveals the target's role to the Baker (stays the whole game)\nRoleblock: Sets the target's kill cooldown to 999 (resets to normal after the meeting)\nBarrier: Gives the target a barrier that is only known to the Baker (barrier is removed after the meeting)", + "BakerInfoLong": "(Apocalypse):\nAs the Baker, you can use your kill button on a player per round to give them bread. \nOnce a set amount of players are alive with bread, you become Famine.\n\nIf the Bread gives additional effects and the setting is on, then you can vent to change the bread that you give out. \nBread Effects:\nReveal: Reveals the target's role to the Baker (stays the whole game)\nRoleblock: Resets the target's kill cooldown when they try to use their kill button\nBarrier: Gives the target a barrier that is only known to the Baker (barrier is removed after the meeting)", "FamineInfoLong": "(Apocalypse):\nOnce the Baker has a set amount of people with bread alive, they will become Famine. If the Famine does not get voted out after the meeting, then they will become Famine, and every player without bread will starve (excluding other Apocalypse members).\nAfter this starvation of everyone without bread, Famine can use their kill button to starve any remaining players, which will kill those players right before the next meeting.\n\nYou are invincible, and your presence is announced to everyone at the meeting after you transform.", "BerserkerInfoLong": "(Apocalypse):\nAs the Berserker, you level up with each kill.\nUpon reaching a certain level defined by the Host, you unlock a new power.\n\nScavenged kills make your kills disappear.\nBombed kills make your kills explode. Be careful when killing, as this can kill your other Apocalypse members if they are near. \nAfter a certain level, you become War.", "WarInfoLong": "(Apocalypse):\nAs War, you are invincible, have a lower kill cooldown, and can kill anyone with your previous powers.\nYour presence is announced to everyone at the meeting after you transform.", @@ -911,12 +899,11 @@ "TraitorInfoLong": "(Neutros):\nEl Traidor era un impostor que ha traicionado a los impostores.\nSabes quienes son los impostores, pero ellos no saben quién eres.\n¿Cuál es la traba? Te pueden matar, y no puedes defenderte de ellos.\n\nElimina a los impostores de otro modo, y mata a todos para ganar!", "TrollerInfoLong": "(Neutrals):\nAs a Troller, you can complete tasks so that random events can happen to players.\nFor example, changing the speed of all players, teleportation, influencing sabotage, etc.\nAlso you can win with the winning team.", "VultureInfoLong": "(Neutros):\nEl Buitre gana reportando cadáveres.\n\nCuando intentes informar de un cadáver, si tu tiempo de espera para comer se haya acabado, te comerás el cadáver, lo que lo hará imposible de reportar.\nSi tu tiempo de espera para comer aún no se acabó o si llegas al límite de cadáveres por ronda, reportarás el cadáver normalmente.", - "AbyssbringerInfoLong": "(Impostors):\nAs the Abyssbringer, you can place black holes. Black holes will suck in players and kill them when colliding with them.", "TaskinatorInfoLong": "(Neutros):\nEl Tarea-Ineitor puede poner una bomba en una tarea una vez que la termine. Si otro jugador hace esa tarea, la bomba le explotará en toda la cara, matándolo en el proceso.\n\nGanarás si sobrevives hasta el final y si la Tripulación no gana.\n\n Nota: Las bombas del Tarea-Ineitor ignoran todas las protecciones.", "BenefactorInfoLong": "(Tripulantes):\nAl hacer tareas, el Bienhechor las marcará. Cuando otro tripulante haga esta tarea, recibirá un escudo temporal.\n\n Nota: Los escudos solo protegen contra ataques directos.", - "MedusaInfoLong": "(Neutros):\nMedusa puede convertir los cadáveres en piedra, similar a si lo limpiaras.\nLos cadáveres convertidos en piedra no pueden ser reportados.\n\nMáta a todos para ganar.", + "MedusaInfoLong": "(Neutrals):\nAs the Medusa, you can stone bodies much like cleaning a body.\nStoned bodies cannot be reported.\n\nKill everyone to win.", "SpiritcallerInfoLong": "(Neutros):\nCuando el Capturador de Espíritus mata, sus víctimas se transformarán en Espíritus Malignos al morir. Estos espíritus te ayudarán a alzarte con la victoria congelando a otros jugadores por un tiempo limitado y/o cegándolos. Alternativamente, los espíritus pueden darte un escudo que te proteje brevemente de cualquier intento de asesinato.", - "AmnesiacInfoLong": "(Neutrals):\nAs the Amnesiac, use your report button to remember a target and get its role.\nTo balance the game, you will not be able to vent after remembering your role if you can't vent as Amnesiac.'", + "AmnesiacInfoLong": "(Neutros):\nEl Amnésico deberá usar el botón de informe para recordar un rol.\n\nSi el cadáver viene de un Impostor, te transformarás en un Refugiado.\nSi viene de un tripulante, te convertirás en Sheriff.\nSi viene de un neutro pasivo o de un asesino neutro no compatible, te volverás el rol definido en las opciones.\nSi viene de ciertos neutros asesinos, copiarás su rol.", "ImitatorInfoLong": "(Neutros):\nEl Imitador puede usar su botón de matar para imitar a otra persona.\n\nTe podrás convertir en un Sheriff, Refugiado o en algún Neutro.", "BanditInfoLong": "(Neutrals):\nAs the Bandit, you can click your kill button one time to steal a player's addon and twice to kill. Depending on the settings, you may instantly steal the addon or after the meeting starts. After the maximum number of steals is reached, you will kill normally. Additionally, if there are no stealable addons on the target or the target is stubborn, you will kill the target.\n\nKill everyone to win.\n\nNote: Cleansed, Last Impostor, and Lovers cannot be stolen.\nNote: If Bandit can vent is on, Nimble will become unstealable.", "DoppelgangerInfoLong": "(Neutros):\nEl Doble puede asesinar a otro jugador para robarle su identidad (Su nombre y apariencia).\n\nMátalos a todos para ganar.\n\nNota:- No podrás robar la identidad de tu objetivo si un camuflaje de cualquier tipo está ocurriendo.", @@ -925,14 +912,14 @@ "ShroudInfoLong": "(Neutros):\nLa Mortaja no mata normalmente.\nEn vez de eso, usa el botón de matar para envolver a un jugador.\nLos jugadores envueltos matarán a otros.\nSi el jugador envuelto no mata, se suicidarán después de la reunión.\n\nLa Mortaja ve a los jugadores envueltos con el icono「◈」al lado de sus nombres.\nLos jugadores envueltos que no mataron también verán el icono「◈」 en las reuniones, donde morirán si la Mortaja no es exiliada antes de que termine la reunión.", "WerewolfInfoLong": "(Neutros):\nEl Hombre Lobo puede matar como cualquier asesino.\nEn cambio, cuando mata, cualquier jugador alrededor de tí también morirá.\nCualquier jugador que muera por esto morirá por acechamiento.\n\nPara balancear esto, tienes un tiempo de espera para matar bastante alto.", "ShamanInfoLong": "(Neutros):\nEl Chamán puede usar su botón de asesinato para seleccionar una muñeca vudú una vez por ronda. Si se utiliza el botón de asesinato en el Chamán, la muñeca vudú recibirá el efecto. Si sobrevives hasta el final, ganarás con el equipo ganador.", - "SeekerInfoLong": "(Neutros):\nEl Buscador debe usar su botón de matar para marcar a su objetivo. Si se equivoca, perderá un punto, y si no, gana uno.\nEl Buscador no podrá moverse durante los 5 primeros segundos después de una reunión y después de obtener un nuevo objetivo.\nEl Buscador debe de obtener un cierto número de puntos elegido por el anfitrión para ganar.", + "SeekerInfoLong": "(Neutrals):\nAs the seeker, use your kill button to tag the target. If the seeker tags the wrong player, a point is deducted, and if the seeker tags the correct player, a point will be added.\nAdditionally, the seeker will not be able to move for 5 seconds after every meeting and after getting a new target.\n\nThe seeker needs to collect a certain number of points set by the Host to win.\nSeeker will see a ★ mark on target's name.", "PixieInfoLong": "(Neutros):\nEl Hada puede marcar hasta x objetivos cada ronda utilizando el botón de asesinato en ellos. Cuando comience la reunión, tu trabajo es hacer que uno de los objetivos marcados sea exiliado. Si no lo consigues, te suicidarás, salvo si no marcaste a nadie o si todos los objetivos han muerto. Los objetivos seleccionados se reiniciarán a 0 después de que termine la reunión. Si lo consigues, ganarás un punto. Ves a todos tus objetivos con nombres de colores. \nGanarás con el equipo ganador cuando tengas una cantidad específica de puntos establecida por el anfitrión.", "SchrodingersCatInfoLong": "(Neutros):\nComo el Gato de Schrödinger, si alguien intenta utilizarte el botón de asesinar, impedirás la acción y te integrarás a su equipo. Esta habilidad de impedimento solo se activa una vez. Inicialmente, no posees una condición específica para ganar, por lo que tu victoria depende únicamente de tu integración a otro equipo.\nAdicionalmente, en el juego serás tratado como un ente inexistente.\n\nNota: Si el ejecutor intenta emplear su botón de asesinar contra ti, la interacción no será impedida y resultarás muerto.", "RomanticInfoLong": "(Neutros):\nEl Romántico puede elegir a su amante usando el botón de matar (Posible en cualquier punto de la partida). Una vez que hayan elegido a su pareja, puedes usar el botón de matar para darle un escudo que le proteja temporalmente cualquier ataque directo. Si su pareja muere, el Romántico cambiará de rol, dependiendo de quien fuera la pareja.\nSi era un impostor, te convertirás en un Refugiado.\nSi era un asesino neutro, te convertirás en un Romántico Implacable.\nSi era un tripulante o un neutro no asesino, te convertirás en un Romántico Vengador.\n\nEl Romántico ganará con el equipo ganador si su pareja gana.\nNota: Si tu rol cambia, tu condición de victoria cambiará acordemente", "RuthlessRomanticInfoLong": "(Neutros):\nSi tu pareja era un Asesino Neutro y ha muerto, tu rol pasará de ser Romántico a Romantico Implacable. Ganarás si matas a todos y eres el último en vida. Si ganas, tu pareja ganará contigo.", "VengefulRomanticInfoLong": "(Neutros):\nSi tu pareja era un tripulante o un neutro no asesino y ha muerto, tu rol pasará de ser Romántico a Romántico Vengador. Tendrás que matar al asesino de tu pareja para vengarlo. Si lo consigues, tú y tu pareja ganarán con el equipo ganador al final de la partida. Si intentas matar a alguien que no sea el asesino de tu pareja, fallarás el tiro y morirás.", - "PoisonerInfoLong": "(Neutros):\nEl Envenenador tendrá sus asesinatos retrasados.\nMata a todos para ganar.", - "HexMasterInfoLong": "(Neutros):\nComo el Hechicero, puedes maldecir a jugadores o matarlos.\nMaldicir a un jugador funciona de la misma manera que hechizarlo como una Bruja.", + "PoisonerInfoLong": "(Neutrals):\nAs the Poisoner, your kills are delayed.\nKill everyone to win.", + "HexMasterInfoLong": "(Neutrals):\nAs the Hex Master, you can hex players or kill them.\nHexing a player works the same as spelling as a Witch.", "WraithInfoLong": "(Neutros):\nEl Espectro puede usar un conducto para Esfumarte temporalmente (Te volverás invisible para todo el mundo menos para tí). Vuelve a usar un conducto para Reaparecer. Ganarás si eres el último en vida.", "JinxInfoLong": "(Neutros):\nEl Gafado matará a quien intente atacarte.\nEsto tiene usos limitados.\n\nMata a todos para matar.", "PotionMasterInfoLong": "(Neutros):\nEl Maestro de las Pociones tiene tres pociones, asignadas a tres acciones distintas.\n\nUn clic revela el rol de una persona.\nDos clics matarán al jugador.\nEl mapa permite sabotear.\nLa poción de revelar tiene un límite, y cuando te acabes esa poción, el botón de matar servirá como un botón de matar por defecto.", @@ -958,7 +945,7 @@ "ParanoiaInfoLong": "(Complementos): \nNo asignado a Neutrales ni a Compañeros Locos. Como Esquizofrénico, serás considerado como dos jugadores en el juego para determinar cuándo termina la partida debido a que los asesinos tienen la mayoría. Además, esto te otorga un voto extra, dependiendo de las opciones.", "MimicInfoLong": "(Complementos):\nSolo el Impostor puede convertirse en Mímico. Cuando el Mímico muere, los otros Impostores recibirán un mensaje una vez que se convoque una reunión, este mensaje incluirá información sobre los roles que fueron asesinados por el Mímico.", "GuesserInfoLong": "(Complementos):\nEste complemento te permite adivinar el rol de otros jugadores para matarlos.\nAdivinar incorrectamente hará que te suicides.\nPara adivinar, escriba el comando /bt [Id del jugador] [role]\nPuedes ver el Id de los jugadores detrás de sus nombres o usando /id.", - "NecroviewInfoLong": "(Complementos):\nEl Nigrovidente puede ver el equipo de los jugadores muertos. La información se mostrará en el nombre del jugador muerto durante las reuniones.\nEl nombre rojo indica a los impostores.\nEl nombre azul claro indica a la tripulación.\nEl nombre gris indica a los neutros.", + "NecroviewInfoLong": "(Add-ons):\nThe Necroview can see the teams of dead players. The following info will be displayed on the dead player's name while in a meeting:\n- The Red name indicates the Impostors.\n- The Cyan name indicates the Crewmates.\n- The Gray name indicates the Neutrals.", "ReachInfoLong": "(Complementos):\nEste complemento es exclusivo para los roles con un botón de matar. Tienes un alcance para matar más alto que el resto.", "BaitInfoLong": "(Complementos): \nCuando el Cebo es asesinado, el asesino que mató al Cebo será forzado a auto-informar el cadáver del Cebo. Sin embargo, esto no sucederá cuando el Cebo sea asesinado por un Carroñero o un Limpiador. El informe puede tener un ligero retraso según las configuraciones del anfitrión.\nNota: Si el asesino fue el Carroñero, el Limpiador, el Swooper, el Espectro o la Máquina de Matar, no pasará nada.", "TrapperInfoLong": "(Complementos):\nCuando el Pegajoso es asesinado, el asesino se queda pegado a tu cadáver por un cierto tiempo.", @@ -981,7 +968,7 @@ "RebirthInfoLong": "(Add-ons):\nAs the Rebirth, if you're the player about to be ejected, you will swap skins with a random crewmate who voted for you.\nNotice: The host vote never counts\nRebirth will be removed from you if you exhausted all your rebirths.", "LoyalInfoLong": "(Complementos): \nEl Leal no puedes ser reclutado por roles como el Chacal o el Líder de Secta. No se le puede asignar a los neutros.", "EvilSpiritInfoLong": "(Complementos): \nEl Espíritu Maligno tiene una tarea: Ayudar al Capturador de Espíritus a la victoria. Puedes usar tu botón de atormentar para petrificar a otros jugadores y reducir su visión. Alternativamente, puedes usar tu botón de atormentar para proteger temporalmente al Capturador de Espíritus con un escudo.", - "RecruitInfoLong": "(Betrayal Add-ons):\nAs a recruit, you are on the Jackal's team and help out the Jackal and their Sidekicks.\nYou cannot win with your original team.\nDepending on the settings, you may turn into Jackal if old Jackal was killed and no sidekicks is alive.", + "RecruitInfoLong": "(Complementos de Traición):\nComo Recluta, estás en el equipo del Chacal y ayudas al Chacal y a sus Secuaces.\n\nNo puedes ganar con tu equipo original.", "AdmiredInfoLong": "(Complementos de Traición):\nEl Admirado gana con la tripulación, no con tu equipo original.\n\nPuedes ver quién es el Admirador.", "GlowInfoLong": "(Add-ons):\nDuring lights out, you and players nearby you will receive a vision boost.", "RadarInfoLong": "(Add-ons):\nAs Radar, you have arrows pointing towards the closest person at all times.", @@ -1025,7 +1012,6 @@ "ProhibitedInfoLong": "(Add-ons):\nAs the Prohibited, you have specific vents that you can't use.\nHow many vents are disabled depends on the Host's settings.", "EavesdropperInfoLong": "(Add-ons):\nAs the Eavesdropper, you have a chance to read other role/addon information-based messages like Mortician or Sleuth.", "ApocalypseInfoLong": "(Apocalypse):\nApocalypse members are on a separate team that works together and wins together. If there are multiple Apocalypse roles in the game, they can see each other's roles.\nDepending on the Host's settings, Apocalypse roles can guess or be guessed.", - "RevenantInfoLong": "(Neutral):\nAs the Revenant, your goal is to be killed. If you are killed, you will take your killer's role and kill your killer instead. You cannot win before being killed.\nNote that Revenant only works when being directly killed.", "ShowTextOverlay": "Superposición de texto", "Overlay.GuesserMode": "Modo Adivino", "Overlay.NoGameEnd": "Partida Sin Fin", @@ -1039,8 +1025,6 @@ "AbilityUseLimit": "Límite de uso de abilidades inicial", "AbilityInUse": "Habilidad en uso", "AbilityExpired": "Ability expired, {0} uses remain", - "RevenantTargeted": "Your role has changed to {0}", - "RevenantCanCopyAddons": "Can Steal Addons", "ShowArrows": "Flechas indicando cadáveres", "ArrowDelayMin": "Retraso mínimo de aparición de flechas", "ArrowDelayMax": "Retraso máximo de aparición de flechas", @@ -1370,8 +1354,6 @@ "ShieldedCanUseKillButton": "Shielded player can use ability / kill button", "PlayerIsShieldedByGame": "Player is protected by the game!", "LegacyNemesis": "Versión de Town of Host 1.4.0", - "LegacyParasite": "Use Legacy Version", - "LegacyTraitor": "Use Legacy Version", "ArsonistKeepsGameGoing": "El Incendiario hace que la partida continue", "ArsonistCanIgniteAnytime": "Puede prender fuego en cualquier momento", "ArsonistMinPlayersToIgnite": "Mínimo de jugadores a empapar para prender fuego", @@ -1514,18 +1496,6 @@ "SheriffCanKillSeparately": "Opciones individuales", "In%team%": "(Equipo %team%)", "SheriffMisfireKillsTarget": "Un disparo erróneo mata a la víctima", - "BlackHolePlaceCooldown": "Black Hole Place Cooldown", - "BlackHoleDespawnMode": "Black Hole Despawn Mode", - "BlackHoleDespawnTime": "Time After Black Hole Despawns", - "Abyssbringer.Suffix": "<#00ffa5>Number of players consumed by {0} <#00ffa5>active black holes:\\n{1}", - "Abyssbringer.Suffix.BlackHole": "<#00ffa5>{0}: {1}", - "BlackHoleMovesTowardsNearestPlayer": "Black Hole Moves Towards Nearest Player", - "BlackHoleMoveSpeed": "Black Hole Moving Speed", - "BlackHoleRadius": "Black Hole Consuming Radius", - "AfterTime": "After Time", - "After1PlayerEaten": "After 1 Player Was Eaten", - "AfterMeeting": "After Meeting", - "None": "None", "SheriffShotLimit": "Número máximo de asesinatos", "SheriffCanKillAllAlive": "Puede asesinar cuando todo el mundo está vivo", "SheriffCanKillCharmed": "Puede matar a Hechizados", @@ -1542,15 +1512,12 @@ "RebirthUses": "Número de Renacimientos", "RebirthCountVotes": "Solo renacer jugadores que hayan votado por él", "RebirthFailed": "Desgraciadamente, no encontraste ningún alma con la que puedas intercambiarte", - "FireworkerCooldown": "Placement Cooldown", "ReverieIncreaseKillCooldown": "Aumentar el tiempo de espera para matar", "ReverieMaxKillCooldown": "Tiempo de espera para matar máximo", "ReverieMisfireSuicide": "Fallar disparo al llegar a tu tiempo de espera máximo para matar", "ReverieResetCooldownMeeting": "Reiniciar tiempo de espera para matar después de una reunión", "ConvertedReverieKillAll": "El Ensimismado puede matar como le dé la gana si es convertido", "VigilanteNotify": "Te convertiste en aquello que juraste destruir", - "DictatorChangeCommandToExpel": "Dictator use Command to expell instad of vote", - "DictatorExpelSelf": "WAIT WAIT WAIT WAT THE HELLLLLL Bro really just want to expel himself", "DoctorTaskCompletedBatteryCharge": "Duración de la batería", "SnitchEnableTargetArrow": "Ve flechas hacia el blanco", "SnitchCanGetArrowColor": "Ve flechas de colores con colores del equipo", @@ -1624,6 +1591,7 @@ "TimeThiefDecreaseMeetingTime": "Reducir el tiempo de la reunión por", "TimeThiefLowerLimitVotingTime": "Tiempo de reunión mínimo", "TimeThiefReturnStolenTimeUponDeath": "Devolver el tiempo robado después de morir", + "TimeThiefMaxTimeOnAdmired": "Maximum Meeting Time if Time Thief Is Admired", "EvilTrackerCanSeeKillFlash": "Puede ver un flash por muertes", "EvilTrackerCanSeeLastRoomInMeeting": "Puede ver la última sala visitada por su blanco", "EvilTrackerTargetMode": "Puede elejir su blanco", @@ -1631,7 +1599,6 @@ "EvilTrackerTargetMode.OnceInGame": "Una vez en toda la partida", "EvilTrackerTargetMode.EveryMeeting": "Cada reunión", "EvilTrackerTargetMode.Always": "En cualquier momento", - "ScavengerHasCustomDeathReason": "Enable Custom Death Reason", "EvilHackerCanSeeDeadMark": "Can See The Location of Dead-bodies", "EvilHackerCanSeeImpostorMark": "Can See The Location of Other Impostors", "EvilHackerCanSeeKillFlash": "Puede ver un flash por muertes", @@ -1864,21 +1831,13 @@ "Jackal_SidekickCountMode_Jackal": "Chacal", "Jackal_SidekickCountMode_Original": "Equipo de Origen", "Jackal_SidekickAssignMode": "Modo de asignación de los Secuaces", - "Jackal_SidekickAssignMode_SidekickAndRecruit": "Sidekick when failed Recruit", - "Jackal_SidekickAssignMode_Sidekick": "Only Sidekick", - "Jackal_SidekickAssignMode_Recruit": "Only Recruit", + "Jackal_SidekickAssignMode_SidekickAndRecruit": "Sidekick+Recruit", + "Jackal_SidekickAssignMode_Sidekick": "Sidekick Only", + "Jackal_SidekickAssignMode_Recruit": "Recruit Only", + "JackalWinWithSidekick": "El Chacal puede ganar con sus Secuaces", "Jackal_SidekickCanKillSidekick": "Sidekicks can kill other Sidekicks", "Jackal_SidekickCanKillJackal": "Sidekick can kill Jackal", - "Jackal_RecruitFailed": "You can not recruit this player!", "JackalCanKillSidekick": "El Chacal puede matar a sus Secuaces", - "Jackal_SidekickCanKillWhenJackalAlive": "Sidekick can kill while Jackal is Alive", - "Jackal_SidekickTurnIntoJackal": "Sidekick can turn into Jackal after its death", - "Jackal_RestoreLimitOnNewJackal": "Restore Recruit limit when Sidekick become new Jackal", - "Jackal_OnBecomeNewJackalMeeting": "The old Jackal {0} is dead.\nYou are selected as new Jackal\nWork together and win the game!", - "Jackal_OnNewJackalSelectedMeeting": "The old Jackal {0} is dead.\n{1} is selected as new Jackal!\nWork together and win the game!", - "Jackal_BecomeNewJackal": "Old Jackal Dead, You are now new Jackal!", - "Jackal_OnNewJackalSelected": "Old Jackal Dead, Please help new Jackal {0} for now!", - "Jackal_BossIsDead": "Opps, the Jackal boss is dead!", "CoronerArrowsPointingToDeadBody": "Arrows pointing to dead bodies", "CoronerLeaveDeadBodyUnreportable": "Bodies the Coroner uses can't be reported", "CoronerInformKillerBeingTracked": "Inform the Killer that he gets tracked", @@ -1916,9 +1875,6 @@ "VipTag": "VIP★", "ApplyVipList": "Usar la lista de VIPs", "AllowSayCommand": "Permitir el uso de /s", - "AllowStartCommand": "Allow moderators to use /start command", - "StartCommandMinCountdown": "Minimum countdown for /start command", - "StartCommandMaxCountdown": "Maximum countdown for /start command", "KickCommandDisabled": "El comando de expulsión está desactivado", "KickCommandNoAccess": "No tienes acceso al comando para expulsar", "KickCommandInvalidID": "Invalid player ID specified.\nPlease use '/kick [playerID] [reason]' to kick a player.\nExample :- /kick 5 not following rules", @@ -1951,11 +1907,6 @@ "WarnCommandNoAccess": "No tienes permiso al comando warn", "WarnCommandInvalidID": "ID de jugador especificado no válido.\nPor favor, use /warn [IDjugador] [razón] para advertir a un jugador.\nPor ejemplo, /warn 5 hablar durante la cinemática de exilio", "WarnCommandWarnHost": "No puedes poner advertencias al anfitrión", - "StartCommandNoAccess": "You do not have access to the start command.", - "StartCommandDisabled": "The start command is currently disabled.", - "StartCommandCountdown": "ERROR\n\nThe game is already starting!", - "StartCommandStarted": "The game has been started by {0}!", - "StartCommandInvalidCountdown": "ERROR\n\nThe countdown must be between {0} and {1}!", "WarnCommandWarnMod": "No puedes poner advertencias a otros moderadores", "WarnCommandWarned": "ha sido advertido. No habrá más avisos y acciones apropiadas serán tomadas \n", "WarnExample": "Usa /warn [id] [razón] en el futuro. \nPor ejemplo, /warn 5 hablar durante la cinemática de exilio", @@ -1983,7 +1934,6 @@ "DeathReason.Quantization": "Cuantificado", "DeathReason.Overtired": "Agotado", "DeathReason.Ashamed": "Avergonzado", - "DeathReason.Consumed": "Consumed", "DeathReason.PissedOff": "Destrozado", "DeathReason.Dismembered": "Descuartizado", "DeathReason.LossOfHead": "Estrangulado", @@ -2007,8 +1957,6 @@ "DeathReason.Starved": "Starved", "DeathReason.Equilibrium": "Equilibrium", "DeathReason.Sacrificed": "Sacrificed", - "DeathReason.Electrocuted": "Electrocuted", - "DeathReason.Scavenged": "Scavenged", "OnlyEnabledDeathReasons": "Solo usar Causas de Muerte activadas", "Alive": "Vivo", "Disconnected": "Desconectado", @@ -2024,10 +1972,11 @@ "DeputyHandcuffCooldown": "Tiempo de espera para Esposar", "DeputyHandcuffMax": "Número de Esposas", "DeputyHandcuffedPlayer": "Objetivo Esposado", - "HandcuffedByDeputy": "Has sido esposado", - "DeputyInvalidTarget": "El objetivo no puede ser esposado", + "HandcuffedByDeputy": "You were handcuffed!\nNow you have broken your handcuff and can kill again.", + "DeputyInvalidTarget": "Target is already handcuffed", + "HandcuffBrokenAfterMeeting": "Remove all handcuffs after meeting", "DeputyHandcuffText": "Esposas", - "DeputyHandcuffCDForTarget": "Tiempo de espera para el jugador esposado", + "DeputyHandcuffCDForTarget": "Next Kill Cooldown for handcuffed player", "RejectShapeshift.AbilityWasUsed": "La habilidad fue utilizada", "EscapisMtarkedPosition": "You marked self-position", "InvestigateCooldown": "Tiempo de espera para lanzar Investigación", @@ -2087,7 +2036,6 @@ "ShowMadmatesInLeftCommand": "Mostrar a los Locos (Incluyendo complementos)", "ShowApocalypseInLeftCommand": "Show Neutral Apocalypse", "SeeEjectedRolesInMeeting": "Ver los roles de los exiliados en las reuniones", - "ThankYouForUsingTOHE": "Thank you for using TOHE!", "SkillUsedLeft": "Has activado tu habilidad para llamar una reunión. \nUsos restantes:", "NemesisDeadMsg": "La muerte del Némesis anuncia el comienzo del reino de la venganza. \nUse /rv + [ID del jugador] para matar al jugador especificado \nPuedes ver el ID de los jugadores al lado de sus nombres. \nO escribe /rv para tener la lista de los IDs de los jugadores.", "NemesisAliveKill": "La venganza del Némesis solo podrá comenzar después de su muerte.", @@ -2107,7 +2055,6 @@ "GuessNotifiedBait": "Bait can't be guessed because it was announced. You thought it would be that easy, right?", "GuessGM": "Hay que ser desagradecido para adivinar al pobre Anfitrión. Y encima de eso, está muerto. ¿Acaso no te has dado cuenta?", "GuessGuardianTask": "No puedes adivinar a un Guardian que haya acabado sus tareas.", - "GuardianCantKilled": "You can't kill a Guardian who has finished their tasks.", "GuessMarshallTask": "No puedes adivinar a un Mariscal que haya terminado sus tareas.", "GuessObviousAddon": "Lo sentimos, pero no se puede adivinar ningún complemento obvio.", "GuessAdtRole": "Desgraciadamente, el Anfitrión no te deja adivinar complementos", @@ -2163,7 +2110,6 @@ "BecomeMadmateCuzMadmateMode": "Te volviste loco porque has muerto", "CleanerCleanBody": "El cadáver ha sido limpiado", "QuickShooterStoraging": "Balas guardadas exitosamente", - "QuickShooterFailed": "You are still in cooldown.", "PoisonerTargetDead": "Tu objetivo ha muerto", "HexesLookLikeSpells": "Los males de ojo aparecen como hechizos", "HexButtonText": "Mal de ojo", @@ -2322,7 +2268,6 @@ "Message.YTPlanNotice": "Nota: El Plan Youtube está activado en esta sala. El Anfitrión podrá especificar el rol que quiera para la próxima partida para simplificarle la vida en el momento de crear contenido. Si abusa de esta función, sal de la sala o denúncialo.\nCredenciales del Creador:", "Message.OnlyCanBeUsedByHost": "ERROR\n\nEste comando es exclusivo al Anfitrión.", "Message.MaxPlayers": "Máximo de jugadores configurado a ", - "Message.MaxPlayersFailByRegion": "Could not set max players: Vanilla regions support a maximum of 15 players.", "Message.GhostRoleInfo": "Información sobre Roles de Fantasma\n¡Hola! Un poco sobre los roles de fantasma...\n\nLos roles de fantasma impactan drásticamente en el juego, por lo que no se recomiendan para lobbies pequeños, si no estás familiarizado.\n\nAparición:\nLos roles de fantasma solo aparecen después de la muerte, las primeras x personas de (equipo) en morir los obtienen.\n\nPD: Si tu rol anterior no tenía tareas (por ejemplo, sheriff), tus tareas como rol de fantasma no son necesarias para ganar por tareas", "ApocalypseInfoTitle": "Neutral Apocalypse Info:", "Message.ApocalypseInfo": "Every role of the <#ff174f>Apocalypse Team has their own objective to carry out in order to transform.\n<#2B0804>Transformed <#ff174f>Apocalypse members have a drastic change on the game and are immortal (except for being voted), but everyone will be notified that they have transformed.\n\nRoles: <#e5f6b4>Plaguebearer, <#A675A1>Soul Collector, <#bf9f7a>Baker, <#cc0044>Berserker\nTransformed: <#343136>Pestilence, <#644661>Death, <#83461c>Famine, <#2B0804>War\n\nApocalypse members can see eachother's roles and ability icons.\nLike Neutral Killers, Apocalypse members keep the game going as well, have fun!", @@ -2454,6 +2399,7 @@ "LastResult": "★ Resultados de la Partida", "LastEndReason": "★ Razón del Desenlace", "KillLog": "Recapitulación de Asesinatos", + "MainRoleLog": "Role Convert Log", "Maximum": "Máximo", "RoleRate": "Activado", "RoleOn": "Siempre", @@ -2640,7 +2586,7 @@ "NeutralRemain": "\n{0} Asesinos Neutros restantes", "OneNeutralRemain": "\n{0} Asesino Neutro restante", "ApocRemain": "\n{0} Neutral Apocalypse remains", - "GameOverReason.HumansByVote": "Todos los Impostores y Asesinos Neutros fueron asesinados o exiliados", + "GameOverReason.HumansByVote": "All Impostors and Neutral Killers were ejected or killed", "GameOverReason.HumansByTask": "La Tripulación terminó sus tareas", "GameOverReason.HumansDisconnect": "La Tripulación se ha desconectado", "GameOverReason.ImpostorByVote": "Los Tripulantes fueron exiliados", @@ -2730,9 +2676,8 @@ "DeathMeetingTimeIncrease": "Increased Meeting time when Death exists", "SoulCollectorMeetingDeath": "Your target has died during the meeting. You have gained a soul.", "SoulCollectorKillButtonText": "Predict", - "SoulCollectorHasImpostorVision": "Soul Collector has Impostor vision", "ApocalypseIsNigh": "[ The Apocalypse Is Nigh! ]", - "ApocalypseImmune": "This role is immune!", + "ApocalypseImmune": "This player is immune because they are invincible!", "BakerToFamine": "You have become Famine!!!", "BakerTransform": "The Baker has transformed into Famine, Horseman of the Apocalypse! A famine has begun!", "BakerAlreadyBreaded": "That player already has bread!", @@ -2741,15 +2686,13 @@ "BakerBreadNeededToTransform": "Required number of bread to become Famine", "BakerCantBreadApoc": "You cannot give other Apocalypse members bread!", "BakerKillButtonText": "Bread", - "BakerUnshiftButtonText": "Switch Bread", "BakerRevealBread": "Reveal", "BakerRoleblockBread": "Roleblock", "BakerBarrierBread": "Barrier", "BakerCurrentBread": "Current Bread: ", "BakerSwitchBread": "Bread Switched to: ", - "BakerCanVent": "Baker can Vent", + "BakerCanVent": "Baker can Vent", "BakerBreadGivesEffects": "Bread gives additional effects", - "BakerTransformNoMoreBread": "Baker transforms if they do not have enough bread", "FamineKillButtonText": "Starve", "FamineStarveCooldown": "Famine starve cooldown", "FamineCantStarveApoc": "You cannot starve other Apocalypse members!", @@ -2796,7 +2739,6 @@ "GodfatherTargetCountMode": "El Asesino se convierte en", "GodfatherCount_Refugee": "Refugee", "GodfatherCount_Madmate": "Loco", - "GodfatherRefugeeMsg": "You have been recruited by GodFather!", "MissChance": "Chance To Miss", "IncreaseByOneIfConvert": "Increase The KillCount +1 If a Crew Is Converted", "HawkMissed": "Missed!", @@ -2829,7 +2771,6 @@ "BerserkerToWar": "You have become War!!!", "BerserkerTransform": "The Berserker has transformed into War, Horseman of the Apocalypse! Cry 'Havoc!', and let slip the dogs of war.", "WarKillCooldown": "War kill cooldown", - "BerserkerCanKillTeamate": "Can kill other Neutral Apocalypse", "BlackmailerSkillCooldown": "Tiempo de Espera para Chantajear", "BlackmailerMax": "Máximo de veces que los jugadores chantajeados pueden hablar", "BlackmailerDead": "Peligro! El Chantajista hizo chantaje a {0}!", @@ -2919,8 +2860,6 @@ "RememberedPursuer": "Recordaste que te gusta perseguir metas", "RememberedFollower": "Recordaste que te gustaba hacerle la pelota a la gente", "RememberedAmnesiac": "Aun así, no te acuerdas de quien eres", - "AmnesiacRemembered": "You remembered you were {0}!", - "ReportWhenFailedRemember": "Report Dead Body when failed to remember", "RememberedImitator": "Recordaste que te gusta imitar a otras personas.", "RememberedImpostor": "Recordaste que levantabas sospechas. Es verdad, eras un Impostor!", "RememberedCrewmate": "Recordaste el momento en el que la nave despegó. Eres un tripulante!", @@ -2941,7 +2880,7 @@ "BanditStealCooldown": "Enfriamiento de robo", "DoppelMaxSteals": "Máximo de Suplantaciones", "DoppelCurrentVictimCanSeeRolesAsDead": "Last victim can see role and add-on info of alive players as a ghost", - "NecromancerRevengeTime": "Límite de tiempo para venganzas", + "NecromancerRevengeTime": "Necromancy time", "NecromancerRevenge": "Tienes {0}s para matar a {1}", "NecromancerSuccess": "Nigromancia completa! Has sobrevivido un día más.", "NecromancerHide": "El Nigromante está buscándote. Puedes huir pero no esconderte!", @@ -3146,7 +3085,7 @@ "DollMaster_PossessedTarget": "Possessed target", "DollMaster_CannotPossessImpTeammate": "Unable to possess teammate", "DollMaster_CouldNotSwapWithTarget": "Unable to possess player", - "DollMaster_CanNotSwapWithDeadTarget": "Possesing a dead player isn't possible", + "DollMaster_CanNotSwapWithDeadTarget": "Possessing a dead player isn't possible", "DollMaster_MainBody": "Main Body", "DollMaster_Doll": "Doll", "DollMaster_UnableToUseAbility": "Unable to use your ability on player", @@ -3164,7 +3103,7 @@ "PitfallTrapCauseVisionTime": "Tiempo de visión reducida por una trampa", "PitfallTrap": "Has caído en una trampa", "ConsigliereDivinationMaxCount": "Máximo de Revelaciones", - "RitualMaxCount": "Máximo de Revelaciones", + "RitualMaxCount": "Maximum Reveals", "CleanserHideVote": "Esconder votos del Purificador", "OracleSkillLimit": "Usos Máximos", "OracleHideVote": "Esconder votos del Oráculo", @@ -3334,12 +3273,9 @@ "PixieTargetAlreadySelected": "Ya has elegido a esta persona. Aunque la odies, solo la puedes seleccionar una vez", "PixieButtonText": "Marcar", "PlagueBearerCooldown": "Tiempo de Espera para pasar la Plaga", - "PlagueBearerCanVent": "Can vent", - "PlagueBearerHasImpostorVision": "Has Impostor vision", "PestilenceCooldown": "Tiempo de Espera para Matar (Pestilencia)", "PestilenceCanVent": "Puede usar conductos (Pestilencia)", "PestilenceHasImpostorVision": "Tiene visión de Impostor (Pestilencia)", - "PestilenceKillGuessers": "Kill players who guess Pestilence", "PlagueBearerAlreadyPlagued": "El jugador ya tiene la plaga", "PlagueBearerToPestilence": "Has evolucionado en Pestilencia!", "GuessPestilence": "Has intentado adivinar a la Pestilencia.\n\nDesgraciadamente, nadie adivina a la Pestilencia. La Pestilencia te adivina a tí.", @@ -3383,7 +3319,6 @@ "EveryoneCanKnowMini": "Todos pueden ver al Niño", "CanBeEvil": "El Niño puede ser Malvado", "EvilMiniSpawnChances": "Probabilidad de que el Niño sea Malvado", - "EvilMiniCanBeGuessed": "Evil Mini can be guessed before 18", "GuessMini": "No está bien intentar adivinar a un Niño indefenso. ¿Qué clase de monstruo eres?", "GrowUpDuration": "Tiempo necesario para volverse mayor (s)", "MajorCooldown": "Tiempo de Espera para matar (Adulto)", @@ -3525,7 +3460,6 @@ "WinnerRoleText.Doppelganger": "¡El Doble ha ganado!", "WinnerRoleText.Quizmaster": "Quizmaster Wins!", "WinnerRoleText.Agitater": "Agitator Wins!", - "WinnerRoleText.Shocker": "Shocker Wins!", "AdditionalWinnerRoleText.Sidekick": "Secuaz", "AdditionalWinnerRoleText.Taskinator": "Tarearista", "AdditionalWinnerRoleText.Opportunist": "Oportunista", @@ -3611,7 +3545,7 @@ "SolsticerOnMeeting": "¡Fuiste testigo de demasiadas muertes! ¡Tendrás {0} tareas cortas más durante la siguiente ronda!", "SolsticerTitle": "Empleado del Mes", "GuessSolsticer": "El Empleado del Mes está demasiado implicado en su trabajo para ser adivinado.", - "ExpelSolsticer": "Sorry, but you can not expel Solsticer!", + "VoteSolsticer": "Votar al Empleado del Mes causaría la bancarrota de la empresa. Vota a otra persona.", "SolsticerTasksReset": "Tus tareas fueron reiniciadas!", "SolsticerMisGuessed": "Tu intento de adivinar fue erróneo. Ya no podrás adivinar.", "SolsticerGuessMax": "Debido a que ya te has equivocado al adivinar, no puedes hacerlo de nuevo.", @@ -3712,19 +3646,6 @@ "MinionAbilityTime": "Duración de la Habilidad", "Minion_Blind": "blinded", "Evader_ChanceNotExiled": "Chance not be exiled", - "ShockerAbilityCooldown": "Ability Cooldown", - "ShockerAbilityDuration": "Ability Duration", - "ShockerAbilityPerRound": "Abilities Per Round", - "ShockerShockInVents": "Shock people in vents", - "ShockerAbilityResetAfterMeeting": "Reset marked rooms after meeting", - "ShockerOutsideRadius": "Radius Of Outside Tasks (not in a room)", - "ShockerCanShockHimself": "Can Shock Himself", - "ShockerImpostorVision": "Shocker has Impostor vision", - "ShockerIsShocking": "You're already shocking!", - "ShockerAbilityActivate": "Begin Shocking!", - "ShockerAbilityDeactivate": "Ability Deactivated", - "ShockerVentButtonText": "Shock", - "ShockerRoomMarked": "Marked Room", "EavesdropperMsgTitle": "You found a secret", "EavesdropPercentChance": "Chance to eavesdrop", "ChiefOfPoliceSkillCooldown": "Cooldown for recruiting sheriffs", @@ -3736,4 +3657,4 @@ "PolicPreventRecruitNonKiller": "Prevent recruit players without kill button", "PolicSuidiceWhenTargetNotKiller": "Suidices when recruit a non killer or non crewmate", "PolicPassConverted": "Can pass Converted Addon to Sheriff" -} +} \ No newline at end of file diff --git a/Resources/Lang/fil_PH.json b/Resources/Lang/fil_PH.json index 99986550e..6c3dbf646 100644 --- a/Resources/Lang/fil_PH.json +++ b/Resources/Lang/fil_PH.json @@ -20,8 +20,6 @@ "SubText.Neutral": "Magtrabaho ng mag-isa upang makamit ang iyong tagumpay", "SubText.Apocalypse": "Become unstoppable with your team", "SubText.Madmate": "Tulungan ang mga Impostors", - "SubText.Lovers": "Stay alive and win together", - "SubText.Egoist": "Win on your own", "TypeImpostor": "Impostors", "TypeCrewmate": "Crewmates", "TypeNeutral": "Neutrals", @@ -31,9 +29,6 @@ "TeamNeutral": "Niyutral", "TeamCrewmate": "Crewmate", "TeamMadmate": "Madmate", - "TeamLovers": "Lovers", - "TeamEgoist": "Egoist", - "TeamApocalypse": "Apocalypse", "YouAreCrewmate": "Ikaw ay isang Crewmate", "YouAreImpostor": "Ikaw ay isang Impostor", "YouAreNeutral": "Ikaw ay isang Niyutral", @@ -225,7 +220,6 @@ "TaskManager": "Task Manager", "Witness": "Witness", "Swapper": "Swapper", - "ChiefOfPolice": "Chief of Police", "NiceMini": "Nice Mini", "Mini": "Mini", "Spy": "Espiya", @@ -254,7 +248,6 @@ "Stalker": "Stalker", "Workaholic": "Workaholic", "Solsticer": "Solsticer", - "Abyssbringer": "Abyssbringer", "Collector": "Collector", "Provocateur": "Provocateur", "BloodKnight": "Blood Knight", @@ -393,8 +386,6 @@ "Sloth": "Sloth", "Prohibited": "Prohibited", "Eavesdropper": "Eavesdropper", - "Shocker": "Shocker", - "Revenant": "Revenant", "BracketAddons": "Add Brackets To Add-ons", "EngineerTOHEInfo": "Use the vents to catch the Impostors", "ScientistTOHEInfo": "Access portable vitals from anywhere", @@ -513,7 +504,7 @@ "PacifistInfo": "Vent to reset kill cooldowns", "RebirthInfo": "Arise Again", "MonarchInfo": "Give your crew extra voting power!", - "AbyssbringerInfo": "Place Black Holes", + "AbyssbringerInfo": "Create Black Holes", "SpurtInfo": "Spring Like A rabbit!", "StealthInfo": "Killing Blinds Everyone in the Room", "PenguinInfo": "Drag your victims", @@ -538,7 +529,7 @@ "AdmirerInfo": "Choose a player to side with you", "TimeMasterInfo": "Rewind time!", "CrusaderInfo": "Kill a player's attacker", - "AltruistInfo": "Revive a player", + "AltruistInfo": "Revive a player\nVent to change between Revive and Report", "ReverieInfo": "With each kill, your cooldown decreases", "LookoutInfo": "See through disguises", "TelecommunicationInfo": "Track device usage", @@ -547,7 +538,6 @@ "WitnessInfo": "Find out if someone killed recently", "GhastlyInfo": "Control somebody!", "SwapperInfo": "Swap the votes of two players", - "ChiefOfPoliceInfo": "Hire Sheriff to Serve the Crews!", "NiceMiniInfo": "No one can hurt you until you grow up.", "ArsonistInfo": "Douse everyone and ignite", "PyromaniacInfo": "Douse and kill everyone", @@ -615,7 +605,7 @@ "ShroudInfo": "Shroud players to make them kill", "WerewolfInfo": "Kill crewmates in groups", "ShamanInfo": "Deflect all the attacks on Voodoo doll", - "SeekerInfo": "Play Hide and Seek with your target", + "SeekerInfo": "Play Hide and Seek with your target\nYour target has a ★ mark.", "PixieInfo": "Tag 'em, Bag 'em, and Eject 'em!", "OccultistInfo": "Kill and curse your enemies", "SchrodingersCatInfo": "The cat is both alive and dead until observed.", @@ -708,8 +698,6 @@ "SlothInfo": "You're slower", "ProhibitedInfo": "Certain vents are blocked", "EavesdropperInfo": "Listen in on other roles", - "ShockerInfo": "Shock unsuspecting players", - "RevenantInfo": "Take your killer's role", "EngineerTOHEInfoLong": "(Crewmates):\nAs the Engineer, you may access the vents while Comms Sabotaged is inactive.", "ScientistTOHEInfoLong": "(Crewmates):\nAs the Scientist, you can see vitals at any time, showing you who is alive and dead.", "NoisemakerTOHEInfoLong": "(Crewmates):\nAs the Noisemaker, whenever you die, you will make a noise, and a visual indicator of your death appears on the screen so the Crewmates can run to catch the person who killed you red-handed (even if it’s not Red).", @@ -781,11 +769,11 @@ "LurkerInfoLong": "(Impostors):\nAs the Lurker, you can jump into a vent to reduce your cooldown by a certain number of seconds. After you kill, your cooldown resets to its original value.", "VisionaryInfoLong": "(Impostors):\nAs the Visionary, you see the alignments of living players during a meeting.\nThe following information will be displayed on the players:\n- The Red name indicates the Impostors.\n- The Cyan name indicates the Crewmates.\n- The Gray name indicates the Neutrals.", "PlagueDoctorInfoLong": "(Neutrals):\n(Plague Doctor from TOH)\nThe Plague Scientist's goal is to infect every living player.\nThey start by choosing one player to infect, after which anyone who spends a set amount of time in the range of the infected player becomes infected themselves.\nInfection progress is cumulative and does not reset with distance or after meetings.", - "RefugeeInfoLong": "(Madmates):\nAs the Refugee, you were either:\n -An Amnesiac who remembered an Impostor\n -A killer who killed the Godfather's target.\n -A Romantic whose partner was an Impostor\n -Or an Imitator that imitated an Impostor.\n\nNow your job is to help the Impostors kill the crewmates.", + "RefugeeInfoLong": "(Madmates):\nAs the Refugee, you were either an Amnesiac who remembered an Impostor or a killer who killed the Godfather's target.\n\nNow your job is to help the Impostors kill the crewmates.", "UnderdogInfoLong": "(Impostors):\nAs the Underdog, you cannot kill until there's a certain amount of players alive.", "ConsigliereInfoLong": "(Impostors):\nAs the Consigliere, you can reveal the roles of other players using your kill button.\n\nSingle click: Reveal role\nDouble click: Kill\n\nIf you run out of reveal uses, your kill button functions normally.", "LudopathInfoLong": "(Impostors):\nAs the Ludopath, your kill cooldown is randomized.\n\nMinimum it can be is 1 second, while the maximum is your default kill cooldown.", - "GodfatherInfoLong": "(Impostors):\nAs the Godfather, you vote someone to make them your target.\nIn the next round, if someone kills the target, the killer will turn into a Refugee or Madmate.", + "GodfatherInfoLong": "(Impostors):\nAs the Godfather, you vote someone to make them your target.\nIn the next round, if someone kills the target, the killer will turn into a Refugee.", "ChronomancerInfoLong": "(Impostors):\nAs the Chronomancer, you have a charge bar which indicates when the slaughter is ready. When it is at 100% the next time you kill someone, you go into slaughter mode, meaning you can kill indefinitely until your bar runs out of charge. Otherwise, you have a normal KCD.", "PitfallInfoLong": "(Impostors):\nAs the Pitfall, you use your shapeshift to mark the area around the shapeshift as a trap. Players who enter this area will be immobilized quickly, and their vision will be affected.", "EvilMiniInfoLong": "(Impostors):\nAs the Evil Mini, you are unkillable until you grow up and have a very long initial kill cooldown, which gets drastically shortened as you grow up.", @@ -821,7 +809,7 @@ "GrenadierInfoLong": "(Crewmates):\nAs the Grenadier, you can vent to Flashbang players nearby, causing them to lose vision if they are an Impostor or, depending on settings, a Neutral.", "MedicInfoLong": "(Crewmates):\nThe Medic can place a shield on the target by pressing the Kill button. The Medic can only give one shield for the whole game. Depending on the settings, the target's shield can or cannot deactivate when the Medic dies. The Medic can also see if someone is trying to break the target's shield.\nDepending on the Host's settings, the Medic or the target can see if the player has a shield (shown as a green circle 「●」 next to the name).", "FortuneTellerInfoLong": "(Crewmates):\nAs the Fortune Teller, vote for a player in a meeting to get a clue to their role.\nThe clue will relate to their actual role.\n\nWhen the Fortune Teller's tasks are complete, they will obtain the exact role rather than a clue!\n\nNote: If the setting to give random active players as a hint is on, you cannot check the same player multiple times.", - "JudgeInfoLong": "(Crewmates):\nThe Judge can judge a certain player during the meeting. If the target is evil, the target will be killed (whether it is evil or not is set by the Host). If it is wrong, the Judge commits suicide.\nCommand for judgment: /tl [player id]\nYou can see the player's id before the player's name, or use the /id command to view the id of all players.\nJudges can judge all players when they become Madmate.", + "JudgeInfoLong": "(Crewmates):\nThe Judge can judge a certain player during the meeting. If the target is evil, the target will be killed (whether it is evil or not is set by the Host). If it is wrong, the Judge commits suicide.\nCommand for judgment: /tl [player id]\nYou can see the player's id before the player's name, or use the /id command to view the id of all players.\nJudges can judge all players when they become Madmate.\nIn meeting the ability count shows how many trails you have in this meeting. Out of meeting the ability counts shows how many trails you have for the whole game.", "MorticianInfoLong": "(Crewmates):\nThe Mortician can see arrows pointing to all dead bodies, and if the Mortician reports a body, they will know the last player the victim had contact with. Note: Mortician won't be Oblivious or Seer.", "MediumInfoLong": "(Crewmates):\nThe Medium can establish contact with a dead player after someone reports a dead body. The player who reports doesn't have to be the Medium. The dead player can answer once with a YES or a NO to the Medium's question, which only the Medium will see (the dead player can use /ms yes or /ms no). Note: Medium won't be Oblivious.", "ObserverInfoLong": "(Crewmates):\nAs the Observer, you can see all shield animations caused by other players after the first meeting. The shied animations typically indicate a role ability, so look out for this.", @@ -833,7 +821,7 @@ "MerchantInfoLong": "(Crewmates):\nAs a merchant, you sell a random add-on to a random player for each task you complete. Each add-on sold earns you money. If you have a certain amount of money, you can prevent the next killing attempt against you by bribing the murderer. The bribed player won't be able to kill you, but you don't know who it is. The money used is lost and not available for additional bribes.", "RetributionistInfoLong": "(Crewmates):\nAs the Retributionist, you can kill a limited amount of players after your death.\n\nUse /ret [playerID] to kill.", "HawkInfoLong": "(Crewmates [Ghost]):\nAs the Hawk, you can kill a limited amount of players decided by the host, though there's a chance you miss, slicing someone multiple times increases the chances.", - "DeputyInfoLong": "(Crewmates):\nAs the Deputy, use your kill button on a player to reset their kill cooldown.\n\nIf the target does not have a kill button, then the handcuff was a waste.", + "DeputyInfoLong": "(Crewmates):\nAs the Deputy, use your kill button to handcuff a player.\nThe player who is handcuffed will have their next kill attempt treated as a handcuff break, and the kill cooldown will be reset.\n\nIf the target does not have a kill button, then the handcuff was a waste.", "InvestigatorInfoLong": "(Crewmates):\nAs an Investigator, you can use your kill button to investigate someone. When you investigate someone, their name will appear in red if they possess a kill button (impostor/SS basis) or light blue if they lack a kill button (crewmate/engineer/scientist basis). However, please note that the color of the names will return to normal when someone calls a meeting.", "GuardianInfoLong": "(Crewmates):\nAs the Guardian, you become immortal upon task completion. Guessers can't even guess you in meetings.", "AddictInfoLong": "(Crewmates):\nAs the Addict, you have a suicide timer. When it expires, you kill yourself.\nThe timer is indicated by the vent cooldown. When the vent cooldown is 0 seconds, you still have a short time to vent.\nIf you don't make it, you die; if you make it, the suicide timer is reset.\nAlso after you vent, no one can interact with you for a defined period.\nAfter; the period is over, and you are immobilized for another defined period, and cannot report any bodies.", @@ -849,7 +837,7 @@ "AdmirerInfoLong": "(Crewmates):\nAs the Admirer, admire a player to make them Crewmate aligned.\nThey'll win with crewmates and not their original team.\n\nYou can only do this once per player.", "TimeMasterInfoLong": "(Crewmates):\nAs the Time Master, use the vents to mark everyone's position.\nWhen using the ability again, every alive player will rewind to the marked positions.\n\nDuring the ability duration, the Time Master gains a time shield, which protects them from death.", "CrusaderInfoLong": "(Crewmates):\nAs the Crusader, use your kill button to crusade a player.\nIf that player gets attacked, you'll kill the attacker.", - "AltruistInfoLong": "(Crewmates):\nAs the Altruist, you can sacrifice yourself to revive a dead body using the «Report» button.\nNote: If a dead player has left the game, you report that body normally.\nAlso revived player cannot report self dead body", + "AltruistInfoLong": "(Crewmates):\nAs the Altruist, you can sacrifice yourself to revive a dead body using the «Report» button.\nNote: If a dead player has left the game, you report that body normally.\nAlso revived player cannot report self dead body\nUse vent button to change between Report & Revive.", "ReverieInfoLong": "(Crewmates):\nAs the Reverie, you can kill, but your cooldown starts high.\n\nIt increases if you kill a crewmate and reduces otherwise.\nDepending on the Host's setting, you may misfire on reaching the max kill cooldown, and your target dies with you. \n\nYou win with other crewmates.", "LookoutInfoLong": "(Crewmates):\nAs the Lookout, you can see the IDs of every player at all times.\nThis allows you to see through shapeshifts and camouflages.", "TelecommunicationInfoLong": "(Crewmates):\nAs the Telecommunication, you are notified when anyone uses cameras, vitals, door logs, or admin.", @@ -872,7 +860,7 @@ "LawyerInfoLong": "(Neutrals):\nLawyer has a target to defend, which will be indicated by a diamond 「♦」 next to their name.\nIf your target wins, you win.\nIf they lose, you lose.", "OpportunistInfoLong": "(Neutrals):\nIf the Opportunist survives at the end of the game, the Opportunist will win with the winning player.", "VectorInfoLong": "(Neutrals):\nVector will win alone by venting a certain number of times.", - "JackalInfoLong": "(Neutrals):\nAs the Jackal, you win if you are the last player alive. Additionally, you may recruit using the kill button. If the target is not one you can recruit, you have run out of uses, or you don't have the option to recruit, then you will kill people normally (i.e., don't use kill buttons in front of others thinking it'll recruit). If the target has a kill button and the option to turn into a Sidekick is on, they will become a Sidekick. Otherwise, they will gain the Recruit add-on if the option to give the Recruit add-on is on.\nDepending on the settings, when Jackal was killed, a Sidekick will be randomly selected as the new Jackal.\nRecruit may be selected if no sidekick is alive.", + "JackalInfoLong": "(Neutrals):\nAs the Jackal, you win if you are the last player alive. Additionally, you may recruit using the kill button. If the target is not one you can recruit, you have run out of uses, or you don't have the option to recruit, then you will kill people normally (i.e., don't use kill buttons in front of others thinking it'll recruit). If the target has a kill button and the option to turn into a Sidekick is on, they will become a Sidekick. Otherwise, they will gain the Recruit add-on if the option to give the Recruit add-on is on.", "GodInfoLong": "(Neutrals):\nAs the God, you know everyone's role from the beginning. If you live until the end of the game, you steal the win, i.e., everyone else loses, and you win.", "InnocentInfoLong": "(Neutrals):\nThe Innocent can use the kill button to plant any player, and the planted target will immediately kill the Innocent. If the target gets voted out in the meeting, the Innocent wins. Note: Jester, Executioner, and Innocent can win together.", "PelicanInfoLong": "(Neutrals):\nAs the Pelican, you can use the kill button to swallow a player alive, teleporting them off-bounds but not killing them yet. Those swallowed will only die if you're still alive at the end of the round. If you die or leave during the round, all alive swallowed players will spawn into the map where you were.", @@ -884,14 +872,14 @@ "SolsticerInfoLong": "(Neutrals):\nAs the Solsticer, you won't die, and you win by finishing all your tasks in a single round. After every meeting finishes, your tasks reset, and you need to start all over again.\nVotes on the Solsticer will be directly canceled.\nKill attempts on the Solsticer will teleport it out of the map like Pelican until the meeting is finished.\nThe killer's kill cooldown will be reset to 10 seconds.\nSolsticer is counted as nothing in-game.", "CollectorInfoLong": "(Neutrals):\nAs the Collector, when you vote for a player, for each other player that voted for them, you gain a point. When you collect the required votes, the game ends, and you win alone, even if you voted a Jester or Executioner's target out.", "GlitchInfoLong": "(Neutrals):\nAs the Glitch, you can hack players (single click) or kill normally (double click).\nThose who have been hacked cannot kill, vent, or report for the hack duration.\nAdditionally, calling a sabotage other than doors will have no effect and will instead disguise you as a random player. You cannot disguise during or after sabotages.\nTo win, be the last player alive.", - "SidekickInfoLong": "(Neutrals):\nAs the Sidekick, your job is to help the Jackal kill everyone.\nYou and the Jackal win together.\nDepending on the settings, you may turn into Jackal if old Jackal was killed.\nYou may not be able to kill until old Jackal is dead.", + "SidekickInfoLong": "(Neutrals):\nAs the Sidekick, your job is to help the Jackal kill everyone.\n\nYou and the Jackal win together.", "ProvocateurInfoLong": "(Neutrals):\nAs the Provocateur, you can kill any target with the kill button. If the target loses at the end of the game, the Provocateur wins with the winning team.", "BloodKnightInfoLong": "(Neutrals):\nThe Blood Knight wins when they're the last killing role alive, and the amount of crewmates is lower or equal to the amount of Blood Knights. The Blood Knight gains a temporary shield after every kill, making them immortal for a few seconds.", "PlagueBearerInfoLong": "(Apocalypse):\nAs the Plaguebearer, plague everyone using your kill button to turn into Pestilence.\nOnce you turn into Pestilence, you will become immortal and gain the ability to kill, and you will kill anyone who tries to kill you.\n\nAlso, when infected players interact with uninfected players, they will also be infected.", "PestilenceInfoLong": "(Apocalypse):\nAs Pestilence, you're an unstoppable machine.\nAny attack towards you will be reflected towards them.\nIndirect kills don't even kill you.\n\nOnly way to kill Pestilence is by voting them out or the Pestilence misguessing.\nYour presence is announced to everyone at the meeting after you transform.", "SoulCollectorInfoLong": "(Apocalypse):\nAs Soul Collector, you can use your kill button on a player to predict their death. You will gain a soul if your target dies in the round you select them or the meeting after.\nYour target resets after each meeting or after they die, whichever comes first. \n\nOnce you collect the configurable amount of souls, you become Death. If the gain passive souls setting is enabled, you will gain a soul each meeting.", "DeathInfoLong": "(Apocalypse):\nOnce the Soul Collector has collected their needed souls, they become Death. Death kills everyone and wins if Death is not ejected by the end of the next meeting.\nA configurable amount of extra meeting time will be given on the meeting Death transforms to have more discussion to find Death.\n\nYou are invincible, and your presence is announced to everyone at the meeting after you transform.", - "BakerInfoLong": "(Apocalypse):\nAs the Baker, you can use your kill button on a player per round to give them bread. \nOnce a set amount of players are alive with bread, you become Famine.\n\nIf the Bread gives additional effects and the setting is on, then you can vent to change the bread that you give out. \nBread Effects:\nReveal: Reveals the target's role to the Baker (stays the whole game)\nRoleblock: Sets the target's kill cooldown to 999 (resets to normal after the meeting)\nBarrier: Gives the target a barrier that is only known to the Baker (barrier is removed after the meeting)", + "BakerInfoLong": "(Apocalypse):\nAs the Baker, you can use your kill button on a player per round to give them bread. \nOnce a set amount of players are alive with bread, you become Famine.\n\nIf the Bread gives additional effects and the setting is on, then you can vent to change the bread that you give out. \nBread Effects:\nReveal: Reveals the target's role to the Baker (stays the whole game)\nRoleblock: Resets the target's kill cooldown when they try to use their kill button\nBarrier: Gives the target a barrier that is only known to the Baker (barrier is removed after the meeting)", "FamineInfoLong": "(Apocalypse):\nOnce the Baker has a set amount of people with bread alive, they will become Famine. If the Famine does not get voted out after the meeting, then they will become Famine, and every player without bread will starve (excluding other Apocalypse members).\nAfter this starvation of everyone without bread, Famine can use their kill button to starve any remaining players, which will kill those players right before the next meeting.\n\nYou are invincible, and your presence is announced to everyone at the meeting after you transform.", "BerserkerInfoLong": "(Apocalypse):\nAs the Berserker, you level up with each kill.\nUpon reaching a certain level defined by the Host, you unlock a new power.\n\nScavenged kills make your kills disappear.\nBombed kills make your kills explode. Be careful when killing, as this can kill your other Apocalypse members if they are near. \nAfter a certain level, you become War.", "WarInfoLong": "(Apocalypse):\nAs War, you are invincible, have a lower kill cooldown, and can kill anyone with your previous powers.\nYour presence is announced to everyone at the meeting after you transform.", @@ -911,12 +899,11 @@ "TraitorInfoLong": "(Neutrals):\nAs the Traitor, you were an Impostor that betrayed the Impostors.\nYou know the Impostors, but they don't know you.\nThe twist? They can kill you, but you can't kill them.\n\nEliminate the Impostors by other means, then kill everyone else to win!", "TrollerInfoLong": "(Neutrals):\nAs a Troller, you can complete tasks so that random events can happen to players.\nFor example, changing the speed of all players, teleportation, influencing sabotage, etc.\nAlso you can win with the winning team.", "VultureInfoLong": "(Neutrals):\nAs the Vulture, report bodies to win!\n\nWhen you report a body, if your eat cooldown is up, you'll eat the body (makes it unreportable).\nIf your eat ability is still on cooldown, then you'll report the body normally.\n\nAdditionally, you'll report bodies normally if the maximum bodies eaten per round is reached.", - "AbyssbringerInfoLong": "(Impostors):\nAs the Abyssbringer, you can place black holes. Black holes will suck in players and kill them when colliding with them.", "TaskinatorInfoLong": "(Neutrals):\nAs the Taskinator, whenever you finish a task, the task will be bombed. When another player completes the bombed task, the bomb will detonate, and the player will die.\n\nYou win if you survive till the end and Crew doesn't win.\n\n Note: Taskinator bombs ignore all protection.", "BenefactorInfoLong": "(Crewmates):\nAs the Benefactor, whenever you finish a task, that task will be marked. When another player completes the marked task, they get a temporary shield.\n\n Note: Shield only protects from direct kill attacks.", "MedusaInfoLong": "(Neutrals):\nAs the Medusa, you can stone bodies much like cleaning a body.\nStoned bodies cannot be reported.\n\nKill everyone to win.", "SpiritcallerInfoLong": "(Neutrals):\nAs the Spiritcaller, your victims become Evil Spirits after they die. These spirits can help you win by freezing other players briefly or blocking their vision. Alternatively, the spirits can give you a shield that protects you briefly from an attempted kill.", - "AmnesiacInfoLong": "(Neutrals):\nAs the Amnesiac, use your report button to remember a target and get its role.\nTo balance the game, you will not be able to vent after remembering your role if you can't vent as Amnesiac.'", + "AmnesiacInfoLong": "(Neutrals):\nAs the Amnesiac, use your report button to remember a role.\n\nIf the target was an Impostor, you'll become a Refugee.\nIf the target was a crewmate, you'll become the target role if compatible (otherwise you become an Engineer).\nIf the target was a passive neutral or a neutral killer not specified, you'll become the role defined in the settings.\nIf the target was a neutral killer of a select few, you'll become the role they are.", "ImitatorInfoLong": "(Neutrals):\nAs the Imitator, use your kill button to imitate a player.\n\nYou'll either become a Sheriff, a Refugee, or some Neutral.", "BanditInfoLong": "(Neutrals):\nAs the Bandit, you can click your kill button one time to steal a player's addon and twice to kill. Depending on the settings, you may instantly steal the addon or after the meeting starts. After the maximum number of steals is reached, you will kill normally. Additionally, if there are no stealable addons on the target or the target is stubborn, you will kill the target.\n\nKill everyone to win.\n\nNote: Cleansed, Last Impostor, and Lovers cannot be stolen.\nNote: If Bandit can vent is on, Nimble will become unstealable.", "DoppelgangerInfoLong": "(Neutrals):\nAs the Doppelganger, use your kill button to steal a player's identity (their name and skin) and then kill your target.\n\nKill everyone to win.\n\nNote: You cannot steal the target's identity when Camouflage is active.", @@ -925,7 +912,7 @@ "ShroudInfoLong": "(Neutrals):\nAs the Shroud, you do not kill normally.\nInstead, use your kill button to shroud a player.\nShrouded players kill others.\nIf the shrouded player doesn't make a kill, they'll kill themselves after a meeting.\n\nShroud sees shrouded players with a 「◈」mark next to their name.\nShrouded players who did not make a kill will also have the 「◈」mark in meetings, where they'll die if the Shroud is alive by the end of the meeting.", "WerewolfInfoLong": "(Neutrals):\nAs the Werewolf, you can kill much like any killer.\nHowever, when you kill, any nearby players also die.\nAny player who dies to this will have their death reason as Mauled.\n\nTo balance this, you have a higher kill cooldown than anyone else.", "ShamanInfoLong": "(Neutrals):\nAs the Shaman, you can use your kill button to select a voodoo doll once per round. If the kill button is used on you, the effect will be deflected onto the voodoo doll.\nIf you survive until the end, you win with the winning team.\nNote: If the killer cannot kill the chosen target, murder is canceled, but if the killer rechecks the Shaman, the killer will kill the Shaman.", - "SeekerInfoLong": "(Neutrals):\nAs the seeker, use your kill button to tag the target. If the seeker tags the wrong player, a point is deducted, and if the seeker tags the correct player, a point will be added.\nAdditionally, the seeker will not be able to move for 5 seconds after every meeting and after getting a new target.\n\nThe seeker needs to collect a certain number of points set by the Host to win.", + "SeekerInfoLong": "(Neutrals):\nAs the seeker, use your kill button to tag the target. If the seeker tags the wrong player, a point is deducted, and if the seeker tags the correct player, a point will be added.\nAdditionally, the seeker will not be able to move for 5 seconds after every meeting and after getting a new target.\n\nThe seeker needs to collect a certain number of points set by the Host to win.\nSeeker will see a ★ mark on target's name.", "PixieInfoLong": "(Neutrals):\nAs the Pixie, Mark up to x amount of targets each round by using the kill button on them. You must have one of the marked targets ejected when the meeting starts. If unsuccessful, you will commit suicide, except if you didn't mark any targets or all the targets are dead. The selected targets reset to 0 after the meeting ends. If you succeed, you will gain a point. You see all your targets in colored names.\n\nYou win with the winning team when you have certain amounts of points set by the Host.", "SchrodingersCatInfoLong": "(Neutrals):\nAs Schrodingers Cat, if someone attempts to use the kill button on you, you will block the action and join their team. This blocking ability works only once. By default, you don't have a victory condition, meaning you win only after switching teams.\nIn Addition to this, you will be counted as nothing in the game.\n\nNote: If the killing machine attempts to use its kill button on you, the interaction is not blocked, and you will die.", "RomanticInfoLong": "(Neutrals):\nThe Romantic can pick their lover partner using their kill button (this can be done at any point of the game). Once they've picked their partner, they can use their kill button to give their partner a temporary shield that protects them from attacks. If their lover partner dies, the Romantic's role will change according to the following conditions:\n1. If their partner was an Impostor, the Romantic becomes the Refugee\n2. If their partner was a Neutral Killer, then they become Ruthless Romantic.\n3. If their partner was a Crewmate or a non-killing neutral, the Romantic becomes the Vengeful Romantic. \n\nThe Romantic wins with the winning team if their partner wins.\nNote: If your role changes, your win condition will be changed accordingly", @@ -937,7 +924,6 @@ "JinxInfoLong": "(Neutrals):\nAs the Jinx, whenever you get attacked, you jinx them, resulting in them dying to a jinx.\nThis has limited uses.\n\nKill off everyone to win.", "PotionMasterInfoLong": "(Neutrals):\nAs the Potion Master, you have three different potions assigned to three different actions.\n\nSingle click: Reveal role\nDouble click: Kill\nMap: Sabotage\n\nThe reveal potion has a limit.\nWhen you run out, the kill buttons default to killing.", "NecromancerInfoLong": "(Neutrals):\nAs the Necromancer, you win when you're the last one standing.\nAdditionally when someone tries to kill you, you will block the kill, and you will teleport to a random vent. You will have a limited time to kill your killer. If you succeed in doing so, you live. If the time runs out before you kill your killer, you die permanently. If you try to kill someone else other than your killer, you will die.", - "ShockerInfoLong": "(Neutrals):\nAs the Shocker, you can mark rooms by doing tasks in them, and then vent to Electrocute anyone in those rooms for a set period of time. When you finish all of your tasks, you get new ones. Note: Doing tasks during that period will mark them for the next ability use.", "LastImpostorInfoLong": "(Add-ons):\nThis special effect is given to the last surviving Impostor. It significantly reduces their kill cooldown.", "OverclockedInfoLong": "(Add-ons):\nAs the Overclocked, your kill cooldown is reduced by a percentage.\n\nThis feature is only assigned to roles with a kill button.", "LoversInfoLong": "(Add-ons):\nLovers are a combination of two players. The Lovers win when they are the last ones standing, and their victory is shared. When one of the Lovers wins, the other also wins together. Lovers can see the 「♥」 next to each other's name. If one of the Lovers dies, the other will die in love (may not die in love according to the Host's settings). When one of the Lovers is exiled in the meeting, the other will die and become a dead body that cannot be reported.", @@ -981,7 +967,7 @@ "RebirthInfoLong": "(Add-ons):\nAs the Rebirth, if you're the player about to be ejected, you will swap skins with a random crewmate who voted for you.\nNotice: The host vote never counts\nRebirth will be removed from you if you exhausted all your rebirths.", "LoyalInfoLong": "(Add-ons):\nAs the Loyal, you cannot be recruited by roles such as Jackal or Cultist.\n\nCannot be assigned to neutrals.", "EvilSpiritInfoLong": "(Add-ons):\nAs Evil Spirit, it's your job to help the Spiritcaller to victory. You can use your Haunt button to freeze players and reduce their vision. Alternatively, you can use your Haunt button to give the Spiritcaller a shield against a kill attempt temporarily.", - "RecruitInfoLong": "(Betrayal Add-ons):\nAs a recruit, you are on the Jackal's team and help out the Jackal and their Sidekicks.\nYou cannot win with your original team.\nDepending on the settings, you may turn into Jackal if old Jackal was killed and no sidekicks is alive.", + "RecruitInfoLong": "(Betrayal Add-ons):\nAs a recruit, you are on the Jackal's team and help out the Jackal and their Sidekicks.\n\nYou cannot win with your original team.", "AdmiredInfoLong": "(Betrayal Add-ons):\nAs an admired player, you win with the crew and not your original team.\n\nYou can see the Admirer.", "GlowInfoLong": "(Add-ons):\nDuring lights out, you and players nearby you will receive a vision boost.", "RadarInfoLong": "(Add-ons):\nAs Radar, you have arrows pointing towards the closest person at all times.", @@ -1025,7 +1011,6 @@ "ProhibitedInfoLong": "(Add-ons):\nAs the Prohibited, you have specific vents that you can't use.\nHow many vents are disabled depends on the Host's settings.", "EavesdropperInfoLong": "(Add-ons):\nAs the Eavesdropper, you have a chance to read other role/addon information-based messages like Mortician or Sleuth.", "ApocalypseInfoLong": "(Apocalypse):\nApocalypse members are on a separate team that works together and wins together. If there are multiple Apocalypse roles in the game, they can see each other's roles.\nDepending on the Host's settings, Apocalypse roles can guess or be guessed.", - "RevenantInfoLong": "(Neutral):\nAs the Revenant, your goal is to be killed. If you are killed, you will take your killer's role and kill your killer instead. You cannot win before being killed.\nNote that Revenant only works when being directly killed.", "ShowTextOverlay": "Text Overlay", "Overlay.GuesserMode": "Guesser Mode", "Overlay.NoGameEnd": "No Game End", @@ -1039,8 +1024,6 @@ "AbilityUseLimit": "Initial Ability Use Limit", "AbilityInUse": "Ability in use", "AbilityExpired": "Ability expired, {0} uses remain", - "RevenantTargeted": "Your role has changed to {0}", - "RevenantCanCopyAddons": "Can Steal Addons", "ShowArrows": "Has Arrows pointing toward bodies", "ArrowDelayMin": "Minimum Arrow show-up delay", "ArrowDelayMax": "Maximum Arrow show-up delay", @@ -1370,8 +1353,6 @@ "ShieldedCanUseKillButton": "Shielded player can use ability / kill button", "PlayerIsShieldedByGame": "Player is protected by the game!", "LegacyNemesis": "Use Legacy Version", - "LegacyParasite": "Use Legacy Version", - "LegacyTraitor": "Use Legacy Version", "ArsonistKeepsGameGoing": "Arsonist keeps the game going", "ArsonistCanIgniteAnytime": "Can Ignite Anytime", "ArsonistMinPlayersToIgnite": "Minimum doused needed for ignite", @@ -1514,18 +1495,6 @@ "SheriffCanKillSeparately": "Individual Settings", "In%team%": "(Team %team%)", "SheriffMisfireKillsTarget": "Misfire Kills Target", - "BlackHolePlaceCooldown": "Black Hole Place Cooldown", - "BlackHoleDespawnMode": "Black Hole Despawn Mode", - "BlackHoleDespawnTime": "Time After Black Hole Despawns", - "Abyssbringer.Suffix": "<#00ffa5>Number of players consumed by {0} <#00ffa5>active black holes:\\n{1}", - "Abyssbringer.Suffix.BlackHole": "<#00ffa5>{0}: {1}", - "BlackHoleMovesTowardsNearestPlayer": "Black Hole Moves Towards Nearest Player", - "BlackHoleMoveSpeed": "Black Hole Moving Speed", - "BlackHoleRadius": "Black Hole Consuming Radius", - "AfterTime": "After Time", - "After1PlayerEaten": "After 1 Player Was Eaten", - "AfterMeeting": "After Meeting", - "None": "None", "SheriffShotLimit": "Max number of Kills", "SheriffCanKillAllAlive": "Can Kill When No One Is Dead", "SheriffCanKillCharmed": "Can kill Charmed players", @@ -1542,15 +1511,12 @@ "RebirthUses": "Amount of Rebirths", "RebirthCountVotes": "Only rebirth to players who voted for them", "RebirthFailed": "Ahh, how unfortunate, you did not find any viable souls to swap bodies with", - "FireworkerCooldown": "Placement Cooldown", "ReverieIncreaseKillCooldown": "Increase kill cooldown", "ReverieMaxKillCooldown": "Max kill cooldown", "ReverieMisfireSuicide": "Misfire on reaching max kill cooldown", "ReverieResetCooldownMeeting": "Reset kill cooldown after meeting", "ConvertedReverieKillAll": "Converted Reverie can kill anyone without repercussions", "VigilanteNotify": "You have become the very thing you swore to destroy", - "DictatorChangeCommandToExpel": "Dictator use Command to expell instad of vote", - "DictatorExpelSelf": "WAIT WAIT WAIT WAT THE HELLLLLL Bro really just want to expel himself", "DoctorTaskCompletedBatteryCharge": "Battery Duration", "SnitchEnableTargetArrow": "See Arrow Towards Target", "SnitchCanGetArrowColor": "See Colored Arrows based on Team Colors", @@ -1624,6 +1590,7 @@ "TimeThiefDecreaseMeetingTime": "Lower Meeting Time by", "TimeThiefLowerLimitVotingTime": "Minimum Voting Time", "TimeThiefReturnStolenTimeUponDeath": "Return Stolen Time Upon Death", + "TimeThiefMaxTimeOnAdmired": "Maximum Meeting Time if Time Thief Is Admired", "EvilTrackerCanSeeKillFlash": "Can See Kill-Flash", "EvilTrackerCanSeeLastRoomInMeeting": "Can See Target's Last Room In Meeting", "EvilTrackerTargetMode": "Can Set Target", @@ -1631,7 +1598,6 @@ "EvilTrackerTargetMode.OnceInGame": "Once in-game", "EvilTrackerTargetMode.EveryMeeting": "Every Meeting", "EvilTrackerTargetMode.Always": "Any time", - "ScavengerHasCustomDeathReason": "Enable Custom Death Reason", "EvilHackerCanSeeDeadMark": "Can See The Location of Dead-bodies", "EvilHackerCanSeeImpostorMark": "Can See The Location of Other Impostors", "EvilHackerCanSeeKillFlash": "Can See Kill-Flash", @@ -1864,21 +1830,13 @@ "Jackal_SidekickCountMode_Jackal": "Jackal", "Jackal_SidekickCountMode_Original": "Original Team", "Jackal_SidekickAssignMode": "Sidekick Assign Mode", - "Jackal_SidekickAssignMode_SidekickAndRecruit": "Sidekick when failed Recruit", - "Jackal_SidekickAssignMode_Sidekick": "Only Sidekick", - "Jackal_SidekickAssignMode_Recruit": "Only Recruit", + "Jackal_SidekickAssignMode_SidekickAndRecruit": "Sidekick+Recruit", + "Jackal_SidekickAssignMode_Sidekick": "Sidekick Only", + "Jackal_SidekickAssignMode_Recruit": "Recruit Only", + "JackalWinWithSidekick": "Jackal can win with Sidekick's team", "Jackal_SidekickCanKillSidekick": "Sidekicks can kill other Sidekicks", "Jackal_SidekickCanKillJackal": "Sidekick can kill Jackal", - "Jackal_RecruitFailed": "You can not recruit this player!", "JackalCanKillSidekick": "Jackal can kill Sidekick", - "Jackal_SidekickCanKillWhenJackalAlive": "Sidekick can kill while Jackal is Alive", - "Jackal_SidekickTurnIntoJackal": "Sidekick can turn into Jackal after its death", - "Jackal_RestoreLimitOnNewJackal": "Restore Recruit limit when Sidekick become new Jackal", - "Jackal_OnBecomeNewJackalMeeting": "The old Jackal {0} is dead.\nYou are selected as new Jackal\nWork together and win the game!", - "Jackal_OnNewJackalSelectedMeeting": "The old Jackal {0} is dead.\n{1} is selected as new Jackal!\nWork together and win the game!", - "Jackal_BecomeNewJackal": "Old Jackal Dead, You are now new Jackal!", - "Jackal_OnNewJackalSelected": "Old Jackal Dead, Please help new Jackal {0} for now!", - "Jackal_BossIsDead": "Opps, the Jackal boss is dead!", "CoronerArrowsPointingToDeadBody": "Arrows pointing to dead bodies", "CoronerLeaveDeadBodyUnreportable": "Bodies the Coroner uses can't be reported", "CoronerInformKillerBeingTracked": "Inform the Killer that he gets tracked", @@ -1916,9 +1874,6 @@ "VipTag": "VIP★", "ApplyVipList": "Apply VIP List", "AllowSayCommand": "Allow moderators to use /say command", - "AllowStartCommand": "Allow moderators to use /start command", - "StartCommandMinCountdown": "Minimum countdown for /start command", - "StartCommandMaxCountdown": "Maximum countdown for /start command", "KickCommandDisabled": "The kick command is currently disabled.", "KickCommandNoAccess": "You do not have access to the kick command.", "KickCommandInvalidID": "Invalid player ID specified.\nPlease use '/kick [playerID] [reason]' to kick a player.\nExample :- /kick 5 not following rules", @@ -1951,11 +1906,6 @@ "WarnCommandNoAccess": "You do not have access to the warn command.", "WarnCommandInvalidID": "Invalid player ID specified.\nPlease use '/warn [playerID] [reason]' to warn a player. \nExample :- /warn 5 lava chatting", "WarnCommandWarnHost": "You are not permitted to warn the host.", - "StartCommandNoAccess": "You do not have access to the start command.", - "StartCommandDisabled": "The start command is currently disabled.", - "StartCommandCountdown": "ERROR\n\nThe game is already starting!", - "StartCommandStarted": "The game has been started by {0}!", - "StartCommandInvalidCountdown": "ERROR\n\nThe countdown must be between {0} and {1}!", "WarnCommandWarnMod": "You are not permitted to warn other moderators.", "WarnCommandWarned": "has been warned. There will be no more warnings given and appropriate action will be taken \n ", "WarnExample": "Use /warn [id] [reason] in future. \nExample :-\n /warn 5 lava chatting", @@ -1983,7 +1933,6 @@ "DeathReason.Quantization": "Quantization", "DeathReason.Overtired": "Overtired", "DeathReason.Ashamed": "Ashamed", - "DeathReason.Consumed": "Consumed", "DeathReason.PissedOff": "Destroyed", "DeathReason.Dismembered": "Dismembered", "DeathReason.LossOfHead": "Strangled", @@ -2007,8 +1956,6 @@ "DeathReason.Starved": "Starved", "DeathReason.Equilibrium": "Equilibrium", "DeathReason.Sacrificed": "Sacrificed", - "DeathReason.Electrocuted": "Electrocuted", - "DeathReason.Scavenged": "Scavenged", "OnlyEnabledDeathReasons": "Only Enabled Death Reasons", "Alive": "Alive", "Disconnected": "Disconnected", @@ -2024,10 +1971,11 @@ "DeputyHandcuffCooldown": "Handcuff Cooldown", "DeputyHandcuffMax": "Maximum Handcuffs", "DeputyHandcuffedPlayer": "Handcuffed target", - "HandcuffedByDeputy": "You were handcuffed!", - "DeputyInvalidTarget": "Target cannot be handcuffed", + "HandcuffedByDeputy": "You were handcuffed!\nNow you have broken your handcuff and can kill again.", + "DeputyInvalidTarget": "Target is already handcuffed", + "HandcuffBrokenAfterMeeting": "Remove all handcuffs after meeting", "DeputyHandcuffText": "Handcuff", - "DeputyHandcuffCDForTarget": "Kill Cooldown for handcuffed player", + "DeputyHandcuffCDForTarget": "Next Kill Cooldown for handcuffed player", "RejectShapeshift.AbilityWasUsed": "Ability was used", "EscapisMtarkedPosition": "You marked self-position", "InvestigateCooldown": "Investigate Cooldown", @@ -2074,7 +2022,6 @@ "Command.dump": "→ Output Log to Desktop", "Command.death": "→ Display info on how you died", "Command.icons": "
╳ - The Player was marked by the Blackmailer and can't talk during the Meeting
☆ - Used by Captain to display themselves. Only Crewmates can see the Captain's star
乂 - This player was hexed by the Hex Master and will die if the Hex Master isn't killed or ejected by the end of the Meeting.
♦ - Used by Lawyer or Executioner or Follower.
♥ - Used by Lovers or Romantic.
✚ - Used by Medic to mark their target.
⦿ - This player is in a duel with the Pirate.
!? - This player was marked by the Quizmaster and must answer the question correctly to survive.
☜ - Used by Schrödinger's cat to mark their teammate.
◈ - This player marked by the Shroud and will die if the Shroud is not killed or ejected by the end of the meeting.
⚠ - This player is a Snitch or Solsticer who has finished their tasks.
★ - Used by Super Star or Cyber or Marshall.
† - This player was spelled and will die if the Witch is not killed by the end of the meeting.
∇ - Used by Kamikaze to mark their targets.
■ - Used by Lightning to mark their quantum ghosts.
⊠ - Used by Jailer to mark their prisoner.
● - Used by Baker to mark who has Bread.
♠ - Used by Soul Collector to mark who's death they're predicting.
⦿ - Used by Plaguebearer to mark who they have plagued.", - "Command.start": "[Seconds] → Start the game", "Command.iconinfo": "→ Display info on in-meeting icons", "Command.iconhelp": "→ Display info on in-meeting icons to everyone", "Command.Poll": "→ Start a poll with up-to 5 choices", @@ -2087,7 +2034,6 @@ "ShowMadmatesInLeftCommand": "Show Madmates (including add-ons)", "ShowApocalypseInLeftCommand": "Show Neutral Apocalypse", "SeeEjectedRolesInMeeting": "See ejected roles in meetings", - "ThankYouForUsingTOHE": "Thank you for using TOHE!", "SkillUsedLeft": "You have activated your skill to call a meeting. \nRemaining amount of uses left:", "NemesisDeadMsg": "The death of the Nemesis means the beginning of the revenge. \nPlease use /rv + [player ID] to kill the specified player \nYou can see player IDs in front of their names. \nOr type /rv to get a list of player IDs", "NemesisAliveKill": "Revenge for the Nemesis can only begin after their death.", @@ -2107,7 +2053,6 @@ "GuessNotifiedBait": "Bait can't be guessed because it was announced. You thought it would be that easy, right?", "GuessGM": "Guessing the GM is impossible because they're already dead.... And why would you do that to the poor Host?", "GuessGuardianTask": "You can't guess a Guardian who has finished their tasks.", - "GuardianCantKilled": "You can't kill a Guardian who has finished their tasks.", "GuessMarshallTask": "You can't guess a Marshall who has finished their tasks.", "GuessObviousAddon": "Sorry, obvious add-ons cannot be guessed.", "GuessAdtRole": "Unfortunately, the Host's settings do not allow you to guess add-ons", @@ -2163,7 +2108,6 @@ "BecomeMadmateCuzMadmateMode": "You became a Madmate because you died", "CleanerCleanBody": "The body has been cleaned", "QuickShooterStoraging": "Bullets stored successfully", - "QuickShooterFailed": "You are still in cooldown.", "PoisonerTargetDead": "Target died", "HexesLookLikeSpells": "Hexes appear as spells", "HexButtonText": "Hex", @@ -2322,7 +2266,6 @@ "Message.YTPlanNotice": "Note: The [YouTuber Plan] is enabled in this lobby, which means the Host can specify their role in the next game to make it easier to get content. If the Host abuses this feature, please exit the game or report it.\nCurrent Creator Credentials:", "Message.OnlyCanBeUsedByHost": "ERROR\n\nThis command may only be used by the host.", "Message.MaxPlayers": "Maximum players set to ", - "Message.MaxPlayersFailByRegion": "Could not set max players: Vanilla regions support a maximum of 15 players.", "Message.GhostRoleInfo": "Ghost Role Info\nHiya! A little about ghost roles...\n\nGhost roles drastically impact the game, so it's not recommended for smaller lobbies if you're unfamiliar. If not explicitly stated otherwise in the description, the Guard button is their ability button ;)\n\nSpawning:\nGhost-roles only spawn after death; the first x people from (team) to die get them.\n\nPS: If your previous role didn't have tasks(e.g., sheriff), your tasks as a ghost-role aren't needed for task-win", "ApocalypseInfoTitle": "Neutral Apocalypse Info:", "Message.ApocalypseInfo": "Every role of the <#ff174f>Apocalypse Team has their own objective to carry out in order to transform.\n<#2B0804>Transformed <#ff174f>Apocalypse members have a drastic change on the game and are immortal (except for being voted), but everyone will be notified that they have transformed.\n\nRoles: <#e5f6b4>Plaguebearer, <#A675A1>Soul Collector, <#bf9f7a>Baker, <#cc0044>Berserker\nTransformed: <#343136>Pestilence, <#644661>Death, <#83461c>Famine, <#2B0804>War\n\nApocalypse members can see eachother's roles and ability icons.\nLike Neutral Killers, Apocalypse members keep the game going as well, have fun!", @@ -2454,6 +2397,7 @@ "LastResult": "★ Match Results", "LastEndReason": "★ End Reason", "KillLog": "Kill Log", + "MainRoleLog": "Role Convert Log", "Maximum": "Max", "RoleRate": "ON", "RoleOn": "ALWAYS", @@ -2730,9 +2674,8 @@ "DeathMeetingTimeIncrease": "Increased Meeting time when Death exists", "SoulCollectorMeetingDeath": "Your target has died during the meeting. You have gained a soul.", "SoulCollectorKillButtonText": "Predict", - "SoulCollectorHasImpostorVision": "Soul Collector has Impostor vision", "ApocalypseIsNigh": "[ The Apocalypse Is Nigh! ]", - "ApocalypseImmune": "This role is immune!", + "ApocalypseImmune": "This player is immune because they are invincible!", "BakerToFamine": "You have become Famine!!!", "BakerTransform": "The Baker has transformed into Famine, Horseman of the Apocalypse! A famine has begun!", "BakerAlreadyBreaded": "That player already has bread!", @@ -2741,15 +2684,13 @@ "BakerBreadNeededToTransform": "Required number of bread to become Famine", "BakerCantBreadApoc": "You cannot give other Apocalypse members bread!", "BakerKillButtonText": "Bread", - "BakerUnshiftButtonText": "Switch Bread", "BakerRevealBread": "Reveal", "BakerRoleblockBread": "Roleblock", "BakerBarrierBread": "Barrier", "BakerCurrentBread": "Current Bread: ", "BakerSwitchBread": "Bread Switched to: ", - "BakerCanVent": "Baker can Vent", + "BakerCanVent": "Baker can Vent", "BakerBreadGivesEffects": "Bread gives additional effects", - "BakerTransformNoMoreBread": "Baker transforms if they do not have enough bread", "FamineKillButtonText": "Starve", "FamineStarveCooldown": "Famine starve cooldown", "FamineCantStarveApoc": "You cannot starve other Apocalypse members!", @@ -2796,7 +2737,6 @@ "GodfatherTargetCountMode": "Killer turns into", "GodfatherCount_Refugee": "Refugee", "GodfatherCount_Madmate": "Madmate", - "GodfatherRefugeeMsg": "You have been recruited by GodFather!", "MissChance": "Chance To Miss", "IncreaseByOneIfConvert": "Increase The KillCount +1 If a Crew Is Converted", "HawkMissed": "Missed!", @@ -2829,7 +2769,6 @@ "BerserkerToWar": "You have become War!!!", "BerserkerTransform": "The Berserker has transformed into War, Horseman of the Apocalypse! Cry 'Havoc!', and let slip the dogs of war.", "WarKillCooldown": "War kill cooldown", - "BerserkerCanKillTeamate": "Can kill other Neutral Apocalypse", "BlackmailerSkillCooldown": "Blackmail Cooldown", "BlackmailerMax": "Maximum times blackmailed players may speak", "BlackmailerDead": "Warning! {0} has been blackmailed by a Blackmailer!", @@ -2919,8 +2858,6 @@ "RememberedPursuer": "You remembered you were a Pursuer!", "RememberedFollower": "You remembered you were a Follower!", "RememberedAmnesiac": "You failed to remember your role.", - "AmnesiacRemembered": "You remembered you were {0}!", - "ReportWhenFailedRemember": "Report Dead Body when failed to remember", "RememberedImitator": "You remembered you were an Imitator.", "RememberedImpostor": "You remembered you were an Impostor!", "RememberedCrewmate": "You remembered you were a crewmate!", @@ -3146,7 +3083,7 @@ "DollMaster_PossessedTarget": "Possessed target", "DollMaster_CannotPossessImpTeammate": "Unable to possess teammate", "DollMaster_CouldNotSwapWithTarget": "Unable to possess player", - "DollMaster_CanNotSwapWithDeadTarget": "Possesing a dead player isn't possible", + "DollMaster_CanNotSwapWithDeadTarget": "Possessing a dead player isn't possible", "DollMaster_MainBody": "Main Body", "DollMaster_Doll": "Doll", "DollMaster_UnableToUseAbility": "Unable to use your ability on player", @@ -3334,12 +3271,9 @@ "PixieTargetAlreadySelected": "Target is already selected", "PixieButtonText": "Mark", "PlagueBearerCooldown": "Plague cooldown", - "PlagueBearerCanVent": "Can vent", - "PlagueBearerHasImpostorVision": "Has Impostor vision", "PestilenceCooldown": "Pestilence Kill cooldown", "PestilenceCanVent": "Pestilence Can Vent", "PestilenceHasImpostorVision": "Pestilence Has Impostor Vision", - "PestilenceKillGuessers": "Kill players who guess Pestilence", "PlagueBearerAlreadyPlagued": "Player has already been plagued", "PlagueBearerToPestilence": "You have turned into Pestilence!!", "GuessPestilence": "You just tried to guess Pestilence!\n\nSorry, Pestilence killed you.", @@ -3383,7 +3317,6 @@ "EveryoneCanKnowMini": "Everyone can see the Mini", "CanBeEvil": "Mini can be an Impostor", "EvilMiniSpawnChances": "Probability of Mini being an Impostor", - "EvilMiniCanBeGuessed": "Evil Mini can be guessed before 18", "GuessMini": "Sorry, you can't hurt a kid Mini.", "GrowUpDuration": "Time required to grow (s)", "MajorCooldown": "Kill Cooldown when over 18", @@ -3525,7 +3458,6 @@ "WinnerRoleText.Doppelganger": "Doppelganger Wins!", "WinnerRoleText.Quizmaster": "Quizmaster Wins!", "WinnerRoleText.Agitater": "Agitator Wins!", - "WinnerRoleText.Shocker": "Shocker Wins!", "AdditionalWinnerRoleText.Sidekick": "Sidekick", "AdditionalWinnerRoleText.Taskinator": "Taskinator", "AdditionalWinnerRoleText.Opportunist": "Opportunist", @@ -3611,7 +3543,7 @@ "SolsticerOnMeeting": "You witnessed too many deaths! Next round you will have {0} more short task!", "SolsticerTitle": "Solsticer", "GuessSolsticer": "Sorry, but you can not guess Solsticer!", - "ExpelSolsticer": "Sorry, but you can not expel Solsticer!", + "VoteSolsticer": "Sorry, but you can not vote Solsticer!", "SolsticerTasksReset": "Your tasks get reset!", "SolsticerMisGuessed": "You just misguessed! You are no longer allowed to guess.", "SolsticerGuessMax": "Because you already misguessed, you are no longer allowed to guess.", @@ -3712,19 +3644,6 @@ "MinionAbilityTime": "Ability Duration", "Minion_Blind": "blinded", "Evader_ChanceNotExiled": "Chance not be exiled", - "ShockerAbilityCooldown": "Ability Cooldown", - "ShockerAbilityDuration": "Ability Duration", - "ShockerAbilityPerRound": "Abilities Per Round", - "ShockerShockInVents": "Shock people in vents", - "ShockerAbilityResetAfterMeeting": "Reset marked rooms after meeting", - "ShockerOutsideRadius": "Radius Of Outside Tasks (not in a room)", - "ShockerCanShockHimself": "Can Shock Himself", - "ShockerImpostorVision": "Shocker has Impostor vision", - "ShockerIsShocking": "You're already shocking!", - "ShockerAbilityActivate": "Begin Shocking!", - "ShockerAbilityDeactivate": "Ability Deactivated", - "ShockerVentButtonText": "Shock", - "ShockerRoomMarked": "Marked Room", "EavesdropperMsgTitle": "You found a secret", "EavesdropPercentChance": "Chance to eavesdrop", "ChiefOfPoliceSkillCooldown": "Cooldown for recruiting sheriffs", @@ -3736,4 +3655,4 @@ "PolicPreventRecruitNonKiller": "Prevent recruit players without kill button", "PolicSuidiceWhenTargetNotKiller": "Suidices when recruit a non killer or non crewmate", "PolicPassConverted": "Can pass Converted Addon to Sheriff" -} +} \ No newline at end of file diff --git a/Resources/Lang/fr_FR.json b/Resources/Lang/fr_FR.json index 36f4564eb..0703f90cc 100644 --- a/Resources/Lang/fr_FR.json +++ b/Resources/Lang/fr_FR.json @@ -20,8 +20,6 @@ "SubText.Neutral": "Travaille seul pour remporter la Victoire", "SubText.Apocalypse": "Devenez imparable avec votre équipe", "SubText.Madmate": "Aide les Imposteurs", - "SubText.Lovers": "Stay alive and win together", - "SubText.Egoist": "Win on your own", "TypeImpostor": "Imposteurs", "TypeCrewmate": "Coéquipiers", "TypeNeutral": "Neutres", @@ -31,9 +29,6 @@ "TeamNeutral": "Neutre", "TeamCrewmate": "Coéquipier", "TeamMadmate": "Complice", - "TeamLovers": "Lovers", - "TeamEgoist": "Egoist", - "TeamApocalypse": "Apocalypse", "YouAreCrewmate": "Tu es un Coéquipier", "YouAreImpostor": "Tu es un Imposteur", "YouAreNeutral": "Tu es un Neutre", @@ -225,7 +220,6 @@ "TaskManager": "Gestionnaire de Tâches", "Witness": "Témoin", "Swapper": "Échangeur", - "ChiefOfPolice": "Chief of Police", "NiceMini": "Bon Gamin", "Mini": "Gamin", "Spy": "Espion", @@ -254,7 +248,6 @@ "Stalker": "Harceleur", "Workaholic": "Aliéné", "Solsticer": "Solsticien", - "Abyssbringer": "Abyssbringer", "Collector": "Collectionneur", "Provocateur": "Provocateur", "BloodKnight": "Chevalier de Sang", @@ -393,8 +386,6 @@ "Sloth": "Paresseux", "Prohibited": "Interdit", "Eavesdropper": "Eavesdropper", - "Shocker": "Shocker", - "Revenant": "Revenant", "BracketAddons": "Ajouter des parenthèses aux Modifieurs", "EngineerTOHEInfo": "Utilise les Évacuations pour démasquer les Imposteurs", "ScientistTOHEInfo": "Accède aux Signes Vitaux de n'importe où", @@ -513,7 +504,7 @@ "PacifistInfo": "Évacue pour réinitialiser les Rechargements d'Exécution", "RebirthInfo": "Surgir de Nouveau", "MonarchInfo": "Donne à ton Équipe des Votes supplémentaire !", - "AbyssbringerInfo": "Place Black Holes", + "AbyssbringerInfo": "Create Black Holes", "SpurtInfo": "Spring Like A rabbit!", "StealthInfo": "Obscurci la Vision de tout le monde dans la pièce en Exécutant", "PenguinInfo": "Fais Glisser tes victimes", @@ -538,7 +529,7 @@ "AdmirerInfo": "Choisis un joueur qui sera à tes côtés", "TimeMasterInfo": "Rembobine le Temps !", "CrusaderInfo": "Exécute l'Agresseur d'un joueur", - "AltruistInfo": "Ressusciter un joueur", + "AltruistInfo": "Revive a player\nVent to change between Revive and Report", "ReverieInfo": "Chaque fois que tu Exécutes un joueur, ton Rechargement diminue", "LookoutInfo": "Vois à travers les Déguisements", "TelecommunicationInfo": "Suis l'utilisation des Appareils de Sécurité", @@ -547,7 +538,6 @@ "WitnessInfo": "Découvre si quelqu'un a Exécuté récemment", "GhastlyInfo": "Contrôlez quelqu'un!", "SwapperInfo": "Échange les Votes de deux joueurs", - "ChiefOfPoliceInfo": "Hire Sheriff to Serve the Crews!", "NiceMiniInfo": "Personne ne peut te faire de mal tant que tu n'as pas grandi.", "ArsonistInfo": "Asperge tout le monde et Incendie !", "PyromaniacInfo": "Asperge et Exécute tout le monde", @@ -603,7 +593,7 @@ "VultureInfo": "Dévore des Cadavres en les Signalant pour Gagner", "TaskinatorInfo": "Tâches silencieuses, Explosions Mortelles", "BenefactorInfo": "Tâche Accomplie, Bouclier d'Élite !", - "MedusaInfo": "Pétrifie les Cadavres en les Signalant", + "MedusaInfo": "Stone bodies by reporting them", "SpiritcallerInfo": "Transforme les joueurs en Mauvais Esprits", "AmnesiacInfo": "Souviens-toi du Rôle d'un Cadavre", "ImitatorInfo": "Imites le Rôle d'un joueur", @@ -615,19 +605,19 @@ "ShroudInfo": "Possède des joueurs pour faire qu'ils Exécutent", "WerewolfInfo": "Exécute les Coéquipiers en groupe", "ShamanInfo": "Dévie toutes les attaques sur la Poupée Vaudou", - "SeekerInfo": "Joue à Cache-Cache avec ta Cible", + "SeekerInfo": "Play Hide and Seek with your target\nYour target has a ★ mark.", "PixieInfo": "Marque-les, Accuse-les, et Éjecte-les !", "OccultistInfo": "Exécute et Maudis tes Ennemis", "SchrodingersCatInfo": "Le Chat est à la fois Vivant et Mort jusqu'à ce qu'on l'observe.", "RomanticInfo": "Protège ton Partenaire pour Gagner ensemble", "VengefulRomanticInfo": "Venge ton Partenaire pour Gagner ensemble", "RuthlessRomanticInfo": "Exécute tout le monde pour Gagner avec ton Partenaire", - "PoisonerInfo": "Exécute tout le monde en Différé", + "PoisonerInfo": "Kill everyone with delayed kills", "HexMasterInfo": "Ensorcèle les joueurs pour les Exécuter pendant la Réunion", "WraithInfo": "Utilisez les ventilations pour être temporairement invisible", - "JinxInfo": "Renvoie les Attaques sur vos Attaquants", + "JinxInfo": "Reflect attacks onto your attackers", "PotionMasterInfo": "Utilise tes Potions à ton avantage", - "NecromancerInfo": "Exécute ton Exécuteur pour défier la Mort", + "NecromancerInfo": "Kill your killer to defy death", "WardenInfo": "(Fantômes):\nAvise des Dangers", "MinionInfo": "(Fantômes)\nAveugle les ennemis", "LoversInfo": "Restez en Vie et Gagnez ensemble", @@ -708,8 +698,6 @@ "SlothInfo": "Vous êtes plus lent", "ProhibitedInfo": "Certains conduits d'aération sont bloqués", "EavesdropperInfo": "Listen in on other roles", - "ShockerInfo": "Shock unsuspecting players", - "RevenantInfo": "Take your killer's role", "EngineerTOHEInfoLong": "(Coéquipiers):\nL'Ingénieur peut accéder aux Évacuations tant qu'il n'y a pas de Sabotage des Communications.", "ScientistTOHEInfoLong": "(Coéquipiers):\nEn tant que Scientifique, vous pouvez voir les Signes Vitaux, à n'importe quel moment, vous montrant qui est en vie et qui est décédé.", "NoisemakerTOHEInfoLong": "(Crewmates):\nAs the Noisemaker, whenever you die, you will make a noise, and a visual indicator of your death appears on the screen so the Crewmates can run to catch the person who killed you red-handed (even if it’s not Red).", @@ -781,11 +769,11 @@ "LurkerInfoLong": "(Imposteurs):\nLe Fureteur peut Sauter dans une Évacuation pour réduire son Rechargement d'un certain nombre de secondes. Après avoir Exécuté, son Rechargement est réinitialisé à sa valeur d'origine.", "VisionaryInfoLong": "(Imposteurs):\nLe Visionnaire voit les Alignements des joueurs Vivants lors d'une Réunion.\nLes Informations suivantes seront Affichées sur le joueur :\n- Le Nom Rouge indique les Imposteurs.\n- Le Nom Cyan indique les Coéquipiers.\n- Le Nom Gris indique les Neutres.", "PlagueDoctorInfoLong": "(Neutres):\n(Plague Doctor de TOH)\nLe Médecin de Peste doit d'Infecter tous les joueurs en Vie.\nIl commence par choisir un joueur à Infecter, après quoi n'importe qui passant un temps défini à poximité du joueur Infecté sera Infecter à son tour.\nLa progression de l'Infection est cumulative et ne se réinitialise pas avec la distance ou après une Réunion.", - "RefugeeInfoLong": "(Madmates):\nAs the Refugee, you were either:\n -An Amnesiac who remembered an Impostor\n -A killer who killed the Godfather's target.\n -A Romantic whose partner was an Impostor\n -Or an Imitator that imitated an Impostor.\n\nNow your job is to help the Impostors kill the crewmates.", + "RefugeeInfoLong": "(Complices):\nLe Réfugié étais soit un Amnésique qui s'est Souvenu être Imposteur, soit l'Exécuteur d'une Cible du Parrain.\n\nMaintenant, son but est d'Aider les Imposteurs à Exécuter les Coéquipiers.", "UnderdogInfoLong": "(Imposteurs):\nLe Postulant ne peut pas Exécuter tant qu'il y a un certain nombre de joueurs en Vie.", "ConsigliereInfoLong": "(Imposteurs):\nL'Éminence Grise peut Révéler le Rôle des autres joueurs en utilisant son Bouton d'Exécution.\n\nUn seul clic : Révéler le Rôle.\nDouble clic : Exécuter.\n\nS'il n'a plus d'utilisation pour Révéler, son Bouton d'Exécution fonctionne normalement.", "LudopathInfoLong": "(Imposteurs):\nLe Ludopathe a un Rechargement d'Exécution Aléatoire.\n\nLe minimum est de 1 seconde, tandis que le maximum est le Rechargement par défaut d'Exécution.", - "GodfatherInfoLong": "(Impostors):\nAs the Godfather, you vote someone to make them your target.\nIn the next round, if someone kills the target, the killer will turn into a Refugee or Madmate.", + "GodfatherInfoLong": "(Imposteurs):\nLe Parrain Vote quelqu'un pour en faire sa Cible.\nÀ prochaine Manche, si quelqu'un Exécute sa Cible, l'Exécuteur se transformera en Réfugié.", "ChronomancerInfoLong": "En tant que Chronomancien, vous avez une barre de recharge qui indique lorsque l'exécution est prête. Lorsqu'elle est à 100% la prochaine fois que vous exécutez quelqu'un, vous irez en mode meurtrier, cela veut dire que vous pouvez tuer constamment jusqu'à ce que votre barre de recharge se vide. Sinon, vous aurez un temps mort d'exécution normal.", "PitfallInfoLong": "(Imposteurs):\nLe Piégeur utilise sa Métamorphose pour Marquer la zone autour de la Métamorphose comme un Piège. Les joueurs qui entrent dans cette zone seront Immobilisés pendant une courte période et leur Vision sera affectée.", "EvilMiniInfoLong": "(Imposteurs):\nLe Mauvais Gamin est inexécutable jusqu'à ce qu'il Grandisse et il a un Rechargement d'Exécution très long, qui sera considérablement réduit quand il Grandira.", @@ -821,7 +809,7 @@ "GrenadierInfoLong": "(Coéquipiers):\nLe Grenadier peut Évacuer pour Aveugler les joueurs proches, cela va Diminuer leur Vision s'ils sont Imposteurs ou, selon les Réglages, les Neutres.", "MedicInfoLong": "(Crewmates):\nThe Medic can place a shield on the target by pressing the Kill button. The Medic can only give one shield for the whole game. Depending on the settings, the target's shield can or cannot deactivate when the Medic dies. The Medic can also see if someone is trying to break the target's shield.\nDepending on the Host's settings, the Medic or the target can see if the player has a shield (shown as a green circle 「●」 next to the name).", "FortuneTellerInfoLong": "(Crewmates):\nAs the Fortune Teller, vote for a player in a meeting to get a clue to their role.\nThe clue will relate to their actual role.\n\nWhen the Fortune Teller's tasks are complete, they will obtain the exact role rather than a clue!\n\nNote: If the setting to give random active players as a hint is on, you cannot check the same player multiple times.", - "JudgeInfoLong": "(Crewmates):\nThe Judge can judge a certain player during the meeting. If the target is evil, the target will be killed (whether it is evil or not is set by the Host). If it is wrong, the Judge commits suicide.\nCommand for judgment: /tl [player id]\nYou can see the player's id before the player's name, or use the /id command to view the id of all players.\nJudges can judge all players when they become Madmate.", + "JudgeInfoLong": "(Crewmates):\nThe Judge can judge a certain player during the meeting. If the target is evil, the target will be killed (whether it is evil or not is set by the Host). If it is wrong, the Judge commits suicide.\nCommand for judgment: /tl [player id]\nYou can see the player's id before the player's name, or use the /id command to view the id of all players.\nJudges can judge all players when they become Madmate.\nIn meeting the ability count shows how many trails you have in this meeting. Out of meeting the ability counts shows how many trails you have for the whole game.", "MorticianInfoLong": "(Crewmates):\nThe Mortician can see arrows pointing to all dead bodies, and if the Mortician reports a body, they will know the last player the victim had contact with. Note: Mortician won't be Oblivious or Seer.", "MediumInfoLong": "(Crewmates):\nThe Medium can establish contact with a dead player after someone reports a dead body. The player who reports doesn't have to be the Medium. The dead player can answer once with a YES or a NO to the Medium's question, which only the Medium will see (the dead player can use /ms yes or /ms no). Note: Medium won't be Oblivious.", "ObserverInfoLong": "(Crewmates):\nAs the Observer, you can see all shield animations caused by other players after the first meeting. The shied animations typically indicate a role ability, so look out for this.", @@ -833,7 +821,7 @@ "MerchantInfoLong": "(Crewmates):\nAs a merchant, you sell a random add-on to a random player for each task you complete. Each add-on sold earns you money. If you have a certain amount of money, you can prevent the next killing attempt against you by bribing the murderer. The bribed player won't be able to kill you, but you don't know who it is. The money used is lost and not available for additional bribes.", "RetributionistInfoLong": "(Crewmates):\nLe Revanchard peut Exécuter un nombre limité de joueurs après sa Mort.\n\nIl utilise /ret [ID du joueur] pour Exécuter.", "HawkInfoLong": "(Coéquipiers [fantôme]):\\nEn tant qu'épurateur, vous pouvez tuer un nombre limité de joueurs décidé par l'hôte, cependant il y a une chance que votre coup rate, Empaler quelqu'un plusieurs fois en augmente les chances.", - "DeputyInfoLong": "(Crewmates):\nL'Adjoint utilise son Bouton d'Exécution sur un joueur pour Réinitialiser son Rechargement.\nSi la Cible n'a pas de Bouton d'Exécution, alors la Menotte a été gaspillée.", + "DeputyInfoLong": "(Crewmates):\nAs the Deputy, use your kill button to handcuff a player.\nThe player who is handcuffed will have their next kill attempt treated as a handcuff break, and the kill cooldown will be reset.\n\nIf the target does not have a kill button, then the handcuff was a waste.", "InvestigatorInfoLong": "(Crewmates):\nAs an Investigator, you can use your kill button to investigate someone. When you investigate someone, their name will appear in red if they possess a kill button (impostor/SS basis) or light blue if they lack a kill button (crewmate/engineer/scientist basis). However, please note that the color of the names will return to normal when someone calls a meeting.", "GuardianInfoLong": "(Crewmates):\nAs the Guardian, you become immortal upon task completion. Guessers can't even guess you in meetings.", "AddictInfoLong": "(Crewmates):\nAs the Addict, you have a suicide timer. When it expires, you kill yourself.\nThe timer is indicated by the vent cooldown. When the vent cooldown is 0 seconds, you still have a short time to vent.\nIf you don't make it, you die; if you make it, the suicide timer is reset.\nAlso after you vent, no one can interact with you for a defined period.\nAfter; the period is over, and you are immobilized for another defined period, and cannot report any bodies.", @@ -849,7 +837,7 @@ "AdmirerInfoLong": "(Crewmates):\nAs the Admirer, admire a player to make them Crewmate aligned.\nThey'll win with crewmates and not their original team.\n\nYou can only do this once per player.", "TimeMasterInfoLong": "(Coéquipiers):\nLe Maître du Temps utilise les conduits pour Marquer la Position de tout le monde.\nLorsqu'il utilise à nouveau cette Capacité, tous les joueurs Vivants seront ramenés aux positions Marquées.\n\nPendant la Durée de la Capacité, le Maître du Temps gagne un Bouclier Temporel, qui le protège de la Mort.", "CrusaderInfoLong": "(Coéquipiers):\nLe Croisé, utilise son Bouton d'Exécution pour Croiser un joueur.\nSi ce joueur est Attaqué, vous Exécuterez l'Attaquant.", - "AltruistInfoLong": "(Crewmates):\nAs the Altruist, you can sacrifice yourself to revive a dead body using the «Report» button.\nNote: If a dead player has left the game, you report that body normally.\nAlso revived player cannot report self dead body", + "AltruistInfoLong": "(Crewmates):\nAs the Altruist, you can sacrifice yourself to revive a dead body using the «Report» button.\nNote: If a dead player has left the game, you report that body normally.\nAlso revived player cannot report self dead body\nUse vent button to change between Report & Revive.", "ReverieInfoLong": "(Coéquipiers):\nLe Réveur peut Exécuter mais son Rechargement est élevé.\n\nIl Augmente s'il Exécute un Coéquipier sinon il Diminue.\nSelon les Réglages de l'Hôte, il peut faire un Tir-Raté en atteignant le Rechargement d'Exécution maximal et sa Cible Meurt avec lui.\n\nIl Gagne avec les autres Coéquipiers.", "LookoutInfoLong": "(Coéquipiers):\nLe Guetteur peut voir les ID de tous les joueurs à tout moment.\nCe qui vous permet de Voir à travers les Métamorphoses et les Camouflages.", "TelecommunicationInfoLong": "(Coéquipiers):\nLe Télécommunication est averti lorsque quelqu'un regarde les Caméras, les Signes Vitaux, le Journal des Portes ou la Table d'Administration.", @@ -872,7 +860,7 @@ "LawyerInfoLong": "(Neutres):\nL'Avocat a une Cible à Défendre, qui sera indiquée par un Diamant 「♦」 à côté de son Nom.\nSi sa Cible Gagne, Il Gagne.\nSi elle Perd, il Perd.", "OpportunistInfoLong": "(Neutres):\nL'Opportuniste a pour but de Survivre jusqu'à la fin de la Partie. Il Gagne avec l'Équipe gagnante.", "VectorInfoLong": "(Neutres):\nLe Chauffagiste Gagnera seul en Évacuant un certain nombre de fois.", - "JackalInfoLong": "(Neutrals):\nAs the Jackal, you win if you are the last player alive. Additionally, you may recruit using the kill button. If the target is not one you can recruit, you have run out of uses, or you don't have the option to recruit, then you will kill people normally (i.e., don't use kill buttons in front of others thinking it'll recruit). If the target has a kill button and the option to turn into a Sidekick is on, they will become a Sidekick. Otherwise, they will gain the Recruit add-on if the option to give the Recruit add-on is on.\nDepending on the settings, when Jackal was killed, a Sidekick will be randomly selected as the new Jackal.\nRecruit may be selected if no sidekick is alive.", + "JackalInfoLong": "(Neutrals):\nAs the Jackal, you win if you are the last player alive. Additionally, you may recruit using the kill button. If the target is not one you can recruit, you have run out of uses, or you don't have the option to recruit, then you will kill people normally (i.e., don't use kill buttons in front of others thinking it'll recruit). If the target has a kill button and the option to turn into a Sidekick is on, they will become a Sidekick. Otherwise, they will gain the Recruit add-on if the option to give the Recruit add-on is on.", "GodInfoLong": "(Neutrals):\nAs the God, you know everyone's role from the beginning. If you live until the end of the game, you steal the win, i.e., everyone else loses, and you win.", "InnocentInfoLong": "(Neutrals):\nThe Innocent can use the kill button to plant any player, and the planted target will immediately kill the Innocent. If the target gets voted out in the meeting, the Innocent wins. Note: Jester, Executioner, and Innocent can win together.", "PelicanInfoLong": "(Neutrals):\nAs the Pelican, you can use the kill button to swallow a player alive, teleporting them off-bounds but not killing them yet. Those swallowed will only die if you're still alive at the end of the round. If you die or leave during the round, all alive swallowed players will spawn into the map where you were.", @@ -884,14 +872,14 @@ "SolsticerInfoLong": "(Neutrals):\nAs the Solsticer, you won't die, and you win by finishing all your tasks in a single round. After every meeting finishes, your tasks reset, and you need to start all over again.\nVotes on the Solsticer will be directly canceled.\nKill attempts on the Solsticer will teleport it out of the map like Pelican until the meeting is finished.\nThe killer's kill cooldown will be reset to 10 seconds.\nSolsticer is counted as nothing in-game.", "CollectorInfoLong": "(Neutrals):\nAs the Collector, when you vote for a player, for each other player that voted for them, you gain a point. When you collect the required votes, the game ends, and you win alone, even if you voted a Jester or Executioner's target out.", "GlitchInfoLong": "(Neutrals):\nAs the Glitch, you can hack players (single click) or kill normally (double click).\nThose who have been hacked cannot kill, vent, or report for the hack duration.\nAdditionally, calling a sabotage other than doors will have no effect and will instead disguise you as a random player. You cannot disguise during or after sabotages.\nTo win, be the last player alive.", - "SidekickInfoLong": "(Neutrals):\nAs the Sidekick, your job is to help the Jackal kill everyone.\nYou and the Jackal win together.\nDepending on the settings, you may turn into Jackal if old Jackal was killed.\nYou may not be able to kill until old Jackal is dead.", + "SidekickInfoLong": "(Neutres):\nL'Acolyte doit aider le Chacal à Exécuter tout le monde.\n\nLui et le Chacal Gagnent ensemble.", "ProvocateurInfoLong": "(Neutres) :\nLe Provocateur peut Exécuter n'importe quelle Cible avec le Bouton d'Exécution. Si la Cible perd à la fin de la Partie, le Provocateur Gagne avec l'Équipe gagnante.", "BloodKnightInfoLong": "(Neutrals):\nThe Blood Knight wins when they're the last killing role alive, and the amount of crewmates is lower or equal to the amount of Blood Knights. The Blood Knight gains a temporary shield after every kill, making them immortal for a few seconds.", "PlagueBearerInfoLong": "(Apocalypse):\nAs the Plaguebearer, plague everyone using your kill button to turn into Pestilence.\nOnce you turn into Pestilence, you will become immortal and gain the ability to kill, and you will kill anyone who tries to kill you.\n\nAlso, when infected players interact with uninfected players, they will also be infected.", "PestilenceInfoLong": "(Apocalypse):\nAs Pestilence, you're an unstoppable machine.\nAny attack towards you will be reflected towards them.\nIndirect kills don't even kill you.\n\nOnly way to kill Pestilence is by voting them out or the Pestilence misguessing.\nYour presence is announced to everyone at the meeting after you transform.", "SoulCollectorInfoLong": "(Apocalypse):\nAs Soul Collector, you can use your kill button on a player to predict their death. You will gain a soul if your target dies in the round you select them or the meeting after.\nYour target resets after each meeting or after they die, whichever comes first. \n\nOnce you collect the configurable amount of souls, you become Death. If the gain passive souls setting is enabled, you will gain a soul each meeting.", "DeathInfoLong": "(Apocalypse):\nOnce the Soul Collector has collected their needed souls, they become Death. Death kills everyone and wins if Death is not ejected by the end of the next meeting.\nA configurable amount of extra meeting time will be given on the meeting Death transforms to have more discussion to find Death.\n\nYou are invincible, and your presence is announced to everyone at the meeting after you transform.", - "BakerInfoLong": "(Apocalypse):\nAs the Baker, you can use your kill button on a player per round to give them bread. \nOnce a set amount of players are alive with bread, you become Famine.\n\nIf the Bread gives additional effects and the setting is on, then you can vent to change the bread that you give out. \nBread Effects:\nReveal: Reveals the target's role to the Baker (stays the whole game)\nRoleblock: Sets the target's kill cooldown to 999 (resets to normal after the meeting)\nBarrier: Gives the target a barrier that is only known to the Baker (barrier is removed after the meeting)", + "BakerInfoLong": "(Apocalypse):\nAs the Baker, you can use your kill button on a player per round to give them bread. \nOnce a set amount of players are alive with bread, you become Famine.\n\nIf the Bread gives additional effects and the setting is on, then you can vent to change the bread that you give out. \nBread Effects:\nReveal: Reveals the target's role to the Baker (stays the whole game)\nRoleblock: Resets the target's kill cooldown when they try to use their kill button\nBarrier: Gives the target a barrier that is only known to the Baker (barrier is removed after the meeting)", "FamineInfoLong": "(Apocalypse):\nOnce the Baker has a set amount of people with bread alive, they will become Famine. If the Famine does not get voted out after the meeting, then they will become Famine, and every player without bread will starve (excluding other Apocalypse members).\nAfter this starvation of everyone without bread, Famine can use their kill button to starve any remaining players, which will kill those players right before the next meeting.\n\nYou are invincible, and your presence is announced to everyone at the meeting after you transform.", "BerserkerInfoLong": "(Apocalypse):\nAs the Berserker, you level up with each kill.\nUpon reaching a certain level defined by the Host, you unlock a new power.\n\nScavenged kills make your kills disappear.\nBombed kills make your kills explode. Be careful when killing, as this can kill your other Apocalypse members if they are near. \nAfter a certain level, you become War.", "WarInfoLong": "(Apocalypse):\nAs War, you are invincible, have a lower kill cooldown, and can kill anyone with your previous powers.\nYour presence is announced to everyone at the meeting after you transform.", @@ -911,12 +899,11 @@ "TraitorInfoLong": "(Neutrals):\nAs the Traitor, you were an Impostor that betrayed the Impostors.\nYou know the Impostors, but they don't know you.\nThe twist? They can kill you, but you can't kill them.\n\nEliminate the Impostors by other means, then kill everyone else to win!", "TrollerInfoLong": "(Neutrals):\nAs a Troller, you can complete tasks so that random events can happen to players.\nFor example, changing the speed of all players, teleportation, influencing sabotage, etc.\nAlso you can win with the winning team.", "VultureInfoLong": "(Neutres):\nLe Vautour Dévore les Cadavres pour Gagner !\n\nLorsqu'il Signale un Cadavre, si son Rechargement pour Dévorer est écoulé, il Dévore le Cadavre (ce qui le rend non Signalable).\nSi sa Capacité à Dévorer est toujours en Rechargement, il Signale le Cadavre normalement.\nDe plus, il Signale les Cavares normalement si le nombre maximal de Cadavres Dévorés par Manche est atteint.", - "AbyssbringerInfoLong": "(Impostors):\nAs the Abyssbringer, you can place black holes. Black holes will suck in players and kill them when colliding with them.", "TaskinatorInfoLong": "(Neutrals):\nAs the Taskinator, whenever you finish a task, the task will be bombed. When another player completes the bombed task, the bomb will detonate, and the player will die.\n\nYou win if you survive till the end and Crew doesn't win.\n\n Note: Taskinator bombs ignore all protection.", "BenefactorInfoLong": "(Crewmates):\nAs the Benefactor, whenever you finish a task, that task will be marked. When another player completes the marked task, they get a temporary shield.\n\n Note: Shield only protects from direct kill attacks.", - "MedusaInfoLong": "(Neutres) :\nLa Méduse peut Pétrifier les Corps de la comme on Nettoie un Cadavre. Les Corps Pétrifiés ne peuvent pas être Signalés.\n\nElle doit Exécuter tout le monde pour Gagner.", + "MedusaInfoLong": "(Neutrals):\nAs the Medusa, you can stone bodies much like cleaning a body.\nStoned bodies cannot be reported.\n\nKill everyone to win.", "SpiritcallerInfoLong": "(Neutrals):\nAs the Spiritcaller, your victims become Evil Spirits after they die. These spirits can help you win by freezing other players briefly or blocking their vision. Alternatively, the spirits can give you a shield that protects you briefly from an attempted kill.", - "AmnesiacInfoLong": "(Neutrals):\nAs the Amnesiac, use your report button to remember a target and get its role.\nTo balance the game, you will not be able to vent after remembering your role if you can't vent as Amnesiac.'", + "AmnesiacInfoLong": "(Neutres):\nL'Amnésique utilise son Bouton de Signalement pour se Souvenir d'un Rôle.\n\nSi la Cible était un Imposteur, il devient un Réfugié.\nSi la Cible était un Coéquipié, il devient le Rôle de la Cible s'il est compatible (sinon vous deviendrez un Ingénieur).\nSi la Cible était un Neutre Passif ou un Neutre Exécuteur non spécifié, il devient le Rôle défini dans les Réglages.\nSi la Cible était un Neutre Exécuteur, il devient le Rôle qu'il été.", "ImitatorInfoLong": "(Neutrals):\nAs the Imitator, use your kill button to imitate a player.\n\nYou'll either become a Sheriff, a Refugee, or some Neutral.", "BanditInfoLong": "(Neutrals):\nAs the Bandit, you can click your kill button one time to steal a player's addon and twice to kill. Depending on the settings, you may instantly steal the addon or after the meeting starts. After the maximum number of steals is reached, you will kill normally. Additionally, if there are no stealable addons on the target or the target is stubborn, you will kill the target.\n\nKill everyone to win.\n\nNote: Cleansed, Last Impostor, and Lovers cannot be stolen.\nNote: If Bandit can vent is on, Nimble will become unstealable.", "DoppelgangerInfoLong": "(Neutrals):\nAs the Doppelganger, use your kill button to steal a player's identity (their name and skin) and then kill your target.\n\nKill everyone to win.\n\nNote: You cannot steal the target's identity when Camouflage is active.", @@ -925,19 +912,18 @@ "ShroudInfoLong": "(Neutres):\nLe Linceul n'Exécute pas normalement.\nA la place, il utilise son Bouton d'Exécution pour Posséder un joueur.\nUn joueur Possédé doit en Exécuter d'autres.\nSi le joueur Possédé n'Exécute pas, il se Suicidera après une Réunion.\n\nLe Linceul voit les joueurs Possédés avec une Marque 「◈」 à côté de leur nom.\nLes joueurs Possédés qui n'ont pas Exécuté auront également la Marque 「◈」 lors des Réunions, où ils Mourront si le Linceul est encore en Vie à la fin de la Réunion.", "WerewolfInfoLong": "(Neutres):\nLe Loup-Garou peut Exécuter comme n'importe quel Exécuteur.\nCependant, lorsqu'il Exécute, tous les joueurs à proximité Meurent également.\nTout joueur qui Meurt à cause de cela verra sa Mort justifiée par le fait qu'il a été Blessé.\n\nPour équilibrer cela, il a un Rechargement plus élevé que n'importe qui d'autre pour Exécuter.", "ShamanInfoLong": "(Neutrals):\nAs the Shaman, you can use your kill button to select a voodoo doll once per round. If the kill button is used on you, the effect will be deflected onto the voodoo doll.\nIf you survive until the end, you win with the winning team.\nNote: If the killer cannot kill the chosen target, murder is canceled, but if the killer rechecks the Shaman, the killer will kill the Shaman.", - "SeekerInfoLong": "(Neutrals):\nAs the seeker, use your kill button to tag the target. If the seeker tags the wrong player, a point is deducted, and if the seeker tags the correct player, a point will be added.\nAdditionally, the seeker will not be able to move for 5 seconds after every meeting and after getting a new target.\n\nThe seeker needs to collect a certain number of points set by the Host to win.", + "SeekerInfoLong": "(Neutrals):\nAs the seeker, use your kill button to tag the target. If the seeker tags the wrong player, a point is deducted, and if the seeker tags the correct player, a point will be added.\nAdditionally, the seeker will not be able to move for 5 seconds after every meeting and after getting a new target.\n\nThe seeker needs to collect a certain number of points set by the Host to win.\nSeeker will see a ★ mark on target's name.", "PixieInfoLong": "(Neutrals):\nAs the Pixie, Mark up to x amount of targets each round by using the kill button on them. You must have one of the marked targets ejected when the meeting starts. If unsuccessful, you will commit suicide, except if you didn't mark any targets or all the targets are dead. The selected targets reset to 0 after the meeting ends. If you succeed, you will gain a point. You see all your targets in colored names.\n\nYou win with the winning team when you have certain amounts of points set by the Host.", "SchrodingersCatInfoLong": "(Neutrals):\nAs Schrodingers Cat, if someone attempts to use the kill button on you, you will block the action and join their team. This blocking ability works only once. By default, you don't have a victory condition, meaning you win only after switching teams.\nIn Addition to this, you will be counted as nothing in the game.\n\nNote: If the killing machine attempts to use its kill button on you, the interaction is not blocked, and you will die.", "RomanticInfoLong": "(Neutrals):\nThe Romantic can pick their lover partner using their kill button (this can be done at any point of the game). Once they've picked their partner, they can use their kill button to give their partner a temporary shield that protects them from attacks. If their lover partner dies, the Romantic's role will change according to the following conditions:\n1. If their partner was an Impostor, the Romantic becomes the Refugee\n2. If their partner was a Neutral Killer, then they become Ruthless Romantic.\n3. If their partner was a Crewmate or a non-killing neutral, the Romantic becomes the Vengeful Romantic. \n\nThe Romantic wins with the winning team if their partner wins.\nNote: If your role changes, your win condition will be changed accordingly", "RuthlessRomanticInfoLong": "(Neutrals):\nYou change your roles from Romantic if your partner (A neutral killer) is killed. As a Ruthless Romantic, you win if you kill everyone and are the last one standing. If you win, your dead partner will also win with you.", "VengefulRomanticInfoLong": "(Neutrals):\nYou change your roles from Romantic if your partner (A crew or non-neutral killer) is killed. As a Vengeful Romantic, your goal is to avenge your partner, which means you must kill the killer of your partner. If you succeed, then you and your partner win with the winning team at the end. If you try to kill someone other than your partner's killer, then you will die by misfire.", - "PoisonerInfoLong": "(Neutres):\nL'Empoisonneur a ses Exécutions retardées.\nIl Exécute tout le monde pour Gagner.", - "HexMasterInfoLong": "(Neutres):\nLe Mage peut Ensorceler les joueurs ou les Exécuter.\nEnsorceler un joueur fonctionne de la même manière qu'avec la Sorcière.", + "PoisonerInfoLong": "(Neutrals):\nAs the Poisoner, your kills are delayed.\nKill everyone to win.", + "HexMasterInfoLong": "(Neutrals):\nAs the Hex Master, you can hex players or kill them.\nHexing a player works the same as spelling as a Witch.", "WraithInfoLong": "(Neutrals):\nAs the Wraith, you can vent to Vanish temporarily. You will still appear visible on your screen. Vent again to become visible. You win if you are the last player remaining.", "JinxInfoLong": "(Neutrals):\nAs the Jinx, whenever you get attacked, you jinx them, resulting in them dying to a jinx.\nThis has limited uses.\n\nKill off everyone to win.", "PotionMasterInfoLong": "(Neutrals):\nAs the Potion Master, you have three different potions assigned to three different actions.\n\nSingle click: Reveal role\nDouble click: Kill\nMap: Sabotage\n\nThe reveal potion has a limit.\nWhen you run out, the kill buttons default to killing.", "NecromancerInfoLong": "(Neutrals):\nAs the Necromancer, you win when you're the last one standing.\nAdditionally when someone tries to kill you, you will block the kill, and you will teleport to a random vent. You will have a limited time to kill your killer. If you succeed in doing so, you live. If the time runs out before you kill your killer, you die permanently. If you try to kill someone else other than your killer, you will die.", - "ShockerInfoLong": "(Neutrals):\nAs the Shocker, you can mark rooms by doing tasks in them, and then vent to Electrocute anyone in those rooms for a set period of time. When you finish all of your tasks, you get new ones. Note: Doing tasks during that period will mark them for the next ability use.", "LastImpostorInfoLong": "(Add-ons):\nThis special effect is given to the last surviving Impostor. It significantly reduces their kill cooldown.", "OverclockedInfoLong": "(Add-ons):\nAs the Overclocked, your kill cooldown is reduced by a percentage.\n\nThis feature is only assigned to roles with a kill button.", "LoversInfoLong": "(Add-ons):\nLovers are a combination of two players. The Lovers win when they are the last ones standing, and their victory is shared. When one of the Lovers wins, the other also wins together. Lovers can see the 「♥」 next to each other's name. If one of the Lovers dies, the other will die in love (may not die in love according to the Host's settings). When one of the Lovers is exiled in the meeting, the other will die and become a dead body that cannot be reported.", @@ -958,7 +944,7 @@ "ParanoiaInfoLong": "(Modifieurs):\\nN'est pas assigné aux Neutres et aux Complices.\\nEn tant que Paranoïaque, vous serez considéré comme étant deux joueurs, par exemple si les imposteurs ont la majorité (2v2) mais que vous êtes en vie, la partie continue. De plus, cela vous donne 1 vote de plus, si l'option est activée par l'hôte.", "MimicInfoLong": "(Add-ons):\nOnly Impostor can become Mimic. When the Mimic is dead, other Impostors will receive a message once a meeting is called. This message will include information on roles which the Mimic killed.", "GuesserInfoLong": "(Add-ons):\nAs a guesser, guess the roles of players in meetings to kill them.\nGuessing the incorrect role kills you instead.\nThe guessing command is: /bt [player id] [role]\nYou can see the player's id before the player's name or use the /id command to view the id of all players.", - "NecroviewInfoLong": "(Modifieurs):\nLa Nécrovision permet de voir les Équipes des joueurs Morts. Les informations suivantes seront affichées sur le Nom du joueur Mort lors d'une Réunion :\n- Le Nom Rouge indique les Imposteurs.\n- Le Nom Cyan indique les Coéquipiers.\n- Le Nom Gris indique les Neutres.", + "NecroviewInfoLong": "(Add-ons):\nThe Necroview can see the teams of dead players. The following info will be displayed on the dead player's name while in a meeting:\n- The Red name indicates the Impostors.\n- The Cyan name indicates the Crewmates.\n- The Gray name indicates the Neutrals.", "ReachInfoLong": "(Add-on)\nOnly roles with a kill button can get this add-on. Unlike everyone else, you have the longest kill range possible in the game.", "BaitInfoLong": "(Add-ons):\nWhen the Bait dies, the murderer who killed the Bait will self-report the Bait's body. However, this won't happen when a Scavenger, Cleaner, Swooper, Wraith, Medusa, or Killing Machine kills the Bait. The report may have a delay according to the Host's settings.", "TrapperInfoLong": "(Add-ons):\nWhen Beartrap dies, Beartrap immobilizes killer for a configurable amount of time.", @@ -981,7 +967,7 @@ "RebirthInfoLong": "(Add-ons):\nAs the Rebirth, if you're the player about to be ejected, you will swap skins with a random crewmate who voted for you.\nNotice: The host vote never counts\nRebirth will be removed from you if you exhausted all your rebirths.", "LoyalInfoLong": "(Modifieurs):\nLe Loyal ne peut pas être Recruté par des Rôles tels que le Chacal ou le Gourou.\n\nIl ne peut pas être assigné aux Neutres.", "EvilSpiritInfoLong": "(Add-ons):\nAs Evil Spirit, it's your job to help the Spiritcaller to victory. You can use your Haunt button to freeze players and reduce their vision. Alternatively, you can use your Haunt button to give the Spiritcaller a shield against a kill attempt temporarily.", - "RecruitInfoLong": "(Betrayal Add-ons):\nAs a recruit, you are on the Jackal's team and help out the Jackal and their Sidekicks.\nYou cannot win with your original team.\nDepending on the settings, you may turn into Jackal if old Jackal was killed and no sidekicks is alive.", + "RecruitInfoLong": "(Modifieurs de Trahison):\nLa Recrue fait partie de l'Équipe du Chacal et il aide le Chacal et ses Acolytes.\nIl ne peut pas gagner avec son Équipe d'Origine.", "AdmiredInfoLong": "(Modifieurs de Trahison):\nL'Admiré Gagne avec l'Équipage et non avec son Équipe d'origine.\n\nIl peut voir l'Admirateur.", "GlowInfoLong": "(Modifieurs):\nLe Luisant et les joueurs proches auront leur Vision Augmentée pendant les Sabotages des Lumières.", "RadarInfoLong": "(Modifieurs):\\nEn tant que Sondeur, vous avez une flèche pointant vers la personne la plus proche tout le temps.", @@ -1025,7 +1011,6 @@ "ProhibitedInfoLong": "(Add-ons):\nAs the Prohibited, you have specific vents that you can't use.\nHow many vents are disabled depends on the Host's settings.", "EavesdropperInfoLong": "(Add-ons):\nAs the Eavesdropper, you have a chance to read other role/addon information-based messages like Mortician or Sleuth.", "ApocalypseInfoLong": "(Apocalypse):\nApocalypse members are on a separate team that works together and wins together. If there are multiple Apocalypse roles in the game, they can see each other's roles.\nDepending on the Host's settings, Apocalypse roles can guess or be guessed.", - "RevenantInfoLong": "(Neutral):\nAs the Revenant, your goal is to be killed. If you are killed, you will take your killer's role and kill your killer instead. You cannot win before being killed.\nNote that Revenant only works when being directly killed.", "ShowTextOverlay": "Texte de la Surcouche", "Overlay.GuesserMode": "Mode Devin", "Overlay.NoGameEnd": "Pas de fin de Partie", @@ -1039,8 +1024,6 @@ "AbilityUseLimit": "Limite d'utilisation initiale de la Capacité", "AbilityInUse": "Ability in use", "AbilityExpired": "Ability expired, {0} uses remain", - "RevenantTargeted": "Your role has changed to {0}", - "RevenantCanCopyAddons": "Can Steal Addons", "ShowArrows": "A des Flèches pointant vers les Cadavres", "ArrowDelayMin": "Délai minimal d'Apparition des Flèches", "ArrowDelayMax": "Délai maximal d'Apparition des Flèches", @@ -1370,8 +1353,6 @@ "ShieldedCanUseKillButton": "Shielded player can use ability / kill button", "PlayerIsShieldedByGame": "Player is protected by the game!", "LegacyNemesis": "Utiliser l'Ancienne Version", - "LegacyParasite": "Use Legacy Version", - "LegacyTraitor": "Use Legacy Version", "ArsonistKeepsGameGoing": "L'Incendiaire fait continuer la Partie", "ArsonistCanIgniteAnytime": "Peut Incendier à tout moment", "ArsonistMinPlayersToIgnite": "Nombre minimal d'Aspergés nécessaires pour Incendier", @@ -1514,18 +1495,6 @@ "SheriffCanKillSeparately": "Réglages Individuels", "In%team%": "(Équipe %team%)", "SheriffMisfireKillsTarget": "Un Tir-Raté Exécute la Cible", - "BlackHolePlaceCooldown": "Black Hole Place Cooldown", - "BlackHoleDespawnMode": "Black Hole Despawn Mode", - "BlackHoleDespawnTime": "Time After Black Hole Despawns", - "Abyssbringer.Suffix": "<#00ffa5>Number of players consumed by {0} <#00ffa5>active black holes:\\n{1}", - "Abyssbringer.Suffix.BlackHole": "<#00ffa5>{0}: {1}", - "BlackHoleMovesTowardsNearestPlayer": "Black Hole Moves Towards Nearest Player", - "BlackHoleMoveSpeed": "Black Hole Moving Speed", - "BlackHoleRadius": "Black Hole Consuming Radius", - "AfterTime": "After Time", - "After1PlayerEaten": "After 1 Player Was Eaten", - "AfterMeeting": "After Meeting", - "None": "None", "SheriffShotLimit": "Nombre maximal d'Exécutions", "SheriffCanKillAllAlive": "Peut Exécuter quand personne n'est Mort", "SheriffCanKillCharmed": "Peut Exécuter les joueurs Charmés", @@ -1542,15 +1511,12 @@ "RebirthUses": "Amount of Rebirths", "RebirthCountVotes": "Only rebirth to players who voted for them", "RebirthFailed": "Ahh, how unfortunate, you did not find any viable souls to swap bodies with", - "FireworkerCooldown": "Placement Cooldown", "ReverieIncreaseKillCooldown": "Augmenter le Rechargement d'Exécution", "ReverieMaxKillCooldown": "Rechargement d'Exécution maximal", "ReverieMisfireSuicide": "Tir-Raté en atteignant le Rechargement maximal d'Exécution", "ReverieResetCooldownMeeting": "Réinitialiser le Rechargement d'Exécution après la Réunion", "ConvertedReverieKillAll": "Le Rêveur Recruté peut Exécuter n'importe qui sans répercutions", "VigilanteNotify": "Tu es devenu la chose même que tu as juré de détruire", - "DictatorChangeCommandToExpel": "Dictator use Command to expell instad of vote", - "DictatorExpelSelf": "WAIT WAIT WAIT WAT THE HELLLLLL Bro really just want to expel himself", "DoctorTaskCompletedBatteryCharge": "Durée de la Batterie", "SnitchEnableTargetArrow": "Voir la Flèche vers la Cible", "SnitchCanGetArrowColor": "Voir les Flèches Colorées en fonction des Couleurs de l'Équipe", @@ -1624,6 +1590,7 @@ "TimeThiefDecreaseMeetingTime": "Réduire la Durée de la Réunion de", "TimeThiefLowerLimitVotingTime": "Temps de vote minimum", "TimeThiefReturnStolenTimeUponDeath": "Restituer le temps Volé à la Mort", + "TimeThiefMaxTimeOnAdmired": "Maximum Meeting Time if Time Thief Is Admired", "EvilTrackerCanSeeKillFlash": "Peut voir l'Alerte d'Exécution", "EvilTrackerCanSeeLastRoomInMeeting": "Peut voir la dernière pièce de sa Cible lors de la Réunion", "EvilTrackerTargetMode": "Peut définir sa Cible", @@ -1631,7 +1598,6 @@ "EvilTrackerTargetMode.OnceInGame": "Une fois par partie", "EvilTrackerTargetMode.EveryMeeting": "À chaque Réunion", "EvilTrackerTargetMode.Always": "À tout moment", - "ScavengerHasCustomDeathReason": "Enable Custom Death Reason", "EvilHackerCanSeeDeadMark": "Peut voir la localisation des cadavres", "EvilHackerCanSeeImpostorMark": "Peut localiser les autres imposteurs", "EvilHackerCanSeeKillFlash": "Peut voir l'Alerte d'Exécution", @@ -1864,21 +1830,13 @@ "Jackal_SidekickCountMode_Jackal": "Chacal", "Jackal_SidekickCountMode_Original": "Équipe d'Origine", "Jackal_SidekickAssignMode": "Mode d'Assignation des Acolytes", - "Jackal_SidekickAssignMode_SidekickAndRecruit": "Sidekick when failed Recruit", - "Jackal_SidekickAssignMode_Sidekick": "Only Sidekick", - "Jackal_SidekickAssignMode_Recruit": "Only Recruit", + "Jackal_SidekickAssignMode_SidekickAndRecruit": "Acolytes+Recrue", + "Jackal_SidekickAssignMode_Sidekick": "Acolyte Uniquement", + "Jackal_SidekickAssignMode_Recruit": "Recrue Uniquement", + "JackalWinWithSidekick": "Le Chacal peut gagner avec l'équipe de l'Acolyte", "Jackal_SidekickCanKillSidekick": "Les Acolytes peuvent Exécuter d'autres Acolytes", "Jackal_SidekickCanKillJackal": "Les Acolytes peuvent Exécuter le Chacal", - "Jackal_RecruitFailed": "You can not recruit this player!", "JackalCanKillSidekick": "Le Chacal peut Exécuter les Acolytes", - "Jackal_SidekickCanKillWhenJackalAlive": "Sidekick can kill while Jackal is Alive", - "Jackal_SidekickTurnIntoJackal": "Sidekick can turn into Jackal after its death", - "Jackal_RestoreLimitOnNewJackal": "Restore Recruit limit when Sidekick become new Jackal", - "Jackal_OnBecomeNewJackalMeeting": "The old Jackal {0} is dead.\nYou are selected as new Jackal\nWork together and win the game!", - "Jackal_OnNewJackalSelectedMeeting": "The old Jackal {0} is dead.\n{1} is selected as new Jackal!\nWork together and win the game!", - "Jackal_BecomeNewJackal": "Old Jackal Dead, You are now new Jackal!", - "Jackal_OnNewJackalSelected": "Old Jackal Dead, Please help new Jackal {0} for now!", - "Jackal_BossIsDead": "Opps, the Jackal boss is dead!", "CoronerArrowsPointingToDeadBody": "Flèches pointant vers des Cadavres", "CoronerLeaveDeadBodyUnreportable": "Les Cadavres que le Légiste utilise ne peuvent pas être Signalés", "CoronerInformKillerBeingTracked": "Informer l'Exécuteur qu'il est Suivi", @@ -1916,9 +1874,6 @@ "VipTag": "VIP★", "ApplyVipList": "Appliquer la Liste VIP", "AllowSayCommand": "Autoriser les Modérateurs à utiliser la commande /say", - "AllowStartCommand": "Allow moderators to use /start command", - "StartCommandMinCountdown": "Minimum countdown for /start command", - "StartCommandMaxCountdown": "Maximum countdown for /start command", "KickCommandDisabled": "La commande d'Exclusion est actuellement désactivée.", "KickCommandNoAccess": "Tu n'as pas accès à la commande d'Exclusion.", "KickCommandInvalidID": "L'ID du joueur spécifié n'est pas valide.\nS'il te plaît utilise '/kick [ID du Joueur] [raison]' pour Exclure un joueur.\nExemple :- /kick 5 ne respecte pas les règles", @@ -1951,11 +1906,6 @@ "WarnCommandNoAccess": "Tu n'as pas accès à la commande warn.", "WarnCommandInvalidID": "ID du joueur sélectionné Invalide.\nS'il te plaît utilise '/warn [ID du joueur] [Raison]' pour avertir un joueur.\nExemple :- /warn 5 parle pendant l'éjection", "WarnCommandWarnHost": "Tu n'es pas autorisé à avertir l'Hôte.", - "StartCommandNoAccess": "You do not have access to the start command.", - "StartCommandDisabled": "The start command is currently disabled.", - "StartCommandCountdown": "ERROR\n\nThe game is already starting!", - "StartCommandStarted": "The game has been started by {0}!", - "StartCommandInvalidCountdown": "ERROR\n\nThe countdown must be between {0} and {1}!", "WarnCommandWarnMod": "Tu n'es pas autorisé à avertir les autres Modérateurs.", "WarnCommandWarned": "a été averti. Il n'y aura pas d'autres avertissements et des mesures appropriées seront prises \n ", "WarnExample": "Utilise /warn [ID du Joueur] [Raison] à l'avenir.\nExemple :\n/warn 5 parle pendant l'Éjection", @@ -1983,7 +1933,6 @@ "DeathReason.Quantization": "Quantification", "DeathReason.Overtired": "A bout de Nerfs", "DeathReason.Ashamed": "Honteux", - "DeathReason.Consumed": "Consumed", "DeathReason.PissedOff": "Détruit", "DeathReason.Dismembered": "Démembré", "DeathReason.LossOfHead": "Étranglé", @@ -2007,8 +1956,6 @@ "DeathReason.Starved": "Starved", "DeathReason.Equilibrium": "Equilibrium", "DeathReason.Sacrificed": "Sacrificed", - "DeathReason.Electrocuted": "Electrocuted", - "DeathReason.Scavenged": "Scavenged", "OnlyEnabledDeathReasons": "Active uniquement les Raisons de la Mort", "Alive": "Vivant", "Disconnected": "Disconnected", @@ -2024,10 +1971,11 @@ "DeputyHandcuffCooldown": "Rechargement pour Menotter", "DeputyHandcuffMax": "Nombre maximal de Menottes", "DeputyHandcuffedPlayer": "Cible Menottée", - "HandcuffedByDeputy": "Tu as été Menotté !", - "DeputyInvalidTarget": "La Cible ne peut pas être Menottée", + "HandcuffedByDeputy": "You were handcuffed!\nNow you have broken your handcuff and can kill again.", + "DeputyInvalidTarget": "Target is already handcuffed", + "HandcuffBrokenAfterMeeting": "Remove all handcuffs after meeting", "DeputyHandcuffText": "Menotter", - "DeputyHandcuffCDForTarget": "Rechargement d'Exécution pour Menotter un joueur", + "DeputyHandcuffCDForTarget": "Next Kill Cooldown for handcuffed player", "RejectShapeshift.AbilityWasUsed": "La Capacité a été utilisée", "EscapisMtarkedPosition": "You marked self-position", "InvestigateCooldown": "Rechargement d'Enquête", @@ -2074,7 +2022,6 @@ "Command.dump": "→ Inscrit le Journal de Bord sur le Bureau", "Command.death": "→ Affiche l'information sur la façon dont tu es Mort", "Command.icons": "
╳ - The Player was marked by the Blackmailer and can't talk during the Meeting
☆ - Used by Captain to display themselves. Only Crewmates can see the Captain's star
乂 - This player was hexed by the Hex Master and will die if the Hex Master isn't killed or ejected by the end of the Meeting.
♦ - Used by Lawyer or Executioner or Follower.
♥ - Used by Lovers or Romantic.
✚ - Used by Medic to mark their target.
⦿ - This player is in a duel with the Pirate.
!? - This player was marked by the Quizmaster and must answer the question correctly to survive.
☜ - Used by Schrödinger's cat to mark their teammate.
◈ - This player marked by the Shroud and will die if the Shroud is not killed or ejected by the end of the meeting.
⚠ - This player is a Snitch or Solsticer who has finished their tasks.
★ - Used by Super Star or Cyber or Marshall.
† - This player was spelled and will die if the Witch is not killed by the end of the meeting.
∇ - Used by Kamikaze to mark their targets.
■ - Used by Lightning to mark their quantum ghosts.
⊠ - Used by Jailer to mark their prisoner.
● - Used by Baker to mark who has Bread.
♠ - Used by Soul Collector to mark who's death they're predicting.
⦿ - Used by Plaguebearer to mark who they have plagued.", - "Command.start": "[Seconds] → Start the game", "Command.iconinfo": "→ Affiche les informations sur les Icônes de Réunion", "Command.iconhelp": "→ Affiche les informations sur les Icônes de Réunion pour tout le monde", "Command.Poll": "→ Start a poll with up-to 5 choices", @@ -2087,7 +2034,6 @@ "ShowMadmatesInLeftCommand": "Show Madmates (including add-ons)", "ShowApocalypseInLeftCommand": "Show Neutral Apocalypse", "SeeEjectedRolesInMeeting": "Voir les Rôles Éjectés dans les Réunions", - "ThankYouForUsingTOHE": "Thank you for using TOHE!", "SkillUsedLeft": "Tu as activé ta Capacité pour convoquer une Réunion. \nNombre d'utilisations restantes :", "NemesisDeadMsg": "La mort de la Némésis signifie le début de la vengeance. \nS'il te plaît utilise /rv + [ID joueur] pour exécuter le joueur spécifié \nTu peux voir les ID joueurs devant leurs noms. \nOu tape /rv pour obtenir la liste des ID des joueurs", "NemesisAliveKill": "La vengeance de la Némésis ne peut commencer qu'après sa mort.", @@ -2107,7 +2053,6 @@ "GuessNotifiedBait": "Bait can't be guessed because it was announced. You thought it would be that easy, right?", "GuessGM": "Deviner le MJ est impossible car il est déjà Mort.... Et pourquoi faire ça au pauvre Hôte ?", "GuessGuardianTask": "Tu ne peux pas Deviner un Gardien qui a terminé ses Tâches.", - "GuardianCantKilled": "You can't kill a Guardian who has finished their tasks.", "GuessMarshallTask": "Tu ne peux pas Deviner un Maréchal qui a terminé ses Tâches.", "GuessObviousAddon": "Désolé, les Modifieurs évidents ne peuvent pas être Devinés.\nAprès tout, ce serait injuste pour celui que tu allais Deviner !", "GuessAdtRole": "Malheureusement, les Réglages de l'Hôte ne permettent pas de Deviner les Modifieurs.", @@ -2163,7 +2108,6 @@ "BecomeMadmateCuzMadmateMode": "Tu es devenu Complice parce que tu es Mort", "CleanerCleanBody": "Le Cadavre a été Nettoyé", "QuickShooterStoraging": "Les Balles ont bien été Emmagasinées", - "QuickShooterFailed": "You are still in cooldown.", "PoisonerTargetDead": "La Cible est Morte", "HexesLookLikeSpells": "Ensorcèlements apparaissent comme Malédictions", "HexButtonText": "Ensorceler", @@ -2322,7 +2266,6 @@ "Message.YTPlanNotice": "Note: The [YouTuber Plan] is enabled in this lobby, which means the Host can specify their role in the next game to make it easier to get content. If the Host abuses this feature, please exit the game or report it.\nCurrent Creator Credentials:", "Message.OnlyCanBeUsedByHost": "ERREUR\n\nCette commande ne peut être utilisée que par l'Hôte.", "Message.MaxPlayers": "Le nombre maximal de Joueurs est fixé à ", - "Message.MaxPlayersFailByRegion": "Could not set max players: Vanilla regions support a maximum of 15 players.", "Message.GhostRoleInfo": "Ghost Role Info\nHiya! A little about ghost roles...\n\nGhost roles drastically impact the game, so it's not recommended for smaller lobbies if you're unfamiliar. If not explicitly stated otherwise in the description, the Guard button is their ability button ;)\n\nSpawning:\nGhost-roles only spawn after death; the first x people from (team) to die get them.\n\nPS: If your previous role didn't have tasks(e.g., sheriff), your tasks as a ghost-role aren't needed for task-win", "ApocalypseInfoTitle": "Neutral Apocalypse Info:", "Message.ApocalypseInfo": "Every role of the <#ff174f>Apocalypse Team has their own objective to carry out in order to transform.\n<#2B0804>Transformed <#ff174f>Apocalypse members have a drastic change on the game and are immortal (except for being voted), but everyone will be notified that they have transformed.\n\nRoles: <#e5f6b4>Plaguebearer, <#A675A1>Soul Collector, <#bf9f7a>Baker, <#cc0044>Berserker\nTransformed: <#343136>Pestilence, <#644661>Death, <#83461c>Famine, <#2B0804>War\n\nApocalypse members can see eachother's roles and ability icons.\nLike Neutral Killers, Apocalypse members keep the game going as well, have fun!", @@ -2454,6 +2397,7 @@ "LastResult": "★ Résultats de la Partie", "LastEndReason": "★ Raison de la Fin", "KillLog": "Journal d'Exécution", + "MainRoleLog": "Role Convert Log", "Maximum": "Maximum", "RoleRate": "ACTIVÉ", "RoleOn": "TOUJOURS", @@ -2640,7 +2584,7 @@ "NeutralRemain": "\n{0} Neutres Exécuteurs restants", "OneNeutralRemain": "\n{0} Neutre Exécuteur restant", "ApocRemain": "\n{0} Neutral Apocalypse remains", - "GameOverReason.HumansByVote": "Tous les Imposteurs et les Neutres Exécuteurs ont été Éjectés ou Exécutés", + "GameOverReason.HumansByVote": "All Impostors and Neutral Killers were ejected or killed", "GameOverReason.HumansByTask": "Les Coéquipiers ont Accompli toutes les Tâches", "GameOverReason.HumansDisconnect": "Les Coéquipiers se sont Déconnectés", "GameOverReason.ImpostorByVote": "Les Coéquipiers ont été Éjectés", @@ -2730,9 +2674,8 @@ "DeathMeetingTimeIncrease": "Increased Meeting time when Death exists", "SoulCollectorMeetingDeath": "Your target has died during the meeting. You have gained a soul.", "SoulCollectorKillButtonText": "Predict", - "SoulCollectorHasImpostorVision": "Soul Collector has Impostor vision", "ApocalypseIsNigh": "[ The Apocalypse Is Nigh! ]", - "ApocalypseImmune": "This role is immune!", + "ApocalypseImmune": "This player is immune because they are invincible!", "BakerToFamine": "You have become Famine!!!", "BakerTransform": "The Baker has transformed into Famine, Horseman of the Apocalypse! A famine has begun!", "BakerAlreadyBreaded": "That player already has bread!", @@ -2741,15 +2684,13 @@ "BakerBreadNeededToTransform": "Required number of bread to become Famine", "BakerCantBreadApoc": "You cannot give other Apocalypse members bread!", "BakerKillButtonText": "Bread", - "BakerUnshiftButtonText": "Switch Bread", "BakerRevealBread": "Reveal", "BakerRoleblockBread": "Roleblock", "BakerBarrierBread": "Barrier", "BakerCurrentBread": "Current Bread: ", "BakerSwitchBread": "Bread Switched to: ", - "BakerCanVent": "Baker can Vent", + "BakerCanVent": "Baker can Vent", "BakerBreadGivesEffects": "Bread gives additional effects", - "BakerTransformNoMoreBread": "Baker transforms if they do not have enough bread", "FamineKillButtonText": "Starve", "FamineStarveCooldown": "Famine starve cooldown", "FamineCantStarveApoc": "You cannot starve other Apocalypse members!", @@ -2796,7 +2737,6 @@ "GodfatherTargetCountMode": "L'Exécuteur se transforme en", "GodfatherCount_Refugee": "Réfugié", "GodfatherCount_Madmate": "Complice", - "GodfatherRefugeeMsg": "You have been recruited by GodFather!", "MissChance": "Chance To Miss", "IncreaseByOneIfConvert": "Increase The KillCount +1 If a Crew Is Converted", "HawkMissed": "Raté !", @@ -2829,7 +2769,6 @@ "BerserkerToWar": "You have become War!!!", "BerserkerTransform": "The Berserker has transformed into War, Horseman of the Apocalypse! Cry 'Havoc!', and let slip the dogs of war.", "WarKillCooldown": "War kill cooldown", - "BerserkerCanKillTeamate": "Can kill other Neutral Apocalypse", "BlackmailerSkillCooldown": "Rechargement du Chantage", "BlackmailerMax": "Nombre maximal de fois où les joueurs soumis au Chantage peuvent Parler", "BlackmailerDead": "Attention ! {0} a été victime d'un Chantage de la part d'un Maître Chanteur !", @@ -2919,8 +2858,6 @@ "RememberedPursuer": "Tu t'es Souvenu que tu étais un Poursuivant !", "RememberedFollower": "Tu t'es Souvenu que tu étais un Adulateur !", "RememberedAmnesiac": "Tu n'as pas réussi à te Souvenir de ton Rôle.", - "AmnesiacRemembered": "You remembered you were {0}!", - "ReportWhenFailedRemember": "Report Dead Body when failed to remember", "RememberedImitator": "Tu t'es Souvenu que tu étais un Imitateur.", "RememberedImpostor": "Tu t'es Souvenu que tu étais un Imposteur !", "RememberedCrewmate": "Tu t'es Souvenu que tu étais un Coéquipier !", @@ -2941,7 +2878,7 @@ "BanditStealCooldown": "Rechargement de Vole", "DoppelMaxSteals": "Nombre maximal de Vols", "DoppelCurrentVictimCanSeeRolesAsDead": "Last victim can see role and add-on info of alive players as a ghost", - "NecromancerRevengeTime": "Durée de la Nécromancie", + "NecromancerRevengeTime": "Necromancy time", "NecromancerRevenge": "Tu as {0}s pour Exécuter {1}", "NecromancerSuccess": "Nécromancie Accomplie ! Tu Vivras un jour de plus.", "NecromancerHide": "L'Évacuation est désactivée, cache-toi du Nécromancien !", @@ -3146,7 +3083,7 @@ "DollMaster_PossessedTarget": "Cible possédée", "DollMaster_CannotPossessImpTeammate": "Impossible de posséder votre partenaire", "DollMaster_CouldNotSwapWithTarget": "Impossible de posséder ce joueur", - "DollMaster_CanNotSwapWithDeadTarget": "Posséder un joueur mort est impossible", + "DollMaster_CanNotSwapWithDeadTarget": "Possessing a dead player isn't possible", "DollMaster_MainBody": "Acteur principal", "DollMaster_Doll": "Scénarisez", "DollMaster_UnableToUseAbility": "Impossible d'utiliser votre habilité sur ce joueur", @@ -3164,7 +3101,7 @@ "PitfallTrapCauseVisionTime": "Durée de la Vision affectée par le Piège", "PitfallTrap": "Tu es Tombé dans un Piège !", "ConsigliereDivinationMaxCount": "Nombre maximal de Révélations", - "RitualMaxCount": "Révélations maximales", + "RitualMaxCount": "Maximum Reveals", "CleanserHideVote": "Cacher le Vote du Purificateur", "OracleSkillLimit": "Nombre maximal d'Utilisations", "OracleHideVote": "Cacher le Vote de l'Oracle", @@ -3334,12 +3271,9 @@ "PixieTargetAlreadySelected": "La Cible a déjà été choisie", "PixieButtonText": "Marquer", "PlagueBearerCooldown": "Rechargement d'Empestation", - "PlagueBearerCanVent": "Can vent", - "PlagueBearerHasImpostorVision": "Has Impostor vision", "PestilenceCooldown": "Rechargement d'Exécution de la Peste", "PestilenceCanVent": "La Peste peut Évacuer", "PestilenceHasImpostorVision": "La Peste a une Vision d'Imposteur", - "PestilenceKillGuessers": "Kill players who guess Pestilence", "PlagueBearerAlreadyPlagued": "Le joueur est déjà Empesté", "PlagueBearerToPestilence": "Tu t'es transformé en Épidémie !", "GuessPestilence": "Tu viens d'essayer de Deviner la Peste ! Désolé, la Peste t'a Exécuté.", @@ -3383,7 +3317,6 @@ "EveryoneCanKnowMini": "Tout le monde peut voir le Gamin", "CanBeEvil": "Le Gamin peut être Imposteur", "EvilMiniSpawnChances": "Probabilité que le Gamin soit Imposteur", - "EvilMiniCanBeGuessed": "Evil Mini can be guessed before 18", "GuessMini": "Ce n'est pas très sympa de ta part de vouloir buter un Gamin comme ça !", "GrowUpDuration": "Temps nécessaire pour Grandir (s)", "MajorCooldown": "Rechargement d'Exécution pour les plus de 18 ans", @@ -3525,7 +3458,6 @@ "WinnerRoleText.Doppelganger": "L'Alter Ego Gagne !", "WinnerRoleText.Quizmaster": "Quizmaster Wins!", "WinnerRoleText.Agitater": "Agitator Wins!", - "WinnerRoleText.Shocker": "Shocker Wins!", "AdditionalWinnerRoleText.Sidekick": "Acolyte", "AdditionalWinnerRoleText.Taskinator": "Tâcheron", "AdditionalWinnerRoleText.Opportunist": "Opportuniste", @@ -3611,7 +3543,7 @@ "SolsticerOnMeeting": "Tu as été témoin de trop de Morts ! Au prochain tour, tu auras {0} Tâches courtes supplémentaires !", "SolsticerTitle": "Solsticien", "GuessSolsticer": "Désolé, mais tu ne peux pas Deviner le Solsticen !", - "ExpelSolsticer": "Sorry, but you can not expel Solsticer!", + "VoteSolsticer": "Désolé, mais tu ne peux pas Voter le Solsticien !", "SolsticerTasksReset": "Tes Tâches ont été réinitialisées !", "SolsticerMisGuessed": "Tu viens juste de mal Deviner ! Tu n'as plus le droit de Deviner.", "SolsticerGuessMax": "Parce que tu as déjà mal Deviné, tu n’es plus autorisé à Deviner.", @@ -3712,19 +3644,6 @@ "MinionAbilityTime": "Durée de la Capacité", "Minion_Blind": "blinded", "Evader_ChanceNotExiled": "Chance not be exiled", - "ShockerAbilityCooldown": "Ability Cooldown", - "ShockerAbilityDuration": "Ability Duration", - "ShockerAbilityPerRound": "Abilities Per Round", - "ShockerShockInVents": "Shock people in vents", - "ShockerAbilityResetAfterMeeting": "Reset marked rooms after meeting", - "ShockerOutsideRadius": "Radius Of Outside Tasks (not in a room)", - "ShockerCanShockHimself": "Can Shock Himself", - "ShockerImpostorVision": "Shocker has Impostor vision", - "ShockerIsShocking": "You're already shocking!", - "ShockerAbilityActivate": "Begin Shocking!", - "ShockerAbilityDeactivate": "Ability Deactivated", - "ShockerVentButtonText": "Shock", - "ShockerRoomMarked": "Marked Room", "EavesdropperMsgTitle": "You found a secret", "EavesdropPercentChance": "Chance to eavesdrop", "ChiefOfPoliceSkillCooldown": "Cooldown for recruiting sheriffs", @@ -3736,4 +3655,4 @@ "PolicPreventRecruitNonKiller": "Prevent recruit players without kill button", "PolicSuidiceWhenTargetNotKiller": "Suidices when recruit a non killer or non crewmate", "PolicPassConverted": "Can pass Converted Addon to Sheriff" -} +} \ No newline at end of file diff --git a/Resources/Lang/it_IT.json b/Resources/Lang/it_IT.json index 3cd332288..c840dc1d3 100644 --- a/Resources/Lang/it_IT.json +++ b/Resources/Lang/it_IT.json @@ -20,8 +20,6 @@ "SubText.Neutral": "Lavora da solo per ottenere la tua vittoria", "SubText.Apocalypse": "Diventa inarrestabile con la tua squadra", "SubText.Madmate": "Aiuta gli Impostori", - "SubText.Lovers": "Rimani in vita e vincete insieme", - "SubText.Egoist": "Vinci per conto tuo", "TypeImpostor": "Impostori", "TypeCrewmate": "Astronauti", "TypeNeutral": "Neutrali", @@ -31,9 +29,6 @@ "TeamNeutral": "Neutrale", "TeamCrewmate": "Astronauta", "TeamMadmate": "Follenauta", - "TeamLovers": "Amanti", - "TeamEgoist": "Egoista", - "TeamApocalypse": "Apocalisse", "YouAreCrewmate": "Sei un Astronauta", "YouAreImpostor": "Sei un Impostore", "YouAreNeutral": "Sei un Neutrale", @@ -156,7 +151,7 @@ "Ludopath": "Ludopatico", "Godfather": "Padrino", "Chronomancer": "Cronomante", - "Pitfall": "Fossa", + "Pitfall": "Insidioso", "EvilMini": "Mini Malvagio", "Blackmailer": "Ricattatore", "Instigator": "Istigatore", @@ -225,7 +220,6 @@ "TaskManager": "Gestore degli Incarichi", "Witness": "Testimone", "Swapper": "Scambiatore", - "ChiefOfPolice": "Capo della Polizia", "NiceMini": "Mini Buono", "Mini": "Mini", "Spy": "Spia", @@ -254,7 +248,6 @@ "Stalker": "Stalker", "Workaholic": "Stacanovista", "Solsticer": "Impiegato", - "Abyssbringer": "Portatore di abissi", "Collector": "Collezionista", "Provocateur": "Provocatore", "BloodKnight": "Cavaliere del Sangue", @@ -268,7 +261,7 @@ "Berserker": "Berserker", "War": "Guerra", "Glitch": "Glitch", - "Sidekick": "Spalla", + "Sidekick": "Aiutante", "Follower": "Seguace", "Cultist": "Cultista", "SerialKiller": "Serial Killer", @@ -393,8 +386,6 @@ "Sloth": "Bradipo", "Prohibited": "Proibito", "Eavesdropper": "Origliatore", - "Shocker": "Shocker", - "Revenant": "Revenant", "BracketAddons": "Aggiungi parentesi ai modificatori", "EngineerTOHEInfo": "Usa i condotti per beccare gli Impostori", "ScientistTOHEInfo": "Accedi ai segni vitali quando vuoi", @@ -411,12 +402,12 @@ "ShapeMasterInfo": "Uccidi velocemente senza ricarica mutazione", "VampireInfo": "Le tue uccisioni sono ritardate", "WarlockInfo": "Maledici gli astronauti poi mutati per farli uccidere", - "NinjaInfo": "Segna un bersaglio, poi mutati per ucciderlo", + "NinjaInfo": "Marca un bersaglio, poi mutati per ucciderlo", "ZombieInfo": "Sei molto lento", "AnonymousInfo": "Obbliga un giocatore a segnalare un corpo", "MinerInfo": "Vai all'ultimo condotto utilizzato mutandoti", "KillingMachineInfo": "Puoi SOLO uccidere, ma con ricarica bassa", - "EscapistInfo": "Mutati per Segnare i luoghi e teletrasportati ad essi", + "EscapistInfo": "Mutati per Marcare i luoghi e teletrasportati ad essi", "WitchInfo": "Incanta gli astronauti per ucciderli nelle riunioni", "NemesisInfo": "Uccidi quando sei l'ultimo impostore", "BeforeNemesisInfo": "Non puoi ancora uccidere", @@ -427,7 +418,7 @@ "MastermindInfo": "Costringi gli altri a uccidere per te", "TimeThiefInfo": "Uccidi per ridurre il tempo delle riunioni", "SniperInfo": "Cecchina i giocatori a distanza mutandoti", - "UndertakerInfo": "Teletrasporta un cadavere alla posizione segnata", + "UndertakerInfo": "Teletrasporta un cadavere alla posizione marcata", "RiftMakerInfo": "Traccio due squarci, toccali per deformare lo spazio", "EvilTrackerInfo": "Mutati per tenere traccia dei giocatori", "EvilHackerInfo": "Hackera il sistema", @@ -513,7 +504,7 @@ "PacifistInfo": "Usa i condotti per ripristinare le ricariche uccisione", "RebirthInfo": "Sorgi di Nuovo", "MonarchInfo": "Dai agli astronauti un potere di voto extra!", - "AbyssbringerInfo": "Piazza Buchi Neri", + "AbyssbringerInfo": "Crea Buchi Neri", "SpurtInfo": "Corri Come Un Coniglio!", "StealthInfo": "Uccidere Acceca Tutti i Presenti nella Stanza", "PenguinInfo": "Trascina le tue vittime", @@ -538,7 +529,7 @@ "AdmirerInfo": "Scegli un giocatore che passi dalla tua parte", "TimeMasterInfo": "Riavvolgi il tempo!", "CrusaderInfo": "Uccidi l'attaccante di un giocatore", - "AltruistInfo": "Rianima un giocatore", + "AltruistInfo": "Revive a player\nVent to change between Revive and Report", "ReverieInfo": "Con ogni uccisione, la tua ricarica uccisione si riduce", "LookoutInfo": "Guarda oltre i travestimenti", "TelecommunicationInfo": "Rintraccia l'uso dei dispositivi", @@ -547,7 +538,6 @@ "WitnessInfo": "Scopri se qualcuno ha ucciso di recente", "GhastlyInfo": "Controlla qualcuno!", "SwapperInfo": "Scambia i voti di due giocatori", - "ChiefOfPoliceInfo": "Assumi lo sceriffo per servire gli equipaggi!", "NiceMiniInfo": "Nessuno può farti del male finché non cresci.", "ArsonistInfo": "Innaffia tutti e infiamma", "PyromaniacInfo": "Innaffia e uccidi tutti", @@ -603,7 +593,7 @@ "VultureInfo": "Mangia i cadaveri segnalandoli per vincere", "TaskinatorInfo": "Incarichi silenziosi, esplosioni mortali", "BenefactorInfo": "Incarico completato, scudo élite!", - "MedusaInfo": "Tramuta i corpi in pietra segnalandoli", + "MedusaInfo": "Stone bodies by reporting them", "SpiritcallerInfo": "Trasforma i giocatori in Spiriti Malvagi", "AmnesiacInfo": "Ricorda il ruolo di un cadavere", "ImitatorInfo": "Imita il ruolo di un giocatore", @@ -615,19 +605,19 @@ "ShroudInfo": "Avvolgi i giocatori per farli uccidere", "WerewolfInfo": "Uccidi gli astronauti in gruppo", "ShamanInfo": "Devia tutti gli attacchi sulla tua bambola Voodoo", - "SeekerInfo": "Gioca a Nascondino con il tuo bersaglio", + "SeekerInfo": "Play Hide and Seek with your target\nYour target has a ★ mark.", "PixieInfo": "Contrassegnali, Raccoglili ed Espellili!", "OccultistInfo": "Uccidi e maledici i tuoi nemici", "SchrodingersCatInfo": "Il gatto è sia vivo che morto finché non viene osservato.", "RomanticInfo": "Proteggi il tuo partner per vincere insieme", "VengefulRomanticInfo": "Vendica il tuo partner per vincere insieme", "RuthlessRomanticInfo": "Uccidi tutti per vincere con il tuo partner", - "PoisonerInfo": "Uccidi tutti con uccisioni in ritardo", + "PoisonerInfo": "Kill everyone with delayed kills", "HexMasterInfo": "Strega i giocatori per ucciderli nelle riunioni", "WraithInfo": "Usa i condotti per essere temporaneamente invisibile", - "JinxInfo": "Rifletti gli attacchi sui tuoi attaccanti", + "JinxInfo": "Reflect attacks onto your attackers", "PotionMasterInfo": "Usa le tue pozioni a tuo vantaggio", - "NecromancerInfo": "Uccidi il tuo assassino per ingannare la morte", + "NecromancerInfo": "Kill your killer to defy death", "WardenInfo": "(Fantasma) Avvisa del pericolo", "MinionInfo": "(Fantasma) Acceca i nemici", "LoversInfo": "Rimanete in vita e vincete insieme", @@ -708,8 +698,6 @@ "SlothInfo": "Sei più lento", "ProhibitedInfo": "Alcuni condotti sono bloccati", "EavesdropperInfo": "Ascolta gli altri ruoli", - "ShockerInfo": "Folgora giocatori ignari", - "RevenantInfo": "Prendi il ruolo del tuo assassino", "EngineerTOHEInfoLong": "(Astronauti):\nCome Ingegnere, potrai accedere ai condotti mentre il sabotaggio delle comunicazioni è disattivato.", "ScientistTOHEInfoLong": "(Astronauti):\nCome scienziato, puoi vedere i segni vitali in qualsiasi momento, mostrandoti chi è vivo e chi è morto.", "NoisemakerTOHEInfoLong": "(Astronauti):\nCome Starnazzatore, Ogni volta che muori, emetti un rumore e sullo schermo appare un indicatore visivo della tua morte, in modo che gli astronauti possano correre a prendere in flagrante la persona che ti ha ucciso (anche se non si tratta di Rosso).", @@ -726,7 +714,7 @@ "VampireInfoLong": "(Impostori):\nCome Vampiro, le tue uccisioni sono ritardate. Ciò significa che il tuo bersaglio muore anche se prima viene convocata una riunione. Tuttavia, Se mordi un'esca, ucciderai normalmente e segnali il cadavere. A seconda delle impostazioni, puoi usare il doppio clic (mordere i giocatori - clic singolo, uccidere normalmente - doppio clic).", "WarlockInfoLong": "(Impostori):\nCome Stregone, puoi maledire fino a un altro giocatore alla volta.\nQuando usi il pulsante Muta, se hai maledetto un giocatore, uccidono la persona più vicina che, a seconda delle impostazioni, può includere te o altri impostori.\nPuoi uccidere normalmente mentre sei Mutato.", "ZombieInfoLong": "(Impostori):\nLo zombi ha una breve ricarica uccisione ma è molto lento e ha un campo visivo davvero basso. Lo Zombi non può essere votato da nessuno tranne che dal dittatore, la velocità dello zombi diminuirà gradualmente quando uccide oppure col tempo che passa.", - "NinjaInfoLong": "(Impostori):\nCome Ninja, puoi usare il pulsante uccidi per segnare il bersaglio (clic singolo) o per ucciderlo normalmente (doppio clic). Potrai poi mutarti per raggiungere il bersaglio segnato e ucciderlo.", + "NinjaInfoLong": "(Impostori):\nCome Ninja, puoi usare il pulsante uccidi per marcare il bersaglio (clic singolo) o per ucciderlo normalmente (doppio clic). Potrai poi mutarti per raggiungere il bersaglio marcato e ucciderlo.", "AnonymousInfoLong": "(Impostori):\nCome Anonimo, puoi mutarti per costringere il tuo bersaglio a segnalare chiunque tu abbia ucciso in questo round.\nSe non hai ucciso nessuno in quel round, il bersaglio segnalerà il proprio cadavere come se fosse morto.\nNota: questo non funziona né sul Pigro né sul Pigrone, e questa abilità funzionerà indipendentemente dal fatto che il corpo possa normalmente essere segnalato.", "MinerInfoLong": "(Impostori):\nCome Minatore, puoi mutarti per teletrasportarti all'ultimo condotto in cui ti trovavi.", "KillingMachineInfoLong": "(Impostori):\nCome Macchina Assassina hai una ricarica uccisione molto breve con un campo visivo basso. Tuttavia, non puoi sabotare, segnalare, chiamare riunioni, né usare i condotti.\n\nNota: Oltrepasserai ogni scudo, uccidere esca e trappola per orsi non avrà alcun effetto", @@ -774,24 +762,24 @@ "SaboteurInfoLong": "(Impostori):\nCome Sabotatore, puoi uccidere solamente quando ci sono sabotaggi critici in corso.\n\nSe il sabotaggio dell'ossigeno o del reattore è attivo, allora puoi uccidere.", "CouncillorInfoLong": "(Impostori):\nCome Assessore, puoi uccidere i giocatori durante le riunioni come un Giudice.\nQuando uccidi in questo modo, quelle uccisioni appariranno come processi da un Giudice.\n\nIl comando per uccidere è /tl [Id del giocatore]\nPuoi vedere l'id dei giocatori di fianco al loro nome, o usare il comando /id per vedere l'id di ogni giocatore.\nA seconda delle impostazioni, L'Assessore si suiciderà quando giudicherà i suoi compagni di squadra.\nL'assessore convertito può giudicare liberamente.", "DazzlerInfoLong": "(Impostori):\nCome Abbagliante, puoi ridurre permanentemente il campo visivo del giocatore in cui ti muti. Quando muori, il loro campo visivo tornerà alla normalità.", - "DeathpactInfoLong": "(Impostori):\nCome Patto Mortale, ti muti per segnare i tuoi bersagli per un patto di morte.\nSe hai abbastanza giocatori segnati per un patto di morte, questi devono incontrarsi entro un determinato periodo; se non ci riescono, muoiono.\nSe un giocatore segnato muore prima che il patto di morte sia completo, il patto viene ritirato.", + "DeathpactInfoLong": "(Impostori):\nCome Patto Mortale, ti muti per marcare i tuoi bersagli per un patto di morte.\nSe hai abbastanza giocatori marcati per un patto di morte, questi devono incontrarsi entro un determinato periodo; se non ci riescono, muoiono.\nSe un giocatore marcato muore prima che il patto di morte sia completo, il patto viene ritirato.", "DevourerInfoLong": "(Impostori):\nCome Divoratore, usi il tuo mutaforma per cambiare l'aspetto del bersaglio del mutaforma permanentemente. Inoltre, per la modifica dell'aspetto di ogni giocatore, la tua ricarica uccisione viene ridotta di un numero definito di secondi. Se il Divoratore muore o viene eliminato durante una riunione, l'aspetto del giocatore tornerà al suo aspetto normale.", "MorphlingInfoLong": "(Impostori):\nCome Mutante, sei un Mutaforma ma non puoi uccidere quando non sei mutato.", "TwisterInfoLong": "(Impostori):\nCome Uragano, puoi usare il mutaforma per scambiare la posizione di tutti i giocatori casualmente. Lo scambio avviene due volte, una volta quando inizi la mutazione e una volta quando ritorni al tuo aspetto originale.\nL'Uragano stesso non si scambierà di posto con nessuno, e i giocatori nei condotti non si teletrasporteranno.", "LurkerInfoLong": "(Impostori):\nCome Predatore, puoi saltare in un condotto per ridurre la ricarica uccisione di un certo numero di secondi, Dopo che hai ucciso, la ricarica uccisione ritorna al suo valore originale.", "VisionaryInfoLong": "(Impostori):\nCome Visionario, vedi gli allineamenti dei giocatori viventi durante un incontro.\nLe seguenti informazioni verranno visualizzate sui giocatori:\n- Il nome Rosso indica gli Impostori.\n- Il nome Ciano indica gli Astronauti.\n- Il nome Grigio indica i Neutrali.", "PlagueDoctorInfoLong": "(Neutrali):\n(Medico della Peste da TOH)\nL'obiettivo dello Scienziato della Peste è infettare ogni giocatore vivente.\nIniziano scegliendo un giocatore da infettare, dopodiché chiunque trascorra un\ndeterminato periodo di tempo nel raggio d'azione del giocatore infetto viene infettato a sua volta.\nL'avanzamento dell'infezione è cumulativo e non si ripristina con la distanza o dopo le riunioni.", - "RefugeeInfoLong": "(Follenauti):\nCome Profugo, eri:\n -Un Amnesico che si è ricordato di essere un Impostore\n -Un assassino che ha ucciso il bersaglio del Padrino.\n -Un Romantico il cui partner era un Impostore\n -O un Imitatore che ha imitato un Impostore.\n\nOra il tuo compito è aiutare gli Impostori a uccidere gli Astronauti.", + "RefugeeInfoLong": "(Follenauta):\nCome Profugo, eri un'Amnesico che si è ricordato di essere un Impostore o un assassino che ha ucciso il bersaglio del Padrino.\n\nOra il tuo lavoro è di aiutare gli Impostori a uccidere gli Astronauti.", "UnderdogInfoLong": "(Impostori):\nCome Sfavorito, non puoi uccidere finché non c'è un certo numero di giocatori vivi.", "ConsigliereInfoLong": "(Impostori):\nCome Consigliere, puoi rivelare i ruoli degli altri giocatori utilizzando il pulsante uccidi.\n\nClic singolo: rivela il ruolo\nDoppio clic: uccidi\n\nSe esaurisci gli usi di rivelazione, il pulsante uccidi funziona normalmente.", "LudopathInfoLong": "(Impostori):\nCome Ludopatico, la tua ricarica uccisione è casuale.\n\nIl minimo può essere 1 secondo, mentre il massimo è la ricarica uccisione normale.", - "GodfatherInfoLong": "(Impostori):\nCome Padrino, voti qualcuno per renderlo il tuo bersaglio.\nNel round successivo, se qualcuno uccide il bersaglio, l'assassino si trasformerà in un Profugo o Follenauta.", + "GodfatherInfoLong": "(Impostori):\nCome Padrino, voti qualcuno per renderlo il tuo bersaglio.\nNel round successivo, se qualcuno uccide il bersaglio, l'assassino si trasformerà in un Profugo.", "ChronomancerInfoLong": "(Impostori):\nCome Cronomante, hai una barra di carica che indica quando il massacro è pronto. Quando è al 100%, la prossima volta che uccidi qualcuno entri in modalità massacro, il che significa che puoi uccidere indefinitamente finché la barra non si esaurisce. Altrimenti hai una normale ricarica uccisione.", "PitfallInfoLong": "(Impostori):\nCome Fossa, usi la mutazione per segnare l'area attorno alla mutazione come una trappola. I giocatori che entrano in quest'area verranno immobilizzati rapidamente, e la loro vista sarà compromessa.", "EvilMiniInfoLong": "(Impostori):\nCome Mini Malvagio, sei immortale finché non cresci e hai una ricarica uccisione iniziale molto lunga, che si riduce drasticamente man mano che cresci.", "BlackmailerInfoLong": "(Impostori):\nCome Ricattatore, quando ti muti in un bersaglio, ricatterai quel giocatore. Ciò significa che durante le riunioni non potrà parlare.\n\nNota: se qualcuno è già stato ricattato, ricattare un'altra persona toglierà il ricatto alla persona attuale.", "InstigatorInfoLong": "(Impostori):\nCome istigatore, il tuo compito è quello di mettere gli astronauti l'uno contro l'altro. Ogni volta che un Astronauta viene eliminato durante una riunione, se sei vivo, un altro Astronauta che ha votato per il giocatore innocente morirà dopo la riunione. L'Host determina Il numero di giocatori aggiuntivi che muoiono.", - "LazyGuyInfoLong": "(Astronauti):\nIl Pigrone ha un solo un incarico. Inoltre, le abilità degli Impostori non possono influenzare il Pigrone, come ad esempio essere un capro espiatorio per Anonimo, essere segnato da uno Stregone o da un Burattinaio e altro ancora. Il Pigrone non avrà alcun Modificatore.", + "LazyGuyInfoLong": "(Astronauti):\nIl Pigrone ha un solo un incarico. Inoltre, le abilità degli Impostori non possono influenzare il Pigrone, come ad esempio essere un capro espiatorio per Anonimo, essere marcato da uno Stregone o da un Burattinaio e altro ancora. Il Pigrone non avrà alcun Modificatore.", "SuperStarInfoLong": "(Astronauti):\nCi sarà il logo di una stella accanto al nome della Super Star, così tutti sapranno chi è la Super Star. La Super Star può essere uccisa solo quando l'assassino è da solo con la Super Star (solo uccisioni regolari). Inoltre, gli indovini non possono indovinare la Super Star. ", "CelebrityInfoLong": "(Astronauti):\nTutti gli Astronauti vedono il flash uccisione quando la Celebrità muore (così come il Veggente vede il flash uccisione) e ricevono un avviso alla riunione successiva. Gli Impostori non ne sapranno nulla.", "CleanserInfoLong": "(Astronauti):\nCome Purificatore, puoi votare per cancellare i modificatori di qualsiasi bersaglio durante la riunione. La cancellazione ha effetto dopo la fine della riunione. A seconda delle impostazioni, il giocatore purificato potrebbe non ricevere più modificatori.", @@ -821,7 +809,7 @@ "GrenadierInfoLong": "(Astronauti):\nCome Granatiere, puoi usare i condotti per accecare i giocatori nelle vicinanze, facendo loro perdere la vista se sono un Impostore o, a seconda delle impostazioni, un Neutrale.", "MedicInfoLong": "(Astronauti):\nIl Medico può posizionare uno scudo sul bersaglio premendo il pulsante Uccidi. Il Medico può fornire un solo scudo per tutta la partita. A seconda delle impostazioni, lo scudo del bersaglio può disattivarsi o meno quando il Medico muore. Il Medico può anche vedere se qualcuno sta cercando di rompere lo scudo del bersaglio.\nA seconda delle impostazioni dell'host, il Medico o il bersaglio possono vedere se il giocatore ha uno scudo (mostrato come un cerchio verde 「●」 accanto al nome).", "FortuneTellerInfoLong": "(Astronauti):\nCome Chiromante, vota un giocatore in una riunione per avere un indizio sul suo ruolo.\nL'indizio riguarderà il loro ruolo reale.\n\nUna volta che il Chiromante avrà finito gli incarichi, otterrà il ruolo esatto anziché un indizio!\n\nNota: Se l'impostazione di dare giocatori attivi casuali come indizi è attiva, non potrai controllare lo stesso giocatore più volte.", - "JudgeInfoLong": "(Astronauti):\nIl Giudice può giudicare un determinato giocatore durante una riunione. Se il bersaglio è malvagio, verrà ucciso (se sia malvagio o meno viene stabilito dall'host), se è sbagliato, il Giudice si suicida.\nIl comando del giudizio è: /tl [Id giocatore]\nPuoi vedere l'id del giocatore prima del nome del giocatore, oppure usare il comando /id per vedere l'id di tutti i giocatori.\nIl Giudice può giudicare ogni giocatore quando diventa un Follenauta.", + "JudgeInfoLong": "(Crewmates):\nThe Judge can judge a certain player during the meeting. If the target is evil, the target will be killed (whether it is evil or not is set by the Host). If it is wrong, the Judge commits suicide.\nCommand for judgment: /tl [player id]\nYou can see the player's id before the player's name, or use the /id command to view the id of all players.\nJudges can judge all players when they become Madmate.\nIn meeting the ability count shows how many trails you have in this meeting. Out of meeting the ability counts shows how many trails you have for the whole game.", "MorticianInfoLong": "(Astronauti):\nL'Imbalsamatore può vedere le frecce che puntano a tutti i cadaveri, e se segnala un cadavere, conoscerà l'ultimo giocatore con cui la vittima ha avuto contatti. Nota: l'Imbalsamatore non sarà Ignaro o Veggente.", "MediumInfoLong": "(Astronauti):\nIl Medium può stabilire un contatto con un giocatore morto dopo che qualcuno segnala un cadavere. Il giocatore che segnala non deve essere il Medium. Il giocatore morto può rispondere una volta con un SI o un NO alla domanda del Medium, che solo il Medium potrà vedere (il giocatore morto può usare /ms yes o /ms no). Nota: il Medium non sarà Ignaro.", "ObserverInfoLong": "(Astronauti):\nCome Osservatore, puoi vedere tutte le animazioni dello scudo causate dagli altri giocatori dopo la prima riunione. Le animazioni dello scudo indicano in genere un'abilità del ruolo, quindi fai attenzione.", @@ -833,13 +821,13 @@ "MerchantInfoLong": "(Astronauti):\nCome mercante, vendi un modificatore a caso a un giocatore a caso per ogni incarico che porti a termine. Ogni modificatore venduto ti fa guadagnare denaro. Se hai una certa somma di denaro, puoi prevenire il prossimo tentativo di uccisione contro di te corrompendo l'assassino. Il giocatore corrotto non potrà ucciderti, ma tu non saprai chi è. Il denaro utilizzato viene perso e non disponibile per altre corruzioni.", "RetributionistInfoLong": "(Astronauti):\nCome Punitore, puoi uccidere un numero limitato di giocatori dopo la tua morte.\n\nUsa /ret [playerID] per uccidere.", "HawkInfoLong": "(Astronauti [Fantasma]):\nCome Falco, puoi uccidere una quantità limitata di giocatori decisa dall'host, ma c'è una possibilità di sbagliare, affettare qualcuno più volte aumenta le possibilità.", - "DeputyInfoLong": "(Astronauti):\nCome Vice, usa il pulsante uccidi su un giocatore per resettare la ricarica dell'uccisione.\n\nSe il bersaglio non ha un pulsante uccidi, allora le manette erano uno spreco.", + "DeputyInfoLong": "(Crewmates):\nAs the Deputy, use your kill button to handcuff a player.\nThe player who is handcuffed will have their next kill attempt treated as a handcuff break, and the kill cooldown will be reset.\n\nIf the target does not have a kill button, then the handcuff was a waste.", "InvestigatorInfoLong": "(Astronauti):\nCome Investigatore, puoi utilizzare il tuo pulsante uccidi per indagare su qualcuno. Quando indaghi su qualcuno, il suo nome apparirà in rosso se possiede un pulsante uccidi (base Impostore/Mutaforma) o in azzurro se non ha un pulsante uccidi (base Astronauta/Ingegnere/Scienziato). Tuttavia, tieni presente che il colore dei nomi tornerà normale quando qualcuno chiamerà una riunione.", "GuardianInfoLong": "(Astronauti):\nCome Guardiano, diventi immortale al completamento dei tuoi incarichi.\nGli indovini non potranno indovinarti nelle riunioni.", "AddictInfoLong": "(Astronauti):\nCome Tossicomane, hai un timer per il suicidio. Quando scade, ti uccidi.\nIl timer è indicato dalla ricarica dei condotti. Quando la ricarica dei condotti è a 0 secondi, hai ancora un breve periodo di tempo per usare i condotti.\nSe non ce la fai, muori; se ce la fai, il timer del suicidio si azzera.\nInoltre, dopo che hai usato i condotti, nessuno può interagire con te per un periodo definito.\nDopo, il periodo termina e tu sei immobilizzato per un altro periodo definito e non puoi segnalare alcun corpo.", "MoleInfoLong": "(Astronauti):\nCome la Talpa, quando usi i condotti, rimani nel condotto per 1 secondo. Quando esci dal condotto, apparirai vicino a un condotto casuale nella mappa (tranne quello che hai usato).", "AlchemistInfoLong": "(Astronauti):\nCome Alchimista, prepari pozioni quando completi gli incarichi. La pozione che hai creato verrà visualizzata sotto il nome del tuo ruolo con la descrizione e le istruzioni corrispondenti. Puoi ottenere sette pozioni diverse, alcune con effetti dannosi o senza effetti. Usa i condotti per usare la pozione.", - "KamikazeInfoLong": "(Impostori):\nCome Kamikaze puoi fare clic con un solo clic per contrassegnare le persone. Fare doppio clic per uccidere normalmente. Quando muori, muoiono anche tutti quelli bersagliati, con causa di morte Bersagliato.", + "KamikazeInfoLong": "(Impostori):\nCome Kamikaze puoi fare clic con un solo clic per marcare le persone. Fare doppio clic per uccidere normalmente. Quando muori, muoiono anche tutti quelli bersagliati, con causa di morte Bersagliato.", "TracefinderInfoLong": "(Astronauta):\nCome Tracciatore, puoi accedere ai segni vitali in qualsiasi momento.\nInoltre, ottieni frecce che puntano a cadaveri, con un ritardo impostato dall'Host.", "OracleInfoLong": "(Astronauta):\nCome Oracolo, puoi votare un giocatore durante una riunione.\nVedrai se è un Astronauta, un Neutrale o un Impostore.\nA seconda delle impostazioni, è possibile che il risultato non sia corretto.", "SpiritualistInfoLong": "(Astronauti):\nCome Spiritualista, ottieni una freccia che punta verso il fantasma della vittima dell'ultima riunione. C'è un'opzione per far scomparire e riapparire la freccia a intervalli. Prova a informare il fantasma della tua abilità se puoi; se sono dalla tua parte, potrebbero condurti a un ruolo malvagio in modo da poterli espellere. Fai attenzione, poiché i ruoli malvagi possono fare lo stesso per gli Astronauti.", @@ -847,9 +835,9 @@ "InspectorInfoLong": "(Astronauti):\nControlla se due giocatori fanno parte della stessa squadra oppure no. Riceverai un messaggio di conferma se fanno parte della stessa squadra o un messaggio di rifiuto se non fanno parte della stessa squadra.\n\nTutti i giocatori neutrali e convertiti vengono conteggiati nella stessa squadra. L'Imbroglione conta come Astronauta e il Mascalzone conta come Impostore.\nComando di controllo: /cmp [id giocatore 1] [id giocatore 2].", "CaptainInfoLong": "(Astronauti):\nCon ogni incarico completato, il Capitano acquisisce il potere di rallentare un ruolo casuale non astronauta. Gli astronauti possono vedere ☆ oltre al nome del Capitano.\n\nSe qualcuno tradisce la fiducia del Capitano votandolo, egli perderà un modificatore.", "AdmirerInfoLong": "(Astronauti):\nCome Ammiratore, ammirare un giocatore lo porterà dalla parte degli Astronauti.\nVinceranno con gli Astronauti e non con la loro squadra originale.\n\nPuoi farlo solo una volta per giocatore.", - "TimeMasterInfoLong": "(Astronauti):\nCome Padrone Temporale, usa i condotti per contrassegnare la posizione di tutti.\nQuando si utilizza nuovamente l'abilità, ogni giocatore vivo verrà riavvolto nelle posizioni contrassegnate.\n\nDurante la durata dell'abilità, il Padrone Temporale ottiene uno scudo temporale, che lo protegge dalla morte.", + "TimeMasterInfoLong": "(Astronauti):\nCome Padrone Temporale, usa i condotti per marcare la posizione di tutti.\nQuando si utilizza nuovamente l'abilità, ogni giocatore vivo verrà riavvolto nelle posizioni marcate.\n\nDurante la durata dell'abilità, il Padrone Temporale ottiene uno scudo temporale, che lo protegge dalla morte.", "CrusaderInfoLong": "(Astronauta):\nCome Crociato, usa il pulsante uccidi per fare una crociata a un giocatore.\nSe quel giocatore viene attaccato, ucciderai l'attaccante.", - "AltruistInfoLong": "(Astronauti):\nCome Altruista, puoi sacrificarti per far rianimare un cadavere usando il pulsante «Segnala».\nNota: se un giocatore morto ha abbandonato il gioco, quel corpo sarà segnalato normalmente.\nInoltre il giocatore rianimato non può segnalare il proprio cadavere", + "AltruistInfoLong": "(Crewmates):\nAs the Altruist, you can sacrifice yourself to revive a dead body using the «Report» button.\nNote: If a dead player has left the game, you report that body normally.\nAlso revived player cannot report self dead body\nUse vent button to change between Report & Revive.", "ReverieInfoLong": "(Astronauti):\nCome Fantasticheria, puoi uccidere, ma la tua ricarica iniziale sara alta.\n\nAumenta se uccidi un astronauta e si riduce in caso contrario.\nA seconda dell'impostazione dell'Host, puoi fare cilecca quando raggiungi la ricarica uccisione massima, e il tuo bersaglio muore con te. \n\nVinci con altri astronauti.", "LookoutInfoLong": "(Astronauti):\nCome vedetta, puoi vedere gli ID di ogni giocatore in ogni momento.\nCiò ti consente di vedere attraverso i mutaforma e i camuffamenti.", "TelecommunicationInfoLong": "(Astronauti):\nCome Telecomunicatore, sarai avvisato quando qualcuno utilizza le telecamere, segni vitali, registri dei corridoi o la mappa in amministrazione.", @@ -872,7 +860,7 @@ "LawyerInfoLong": "(Neutrali):\nL'Avvocato ha un bersaglio da difendere, il quale sarà indicato con un diamante 「♦」 accanto al loro nome.\nSe il bersaglio vince, vinci.\nSe perde, perdi anche tu.", "OpportunistInfoLong": "(Neutrali):\nSe l'Opportunista sopravvive alla fine del gioco, l'Opportunista vince con la squadra vincente.", "VectorInfoLong": "(Neutrali):\nIl Vettore vince da solo usando i condotti un certo numero di volte.", - "JackalInfoLong": "(Neutrali):\nCome Sciacallo, vinci se sei l'ultimo giocatore vivo. Inoltre, puoi reclutare utilizzando il pulsante uccidi. Se il bersaglio non è uno che puoi reclutare, hai esaurito gli usi o non hai la possibilità di reclutare, allora ucciderai le persone normalmente (cioè non usare il pulsanti uccidi davanti agli altri pensando che recluterà).\nSe il bersaglio ha un pulsante uccidi e l'opzione per trasformarsi in una Spalla è attiva, diventerà una Spalla. Altrimenti, otterranno il modificatore Recluta se l'opzione per fornire il modificatore Recluta è attiva.\nA seconda delle impostazioni, quando lo Sciacallo viene ucciso, una Spalla verrà selezionata casualmente come nuovo Sciacallo.\nÈ possibile selezionare una Recluta se ne non ci sono Spalle in vita.", + "JackalInfoLong": "(Neutrali):\nCome Sciacallo, vinci se sei l'ultimo giocatore vivo. Inoltre, puoi reclutare utilizzando il pulsante uccidi. Se il bersaglio non è uno che puoi reclutare, hai esaurito gli usi o non hai la possibilità di reclutare, allora ucciderai le persone normalmente (cioè non usare il pulsanti uccidi davanti agli altri pensando che recluterà).\nSe il bersaglio ha un pulsante uccidi e l'opzione per trasformarsi in un Aiutante è attiva, diventerà un Aiutante. Altrimenti, otterranno il modificatore Recluta se l'opzione per fornire il modificatore Recluta è attiva.", "GodInfoLong": "(Neutrali):\nCome Dio, conosci il ruolo di ognuno fin dall'inizio. Se vivi fino alla fine del gioco, rubi la vittoria, cioè., tutti gli altri perdono, e tu vinci.", "InnocentInfoLong": "(Neutrali):\nL'Innocente può usare il pulsante uccidi per incastrare qualsiasi giocatore e il bersaglio incastrato ucciderà immediatamente l'Innocente. Se il bersaglio viene espulso durante la riunione, l'Innocente vince. Nota: Giullare, Esecutore e Innocente possono vincere insieme.", "PelicanInfoLong": "(Neutrali):\nCome Pellicano, puoi usare il pulsante uccidi per inghiottire un giocatore vivo, teletrasportandolo fuori dalla mappa ma senza ucciderlo. I giocatori inghiottiti moriranno solo se tu sarai ancora vivo alla fine del round. Se muori o te ne vai durante il round, tutti i giocatori vivi inghiottiti appariranno nella mappa in cui ti trovavi.", @@ -884,14 +872,14 @@ "SolsticerInfoLong": "(Neutrali):\nCome Impiegato, non morirai e vincerai completando tutti i tuoi incarichi in un unico round. Al termine di ogni riunione, i tuoi incarichi vengono ripristinati e devi ricominciare tutto da capo.\nOgni voto sull'Impiegato verrà cancellato direttamente.\nI tentativi di uccisione sull'Impiegato lo teletrasporteranno fuori dalla mappa come Pellicano fino al termine dell'incontro.\nLa ricarica uccisione dell'assassino verrà ripristinato a 10 secondi.\nL'Impiegato non viene considerato nulla nel gioco.", "CollectorInfoLong": "(Neutrali):\nCome Collezionista, quando voti per un giocatore, per ogni altro giocatore che lo ha votato, guadagni un punto. Quando raccogli i voti richiesti, il gioco finisce e vinci da solo, anche se hai eliminato un giullare o il bersaglio di un esecutore.", "GlitchInfoLong": "(Neutrali):\nCome Glitch, puoi hackerare i giocatori (clic singolo) o uccidere normalmente (doppio clic).\nColoro che sono stati hackerati non possono uccidere, usare i condotti o segnalare per la durata delle hack.\nInoltre, chiamare un sabotaggio diverso dalle porte non avrà alcun effetto e ti travestirà invece da giocatore casuale. Non puoi mascherarti durante o dopo i sabotaggi.\nPer vincere, sii l'ultimo giocatore vivo.", - "SidekickInfoLong": "(Neutrali):\nCome Spalla, il vostro compito è quello di aiutare lo Sciacallo uccidere tutti.\nTu e lo Sciacallo vincerete insieme.\nA seconda delle impostazioni, puoi trasformarti in Sciacallo se il vecchio Sciacallo è stato ucciso.\nPotresti non essere in grado di uccidere fino a quando il vecchio Sciacallo non è morto.", + "SidekickInfoLong": "(Neutrali):\nCome Aiutante, il tuo compito è aiutare lo Sciacallo a uccidere tutti.\n\nTu e lo Sciacallo vincete insieme.", "ProvocateurInfoLong": "(Neutrali):\nCome Provocatore, puoi uccidere qualsiasi bersaglio con il pulsante uccidi. Se il bersaglio perde alla fine della partita, il Provocatore vince con la squadra vincitrice.", "BloodKnightInfoLong": "(Neutrali):\nIl Cavaliere del Sangue vince quando è l'ultimo ruolo assassino in vita, e il numero di astronauti è inferiore o uguale al numero di Cavalieri del Sangue. Dopo ogni uccisione, il Cavaliere del Sangue ottiene uno scudo temporaneo rendendolo immortale per alcuni secondi.", "PlagueBearerInfoLong": "(Apocalisse):\nCome Untore, infetta tutti usando il pulsante uccidi per trasformarti in Pestilenza.\nUna volta che ti trasformerai in Pestilenza, diventerai immortale e acquisirai la capacità di uccidere, e ucciderai chiunque tenti di ucciderti.\n\nInoltre, quando i giocatori infetti interagiscono con giocatori non infetti, anche loro verranno infettati.", "PestilenceInfoLong": "(Apocalisse):\nCome Pestilenza sei una macchina inarrestabile.\nQualsiasi attacco nei tuoi confronti si rifletterà contro di loro.\nLe uccisioni indirette non ti uccidono nemmeno.\n\nL'unico modo per uccidere Pestilenza è votarla oppure se Pestilenza sbaglia a indovinare.\nLa tua presenza verrà annunciata nella riunione dopo la tua trasformazione.", "SoulCollectorInfoLong": "(Apocalisse):\nCome Collezionista di Anime, puoi usare il pulsante uccidi su un giocatore per prevederne la morte. Guadagnerai un'anima se il tuo bersaglio muore nel round in cui lo selezioni o nella riunione successiva.\nIl tuo obiettivo si ripristina dopo ogni riunione o dopo la morte, a seconda di quale evento si verifica per primo. \n\nUna volta raccolta la quantità configurabile di anime, diventerai La Morte. Se l'impostazione guadagno anime passive è abilitata, otterrai un'anima ad ogni riunione.", "DeathInfoLong": "(Apocalisse):\nUna volta che il Collezionista di Anime ha raccolto le anime necessarie, diventa la Morte. La Morte uccide tutti e vince se la Morte non viene espulsa entro la fine della prossima riunione.\nUn tempo extra configurabile per la riunione verrà assegnato alla riunione in cui la Morte si è trasformata per avere più discussioni per trovare la Morte.\n\nSei invincibile, e la tua presenza viene annunciata a tutti alla riunione dopo che ti sei trasformato.", - "BakerInfoLong": "(Apocalisse):\nCome Fornaio, puoi usare il pulsante uccidi su un giocatore per round per dargli il pane. \nUna volta che un determinato numero di giocatori sono vivi con il pane, diventi Carestia.\n\nSe il Pane fornisce effetti aggiuntivi e l'impostazione è attiva, puoi usare i condotti per cambiare il pane che distribuisci. \nEffetti del pane:\nRivela: rivela il ruolo del bersaglio al Fornaio (rimane per l'intera partita)\nBloccaruolo: imposta la ricarica uccisione del bersaglio su 999 (si ripristina alla normalità dopo la riunione)\nBarriera: Fornisce al bersaglio una barriera conosciuta solo dal Fornaio (la barriera viene rimossa dopo la riunione)", + "BakerInfoLong": "(Apocalypse):\nAs the Baker, you can use your kill button on a player per round to give them bread. \nOnce a set amount of players are alive with bread, you become Famine.\n\nIf the Bread gives additional effects and the setting is on, then you can vent to change the bread that you give out. \nBread Effects:\nReveal: Reveals the target's role to the Baker (stays the whole game)\nRoleblock: Resets the target's kill cooldown when they try to use their kill button\nBarrier: Gives the target a barrier that is only known to the Baker (barrier is removed after the meeting)", "FamineInfoLong": "(Apocalisse):\nUna volta che il Fornaio ha un numero stabilito di persone vive con il pane, diventa Carestia. Se la Carestia non viene eliminata dopo la riunione, allora diventerà Carestia, e ogni giocatore senza pane morirà di fame (esclusi gli altri membri dell'Apocalisse).\nDopo aver fatto morire di fame tutti quelli senza pane, Carestia può usare il suo pulsante uccidi per far morire di fame tutti i giocatori rimasti, il che ucciderà quei giocatori appena prima della riunione successiva.\n\nSei invincibile e la tua presenza viene annunciata a tutti alla riunione dopo che ti sei trasformato.", "BerserkerInfoLong": "(Apocalisse):\nCome Berserker, sali di livello ad ogni uccisione.\nAl raggiungimento di un certo livello definito dall'Host, sblocchi un nuovo potere.\n\nLe uccisioni da spazzino fanno sparire le tue uccisioni.\nLe uccisioni bombardate rendono le tue uccisioni esplosive. Fai attenzione quando uccidi, poiché ciò potrebbe uccidere gli altri membri della Apocalisse se sono vicini.\nDopo un certo livello diventi Guerra.", "WarInfoLong": "(Apocalisse):\nCome Guerra, sei invincibile, hai una ricarica uccisione inferiore e puoi uccidere chiunque con i tuoi poteri precedenti.\nLa tua presenza viene annunciata a tutti i partecipanti alla riunione dopo la trasformazione.", @@ -911,7 +899,6 @@ "TraitorInfoLong": "(Neutrali):\nCome Traditore, eri un impostore che ha tradito gli impostori.\nConosci gli Impostori, ma loro non conoscono te.\nLa svolta? Possono ucciderti ma tu non puoi uccidere loro.\n\nElimina gli impostori con altri mezzi, poi uccidi tutti gli altri per vincere!", "TrollerInfoLong": "(Neutrali):\nCome Troller, puoi completare gli incarichi in modo che possano accadere eventi casuali ai giocatori.\nAd esempio, modificando la velocità di tutti i giocatori, teletrasporto, influenzando il sabotaggio, ecc.\nInoltre puoi vincere con la squadra vincitrice.", "VultureInfoLong": "(Neutrali):\nCome Avvoltoio, segnala i corpi per vincere!\n\nQuando segnali un corpo, se la ricarica di mangiare è scaduto, mangerai il corpo (rendendolo non segnalabile).\nSe la tua abilità di mangiare è ancora in ricarica, riporterai il corpo normalmente.\n\nInoltre, segnalerai i corpi normalmente se viene raggiunto il numero massimo di corpi mangiati per round.", - "AbyssbringerInfoLong": "(Impostori):\nCome Portatore di abissi, puoi piazzare buchi neri. I buchi neri risucchieranno i giocatori e li uccideranno quando entreranno in collisione con loro.", "TaskinatorInfoLong": "(Neutrali):\nCome Incaricator, quando completi un incarico, verrà piazzata una bomba sull'incarico. Quando un altro giocatore completa l'incarico con la bomba, essa esploderà, e il giocatore morirà.\n\nVinci se sopravvivi fino alla fine e se gli Astronauti non vincono.\n\n Nota: Le bombe dell'Incaricator ignora tutte le protezioni.", "BenefactorInfoLong": "(Astronauti):\nCome Benefattore, ogni volta che completi un incarico, quel incarico verrà contrassegnato. Quando un altro giocatore completa l'incarico contrassegnato, ottiene uno scudo temporaneo.\n\n Nota: lo scudo protegge solo dagli attacchi diretti.", "MedusaInfoLong": "(Neutrali):\nCome Medusa, puoi pietrificare i corpi proprio come pulire un corpo.\nI corpi Pietrificati non possono essere segnalati.\n\nUccidi tutti per vincere.", @@ -931,8 +918,8 @@ "RomanticInfoLong": "(Neutrali):\nIl Romantico può scegliere il proprio partner amante usando il pulsante uccidi (questo può essere fatto in qualsiasi momento del gioco). Una volta scelto il partner, possono utilizzare il pulsante uccidi per fornire al proprio partner uno scudo temporaneo che lo protegge dagli attacchi. Se il partner muore, il ruolo del Romantico cambierà in base alle seguenti condizioni:\n1. Se il partner era un Impostore, il romantico diventa Profugo\n2. Se il loro partner era un Assassino Neutrale, allora diventa un Romantico Spietato.\n3. Se il loro partner era un Astronauta o un Neutrale che non uccide, il Romantico diventa il Romantico Vendicativo.\n\nIl Romantico vince con la squadra vincente se vince il suo partner.\nNota: se il tuo ruolo cambia, la tua condizione di vittoria verrà modificata di conseguenza", "RuthlessRomanticInfoLong": "(Neutrali):\nCambi il tuo ruolo da Romantico se il tuo partner (Un assassino neutrale) viene ucciso. Come Romantico Spietato, vinci se uccidi tutti e sei l'ultimo rimasto. Se vinci, anche il tuo partner morto vince con te.", "VengefulRomanticInfoLong": "(Neutrali):\nCambi il tuo ruolo da Romantico se il tuo partner (un astronauta o un neutrale non assassino) viene ucciso. In quanto Romantico Vendicativo, il tuo obiettivo è vendicare il tuo partner, il che significa che devi uccidere l'assassino del tuo partner. Se ci riesci, sia tu che il tuo partner vincerete con la squadra vincitrice alla fine. Se provi a uccidere qualcuno che non sia l'assassino del tuo partner, morirai per cilecca.", - "PoisonerInfoLong": "(Neutrali):\nCome Avvelenatore, le tue uccisioni vengono ritardate.\nUccidi tutti per vincere.", - "HexMasterInfoLong": "(Neutrali):\nCome Fattucchiere, puoi maledire i giocatori o ucciderli.\nLanciare un maleficio a un giocatore funziona allo stesso modo dell'incantesimo di una Strega.", + "PoisonerInfoLong": "(Neutrals):\nAs the Poisoner, your kills are delayed.\nKill everyone to win.", + "HexMasterInfoLong": "(Neutrals):\nAs the Hex Master, you can hex players or kill them.\nHexing a player works the same as spelling as a Witch.", "WraithInfoLong": "(Neutrali):\nCome Spirito, puoi usare i condotti per svanire temporaneamente. Apparirai comunque visibile sullo schermo. Usa i condotti nuovamente per diventare visibile. Vinci se sei l'ultimo giocatore rimasto.", "JinxInfoLong": "(Neutrale):\nCome lo Iettatore, ogni volta che vieni attaccato, gli porti sfortuna, con il risultato di morire sfortunati.\nQuesto ha degli usi limitati.\n\nUccidi chiunque per vincere.", "PotionMasterInfoLong": "(Neutrali):\nCome Maestro delle Pozioni, hai tre diverse pozioni assegnate a tre diverse azioni.\n\nClic singolo: Rivela il ruolo\nDoppio clic: Uccidi\nMappa: Sabotaggio\n\nLa pozione di rivelazione ha un limite.\nQuando le finisci, il pulsante uccidi si imposta automaticamente sull'uccisione.", @@ -958,7 +945,7 @@ "ParanoiaInfoLong": "(Modificatori):\nNon assegnato ai Neutrali né ai Follenauti.\nCome Paranoia, sarai considerato come due giocatori nel gioco per determinare quando il gioco finirà a causa della maggioranza degli assassini. Inoltre, questo ti garantisce un voto extra, a seconda delle impostazioni.", "MimicInfoLong": "(Modificatori):\nSolo l'Impostore può diventare Mimic. Quando il Mimic è morto, gli altri impostori riceveranno un messaggio una volta convocata una riunione. Questo messaggio includerà informazioni sui ruoli uccisi dal Mimic.", "GuesserInfoLong": "(Modificatori):\nCome Indovino, indovina i ruoli dei giocatori nelle riunioni per ucciderli.\nIndovinare il ruolo sbagliato invece ti uccide.\nIl comando per indovinare è: /bt [Id giocatore] [role]\nPuoi vedere l'id del giocatore prima del nome del giocatore oppure usare il comando /id per vedere l'id di tutti i giocatori.", - "NecroviewInfoLong": "(Modificatori):\nLa Necrovisione può vedere le squadre dei giocatori morti. Le seguenti informazioni verranno visualizzate sul nome del giocatore morto durante una riunione:\n- Il nome Rosso indica gli Impostori.\n- Il nome ciano indica gli Astronauti.\n- Il nome Grigio indica i Neutrali.", + "NecroviewInfoLong": "(Add-ons):\nThe Necroview can see the teams of dead players. The following info will be displayed on the dead player's name while in a meeting:\n- The Red name indicates the Impostors.\n- The Cyan name indicates the Crewmates.\n- The Gray name indicates the Neutrals.", "ReachInfoLong": "(Modificatori):\nSolo i ruolo con un pulsante uccidi possono avere questo modificatore. A differenza di tutti gli altri, hai la distanza uccisione più lunga possibile nel gioco.", "BaitInfoLong": "(Modificatori):\nQuando l'Esca muore, l'assassino che l'ha ucciso auto-segnalerà il suo cadavere. Tuttavia, questo non accade quando uno Spazzino, Pulitore, Invisibile, Spirito, Medusa o Macchina Assassina uccidono l'esca. La segnalazione potrebbe avere un ritardo in base alle impostazioni dell'host.", "TrapperInfoLong": "(Modificatore):\nQuando la Trappola per Orsi muore, immobilizzerà l'assassino per una quantità configurabile di tempo.", @@ -1024,11 +1011,10 @@ "SlothInfoLong": "(Modificatori):\nLa velocità di movimento predefinita del Bradipo è più lenta rispetto alle altre.\n(La velocità dipende dalle impostazioni dell'host)", "ProhibitedInfoLong": "(Modificatori):\nCome Proibito, hai dei condotti specifici che non puoi usare.\nQuanti condotti sono disabilitati dipende dalle impostazioni dell'Host.", "EavesdropperInfoLong": "(Modificatori):\nCome Origliatore, hai la possibilità di leggere messaggi basati su informazioni relative ad altri ruoli/modificatori, come Imbalsamatore o Indagatore.", - "ApocalypseInfoLong": "(Apocalisse):\nI membri dell'Apocalisse sono in una squadra separata che lavora insieme e vince insieme. Se ci sono più ruoli dell'Apocalisse nel gioco, possono vedere i ruoli degli altri.\nA seconda delle impostazioni dell'host, i ruoli dell'Apocalisse possono indovinare o essere indovinati.", - "RevenantInfoLong": "(Neutrale):\nCome Revenant, il tuo obiettivo è di essere ucciso. Se sei ucciso, prenderai il ruolo del tuo assassino e ucciderai il tuo assassino. Non puoi vincere prima di essere ucciso.\nNota che Revenant funziona solo quando viene ucciso direttamente.", + "ApocalypseInfoLong": "(Apocalypse):\nApocalypse members are on a separate team that works together and wins together. If there are multiple Apocalypse roles in the game, they can see each other's roles.\nDepending on the Host's settings, Apocalypse roles can guess or be guessed.", "ShowTextOverlay": "Sovrapposizione Testo", "Overlay.GuesserMode": "Modalità Indovino", - "Overlay.NoGameEnd": "Nessuna Fine del Gioco", + "Overlay.NoGameEnd": "Gioco senza fine", "Overlay.DebugMode": "Modalità Debug", "Overlay.LowLoadMode": "Modalità Leggera", "Overlay.AllowConsole": "Console", @@ -1039,8 +1025,6 @@ "AbilityUseLimit": "Limite iniziale di utilizzo delle abilità", "AbilityInUse": "Abilità in uso", "AbilityExpired": "Abilità scaduta, {0} usi rimanenti", - "RevenantTargeted": "Il tuo ruolo è cambiato in {0}", - "RevenantCanCopyAddons": "Puoi Rubare i Modificatori", "ShowArrows": "Ha frecce che puntano verso i cadaveri", "ArrowDelayMin": "Ritardo Minimo di visualizzazione della Freccia", "ArrowDelayMax": "Ritardo Massimo di visualizzazione della Freccia", @@ -1054,7 +1038,7 @@ "DisableMeeting": "Disabilita le Riunioni", "DisableCloseDoor": "Disabilita il Sabotaggio delle Porte", "DisableSabotage": "Disabilita i Sabotaggi", - "NoGameEnd": "Nessuna Fine del Gioco", + "NoGameEnd": "Gioco Senza Fine", "AllowConsole": "Console BepInEx", "DebugMode": "Modalità di Debug", "SyncButtonMode": "Limite Utilizzi Riunioni", @@ -1342,7 +1326,7 @@ "ShowNARemainOnEject": "Mostra Neutrali dell'Apocalisse rimasti nelle espulsioni", "ConfirmEgoistOnEject": "Conferma Egoista all'espulsione", "ConfirmLoversOnEject": "Conferma Amanti all'espulsione", - "ConfirmSidekickOnEject": "Conferma Spalle all'espulsione", + "ConfirmSidekickOnEject": "Conferma Aiutanti all'espulsione", "HideBittenRolesOnEject": "Nascondi ruoli dei giocatori morsi all'espulsione", "ShowTeamNextToRoleNameOnEject": "Mostra a quale squadra apparteneva il ruolo del giocatore espulso", "Ban": "Ban", @@ -1370,8 +1354,6 @@ "ShieldedCanUseKillButton": "Il giocatore protetto può usare il pulsante abilità / uccidi", "PlayerIsShieldedByGame": "Il giocatore è protetto dal gioco!", "LegacyNemesis": "Utilizza la versione precedente", - "LegacyParasite": "Utilizza la versione precedente", - "LegacyTraitor": "Utilizza la versione precedente", "ArsonistKeepsGameGoing": "L' Incendiario fa continuare il gioco", "ArsonistCanIgniteAnytime": "Può dare Fuoco in qualsiasi momento", "ArsonistMinPlayersToIgnite": "Minimo Innaffiati per dare fuoco", @@ -1514,23 +1496,11 @@ "SheriffCanKillSeparately": "Impostazioni Individuali", "In%team%": "(Squadra %team%)", "SheriffMisfireKillsTarget": "Cilecca Uccide il Bersaglio", - "BlackHolePlaceCooldown": "Ricarica Piazzamento Buco Nero", - "BlackHoleDespawnMode": "Modalità Scomparsa Buco Nero", - "BlackHoleDespawnTime": "Tempo dopo la scomparsa del buco nero", - "Abyssbringer.Suffix": "Numero di giocatori consumati da {0} buchi neri attivi:\\n{1}", - "Abyssbringer.Suffix.BlackHole": "{0}: {1}", - "BlackHoleMovesTowardsNearestPlayer": "Il buco nero si muove verso il giocatore più vicino", - "BlackHoleMoveSpeed": "Velocità Di Movimento Buco Nero", - "BlackHoleRadius": "Raggio di consumo del buco nero", - "AfterTime": "Dopo il tempo", - "After1PlayerEaten": "Dopo che 1 giocatore è stato mangiato", - "AfterMeeting": "Dopo la riunione", - "None": "Nessuno", "SheriffShotLimit": "Massimo Numero di Uccisioni", "SheriffCanKillAllAlive": "Può Uccidere Quando Nessuno è Morto", "SheriffCanKillCharmed": "Può uccidere i giocatori Affascinati", "SheriffCanKillEgoist": "Può Uccidere gli Egoisti", - "SheriffCanKillSidekick": "Può Uccidere le Spalle", + "SheriffCanKillSidekick": "Può Uccidere gli Aiutanti", "SheriffCanKillLovers": "Può Uccidere gli Amanti", "SheriffCanKillMadmate": "Può Uccidere i Follenauti", "SheriffCanKillInfected": "Può Uccidere i giocatori Infettati", @@ -1542,15 +1512,12 @@ "RebirthUses": "Quantità di Rinascite", "RebirthCountVotes": "Rinascita solo in giocatori che lo hanno votato", "RebirthFailed": "Ahh, che sfortuna, non hai trovato nessuna anima vitale con cui scambiare i corpi", - "FireworkerCooldown": "Ricarica Piazzamento", "ReverieIncreaseKillCooldown": "Incrementa Ricarica Uccisione", "ReverieMaxKillCooldown": "Ricarica uccisione Massimo", "ReverieMisfireSuicide": "Cilecca raggiungendo la ricarica uccisione massima", "ReverieResetCooldownMeeting": "Ripristina ricarica uccisione dopo le riunioni", "ConvertedReverieKillAll": "Il Capriccioso convertito può uccidere chiunque senza ripercussioni", "VigilanteNotify": "Sei diventato la cosa che hai giurato di distruggere", - "DictatorChangeCommandToExpel": "Dittatore usa il comando per espellere invece di votare", - "DictatorExpelSelf": "ASPE ASPE ASPE MA CHE DIAVOLO il Bro vuole solo espellere se stesso", "DoctorTaskCompletedBatteryCharge": "Durata Batteria", "SnitchEnableTargetArrow": "Vede Freccia Verso il Bersaglio", "SnitchCanGetArrowColor": "Vede Frecce Colorate basate sui Colori della Squadra", @@ -1624,6 +1591,7 @@ "TimeThiefDecreaseMeetingTime": "Abbassa Tempo Riunione di", "TimeThiefLowerLimitVotingTime": "Minimo Tempo di Voto", "TimeThiefReturnStolenTimeUponDeath": "Restituisci Tempo Rubato Alla Morte", + "TimeThiefMaxTimeOnAdmired": "Maximum Meeting Time if Time Thief Is Admired", "EvilTrackerCanSeeKillFlash": "Può vedere il Flash Uccisione", "EvilTrackerCanSeeLastRoomInMeeting": "Può Vedere l'Ultima Stanza del Bersaglio nella Riunione", "EvilTrackerTargetMode": "Può Selezionare il Bersaglio", @@ -1631,7 +1599,6 @@ "EvilTrackerTargetMode.OnceInGame": "Una volta a partita", "EvilTrackerTargetMode.EveryMeeting": "Ogni Riunione", "EvilTrackerTargetMode.Always": "Quando vuoi", - "ScavengerHasCustomDeathReason": "Abilita Causa Di Morte Personalizzata", "EvilHackerCanSeeDeadMark": "Può Vedere La Posizione dei Cadaveri", "EvilHackerCanSeeImpostorMark": "Può Vedere La Posizione degli Altri Impostori", "EvilHackerCanSeeKillFlash": "Può vedere il Flash Uccisione", @@ -1712,7 +1679,7 @@ "TicketsPerKill": "Aumento Numero Voti per Uccisione", "GangsterRecruitCooldown": "Ricarica Reclutamento", "GangsterRecruitLimit": "Limite Reclute", - "KamikazeMaxMarked": "Massimo di Bersagli", + "KamikazeMaxMarked": "Massimo di Marcati", "RevolutionistDrawTime": "Durata del Marchio", "RevolutionistCooldown": "Ricarica del Marchio", "RevolutionistDrawCount": "Quantità di Giocatori necessari da Taggare", @@ -1780,16 +1747,16 @@ "RandomActiveRoles": "Mostra ruoli attivi casuali nei suggerimenti del Chiromante", "CamouflageCooldown": "Ricarica Camuffamento", "CamouflageDuration": "Durata del Camuffamento", - "NinjaMarkCooldown": "Ricarica Contrassegno", + "NinjaMarkCooldown": "Ricarica Marca", "NinjaAssassinateCooldown": "Ricarica Assassinio", - "NinjaModeDouble": "Doppio Clic = Uccidi, Clic Singolo = Segna", + "NinjaModeDouble": "Doppio Clic = Uccidi, Clic Singolo = Marca", "JudgeCanTrialnCrewKilling": "Può processare gli Astronauti Uccisori", "JudgeCanTrialNeutralB": "Può processare i Neutrali Benigni", "JudgeCanTrialNeutralK": "Può processare i Neutrali Assassini", "JudgeCanTrialNeutralE": "Può processare i Neutrali Maligni", "JudgeCanTrialNeutralC": "Può processare i Neutrali Caotici", "JudgeCanTrialNeutralA": "Può processare i Neutrali dell'Apocalisse", - "JudgeCanTrialSidekick": "Può processare le Spalle", + "JudgeCanTrialSidekick": "Può processare gli Aiutanti", "JudgeCanTrialInfected": "Può processare gli Infetti", "JudgeCanTrialContagious": "Può processare i Contagiosi", "JudgeTryHideMsg": "Nascondi il comando del Giudice", @@ -1857,28 +1824,20 @@ "JackalCanWinBySabotageWhenNoImpAlive": "Quando tutti gli Impostori sono morti, lo Sciacallo vince invece con il sabotaggio", "JackalResetKillCooldownWhenPlayerGetKilled": "Azzera ricarica uccisione se qualcuno viene ucciso da un altro giocatore", "JackalResetKillCooldownOn": "Ricarica Uccisione al Ripristino", - "JackalCanRecruitSidekick": "Può reclutare Spalle", - "JackalSidekickRecruitLimit": "Numero Massimo Di Reclutamenti", - "Jackal_SidekickCountMode": "Le Spalle contano come", + "JackalCanRecruitSidekick": "Può reclutare Aiutanti", + "JackalSidekickRecruitLimit": "Numero massimo di Reclute", + "Jackal_SidekickCountMode": "Gli Aiutanti contano come", "Jackal_SidekickCountMode_None": "Nulla", "Jackal_SidekickCountMode_Jackal": "Sciacallo", "Jackal_SidekickCountMode_Original": "Squadra Originale", "Jackal_SidekickAssignMode": "Modalità Assegnazione Spalle", - "Jackal_SidekickAssignMode_SidekickAndRecruit": "Spalla quando fallisce Recluta", + "Jackal_SidekickAssignMode_SidekickAndRecruit": "Sidekick when failed Recruit", "Jackal_SidekickAssignMode_Sidekick": "Solo Spalla", "Jackal_SidekickAssignMode_Recruit": "Solo Recluta", - "Jackal_SidekickCanKillSidekick": "Le Spalle possono uccidere altre Spalle", - "Jackal_SidekickCanKillJackal": "Spalla può uccidere Sciacallo", - "Jackal_RecruitFailed": "Non puoi reclutare questo giocatore!", - "JackalCanKillSidekick": "Lo Sciacallo può uccidere la Spalla", - "Jackal_SidekickCanKillWhenJackalAlive": "Spalla può uccidere quando Sciacallo è vivo", - "Jackal_SidekickTurnIntoJackal": "Spalla può trasformarsi in Sciacallo dopo la sua morte", - "Jackal_RestoreLimitOnNewJackal": "Ripristina il limite di Reclutamento quando Spalla diventa nuovo Sciacallo", - "Jackal_OnBecomeNewJackalMeeting": "Il vecchio Sciacallo {0} è morto.\nSei stato selezionato come nuovo Sciacallo\nLavorate insieme e vinci la partita!", - "Jackal_OnNewJackalSelectedMeeting": "Il vecchio Sciacallo {0} è morto.\n{1} è selezionato come nuovo Sciacallo!\nLavorate insieme e vinci la partita!", - "Jackal_BecomeNewJackal": "Vecchio Sciacallo Morto, Ora sei il nuovo Sciacallo!", - "Jackal_OnNewJackalSelected": "Vecchio sciacallo morto, per favore aiuta il nuovo sciacallo {0} per ora!", - "Jackal_BossIsDead": "Ops, il capo Sciacallo è morto!", + "JackalWinWithSidekick": "Lo Sciacallo può vincere con il team dell' Aiutante", + "Jackal_SidekickCanKillSidekick": "Gli Aiutanti possono uccidere altri Aiutanti", + "Jackal_SidekickCanKillJackal": "Aiutante può uccidere Sciacallo", + "JackalCanKillSidekick": "Lo Sciacallo può uccidere l'Aiutante", "CoronerArrowsPointingToDeadBody": "Ha frecce che puntano sui cadaveri", "CoronerLeaveDeadBodyUnreportable": "I corpi che il Medico Legale utilizza non sono segnalabili", "CoronerInformKillerBeingTracked": "Informa all'assassino di essere localizzato", @@ -1916,9 +1875,6 @@ "VipTag": "VIP★", "ApplyVipList": "Applica Lista VIP", "AllowSayCommand": "Permetti ai moderatori di usare il comando /say", - "AllowStartCommand": "Permetti ai moderatori di usare il comando /start", - "StartCommandMinCountdown": "Conto alla rovescia minimo per il comando /start", - "StartCommandMaxCountdown": "Conto alla rovescia massimo per il comando /start", "KickCommandDisabled": "Il comando per cacciare è attualmente disabilitato.", "KickCommandNoAccess": "Non hai accesso al comando per cacciare.", "KickCommandInvalidID": "ID giocatore specificato non valido.\nPer favore usa '/kick [playerID] [reason]' per cacciare un giocatore.\nEsempio:- /kick 5 not following rules", @@ -1951,11 +1907,6 @@ "WarnCommandNoAccess": "Non hai accesso al comando per gli avvertimenti.", "WarnCommandInvalidID": "ID giocatore specificato non valido.\nPer favore usa '/warn [playerID] [reason]' per avvertire un giocatore. \nEsempio:- /warn 5 lava chatting", "WarnCommandWarnHost": "Non sei permesso ad avvertire l'host.", - "StartCommandNoAccess": "Non hai accesso al comando start.", - "StartCommandDisabled": "Il comando start è attualmente disabilitato.", - "StartCommandCountdown": "ERRORE\n\nIl gioco sta già iniziando!", - "StartCommandStarted": "La partita è stata avviata da {0}!", - "StartCommandInvalidCountdown": "ERRORE\n\nIl conto alla rovescia deve essere tra {0} e {1}!", "WarnCommandWarnMod": "Non sei permesso ad avvertire gli altri moderatori.", "WarnCommandWarned": "è stato avvertito. Non verranno più forniti avvisi e verranno intraprese le azioni appropriate \n ", "WarnExample": "Usa /warn [id] [reason] in futuro. \nEsempio :-\n /warn 5 lava chatting", @@ -1983,7 +1934,6 @@ "DeathReason.Quantization": "Quantizzazione", "DeathReason.Overtired": "Esausto", "DeathReason.Ashamed": "Imbarazzato", - "DeathReason.Consumed": "Consumato", "DeathReason.PissedOff": "Distrutto", "DeathReason.Dismembered": "Smembrato", "DeathReason.LossOfHead": "Strangolato", @@ -2007,8 +1957,6 @@ "DeathReason.Starved": "Affamato", "DeathReason.Equilibrium": "Equilibrio", "DeathReason.Sacrificed": "Sacrificato", - "DeathReason.Electrocuted": "Elettrificato", - "DeathReason.Scavenged": "Spazzato", "OnlyEnabledDeathReasons": "Solo Cause di Morte Attive", "Alive": "Vivo", "Disconnected": "Disconnesso", @@ -2024,10 +1972,11 @@ "DeputyHandcuffCooldown": "Ricarica Manette", "DeputyHandcuffMax": "Massimo di Manette", "DeputyHandcuffedPlayer": "Bersaglio ammanettato", - "HandcuffedByDeputy": "Sei stato ammanettato!", - "DeputyInvalidTarget": "Il bersaglio non è ammanettatile", + "HandcuffedByDeputy": "You were handcuffed!\nNow you have broken your handcuff and can kill again.", + "DeputyInvalidTarget": "Target is already handcuffed", + "HandcuffBrokenAfterMeeting": "Remove all handcuffs after meeting", "DeputyHandcuffText": "Manette", - "DeputyHandcuffCDForTarget": "Ricarica uccisione per i giocatori ammanettati", + "DeputyHandcuffCDForTarget": "Next Kill Cooldown for handcuffed player", "RejectShapeshift.AbilityWasUsed": "Hai già usato l'abilità", "EscapisMtarkedPosition": "Hai marcato la tua posizione", "InvestigateCooldown": "Ricarica Investigazione", @@ -2087,7 +2036,6 @@ "ShowMadmatesInLeftCommand": "Mostra Follenauti (Inclusi modificatori)", "ShowApocalypseInLeftCommand": "Mostra Neutrali dell'Apocalisse", "SeeEjectedRolesInMeeting": "Vedi i ruoli degli espulsi", - "ThankYouForUsingTOHE": "Grazie per aver usato TOHE!", "SkillUsedLeft": "Hai attivato la tua abilità per convocare una riunione. \nQuantità rimanente di usi rimasti:", "NemesisDeadMsg": "La morte della Nemesi significa l'inizio della vendetta. \nPer favore usa /rv + [ID giocatore] per uccidere quel specifico giocatore \nPuoi vedere gli ID dei giocatori di fronte ai loro nomi. \nO scrivi /rv per avere gli ID dei giocatori", "NemesisAliveKill": "La vendetta per la Nemesi può iniziare solo dopo la loro morte.", @@ -2107,7 +2055,6 @@ "GuessNotifiedBait": "L'Esca non può essere indovinata perché è stata annunciata. Pensavi che sarebbe stato così facile, vero?", "GuessGM": "Indovinare il GM è impossibile perché è già morto.... E perché vorresti fare questo al povero Host?", "GuessGuardianTask": "Non puoi indovinare un Guardiano che ha finito i suoi incarichi.", - "GuardianCantKilled": "Non puoi uccidere un Guardiano che ha finito i suoi incarichi.", "GuessMarshallTask": "Non puoi indovinare un Maresciallo che ha finito i suoi incarichi.", "GuessObviousAddon": "Spiacenti, i modificatori ovvi non possono essere indovinati.", "GuessAdtRole": "Sfortunatamente, le impostazioni dell'host non ti permettono d'indovinare i modificatori", @@ -2163,13 +2110,12 @@ "BecomeMadmateCuzMadmateMode": "Sei diventato un Follenauta perché sei morto", "CleanerCleanBody": "Il corpo è stato ripulito", "QuickShooterStoraging": "Proiettili riservati con successo", - "QuickShooterFailed": "Stai ancora ricaricando.", "PoisonerTargetDead": "L'obiettivo è morto", "HexesLookLikeSpells": "I malefici appaiono come incantesimi", "HexButtonText": "Maleficio", "BloodthirstAdded": "La tua sete di sangue è ora attiva!", "WarlockNoTarget": "Manipolazione fallita non c'e un bersaglio", - "WarlockNoTargetYet": "Non hai segnato un bersaglio.", + "WarlockNoTargetYet": "Non hai marcato un bersaglio.", "WarlockTargetDead": "Manipolazione fallita a causa del bersaglio morto", "WarlockControlKill": "L'obiettivo è morto", "OnCelebrityDead": "Attenzione: Celebrità morta!", @@ -2222,7 +2168,7 @@ "PacifistOnGuard": "Abilità usata, {0} usi rimasti", "PacifistSkillNotify": "Il Pacifista ha azzerato la tua ricarica uccisione", "BeRecruitedByJackal": "Lo Sciacallo ti ha reclutato", - "YinYangerAlreadyMarked": "{0} è già in uno stato di calma, grazie a un compagno YinYanger", + "YinYangerAlreadyMarked": "{0} è già in uno stato di calma, dotato di un compagno YinYanger", "CoronerTrackRecorded": "Rintracciamento registrato", "CoronerNoTrack": "Niente da rintracciare", "CoronerIsTrackingYou": "Il Medico Legale ti sta rintracciando!", @@ -2244,7 +2190,7 @@ "MonarchInvalidTarget": "Il bersaglio non può essere cavallerizzato", "GhostTransformTitle": "Il Tuo Ruolo Si è Trasformato!", "SpiritcallerNoticeTitle": "SEI DIVENTATO UNO SPIRITO MALVAGIO ", - "SpiritcallerNoticeMessage": "L'Evocatore ti ha ucciso e ti ha trasformato in uno spirito maligno. Il tuo compito ora è aiutare l'Evocatore a vincere usando il pulsante tormenta per ostacolare gli altri giocatori o proteggere l'Evocatore. Utilizzare /m per ulteriori informazioni.", + "SpiritcallerNoticeMessage": "L'Invocatore di spiriti ti ha ucciso e ti ha trasformato in uno spirito maligno. Il tuo compito ora è aiutare l'Invocatore di spiriti a vincere usando il pulsante tormenta per ostacolare gli altri giocatori o proteggere l'Invocatore di spiriti. Utilizzare /m per ulteriori informazioni.", "OverseerRevealCooldown": "Ricarica Rivelazione", "OverseerRevealTime": "Tempo per la Rivelazione", "OverseerVision": "Campo visivo Chiaroveggente", @@ -2322,7 +2268,6 @@ "Message.YTPlanNotice": "Nota che: Il [Piano dello YouTuber] è attivato in questa lobby, ciò vuol dire che l'host può specificare il suo ruolo la prossima partita per rendere più facile ottenere il contenuto. Se l'host abusa di questa funzionalità, esci dal gioco o segnalalo.\nCredenziali dell'attuale Creatore:", "Message.OnlyCanBeUsedByHost": "ERRORE\n\nQuesto comando può essere usato solo dall'host.", "Message.MaxPlayers": "Numero massimo di giocatori impostato a ", - "Message.MaxPlayersFailByRegion": "Impossibile impostare un massimo di giocatori: Le regioni vanilla supportano un massimo di 15 giocatori.", "Message.GhostRoleInfo": "Informazioni sui ruoli fantasma\nEhilà! Riguardante ai ruoli fantasma...\n\nI ruoli fantasma hanno un impatto drastico sul gioco, quindi non sono consigliati per lobby più piccole se non hai familiarità. Se non diversamente specificato nella descrizione, il pulsante Proteggi è il pulsante della loro abilità ;)\n\nGenerazione:\nI ruoli fantasma si generano solo dopo la morte; le prime x persone di (squadra) a morire li ottengono.\n\nPS: se il tuo ruolo precedente non aveva incarichi (ad esempio., sceriffo), i tuoi incarichi come ruolo fantasma non sono necessari per vincere di incarichi", "ApocalypseInfoTitle": "Informazioni Neutrali dell'Apocalisse:", "Message.ApocalypseInfo": "Ogni ruolo del team Apocalisse ha un proprio obiettivo da raggiungere per trasformarsi.\n\nI membri dell'Apocalisse Trasformati hanno un drastico cambiamento nel gioco e sono immortali (tranne per essere stati votati), ma tutti saranno avvisati della loro trasformazione.\n\nRuoli: Untore, Collezionista di anime, Fornaio, Berserker\nTrasformati: Pestilenza, Morte, Carestia, Guerra\n\nI membri dell'Apocalisse possono vedere i ruoli e le icone delle abilità degli altri.\nCome gli Assassini Neutrali, anche i membri dell'Apocalisse continuano a far andare avanti il ​​gioco, divertitevi!", @@ -2454,6 +2399,7 @@ "LastResult": "★ Risultati Partita", "LastEndReason": "★ Motivazione Fine", "KillLog": "Registro Uccisioni", + "MainRoleLog": "Role Convert Log", "Maximum": "Massimo", "RoleRate": "ON", "RoleOn": "ALWAYS", @@ -2514,7 +2460,7 @@ "MercenarySuicideButtonText": "Timer Suicidio", "WarlockCurseButtonText": "Maledici", "NinjaShapeshiftText": "Uccidi", - "NinjaMarkButtonText": "Segna", + "NinjaMarkButtonText": "Marca", "WitchSpellButtonText": "Incantesimo", "VampireBiteButtonText": "Mordi", "MinerTeleButtonText": "Teletrasporto", @@ -2525,7 +2471,7 @@ "EvilTrackerChangeButtonText": "Rintraccia", "RiftMakerButtonText": "Crea Squarcio", "AbyssbringerButtonText": "Buco Nero", - "PitfallButtonText": "Imposta Trappola", + "PitfallButtonText": "Imposta Insidia", "InnocentButtonText": "Incastra", "PelicanButtonText": "Mangia", "DeceiverButtonText": "Inganna", @@ -2555,7 +2501,7 @@ "GrenadierVentButtonText": "Flash", "MayorVentButtonText": "Pulsante", "SheriffKillButtonText": "Spara", - "UndertakerButtonText": "Segna", + "UndertakerButtonText": "Marca", "ArsonistVentButtonText": "Dai Fuoco", "RevolutionistVentButtonText": "Rivoluzione", "FollowerKillButtonText": "Segui", @@ -2640,7 +2586,7 @@ "NeutralRemain": "\nRimangono {0} Assassini Neutrali", "OneNeutralRemain": "\nRimangono {0} Assassini Neutrali", "ApocRemain": "\n{0} Neutrali dell'Apocalisse rimanenti", - "GameOverReason.HumansByVote": "Tutti gli Impostori e gli Assassini Neutrali sono stati espulsi o uccisi", + "GameOverReason.HumansByVote": "All Impostors and Neutral Killers were ejected or killed", "GameOverReason.HumansByTask": "Gli Astronauti hanno completato tutti gli incarichi", "GameOverReason.HumansDisconnect": "Gli Astronauti si sono disconnessi", "GameOverReason.ImpostorByVote": "Gli Astronauti sono stati espulsi", @@ -2730,9 +2676,8 @@ "DeathMeetingTimeIncrease": "Tempo di riunione aumentato quando esiste la Morte", "SoulCollectorMeetingDeath": "Il tuo bersaglio è morto durante la riunione. Hai guadagnato un'anima.", "SoulCollectorKillButtonText": "Predici", - "SoulCollectorHasImpostorVision": "Collezionista di Anime ha il campo visivo impostore", "ApocalypseIsNigh": "[ L'Apocalisse è vicina! ]", - "ApocalypseImmune": "Questo ruolo è immune!", + "ApocalypseImmune": "Questo giocatore è immune perché è invincibile!", "BakerToFamine": "Sei diventato Carestia!!!", "BakerTransform": "Il Fornaio si è trasformato in Carestia, Cavaliere dell'Apocalisse! Una carestia è iniziata!", "BakerAlreadyBreaded": "Quel giocatore ha già il pane!", @@ -2741,15 +2686,13 @@ "BakerBreadNeededToTransform": "Numero di pane necessario per diventare Carestia", "BakerCantBreadApoc": "Non puoi dare pane agli altri membri dell'Apocalisse!", "BakerKillButtonText": "Pane", - "BakerUnshiftButtonText": "Cambia Pane", "BakerRevealBread": "Rivela", "BakerRoleblockBread": "Bloccaruolo", "BakerBarrierBread": "Barriera", "BakerCurrentBread": "Pane Attuale: ", "BakerSwitchBread": "Pane Cambiato in: ", - "BakerCanVent": "Fornaio può usare i condotti", + "BakerCanVent": "Fornaio può usare i condotti", "BakerBreadGivesEffects": "Il pane dà effetti aggiuntivi", - "BakerTransformNoMoreBread": "Il fornaio si trasforma se non ha abbastanza pane", "FamineKillButtonText": "Affamare", "FamineStarveCooldown": "Carestia ricarica affamare", "FamineCantStarveApoc": "Non puoi affamare gli altri membri dell'Apocalisse!", @@ -2796,7 +2739,6 @@ "GodfatherTargetCountMode": "L'assassino si trasforma in", "GodfatherCount_Refugee": "Profugo", "GodfatherCount_Madmate": "Follenauta", - "GodfatherRefugeeMsg": "Sei stato reclutato dal Padrino!", "MissChance": "Possibilità di mancare", "IncreaseByOneIfConvert": "Aumenta il ConteggioUccisioni +1 se un astronauta è stato convertito", "HawkMissed": "Mancato!", @@ -2829,7 +2771,6 @@ "BerserkerToWar": "Sei diventato Guerra!!!", "BerserkerTransform": "Il Berserker si è trasformato in Guerra, Cavaliere dell'Apocalisse! Grida \"Devastazione!\" e scatena i cani da guerra.", "WarKillCooldown": "Guerra ricarica uccisione", - "BerserkerCanKillTeamate": "Può uccidere altri Neutrali Dell'Apocalisse", "BlackmailerSkillCooldown": "Ricarica Ricatto", "BlackmailerMax": "Massimo di volte in cui i giocatori ricattati possono parlare", "BlackmailerDead": "Attenzione! {0} è stato ricattato da un Ricattatore!", @@ -2919,8 +2860,6 @@ "RememberedPursuer": "Ti sei ricordato che eri un Persecutore!", "RememberedFollower": "Ti sei ricordato che eri un Seguace!", "RememberedAmnesiac": "Hai fallito di ricordare il tuo ruolo.", - "AmnesiacRemembered": "Ti sei ricordato che eri {0}!", - "ReportWhenFailedRemember": "Segnala Cadavere quando non è riuscito a ricordare", "RememberedImitator": "Ti sei ricordato che eri un Imitatore.", "RememberedImpostor": "Ti sei ricordato che eri un Impostore!", "RememberedCrewmate": "Ti sei ricordato che eri un Astronauta!", @@ -2941,7 +2880,7 @@ "BanditStealCooldown": "Ricarica Furto", "DoppelMaxSteals": "Furti Massimi", "DoppelCurrentVictimCanSeeRolesAsDead": "L'ultima vittima può vedere le informazioni sul ruolo e sui modificatori dei giocatori vivi da fantasma", - "NecromancerRevengeTime": "Durata Necromanzia", + "NecromancerRevengeTime": "Necromancy time", "NecromancerRevenge": "Hai {0}s per uccidere {1}", "NecromancerSuccess": "Necromanzia completata! Vivrai per vedere un altro giorno.", "NecromancerHide": "I condotti sono disattivati, nasconditi dal Necromante!", @@ -3146,7 +3085,7 @@ "DollMaster_PossessedTarget": "Bersaglio posseduto", "DollMaster_CannotPossessImpTeammate": "Impossibile possedere un compagno", "DollMaster_CouldNotSwapWithTarget": "Impossibile possedere il giocatore", - "DollMaster_CanNotSwapWithDeadTarget": "Possedere un giocatore morto non è possibile", + "DollMaster_CanNotSwapWithDeadTarget": "Possessing a dead player isn't possible", "DollMaster_MainBody": "Corpo Principale", "DollMaster_Doll": "Bambola", "DollMaster_UnableToUseAbility": "Impossibile utilizzare la tua abilità sul giocatore", @@ -3154,17 +3093,17 @@ "EatenByDevourer": "Il Divoratore ha mangiato la tua skin", "DevourerEatenSkin": "Skin del bersaglio mangiata", "DevouredName": "Divorato", - "PitfallTrapCooldown": "Ricarica Trappola", - "PitfallMaxTrapCount": "Numero di trappole che possono essere piazzate", - "PitfallTrapMaxPlayerCount": "Numero di Giocatori che possono essere catturati per Trappola", - "PitfallTrapDuration": "Tempo in cui le trappole rimangono attive", - "PitfallTrapRadius": "Raggio delle Trappole", - "PitfallTrapFreezeTime": "Durata Immobilizzazione trappola", - "PitfallTrapCauseVision": "Campo visivo causato dalla trappola", - "PitfallTrapCauseVisionTime": "Durata campo visivo causato dalla trappola", - "PitfallTrap": "Sei caduto in una trappola!", + "PitfallTrapCooldown": "Ricarica Insidia", + "PitfallMaxTrapCount": "Numero d'insidie che possono essere piazzate", + "PitfallTrapMaxPlayerCount": "Numero di Giocatori che possono essere catturati per Insidia", + "PitfallTrapDuration": "Tempo in cui le Insidie rimangono attive", + "PitfallTrapRadius": "Raggio Insidia", + "PitfallTrapFreezeTime": "Durata Immobilizzazione Insidia", + "PitfallTrapCauseVision": "Campo visivo causato dall'insidia", + "PitfallTrapCauseVisionTime": "Durata campo visivo causato dall'insidia", + "PitfallTrap": "Sei caduto in un'insidia!", "ConsigliereDivinationMaxCount": "Rivelazioni Massime", - "RitualMaxCount": "Rivelazioni Massime", + "RitualMaxCount": "Maximum Reveals", "CleanserHideVote": "Nascondi il voto del Purificatore", "OracleSkillLimit": "Usi massimi", "OracleHideVote": "Nascondi il voto dell'Oracolo", @@ -3289,11 +3228,11 @@ "GhastlyYouvePosses": "Sei Stato Posseduto!", "GhastlyPossessedUser": "Hai posseduto: {0}", "GhastlyExpired": "{0} non è più posseduto", - "TasksMarkPerRound": "Numero d'incarichi che possono essere contrassegnati in un round", + "TasksMarkPerRound": "Numero d'incarichi che possono essere marcati in un round", "TaskinatorBombPlanted": "La Bomba è stata piazzata", "ShieldDuration": "Durata Scudo", "ShieldIsOneTimeUse": "Lo scudo si rompe dopo un tentativo di uccisione", - "BenefactorTaskMarked": "Incarico segnato con successo", + "BenefactorTaskMarked": "Incarico marcato con successo", "BenefactorTargetGotShield": "Hai avuto uno scudo dal Benefattore", "PirateTryHideMsg": "Nascondi il comando del Pirata", "SuccessfulDuelsToWin": "Numero di duelli vinti necessari per vincere", @@ -3328,18 +3267,15 @@ "SeekerKillButtonText": "Tagga", "PixiePointsToWin": "Numero di punti necessari per vincere", "MaxTargets": "Massimo numero di bersagli per round", - "MarkCooldown": "Ricarica Segna", + "MarkCooldown": "Ricarica Marca", "PixieSuicide": "Il Folletto si suicida se il bersaglio non viene espulso", "PixieMaxTargetReached": "Hai già selezionato tutti i bersagli per questo round", "PixieTargetAlreadySelected": "Il Bersaglio è già stato selezionato", - "PixieButtonText": "Segna", + "PixieButtonText": "Marca", "PlagueBearerCooldown": "Ricarica Infetta", - "PlagueBearerCanVent": "Può usare i condotti", - "PlagueBearerHasImpostorVision": "Ha il campo visivo impostore", "PestilenceCooldown": "Ricarica uccisione della Pestilenza", "PestilenceCanVent": "La Pestilenza può usare i condotti", "PestilenceHasImpostorVision": "La Pestilenza Ha il campo visivo Impostore", - "PestilenceKillGuessers": "Uccidi i giocatori che indovinano Pestilenza", "PlagueBearerAlreadyPlagued": "Il Giocatore è stato già Infettato", "PlagueBearerToPestilence": "Ti sei trasformato in Pestilenza!!", "GuessPestilence": "Hai appena provato a indovinare la Pestilenza!\n\nSpiacenti, la Pestilenza ti ha ucciso.", @@ -3383,7 +3319,6 @@ "EveryoneCanKnowMini": "Tutti possono vedere il Mini", "CanBeEvil": "Il Mini può essere un Impostore", "EvilMiniSpawnChances": "Probabilità che il Mini sia un Impostore", - "EvilMiniCanBeGuessed": "Mini Malvagio può essere indovinato prima dei 18", "GuessMini": "Spiacenti, non puoi fare del male a un Mini bambino.", "GrowUpDuration": "Tempo richiesto per crescere (s)", "MajorCooldown": "Ricarica Uccisione quando sopra 18 anni", @@ -3394,7 +3329,7 @@ "CantBoom": "Non puoi esplodere con un Mini che non è ancora cresciuto.", "CantRecruit": "Non puoi reclutare un Mini che non è ancora cresciuto.", "CantDuel": "Non puoi duellare un Mini che non è ancora cresciuto.", - "CantMark": "Non puoi segnare un Mini che non è ancora cresciuto.", + "CantMark": "Non puoi marcare un Mini che non è ancora cresciuto.", "CantBlood": "Non puoi Insanguinare un Mini che non è ancora cresciuto.", "CantPosses": "Non puoi possedere un Mini che non è ancora cresciuto.", "ExiledNiceMini": "È stato espulso un Mini Buono prima che crescesse.\nAvete perso tutti", @@ -3504,7 +3439,7 @@ "WinnerRoleText.Traitor": "Traditore Vince!", "WinnerRoleText.Vulture": "Avvoltoio Vince!", "WinnerRoleText.Medusa": "Medusa Vince!", - "WinnerRoleText.Spiritcaller": "Evocatore Vince!", + "WinnerRoleText.Spiritcaller": "Invocatore di spiriti Vince!", "WinnerRoleText.Glitch": "Glitch Vince!", "WinnerRoleText.Pestilence": "Pestilenza Vince!", "WinnerRoleText.PlagueBearer": "Untore Vince!", @@ -3525,8 +3460,7 @@ "WinnerRoleText.Doppelganger": "Doppelganger Vince!", "WinnerRoleText.Quizmaster": "Maestro dei quiz Vince!", "WinnerRoleText.Agitater": "Agitatore Vince!", - "WinnerRoleText.Shocker": "Shocker Vince!", - "AdditionalWinnerRoleText.Sidekick": "Spalla", + "AdditionalWinnerRoleText.Sidekick": "Aiutante", "AdditionalWinnerRoleText.Taskinator": "Incaricator", "AdditionalWinnerRoleText.Opportunist": "Opportunista", "AdditionalWinnerRoleText.Lawyer": "Avvocato", @@ -3611,7 +3545,7 @@ "SolsticerOnMeeting": "Hai assistito a troppe morti! Nel prossimo round avrai altri {0} incarichi brevi!", "SolsticerTitle": "Impiegato", "GuessSolsticer": "Spiacenti, ma non puoi indovinare l'Impiegato!", - "ExpelSolsticer": "Spiacenti, ma non puoi espellere l'Impiegato!", + "VoteSolsticer": "Spiacenti, ma non puoi votare l'Impiegato!", "SolsticerTasksReset": "I tuoi incarichi sono ripristinati!", "SolsticerMisGuessed": "Hai semplicemente sbagliato a indovinare! Non ti è più consentito indovinare.", "SolsticerGuessMax": "Siccome hai già sbagliato a indovinare! Non ti è più permesso indovinare.", @@ -3623,18 +3557,18 @@ "dbConnect.nullFriendCode": "Questa versione di TOHE non è disponibile per gli utenti senza codice amico!", "Quizmaster": "Maestro dei quiz", "QuizmasterInfo": "Fai domande ai giocatori per ucciderli nelle riunioni", - "QuizmasterInfoLong": "(Neutrali):\nCome Maestro dei Quiz, puoi contrassegnare un giocatore utilizzando il pulsante uccidi. Nella riunione successiva, il giocatore contrassegnare avrà \"?!\" accanto al suo nome. Il giocatore morirà se risponderà male alla domanda o non risponderà. Il giocatore vivrà se il Maestro dei Quiz viene ucciso/espulso nella stessa riunione.\nIl Maestro dei Quiz non può contrassegnare più persone nello stesso turno", + "QuizmasterInfoLong": "(Neutrali):\nCome Maestro dei Quiz, puoi marcare un giocatore utilizzando il pulsante uccidi. Nella riunione successiva, il giocatore marcato avrà \"?!\" accanto al suo nome. Il giocatore morirà se risponderà male alla domanda o non risponderà. Il giocatore vivrà se il Maestro dei Quiz viene ucciso/espulso nella stessa riunione.\nIl Maestro dei Quiz non può marcare più persone nello stesso turno", "QuizmasterKillButtonText": "Quiz", - "QuizmasterChat.MarkedBy": "Sei stato contrassegnato dal Maestro dei Quiz\nPer sopravvivere devi rispondere correttamente a questa domanda:\n\n{QMQUESTION}", - "QuizmasterChat.MarkedPublic": "{QMTARGET} è stato contrassegnato dal Maestro dei Quiz\nPer sopravvivere {QMTARGET} deve rispondere correttamente alla loro domanda!", + "QuizmasterChat.MarkedBy": "Sei stato marcato dal Maestro dei Quiz\nPer sopravvivere devi rispondere correttamente a questa domanda:\n\n{QMQUESTION}", + "QuizmasterChat.MarkedPublic": "{QMTARGET} è stato marcato dal Maestro dei Quiz\nPer sopravvivere {QMTARGET} deve rispondere correttamente alla loro domanda!", "QuizmasterChat.Answers": "Risposte\nA:{QMA}\nB:{QMB}\nC:{QMC}\n\nPer rispondere basta digitare /answer [answer letter]\n\nSe hai bisogno di ricontrollare la risposta e le domande basta usare /qmquiz", "QuizmasterChat.CorrectTarget": "Corretto", - "QuizmasterChat.Correct": "{QMTARGET} ha dato la risposta giusta!\nOra puoi contrassegnare qualcun altro!", + "QuizmasterChat.Correct": "{QMTARGET} ha dato la risposta giusta!\nOra puoi marcare qualcun altro!", "QuizmasterChat.CorrectPublic": "{QMTARGET} ha risposto correttamente alla domanda del Maestro dei Quiz ed è sopravvissuto!\nAttenzione al Maestro dei Quiz!", "QuizmasterChat.WrongTarget": "Sbagliato\nLa tua risposta era {QMWRONG}\nLa risposta corretta era {QMRIGHT}\n\nIl Maestro dei Quiz era {QM}", - "QuizmasterChat.Wrong": "{QMTARGET} ha dato la risposta sbagliata ed è morto!\nOra puoi contrassegnare qualcun altro!", + "QuizmasterChat.Wrong": "{QMTARGET} ha dato la risposta sbagliata ed è morto!\nOra puoi marcare qualcun altro!", "QuizmasterChat.WrongPublic": "{QMTARGET} ha risposto erroneamente alla domanda del Maestro dei Quiz ed è morto!\nAttenzione al Maestro dei Quiz!", - "QuizmasterChat.Marked": "Hai contrassegnato {QMTARGET}\nse {QMTARGET} non risponde alla fine della riunione oppure risponde erroneamente {QMTARGET} morirà\n\nDomanda per {QMTARGET} => {QMQUESTION}", + "QuizmasterChat.Marked": "Hai marcato {QMTARGET}\nse {QMTARGET} non risponde alla fine della riunione oppure risponde erroneamente {QMTARGET} morirà\n\nDomanda per {QMTARGET} => {QMQUESTION}", "QuizmasterChat.Title": "Informazioni sul Maestro dei Quiz", "QuizmasterChat.CantAnswer": "Come Maestro dei Quiz, non puoi rispondere alle domande", "QuizmasterChat.AnswerNotValid": "La tua risposta deve essere A, B, o C", @@ -3712,19 +3646,6 @@ "MinionAbilityTime": "Durata Abilità", "Minion_Blind": "accecato", "Evader_ChanceNotExiled": "Possibilità di non essere espulso", - "ShockerAbilityCooldown": "Ricarica Abilità", - "ShockerAbilityDuration": "Durata Abilità", - "ShockerAbilityPerRound": "Abilità Per Round", - "ShockerShockInVents": "Elettrifica persone nei condotti", - "ShockerAbilityResetAfterMeeting": "Reimposta le stanze contrassegnate dopo la riunione", - "ShockerOutsideRadius": "Raggio d'incarichi esterni (non in una stanza)", - "ShockerCanShockHimself": "Può Elettrificare Stesso", - "ShockerImpostorVision": "Shocker ha il campo visivo impostore", - "ShockerIsShocking": "Stai già elettrificando!", - "ShockerAbilityActivate": "Comincia l'Elettrificazione!", - "ShockerAbilityDeactivate": "Abilità Disattivata", - "ShockerVentButtonText": "Scossa", - "ShockerRoomMarked": "Stanza Contrassegnata", "EavesdropperMsgTitle": "Hai trovato un segreto", "EavesdropPercentChance": "Possibilità di origliare", "ChiefOfPoliceSkillCooldown": "Ricarica per reclutare sceriffi", @@ -3736,4 +3657,4 @@ "PolicPreventRecruitNonKiller": "Impedisci di reclutare giocatori senza pulsante uccidi", "PolicSuidiceWhenTargetNotKiller": "Si suicida quando reclutano un non assassino o non astronauta", "PolicPassConverted": "Puo passare Modificatore Convertito a Sceriffo" -} +} \ No newline at end of file diff --git a/Resources/Lang/ja_JP.json b/Resources/Lang/ja_JP.json index 04ee0edfb..6b628e1c6 100644 --- a/Resources/Lang/ja_JP.json +++ b/Resources/Lang/ja_JP.json @@ -20,8 +20,6 @@ "SubText.Neutral": "勝利を達成するために一人で働く", "SubText.Apocalypse": "チームと共に止められない存在になろう", "SubText.Madmate": " インポスターを助ける", - "SubText.Lovers": "生き延びて一緒に勝利を掴もう", - "SubText.Egoist": "自分だけで勝利を目指せ", "TypeImpostor": "インポスター", "TypeCrewmate": "クルーメイト", "TypeNeutral": "ニュートラル", @@ -31,9 +29,6 @@ "TeamNeutral": "ニュートラル", "TeamCrewmate": "クルーメイト", "TeamMadmate": "マッドメイト", - "TeamLovers": "恋人たち", - "TeamEgoist": "エゴイスト", - "TeamApocalypse": "黙示録", "YouAreCrewmate": "あなたはクルーメイトです", "YouAreImpostor": "あなたはインポスターです", "YouAreNeutral": "あなたはニュートラルです", @@ -225,7 +220,6 @@ "TaskManager": "タスクマネージャー", "Witness": "証人", "Swapper": "スワッパー", - "ChiefOfPolice": "警察署長", "NiceMini": "ナイスミニ", "Mini": "ミニ", "Spy": "スパイ", @@ -254,7 +248,6 @@ "Stalker": "ストーカー", "Workaholic": "ワーカホリック", "Solsticer": "ソルスティス", - "Abyssbringer": "深淵をもたらす者", "Collector": "コレクター", "Provocateur": "プロヴォカトゥール", "BloodKnight": "血の騎士", @@ -316,7 +309,7 @@ "Ghastly": "ゴース", "LastImpostor": "最後のインポスター", "Overclocked": "オーバークロック", - "Lovers": "恋人たち", + "Lovers": "恋人", "Madmate": "マッドメイト", "Watcher": "見守り人", "Flash": "閃光", @@ -393,8 +386,6 @@ "Sloth": "怠け者", "Prohibited": "禁止された者", "Eavesdropper": "立ち聞き", - "Shocker": "ショッカー", - "Revenant": "レヴナント(亡霊)", "BracketAddons": "アドオンに括弧を追加", "EngineerTOHEInfo": "通気口を使って インポスター を捕まえる", "ScientistTOHEInfo": "どこからでも携帯用バイタルにアクセス", @@ -513,7 +504,7 @@ "PacifistInfo": "キルのクールダウンをリセットするために通気口を使用", "RebirthInfo": "再び蘇る", "MonarchInfo": "クルーに追加の投票権を与える!", - "AbyssbringerInfo": "Place Black Holes", + "AbyssbringerInfo": "ブラックホールを創造する", "SpurtInfo": "ウサギのように跳ねる!", "StealthInfo": "部屋の中の全員がキルで目が見えなくなる", "PenguinInfo": "犠牲者を引きずる", @@ -538,7 +529,7 @@ "AdmirerInfo": "あなたと一緒に行動するプレイヤーを選ぶ", "TimeMasterInfo": "時間を巻き戻す!", "CrusaderInfo": "プレイヤーの攻撃者を倒す", - "AltruistInfo": "プレイヤーを蘇生する", + "AltruistInfo": "Revive a player\nVent to change between Revive and Report", "ReverieInfo": "各キルでクールダウンが減少", "LookoutInfo": "変装を見破る", "TelecommunicationInfo": "デバイスの使用状況を追跡する", @@ -547,7 +538,6 @@ "WitnessInfo": "最近誰かが殺人を犯したかを突き止める", "GhastlyInfo": "誰かを支配して!", "SwapperInfo": "2人のプレイヤーの投票を入れ替える", - "ChiefOfPoliceInfo": "保安官を雇い、クルーを守らせよう!", "NiceMiniInfo": "成長するまで誰もあなたに害を与えることはできません。", "ArsonistInfo": "誰もを浸す、そして点火する", "PyromaniacInfo": "誰もを浸して、誰もを殺す", @@ -603,7 +593,7 @@ "VultureInfo": "報告して体を食べて勝つ", "TaskinatorInfo": "サイレントなタスク、致命的な爆発", "BenefactorInfo": "タスク完了、盾はエリート!", - "MedusaInfo": "それらを報告して石にする", + "MedusaInfo": "Stone bodies by reporting them", "SpiritcallerInfo": "プレイヤーを邪悪な霊に変える", "AmnesiacInfo": "死体の役割を覚える", "ImitatorInfo": "プレイヤーの役割を真似る", @@ -615,19 +605,19 @@ "ShroudInfo": "プレイヤーを覆いで包んで、彼らに他のプレイヤーを倒させる", "WerewolfInfo": "仲間を一斉に襲撃", "ShamanInfo": "Voodoo 人形に対するすべての攻撃をかわす", - "SeekerInfo": "ターゲットとかくれんぼをする", + "SeekerInfo": "Play Hide and Seek with your target\nYour target has a ★ mark.", "PixieInfo": "『タグ付けて、袋詰めて、追放しよう!』", "OccultistInfo": "敵を殺して呪う", "SchrodingersCatInfo": "猫は観察されるまで生死の両方である。", "RomanticInfo": "共に勝利するためにパートナーを守る", "VengefulRomanticInfo": "共に勝利するために仇討ちする", "RuthlessRomanticInfo": "パートナーと一緒に勝利するために誰もを殺す", - "PoisonerInfo": "遅延キルで誰もを殺す", + "PoisonerInfo": "Kill everyone with delayed kills", "HexMasterInfo": "会議中にプレイヤーを殺すために呪う", "WraithInfo": "ベントを使って一時的に透明になる", - "JinxInfo": "攻撃を加える者に攻撃を反映させる", + "JinxInfo": "Reflect attacks onto your attackers", "PotionMasterInfo": "あなたのポーションを活用する", - "NecromancerInfo": "死を克服するためにあなたの殺人者を殺す", + "NecromancerInfo": "Kill your killer to defy death", "WardenInfo": "(幽霊) 危険を警告する", "MinionInfo": "(幽霊) 敵を盲目にする", "LoversInfo": "一緒に生き残って勝つ", @@ -708,8 +698,6 @@ "SlothInfo": "あなたは遅くなっています", "ProhibitedInfo": "特定のベントが封鎖されています", "EavesdropperInfo": "他の役割を盗み聞きする", - "ShockerInfo": "不意を突いてプレイヤーを驚かせる", - "RevenantInfo": "キラーの役割を奪え", "EngineerTOHEInfoLong": "(クルーメイト):\nエンジニアとして、通信妨害が非アクティブの間はベントを使用できます。", "ScientistTOHEInfoLong": "(クルーメイト):\nサイエンティストとして、いつでもバイタルを見ることができ、誰が生きていて誰が死んでいるかを確認できます。", "NoisemakerTOHEInfoLong": "(クルーメイト):\nノイズメーカーとして、あなたが死ぬたびに音が鳴り、あなたの死のビジュアルインジケーターが画面に表示されます。これにより、クルーメイトはあなたを殺した人を現行犯で捕まえるために走ってくるでしょう (たとえその人が赤でなくても)。", @@ -781,14 +769,14 @@ "LurkerInfoLong": "(インポスター):\n潜伏者として、クールダウンを一定の秒数短縮するためにベントに入ることができます。キルした後、クールダウンは元の値にリセットされます。", "VisionaryInfoLong": "(インポスター):\nビジョナリーとして、会議中に生存プレイヤーの陣営を見ることができます。以下の情報がプレイヤーに表示されます:\n\n- 赤い名前はインポスターを示します。\n- シアンの名前はクルーメイトを示します。\n- グレーの名前はニュートラルを示します。", "PlagueDoctorInfoLong": "(中立):\n(TOHのペスト医師)\nペストドクターの目標は、生きているすべてのプレイヤーを感染させることです。\n彼らは最初に一人のプレイヤーを感染させることから始め、その後、感染したプレイヤーの範囲内で設定された時間を過ごした人は誰でも自身が感染します。\n感染の進行は累積的であり、距離が離れたり会議後でもリセットされません。", - "RefugeeInfoLong": "(マッドメイツ):\n難民として、あなたは次のいずれかでした:\n -インポスターを思い出した記憶喪失者\n -ゴッドファーザーのターゲットを殺した殺人者\n -パートナーがインポスターだったロマンティック\n -インポスターを模倣した模倣者\n\n今、あなたの役割はインポスターを助けてクルーメイトを排除することです。", + "RefugeeInfoLong": "(マッドメイツ):\n避難民として、あなたは記憶喪失者であり、偽装者を思い出したか、またはゴッドファーザーの標的を殺害した殺人者でした。\n今はあなたの仕事はインポスターがクルーメイトを殺すのを手伝うことです。", "UnderdogInfoLong": "(インポスター):\nアンダードッグとして、一定数のプレイヤーが生存するまでキルできません。", "ConsigliereInfoLong": "(インポスター):\nコンシリエーレとして、キルボタンを使用して他のプレイヤーの役割を明らかにすることができます。\n\n1回クリック:役割を明らかにする\n2回クリック:キル\n\n明らかにする回数が尽きた場合、キルボタンは通常通り機能します。", "LudopathInfoLong": "(インポスター):\nルードパスとして、キルのクールダウンはランダム化されます。\n\n最小値は1秒で、最大値はデフォルトのキルクールダウンです。", - "GodfatherInfoLong": "(インポスター):\nゴッドファーザーとして、誰かをターゲットにするために投票します。\n次のラウンドで、もしそのターゲットが誰かに殺された場合、殺した人物は難民またはマッドメイツに変わります。", + "GodfatherInfoLong": "(インポスター):\nゴッドファーザーとして、誰かを選んで彼らをあなたのターゲットにします。次のラウンドで誰かがそのターゲットをキルした場合、キラーは難民に変わります。", "ChronomancerInfoLong": "(インポスター):\n時間魔術師として、虐殺の準備が整うときに示すチャージバーがあります。それが100%になると、次に誰かをキルしたときに虐殺モードに入ります。これにより、チャージがなくなるまで無限にキルすることができます。そうでない場合、通常のキルクールダウンがあります。", "PitfallInfoLong": "(インポスター):\nピットフォールとして、シェイプシフトを使用してシェイプシフトの周りのエリアをトラップとしてマークします。このエリアに入るプレイヤーは一時的に動けなくなり、視界も影響を受けます。", - "EvilMiniInfoLong": "(インポスター):\nイービルミニとして(邪悪な子供)、成長するまで不死身で、非常に長い初期キルのクールダウンがあります。成長するにつれてクールダウンが大幅に短縮されます。", + "EvilMiniInfoLong": "(インポスター):\nイービルミニとして、成長するまで不死身で、非常に長い初期キルのクールダウンがあります。成長するにつれてクールダウンが大幅に短縮されます。", "BlackmailerInfoLong": "(インポスター):\n恐喝者として、ターゲットに変身するとそのプレイヤーを脅迫します。これは、会議中にそのプレイヤーが話せなくなることを意味します。\n\n注意: すでに誰かが脅迫されている場合、別の人を脅迫すると現在の脅迫が解除されます。", "InstigatorInfoLong": "(インポスター):\n煽動者として、あなたの役割はクルーメイト同士を対立させることです。会議でクルーメイトが投票によって追放されるたびに、あなたが生きている限り、無実のプレイヤーに投票した追加のクルーメイトが会議後に死亡します。追加で死亡するプレイヤーの数はホストが決定します。", "LazyGuyInfoLong": "(クルーメイト):\n怠け者は1つのタスクしか持っていません。さらに、インポスターの能力は怠け者に影響を与えません。例えば、アノニマスのスケープゴートになること、ウォーロックやパペティアーによってマークされることなどはできません。怠け者にはアドオンはありません。", @@ -821,7 +809,7 @@ "GrenadierInfoLong": "(クルーメイト):\n擲弾兵(投擲者)として、近くのプレイヤーにフラッシュバングを使って視界を奪うことができます。これにより、インポスターは視界を失い、設定によってはニュートラルも同様です。", "MedicInfoLong": "(クルーメイト):\nメディックはキルボタンを押して対象にシールドを配置できます。メディックはゲーム全体で1つのシールドしか提供できず、メディックが死ぬと対象のシールドが削除されます。メディックはまた、誰かが対象のシールドを破ろうとしているかどうかを見ることもできます。\nホストの設定に応じて、メディックまたは対象がプレイヤーがシールドを持っているかどうかを見ることができます (名前の横に緑の円「●」として表示されます) 。", "FortuneTellerInfoLong": "(クルーメイト):\n占い師として、ミーティングでプレイヤーに投票して、彼らの役割に関する手がかりを得ることができます。手がかりは実際の役割に関連します。\n\n占い師のタスクが完了した場合、手がかりではなく正確な役割が分かります!\n\n注意:ランダムなアクティブプレイヤーをヒントとして与える設定がオンになっている場合、同じプレイヤーを複数回チェックすることはできません。", - "JudgeInfoLong": "(クルーメイト):\nジャッジは会議中に特定のプレイヤーを判断できます。対象が悪である場合、対象は殺されます (対象が悪であるかどうかはホストによって設定されます) 、間違っている場合、ジャッジは自殺します。\n判決コマンドは:/tl [プレイヤーID] です。\nプレイヤーの名前の前にプレイヤーのIDを見ることができます。また、すべてのプレイヤーのIDを表示するには/idコマンドを使用できます。\nジャッジはマッドメイトになるとすべてのプレイヤーを判断できます。", + "JudgeInfoLong": "(Crewmates):\nThe Judge can judge a certain player during the meeting. If the target is evil, the target will be killed (whether it is evil or not is set by the Host). If it is wrong, the Judge commits suicide.\nCommand for judgment: /tl [player id]\nYou can see the player's id before the player's name, or use the /id command to view the id of all players.\nJudges can judge all players when they become Madmate.\nIn meeting the ability count shows how many trails you have in this meeting. Out of meeting the ability counts shows how many trails you have for the whole game.", "MorticianInfoLong": "(クルーメイト):\nモーティシャンはすべての死体に矢印が指し示すのを見ることができ、モーティシャンが死体を報告すると、被害者が最後に接触したプレイヤーを知ることができます。注意:モーティシャンは気づかないまたは預言者ではありません。", "MediumInfoLong": "(クルーメイト):\nミディアムは死体が報告された後、死んだプレイヤーとコンタクトを取ることができます。報告するのはミディアムでなくてもかまいません。死んだプレイヤーはミディアムの質問にYESまたはNOで1回だけ答えることができます (死んだプレイヤーは/ms yesまたは/ms noを使用できます) 。注意:ミディアムはObliviousではありません。", "ObserverInfoLong": "(クルーメイト):\nオブザーバーとして、最初の会議後、他のプレイヤーによって引き起こされるすべてのシールドアニメーションを確認できます。これは通常、何らかの役割能力の使用を示しているので、注意が必要です。", @@ -833,7 +821,7 @@ "MerchantInfoLong": "(クルーメイト):\n 商人 、タスクを完了するごとに、ランダムなプレイヤーにランダムなアドオンを販売します。売ったアドオンごとにお金が入ります。一定額のお金を持っている場合、殺害を図った人に賄賂を与えることで次の殺害を回避できます。賄賂を受け取ったプレイヤーはあなたを殺すことができませんが、誰かは分かりません。使用した賄賂のお金は失われ、追加の賄賂には利用できません。", "RetributionistInfoLong": "(クルーメイト):\n ふくしゅうしゃ、 死後、限られた数のプレイヤーを殺害できます。\n使用方法: /ret [playerID] で殺害。", "HawkInfoLong": "(クルーメイト [幽霊]):\nホークとして、ホストが決めた限られた数のプレイヤーを殺すことができますが、外す可能性があります。何度も同じ人を斬ると命中率が上がります。", - "DeputyInfoLong": "(クルーメイト): \n副官 、 プレイヤーに対してキルボタンを使用して、そのプレイヤーのキルクールダウンをリセットします。\nターゲットにキルボタンがない場合、手錠は無駄になります。", + "DeputyInfoLong": "(Crewmates):\nAs the Deputy, use your kill button to handcuff a player.\nThe player who is handcuffed will have their next kill attempt treated as a handcuff break, and the kill cooldown will be reset.\n\nIf the target does not have a kill button, then the handcuff was a waste.", "InvestigatorInfoLong": "(クルーメイト):\n捜査官として、あなたは調査ボタンを使用して調査対象者を調べることができます。誰かを調査すると、彼らの名前は、キルボタンを持っている場合 (インポスター/SS基準) 、赤色で表示されるか、キルボタンを持っていない場合 (クルーメイト/エンジニア/科学者基準) 、薄い青色で表示されます。ただし、会議が開かれると、名前の色は通常に戻ります。", "GuardianInfoLong": "(クルーメイト):\nガーディアンとして、タスクの完了時に不死身になります。\nミーティングでも当てられない。", "AddictInfoLong": "(クルーメイト):\n中毒者として、自殺タイマーがあります。期限が切れると自殺します。\nタイマーは通気口のクールダウンによって示されます。通気口のクールダウンが0秒になると、まだ通気する時間があります。\nそれに間に合わない場合、死亡し、間に合った場合、自殺タイマーがリセットされます。\nまた、通気された後、一定の期間誰もあなたと対話できません。\nこの期間が終了すると、さらに一定の期間行動不能になり、死体を報告することはできません。", @@ -849,7 +837,7 @@ "AdmirerInfoLong": "(クルーメイト):\nファンとして、プレイヤーを賞賛してクルーメイトの陣営に変えることができます。彼らはクルーメイトと一緒に勝利し、元のチームでは勝利できません。\n\n1人のプレイヤーにつき1回しか実行できません。", "TimeMasterInfoLong": "(クルーメイト):\nタイムマスターとして、通気口を使用してすべてのプレイヤーの位置をマークします。\n能力を再度使用すると、生存しているすべてのプレイヤーがマークされた位置に巻き戻されます。\n\n能力の期間中、タイムマスターは死亡から保護するタイムシールドを獲得します。", "CrusaderInfoLong": "(クルーメイト):\nクルセイダーとして、キルボタンを使用してプレイヤーを十字軍のように討つことができます。\nそのプレイヤーが攻撃を受けると、あなたは攻撃者を殺します。", - "AltruistInfoLong": "(クルーメイト):\n利他主義者として、あなたは「報告」ボタンを使って自分を犠牲にし、死体を蘇生することができます。\n注: 死んだプレイヤーがゲームを退出した場合、その死体は通常どおり報告できます。\nまた、蘇生されたプレイヤーは自分の死体を報告することはできません。", + "AltruistInfoLong": "(Crewmates):\nAs the Altruist, you can sacrifice yourself to revive a dead body using the «Report» button.\nNote: If a dead player has left the game, you report that body normally.\nAlso revived player cannot report self dead body\nUse vent button to change between Report & Revive.", "ReverieInfoLong": "(クルーメイト):\n夢想として、キルできますが、クールダウンは高めです。\n\nクルーメイトをキルすると増加し、それ以外の場合は減少します。\nホストの設定によっては、最大キルクールダウンに達したときに誤射し、ターゲットがあなたと一緒に死ぬことがあります。\n\n他のクルーメイトと一緒に勝つことができます。", "LookoutInfoLong": "(クルーメイト):\nルックアウトとして、いつでもすべてのプレイヤーのIDを見ることができます。\nこれにより、シェイプシフトやカムフラージュを見破ることができます。", "TelecommunicationInfoLong": "(クルーメイト):\nテレコミュニケーションとして、誰かがカメラ、バイタル、ドアログ、または管理を使用すると通知されます。", @@ -872,7 +860,7 @@ "LawyerInfoLong": "(中立):\n弁護士は守るべき対象がおり、その対象は名前の横にダイヤモンド「♦」で表示されます。\n対象が勝利すれば、あなたも勝利します。\n彼らが負けると、あなたも負けます。", "OpportunistInfoLong": "(中立):\nもしオポチュニストがゲームの最後まで生き残れば、オポチュニストは勝利したプレイヤーと共に勝利します。", "VectorInfoLong": "(中立):\nマリオは一定回数吐き出すと単独で勝利します。", - "JackalInfoLong": "(中立):\nジャッカルとして、最後の生存者になれば勝利します。さらに、殺害ボタンを使ってリクルートすることが可能です。\nただし、ターゲットがリクルート不可能な場合、使用回数を使い果たしている場合、またはリクルートオプションがない場合は、通常通りに殺害します(リクルートできると思って他人の前で殺害ボタンを押さないでください) 。\nターゲットが殺害ボタンを持ち、サイドキックに変わるオプションがオンの場合、ターゲットはサイドキックになります。それ以外の場合、リクルートアドオンを与えるオプションがオンなら、ターゲットはリクルートアドオンを獲得します。\n設定によっては、ジャッカルが殺された場合、ランダムにサイドキックが新たなジャッカルとして選ばれます。サイドキックがいない場合、リクルートが選ばれる場合があります。", + "JackalInfoLong": "(中立):\nジャッカルとして、最後の生存者になると勝利します。さらに、殺害ボタンを使用してリクルートすることができます。ターゲットがリクルート可能ではない場合、リクルートの使用回数を使い果たしている場合、またはリクルートオプションがない場合は、通常通りに殺害します (つまり、リクルートすると思って他人の前で殺害ボタンを使用しないでください)。ターゲットに殺害ボタンがあり、サイドキックに変わるオプションがオンの場合は、サイドキックになります。それ以外の場合は、リクルートアドオンを与えるオプションがオンの場合はリクルートアドオンを獲得します。", "GodInfoLong": "(中立):\n神として、最初から全員の役割を知っています。ゲームの最後まで生き残れば、勝利を手に入れます。つまり、他の全員が負けてあなたが勝ちます。", "InnocentInfoLong": "(中立):\nイノセントはキルボタンを使用して任意のプレイヤーを植え付けることができ、植え付けられた対象は即座にイノセントを殺害します。対象が会議で投票により追放されると、イノセントが勝利します。注:道化師、執行者、およびイノセントは一緒に勝利することができます。", "PelicanInfoLong": "(中立):\nペリカンとして、キルボタンを使用してプレイヤーを生きたまま飲み込み、マップ外にテレポートしますが、すぐには殺害しません。飲み込まれたプレイヤーは、ラウンドの終わりにあなたがまだ生きている場合のみ死亡します。ラウンド中に死亡したり離れたりすると、生存している飲み込まれたプレイヤーはあなたがいた場所にマップ内で再出現します。", @@ -884,14 +872,14 @@ "SolsticerInfoLong": "(中立):\nソルスティスとして、あなたは死ぬことはありません。一回のラウンドで全てのタスクを完了させることで勝利します。会議が終わるたびに、タスクはリセットされ、最初からやり直さなければなりません。\nソルスティスに対する投票は直接キャンセルされます。\nソルスティスに対する殺害試みは、会議が終了するまでペリカンのようにマップ外へテレポートさせます。\nキラーのキルクールダウンは10秒にリセットされます。", "CollectorInfoLong": "(中立):\nコレクターとして、プレイヤーに投票すると、そのプレイヤーに投票した他のプレイヤー1人につき1ポイントを獲得します。必要な投票数を集めると、ジェスターやエグゼキューショナーのターゲットを追放しても、ゲームが終了し、あなたは単独で勝利します。", "GlitchInfoLong": "(中立):\nグリッチとして、プレイヤーをハックする (シングルクリック) か通常通り殺害する (ダブルクリック) ことができます。ハックされたプレイヤーは、ハックの期間中、殺害、ベント、報告をすることができません。さらに、ドア以外の妨害を呼び出すと効果がなく、ランダムなプレイヤーに変装します。妨害中または後に変装することはできません。勝利するためには、最後の生存プレイヤーである必要があります。", - "SidekickInfoLong": "(中立):\nサイドキックとして、あなたの役割はジャッカルを助けて全員を排除することです。\nあなたとジャッカルは一緒に勝利します。\n設定によっては、元のジャッカルが殺された場合に新しいジャッカルになることがあります。\n元のジャッカルが死ぬまで、殺害ができない場合もあります。", + "SidekickInfoLong": "(中立):\nサイドキックとして、あなたの仕事はジャッカルが誰もを殺すのを手伝うことです。\n\nあなたとジャッカルは一緒に勝利します。", "ProvocateurInfoLong": "(中立):\nプロヴォケーターはキルボタンで任意のターゲットを殺すことができます。ゲームの最後にターゲットが負けると、プロヴォケーターは勝利チームと一緒に勝利します。", "BloodKnightInfoLong": "(中立):\n血の騎士は、最後のキル役が生き残り、クルーメイトの数がブラッドナイトの数以下または同じ場合に勝利します。ブラッドナイトは、各キルの後に一時的なシールドを獲得し、数秒間不死身になります", "PlagueBearerInfoLong": "(黙示録):\nプレイグベアラーとして、キルボタンを使用して誰もがペスティレンスに変身するために皆を感染させます。\nペスティレンスに変身したら、不死でキルの能力を獲得します。\nさらに、ペスティレンスに変身した後、あなたを殺そうとする誰もがあなたを殺します。\nまた、感染したプレイヤーが未感染のプレイヤーと接触すると、そのプレイヤーも感染します。", "PestilenceInfoLong": "(黙示録):\nペスティレンスとして、あなたは止められない機械です。\nあなたへの攻撃はすべて反射されます。\n間接的な殺害すらあなたを倒しません。\nペスティレンスを倒す唯一の方法は、投票または誤った予想です。\n変身すると、会議で全員にあなたの存在が知らされます。", "SoulCollectorInfoLong": "(黙示録):\n魂の収集者として、キルボタンを使ってプレイヤーの死亡を予測できます。ターゲットが選択したラウンド中か、その後の会議で死亡した場合、魂を獲得します。\n\nターゲットは各会議後、または死亡した時点でリセットされます。 \n\n設定可能な数の魂を集めると、“死”になります。また、パッシブ魂獲得設定が有効の場合、会議ごとに魂を1つ獲得します。", "DeathInfoLong": "(黙示録):\n魂の収集者が必要な魂を集めると、“死”になります。“死”は、次の会議の終了までに追放されなければ、全員をキルして勝利します。\n\n“死”に変身する会議では、設定可能な追加の会議時間が与えられ、“死”を見つけるための議論ができます。\n\nあなたは無敵であり、変身後の会議でその存在が全員に知らされます。", - "BakerInfoLong": "(黙示録):\nパン職人として、ラウンドごとにプレイヤーにパンを与えるためにキルボタンを使用できます。パンを持つプレイヤーが設定数に達すると、“飢饉”になります。\n\nパンに追加の効果があり、その設定がオンの場合、通気口に入って与えるパンの種類を変更できます。 \n\nパンの効果:\n\n開示: 対象の役割がパン職人に明かされます (ゲーム全体を通して維持されます)\nロールブロック: 対象のキルクールダウンが999に設定されます (会議後に通常に戻ります)\nバリア: 対象にバリアを与えますが、それはパン職人にのみ知られています (会議後にバリアは消えます)", + "BakerInfoLong": "(Apocalypse):\nAs the Baker, you can use your kill button on a player per round to give them bread. \nOnce a set amount of players are alive with bread, you become Famine.\n\nIf the Bread gives additional effects and the setting is on, then you can vent to change the bread that you give out. \nBread Effects:\nReveal: Reveals the target's role to the Baker (stays the whole game)\nRoleblock: Resets the target's kill cooldown when they try to use their kill button\nBarrier: Gives the target a barrier that is only known to the Baker (barrier is removed after the meeting)", "FamineInfoLong": "(黙示録):\nパン職人が設定された数のパンを持つプレイヤーを生存させると、“飢饉”になります。会議後に飢饉が追放されなかった場合、“飢饉”となり、パンを持っていないプレイヤー (他の黙示録メンバーを除く) は餓死します。\n\nパンを持っていないプレイヤーの餓死後、飢饉はキルボタンを使用して残りのプレイヤーを飢えさせることができ、次の会議直前にそのプレイヤーをキルします。\n\nあなたは無敵であり、変身後の会議でその存在が全員に知らされます。", "BerserkerInfoLong": "(黙示録):\n狂戦士として、キルごとにレベルが上がります。ホストが設定したレベルに達すると、新しい能力を解放します。\n\nスカベンジャーキルは、自分のキルを消失させます。\n爆弾キルは、キルした対象を爆発させます。キルする際には注意が必要で、他の黙示録メンバーが近くにいると巻き込まれることがあります。 \nあるレベルに達すると、“戦争”になります。", "WarInfoLong": "(黙示録):\n戦争として、あなたは無敵で、キルのクールダウンが短く、以前の能力で誰でもキルすることができます。\n変身すると、会議で全員にあなたの存在が知らされます。", @@ -911,12 +899,11 @@ "TraitorInfoLong": "(中立):\n裏切り者として、私は詐欺師を裏切った詐欺師でした。\nあなたは詐欺師のことを知っていますが、彼らはあなたのことを知りません。\nでもトリック? 彼らはあなたを殺すことができますが、あなたは彼らを殺すことはできません。\n他の手段で詐欺師を排除し、他の全員を倒して勝利してください!", "TrollerInfoLong": "(中立):\nトローラーとして、タスクを完了させることで、プレイヤーにランダムなイベントを発生させることができます。例えば、全プレイヤーのスピードを変えたり、テレポートさせたり、サボタージュに影響を与えたりすることができます。また、勝利チームと共に勝利することができます。", "VultureInfoLong": "(中立):\nハゲタカとして、死体を通報して勝ちましょう!\n死体を報告すると、食べるクールダウンがリセットされていれば、その死体を食べることができるようになります (その後は報告できなくなります)。\n食べる能力がクールダウン中の場合は、通常どおり死体を報告します。\nまた、ラウンドあたりの食事の最大数に達した場合、死体は通常通り報告されます。", - "AbyssbringerInfoLong": "(インポスター):\n深淵をもたらす者として、ブラックホールを設置することができます。\nブラックホールはプレイヤーを吸い込み、接触すると殺害します。", "TaskinatorInfoLong": "(中立):\nタスキネーターとして、タスクを完了するたびにそのタスクは爆弾を設置されます。別のプレイヤーが爆弾付きのタスクを完了した時、爆弾が爆発してそのプレイヤーは死亡します。\n\nクルーが勝利しない状況で最後まで生き残れば勝ちです。\n\n 注意:タスキネーターの爆弾はあらゆる保護を無視します。", "BenefactorInfoLong": "(クルーメイト):\n恩人として、タスクを完了すると、そのタスクはマークされます。別のプレイヤーがマークされたタスクを完了すると、一時的な盾が得られます。\n\n注:盾は直接の攻撃からのみ保護します。", - "MedusaInfoLong": "(中立):\nメデューサとして、あなたは死体を石化することができます。あなたは死体を掃除するのと同じように死体を石化させます。石化した死体は報告できません。\n全員を倒して勝ちます。", + "MedusaInfoLong": "(Neutrals):\nAs the Medusa, you can stone bodies much like cleaning a body.\nStoned bodies cannot be reported.\n\nKill everyone to win.", "SpiritcallerInfoLong": "(中立):\n精霊召喚師として、あなたの犠牲者は死後、悪霊になります。これらの悪霊は、他のプレイヤーを一時的に凍らせたり、視界を遮ったりして攻撃することができます。また、殺人未遂からあなたを守る一時的な盾を与えることもできます。", - "AmnesiacInfoLong": "(中立):\n記憶喪失者として、リポートボタンを使用してターゲットを記憶し、その役割を引き継ぐことができます。\nゲームバランスを保つため、記憶した役割がベントを使用できない場合、記憶喪失者としてもベントを使用することはできません。", + "AmnesiacInfoLong": "(中立):\n記憶ボタンを使用して役職を思い出すアムネジアックとして行動します。\n対象がインポスターだった場合、難民になります。\n対象がクルーだった場合、互換性があれば対象の役職になります (それ以外の場合はエンジニアになります) 。\n対象が受動的な中立か特定されていない中立キラーだった場合、設定で定義された役職になります。\n対象が選ばれた中立キラーだった場合、彼らの役職になります。", "ImitatorInfoLong": "(中立): \n模倣者として、あなたのキルボタンを使用してプレイヤーを模倣してください。\n\nあなたはシェリフ、難民、またはいくつかのニュートラルになるでしょう。", "BanditInfoLong": "(中立):\n山賊として、キルボタンを1回クリックするとプレイヤーのアドオンを盗み、2回クリックするとキルが可能です。設定に応じて、アドオンは即座に盗むか、会議開始後に盗むかが決まります。最大の盗み回数に達した後は、通常通りキルが行われます。また、ターゲットに盗めるアドオンがない場合やターゲットが頑固な場合、ターゲットをキルします。\n\n全員を倒して勝ちます。\n\n注: 浄化されたプレイヤー、ラストインポスター、およびラヴァーズのアドオンは盗むことができません。\n注:「バンディットがベントを使える」が有効な場合、器用なプレイヤーから盗むのがより困難になります。", "DoppelgangerInfoLong": "(中立):\nドッペルゲンガーとして、キルボタンを使用してプレイヤーのアイデンティティ (名前とスキン) を奪い、ターゲットを殺します。\n\n全員を倒して勝ちます。\n\n注: 迷彩が有効な場合、ターゲットのアイデンティティを奪うことはできません。", @@ -925,14 +912,14 @@ "ShroudInfoLong": "(中立):\n覆いとして、あなたは通常殺さない。\n代わりに、プレイヤーを包むためにあなたのキルボタンを使用してください。\n包まれたプレイヤーは他の人を殺します。\n包まれたプレイヤーが殺害を行わなければ、会議の後に自分自身を殺すでしょう。\n\n覆いは、名前の隣に「◈」マークがある包まれたプレイヤーを見ます。\n殺害を行わなかった包まれたプレイヤーも、会議で「◈」マークを持っており、会議の終わりまでに覆いが生きていれば死にます。", "WerewolfInfoLong": "(中立):\nウェアウルフとして、あなたは通常の殺人者と同じように殺すことができます。\nただし、倒すと近くのプレイヤーも死んでしまいます。\nこれにより死亡したプレイヤーの死因は「Mauled」としてリストされます。\n\nこれをバランスさせるために、彼は他の誰よりも高いキルクールダウンを持っています。", "ShamanInfoLong": "(中立):\nシャーマンとして、ラウンドごとに一度、キルボタンを使用してブードゥー人形を選択できます。キルボタンがあなたに使用された場合、その効果はブードゥー人形に反射されます。最後まで生き残れば、勝利チームと一緒に勝利します。\n注意: キラーが選択されたターゲットを殺せない場合、殺害はキャンセルされますが、キラーが再度シャーマンを確認した場合、シャーマンが殺されます。", - "SeekerInfoLong": "(中立):\nシーカーとして、キルボタンを使用してターゲットにタグを付けることができます。シーカーが間違ったプレーヤーにタグを付けた場合はポイントが減り、シーカーが正しいプレーヤーにタグを付けた場合はポイントが追加されます。さらに、シーカーは次のことを行うことができます」 会議後、および新しいターゲットを獲得した後は 5 秒間移動しないでください。\n\n勝つためには、ホストが設定した一定数のポイントを集める必要があります。", + "SeekerInfoLong": "(Neutrals):\nAs the seeker, use your kill button to tag the target. If the seeker tags the wrong player, a point is deducted, and if the seeker tags the correct player, a point will be added.\nAdditionally, the seeker will not be able to move for 5 seconds after every meeting and after getting a new target.\n\nThe seeker needs to collect a certain number of points set by the Host to win.\nSeeker will see a ★ mark on target's name.", "PixieInfoLong": "(中立):\nピクシーとして、各ラウンドでキルボタンを使用して最大x人のターゲットにマークを付けます。会議が始まると、マークされたターゲットのうちの1人を追放することがあなたの仕事です。もし成功しなければ、ターゲットをマークしなかった場合や全てのターゲットが死んでいる場合を除いて、自殺します。会議が終了すると選択されたターゲットは0にリセットされます。成功するとポイントが得られます。あなたのターゲットは色付きの名前で表示されます。\n\n勝利チームとともに勝利するには、ホストによって設定された特定のポイント数が必要です。", "SchrodingersCatInfoLong": "(中立):\nシュレーディンガーの猫として、誰かがあなたに対してキルボタンを使用しようとすると、その行動をブロックして彼らのチームに加わります。このブロック能力は1回しか使用できません。デフォルトでは、勝利条件がありません。つまり、チームを変えた後に勝利します。\nさらに、このゲームではあなたは存在しないものとして数えられます。\n\n注意: キリングマシンがあなたに対してキルボタンを使用しようとした場合、その相互作用はブロックされず、あなたは死亡します。", "RomanticInfoLong": "(中立):\nロマンティック」では、「彼女を殺す」ボタンを使用して恋人のパートナーを選択できます (これはゲームのどの時点でも行うことができます)。 パートナーを選択したら、キルボタンを使用して一時的なシールドを与えることができます。 この盾は攻撃から身を守ります。 恋人が死亡した場合、恋人の役割は以下の条件に従って変化します。\n\nパートナーが詐欺師の場合、ロマンチックな人は難民になります。\nあなたのパートナーが中立的な殺人者であれば、あなたは冷酷なロマンチストになります。\nパートナーがクルーメイトまたは非殺人者ニュートラルの場合、ロマンティックはリベンジロマンティックになります。\nパートナーが勝てば、ロマンチックな人も勝ちます。\n注: 役割が変化すると、勝利条件もそれに応じて変化します。", "RuthlessRomanticInfoLong": "(中立):\nあなたのパートナー (ニュートラルキラー) が殺されると、あなたの役割はロマンティックから変わります。無慈悲なロマンティックとして、あなたの勝利条件は、全員が死ぬまで全員を殺し、最後に生き残ることです。あなたが勝てば、あなたの死んだパートナーはあなたと一緒に勝ちます", "VengefulRomanticInfoLong": "(中立):\nあなたのパートナー (乗組員または非中立的殺人者) が殺された場合、あなたの役割はロマンティックから変わります。復讐的ロマンティックとして、あなたの目標はパートナーに復讐することです。つまり、パートナーの殺人者を殺さなければなりません。 つまり、あなたとあなたのパートナーは、最終的には勝者チームで勝つことになります。パートナーを殺した人以外の誰かを殺そうとすると、不発で死ぬことになります。", - "PoisonerInfoLong": "(中立):\n毒殺者として、あなたの殺害は遅れます。\n勝つために全員を殺してください。", - "HexMasterInfoLong": "(中立):\nヘックスマスターとして、プレイヤーに呪詛をかけるか、彼らを殺害することができます。プレイヤーに呪詛をかけることは、魔女として呪文をかけるのと同じ方法で機能します。", + "PoisonerInfoLong": "(Neutrals):\nAs the Poisoner, your kills are delayed.\nKill everyone to win.", + "HexMasterInfoLong": "(Neutrals):\nAs the Hex Master, you can hex players or kill them.\nHexing a player works the same as spelling as a Witch.", "WraithInfoLong": "(中立):\nレイスとして、ベントを使用して一時的に姿を消すことができます。画面上では見えている状態が維持されます。再びベントすると、再び見えるようになります。最後の生存プレイヤーであれば勝利します。", "JinxInfoLong": "(中立):\nジンクスとして、攻撃されるたびに相手を呪い、呪いで相手を死に至らしめます。これには使用回数が限られています。全員を倒すと勝利します。", "PotionMasterInfoLong": "(中立):\nポーションマスターとして、あなたは 3 つのポーションを持っており、彼は 3 つの異なるアクションに割り当てます。\nシングルクリック: プレーヤーの役割を表示\nダブルクリック: プレイヤーをキルします\nマップ: サボタージュ\nショープレイヤーの役割ポーションには制限があります。 ポーションが完成すると、キルボタンはデフォルトでキルに切り替わります。", @@ -958,7 +945,7 @@ "ParanoiaInfoLong": "(アドオン):\n中立者やマッドメイトには割り当てられません。パラノイアとして、ゲーム終了の判断において、キラーが多数派を占めたときに2人のプレイヤーとしてカウントされます。さらに、オプションによっては追加の投票権が与えられます。", "MimicInfoLong": "(アドオン):\n「模倣者」になれるのは詐欺師だけです。 ミミックが死亡すると、会議が開催されるたびに、他の詐欺師はミミックによって殺されたプレイヤーに関する情報を含むメッセージを受信します。", "GuesserInfoLong": "(アドオン):\nゲッサーは会議中にプレイヤーの役職を推測して殺すために役立ちます。誤った推測はあなたを殺します。推測のコマンドは次のとおりです:/bt [プレイヤーID] [role] プレイヤーの名前の前にプレイヤーIDを表示できます、またはすべてのプレイヤーのIDを表示するために/idコマンドを使用できます。", - "NecroviewInfoLong": "(アドオン):\n「ネクロビュー」は死亡したプレイヤーのチームを見ることができます。会議中に死んだプレイヤーの名前には以下の情報が表示されます:- 赤い名前はインポスターを示します。- シアンの名前はクルーメイトを示します。- グレーの名前はニュートラルを示します。", + "NecroviewInfoLong": "(Add-ons):\nThe Necroview can see the teams of dead players. The following info will be displayed on the dead player's name while in a meeting:\n- The Red name indicates the Impostors.\n- The Cyan name indicates the Crewmates.\n- The Gray name indicates the Neutrals.", "ReachInfoLong": "(アドオン):\nキルボタンを持つ役割のみがこのアドオンを取得できます。他のすべてのプレイヤーとは異なり、あなたはゲーム内で最長のキル範囲を持っています。", "BaitInfoLong": "(アドオン):\nおとりが死ぬと、おとりを殺した犯人が自動的におとりの死体を報告します。ただし、スカベンジャー、クリーナー、スウーパー、レイス、メデューサ、または殺人マシンが おとり を殺した場合、この報告は行われません。報告にはホストの設定に応じて遅延が生じる場合があります。", "TrapperInfoLong": "(アドオン):\n「ベアトラップ」が殺されると、ベアトラップは殺人者を設定可能な時間だけ動けなくします。", @@ -981,7 +968,7 @@ "RebirthInfoLong": "(アドオン):\n再生として、あなたが追放される際、あなたに投票したランダムなクルーメイトとスキンを交換します。\n注意: ホストの投票はカウントされません。\n再生をすべて使い果たした場合、再生の能力は失われます。", "LoyalInfoLong": "(アドオン): \n忠実な役割として、あなたはジャッカルやカルトなどの役割に勧誘されません。中立役には割り当てられません。", "EvilSpiritInfoLong": "(アドオン):\n邪悪なスピリットとして、あなたの仕事はスピリットコーラーを勝利に導くことです。ハントボタンを使用してプレイヤーを凍結させ、視界を制限することができます。また、ハントボタンを使用してスピリットコーラーがキルの試みに対するシールドを一時的に得ることもできます。", - "RecruitInfoLong": "(裏切りアドオン):\nリクルートとして、あなたはジャッカルのチームに所属し、ジャッカルとそのサイドキックを支援します。\n元のチームと一緒に勝利することはできません。\n設定によっては、元のジャッカルが殺されてサイドキックがいない場合、新たなジャッカルになることがあります。", + "RecruitInfoLong": "(裏切りのアドオン):\nリクルートとして、あなたはジャッカルのチームに所属し、ジャッカルとそのサイドキックを支援します。\n元のチームでは勝てません。", "AdmiredInfoLong": "(裏切りのアドオン):\n賞賛されたプレイヤーとして、クルーと一緒に勝利し、元のチームでは勝利できません。\n\nファンを見ることができます。", "GlowInfoLong": "(アドオン):\n停電中、あなたと近くにいるプレイヤーは視界が広がります。", "RadarInfoLong": "(アドオン):\nレーダーとして、常に最も近くにいる人を指す矢印が表示されます。", @@ -1022,10 +1009,9 @@ "DollMasterInfoLong": "(インポスター):\nドールマスターとして、シェイプシフトボタンを使って任意のプレイヤーを一時的に操作し、あなたの行為を行わせることができます!", "DoubleAgentInfoLong": "(インポスター):\n二重スパイとして、キルボタンにはアクセスできません。しかし、会議で誰かに投票することで、そのプレイヤーに爆弾を渡すことができ、一度に1人にしか渡せません。会議が終了すると、爆弾は一定時間後に作動し、爆発します。\n注: 会議中に誰かに爆弾を渡した後、さらに投票することができます。\n\nまた、設定に応じて、二重スパイはベント中にバスティオンやアジテーターの爆弾を解除できることがあります。\n\n二重スパイは、最後のインポスターとなったときに役割を変更することができ、設定に応じて、役割が尊敬されるインポスター、いたずら者、裏切り者、または二重スパイのままになることがあります。", "SlothInfoLong": "(アドオン):\n怠け者のデフォルト移動速度は他のプレイヤーよりも遅いです (速度はホストの設定に依存します)。", - "ProhibitedInfoLong": "(アドオン):\n禁止された者として、使用できない特定のベントがあります。\n無効化されるベントの数はホストの設定によって決まります。", - "EavesdropperInfoLong": "(アドオン):\n立ち聞きとして、葬儀屋や探偵のように、他の役職やアドオンに基づく情報メッセージを読むチャンスがあります。", - "ApocalypseInfoLong": "(黙示録):\n黙示録のメンバーは、独自のチームに所属し、一緒に行動して勝利を目指します。\nゲーム内に複数の黙示録役職がある場合、互いの役職を確認することができます。\nホストの設定によっては、黙示録役職が推測を行ったり、推測されることが可能です。", - "RevenantInfoLong": "(中立):\nレヴナント(亡霊)として、あなたの目標は殺されることです。\nもし殺されると、あなたは殺した相手の役職を奪い、その相手を逆に殺害します。\n殺される前に勝利することはできません。\nなお、レヴナント(亡霊)の能力は直接殺される場合のみ有効です。", + "ProhibitedInfoLong": "(アドオン)\n妨害者 使用できない特定のベントがあります.\nいくつのベントが使用不可になるかは, ホストの設定によります.", + "EavesdropperInfoLong": "(アドオン):\n盗聴者, 他の役を読むチャンスがありますか/アドオン\n情報化メッセージ, ような 葬儀屋和探偵.", + "ApocalypseInfoLong": "(Apocalypse):\nApocalypse members are on a separate team that works together and wins together. If there are multiple Apocalypse roles in the game, they can see each other's roles.\nDepending on the Host's settings, Apocalypse roles can guess or be guessed.", "ShowTextOverlay": "テキストオーバーレイ", "Overlay.GuesserMode": "ゲッサーモード", "Overlay.NoGameEnd": "ゲーム終了なし", @@ -1039,8 +1025,6 @@ "AbilityUseLimit": "初期の能力使用制限", "AbilityInUse": "能力が使用中", "AbilityExpired": "アビリティの期限切れ、{0} 回使用可能", - "RevenantTargeted": "役職が{0}に変更されました", - "RevenantCanCopyAddons": "アドオンを盗むことができます", "ShowArrows": "ボディを指し示す矢印があります", "ArrowDelayMin": "最小の矢印表示遅延", "ArrowDelayMax": "最大の矢印表示遅延", @@ -1370,8 +1354,6 @@ "ShieldedCanUseKillButton": "シールドされたプレイヤーは能力/キルボタンを使用できる", "PlayerIsShieldedByGame": "プレイヤーはゲームによって守られています!", "LegacyNemesis": "レガシーバージョンを使用", - "LegacyParasite": "レガシーバージョンを使用", - "LegacyTraitor": "レガシーバージョンを使用", "ArsonistKeepsGameGoing": "アーソニスト がゲームを続けます", "ArsonistCanIgniteAnytime": "いつでも点火できる", "ArsonistMinPlayersToIgnite": "点火に必要な最小投与量", @@ -1381,13 +1363,13 @@ "DollMasterPossessionDuration": "支配の持続時間", "DollMasterCanKillAsMainBody": "本体として殺すことができる", "DollMasterTargetDiesAfterPossession": "憑依後に対象が死亡", - "DoubleAgentCanDiffuseBombs": "ダブルエージェントは他の役職の爆弾を解除できます", + "DoubleAgentCanDiffuseBombs": "Double Agent can diffuse bombs from other roles", "DoubleAgentClearBombOnMeetingCall": "会議が召集されるときにアクティブな爆弾を解除する", "DoubleAgentCanUseAbilityInCalledMeeting": "解除に成功すると、召集された会議で能力を使用できる", "DoubleAgentBombExplosionTimer": "爆発の時間", "DoubleAgentExplosionRadius": "爆発の半径", - "DoubleAgent_DiffusedAgitaterBomb": "アジテーターの爆弾を成功裏に解除しました", - "DoubleAgent_DiffusedBastionBomb": "バスティオンの爆弾を成功裏に解除しました", + "DoubleAgent_DiffusedAgitaterBomb": "Agitator bomb successfully diffused", + "DoubleAgent_DiffusedBastionBomb": "Bastion bomb successfully diffused", "DoubleAgent_BombExplodesIn": "爆弾が爆発するまで: {0}秒", "DoubleAgent_BombExploded": "爆弾が爆発しました!", "DoubleAgentChangeRoleTo": "最後のインポスターで役割を変更", @@ -1514,18 +1496,6 @@ "SheriffCanKillSeparately": "個別の設定", "In%team%": "(チーム%team%)", "SheriffMisfireKillsTarget": "誤射でターゲットを倒す", - "BlackHolePlaceCooldown": "ブラックホール設置のクールダウン", - "BlackHoleDespawnMode": "ブラックホール消滅モード", - "BlackHoleDespawnTime": "ブラックホール消滅後の時間", - "Abyssbringer.Suffix": "<#00ffa5>現在のブラックホールによって飲み込まれたプレイヤー数: {0} <#00ffa5>アクティブなブラックホール:\\n{1}", - "Abyssbringer.Suffix.BlackHole": "<#00ffa5>{0}: {1}", - "BlackHoleMovesTowardsNearestPlayer": "ブラックホールが最も近いプレイヤーに向かって移動します", - "BlackHoleMoveSpeed": "ブラックホールの移動速度", - "BlackHoleRadius": "ブラックホールの吸引半径", - "AfterTime": "時間経過後", - "After1PlayerEaten": "1人が飲み込まれた後", - "AfterMeeting": "会議後", - "None": "なし", "SheriffShotLimit": "最大キル数", "SheriffCanKillAllAlive": "誰も死んでいなければ、誰かを殺すことができます。", "SheriffCanKillCharmed": "魅了 されたプレイヤーを殺すことができます", @@ -1542,15 +1512,12 @@ "RebirthUses": "再生の回数", "RebirthCountVotes": "自分に投票したプレイヤーにのみ再生する", "RebirthFailed": "ああ、残念。入れ替えるための適切な魂が見つかりませんでした。", - "FireworkerCooldown": "設置クールダウン", "ReverieIncreaseKillCooldown": "キルクールダウンを増加", "ReverieMaxKillCooldown": "最大キルクールダウン", "ReverieMisfireSuicide": "最大キルクールダウンに達した際の誤射", "ReverieResetCooldownMeeting": "会議後にキルクールダウンをリセット", "ConvertedReverieKillAll": "変換された夢想は、報復を受けることなく誰でも殺害できます。", "VigilanteNotify": "君は滅ぼすことを誓ったものそのものになった", - "DictatorChangeCommandToExpel": "ディクテーター は投票ではなくコマンドを使って追放する", - "DictatorExpelSelf": "待て待て待て、何が起きてるんだ?!マジで自分を追放しようとしてる…", "DoctorTaskCompletedBatteryCharge": "バッテリーの持続時間", "SnitchEnableTargetArrow": "ターゲットへの矢印を見る", "SnitchCanGetArrowColor": "チームカラーに基づいて色分けされた矢印を見る", @@ -1624,6 +1591,7 @@ "TimeThiefDecreaseMeetingTime": "会議時間を短縮する", "TimeThiefLowerLimitVotingTime": "最小投票時間", "TimeThiefReturnStolenTimeUponDeath": "死亡時に盗まれた時間を返す", + "TimeThiefMaxTimeOnAdmired": "Maximum Meeting Time if Time Thief Is Admired", "EvilTrackerCanSeeKillFlash": "キルフラッシュを見ることができる", "EvilTrackerCanSeeLastRoomInMeeting": "会議中にターゲットの最後の部屋を見ることができる", "EvilTrackerTargetMode": "ターゲットを設定できる", @@ -1631,7 +1599,6 @@ "EvilTrackerTargetMode.OnceInGame": "ゲーム内で1回", "EvilTrackerTargetMode.EveryMeeting": "すべての会議で", "EvilTrackerTargetMode.Always": "いつでも", - "ScavengerHasCustomDeathReason": "カスタム死亡理由を有効化", "EvilHackerCanSeeDeadMark": "死体の位置を感知", "EvilHackerCanSeeImpostorMark": "他のインポスターの位置が見える", "EvilHackerCanSeeKillFlash": "キルフラッシュを見ることができる", @@ -1639,9 +1606,9 @@ "EvilHackerMurderNotify": "での殺害", "EvilHackerLastAdminInfoTitle": "直前の管理情報", "EvilHackerDeadbody": "死亡", - "Ventguard": "ベントガード", + "Ventguard": "Ventguard", "VentguardInfo": "通気口に入ることでブロック", - "VentguardInfoLong": "(クルーメイト):\nベントガードとして、ベントに入ってそれをブロックすることができます。\nブロックされたベントには誰も入ることができませんが、設定によってはクルーメイトのみが入れる場合があります。\nブロックされたベントは会議ごとにリセットされます。", + "VentguardInfoLong": "(Crewmates):\nAs the Ventguard, you can enter vents to block them. No one can enter blocked vents, except Crewmates, if the setting is on. Blocked vents can be resets every meeting.", "VentguardVentButtonText": "ブロック", "Ventguard_MaxGuards": "最大通気口ブロック数", "Ventguard_BlockVentCooldown": "通気口ブロックのクールダウン", @@ -1864,21 +1831,13 @@ "Jackal_SidekickCountMode_Jackal": "ジャッカル", "Jackal_SidekickCountMode_Original": "オリジナルのチーム", "Jackal_SidekickAssignMode": "サイドキック 割り当てモード", - "Jackal_SidekickAssignMode_SidekickAndRecruit": "サイドキック は リクルート に失敗した場合", + "Jackal_SidekickAssignMode_SidekickAndRecruit": "サイドキック+リクルート", "Jackal_SidekickAssignMode_Sidekick": "サイドキック のみ", - "Jackal_SidekickAssignMode_Recruit": "リクルート のみ", + "Jackal_SidekickAssignMode_Recruit": "リクルートのみ", + "JackalWinWithSidekick": "ジャッカル はサイドキック のチームと一緒に勝つことができます", "Jackal_SidekickCanKillSidekick": "サイドキック たちは他のサイドキック を殺すことができます", "Jackal_SidekickCanKillJackal": "サイドキック は ジャッカル を殺すことができます", - "Jackal_RecruitFailed": "このプレイヤーをリクルートすることはできません!", "JackalCanKillSidekick": "ジャッカル は サイドキック を殺せます", - "Jackal_SidekickCanKillWhenJackalAlive": "サイドキック は \nジャッカル が生存している間でも殺害できます", - "Jackal_SidekickTurnIntoJackal": "サイドキック は ジャッカル の死後、ジャッカルに昇格できます", - "Jackal_RestoreLimitOnNewJackal": "サイドキック が新しい ジャッカル になったとき、リクルート制限をリセットします", - "Jackal_OnBecomeNewJackalMeeting": "古い ジャッカル {0} は死にました。\nあなたが新しい ジャッカル に選ばれました!\n協力してゲームに勝利しましょう!", - "Jackal_OnNewJackalSelectedMeeting": "古い ジャッカル {0} は死にました。\n{1} が新しい ジャッカル に選ばれました!\n協力してゲームに勝利しましょう!", - "Jackal_BecomeNewJackal": "古いジャッカルが死亡、あなたが新しいジャッカルです!", - "Jackal_OnNewJackalSelected": "古いジャッカルが死亡、しばらくの間新しいジャッカル {0} を助けてください!", - "Jackal_BossIsDead": "おっと、ジャッカルのボスが死にました!", "CoronerArrowsPointingToDeadBody": "ボディを指し示す矢印があります", "CoronerLeaveDeadBodyUnreportable": "死体解剖医が使用した死体は報告できません", "CoronerInformKillerBeingTracked": "追跡されていることをキラー・プレーヤーに知らせる", @@ -1916,9 +1875,6 @@ "VipTag": "VIP★", "ApplyVipList": "VIPリストを適用", "AllowSayCommand": "モデレーターが/sayコマンドを使用できるようにする", - "AllowStartCommand": "モデレーターが /start コマンドを使用できるようにする", - "StartCommandMinCountdown": "/start コマンドの最小カウントダウン", - "StartCommandMaxCountdown": "/start コマンドの最大カウントダウン", "KickCommandDisabled": "キックコマンドは現在無効です。", "KickCommandNoAccess": "キックコマンドにアクセスできません。", "KickCommandInvalidID": "無効なプレイヤーIDが指定されました。プレイヤーをキックするには '/kick [playerID] [reseaon] ' を使用してください。例:- /kick 5 ルールに従わない", @@ -1951,11 +1907,6 @@ "WarnCommandNoAccess": "Warn コマンドに対する権限がありません", "WarnCommandInvalidID": "無効なプレイヤーIDが指定されました。プレイヤーに警告を出すには '/warn [playerID] [reason]' を使用してください。例:- /warn 5 ラヴァのチャット", "WarnCommandWarnHost": "ホストに警告する権限はありません。", - "StartCommandNoAccess": "/start コマンドにアクセスする権限がありません。", - "StartCommandDisabled": "スタートコマンドは現在無効です。", - "StartCommandCountdown": "エラー\n\nゲームはすでに開始しています!", - "StartCommandStarted": "{0} によってゲームが開始されました!", - "StartCommandInvalidCountdown": "エラー\n\nカウントダウンは {0} ~ {1} の間でなければなりません!", "WarnCommandWarnMod": "他のモデレーターに警告する権限はありません。", "WarnCommandWarned": "に警告されました。これ以上の警告はありません。適切な対処が取られます。 ", "WarnExample": "将来的には /warn [id] [reason] を使用してください。例:- /warn 5 ラヴァのチャット", @@ -1983,7 +1934,6 @@ "DeathReason.Quantization": "量子化", "DeathReason.Overtired": "過労", "DeathReason.Ashamed": "羞恥心", - "DeathReason.Consumed": "消費済み", "DeathReason.PissedOff": "滅ぼす", "DeathReason.Dismembered": "体がバラバラになる", "DeathReason.LossOfHead": "絞める", @@ -2007,8 +1957,6 @@ "DeathReason.Starved": "飢えさせられた", "DeathReason.Equilibrium": "均衡", "DeathReason.Sacrificed": "犠牲にされた", - "DeathReason.Electrocuted": "感電", - "DeathReason.Scavenged": "回収済み", "OnlyEnabledDeathReasons": "有効な死因のみ", "Alive": "生存中", "Disconnected": "断絶。", @@ -2024,10 +1972,11 @@ "DeputyHandcuffCooldown": "手錠のクールダウン", "DeputyHandcuffMax": "最大手錠数", "DeputyHandcuffedPlayer": "手錠をかけられたターゲット", - "HandcuffedByDeputy": "手錠をかけられている!", - "DeputyInvalidTarget": "ターゲットは手錠をかけられません", + "HandcuffedByDeputy": "You were handcuffed!\nNow you have broken your handcuff and can kill again.", + "DeputyInvalidTarget": "Target is already handcuffed", + "HandcuffBrokenAfterMeeting": "Remove all handcuffs after meeting", "DeputyHandcuffText": "手錠", - "DeputyHandcuffCDForTarget": "手錠をかけられたプレイヤーのキルクールダウン", + "DeputyHandcuffCDForTarget": "Next Kill Cooldown for handcuffed player", "RejectShapeshift.AbilityWasUsed": "能力が使用されました", "EscapisMtarkedPosition": "自分の位置をマークしました", "InvestigateCooldown": "調査のクールダウン", @@ -2087,7 +2036,6 @@ "ShowMadmatesInLeftCommand": "マッドメイツ を表示 (アドオンを含む)", "ShowApocalypseInLeftCommand": "中立黙示録を表示", "SeeEjectedRolesInMeeting": "ミーティングで排除された役割を見る", - "ThankYouForUsingTOHE": "TOHEをご利用いただきありがとうございます!", "SkillUsedLeft": "会議を呼び出すスキルを発動しました。\n残りの使用回数:", "NemesisDeadMsg": "ネメシスの死は復讐の始まりを告げる。\n指定したプレイヤーを殺すには、/rv + [プレイヤー ID] を使用してください。プレイヤーの名前の前にプレイヤー ID が表示されます。または、/rv を入力してプレイヤー ID のリストを取得します。", "NemesisAliveKill": "ネメシスの復讐は、彼らの死後にのみ始まることができます。", @@ -2107,7 +2055,6 @@ "GuessNotifiedBait": "おとりは発表されたため、推測できません、簡単だと思いましたか?", "GuessGM": "GMを推測することは不可能です、なぜなら彼らはすでに死んでいます... そして、なぜ可哀想なホストにそんなことをするのでしょうか?", "GuessGuardianTask": "タスクを終えたガーディアンを推測することはできません。", - "GuardianCantKilled": "タスクを完了したガーディアンを殺すことはできません。", "GuessMarshallTask": "任務を完了した指揮官は、推測することはできません。", "GuessObviousAddon": "申し訳ありませんが、明らかなアドオンを使用しているプレイヤーを推測することはできません。", "GuessAdtRole": "残念ながら、ホストの設定ではアドオンを推測することはできません", @@ -2163,7 +2110,6 @@ "BecomeMadmateCuzMadmateMode": "死んだので、あなたはマッドメイトになりました", "CleanerCleanBody": "遺体はきれいにされました", "QuickShooterStoraging": "弾丸が成功裏に格納されました", - "QuickShooterFailed": "まだクールダウン中です。", "PoisonerTargetDead": "対象が死亡しました", "HexesLookLikeSpells": "ヘックス は 呪文 として表示されます", "HexButtonText": "呪い", @@ -2322,7 +2268,6 @@ "Message.YTPlanNotice": "注意:このロビーでは「YouTuberプラン」が有効になっており、ホストは次のゲームで役割を指定してコンテンツを作成しやすくすることができます。ホストがこの機能を乱用した場合、ゲームを終了するか、報告してください。\n現在の作成者の資格:", "Message.OnlyCanBeUsedByHost": "エラー\nこのコマンドはホストのみ使用できます。", "Message.MaxPlayers": "最大プレイヤー数が設定されました ", - "Message.MaxPlayersFailByRegion": "最大プレイヤー数を設定できませんでした:バニラリージョンでは最大15人まで対応可能です。", "Message.GhostRoleInfo": "ゴーストロール情報\nこんにちは!ゴーストロールについて少し…\n\nゴーストロールはゲームに大きな影響を与えるため、あまり詳しくない場合や小さなロビーではお勧めしません。説明に特に記載がない限り、ガードボタンが彼らの能力ボタンです ;) \n\nスポーンについて:\nゴーストロールは死後にのみスポーンします。死亡した最初のx人の (チーム) メンバーがそれらを得ます。\n\nPS:以前のロールにタスクがなかった場合 (例:シェリフ) 、ゴーストロールとしてのタスクはタスク勝利には必要ありません", "ApocalypseInfoTitle": "中立黙示録情報:", "Message.ApocalypseInfo": "黙示録チームの各役割には、変身を遂げるための独自の目標があります。\n変身後の 黙示録メンバーはゲームに大きな変化をもたらし、不死身になります (投票でのみ排除可能) が、変身したことは全員に通知されます。\n\n役割: 疫病媒介者, 魂の収集者, パン職人, 狂戦士\n変身後: ペスティレンス, 死, 飢饉, 戦争\n\n黙示録のメンバーはお互いの役割や能力アイコンを見ることができます。\n中立のキラーと同様に、黙示録のメンバーもゲームを続ける存在です。楽しんでください!", @@ -2454,6 +2399,7 @@ "LastResult": "★ マッチ結果", "LastEndReason": "★ 終了理由", "KillLog": "キルログ", + "MainRoleLog": "Role Convert Log", "Maximum": "最大", "RoleRate": "オン ", "RoleOn": "いつも ", @@ -2640,7 +2586,7 @@ "NeutralRemain": "\nニュートラルキラー が {0} 人残っています。", "OneNeutralRemain": "\nニュートラルキラー が {0} 人残っています。", "ApocRemain": "\n残り{0} 人の中立 黙示録", - "GameOverReason.HumansByVote": "すべてのインポスターとニュートラルキラーが追放または殺されました", + "GameOverReason.HumansByVote": "All Impostors and Neutral Killers were ejected or killed", "GameOverReason.HumansByTask": "クルーメイトがすべてのタスクを完了しました", "GameOverReason.HumansDisconnect": "クルーメイトが切断されました", "GameOverReason.ImpostorByVote": "クルーメイトが追放されました", @@ -2730,9 +2676,8 @@ "DeathMeetingTimeIncrease": "死が存在する場合、会議時間が増加", "SoulCollectorMeetingDeath": "ターゲットが会議中に死亡しました。ソウルを獲得しました。", "SoulCollectorKillButtonText": "予測する", - "SoulCollectorHasImpostorVision": "魂の収集者 はインポスターの視界を持っています", "ApocalypseIsNigh": "「終末が迫っています!」", - "ApocalypseImmune": "この役職は無効化されません!", + "ApocalypseImmune": "このプレイヤーは無敵なので免疫があります!", "BakerToFamine": "あなたは飢饉になりました!!!", "BakerTransform": "パン職人飢饉に変身し、黙示録の騎士となった!飢饉が始まった!", "BakerAlreadyBreaded": "そのプレイヤーにはすでにパンが与えられています!", @@ -2741,15 +2686,13 @@ "BakerBreadNeededToTransform": "飢饉になるために必要なパンの数", "BakerCantBreadApoc": "他のアポカリプスメンバーにはパンを与えることはできません!", "BakerKillButtonText": "パン", - "BakerUnshiftButtonText": "パンの種類を切り替える", "BakerRevealBread": "公開する", "BakerRoleblockBread": "役割をブロックする", "BakerBarrierBread": "バリア", "BakerCurrentBread": "現在のパン数: ", "BakerSwitchBread": "パンが切り替えられました: ", - "BakerCanVent": "パン職人はベントを使用できます", + "BakerCanVent": "パン職人は通気口を使用できます", "BakerBreadGivesEffects": "パンが追加効果を与える", - "BakerTransformNoMoreBread": "パン職人はパンが不足すると変身します", "FamineKillButtonText": "飢えさせる", "FamineStarveCooldown": "飢饉の飢えクールダウン", "FamineCantStarveApoc": "他のアポカリプスメンバーを飢えさせることはできません!", @@ -2796,7 +2739,6 @@ "GodfatherTargetCountMode": "キラーが変身します", "GodfatherCount_Refugee": "難民", "GodfatherCount_Madmate": "マッドメイツ", - "GodfatherRefugeeMsg": "あなたはゴッドファーザーにリクルートされました!", "MissChance": "失敗する確率", "IncreaseByOneIfConvert": "クルーが変換された場合、キルカウントを+1増やす", "HawkMissed": "失敗!", @@ -2829,7 +2771,6 @@ "BerserkerToWar": "戦争に変身!!!", "BerserkerTransform": "狂戦士戦争に変身し、黙示録の騎士となった!「ハヴォック!」と叫び、戦の犬を解き放て。", "WarKillCooldown": "戦争のキルクールダウン", - "BerserkerCanKillTeamate": "他の中立黙示録を殺すことができます", "BlackmailerSkillCooldown": "脅迫のクールダウン", "BlackmailerMax": "脅迫されたプレイヤーが発言できる最大回数", "BlackmailerDead": "警告! {0}ブラックメイラー によって脅迫されています!", @@ -2919,8 +2860,6 @@ "RememberedPursuer": "あなたは自分が追跡者であることを思い出しました!", "RememberedFollower": "あなたはフォロワーであることを思い出しました!", "RememberedAmnesiac": "役職を思い出すことができませんでした。", - "AmnesiacRemembered": "あなたは {0} だったことを思い出しました!", - "ReportWhenFailedRemember": "思い出しに失敗した場合は死体を報告してください", "RememberedImitator": "あなたは自分が模倣者であることを思い出しました。", "RememberedImpostor": "あなたはインポスターであることを思い出しました!", "RememberedCrewmate": "あなたはクルーメイトであることを思い出しました!", @@ -2941,7 +2880,7 @@ "BanditStealCooldown": "クールダウンを盗む", "DoppelMaxSteals": "最大窃盗数", "DoppelCurrentVictimCanSeeRolesAsDead": "最後の被害者はゴーストとして生存プレイヤーの役割とアドオン情報を確認できます", - "NecromancerRevengeTime": "死者蘇生の時間", + "NecromancerRevengeTime": "Necromancy time", "NecromancerRevenge": "{0}秒以内に {1} を殺す時間があります", "NecromancerSuccess": "死者蘇生が完了しました!また明日も生きて見ることができます。", "NecromancerHide": "通気が無効になっています、死者蘇生者から隠れて!", @@ -3146,7 +3085,7 @@ "DollMaster_PossessedTarget": "憑依された対象", "DollMaster_CannotPossessImpTeammate": "チームメイトを憑依できない", "DollMaster_CouldNotSwapWithTarget": "プレイヤーを憑依できません", - "DollMaster_CanNotSwapWithDeadTarget": "死んだプレイヤーを憑依することはできません", + "DollMaster_CanNotSwapWithDeadTarget": "Possessing a dead player isn't possible", "DollMaster_MainBody": "本体", "DollMaster_Doll": "人形", "DollMaster_UnableToUseAbility": "プレイヤーに能力を使用できない", @@ -3164,7 +3103,7 @@ "PitfallTrapCauseVisionTime": "トラップが視界に影響を与える時間", "PitfallTrap": "あなたはトラップにかかりました!", "ConsigliereDivinationMaxCount": "最大の公開数", - "RitualMaxCount": "最大の公開数", + "RitualMaxCount": "Maximum Reveals", "CleanserHideVote": "クレンザーの投票を隠す", "OracleSkillLimit": "最大の使用回数", "OracleHideVote": "オラクルの投票を隠す", @@ -3334,12 +3273,9 @@ "PixieTargetAlreadySelected": "ターゲットはすでに選択されています。", "PixieButtonText": "マーク", "PlagueBearerCooldown": "疫病のクールダウン", - "PlagueBearerCanVent": "ベント可能", - "PlagueBearerHasImpostorVision": "インポスターの視界を持っています", "PestilenceCooldown": "ペスティレンスのキルクールダウン", "PestilenceCanVent": "ペスティレンスはベントを使える", "PestilenceHasImpostorVision": "ペスティレンスにはインポスターの視界がある", - "PestilenceKillGuessers": "ペスティレンス を推測したプレイヤーを殺す", "PlagueBearerAlreadyPlagued": "プレイヤーはすでに疫病にかかっています", "PlagueBearerToPestilence": "あなたはペスティレンスになりました!!", "GuessPestilence": "あなたはペスティレンスを予想しようとしました!\n\nごめんなさい、ペスティレンスによって殺されました。", @@ -3383,7 +3319,6 @@ "EveryoneCanKnowMini": "みんながミニを見ることができます", "CanBeEvil": "ミニはインポスターになり得る", "EvilMiniSpawnChances": "ミニがインポスターである確率", - "EvilMiniCanBeGuessed": "イービルミニは18歳未満でも推測可能", "GuessMini": "ごめんなさい、子供のミニには攻撃できません。", "GrowUpDuration": "成長に必要な時間 (秒)", "MajorCooldown": "18歳以上の場合のキルクールダウン", @@ -3525,7 +3460,6 @@ "WinnerRoleText.Doppelganger": "ドッペルゲンガーの勝利!", "WinnerRoleText.Quizmaster": "クイズ監督者の勝利!", "WinnerRoleText.Agitater": "アジテーターの勝利!", - "WinnerRoleText.Shocker": "ショッカーの勝利!", "AdditionalWinnerRoleText.Sidekick": "相棒", "AdditionalWinnerRoleText.Taskinator": "タスキネーター", "AdditionalWinnerRoleText.Opportunist": "オポチュニスト", @@ -3611,7 +3545,7 @@ "SolsticerOnMeeting": "死をあまりにも多く目撃しました!次のラウンドではさらに{0} つの短いタスクが増えます!", "SolsticerTitle": "ソルスティス", "GuessSolsticer": "申し訳ありませんが、ソルスティスを推測することはできません!", - "ExpelSolsticer": "申し訳ありませんが、ソルスティスを追放することはできません!", + "VoteSolsticer": "申し訳ありませんが、ソルスティスに投票することはできません!", "SolsticerTasksReset": "あなたのタスクがリセットされた!", "SolsticerMisGuessed": "あなたは推測を誤りました!もう推測することはできません。", "SolsticerGuessMax": "あなたはすでに誤った推測をしたため、もう推測することは許可されていません。", @@ -3712,19 +3646,6 @@ "MinionAbilityTime": "能力の持続時間", "Minion_Blind": "盲目的", "Evader_ChanceNotExiled": "追放されない可能性", - "ShockerAbilityCooldown": "能力のクールダウン", - "ShockerAbilityDuration": "能力の持続時間", - "ShockerAbilityPerRound": "ラウンドごとの能力回数", - "ShockerShockInVents": "ベント内の人々を感電させる", - "ShockerAbilityResetAfterMeeting": "会議後にマークされた部屋をリセットする", - "ShockerOutsideRadius": "部屋外タスクの半径 (部屋内ではない場合)", - "ShockerCanShockHimself": "自分自身を感電させることができる", - "ShockerImpostorVision": "ショッカーはインポスターの視界を持っています", - "ShockerIsShocking": "すでに感電中です!", - "ShockerAbilityActivate": "感電を開始!", - "ShockerAbilityDeactivate": "能力が無効化されました", - "ShockerVentButtonText": "感電", - "ShockerRoomMarked": "マークされた部屋", "EavesdropperMsgTitle": "秘密を見つけた", "EavesdropPercentChance": "盗み聞きするチャンス", "ChiefOfPoliceSkillCooldown": "保安官をリクルートするためのクールダウン", @@ -3736,4 +3657,4 @@ "PolicPreventRecruitNonKiller": "キルボタンを持たないプレイヤーをリクルートすることを防止する", "PolicSuidiceWhenTargetNotKiller": "非キラーまたは非クルーメイトをリクルートすると自殺します", "PolicPassConverted": "変換されたアドオンを保安官に渡すことができる" -} +} \ No newline at end of file diff --git a/Resources/Lang/ko_KR.json b/Resources/Lang/ko_KR.json index 8298361c9..30e3a9661 100644 --- a/Resources/Lang/ko_KR.json +++ b/Resources/Lang/ko_KR.json @@ -20,8 +20,6 @@ "SubText.Neutral": "Work alone to achieve your victory", "SubText.Apocalypse": "Become unstoppable with your team", "SubText.Madmate": "Help the Impostors", - "SubText.Lovers": "Stay alive and win together", - "SubText.Egoist": "Win on your own", "TypeImpostor": "Impostors", "TypeCrewmate": "Crewmates", "TypeNeutral": "Neutrals", @@ -31,9 +29,6 @@ "TeamNeutral": "Neutral", "TeamCrewmate": "Crewmate", "TeamMadmate": "Madmate", - "TeamLovers": "Lovers", - "TeamEgoist": "Egoist", - "TeamApocalypse": "Apocalypse", "YouAreCrewmate": "You are a Crewmate", "YouAreImpostor": "You are an Impostor", "YouAreNeutral": "You are a Neutral", @@ -225,7 +220,6 @@ "TaskManager": "Task Manager", "Witness": "Witness", "Swapper": "Swapper", - "ChiefOfPolice": "Chief of Police", "NiceMini": "Nice Mini", "Mini": "Mini", "Spy": "Spy", @@ -254,7 +248,6 @@ "Stalker": "Stalker", "Workaholic": "Workaholic", "Solsticer": "Solsticer", - "Abyssbringer": "Abyssbringer", "Collector": "Collector", "Provocateur": "Provocateur", "BloodKnight": "Blood Knight", @@ -393,8 +386,6 @@ "Sloth": "Sloth", "Prohibited": "Prohibited", "Eavesdropper": "Eavesdropper", - "Shocker": "Shocker", - "Revenant": "Revenant", "BracketAddons": "Add Brackets To Add-ons", "EngineerTOHEInfo": "Use the vents to catch the Impostors", "ScientistTOHEInfo": "Access portable vitals from anywhere", @@ -513,7 +504,7 @@ "PacifistInfo": "Vent to reset kill cooldowns", "RebirthInfo": "Arise Again", "MonarchInfo": "Give your crew extra voting power!", - "AbyssbringerInfo": "Place Black Holes", + "AbyssbringerInfo": "Create Black Holes", "SpurtInfo": "Spring Like A rabbit!", "StealthInfo": "Killing Blinds Everyone in the Room", "PenguinInfo": "Drag your victims", @@ -538,7 +529,7 @@ "AdmirerInfo": "Choose a player to side with you", "TimeMasterInfo": "Rewind time!", "CrusaderInfo": "Kill a player's attacker", - "AltruistInfo": "Revive a player", + "AltruistInfo": "Revive a player\nVent to change between Revive and Report", "ReverieInfo": "With each kill, your cooldown decreases", "LookoutInfo": "See through disguises", "TelecommunicationInfo": "Track device usage", @@ -547,7 +538,6 @@ "WitnessInfo": "Find out if someone killed recently", "GhastlyInfo": "Control somebody!", "SwapperInfo": "Swap the votes of two players", - "ChiefOfPoliceInfo": "Hire Sheriff to Serve the Crews!", "NiceMiniInfo": "No one can hurt you until you grow up.", "ArsonistInfo": "Douse everyone and ignite", "PyromaniacInfo": "Douse and kill everyone", @@ -615,7 +605,7 @@ "ShroudInfo": "Shroud players to make them kill", "WerewolfInfo": "Kill crewmates in groups", "ShamanInfo": "Deflect all the attacks on Voodoo doll", - "SeekerInfo": "Play Hide and Seek with your target", + "SeekerInfo": "Play Hide and Seek with your target\nYour target has a ★ mark.", "PixieInfo": "Tag 'em, Bag 'em, and Eject 'em!", "OccultistInfo": "Kill and curse your enemies", "SchrodingersCatInfo": "The cat is both alive and dead until observed.", @@ -708,8 +698,6 @@ "SlothInfo": "You're slower", "ProhibitedInfo": "Certain vents are blocked", "EavesdropperInfo": "Listen in on other roles", - "ShockerInfo": "Shock unsuspecting players", - "RevenantInfo": "Take your killer's role", "EngineerTOHEInfoLong": "(Crewmates):\nAs the Engineer, you may access the vents while Comms Sabotaged is inactive.", "ScientistTOHEInfoLong": "(Crewmates):\nAs the Scientist, you can see vitals at any time, showing you who is alive and dead.", "NoisemakerTOHEInfoLong": "(Crewmates):\nAs the Noisemaker, whenever you die, you will make a noise, and a visual indicator of your death appears on the screen so the Crewmates can run to catch the person who killed you red-handed (even if it’s not Red).", @@ -781,11 +769,11 @@ "LurkerInfoLong": "(Impostors):\nAs the Lurker, you can jump into a vent to reduce your cooldown by a certain number of seconds. After you kill, your cooldown resets to its original value.", "VisionaryInfoLong": "(Impostors):\nAs the Visionary, you see the alignments of living players during a meeting.\nThe following information will be displayed on the players:\n- The Red name indicates the Impostors.\n- The Cyan name indicates the Crewmates.\n- The Gray name indicates the Neutrals.", "PlagueDoctorInfoLong": "(Neutrals):\n(Plague Doctor from TOH)\nThe Plague Scientist's goal is to infect every living player.\nThey start by choosing one player to infect, after which anyone who spends a set amount of time in the range of the infected player becomes infected themselves.\nInfection progress is cumulative and does not reset with distance or after meetings.", - "RefugeeInfoLong": "(Madmates):\nAs the Refugee, you were either:\n -An Amnesiac who remembered an Impostor\n -A killer who killed the Godfather's target.\n -A Romantic whose partner was an Impostor\n -Or an Imitator that imitated an Impostor.\n\nNow your job is to help the Impostors kill the crewmates.", + "RefugeeInfoLong": "(Madmates):\nAs the Refugee, you were either an Amnesiac who remembered an Impostor or a killer who killed the Godfather's target.\n\nNow your job is to help the Impostors kill the crewmates.", "UnderdogInfoLong": "(Impostors):\nAs the Underdog, you cannot kill until there's a certain amount of players alive.", "ConsigliereInfoLong": "(Impostors):\nAs the Consigliere, you can reveal the roles of other players using your kill button.\n\nSingle click: Reveal role\nDouble click: Kill\n\nIf you run out of reveal uses, your kill button functions normally.", "LudopathInfoLong": "(Impostors):\nAs the Ludopath, your kill cooldown is randomized.\n\nMinimum it can be is 1 second, while the maximum is your default kill cooldown.", - "GodfatherInfoLong": "(Impostors):\nAs the Godfather, you vote someone to make them your target.\nIn the next round, if someone kills the target, the killer will turn into a Refugee or Madmate.", + "GodfatherInfoLong": "(Impostors):\nAs the Godfather, you vote someone to make them your target.\nIn the next round, if someone kills the target, the killer will turn into a Refugee.", "ChronomancerInfoLong": "(Impostors):\nAs the Chronomancer, you have a charge bar which indicates when the slaughter is ready. When it is at 100% the next time you kill someone, you go into slaughter mode, meaning you can kill indefinitely until your bar runs out of charge. Otherwise, you have a normal KCD.", "PitfallInfoLong": "(Impostors):\nAs the Pitfall, you use your shapeshift to mark the area around the shapeshift as a trap. Players who enter this area will be immobilized quickly, and their vision will be affected.", "EvilMiniInfoLong": "(Impostors):\nAs the Evil Mini, you are unkillable until you grow up and have a very long initial kill cooldown, which gets drastically shortened as you grow up.", @@ -821,7 +809,7 @@ "GrenadierInfoLong": "(Crewmates):\nAs the Grenadier, you can vent to Flashbang players nearby, causing them to lose vision if they are an Impostor or, depending on settings, a Neutral.", "MedicInfoLong": "(Crewmates):\nThe Medic can place a shield on the target by pressing the Kill button. The Medic can only give one shield for the whole game. Depending on the settings, the target's shield can or cannot deactivate when the Medic dies. The Medic can also see if someone is trying to break the target's shield.\nDepending on the Host's settings, the Medic or the target can see if the player has a shield (shown as a green circle 「●」 next to the name).", "FortuneTellerInfoLong": "(Crewmates):\nAs the Fortune Teller, vote for a player in a meeting to get a clue to their role.\nThe clue will relate to their actual role.\n\nWhen the Fortune Teller's tasks are complete, they will obtain the exact role rather than a clue!\n\nNote: If the setting to give random active players as a hint is on, you cannot check the same player multiple times.", - "JudgeInfoLong": "(Crewmates):\nThe Judge can judge a certain player during the meeting. If the target is evil, the target will be killed (whether it is evil or not is set by the Host). If it is wrong, the Judge commits suicide.\nCommand for judgment: /tl [player id]\nYou can see the player's id before the player's name, or use the /id command to view the id of all players.\nJudges can judge all players when they become Madmate.", + "JudgeInfoLong": "(Crewmates):\nThe Judge can judge a certain player during the meeting. If the target is evil, the target will be killed (whether it is evil or not is set by the Host). If it is wrong, the Judge commits suicide.\nCommand for judgment: /tl [player id]\nYou can see the player's id before the player's name, or use the /id command to view the id of all players.\nJudges can judge all players when they become Madmate.\nIn meeting the ability count shows how many trails you have in this meeting. Out of meeting the ability counts shows how many trails you have for the whole game.", "MorticianInfoLong": "(Crewmates):\nThe Mortician can see arrows pointing to all dead bodies, and if the Mortician reports a body, they will know the last player the victim had contact with. Note: Mortician won't be Oblivious or Seer.", "MediumInfoLong": "(Crewmates):\nThe Medium can establish contact with a dead player after someone reports a dead body. The player who reports doesn't have to be the Medium. The dead player can answer once with a YES or a NO to the Medium's question, which only the Medium will see (the dead player can use /ms yes or /ms no). Note: Medium won't be Oblivious.", "ObserverInfoLong": "(Crewmates):\nAs the Observer, you can see all shield animations caused by other players after the first meeting. The shied animations typically indicate a role ability, so look out for this.", @@ -833,7 +821,7 @@ "MerchantInfoLong": "(Crewmates):\nAs a merchant, you sell a random add-on to a random player for each task you complete. Each add-on sold earns you money. If you have a certain amount of money, you can prevent the next killing attempt against you by bribing the murderer. The bribed player won't be able to kill you, but you don't know who it is. The money used is lost and not available for additional bribes.", "RetributionistInfoLong": "(Crewmates):\nAs the Retributionist, you can kill a limited amount of players after your death.\n\nUse /ret [playerID] to kill.", "HawkInfoLong": "(Crewmates [Ghost]):\nAs the Hawk, you can kill a limited amount of players decided by the host, though there's a chance you miss, slicing someone multiple times increases the chances.", - "DeputyInfoLong": "(Crewmates):\nAs the Deputy, use your kill button on a player to reset their kill cooldown.\n\nIf the target does not have a kill button, then the handcuff was a waste.", + "DeputyInfoLong": "(Crewmates):\nAs the Deputy, use your kill button to handcuff a player.\nThe player who is handcuffed will have their next kill attempt treated as a handcuff break, and the kill cooldown will be reset.\n\nIf the target does not have a kill button, then the handcuff was a waste.", "InvestigatorInfoLong": "(Crewmates):\nAs an Investigator, you can use your kill button to investigate someone. When you investigate someone, their name will appear in red if they possess a kill button (impostor/SS basis) or light blue if they lack a kill button (crewmate/engineer/scientist basis). However, please note that the color of the names will return to normal when someone calls a meeting.", "GuardianInfoLong": "(Crewmates):\nAs the Guardian, you become immortal upon task completion. Guessers can't even guess you in meetings.", "AddictInfoLong": "(Crewmates):\nAs the Addict, you have a suicide timer. When it expires, you kill yourself.\nThe timer is indicated by the vent cooldown. When the vent cooldown is 0 seconds, you still have a short time to vent.\nIf you don't make it, you die; if you make it, the suicide timer is reset.\nAlso after you vent, no one can interact with you for a defined period.\nAfter; the period is over, and you are immobilized for another defined period, and cannot report any bodies.", @@ -849,7 +837,7 @@ "AdmirerInfoLong": "(Crewmates):\nAs the Admirer, admire a player to make them Crewmate aligned.\nThey'll win with crewmates and not their original team.\n\nYou can only do this once per player.", "TimeMasterInfoLong": "(Crewmates):\nAs the Time Master, use the vents to mark everyone's position.\nWhen using the ability again, every alive player will rewind to the marked positions.\n\nDuring the ability duration, the Time Master gains a time shield, which protects them from death.", "CrusaderInfoLong": "(Crewmates):\nAs the Crusader, use your kill button to crusade a player.\nIf that player gets attacked, you'll kill the attacker.", - "AltruistInfoLong": "(Crewmates):\nAs the Altruist, you can sacrifice yourself to revive a dead body using the «Report» button.\nNote: If a dead player has left the game, you report that body normally.\nAlso revived player cannot report self dead body", + "AltruistInfoLong": "(Crewmates):\nAs the Altruist, you can sacrifice yourself to revive a dead body using the «Report» button.\nNote: If a dead player has left the game, you report that body normally.\nAlso revived player cannot report self dead body\nUse vent button to change between Report & Revive.", "ReverieInfoLong": "(Crewmates):\nAs the Reverie, you can kill, but your cooldown starts high.\n\nIt increases if you kill a crewmate and reduces otherwise.\nDepending on the Host's setting, you may misfire on reaching the max kill cooldown, and your target dies with you. \n\nYou win with other crewmates.", "LookoutInfoLong": "(Crewmates):\nAs the Lookout, you can see the IDs of every player at all times.\nThis allows you to see through shapeshifts and camouflages.", "TelecommunicationInfoLong": "(Crewmates):\nAs the Telecommunication, you are notified when anyone uses cameras, vitals, door logs, or admin.", @@ -872,7 +860,7 @@ "LawyerInfoLong": "(Neutrals):\nLawyer has a target to defend, which will be indicated by a diamond 「♦」 next to their name.\nIf your target wins, you win.\nIf they lose, you lose.", "OpportunistInfoLong": "(Neutrals):\nIf the Opportunist survives at the end of the game, the Opportunist will win with the winning player.", "VectorInfoLong": "(Neutrals):\nVector will win alone by venting a certain number of times.", - "JackalInfoLong": "(Neutrals):\nAs the Jackal, you win if you are the last player alive. Additionally, you may recruit using the kill button. If the target is not one you can recruit, you have run out of uses, or you don't have the option to recruit, then you will kill people normally (i.e., don't use kill buttons in front of others thinking it'll recruit). If the target has a kill button and the option to turn into a Sidekick is on, they will become a Sidekick. Otherwise, they will gain the Recruit add-on if the option to give the Recruit add-on is on.\nDepending on the settings, when Jackal was killed, a Sidekick will be randomly selected as the new Jackal.\nRecruit may be selected if no sidekick is alive.", + "JackalInfoLong": "(Neutrals):\nAs the Jackal, you win if you are the last player alive. Additionally, you may recruit using the kill button. If the target is not one you can recruit, you have run out of uses, or you don't have the option to recruit, then you will kill people normally (i.e., don't use kill buttons in front of others thinking it'll recruit). If the target has a kill button and the option to turn into a Sidekick is on, they will become a Sidekick. Otherwise, they will gain the Recruit add-on if the option to give the Recruit add-on is on.", "GodInfoLong": "(Neutrals):\nAs the God, you know everyone's role from the beginning. If you live until the end of the game, you steal the win, i.e., everyone else loses, and you win.", "InnocentInfoLong": "(Neutrals):\nThe Innocent can use the kill button to plant any player, and the planted target will immediately kill the Innocent. If the target gets voted out in the meeting, the Innocent wins. Note: Jester, Executioner, and Innocent can win together.", "PelicanInfoLong": "(Neutrals):\nAs the Pelican, you can use the kill button to swallow a player alive, teleporting them off-bounds but not killing them yet. Those swallowed will only die if you're still alive at the end of the round. If you die or leave during the round, all alive swallowed players will spawn into the map where you were.", @@ -884,14 +872,14 @@ "SolsticerInfoLong": "(Neutrals):\nAs the Solsticer, you won't die, and you win by finishing all your tasks in a single round. After every meeting finishes, your tasks reset, and you need to start all over again.\nVotes on the Solsticer will be directly canceled.\nKill attempts on the Solsticer will teleport it out of the map like Pelican until the meeting is finished.\nThe killer's kill cooldown will be reset to 10 seconds.\nSolsticer is counted as nothing in-game.", "CollectorInfoLong": "(Neutrals):\nAs the Collector, when you vote for a player, for each other player that voted for them, you gain a point. When you collect the required votes, the game ends, and you win alone, even if you voted a Jester or Executioner's target out.", "GlitchInfoLong": "(Neutrals):\nAs the Glitch, you can hack players (single click) or kill normally (double click).\nThose who have been hacked cannot kill, vent, or report for the hack duration.\nAdditionally, calling a sabotage other than doors will have no effect and will instead disguise you as a random player. You cannot disguise during or after sabotages.\nTo win, be the last player alive.", - "SidekickInfoLong": "(Neutrals):\nAs the Sidekick, your job is to help the Jackal kill everyone.\nYou and the Jackal win together.\nDepending on the settings, you may turn into Jackal if old Jackal was killed.\nYou may not be able to kill until old Jackal is dead.", + "SidekickInfoLong": "(Neutrals):\nAs the Sidekick, your job is to help the Jackal kill everyone.\n\nYou and the Jackal win together.", "ProvocateurInfoLong": "(Neutrals):\nAs the Provocateur, you can kill any target with the kill button. If the target loses at the end of the game, the Provocateur wins with the winning team.", "BloodKnightInfoLong": "(Neutrals):\nThe Blood Knight wins when they're the last killing role alive, and the amount of crewmates is lower or equal to the amount of Blood Knights. The Blood Knight gains a temporary shield after every kill, making them immortal for a few seconds.", "PlagueBearerInfoLong": "(Apocalypse):\nAs the Plaguebearer, plague everyone using your kill button to turn into Pestilence.\nOnce you turn into Pestilence, you will become immortal and gain the ability to kill, and you will kill anyone who tries to kill you.\n\nAlso, when infected players interact with uninfected players, they will also be infected.", "PestilenceInfoLong": "(Apocalypse):\nAs Pestilence, you're an unstoppable machine.\nAny attack towards you will be reflected towards them.\nIndirect kills don't even kill you.\n\nOnly way to kill Pestilence is by voting them out or the Pestilence misguessing.\nYour presence is announced to everyone at the meeting after you transform.", "SoulCollectorInfoLong": "(Apocalypse):\nAs Soul Collector, you can use your kill button on a player to predict their death. You will gain a soul if your target dies in the round you select them or the meeting after.\nYour target resets after each meeting or after they die, whichever comes first. \n\nOnce you collect the configurable amount of souls, you become Death. If the gain passive souls setting is enabled, you will gain a soul each meeting.", "DeathInfoLong": "(Apocalypse):\nOnce the Soul Collector has collected their needed souls, they become Death. Death kills everyone and wins if Death is not ejected by the end of the next meeting.\nA configurable amount of extra meeting time will be given on the meeting Death transforms to have more discussion to find Death.\n\nYou are invincible, and your presence is announced to everyone at the meeting after you transform.", - "BakerInfoLong": "(Apocalypse):\nAs the Baker, you can use your kill button on a player per round to give them bread. \nOnce a set amount of players are alive with bread, you become Famine.\n\nIf the Bread gives additional effects and the setting is on, then you can vent to change the bread that you give out. \nBread Effects:\nReveal: Reveals the target's role to the Baker (stays the whole game)\nRoleblock: Sets the target's kill cooldown to 999 (resets to normal after the meeting)\nBarrier: Gives the target a barrier that is only known to the Baker (barrier is removed after the meeting)", + "BakerInfoLong": "(Apocalypse):\nAs the Baker, you can use your kill button on a player per round to give them bread. \nOnce a set amount of players are alive with bread, you become Famine.\n\nIf the Bread gives additional effects and the setting is on, then you can vent to change the bread that you give out. \nBread Effects:\nReveal: Reveals the target's role to the Baker (stays the whole game)\nRoleblock: Resets the target's kill cooldown when they try to use their kill button\nBarrier: Gives the target a barrier that is only known to the Baker (barrier is removed after the meeting)", "FamineInfoLong": "(Apocalypse):\nOnce the Baker has a set amount of people with bread alive, they will become Famine. If the Famine does not get voted out after the meeting, then they will become Famine, and every player without bread will starve (excluding other Apocalypse members).\nAfter this starvation of everyone without bread, Famine can use their kill button to starve any remaining players, which will kill those players right before the next meeting.\n\nYou are invincible, and your presence is announced to everyone at the meeting after you transform.", "BerserkerInfoLong": "(Apocalypse):\nAs the Berserker, you level up with each kill.\nUpon reaching a certain level defined by the Host, you unlock a new power.\n\nScavenged kills make your kills disappear.\nBombed kills make your kills explode. Be careful when killing, as this can kill your other Apocalypse members if they are near. \nAfter a certain level, you become War.", "WarInfoLong": "(Apocalypse):\nAs War, you are invincible, have a lower kill cooldown, and can kill anyone with your previous powers.\nYour presence is announced to everyone at the meeting after you transform.", @@ -911,12 +899,11 @@ "TraitorInfoLong": "(Neutrals):\nAs the Traitor, you were an Impostor that betrayed the Impostors.\nYou know the Impostors, but they don't know you.\nThe twist? They can kill you, but you can't kill them.\n\nEliminate the Impostors by other means, then kill everyone else to win!", "TrollerInfoLong": "(Neutrals):\nAs a Troller, you can complete tasks so that random events can happen to players.\nFor example, changing the speed of all players, teleportation, influencing sabotage, etc.\nAlso you can win with the winning team.", "VultureInfoLong": "(Neutrals):\nAs the Vulture, report bodies to win!\n\nWhen you report a body, if your eat cooldown is up, you'll eat the body (makes it unreportable).\nIf your eat ability is still on cooldown, then you'll report the body normally.\n\nAdditionally, you'll report bodies normally if the maximum bodies eaten per round is reached.", - "AbyssbringerInfoLong": "(Impostors):\nAs the Abyssbringer, you can place black holes. Black holes will suck in players and kill them when colliding with them.", "TaskinatorInfoLong": "(Neutrals):\nAs the Taskinator, whenever you finish a task, the task will be bombed. When another player completes the bombed task, the bomb will detonate, and the player will die.\n\nYou win if you survive till the end and Crew doesn't win.\n\n Note: Taskinator bombs ignore all protection.", "BenefactorInfoLong": "(Crewmates):\nAs the Benefactor, whenever you finish a task, that task will be marked. When another player completes the marked task, they get a temporary shield.\n\n Note: Shield only protects from direct kill attacks.", "MedusaInfoLong": "(Neutrals):\nAs the Medusa, you can stone bodies much like cleaning a body.\nStoned bodies cannot be reported.\n\nKill everyone to win.", "SpiritcallerInfoLong": "(Neutrals):\nAs the Spiritcaller, your victims become Evil Spirits after they die. These spirits can help you win by freezing other players briefly or blocking their vision. Alternatively, the spirits can give you a shield that protects you briefly from an attempted kill.", - "AmnesiacInfoLong": "(Neutrals):\nAs the Amnesiac, use your report button to remember a target and get its role.\nTo balance the game, you will not be able to vent after remembering your role if you can't vent as Amnesiac.'", + "AmnesiacInfoLong": "(Neutrals):\nAs the Amnesiac, use your report button to remember a role.\n\nIf the target was an Impostor, you'll become a Refugee.\nIf the target was a crewmate, you'll become the target role if compatible (otherwise you become an Engineer).\nIf the target was a passive neutral or a neutral killer not specified, you'll become the role defined in the settings.\nIf the target was a neutral killer of a select few, you'll become the role they are.", "ImitatorInfoLong": "(Neutrals):\nAs the Imitator, use your kill button to imitate a player.\n\nYou'll either become a Sheriff, a Refugee, or some Neutral.", "BanditInfoLong": "(Neutrals):\nAs the Bandit, you can click your kill button one time to steal a player's addon and twice to kill. Depending on the settings, you may instantly steal the addon or after the meeting starts. After the maximum number of steals is reached, you will kill normally. Additionally, if there are no stealable addons on the target or the target is stubborn, you will kill the target.\n\nKill everyone to win.\n\nNote: Cleansed, Last Impostor, and Lovers cannot be stolen.\nNote: If Bandit can vent is on, Nimble will become unstealable.", "DoppelgangerInfoLong": "(Neutrals):\nAs the Doppelganger, use your kill button to steal a player's identity (their name and skin) and then kill your target.\n\nKill everyone to win.\n\nNote: You cannot steal the target's identity when Camouflage is active.", @@ -925,7 +912,7 @@ "ShroudInfoLong": "(Neutrals):\nAs the Shroud, you do not kill normally.\nInstead, use your kill button to shroud a player.\nShrouded players kill others.\nIf the shrouded player doesn't make a kill, they'll kill themselves after a meeting.\n\nShroud sees shrouded players with a 「◈」mark next to their name.\nShrouded players who did not make a kill will also have the 「◈」mark in meetings, where they'll die if the Shroud is alive by the end of the meeting.", "WerewolfInfoLong": "(Neutrals):\nAs the Werewolf, you can kill much like any killer.\nHowever, when you kill, any nearby players also die.\nAny player who dies to this will have their death reason as Mauled.\n\nTo balance this, you have a higher kill cooldown than anyone else.", "ShamanInfoLong": "(Neutrals):\nAs the Shaman, you can use your kill button to select a voodoo doll once per round. If the kill button is used on you, the effect will be deflected onto the voodoo doll.\nIf you survive until the end, you win with the winning team.\nNote: If the killer cannot kill the chosen target, murder is canceled, but if the killer rechecks the Shaman, the killer will kill the Shaman.", - "SeekerInfoLong": "(Neutrals):\nAs the seeker, use your kill button to tag the target. If the seeker tags the wrong player, a point is deducted, and if the seeker tags the correct player, a point will be added.\nAdditionally, the seeker will not be able to move for 5 seconds after every meeting and after getting a new target.\n\nThe seeker needs to collect a certain number of points set by the Host to win.", + "SeekerInfoLong": "(Neutrals):\nAs the seeker, use your kill button to tag the target. If the seeker tags the wrong player, a point is deducted, and if the seeker tags the correct player, a point will be added.\nAdditionally, the seeker will not be able to move for 5 seconds after every meeting and after getting a new target.\n\nThe seeker needs to collect a certain number of points set by the Host to win.\nSeeker will see a ★ mark on target's name.", "PixieInfoLong": "(Neutrals):\nAs the Pixie, Mark up to x amount of targets each round by using the kill button on them. You must have one of the marked targets ejected when the meeting starts. If unsuccessful, you will commit suicide, except if you didn't mark any targets or all the targets are dead. The selected targets reset to 0 after the meeting ends. If you succeed, you will gain a point. You see all your targets in colored names.\n\nYou win with the winning team when you have certain amounts of points set by the Host.", "SchrodingersCatInfoLong": "(Neutrals):\nAs Schrodingers Cat, if someone attempts to use the kill button on you, you will block the action and join their team. This blocking ability works only once. By default, you don't have a victory condition, meaning you win only after switching teams.\nIn Addition to this, you will be counted as nothing in the game.\n\nNote: If the killing machine attempts to use its kill button on you, the interaction is not blocked, and you will die.", "RomanticInfoLong": "(Neutrals):\nThe Romantic can pick their lover partner using their kill button (this can be done at any point of the game). Once they've picked their partner, they can use their kill button to give their partner a temporary shield that protects them from attacks. If their lover partner dies, the Romantic's role will change according to the following conditions:\n1. If their partner was an Impostor, the Romantic becomes the Refugee\n2. If their partner was a Neutral Killer, then they become Ruthless Romantic.\n3. If their partner was a Crewmate or a non-killing neutral, the Romantic becomes the Vengeful Romantic. \n\nThe Romantic wins with the winning team if their partner wins.\nNote: If your role changes, your win condition will be changed accordingly", @@ -937,7 +924,6 @@ "JinxInfoLong": "(Neutrals):\nAs the Jinx, whenever you get attacked, you jinx them, resulting in them dying to a jinx.\nThis has limited uses.\n\nKill off everyone to win.", "PotionMasterInfoLong": "(Neutrals):\nAs the Potion Master, you have three different potions assigned to three different actions.\n\nSingle click: Reveal role\nDouble click: Kill\nMap: Sabotage\n\nThe reveal potion has a limit.\nWhen you run out, the kill buttons default to killing.", "NecromancerInfoLong": "(Neutrals):\nAs the Necromancer, you win when you're the last one standing.\nAdditionally when someone tries to kill you, you will block the kill, and you will teleport to a random vent. You will have a limited time to kill your killer. If you succeed in doing so, you live. If the time runs out before you kill your killer, you die permanently. If you try to kill someone else other than your killer, you will die.", - "ShockerInfoLong": "(Neutrals):\nAs the Shocker, you can mark rooms by doing tasks in them, and then vent to Electrocute anyone in those rooms for a set period of time. When you finish all of your tasks, you get new ones. Note: Doing tasks during that period will mark them for the next ability use.", "LastImpostorInfoLong": "(Add-ons):\nThis special effect is given to the last surviving Impostor. It significantly reduces their kill cooldown.", "OverclockedInfoLong": "(Add-ons):\nAs the Overclocked, your kill cooldown is reduced by a percentage.\n\nThis feature is only assigned to roles with a kill button.", "LoversInfoLong": "(Add-ons):\nLovers are a combination of two players. The Lovers win when they are the last ones standing, and their victory is shared. When one of the Lovers wins, the other also wins together. Lovers can see the 「♥」 next to each other's name. If one of the Lovers dies, the other will die in love (may not die in love according to the Host's settings). When one of the Lovers is exiled in the meeting, the other will die and become a dead body that cannot be reported.", @@ -981,7 +967,7 @@ "RebirthInfoLong": "(Add-ons):\nAs the Rebirth, if you're the player about to be ejected, you will swap skins with a random crewmate who voted for you.\nNotice: The host vote never counts\nRebirth will be removed from you if you exhausted all your rebirths.", "LoyalInfoLong": "(Add-ons):\nAs the Loyal, you cannot be recruited by roles such as Jackal or Cultist.\n\nCannot be assigned to neutrals.", "EvilSpiritInfoLong": "(Add-ons):\nAs Evil Spirit, it's your job to help the Spiritcaller to victory. You can use your Haunt button to freeze players and reduce their vision. Alternatively, you can use your Haunt button to give the Spiritcaller a shield against a kill attempt temporarily.", - "RecruitInfoLong": "(Betrayal Add-ons):\nAs a recruit, you are on the Jackal's team and help out the Jackal and their Sidekicks.\nYou cannot win with your original team.\nDepending on the settings, you may turn into Jackal if old Jackal was killed and no sidekicks is alive.", + "RecruitInfoLong": "(Betrayal Add-ons):\nAs a recruit, you are on the Jackal's team and help out the Jackal and their Sidekicks.\n\nYou cannot win with your original team.", "AdmiredInfoLong": "(Betrayal Add-ons):\nAs an admired player, you win with the crew and not your original team.\n\nYou can see the Admirer.", "GlowInfoLong": "(Add-ons):\nDuring lights out, you and players nearby you will receive a vision boost.", "RadarInfoLong": "(Add-ons):\nAs Radar, you have arrows pointing towards the closest person at all times.", @@ -1025,7 +1011,6 @@ "ProhibitedInfoLong": "(Add-ons):\nAs the Prohibited, you have specific vents that you can't use.\nHow many vents are disabled depends on the Host's settings.", "EavesdropperInfoLong": "(Add-ons):\nAs the Eavesdropper, you have a chance to read other role/addon information-based messages like Mortician or Sleuth.", "ApocalypseInfoLong": "(Apocalypse):\nApocalypse members are on a separate team that works together and wins together. If there are multiple Apocalypse roles in the game, they can see each other's roles.\nDepending on the Host's settings, Apocalypse roles can guess or be guessed.", - "RevenantInfoLong": "(Neutral):\nAs the Revenant, your goal is to be killed. If you are killed, you will take your killer's role and kill your killer instead. You cannot win before being killed.\nNote that Revenant only works when being directly killed.", "ShowTextOverlay": "Text Overlay", "Overlay.GuesserMode": "Guesser Mode", "Overlay.NoGameEnd": "No Game End", @@ -1039,8 +1024,6 @@ "AbilityUseLimit": "Initial Ability Use Limit", "AbilityInUse": "Ability in use", "AbilityExpired": "Ability expired, {0} uses remain", - "RevenantTargeted": "Your role has changed to {0}", - "RevenantCanCopyAddons": "Can Steal Addons", "ShowArrows": "Has Arrows pointing toward bodies", "ArrowDelayMin": "Minimum Arrow show-up delay", "ArrowDelayMax": "Maximum Arrow show-up delay", @@ -1370,8 +1353,6 @@ "ShieldedCanUseKillButton": "Shielded player can use ability / kill button", "PlayerIsShieldedByGame": "Player is protected by the game!", "LegacyNemesis": "Use Legacy Version", - "LegacyParasite": "Use Legacy Version", - "LegacyTraitor": "Use Legacy Version", "ArsonistKeepsGameGoing": "Arsonist keeps the game going", "ArsonistCanIgniteAnytime": "Can Ignite Anytime", "ArsonistMinPlayersToIgnite": "Minimum doused needed for ignite", @@ -1514,18 +1495,6 @@ "SheriffCanKillSeparately": "Individual Settings", "In%team%": "(Team %team%)", "SheriffMisfireKillsTarget": "Misfire Kills Target", - "BlackHolePlaceCooldown": "Black Hole Place Cooldown", - "BlackHoleDespawnMode": "Black Hole Despawn Mode", - "BlackHoleDespawnTime": "Time After Black Hole Despawns", - "Abyssbringer.Suffix": "<#00ffa5>Number of players consumed by {0} <#00ffa5>active black holes:\\n{1}", - "Abyssbringer.Suffix.BlackHole": "<#00ffa5>{0}: {1}", - "BlackHoleMovesTowardsNearestPlayer": "Black Hole Moves Towards Nearest Player", - "BlackHoleMoveSpeed": "Black Hole Moving Speed", - "BlackHoleRadius": "Black Hole Consuming Radius", - "AfterTime": "After Time", - "After1PlayerEaten": "After 1 Player Was Eaten", - "AfterMeeting": "After Meeting", - "None": "None", "SheriffShotLimit": "Max number of Kills", "SheriffCanKillAllAlive": "Can Kill When No One Is Dead", "SheriffCanKillCharmed": "Can kill Charmed players", @@ -1542,15 +1511,12 @@ "RebirthUses": "Amount of Rebirths", "RebirthCountVotes": "Only rebirth to players who voted for them", "RebirthFailed": "Ahh, how unfortunate, you did not find any viable souls to swap bodies with", - "FireworkerCooldown": "Placement Cooldown", "ReverieIncreaseKillCooldown": "Increase kill cooldown", "ReverieMaxKillCooldown": "Max kill cooldown", "ReverieMisfireSuicide": "Misfire on reaching max kill cooldown", "ReverieResetCooldownMeeting": "Reset kill cooldown after meeting", "ConvertedReverieKillAll": "Converted Reverie can kill anyone without repercussions", "VigilanteNotify": "You have become the very thing you swore to destroy", - "DictatorChangeCommandToExpel": "Dictator use Command to expell instad of vote", - "DictatorExpelSelf": "WAIT WAIT WAIT WAT THE HELLLLLL Bro really just want to expel himself", "DoctorTaskCompletedBatteryCharge": "Battery Duration", "SnitchEnableTargetArrow": "See Arrow Towards Target", "SnitchCanGetArrowColor": "See Colored Arrows based on Team Colors", @@ -1624,6 +1590,7 @@ "TimeThiefDecreaseMeetingTime": "Lower Meeting Time by", "TimeThiefLowerLimitVotingTime": "Minimum Voting Time", "TimeThiefReturnStolenTimeUponDeath": "Return Stolen Time Upon Death", + "TimeThiefMaxTimeOnAdmired": "Maximum Meeting Time if Time Thief Is Admired", "EvilTrackerCanSeeKillFlash": "Can See Kill-Flash", "EvilTrackerCanSeeLastRoomInMeeting": "Can See Target's Last Room In Meeting", "EvilTrackerTargetMode": "Can Set Target", @@ -1631,7 +1598,6 @@ "EvilTrackerTargetMode.OnceInGame": "Once in-game", "EvilTrackerTargetMode.EveryMeeting": "Every Meeting", "EvilTrackerTargetMode.Always": "Any time", - "ScavengerHasCustomDeathReason": "Enable Custom Death Reason", "EvilHackerCanSeeDeadMark": "Can See The Location of Dead-bodies", "EvilHackerCanSeeImpostorMark": "Can See The Location of Other Impostors", "EvilHackerCanSeeKillFlash": "Can See Kill-Flash", @@ -1864,21 +1830,13 @@ "Jackal_SidekickCountMode_Jackal": "Jackal", "Jackal_SidekickCountMode_Original": "Original Team", "Jackal_SidekickAssignMode": "Sidekick Assign Mode", - "Jackal_SidekickAssignMode_SidekickAndRecruit": "Sidekick when failed Recruit", - "Jackal_SidekickAssignMode_Sidekick": "Only Sidekick", - "Jackal_SidekickAssignMode_Recruit": "Only Recruit", + "Jackal_SidekickAssignMode_SidekickAndRecruit": "Sidekick+Recruit", + "Jackal_SidekickAssignMode_Sidekick": "Sidekick Only", + "Jackal_SidekickAssignMode_Recruit": "Recruit Only", + "JackalWinWithSidekick": "Jackal can win with Sidekick's team", "Jackal_SidekickCanKillSidekick": "Sidekicks can kill other Sidekicks", "Jackal_SidekickCanKillJackal": "Sidekick can kill Jackal", - "Jackal_RecruitFailed": "You can not recruit this player!", "JackalCanKillSidekick": "Jackal can kill Sidekick", - "Jackal_SidekickCanKillWhenJackalAlive": "Sidekick can kill while Jackal is Alive", - "Jackal_SidekickTurnIntoJackal": "Sidekick can turn into Jackal after its death", - "Jackal_RestoreLimitOnNewJackal": "Restore Recruit limit when Sidekick become new Jackal", - "Jackal_OnBecomeNewJackalMeeting": "The old Jackal {0} is dead.\nYou are selected as new Jackal\nWork together and win the game!", - "Jackal_OnNewJackalSelectedMeeting": "The old Jackal {0} is dead.\n{1} is selected as new Jackal!\nWork together and win the game!", - "Jackal_BecomeNewJackal": "Old Jackal Dead, You are now new Jackal!", - "Jackal_OnNewJackalSelected": "Old Jackal Dead, Please help new Jackal {0} for now!", - "Jackal_BossIsDead": "Opps, the Jackal boss is dead!", "CoronerArrowsPointingToDeadBody": "Arrows pointing to dead bodies", "CoronerLeaveDeadBodyUnreportable": "Bodies the Coroner uses can't be reported", "CoronerInformKillerBeingTracked": "Inform the Killer that he gets tracked", @@ -1916,9 +1874,6 @@ "VipTag": "VIP★", "ApplyVipList": "Apply VIP List", "AllowSayCommand": "Allow moderators to use /say command", - "AllowStartCommand": "Allow moderators to use /start command", - "StartCommandMinCountdown": "Minimum countdown for /start command", - "StartCommandMaxCountdown": "Maximum countdown for /start command", "KickCommandDisabled": "The kick command is currently disabled.", "KickCommandNoAccess": "You do not have access to the kick command.", "KickCommandInvalidID": "Invalid player ID specified.\nPlease use '/kick [playerID] [reason]' to kick a player.\nExample :- /kick 5 not following rules", @@ -1951,11 +1906,6 @@ "WarnCommandNoAccess": "You do not have access to the warn command.", "WarnCommandInvalidID": "Invalid player ID specified.\nPlease use '/warn [playerID] [reason]' to warn a player. \nExample :- /warn 5 lava chatting", "WarnCommandWarnHost": "You are not permitted to warn the host.", - "StartCommandNoAccess": "You do not have access to the start command.", - "StartCommandDisabled": "The start command is currently disabled.", - "StartCommandCountdown": "ERROR\n\nThe game is already starting!", - "StartCommandStarted": "The game has been started by {0}!", - "StartCommandInvalidCountdown": "ERROR\n\nThe countdown must be between {0} and {1}!", "WarnCommandWarnMod": "You are not permitted to warn other moderators.", "WarnCommandWarned": "has been warned. There will be no more warnings given and appropriate action will be taken \n ", "WarnExample": "Use /warn [id] [reason] in future. \nExample :-\n /warn 5 lava chatting", @@ -1983,7 +1933,6 @@ "DeathReason.Quantization": "Quantization", "DeathReason.Overtired": "Overtired", "DeathReason.Ashamed": "Ashamed", - "DeathReason.Consumed": "Consumed", "DeathReason.PissedOff": "Destroyed", "DeathReason.Dismembered": "Dismembered", "DeathReason.LossOfHead": "Strangled", @@ -2007,8 +1956,6 @@ "DeathReason.Starved": "Starved", "DeathReason.Equilibrium": "Equilibrium", "DeathReason.Sacrificed": "Sacrificed", - "DeathReason.Electrocuted": "Electrocuted", - "DeathReason.Scavenged": "Scavenged", "OnlyEnabledDeathReasons": "Only Enabled Death Reasons", "Alive": "Alive", "Disconnected": "Disconnected", @@ -2024,10 +1971,11 @@ "DeputyHandcuffCooldown": "Handcuff Cooldown", "DeputyHandcuffMax": "Maximum Handcuffs", "DeputyHandcuffedPlayer": "Handcuffed target", - "HandcuffedByDeputy": "You were handcuffed!", - "DeputyInvalidTarget": "Target cannot be handcuffed", + "HandcuffedByDeputy": "You were handcuffed!\nNow you have broken your handcuff and can kill again.", + "DeputyInvalidTarget": "Target is already handcuffed", + "HandcuffBrokenAfterMeeting": "Remove all handcuffs after meeting", "DeputyHandcuffText": "Handcuff", - "DeputyHandcuffCDForTarget": "Kill Cooldown for handcuffed player", + "DeputyHandcuffCDForTarget": "Next Kill Cooldown for handcuffed player", "RejectShapeshift.AbilityWasUsed": "Ability was used", "EscapisMtarkedPosition": "You marked self-position", "InvestigateCooldown": "Investigate Cooldown", @@ -2074,7 +2022,6 @@ "Command.dump": "→ Output Log to Desktop", "Command.death": "→ Display info on how you died", "Command.icons": "
╳ - The Player was marked by the Blackmailer and can't talk during the Meeting
☆ - Used by Captain to display themselves. Only Crewmates can see the Captain's star
乂 - This player was hexed by the Hex Master and will die if the Hex Master isn't killed or ejected by the end of the Meeting.
♦ - Used by Lawyer or Executioner or Follower.
♥ - Used by Lovers or Romantic.
✚ - Used by Medic to mark their target.
⦿ - This player is in a duel with the Pirate.
!? - This player was marked by the Quizmaster and must answer the question correctly to survive.
☜ - Used by Schrödinger's cat to mark their teammate.
◈ - This player marked by the Shroud and will die if the Shroud is not killed or ejected by the end of the meeting.
⚠ - This player is a Snitch or Solsticer who has finished their tasks.
★ - Used by Super Star or Cyber or Marshall.
† - This player was spelled and will die if the Witch is not killed by the end of the meeting.
∇ - Used by Kamikaze to mark their targets.
■ - Used by Lightning to mark their quantum ghosts.
⊠ - Used by Jailer to mark their prisoner.
● - Used by Baker to mark who has Bread.
♠ - Used by Soul Collector to mark who's death they're predicting.
⦿ - Used by Plaguebearer to mark who they have plagued.", - "Command.start": "[Seconds] → Start the game", "Command.iconinfo": "→ Display info on in-meeting icons", "Command.iconhelp": "→ Display info on in-meeting icons to everyone", "Command.Poll": "→ Start a poll with up-to 5 choices", @@ -2087,7 +2034,6 @@ "ShowMadmatesInLeftCommand": "Show Madmates (including add-ons)", "ShowApocalypseInLeftCommand": "Show Neutral Apocalypse", "SeeEjectedRolesInMeeting": "See ejected roles in meetings", - "ThankYouForUsingTOHE": "Thank you for using TOHE!", "SkillUsedLeft": "You have activated your skill to call a meeting. \nRemaining amount of uses left:", "NemesisDeadMsg": "The death of the Nemesis means the beginning of the revenge. \nPlease use /rv + [player ID] to kill the specified player \nYou can see player IDs in front of their names. \nOr type /rv to get a list of player IDs", "NemesisAliveKill": "Revenge for the Nemesis can only begin after their death.", @@ -2107,7 +2053,6 @@ "GuessNotifiedBait": "Bait can't be guessed because it was announced. You thought it would be that easy, right?", "GuessGM": "Guessing the GM is impossible because they're already dead.... And why would you do that to the poor Host?", "GuessGuardianTask": "You can't guess a Guardian who has finished their tasks.", - "GuardianCantKilled": "You can't kill a Guardian who has finished their tasks.", "GuessMarshallTask": "You can't guess a Marshall who has finished their tasks.", "GuessObviousAddon": "Sorry, obvious add-ons cannot be guessed.", "GuessAdtRole": "Unfortunately, the Host's settings do not allow you to guess add-ons", @@ -2163,7 +2108,6 @@ "BecomeMadmateCuzMadmateMode": "You became a Madmate because you died", "CleanerCleanBody": "The body has been cleaned", "QuickShooterStoraging": "Bullets stored successfully", - "QuickShooterFailed": "You are still in cooldown.", "PoisonerTargetDead": "Target died", "HexesLookLikeSpells": "Hexes appear as spells", "HexButtonText": "Hex", @@ -2322,7 +2266,6 @@ "Message.YTPlanNotice": "Note: The [YouTuber Plan] is enabled in this lobby, which means the Host can specify their role in the next game to make it easier to get content. If the Host abuses this feature, please exit the game or report it.\nCurrent Creator Credentials:", "Message.OnlyCanBeUsedByHost": "ERROR\n\nThis command may only be used by the host.", "Message.MaxPlayers": "Maximum players set to ", - "Message.MaxPlayersFailByRegion": "Could not set max players: Vanilla regions support a maximum of 15 players.", "Message.GhostRoleInfo": "Ghost Role Info\nHiya! A little about ghost roles...\n\nGhost roles drastically impact the game, so it's not recommended for smaller lobbies if you're unfamiliar. If not explicitly stated otherwise in the description, the Guard button is their ability button ;)\n\nSpawning:\nGhost-roles only spawn after death; the first x people from (team) to die get them.\n\nPS: If your previous role didn't have tasks(e.g., sheriff), your tasks as a ghost-role aren't needed for task-win", "ApocalypseInfoTitle": "Neutral Apocalypse Info:", "Message.ApocalypseInfo": "Every role of the <#ff174f>Apocalypse Team has their own objective to carry out in order to transform.\n<#2B0804>Transformed <#ff174f>Apocalypse members have a drastic change on the game and are immortal (except for being voted), but everyone will be notified that they have transformed.\n\nRoles: <#e5f6b4>Plaguebearer, <#A675A1>Soul Collector, <#bf9f7a>Baker, <#cc0044>Berserker\nTransformed: <#343136>Pestilence, <#644661>Death, <#83461c>Famine, <#2B0804>War\n\nApocalypse members can see eachother's roles and ability icons.\nLike Neutral Killers, Apocalypse members keep the game going as well, have fun!", @@ -2454,6 +2397,7 @@ "LastResult": "★ Match Results", "LastEndReason": "★ End Reason", "KillLog": "Kill Log", + "MainRoleLog": "Role Convert Log", "Maximum": "Max", "RoleRate": "ON", "RoleOn": "ALWAYS", @@ -2730,9 +2674,8 @@ "DeathMeetingTimeIncrease": "Increased Meeting time when Death exists", "SoulCollectorMeetingDeath": "Your target has died during the meeting. You have gained a soul.", "SoulCollectorKillButtonText": "Predict", - "SoulCollectorHasImpostorVision": "Soul Collector has Impostor vision", "ApocalypseIsNigh": "[ The Apocalypse Is Nigh! ]", - "ApocalypseImmune": "This role is immune!", + "ApocalypseImmune": "This player is immune because they are invincible!", "BakerToFamine": "You have become Famine!!!", "BakerTransform": "The Baker has transformed into Famine, Horseman of the Apocalypse! A famine has begun!", "BakerAlreadyBreaded": "That player already has bread!", @@ -2741,15 +2684,13 @@ "BakerBreadNeededToTransform": "Required number of bread to become Famine", "BakerCantBreadApoc": "You cannot give other Apocalypse members bread!", "BakerKillButtonText": "Bread", - "BakerUnshiftButtonText": "Switch Bread", "BakerRevealBread": "Reveal", "BakerRoleblockBread": "Roleblock", "BakerBarrierBread": "Barrier", "BakerCurrentBread": "Current Bread: ", "BakerSwitchBread": "Bread Switched to: ", - "BakerCanVent": "Baker can Vent", + "BakerCanVent": "Baker can Vent", "BakerBreadGivesEffects": "Bread gives additional effects", - "BakerTransformNoMoreBread": "Baker transforms if they do not have enough bread", "FamineKillButtonText": "Starve", "FamineStarveCooldown": "Famine starve cooldown", "FamineCantStarveApoc": "You cannot starve other Apocalypse members!", @@ -2796,7 +2737,6 @@ "GodfatherTargetCountMode": "Killer turns into", "GodfatherCount_Refugee": "Refugee", "GodfatherCount_Madmate": "Madmate", - "GodfatherRefugeeMsg": "You have been recruited by GodFather!", "MissChance": "Chance To Miss", "IncreaseByOneIfConvert": "Increase The KillCount +1 If a Crew Is Converted", "HawkMissed": "Missed!", @@ -2829,7 +2769,6 @@ "BerserkerToWar": "You have become War!!!", "BerserkerTransform": "The Berserker has transformed into War, Horseman of the Apocalypse! Cry 'Havoc!', and let slip the dogs of war.", "WarKillCooldown": "War kill cooldown", - "BerserkerCanKillTeamate": "Can kill other Neutral Apocalypse", "BlackmailerSkillCooldown": "Blackmail Cooldown", "BlackmailerMax": "Maximum times blackmailed players may speak", "BlackmailerDead": "Warning! {0} has been blackmailed by a Blackmailer!", @@ -2919,8 +2858,6 @@ "RememberedPursuer": "You remembered you were a Pursuer!", "RememberedFollower": "You remembered you were a Follower!", "RememberedAmnesiac": "You failed to remember your role.", - "AmnesiacRemembered": "You remembered you were {0}!", - "ReportWhenFailedRemember": "Report Dead Body when failed to remember", "RememberedImitator": "You remembered you were an Imitator.", "RememberedImpostor": "You remembered you were an Impostor!", "RememberedCrewmate": "You remembered you were a crewmate!", @@ -3146,7 +3083,7 @@ "DollMaster_PossessedTarget": "Possessed target", "DollMaster_CannotPossessImpTeammate": "Unable to possess teammate", "DollMaster_CouldNotSwapWithTarget": "Unable to possess player", - "DollMaster_CanNotSwapWithDeadTarget": "Possesing a dead player isn't possible", + "DollMaster_CanNotSwapWithDeadTarget": "Possessing a dead player isn't possible", "DollMaster_MainBody": "Main Body", "DollMaster_Doll": "Doll", "DollMaster_UnableToUseAbility": "Unable to use your ability on player", @@ -3334,12 +3271,9 @@ "PixieTargetAlreadySelected": "Target is already selected", "PixieButtonText": "Mark", "PlagueBearerCooldown": "Plague cooldown", - "PlagueBearerCanVent": "Can vent", - "PlagueBearerHasImpostorVision": "Has Impostor vision", "PestilenceCooldown": "Pestilence Kill cooldown", "PestilenceCanVent": "Pestilence Can Vent", "PestilenceHasImpostorVision": "Pestilence Has Impostor Vision", - "PestilenceKillGuessers": "Kill players who guess Pestilence", "PlagueBearerAlreadyPlagued": "Player has already been plagued", "PlagueBearerToPestilence": "You have turned into Pestilence!!", "GuessPestilence": "You just tried to guess Pestilence!\n\nSorry, Pestilence killed you.", @@ -3383,7 +3317,6 @@ "EveryoneCanKnowMini": "Everyone can see the Mini", "CanBeEvil": "Mini can be an Impostor", "EvilMiniSpawnChances": "Probability of Mini being an Impostor", - "EvilMiniCanBeGuessed": "Evil Mini can be guessed before 18", "GuessMini": "Sorry, you can't hurt a kid Mini.", "GrowUpDuration": "Time required to grow (s)", "MajorCooldown": "Kill Cooldown when over 18", @@ -3525,7 +3458,6 @@ "WinnerRoleText.Doppelganger": "Doppelganger Wins!", "WinnerRoleText.Quizmaster": "Quizmaster Wins!", "WinnerRoleText.Agitater": "Agitator Wins!", - "WinnerRoleText.Shocker": "Shocker Wins!", "AdditionalWinnerRoleText.Sidekick": "Sidekick", "AdditionalWinnerRoleText.Taskinator": "Taskinator", "AdditionalWinnerRoleText.Opportunist": "Opportunist", @@ -3611,7 +3543,7 @@ "SolsticerOnMeeting": "You witnessed too many deaths! Next round you will have {0} more short task!", "SolsticerTitle": "Solsticer", "GuessSolsticer": "Sorry, but you can not guess Solsticer!", - "ExpelSolsticer": "Sorry, but you can not expel Solsticer!", + "VoteSolsticer": "Sorry, but you can not vote Solsticer!", "SolsticerTasksReset": "Your tasks get reset!", "SolsticerMisGuessed": "You just misguessed! You are no longer allowed to guess.", "SolsticerGuessMax": "Because you already misguessed, you are no longer allowed to guess.", @@ -3712,19 +3644,6 @@ "MinionAbilityTime": "Ability Duration", "Minion_Blind": "blinded", "Evader_ChanceNotExiled": "Chance not be exiled", - "ShockerAbilityCooldown": "Ability Cooldown", - "ShockerAbilityDuration": "Ability Duration", - "ShockerAbilityPerRound": "Abilities Per Round", - "ShockerShockInVents": "Shock people in vents", - "ShockerAbilityResetAfterMeeting": "Reset marked rooms after meeting", - "ShockerOutsideRadius": "Radius Of Outside Tasks (not in a room)", - "ShockerCanShockHimself": "Can Shock Himself", - "ShockerImpostorVision": "Shocker has Impostor vision", - "ShockerIsShocking": "You're already shocking!", - "ShockerAbilityActivate": "Begin Shocking!", - "ShockerAbilityDeactivate": "Ability Deactivated", - "ShockerVentButtonText": "Shock", - "ShockerRoomMarked": "Marked Room", "EavesdropperMsgTitle": "You found a secret", "EavesdropPercentChance": "Chance to eavesdrop", "ChiefOfPoliceSkillCooldown": "Cooldown for recruiting sheriffs", @@ -3736,4 +3655,4 @@ "PolicPreventRecruitNonKiller": "Prevent recruit players without kill button", "PolicSuidiceWhenTargetNotKiller": "Suidices when recruit a non killer or non crewmate", "PolicPassConverted": "Can pass Converted Addon to Sheriff" -} +} \ No newline at end of file diff --git a/Resources/Lang/nl_NL.json b/Resources/Lang/nl_NL.json index d723084e9..012a87459 100644 --- a/Resources/Lang/nl_NL.json +++ b/Resources/Lang/nl_NL.json @@ -20,8 +20,6 @@ "SubText.Neutral": "Werk alleen om je overwinning te behalen", "SubText.Apocalypse": "Become unstoppable with your team", "SubText.Madmate": "Help de Bedriegers", - "SubText.Lovers": "Stay alive and win together", - "SubText.Egoist": "Win on your own", "TypeImpostor": "Bedriegers", "TypeCrewmate": "Bemanningsleden", "TypeNeutral": "Neutralen", @@ -31,9 +29,6 @@ "TeamNeutral": "Neutraal", "TeamCrewmate": "Bemanningslid", "TeamMadmate": "Gekke", - "TeamLovers": "Lovers", - "TeamEgoist": "Egoist", - "TeamApocalypse": "Apocalypse", "YouAreCrewmate": "Je bent een Bemanningslid", "YouAreImpostor": "Je bent een Bedrieger", "YouAreNeutral": "Je bent een Neutraal", @@ -225,7 +220,6 @@ "TaskManager": "Taakmanager", "Witness": "Getuige", "Swapper": "Swapper", - "ChiefOfPolice": "Chief of Police", "NiceMini": "Goeie Mini", "Mini": "Goeie Mini", "Spy": "Spion", @@ -254,7 +248,6 @@ "Stalker": "Stalker", "Workaholic": "Werkverslaafde", "Solsticer": "Zonnewende", - "Abyssbringer": "Abyssbringer", "Collector": "Verzamelaar", "Provocateur": "Provocateur", "BloodKnight": "Bloedsridder", @@ -393,8 +386,6 @@ "Sloth": "Sloth", "Prohibited": "Prohibited", "Eavesdropper": "Eavesdropper", - "Shocker": "Shocker", - "Revenant": "Revenant", "BracketAddons": "Voeg brackets toe aan toevoegingen", "EngineerTOHEInfo": "Gebruik de vents om de Bedriegers te vinden", "ScientistTOHEInfo": "Heb overal toegang tot draagbare vitale functies", @@ -513,7 +504,7 @@ "PacifistInfo": "Vent to reset kill cooldowns", "RebirthInfo": "Arise Again", "MonarchInfo": "Geef de bemanning extra stemkracht!", - "AbyssbringerInfo": "Place Black Holes", + "AbyssbringerInfo": "Create Black Holes", "SpurtInfo": "Spring Like A rabbit!", "StealthInfo": "Als je blinden doodt, wordt iedereen in de kamer gedood", "PenguinInfo": "Sleep je slachtoffers", @@ -538,7 +529,7 @@ "AdmirerInfo": "Kies een speler die jou gaat helpen", "TimeMasterInfo": "Terugspoel tijd!", "CrusaderInfo": "Dood een speler zijn aanvaller", - "AltruistInfo": "Revive a player", + "AltruistInfo": "Revive a player\nVent to change between Revive and Report", "ReverieInfo": "Met elke moord die je doet, wordt je cooldown lager", "LookoutInfo": "Zie door vermonningen heen", "TelecommunicationInfo": "Track device usage", @@ -547,7 +538,6 @@ "WitnessInfo": "Kom erachter of iemand recent een ander heeft vermoord", "GhastlyInfo": "Control somebody!", "SwapperInfo": "Verwissel de stemmen van twee spelers", - "ChiefOfPoliceInfo": "Hire Sheriff to Serve the Crews!", "NiceMiniInfo": "Niemand kan je pijn doen totdat je gegroeid bent.", "ArsonistInfo": "Blus iedereen en verbrand", "PyromaniacInfo": "Blus en dood iedereen", @@ -603,7 +593,7 @@ "VultureInfo": "Eet lichamen door ze te rapporteren om te winnen", "TaskinatorInfo": "Stille taken, dodelijke knallen", "BenefactorInfo": "Taak voltooid, schild elite!", - "MedusaInfo": "Versteen lijken door ze te rapporteren", + "MedusaInfo": "Stone bodies by reporting them", "SpiritcallerInfo": "Verander spelers naar Kwaadaardige Geesten", "AmnesiacInfo": "Herinner de rol van een dood lijk", "ImitatorInfo": "Imiteer een spelers rol", @@ -615,19 +605,19 @@ "ShroudInfo": "Omhels spelers om ze te laten doden", "WerewolfInfo": "Dood bemanningsleden in groepen", "ShamanInfo": "Deflecteer alle aanvallen op een Voodoo pop", - "SeekerInfo": "Speel verstoppertje met jouw doel", + "SeekerInfo": "Play Hide and Seek with your target\nYour target has a ★ mark.", "PixieInfo": "Tag ze, zak ze en werp ze uit!", "OccultistInfo": "Dood en beheks jouw tegenstanders", "SchrodingersCatInfo": "De kat is levend en dood tegelijkertijd totdat het een maatje krijgt.", "RomanticInfo": "Bescherm jouw partner om samen te winnen", "VengefulRomanticInfo": "Revenge jouw partner om samen te winnen", "RuthlessRomanticInfo": "Dood iedereen om te winnen met jouw partner", - "PoisonerInfo": "Dood iedereen met vertraagde kills", + "PoisonerInfo": "Kill everyone with delayed kills", "HexMasterInfo": "Hex spelers om ze dood te maken in meetings", "WraithInfo": "Vent to go invisible temporarily", - "JinxInfo": "Weerkaats aanvallen terug naar jouw aanvallers", + "JinxInfo": "Reflect attacks onto your attackers", "PotionMasterInfo": "Gebruik jouw brouwsels naar jouw voordeel", - "NecromancerInfo": "Dood jouw moordenaar om de dood te trotseren", + "NecromancerInfo": "Kill your killer to defy death", "WardenInfo": "(Geest) Waarschuwing voor gevaar", "MinionInfo": "(Geest) Verblind vijanden", "LoversInfo": "Blijf levend en win samen", @@ -708,8 +698,6 @@ "SlothInfo": "You're slower", "ProhibitedInfo": "Certain vents are blocked", "EavesdropperInfo": "Listen in on other roles", - "ShockerInfo": "Shock unsuspecting players", - "RevenantInfo": "Take your killer's role", "EngineerTOHEInfoLong": "(Bemanningslid):\nAls de werktuigkunde heb je toegang tot de vents terwijl een Comms Sabotage inactief is.", "ScientistTOHEInfoLong": "(Crewmates):\nAs the Scientist, you can see vitals at any time, showing you who is alive and dead.", "NoisemakerTOHEInfoLong": "(Crewmates):\nAs the Noisemaker, whenever you die, you will make a noise, and a visual indicator of your death appears on the screen so the Crewmates can run to catch the person who killed you red-handed (even if it’s not Red).", @@ -781,11 +769,11 @@ "LurkerInfoLong": "(Impostors):\nAs the Lurker, you can jump into a vent to reduce your cooldown by a certain number of seconds. After you kill, your cooldown resets to its original value.", "VisionaryInfoLong": "(Impostors):\nAs the Visionary, you see the alignments of living players during a meeting.\nThe following information will be displayed on the players:\n- The Red name indicates the Impostors.\n- The Cyan name indicates the Crewmates.\n- The Gray name indicates the Neutrals.", "PlagueDoctorInfoLong": "(Neutrals):\n(Plague Doctor from TOH)\nThe Plague Scientist's goal is to infect every living player.\nThey start by choosing one player to infect, after which anyone who spends a set amount of time in the range of the infected player becomes infected themselves.\nInfection progress is cumulative and does not reset with distance or after meetings.", - "RefugeeInfoLong": "(Madmates):\nAs the Refugee, you were either:\n -An Amnesiac who remembered an Impostor\n -A killer who killed the Godfather's target.\n -A Romantic whose partner was an Impostor\n -Or an Imitator that imitated an Impostor.\n\nNow your job is to help the Impostors kill the crewmates.", + "RefugeeInfoLong": "(Madmates):\nAs the Refugee, you were either an Amnesiac who remembered an Impostor or a killer who killed the Godfather's target.\n\nNow your job is to help the Impostors kill the crewmates.", "UnderdogInfoLong": "(Bedriegers):\nAls Underdog kun je niet doden totdat er een bepaald aantal spelers in leven is.", "ConsigliereInfoLong": "(Impostors):\nAs the Consigliere, you can reveal the roles of other players using your kill button.\n\nSingle click: Reveal role\nDouble click: Kill\n\nIf you run out of reveal uses, your kill button functions normally.", "LudopathInfoLong": "(Bedriegers):\nDe Ludopaat zijn kill cooldown is willekeurig.\nDit is minimaal 1 seconde en maximaal je normale kill cooldown.", - "GodfatherInfoLong": "(Impostors):\nAs the Godfather, you vote someone to make them your target.\nIn the next round, if someone kills the target, the killer will turn into a Refugee or Madmate.", + "GodfatherInfoLong": "(Impostors):\nAs the Godfather, you vote someone to make them your target.\nIn the next round, if someone kills the target, the killer will turn into a Refugee.", "ChronomancerInfoLong": "(Impostors):\nAs the Chronomancer, you have a charge bar which indicates when the slaughter is ready. When it is at 100% the next time you kill someone, you go into slaughter mode, meaning you can kill indefinitely until your bar runs out of charge. Otherwise, you have a normal KCD.", "PitfallInfoLong": "(Impostors):\nAs the Pitfall, you use your shapeshift to mark the area around the shapeshift as a trap. Players who enter this area will be immobilized quickly, and their vision will be affected.", "EvilMiniInfoLong": "(Impostors):\nAs the Evil Mini, you are unkillable until you grow up and have a very long initial kill cooldown, which gets drastically shortened as you grow up.", @@ -821,7 +809,7 @@ "GrenadierInfoLong": "(Bemanningslid):\nAls Granaatwerper kun je venten om spelers in de buurt te verblinden, waardoor ze hun zicht verliezen als ze een Bedrieger zijn en afhankelijk van de instellingen, ook Neutralen.", "MedicInfoLong": "(Crewmates):\nThe Medic can place a shield on the target by pressing the Kill button. The Medic can only give one shield for the whole game. Depending on the settings, the target's shield can or cannot deactivate when the Medic dies. The Medic can also see if someone is trying to break the target's shield.\nDepending on the Host's settings, the Medic or the target can see if the player has a shield (shown as a green circle 「●」 next to the name).", "FortuneTellerInfoLong": "(Crewmates):\nAs the Fortune Teller, vote for a player in a meeting to get a clue to their role.\nThe clue will relate to their actual role.\n\nWhen the Fortune Teller's tasks are complete, they will obtain the exact role rather than a clue!\n\nNote: If the setting to give random active players as a hint is on, you cannot check the same player multiple times.", - "JudgeInfoLong": "(Crewmates):\nThe Judge can judge a certain player during the meeting. If the target is evil, the target will be killed (whether it is evil or not is set by the Host). If it is wrong, the Judge commits suicide.\nCommand for judgment: /tl [player id]\nYou can see the player's id before the player's name, or use the /id command to view the id of all players.\nJudges can judge all players when they become Madmate.", + "JudgeInfoLong": "(Crewmates):\nThe Judge can judge a certain player during the meeting. If the target is evil, the target will be killed (whether it is evil or not is set by the Host). If it is wrong, the Judge commits suicide.\nCommand for judgment: /tl [player id]\nYou can see the player's id before the player's name, or use the /id command to view the id of all players.\nJudges can judge all players when they become Madmate.\nIn meeting the ability count shows how many trails you have in this meeting. Out of meeting the ability counts shows how many trails you have for the whole game.", "MorticianInfoLong": "(Crewmates):\nThe Mortician can see arrows pointing to all dead bodies, and if the Mortician reports a body, they will know the last player the victim had contact with. Note: Mortician won't be Oblivious or Seer.", "MediumInfoLong": "(Crewmates):\nThe Medium can establish contact with a dead player after someone reports a dead body. The player who reports doesn't have to be the Medium. The dead player can answer once with a YES or a NO to the Medium's question, which only the Medium will see (the dead player can use /ms yes or /ms no). Note: Medium won't be Oblivious.", "ObserverInfoLong": "(Crewmates):\nAs the Observer, you can see all shield animations caused by other players after the first meeting. The shied animations typically indicate a role ability, so look out for this.", @@ -833,7 +821,7 @@ "MerchantInfoLong": "(Crewmates):\nAs a merchant, you sell a random add-on to a random player for each task you complete. Each add-on sold earns you money. If you have a certain amount of money, you can prevent the next killing attempt against you by bribing the murderer. The bribed player won't be able to kill you, but you don't know who it is. The money used is lost and not available for additional bribes.", "RetributionistInfoLong": "(Crewmates):\nAs the Retributionist, you can kill a limited amount of players after your death.\n\nUse /ret [playerID] to kill.", "HawkInfoLong": "(Crewmates [Ghost]):\nAs the Hawk, you can kill a limited amount of players decided by the host, though there's a chance you miss, slicing someone multiple times increases the chances.", - "DeputyInfoLong": "(Bemanningslid):\nGebruik als Adjunct je kill knop op een speler om zijn kill cooldown te resetten.\n\nAls het doelwit geen kill knop heeft, zijn de handboeien een verspilling.", + "DeputyInfoLong": "(Crewmates):\nAs the Deputy, use your kill button to handcuff a player.\nThe player who is handcuffed will have their next kill attempt treated as a handcuff break, and the kill cooldown will be reset.\n\nIf the target does not have a kill button, then the handcuff was a waste.", "InvestigatorInfoLong": "(Crewmates):\nAs an Investigator, you can use your kill button to investigate someone. When you investigate someone, their name will appear in red if they possess a kill button (impostor/SS basis) or light blue if they lack a kill button (crewmate/engineer/scientist basis). However, please note that the color of the names will return to normal when someone calls a meeting.", "GuardianInfoLong": "(Crewmates):\nAs the Guardian, you become immortal upon task completion. Guessers can't even guess you in meetings.", "AddictInfoLong": "(Crewmates):\nAs the Addict, you have a suicide timer. When it expires, you kill yourself.\nThe timer is indicated by the vent cooldown. When the vent cooldown is 0 seconds, you still have a short time to vent.\nIf you don't make it, you die; if you make it, the suicide timer is reset.\nAlso after you vent, no one can interact with you for a defined period.\nAfter; the period is over, and you are immobilized for another defined period, and cannot report any bodies.", @@ -849,7 +837,7 @@ "AdmirerInfoLong": "(Crewmates):\nAs the Admirer, admire a player to make them Crewmate aligned.\nThey'll win with crewmates and not their original team.\n\nYou can only do this once per player.", "TimeMasterInfoLong": "(Crewmates):\nAs the Time Master, use the vents to mark everyone's position.\nWhen using the ability again, every alive player will rewind to the marked positions.\n\nDuring the ability duration, the Time Master gains a time shield, which protects them from death.", "CrusaderInfoLong": "(Bemanningslid):\nGebruik als kruisvaarder je kill knop om een speler te beschermen.\nAls die speler wordt aangevallen, dood je de aanvaller.", - "AltruistInfoLong": "(Crewmates):\nAs the Altruist, you can sacrifice yourself to revive a dead body using the «Report» button.\nNote: If a dead player has left the game, you report that body normally.\nAlso revived player cannot report self dead body", + "AltruistInfoLong": "(Crewmates):\nAs the Altruist, you can sacrifice yourself to revive a dead body using the «Report» button.\nNote: If a dead player has left the game, you report that body normally.\nAlso revived player cannot report self dead body\nUse vent button to change between Report & Revive.", "ReverieInfoLong": "(Crewmates):\nAs the Reverie, you can kill, but your cooldown starts high.\n\nIt increases if you kill a crewmate and reduces otherwise.\nDepending on the Host's setting, you may misfire on reaching the max kill cooldown, and your target dies with you. \n\nYou win with other crewmates.", "LookoutInfoLong": "(Bemanningslid):\nAls uitkijk kun je altijd de ID's van elke speler zien.\nHierdoor kun je door vormveranderingen en camouflages heen kijken.", "TelecommunicationInfoLong": "(Crewmates):\nAs the Telecommunication, you are notified when anyone uses cameras, vitals, door logs, or admin.", @@ -872,7 +860,7 @@ "LawyerInfoLong": "(Neutralen):\nDe Advocaat heeft een doelwit die ze moeten verdedigen. Dit doelwit wordt aangegeven met een diamant 「♦」 naast hun naam.\nAls je doelwit wint, win jij ook. \nAls die verliest, verlies jij ook.", "OpportunistInfoLong": "(Neutralen):\nAls de Opportunist aan het einde van het spel overleeft, wint de Opportunist met de winnende speler.", "VectorInfoLong": "(Neutrals):\nVector will win alone by venting a certain number of times.", - "JackalInfoLong": "(Neutrals):\nAs the Jackal, you win if you are the last player alive. Additionally, you may recruit using the kill button. If the target is not one you can recruit, you have run out of uses, or you don't have the option to recruit, then you will kill people normally (i.e., don't use kill buttons in front of others thinking it'll recruit). If the target has a kill button and the option to turn into a Sidekick is on, they will become a Sidekick. Otherwise, they will gain the Recruit add-on if the option to give the Recruit add-on is on.\nDepending on the settings, when Jackal was killed, a Sidekick will be randomly selected as the new Jackal.\nRecruit may be selected if no sidekick is alive.", + "JackalInfoLong": "(Neutrals):\nAs the Jackal, you win if you are the last player alive. Additionally, you may recruit using the kill button. If the target is not one you can recruit, you have run out of uses, or you don't have the option to recruit, then you will kill people normally (i.e., don't use kill buttons in front of others thinking it'll recruit). If the target has a kill button and the option to turn into a Sidekick is on, they will become a Sidekick. Otherwise, they will gain the Recruit add-on if the option to give the Recruit add-on is on.", "GodInfoLong": "(Neutrals):\nAs the God, you know everyone's role from the beginning. If you live until the end of the game, you steal the win, i.e., everyone else loses, and you win.", "InnocentInfoLong": "(Neutrals):\nThe Innocent can use the kill button to plant any player, and the planted target will immediately kill the Innocent. If the target gets voted out in the meeting, the Innocent wins. Note: Jester, Executioner, and Innocent can win together.", "PelicanInfoLong": "(Neutrals):\nAs the Pelican, you can use the kill button to swallow a player alive, teleporting them off-bounds but not killing them yet. Those swallowed will only die if you're still alive at the end of the round. If you die or leave during the round, all alive swallowed players will spawn into the map where you were.", @@ -884,14 +872,14 @@ "SolsticerInfoLong": "(Neutrals):\nAs the Solsticer, you won't die, and you win by finishing all your tasks in a single round. After every meeting finishes, your tasks reset, and you need to start all over again.\nVotes on the Solsticer will be directly canceled.\nKill attempts on the Solsticer will teleport it out of the map like Pelican until the meeting is finished.\nThe killer's kill cooldown will be reset to 10 seconds.\nSolsticer is counted as nothing in-game.", "CollectorInfoLong": "(Neutrals):\nAs the Collector, when you vote for a player, for each other player that voted for them, you gain a point. When you collect the required votes, the game ends, and you win alone, even if you voted a Jester or Executioner's target out.", "GlitchInfoLong": "(Neutrals):\nAs the Glitch, you can hack players (single click) or kill normally (double click).\nThose who have been hacked cannot kill, vent, or report for the hack duration.\nAdditionally, calling a sabotage other than doors will have no effect and will instead disguise you as a random player. You cannot disguise during or after sabotages.\nTo win, be the last player alive.", - "SidekickInfoLong": "(Neutrals):\nAs the Sidekick, your job is to help the Jackal kill everyone.\nYou and the Jackal win together.\nDepending on the settings, you may turn into Jackal if old Jackal was killed.\nYou may not be able to kill until old Jackal is dead.", + "SidekickInfoLong": "(Neutralen):\nAls het Hulpje is het jouw taak om de Jakhals te helpen met iedereen te vermoorden. \n\nJij en de Jakhals winnen samen.", "ProvocateurInfoLong": "(Neutralen):\nAls Provocateur kun je een keer iemand doden met de kill knop. Als het doelwit aan het einde van het spel verliest, wint de Provocateur met het winnende team.", "BloodKnightInfoLong": "(Neutrals):\nThe Blood Knight wins when they're the last killing role alive, and the amount of crewmates is lower or equal to the amount of Blood Knights. The Blood Knight gains a temporary shield after every kill, making them immortal for a few seconds.", "PlagueBearerInfoLong": "(Apocalypse):\nAs the Plaguebearer, plague everyone using your kill button to turn into Pestilence.\nOnce you turn into Pestilence, you will become immortal and gain the ability to kill, and you will kill anyone who tries to kill you.\n\nAlso, when infected players interact with uninfected players, they will also be infected.", "PestilenceInfoLong": "(Apocalypse):\nAs Pestilence, you're an unstoppable machine.\nAny attack towards you will be reflected towards them.\nIndirect kills don't even kill you.\n\nOnly way to kill Pestilence is by voting them out or the Pestilence misguessing.\nYour presence is announced to everyone at the meeting after you transform.", "SoulCollectorInfoLong": "(Apocalypse):\nAs Soul Collector, you can use your kill button on a player to predict their death. You will gain a soul if your target dies in the round you select them or the meeting after.\nYour target resets after each meeting or after they die, whichever comes first. \n\nOnce you collect the configurable amount of souls, you become Death. If the gain passive souls setting is enabled, you will gain a soul each meeting.", "DeathInfoLong": "(Apocalypse):\nOnce the Soul Collector has collected their needed souls, they become Death. Death kills everyone and wins if Death is not ejected by the end of the next meeting.\nA configurable amount of extra meeting time will be given on the meeting Death transforms to have more discussion to find Death.\n\nYou are invincible, and your presence is announced to everyone at the meeting after you transform.", - "BakerInfoLong": "(Apocalypse):\nAs the Baker, you can use your kill button on a player per round to give them bread. \nOnce a set amount of players are alive with bread, you become Famine.\n\nIf the Bread gives additional effects and the setting is on, then you can vent to change the bread that you give out. \nBread Effects:\nReveal: Reveals the target's role to the Baker (stays the whole game)\nRoleblock: Sets the target's kill cooldown to 999 (resets to normal after the meeting)\nBarrier: Gives the target a barrier that is only known to the Baker (barrier is removed after the meeting)", + "BakerInfoLong": "(Apocalypse):\nAs the Baker, you can use your kill button on a player per round to give them bread. \nOnce a set amount of players are alive with bread, you become Famine.\n\nIf the Bread gives additional effects and the setting is on, then you can vent to change the bread that you give out. \nBread Effects:\nReveal: Reveals the target's role to the Baker (stays the whole game)\nRoleblock: Resets the target's kill cooldown when they try to use their kill button\nBarrier: Gives the target a barrier that is only known to the Baker (barrier is removed after the meeting)", "FamineInfoLong": "(Apocalypse):\nOnce the Baker has a set amount of people with bread alive, they will become Famine. If the Famine does not get voted out after the meeting, then they will become Famine, and every player without bread will starve (excluding other Apocalypse members).\nAfter this starvation of everyone without bread, Famine can use their kill button to starve any remaining players, which will kill those players right before the next meeting.\n\nYou are invincible, and your presence is announced to everyone at the meeting after you transform.", "BerserkerInfoLong": "(Apocalypse):\nAs the Berserker, you level up with each kill.\nUpon reaching a certain level defined by the Host, you unlock a new power.\n\nScavenged kills make your kills disappear.\nBombed kills make your kills explode. Be careful when killing, as this can kill your other Apocalypse members if they are near. \nAfter a certain level, you become War.", "WarInfoLong": "(Apocalypse):\nAs War, you are invincible, have a lower kill cooldown, and can kill anyone with your previous powers.\nYour presence is announced to everyone at the meeting after you transform.", @@ -911,12 +899,11 @@ "TraitorInfoLong": "(Neutrals):\nAs the Traitor, you were an Impostor that betrayed the Impostors.\nYou know the Impostors, but they don't know you.\nThe twist? They can kill you, but you can't kill them.\n\nEliminate the Impostors by other means, then kill everyone else to win!", "TrollerInfoLong": "(Neutrals):\nAs a Troller, you can complete tasks so that random events can happen to players.\nFor example, changing the speed of all players, teleportation, influencing sabotage, etc.\nAlso you can win with the winning team.", "VultureInfoLong": "(Neutralen):\nMeld als de Gier lichamen om te winnen!\n\nAls je een lichaam rapporteert en de cooldown voor eten is verstreken, eet je het lichaam op (waardoor het niet meer kan worden gerapporteerd).\nAls jouw vaardigheid nog steeds cooldown heeft, rapporteer je het lichaam als normaal.", - "AbyssbringerInfoLong": "(Impostors):\nAs the Abyssbringer, you can place black holes. Black holes will suck in players and kill them when colliding with them.", "TaskinatorInfoLong": "(Neutrals):\nAs the Taskinator, whenever you finish a task, the task will be bombed. When another player completes the bombed task, the bomb will detonate, and the player will die.\n\nYou win if you survive till the end and Crew doesn't win.\n\n Note: Taskinator bombs ignore all protection.", "BenefactorInfoLong": "(Crewmates):\nAs the Benefactor, whenever you finish a task, that task will be marked. When another player completes the marked task, they get a temporary shield.\n\n Note: Shield only protects from direct kill attacks.", - "MedusaInfoLong": "(Neutralen):\nAls Medusa kun je lichamen verstenen, net zoals je een lichaam schoonmaakt.\nVersteende lichamen kunnen niet worden gerapporteerd.\n\nDood iedereen om te winnen.", + "MedusaInfoLong": "(Neutrals):\nAs the Medusa, you can stone bodies much like cleaning a body.\nStoned bodies cannot be reported.\n\nKill everyone to win.", "SpiritcallerInfoLong": "(Neutrals):\nAs the Spiritcaller, your victims become Evil Spirits after they die. These spirits can help you win by freezing other players briefly or blocking their vision. Alternatively, the spirits can give you a shield that protects you briefly from an attempted kill.", - "AmnesiacInfoLong": "(Neutrals):\nAs the Amnesiac, use your report button to remember a target and get its role.\nTo balance the game, you will not be able to vent after remembering your role if you can't vent as Amnesiac.'", + "AmnesiacInfoLong": "(Neutralen)\nAls Vergeetachtige kan je de rapporteer knop gebruiken om een rol te herinneren\n\nAls jouw lijk een Bedrieger was, wordt je een Vluchteling\nAls jouw lijk een Bemanningslid was, wordt je hetzelfde rol als dat mogelijk is\nAls jouw lijk een passieve neutraal was of onbekende neutrale moordenaar, krijg je een willekeurige rol afhankelijk van instellingen\nAls jouw lijk een neutrale moordenaar was, wordt jij dezelfde rol.", "ImitatorInfoLong": "(Neutrals):\nAs the Imitator, use your kill button to imitate a player.\n\nYou'll either become a Sheriff, a Refugee, or some Neutral.", "BanditInfoLong": "(Neutrals):\nAs the Bandit, you can click your kill button one time to steal a player's addon and twice to kill. Depending on the settings, you may instantly steal the addon or after the meeting starts. After the maximum number of steals is reached, you will kill normally. Additionally, if there are no stealable addons on the target or the target is stubborn, you will kill the target.\n\nKill everyone to win.\n\nNote: Cleansed, Last Impostor, and Lovers cannot be stolen.\nNote: If Bandit can vent is on, Nimble will become unstealable.", "DoppelgangerInfoLong": "(Neutrals):\nAs the Doppelganger, use your kill button to steal a player's identity (their name and skin) and then kill your target.\n\nKill everyone to win.\n\nNote: You cannot steal the target's identity when Camouflage is active.", @@ -925,19 +912,18 @@ "ShroudInfoLong": "(Neutrals):\nAs the Shroud, you do not kill normally.\nInstead, use your kill button to shroud a player.\nShrouded players kill others.\nIf the shrouded player doesn't make a kill, they'll kill themselves after a meeting.\n\nShroud sees shrouded players with a 「◈」mark next to their name.\nShrouded players who did not make a kill will also have the 「◈」mark in meetings, where they'll die if the Shroud is alive by the end of the meeting.", "WerewolfInfoLong": "(Neutralen):\nAls Weerwolf kun je doden zoals elke moordenaar.\nMaar als je doodt, sterven alle spelers in de buurt ook.\nElke speler die hierdoor sterft, krijgt zijn doodsreden als Verscheurd.\n\nOm dit in evenwicht te brengen, heb je een hogere kill cooldown dan anderen.", "ShamanInfoLong": "(Neutrals):\nAs the Shaman, you can use your kill button to select a voodoo doll once per round. If the kill button is used on you, the effect will be deflected onto the voodoo doll.\nIf you survive until the end, you win with the winning team.\nNote: If the killer cannot kill the chosen target, murder is canceled, but if the killer rechecks the Shaman, the killer will kill the Shaman.", - "SeekerInfoLong": "(Neutrals):\nAs the seeker, use your kill button to tag the target. If the seeker tags the wrong player, a point is deducted, and if the seeker tags the correct player, a point will be added.\nAdditionally, the seeker will not be able to move for 5 seconds after every meeting and after getting a new target.\n\nThe seeker needs to collect a certain number of points set by the Host to win.", + "SeekerInfoLong": "(Neutrals):\nAs the seeker, use your kill button to tag the target. If the seeker tags the wrong player, a point is deducted, and if the seeker tags the correct player, a point will be added.\nAdditionally, the seeker will not be able to move for 5 seconds after every meeting and after getting a new target.\n\nThe seeker needs to collect a certain number of points set by the Host to win.\nSeeker will see a ★ mark on target's name.", "PixieInfoLong": "(Neutrals):\nAs the Pixie, Mark up to x amount of targets each round by using the kill button on them. You must have one of the marked targets ejected when the meeting starts. If unsuccessful, you will commit suicide, except if you didn't mark any targets or all the targets are dead. The selected targets reset to 0 after the meeting ends. If you succeed, you will gain a point. You see all your targets in colored names.\n\nYou win with the winning team when you have certain amounts of points set by the Host.", "SchrodingersCatInfoLong": "(Neutrals):\nAs Schrodingers Cat, if someone attempts to use the kill button on you, you will block the action and join their team. This blocking ability works only once. By default, you don't have a victory condition, meaning you win only after switching teams.\nIn Addition to this, you will be counted as nothing in the game.\n\nNote: If the killing machine attempts to use its kill button on you, the interaction is not blocked, and you will die.", "RomanticInfoLong": "(Neutrals):\nThe Romantic can pick their lover partner using their kill button (this can be done at any point of the game). Once they've picked their partner, they can use their kill button to give their partner a temporary shield that protects them from attacks. If their lover partner dies, the Romantic's role will change according to the following conditions:\n1. If their partner was an Impostor, the Romantic becomes the Refugee\n2. If their partner was a Neutral Killer, then they become Ruthless Romantic.\n3. If their partner was a Crewmate or a non-killing neutral, the Romantic becomes the Vengeful Romantic. \n\nThe Romantic wins with the winning team if their partner wins.\nNote: If your role changes, your win condition will be changed accordingly", "RuthlessRomanticInfoLong": "(Neutrals):\nYou change your roles from Romantic if your partner (A neutral killer) is killed. As a Ruthless Romantic, you win if you kill everyone and are the last one standing. If you win, your dead partner will also win with you.", "VengefulRomanticInfoLong": "(Neutrals):\nYou change your roles from Romantic if your partner (A crew or non-neutral killer) is killed. As a Vengeful Romantic, your goal is to avenge your partner, which means you must kill the killer of your partner. If you succeed, then you and your partner win with the winning team at the end. If you try to kill someone other than your partner's killer, then you will die by misfire.", - "PoisonerInfoLong": "(Neutralen):\nAls Vergiftiger worden je kills uitgesteld.\nDood iedereen om te winnen.", + "PoisonerInfoLong": "(Neutrals):\nAs the Poisoner, your kills are delayed.\nKill everyone to win.", "HexMasterInfoLong": "(Neutrals):\nAs the Hex Master, you can hex players or kill them.\nHexing a player works the same as spelling as a Witch.", "WraithInfoLong": "(Neutrals):\nAs the Wraith, you can vent to Vanish temporarily. You will still appear visible on your screen. Vent again to become visible. You win if you are the last player remaining.", "JinxInfoLong": "(Neutrals):\nAs the Jinx, whenever you get attacked, you jinx them, resulting in them dying to a jinx.\nThis has limited uses.\n\nKill off everyone to win.", "PotionMasterInfoLong": "(Neutrals):\nAs the Potion Master, you have three different potions assigned to three different actions.\n\nSingle click: Reveal role\nDouble click: Kill\nMap: Sabotage\n\nThe reveal potion has a limit.\nWhen you run out, the kill buttons default to killing.", "NecromancerInfoLong": "(Neutrals):\nAs the Necromancer, you win when you're the last one standing.\nAdditionally when someone tries to kill you, you will block the kill, and you will teleport to a random vent. You will have a limited time to kill your killer. If you succeed in doing so, you live. If the time runs out before you kill your killer, you die permanently. If you try to kill someone else other than your killer, you will die.", - "ShockerInfoLong": "(Neutrals):\nAs the Shocker, you can mark rooms by doing tasks in them, and then vent to Electrocute anyone in those rooms for a set period of time. When you finish all of your tasks, you get new ones. Note: Doing tasks during that period will mark them for the next ability use.", "LastImpostorInfoLong": "(Add-ons):\nThis special effect is given to the last surviving Impostor. It significantly reduces their kill cooldown.", "OverclockedInfoLong": "(Add-ons):\nAs the Overclocked, your kill cooldown is reduced by a percentage.\n\nThis feature is only assigned to roles with a kill button.", "LoversInfoLong": "(Add-ons):\nLovers are a combination of two players. The Lovers win when they are the last ones standing, and their victory is shared. When one of the Lovers wins, the other also wins together. Lovers can see the 「♥」 next to each other's name. If one of the Lovers dies, the other will die in love (may not die in love according to the Host's settings). When one of the Lovers is exiled in the meeting, the other will die and become a dead body that cannot be reported.", @@ -981,7 +967,7 @@ "RebirthInfoLong": "(Add-ons):\nAs the Rebirth, if you're the player about to be ejected, you will swap skins with a random crewmate who voted for you.\nNotice: The host vote never counts\nRebirth will be removed from you if you exhausted all your rebirths.", "LoyalInfoLong": "(Add-ons):\nAs the Loyal, you cannot be recruited by roles such as Jackal or Cultist.\n\nCannot be assigned to neutrals.", "EvilSpiritInfoLong": "(Add-ons):\nAs Evil Spirit, it's your job to help the Spiritcaller to victory. You can use your Haunt button to freeze players and reduce their vision. Alternatively, you can use your Haunt button to give the Spiritcaller a shield against a kill attempt temporarily.", - "RecruitInfoLong": "(Betrayal Add-ons):\nAs a recruit, you are on the Jackal's team and help out the Jackal and their Sidekicks.\nYou cannot win with your original team.\nDepending on the settings, you may turn into Jackal if old Jackal was killed and no sidekicks is alive.", + "RecruitInfoLong": "(Betrayal Add-ons):\nAs a recruit, you are on the Jackal's team and help out the Jackal and their Sidekicks.\n\nYou cannot win with your original team.", "AdmiredInfoLong": "(Betrayal Add-ons):\nAs an admired player, you win with the crew and not your original team.\n\nYou can see the Admirer.", "GlowInfoLong": "(Add-ons):\nDuring lights out, you and players nearby you will receive a vision boost.", "RadarInfoLong": "(Add-ons):\nAs Radar, you have arrows pointing towards the closest person at all times.", @@ -1025,7 +1011,6 @@ "ProhibitedInfoLong": "(Add-ons):\nAs the Prohibited, you have specific vents that you can't use.\nHow many vents are disabled depends on the Host's settings.", "EavesdropperInfoLong": "(Add-ons):\nAs the Eavesdropper, you have a chance to read other role/addon information-based messages like Mortician or Sleuth.", "ApocalypseInfoLong": "(Apocalypse):\nApocalypse members are on a separate team that works together and wins together. If there are multiple Apocalypse roles in the game, they can see each other's roles.\nDepending on the Host's settings, Apocalypse roles can guess or be guessed.", - "RevenantInfoLong": "(Neutral):\nAs the Revenant, your goal is to be killed. If you are killed, you will take your killer's role and kill your killer instead. You cannot win before being killed.\nNote that Revenant only works when being directly killed.", "ShowTextOverlay": "Tekst Overlay", "Overlay.GuesserMode": "Gokker Modus", "Overlay.NoGameEnd": "No Game End", @@ -1039,8 +1024,6 @@ "AbilityUseLimit": "Initiële ability gebruikslimiet", "AbilityInUse": "Ability in use", "AbilityExpired": "Ability expired, {0} uses remain", - "RevenantTargeted": "Your role has changed to {0}", - "RevenantCanCopyAddons": "Can Steal Addons", "ShowArrows": "Heeft wijzende pijlen naar dode lichamen", "ArrowDelayMin": "Minimale pijl verschijning vertraging", "ArrowDelayMax": "Maximale pijl verschijning vertraging", @@ -1370,8 +1353,6 @@ "ShieldedCanUseKillButton": "Shielded player can use ability / kill button", "PlayerIsShieldedByGame": "Player is protected by the game!", "LegacyNemesis": "Use Legacy Version", - "LegacyParasite": "Use Legacy Version", - "LegacyTraitor": "Use Legacy Version", "ArsonistKeepsGameGoing": "Brandstichter houdt het spel gaande", "ArsonistCanIgniteAnytime": "Kan vuur altijd aansteken", "ArsonistMinPlayersToIgnite": "Minimum doused needed for ignite", @@ -1514,18 +1495,6 @@ "SheriffCanKillSeparately": "Individuele Instellingen", "In%team%": "(Team %team%)", "SheriffMisfireKillsTarget": "Misfire Kills Target", - "BlackHolePlaceCooldown": "Black Hole Place Cooldown", - "BlackHoleDespawnMode": "Black Hole Despawn Mode", - "BlackHoleDespawnTime": "Time After Black Hole Despawns", - "Abyssbringer.Suffix": "<#00ffa5>Number of players consumed by {0} <#00ffa5>active black holes:\\n{1}", - "Abyssbringer.Suffix.BlackHole": "<#00ffa5>{0}: {1}", - "BlackHoleMovesTowardsNearestPlayer": "Black Hole Moves Towards Nearest Player", - "BlackHoleMoveSpeed": "Black Hole Moving Speed", - "BlackHoleRadius": "Black Hole Consuming Radius", - "AfterTime": "After Time", - "After1PlayerEaten": "After 1 Player Was Eaten", - "AfterMeeting": "After Meeting", - "None": "None", "SheriffShotLimit": "Max number of Kills", "SheriffCanKillAllAlive": "Can Kill When No One Is Dead", "SheriffCanKillCharmed": "Kan Gecharmeerde spelers doden", @@ -1542,15 +1511,12 @@ "RebirthUses": "Amount of Rebirths", "RebirthCountVotes": "Only rebirth to players who voted for them", "RebirthFailed": "Ahh, how unfortunate, you did not find any viable souls to swap bodies with", - "FireworkerCooldown": "Placement Cooldown", "ReverieIncreaseKillCooldown": "Verhoging kill cooldown", "ReverieMaxKillCooldown": "Maximale kill cooldown", "ReverieMisfireSuicide": "Misfire on reaching max kill cooldown", "ReverieResetCooldownMeeting": "Herstart kill cooldown na vergadering", "ConvertedReverieKillAll": "Converted Reverie can kill anyone without repercussions", "VigilanteNotify": "Je bent precies datgene geworden waarvan je hebt gezworen het te vernietigen", - "DictatorChangeCommandToExpel": "Dictator use Command to expell instad of vote", - "DictatorExpelSelf": "WAIT WAIT WAIT WAT THE HELLLLLL Bro really just want to expel himself", "DoctorTaskCompletedBatteryCharge": "Batterij Tijdsduur", "SnitchEnableTargetArrow": "See Arrow Towards Target", "SnitchCanGetArrowColor": "See Colored Arrows based on Team Colors", @@ -1624,6 +1590,7 @@ "TimeThiefDecreaseMeetingTime": "Verminder vergadertijd met", "TimeThiefLowerLimitVotingTime": "Minimum Voting Time", "TimeThiefReturnStolenTimeUponDeath": "Return Stolen Time Upon Death", + "TimeThiefMaxTimeOnAdmired": "Maximum Meeting Time if Time Thief Is Admired", "EvilTrackerCanSeeKillFlash": "Can See Kill-Flash", "EvilTrackerCanSeeLastRoomInMeeting": "Kan Laatste Kamer Van Doelwit Zien In Meetings", "EvilTrackerTargetMode": "Can Set Target", @@ -1631,7 +1598,6 @@ "EvilTrackerTargetMode.OnceInGame": "Once in-game", "EvilTrackerTargetMode.EveryMeeting": "Elke vergadering", "EvilTrackerTargetMode.Always": "Any time", - "ScavengerHasCustomDeathReason": "Enable Custom Death Reason", "EvilHackerCanSeeDeadMark": "Can See The Location of Dead-bodies", "EvilHackerCanSeeImpostorMark": "Can See The Location of Other Impostors", "EvilHackerCanSeeKillFlash": "Can See Kill-Flash", @@ -1864,21 +1830,13 @@ "Jackal_SidekickCountMode_Jackal": "Jackal", "Jackal_SidekickCountMode_Original": "Original Team", "Jackal_SidekickAssignMode": "Sidekick Assign Mode", - "Jackal_SidekickAssignMode_SidekickAndRecruit": "Sidekick when failed Recruit", - "Jackal_SidekickAssignMode_Sidekick": "Only Sidekick", - "Jackal_SidekickAssignMode_Recruit": "Only Recruit", + "Jackal_SidekickAssignMode_SidekickAndRecruit": "Sidekick+Recruit", + "Jackal_SidekickAssignMode_Sidekick": "Sidekick Only", + "Jackal_SidekickAssignMode_Recruit": "Recruit Only", + "JackalWinWithSidekick": "Jakhals kan winnen met Hulpje's team", "Jackal_SidekickCanKillSidekick": "Sidekicks can kill other Sidekicks", "Jackal_SidekickCanKillJackal": "Sidekick can kill Jackal", - "Jackal_RecruitFailed": "You can not recruit this player!", "JackalCanKillSidekick": "Jakhals kan Hulpje doden", - "Jackal_SidekickCanKillWhenJackalAlive": "Sidekick can kill while Jackal is Alive", - "Jackal_SidekickTurnIntoJackal": "Sidekick can turn into Jackal after its death", - "Jackal_RestoreLimitOnNewJackal": "Restore Recruit limit when Sidekick become new Jackal", - "Jackal_OnBecomeNewJackalMeeting": "The old Jackal {0} is dead.\nYou are selected as new Jackal\nWork together and win the game!", - "Jackal_OnNewJackalSelectedMeeting": "The old Jackal {0} is dead.\n{1} is selected as new Jackal!\nWork together and win the game!", - "Jackal_BecomeNewJackal": "Old Jackal Dead, You are now new Jackal!", - "Jackal_OnNewJackalSelected": "Old Jackal Dead, Please help new Jackal {0} for now!", - "Jackal_BossIsDead": "Opps, the Jackal boss is dead!", "CoronerArrowsPointingToDeadBody": "Arrows pointing to dead bodies", "CoronerLeaveDeadBodyUnreportable": "Bodies the Coroner uses can't be reported", "CoronerInformKillerBeingTracked": "Inform the Killer that he gets tracked", @@ -1916,9 +1874,6 @@ "VipTag": "VIP★", "ApplyVipList": "Apply VIP List", "AllowSayCommand": "Allow moderators to use /say command", - "AllowStartCommand": "Allow moderators to use /start command", - "StartCommandMinCountdown": "Minimum countdown for /start command", - "StartCommandMaxCountdown": "Maximum countdown for /start command", "KickCommandDisabled": "The kick command is currently disabled.", "KickCommandNoAccess": "You do not have access to the kick command.", "KickCommandInvalidID": "Invalid player ID specified.\nPlease use '/kick [playerID] [reason]' to kick a player.\nExample :- /kick 5 not following rules", @@ -1951,11 +1906,6 @@ "WarnCommandNoAccess": "You do not have access to the warn command.", "WarnCommandInvalidID": "Invalid player ID specified.\nPlease use '/warn [playerID] [reason]' to warn a player. \nExample :- /warn 5 lava chatting", "WarnCommandWarnHost": "You are not permitted to warn the host.", - "StartCommandNoAccess": "You do not have access to the start command.", - "StartCommandDisabled": "The start command is currently disabled.", - "StartCommandCountdown": "ERROR\n\nThe game is already starting!", - "StartCommandStarted": "The game has been started by {0}!", - "StartCommandInvalidCountdown": "ERROR\n\nThe countdown must be between {0} and {1}!", "WarnCommandWarnMod": "You are not permitted to warn other moderators.", "WarnCommandWarned": "has been warned. There will be no more warnings given and appropriate action will be taken \n ", "WarnExample": "Use /warn [id] [reason] in future. \nExample :-\n /warn 5 lava chatting", @@ -1983,7 +1933,6 @@ "DeathReason.Quantization": "Quantization", "DeathReason.Overtired": "Uitgeput", "DeathReason.Ashamed": "Beschaamd", - "DeathReason.Consumed": "Consumed", "DeathReason.PissedOff": "Vernietigd", "DeathReason.Dismembered": "Dismembered", "DeathReason.LossOfHead": "Gewurgd", @@ -2007,8 +1956,6 @@ "DeathReason.Starved": "Starved", "DeathReason.Equilibrium": "Equilibrium", "DeathReason.Sacrificed": "Sacrificed", - "DeathReason.Electrocuted": "Electrocuted", - "DeathReason.Scavenged": "Scavenged", "OnlyEnabledDeathReasons": "Only Enabled Death Reasons", "Alive": "In Leven", "Disconnected": "Disconnected", @@ -2024,10 +1971,11 @@ "DeputyHandcuffCooldown": "Handboeien Cooldown", "DeputyHandcuffMax": "Max Aantal Handboeien", "DeputyHandcuffedPlayer": "Geboeid doelwit", - "HandcuffedByDeputy": "Je was geboeid!", - "DeputyInvalidTarget": "Doelwit kan niet worden geboeid", + "HandcuffedByDeputy": "You were handcuffed!\nNow you have broken your handcuff and can kill again.", + "DeputyInvalidTarget": "Target is already handcuffed", + "HandcuffBrokenAfterMeeting": "Remove all handcuffs after meeting", "DeputyHandcuffText": "Handboei", - "DeputyHandcuffCDForTarget": "Kill Cooldown for handcuffed player", + "DeputyHandcuffCDForTarget": "Next Kill Cooldown for handcuffed player", "RejectShapeshift.AbilityWasUsed": "Ability was used", "EscapisMtarkedPosition": "You marked self-position", "InvestigateCooldown": "Investigate Cooldown", @@ -2074,7 +2022,6 @@ "Command.dump": "→ Output Log to Desktop", "Command.death": "→ Display info on how you died", "Command.icons": "
╳ - The Player was marked by the Blackmailer and can't talk during the Meeting
☆ - Used by Captain to display themselves. Only Crewmates can see the Captain's star
乂 - This player was hexed by the Hex Master and will die if the Hex Master isn't killed or ejected by the end of the Meeting.
♦ - Used by Lawyer or Executioner or Follower.
♥ - Used by Lovers or Romantic.
✚ - Used by Medic to mark their target.
⦿ - This player is in a duel with the Pirate.
!? - This player was marked by the Quizmaster and must answer the question correctly to survive.
☜ - Used by Schrödinger's cat to mark their teammate.
◈ - This player marked by the Shroud and will die if the Shroud is not killed or ejected by the end of the meeting.
⚠ - This player is a Snitch or Solsticer who has finished their tasks.
★ - Used by Super Star or Cyber or Marshall.
† - This player was spelled and will die if the Witch is not killed by the end of the meeting.
∇ - Used by Kamikaze to mark their targets.
■ - Used by Lightning to mark their quantum ghosts.
⊠ - Used by Jailer to mark their prisoner.
● - Used by Baker to mark who has Bread.
♠ - Used by Soul Collector to mark who's death they're predicting.
⦿ - Used by Plaguebearer to mark who they have plagued.", - "Command.start": "[Seconds] → Start the game", "Command.iconinfo": "→ Display info on in-meeting icons", "Command.iconhelp": "→ Display info on in-meeting icons to everyone", "Command.Poll": "→ Start a poll with up-to 5 choices", @@ -2087,7 +2034,6 @@ "ShowMadmatesInLeftCommand": "Show Madmates (including add-ons)", "ShowApocalypseInLeftCommand": "Show Neutral Apocalypse", "SeeEjectedRolesInMeeting": "See ejected roles in meetings", - "ThankYouForUsingTOHE": "Thank you for using TOHE!", "SkillUsedLeft": "You have activated your skill to call a meeting. \nRemaining amount of uses left:", "NemesisDeadMsg": "The death of the Nemesis means the beginning of the revenge. \nPlease use /rv + [player ID] to kill the specified player \nYou can see player IDs in front of their names. \nOr type /rv to get a list of player IDs", "NemesisAliveKill": "Revenge for the Nemesis can only begin after their death.", @@ -2107,7 +2053,6 @@ "GuessNotifiedBait": "Bait can't be guessed because it was announced. You thought it would be that easy, right?", "GuessGM": "Guessing the GM is impossible because they're already dead.... And why would you do that to the poor Host?", "GuessGuardianTask": "You can't guess a Guardian who has finished their tasks.", - "GuardianCantKilled": "You can't kill a Guardian who has finished their tasks.", "GuessMarshallTask": "You can't guess a Marshall who has finished their tasks.", "GuessObviousAddon": "Sorry, obvious add-ons cannot be guessed.", "GuessAdtRole": "Unfortunately, the Host's settings do not allow you to guess add-ons", @@ -2163,7 +2108,6 @@ "BecomeMadmateCuzMadmateMode": "Je bent een Gekke geworden omdat je stierf", "CleanerCleanBody": "The body has been cleaned", "QuickShooterStoraging": "Bullets stored successfully", - "QuickShooterFailed": "You are still in cooldown.", "PoisonerTargetDead": "Doelwit gestorven", "HexesLookLikeSpells": "Hexes appear as spells", "HexButtonText": "Hex", @@ -2322,7 +2266,6 @@ "Message.YTPlanNotice": "Note: The [YouTuber Plan] is enabled in this lobby, which means the Host can specify their role in the next game to make it easier to get content. If the Host abuses this feature, please exit the game or report it.\nCurrent Creator Credentials:", "Message.OnlyCanBeUsedByHost": "ERROR\n\nThis command may only be used by the host.", "Message.MaxPlayers": "Maximum players set to ", - "Message.MaxPlayersFailByRegion": "Could not set max players: Vanilla regions support a maximum of 15 players.", "Message.GhostRoleInfo": "Ghost Role Info\nHiya! A little about ghost roles...\n\nGhost roles drastically impact the game, so it's not recommended for smaller lobbies if you're unfamiliar. If not explicitly stated otherwise in the description, the Guard button is their ability button ;)\n\nSpawning:\nGhost-roles only spawn after death; the first x people from (team) to die get them.\n\nPS: If your previous role didn't have tasks(e.g., sheriff), your tasks as a ghost-role aren't needed for task-win", "ApocalypseInfoTitle": "Neutral Apocalypse Info:", "Message.ApocalypseInfo": "Every role of the <#ff174f>Apocalypse Team has their own objective to carry out in order to transform.\n<#2B0804>Transformed <#ff174f>Apocalypse members have a drastic change on the game and are immortal (except for being voted), but everyone will be notified that they have transformed.\n\nRoles: <#e5f6b4>Plaguebearer, <#A675A1>Soul Collector, <#bf9f7a>Baker, <#cc0044>Berserker\nTransformed: <#343136>Pestilence, <#644661>Death, <#83461c>Famine, <#2B0804>War\n\nApocalypse members can see eachother's roles and ability icons.\nLike Neutral Killers, Apocalypse members keep the game going as well, have fun!", @@ -2454,6 +2397,7 @@ "LastResult": "★ Match Results", "LastEndReason": "★ End Reason", "KillLog": "Kill Log", + "MainRoleLog": "Role Convert Log", "Maximum": "Max", "RoleRate": "ON", "RoleOn": "ALWAYS", @@ -2730,9 +2674,8 @@ "DeathMeetingTimeIncrease": "Increased Meeting time when Death exists", "SoulCollectorMeetingDeath": "Your target has died during the meeting. You have gained a soul.", "SoulCollectorKillButtonText": "Predict", - "SoulCollectorHasImpostorVision": "Soul Collector has Impostor vision", "ApocalypseIsNigh": "[ The Apocalypse Is Nigh! ]", - "ApocalypseImmune": "This role is immune!", + "ApocalypseImmune": "This player is immune because they are invincible!", "BakerToFamine": "You have become Famine!!!", "BakerTransform": "The Baker has transformed into Famine, Horseman of the Apocalypse! A famine has begun!", "BakerAlreadyBreaded": "That player already has bread!", @@ -2741,15 +2684,13 @@ "BakerBreadNeededToTransform": "Required number of bread to become Famine", "BakerCantBreadApoc": "You cannot give other Apocalypse members bread!", "BakerKillButtonText": "Bread", - "BakerUnshiftButtonText": "Switch Bread", "BakerRevealBread": "Reveal", "BakerRoleblockBread": "Roleblock", "BakerBarrierBread": "Barrier", "BakerCurrentBread": "Current Bread: ", "BakerSwitchBread": "Bread Switched to: ", - "BakerCanVent": "Baker can Vent", + "BakerCanVent": "Baker can Vent", "BakerBreadGivesEffects": "Bread gives additional effects", - "BakerTransformNoMoreBread": "Baker transforms if they do not have enough bread", "FamineKillButtonText": "Starve", "FamineStarveCooldown": "Famine starve cooldown", "FamineCantStarveApoc": "You cannot starve other Apocalypse members!", @@ -2796,7 +2737,6 @@ "GodfatherTargetCountMode": "Moordenaars veranderen in", "GodfatherCount_Refugee": "Refugee", "GodfatherCount_Madmate": "Madmate", - "GodfatherRefugeeMsg": "You have been recruited by GodFather!", "MissChance": "Chance To Miss", "IncreaseByOneIfConvert": "Increase The KillCount +1 If a Crew Is Converted", "HawkMissed": "Missed!", @@ -2829,7 +2769,6 @@ "BerserkerToWar": "You have become War!!!", "BerserkerTransform": "The Berserker has transformed into War, Horseman of the Apocalypse! Cry 'Havoc!', and let slip the dogs of war.", "WarKillCooldown": "War kill cooldown", - "BerserkerCanKillTeamate": "Can kill other Neutral Apocalypse", "BlackmailerSkillCooldown": "Blackmail Cooldown", "BlackmailerMax": "Maximum times blackmailed players may speak", "BlackmailerDead": "Warning! {0} has been blackmailed by a Blackmailer!", @@ -2919,8 +2858,6 @@ "RememberedPursuer": "Je herinnerde je dat je een Achtervolger was!", "RememberedFollower": "Je herinnerde je dat je een Volger was!", "RememberedAmnesiac": "Het lukte je niet je rol te herinneren.", - "AmnesiacRemembered": "You remembered you were {0}!", - "ReportWhenFailedRemember": "Report Dead Body when failed to remember", "RememberedImitator": "You remembered you were an Imitator.", "RememberedImpostor": "Je herinnerde je dat je een Verrader was!", "RememberedCrewmate": "Je herinnerde je dat je een Bemanningslid was!", @@ -3146,7 +3083,7 @@ "DollMaster_PossessedTarget": "Possessed target", "DollMaster_CannotPossessImpTeammate": "Unable to possess teammate", "DollMaster_CouldNotSwapWithTarget": "Unable to possess player", - "DollMaster_CanNotSwapWithDeadTarget": "Possesing a dead player isn't possible", + "DollMaster_CanNotSwapWithDeadTarget": "Possessing a dead player isn't possible", "DollMaster_MainBody": "Main Body", "DollMaster_Doll": "Doll", "DollMaster_UnableToUseAbility": "Unable to use your ability on player", @@ -3334,12 +3271,9 @@ "PixieTargetAlreadySelected": "Doelwit al geselecteerd", "PixieButtonText": "Mark", "PlagueBearerCooldown": "Plague cooldown", - "PlagueBearerCanVent": "Can vent", - "PlagueBearerHasImpostorVision": "Has Impostor vision", "PestilenceCooldown": "Pestilence Kill cooldown", "PestilenceCanVent": "Pestilence Can Vent", "PestilenceHasImpostorVision": "Pestilence Has Impostor Vision", - "PestilenceKillGuessers": "Kill players who guess Pestilence", "PlagueBearerAlreadyPlagued": "Player has already been plagued", "PlagueBearerToPestilence": "You have turned into Pestilence!!", "GuessPestilence": "You just tried to guess Pestilence!\n\nSorry, Pestilence killed you.", @@ -3383,7 +3317,6 @@ "EveryoneCanKnowMini": "Iedereen kan zien wie de Mini is", "CanBeEvil": "Mini can be an Impostor", "EvilMiniSpawnChances": "Waarschijnlijkheid dat Mini een Bedrieger is", - "EvilMiniCanBeGuessed": "Evil Mini can be guessed before 18", "GuessMini": "Sorry, je kan een jonge Mini geen pijn doen.", "GrowUpDuration": "Tijd nodig om te groeien (s)", "MajorCooldown": "Kill Cooldown when over 18", @@ -3525,7 +3458,6 @@ "WinnerRoleText.Doppelganger": "Doppelganger Wins!", "WinnerRoleText.Quizmaster": "Quizmaster Wins!", "WinnerRoleText.Agitater": "Agitator Wins!", - "WinnerRoleText.Shocker": "Shocker Wins!", "AdditionalWinnerRoleText.Sidekick": "Hulpje", "AdditionalWinnerRoleText.Taskinator": "Taakinator", "AdditionalWinnerRoleText.Opportunist": "Opportunist", @@ -3611,7 +3543,7 @@ "SolsticerOnMeeting": "You witnessed too many deaths! Next round you will have {0} more short task!", "SolsticerTitle": "Solsticer", "GuessSolsticer": "Sorry, but you can not guess Solsticer!", - "ExpelSolsticer": "Sorry, but you can not expel Solsticer!", + "VoteSolsticer": "Sorry, but you can not vote Solsticer!", "SolsticerTasksReset": "Your tasks get reset!", "SolsticerMisGuessed": "You just misguessed! You are no longer allowed to guess.", "SolsticerGuessMax": "Because you already misguessed, you are no longer allowed to guess.", @@ -3712,19 +3644,6 @@ "MinionAbilityTime": "Ability Duration", "Minion_Blind": "blinded", "Evader_ChanceNotExiled": "Chance not be exiled", - "ShockerAbilityCooldown": "Ability Cooldown", - "ShockerAbilityDuration": "Ability Duration", - "ShockerAbilityPerRound": "Abilities Per Round", - "ShockerShockInVents": "Shock people in vents", - "ShockerAbilityResetAfterMeeting": "Reset marked rooms after meeting", - "ShockerOutsideRadius": "Radius Of Outside Tasks (not in a room)", - "ShockerCanShockHimself": "Can Shock Himself", - "ShockerImpostorVision": "Shocker has Impostor vision", - "ShockerIsShocking": "You're already shocking!", - "ShockerAbilityActivate": "Begin Shocking!", - "ShockerAbilityDeactivate": "Ability Deactivated", - "ShockerVentButtonText": "Shock", - "ShockerRoomMarked": "Marked Room", "EavesdropperMsgTitle": "You found a secret", "EavesdropPercentChance": "Chance to eavesdrop", "ChiefOfPoliceSkillCooldown": "Cooldown for recruiting sheriffs", @@ -3736,4 +3655,4 @@ "PolicPreventRecruitNonKiller": "Prevent recruit players without kill button", "PolicSuidiceWhenTargetNotKiller": "Suidices when recruit a non killer or non crewmate", "PolicPassConverted": "Can pass Converted Addon to Sheriff" -} +} \ No newline at end of file diff --git a/Resources/Lang/pt_BR.json b/Resources/Lang/pt_BR.json index 5eaf1d8b8..32bc660f9 100644 --- a/Resources/Lang/pt_BR.json +++ b/Resources/Lang/pt_BR.json @@ -20,8 +20,6 @@ "SubText.Neutral": "Trabalhe sozinho para alcançar a vitória", "SubText.Apocalypse": "Torne-se imparável com a sua equipe", "SubText.Madmate": "Ajude os Impostores", - "SubText.Lovers": "Stay alive and win together", - "SubText.Egoist": "Win on your own", "TypeImpostor": "Impostores", "TypeCrewmate": "Tripulantes", "TypeNeutral": "Neutros", @@ -31,9 +29,6 @@ "TeamNeutral": "Neutro", "TeamCrewmate": "Tripulante", "TeamMadmate": "Cúmplice", - "TeamLovers": "Lovers", - "TeamEgoist": "Egoist", - "TeamApocalypse": "Apocalypse", "YouAreCrewmate": "Você é um Tripulante", "YouAreImpostor": "Você é um Impostor", "YouAreNeutral": "Você é um Neutro", @@ -225,7 +220,6 @@ "TaskManager": "Gerenciador de Tarefas", "Witness": "Detector", "Swapper": "Trocador", - "ChiefOfPolice": "Chefe da Polícia", "NiceMini": "Mini do Bem", "Mini": "Mini", "Spy": "Espião", @@ -254,7 +248,6 @@ "Stalker": "Stalker", "Workaholic": "Trabalhador", "Solsticer": "Speedrunner", - "Abyssbringer": "Abyssbringer", "Collector": "Coletor", "Provocateur": "Provocador", "BloodKnight": "Cavaleiro Sangrento", @@ -393,8 +386,6 @@ "Sloth": "Preguiçoso", "Prohibited": "Proibido", "Eavesdropper": "Interceptador", - "Shocker": "Chocador", - "Revenant": "Assombração", "BracketAddons": "Adicionar parênteses para Atributos", "EngineerTOHEInfo": "Use ventilações para encontrar os Impostores", "ScientistTOHEInfo": "Acesse vitais portáveis de qualquer lugar", @@ -513,7 +504,7 @@ "PacifistInfo": "Use dutos para resetar todas as recargas de abate", "RebirthInfo": "Levante-se novamente", "MonarchInfo": "Dê à sua tripulação um poder extra de voto!", - "AbyssbringerInfo": "Place Black Holes", + "AbyssbringerInfo": "Create Black Holes", "SpurtInfo": "Salte como um coelho!", "StealthInfo": "Matar cega todos na sala", "PenguinInfo": "Arraste suas vítimas", @@ -538,7 +529,7 @@ "AdmirerInfo": "Escolha um jogador para ficar ao seu lado", "TimeMasterInfo": "Volte no tempo!", "CrusaderInfo": "Mate um jogador assassino", - "AltruistInfo": "Reviva um jogador", + "AltruistInfo": "Revive a player\nVent to change between Revive and Report", "ReverieInfo": "Com cada abate, seu tempo de recarga diminui", "LookoutInfo": "Olhe através de metamorfoses", "TelecommunicationInfo": "Localize usos de dispositivos", @@ -547,7 +538,6 @@ "WitnessInfo": "Descubra se o seu alvo matou recentemente", "GhastlyInfo": "Controle alguém!", "SwapperInfo": "Troque os Votos de Jogadores", - "ChiefOfPoliceInfo": "Contrate Xerife para Servir as Tripulações!", "NiceMiniInfo": "Ninguém pode machucá-lo até que você cresça!", "ArsonistInfo": "Mergulhe todos na gasolina e acenda!", "PyromaniacInfo": "Mergulhe todos na gasolina e acenda!", @@ -603,7 +593,7 @@ "VultureInfo": "Devore corpos reportando para ganhar", "TaskinatorInfo": "Tarefas silenciosas, explosões mortais", "BenefactorInfo": "Tarefa completa, escudo de elite!", - "MedusaInfo": "Petrifique os corpos reportando eles", + "MedusaInfo": "Stone bodies by reporting them", "SpiritcallerInfo": "Transforme jogadores em Espíritos Malignos", "AmnesiacInfo": "Relembre a função de um cadáver", "ImitatorInfo": "Imite a função de um jogador", @@ -615,19 +605,19 @@ "ShroudInfo": "Encoberte jogadores para fazer eles matarem", "WerewolfInfo": "Espanque os Tripulantes", "ShamanInfo": "Reflita todos os ataques em você para a boneca de vodu", - "SeekerInfo": "Jogue esconde-esconde com seu alvo", + "SeekerInfo": "Play Hide and Seek with your target\nYour target has a ★ mark.", "PixieInfo": "Marque-os, embale-os e ejete-os!", "OccultistInfo": "Mate e amaldiçoe seus inimigos", "SchrodingersCatInfo": "O gato está vivo e morto ao mesmo tempo, até ser observado.", "RomanticInfo": "Proteja seu parceiro para ganhar junto com ele", "VengefulRomanticInfo": "Vingue seu parceiro para ganhar", "RuthlessRomanticInfo": "Mate todos para ganhar com seu parceiro", - "PoisonerInfo": "Envenene todos os jogadores!", + "PoisonerInfo": "Kill everyone with delayed kills", "HexMasterInfo": "Enfeitiçe jogadores para matá-los em reuniões", "WraithInfo": "Use os dutos para ficar temporariamente invisível", - "JinxInfo": "Reflita ataques em seus atacantes", + "JinxInfo": "Reflect attacks onto your attackers", "PotionMasterInfo": "Use poções ao seu favor", - "NecromancerInfo": "Mate Tripulantes depois da morte usando espirítos", + "NecromancerInfo": "Kill your killer to defy death", "WardenInfo": "(Fantasma) Avise sobre os perigos", "MinionInfo": "(Fantasma) Cegue seus Inimigos", "LoversInfo": "Fique vivo e ganhe junto com seu parceiro", @@ -708,8 +698,6 @@ "SlothInfo": "Você é lento", "ProhibitedInfo": "Certos dutos estão bloqueados", "EavesdropperInfo": "Escute outras funções", - "ShockerInfo": "Eletrocutar jogadores desavisados", - "RevenantInfo": "Assuma a função de assassino", "EngineerTOHEInfoLong": "(Tripulantes):\n★Como um Engenheiro, você pode acessar as tubulações enquanto as comunicações não são sabotadas.", "ScientistTOHEInfoLong": "(Tripulantes):\nComo um Cientista, você tem um tablet portátil com os dados vitais da Tripulação.\nUse-o da maneira que quiser.", "NoisemakerTOHEInfoLong": "(Tripulantes):\nComo o Sirene, sempre que você morrer você fará um barulho, e um indicador visual de sua morte aparecerá na tela para que os tripulantes possam correr para pegar a pessoa que o matou em flagrante (mesmo que não seja Vermelho).", @@ -770,8 +758,8 @@ "PenguinInfoLong": "(Impostores):\nComo o Pinguim, você pode arrastar um jogador pressionando o botão de matar e o movendo por aí.\nAo arrastar, o jogador pode morrer pressionando o botão de matar novamente ou após um determinado período.\nPressione o botão de matar duas vezes para matar diretamente.", "ParasiteInfoLong": "(Time Impostor):\n★O Parasita é um Impostor que não sabe quem são os outros Impostores. \n★Você deverá matar, usar o duto, sabotar, etc.\n★Só saiba que você é Impostor.", "DisperserInfoLong": "(Impostores):\nO Dispersor pode se Transformar para teletransportar todos os jogadores para dutos aleatórios.", - "InhibitorInfoLong": "(Impostores):\n★O Inibidor não pode matar quando uma sabotagem crítica está ativa.\n★Se uma sabotagem crítica for ativa (por exemplo Luzes ou Reator), você não poderá matar.", - "SaboteurInfoLong": "(Impostores):\n★O Sabotador só pode matar quando uma sabotagem crítica estiver ativa.\n★Se uma sabotagem crítica estiver ativa (por exemplo, Comms ou O2), você pode matar.", + "InhibitorInfoLong": "(Impostors):\nAs the Inhibitor, you can only kill when there is not a critical sabotage active.\n\nIf light or comms sabotage is active, then you can kill.", + "SaboteurInfoLong": "(Impostors):\nAs the Saboteur, you can only kill when there is a critical sabotage active.\n\nIf reactor or O2 sabotage is active, then you can kill.", "CouncillorInfoLong": "(Impostores):\nComo o Conselheiro, você pode matar jogadores durante uma reunião como um Juiz.\nQuando você matar em uma reunião, essas mortes aparecerão como um julgamento de um Juiz.\n\nO comando para matar é /tl [Id do jogador]\nVocê pode ver o Id dos jogadores antes do nome do jogador ou usar o comando /id para ver o Id de todos os jogadores.\nDependendo das configurações, o Conselheiro cometerá suicídio se julgar alguém de sua equipe.\nConselheiros convertidos podem julgar livremente.", "DazzlerInfoLong": "(Impostores):\n★O Cegador pode reduzir permanentemente a visão do alvo de sua metamorfose. Quando o Cegador morrer, a visão dos jogadores voltará ao normal.", "DeathpactInfoLong": "(Impostores):\nComo o Pacto da Morte, você se transforma para marcar seus alvos para um pacto da morte.\nSe você tiver jogadores suficientemente marcados para um pacto da morte, eles devem se encontrar dentro de um período específico; se falharem em fazer isso, eles morrem.\nSe um jogador marcado morrer antes que o pacto da morte seja concluído, o pacto é retirado.", @@ -781,7 +769,7 @@ "LurkerInfoLong": "(Impostores):\nO Espreitador pode entrar em uma ventilação para diminuir sua recarga de abate. Depois de você matar, sua recarga de abate vai voltar ao normal.", "VisionaryInfoLong": "(Impostores):\nO Visionário pode ver as facções dos jogadores vivos atualmente, porém apenas consegue ver durante as reuniões. \nA seguinte informação será mostrada no jogador: \n- Nome vermelho indica Impostor. \n- Nome ciano indica Tripulante. \n- Nome cinza indica Neutro.", "PlagueDoctorInfoLong": "(Neutros):\n(Doutor da Praga de TOH)\nO objetivo da Maldição é Infectar todos.\nEle começa escolhendo um jogador para infectar, após isso qualquer jogador que passe um certo tempo no alcançe desse jogador infectado será infectado tambem.\nO Progresso da infecção é cumulativo, e não é redefinido com a distancia ou após reuniões.", - "RefugeeInfoLong": "(Tripulantes Loucos):\nComo Refugiado, você era:\n -Um amnésico que se lembrava de um impostor\n -Um assassino que matou o alvo do Chefão.\n -Um romântico cujo parceiro era um Impostor\n -ou um imitador que imitava um impostor.\n\nAgora seu trabalho é ajudar os Impostores a matar os colegas de tripulação.", + "RefugeeInfoLong": "(Cúmplices):\nComo Refugiado, ou você foi relembrado pelo Amnésico ou você matou o alvo do Rei do Crime.\n\nAgora seu trabalho é ajudar os Impostores a matar os Tripulantes.", "UnderdogInfoLong": "(Impostores):\n★Como Azarão, você não pode matar enquanto tiver uma certa quantidade de jogadores vivos.", "ConsigliereInfoLong": "(Impostores):\nComo Consultor, você pode revelar as funções de outros jogadores usando o botão de matar.\n\nClique único: Revelar função\nClique duplo: Matar normalmente\n\nSe você ficar sem usos de revelação, seu botão de matar funcionará normalmente.", "LudopathInfoLong": "(Impostores):\n★Como Ludopata, seu tempo de recarga é aleatório \n★O minimo é de 1 segundo, enquanto o máximo é o seu tempo de recarga normal definido.", @@ -821,11 +809,11 @@ "GrenadierInfoLong": "(Tripulantes):\\n★O Atordoador pode usar as ventilações para usar o flashbang, o qual vai fazer o Impostor perder visão. \\n★ Quando o flashbang falha, o atordoador verá uma animação de escudo como lembrete. \\n★ Flashbangs apenas funcionam em Tripulantes quando o atordoador se torna um Cúmplice.", "MedicInfoLong": "(Tripulantes):\nO Médico pode colocar um escudo no alvo ao pressionar o botão de matar. O Médico só pode dar um escudo durante todo o jogo. Dependendo das configurações, o escudo do alvo pode ou não ser desativado quando o Médico morre. O Médico também pode ver se alguém está tentando quebrar o escudo do alvo.\nConforme as configurações do Anfitrião, o Médico ou o alvo podem ver se um jogador possui um escudo (mostrado como um círculo verde 「●」 ao lado do nome).", "FortuneTellerInfoLong": "(Tripulantes):\nComo Vidente, vote em um jogador em uma reunião para obter uma pista sobre sua função.\nA pista estará relacionada a sua função real.\n\nQuando as tarefas do Vidente forem concluídas, ele obterá a função exata em vez de uma pista!\n\nNota: - Se a configuração para dar dicas a jogadores ativos aleatórios estiver ativada, você não poderá verificar o mesmo jogador várias vezes.", - "JudgeInfoLong": "(Tripulantes):\nO Juiz pode julgar um certo jogador durante a reunião. \nSe o alvo for malvado, o alvo vai ser morto, e se estiver errado, o Juiz vai cometer suicidio.\nO comando de Julgamente é: /tl [id do jogador] \nVocê pode ver o id do jogador antes de seu nome. \nJuizes podem julgar todos os jogadores quando ele se torna Cúmplice.", + "JudgeInfoLong": "(Crewmates):\nThe Judge can judge a certain player during the meeting. If the target is evil, the target will be killed (whether it is evil or not is set by the Host). If it is wrong, the Judge commits suicide.\nCommand for judgment: /tl [player id]\nYou can see the player's id before the player's name, or use the /id command to view the id of all players.\nJudges can judge all players when they become Madmate.\nIn meeting the ability count shows how many trails you have in this meeting. Out of meeting the ability counts shows how many trails you have for the whole game.", "MorticianInfoLong": "(Tripulantes):\nO Funerário pode ver setas apontando para todos os cadáveres, e se o Funerário reportar o cadáver, ele vai saber o último jogador que teve contado com a vítima.", "MediumInfoLong": "(Tripulantes):\nO Médium pode estabelecer contato com os mortos depois de seu corpo ser reportado. \nO jogador que reportar não precisa ser o Médium. \nO jogador morto pode responder apenas SIM ou NÃO para a pergunta do Médium qual apenas o Médium vai poder ver.", "ObserverInfoLong": "(Tripulantes):\nO Observador pode ver todas as animações de escudo causado por outros jogadores depois da primeira reunião.", - "MonarchInfoLong": "(Tripulantes):\nComo Monarca, você pode dar aos jogadores um voto extra.\n\nVocê não pode dar um voto extra a alguém que já tem votos extras.\n\nOs jogadores que receberem os votos apareceram com o nome dourado.\nSe um jogador que você deu um voto extra estiver vivo, o Monarca não poderá ser adivinhado ou ejetado.", + "MonarchInfoLong": "(Crewmates):\nAs the Monarch, you can knight players to give them an extra vote.\n\nYou cannot knight someone who already has multiple votes.\n\nKnighted players appear with a golden name.\nIf a knighted player is alive, the Monarch cannot be guessed or killed.", "PacifistInfoLong": "(Tripulantes):\n★Quando Pacifista usa a ventilação, ele resetará o tempo de abate para todos os jogadores com botão de matar. \n★ Quando ele se torna um Cúmplice, essa habilidade vai apenas funcionar em Tripulantes.", "OverseerInfoLong": "(Tripulantes): \nComo o Profeta, você tem visão mínima, mas pode usar seu botão de matar para revelar a função de um jogador próximo. Um 「○」 será exibido ao lado do alvo revelado após você usar o botão de matar nele, e você também estará escaneando-o (somente você pode ver isso). Fique perto do alvo por um tempo definido para revelar sua função; se você se afastar demais, a revelação será cancelada.", "CoronerInfoLong": "(Tripulantes):\nComo Detetive você não pode reportar cadáveres, assim que você tentar reportar você verá uma seta apontando para o assassino do cadáver. \nSe a reunião for chamada, as setas somem.", @@ -833,7 +821,7 @@ "MerchantInfoLong": "(Tripulantes):\nComo Atribuidor, você vende um add-on aleatório para um jogador aleatório qual tiver todas as suas tarefas concluídas. \nCada add-on vendido lhe rende dinheiro. \nSe você tiver uma certa quantidade de dinheiro, você pode evitar a próxima tentativa de abate. \nO jogador subornado não será capaz de matar você, mas você não sabe quem é.", "RetributionistInfoLong": "(Tripulantes):\n★Como Fantasma Assassino, você pode matar uma quantidade limitada de jogadores depois de sua morte. \n★ Use /ret [ID do jogador].", "HawkInfoLong": "(Tripulantes [Fantasma]):\nComo o Falcão, você pode matar uma quantidade limitada de jogadores decididos pelo anfitrião, embora haja uma chance de você errar, fatiar alguém várias vezes aumenta as chances.", - "DeputyInfoLong": "(Tripulantes):\n★Como Deputado, use seu botão de abate em um jogador para resetar seu tempo de recarga. \n★ Se o alvo não tiver um botão de abate, foi um desperdício.", + "DeputyInfoLong": "(Crewmates):\nAs the Deputy, use your kill button to handcuff a player.\nThe player who is handcuffed will have their next kill attempt treated as a handcuff break, and the kill cooldown will be reset.\n\nIf the target does not have a kill button, then the handcuff was a waste.", "InvestigatorInfoLong": "(Tripulantes):\nComo Investigador, você pode usar o botão de matar para investigar alguém. Quando você investiga alguém, seu nome aparecerá em vermelho se ele possuir um botão de matar (base impostor/Metamorfo) ou azul claro se ele não tiver um botão de matar (base tripulante/engenheiro/cientista). No entanto, observe que a cor dos nomes voltará ao normal quando uma reunião for convocada.", "GuardianInfoLong": "(Tripulantes):\nComo Imortal, você se torna imortal completando suas tarefas. \nVocê não pode ser adivinhado nas reuniões.", "AddictInfoLong": "(Tripulantes):\nComo o Invulnerável, você possui um cronômetro de suicídio. Quando ele expira, você se mata.\nO cronômetro é indicado pelo tempo de recarga do duto. Quando o tempo de recarga do duto está em 0 segundos, você ainda tem um curto período para usar o duto.\nSe você não conseguir, morre; se conseguir, o cronômetro de suicídio é resetado.\nAlém disso, após usar o duto, ninguém pode interagir com você por um período definido.\nApós esse período, você fica imobilizado por outro período definido e não pode reportar nenhum corpo.", @@ -849,7 +837,7 @@ "AdmirerInfoLong": "(Tripulantes):\nComo Admirador, admire um jogador para o transformar em um tripulante.\nEles vencerão com os tripulantes e não com seu time original.\n\nVocê só pode fazer isso uma vez por jogador.", "TimeMasterInfoLong": "(Tripulantes):\nO Mestre do Tempo pode usar os dutos para marcar as posições de todos. \nQuando ele usar a habilidade denovo, todos os jogadores vivos irão ser revogados para suas posições marcadas \nDurante a habilidade, o Mestre o Tempo ganha um escudo do tempo, qual proteje ele da morte.", "CrusaderInfoLong": "(Tripulantes):\n★O Cruzador pode usar seu botão de abater para cruzar um jogador. \n★Se esse jogador for atacado, você matará o assassino.", - "AltruistInfoLong": "(Tripulantes):\nComo Altruísta, você pode se sacrificar para reviver um corpo morto usando o botão «Reportar».\\nNota: Se um jogador morto saiu do jogo, você reporta o corpo normalmente.\\nAlém disso, o jogador revivido não pode reportar seu próprio corpo morto.", + "AltruistInfoLong": "(Crewmates):\nAs the Altruist, you can sacrifice yourself to revive a dead body using the «Report» button.\nNote: If a dead player has left the game, you report that body normally.\nAlso revived player cannot report self dead body\nUse vent button to change between Report & Revive.", "ReverieInfoLong": "(Tripulantes):\nComo o Devaneio, você pode matar, mas seu tempo de recarga começa alto.\n\nEle aumenta se você matar um tripulante e diminui caso contrário.\nDependendo das configurações do Anfitrião, você pode errar ao atingir o máximo de tempo de recarga para matar, e seu alvo morre junto com você.\n\nVocê vence com os outros tripulantes.", "LookoutInfoLong": "(Tripulantes):\n★O Vigia pode ver os IDs de todos os jogadores a qualquer hora. \n★Isso permite ele ver além das camuflagens e metamorfoses.", "TelecommunicationInfoLong": "(Tripulantes):\nO Telecomunicador é notificado quando qualquer um usa as câmeras, vitais, registro de portas ou a administração.", @@ -872,7 +860,7 @@ "LawyerInfoLong": "(Neutros):\n★O Advogado tem um alvo para defender, o alvo será indicado por um diamante 「♦」 perto de seu nome.\n★ Se o alvo do Advogado vencer, ele vence.\n★ Se o alvo do Advogado perder, ele perde.", "OpportunistInfoLong": "(Neutros):\n★Se o Oportunista sobreviver até o final do jogo, o Oportunista ganha junto com o jogador que venceu", "VectorInfoLong": "(Neutros):\n★O Mario vence sozinho após entrar na ventilação um determinado número de vezes.", - "JackalInfoLong": "(Neutros):\nComo Jackal, você vence se for o último jogador vivo. Além disso, você pode recrutar usando o botão de matar. Se o alvo não for um que você possa recrutar, se você ficar sem uso ou não tiver a opção de recrutar, então você matará normalmente (ou seja, não use a habilidade de recrutar na frente de outras pessoas pensando que vai recrutar). Se o alvo tiver um botão de matar e a opção de se transformar em Recruta estiver ativada, ele se tornará um Recruta. Caso contrário, eles ganharão o complemento Recruta se a opção de fornecer o complemento Recruta estiver ativada.", + "JackalInfoLong": "(Neutros):\nComo Chacal, você vence se for o último jogador vivo. Além disso, você pode recrutar usando o botão de matar. Se o alvo não for um que você possa recrutar, se você ficar sem uso ou não tiver a opção de recrutar, então você matará normalmente (ou seja, não use a habilidade de recrutar na frente de outras pessoas pensando que vai recrutar). Se o alvo tiver um botão de matar e a opção de se transformar em Recruta estiver ativada, ele se tornará um Recruta. Caso contrário, eles ganharão o complemento Recruta se a opção de fornecer o complemento Recruta estiver ativada.", "GodInfoLong": "(Neutros):\nComo o Deus, você conhece a função de todos desde o início. Se você sobreviver até o final do jogo, você rouba a vitória, ou seja, todos os outros perdem e você vence.", "InnocentInfoLong": "(Neutros):\nO Inocente pode usar o botão de matar para fazer qualquer jogador mata-lo. Se o alvo for votado na reunião, o Inocente vence. Nota: Palhaço, Executor e Inocente podem ganhar juntos.", "PelicanInfoLong": "(Neutros):\nComo Glutão, você pode usar o botão de matar para engolir um jogador vivo, teletransportando-o para fora do mapa, mas sem matá-lo ainda. Aqueles engolidos só morrerão se você ainda estiver vivo no final da rodada. Se você morrer ou sair durante a rodada, todos os jogadores engolidos vivos aparecerão no mapa onde você estava.", @@ -884,14 +872,14 @@ "SolsticerInfoLong": "(Neutros):\nComo Speedrunner, você será imortal, e vencerá ao terminar todas as suas tarefas em uma única rodada. Após o término de cada reunião, suas tarefas são redefinidas e você precisa começar tudo de novo.\nOs votos no Speedrunner serão cancelados.\nTentativas de matar o Speedrunner irão teletransportá-lo para fora do mapa como o Glutão até que a reunião termine.\nO tempo de espera para matar do assassino será redefinido para 10 segundos.", "CollectorInfoLong": "(Neutros):\nQuando o Coletor coletar um número específico de votos, ele vence. Nota: A vitória do Coletor tem precedência dos jogadores exilados.", "GlitchInfoLong": "(Neutros):\nO Glitch é um erro da nave e tem que matar todo mundo \nVocê pode hackear os jogadores, o que os impede de matar, usar dutos e reportar cadáveres por algum tempo. \nVocê precisa matar todo mundo para vencer. \nClique Único = Hackear \nClique Duplo = Matar \nVocê pode usar dutos.\nVocê Pode se transformar usando o botão sabotagem, não as portas mas os botões clássicos de sabotagem, Elétrica, O2 e Reator. \nDevido a problemas técnicos não é possível se transformar quando a sabotagem está ativa.", - "SidekickInfoLong": "Neutrais):\nComo Assistente, seu trabalho é ajudar o Jackal a matar todos.\nVocê e o Jackal ganham juntos.\nDependendo das configurações, você pode se transformar em Jackal se o Jackal antigo foi morto.\nTalvez você não seja capaz de matar até que o antigo Jackal esteja morto.", + "SidekickInfoLong": "(Neutros):\n★O Ajudante ajuda o Chacal a matar todos.\n★ O Ajudante e o Chacal vencem juntos.", "ProvocateurInfoLong": "(Neutros):\n★O Provocador pode matar seu alvo com o botão de matar. Se o alvo perder ao final do jogo, o Provocador vence com quem vencer.", "BloodKnightInfoLong": "(Neutros):\nO Cavaleiro Sangrento vence quando é a única função que mata viva e a quantidade de Tripulantes for menor ou igual a de Cavaleiros Sangrentos. Após todo abate, o Cavaleiro Sangrento ganha um escudo temporário que faz ele se tornar Imortal por alguns segundos.", "PlagueBearerInfoLong": "(Apocalipse):\nComo o Porta-Pragas, contamine todos usando seu botão de matar para se transformar na Peste. Uma vez que você se transforme na Peste, você se tornará imortal e ganhará a capacidade de matar, e você matará qualquer um que tentar matá-lo.\n\nAlém disso, quando jogadores infectados interagem com jogadores não infectados, eles também serão infectados.", "PestilenceInfoLong": "(Apocalipse):\nComo a Peste, você é uma máquina imparável.\nQualquer ataque direcionado a você será refletido de volta para quem o atacou. Ataques indiretos nem sequer o mata.\n\nA única maneira de matar a Peste é por votação, ou se ele errar ao adivinhar. \nSua presença é anunciada a todos na reunião depois que você se transforma.", "SoulCollectorInfoLong": "(Apocalipse):\nComo Coletor de Almas, você pode usar seu botão de matar em um jogador para prever a morte dele. Você ganhará uma alma se o seu alvo morrer na rodada em que você o selecionou ou na reunião seguinte. Seu alvo é reiniciado após cada reunião ou depois que ele morre, o que ocorrer primeiro. \n\nUma vez que você coleta a quantidade configurável de almas, você se torna a Morte. Se a configuração de ganho de almas passivas estiver ativada, você ganhará uma alma a cada reunião.", "DeathInfoLong": "(Apocalipse):\nUma vez que o Coletor de Almas tenha coletado as almas necessárias, ele se torna a Morte. A Morte mata todos e vence se não for expulsa até o final da próxima reunião. Um tempo extra configurável será dado na reunião em que a Morte se transforma para permitir mais discussão para encontrá-la.\n\nVocê é invencível e sua presença é anunciada a todos na reunião depois que você se transforma.", - "BakerInfoLong": "(Apocalipse):\nComo o Padeiro, você pode usar seu botão de matar em um jogador por rodada para dar a ele um Pão. Uma vez que um número determinado de jogadores esteja vivo com pão, você se torna o Faminto.\n\nSe a configuração de efeitos adicionais do Pão estiver ativada, você pode usar os dutos para mudar o pão que você distribui.\nEfeitos do Pão:\nRevelar: Revela a função do alvo para o Padeiro (permanece durante todo o jogo)\nBloquear Função: Define o tempo de recarga para matar do alvo para 999 (é reiniciado para o normal após a reunião)\nBarreira: Dá ao alvo uma barreira que só é conhecida pelo Padeiro (a barreira é removida após a reunião)", + "BakerInfoLong": "(Apocalypse):\nAs the Baker, you can use your kill button on a player per round to give them bread. \nOnce a set amount of players are alive with bread, you become Famine.\n\nIf the Bread gives additional effects and the setting is on, then you can vent to change the bread that you give out. \nBread Effects:\nReveal: Reveals the target's role to the Baker (stays the whole game)\nRoleblock: Resets the target's kill cooldown when they try to use their kill button\nBarrier: Gives the target a barrier that is only known to the Baker (barrier is removed after the meeting)", "FamineInfoLong": "(Apocalipse): \nUma vez que o Padeiro tenha o número definido de pessoas vivas com pão, ele se tornará o Faminto. Se o Faminto não for votado para fora após a reunião em que ela se torna o Faminto, todos os jogadores sem o pão morrerão de fome (excluindo os outros membros do Apocalipse). \n\nApós a fome de todos sem pão, o Faminto pode usar seu botão de matar para fazer qualquer jogador restante morrer de fome, o que matará esses jogadores pouco antes da próxima reunião.\n\nVocê é invencível e sua presença é anunciada a todos na reunião depois que você se transforma.", "BerserkerInfoLong": "(Apocalipse):\nComo o Aprimorador, você evolui a cada abate. Ao atingir um certo nível definido pelo anfitrião, você desbloqueia um novo poder.\n\nAbates iguais ao do Necrófago fazem com que as pessoas que você matar desapareçam.\nAbates com bombas fazem com que seus abates explodam. Tenha cuidado ao matar, pois isso pode matar seus outros membros do Apocalipse se estiverem perto.\nApós um certo nível, você se torna o Guerreiro.", "WarInfoLong": "(Apocalipse):\nComo Guerreiro, você é invencível, tem um tempo de recarga para matar reduzido e pode matar qualquer um usando seus poderes anteriores. \nSua presença é anunciada a todos na reunião depois que você se transforma.", @@ -911,12 +899,11 @@ "TraitorInfoLong": "(Neutros):\nO Traidor é um Impostor que traiu os Impostores.\nO Traidor saberá quem são os impostores, mas os impostores não saberão quem é o traidor.\nOs Impostores podem matar o Traidor, mas o Traidor não pode matar os Impostores.\n\nO Traidor precisa encontrar outra forma de eliminar os Impostores, então matar todos e vencer!", "TrollerInfoLong": "(Neutros):\nComo Trollador, você pode completar tarefas para que eventos aleatórios aconteçam com os jogadores. Por exemplo, mudar a velocidade de todos os jogadores, teleportação, influenciar sabotagens, etc.\nAlém disso, você pode vencer com a equipe vencedora.", "VultureInfoLong": "(Neutros):\n★O Canibal não reporta corpos normalmente.\n★ O Canibal come o corpo clicando em reportar, fazendo com que não seja mais possível reportar o corpo.\n★ Coma a maioria dos corpos para vencer!", - "AbyssbringerInfoLong": "(Impostors):\nAs the Abyssbringer, you can place black holes. Black holes will suck in players and kill them when colliding with them.", "TaskinatorInfoLong": "(Neutros):\nComo Sabota-Tarefas, sempre que você concluir uma tarefa, ela será bombardeada. Quando outro jogador concluir a tarefa bombardeada, a bomba será detonada e o jogador morrerá.\n\nVocê vence se sobreviver até o fim e a equipe não vencer.\n\n Observação: as bombas do Sabota-Tarefas ignoram qualquer tipo de proteção.", "BenefactorInfoLong": "(Tripulantes):\nComo Benfeitor, sempre que você completar uma tarefa, a tarefa será marcada. Quando outro jogador for completar a tarefa marcada, ele receberá um escudo temporário.\n\n Nota: O escudo protege apenas contra ataques diretos.", - "MedusaInfoLong": "(Neutros):\n★A Medusa pode transformar os corpos em pedra, como se tivesse limpado eles.\n★ Corpos transformados em pedras não podem ser reportados.\n★ Mate todos para vencer.", + "MedusaInfoLong": "(Neutrals):\nAs the Medusa, you can stone bodies much like cleaning a body.\nStoned bodies cannot be reported.\n\nKill everyone to win.", "SpiritcallerInfoLong": "(Neutros):\nO Caçador de Almas tem o poder de transformar suas vítimas em Espírtos Malvados depois de morrerem. \nEsses espíritos podem ajudar você a ganhar congelando outros jogadores por um curto tempo, além dos espíritos poderem bloquear sua visão. \nAdicionalmente, os espíritos podem te dar um escudo que te protege de uma tentativa de abate.", - "AmnesiacInfoLong": "Neutrais):\nComo Amnesiac, use o botão de relatório para lembrar um alvo e obter seu papel.\nPara equilibrar o jogo, você não será capaz de evitar depois de lembrar o seu papel se não puder evitar como Amnesiac.'", + "AmnesiacInfoLong": "(Neutros):\n★O Amnésico pode usar seu botão de reportar para relembrar uma função. \n★Se o alvo for um Impostor, você se tornará um Refugiado. \n★Se o alvo era um tripulante, você se tornará um Xerife. \n★Se o alvo era um neutro passivo ou um neutro assassino não especificado, você se tornará o que está definido nas configurações. \n★Se o alvo era um neutro assassino dos poucos, você se tornará a função que ele é. \n★Se o alvo for um membro do Coventículo, você se tornará a Alma Penada", "ImitatorInfoLong": "(Neutros):\nComo o Imitador, use o botão de matar para imitar um jogador.\n\nVocê se tornará um xerife, um refugiado ou algum neutro.", "BanditInfoLong": "(Neutros):\nComo Bandido, você pode clicar no botão de matar uma vez para roubar o atributo de um jogador. Dependendo das configurações, você pode roubar o atributo instantaneamente ou após o início da reunião. Depois que o número máximo de roubos for atingido, você matará normalmente. Além disso, se não houver atributos roubáveis presentes no alvo ou se o alvo tiver o atributo Protegido, você o matará direto.\n\nClique Único: Roubar o Atributo\nClique Duplo: Matar\n\nMate todos para vencer.\n\nNota:- Limpo, Último Impostor e Amantes não podem ser roubados.\nNota:- Se a opção pro Bandido poder usar os dutos estiver ativado, o atributo Ágil se tornará inroubável", "DoppelgangerInfoLong": "(Neutros):\nComo Sósia, use o botão de matar para roubar a identidade de um jogador (nome e skin) e, em seguida, mate seu alvo.\n\nMate todos para vencer.\n\nObservação: Você não pode roubar a identidade do alvo quando a Camuflagem estiver ativa.", @@ -925,14 +912,14 @@ "ShroudInfoLong": "(Neutros):\n★O Encobertador não mata normalmente. \n★Em vez disso, use seu botão de abate para encobertar um jogador.\n★Jogadores encobertos matam outros. \n★Se o jogador encoberdo não fizer nenhum abate, eles cometerão suicídio depois da reunião. \n★O Encobertador pode ver os jogadores encobertos com um 「◈」 marcado próximo ao seu nome. \n★Jogadores encobertos que não realizaram o abate também terão o 「◈」.", "WerewolfInfoLong": "(Neutros):\n★O Lobisomen pode realizar abates bem parecido com qualquer assassino. \n★No entando, quando você matar, qualquer jogador próximo morrerá também. \n★Qualquer jogador que morrer para o Lobisomen terá a razão de morte como Espancado. \n★Para balancear isso, você tem um número maior de recarga do que qualquer um.", "ShamanInfoLong": "(Neutros):\nComo o Xamã, você pode usar seu botão de matar para selecionar um boneco de vodu uma vez por rodada. Se alguém usar o botão de matar em você, o efeito será refletido no boneco de vodu.\nSe você sobreviver até o final, você vence com o time vencedor.\nNota: Se o assassino não puder matar o alvo escolhido, o assassinato é cancelado, mas se o assassino revisitar o Xamã, o assassino matará o Xamã.", - "SeekerInfoLong": "(Neutros):\nComo o Procurador, use seu botão de matar para marcar o alvo. Se o Procurador marcar o jogador errado, um ponto será deduzido, e se o Procurador marcar o jogador correto, um ponto será adicionado.\nAlém disso, o Procurador não poderá se mover por 5 segundos após cada reunião e ao obter um novo alvo.\n\nO Procurador precisa coletar um certo número de pontos definido pelo Anfitrião para vencer.", + "SeekerInfoLong": "(Neutrals):\nAs the seeker, use your kill button to tag the target. If the seeker tags the wrong player, a point is deducted, and if the seeker tags the correct player, a point will be added.\nAdditionally, the seeker will not be able to move for 5 seconds after every meeting and after getting a new target.\n\nThe seeker needs to collect a certain number of points set by the Host to win.\nSeeker will see a ★ mark on target's name.", "PixieInfoLong": "(Neutros):\nComo Fada, marque até uma quantidade x de alvos a cada rodada usando o botão de matar neles. Quando a reunião começar, sua tarefa é fazer com que um dos alvos marcados sejam ejetados. Se não tiver êxito, você se suicidará, exceto se não tiver marcado nenhum alvo ou se todos os alvos estiverem mortos. Os alvos selecionados são redefinidos para 0 após o término da reunião. Se for bem-sucedido, você ganhará um ponto. Você verá todos os seus alvos com nomes coloridos.\nVocê vence com a equipe vencedora quando tiver determinadas quantidades de pontos definidas pelo anfitrião.", "SchrodingersCatInfoLong": "(Neutros):\nComo o Gato de Schrödinger, se alguém tentar usar o botão de matar em você, você bloqueará a ação e se juntará ao time deles. Esta habilidade de bloqueio funciona apenas uma vez. Por padrão, você não tem uma condição de vitória, o que significa que você vence apenas após mudar de equipe.\nAlém disso, você será contado como \"nada\" no jogo.\n\nNota: Se a Máquina Mortiféra tentar usar o botão de matar em você, a interação não será bloqueada, e você morrerá.", "RomanticInfoLong": "(Neutros):\nO Romântico pode escolher seu parceiro usando seu botão de abate (isso pode ser feito a qualquer ponto do jogo). Uma vez que o parceiro for escolhido, o Romântico poderá usar seu botão de abate para dar ao seu parceiro um escudo temporário, o qual vai proteger ele de ataques. Se o parceiro dele morrer, a função do Romântico mudará de acordo com as seguintes condições:\n1. Se o parceiro dele era um Impostor, o Romântico se torna um Refugiado.\n2. Se o parceiro dele era um Neutro Assassino, então ele se torna um Romântico Impiedoso.\n3. Se o parceiro dele era um Membro do Coventículo, então ele se torna uma Alma Penada.\n4. Se o parceiro dele era um Tripulante ou um neutro não assassino, o Romântico se torna o Romântico Vingativo. \n\nO Romântico ganha com o time vencedor se o parceiro dele vencer.\nNota: Se sua função mudar, sua condição de vitória será mudada de acordo", "RuthlessRomanticInfoLong": "(Neutros):\nVocê muda sua função de Romântico se seu parceiro (um assassino neutro) for morto. Como um Romântico Implacável, você vence se matar todos e for o último sobrevivente. Se você vencer, seu parceiro morto também vencerá com você.", "VengefulRomanticInfoLong": "(Neutros):\nVocê muda sua função de Romântico se seu parceiro (um tripulante ou um assassino não neutro) for morto. Como um Romântico Vingativo, seu objetivo é vingar seu parceiro, o que significa que você deve matar o assassino do seu parceiro. Se você conseguir, então você e seu parceiro vencem com o time vencedor no final. Se você tentar matar alguém que não seja o assassino do seu parceiro, você morrerá por falha.", - "PoisonerInfoLong": "(Coventículo):\n★Como Envenenador, suas mortes são atrasadas. \n★ Mate todos para vencer.", - "HexMasterInfoLong": "(Neutros):\nComo o Mestre Feiticeiro, você pode enfeitiçar os jogadores ou matá-los.\nEnfeitiçar um jogador funciona da mesma forma que enfeitiçar como um Feiticeiro.", + "PoisonerInfoLong": "(Neutrals):\nAs the Poisoner, your kills are delayed.\nKill everyone to win.", + "HexMasterInfoLong": "(Neutrals):\nAs the Hex Master, you can hex players or kill them.\nHexing a player works the same as spelling as a Witch.", "WraithInfoLong": "(Neutros):\nComo o Invisível, você pode usar o duto para Desaparecer temporariamente. Você ainda aparecerá visível na sua tela. Use o duto novamente para ficar visível. Você vence se for o último jogador restante.", "JinxInfoLong": "(Neutros):\nComo a Jinx, sempre que você é atacado, você amaldiçoa o atacante, resultando na morte deles por uma maldição.\nIsso tem usos limitados.\n\nMate todos para vencer.", "PotionMasterInfoLong": "(Neutros):\nComo o Mestre das Poções, você tem três poções diferentes atribuídas a três ações diferentes.\n\nUm clique simples: Revelar função\nDuplo clique: Matar\nMapa: Sabotar\n\nA poção de revelação tem um limite.\nQuando você acabar, os botões de matar voltam ao padrão de matar.", @@ -958,7 +945,7 @@ "ParanoiaInfoLong": "(Atributos):\nNão atribuído aos Neutros nem aos Cúmplices.\nComo a Paranoia, você será considerado como dois jogadores no jogo para determinar quando o jogo termina devido aos assassinos terem a maioria. Além disso, isso lhe concede um voto extra, dependendo das opções.", "MimicInfoLong": "(Atributos):\nApenas o Impostor pode se tornar o Mimico. Quando o Mimico morre, outros Impostores receberão uma mensagem assim que uma reunião for convocada. Esta mensagem incluirá informações sobre os papéis que o Mimico matou.", "GuesserInfoLong": "Entendido! Aqui está a correção:\n\n(Atributos):\nComo Adivinhador, adivinhe as funções dos jogadores nas reuniões para matá-los.\nAdivinhar a função incorreta resulta na sua própria morte.\nO comando de adivinhação é: /bt [ID do jogador] [função]\nVocê pode ver o ID do jogador antes do nome do jogador ou usar o comando /id para ver o ID de todos os jogadores.", - "NecroviewInfoLong": "(Atributos):\n★O Necropista pode ver o time dos jogadores mortos. O time do jogador será revelado da seguinte forma:\n★ Estrela Vermelha indica Impostor.\n★ Estrela Ciana indica Tripulante.\n★ Estrela Cinza indica Neutro.", + "NecroviewInfoLong": "(Add-ons):\nThe Necroview can see the teams of dead players. The following info will be displayed on the dead player's name while in a meeting:\n- The Red name indicates the Impostors.\n- The Cyan name indicates the Crewmates.\n- The Gray name indicates the Neutrals.", "ReachInfoLong": "(Atributos):\nApenas funções com um botão de matar podem obter este atributo. Ao contrário de todos os outros, você tem o alcance de matar mais longo possível no jogo.", "BaitInfoLong": "(Atributos):\nQuando o Armador é morto, a pessoa que matou o Armador vai reportar o corpo automaticamente. No entanto, isso não acontecerá quando o Armador for morto por um Necrófago, Faxineiro, Camaleão, Invisível ou Máquina Mortífera. O reporte pode ter um atraso de acordo com as configurações do Anfitrião.", "TrapperInfoLong": "(Atributos):\nQuando o Imobilizador é morto, ele imobiliza o jogador que o matou por um tempo configurado pelo Anfitrião.", @@ -978,10 +965,10 @@ "GravestoneInfoLong": "(Atributos):\n★Como uma Lápide, a sua função é revelada a todos quando você morre.", "LazyInfoLong": "(Atributos):\nComo o Preguiçoso, você recebe uma única tarefa curta e é imune ao Controlador de Mentes, Marionetista e Gangster.", "AutopsyInfoLong": "(Atributo)\n★Como um Autópsia, você pode ver como as pessoas morreram.\n\nNão pode ser atribuído ao Médico, Super Detetive, Cientista ou Sunnyboy.", - "RebirthInfoLong": "(Atributos):\nComo o Renascido, se você for o jogador que vai ser ejetado, você trocará de skins com alguém e renascerá mais uma vez.\n\nAviso: O Renascido será removido de você se você usar todos os seus renascimentos.", + "RebirthInfoLong": "(Add-ons):\nAs the Rebirth, if you're the player about to be ejected, you will swap skins with a random crewmate who voted for you.\nNotice: The host vote never counts\nRebirth will be removed from you if you exhausted all your rebirths.", "LoyalInfoLong": "(Atributos):\n★Como um Leal, você não pode ser recrutado por funções como Chacal ou Cultista.\n\nNão pode ser atribuído a neutros.", "EvilSpiritInfoLong": "(Atributos):\nComo um Espírito Maligno, seu objetivo é ajudar o Caçador de Almas a vencer. Você pode usar seu botão Assombrar para congelar jogadores e reduzir sua visão. Alternativamente, você pode usar seu botão Assombrar para dar temporariamente ao Caçador de Almas um escudo contra uma tentativa de abate.", - "RecruitInfoLong": "(Betrayal Add-ons):\nComo recruta, você faz parte da equipe do Jackal e ajuda o Jackal e seus Assistente.\nNão é possível vencer com sua equipe original.\nDependendo das configurações, você pode se transformar em Jackal se o antigo Jackal tiver sido morto e nenhum Assistente estiver vivo.", + "RecruitInfoLong": "(Atributos de Traição):\n★O Recruto é do time do Chacal e precisa ajudar o Chacal e seus AjudantesAs. \n★Você não pode ganhar com seu time original.", "AdmiredInfoLong": "(Atributos de Traição): \n★Você foi admirado pelo Admirador e agora ganha com a tripulação e não com seu time original. \n★Você pode ver o Admirador.", "GlowInfoLong": "(Atributos):\nDurante o apagamento das luzes, você e os jogadores próximos receberão um aumento de visão.", "RadarInfoLong": "(Atributos):\nComo Radar, você sempre terá setas apontando para a pessoa mais próxima.", @@ -1024,8 +1011,7 @@ "SlothInfoLong": "(Atributos):\nA velocidade de movimento padrão do Preguiçoso é mais lenta que outras.\n(a velocidade depende da configuração do Anfitrião)", "ProhibitedInfoLong": "(Atributos):\nComo Proibido, você tem dutos específicos que você não pode usar.\nQuantos dutos estão desativados dependerá das configurações do Anfitrião.", "EavesdropperInfoLong": "(Atributos):\nComo Interceptador, você tem a chance de ler mensagens baseadas em informações de outras funções/atributos, como Funerário ou Cão de Caça.", - "ApocalypseInfoLong": "(Apocalypse):\nOs membros do Apocalypse fazem parte de uma equipe separada que trabalha e vence em conjunto. Se houver vários jogadores do Apocalypse no jogo, eles poderão ver as funções uns dos outros.\nDependendo das configurações do Host, as funções do Apocalypse podem ser adivinhadas ou não.", - "RevenantInfoLong": "Neutro):\nSendo a Assombração, seu objetivo é ser morto. Se você for morto, tomará o papel de seu assassino e, em vez disso, matará o assassino. Você não pode vencer antes de ser morto.\nNote que a Assombração só funciona quando é morto.", + "ApocalypseInfoLong": "(Apocalypse):\nApocalypse members are on a separate team that works together and wins together. If there are multiple Apocalypse roles in the game, they can see each other's roles.\nDepending on the Host's settings, Apocalypse roles can guess or be guessed.", "ShowTextOverlay": "Sobrepor Texto", "Overlay.GuesserMode": "Modo Adivinhador", "Overlay.NoGameEnd": "Sem Fim de Jogo", @@ -1039,8 +1025,6 @@ "AbilityUseLimit": "Limite de Uso de Habilidade Inicial", "AbilityInUse": "Habilidade em uso", "AbilityExpired": "A habilidade expirou, {0} usos restantes", - "RevenantTargeted": "Sua função mudou para {0}", - "RevenantCanCopyAddons": "Pode Roubar Addons", "ShowArrows": "Tem setas apontando para corpos", "ArrowDelayMin": "Atraso Mínimo de Exibição da Seta", "ArrowDelayMax": "Atraso Máximo de Exibição da Seta", @@ -1370,8 +1354,6 @@ "ShieldedCanUseKillButton": "Jogador com escudo pode usar a sua habilidade / botão de matar", "PlayerIsShieldedByGame": "Esse jogador está protegido pelo o jogo!", "LegacyNemesis": "Usar Versão Legado", - "LegacyParasite": "Use Legacy Version", - "LegacyTraitor": "Use Legacy Version", "ArsonistKeepsGameGoing": "Pirômano mantém o jogo em andamento", "ArsonistCanIgniteAnytime": "Pode incendiar a qualquer momento", "ArsonistMinPlayersToIgnite": "Mínimo de jogadores molhados necessários para Incendiar", @@ -1514,18 +1496,6 @@ "SheriffCanKillSeparately": "Configurações Individuais", "In%team%": "(Facção %team%)", "SheriffMisfireKillsTarget": "Disparo acidental mata o alvo", - "BlackHolePlaceCooldown": "Black Hole Place Cooldown", - "BlackHoleDespawnMode": "Black Hole Despawn Mode", - "BlackHoleDespawnTime": "Time After Black Hole Despawns", - "Abyssbringer.Suffix": "<#00ffa5>Number of players consumed by {0} <#00ffa5>active black holes:\\n{1}", - "Abyssbringer.Suffix.BlackHole": "<#00ffa5>{0}: {1}", - "BlackHoleMovesTowardsNearestPlayer": "Black Hole Moves Towards Nearest Player", - "BlackHoleMoveSpeed": "Black Hole Moving Speed", - "BlackHoleRadius": "Black Hole Consuming Radius", - "AfterTime": "After Time", - "After1PlayerEaten": "After 1 Player Was Eaten", - "AfterMeeting": "After Meeting", - "None": "None", "SheriffShotLimit": "Número máximo de abates", "SheriffCanKillAllAlive": "Pode abater quando todos estão vivos", "SheriffCanKillCharmed": "Pode abater jogadores Servos", @@ -1542,15 +1512,12 @@ "RebirthUses": "Quantidade de Renascimentos", "RebirthCountVotes": "Apenas renasça pessoas quem votou nele", "RebirthFailed": "Ah, que pena, você não encontrou almas viáveis para trocar de corpo", - "FireworkerCooldown": "Placement Cooldown", "ReverieIncreaseKillCooldown": "Aumentar a recarga de abate", "ReverieMaxKillCooldown": "Máximo de recarga de abate", "ReverieMisfireSuicide": "Falha no disparo ao atingir o tempo máximo de recarga", "ReverieResetCooldownMeeting": "Redefinir tempo de recarga depois da reunião", "ConvertedReverieKillAll": "O Devaneio convertido pode matar qualquer pessoa sem consequências", "VigilanteNotify": "Você se tornou exatamente aquilo que jurou eliminar", - "DictatorChangeCommandToExpel": "Dictator use Command to expell instad of vote", - "DictatorExpelSelf": "PAPAPAPARAPARAPAROOOOOO O cara realmente quer se expulsar", "DoctorTaskCompletedBatteryCharge": "Duração da Bateria", "SnitchEnableTargetArrow": "Ver seta em direção ao alvo", "SnitchCanGetArrowColor": "Ver setas coloridas com base nas cores das facções", @@ -1562,7 +1529,7 @@ "MayorHasPortableButton": "Prefeito tem um Botão de Emergência Móvel", "MayorNumOfUseButton": "Número Máximo de Botões de Emergência Móveis", "MeetingsNeededForWin": "Reuniões necessárias para vitória", - "Jester_RevealUponEject": "Revelar na Ejeção ", + "Jester_RevealUponEject": "Reveal Upon Eject", "CannotVoteWhenDead": "Não é possível votar enquanto estiver morto", "EnableVote": "Habilitar comando /vote", "ShouldVoteSpam": "Tentar esconder o comando /vote", @@ -1574,7 +1541,7 @@ "ExecutionerCanTargetNeutralBenign": "Pode Julgar Neutros Passivos", "ExecutionerCanTargetNeutralEvil": "Pode Julgar Neutros Passivos", "ExecutionerCanTargetNeutralChaos": "Pode Julgar Neutros do Caos", - "Executioner_RevealTargetUponEject": "Revelar Alvo na Ejeção", + "Executioner_RevealTargetUponEject": "Reveal Target Upon Ejection", "SidekickSheriffCanGoBerserk": "Xerife Recrutado pode enlouquecer", "LawyerCanTargetImpostor": "O seu cliente pode ser um Impostor", "LawyerCanTargetNeutralKiller": "O seu alvo pode ser um Neutro Assassino", @@ -1624,6 +1591,7 @@ "TimeThiefDecreaseMeetingTime": "Reduza o Tempo da Reunião em", "TimeThiefLowerLimitVotingTime": "Tempo Mínimo de Votação", "TimeThiefReturnStolenTimeUponDeath": "Devolva o Tempo Roubado Após a Morte", + "TimeThiefMaxTimeOnAdmired": "Maximum Meeting Time if Time Thief Is Admired", "EvilTrackerCanSeeKillFlash": "Pode ver o Flash de Abate", "EvilTrackerCanSeeLastRoomInMeeting": "Pode Ver a Última Sala do Alvo na Reunião", "EvilTrackerTargetMode": "Pode Marcar o Alvo", @@ -1631,7 +1599,6 @@ "EvilTrackerTargetMode.OnceInGame": "Uma vez no jogo", "EvilTrackerTargetMode.EveryMeeting": "Cada reunião", "EvilTrackerTargetMode.Always": "A qualquer momento", - "ScavengerHasCustomDeathReason": "Habilitar Razão de Morte Personalizada", "EvilHackerCanSeeDeadMark": "Pode ver a localização de corpos mortos", "EvilHackerCanSeeImpostorMark": "Pode ver a localização de outros impostores", "EvilHackerCanSeeKillFlash": "Pode ver o Flash de Abate", @@ -1864,21 +1831,13 @@ "Jackal_SidekickCountMode_Jackal": "Jackal", "Jackal_SidekickCountMode_Original": "Time Original", "Jackal_SidekickAssignMode": "Modo de Atribuição de Ajudante", - "Jackal_SidekickAssignMode_SidekickAndRecruit": "Sidekick when failed Recruit", - "Jackal_SidekickAssignMode_Sidekick": "Only Sidekick", - "Jackal_SidekickAssignMode_Recruit": "Only Recruit", + "Jackal_SidekickAssignMode_SidekickAndRecruit": "Ajudante+Recruta", + "Jackal_SidekickAssignMode_Sidekick": "Apenas Ajudante", + "Jackal_SidekickAssignMode_Recruit": "Apenas Recruta", + "JackalWinWithSidekick": "Chacal pode vencer com a facção do Ajudante", "Jackal_SidekickCanKillSidekick": "Ajudantes podem matar outros Ajudantes", "Jackal_SidekickCanKillJackal": "Ajudantes podem matar Jackal", - "Jackal_RecruitFailed": "Você não pode recrutar este jogador!", "JackalCanKillSidekick": "Chacal pode assassinar Ajudantes", - "Jackal_SidekickCanKillWhenJackalAlive": "Sidekick can kill while Jackal is Alive", - "Jackal_SidekickTurnIntoJackal": "Sidekick can turn into Jackal after its death", - "Jackal_RestoreLimitOnNewJackal": "Restore Recruit limit when Sidekick become new Jackal", - "Jackal_OnBecomeNewJackalMeeting": "The old Jackal {0} is dead.\nYou are selected as new Jackal\nWork together and win the game!", - "Jackal_OnNewJackalSelectedMeeting": "O velho Jackal {0} está morto.\n{1} está selecionado como novo Jackal!\nTrabalhem juntos e vença o jogo!", - "Jackal_BecomeNewJackal": "O Jackal Antigo está morto, você agora é o novo Jackal!", - "Jackal_OnNewJackalSelected": "O Jackal Antigo está morto, por favor ajude o novo Jackal {0} agora!", - "Jackal_BossIsDead": "Ops, o chefe de Jackal está morto!", "CoronerArrowsPointingToDeadBody": "Setas apontando para os corpos", "CoronerLeaveDeadBodyUnreportable": "Os corpos usados ​​pelo Detetive não podem ser repotados", "CoronerInformKillerBeingTracked": "Informar ao assassino que ele está sendo rastreado", @@ -1916,9 +1875,6 @@ "VipTag": "VIP★", "ApplyVipList": "Aplicar Lista VIP", "AllowSayCommand": "Permitir que moderadores usem o comando /say", - "AllowStartCommand": "Permitir que moderadores usem o comando /start", - "StartCommandMinCountdown": "Contagem regressiva mínima para o comando /start", - "StartCommandMaxCountdown": "Contagem regressiva máxima para o comando /start", "KickCommandDisabled": "O comando de expulsar está atualmente desativado.", "KickCommandNoAccess": "Você não tem acesso ao comando de expulsar.", "KickCommandInvalidID": "ID de Jogador Inválido.\nPor favor, use '/kick [ID jogador] [motivo]' para expulsar um jogador.\nExemplo: - /kick 5 fã do erik carr", @@ -1951,11 +1907,6 @@ "WarnCommandNoAccess": "Você não tem acesso ao comando de alertar.", "WarnCommandInvalidID": "ID de Jogador Inválido.\nPor favor, use '/warn [ID jogador] [motivo]' para alertar um jogador. \nExemplo: - /warn 5 super cringe", "WarnCommandWarnHost": "Você não pode alertar o anfitrião.", - "StartCommandNoAccess": "Você não tem acesso ao comando start.", - "StartCommandDisabled": "The start command is currently disabled.", - "StartCommandCountdown": "ERROR\n\nThe game is already starting!", - "StartCommandStarted": "The game has been started by {0}!", - "StartCommandInvalidCountdown": "ERROR\n\nThe countdown must be between {0} and {1}!", "WarnCommandWarnMod": "Você não tem permissão para alertar outros moderadores.", "WarnCommandWarned": "foi alertado. Não haverá mais avisos e ações apropriadas serão tomadas \n ", "WarnExample": "Use /warn [ID] [motivo] no futuro. \nExemplo:-\n /warn 5 super cringe", @@ -1983,7 +1934,6 @@ "DeathReason.Quantization": "Quantização", "DeathReason.Overtired": "Cansado Demais", "DeathReason.Ashamed": "Envergonhado", - "DeathReason.Consumed": "Consumed", "DeathReason.PissedOff": "Destruído", "DeathReason.Dismembered": "Desmembrado", "DeathReason.LossOfHead": "Estrangulado", @@ -2007,8 +1957,6 @@ "DeathReason.Starved": "Fome", "DeathReason.Equilibrium": "Equilíbrio", "DeathReason.Sacrificed": "Sacrificado", - "DeathReason.Electrocuted": "Electrocuted", - "DeathReason.Scavenged": "Scavenged", "OnlyEnabledDeathReasons": "Apenas motivos de morte habilitados", "Alive": "Vivo", "Disconnected": "Desconectado", @@ -2024,10 +1972,11 @@ "DeputyHandcuffCooldown": "Recarga de Algemas", "DeputyHandcuffMax": "Máximo de Algemamentos", "DeputyHandcuffedPlayer": "Alvo algemado", - "HandcuffedByDeputy": "Você foi algemado!", - "DeputyInvalidTarget": "O alvo não pode ser algemado", + "HandcuffedByDeputy": "You were handcuffed!\nNow you have broken your handcuff and can kill again.", + "DeputyInvalidTarget": "Target is already handcuffed", + "HandcuffBrokenAfterMeeting": "Remove all handcuffs after meeting", "DeputyHandcuffText": "Algemar", - "DeputyHandcuffCDForTarget": "Recarga de Abate para jogador algemado", + "DeputyHandcuffCDForTarget": "Next Kill Cooldown for handcuffed player", "RejectShapeshift.AbilityWasUsed": "A habilidade foi usada", "EscapisMtarkedPosition": "Você marcou a sua própria posição", "InvestigateCooldown": "Recarga para Investigar", @@ -2087,7 +2036,6 @@ "ShowMadmatesInLeftCommand": "Mostrar Cúmplices (incluindo atributos)", "ShowApocalypseInLeftCommand": "Mostrar Neutros do Apocalipse", "SeeEjectedRolesInMeeting": "Ver Funções Ejetadas em Reuniões", - "ThankYouForUsingTOHE": "Thank you for using TOHE!", "SkillUsedLeft": "Você ativou sua habilidade para convocar uma reunião. \nQuantidade restante de usos disponíveis::", "NemesisDeadMsg": "A morte do Mafioso significa o início da Vingança! \nPor favor, use /rv + [ID do jogador] para matar o jogador especificado. \nVocê pode ver os IDs dos jogadores na frente de seus nomes. \nOu digite /rv para obter uma lista de IDs dos jogadores", "NemesisAliveKill": "A Vingança pelo Mafioso só pode começar após sua morte.", @@ -2107,7 +2055,6 @@ "GuessNotifiedBait": "O Armador não pode ser adivinhado porque foi anunciado, você pensou que seria fácil, não é?", "GuessGM": "Adivinhar o Espectador é impossível porque ele já está morto... E também... por que você faria isso com o pobre anfitrião?", "GuessGuardianTask": "Você não pode adivinhar um Anjo Guardião que já completou suas tarefas.", - "GuardianCantKilled": "You can't kill a Guardian who has finished their tasks.", "GuessMarshallTask": "Você não pode adivinhar um Marechal que já completou suas tarefas.", "GuessObviousAddon": "Desculpe, mas Atributos óbvios não podem ser adivinhados.", "GuessAdtRole": "Infelizmente, as configurações do anfitrião não permitem que você adivinhe Atributos.", @@ -2163,7 +2110,6 @@ "BecomeMadmateCuzMadmateMode": "Você se tornou um Cúmplice porque morreu", "CleanerCleanBody": "O corpo foi limpo!", "QuickShooterStoraging": "Marcadores armazenados com sucesso", - "QuickShooterFailed": "You are still in cooldown.", "PoisonerTargetDead": "O alvo foi morto!", "HexesLookLikeSpells": "Mestres Feiticeiros aparecem como magia", "HexButtonText": "Feitiço", @@ -2322,7 +2268,6 @@ "Message.YTPlanNotice": "Observação: o [Plano YouTuber] está habilitado neste lobby, o que significa que o anfitrião pode especificar sua função no próximo jogo para facilitar a obtenção de conteúdo. Caso o anfitrião abuse deste recurso, saia do jogo ou denuncie.\nJogador:", "Message.OnlyCanBeUsedByHost": "ERRO\n\nEste comando só pode ser usado pelo anfitrião.", "Message.MaxPlayers": "Máximo de jogadores definido para ", - "Message.MaxPlayersFailByRegion": "Could not set max players: Vanilla regions support a maximum of 15 players.", "Message.GhostRoleInfo": "Informações sobre as Funções de Fantasma\nOlá! Um pouco sobre as funções de fantasma...\n\nAs funções de fantasma impactam drasticamente o jogo, por isso não são recomendadas em salas com poucas pessoas, se você não estiver familiarizado.\n\nAparecerá:\nAs funções de fantasma só aparecem após a morte, as primeiras x pessoas da (equipe) a morrer as pegam.\n\nPS: Se sua função anterior não tinha tarefas (por exemplo, xerife), suas tarefas como função fantasma não são necessárias para vencer por tarefas", "ApocalypseInfoTitle": "Informações sobre Neutros do Apocalipse:", "Message.ApocalypseInfo": "Cada função da Equipe <#ff174f>Apocalipse tem seu próprio objetivo a ser cumprido para se transformar.\nMembros <#2B0804>Transformados <#ff174f>do Apocalipse têm uma mudança drástica no jogo e são imortais (exceto por serem votados), mas todos serão notificados de que eles se transformaram.\n\nFunções: <#e5f6b4>Porta-Pragas, <#A675A1>Coletor de Almas, <#bf9f7a>Padeiro, <#cc0044>Aprimorador \nTransformados: <#343136>Peste, <#644661>Morte, <#83461c>Faminto, <#2B0804>Guerra\n\nMembros do Apocalipse podem ver as funções e os ícones de habilidades uns dos outros. Assim como os Neutros Assassinos, os membros do Apocalipse também mantêm o jogo em andamento, divirta-se!", @@ -2454,6 +2399,7 @@ "LastResult": "★ Resultados da partida", "LastEndReason": "★ Motivo do fim do jogo", "KillLog": "Registro de abates", + "MainRoleLog": "Role Convert Log", "Maximum": "Máximo", "RoleRate": "LIGADO", "RoleOn": "SEMPRE", @@ -2640,7 +2586,7 @@ "NeutralRemain": "\n{0} Neutro Assassino restante", "OneNeutralRemain": "\n{0} Neutros Assassinos restantes", "ApocRemain": "\n{0} Neutros Apocalipse restantes", - "GameOverReason.HumansByVote": "Todos os Impostores e Neutros Assassinos foram ejetados ou Mortos", + "GameOverReason.HumansByVote": "All Impostors and Neutral Killers were ejected or killed", "GameOverReason.HumansByTask": "Os Tripulantes completaram todas as Tarefas", "GameOverReason.HumansDisconnect": "Tripulantes Desconectados", "GameOverReason.ImpostorByVote": "Os Tripulantes foram Ejetados", @@ -2730,9 +2676,8 @@ "DeathMeetingTimeIncrease": "Aumentar o tempo de reunião quando a Morte existe", "SoulCollectorMeetingDeath": "Seu alvo morreu durante a reunião. Você ganhou uma alma.", "SoulCollectorKillButtonText": "Preditar", - "SoulCollectorHasImpostorVision": "Soul Collector has Impostor vision", "ApocalypseIsNigh": "[ O Apocalipse Está Próximo! ]", - "ApocalypseImmune": "This role is immune!", + "ApocalypseImmune": "Esse jogador é imune por causa que ele é invéncivel!", "BakerToFamine": "Você virou o Faminto!!!", "BakerTransform": "O Padeiro se transformou no Faminto, Cavaleiro do Apocalipse! Uma fome começou!", "BakerAlreadyBreaded": "Esse jogador ja está com um pão!", @@ -2741,15 +2686,13 @@ "BakerBreadNeededToTransform": "Número de pães requeridos para se tornar o Faminto", "BakerCantBreadApoc": "Você não pode dar um pão a outros Membros do Apocalipse!", "BakerKillButtonText": "Alimentar", - "BakerUnshiftButtonText": "Switch Bread", "BakerRevealBread": "Revelar", "BakerRoleblockBread": "Bloquear", "BakerBarrierBread": "Barreira", "BakerCurrentBread": "Pão Atual: ", "BakerSwitchBread": "Pão Trocado para: ", - "BakerCanVent": "Baker can Vent", + "BakerCanVent": "Padeiro pode usar os dutos", "BakerBreadGivesEffects": "O Pão da efeitos adicionais", - "BakerTransformNoMoreBread": "Baker transforms if they do not have enough bread", "FamineKillButtonText": "Fome", "FamineStarveCooldown": "Tempo para morrer de fome do Faminto", "FamineCantStarveApoc": "Você não pode fazer outros Membros do Apocalipse morrerem de fome!", @@ -2796,7 +2739,6 @@ "GodfatherTargetCountMode": "Assassino se torna", "GodfatherCount_Refugee": "Refugiado", "GodfatherCount_Madmate": "Trimpostor", - "GodfatherRefugeeMsg": "You have been recruited by GodFather!", "MissChance": "Chance de errar", "IncreaseByOneIfConvert": "Aumentar a contagem de mortes +1 se um tripulante for convertido", "HawkMissed": "Errou Bichão!", @@ -2829,7 +2771,6 @@ "BerserkerToWar": "Você virou o Guerreiro!!!", "BerserkerTransform": "O Aprimorador se transformou no Guerreiro, Cavaleiro do Apocalipse! Grite 'Desordem!' e solte os cães da guerra.", "WarKillCooldown": "Recarga para matar do Guerreiro", - "BerserkerCanKillTeamate": "Can kill other Neutral Apocalypse", "BlackmailerSkillCooldown": "Recarga para Silenciar", "BlackmailerMax": "Máximo de vezes que os jogadores silenciados podem falar", "BlackmailerDead": "Aviso: {0} foi silenciado por um Silenciador.", @@ -2919,8 +2860,6 @@ "RememberedPursuer": "Você relembrou que era um Perseguidor!", "RememberedFollower": "Você relembrou que era um Seguidor!", "RememberedAmnesiac": "Você falhou ao lembrar sua função.", - "AmnesiacRemembered": "You remembered you were {0}!", - "ReportWhenFailedRemember": "Report Dead Body when failed to remember", "RememberedImitator": "Você se lembrou que você era um Imitador.", "RememberedImpostor": "Você relembrou que era um Impostor!", "RememberedCrewmate": "Você relembrou que era um Tripulante!", @@ -2941,7 +2880,7 @@ "BanditStealCooldown": "Recarga para Roubar", "DoppelMaxSteals": "Máximo de roubos", "DoppelCurrentVictimCanSeeRolesAsDead": "O último jogador morto pode ver a função e informações adicionais dos jogadores vivos como um fantasma", - "NecromancerRevengeTime": "Tempo da Necromancia", + "NecromancerRevengeTime": "Necromancy time", "NecromancerRevenge": "Você tem {0}s para matar {1}", "NecromancerSuccess": "Necromancia concluída! Você vive para ver o outro dia.", "NecromancerHide": "Entrar nas ventilações está desativado, esconda-se do Necromante!", @@ -3146,7 +3085,7 @@ "DollMaster_PossessedTarget": "Alvo possuído", "DollMaster_CannotPossessImpTeammate": "Incapaz de possuir alguém do mesmo time", "DollMaster_CouldNotSwapWithTarget": "Incapaz de possuir alguém do mesmo time", - "DollMaster_CanNotSwapWithDeadTarget": "Não se pode possuir um jogador morto", + "DollMaster_CanNotSwapWithDeadTarget": "Possessing a dead player isn't possible", "DollMaster_MainBody": "Corpo principal", "DollMaster_Doll": "Marionete", "DollMaster_UnableToUseAbility": "Não foi possível usar a habilidade no jogador", @@ -3164,7 +3103,7 @@ "PitfallTrapCauseVisionTime": "Duração da Visão afetada pela Armadilha", "PitfallTrap": "Você caiu em uma Armadilha!", "ConsigliereDivinationMaxCount": "Máximo de Revelações", - "RitualMaxCount": "Máximo de Revelações", + "RitualMaxCount": "Maximum Reveals", "CleanserHideVote": "Esconder o voto do Limpador", "OracleSkillLimit": "Máximo de Usos", "OracleHideVote": "Esconder votos do Oráculo", @@ -3334,12 +3273,9 @@ "PixieTargetAlreadySelected": "O alvo já foi selecionado", "PixieButtonText": "Marcar", "PlagueBearerCooldown": "Recarga para passar a praga", - "PlagueBearerCanVent": "Can vent", - "PlagueBearerHasImpostorVision": "Has Impostor vision", "PestilenceCooldown": "Recarga de ataque da Peste", "PestilenceCanVent": "A Peste Can Vent", "PestilenceHasImpostorVision": "A Peste tem Visão de Impostor", - "PestilenceKillGuessers": "Kill players who guess Pestilence", "PlagueBearerAlreadyPlagued": "O Jogador já está infectado", "PlagueBearerToPestilence": "Você se tornou a Peste!!", "GuessPestilence": "Você tentou matar a Peste!\n\n★ A Peste te matou.", @@ -3383,7 +3319,6 @@ "EveryoneCanKnowMini": "Todos podem ver o Mini", "CanBeEvil": "O Mini pode ser um Impostor", "EvilMiniSpawnChances": "Probabilidade de o Mini ser um Impostor", - "EvilMiniCanBeGuessed": "Evil Mini can be guessed before 18", "GuessMini": "Desculpe, mas você pode não fazer mal a uma criança Mini.", "GrowUpDuration": "Tempo necessário para crescer", "MajorCooldown": "Tempo de recarga quando tiver mais de 18 anos", @@ -3525,7 +3460,6 @@ "WinnerRoleText.Doppelganger": "Vitória do Sósia!", "WinnerRoleText.Quizmaster": "Vitória do Mestre das Charadas!", "WinnerRoleText.Agitater": "Vitória do Demolidor!", - "WinnerRoleText.Shocker": "Shocker Wins!", "AdditionalWinnerRoleText.Sidekick": "Ajudante", "AdditionalWinnerRoleText.Taskinator": "Sabota-Tarefas", "AdditionalWinnerRoleText.Opportunist": "Oportunista", @@ -3611,7 +3545,7 @@ "SolsticerOnMeeting": "Você testemunhou muitas mortes! Na próxima rodada você terá mais {0} tarefas curtas!", "SolsticerTitle": "Speedrunner", "GuessSolsticer": "Desculpe, mas você não pode adivinhar o Speedrunner!", - "ExpelSolsticer": "Sorry, but you can not expel Solsticer!", + "VoteSolsticer": "Desculpe, mas você não pode votar no Speedrunner!", "SolsticerTasksReset": "Suas tarefas foram redefinidas!", "SolsticerMisGuessed": "Você adivinhou errado! Então você não irá mais poder adivinhar.", "SolsticerGuessMax": "Você adivinhou errado na sua adivinhação anterior, você não tem mais permissão para adivinhar.", @@ -3712,19 +3646,6 @@ "MinionAbilityTime": "Duração da Habilidade", "Minion_Blind": "cegado", "Evader_ChanceNotExiled": "Chance de não ser expulso", - "ShockerAbilityCooldown": "Ability Cooldown", - "ShockerAbilityDuration": "Ability Duration", - "ShockerAbilityPerRound": "Abilities Per Round", - "ShockerShockInVents": "Shock people in vents", - "ShockerAbilityResetAfterMeeting": "Reset marked rooms after meeting", - "ShockerOutsideRadius": "Radius Of Outside Tasks (not in a room)", - "ShockerCanShockHimself": "Can Shock Himself", - "ShockerImpostorVision": "Shocker has Impostor vision", - "ShockerIsShocking": "You're already shocking!", - "ShockerAbilityActivate": "Begin Shocking!", - "ShockerAbilityDeactivate": "Ability Deactivated", - "ShockerVentButtonText": "Shock", - "ShockerRoomMarked": "Marked Room", "EavesdropperMsgTitle": "Você encontrou um segredo", "EavesdropPercentChance": "Chance de Interceptar", "ChiefOfPoliceSkillCooldown": "Cooldown for recruiting sheriffs", @@ -3736,4 +3657,4 @@ "PolicPreventRecruitNonKiller": "Prevent recruit players without kill button", "PolicSuidiceWhenTargetNotKiller": "Suidices when recruit a non killer or non crewmate", "PolicPassConverted": "Can pass Converted Addon to Sheriff" -} +} \ No newline at end of file diff --git a/Resources/Lang/pt_PT.json b/Resources/Lang/pt_PT.json index 4cc9530af..5ef5950a4 100644 --- a/Resources/Lang/pt_PT.json +++ b/Resources/Lang/pt_PT.json @@ -20,8 +20,6 @@ "SubText.Neutral": "Trabalhe sozinho para alcançar a sua vitória", "SubText.Apocalypse": "Become unstoppable with your team", "SubText.Madmate": "Ajuda os Impostores", - "SubText.Lovers": "Stay alive and win together", - "SubText.Egoist": "Win on your own", "TypeImpostor": "Impostores", "TypeCrewmate": "Tripulantes", "TypeNeutral": "Neutros", @@ -31,9 +29,6 @@ "TeamNeutral": "Neutro", "TeamCrewmate": "Tripulante", "TeamMadmate": "Traidor", - "TeamLovers": "Lovers", - "TeamEgoist": "Egoist", - "TeamApocalypse": "Apocalypse", "YouAreCrewmate": "Tu és um Tripulante", "YouAreImpostor": "Tu és um Impostor", "YouAreNeutral": "Tu és um Neutro", @@ -225,7 +220,6 @@ "TaskManager": "Regulador de Tarefas", "Witness": "Testemunha", "Swapper": "Trocador", - "ChiefOfPolice": "Chief of Police", "NiceMini": "Mini Bondoso", "Mini": "Mini", "Spy": "Espião", @@ -254,7 +248,6 @@ "Stalker": "Stalker", "Workaholic": "Workaholic", "Solsticer": "Solsticer", - "Abyssbringer": "Abyssbringer", "Collector": "Collector", "Provocateur": "Provocateur", "BloodKnight": "Blood Knight", @@ -393,8 +386,6 @@ "Sloth": "Sloth", "Prohibited": "Prohibited", "Eavesdropper": "Eavesdropper", - "Shocker": "Shocker", - "Revenant": "Revenant", "BracketAddons": "Add Brackets To Add-ons", "EngineerTOHEInfo": "Use the vents to catch the Impostors", "ScientistTOHEInfo": "Access portable vitals from anywhere", @@ -513,7 +504,7 @@ "PacifistInfo": "Vent to reset kill cooldowns", "RebirthInfo": "Arise Again", "MonarchInfo": "Give your crew extra voting power!", - "AbyssbringerInfo": "Place Black Holes", + "AbyssbringerInfo": "Create Black Holes", "SpurtInfo": "Spring Like A rabbit!", "StealthInfo": "Killing Blinds Everyone in the Room", "PenguinInfo": "Drag your victims", @@ -538,7 +529,7 @@ "AdmirerInfo": "Choose a player to side with you", "TimeMasterInfo": "Rewind time!", "CrusaderInfo": "Kill a player's attacker", - "AltruistInfo": "Revive a player", + "AltruistInfo": "Revive a player\nVent to change between Revive and Report", "ReverieInfo": "With each kill, your cooldown decreases", "LookoutInfo": "See through disguises", "TelecommunicationInfo": "Track device usage", @@ -547,7 +538,6 @@ "WitnessInfo": "Find out if someone killed recently", "GhastlyInfo": "Control somebody!", "SwapperInfo": "Swap the votes of two players", - "ChiefOfPoliceInfo": "Hire Sheriff to Serve the Crews!", "NiceMiniInfo": "No one can hurt you until you grow up.", "ArsonistInfo": "Douse everyone and ignite", "PyromaniacInfo": "Douse and kill everyone", @@ -615,7 +605,7 @@ "ShroudInfo": "Shroud players to make them kill", "WerewolfInfo": "Kill crewmates in groups", "ShamanInfo": "Deflect all the attacks on Voodoo doll", - "SeekerInfo": "Play Hide and Seek with your target", + "SeekerInfo": "Play Hide and Seek with your target\nYour target has a ★ mark.", "PixieInfo": "Tag 'em, Bag 'em, and Eject 'em!", "OccultistInfo": "Kill and curse your enemies", "SchrodingersCatInfo": "The cat is both alive and dead until observed.", @@ -708,8 +698,6 @@ "SlothInfo": "You're slower", "ProhibitedInfo": "Certain vents are blocked", "EavesdropperInfo": "Listen in on other roles", - "ShockerInfo": "Shock unsuspecting players", - "RevenantInfo": "Take your killer's role", "EngineerTOHEInfoLong": "(Crewmates):\nAs the Engineer, you may access the vents while Comms Sabotaged is inactive.", "ScientistTOHEInfoLong": "(Crewmates):\nAs the Scientist, you can see vitals at any time, showing you who is alive and dead.", "NoisemakerTOHEInfoLong": "(Crewmates):\nAs the Noisemaker, whenever you die, you will make a noise, and a visual indicator of your death appears on the screen so the Crewmates can run to catch the person who killed you red-handed (even if it’s not Red).", @@ -781,11 +769,11 @@ "LurkerInfoLong": "(Impostors):\nAs the Lurker, you can jump into a vent to reduce your cooldown by a certain number of seconds. After you kill, your cooldown resets to its original value.", "VisionaryInfoLong": "(Impostors):\nAs the Visionary, you see the alignments of living players during a meeting.\nThe following information will be displayed on the players:\n- The Red name indicates the Impostors.\n- The Cyan name indicates the Crewmates.\n- The Gray name indicates the Neutrals.", "PlagueDoctorInfoLong": "(Neutrals):\n(Plague Doctor from TOH)\nThe Plague Scientist's goal is to infect every living player.\nThey start by choosing one player to infect, after which anyone who spends a set amount of time in the range of the infected player becomes infected themselves.\nInfection progress is cumulative and does not reset with distance or after meetings.", - "RefugeeInfoLong": "(Madmates):\nAs the Refugee, you were either:\n -An Amnesiac who remembered an Impostor\n -A killer who killed the Godfather's target.\n -A Romantic whose partner was an Impostor\n -Or an Imitator that imitated an Impostor.\n\nNow your job is to help the Impostors kill the crewmates.", + "RefugeeInfoLong": "(Madmates):\nAs the Refugee, you were either an Amnesiac who remembered an Impostor or a killer who killed the Godfather's target.\n\nNow your job is to help the Impostors kill the crewmates.", "UnderdogInfoLong": "(Impostors):\nAs the Underdog, you cannot kill until there's a certain amount of players alive.", "ConsigliereInfoLong": "(Impostors):\nAs the Consigliere, you can reveal the roles of other players using your kill button.\n\nSingle click: Reveal role\nDouble click: Kill\n\nIf you run out of reveal uses, your kill button functions normally.", "LudopathInfoLong": "(Impostors):\nAs the Ludopath, your kill cooldown is randomized.\n\nMinimum it can be is 1 second, while the maximum is your default kill cooldown.", - "GodfatherInfoLong": "(Impostors):\nAs the Godfather, you vote someone to make them your target.\nIn the next round, if someone kills the target, the killer will turn into a Refugee or Madmate.", + "GodfatherInfoLong": "(Impostors):\nAs the Godfather, you vote someone to make them your target.\nIn the next round, if someone kills the target, the killer will turn into a Refugee.", "ChronomancerInfoLong": "(Impostors):\nAs the Chronomancer, you have a charge bar which indicates when the slaughter is ready. When it is at 100% the next time you kill someone, you go into slaughter mode, meaning you can kill indefinitely until your bar runs out of charge. Otherwise, you have a normal KCD.", "PitfallInfoLong": "(Impostors):\nAs the Pitfall, you use your shapeshift to mark the area around the shapeshift as a trap. Players who enter this area will be immobilized quickly, and their vision will be affected.", "EvilMiniInfoLong": "(Impostors):\nAs the Evil Mini, you are unkillable until you grow up and have a very long initial kill cooldown, which gets drastically shortened as you grow up.", @@ -821,7 +809,7 @@ "GrenadierInfoLong": "(Crewmates):\nAs the Grenadier, you can vent to Flashbang players nearby, causing them to lose vision if they are an Impostor or, depending on settings, a Neutral.", "MedicInfoLong": "(Crewmates):\nThe Medic can place a shield on the target by pressing the Kill button. The Medic can only give one shield for the whole game. Depending on the settings, the target's shield can or cannot deactivate when the Medic dies. The Medic can also see if someone is trying to break the target's shield.\nDepending on the Host's settings, the Medic or the target can see if the player has a shield (shown as a green circle 「●」 next to the name).", "FortuneTellerInfoLong": "(Crewmates):\nAs the Fortune Teller, vote for a player in a meeting to get a clue to their role.\nThe clue will relate to their actual role.\n\nWhen the Fortune Teller's tasks are complete, they will obtain the exact role rather than a clue!\n\nNote: If the setting to give random active players as a hint is on, you cannot check the same player multiple times.", - "JudgeInfoLong": "(Crewmates):\nThe Judge can judge a certain player during the meeting. If the target is evil, the target will be killed (whether it is evil or not is set by the Host). If it is wrong, the Judge commits suicide.\nCommand for judgment: /tl [player id]\nYou can see the player's id before the player's name, or use the /id command to view the id of all players.\nJudges can judge all players when they become Madmate.", + "JudgeInfoLong": "(Crewmates):\nThe Judge can judge a certain player during the meeting. If the target is evil, the target will be killed (whether it is evil or not is set by the Host). If it is wrong, the Judge commits suicide.\nCommand for judgment: /tl [player id]\nYou can see the player's id before the player's name, or use the /id command to view the id of all players.\nJudges can judge all players when they become Madmate.\nIn meeting the ability count shows how many trails you have in this meeting. Out of meeting the ability counts shows how many trails you have for the whole game.", "MorticianInfoLong": "(Crewmates):\nThe Mortician can see arrows pointing to all dead bodies, and if the Mortician reports a body, they will know the last player the victim had contact with. Note: Mortician won't be Oblivious or Seer.", "MediumInfoLong": "(Crewmates):\nThe Medium can establish contact with a dead player after someone reports a dead body. The player who reports doesn't have to be the Medium. The dead player can answer once with a YES or a NO to the Medium's question, which only the Medium will see (the dead player can use /ms yes or /ms no). Note: Medium won't be Oblivious.", "ObserverInfoLong": "(Crewmates):\nAs the Observer, you can see all shield animations caused by other players after the first meeting. The shied animations typically indicate a role ability, so look out for this.", @@ -833,7 +821,7 @@ "MerchantInfoLong": "(Crewmates):\nAs a merchant, you sell a random add-on to a random player for each task you complete. Each add-on sold earns you money. If you have a certain amount of money, you can prevent the next killing attempt against you by bribing the murderer. The bribed player won't be able to kill you, but you don't know who it is. The money used is lost and not available for additional bribes.", "RetributionistInfoLong": "(Crewmates):\nAs the Retributionist, you can kill a limited amount of players after your death.\n\nUse /ret [playerID] to kill.", "HawkInfoLong": "(Crewmates [Ghost]):\nAs the Hawk, you can kill a limited amount of players decided by the host, though there's a chance you miss, slicing someone multiple times increases the chances.", - "DeputyInfoLong": "(Crewmates):\nAs the Deputy, use your kill button on a player to reset their kill cooldown.\n\nIf the target does not have a kill button, then the handcuff was a waste.", + "DeputyInfoLong": "(Crewmates):\nAs the Deputy, use your kill button to handcuff a player.\nThe player who is handcuffed will have their next kill attempt treated as a handcuff break, and the kill cooldown will be reset.\n\nIf the target does not have a kill button, then the handcuff was a waste.", "InvestigatorInfoLong": "(Crewmates):\nAs an Investigator, you can use your kill button to investigate someone. When you investigate someone, their name will appear in red if they possess a kill button (impostor/SS basis) or light blue if they lack a kill button (crewmate/engineer/scientist basis). However, please note that the color of the names will return to normal when someone calls a meeting.", "GuardianInfoLong": "(Crewmates):\nAs the Guardian, you become immortal upon task completion. Guessers can't even guess you in meetings.", "AddictInfoLong": "(Crewmates):\nAs the Addict, you have a suicide timer. When it expires, you kill yourself.\nThe timer is indicated by the vent cooldown. When the vent cooldown is 0 seconds, you still have a short time to vent.\nIf you don't make it, you die; if you make it, the suicide timer is reset.\nAlso after you vent, no one can interact with you for a defined period.\nAfter; the period is over, and you are immobilized for another defined period, and cannot report any bodies.", @@ -849,7 +837,7 @@ "AdmirerInfoLong": "(Crewmates):\nAs the Admirer, admire a player to make them Crewmate aligned.\nThey'll win with crewmates and not their original team.\n\nYou can only do this once per player.", "TimeMasterInfoLong": "(Crewmates):\nAs the Time Master, use the vents to mark everyone's position.\nWhen using the ability again, every alive player will rewind to the marked positions.\n\nDuring the ability duration, the Time Master gains a time shield, which protects them from death.", "CrusaderInfoLong": "(Crewmates):\nAs the Crusader, use your kill button to crusade a player.\nIf that player gets attacked, you'll kill the attacker.", - "AltruistInfoLong": "(Crewmates):\nAs the Altruist, you can sacrifice yourself to revive a dead body using the «Report» button.\nNote: If a dead player has left the game, you report that body normally.\nAlso revived player cannot report self dead body", + "AltruistInfoLong": "(Crewmates):\nAs the Altruist, you can sacrifice yourself to revive a dead body using the «Report» button.\nNote: If a dead player has left the game, you report that body normally.\nAlso revived player cannot report self dead body\nUse vent button to change between Report & Revive.", "ReverieInfoLong": "(Crewmates):\nAs the Reverie, you can kill, but your cooldown starts high.\n\nIt increases if you kill a crewmate and reduces otherwise.\nDepending on the Host's setting, you may misfire on reaching the max kill cooldown, and your target dies with you. \n\nYou win with other crewmates.", "LookoutInfoLong": "(Crewmates):\nAs the Lookout, you can see the IDs of every player at all times.\nThis allows you to see through shapeshifts and camouflages.", "TelecommunicationInfoLong": "(Crewmates):\nAs the Telecommunication, you are notified when anyone uses cameras, vitals, door logs, or admin.", @@ -872,7 +860,7 @@ "LawyerInfoLong": "(Neutrals):\nLawyer has a target to defend, which will be indicated by a diamond 「♦」 next to their name.\nIf your target wins, you win.\nIf they lose, you lose.", "OpportunistInfoLong": "(Neutrals):\nIf the Opportunist survives at the end of the game, the Opportunist will win with the winning player.", "VectorInfoLong": "(Neutrals):\nVector will win alone by venting a certain number of times.", - "JackalInfoLong": "(Neutrals):\nAs the Jackal, you win if you are the last player alive. Additionally, you may recruit using the kill button. If the target is not one you can recruit, you have run out of uses, or you don't have the option to recruit, then you will kill people normally (i.e., don't use kill buttons in front of others thinking it'll recruit). If the target has a kill button and the option to turn into a Sidekick is on, they will become a Sidekick. Otherwise, they will gain the Recruit add-on if the option to give the Recruit add-on is on.\nDepending on the settings, when Jackal was killed, a Sidekick will be randomly selected as the new Jackal.\nRecruit may be selected if no sidekick is alive.", + "JackalInfoLong": "(Neutrals):\nAs the Jackal, you win if you are the last player alive. Additionally, you may recruit using the kill button. If the target is not one you can recruit, you have run out of uses, or you don't have the option to recruit, then you will kill people normally (i.e., don't use kill buttons in front of others thinking it'll recruit). If the target has a kill button and the option to turn into a Sidekick is on, they will become a Sidekick. Otherwise, they will gain the Recruit add-on if the option to give the Recruit add-on is on.", "GodInfoLong": "(Neutrals):\nAs the God, you know everyone's role from the beginning. If you live until the end of the game, you steal the win, i.e., everyone else loses, and you win.", "InnocentInfoLong": "(Neutrals):\nThe Innocent can use the kill button to plant any player, and the planted target will immediately kill the Innocent. If the target gets voted out in the meeting, the Innocent wins. Note: Jester, Executioner, and Innocent can win together.", "PelicanInfoLong": "(Neutrals):\nAs the Pelican, you can use the kill button to swallow a player alive, teleporting them off-bounds but not killing them yet. Those swallowed will only die if you're still alive at the end of the round. If you die or leave during the round, all alive swallowed players will spawn into the map where you were.", @@ -884,14 +872,14 @@ "SolsticerInfoLong": "(Neutrals):\nAs the Solsticer, you won't die, and you win by finishing all your tasks in a single round. After every meeting finishes, your tasks reset, and you need to start all over again.\nVotes on the Solsticer will be directly canceled.\nKill attempts on the Solsticer will teleport it out of the map like Pelican until the meeting is finished.\nThe killer's kill cooldown will be reset to 10 seconds.\nSolsticer is counted as nothing in-game.", "CollectorInfoLong": "(Neutrals):\nAs the Collector, when you vote for a player, for each other player that voted for them, you gain a point. When you collect the required votes, the game ends, and you win alone, even if you voted a Jester or Executioner's target out.", "GlitchInfoLong": "(Neutrals):\nAs the Glitch, you can hack players (single click) or kill normally (double click).\nThose who have been hacked cannot kill, vent, or report for the hack duration.\nAdditionally, calling a sabotage other than doors will have no effect and will instead disguise you as a random player. You cannot disguise during or after sabotages.\nTo win, be the last player alive.", - "SidekickInfoLong": "(Neutrals):\nAs the Sidekick, your job is to help the Jackal kill everyone.\nYou and the Jackal win together.\nDepending on the settings, you may turn into Jackal if old Jackal was killed.\nYou may not be able to kill until old Jackal is dead.", + "SidekickInfoLong": "(Neutrals):\nAs the Sidekick, your job is to help the Jackal kill everyone.\n\nYou and the Jackal win together.", "ProvocateurInfoLong": "(Neutrals):\nAs the Provocateur, you can kill any target with the kill button. If the target loses at the end of the game, the Provocateur wins with the winning team.", "BloodKnightInfoLong": "(Neutrals):\nThe Blood Knight wins when they're the last killing role alive, and the amount of crewmates is lower or equal to the amount of Blood Knights. The Blood Knight gains a temporary shield after every kill, making them immortal for a few seconds.", "PlagueBearerInfoLong": "(Apocalypse):\nAs the Plaguebearer, plague everyone using your kill button to turn into Pestilence.\nOnce you turn into Pestilence, you will become immortal and gain the ability to kill, and you will kill anyone who tries to kill you.\n\nAlso, when infected players interact with uninfected players, they will also be infected.", "PestilenceInfoLong": "(Apocalypse):\nAs Pestilence, you're an unstoppable machine.\nAny attack towards you will be reflected towards them.\nIndirect kills don't even kill you.\n\nOnly way to kill Pestilence is by voting them out or the Pestilence misguessing.\nYour presence is announced to everyone at the meeting after you transform.", "SoulCollectorInfoLong": "(Apocalypse):\nAs Soul Collector, you can use your kill button on a player to predict their death. You will gain a soul if your target dies in the round you select them or the meeting after.\nYour target resets after each meeting or after they die, whichever comes first. \n\nOnce you collect the configurable amount of souls, you become Death. If the gain passive souls setting is enabled, you will gain a soul each meeting.", "DeathInfoLong": "(Apocalypse):\nOnce the Soul Collector has collected their needed souls, they become Death. Death kills everyone and wins if Death is not ejected by the end of the next meeting.\nA configurable amount of extra meeting time will be given on the meeting Death transforms to have more discussion to find Death.\n\nYou are invincible, and your presence is announced to everyone at the meeting after you transform.", - "BakerInfoLong": "(Apocalypse):\nAs the Baker, you can use your kill button on a player per round to give them bread. \nOnce a set amount of players are alive with bread, you become Famine.\n\nIf the Bread gives additional effects and the setting is on, then you can vent to change the bread that you give out. \nBread Effects:\nReveal: Reveals the target's role to the Baker (stays the whole game)\nRoleblock: Sets the target's kill cooldown to 999 (resets to normal after the meeting)\nBarrier: Gives the target a barrier that is only known to the Baker (barrier is removed after the meeting)", + "BakerInfoLong": "(Apocalypse):\nAs the Baker, you can use your kill button on a player per round to give them bread. \nOnce a set amount of players are alive with bread, you become Famine.\n\nIf the Bread gives additional effects and the setting is on, then you can vent to change the bread that you give out. \nBread Effects:\nReveal: Reveals the target's role to the Baker (stays the whole game)\nRoleblock: Resets the target's kill cooldown when they try to use their kill button\nBarrier: Gives the target a barrier that is only known to the Baker (barrier is removed after the meeting)", "FamineInfoLong": "(Apocalypse):\nOnce the Baker has a set amount of people with bread alive, they will become Famine. If the Famine does not get voted out after the meeting, then they will become Famine, and every player without bread will starve (excluding other Apocalypse members).\nAfter this starvation of everyone without bread, Famine can use their kill button to starve any remaining players, which will kill those players right before the next meeting.\n\nYou are invincible, and your presence is announced to everyone at the meeting after you transform.", "BerserkerInfoLong": "(Apocalypse):\nAs the Berserker, you level up with each kill.\nUpon reaching a certain level defined by the Host, you unlock a new power.\n\nScavenged kills make your kills disappear.\nBombed kills make your kills explode. Be careful when killing, as this can kill your other Apocalypse members if they are near. \nAfter a certain level, you become War.", "WarInfoLong": "(Apocalypse):\nAs War, you are invincible, have a lower kill cooldown, and can kill anyone with your previous powers.\nYour presence is announced to everyone at the meeting after you transform.", @@ -911,12 +899,11 @@ "TraitorInfoLong": "(Neutrals):\nAs the Traitor, you were an Impostor that betrayed the Impostors.\nYou know the Impostors, but they don't know you.\nThe twist? They can kill you, but you can't kill them.\n\nEliminate the Impostors by other means, then kill everyone else to win!", "TrollerInfoLong": "(Neutrals):\nAs a Troller, you can complete tasks so that random events can happen to players.\nFor example, changing the speed of all players, teleportation, influencing sabotage, etc.\nAlso you can win with the winning team.", "VultureInfoLong": "(Neutrals):\nAs the Vulture, report bodies to win!\n\nWhen you report a body, if your eat cooldown is up, you'll eat the body (makes it unreportable).\nIf your eat ability is still on cooldown, then you'll report the body normally.\n\nAdditionally, you'll report bodies normally if the maximum bodies eaten per round is reached.", - "AbyssbringerInfoLong": "(Impostors):\nAs the Abyssbringer, you can place black holes. Black holes will suck in players and kill them when colliding with them.", "TaskinatorInfoLong": "(Neutrals):\nAs the Taskinator, whenever you finish a task, the task will be bombed. When another player completes the bombed task, the bomb will detonate, and the player will die.\n\nYou win if you survive till the end and Crew doesn't win.\n\n Note: Taskinator bombs ignore all protection.", "BenefactorInfoLong": "(Crewmates):\nAs the Benefactor, whenever you finish a task, that task will be marked. When another player completes the marked task, they get a temporary shield.\n\n Note: Shield only protects from direct kill attacks.", "MedusaInfoLong": "(Neutrals):\nAs the Medusa, you can stone bodies much like cleaning a body.\nStoned bodies cannot be reported.\n\nKill everyone to win.", "SpiritcallerInfoLong": "(Neutrals):\nAs the Spiritcaller, your victims become Evil Spirits after they die. These spirits can help you win by freezing other players briefly or blocking their vision. Alternatively, the spirits can give you a shield that protects you briefly from an attempted kill.", - "AmnesiacInfoLong": "(Neutrals):\nAs the Amnesiac, use your report button to remember a target and get its role.\nTo balance the game, you will not be able to vent after remembering your role if you can't vent as Amnesiac.'", + "AmnesiacInfoLong": "(Neutrals):\nAs the Amnesiac, use your report button to remember a role.\n\nIf the target was an Impostor, you'll become a Refugee.\nIf the target was a crewmate, you'll become the target role if compatible (otherwise you become an Engineer).\nIf the target was a passive neutral or a neutral killer not specified, you'll become the role defined in the settings.\nIf the target was a neutral killer of a select few, you'll become the role they are.", "ImitatorInfoLong": "(Neutrals):\nAs the Imitator, use your kill button to imitate a player.\n\nYou'll either become a Sheriff, a Refugee, or some Neutral.", "BanditInfoLong": "(Neutrals):\nAs the Bandit, you can click your kill button one time to steal a player's addon and twice to kill. Depending on the settings, you may instantly steal the addon or after the meeting starts. After the maximum number of steals is reached, you will kill normally. Additionally, if there are no stealable addons on the target or the target is stubborn, you will kill the target.\n\nKill everyone to win.\n\nNote: Cleansed, Last Impostor, and Lovers cannot be stolen.\nNote: If Bandit can vent is on, Nimble will become unstealable.", "DoppelgangerInfoLong": "(Neutrals):\nAs the Doppelganger, use your kill button to steal a player's identity (their name and skin) and then kill your target.\n\nKill everyone to win.\n\nNote: You cannot steal the target's identity when Camouflage is active.", @@ -925,7 +912,7 @@ "ShroudInfoLong": "(Neutrals):\nAs the Shroud, you do not kill normally.\nInstead, use your kill button to shroud a player.\nShrouded players kill others.\nIf the shrouded player doesn't make a kill, they'll kill themselves after a meeting.\n\nShroud sees shrouded players with a 「◈」mark next to their name.\nShrouded players who did not make a kill will also have the 「◈」mark in meetings, where they'll die if the Shroud is alive by the end of the meeting.", "WerewolfInfoLong": "(Neutrals):\nAs the Werewolf, you can kill much like any killer.\nHowever, when you kill, any nearby players also die.\nAny player who dies to this will have their death reason as Mauled.\n\nTo balance this, you have a higher kill cooldown than anyone else.", "ShamanInfoLong": "(Neutrals):\nAs the Shaman, you can use your kill button to select a voodoo doll once per round. If the kill button is used on you, the effect will be deflected onto the voodoo doll.\nIf you survive until the end, you win with the winning team.\nNote: If the killer cannot kill the chosen target, murder is canceled, but if the killer rechecks the Shaman, the killer will kill the Shaman.", - "SeekerInfoLong": "(Neutrals):\nAs the seeker, use your kill button to tag the target. If the seeker tags the wrong player, a point is deducted, and if the seeker tags the correct player, a point will be added.\nAdditionally, the seeker will not be able to move for 5 seconds after every meeting and after getting a new target.\n\nThe seeker needs to collect a certain number of points set by the Host to win.", + "SeekerInfoLong": "(Neutrals):\nAs the seeker, use your kill button to tag the target. If the seeker tags the wrong player, a point is deducted, and if the seeker tags the correct player, a point will be added.\nAdditionally, the seeker will not be able to move for 5 seconds after every meeting and after getting a new target.\n\nThe seeker needs to collect a certain number of points set by the Host to win.\nSeeker will see a ★ mark on target's name.", "PixieInfoLong": "(Neutrals):\nAs the Pixie, Mark up to x amount of targets each round by using the kill button on them. You must have one of the marked targets ejected when the meeting starts. If unsuccessful, you will commit suicide, except if you didn't mark any targets or all the targets are dead. The selected targets reset to 0 after the meeting ends. If you succeed, you will gain a point. You see all your targets in colored names.\n\nYou win with the winning team when you have certain amounts of points set by the Host.", "SchrodingersCatInfoLong": "(Neutrals):\nAs Schrodingers Cat, if someone attempts to use the kill button on you, you will block the action and join their team. This blocking ability works only once. By default, you don't have a victory condition, meaning you win only after switching teams.\nIn Addition to this, you will be counted as nothing in the game.\n\nNote: If the killing machine attempts to use its kill button on you, the interaction is not blocked, and you will die.", "RomanticInfoLong": "(Neutrals):\nThe Romantic can pick their lover partner using their kill button (this can be done at any point of the game). Once they've picked their partner, they can use their kill button to give their partner a temporary shield that protects them from attacks. If their lover partner dies, the Romantic's role will change according to the following conditions:\n1. If their partner was an Impostor, the Romantic becomes the Refugee\n2. If their partner was a Neutral Killer, then they become Ruthless Romantic.\n3. If their partner was a Crewmate or a non-killing neutral, the Romantic becomes the Vengeful Romantic. \n\nThe Romantic wins with the winning team if their partner wins.\nNote: If your role changes, your win condition will be changed accordingly", @@ -937,7 +924,6 @@ "JinxInfoLong": "(Neutrals):\nAs the Jinx, whenever you get attacked, you jinx them, resulting in them dying to a jinx.\nThis has limited uses.\n\nKill off everyone to win.", "PotionMasterInfoLong": "(Neutrals):\nAs the Potion Master, you have three different potions assigned to three different actions.\n\nSingle click: Reveal role\nDouble click: Kill\nMap: Sabotage\n\nThe reveal potion has a limit.\nWhen you run out, the kill buttons default to killing.", "NecromancerInfoLong": "(Neutrals):\nAs the Necromancer, you win when you're the last one standing.\nAdditionally when someone tries to kill you, you will block the kill, and you will teleport to a random vent. You will have a limited time to kill your killer. If you succeed in doing so, you live. If the time runs out before you kill your killer, you die permanently. If you try to kill someone else other than your killer, you will die.", - "ShockerInfoLong": "(Neutrals):\nAs the Shocker, you can mark rooms by doing tasks in them, and then vent to Electrocute anyone in those rooms for a set period of time. When you finish all of your tasks, you get new ones. Note: Doing tasks during that period will mark them for the next ability use.", "LastImpostorInfoLong": "(Add-ons):\nThis special effect is given to the last surviving Impostor. It significantly reduces their kill cooldown.", "OverclockedInfoLong": "(Add-ons):\nAs the Overclocked, your kill cooldown is reduced by a percentage.\n\nThis feature is only assigned to roles with a kill button.", "LoversInfoLong": "(Add-ons):\nLovers are a combination of two players. The Lovers win when they are the last ones standing, and their victory is shared. When one of the Lovers wins, the other also wins together. Lovers can see the 「♥」 next to each other's name. If one of the Lovers dies, the other will die in love (may not die in love according to the Host's settings). When one of the Lovers is exiled in the meeting, the other will die and become a dead body that cannot be reported.", @@ -981,7 +967,7 @@ "RebirthInfoLong": "(Add-ons):\nAs the Rebirth, if you're the player about to be ejected, you will swap skins with a random crewmate who voted for you.\nNotice: The host vote never counts\nRebirth will be removed from you if you exhausted all your rebirths.", "LoyalInfoLong": "(Add-ons):\nAs the Loyal, you cannot be recruited by roles such as Jackal or Cultist.\n\nCannot be assigned to neutrals.", "EvilSpiritInfoLong": "(Add-ons):\nAs Evil Spirit, it's your job to help the Spiritcaller to victory. You can use your Haunt button to freeze players and reduce their vision. Alternatively, you can use your Haunt button to give the Spiritcaller a shield against a kill attempt temporarily.", - "RecruitInfoLong": "(Betrayal Add-ons):\nAs a recruit, you are on the Jackal's team and help out the Jackal and their Sidekicks.\nYou cannot win with your original team.\nDepending on the settings, you may turn into Jackal if old Jackal was killed and no sidekicks is alive.", + "RecruitInfoLong": "(Betrayal Add-ons):\nAs a recruit, you are on the Jackal's team and help out the Jackal and their Sidekicks.\n\nYou cannot win with your original team.", "AdmiredInfoLong": "(Betrayal Add-ons):\nAs an admired player, you win with the crew and not your original team.\n\nYou can see the Admirer.", "GlowInfoLong": "(Add-ons):\nDuring lights out, you and players nearby you will receive a vision boost.", "RadarInfoLong": "(Add-ons):\nAs Radar, you have arrows pointing towards the closest person at all times.", @@ -1025,7 +1011,6 @@ "ProhibitedInfoLong": "(Add-ons):\nAs the Prohibited, you have specific vents that you can't use.\nHow many vents are disabled depends on the Host's settings.", "EavesdropperInfoLong": "(Add-ons):\nAs the Eavesdropper, you have a chance to read other role/addon information-based messages like Mortician or Sleuth.", "ApocalypseInfoLong": "(Apocalypse):\nApocalypse members are on a separate team that works together and wins together. If there are multiple Apocalypse roles in the game, they can see each other's roles.\nDepending on the Host's settings, Apocalypse roles can guess or be guessed.", - "RevenantInfoLong": "(Neutral):\nAs the Revenant, your goal is to be killed. If you are killed, you will take your killer's role and kill your killer instead. You cannot win before being killed.\nNote that Revenant only works when being directly killed.", "ShowTextOverlay": "Text Overlay", "Overlay.GuesserMode": "Guesser Mode", "Overlay.NoGameEnd": "No Game End", @@ -1039,8 +1024,6 @@ "AbilityUseLimit": "Initial Ability Use Limit", "AbilityInUse": "Ability in use", "AbilityExpired": "Ability expired, {0} uses remain", - "RevenantTargeted": "Your role has changed to {0}", - "RevenantCanCopyAddons": "Can Steal Addons", "ShowArrows": "Has Arrows pointing toward bodies", "ArrowDelayMin": "Minimum Arrow show-up delay", "ArrowDelayMax": "Maximum Arrow show-up delay", @@ -1370,8 +1353,6 @@ "ShieldedCanUseKillButton": "Shielded player can use ability / kill button", "PlayerIsShieldedByGame": "Player is protected by the game!", "LegacyNemesis": "Use Legacy Version", - "LegacyParasite": "Use Legacy Version", - "LegacyTraitor": "Use Legacy Version", "ArsonistKeepsGameGoing": "Arsonist keeps the game going", "ArsonistCanIgniteAnytime": "Can Ignite Anytime", "ArsonistMinPlayersToIgnite": "Minimum doused needed for ignite", @@ -1514,18 +1495,6 @@ "SheriffCanKillSeparately": "Individual Settings", "In%team%": "(Team %team%)", "SheriffMisfireKillsTarget": "Misfire Kills Target", - "BlackHolePlaceCooldown": "Black Hole Place Cooldown", - "BlackHoleDespawnMode": "Black Hole Despawn Mode", - "BlackHoleDespawnTime": "Time After Black Hole Despawns", - "Abyssbringer.Suffix": "<#00ffa5>Number of players consumed by {0} <#00ffa5>active black holes:\\n{1}", - "Abyssbringer.Suffix.BlackHole": "<#00ffa5>{0}: {1}", - "BlackHoleMovesTowardsNearestPlayer": "Black Hole Moves Towards Nearest Player", - "BlackHoleMoveSpeed": "Black Hole Moving Speed", - "BlackHoleRadius": "Black Hole Consuming Radius", - "AfterTime": "After Time", - "After1PlayerEaten": "After 1 Player Was Eaten", - "AfterMeeting": "After Meeting", - "None": "None", "SheriffShotLimit": "Max number of Kills", "SheriffCanKillAllAlive": "Can Kill When No One Is Dead", "SheriffCanKillCharmed": "Can kill Charmed players", @@ -1542,15 +1511,12 @@ "RebirthUses": "Amount of Rebirths", "RebirthCountVotes": "Only rebirth to players who voted for them", "RebirthFailed": "Ahh, how unfortunate, you did not find any viable souls to swap bodies with", - "FireworkerCooldown": "Placement Cooldown", "ReverieIncreaseKillCooldown": "Increase kill cooldown", "ReverieMaxKillCooldown": "Max kill cooldown", "ReverieMisfireSuicide": "Misfire on reaching max kill cooldown", "ReverieResetCooldownMeeting": "Reset kill cooldown after meeting", "ConvertedReverieKillAll": "Converted Reverie can kill anyone without repercussions", "VigilanteNotify": "You have become the very thing you swore to destroy", - "DictatorChangeCommandToExpel": "Dictator use Command to expell instad of vote", - "DictatorExpelSelf": "WAIT WAIT WAIT WAT THE HELLLLLL Bro really just want to expel himself", "DoctorTaskCompletedBatteryCharge": "Battery Duration", "SnitchEnableTargetArrow": "See Arrow Towards Target", "SnitchCanGetArrowColor": "See Colored Arrows based on Team Colors", @@ -1624,6 +1590,7 @@ "TimeThiefDecreaseMeetingTime": "Lower Meeting Time by", "TimeThiefLowerLimitVotingTime": "Minimum Voting Time", "TimeThiefReturnStolenTimeUponDeath": "Return Stolen Time Upon Death", + "TimeThiefMaxTimeOnAdmired": "Maximum Meeting Time if Time Thief Is Admired", "EvilTrackerCanSeeKillFlash": "Can See Kill-Flash", "EvilTrackerCanSeeLastRoomInMeeting": "Can See Target's Last Room In Meeting", "EvilTrackerTargetMode": "Can Set Target", @@ -1631,7 +1598,6 @@ "EvilTrackerTargetMode.OnceInGame": "Once in-game", "EvilTrackerTargetMode.EveryMeeting": "Every Meeting", "EvilTrackerTargetMode.Always": "Any time", - "ScavengerHasCustomDeathReason": "Enable Custom Death Reason", "EvilHackerCanSeeDeadMark": "Can See The Location of Dead-bodies", "EvilHackerCanSeeImpostorMark": "Can See The Location of Other Impostors", "EvilHackerCanSeeKillFlash": "Can See Kill-Flash", @@ -1864,21 +1830,13 @@ "Jackal_SidekickCountMode_Jackal": "Jackal", "Jackal_SidekickCountMode_Original": "Original Team", "Jackal_SidekickAssignMode": "Sidekick Assign Mode", - "Jackal_SidekickAssignMode_SidekickAndRecruit": "Sidekick when failed Recruit", - "Jackal_SidekickAssignMode_Sidekick": "Only Sidekick", - "Jackal_SidekickAssignMode_Recruit": "Only Recruit", + "Jackal_SidekickAssignMode_SidekickAndRecruit": "Sidekick+Recruit", + "Jackal_SidekickAssignMode_Sidekick": "Sidekick Only", + "Jackal_SidekickAssignMode_Recruit": "Recruit Only", + "JackalWinWithSidekick": "Jackal can win with Sidekick's team", "Jackal_SidekickCanKillSidekick": "Sidekicks can kill other Sidekicks", "Jackal_SidekickCanKillJackal": "Sidekick can kill Jackal", - "Jackal_RecruitFailed": "You can not recruit this player!", "JackalCanKillSidekick": "Jackal can kill Sidekick", - "Jackal_SidekickCanKillWhenJackalAlive": "Sidekick can kill while Jackal is Alive", - "Jackal_SidekickTurnIntoJackal": "Sidekick can turn into Jackal after its death", - "Jackal_RestoreLimitOnNewJackal": "Restore Recruit limit when Sidekick become new Jackal", - "Jackal_OnBecomeNewJackalMeeting": "The old Jackal {0} is dead.\nYou are selected as new Jackal\nWork together and win the game!", - "Jackal_OnNewJackalSelectedMeeting": "The old Jackal {0} is dead.\n{1} is selected as new Jackal!\nWork together and win the game!", - "Jackal_BecomeNewJackal": "Old Jackal Dead, You are now new Jackal!", - "Jackal_OnNewJackalSelected": "Old Jackal Dead, Please help new Jackal {0} for now!", - "Jackal_BossIsDead": "Opps, the Jackal boss is dead!", "CoronerArrowsPointingToDeadBody": "Arrows pointing to dead bodies", "CoronerLeaveDeadBodyUnreportable": "Bodies the Coroner uses can't be reported", "CoronerInformKillerBeingTracked": "Inform the Killer that he gets tracked", @@ -1916,9 +1874,6 @@ "VipTag": "VIP★", "ApplyVipList": "Apply VIP List", "AllowSayCommand": "Allow moderators to use /say command", - "AllowStartCommand": "Allow moderators to use /start command", - "StartCommandMinCountdown": "Minimum countdown for /start command", - "StartCommandMaxCountdown": "Maximum countdown for /start command", "KickCommandDisabled": "The kick command is currently disabled.", "KickCommandNoAccess": "You do not have access to the kick command.", "KickCommandInvalidID": "Invalid player ID specified.\nPlease use '/kick [playerID] [reason]' to kick a player.\nExample :- /kick 5 not following rules", @@ -1951,11 +1906,6 @@ "WarnCommandNoAccess": "You do not have access to the warn command.", "WarnCommandInvalidID": "Invalid player ID specified.\nPlease use '/warn [playerID] [reason]' to warn a player. \nExample :- /warn 5 lava chatting", "WarnCommandWarnHost": "You are not permitted to warn the host.", - "StartCommandNoAccess": "You do not have access to the start command.", - "StartCommandDisabled": "The start command is currently disabled.", - "StartCommandCountdown": "ERROR\n\nThe game is already starting!", - "StartCommandStarted": "The game has been started by {0}!", - "StartCommandInvalidCountdown": "ERROR\n\nThe countdown must be between {0} and {1}!", "WarnCommandWarnMod": "You are not permitted to warn other moderators.", "WarnCommandWarned": "has been warned. There will be no more warnings given and appropriate action will be taken \n ", "WarnExample": "Use /warn [id] [reason] in future. \nExample :-\n /warn 5 lava chatting", @@ -1983,7 +1933,6 @@ "DeathReason.Quantization": "Quantization", "DeathReason.Overtired": "Overtired", "DeathReason.Ashamed": "Ashamed", - "DeathReason.Consumed": "Consumed", "DeathReason.PissedOff": "Destroyed", "DeathReason.Dismembered": "Dismembered", "DeathReason.LossOfHead": "Strangled", @@ -2007,8 +1956,6 @@ "DeathReason.Starved": "Starved", "DeathReason.Equilibrium": "Equilibrium", "DeathReason.Sacrificed": "Sacrificed", - "DeathReason.Electrocuted": "Electrocuted", - "DeathReason.Scavenged": "Scavenged", "OnlyEnabledDeathReasons": "Only Enabled Death Reasons", "Alive": "Alive", "Disconnected": "Disconnected", @@ -2024,10 +1971,11 @@ "DeputyHandcuffCooldown": "Handcuff Cooldown", "DeputyHandcuffMax": "Maximum Handcuffs", "DeputyHandcuffedPlayer": "Handcuffed target", - "HandcuffedByDeputy": "You were handcuffed!", - "DeputyInvalidTarget": "Target cannot be handcuffed", + "HandcuffedByDeputy": "You were handcuffed!\nNow you have broken your handcuff and can kill again.", + "DeputyInvalidTarget": "Target is already handcuffed", + "HandcuffBrokenAfterMeeting": "Remove all handcuffs after meeting", "DeputyHandcuffText": "Handcuff", - "DeputyHandcuffCDForTarget": "Kill Cooldown for handcuffed player", + "DeputyHandcuffCDForTarget": "Next Kill Cooldown for handcuffed player", "RejectShapeshift.AbilityWasUsed": "Ability was used", "EscapisMtarkedPosition": "You marked self-position", "InvestigateCooldown": "Investigate Cooldown", @@ -2074,7 +2022,6 @@ "Command.dump": "→ Output Log to Desktop", "Command.death": "→ Display info on how you died", "Command.icons": "
╳ - The Player was marked by the Blackmailer and can't talk during the Meeting
☆ - Used by Captain to display themselves. Only Crewmates can see the Captain's star
乂 - This player was hexed by the Hex Master and will die if the Hex Master isn't killed or ejected by the end of the Meeting.
♦ - Used by Lawyer or Executioner or Follower.
♥ - Used by Lovers or Romantic.
✚ - Used by Medic to mark their target.
⦿ - This player is in a duel with the Pirate.
!? - This player was marked by the Quizmaster and must answer the question correctly to survive.
☜ - Used by Schrödinger's cat to mark their teammate.
◈ - This player marked by the Shroud and will die if the Shroud is not killed or ejected by the end of the meeting.
⚠ - This player is a Snitch or Solsticer who has finished their tasks.
★ - Used by Super Star or Cyber or Marshall.
† - This player was spelled and will die if the Witch is not killed by the end of the meeting.
∇ - Used by Kamikaze to mark their targets.
■ - Used by Lightning to mark their quantum ghosts.
⊠ - Used by Jailer to mark their prisoner.
● - Used by Baker to mark who has Bread.
♠ - Used by Soul Collector to mark who's death they're predicting.
⦿ - Used by Plaguebearer to mark who they have plagued.", - "Command.start": "[Seconds] → Start the game", "Command.iconinfo": "→ Display info on in-meeting icons", "Command.iconhelp": "→ Display info on in-meeting icons to everyone", "Command.Poll": "→ Start a poll with up-to 5 choices", @@ -2087,7 +2034,6 @@ "ShowMadmatesInLeftCommand": "Show Madmates (including add-ons)", "ShowApocalypseInLeftCommand": "Show Neutral Apocalypse", "SeeEjectedRolesInMeeting": "See ejected roles in meetings", - "ThankYouForUsingTOHE": "Thank you for using TOHE!", "SkillUsedLeft": "You have activated your skill to call a meeting. \nRemaining amount of uses left:", "NemesisDeadMsg": "The death of the Nemesis means the beginning of the revenge. \nPlease use /rv + [player ID] to kill the specified player \nYou can see player IDs in front of their names. \nOr type /rv to get a list of player IDs", "NemesisAliveKill": "Revenge for the Nemesis can only begin after their death.", @@ -2107,7 +2053,6 @@ "GuessNotifiedBait": "Bait can't be guessed because it was announced. You thought it would be that easy, right?", "GuessGM": "Guessing the GM is impossible because they're already dead.... And why would you do that to the poor Host?", "GuessGuardianTask": "You can't guess a Guardian who has finished their tasks.", - "GuardianCantKilled": "You can't kill a Guardian who has finished their tasks.", "GuessMarshallTask": "You can't guess a Marshall who has finished their tasks.", "GuessObviousAddon": "Sorry, obvious add-ons cannot be guessed.", "GuessAdtRole": "Unfortunately, the Host's settings do not allow you to guess add-ons", @@ -2163,7 +2108,6 @@ "BecomeMadmateCuzMadmateMode": "You became a Madmate because you died", "CleanerCleanBody": "The body has been cleaned", "QuickShooterStoraging": "Bullets stored successfully", - "QuickShooterFailed": "You are still in cooldown.", "PoisonerTargetDead": "Target died", "HexesLookLikeSpells": "Hexes appear as spells", "HexButtonText": "Hex", @@ -2322,7 +2266,6 @@ "Message.YTPlanNotice": "Note: The [YouTuber Plan] is enabled in this lobby, which means the Host can specify their role in the next game to make it easier to get content. If the Host abuses this feature, please exit the game or report it.\nCurrent Creator Credentials:", "Message.OnlyCanBeUsedByHost": "ERROR\n\nThis command may only be used by the host.", "Message.MaxPlayers": "Maximum players set to ", - "Message.MaxPlayersFailByRegion": "Could not set max players: Vanilla regions support a maximum of 15 players.", "Message.GhostRoleInfo": "Ghost Role Info\nHiya! A little about ghost roles...\n\nGhost roles drastically impact the game, so it's not recommended for smaller lobbies if you're unfamiliar. If not explicitly stated otherwise in the description, the Guard button is their ability button ;)\n\nSpawning:\nGhost-roles only spawn after death; the first x people from (team) to die get them.\n\nPS: If your previous role didn't have tasks(e.g., sheriff), your tasks as a ghost-role aren't needed for task-win", "ApocalypseInfoTitle": "Neutral Apocalypse Info:", "Message.ApocalypseInfo": "Every role of the <#ff174f>Apocalypse Team has their own objective to carry out in order to transform.\n<#2B0804>Transformed <#ff174f>Apocalypse members have a drastic change on the game and are immortal (except for being voted), but everyone will be notified that they have transformed.\n\nRoles: <#e5f6b4>Plaguebearer, <#A675A1>Soul Collector, <#bf9f7a>Baker, <#cc0044>Berserker\nTransformed: <#343136>Pestilence, <#644661>Death, <#83461c>Famine, <#2B0804>War\n\nApocalypse members can see eachother's roles and ability icons.\nLike Neutral Killers, Apocalypse members keep the game going as well, have fun!", @@ -2454,6 +2397,7 @@ "LastResult": "★ Match Results", "LastEndReason": "★ End Reason", "KillLog": "Kill Log", + "MainRoleLog": "Role Convert Log", "Maximum": "Max", "RoleRate": "ON", "RoleOn": "ALWAYS", @@ -2730,9 +2674,8 @@ "DeathMeetingTimeIncrease": "Increased Meeting time when Death exists", "SoulCollectorMeetingDeath": "Your target has died during the meeting. You have gained a soul.", "SoulCollectorKillButtonText": "Predict", - "SoulCollectorHasImpostorVision": "Soul Collector has Impostor vision", "ApocalypseIsNigh": "[ The Apocalypse Is Nigh! ]", - "ApocalypseImmune": "This role is immune!", + "ApocalypseImmune": "This player is immune because they are invincible!", "BakerToFamine": "You have become Famine!!!", "BakerTransform": "The Baker has transformed into Famine, Horseman of the Apocalypse! A famine has begun!", "BakerAlreadyBreaded": "That player already has bread!", @@ -2741,15 +2684,13 @@ "BakerBreadNeededToTransform": "Required number of bread to become Famine", "BakerCantBreadApoc": "You cannot give other Apocalypse members bread!", "BakerKillButtonText": "Bread", - "BakerUnshiftButtonText": "Switch Bread", "BakerRevealBread": "Reveal", "BakerRoleblockBread": "Roleblock", "BakerBarrierBread": "Barrier", "BakerCurrentBread": "Current Bread: ", "BakerSwitchBread": "Bread Switched to: ", - "BakerCanVent": "Baker can Vent", + "BakerCanVent": "Baker can Vent", "BakerBreadGivesEffects": "Bread gives additional effects", - "BakerTransformNoMoreBread": "Baker transforms if they do not have enough bread", "FamineKillButtonText": "Starve", "FamineStarveCooldown": "Famine starve cooldown", "FamineCantStarveApoc": "You cannot starve other Apocalypse members!", @@ -2796,7 +2737,6 @@ "GodfatherTargetCountMode": "Killer turns into", "GodfatherCount_Refugee": "Refugee", "GodfatherCount_Madmate": "Madmate", - "GodfatherRefugeeMsg": "You have been recruited by GodFather!", "MissChance": "Chance To Miss", "IncreaseByOneIfConvert": "Increase The KillCount +1 If a Crew Is Converted", "HawkMissed": "Missed!", @@ -2829,7 +2769,6 @@ "BerserkerToWar": "You have become War!!!", "BerserkerTransform": "The Berserker has transformed into War, Horseman of the Apocalypse! Cry 'Havoc!', and let slip the dogs of war.", "WarKillCooldown": "War kill cooldown", - "BerserkerCanKillTeamate": "Can kill other Neutral Apocalypse", "BlackmailerSkillCooldown": "Blackmail Cooldown", "BlackmailerMax": "Maximum times blackmailed players may speak", "BlackmailerDead": "Warning! {0} has been blackmailed by a Blackmailer!", @@ -2919,8 +2858,6 @@ "RememberedPursuer": "You remembered you were a Pursuer!", "RememberedFollower": "You remembered you were a Follower!", "RememberedAmnesiac": "You failed to remember your role.", - "AmnesiacRemembered": "You remembered you were {0}!", - "ReportWhenFailedRemember": "Report Dead Body when failed to remember", "RememberedImitator": "You remembered you were an Imitator.", "RememberedImpostor": "You remembered you were an Impostor!", "RememberedCrewmate": "You remembered you were a crewmate!", @@ -3146,7 +3083,7 @@ "DollMaster_PossessedTarget": "Possessed target", "DollMaster_CannotPossessImpTeammate": "Unable to possess teammate", "DollMaster_CouldNotSwapWithTarget": "Unable to possess player", - "DollMaster_CanNotSwapWithDeadTarget": "Possesing a dead player isn't possible", + "DollMaster_CanNotSwapWithDeadTarget": "Possessing a dead player isn't possible", "DollMaster_MainBody": "Main Body", "DollMaster_Doll": "Doll", "DollMaster_UnableToUseAbility": "Unable to use your ability on player", @@ -3334,12 +3271,9 @@ "PixieTargetAlreadySelected": "Target is already selected", "PixieButtonText": "Mark", "PlagueBearerCooldown": "Plague cooldown", - "PlagueBearerCanVent": "Can vent", - "PlagueBearerHasImpostorVision": "Has Impostor vision", "PestilenceCooldown": "Pestilence Kill cooldown", "PestilenceCanVent": "Pestilence Can Vent", "PestilenceHasImpostorVision": "Pestilence Has Impostor Vision", - "PestilenceKillGuessers": "Kill players who guess Pestilence", "PlagueBearerAlreadyPlagued": "Player has already been plagued", "PlagueBearerToPestilence": "You have turned into Pestilence!!", "GuessPestilence": "You just tried to guess Pestilence!\n\nSorry, Pestilence killed you.", @@ -3383,7 +3317,6 @@ "EveryoneCanKnowMini": "Everyone can see the Mini", "CanBeEvil": "Mini can be an Impostor", "EvilMiniSpawnChances": "Probability of Mini being an Impostor", - "EvilMiniCanBeGuessed": "Evil Mini can be guessed before 18", "GuessMini": "Sorry, you can't hurt a kid Mini.", "GrowUpDuration": "Time required to grow (s)", "MajorCooldown": "Kill Cooldown when over 18", @@ -3525,7 +3458,6 @@ "WinnerRoleText.Doppelganger": "Doppelganger Wins!", "WinnerRoleText.Quizmaster": "Quizmaster Wins!", "WinnerRoleText.Agitater": "Agitator Wins!", - "WinnerRoleText.Shocker": "Shocker Wins!", "AdditionalWinnerRoleText.Sidekick": "Sidekick", "AdditionalWinnerRoleText.Taskinator": "Taskinator", "AdditionalWinnerRoleText.Opportunist": "Opportunist", @@ -3611,7 +3543,7 @@ "SolsticerOnMeeting": "You witnessed too many deaths! Next round you will have {0} more short task!", "SolsticerTitle": "Solsticer", "GuessSolsticer": "Sorry, but you can not guess Solsticer!", - "ExpelSolsticer": "Sorry, but you can not expel Solsticer!", + "VoteSolsticer": "Sorry, but you can not vote Solsticer!", "SolsticerTasksReset": "Your tasks get reset!", "SolsticerMisGuessed": "You just misguessed! You are no longer allowed to guess.", "SolsticerGuessMax": "Because you already misguessed, you are no longer allowed to guess.", @@ -3712,19 +3644,6 @@ "MinionAbilityTime": "Ability Duration", "Minion_Blind": "blinded", "Evader_ChanceNotExiled": "Chance not be exiled", - "ShockerAbilityCooldown": "Ability Cooldown", - "ShockerAbilityDuration": "Ability Duration", - "ShockerAbilityPerRound": "Abilities Per Round", - "ShockerShockInVents": "Shock people in vents", - "ShockerAbilityResetAfterMeeting": "Reset marked rooms after meeting", - "ShockerOutsideRadius": "Radius Of Outside Tasks (not in a room)", - "ShockerCanShockHimself": "Can Shock Himself", - "ShockerImpostorVision": "Shocker has Impostor vision", - "ShockerIsShocking": "You're already shocking!", - "ShockerAbilityActivate": "Begin Shocking!", - "ShockerAbilityDeactivate": "Ability Deactivated", - "ShockerVentButtonText": "Shock", - "ShockerRoomMarked": "Marked Room", "EavesdropperMsgTitle": "You found a secret", "EavesdropPercentChance": "Chance to eavesdrop", "ChiefOfPoliceSkillCooldown": "Cooldown for recruiting sheriffs", @@ -3736,4 +3655,4 @@ "PolicPreventRecruitNonKiller": "Prevent recruit players without kill button", "PolicSuidiceWhenTargetNotKiller": "Suidices when recruit a non killer or non crewmate", "PolicPassConverted": "Can pass Converted Addon to Sheriff" -} +} \ No newline at end of file diff --git a/Resources/Lang/ru_RU.json b/Resources/Lang/ru_RU.json index e4f34749d..4bcb24cc8 100644 --- a/Resources/Lang/ru_RU.json +++ b/Resources/Lang/ru_RU.json @@ -20,8 +20,6 @@ "SubText.Neutral": "Играйте в одиночку, чтобы добиться своей цели", "SubText.Apocalypse": "Станьте непобедимым вместе со своей командой", "SubText.Madmate": "Помогите своим Предателям", - "SubText.Lovers": "Stay alive and win together", - "SubText.Egoist": "Win on your own", "TypeImpostor": "Предатели", "TypeCrewmate": "Члены Экипажа", "TypeNeutral": "Нейтралы", @@ -31,9 +29,6 @@ "TeamNeutral": "Нейтрал", "TeamCrewmate": "Член Экипажа", "TeamMadmate": "Безумец", - "TeamLovers": "Lovers", - "TeamEgoist": "Egoist", - "TeamApocalypse": "Apocalypse", "YouAreCrewmate": "Ты - Член Экипажа", "YouAreImpostor": "Ты - Предатель", "YouAreNeutral": "Ты - Нейтрал", @@ -225,7 +220,6 @@ "TaskManager": "Мастер Задач", "Witness": "Свидетель", "Swapper": "Обменник", - "ChiefOfPolice": "Chief of Police", "NiceMini": "Добрый Мини", "Mini": "Мини", "Spy": "Шпион", @@ -254,7 +248,6 @@ "Stalker": "Сталкер", "Workaholic": "Трудоголик", "Solsticer": "Солнечный", - "Abyssbringer": "Abyssbringer", "Collector": "Коллектор", "Provocateur": "Провокатор", "BloodKnight": "Кровный Рыцарь", @@ -393,8 +386,6 @@ "Sloth": "Ленивец", "Prohibited": "Ограниченный", "Eavesdropper": "Подслушиватель", - "Shocker": "Shocker", - "Revenant": "Revenant", "BracketAddons": "Добавить скобки к Атрибутам", "EngineerTOHEInfo": "Используйте вентиляцию, чтобы поймать Предателей", "ScientistTOHEInfo": "У вас есть доступ к портативным пульсам", @@ -513,7 +504,7 @@ "PacifistInfo": "Используйте вентиляцию, чтобы сбросить откаты убийства", "RebirthInfo": "Восстань снова", "MonarchInfo": "Дайте игрокам дополнительные голоса!", - "AbyssbringerInfo": "Place Black Holes", + "AbyssbringerInfo": "Create Black Holes", "SpurtInfo": "Ваша скорость меняется!", "StealthInfo": "Ваше убийство ослепляет всех в комнате", "PenguinInfo": "Перетаскивайте своих жертв", @@ -538,7 +529,7 @@ "AdmirerInfo": "Выбери игрока, который будет на твоей стороне", "TimeMasterInfo": "Время вспять!", "CrusaderInfo": "Убей нападающего", - "AltruistInfo": "Оживляйте игроков", + "AltruistInfo": "Revive a player\nVent to change between Revive and Report", "ReverieInfo": "С каждым убийством, откат уменьшается", "LookoutInfo": "Видеть сквозь маскировки", "TelecommunicationInfo": "Отслеживайте использование устройств", @@ -547,7 +538,6 @@ "WitnessInfo": "Узнайте, убивал ли кто-то в недавно", "GhastlyInfo": "Поиграй с ними!", "SwapperInfo": "Обменяй голоса игроков", - "ChiefOfPoliceInfo": "Hire Sheriff to Serve the Crews!", "NiceMiniInfo": "Никто не причинит тебе вред, пока ты не вырастешь.", "ArsonistInfo": "Облейте всех и подожгите", "PyromaniacInfo": "Облейте всех игроков", @@ -603,7 +593,7 @@ "VultureInfo": "Ешьте тела, чтобы победить", "TaskinatorInfo": "Закладывайте бомбы в заданиях", "BenefactorInfo": "Задача выполнена, выдаётся щит!", - "MedusaInfo": "Трупы становятся камнями при вашем репорте", + "MedusaInfo": "Stone bodies by reporting them", "SpiritcallerInfo": "Превращайте игроков в Злых Духов", "AmnesiacInfo": "Вспомни роль трупа", "ImitatorInfo": "Имитируйте роли игроков", @@ -615,19 +605,19 @@ "ShroudInfo": "Накройте игроков, чтобы заставить их убивать", "WerewolfInfo": "Растерзайте всех игроков во тьме", "ShamanInfo": "Отразите все атаки на куклу Вуду", - "SeekerInfo": "Играйте в прятки со своей целью", + "SeekerInfo": "Play Hide and Seek with your target\nYour target has a ★ mark.", "PixieInfo": "Пометь, упакуй и выбрось!", "OccultistInfo": "Убивайте и проклинайте своих врагов", "SchrodingersCatInfo": "Дайте попытку убить себя и присоединитесь к команде", "RomanticInfo": "Защитите своего партнера, чтобы победить вместе", "VengefulRomanticInfo": "Отомстите за своего партнера, чтобы победить вместе", "RuthlessRomanticInfo": "Убивайте всех, чтобы выиграть с вашим партнером", - "PoisonerInfo": "Ваши убийства задерживаются", + "PoisonerInfo": "Kill everyone with delayed kills", "HexMasterInfo": "Ставь порчу, чтобы убивать в собраниях", "WraithInfo": "Прыгните в вентиляцию, чтобы стать невидимым", - "JinxInfo": "Отражайте атаки", + "JinxInfo": "Reflect attacks onto your attackers", "PotionMasterInfo": "Убивайте и раскрывайте роли своих врагов", - "NecromancerInfo": "Убей своего убийцу, чтобы бросить ему вызов", + "NecromancerInfo": "Kill your killer to defy death", "WardenInfo": "(Призрак) Оповещение об опасности", "MinionInfo": "(Призрак) Ослепить врагов", "LoversInfo": "Выживите со своим Любовником", @@ -708,8 +698,6 @@ "SlothInfo": "Вы очень медленный", "ProhibitedInfo": "Некоторые вентиляции заблокированы", "EavesdropperInfo": "Слушайте другие роли", - "ShockerInfo": "Shock unsuspecting players", - "RevenantInfo": "Take your killer's role", "EngineerTOHEInfoLong": "(Член Экипажа):\nИнженер может вентоваться, пока «Саботаж связи» неактивен.", "ScientistTOHEInfoLong": "(Член Экипажа):\nУчёный может в любое время использовать пульсы, которые покажут ему, кто жив, а кто мёртв.", "NoisemakerTOHEInfoLong": "(Член Экипажа):\nВсякий раз когда Паникёр умирает, он издает шум, и на экране появляется визуальный индикатор его смерти который указывает его местоположение, чтобы Члены Экипажа могли найти его труп.", @@ -781,11 +769,11 @@ "LurkerInfoLong": "(Предатель):\nСкрытень может прыгнуть в вентиляцию, чтобы сократить откат убийства на определенное количество секунд. После того как он убьёт, откат сбрасывается до исходного значения.", "VisionaryInfoLong": "(Предатель):\nВизионер видит мировоззрение живых игроков во время встречи.\nНа игроке будет отображаться следующая информация.:\n– Красное имя указывает на Предателей.\n– Голубое имя указывает на Членов Экипажа.\n– Имя Серых указывает на Нейтралов.", "PlagueDoctorInfoLong": "(Злой Нейтрал):\nЦель Чумного Доктора — заразить каждого живого игрока.\nОн начинает с выбора одного игрока для заражения, после чего любой, кто проводит определенное количество времени в радиусе действия зараженного игрока, он заражается вместе с ним.\nПрогресс заражения суммируется и не сбрасывается при изгнии или после встречи.", - "RefugeeInfoLong": "(Madmates):\nAs the Refugee, you were either:\n -An Amnesiac who remembered an Impostor\n -A killer who killed the Godfather's target.\n -A Romantic whose partner was an Impostor\n -Or an Imitator that imitated an Impostor.\n\nNow your job is to help the Impostors kill the crewmates.", + "RefugeeInfoLong": "(Безумец):\nБеженец был Амнезияком который, вспомнил роль Предателя.\n\nПомогите Предателям убить Членов Экипажа.", "UnderdogInfoLong": "(Предатель):\nКак Аутсайдер, ты не можешь убивать пока определённое количество игроков живо.", "ConsigliereInfoLong": "(Предатель):\nСоветник может раскрыть роль других игроков с помощью кнопки убийства.\n\nОдин щелчок: раскрыть роль игрока\nДвойной щелчок: убить игрока\n\nЕсли количество раскрытий закончится, то кнопка убийства будет работать как обычно.", "LudopathInfoLong": "(Предатель):\nУ Людопата случайный откат убийства.\n\nМинимальное значение может составлять 1 секунду, а максимальное - это откат убийства установленный по умолчанию.", - "GodfatherInfoLong": "(Impostors):\nAs the Godfather, you vote someone to make them your target.\nIn the next round, if someone kills the target, the killer will turn into a Refugee or Madmate.", + "GodfatherInfoLong": "(Предатель):\nКогда Крестный голосует за кого-то, он делает игрока своей целью.\nВ следующем раунде, если кто-то убьет его цель, убийца превратится в Беженца.", "ChronomancerInfoLong": "(Предатель):\nКак Хрономант, ты имеешь индикатор заряда, который показывает, когда режим ярости будет готов. При 100% заряде, после убийства, ярость будет включена - ты можешь убивать без отката пока заряд не закончится. В другом случае, у тебя нормальный откат убийства.", "PitfallInfoLong": "(Предатели):\nЛовушка, может использовать Морф, чтобы пометить область вокруг него как ловушку.\nИгроки, попавшие в эту зону, будут обездвижены на короткий период времени, а их зрение будет нарушено.", "EvilMiniInfoLong": "(Предатель):\nЗлой Мини не убиваем, пока не вырастет и у него очень долгий начальный откат убийства, которое сокращается по мере взросления.", @@ -821,7 +809,7 @@ "GrenadierInfoLong": "(Член Экипажа):\nГренадёр может ослепить игроков светошумовой гранатой поблизости, заставляя их терять зрение, если игрок Предатель или Нейтрал, в зависимости от настроек.", "MedicInfoLong": "(Член Экипажа):\nМедик может наложить на цель щит, нажав кнопку ''Убить''. Медик может дать только один щит на всю игру, когда Медик умрёт то щит у цели будет снят. Так же Медик может видеть что кто-то пытается сломать щит у цели.\nВ зависимости от настроек хоста Медик или цель могут видеть, есть ли у игрока щит (показан зелёным кружком рядом с именем).", "FortuneTellerInfoLong": "(Член Экипажа):\nСледователь может проголосовать за игрока на встрече, чтобы узнать его роль.\nПодсказка будет связана с его фактической ролью.\n\nКогда он выполнит все задания, он получит точную роль, а не подсказку!\n\nПримечание: Если включена настройка «Показывать случайные активные роли в подсказках», он не сможете проверять одного и того же игрока несколько раз.", - "JudgeInfoLong": "(Член Экипажа):\nСудья может судить определенного игрока во время встречи. Если цель - плохая роль, он будет убит, а если нет, судья покончит с собой.\nПробная команда: '/tl [Номер игрока]' \nВы можете увидеть номер игрока перед именем игрока или использовать команду /id для просмотра номеров всех игроков. Когда судья - Безумец, он может судить любого, кто захочет.", + "JudgeInfoLong": "(Crewmates):\nThe Judge can judge a certain player during the meeting. If the target is evil, the target will be killed (whether it is evil or not is set by the Host). If it is wrong, the Judge commits suicide.\nCommand for judgment: /tl [player id]\nYou can see the player's id before the player's name, or use the /id command to view the id of all players.\nJudges can judge all players when they become Madmate.\nIn meeting the ability count shows how many trails you have in this meeting. Out of meeting the ability counts shows how many trails you have for the whole game.", "MorticianInfoLong": "(Член Экипажа):\nГробовщик в зависимости от настройки, может видеть стрелки, указывающие на все трупы, и если Гробовщик зарепортит труп, он узнает последнего игрока, с которым жертва контактировала.", "MediumInfoLong": "(Член Экипажа):\nМедиум может установить контакт с мертвым игроком, зарепортив его труп. Он может один раз ответить Да или НЕТ на вопрос Медиума, ответ на вопрос увидит только Медиум. \n(Мертвый игрок может использовать /ms Yes или /ms No). Примечание: Медиум не будет Забывчивым.", "ObserverInfoLong": "(Член Экипажа):\nАудитор может видеть все анимации щита, вызванную другими игроками после первой встречи. Обычно это указывает на использование какой-либо ролевой способности, поэтому обращайте на это внимание.", @@ -833,7 +821,7 @@ "MerchantInfoLong": "(Член Экипажа):\nТорговец продаёт случайный атрибут случайному игроку за каждое выполненное его задание. Каждый проданный атрибут приносит вам деньги.\nЕсли у вас есть определенная сумма денег, вы можете предотвратить следующую попытку убийства против вас, подкупив убийцу. Подкупленный игрок не сможет вас убить, но вы не знаете, кто это. Использованные деньги потеряны и не доступны для дополнительных взяток.", "RetributionistInfoLong": "(Член Экипажа):\nВозмездник может убить определённое количество игроков после своей смерти.\n\nИспользуйте '/ret [номер игрока]' чтобы убить цель.", "HawkInfoLong": "(Член Экипажа [Призрак]):\nЯстреб может убить определённое количество игроков, но есть шанс, что он промахнётся\nНо если промахнуться несколько раз по одному и тому же игроку, шансы убить цель увеличиваются.", - "DeputyInfoLong": "(Член Экипажа):\nЗаместитель при использовании кнопки убийства на игроке, может сбросить откат убийства.\n\nЕсли у цели нет кнопки убийства, то наручники были пустой тратой времени.", + "DeputyInfoLong": "(Crewmates):\nAs the Deputy, use your kill button to handcuff a player.\nThe player who is handcuffed will have their next kill attempt treated as a handcuff break, and the kill cooldown will be reset.\n\nIf the target does not have a kill button, then the handcuff was a waste.", "InvestigatorInfoLong": "(Член Экипажа):\nИсследователь может использовать кнопку убийства, чтобы расследовать кого-либо.\nКогда он исследует кого-то, его имя будет отображаться либо красным, если у него есть кнопка убийства, либо голубым, если у него нет кнопки убийства. \nОднако обратите внимание, что цвет имен вернется к обычному цвету при созыве собрания.", "GuardianInfoLong": "(Член Экипажа):\nСтраж становится бессмертным после выполнения всех заданий. На встречах его нельзя будет угадать.", "AddictInfoLong": "(Член Экипажа):\nУ Зависимого есть таймер до самоубийства. Когда он истечет, он убьет себя.\nТаймер показывает откат вентиляции. Когда откат вентиляции составит 0 секунд, у него все еще будет короткое время для запрыгивания в вентиляцию.\nЕсли он не успеет прыгнуть в вентиляцию.\nПосле того как он вентанётся, никто не сможет взаимодействовать с ним в течение определенного периода времени.\nПо истечении этого периода вы обездвижены на другой определенный период времени и не можете зарепортить какой либо труп.", @@ -849,7 +837,7 @@ "AdmirerInfoLong": "(Член Экипажа):\nКак Поклонник, вы восхищайте игрока, чтобы объединить его в команду Членов Экипажа.\nЭтот игрок победит с Членами Экипажа, а не со своей первоначальной командой.\n\nВы можете сделать это только один раз.", "TimeMasterInfoLong": "(Член Экипажа)\nПовелитель Времени использует вентиляцию, чтобы отметить текущее положение каждого игрока.\nПри повторном использовании способности каждый живой игрок будет телепортирован на отмеченные позиции.\n\nВо время действия способности Повелитель Времени получает временный щит, защищающий его от смерти.", "CrusaderInfoLong": "(Член Экипажа):\nКак Крестоносец, используйте кнопку 'Убить' чтобы защитить игрока.\nЕсли этот игрок был атакован, вы убьете атакующего.", - "AltruistInfoLong": "(Член Экипажа):\nБудучи Альтруистом, вы можете пожертвовать собой ради оживления мертвого игрока, нажав кнопку «Сообщить»\nПримечание. Если мертвый игрок покинул игру, вы сообщаете об этом трупе как обычно.\nТакже возрожденный игрок не может сообщить о своем трупе", + "AltruistInfoLong": "(Crewmates):\nAs the Altruist, you can sacrifice yourself to revive a dead body using the «Report» button.\nNote: If a dead player has left the game, you report that body normally.\nAlso revived player cannot report self dead body\nUse vent button to change between Report & Revive.", "ReverieInfoLong": "(Член Экипажа):\nКак Мечтатель, ваш откат убийства очень большой.\n\nОткат уменьшается с каждым убийством.\n\nВы побеждаете с Членами Экипажа.", "LookoutInfoLong": "(Член Экипажа):\nДозорный может видеть идентификаторы каждого игрока в любое время.\nЭто позволяет вам видеть идентификатор игра даже в морфлинге и при камуфляже.", "TelecommunicationInfoLong": "(Член Экипажа):\nКоммуникатор получает уведомления, когда кто-либо пользуется:\nКамерами, Пульсам, Журналами или Админкой.", @@ -872,7 +860,7 @@ "LawyerInfoLong": "(Злой - Нейтрал):\nУ Адвоката есть цель для защиты, которая будет отмечена ромбом 「♦」 рядом с его никнеймом.\nЕсли ваша цель выиграет, он тоже победит.\nЕсли цель проиграет, то Адвокат соответственно тоже проиграет.", "OpportunistInfoLong": "(Добрый - Нейтрал):\nВыживший выигрывает игру вместе с любыми другими ролями, но только если он выжил.", "VectorInfoLong": "(Злой - Нейтрал):\nЕсли Вектор прыгнет в вентиляцию определенное количество раз, то победит в одиночку.", - "JackalInfoLong": "(Neutrals):\nAs the Jackal, you win if you are the last player alive. Additionally, you may recruit using the kill button. If the target is not one you can recruit, you have run out of uses, or you don't have the option to recruit, then you will kill people normally (i.e., don't use kill buttons in front of others thinking it'll recruit). If the target has a kill button and the option to turn into a Sidekick is on, they will become a Sidekick. Otherwise, they will gain the Recruit add-on if the option to give the Recruit add-on is on.\nDepending on the settings, when Jackal was killed, a Sidekick will be randomly selected as the new Jackal.\nRecruit may be selected if no sidekick is alive.", + "JackalInfoLong": "(Нейтрал):\nШакал побеждаем в том случае, если остаётся последним в живых. Также, вы можете завербовывать, используя кнопку убийства. Если вы не можете завербовать цель, у вас кончились использования или эта возможность недоступна, тогда вы просто убьёте (не используйте кнопку убийства перед всеми, думая, что вы завербуете вашу цель). Если у вашей цели есть кнопка убийства и возможность появления Помощников включена, то цель станет Помощником. В другом случае они получат атрибут \"Завербованный\", если этот атрибут включен.", "GodInfoLong": "(Нейтрал):\nБог знает роль каждого игрока в начале игры. Если он доживет до конца игры, он победит.", "InnocentInfoLong": "(Злой - Нейтрал):\nОбвинитель может использовать кнопку ''Убить'', чтобы пометить любого игрока.\nПомеченная цель немедленно убьёт Обвинителя.\nЕсли помеченная цель будет изгнана во время встречи, то Обвинитель одержит победу.\nПримечание: Шут, Палач и Обвинитель могут победить вместе.", "PelicanInfoLong": "(Нейтрал):\nПеликан может использовать кнопку убийства, чтобы съесть живого игрока, телепортируя его за пределы карты, но при этом не убивая. Те, кого вы съели, будут убиты только в том случае, если вы остались в живых в конце раунда. Если вы были убиты или вышли из игры во время раунда, все живые съеденные игроки будут заспавнены в том месте, где сейчас стоите вы.", @@ -884,14 +872,14 @@ "SolsticerInfoLong": "(Злой Нейтрал):\nСолнечный не умрет и выиграет, выполнив все свои задания за один раунд. После завершения каждой встречи его задачи сбрасываются, и ему нужно начинать все заново.\nГолос по Солнечному будет напрямую отменено.\nПри попытки убить Солнечного игрока телепортируют его за пределы карты, как Пеликана, до тех пор, пока встреча не завершится.\nОткат убийства у убийцы будет сброшено до 10 секунд.\nСолнечный не считается никем.", "CollectorInfoLong": "(Злой Нейтрал):\nКогда Коллектор голосует за игрока, и если у этого игрока есть другие голоса то он получает очки (количество зависит от количества голосов).\nКогда он наберет необходимое количество голосов, игра закончится, и он выиграет, даже если он проголосовал за Шута или Палача.", "GlitchInfoLong": "(Злой Нейтрал):\nГлич может взламывать игроков (одиним нажатием на кнопку убийства) или убивать обычным способом (двойным нажатием на кнопку убийства).\nТе, кого взломали, не могут убивать, вентоваться или репортить трупы в течение периода взлома.\nКроме того, вызов саботажа замаскирует Глича под случайного игрока.\nЧтобы победить, станьте последним выжившим игроком.", - "SidekickInfoLong": "(Neutrals):\nAs the Sidekick, your job is to help the Jackal kill everyone.\nYou and the Jackal win together.\nDepending on the settings, you may turn into Jackal if old Jackal was killed.\nYou may not be able to kill until old Jackal is dead.", + "SidekickInfoLong": "(Злой - Нейтрал):\nСоюзник должен — помочь Шакалу.\n\nСоюзник и Шакал победят вместе, но они также могут достичь своего обычного условия победы.", "ProvocateurInfoLong": "(Злой - Нейтрал)\nПровокатор может использовать кнопку убийства, чтобы погибнуть вместе с любой целью. Если цель проиграет в конце игры, Провокатор выиграет вместе с командой-победителем.", "BloodKnightInfoLong": "(Злой - Нейтрал):\nКровный Рыцарь побеждает, когда он остается последним живым убийцей, а количество Членов Экипажа меньше или равно количеству Кровных Рыцарей.\nПосле каждого своего убийства он получает временный щит, который делает его бессмертным от прямых атак на несколько секунд.", "PlagueBearerInfoLong": "(Апокалипсис):\nЗаразите всех, чтобы превратиться в Чуму.\nКак только вы превратитесь в Чуму, вы станете бессмертным и получите способность убивать.\nВы убьете любого, кто попытается убить вас.\n\nКроме того, когда зараженные игроки взаимодействуют с незараженными игроками, они также будут заражены.", "PestilenceInfoLong": "(Апокалипсис):\nВ роли Чумы вы не остановимая машина.\nЛюбая атака в ваш адрес будет отражена в их сторону.\nКосвенные убийства даже не убивают вас.\n\nЕдинственный способ убить Чуму — проголосовать за нее или при ошибке угадывания.\nПосле трансформации ваше присутствие будет объявлено всем на собрании.", "SoulCollectorInfoLong": "(Апокалипсис):\nКак Коллектор Душ, вы можете использовать кнопку убийства на игроке, чтобы предсказать его смерть. Вы получите душу, если ваша цель умрет в выбранном вами раунде или во время следующей встречи.\nВаша цель сбрасывается после каждой встречи или после ее смерти, в зависимости от того, что наступит раньше. \n\nКак только вы соберете заданное количество душ, вы станете Смертью.\nЕсли включена настройка получения пассивных душ, вы будете получать по одной душе при каждой встрече.", "DeathInfoLong": "(Апокалипсис):\nКак только Коллектор Душ соберет необходимые души, они становятся Смертью.\nСмерти нужно убить всех и победить, если Смерть не будет изгнана к концу следующей встречи.\nНа встрече будет предоставлено настраиваемое количество дополнительного времени, чтобы провести больше обсуждений по поиску Смерти.\n\nВы непобедимы, и после трансформации ваше присутствие будет объявлено всем на собрании.", - "BakerInfoLong": "(Апокалипсис):\nИграя за Пекаря, вы можете использовать кнопку убийства на игроке за раунд, чтобы дать ему хлеб. \nКак только определенное количество игроков заработает хлебом, вы станете Голодом.\n\nЕсли Хлеб дает дополнительные эффекты и настройка включена, то вы можете изменить хлеб, который вам раздают. \nЭффекты хлеба:\nРаскрытие: раскрывает роль для Пекаря (остается на протяжении всей игры).\nРолевой блок: устанавливает откат убийства цели на 999 (сбрасывается до нормального значения после встречи).\nБарьер: дает цели барьер, известный только Пекарю (барьер удаляется после встречи)", + "BakerInfoLong": "(Apocalypse):\nAs the Baker, you can use your kill button on a player per round to give them bread. \nOnce a set amount of players are alive with bread, you become Famine.\n\nIf the Bread gives additional effects and the setting is on, then you can vent to change the bread that you give out. \nBread Effects:\nReveal: Reveals the target's role to the Baker (stays the whole game)\nRoleblock: Resets the target's kill cooldown when they try to use their kill button\nBarrier: Gives the target a barrier that is only known to the Baker (barrier is removed after the meeting)", "FamineInfoLong": "(Апокалипсис):\nКак только у Пекаря останется определенное количество живых людей с хлебом, они станут Голодом.\nЕсли после собрания не проголосуют за Голод, то они станут Голодом, и каждый игрок без хлеба умрет от голода (за исключением других участников Апокалипсиса).\nПосле голодной смерти всех без хлеба Голод может использовать кнопку убийства, чтобы морить голодом всех оставшихся игроков, что убьет этих игроков прямо перед следующей встречей.\n\nВы непобедимы, и после трансформации ваше присутствие будет объявлено всем на собрании.", "BerserkerInfoLong": "(Апокалипсис):\nИграя за Берсерка, вы повышаете уровень с каждым убийством.\nДостигнув определенного уровня, определенным Хостом, вы открываете новую новые силы такие как:\nВаши цели при убийстве исчезают.\nУбийства с помощью бомбы заставляют ваши убийства взрываться. Будьте осторожны при убийстве, так как это может убить других ваших членов Апокалипсиса, если они окажутся рядом. \nПосле определенного уровня вы становитесь Войной.", "WarInfoLong": "(Апокалипсис):\nИграя за Войну, вы непобедимы, у вас маленький откат убийства и вы можете убить любого, используя свои предыдущие способности.\nПосле трансформации ваше присутствие будет объявлено всем на собрании.", @@ -911,12 +899,11 @@ "TraitorInfoLong": "(Злой - Нейтрал):\nТрейтор был Предателем, который предал команду Предателей.\nОн знает кто является Предателем, но они не знают кто является Трейтором.\nОни могут убить вас, но вы не сможете убить их.\n\nУбейте Предателей другими возможными способами, а затем убейте всех остальных игроков, чтобы победить!", "TrollerInfoLong": "(Нейтрал):\nБудучи Троллем, вы можете выполнять задания, чтобы с игроками могли происходить случайные события.\nНапример, изменение скорости всех игроков, телепортация, влияние на саботаж и т. д.\nТакже вы можете выиграть вместе с командой победителем.", "VultureInfoLong": "(Злой - Нейтрал):\nСтервятник может репортить трупы для победы!\n\nКогда он репортит труп, если откат съедения истек, он съест труп.\n(Обратите внимение что после съедения трупа, труп не может исчезнуть из-за технических ограничений, его просто нельзя будет зарепортить)\nЕсли его способность есть все еще в откате, он зарепортит труп как обычно.\n\nКроме того, он будет репортить трупы в обычном режиме, если будет достигнуто максимальное количество тел, съеденных за раунд.", - "AbyssbringerInfoLong": "(Impostors):\nAs the Abyssbringer, you can place black holes. Black holes will suck in players and kill them when colliding with them.", "TaskinatorInfoLong": "(Нейтрал):\nВсякий раз когда Таскинатор выполняет задание, задание будет заложено бомбой.\nКогда другой игрок выполнит задание которая была заложена, бомба моментально взорвется, и этот игрок умрет.\n\nВы выиграете, если доживете до конца.\n\nПримечание: Все бомбы Таскинатора игнорируют все защиты.", "BenefactorInfoLong": "(Член Экипажа):\nКаждый раз когда Благодетель выполняет задание, оно будет отмечено. Когда другой игрок выполняет отмеченное задание, он получает временный щит.\n\n Примечание. Щит защищает только от прямых убийств.", - "MedusaInfoLong": "(Злой - Нейтрал):\nМедуза может нажать кнопку репорта и превратить труп в камень.\nЭтот труп нельзя будет зарепортить.\nУбейте всех, чтобы победить.", + "MedusaInfoLong": "(Neutrals):\nAs the Medusa, you can stone bodies much like cleaning a body.\nStoned bodies cannot be reported.\n\nKill everyone to win.", "SpiritcallerInfoLong": "(Злой - Нейтрал):\nКогда Призыватель убивает игроков, они становятся Злыми Духами. Эти духи могут помочь ему победить, заморозив других игроков на короткое время и/или уменьшить их дальность обзора. Кроме того, Злые Духи могут дать ему щит, который ненадолго защитит его от попытки убийства.", - "AmnesiacInfoLong": "(Neutrals):\nAs the Amnesiac, use your report button to remember a target and get its role.\nTo balance the game, you will not be able to vent after remembering your role if you can't vent as Amnesiac.'", + "AmnesiacInfoLong": "(Нейтрал):\nАмнезияк использует кнопку ''Репорт'', чтобы запомнить роль трупа.\n\nЕсли целью был Предатель, он станет Беженцем.\nЕсли цель был Членом Экипажа, вы заберёте его роль если он был совместим (в противном случае вы станете обычным Инженером).\nЕсли цель был Пассивным Нейтралом или Нейтральным Убийцей, он станет ролью которая определена в настройках", "ImitatorInfoLong": "(Нейтрал):\nИмитатор использует кнопку убийства, чтобы подражать ролями игроков.\n\nВы станете Шерифом, Беженцем или Нейтралом.", "BanditInfoLong": "(Нейтрал):\nБандит может нажать кнопку убийства один раз, чтобы украсть атрибут у игрока\nДвойное нажатие убьёт игрока.\nВ зависимости от настроек вы можете украсть атрибут сразу или после начала встречи.\nПосле достижения максимального количества краж вы будете убивать как обычно.\nКроме того, если на цели нет украденных атрибутов вы убьете цель.\n\nУбейте всех, чтобы победить.\n\nПримечание: - Очищенный, Последний Предатель и Любовники не могут быть украдены.\nЕсли он может использовать вентиляцию, Шустрый станет недоступным для кражи.", "DoppelgangerInfoLong": "(Нейтрал):\nДвойник использует кнопку убийства, чтобы украсть личность игрока (его ник и скин), а затем убивает свою цель.\n\nПримечание: Вы не можете украсть личность цели, находясь в камуфляже (если он активен).", @@ -925,14 +912,14 @@ "ShroudInfoLong": "(Злой - Нейтрал):\nНакрыватель не убивает игроков как обычно.\nВместо этого использует кнопку убийства, чтобы накрыть игрока.\nНакрытые игроки убивают других игроков.\nЕсли накрытый игрок не совершит убийство, он убьет себя после встречи.\n\nНакрыватель видит накрытых игроков с отметкой「◈」рядом с их именем.\nНакрытые игроки, не совершившие убийства, также будут иметь метку「◈」на встречах, где они умрут, если Накрыватель будет жив к концу встречи.", "WerewolfInfoLong": "(Злой - Нейтрал):\nВолк может убивать так же, как и любой убийца.\nОднако, когда он убивает, все ближайшие игроки также умирают.\nЛюбой игрок, который умирает от этого, будет иметь причину смерти как 'Растерзан'.\n\nЧтобы сбалансировать это, у него есть более высокий откат убийства, чем у кого-либо еще.", "ShamanInfoLong": "(Злой - Нейтрал):\nШаман может использовать кнопку убийства, чтобы выбрать куклу вуду один раз за раунд.\nЕсли на нём будет использована кнопка убийства, эффект будет перенаправлен на куклу вуду.\nЕсли вы доживете до конца, вы выиграете вместе с командой-победителем.\nПримечание: Если убийца не может убить выбранную цель, убийство отменяется, но если убийца попытается убить Шамана снова, то Шаман умрёт.", - "SeekerInfoLong": "(Злой - Нейтрал):\nИщущий использует кнопку убийства, чтобы пометить цель. Если Ищущий отмечает неправильного игрока, очко вычитается, а если искатель отмечает правильного игрока, очко будет добавлено.\nКроме того ищущий не сможет двигаться в течение 5 секунд после каждой встречи и после получения новой цели.\n\nИщущему необходимо набрать определенное количество очков, установленное хостом, чтобы выиграть.", + "SeekerInfoLong": "(Neutrals):\nAs the seeker, use your kill button to tag the target. If the seeker tags the wrong player, a point is deducted, and if the seeker tags the correct player, a point will be added.\nAdditionally, the seeker will not be able to move for 5 seconds after every meeting and after getting a new target.\n\nThe seeker needs to collect a certain number of points set by the Host to win.\nSeeker will see a ★ mark on target's name.", "PixieInfoLong": "(Нейтрал):\nИграя за Пикси, помечайте до X количество целей каждый раунд, нажимая на кнопку убийства. Когда собрание начнется, ваша задача — выбросить одну из отмеченных целей. В случае неудачи вы покончите жизнь самоубийством, за исключением случаев, когда вы не отметили ни одной цели или все цели мертвы. Выбранные цели сбрасываются до 0 после окончания встречи. Если вам это удастся, вы получите очко. Вы видите все свои цели в цветных именах.\n\nВы выигрываете вместе с командой-победителем, если у вас есть определенное количество очков.", "SchrodingersCatInfoLong": "(Добрый Нейтрал):\nЕсли кто-то попытается использовать против Пленного Кота кнопку убийства, он присоединится к команде убийцы, и при этом сам останется жив.\nБлокирующая способность срабатывает только один раз.\nПо умолчанию у него нет условия победы, но он выигрывает после смены команды.\nКроме того, в игре он не будете считаться никем.\n\nПримечание: Если Машина для Убийств попытается убить вас, взаимодействие не будет заблокировано, и Кот умрет.", "RomanticInfoLong": "(Нейтрал):\nРомантик может выбрать своего любовного партнёра используя кнопку убийств (это может быть сделано в любом моменте игры). Как только они выбрали партнера, они могут использовать кнопку убийства, чтобы дать своему партнёру временный щит. Если любовный партнёр умирает, Романтик поменяет свою роль.\n1. Если партнёр был Предателем, Романтик становятся Беженцем.\n2. Если партнёр был Нейтральным Убийцей, Романтик становится Безжалостным.\n3. Если партнёр был Ковеном, Романтик становится Банши.\n4. Если их партнёр был Членом Экипажа, или не убивающим нейтралом, Романтик становтся Мстящим.\n\nРомантик побеждает если партнёр побеждает.\n★Обратите внимание★: Если ваша роль меняется, то условия победы будут менятся тоже", "RuthlessRomanticInfoLong": "(Нейтрал):\nВы меняете свою роль с Романтика, если ваш партнёр (нейтральный убийца) мертв. Как Безжалостный Романтик, вы побеждаете когда убьете всех и останетесь последним в живых. Вы побеждаете когда ваш мертвый партнёр также побеждает с вами.", "VengefulRomanticInfoLong": "(Нейтрал):\nВы меняете свои роль с Романтика, если ваш партнер убит (Член Экипажа или не убивающий нейтрал). В качестве Мстящего Романтика, Ваша цель - отомстить за вашего партнера, а значит вы должны убить убийцу своего партнера. Если вы добились успеха, то оба вы и ваш партнер выигрывают с командой победителей в конце. Если вы пытаетесь убить кого-нибудь кроме убийцы вашего партнера, то вы умрете от промаха.", - "PoisonerInfoLong": "(Злой - Нейтрал)\nУ Отравителя убийства происходят спустя время.\nУбейте всех, чтобы победить.", - "HexMasterInfoLong": "(Злой - Нейтрал):\nМастер Проклятий может проклинать игроков или убивать их.\nПроклятия убивают игроков после собрания.", + "PoisonerInfoLong": "(Neutrals):\nAs the Poisoner, your kills are delayed.\nKill everyone to win.", + "HexMasterInfoLong": "(Neutrals):\nAs the Hex Master, you can hex players or kill them.\nHexing a player works the same as spelling as a Witch.", "WraithInfoLong": "(Злой Нейтрал):\nДух может временно стать невидимым прыгнув в вентиляцию. Но он по-прежнему будете видимым для самого игрока. Чтобы стать видимым снова прыгните в вентиляцию. Он выиграет, если останется последним игроком.", "JinxInfoLong": "(Злой - Нейтрал):\nВсякий раз когда Джинкс подвергается нападению, он накладывает на них порчу, в результате чего они умирают от проклятия.\nЭта способность имеет ограниченное применение.\n\nУбейте всех, чтобы победить.", "PotionMasterInfoLong": "(Злой - Нейтрал):\nРитуальщик может раскрыть роли других игроков, используя кнопку убийства.\n\nОдин щелчок: раскрыть роль игрока\nДвойной щелчок: убить игрока\n\nЕсли количество раскрытий закончится, то кнопка убийства будет работать как обычно.", @@ -958,7 +945,7 @@ "ParanoiaInfoLong": "(Атрибут):\nНе выдаётся Нейтралам либо Безумцам.\nКак Паранойя, ты будешь считаться как 2 игрока.", "MimicInfoLong": "(Атрибут):\nТолько Предатель может стать Мимиком. Когда Мимик умрёт, другие Предатели получат сообщение на собрании, это сообщение содержит роли, которые были убиты Предателем с атрибутом Мимика.", "GuesserInfoLong": "(Атрибут):\nУгадыватель может угадывать роли определённого игрока во время встречи. Если он угадает роль правильно, то он убьет эту цель, а если неправильно, то он совершит самоубийство. \nКоманда для угадываний: ''/bt [Номер игрока] [Название Роли]''\nПример: ''/bt 3 Байт''\nВы можете увидеть номер игрока перед его никнеймом, или же для просмотра номеров всех игроков нужно использовать команду ''/id''.", - "NecroviewInfoLong": "(Атрибут):\nНекровил может видеть в какой команде был мертвый игрок. Информация на никнейме мертвого игрока во время встречи:\n– Красный никнейм означает что он был в команде Предателей.\n– Голубой никнейм означает что он был в команде Членов Экипажа.\n– Оранжевый никнейм означает что он был в команде Нейтралов.", + "NecroviewInfoLong": "(Add-ons):\nThe Necroview can see the teams of dead players. The following info will be displayed on the dead player's name while in a meeting:\n- The Red name indicates the Impostors.\n- The Cyan name indicates the Crewmates.\n- The Gray name indicates the Neutrals.", "ReachInfoLong": "(Атрибут):\nТолько роли с кнопкой убийства могут получить это дополнение. В отличие от всех остальных, у вас самая большая дальность убийтсва.", "BaitInfoLong": "(Атрибут):\nКогда Байта убивают, он заставляет убившего игрока моментально зарепортить ваш труп.\nОднако этого не произойдет, если Байт будет убит Уборщиком, Очистщиком, Невидимкой, Духом или Машиной для Убийств. Репорт может произойти спустя время (в соответствии с настройками Хоста).", "TrapperInfoLong": "(Атрибут):\nПосле того как Капкана убьют, то его убийца будет обездвижен на несколько секунд. (время зависит от настроек).", @@ -981,7 +968,7 @@ "RebirthInfoLong": "(Атрибут):\nЕсли игрока у которого есть атрибут Перерождённого собираются изгнать, он поменяется скинами со случайным Членом Экипажа который голосовал за вас.\nПримечание. Голос хоста никогда не учитывается.\nПерерождённый будет удален, если он исчерпает все свои перерождения.", "LoyalInfoLong": "(Атрибут):\nЛояльного нельзя завербовать такими ролями, как Шакал или Суккубом.\n\nНе может быть назначен Нейтралам.", "EvilSpiritInfoLong": "(Злой - Нейтрал):\nУ Злого Духа есть задача помочь Призывателю победить. Вы можете использовать кнопку «Защитить», чтобы заморозить игроков и уменьшить их дальность обзора или дать Призывателю временный щит.", - "RecruitInfoLong": "(Betrayal Add-ons):\nAs a recruit, you are on the Jackal's team and help out the Jackal and their Sidekicks.\nYou cannot win with your original team.\nDepending on the settings, you may turn into Jackal if old Jackal was killed and no sidekicks is alive.", + "RecruitInfoLong": "(Предательский Атрибут):\nКак Завербованный, вы больше не сможете победить с вашей первоначальной командой. Взамен, вы должны помочь Шакалу и победить.", "AdmiredInfoLong": "(Предательский Атрибут):\nКак человек, которому признался в любви Поклонник, вы побеждаете с Членами Экипажа.\n\nВы видите Поклонника.", "GlowInfoLong": "(Атрибут):\nВо время отключения света, вы и игроки рядом с вами получите усиление обзора.", "RadarInfoLong": "(Атрибут):\nУ Радара всегда есть стрелка, которая указывает на ближайшего к нему игрока.", @@ -1025,7 +1012,6 @@ "ProhibitedInfoLong": "(Атрибут):\nКак Ограниченный, вы не можете использовать определенные вентиляции\nКоличество отключенных вентиляций зависит от настроек хоста.", "EavesdropperInfoLong": "(Add-ons):\nУ Подслушиваетеля есть возможность читать сообщения, которые были отправленные другим ролям/атрибутам, например, «Гробовщик» или «Сыщик».", "ApocalypseInfoLong": "(Apocalypse):\nApocalypse members are on a separate team that works together and wins together. If there are multiple Apocalypse roles in the game, they can see each other's roles.\nDepending on the Host's settings, Apocalypse roles can guess or be guessed.", - "RevenantInfoLong": "(Neutral):\nAs the Revenant, your goal is to be killed. If you are killed, you will take your killer's role and kill your killer instead. You cannot win before being killed.\nNote that Revenant only works when being directly killed.", "ShowTextOverlay": "Наложение текста", "Overlay.GuesserMode": "Режим Угадывателей", "Overlay.NoGameEnd": "Игра Не Закончится", @@ -1039,8 +1025,6 @@ "AbilityUseLimit": "Первоначальный лимит на использование способности", "AbilityInUse": "Способность использована", "AbilityExpired": "Способность окончена, осталось {0}", - "RevenantTargeted": "Your role has changed to {0}", - "RevenantCanCopyAddons": "Can Steal Addons", "ShowArrows": "Может видеть стрелки ведущие к трупам", "ArrowDelayMin": "Минимальная задержка показа стрелок", "ArrowDelayMax": "Максимальная задержка показа стрелок", @@ -1370,8 +1354,6 @@ "ShieldedCanUseKillButton": "Защищенный игрок может использовать кнопку способности/убийства", "PlayerIsShieldedByGame": "Игрок защищен игрой!", "LegacyNemesis": "Использовать устаревшую версию", - "LegacyParasite": "Use Legacy Version", - "LegacyTraitor": "Use Legacy Version", "ArsonistKeepsGameGoing": "Поджигатель продолжает игру", "ArsonistCanIgniteAnytime": "Может жечь в любое время", "ArsonistMinPlayersToIgnite": "Минимум обливаний, необходимых для поджигания", @@ -1514,18 +1496,6 @@ "SheriffCanKillSeparately": "Выбрать кого", "In%team%": "(Команда %team%)", "SheriffMisfireKillsTarget": "Шериф убивает цель вместе с собой", - "BlackHolePlaceCooldown": "Black Hole Place Cooldown", - "BlackHoleDespawnMode": "Black Hole Despawn Mode", - "BlackHoleDespawnTime": "Time After Black Hole Despawns", - "Abyssbringer.Suffix": "<#00ffa5>Number of players consumed by {0} <#00ffa5>active black holes:\\n{1}", - "Abyssbringer.Suffix.BlackHole": "<#00ffa5>{0}: {1}", - "BlackHoleMovesTowardsNearestPlayer": "Black Hole Moves Towards Nearest Player", - "BlackHoleMoveSpeed": "Black Hole Moving Speed", - "BlackHoleRadius": "Black Hole Consuming Radius", - "AfterTime": "After Time", - "After1PlayerEaten": "After 1 Player Was Eaten", - "AfterMeeting": "After Meeting", - "None": "None", "SheriffShotLimit": "Количество выстрелов", "SheriffCanKillAllAlive": "Может убивать когда никто не умер", "SheriffCanKillCharmed": "Может убить Зачарованных игроков", @@ -1542,15 +1512,12 @@ "RebirthUses": "Количество перерождений", "RebirthCountVotes": "Действует только на тех игроках, которые проголосовали за него", "RebirthFailed": "Вы не нашли живых игроков с которыми можно было бы поменяться телами", - "FireworkerCooldown": "Placement Cooldown", "ReverieIncreaseKillCooldown": "Увеличить откат убийства", "ReverieMaxKillCooldown": "Максимальный откат убийства", "ReverieMisfireSuicide": "Убивается если откат убийства дойдёт до максимума", "ReverieResetCooldownMeeting": "Сбросить откат убийства после встречи", "ConvertedReverieKillAll": "Преобразованный Мечтатель может убить кого угодно без каких-либо последствий", "VigilanteNotify": "Ты стал тем, что поклялся уничтожить", - "DictatorChangeCommandToExpel": "Dictator use Command to expell instad of vote", - "DictatorExpelSelf": "WAIT WAIT WAIT WAT THE HELLLLLL Bro really just want to expel himself", "DoctorTaskCompletedBatteryCharge": "Длительность батарейки", "SnitchEnableTargetArrow": "Может видеть стрелку цели", "SnitchCanGetArrowColor": "Может видеть цвета стрелок", @@ -1624,6 +1591,7 @@ "TimeThiefDecreaseMeetingTime": "Уменьшить время встречи на", "TimeThiefLowerLimitVotingTime": "Минимальное время встречи", "TimeThiefReturnStolenTimeUponDeath": "Вернуть украденное время после его смерти", + "TimeThiefMaxTimeOnAdmired": "Maximum Meeting Time if Time Thief Is Admired", "EvilTrackerCanSeeKillFlash": "Может видеть Вспышку-Убийства", "EvilTrackerCanSeeLastRoomInMeeting": "Может видеть местоположение целей во время встречи", "EvilTrackerTargetMode": "Может установить цель", @@ -1631,7 +1599,6 @@ "EvilTrackerTargetMode.OnceInGame": "В каждой игре", "EvilTrackerTargetMode.EveryMeeting": "На каждом собрании", "EvilTrackerTargetMode.Always": "Всегда", - "ScavengerHasCustomDeathReason": "Enable Custom Death Reason", "EvilHackerCanSeeDeadMark": "Может видеть местонахождение трупов", "EvilHackerCanSeeImpostorMark": "Может видеть местонахождение других предателей", "EvilHackerCanSeeKillFlash": "Может видеть Вспышку-Убийства", @@ -1864,21 +1831,13 @@ "Jackal_SidekickCountMode_Jackal": "Шакал", "Jackal_SidekickCountMode_Original": "Первоначальная команда", "Jackal_SidekickAssignMode": "Режим назначения Союзников", - "Jackal_SidekickAssignMode_SidekickAndRecruit": "Sidekick when failed Recruit", - "Jackal_SidekickAssignMode_Sidekick": "Only Sidekick", - "Jackal_SidekickAssignMode_Recruit": "Only Recruit", + "Jackal_SidekickAssignMode_SidekickAndRecruit": "Союзник+Завербованный", + "Jackal_SidekickAssignMode_Sidekick": "Союзник", + "Jackal_SidekickAssignMode_Recruit": "Завербованный", + "JackalWinWithSidekick": "Шакал может победить с командой Союзника", "Jackal_SidekickCanKillSidekick": "Союзники могут убить других Союзников", "Jackal_SidekickCanKillJackal": "Союзники могут убить Шакала", - "Jackal_RecruitFailed": "You can not recruit this player!", "JackalCanKillSidekick": "Шакал может убить Союзника", - "Jackal_SidekickCanKillWhenJackalAlive": "Sidekick can kill while Jackal is Alive", - "Jackal_SidekickTurnIntoJackal": "Sidekick can turn into Jackal after its death", - "Jackal_RestoreLimitOnNewJackal": "Restore Recruit limit when Sidekick become new Jackal", - "Jackal_OnBecomeNewJackalMeeting": "The old Jackal {0} is dead.\nYou are selected as new Jackal\nWork together and win the game!", - "Jackal_OnNewJackalSelectedMeeting": "The old Jackal {0} is dead.\n{1} is selected as new Jackal!\nWork together and win the game!", - "Jackal_BecomeNewJackal": "Old Jackal Dead, You are now new Jackal!", - "Jackal_OnNewJackalSelected": "Old Jackal Dead, Please help new Jackal {0} for now!", - "Jackal_BossIsDead": "Opps, the Jackal boss is dead!", "CoronerArrowsPointingToDeadBody": "Стрелки указывающие на трупы", "CoronerLeaveDeadBodyUnreportable": "Трупы, с которыми взаимодействовал Коронер нельзя будет зарепортить", "CoronerInformKillerBeingTracked": "Сообщать убийце что его отслеживают", @@ -1916,9 +1875,6 @@ "VipTag": "VIP★", "ApplyVipList": "Применить VIP список", "AllowSayCommand": "Разрешить модераторам использовать команду /say", - "AllowStartCommand": "Allow moderators to use /start command", - "StartCommandMinCountdown": "Minimum countdown for /start command", - "StartCommandMaxCountdown": "Maximum countdown for /start command", "KickCommandDisabled": "Команда кика в настоящее время отключена.", "KickCommandNoAccess": "У вас нет доступа к команде кика.", "KickCommandInvalidID": "Указан неверный идентификатор игрока.\nИспользуйте «/kick [playerID] [причина]», чтобы кикнуть игрока.\nПример:- /kick 5 не соблюдает правила", @@ -1951,11 +1907,6 @@ "WarnCommandNoAccess": "У вас нет доступа к команде предупреждения.", "WarnCommandInvalidID": "Указан неверный идентификатор игрока.\nИспользуйте «/warn [идентификатор игрока] [причина]», чтобы предупредить игрока. \nПример: - /warn 5 пишет в чат во время изгнания", "WarnCommandWarnHost": "Вам не разрешено предупреждать Хоста.", - "StartCommandNoAccess": "You do not have access to the start command.", - "StartCommandDisabled": "The start command is currently disabled.", - "StartCommandCountdown": "ERROR\n\nThe game is already starting!", - "StartCommandStarted": "The game has been started by {0}!", - "StartCommandInvalidCountdown": "ERROR\n\nThe countdown must be between {0} and {1}!", "WarnCommandWarnMod": "Вы не имеете права предупреждать других модераторов.", "WarnCommandWarned": "был предупрежден. Предупреждений больше не будет, и будут предприняты соответствующие действия \n ", "WarnExample": "Используйте /warn [Айди] [Причина] в будущем. \nПример:-\n /warn 5 пишет в чат во время изгнания", @@ -1983,7 +1934,6 @@ "DeathReason.Quantization": "Квантование", "DeathReason.Overtired": "Переработал", "DeathReason.Ashamed": "Пристыженный", - "DeathReason.Consumed": "Consumed", "DeathReason.PissedOff": "Уничтожен", "DeathReason.Dismembered": "Расчленен", "DeathReason.LossOfHead": "Задушен", @@ -2007,8 +1957,6 @@ "DeathReason.Starved": "Голод", "DeathReason.Equilibrium": "Равновесие", "DeathReason.Sacrificed": "Пожертвовал", - "DeathReason.Electrocuted": "Electrocuted", - "DeathReason.Scavenged": "Scavenged", "OnlyEnabledDeathReasons": "Только активные причины смерти", "Alive": "Выжил", "Disconnected": "Вышел", @@ -2024,10 +1972,11 @@ "DeputyHandcuffCooldown": "Откат наручников", "DeputyHandcuffMax": "Максимум наручников", "DeputyHandcuffedPlayer": "Цель в наручниках", - "HandcuffedByDeputy": "На вас были одеты наручники!", - "DeputyInvalidTarget": "На цель не могут быть надеты наручники", + "HandcuffedByDeputy": "You were handcuffed!\nNow you have broken your handcuff and can kill again.", + "DeputyInvalidTarget": "Target is already handcuffed", + "HandcuffBrokenAfterMeeting": "Remove all handcuffs after meeting", "DeputyHandcuffText": "Наручники", - "DeputyHandcuffCDForTarget": "Откат убийства у игроков с наручниками", + "DeputyHandcuffCDForTarget": "Next Kill Cooldown for handcuffed player", "RejectShapeshift.AbilityWasUsed": "Способность была использована", "EscapisMtarkedPosition": "Вы отметили свою позицию", "InvestigateCooldown": "Откат исследования", @@ -2087,7 +2036,6 @@ "ShowMadmatesInLeftCommand": "Показывать Безумцев (включая атрибут)", "ShowApocalypseInLeftCommand": "Может видеть Нейтральный Апокалипсис", "SeeEjectedRolesInMeeting": "Видеть роли изгнанных во время встречи", - "ThankYouForUsingTOHE": "Thank you for using TOHE!", "SkillUsedLeft": "Вы активировали навык для проведения собрания. \nОставшееся количество использование вашего навыка:", "NemesisDeadMsg": "Смерть Немезиса означает начало мести. \nПожалуйста, используйте /rv + [номер игрока], чтобы убить указанного игрока \nВы можете увидеть номер игрока перед его именем. \nИли введите команду /rv, чтобы получить список номеров игроков", "NemesisAliveKill": "Месть за Немезиса может начаться только после его смерти.", @@ -2107,7 +2055,6 @@ "GuessNotifiedBait": "Супер Звезда не может быть угадана, ты думал что всё так просто, да?", "GuessGM": "Угадать GM невозможно, потому что он уже и так мертв... И зачем так поступать с бедным Хостом?", "GuessGuardianTask": "Вы не можете угадать Стража, который выполнил все свои задания.", - "GuardianCantKilled": "You can't kill a Guardian who has finished their tasks.", "GuessMarshallTask": "Вы не можете угадать маршала, который выполнил все свои задания.", "GuessObviousAddon": "Извините, очевидные атрибуты не угадываются.", "GuessAdtRole": "К сожалению, настройки Хоста не позволяют угадывать Атрибуты", @@ -2163,7 +2110,6 @@ "BecomeMadmateCuzMadmateMode": "Вы стали Безумцем из-за своей смерти", "CleanerCleanBody": "Труп был очищен", "QuickShooterStoraging": "Пули сохранены успешно", - "QuickShooterFailed": "You are still in cooldown.", "PoisonerTargetDead": "Ваша цель умерла", "HexesLookLikeSpells": "Мастер Проклятий выглядят как Заклинатель", "HexButtonText": "Порча", @@ -2322,7 +2268,6 @@ "Message.YTPlanNotice": "Внимание: в этой комнате включен [режим Ютуб Ролика], владелец может поставить отдельные роли игрокам.\n Эта функция может использоваться только для создания видео роликов, если создатель комнаты нарушает это правило, выйдите или сообщите о нём.\n Текущие настройки:", "Message.OnlyCanBeUsedByHost": "ОШИБКА\n\nЭту команду может использовать только хост лобби", "Message.MaxPlayers": "Максимальное количество игроков установлено на ", - "Message.MaxPlayersFailByRegion": "Could not set max players: Vanilla regions support a maximum of 15 players.", "Message.GhostRoleInfo": "Информация о роли призрака\nПривет! Немного о ролях-призраках...\n\nРоли призраков сильно влияют на игру, поэтому не рекомендуется использовать их в небольших лобби.\nЕсли в описании явно не указано иное, кнопка «Охрана» является кнопкой их способностей ;)\n\nПоявление:\nРоли-призраки появляются только после смерти, их получают первые X игроков из (команды), которые умрут.\n\nПримечание: Если у изначальной роли не было задач (например у шерифа), ваши задачи в роли призрака не нужны для победы с помощью выполнения всех задач.", "ApocalypseInfoTitle": "Нейтральный Апокалипсис инфо:", "Message.ApocalypseInfo": "У каждой роли команды <#ff174f>Апокалипсиса есть своя цель, которую нужно выполнить, чтобы трансформироваться.\nУчастники <#2B0804>Трансформированного <#ff174f>Апокалипсиса кардинально меняют игру и становятся бессмертными (за исключением голосования), но все будут уведомлены о том, что они трансформировались.\n\nРоли: <#e5f6b4>Носитель Чумы, <#A675A1>Коллектор Душ, <#bf9f7a>Пекарь,<#cc0044>Берсерк.\nТрансформированные: <#343136>Чума, <#644661>Смерть, <#83461c>Голод, <#2B0804>Война.\n\nАпокалипсис может видеть роли и иконки способностей друг друга.\nКак и нейтральные убийцы, участники Апокалипсиса продолжают игру, веселитесь!", @@ -2454,6 +2399,7 @@ "LastResult": "★ Результат матча", "LastEndReason": "★ Причина окончания", "KillLog": "История убийств", + "MainRoleLog": "Role Convert Log", "Maximum": "Максимум", "RoleRate": "ВКЛ", "RoleOn": "ВСЕГДА", @@ -2640,7 +2586,7 @@ "NeutralRemain": "\nНейтральных Убийц осталось: {0}", "OneNeutralRemain": "\nОстался {0} Нейтральный Убийца", "ApocRemain": "\nОсталось {0} Нейтрального Апокалипсиса", - "GameOverReason.HumansByVote": "Все Предатели и Нейтралы были изгнаны", + "GameOverReason.HumansByVote": "All Impostors and Neutral Killers were ejected or killed", "GameOverReason.HumansByTask": "Члены Экипажа выполнили задания", "GameOverReason.HumansDisconnect": "Члены Экипажа вышли из игры", "GameOverReason.ImpostorByVote": "Члены Экипажа были изгнаны", @@ -2730,9 +2676,8 @@ "DeathMeetingTimeIncrease": "Увеличено время встречи при наличии Смерти", "SoulCollectorMeetingDeath": "Ваша цель умерла во время встречи. Вы обрели душу.", "SoulCollectorKillButtonText": "Прогноз", - "SoulCollectorHasImpostorVision": "Soul Collector has Impostor vision", "ApocalypseIsNigh": "[ Апокалипсис близок! ]", - "ApocalypseImmune": "This role is immune!", + "ApocalypseImmune": "Этот игрок имеет иммунитет потому что он непобедим!", "BakerToFamine": "Ты стал Голодом!!!", "BakerTransform": "Пекарь стал Голодом, Всадником Апокалипсиса! Начался голод!", "BakerAlreadyBreaded": "Игрок уже имеет хлеб!", @@ -2741,15 +2686,13 @@ "BakerBreadNeededToTransform": "Количество хлеба для того, чтобы стать Голодом", "BakerCantBreadApoc": "Ты не можешь давать хлеб другим Апокалипсисам!", "BakerKillButtonText": "ХЛЕБ", - "BakerUnshiftButtonText": "Switch Bread", "BakerRevealBread": "РАСКРЫТЬ", "BakerRoleblockBread": "ЗАБЛОКИРОВАТЬ", "BakerBarrierBread": "БАРЬЕР", "BakerCurrentBread": "Количество хлеба: ", "BakerSwitchBread": "Хлеб переключен на: ", - "BakerCanVent": "Baker can Vent", + "BakerCanVent": "Пекарь может использовать вентиляцию", "BakerBreadGivesEffects": "Хлеб даёт дополнительные эффекты", - "BakerTransformNoMoreBread": "Baker transforms if they do not have enough bread", "FamineKillButtonText": "ГОЛОДАТЬ", "FamineStarveCooldown": "Откат голода (Голод)", "FamineCantStarveApoc": "Ты не можешь голодать других Апокалипсисов!", @@ -2796,7 +2739,6 @@ "GodfatherTargetCountMode": "Убийца превращается в", "GodfatherCount_Refugee": "Беженец", "GodfatherCount_Madmate": "Безумец", - "GodfatherRefugeeMsg": "You have been recruited by GodFather!", "MissChance": "Шанс промазать", "IncreaseByOneIfConvert": "Увеличить количество убийств на +1, если экипаж был преобразован", "HawkMissed": "Промах!", @@ -2829,7 +2771,6 @@ "BerserkerToWar": "Вы стали Войной!!!", "BerserkerTransform": "Берсерк
превратился в Войну,\nВсадник Апокалипсиса! Крикните «Хаос!» и выпустите псов войны.", "WarKillCooldown": "Откат убийства у Войны", - "BerserkerCanKillTeamate": "Can kill other Neutral Apocalypse", "BlackmailerSkillCooldown": "Откат Шантажа", "BlackmailerMax": "Максимальное количество раз, когда шантажированный игрок может говорить", "BlackmailerDead": "Внимание! {0} был Шантажирован!", @@ -2919,8 +2860,6 @@ "RememberedPursuer": "Ты вспомнил что ты Преследователь!", "RememberedFollower": "Ты вспомнил что ты Последователь!", "RememberedAmnesiac": "Тебе не удалось вспомнить свою роль.", - "AmnesiacRemembered": "You remembered you were {0}!", - "ReportWhenFailedRemember": "Report Dead Body when failed to remember", "RememberedImitator": "Вы вспомнили, что вы Имитатор.", "RememberedImpostor": "Ты вспомнил что ты Предатель!", "RememberedCrewmate": "Ты вспомнил что ты Член Экипажа!", @@ -2941,7 +2880,7 @@ "BanditStealCooldown": "Откат кражи", "DoppelMaxSteals": "Максимум кражи", "DoppelCurrentVictimCanSeeRolesAsDead": "Последняя жертва может видеть роли живых игроков как призрак", - "NecromancerRevengeTime": "Время некромантии", + "NecromancerRevengeTime": "Necromancy time", "NecromancerRevenge": "У тебя есть {0}, чтобы убить {1}", "NecromancerSuccess": "Некромантия завершена! Ты выжил убив своего убийцу.", "NecromancerHide": "Вентиляция отключена, бегите от Некроманта!", @@ -3146,7 +3085,7 @@ "DollMaster_PossessedTarget": "Вы завладели целью", "DollMaster_CannotPossessImpTeammate": "Невозможно завладеть другим предателем", "DollMaster_CouldNotSwapWithTarget": "Невозможно завладеть игроком", - "DollMaster_CanNotSwapWithDeadTarget": "Завладеть мертвым игроком невозможно", + "DollMaster_CanNotSwapWithDeadTarget": "Possessing a dead player isn't possible", "DollMaster_MainBody": "Основное тело", "DollMaster_Doll": "Кукла", "DollMaster_UnableToUseAbility": "Невозможно использовать способности на игроке", @@ -3164,7 +3103,7 @@ "PitfallTrapCauseVisionTime": "Длительность ослепления", "PitfallTrap": "Ты попался в ловушку!", "ConsigliereDivinationMaxCount": "Максимальное количество раскрытий", - "RitualMaxCount": "Максимум раскрытий", + "RitualMaxCount": "Maximum Reveals", "CleanserHideVote": "Скрыть голоса Очистителя", "OracleSkillLimit": "Максимум использований", "OracleHideVote": "Скрыть голоса Оракла", @@ -3334,12 +3273,9 @@ "PixieTargetAlreadySelected": "Цель уже выбрана", "PixieButtonText": "Пометить", "PlagueBearerCooldown": "Откат заражения", - "PlagueBearerCanVent": "Can vent", - "PlagueBearerHasImpostorVision": "Has Impostor vision", "PestilenceCooldown": "Откат убийства Чумы", "PestilenceCanVent": "Чума может использовать вентиляцию", "PestilenceHasImpostorVision": "Чума имеет обзор Предателей", - "PestilenceKillGuessers": "Kill players who guess Pestilence", "PlagueBearerAlreadyPlagued": "Игрок уже заражён", "PlagueBearerToPestilence": "Вы превратились в Чуму!!", "GuessPestilence": "Вы только что попытались угадать Чуму!\n\nВ подарок, Чума убила вас.", @@ -3383,7 +3319,6 @@ "EveryoneCanKnowMini": "Все могут видеть Мини", "CanBeEvil": "Может стать Злым Мини", "EvilMiniSpawnChances": "Вероятность что Мини окажется Злым Мини", - "EvilMiniCanBeGuessed": "Evil Mini can be guessed before 18", "GuessMini": "Извините, вы не можете угадать Мини пока он не вырастет.", "GrowUpDuration": "Секунды необходимое для роста", "MajorCooldown": "Откат убийства когда ему больше 18 лет", @@ -3525,7 +3460,6 @@ "WinnerRoleText.Doppelganger": "Двойник Победил!", "WinnerRoleText.Quizmaster": "Мастер Викторины Победил!", "WinnerRoleText.Agitater": "Агитатор Победил!", - "WinnerRoleText.Shocker": "Shocker Wins!", "AdditionalWinnerRoleText.Sidekick": "Союзник", "AdditionalWinnerRoleText.Taskinator": "Таскинатор", "AdditionalWinnerRoleText.Opportunist": "Выжившие", @@ -3611,7 +3545,7 @@ "SolsticerOnMeeting": "Вы стали свидетелем слишком большого количества смертей! В следующем раунде у вас будет еще {0} короткое задание!", "SolsticerTitle": "СОЛНЕЧНЫЙ", "GuessSolsticer": "Извините, но вы не можете угадать Солнечного!", - "ExpelSolsticer": "Sorry, but you can not expel Solsticer!", + "VoteSolsticer": "Извините, но вы не можете голосовать за Солнечного!", "SolsticerTasksReset": "Ваши задания были сброшены!", "SolsticerMisGuessed": "Вы неправильно угадали! Теперь вы не можете гадать.", "SolsticerGuessMax": "По скольку вы уже неправильно угадали, вы больше не можете гадать.", @@ -3712,19 +3646,6 @@ "MinionAbilityTime": "Продолжительность способности", "Minion_Blind": "ослеплён", "Evader_ChanceNotExiled": "Шанс не быть выкинутым", - "ShockerAbilityCooldown": "Ability Cooldown", - "ShockerAbilityDuration": "Ability Duration", - "ShockerAbilityPerRound": "Abilities Per Round", - "ShockerShockInVents": "Shock people in vents", - "ShockerAbilityResetAfterMeeting": "Reset marked rooms after meeting", - "ShockerOutsideRadius": "Radius Of Outside Tasks (not in a room)", - "ShockerCanShockHimself": "Can Shock Himself", - "ShockerImpostorVision": "Shocker has Impostor vision", - "ShockerIsShocking": "You're already shocking!", - "ShockerAbilityActivate": "Begin Shocking!", - "ShockerAbilityDeactivate": "Ability Deactivated", - "ShockerVentButtonText": "Shock", - "ShockerRoomMarked": "Marked Room", "EavesdropperMsgTitle": "Вы нашли секрет", "EavesdropPercentChance": "Шанс подслушать", "ChiefOfPoliceSkillCooldown": "Cooldown for recruiting sheriffs", @@ -3736,4 +3657,4 @@ "PolicPreventRecruitNonKiller": "Prevent recruit players without kill button", "PolicSuidiceWhenTargetNotKiller": "Suidices when recruit a non killer or non crewmate", "PolicPassConverted": "Can pass Converted Addon to Sheriff" -} +} \ No newline at end of file diff --git a/Resources/Lang/zh_CN.json b/Resources/Lang/zh_CN.json index 859ab3fe2..6242008d3 100644 --- a/Resources/Lang/zh_CN.json +++ b/Resources/Lang/zh_CN.json @@ -14,14 +14,12 @@ "Website": "TOHE官方网站", "PlayerNameForRoleInfo": "嗨{0}你的职业是:", "HostIconInMeeting": "房主:{0}", - "SubText.GM": "Spectate the chaos!", + "SubText.GM": "开局死的冤魂隔岸观火", "SubText.Crewmate": "你是正义的,驱散所有的邪恶!", "SubText.Impostor": "你是邪恶的,把正义压制住吧!", "SubText.Neutral": "不属于其他阵营的独立阵营", "SubText.Apocalypse": "与你的队伍一起变得势不可挡", "SubText.Madmate": "不要给内鬼帮倒忙了哦", - "SubText.Lovers": "最重要的是,记得照顾好你的另一半", - "SubText.Egoist": "什么叫做一波三折?", "TypeImpostor": "内鬼阵营", "TypeCrewmate": "船员阵营", "TypeNeutral": "中立阵营", @@ -31,9 +29,6 @@ "TeamNeutral": "中立阵营", "TeamCrewmate": "船员阵营", "TeamMadmate": "叛徒阵营", - "TeamLovers": "恋人", - "TeamEgoist": "利己主义者", - "TeamApocalypse": "灾厄职业", "YouAreCrewmate": "你是一名船员", "YouAreImpostor": "你是一名内鬼", "YouAreNeutral": "你是一名中立", @@ -225,7 +220,6 @@ "TaskManager": "任务管理者", "Witness": "目击者", "Swapper": "换票师", - "ChiefOfPolice": "警局局长", "NiceMini": "好迷你船员", "Mini": "迷你船员", "Spy": "间谍", @@ -254,7 +248,6 @@ "Stalker": "潜藏者", "Workaholic": "工作狂", "Solsticer": "至日者", - "Abyssbringer": "深渊使者", "Collector": "集票者", "Provocateur": "自爆卡车", "BloodKnight": "嗜血骑士", @@ -393,8 +386,6 @@ "Sloth": "树懒", "Prohibited": "受限者", "Eavesdropper": "窃听者", - "Shocker": "震击者", - "Revenant": "荒野猎人", "BracketAddons": "将附加职业以括号的形式显示", "EngineerTOHEInfo": "敌明我暗,邪恶无处遁形", "ScientistTOHEInfo": "随时使用生命体征器,生死拿捏于股掌", @@ -513,7 +504,7 @@ "PacifistInfo": "何必打打杀杀呢?", "RebirthInfo": "再次崛起", "MonarchInfo": "我今日封你为骑士,至此你无论如何都要效忠于我", - "AbyssbringerInfo": "Place Black Holes", + "AbyssbringerInfo": "创造黑洞", "SpurtInfo": "敏捷如兔,跃入春日!", "StealthInfo": "你似乎不该看到什么,闭上眼睛", "PenguinInfo": "你充Q币吗?不充?拖走!", @@ -538,7 +529,7 @@ "AdmirerInfo": "来吧,让我们并肩作战,进行到底", "TimeMasterInfo": "時よ止まれ!(时间暂停!)", "CrusaderInfo": "放心,有我在,你一定会毫发无损的", - "AltruistInfo": "我的性命就交给你了...", + "AltruistInfo": "复活一名玩家\n钻洞来改变报告按钮为复活或报告", "ReverieInfo": "鲜血...使我疯狂!!", "LookoutInfo": "笨拙的伪装,已经看穿!", "TelecommunicationInfo": "你是不是在使用设备?", @@ -547,7 +538,6 @@ "WitnessInfo": "我似乎目击到了什么", "GhastlyInfo": "你的附身具有强迫", "SwapperInfo": "打出极限翻盘的操作吧", - "ChiefOfPoliceInfo": "雇佣警长为船员服务!", "NiceMiniInfo": "长大前没人能伤害你", "ArsonistInfo": "燃烧吧!燃烧吧!我要让你们尸骨无存!!", "PyromaniacInfo": "让我把你的火浇灭吧", @@ -603,7 +593,7 @@ "VultureInfo": "我需要鸡腿!!!", "TaskinatorInfo": "完成无声的任务,享受致命的爆炸吧!!!", "BenefactorInfo": "任务完成,盾牌精英!", - "MedusaInfo": "看好我的眼睛!", + "MedusaInfo": "把尸体石化掉!", "SpiritcallerInfo": "为成就灵魂召唤者的伟业,甘愿为其效忠", "AmnesiacInfo": "我是谁呢?", "ImitatorInfo": "想赌我的刀...有多快吗?", @@ -615,7 +605,7 @@ "ShroudInfo": "让我来保护你活到下一轮吧~仅此而已", "WerewolfInfo": "咬死所有人!!!", "ShamanInfo": "抵挡所有对巫毒娃娃的攻击", - "SeekerInfo": "让我猜猜,你在哪里~", + "SeekerInfo": "让我猜猜,你在哪里~\n你的目标被★标记", "PixieInfo": "贴上标签,装进袋子,然后驱逐!", "OccultistInfo": "击杀并诅咒你的敌人", "SchrodingersCatInfo": "在被观察到之前,猫既是活的,也是死的", @@ -708,8 +698,6 @@ "SlothInfo": "见证树懒修BUG的速度", "ProhibitedInfo": "有的管道你注定钻不了", "EavesdropperInfo": "我能听到你在干什么", - "ShockerInfo": "震击毫无戒心的玩家", - "RevenantInfo": "担任带刀职业", "EngineerTOHEInfoLong": "(船员阵营):\n工程师可以在通讯被破坏情况下进入通风口", "ScientistTOHEInfoLong": "(船员阵营):\n科学家可以随时查看生命体征,了解谁还活着,谁已经死亡", "NoisemakerTOHEInfoLong": "(船员阵营):\n大嗓门每当死亡时都会发出声音,屏幕上也会出现大嗓门死亡的直观提示", @@ -781,11 +769,11 @@ "LurkerInfoLong": "(内鬼阵营):\n潜伏者可以通过钻洞减少一定的击杀CD。在完成击杀后,潜伏者的冷却时间会被重置为默认值", "VisionaryInfoLong": "(内鬼阵营):\n幻想家可以在会议上看见每个玩家的阵营:\n- 红色名表示内鬼阵营\n- 青色名表示船员阵营\n -灰色名表示中立阵营", "PlagueDoctorInfoLong": "(中立阵营)「来自TOH的瘟疫医生」:\n瘟疫学家选择一名玩家进行感染。任何在被感染玩家范围内停留一定时间的玩家都会被感染。感染进度是累积性的,不会随着距离或会议后重置", - "RefugeeInfoLong": "(叛徒阵营):\n逃亡者可能是:\n -通过回忆得知自己是一名内鬼\n -击杀了教父目标的带刀玩家\n -其恋人是内鬼的浪漫者\n -效仿了内鬼的效仿者\n\n现在你的职责是帮助内鬼阵营击杀船员阵营", + "RefugeeInfoLong": "(叛徒阵营):\n逃亡者通过回忆或者被教父洗脑获得这个职业。逃亡者相当于普通内鬼", "UnderdogInfoLong": "(内鬼阵营):\n失败者只能在在场存活人数小于房主设置的人数时才能进行击杀", "ConsigliereInfoLong": "(内鬼阵营):\n军师可以对一位玩家使用击杀键来得知目标的职业。当显示职业次数用完时,击杀为正常击杀\n- 单击显示身份\n- 双击正常击杀", "LudopathInfoLong": "(内鬼阵营):\n速度者的击杀冷却时间是随机的。击杀冷却最小值为1秒,而最大值是房主设置的默认击杀冷却时间", - "GodfatherInfoLong": "(内鬼阵营):\n教父投票给某人,让他们成为教父的目标。在下一轮中,如果有人击杀了目标,凶手将变成逃亡者或者叛徒", + "GodfatherInfoLong": "(内鬼阵营):\n教父投票给某人,让他们成为教父的目标。在下一轮中,如果有人击杀了目标,凶手将变成逃亡者", "ChronomancerInfoLong": "(内鬼阵营):\n天文学家有一个电量条,显示屠杀准备就绪的时间。 当电量达到「100%」时,下一次击杀时天文学家就会进入屠杀模式,天文学家就可以展现杀戮光环,直到电量耗尽。其他情况下,天文学家的击杀冷却是正常的", "PitfallInfoLong": "(内鬼阵营):\n设陷者使用变形可以将变形周围的区域标记为陷阱。进入该区域的玩家会在短时间内无法动弹,视野也会受到影响", "EvilMiniInfoLong": "(内鬼阵营):\n坏迷你船员在长大之前不可被击杀和被招募,且初始击杀冷却非常长,当坏迷你船员长大后击杀冷却会大幅缩短", @@ -821,7 +809,7 @@ "GrenadierInfoLong": "(船员阵营):\n掷雷兵可以通过使用通风管道使用闪光弹,闪光弹会导致内鬼失去大部分视野(根据房主设置闪光弹可能影响到中立阵营玩家)。闪光弹生效以及失效时掷雷兵会看到自己身上有护盾破碎作为提示。当掷雷兵成为叛徒时闪光弹只对船员生效", "MedicInfoLong": "(船员阵营):\n医生可以通过使用击杀按键给目标发放一个护盾,若护盾发放成功则医生会看到目标身上出现护盾破碎动画作为提示,同时目标的名字旁会显示一个绿色的「●」。医生可以发放护盾的数量会显示在医生的名字旁的括号内。每位玩家最多只能持有一个来自医生的护盾。根据房主设定目标可能可以看到自己是否持有护盾(显示在名字旁的绿色「●」)。", "FortuneTellerInfoLong": "(船员阵营):\n调查员可以会议中给玩家投票以获得它们身份的线索,该线索将与它们的实际身份相关,当调查员的任务完成时,将获得确切的身份而不是线索!\n注意:如果开启了随机给予目标职业与混合职业的设置,则无法多次调查同一玩家\n随机给予的目标职业与混合职业中必有目标的真实职业", - "JudgeInfoLong": "(船员阵营):\n正义法官可以在会议中审判某位玩家,若目标为邪恶角色则击杀目标(是否邪恶根据房主设定),错误则会自杀。\n审判指令为:/tl [玩家编号]\n你可以在玩家名字前看到该玩家的编号,或者使用/id指令查看所有玩家的编号\n当正义法官成为叛徒时可以随意审判", + "JudgeInfoLong": "(船员阵营):\n正义法官可以在会议中审判某位玩家,若目标为邪恶角色则击杀目标(是否邪恶根据房主设定),错误则会自杀。\n审判指令为:/tl [玩家编号]\\n你可以在玩家名字前看到该玩家的编号,或者使用/id指令查看所有玩家的编号\n当正义法官成为叛徒时可以随意审判\n在会议中技能次数为你本次会议可用的审判次数,在会议外技能次数为你全局游戏可用的审判次数。", "MorticianInfoLong": "(船员阵营):\n入殓师可以看到指向所有尸体的箭头,入殓师报告尸体可以在会议上得知被害者生前最后一个接触的玩家。请注意:入殓师不会成为胆小鬼或灵媒。", "MediumInfoLong": "(船员阵营):\n当场上有玩家被击杀,通灵师会收到提示。每次会议召开时通灵师会与被报告的尸体建立联系(只有被报告的尸体而不是被发现的所有尸体),在本次会议结束前,被害者拥有一次机会回答通灵师的问题,(死亡玩家使用「/ms 是」或「/ms 否」)回答是或否\n注意:通灵师不会成为胆小鬼", "ObserverInfoLong": "(船员阵营):\n观察者可以看到其他玩家的碎盾动画。首次会议召开前观察者的技能不会生效", @@ -833,7 +821,7 @@ "MerchantInfoLong": "(船员阵营):\n商人可以每完成一个任务就会向随机玩家出售一个随机附加职业。出售的附加职业都能为商人带来钱,如果商人有一定的钱,商人可以通过贿赂带刀玩家来避免对商人的击杀。被贿赂的玩家不能击杀商人,但商人不知道带刀玩家是谁", "RetributionistInfoLong": "(船员阵营):\n惩罚者死后可以击杀有限数量的玩家,但在任务全部完成的情况下才能击杀(房主设置)\n使用 /ret [玩家 ID]进行击杀\n你可以在玩家名字前看到该玩家的编号,或者使用/id指令查看所有玩家的编号。", "HawkInfoLong": "(船员阵营 [幽灵]):\n猎鹰是第一个船员死亡后会获得的职业(之一)。猎鹰可以使用守护天使的保护技能来击杀玩家,成功击杀玩家的概率由房主设置。多次击杀同一个人会增加成功击杀的概率", - "DeputyInfoLong": "(船员阵营):\n捕快可以使用击杀按钮重置目标的击杀冷却时间。如果目标没有击杀按钮,那么手铐就是个废物", + "DeputyInfoLong": "(船员阵营):\n捕快可以使用击杀按钮给目标戴上手铐。\n目标的下一次击杀相当于破坏手铐,重置击杀冷却。\n如果目标没有击杀按钮,那么手铐就是个废物", "InvestigatorInfoLong": "(船员阵营):\n研究者可以使用击杀按钮调查某人。当您调查某人时,如果他拥有击杀按钮,他的名字将显示为红色;如果他没有击杀按钮,他的名字将显示为浅蓝色。但请注意,当召集会议时,名字的颜色将恢复正常。", "GuardianInfoLong": "(船员阵营):\n守护者完成任务时将获得庇护无敌。甚至在会议上都不会被赌", "AddictInfoLong": "(船员阵营):\n瘾君子可以使用通风管来获得护盾。但是护盾结束后会让瘾君子一段时间内无法移动。如果瘾君子在通风管冷却结束后,且长时间没使用通风管,则会自杀", @@ -872,7 +860,7 @@ "LawyerInfoLong": "(中立阵营):\n游戏开始时律师会被分配到一个目标,并在其昵称旁用菱形「♦」表示。若律师目标胜利,则律师一起胜利。若律师的目标死亡,将依据房主设置变换。\n注意:律师死亡后也可以胜利", "OpportunistInfoLong": "(中立阵营):\n若投机者在游戏结束时存活,则投机者跟随获胜玩家一同获得胜利", "VectorInfoLong": "(中立阵营):\n马里奥跳管达到一定次数就会单独获得胜利", - "JackalInfoLong": "(中立阵营):\n豺狼可以使用击杀按钮进行招募。如果目标不是可以招募的,要么招募次数已经用完了,要么房主没开招募的选项,那么豺狼将正常击杀(也就是说,不要在其他人面前使用击杀按钮,以为这样就能招募)。如果目标有击杀按钮,并且开启了招募跟班的选项,那么他们就会变成跟班。根据设置,当豺狼被击杀时,会随机选择一个跟班作为新的豺狼。\n如果没有跟班活着,可以选择招募。", + "JackalInfoLong": "(中立阵营):\n豺狼可以使用击杀按钮进行招募。如果目标不是可以招募的,要么招募次数已经用完了,要么房主没开招募的选项,那么豺狼将正常击杀(也就是说,不要在其他人面前使用击杀按钮,以为这样就能招募)。如果目标有击杀按钮,并且开启了招募跟班的选项,那么他们就会变成跟班", "GodInfoLong": "(中立阵营):\n神从一开始就知道所有人的身份,而神只要活到最后就会抢走胜利", "InnocentInfoLong": "(中立阵营):\n冤罪师可以用击杀键栽赃任意一位玩家,被栽赃的目标会立刻击杀冤罪师,若目标在会议上被驱逐则冤罪师获胜", "PelicanInfoLong": "(中立阵营):\n仅剩鹈鹕阵营与船员阵营且鹈鹕阵营人数大于船员人数,鹈鹕获得胜利。鹈鹕可以使用击杀键活吞一位玩家(被活吞的玩家将被传送到地图外且无法与游戏互动),活吞成功后鹈鹕将看到自己身上出现盾牌破碎的动画作为提示。紧急会议或报告尸体会导致鹈鹕吞下的所有玩家立刻死亡。若鹈鹕死亡或掉线,则被吞下的所有玩家立刻回到鹈鹕死亡的位置。\n请注意:鹈鹕吞人不是正常击杀方式,因此保镖、老兵等职业技能不会生效。", @@ -884,14 +872,14 @@ "SolsticerInfoLong": "(中立阵营):\n至日者无法死亡的,只要做完任务就朝圣成功获胜了,但是每一轮会议后至日者的任务都会被重置。\n注意:试图击杀至日者会让至日者像被鹈鹕吞掉一样传送到地图外,击杀者的CD被重置为10秒\n注意:根据设定,至日者可能知道试图击杀他的人的职业。在至日者将要完成任务时,带刀玩家会得到指向至日者的箭头。\n至日者在游戏中为无阵营", "CollectorInfoLong": "(中立阵营):\n集票者投票给一名玩家后,可以收集到本次会议该玩家被投的所有票数。当集票者收集到指定数量的票后,则集票者单独胜利。请注意:集票者的胜利优先于驱逐玩家。", "GlitchInfoLong": "(中立阵营):\n缺点者可以入侵玩家(单击)或正常击杀(双击)。缺点者可以黑进玩家,让他们在一段时间内无法击杀、使用通风管和报告尸体。此外,除门以外的破坏行为不会产生任何效果。", - "SidekickInfoLong": "(中立阵营):\n跟班的职责是帮助豺狼击杀所有人。\n你和豺狼同赢共败。\n根据设置,如果老豺狼被杀,你可能会变成新的豺狼。\n在老豺狼死之前,你可能无法进行击杀。", + "SidekickInfoLong": "(中立阵营):\n仅剩豺狼阵营与船员阵营且豺狼阵营人数大于船员人数,豺狼阵营获得胜利。跟班属于豺狼阵营。", "ProvocateurInfoLong": "(中立阵营):\n自爆卡车可以用击杀键与任意目标同归于尽。若游戏结束时目标输了,则自爆卡车与胜利阵营一起胜利。", "BloodKnightInfoLong": "(中立阵营):\n仅剩嗜血骑士阵营与船员阵营且嗜血骑士阵营人数大于船员人数,嗜血骑士获得胜利。嗜血骑士每次击杀后都可以获得一定时间的护盾,护盾可以抵消所有常规击杀,直到护盾超时失效。", "PlagueBearerInfoLong": "(灾厄职业):\n瘟疫使者可以使用击杀按钮将其他玩家变成瘟疫。一旦变成瘟疫,瘟疫使者将拥有不死之身!并获击杀能力。且瘟疫使者将击杀任何试图击杀瘟疫使者的玩家。\n此外,当受感染瘟疫的玩家与未受感染瘟疫的玩家互动时,也会受到瘟疫感染", "PestilenceInfoLong": "(灾厄职业):\n瘟疫是瘟疫使者感染玩家后得到的职业,瘟疫在大部分情况下是无法击杀的,任何试图击杀瘟疫的人都会适得其反,瘟疫可以在被投票、被下咒的情况下死亡。你变身后,会议上的每个人都知道了你的到来。", "SoulCollectorInfoLong": "(灾厄职业):\n灵魂收集者可以对玩家使用击杀按钮来预测他们的死亡。如果目标在选择他们的回合或之后的会议中死亡,将获得一个灵魂。目标会在每次会议或死亡后重置\n一旦收集到设置的灵魂数量,就会成为死亡。如果启用了被动获得灵魂的设置,则每次会议都会获得一个灵魂。", "DeathInfoLong": "(灾厄职业):\n一旦灵魂收集者收集到所需的灵魂,就会变成死亡。死亡会击杀所有人。如果死亡在会议结束前没有被驱逐,死亡就赢了。在死亡变身的会议上会有可设置的额外会议时间,以便有更多的讨论时间来找到死亡\n死亡是无敌的,在变身之后,死亡的存在会在会议上向所有人宣布", - "BakerInfoLong": "(灾厄职业):\n面包师可以在每一轮中使用击杀按钮来给一名玩家面包。一旦有设定数量的玩家存活并拥有面包,面包师就会变成饥荒。如果面包有额外的效果并且设置已开启,那么可以通过使用通风管来改变面包师给出的面包。\n\n面包效果:\n1.揭示:向面包师揭示目标的职业(在整个游戏中保持不变)\n2.击杀封锁:将目标的击杀冷却时间设置为999(会议后重置为正常)\n3.护盾:为目标玩家提供一个只有面包师知道的护盾(会议后护盾会被移除)", + "BakerInfoLong": "(灾厄职业):\n面包师可以在每一轮中使用击杀按钮来给一名玩家面包。一旦有设定数量的玩家存活并拥有面包,面包师就会变成饥荒。如果面包有额外的效果并且设置已开启,那么可以通过使用通风管来改变面包师给出的面包。\n\n面包效果:\n1.揭示:向面包师揭示目标的职业(在整个游戏中保持不变)\n2.击杀封锁:在目标尝试击杀时直接重置其击杀冷却\n3.护盾:为目标玩家提供一个只有面包师知道的护盾(会议后护盾会被移除)", "FamineInfoLong": "(灾厄职业):\n一旦面包师有了一定数量的面包幸存者,面包幸存者就会变成饥荒。所有没有面包的玩家都会饿死(不包括其他灾厄玩家)。所有没有面包的玩家饿死之后,饥荒可以使用击杀来饿死剩余的玩家,这些玩家会在下一次会议之前被杀死\n你是无敌的,在你转变后,你的存在会在会议中被所有人宣布", "BerserkerInfoLong": "(灾厄职业):\n狂战士每次击杀玩家都会提升等级。达到房主设置的等级后,就能解锁新的buff。\n1.获得清道夫的击杀方式。\n2.击杀会让玩家爆炸。且击杀时要小心,因为如果其它灾厄职业玩家在附近,这可能会击杀它们。\n3达到一定等级后,就会成为战争者", "WarInfoLong": "(灾厄职业):\n战争者将变得无敌,击杀冷却时间更短,并能用以前的buff击杀\n变身后,会议上的每个人都知道了战争者的到来", @@ -911,12 +899,11 @@ "TraitorInfoLong": "(中立阵营):\n背叛者知道内鬼,但内鬼不知道背叛者。内鬼可以击杀背叛者,但背叛者不能击杀内鬼。通过其他方式击杀内鬼,然后击杀其他人获胜", "TrollerInfoLong": "(中立阵营):\n暴君可以通过完成任务,让随机事件发生在玩家身上。例如,改变所有玩家的速度、传送、影响破坏等\n暴君与获胜的阵营一起获胜", "VultureInfoLong": "(中立阵营):\n秃鹫报告一具尸体时,且秃鹫的进食冷却时间到了,秃鹫可以吃掉尸体。如果秃鹫的进食技能仍然处于冷却状态,那么秃鹫会正常报告尸体。此外,如果达到每轮吃掉的最大尸体数,秃鹫将正常报告尸体", - "AbyssbringerInfoLong": "(内鬼阵营):\n深渊使者可以放置黑洞。黑洞将玩家吸入并在与他们碰撞时击杀他们。", "TaskinatorInfoLong": "(中立阵营):\n任务执行者完成任务时,任务就会被轰炸。 当其他玩家完成被炸任务时,炸弹就会爆炸,玩家就会死亡\n注意:任务执行者放置的炸弹忽略所有保护\n例如:医生的护盾", "BenefactorInfoLong": "(船员阵营):\n恩人每当完成一项任务,该任务就会被标记。当其他玩家完成被恩人标记的任务时,将获得一个临时护盾\n注意:护盾只能抵御直接击杀", - "MedusaInfoLong": "(中立阵营):\n美杜莎可以像清理尸体一样石化尸体。无法报告被石化的尸体", + "MedusaInfoLong": "(中立阵营):\n美杜莎可以像清理尸体一样石化尸体\n他人无法报告被石化的尸体\n\n击杀所有人赢得胜利", "SpiritcallerInfoLong": "(中立阵营):\n灵魂召唤者可以把玩家被击杀后变成恶灵。这些恶灵可以通过短时间冻结其他玩家。或者阻挡他们的视线来帮助灵魂召唤者获胜。再或者,恶灵可以给灵魂召唤者一个护盾,短暂地保护灵魂召唤者免受被击杀", - "AmnesiacInfoLong": "(中立阵营):\n失忆者使用自己的报告按钮记住并获得目标的职业\n为了游戏平衡,当你的职业是失忆者的时候就不能使用通风口,即使你回忆起了自己的职业,你仍然无法使用通风口", + "AmnesiacInfoLong": "(中立阵营):\n失忆者使用的报告按钮来记住玩家的身份。如果目标是内鬼,失忆者将成为逃亡者。如果目标是一名船员,且符合条件,失忆者将成为目标的身份(否则失忆者将成为一名工程师)。如果目标是被动中立或未指定的带刀中立,失忆者将成为设置的中立身份。如果目标是少数人中的带刀中立,失忆者就会成为他们的身份", "ImitatorInfoLong": "(中立阵营):\n效仿者使用击杀按钮效仿一名玩家。效仿者会成为警长、逃亡者或中立.", "BanditInfoLong": "(中立阵营):\n强盗可以使用击杀按钮偷取玩家的附加职业。根据设置,强盗可以立即或在会议开始后偷取附加职业。达到最大偷取次数后,只能正常击杀。此外,如果目标身上没有可偷取的附加职业,就会击杀目标\n注意:- 干净的、仅存内鬼和恋人不能被偷取", "DoppelgangerInfoLong": "(中立阵营):\n替身者使用击杀按钮偷取玩家的身份(他们的名字和皮肤),然后击杀目标玩家。\n注意:- 隐蔽激活时,无法偷取目标身份", @@ -925,14 +912,14 @@ "ShroudInfoLong": "(中立阵营):\n裹尸布不能进行正常的击杀。而是对玩家使用击杀按钮进行保护,被保护的玩家名字旁边打上「◈」标记。被保护的玩家在遇到其他玩家就会击杀。如果被保护的玩家活到会议后,且会议结束时裹尸布还活着,被保护的玩家就会死亡", "WerewolfInfoLong": "(中立阵营):\n月下狼人可以在破坏灯光来进行击杀(不破坏灯光也可以击杀)。在破坏灯光时月下狼人的击杀冷却时间很短,且击杀时不会瞬移", "ShamanInfoLong": "(中立阵营):\n萨满可以使用击杀按钮选择一个巫毒娃娃,每回合一次。如果有人对萨满使用了技能,效果会转移到巫毒娃娃身上", - "SeekerInfoLong": "(中立阵营):\n搜寻者使用击杀按钮标记目标。此外,在每次见面后和获得新目标后的5秒钟内,搜寻者将无法移动。搜寻者需要收集到由房主设定的一定数量的分数才能获胜", + "SeekerInfoLong": "(中立阵营):\n搜寻者使用击杀按钮标记目标。标记正确将获得正向点数,标记错误会被扣点。点数到达预设值即获胜。\n此外,在每次会议结束后和切换新目标后,搜寻者会被冻结5秒\n搜寻者将会在其目标的名字上看到 ★ 标记", "PixieInfoLong": "(中立阵营):\n小精灵每轮使用击杀按钮可以标记多达x个目标。当会议开始时,小精灵的任务是将其中一个被标记的目标驱逐出去。如果没有驱逐成功,就会自杀,除非没有标记任何目标或所有目标都已死亡。会议结束后,所选目标重置为0。如果成功,将获得一分。可以看到所有目标的彩色名称\n当获得房主设定的一定分数时,小精灵将与获胜阵营一起获胜", "SchrodingersCatInfoLong": "(中立阵营):\n如果有人试图对薛定谔的猫使用击杀技能,薛定谔的猫就会阻止击杀并加入击杀薛定谔的猫的玩家队伍。这种阻止击杀只生效一次。默认情况下,薛定谔的猫没有胜利条件,这意味着薛定谔的猫只有在更换阵营后才能胜利。此外,薛定谔的猫在游戏中将被视为无阵营\n注意:如果杀戮机器试图对薛定谔的猫使用击杀技能,互动不会被阻止,薛定谔的猫将会死亡", "RomanticInfoLong": "(中立阵营):\n浪漫者可以使用击杀按钮挑选自己的恋人(这可以在游戏的任何时候进行)。一旦他们挑选了恋人,就可以使用击杀按钮为恋人提供一个临时护盾,保护他们免受攻击。如果浪漫者的恋人死亡,浪漫者的身份将根据以下条件发生变化:\n1. 如果浪漫者的恋人是内鬼,浪漫者将成为逃亡者\n2.如果浪漫者的恋人是带刀中立,那么浪漫者就会变成无情浪漫者\n3.如果浪漫者的恋人是船员或无刀中立,浪漫者就会变成复仇浪漫者\n注:如果浪漫者的身份发生变化,浪漫者的获胜条件也会相应改变", "RuthlessRomanticInfoLong": "(中立阵营):\n如果浪漫者的恋人(带刀中立)被杀,浪漫者将转变为无情浪漫者,无情浪漫者击杀所有人并成为最后一个站着的人!\n死去的恋人也会和浪漫者一起赢", "VengefulRomanticInfoLong": "(中立阵营):\n如果浪漫者的恋人(船员或无刀中立)被杀,浪漫者将份转换为复仇浪漫者,复仇浪漫者的目标是为死去的恋人复仇,这意味着复仇浪漫者必须击杀杀害浪漫者恋人的玩家。如果复仇浪漫者成功做到这一点,复仇浪漫者和浪漫者的恋人都会获胜\n如果复仇浪漫者试图击杀的人不是杀害浪漫者恋人的玩家,那么复仇浪漫者将死于误杀", "PoisonerInfoLong": "(中立阵营):\n投毒者能放毒在一名玩家身上,那名玩家将会延迟一段时间突然暴毙(跟吸血一样)", - "HexMasterInfoLong": "(中立阵营):\n巫师拥有两种攻击方式:直接击杀与诅咒(切换方式根据房主设定)被诅咒的目标会带有对全员可见的诅咒标记紫色(根据房主设定)的「乂」。如果会议结束时巫师未被驱逐或击杀,则被诅咒的目标死亡", + "HexMasterInfoLong": "(中立阵营):\n巫师拥有两种攻击方式:直接击杀与诅咒(切换方式根据房主设定)\n被诅咒的目标会带有对全员可见的诅咒标记紫色(根据房主设定)的「乂」。\n如果会议结束时巫师未被驱逐或击杀,则被诅咒的目标死亡", "WraithInfoLong": "(中立阵营):\n魅影无法正常使用管道。但可以通过通风管进入隐身状态,再次使用通风管则取消隐身状态", "JinxInfoLong": "(中立阵营):\n每当扫把星受到攻击时,扫把星都会诅咒他们,导致他们死于厄运。这种用途有限。", "PotionMasterInfoLong": "(中立阵营):\n药剂师有三种药水,分别用于三种不同的行动: 揭示身份、双击击杀、地图破坏\n提示:揭示药水是有上限的。当你的药水用完时,会转变为击杀按钮。", @@ -981,7 +968,7 @@ "RebirthInfoLong": "(附加职业):\n重生者是即将被驱逐的玩家,将与他人交换皮肤,并再次茁壮成长\n警告:如果你耗尽了所有的重生次数,重生就会从你身上消失", "LoyalInfoLong": "(附加职业):\n忠诚不能被豺狼或邪教等身份招募。不能分配给中立", "EvilSpiritInfoLong": "(附加职业):\n恶灵的工作是帮助灵魂召唤者取得胜利。恶灵可以使用闹鬼技能来冻结玩家并减少他们的视野。或者,恶灵可以使用你的闹鬼技能暂时为灵魂召唤者提供一个防御击杀的盾牌", - "RecruitInfoLong": "(附加职业):\n当你被招募时,你加入了豺狼的团队,帮助豺狼和他们的跟班。\n你不能和你原来的阵营一起获胜。\n根据设置,如果老豺狼被杀,且没有跟班活着,你可能会变成豺狼。", + "RecruitInfoLong": "(附加职业):\n帮助豺狼。无法与原阵营一起获胜", "AdmiredInfoLong": "(附加职业):\n你的目的是帮助船员阵营,而不是你原来的阵营", "GlowInfoLong": "(附加职业):\n熄灯期间,「光辉」和「光辉附近的玩家」都会获得视野提升", "RadarInfoLong": "(附加职业):\n雷达的箭头始终指向最近的人", @@ -1025,7 +1012,6 @@ "ProhibitedInfoLong": "(附加职业):\n受限者可以禁用通风口", "EavesdropperInfoLong": "(附加职业):\n窃听者可以阅读其他「职业/附加职业」相关的消息,比如入殓师或侦探", "ApocalypseInfoLong": "(灾厄职业):\n灾厄职业的成员是一个单独的团队,他们一起工作并获胜。 如果游戏中有多个灾厄职业的玩家,他们可以看到彼此的职业。\n取决于房主的设置,灾厄职业可以赌人或被赌。", - "RevenantInfoLong": "(中立阵营):\n荒野猎人的目标是被杀。如果你被杀,你将夺走该带刀玩家的职业并杀掉这个带刀玩家。在你被杀之前,你无法获胜。\n\n注意,荒野猎人的能力只有在被直接击杀时才会生效。", "ShowTextOverlay": "文本覆盖(小字显示)", "Overlay.GuesserMode": "猜测模式", "Overlay.NoGameEnd": "测试模式", @@ -1039,8 +1025,6 @@ "AbilityUseLimit": "初始技能数量", "AbilityInUse": "技能已生效", "AbilityExpired": "技能已结束,剩余{0}次技能", - "RevenantTargeted": "你的身份已模仿为{0}", - "RevenantCanCopyAddons": "可以窃取附加职业", "ShowArrows": "指向尸体的箭头", "ArrowDelayMin": "箭头显示最短延迟时间", "ArrowDelayMax": "箭头显示最长延迟时间", @@ -1173,7 +1157,7 @@ "FixKillCooldownValue": "初始击杀冷却时间", "OverclockedReduction": "击杀冷却减少", "GhostCanSeeOtherRoles": "幽灵可见他人职业", - "PreventSeeRolesImmediatelyAfterDeath": "Prevent seeing other's roles immediately after death", + "PreventSeeRolesImmediatelyAfterDeath": "阻止在死后立刻看到他人职业", "GhostCanSeeOtherVotes": "幽灵可见投票情况", "GhostCanSeeDeathReason": "幽灵可以看见死因", "GhostIgnoreTasks": "幽灵没有任务", @@ -1370,8 +1354,6 @@ "ShieldedCanUseKillButton": "受保护玩家可以使用能力/击杀按钮", "PlayerIsShieldedByGame": "玩家受到游戏的保护!", "LegacyNemesis": "使用旧版本", - "LegacyParasite": "使用旧版本", - "LegacyTraitor": "使用旧版本", "ArsonistKeepsGameGoing": "当纵火犯在场时,游戏不会结束", "ArsonistCanIgniteAnytime": "可随时点燃", "ArsonistMinPlayersToIgnite": "点火所需的最小浇油量", @@ -1514,18 +1496,6 @@ "SheriffCanKillSeparately": "单独设定", "In%team%": "(%team%阵营)", "SheriffMisfireKillsTarget": "误杀好人的同时击杀目标", - "BlackHolePlaceCooldown": "黑洞放置冷却时间", - "BlackHoleDespawnMode": "黑洞消失模式", - "BlackHoleDespawnTime": "黑洞消失后的时间", - "Abyssbringer.Suffix": "<#00ffa5> {0} 吞噬的玩家数量<#00ffa5>活跃的黑洞:\\n{1}", - "Abyssbringer.Suffix.BlackHole": "<#00ffa5>{0}: {1}", - "BlackHoleMovesTowardsNearestPlayer": "黑洞向最近的玩家移动", - "BlackHoleMoveSpeed": "黑洞移速", - "BlackHoleRadius": "黑洞范围半径", - "AfterTime": "一段时间后", - "After1PlayerEaten": "1名玩家被吞噬后", - "AfterMeeting": "会议之后", - "None": "无", "SheriffShotLimit": "执法次数上限", "SheriffCanKillAllAlive": "全员存活时可以执法", "SheriffCanKillCharmed": "可以执法被魅惑的玩家", @@ -1542,15 +1512,12 @@ "RebirthUses": "重生次数", "RebirthCountVotes": "只有投票给他们的玩家才能重生", "RebirthFailed": "啊,真不幸,你们没有找到可以交换身体的灵魂", - "FireworkerCooldown": "放置黑洞冷却时间", "ReverieIncreaseKillCooldown": "增加击杀冷却时间", "ReverieMaxKillCooldown": "最大击杀冷却时间", "ReverieMisfireSuicide": "在达到最大击杀冷却时间时误杀", "ReverieResetCooldownMeeting": "会议后重置击杀冷却时间", "ConvertedReverieKillAll": "非船员阵营的遐想者可以随意击杀并不受影响", "VigilanteNotify": "你变成了你发誓要摧毁的东西", - "DictatorChangeCommandToExpel": "独裁者使用指令驱逐玩家,而不是投票", - "DictatorExpelSelf": "我嘞个骚刚啊!不是,哥们,你真的想自我驱逐吗?", "DoctorTaskCompletedBatteryCharge": "完成任务增加的设备充能数", "SnitchEnableTargetArrow": "完成任务后显示箭头指向所有目标", "SnitchCanGetArrowColor": "对不同阵营的目标显示不同颜色的箭头", @@ -1624,6 +1591,7 @@ "TimeThiefDecreaseMeetingTime": "每次击杀缩短的会议时间", "TimeThiefLowerLimitVotingTime": "存活时会议时间下限", "TimeThiefReturnStolenTimeUponDeath": "死亡后会议时间重置", + "TimeThiefMaxTimeOnAdmired": "蚀时者被仰慕后,允许延长的最大会议时间", "EvilTrackerCanSeeKillFlash": "内鬼进行击杀时可见击杀闪光", "EvilTrackerCanSeeLastRoomInMeeting": "可以看见船员的位置", "EvilTrackerTargetMode": "追踪模式", @@ -1631,7 +1599,6 @@ "EvilTrackerTargetMode.OnceInGame": "仅限一次", "EvilTrackerTargetMode.EveryMeeting": "每次会议", "EvilTrackerTargetMode.Always": "永久显示", - "ScavengerHasCustomDeathReason": "启用自定义死因", "EvilHackerCanSeeDeadMark": "可以看到尸体的位置", "EvilHackerCanSeeImpostorMark": "可以看到其他内鬼的位置", "EvilHackerCanSeeKillFlash": "内鬼阵营进行击杀时可见击杀闪光", @@ -1864,21 +1831,13 @@ "Jackal_SidekickCountMode_Jackal": "豺狼", "Jackal_SidekickCountMode_Original": "原始阵营", "Jackal_SidekickAssignMode": "跟班分配模式", - "Jackal_SidekickAssignMode_SidekickAndRecruit": "当选择跟班失败时选择招募", + "Jackal_SidekickAssignMode_SidekickAndRecruit": "跟班+招募的", "Jackal_SidekickAssignMode_Sidekick": "只有跟班", - "Jackal_SidekickAssignMode_Recruit": "只有招募", + "Jackal_SidekickAssignMode_Recruit": "只有招募的", + "JackalWinWithSidekick": "豺狼可以和跟班一起获胜", "Jackal_SidekickCanKillSidekick": "跟班可以击杀其他跟班", "Jackal_SidekickCanKillJackal": "跟班可以击杀豺狼", - "Jackal_RecruitFailed": "您不能招募这位玩家!", "JackalCanKillSidekick": "豺狼可以杀死跟班", - "Jackal_SidekickCanKillWhenJackalAlive": "跟班可以在豺狼存活时进行击杀", - "Jackal_SidekickTurnIntoJackal": "跟班会在豺狼死后变成新豺狼", - "Jackal_RestoreLimitOnNewJackal": "当跟班成为新豺狼时,重置招募次数限制", - "Jackal_OnBecomeNewJackalMeeting": "老豺狼 {0}已经逝去\n你被选为新豺狼\n齐心协力,共赴胜局!", - "Jackal_OnNewJackalSelectedMeeting": "老豺狼 {0}已经逝去\n{1}被选为新豺狼\n齐心协力,共赴胜局!", - "Jackal_BecomeNewJackal": "老豺狼已经逝去,你成为了新豺狼!", - "Jackal_OnNewJackalSelected": "老豺狼已经逝去,请帮助新豺狼{0}!", - "Jackal_BossIsDead": "哦,不!豺狼老大死了!", "CoronerArrowsPointingToDeadBody": "指向尸体的箭头", "CoronerLeaveDeadBodyUnreportable": "验尸官无法报告尸体", "CoronerInformKillerBeingTracked": "通知带刀玩家被跟踪了", @@ -1916,9 +1875,6 @@ "VipTag": "VIP ★", "ApplyVipList": "申请VIP名单", "AllowSayCommand": "允许协管使用/say指令", - "AllowStartCommand": "允许协管使用/start指令", - "StartCommandMinCountdown": "/start 指令的最小倒计时", - "StartCommandMaxCountdown": "/start 指令的最大倒计时", "KickCommandDisabled": "踢出指令已禁用", "KickCommandNoAccess": "你无法使用踢出指令\n因为你没有权限", "KickCommandInvalidID": "指定的玩家ID无效\n请使用“/kick [玩家编号] [理由] 踢出该玩家”\n例子:- /kick 5 不遵守规则", @@ -1951,11 +1907,6 @@ "WarnCommandNoAccess": "你无法使用警告指令\n因为你没有权限", "WarnCommandInvalidID": "指定的玩家ID无效\n请使用“/warn [玩家编号] [理由] 警告该玩家”\n例子:- /warn 5 在驱逐时对话", "WarnCommandWarnHost": "你不能警告房主", - "StartCommandNoAccess": "你无法使用开始指令\n因为你没有权限", - "StartCommandDisabled": "开始指令已禁用", - "StartCommandCountdown": "错误\n\n游戏已经开始!", - "StartCommandStarted": "游戏已由 {0} 开始 !", - "StartCommandInvalidCountdown": "错误\n\n倒计时必须在 {0} 和 {1}之间!", "WarnCommandWarnMod": "你不能警告其他协管玩家", "WarnCommandWarned": "已被警告。我们不会再发出警告,继续犯规会被惩罚。\n ", "WarnExample": "请使用 “/warn [玩家编号] [理由] 警告该玩家”\n例子:-\n /warn 5 在驱逐时对话", @@ -1983,7 +1934,6 @@ "DeathReason.Quantization": "量子化", "DeathReason.Overtired": "猝死", "DeathReason.Ashamed": "卷死", - "DeathReason.Consumed": "吞噬", "DeathReason.PissedOff": "气死", "DeathReason.Dismembered": "肢解", "DeathReason.LossOfHead": "绞杀", @@ -2007,8 +1957,6 @@ "DeathReason.Starved": "饥饿", "DeathReason.Equilibrium": "平衡", "DeathReason.Sacrificed": "献身", - "DeathReason.Electrocuted": "触电", - "DeathReason.Scavenged": "已抹除", "OnlyEnabledDeathReasons": "仅启用死亡原因", "Alive": "存活", "Disconnected": "断连", @@ -2024,10 +1972,11 @@ "DeputyHandcuffCooldown": "手铐冷却", "DeputyHandcuffMax": "手铐最大数量", "DeputyHandcuffedPlayer": "你给目标铐上了手铐!", - "HandcuffedByDeputy": "你被铐上了手铐!", - "DeputyInvalidTarget": "目标不能被铐手铐", + "HandcuffedByDeputy": "你刚刚被戴手铐了!\n现在你破坏了手铐,过会就能杀入了。", + "DeputyInvalidTarget": "目标已经被戴手铐了", + "HandcuffBrokenAfterMeeting": "在会议结束后移除所有手铐", "DeputyHandcuffText": "手铐", - "DeputyHandcuffCDForTarget": "带手铐玩家的击杀冷却时间", + "DeputyHandcuffCDForTarget": "带手铐玩家下一次的击杀cd", "RejectShapeshift.AbilityWasUsed": "使用技能", "EscapisMtarkedPosition": "你标记了自己的位置", "InvestigateCooldown": "探查冷却时间", @@ -2074,7 +2023,6 @@ "Command.dump": "→ 将游戏运行日志输出到桌面", "Command.death": "→ 显示你的死亡信息", "Command.icons": "
╳ - 玩家被勒索者标记,会议期间无法发言。\n
☆ - 被舰长用来标记他们自己。只有船员阵营能看到舰长的星星。\n
乂 - 该玩家被巫师施邪咒,如果巫师在会议结束前没有被击杀或驱逐,该玩家将死亡。\n
♦ - 由律师、刽子手或赌徒使用。\n
♥ - 由恋人或浪漫主义者使用。\n
✚ - 医生用来标记他们的目标。\n
⦿ - 该玩家与决斗者正在进行决斗。\n
!? - 该玩家被测验长标记,必须正确回答问题才能活下去。\n
☜ - 由薛定谔的猫用来标记他们的队友。\n
◈ - 该玩家被裹尸布标记,如果裹尸布在会议结束前没有被击杀或驱逐,该玩家将死亡。\n
⚠ - 该玩家是已完成任务的告密者或至日者。\n
★ - 由大明星、网络员或展现者使用。\n
† - 该玩家被咒杀,如果女巫在会议结束前没有被杀死,该玩家将死亡。\n
∇ - 由神风特攻队用来标记他们的目标。\n
■ - 由球形闪电用来量子轰炸。\n
⊠ - 由狱卒使用来标记被监禁的玩家。\n
● - 由面包师使用来标记谁有面包。\n
♠ - 由灵魂收集者使用来标记他们正在预测谁的死亡。\n
⦿ - 由瘟疫使者使用来标记他们已经使谁染上了瘟疫。", - "Command.start": "[Seconds] → 开始游戏", "Command.iconinfo": "→ 显示会议中图标的信息", "Command.iconhelp": "→ 向每个人显示会议中图标的信息", "Command.Poll": "→ 发起投票,最多5个选项", @@ -2087,7 +2035,6 @@ "ShowMadmatesInLeftCommand": "显示剩余叛徒阵营人数(包括附加职业)", "ShowApocalypseInLeftCommand": "显示<#ff174f>灾厄中立", "SeeEjectedRolesInMeeting": "查看驱逐时的会议身份", - "ThankYouForUsingTOHE": "感谢您使用 TOHE!", "SkillUsedLeft": "你发动技能召开了会议。\n你的技能剩余使用次数:", "NemesisDeadMsg": "黑手党的死亡,意味着复仇的开始\n请使用/rv + [玩家编号] 以击杀指定玩家\n你可以在玩家名字前看到该玩家的编号\n或输入/rv获取玩家编号列表", "NemesisAliveKill": "黑手党的复仇只能在死亡后发动", @@ -2107,7 +2054,6 @@ "GuessNotifiedBait": "大明星才不会和你赌博,选个别的目标吧?", "GuessGM": "能想出这个也是把你闲的", "GuessGuardianTask": "你无法赌死已经完成了任务的守护者", - "GuardianCantKilled": "你无法击杀已经完成了任务的守护者", "GuessMarshallTask": "你无法赌死已经完成了任务的展现者", "GuessObviousAddon": "抱歉,无法猜测明显的附加职业", "GuessAdtRole": "很抱歉,该房设置不允许猜测附加职业", @@ -2163,7 +2109,6 @@ "BecomeMadmateCuzMadmateMode": "你因死亡成为叛徒", "CleanerCleanBody": "目标的尸体已被清理", "QuickShooterStoraging": "子弹储存成功", - "QuickShooterFailed": "您仍处于冷却状态。", "PoisonerTargetDead": "目标已死亡", "HexesLookLikeSpells": "妖术显示为符咒", "HexButtonText": "妖术", @@ -2322,7 +2267,6 @@ "Message.YTPlanNotice": "提示:该房间启用了「创作者素材保护计划」,房主可以指定自己的职业。\n该功能仅允许创作者用于获取视频素材,如遇滥用情况,请退出游戏或举报。\n当前创作者认证:", "Message.OnlyCanBeUsedByHost": "错误\n该指令只能由房主使用", "Message.MaxPlayers": "最大玩家数量设置为", - "Message.MaxPlayersFailByRegion": "无法设置最大玩家数量:原版服务器最多支持15位玩家", "Message.GhostRoleInfo": "幽灵职业信息\n关于幽灵职业的一些信息…\n幽灵职业会对游戏产生巨大影响,因此如果您不熟悉幽灵职业,不建议在少人房间中使用。如果描述中没有明确说明,守护按钮就是幽灵的技能按钮 :)\n出现:\n幽灵职业只有在死亡后才会出现,阵营中最先死亡的人会获得幽灵职业(除中立阵营)\n注:如果您之前的职业没有任务(如警长),则变成幽灵职业的您不需要为任务胜利而去做任务(前提是你没任务)", "ApocalypseInfoTitle": "灾厄中立的信息:", "Message.ApocalypseInfo": "<#ff174f>灾厄阵营中每个职业都有其自己的目标,以实现转变\n<#2B0804>转变后的<#ff174f>灾厄职业将对游戏产生巨大影响,并且它们将不会死亡(除了被投票淘汰外),但所有人都会被通知到它们已经发生了转变。\n职业:<#e5f6b4>瘟疫使者,<#A675A1>灵魂收集者,<#bf9f7a>面包师,<#cc0044>狂战士\n转变后:<#343136>瘟疫,<#644661>死亡,<#83461c>饥荒,<#2B0804>战争者\n灾厄阵营玩家可以看到彼此的职业和技能图标。\n就像带刀中立一样,灾厄玩家也会让游戏继续下去,玩得开心!", @@ -2454,6 +2398,7 @@ "LastResult": " ★ 游戏结果", "LastEndReason": " ★ 结束原因", "KillLog": "击杀日志", + "MainRoleLog": "角色转换日志", "Maximum": "最大人数", "RoleRate": "开", "RoleOn": "总是", @@ -2523,9 +2468,9 @@ "WarlockShapeshiftButtonText": "咒杀", "BountyHunterChangeButtonText": "变更", "EvilTrackerChangeButtonText": "追踪", - "RiftMakerButtonText": "Create Rift", - "AbyssbringerButtonText": "Black Hole", - "PitfallButtonText": "Set Trap", + "RiftMakerButtonText": "放置裂缝", + "AbyssbringerButtonText": "黑洞", + "PitfallButtonText": "放置陷阱", "InnocentButtonText": "栽赃", "PelicanButtonText": "吞下", "DeceiverButtonText": "贩卖", @@ -2640,7 +2585,7 @@ "NeutralRemain": "\n还剩余 {0} 个带刀中立", "OneNeutralRemain": "\n还剩余 {0} 个带刀中立", "ApocRemain": "\n还剩余 {0} 个<#ff174f>灾厄中立", - "GameOverReason.HumansByVote": "内鬼被驱逐", + "GameOverReason.HumansByVote": "所有的内鬼和带刀中立都被驱逐了", "GameOverReason.HumansByTask": "船员完成了任务", "GameOverReason.HumansDisconnect": "船员断线", "GameOverReason.ImpostorByVote": "船员被驱逐", @@ -2730,9 +2675,8 @@ "DeathMeetingTimeIncrease": "当死亡存在时,会议时间延长", "SoulCollectorMeetingDeath": "你的目标在会议中死亡。你获得了一个灵魂。", "SoulCollectorKillButtonText": "预言", - "SoulCollectorHasImpostorVision": "灵魂收集者拥有内鬼视野", "ApocalypseIsNigh": "【 ★ 末日即将来临 ★ 】", - "ApocalypseImmune": "该职业免疫!", + "ApocalypseImmune": "这个玩家免疫,因为它们是无敌的!", "BakerToFamine": "你成为了饥荒!!!!", "BakerTransform": "面包师转变成了饥荒,灾厄的骑士,饥荒开始了!", "BakerAlreadyBreaded": "那个玩家已经有面包了!", @@ -2741,15 +2685,13 @@ "BakerBreadNeededToTransform": "饥荒所需的面包数量", "BakerCantBreadApoc": "你不能给其他灾厄成员面包!", "BakerKillButtonText": "面包", - "BakerUnshiftButtonText": "切换面包", "BakerRevealBread": "揭示", "BakerRoleblockBread": "职业封锁", "BakerBarrierBread": "屏障", "BakerCurrentBread": "当前面包: ", "BakerSwitchBread": "面包切换到: ", - "BakerCanVent": "面包师可以使用通风口", + "BakerCanVent": "面包师可以使用通风口", "BakerBreadGivesEffects": "面包具有额外的效果", - "BakerTransformNoMoreBread": "面包师在没有足够的面包时转变", "FamineKillButtonText": "饥饿", "FamineStarveCooldown": "饥荒的饥饿冷却", "FamineCantStarveApoc": "你不能饿死其他灾厄成员!", @@ -2796,7 +2738,6 @@ "GodfatherTargetCountMode": "带刀玩家变成", "GodfatherCount_Refugee": "逃亡者", "GodfatherCount_Madmate": "叛徒", - "GodfatherRefugeeMsg": "你已被教父招募!", "MissChance": "错失概率", "IncreaseByOneIfConvert": "如果船员被更改,最大击杀数会增加+1", "HawkMissed": "你的欧气似乎不太行呢,LOL", @@ -2829,7 +2770,6 @@ "BerserkerToWar": "你成为了战争者!!!!", "BerserkerTransform": "狂战士变成了战争者,灾厄的骑士,大喊大叫,放出战争的猛犬!!!!!!", "WarKillCooldown": "战争者的击杀冷却时间", - "BerserkerCanKillTeamate": "可以击杀其他灾厄中立成员", "BlackmailerSkillCooldown": "勒索冷却时间", "BlackmailerMax": "目标最大说话次数", "BlackmailerDead": "警告!玩家{0}被勒索者勒索了!", @@ -2919,8 +2859,6 @@ "RememberedPursuer": "你记得你是一个起诉人!", "RememberedFollower": "你记得你是一个赌徒!", "RememberedAmnesiac": "你没有记住自己的身份lol", - "AmnesiacRemembered": "你记得你是个{0}!", - "ReportWhenFailedRemember": "当回忆失败时报告尸体", "RememberedImitator": "你记得自己是个效仿者", "RememberedImpostor": "你记得你是个内鬼!", "RememberedCrewmate": "你记得你是个船员", @@ -2941,7 +2879,7 @@ "BanditStealCooldown": "偷窃冷却时间", "DoppelMaxSteals": "最大偷取数量", "DoppelCurrentVictimCanSeeRolesAsDead": "最后一名受害者可以像幽灵一样看到存活玩家的职业和附加职业", - "NecromancerRevengeTime": "亡灵魔法时间", + "NecromancerRevengeTime": "复仇时间上限", "NecromancerRevenge": "你有{0}秒的时间击杀{1}", "NecromancerSuccess": "亡灵魔法完成 你苟活了下来", "NecromancerHide": "通风口已关闭,请躲避亡灵巫师", @@ -3146,7 +3084,7 @@ "DollMaster_PossessedTarget": "附身目标", "DollMaster_CannotPossessImpTeammate": "无法附身队友", "DollMaster_CouldNotSwapWithTarget": "无法附身玩家", - "DollMaster_CanNotSwapWithDeadTarget": "附身死亡玩家是不可能的", + "DollMaster_CanNotSwapWithDeadTarget": "不能附身已经死亡的玩家", "DollMaster_MainBody": "主体", "DollMaster_Doll": "玩偶", "DollMaster_UnableToUseAbility": "无法对玩家使用技能", @@ -3164,7 +3102,7 @@ "PitfallTrapCauseVisionTime": "陷阱造成的玩家视野大小的持续时间", "PitfallTrap": "你掉进了一个陷阱!", "ConsigliereDivinationMaxCount": "最大显示次数", - "RitualMaxCount": "最大显示次数", + "RitualMaxCount": "最大复活数量", "CleanserHideVote": "隐藏清洗者的投票", "OracleSkillLimit": "最大使用量", "OracleHideVote": "隐藏神谕的投票", @@ -3334,12 +3272,9 @@ "PixieTargetAlreadySelected": "目标已选定", "PixieButtonText": "标记", "PlagueBearerCooldown": "瘟疫使者冷却时间", - "PlagueBearerCanVent": "可以使用通风口", - "PlagueBearerHasImpostorVision": "拥有内鬼视野", "PestilenceCooldown": "瘟疫击杀冷却", "PestilenceCanVent": "瘟疫可以使用通风口", "PestilenceHasImpostorVision": "瘟疫有内鬼视野", - "PestilenceKillGuessers": "击杀试图猜测瘟疫的玩家", "PlagueBearerAlreadyPlagued": "玩家已经受到瘟疫使者攻击", "PlagueBearerToPestilence": "你变成了瘟疫使者!!", "GuessPestilence": "你只是想猜测瘟疫!\n抱歉,瘟疫杀死了你", @@ -3383,7 +3318,6 @@ "EveryoneCanKnowMini": "所有人都能看到迷你船员", "CanBeEvil": "可以成为坏迷你船员", "EvilMiniSpawnChances": "坏迷你船员的出现概率", - "EvilMiniCanBeGuessed": "坏迷你船员可以在18岁之前被赌", "GuessMini": "球球你放过孩子吧", "GrowUpDuration": "长大所需要的时间(秒)", "MajorCooldown": "长大后的击杀冷却时间", @@ -3525,7 +3459,6 @@ "WinnerRoleText.Doppelganger": "替身者胜利!", "WinnerRoleText.Quizmaster": "测验长胜利", "WinnerRoleText.Agitater": "煽动者胜利!", - "WinnerRoleText.Shocker": "震击者胜利!", "AdditionalWinnerRoleText.Sidekick": "跟班", "AdditionalWinnerRoleText.Taskinator": "任务执行者胜利!", "AdditionalWinnerRoleText.Opportunist": "投机者", @@ -3611,7 +3544,7 @@ "SolsticerOnMeeting": "因为太多人嗝屁了,你感到身上的负担更重了。\n下一轮你将额外获得{0}个短任务", "SolsticerTitle": "至日者", "GuessSolsticer": "你不能猜测神的信徒!", - "ExpelSolsticer": "你不能驱逐神的信徒!", + "VoteSolsticer": "你不能票出神的信徒!", "SolsticerTasksReset": "你的任务惨遭重置了", "SolsticerMisGuessed": "你刚刚猜错了!所以你不能再猜了", "SolsticerGuessMax": "因为你已经猜错了,所以你不能再猜了", @@ -3712,19 +3645,6 @@ "MinionAbilityTime": "技能持续时间", "Minion_Blind": "失明", "Evader_ChanceNotExiled": "概率不被驱逐", - "ShockerAbilityCooldown": "技能冷却时间", - "ShockerAbilityDuration": "技能持续时间", - "ShockerAbilityPerRound": "每轮的技能", - "ShockerShockInVents": "震击通风口内的人", - "ShockerAbilityResetAfterMeeting": "会议后重置标记的房间", - "ShockerOutsideRadius": "外部任务震击半径(不在房间内)", - "ShockerCanShockHimself": "可以震击自己", - "ShockerImpostorVision": "震击者有内鬼视野", - "ShockerIsShocking": "你已经准备好震击了!", - "ShockerAbilityActivate": "震击开始!", - "ShockerAbilityDeactivate": "技能失效", - "ShockerVentButtonText": "震击", - "ShockerRoomMarked": "标记房间", "EavesdropperMsgTitle": "你发现了一个秘密", "EavesdropPercentChance": "概率偷听", "ChiefOfPoliceSkillCooldown": "招募警长的冷却时间", @@ -3736,4 +3656,4 @@ "PolicPreventRecruitNonKiller": "防止招募没有击杀按钮的玩家", "PolicSuidiceWhenTargetNotKiller": "招募非带刀玩家或非船员时自杀", "PolicPassConverted": "可以将已转换的附加职业转移给警长" -} +} \ No newline at end of file diff --git a/Resources/Lang/zh_TW.json b/Resources/Lang/zh_TW.json index d7961a924..eb4bec7a4 100644 --- a/Resources/Lang/zh_TW.json +++ b/Resources/Lang/zh_TW.json @@ -20,8 +20,6 @@ "SubText.Neutral": "不屬於其他陣營的獨立陣營", "SubText.Apocalypse": "與你的團隊一起變得勢不可擋", "SubText.Madmate": "幫助偽裝者陣營", - "SubText.Lovers": "你墜入了愛河", - "SubText.Egoist": "搶走你的陣營的勝利", "TypeImpostor": "偽裝者", "TypeCrewmate": "船員", "TypeNeutral": "中立", @@ -31,9 +29,6 @@ "TeamNeutral": "中立陣營", "TeamCrewmate": "船員陣營", "TeamMadmate": "叛徒陣營", - "TeamLovers": "戀人陣營", - "TeamEgoist": "利己主義陣營", - "TeamApocalypse": "災厄陣營", "YouAreCrewmate": "你是船員", "YouAreImpostor": "你是偽裝者", "YouAreNeutral": "你是中立", @@ -225,7 +220,6 @@ "TaskManager": "任務管理員", "Witness": "目擊者", "Swapper": "換票師", - "ChiefOfPolice": "警察局長", "NiceMini": "好迷你船員", "Mini": "迷你船員", "Spy": "間諜", @@ -254,7 +248,6 @@ "Stalker": "潛藏者", "Workaholic": "工作狂", "Solsticer": "至聖者", - "Abyssbringer": "深淵使者", "Collector": "集票者", "Provocateur": "挑釁者", "BloodKnight": "嗜血騎士", @@ -287,7 +280,7 @@ "Vulture": "禿鷲", "Taskinator": "搗蛋鬼", "Benefactor": "慈善家", - "Medusa": "美杜莎", + "Medusa": "梅杜莎", "Spiritcaller": "靈魂召喚者", "Amnesiac": "失憶者", "Imitator": "效顰者", @@ -361,7 +354,7 @@ "Autopsy": "驗屍", "Loyal": "忠誠", "EvilSpirit": "惡靈", - "Recruit": "被招募", + "Recruit": "狼化", "Admired": "被仰慕", "Glow": "發光", "Radar": "雷達", @@ -393,8 +386,6 @@ "Sloth": "樹懶", "Prohibited": "受限者", "Eavesdropper": "竊聽者", - "Shocker": "電擊者", - "Revenant": "返生者", "BracketAddons": "附加職業使用括弧顯示", "EngineerTOHEInfo": "使用通風管來抓到偽裝者", "ScientistTOHEInfo": "隨時隨地存取心電圖", @@ -513,7 +504,7 @@ "PacifistInfo": "何必打打殺殺呢?", "RebirthInfo": "重獲新生", "MonarchInfo": "給予你的騎士額外的票數!", - "AbyssbringerInfo": "放置黑洞!", + "AbyssbringerInfo": "創造黑洞", "SpurtInfo": "像隻兔子般敏捷", "StealthInfo": "在黑暗中殺人", "PenguinInfo": "把他們通通綁起來!", @@ -538,7 +529,7 @@ "AdmirerInfo": "選擇一名玩家加入你的陣營", "TimeMasterInfo": "Za Warudo!", "CrusaderInfo": "別怕,我會幫你報仇的", - "AltruistInfo": "復活玩家", + "AltruistInfo": "復活死去的玩家\n用管道來在報告與復活之間切換", "ReverieInfo": "殺死你的敵人可以將冷卻縮短", "LookoutInfo": "看穿一切", "TelecommunicationInfo": "你是不是在使用設備?", @@ -547,7 +538,6 @@ "WitnessInfo": "我好像目擊了什麼", "GhastlyInfo": "陰魂不散的操控別人!", "SwapperInfo": "交換兩名玩家的票數", - "ChiefOfPoliceInfo": "雇傭警長來為船員服務!", "NiceMiniInfo": "在你長大之前沒有人能傷害你", "ArsonistInfo": "燒吧,燒吧,燃燒吧", "PyromaniacInfo": "澆油並殺光所有人", @@ -615,7 +605,7 @@ "ShroudInfo": "感受被遮蓋的恐懼吧", "WerewolfInfo": "凡是我走過之處,必定橫屍遍野", "ShamanInfo": "把所有攻擊轉移", - "SeekerInfo": "小目標,你在哪裡呀?", + "SeekerInfo": "跟你的目標玩捉迷藏\n你的目標會有★標記", "PixieInfo": "給他們貼上標籤,裝進袋子,然後逐出他們!", "OccultistInfo": "殺人並詛咒你的敵人", "SchrodingersCatInfo": "在開蓋前你不知道我是生是死", @@ -708,8 +698,6 @@ "SlothInfo": "跟某家遊戲公司一點關係都沒有", "ProhibitedInfo": "你無法進入某些通風口", "EavesdropperInfo": "隔牆有耳", - "ShockerInfo": "用雷霆為船員降下審判!", - "RevenantInfo": "偷走殺了你的兇手的職業", "EngineerTOHEInfoLong": "(船員陣營):\n工程師可以在通訊未被破壞時使用通風口。", "ScientistTOHEInfoLong": "(船員陣營):\n科學家擁有隨身心電圖,有助於辨識是否為自行舉報,屍體死了多久等等...", "NoisemakerTOHEInfoLong": "(船員陣營):\n警示者死亡時會發出聲音以及提示,這樣船員們就可以當場抓獲擊殺你的人。", @@ -781,11 +769,11 @@ "LurkerInfoLong": "(偽裝者陣營):\n策畫者可以通過跳管道來減少殺人冷卻數秒,當他殺人時,他的冷卻將回復至預設值。", "VisionaryInfoLong": "(偽裝者陣營):\n幻想家可以在會議上看到存活玩家的陣營:\n- 紅色的名字代表偽裝者陣營\n- 藍色的名字代表船員陣營\n- 灰色的名字代表中立陣營", "PlagueDoctorInfoLong": "(中立陣營):\n疫醫的目標是讓所有活著的玩家被感染。\n疫醫可以選擇一名玩家作為感染源,之後任何靠近感染源範圍內一段時間的人也會受到感染並成為感染源。\n感染進度是累積的,不會在遠離後或者會議後重置。", - "RefugeeInfoLong": "(叛徒陣營):\n逃亡者可能為:\n -記起了偽裝者或叛徒的失憶者\n -殺死了懸賞者的懸賞目標的兇手\n -偽裝者伴侶死亡的暗戀者\n -效顰了偽裝者的效顰者\n\n現在你的任務是幫助偽裝者殺死所有船員。", + "RefugeeInfoLong": "(叛徒陣營):\n逃亡者原本可能為失憶者報告了偽裝者的屍體,或是殺死了懸賞者的目標的兇手\n如果你符合以上條件兩者之一,你就會加入偽裝者陣營並跟隨他們獲勝。", "UnderdogInfoLong": "(偽裝者陣營):\n潛伏者只能在場上剩下一定數量的玩家之後才可以開始殺人。", "ConsigliereInfoLong": "(偽裝者陣營):\n軍師可以嘗試對一名玩家使用殺人鍵來揭示他的身分。\n如果揭示技能用完,殺人為正常殺人。\n\n點一下: 揭示身分&點兩下: 殺人", "LudopathInfoLong": "(偽裝者陣營):\n賭博者的殺人冷卻是隨機的,最小為1秒,最大為預設殺人冷卻。", - "GodfatherInfoLong": "(偽裝者陣營):\n懸賞者可以在會議上投給一名玩家作為目標,在下一輪中,如果目標被殺,則兇手變為逃亡者或叛徒。", + "GodfatherInfoLong": "(偽裝者陣營):\n懸賞者可以在會議上投給一名玩家作為目標,在下一輪中,如果目標被殺,則兇手變為逃亡者。", "ChronomancerInfoLong": "(偽裝者陣營):\n天文學家有一個充電進度條,當電量到達100%後,就會在下次擊殺時進入大屠殺模式,此時可以不斷地進行擊殺直到電量耗盡。在其他情況下,你的擊殺冷卻是正常的。", "PitfallInfoLong": "(偽裝者陣營):\n設陷者可以通過變形來將一定區域內設下陷阱,當有玩家進入此區域會在短時間內無法移動,並且視野受到影響。", "EvilMiniInfoLong": "(偽裝者陣營):\n壞迷你船員在成年前免疫所有攻擊,並且殺人冷卻很長,當壞迷你船員成年後,殺人冷卻會變的極低。", @@ -821,7 +809,7 @@ "GrenadierInfoLong": "(船員陣營):\n擲彈兵可以通過使用通風管來使用閃光彈,閃光彈會導致偽裝者陣營的玩家失去大部分的視野(根據房主設定,效果可能影響到中立玩家),閃光彈生效或失效時擲彈兵會看到自己身上有盾牌破碎的效果作為提示。當擲彈兵成為叛徒時,閃光彈將只對船員生效。", "MedicInfoLong": "(船員陣營):\n軍醫可以通過殺人鍵來發給某位玩家一個護盾,若護盾發放成功軍醫自己身上會出現盾牌破碎的效果作為提示,同時目標名字旁邊會出現藍色的「✚」(只有軍醫可以看到),剩餘的護盾數量會顯示在名字旁,每位玩家最多只能持有來自軍醫的一個護盾,根據房主設定,被上盾的人或許可以知道自己被上盾(名字旁有藍色的「✚」)", "FortuneTellerInfoLong": "(船員陣營):\n占卜師在會議上投票給某一個人時可以獲得該玩家的相關訊息,該訊息與玩家的主職業關聯。若占卜師完成所有任務,則占卜師將可以直接知道該玩家的職業。占卜師每次會議只能占卜一次,占卜次數根據房主設定。\n請注意: 當\"在占卜師的提示中隨機顯示部分已開啟的職業\"開啟時,將無法多次占卜同個玩家。", - "JudgeInfoLong": "(船員陣營):\n法官在會議時可以審判某位玩家,若該玩家的職業為邪惡方職業則殺死該目標(部分邪惡方是否可以審判視房主設定),錯誤則會自殺,\n審判指令為:/tl [玩家ID] (這是L不是i喔~)\n你可以在玩家名字前看到該玩家的ID,或使用/id來查詢所有玩家的編號,當法官成為叛徒時可以隨意審判。", + "JudgeInfoLong": "(船員陣營):\n法官在會議時可以審判某位玩家,若該玩家的職業為邪惡方職業則殺死該目標(部分邪惡方是否可以審判視房主設定),錯誤則會自殺,\n審判指令為:/tl [玩家ID] (這是L不是i喔~)\n你可以在玩家名字前看到該玩家的ID,或使用/id來查詢所有玩家的編號,當法官成為叛徒時可以隨意審判。\n會議上顯示的技能次數代表該次會議可以審判的次數,會議外的技能次數則表示該局遊戲可以審判的次數", "MorticianInfoLong": "(船員陣營):\n殯葬師可以看到指向所有屍體的箭頭,當殯葬師報告屍體時可以在會議上得知被害者生前最後一個接觸的玩家。請注意: 殯葬師不會成為膽小鬼。", "MediumInfoLong": "(船員陣營):\n當場上有玩家被殺死,通靈師會收到提示。當每次報告屍體時通靈師可以與被報告的屍體建立聯繫(只有被報告的而不是全部被害者),在此次會議結束前,被害者擁有一次機會回答通靈師的問題,只能回答是或否。請注意: 通靈師不會成為膽小鬼。", "ObserverInfoLong": "(船員陣營):\n窺視者可以在第一次會議後看到所有玩家的碎盾動畫(包括技能的碎盾提示)。", @@ -833,7 +821,7 @@ "MerchantInfoLong": "(船員陣營):\n商人每完成一個任務就會向隨機玩家出售隨機的附加職業,每次出售都可以獲得金錢,如果商人有一定的錢,商人可以通過賄賂兇手保證自己不被殺害,被賄絡的玩家將無法再次殺害殺人,但商人無法知道誰嘗試殺害他。", "RetributionistInfoLong": "(船員陣營):\n報應者可以在死後讓一定數量(數量依據房主設定) 的玩家受到報應。\n\n報應指令為: /ret [playerID]", "HawkInfoLong": "(船員陣營 [幽靈]):\n獵鷹可以使用守護鍵來殺死一定數量的玩家,但是有機率擊殺失敗(機率由房主設定)", - "DeputyInfoLong": "(船員陣營):\n捕快可以嘗試對一名玩家使用殺人鍵以讓他戴上手銬,被戴上手銬的玩家將會重置殺人冷卻,如果被戴上手銬的玩家未持有殺人鍵,那麼手銬就會被浪費。", + "DeputyInfoLong": "(船員陣營):\n捕快可以嘗試對一名玩家使用殺人鍵以讓他戴上手銬,被戴上手銬的玩家將會在他使用殺人鍵時阻擋該操作並重置殺人冷卻,如果被戴上手銬的玩家未持有殺人鍵,那麼手銬就會被浪費。", "InvestigatorInfoLong": "(船員陣營):\n算命師可以使用殺人鍵來知道某位玩家的訊息。如果算命對象擁有殺人鍵(基於偽裝者/變形者的職業),名字將顯示為紅色。如果算命對象沒有殺人鍵(基於工程師/科學家/船員的職業),則名字顯示為淺藍色。\n請注意: 會議時看不見算命對象的名字顏色", "GuardianInfoLong": "(船員陣營):\n守護者完成任務後免疫所有攻擊。(包括被賭)", "AddictInfoLong": "(船員陣營):\n賢者可以通過使用通風口來獲得護盾,但是護盾結束後會讓賢者無法移動一段時間,並且如果賢者在通風管冷卻結束後太久沒有跳入管道,賢者將會自殺。", @@ -849,7 +837,7 @@ "AdmirerInfoLong": "(船員陣營):\n仰慕者可以通過仰慕一名玩家來讓其加入船員陣營,被仰慕的玩家將跟隨船員獲勝而不是原先的陣營。\n\n請注意: 仰慕者只能仰慕一次。", "TimeMasterInfoLong": "(船員陣營):\n時間之主使用通風口時會記錄目前所有玩家所在的位置,時間之主再次使用通風口時,所有存活的玩家都會被傳送回原先紀錄的位置,在該技能持續時間中,時間之主會獲得時間之盾,使他免於死亡。\n\n請注意: 由於技術限制,時間之主的技能不能復活死亡的玩家", "CrusaderInfoLong": "(船員陣營):\n十字軍可以嘗試對某位玩家使用殺人鍵使他成為保護目標,如果有人嘗試殺害他,則十字軍會殺死兇手。", - "AltruistInfoLong": "(船員陣營):\n殉道者可以使用«報告»鍵來犧牲自己復活死去的玩家。(可以使用跳管來切換報告模式)\n請注意: 若該玩家在死後離開遊戲,殉道者會直接報告該屍體,而不是復活。\n被復活的玩家無法報告自己的屍體。", + "AltruistInfoLong": "(船員陣營):\n殉道者可以使用«報告»鍵來犧牲自己復活死去的玩家。\n請注意: 若該玩家在死後離開遊戲,殉道者會直接報告該屍體,而不是復活。\n被復活的玩家無法報告自己的屍體。\n使用跳管來切換報告模式", "ReverieInfoLong": "(船員陣營):\n遐想者可以殺人,不過在剛開始時冷卻時間特別高,如果遐想者殺死了一名船員,則冷卻時間會增加(時間依據房主設定),反之則縮短。\n依據房主設定,遐想者在達到最大殺人冷卻後可能會誤殺,導致目標與遐想者同歸於盡。", "LookoutInfoLong": "(船員陣營):\n瞭望者可以看到每個玩家的ID,變形者顯示的是本體的ID,這表示你可以看穿變形以及隱蔽效果。", "TelecommunicationInfoLong": "(船員陣營):\n當有人使用監控,心電圖,管理室地圖,門禁日誌時,通訊員會收到通知。", @@ -872,7 +860,7 @@ "LawyerInfoLong": "(中立陣營):\n遊戲開始時律師會被分配一個目標,並在他的名字旁用「♦」標示,若目標活到最後並獲勝,則律師一同獲勝,如果目標死亡,將依據房主設定變為船員,小丑,投機主義者。\n\n請注意: 律師死亡後仍可獲勝。", "OpportunistInfoLong": "(中立陣營)\n若投機主義者活到遊戲結束時,那麼投機主義者會跟勝利方玩家一同獲勝。", "VectorInfoLong": "(中立陣營):\n當瑪利歐跳管道達到一定次數就會單獨獲勝。", - "JackalInfoLong": "(中立陣營):\n豺狼可以嘗試對一名玩家使用殺人鍵來招募跟班。 如果目標不是你可以招募的目標,要麼你的招募次數已經達到上限,或者房主不允許招募,那麼你將殺害該玩家(所以不要輕易在別人面前招募) 。 如果目標有殺人鍵並且可以招募跟班的選項為啟用,那麼他們將成為跟班。否則,如果提供跟班附加職業的選項處於開啟狀態,他們將獲得跟班附加職業。當豺狼陣營人數大於場上存活陣營的玩家數,則豺狼陣營獲勝。\n根據設定,當豺狼死亡後跟班可能會成為新的豺狼\n如果沒有跟班存活,則可能會讓被招募的玩家成為新豺狼", + "JackalInfoLong": "(中立陣營):\n豺狼可以嘗試對一名玩家使用殺人鍵來招募跟班。 如果目標不是你可以招募的目標,要麼你的招募次數已經達到上限,或者房主不允許招募,那麼你將殺害該玩家(所以不要輕易在別人面前招募) 。 如果目標有殺人鍵並且可以招募跟班的選項為啟用,那麼他們將成為跟班。否則,如果提供跟班附加職業的選項處於開啟狀態,他們將獲得跟班附加職業。當豺狼陣營人數大於場上存活陣營的玩家數,則豺狼陣營獲勝。", "GodInfoLong": "(中立陣營):\n神在開始時已經會知道所有人的職業。如果神在結束時還在場上,神會竊取勝利(其他人都會輸,只有神獲勝)", "InnocentInfoLong": "(中立陣營):\n冤罪師可以對某位玩家使用殺人鍵來栽贓他,被栽贓的目標將會立刻殺死冤罪師,如果目標在會議中被逐出(這個動作可以跨輪執行),則冤罪師獲勝。\n請注意: 小丑、暴民、冤罪師可以一同獲勝", "PelicanInfoLong": "(中立陣營):\n鵜鶘可以對某一位玩家使用殺人鍵來活吞該玩家,被活吞的玩家將會被傳送到地圖外並且無法與遊戲互動,活吞成功後鵜鶘將會看到自己身上出現盾牌破碎的效果作為提示。進入會議時將導致所有被鵜鶘吞下的玩家立刻死亡,若鵜鶘死亡或斷線,則被鵜鶘吞下的玩家將會立刻傳送到鵜鶘死亡的位置並可以再次與遊戲互動。當只剩下鵜鶘與船員陣營且鵜鶘陣營人數大於船員陣營人數,則鵜鶘獲得勝利。\n請注意: 鵜鶘活吞玩家不是正常的殺人方式,因此老兵、保鑣等技能不會生效。", @@ -884,14 +872,14 @@ "SolsticerInfoLong": "(中立陣營):\n至聖者為無敵狀態,並且需要在一輪遊戲中完成所有的任務以獲勝,否則當會議結束時,至聖者的任務將被重置。\n\n請注意:\n1. 嘗試投給至聖者的票數會被強制取消\n2. 玩家嘗試殺害至聖者時,兇手的冷卻會重置為 10 秒至,且至聖者會被傳送至地圖外直到進入會議。\n3. 依據房主設定,至聖者可能可以知道兇手的職業\n4. 至聖者在計算人數時會被算作死亡", "CollectorInfoLong": "(中立陣營):\n當集票者在會議上投票給一名玩家時,將會收集到本次會議上該玩家被投的所有票數。當集票者收集到指定票數之後,集票者將獨立獲勝\n請注意: 集票者的勝利優先於被逐出玩家的勝利(例如小丑、暴民、冤罪師等)。", "GlitchInfoLong": "(中立陣營):\n故障者可以駭入玩家,玩家在被駭入期間無法殺人,使用通風口,和舉報屍體。\n\n單點殺人鍵駭入&雙點殺人鍵殺人。\n此外,故障者可以使用破壞(除了門之外的所有破壞,例如關燈) 來在一定時間內變形成一個隨機的玩家(破壞並不會真正發生,並且由於技術限制,你無法在破壞時或破壞後變形)。\n\n殺光所有人來獲勝。", - "SidekickInfoLong": "(中立陣營):\n跟班需要幫助豺狼殺死所有人\n你會跟著豺狼一起獲勝\n根據設定,你可能會在豺狼死後成為新的豺狼\n並且你可能無法在老豺狼死亡前殺人", + "SidekickInfoLong": "(中立陣營):\n跟班的目標是幫忙豺狼殺光所有人,你與豺狼共享勝利。", "ProvocateurInfoLong": "(中立陣營):\n挑釁者可以使用殺人鍵與任何玩家同歸於盡。若遊戲結束時目標輸了,則挑釁者與獲勝方一同獲勝。", "BloodKnightInfoLong": "(中立陣營):\n嗜血騎士每次殺人後都可以獲得一定時間的護盾,護盾可以抵擋掉所有正常殺人的舉動,直到護盾時間結束並失效。當只剩下嗜血騎士陣營與船員陣營且嗜血騎士陣營人數大於船員陣營,則嗜血騎士方獲勝", "PlagueBearerInfoLong": "(災厄陣營):\n瘟疫之源可以嘗試對玩家使用殺人鍵將其感染,當所有人都被感染時,瘟疫之源將轉化為萬疫之神,萬疫之神免疫所有攻擊並且可以殺人,如果有人嘗試殺死萬疫之神,則萬疫之神將反殺兇手。\n\n此外,當受感染的玩家與未感染的玩家進行互動後,未受感染的玩家也會受到感染", "PestilenceInfoLong": "(災厄陣營):\n萬疫之神免疫所有攻擊並且可以殺人,如果有人嘗試通過正常殺人方式殺死萬疫之神,則萬疫之神將反殺兇手。\n\n消滅萬疫之神的唯一方法是透過投票,或是萬疫之神猜測錯誤。\n在你變成萬疫之神後,你的存在將在會議上向所有人告知。", "SoulCollectorInfoLong": "(災厄陣營):\n靈魂收割者可以對玩家使用擊殺來預測他們的死亡,如果你的目標在該回合或之後的會議中死亡,你將收集他的靈魂。\n你的目標會在每次會議後或目標死亡後重置。\n\n一旦收集了一定量的靈魂(可設置),就會成為死亡使者。\n如果啟用被動獲得靈魂設置,則每次會議都會獲得一個靈魂。", "DeathInfoLong": "(災厄陣營):\n一旦靈魂收割者收集到了他們所需的靈魂,他們就會成為死亡使者。\n如果死亡使者在下一次會議結束時沒有被驅逐,死亡使者將會殺死所有人並獲勝。\n在死亡使者轉變的會議上將給予可配置的額外會議時間,以便進行更多討論以找到死亡使者並驅逐他。\n\n死亡使者為無敵狀態,他的存在將會在會議上進行公告", - "BakerInfoLong": "(災厄陣營):\n麵包師可以使用擊殺來向玩家發放麵包\n一旦一定數量的存活玩家拿到了麵包,麵包師就會成為飢餓之神。\n\n如果\"麵包給予額外效果\"的設定開啟,那麼你可以使用通風管來改變你給予的麵包種類。\n麵包效果:\n揭示: 向麵包師揭示目標的職業(整場遊戲持續有效)\n職業封鎖: 將目標的擊殺冷卻時間設定為999(會議後恢復正常)\n屏障: 給目標一個只有麵包師知道的屏障(會議後屏障消失)", + "BakerInfoLong": "(災厄陣營):\n麵包師可以使用擊殺來向玩家發放麵包\n一旦一定數量的存活玩家拿到了麵包,麵包師就會成為飢餓之神。\n\n如果\"麵包給予額外效果\"的設定開啟,那麼你可以使用通風管來改變你給予的麵包種類。\n麵包效果:\n揭示: 向麵包師揭示目標的職業(整場遊戲持續有效)\n職業封鎖: 當目標試圖使用擊殺鍵時阻擋操作並重置擊殺冷卻\n屏障: 給目標一個只有麵包師知道的屏障(會議後屏障消失)", "FamineInfoLong": "(災厄陣營):\n麵包師向一定數量的玩家發放麵包後,將成為飢餓之神,若飢餓之神未在成神的第一次會議中被逐出或擊殺,所有沒有麵包的玩家都會餓死。\n之後飢餓之神可以使用擊殺來讓玩家挨餓,並在下次會議殺死該玩家。\n\n飢餓之神的存在會在會議中向所有人公布", "BerserkerInfoLong": "(災厄陣營):\n狂戰士每殺人一次都會升等,當達到一定等級時,狂戰士將解鎖新能力。\n\n清道夫的殺人不會出現屍體。\n自爆兵的殺人會讓被殺目標爆炸。請小心使用,因為這將可能殺死附近的其他災厄陣營玩家。 \n在達到一定的等級後,你將會變成戰神。", "WarInfoLong": "(災厄陣營):\n戰神為無敵狀態,擊殺時間更短,且可以使用狂戰士期間取得的所有技能進行擊殺。\n每個人都會在會議上取得你在場的訊息", @@ -911,12 +899,11 @@ "TraitorInfoLong": "(中立陣營):\n背叛者知道偽裝者,但偽裝者不知道背叛者,偽裝者可以殺死背叛者,但背叛者無法直接殺了偽裝者,通過其他方式消滅偽裝者,然後殺死其他人獲勝!", "TrollerInfoLong": "(中立陣營):\n搗亂者可以透過做任務來觸發一些隨機事件。\n例如改變所有玩家速度、傳送、影響破壞等事件。\n搗亂者只要存活到最後就能獲勝。", "VultureInfoLong": "(中立陣營):\n禿鷲報告屍體時,如果他的進食冷卻結束,則禿鷲即可吃下該具屍體(將其變為無法報告),如果冷卻未結束,禿鷲將正常報告此屍體,如果禿鷲達到每回合最大進食限制,則禿鷲也正常報告此屍體。依據房主設定,每回合最大進食限制的數值可以被調整。", - "AbyssbringerInfoLong": "(偽裝者陣營):\n深淵使者可以使用變形來放置黑洞,黑洞將在玩家靠近時將其吸入並殺死他們。", "TaskinatorInfoLong": "(中立陣營):\n作為搗蛋鬼,每當你完成一個任務,該任務就會被裝上炸彈。當其他玩家完成有炸彈的任務時,炸彈就會爆炸,玩家就會死亡。\n\n當搗蛋鬼活到最後,並且船員陣營失敗,則搗蛋鬼跟隨獲勝陣營獲勝。\n\n 請注意: 搗蛋鬼的炸彈無視所有保護(例如軍醫護盾)", "BenefactorInfoLong": "(船員陣營):\n當慈善家做完一項任務時,該任務會被標記。而當其他玩家完成了被標記的任務時,將會獲得護盾。\n\n請注意:護盾僅能防禦直接性擊殺", "MedusaInfoLong": "(中立陣營):\n美杜莎可以石化屍體,被石化的屍體將無法被報告,殺光所有人獲勝!", "SpiritcallerInfoLong": "(中立陣營):\n靈魂召喚者可以把玩家被殺害後變成惡靈,惡靈透過作祟按鈕暫時凍結其他玩家,或暫時阻擋他們的視野,在或者,惡靈可以給予靈魂召喚者一個護盾,短暫的保護靈魂召喚者不受殺害。", - "AmnesiacInfoLong": "(中立陣營):\n失憶者可以使用報告按鈕來回憶並獲取屍體的職業\n為了平衡遊戲,如果失憶者的設定為無法使用通風口,則你回憶職業後也不能夠使用通風口。", + "AmnesiacInfoLong": "(中立陣營):\n失憶者可以通過報告屍體來回想起一個職業\n\n如果屍體是偽裝者的,則失憶者將變為逃亡者。\n如果屍體是船員的,且符合條件,則失憶者將變為他的職業(否則你將會變成工程師)。\n如果屍體是不帶刀中立或是未指定的帶刀中立的,你將變為特定的中立職業(具體依據房主設定)。\n如果屍體是少數的帶刀中立的,則你將會變為他們的職業。", "ImitatorInfoLong": "(中立陣營):\n效顰者可以嘗試對一名玩家使用殺人鍵來效仿該玩家的職業。\n如果你效仿了船員,你會變成警長。\n如果你效仿了偽裝者,你會變成逃亡者。\n如果你效仿了中立玩家,你會變成某些中立職業。", "BanditInfoLong": "(中立陣營):\n強盜可以嘗試對一名玩家使用殺人鍵來偷走該名玩家的附加職業,雙擊來正常殺人。如果該名玩家沒有可偷取的附加職業,則正常殺死該玩家,基於房主設定,強盜可能可以立刻偷走附加職業,或在進入會議時偷走附加職業,當達到最大偷取次數時,你將可以正常殺人,殺光所有人來獲勝。\n\n請注意:\n1. 乾淨,絕境者,戀人無法被偷取。\n2. 如果強盜可以使用通風口,則敏捷無法被偷取。", "DoppelgangerInfoLong": "(中立陣營):\n分身者在殺死玩家時將會偷走他們的名字與外觀,殺光所有人來獲勝。\n\n請注意: 你無法在隱蔽效果期間偷取目標的特徵。", @@ -925,7 +912,7 @@ "ShroudInfoLong": "(中立陣營):\n裹屍布可以嘗試對一名玩家使用殺人鍵來用裹屍布遮蓋他們,被遮蓋的玩家名字旁會顯示「◈」,遮蓋目標在遇到玩家後就會殺死他,如果遮蓋目標活到會議後,且裹屍布仍存活,則被遮蓋目標會在會議結束後窒息而亡。", "WerewolfInfoLong": "(中立陣營):\n月下狼人殺人時為範圍性殺人(範圍依據房主設定),被範圍性殺死的玩家的死因將會顯示為被獵殺,不過月下狼人的冷卻會比正常帶刀玩家的冷卻較高。", "ShamanInfoLong": "(中立陣營):\n薩滿可以對一名玩家嘗試使用殺人鍵來選擇為巫毒娃娃,每回合一次,所有與你有互動的效果都會被轉移到巫毒娃娃身上。如果遊戲結束時,薩滿活到最後,則薩滿與獲勝陣營一同獲勝。\n請注意: 如果兇手無法正常擊殺目標,本次擊殺將會失效,但當兇手再次嘗試擊殺時,薩滿會死亡。", - "SeekerInfoLong": "(中立陣營):\n冒險家可以嘗試對一名玩家使用殺人鍵來為目標打上標籤,如果冒險家為目標打上標籤,即增加 1 點積分,如果冒險家給其他人打上標籤,而不是目標,則扣掉 1 點分數,冒險家在會議結束後或重新獲得新目標會無法移動 5 秒,當冒險家達到一定的積分時(具體數值由房主設定),冒險家獲勝。", + "SeekerInfoLong": "(中立陣營):\n冒險家可以嘗試對一名玩家使用殺人鍵來為目標打上標籤,如果冒險家為目標打上標籤,即增加 1 點積分,如果冒險家給其他人打上標籤,而不是目標,則扣掉 1 點分數,冒險家在會議結束後或重新獲得新目標會無法移動 5 秒。\n\n當冒險家達到一定的積分時(具體數值由房主設定),冒險家獲勝。冒險家將會看到自己的目標有★標記", "PixieInfoLong": "(中立陣營):\n精靈可以嘗試對一名玩家使用殺人鍵來標記多個目標,你將會看到目標的名字具有顏色。會議時你必須逐出其中一個目標,如果你失敗了,根據設定你可能會自殺,如果進入會議時你沒有標記任何玩家,或是你所有的目標都死亡,則你的目標將重設為 0。如果你成功逐出目標,你則獲得 1 點積分。\n\n當精靈達到一定的積分時(具體數值由房主設定),則精靈獲勝。", "SchrodingersCatInfoLong": "(中立陣營):\n如果有人試圖對薛丁格的貓使用殺人鍵,薛丁格的貓將阻止該操作並加入兇手的陣營。阻擋只能進行一次。 在沒有被殺的情況下,薛丁格的貓沒有勝利條件,所以薛丁格的貓必須在遊戲結束前被殺。\n此外,薛丁格的貓雖然會和自身陣營獲勝,但是計算人數時不會被計入。\n\n請注意: 如果殺人機器試圖對你使用殺人鍵,互動不會被阻止,薛丁格的貓會直接死亡。", "RomanticInfoLong": "(中立陣營):\n暗戀者可以嘗試對一名玩家使用殺人鍵來選擇他的戀人(這個操作可以在任一輪中被執行),當暗戀者選擇了戀人後,他就可以對戀人使用殺人鍵來給他臨時的護盾,護盾可以保護戀人不被殺死,如果他的戀人死亡,則暗戀者會轉變為以下職業:\n1. 如果他的戀人是偽裝者,則暗戀者變為逃亡者\n2. 如果他的戀人是帶刀中立,則暗戀者變為絕情者\n3. 如果他的戀人是船員或不帶刀中立,則暗戀者變為報復者。\n遊戲結束時,如果暗戀者的戀人的所處陣營獲勝,則暗戀者和他的戀人與獲勝陣營一同獲勝。\n\n請注意: 如果暗戀者的職業改變,勝利條件也會隨之改變。", @@ -937,7 +924,6 @@ "JinxInfoLong": "(中立陣營):\n每當掃把星受到攻擊時,掃把星都會詛咒他們,導致他們死於厄運。該技能有使用次數限制。", "PotionMasterInfoLong": "(中立陣營):\n魔藥師擁有三瓶藥水,分別有不同的作用\n\n對玩家按一下殺人鍵: 揭示身分\n按兩下殺人鍵: 殺人\n地圖: 破壞\n\n請注意: 揭示的藥水具有上限,當用完時,就會轉變為正常的殺人鍵。", "NecromancerInfoLong": "(中立陣營):\n當有人嘗試殺死死靈法師時,殺人行動會被阻擋並且死靈法師會傳送到隨機的通風口中,並且必須在倒數計時時間內殺死兇手,如果成功殺死,則存活,反之,如果倒數計時結束時你沒有殺死兇手,或是殺錯人,你會永久死亡。遊戲結束時,如果死靈法師活到最後,則死靈法師獨自獲勝。", - "ShockerInfoLong": "(中立陣營):\n電擊者可以透過在房間中執行任務來標記此房間,在一段時間(根據房主設定) 內跳進管道,你將電擊該房間內的所有人。當你完成所有任務後,你會得到新的任務。請注意: 在未電擊期間內完成任務將為下一次能力使用標記它們。", "LastImpostorInfoLong": "(附加職業):\n這個效果只在偽裝者陣營只剩下一人時賦予該玩家,被賦予效果的玩家殺人冷卻將會縮短。", "OverclockedInfoLong": "(附加職業):\n超頻的冷卻時間會被減少至設定的百分比(%) 數(依據房主設定),該附加職業只會給予帶刀玩家。", "LoversInfoLong": "(附加職業):\n戀人為兩名玩家的組合。戀人可以看到對方名字旁有「♥」圖標作為提示,當戀人其中一人死亡時則另一人殉情(根據房主設定可能不會殉情)。戀人其中一人在會議中被逐出時,另一人也將死亡並變成不可報告的屍體。當場上只剩下戀人時戀人將獨自獲勝,戀人其中一人獲勝時另一人也一起獲勝。", @@ -981,7 +967,7 @@ "RebirthInfoLong": "(附加職業):\n重生者在即將被逐出時會隨機跟一名投給自己的玩家交換裝扮與名字,並且他將代替重生者被逐出。\n請注意: 房主的投票不會被計入\n如果重生者用盡了所有重生次數,則不會觸發效果", "LoyalInfoLong": "(附加職業):\n持有忠誠附加職業的玩家無法被招募,該職業無法分配給中立陣營。", "EvilSpiritInfoLong": "(附加職業):\n惡靈的任務為幫助靈魂召喚者獲勝,你可以使用你的作祟按鈕來讓某名玩家無法移動並且視野被縮小,如果你在靈魂召喚者上使用作祟按鈕,則你會給予靈魂召喚者短暫的護盾。", - "RecruitInfoLong": "(背叛的附加職業):\n當你獲得了被招募的附加職業,代表你已被豺狼招募並加入了豺狼陣營,需要幫助豺狼及跟班獲勝。\n你不能和原來的陣營一起獲勝。\n根據設置,如果老豺狼被殺死並且沒有跟班活著,你可能會變成豺狼。", + "RecruitInfoLong": "(背叛的附加職業):\n被授予狼化附加職業代表你被豺狼招募,當你持有此附加職業時,你將會加入豺狼陣營並無法與原先的陣營獲勝。", "AdmiredInfoLong": "(背叛的附加職業):\n被授予被仰慕附加職業代表你被仰慕者仰慕,當你持有此附加職業時,你將會與船員獲勝,你可以看見仰慕者。", "GlowInfoLong": "(附加職業):\n關燈期間,發光和發光周圍的玩家都會獲得視野提升", "RadarInfoLong": "(附加職業):\n擁有雷達的玩家將有一個指向最近玩家的箭頭", @@ -1025,7 +1011,6 @@ "ProhibitedInfoLong": "(附加職業):\n受限者無法使用某些特定的通風口。\n不能使用的管道數根據房主設定而不同。", "EavesdropperInfoLong": "(附加職業):\n竊聽者有一定機率能夠在會議上看到其他人的職業/附加職業的信息,比如殯葬師或偵探。", "ApocalypseInfoLong": "(災厄陣營):\n災厄陣營是一個獨立的陣營,災厄成員會共同獲勝,且可以看到彼此的職業。\n根據房主設置,災厄陣營的玩家可以賭人或是被賭", - "RevenantInfoLong": "(中立陣營):\n返生者的目標就是被殺死,如果你被殺死,你會奪走兇手的職業並將其擊殺。你在被殺之前沒有任何方法獲勝。\n請注意: 返生者的技能只有被直接性擊殺時會生效", "ShowTextOverlay": "文字覆蓋(小字顯示)", "Overlay.GuesserMode": "賭怪模式", "Overlay.NoGameEnd": "測試模式(遊戲不結束)", @@ -1039,8 +1024,6 @@ "AbilityUseLimit": "初始技能數量", "AbilityInUse": "技能生效中", "AbilityExpired": "技能已失效,剩餘{0} 次使用次數", - "RevenantTargeted": "你的職業變成了{0}", - "RevenantCanCopyAddons": "可以奪走附加職業", "ShowArrows": "指向屍體的箭頭", "ArrowDelayMin": "箭頭最短延遲時間", "ArrowDelayMax": "箭頭最長延遲時間", @@ -1057,7 +1040,7 @@ "NoGameEnd": "測試模式(遊戲不結束)", "AllowConsole": "開啟控制台(可能會被用於作弊)", "DebugMode": "偵錯模式", - "SyncButtonMode": "限制會議次數", + "SyncButtonMode": "限制會議時間", "RandomMapsMode": "隨機地圖模式", "SyncedButtonCount": "可用緊急會議次數", "HHSuccessKCDDecrease": "殺死目標減少的冷卻時間", @@ -1352,7 +1335,7 @@ "TempBan": "暫時封禁", "OnlyCancel": "只取消作弊行為", "CheatResponses": "檢測到外掛時", - "NeutralRoleWinTogether": "中立陣營玩家共同獲勝", + "NeutralRoleWinTogether": "同種職業的中立玩家共同獲勝", "NeutralWinTogether": "全體中立陣營玩家共同獲勝", "MenuTitle.Disable": "★ 禁用相關設定", "MenuTitle.MapsSettings": "★ 地圖 ★", @@ -1370,8 +1353,6 @@ "ShieldedCanUseKillButton": "受保護玩家可以使用能力/擊殺按鈕", "PlayerIsShieldedByGame": "該玩家受到了遊戲的保護!", "LegacyNemesis": "使用舊版本", - "LegacyParasite": "使用舊版本", - "LegacyTraitor": "使用舊版本", "ArsonistKeepsGameGoing": "當縱火犯在場時遊戲不會結束", "ArsonistCanIgniteAnytime": "可以在任何時候點燃", "ArsonistMinPlayersToIgnite": "點燃所需的最小澆油數", @@ -1514,18 +1495,6 @@ "SheriffCanKillSeparately": "單獨設定", "In%team%": "(%team%陣營)", "SheriffMisfireKillsTarget": "當誤殺好人時同時殺死目標", - "BlackHolePlaceCooldown": "放置黑洞冷卻時間", - "BlackHoleDespawnMode": "黑洞消失模式", - "BlackHoleDespawnTime": "黑洞消失後的時間", - "Abyssbringer.Suffix": "<#00ffa5>被吞噬的玩家數量 {0} <#00ffa5>活躍的黑洞:\\n{1}", - "Abyssbringer.Suffix.BlackHole": "<#00ffa5>{0}: {1}", - "BlackHoleMovesTowardsNearestPlayer": "黑洞向最近的玩家移動", - "BlackHoleMoveSpeed": "黑洞移動速度", - "BlackHoleRadius": "黑洞吞噬範圍半徑", - "AfterTime": "一段時間後", - "After1PlayerEaten": "1名玩家被吞噬後", - "AfterMeeting": "會議後", - "None": "無", "SheriffShotLimit": "執法次數上限", "SheriffCanKillAllAlive": "全員存活時可以執法", "SheriffCanKillCharmed": "可以執法被魅惑的玩家", @@ -1542,15 +1511,12 @@ "RebirthUses": "重生次數上限", "RebirthCountVotes": "重生目標僅從投給自己的玩家中選擇", "RebirthFailed": "沒有找到能與你交換身體的靈魂。", - "FireworkerCooldown": "放置黑洞冷卻時間", "ReverieIncreaseKillCooldown": "增加殺人冷卻時間", "ReverieMaxKillCooldown": "最大殺人冷卻", "ReverieMisfireSuicide": "到達最大殺人冷卻時可能會誤殺", "ReverieResetCooldownMeeting": "會議後重設殺人冷卻時間", "ConvertedReverieKillAll": "非船員陣營的遐想者可以殺死任何人並且不受冷卻增加影響", "VigilanteNotify": "你變成了你發誓要摧毀的東西", - "DictatorChangeCommandToExpel": "獨裁主義者使用指令逐出玩家而不是透過投票", - "DictatorExpelSelf": "等等等等等等什麼鬼? Bro真的只是想驅逐自己", "DoctorTaskCompletedBatteryCharge": "完成任務增加的心電圖電量", "SnitchEnableTargetArrow": "完成任務後箭頭指向所有目標", "SnitchCanGetArrowColor": "對不同陣營的目標顯示不同顏色的箭頭", @@ -1624,6 +1590,7 @@ "TimeThiefDecreaseMeetingTime": "每次殺人縮短的會議時間", "TimeThiefLowerLimitVotingTime": "會議時間下限", "TimeThiefReturnStolenTimeUponDeath": "死亡後會議時間恢復", + "TimeThiefMaxTimeOnAdmired": "時間竊賊被仰慕時的最大會議時間上限", "EvilTrackerCanSeeKillFlash": "偽裝者殺人時可以看到殺人閃光", "EvilTrackerCanSeeLastRoomInMeeting": "可以看見船員的位置", "EvilTrackerTargetMode": "追蹤模式", @@ -1631,7 +1598,6 @@ "EvilTrackerTargetMode.OnceInGame": "僅限一次", "EvilTrackerTargetMode.EveryMeeting": "每次會議", "EvilTrackerTargetMode.Always": "隨時隨地", - "ScavengerHasCustomDeathReason": "啟用自訂死亡原因", "EvilHackerCanSeeDeadMark": "可以看到屍體的位置", "EvilHackerCanSeeImpostorMark": "可以看到其他偽裝者的位置", "EvilHackerCanSeeKillFlash": "可以看到殺人閃光", @@ -1743,9 +1709,9 @@ "MadmateCountMode.Imp": "偽裝者", "MadmateCountMode.Original": "原始陣營", "Altruist_RevivedDeadBodyCannotBeReported_Option": "被復活的屍體無法報告", - "Altruist_ImpostorsCanGetsAlert": "偽裝者 可以在復活時收到通知", + "Altruist_ImpostorsCanGetsAlert": "偽裝者 可以在有玩家復活時收到通知", "Altruist_ImpostorsCanGetsArrow": "偽裝者 有指向復活玩家的箭頭", - "Altruist_NeutralKillersCanGetsAlert": "帶刀 中立 可以在復活時收到通知", + "Altruist_NeutralKillersCanGetsAlert": "帶刀 中立 可以在有玩家復活時收到通知", "Altruist_NeutralKillersCanGetsArrow": "帶刀 中立 有指向復活玩家的箭頭", "AltruistSuffix": "報告模式: {0}", "AltruistReviveMode": "復活", @@ -1783,12 +1749,12 @@ "NinjaMarkCooldown": "標記冷卻時間", "NinjaAssassinateCooldown": "刺殺冷卻時間", "NinjaModeDouble": "按一下標記&按兩下殺人", - "JudgeCanTrialnCrewKilling": "可以審判帶刀 船員", - "JudgeCanTrialNeutralB": "可以審判友善 中立", - "JudgeCanTrialNeutralK": "可以審判帶刀 中立", - "JudgeCanTrialNeutralE": "可以審判邪惡 中立", - "JudgeCanTrialNeutralC": "可以審判混亂 中立", - "JudgeCanTrialNeutralA": "可以審判災厄 中立", + "JudgeCanTrialnCrewKilling": "可以審判帶刀船員", + "JudgeCanTrialNeutralB": "可以審判無刀中立", + "JudgeCanTrialNeutralK": "可以審判帶刀中立", + "JudgeCanTrialNeutralE": "可以審判邪惡中立", + "JudgeCanTrialNeutralC": "可以審判混亂中立", + "JudgeCanTrialNeutralA": "可以審判災厄中立", "JudgeCanTrialSidekick": "可以審判跟班", "JudgeCanTrialInfected": "可以審判被感染的玩家", "JudgeCanTrialContagious": "可以審判被傳染的玩家", @@ -1864,21 +1830,13 @@ "Jackal_SidekickCountMode_Jackal": "豺狼", "Jackal_SidekickCountMode_Original": "原陣營", "Jackal_SidekickAssignMode": "跟班生成模式", - "Jackal_SidekickAssignMode_SidekickAndRecruit": "當選擇跟班失敗時選擇被招募的", - "Jackal_SidekickAssignMode_Sidekick": "只選擇 跟班", - "Jackal_SidekickAssignMode_Recruit": "只選擇 被招募的", + "Jackal_SidekickAssignMode_SidekickAndRecruit": "跟班+狼化", + "Jackal_SidekickAssignMode_Sidekick": "僅限跟班", + "Jackal_SidekickAssignMode_Recruit": "僅限狼化", + "JackalWinWithSidekick": "豺狼可以與跟班所在的陣營獲勝", "Jackal_SidekickCanKillSidekick": "跟班可以互相殺害", "Jackal_SidekickCanKillJackal": "跟班可以擊殺豺狼", - "Jackal_RecruitFailed": "你無法招募該玩家!", "JackalCanKillSidekick": "豺狼可以殺死跟班", - "Jackal_SidekickCanKillWhenJackalAlive": "跟班可以在豺狼存活時擊殺", - "Jackal_SidekickTurnIntoJackal": "跟班會在豺狼死後變成新的豺狼", - "Jackal_RestoreLimitOnNewJackal": "當跟班變成新豺狼後可以再次招募跟班", - "Jackal_OnBecomeNewJackalMeeting": "舊的 豺狼 {0} 已經死了。\n你被選為了新的 豺狼\n齊心協力,贏得遊戲!", - "Jackal_OnNewJackalSelectedMeeting": "舊的 豺狼 {0} 已經死了。\n{1} 已被選為新的 豺狼!\n齊心協力,贏得遊戲!", - "Jackal_BecomeNewJackal": "舊的豺狼死了,你成為了新的豺狼!", - "Jackal_OnNewJackalSelected": "舊的豺狼死了,現在請幫助新的豺狼 {0}!", - "Jackal_BossIsDead": "哎呀,豺狼老大死了!", "CoronerArrowsPointingToDeadBody": "有指向屍體的箭頭", "CoronerLeaveDeadBodyUnreportable": "驗屍官報告過的屍體無法再次被報告", "CoronerInformKillerBeingTracked": "告知兇手已被追蹤", @@ -1916,9 +1874,6 @@ "VipTag": "VIP★", "ApplyVipList": "套用VIP列表", "AllowSayCommand": "允許管理員使用/say指令", - "AllowStartCommand": "允許管理員使用/start指令", - "StartCommandMinCountdown": "/start 指令的最小倒數計時", - "StartCommandMaxCountdown": "/start 指令的最大倒數計時", "KickCommandDisabled": "踢出指令目前已被禁用", "KickCommandNoAccess": "你沒有權限使用踢出指令", "KickCommandInvalidID": "無效的玩家ID\n請使用 /kick [玩家ID] [原因] 來踢出玩家\n範例: /kick 5 不遵守規則", @@ -1951,11 +1906,6 @@ "WarnCommandNoAccess": "你沒有權限使用警告指令", "WarnCommandInvalidID": "無效的玩家ID\n請使用 /warn [玩家ID] [原因] 來封禁玩家\n範例: /warn 5 在逐出畫面時討論", "WarnCommandWarnHost": "你無法警告房主", - "StartCommandNoAccess": "你沒有權限使用開始指令", - "StartCommandDisabled": "開始指令目前已被禁用", - "StartCommandCountdown": "錯誤\n\n遊戲已經開始了!", - "StartCommandStarted": "遊戲將於 {0} 開始!", - "StartCommandInvalidCountdown": "錯誤\n\n開始倒數應在 {0} 和 {1} 中間!", "WarnCommandWarnMod": "你不能警告其他管理員", "WarnCommandWarned": "已被警告,我們將不會再繼續發出警告,繼續犯規將會被懲罰。 \n ", "WarnExample": "使用 /warn [玩家ID] [原因] 來警告玩家。\n範例:\n /warn 5 在逐出畫面時討論", @@ -1983,7 +1933,6 @@ "DeathReason.Quantization": "量子化", "DeathReason.Overtired": "猝死", "DeathReason.Ashamed": "卷死", - "DeathReason.Consumed": "吞噬", "DeathReason.PissedOff": "氣死", "DeathReason.Dismembered": "肢解", "DeathReason.LossOfHead": "絞殺", @@ -2007,8 +1956,6 @@ "DeathReason.Starved": "餓死", "DeathReason.Equilibrium": "平衡", "DeathReason.Sacrificed": "獻身", - "DeathReason.Electrocuted": "電擊", - "DeathReason.Scavenged": "清理", "OnlyEnabledDeathReasons": "只顯示已開啟的死亡原因", "Alive": "存活", "Disconnected": "斷線", @@ -2024,10 +1971,11 @@ "DeputyHandcuffCooldown": "上銬冷卻時間", "DeputyHandcuffMax": "手銬最大數量", "DeputyHandcuffedPlayer": "你給目標戴上了手銬!", - "HandcuffedByDeputy": "你被上銬了!", - "DeputyInvalidTarget": "目標無法被上銬", + "HandcuffedByDeputy": "你被銬上了手銬!\n現在你破壞了手銬並且你可以在冷卻結束後再次擊殺", + "DeputyInvalidTarget": "目標已經戴上手銬", + "HandcuffBrokenAfterMeeting": "會議後移除所有手銬", "DeputyHandcuffText": "上銬", - "DeputyHandcuffCDForTarget": "被上銬玩家的殺人冷卻", + "DeputyHandcuffCDForTarget": "戴上手銬的玩家的下一次擊殺冷卻時間", "RejectShapeshift.AbilityWasUsed": "技能已生效", "EscapisMtarkedPosition": "你成功標記了自己的位置", "InvestigateCooldown": "檢查冷卻時間", @@ -2074,7 +2022,6 @@ "Command.dump": "→ 將遊戲運行紀錄輸出到桌面", "Command.death": "→ 顯示你的死因", "Command.icons": "
╳ - 該玩家被勒索者勒索,並且無法在會議上發言。
☆ - 船長的特殊標記,只有船員能看見船長名字後的星星
乂 - 該玩家被妖術師施展妖術了,若代碼工程師沒有在會議結束時死亡或被放逐,該玩家將死亡
♦ - 該玩家是律師、暴民或追隨者的目標
♥ - 用來標記戀人或暗戀者
✚ - 用來標記軍醫的目標
⦿ - 該玩家是挑戰者挑戰目標
!? - 該玩家是測驗者的目標,需要回答問題才能存活
☜ - 用來為薛丁格的貓標記他們的隊友
◈ - 該玩家被裹屍布蓋住了,若裹屍布沒有在會議結束時死亡或被放逐,該玩家將死亡
⚠ - 該玩家是即將完成任務的告密者或至聖者
★ - 該玩家是大明星或名人或展現者
† - 該玩家被女巫詛咒了,若女巫沒有在會議結束時死亡或被放逐,該玩家將死亡
∇ - 用來為神風特攻隊標記目標
■ - 該玩家被球狀閃電汽化為量子幽靈
⊠ - 用來為監禁者標記他們的目標
● - 用來為麵包師標記已獲得麵包的玩家
♠ - 用來標記靈魂收割者的目標
⦿ - 用來為瘟疫之源顯示已感染的玩家", - "Command.start": "[Seconds] → 遊戲開始前的倒數計時", "Command.iconinfo": "→ 顯示會議圖標代表的意思", "Command.iconhelp": "→ 給所有人顯示會議圖標代表的意思", "Command.Poll": "→ 發起投票,最多可以有5個選項", @@ -2087,7 +2034,6 @@ "ShowMadmatesInLeftCommand": "顯示叛徒 (包括附加職業)", "ShowApocalypseInLeftCommand": "顯示災厄中立", "SeeEjectedRolesInMeeting": "會議中看見被逐出的玩家的職業", - "ThankYouForUsingTOHE": "感謝你使用 TOHE!", "SkillUsedLeft": "您發動了技能召開了會議。\n您的技能剩餘使用次數:", "NemesisDeadMsg": "黑手黨的死亡,意味著復仇的開始\n請使用/rv + [玩家ID] 以殺死指定玩家\n您可以在玩家名字前看到該玩家的ID\n或輸入/rv獲得玩家ID列表", "NemesisAliveKill": "黑手黨的復仇技能只能在死亡後發動", @@ -2107,7 +2053,6 @@ "GuessNotifiedBait": "因為誘餌已經被公告出來了,所以無法被猜測,你覺得這會很簡單,對吧?", "GuessGM": "你會什麼會想要讓一個剛開局就死的人在死一次", "GuessGuardianTask": "很抱歉,你無法猜測已完成任務的守護者", - "GuardianCantKilled": "你不能擊殺已經完成任務的守護者", "GuessMarshallTask": "很抱歉,你無法猜測已經完成任務的展現者", "GuessObviousAddon": "很抱歉,你無法猜測過於明顯的附加職業", "GuessAdtRole": "很抱歉,根據該房設定不允許猜測附加職業", @@ -2163,7 +2108,6 @@ "BecomeMadmateCuzMadmateMode": "您因死亡而成為叛徒", "CleanerCleanBody": "目標的屍體已被清理", "QuickShooterStoraging": "子彈儲存成功", - "QuickShooterFailed": "你處於冷卻時間。", "PoisonerTargetDead": "您的目標已死亡", "HexesLookLikeSpells": "妖術 看起來像詛咒", "HexButtonText": "妖術", @@ -2222,7 +2166,7 @@ "PacifistOnGuard": "和平技能已生效,剩餘{0} 次", "PacifistSkillNotify": "和平之鴿重置了您的殺人/技能冷卻", "BeRecruitedByJackal": "你被豺狼招募成跟班了!", - "YinYangerAlreadyMarked": "{0} 已處於平靜狀態,並得到一位陰陽師的幫助", + "YinYangerAlreadyMarked": "{0} is already in a state of calm, endowed by a fellow YinYanger", "CoronerTrackRecorded": "追蹤已被錄製", "CoronerNoTrack": "沒有追蹤紀錄", "CoronerIsTrackingYou": "驗屍官正在追蹤你!", @@ -2322,7 +2266,6 @@ "Message.YTPlanNotice": "提醒: 該房間已啟用【創作者素材保護計畫】,房主可以指定自己的職業。\n該功能只允許創作者錄製影片素材,如有濫用情況,請退出遊戲或舉報。\n目前創作者認證:", "Message.OnlyCanBeUsedByHost": "錯誤\n該指令只能由房主使用", "Message.MaxPlayers": "最大玩家數量已設定為 ", - "Message.MaxPlayersFailByRegion": "無法設定最大玩家人數: 原版伺服器最多支援 15 名玩家。", "Message.GhostRoleInfo": "關於幽靈職業\n你好!這裡是有關於幽靈職業的一些介紹\n\n請注意: 幽靈職業會對遊戲產生極大的影響,因此如果您不熟悉幽靈職業,不建議在小型房間中使用。\n如果沒有明確的說明,幽靈職業的技能按鈕就是守護按鍵。\n\n幽靈職業的生成:\n幽靈職業只有在死亡後才會出現,一個陣營中最先死亡的玩家將會獲得幽靈職業。\n\n注意:如果您以前的職業沒有任務(例如: 警長),則您作為幽靈職業的任務不需要用於任務勝利
", "ApocalypseInfoTitle": "中立災厄陣營簡介:", "Message.ApocalypseInfo": "災厄陣營的每個職業都有自己的目標轉變職業。\n轉變的 災厄成員將在遊戲中發生巨大的變化並且處於無敵狀態(除了投票之外),但每個人都會被通知他們已經轉變。\n\n職業:瘟疫之源、靈魂收割者、麵包師、狂戰士\n轉變目標職業:萬疫之神、死亡使者、飢餓之神、戰神\n\n災厄成員可以看到彼此的職業和能力圖示。\n與帶刀中立一樣,災厄成員也讓遊戲繼續進行,玩得開心!", @@ -2393,7 +2336,7 @@ "FortuneTellerCheckMsgTitle": "【 ★ 水晶球 ★ 】", "MimicMsgTitle": "【 ★ 保險箱 ★ 】", "MorticianCheckTitle": "【 ★ 屍體檢查 ★ 】", - "NemesisRevengeTitle": "【 ★ 特供情報 ★ 】", + "NemesisRevengeTitle": "【 ★ 特供情报 ★ 】", "RetributionistRevengeTitle": "【 ★ 報應者 ★ 】", "TabVanilla.GameSettings": "遊戲設定", "TabGroup.SystemSettings": "系統設定", @@ -2454,6 +2397,7 @@ "LastResult": " ★ 遊戲結果", "LastEndReason": " ★ 結束原因", "KillLog": "殺人紀錄", + "MainRoleLog": "職業轉變日誌", "Maximum": "最大人數", "RoleRate": "開啟", "RoleOn": "優先", @@ -2640,7 +2584,7 @@ "NeutralRemain": "\n剩下 {0} 個帶刀中立", "OneNeutralRemain": "\n剩下 {0} 個帶刀中立", "ApocRemain": "\n剩下 {0} 個 災厄 中立", - "GameOverReason.HumansByVote": "偽裝者被逐出", + "GameOverReason.HumansByVote": "所有偽裝者及帶刀中立皆被逐出或殺死", "GameOverReason.HumansByTask": "船員完成了任務", "GameOverReason.HumansDisconnect": "船員斷線", "GameOverReason.ImpostorByVote": "船員被逐出", @@ -2653,7 +2597,7 @@ "FortuneTellerCheck.Result": "【{0}】可以是以下職業:\n{1}", "SunnyboyChance": "成為陽光開朗大男孩的機率", "BardChance": "成為吟遊詩人的機率", - "SkeldChance": "地圖為The Skeld的機率", + "SkeldChance": "地圖是 The Skeld的機率", "MiraChance": "地圖為MIRA HQ的機率", "PolusChance": "地圖為Polus的機率", "DleksChance": "地圖是dlekS ehT的機率", @@ -2730,9 +2674,8 @@ "DeathMeetingTimeIncrease": "當死亡使者存在時,會議時間延長", "SoulCollectorMeetingDeath": "你的目標在會議中死亡,你收割了他的靈魂。", "SoulCollectorKillButtonText": "預測", - "SoulCollectorHasImpostorVision": "靈魂收割者 擁有偽裝者視野", "ApocalypseIsNigh": "【末日即將來臨 !】", - "ApocalypseImmune": "該職業免疫!", + "ApocalypseImmune": "該玩家免疫了你的攻擊,因為他處於無敵狀態!", "BakerToFamine": "你變成了飢餓之神!!!", "BakerTransform": "麵包師已經變成了飢餓之神! 飢荒就要到來了!", "BakerAlreadyBreaded": "該玩家已經擁有麵包", @@ -2741,15 +2684,13 @@ "BakerBreadNeededToTransform": "成為飢餓之神需要發放的麵包數量", "BakerCantBreadApoc": "你不能給其他災厄成員發放麵包", "BakerKillButtonText": "發放麵包", - "BakerUnshiftButtonText": "切換", "BakerRevealBread": "揭示", "BakerRoleblockBread": "職業封鎖", "BakerBarrierBread": "屏障", "BakerCurrentBread": "當前麵包種類: ", "BakerSwitchBread": "麵包種類切換至: ", - "BakerCanVent": "麵包師可以使用通風口", + "BakerCanVent": "麵包師可以使用通風口", "BakerBreadGivesEffects": "麵包具有額外效果", - "BakerTransformNoMoreBread": "麵包師在沒有足夠的麵包時轉變", "FamineKillButtonText": "飢餓", "FamineStarveCooldown": "飢餓之神的飢荒冷卻時間", "FamineCantStarveApoc": "你不能餓死其他災厄成員", @@ -2796,7 +2737,6 @@ "GodfatherTargetCountMode": "兇手職業將轉變成", "GodfatherCount_Refugee": "逃亡者", "GodfatherCount_Madmate": "叛徒", - "GodfatherRefugeeMsg": "你已被懸賞者招募!", "MissChance": "失誤的機率", "IncreaseByOneIfConvert": "如果船員的陣營被轉換則最大擊殺數+1", "HawkMissed": "失誤了!", @@ -2829,7 +2769,6 @@ "BerserkerToWar": "你變成了戰神!!!", "BerserkerTransform": "狂戰士已經變成了戰神! 這將是一場浩劫", "WarKillCooldown": "戰神的殺人冷卻", - "BerserkerCanKillTeamate": "可以殺死其他災厄陣營的成員", "BlackmailerSkillCooldown": "勒索冷卻時間", "BlackmailerMax": "目標最大說話次數", "BlackmailerDead": "警告!玩家 {0} 被勒索者勒索了!", @@ -2919,8 +2858,6 @@ "RememberedPursuer": "你回想起了你是一個起訴人!", "RememberedFollower": "你回想起了你是一個追隨者", "RememberedAmnesiac": "你沒有成功地記住自己的職業", - "AmnesiacRemembered": "你回想起了你是一個{0}!", - "ReportWhenFailedRemember": "回憶失敗時報告屍體", "RememberedImitator": "你回想起了你是一個效顰者", "RememberedImpostor": "你回想起了你是一個偽裝者!", "RememberedCrewmate": "你回想起了你是一個船員!", @@ -3334,12 +3271,9 @@ "PixieTargetAlreadySelected": "目標已選定", "PixieButtonText": "標記", "PlagueBearerCooldown": "瘟疫之源冷卻時間", - "PlagueBearerCanVent": "可以使用通風管", - "PlagueBearerHasImpostorVision": "擁有偽裝者視野", "PestilenceCooldown": "萬疫之神殺人冷卻", "PestilenceCanVent": "萬疫之神可以使用通風口", "PestilenceHasImpostorVision": "萬疫之神有偽裝者視野", - "PestilenceKillGuessers": "殺死試圖猜測萬疫之神的玩家", "PlagueBearerAlreadyPlagued": "玩家已被感染", "PlagueBearerToPestilence": "你成為了萬疫之神!!", "GuessPestilence": "你試圖猜測萬疫之神!\n\n但抱歉,萬疫之神殺死了你。", @@ -3377,13 +3311,12 @@ "DoomsayerCantGuess": "抱歉,你只能在下次會議進行猜測", "DoomsayerCorrectlyGuessRole": "你猜對了職業!\n但很抱歉,該玩家並沒有死亡,因為房主設定不允許玩家死亡", "DoomsayerNotCorrectlyGuessRole": "你沒有猜對該玩家的職業!\n但你沒有死亡,因為房主設定不允許你死亡", - "DoomsayerGuessCountMsg": "你已猜對了{0}個職業", + "DoomsayerGuessCountMsg": "你已猜對了{0}個身份", "DoomsayerGuessCountTitle": "【 ★ 賭神 ★ 】", "DoomsayerGuessSameRoleAgainMsg": "你試著猜測與之前一樣的職業/附加職業", "EveryoneCanKnowMini": "所有人都能知道迷你船員是誰", "CanBeEvil": "迷你船員可以是偽裝者", "EvilMiniSpawnChances": "迷你船員成為偽裝者的機率", - "EvilMiniCanBeGuessed": "壞迷你船員可以在18歲前被賭", "GuessMini": "很抱歉,你無法傷害迷你船員", "GrowUpDuration": "長大所需要的時間(秒)", "MajorCooldown": "成年後的殺人冷卻時間", @@ -3414,9 +3347,9 @@ "Booster": "Discord伺服器加成", "Translator": "翻譯支援", "NoAccess": "未經授權的存取!\n你是否使用了被洩漏的版本或是自行構建dll?\n請於Discord群組開啟一張支援票以了解更多資訊(discord.gg/tohe)", - "DCNotify.Hacking": "你因為使用外掛而被封禁\n\n請停止", - "DCNotify.Banned": "您被該房間封禁\n\n若這是一個錯誤請告知房主", - "DCNotify.Kicked": "您被該房間踢出\n\n你可以嘗試重新加入", + "DCNotify.Hacking": "您被Innersloth的反作弊系統踢出了\r\n(Innersloth還在持續發瘋)", + "DCNotify.Banned": "您被該房間封禁", + "DCNotify.Kicked": "您被該房間踢出", "DCNotify.DCFromServer": "您與伺服器的連接已中斷\r\n這可能是因為您的網路不穩定\r\n也可能是因為伺服器不穩定或拒絕了您的存取", "DCNotify.GameNotFound": "未找到指定房間,可能是房間已經解散\r\n或檢查您是否選擇了與該房間不同的伺服器", "DCNotify.GameStarted": "該房間正在遊戲中,請等待遊戲結束後加入", @@ -3503,7 +3436,7 @@ "WinnerRoleText.Pickpocket": "竊賊獲勝!", "WinnerRoleText.Traitor": "背叛者獲勝!", "WinnerRoleText.Vulture": "禿鷲獲勝!", - "WinnerRoleText.Medusa": "美杜莎獲勝!", + "WinnerRoleText.Medusa": "梅杜莎獲勝!", "WinnerRoleText.Spiritcaller": "靈魂召喚者獲勝!", "WinnerRoleText.Glitch": "故障者獲勝!", "WinnerRoleText.Pestilence": "萬疫之神獲勝!", @@ -3525,7 +3458,6 @@ "WinnerRoleText.Doppelganger": "分身者獲勝!", "WinnerRoleText.Quizmaster": "測驗者獲勝!", "WinnerRoleText.Agitater": "炸彈王獲勝!", - "WinnerRoleText.Shocker": "電擊者獲勝!", "AdditionalWinnerRoleText.Sidekick": "跟班", "AdditionalWinnerRoleText.Taskinator": "搗蛋鬼", "AdditionalWinnerRoleText.Opportunist": "投機主義者", @@ -3611,7 +3543,7 @@ "SolsticerOnMeeting": "過多的犧牲使你感到不安,下一輪你將額外獲得 {0} 個短任務!", "SolsticerTitle": "【 ★ 至聖者 ★ 】", "GuessSolsticer": "很抱歉,至聖者是至高無上的,為此你畏懼於與他賭博的後果", - "ExpelSolsticer": "很抱歉,至聖者是至高無上的,為此你畏懼於將其放逐的後果", + "VoteSolsticer": "很抱歉,至聖者是至高無上的,為此你畏懼於與他作對的後果", "SolsticerTasksReset": "你的任務重置了!", "SolsticerMisGuessed": "很抱歉,你因為猜測錯誤而失去猜測的能力", "SolsticerGuessMax": "很抱歉,您先前因猜測錯誤而無法繼續猜測", @@ -3712,19 +3644,6 @@ "MinionAbilityTime": "技能持續時間", "Minion_Blind": "致盲", "Evader_ChanceNotExiled": "逃過逐出的機率", - "ShockerAbilityCooldown": "技能冷卻時間", - "ShockerAbilityDuration": "技能持續時間", - "ShockerAbilityPerRound": "一回合可以使用的技能次數", - "ShockerShockInVents": "可以電擊在管道內的玩家", - "ShockerAbilityResetAfterMeeting": "會議後重置被標記的房間", - "ShockerOutsideRadius": "外部任務的電擊半徑 (房間內以外的區域)", - "ShockerCanShockHimself": "可以電擊自己", - "ShockerImpostorVision": "電擊者擁有偽裝者視野", - "ShockerIsShocking": "你已準備好電擊了!", - "ShockerAbilityActivate": "電擊已開始!", - "ShockerAbilityDeactivate": "能力已失效", - "ShockerVentButtonText": "電擊", - "ShockerRoomMarked": "標記房間", "EavesdropperMsgTitle": "你竊聽到了一個秘密", "EavesdropPercentChance": "成功竊聽的機率", "ChiefOfPoliceSkillCooldown": "招募警長的冷卻時間", @@ -3736,4 +3655,4 @@ "PolicPreventRecruitNonKiller": "防止招募沒有擊殺按鈕的玩家", "PolicSuidiceWhenTargetNotKiller": "當招募到非船員或非帶刀玩家時自殺", "PolicPassConverted": "可以傳遞被招募的附加職業給警長" -} +} \ No newline at end of file diff --git a/Resources/roleColor.json b/Resources/roleColor.json index f91ab992e..a8d7a312a 100644 --- a/Resources/roleColor.json +++ b/Resources/roleColor.json @@ -1,253 +1,253 @@ { - "Crewmate": "#8cffff", - "Engineer": "#FF6A00", - "Scientist": "#8ee98e", - "GuardianAngel": "#77e6d1", - "Noisemaker": "#9100E3", - "Tracker": "#1BB313", - "CrewmateTOHE": "#8cffff", - "EngineerTOHE": "#FF6A00", - "ScientistTOHE": "#8ee98e", - "GuardianAngelTOHE": "#77e6d1", - "NoisemakerTOHE": "#9100E3", - "TrackerTOHE": "#1BB313", - "EvilMini": "#FF1919", - "NiceMini": "#edc240", - "Mini": "#dddddd", - "President": "#00ffac", - "LazyGuy": "#a4dffe", - "Mechanic": "#3333ff", - "Snitch": "#b8fb4f", - "Marshall": "#5573aa", - "Mayor": "#204d42", - "Bastion": "#696969", - "Psychic": "#6F698C", - "Cleanser": "#98FF98", - "Sheriff": "#ffb347", - "Vigilante": "#9900CC", - "CopyCat": "#ffb2ab", - "SuperStar": "#f6f657", - "Celebrity": "#ee4a55", - "SpeedBooster": "#00ffff", - "Doctor": "#80ffdd", - "Dictator": "#df9b00", - "Detective": "#7160e8", - "NiceGuesser": "#f0e68c", - "Knight": "#7a7a7a", - "Transporter": "#42D1FF", - "TimeManager": "#6495ed", - "Veteran": "#a77738", - "Altruist": "#9b0202", - "Bodyguard": "#185abd", - "Deceiver": "#BE29EC", - "Witness": "#e70052", - "Grenadier": "#3c4a16", - "Lighter": "#eee5be", - "TaskManager": "#00ffa5", - "Medic": "#00ff97", - "FortuneTeller": "#882c83", - "Glitch": "#39FF14", - "Judge": "#f8d85a", - "Lookout": "#2a52be", - "Mortician": "#333c49", - "Medium": "#a200ff", - "Observer": "#a8e0fa", - "Pacifist": "#007FFF", - "Monarch": "#FFA500", - "Coroner": "#8B0000", - "Merchant": "#D27D2D", - "Retributionist": "#228B22", - "Alchemist": "#a058bf", - "Deputy": "#df9026", - "Investigator": "#007FFF", - "Jailer": "#aa900d", - "Guardian": "#2E8B57", - "Addict": "#008000", - "Mole": "#3E2723", - "Tracefinder": "#0066CC", - "Oracle": "#6666FF", - "Spiritualist": "#669999", - "Chameleon": "#01C834", - "Inspector": "#0D57AF", - "Admirer": "#ee43c3", - "TimeMaster": "#44baff", - "Crusader": "#C65C39", - "Reverie": "#00BFFF", - "Telecommunication": "#7223DA", - "Swapper": "#66E666", - "ChiefOfPolice": "#f8cd46", - "Spy": "#34495E", - "Randomizer": "#FFA500", - "Enigma": "#676798", - "Arsonist": "#ff6633", - "Pyromaniac": "#fc8a4c", - "Ventguard": "#ffa5ff", - "Agitater": "#F3A359", - "Bandit": "#8B008B", - "Apocalypse": "#ff174f", - "PlagueBearer": "#e5f6b4", - "Pestilence": "#343136", - "SoulCollector": "#A675A1", - "Death": "#644661", - "Baker": "#bf9f7a", - "Famine": "#83461c", - "Berserker": "#cc0044", - "War": "#2B0804", - "Jester": "#ec62a5", - "Terrorist": "#00e600", - "Executioner": "#c0c0c0", - "Lawyer": "#008080", - "God": "#f96464", - "Opportunist": "#4dff4d", - "Shaman": "#50c878", - "Vector": "#ff6201", - "Jackal": "#00b4eb", - "Sidekick": "#00b4eb", - "Innocent": "#8f815e", - "Pelican": "#34C849", - "Revolutionist": "#ba4d06", - "Hater": "#414b66", - "Prohibited": "#6a8f8f", - "Demon": "#68bc71", - "Stalker": "#483d8b", - "Workaholic": "#008b8b", - "Solsticer": "#fbfa83", - "Collector": "#9d8892", - "Provocateur": "#74ba43", - "Sunnyboy": "#ff9902", - "Poisoner": "#478800", - "Huntsman": "#ad8739", - "Necromancer": "#9C87AB", - "Follower": "#ff9409", - "Romantic": "#FF1493", - "VengefulRomantic": "#8B0000", - "RuthlessRomantic": "#D2691E", - "Cultist": "#cf6acd", - "HexMaster": "#ff00ff", - "Wraith": "#4B0082", - "SerialKiller": "#233fcc", - "BloodKnight": "#630000", - "Juggernaut": "#A41342", - "Parasite": "#ff1919", - "Crewpostor": "#ff1919", - "Refugee": "#ff1919", - "Infectious": "#7B8968", - "Virus": "#2E8B57", - "Overseer": "#BA55D3", - "Pursuer": "#617218", - "Specter": "#662962", - "Jinx": "#ed2f91", - "Troller": "#006994", - "Maverick": "#781717", - "CursedSoul": "#531269", - "PotionMaster": "#663399", - "Pickpocket": "#47008B", - "Traitor": "#BA2E05", - "Vulture": "#556B2F", - "Taskinator": "#4737ae", - "Medusa": "#9900CC", - "Spiritcaller": "#003366", - "EvilSpirit": "#003366", - "Evader": "#9beb34", - "Amnesiac": "#7FBFFF", - "Doomsayer": "#14f786", - "PunchingBag": "#684405", - "Pirate": "#EDC240", - "Shroud": "#6697FF", - "Werewolf": "#191970", - "Seeker": "#ffaa00", - "Pixie": "#00FF00", - "Imitator": "#B3D94C", - "Doppelganger": "#f6f4a3", - "GM": "#ff5b70", - "NotAssigned": "#ffffff", - "LastImpostor": "#ff1919", - "Lovers": "#ff9ace", - "Madmate": "#ff1919", - "Watcher": "#800080", - "Flash": "#ff8400", - "Torch": "#eee5be", - "Seer": "#61b26c", - "Tiebreaker": "#1447af", - "Oblivious": "#424242", - "Bewilder": "#c894f5", - "Workhorse": "#00ffff", - "Fool": "#e6e7ff", - "Avanger": "#ffab1c", - "Youtuber": "#fb749b", - "Egoist": "#5600ff", - "Stealer": "#ff1919", - "Paranoia": "#3a648f", - "Mimic": "#ff1919", - "Guesser": "#f8cd46", - "Necroview": "#663399", - "Reach": "#74ba43", - "Charmed": "#cf6acd", - "Cleansed": "#98FF98", - "Bait": "#00f7ff", - "Trapper": "#5a8fd0", - "Infected": "#7B8968", - "Onbound": "#BAAAE9", - "Rebound": "#56b5ff", - "Knighted": "#FFA500", - "Contagious": "#2E8B57", - "Unreportable": "#FF6347", - "Lucky": "#b8d7a3", - "Unlucky": "#d7a3a3", - "DoubleShot": "#19fa8d", - "Rascal": "#990000", - "Soulless": "#531269", - "Gravestone": "#2EA8E7", - "Lazy": "#a4dffe", - "Autopsy": "#80ffdd", - "Loyal": "#B71556", - "Visionary": "#ff1919", - "Recruit": "#00b4eb", - "Admired": "#ee43c3", - "Diseased": "#AAAAAA", - "Antidote": "#FF9876", - "VoidBallot": "#FF3399", - "Aware": "#4B0082", - "Stubborn": "#FF5733", - "Fragile": "#D3D3D3", - "Burst": "#B619B9", - "Bloodthirst": "#691a2e", - "Overclocked": "#C4AD2C", - "Swift": "#ff1919", - "Mare": "#ff1919", - "Ghoul": "#B22222", - "Sleuth": "#803333", - "Clumsy": "#ff1919", - "Circumvent": "#ff1919", - "Tricky": "#ff1919", - "Nimble": "#FFFAA6", - "Cyber": "#F46F4E", - "Hurried": "#136cf0", - "Oiiai": "#2bdb2b", - "Influenced": "#b0006a", - "Captain": "#4682B4", - "Benefactor": "#27ae60", - "Silent": "#9da9cf", - "Susceptible": "#2DFA04", - "Keeper": "#9ed9c8", - "Mundane": "#E69B4C", - "GuessMaster": "#FFD700", - "Killer": "#00ffff", - "Quizmaster": "#8666bd", - "Tired": "#9cdff0", - "SchrodingersCat": "#404040", - "PlagueDoctor": "#ff6633", - "Rainbow": "#55FFCB", - "Statue": "#7E9C8A", - "Warden": "#588733", - "Hawk": "#606c80", - "Spurt": "#c9e8f5", - "Ghastly": "#9ad6d4", - "Glow": "#E2F147", - "Radar": "#1eff1e", - "Rebirth": "#f08c22", - "Sloth": "#376db8", - "Eavesdropper": "#ffe6bf", - "Shocker": "#CCCC00", - "Revenant": "#cc9329" + "Crewmate": "#8cffff", + "Engineer": "#FF6A00", + "Scientist": "#8ee98e", + "GuardianAngel": "#77e6d1", + "Noisemaker": "#9100E3", + "Tracker": "#1BB313", + "CrewmateTOHE": "#8cffff", + "EngineerTOHE": "#FF6A00", + "ScientistTOHE": "#8ee98e", + "GuardianAngelTOHE": "#77e6d1", + "NoisemakerTOHE": "#9100E3", + "TrackerTOHE": "#1BB313", + "EvilMini": "#FF1919", + "NiceMini": "#edc240", + "Mini": "#dddddd", + "President": "#00ffac", + "LazyGuy": "#a4dffe", + "Mechanic": "#3333ff", + "Snitch": "#b8fb4f", + "Marshall": "#5573aa", + "Mayor": "#204d42", + "Bastion": "#696969", + "Psychic": "#6F698C", + "Cleanser": "#98FF98", + "Sheriff": "#ffb347", + "Vigilante": "#9900CC", + "CopyCat": "#ffb2ab", + "SuperStar": "#f6f657", + "Celebrity": "#ee4a55", + "SpeedBooster": "#00ffff", + "Doctor": "#80ffdd", + "Dictator": "#df9b00", + "Detective": "#7160e8", + "NiceGuesser": "#f0e68c", + "Knight": "#7a7a7a", + "Transporter": "#42D1FF", + "TimeManager": "#6495ed", + "Veteran": "#a77738", + "Altruist": "#9b0202", + "Bodyguard": "#185abd", + "Deceiver": "#BE29EC", + "Witness": "#e70052", + "Grenadier": "#3c4a16", + "Lighter": "#eee5be", + "TaskManager": "#00ffa5", + "Medic": "#00ff97", + "FortuneTeller": "#882c83", + "Glitch": "#39FF14", + "Judge": "#f8d85a", + "Lookout": "#2a52be", + "Evolver": "#6dd85e", + "Mortician": "#333c49", + "Medium": "#a200ff", + "Observer": "#a8e0fa", + "Pacifist": "#007FFF", + "Monarch": "#FFA500", + "Coroner": "#8B0000", + "Merchant": "#D27D2D", + "Retributionist": "#228B22", + "Alchemist": "#a058bf", + "Deputy": "#df9026", + "Investigator": "#007FFF", + "Jailer": "#aa900d", + "Guardian": "#2E8B57", + "Addict": "#008000", + "Mole": "#3E2723", + "Tracefinder": "#0066CC", + "Oracle": "#6666FF", + "Spiritualist": "#669999", + "Chameleon": "#01C834", + "Inspector": "#0D57AF", + "Admirer": "#ee43c3", + "TimeMaster": "#44baff", + "Crusader": "#C65C39", + "Reverie": "#00BFFF", + "Telecommunication": "#7223DA", + "Swapper": "#66E666", + "ChiefOfPolice": "#f8cd46", + "Spy": "#34495E", + "Randomizer": "#FFFFFF", + "Enigma": "#676798", + "Arsonist": "#ff6633", + "Pyromaniac": "#fc8a4c", + "Ventguard": "#ffa5ff", + "Agitater": "#F3A359", + "Bandit": "#8B008B", + "Apocalypse": "#ff174f", + "PlagueBearer": "#e5f6b4", + "Pestilence": "#343136", + "SoulCollector": "#A675A1", + "Death": "#644661", + "Baker": "#bf9f7a", + "Famine": "#83461c", + "Berserker": "#cc0044", + "War": "#2B0804", + "Jester": "#ec62a5", + "Terrorist": "#00e600", + "Executioner": "#c0c0c0", + "Lawyer": "#008080", + "God": "#f96464", + "Opportunist": "#4dff4d", + "Shaman": "#50c878", + "Vector": "#ff6201", + "Jackal": "#00b4eb", + "Sidekick": "#00b4eb", + "Innocent": "#8f815e", + "Pelican": "#34C849", + "Revolutionist": "#ba4d06", + "Hater": "#414b66", + "Prohibited": "#6a8f8f", + "Demon": "#68bc71", + "Stalker": "#483d8b", + "Workaholic": "#008b8b", + "Solsticer": "#fbfa83", + "Collector": "#9d8892", + "Provocateur": "#74ba43", + "Sunnyboy": "#ff9902", + "Poisoner": "#478800", + "Huntsman": "#ad8739", + "Necromancer": "#9C87AB", + "Follower": "#ff9409", + "Romantic": "#FF1493", + "VengefulRomantic": "#8B0000", + "RuthlessRomantic": "#D2691E", + "Cultist": "#cf6acd", + "HexMaster": "#ff00ff", + "Wraith": "#4B0082", + "SerialKiller": "#233fcc", + "BloodKnight": "#630000", + "Juggernaut": "#A41342", + "Parasite": "#ff1919", + "Crewpostor": "#ff1919", + "Refugee": "#ff1919", + "Infectious": "#7B8968", + "Virus": "#2E8B57", + "Overseer": "#BA55D3", + "Pursuer": "#617218", + "Specter": "#662962", + "Jinx": "#ed2f91", + "Troller": "#006994", + "Maverick": "#781717", + "CursedSoul": "#531269", + "PotionMaster": "#663399", + "Pickpocket": "#47008B", + "Traitor": "#BA2E05", + "Vulture": "#556B2F", + "Taskinator": "#4737ae", + "Medusa": "#9900CC", + "Spiritcaller": "#003366", + "EvilSpirit": "#003366", + "Evader": "#9beb34", + "Amnesiac": "#7FBFFF", + "Doomsayer": "#14f786", + "PunchingBag": "#684405", + "Pirate": "#EDC240", + "Shroud": "#6697FF", + "Werewolf": "#191970", + "Seeker": "#ffaa00", + "Pixie": "#00FF00", + "Imitator": "#B3D94C", + "Doppelganger": "#f6f4a3", + "GM": "#ff5b70", + "NotAssigned": "#ffffff", + "LastImpostor": "#ff1919", + "Lovers": "#ff9ace", + "Madmate": "#ff1919", + "Watcher": "#800080", + "Flash": "#ff8400", + "Torch": "#eee5be", + "Seer": "#61b26c", + "Tiebreaker": "#1447af", + "Oblivious": "#424242", + "Bewilder": "#c894f5", + "Workhorse": "#00ffff", + "Fool": "#e6e7ff", + "Avanger": "#ffab1c", + "Youtuber": "#fb749b", + "Egoist": "#5600ff", + "Stealer": "#ff1919", + "Paranoia": "#3a648f", + "Mimic": "#ff1919", + "Guesser": "#f8cd46", + "Necroview": "#663399", + "Reach": "#74ba43", + "Charmed": "#cf6acd", + "Cleansed": "#98FF98", + "Bait": "#00f7ff", + "Trapper": "#5a8fd0", + "Infected": "#7B8968", + "Onbound": "#BAAAE9", + "Rebound": "#56b5ff", + "Knighted": "#FFA500", + "Contagious": "#2E8B57", + "Unreportable": "#FF6347", + "Lucky": "#b8d7a3", + "Unlucky": "#d7a3a3", + "DoubleShot": "#19fa8d", + "Rascal": "#990000", + "Soulless": "#531269", + "Gravestone": "#2EA8E7", + "Lazy": "#a4dffe", + "Autopsy": "#80ffdd", + "Loyal": "#B71556", + "Visionary": "#ff1919", + "Recruit": "#00b4eb", + "Admired": "#ee43c3", + "Diseased": "#AAAAAA", + "Antidote": "#FF9876", + "VoidBallot": "#FF3399", + "Aware": "#4B0082", + "Stubborn": "#FF5733", + "Fragile": "#D3D3D3", + "Burst": "#B619B9", + "Bloodthirst": "#691a2e", + "Overclocked": "#C4AD2C", + "Swift": "#ff1919", + "Mare": "#ff1919", + "Ghoul": "#B22222", + "Sleuth": "#803333", + "Clumsy": "#ff1919", + "Circumvent": "#ff1919", + "Tricky": "#ff1919", + "Nimble": "#FFFAA6", + "Cyber": "#F46F4E", + "Hurried": "#136cf0", + "Oiiai": "#2bdb2b", + "Influenced": "#b0006a", + "Captain": "#4682B4", + "Benefactor": "#27ae60", + "Silent": "#9da9cf", + "Susceptible": "#2DFA04", + "Keeper": "#9ed9c8", + "Mundane": "#E69B4C", + "GuessMaster": "#FFD700", + "Killer": "#00ffff", + "Quizmaster": "#8666bd", + "Tired": "#9cdff0", + "SchrodingersCat": "#404040", + "PlagueDoctor": "#ff6633", + "Rainbow": "#55FFCB", + "Statue": "#7E9C8A", + "Warden": "#588733", + "Hawk": "#606c80", + "Allergic": "#f2b542", + "Spurt": "#c9e8f5", + "Ghastly": "#9ad6d4", + "Glow": "#E2F147", + "Radar": "#1eff1e", + "Rebirth": "#f08c22", + "Sloth": "#376db8", + "Eavesdropper": "#ffe6bf" } diff --git a/Roles/(Ghosts)/Crewmate/Ghastly.cs b/Roles/(Ghosts)/Crewmate/Ghastly.cs index eb70bc74c..cadfe072f 100644 --- a/Roles/(Ghosts)/Crewmate/Ghastly.cs +++ b/Roles/(Ghosts)/Crewmate/Ghastly.cs @@ -1,19 +1,16 @@ using AmongUs.GameOptions; -using Hazel; -using InnerNet; using TOHE.Roles.Core; -using TOHE.Roles.Double; -using UnityEngine; using static TOHE.Options; using static TOHE.Translator; using static TOHE.Utils; +using UnityEngine; +using TOHE.Roles.Double; namespace TOHE.Roles._Ghosts_.Crewmate; internal class Ghastly : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Ghastly; private const int Id = 22060; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Ghastly); public override CustomRoles ThisRoleBase => CustomRoles.GuardianAngel; @@ -44,14 +41,6 @@ public override void SetupCustomOption() GhastlyKillAllies = BooleanOptionItem.Create(Id + 14, "GhastlyKillAllies", false, TabGroup.CrewmateRoles, false) .SetParent(CustomRoleSpawnChances[CustomRoles.Ghastly]); } - - public override void Init() - { - KillerIsChosen = false; - killertarget = (byte.MaxValue, byte.MaxValue); - LastTime.Clear(); - } - public override void Add(byte playerId) { AbilityLimit = MaxPossesions.GetInt(); @@ -60,26 +49,6 @@ public override void Add(byte playerId) CustomRoleManager.CheckDeadBodyOthers.Add(CheckDeadBody); } - public void SendRPC() - { - var writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.PlayerId, (byte)CustomRPC.SyncRoleSkill, SendOption.Reliable, -1); - writer.WriteNetObject(_Player); - writer.Write(AbilityLimit); - writer.Write(KillerIsChosen); - writer.Write(killertarget.Item1); - writer.Write(killertarget.Item2); - AmongUsClient.Instance.FinishRpcImmediately(writer); - } - - public override void ReceiveRPC(MessageReader reader, PlayerControl pc) - { - AbilityLimit = reader.ReadSingle(); - KillerIsChosen = reader.ReadBoolean(); - var item1 = reader.ReadByte(); - var item2 = reader.ReadByte(); - killertarget = (item1, item2); - } - public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.GuardianAngelCooldown = PossessCooldown.GetFloat(); @@ -92,10 +61,8 @@ public override bool OnCheckProtect(PlayerControl angel, PlayerControl target) angel.Notify(ColorString(GetRoleColor(CustomRoles.Gangster), GetString("CantPosses"))); return true; } - if (AbilityLimit <= 0) { - SendRPC(); angel.Notify(GetString("GhastlyNoMorePossess")); return false; } @@ -123,6 +90,7 @@ public override bool OnCheckProtect(PlayerControl angel, PlayerControl target) { Target = target.PlayerId; AbilityLimit--; + SendSkillRPC(); LastTime.Add(killer, GetTimeStamp()); KillerIsChosen = false; @@ -141,12 +109,11 @@ public override bool OnCheckProtect(PlayerControl angel, PlayerControl target) } killertarget = (killer, Target); - SendRPC(); return false; } private bool CheckConflicts(PlayerControl target) => target != null && (!GhastlyKillAllies.GetBool() || target.GetCountTypes() != _Player.GetCountTypes()); - + public override void OnFixedUpdate(PlayerControl player, bool lowLoad, long nowTime) { if (lowLoad) return; @@ -159,16 +126,16 @@ public override void OnFixedUpdate(PlayerControl player, bool lowLoad, long nowT } public void OnFixUpdateOthers(PlayerControl player, bool lowLoad, long nowTime) { - if (!lowLoad && killertarget.Item1 == player.PlayerId + if (!lowLoad && killertarget.Item1 == player.PlayerId && LastTime.TryGetValue(player.PlayerId, out var now) && now + PossessDur.GetInt() <= nowTime) { - _Player?.Notify(string.Format($"\n{GetString("GhastlyExpired")}\n", player.GetRealName())); + _Player?.Notify(string.Format($"\n{ GetString("GhastlyExpired")}\n", player.GetRealName())); TargetArrow.Remove(killertarget.Item1, killertarget.Item2); LastTime.Remove(player.PlayerId); KillerIsChosen = false; killertarget = (byte.MaxValue, byte.MaxValue); - SendRPC(); } + } public override bool CheckMurderOnOthersTarget(PlayerControl killer, PlayerControl target) { @@ -180,14 +147,13 @@ public override bool CheckMurderOnOthersTarget(PlayerControl killer, PlayerContr killer.Notify(GetString("GhastlyNotUrTarget")); return true; } - else + else { _Player?.Notify(string.Format($"\n{GetString("GhastlyExpired")}\n", killer.GetRealName())); TargetArrow.Remove(killertarget.Item1, killertarget.Item2); LastTime.Remove(killer.PlayerId); KillerIsChosen = false; killertarget = (byte.MaxValue, byte.MaxValue); - SendRPC(); } } return false; @@ -222,7 +188,6 @@ private void CheckDeadBody(PlayerControl killer, PlayerControl target, bool inMe LastTime.Remove(target.PlayerId); KillerIsChosen = false; killertarget = (byte.MaxValue, byte.MaxValue); - SendRPC(); } } diff --git a/Roles/(Ghosts)/Crewmate/GuardianAngelTOHE.cs b/Roles/(Ghosts)/Crewmate/GuardianAngelTOHE.cs index ab61d0d43..70374b978 100644 --- a/Roles/(Ghosts)/Crewmate/GuardianAngelTOHE.cs +++ b/Roles/(Ghosts)/Crewmate/GuardianAngelTOHE.cs @@ -7,9 +7,10 @@ namespace TOHE.Roles._Ghosts_.Crewmate; internal class GuardianAngelTOHE : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.GuardianAngelTOHE; private const int Id = 20900; - + private static readonly HashSet PlayerIds = []; + public static bool HasEnabled => PlayerIds.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.GuardianAngel; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateVanillaGhosts; //==================================================================\\ @@ -31,11 +32,13 @@ public override void SetupCustomOption() public override void Init() { PlayerShield.Clear(); + PlayerIds.Clear(); } public override void Add(byte playerId) { CustomRoleManager.OnFixedUpdateOthers.Add(OnOthersFixedUpdate); CustomRoleManager.CheckDeadBodyOthers.Add(CheckDeadBody); + PlayerIds.Add(playerId); } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { diff --git a/Roles/(Ghosts)/Crewmate/Hawk.cs b/Roles/(Ghosts)/Crewmate/Hawk.cs index f259593c1..042d5ac15 100644 --- a/Roles/(Ghosts)/Crewmate/Hawk.cs +++ b/Roles/(Ghosts)/Crewmate/Hawk.cs @@ -12,7 +12,6 @@ namespace TOHE.Roles._Ghosts_.Crewmate; internal class Hawk : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Hawk; private const int Id = 28000; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Hawk); public override CustomRoles ThisRoleBase => CustomRoles.GuardianAngel; @@ -24,7 +23,7 @@ internal class Hawk : RoleBase public static OptionItem MinimumPlayersAliveToKill; public static OptionItem MissChance; public static OptionItem IncreaseByOneIfConvert; - + public readonly Dictionary KillerChanceMiss = []; public int KeepCount = 0; public override void SetupCustomOption() @@ -115,7 +114,7 @@ private bool CheckRetriConflicts(PlayerControl target) && !target.Is(CustomRoles.CursedWolf) && (!target.Is(CustomRoles.NiceMini) || Mini.Age > 18); } - public override string GetProgressText(byte playerId, bool coms) + public override string GetProgressText(byte playerId, bool coms) => ColorString(AbilityLimit > 0 ? GetRoleColor(CustomRoles.Hawk).ShadeColor(0.25f) : Color.gray, $"({AbilityLimit})"); } diff --git a/Roles/(Ghosts)/Crewmate/Warden.cs b/Roles/(Ghosts)/Crewmate/Warden.cs index 0e708b8aa..6d2718685 100644 --- a/Roles/(Ghosts)/Crewmate/Warden.cs +++ b/Roles/(Ghosts)/Crewmate/Warden.cs @@ -9,7 +9,6 @@ namespace TOHE.Roles._Ghosts_.Crewmate; internal class Warden : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Warden; private const int Id = 27800; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Warden); public override CustomRoles ThisRoleBase => CustomRoles.GuardianAngel; @@ -43,7 +42,7 @@ public override void ApplyGameOptions(IGameOptions opt, byte playerId) public override bool OnCheckProtect(PlayerControl killer, PlayerControl target) { var getTargetRole = target.GetCustomRole(); - if (AbilityLimit > 0) + if (AbilityLimit > 0) { if (getTargetRole.IsSpeedRole() || target.IsAnySubRole(x => x.IsSpeedRole()) || IsAffected.Contains(target.PlayerId)) goto Notifiers; // Incompactible speed-roles @@ -62,7 +61,7 @@ public override bool OnCheckProtect(PlayerControl killer, PlayerControl target) Notifiers: target.Notify(Utils.ColorString(new Color32(179, 0, 0, byte.MaxValue), GetString("WardenWarn"))); - + killer.RpcResetAbilityCooldown(); AbilityLimit--; SendSkillRPC(); @@ -72,4 +71,4 @@ public override bool OnCheckProtect(PlayerControl killer, PlayerControl target) public override string GetProgressText(byte playerId, bool cooms) => Utils.ColorString(AbilityLimit > 0 ? Utils.GetRoleColor(CustomRoles.Warden).ShadeColor(0.25f) : Color.gray, $"({AbilityLimit})"); -} +} \ No newline at end of file diff --git a/Roles/(Ghosts)/Impostor/Bloodmoon.cs b/Roles/(Ghosts)/Impostor/Bloodmoon.cs index d45670ade..57312a311 100644 --- a/Roles/(Ghosts)/Impostor/Bloodmoon.cs +++ b/Roles/(Ghosts)/Impostor/Bloodmoon.cs @@ -13,7 +13,6 @@ namespace TOHE.Roles._Ghosts_.Impostor; internal class Bloodmoon : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Bloodmoon; private const int Id = 28100; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Bloodmoon); public override CustomRoles ThisRoleBase => CustomRoles.GuardianAngel; @@ -102,8 +101,8 @@ public override bool OnCheckProtect(PlayerControl killer, PlayerControl target) return false; } public override string GetProgressText(byte playerId, bool cooms) - => ColorString(AbilityLimit > 0 ? GetRoleColor(CustomRoles.Bloodmoon).ShadeColor(0.25f) : Color.gray, $"({AbilityLimit})"); - + => ColorString(AbilityLimit > 0 ? GetRoleColor(CustomRoles.Bloodmoon).ShadeColor(0.25f) : Color.gray, $"({AbilityLimit})"); + private void OnFixedUpdateOther(PlayerControl player, bool lowLoad, long nowTime) { if (lowLoad || _Player == null) return; diff --git a/Roles/(Ghosts)/Impostor/Minion.cs b/Roles/(Ghosts)/Impostor/Minion.cs index 62ce41111..028cea345 100644 --- a/Roles/(Ghosts)/Impostor/Minion.cs +++ b/Roles/(Ghosts)/Impostor/Minion.cs @@ -8,9 +8,10 @@ namespace TOHE.Roles._Ghosts_.Impostor; internal class Minion : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Minion; private const int Id = 27900; - + private static readonly HashSet Playerids = []; + public static bool HasEnabled => Playerids.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.GuardianAngel; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorGhosts; //==================================================================\\ @@ -26,6 +27,14 @@ public override void SetupCustomOption() AbilityTime = FloatOptionItem.Create(Id + 11, "MinionAbilityTime", new(1f, 10f, 1f), 5f, TabGroup.ImpostorRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Minion]) .SetValueFormat(OptionFormat.Seconds); } + public override void Init() + { + Playerids.Clear(); + } + public override void Add(byte playerId) + { + Playerids.Add(playerId); + } // EAC bans players when GA uses sabotage public override bool CanUseSabotage(PlayerControl pc) => false; public override void ApplyGameOptions(IGameOptions opt, byte playerId) @@ -49,7 +58,7 @@ public override bool OnCheckProtect(PlayerControl killer, PlayerControl target) { Main.PlayerStates[target.PlayerId].IsBlackOut = true; target.MarkDirtySettings(); - + _ = new LateTask(() => { Main.PlayerStates[target.PlayerId].IsBlackOut = false; diff --git a/Roles/(Ghosts)/Impostor/Possessor.cs b/Roles/(Ghosts)/Impostor/Possessor.cs index 958ede4ba..5ef7042b4 100644 --- a/Roles/(Ghosts)/Impostor/Possessor.cs +++ b/Roles/(Ghosts)/Impostor/Possessor.cs @@ -9,7 +9,6 @@ namespace TOHE.Roles._Ghosts_.Impostor; internal class Possessor : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Possessor; private const int Id = 28900; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Possessor); public override CustomRoles ThisRoleBase => CustomRoles.GuardianAngel; @@ -131,8 +130,16 @@ public override bool OnCheckProtect(PlayerControl killer, PlayerControl target) { if (target.GetCustomRole().IsImpostorTeam()) { + var killerState = Main.PlayerStates[killer.PlayerId]; + + // Allow Randomizer to bypass the check + if (killerState.IsRandomizer) + { + Logger.Info($"Randomizer {killer.name} is attempting to use the ability on {target.name}. Bypassing impostor restriction.", "GhostRole"); + return true; // Allow the ability to proceed + } killer.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Possessor), GetString("DollMaster_CannotPossessImpTeammate"))); - return false; + return true; } if (!controllingPlayer) diff --git a/Roles/AddOns/Common/Antidote.cs b/Roles/AddOns/Common/Antidote.cs index 25194449e..932e1ae8a 100644 --- a/Roles/AddOns/Common/Antidote.cs +++ b/Roles/AddOns/Common/Antidote.cs @@ -4,12 +4,10 @@ namespace TOHE.Roles.AddOns.Common; public class Antidote : IAddon { - public CustomRoles Role => CustomRoles.Antidote; private const int Id = 21400; public static bool IsEnable = false; public AddonTypes Type => AddonTypes.Mixed; - private static OptionItem AntidoteCDOpt; private static OptionItem AntidoteCDReset; diff --git a/Roles/AddOns/Common/Autopsy.cs b/Roles/AddOns/Common/Autopsy.cs index 16295cedb..affe2375f 100644 --- a/Roles/AddOns/Common/Autopsy.cs +++ b/Roles/AddOns/Common/Autopsy.cs @@ -4,7 +4,6 @@ namespace TOHE.Roles.AddOns.Common; public class Autopsy : IAddon { - public CustomRoles Role => CustomRoles.Autopsy; private const int Id = 18600; public AddonTypes Type => AddonTypes.Helpful; public void SetupCustomOption() @@ -17,4 +16,4 @@ public void Add(byte playerId, bool gameIsLoading = true) { } public void Remove(byte playerId) { } -} +} \ No newline at end of file diff --git a/Roles/AddOns/Common/Avanger.cs b/Roles/AddOns/Common/Avanger.cs index dc421a8f1..edbf1b64d 100644 --- a/Roles/AddOns/Common/Avanger.cs +++ b/Roles/AddOns/Common/Avanger.cs @@ -8,7 +8,6 @@ namespace TOHE.Roles.AddOns.Common; public class Avanger : IAddon { - public CustomRoles Role => CustomRoles.Avanger; private const int Id = 21500; public AddonTypes Type => AddonTypes.Mixed; @@ -27,7 +26,7 @@ public static void OnMurderPlayer(PlayerControl target) { var pcList = Main.AllAlivePlayerControls.Where(pc => pc.PlayerId != target.PlayerId && !Pelican.IsEaten(pc.PlayerId) && !Guardian.CannotBeKilled(pc) && !Medic.IsProtected(pc.PlayerId) && !pc.Is(CustomRoles.Pestilence) && !pc.Is(CustomRoles.Necromancer) && !pc.Is(CustomRoles.PunchingBag) && !pc.Is(CustomRoles.Solsticer) && !((pc.Is(CustomRoles.NiceMini) || pc.Is(CustomRoles.EvilMini)) && Mini.Age < 18)).ToList(); - + if (pcList.Any()) { PlayerControl rp = pcList.RandomElement(); diff --git a/Roles/AddOns/Common/Aware.cs b/Roles/AddOns/Common/Aware.cs index 6449e07c9..e83998dcb 100644 --- a/Roles/AddOns/Common/Aware.cs +++ b/Roles/AddOns/Common/Aware.cs @@ -1,11 +1,10 @@ -using static TOHE.Options; -using static TOHE.Translator; +using static TOHE.Translator; +using static TOHE.Options; namespace TOHE.Roles.AddOns.Common; public class Aware : IAddon { - public CustomRoles Role => CustomRoles.Aware; private const int Id = 21600; public static bool IsEnable = false; public AddonTypes Type => AddonTypes.Mixed; @@ -61,7 +60,7 @@ public static void OnCheckMurder(CustomRoles killerRole, PlayerControl target) } } - public static void OnReportDeadBody() + public static void OnReportDeadBody() { foreach (var (pid, list) in AwareInteracted) { diff --git a/Roles/AddOns/Common/Bait.cs b/Roles/AddOns/Common/Bait.cs index c45b24cd3..3184cf1f1 100644 --- a/Roles/AddOns/Common/Bait.cs +++ b/Roles/AddOns/Common/Bait.cs @@ -1,13 +1,12 @@ using System; using TOHE.Modules; -using static TOHE.Options; using static TOHE.Translator; +using static TOHE.Options; namespace TOHE.Roles.AddOns.Common; public class Bait : IAddon { - public CustomRoles Role => CustomRoles.Bait; private const int Id = 18700; public AddonTypes Type => AddonTypes.Helpful; @@ -16,7 +15,7 @@ public class Bait : IAddon public static OptionItem BaitDelayNotify; public static OptionItem BaitNotification; public static OptionItem BaitCanBeReportedUnderAllConditions; - + public static readonly HashSet BaitAlive = []; public void SetupCustomOption() @@ -63,7 +62,7 @@ public static void SendNotify() } } public static void BaitAfterDeathTasks(PlayerControl killer, PlayerControl target) - { + { if (killer.PlayerId == target.PlayerId) { if (target.GetRealKiller() != null) diff --git a/Roles/AddOns/Common/Beartrap.cs b/Roles/AddOns/Common/Beartrap.cs index 2ff639308..a465b7000 100644 --- a/Roles/AddOns/Common/Beartrap.cs +++ b/Roles/AddOns/Common/Beartrap.cs @@ -4,7 +4,6 @@ namespace TOHE.Roles.AddOns.Common; public class Trapper : IAddon { - public CustomRoles Role => CustomRoles.Trapper; private const int Id = 18800; public AddonTypes Type => AddonTypes.Helpful; diff --git a/Roles/AddOns/Common/Bewilder.cs b/Roles/AddOns/Common/Bewilder.cs index 67193b642..dbd1f02ba 100644 --- a/Roles/AddOns/Common/Bewilder.cs +++ b/Roles/AddOns/Common/Bewilder.cs @@ -5,7 +5,6 @@ namespace TOHE.Roles.AddOns.Common; public class Bewilder : IAddon { - public CustomRoles Role => CustomRoles.Bewilder; private const int Id = 18900; public AddonTypes Type => AddonTypes.Helpful; @@ -40,11 +39,11 @@ public void Remove(byte playerId) IsEnable = false; } - public static void ApplyVisionOptions(IGameOptions opt) - { - opt.SetVision(false); - opt.SetFloat(FloatOptionNames.ImpostorLightMod, BewilderVision.GetFloat()); - opt.SetFloat(FloatOptionNames.CrewLightMod, BewilderVision.GetFloat()); + public static void ApplyVisionOptions(IGameOptions opt) + { + opt.SetVision(false); + opt.SetFloat(FloatOptionNames.ImpostorLightMod, BewilderVision.GetFloat()); + opt.SetFloat(FloatOptionNames.CrewLightMod, BewilderVision.GetFloat()); } public static void ApplyGameOptions(IGameOptions opt, PlayerControl player) { diff --git a/Roles/AddOns/Common/Burst.cs b/Roles/AddOns/Common/Burst.cs index 55df80e62..f87214610 100644 --- a/Roles/AddOns/Common/Burst.cs +++ b/Roles/AddOns/Common/Burst.cs @@ -5,7 +5,6 @@ namespace TOHE.Roles.AddOns.Common; public class Burst : IAddon { - public CustomRoles Role => CustomRoles.Burst; private const int Id = 19000; public static bool IsEnable = false; public AddonTypes Type => AddonTypes.Helpful; @@ -71,4 +70,4 @@ public static void AfterBurstDeadTasks(PlayerControl killer, PlayerControl targe }, BurstKillDelay.GetFloat(), "Burst Suicide"); } } -} +} \ No newline at end of file diff --git a/Roles/AddOns/Common/Cyber.cs b/Roles/AddOns/Common/Cyber.cs index 8391d8680..4afeda11a 100644 --- a/Roles/AddOns/Common/Cyber.cs +++ b/Roles/AddOns/Common/Cyber.cs @@ -4,7 +4,6 @@ namespace TOHE.Roles.AddOns.Common; public class Cyber : IAddon { - public CustomRoles Role => CustomRoles.Cyber; private const int Id = 19100; public AddonTypes Type => AddonTypes.Helpful; @@ -62,4 +61,4 @@ public static void AfterCyberDeadTask(PlayerControl target, bool inMeeting) if (!inMeeting && !CyberDead.Contains(target.PlayerId)) CyberDead.Add(target.PlayerId); } -} +} \ No newline at end of file diff --git a/Roles/AddOns/Common/Diseased.cs b/Roles/AddOns/Common/Diseased.cs index 5fb1dc12c..75732fd3a 100644 --- a/Roles/AddOns/Common/Diseased.cs +++ b/Roles/AddOns/Common/Diseased.cs @@ -4,7 +4,6 @@ namespace TOHE.Roles.AddOns.Common; public class Diseased : IAddon { - public CustomRoles Role => CustomRoles.Diseased; private const int Id = 21800; public static bool IsEnable = false; public AddonTypes Type => AddonTypes.Mixed; @@ -66,8 +65,8 @@ public static void AfterMeetingTasks() } } - public static void CheckMurder(PlayerControl killer) - { + public static void CheckMurder(PlayerControl killer) + { if (KilledDiseased.ContainsKey(killer.PlayerId)) { // Key already exists, update the value @@ -78,7 +77,7 @@ public static void CheckMurder(PlayerControl killer) // Key doesn't exist, add the key-value pair KilledDiseased.Add(killer.PlayerId, 1); } - } + } } diff --git a/Roles/AddOns/Common/DoubleShot.cs b/Roles/AddOns/Common/DoubleShot.cs index 44b9903c8..de2155975 100644 --- a/Roles/AddOns/Common/DoubleShot.cs +++ b/Roles/AddOns/Common/DoubleShot.cs @@ -4,7 +4,6 @@ namespace TOHE.Roles.AddOns.Common; public class DoubleShot : IAddon { - public CustomRoles Role => CustomRoles.DoubleShot; public static readonly HashSet IsActive = []; public AddonTypes Type => AddonTypes.Guesser; @@ -31,4 +30,4 @@ public void Add(byte playerId, bool gameIsLoading = true) { } public void Remove(byte playerId) { } -} +} \ No newline at end of file diff --git a/Roles/AddOns/Common/Eavesdropper.cs b/Roles/AddOns/Common/Eavesdropper.cs index 8bad4bb9f..f26b7ae38 100644 --- a/Roles/AddOns/Common/Eavesdropper.cs +++ b/Roles/AddOns/Common/Eavesdropper.cs @@ -4,7 +4,6 @@ namespace TOHE.Roles.AddOns.Common; public class Eavesdropper : IAddon { - public CustomRoles Role => CustomRoles.Eavesdropper; public const int Id = 30100; private static readonly HashSet playerList = []; public static bool IsEnable = false; @@ -45,7 +44,7 @@ public static void GetMessage() { // Get all specific msg var eavesdropperMsg = MeetingHudStartPatch.msgToSend.Where(x => x.Item2 != 255).Select(x => x.Item1).ToList(); - + // Check any data if (eavesdropperMsg.Any()) { diff --git a/Roles/AddOns/Common/Egoist.cs b/Roles/AddOns/Common/Egoist.cs index 315774258..f7d44af41 100644 --- a/Roles/AddOns/Common/Egoist.cs +++ b/Roles/AddOns/Common/Egoist.cs @@ -4,7 +4,6 @@ namespace TOHE.Roles.AddOns.Common; public class Egoist : IAddon { - public CustomRoles Role => CustomRoles.Egoist; private const int Id = 23500; public AddonTypes Type => AddonTypes.Misc; @@ -28,4 +27,4 @@ public void Add(byte playerId, bool gameIsLoading = true) { } public void Remove(byte playerId) { } -} +} \ No newline at end of file diff --git a/Roles/AddOns/Common/Evader.cs b/Roles/AddOns/Common/Evader.cs index 202444fe2..6c5c7da5f 100644 --- a/Roles/AddOns/Common/Evader.cs +++ b/Roles/AddOns/Common/Evader.cs @@ -3,7 +3,6 @@ namespace TOHE.Roles.AddOns.Common; public class Evader : IAddon { - public CustomRoles Role => CustomRoles.Evader; private const int Id = 29600; public AddonTypes Type => AddonTypes.Helpful; diff --git a/Roles/AddOns/Common/Flash.cs b/Roles/AddOns/Common/Flash.cs index 958aabb3e..2f61da7dd 100644 --- a/Roles/AddOns/Common/Flash.cs +++ b/Roles/AddOns/Common/Flash.cs @@ -5,7 +5,6 @@ namespace TOHE.Roles.AddOns.Common; public class Flash : IAddon { - public CustomRoles Role => CustomRoles.Flash; private const int Id = 26100; public AddonTypes Type => AddonTypes.Helpful; @@ -33,4 +32,4 @@ public static void SetSpeed(byte playerId) { Main.AllPlayerSpeed[playerId] = OptionSpeed.GetFloat(); } -} +} \ No newline at end of file diff --git a/Roles/AddOns/Common/Fool.cs b/Roles/AddOns/Common/Fool.cs index b624c5b33..8338f3f3c 100644 --- a/Roles/AddOns/Common/Fool.cs +++ b/Roles/AddOns/Common/Fool.cs @@ -4,7 +4,6 @@ namespace TOHE.Roles.AddOns.Common; public class Fool : IAddon { - public CustomRoles Role => CustomRoles.Fool; private const int Id = 25600; public static bool IsEnable = false; public AddonTypes Type => AddonTypes.Harmful; diff --git a/Roles/AddOns/Common/Fragile.cs b/Roles/AddOns/Common/Fragile.cs index a43cd18ea..b667681db 100644 --- a/Roles/AddOns/Common/Fragile.cs +++ b/Roles/AddOns/Common/Fragile.cs @@ -4,7 +4,6 @@ namespace TOHE.Roles.AddOns.Common; public class Fragile : IAddon { - public CustomRoles Role => CustomRoles.Fragile; private const int Id = 20600; public AddonTypes Type => AddonTypes.Harmful; diff --git a/Roles/AddOns/Common/FragileSoul.cs b/Roles/AddOns/Common/FragileSoul.cs new file mode 100644 index 000000000..5f282702b --- /dev/null +++ b/Roles/AddOns/Common/FragileSoul.cs @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Roles/AddOns/Common/Glow.cs b/Roles/AddOns/Common/Glow.cs index 79befa47c..980a9bf1a 100644 --- a/Roles/AddOns/Common/Glow.cs +++ b/Roles/AddOns/Common/Glow.cs @@ -5,7 +5,6 @@ namespace TOHE.Roles.AddOns.Common; public class Glow : IAddon { - public CustomRoles Role => CustomRoles.Glow; private const int Id = 22000; public static bool IsEnable = false; public AddonTypes Type => AddonTypes.Experimental; @@ -57,8 +56,7 @@ public static void ApplyGameOptions(IGameOptions opt, PlayerControl player) if (!Utils.IsActive(SystemTypes.Electrical)) return; if (!player.Is(CustomRoles.Glow)) - { - HashSet affectedPlaters = []; + { HashSet affectedPlaters = []; foreach (var allSets in InRadius.Values) affectedPlaters.UnionWith(allSets); @@ -78,24 +76,24 @@ public static void ApplyGameOptions(IGameOptions opt, PlayerControl player) public void OnFixedUpdateLowLoad(PlayerControl player) { if (!IsEnable || player == null || !player.Is(CustomRoles.Glow)) return; - if (!Utils.IsActive(SystemTypes.Electrical)) - { + if (!Utils.IsActive(SystemTypes.Electrical)) + { InRadius[player.PlayerId].Clear(); MarkedOnce[player.PlayerId] = false; return; } var prevList = InRadius[player.PlayerId]; InRadius[player.PlayerId] = Main.AllAlivePlayerControls - .Where(target => target != null - && !target.Is(CustomRoles.Glow) + .Where(target => target != null + && !target.Is(CustomRoles.Glow) && Utils.GetDistance(player.GetCustomPosition(), target.GetCustomPosition()) <= GlowRadius.GetFloat()) .Select(target => target.PlayerId) .ToHashSet(); - if (!MarkedOnce[player.PlayerId] || (!prevList.SetEquals(InRadius[player.PlayerId]))) + if (!MarkedOnce[player.PlayerId] || (!prevList.SetEquals(InRadius[player.PlayerId]))) { MarkedOnce[player.PlayerId] = true; - Utils.MarkEveryoneDirtySettings(); + Utils.MarkEveryoneDirtySettings(); } } } diff --git a/Roles/AddOns/Common/Gravestone.cs b/Roles/AddOns/Common/Gravestone.cs index 2d4871a6c..bfba077dd 100644 --- a/Roles/AddOns/Common/Gravestone.cs +++ b/Roles/AddOns/Common/Gravestone.cs @@ -4,7 +4,6 @@ namespace TOHE.Roles.AddOns.Common; public class Gravestone : IAddon { - public CustomRoles Role => CustomRoles.Gravestone; private const int Id = 22100; public AddonTypes Type => AddonTypes.Mixed; diff --git a/Roles/AddOns/Common/Guesser.cs b/Roles/AddOns/Common/Guesser.cs index 0ba1afd99..1085fba42 100644 --- a/Roles/AddOns/Common/Guesser.cs +++ b/Roles/AddOns/Common/Guesser.cs @@ -1,11 +1,10 @@ -using UnityEngine; -using static TOHE.Options; +using static TOHE.Options; +using UnityEngine; namespace TOHE.Roles.AddOns.Common; public class Guesser : IAddon { - public CustomRoles Role => CustomRoles.Guesser; private const int Id = 22200; public AddonTypes Type => AddonTypes.Guesser; @@ -22,7 +21,7 @@ public void SetupCustomOption() ImpCanBeGuesser = BooleanOptionItem.Create(Id + 10, "ImpCanBeGuesser", true, TabGroup.Addons, false).SetParent(CustomRoleSpawnChances[CustomRoles.Guesser]); CrewCanBeGuesser = BooleanOptionItem.Create(Id + 11, "CrewCanBeGuesser", true, TabGroup.Addons, false).SetParent(CustomRoleSpawnChances[CustomRoles.Guesser]); NeutralCanBeGuesser = BooleanOptionItem.Create(Id + 12, "NeutralCanBeGuesser", true, TabGroup.Addons, false).SetParent(CustomRoleSpawnChances[CustomRoles.Guesser]); - GCanGuessAdt = BooleanOptionItem.Create(Id + 13, "GCanGuessAdt", false, TabGroup.Addons, false).SetParent(CustomRoleSpawnChances[CustomRoles.Guesser]); + GCanGuessAdt = BooleanOptionItem.Create(Id+ 13, "GCanGuessAdt", false, TabGroup.Addons, false).SetParent(CustomRoleSpawnChances[CustomRoles.Guesser]); GCanGuessTaskDoneSnitch = BooleanOptionItem.Create(Id + 14, "GCanGuessTaskDoneSnitch", true, TabGroup.Addons, false).SetParent(CustomRoleSpawnChances[CustomRoles.Guesser]); GTryHideMsg = BooleanOptionItem.Create(Id + 15, "GuesserTryHideMsg", true, TabGroup.Addons, false).SetParent(CustomRoleSpawnChances[CustomRoles.Guesser]) .SetColor(Color.green); diff --git a/Roles/AddOns/Common/Influenced.cs b/Roles/AddOns/Common/Influenced.cs index be00273a4..6b0008d57 100644 --- a/Roles/AddOns/Common/Influenced.cs +++ b/Roles/AddOns/Common/Influenced.cs @@ -2,7 +2,6 @@ public class Influenced : IAddon { - public CustomRoles Role => CustomRoles.Influenced; private const int Id = 21200; public AddonTypes Type => AddonTypes.Harmful; @@ -17,15 +16,15 @@ public void Add(byte playerId, bool gameIsLoading = true) public void Remove(byte playerId) { } public static void ChangeVotingData(Dictionary VotingData) - { + { //The incoming votedata does not count influenced votes - HashSet influencedPlayerIds = []; + HashSet playerIdList = []; Main.AllAlivePlayerControls.Where(x => x.Is(CustomRoles.Influenced)) - .Do(x => influencedPlayerIds.Add(x.PlayerId)); - - if (influencedPlayerIds.Count == 0) return; - if (influencedPlayerIds.Count >= Main.AllAlivePlayerControls.Length) return; + .Do(x => playerIdList.Add(x.PlayerId)); + + if (playerIdList.Count == 0) return; + if (playerIdList.Count >= Main.AllAlivePlayerControls.Length) return; int max = 0; bool tie = false; @@ -46,7 +45,7 @@ public static void ChangeVotingData(Dictionary VotingData) } if (tie) return; - foreach (var playerId in influencedPlayerIds) + foreach (var playerId in playerIdList) { PlayerVoteArea pva = CheckForEndVotingPatch.GetPlayerVoteArea(playerId); if (pva != null && pva.VotedFor != exileId) diff --git a/Roles/AddOns/Common/Loyal.cs b/Roles/AddOns/Common/Loyal.cs index d700e4e3a..c01c8460c 100644 --- a/Roles/AddOns/Common/Loyal.cs +++ b/Roles/AddOns/Common/Loyal.cs @@ -4,7 +4,6 @@ namespace TOHE.Roles.AddOns.Common; public class Loyal : IAddon { - public CustomRoles Role => CustomRoles.Loyal; private const int Id = 19400; public AddonTypes Type => AddonTypes.Helpful; @@ -24,4 +23,4 @@ public void Add(byte playerId, bool gameIsLoading = true) { } public void Remove(byte playerId) { } -} +} \ No newline at end of file diff --git a/Roles/AddOns/Common/Lucky.cs b/Roles/AddOns/Common/Lucky.cs index 5f3f509d7..5960b3386 100644 --- a/Roles/AddOns/Common/Lucky.cs +++ b/Roles/AddOns/Common/Lucky.cs @@ -4,7 +4,6 @@ namespace TOHE.Roles.AddOns.Common; public class Lucky : IAddon { - public CustomRoles Role => CustomRoles.Lucky; private const int Id = 19500; public AddonTypes Type => AddonTypes.Helpful; @@ -23,7 +22,7 @@ public void Init() { LuckyAvoid.Clear(); } - public void Add(byte playerId, bool gameIsLoading = true) + public void Add(byte playerId, bool gameIsLoading = true) { LuckyAvoid[playerId] = false; } @@ -53,4 +52,4 @@ public static bool OnCheckMurder(PlayerControl killer, PlayerControl target) return true; } -} +} \ No newline at end of file diff --git a/Roles/AddOns/Common/Mundane.cs b/Roles/AddOns/Common/Mundane.cs index 23207e2f2..6e5b30824 100644 --- a/Roles/AddOns/Common/Mundane.cs +++ b/Roles/AddOns/Common/Mundane.cs @@ -4,7 +4,6 @@ namespace TOHE.Roles.AddOns.Common; public class Mundane : IAddon { - public CustomRoles Role => CustomRoles.Mundane; private const int Id = 26700; public AddonTypes Type => AddonTypes.Harmful; @@ -30,4 +29,4 @@ public static bool OnGuess(PlayerControl pc) return pc.GetPlayerTaskState().IsTaskFinished; } -} +} \ No newline at end of file diff --git a/Roles/AddOns/Common/Necroview.cs b/Roles/AddOns/Common/Necroview.cs index 5eb4af49b..3a4b3b602 100644 --- a/Roles/AddOns/Common/Necroview.cs +++ b/Roles/AddOns/Common/Necroview.cs @@ -4,7 +4,6 @@ namespace TOHE.Roles.AddOns.Common; public class Necroview : IAddon { - public CustomRoles Role => CustomRoles.Necroview; private const int Id = 19600; public AddonTypes Type => AddonTypes.Helpful; diff --git a/Roles/AddOns/Common/Oblivious.cs b/Roles/AddOns/Common/Oblivious.cs index e666bbf77..6b3296c32 100644 --- a/Roles/AddOns/Common/Oblivious.cs +++ b/Roles/AddOns/Common/Oblivious.cs @@ -4,7 +4,6 @@ namespace TOHE.Roles.AddOns.Common; public class Oblivious : IAddon { - public CustomRoles Role => CustomRoles.Oblivious; private const int Id = 20700; public AddonTypes Type => AddonTypes.Harmful; @@ -22,4 +21,4 @@ public void Add(byte playerId, bool gameIsLoading = true) public void Remove(byte playerId) { } -} +} \ No newline at end of file diff --git a/Roles/AddOns/Common/Oiiai.cs b/Roles/AddOns/Common/Oiiai.cs index b4d099d9d..1b73db716 100644 --- a/Roles/AddOns/Common/Oiiai.cs +++ b/Roles/AddOns/Common/Oiiai.cs @@ -8,7 +8,6 @@ namespace TOHE.Roles.AddOns.Common; public class Oiiai : IAddon { - public CustomRoles Role => CustomRoles.Oiiai; private const int Id = 25700; private readonly static List playerIdList = []; public static bool IsEnable = false; @@ -18,7 +17,6 @@ public class Oiiai : IAddon private static OptionItem CanPassOn; private static OptionItem ChangeNeutralRole; - [Obfuscation(Exclude = true)] private enum ChangeRolesSelectList { Role_NoChange, @@ -45,15 +43,12 @@ public void Init() } public void Add(byte playerId, bool gameIsLoading = true) { - if (!playerIdList.Contains(playerId)) - playerIdList.Add(playerId); - + playerIdList.Add(playerId); IsEnable = true; } public static void PassOnKiller(byte playerId) { - if (!playerIdList.Contains(playerId)) - playerIdList.Add(playerId); + playerIdList.Add(playerId); IsEnable = true; } public void Remove(byte playerId) @@ -98,12 +93,8 @@ public static void OnMurderPlayer(PlayerControl killer, PlayerControl target) } else if (!killer.GetCustomRole().IsNeutral()) { - var readyrole = Eraser.GetErasedRole(killer.GetCustomRole().GetRoleTypes(), killer.GetCustomRole()); //Use eraser here LOL - killer.GetRoleClass()?.OnRemove(killer.PlayerId); - killer.RpcChangeRoleBasis(readyrole); - killer.RpcSetCustomRole(readyrole); - killer.GetRoleClass()?.OnAdd(killer.PlayerId); + killer.RpcSetCustomRole(Eraser.GetErasedRole(killer.GetCustomRole().GetRoleTypes(), killer.GetCustomRole())); Logger.Info($"Oiiai {killer.GetNameWithRole().RemoveHtmlTags()} with eraser assign.", "Oiiai"); } else @@ -115,7 +106,6 @@ public static void OnMurderPlayer(PlayerControl killer, PlayerControl target) if (changeValue != 0) { killer.GetRoleClass().OnRemove(killer.PlayerId); - killer.RpcChangeRoleBasis(NRoleChangeRoles[changeValue - 1]); killer.RpcSetCustomRole(NRoleChangeRoles[changeValue - 1]); killer.GetRoleClass().OnAdd(killer.PlayerId); @@ -126,10 +116,7 @@ public static void OnMurderPlayer(PlayerControl killer, PlayerControl target) } else { - killer.GetRoleClass().OnRemove(killer.PlayerId); - killer.RpcChangeRoleBasis(CustomRoles.Opportunist); killer.RpcSetCustomRole(CustomRoles.Opportunist); - killer.GetRoleClass().OnAdd(killer.PlayerId); Logger.Info($"Oiiai {killer.GetNameWithRole().RemoveHtmlTags()} with Neutrals without kill button assign.", "Oiiai"); } } diff --git a/Roles/AddOns/Common/Onbound.cs b/Roles/AddOns/Common/Onbound.cs index 726fd072e..b48ece0e4 100644 --- a/Roles/AddOns/Common/Onbound.cs +++ b/Roles/AddOns/Common/Onbound.cs @@ -4,7 +4,6 @@ namespace TOHE.Roles.AddOns.Common; public class Onbound : IAddon { - public CustomRoles Role => CustomRoles.Onbound; private const int Id = 25800; public AddonTypes Type => AddonTypes.Guesser; diff --git a/Roles/AddOns/Common/Overlocked.cs b/Roles/AddOns/Common/Overlocked.cs index 13d2f7655..12bca6823 100644 --- a/Roles/AddOns/Common/Overlocked.cs +++ b/Roles/AddOns/Common/Overlocked.cs @@ -4,7 +4,6 @@ namespace TOHE.Roles.AddOns.Common; public class Overclocked : IAddon { - public CustomRoles Role => CustomRoles.Overclocked; private const int Id = 19800; public AddonTypes Type => AddonTypes.Helpful; diff --git a/Roles/AddOns/Common/Paranoia.cs b/Roles/AddOns/Common/Paranoia.cs index 3710aece9..7a5fb07a3 100644 --- a/Roles/AddOns/Common/Paranoia.cs +++ b/Roles/AddOns/Common/Paranoia.cs @@ -4,7 +4,6 @@ namespace TOHE.Roles.AddOns.Common; public class Paranoia : IAddon { - public CustomRoles Role => CustomRoles.Paranoia; private const int Id = 22400; public static OptionItem CanBeImp; diff --git a/Roles/AddOns/Common/Prohibited.cs b/Roles/AddOns/Common/Prohibited.cs index b68cc8986..963461d5a 100644 --- a/Roles/AddOns/Common/Prohibited.cs +++ b/Roles/AddOns/Common/Prohibited.cs @@ -5,7 +5,6 @@ namespace TOHE.Roles.AddOns.Common; public class Prohibited : IAddon { - public CustomRoles Role => CustomRoles.Prohibited; private const int Id = 29900; public AddonTypes Type => AddonTypes.Harmful; diff --git a/Roles/AddOns/Common/Radar.cs b/Roles/AddOns/Common/Radar.cs index b05d0c98f..f64de2dc6 100644 --- a/Roles/AddOns/Common/Radar.cs +++ b/Roles/AddOns/Common/Radar.cs @@ -4,7 +4,6 @@ namespace TOHE.Roles.AddOns.Common; public class Radar : IAddon { - public CustomRoles Role => CustomRoles.Radar; private const int Id = 28200; public AddonTypes Type => AddonTypes.Helpful; @@ -15,7 +14,7 @@ public void SetupCustomOption() SetupAdtRoleOptions(Id, CustomRoles.Radar, canSetNum: true, tab: TabGroup.Addons, teamSpawnOptions: true); } public void Init() - { + { ClosestPlayer.Clear(); } public void Add(byte playerId, bool gameIsLoading = true) diff --git a/Roles/AddOns/Common/Rainbow.cs b/Roles/AddOns/Common/Rainbow.cs index e936c5aa5..50cf04d6a 100644 --- a/Roles/AddOns/Common/Rainbow.cs +++ b/Roles/AddOns/Common/Rainbow.cs @@ -5,7 +5,6 @@ namespace TOHE.Roles.AddOns.Common; // https://github.com/Yumenopai/TownOfHost_Y/blob/main/Roles/Crewmate/Y/Rainbow.cs public class Rainbow : IAddon { - public CustomRoles Role => CustomRoles.Rainbow; private const int Id = 27700; public AddonTypes Type => AddonTypes.Misc; diff --git a/Roles/AddOns/Common/Reach.cs b/Roles/AddOns/Common/Reach.cs index a0632f2a7..02c6e9769 100644 --- a/Roles/AddOns/Common/Reach.cs +++ b/Roles/AddOns/Common/Reach.cs @@ -5,11 +5,10 @@ namespace TOHE.Roles.AddOns.Common; public class Reach : IAddon { - public CustomRoles Role => CustomRoles.Reach; private const int Id = 23700; public AddonTypes Type => AddonTypes.Helpful; public static CustomRoles IsReach => CustomRoles.Reach; // Used to find "references" of this addon. - + public void SetupCustomOption() { SetupAdtRoleOptions(Id, CustomRoles.Reach, canSetNum: true); @@ -21,4 +20,4 @@ public void Add(byte playerId, bool gameIsLoading = true) public void Remove(byte playerId) { } public static void ApplyGameOptions(IGameOptions opt) => opt.SetInt(Int32OptionNames.KillDistance, 2); -} +} \ No newline at end of file diff --git a/Roles/AddOns/Common/Rebirth.cs b/Roles/AddOns/Common/Rebirth.cs index 5dbe53dc7..30fd89613 100644 --- a/Roles/AddOns/Common/Rebirth.cs +++ b/Roles/AddOns/Common/Rebirth.cs @@ -1,13 +1,12 @@ using TOHE.Modules; using static TOHE.Options; -using static TOHE.Translator; using static TOHE.Utils; +using static TOHE.Translator; namespace TOHE.Roles.AddOns.Common; public class Rebirth : IAddon { - public CustomRoles Role => CustomRoles.Rebirth; private const int Id = 29500; public AddonTypes Type => AddonTypes.Helpful; public static OptionItem RebirthUses; @@ -32,7 +31,7 @@ public void Add(byte playerId, bool gameIsLoading = true) Rebirths[playerId] = RebirthUses.GetInt(); VotedCount[playerId] = []; } - public void Remove(byte Playerid) + public void Remove(byte Playerid) { Rebirths.Remove(Playerid); } @@ -45,7 +44,7 @@ public static void CountVotes(byte playerid, byte voter) } public static void OnReportDeadBody() { - foreach (var KvP in VotedCount) + foreach(var KvP in VotedCount) { KvP.Value.Clear(); } @@ -54,16 +53,16 @@ public static bool SwapSkins(PlayerControl pc, out NetworkedPlayerInfo NewExiled { NewExiledPlayer = default; if (!pc.Is(CustomRoles.Rebirth)) return false; - List list = [.. Main.AllAlivePlayerControls]; + List list = [..Main.AllAlivePlayerControls]; if (OnlyVoted.GetBool()) { - list = [.. VotedCount[pc.PlayerId].Select(x => GetPlayerById(x))]; + list = [..VotedCount[pc.PlayerId].Select(x => GetPlayerById(x))]; } var ViablePlayer = list.Where(x => x != null && x.PlayerId != pc.PlayerId).Shuffle() - .FirstOrDefault(x => !x.IsHost() && AntiBlackout.ExilePlayerId != x.PlayerId && !x.IsAnySubRole(x => x.IsConverted()) && !x.Is(CustomRoles.Admired) && !x.Is(CustomRoles.Knighted) && + .FirstOrDefault(x => !x.IsHost() && AntiBlackout.ExilePlayerId != x.PlayerId && !x.IsAnySubRole(x => x.IsConverted()) && !x.Is(CustomRoles.Admired) && !x.Is(CustomRoles.Knighted) && /*All converters */ !x.Is(CustomRoles.Cultist) && !x.Is(CustomRoles.Infectious) && !x.Is(CustomRoles.Virus) && !x.Is(CustomRoles.Jackal) && !x.Is(CustomRoles.Admirer) && - !x.Is(CustomRoles.Lovers) && !x.Is(CustomRoles.Romantic) && !x.Is(CustomRoles.Doppelganger) && !x.GetCustomRole().IsImpostor() && !x.Is(CustomRoles.Solsticer) && !x.Is(CustomRoles.NiceMini)); + !x.Is(CustomRoles.Lovers) && !x.Is(CustomRoles.Romantic) && !x.Is(CustomRoles.Doppelganger) && !x.GetCustomRole().IsImpostor()); if (ViablePlayer == null) { @@ -86,4 +85,4 @@ public static bool SwapSkins(PlayerControl pc, out NetworkedPlayerInfo NewExiled return true; } -} +} \ No newline at end of file diff --git a/Roles/AddOns/Common/Rebound.cs b/Roles/AddOns/Common/Rebound.cs index 0514c7602..6e0b2c4d4 100644 --- a/Roles/AddOns/Common/Rebound.cs +++ b/Roles/AddOns/Common/Rebound.cs @@ -5,7 +5,6 @@ namespace TOHE.Roles.AddOns.Common; public class Rebound : IAddon { - public CustomRoles Role => CustomRoles.Rebound; private const int Id = 22300; public AddonTypes Type => AddonTypes.Guesser; @@ -19,4 +18,4 @@ public void Add(byte playerId, bool gameIsLoading = true) { } public void Remove(byte playerId) { } -} +} \ No newline at end of file diff --git a/Roles/AddOns/Common/Seer.cs b/Roles/AddOns/Common/Seer.cs index 337c03541..e177d16bb 100644 --- a/Roles/AddOns/Common/Seer.cs +++ b/Roles/AddOns/Common/Seer.cs @@ -3,7 +3,6 @@ namespace TOHE.Roles.AddOns.Common; public class Seer : IAddon { - public CustomRoles Role => CustomRoles.Seer; private const int Id = 20000; public AddonTypes Type => AddonTypes.Helpful; diff --git a/Roles/AddOns/Common/Silent.cs b/Roles/AddOns/Common/Silent.cs index 2d6eae16d..924473f11 100644 --- a/Roles/AddOns/Common/Silent.cs +++ b/Roles/AddOns/Common/Silent.cs @@ -3,7 +3,6 @@ namespace TOHE.Roles.AddOns.Common; public class Silent : IAddon { - public CustomRoles Role => CustomRoles.Silent; private const int Id = 26600; public AddonTypes Type => AddonTypes.Helpful; public void SetupCustomOption() diff --git a/Roles/AddOns/Common/Sleuth.cs b/Roles/AddOns/Common/Sleuth.cs index 5cb304d1f..793643cb4 100644 --- a/Roles/AddOns/Common/Sleuth.cs +++ b/Roles/AddOns/Common/Sleuth.cs @@ -2,14 +2,13 @@ public class Sleuth : IAddon { - public CustomRoles Role => CustomRoles.Sleuth; private const int Id = 20100; public AddonTypes Type => AddonTypes.Helpful; - + public static OptionItem SleuthCanKnowKillerRole; - + public static readonly Dictionary SleuthNotify = []; - + public void SetupCustomOption() { Options.SetupAdtRoleOptions(Id, CustomRoles.Sleuth, canSetNum: true, teamSpawnOptions: true); diff --git a/Roles/AddOns/Common/Sloth.cs b/Roles/AddOns/Common/Sloth.cs index 3d870b410..fbf1c2859 100644 --- a/Roles/AddOns/Common/Sloth.cs +++ b/Roles/AddOns/Common/Sloth.cs @@ -5,7 +5,6 @@ namespace TOHE.Roles.AddOns.Common; public class Sloth : IAddon { - public CustomRoles Role => CustomRoles.Sloth; private const int Id = 29700; public AddonTypes Type => AddonTypes.Harmful; @@ -14,7 +13,7 @@ public class Sloth : IAddon public void SetupCustomOption() { SetupAdtRoleOptions(Id, CustomRoles.Sloth, canSetNum: true, tab: TabGroup.Addons, teamSpawnOptions: true); - OptionSpeed = FloatOptionItem.Create(Id + 10, "SlothSpeed", new(0.25f, 1f, 0.25f), 0.5f, TabGroup.Addons, false) + OptionSpeed = FloatOptionItem.Create(Id + 10, "SlothSpeed", new(0.25f, 0.75f, 0.25f), 0.75f, TabGroup.Addons, false) .SetParent(CustomRoleSpawnChances[CustomRoles.Sloth]) .SetValueFormat(OptionFormat.Multiplier); } @@ -33,4 +32,4 @@ public static void SetSpeed(byte playerId) { Main.AllPlayerSpeed[playerId] = OptionSpeed.GetFloat(); } -} +} \ No newline at end of file diff --git a/Roles/AddOns/Common/Spurt.cs b/Roles/AddOns/Common/Spurt.cs index f99fd2c1e..4715aad77 100644 --- a/Roles/AddOns/Common/Spurt.cs +++ b/Roles/AddOns/Common/Spurt.cs @@ -1,11 +1,10 @@ -using UnityEngine; -using static TOHE.Options; +using static TOHE.Options; +using UnityEngine; namespace TOHE.Roles.AddOns.Common; internal class Spurt : IAddon { - public CustomRoles Role => CustomRoles.Spurt; private static OptionItem MinSpeed; private static OptionItem Modulator; private static OptionItem MaxSpeed; @@ -27,7 +26,7 @@ public void SetupCustomOption() MaxSpeed = FloatOptionItem.Create(id + 7, "SpurtMaxSpeed", new(1.5f, 3f, 0.25f), 3f, TabGroup.Addons, false) .SetParent(CustomRoleSpawnChances[CustomRoles.Spurt]) .SetValueFormat(OptionFormat.Multiplier); - Modulator = FloatOptionItem.Create(id + 8, "SpurtModule", new(0.25f, 3f, 0.25f), 1.25f, TabGroup.Addons, false) + Modulator =FloatOptionItem.Create(id + 8, "SpurtModule", new(0.25f, 3f, 0.25f), 1.25f, TabGroup.Addons, false) .SetParent(CustomRoleSpawnChances[CustomRoles.Spurt]) .SetValueFormat(OptionFormat.Multiplier); DisplaysCharge = BooleanOptionItem.Create(id + 9, "EnableSpurtCharge", false, TabGroup.Addons, false) @@ -108,19 +107,16 @@ public void OnFixedUpdate(PlayerControl player) { Utils.NotifyRoles(SpecifySeer: player, SpecifyTarget: player); LastUpdate[player.PlayerId] = now; - player.SyncSpeed(); } } if (!moving) { Main.AllPlayerSpeed[player.PlayerId] += Mathf.Clamp(ChargeBy, 0f, MaxSpeed.GetFloat() - Main.AllPlayerSpeed[player.PlayerId]); - player.SyncSpeed(); return; } Main.AllPlayerSpeed[player.PlayerId] -= Mathf.Clamp(Decreaseby, 0f, Main.AllPlayerSpeed[player.PlayerId] - MinSpeed.GetFloat()); - player.SyncSpeed(); player.MarkDirtySettings(); } } diff --git a/Roles/AddOns/Common/Statue.cs b/Roles/AddOns/Common/Statue.cs index d0792fce6..2fefb3799 100644 --- a/Roles/AddOns/Common/Statue.cs +++ b/Roles/AddOns/Common/Statue.cs @@ -4,7 +4,6 @@ namespace TOHE.Roles.AddOns.Common; public class Statue : IAddon { - public CustomRoles Role => CustomRoles.Statue; private const int Id = 13800; public AddonTypes Type => AddonTypes.Harmful; public static bool IsEnable = false; @@ -61,13 +60,13 @@ public static void AfterMeetingTasks() } Active = false; CountNearplr.Clear(); - _ = new LateTask(() => + _ = new LateTask(() => { Active = true; }, 6f); } - public void OnFixedUpdate(PlayerControl victim) + public void OnFixedUpdate(PlayerControl victim) { if (!victim.Is(CustomRoles.Statue)) return; if (!victim.IsAlive() && victim != null) @@ -106,8 +105,8 @@ public void OnFixedUpdate(PlayerControl victim) if (CountNearplr.Count >= PeopleAmount.GetInt()) { - if (Main.AllPlayerSpeed[victim.PlayerId] != SlowDown.GetFloat()) - { + if (Main.AllPlayerSpeed[victim.PlayerId] != SlowDown.GetFloat()) + { Main.AllPlayerSpeed[victim.PlayerId] = SlowDown.GetFloat(); victim.MarkDirtySettings(); } diff --git a/Roles/AddOns/Common/Stubborn.cs b/Roles/AddOns/Common/Stubborn.cs index 9f653626d..5970d18ad 100644 --- a/Roles/AddOns/Common/Stubborn.cs +++ b/Roles/AddOns/Common/Stubborn.cs @@ -4,7 +4,6 @@ namespace TOHE.Roles.AddOns.Common; public class Stubborn : IAddon { - public CustomRoles Role => CustomRoles.Stubborn; private const int Id = 22500; public AddonTypes Type => AddonTypes.Mixed; diff --git a/Roles/AddOns/Common/Susceptible.cs b/Roles/AddOns/Common/Susceptible.cs index 5bc0f17ca..4151d635b 100644 --- a/Roles/AddOns/Common/Susceptible.cs +++ b/Roles/AddOns/Common/Susceptible.cs @@ -4,7 +4,6 @@ namespace TOHE.Roles.AddOns.Common; public class Susceptible : IAddon { - public CustomRoles Role => CustomRoles.Susceptible; private const int Id = 27100; public AddonTypes Type => AddonTypes.Mixed; private static OptionItem EnabledDeathReasons; diff --git a/Roles/AddOns/Common/Tiebreaker.cs b/Roles/AddOns/Common/Tiebreaker.cs index adf299e13..337e1de0c 100644 --- a/Roles/AddOns/Common/Tiebreaker.cs +++ b/Roles/AddOns/Common/Tiebreaker.cs @@ -2,7 +2,6 @@ public class Tiebreaker : IAddon { - public CustomRoles Role => CustomRoles.Tiebreaker; private const int Id = 20200; public AddonTypes Type => AddonTypes.Helpful; @@ -27,4 +26,4 @@ public static void CheckVote(PlayerControl target, PlayerVoteArea ps) if (CheckForEndVotingPatch.CheckRole(ps.TargetPlayerId, CustomRoles.Tiebreaker) && !VoteFor.Contains(target.PlayerId)) VoteFor.Add(target.PlayerId); } -} +} \ No newline at end of file diff --git a/Roles/AddOns/Common/Tired.cs b/Roles/AddOns/Common/Tired.cs index dcaec14ca..ea42337f7 100644 --- a/Roles/AddOns/Common/Tired.cs +++ b/Roles/AddOns/Common/Tired.cs @@ -6,13 +6,12 @@ namespace TOHE.Roles.AddOns.Common; public class Tired : IAddon { - public CustomRoles Role => CustomRoles.Tired; private const int Id = 27300; public AddonTypes Type => AddonTypes.Harmful; private static readonly Dictionary playerIdList = []; // Target Action player for Vision - private static OptionItem SetVision; - private static OptionItem SetSpeed; + public static OptionItem SetSpeed; + public static OptionItem SetVision; private static OptionItem TiredDuration; public void SetupCustomOption() @@ -61,7 +60,7 @@ public static void ApplyGameOptions(IGameOptions opt, PlayerControl player) opt.SetFloat(FloatOptionNames.ImpostorLightMod, Main.DefaultImpostorVision); } } - + public static void AfterActionTasks(PlayerControl player) { // Speed diff --git a/Roles/AddOns/Common/Unlucky.cs b/Roles/AddOns/Common/Unlucky.cs index a1d6d22e4..a0a30815f 100644 --- a/Roles/AddOns/Common/Unlucky.cs +++ b/Roles/AddOns/Common/Unlucky.cs @@ -4,7 +4,6 @@ namespace TOHE.Roles.AddOns.Common; public class Unlucky : IAddon { - public CustomRoles Role => CustomRoles.Unlucky; private const int Id = 21000; public AddonTypes Type => AddonTypes.Harmful; @@ -14,7 +13,6 @@ public class Unlucky : IAddon private static OptionItem UnluckyReportSuicideChance; private static OptionItem UnluckyOpenDoorSuicideChance; - [Obfuscation(Exclude = true)] public enum StateSuicide { TryKill, diff --git a/Roles/AddOns/Common/Unreportable.cs b/Roles/AddOns/Common/Unreportable.cs index d6d6af376..eb23d25d7 100644 --- a/Roles/AddOns/Common/Unreportable.cs +++ b/Roles/AddOns/Common/Unreportable.cs @@ -4,7 +4,6 @@ namespace TOHE.Roles.AddOns.Common; public class Unreportable : IAddon { - public CustomRoles Role => CustomRoles.Unreportable; private const int Id = 20500; public AddonTypes Type => AddonTypes.Harmful; @@ -18,4 +17,4 @@ public void Add(byte playerId, bool gameIsLoading = true) { } public void Remove(byte playerId) { } -} +} \ No newline at end of file diff --git a/Roles/AddOns/Common/Voidballot.cs b/Roles/AddOns/Common/Voidballot.cs index 11867a527..44a76708b 100644 --- a/Roles/AddOns/Common/Voidballot.cs +++ b/Roles/AddOns/Common/Voidballot.cs @@ -4,7 +4,6 @@ namespace TOHE.Roles.AddOns.Common; public class VoidBallot : IAddon { - public CustomRoles Role => CustomRoles.VoidBallot; private const int Id = 21100; public AddonTypes Type => AddonTypes.Harmful; @@ -18,4 +17,4 @@ public void Add(byte playerId, bool gameIsLoading = true) { } public void Remove(byte playerId) { } -} +} \ No newline at end of file diff --git a/Roles/AddOns/Common/Watcher.cs b/Roles/AddOns/Common/Watcher.cs index ad1e3db0e..9a7dc556b 100644 --- a/Roles/AddOns/Common/Watcher.cs +++ b/Roles/AddOns/Common/Watcher.cs @@ -5,7 +5,6 @@ namespace TOHE.Roles.AddOns.Common; public class Watcher : IAddon { - public CustomRoles Role => CustomRoles.Watcher; private const int Id = 20400; public AddonTypes Type => AddonTypes.Helpful; diff --git a/Roles/AddOns/Common/Youtuber.cs b/Roles/AddOns/Common/Youtuber.cs index 1fdb132e9..96832f6fa 100644 --- a/Roles/AddOns/Common/Youtuber.cs +++ b/Roles/AddOns/Common/Youtuber.cs @@ -5,7 +5,6 @@ namespace TOHE.Roles.AddOns.Common; public class Youtuber : IAddon { - public CustomRoles Role => CustomRoles.Youtuber; private const int Id = 25500; public AddonTypes Type => AddonTypes.Misc; diff --git a/Roles/AddOns/Common/allergic.cs b/Roles/AddOns/Common/allergic.cs new file mode 100644 index 000000000..98bfb3075 --- /dev/null +++ b/Roles/AddOns/Common/allergic.cs @@ -0,0 +1,143 @@ +using Hazel; +using TOHE.Roles.Core; +using UnityEngine; +using static TOHE.Options; +namespace TOHE.Roles.AddOns.Common +{ + public class Allergic : IAddon + { + private const int Id = 220000; + public AddonTypes Type => AddonTypes.Harmful; + + private static OptionItem AllergicDistance; + private static OptionItem AllergicTime; + + private static Dictionary allergicTargets = new(); + private Dictionary proximityTimers = new Dictionary(); + + public void SetupCustomOption() + { + SetupAdtRoleOptions(Id, CustomRoles.Allergic, canSetNum: true, teamSpawnOptions: true); + + AllergicDistance = FloatOptionItem.Create(Id + 10, "AllergicDistance", new(1.0f, 5.0f, 0.1f), 2.0f, TabGroup.Addons, false) + .SetParent(CustomRoleSpawnChances[CustomRoles.Allergic]) + .SetValueFormat(OptionFormat.Multiplier); + + AllergicTime = FloatOptionItem.Create(Id + 11, "AllergicTime", new(1.0f, 10.0f, 0.5f), 3.0f, TabGroup.Addons, false) + .SetParent(CustomRoleSpawnChances[CustomRoles.Allergic]) + .SetValueFormat(OptionFormat.Seconds); + } + + public void Init() => allergicTargets.Clear(); + + public void Add(byte playerId, bool gameIsLoading = true) + { + var allergicPlayer = PlayerControl.LocalPlayer; + if (AmongUsClient.Instance.AmHost && allergicPlayer.IsAlive()) + { + var eligibleTargets = new List(); + foreach (var p in PlayerControl.AllPlayerControls) + { + if (p.PlayerId != playerId && !p.Data.IsDead) + { + eligibleTargets.Add(p); + } + } + + + if (eligibleTargets.Count > 0) + { + var selectedTarget = eligibleTargets[UnityEngine.Random.Range(0, eligibleTargets.Count)]; + allergicTargets[allergicPlayer.PlayerId] = selectedTarget.PlayerId; + proximityTimers[allergicPlayer.PlayerId] = 0f; + + SendRPC(allergicPlayer.PlayerId, selectedTarget.PlayerId, true); + Logger.Info($"{allergicPlayer.GetNameWithRole()} is now allergic to {selectedTarget.GetNameWithRole()}", "Allergic"); + } + else + { + Logger.Info($"{allergicPlayer.GetNameWithRole()} has no valid targets to be allergic to.", "Allergic"); + } + } + } + + private void OnFixedUpdate(PlayerControl player, bool lowLoad, long nowTime) + { + if (!player.Is(CustomRoles.Allergic) || player.Data.IsDead) return; + + if (!allergicTargets.TryGetValue(player.PlayerId, out byte targetId)) + { + Logger.Info("No valid target for allergic player.", "Allergic"); + return; + } + + PlayerControl targetPlayer = null; + foreach (var p in PlayerControl.AllPlayerControls) + { + if (p.PlayerId == targetId) + { + targetPlayer = p; + break; + } + } + + + if (targetPlayer == null || targetPlayer.Data.IsDead) return; + + var distance = Vector3.Distance(player.transform.position, targetPlayer.transform.position); + + if (distance <= AllergicDistance.GetFloat()) + { + proximityTimers[player.PlayerId] += Time.deltaTime; + + if (proximityTimers[player.PlayerId] >= AllergicTime.GetFloat()) + { + KillAllergic(player); + proximityTimers[player.PlayerId] = 0f; + } + } + else + { + proximityTimers[player.PlayerId] = 0f; + } + } + + private void KillAllergic(PlayerControl player) + { + Logger.Info($"{player.GetNameWithRole()} has died due to allergic reaction proximity.", "Allergic"); + + player.SetDeathReason(PlayerState.DeathReason.Suicide); + player.RpcMurderPlayer(player); // Broadcasts the player's death to all clients + } + + public void Remove(byte playerId) + { + if (allergicTargets.ContainsKey(playerId)) + { + allergicTargets.Remove(playerId); + Logger.Info($"Removed Allergic target for player {playerId}", "Allergic"); + } + } + + private static void SendRPC(byte allergicPlayerId, byte targetId, bool setTarget) + { + MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately( + PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.SyncRoleSkill, SendOption.Reliable); + + writer.Write(setTarget); + writer.Write(allergicPlayerId); + writer.Write(targetId); + + AmongUsClient.Instance.FinishRpcImmediately(writer); + } + + public static string GetMarkOthers(PlayerControl seer, PlayerControl target, bool isForMeeting = false) + { + if (allergicTargets.TryGetValue(seer.PlayerId, out byte targetId) && target.PlayerId == targetId) + { + return Utils.ColorString(Utils.GetRoleColor(CustomRoles.Allergic), "⚠"); + } + return string.Empty; + } + } +} diff --git a/Roles/AddOns/Crewmate/Bloodthirst.cs b/Roles/AddOns/Crewmate/Bloodthirst.cs index e99c513a2..5ab9cbb59 100644 --- a/Roles/AddOns/Crewmate/Bloodthirst.cs +++ b/Roles/AddOns/Crewmate/Bloodthirst.cs @@ -5,7 +5,6 @@ namespace TOHE.Roles.AddOns.Crewmate; public class Bloodthirst : IAddon { - public CustomRoles Role => CustomRoles.Bloodthirst; private const int Id = 21700; public AddonTypes Type => AddonTypes.Mixed; diff --git a/Roles/AddOns/Crewmate/Ghoul.cs b/Roles/AddOns/Crewmate/Ghoul.cs index b93339092..01226169e 100644 --- a/Roles/AddOns/Crewmate/Ghoul.cs +++ b/Roles/AddOns/Crewmate/Ghoul.cs @@ -4,7 +4,6 @@ namespace TOHE.Roles.AddOns.Crewmate; public class Ghoul : IAddon { - public CustomRoles Role => CustomRoles.Ghoul; private const int Id = 21900; public AddonTypes Type => AddonTypes.Mixed; @@ -31,7 +30,7 @@ public void Remove(byte playerId) IsEnable = false; } - public static void ApplyGameOptions(PlayerControl player) + public static void ApplyGameOptions(PlayerControl player) { if (Main.AllPlayerControls.Any(x => x.Is(CustomRoles.Ghoul) && !x.IsAlive() && x.GetRealKiller()?.PlayerId == player.PlayerId)) { diff --git a/Roles/AddOns/Crewmate/Hurried.cs b/Roles/AddOns/Crewmate/Hurried.cs index ca8430e8b..e4c45f553 100644 --- a/Roles/AddOns/Crewmate/Hurried.cs +++ b/Roles/AddOns/Crewmate/Hurried.cs @@ -3,7 +3,6 @@ namespace TOHE.Roles.AddOns.Crewmate; public class Hurried : IAddon { - public CustomRoles Role => CustomRoles.Hurried; private const int Id = 21300; public AddonTypes Type => AddonTypes.Harmful; diff --git a/Roles/AddOns/Crewmate/Lazy.cs b/Roles/AddOns/Crewmate/Lazy.cs index 91fbf8292..9e342e693 100644 --- a/Roles/AddOns/Crewmate/Lazy.cs +++ b/Roles/AddOns/Crewmate/Lazy.cs @@ -4,13 +4,12 @@ namespace TOHE.Roles.AddOns.Crewmate; public class Lazy : IAddon { - public CustomRoles Role => CustomRoles.Lazy; private const int Id = 19300; public AddonTypes Type => AddonTypes.Helpful; private static OptionItem TasklessCrewCanBeLazy; private static OptionItem TaskBasedCrewCanBeLazy; - + public void SetupCustomOption() { SetupAdtRoleOptions(Id, CustomRoles.Lazy, canSetNum: true); @@ -31,12 +30,12 @@ public static bool CheckConflicts(PlayerControl player) || player.Is(CustomRoles.LazyGuy)) return false; - if (player.GetCustomRole().IsNeutral() - || player.GetCustomRole().IsImpostor() + if (player.GetCustomRole().IsNeutral() + || player.GetCustomRole().IsImpostor() || (player.GetCustomRole().IsTasklessCrewmate() && !TasklessCrewCanBeLazy.GetBool()) || (player.GetCustomRole().IsTaskBasedCrewmate() && !TaskBasedCrewCanBeLazy.GetBool())) return false; return true; } -} +} \ No newline at end of file diff --git a/Roles/AddOns/Crewmate/Nimble.cs b/Roles/AddOns/Crewmate/Nimble.cs index cac379b55..b22a4717c 100644 --- a/Roles/AddOns/Crewmate/Nimble.cs +++ b/Roles/AddOns/Crewmate/Nimble.cs @@ -4,7 +4,6 @@ namespace TOHE.Roles.AddOns.Crewmate; public class Nimble : IAddon { - public CustomRoles Role => CustomRoles.Nimble; private const int Id = 19700; public AddonTypes Type => AddonTypes.Helpful; @@ -18,4 +17,4 @@ public void Add(byte playerId, bool gameIsLoading = true) { } public void Remove(byte playerId) { } -} +} \ No newline at end of file diff --git a/Roles/AddOns/Crewmate/Rascal.cs b/Roles/AddOns/Crewmate/Rascal.cs index 560b35ae5..809552f93 100644 --- a/Roles/AddOns/Crewmate/Rascal.cs +++ b/Roles/AddOns/Crewmate/Rascal.cs @@ -4,12 +4,11 @@ namespace TOHE.Roles.AddOns.Crewmate; public class Rascal : IAddon { - public CustomRoles Role => CustomRoles.Rascal; private const int Id = 20800; public AddonTypes Type => AddonTypes.Harmful; private static OptionItem RascalAppearAsMadmate; - + public void SetupCustomOption() { SetupAdtRoleOptions(Id, CustomRoles.Rascal, canSetNum: true, tab: TabGroup.Addons); diff --git a/Roles/AddOns/Crewmate/Torch.cs b/Roles/AddOns/Crewmate/Torch.cs index 7e036a5b0..e70f9d201 100644 --- a/Roles/AddOns/Crewmate/Torch.cs +++ b/Roles/AddOns/Crewmate/Torch.cs @@ -5,7 +5,6 @@ namespace TOHE.Roles.AddOns.Crewmate; public class Torch : IAddon { - public CustomRoles Role => CustomRoles.Torch; private const int Id = 20300; public AddonTypes Type => AddonTypes.Helpful; private static OptionItem TorchVision; @@ -13,10 +12,10 @@ public class Torch : IAddon public void SetupCustomOption() { - SetupAdtRoleOptions(Id, CustomRoles.Torch, canSetNum: true); - TorchVision = FloatOptionItem.Create(Id + 10, "TorchVision", new(0.5f, 5f, 0.25f), 1.25f, TabGroup.Addons, false).SetParent(CustomRoleSpawnChances[CustomRoles.Torch]) + SetupAdtRoleOptions(Id , CustomRoles.Torch, canSetNum: true); + TorchVision = FloatOptionItem.Create(Id +10, "TorchVision", new(0.5f, 5f, 0.25f), 1.25f, TabGroup.Addons, false).SetParent(CustomRoleSpawnChances[CustomRoles.Torch]) .SetValueFormat(OptionFormat.Multiplier); - TorchAffectedByLights = BooleanOptionItem.Create(Id + 11, "TorchAffectedByLights", false, TabGroup.Addons, false).SetParent(CustomRoleSpawnChances[CustomRoles.Torch]); + TorchAffectedByLights = BooleanOptionItem.Create(Id +11, "TorchAffectedByLights", false, TabGroup.Addons, false).SetParent(CustomRoleSpawnChances[CustomRoles.Torch]); } public void Init() { } @@ -36,4 +35,4 @@ public static void ApplyGameOptions(IGameOptions opt) opt.SetFloat(FloatOptionNames.CrewLightMod, TorchVision.GetFloat() * 5); opt.SetFloat(FloatOptionNames.ImpostorLightMod, TorchVision.GetFloat() * 5); } -} +} \ No newline at end of file diff --git a/Roles/AddOns/Crewmate/Workhorse.cs b/Roles/AddOns/Crewmate/Workhorse.cs index fa9b81f6f..38fe0cf42 100644 --- a/Roles/AddOns/Crewmate/Workhorse.cs +++ b/Roles/AddOns/Crewmate/Workhorse.cs @@ -6,7 +6,6 @@ namespace TOHE.Roles.AddOns.Crewmate; public class Workhorse : IAddon { - public CustomRoles Role => CustomRoles.Workhorse; private const int Id = 23730; public AddonTypes Type => AddonTypes.Misc; private static readonly HashSet playerIdList = []; @@ -46,8 +45,7 @@ public void Add(byte playerId, bool gameIsLoading = true) { } public static void AddMidGame(byte playerId) { - if (!playerIdList.Contains(playerId)) - playerIdList.Add(playerId); + playerIdList.Add(playerId); IsEnable = true; } public void Remove(byte playerId) @@ -94,4 +92,4 @@ public static bool OnAddTask(PlayerControl pc) return false; } -} +} \ No newline at end of file diff --git a/Roles/AddOns/IAddon.cs b/Roles/AddOns/IAddon.cs index a4900a452..3e0a78053 100644 --- a/Roles/AddOns/IAddon.cs +++ b/Roles/AddOns/IAddon.cs @@ -2,7 +2,6 @@ namespace TOHE.Roles.AddOns { - [Obfuscation(Exclude = true)] public enum AddonTypes { Impostor, @@ -15,7 +14,6 @@ public enum AddonTypes } public interface IAddon { - public CustomRoles Role { get; } public AddonTypes Type { get; } public void SetupCustomOption(); diff --git a/Roles/AddOns/Impostor/Circumvent.cs b/Roles/AddOns/Impostor/Circumvent.cs index 650ef30de..07ab4d8e3 100644 --- a/Roles/AddOns/Impostor/Circumvent.cs +++ b/Roles/AddOns/Impostor/Circumvent.cs @@ -3,7 +3,6 @@ namespace TOHE.Roles.AddOns.Impostor; public class Circumvent : IAddon { - public CustomRoles Role => CustomRoles.Circumvent; private const int Id = 22600; public AddonTypes Type => AddonTypes.Impostor; @@ -18,4 +17,4 @@ public void Add(byte playerId, bool gameIsLoading = true) public void Remove(byte playerId) { } public static bool CantUseVent(PlayerControl player) => player.Is(CustomRoles.Circumvent); -} +} \ No newline at end of file diff --git a/Roles/AddOns/Impostor/Clumsy.cs b/Roles/AddOns/Impostor/Clumsy.cs index 80cc80384..b61f8265c 100644 --- a/Roles/AddOns/Impostor/Clumsy.cs +++ b/Roles/AddOns/Impostor/Clumsy.cs @@ -4,7 +4,6 @@ namespace TOHE.Roles.AddOns.Impostor; public class Clumsy : IAddon { - public CustomRoles Role => CustomRoles.Clumsy; private const int Id = 22700; public AddonTypes Type => AddonTypes.Impostor; @@ -55,4 +54,4 @@ public static bool OnCheckMurder(PlayerControl killer) return true; } -} +} \ No newline at end of file diff --git a/Roles/AddOns/Impostor/LastImpostor.cs b/Roles/AddOns/Impostor/LastImpostor.cs index 2386b6d1d..4e47b270a 100644 --- a/Roles/AddOns/Impostor/LastImpostor.cs +++ b/Roles/AddOns/Impostor/LastImpostor.cs @@ -3,7 +3,6 @@ namespace TOHE.Roles.AddOns.Impostor; public class LastImpostor : IAddon { - public CustomRoles Role => CustomRoles.LastImpostor; private const int Id = 22800; public AddonTypes Type => AddonTypes.Impostor; public static byte currentId = byte.MaxValue; @@ -31,8 +30,8 @@ public static void SetKillCooldown() Main.AllPlayerKillCooldown[currentId] -= removeCooldown; } private static bool CanBeLastImpostor(PlayerControl pc) - => pc.IsAlive() && !pc.Is(CustomRoles.LastImpostor) && !pc.Is(CustomRoles.Overclocked) && pc.Is(Custom_Team.Impostor); - + => pc.IsAlive() && !pc.Is(CustomRoles.LastImpostor)&& !pc.Is(CustomRoles.Overclocked) && pc.Is(Custom_Team.Impostor); + public static void SetSubRole() { if (currentId != byte.MaxValue || !AmongUsClient.Instance.AmHost) return; @@ -51,4 +50,4 @@ public static void SetSubRole() } } } -} +} \ No newline at end of file diff --git a/Roles/AddOns/Impostor/Madmate.cs b/Roles/AddOns/Impostor/Madmate.cs index 033ed2476..f368b568d 100644 --- a/Roles/AddOns/Impostor/Madmate.cs +++ b/Roles/AddOns/Impostor/Madmate.cs @@ -100,7 +100,6 @@ public static bool CanBeMadmate(this PlayerControl pc, bool forAdmirer = false, { return pc != null && !pc.Is(CustomRoles.Madmate) && (pc.GetCustomRole().IsCrewmate() || (forAdmirer && pc.GetCustomRole().IsNeutral())) && !(pc.CheckCanBeMadmate(forGangster) || - pc.Is(CustomRoles.ChiefOfPolice) || pc.Is(CustomRoles.LazyGuy) || pc.Is(CustomRoles.Lazy) || pc.Is(CustomRoles.Loyal) || @@ -127,4 +126,4 @@ public static bool CheckCanBeMadmate(this PlayerControl pc, bool forGangster = f (pc.Is(CustomRoles.Retributionist) && (!forGangster ? !RetributionistCanBeMadmate.GetBool() : !Gangster.RetributionistCanBeMadmate.GetBool())) || (pc.Is(CustomRoles.Overseer) && (!forGangster ? !OverseerCanBeMadmate.GetBool() : !Gangster.OverseerCanBeMadmate.GetBool())); } -} +} \ No newline at end of file diff --git a/Roles/AddOns/Impostor/Mare.cs b/Roles/AddOns/Impostor/Mare.cs index 8a9446a26..94a26e88a 100644 --- a/Roles/AddOns/Impostor/Mare.cs +++ b/Roles/AddOns/Impostor/Mare.cs @@ -5,7 +5,6 @@ namespace TOHE.Roles.AddOns.Impostor; public class Mare : IAddon { - public CustomRoles Role => CustomRoles.Mare; private const int Id = 23000; public AddonTypes Type => AddonTypes.Impostor; public static readonly HashSet playerIdList = []; @@ -28,15 +27,14 @@ public void Init() } public void Add(byte playerId, bool gameIsLoading = true) { - if (!playerIdList.Contains(playerId)) - playerIdList.Add(playerId); + playerIdList.Add(playerId); } public void Remove(byte playerId) { playerIdList.Remove(playerId); } public static bool IsEnable => playerIdList.Any(); - + public static float GetKillCooldown => Utils.IsActive(SystemTypes.Electrical) ? KillCooldownInLightsOut.GetFloat() : DefaultKillCooldown; public static void ApplyGameOptions(byte playerId) @@ -56,4 +54,4 @@ public static void ApplyGameOptions(byte playerId) public static bool KnowTargetRoleColor(PlayerControl target, bool isMeeting) => !isMeeting && playerIdList.Contains(target.PlayerId) && Utils.IsActive(SystemTypes.Electrical); -} +} \ No newline at end of file diff --git a/Roles/AddOns/Impostor/Mimic.cs b/Roles/AddOns/Impostor/Mimic.cs index 7642676f0..2774d0a1e 100644 --- a/Roles/AddOns/Impostor/Mimic.cs +++ b/Roles/AddOns/Impostor/Mimic.cs @@ -3,7 +3,6 @@ namespace TOHE.Roles.AddOns.Impostor; public class Mimic : IAddon { - public CustomRoles Role => CustomRoles.Mimic; private const int Id = 23100; public AddonTypes Type => AddonTypes.Impostor; @@ -20,4 +19,4 @@ public void Add(byte playerId, bool gameIsLoading = true) public void Remove(byte playerId) { } public static bool CanSeeDeadRoles(PlayerControl seer, PlayerControl target) => seer.Is(CustomRoles.Mimic) && CanSeeDeadRolesOpt.GetBool() && Main.VisibleTasksCount && !target.IsAlive(); -} +} \ No newline at end of file diff --git a/Roles/AddOns/Impostor/Stealer.cs b/Roles/AddOns/Impostor/Stealer.cs index f513e6c67..a561a073d 100644 --- a/Roles/AddOns/Impostor/Stealer.cs +++ b/Roles/AddOns/Impostor/Stealer.cs @@ -4,7 +4,6 @@ namespace TOHE.Roles.AddOns.Impostor; public class Stealer : IAddon { - public CustomRoles Role => CustomRoles.Stealer; private const int Id = 23200; public AddonTypes Type => AddonTypes.Impostor; @@ -47,7 +46,7 @@ public static void AddVisualVotes(PlayerVoteArea votedPlayer, ref List x.GetRealKiller()?.PlayerId == killer.PlayerId)) * TicketsPerKill.GetFloat() + 1f) + ((Main.AllPlayerControls.Count(x => x.GetRealKiller()?.PlayerId == killer.PlayerId) + 1) * TicketsPerKill.GetFloat()) .ToString("0.0#####"))); } -} +} \ No newline at end of file diff --git a/Roles/AddOns/Impostor/Swift.cs b/Roles/AddOns/Impostor/Swift.cs index 7de17d9a9..f326ef865 100644 --- a/Roles/AddOns/Impostor/Swift.cs +++ b/Roles/AddOns/Impostor/Swift.cs @@ -5,7 +5,6 @@ namespace TOHE.Roles.AddOns.Impostor; public class Swift : IAddon { - public CustomRoles Role => CustomRoles.Swift; private const int Id = 23300; public AddonTypes Type => AddonTypes.Experimental; @@ -28,8 +27,8 @@ public static bool OnCheckMurder(PlayerControl killer, PlayerControl target) killer.TrapperKilled(target); killer.SetKillCooldown(); - + RPC.PlaySoundRPC(killer.PlayerId, Sounds.KillSound); return false; } -} +} \ No newline at end of file diff --git a/Roles/AddOns/Impostor/Tricky.cs b/Roles/AddOns/Impostor/Tricky.cs index a59bb2d55..25925151f 100644 --- a/Roles/AddOns/Impostor/Tricky.cs +++ b/Roles/AddOns/Impostor/Tricky.cs @@ -3,7 +3,6 @@ namespace TOHE.Roles.AddOns.Impostor; public class Tricky : IAddon { - public CustomRoles Role => CustomRoles.Tricky; private const int Id = 19900; public AddonTypes Type => AddonTypes.Impostor; private static OptionItem EnabledDeathReasons; @@ -43,7 +42,7 @@ public static void AfterPlayerDeathTasks(PlayerControl target) { var killer = target.GetRealKiller(); if (killer == null || !killer.Is(CustomRoles.Tricky)) return; - + var randomDeathReason = ChangeRandomDeath(); Main.PlayerStates[target.PlayerId].deathReason = randomDeathReason; Main.PlayerStates[target.PlayerId].SetDead(); @@ -52,4 +51,4 @@ public static void AfterPlayerDeathTasks(PlayerControl target) Logger.Info($"Set death reason: {randomDeathReason}", "Tricky"); }, 0.3f, "Tricky random death reason"); } -} +} \ No newline at end of file diff --git a/Roles/Core/AssignManager/GhostRoleAssign.cs b/Roles/Core/AssignManager/GhostRoleAssign.cs index 52346fde6..9eda1efd5 100644 --- a/Roles/Core/AssignManager/GhostRoleAssign.cs +++ b/Roles/Core/AssignManager/GhostRoleAssign.cs @@ -19,14 +19,16 @@ public static class GhostRoleAssign private static readonly List ImpHauntedList = []; public static void GhostAssignPatch(PlayerControl player) { - if (GameStates.IsHideNSeek - || Options.CurrentGameMode == CustomGameMode.FFA - || player == null + if (GameStates.IsHideNSeek + || Options.CurrentGameMode == CustomGameMode.FFA + || player == null || player.Data == null - || player.Data.Disconnected + || player.Data.Disconnected || GhostGetPreviousRole.ContainsKey(player.PlayerId)) return; - if (forceRole.TryGetValue(player.PlayerId, out CustomRoles forcerole)) + + + if (forceRole.TryGetValue(player.PlayerId, out CustomRoles forcerole)) { Logger.Info($" Debug set {player.GetRealName()}'s role to {forcerole}", "GhostAssignPatch"); player.GetRoleClass()?.OnRemove(player.PlayerId); @@ -76,7 +78,7 @@ or CustomRoles.Virus CustomRoles ChosenRole = CustomRoles.NotAssigned; foreach (var ghostRole in getCount.Keys.Where(x => x.GetMode() > 0)) - { + { if (ghostRole.IsCrewmate()) { if (HauntedList.Contains(ghostRole) && getCount[ghostRole] <= 0) @@ -84,18 +86,18 @@ or CustomRoles.Virus if (HauntedList.Contains(ghostRole) || getCount[ghostRole] <= 0) continue; - - if (ghostRole.GetChance()) HauntedList.Add(ghostRole); + + if (ghostRole.GetChance()) HauntedList.Add(ghostRole); } if (ghostRole.IsImpostor()) { if (ImpHauntedList.Contains(ghostRole) && getCount[ghostRole] <= 0) - ImpHauntedList.Remove(ghostRole); + ImpHauntedList.Remove(ghostRole); if (ImpHauntedList.Contains(ghostRole) || getCount[ghostRole] <= 0) - continue; + continue; - if (ghostRole.GetChance()) ImpHauntedList.Add(ghostRole); + if (ghostRole.GetChance()) ImpHauntedList.Add(ghostRole); } } @@ -140,11 +142,11 @@ or CustomRoles.Virus } } - public static void Init() + public static void Init() { CrewCount = 0; ImpCount = 0; - getCount.Clear(); + getCount.Clear(); GhostGetPreviousRole.Clear(); } public static void Add() @@ -161,8 +163,7 @@ public static void Add() public static void CreateGAMessage(PlayerControl __instance) { Utils.NotifyRoles(SpecifyTarget: __instance); - _ = new LateTask(() => - { + _ = new LateTask(() => { __instance.RpcResetAbilityCooldown(); diff --git a/Roles/Core/AssignManager/RoleAssign.cs b/Roles/Core/AssignManager/RoleAssign.cs index c4f7950ad..db1c51e07 100644 --- a/Roles/Core/AssignManager/RoleAssign.cs +++ b/Roles/Core/AssignManager/RoleAssign.cs @@ -11,7 +11,6 @@ public class RoleAssign public static Dictionary RoleResult = []; public static CustomRoles[] AllRoles => [.. RoleResult.Values]; - [Obfuscation(Exclude = true)] enum RoleAssignType { Impostor, diff --git a/Roles/Core/CustomRoleManager.cs b/Roles/Core/CustomRoleManager.cs index 87bf1700e..6458d4a14 100644 --- a/Roles/Core/CustomRoleManager.cs +++ b/Roles/Core/CustomRoleManager.cs @@ -16,20 +16,7 @@ public static class CustomRoleManager { public static readonly Dictionary RoleClass = []; public static readonly Dictionary AddonClasses = []; - public static RoleBase GetStaticRoleClass(this CustomRoles role) - { - var roleClass = RoleClass.FirstOrDefault(x => x.Key == role).Value; - - if (!role.IsVanilla() && !role.IsAdditionRole() - && role is not CustomRoles.Apocalypse and not CustomRoles.Mini and not CustomRoles.NotAssigned and not CustomRoles.SpeedBooster and not CustomRoles.Killer and not CustomRoles.GM) - { - if (RoleClass.Where(x => x.Value.Role == role).Count() > 1) - Logger.Error($"RoleClass for {role} is not unique.", "GetStaticRoleClass"); - if (roleClass == null) - Logger.Error($"RoleClass for {role} is null.", "GetStaticRoleClass"); - } - return roleClass ?? new DefaultSetup(); - } + public static RoleBase GetStaticRoleClass(this CustomRoles role) => RoleClass.TryGetValue(role, out var roleClass) & roleClass != null ? roleClass : new DefaultSetup(); public static List AllEnabledRoles => Main.PlayerStates.Values.Select(x => x.RoleClass).ToList(); //Since there are classes which use object attributes and playerstate is not removed. public static bool HasEnabled(this CustomRoles role) => role.GetStaticRoleClass().IsEnable; @@ -75,7 +62,7 @@ public static List GetExperimentalOptions(Custom_Team team) public static RoleBase GetRoleClass(this PlayerControl player) => GetRoleClassById(player.PlayerId); public static RoleBase GetRoleClassById(this byte playerId) => Main.PlayerStates.TryGetValue(playerId, out var statePlayer) && statePlayer != null ? statePlayer.RoleClass : new DefaultSetup(); - public static RoleBase CreateRoleClass(this CustomRoles role) + public static RoleBase CreateRoleClass(this CustomRoles role) { return (RoleBase)Activator.CreateInstance(role.GetStaticRoleClass().GetType()); // Converts this.RoleBase back to its type and creates an unique one. } @@ -119,10 +106,10 @@ public static void BuildCustomGameOptions(this PlayerControl player, ref IGameOp } if (Grenadier.HasEnabled) Grenadier.ApplyGameOptionsForOthers(opt, player); - if (CustomRoles.Dazzler.RoleExist()) Dazzler.SetDazzled(player, opt); - if (CustomRoles.Deathpact.RoleExist()) Deathpact.SetDeathpactVision(player, opt); + if (Dazzler.HasEnabled) Dazzler.SetDazzled(player, opt); + if (Deathpact.HasEnabled) Deathpact.SetDeathpactVision(player, opt); if (Spiritcaller.HasEnabled) Spiritcaller.ReduceVision(opt, player); - if (CustomRoles.Pitfall.RoleExist()) Pitfall.SetPitfallTrapVision(opt, player); + if (Pitfall.HasEnabled) Pitfall.SetPitfallTrapVision(opt, player); var playerSubRoles = player.GetCustomSubRoles(); @@ -174,6 +161,7 @@ public static bool OnCheckMurder(ref PlayerControl killer, ref PlayerControl tar { if (killer == target) return true; + // Check if the target is Fragile if (target != null && target.Is(CustomRoles.Fragile)) { if (Fragile.KillFragile(killer, target)) @@ -182,18 +170,31 @@ public static bool OnCheckMurder(ref PlayerControl killer, ref PlayerControl tar return false; } } - var canceled = false; + + // Check if the target is Lingering Presence + if (target != null && target.Is(CustomRoles.LingeringPresence)) + { + if (LingeringPresence.KillLingeringPresence(killer, target)) + { + Logger.Info("Lingering Presence killed in OnCheckMurder, returning false", "LingeringPresence"); + return false; + } + } + + + + var canceled = false; var cancelbutkill = false; var killerRoleClass = killer.GetRoleClass(); var killerSubRoles = killer.GetCustomSubRoles(); // If Target is possessed by Dollmaster swap controllers. - target = DollMaster.SwapPlayerInfo(target); + target = DollMaster.SwapPlayerInfo(target); Logger.Info("Start", "PlagueBearer.CheckAndInfect"); - if (CustomRoles.PlagueBearer.RoleExist(true) && !killer.Is(CustomRoles.PlagueBearer)) + if (PlagueBearer.HasEnabled && !killer.Is(CustomRoles.PlagueBearer)) { PlagueBearer.CheckAndInfect(killer, target); } @@ -263,7 +264,7 @@ public static bool OnCheckMurder(ref PlayerControl killer, ref PlayerControl tar if (killerRoleClass.OnCheckMurderAsKiller(killer, target) == false) { __state = true; - if (cancelbutkill && target.IsAlive() + if (cancelbutkill && target.IsAlive() && !DoubleTrigger.FirstTriggerTimer.TryGetValue(killer.PlayerId, out _)) // some roles have an internal rpcmurderplayer, but still had to cancel { target.RpcMurderPlayer(target); @@ -300,7 +301,7 @@ public static bool OnCheckMurder(ref PlayerControl killer, ref PlayerControl tar Oiiai.OnMurderPlayer(killer, target); return false; } - + return true; } /// @@ -365,6 +366,8 @@ public static void OnMurderPlayer(PlayerControl killer, PlayerControl target, bo case CustomRoles.Spurt: Spurt.DeathTask(target); break; + + } } @@ -397,13 +400,13 @@ public static void OnMurderPlayer(PlayerControl killer, PlayerControl target, bo FixedUpdateInNormalGamePatch.LoversSuicide(target.PlayerId, inMeeting); } } - + /// /// Check if this task is marked by a role and do something. /// public static void OthersCompleteThisTask(PlayerControl player, PlayerTask task) => AllEnabledRoles.Do(RoleClass => RoleClass.OnOthersTaskComplete(player, task)); // - + public static HashSet> CheckDeadBodyOthers = []; /// @@ -473,6 +476,8 @@ public static string GetLowerTextOthers(PlayerControl seer, PlayerControl seen, return sb.ToString(); } + + private static HashSet> SuffixOthers = []; /// @@ -511,8 +516,7 @@ public static void Add() // ADDONS //////////////////////////// - public static void OnFixedAddonUpdate(this PlayerControl pc, bool lowload) => pc.GetCustomSubRoles().Do(x => - { + public static void OnFixedAddonUpdate(this PlayerControl pc, bool lowload) => pc.GetCustomSubRoles().Do(x => { if (AddonClasses.TryGetValue(x, out var IAddon) && IAddon != null) IAddon.OnFixedUpdate(pc); else return; diff --git a/Roles/Core/RoleBase.cs b/Roles/Core/RoleBase.cs index f8694bddc..f945e6424 100644 --- a/Roles/Core/RoleBase.cs +++ b/Roles/Core/RoleBase.cs @@ -8,13 +8,12 @@ namespace TOHE; public abstract class RoleBase { - public abstract CustomRoles Role { get; } public PlayerState _state; #pragma warning disable IDE1006 public PlayerControl _Player => _state != null ? Utils.GetPlayerById(_state.PlayerId) ?? null : null; public List _playerIdList => Main.PlayerStates.Values.Where(x => x.MainRole == _state.MainRole).Select(x => x.PlayerId).Cast().ToList(); #pragma warning restore IDE1006 - + private static readonly Dictionary RoleTypeOverrides = new(); public float AbilityLimit { get; set; } = -100; public virtual bool IsEnable { get; set; } = false; public bool HasVoted = false; @@ -31,12 +30,10 @@ public void OnInit() // CustomRoleManager.RoleClass executes this public void OnAdd(byte playerid) // The player with the class executes this { _state = Main.PlayerStates.Values.FirstOrDefault(state => state.PlayerId == playerid); - try - { + try { CustomRoleManager.RoleClass.FirstOrDefault(r => r.Key == _state.MainRole).Value.IsEnable = true; this.IsEnable = true; // Not supposed to be used, but some methods may have still implemented that check. - } - catch { } // temporary try catch + } catch { } // temporary try catch Add(playerid); @@ -55,8 +52,16 @@ public void OnRemove(byte playerId) { Remove(playerId); IsEnable = false; + } + public static void OverrideRoleType(CustomRoles role, Custom_RoleType newType) + { + RoleTypeOverrides[role] = newType; + Logger.Info($"Role type for {role} overridden to {newType}.", "Randomizer"); + } - Main.UnShapeShifter.Remove(playerId); + public static Custom_RoleType GetEffectiveRoleType(CustomRoles role) + { + return RoleTypeOverrides.TryGetValue(role, out var overriddenType) ? overriddenType : role.GetStaticRoleClass().ThisRoleType; } /// @@ -89,7 +94,7 @@ public virtual void Remove(byte playerId) /// /// Defines the custom role /// - public CustomRoles ThisCustomRole => Role; + public CustomRoles ThisCustomRole => System.Enum.Parse(GetType().Name, true); //this is a draft, it is not usable yet, Imma fix it in another PR @@ -119,12 +124,6 @@ public virtual void SetDesyncImpostorBuddies(ref Dictionary public virtual bool OnSabotage(PlayerControl pc) => pc != null; - /// - /// When player is enginner role base but should not move in vents - /// - public virtual bool BlockMoveInVent(PlayerControl pc) => false; - - public HashSet LastBlockedMoveInVentVents = []; public virtual void SetupCustomOption() { } @@ -267,11 +266,10 @@ public virtual void OnShapeshift(PlayerControl shapeshifter, PlayerControl targe // NOTE: when using UnShapeshift button, it will not be possible to revert to normal state because of complications. // So OnCheckShapeShift and OnShapeshift are pointless when using it. // Last thing, while the button may say "shift" after resetability, the game still thinks you're shapeshifted and will work instantly as intended. - + /// /// A method which when implemented automatically makes the players always shapeshifted (as themselves). Inside you can put functions to happen when "Un-Shapeshift" button is pressed. /// - [Obfuscation(Exclude = true)] public virtual void UnShapeShiftButton(PlayerControl shapeshifter) { } /// @@ -299,7 +297,6 @@ public virtual void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo public virtual bool GuessCheck(bool isUI, PlayerControl guesser, PlayerControl target, CustomRoles role, ref bool guesserSuicide) => target == null; /// /// When guesser trying guess target a role - /// Target need to check whether misguessed so it wont cancel mis guesses. /// public virtual bool OnRoleGuess(bool isUI, PlayerControl target, PlayerControl guesser, CustomRoles role, ref bool guesserSuicide) => target == null; @@ -378,7 +375,6 @@ public virtual void OnCoEndGame() /// /// If role wants to return the vote to the player during meeting. Can also work to check any abilities during meeting. /// - [Obfuscation(Exclude = true)] public virtual bool CheckVote(PlayerControl voter, PlayerControl target) => voter != null && target != null; /// @@ -447,7 +443,7 @@ public virtual void SetAbilityButtonText(HudManager hud, byte playerId) public virtual string GetMarkOthers(PlayerControl seer, PlayerControl seen, bool isForMeeting = false) => string.Empty; public virtual string GetLowerTextOthers(PlayerControl seer, PlayerControl seen = null, bool isForMeeting = false, bool isForHud = false) => string.Empty; public virtual string GetSuffixOthers(PlayerControl seer, PlayerControl seen, bool isForMeeting = false) => string.Empty; - + // Player know role target, color role target @@ -456,7 +452,7 @@ public virtual void SetAbilityButtonText(HudManager hud, byte playerId) public virtual bool OthersKnowTargetRoleColor(PlayerControl seer, PlayerControl target) => false; - public void OnReceiveRPC(MessageReader reader) + public void OnReceiveRPC(MessageReader reader) { float Limit = reader.ReadSingle(); AbilityLimit = Limit; @@ -473,7 +469,6 @@ public virtual void ReceiveRPC(MessageReader reader, PlayerControl pc) OnReceiveRPC(reader); // Default implementation } - [Obfuscation(Exclude = true)] public enum GeneralOption { // Ability diff --git a/Roles/Crewmate/Addict.cs b/Roles/Crewmate/Addict.cs index 07a8fc229..076c9ce65 100644 --- a/Roles/Crewmate/Addict.cs +++ b/Roles/Crewmate/Addict.cs @@ -7,11 +7,12 @@ namespace TOHE.Roles.Crewmate; internal class Addict : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Addict; private const int Id = 6300; + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Engineer; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateBasic; - public override bool BlockMoveInVent(PlayerControl pc) => true; //==================================================================\\ private static OptionItem VentCooldown; @@ -38,6 +39,7 @@ public override void SetupCustomOption() } public override void Init() { + playerIdList.Clear(); SuicideTimer.Clear(); ImmortalTimer.Clear(); DefaultSpeed = new(); @@ -45,12 +47,14 @@ public override void Init() } public override void Add(byte playerId) { + playerIdList.Add(playerId); SuicideTimer.TryAdd(playerId, -10f); ImmortalTimer.TryAdd(playerId, 420f); DefaultSpeed = Main.AllPlayerSpeed[playerId]; } public override void Remove(byte playerId) { + playerIdList.Remove(playerId); SuicideTimer.Remove(playerId); ImmortalTimer.Remove(playerId); DefaultSpeed = Main.AllPlayerSpeed[playerId]; @@ -70,7 +74,7 @@ public override bool OnCheckMurderAsTarget(PlayerControl killer, PlayerControl t } public override void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo target) { - foreach (var player in _playerIdList.ToArray()) + foreach (var player in playerIdList.ToArray()) { SuicideTimer[player] = -10f; ImmortalTimer[player] = 420f; diff --git a/Roles/Crewmate/Admirer.cs b/Roles/Crewmate/Admirer.cs index 5c0c9481a..f6a3a6cf1 100644 --- a/Roles/Crewmate/Admirer.cs +++ b/Roles/Crewmate/Admirer.cs @@ -13,7 +13,6 @@ namespace TOHE.Roles.Crewmate; internal class Admirer : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Admirer; private const int Id = 24800; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Admired); public override bool IsDesyncRole => true; @@ -42,7 +41,7 @@ public override void Init() } public override void Add(byte playerId) { - AbilityLimit = SkillLimit.GetInt(); + AbilityLimit = SkillLimit.GetInt(); AdmiredList[playerId] = []; } public override void Remove(byte playerId) @@ -82,7 +81,7 @@ public static void ReceiveRPC(MessageReader reader, bool isList) else AdmiredList[playerId].Add(targetId); } } - + public override void SetKillCooldown(byte id) => Main.AllPlayerKillCooldown[id] = AbilityLimit >= 1 ? AdmireCooldown.GetFloat() : 300f; public override bool CanUseKillButton(PlayerControl player) => AbilityLimit >= 1; @@ -98,7 +97,7 @@ public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl t if (!AdmiredList.ContainsKey(killer.PlayerId)) AdmiredList.Add(killer.PlayerId, []); - if (AbilityLimit < 1) return false; + if (AbilityLimit< 1) return false; if (CanBeAdmired(target, killer)) { if (KnowTargetRole.GetBool()) @@ -163,18 +162,18 @@ public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl t target.RpcGuardAndKill(killer); target.ResetKillCooldown(); target.SetKillCooldown(forceAnime: true); - + Logger.Info("设置职业:" + target?.Data?.PlayerName + " = " + target.GetCustomRole().ToString() + " + " + CustomRoles.Admirer.ToString(), "Assign " + CustomRoles.Admirer.ToString()); Logger.Info($"{killer.GetNameWithRole()} : 剩余{AbilityLimit}次仰慕机会", "Admirer"); - + return false; } - AdmirerFailed: + AdmirerFailed: SendRPC(killer.PlayerId); //Sync skill - + killer.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Admirer), GetString("AdmirerInvalidTarget"))); - + Logger.Info($"{killer.GetNameWithRole()} : 剩余{AbilityLimit}次仰慕机会", "Admirer"); return false; } diff --git a/Roles/Crewmate/Alchemist.cs b/Roles/Crewmate/Alchemist.cs index ff5f69994..d55c3a9f1 100644 --- a/Roles/Crewmate/Alchemist.cs +++ b/Roles/Crewmate/Alchemist.cs @@ -13,14 +13,14 @@ namespace TOHE.Roles.Crewmate; internal class Alchemist : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Alchemist; private const int Id = 6400; + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Engineer; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateBasic; - public override bool BlockMoveInVent(PlayerControl pc) => true; //==================================================================\\ - private static List PlayerIdList => Main.PlayerStates.Values.Where(x => x.MainRole == CustomRoles.Alchemist).Select(x => x.PlayerId).ToList(); private static OptionItem VentCooldown; private static OptionItem ShieldDuration; private static OptionItem Vision; @@ -61,6 +61,7 @@ public override void SetupCustomOption() public override void Init() { + playerIdList.Clear(); BloodthirstList.Clear(); PotionID = 10; PlayerName = string.Empty; @@ -71,6 +72,7 @@ public override void Init() } public override void Add(byte playerId) { + playerIdList.Add(playerId); PlayerName = Utils.GetPlayerById(playerId).GetRealName(); if (AmongUsClient.Instance.AmHost) @@ -250,10 +252,9 @@ public override void OnFixedUpdate(PlayerControl player, bool lowLoad, long nowT SendRPC(player); } } - public static void OnReportDeadBodyGlobal() { - foreach (var alchemistId in PlayerIdList) + foreach (var alchemistId in playerIdList) { if (!IsInvis(alchemistId)) continue; var alchemist = Utils.GetPlayerById(alchemistId); @@ -383,14 +384,14 @@ public override void OnCoEnterVent(PlayerPhysics __instance, int ventId) public override string GetLowerText(PlayerControl seer, PlayerControl seen = null, bool isForMeeting = false, bool isForHud = false) { if (seer == null || !seer.IsAlive() || isForMeeting || !isForHud) return string.Empty; - + var str = new StringBuilder(); if (IsInvis(seer.PlayerId)) { var remainTime = InvisTime[seer.PlayerId] + (long)InvisDuration.GetFloat() - Utils.GetTimeStamp(); str.Append(string.Format(GetString("ChameleonInvisStateCountdown"), remainTime + 1)); } - else + else { switch (PotionID) { @@ -432,7 +433,7 @@ public override string GetProgressText(byte playerId, bool comms) { var player = Utils.GetPlayerById(playerId); if (player == null || !GameStates.IsInTask) return string.Empty; - + var str = new StringBuilder(); switch (PotionID) { @@ -464,7 +465,7 @@ public override string GetProgressText(byte playerId, bool comms) break; } if (FixNextSabo) str.Append("★"); - + return str.ToString(); } public override void UpdateSystem(ShipStatus __instance, SystemTypes systemType, byte amount, PlayerControl player) diff --git a/Roles/Crewmate/Altruist.cs b/Roles/Crewmate/Altruist.cs index 24edaf746..b7f3ae126 100644 --- a/Roles/Crewmate/Altruist.cs +++ b/Roles/Crewmate/Altruist.cs @@ -8,7 +8,6 @@ namespace TOHE.Roles.Crewmate; internal class Altruist : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Altruist; private const int Id = 29800; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Altruist); public override CustomRoles ThisRoleBase => CustomRoles.Engineer; @@ -46,6 +45,7 @@ public override void Init() RevivedPlayerId = byte.MaxValue; //AllRevivedPlayerId.Clear(); IsRevivingMode = true; + } public override void ApplyGameOptions(IGameOptions opt, byte playerId) @@ -121,7 +121,7 @@ public override bool OnCheckReportDeadBody(PlayerControl reporter, NetworkedPlay if (NeutralKillersCanGetsArrow.GetBool()) getArrow = true; } - + if (getAlert) { pc.KillFlash(playKillSound: false); @@ -149,7 +149,7 @@ public override bool OnCheckReportDeadBody(PlayerControl reporter, NetworkedPlay } public override string GetLowerText(PlayerControl seer, PlayerControl target, bool isForMeeting = false, bool isForHud = false) { - if (seer.PlayerId != target.PlayerId || isForMeeting || !_Player.IsAlive()) return string.Empty; + if (seer.PlayerId != target.PlayerId || isForMeeting || !_Player.IsAlive()) return string.Empty; return string.Format(Translator.GetString("AltruistSuffix"), Translator.GetString(IsRevivingMode ? "AltruistReviveMode" : "AltruistReportMode")); } public override string GetSuffixOthers(PlayerControl seer, PlayerControl target, bool isForMeeting = false) diff --git a/Roles/Crewmate/Bastion.cs b/Roles/Crewmate/Bastion.cs index 2bad61300..47cacc467 100644 --- a/Roles/Crewmate/Bastion.cs +++ b/Roles/Crewmate/Bastion.cs @@ -3,19 +3,20 @@ using System.Text; using UnityEngine; using static TOHE.Options; -using static TOHE.Translator; using static TOHE.Utils; +using static TOHE.Translator; namespace TOHE.Roles.Crewmate; internal class Bastion : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Bastion; private const int Id = 10200; + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Engineer; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateKilling; - public override bool BlockMoveInVent(PlayerControl pc) => true; //==================================================================\\ private static OptionItem BombsClearAfterMeeting; @@ -37,10 +38,12 @@ public override void SetupCustomOption() } public override void Init() { + playerIdList.Clear(); BombedVents.Clear(); } public override void Add(byte playerId) { + playerIdList.Add(playerId); AbilityLimit = BastionMaxBombs.GetInt(); } public override void ApplyGameOptions(IGameOptions opt, byte playerId) @@ -52,7 +55,7 @@ public override bool OnTaskComplete(PlayerControl player, int completedTaskCount { if (player.IsAlive()) AbilityLimit += BastionAbilityUseGainWithEachTaskCompleted.GetFloat(); - + return true; } public override string GetProgressText(byte playerId, bool comms) @@ -77,7 +80,7 @@ public override bool OnCoEnterVentOthers(PlayerPhysics physics, int ventId) if (!BombedVents.Contains(ventId)) return false; var pc = physics.myPlayer; - if (pc.Is(Custom_Team.Crewmate) && !pc.Is(CustomRoles.Bastion) && !pc.IsCrewVenter() && !CopyCat.playerIdList.Contains(pc.PlayerId) && !Main.TasklessCrewmate.Contains(pc.PlayerId)) + if (pc.Is(Custom_Team.Crewmate) && !pc.Is(CustomRoles.Bastion) && !pc.IsCrewVenter() && !CopyCat.playerIdList.Contains(pc.PlayerId) && !Main.TasklessCrewmate.Contains(pc.PlayerId)) { Logger.Info("Crewmate enter in bombed vent, bombed is cancel", "Bastion.OnCoEnterVentOther"); return false; diff --git a/Roles/Crewmate/Benefactor.cs b/Roles/Crewmate/Benefactor.cs index 49cafa8fa..8cc9aed02 100644 --- a/Roles/Crewmate/Benefactor.cs +++ b/Roles/Crewmate/Benefactor.cs @@ -7,9 +7,10 @@ namespace TOHE.Roles.Crewmate; internal class Benefactor : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Benefactor; private const int Id = 26400; - + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateSupport; //==================================================================\\ @@ -37,6 +38,7 @@ public override void SetupCustomOption() public override void Init() { + playerIdList.Clear(); taskIndex.Clear(); shieldedPlayers.Clear(); TaskMarkPerRound.Clear(); @@ -44,10 +46,12 @@ public override void Init() } public override void Add(byte playerId) { + playerIdList.Add(playerId); TaskMarkPerRound[playerId] = 0; } public override void Remove(byte playerId) { + playerIdList.Remove(playerId); TaskMarkPerRound.Remove(playerId); } @@ -142,12 +146,13 @@ public override void AfterMeetingTasks() public override void OnOthersTaskComplete(PlayerControl player, PlayerTask task) // runs for every player which compeletes a task { if (!AmongUsClient.Instance.AmHost) return; - + + if (!HasEnabled) return; if (player == null || _Player == null) return; - if (!player.IsAlive() || !_Player.IsAlive()) return; - + if (!player.IsAlive()) return; + byte playerId = player.PlayerId; - + if (player.Is(CustomRoles.Benefactor)) { if (!TaskMarkPerRound.ContainsKey(playerId)) TaskMarkPerRound[playerId] = 0; @@ -211,7 +216,7 @@ public override void OnFixedUpdate(PlayerControl player, bool lowLoad, long nowT shieldedPlayers.Remove(targetId); target?.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Benefactor), GetString("BKProtectOut"))); target?.RpcGuardAndKill(); - + SendRPC(type: 4, targetId: targetId); } } diff --git a/Roles/Crewmate/Bodyguard.cs b/Roles/Crewmate/Bodyguard.cs index 51a116bab..9290ac24a 100644 --- a/Roles/Crewmate/Bodyguard.cs +++ b/Roles/Crewmate/Bodyguard.cs @@ -6,7 +6,6 @@ namespace TOHE.Roles.Crewmate; internal class Bodyguard : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Bodyguard; private const int Id = 10300; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Bodyguard); diff --git a/Roles/Crewmate/Captain.cs b/Roles/Crewmate/Captain.cs index 3732f02c1..e3480bcb8 100644 --- a/Roles/Crewmate/Captain.cs +++ b/Roles/Crewmate/Captain.cs @@ -8,8 +8,10 @@ namespace TOHE.Roles.Crewmate; internal class Captain : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Captain; private const int Id = 26300; + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmatePower; //==================================================================\\ @@ -50,9 +52,15 @@ public override void SetupCustomOption() public override void Init() { + playerIdList.Clear(); OriginalSpeed.Clear(); CaptainVoteTargets.Clear(); } + + public override void Add(byte playerId) + { + playerIdList.Add(playerId); + } public static void ReceiveRPCRevertAllSpeed() { OriginalSpeed.Clear(); @@ -70,8 +78,8 @@ public override bool OnTaskComplete(PlayerControl pc, int completedTaskCount, in (CaptainCanTargetNB.GetBool() && x.GetCustomRole().IsNB()) || (CaptainCanTargetNE.GetBool() && x.GetCustomRole().IsNE()) || (CaptainCanTargetNC.GetBool() && x.GetCustomRole().IsNC()) || - (CaptainCanTargetNK.GetBool() && x.GetCustomRole().IsNeutralKillerTeam()) - || (CaptainCanTargetNA.GetBool() && x.GetCustomRole().IsNA()))).ToList(); + (CaptainCanTargetNK.GetBool() && x.GetCustomRole().IsNeutralKillerTeam()) + || (CaptainCanTargetNA.GetBool() && x.GetCustomRole().IsNA()))).ToList(); Logger.Info($"Total Number of Potential Target {allTargets.Count}", "Total Captain Target"); if (allTargets.Count == 0) return true; @@ -128,7 +136,7 @@ public override void OnPlayerExiled(PlayerControl captain, NetworkedPlayerInfo e for (int i = 0; i < CaptainVoteTargets[playerId].Count; i++) { var captainTarget = CaptainVoteTargets[playerId][i]; - if (captainTarget == byte.MaxValue || !GetPlayerById(captainTarget).IsAlive()) continue; + if (captainTarget == byte.MaxValue || !GetPlayerById(captainTarget).IsAlive()) continue; var SelectedAddOn = SelectRandomAddon(captainTarget); if (SelectedAddOn == null) continue; Main.PlayerStates[captainTarget].RemoveSubRole((CustomRoles)SelectedAddOn); diff --git a/Roles/Crewmate/Celebrity.cs b/Roles/Crewmate/Celebrity.cs index 921de86d5..a7b132156 100644 --- a/Roles/Crewmate/Celebrity.cs +++ b/Roles/Crewmate/Celebrity.cs @@ -1,15 +1,17 @@ -using static TOHE.MeetingHudStartPatch; -using static TOHE.Options; -using static TOHE.Translator; +using static TOHE.Options; using static TOHE.Utils; +using static TOHE.Translator; +using static TOHE.MeetingHudStartPatch; namespace TOHE.Roles.Crewmate; internal class Celebrity : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Celebrity; private const int Id = 6500; + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateBasic; //==================================================================\\ @@ -30,8 +32,13 @@ public override void SetupCustomOption() } public override void Init() { + playerIdList.Clear(); CelebrityDead.Clear(); } + public override void Add(byte playerId) + { + playerIdList.Add(playerId); + } public override bool GlobalKillFlashCheck(PlayerControl killer, PlayerControl target, PlayerControl seer) { // if Celebrity killed and seer is Celebrity, return true for show kill flash diff --git a/Roles/Crewmate/Chameleon.cs b/Roles/Crewmate/Chameleon.cs index 914f2900d..dcf4147be 100644 --- a/Roles/Crewmate/Chameleon.cs +++ b/Roles/Crewmate/Chameleon.cs @@ -2,18 +2,17 @@ using Hazel; using System; using System.Text; -using TOHE.Roles.Core; using UnityEngine; +using TOHE.Roles.Core; +using static TOHE.Utils; using static TOHE.Options; using static TOHE.Translator; -using static TOHE.Utils; namespace TOHE.Roles.Crewmate; internal class Chameleon : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Chameleon; private const int Id = 7600; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Chameleon); public override CustomRoles ThisRoleBase => CustomRoles.Engineer; @@ -77,7 +76,7 @@ public static void ReceiveRPC_Custom(MessageReader reader) float limit = reader.ReadSingle(); Main.PlayerStates[pid].RoleClass.AbilityLimit = limit; } - else + else { InvisCooldown.Clear(); InvisDuration.Clear(); @@ -92,12 +91,12 @@ public override void ApplyGameOptions(IGameOptions opt, byte playerId) AURoleOptions.EngineerCooldown = ChameleonCooldown.GetFloat() + 1f; AURoleOptions.EngineerInVentMaxTime = 1f; } - + private static bool CanGoInvis(byte id) => GameStates.IsInTask && !InvisDuration.ContainsKey(id) && !InvisCooldown.ContainsKey(id); - + private static bool IsInvis(byte id) => InvisDuration.ContainsKey(id); - + public override void OnReportDeadBody(PlayerControl y, NetworkedPlayerInfo x) { foreach (var chameleonId in _playerIdList.ToArray()) @@ -170,7 +169,7 @@ public override void OnFixedUpdate(PlayerControl player, bool lowLoad, long nowT InvisCooldown.Add(chameleonId, nowTime); chameleon.Notify(GetString("ChameleonInvisStateOut")); - + needSync = true; InvisDuration.Remove(chameleonId); } @@ -289,4 +288,4 @@ public override string GetProgressText(byte playerId, bool comms) ProgressText.Append(ColorString(TextColor131, $" - {Math.Round(AbilityLimit, 1)}")); return ProgressText.ToString(); } -} +} \ No newline at end of file diff --git a/Roles/Crewmate/ChiefOfPolice.cs b/Roles/Crewmate/ChiefOfPolice.cs index 5d42afa3b..17d89de72 100644 --- a/Roles/Crewmate/ChiefOfPolice.cs +++ b/Roles/Crewmate/ChiefOfPolice.cs @@ -1,165 +1,115 @@ -using TOHE.Roles.Core; -using UnityEngine; -using static TOHE.Options; -using static TOHE.Translator; +//namespace TOHE.Roles.Crewmate; -namespace TOHE.Roles.Crewmate; -internal class ChiefOfPolice : RoleBase +// Unused role +/* +public static class ChiefOfPolice { - //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.ChiefOfPolice; private const int Id = 12600; - public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.ChiefOfPolice); - public override bool IsDesyncRole => true; - public override CustomRoles ThisRoleBase => CustomRoles.Impostor; - public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmatePower; - //==================================================================\\ + private static List playerIdList = []; + public static Dictionary PoliceLimit = []; + public static bool IsEnable = false; private static OptionItem SkillCooldown; - private static OptionItem CanRecruitImpostorAndNeutarl; - private static OptionItem PreventRecruitNonKiller; - private static OptionItem SuidiceWhenTargetNotKiller; - private static OptionItem PassConverted; + private static OptionItem CanImpostorAndNeutarl; - public override void SetupCustomOption() + public override void SetupCustomOptions() { - SetupSingleRoleOptions(Id, TabGroup.CrewmateRoles, CustomRoles.ChiefOfPolice); - SkillCooldown = FloatOptionItem.Create(Id + 10, "ChiefOfPoliceSkillCooldown", new(2.5f, 900f, 2.5f), 20f, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.ChiefOfPolice]) + Options.SetupRoleOptions(Id, TabGroup.CrewmateRoles, CustomRoles.ChiefOfPolice); + SkillCooldown = FloatOptionItem.Create(Id + 10, "ChiefOfPoliceSkillCooldown", new(2.5f, 900f, 2.5f), 20f, TabGroup.CrewmateRoles, false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.ChiefOfPolice]) .SetValueFormat(OptionFormat.Seconds); - CanRecruitImpostorAndNeutarl = BooleanOptionItem.Create(Id + 11, "PolicCanImpostorAndNeutarl", false, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.ChiefOfPolice]); - PreventRecruitNonKiller = BooleanOptionItem.Create(Id + 12, "PolicPreventRecruitNonKiller", false, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.ChiefOfPolice]); - SuidiceWhenTargetNotKiller = BooleanOptionItem.Create(Id + 13, "PolicSuidiceWhenTargetNotKiller", false, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.ChiefOfPolice]); - PassConverted = BooleanOptionItem.Create(Id + 14, "PolicPassConverted", false, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.ChiefOfPolice]); + CanImpostorAndNeutarl = BooleanOptionItem.Create(Id + 16, "PolicCanImpostorAndNeutarl", false, TabGroup.CrewmateRoles, false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.ChiefOfPolice]); } - - public override void Add(byte playerId) + public static void Init() { - AbilityLimit = 1; + playerIdList = []; + PoliceLimit = []; + IsEnable = false; } + public static void Add(byte playerId) + { + playerIdList.Add(playerId); + PoliceLimit.TryAdd(playerId, 1); + IsEnable = true; - public override bool CanUseKillButton(PlayerControl pc) => AbilityLimit > 0; - - public override void SetKillCooldown(byte id) => Main.AllPlayerKillCooldown[id] = AbilityLimit > 0 ? SkillCooldown.GetFloat() : 999f; - - public override bool KnowRoleTarget(PlayerControl seer, PlayerControl target) + if (!AmongUsClient.Instance.AmHost) return; + if (!Main.ResetCamPlayerList.Contains(playerId)) + Main.ResetCamPlayerList.Add(playerId); + } + private static void SendRPC(byte playerId) { - if (seer.IsAnySubRole(x => x.IsConverted()) || target.IsAnySubRole(x => x.IsConverted())) - return false; - if (seer.Is(CustomRoles.ChiefOfPolice) && target.Is(CustomRoles.Sheriff)) - return true; - if (seer.Is(CustomRoles.Sheriff) && target.Is(CustomRoles.ChiefOfPolice)) - return true; - return false; + MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.SyncRoleSkill, SendOption.Reliable, -1); + writer.WritePacked((int)CustomRoles.ChiefOfPolice); + writer.Write(playerId); + writer.Write(PoliceLimit[playerId]); + AmongUsClient.Instance.FinishRpcImmediately(writer); } - - public override bool ForcedCheckMurderAsKiller(PlayerControl killer, PlayerControl target) + public static void ReceiveRPC(MessageReader reader) { - if (AbilityLimit < 1) return false; - bool suidice = false; - bool isSuccess = false; - - if (target.GetCustomRole().IsCrewmate() && !target.IsAnySubRole(x => x.IsConverted())) - { - if (PreventRecruitNonKiller.GetBool() && !target.CanUseKillButton()) - { - suidice = true; - } - else - { - AbilityLimit--; - killer.RpcGuardAndKill(target); - killer.ResetKillCooldown(); - killer.SetKillCooldown(); - - target.GetRoleClass()?.OnRemove(target.PlayerId); - target.RpcChangeRoleBasis(CustomRoles.Sheriff); - target.RpcSetCustomRole(CustomRoles.Sheriff); - target.GetRoleClass()?.OnAdd(target.PlayerId); - - target.ResetKillCooldown(); - target.SetKillCooldown(forceAnime: true); - - killer.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.ChiefOfPolice), GetString("SheriffSuccessfullyRecruited"))); - target.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.ChiefOfPolice), GetString("BeSheriffByPolice"))); - - Utils.NotifyRoles(killer); - Utils.NotifyRoles(target); - isSuccess = true; - } - } + byte PlayerId = reader.ReadByte(); + int Limit = reader.ReadInt32(); + if (PoliceLimit.ContainsKey(PlayerId)) + PoliceLimit[PlayerId] = Limit; else - { - if (!CanRecruitImpostorAndNeutarl.GetBool()) - { - suidice = true; - } - else - { - if (PreventRecruitNonKiller.GetBool() && !target.CanUseKillButton()) - { - suidice = true; - } - else - { - AbilityLimit--; - killer.RpcGuardAndKill(target); - killer.ResetKillCooldown(); - killer.SetKillCooldown(); - - target.GetRoleClass()?.OnRemove(target.PlayerId); - target.RpcChangeRoleBasis(CustomRoles.Sheriff); - target.RpcSetCustomRole(CustomRoles.Sheriff); - target.GetRoleClass()?.OnAdd(target.PlayerId); - - target.ResetKillCooldown(); - target.SetKillCooldown(forceAnime: true); + PoliceLimit.Add(PlayerId, 1); + } + public static bool CanUseKillButton(byte playerId) + => !Main.PlayerStates[playerId].IsDead + && (PoliceLimit.TryGetValue(playerId, out var x) ? x : 1) >= 1; - killer.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.ChiefOfPolice), GetString("SheriffSuccessfullyRecruited"))); - target.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.ChiefOfPolice), GetString("BeSheriffByPolice"))); + public static void SetKillCooldown(byte id) => Main.AllPlayerKillCooldown[id] = CanUseKillButton(id) ? SkillCooldown.GetFloat() : 300f; - Utils.NotifyRoles(killer); - Utils.NotifyRoles(target); - isSuccess = true; - } - } - } - - if (suidice && SuidiceWhenTargetNotKiller.GetBool()) - { - AbilityLimit--; - killer.SetDeathReason(PlayerState.DeathReason.Misfire); - killer.SetRealKiller(killer); - killer.RpcMurderPlayer(killer); - } - else if (isSuccess) + public static string GetSkillLimit(byte playerId) => Utils.ColorString(CanUseKillButton(playerId) ? Utils.GetRoleColor(CustomRoles.ChiefOfPolice) : Color.gray, PoliceLimit.TryGetValue(playerId, out var policeLimit) ? $"({policeLimit})" : "Invalid"); + + public static bool OnCheckMurder(PlayerControl killer, PlayerControl target) + { + PoliceLimit[killer.PlayerId]--; + SendRPC(killer.PlayerId); + if (CanBeSheriff(target)) { - if (PassConverted.GetBool()) + target.RpcSetCustomRole(CustomRoles.Sheriff); + var targetId = target.PlayerId; + foreach (var player in Main.AllAlivePlayerControls) { - if (killer.IsAnySubRole(x => x.IsConverted() && x is not CustomRoles.Egoist)) + if (player.PlayerId == targetId) { - var role = killer.GetCustomSubRoles().FirstOrDefault(x => x.IsConverted() && x is not CustomRoles.Egoist); - Logger.Info($"Giving addon {role} to {target.GetNameWithRole()}", "ChiefOfPolice"); - target.RpcSetCustomRole(role); + // Sheriff.Add(player.PlayerId); + // Sheriff.Add(player.PlayerId); } } + killer.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Sheriff), GetString("SheriffSuccessfullyRecruited"))); + target.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Sheriff), GetString("BeSheriffByPolice"))); + + killer.ResetKillCooldown(); + target.ResetKillCooldown(); + killer.RpcGuardAndKill(target); + killer.SetKillCooldown(forceAnime: true); + target.RpcGuardAndKill(killer); + target.SetKillCooldown(forceAnime: true); } else { - killer.ResetKillCooldown(); - killer.SetKillCooldown(forceAnime: true); - killer.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.ChiefOfPolice), GetString("PoliceFailedRecruit"))); - Utils.NotifyRoles(killer); + //if (ChiefOfPoliceCountMode.GetInt() == 1) + //{ + // killer.RpcMurderPlayer(killer); + // return true; + //} + //if (ChiefOfPoliceCountMode.GetInt() == 2) + //{ + // killer.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Sheriff), GetString("NotSheriff!!!"))); + // return true; + //} } - - SendSkillRPC(); return false; } - public override void SetAbilityButtonText(HudManager hud, byte playerId) + public static bool CanBeSheriff(this PlayerControl pc) { - hud.KillButton.OverrideText(GetString("ChiefOfPoliceKillButtonText")); + return pc != null && (pc.GetCustomRole().IsCrewmate() && pc.CanUseKillButton()) || pc.GetCustomRole().IsNeutral() && pc.CanUseKillButton() && CanImpostorAndNeutarl.GetBool()|| pc.GetCustomRole().IsImpostor() && CanImpostorAndNeutarl.GetBool(); } - public override string GetProgressText(byte playerId, bool commns) - => !commns ? Utils.ColorString(AbilityLimit > 0 ? Utils.GetRoleColor(CustomRoles.ChiefOfPolice).ShadeColor(0.25f) : Color.gray, $"({AbilityLimit})") : ""; + public static void SetAbilityButtonText(HudManager hud, byte playerId) + { + hud.KillButton.OverrideText(GetString("ChiefOfPoliceKillButtonText")); + } } +*/ \ No newline at end of file diff --git a/Roles/Crewmate/Cleanser.cs b/Roles/Crewmate/Cleanser.cs index 3abbae17b..c2d584690 100644 --- a/Roles/Crewmate/Cleanser.cs +++ b/Roles/Crewmate/Cleanser.cs @@ -8,7 +8,6 @@ namespace TOHE.Roles.Crewmate; internal class Cleanser : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Cleanser; private const int Id = 6600; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Cleanser); public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; @@ -20,7 +19,7 @@ internal class Cleanser : RoleBase //private static OptionItem AbilityUseGainWithEachTaskCompleted; private readonly HashSet CleansedPlayers = []; - private readonly Dictionary CleanserTarget = []; + private readonly Dictionary CleanserTarget = []; private bool DidVote; public override void SetupCustomOption() @@ -111,4 +110,4 @@ public override void AfterMeetingTasks() } Utils.MarkEveryoneDirtySettings(); } -} +} \ No newline at end of file diff --git a/Roles/Crewmate/CopyCat.cs b/Roles/Crewmate/CopyCat.cs index d8448d367..5aad19da9 100644 --- a/Roles/Crewmate/CopyCat.cs +++ b/Roles/Crewmate/CopyCat.cs @@ -8,10 +8,9 @@ namespace TOHE.Roles.Crewmate; internal class CopyCat : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.CopyCat; private const int Id = 11500; public static readonly HashSet playerIdList = []; - + public static bool HasEnabled => playerIdList.Any(); public override bool IsDesyncRole => true; public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmatePower; @@ -40,14 +39,12 @@ public override void Init() public override void Add(byte playerId) { - if (!playerIdList.Contains(playerId)) - playerIdList.Add(playerId); + playerIdList.Add(playerId); CurrentKillCooldown = KillCooldown.GetFloat(); } public override void Remove(byte playerId) //only to be used when copycat's role is going to be changed permanently { - // Copy cat role wont be removed for now i guess - // playerIdList.Remove(playerId); + //playerIdList.Remove(playerId); } public static bool CanCopyTeamChangingAddon() => CopyTeamChangingAddon.GetBool(); public static bool NoHaveTask(byte playerId, bool ForRecompute) => playerIdList.Contains(playerId) && (playerId.GetPlayer().GetCustomRole().IsDesyncRole() || ForRecompute); @@ -70,19 +67,18 @@ public static void UnAfterMeetingTasks() continue; } //////////// /*remove the settings for current role*/ ///////////////////// - + var pcRole = pc.GetCustomRole(); - if (pcRole is not CustomRoles.Sidekick && !(!pc.IsAlive() && pcRole is CustomRoles.Retributionist)) + if (pcRole is not CustomRoles.Sidekick and not CustomRoles.Retributionist) { if (pcRole != CustomRoles.CopyCat) { pc.GetRoleClass()?.OnRemove(pc.PlayerId); - pc.RpcChangeRoleBasis(CustomRoles.CopyCat); - pc.RpcSetCustomRole(CustomRoles.CopyCat); } + pc.RpcChangeRoleBasis(CustomRoles.CopyCat); + pc.RpcSetCustomRole(CustomRoles.CopyCat); } pc.ResetKillCooldown(); - pc.SetKillCooldown(); } } @@ -91,8 +87,7 @@ private static bool BlackList(CustomRoles role) return role is CustomRoles.CopyCat or CustomRoles.Doomsayer or // CopyCat cannot guessed roles because he can be know others roles players CustomRoles.EvilGuesser or - CustomRoles.NiceGuesser or - CustomRoles.Baker or CustomRoles.Famine; + CustomRoles.NiceGuesser; } public override bool ForcedCheckMurderAsKiller(PlayerControl killer, PlayerControl target) @@ -102,7 +97,6 @@ public override bool ForcedCheckMurderAsKiller(PlayerControl killer, PlayerContr { killer.Notify(GetString("CopyCatCanNotCopy")); killer.ResetKillCooldown(); - killer.SetKillCooldown(); return false; } if (CopyCrewVar.GetBool()) @@ -144,6 +138,7 @@ CustomRoles.Baker when Baker.CurrentBread() is 2 => CustomRoles.Medic, killer.RpcSetCustomRole(role); killer.GetRoleClass()?.OnAdd(killer.PlayerId); killer.SyncSettings(); + Main.PlayerStates[killer.PlayerId].InitTask(killer); } if (CopyTeamChangingAddon.GetBool()) { @@ -157,11 +152,10 @@ CustomRoles.Baker when Baker.CurrentBread() is 2 => CustomRoles.Medic, killer.RpcGuardAndKill(killer); killer.Notify(string.Format(GetString("CopyCatRoleChange"), Utils.GetRoleName(role))); return false; - + } killer.Notify(GetString("CopyCatCanNotCopy")); killer.ResetKillCooldown(); - killer.SetKillCooldown(); return false; } @@ -170,4 +164,4 @@ public override void SetAbilityButtonText(HudManager hud, byte id) hud.ReportButton.OverrideText(GetString("ReportButtonText")); hud.KillButton.OverrideText(GetString("CopyButtonText")); } -} +} \ No newline at end of file diff --git a/Roles/Crewmate/Coroner.cs b/Roles/Crewmate/Coroner.cs index 0f60e1570..2dd952338 100644 --- a/Roles/Crewmate/Coroner.cs +++ b/Roles/Crewmate/Coroner.cs @@ -1,19 +1,18 @@ using Hazel; -using InnerNet; using System; using System.Text; -using TOHE.Roles.Core; using UnityEngine; +using TOHE.Roles.Core; using static TOHE.Options; using static TOHE.Translator; using static TOHE.Utils; +using InnerNet; namespace TOHE.Roles.Crewmate; internal class Coroner : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Coroner; private const int Id = 7700; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Coroner); public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; diff --git a/Roles/Crewmate/Crusader.cs b/Roles/Crewmate/Crusader.cs index 3e42d89a1..67e0d0eb0 100644 --- a/Roles/Crewmate/Crusader.cs +++ b/Roles/Crewmate/Crusader.cs @@ -8,7 +8,6 @@ namespace TOHE.Roles.Crewmate; internal class Crusader : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Crusader; private const int Id = 10400; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Crusader); public override bool IsDesyncRole => true; @@ -39,9 +38,9 @@ public override void Add(byte playerId) public override void SetKillCooldown(byte id) => Main.AllPlayerKillCooldown[id] = CanUseKillButton(Utils.GetPlayerById(id)) ? CurrentKillCooldown : 300f; public override bool CanUseKillButton(PlayerControl pc) => AbilityLimit > 0; - + public override void ApplyGameOptions(IGameOptions opt, byte playerId) => opt.SetVision(false); - + public override string GetProgressText(byte playerId, bool comms) => Utils.ColorString(CanUseKillButton(Utils.GetPlayerById(playerId)) ? Utils.GetRoleColor(CustomRoles.Crusader).ShadeColor(0.25f) : Color.gray, $"({AbilityLimit})"); public override bool ForcedCheckMurderAsKiller(PlayerControl killer, PlayerControl target) @@ -54,10 +53,10 @@ public override bool ForcedCheckMurderAsKiller(PlayerControl killer, PlayerContr SendSkillRPC(); killer.SetKillCooldown(); - + if (!Options.DisableShieldAnimations.GetBool()) killer.RpcGuardAndKill(target); target.RpcGuardAndKill(killer); - + return false; } public override bool CheckMurderOnOthersTarget(PlayerControl killer, PlayerControl target) @@ -101,4 +100,4 @@ public override void SetAbilityButtonText(HudManager hud, byte id) hud.ReportButton.OverrideText(GetString("ReportButtonText")); hud.KillButton.OverrideText(GetString("CrusaderKillButtonText")); } -} +} \ No newline at end of file diff --git a/Roles/Crewmate/Deceiver.cs b/Roles/Crewmate/Deceiver.cs index 15ab45cb0..1bc0756ac 100644 --- a/Roles/Crewmate/Deceiver.cs +++ b/Roles/Crewmate/Deceiver.cs @@ -9,7 +9,6 @@ namespace TOHE.Roles.Crewmate; internal class Deceiver : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Deceiver; private const int Id = 10500; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Deceiver); public override bool IsDesyncRole => true; @@ -132,4 +131,4 @@ public override void SetAbilityButtonText(HudManager hud, byte id) hud.ReportButton.OverrideText(GetString("ReportButtonText")); hud.KillButton.OverrideText(GetString("DeceiverButtonText")); } -} +} \ No newline at end of file diff --git a/Roles/Crewmate/Deputy.cs b/Roles/Crewmate/Deputy.cs index 41fbcda86..2e9e0b2b5 100644 --- a/Roles/Crewmate/Deputy.cs +++ b/Roles/Crewmate/Deputy.cs @@ -8,7 +8,6 @@ namespace TOHE.Roles.Crewmate; internal class Deputy : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Deputy; private const int Id = 7800; public override bool IsDesyncRole => true; public override CustomRoles ThisRoleBase => CustomRoles.Impostor; @@ -57,7 +56,7 @@ public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl t return false; } - + killer.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Deputy), GetString("DeputyInvalidTarget"))); return false; } diff --git a/Roles/Crewmate/Detective.cs b/Roles/Crewmate/Detective.cs index 43d9e0714..d160ec00b 100644 --- a/Roles/Crewmate/Detective.cs +++ b/Roles/Crewmate/Detective.cs @@ -1,7 +1,7 @@ using System.Text; using TOHE.Roles.Core; -using static TOHE.MeetingHudStartPatch; using static TOHE.Options; +using static TOHE.MeetingHudStartPatch; using static TOHE.Translator; namespace TOHE.Roles.Crewmate; @@ -9,8 +9,10 @@ namespace TOHE.Roles.Crewmate; internal class Detective : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Detective; private const int Id = 7900; + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateSupport; //==================================================================\\ @@ -29,16 +31,19 @@ public override void SetupCustomOption() public override void Init() { + playerIdList.Clear(); DetectiveNotify.Clear(); InfoAboutDeadPlayerAndKiller.Clear(); } public override void Add(byte playerId) { + playerIdList.Add(playerId); CustomRoleManager.CheckDeadBodyOthers.Add(GetInfoFromDeadBody); } public override void Remove(byte playerId) { + playerIdList.Remove(playerId); CustomRoleManager.CheckDeadBodyOthers.Remove(GetInfoFromDeadBody); } private void GetInfoFromDeadBody(PlayerControl killer, PlayerControl target, bool inMeeting) diff --git a/Roles/Crewmate/Dictator.cs b/Roles/Crewmate/Dictator.cs index 710229f60..e181053de 100644 --- a/Roles/Crewmate/Dictator.cs +++ b/Roles/Crewmate/Dictator.cs @@ -1,207 +1,32 @@ -using Hazel; -using System; -using TOHE.Modules.ChatManager; -using TOHE.Roles.Core; -using UnityEngine; -using static TOHE.Options; -using static TOHE.Translator; -using static TOHE.Utils; +using static TOHE.Options; namespace TOHE.Roles.Crewmate; internal class Dictator : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Dictator; private const int Id = 11600; + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmatePower; //==================================================================\\ - public static OptionItem ChangeCommandToExpel; + public override void SetupCustomOption() { SetupRoleOptions(Id, TabGroup.CrewmateRoles, CustomRoles.Dictator); - ChangeCommandToExpel = BooleanOptionItem.Create(Id + 10, "DictatorChangeCommandToExpel", false, TabGroup.CrewmateRoles, false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Dictator]); - } - - public static bool CheckVotingForTarget(PlayerControl pc, PlayerVoteArea pva) - => pc.Is(CustomRoles.Dictator) && pva.DidVote && pc.PlayerId != pva.VotedFor && pva.VotedFor < 253 && !pc.Data.IsDead; - public bool ExilePlayer(PlayerControl pc, string msg, bool isUI = false) - { - if (!ChangeCommandToExpel.GetBool()) return false; - if (!AmongUsClient.Instance.AmHost) return false; - if (!GameStates.IsMeeting || pc == null || GameStates.IsExilling) return false; - if (!pc.IsAlive()) return false; - if (!pc.Is(CustomRoles.Dictator)) return false; - int operate = 0; // 1:ID 2:猜测 - msg = msg.ToLower().TrimStart().TrimEnd(); - if (ChatManager.CheckCommond(ref msg, "id|guesslist|gl编号|玩家编号|玩家id|id列表|玩家列表|列表|所有id|全部id||編號|玩家編號")) operate = 1; - else if (ChatManager.CheckCommond(ref msg, "exp|expel|独裁|獨裁", false)) operate = 2; - else return false; - List statesList = []; - MeetingHud.VoterState[] states; - - if (operate == 1) - { - Utils.SendMessage(GuessManager.GetFormatString(), pc.PlayerId); - // GuessManager.TryHideMsg(); - // ChatManager.SendPreviousMessagesToAll(); - return true; - } - if (operate == 2) - { - if (msg.StartsWith("/")) msg = msg.Replace("/", string.Empty); - var targetid = 0; - if (int.TryParse(msg, out int num)) - { - targetid = Convert.ToByte(num); - } - var target = Utils.GetPlayerById(targetid); - if (target == pc) - { - pc.ShowInfoMessage(isUI, GetString("DictatorExpelSelf")); - return true; - } - if (!target.IsAlive()) - { - return true; - } - - if (target.Is(CustomRoles.Solsticer)) - { - pc.ShowInfoMessage(isUI, GetString("ExpelSolsticer")); - MeetingHud.Instance.RpcClearVoteDelay(pc.GetClientId()); - return true; - } - - statesList.Add(new() - { - VoterId = pc.PlayerId, - VotedForId = target.PlayerId - }); - states = [.. statesList]; - var exiled = target.Data; - var isBlackOut = AntiBlackout.BlackOutIsActive; - CheckForEndVotingPatch.TryAddAfterMeetingDeathPlayers(PlayerState.DeathReason.Suicide, pc.PlayerId); - ExileControllerWrapUpPatch.AntiBlackout_LastExiled = exiled; - Main.LastVotedPlayerInfo = exiled; - AntiBlackout.ExilePlayerId = exiled.PlayerId; - if (AntiBlackout.BlackOutIsActive) - { - if (isBlackOut) - MeetingHud.Instance.AntiBlackRpcVotingComplete(states, exiled, false); - else - MeetingHud.Instance.RpcVotingComplete(statesList.ToArray(), exiled, false); - if (exiled != null) - { - AntiBlackout.ShowExiledInfo = isBlackOut; - CheckForEndVotingPatch.ConfirmEjections(exiled, isBlackOut); - MeetingHud.Instance.RpcVotingComplete(statesList.ToArray(), null, true); - MeetingHud.Instance.RpcClose(); - } - } - else - { - MeetingHud.Instance.RpcVotingComplete(states, exiled, false); - - if (exiled != null) - { - CheckForEndVotingPatch.ConfirmEjections(exiled); - } - } - - Logger.Info($"{target.GetNameWithRole()} expelled by Dictator", "Dictator"); - - CheckForEndVotingPatch.CheckForDeathOnExile(PlayerState.DeathReason.Vote, target.PlayerId); - - Logger.Info("Dictatorial vote, forced closure of the meeting", "Special Phase"); - - target.SetRealKiller(pc); - - } - return true; - } - public override string PVANameText(PlayerVoteArea pva, PlayerControl seer, PlayerControl target) - => seer.IsAlive() && target.IsAlive() ? ColorString(GetRoleColor(CustomRoles.Dictator), target.PlayerId.ToString()) + " " + pva.NameText.text : ""; - public override string NotifyPlayerName(PlayerControl seer, PlayerControl target, string TargetPlayerName = "", bool IsForMeeting = false) - => IsForMeeting && ChangeCommandToExpel.GetBool() ? ColorString(GetRoleColor(CustomRoles.Dictator), target.PlayerId.ToString()) + " " + TargetPlayerName : ""; - - private void SendDictatorRPC(byte playerId) - { - MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.DictatorRPC, SendOption.Reliable, -1); - writer.Write(playerId); - AmongUsClient.Instance.FinishRpcImmediately(writer); } - public static void OnReceiveDictatorRPC(MessageReader reader, PlayerControl pc) + public override void Init() { - byte pid = reader.ReadByte(); - if (pc.Is(CustomRoles.Dictator) && pc.IsAlive() && GameStates.IsVoting) - { - if (pc.GetRoleClass() is Dictator dictator) - dictator.ExilePlayer(pc, $"/exp {pid}", true); - } + playerIdList.Clear(); } - - private void DictatorOnClick(byte playerId, MeetingHud __instance) + public override void Add(byte playerId) { - Logger.Msg($"Click: ID {playerId}", "Dictator UI"); - var pc = playerId.GetPlayer(); - if (pc == null || !pc.IsAlive() || !GameStates.IsVoting) return; - - if (AmongUsClient.Instance.AmHost) ExilePlayer(PlayerControl.LocalPlayer, $"/exp {playerId}"); - else SendDictatorRPC(playerId); - - CreateDictatorButton(__instance); + playerIdList.Add(playerId); } - [HarmonyPatch(typeof(MeetingHud), nameof(MeetingHud.Start))] - class StartMeetingPatch - { - public static void Postfix(MeetingHud __instance) - { - if (PlayerControl.LocalPlayer.GetRoleClass() is Dictator dictator) - if (ChangeCommandToExpel.GetBool()) - dictator.CreateDictatorButton(__instance); - } - } - - [HarmonyPatch(typeof(MeetingHud), nameof(MeetingHud.OnDestroy))] - class OnDestroyPatch - { - public static void Postfix(MeetingHud __instance) - { - foreach (var pva in __instance.playerStates) - { - if (pva.transform.Find("DictatorButton") != null) - UnityEngine.Object.Destroy(pva.transform.Find("DictatorButton").gameObject); - } - } - } - - private void CreateDictatorButton(MeetingHud __instance) - { - foreach (var pva in __instance.playerStates) - { - if (pva.transform.Find("DictatorButton") != null) UnityEngine.Object.Destroy(pva.transform.Find("DictatorButton").gameObject); - - var pc = pva.TargetPlayerId.GetPlayer(); - var local = PlayerControl.LocalPlayer; - if (pc == null || !pc.IsAlive()) continue; - - GameObject template = pva.Buttons.transform.Find("CancelButton").gameObject; - GameObject targetBox = UnityEngine.Object.Instantiate(template, pva.transform); - targetBox.name = "DictatorButton"; - targetBox.transform.localPosition = new Vector3(-0.35f, 0.03f, -1.31f); - SpriteRenderer renderer = targetBox.GetComponent(); - PassiveButton button = targetBox.GetComponent(); - renderer.sprite = CustomButton.Get("JudgeIcon"); - - button.OnClick.RemoveAllListeners(); - button.OnClick.AddListener((UnityEngine.Events.UnityAction)(() => - { - DictatorOnClick(pva.TargetPlayerId, __instance); - })); - } - } + public static bool CheckVotingForTarget(PlayerControl pc, PlayerVoteArea pva) + => pc.Is(CustomRoles.Dictator) && pva.DidVote && pc.PlayerId != pva.VotedFor && pva.VotedFor < 253 && !pc.Data.IsDead; } diff --git a/Roles/Crewmate/Doctor.cs b/Roles/Crewmate/Doctor.cs index 8bd75c5bc..260ededdc 100644 --- a/Roles/Crewmate/Doctor.cs +++ b/Roles/Crewmate/Doctor.cs @@ -1,14 +1,16 @@ using AmongUs.GameOptions; -using static TOHE.Options; using static TOHE.Translator; +using static TOHE.Options; namespace TOHE.Roles.Crewmate; internal class Doctor : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Doctor; private const int Id = 6700; + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Scientist; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateBasic; //==================================================================\\ @@ -25,6 +27,14 @@ public override void SetupCustomOption() VisibleToEveryoneOpt = BooleanOptionItem.Create(Id + 11, "DoctorVisibleToEveryone", false, TabGroup.CrewmateRoles, false) .SetParent(CustomRoleSpawnChances[CustomRoles.Doctor]); } + public override void Init() + { + playerIdList.Clear(); + } + public override void Add(byte playerId) + { + playerIdList.Add(playerId); + } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.ScientistCooldown = 0f; @@ -38,7 +48,6 @@ public override bool OnTaskComplete(PlayerControl player, int completedTaskCount public override bool OnRoleGuess(bool isUI, PlayerControl target, PlayerControl pc, CustomRoles role, ref bool guesserSuicide) { - if (role != CustomRoles.Doctor) return false; if (VisibleToEveryoneOpt.GetBool() && !target.GetCustomSubRoles().Any(sub => sub.IsBetrayalAddon())) { pc.ShowInfoMessage(isUI, GetString("GuessDoctor")); diff --git a/Roles/Crewmate/Enigma.cs b/Roles/Crewmate/Enigma.cs index 71604d57f..f1225c728 100644 --- a/Roles/Crewmate/Enigma.cs +++ b/Roles/Crewmate/Enigma.cs @@ -1,14 +1,16 @@ -using static TOHE.MeetingHudStartPatch; -using static TOHE.Options; +using static TOHE.Options; using static TOHE.Translator; +using static TOHE.MeetingHudStartPatch; namespace TOHE.Roles.Crewmate; internal class Enigma : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Enigma; private const int Id = 8100; + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateSupport; //==================================================================\\ @@ -71,16 +73,19 @@ public override void SetupCustomOption() } public override void Init() { + playerIdList.Clear(); ShownClues.Clear(); MsgToSend.Clear(); MsgToSendTitle.Clear(); } public override void Add(byte playerId) { + playerIdList.Add(playerId); ShownClues.Add(playerId, []); } public override void Remove(byte playerId) { + playerIdList.Remove(playerId); ShownClues.Remove(playerId); } @@ -95,13 +100,12 @@ public override void OnReportDeadBody(PlayerControl player, NetworkedPlayerInfo string msg; var rd = IRandom.Instance; - if (_Player) + foreach (var playerId in playerIdList.ToArray()) { - var playerId = _Player.PlayerId; - if (!EnigmaGetCluesWithoutReporting.GetBool() && playerId != player.PlayerId) return; + if (!EnigmaGetCluesWithoutReporting.GetBool() && playerId != player.PlayerId) continue; var enigmaPlayer = Utils.GetPlayerById(playerId); - if (enigmaPlayer == null) return; + if (enigmaPlayer == null) continue; int tasksCompleted = enigmaPlayer.GetPlayerTaskState().CompletedTasksCount; int stage = 0; @@ -120,12 +124,10 @@ public override void OnReportDeadBody(PlayerControl player, NetworkedPlayerInfo else if (tasksCompleted >= EnigmaClueStage1Tasks.GetInt()) stage = 1; - Logger.Info($"Enigma clue {playerId} is {stage} with taskcount {tasksCompleted}", "Enigma"); - var clues = EnigmaClues.Where(a => a.ClueStage <= stage && !ShownClues[playerId].Any(b => b.EnigmaClueType == a.EnigmaClueType && b.ClueStage == a.ClueStage)) .ToList(); - if (clues.Count == 0) return; + if (clues.Count == 0) continue; if (showStageClue && clues.Any(a => a.ClueStage == stage)) clues = clues.Where(a => a.ClueStage == stage).ToList(); @@ -516,7 +518,6 @@ public override string GetMessage(PlayerControl killer, bool showStageClue) } } - [Obfuscation(Exclude = true)] private enum EnigmaClueType { HatClue, diff --git a/Roles/Crewmate/FortuneTeller.cs b/Roles/Crewmate/FortuneTeller.cs index 2b3904f2a..b1c4c1e3e 100644 --- a/Roles/Crewmate/FortuneTeller.cs +++ b/Roles/Crewmate/FortuneTeller.cs @@ -13,7 +13,6 @@ namespace TOHE.Roles.Crewmate; internal class FortuneTeller : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.FortuneTeller; private const int Id = 8000; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.FortuneTeller); public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; diff --git a/Roles/Crewmate/Grenadier.cs b/Roles/Crewmate/Grenadier.cs index 29c3d26a4..ba9acdf68 100644 --- a/Roles/Crewmate/Grenadier.cs +++ b/Roles/Crewmate/Grenadier.cs @@ -1,24 +1,22 @@ using AmongUs.GameOptions; using System; using System.Text; -using TOHE.Modules; -using TOHE.Roles.Core; using UnityEngine; +using TOHE.Modules; +using static TOHE.Utils; using static TOHE.Options; using static TOHE.Translator; -using static TOHE.Utils; +using TOHE.Roles.Core; namespace TOHE.Roles.Crewmate; internal class Grenadier : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Grenadier; private const int Id = 8200; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Grenadier); public override CustomRoles ThisRoleBase => CustomRoles.Engineer; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateSupport; - public override bool BlockMoveInVent(PlayerControl pc) => true; //==================================================================\\ private static readonly Dictionary GrenadierBlinding = []; @@ -31,7 +29,7 @@ internal class Grenadier : RoleBase private static OptionItem GrenadierSkillMaxOfUseage; private static OptionItem GrenadierAbilityUseGainWithEachTaskCompleted; - public override void SetupCustomOption() + public override void SetupCustomOption() { SetupRoleOptions(Id, TabGroup.CrewmateRoles, CustomRoles.Grenadier); GrenadierSkillCooldown = FloatOptionItem.Create(Id + 10, "GrenadierSkillCooldown", new(1f, 180f, 1f), 25f, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Grenadier]) @@ -80,7 +78,7 @@ public static void ApplyGameOptionsForOthers(IGameOptions opt, PlayerControl pla public override bool OnTaskComplete(PlayerControl player, int completedTaskCount, int totalTaskCount) { if (player.IsAlive()) - { + { AbilityLimit += GrenadierAbilityUseGainWithEachTaskCompleted.GetFloat(); SendSkillRPC(); } diff --git a/Roles/Crewmate/Guardian.cs b/Roles/Crewmate/Guardian.cs index a13e07682..6852aaadd 100644 --- a/Roles/Crewmate/Guardian.cs +++ b/Roles/Crewmate/Guardian.cs @@ -6,8 +6,10 @@ namespace TOHE.Roles.Crewmate; internal class Guardian : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Guardian; private const int Id = 11700; + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmatePower; //==================================================================\\ @@ -17,18 +19,21 @@ public override void SetupCustomOption() SetupRoleOptions(Id, TabGroup.CrewmateRoles, CustomRoles.Guardian); OverrideTasksData.Create(Id + 10, TabGroup.CrewmateRoles, CustomRoles.Guardian); } + + public override void Init() + { + playerIdList.Clear(); + } + + public override void Add(byte playerId) + { + playerIdList.Add(playerId); + } public static bool CannotBeKilled(PlayerControl Guardian) => Guardian.Is(CustomRoles.Guardian) && Guardian.GetPlayerTaskState().IsTaskFinished; public override bool OnCheckMurderAsTarget(PlayerControl killer, PlayerControl target) { if (CannotBeKilled(target)) - { - killer.SetKillCooldown(5f, target, forceAnime: true); - killer.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Guardian), GetString("GuardianCantKilled"))); - - killer.ResetKillCooldown(); - killer.SyncSettings(); return false; - } return true; } diff --git a/Roles/Crewmate/GuessMaster.cs b/Roles/Crewmate/GuessMaster.cs index 9dc7438e3..e93ccaaea 100644 --- a/Roles/Crewmate/GuessMaster.cs +++ b/Roles/Crewmate/GuessMaster.cs @@ -5,11 +5,10 @@ namespace TOHE.Roles.Crewmate; internal class GuessMaster : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.GuessMaster; private const int Id = 26800; private static readonly HashSet playerIdList = []; public static bool HasEnabled => playerIdList.Any(); - + public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateBasic; //==================================================================\\ @@ -25,8 +24,7 @@ public override void Init() } public override void Add(byte playerId) { - if (!playerIdList.Contains(playerId)) - playerIdList.Add(playerId); + playerIdList.Add(playerId); } public override void Remove(byte playerId) { @@ -57,4 +55,4 @@ public static void OnGuess(CustomRoles role, bool isMisguess = false, PlayerCont } } } -} +} \ No newline at end of file diff --git a/Roles/Crewmate/Inspector.cs b/Roles/Crewmate/Inspector.cs index f4a14b10b..6094cf138 100644 --- a/Roles/Crewmate/Inspector.cs +++ b/Roles/Crewmate/Inspector.cs @@ -13,10 +13,9 @@ namespace TOHE.Roles.Crewmate; internal class Inspector : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Inspector; private const int Id = 8300; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Inspector); - + public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateSupport; //==================================================================\\ @@ -214,7 +213,7 @@ public static bool InspectCheckMsg(PlayerControl pc, string msg, bool isUI = fal } else { - if + if ( ( (target1.GetCustomRole().IsImpostorTeamV2() || target1.IsAnySubRole(role => role.IsImpostorTeamV2())) && !target1.Is(CustomRoles.Admired) @@ -426,7 +425,7 @@ public override string GetProgressText(byte playerId, bool comms) public override string PVANameText(PlayerVoteArea pva, PlayerControl seer, PlayerControl target) => ColorString(GetRoleColor(CustomRoles.Inspector), target.PlayerId.ToString()) + " " + pva.NameText.text; - + public override string NotifyPlayerName(PlayerControl seer, PlayerControl target, string TargetPlayerName = "", bool IsForMeeting = false) => IsForMeeting ? ColorString(GetRoleColor(CustomRoles.Inspector), target.PlayerId.ToString()) + " " + TargetPlayerName : string.Empty; -} +} \ No newline at end of file diff --git a/Roles/Crewmate/Investigator.cs b/Roles/Crewmate/Investigator.cs index 8c365beb0..a2845fe44 100644 --- a/Roles/Crewmate/Investigator.cs +++ b/Roles/Crewmate/Investigator.cs @@ -8,8 +8,9 @@ namespace TOHE.Roles.Crewmate; internal class Investigator : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Investigator; private const int Id = 24900; + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); public override bool IsDesyncRole => true; public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateSupport; @@ -36,18 +37,21 @@ public override void SetupCustomOption() public override void Init() { + playerIdList.Clear(); InvestigatedList.Clear(); MaxInvestigateLimit.Clear(); RoundInvestigateLimit.Clear(); } public override void Add(byte playerId) { + playerIdList.Add(playerId); MaxInvestigateLimit[playerId] = InvestigateMax.GetInt(); RoundInvestigateLimit[playerId] = InvestigateRoundMax.GetInt(); InvestigatedList[playerId] = []; } public override void Remove(byte playerId) { + playerIdList.Remove(playerId); MaxInvestigateLimit.Remove(playerId); RoundInvestigateLimit.Remove(playerId); InvestigatedList.Remove(playerId); @@ -156,4 +160,4 @@ public override void SetAbilityButtonText(HudManager hud, byte playerId) { hud.KillButton.OverrideText(Translator.GetString("InvestigatorButtonText")); ; } -} +} \ No newline at end of file diff --git a/Roles/Crewmate/Jailer.cs b/Roles/Crewmate/Jailer.cs index 952faebd5..09c9f9e7a 100644 --- a/Roles/Crewmate/Jailer.cs +++ b/Roles/Crewmate/Jailer.cs @@ -9,8 +9,9 @@ namespace TOHE.Roles.Crewmate; internal class Jailer : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Jailer; private const int Id = 10600; + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); public override bool IsDesyncRole => true; public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateKilling; @@ -49,6 +50,7 @@ public override void SetupCustomOption() public override void Init() { + playerIdList.Clear(); JailerExeLimit.Clear(); JailerTarget.Clear(); JailerHasExe.Clear(); @@ -56,6 +58,7 @@ public override void Init() } public override void Add(byte playerId) { + playerIdList.Add(playerId); JailerExeLimit.Add(playerId, MaxExecution.GetInt()); JailerTarget[playerId] = byte.MaxValue; JailerHasExe.Add(playerId, false); @@ -63,6 +66,7 @@ public override void Add(byte playerId) } public override void Remove(byte playerId) { + playerIdList.Remove(playerId); JailerExeLimit.Remove(playerId); JailerHasExe.Remove(playerId); JailerDidVote.Remove(playerId); @@ -218,4 +222,4 @@ public override void SetAbilityButtonText(HudManager hud, byte id) hud.KillButton.OverrideText(GetString("JailorKillButtonText")); } public override Sprite GetKillButtonSprite(PlayerControl player, bool shapeshifting) => CustomButton.Get("penitentiary"); -} +} \ No newline at end of file diff --git a/Roles/Crewmate/Judge.cs b/Roles/Crewmate/Judge.cs index f9ebbb0f4..39ec8fc33 100644 --- a/Roles/Crewmate/Judge.cs +++ b/Roles/Crewmate/Judge.cs @@ -1,21 +1,23 @@ using Hazel; using System; -using System.Text; using System.Text.RegularExpressions; using TOHE.Modules.ChatManager; -using TOHE.Roles.Core; using TOHE.Roles.Double; using UnityEngine; -using static TOHE.Translator; using static TOHE.Utils; +using static TOHE.Translator; +using TOHE.Roles.Core; +using System.Text; namespace TOHE.Roles.Crewmate; internal class Judge : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Judge; private const int Id = 10700; + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateKilling; //==================================================================\\ @@ -60,15 +62,18 @@ public override void SetupCustomOption() } public override void Init() { + playerIdList.Clear(); TrialLimitMeeting.Clear(); } public override void Add(byte playerId) { + playerIdList.Add(playerId); TrialLimitMeeting[playerId] = TrialLimitPerMeeting.GetInt(); AbilityLimit = TrialLimitPerGame.GetInt(); } public override void Remove(byte playerId) { + playerIdList.Remove(playerId); TrialLimitMeeting.Remove(playerId); } public override void OnReportDeadBody(PlayerControl party, NetworkedPlayerInfo dinosaur) @@ -106,7 +111,7 @@ public bool TrialMsg(PlayerControl pc, string msg, bool isUI = false) else if (operate == 2) { - if (TryHideMsg.GetBool()) + if (TryHideMsg.GetBool()) { //if (Options.NewHideMsg.GetBool()) ChatManager.SendPreviousMessagesToAll(); //else GuessManager.TryHideMsg(); diff --git a/Roles/Crewmate/Keeper.cs b/Roles/Crewmate/Keeper.cs index ebaf4c75f..e3fcd6b65 100644 --- a/Roles/Crewmate/Keeper.cs +++ b/Roles/Crewmate/Keeper.cs @@ -1,19 +1,20 @@ using Hazel; using System; using System.Text; -using TOHE.Roles.Core; using UnityEngine; -using static TOHE.Options; +using TOHE.Roles.Core; using static TOHE.Translator; +using static TOHE.Options; namespace TOHE.Roles.Crewmate; internal class Keeper : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Keeper; private const int Id = 26500; - + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateSupport; //==================================================================\\ @@ -29,10 +30,11 @@ public override void SetupCustomOption() SetupRoleOptions(Id, TabGroup.CrewmateRoles, CustomRoles.Keeper); KeeperUsesOpt = IntegerOptionItem.Create(Id + 10, "MaxProtections", new(1, 14, 1), 3, TabGroup.CrewmateRoles, false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Keeper]) .SetValueFormat(OptionFormat.Times); - + } public override void Init() { + playerIdList.Clear(); keeperTarget.Clear(); keeperUses.Clear(); DidVote.Clear(); @@ -40,11 +42,13 @@ public override void Init() public override void Add(byte playerId) { + playerIdList.Add(playerId); DidVote.Add(playerId, false); keeperUses[playerId] = 0; } public override void Remove(byte playerId) { + playerIdList.Remove(playerId); DidVote.Remove(playerId); keeperUses.Remove(playerId); } @@ -91,7 +95,7 @@ public static void ReceiveRPC(MessageReader reader) { byte keeperId = reader.ReadByte(); DidVote[keeperId] = true; - + int uses = reader.ReadInt32(); keeperUses[keeperId] = uses; @@ -139,4 +143,4 @@ public override void AfterMeetingTasks() } public static bool IsTargetExiled(byte exileId) => keeperTarget.Contains(exileId); -} +} \ No newline at end of file diff --git a/Roles/Crewmate/Knight.cs b/Roles/Crewmate/Knight.cs index 9ddafe62e..b9f572665 100644 --- a/Roles/Crewmate/Knight.cs +++ b/Roles/Crewmate/Knight.cs @@ -7,7 +7,6 @@ namespace TOHE.Roles.Crewmate; internal class Knight : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Knight; private const int Id = 10800; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Knight); public override bool IsDesyncRole => true; @@ -40,12 +39,12 @@ public override bool CanUseKillButton(PlayerControl pc) public override string GetProgressText(byte id, bool comms) => Utils.ColorString(!IsKilled(id) ? Utils.GetRoleColor(CustomRoles.Knight).ShadeColor(0.25f) : Color.gray, $"({AbilityLimit})"); - + private bool IsKilled(byte playerId) => AbilityLimit <= 0; public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl banana) { AbilityLimit--; - SendSkillRPC(); + SendSkillRPC(); Logger.Info($"{killer.GetNameWithRole()} : " + "Kill chance used", "Knight"); killer.ResetKillCooldown(); killer.SetKillCooldown(); diff --git a/Roles/Crewmate/LazyGuy.cs b/Roles/Crewmate/LazyGuy.cs index 926036eba..5d2bdc8e8 100644 --- a/Roles/Crewmate/LazyGuy.cs +++ b/Roles/Crewmate/LazyGuy.cs @@ -5,8 +5,10 @@ namespace TOHE.Roles.Crewmate; internal class LazyGuy : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.LazyGuy; private const int Id = 6800; + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateBasic; //==================================================================\\ @@ -15,4 +17,12 @@ public override void SetupCustomOption() { SetupRoleOptions(Id, TabGroup.CrewmateRoles, CustomRoles.LazyGuy); } + public override void Init() + { + playerIdList.Clear(); + } + public override void Add(byte playerId) + { + playerIdList.Add(playerId); + } } diff --git a/Roles/Crewmate/Lighter.cs b/Roles/Crewmate/Lighter.cs index 3db459811..9ec118a32 100644 --- a/Roles/Crewmate/Lighter.cs +++ b/Roles/Crewmate/Lighter.cs @@ -2,19 +2,20 @@ using System; using System.Text; using UnityEngine; -using static TOHE.Translator; using static TOHE.Utils; +using static TOHE.Translator; namespace TOHE.Roles.Crewmate; internal class Lighter : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Lighter; private const int Id = 8400; + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Engineer; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateSupport; - public override bool BlockMoveInVent(PlayerControl pc) => true; //==================================================================\\ private static OptionItem LighterVisionNormal; @@ -24,7 +25,8 @@ internal class Lighter : RoleBase private static OptionItem LighterSkillMaxOfUseage; private static OptionItem LighterAbilityUseGainWithEachTaskCompleted; - private long Timer; + private static readonly Dictionary Timer = []; + private static readonly Dictionary LighterNumOfUsed = []; public override void SetupCustomOption() { @@ -35,7 +37,7 @@ public override void SetupCustomOption() .SetValueFormat(OptionFormat.Seconds); LighterVisionNormal = FloatOptionItem.Create(Id + 12, "LighterVisionNormal", new(0f, 5f, 0.05f), 1.35f, TabGroup.CrewmateRoles, false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Lighter]) .SetValueFormat(OptionFormat.Multiplier); - LighterVisionOnLightsOut = FloatOptionItem.Create(Id + 13, "LighterVisionOnLightsOut", new(0f, 5f, 0.05f), 0.5f, TabGroup.CrewmateRoles, false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Lighter]) + LighterVisionOnLightsOut = FloatOptionItem.Create(Id +13, "LighterVisionOnLightsOut", new(0f, 5f, 0.05f), 0.5f, TabGroup.CrewmateRoles, false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Lighter]) .SetValueFormat(OptionFormat.Multiplier); LighterSkillMaxOfUseage = IntegerOptionItem.Create(Id + 14, "AbilityUseLimit", new(0, 180, 1), 4, TabGroup.CrewmateRoles, false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Lighter]) .SetValueFormat(OptionFormat.Times); @@ -44,22 +46,25 @@ public override void SetupCustomOption() } public override void Init() { - Timer = 0; + playerIdList.Clear(); + Timer.Clear(); + LighterNumOfUsed.Clear(); } public override void Add(byte playerId) { - Timer = 0; - AbilityLimit = LighterSkillMaxOfUseage.GetInt(); + playerIdList.Add(playerId); + LighterNumOfUsed.Add(playerId, LighterSkillMaxOfUseage.GetInt()); } public override void Remove(byte playerId) { - Timer = 0; + playerIdList.Remove(playerId); + LighterNumOfUsed.Remove(playerId); } public override void OnFixedUpdate(PlayerControl player, bool lowLoad, long nowTime) { - if (!lowLoad && Timer != 0 && Timer + LighterSkillDuration.GetInt() < nowTime) + if (!lowLoad && Timer.TryGetValue(player.PlayerId, out var ltime) && ltime + LighterSkillDuration.GetInt() < nowTime) { - Timer = 0; + Timer.Remove(player.PlayerId); if (!Options.DisableShieldAnimations.GetBool()) { player.RpcGuardAndKill(); @@ -68,28 +73,27 @@ public override void OnFixedUpdate(PlayerControl player, bool lowLoad, long nowT { player.RpcResetAbilityCooldown(); } - player.Notify(string.Format(GetString("AbilityExpired"), Math.Round(AbilityLimit, 1))); + player.Notify(GetString("AbilityExpired")); player.MarkDirtySettings(); } } public override void OnEnterVent(PlayerControl pc, Vent vent) { - if (AbilityLimit >= 1) + if (LighterNumOfUsed[pc.PlayerId] >= 1) { - Timer = GetTimeStamp(); + Timer.Remove(pc.PlayerId); + Timer.Add(pc.PlayerId, GetTimeStamp()); if (!Options.DisableShieldAnimations.GetBool()) pc.RpcGuardAndKill(pc); pc.Notify(GetString("AbilityInUse"), LighterSkillDuration.GetFloat()); - AbilityLimit--; + LighterNumOfUsed[pc.PlayerId] -= 1; pc.MarkDirtySettings(); } else { pc.Notify(GetString("OutOfAbilityUsesDoMoreTasks")); } - - SendSkillRPC(); } - public override void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo target) => Timer = 0; + public override void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo target) => Timer.Clear(); public override string GetProgressText(byte playerId, bool comms) { var ProgressText = new StringBuilder(); @@ -101,16 +105,16 @@ public override string GetProgressText(byte playerId, bool comms) TextColor14 = comms ? Color.gray : NormalColor14; string Completed14 = comms ? "?" : $"{taskState14.CompletedTasksCount}"; Color TextColor141; - if (AbilityLimit < 1) TextColor141 = Color.red; + if (LighterNumOfUsed[playerId] < 1) TextColor141 = Color.red; else TextColor141 = Color.white; ProgressText.Append(ColorString(TextColor14, $"({Completed14}/{taskState14.AllTasksCount})")); - ProgressText.Append(ColorString(TextColor141, $" - {Math.Round(AbilityLimit, 1)}")); + ProgressText.Append(ColorString(TextColor141, $" - {Math.Round(LighterNumOfUsed[playerId], 1)}")); return ProgressText.ToString(); } public override bool OnTaskComplete(PlayerControl player, int completedTaskCount, int totalTaskCount) { if (player.IsAlive()) - AbilityLimit += LighterAbilityUseGainWithEachTaskCompleted.GetFloat(); + LighterNumOfUsed[player.PlayerId] += LighterAbilityUseGainWithEachTaskCompleted.GetFloat(); return true; } @@ -119,7 +123,7 @@ public override void ApplyGameOptions(IGameOptions opt, byte playerId) AURoleOptions.EngineerInVentMaxTime = 1; AURoleOptions.EngineerCooldown = LighterSkillCooldown.GetFloat(); - if (Timer != 0) + if (Timer.Any()) { opt.SetVision(false); if (IsActive(SystemTypes.Electrical)) opt.SetFloat(FloatOptionNames.CrewLightMod, LighterVisionOnLightsOut.GetFloat() * 5); diff --git a/Roles/Crewmate/Lookout.cs b/Roles/Crewmate/Lookout.cs index 096d67660..d8a052f9a 100644 --- a/Roles/Crewmate/Lookout.cs +++ b/Roles/Crewmate/Lookout.cs @@ -6,8 +6,10 @@ namespace TOHE.Roles.Crewmate; internal class Lookout : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Lookout; private const int Id = 11800; + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmatePower; //==================================================================\\ @@ -16,6 +18,15 @@ public override void SetupCustomOption() { SetupRoleOptions(Id, TabGroup.CrewmateRoles, CustomRoles.Lookout); } + + public override void Init() + { + playerIdList.Clear(); + } + public override void Add(byte playerId) + { + playerIdList.Add(playerId); + } public override string GetMark(PlayerControl seer, PlayerControl seen, bool isForMeeting = false) { diff --git a/Roles/Crewmate/Marshall.cs b/Roles/Crewmate/Marshall.cs index 958a2a79e..81b60362a 100644 --- a/Roles/Crewmate/Marshall.cs +++ b/Roles/Crewmate/Marshall.cs @@ -1,5 +1,5 @@ -using TOHE.Roles.Core; using UnityEngine; +using TOHE.Roles.Core; using static TOHE.Options; using static TOHE.Translator; @@ -8,8 +8,10 @@ namespace TOHE.Roles.Crewmate; internal class Marshall : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Marshall; private const int Id = 11900; + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmatePower; //==================================================================\\ @@ -21,6 +23,14 @@ public override void SetupCustomOption() SetupRoleOptions(Id, TabGroup.CrewmateRoles, CustomRoles.Marshall); OverrideTasksData.Create(Id + 10, TabGroup.CrewmateRoles, CustomRoles.Marshall); } + public override void Init() + { + playerIdList.Clear(); + } + public override void Add(byte playerId) + { + playerIdList.Add(playerId); + } private static bool GetExpose(PlayerControl pc) { if (!pc.IsAlive() || pc.Is(CustomRoles.Madmate)) return false; @@ -38,10 +48,9 @@ public override string GetMark(PlayerControl seer, PlayerControl target = null, private static bool VisibleToCrewmate(PlayerControl seer, PlayerControl target) => target.GetPlayerTaskState().IsTaskFinished && target.Is(CustomRoles.Marshall) && seer.Is(Custom_Team.Crewmate); public override bool KnowRoleTarget(PlayerControl seer, PlayerControl target) => VisibleToCrewmate(seer, target); public override bool OthersKnowTargetRoleColor(PlayerControl seer, PlayerControl target) => VisibleToCrewmate(seer, target); - + public override bool OnRoleGuess(bool isUI, PlayerControl target, PlayerControl pc, CustomRoles role, ref bool guesserSuicide) { - if (role != CustomRoles.Marshall) return false; if (target.GetPlayerTaskState().IsTaskFinished) { pc.ShowInfoMessage(isUI, GetString("GuessMarshallTask")); diff --git a/Roles/Crewmate/Mayor.cs b/Roles/Crewmate/Mayor.cs index 67172298f..1f62366e7 100644 --- a/Roles/Crewmate/Mayor.cs +++ b/Roles/Crewmate/Mayor.cs @@ -8,11 +8,12 @@ namespace TOHE.Roles.Crewmate; internal partial class Mayor : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Mayor; private const int Id = 12000; + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); + public override CustomRoles ThisRoleBase => MayorHasPortableButton.GetBool() ? CustomRoles.Engineer : CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmatePower; - public override bool BlockMoveInVent(PlayerControl pc) => true; //==================================================================\\ public override Sprite GetAbilityButtonSprite(PlayerControl player, bool shapeshifting) => CustomButton.Get("Collective"); @@ -45,14 +46,17 @@ public override void SetupCustomOption() public override void Init() { + playerIdList.Clear(); MayorUsedButtonCount.Clear(); } public override void Add(byte playerId) { + playerIdList.Add(playerId); MayorUsedButtonCount[playerId] = 0; } public override void Remove(byte playerId) { + playerIdList.Remove(playerId); MayorUsedButtonCount[playerId] = 0; } @@ -103,7 +107,6 @@ public override bool CheckBootFromVent(PlayerPhysics physics, int ventId) public override bool OnRoleGuess(bool isUI, PlayerControl target, PlayerControl guesser, CustomRoles role, ref bool guesserSuicide) { - if (role != CustomRoles.Mayor) return false; if (MayorRevealWhenDoneTasks.GetBool() && target.GetPlayerTaskState().IsTaskFinished) { guesser.ShowInfoMessage(isUI, GetString("GuessMayor")); @@ -115,7 +118,7 @@ public override bool OnRoleGuess(bool isUI, PlayerControl target, PlayerControl public static bool VisibleToEveryone(PlayerControl target) => target.Is(CustomRoles.Mayor) && MayorRevealWhenDoneTasks.GetBool() && target.GetPlayerTaskState().IsTaskFinished; public override bool KnowRoleTarget(PlayerControl seer, PlayerControl target) => VisibleToEveryone(target); public override bool OthersKnowTargetRoleColor(PlayerControl seer, PlayerControl target) => VisibleToEveryone(target); - + public override void SetAbilityButtonText(HudManager hud, byte id) { hud.AbilityButton.buttonLabelText.text = GetString("MayorVentButtonText"); diff --git a/Roles/Crewmate/Mechanic.cs b/Roles/Crewmate/Mechanic.cs index 0f99a7856..31cba853f 100644 --- a/Roles/Crewmate/Mechanic.cs +++ b/Roles/Crewmate/Mechanic.cs @@ -1,16 +1,15 @@ -using AmongUs.GameOptions; using System; using System.Text; -using TOHE.Roles.Core; using UnityEngine; +using AmongUs.GameOptions; using static TOHE.Utils; +using TOHE.Roles.Core; namespace TOHE.Roles.Crewmate; internal class Mechanic : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Mechanic; private const int Id = 8500; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Mechanic); public override CustomRoles ThisRoleBase => CustomRoles.Engineer; @@ -137,7 +136,7 @@ public override void SwitchSystemUpdate(SwitchSystem __instance, byte amount, Pl if (!FixesElectrical.GetBool()) return; //var playerId = player.PlayerId; - + if (SkillLimit.GetFloat() > 0 && AbilityLimit + UsesUsedWhenFixingLightsOrComms.GetFloat() - 1 <= 0) return; @@ -181,4 +180,4 @@ public override void ApplyGameOptions(IGameOptions opt, byte playerId) AURoleOptions.EngineerCooldown = 1f; AURoleOptions.EngineerInVentMaxTime = 0f; } -} +} \ No newline at end of file diff --git a/Roles/Crewmate/Medic.cs b/Roles/Crewmate/Medic.cs index 9fe0ec7ec..5e2a6b15d 100644 --- a/Roles/Crewmate/Medic.cs +++ b/Roles/Crewmate/Medic.cs @@ -1,11 +1,11 @@ using AmongUs.GameOptions; using Hazel; using InnerNet; +using UnityEngine; using TOHE.Modules; using TOHE.Roles.Core; -using UnityEngine; -using static TOHE.Translator; using static TOHE.Utils; +using static TOHE.Translator; namespace TOHE.Roles.Crewmate; @@ -13,7 +13,6 @@ namespace TOHE.Roles.Crewmate; internal class Medic : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Medic; private const int Id = 8600; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Medic); public override bool IsDesyncRole => true; @@ -34,7 +33,6 @@ internal class Medic : RoleBase private readonly HashSet ProtectedList = []; private readonly HashSet TempMarkProtected = []; - [Obfuscation(Exclude = true)] private enum SelectOptionsList { Medic_SeeMedicAndTarget, @@ -42,7 +40,7 @@ private enum SelectOptionsList Medic_SeeTarget, Medic_SeeNoOne } - [Obfuscation(Exclude = true)] + private enum ShieldDeactivationIsVisibleList { MedicShieldDeactivationIsVisible_Immediately, diff --git a/Roles/Crewmate/Medium.cs b/Roles/Crewmate/Medium.cs index 52b8a3af4..20180d64f 100644 --- a/Roles/Crewmate/Medium.cs +++ b/Roles/Crewmate/Medium.cs @@ -1,19 +1,18 @@ using Hazel; -using InnerNet; using System; using System.Text; using TOHE.Roles.Core; using UnityEngine; -using static TOHE.MeetingHudStartPatch; -using static TOHE.Translator; using static TOHE.Utils; +using static TOHE.Translator; +using static TOHE.MeetingHudStartPatch; +using InnerNet; namespace TOHE.Roles.Crewmate; internal class Medium : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Medium; private const int Id = 8700; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Medium); public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; @@ -168,4 +167,4 @@ public override void OnOthersMeetingHudStart(PlayerControl pc) if (ContactPlayer.ContainsKey(pc.PlayerId) && (!OnlyReceiveMsgFromCrew.GetBool() || pc.GetCustomRole().IsCrewmate())) AddMsg(string.Format(GetString("MediumNotifyTarget"), Main.AllPlayerNames[ContactPlayer[pc.PlayerId]]), pc.PlayerId, ColorString(GetRoleColor(CustomRoles.Medium), GetString("MediumTitle"))); } -} +} \ No newline at end of file diff --git a/Roles/Crewmate/Merchant.cs b/Roles/Crewmate/Merchant.cs index 9e6085329..4d7a7e311 100644 --- a/Roles/Crewmate/Merchant.cs +++ b/Roles/Crewmate/Merchant.cs @@ -7,8 +7,10 @@ namespace TOHE.Roles.Crewmate; internal class Merchant : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Merchant; private const int Id = 8800; + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateSupport; //==================================================================\\ @@ -51,12 +53,14 @@ public override void SetupCustomOption() OptionCanSellNeutral = BooleanOptionItem.Create(Id + 11, "MerchantSellMixed", true, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Merchant]); OptionSellOnlyHarmfulToEvil = BooleanOptionItem.Create(Id + 13, "MerchantSellHarmfulToEvil", false, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Merchant]); OptionSellOnlyHelpfulToCrew = BooleanOptionItem.Create(Id + 14, "MerchantSellHelpfulToCrew", false, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Merchant]); - OptionSellOnlyEnabledAddons = BooleanOptionItem.Create(Id + 15, "MerchantSellOnlyEnabledAddons", false, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Merchant]); + OptionSellOnlyEnabledAddons = BooleanOptionItem.Create(Id + 15, "MerchantSellOnlyEnabledAddons",false, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Merchant]); OverrideTasksData.Create(Id + 16, TabGroup.CrewmateRoles, CustomRoles.Merchant); } public override void Init() { + playerIdList.Clear(); + addons.Clear(); addonsSold.Clear(); bribedKiller.Clear(); @@ -76,18 +80,20 @@ public override void Init() addons.AddRange(GroupedAddons[AddonTypes.Mixed]); } if (OptionSellOnlyEnabledAddons.GetBool()) - { + { addons = addons.Where(role => role.GetMode() != 0).ToList(); } } public override void Add(byte playerId) { + playerIdList.Add(playerId); addonsSold[playerId] = 0; bribedKiller.TryAdd(playerId, []); } public override void Remove(byte playerId) { + playerIdList.Remove(playerId); addonsSold.Remove(playerId); bribedKiller.Remove(playerId); } @@ -127,7 +133,7 @@ public override bool OnTaskComplete(PlayerControl player, int completedTaskCount (!Cleanser.CantGetAddon() || (Cleanser.CantGetAddon() && !x.Is(CustomRoles.Cleansed))) && ( - (OptionCanTargetCrew.GetBool() && x.GetCustomRole().IsCrewmate()) + (OptionCanTargetCrew.GetBool() && x.GetCustomRole().IsCrewmate()) || (OptionCanTargetImpostor.GetBool() && x.GetCustomRole().IsImpostor()) || @@ -151,7 +157,7 @@ public override bool OnTaskComplete(PlayerControl player, int completedTaskCount a.GetCustomRole().IsImpostor() || a.GetCustomRole().IsNeutral() - + ).ToList(); } @@ -162,7 +168,7 @@ public override bool OnTaskComplete(PlayerControl player, int completedTaskCount player.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Merchant), GetString("MerchantAddonDelivered"))); target.AddInSwitchAddons(target, addon); - + addonsSold[player.PlayerId] += 1; } else @@ -176,7 +182,6 @@ public override bool OnTaskComplete(PlayerControl player, int completedTaskCount } public override bool OnRoleGuess(bool isUI, PlayerControl target, PlayerControl pc, CustomRoles role, ref bool guesserSuicide) { - if (role != CustomRoles.Merchant) return false; if (IsBribedKiller(pc, target)) { pc.ShowInfoMessage(isUI, GetString("BribedByMerchant2")); diff --git a/Roles/Crewmate/Mole.cs b/Roles/Crewmate/Mole.cs index 1c3d37921..5945aeaaa 100644 --- a/Roles/Crewmate/Mole.cs +++ b/Roles/Crewmate/Mole.cs @@ -8,11 +8,12 @@ namespace TOHE.Roles.Crewmate; internal class Mole : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Mole; private const int Id = 26000; + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Engineer; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateBasic; - public override bool BlockMoveInVent(PlayerControl pc) => true; //==================================================================\\ private static OptionItem VentCooldown; @@ -23,6 +24,14 @@ public override void SetupCustomOption() VentCooldown = FloatOptionItem.Create(Id + 11, "MoleVentCooldown", new(5f, 180f, 1f), 20f, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Mole]) .SetValueFormat(OptionFormat.Seconds); } + public override void Init() + { + playerIdList.Clear(); + } + public override void Add(byte playerId) + { + playerIdList.Add(playerId); + } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.EngineerCooldown = VentCooldown.GetFloat(); diff --git a/Roles/Crewmate/Monarch.cs b/Roles/Crewmate/Monarch.cs index 6c35a063c..4bc0d8e98 100644 --- a/Roles/Crewmate/Monarch.cs +++ b/Roles/Crewmate/Monarch.cs @@ -10,7 +10,6 @@ namespace TOHE.Roles.Crewmate; internal class Monarch : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Monarch; private const int Id = 12100; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Monarch); public override bool IsDesyncRole => true; @@ -120,4 +119,4 @@ public override void SetAbilityButtonText(HudManager hud, byte playerId) { hud.KillButton.OverrideText(GetString("MonarchKillButtonText")); } -} +} \ No newline at end of file diff --git a/Roles/Crewmate/Mortician.cs b/Roles/Crewmate/Mortician.cs index fa7cad5a0..0f4cfa26d 100644 --- a/Roles/Crewmate/Mortician.cs +++ b/Roles/Crewmate/Mortician.cs @@ -1,15 +1,17 @@ using TOHE.Roles.Core; using UnityEngine; -using static TOHE.MeetingHudStartPatch; using static TOHE.Options; +using static TOHE.MeetingHudStartPatch; using static TOHE.Translator; namespace TOHE.Roles.Crewmate; internal class Mortician : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Mortician; private const int Id = 8900; + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateSupport; //==================================================================\\ @@ -25,31 +27,38 @@ public override void SetupCustomOption() } public override void Init() { + playerIdList.Clear(); msgToSend.Clear(); } public override void Add(byte playerId) { + playerIdList.Add(playerId); + CustomRoleManager.CheckDeadBodyOthers.Add(CheckDeadBody); } public override void Remove(byte playerId) { - CustomRoleManager.CheckDeadBodyOthers.Remove(CheckDeadBody); + playerIdList.Remove(playerId); } private void CheckDeadBody(PlayerControl killer, PlayerControl target, bool inMeeting) { if (inMeeting || target.IsDisconnected()) return; - var player = _Player; - if (player == null || !player.IsAlive()) return; - LocateArrow.Add(player.PlayerId, target.Data.GetDeadBody().transform.position); + foreach (var pc in playerIdList.ToArray()) + { + var player = pc.GetPlayer(); + if (player == null || !player.IsAlive()) continue; + LocateArrow.Add(pc, target.Data.GetDeadBody().transform.position); + } } public override void OnReportDeadBody(PlayerControl pc, NetworkedPlayerInfo target) { - if (_Player) - LocateArrow.RemoveAllTarget(_Player.PlayerId); - + foreach (var apc in playerIdList) + { + LocateArrow.RemoveAllTarget(apc); + } if (pc == null || target == null || !pc.Is(CustomRoles.Mortician) || pc.PlayerId == target.PlayerId) return; - + string name = string.Empty; var killer = target.PlayerId.GetRealKillerById(); if (killer == null) @@ -72,4 +81,4 @@ public override void OnMeetingHudStart(PlayerControl pc) AddMsg(msgToSend[pc.PlayerId], pc.PlayerId, Utils.ColorString(Utils.GetRoleColor(CustomRoles.Mortician), GetString("MorticianCheckTitle"))); } public override void MeetingHudClear() => msgToSend.Clear(); -} +} \ No newline at end of file diff --git a/Roles/Crewmate/NiceGuesser.cs b/Roles/Crewmate/NiceGuesser.cs index 6f0c296a5..cc5fe0f50 100644 --- a/Roles/Crewmate/NiceGuesser.cs +++ b/Roles/Crewmate/NiceGuesser.cs @@ -6,8 +6,10 @@ namespace TOHE.Roles.Crewmate; internal class NiceGuesser : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.NiceGuesser; private const int Id = 10900; + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateKilling; //==================================================================\\ @@ -27,6 +29,18 @@ public override void SetupCustomOption() GGTryHideMsg = BooleanOptionItem.Create(Id + 13, "GuesserTryHideMsg", true, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.NiceGuesser]) .SetColor(Color.green); } + public override void Init() + { + playerIdList.Clear(); + } + public override void Add(byte playerId) + { + playerIdList.Add(playerId); + } + public override void Remove(byte playerId) + { + playerIdList.Remove(playerId); + } public override string PVANameText(PlayerVoteArea pva, PlayerControl seer, PlayerControl target) => seer.IsAlive() && target.IsAlive() ? Utils.ColorString(Utils.GetRoleColor(CustomRoles.NiceGuesser), target.PlayerId.ToString()) + " " + pva.NameText.text : string.Empty; diff --git a/Roles/Crewmate/Observer.cs b/Roles/Crewmate/Observer.cs index 26e7fcec7..f60931e4d 100644 --- a/Roles/Crewmate/Observer.cs +++ b/Roles/Crewmate/Observer.cs @@ -5,11 +5,10 @@ namespace TOHE.Roles.Crewmate; internal class Observer : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Observer; private const int Id = 9000; private static readonly HashSet playerIdList = []; public static bool HasEnabled => playerIdList.Any(); - + public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateSupport; //==================================================================\\ @@ -25,12 +24,7 @@ public override void Init() } public override void Add(byte playerId) { - if (!playerIdList.Contains(playerId)) - playerIdList.Add(playerId); - } - public override void Remove(byte playerId) - { - playerIdList.Remove(playerId); + playerIdList.Add(playerId); } public static void ActivateGuardAnimation(byte killerId, PlayerControl target) { diff --git a/Roles/Crewmate/Oracle.cs b/Roles/Crewmate/Oracle.cs index 8cb452931..76990d760 100644 --- a/Roles/Crewmate/Oracle.cs +++ b/Roles/Crewmate/Oracle.cs @@ -1,19 +1,18 @@ using Hazel; -using InnerNet; -using System; using System.Text; +using System; using TOHE.Roles.Core; using UnityEngine; using static TOHE.Options; using static TOHE.Translator; using static TOHE.Utils; +using InnerNet; namespace TOHE.Roles.Crewmate; internal class Oracle : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Oracle; private const int Id = 9100; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Oracle); public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; @@ -40,7 +39,7 @@ public override void SetupCustomOption() OracleAbilityUseGainWithEachTaskCompleted = FloatOptionItem.Create(Id + 14, "AbilityUseGainWithEachTaskCompleted", new(0f, 5f, 0.1f), 1f, TabGroup.CrewmateRoles, false) .SetParent(CustomRoleSpawnChances[CustomRoles.Oracle]) .SetValueFormat(OptionFormat.Times); - ChangeRecruitTeam = BooleanOptionItem.Create(Id + 15, "OracleCheckAddons", false, TabGroup.CrewmateRoles, false) + ChangeRecruitTeam = BooleanOptionItem.Create(Id+15,"OracleCheckAddons",false,TabGroup.CrewmateRoles, false) .SetParent(CustomRoleSpawnChances[CustomRoles.Oracle]); } @@ -161,10 +160,10 @@ public override bool OnTaskComplete(PlayerControl player, int completedTaskCount public override void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo tagret) { DidVote.Clear(); - + TempCheckLimit[_state.PlayerId] = AbilityLimit; SendRPC(_state.PlayerId, isTemp: true); - + } public override string GetProgressText(byte playerId, bool comms) { @@ -183,4 +182,4 @@ public override string GetProgressText(byte playerId, bool comms) ProgressText.Append(ColorString(TextColor91, $" - {Math.Round(AbilityLimit, 1)}")); return ProgressText.ToString(); } -} +} \ No newline at end of file diff --git a/Roles/Crewmate/Overseer.cs b/Roles/Crewmate/Overseer.cs index 8aa6e9728..02c650c70 100644 --- a/Roles/Crewmate/Overseer.cs +++ b/Roles/Crewmate/Overseer.cs @@ -1,9 +1,9 @@ using AmongUs.GameOptions; using Hazel; using InnerNet; +using UnityEngine; using TOHE.Roles.AddOns.Common; using TOHE.Roles.Neutral; -using UnityEngine; using static TOHE.Options; using static TOHE.Translator; using static TOHE.Utils; @@ -13,8 +13,9 @@ namespace TOHE.Roles.Crewmate; internal class Overseer : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Overseer; private const int Id = 12200; + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); public override bool IsDesyncRole => true; public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmatePower; @@ -86,12 +87,15 @@ public override void SetupCustomOption() } public override void Init() { + playerIdList.Clear(); OverseerTimer.Clear(); RandomRole.Clear(); IsRevealed.Clear(); } public override void Add(byte playerId) { + playerIdList.Add(playerId); + foreach (var ar in Main.AllPlayerControls) { IsRevealed.Add((playerId, ar.PlayerId), false); @@ -199,7 +203,7 @@ public override void OnFixedUpdate(PlayerControl player, bool lowLoad, long nowT else { var (farTarget, farTime) = data; - + if (!farTarget.IsAlive()) { OverseerTimer.Remove(playerId); diff --git a/Roles/Crewmate/Pacifist.cs b/Roles/Crewmate/Pacifist.cs index 203c15932..e752e73f5 100644 --- a/Roles/Crewmate/Pacifist.cs +++ b/Roles/Crewmate/Pacifist.cs @@ -1,25 +1,23 @@ -using AmongUs.GameOptions; -using System; +using System; using System.Text; -using TOHE.Modules; -using TOHE.Roles.Core; -using TOHE.Roles.Impostor; using UnityEngine; +using AmongUs.GameOptions; +using TOHE.Roles.Impostor; +using TOHE.Modules; using static TOHE.Options; -using static TOHE.Translator; using static TOHE.Utils; +using static TOHE.Translator; +using TOHE.Roles.Core; namespace TOHE.Roles.Crewmate; internal class Pacifist : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Pacifist; private const int Id = 9200; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Pacifist); public override CustomRoles ThisRoleBase => CustomRoles.Engineer; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateSupport; - public override bool BlockMoveInVent(PlayerControl pc) => true; //==================================================================\\ private static OptionItem PacifistCooldown; @@ -50,7 +48,7 @@ public override void OnEnterVent(PlayerControl pc, Vent vent) { AbilityLimit -= 1; if (!DisableShieldAnimations.GetBool()) pc.RpcGuardAndKill(pc); - + Main.AllAlivePlayerControls.Where(x => pc.Is(CustomRoles.Madmate) ? (x.CanUseKillButton() && x.GetCustomRole().IsCrewmate()) @@ -60,9 +58,9 @@ public override void OnEnterVent(PlayerControl pc, Vent vent) x.RPCPlayCustomSound("Dove"); x.ResetKillCooldown(); x.SetKillCooldown(); - + if (x.Is(CustomRoles.Mercenary)) - { Mercenary.ClearSuicideTimer(); } + { Mercenary.ClearSuicideTimer(); } x.Notify(ColorString(GetRoleColor(CustomRoles.Pacifist), GetString("PacifistSkillNotify"))); }); @@ -77,7 +75,7 @@ public override bool OnTaskComplete(PlayerControl player, int completedTaskCount { if (player.IsAlive()) AbilityLimit += PacifistAbilityUseGainWithEachTaskCompleted.GetFloat(); - + return true; } public override void ApplyGameOptions(IGameOptions opt, byte playerId) diff --git a/Roles/Crewmate/President.cs b/Roles/Crewmate/President.cs index 883b8938d..502d089ec 100644 --- a/Roles/Crewmate/President.cs +++ b/Roles/Crewmate/President.cs @@ -8,8 +8,10 @@ namespace TOHE.Roles.Crewmate; internal class President : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.President; private const int Id = 12300; + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmatePower; //==================================================================\\ @@ -38,12 +40,14 @@ public override void SetupCustomOption() } public override void Init() { + playerIdList.Clear(); CheckPresidentReveal.Clear(); EndLimit.Clear(); RevealLimit.Clear(); } public override void Add(byte playerId) { + playerIdList.Add(playerId); CheckPresidentReveal.Add(playerId, false); EndLimit.Add(playerId, PresidentAbilityUses.GetInt()); RevealLimit.Add(playerId, 1); @@ -211,7 +215,7 @@ private static void SendRPC(byte playerId, bool isEnd = true) public static void ReceiveRPC(MessageReader reader, PlayerControl pc, bool isEnd = true) { byte PlayerId = reader.ReadByte(); - if (!isEnd) + if (!isEnd) { bool revealed = reader.ReadBoolean(); if (CheckPresidentReveal.ContainsKey(PlayerId)) CheckPresidentReveal[PlayerId] = revealed; @@ -222,7 +226,6 @@ public static void ReceiveRPC(MessageReader reader, PlayerControl pc, bool isEnd } public override bool OnRoleGuess(bool isUI, PlayerControl target, PlayerControl guesser, CustomRoles role, ref bool guesserSuicide) { - if (role != CustomRoles.President) return false; if (CheckPresidentReveal[target.PlayerId] && !PresidentCanBeGuessedAfterRevealing.GetBool()) { guesser.ShowInfoMessage(isUI, GetString("GuessPresident")); @@ -235,6 +238,6 @@ public override bool KnowRoleTarget(PlayerControl seer, PlayerControl target) (target.Is(CustomRoles.President) && seer.Is(CustomRoles.Madmate) && MadmatesSeePresident.GetBool() && CheckPresidentReveal[target.PlayerId] == true) || (target.Is(CustomRoles.President) && seer.GetCustomRole().IsNeutral() && NeutralsSeePresident.GetBool() && CheckPresidentReveal[target.PlayerId] == true) || (target.Is(CustomRoles.President) && seer.GetCustomRole().IsImpostor() && ImpsSeePresident.GetBool() && CheckPresidentReveal[target.PlayerId] == true); - + public override bool OthersKnowTargetRoleColor(PlayerControl seer, PlayerControl target) => KnowRoleTarget(seer, target); -} +} \ No newline at end of file diff --git a/Roles/Crewmate/Psychic.cs b/Roles/Crewmate/Psychic.cs index b6be3c5a3..be3f25e46 100644 --- a/Roles/Crewmate/Psychic.cs +++ b/Roles/Crewmate/Psychic.cs @@ -9,7 +9,6 @@ namespace TOHE.Roles.Crewmate; internal class Psychic : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Psychic; private const int Id = 9400; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Psychic); @@ -120,4 +119,4 @@ public override string NotifyPlayerName(PlayerControl seer, PlayerControl target public override string PVANameText(PlayerVoteArea pva, PlayerControl seer, PlayerControl target) => IsRedForPsy(target, seer) && seer.IsAlive() ? ColorString(GetRoleColor(CustomRoles.Impostor), pva.NameText.text) : string.Empty; -} +} \ No newline at end of file diff --git a/Roles/Crewmate/Randomizer.cs b/Roles/Crewmate/Randomizer.cs index c8055fa3e..7492b9676 100644 --- a/Roles/Crewmate/Randomizer.cs +++ b/Roles/Crewmate/Randomizer.cs @@ -1,129 +1,897 @@ -using System; -using TOHE.Modules; -using TOHE.Roles.AddOns.Common; +using AmongUs.GameOptions; +using Il2CppSystem.Configuration; +using MS.Internal.Xml.XPath; +using TOHE; +using TOHE.Roles.Core; +using UnityEngine; using static TOHE.Options; -using static TOHE.Translator; +using static UnityEngine.GraphicsBuffer; -namespace TOHE.Roles.Crewmate; -internal class Randomizer : RoleBase +namespace TOHE.Roles.Neutral { - //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Randomizer; - private const int Id = 7500; - public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; - public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateBasic; - //==================================================================\\ - - public static OptionItem BecomeBaitDelayNotify; - public static OptionItem BecomeBaitDelayMin; - public static OptionItem BecomeBaitDelayMax; - public static OptionItem BecomeTrapperBlockMoveTime; - - public override void SetupCustomOption() + internal class Randomizer : RoleBase { - SetupRoleOptions(Id, TabGroup.CrewmateRoles, CustomRoles.Randomizer); - BecomeBaitDelayNotify = BooleanOptionItem.Create(Id + 10, "BecomeBaitDelayNotify", false, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Randomizer]); - BecomeBaitDelayMin = FloatOptionItem.Create(Id + 11, "BaitDelayMin", new(0f, 5f, 1f), 0f, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Randomizer]) - .SetValueFormat(OptionFormat.Seconds); - BecomeBaitDelayMax = FloatOptionItem.Create(Id + 12, "BaitDelayMax", new(0f, 10f, 1f), 0f, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Randomizer]) - .SetValueFormat(OptionFormat.Seconds); - BecomeTrapperBlockMoveTime = FloatOptionItem.Create(Id + 13, "BecomeTrapperBlockMoveTime", new(1f, 180f, 1f), 5f, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Randomizer]) - .SetValueFormat(OptionFormat.Seconds); - } - public override void OnMurderPlayerAsTarget(PlayerControl killer, PlayerControl target, bool inMeeting, bool isSuicide) - { - if (inMeeting || isSuicide) return; + //===========================SETUP================================\\ + private const int Id = 82000; // Unique ID for Randomizer + public static readonly HashSet playerIdList = new(); + public static bool HasEnabled => playerIdList.Any(); + public override bool IsDesyncRole => true; + + public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; // Base role remains Neutral + public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralChaos; + //================================================================\\ + + private static readonly Dictionary RoleAvailabilityOptions = new(); + + + private static OptionItem ChanceCrew; + private static OptionItem ChanceImpostor; + private static OptionItem ChanceNeutral; + + private static OptionItem AllowGhostRoles; + private static OptionItem MinAddOns; + private static OptionItem MaxAddOns; + - var Fg = IRandom.Instance; - int Randomizer = Fg.Next(1, 5); - if (Randomizer == 1) + + + + public override void SetupCustomOption() { - if (isSuicide) + Options.SetupRoleOptions(Id, TabGroup.NeutralRoles, CustomRoles.Randomizer); + + // Add Chance Crew Option + ChanceCrew = IntegerOptionItem.Create(Id + 10, "ChanceCrew", new(0, 100, 5), 40, TabGroup.NeutralRoles, false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Randomizer]) + .SetValueFormat(OptionFormat.Percent); + + + // Add Chance Impostor Option + ChanceImpostor = IntegerOptionItem.Create(Id + 11, "ChanceImpostor", new(0, 100, 5), 40, TabGroup.NeutralRoles, false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Randomizer]) + .SetValueFormat(OptionFormat.Percent); + + + // Add Chance Neutral Option + ChanceNeutral = IntegerOptionItem.Create(Id + 12, "ChanceNeutral", new(0, 100, 5), 20, TabGroup.NeutralRoles, false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Randomizer]) + .SetValueFormat(OptionFormat.Percent); + + + AllowGhostRoles = BooleanOptionItem.Create(Id + 20, "AllowGhostRoles", false, TabGroup.NeutralRoles, false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Randomizer]); + + + MinAddOns = IntegerOptionItem.Create(Id + 30, "MinAddOns", new(0, 10, 1), 0, TabGroup.NeutralRoles, false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Randomizer]); + + MaxAddOns = IntegerOptionItem.Create(Id + 31, "MaxAddOns", new(0, 10, 1), 3, TabGroup.NeutralRoles, false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Randomizer]); + } + + + + + + + + + + + + public override void Init() + { + playerIdList.Clear(); + + int crewChance = ChanceCrew.GetInt(); + int impostorChance = ChanceImpostor.GetInt(); + int neutralChance = ChanceNeutral.GetInt(); + + int totalChance = crewChance + impostorChance + neutralChance; + + // Check if total chances exceed 100% + if (totalChance > 100) { - if (target.GetRealKiller() != null) - { - if (!target.GetRealKiller().IsAlive()) return; - killer = target.GetRealKiller(); - } + Logger.Warn("Total team chances exceed 100%. Overlap resolution will be applied during role assignment.", "Randomizer"); + } + else if (totalChance == 0) + { + Logger.Warn("All team chances are set to 0. Using default equal distribution.", "Randomizer"); } - if (killer.PlayerId == target.PlayerId) return; + Logger.Info($"Initialized Randomizer with team chances - Crewmate: {crewChance}%, Impostor: {impostorChance}%, Neutral: {neutralChance}%.", "Randomizer"); + } + + - if (killer.Is(CustomRoles.KillingMachine) - || (killer.Is(CustomRoles.Oblivious) && Oblivious.ObliviousBaitImmune.GetBool())) - return; - if (!isSuicide || (target.GetRealKiller()?.GetCustomRole() is CustomRoles.Swooper or CustomRoles.Wraith) || !killer.Is(CustomRoles.KillingMachine) || !killer.Is(CustomRoles.Oblivious) || (killer.Is(CustomRoles.Oblivious) && !Oblivious.ObliviousBaitImmune.GetBool())) + + + + public override void Add(byte playerId) + { + if (playerIdList.Contains(playerId)) return; // Avoid duplicates + + playerIdList.Add(playerId); + + + + var pc = Utils.GetPlayerById(playerId); + if (pc == null) return; + + // Set Randomizer role + var playerState = Main.PlayerStates[playerId]; + playerState.SetMainRole(CustomRoles.Randomizer); + playerState.IsRandomizer = true; + + if (pc.GetCustomRole() != CustomRoles.Randomizer) { - killer.RPCPlayCustomSound("Congrats"); - target.RPCPlayCustomSound("Congrats"); + pc.RpcChangeRoleBasis(CustomRoles.Crewmate); + pc.RpcSetCustomRole(CustomRoles.Randomizer); + } + + // Notify player + pc.Notify($"You are the Randomizer! Your role will change after each meeting."); + } + - float delay; - if (BecomeBaitDelayMax.GetFloat() < BecomeBaitDelayMin.GetFloat()) + private void AssignRandomRole(byte playerId) + { + var pc = Utils.GetPlayerById(playerId); + if (pc == null) return; + + // Reset subroles before assigning a new role + ResetSubRoles(playerId); + + // Get the player's state + var playerState = Main.PlayerStates[playerId]; + if (playerState == null) return; + + // Determine team lock if not already applied + if (!playerState.TeamLockApplied) + { + CustomRoles randomRole = GetRandomRoleAcrossAllTeams(playerId); + + // Lock the team based on the role + if (randomRole.IsCrewmate()) { - delay = 0f; + playerState.IsCrewmateTeam = true; + playerState.LockedRoleType = Custom_RoleType.CrewmateBasic; // Lock to Crewmate type + Logger.Info($"Randomizer locked to Crewmate team.", "Randomizer"); } - else + else if (randomRole.IsImpostorTeam()) { - delay = IRandom.Instance.Next((int)BecomeBaitDelayMin.GetFloat(), (int)BecomeBaitDelayMax.GetFloat() + 1); + playerState.IsImpostorTeam = true; + playerState.LockedRoleType = Custom_RoleType.ImpostorVanilla; // Lock to Impostor type + Logger.Info($"Randomizer locked to Impostor team.", "Randomizer"); } - delay = Math.Max(delay, 0.15f); - if (delay > 0.15f && BecomeBaitDelayNotify.GetBool()) + else if (randomRole.IsNeutral()) { - killer.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Bait), string.Format(GetString("KillBaitNotify"), (int)delay)), delay); + playerState.IsNeutralTeam = true; + playerState.LockedRoleType = Custom_RoleType.NeutralChaos; // Lock to Neutral type + Logger.Info($"Randomizer locked to Neutral team.", "Randomizer"); } - Logger.Info($"{killer.GetNameWithRole()} 击杀了萧暮触发自动报告 => {target.GetNameWithRole()}", "Randomizer"); + // Apply the role + pc.RpcChangeRoleBasis(randomRole); // Update basis to match the new role + pc.RpcSetCustomRole(randomRole); // Set the random role + pc.GetRoleClass()?.OnAdd(playerId); // Initialize the new role logic + pc.SyncSettings(); // Ensures the player's UI reflects the changes + + // Initialize tasks and abilities + playerState.InitTask(pc); - killer.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Randomizer), GetString("YouKillRandomizer1"))); + Logger.Info($"Randomizer assigned initial role {randomRole} to player {pc.name}", "Randomizer"); + } + else + { + // If team is already locked, get a new random role + CustomRoles randomRole = GetRandomRoleAcrossAllTeams(playerId); + + // Apply the new role while maintaining the locked team + pc.RpcChangeRoleBasis(randomRole); // Update basis to match the new role + pc.RpcSetCustomRole(randomRole); // Set the random role + pc.GetRoleClass()?.OnAdd(playerId); // Initialize the new role logic + pc.SyncSettings(); // Ensures the player's UI reflects the changes + + // Initialize tasks and abilities + playerState.InitTask(pc); + + Logger.Info($"Randomizer assigned new role {randomRole} to player {pc.name} (team locked to {playerState.LockedRoleType})", "Randomizer"); + } + } - _ = new LateTask(() => + + public static void RandomizerWinCondition(PlayerControl pc) + { + if (pc == null) return; + + var playerState = Main.PlayerStates[pc.PlayerId]; + if (!playerState.IsRandomizer || !playerState.TeamLockApplied) + { + Logger.Warn($"Randomizer {pc.name} has no team lock applied or is not a Randomizer. Skipping win condition check.", "Randomizer"); + return; + } + + // Alive players' win conditions + switch (playerState.RandomizerWinCondition) + { + case Custom_Team.Crewmate: + if (CustomWinnerHolder.WinnerTeam == CustomWinner.Crewmate && pc.IsAlive()) + { + CustomWinnerHolder.WinnerIds.Add(pc.PlayerId); + CustomWinnerHolder.AdditionalWinnerTeams.Add(AdditionalWinners.Randomizer); + Logger.Info($"Randomizer {pc.name} (alive) wins with the Crewmate team.", "Randomizer"); + } + break; + + case Custom_Team.Impostor: + if (CustomWinnerHolder.WinnerTeam == CustomWinner.Impostor && pc.IsAlive()) + { + CustomWinnerHolder.WinnerIds.Add(pc.PlayerId); + CustomWinnerHolder.AdditionalWinnerTeams.Add(AdditionalWinners.Randomizer); + Logger.Info($"Randomizer {pc.name} (alive) wins with the Impostor team.", "Randomizer"); + } + break; + + case Custom_Team.Neutral: + if (pc.IsAlive()) + { + CustomWinnerHolder.WinnerIds.Add(pc.PlayerId); + CustomWinnerHolder.AdditionalWinnerTeams.Add(AdditionalWinners.Randomizer); + Logger.Info($"Randomizer {pc.name} wins as a Neutral player (alive).", "Randomizer"); + } + break; + + default: + Logger.Warn($"Randomizer {pc.name} has an unknown or invalid win condition: {playerState.RandomizerWinCondition}.", "Randomizer"); + break; + } + + // Dead players' win conditions + if (!pc.IsAlive()) + { + if (playerState.LockedTeam == Custom_Team.Crewmate && CustomWinnerHolder.WinnerTeam == CustomWinner.Crewmate) { - if (GameStates.IsInTask) killer.CmdReportDeadBody(target.Data); - }, delay, "Bait Self Report"); + CustomWinnerHolder.WinnerIds.Add(pc.PlayerId); + CustomWinnerHolder.AdditionalWinnerTeams.Add(AdditionalWinners.Randomizer); + Logger.Info($"Randomizer {pc.name} (dead) wins with the Crewmate team.", "Randomizer"); + } + else if (playerState.LockedTeam == Custom_Team.Impostor && CustomWinnerHolder.WinnerTeam == CustomWinner.Impostor) + { + CustomWinnerHolder.WinnerIds.Add(pc.PlayerId); + CustomWinnerHolder.AdditionalWinnerTeams.Add(AdditionalWinners.Randomizer); + Logger.Info($"Randomizer {pc.name} (dead) wins with the Impostor team.", "Randomizer"); + } } } - else if (Randomizer == 2) + + + + + + + + + + + private static Custom_Team DetermineTeam() { - Logger.Info($"{killer.GetNameWithRole()} 击杀了萧暮触发暂时无法移动 => {target.GetNameWithRole()}", "Randomizer"); + int crewChance = ChanceCrew.GetInt(); + int impostorChance = ChanceImpostor.GetInt(); + int neutralChance = ChanceNeutral.GetInt(); - killer.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Randomizer), GetString("YouKillRandomizer2"))); - var tmpSpeed = Main.AllPlayerSpeed[killer.PlayerId]; - Main.AllPlayerSpeed[killer.PlayerId] = Main.MinSpeed; - ReportDeadBodyPatch.CanReport[killer.PlayerId] = false; - killer.MarkDirtySettings(); + int totalChance = crewChance + impostorChance + neutralChance; - _ = new LateTask(() => + // Handle all chances set to 0 or if total chance is 0 + if (totalChance == 0) { - Main.AllPlayerSpeed[killer.PlayerId] = Main.AllPlayerSpeed[killer.PlayerId] - Main.MinSpeed + tmpSpeed; - ReportDeadBodyPatch.CanReport[killer.PlayerId] = true; - killer.MarkDirtySettings(); - RPC.PlaySoundRPC(killer.PlayerId, Sounds.TaskComplete); - }, BecomeTrapperBlockMoveTime.GetFloat(), "Trapper BlockMove"); + Logger.Warn("All team chances are set to 0. Running default overlap with equal chances.", "DetermineTeam"); + return ResolveOverlap(new[] { Custom_Team.Crewmate, Custom_Team.Impostor, Custom_Team.Neutral }); + } + + int roll = UnityEngine.Random.Range(0, totalChance); + + // Check for overlapping chances + List overlappingTeams = new(); + + if (roll < crewChance) overlappingTeams.Add(Custom_Team.Crewmate); + if (roll < crewChance + impostorChance && roll >= crewChance) overlappingTeams.Add(Custom_Team.Impostor); + if (roll >= crewChance + impostorChance) overlappingTeams.Add(Custom_Team.Neutral); + + // Handle overlap dynamically + if (overlappingTeams.Count > 1) + { + Logger.Warn($"Chance overlap detected for teams: {string.Join(", ", overlappingTeams)}. Resolving overlap...", "DetermineTeam"); + return ResolveOverlap(overlappingTeams); + } + + // Return the determined team if no overlap + if (roll < crewChance) return Custom_Team.Crewmate; + if (roll < crewChance + impostorChance) return Custom_Team.Impostor; + return Custom_Team.Neutral; } - else if (Randomizer == 3) + private static Custom_Team ResolveOverlap(IEnumerable overlappingTeams) { - Logger.Info($"{killer.GetNameWithRole()} 击杀了萧暮触发凶手CD变成600 => {target.GetNameWithRole()}", "Randomizer"); - killer.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Randomizer), GetString("YouKillRandomizer3"))); - Main.AllPlayerKillCooldown[killer.PlayerId] = 600f; - killer.SyncSettings(); + var teams = overlappingTeams.ToList(); + int roll = UnityEngine.Random.Range(0, teams.Count); + + Logger.Info($"Resolved overlap. Selected team: {teams[roll]}", "ResolveOverlap"); + return teams[roll]; } - else if (Randomizer == 4) + + private static void NotifyRoleChange(PlayerControl pc, CustomRoles newRole) { - Logger.Info($"{killer.GetNameWithRole()} 击杀了萧暮触发随机复仇 => {target.GetNameWithRole()}", "Randomizer"); - killer.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Randomizer), GetString("YouKillRandomizer4"))); + var playerState = Main.PlayerStates[pc.PlayerId]; + + // Get a list of add-ons for the player + var addOns = string.Join(", ", playerState.SubRoles.Select(addOn => Utils.GetRoleName(addOn))); + + // Notify Randomizer about its role and add-ons + string message = $"You are still the Randomizer! Your current role is {Utils.GetRoleName(newRole)}"; + if (!string.IsNullOrEmpty(addOns)) { - var pcList = Main.AllAlivePlayerControls.Where(x => x.PlayerId != target.PlayerId && target.RpcCheckAndMurder(x, true)).ToList(); - var pc = pcList[IRandom.Instance.Next(0, pcList.Count)]; - if (!pc.IsTransformedNeutralApocalypse()) + message += $" with the following add-ons: {addOns}."; + } + + pc.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Randomizer), message)); + } + private static bool IsRoleEnabled(CustomRoles role) + { + if (RoleAvailabilityOptions.TryGetValue(role, out var option)) + { + return option.GetBool(); + } + return true; // Default to enabled if not explicitly configured + } + private static CustomRoles GetGhostRole(byte playerId) + { + if (!GhostRolesList.Any()) + { + Logger.Warn("No ghost roles available. Defaulting to a fallback role.", "Randomizer"); + return CustomRoles.CrewmateTOHE; // Default fallback if the list is empty + } + + // Select a random ghost role + CustomRoles selectedRole = GhostRolesList[UnityEngine.Random.Range(0, GhostRolesList.Count)]; + Logger.Info($"Assigned ghost role {selectedRole} to player ID {playerId}.", "Randomizer"); + return selectedRole; + } + + + + + + + private static CustomRoles GetRandomRoleAcrossAllTeams(byte playerId) + { + var pc = Utils.GetPlayerById(playerId); + if (pc == null) return CustomRoles.CrewmateTOHE; // Default fallback + + var playerState = Main.PlayerStates[playerId]; + + // Determine team based on percentage chances + var team = DetermineTeam(); + + List availableRoles = team switch + { + Custom_Team.Crewmate => GetAllCrewmateRoles(), + Custom_Team.Impostor => GetAllImpostorRoles(), + Custom_Team.Neutral => GetAllNeutralRoles(), + _ => new List() // Default empty list + }; + + if (!availableRoles.Any()) + { + Logger.Error("Available roles list is empty for the determined team. Defaulting to Crewmate.", "Randomizer"); + return CustomRoles.CrewmateTOHE; // Fallback role + } + + // Select a random role from the available roles + var selectedRole = availableRoles[UnityEngine.Random.Range(0, availableRoles.Count)]; + + // Lock the team if not already locked + if (!playerState.TeamLockApplied) + { + playerState.TeamLockApplied = true; + playerState.IsCrewmateTeam = team == Custom_Team.Crewmate; + playerState.IsImpostorTeam = team == Custom_Team.Impostor; + playerState.IsNeutralTeam = team == Custom_Team.Neutral; + + Logger.Info($"Randomizer locked to {team} team.", "Randomizer"); + } + + Logger.Info($"Randomizer assigned role: {selectedRole}", "Randomizer"); + return selectedRole; + } + public override bool OnCheckMurderAsTarget(PlayerControl killer, PlayerControl target) + { + + var playerState = Main.PlayerStates[target.PlayerId]; + var isRandomizer = playerState.IsRandomizer; + + if (!isRandomizer) + { + Logger.Info($"Player {target.name} is not Randomizer. Skipping ghost role assignment.", "Randomizer"); + return false; // Continue with default behavior + } + + Logger.Info($"Randomizer {target.name} is being killed by {killer.name}. Checking ghost role settings...", "Randomizer"); + + // Check if ghost roles are allowed + if (AllowGhostRoles.GetBool()) + { + Logger.Info($"Ghost roles are enabled. Assigning GuardianAngel base to {target.name}.", "Randomizer"); + + // Assign GuardianAngel base and link the role + var newGhostRole = GetGhostRole(target.PlayerId); + target.RpcChangeRoleBasis(CustomRoles.GuardianAngel); // Change to GuardianAngel base + target.RpcSetCustomRole(newGhostRole); // Assign the selected ghost role + target.GetRoleClass()?.OnAdd(target.PlayerId); // Initialize the role class + target.SyncSettings(); // Sync role settings + playerState.IsDead = true; // Ensure the player is marked as a ghost + + Logger.Info($"Assigned ghost role {newGhostRole} to Randomizer {target.name}.", "Randomizer"); + return true; // Prevent further processing of the murder + } + else + { + Logger.Info($"Ghost roles are disabled. Keeping Randomizer {target.name} as a standard dead player.", "Randomizer"); + return true; // Allow the murder to proceed without ghost role assignment + } + } + + + public static void RandomizerGhost(PlayerControl pc) + { + var playerState = Main.PlayerStates[pc.PlayerId]; + + + + Logger.Info($"Applying RandomizerGhost logic to {pc.name}.", "Randomizer"); + + // Teleport player outside the map + pc.RpcTeleport(ExtendedPlayerControl.GetBlackRoomPosition()); + + // Schedule a task to "kill" the player + _ = new LateTask( + () => { - pc.SetDeathReason(PlayerState.DeathReason.Revenge); + // Kill the player pc.RpcMurderPlayer(pc); - pc.SetRealKiller(target); + playerState.IsDead = true; + + // Sync death information + pc.SetRealKiller(pc); // Set self as killer (or null if unnecessary) + Logger.Info($"{pc.name} has been killed and marked as a ghost Randomizer.", "Randomizer"); + + // Teleport back to spawn + _ = new LateTask( + () => + { + Vector3 spawnPosition = new Vector3(0, 0, 0); + pc.RpcTeleport(spawnPosition); + Logger.Info($"{pc.name} teleported back to spawn as a ghost Randomizer.", "Randomizer"); + }, + 1f, // Delay to ensure smooth transition + "TeleportBackToSpawn" + ); + }, + 0.5f, // Delay before killing + "RandomizerKillTask" + ); + } + + + public static void AfterMeetingTasks() + { + foreach (var playerId in playerIdList.ToList()) + { + var pc = Utils.GetPlayerById(playerId); + if (pc == null) continue; + + // Reset subroles + Main.PlayerStates[playerId].ResetSubRoles(); + pc.GetRoleClass()?.OnRemove(pc.PlayerId); + + // Determine role assignment based on player's alive status + CustomRoles newRole; + if (!pc.IsAlive()) + { + if (AllowGhostRoles.GetBool()) // Ghost roles are enabled + { + Logger.Info($"Randomizer {pc.name} is dead. Assigning a new ghost role.", "Randomizer"); + + // Assign ghost role + newRole = GetGhostRole(pc.PlayerId); + pc.RpcChangeRoleBasis(CustomRoles.GuardianAngel); // Set base role + pc.RpcSetCustomRole(newRole); // Set the custom ghost role + pc.GetRoleClass()?.OnAdd(pc.PlayerId); // Initialize role + pc.SyncSettings(); // Sync the role settings + RandomizerGhost(pc); + // Explicitly set dead state + Main.PlayerStates[pc.PlayerId].IsDead = true; // Mark as dead + + + Logger.Info($"Randomizer {pc.name} has been marked as dead and assigned the ghost role: {newRole}.", "Randomizer"); + } + + + else + { + // Ghost roles are disabled, do nothing to avoid reviving + Logger.Info($"Randomizer {pc.name} is dead. Ghost roles are disabled. No role changes applied.", "Randomizer"); + continue; + } + } + else if (pc.IsAlive()) // Player is alive, assign a normal role + { + Logger.Info($"Randomizer {pc.name} is alive. Assigning a normal role.", "Randomizer"); + newRole = GetRandomRoleAcrossAllTeams(playerId); // Assign from the normal role pool } + else + { + Logger.Warn($"Randomizer {pc.name} could not be assigned a role. Defaulting to Crewmate.", "Randomizer"); + newRole = CustomRoles.CrewmateTOHE; // Fallback in case of unexpected condition + } + + Logger.Info($"Assigning role {newRole} to player {pc.name}", "Randomizer"); + + // Update the player's role + pc.RpcChangeRoleBasis(newRole); // Update the role basis + pc.RpcSetCustomRole(newRole); // Set the actual role + + // Preserve Randomizer flag + var playerState = Main.PlayerStates[playerId]; + playerState.IsRandomizer = true; + + // Notify the player after the role is finalized + NotifyRoleChange(pc, newRole); + + // Assign random add-ons (only for alive players) + if (pc.IsAlive()) + { + // Retrieve the min and max add-on settings + int minAddOns = MinAddOns.GetInt(); + int maxAddOns = MaxAddOns.GetInt(); + + // Ensure maxAddOns is not less than minAddOns + if (maxAddOns < minAddOns) + { + Logger.Warn($"Max Add-Ons ({maxAddOns}) is less than Min Add-Ons ({minAddOns}). Using Min Add-Ons.", "Randomizer"); + maxAddOns = minAddOns; + } + + // Randomly determine the number of add-ons to assign + int addOnCount = UnityEngine.Random.Range(minAddOns, maxAddOns + 1); + List selectedAddOns = GetAvailableAddOns() + .OrderBy(_ => UnityEngine.Random.value) + .Take(addOnCount) + .ToList(); + + foreach (var addOn in selectedAddOns) + { + playerState.SetSubRole(addOn, pc); + Logger.Info($"Assigned Add-on {addOn} to {pc.name}", "Randomizer"); + } + } + + // Sync settings and tasks + pc.SyncSettings(); + playerState.InitTask(pc); + pc.GetRoleClass()?.OnAdd(pc.PlayerId); + } + } + + + + + + + + + private void ResetSubRoles(byte playerId) + { + var playerState = Main.PlayerStates[playerId]; + if (playerState == null) return; + + foreach (var subRole in playerState.SubRoles.ToList()) // Use ToList() to avoid modification during enumeration + { + playerState.RemoveSubRole(subRole); } + + playerState.SubRoles.Clear(); // Ensure the SubRoles list is empty + } + public override void Remove(byte playerId) + { + var playerState = Main.PlayerStates[playerId]; + if (playerState != null) + playerState.IsRandomizer = false; // Clear Randomizer flag + playerState.TeamLockApplied = false; // Reset team lock + playerState.IsCrewmateTeam = false; + playerState.IsImpostorTeam = false; + playerState.IsNeutralTeam = false; } + + // Define role lists inside the Randomizer class + private static List GetAllCrewmateRoles() + { + return new List + { + CustomRoles.Addict, + CustomRoles.Alchemist, + CustomRoles.Bastion, + CustomRoles.Benefactor, + CustomRoles.Bodyguard, + CustomRoles.Captain, + CustomRoles.Celebrity, + CustomRoles.Cleanser, + CustomRoles.Coroner, + CustomRoles.Crusader, + CustomRoles.Deceiver, + CustomRoles.Deputy, + CustomRoles.Detective, + CustomRoles.Dictator, + CustomRoles.Enigma, + CustomRoles.FortuneTeller, + CustomRoles.Grenadier, + CustomRoles.Guardian, + CustomRoles.GuessMaster, + CustomRoles.Inspector, + CustomRoles.Investigator, + CustomRoles.Jailer, + CustomRoles.Judge, + CustomRoles.Keeper, + CustomRoles.Knight, + CustomRoles.LazyGuy, + CustomRoles.Lighter, + CustomRoles.Lookout, + CustomRoles.Marshall, + CustomRoles.Mayor, + CustomRoles.Mechanic, + CustomRoles.Medium, + CustomRoles.Merchant, + CustomRoles.Mole, + CustomRoles.Mortician, + CustomRoles.NiceGuesser, + CustomRoles.Observer, + CustomRoles.Oracle, + CustomRoles.Overseer, + CustomRoles.Pacifist, + CustomRoles.Psychic, + CustomRoles.Reverie, + CustomRoles.Sheriff, + CustomRoles.Snitch, + CustomRoles.Spiritualist, + CustomRoles.Spy, + CustomRoles.Swapper, + CustomRoles.TaskManager, + CustomRoles.Telecommunication, + CustomRoles.TimeManager, + CustomRoles.TimeMaster, + CustomRoles.Tracefinder, + CustomRoles.Transporter, + CustomRoles.Ventguard, + CustomRoles.Veteran, + CustomRoles.Vigilante, + CustomRoles.Witness, + // Add other Crewmate roles here + }; + } + + private static List GetAllNeutralRoles() + { + return new List + { + CustomRoles.Arsonist, + CustomRoles.Arsonist, + CustomRoles.Bandit, + + CustomRoles.BloodKnight, + CustomRoles.Collector, + CustomRoles.Demon, + CustomRoles.Doomsayer, + CustomRoles.Executioner, + CustomRoles.Evolver, + CustomRoles.Follower, + CustomRoles.Glitch, + CustomRoles.God, + CustomRoles.Hater, + CustomRoles.HexMaster, + CustomRoles.Huntsman, + CustomRoles.Jester, + CustomRoles.Jinx, + CustomRoles.Juggernaut, + CustomRoles.Maverick, + CustomRoles.Medusa, + CustomRoles.Necromancer, + CustomRoles.Opportunist, + CustomRoles.Pelican, + CustomRoles.Pickpocket, + CustomRoles.Pirate, + CustomRoles.Pixie, + CustomRoles.PlagueDoctor, + CustomRoles.Poisoner, + CustomRoles.PotionMaster, + CustomRoles.PunchingBag, + CustomRoles.Pursuer, + CustomRoles.Pyromaniac, + CustomRoles.Quizmaster, + CustomRoles.Revolutionist, + CustomRoles.RuthlessRomantic, + CustomRoles.SchrodingersCat, + CustomRoles.Seeker, + CustomRoles.SerialKiller, + CustomRoles.Shaman, + CustomRoles.Shroud, + CustomRoles.Sidekick, + CustomRoles.Solsticer, + CustomRoles.Stalker, + CustomRoles.Sunnyboy, + CustomRoles.Taskinator, + CustomRoles.Terrorist, + CustomRoles.Traitor, + CustomRoles.Troller, + CustomRoles.Vector, + CustomRoles.VengefulRomantic, + CustomRoles.Vulture, + CustomRoles.Werewolf, + CustomRoles.Workaholic, + + // Add other Neutral roles here + }; + } + + private static List GetAllImpostorRoles() + { + return new List + { + CustomRoles.Consigliere, + CustomRoles.Crewpostor, + CustomRoles.Cleaner, + CustomRoles.Anonymous, + CustomRoles.AntiAdminer, + CustomRoles.Arrogance, + CustomRoles.Bard, + CustomRoles.Blackmailer, + CustomRoles.Bomber, + CustomRoles.BountyHunter, + CustomRoles.Butcher, + CustomRoles.Camouflager, + CustomRoles.Chronomancer, + CustomRoles.Councillor, + CustomRoles.CursedWolf, + CustomRoles.Dazzler, + CustomRoles.Deathpact, + CustomRoles.Disperser, + CustomRoles.DoubleAgent, + CustomRoles.Eraser, + CustomRoles.Escapist, + CustomRoles.EvilGuesser, + CustomRoles.EvilHacker, + CustomRoles.EvilTracker, + CustomRoles.Fireworker, + CustomRoles.Greedy, + CustomRoles.Hangman, + CustomRoles.Inhibitor, + CustomRoles.Kamikaze, + CustomRoles.KillingMachine, + CustomRoles.Lightning, + CustomRoles.Ludopath, + CustomRoles.Lurker, + CustomRoles.Mastermind, + CustomRoles.Miner, + CustomRoles.Morphling, + CustomRoles.Ninja, + CustomRoles.Parasite, + CustomRoles.Penguin, + CustomRoles.Pitfall, + CustomRoles.Puppeteer, + CustomRoles.QuickShooter, + CustomRoles.Refugee, + CustomRoles.RiftMaker, + CustomRoles.Saboteur, + CustomRoles.Scavenger, + CustomRoles.ShapeMaster, + CustomRoles.Sniper, + CustomRoles.SoulCatcher, + CustomRoles.Stealth, + CustomRoles.YinYanger, + CustomRoles.Swooper, + CustomRoles.Trapster, + CustomRoles.Trickster, + CustomRoles.Twister, + CustomRoles.Undertaker, + CustomRoles.Vampire, + CustomRoles.Vindicator, + CustomRoles.Visionary, + CustomRoles.Warlock, + CustomRoles.Wildling, + CustomRoles.Witch, + CustomRoles.Zombie, + // Add other existing impostor roles here + }; + } + + + private static List GetAvailableAddOns() + { + return new List + { + + CustomRoles.Antidote, + CustomRoles.Autopsy, + CustomRoles.Avanger, + CustomRoles.Aware, + CustomRoles.Bait, + CustomRoles.Bewilder, + CustomRoles.Bloodthirst, + CustomRoles.Burst, + CustomRoles.Circumvent, + CustomRoles.Cleansed, + CustomRoles.Clumsy, + CustomRoles.Cyber, + CustomRoles.Diseased, + CustomRoles.DoubleShot, + CustomRoles.Eavesdropper, + CustomRoles.Evader, + CustomRoles.Flash, + CustomRoles.Fool, + CustomRoles.Fragile, + CustomRoles.Ghoul, + CustomRoles.Glow, + CustomRoles.Gravestone, + CustomRoles.Guesser, + CustomRoles.Influenced, + CustomRoles.LastImpostor, + CustomRoles.Lazy, + CustomRoles.Loyal, + CustomRoles.Lucky, + CustomRoles.Mare, + CustomRoles.Rebirth, + CustomRoles.Mimic, + CustomRoles.Mundane, + CustomRoles.Necroview, + CustomRoles.Nimble, + CustomRoles.Oblivious, + CustomRoles.Onbound, + CustomRoles.Overclocked, + CustomRoles.Paranoia, + CustomRoles.Prohibited, + CustomRoles.Radar, + CustomRoles.Rainbow, + CustomRoles.Rascal, + CustomRoles.Reach, + CustomRoles.Rebound, + CustomRoles.Spurt, + CustomRoles.Seer, + CustomRoles.Silent, + CustomRoles.Sleuth, + CustomRoles.Sloth, + CustomRoles.Statue, + CustomRoles.Stubborn, + CustomRoles.Susceptible, + CustomRoles.Swift, + CustomRoles.Tiebreaker, + CustomRoles.Stealer, + CustomRoles.Torch, + CustomRoles.Trapper, + CustomRoles.Tricky, + CustomRoles.Tired, + CustomRoles.Unlucky, + CustomRoles.VoidBallot, + CustomRoles.Watcher, + CustomRoles.Workhorse, + + }; + + + } + + private static readonly List GhostRolesList = new() +{ + CustomRoles.Bloodmoon, + CustomRoles.Minion, + CustomRoles.Possessor, + CustomRoles.Ghastly, + CustomRoles.Hawk, + CustomRoles.Warden +}; } } diff --git a/Roles/Crewmate/Retributionist.cs b/Roles/Crewmate/Retributionist.cs index 0bfaa6664..db0b634aa 100644 --- a/Roles/Crewmate/Retributionist.cs +++ b/Roles/Crewmate/Retributionist.cs @@ -2,18 +2,20 @@ using TOHE.Modules; using TOHE.Roles.Double; using UnityEngine; -using static TOHE.MeetingHudStartPatch; using static TOHE.Options; using static TOHE.Translator; using static TOHE.Utils; +using static TOHE.MeetingHudStartPatch; namespace TOHE.Roles.Crewmate; internal class Retributionist : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Retributionist; private const int Id = 11000; + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateKilling; //==================================================================\\ @@ -21,7 +23,6 @@ internal class Retributionist : RoleBase private static OptionItem RetributionistCanKillNum; private static OptionItem MinimumPlayersAliveToRetri; private static OptionItem CanOnlyRetributeWithTasksDone; - private static OptionItem PreventSeeRolesBeforeSkillUsedUp; private static readonly Dictionary RetributionistRevenged = []; @@ -31,8 +32,6 @@ public override void SetupCustomOption() RetributionistCanKillNum = IntegerOptionItem.Create(Id + 10, "RetributionistCanKillNum", new(1, 15, 1), 1, TabGroup.CrewmateRoles, false) .SetParent(CustomRoleSpawnChances[CustomRoles.Retributionist]) .SetValueFormat(OptionFormat.Players); - PreventSeeRolesBeforeSkillUsedUp = BooleanOptionItem.Create(Id + 20, "PreventSeeRolesBeforeSkillUsedUp", true, TabGroup.ImpostorRoles, false) - .SetParent(CustomRoleSpawnChances[CustomRoles.Retributionist]); MinimumPlayersAliveToRetri = IntegerOptionItem.Create(Id + 11, "MinimumPlayersAliveToRetri", new(0, 15, 1), 5, TabGroup.CrewmateRoles, false) .SetParent(CustomRoleSpawnChances[CustomRoles.Retributionist]) .SetValueFormat(OptionFormat.Players); @@ -42,19 +41,15 @@ public override void SetupCustomOption() } public override void Init() { + playerIdList.Clear(); RetributionistRevenged.Clear(); } public override void Add(byte playerId) { + playerIdList.Add(playerId); RetributionistRevenged[playerId] = 0; } - public static bool PreventKnowRole(PlayerControl seer) - { - if (!seer.Is(CustomRoles.Retributionist) || seer.IsAlive()) return false; - if (PreventSeeRolesBeforeSkillUsedUp.GetBool() && RetributionistRevenged.TryGetValue(seer.PlayerId, out var killNum) && killNum < RetributionistCanKillNum.GetInt()) - return true; - return false; - } + public override string GetMark(PlayerControl seer, PlayerControl seen = null, bool isForMeeting = false) { seen ??= seer; @@ -188,8 +183,7 @@ public static bool RetributionistMsgCheck(PlayerControl pc, string msg, bool isU } target.SetRealKiller(pc); - _ = new LateTask(() => - { + _ = new LateTask(() => { SendMessage(string.Format(GetString("RetributionistKillSucceed"), Name), 255, ColorString(GetRoleColor(CustomRoles.Retributionist), GetString("RetributionistRevengeTitle")), true); }, 0.6f, "Retributionist Kill"); @@ -222,7 +216,7 @@ public override void OnMeetingHudStart(PlayerControl pc) if (!pc.IsAlive()) AddMsg(GetString("RetributionistDeadMsg"), pc.PlayerId); } - + [HarmonyPatch(typeof(MeetingHud), nameof(MeetingHud.Start))] class StartMeetingPatch { @@ -250,4 +244,4 @@ public static void CreateJudgeButton(MeetingHud __instance) button.OnClick.AddListener((UnityEngine.Events.UnityAction)(() => RetributionistOnClick(pva.TargetPlayerId/*, __instance*/))); } } -} +} \ No newline at end of file diff --git a/Roles/Crewmate/Reverie.cs b/Roles/Crewmate/Reverie.cs index 1fc93219a..ad8b5c428 100644 --- a/Roles/Crewmate/Reverie.cs +++ b/Roles/Crewmate/Reverie.cs @@ -1,5 +1,5 @@ -using AmongUs.GameOptions; using System; +using AmongUs.GameOptions; using static TOHE.Options; namespace TOHE.Roles.Crewmate; @@ -7,9 +7,9 @@ namespace TOHE.Roles.Crewmate; internal class Reverie : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Reverie; private const int Id = 11100; - + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); public override bool IsDesyncRole => true; public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateKilling; @@ -39,20 +39,23 @@ public override void SetupCustomOption() .SetValueFormat(OptionFormat.Seconds); MaxKillCooldown = FloatOptionItem.Create(Id + 14, "ReverieMaxKillCooldown", new(0f, 180f, 2.5f), 40f, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Reverie]) .SetValueFormat(OptionFormat.Seconds); - MisfireSuicide = BooleanOptionItem.Create(Id + 15, "ReverieMisfireSuicide", true, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Reverie]); - ResetCooldownMeeting = BooleanOptionItem.Create(Id + 16, "ReverieResetCooldownMeeting", false, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Reverie]); + MisfireSuicide = BooleanOptionItem.Create(Id + 15, "ReverieMisfireSuicide", true, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Reverie]); + ResetCooldownMeeting = BooleanOptionItem.Create(Id + 16, "ReverieResetCooldownMeeting", false, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Reverie]); ConvertedReverieRogue = BooleanOptionItem.Create(Id + 17, "ConvertedReverieKillAll", true, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Reverie]); } public override void Init() { + playerIdList.Clear(); NowCooldown.Clear(); } public override void Add(byte playerId) { + playerIdList.Add(playerId); NowCooldown.TryAdd(playerId, DefaultKillCooldown.GetFloat()); } public override void Remove(byte playerId) { + playerIdList.Remove(playerId); NowCooldown.Remove(playerId); } public override void OnReportDeadBody(PlayerControl HES, NetworkedPlayerInfo HIM) @@ -77,7 +80,7 @@ public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl t float kcd; if ((!target.GetCustomRole().IsCrewmate() && !target.Is(CustomRoles.Trickster)) || (ConvertedReverieRogue.GetBool() && killer.GetCustomSubRoles().Any(subrole => subrole.IsConverted() || subrole == CustomRoles.Madmate))) // if killed non crew or if converted - kcd = NowCooldown[killer.PlayerId] - ReduceKillCooldown.GetFloat(); + kcd = NowCooldown[killer.PlayerId] - ReduceKillCooldown.GetFloat(); else kcd = NowCooldown[killer.PlayerId] + IncreaseKillCooldown.GetFloat(); NowCooldown[killer.PlayerId] = Math.Clamp(kcd, MinKillCooldown.GetFloat(), MaxKillCooldown.GetFloat()); killer.ResetKillCooldown(); @@ -89,4 +92,4 @@ public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl t } return true; } -} +} \ No newline at end of file diff --git a/Roles/Crewmate/Sheriff.cs b/Roles/Crewmate/Sheriff.cs index d20aec8c6..062f6c550 100644 --- a/Roles/Crewmate/Sheriff.cs +++ b/Roles/Crewmate/Sheriff.cs @@ -8,11 +8,10 @@ namespace TOHE.Roles.Crewmate; internal class Sheriff : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Sheriff; private const int Id = 11200; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Sheriff); public override bool IsDesyncRole => true; - public override CustomRoles ThisRoleBase => CustomRoles.Impostor; + public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateKilling; //==================================================================\\ @@ -40,7 +39,6 @@ internal class Sheriff : RoleBase private static readonly Dictionary KillTargetOptions = []; - [Obfuscation(Exclude = true)] private enum KillOptionList { SheriffCanKillAll, @@ -134,6 +132,7 @@ public static bool CanBeKilledBySheriff(PlayerControl player) var cRole = player.GetCustomRole(); var subRole = player.GetCustomSubRoles(); bool CanKill = false; + foreach (var SubRoleTarget in subRole) { if (SubRoleTarget == CustomRoles.Madmate) @@ -156,7 +155,6 @@ public static bool CanBeKilledBySheriff(PlayerControl player) CanKill = false; } - return cRole switch { CustomRoles.Trickster => false, @@ -169,9 +167,10 @@ var r when cRole.IsTNA() => false, } }; } + public override void SetAbilityButtonText(HudManager hud, byte id) { hud.KillButton.OverrideText(GetString("SheriffKillButtonText")); } public override Sprite GetKillButtonSprite(PlayerControl player, bool shapeshifting) => CustomButton.Get("Kill"); -} +} \ No newline at end of file diff --git a/Roles/Crewmate/Snitch.cs b/Roles/Crewmate/Snitch.cs index adc460c11..e8343a780 100644 --- a/Roles/Crewmate/Snitch.cs +++ b/Roles/Crewmate/Snitch.cs @@ -1,19 +1,18 @@ using Hazel; -using InnerNet; using UnityEngine; -using static TOHE.Options; using static TOHE.Translator; +using static TOHE.Options; +using InnerNet; namespace TOHE.Roles.Crewmate; internal class Snitch : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Snitch; private const int Id = 9500; private static readonly HashSet playerIdList = []; public static bool HasEnabled => playerIdList.Any(); - + public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateSupport; //==================================================================\\ @@ -71,8 +70,7 @@ public override void Init() public override void Add(byte playerId) { - if (!playerIdList.Contains(playerId)) - playerIdList.Add(playerId); + playerIdList.Add(playerId); IsExposed[playerId] = false; IsComplete[playerId] = false; @@ -96,8 +94,8 @@ private static bool GetExpose(PlayerControl pc) } private static bool IsSnitchTarget(PlayerControl target) - => HasEnabled && (target.Is(Custom_Team.Impostor) && !target.Is(CustomRoles.Trickster) || (target.IsNeutralKiller() && CanFindNeutralKiller) || (target.IsNeutralApocalypse() && CanFindNeutralApocalypse) || (target.Is(CustomRoles.Madmate) && CanFindMadmate) || (target.Is(CustomRoles.Rascal) && CanFindMadmate)); - + => HasEnabled && (target.Is(Custom_Team.Impostor) && !target.Is(CustomRoles.Trickster) || (target.IsNeutralKiller() && CanFindNeutralKiller) || (target.IsNeutralApocalypse() && CanFindNeutralApocalypse)|| (target.Is(CustomRoles.Madmate) && CanFindMadmate) || (target.Is(CustomRoles.Rascal) && CanFindMadmate)); + private void CheckTask(PlayerControl snitch) { if (!snitch.IsAlive() || snitch.Is(CustomRoles.Madmate)) return; @@ -177,7 +175,7 @@ public override void ReceiveRPC(MessageReader reader, PlayerControl pc) foreach (var target in Main.AllAlivePlayerControls) { if (!IsSnitchTarget(target)) continue; - + var targetId = target.PlayerId; if (!TargetList.Contains(targetId)) @@ -237,7 +235,6 @@ public override string GetSuffixOthers(PlayerControl seer, PlayerControl target, public override bool OnRoleGuess(bool isUI, PlayerControl target, PlayerControl pc, CustomRoles role, ref bool guesserSuicide) { - if (role != CustomRoles.Snitch) return false; if (target.GetPlayerTaskState().IsTaskFinished) { pc.ShowInfoMessage(isUI, GetString("EGGuessSnitchTaskDone")); diff --git a/Roles/Crewmate/Spiritualist.cs b/Roles/Crewmate/Spiritualist.cs index 5b9eac62b..3de667a61 100644 --- a/Roles/Crewmate/Spiritualist.cs +++ b/Roles/Crewmate/Spiritualist.cs @@ -7,8 +7,10 @@ namespace TOHE.Roles.Crewmate; internal class Spiritualist : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Spiritualist; private const int Id = 9600; + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateSupport; //==================================================================\\ @@ -30,18 +32,21 @@ public override void SetupCustomOption() } public override void Init() { + playerIdList.Clear(); LastGhostArrowShowTime.Clear(); ShowGhostArrowUntil.Clear(); SpiritualistTarget = new(); } public override void Add(byte playerId) { + playerIdList.Add(playerId); SpiritualistTarget = byte.MaxValue; LastGhostArrowShowTime.Add(playerId, 0); ShowGhostArrowUntil.Add(playerId, 0); } public override void Remove(byte playerId) { + playerIdList.Remove(playerId); LastGhostArrowShowTime.Remove(playerId); ShowGhostArrowUntil.Remove(playerId); } @@ -73,34 +78,37 @@ public override void OnReportDeadBody(PlayerControl reported, NetworkedPlayerInf public override void AfterMeetingTasks() { - PlayerControl player = _Player; - - if (!player || !player.IsAlive()) return; - - LastGhostArrowShowTime[player.PlayerId] = 0; - ShowGhostArrowUntil[player.PlayerId] = 0; - - PlayerControl target = Main.AllPlayerControls.FirstOrDefault(a => a.PlayerId == SpiritualistTarget); - - if (target == null) return; - - TargetArrow.Add(player.PlayerId, target.PlayerId); - - var writer = CustomRpcSender.Create("SpiritualistSendMessage", SendOption.None); - writer.StartMessage(target.GetClientId()); - writer.StartRpc(target.NetId, (byte)RpcCalls.SetName) - .Write(target.Data.NetId) - .Write(GetString("SpiritualistNoticeTitle")) - .EndRpc(); - writer.StartRpc(target.NetId, (byte)RpcCalls.SendChat) - .Write(GetString("SpiritualistNoticeMessage")) - .EndRpc(); - writer.StartRpc(target.NetId, (byte)RpcCalls.SetName) - .Write(target.Data.NetId) - .Write(target.Data.PlayerName) - .EndRpc(); - writer.EndMessage(); - writer.SendMessage(); + foreach (var spiritualist in playerIdList) + { + PlayerControl player = Main.AllPlayerControls.FirstOrDefault(a => a.PlayerId == spiritualist); + + if (!player.IsAlive()) continue; + + LastGhostArrowShowTime[spiritualist] = 0; + ShowGhostArrowUntil[spiritualist] = 0; + + PlayerControl target = Main.AllPlayerControls.FirstOrDefault(a => a.PlayerId == SpiritualistTarget); + + if (target == null) continue; + + TargetArrow.Add(spiritualist, target.PlayerId); + + var writer = CustomRpcSender.Create("SpiritualistSendMessage", SendOption.None); + writer.StartMessage(target.GetClientId()); + writer.StartRpc(target.NetId, (byte)RpcCalls.SetName) + .Write(target.Data.NetId) + .Write(GetString("SpiritualistNoticeTitle")) + .EndRpc(); + writer.StartRpc(target.NetId, (byte)RpcCalls.SendChat) + .Write(GetString("SpiritualistNoticeMessage")) + .EndRpc(); + writer.StartRpc(target.NetId, (byte)RpcCalls.SetName) + .Write(target.Data.NetId) + .Write(target.Data.PlayerName) + .EndRpc(); + writer.EndMessage(); + writer.SendMessage(); + } } public override string GetSuffix(PlayerControl seer, PlayerControl target = null, bool isForMeeting = false) @@ -110,7 +118,7 @@ public override string GetSuffix(PlayerControl seer, PlayerControl target = null if (GameStates.IsMeeting) return string.Empty; if (SpiritualistTarget != byte.MaxValue && ShowArrow(seer.PlayerId)) { - return Utils.ColorString(seer.GetRoleColor(), TargetArrow.GetArrows(seer, SpiritualistTarget)); + return Utils.ColorString(seer.GetRoleColor(), TargetArrow.GetArrows(seer, SpiritualistTarget)); } return string.Empty; } @@ -120,11 +128,11 @@ public static void RemoveTarget(byte player) if (SpiritualistTarget != player) return; if (AmongUsClient.Instance.AmHost) - foreach (var spiritualist in Main.AllPlayerControls.Where(x => x.Is(CustomRoles.Spiritualist)).Select(x => x.PlayerId).ToList()) + foreach (var spiritualist in playerIdList) { TargetArrow.Remove(spiritualist, SpiritualistTarget); } SpiritualistTarget = byte.MaxValue; } -} +} \ No newline at end of file diff --git a/Roles/Crewmate/Spy.cs b/Roles/Crewmate/Spy.cs index a501ccafa..24585eee6 100644 --- a/Roles/Crewmate/Spy.cs +++ b/Roles/Crewmate/Spy.cs @@ -1,5 +1,4 @@ using Hazel; -using InnerNet; using System; using UnityEngine; using static TOHE.Options; @@ -10,8 +9,10 @@ namespace TOHE.Roles.Crewmate; internal class Spy : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Spy; private const int Id = 9700; + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateSupport; //==================================================================\\ @@ -21,12 +22,12 @@ internal class Spy : RoleBase private static OptionItem SpyAbilityUseGainWithEachTaskCompleted; private static OptionItem SpyInteractionBlocked; - private readonly Dictionary SpyRedNameList = []; + private static readonly Dictionary SpyRedNameList = []; private static bool change = false; public override void SetupCustomOption() { - SetupRoleOptions(Id, TabGroup.CrewmateRoles, CustomRoles.Spy); + SetupSingleRoleOptions(Id, TabGroup.CrewmateRoles, CustomRoles.Spy, 1); UseLimitOpt = IntegerOptionItem.Create(Id + 10, "AbilityUseLimit", new(1, 20, 1), 1, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Spy]) .SetValueFormat(OptionFormat.Times); SpyRedNameDur = FloatOptionItem.Create(Id + 11, "SpyRedNameDur", new(0f, 70f, 1f), 3f, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Spy]) @@ -34,48 +35,40 @@ public override void SetupCustomOption() SpyAbilityUseGainWithEachTaskCompleted = FloatOptionItem.Create(Id + 12, "AbilityUseGainWithEachTaskCompleted", new(0f, 5f, 0.1f), 0.5f, TabGroup.CrewmateRoles, false) .SetParent(CustomRoleSpawnChances[CustomRoles.Spy]) .SetValueFormat(OptionFormat.Times); - SpyInteractionBlocked = BooleanOptionItem.Create(Id + 13, "SpyInteractionBlocked", true, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Spy]).SetHidden(true); + SpyInteractionBlocked = BooleanOptionItem.Create(Id + 13, "SpyInteractionBlocked", true, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Spy]); } public override void Init() { + playerIdList.Clear(); SpyRedNameList.Clear(); change = false; } public override void Add(byte playerId) { + playerIdList.Add(playerId); AbilityLimit = UseLimitOpt.GetInt(); - - if (!SpyInteractionBlocked.GetBool()) - { - SpyInteractionBlocked.SetValue(1, false); - } } public override void Remove(byte playerId) { - + playerIdList.Remove(playerId); } - public void SendRPC(byte susId) + public static void SendRPC(byte susId) { - MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.SyncRoleSkill, SendOption.Reliable, -1); - writer.WriteNetObject(_Player); - writer.Write((byte)1); + MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.SpyRedNameSync, SendOption.Reliable, -1); writer.Write(susId); writer.Write(SpyRedNameList[susId].ToString()); AmongUsClient.Instance.FinishRpcImmediately(writer); } - public void SendRPC(byte susId, bool changeColor) + public static void SendRPC(byte susId, bool changeColor) { - MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.SyncRoleSkill, SendOption.Reliable, -1); - writer.WriteNetObject(_Player); - writer.Write((byte)2); + MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.SpyRedNameRemove, SendOption.Reliable, -1); writer.Write(susId); writer.Write(changeColor); Logger.Info($"RPC to remove player {susId} from red name list and change `change` to {changeColor}", "Spy"); AmongUsClient.Instance.FinishRpcImmediately(writer); } - public override void ReceiveRPC(MessageReader reader, PlayerControl player) + public static void ReceiveRPC(MessageReader reader, bool isRemove = false) { - bool isRemove = reader.ReadByte() == 2; if (isRemove) { SpyRedNameList.Remove(reader.ReadByte()); @@ -96,15 +89,11 @@ public bool OnKillAttempt(PlayerControl killer, PlayerControl target) AbilityLimit -= 1; SendSkillRPC(); SpyRedNameList.TryAdd(killer.PlayerId, GetTimeStamp()); - SendRPC(killer.PlayerId); - if (SpyInteractionBlocked.GetBool()) - { - killer.SetKillCooldown(time: 10f, target, forceAnime: true); - NotifyRoles(SpecifySeer: target, ForceLoop: true); - killer.ResetKillCooldown(); - killer.SyncSettings(); - return false; - } + SendRPC(killer.PlayerId); + if (SpyInteractionBlocked.GetBool()) + killer.SetKillCooldown(time: 10f); + NotifyRoles(SpecifySeer: target, ForceLoop: true); + return false; } return true; } @@ -114,7 +103,7 @@ public override bool OnCheckMurderAsTarget(PlayerControl killer, PlayerControl t public override void OnFixedUpdate(PlayerControl player, bool lowLoad, long nowTime) { if (lowLoad || !SpyRedNameList.Any()) return; - + change = false; foreach (var x in SpyRedNameList) { @@ -161,4 +150,4 @@ public override string GetProgressText(byte playerId, bool comms) return sb; } public override string PlayerKnowTargetColor(PlayerControl seer, PlayerControl target) => (seer.Is(CustomRoles.Spy) && SpyRedNameList.ContainsKey(target.PlayerId)) ? "#BA4A00" : ""; -} +} \ No newline at end of file diff --git a/Roles/Crewmate/SuperStar.cs b/Roles/Crewmate/SuperStar.cs index 485dac8e2..acf5a1796 100644 --- a/Roles/Crewmate/SuperStar.cs +++ b/Roles/Crewmate/SuperStar.cs @@ -1,14 +1,16 @@ using static TOHE.Options; -using static TOHE.Translator; using static TOHE.Utils; +using static TOHE.Translator; namespace TOHE.Roles.Crewmate; internal class SuperStar : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.SuperStar; private const int Id = 7150; + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateBasic; //==================================================================\\ @@ -21,6 +23,14 @@ public override void SetupCustomOption() EveryOneKnowSuperStar = BooleanOptionItem.Create(7152, "EveryOneKnowSuperStar", true, TabGroup.CrewmateRoles, false) .SetParent(CustomRoleSpawnChances[CustomRoles.SuperStar]); } + public override void Init() + { + playerIdList.Clear(); + } + public override void Add(byte playerId) + { + playerIdList.Add(playerId); + } public override string GetMarkOthers(PlayerControl seer, PlayerControl seen, bool isForMeeting = false) => seen.Is(CustomRoles.SuperStar) && (seer.PlayerId == seen.PlayerId || EveryOneKnowSuperStar.GetBool()) ? ColorString(GetRoleColor(CustomRoles.SuperStar), "★") : string.Empty; diff --git a/Roles/Crewmate/Swapper.cs b/Roles/Crewmate/Swapper.cs index a9064ecc5..54971de43 100644 --- a/Roles/Crewmate/Swapper.cs +++ b/Roles/Crewmate/Swapper.cs @@ -1,12 +1,12 @@ using Hazel; using System; -using System.Text; using System.Text.RegularExpressions; using TOHE.Modules.ChatManager; using TOHE.Roles.Core; using UnityEngine; -using static TOHE.CheckForEndVotingPatch; +using System.Text; using static TOHE.Translator; +using static TOHE.CheckForEndVotingPatch; using static TOHE.Utils; namespace TOHE.Roles.Crewmate; @@ -14,7 +14,6 @@ namespace TOHE.Roles.Crewmate; internal class Swapper : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Swapper; private const int Id = 12400; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Swapper); public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; @@ -69,7 +68,7 @@ public override string GetProgressText(byte playerId, bool comms) public override string NotifyPlayerName(PlayerControl seer, PlayerControl target, string TargetPlayerName = "", bool IsForMeeting = false) => IsForMeeting && seer.IsAlive() && target.IsAlive() ? Utils.ColorString(Utils.GetRoleColor(CustomRoles.Swapper), target.PlayerId.ToString()) + " " + TargetPlayerName : string.Empty; - + public override string PVANameText(PlayerVoteArea pva, PlayerControl seer, PlayerControl target) => seer.IsAlive() && target.IsAlive() ? Utils.ColorString(Utils.GetRoleColor(CustomRoles.Swapper), target.PlayerId.ToString()) + " " + pva.NameText.text : string.Empty; @@ -364,7 +363,7 @@ private void SwapperOnClick(byte playerId, MeetingHud __instance) Logger.Msg($"Click: ID {playerId}", "Swapper UI"); var pc = playerId.GetPlayer(); if (pc == null || !pc.IsAlive() || !GameStates.IsVoting) return; - + if (AmongUsClient.Instance.AmHost) SwapMsg(PlayerControl.LocalPlayer, $"/sw {playerId}", true); else SendSwapRPC(playerId); @@ -420,10 +419,9 @@ public void CreateSwapperButton(MeetingHud __instance) renderer.sprite = CustomButton.Get("SwapNo"); button.OnClick.RemoveAllListeners(); - button.OnClick.AddListener((UnityEngine.Events.UnityAction)(() => - { - SwapperOnClick(pva.TargetPlayerId, __instance); + button.OnClick.AddListener((UnityEngine.Events.UnityAction)(() => { + SwapperOnClick(pva.TargetPlayerId, __instance); })); } } -} +} \ No newline at end of file diff --git a/Roles/Crewmate/TaskManager.cs b/Roles/Crewmate/TaskManager.cs index e7e9c4948..f50b6c0a7 100644 --- a/Roles/Crewmate/TaskManager.cs +++ b/Roles/Crewmate/TaskManager.cs @@ -1,15 +1,17 @@ using System.Text; using UnityEngine; -using static TOHE.Options; using static TOHE.Utils; +using static TOHE.Options; namespace TOHE.Roles.Crewmate; internal class TaskManager : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.TaskManager; private const int Id = 7200; + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateBasic; //==================================================================\\ @@ -18,6 +20,14 @@ public override void SetupCustomOption() { SetupRoleOptions(Id, TabGroup.CrewmateRoles, CustomRoles.TaskManager); } + public override void Init() + { + playerIdList.Clear(); + } + public override void Add(byte playerId) + { + playerIdList.Add(playerId); + } public override string GetProgressText(byte PlayerId, bool comms) { var ProgressText = new StringBuilder(); diff --git a/Roles/Crewmate/Telecommunication.cs b/Roles/Crewmate/Telecommunication.cs index f54860715..e2aa49362 100644 --- a/Roles/Crewmate/Telecommunication.cs +++ b/Roles/Crewmate/Telecommunication.cs @@ -1,24 +1,26 @@ -using AmongUs.GameOptions; using System; using System.Text; using UnityEngine; -using static TOHE.Translator; using static TOHE.Utils; +using static TOHE.Translator; +using AmongUs.GameOptions; namespace TOHE.Roles.Crewmate; internal class Telecommunication : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Telecommunication; private const int Id = 12500; + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); + public override CustomRoles ThisRoleBase => CanVent.GetBool() ? CustomRoles.Engineer : CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmatePower; //==================================================================\\ private static OptionItem CanCheckCamera; private static OptionItem CanVent; - + private static bool IsAdminWatch; private static bool IsVitalWatch; private static bool IsDoorLogWatch; @@ -32,11 +34,20 @@ public override void SetupCustomOption() } public override void Init() { + playerIdList.Clear(); IsAdminWatch = false; IsVitalWatch = false; IsDoorLogWatch = false; IsCameraWatch = false; } + public override void Add(byte playerId) + { + playerIdList.Add(playerId); + } + public override void Remove(byte playerId) + { + playerIdList.Remove(playerId); + } public static bool CanUseVent() => CanVent.GetBool(); @@ -132,7 +143,7 @@ public override void OnFixedUpdate(PlayerControl player, bool lowLoad, long nowT if (isChange) { - foreach (var pc in _playerIdList) + foreach (var pc in playerIdList) { var antiAdminer = pc.GetPlayer(); NotifyRoles(SpecifySeer: antiAdminer, ForceLoop: false); @@ -151,4 +162,4 @@ public override string GetSuffix(PlayerControl seer, PlayerControl seen = null, return sb.ToString(); } -} +} \ No newline at end of file diff --git a/Roles/Crewmate/TimeManager.cs b/Roles/Crewmate/TimeManager.cs index 37a84a672..70cdec041 100644 --- a/Roles/Crewmate/TimeManager.cs +++ b/Roles/Crewmate/TimeManager.cs @@ -3,11 +3,10 @@ namespace TOHE.Roles.Crewmate; internal class TimeManager : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.TimeManager; private const int Id = 9800; private static readonly HashSet playerIdList = []; public static bool HasEnabled => playerIdList.Any(); - + public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateSupport; //==================================================================\\ @@ -33,8 +32,7 @@ public override void Init() } public override void Add(byte playerId) { - if (!playerIdList.Contains(playerId)) - playerIdList.Add(playerId); + playerIdList.Add(playerId); } public override void Remove(byte playerId) { @@ -57,4 +55,4 @@ public static int TotalIncreasedMeetingTime() Logger.Info($"{sec}second", "TimeManager.TotalIncreasedMeetingTime"); return sec; } -} +} \ No newline at end of file diff --git a/Roles/Crewmate/TimeMaster.cs b/Roles/Crewmate/TimeMaster.cs index f516cf33e..63476e346 100644 --- a/Roles/Crewmate/TimeMaster.cs +++ b/Roles/Crewmate/TimeMaster.cs @@ -1,23 +1,21 @@ using AmongUs.GameOptions; using System; using System.Text; -using TOHE.Roles.Core; using UnityEngine; using static TOHE.Options; -using static TOHE.Translator; using static TOHE.Utils; +using static TOHE.Translator; +using TOHE.Roles.Core; namespace TOHE.Roles.Crewmate; internal class TimeMaster : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.TimeMaster; private const int Id = 9900; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.TimeMaster); public override CustomRoles ThisRoleBase => CustomRoles.Engineer; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateSupport; - public override bool BlockMoveInVent(PlayerControl pc) => true; //==================================================================\\ private static OptionItem TimeMasterSkillCooldown; @@ -38,7 +36,7 @@ public override void SetupCustomOption() .SetValueFormat(OptionFormat.Seconds); TimeMasterMaxUses = IntegerOptionItem.Create(Id + 12, "TimeMasterMaxUses", new(0, 20, 1), 1, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.TimeMaster]) .SetValueFormat(OptionFormat.Times); - TimeMasterAbilityUseGainWithEachTaskCompleted = FloatOptionItem.Create(Id + 13, "AbilityUseGainWithEachTaskCompleted", new(0f, 5f, 0.1f), 1f, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.TimeMaster]) + TimeMasterAbilityUseGainWithEachTaskCompleted = FloatOptionItem.Create(Id+ 13, "AbilityUseGainWithEachTaskCompleted", new(0f, 5f, 0.1f), 1f, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.TimeMaster]) .SetValueFormat(OptionFormat.Times); } public override void Init() diff --git a/Roles/Crewmate/Tracefinder.cs b/Roles/Crewmate/Tracefinder.cs index d939a404c..40fe8b566 100644 --- a/Roles/Crewmate/Tracefinder.cs +++ b/Roles/Crewmate/Tracefinder.cs @@ -9,8 +9,10 @@ namespace TOHE.Roles.Crewmate; internal class Tracefinder : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Tracefinder; private const int Id = 7300; + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Scientist; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateBasic; //==================================================================\\ @@ -36,8 +38,14 @@ public override void SetupCustomOption() .SetParent(CustomRoleSpawnChances[CustomRoles.Tracefinder]) .SetValueFormat(OptionFormat.Seconds); } + public override void Init() + { + playerIdList.Clear(); + } public override void Add(byte playerId) { + playerIdList.Add(playerId); + if (AmongUsClient.Instance.AmHost) { CustomRoleManager.CheckDeadBodyOthers.Add(CheckDeadBody); @@ -45,7 +53,7 @@ public override void Add(byte playerId) } public override void Remove(byte playerId) { - CustomRoleManager.CheckDeadBodyOthers.Remove(CheckDeadBody); + playerIdList.Remove(playerId); } public override void ApplyGameOptions(IGameOptions opt, byte playerid) { @@ -55,11 +63,13 @@ public override void ApplyGameOptions(IGameOptions opt, byte playerid) public override void OnReportDeadBody(PlayerControl GODZILLA_VS, NetworkedPlayerInfo KINGKONG) { - if (_Player) - LocateArrow.RemoveAllTarget(_Player.PlayerId); + foreach (var apc in playerIdList) + { + LocateArrow.RemoveAllTarget(apc); + } } - public void CheckDeadBody(PlayerControl killer, PlayerControl target, bool inMeeting) + public static void CheckDeadBody(PlayerControl killer, PlayerControl target, bool inMeeting) { if (inMeeting || target.IsDisconnected()) return; @@ -72,13 +82,15 @@ public void CheckDeadBody(PlayerControl killer, PlayerControl target, bool inMee var tempPositionTarget = target.transform.position; - _ = new LateTask(() => - { + _ = new LateTask(() => { if (!GameStates.IsMeeting && GameStates.IsInTask) { - var player = _Player; - if (player == null || !player.IsAlive()) return; - LocateArrow.Add(player.PlayerId, tempPositionTarget); + foreach (var pc in playerIdList) + { + var player = Utils.GetPlayerById(pc); + if (player == null || !player.IsAlive()) continue; + LocateArrow.Add(pc, tempPositionTarget); + } } }, delay, "Get Arrow Tracefinder"); } @@ -87,4 +99,4 @@ public override string GetSuffix(PlayerControl seer, PlayerControl target, bool if (isForMeeting || seer.PlayerId != target.PlayerId) return string.Empty; return Utils.ColorString(Color.white, LocateArrow.GetArrows(seer)); } -} +} \ No newline at end of file diff --git a/Roles/Crewmate/Transporter.cs b/Roles/Crewmate/Transporter.cs index 5c68a3612..9f2b3f338 100644 --- a/Roles/Crewmate/Transporter.cs +++ b/Roles/Crewmate/Transporter.cs @@ -7,8 +7,10 @@ namespace TOHE.Roles.Crewmate; internal class Transporter : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Transporter; private const int Id = 7400; + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateBasic; //==================================================================\\ @@ -23,6 +25,14 @@ public override void SetupCustomOption() .SetValueFormat(OptionFormat.Times); OverrideTasksData.Create(Id + 10, TabGroup.CrewmateRoles, CustomRoles.Transporter); } + public override void Init() + { + playerIdList.Clear(); + } + public override void Add(byte playerId) + { + playerIdList.Add(playerId); + } public override bool OnTaskComplete(PlayerControl player, int completedTaskCount, int totalTaskCount) { if (player.IsAlive() && (completedTaskCount + 1) <= TransporterTeleportMax.GetInt()) diff --git a/Roles/Crewmate/Ventguard.cs b/Roles/Crewmate/Ventguard.cs index e42929096..b66a95ed3 100644 --- a/Roles/Crewmate/Ventguard.cs +++ b/Roles/Crewmate/Ventguard.cs @@ -1,8 +1,8 @@ using AmongUs.GameOptions; using System; using System.Text; -using TOHE.Roles.Core; using UnityEngine; +using TOHE.Roles.Core; using static TOHE.Translator; namespace TOHE.Roles.Crewmate; @@ -10,12 +10,10 @@ namespace TOHE.Roles.Crewmate; internal class Ventguard : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Ventguard; private const int Id = 30000; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Ventguard); public override CustomRoles ThisRoleBase => CustomRoles.Engineer; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateSupport; - public override bool BlockMoveInVent(PlayerControl pc) => true; //==================================================================\\ private static OptionItem MaxGuards; @@ -106,20 +104,6 @@ public override void AfterMeetingTasks() } BlockedVents.Clear(); } - else if (BlockedVents.Any()) - { - foreach (var ventId in BlockedVents) - { - foreach (var player in Main.AllPlayerControls) - { - if (!player.IsAlive()) continue; - if (player.NotUnlockVent(ventId)) continue; - if (player.PlayerId != _Player?.PlayerId && BlockDoesNotAffectCrew.GetBool() && player.Is(Custom_Team.Crewmate)) continue; - - CustomRoleManager.BlockedVentsList[player.PlayerId].Add(ventId); - } - } - } } public override string GetProgressText(byte playerId, bool comms) { diff --git a/Roles/Crewmate/Veteran.cs b/Roles/Crewmate/Veteran.cs index a32b70237..097f55cef 100644 --- a/Roles/Crewmate/Veteran.cs +++ b/Roles/Crewmate/Veteran.cs @@ -1,24 +1,22 @@ using AmongUs.GameOptions; using System; using System.Text; -using TOHE.Modules; -using TOHE.Roles.Core; using UnityEngine; +using TOHE.Modules; using static TOHE.Options; using static TOHE.Translator; using static TOHE.Utils; +using TOHE.Roles.Core; namespace TOHE.Roles.Crewmate; internal class Veteran : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Veteran; private const int Id = 11350; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Veteran); public override CustomRoles ThisRoleBase => CustomRoles.Engineer; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateKilling; - public override bool BlockMoveInVent(PlayerControl pc) => true; //==================================================================\\ private static OptionItem VeteranSkillCooldown; @@ -58,7 +56,7 @@ public override bool OnTaskComplete(PlayerControl player, int completedTaskCount if (player.IsAlive()) AbilityLimit += VeteranAbilityUseGainWithEachTaskCompleted.GetFloat(); SendSkillRPC(); - + return true; } public override bool OnCheckMurderAsTarget(PlayerControl killer, PlayerControl target) @@ -140,7 +138,7 @@ public override bool CheckBootFromVent(PlayerPhysics physics, int ventId) => AbilityLimit < 1; public override void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo target) => VeteranInProtect.Clear(); - + public override string GetProgressText(byte playerId, bool comms) { var ProgressText = new StringBuilder(); diff --git a/Roles/Crewmate/Vigilante.cs b/Roles/Crewmate/Vigilante.cs index 0228d350f..f36691c3b 100644 --- a/Roles/Crewmate/Vigilante.cs +++ b/Roles/Crewmate/Vigilante.cs @@ -1,13 +1,14 @@ -using static TOHE.Options; -using static TOHE.Translator; +using static TOHE.Translator; +using static TOHE.Options; namespace TOHE.Roles.Crewmate; internal class Vigilante : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Vigilante; private const int Id = 11400; + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); public override bool IsDesyncRole => true; public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateKilling; @@ -22,6 +23,14 @@ public override void SetupCustomOption() .SetParent(CustomRoleSpawnChances[CustomRoles.Vigilante]) .SetValueFormat(OptionFormat.Seconds); } + public override void Init() + { + playerIdList.Clear(); + } + public override void Add(byte playerId) + { + playerIdList.Add(playerId); + } public override void SetKillCooldown(byte id) => Main.AllPlayerKillCooldown[id] = VigilanteKillCooldown.GetFloat(); public override bool CanUseKillButton(PlayerControl pc) => true; public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) diff --git a/Roles/Crewmate/Witness.cs b/Roles/Crewmate/Witness.cs index 3a2c771cd..7930b63e4 100644 --- a/Roles/Crewmate/Witness.cs +++ b/Roles/Crewmate/Witness.cs @@ -9,8 +9,9 @@ namespace TOHE.Roles.Crewmate; internal class Witness : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Witness; private const int Id = 10100; + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); public override bool IsDesyncRole => true; public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateSupport; @@ -27,8 +28,14 @@ public override void SetupCustomOption() WitnessTime = IntegerOptionItem.Create(Id + 11, "WitnessTime", new(1, 30, 1), 10, TabGroup.CrewmateRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Witness]) .SetValueFormat(OptionFormat.Seconds); } + public override void Init() + { + playerIdList.Clear(); + } public override void Add(byte playerId) { + playerIdList.Add(playerId); + if (AmongUsClient.Instance.AmHost) { CustomRoleManager.OnFixedUpdateOthers.Add(OnFixedUpdateLowLoadOthers); diff --git a/Roles/Double/Mini.cs b/Roles/Double/Mini.cs index 68821fc92..3b4c288c4 100644 --- a/Roles/Double/Mini.cs +++ b/Roles/Double/Mini.cs @@ -9,7 +9,6 @@ namespace TOHE.Roles.Double; internal class Mini : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Mini; private const int Id = 7000; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.EvilMini) || CustomRoleManager.HasEnabled(CustomRoles.NiceMini); public override CustomRoles ThisRoleBase => IsEvilMini ? CustomRoles.Impostor : CustomRoles.Crewmate; @@ -21,7 +20,6 @@ internal class Mini : RoleBase private static OptionItem CountMeetingTime; private static OptionItem EvilMiniSpawnChances; private static OptionItem CanBeEvil; - public static OptionItem CanGuessEvil; private static OptionItem UpDateAge; private static OptionItem MinorCD; private static OptionItem MajorCD; @@ -43,7 +41,6 @@ public override void SetupCustomOption() CanBeEvil = BooleanOptionItem.Create(Id + 106, "CanBeEvil", true, TabGroup.CrewmateRoles, false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Mini]); EvilMiniSpawnChances = IntegerOptionItem.Create(Id + 108, "EvilMiniSpawnChances", new(0, 100, 5), 50, TabGroup.CrewmateRoles, false).SetParent(CanBeEvil) .SetValueFormat(OptionFormat.Percent); - CanGuessEvil = BooleanOptionItem.Create(Id + 104, "EvilMiniCanBeGuessed", true, TabGroup.CrewmateRoles, false).SetParent(CanBeEvil); MinorCD = FloatOptionItem.Create(Id + 110, GeneralOption.KillCooldown, new(0f, 180f, 2.5f), 45f, TabGroup.CrewmateRoles, false).SetParent(CanBeEvil) .SetValueFormat(OptionFormat.Seconds); MajorCD = FloatOptionItem.Create(Id + 112, "MajorCooldown", new(0f, 180f, 2.5f), 15f, TabGroup.CrewmateRoles, false).SetParent(CanBeEvil) @@ -133,7 +130,7 @@ public void OnFixedUpdates(PlayerControl player) if (player.Is(CustomRoles.NiceMini)) player.RpcGuardAndKill(); - + /*Dont show guard animation for evil mini, this would simply stop them from murdering. Imagine reseting kill cool down every 20 seconds @@ -171,8 +168,7 @@ public override bool GuessCheck(bool isUI, PlayerControl guesser, PlayerControl } public override bool OnRoleGuess(bool isUI, PlayerControl target, PlayerControl guesser, CustomRoles role, ref bool guesserSuicide) { - if (role is not CustomRoles.NiceMini or CustomRoles.EvilMini) return false; - if (Age < 18 && (target.Is(CustomRoles.NiceMini) || !CanGuessEvil.GetBool() && target.Is(CustomRoles.EvilMini))) + if (target.Is(CustomRoles.NiceMini) && Age < 18) { guesser.ShowInfoMessage(isUI, GetString("GuessMini")); return true; @@ -220,4 +216,4 @@ public override void CheckExile(NetworkedPlayerInfo exiled, ref bool DecidedWinn public override string GetMarkOthers(PlayerControl seer, PlayerControl target = null, bool isForMeeting = false) => EveryoneCanKnowMini.GetBool() && (target.Is(CustomRoles.NiceMini) || target.Is(CustomRoles.EvilMini)) ? ColorString(GetRoleColor(CustomRoles.Mini), Age != 18 && UpDateAge.GetBool() ? $"({Age})" : string.Empty) : string.Empty; -} +} \ No newline at end of file diff --git a/Roles/Impostor/Anonymous.cs b/Roles/Impostor/Anonymous.cs index 695b37095..73bbfb7e8 100644 --- a/Roles/Impostor/Anonymous.cs +++ b/Roles/Impostor/Anonymous.cs @@ -10,7 +10,6 @@ namespace TOHE.Roles.Impostor; internal class Anonymous : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Anonymous; private const int Id = 5300; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Anonymous); public override CustomRoles ThisRoleBase => CustomRoles.Shapeshifter; @@ -18,8 +17,9 @@ internal class Anonymous : RoleBase //==================================================================\\ public override Sprite GetAbilityButtonSprite(PlayerControl player, bool shapeshifting) => CustomButton.Get("Hack"); - private static OptionItem HackLimitOpt; - private static OptionItem KillCooldown; + public static OptionItem HackLimitOpt; + public static OptionItem KillCooldown; + private static readonly List DeadBodyList = []; @@ -38,6 +38,12 @@ public override void Init() public override void Add(byte playerId) { AbilityLimit = HackLimitOpt.GetInt(); + if (Main.PlayerStates[playerId].IsRandomizer) + { + + } + + base.Add(playerId); } public override void SetKillCooldown(byte id) => Main.AllPlayerKillCooldown[id] = KillCooldown.GetFloat(); public override void ApplyGameOptions(IGameOptions opt, byte playerId) @@ -90,4 +96,4 @@ public override void OnShapeshift(PlayerControl shapeshifter, PlayerControl ssTa else _ = new LateTask(() => ssTarget?.NoCheckStartMeeting(Utils.GetPlayerById(targetId)?.Data), 0.15f, "Anonymous Hacking Report"); } -} +} \ No newline at end of file diff --git a/Roles/Impostor/AntiAdminer.cs b/Roles/Impostor/AntiAdminer.cs index b6f5a3077..228db6101 100644 --- a/Roles/Impostor/AntiAdminer.cs +++ b/Roles/Impostor/AntiAdminer.cs @@ -1,8 +1,8 @@ using System; using System.Text; using UnityEngine; -using static TOHE.Translator; using static TOHE.Utils; +using static TOHE.Translator; namespace TOHE.Roles.Impostor; @@ -11,16 +11,15 @@ namespace TOHE.Roles.Impostor; internal class AntiAdminer : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.AntiAdminer; private const int Id = 2800; private static readonly HashSet playerIdList = []; public static bool HasEnabled => playerIdList.Any(); - + public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorSupport; //==================================================================\\ - private static OptionItem CanCheckCamera; + public static OptionItem CanCheckCamera; private static bool IsAdminWatch; private static bool IsVitalWatch; @@ -34,11 +33,20 @@ public override void SetupCustomOption() } public override void Init() { + playerIdList.Clear(); IsAdminWatch = false; IsVitalWatch = false; IsDoorLogWatch = false; IsCameraWatch = false; } + public override void Add(byte playerId) + { + playerIdList.Add(playerId); + } + public override void Remove(byte playerId) + { + playerIdList.Remove(playerId); + } private static int Count = 0; public override void OnFixedUpdate(PlayerControl player, bool lowLoad, long nowTime) @@ -128,8 +136,11 @@ public override void OnFixedUpdate(PlayerControl player, bool lowLoad, long nowT if (isChange) { - if (_Player) - NotifyRoles(SpecifySeer: _Player, ForceLoop: false); + foreach (var pc in playerIdList.ToArray()) + { + var antiAdminer = pc.GetPlayer(); + NotifyRoles(SpecifySeer: antiAdminer, ForceLoop: false); + } } } public override string GetSuffix(PlayerControl seer, PlayerControl seen, bool isForMeeting = false) @@ -144,4 +155,4 @@ public override string GetSuffix(PlayerControl seer, PlayerControl seen, bool is return sb.ToString(); } -} +} \ No newline at end of file diff --git a/Roles/Impostor/Arrogance.cs b/Roles/Impostor/Arrogance.cs index 3491d6974..aacb2b0d8 100644 --- a/Roles/Impostor/Arrogance.cs +++ b/Roles/Impostor/Arrogance.cs @@ -6,15 +6,17 @@ namespace TOHE.Roles.Impostor; internal class Arrogance : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Arrogance; private const int Id = 500; + public static HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorKilling; //==================================================================\\ - private static OptionItem DefaultKillCooldown; - private static OptionItem ReduceKillCooldown; - private static OptionItem MinKillCooldown; + public static OptionItem DefaultKillCooldown; + public static OptionItem ReduceKillCooldown; + public static OptionItem MinKillCooldown; public static OptionItem BardChance; private static readonly Dictionary NowCooldown = []; @@ -34,14 +36,17 @@ public override void SetupCustomOption() } public override void Init() { + playerIdList.Clear(); NowCooldown.Clear(); } public override void Add(byte playerId) { + playerIdList.Add(playerId); NowCooldown.TryAdd(playerId, DefaultKillCooldown.GetFloat()); } public override void Remove(byte playerId) { + playerIdList.Remove(playerId); NowCooldown.Remove(playerId); } public override void SetKillCooldown(byte id) => Main.AllPlayerKillCooldown[id] = NowCooldown[id]; @@ -53,4 +58,4 @@ public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl t return true; } -} +} \ No newline at end of file diff --git a/Roles/Impostor/Bard.cs b/Roles/Impostor/Bard.cs index e22de6c1b..c7bd83cd5 100644 --- a/Roles/Impostor/Bard.cs +++ b/Roles/Impostor/Bard.cs @@ -1,12 +1,22 @@ namespace TOHE.Roles.Impostor; -internal class Bard : RoleBase +internal class Bard: RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Bard; + public static readonly HashSet PlayerIds = []; + public static bool HasEnabled => PlayerIds.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorKilling; //==================================================================\\ + public override void Init() + { + PlayerIds.Clear(); + } + public override void Add(byte playerId) + { + PlayerIds.Add(playerId); + } public static bool CheckSpawn() { diff --git a/Roles/Impostor/Blackmailer.cs b/Roles/Impostor/Blackmailer.cs index 32460a166..67bba3ca5 100644 --- a/Roles/Impostor/Blackmailer.cs +++ b/Roles/Impostor/Blackmailer.cs @@ -10,18 +10,17 @@ namespace TOHE.Roles.Impostor; internal class Blackmailer : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Blackmailer; private const int Id = 24600; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Blackmailer); - + public override CustomRoles ThisRoleBase => CustomRoles.Shapeshifter; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorSupport; //==================================================================\\ - private static OptionItem SkillCooldown; - private static OptionItem ShowShapeshiftAnimationsOpt; + public static OptionItem SkillCooldown; + public static OptionItem ShowShapeshiftAnimationsOpt; - private static readonly Dictionary ForBlackmailer = []; // + public static readonly HashSet ForBlackmailer = []; public override void SetupCustomOption() { @@ -34,17 +33,6 @@ public override void Init() { ForBlackmailer.Clear(); } - public override void Remove(byte playerId) - { - foreach (var item in ForBlackmailer) - { - if (item.Value == playerId) - { - ForBlackmailer.Remove(item.Key); - SendRPC(); - } - } - } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.ShapeshifterCooldown = SkillCooldown.GetFloat(); @@ -63,16 +51,9 @@ public override void ReceiveRPC(MessageReader reader, PlayerControl NaN) var targetId = reader.ReadByte(); if (targetId == byte.MaxValue) - { ClearBlackmaile(false); - } else - { - if (!ForBlackmailer.ContainsKey(targetId)) - { - ForBlackmailer.Add(targetId, _Player.PlayerId); - } - } + ForBlackmailer.Add(targetId); } public override bool OnCheckShapeshift(PlayerControl blackmailer, PlayerControl target, ref bool resetCooldown, ref bool shouldAnimate) { @@ -82,13 +63,15 @@ public override bool OnCheckShapeshift(PlayerControl blackmailer, PlayerControl blackmailer.Notify(GetString("RejectShapeshift.AbilityWasUsed"), time: 2f); return false; } - private void DoBlackmaile(PlayerControl blackmailer, PlayerControl target) + public override void OnShapeshift(PlayerControl blackmailer, PlayerControl target, bool IsAnimate, bool shapeshifting) { - if (ForBlackmailer.ContainsKey(target.PlayerId)) + if (shapeshifting && IsAnimate) { - return; + DoBlackmaile(blackmailer, target); } - + } + private void DoBlackmaile(PlayerControl blackmailer, PlayerControl target) + { if (!target.IsAlive()) { blackmailer.Notify(Utils.ColorString(Utils.GetRoleColor(blackmailer.GetCustomRole()), GetString("TargetIsAlreadyDead"))); @@ -96,7 +79,7 @@ private void DoBlackmaile(PlayerControl blackmailer, PlayerControl target) } ClearBlackmaile(true); - ForBlackmailer.Add(target.PlayerId, _Player.PlayerId); + ForBlackmailer.Add(target.PlayerId); SendRPC(target.PlayerId); } @@ -113,8 +96,8 @@ private void ClearBlackmaile(bool sendRpc) ForBlackmailer.Clear(); if (sendRpc) SendRPC(); } - - public static bool CheckBlackmaile(PlayerControl player) => HasEnabled && GameStates.IsInGame && ForBlackmailer.ContainsKey(player.PlayerId); + + public static bool CheckBlackmaile(PlayerControl player) => HasEnabled && GameStates.IsInGame && ForBlackmailer.Contains(player.PlayerId); public override string GetMarkOthers(PlayerControl seer, PlayerControl target, bool isForMeeting = false) => isForMeeting && CheckBlackmaile(target) ? Utils.ColorString(Utils.GetRoleColor(CustomRoles.Blackmailer), "╳") : string.Empty; @@ -124,8 +107,8 @@ public override void OnOthersMeetingHudStart(PlayerControl pc) if (CheckBlackmaile(pc)) { var playername = pc.GetRealName(isMeeting: true); - if (Main.OvverideOutfit.TryGetValue(pc.PlayerId, out var realfit)) playername = realfit.name; + if (Main.OvverideOutfit.TryGetValue(pc.PlayerId, out var realfit)) playername = realfit.name; AddMsg(string.Format(string.Format(GetString("BlackmailerDead"), playername), byte.MaxValue, Utils.ColorString(Utils.GetRoleColor(CustomRoles.Blackmailer), GetString("BlackmaileKillTitle")))); } } -} +} \ No newline at end of file diff --git a/Roles/Impostor/Bomber.cs b/Roles/Impostor/Bomber.cs index 4693c4da8..6d82c18ad 100644 --- a/Roles/Impostor/Bomber.cs +++ b/Roles/Impostor/Bomber.cs @@ -1,16 +1,17 @@ using AmongUs.GameOptions; +using UnityEngine; using TOHE.Modules; using TOHE.Roles.Crewmate; -using UnityEngine; namespace TOHE.Roles.Impostor; internal class Bomber : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Bomber; private const int Id = 700; - + public static readonly HashSet Playerids = []; + public static bool HasEnabled => Playerids.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Shapeshifter; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorKilling; //==================================================================\\ @@ -43,6 +44,14 @@ public override void SetupCustomOption() BomberDiesInExplosion = BooleanOptionItem.Create(Id + 7, "BomberDiesInExplosion", true, TabGroup.ImpostorRoles, false) .SetParent(Options.CustomRoleSpawnChances[CustomRoles.Bomber]); } + public override void Init() + { + Playerids.Clear(); + } + public override void Add(byte playerId) + { + Playerids.Add(playerId); + } public override bool CanUseKillButton(PlayerControl pc) => BomberCanKill.GetBool() && pc.IsAlive(); public override void SetKillCooldown(byte id) { @@ -62,8 +71,6 @@ public override void UnShapeShiftButton(PlayerControl shapeshifter) Logger.Info("The bomb went off", playerRole.ToString()); CustomSoundsManager.RPCPlayCustomSoundAll("Boom"); - _ = new Explosion(5f, 0.5f, shapeshifter.GetCustomPosition()); - foreach (var target in Main.AllPlayerControls) { if (!target.IsModded()) target.KillFlash(); diff --git a/Roles/Impostor/BountyHunter.cs b/Roles/Impostor/BountyHunter.cs index dfaf2f59d..c4534ec5a 100644 --- a/Roles/Impostor/BountyHunter.cs +++ b/Roles/Impostor/BountyHunter.cs @@ -10,23 +10,25 @@ namespace TOHE.Roles.Impostor; internal class BountyHunter : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.BountyHunter; private const int Id = 800; + public static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Shapeshifter; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorKilling; //==================================================================\\ - private static OptionItem OptionTargetChangeTime; - private static OptionItem OptionSuccessKillCooldown; - private static OptionItem OptionFailureKillCooldown; - private static OptionItem OptionShowTargetArrow; + public static OptionItem OptionTargetChangeTime; + public static OptionItem OptionSuccessKillCooldown; + public static OptionItem OptionFailureKillCooldown; + public static OptionItem OptionShowTargetArrow; - private static float TargetChangeTime; - private static float SuccessKillCooldown; - private static float FailureKillCooldown; - private static bool ShowTargetArrow; + public static float TargetChangeTime; + public static float SuccessKillCooldown; + public static float FailureKillCooldown; + public static bool ShowTargetArrow; - private static Dictionary Targets = []; + public static Dictionary Targets = []; public static readonly Dictionary ChangeTimer = []; public override void SetupCustomOption() @@ -42,11 +44,15 @@ public override void SetupCustomOption() } public override void Init() { + playerIdList.Clear(); + Targets.Clear(); ChangeTimer.Clear(); } public override void Add(byte playerId) { + playerIdList.Add(playerId); + TargetChangeTime = OptionTargetChangeTime.GetFloat(); SuccessKillCooldown = OptionSuccessKillCooldown.GetFloat(); FailureKillCooldown = OptionFailureKillCooldown.GetFloat(); @@ -58,6 +64,11 @@ public override void Add(byte playerId) //CustomRoleManager.OnFixedUpdateLowLoadOthers.Add(OnFixedUpdateLowLoadOthers); } } + public override void Remove(byte playerId) + { + playerIdList.Remove(playerId); + } + private static void SendRPC(byte bountyId, byte targetId) { MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.SetBountyTarget, SendOption.Reliable, -1); @@ -86,7 +97,9 @@ public override bool OnCheckShapeshift(PlayerControl shapeshifter, PlayerControl return false; } - public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) +#pragma warning disable CS0114 // Member hides inherited member; missing override keyword + public static bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) +#pragma warning restore CS0114 // Member hides inherited member; missing override keyword { if (GetTarget(killer) == target.PlayerId) { @@ -105,7 +118,9 @@ public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl t return true; } public override void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo target) => ChangeTimer.Clear(); - public override void OnFixedUpdate(PlayerControl player, bool lowLoad, long nowTime) +#pragma warning disable CS0114 // Member hides inherited member; missing override keyword + public static void OnFixedUpdate(PlayerControl player, bool lowLoad, long nowTime) +#pragma warning restore CS0114 // Member hides inherited member; missing override keyword { if (!ChangeTimer.TryGetValue(player.PlayerId, out var timer)) return; @@ -146,7 +161,7 @@ public static PlayerControl GetTargetPC(PlayerControl player) var targetId = GetTarget(player); return targetId == 0xff ? null : Utils.GetPlayerById(targetId); } - private static bool PotentialTarget(PlayerControl player, PlayerControl target) + public static bool PotentialTarget(PlayerControl player, PlayerControl target) { if (target == null || player == null) return false; @@ -182,7 +197,7 @@ private static bool PotentialTarget(PlayerControl player, PlayerControl target) return true; } - private static byte ResetTarget(PlayerControl player) + public static byte ResetTarget(PlayerControl player) { if (!AmongUsClient.Instance.AmHost) return 0xff; @@ -208,7 +223,7 @@ private static byte ResetTarget(PlayerControl player) var target = cTargets.RandomElement(); var targetId = target.PlayerId; Targets[playerId] = targetId; - + if (ShowTargetArrow) TargetArrow.Add(playerId, targetId); Logger.Info($"Change {player.GetNameWithRole()} target to: {target.GetNameWithRole()}", "BountyHunter"); @@ -216,9 +231,11 @@ private static byte ResetTarget(PlayerControl player) return targetId; } public override void SetAbilityButtonText(HudManager hud, byte playerId) => hud.AbilityButton.OverrideText(GetString("BountyHunterChangeButtonText")); - public override void AfterMeetingTasks() +#pragma warning disable CS0114 // Member hides inherited member; missing override keyword + public static void AfterMeetingTasks() +#pragma warning restore CS0114 // Member hides inherited member; missing override keyword { - foreach (var id in _playerIdList.ToArray()) + foreach (var id in playerIdList.ToArray()) { if (!Main.PlayerStates[id].IsDead) { @@ -227,14 +244,18 @@ public override void AfterMeetingTasks() } } } - public override string GetLowerText(PlayerControl seer, PlayerControl seen = null, bool isForMeeting = false, bool isForHud = false) +#pragma warning disable CS0114 // Member hides inherited member; missing override keyword + public static string GetLowerText(PlayerControl seer, PlayerControl seen = null, bool isForMeeting = false, bool isForHud = false) +#pragma warning restore CS0114 // Member hides inherited member; missing override keyword { if (isForMeeting) return string.Empty; var targetId = GetTarget(seer); return targetId != 0xff ? $"{(isForHud ? GetString("BountyCurrentTarget") : GetString("Target"))}: {Main.AllPlayerNames[targetId].RemoveHtmlTags().Replace("\r\n", string.Empty)}" : string.Empty; } - public override string GetSuffix(PlayerControl seer, PlayerControl seen = null, bool isForMeeting = false) +#pragma warning disable CS0114 // Member hides inherited member; missing override keyword + public static string GetSuffix(PlayerControl seer, PlayerControl seen = null, bool isForMeeting = false) +#pragma warning restore CS0114 // Member hides inherited member; missing override keyword { if (!ShowTargetArrow || isForMeeting || seer.PlayerId != seen.PlayerId) return string.Empty; diff --git a/Roles/Impostor/Butcher.cs b/Roles/Impostor/Butcher.cs index e6d17fc55..6866d65e0 100644 --- a/Roles/Impostor/Butcher.cs +++ b/Roles/Impostor/Butcher.cs @@ -8,14 +8,15 @@ namespace TOHE.Roles.Impostor; internal class Butcher : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Butcher; private const int Id = 24300; - + public static readonly HashSet PlayerIds = []; + public static bool HasEnabled => PlayerIds.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorKilling; //==================================================================\\ - private static Dictionary MurderTargetLateTask = []; + public static Dictionary MurderTargetLateTask = []; public override void SetupCustomOption() { SetupRoleOptions(Id, TabGroup.ImpostorRoles, CustomRoles.Butcher); @@ -23,23 +24,23 @@ public override void SetupCustomOption() public override void Init() { MurderTargetLateTask = []; + PlayerIds.Clear(); } public override void Add(byte playerId) { + PlayerIds.Add(playerId); + if (AmongUsClient.Instance.AmHost) { CustomRoleManager.OnFixedUpdateOthers.Add(OnFixedUpdateOthers); } } - public override void Remove(byte playerId) - { - CustomRoleManager.OnFixedUpdateOthers.Remove(OnFixedUpdateOthers); - } - public override void SetAbilityButtonText(HudManager hud, byte playerId) => hud.KillButton.OverrideText(Translator.GetString("ButcherButtonText")); - public override void OnMurderPlayerAsKiller(PlayerControl killer, PlayerControl target, bool inMeeting, bool isSuicide) +#pragma warning disable CS0114 // Member hides inherited member; missing override keyword + public static void OnMurderPlayerAsKiller(PlayerControl killer, PlayerControl target, bool inMeeting, bool isSuicide) +#pragma warning restore CS0114 // Member hides inherited member; missing override keyword { if (inMeeting || isSuicide) return; if (target == null) return; @@ -92,7 +93,7 @@ public override void OnMurderPlayerAsKiller(PlayerControl killer, PlayerControl public override void AfterMeetingTasks() => MurderTargetLateTask = []; public override void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo target) => MurderTargetLateTask.Clear(); - public void OnFixedUpdateOthers(PlayerControl target, bool lowLoad, long nowTime) + public static void OnFixedUpdateOthers(PlayerControl target, bool lowLoad, long nowTime) { if (!target.IsAlive()) return; if (!MurderTargetLateTask.TryGetValue(target.PlayerId, out var data)) return; @@ -107,7 +108,7 @@ public void OnFixedUpdateOthers(PlayerControl target, bool lowLoad, long nowTime Vector2 location = new(ops.x + ((float)(rd.Next(1, 200) - 100) / 100), ops.y + ((float)(rd.Next(1, 200) - 100) / 100)); target.RpcTeleport(location); target.RpcMurderPlayer(target); - target.SetRealKiller(_Player, true); + target.SetRealKiller(Utils.GetPlayerById(PlayerIds.First()), true); MurderTargetLateTask[target.PlayerId] = (0, data.Item2 + 1, ops); } else MurderTargetLateTask.Remove(target.PlayerId); @@ -116,4 +117,4 @@ public void OnFixedUpdateOthers(PlayerControl target, bool lowLoad, long nowTime MurderTargetLateTask[target.PlayerId] = (data.Item1 + 1, data.Item2, ops); } -} +} \ No newline at end of file diff --git a/Roles/Impostor/Camouflager.cs b/Roles/Impostor/Camouflager.cs index e14569909..2e67f6fef 100644 --- a/Roles/Impostor/Camouflager.cs +++ b/Roles/Impostor/Camouflager.cs @@ -10,11 +10,10 @@ namespace TOHE.Roles.Impostor; internal class Camouflager : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Camouflager; private const int Id = 2900; public static readonly HashSet Playerids = []; public static bool HasEnabled => Playerids.Any(); - + public override CustomRoles ThisRoleBase => CustomRoles.Shapeshifter; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorSupport; //==================================================================\\ @@ -58,8 +57,7 @@ public override void Add(byte playerId) CanUseCommsSabotage = CanUseCommsSabotagOpt.GetBool(); DisableReportWhenCamouflageIsActive = DisableReportWhenCamouflageIsActiveOpt.GetBool(); - if (!Playerids.Contains(playerId)) - Playerids.Add(playerId); + Playerids.Add(playerId); } public override void Remove(byte playerId) { diff --git a/Roles/Impostor/Chronomancer.cs b/Roles/Impostor/Chronomancer.cs index 6ecc49d2c..490f3bd95 100644 --- a/Roles/Impostor/Chronomancer.cs +++ b/Roles/Impostor/Chronomancer.cs @@ -1,43 +1,42 @@ -using AmongUs.GameOptions; -using Hazel; -using InnerNet; -using System; +using System; using System.Text; using UnityEngine; using static TOHE.Options; using static TOHE.Translator; +using AmongUs.GameOptions; +using Hazel; +using InnerNet; namespace TOHE.Roles.Impostor; internal class Chronomancer : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Chronomancer; private const int Id = 900; public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorKilling; //==================================================================\\ - private int ChargedTime = 0; + public int ChargedTime = 0; long now = Utils.GetTimeStamp(); - private int FullCharge = 0; - private bool IsInMassacre; + public int FullCharge = 0; + public bool IsInMassacre; public float realcooldown; - private float LastNowF = 0; - private float countnowF = 0; + public float LastNowF = 0; + public float countnowF = 0; - private string LastCD; + public string LastCD; - private static Color32 OrangeColor = new(255, 190, 92, 255); // The lest color - private static Color32 GreenColor = new(0, 128, 0, 255); // The final color + public static Color32 OrangeColor = new(255, 190, 92, 255); // The lest color + public static Color32 GreenColor = new(0, 128, 0, 255); // The final color - private static int Charges; + public static int Charges; - private static OptionItem KillCooldown; - private static OptionItem Dtime; - private static OptionItem ReduceVision; + public static OptionItem KillCooldown; + public static OptionItem Dtime; + public static OptionItem ReduceVision; public override void SetupCustomOption() { @@ -200,4 +199,4 @@ public override string GetLowerText(PlayerControl seer, PlayerControl seen = nul } return string.Empty; } -} +} \ No newline at end of file diff --git a/Roles/Impostor/Cleaner.cs b/Roles/Impostor/Cleaner.cs index a08230693..17748f9f3 100644 --- a/Roles/Impostor/Cleaner.cs +++ b/Roles/Impostor/Cleaner.cs @@ -5,8 +5,10 @@ namespace TOHE.Roles.Impostor; internal class Cleaner : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Cleaner; private const int Id = 3000; + private static readonly HashSet Playerids = []; + public static bool HasEnabled => Playerids.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorSupport; //==================================================================\\ @@ -26,6 +28,14 @@ public override void SetupCustomOption() .SetParent(Options.CustomRoleSpawnChances[CustomRoles.Cleaner]) .SetValueFormat(OptionFormat.Seconds); } + public override void Init() + { + Playerids.Clear(); + } + public override void Add(byte playerId) + { + Playerids.Add(playerId); + } public override void SetKillCooldown(byte id) => Main.AllPlayerKillCooldown[id] = KillCooldown.GetFloat(); diff --git a/Roles/Impostor/Consigliere.cs b/Roles/Impostor/Consigliere.cs index 1bd50b82e..e9718b0c8 100644 --- a/Roles/Impostor/Consigliere.cs +++ b/Roles/Impostor/Consigliere.cs @@ -7,8 +7,10 @@ namespace TOHE.Roles.Impostor; internal class Consigliere : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Consigliere; private const int Id = 3100; + private static readonly HashSet PlayerIds = []; + public static bool HasEnabled => PlayerIds.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorSupport; //==================================================================\\ @@ -16,7 +18,7 @@ internal class Consigliere : RoleBase private static OptionItem KillCooldown; private static OptionItem DivinationMaxCount; - private static readonly Dictionary DivinationCount = []; + public static readonly Dictionary DivinationCount = []; private static readonly Dictionary> DivinationTarget = []; public override void SetupCustomOption() @@ -31,13 +33,13 @@ public override void Init() { DivinationCount.Clear(); DivinationTarget.Clear(); - + PlayerIds.Clear(); } public override void Add(byte playerId) { DivinationCount.TryAdd(playerId, DivinationMaxCount.GetInt()); DivinationTarget.TryAdd(playerId, []); - + PlayerIds.Add(playerId); var pc = Utils.GetPlayerById(playerId); pc.AddDoubleTrigger(); @@ -59,8 +61,7 @@ public static void ReceiveRPC(MessageReader reader) DivinationCount[playerId] = reader.ReadInt32(); else DivinationCount.Add(playerId, DivinationMaxCount.GetInt()); - } - { + }{ if (DivinationCount.ContainsKey(playerId)) DivinationTarget[playerId].Add(reader.ReadByte()); else @@ -69,13 +70,13 @@ public static void ReceiveRPC(MessageReader reader) } public override void SetKillCooldown(byte id) => Main.AllPlayerKillCooldown[id] = KillCooldown.GetFloat(); - public override bool ForcedCheckMurderAsKiller(PlayerControl killer, PlayerControl target) + public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { if (DivinationCount[killer.PlayerId] > 0) { return killer.CheckDoubleTrigger(target, () => { SetDivination(killer, target); }); } - else return true; + else return true; } private static bool IsDivination(byte seer, byte target) @@ -92,11 +93,13 @@ private static void SetDivination(PlayerControl killer, PlayerControl target) { DivinationCount[killer.PlayerId]--; DivinationTarget[killer.PlayerId].Add(target.PlayerId); - Logger.Info($"{killer.GetNameWithRole()}:Checked→{target.GetNameWithRole()} || Remaining Ability: {DivinationCount[killer.PlayerId]}", "Consigliere"); + Logger.Info($"{killer.GetNameWithRole()}:占った 占い先→{target.GetNameWithRole()} || 残り{DivinationCount[killer.PlayerId]}回", "Consigliere"); Utils.NotifyRoles(SpecifySeer: killer, SpecifyTarget: target, ForceLoop: true); SendRPC(killer.PlayerId, target.PlayerId); - killer.SetKillCooldown(target: target, forceAnime: true); + //キルクールの適正化 + killer.SetKillCooldown(); + //killer.RpcGuardAndKill(target); } } public override bool KnowRoleTarget(PlayerControl seer, PlayerControl target) @@ -109,6 +112,6 @@ public override bool KnowRoleTarget(PlayerControl seer, PlayerControl target) }); return IsWatch; } - public override string GetProgressText(byte playerId, bool comms) + public override string GetProgressText(byte playerId, bool comms) => Utils.ColorString(DivinationCount[playerId] > 0 ? Utils.GetRoleColor(CustomRoles.Consigliere).ShadeColor(0.25f) : Color.gray, DivinationCount.TryGetValue(playerId, out var shotLimit) ? $"({shotLimit})" : "Invalid"); -} +} \ No newline at end of file diff --git a/Roles/Impostor/Councillor.cs b/Roles/Impostor/Councillor.cs index cf6256d35..50bca244d 100644 --- a/Roles/Impostor/Councillor.cs +++ b/Roles/Impostor/Councillor.cs @@ -13,7 +13,6 @@ namespace TOHE.Roles.Impostor; internal class Councillor : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Councillor; private const int Id = 1000; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Councillor); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; @@ -29,15 +28,15 @@ internal class Councillor : RoleBase private static OptionItem SuicideOnJudgeImpTeam; private static OptionItem CanMurderTaskDoneSnitch; private static OptionItem KillCooldown; - + private int MurderLimitMeeting; public override void SetupCustomOption() { Options.SetupRoleOptions(Id, TabGroup.ImpostorRoles, CustomRoles.Councillor); - KillCooldown = FloatOptionItem.Create(Id + 10, GeneralOption.KillCooldown, new(0f, 180f, 2.5f), 30f, TabGroup.ImpostorRoles, false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Councillor]) - .SetValueFormat(OptionFormat.Seconds); + KillCooldown = FloatOptionItem.Create(Id + 10, GeneralOption.KillCooldown, new(0f, 180f, 2.5f), 30f, TabGroup.ImpostorRoles, false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Councillor]) + .SetValueFormat(OptionFormat.Seconds); MurderLimitPerMeeting = IntegerOptionItem.Create(Id + 11, "CouncillorMurderLimitPerMeeting", new(1, 15, 1), 1, TabGroup.ImpostorRoles, false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Councillor]) .SetValueFormat(OptionFormat.Times); MurderLimitPerGame = IntegerOptionItem.Create(Id + 12, "CouncillorMurderLimitPerGame", new(1, 15, 1), 4, TabGroup.ImpostorRoles, false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Councillor]) @@ -119,7 +118,7 @@ public bool MurderMsg(PlayerControl pc, string msg, bool isUI = false) else if (AbilityLimit <= 0) { pc.ShowInfoMessage(isUI, GetString("CouncillorMurderMaxGame")); - return true; + return true; } if (Jailer.IsTarget(target.PlayerId)) @@ -245,28 +244,27 @@ public bool MurderMsg(PlayerControl pc, string msg, bool isUI = false) SendSkillRPC(); if (!GameStates.IsProceeding) - _ = new LateTask(() => - { - dp.SetDeathReason(PlayerState.DeathReason.Trialed); - dp.SetRealKiller(pc); - GuessManager.RpcGuesserMurderPlayer(dp); + _ = new LateTask(() => + { + dp.SetDeathReason(PlayerState.DeathReason.Trialed); + dp.SetRealKiller(pc); + GuessManager.RpcGuesserMurderPlayer(dp); - Main.PlayersDiedInMeeting.Add(dp.PlayerId); - MurderPlayerPatch.AfterPlayerDeathTasks(pc, dp, true); + Main.PlayersDiedInMeeting.Add(dp.PlayerId); + MurderPlayerPatch.AfterPlayerDeathTasks(pc, dp, true); - _ = new LateTask(() => + _ = new LateTask(() => { + if (!MakeEvilJudgeClear.GetBool()) + { + Utils.SendMessage(string.Format(GetString("Judge_TrialKill"), Name), 255, Utils.ColorString(Utils.GetRoleColor(CustomRoles.Judge), GetString("Judge_TrialKillTitle")), true); + } + else { - if (!MakeEvilJudgeClear.GetBool()) - { - Utils.SendMessage(string.Format(GetString("Judge_TrialKill"), Name), 255, Utils.ColorString(Utils.GetRoleColor(CustomRoles.Judge), GetString("Judge_TrialKillTitle")), true); - } - else - { - Utils.SendMessage(string.Format(GetString("Councillor_MurderKill"), Name), 255, Utils.ColorString(Utils.GetRoleColor(CustomRoles.Councillor), GetString("Councillor_MurderKillTitle")), true); - } - }, 0.6f, "Guess Msg"); - - }, 0.2f, "Murder Kill"); + Utils.SendMessage(string.Format(GetString("Councillor_MurderKill"), Name), 255, Utils.ColorString(Utils.GetRoleColor(CustomRoles.Councillor), GetString("Councillor_MurderKillTitle")), true); + } + }, 0.6f, "Guess Msg"); + + }, 0.2f, "Murder Kill"); } } return true; diff --git a/Roles/Impostor/Crewpostor.cs b/Roles/Impostor/Crewpostor.cs index b5b79b3e8..58041a34e 100644 --- a/Roles/Impostor/Crewpostor.cs +++ b/Roles/Impostor/Crewpostor.cs @@ -1,14 +1,16 @@ -using AmongUs.GameOptions; -using Hazel; +using Hazel; using static TOHE.Options; +using AmongUs.GameOptions; namespace TOHE.Roles.Impostor; internal class Crewpostor : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Crewpostor; private const int Id = 5800; + private static readonly HashSet PlayerIds = []; + public static bool HasEnabled => PlayerIds.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Engineer; public override Custom_RoleType ThisRoleType => Custom_RoleType.Madmate; //==================================================================\\ @@ -19,7 +21,7 @@ internal class Crewpostor : RoleBase private static OptionItem LungeKill; private static OptionItem KillAfterTask; - private static Dictionary TasksDone = []; + public static Dictionary TasksDone = []; public override void SetupCustomOption() { @@ -40,22 +42,22 @@ public override void SetupCustomOption() public override void Init() { TasksDone = []; - + PlayerIds.Clear(); } public override void Add(byte playerId) { TasksDone[playerId] = 0; - + PlayerIds.Add(playerId); } - public override bool HasTasks(NetworkedPlayerInfo player, CustomRoles role, bool ForRecompute) - { + public override bool HasTasks(NetworkedPlayerInfo player, CustomRoles role, bool ForRecompute) + { if (ForRecompute & !player.IsDead) return false; if (player.IsDead) return false; return true; - + } private static void SendRPC(byte cpID, int tasksDone) @@ -148,7 +150,7 @@ public override bool OnTaskComplete(PlayerControl player, int completedTaskCount player.RpcGuardAndKill(); Logger.Info($"Crewpostor tried to kill pestilence (reflected back):{target.GetNameWithRole().RemoveHtmlTags()} => {player.GetNameWithRole().RemoveHtmlTags()}", "Pestilence Reflect"); } - else + else { player.RpcGuardAndKill(); Logger.Info($"Crewpostor tried to kill Apocalypse Member:{target.GetNameWithRole().RemoveHtmlTags()} => {player.GetNameWithRole().RemoveHtmlTags()}", "Apocalypse Immune"); diff --git a/Roles/Impostor/CursedWolf.cs b/Roles/Impostor/CursedWolf.cs index 4e1c6325e..7a03fd7f1 100644 --- a/Roles/Impostor/CursedWolf.cs +++ b/Roles/Impostor/CursedWolf.cs @@ -6,7 +6,6 @@ namespace TOHE.Roles.Impostor; internal class CursedWolf : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.CursedWolf; private const int Id = 1100; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.CursedWolf); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; @@ -16,6 +15,7 @@ internal class CursedWolf : RoleBase private static OptionItem GuardSpellTimes; private static OptionItem KillAttacker; + public override void SetupCustomOption() { diff --git a/Roles/Impostor/Dazzler.cs b/Roles/Impostor/Dazzler.cs index 1813b1b13..18abaf63a 100644 --- a/Roles/Impostor/Dazzler.cs +++ b/Roles/Impostor/Dazzler.cs @@ -9,8 +9,10 @@ namespace TOHE.Roles.Impostor; internal class Dazzler : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Dazzler; private const int Id = 5400; + private static readonly HashSet PlayerIds = []; + public static bool HasEnabled => PlayerIds.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Shapeshifter; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorHindering; //==================================================================\\ @@ -44,16 +46,19 @@ public override void SetupCustomOption() public override void Init() { PlayersDazzled = []; + PlayerIds.Clear(); } public override void Add(byte playerId) { PlayersDazzled.TryAdd(playerId, []); + PlayerIds.Add(playerId); } public override void Remove(byte playerId) { PlayersDazzled.Remove(playerId); + PlayerIds.Remove(playerId); } public override void ApplyGameOptions(IGameOptions opt, byte playerId) @@ -105,4 +110,4 @@ public override void SetAbilityButtonText(HudManager hud, byte playerId) { hud.AbilityButton.OverrideText(GetString("DazzleButtonText")); } -} +} \ No newline at end of file diff --git a/Roles/Impostor/Deathpact.cs b/Roles/Impostor/Deathpact.cs index bab77f3bf..8068b1be6 100644 --- a/Roles/Impostor/Deathpact.cs +++ b/Roles/Impostor/Deathpact.cs @@ -13,9 +13,10 @@ namespace TOHE.Roles.Impostor; internal class Deathpact : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Deathpact; private const int Id = 1200; - + private static readonly HashSet Playerids = []; + public static bool HasEnabled => Playerids.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Shapeshifter; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorKilling; //==================================================================\\ @@ -63,16 +64,19 @@ public override void Init() PlayersInDeathpact.Clear(); DeathpactTime.Clear(); ActiveDeathpacts.Clear(); + Playerids.Clear(); } public override void Add(byte playerId) { PlayersInDeathpact[playerId] = []; DeathpactTime[playerId] = 0; + Playerids.Add(playerId); } public override void Remove(byte playerId) { PlayersInDeathpact.Remove(playerId); DeathpactTime.Remove(playerId); + Playerids.Remove(playerId); } public override void ApplyGameOptions(IGameOptions opt, byte playerId) @@ -143,7 +147,7 @@ public static void SetDeathpactVision(PlayerControl player, IGameOptions opt) return; } - if (PlayersInDeathpact.Any(a => a.Value.Any(b => b.PlayerId == player.PlayerId) && a.Value.Count == NumberOfPlayersInPact.GetInt())) + if (PlayersInDeathpact.Any(a => a.Value.Any(b => b.PlayerId == player.PlayerId) && a.Value.Count == NumberOfPlayersInPact.GetInt() )) { opt.SetVision(false); opt.SetFloat(FloatOptionNames.CrewLightMod, VisionWhileInPact.GetFloat()); @@ -215,7 +219,7 @@ private static void KillPlayerInDeathpact(PlayerControl deathpact, PlayerControl { if (deathpact == null || target == null || target.Data.Disconnected) return; if (!target.IsAlive()) return; - + target.SetDeathReason(PlayerState.DeathReason.Suicide); target.RpcMurderPlayer(target); target.SetRealKiller(deathpact); @@ -327,4 +331,4 @@ public override void SetAbilityButtonText(HudManager hud, byte playerId) { hud.AbilityButton.OverrideText(GetString("DeathpactButtonText")); } -} +} \ No newline at end of file diff --git a/Roles/Impostor/Devourer.cs b/Roles/Impostor/Devourer.cs index dc3799c31..f4c8d88ad 100644 --- a/Roles/Impostor/Devourer.cs +++ b/Roles/Impostor/Devourer.cs @@ -11,8 +11,10 @@ internal class Devourer : RoleBase private static readonly Dictionary OriginalPlayerSkins = []; //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Devourer; private const int Id = 5500; + private static readonly HashSet PlayerIds = []; + public static bool HasEnabled => PlayerIds.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Shapeshifter; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorHindering; //==================================================================\\ @@ -46,17 +48,20 @@ public override void Init() PlayerSkinsCosumed.Clear(); OriginalPlayerSkins.Clear(); NowCooldown.Clear(); + PlayerIds.Clear(); } public override void Add(byte playerId) { PlayerSkinsCosumed.TryAdd(playerId, []); NowCooldown.TryAdd(playerId, DefaultKillCooldown.GetFloat()); + PlayerIds.Add(playerId); } public override void Remove(byte playerId) { OnDevourerDied(Utils.GetPlayerById(playerId)); PlayerSkinsCosumed.Remove(playerId); NowCooldown.Remove(playerId); + PlayerIds.Remove(playerId); } public override void ApplyGameOptions(IGameOptions opt, byte playerId) @@ -141,4 +146,4 @@ public override void SetAbilityButtonText(HudManager hud, byte playerId) { hud.AbilityButton.OverrideText(GetString("DevourerButtonText")); } -} +} \ No newline at end of file diff --git a/Roles/Impostor/Disperser.cs b/Roles/Impostor/Disperser.cs index b09158502..2ecb7fe35 100644 --- a/Roles/Impostor/Disperser.cs +++ b/Roles/Impostor/Disperser.cs @@ -9,8 +9,9 @@ namespace TOHE.Roles.Impostor; internal class Disperser : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Disperser; private const int Id = 24400; + private static readonly HashSet PlayerIds = []; + public static bool HasEnabled => PlayerIds.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Shapeshifter; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorHindering; //==================================================================\\ @@ -27,6 +28,15 @@ public override void SetupCustomOption() .SetValueFormat(OptionFormat.Seconds); } + public override void Init() + { + PlayerIds.Clear(); + } + public override void Add(byte playerId) + { + PlayerIds.Add(playerId); + } + public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.ShapeshifterCooldown = DisperserShapeshiftCooldown.GetFloat(); @@ -35,7 +45,7 @@ public override void ApplyGameOptions(IGameOptions opt, byte playerId) public override bool OnCheckShapeshift(PlayerControl shapeshifter, PlayerControl target, ref bool resetCooldown, ref bool shouldAnimate) { if (shapeshifter.PlayerId == target.PlayerId) return false; - + foreach (var pc in Main.AllAlivePlayerControls) { if (!pc.CanBeTeleported()) @@ -51,4 +61,4 @@ public override bool OnCheckShapeshift(PlayerControl shapeshifter, PlayerControl return false; } -} +} \ No newline at end of file diff --git a/Roles/Impostor/DollMaster.cs b/Roles/Impostor/DollMaster.cs index a5bbbd46c..a2f2465c2 100644 --- a/Roles/Impostor/DollMaster.cs +++ b/Roles/Impostor/DollMaster.cs @@ -11,7 +11,6 @@ namespace TOHE.Roles.Impostor; internal class DollMaster : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.DollMaster; private const int Id = 28500; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.DollMaster); public override bool IsExperimental => true; @@ -367,10 +366,10 @@ private static void Possess(PlayerControl pc, PlayerControl target) { (target.MyPhysics.FlipX, pc.MyPhysics.FlipX) = (pc.MyPhysics.FlipX, target.MyPhysics.FlipX); // Copy the players directions that they are facing, Note this only works for modded clients! pc?.RpcShapeshift(target, false); - + pc?.ResetPlayerOutfit(Main.PlayerStates[target.PlayerId].NormalOutfit); target?.ResetPlayerOutfit(Main.PlayerStates[pc.PlayerId].NormalOutfit); - + pc?.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.DollMaster), GetString("DollMaster_PossessedTarget"))); } @@ -379,7 +378,7 @@ private static void UnPossess(PlayerControl pc, PlayerControl target) { (target.MyPhysics.FlipX, pc.MyPhysics.FlipX) = (pc.MyPhysics.FlipX, target.MyPhysics.FlipX); // Copy the players directions that they are facing, Note this only works for modded clients! pc?.RpcShapeshift(pc, false); - + pc?.ResetPlayerOutfit(); target?.ResetPlayerOutfit(); @@ -443,4 +442,4 @@ public override string GetSuffix(PlayerControl seer, PlayerControl target = null public override void SetAbilityButtonText(HudManager hud, byte playerId) => hud.AbilityButton.OverrideText(GetString(IsControllingPlayer ? "DollMasterUnPossessionButtonText" : "DollMasterPossessionButtonText")); public override Sprite GetAbilityButtonSprite(PlayerControl player, bool shapeshifting) => CustomButton.Get("Puttpuer"); -} +} \ No newline at end of file diff --git a/Roles/Impostor/DoubleAgent.cs b/Roles/Impostor/DoubleAgent.cs index badeb495c..eeef38bf9 100644 --- a/Roles/Impostor/DoubleAgent.cs +++ b/Roles/Impostor/DoubleAgent.cs @@ -1,20 +1,22 @@ using Hazel; using InnerNet; +using UnityEngine; using TOHE.Modules; using TOHE.Roles.Core; using TOHE.Roles.Crewmate; using TOHE.Roles.Neutral; -using UnityEngine; +using static TOHE.Utils; using static TOHE.Options; using static TOHE.Translator; -using static TOHE.Utils; namespace TOHE.Roles.Impostor; internal class DoubleAgent : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.DoubleAgent; private const int Id = 29000; + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); + public override bool IsEnable => HasEnabled; public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorSupport; //==================================================================\\ @@ -32,7 +34,6 @@ internal class DoubleAgent : RoleBase private static OptionItem ExplosionRadius; private static OptionItem ChangeRoleToOnLast; - [Obfuscation(Exclude = true)] private enum ChangeRolesSelectOnLast { Role_NoChange, @@ -65,6 +66,7 @@ public override void SetupCustomOption() } public override void Init() { + playerIdList.Clear(); CurrentBombedPlayers.Clear(); CurrentBombedTime = -1; BombIsActive = false; @@ -74,6 +76,7 @@ public override void Init() public override void Add(byte playerId) { + playerIdList.Add(playerId); CustomRoleManager.OnFixedUpdateOthers.Add(OnFixedUpdateOthers); if (Main.AllAlivePlayerControls.Count(player => player.Is(Custom_Team.Impostor)) > 1) StartedWithMoreThanOneImp = true; @@ -226,8 +229,6 @@ public override void OnFixedUpdate(PlayerControl player, bool lowLoad, long nowT player.GetCustomSubRoles()?.Add(CustomRoles.Admired); Init(); - player.GetRoleClass().OnRemove(player.PlayerId); - player.RpcChangeRoleBasis(Role); player.RpcSetCustomRole(Role); player.GetRoleClass()?.Add(player.PlayerId); player.MarkDirtySettings(); @@ -265,7 +266,7 @@ private void BoomBoom(PlayerControl player) // Set bomb mark on player. public override string GetMark(PlayerControl seer, PlayerControl seen = null, bool isForMeeting = false) { - if (seen == null) return string.Empty; + if (seen == null ) return string.Empty; if (CurrentBombedPlayers.Contains(seen.PlayerId)) return ColorString(Color.red, "Ⓑ"); // L Rizz :) return string.Empty; } @@ -325,8 +326,10 @@ public static void CreatePlantBombButton(MeetingHud __instance) targetBox.name = "PlantBombButton"; targetBox.transform.localPosition = new Vector3(-0.35f, 0.03f, -1.31f); createdButtonsList.Add(targetBox); + SpriteRenderer renderer = targetBox.GetComponent(); renderer.sprite = CustomButton.Get("DoubleAgentPocketBomb"); + PassiveButton button = targetBox.GetComponent(); button.OnClick.RemoveAllListeners(); button.OnClick.AddListener((UnityEngine.Events.UnityAction)(() => DestroyButtons(targetBox))); @@ -358,5 +361,4 @@ private static void DestroyButtons(GameObject pressedButton) } // FieryFlower was here ඞ -// Drakos wasn't here, 100% not -// Niko is here, what dog shxt has you guys code +// Drakos wasn't here, 100% not \ No newline at end of file diff --git a/Roles/Impostor/Eraser.cs b/Roles/Impostor/Eraser.cs index dc2ad757d..0a19454d6 100644 --- a/Roles/Impostor/Eraser.cs +++ b/Roles/Impostor/Eraser.cs @@ -10,7 +10,6 @@ namespace TOHE.Roles.Impostor; internal class Eraser : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Eraser; private const int Id = 24200; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Eraser); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; @@ -126,10 +125,7 @@ public override void AfterMeetingTasks() Logger.Info($"Canceled {player.GetNameWithRole()} because player have ghost role", "Eraser"); return; } - player.GetRoleClass()?.OnRemove(player.PlayerId); - player.RpcChangeRoleBasis(GetErasedRole(player.GetCustomRole().GetRoleTypes(), player.GetCustomRole())); player.RpcSetCustomRole(GetErasedRole(player.GetCustomRole().GetRoleTypes(), player.GetCustomRole())); - player.GetRoleClass()?.OnAdd(player.PlayerId); player.ResetKillCooldown(); player.SetKillCooldown(); Logger.Info($"{player.GetNameWithRole()} Erase by Eraser", "Eraser"); diff --git a/Roles/Impostor/Escapist.cs b/Roles/Impostor/Escapist.cs index fe13802f4..374746f0d 100644 --- a/Roles/Impostor/Escapist.cs +++ b/Roles/Impostor/Escapist.cs @@ -7,8 +7,11 @@ namespace TOHE.Roles.Impostor; internal class Escapist : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Escapist; private const int Id = 4000; + + private static readonly HashSet PlayerIds = []; + public static bool HasEnabled => PlayerIds.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Shapeshifter; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorConcealing; //==================================================================\\ @@ -32,6 +35,11 @@ public override void SetupCustomOption() public override void Init() { EscapeLocation.Clear(); + PlayerIds.Clear(); + } + public override void Add(byte playerId) + { + PlayerIds.Add(playerId); } public override void ApplyGameOptions(IGameOptions opt, byte playerId) diff --git a/Roles/Impostor/EvilGuesser.cs b/Roles/Impostor/EvilGuesser.cs index 2ee4e3982..151c1b39f 100644 --- a/Roles/Impostor/EvilGuesser.cs +++ b/Roles/Impostor/EvilGuesser.cs @@ -5,8 +5,11 @@ namespace TOHE.Roles.Impostor; internal class EvilGuesser : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.EvilGuesser; private const int Id = 1300; + + private static readonly HashSet PlayerIds = []; + public static bool HasEnabled => PlayerIds.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorKilling; //==================================================================\\ @@ -33,6 +36,14 @@ public override void SetupCustomOption() .SetParent(Options.CustomRoleSpawnChances[CustomRoles.EvilGuesser]) .SetColor(Color.green); } + public override void Init() + { + PlayerIds.Clear(); + } + public override void Add(byte playerId) + { + PlayerIds.Add(playerId); + } public override string PVANameText(PlayerVoteArea pva, PlayerControl seer, PlayerControl target) => seer.IsAlive() && target.IsAlive() ? Utils.ColorString(Utils.GetRoleColor(CustomRoles.EvilGuesser), target.PlayerId.ToString()) + " " + pva.NameText.text : string.Empty; diff --git a/Roles/Impostor/EvilHacker.cs b/Roles/Impostor/EvilHacker.cs index d30ec6d98..ef37463df 100644 --- a/Roles/Impostor/EvilHacker.cs +++ b/Roles/Impostor/EvilHacker.cs @@ -1,7 +1,7 @@ -using Hazel; -using InnerNet; using System; using System.Text; +using Hazel; +using InnerNet; using TOHE.Modules; using TOHE.Roles.Core; using UnityEngine; @@ -13,7 +13,6 @@ namespace TOHE.Roles.Impostor; internal class EvilHacker : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.EvilHacker; private const int Id = 28400; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.EvilHacker); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; @@ -28,7 +27,6 @@ internal class EvilHacker : RoleBase private static byte player = 0; private string message; - [Obfuscation(Exclude = true)] public enum OptionName { EvilHackerCanSeeDeadMark, diff --git a/Roles/Impostor/EvilTracker.cs b/Roles/Impostor/EvilTracker.cs index 62bcaf4fa..f7d5ed64f 100644 --- a/Roles/Impostor/EvilTracker.cs +++ b/Roles/Impostor/EvilTracker.cs @@ -10,11 +10,10 @@ namespace TOHE.Roles.Impostor; internal class EvilTracker : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.EvilTracker; private const int Id = 1400; private static readonly HashSet playerIdList = []; public static bool HasEnabled => playerIdList.Any(); - + public override CustomRoles ThisRoleBase => (TargetMode)OptionTargetMode.GetValue() == TargetMode.Never ? CustomRoles.Impostor : CustomRoles.Shapeshifter; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorKilling; //==================================================================\\ @@ -32,7 +31,6 @@ internal class EvilTracker : RoleBase private static readonly Dictionary CanSetTarget = []; private static readonly Dictionary> ImpostorsId = []; - [Obfuscation(Exclude = true)] private enum TargetMode { Never, @@ -71,8 +69,7 @@ public override void Init() } public override void Add(byte playerId) { - if (!playerIdList.Contains(playerId)) - playerIdList.Add(playerId); + playerIdList.Add(playerId); Target.Add(playerId, byte.MaxValue); CanSetTarget.Add(playerId, CurrentTargetMode != TargetMode.Never); @@ -104,10 +101,10 @@ public override void SetAbilityButtonText(HudManager hud, byte id) private static bool CanTarget(byte playerId) => !Main.PlayerStates[playerId].IsDead && CanSetTarget.TryGetValue(playerId, out var value) && value; - + private static byte GetTargetId(byte playerId) => Target.TryGetValue(playerId, out var targetId) ? targetId : byte.MaxValue; - + public static bool IsTrackTarget(PlayerControl seer, PlayerControl target) => seer.IsAlive() && playerIdList.Contains(seer.PlayerId) && target.IsAlive() && seer != target @@ -156,7 +153,7 @@ private static void SetTarget(byte trackerId = byte.MaxValue, byte targetId = by Target[trackerId] = targetId; // Set Target if (CurrentTargetMode != TargetMode.Always) CanSetTarget[trackerId] = false; // Target cannot be re-set - + if (AmongUsClient.Instance.AmHost) TargetArrow.Add(trackerId, targetId); } @@ -241,4 +238,4 @@ private static string GetArrowAndLastRoom(PlayerControl seer, PlayerControl targ else text += Utils.ColorString(Palette.ImpostorRed, "@" + GetString(room.RoomId.ToString())); return text; } -} +} \ No newline at end of file diff --git a/Roles/Impostor/Fireworker.cs b/Roles/Impostor/Fireworker.cs index 406bf5141..6957605d8 100644 --- a/Roles/Impostor/Fireworker.cs +++ b/Roles/Impostor/Fireworker.cs @@ -1,6 +1,5 @@ using AmongUs.GameOptions; using Hazel; -using TOHE.Modules; using UnityEngine; using static TOHE.Translator; @@ -8,7 +7,6 @@ namespace TOHE.Roles.Impostor; internal class Fireworker : RoleBase { - [Obfuscation(Exclude = true)] private enum FireworkerState { Initial = 1, @@ -19,10 +17,10 @@ private enum FireworkerState CanUseKill = Initial | FireEnd } //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Fireworker; - [Obfuscation(Exclude = true)] private const int Id = 3200; - + private static readonly HashSet PlayerIds = []; + public static bool HasEnabled => PlayerIds.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Shapeshifter; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorSupport; //==================================================================\\ @@ -31,22 +29,17 @@ private enum FireworkerState private static OptionItem FireworkerCount; private static OptionItem FireworkerRadius; private static OptionItem CanKill; - private static OptionItem PlaceCooldown; private static readonly Dictionary nowFireworkerCount = []; private static readonly Dictionary> FireworkerPosition = []; private static readonly Dictionary state = []; private static readonly Dictionary FireworkerBombKill = []; - private readonly List Fireworks = []; - private static int fireworkerCount = 1; private static float fireworkerRadius = 1; public override void SetupCustomOption() { Options.SetupRoleOptions(Id, TabGroup.ImpostorRoles, CustomRoles.Fireworker); - PlaceCooldown = FloatOptionItem.Create(Id + 9, "FireworkerCooldown", new(1f, 180f, 0.5f), 15f, TabGroup.ImpostorRoles, false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Fireworker]) - .SetValueFormat(OptionFormat.Multiplier); FireworkerCount = IntegerOptionItem.Create(Id + 10, "FireworkerMaxCount", new(1, 20, 1), 3, TabGroup.ImpostorRoles, false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Fireworker]) .SetValueFormat(OptionFormat.Pieces); FireworkerRadius = FloatOptionItem.Create(Id + 11, "FireworkerRadius", new(0.5f, 5f, 0.5f), 2f, TabGroup.ImpostorRoles, false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Fireworker]) @@ -56,6 +49,7 @@ public override void SetupCustomOption() public override void Init() { + PlayerIds.Clear(); nowFireworkerCount.Clear(); FireworkerPosition.Clear(); state.Clear(); @@ -71,6 +65,7 @@ public override void Add(byte playerId) FireworkerPosition[playerId] = []; state.TryAdd(playerId, FireworkerState.Initial); FireworkerBombKill[playerId] = 0; + PlayerIds.Add(playerId); } private static void SendRPC(byte playerId) @@ -93,7 +88,8 @@ public static void ReceiveRPC(MessageReader msg) public override void ApplyGameOptions(IGameOptions opt, byte playerId) { - AURoleOptions.ShapeshifterCooldown = PlaceCooldown.GetFloat(); + AURoleOptions.ShapeshifterDuration = state[playerId] != FireworkerState.FireEnd ? 1f : 30f; + AURoleOptions.ShapeshifterLeaveSkin = true; } public override bool CanUseKillButton(PlayerControl pc) @@ -112,9 +108,10 @@ public override bool CanUseKillButton(PlayerControl pc) return canUse; } - public override void UnShapeShiftButton(PlayerControl shapeshifter) + public override bool OnCheckShapeshift(PlayerControl shapeshifter, PlayerControl target, ref bool resetCooldown, ref bool shouldAnimate) { Logger.Info($"Fireworker ShapeShift", "Fireworker"); + if (shapeshifter.PlayerId == target.PlayerId) return false; var shapeshifterId = shapeshifter.PlayerId; switch (state[shapeshifterId]) @@ -124,7 +121,6 @@ public override void UnShapeShiftButton(PlayerControl shapeshifter) Logger.Info("One firework set up", "Fireworker"); FireworkerPosition[shapeshifterId].Add(shapeshifter.transform.position); - Fireworks.Add(new(shapeshifter.GetCustomPosition(), [.. Main.AllPlayerControls.Where(x => x.GetCountTypes() == CountTypes.Impostor).Select(x => x.PlayerId)], _state.PlayerId)); nowFireworkerCount[shapeshifterId]--; state[shapeshifterId] = nowFireworkerCount[shapeshifterId] == 0 ? Main.AliveImpostorCount <= 1 ? FireworkerState.ReadyFire : FireworkerState.WaitTime @@ -136,8 +132,6 @@ public override void UnShapeShiftButton(PlayerControl shapeshifter) case FireworkerState.ReadyFire: Logger.Info("Blowing up fireworks", "Fireworker"); bool suicide = false; - Fireworks.Do(x => x.Despawn()); - Fireworks.Clear(); foreach (var player in Main.AllAlivePlayerControls) { foreach (var pos in FireworkerPosition[shapeshifterId].ToArray()) @@ -172,6 +166,8 @@ public override void UnShapeShiftButton(PlayerControl shapeshifter) } SendRPC(shapeshifterId); Utils.NotifyRoles(ForceLoop: true); + + return false; } public override string GetLowerText(PlayerControl seer, PlayerControl seen = null, bool isForMeeting = false, bool isForHud = false) diff --git a/Roles/Impostor/Gangster.cs b/Roles/Impostor/Gangster.cs index 0785edd7e..6548dc145 100644 --- a/Roles/Impostor/Gangster.cs +++ b/Roles/Impostor/Gangster.cs @@ -1,18 +1,17 @@ using TOHE.Roles.AddOns.Crewmate; -using TOHE.Roles.AddOns.Impostor; -using TOHE.Roles.Core; using TOHE.Roles.Crewmate; +using TOHE.Roles.AddOns.Impostor; using TOHE.Roles.Double; using TOHE.Roles.Neutral; using UnityEngine; using static TOHE.Translator; +using TOHE.Roles.Core; namespace TOHE.Roles.Impostor; internal class Gangster : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Gangster; private const int Id = 3300; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Gangster); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; @@ -145,7 +144,7 @@ public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl t Utils.NotifyRoles(SpecifySeer: target, SpecifyTarget: killer, ForceLoop: true); return true; } - public override string GetProgressText(byte playerId, bool comms) => Utils.ColorString(CanRecruit(playerId) ? Utils.GetRoleColor(CustomRoles.Gangster).ShadeColor(0.25f) : Color.gray, $"({AbilityLimit})"); + public override string GetProgressText(byte playerId, bool comms) => Utils.ColorString(CanRecruit(playerId)? Utils.GetRoleColor(CustomRoles.Gangster).ShadeColor(0.25f) : Color.gray, $"({AbilityLimit})"); private bool CanRecruit(byte id) => AbilityLimit >= 1; private static bool CanBeGansterRecruit(PlayerControl pc) @@ -155,4 +154,4 @@ private static bool CanBeGansterRecruit(PlayerControl pc) && !((pc.Is(CustomRoles.NiceMini) || pc.Is(CustomRoles.EvilMini)) && Mini.Age < 18) && !(pc.GetCustomSubRoles().Contains(CustomRoles.Hurried) && !Hurried.CanBeConverted.GetBool()); } -} +} \ No newline at end of file diff --git a/Roles/Impostor/Godfather.cs b/Roles/Impostor/Godfather.cs index db1b692d3..998f520bd 100644 --- a/Roles/Impostor/Godfather.cs +++ b/Roles/Impostor/Godfather.cs @@ -1,14 +1,16 @@ using TOHE.Roles.Core; -using static TOHE.Translator; using static TOHE.Utils; +using static TOHE.Translator; namespace TOHE.Roles.Impostor; internal class Godfather : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Godfather; private const int Id = 3400; + private static readonly HashSet PlayerIds = []; + public static bool HasEnabled => PlayerIds.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorSupport; //==================================================================\\ @@ -18,7 +20,6 @@ internal class Godfather : RoleBase private static readonly HashSet GodfatherTarget = []; private bool Didvote = false; - [Obfuscation(Exclude = true)] private enum GodfatherChangeModeList { GodfatherCount_Refugee, @@ -34,42 +35,26 @@ public override void SetupCustomOption() public override void Init() { + PlayerIds.Clear(); GodfatherTarget.Clear(); } public override void Add(byte playerId) { + PlayerIds.Add(playerId); + if (AmongUsClient.Instance.AmHost) { CustomRoleManager.CheckDeadBodyOthers.Add(CheckDeadBody); } } - public override void Remove(byte playerId) - { - CustomRoleManager.CheckDeadBodyOthers.Remove(CheckDeadBody); - } public override void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo target) => GodfatherTarget.Clear(); private void CheckDeadBody(PlayerControl killer, PlayerControl target, bool inMeeting) { - if (GodfatherTarget.Contains(target.PlayerId)) + if (GodfatherTarget.Contains(target.PlayerId) && !(killer.GetCustomRole().IsImpostor() || killer.GetCustomRole().IsMadmate() || killer.Is(CustomRoles.Madmate))) { - if (GodfatherChangeOpt.GetValue() == 0) - { - killer.RpcChangeRoleBasis(CustomRoles.Refugee); - killer.GetRoleClass()?.OnRemove(killer.PlayerId); - killer.RpcSetCustomRole(CustomRoles.Refugee); - killer.GetRoleClass()?.OnAdd(killer.PlayerId); - } - else - { - killer.RpcSetCustomRole(CustomRoles.Madmate); - } - - killer.RpcGuardAndKill(); - killer.ResetKillCooldown(); - killer.SetKillCooldown(); - killer.Notify(ColorString(GetRoleColor(CustomRoles.Godfather), GetString("GodfatherRefugeeMsg"))); - NotifyRoles(killer); + if (GodfatherChangeOpt.GetValue() == 0) killer.RpcSetCustomRole(CustomRoles.Refugee); + else killer.RpcSetCustomRole(CustomRoles.Madmate); } } public override void AfterMeetingTasks() => Didvote = false; diff --git a/Roles/Impostor/Greedy.cs b/Roles/Impostor/Greedy.cs index ad3843d5f..3b0a62b05 100644 --- a/Roles/Impostor/Greedy.cs +++ b/Roles/Impostor/Greedy.cs @@ -6,8 +6,10 @@ namespace TOHE.Roles.Impostor; internal class Greedy : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Greedy; private const int Id = 1500; + public static HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorKilling; //==================================================================\\ @@ -29,10 +31,12 @@ public override void SetupCustomOption() } public override void Init() { + playerIdList.Clear(); IsOdd.Clear(); } public override void Add(byte playerId) { + playerIdList.Add(playerId); IsOdd.Add(playerId, true); } @@ -53,7 +57,7 @@ public static void ReceiveRPC(MessageReader reader) public override void SetKillCooldown(byte id) => Main.AllPlayerKillCooldown[id] = OddKillCooldown.GetFloat(); public override void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo target) { - foreach (var greedyId in _playerIdList) + foreach (var greedyId in playerIdList.ToArray()) { IsOdd[greedyId] = true; SendRPC(greedyId); @@ -80,4 +84,4 @@ public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl t killer.SyncSettings(); return true; } -} +} \ No newline at end of file diff --git a/Roles/Impostor/Hangman.cs b/Roles/Impostor/Hangman.cs index 1e6f652cd..62f28b34e 100644 --- a/Roles/Impostor/Hangman.cs +++ b/Roles/Impostor/Hangman.cs @@ -1,8 +1,8 @@ using AmongUs.GameOptions; +using UnityEngine; using TOHE.Roles.AddOns.Impostor; using TOHE.Roles.Core; using TOHE.Roles.Double; -using UnityEngine; using static TOHE.Options; namespace TOHE.Roles.Impostor; @@ -10,7 +10,6 @@ namespace TOHE.Roles.Impostor; internal class Hangman : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Hangman; private const int Id = 24500; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Hangman); public override CustomRoles ThisRoleBase => CustomRoles.Shapeshifter; @@ -61,4 +60,4 @@ public override bool ForcedCheckMurderAsKiller(PlayerControl killer, PlayerContr } public override Sprite GetAbilityButtonSprite(PlayerControl player, bool shapeshifting) => shapeshifting ? CustomButton.Get("Hangman") : null; -} +} \ No newline at end of file diff --git a/Roles/Impostor/Inhibitor.cs b/Roles/Impostor/Inhibitor.cs index 8a36cbf8a..06243a3e6 100644 --- a/Roles/Impostor/Inhibitor.cs +++ b/Roles/Impostor/Inhibitor.cs @@ -3,8 +3,10 @@ internal class Inhibitor : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Inhibitor; private const int Id = 1600; + private static readonly HashSet PlayerIds = []; + public static bool HasEnabled => PlayerIds.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorKilling; //==================================================================\\ @@ -18,9 +20,17 @@ public override void SetupCustomOption() .SetParent(Options.CustomRoleSpawnChances[CustomRoles.Inhibitor]) .SetValueFormat(OptionFormat.Seconds); } + public override void Init() + { + PlayerIds.Clear(); + } + public override void Add(byte playerId) + { + PlayerIds.Add(playerId); + } public override void SetKillCooldown(byte id) => Main.AllPlayerKillCooldown[id] = InhibitorCD.GetFloat(); public override bool CanUseKillButton(PlayerControl pc) => !Saboteur.IsCriticalSabotage(); -} +} \ No newline at end of file diff --git a/Roles/Impostor/Instigator.cs b/Roles/Impostor/Instigator.cs index 494b7bd92..d821cb4b2 100644 --- a/Roles/Impostor/Instigator.cs +++ b/Roles/Impostor/Instigator.cs @@ -5,8 +5,10 @@ namespace TOHE.Roles.Impostor; internal class Instigator : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Instigator; private const int Id = 1700; + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorKilling; //==================================================================\\ @@ -27,8 +29,13 @@ public override void SetupCustomOption() KillsPerAbilityUse = IntegerOptionItem.Create(Id + 12, "InstigatorKillsPerAbilityUse", new(1, 15, 1), 1, TabGroup.ImpostorRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Instigator]) .SetValueFormat(OptionFormat.Times); } + public override void Init() + { + playerIdList.Clear(); + } public override void Add(byte playerId) { + playerIdList.Add(playerId); AbilityLimit = AbilityLimitt.GetInt(); } @@ -48,7 +55,7 @@ public override void OnPlayerExiled(PlayerControl instigator, NetworkedPlayerInf foreach (var playerVote in votedForExiled) { var crewPlayer = Main.AllPlayerControls.FirstOrDefault(a => a.PlayerId == playerVote.TargetPlayerId); - if (crewPlayer == null || !crewPlayer.GetCustomRole().IsCrewmate() || crewPlayer.IsAnySubRole(x => !x.IsCrewmateTeamV2()) || !crewPlayer.IsAlive()) continue; + if (crewPlayer == null || !crewPlayer.GetCustomRole().IsCrewmate()) return; killPotentials.Add(crewPlayer); } diff --git a/Roles/Impostor/Kamikaze.cs b/Roles/Impostor/Kamikaze.cs index e5628812b..ce137407c 100644 --- a/Roles/Impostor/Kamikaze.cs +++ b/Roles/Impostor/Kamikaze.cs @@ -1,6 +1,4 @@ -using Hazel; -using InnerNet; -using TOHE.Roles.Core; +using TOHE.Roles.Core; using TOHE.Roles.Double; using UnityEngine; using static TOHE.Options; @@ -11,7 +9,6 @@ namespace TOHE.Roles.Impostor; internal class Kamikaze : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Kamikaze; private const int Id = 26900; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Kamikaze); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; @@ -40,9 +37,9 @@ public override void Add(byte playerId) var pc = Utils.GetPlayerById(playerId); pc.AddDoubleTrigger(); } - + public override void SetKillCooldown(byte id) => Main.AllPlayerKillCooldown[id] = KillCooldown.GetFloat(); - + public override string GetMark(PlayerControl seer, PlayerControl seen, bool isForMeeting = false) => KamikazedList.Contains(seen.PlayerId) ? Utils.ColorString(Utils.GetRoleColor(CustomRoles.Kamikaze), "∇") : string.Empty; @@ -50,27 +47,28 @@ public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl t { if (target.Is(CustomRoles.NiceMini) && Mini.Age < 18) { - killer.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Kamikaze), GetString("KamikazeHostage"))); + killer.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Kamikaze), GetString("KamikazeHostage"))); return false; } return killer.CheckDoubleTrigger(target, () => { - if (AbilityLimit >= 1 && !KamikazedList.Contains(target.PlayerId)) + + if (AbilityLimit >= 1 && !KamikazedList.Contains(target.PlayerId)) { KamikazedList.Add(target.PlayerId); killer.RpcGuardAndKill(killer); killer.SetKillCooldown(KillCooldown.GetFloat()); Utils.NotifyRoles(SpecifySeer: killer); AbilityLimit--; - SendRPC(); - } + SendSkillRPC(); + } else { killer.RpcMurderPlayer(target); } }); - + } public override void OnMurderPlayerAsTarget(PlayerControl killer, PlayerControl target, bool inMeeting, bool isSuicide) @@ -96,34 +94,6 @@ public override void OnMurderPlayerAsTarget(PlayerControl killer, PlayerControl pc.SetRealKiller(_Player); } KamikazedList.Clear(); - SendRPC(); - } - - public void SendRPC() - { - MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.SyncRoleSkill, SendOption.Reliable); - writer.WriteNetObject(_Player); - writer.Write(AbilityLimit); - writer.WritePacked(KamikazedList.Count); - foreach (var playerId in KamikazedList) - { - writer.Write(playerId); - } - AmongUsClient.Instance.FinishRpcImmediately(writer); - } - - public override void ReceiveRPC(MessageReader reader, PlayerControl pc) - { - AbilityLimit = reader.ReadSingle(); - var count = reader.ReadPackedInt32(); - KamikazedList.Clear(); - if (count > 0) - { - for (int i = 0; i < count; i++) - { - KamikazedList.Add(reader.ReadByte()); - } - } } public override string GetProgressText(byte playerId, bool comms) diff --git a/Roles/Impostor/KillingMachine.cs b/Roles/Impostor/KillingMachine.cs index c38665f56..a0aab068f 100644 --- a/Roles/Impostor/KillingMachine.cs +++ b/Roles/Impostor/KillingMachine.cs @@ -6,8 +6,11 @@ namespace TOHE.Roles.Impostor; internal class KillingMachine : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.KillingMachine; private const int Id = 23800; + + private static readonly HashSet PlayerIds = []; + public static bool HasEnabled => PlayerIds.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorKilling; //==================================================================\\ @@ -22,6 +25,15 @@ public override void SetupCustomOption() .SetValueFormat(OptionFormat.Seconds); } + public override void Init() + { + PlayerIds.Clear(); + } + public override void Add(byte playerId) + { + PlayerIds.Add(playerId); + } + public override bool CanUseImpostorVentButton(PlayerControl pc) => false; public override bool CanUseSabotage(PlayerControl pc) => false; public override void SetKillCooldown(byte id) => Main.AllPlayerKillCooldown[id] = MNKillCooldown.GetFloat(); diff --git a/Roles/Impostor/Lightning.cs b/Roles/Impostor/Lightning.cs index 70b8703b8..e5a9e8b75 100644 --- a/Roles/Impostor/Lightning.cs +++ b/Roles/Impostor/Lightning.cs @@ -9,8 +9,10 @@ namespace TOHE.Roles.Impostor; internal class Lightning : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Lightning; private const int Id = 24100; + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorConcealing; //==================================================================\\ @@ -33,9 +35,15 @@ public override void SetupCustomOption() } public override void Init() { + playerIdList.Clear(); GhostPlayer.Clear(); RealKiller.Clear(); } + public override void Add(byte playerId) + { + playerIdList.Add(playerId); + + } private static void SendRPC(byte playerId) { MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.LightningSetGhostPlayer, SendOption.Reliable, -1); @@ -64,10 +72,10 @@ public static void ReceiveRPC(MessageReader reader) } } public override void SetKillCooldown(byte id) => Main.AllPlayerKillCooldown[id] = KillCooldown.GetFloat(); - + public static bool IsGhost(PlayerControl player) => IsGhost(player.PlayerId); private static bool IsGhost(byte id) => GhostPlayer.Contains(id); - + public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { if (killer == null || target == null || !killer.Is(CustomRoles.Lightning)) return false; @@ -171,4 +179,4 @@ public override void SetAbilityButtonText(HudManager hud, byte playerId) { hud.KillButton.OverrideText(Translator.GetString("LightningButtonText")); } -} +} \ No newline at end of file diff --git a/Roles/Impostor/Ludopath.cs b/Roles/Impostor/Ludopath.cs index 65023310b..b25f06ec8 100644 --- a/Roles/Impostor/Ludopath.cs +++ b/Roles/Impostor/Ludopath.cs @@ -3,8 +3,10 @@ internal class Ludopath : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Ludopath; private const int Id = 1800; + private static readonly HashSet PlayerIds = []; + public static bool HasEnabled => PlayerIds.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorKilling; //==================================================================\\ @@ -18,6 +20,14 @@ public override void SetupCustomOption() .SetParent(Options.CustomRoleSpawnChances[CustomRoles.Ludopath]) .SetValueFormat(OptionFormat.Seconds); } + public override void Init() + { + PlayerIds.Clear(); + } + public override void Add(byte playerId) + { + PlayerIds.Add(playerId); + } public override void SetKillCooldown(byte id) => Main.AllPlayerKillCooldown[id] = LudopathRandomKillCD.GetFloat(); @@ -30,4 +40,4 @@ public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl t } return true; } -} +} \ No newline at end of file diff --git a/Roles/Impostor/Lurker.cs b/Roles/Impostor/Lurker.cs index 8c4412e23..5db4a4519 100644 --- a/Roles/Impostor/Lurker.cs +++ b/Roles/Impostor/Lurker.cs @@ -5,8 +5,11 @@ namespace TOHE.Roles.Impostor; internal class Lurker : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Lurker; private const int Id = 1900; + + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorKilling; //==================================================================\\ @@ -23,7 +26,16 @@ public override void SetupCustomOption() ReduceKillCooldown = FloatOptionItem.Create(Id + 11, GeneralOption.ReduceKillCooldown, new(0f, 10f, 1f), 2f, TabGroup.ImpostorRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Lurker]) .SetValueFormat(OptionFormat.Seconds); } - public override void SetKillCooldown(byte id) => Main.AllPlayerKillCooldown[id] = DefaultKillCooldown.GetFloat(); + public override void Init() + { + playerIdList.Clear(); + } + public override void Add(byte playerId) + { + playerIdList.Add(playerId); + } + + public override void SetKillCooldown(byte id) => Main.AllPlayerKillCooldown[id] = DefaultKillCooldown.GetFloat(); public override void OnEnterVent(PlayerControl pc, Vent vent) { diff --git a/Roles/Impostor/Mastermind.cs b/Roles/Impostor/Mastermind.cs index 897bf5787..2c975710f 100644 --- a/Roles/Impostor/Mastermind.cs +++ b/Roles/Impostor/Mastermind.cs @@ -8,11 +8,13 @@ namespace TOHE.Roles.Impostor; internal class Mastermind : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Mastermind; private const int Id = 4100; + + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorConcealing; - public override bool IsExperimental => true; //==================================================================\\ private static OptionItem KillCooldown; @@ -38,6 +40,7 @@ public override void SetupCustomOption() public override void Init() { + playerIdList.Clear(); ManipulatedPlayers.Clear(); ManipulateDelays.Clear(); TempKCDs.Clear(); @@ -45,16 +48,13 @@ public override void Init() public override void Add(byte playerId) { + playerIdList.Add(playerId); ManipulateCD = KillCooldown.GetFloat() + (TimeLimit.GetFloat() / 2) + (Delay.GetFloat() / 2); // Double Trigger var pc = GetPlayerById(playerId); pc.AddDoubleTrigger(); - } - public override void Remove(byte playerId) - { - DoubleTrigger.PlayerIdList.Remove(playerId); } public override void SetKillCooldown(byte id) => Main.AllPlayerKillCooldown[id] = KillCooldown.GetFloat(); @@ -139,7 +139,7 @@ public override void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInf { pc.SetDeathReason(PlayerState.DeathReason.Suicide); pc.RpcMurderPlayer(pc); - pc.SetRealKiller(GetPlayerById(_playerIdList.First())); + pc.SetRealKiller(GetPlayerById(playerIdList.First())); } } ManipulateDelays.Clear(); @@ -153,7 +153,7 @@ public override bool CheckMurderOnOthersTarget(PlayerControl killer, PlayerContr ManipulatedPlayers.Remove(killer.PlayerId); - var mastermind = GetPlayerById(_playerIdList.First()); + var mastermind = GetPlayerById(playerIdList.First()); mastermind?.Notify(string.Format(GetString("ManipulatedKilled"), killer.GetRealName()), 4f); mastermind?.SetKillCooldown(time: KillCooldown.GetFloat()); killer.Notify(GetString("SurvivedManipulation")); diff --git a/Roles/Impostor/Mercenary.cs b/Roles/Impostor/Mercenary.cs index 0956ca79d..f7964eb60 100644 --- a/Roles/Impostor/Mercenary.cs +++ b/Roles/Impostor/Mercenary.cs @@ -7,8 +7,10 @@ namespace TOHE.Roles.Impostor; internal class Mercenary : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Mercenary; private const int Id = 2000; + public static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Shapeshifter; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorKilling; //==================================================================\\ @@ -30,10 +32,12 @@ public override void SetupCustomOption() } public override void Init() { + playerIdList.Clear(); SuicideTimer.Clear(); } public override void Add(byte serial) { + playerIdList.Add(serial); OptTimeLimit = TimeLimit.GetFloat(); } @@ -103,17 +107,17 @@ public override void SetAbilityButtonText(HudManager hud, byte playerId) public override void AfterMeetingTasks() { - foreach (var id in _playerIdList) + foreach (var id in playerIdList) { var pc = Utils.GetPlayerById(id); - + if (pc != null && pc.IsAlive()) { pc.RpcResetAbilityCooldown(); - + if (HasKilled(pc)) SuicideTimer[id] = 0f; } } } -} +} \ No newline at end of file diff --git a/Roles/Impostor/Miner.cs b/Roles/Impostor/Miner.cs index 04fda0861..6d56f1dbc 100644 --- a/Roles/Impostor/Miner.cs +++ b/Roles/Impostor/Miner.cs @@ -6,8 +6,10 @@ namespace TOHE.Roles.Impostor; internal class Miner : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Miner; private const int Id = 4200; + private static readonly HashSet PlayerIds = []; + public static bool HasEnabled => PlayerIds.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Shapeshifter; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorConcealing; //==================================================================\\ @@ -25,6 +27,15 @@ public override void SetupCustomOption() .SetParent(Options.CustomRoleSpawnChances[CustomRoles.Miner]) .SetValueFormat(OptionFormat.Seconds); } + public override void Init() + { + PlayerIds.Clear(); + } + public override void Add(byte playerId) + { + PlayerIds.Add(playerId); + } + public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.ShapeshifterCooldown = MinerSSCD.GetFloat(); diff --git a/Roles/Impostor/Morphling.cs b/Roles/Impostor/Morphling.cs index 30ce84c52..d46093484 100644 --- a/Roles/Impostor/Morphling.cs +++ b/Roles/Impostor/Morphling.cs @@ -6,8 +6,10 @@ namespace TOHE.Roles.Impostor; internal class Morphling : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Morphling; private const int Id = 3500; + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Shapeshifter; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorSupport; //===========================SETUP================================\\ @@ -27,6 +29,14 @@ public override void SetupCustomOption() ShapeshiftDur = FloatOptionItem.Create(Id + 16, GeneralOption.ShapeshifterBase_ShapeshiftDuration, new(1f, 180f, 1f), 25f, TabGroup.ImpostorRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Morphling]) .SetValueFormat(OptionFormat.Seconds); } + public override void Init() + { + playerIdList.Clear(); + } + public override void Add(byte playerId) + { + playerIdList.Add(playerId); + } public override bool CanUseKillButton(PlayerControl player) { @@ -44,4 +54,4 @@ public override void ApplyGameOptions(IGameOptions opt, byte playerId) } public override void SetKillCooldown(byte id) => Main.AllPlayerKillCooldown[id] = KillCooldown.GetFloat(); -} +} \ No newline at end of file diff --git a/Roles/Impostor/Nemesis.cs b/Roles/Impostor/Nemesis.cs index 5767aa182..cc57315e1 100644 --- a/Roles/Impostor/Nemesis.cs +++ b/Roles/Impostor/Nemesis.cs @@ -3,23 +3,24 @@ using TOHE.Modules; using TOHE.Roles.Double; using UnityEngine; -using static TOHE.MeetingHudStartPatch; using static TOHE.Options; using static TOHE.Translator; +using static TOHE.MeetingHudStartPatch; namespace TOHE.Roles.Impostor; internal class Nemesis : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Nemesis; private const int Id = 3600; + private static readonly HashSet PlayerIds = []; + public static bool HasEnabled => PlayerIds.Any(); + public override CustomRoles ThisRoleBase => LegacyNemesis.GetBool() ? CustomRoles.Shapeshifter : CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorSupport; //==================================================================\\ private static OptionItem NemesisCanKillNum; - public static OptionItem PreventSeeRolesBeforeSkillUsedUp; public static OptionItem LegacyNemesis; private static OptionItem NemesisShapeshiftCD; private static OptionItem NemesisShapeshiftDur; @@ -32,8 +33,6 @@ public override void SetupCustomOption() NemesisCanKillNum = IntegerOptionItem.Create(Id + 10, "NemesisCanKillNum", new(0, 15, 1), 1, TabGroup.ImpostorRoles, false) .SetParent(CustomRoleSpawnChances[CustomRoles.Nemesis]) .SetValueFormat(OptionFormat.Players); - PreventSeeRolesBeforeSkillUsedUp = BooleanOptionItem.Create(Id + 14, "PreventSeeRolesBeforeSkillUsedUp", true, TabGroup.ImpostorRoles, false) - .SetParent(CustomRoleSpawnChances[CustomRoles.Nemesis]); LegacyNemesis = BooleanOptionItem.Create(Id + 11, "LegacyNemesis", false, TabGroup.ImpostorRoles, false) .SetParent(CustomRoleSpawnChances[CustomRoles.Nemesis]); NemesisShapeshiftCD = FloatOptionItem.Create(Id + 12, GeneralOption.ShapeshifterBase_ShapeshiftCooldown, new(1f, 180f, 1f), 15f, TabGroup.ImpostorRoles, false) @@ -46,6 +45,11 @@ public override void SetupCustomOption() public override void Init() { NemesisRevenged.Clear(); + PlayerIds.Clear(); + } + public override void Add(byte playerId) + { + PlayerIds.Add(playerId); } public override void ApplyGameOptions(IGameOptions opt, byte playerId) @@ -53,13 +57,7 @@ public override void ApplyGameOptions(IGameOptions opt, byte playerId) AURoleOptions.ShapeshifterCooldown = NemesisShapeshiftCD.GetFloat(); AURoleOptions.ShapeshifterDuration = NemesisShapeshiftDur.GetFloat(); } - public static bool PreventKnowRole(PlayerControl seer) - { - if (!seer.Is(CustomRoles.Nemesis) || seer.IsAlive()) return false; - if (PreventSeeRolesBeforeSkillUsedUp.GetBool() && NemesisRevenged.TryGetValue(seer.PlayerId, out var killNum) && killNum < NemesisCanKillNum.GetInt()) - return true; - return false; - } + public override void OnMeetingHudStart(PlayerControl player) { if (!player.IsAlive()) @@ -73,7 +71,7 @@ public static bool NemesisMsgCheck(PlayerControl pc, string msg, bool isUI = fal if (!pc.Is(CustomRoles.Nemesis)) return false; msg = msg.Trim().ToLower(); if (msg.Length < 3 || msg[..3] != "/rv") return false; - + if (NemesisCanKillNum.GetInt() < 1) { pc.ShowInfoMessage(isUI, GetString("NemesisKillDisable")); @@ -198,7 +196,7 @@ public static void ReceiveRPC_Custom(MessageReader reader, PlayerControl pc) public static bool CheckCanUseKillButton() { if (Main.PlayerStates == null) return false; - + // Number of Living Impostors excluding Nemesis int LivingImpostorsNum = 0; foreach (var player in Main.AllAlivePlayerControls) @@ -256,4 +254,4 @@ public static void CreateJudgeButton(MeetingHud __instance) button.OnClick.AddListener((UnityEngine.Events.UnityAction)(() => NemesisOnClick(pva.TargetPlayerId/*, __instance*/))); } } -} +} \ No newline at end of file diff --git a/Roles/Impostor/Ninja.cs b/Roles/Impostor/Ninja.cs index 4efe9d0f5..56e09ef65 100644 --- a/Roles/Impostor/Ninja.cs +++ b/Roles/Impostor/Ninja.cs @@ -12,8 +12,10 @@ namespace TOHE.Roles.Impostor; internal class Ninja : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Ninja; private const int Id = 2100; + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Shapeshifter; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorKilling; //==================================================================\\ @@ -36,10 +38,13 @@ public override void SetupCustomOption() } public override void Init() { + playerIdList.Clear(); MarkedPlayer.Clear(); } public override void Add(byte playerId) { + playerIdList.Add(playerId); + var pc = Utils.GetPlayerById(playerId); pc.AddDoubleTrigger(); } @@ -62,7 +67,7 @@ public static void ReceiveRPC(MessageReader reader) } private static bool Shapeshifting(byte id) => Main.CheckShapeshift.TryGetValue(id, out bool shapeshifting) && shapeshifting; - + public override void SetKillCooldown(byte id) => Main.AllPlayerKillCooldown[id] = Shapeshifting(id) ? DefaultKillCooldown : MarkCooldown.GetFloat(); @@ -80,9 +85,9 @@ public override bool ForcedCheckMurderAsKiller(PlayerControl killer, PlayerContr killer.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Gangster), GetString("CantMark"))); return true; } - + return killer.CheckDoubleTrigger(target, - () => + () => { MarkedPlayer.Remove(killer.PlayerId); MarkedPlayer.Add(killer.PlayerId, target.PlayerId); @@ -119,7 +124,7 @@ public override bool OnCheckShapeshift(PlayerControl shapeshifter, PlayerControl if (MarkedPlayer.TryGetValue(shapeshifter.PlayerId, out var targetId)) { var marketTarget = Utils.GetPlayerById(targetId); - + MarkedPlayer.Remove(shapeshifter.PlayerId); SendRPC(shapeshifter.PlayerId); @@ -167,4 +172,4 @@ public override void SetAbilityButtonText(HudManager hud, byte playerid) public override Sprite GetKillButtonSprite(PlayerControl player, bool shapeshifting) => !shapeshifting ? CustomButton.Get("Mark") : null; public override Sprite GetAbilityButtonSprite(PlayerControl player, bool shapeshifting) => !shapeshifting && MarkedPlayer.ContainsKey(player.PlayerId) ? CustomButton.Get("Assassinate") : null; -} +} \ No newline at end of file diff --git a/Roles/Impostor/Parasite.cs b/Roles/Impostor/Parasite.cs index bddf9a6e8..09ea6f33a 100644 --- a/Roles/Impostor/Parasite.cs +++ b/Roles/Impostor/Parasite.cs @@ -1,44 +1,40 @@ -using AmongUs.GameOptions; + +using AmongUs.GameOptions; namespace TOHE.Roles.Impostor; internal class Parasite : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Parasite; private const int Id = 5900; - - public override CustomRoles ThisRoleBase => LegacyParasite.GetBool() ? CustomRoles.Shapeshifter : CustomRoles.Impostor; + private static readonly HashSet Playerids = []; + public static bool HasEnabled => Playerids.Any(); + + public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.Madmate; //==================================================================\\ private static OptionItem ParasiteCD; - private static OptionItem LegacyParasite; - private static OptionItem ParasiteShapeshiftCD; - private static OptionItem ParasiteShapeshiftDur; public override void SetupCustomOption() { Options.SetupSingleRoleOptions(Id, TabGroup.ImpostorRoles, CustomRoles.Parasite, zeroOne: false); - ParasiteCD = FloatOptionItem.Create(Id + 10, GeneralOption.KillCooldown, new(0f, 180f, 2.5f), 30f, TabGroup.ImpostorRoles, false) + ParasiteCD = FloatOptionItem.Create(Id + 2, GeneralOption.KillCooldown, new(0f, 180f, 2.5f), 30f, TabGroup.ImpostorRoles, false) .SetParent(Options.CustomRoleSpawnChances[CustomRoles.Parasite]) .SetValueFormat(OptionFormat.Seconds); - LegacyParasite = BooleanOptionItem.Create(Id + 11, "LegacyParasite", false, TabGroup.ImpostorRoles, false) - .SetParent(Options.CustomRoleSpawnChances[CustomRoles.Parasite]); - ParasiteShapeshiftCD = FloatOptionItem.Create(Id + 12, GeneralOption.ShapeshifterBase_ShapeshiftCooldown, new(1f, 180f, 1f), 15f, TabGroup.ImpostorRoles, false) - .SetParent(LegacyParasite) - .SetValueFormat(OptionFormat.Seconds); - ParasiteShapeshiftDur = FloatOptionItem.Create(Id + 13, GeneralOption.ShapeshifterBase_ShapeshiftDuration, new(1f, 180f, 1f), 30f, TabGroup.ImpostorRoles, false) - .SetParent(LegacyParasite) - .SetValueFormat(OptionFormat.Seconds); } - public override void ApplyGameOptions(IGameOptions opt, byte playerId) + public override void Init() + { + Playerids.Clear(); + } + public override void Add(byte playerId) { - opt.SetVision(true); - AURoleOptions.ShapeshifterCooldown = ParasiteShapeshiftCD.GetFloat(); - AURoleOptions.ShapeshifterDuration = ParasiteShapeshiftDur.GetFloat(); + Playerids.Add(playerId); } + + public override void ApplyGameOptions(IGameOptions opt, byte playerId) => opt.SetVision(true); public override void SetKillCooldown(byte id) => Main.AllPlayerKillCooldown[id] = ParasiteCD.GetFloat(); + public override bool CanUseKillButton(PlayerControl pc) => true; public override bool CanUseImpostorVentButton(PlayerControl pc) => true; public override bool CanUseSabotage(PlayerControl pc) => true; diff --git a/Roles/Impostor/Penguin.cs b/Roles/Impostor/Penguin.cs index fb80b43f3..f2b2d238d 100644 --- a/Roles/Impostor/Penguin.cs +++ b/Roles/Impostor/Penguin.cs @@ -1,10 +1,10 @@ -using AmongUs.GameOptions; -using Hazel; -using InnerNet; -using TOHE.Roles.Core; +using Hazel; +using AmongUs.GameOptions; using UnityEngine; -using static TOHE.Options; using static TOHE.Translator; +using static TOHE.Options; +using TOHE.Roles.Core; +using InnerNet; // https://github.com/tukasa0001/TownOfHost/blob/main/Roles/Impostor/Penguin.cs namespace TOHE.Roles.Impostor; @@ -12,7 +12,6 @@ namespace TOHE.Roles.Impostor; internal class Penguin : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Penguin; private const int Id = 27500; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Penguin); public override CustomRoles ThisRoleBase => CustomRoles.Shapeshifter; @@ -223,7 +222,7 @@ public override void OnFixedUpdate(PlayerControl penguin, bool lowLoad, long now penguin.MurderPlayer(abductVictim, ExtendedPlayerControl.ResultFlags); var sender = CustomRpcSender.Create("PenguinMurder"); - { + { sender.AutoStartRpc(abductVictim.NetTransform.NetId, (byte)RpcCalls.SnapTo); { NetHelpers.WriteVector2(penguin.transform.position, sender.stream); diff --git a/Roles/Impostor/Pitfall.cs b/Roles/Impostor/Pitfall.cs index f13b4f8ff..b374acd3e 100644 --- a/Roles/Impostor/Pitfall.cs +++ b/Roles/Impostor/Pitfall.cs @@ -10,8 +10,10 @@ namespace TOHE.Roles.Impostor; internal class Pitfall : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Pitfall; private const int Id = 5600; + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Shapeshifter; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorHindering; //==================================================================\\ @@ -54,6 +56,7 @@ public override void SetupCustomOption() } public override void Init() { + playerIdList.Clear(); Traps.Clear(); ReducedVisionPlayers.Clear(); DefaultSpeed = new(); @@ -62,6 +65,7 @@ public override void Init() } public override void Add(byte playerId) { + playerIdList.Add(playerId); DefaultSpeed = Main.AllPlayerSpeed[playerId]; TrapMaxPlayerCount = TrapMaxPlayerCountOpt.GetFloat(); @@ -78,9 +82,6 @@ public override void ApplyGameOptions(IGameOptions opt, byte playerId) AURoleOptions.ShapeshifterCooldown = ShapeshiftCooldown.GetFloat(); } - public override void SetAbilityButtonText(HudManager hud, byte id) => hud.AbilityButton.OverrideText(Translator.GetString("PitfallButtonText")); - // public override Sprite GetAbilityButtonSprite(PlayerControl player, bool shapeshifting) => CustomButton.Get("Set Trap"); - public override void UnShapeShiftButton(PlayerControl shapeshifter) { //if (!CheckUnshapeshift) return; diff --git a/Roles/Impostor/Puppeteer.cs b/Roles/Impostor/Puppeteer.cs index d5e880357..054a6da75 100644 --- a/Roles/Impostor/Puppeteer.cs +++ b/Roles/Impostor/Puppeteer.cs @@ -13,8 +13,10 @@ namespace TOHE.Roles.Impostor; internal class Puppeteer : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Puppeteer; private const int Id = 4300; + private static readonly HashSet PlayerIds = []; + public static bool HasEnabled => PlayerIds.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorConcealing; //==================================================================\\ @@ -31,6 +33,7 @@ public override void SetupCustomOption() } public override void Init() { + PlayerIds.Clear(); PuppeteerList.Clear(); } public override void Add(byte playerId) @@ -39,16 +42,13 @@ public override void Add(byte playerId) var pc = Utils.GetPlayerById(playerId); pc.AddDoubleTrigger(); + PlayerIds.Add(playerId); + if (AmongUsClient.Instance.AmHost) { CustomRoleManager.OnFixedUpdateOthers.Add(OnFixedUpdateOthers); } } - public override void Remove(byte playerId) - { - DoubleTrigger.PlayerIdList.Remove(playerId); - CustomRoleManager.OnFixedUpdateOthers.Remove(OnFixedUpdateOthers); - } private static void SendRPC(byte puppetId, byte targetId, byte typeId) { @@ -82,19 +82,19 @@ public static void ReceiveRPC(MessageReader reader) public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { - if (target.Is(CustomRoles.LazyGuy) + if (target.Is(CustomRoles.LazyGuy) || target.Is(CustomRoles.Lazy) || target.Is(CustomRoles.NiceMini) && Mini.Age < 18) return false; - return killer.CheckDoubleTrigger(target, () => - { - PuppeteerList[target.PlayerId] = killer.PlayerId; - killer.SetKillCooldown(); - SendRPC(killer.PlayerId, target.PlayerId, 1); - killer.RPCPlayCustomSound("Line"); - Utils.NotifyRoles(SpecifySeer: killer, SpecifyTarget: target); - }); + return killer.CheckDoubleTrigger(target, () => + { + PuppeteerList[target.PlayerId] = killer.PlayerId; + killer.SetKillCooldown(); + SendRPC(killer.PlayerId, target.PlayerId, 1); + killer.RPCPlayCustomSound("Line"); + Utils.NotifyRoles(SpecifySeer: killer, SpecifyTarget: target); + }); } private void OnFixedUpdateOthers(PlayerControl puppet, bool lowLoad, long nowTime) diff --git a/Roles/Impostor/QuickShooter.cs b/Roles/Impostor/QuickShooter.cs index 09e24bd51..e8fd5dc0a 100644 --- a/Roles/Impostor/QuickShooter.cs +++ b/Roles/Impostor/QuickShooter.cs @@ -1,6 +1,4 @@ using AmongUs.GameOptions; -using Hazel; -using InnerNet; using System; using TOHE.Modules; using TOHE.Roles.Core; @@ -11,7 +9,6 @@ namespace TOHE.Roles.Impostor; internal class QuickShooter : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.QuickShooter; private const int Id = 2200; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.QuickShooter); public override CustomRoles ThisRoleBase => CustomRoles.Shapeshifter; @@ -53,33 +50,6 @@ public override void SetKillCooldown(byte id) Storaging = false; } - public void SendRPC(bool timer = false) - { - var writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.SyncRoleSkill, SendOption.Reliable, _Player.GetClientId()); - writer.WriteNetObject(_Player); - writer.Write((byte)AbilityLimit); - - if (_Player == null) { timer = false; } - writer.Write(timer); - if (timer) - writer.Write(_Player.GetKillTimer()); - AmongUsClient.Instance.FinishRpcImmediately(writer); - } - - public override void ReceiveRPC(MessageReader reader, PlayerControl pc) - { - AbilityLimit = reader.ReadByte(); - var shouldtime = reader.ReadBoolean(); - float timer = 0f; - if (shouldtime) - { - timer = reader.ReadSingle(); - } - - if (pc.AmOwner && shouldtime) - DestroyableSingleton.Instance.AbilityButton.SetCoolDown(timer, ShapeshiftCooldown.GetFloat()); - } - public override bool OnCheckShapeshift(PlayerControl shapeshifter, PlayerControl target, ref bool resetCooldown, ref bool shouldAnimate) { if (shapeshifter.PlayerId == target.PlayerId) return false; @@ -90,22 +60,16 @@ public override bool OnCheckShapeshift(PlayerControl shapeshifter, PlayerControl if (killTimer <= 0) { AbilityLimit++; - SendRPC(); + SendSkillRPC(); resetCooldown = false; Storaging = true; shapeshifter.ResetKillCooldown(); shapeshifter.SetKillCooldown(); - shapeshifter.RpcResetAbilityCooldown(); shapeshifter.Notify(Translator.GetString("QuickShooterStoraging")); Logger.Info($"{Utils.GetPlayerById(shapeshifter.PlayerId)?.GetNameWithRole()} : shot limit: {AbilityLimit}", "QuickShooter"); } - else - { - shapeshifter.Notify(Translator.GetString("QuickShooterFailed")); - SendRPC(true); - } return false; } public override void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo target) @@ -113,20 +77,21 @@ public override void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInf NewSL[_state.PlayerId] = Math.Clamp((int)AbilityLimit, 0, MeetingReserved.GetInt()); AbilityLimit = NewSL[_state.PlayerId]; - SendRPC(); + SendSkillRPC(); + } public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { AbilityLimit--; AbilityLimit = Math.Max(AbilityLimit, 0); - SendRPC(); + SendSkillRPC(); return true; } public override string GetProgressText(byte playerId, bool comms) => Utils.ColorString(AbilityLimit > 0 - ? Utils.GetRoleColor(CustomRoles.QuickShooter).ShadeColor(0.25f) + ? Utils.GetRoleColor(CustomRoles.QuickShooter).ShadeColor(0.25f) : Color.gray, $"({AbilityLimit})"); public override void SetAbilityButtonText(HudManager hud, byte playerId) @@ -134,4 +99,4 @@ public override void SetAbilityButtonText(HudManager hud, byte playerId) hud.AbilityButton?.OverrideText(Translator.GetString("QuickShooterShapeshiftText")); hud.AbilityButton?.SetUsesRemaining((int)AbilityLimit); } -} +} \ No newline at end of file diff --git a/Roles/Impostor/Refugee.cs b/Roles/Impostor/Refugee.cs index e11fe0f73..b5e33f294 100644 --- a/Roles/Impostor/Refugee.cs +++ b/Roles/Impostor/Refugee.cs @@ -6,8 +6,10 @@ namespace TOHE.Roles.Impostor; internal class Refugee : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Refugee; private const int Id = 60009; + private static readonly HashSet PlayerIds = []; + public static bool HasEnabled => PlayerIds.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.Madmate; //==================================================================\\ @@ -21,6 +23,14 @@ public override void SetupCustomOption() .SetValueFormat(OptionFormat.Seconds) .SetGameMode(CustomGameMode.Standard); } + public override void Init() + { + PlayerIds.Clear(); + } + public override void Add(byte playerId) + { + PlayerIds.Add(playerId); + } public override void ApplyGameOptions(IGameOptions opt, byte playerId) => opt.SetVision(true); public override void SetKillCooldown(byte id) => Main.AllPlayerKillCooldown[id] = RefugeeKillCD.GetFloat(); diff --git a/Roles/Impostor/RiftMaker.cs b/Roles/Impostor/RiftMaker.cs index d0f27cff4..7fdb32b31 100644 --- a/Roles/Impostor/RiftMaker.cs +++ b/Roles/Impostor/RiftMaker.cs @@ -1,7 +1,5 @@ using AmongUs.GameOptions; using Hazel; -using InnerNet; -using TOHE.Modules; using TOHE.Roles.Neutral; using UnityEngine; using static TOHE.Translator; @@ -11,9 +9,10 @@ namespace TOHE.Roles.Impostor; internal class RiftMaker : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.RiftMaker; private const int Id = 27200; - + private static readonly HashSet Playerids = []; + public static bool HasEnabled => Playerids.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Shapeshifter; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorConcealing; //==================================================================\\ @@ -22,9 +21,9 @@ internal class RiftMaker : RoleBase private static OptionItem KillCooldown; private static OptionItem TPCooldownOpt; private static OptionItem RiftRadius; + private static OptionItem ShowShapeshiftAnimationsOpt; - private readonly Dictionary MarkedLocation = []; - private Vector2 Lastadded = Vector2.zero; + private static readonly Dictionary> MarkedLocation = []; private static readonly Dictionary LastTP = []; private static float TPCooldown = new(); @@ -35,33 +34,33 @@ public override void SetupCustomOption() .SetValueFormat(OptionFormat.Seconds); SSCooldown = FloatOptionItem.Create(Id + 11, GeneralOption.ShapeshifterBase_ShapeshiftCooldown, new(0f, 180f, 2.5f), 25f, TabGroup.ImpostorRoles, false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.RiftMaker]) .SetValueFormat(OptionFormat.Seconds); - TPCooldownOpt = FloatOptionItem.Create(Id + 12, "TPCooldown", new(2.5f, 25f, 2.5f), 5f, TabGroup.ImpostorRoles, false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.RiftMaker]) + TPCooldownOpt = FloatOptionItem.Create(Id + 12, "TPCooldown", new(5f, 25f, 2.5f), 5f, TabGroup.ImpostorRoles, false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.RiftMaker]) .SetValueFormat(OptionFormat.Seconds); - RiftRadius = FloatOptionItem.Create(Id + 13, "RiftRadius", new(0.5f, 4f, 0.5f), 1f, TabGroup.ImpostorRoles, false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.RiftMaker]) + RiftRadius = FloatOptionItem.Create(Id + 13, "RiftRadius", new(0.5f, 2f, 0.5f), 1f, TabGroup.ImpostorRoles, false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.RiftMaker]) .SetValueFormat(OptionFormat.Multiplier); + ShowShapeshiftAnimationsOpt = BooleanOptionItem.Create(Id + 14, GeneralOption.ShowShapeshiftAnimations, true, TabGroup.ImpostorRoles, false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.RiftMaker]); } public override void Init() { + Playerids.Clear(); MarkedLocation.Clear(); LastTP.Clear(); TPCooldown = new(); } public override void Add(byte playerId) { + MarkedLocation[playerId] = []; var now = Utils.GetTimeStamp(); LastTP[playerId] = now; TPCooldown = TPCooldownOpt.GetFloat(); + Playerids.Add(playerId); } - public override void SetAbilityButtonText(HudManager hud, byte id) => hud.AbilityButton.OverrideText(Translator.GetString("RiftMakerButtonText")); - // public override Sprite GetAbilityButtonSprite(PlayerControl player, bool shapeshifting) => CustomButton.Get("Create Rift"); - - private void SendRPC(byte riftID, int operate) + private static void SendRPC(byte riftID, int operate) { - MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.SyncRoleSkill, SendOption.Reliable, -1); - writer.WriteNetObject(_Player); + MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.RiftMakerSyncData, SendOption.Reliable, -1); writer.Write(operate); if (operate == 3) { @@ -72,9 +71,9 @@ private void SendRPC(byte riftID, int operate) if (operate == 0) //sync markedloaction and last tp { - int length = MarkedLocation.Count; - writer.Write(MarkedLocation.ElementAt(length - 1).Key.x); //x coordinate - writer.Write(MarkedLocation.ElementAt(length - 1).Key.y); //y coordinate + int length = MarkedLocation[riftID].Count; + writer.Write(MarkedLocation[riftID][length - 1].x); //x coordinate + writer.Write(MarkedLocation[riftID][length - 1].y); //y coordinate writer.Write(LastTP[riftID].ToString()); } @@ -84,7 +83,7 @@ private void SendRPC(byte riftID, int operate) } AmongUsClient.Instance.FinishRpcImmediately(writer); } - public override void ReceiveRPC(MessageReader reader, PlayerControl pc) + public static void ReceiveRPC(MessageReader reader) { int operate = reader.ReadInt32(); if (operate == 3) @@ -101,15 +100,16 @@ public override void ReceiveRPC(MessageReader reader, PlayerControl pc) { float xLoc = reader.ReadSingle(); float yLoc = reader.ReadSingle(); - if (MarkedLocation.Count >= 2) MarkedLocation.Remove(MarkedLocation.ElementAt(0).Key); - MarkedLocation.Add(new Vector2(xLoc, yLoc), new(pc.GetCustomPosition(), [], pc.PlayerId)); + if (!MarkedLocation.ContainsKey(riftID)) MarkedLocation[riftID] = []; + if (MarkedLocation[riftID].Count >= 2) MarkedLocation[riftID].RemoveAt(0); + MarkedLocation[riftID].Add(new Vector2(xLoc, yLoc)); string stimeStamp = reader.ReadString(); if (long.TryParse(stimeStamp, out long timeStamp)) LastTP[riftID] = timeStamp; } else if (operate == 1) //clear marked location { - MarkedLocation.Clear(); + if (MarkedLocation.ContainsKey(riftID)) MarkedLocation[riftID].Clear(); } else if (operate == 2) //sync last tp { @@ -121,40 +121,64 @@ public override void ReceiveRPC(MessageReader reader, PlayerControl pc) public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.ShapeshifterCooldown = SSCooldown.GetFloat(); + AURoleOptions.ShapeshifterLeaveSkin = true; + AURoleOptions.ShapeshifterDuration = 1f; } public override void SetKillCooldown(byte id) => Main.AllPlayerKillCooldown[id] = KillCooldown.GetFloat(); - public override void UnShapeShiftButton(PlayerControl shapeshifter) + public override bool OnCheckShapeshift(PlayerControl shapeshifter, PlayerControl target, ref bool resetCooldown, ref bool shouldAnimate) + { + // Unshift + if (shapeshifter.PlayerId == target.PlayerId) + { + // No animate unshift + if (shouldAnimate) + { + shouldAnimate = false; + } + return true; + } + + // Always do animation shapeshift + if (ShowShapeshiftAnimationsOpt.GetBool()) return true; + + + DoRifts(shapeshifter, target); + return false; + } + public override void OnShapeshift(PlayerControl shapeshifter, PlayerControl target, bool IsAnimate, bool shapeshifting) + { + if (!shapeshifting) return; + + DoRifts(shapeshifter, target); + } + + private static void DoRifts(PlayerControl shapeshifter, PlayerControl target) { var shapeshifterId = shapeshifter.PlayerId; + if (!MarkedLocation.ContainsKey(shapeshifterId)) MarkedLocation[shapeshifterId] = []; var currentPos = shapeshifter.GetCustomPosition(); - var totalMarked = MarkedLocation.Count; - if (totalMarked == 1 && Utils.GetDistance(currentPos, MarkedLocation.ElementAt(0).Key) <= 5f) + var totalMarked = MarkedLocation[shapeshifterId].Count; + if (totalMarked == 1 && Utils.GetDistance(currentPos, MarkedLocation[shapeshifterId][0]) <= 5f) { shapeshifter.Notify(GetString("RiftsTooClose")); return; } - else if (totalMarked == 2 && Utils.GetDistance(currentPos, MarkedLocation.ElementAt(1).Key) <= 5f) + else if (totalMarked == 2 && Utils.GetDistance(currentPos, MarkedLocation[shapeshifterId][1]) <= 5f) { shapeshifter.Notify(GetString("RiftsTooClose")); return; } - if (totalMarked >= 2) - { - MarkedLocation.First(x => x.Key != Lastadded).Value.Despawn(); - MarkedLocation.Remove(MarkedLocation.First(x => x.Key != Lastadded).Key); - } + if (totalMarked >= 2) MarkedLocation[shapeshifterId].RemoveAt(0); - MarkedLocation.Add(shapeshifter.GetCustomPosition(), new(shapeshifter.GetCustomPosition(), [_state.PlayerId], _state.PlayerId)); - Lastadded = shapeshifter.GetCustomPosition(); - if (MarkedLocation.Count == 2) LastTP[shapeshifterId] = Utils.GetTimeStamp(); + MarkedLocation[shapeshifterId].Add(shapeshifter.GetCustomPosition()); + if (MarkedLocation[shapeshifterId].Count == 2) LastTP[shapeshifterId] = Utils.GetTimeStamp(); shapeshifter.Notify(GetString("RiftCreated")); SendRPC(shapeshifterId, 0); //sendrpc for marked location and lasttp - return; } public override void OnCoEnterVent(PlayerPhysics physics, int ventId) @@ -166,7 +190,7 @@ public override void OnCoEnterVent(PlayerPhysics physics, int ventId) { physics?.RpcBootFromVent(ventId); - MarkedLocation.Clear(); + MarkedLocation[player.PlayerId].Clear(); //send rpc for clearing markedlocation SendRPC(player.PlayerId, 1); player.Notify(GetString("RiftsDestroyed")); @@ -176,30 +200,29 @@ public override void OnCoEnterVent(PlayerPhysics physics, int ventId) public override void OnFixedUpdate(PlayerControl player, bool lowLoad, long nowTime) { - if (player == null) return; - if (Pelican.IsEaten(player.PlayerId) || !player.IsAlive()) return; - byte playerId = player.PlayerId; - if (MarkedLocation.Count != 2) return; + if (lowLoad || Pelican.IsEaten(playerId) || !player.IsAlive()) return; + if (!MarkedLocation.TryGetValue(playerId, out var locationList)) return; - var now = Utils.GetTimeStamp(); - if (!LastTP.ContainsKey(playerId)) LastTP[playerId] = now; - if (now - LastTP[playerId] <= TPCooldown) return; + if (locationList.Count != 2) return; + + if (!LastTP.ContainsKey(playerId)) LastTP[playerId] = nowTime; + if (nowTime - LastTP[playerId] <= TPCooldown) return; Vector2 position = player.GetCustomPosition(); Vector2 TPto; - if (Vector2.Distance(position, MarkedLocation.ElementAt(0).Key) <= RiftRadius.GetFloat()) + if (Utils.GetDistance(position, locationList[0]) <= RiftRadius.GetFloat()) { - TPto = MarkedLocation.ElementAt(1).Key; + TPto = locationList[1]; } - else if (Vector2.Distance(position, MarkedLocation.ElementAt(1).Key) <= RiftRadius.GetFloat()) + else if (Utils.GetDistance(position, locationList[1]) <= RiftRadius.GetFloat()) { - TPto = MarkedLocation.ElementAt(0).Key; + TPto = locationList[0]; } else return; - LastTP[playerId] = now; + LastTP[playerId] = nowTime; //SENDRPC SendRPC(playerId, 2); player.RpcTeleport(TPto); diff --git a/Roles/Impostor/Saboteur.cs b/Roles/Impostor/Saboteur.cs index 9c346babb..3b374bb6b 100644 --- a/Roles/Impostor/Saboteur.cs +++ b/Roles/Impostor/Saboteur.cs @@ -5,8 +5,10 @@ namespace TOHE.Roles.Impostor; internal class Saboteur : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Saboteur; private const int Id = 2300; + private static readonly HashSet PlayerIds = []; + public static bool HasEnabled => PlayerIds.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorKilling; //==================================================================\\ @@ -20,6 +22,14 @@ public override void SetupCustomOption() .SetParent(Options.CustomRoleSpawnChances[CustomRoles.Saboteur]) .SetValueFormat(OptionFormat.Seconds); } + public override void Init() + { + PlayerIds.Clear(); + } + public override void Add(byte playerId) + { + PlayerIds.Add(playerId); + } public override void SetKillCooldown(byte id) => Main.AllPlayerKillCooldown[id] = SaboteurCD.GetFloat(); @@ -30,4 +40,4 @@ public static bool IsCriticalSabotage() || IsActive(SystemTypes.LifeSupp) || IsActive(SystemTypes.Reactor) || IsActive(SystemTypes.HeliSabotage); -} +} \ No newline at end of file diff --git a/Roles/Impostor/Scavenger.cs b/Roles/Impostor/Scavenger.cs index 9ab0cff02..9b42d533c 100644 --- a/Roles/Impostor/Scavenger.cs +++ b/Roles/Impostor/Scavenger.cs @@ -3,14 +3,15 @@ internal class Scavenger : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Scavenger; private const int Id = 4400; + private static readonly HashSet PlayerIds = []; + public static bool HasEnabled => PlayerIds.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorConcealing; //==================================================================\\ private static OptionItem ScavengerKillCooldown; - private static OptionItem ScavengerHasCustomDeathReason; public static readonly HashSet KilledPlayersId = []; @@ -20,13 +21,17 @@ public override void SetupCustomOption() ScavengerKillCooldown = FloatOptionItem.Create(Id + 2, GeneralOption.KillCooldown, new(5f, 180f, 2.5f), 40f, TabGroup.ImpostorRoles, false) .SetParent(Options.CustomRoleSpawnChances[CustomRoles.Scavenger]) .SetValueFormat(OptionFormat.Seconds); - ScavengerHasCustomDeathReason = BooleanOptionItem.Create(Id + 3, "ScavengerHasCustomDeathReason", true, TabGroup.ImpostorRoles, false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Scavenger]); - } public override void Init() { + PlayerIds.Clear(); KilledPlayersId.Clear(); } + public override void Add(byte playerId) + { + PlayerIds.Add(playerId); + } + public override void SetKillCooldown(byte id) => Main.AllPlayerKillCooldown[id] = ScavengerKillCooldown.GetFloat(); public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) @@ -37,17 +42,13 @@ public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl t _ = new LateTask( () => { - if (ScavengerHasCustomDeathReason.GetBool()) - { - target.SetDeathReason(PlayerState.DeathReason.Scavenged); - } target.RpcMurderPlayer(target); target.SetRealKiller(killer); RPC.PlaySoundRPC(killer.PlayerId, Sounds.KillSound); target.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Scavenger), Translator.GetString("KilledByScavenger")), time: 8f); }, 0.5f, "Scavenger Kill"); - + killer.SetKillCooldown(); return false; } diff --git a/Roles/Impostor/ShapeMaster.cs b/Roles/Impostor/ShapeMaster.cs index 9b2a0117f..590d3b8b9 100644 --- a/Roles/Impostor/ShapeMaster.cs +++ b/Roles/Impostor/ShapeMaster.cs @@ -5,8 +5,10 @@ namespace TOHE.Roles.Impostor; internal class ShapeMaster : RoleBase // Should be deleted tbh, because it's litteraly vanilla shapeshifter { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.ShapeMaster; private const int Id = 4500; + private static readonly HashSet Playerids = []; + public static bool HasEnabled => Playerids.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Shapeshifter; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorConcealing; //==================================================================\\ @@ -20,6 +22,14 @@ public override void SetupCustomOption() .SetParent(Options.CustomRoleSpawnChances[CustomRoles.ShapeMaster]) .SetValueFormat(OptionFormat.Seconds); } + public override void Init() + { + Playerids.Clear(); + } + public override void Add(byte playerId) + { + Playerids.Add (playerId); + } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { diff --git a/Roles/Impostor/Sniper.cs b/Roles/Impostor/Sniper.cs index baa99ea38..bc425f3cd 100644 --- a/Roles/Impostor/Sniper.cs +++ b/Roles/Impostor/Sniper.cs @@ -9,11 +9,10 @@ namespace TOHE.Roles.Impostor; internal class Sniper : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Sniper; private const int Id = 2400; private static readonly HashSet PlayerIdList = []; public static bool HasEnabled => PlayerIdList.Any(); - + public override CustomRoles ThisRoleBase => CustomRoles.Shapeshifter; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorKilling; //==================================================================\\ @@ -68,8 +67,7 @@ public override void Init() } public override void Add(byte playerId) { - if (!PlayerIdList.Contains(playerId)) - PlayerIdList.Add(playerId); + PlayerIdList.Add(playerId); maxBulletCount = SniperBulletCount.GetInt(); precisionShooting = SniperPrecisionShooting.GetBool(); @@ -331,7 +329,7 @@ public override string GetMark(PlayerControl seer, PlayerControl seen = null, bo seen ??= seer; var sniper = Utils.GetPlayerById(PlayerIdList.First()); if (!(sniper == seer) || !(sniper == seen)) return string.Empty; - + var seerId = seer.PlayerId; if (AimAssist) diff --git a/Roles/Impostor/SoulCatcher.cs b/Roles/Impostor/SoulCatcher.cs index 328474320..8039f1a44 100644 --- a/Roles/Impostor/SoulCatcher.cs +++ b/Roles/Impostor/SoulCatcher.cs @@ -7,8 +7,10 @@ namespace TOHE.Roles.Impostor; internal class SoulCatcher : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.SoulCatcher; private const int Id = 4600; + private static readonly HashSet PlayerIds = []; + public static bool HasEnabled => PlayerIds.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Shapeshifter; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorConcealing; //==================================================================\\ @@ -26,6 +28,15 @@ public override void SetupCustomOption() .SetParent(Options.CustomRoleSpawnChances[CustomRoles.SoulCatcher]) .SetValueFormat(OptionFormat.Seconds); } + public override void Init() + { + PlayerIds.Clear(); + } + public override void Add(byte playerId) + { + PlayerIds.Add(playerId); + } + public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.ShapeshifterDuration = ShapeSoulCatcherShapeshiftDuration.GetFloat(); diff --git a/Roles/Impostor/Stealth.cs b/Roles/Impostor/Stealth.cs index 687929b59..065bd1e7b 100644 --- a/Roles/Impostor/Stealth.cs +++ b/Roles/Impostor/Stealth.cs @@ -9,7 +9,6 @@ namespace TOHE.Roles.Impostor; internal class Stealth : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Stealth; private const int Id = 27400; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Stealth); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; @@ -53,7 +52,7 @@ public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl t playersToDarken = playersToDarken.Where(player => !player.Is(CustomRoles.Impostor)).ToArray(); } DarkenPlayers(playersToDarken); - + return true; } /// Get all players in the same room as you diff --git a/Roles/Impostor/Swooper.cs b/Roles/Impostor/Swooper.cs index a0699d795..de0de9c31 100644 --- a/Roles/Impostor/Swooper.cs +++ b/Roles/Impostor/Swooper.cs @@ -11,7 +11,6 @@ namespace TOHE.Roles.Impostor; internal class Swooper : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Swooper; private const int Id = 4700; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Swooper); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; @@ -89,7 +88,7 @@ public override void OnCoEnterVent(PlayerPhysics physics, int ventId) var swooperId = swooper.PlayerId; if (!AmongUsClient.Instance.AmHost || IsInvis(swooperId)) return; - + _ = new LateTask(() => { if (CanGoInvis(swooperId)) @@ -102,7 +101,7 @@ public override void OnCoEnterVent(PlayerPhysics physics, int ventId) InvisDuration.Remove(swooperId); InvisDuration.Add(swooperId, Utils.GetTimeStamp()); SendRPC(swooper); - + swooper.Notify(GetString("SwooperInvisState"), SwooperDuration.GetFloat()); } else @@ -213,7 +212,7 @@ public override string GetLowerText(PlayerControl seer, PlayerControl seen = nul { // Only for modded if (seer == null || !isForHud || isForMeeting || !seer.IsAlive()) return string.Empty; - + var str = new StringBuilder(); var seerId = seer.PlayerId; @@ -239,4 +238,4 @@ public override void SetAbilityButtonText(HudManager hud, byte playerId) hud.ImpostorVentButton?.OverrideText(GetString(IsInvis(playerId) ? "SwooperRevertVentButtonText" : "SwooperVentButtonText")); } public override Sprite ImpostorVentButtonSprite(PlayerControl player) => CustomButton.Get("invisible"); -} +} \ No newline at end of file diff --git a/Roles/Impostor/TimeThief.cs b/Roles/Impostor/TimeThief.cs index 86523b7e2..f67a959ae 100644 --- a/Roles/Impostor/TimeThief.cs +++ b/Roles/Impostor/TimeThief.cs @@ -3,11 +3,10 @@ namespace TOHE.Roles.Impostor; internal class TimeThief : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.TimeThief; private const int Id = 3700; private static readonly HashSet playerIdList = []; public static bool HasEnabled => playerIdList.Any(); - + public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorSupport; //==================================================================\\ @@ -35,8 +34,7 @@ public override void Init() } public override void Add(byte playerId) { - if (!playerIdList.Contains(playerId)) - playerIdList.Add(playerId); + playerIdList.Add(playerId); } public override void Remove(byte playerId) { @@ -44,9 +42,9 @@ public override void Remove(byte playerId) } public override void SetKillCooldown(byte id) => Main.AllPlayerKillCooldown[id] = KillCooldown.GetFloat(); - - private static int StolenTime(byte id) - => playerIdList.Contains(id) && (Utils.GetPlayerById(id).IsAlive() || !ReturnStolenTimeUponDeath.GetBool()) + + private static int StolenTime(byte id) + => playerIdList.Contains(id) && (Utils.GetPlayerById(id).IsAlive() || !ReturnStolenTimeUponDeath.GetBool()) ? DecreaseMeetingTime.GetInt() * Main.PlayerStates[id].GetKillCount(true) : 0; @@ -62,4 +60,4 @@ public static int TotalDecreasedMeetingTime() public override string GetProgressText(byte playerId, bool cooms) => StolenTime(playerId) > 0 ? Utils.ColorString(Palette.ImpostorRed.ShadeColor(0.5f), $"{-StolenTime(playerId)}s") : string.Empty; -} +} \ No newline at end of file diff --git a/Roles/Impostor/Trapster.cs b/Roles/Impostor/Trapster.cs index d35ed831d..100645ca1 100644 --- a/Roles/Impostor/Trapster.cs +++ b/Roles/Impostor/Trapster.cs @@ -3,8 +3,10 @@ internal class Trapster : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Trapster; private const int Id = 2600; + private static readonly HashSet Playerids = []; + public static bool HasEnabled => Playerids.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorKilling; //==================================================================\\ @@ -35,7 +37,11 @@ public override void Init() { BoobyTrapBody.Clear(); KillerOfBoobyTrapBody.Clear(); - + Playerids.Clear(); + } + public override void Add(byte playerId) + { + Playerids.Clear(); } public override void SetKillCooldown(byte id) => Main.AllPlayerKillCooldown[id] = TrapsterKillCooldown.GetFloat(); @@ -59,12 +65,12 @@ public override bool OnCheckReportDeadBody(PlayerControl reporter, NetworkedPlay reporter.SetRealKiller(deadBody.Object); RPC.PlaySoundRPC(killerId, Sounds.KillSound); - + if (TrapConsecutiveTrapsterBodies.GetBool()) { BoobyTrapBody.Add(reporter.PlayerId); } - + return false; } diff --git a/Roles/Impostor/Trickster.cs b/Roles/Impostor/Trickster.cs index a6dc2dab7..405c03926 100644 --- a/Roles/Impostor/Trickster.cs +++ b/Roles/Impostor/Trickster.cs @@ -3,8 +3,10 @@ internal class Trickster : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Trickster; private const int Id = 4800; + private static readonly HashSet PlayerIds = []; + public static bool HasEnabled => PlayerIds.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorConcealing; //==================================================================\\ @@ -13,4 +15,12 @@ public override void SetupCustomOption() { Options.SetupRoleOptions(Id, TabGroup.ImpostorRoles, CustomRoles.Trickster); } + public override void Init() + { + PlayerIds.Clear(); + } + public override void Add(byte playerId) + { + PlayerIds.Add(playerId); + } } diff --git a/Roles/Impostor/Twister.cs b/Roles/Impostor/Twister.cs index 4111e7f74..b604f5c6e 100644 --- a/Roles/Impostor/Twister.cs +++ b/Roles/Impostor/Twister.cs @@ -10,7 +10,6 @@ namespace TOHE.Roles.Impostor; internal class Twister : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Twister; private const int Id = 5700; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Twister); public override CustomRoles ThisRoleBase => CustomRoles.Shapeshifter; @@ -84,4 +83,4 @@ public override void SetAbilityButtonText(HudManager hud, byte playerId) { hud.AbilityButton?.OverrideText(GetString("TwisterButtonText")); } -} +} \ No newline at end of file diff --git a/Roles/Impostor/Underdog.cs b/Roles/Impostor/Underdog.cs index a8b2bff00..ebe294d67 100644 --- a/Roles/Impostor/Underdog.cs +++ b/Roles/Impostor/Underdog.cs @@ -3,8 +3,10 @@ internal class Underdog : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Underdog; private const int Id = 2700; + private static readonly HashSet PlayerIds = []; + public static bool HasEnabled => PlayerIds.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorKilling; //==================================================================\\ @@ -22,6 +24,14 @@ public override void SetupCustomOption() .SetParent(Options.CustomRoleSpawnChances[CustomRoles.Underdog]) .SetValueFormat(OptionFormat.Seconds); } + public override void Init() + { + PlayerIds.Clear(); + } + public override void Add(byte playerId) + { + PlayerIds.Add(playerId); + } public override bool CanUseKillButton(PlayerControl pc) => Main.AllAlivePlayerControls.Length <= UnderdogMaximumPlayersNeededToKill.GetInt(); diff --git a/Roles/Impostor/Undertaker.cs b/Roles/Impostor/Undertaker.cs index 5c412da4f..e3214f654 100644 --- a/Roles/Impostor/Undertaker.cs +++ b/Roles/Impostor/Undertaker.cs @@ -7,8 +7,10 @@ namespace TOHE.Roles.Impostor; internal class Undertaker : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Undertaker; private const int Id = 4900; + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Shapeshifter; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorConcealing; //==================================================================\\ @@ -18,7 +20,7 @@ internal class Undertaker : RoleBase private static OptionItem FreezeTime; private static readonly Dictionary MarkedLocation = []; - + private static float DefaultSpeed = new(); public override void SetupCustomOption() @@ -34,12 +36,14 @@ public override void SetupCustomOption() public override void Init() { + playerIdList.Clear(); MarkedLocation.Clear(); DefaultSpeed = new(); } public override void Add(byte playerId) { + playerIdList.Add(playerId); MarkedLocation.TryAdd(playerId, ExtendedPlayerControl.GetBlackRoomPosition()); DefaultSpeed = Main.AllPlayerSpeed[playerId]; } @@ -68,7 +72,7 @@ public static void ReceiveRPC(MessageReader reader) float yLoc = reader.ReadSingle(); if (MarkedLocation.ContainsKey(PlayerId)) - MarkedLocation[PlayerId] = new Vector2(xLoc, yLoc); + MarkedLocation[PlayerId] = new Vector2(xLoc,yLoc); else MarkedLocation.Add(PlayerId, ExtendedPlayerControl.GetBlackRoomPosition()); } @@ -112,10 +116,10 @@ public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl t target.SetRealKiller(killer); MarkedLocation[killer.PlayerId] = ExtendedPlayerControl.GetBlackRoomPosition(); - + SendRPC(killer.PlayerId); FreezeUndertaker(killer); - + killer.SyncSettings(); } return false; @@ -123,7 +127,7 @@ public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl t public override void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo target) { - foreach (var playerId in MarkedLocation.Keys) + foreach(var playerId in MarkedLocation.Keys) { MarkedLocation[playerId] = ExtendedPlayerControl.GetBlackRoomPosition(); Main.AllPlayerSpeed[playerId] = DefaultSpeed; diff --git a/Roles/Impostor/Vampire.cs b/Roles/Impostor/Vampire.cs index 0307ec331..c4dbbf6c9 100644 --- a/Roles/Impostor/Vampire.cs +++ b/Roles/Impostor/Vampire.cs @@ -1,6 +1,6 @@ +using UnityEngine; using TOHE.Modules; using TOHE.Roles.AddOns.Common; -using UnityEngine; using static TOHE.Translator; namespace TOHE.Roles.Impostor; @@ -14,8 +14,10 @@ private class BittenInfo(byte vampierId, float killTimer) } //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Vampire; private const int Id = 5000; + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorConcealing; //==================================================================\\ @@ -24,7 +26,6 @@ private class BittenInfo(byte vampierId, float killTimer) private static OptionItem CanVent; private static OptionItem ActionModeOpt; - [Obfuscation(Exclude = true)] private enum ActionModeList { Vampire_OnlyBites, @@ -46,6 +47,7 @@ public override void SetupCustomOption() } public override void Init() { + playerIdList.Clear(); BittenPlayers.Clear(); KillDelay = OptionKillDelay.GetFloat(); @@ -53,6 +55,8 @@ public override void Init() } public override void Add(byte playerId) { + playerIdList.Add(playerId); + if (NowActionMode == ActionModeList.TriggerDouble) { Utils.GetPlayerById(playerId)?.AddDoubleTrigger(); @@ -130,10 +134,10 @@ private static void KillBitten(PlayerControl vampire, PlayerControl target) if (vampire.IsAlive()) { RPC.PlaySoundRPC(vampire.PlayerId, Sounds.KillSound); - + if (target.Is(CustomRoles.Trapper)) vampire.TrapperKilled(target); - + vampire.Notify(GetString("VampireTargetDead")); vampire.SetKillCooldown(); } diff --git a/Roles/Impostor/Vindicator.cs b/Roles/Impostor/Vindicator.cs index 7cd0b8361..b7312bd5a 100644 --- a/Roles/Impostor/Vindicator.cs +++ b/Roles/Impostor/Vindicator.cs @@ -3,8 +3,10 @@ internal class Vindicator : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Vindicator; private const int Id = 3800; + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorSupport; //==================================================================\\ @@ -21,6 +23,15 @@ public override void SetupCustomOption() VindicatorHideVote = BooleanOptionItem.Create(Id + 3, GeneralOption.HideAdditionalVotes, false, TabGroup.ImpostorRoles, false) .SetParent(Options.CustomRoleSpawnChances[CustomRoles.Vindicator]); } + public override void Init() + { + playerIdList.Clear(); + } + public override void Add(byte playerId) + { + playerIdList.Add(playerId); + } + public override void AddVisualVotes(PlayerVoteArea votedPlayer, ref List statesList) { if (VindicatorHideVote.GetBool()) return; diff --git a/Roles/Impostor/Visionary.cs b/Roles/Impostor/Visionary.cs index 3d2c805b0..4a2431639 100644 --- a/Roles/Impostor/Visionary.cs +++ b/Roles/Impostor/Visionary.cs @@ -3,8 +3,10 @@ internal class Visionary : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Visionary; private const int Id = 3900; + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorSupport; //==================================================================\\ @@ -13,6 +15,14 @@ public override void SetupCustomOption() { Options.SetupRoleOptions(Id, TabGroup.ImpostorRoles, CustomRoles.Visionary); } + public override void Init() + { + playerIdList.Clear(); + } + public override void Add(byte playerId) + { + playerIdList.Add(playerId); + } public override string PlayerKnowTargetColor(PlayerControl seer, PlayerControl target) { @@ -32,7 +42,10 @@ or CustomRoles.Refugee or CustomRoles.Admired) return Main.roleColors[CustomRoles.Knight]; } - + if (Main.PlayerStates[target.PlayerId].IsRandomizer) + { + return Main.roleColors[CustomRoles.Crewmate]; + } if (customRole.IsImpostorTeamV2() || customRole.IsMadmate()) { return Main.roleColors[CustomRoles.Impostor]; diff --git a/Roles/Impostor/Warlock.cs b/Roles/Impostor/Warlock.cs index 5e5782fca..55c93d009 100644 --- a/Roles/Impostor/Warlock.cs +++ b/Roles/Impostor/Warlock.cs @@ -10,8 +10,10 @@ namespace TOHE.Roles.Impostor; internal class Warlock : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Warlock; private const int Id = 5100; + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Shapeshifter; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorConcealing; //==================================================================\\ @@ -39,7 +41,7 @@ public override void SetupCustomOption() } public override void Init() { - + playerIdList.Clear(); CursedPlayers.Clear(); IsCurseAndKill.Clear(); WarlockTimer.Clear(); @@ -47,7 +49,7 @@ public override void Init() } public override void Add(byte playerId) { - + playerIdList.Add(playerId); CursedPlayers.Add(playerId, null); IsCurseAndKill.Add(playerId, false); } @@ -65,7 +67,7 @@ public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl t if (!Main.CheckShapeshift[killer.PlayerId] && !IsCurseAndKill[killer.PlayerId]) { if (target.Is(CustomRoles.LazyGuy) || target.Is(CustomRoles.Lazy) || target.Is(CustomRoles.NiceMini) && Mini.Age < 18) return false; - + IsCursed = true; killer.SetKillCooldown(); killer.RPCPlayCustomSound("Line"); @@ -74,7 +76,7 @@ public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl t IsCurseAndKill[killer.PlayerId] = true; return false; } - + if (Main.CheckShapeshift[killer.PlayerId]) { killer.RpcCheckAndMurder(target); @@ -97,7 +99,7 @@ public override void OnShapeshift(PlayerControl shapeshifter, PlayerControl targ Vector2 cppos = cp.transform.position; Dictionary cpdistance = []; float dis; - + foreach (PlayerControl p in Main.AllAlivePlayerControls) { if (p.PlayerId == cp.PlayerId) continue; @@ -105,7 +107,7 @@ public override void OnShapeshift(PlayerControl shapeshifter, PlayerControl targ if (!WarlockCanKillAllies.GetBool() && p.Is(Custom_Team.Impostor)) continue; if (Pelican.IsEaten(p.PlayerId) || Medic.IsProtected(p.PlayerId)) continue; if (p.Is(CustomRoles.Glitch) || p.Is(CustomRoles.Pestilence)) continue; - + dis = Utils.GetDistance(cppos, p.transform.position); cpdistance.Add(p, dis); Logger.Info($"{p?.Data?.PlayerName} distance: {dis}", "Warlock"); @@ -170,7 +172,7 @@ public override void OnFixedUpdate(PlayerControl player, bool lowLoad, long nowT public override void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo target) { - foreach (var warlockId in _playerIdList) + foreach (var warlockId in playerIdList) { CursedPlayers[warlockId] = null; IsCurseAndKill[warlockId] = false; diff --git a/Roles/Impostor/Wildling.cs b/Roles/Impostor/Wildling.cs index 756b57231..313b8a0c3 100644 --- a/Roles/Impostor/Wildling.cs +++ b/Roles/Impostor/Wildling.cs @@ -11,7 +11,6 @@ namespace TOHE.Roles.Impostor; internal class Wildling : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Wildling; private const int Id = 5200; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Wildling); public override CustomRoles ThisRoleBase => CustomRoles.Shapeshifter; @@ -106,4 +105,4 @@ public override string GetLowerText(PlayerControl seer, PlayerControl seen = nul return str.ToString(); } -} +} \ No newline at end of file diff --git a/Roles/Impostor/Witch.cs b/Roles/Impostor/Witch.cs index ba593c261..c1c847de2 100644 --- a/Roles/Impostor/Witch.cs +++ b/Roles/Impostor/Witch.cs @@ -9,11 +9,10 @@ namespace TOHE.Roles.Impostor; internal class Witch : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Witch; private const int Id = 2500; private static readonly HashSet playerIdList = []; public static bool HasEnabled => playerIdList.Any(); - + public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorKilling; //==================================================================\\ @@ -23,7 +22,6 @@ internal class Witch : RoleBase private static readonly Dictionary SpellMode = []; private static readonly Dictionary> SpelledPlayer = []; - [Obfuscation(Exclude = true)] private enum SwitchTriggerList { TriggerKill, @@ -46,8 +44,7 @@ public override void Init() } public override void Add(byte playerId) { - if (!playerIdList.Contains(playerId)) - playerIdList.Add(playerId); + playerIdList.Add(playerId); SpellMode.Add(playerId, false); SpelledPlayer.Add(playerId, []); NowSwitchTrigger = (SwitchTriggerList)ModeSwitchActionOpt.GetValue(); @@ -185,7 +182,7 @@ public override void OnCheckForEndVoting(PlayerState.DeathReason deathReason, pa Main.AfterMeetingDeathPlayers.Remove(pc.PlayerId); } } - + CheckForEndVotingPatch.TryAddAfterMeetingDeathPlayers(PlayerState.DeathReason.Spell, [.. spelledIdList]); RemoveSpelledPlayer(); } @@ -245,13 +242,4 @@ public override void SetAbilityButtonText(HudManager hud, byte playerId) hud.KillButton.OverrideText(GetString("KillButtonText")); } } - - public override void Remove(byte playerId) - { - if (SpelledPlayer.ContainsKey(playerId)) - { - SpelledPlayer[playerId].Clear(); - SendRPC(true, playerId); - } - } -} +} \ No newline at end of file diff --git a/Roles/Impostor/YinYanger.cs b/Roles/Impostor/YinYanger.cs index a8c0befc9..f75ca7d8d 100644 --- a/Roles/Impostor/YinYanger.cs +++ b/Roles/Impostor/YinYanger.cs @@ -1,5 +1,5 @@ -using TOHE.Roles.Core; -using UnityEngine; +using UnityEngine; +using TOHE.Roles.Core; using static TOHE.Options; using static TOHE.Translator; using static TOHE.Utils; @@ -9,7 +9,6 @@ namespace TOHE.Roles.Impostor; internal class YinYanger : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.YinYanger; const int Id = 29100; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.YinYanger); public override CustomRoles ThisRoleBase => CustomRoles.Impostor; diff --git a/Roles/Impostor/Zombie.cs b/Roles/Impostor/Zombie.cs index ca8eb1135..530682389 100644 --- a/Roles/Impostor/Zombie.cs +++ b/Roles/Impostor/Zombie.cs @@ -6,8 +6,10 @@ namespace TOHE.Roles.Impostor; internal class Zombie : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Zombie; private const int Id = 23900; + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorKilling; //==================================================================\\ @@ -25,6 +27,14 @@ public override void SetupCustomOption() .SetParent(Options.CustomRoleSpawnChances[CustomRoles.Zombie]) .SetValueFormat(OptionFormat.Multiplier); } + public override void Init() + { + playerIdList.Clear(); + } + public override void Add(byte playerId) + { + playerIdList.Add(playerId); + } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { @@ -33,7 +43,7 @@ public override void ApplyGameOptions(IGameOptions opt, byte playerId) public override void SetKillCooldown(byte id) { Main.AllPlayerKillCooldown[id] = ZombieKillCooldown.GetFloat(); - Main.AllPlayerSpeed[id] -= (float)Math.Clamp(ZombieSpeedReduce.GetFloat(), 0, (double)Main.AllPlayerSpeed[id] - 0.5); + Main.AllPlayerSpeed[id] -= (float)Math.Clamp(ZombieSpeedReduce.GetFloat(), 0, (double)Main.AllPlayerSpeed[id] - 0.5); } public static void CheckRealVotes(PlayerControl target, ref int VoteNum) diff --git a/Roles/Neutral/Agitater.cs b/Roles/Neutral/Agitater.cs index 216969a29..269d0bf42 100644 --- a/Roles/Neutral/Agitater.cs +++ b/Roles/Neutral/Agitater.cs @@ -1,16 +1,17 @@ using AmongUs.GameOptions; using Hazel; -using InnerNet; -using TOHE.Roles.Core; using UnityEngine; using static TOHE.Translator; +using TOHE.Roles.Core; +using InnerNet; namespace TOHE.Roles.Neutral; internal class Agitater : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Agitater; private const int Id = 15800; + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); public override bool IsDesyncRole => true; public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralKilling; @@ -45,6 +46,7 @@ public override void SetupCustomOption() } public override void Init() { + playerIdList.Clear(); CurrentBombedPlayer = byte.MaxValue; LastBombedPlayer = byte.MaxValue; AgitaterHasBombed = false; @@ -53,6 +55,7 @@ public override void Init() public override void Add(byte playerId) { + playerIdList.Add(playerId); CustomRoleManager.OnFixedUpdateOthers.Add(OnFixedUpdateOthers); } @@ -77,6 +80,7 @@ public override void OnFixedUpdate(PlayerControl player, bool lowLoad, long nowT public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { + if (!HasEnabled) return false; if (AgitaterAutoReportBait.GetBool() && target.Is(CustomRoles.Bait)) return true; if (target.Is(CustomRoles.Pestilence)) { @@ -94,7 +98,7 @@ public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl t AgitaterHasBombed = true; killer.ResetKillCooldown(); killer.SetKillCooldown(); - + _ = new LateTask(() => { if (CurrentBombedPlayer != byte.MaxValue && GameStates.IsInTask) @@ -118,7 +122,7 @@ public override void OnReportDeadBody(PlayerControl reported, NetworkedPlayerInf { if (CurrentBombedPlayer == byte.MaxValue) return; var target = Utils.GetPlayerById(CurrentBombedPlayer); - var killer = _Player; + var killer = Utils.GetPlayerById(playerIdList.First()); if (target == null || killer == null) return; CurrentBombedPlayer.SetDeathReason(PlayerState.DeathReason.Bombed); diff --git a/Roles/Neutral/Amnesiac.cs b/Roles/Neutral/Amnesiac.cs index 9c2d264fe..4a0b25dd2 100644 --- a/Roles/Neutral/Amnesiac.cs +++ b/Roles/Neutral/Amnesiac.cs @@ -1,49 +1,50 @@ -using AmongUs.GameOptions; -using TOHE.Roles.Core.AssignManager; using UnityEngine; +using static TOHE.Translator; using static TOHE.Options; using static TOHE.Roles.Core.CustomRoleManager; -using static TOHE.Translator; +using AmongUs.GameOptions; namespace TOHE.Roles.Neutral; internal class Amnesiac : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Amnesiac; private const int Id = 12700; - public override CustomRoles ThisRoleBase => AmnesiacCanUseVent.GetBool() ? CustomRoles.Engineer : CustomRoles.Crewmate; + private static readonly HashSet playerIdList = []; + public static bool HasEnabled = playerIdList.Any(); + public override bool IsDesyncRole => true; + public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralBenign; //==================================================================\\ - private static OptionItem ImpostorVision; + private static OptionItem IncompatibleNeutralMode; private static OptionItem ShowArrows; - private static OptionItem AmnesiacCanUseVent; - private static OptionItem VentCoolDown; - private static OptionItem VentDuration; - private static OptionItem ReportWhenFailedRemember; private static readonly Dictionary CanUseVent = []; - + private enum AmnesiacIncompatibleNeutralModeSelectList + { + Role_Amnesiac, + Role_Pursuer, + Role_Follower, + Role_Maverick, + Role_Imitator, + } + public override void SetupCustomOption() { SetupRoleOptions(Id, TabGroup.NeutralRoles, CustomRoles.Amnesiac); - ImpostorVision = BooleanOptionItem.Create(Id + 13, "ImpostorVision", false, TabGroup.NeutralRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Amnesiac]); - ShowArrows = BooleanOptionItem.Create(Id + 11, "ShowArrows", true, TabGroup.NeutralRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Amnesiac]); - AmnesiacCanUseVent = BooleanOptionItem.Create(Id + 12, GeneralOption.CanVent, false, TabGroup.NeutralRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Amnesiac]); - VentCoolDown = FloatOptionItem.Create(Id + 14, GeneralOption.EngineerBase_VentCooldown, new(0f, 60f, 2.5f), 10f, TabGroup.NeutralRoles, false).SetParent(AmnesiacCanUseVent); - VentDuration = FloatOptionItem.Create(Id + 16, GeneralOption.EngineerBase_InVentMaxTime, new(0f, 180f, 2.5f), 15f, TabGroup.NeutralRoles, false).SetParent(AmnesiacCanUseVent); - ReportWhenFailedRemember = BooleanOptionItem.Create(Id + 15, "ReportWhenFailedRemember", true, TabGroup.NeutralRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Amnesiac]).SetHidden(true); + IncompatibleNeutralMode = StringOptionItem.Create(Id + 10, "IncompatibleNeutralMode", EnumHelper.GetAllNames(), 0, TabGroup.NeutralRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Amnesiac]); + ShowArrows = BooleanOptionItem.Create(Id + 11, "ShowArrows", false, TabGroup.NeutralRoles, false).SetParent(Options.CustomRoleSpawnChances[CustomRoles.Amnesiac]); } public override void Init() { - + playerIdList.Clear(); CanUseVent.Clear(); } public override void Add(byte playerId) { - - CanUseVent[playerId] = AmnesiacCanUseVent.GetBool(); + playerIdList.Add(playerId); + CanUseVent[playerId] = true; if (ShowArrows.GetBool()) { @@ -52,15 +53,27 @@ public override void Add(byte playerId) } public override void Remove(byte playerId) { - - CheckDeadBodyOthers.Remove(CheckDeadBody); + playerIdList.Remove(playerId); } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { - opt.SetVision(ImpostorVision.GetBool()); - AURoleOptions.EngineerCooldown = VentCoolDown.GetFloat(); - AURoleOptions.EngineerInVentMaxTime = VentDuration.GetFloat(); + var player = playerId.GetPlayer(); + if (player == null) return; + + if (player.Is(Custom_Team.Crewmate)) + { + opt.SetVision(false); + opt.SetFloat(FloatOptionNames.CrewLightMod, opt.GetFloat(FloatOptionNames.CrewLightMod)); + opt.SetFloat(FloatOptionNames.ImpostorLightMod, opt.GetFloat(FloatOptionNames.CrewLightMod)); + } + else + { + opt.SetVision(true); + opt.SetFloat(FloatOptionNames.CrewLightMod, opt.GetFloat(FloatOptionNames.ImpostorLightMod)); + opt.SetFloat(FloatOptionNames.ImpostorLightMod, opt.GetFloat(FloatOptionNames.ImpostorLightMod)); + } } + public override bool CanUseImpostorVentButton(PlayerControl pc) => true; public static bool PreviousAmnesiacCanVent(PlayerControl pc) => CanUseVent.TryGetValue(pc.PlayerId, out var canUse) && canUse; public override void SetAbilityButtonText(HudManager hud, byte playerId) { @@ -71,11 +84,10 @@ public override void SetAbilityButtonText(HudManager hud, byte playerId) private void CheckDeadBody(PlayerControl killer, PlayerControl target, bool inMeeting) { if (inMeeting || Main.MeetingIsStarted) return; - if (target == null || target.Data.GetDeadBody() == null) return; - foreach (var playerId in _playerIdList.ToArray()) + foreach (var playerId in playerIdList.ToArray()) { var player = playerId.GetPlayer(); - if (player == null || !player.IsAlive()) continue; + if (!player.IsAlive()) continue; LocateArrow.Add(playerId, target.Data.GetDeadBody().transform.position); } @@ -94,74 +106,93 @@ public override string GetSuffix(PlayerControl seer, PlayerControl target, bool public override void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo target) { if (ShowArrows.GetBool()) - foreach (var apc in _playerIdList.ToArray()) + foreach (var apc in playerIdList.ToArray()) { LocateArrow.RemoveAllTarget(apc); } } public override bool OnCheckReportDeadBody(PlayerControl __instance, NetworkedPlayerInfo deadBody, PlayerControl killer) { - if (__instance.PlayerId != _Player.PlayerId) return true; - - bool isSuccess = false; - if (Main.PlayerStates.TryGetValue(deadBody.PlayerId, out var targetPlayerStates)) + var tar = deadBody.Object; + if (__instance.Is(CustomRoles.Amnesiac)) { - if (targetPlayerStates.MainRole == CustomRoles.Amnesiac) + var tempRole = CustomRoles.Amnesiac; + if (tar.GetCustomRole().IsImpostor() || tar.GetCustomRole().IsMadmate() || tar.Is(CustomRoles.Madmate)) { - __instance.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Amnesiac), GetString("RememberedAmnesiac"))); + tempRole = CustomRoles.Refugee; } - - if (targetPlayerStates.MainRole.IsGhostRole()) + if (tar.GetCustomRole().IsCrewmate() && !tar.Is(CustomRoles.Madmate)) { - if (GhostRoleAssign.GhostGetPreviousRole.TryGetValue(targetPlayerStates.PlayerId, out var role) && !role.IsGhostRole()) + if (tar.IsAmneCrew()) { - __instance.GetRoleClass()?.OnRemove(__instance.PlayerId); - __instance.RpcChangeRoleBasis(role); - __instance.RpcSetCustomRole(role); - __instance.GetRoleClass()?.OnAdd(__instance.PlayerId); - - __instance.RpcGuardAndKill(); - __instance.ResetKillCooldown(); - __instance.SetKillCooldown(); - - role.GetActualRoleName(out var rolename); - __instance.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Amnesiac), string.Format(GetString("AmnesiacRemembered"), rolename))); - isSuccess = true; + tempRole = tar.GetCustomRole(); } else { - __instance.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Amnesiac), GetString("RememberedAmnesiac"))); + tempRole = CustomRoles.EngineerTOHE; + } + Main.TasklessCrewmate.Add(__instance.PlayerId); + } + if (tar.GetCustomRole().IsNA()) + { + __instance.RpcSetCustomRole(tar.GetCustomRole()); + __instance.GetRoleClass().Add(__instance.PlayerId); + __instance.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Amnesiac), GetString("YouRememberedRole"))); + tar.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Amnesiac), GetString("RememberedYourRole"))); + } + if (tar.GetCustomRole().IsAmneNK()) + { + tempRole = tar.GetCustomRole(); + } + if (tar.GetCustomRole().IsAmneMaverick()) + { + switch (IncompatibleNeutralMode.GetValue()) + { + case 0: // Amnesiac + tempRole = CustomRoles.Amnesiac; + break; + case 1: // Pursuer + tempRole = CustomRoles.Pursuer; + break; + case 2: // Follower + tempRole = CustomRoles.Follower; + break; + case 3: // Maverick + tempRole = CustomRoles.Maverick; + break; + case 4: // Imitator + tempRole = CustomRoles.Imitator; + break; } } - else + if (tempRole != CustomRoles.Amnesiac) { - var role = targetPlayerStates.MainRole; - __instance.GetRoleClass()?.OnRemove(__instance.PlayerId); - __instance.RpcChangeRoleBasis(role); - __instance.RpcSetCustomRole(role); - __instance.GetRoleClass()?.OnAdd(__instance.PlayerId); + __instance.GetRoleClass().OnRemove(__instance.PlayerId); + __instance.RpcSetCustomRole(tempRole); + __instance.GetRoleClass().OnAdd(__instance.PlayerId); + __instance.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Amnesiac), GetString("YouRememberedRole"))); + tar.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Amnesiac), GetString("RememberedYourRole"))); - __instance.RpcGuardAndKill(); - __instance.ResetKillCooldown(); - __instance.SetKillCooldown(); + __instance.SyncSettings(); - role.GetActualRoleName(out var rolename); - __instance.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Amnesiac), string.Format(GetString("AmnesiacRemembered"), rolename))); - isSuccess = true; + var roleClass = tar.GetRoleClass(); + CanUseVent[__instance.PlayerId] = (roleClass?.ThisRoleBase) switch + { + CustomRoles.Engineer => true, + CustomRoles.Impostor or CustomRoles.Shapeshifter or CustomRoles.Phantom => roleClass.CanUseImpostorVentButton(tar), + _ => false, + }; + Logger.Info($"player id: {__instance.PlayerId}, Can use vent: {CanUseVent[__instance.PlayerId]}", "Previous Amne Vent"); + } + if (ShowArrows.GetBool()) + { + foreach (var apc in playerIdList.ToArray()) + { + LocateArrow.RemoveAllTarget(apc); + } } - } - else - { - __instance.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Amnesiac), GetString("RememberedAmnesiac"))); - } - - if (!isSuccess) - { - return ReportWhenFailedRemember.GetBool(); - } - else - { return false; } + return true; } } diff --git a/Roles/Neutral/Arsonist.cs b/Roles/Neutral/Arsonist.cs index a3ad78043..6b42da3dd 100644 --- a/Roles/Neutral/Arsonist.cs +++ b/Roles/Neutral/Arsonist.cs @@ -1,20 +1,21 @@ using AmongUs.GameOptions; +using UnityEngine; using Hazel; using TOHE.Modules; -using TOHE.Roles.AddOns.Common; using TOHE.Roles.Core; -using UnityEngine; +using TOHE.Roles.AddOns.Common; using static TOHE.Options; -using static TOHE.Translator; using static TOHE.Utils; +using static TOHE.Translator; namespace TOHE.Roles.Neutral; internal class Arsonist : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Arsonist; private const int id = 15900; + private static readonly HashSet PlayerIds = []; + public static bool HasEnabled = PlayerIds.Any(); public override bool IsDesyncRole => true; public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => CanIgniteAnytime() ? Custom_RoleType.NeutralKilling : Custom_RoleType.NeutralBenign; @@ -30,6 +31,7 @@ internal class Arsonist : RoleBase private static readonly Dictionary<(byte, byte), bool> IsDoused = []; private static byte CurrentDousingTarget = byte.MaxValue; + private static bool ArsonistCanIgniteAnytime = true; public override void SetupCustomOption() { @@ -44,12 +46,16 @@ public override void SetupCustomOption() } public override void Init() { + PlayerIds.Clear(); ArsonistTimer.Clear(); IsDoused.Clear(); CurrentDousingTarget = byte.MaxValue; + ArsonistCanIgniteAnytime = ArsonistCanIgniteAnytimeOpt.GetBool(); } public override void Add(byte playerId) { + PlayerIds.Add(playerId); + foreach (var ar in Main.AllPlayerControls) IsDoused.Add((playerId, ar.PlayerId), false); @@ -97,16 +103,16 @@ public static void ReceiveSetDousedPlayerRPC(MessageReader reader) } public override void SetKillCooldown(byte id) => Main.AllPlayerKillCooldown[id] = ArsonistCooldown.GetFloat(); - + public override bool CanUseKillButton(PlayerControl pc) => CanIgniteAnytime() ? GetDousedPlayerCount(pc.PlayerId).Item1 < ArsonistMaxPlayersToIgnite.GetInt() : !IsDouseDone(pc); - + public override bool CanUseImpostorVentButton(PlayerControl pc) => IsDouseDone(pc) || (CanIgniteAnytime() && (GetDousedPlayerCount(pc.PlayerId).Item1 >= ArsonistMinPlayersToIgnite.GetInt() || pc.inVent)); - + public override void ApplyGameOptions(IGameOptions opt, byte playerId) => opt.SetVision(false); - - public override bool ForcedCheckMurderAsKiller(PlayerControl killer, PlayerControl target) + + public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { killer.SetKillCooldown(ArsonistDouseTime.GetFloat()); if (!IsDoused[(killer.PlayerId, target.PlayerId)] && !ArsonistTimer.ContainsKey(killer.PlayerId)) @@ -121,7 +127,7 @@ public override bool ForcedCheckMurderAsKiller(PlayerControl killer, PlayerContr private void CheckDeadBody(PlayerControl killer, PlayerControl target, bool inMeeting) { if (!_Player.IsAlive() || target.PlayerId == _Player.PlayerId || inMeeting || Main.MeetingIsStarted) return; - + _Player.RpcSetVentInteraction(); _ = new LateTask(() => { NotifyRoles(SpecifySeer: _Player, ForceLoop: false); }, 1f, $"Update name for Arsonist {_Player?.PlayerId}", shoudLog: false); } @@ -177,7 +183,7 @@ public override void OnFixedUpdate(PlayerControl player, bool lowLoad, long nowT public override void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo target) => ArsonistTimer.Clear(); - + public override string GetMark(PlayerControl seer, PlayerControl seen = null, bool isForMeeting = false) { if (seen == null) return string.Empty; @@ -191,7 +197,7 @@ public override string GetMark(PlayerControl seer, PlayerControl seen = null, bo return string.Empty; } - public override string GetLowerText(PlayerControl seer, PlayerControl seen = null, bool isForMeeting = false, bool isForHud = false) + public override string GetLowerText(PlayerControl seer, PlayerControl seen = null, bool isForMeeting = false, bool isForHud = false) => !isForMeeting && IsDouseDone(seer) ? ColorString(GetRoleColor(CustomRoles.Arsonist), GetString("EnterVentToWin")) : string.Empty; public override string GetProgressText(byte playerId, bool comms) @@ -203,16 +209,16 @@ public override string GetProgressText(byte playerId, bool comms) else return ColorString(GetRoleColor(CustomRoles.Arsonist).ShadeColor(0.25f), $"({doused}/{ArsonistMaxPlayersToIgnite.GetInt()})"); } - + public override void SetAbilityButtonText(HudManager hud, byte playerId) { hud.KillButton.OverrideText(GetString("ArsonistDouseButtonText")); hud.ImpostorVentButton.OverrideText(GetString("ArsonistVentButtonText")); } - + public override Sprite ImpostorVentButtonSprite(PlayerControl player) => (IsDouseDone(player) || (CanIgniteAnytime() && GetDousedPlayerCount(player.PlayerId).Item1 >= ArsonistMinPlayersToIgnite.GetInt())) ? CustomButton.Get("Ignite") : null; - + public override Sprite GetKillButtonSprite(PlayerControl player, bool shapeshifting) => CustomButton.Get("Douse"); public override void OnCoEnterVent(PlayerPhysics __instance, int ventId) @@ -270,7 +276,7 @@ public override void OnCoEnterVent(PlayerPhysics __instance, int ventId) } } - public static bool CanIgniteAnytime() => ArsonistCanIgniteAnytimeOpt == null ? false : ArsonistCanIgniteAnytimeOpt.GetBool(); + public static bool CanIgniteAnytime() => ArsonistCanIgniteAnytime; private static void ResetCurrentDousingTarget(byte arsonistId) => SendCurrentDousingTargetRPC(arsonistId, 255); @@ -303,4 +309,4 @@ public static (int, int) GetDousedPlayerCount(byte playerId) return (doused, all); } -} +} \ No newline at end of file diff --git a/Roles/Neutral/Baker.cs b/Roles/Neutral/Baker.cs index cc203c485..a805941e8 100644 --- a/Roles/Neutral/Baker.cs +++ b/Roles/Neutral/Baker.cs @@ -12,19 +12,18 @@ namespace TOHE.Roles.Neutral; internal class Baker : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Baker; private const int Id = 28600; + public static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); public override bool IsDesyncRole => true; - public override CustomRoles ThisRoleBase => BTOS2Baker.GetBool() ? CustomRoles.Shapeshifter : CustomRoles.Impostor; + public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralApocalypse; //==================================================================\\ private static OptionItem BreadNeededToTransform; public static OptionItem FamineStarveCooldown; private static OptionItem BTOS2Baker; - private static OptionItem TransformNoMoreBread; - public static OptionItem CanVent; private static byte BreadID = 0; public static readonly Dictionary> BreadList = []; @@ -42,11 +41,10 @@ public override void SetupCustomOption() FamineStarveCooldown = FloatOptionItem.Create(Id + 11, "FamineStarveCooldown", new(0f, 180f, 2.5f), 30f, TabGroup.NeutralRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Baker]) .SetValueFormat(OptionFormat.Seconds); BTOS2Baker = BooleanOptionItem.Create(Id + 12, "BakerBreadGivesEffects", true, TabGroup.NeutralRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Baker]); - TransformNoMoreBread = BooleanOptionItem.Create(Id + 13, "BakerTransformNoMoreBread", true, TabGroup.NeutralRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Baker]); - CanVent = BooleanOptionItem.Create(Id + 14, "BakerCanVent", true, TabGroup.NeutralRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Baker]); } public override void Init() { + playerIdList.Clear(); BreadList.Clear(); RevealList.Clear(); BarrierList.Clear(); @@ -56,6 +54,7 @@ public override void Init() } public override void Add(byte playerId) { + playerIdList.Add(playerId); BreadList[playerId] = []; RevealList[playerId] = []; BarrierList[playerId] = []; @@ -79,34 +78,21 @@ private static (int, int) BreadedPlayerCount(byte playerId) return (breaded, all); } public static byte CurrentBread() => BreadID; - private static void SendRPC(byte typeId, PlayerControl player, PlayerControl target) + private static void SendRPC(PlayerControl player, PlayerControl target) { - if (!player.IsNonHostModdedClient()) return; MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.SyncRoleSkill, SendOption.Reliable); writer.WriteNetObject(player); - writer.Write(typeId); writer.Write(player.PlayerId); writer.Write(target.PlayerId); AmongUsClient.Instance.FinishRpcImmediately(writer); } public override void ReceiveRPC(MessageReader reader, PlayerControl NaN) { - byte typeId = reader.ReadByte(); byte BakerId = reader.ReadByte(); byte BreadHolderId = reader.ReadByte(); - switch (typeId) - { - case 0: - BreadList[BakerId].Add(BreadHolderId); - break; - case 1: - RevealList[BakerId].Add(BreadHolderId); - break; - case 2: - BarrierList[BakerId].Add(BreadHolderId); - break; - } + BreadList[BakerId].Add(BreadHolderId); + BarrierList[BakerId].Add(BreadHolderId); } public override string GetProgressText(byte playerId, bool comms) => ColorString(GetRoleColor(CustomRoles.Baker).ShadeColor(0.25f), $"({BreadedPlayerCount(playerId).Item1}/{BreadedPlayerCount(playerId).Item2})"); public override bool OthersKnowTargetRoleColor(PlayerControl seer, PlayerControl target) => KnowRoleTarget(seer, target); @@ -137,21 +123,16 @@ public override string GetMark(PlayerControl seer, PlayerControl seen = null, bo } public override string GetMarkOthers(PlayerControl seer, PlayerControl target, bool isForMeeting = false) { - if (!_Player) return string.Empty; - if (HasBread(_Player.PlayerId, target.PlayerId) && seer.IsNeutralApocalypse() && seer.PlayerId != _Player.PlayerId) + if (playerIdList.Any() && HasBread(playerIdList.First(), target.PlayerId) && seer.IsNeutralApocalypse() && seer.PlayerId != playerIdList.First()) { return ColorString(GetRoleColor(CustomRoles.Baker), "●"); } return string.Empty; } public override bool CanUseKillButton(PlayerControl pc) => pc.IsAlive(); - public override bool CanUseImpostorVentButton(PlayerControl pc) => CanVent.GetBool(); + public override bool CanUseImpostorVentButton(PlayerControl pc) => true; public override void SetKillCooldown(byte id) => Main.AllPlayerKillCooldown[id] = Main.AllPlayerKillCooldown[id]; - public override void SetAbilityButtonText(HudManager hud, byte playerId) - { - hud.KillButton.OverrideText(GetString("BakerKillButtonText")); - hud.AbilityButton.OverrideText(GetString("BakerUnshiftButtonText")); - } + public override void SetAbilityButtonText(HudManager hud, byte playerId) => hud.KillButton.OverrideText(GetString("BakerKillButtonText")); public static bool HasBread(byte pc, byte target) => BreadList.TryGetValue(pc, out var breadList) && breadList.Contains(target); private static bool AllHasBread(PlayerControl player) { @@ -175,10 +156,9 @@ private void OnPlayerDead(PlayerControl killer, PlayerControl deadPlayer, bool i } } } - public override void UnShapeShiftButton(PlayerControl pc) + public override void OnEnterVent(PlayerControl pc, Vent vent) { - if (BTOS2Baker.GetBool()) - { + if (BTOS2Baker.GetBool()) { var sb = new StringBuilder(); switch (BreadID) // 0 = Reveal, 1 = Roleblock, 2 = Barrier { @@ -231,10 +211,9 @@ public override bool ForcedCheckMurderAsKiller(PlayerControl killer, PlayerContr else if (HasBread(killer.PlayerId, target.PlayerId)) killer.Notify(GetString("BakerAlreadyBreaded")); - else + else { BreadList[killer.PlayerId].Add(target.PlayerId); - SendRPC(0, killer, target); NotifyRoles(SpecifySeer: killer); killer.Notify(GetString("BakerBreaded")); @@ -243,22 +222,21 @@ public override bool ForcedCheckMurderAsKiller(PlayerControl killer, PlayerContr Logger.Info($"Bread given to " + target.GetRealName(), "Baker"); if (BTOS2Baker.GetBool()) - { + { switch (BreadID) { case 0: // Reveal RevealList[killer.PlayerId].Add(target.PlayerId); - SendRPC(1, killer, target); break; case 1: // Roleblock target.SetKillCooldownV3(999f); break; case 2: // Barrier BarrierList[killer.PlayerId].Add(target.PlayerId); - SendRPC(2, killer, target); break; - } + } } + SendRPC(killer, target); } return false; } @@ -277,27 +255,23 @@ public override bool CheckMurderOnOthersTarget(PlayerControl killer, PlayerContr } public override void AfterMeetingTasks() { - if (_Player) - BarrierList[_Player.PlayerId].Clear(); + if (playerIdList.Any()) + BarrierList[playerIdList.First()].Clear(); } public override void OnFixedUpdate(PlayerControl player, bool lowLoad, long nowTime) { - if (lowLoad || (!AllHasBread(player) && !TransformNoMoreBread.GetBool()) || player.Is(CustomRoles.Famine)) return; - if (TransformNoMoreBread.GetBool() && BreadedPlayerCount(player.PlayerId).Item1 < Main.AllAlivePlayerControls.Where(x => !x.IsNeutralApocalypse()).Count()) return; + if (lowLoad || !AllHasBread(player) || player.Is(CustomRoles.Famine)) return; - player.RpcChangeRoleBasis(CustomRoles.Famine); player.RpcSetCustomRole(CustomRoles.Famine); player.GetRoleClass()?.OnAdd(_Player.PlayerId); player.Notify(GetString("BakerToFamine")); player.RpcGuardAndKill(player); } - } internal class Famine : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Famine; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Famine); public override bool IsDesyncRole => true; public override CustomRoles ThisRoleBase => CustomRoles.Impostor; @@ -315,7 +289,7 @@ public override void Add(byte playerId) public override void SetKillCooldown(byte id) => Main.AllPlayerKillCooldown[id] = Baker.FamineStarveCooldown.GetFloat(); public override void ApplyGameOptions(IGameOptions opt, byte playerId) => opt.SetVision(true); public override bool CanUseKillButton(PlayerControl pc) => true; - public override bool CanUseImpostorVentButton(PlayerControl pc) => Baker.CanVent.GetBool(); + public override bool CanUseImpostorVentButton(PlayerControl pc) => true; public override bool OnCheckMurderAsTarget(PlayerControl killer, PlayerControl target) => false; public override void SetAbilityButtonText(HudManager hud, byte playerId) => hud.KillButton.OverrideText(GetString("FamineKillButtonText")); diff --git a/Roles/Neutral/Bandit.cs b/Roles/Neutral/Bandit.cs index ede6840e2..3d5267119 100644 --- a/Roles/Neutral/Bandit.cs +++ b/Roles/Neutral/Bandit.cs @@ -10,7 +10,6 @@ namespace TOHE.Roles.Neutral; internal class Bandit : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Bandit; private const int Id = 16000; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Bandit); public override bool IsDesyncRole => true; @@ -30,7 +29,6 @@ internal class Bandit : RoleBase private float killCooldown; private readonly Dictionary Targets = []; - [Obfuscation(Exclude = true)] private enum BanditStealModeOptList { BanditStealMode_OnMeeting, @@ -54,7 +52,7 @@ public override void SetupCustomOption() public override void Add(byte playerId) { AbilityLimit = MaxSteals.GetInt(); - killCooldown = KillCooldownOpt.GetFloat(); + killCooldown = KillCooldownOpt.GetFloat(); var pc = Utils.GetPlayerById(playerId); pc?.AddDoubleTrigger(); @@ -81,9 +79,9 @@ public override void SetKillCooldown(byte id) (role.IsImpOnlyAddon() && !CanStealImpOnlyAddon.GetBool()) || (role == CustomRoles.Nimble && CanVent.GetBool()) || ((role.IsBetrayalAddon() || role is CustomRoles.Lovers) && !CanStealBetrayalAddon.GetBool())) - { - Logger.Info($"Removed {role} from list of stealable addons", "Bandit"); - AllSubRoles.Remove(role); + { + Logger.Info($"Removed {role} from list of stealable addons", "Bandit"); + AllSubRoles.Remove(role); } } @@ -125,7 +123,7 @@ public override void ReceiveRPC(MessageReader reader, PlayerControl pc) private void StealAddon(PlayerControl killer, PlayerControl target, CustomRoles? SelectedAddOn) { target.AddInSwitchAddons(killer, IsAddon: SelectedAddOn); - + if (StealMode.GetValue() == 1) { Main.PlayerStates[target.PlayerId].RemoveSubRole((CustomRoles)SelectedAddOn); @@ -201,7 +199,7 @@ public override void OnReportDeadBody(PlayerControl reportash, NetworkedPlayerIn byte targetId = kvp2.Key; var target = Utils.GetPlayerById(targetId); if (target == null) continue; - + CustomRoles role = kvp2.Value; Main.PlayerStates[targetId].RemoveSubRole(role); Logger.Info($"Successfully removed {role} addon from {target.GetNameWithRole()}", "Bandit"); diff --git a/Roles/Neutral/Berserker.cs b/Roles/Neutral/Berserker.cs index 243bb681b..9454facc9 100644 --- a/Roles/Neutral/Berserker.cs +++ b/Roles/Neutral/Berserker.cs @@ -1,8 +1,8 @@ -using AmongUs.GameOptions; +using AmongUs.GameOptions; +using TOHE.Roles.Core; using Hazel; using InnerNet; using TOHE.Modules; -using TOHE.Roles.Core; using TOHE.Roles.Impostor; using static TOHE.Options; using static TOHE.Translator; @@ -12,15 +12,16 @@ namespace TOHE.Roles.Neutral; internal class Berserker : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Berserker; private const int Id = 600; + + private static readonly HashSet PlayerIds = []; + public static bool HasEnabled => PlayerIds.Any(); public override bool IsDesyncRole => true; public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralApocalypse; //==================================================================\\ private static OptionItem BerserkerKillCooldown; - private static OptionItem BerserkerCanKillTeamate; private static OptionItem BerserkerMax; private static OptionItem BerserkerOneCanKillCooldown; private static OptionItem BerserkerKillCooldownLevel; @@ -39,7 +40,7 @@ internal class Berserker : RoleBase private static OptionItem BerserkerCanVent; public static OptionItem WarCanVent; - public static readonly Dictionary BerserkerKillMax = []; + private readonly Dictionary BerserkerKillMax = []; public override void SetupCustomOption() { @@ -52,16 +53,16 @@ public override void SetupCustomOption() WarHasImpostorVision = BooleanOptionItem.Create(Id + 16, "WarHasImpostorVision", true, TabGroup.NeutralRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Berserker]); BerserkerCanVent = BooleanOptionItem.Create(Id + 17, "BerserkerCanVent", true, TabGroup.NeutralRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Berserker]); WarCanVent = BooleanOptionItem.Create(Id + 18, "WarCanVent", true, TabGroup.NeutralRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Berserker]); - BerserkerOneCanKillCooldown = BooleanOptionItem.Create(Id + 5, "BerserkerOneCanKillCooldown", true, TabGroup.NeutralRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Berserker]); - BerserkerOneKillCooldown = FloatOptionItem.Create(Id + 6, "BerserkerOneKillCooldown", new(10f, 45f, 2.5f), 15f, TabGroup.NeutralRoles, false).SetParent(BerserkerOneCanKillCooldown) + BerserkerOneCanKillCooldown = BooleanOptionItem.Create(Id + 4, "BerserkerOneCanKillCooldown", true, TabGroup.NeutralRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Berserker]); + BerserkerOneKillCooldown = FloatOptionItem.Create(Id + 5, "BerserkerOneKillCooldown", new(10f, 45f, 2.5f), 15f, TabGroup.NeutralRoles, false).SetParent(BerserkerOneCanKillCooldown) .SetValueFormat(OptionFormat.Seconds); - BerserkerKillCooldownLevel = IntegerOptionItem.Create(Id + 7, "BerserkerLevelRequirement", new(1, 10, 1), 1, TabGroup.NeutralRoles, false).SetParent(BerserkerOneCanKillCooldown) + BerserkerKillCooldownLevel = IntegerOptionItem.Create(Id + 6, "BerserkerLevelRequirement", new(1, 10, 1), 1, TabGroup.NeutralRoles, false).SetParent(BerserkerOneCanKillCooldown) .SetValueFormat(OptionFormat.Level); - BerserkerTwoCanScavenger = BooleanOptionItem.Create(Id + 8, "BerserkerTwoCanScavenger", true, TabGroup.NeutralRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Berserker]); - BerserkerScavengerLevel = IntegerOptionItem.Create(Id + 9, "BerserkerLevelRequirement", new(1, 10, 1), 2, TabGroup.NeutralRoles, false).SetParent(BerserkerTwoCanScavenger) + BerserkerTwoCanScavenger = BooleanOptionItem.Create(Id + 7, "BerserkerTwoCanScavenger", true, TabGroup.NeutralRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Berserker]); + BerserkerScavengerLevel = IntegerOptionItem.Create(Id + 8, "BerserkerLevelRequirement", new(1, 10, 1), 2, TabGroup.NeutralRoles, false).SetParent(BerserkerTwoCanScavenger) .SetValueFormat(OptionFormat.Level); - BerserkerThreeCanBomber = BooleanOptionItem.Create(Id + 10, "BerserkerThreeCanBomber", true, TabGroup.NeutralRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Berserker]); - BerserkerBomberLevel = IntegerOptionItem.Create(Id + 11, "BerserkerLevelRequirement", new(1, 10, 1), 3, TabGroup.NeutralRoles, false).SetParent(BerserkerThreeCanBomber) + BerserkerThreeCanBomber = BooleanOptionItem.Create(Id + 9, "BerserkerThreeCanBomber", true, TabGroup.NeutralRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Berserker]); + BerserkerBomberLevel = IntegerOptionItem.Create(Id + 10, "BerserkerLevelRequirement", new(1, 10, 1), 3, TabGroup.NeutralRoles, false).SetParent(BerserkerThreeCanBomber) .SetValueFormat(OptionFormat.Level); //BerserkerFourCanFlash = BooleanOptionItem.Create(Id + 11, "BerserkerFourCanFlash", true, TabGroup.NeutralRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Berserker]); //BerserkerSpeed = FloatOptionItem.Create(611, "BerserkerSpeed", new(1.5f, 5f, 0.25f), 2.5f, TabGroup.NeutralRoles, false).SetParent(BerserkerOneCanKillCooldown) @@ -71,25 +72,26 @@ public override void SetupCustomOption() .SetValueFormat(OptionFormat.Level); WarKillCooldown = FloatOptionItem.Create(Id + 14, "WarKillCooldown", new(0f, 150f, 2.5f), 15f, TabGroup.NeutralRoles, false).SetParent(BerserkerFourCanNotKill) .SetValueFormat(OptionFormat.Seconds); - BerserkerCanKillTeamate = BooleanOptionItem.Create(Id + 19, "BerserkerCanKillTeamate", true, TabGroup.NeutralRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Berserker]); } public override void Init() { BerserkerKillMax.Clear(); + PlayerIds.Clear(); } public override void Add(byte playerId) { Main.AllPlayerKillCooldown[playerId] = BerserkerKillCooldown.GetFloat(); BerserkerKillMax[playerId] = 0; + PlayerIds.Add(playerId); } public override void Remove(byte playerId) { BerserkerKillMax.Remove(playerId); } - private void SendRPC(PlayerControl player) + private void SendRPC() { MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.SyncRoleSkill, SendOption.Reliable); - writer.WriteNetObject(player); + writer.WriteNetObject(_Player); writer.WritePacked(BerserkerKillMax[_Player.PlayerId]); AmongUsClient.Instance.FinishRpcImmediately(writer); } @@ -99,19 +101,19 @@ public override void ReceiveRPC(MessageReader reader, PlayerControl NaN) BerserkerKillMax[_Player.PlayerId] = killCount; } - public override bool OthersKnowTargetRoleColor(PlayerControl seer, PlayerControl target) + public override bool OthersKnowTargetRoleColor(PlayerControl seer, PlayerControl target) => KnowRoleTarget(seer, target); - public override bool KnowRoleTarget(PlayerControl seer, PlayerControl target) - => target.IsNeutralApocalypse() && seer.IsNeutralApocalypse(); + public override bool KnowRoleTarget(PlayerControl seer, PlayerControl target) + => (target.IsNeutralApocalypse() && seer.IsNeutralApocalypse()); public override string GetProgressText(byte playerId, bool cvooms) => Utils.ColorString(Utils.GetRoleColor(CustomRoles.Berserker).ShadeColor(0.25f), BerserkerKillMax.TryGetValue(playerId, out var x) ? $"({x}/{BerserkerMax.GetInt()})" : "Invalid"); public override bool CanUseImpostorVentButton(PlayerControl pc) => BerserkerCanVent.GetBool(); - public override void ApplyGameOptions(IGameOptions opt, byte playerId) + public override void ApplyGameOptions(IGameOptions opt, byte playerId) => opt.SetVision(BerserkerHasImpostorVision.GetBool()); public override bool CanUseKillButton(PlayerControl pc) => pc.IsAlive(); public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { - if (target.IsNeutralApocalypse() && !BerserkerCanKillTeamate.GetBool()) return false; - + if (target.IsNeutralApocalypse()) return false; + bool noScav = true; if (BerserkerKillMax[killer.PlayerId] < BerserkerMax.GetInt()) { @@ -137,7 +139,7 @@ public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl t killer.RpcTeleport(target.GetCustomPosition()); RPC.PlaySoundRPC(killer.PlayerId, Sounds.KillSound); target.RpcTeleport(ExtendedPlayerControl.GetBlackRoomPosition()); - + Main.PlayerStates[target.PlayerId].SetDead(); target.RpcMurderPlayer(target); target.SetRealKiller(killer); @@ -161,22 +163,13 @@ public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl t if (Utils.GetDistance(killer.transform.position, player.transform.position) <= Bomber.BomberRadius.GetFloat()) { - if (!target.IsNeutralApocalypse()) - { - Main.PlayerStates[player.PlayerId].deathReason = PlayerState.DeathReason.Bombed; - player.RpcMurderPlayer(player); - player.SetRealKiller(killer); - } - if (target.IsNeutralApocalypse() && BerserkerCanKillTeamate.GetBool()) - { - Main.PlayerStates[player.PlayerId].deathReason = PlayerState.DeathReason.Bombed; - player.RpcMurderPlayer(player); - player.SetRealKiller(killer); - } + Main.PlayerStates[player.PlayerId].deathReason = PlayerState.DeathReason.Bombed; + player.RpcMurderPlayer(player); + player.SetRealKiller(killer); } } } - if (BerserkerKillMax[killer.PlayerId] >= BerserkerImmortalLevel.GetInt() && BerserkerFourCanNotKill.GetBool() && !killer.Is(CustomRoles.War)) + if (BerserkerKillMax[killer.PlayerId] >= BerserkerImmortalLevel.GetInt() && BerserkerFourCanNotKill.GetBool()&& !killer.Is(CustomRoles.War)) { killer.RpcSetCustomRole(CustomRoles.War); killer.GetRoleClass()?.OnAdd(killer.PlayerId); @@ -185,24 +178,23 @@ public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl t Main.AllPlayerKillCooldown[killer.PlayerId] = WarKillCooldown.GetFloat(); } - SendRPC(killer); + SendRPC(); return noScav; } } internal class War : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.War; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Berserker); public override bool IsDesyncRole => true; public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralApocalypse; //==================================================================\\ - public override bool OthersKnowTargetRoleColor(PlayerControl seer, PlayerControl target) + public override bool OthersKnowTargetRoleColor(PlayerControl seer, PlayerControl target) => KnowRoleTarget(seer, target); public override bool KnowRoleTarget(PlayerControl seer, PlayerControl target) - => target.IsNeutralApocalypse() && seer.IsNeutralApocalypse(); + => (target.IsNeutralApocalypse() && seer.IsNeutralApocalypse()); public override void SetKillCooldown(byte id) => Main.AllPlayerKillCooldown[id] = Berserker.WarKillCooldown.GetFloat(); public override void ApplyGameOptions(IGameOptions opt, byte playerId) => opt.SetVision(Berserker.WarHasImpostorVision.GetBool()); public override bool CanUseKillButton(PlayerControl pc) => true; @@ -212,16 +204,4 @@ public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl t { return CustomRoles.Berserker.GetStaticRoleClass().OnCheckMurderAsKiller(killer, target); } - - public override void Remove(byte playerId) - { - Berserker.BerserkerKillMax.Remove(playerId); - } - - public override void ReceiveRPC(MessageReader reader, PlayerControl NaN) - { - var killCount = reader.ReadPackedInt32(); - - Berserker.BerserkerKillMax[_Player.PlayerId] = killCount; - } -} +} \ No newline at end of file diff --git a/Roles/Neutral/BloodKnight.cs b/Roles/Neutral/BloodKnight.cs index 0d7425ab8..4bf2694fa 100644 --- a/Roles/Neutral/BloodKnight.cs +++ b/Roles/Neutral/BloodKnight.cs @@ -11,7 +11,6 @@ namespace TOHE.Roles.Neutral; internal class BloodKnight : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.BloodKnight; private const int Id = 16100; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.BloodKnight); public override bool IsDesyncRole => true; @@ -57,7 +56,7 @@ public override void ReceiveRPC(MessageReader reader, PlayerControl NaN) public override void ApplyGameOptions(IGameOptions opt, byte id) => opt.SetVision(HasImpostorVision.GetBool()); private bool InProtect() => TimeStamp > Utils.GetTimeStamp(); - + public override bool OnCheckMurderAsTarget(PlayerControl killer, PlayerControl target) { if (InProtect()) @@ -106,4 +105,4 @@ public override string GetLowerText(PlayerControl seer, PlayerControl seen, bool } return str.ToString(); } -} +} \ No newline at end of file diff --git a/Roles/Neutral/Collector.cs b/Roles/Neutral/Collector.cs index 9747b9682..650d236db 100644 --- a/Roles/Neutral/Collector.cs +++ b/Roles/Neutral/Collector.cs @@ -8,7 +8,6 @@ internal class Collector : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Collector; private const int Id = 14700; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Collector); public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; diff --git a/Roles/Neutral/Cultist.cs b/Roles/Neutral/Cultist.cs index e39f1a09d..c3c42027f 100644 --- a/Roles/Neutral/Cultist.cs +++ b/Roles/Neutral/Cultist.cs @@ -10,7 +10,6 @@ namespace TOHE.Roles.Neutral; internal class Cultist : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Cultist; private const int Id = 14800; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Cultist); public override bool IsDesyncRole => true; @@ -26,7 +25,6 @@ internal class Cultist : RoleBase private static OptionItem CanCharmNeutral; public static OptionItem CharmedCountMode; - [Obfuscation(Exclude = true)] private enum CharmedCountModeSelectList { Cultist_CharmedCountMode_None, @@ -70,7 +68,7 @@ public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl t killer.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Cultist), GetString("CultistCharmedPlayer"))); target.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Cultist), GetString("CharmedByCultist"))); - + Utils.NotifyRoles(SpecifySeer: killer, SpecifyTarget: target, ForceLoop: true); Utils.NotifyRoles(SpecifySeer: target, SpecifyTarget: killer, ForceLoop: true); @@ -103,9 +101,9 @@ public static bool KnowRole(PlayerControl player, PlayerControl target) public override string GetProgressText(byte playerid, bool cooms) => Utils.ColorString(AbilityLimit >= 1 ? Utils.GetRoleColor(CustomRoles.Cultist).ShadeColor(0.25f) : Color.gray, $"({AbilityLimit})"); public static bool CanBeCharmed(PlayerControl pc) { - return pc != null && (pc.GetCustomRole().IsCrewmate() || pc.GetCustomRole().IsImpostor() || - (CanCharmNeutral.GetBool() && pc.GetCustomRole().IsNeutral())) && !pc.Is(CustomRoles.Charmed) - && !pc.Is(CustomRoles.Admired) && !pc.Is(CustomRoles.Loyal) && !pc.Is(CustomRoles.Infectious) + return pc != null && (pc.GetCustomRole().IsCrewmate() || pc.GetCustomRole().IsImpostor() || + (CanCharmNeutral.GetBool() && pc.GetCustomRole().IsNeutral())) && !pc.Is(CustomRoles.Charmed) + && !pc.Is(CustomRoles.Admired) && !pc.Is(CustomRoles.Loyal) && !pc.Is(CustomRoles.Infectious) && !pc.Is(CustomRoles.Virus) && !pc.Is(CustomRoles.Cultist) && !(pc.GetCustomSubRoles().Contains(CustomRoles.Hurried) && !Hurried.CanBeConverted.GetBool()); } @@ -114,7 +112,7 @@ public static bool NameRoleColor(PlayerControl seer, PlayerControl target) if (seer.Is(CustomRoles.Charmed) && target.Is(CustomRoles.Cultist)) return true; if (seer.Is(CustomRoles.Cultist) && target.Is(CustomRoles.Charmed)) return true; if (seer.Is(CustomRoles.Charmed) && target.Is(CustomRoles.Charmed) && TargetKnowOtherTarget.GetBool()) return true; - + return false; } public override void SetAbilityButtonText(HudManager hud, byte playerId) @@ -122,4 +120,4 @@ public override void SetAbilityButtonText(HudManager hud, byte playerId) hud.KillButton.OverrideText(GetString("CultistKillButtonText")); } public override Sprite GetKillButtonSprite(PlayerControl player, bool shapeshifting) => CustomButton.Get("Subbus"); -} +} \ No newline at end of file diff --git a/Roles/Neutral/CursedSoul.cs b/Roles/Neutral/CursedSoul.cs index 9563195c1..d2f0bf09d 100644 --- a/Roles/Neutral/CursedSoul.cs +++ b/Roles/Neutral/CursedSoul.cs @@ -9,8 +9,9 @@ namespace TOHE.Roles.Neutral; internal class CursedSoul : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.CursedSoul; private const int Id = 14000; + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); public override bool IsDesyncRole => true; public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralEvil; @@ -38,10 +39,12 @@ public override void SetupCustomOption() } public override void Init() { + playerIdList.Clear(); CurseLimit = CurseMax.GetInt(); } public override void Add(byte playerId) { + playerIdList.Add(playerId); CurseLimit = CurseMax.GetInt(); } @@ -55,13 +58,13 @@ private void SendRPC() public static void ReceiveRPC(MessageReader reader) { var pID = reader.ReadByte(); - if (Main.PlayerStates[pID].RoleClass is CursedSoul cs) + if (Main.PlayerStates[pID].RoleClass is CursedSoul cs) cs.CurseLimit = reader.ReadInt32(); } public override void SetKillCooldown(byte id) => Main.AllPlayerKillCooldown[id] = CurseLimit >= 1 ? CurseCooldown.GetFloat() + (CurseMax.GetInt() - CurseLimit) * CurseCooldownIncrese.GetFloat() : 300f; public override bool CanUseKillButton(PlayerControl player) => CurseLimit >= 1; - + public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { if (CurseLimit < 1) return false; @@ -78,8 +81,8 @@ public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl t killer.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.CursedSoul), GetString("CursedSoulSoullessPlayer"))); target.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.CursedSoul), GetString("SoullessByCursedSoul"))); - - Utils.NotifyRoles(SpecifySeer: target, SpecifyTarget: killer, ForceLoop: true); + + Utils.NotifyRoles(SpecifySeer: target , SpecifyTarget: killer, ForceLoop: true); Utils.NotifyRoles(SpecifySeer: killer, SpecifyTarget: target, ForceLoop: true); killer.ResetKillCooldown(); @@ -101,11 +104,11 @@ public override bool KnowRoleTarget(PlayerControl player, PlayerControl target) public override string PlayerKnowTargetColor(PlayerControl seer, PlayerControl target) => KnowRoleTarget(seer, target) ? Main.roleColors[CustomRoles.Soulless] : string.Empty; - + public override string GetProgressText(byte id, bool cooms) => Utils.ColorString(CurseLimit >= 1 ? Utils.GetRoleColor(CustomRoles.CursedSoul) : Color.gray, $"({CurseLimit})"); private static bool CanBeSoulless(PlayerControl pc) { - return pc != null && (pc.GetCustomRole().IsCrewmate() || pc.GetCustomRole().IsImpostor() || + return pc != null && (pc.GetCustomRole().IsCrewmate() || pc.GetCustomRole().IsImpostor() || (CanCurseNeutral.GetBool() && pc.GetCustomRole().IsNeutral())) && !pc.Is(CustomRoles.Soulless) && !pc.Is(CustomRoles.Admired) && !pc.Is(CustomRoles.Loyal); } public override void SetAbilityButtonText(HudManager hud, byte playerId) @@ -113,4 +116,4 @@ public override void SetAbilityButtonText(HudManager hud, byte playerId) hud.KillButton.OverrideText(GetString("CursedSoulKillButtonText")); } public override Sprite GetKillButtonSprite(PlayerControl player, bool shapeshifting) => CustomButton.Get("Soul"); -} +} \ No newline at end of file diff --git a/Roles/Neutral/Demon.cs b/Roles/Neutral/Demon.cs index c2ab0e4bf..4cc16258e 100644 --- a/Roles/Neutral/Demon.cs +++ b/Roles/Neutral/Demon.cs @@ -11,7 +11,6 @@ namespace TOHE.Roles.Neutral; internal class Demon : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Demon; private const int Id = 16200; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Demon); public override bool IsDesyncRole => true; @@ -113,7 +112,7 @@ public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl t public override bool OnCheckMurderAsTarget(PlayerControl killer, PlayerControl target) { if (target.IsTransformedNeutralApocalypse()) return true; - if (killer == null || target == null) return true; + if (killer == null || target == null) return true; if (DemonHealth.TryGetValue(target.PlayerId, out var Health) && Health - SelfDamage.GetInt() < 1) { @@ -165,4 +164,4 @@ public override void SetAbilityButtonText(HudManager hud, byte playerId) { hud.KillButton.OverrideText(GetString("DemonButtonText")); } -} +} \ No newline at end of file diff --git a/Roles/Neutral/Doomsayer.cs b/Roles/Neutral/Doomsayer.cs index e88d9370c..3fb16a208 100644 --- a/Roles/Neutral/Doomsayer.cs +++ b/Roles/Neutral/Doomsayer.cs @@ -1,17 +1,16 @@ -using AmongUs.GameOptions; -using Hazel; -using InnerNet; -using TOHE.Roles.Core; +using Hazel; using UnityEngine; -using static TOHE.Translator; using static TOHE.Utils; +using static TOHE.Translator; +using TOHE.Roles.Core; +using InnerNet; +using AmongUs.GameOptions; namespace TOHE.Roles.Neutral; internal class Doomsayer : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Doomsayer; private const int Id = 14100; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Doomsayer); public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; @@ -102,12 +101,12 @@ public override string GetProgressText(byte playerId, bool comms) { var (GuessingToWin, AmountOfGuessesToWin) = GuessedPlayerCount(playerId); return ColorString(GetRoleColor(CustomRoles.Doomsayer).ShadeColor(0.25f), $"({GuessingToWin}/{AmountOfGuessesToWin})"); - + } public static bool CheckCantGuess = CantGuess; public static bool NeedHideMsg(PlayerControl pc) => pc.Is(CustomRoles.Doomsayer) && DoomsayerTryHideMsg.GetBool(); - + private void CheckCountGuess(PlayerControl doomsayer) { if (!(GuessingToWin[doomsayer.PlayerId] >= DoomsayerAmountOfGuessesToWin.GetInt())) return; @@ -120,7 +119,7 @@ private void CheckCountGuess(PlayerControl doomsayer) CustomWinnerHolder.WinnerIds.Add(doomsayer.PlayerId); } } - + public override void OnReportDeadBody(PlayerControl goku, NetworkedPlayerInfo solos) { if (!AdvancedSettings.GetBool()) return; @@ -147,7 +146,7 @@ public static bool HideTabInGuesserUI(int TabId) public override bool GuessCheck(bool isUI, PlayerControl guesser, PlayerControl target, CustomRoles role, ref bool guesserSuicide) { - if (CheckCantGuess || GuessesCountPerMeeting >= MaxNumberOfGuessesPerMeeting.GetInt()) + if (CheckCantGuess) { guesser.ShowInfoMessage(isUI, GetString("DoomsayerCantGuess")); return true; @@ -188,7 +187,6 @@ public override bool CheckMisGuessed(bool isUI, PlayerControl guesser, PlayerCon { if (GuessesCountPerMeeting >= MaxNumberOfGuessesPerMeeting.GetInt() && guesser.PlayerId != target.PlayerId) { - CantGuess = true; guesser.ShowInfoMessage(isUI, GetString("DoomsayerCantGuess")); return true; } @@ -261,4 +259,4 @@ public void SendMessageAboutGuess(PlayerControl guesser, PlayerControl playerMis }, 0.7f, "Doomsayer Guess Msg 2"); } } -} +} \ No newline at end of file diff --git a/Roles/Neutral/Doppelganger.cs b/Roles/Neutral/Doppelganger.cs index 1d1d74b06..6c27d9e23 100644 --- a/Roles/Neutral/Doppelganger.cs +++ b/Roles/Neutral/Doppelganger.cs @@ -10,7 +10,6 @@ namespace TOHE.Roles.Neutral; internal class Doppelganger : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Doppelganger; private const int Id = 25000; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Doppelganger); public override bool IsDesyncRole => true; @@ -88,4 +87,4 @@ public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl t } public override string GetProgressText(byte playerId, bool cooms) => Utils.ColorString(AbilityLimit > 0 ? Utils.GetRoleColor(CustomRoles.Doppelganger).ShadeColor(0.25f) : Color.gray, $"({AbilityLimit})"); -} +} \ No newline at end of file diff --git a/Roles/Neutral/Executioner.cs b/Roles/Neutral/Executioner.cs index 6462d5af7..4d0d12b6c 100644 --- a/Roles/Neutral/Executioner.cs +++ b/Roles/Neutral/Executioner.cs @@ -8,9 +8,10 @@ namespace TOHE.Roles.Neutral; internal class Executioner : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Executioner; private const int Id = 14200; public static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralEvil; //==================================================================\\ @@ -28,7 +29,6 @@ internal class Executioner : RoleBase public static HashSet TargetList = []; private byte TargetId; - [Obfuscation(Exclude = true)] private enum ChangeRolesSelectList { Role_Crewmate, @@ -73,10 +73,7 @@ public override void Init() } public override void Add(byte playerId) { - if (!playerIdList.Contains(playerId)) - { - playerIdList.Add(playerId); - } + playerIdList.Add(playerId); CustomRoleManager.CheckDeadBodyOthers.Add(OnOthersDead); @@ -110,7 +107,7 @@ public override void Add(byte playerId) } else { - Logger.Warn("Warning! No suitableable target was found for executioner, switching role", "Executioner.Add"); + Logger.Warn("Warning! No suitableable target was found for executioner, switching role","Executioner.Add"); ChangeRole(); } } @@ -121,7 +118,7 @@ public override void Remove(byte playerId) { SendRPC(SetTarget: false); } - + playerIdList.Remove(playerId); TargetList.Remove(TargetId); TargetId = byte.MaxValue; } @@ -239,4 +236,4 @@ private static void ExeWin(byte executionerId, bool DecidedWinner) CustomWinnerHolder.WinnerIds.Add(executionerId); } } -} +} \ No newline at end of file diff --git a/Roles/Neutral/Follower.cs b/Roles/Neutral/Follower.cs index 8c49c9365..fe9a3ab0f 100644 --- a/Roles/Neutral/Follower.cs +++ b/Roles/Neutral/Follower.cs @@ -12,8 +12,9 @@ namespace TOHE.Roles.Neutral; internal class Follower : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Follower; private const int Id = 12800; + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); public override bool IsDesyncRole => true; public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralBenign; @@ -45,11 +46,13 @@ public override void SetupCustomOption() } public override void Init() { + playerIdList.Clear(); BetTimes.Clear(); BetPlayer.Clear(); } public override void Add(byte playerId) { + playerIdList.Add(playerId); BetTimes.Add(playerId, MaxBetTimes.GetInt()); } private void SendRPC(byte playerId) @@ -105,7 +108,7 @@ public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl t Utils.NotifyRoles(SpecifySeer: killer, SpecifyTarget: Utils.GetPlayerById(originalTarget), ForceLoop: true); Utils.NotifyRoles(SpecifySeer: Utils.GetPlayerById(originalTarget), SpecifyTarget: killer, ForceLoop: true); } - + BetPlayer.Remove(killer.PlayerId); BetPlayer.Add(killer.PlayerId, target.PlayerId); SendRPC(killer.PlayerId); @@ -145,4 +148,4 @@ public override void SetAbilityButtonText(HudManager hud, byte playerId) { hud.KillButton.OverrideText(GetString("FollowerKillButtonText")); } -} +} \ No newline at end of file diff --git a/Roles/Neutral/Glitch.cs b/Roles/Neutral/Glitch.cs index 2e92e58f8..3fb21e3ee 100644 --- a/Roles/Neutral/Glitch.cs +++ b/Roles/Neutral/Glitch.cs @@ -1,17 +1,16 @@ using AmongUs.GameOptions; -using Hazel; -using InnerNet; using System.Text; -using TOHE.Roles.Core; -using static TOHE.Options; using static TOHE.Translator; +using static TOHE.Options; +using Hazel; +using TOHE.Roles.Core; +using InnerNet; namespace TOHE.Roles.Neutral; internal class Glitch : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Glitch; private const int Id = 16300; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Glitch); public override bool IsDesyncRole => true; @@ -270,7 +269,7 @@ public static void CancelReportInFixedUpdate(PlayerControl __instance, byte id) } public static bool OnCheckMurderOthers(PlayerControl killer, PlayerControl target) { - if (killer == target || killer == null) return true; + if (killer == target || killer == null) return true; if (hackedIdList.ContainsKey(killer.PlayerId)) { killer.Notify(string.Format(GetString("HackedByGlitch"), GetString("GlitchKill"))); diff --git a/Roles/Neutral/God.cs b/Roles/Neutral/God.cs index 50f8534ab..2d4ffd0d4 100644 --- a/Roles/Neutral/God.cs +++ b/Roles/Neutral/God.cs @@ -5,8 +5,9 @@ namespace TOHE.Roles.Neutral; internal class God : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.God; private const int Id = 25100; + public static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralChaos; //==================================================================\\ @@ -23,6 +24,15 @@ public override void SetupCustomOption() .SetParent(Options.CustomRoleSpawnChances[CustomRoles.God]); } + public override void Init() + { + playerIdList.Clear(); + } + public override void Add(byte playerId) + { + playerIdList.Add(playerId); + } + public override bool GuessCheck(bool isUI, PlayerControl guesser, PlayerControl target, CustomRoles role, ref bool guesserSuicide) { if (!CanGuess.GetBool()) diff --git a/Roles/Neutral/Hater.cs b/Roles/Neutral/Hater.cs index f40d6e18d..2c332ade3 100644 --- a/Roles/Neutral/Hater.cs +++ b/Roles/Neutral/Hater.cs @@ -7,10 +7,9 @@ namespace TOHE.Roles.Neutral; internal class Hater : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Hater; private const int Id = 12900; public static readonly HashSet playerIdList = []; - + public static bool HasEnabled => playerIdList.Any(); public override bool IsDesyncRole => true; public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralBenign; @@ -28,7 +27,7 @@ internal class Hater : RoleBase private static OptionItem CanKillContagious; public static bool isWon = false; // There's already a playerIdList, so replaced this with a boolean value - + public override void SetupCustomOption() { SetupRoleOptions(Id, TabGroup.NeutralRoles, CustomRoles.Hater, zeroOne: false); @@ -52,8 +51,7 @@ public override void Init() public override void Add(byte playerId) { - if (!playerIdList.Contains(playerId)) - playerIdList.Add(playerId); + playerIdList.Add(playerId); } public override bool CanUseKillButton(PlayerControl pc) => true; public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) @@ -96,7 +94,7 @@ public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl t killer.SetDeathReason(PlayerState.DeathReason.Sacrifice); killer.RpcMurderPlayer(killer); - + Logger.Info($"{killer.GetRealName()} killed incorrect target => misfire", "Hater"); return false; } diff --git a/Roles/Neutral/HexMaster.cs b/Roles/Neutral/HexMaster.cs index 9a3c68d33..bb3819786 100644 --- a/Roles/Neutral/HexMaster.cs +++ b/Roles/Neutral/HexMaster.cs @@ -1,7 +1,7 @@ using AmongUs.GameOptions; using Hazel; -using System.Text; using UnityEngine; +using System.Text; using static TOHE.Options; using static TOHE.Translator; @@ -11,7 +11,6 @@ namespace TOHE.Roles.Neutral; internal class HexMaster : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.HexMaster; private const int Id = 16400; private static readonly HashSet playerIdList = []; public static bool HasEnabled => playerIdList.Any(); @@ -30,7 +29,6 @@ internal class HexMaster : RoleBase private static readonly Color RoleColorHex = Utils.GetRoleColor(CustomRoles.HexMaster); private static readonly Color RoleColorSpell = Utils.GetRoleColor(CustomRoles.Impostor); - [Obfuscation(Exclude = true)] private enum SwitchTriggerList { TriggerKill, @@ -41,10 +39,10 @@ private enum SwitchTriggerList public override void SetupCustomOption() { - SetupSingleRoleOptions(Id, TabGroup.NeutralRoles, CustomRoles.HexMaster, 1, zeroOne: false); + SetupSingleRoleOptions(Id, TabGroup.NeutralRoles, CustomRoles.HexMaster, 1, zeroOne: false); ModeSwitchAction = StringOptionItem.Create(Id + 10, GeneralOption.ModeSwitchAction, EnumHelper.GetAllNames(), 2, TabGroup.NeutralRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.HexMaster]); - HexesLookLikeSpells = BooleanOptionItem.Create(Id + 11, "HexesLookLikeSpells", false, TabGroup.NeutralRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.HexMaster]); - HasImpostorVision = BooleanOptionItem.Create(Id + 12, GeneralOption.ImpostorVision, true, TabGroup.NeutralRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.HexMaster]); + HexesLookLikeSpells = BooleanOptionItem.Create(Id + 11, "HexesLookLikeSpells", false, TabGroup.NeutralRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.HexMaster]); + HasImpostorVision = BooleanOptionItem.Create(Id + 12, GeneralOption.ImpostorVision, true, TabGroup.NeutralRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.HexMaster]); } public override void Init() { @@ -54,9 +52,7 @@ public override void Init() } public override void Add(byte playerId) { - if (!playerIdList.Contains(playerId)) - playerIdList.Add(playerId); - + playerIdList.Add(playerId); HexMode.Add(playerId, false); HexedPlayer.Add(playerId, []); NowSwitchTrigger = (SwitchTriggerList)ModeSwitchAction.GetValue(); @@ -269,7 +265,7 @@ public override string GetLowerText(PlayerControl hexmaster, PlayerControl seen return str.ToString(); } - + public override void SetAbilityButtonText(HudManager hud, byte playerid) { if (IsHexMode(playerid) && NowSwitchTrigger != SwitchTriggerList.TriggerDouble) @@ -281,13 +277,4 @@ public override void SetAbilityButtonText(HudManager hud, byte playerid) hud.KillButton.OverrideText($"{GetString("KillButtonText")}"); } } - - public override void Remove(byte playerId) - { - if (HexedPlayer.ContainsKey(playerId)) - { - HexedPlayer[playerId].Clear(); - SendRPC(true, playerId); - } - } -} +} \ No newline at end of file diff --git a/Roles/Neutral/Huntsman.cs b/Roles/Neutral/Huntsman.cs index 01cefcfe6..7a24cdaf0 100644 --- a/Roles/Neutral/Huntsman.cs +++ b/Roles/Neutral/Huntsman.cs @@ -11,7 +11,6 @@ namespace TOHE.Roles.Neutral; internal class Huntsman : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Huntsman; private const int Id = 16500; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Huntsman); public override bool IsDesyncRole => true; diff --git a/Roles/Neutral/Imitator.cs b/Roles/Neutral/Imitator.cs index ef984e06d..2ff2325b3 100644 --- a/Roles/Neutral/Imitator.cs +++ b/Roles/Neutral/Imitator.cs @@ -7,7 +7,6 @@ namespace TOHE.Roles.Neutral; internal class Imitator : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Imitator; private const int Id = 13000; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Imitator); public override bool IsExperimental => true; @@ -19,7 +18,6 @@ internal class Imitator : RoleBase private static OptionItem RememberCooldown; private static OptionItem IncompatibleNeutralMode; - [Obfuscation(Exclude = true)] private enum ImitatorIncompatibleNeutralModeSelectList { Role_Imitator, @@ -51,7 +49,7 @@ public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl t if (role is CustomRoles.Jackal or CustomRoles.HexMaster or CustomRoles.Poisoner - or CustomRoles.Juggernaut + or CustomRoles.Juggernaut or CustomRoles.BloodKnight or CustomRoles.Sheriff) { diff --git a/Roles/Neutral/Infectious.cs b/Roles/Neutral/Infectious.cs index 56498827a..b0100fbd1 100644 --- a/Roles/Neutral/Infectious.cs +++ b/Roles/Neutral/Infectious.cs @@ -10,7 +10,6 @@ namespace TOHE.Roles.Neutral; internal class Infectious : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Infectious; private const int Id = 16600; private static readonly HashSet PlayerIds = []; public static bool HasEnabled => PlayerIds.Any(); @@ -39,7 +38,7 @@ public override void SetupCustomOption() KnowTargetRole = BooleanOptionItem.Create(Id + 13, "InfectiousKnowTargetRole", true, TabGroup.NeutralRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Infectious]); TargetKnowOtherTarget = BooleanOptionItem.Create(Id + 14, "InfectiousTargetKnowOtherTarget", true, TabGroup.NeutralRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Infectious]); HasImpostorVision = BooleanOptionItem.Create(Id + 15, GeneralOption.ImpostorVision, true, TabGroup.NeutralRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Infectious]); - CanVent = BooleanOptionItem.Create(Id + 17, GeneralOption.CanVent, true, TabGroup.NeutralRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Infectious]); + CanVent = BooleanOptionItem.Create(Id + 17, GeneralOption.CanVent, true, TabGroup.NeutralRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Infectious]); DoubleClickKill = BooleanOptionItem.Create(Id + 18, "DoubleClickKill", true, TabGroup.NeutralRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Infectious]); } public override void Init() @@ -50,9 +49,7 @@ public override void Init() public override void Add(byte playerId) { BiteLimit = BiteMax.GetInt(); - if (!PlayerIds.Contains(playerId)) - PlayerIds.Add(playerId); - + PlayerIds.Add(playerId); var pc = Utils.GetPlayerById(playerId); pc?.AddDoubleTrigger(); } @@ -62,7 +59,7 @@ public override void Add(byte playerId) public override void SetKillCooldown(byte id) => Main.AllPlayerKillCooldown[id] = BiteCooldown.GetFloat(); public override bool CanUseKillButton(PlayerControl player) => BiteLimit >= 1; public override bool CanUseImpostorVentButton(PlayerControl pc) => CanVent.GetBool(); - + private static bool InfectOrMurder(PlayerControl killer, PlayerControl target) { if (CanBeBitten(target)) @@ -123,7 +120,7 @@ public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl t return false; } if (DoubleClickKill.GetBool()) - { + { bool check = killer.CheckDoubleTrigger(target, () => { InfectOrMurder(killer, target); }); //Logger.Warn("VALUE OF CHECK IS") if (check) @@ -168,15 +165,15 @@ public static bool InfectedKnowColorOthersInfected(PlayerControl player, PlayerC } public override string GetProgressText(byte playerid, bool cooms) => Utils.ColorString(BiteLimit >= 1 ? Utils.GetRoleColor(CustomRoles.Infectious).ShadeColor(0.25f) : Color.gray, $"({BiteLimit})"); - + public static bool CanBeBitten(PlayerControl pc) { - return pc != null && (pc.GetCustomRole().IsCrewmate() - || pc.GetCustomRole().IsImpostor() - || pc.GetCustomRole().IsNK()) && !pc.Is(CustomRoles.Infected) - && !pc.Is(CustomRoles.Admired) - && !pc.Is(CustomRoles.Loyal) - && !pc.Is(CustomRoles.Cultist) + return pc != null && (pc.GetCustomRole().IsCrewmate() + || pc.GetCustomRole().IsImpostor() + || pc.GetCustomRole().IsNK()) && !pc.Is(CustomRoles.Infected) + && !pc.Is(CustomRoles.Admired) + && !pc.Is(CustomRoles.Loyal) + && !pc.Is(CustomRoles.Cultist) && !pc.Is(CustomRoles.Infectious) && !pc.Is(CustomRoles.Virus); } public override void SetAbilityButtonText(HudManager hud, byte playerId) diff --git a/Roles/Neutral/Innocent.cs b/Roles/Neutral/Innocent.cs index 2b7f4cf0c..fb92ff17c 100644 --- a/Roles/Neutral/Innocent.cs +++ b/Roles/Neutral/Innocent.cs @@ -7,15 +7,16 @@ namespace TOHE.Roles.Neutral; internal class Innocent : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Innocent; private const int Id = 14300; + private static readonly HashSet PlayerIds = []; + public static bool HasEnabled => PlayerIds.Any(); public override bool IsDesyncRole => true; public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralEvil; //==================================================================\\ private static OptionItem InnocentCanWinByImp; - private bool TargetIsKilled = false; + private bool TargetIsKilled = false; public override void SetupCustomOption() { @@ -25,10 +26,12 @@ public override void SetupCustomOption() } public override void Init() { + PlayerIds.Clear(); TargetIsKilled = false; } public override void Add(byte playerId) { + PlayerIds.Add(playerId); TargetIsKilled = false; } public override bool CanUseKillButton(PlayerControl pc) => true; diff --git a/Roles/Neutral/Jackal.cs b/Roles/Neutral/Jackal.cs index e0a00b0cf..12eed319e 100644 --- a/Roles/Neutral/Jackal.cs +++ b/Roles/Neutral/Jackal.cs @@ -10,10 +10,8 @@ namespace TOHE.Roles.Neutral; internal class Jackal : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Jackal; private const int Id = 16700; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Jailer); - public static readonly HashSet Playerids = []; public override bool IsDesyncRole => true; public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralKilling; @@ -29,25 +27,20 @@ internal class Jackal : RoleBase private static OptionItem ResetKillCooldownOn; private static OptionItem JackalCanKillSidekick; private static OptionItem CanRecruitSidekick; - public static OptionItem SidekickRecruitLimitOpt; + private static OptionItem SidekickRecruitLimitOpt; public static OptionItem SidekickCountMode; private static OptionItem SidekickAssignMode; public static OptionItem KillCooldownSK; - public static OptionItem SidekickCanKillWhenJackalAlive; - public static OptionItem SidekickTurnIntoJackal; - public static OptionItem RestoreLimitOnNewJackal; public static OptionItem CanVentSK; public static OptionItem CanUseSabotageSK; private static OptionItem SidekickCanKillJackal; private static OptionItem SidekickCanKillSidekick; - [Obfuscation(Exclude = true)] private enum SidekickAssignModeSelectList { Jackal_SidekickAssignMode_SidekickAndRecruit, Jackal_SidekickAssignMode_Sidekick, Jackal_SidekickAssignMode_Recruit, } - [Obfuscation(Exclude = true)] private enum SidekickCountModeSelectList { Jackal_SidekickCountMode_Jackal, @@ -64,28 +57,20 @@ public override void SetupCustomOption() CanUsesSabotage = BooleanOptionItem.Create(Id + 12, GeneralOption.CanUseSabotage, true, TabGroup.NeutralRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Jackal]); CanWinBySabotageWhenNoImpAlive = BooleanOptionItem.Create(Id + 14, "JackalCanWinBySabotageWhenNoImpAlive", true, TabGroup.NeutralRoles, false).SetParent(CanUsesSabotage); HasImpostorVision = BooleanOptionItem.Create(Id + 13, GeneralOption.ImpostorVision, true, TabGroup.NeutralRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Jackal]); - OptionResetKillCooldownWhenSbGetKilled = BooleanOptionItem.Create(Id + 16, "JackalResetKillCooldownWhenPlayerGetKilled", false, TabGroup.NeutralRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Jackal]); ResetKillCooldownOn = FloatOptionItem.Create(Id + 28, "JackalResetKillCooldownOn", new(0f, 180f, 2.5f), 15f, TabGroup.NeutralRoles, false) .SetParent(OptionResetKillCooldownWhenSbGetKilled) .SetValueFormat(OptionFormat.Seconds); - - CanRecruitSidekick = BooleanOptionItem.Create(Id + 30, "JackalCanRecruitSidekick", true, TabGroup.NeutralRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Jackal]); JackalCanKillSidekick = BooleanOptionItem.Create(Id + 15, "JackalCanKillSidekick", false, TabGroup.NeutralRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Jackal]); + CanRecruitSidekick = BooleanOptionItem.Create(Id + 30, "JackalCanRecruitSidekick", true, TabGroup.NeutralRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Jackal]); SidekickAssignMode = StringOptionItem.Create(Id + 34, "Jackal_SidekickAssignMode", EnumHelper.GetAllNames(), 0, TabGroup.NeutralRoles, false).SetParent(CanRecruitSidekick) .SetHidden(false); - SidekickRecruitLimitOpt = IntegerOptionItem.Create(Id + 33, "JackalSidekickRecruitLimit", new(0, 15, 1), 1, TabGroup.NeutralRoles, false).SetParent(CanRecruitSidekick) + SidekickRecruitLimitOpt = IntegerOptionItem.Create(Id + 33, "JackalSidekickRecruitLimit", new(0, 15, 1), 2, TabGroup.NeutralRoles, false).SetParent(CanRecruitSidekick) .SetValueFormat(OptionFormat.Times); - - SidekickCanKillWhenJackalAlive = BooleanOptionItem.Create(Id + 35, "Jackal_SidekickCanKillWhenJackalAlive", false, TabGroup.NeutralRoles, false).SetParent(CanRecruitSidekick); - SidekickTurnIntoJackal = BooleanOptionItem.Create(Id + 36, "Jackal_SidekickTurnIntoJackal", true, TabGroup.NeutralRoles, false).SetParent(CanRecruitSidekick); - RestoreLimitOnNewJackal = BooleanOptionItem.Create(Id + 37, "Jackal_RestoreLimitOnNewJackal", true, TabGroup.NeutralRoles, false).SetParent(SidekickTurnIntoJackal); - KillCooldownSK = FloatOptionItem.Create(Id + 20, GeneralOption.KillCooldown, new(0f, 180f, 2.5f), 20f, TabGroup.NeutralRoles, false).SetParent(CanRecruitSidekick) .SetValueFormat(OptionFormat.Seconds); CanVentSK = BooleanOptionItem.Create(Id + 21, GeneralOption.CanVent, true, TabGroup.NeutralRoles, false).SetParent(CanRecruitSidekick); CanUseSabotageSK = BooleanOptionItem.Create(Id + 22, GeneralOption.CanUseSabotage, true, TabGroup.NeutralRoles, false).SetParent(CanRecruitSidekick); - SidekickCanKillJackal = BooleanOptionItem.Create(Id + 23, "Jackal_SidekickCanKillJackal", false, TabGroup.NeutralRoles, false).SetParent(CanRecruitSidekick); SidekickCanKillSidekick = BooleanOptionItem.Create(Id + 24, "Jackal_SidekickCanKillSidekick", false, TabGroup.NeutralRoles, false).SetParent(CanRecruitSidekick); SidekickCountMode = StringOptionItem.Create(Id + 25, "Jackal_SidekickCountMode", EnumHelper.GetAllNames(), 0, TabGroup.NeutralRoles, false).SetParent(CanRecruitSidekick) @@ -94,35 +79,16 @@ public override void SetupCustomOption() public override void Init() { ResetKillCooldownWhenSbGetKilled = OptionResetKillCooldownWhenSbGetKilled; - Playerids.Clear(); } public override void Add(byte playerId) { - AbilityLimit = 0; - if (Playerids.Count == 0 || RestoreLimitOnNewJackal.GetBool()) - { - AbilityLimit = CanRecruitSidekick.GetBool() ? SidekickRecruitLimitOpt.GetInt() : 0; - } - - if (!Playerids.Contains(playerId)) - Playerids.Add(playerId); + AbilityLimit = CanRecruitSidekick.GetBool() ? SidekickRecruitLimitOpt.GetInt() : 0; if (AmongUsClient.Instance.AmHost) { - SendSkillRPC(); CustomRoleManager.CheckDeadBodyOthers.Add(OthersPlayersDead); - if (_Player.Is(CustomRoles.Recruit)) - { - Main.PlayerStates[playerId].RemoveSubRole(CustomRoles.Recruit); - } } } - - public override void Remove(byte playerId) - { - CustomRoleManager.CheckDeadBodyOthers.Remove(OthersPlayersDead); - } - public override void ApplyGameOptions(IGameOptions opt, byte babuyaga) => opt.SetVision(HasImpostorVision.GetBool()); public override void SetKillCooldown(byte id) => Main.AllPlayerKillCooldown[id] = KillCooldown.GetFloat(); @@ -138,10 +104,10 @@ public static bool JackalKnowRole(PlayerControl seer, PlayerControl target) return false; } - private bool CanRecruit() => AbilityLimit > 0; + private bool CanRecruit(byte id) => AbilityLimit > 0; public override void SetAbilityButtonText(HudManager hud, byte playerId) { - if (CanRecruit()) + if (CanRecruit(playerId)) hud.KillButton?.OverrideText($"{GetString("GangsterButtonText")}"); else hud.KillButton?.OverrideText($"{GetString("KillButtonText")}"); @@ -161,119 +127,6 @@ private void OthersPlayersDead(PlayerControl killer, PlayerControl target, bool public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) { - if (target.Is(CustomRoles.Jackal)) return false; - if ((target.Is(CustomRoles.Recruit) || target.Is(CustomRoles.Sidekick))) return JackalCanKillSidekick.GetBool(); - if (!CanRecruitSidekick.GetBool() || !CanRecruit()) - { - Logger.Info("Jackal run out of recruits or Recruit disabled?", "Jackal"); - return true; - } - - if (target.Is(CustomRoles.Loyal) - || SidekickAssignMode.GetInt() == 2 && (target.Is(CustomRoles.Cleansed) || target.Is(CustomRoles.Stubborn))) - { - // Loyal or Only Recruit & can not get addon - killer.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Jackal), GetString("Jackal_RecruitFailed"))); - return true; - } - - if (target.IsAnySubRole(x => (x.IsConverted() || x == CustomRoles.Admired) && x != CustomRoles.Recruit)) - { - // Remove other team converted roles first - foreach (var x in target.GetCustomSubRoles()) - { - if (x.IsConverted() && x != CustomRoles.Recruit) - { - Main.PlayerStates[target.PlayerId].RemoveSubRole(x); - Main.PlayerStates[target.PlayerId].SubRoles.Remove(CustomRoles.Rascal); - Main.PlayerStates[target.PlayerId].SubRoles.Remove(CustomRoles.Admired); - } - } - } - - switch (SidekickAssignMode.GetInt()) - { - case 1: // Only SideKick - AbilityLimit--; - - Logger.Info($"Jackal {killer.GetNameWithRole()} assigned SideKick to {target.GetNameWithRole()}", "Jackal"); - - target.GetRoleClass()?.OnRemove(target.PlayerId); - target.RpcChangeRoleBasis(CustomRoles.Sidekick); - target.RpcSetCustomRole(CustomRoles.Sidekick); - target.GetRoleClass()?.OnAdd(target.PlayerId); - - killer.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Jackal), GetString("GangsterSuccessfullyRecruited"))); - target.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Jackal), GetString("BeRecruitedByJackal"))); - - Utils.NotifyRoles(killer, target, true); - Utils.NotifyRoles(target, killer, true); - - target.ResetKillCooldown(); - target.SetKillCooldown(forceAnime: true); - killer.ResetKillCooldown(); - killer.SetKillCooldown(forceAnime: !DisableShieldAnimations.GetBool()); - break; - case 2: // Only Recruit - if (target.GetCustomRole().IsNeutral() && target.HasImpKillButton() || target.Is(CustomRoles.Lawyer)) - { - killer.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Jackal), GetString("Jackal_RecruitFailed"))); - return true; - } - - AbilityLimit--; - Logger.Info($"Jackal {killer.GetNameWithRole()} assigned Recruit to {target.GetNameWithRole()}", "Jackal"); - target.RpcSetCustomRole(CustomRoles.Recruit); - - killer.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Jackal), GetString("GangsterSuccessfullyRecruited"))); - target.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Jackal), GetString("BeRecruitedByJackal"))); - - Utils.NotifyRoles(SpecifySeer: killer, SpecifyTarget: target, ForceLoop: true); - Utils.NotifyRoles(SpecifySeer: target, SpecifyTarget: killer, ForceLoop: true); - - killer.ResetKillCooldown(); - killer.SetKillCooldown(forceAnime: !DisableShieldAnimations.GetBool()); - - target.ResetKillCooldown(); - target.SetKillCooldown(forceAnime: true); - Main.PlayerStates[target.PlayerId].taskState.hasTasks = false; - break; - case 0: // SideKick when failed Recruit - if (target.GetCustomRole().IsNeutral() && target.HasImpKillButton() || target.Is(CustomRoles.Lawyer)) - { - target.GetRoleClass()?.OnRemove(target.PlayerId); - target.RpcChangeRoleBasis(CustomRoles.Sidekick); - target.RpcSetCustomRole(CustomRoles.Sidekick); - target.GetRoleClass()?.OnAdd(target.PlayerId); - } - else - { - target.RpcSetCustomRole(CustomRoles.Recruit); - } - AbilityLimit--; - - killer.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Jackal), GetString("GangsterSuccessfullyRecruited"))); - target.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Jackal), GetString("BeRecruitedByJackal"))); - - Utils.NotifyRoles(SpecifySeer: killer, SpecifyTarget: target, ForceLoop: true); - Utils.NotifyRoles(SpecifySeer: target, SpecifyTarget: killer, ForceLoop: true); - - killer.ResetKillCooldown(); - killer.SetKillCooldown(forceAnime: !DisableShieldAnimations.GetBool()); - - target.ResetKillCooldown(); - target.SetKillCooldown(forceAnime: true); - break; - } - - SendSkillRPC(); - if (AbilityLimit < 1) - HudManager.Instance.KillButton.OverrideText($"{GetString("KillButtonText")}"); - - Logger.Info($"{killer.GetNameWithRole().RemoveHtmlTags()} - Recruit limit:{AbilityLimit}", "Jackal"); - - return false; - /* if (target.Is(CustomRoles.Jackal)) return false; if (!CanRecruitSidekick.GetBool() || AbilityLimit < 1) return true; @@ -351,90 +204,24 @@ public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl t Logger.Info($"{killer.GetNameWithRole().RemoveHtmlTags()} - Recruit limit:{AbilityLimit}", "Jackal"); return true; - */ } - // very very Long Dog shit lmao public static bool CanBeSidekick(PlayerControl pc) { - return pc != null && !pc.Is(CustomRoles.Sidekick) && !pc.Is(CustomRoles.Recruit) - && !pc.Is(CustomRoles.Loyal) && !pc.Is(CustomRoles.Admired) && !pc.Is(CustomRoles.Rascal) && !pc.Is(CustomRoles.Madmate) - && !pc.Is(CustomRoles.Charmed) && !pc.Is(CustomRoles.Infected) && !pc.Is(CustomRoles.Paranoia) - && !pc.Is(CustomRoles.Contagious) && pc.GetCustomRole().IsAbleToBeSidekicked() + return pc != null && !pc.Is(CustomRoles.Sidekick) && !pc.Is(CustomRoles.Recruit) + && !pc.Is(CustomRoles.Loyal) && !pc.Is(CustomRoles.Admired) && !pc.Is(CustomRoles.Rascal) && !pc.Is(CustomRoles.Madmate) + && !pc.Is(CustomRoles.Charmed) && !pc.Is(CustomRoles.Infected) && !pc.Is(CustomRoles.Paranoia) + && !pc.Is(CustomRoles.Contagious) && pc.GetCustomRole().IsAbleToBeSidekicked() && !(pc.GetCustomSubRoles().Contains(CustomRoles.Hurried) && !Hurried.CanBeConverted.GetBool()); } - public override void OnMurderPlayerAsTarget(PlayerControl killer, PlayerControl target, bool inMeeting, bool isSuidice) - { - if (!target.Is(CustomRoles.Jackal)) return; - - if (SidekickTurnIntoJackal.GetBool()) - { - Logger.Info("Starting Jackal Death Assign.", "Jackal"); - var readySideKicks = Main.AllAlivePlayerControls.Where(x => x.IsAlive() && x.Is(CustomRoles.Sidekick) && x.PlayerId != target.PlayerId).ToList(); - - if (readySideKicks.Count < 1) - { - readySideKicks = Main.AllAlivePlayerControls.Where(x => x.IsAlive() && x.Is(CustomRoles.Recruit) && x.PlayerId != target.PlayerId).ToList(); - } - - if (readySideKicks.Count < 1) - { - Logger.Info("Jackal dead, but no alive sidekick can be assigned!", "Jackal"); - return; - } - - var newJackal = readySideKicks.RandomElement(); - if (newJackal.IsAlive()) - { - Logger.Info($"Assigned new Jackal {newJackal.GetNameWithRole()}", "Jackal"); - newJackal.GetRoleClass()?.OnRemove(newJackal.PlayerId); - newJackal.RpcChangeRoleBasis(CustomRoles.Jackal); - newJackal.RpcSetCustomRole(CustomRoles.Jackal); - newJackal.GetRoleClass()?.OnAdd(target.PlayerId); - - if (inMeeting) - { - Utils.SendMessage(string.Format(GetString("Jackal_OnBecomeNewJackalMeeting"), target.GetRealName(true)), newJackal.PlayerId); - foreach (var player in Main.AllPlayerControls.Where(x => x.Is(CustomRoles.Recruit) || x.Is(CustomRoles.Sidekick))) - { - if (player.PlayerId == newJackal.PlayerId) continue; - Utils.SendMessage(string.Format(GetString("Jackal_OnNewJackalSelectedMeeting"), target.GetRealName(true), newJackal.GetRealName(true)), player.PlayerId); - } - } - - newJackal.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Jackal), GetString("Jackal_BecomeNewJackal"))); - newJackal.ResetKillCooldown(); - target.SetKillCooldown(forceAnime: true); - - foreach (var player in Main.AllAlivePlayerControls.Where(x => x.Is(CustomRoles.Recruit) || x.Is(CustomRoles.Sidekick))) - { - player.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Jackal), string.Format(GetString("Jackal_OnNewJackalSelected"), newJackal.GetRealName()))); - } - Utils.NotifyRoles(); - } - else - { - Logger.Info($"Selected alive Sidekick [{newJackal.PlayerId}]{newJackal.GetNameWithRole()} is dead? wtf", "Jackal"); - } - } - else - { - Logger.Info("Opps, Jackal boss is dead!", "Jackal"); - foreach (var player in Main.AllAlivePlayerControls.Where(x => x.Is(CustomRoles.Recruit) || x.Is(CustomRoles.Sidekick))) - { - player.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Jackal), GetString("Jackal_BossIsDead"))); - } - Utils.NotifyRoles(); - } - } - private string GetRecruitLimit() - => Utils.ColorString(CanRecruit() + private string GetRecruitLimit(byte playerId) + => Utils.ColorString(CanRecruit(playerId) ? Utils.GetRoleColor(CustomRoles.Jackal).ShadeColor(0.25f) : Color.gray, $"({AbilityLimit})"); - + public override string GetProgressText(byte playerId, bool comms) - => CanRecruitSidekick.GetBool() ? GetRecruitLimit() : ""; + => CanRecruitSidekick.GetBool() ? GetRecruitLimit(playerId) : ""; public override bool CheckMurderOnOthersTarget(PlayerControl killer, PlayerControl target) { @@ -443,6 +230,10 @@ public override bool CheckMurderOnOthersTarget(PlayerControl killer, PlayerContr // Jackal can kill Sidekick/Recruit if (killer.Is(CustomRoles.Jackal) && (target.Is(CustomRoles.Sidekick) || target.Is(CustomRoles.Recruit))) return true; + + // Sidekick/Recruit can kill Jackal + else if ((killer.Is(CustomRoles.Sidekick) || killer.Is(CustomRoles.Recruit)) && target.Is(CustomRoles.Jackal)) + return true; } if (!SidekickCanKillSidekick.GetBool()) @@ -465,56 +256,3 @@ public override bool CheckMurderOnOthersTarget(PlayerControl killer, PlayerContr return false; } } - -internal class Sidekick : RoleBase -{ - public override CustomRoles Role => CustomRoles.Sidekick; - - public override bool IsDesyncRole => true; - public override CustomRoles ThisRoleBase => CustomRoles.Impostor; - public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralKilling; - - public override void Init() - { - - } - public override void Add(byte playerId) - { - - Main.PlayerStates[playerId].taskState.hasTasks = false; - AbilityLimit = 0; - - if (Jackal.RestoreLimitOnNewJackal.GetBool()) - { - AbilityLimit = Jackal.SidekickRecruitLimitOpt.GetInt(); - } - - if (AmongUsClient.Instance.AmHost) - { - SendSkillRPC(); - } - } - public override void SetKillCooldown(byte id) => Main.AllPlayerKillCooldown[id] = Jackal.KillCooldownSK.GetFloat(); - public override void ApplyGameOptions(IGameOptions opt, byte ico) => opt.SetVision(Jackal.HasImpostorVision.GetBool()); - public override bool CanUseKillButton(PlayerControl player) => Jackal.SidekickCanKillWhenJackalAlive.GetBool() || !CustomRoles.Jackal.RoleExist(); - public override bool CanUseImpostorVentButton(PlayerControl player) => Jackal.CanVentSK.GetBool(); - public override bool CanUseSabotage(PlayerControl player) => Jackal.CanUseSabotageSK.GetBool(); - public override string GetProgressText(byte playerId, bool comms) - { - return ""; - } - - //public override bool KnowRoleTarget(PlayerControl seer, PlayerControl target) => SidekickKnowRole(target); - //public override string PlayerKnowTargetColor(PlayerControl seer, PlayerControl target) => SidekickKnowRole(target) ? Main.roleColors[CustomRoles.Jackal] : string.Empty; - - //private static bool SidekickKnowRole(PlayerControl target) - //{ - // return target.Is(CustomRoles.Jackal) || target.Is(CustomRoles.Recruit) || target.Is(CustomRoles.Sidekick); - //} - - public override void SetAbilityButtonText(HudManager hud, byte playerId) - { - hud.KillButton.OverrideText(GetString("KillButtonText")); - hud.SabotageButton.OverrideText(GetString("SabotageButtonText")); - } -} diff --git a/Roles/Neutral/Jester.cs b/Roles/Neutral/Jester.cs index 96bd2f2de..0554c8880 100644 --- a/Roles/Neutral/Jester.cs +++ b/Roles/Neutral/Jester.cs @@ -7,14 +7,11 @@ namespace TOHE.Roles.Neutral; internal class Jester : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Jester; private const int Id = 14400; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Jester); public override CustomRoles ThisRoleBase => CanVent.GetBool() ? CustomRoles.Engineer : CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralEvil; - - public override bool BlockMoveInVent(PlayerControl pc) => CantMoveInVents.GetBool(); //==================================================================\\ private static OptionItem CanUseMeetingButton; @@ -26,6 +23,8 @@ internal class Jester : RoleBase public static OptionItem SunnyboyChance; private static OptionItem RevealJesterUponEjection; + private readonly HashSet RememberBlockedVents = []; + public override void SetupCustomOption() { SetupRoleOptions(Id, TabGroup.NeutralRoles, CustomRoles.Jester); @@ -48,6 +47,10 @@ public override void SetupCustomOption() .SetParent(CustomRoleSpawnChances[CustomRoles.Jester]) .SetValueFormat(OptionFormat.Percent); } + public override void Init() + { + RememberBlockedVents.Clear(); + } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.EngineerCooldown = 1f; @@ -58,6 +61,40 @@ public override void ApplyGameOptions(IGameOptions opt, byte playerId) public override bool HideVote(PlayerVoteArea votedPlayer) => HideJesterVote.GetBool(); public override bool OnCheckStartMeeting(PlayerControl reporter) => CanUseMeetingButton.GetBool(); + public override void OnCoEnterVent(PlayerPhysics physics, int ventId) + { + if (!CantMoveInVents.GetBool()) return; + + var player = physics.myPlayer; + foreach (var vent in ShipStatus.Instance.AllVents) + { + // Skip current vent or ventid 5 in Dleks to prevent stuck + if (vent.Id == ventId || (GameStates.DleksIsActive && ventId is 5 && vent.Id is 6)) continue; + + RememberBlockedVents.Add(vent.Id); + CustomRoleManager.BlockedVentsList[player.PlayerId].Add(vent.Id); + } + player.RpcSetVentInteraction(); + } + public override void OnExitVent(PlayerControl pc, int ventId) + { + ResetBlockedVent(); + } + public override void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo target) + { + ResetBlockedVent(); + } + private void ResetBlockedVent() + { + if (!CantMoveInVents.GetBool() || _Player == null) return; + + foreach (var ventId in RememberBlockedVents) + { + CustomRoleManager.BlockedVentsList[_Player.PlayerId].Remove(ventId); + } + RememberBlockedVents.Clear(); + } + public override void CheckExile(NetworkedPlayerInfo exiled, ref bool DecidedWinner, bool isMeetingHud, ref string name) { if (MeetingsNeededForWin.GetInt() <= Main.MeetingsPassed) diff --git a/Roles/Neutral/Jinx.cs b/Roles/Neutral/Jinx.cs index ef6b7fcc1..2696e6827 100644 --- a/Roles/Neutral/Jinx.cs +++ b/Roles/Neutral/Jinx.cs @@ -1,14 +1,13 @@ using AmongUs.GameOptions; -using TOHE.Roles.Core; using UnityEngine; using static TOHE.Options; +using TOHE.Roles.Core; namespace TOHE.Roles.Neutral; internal class Jinx : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Jinx; private const int Id = 16800; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Jinx); public override bool IsDesyncRole => true; @@ -44,10 +43,10 @@ public override bool OnCheckMurderAsTarget(PlayerControl killer, PlayerControl t if (AbilityLimit <= 0) return true; if (killer.IsTransformedNeutralApocalypse()) return true; if (killer == target) return true; - + killer.RpcGuardAndKill(target); target.RpcGuardAndKill(target); - + AbilityLimit -= 1; SendSkillRPC(); @@ -66,8 +65,8 @@ public override bool OnCheckMurderAsTarget(PlayerControl killer, PlayerControl t public override bool CanUseKillButton(PlayerControl pc) => true; public override bool CanUseImpostorVentButton(PlayerControl player) => CanVent.GetBool(); - public override string GetProgressText(byte playerId, bool comms) + public override string GetProgressText(byte playerId, bool comms) => Utils.ColorString(CanJinx(playerId) ? Utils.GetRoleColor(CustomRoles.Gangster).ShadeColor(0.25f) : Color.gray, $"({AbilityLimit})"); - + private bool CanJinx(byte id) => AbilityLimit > 0; } diff --git a/Roles/Neutral/Juggernaut.cs b/Roles/Neutral/Juggernaut.cs index 477b1b69a..169c22fc5 100644 --- a/Roles/Neutral/Juggernaut.cs +++ b/Roles/Neutral/Juggernaut.cs @@ -7,8 +7,9 @@ namespace TOHE.Roles.Neutral; internal class Juggernaut : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Juggernaut; private const int Id = 16900; + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); public override bool IsDesyncRole => true; public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralKilling; @@ -36,10 +37,12 @@ public override void SetupCustomOption() } public override void Init() { + playerIdList.Clear(); NowCooldown.Clear(); } public override void Add(byte playerId) { + playerIdList.Add(playerId); NowCooldown.TryAdd(playerId, DefaultKillCooldown.GetFloat()); } public override void SetKillCooldown(byte id) => Main.AllPlayerKillCooldown[id] = NowCooldown[id]; @@ -53,4 +56,4 @@ public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl t public override bool CanUseImpostorVentButton(PlayerControl pc) => CanVent.GetBool(); public override bool CanUseKillButton(PlayerControl pc) => true; public override void ApplyGameOptions(IGameOptions opt, byte playerId) => opt.SetVision(HasImpostorVision.GetBool()); -} +} \ No newline at end of file diff --git a/Roles/Neutral/Lawyer.cs b/Roles/Neutral/Lawyer.cs index 1ac3a4929..3023ed0f5 100644 --- a/Roles/Neutral/Lawyer.cs +++ b/Roles/Neutral/Lawyer.cs @@ -10,7 +10,6 @@ namespace TOHE.Roles.Neutral; internal class Lawyer : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Lawyer; private const int Id = 13100; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Lawyer); public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; @@ -30,7 +29,6 @@ internal class Lawyer : RoleBase public static HashSet TargetList = []; private byte TargetId; - [Obfuscation(Exclude = true)] private enum ChangeRolesSelectList { Role_Crewmate, @@ -56,7 +54,7 @@ private enum ChangeRolesSelectList public override void SetupCustomOption() { - SetupSingleRoleOptions(Id, TabGroup.NeutralRoles, CustomRoles.Lawyer); + SetupRoleOptions(Id, TabGroup.NeutralRoles, CustomRoles.Lawyer); CanTargetImpostor = BooleanOptionItem.Create(Id + 10, "LawyerCanTargetImpostor", true, TabGroup.NeutralRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Lawyer]); CanTargetNeutralKiller = BooleanOptionItem.Create(Id + 11, "LawyerCanTargetNeutralKiller", false, TabGroup.NeutralRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Lawyer]); CanTargetNeutralApoc = BooleanOptionItem.Create(Id + 18, "LawyerCanTargetNeutralApocalypse", false, TabGroup.NeutralRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Lawyer]); @@ -127,7 +125,6 @@ public override void Remove(byte playerId) } TargetList.Remove(TargetId); TargetId = byte.MaxValue; - CustomRoleManager.CheckDeadBodyOthers.Remove(OthersAfterPlayerDeathTask); } private void SendRPC(bool SetTarget = false) { @@ -214,4 +211,4 @@ private void ChangeRole(bool inMeeting) Utils.NotifyRoles(SpecifySeer: lawyer); } } -} +} \ No newline at end of file diff --git a/Roles/Neutral/LingeringPresence.cs b/Roles/Neutral/LingeringPresence.cs new file mode 100644 index 000000000..0ab6b8c28 --- /dev/null +++ b/Roles/Neutral/LingeringPresence.cs @@ -0,0 +1,718 @@ +using Hazel; +using Il2CppInterop.Runtime.InteropTypes.Arrays; +using InnerNet; +using System; +using TOHE.Roles.Core; +using UnityEngine; +using UnityEngine.Playables; +using static TOHE.Options; + + +namespace TOHE.Roles.Neutral +{ + internal class LingeringPresence : RoleBase + { + //===========================SETUP================================\\ + private const int Id = 63500; + public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.LingeringPresence); + + public override bool IsExperimental => true; + public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; + public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralBenign; + //==================================================================\\ + + private static OptionItem SoulDrainRange; + private static OptionItem SoulDrainSpeed; + private static OptionItem TaskRechargeAmount; + private static OptionItem KillRechargeAmount; + private static OptionItem WinConditionOption; + public static OptionItem LingeringPresenceShortTasks; + public static OptionItem LingeringPresenceLongTasks; + + + private static CustomWinner SelectedWinCondition; + + private static readonly Dictionary SoulMeters = new(); + private static readonly Dictionary LastUpdateTimes = new(); + private static readonly Dictionary TeamDescriptions = new() +{ + { 0, "Crewmates" }, + { 1, "Neutral" }, + { 2, "Imposter" }, + { 3, "Random" } +}; + + // Method to retrieve the descriptive name + public static string GetWinConditionDescription(int optionValue) + { + return TeamDescriptions.TryGetValue(optionValue, out var description) ? description : "Unknown"; + } +#pragma warning disable IDE0052 // Remove unread private members + private static bool taskResetPatched = false; +#pragma warning restore IDE0052 // Remove unread private members +#pragma warning disable IDE0052 // Remove unread private members + private static string deathReasonMessage = string.Empty; +#pragma warning restore IDE0052 // Remove unread private members + private static bool patched = false; + private static OptionItem SoulDrainTickRate; +#pragma warning disable IDE0052 // Remove unread private members + private static bool IsReviving = false; +#pragma warning restore IDE0052 // Remove unread private members + private byte lingeringPlayerId; + private Dictionary TimeSinceLastTick = new(); + + public override bool HasTasks(NetworkedPlayerInfo player, CustomRoles role, bool ForRecompute) => !ForRecompute; + + public override void SetupCustomOption() + { + SetupRoleOptions(Id, TabGroup.NeutralRoles, CustomRoles.LingeringPresence); + + SoulDrainRange = FloatOptionItem.Create(Id + 10, "SoulDrainRange", new(1f, 10f, 0.5f), 5f, TabGroup.NeutralRoles, false) + .SetParent(CustomRoleSpawnChances[CustomRoles.LingeringPresence]) + .SetValueFormat(OptionFormat.Multiplier); + SoulDrainSpeed = FloatOptionItem.Create(Id + 11, "SoulDrainSpeed", new(1f, 10f, 0.5f), 2f, TabGroup.NeutralRoles, false) + .SetParent(CustomRoleSpawnChances[CustomRoles.LingeringPresence]) + .SetValueFormat(OptionFormat.Seconds); + TaskRechargeAmount = FloatOptionItem.Create(Id + 12, "TaskRechargeAmount", new(1f, 100f, 1f), 25f, TabGroup.NeutralRoles, false) + .SetParent(CustomRoleSpawnChances[CustomRoles.LingeringPresence]) + .SetValueFormat(OptionFormat.Health); + KillRechargeAmount = FloatOptionItem.Create(Id + 13, "KillRechargeAmount", new(1f, 100f, 1f), 50f, TabGroup.NeutralRoles, false) + .SetParent(CustomRoleSpawnChances[CustomRoles.LingeringPresence]) + .SetValueFormat(OptionFormat.Health); + WinConditionOption = StringOptionItem.Create(Id + 20, "Lingering Presence Win Condition", new[] { "Crewmates", "Neutral", "Impostor", "Random" }, 0, TabGroup.NeutralRoles, false) + .SetParent(CustomRoleSpawnChances[CustomRoles.LingeringPresence]); + + + SoulDrainTickRate = FloatOptionItem.Create(Id + 14, "SoulDrainTickRate", new(0.1f, 5f, 0.1f), 1f, TabGroup.NeutralRoles, false) + .SetParent(CustomRoleSpawnChances[CustomRoles.LingeringPresence]) + .SetValueFormat(OptionFormat.Seconds); + OverrideTasksData.Create(Id + 15, TabGroup.NeutralRoles, CustomRoles.LingeringPresence); + + + } + public override void Init() + { + + SoulMeters.Clear(); + LastUpdateTimes.Clear(); + IsReviving = false; + lingeringPlayerId = byte.MaxValue; + taskResetPatched = false; + deathReasonMessage = string.Empty; + SelectedWinCondition = (CustomWinner)WinConditionOption.GetInt(); + if (SelectedWinCondition == CustomWinner.Random) + { + SelectedWinCondition = AssignRandomTeam(); + Logger.Info($"Lingering Presence assigned random team: {SelectedWinCondition}", "LingeringPresence"); + } + + + foreach (var player in PlayerControl.AllPlayerControls) + { + if (player.Is(CustomRoles.LingeringPresence)) + { + KillLingeringPresence(player, player); + } + } + } + + +#pragma warning disable IDE0044 // Add readonly modifier + private Custom_RoleType selectedTeam; +#pragma warning restore IDE0044 // Add readonly modifier + + + public enum TeamOption + { + Crewmates = 0, + Neutral = 1, + Imposter = 2, + Random = 3 + } + private CustomWinner AssignRandomTeam() + { + CustomWinner[] possibleTeams = { CustomWinner.Crewmate, CustomWinner.Impostor, CustomWinner.Neutrals }; + var selectedTeam = possibleTeams[UnityEngine.Random.Range(0, possibleTeams.Length)]; + Logger.Info($"[LingeringPresence] Random team assigned: {selectedTeam}"); + return selectedTeam; + } + + + + + + + + + public static void LingeringPresenceWinCondition(PlayerControl player) + { + var playerState = Main.PlayerStates[player.PlayerId]; + if (!playerState.IsLingeringPresence) + { + Logger.Warn($"[LingeringPresence] {player.GetNameWithRole()} is not Lingering Presence. Skipping win condition check."); + return; + } + + var winCondition = (CustomWinner)WinConditionOption.GetInt(); + + switch (winCondition) + { + case CustomWinner.Crewmate: + if (CustomWinnerHolder.WinnerTeam == CustomWinner.Crewmate) + { + CustomWinnerHolder.WinnerIds.Add(player.PlayerId); + Logger.Info($"[LingeringPresence] {player.GetNameWithRole()} wins with the Crewmate team."); + } + break; + + case CustomWinner.Impostor: + if (CustomWinnerHolder.WinnerTeam == CustomWinner.Impostor) + { + CustomWinnerHolder.WinnerIds.Add(player.PlayerId); + Logger.Info($"[LingeringPresence] {player.GetNameWithRole()} wins with the Impostor team."); + } + break; + + case CustomWinner.Neutrals: + if (IsWinningWithNeutral(player)) + { + CustomWinnerHolder.WinnerIds.Add(player.PlayerId); + Logger.Info($"[LingeringPresence] {player.GetNameWithRole()} wins with the Neutral team."); + } + else + { + Logger.Warn($"[LingeringPresence] {player.GetNameWithRole()} does not meet Neutral win condition."); + } + break; + + + default: + Logger.Warn($"[LingeringPresence] {player.GetNameWithRole()} does not meet any win condition."); + break; + } + } + + + + + + + + public static void OnMeetingCalled() + { + foreach (var player in PlayerControl.AllPlayerControls) + { + if (player.Is(CustomRoles.LingeringPresence) && player.IsAlive()) + { + // Trigger Lingering Presence's custom death mechanics during meetings + if (KillLingeringPresence(PlayerControl.LocalPlayer, player)) + { + // Schedule ResetTasks to be called shortly after death handling completes + new LateTask(() => LingeringPresence.Instance?.ResetTasks(player), 0.5f, "LingeringPresence ResetTasks After Death"); + } + } + } + } + + + + + public override void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo bodyInfo) + { + foreach (var player in PlayerControl.AllPlayerControls) + { + if (player.Is(CustomRoles.LingeringPresence) && player.IsAlive()) + { + // Trigger Lingering Presence's custom death mechanics when a body is reported + KillLingeringPresence(PlayerControl.LocalPlayer, player); + } + } + } + + + public override bool OnCheckMurderAsTarget(PlayerControl killer, PlayerControl target) + { + if (target.Is(CustomRoles.LingeringPresence)) + { + // Ignore protection checks for Lingering Presence + return KillLingeringPresence(killer, target); + } + + return true; // For other roles, proceed with default behavior + } + + + public static bool KillLingeringPresence(PlayerControl killer, PlayerControl target) + { + try + { + if (killer == null || target == null || !target.IsAlive()) return false; + + // Set custom death properties specific to Lingering Presence + target.SetDeathReason(PlayerState.DeathReason.FadedAway); // Customize death reason + target.RpcExileV2(); // Exile without leaving a body + + if (Main.PlayerStates.ContainsKey(target.PlayerId)) + { + Main.PlayerStates[target.PlayerId].SetDead(); + } + + target.Data.IsDead = true; + target.SetRealKiller(killer); + killer.ResetKillCooldown(); + + Logger.Info($"{target.GetNameWithRole()} was killed by {killer?.GetNameWithRole()} due to Lingering Presence mechanics (no body)", "LingeringPresence"); + + // Successfully handled death; return true + return true; + } + catch (Exception ex) + { + Logger.Error($"Error in KillLingeringPresence: {ex.Message}", "LingeringPresence"); + } + + return false; + } + + + + public static void SyncRoleSkillReader(MessageReader reader) + { + try + { + var pc = reader.ReadNetObject(); + + if (pc != null) + { + // Read task-related data directly + pc.GetRoleClass()?.ReceiveRPC(reader, pc); + } + } + catch (Exception error) + { + Logger.Error($"Error in SyncRoleSkillReader RPC: {error}", "SyncRoleSkillReader"); + } + } + + + + + + + + + private string GetWinConditionMessage(CustomWinner winCondition) + { + switch (winCondition) + { + case CustomWinner.Crewmate: return "You win with the Crewmates!"; + case CustomWinner.Impostor: return "You win with the Impostors!"; + case CustomWinner.Neutrals: return "You win with Neutral roles!"; + default: return "Your team will be randomly assigned!"; + } + } + + public override void Add(byte playerId) + { + // Notify Lingering Presence of their team at game start + string teamMessage = GetWinConditionMessage((CustomWinner)WinConditionOption.GetInt()); + Utils.SendMessage(teamMessage, playerId); + + PlayerControl player = null; + + // Locate the PlayerControl object for the given playerId + foreach (var pc in PlayerControl.AllPlayerControls) + { + if (pc.PlayerId == playerId) + { + player = pc; + break; + } + } + + if (player == null) + { + Logger.Error($"Player with ID {playerId} not found for Lingering Presence role.", "LingeringPresence"); + return; + } + + + + // Initialize soul meters for other players + foreach (var pc in PlayerControl.AllPlayerControls) + { + if (!pc.Is(CustomRoles.LingeringPresence)) + { + SoulMeters[pc.PlayerId] = 100f; + } + + + // Reset camera list if necessary + if (!Main.ResetCamPlayerList.Contains(playerId)) + { + Main.ResetCamPlayerList.Add(playerId); + } + + // Only apply OnFixedUpdate for the host + if (AmongUsClient.Instance.AmHost) + { + CustomRoleManager.OnFixedUpdateOthers.Add(OnFixedUpdate); + } + } + } + + + public override bool OnTaskComplete(PlayerControl player, int completedTaskCount, int totalTaskCount) + { + if (player == null) + + // Sync task data for modded clients + SendRPC(); + + if (patched) + { + ResetTasks(player); + patched = false; // Reset patched to prevent repeated task resets + } + // Check if tasks are complete + var taskState = player.GetPlayerTaskState(); + if (taskState.IsTaskFinished && player.Data.IsDead) + { + Logger.Info("Revival conditions met. Attempting to revive Lingering Presence.", "LingeringPresence"); + ReviveLingeringPresence(player); + new LateTask(() => ResetTasks(player), 0.5f, "LingeringPresence ResetTasks"); + + } + + return true; + } + + + + + // Sync task status across clients + private void SendRPC() + { + MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.SyncRoleSkill, SendOption.Reliable, -1); + var player = Utils.GetPlayerById(lingeringPlayerId); + var taskState = player?.GetPlayerTaskState(); + writer.WriteNetObject(player); + writer.Write(taskState?.AllTasksCount ?? 0); + writer.Write(taskState?.CompletedTasksCount ?? 0); + writer.Write(lingeringPlayerId); + + AmongUsClient.Instance.FinishRpcImmediately(writer); + } + + + + + + public override void ReceiveRPC(MessageReader reader, PlayerControl pc) + { + int allTasksCount = reader.ReadInt32(); + int completedTasksCount = reader.ReadInt32(); + byte playerId = reader.ReadByte(); + + var taskState = Utils.GetPlayerById(playerId)?.GetPlayerTaskState(); + if (taskState != null) + { + taskState.AllTasksCount = allTasksCount; + taskState.CompletedTasksCount = completedTasksCount; + } + + Logger.Info($"Lingering Presence tasks synced for player {playerId}: {completedTasksCount}/{allTasksCount} completed.", "LingeringPresence"); + } + + + + + + + + private static void ReviveLingeringPresence(PlayerControl player) + { + if (!player.Data.IsDead) return; + + IsReviving = true; + + // Teleport the player to the spawn position + Vector3 spawnPosition = new Vector3(0, 0, 0); + player.RpcTeleport(spawnPosition); + + // Set the player's role back to LingeringPresence and revive + player.RpcSetRole((AmongUs.GameOptions.RoleTypes)CustomRoles.LingeringPresence); + player.RpcRevive(); + + Logger.Info($"{player.GetNameWithRole()} has been revived at spawn.", "LingeringPresence"); + + + + IsReviving = false; + } + + + + + + public static LingeringPresence Instance { get; private set; } + + public LingeringPresence() + { + Instance = this; + } + private void SetShortTasksToAdd() + { + + } + + // Reset tasks for LingeringPresence upon revival + public void ResetTasks(PlayerControl player) + { + // Ensure additional task-related variables are reset, even if no extra tasks are added + SetShortTasksToAdd(); // Placeholder for consistency; adjust as needed + + var taskState = player.GetPlayerTaskState(); + player.Data.RpcSetTasks(new Il2CppStructArray(0)); // Clear task list to allow reassignment + taskState.CompletedTasksCount = 0; + + // Call necessary functions for resetting visuals and states + player.RpcGuardAndKill(); + player.Notify("Your tasks have been reset!"); + + Logger.Info($"{player.GetRealName()}'s tasks reset.", "LingeringPresence"); + + // Remove any visual indicators + Main.AllPlayerControls.Do(x => TargetArrow.Remove(x.PlayerId, player.PlayerId)); + + // Reset any flags or variables that track state for task warnings or notifications + + + // Sync updated task state across clients, especially for the host + SendRPC(); + } + + + + + + + + + + + private void OnFixedUpdate(PlayerControl player, bool lowLoad, long nowTime) + + { + if (!player.Is(CustomRoles.LingeringPresence) || player.Data.IsDead) return; + + foreach (var target in PlayerControl.AllPlayerControls) + { + if (player.PlayerId == target.PlayerId || target.Data.IsDead) continue; + + var distance = Vector3.Distance(player.transform.position, target.transform.position); + + if (distance <= SoulDrainRange.GetFloat()) + { + DrainSoul(player, target); + } + else + { + ResetSoulDamage(target.PlayerId); + } + } + } + + + + + + private void DrainSoul(PlayerControl presence, PlayerControl target) + { + var currentTime = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); + + if (!LastUpdateTimes.TryGetValue(target.PlayerId, out var lastUpdateTime)) + { + lastUpdateTime = currentTime; + } + + var deltaTime = currentTime - lastUpdateTime; + var drainAmount = SoulDrainSpeed.GetFloat() * deltaTime; + + SoulMeters[target.PlayerId] = Mathf.Clamp(SoulMeters[target.PlayerId] - drainAmount, 0f, 100f); + + ApplyFadingLight(target); + + if (SoulMeters[target.PlayerId] <= 0) + { + target.SetDeathReason(PlayerState.DeathReason.FadedAway); + target.RpcMurderPlayer(target); + } + + LastUpdateTimes[target.PlayerId] = currentTime; + } + + private void ApplyFadingLight(PlayerControl target) + { + Logger.Info($"Updating FadingLight to {target.GetNameWithRole().RemoveHtmlTags()}", "Lingering Presence"); + + target.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.FadingLight), $"Your soul is at {Mathf.RoundToInt(SoulMeters[target.PlayerId])}%")); + target.RpcSetCustomRole(CustomRoles.FadingLight); + } + + private void ResetSoulDamage(byte playerId) + { + LastUpdateTimes.Remove(playerId); + } + + + + public override string GetMarkOthers(PlayerControl seer, PlayerControl target = null, bool isForMeeting = false) + { + if (!seer.Is(CustomRoles.LingeringPresence)) return string.Empty; + + target ??= seer; + + if (SoulMeters.TryGetValue(target.PlayerId, out var soulMeter)) + { + return Utils.ColorString(Color.white, $"Soul: {Mathf.RoundToInt(soulMeter)}%"); + } + + return string.Empty; + } + public override void AfterMeetingTasks() + { + foreach (var player in PlayerControl.AllPlayerControls) + { + if (player.Is(CustomRoles.LingeringPresence) && player.IsAlive()) + { + // Delay the reset to give time for the meeting phase to end completely + new LateTask(() => ResetTasks(player), 0.5f, "LingeringPresence ResetTasks After Meeting"); + } + } + } + + public static void OnOthersTaskComplete(PlayerControl player) + { + // Check if the player has the Fading Light add-on + if (player.HasSpecificSubRole(CustomRoles.FadingLight)) + { + // Get the host-set task recharge amount + float rechargeAmount = TaskRechargeAmount.GetFloat(); + + // Increase soul level and clamp it to a maximum of 100% + SoulMeters[player.PlayerId] = Mathf.Clamp(SoulMeters[player.PlayerId] + rechargeAmount, 0f, 100f); + + // Optionally notify the player of their updated soul level + player.Notify($"Completing a task has increased your soul to {Mathf.RoundToInt(SoulMeters[player.PlayerId])}%."); + } + } + public override bool CheckMurderOnOthersTarget(PlayerControl killer, PlayerControl target) + { + if (killer.HasSpecificSubRole(CustomRoles.FadingLight)) + { + // Retrieve the host-set kill recharge amount + float rechargeAmount = KillRechargeAmount.GetFloat(); + + // Increase the soul level for the killer, capping it at 100% + SoulMeters[killer.PlayerId] = Mathf.Clamp(SoulMeters[killer.PlayerId] + rechargeAmount, 0f, 100f); + + // Optionally notify the killer of their updated soul level + killer.Notify($"Killing a player has increased your soul to {Mathf.RoundToInt(SoulMeters[killer.PlayerId])}%."); + } + + // Proceed with the usual behavior for CheckMurderOnOthersTarget + return base.CheckMurderOnOthersTarget(killer, target); + } + + + + + + + + + + + public override void Remove(byte playerId) + { + SoulMeters.Remove(playerId); + LastUpdateTimes.Remove(playerId); + CustomRoleManager.OnFixedUpdateOthers.Remove(OnFixedUpdate); + } + + + + private static bool IsWinningWithNeutral(PlayerControl player) + { + // Define viable Neutral roles + var viableNeutralRoles = new[] + { + CustomRoles.Agitater, + CustomRoles.Arsonist, + CustomRoles.Baker, + CustomRoles.Bandit, + CustomRoles.Berserker, + CustomRoles. BloodKnight, + CustomRoles.Collector, + CustomRoles.Cultist, + CustomRoles.CursedSoul, + CustomRoles.Death, + CustomRoles.Demon, + CustomRoles.Doomsayer, + CustomRoles.Doppelganger, + CustomRoles.Executioner, + CustomRoles.Famine, + CustomRoles.Glitch, + CustomRoles.God, + CustomRoles.HexMaster, + CustomRoles.Huntsman, + CustomRoles.Infectious, + CustomRoles.Innocent, + CustomRoles.Jackal, + CustomRoles.Jester, + CustomRoles.Jinx, + CustomRoles.Juggernaut, + CustomRoles.Medusa, + CustomRoles.Necromancer, + CustomRoles.Pelican, + CustomRoles.Pestilence, + CustomRoles.Pickpocket, + CustomRoles.Pirate, + CustomRoles.PlagueBearer, + CustomRoles.PlagueDoctor, + CustomRoles.Poisoner, + CustomRoles.PotionMaster, + CustomRoles.Provocateur, + CustomRoles.PunchingBag, + CustomRoles.Pyromaniac, + CustomRoles.Quizmaster, + CustomRoles.Revolutionist, + CustomRoles.RuthlessRomantic, + CustomRoles.Seeker, + CustomRoles.SerialKiller, + CustomRoles.Shroud, + CustomRoles.Sidekick, + CustomRoles.Solsticer, + CustomRoles.SoulCollector, + CustomRoles.Spiritcaller, + CustomRoles.Stalker, + CustomRoles.Terrorist, + CustomRoles.Traitor, + CustomRoles.Troller, + CustomRoles.Vector, + CustomRoles.VengefulRomantic, + CustomRoles.Virus, + CustomRoles.Vulture, + CustomRoles.War, + CustomRoles.Werewolf, + CustomRoles.Workaholic, + CustomRoles.Wraith, + }; + + // Check if the winning team is Neutral and contains a viable role + return CustomWinnerHolder.WinnerTeam == CustomWinner.Neutrals && + CustomWinnerHolder.WinnerRoles.Any(role => viableNeutralRoles.Contains(role)); + } + } +} \ No newline at end of file diff --git a/Roles/Neutral/Maverick.cs b/Roles/Neutral/Maverick.cs index fd0359dbb..ce2b86fc6 100644 --- a/Roles/Neutral/Maverick.cs +++ b/Roles/Neutral/Maverick.cs @@ -8,7 +8,6 @@ namespace TOHE.Roles.Neutral; internal class Maverick : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Maverick; private const int Id = 13200; public static bool HasEnabled = CustomRoleManager.HasEnabled(CustomRoles.Maverick); public override bool IsDesyncRole => true; diff --git a/Roles/Neutral/Medusa.cs b/Roles/Neutral/Medusa.cs index 00fec1016..7cda652c2 100644 --- a/Roles/Neutral/Medusa.cs +++ b/Roles/Neutral/Medusa.cs @@ -1,14 +1,15 @@ using AmongUs.GameOptions; -using static TOHE.Options; using static TOHE.Translator; +using static TOHE.Options; namespace TOHE.Roles.Neutral; internal class Medusa : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Medusa; private const int Id = 17000; + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); public override bool IsDesyncRole => true; public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralKilling; @@ -29,6 +30,14 @@ public override void SetupCustomOption() CanVent = BooleanOptionItem.Create(Id + 11, GeneralOption.CanVent, true, TabGroup.NeutralRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Medusa]); HasImpostorVision = BooleanOptionItem.Create(Id + 13, GeneralOption.ImpostorVision, true, TabGroup.NeutralRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Medusa]); } + public override void Init() + { + playerIdList.Clear(); + } + public override void Add(byte playerId) + { + playerIdList.Add(playerId); + } public override void SetKillCooldown(byte id) => Main.AllPlayerKillCooldown[id] = KillCooldown.GetFloat(); public override void ApplyGameOptions(IGameOptions opt, byte id) => opt.SetVision(HasImpostorVision.GetBool()); public override bool CanUseKillButton(PlayerControl pc) => true; diff --git a/Roles/Neutral/Necromancer.cs b/Roles/Neutral/Necromancer.cs index 2db76add0..9cd89ea42 100644 --- a/Roles/Neutral/Necromancer.cs +++ b/Roles/Neutral/Necromancer.cs @@ -7,8 +7,9 @@ namespace TOHE.Roles.Neutral; internal class Necromancer : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Necromancer; private const int Id = 17100; + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); public override bool IsDesyncRole => true; public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralKilling; @@ -37,6 +38,7 @@ public override void SetupCustomOption() } public override void Init() { + playerIdList.Clear(); IsRevenge = false; Success = false; Killer = null; @@ -44,13 +46,14 @@ public override void Init() } public override void Add(byte playerId) { + playerIdList.Add(playerId); Timer = RevengeTime.GetInt(); } public override void ApplyGameOptions(IGameOptions opt, byte id) => opt.SetVision(HasImpostorVision.GetBool()); public override void SetKillCooldown(byte id) => Main.AllPlayerKillCooldown[id] = KillCooldown.GetFloat(); public override bool CanUseKillButton(PlayerControl pc) => true; public override bool CanUseImpostorVentButton(PlayerControl pc) => CanVent.GetBool(); - + public override bool OnCheckMurderAsTarget(PlayerControl killer, PlayerControl target) { if (IsRevenge) return true; @@ -95,7 +98,7 @@ private static void Countdown(int seconds, PlayerControl player) { Timer = RevengeTime.GetInt(); Success = false; - Killer = null; + Killer = null; return; } if (GameStates.IsMeeting && player.IsAlive()) @@ -109,12 +112,12 @@ private static void Countdown(int seconds, PlayerControl player) Killer = null; return; } - if (seconds <= 0) - { - player.RpcMurderPlayer(player); + if (seconds <= 0) + { + player.RpcMurderPlayer(player); player.SetRealKiller(killer); - Killer = null; - return; + Killer = null; + return; } player.Notify(string.Format(GetString("NecromancerRevenge"), seconds, Killer.GetRealName()), 1.1f); Timer = seconds; diff --git a/Roles/Neutral/Opportunist.cs b/Roles/Neutral/Opportunist.cs index 74605e706..d608d34c0 100644 --- a/Roles/Neutral/Opportunist.cs +++ b/Roles/Neutral/Opportunist.cs @@ -1,42 +1,38 @@ -using AmongUs.GameOptions; -using static TOHE.Options; +using static TOHE.Options; namespace TOHE.Roles.Neutral; internal class Opportunist : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Opportunist; private const int Id = 13300; - public override CustomRoles ThisRoleBase => OpportunistCanUseVent.GetBool() ? CustomRoles.Engineer : CustomRoles.Crewmate; + private static readonly HashSet PlayerIds = []; + public static bool HasEnabled = PlayerIds.Any(); + + public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralBenign; //==================================================================\\ public override bool HasTasks(NetworkedPlayerInfo player, CustomRoles role, bool ForRecompute) => !ForRecompute; public static OptionItem OppoImmuneToAttacksWhenTasksDone; - private static OptionItem OpportunistCanUseVent; - private static OptionItem VentCoolDown; - private static OptionItem VentDuration; public override void SetupCustomOption() { - SetupRoleOptions(Id, TabGroup.NeutralRoles, CustomRoles.Opportunist); - OppoImmuneToAttacksWhenTasksDone = BooleanOptionItem.Create(Id + 10, "ImmuneToAttacksWhenTasksDone", false, TabGroup.NeutralRoles, false) + SetupRoleOptions(13300, TabGroup.NeutralRoles, CustomRoles.Opportunist); + OppoImmuneToAttacksWhenTasksDone = BooleanOptionItem.Create(13302, "ImmuneToAttacksWhenTasksDone", false, TabGroup.NeutralRoles, false) .SetParent(CustomRoleSpawnChances[CustomRoles.Opportunist]); - OpportunistCanUseVent = BooleanOptionItem.Create(Id + 11, GeneralOption.CanVent, true, TabGroup.NeutralRoles, false) - .SetParent(CustomRoleSpawnChances[CustomRoles.Opportunist]); - VentCoolDown = FloatOptionItem.Create(Id + 12, GeneralOption.EngineerBase_VentCooldown, new(0f, 60f, 2.5f), 10f, TabGroup.NeutralRoles, false) - .SetParent(OpportunistCanUseVent); - VentDuration = FloatOptionItem.Create(Id + 13, GeneralOption.EngineerBase_InVentMaxTime, new(0f, 180f, 2.5f), 15f, TabGroup.NeutralRoles, false) - .SetParent(OpportunistCanUseVent); - OverrideTasksData.Create(Id + 20, TabGroup.NeutralRoles, CustomRoles.Opportunist); + OverrideTasksData.Create(13303, TabGroup.NeutralRoles, CustomRoles.Opportunist); + } + public override void Init() + { + PlayerIds.Clear(); } - public override void ApplyGameOptions(IGameOptions opt, byte id) + public override void Add(byte playerId) { - AURoleOptions.EngineerCooldown = VentCoolDown.GetFloat(); - AURoleOptions.EngineerInVentMaxTime = VentDuration.GetFloat(); + PlayerIds.Add(playerId); } + public override bool OnCheckMurderAsTarget(PlayerControl killer, PlayerControl target) => !(OppoImmuneToAttacksWhenTasksDone.GetBool() && target.AllTasksCompleted()); - + } diff --git a/Roles/Neutral/Pelican.cs b/Roles/Neutral/Pelican.cs index e47c760fe..4f0911ae5 100644 --- a/Roles/Neutral/Pelican.cs +++ b/Roles/Neutral/Pelican.cs @@ -14,7 +14,6 @@ namespace TOHE.Roles.Neutral; internal class Pelican : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Pelican; private const int Id = 17300; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Pelican); public override bool IsDesyncRole => true; @@ -232,7 +231,7 @@ private void ReturnEatenPlayerBack(PlayerControl pelican) Vector2 teleportPosition; if (Scavenger.KilledPlayersId.Contains(pelicanId) && PelicanLastPosition.TryGetValue(pelicanId, out var lastPosition)) teleportPosition = lastPosition; - else + else teleportPosition = pelican.GetCustomPosition(); foreach (var tar in eatenList[pelicanId]) @@ -269,9 +268,9 @@ public override void OnFixedUpdate(PlayerControl player, bool lowLoad, long nowT if (lowLoad) return; Count--; - - if (Count > 0) return; - + + if (Count > 0) return; + Count = 4; if (eatenList.TryGetValue(player.PlayerId, out var playerList)) diff --git a/Roles/Neutral/Pickpocket.cs b/Roles/Neutral/Pickpocket.cs index 4b6ff5fa4..494d905af 100644 --- a/Roles/Neutral/Pickpocket.cs +++ b/Roles/Neutral/Pickpocket.cs @@ -8,7 +8,6 @@ namespace TOHE.Roles.Neutral; internal class Pickpocket : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Pickpocket; private const int Id = 17400; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Pickpocket); public override bool IsDesyncRole => true; @@ -65,7 +64,7 @@ public override void OnMurderPlayerAsKiller(PlayerControl killer, PlayerControl if (isSuicide || inMeeting) return; killer.Notify(string.Format(GetString("PickpocketGetVote"), - ((Main.AllPlayerControls.Count(x => x.GetRealKiller()?.PlayerId == killer.PlayerId)) * VotesPerKill.GetFloat() + 1f) + ((Main.AllPlayerControls.Count(x => x.GetRealKiller()?.PlayerId == killer.PlayerId) + 1) * VotesPerKill.GetFloat()) .ToString("0.0#####"))); } } diff --git a/Roles/Neutral/Pirate.cs b/Roles/Neutral/Pirate.cs index ed7dfb398..ba0ee1c0a 100644 --- a/Roles/Neutral/Pirate.cs +++ b/Roles/Neutral/Pirate.cs @@ -13,7 +13,6 @@ namespace TOHE.Roles.Neutral; internal class Pirate : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Pirate; private const int Id = 15000; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Pirate); public override bool IsDesyncRole => true; @@ -68,7 +67,7 @@ public override void OnMeetingHudStart(PlayerControl pc) public override bool CanUseKillButton(PlayerControl pc) => true; public override string GetProgressText(byte playerId, bool comms) => ColorString(GetRoleColor(CustomRoles.Pirate).ShadeColor(0.25f), $"({NumWin}/{SuccessfulDuelsToWin.GetInt()})"); - + public void SendRPC(int operate, byte target = byte.MaxValue, int points = -1) { MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.SyncRoleSkill, SendOption.Reliable, -1); @@ -129,7 +128,7 @@ public override string GetMarkOthers(PlayerControl seer, PlayerControl target, b public override void OnCheckForEndVoting(PlayerState.DeathReason deathReason, params byte[] exileIds) { if (_Player == null || PirateTarget == byte.MaxValue) return; - + var pirateId = _state.PlayerId; if (!DuelDone[pirateId]) return; diff --git a/Roles/Neutral/Pixie.cs b/Roles/Neutral/Pixie.cs index cb16a9b44..dd6afdaa0 100644 --- a/Roles/Neutral/Pixie.cs +++ b/Roles/Neutral/Pixie.cs @@ -8,7 +8,6 @@ namespace TOHE.Roles.Neutral; internal class Pixie : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Pixie; private const int Id = 25900; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Pirate); public override bool IsDesyncRole => true; @@ -58,7 +57,7 @@ public override void Remove(byte playerId) public override bool CanUseKillButton(PlayerControl pc) => true; public override bool CanUseSabotage(PlayerControl pc) => false; public override bool CanUseImpostorVentButton(PlayerControl pc) => false; - + public override void SetAbilityButtonText(HudManager hud, byte playerId) { HudManager.Instance.KillButton.OverrideText(GetString("PixieButtonText")); diff --git a/Roles/Neutral/PlagueBearer.cs b/Roles/Neutral/PlagueBearer.cs index 082400183..a734e2543 100644 --- a/Roles/Neutral/PlagueBearer.cs +++ b/Roles/Neutral/PlagueBearer.cs @@ -1,4 +1,4 @@ -using AmongUs.GameOptions; +using AmongUs.GameOptions; using Hazel; using InnerNet; using TOHE.Roles.Core; @@ -11,7 +11,6 @@ namespace TOHE.Roles.Neutral; internal class PlagueBearer : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.PlagueBearer; private const int Id = 17600; public static readonly HashSet playerIdList = []; public static bool HasEnabled => playerIdList.Any(); @@ -23,11 +22,8 @@ internal class PlagueBearer : RoleBase private static OptionItem PlagueBearerCooldownOpt; public static OptionItem PestilenceCooldownOpt; - private static OptionItem PlagueBearerCanVent; - private static OptionItem PlagueBearerHasImpostorVision; public static OptionItem PestilenceCanVent; public static OptionItem PestilenceHasImpostorVision; - public static OptionItem PestilenceKillsGuessers; private static readonly Dictionary> PlaguedList = []; @@ -44,12 +40,6 @@ public override void SetupCustomOption() .SetParent(CustomRoleSpawnChances[CustomRoles.PlagueBearer]); PestilenceHasImpostorVision = BooleanOptionItem.Create(Id + 13, "PestilenceHasImpostorVision", true, TabGroup.NeutralRoles, false) .SetParent(CustomRoleSpawnChances[CustomRoles.PlagueBearer]); - PlagueBearerCanVent = BooleanOptionItem.Create(Id + 14, "PlagueBearerCanVent", true, TabGroup.NeutralRoles, false) - .SetParent(CustomRoleSpawnChances[CustomRoles.PlagueBearer]); - PlagueBearerHasImpostorVision = BooleanOptionItem.Create(Id + 15, "PlagueBearerHasImpostorVision", true, TabGroup.NeutralRoles, false) - .SetParent(CustomRoleSpawnChances[CustomRoles.PlagueBearer]); - PestilenceKillsGuessers = BooleanOptionItem.Create(Id + 16, "PestilenceKillGuessers", true, TabGroup.NeutralRoles, false) - .SetParent(CustomRoleSpawnChances[CustomRoles.PlagueBearer]); } public override void Init() @@ -59,9 +49,7 @@ public override void Init() } public override void Add(byte playerId) { - if (!playerIdList.Contains(playerId)) - playerIdList.Add(playerId); - + playerIdList.Add(playerId); PlaguedList[playerId] = []; CustomRoleManager.CheckDeadBodyOthers.Add(OnPlayerDead); @@ -72,9 +60,6 @@ public override void Remove(byte playerId) PlaguedList.Remove(playerId); CustomRoleManager.CheckDeadBodyOthers.Remove(OnPlayerDead); } - public override bool CanUseImpostorVentButton(PlayerControl pc) => PlagueBearerCanVent.GetBool(); - public override void ApplyGameOptions(IGameOptions opt, byte playerId) - => opt.SetVision(PlagueBearerHasImpostorVision.GetBool()); public override bool OthersKnowTargetRoleColor(PlayerControl seer, PlayerControl target) => KnowRoleTarget(seer, target); public override bool KnowRoleTarget(PlayerControl seer, PlayerControl target) => (target.IsNeutralApocalypse() && seer.IsNeutralApocalypse()); @@ -82,7 +67,7 @@ public override bool KnowRoleTarget(PlayerControl seer, PlayerControl target) public override void SetKillCooldown(byte id) => Main.AllPlayerKillCooldown[id] = PlagueBearerCooldownOpt.GetFloat(); public override bool CanUseKillButton(PlayerControl pc) => true; private static bool IsPlagued(byte pc, byte target) => PlaguedList.TryGetValue(pc, out var Targets) && Targets.Contains(target); - + public static void SendRPC(PlayerControl player, PlayerControl target) { MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.SyncRoleSkill, SendOption.Reliable); @@ -228,7 +213,7 @@ public override string GetProgressText(byte playerId, bool comms) var (plagued, all) = PlaguedPlayerCount(playerId); return ColorString(GetRoleColor(CustomRoles.PlagueBearer).ShadeColor(0.25f), $"({plagued}/{all})"); } - + public override void SetAbilityButtonText(HudManager hud, byte playerId) { hud.KillButton.OverrideText(GetString("InfectiousKillButtonText")); @@ -238,7 +223,6 @@ public override void SetAbilityButtonText(HudManager hud, byte playerId) internal class Pestilence : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Pestilence; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Pestilence); public override bool IsDesyncRole => true; public override CustomRoles ThisRoleBase => CustomRoles.Impostor; @@ -268,14 +252,10 @@ public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl t public override bool OnRoleGuess(bool isUI, PlayerControl target, PlayerControl pc, CustomRoles role, ref bool guesserSuicide) { - if (PlagueBearer.PestilenceKillsGuessers.GetBool()) - { - if (role != CustomRoles.Pestilence) return false; - pc.ShowInfoMessage(isUI, GetString("GuessPestilence")); + pc.ShowInfoMessage(isUI, GetString("GuessPestilence")); - guesserSuicide = true; - Logger.Msg($"Is Active: {guesserSuicide}", "guesserSuicide - Pestilence"); - } + guesserSuicide = true; + Logger.Msg($"Is Active: {guesserSuicide}", "guesserSuicide - Pestilence"); return false; } -} +} \ No newline at end of file diff --git a/Roles/Neutral/PlagueDoctor.cs b/Roles/Neutral/PlagueDoctor.cs index 047f1b57a..0cd4a9db2 100644 --- a/Roles/Neutral/PlagueDoctor.cs +++ b/Roles/Neutral/PlagueDoctor.cs @@ -13,7 +13,6 @@ namespace TOHE.Roles.Neutral; internal class PlagueDoctor : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.PlagueDoctor; private const int Id = 27600; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.PlagueDoctor); public override bool IsDesyncRole => true; @@ -96,7 +95,7 @@ public override void Add(byte playerId) public override bool CanUseKillButton(PlayerControl pc) => InfectCount != 0; public override string GetProgressText(byte plr, bool coomns) => Utils.ColorString(Utils.GetRoleColor(CustomRoles.PlagueDoctor).ShadeColor(0.25f), $"({InfectCount})"); - + public override void ApplyGameOptions(IGameOptions opt, byte id) => opt.SetVision(false); public override void SetAbilityButtonText(HudManager hud, byte playerId) diff --git a/Roles/Neutral/Poisoner.cs b/Roles/Neutral/Poisoner.cs index 76233fa37..d8b938610 100644 --- a/Roles/Neutral/Poisoner.cs +++ b/Roles/Neutral/Poisoner.cs @@ -1,20 +1,21 @@ using AmongUs.GameOptions; -using TOHE.Roles.AddOns.Common; using UnityEngine; +using TOHE.Roles.AddOns.Common; using static TOHE.Translator; namespace TOHE.Roles.Neutral; internal class Poisoner : RoleBase { - private class PoisonedInfo(byte poisonerId, float killTimer) + private class PoisonedInfo(byte poisonerId, float killTimer) { public byte PoisonerId = poisonerId; public float KillTimer = killTimer; } //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Poisoner; private const int Id = 17500; + public static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); public override bool IsDesyncRole => true; public override CustomRoles ThisRoleBase => CustomRoles.Impostor; @@ -43,10 +44,15 @@ public override void SetupCustomOption() public override void Init() { + playerIdList.Clear(); PoisonedPlayers.Clear(); KillDelay = OptionKillDelay.GetFloat(); } + public override void Add(byte playerId) + { + playerIdList.Add(playerId); + } public override void ApplyGameOptions(IGameOptions opt, byte id) => opt.SetVision(HasImpostorVision.GetBool()); public override void SetKillCooldown(byte id) => Main.AllPlayerKillCooldown[id] = KillCooldown.GetFloat(); public override bool CanUseKillButton(PlayerControl pc) => true; diff --git a/Roles/Neutral/PotionMaster.cs b/Roles/Neutral/PotionMaster.cs index 030ee61a6..db55f619a 100644 --- a/Roles/Neutral/PotionMaster.cs +++ b/Roles/Neutral/PotionMaster.cs @@ -10,7 +10,6 @@ namespace TOHE.Roles.Neutral; internal class PotionMaster : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.PotionMaster; private const int Id = 17700; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.PotionMaster); public override bool IsDesyncRole => true; @@ -62,8 +61,8 @@ public override void ReceiveRPC(MessageReader reader, PlayerControl NaN) byte playerId = reader.ReadByte(); AbilityLimit = reader.ReadSingle(); - RitualTarget[playerId].Add(reader.ReadByte()); - + RitualTarget[playerId].Add(reader.ReadByte()); + } public override void ApplyGameOptions(IGameOptions opt, byte id) => opt.SetVision(HasImpostorVision.GetBool()); public override void SetKillCooldown(byte id) => Main.AllPlayerKillCooldown[id] = KillCooldown.GetFloat(); @@ -116,4 +115,4 @@ public override bool OthersKnowTargetRoleColor(PlayerControl seer, PlayerControl => KnowRoleTarget(seer, target); public override string GetProgressText(byte playerId, bool coooonms) => Utils.ColorString(AbilityLimit > 0 ? Utils.GetRoleColor(CustomRoles.PotionMaster).ShadeColor(0.25f) : Color.gray, $"({AbilityLimit})"); -} +} \ No newline at end of file diff --git a/Roles/Neutral/Provocateur.cs b/Roles/Neutral/Provocateur.cs index d23f6cc46..8e11cf233 100644 --- a/Roles/Neutral/Provocateur.cs +++ b/Roles/Neutral/Provocateur.cs @@ -7,8 +7,10 @@ namespace TOHE.Roles.Neutral; internal class Provocateur : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Provocateur; private const int Id = 15100; + private static readonly HashSet Playerids = []; + public static bool HasEnabled => Playerids.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralChaos; //==================================================================\\ @@ -26,8 +28,13 @@ public override void SetupCustomOption() } public override void Init() { + Playerids.Clear(); Provoked.Clear(); } + public override void Add(byte playerId) + { + Playerids.Add(playerId); + } public override void SetKillCooldown(byte id) => Main.AllPlayerKillCooldown[id] = ProvKillCD.GetFloat(); public override bool CanUseKillButton(PlayerControl pc) => true; public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) diff --git a/Roles/Neutral/PunchingBag.cs b/Roles/Neutral/PunchingBag.cs index 95f7fe758..e6c02cf01 100644 --- a/Roles/Neutral/PunchingBag.cs +++ b/Roles/Neutral/PunchingBag.cs @@ -1,23 +1,24 @@ using Hazel; using InnerNet; using static TOHE.Options; -using static TOHE.Translator; using static TOHE.Utils; +using static TOHE.Translator; namespace TOHE.Roles.Neutral; internal class PunchingBag : RoleBase// bad roll, plz don't use this hosts { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.PunchingBag; private const int Id = 14500; - + private static readonly HashSet PlayerIds = []; + public static bool HasEnabled => PlayerIds.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralEvil; //==================================================================\\ private static OptionItem PunchingBagKillMax; - + private readonly Dictionary PunchingBagMax = []; private readonly HashSet BlockGuess = []; @@ -30,11 +31,13 @@ public override void SetupCustomOption() } public override void Init() { + PlayerIds.Clear(); PunchingBagMax.Clear(); BlockGuess.Clear(); } public override void Add(byte playerId) { + PlayerIds.Add(playerId); PunchingBagMax.Add(playerId, 0); } @@ -56,7 +59,7 @@ public override void ReceiveRPC(MessageReader reader, PlayerControl pc) public override string GetProgressText(byte playerId, bool comms) => ColorString(GetRoleColor(CustomRoles.PunchingBag).ShadeColor(0.25f), $"({(PunchingBagMax.TryGetValue(playerId, out var count) ? count : 0)}/{PunchingBagKillMax.GetInt()})"); - + public override bool OnCheckMurderAsTarget(PlayerControl killer, PlayerControl target) { killer.SetKillCooldown(target: target, forceAnime: true); @@ -70,7 +73,6 @@ public override bool OnCheckMurderAsTarget(PlayerControl killer, PlayerControl t } public override bool OnRoleGuess(bool isUI, PlayerControl target, PlayerControl pc, CustomRoles role, ref bool guesserSuicide) { - if (role != CustomRoles.PunchingBag) return false; if (BlockGuess.Contains(pc.PlayerId)) { pc.ShowInfoMessage(isUI, GetString("GuessPunchingBagAgain")); @@ -89,7 +91,7 @@ public override bool OnRoleGuess(bool isUI, PlayerControl target, PlayerControl private void CheckWin() { var punchingBagId = _Player.PlayerId; - + if (PunchingBagMax[punchingBagId] >= PunchingBagKillMax.GetInt()) { if (!CustomWinnerHolder.CheckForConvertedWinner(punchingBagId)) diff --git a/Roles/Neutral/Pursuer.cs b/Roles/Neutral/Pursuer.cs index 6907bc471..76a9b77f9 100644 --- a/Roles/Neutral/Pursuer.cs +++ b/Roles/Neutral/Pursuer.cs @@ -1,15 +1,14 @@ using AmongUs.GameOptions; -using TOHE.Modules; -using TOHE.Roles.Core; using UnityEngine; +using TOHE.Modules; using static TOHE.Translator; +using TOHE.Roles.Core; namespace TOHE.Roles.Neutral; internal class Pursuer : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Pursuer; private const int Id = 13400; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Pursuer); public override bool IsDesyncRole => true; @@ -40,7 +39,7 @@ public override void Add(byte playerId) AbilityLimit = PursuerSkillLimitTimes.GetInt(); } public override bool CanUseKillButton(PlayerControl pc) => CanUseKillButton(pc.PlayerId); - + public bool CanUseKillButton(byte playerId) => !Main.PlayerStates[playerId].IsDead && AbilityLimit >= 1; @@ -61,10 +60,10 @@ public override bool OnCheckMurderAsKiller(PlayerControl pc, PlayerControl targe AbilityLimit--; SendSkillRPC(); - if (target.Is(CustomRoles.KillingMachine)) + if (target.Is(CustomRoles.KillingMachine)) { Logger.Info("target is Killing Machine, ability used count reduced, but target will not die", "Purser"); - return false; + return false; } clientList.Add(target.PlayerId); @@ -84,13 +83,13 @@ public override bool OnCheckMurderAsKiller(PlayerControl pc, PlayerControl targe public override bool CheckMurderOnOthersTarget(PlayerControl pc, PlayerControl _) // Target of Pursuer attempt to murder someone { if (!IsClient(pc.PlayerId) || notActiveList.Contains(pc.PlayerId)) return false; - + byte cfId = byte.MaxValue; foreach (var cf in clientList) if (cf == pc.PlayerId) cfId = cf; - + if (cfId == byte.MaxValue) return false; - + var killer = Utils.GetPlayerById(cfId); var target = pc; if (killer == null) return false; @@ -107,4 +106,4 @@ public override void SetAbilityButtonText(HudManager hud, byte playerId) hud.KillButton.OverrideText(GetString("PursuerButtonText")); } public override Sprite GetKillButtonSprite(PlayerControl player, bool shapeshifting) => CustomButton.Get("Pursuer"); -} +} \ No newline at end of file diff --git a/Roles/Neutral/Pyromaniac.cs b/Roles/Neutral/Pyromaniac.cs index a9eaa9f79..2cb963458 100644 --- a/Roles/Neutral/Pyromaniac.cs +++ b/Roles/Neutral/Pyromaniac.cs @@ -7,8 +7,9 @@ namespace TOHE.Roles.Neutral; internal class Pyromaniac : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Pyromaniac; private const int Id = 17800; + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); public override bool IsDesyncRole => true; public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralKilling; @@ -36,10 +37,13 @@ public override void SetupCustomOption() } public override void Init() { + playerIdList.Clear(); DousedList.Clear(); } public override void Add(byte playerId) { + playerIdList.Add(playerId); + // Double Trigger var pc = Utils.GetPlayerById(playerId); pc.AddDoubleTrigger(); @@ -64,8 +68,8 @@ public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl t } else { - return killer.CheckDoubleTrigger(target, () => - { + return killer.CheckDoubleTrigger(target, () => + { DousedList.Add(target.PlayerId); killer.SetKillCooldown(DouseCooldown.GetFloat()); Utils.NotifyRoles(SpecifySeer: killer, SpecifyTarget: target); diff --git a/Roles/Neutral/Quizmaster.cs b/Roles/Neutral/Quizmaster.cs index ced2045e6..5e8dbac1f 100644 --- a/Roles/Neutral/Quizmaster.cs +++ b/Roles/Neutral/Quizmaster.cs @@ -1,11 +1,11 @@ using Hazel; -using InnerNet; using System; +using InnerNet; using TOHE.Modules; using TOHE.Roles.Core; -using static TOHE.MeetingHudStartPatch; using static TOHE.Options; using static TOHE.Translator; +using static TOHE.MeetingHudStartPatch; namespace TOHE.Roles.Neutral; @@ -13,7 +13,6 @@ namespace TOHE.Roles.Neutral; internal class Quizmaster : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Quizmaster; private const int Id = 27000; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Quizmaster); public override bool IsExperimental => true; @@ -131,7 +130,7 @@ public override void ReceiveRPC(MessageReader reader, PlayerControl NaN) public override bool CanUseImpostorVentButton(PlayerControl pc) { if (pc == null || !pc.IsAlive()) return false; - + bool canVent = false; if (CanVentAfterMark.GetBool() && MarkedPlayer != byte.MaxValue) { @@ -227,35 +226,38 @@ private void DoQuestion() Player = _Player; if (MarkedPlayer != byte.MaxValue) { + // Get random roles CustomRoles randomRole = GetRandomRole([.. CustomRolesHelper.AllRoles], false); CustomRoles randomRoleWithAddon = GetRandomRole([.. CustomRolesHelper.AllRoles], false); List Questions = [ new SabotageQuestion { Stage = 1, Question = "LastSabotage",/* JSON ENTRIES */ QuizmasterQuestionType = QuizmasterQuestionType.LatestSabotageQuestion }, - new SabotageQuestion { Stage = 1, Question = "FirstRoundSabotage", QuizmasterQuestionType = QuizmasterQuestionType.FirstRoundSabotageQuestion }, - new PlrColorQuestion { Stage = 1, Question = "LastEjectedPlayerColor", QuizmasterQuestionType = QuizmasterQuestionType.EjectionColorQuestion }, - new PlrColorQuestion { Stage = 1, Question = "LastReportPlayerColor", QuizmasterQuestionType = QuizmasterQuestionType.ReportColorQuestion }, - new PlrColorQuestion { Stage = 1, Question = "LastButtonPressedPlayerColor", QuizmasterQuestionType = QuizmasterQuestionType.LastMeetingColorQuestion }, + new SabotageQuestion { Stage = 1, Question = "FirstRoundSabotage", QuizmasterQuestionType = QuizmasterQuestionType.FirstRoundSabotageQuestion }, + new PlrColorQuestion { Stage = 1, Question = "LastEjectedPlayerColor", QuizmasterQuestionType = QuizmasterQuestionType.EjectionColorQuestion }, + new PlrColorQuestion { Stage = 1, Question = "LastReportPlayerColor", QuizmasterQuestionType = QuizmasterQuestionType.ReportColorQuestion }, + new PlrColorQuestion { Stage = 1, Question = "LastButtonPressedPlayerColor", QuizmasterQuestionType = QuizmasterQuestionType.LastMeetingColorQuestion }, - new CountQuestion { Stage = 2, Question = "MeetingPassed", QuizmasterQuestionType = QuizmasterQuestionType.MeetingCountQuestion }, + new CountQuestion { Stage = 2, Question = "MeetingPassed", QuizmasterQuestionType = QuizmasterQuestionType.MeetingCountQuestion }, new SetAnswersQuestion { Stage = 2, Question = "HowManyFactions", Answer = "Three", PossibleAnswers = { "One", "Two", "Three", "Four", "Five" }, QuizmasterQuestionType = QuizmasterQuestionType.FactionQuestion }, new SetAnswersQuestion { Stage = 2, Question = GetString("QuizmasterQuestions.BasisOfRole").Replace("{QMROLE}", randomRoleWithAddon.ToString()), HasQuestionTranslation = false, Answer = CustomRolesHelper.GetCustomRoleTeam(randomRoleWithAddon).ToString(), PossibleAnswers = { "Crewmate", "Impostor", "Neutral", "Addon" }, QuizmasterQuestionType = QuizmasterQuestionType.RoleBasisQuestion }, new SetAnswersQuestion { Stage = 2, Question = GetString("QuizmasterQuestions.FactionOfRole").Replace("{QMROLE}", randomRole.ToString()), HasQuestionTranslation = false, Answer = CustomRolesHelper.GetRoleTypes(randomRole).ToString(), PossibleAnswers = { "Crewmate", "Impostor", "Neutral" }, QuizmasterQuestionType = QuizmasterQuestionType.RoleFactionQuestion }, - new SetAnswersQuestion { Stage = 3, Question = "FactionRemovedName", Answer = "Coven", PossibleAnswers = { "Sabotuer", "Sorcerers", "Coven", "Killer" }, QuizmasterQuestionType = QuizmasterQuestionType.RemovedFactionQuestion }, - new SetAnswersQuestion { Stage = 3, Question = "WhatDoesEOgMeansInName", Answer = "Edited", PossibleAnswers = { "Edition", "Experimental", "Enhanced", "Edited" }, QuizmasterQuestionType = QuizmasterQuestionType.NameOriginQuestion }, - new CountQuestion { Stage = 3, Question = "HowManyDiedFirstRound", QuizmasterQuestionType = QuizmasterQuestionType.DiedFirstRoundCountQuestion }, - new CountQuestion { Stage = 3, Question = "ButtonPressedBefore", QuizmasterQuestionType = QuizmasterQuestionType.ButtonPressedBeforeThisQuestion }, + new SetAnswersQuestion { Stage = 3, Question = "FactionRemovedName", Answer = "Coven", PossibleAnswers = { "Sabotuer", "Sorcerers", "Coven", "Killer" }, QuizmasterQuestionType = QuizmasterQuestionType.RemovedFactionQuestion }, + new SetAnswersQuestion { Stage = 3, Question = "WhatDoesEOgMeansInName", Answer = "Edited", PossibleAnswers = { "Edition", "Experimental", "Enhanced", "Edited" }, QuizmasterQuestionType = QuizmasterQuestionType.NameOriginQuestion }, + new CountQuestion { Stage = 3, Question = "HowManyDiedFirstRound", QuizmasterQuestionType = QuizmasterQuestionType.DiedFirstRoundCountQuestion }, + new CountQuestion { Stage = 3, Question = "ButtonPressedBefore", QuizmasterQuestionType = QuizmasterQuestionType.ButtonPressedBeforeThisQuestion }, new DeathReasonQuestion { Stage = 4, Question = "PlrDieReason", QuizmasterQuestionType = QuizmasterQuestionType.PlrDeathReasonQuestion}, new DeathReasonQuestion { Stage = 4, Question = "PlrDieMethod", QuizmasterQuestionType = QuizmasterQuestionType.PlrDeathMethodQuestion}, - new SetAnswersQuestion { Stage = 4, Question = "LastAddedRoleForKarped", Answer = "Pacifist", PossibleAnswers = { "Pacifist", "Vampire", "Snitch", "Vigilante", "Jackal", "Mole", "Sniper" }, QuizmasterQuestionType = QuizmasterQuestionType.RoleAddedQuestion }, + new SetAnswersQuestion { Stage = 4, Question = "LastAddedRoleForKarped", Answer = "Pacifist", PossibleAnswers = { "Pacifist", "Vampire", "Snitch", "Vigilante", "Jackal", "Mole", "Sniper" }, QuizmasterQuestionType = QuizmasterQuestionType.RoleAddedQuestion }, new DeathReasonQuestion { Stage = 4, Question = "PlrDieFaction", QuizmasterQuestionType = QuizmasterQuestionType.PlrDeathKillerFactionQuestion}, ]; + // Randomize the question Question = GetRandomQuestion(Questions); } } + public override void OnMeetingHudStart(PlayerControl pc) { if (Player == null) return; @@ -330,7 +332,7 @@ public override string GetMark(PlayerControl seer, PlayerControl target = null, public override string GetMarkOthers(PlayerControl seer, PlayerControl target, bool isForMeeting = false) => (isForMeeting && MarkedPlayer == target.PlayerId) ? Utils.ColorString(Utils.GetRoleColor(CustomRoles.Quizmaster), " ?!") : string.Empty; - + public static void OnSabotageCall(SystemTypes systemType) { @@ -432,17 +434,17 @@ public static void AnswerByChat(PlayerControl plr, string[] args) } else { - Utils.SendMessage(GetString("QuizmasterChat.AnswerNotValid"), plr.PlayerId, GetString("QuizmasterChat.Title")); + Utils.SendMessage(GetString("QuizmasterAnswerNotValid"), plr.PlayerId, GetString("QuizmasterChat.Title")); } } else { - Utils.SendMessage(GetString("QuizmasterChat.SyntaxNotValid"), plr.PlayerId, GetString("QuizmasterChat.Title")); + Utils.SendMessage(GetString("QuizmasterSyntaxNotValid"), plr.PlayerId, GetString("QuizmasterChat.Title")); } } else if (plr.GetCustomRole() is CustomRoles.Quizmaster) { - Utils.SendMessage(GetString("QuizmasterChat.CantAnswer"), plr.PlayerId, GetString("QuizmasterChat.Title")); + Utils.SendMessage(GetString("QuizmasterCantAnswer"), plr.PlayerId, GetString("QuizmasterChat.Title")); } } @@ -462,7 +464,7 @@ abstract public class QuizQuestionBase public int Stage { get; set; } public QuizmasterQuestionType QuizmasterQuestionType { get; set; } - public string Question { get; set; } + public string Question { get; set; } public string Answer { get; set; } public string AnswerLetter { get; set; } public List Answers { get; set; } @@ -481,7 +483,7 @@ public override void FixUnsetAnswers() foreach (PlayerControl plr in Main.AllPlayerControls) { - if (!PossibleAnswers.Contains(plr.Data.GetPlayerColorString())) + if (!PossibleAnswers.Contains(plr.Data.GetPlayerColorString())) PossibleAnswers.Add(plr.Data.GetPlayerColorString()); } @@ -742,7 +744,6 @@ public override void FixUnsetAnswers() } } -[Obfuscation(Exclude = true)] public enum QuizmasterQuestionType { FirstRoundSabotageQuestion, @@ -764,7 +765,6 @@ public enum QuizmasterQuestionType PlrDeathKillerFactionQuestion, } -[Obfuscation(Exclude = true)] public enum Sabotages { None = -1, @@ -774,4 +774,4 @@ public enum Sabotages O2, Communications, MushroomMixup -} +} \ No newline at end of file diff --git a/Roles/Neutral/Revolutionist.cs b/Roles/Neutral/Revolutionist.cs index dc9df1a8a..9e5113309 100644 --- a/Roles/Neutral/Revolutionist.cs +++ b/Roles/Neutral/Revolutionist.cs @@ -1,19 +1,21 @@ -using AmongUs.GameOptions; -using Hazel; -using TOHE.Roles.AddOns.Common; -using TOHE.Roles.Core; +using Hazel; +using AmongUs.GameOptions; using UnityEngine; +using TOHE.Roles.Core; +using TOHE.Roles.AddOns.Common; using static TOHE.Options; -using static TOHE.Translator; using static TOHE.Utils; +using static TOHE.Translator; namespace TOHE.Roles.Neutral; internal class Revolutionist : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Revolutionist; private const int Id = 15200; + private static readonly HashSet PlayerIds = []; + public static bool HasEnabled => PlayerIds.Any(); + public override bool IsDesyncRole => true; public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralChaos; @@ -61,20 +63,19 @@ public override void Init() RevolutionistLastTime.Clear(); RevolutionistCountdown.Clear(); CurrentDrawTarget = byte.MaxValue; + + PlayerIds.Clear(); } public override void Add(byte playerId) { + PlayerIds.Add(playerId); + CustomRoleManager.OnFixedUpdateOthers.Add(OnFixUpdateOthers); CustomRoleManager.CheckDeadBodyOthers.Add(CheckDeadBody); foreach (var ar in Main.AllPlayerControls) IsDraw.Add((playerId, ar.PlayerId), false); } - public override void Remove(byte playerId) - { - CustomRoleManager.OnFixedUpdateOthers.Remove(OnFixUpdateOthers); - CustomRoleManager.CheckDeadBodyOthers.Remove(CheckDeadBody); - } public override void SetKillCooldown(byte id) => Main.AllPlayerKillCooldown[id] = RevolutionistCooldown.GetFloat(); public override string GetProgressText(byte playerId, bool comms) diff --git a/Roles/Neutral/Romantic.cs b/Roles/Neutral/Romantic.cs index 11c01d2e4..360c75d56 100644 --- a/Roles/Neutral/Romantic.cs +++ b/Roles/Neutral/Romantic.cs @@ -13,7 +13,6 @@ namespace TOHE.Roles.Neutral; internal class Romantic : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Romantic; private const int Id = 13500; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Romantic); public override bool IsDesyncRole => true; @@ -175,7 +174,7 @@ public override bool ForcedCheckMurderAsKiller(PlayerControl killer, PlayerContr killer.RPCPlayCustomSound("Shield"); killer.Notify(GetString("RomanticProtectPartner")); tpc.Notify(GetString("RomanticIsProtectingYou")); - + _ = new LateTask(() => { if (!GameStates.IsInTask || !tpc.IsAlive()) return; @@ -196,7 +195,7 @@ public override bool CheckMurderOnOthersTarget(PlayerControl killer, PlayerContr public override string GetMark(PlayerControl seer, PlayerControl seen, bool isForMeeting = false) { - if (seer == seen) return string.Empty; + if (seer == seen) return string.Empty; return BetPlayer.ContainsValue(seen.PlayerId) ? Utils.ColorString(Utils.GetRoleColor(CustomRoles.Romantic), "♥") : string.Empty; @@ -265,9 +264,7 @@ private static void ChangeRole(PlayerControl player) if (player.GetCustomRole().IsImpostorTeamV3()) { Logger.Info($"Impostor Romantic Partner Died changing {pc.GetNameWithRole()} to Refugee", "Romantic"); - pc.GetRoleClass()?.OnRemove(pc.PlayerId); pc.RpcSetCustomRole(CustomRoles.Refugee); - pc.GetRoleClass()?.OnAdd(pc.PlayerId); Utils.NotifyRoles(ForceLoop: true); pc.ResetKillCooldown(); pc.SetKillCooldown(); @@ -314,7 +311,7 @@ internal class VengefulRomantic : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.VengefulRomantic; + public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Romantic); public override bool IsDesyncRole => new Romantic().IsDesyncRole; public override CustomRoles ThisRoleBase => new Romantic().ThisRoleBase; public override Custom_RoleType ThisRoleType => new Romantic().ThisRoleType; @@ -381,18 +378,20 @@ public override void ReceiveRPC(MessageReader reader, PlayerControl NaN) internal class RuthlessRomantic : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.RuthlessRomantic; + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); + public override bool IsDesyncRole => new Romantic().IsDesyncRole; public override CustomRoles ThisRoleBase => new Romantic().ThisRoleBase; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralKilling; //==================================================================\\ public override void Init() { - + playerIdList.Clear(); } public override void Add(byte playerId) { - + playerIdList.Add(playerId); } public override void SetKillCooldown(byte id) => Main.AllPlayerKillCooldown[id] = Romantic.RuthlessKCD.GetFloat(); public override bool CanUseKillButton(PlayerControl pc) => true; diff --git a/Roles/Neutral/SchrodingersCat.cs b/Roles/Neutral/SchrodingersCat.cs index ab5097bf9..e70e37888 100644 --- a/Roles/Neutral/SchrodingersCat.cs +++ b/Roles/Neutral/SchrodingersCat.cs @@ -8,7 +8,6 @@ namespace TOHE.Roles.Neutral; internal class SchrodingersCat : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.SchrodingersCat; private const int Id = 6900; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.SchrodingersCat); public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; diff --git a/Roles/Neutral/Seeker.cs b/Roles/Neutral/Seeker.cs index 9331a7bcd..e0cdc3650 100644 --- a/Roles/Neutral/Seeker.cs +++ b/Roles/Neutral/Seeker.cs @@ -8,7 +8,6 @@ namespace TOHE.Roles.Neutral; internal class Seeker : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Seeker; private const int Id = 14600; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Seeker); public override bool IsDesyncRole => true; @@ -110,7 +109,7 @@ public override bool ForcedCheckMurderAsKiller(PlayerControl killer, PlayerContr } public override void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo target) { - Main.AllPlayerSpeed[_state.PlayerId] = DefaultSpeed[_state.PlayerId]; + Main.AllPlayerSpeed[_state.PlayerId] = DefaultSpeed[_state.PlayerId]; } public override void OnFixedUpdate(PlayerControl player, bool lowLoad, long nowTime) @@ -127,7 +126,7 @@ public override void OnFixedUpdate(PlayerControl player, bool lowLoad, long nowT { ResetTarget(player); } - + if (totalPoints >= PointsToWinOpt) { TotalPoints[seekerId] = PointsToWinOpt; @@ -144,7 +143,7 @@ private byte GetTarget(PlayerControl player) if (!Targets.TryGetValue(player.PlayerId, out var targetId)) targetId = ResetTarget(player); - + return targetId; } private static void FreezeSeeker(PlayerControl player) diff --git a/Roles/Neutral/SerialKiller.cs b/Roles/Neutral/SerialKiller.cs index 70cecdf54..1ed578f98 100644 --- a/Roles/Neutral/SerialKiller.cs +++ b/Roles/Neutral/SerialKiller.cs @@ -6,8 +6,10 @@ namespace TOHE.Roles.Neutral; internal class SerialKiller : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.SerialKiller; private const int Id = 17900; + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); + public override bool IsDesyncRole => true; public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralKilling; @@ -31,6 +33,14 @@ public override void SetupCustomOption() // .SetParent(HasSerialKillerBuddy) // .SetValueFormat(OptionFormat.Percent); } + public override void Init() + { + playerIdList.Clear(); + } + public override void Add(byte playerId) + { + playerIdList.Add(playerId); + } public override void SetKillCooldown(byte id) => Main.AllPlayerKillCooldown[id] = KillCooldown.GetFloat(); public override void ApplyGameOptions(IGameOptions opt, byte id) => opt.SetVision(HasImpostorVision.GetBool()); public override bool CanUseKillButton(PlayerControl pc) => true; diff --git a/Roles/Neutral/Shaman.cs b/Roles/Neutral/Shaman.cs index 6b97cce63..e161e5737 100644 --- a/Roles/Neutral/Shaman.cs +++ b/Roles/Neutral/Shaman.cs @@ -1,13 +1,12 @@ -using TOHE.Roles.Core; +using static TOHE.Translator; using static TOHE.Options; -using static TOHE.Translator; +using TOHE.Roles.Core; namespace TOHE.Roles.Neutral; internal class Shaman : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Shaman; private const int Id = 13600; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Shaman); public override bool IsDesyncRole => true; @@ -74,5 +73,5 @@ public override bool ForcedCheckMurderAsKiller(PlayerControl killer, PlayerContr } private PlayerControl ChangeTarget(PlayerControl target) => target.IsAlive() && ShamanTargetChoosen ? Utils.GetPlayerById(ShamanTarget) : target; - + } diff --git a/Roles/Neutral/Shroud.cs b/Roles/Neutral/Shroud.cs index d1409b2ae..8863610b7 100644 --- a/Roles/Neutral/Shroud.cs +++ b/Roles/Neutral/Shroud.cs @@ -13,7 +13,6 @@ namespace TOHE.Roles.Neutral; internal class Shroud : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Shroud; private const int Id = 18000; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Shroud); public override bool IsDesyncRole => true; diff --git a/Roles/Neutral/Sidekick.cs b/Roles/Neutral/Sidekick.cs new file mode 100644 index 000000000..d20543bb0 --- /dev/null +++ b/Roles/Neutral/Sidekick.cs @@ -0,0 +1,41 @@ +using AmongUs.GameOptions; + +namespace TOHE.Roles.Neutral; + +internal class Sidekick : RoleBase +{ + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); + public override bool IsDesyncRole => true; + public override CustomRoles ThisRoleBase => CustomRoles.Impostor; + public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralKilling; + + public override void Init() + { + playerIdList.Clear(); + } + public override void Add(byte playerId) + { + playerIdList.Add(playerId); + } + public override void SetKillCooldown(byte id) => Main.AllPlayerKillCooldown[id] = Jackal.KillCooldownSK.GetFloat(); + public override void ApplyGameOptions(IGameOptions opt, byte ico) => opt.SetVision(Jackal.HasImpostorVision.GetBool()); + + public override bool CanUseKillButton(PlayerControl player) => true; + public override bool CanUseImpostorVentButton(PlayerControl player) => Jackal.CanVentSK.GetBool(); + public override bool CanUseSabotage(PlayerControl player) => Jackal.CanUseSabotageSK.GetBool(); + + //public override bool KnowRoleTarget(PlayerControl seer, PlayerControl target) => SidekickKnowRole(target); + //public override string PlayerKnowTargetColor(PlayerControl seer, PlayerControl target) => SidekickKnowRole(target) ? Main.roleColors[CustomRoles.Jackal] : string.Empty; + + //private static bool SidekickKnowRole(PlayerControl target) + //{ + // return target.Is(CustomRoles.Jackal) || target.Is(CustomRoles.Recruit) || target.Is(CustomRoles.Sidekick); + //} + + public override void SetAbilityButtonText(HudManager hud, byte playerId) + { + hud.KillButton.OverrideText(Translator.GetString("KillButtonText")); + hud.SabotageButton.OverrideText(Translator.GetString("SabotageButtonText")); + } +} diff --git a/Roles/Neutral/Solsticer.cs b/Roles/Neutral/Solsticer.cs index a90def434..4ecfd7f8d 100644 --- a/Roles/Neutral/Solsticer.cs +++ b/Roles/Neutral/Solsticer.cs @@ -1,18 +1,17 @@ using AmongUs.GameOptions; using Hazel; -using Il2CppInterop.Runtime.InteropTypes.Arrays; -using InnerNet; using TOHE.Roles.Core; -using static TOHE.MeetingHudStartPatch; using static TOHE.Options; using static TOHE.Translator; +using static TOHE.MeetingHudStartPatch; +using InnerNet; +using Il2CppInterop.Runtime.InteropTypes.Arrays; namespace TOHE.Roles.Neutral; internal class Solsticer : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Solsticer; private const int Id = 26200; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Solsticer); public override CustomRoles ThisRoleBase => SolsticerCanVent.GetBool() ? CustomRoles.Engineer : CustomRoles.Crewmate; @@ -82,10 +81,10 @@ public override void ApplyGameOptions(IGameOptions opt, byte id) public override bool OnTaskComplete(PlayerControl player, int completedTaskCount, int totalTaskCount) { if (player == null) return true; - + // Sycn for modded clients SendRPC(); - + if (patched) { ResetTasks(player); @@ -315,4 +314,4 @@ public override string PlayerKnowTargetColor(PlayerControl seer, PlayerControl t } return string.Empty; } -} +} \ No newline at end of file diff --git a/Roles/Neutral/SoulCollector.cs b/Roles/Neutral/SoulCollector.cs index 51c21de5c..91d6b58b3 100644 --- a/Roles/Neutral/SoulCollector.cs +++ b/Roles/Neutral/SoulCollector.cs @@ -10,7 +10,6 @@ namespace TOHE.Roles.Neutral; internal class SoulCollector : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.SoulCollector; private const int Id = 15300; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.SoulCollector); public override bool IsDesyncRole => true; @@ -21,7 +20,6 @@ internal class SoulCollector : RoleBase private static OptionItem SoulCollectorPointsOpt; private static OptionItem GetPassiveSouls; public static OptionItem SoulCollectorCanVent; - private static OptionItem SoulCollectorHasImpostorVision; public static OptionItem DeathMeetingTimeIncrease; private byte TargetId; @@ -31,11 +29,10 @@ public override void SetupCustomOption() SetupSingleRoleOptions(Id, TabGroup.NeutralRoles, CustomRoles.SoulCollector, 1, zeroOne: false); SoulCollectorPointsOpt = IntegerOptionItem.Create(Id + 10, "SoulCollectorPointsToWin", new(1, 14, 1), 3, TabGroup.NeutralRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.SoulCollector]) .SetValueFormat(OptionFormat.Times); - GetPassiveSouls = BooleanOptionItem.Create(Id + 11, "GetPassiveSouls", true, TabGroup.NeutralRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.SoulCollector]); - SoulCollectorCanVent = BooleanOptionItem.Create(Id + 12, "SoulCollectorCanVent", true, TabGroup.NeutralRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.SoulCollector]); - DeathMeetingTimeIncrease = IntegerOptionItem.Create(Id + 13, "DeathMeetingTimeIncrease", new(0, 120, 1), 0, TabGroup.NeutralRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.SoulCollector]) + GetPassiveSouls = BooleanOptionItem.Create(Id + 12, "GetPassiveSouls", true, TabGroup.NeutralRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.SoulCollector]); + SoulCollectorCanVent = BooleanOptionItem.Create(Id + 13, "SoulCollectorCanVent", true, TabGroup.NeutralRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.SoulCollector]); + DeathMeetingTimeIncrease = IntegerOptionItem.Create(Id + 14, "DeathMeetingTimeIncrease", new(0, 120, 1), 0, TabGroup.NeutralRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.SoulCollector]) .SetValueFormat(OptionFormat.Seconds); - SoulCollectorHasImpostorVision = BooleanOptionItem.Create(Id + 14, "SoulCollectorHasImpostorVision", true, TabGroup.NeutralRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.SoulCollector]); } public override void Init() { @@ -50,7 +47,7 @@ public override void Add(byte playerId) CustomRoleManager.CheckDeadBodyOthers.Add(OnPlayerDead); } - public override string GetProgressText(byte playerId, bool cvooms) => Utils.ColorString(Utils.GetRoleColor(CustomRoles.SoulCollector).ShadeColor(0.25f), $"({AbilityLimit}/{SoulCollectorPointsOpt.GetInt()})"); + public override string GetProgressText(byte playerId, bool cvooms) => Utils.ColorString(Utils.GetRoleColor(CustomRoles.SoulCollector).ShadeColor(0.25f), $"({AbilityLimit}/{SoulCollectorPointsOpt.GetInt()})"); public override void SetAbilityButtonText(HudManager hud, byte playerId) => hud.KillButton.OverrideText(GetString("SoulCollectorKillButtonText")); private void SendRPC() { @@ -66,15 +63,15 @@ public override void ReceiveRPC(MessageReader reader, PlayerControl NaN) byte target = reader.ReadByte(); AbilityLimit = limit; - TargetId = target; + TargetId = target; } public override bool OthersKnowTargetRoleColor(PlayerControl seer, PlayerControl target) => KnowRoleTarget(seer, target); public override bool KnowRoleTarget(PlayerControl seer, PlayerControl target) => (target.IsNeutralApocalypse() && seer.IsNeutralApocalypse()); - + public override string GetMark(PlayerControl seer, PlayerControl seen = null, bool isForMeeting = false) => TargetId == seen.PlayerId ? Utils.ColorString(Utils.GetRoleColor(CustomRoles.SoulCollector), "♠") : string.Empty; - + public override string GetMarkOthers(PlayerControl seer, PlayerControl target, bool isForMeeting = false) { if (_Player == null) return string.Empty; @@ -84,8 +81,6 @@ public override string GetMarkOthers(PlayerControl seer, PlayerControl target, b } return string.Empty; } - public override void ApplyGameOptions(IGameOptions opt, byte playerId) - => opt.SetVision(SoulCollectorHasImpostorVision.GetBool()); public override bool CanUseKillButton(PlayerControl pc) => pc.Is(CustomRoles.SoulCollector); public override bool CanUseImpostorVentButton(PlayerControl pc) => SoulCollectorCanVent.GetBool(); public override bool ForcedCheckMurderAsKiller(PlayerControl killer, PlayerControl target) @@ -104,7 +99,7 @@ public override bool ForcedCheckMurderAsKiller(PlayerControl killer, PlayerContr public override void OnReportDeadBody(PlayerControl ryuak, NetworkedPlayerInfo iscute) { if (_Player == null || !_Player.IsAlive() || !GetPassiveSouls.GetBool()) return; - + AbilityLimit++; SendRPC(); } @@ -166,7 +161,6 @@ public override void AfterMeetingTasks() internal class Death : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Death; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Death); public override bool IsDesyncRole => true; public override CustomRoles ThisRoleBase => CustomRoles.Impostor; @@ -176,13 +170,14 @@ internal class Death : RoleBase public override bool OthersKnowTargetRoleColor(PlayerControl seer, PlayerControl target) => KnowRoleTarget(seer, target); public override bool KnowRoleTarget(PlayerControl seer, PlayerControl target) => target.IsNeutralApocalypse() && seer.IsNeutralApocalypse(); + public override void ApplyGameOptions(IGameOptions opt, byte playerId) => opt.SetVision(true); public override bool CanUseImpostorVentButton(PlayerControl pc) => SoulCollector.SoulCollectorCanVent.GetBool(); public override bool OnCheckMurderAsTarget(PlayerControl killer, PlayerControl target) => false; - + public override void OnCheckForEndVoting(PlayerState.DeathReason deathReason, params byte[] exileIds) { if (_Player == null || exileIds == null || exileIds.Contains(_Player.PlayerId)) return; - + var deathList = new List(); var death = _Player; foreach (var pc in Main.AllAlivePlayerControls) @@ -221,4 +216,4 @@ public override void CheckExileTarget(NetworkedPlayerInfo exiled, ref bool Decid } } } -} +} \ No newline at end of file diff --git a/Roles/Neutral/Specter.cs b/Roles/Neutral/Specter.cs index bc60643a0..ee7f88e91 100644 --- a/Roles/Neutral/Specter.cs +++ b/Roles/Neutral/Specter.cs @@ -6,8 +6,10 @@ namespace TOHE.Roles.Neutral; internal class Specter : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Specter; private const int Id = 14900; + private static readonly HashSet PlayerIds = []; + public static bool HasEnabled => PlayerIds.Any(); + public override CustomRoles ThisRoleBase => CanVent.GetBool() ? CustomRoles.Engineer : CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralChaos; //==================================================================\\ @@ -28,6 +30,14 @@ public override void SetupCustomOption() .SetParent(CustomRoleSpawnChances[CustomRoles.Specter]); OverrideTasksData.Create(14905, TabGroup.NeutralRoles, CustomRoles.Specter); } + public override void Init() + { + PlayerIds.Clear(); + } + public override void Add(byte playerId) + { + PlayerIds.Add(playerId); + } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { diff --git a/Roles/Neutral/Spiritcaller.cs b/Roles/Neutral/Spiritcaller.cs index 93b7f3920..a2509d74c 100644 --- a/Roles/Neutral/Spiritcaller.cs +++ b/Roles/Neutral/Spiritcaller.cs @@ -10,7 +10,6 @@ namespace TOHE.Roles.Neutral; internal class Spiritcaller : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Spiritcaller; private const int Id = 25200; public static bool HasEnabled = CustomRoleManager.HasEnabled(CustomRoles.Spiritcaller); public override bool IsDesyncRole => true; @@ -180,4 +179,4 @@ public void ProtectSpiritcaller() public override string PlayerKnowTargetColor(PlayerControl seer, PlayerControl target) => seer.Is(CustomRoles.Spiritcaller) && target.Is(CustomRoles.EvilSpirit) ? Main.roleColors[CustomRoles.EvilSpirit] : ""; -} +} \ No newline at end of file diff --git a/Roles/Neutral/Stalker.cs b/Roles/Neutral/Stalker.cs index 1e50acc75..e847636c7 100644 --- a/Roles/Neutral/Stalker.cs +++ b/Roles/Neutral/Stalker.cs @@ -7,8 +7,9 @@ namespace TOHE.Roles.Neutral; internal class Stalker : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Stalker; private const int Id = 18100; + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); public override bool IsDesyncRole => true; public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => SnatchesWins ? Custom_RoleType.NeutralEvil : Custom_RoleType.NeutralKilling; @@ -36,11 +37,13 @@ public override void SetupCustomOption() } public override void Init() { + playerIdList.Clear(); IsWinKill.Clear(); SnatchesWins = SnatchesWin.GetBool(); } public override void Add(byte playerId) { + playerIdList.Add(playerId); IsWinKill[playerId] = false; CustomRoleManager.CheckDeadBodyOthers.Add(CheckDeadBody); diff --git a/Roles/Neutral/Sunnyboy.cs b/Roles/Neutral/Sunnyboy.cs index 9bd5444bc..79b9cddba 100644 --- a/Roles/Neutral/Sunnyboy.cs +++ b/Roles/Neutral/Sunnyboy.cs @@ -5,11 +5,10 @@ namespace TOHE.Roles.Neutral; internal class Sunnyboy : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Sunnyboy; private const int Id = 14400; private static readonly HashSet PlayerIds = []; public static bool HasEnabled => PlayerIds.Any(); - + public override CustomRoles ThisRoleBase => CustomRoles.Scientist; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralEvil; //==================================================================\\ @@ -20,8 +19,7 @@ public override void Init() } public override void Add(byte playerId) { - if (!PlayerIds.Contains(playerId)) - PlayerIds.Add(playerId); + PlayerIds.Add(playerId); } public override void ApplyGameOptions(IGameOptions opt, byte playerId) diff --git a/Roles/Neutral/Taskinator.cs b/Roles/Neutral/Taskinator.cs index b7cbd6f91..bd1157822 100644 --- a/Roles/Neutral/Taskinator.cs +++ b/Roles/Neutral/Taskinator.cs @@ -10,7 +10,6 @@ namespace TOHE.Roles.Neutral; internal class Taskinator : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Taskinator; private const int Id = 13700; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Taskinator); public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; @@ -22,7 +21,7 @@ internal class Taskinator : RoleBase private static readonly Dictionary> taskIndex = []; private static readonly Dictionary TaskMarkPerRound = []; - + private static int maxTasksMarkedPerRound = new(); public override void SetupCustomOption() @@ -35,7 +34,7 @@ public override void SetupCustomOption() public override void Init() { - taskIndex.Clear(); + taskIndex.Clear(); TaskMarkPerRound.Clear(); maxTasksMarkedPerRound = TaskMarkPerRoundOpt.GetInt(); } @@ -53,8 +52,8 @@ private void SendRPC(byte taskinatorID, int taskIndex = -1, bool isKill = false, writer.Write(isKill); writer.Write(clearAll); if (!isKill) - { - writer.Write(TaskMarkPerRound[taskinatorID]); + { + writer.Write(TaskMarkPerRound[taskinatorID]); } AmongUsClient.Instance.FinishRpcImmediately(writer); } @@ -68,8 +67,8 @@ public override void ReceiveRPC(MessageReader reader, PlayerControl NaN) { int uses = reader.ReadInt32(); TaskMarkPerRound[taskinatorID] = uses; - if (!clearAll) - { + if (!clearAll) + { if (!taskIndex.ContainsKey(taskinatorID)) taskIndex[taskinatorID] = []; taskIndex[taskinatorID].Add(taskInd); } @@ -78,7 +77,7 @@ public override void ReceiveRPC(MessageReader reader, PlayerControl NaN) { if (taskIndex.ContainsKey(taskinatorID)) taskIndex[taskinatorID].Remove(taskInd); } - if (clearAll && taskIndex.ContainsKey(taskinatorID)) taskIndex[taskinatorID].Clear(); + if (clearAll && taskIndex.ContainsKey(taskinatorID)) taskIndex[taskinatorID].Clear(); } public override string GetProgressText(byte playerId, bool cooms) @@ -127,7 +126,7 @@ public override void OnOthersTaskComplete(PlayerControl player, PlayerTask task) else if (_Player.RpcCheckAndMurder(player, true)) { foreach (var taskinatorId in taskIndex.Keys) - { + { if (taskIndex[taskinatorId].Contains(task.Index)) { var taskinatorPC = Utils.GetPlayerById(taskinatorId); @@ -138,7 +137,7 @@ public override void OnOthersTaskComplete(PlayerControl player, PlayerTask task) player.SetRealKiller(taskinatorPC); taskIndex[taskinatorId].Remove(task.Index); - SendRPC(taskinatorID: taskinatorId, taskIndex: task.Index, isKill: true); + SendRPC(taskinatorID : taskinatorId, taskIndex:task.Index, isKill : true); Logger.Info($"{player.GetAllRoleName()} died because of {taskinatorPC.GetNameWithRole()}", "Taskinator"); } } diff --git a/Roles/Neutral/Terrorist.cs b/Roles/Neutral/Terrorist.cs index c6b600859..85e2cc582 100644 --- a/Roles/Neutral/Terrorist.cs +++ b/Roles/Neutral/Terrorist.cs @@ -7,8 +7,9 @@ namespace TOHE.Roles.Neutral; internal class Terrorist : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Terrorist; private const int id = 15400; + private static readonly HashSet PlayerIds = []; + public static bool HasEnabled = PlayerIds.Any(); public override CustomRoles ThisRoleBase => CustomRoles.Engineer; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralChaos; @@ -28,6 +29,14 @@ public override void SetupCustomOption() .SetParent(CustomRoleSpawnChances[CustomRoles.Terrorist]); OverrideTasksData.Create(15404, TabGroup.NeutralRoles, CustomRoles.Terrorist); } + public override void Init() + { + PlayerIds.Clear(); + } + public override void Add(byte playerId) + { + PlayerIds.Add(playerId); + } public override void ApplyGameOptions(IGameOptions opt, byte playerId) { @@ -55,7 +64,7 @@ private static void CheckTerroristWin(NetworkedPlayerInfo terroristData) if (taskState.IsTaskFinished && (!state.IsSuicide || CanTerroristSuicideWin.GetBool()) && (state.deathReason != PlayerState.DeathReason.Armageddon)) { if (CustomWinnerHolder.WinnerTeam != CustomWinner.Default) return; - + if (!CustomWinnerHolder.CheckForConvertedWinner(terrorist.PlayerId)) { CustomWinnerHolder.ResetAndSetWinner(CustomWinner.Terrorist); diff --git a/Roles/Neutral/Traitor.cs b/Roles/Neutral/Traitor.cs index da055c506..a2b6a0b35 100644 --- a/Roles/Neutral/Traitor.cs +++ b/Roles/Neutral/Traitor.cs @@ -6,10 +6,12 @@ namespace TOHE.Roles.Neutral; internal class Traitor : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Traitor; private const int Id = 18200; + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); + public override bool IsDesyncRole => true; - public override CustomRoles ThisRoleBase => LegacyTraitor.GetBool() ? CustomRoles.Shapeshifter : CustomRoles.Impostor; + public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralKilling; //==================================================================\\ @@ -17,10 +19,7 @@ internal class Traitor : RoleBase private static OptionItem CanVent; private static OptionItem HasImpostorVision; private static OptionItem CanUsesSabotage; - public static OptionItem KnowMadmate; - private static OptionItem LegacyTraitor; - private static OptionItem TraitorShapeshiftCD; - private static OptionItem TraitorShapeshiftDur; + private static OptionItem KnowMadmate; public override void SetupCustomOption() { @@ -31,25 +30,19 @@ public override void SetupCustomOption() HasImpostorVision = BooleanOptionItem.Create(Id + 13, GeneralOption.ImpostorVision, true, TabGroup.NeutralRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Traitor]); CanUsesSabotage = BooleanOptionItem.Create(Id + 15, GeneralOption.CanUseSabotage, true, TabGroup.NeutralRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Traitor]); KnowMadmate = BooleanOptionItem.Create(Id + 16, "TraitorKnowMadmate", true, TabGroup.NeutralRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Traitor]); - LegacyTraitor = BooleanOptionItem.Create(Id + 17, "LegacyTraitor", false, TabGroup.NeutralRoles, false) - .SetParent(CustomRoleSpawnChances[CustomRoles.Traitor]); - TraitorShapeshiftCD = FloatOptionItem.Create(Id + 19, GeneralOption.ShapeshifterBase_ShapeshiftCooldown, new(1f, 180f, 1f), 15f, TabGroup.NeutralRoles, false) - .SetParent(LegacyTraitor) - .SetValueFormat(OptionFormat.Seconds); - TraitorShapeshiftDur = FloatOptionItem.Create(Id + 21, GeneralOption.ShapeshifterBase_ShapeshiftDuration, new(1f, 180f, 1f), 30f, TabGroup.NeutralRoles, false) - .SetParent(LegacyTraitor) - .SetValueFormat(OptionFormat.Seconds); } - - public override void ApplyGameOptions(IGameOptions opt, byte playerId) + public override void Init() + { + playerIdList.Clear(); + } + public override void Add(byte playerId) { - opt.SetVision(HasImpostorVision.GetBool()); - AURoleOptions.ShapeshifterCooldown = TraitorShapeshiftCD.GetFloat(); - AURoleOptions.ShapeshifterDuration = TraitorShapeshiftDur.GetFloat(); + playerIdList.Add(playerId); } public override void SetKillCooldown(byte id) => Main.AllPlayerKillCooldown[id] = KillCooldown.GetFloat(); - + public override void ApplyGameOptions(IGameOptions opt, byte id) => opt.SetVision(HasImpostorVision.GetBool()); + public override bool CanUseKillButton(PlayerControl pc) => true; public override bool CanUseImpostorVentButton(PlayerControl pc) => CanVent.GetBool(); public override bool CanUseSabotage(PlayerControl pc) => CanUsesSabotage.GetBool(); @@ -58,8 +51,10 @@ public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl t { return !(target == killer || target.Is(Custom_Team.Impostor)); } + public override string PlayerKnowTargetColor(PlayerControl seer, PlayerControl target) { + if (Main.PlayerStates[seer.PlayerId].IsRandomizer || Main.PlayerStates[target.PlayerId].IsRandomizer) return string.Empty; if (target.Is(Custom_Team.Impostor)) { return Main.roleColors[CustomRoles.Impostor]; diff --git a/Roles/Neutral/Troller.cs b/Roles/Neutral/Troller.cs index f2c0be098..da62d2bbc 100644 --- a/Roles/Neutral/Troller.cs +++ b/Roles/Neutral/Troller.cs @@ -1,9 +1,9 @@ using AmongUs.GameOptions; +using UnityEngine; using System; using System.Text; using TOHE.Modules; using TOHE.Roles.Core; -using UnityEngine; using static TOHE.Options; using static TOHE.Translator; using static TOHE.Utils; @@ -13,7 +13,6 @@ namespace TOHE.Roles.Neutral; internal class Troller : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Troller; private const int Id = 28700; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Troller); public override CustomRoles ThisRoleBase => CustomRoles.Engineer; @@ -26,7 +25,6 @@ internal class Troller : RoleBase private SystemTypes CurrentActiveSabotage = SystemTypes.Hallway; private List AllEvents = []; - [Obfuscation(Exclude = true)] enum Events { LowSpeed, diff --git a/Roles/Neutral/Vector.cs b/Roles/Neutral/Vector.cs index 3a9e028e1..2b23cc945 100644 --- a/Roles/Neutral/Vector.cs +++ b/Roles/Neutral/Vector.cs @@ -1,58 +1,55 @@ -using AmongUs.GameOptions; +using static TOHE.Options; +using static TOHE.Utils; +using static TOHE.Translator; +using UnityEngine; +using AmongUs.GameOptions; using Hazel; using InnerNet; -using UnityEngine; -using static TOHE.Options; -using static TOHE.Translator; -using static TOHE.Utils; namespace TOHE.Roles.Neutral; internal class Vector : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Vector; private const int Id = 15500; + private static readonly HashSet PlayerIds = []; + public static bool HasEnabled => PlayerIds.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Engineer; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralChaos; - public override bool BlockMoveInVent(PlayerControl pc) => VectorInVentMaxTime.GetFloat() <= 1f; //==================================================================\\ private static OptionItem VectorVentNumWin; private static OptionItem VectorVentCD; - private static OptionItem VectorInVentMaxTime; private static readonly Dictionary VectorVentCount = []; public override void SetupCustomOption() { - SetupRoleOptions(Id, TabGroup.NeutralRoles, CustomRoles.Vector); - VectorVentNumWin = IntegerOptionItem.Create(Id + 10, "VectorVentNumWin", new(5, 500, 5), 40, TabGroup.NeutralRoles, false) + SetupRoleOptions(15500, TabGroup.NeutralRoles, CustomRoles.Vector); + VectorVentNumWin = IntegerOptionItem.Create(15502, "VectorVentNumWin", new(5, 500, 5), 40, TabGroup.NeutralRoles, false) .SetParent(CustomRoleSpawnChances[CustomRoles.Vector]) .SetValueFormat(OptionFormat.Times); - VectorVentCD = FloatOptionItem.Create(Id + 11, GeneralOption.EngineerBase_VentCooldown, new(0f, 180f, 1f), 15f, TabGroup.NeutralRoles, false) - .SetParent(CustomRoleSpawnChances[CustomRoles.Vector]) - .SetValueFormat(OptionFormat.Seconds); - VectorInVentMaxTime = FloatOptionItem.Create(Id + 12, GeneralOption.EngineerBase_InVentMaxTime, new(0f, 180f, 1f), 1f, TabGroup.CrewmateRoles, false) + VectorVentCD = FloatOptionItem.Create(15503, GeneralOption.EngineerBase_VentCooldown, new(0f, 180f, 1f), 15f, TabGroup.NeutralRoles, false) .SetParent(CustomRoleSpawnChances[CustomRoles.Vector]) .SetValueFormat(OptionFormat.Seconds); } public override void Init() { VectorVentCount.Clear(); - + PlayerIds.Clear(); } public override void Add(byte playerId) { VectorVentCount[playerId] = 0; - + PlayerIds.Add(playerId); } private void SendRPC() { if (!_Player.IsNonHostModdedClient()) return; MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.SyncRoleSkill, SendOption.Reliable, _Player.GetClientId()); writer.WriteNetObject(_Player); - writer.WritePacked(VectorVentCount[_Player.PlayerId]); + writer.WritePacked(VectorVentCount[_Player.PlayerId]); AmongUsClient.Instance.FinishRpcImmediately(writer); } public override void ReceiveRPC(MessageReader reader, PlayerControl pc) @@ -67,16 +64,16 @@ public override string GetProgressText(byte playerId, bool comms) public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.EngineerCooldown = VectorVentCD.GetFloat(); - AURoleOptions.EngineerInVentMaxTime = VectorInVentMaxTime.GetFloat(); + AURoleOptions.EngineerInVentMaxTime = 1; } public override void OnEnterVent(PlayerControl pc, Vent vent) { VectorVentCount[pc.PlayerId]++; SendRPC(); NotifyRoles(SpecifySeer: pc); - + Logger.Info($"Vent count {VectorVentCount[pc.PlayerId]}", "Vector"); - + if (VectorVentCount[pc.PlayerId] >= VectorVentNumWin.GetInt()) { if (!CustomWinnerHolder.CheckForConvertedWinner(pc.PlayerId)) diff --git a/Roles/Neutral/Virus.cs b/Roles/Neutral/Virus.cs index 80cd0ba67..1bd483019 100644 --- a/Roles/Neutral/Virus.cs +++ b/Roles/Neutral/Virus.cs @@ -1,18 +1,17 @@ -using AmongUs.GameOptions; -using System; -using TOHE.Roles.AddOns.Crewmate; -using TOHE.Roles.Core; +using System; using UnityEngine; -using static TOHE.MeetingHudStartPatch; +using AmongUs.GameOptions; +using TOHE.Roles.AddOns.Crewmate; using static TOHE.Options; using static TOHE.Translator; +using static TOHE.MeetingHudStartPatch; +using TOHE.Roles.Core; namespace TOHE.Roles.Neutral; internal class Virus : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Virus; private const int Id = 18300; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Virus); public override bool IsDesyncRole => true; @@ -33,7 +32,6 @@ internal class Virus : RoleBase private readonly HashSet InfectedPlayer = []; private readonly Dictionary VirusNotify = []; - [Obfuscation(Exclude = true)] private enum ContagiousCountModeSelectList { Virus_ContagiousCountMode_None, @@ -108,16 +106,16 @@ public override void OnCheckForEndVoting(PlayerState.DeathReason deathReason, pa if (!_Player.IsAlive() || !KillInfectedPlayerAfterMeeting.GetBool()) return; var virus = _Player; - if (exileIds.Contains(virus.PlayerId)) + if (exileIds.Contains(virus.PlayerId)) { InfectedPlayer.Clear(); return; - } + } var infectedIdList = new List(); foreach (var infectedId in InfectedPlayer) { - var infected = infectedId.GetPlayer(); + var infected = infectedId.GetPlayer(); if (virus.IsAlive() && infected != null) { if (!Main.AfterMeetingDeathPlayers.ContainsKey(infectedId)) @@ -166,4 +164,4 @@ public static bool CanBeInfected(this PlayerControl pc) && !pc.Is(CustomRoles.Admired) && !pc.Is(CustomRoles.Cultist) && !pc.Is(CustomRoles.Infectious) && !pc.Is(CustomRoles.Specter) && !(pc.GetCustomSubRoles().Contains(CustomRoles.Hurried) && !Hurried.CanBeConverted.GetBool()); } -} +} \ No newline at end of file diff --git a/Roles/Neutral/Vulture.cs b/Roles/Neutral/Vulture.cs index f997546a2..7de01e445 100644 --- a/Roles/Neutral/Vulture.cs +++ b/Roles/Neutral/Vulture.cs @@ -11,11 +11,10 @@ namespace TOHE.Roles.Neutral; internal class Vulture : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Vulture; private const int Id = 15600; private static readonly HashSet playerIdList = []; public static bool HasEnabled => playerIdList.Any(); - + public override CustomRoles ThisRoleBase => CanVent.GetBool() ? CustomRoles.Engineer : CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralChaos; //==================================================================\\ @@ -26,7 +25,7 @@ internal class Vulture : RoleBase private static OptionItem VultureReportCD; private static OptionItem MaxEaten; private static OptionItem HasImpVision; - + private static readonly Dictionary BodyReportCount = []; private static readonly Dictionary AbilityLeftInRound = []; private static readonly Dictionary LastReport = []; @@ -51,9 +50,7 @@ public override void Init() } public override void Add(byte playerId) { - if (!playerIdList.Contains(playerId)) - playerIdList.Add(playerId); - + playerIdList.Add(playerId); BodyReportCount[playerId] = 0; AbilityLeftInRound[playerId] = MaxEaten.GetInt(); LastReport[playerId] = GetTimeStamp(); @@ -95,7 +92,7 @@ public static void ReceiveBodyRPC(MessageReader reader) if (!BodyReportCount.ContainsKey(playerId)) { - BodyReportCount.Add(playerId, body); + BodyReportCount.Add(playerId , body); } else BodyReportCount[playerId] = body; @@ -156,7 +153,7 @@ public override void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInf } } private static void OnEatDeadBody(PlayerControl pc, NetworkedPlayerInfo target) - { + { BodyReportCount[pc.PlayerId]++; AbilityLeftInRound[pc.PlayerId]--; Logger.Msg($"target is null? {target == null}", "VultureNull"); @@ -221,7 +218,7 @@ private void CheckDeadBody(PlayerControl killer, PlayerControl target, bool inMe public override string GetSuffix(PlayerControl seer, PlayerControl target = null, bool isForMeeting = false) { if (isForMeeting || seer.PlayerId != target.PlayerId) return string.Empty; - + return ColorString(Color.white, LocateArrow.GetArrows(seer)); } public override void SetAbilityButtonText(HudManager hud, byte playerId) @@ -231,4 +228,4 @@ public override void SetAbilityButtonText(HudManager hud, byte playerId) public override Sprite ReportButtonSprite => CustomButton.Get("Eat"); public override string GetProgressText(byte playerId, bool comms) => ColorString(GetRoleColor(CustomRoles.Vulture).ShadeColor(0.25f), $"({(BodyReportCount.TryGetValue(playerId, out var count1) ? count1 : 0)}/{NumberOfReportsToWin.GetInt()})"); -} +} \ No newline at end of file diff --git a/Roles/Neutral/Werewolf.cs b/Roles/Neutral/Werewolf.cs index 0d5f59950..afb21378c 100644 --- a/Roles/Neutral/Werewolf.cs +++ b/Roles/Neutral/Werewolf.cs @@ -7,9 +7,9 @@ namespace TOHE.Roles.Neutral; internal class Werewolf : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Werewolf; private const int Id = 18400; - + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); public override bool IsDesyncRole => true; public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralKilling; @@ -31,10 +31,18 @@ public override void SetupCustomOption() CanVent = BooleanOptionItem.Create(Id + 11, GeneralOption.CanVent, true, TabGroup.NeutralRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Werewolf]); HasImpostorVision = BooleanOptionItem.Create(Id + 13, GeneralOption.ImpostorVision, true, TabGroup.NeutralRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Werewolf]); } + public override void Init() + { + playerIdList.Clear(); + } + public override void Add(byte playerId) + { + playerIdList.Add(playerId); + } public override void SetKillCooldown(byte id) => Main.AllPlayerKillCooldown[id] = KillCooldown.GetFloat(); public override void ApplyGameOptions(IGameOptions opt, byte id) => opt.SetVision(HasImpostorVision.GetBool()); public override void SetAbilityButtonText(HudManager hud, byte playerId) => hud.KillButton.OverrideText(Translator.GetString("WerewolfKillButtonText")); - + public override bool CanUseKillButton(PlayerControl pc) => true; public override bool CanUseImpostorVentButton(PlayerControl pc) => CanVent.GetBool(); diff --git a/Roles/Neutral/Workaholic.cs b/Roles/Neutral/Workaholic.cs index bb760d9e6..df19db45c 100644 --- a/Roles/Neutral/Workaholic.cs +++ b/Roles/Neutral/Workaholic.cs @@ -1,7 +1,7 @@ using AmongUs.GameOptions; -using static TOHE.MeetingHudStartPatch; using static TOHE.Options; using static TOHE.Translator; +using static TOHE.MeetingHudStartPatch; //Thanks TOH_Y namespace TOHE.Roles.Neutral; @@ -9,8 +9,10 @@ namespace TOHE.Roles.Neutral; internal class Workaholic : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Workaholic; private const int Id = 15800; + private static readonly HashSet PlayerIds = []; + public static bool HasEnabled => PlayerIds.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Engineer; public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralChaos; //==================================================================\\ @@ -43,9 +45,13 @@ public override void SetupCustomOption() public override void Init() { WorkaholicAlive.Clear(); - + PlayerIds.Clear(); } - + public override void Add(byte playerId) + { + PlayerIds.Add(playerId); + } + public static bool OthersKnowWorka(PlayerControl target) => WorkaholicVisibleToEveryone.GetBool() && target.Is(CustomRoles.Workaholic); @@ -103,7 +109,6 @@ public override void OnMeetingHudStart(PlayerControl player) } public override bool OnRoleGuess(bool isUI, PlayerControl target, PlayerControl pc, CustomRoles role, ref bool guesserSuicide) { - if (role != CustomRoles.Workaholic) return false; if (WorkaholicVisibleToEveryone.GetBool()) { if (!isUI) Utils.SendMessage(GetString("GuessWorkaholic"), pc.PlayerId); diff --git a/Roles/Neutral/Wraith.cs b/Roles/Neutral/Wraith.cs index 4eb5bd6f6..e71aac327 100644 --- a/Roles/Neutral/Wraith.cs +++ b/Roles/Neutral/Wraith.cs @@ -12,7 +12,6 @@ namespace TOHE.Roles.Neutral; internal class Wraith : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.Wraith; private const int Id = 18500; public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Wraith); public override bool IsDesyncRole => true; @@ -33,7 +32,7 @@ internal class Wraith : RoleBase public override void SetupCustomOption() { - SetupSingleRoleOptions(Id, TabGroup.NeutralRoles, CustomRoles.Wraith, 1, zeroOne: false); + SetupSingleRoleOptions(Id, TabGroup.NeutralRoles, CustomRoles.Wraith, 1, zeroOne: false); WraithCooldown = FloatOptionItem.Create(Id + 2, "WraithCooldown", new(1f, 180f, 1f), 30f, TabGroup.NeutralRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Wraith]) .SetValueFormat(OptionFormat.Seconds); WraithDuration = FloatOptionItem.Create(Id + 4, "WraithDuration", new(1f, 60f, 1f), 15f, TabGroup.NeutralRoles, false).SetParent(CustomRoleSpawnChances[CustomRoles.Wraith]) @@ -221,4 +220,4 @@ public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl t return false; } public override Sprite ImpostorVentButtonSprite(PlayerControl player) => CustomButton.Get("invisible"); -} +} \ No newline at end of file diff --git a/Roles/Neutral/evolver.cs b/Roles/Neutral/evolver.cs new file mode 100644 index 000000000..75cdae049 --- /dev/null +++ b/Roles/Neutral/evolver.cs @@ -0,0 +1,721 @@ +using Hazel; +using InnerNet; +using System.Text.RegularExpressions; +using static TOHE.Options; +using static TOHE.Translator; +using TOHE.Roles.Core; +using UnityEngine; +using System; + +namespace TOHE.Roles.Neutral +{ + internal class Evolver : RoleBase + { + //===========================SETUP================================\\ + private const int Id = 64000; + public static bool HasEnabled => CustomRoleManager.HasEnabled(CustomRoles.Evolver); + public override bool IsExperimental => true; + public override CustomRoles ThisRoleBase => CustomRoles.Impostor; + public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralBenign; + //==================================================================\\ + + + public static OptionItem MinEvolutionsForWin; + private static readonly Dictionary PurchaseDone = new(); + + private static readonly Dictionary evolverCache = new(); + private static int evolverPoints = 0; + private int purchasedUpgrades = 0; + private bool hasNewMegaPoint = false; + private float catchCooldown = 0.0f; + public int EvolverPoints = new(); + private int voteLevel = 0; + private static PlayerControl evolverPlayer; + private int cooldownLevel = 0; + private int voteUpgradeLevel = 0; // Starting level + private int megaPoints = 0; + private static int requiredPoints; + private float baseCatchChance = 0.5f; // 50% base chance + private bool isImmortalityActive = false; + private const float MEGA_POINT_CHANCE = 0.05f; + private const float IMMORTALITY_CATCH_CHANCE_DEBUFF = 0.5f; + private const float IMMORTALITY_CATCH_COOLDOWN_MULTIPLIER = 1.5f; + private float baseCatchCooldown = 20f; + private int basePointsPerCatch = 1; // 1 point per successful catch + private readonly int maxVoteLevel = 4; // Upgrade level variables for Evolver's perks + private int catchChanceLevel = 0; // Tracks the level of the catch chance upgrade + private int cooldownReductionLevel = 0; // Tracks the level of the cooldown reduction upgrade + private int pointsOnCatchLevel = 0; // Tracks the level of points gained per catch + private readonly int[] catchChanceUpgradeCosts = { 2, 4, 6, 9, 12 }; + private readonly int[] pointsOnCatchUpgradeCosts = { 3, 6, 10, 20 }; + private readonly int[] cooldownReductionUpgradeCosts = { 1, 5, 9, 14 }; + private readonly int[] voteUpgradeCosts = { 4, 9, 12, 17 }; + + + + + // These methods retrieve modified values based on upgrades + private float GetCatchChance() + { + float catchChanceIncrease = catchChanceLevel * 0.1f; + float cooldownReductionPenalty = cooldownReductionLevel * 0.05f; + + // Apply immortality catch chance debuff if active + float adjustedCatchChance = baseCatchChance + catchChanceIncrease - cooldownReductionPenalty; + if (isImmortalityActive) + { + adjustedCatchChance *= IMMORTALITY_CATCH_CHANCE_DEBUFF; + } + + return Mathf.Clamp(adjustedCatchChance, 0.1f, 1f); // Clamps the value between 0.1 and 1 + } + public void AddEvolutionPoint() + { + EvolverPoints++; + Logger.Info($"Evolver Points Updated: {EvolverPoints}", "Evolver"); + } + public override string GetProgressText(byte playerId, bool comms) + { + int minUpgrades = MinEvolutionsForWin.GetInt(); + if (minUpgrades == 0) return string.Empty; + + if (Main.PlayerStates[playerId].RoleClass is not Evolver ev) return string.Empty; + int upgrades = ev.purchasedUpgrades; + Color color = upgrades >= minUpgrades ? Color.green : Color.red; + return Utils.ColorString(color, $"({upgrades}/{minUpgrades})"); + + } + public int GetPurchasedUpgrades() // Public method to access the value + { + return purchasedUpgrades; + } + + private float GetCooldownReduction() + { + float baseCooldown = 25f; // 25 seconds base cooldown + float cooldownReductionPerLevel = 2f; // 2 seconds per level + return baseCooldown - (cooldownReductionLevel * cooldownReductionPerLevel); + } + + private int GetPointsPerCatch() + { + return basePointsPerCatch + pointsOnCatchLevel; + } + private float GetCatchCooldown() + { + float cooldownIncrease = catchChanceLevel * 5f; + float cooldownReduction = cooldownReductionLevel * 10f; + + // Apply immortality cooldown multiplier if active + float adjustedCooldown = baseCatchCooldown + cooldownIncrease - cooldownReduction; + if (isImmortalityActive) + { + adjustedCooldown *= IMMORTALITY_CATCH_COOLDOWN_MULTIPLIER; + } + + return Mathf.Max(adjustedCooldown, 5f); // Ensures a minimum cooldown of 5 seconds + } + public void UpgradeCooldownReduction() + { + cooldownReductionLevel++; + // Notify the player of the new cooldown only when they purchase an upgrade + Utils.SendMessage("Cooldown reduction upgraded! New cooldown: {GetCatchCooldown():F1} seconds", PlayerControl.LocalPlayer.PlayerId); + + + + + } + public int GetEvolverPoints() + { + return evolverPoints; + } + public static void Reset() + { + evolverCache.Clear(); + foreach (var pc in Main.AllPlayerControls) + { + if (pc.GetCustomRole() == CustomRoles.Evolver) + { + var points = Evolver.evolverPoints; + } + } + } + + + // Options for evolver role + public override void SetupCustomOption() + { + SetupSingleRoleOptions(Id, TabGroup.NeutralRoles, CustomRoles.Evolver, 1, zeroOne: false); + + // Minimum upgrades required to win + MinEvolutionsForWin = IntegerOptionItem.Create(Id + 10, "Evolver_MinUpgradesToWin", new(0, 15, 1), 3, + TabGroup.NeutralRoles, false) + .SetParent(CustomRoleSpawnChances[CustomRoles.Evolver]); + + } + + + + + public override bool CanUseKillButton(PlayerControl pc) => true; + + public override void SetKillCooldown(byte id) + { + Main.AllPlayerKillCooldown[id] = GetCatchCooldown(); // Sets the Evolver's cooldown using their current upgraded cooldown + } + + + + public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) + { + + + // Run the catch attempt if the target is valid + if (target != _Player) + { + + SendSkillRPC(); // Sync ability usage if necessary + + AttemptCatch(killer, target); // Run the catch mechanic + + killer.SetKillCooldown(); // Resets the cooldown for the Evolver (the one who used the ability) + + return false; // Prevent the actual kill + + } + + killer.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Evolver), GetString("EvolverInvalidTarget"))); + return false; // Always return false to block unintended kills + } + + + public override void SetAbilityButtonText(HudManager hud, byte id) + { + hud.KillButton.OverrideText(GetString("EvolverCatchText")); + } + + public override void Init() + { + + + if (MinEvolutionsForWin == null) + { + Logger.Error("MinEvolutionsForWin is not initialized.", "Evolver"); + return; // Prevent further initialization to avoid crashing. + } + PurchaseDone.Clear(); + evolverPoints = 0; + + + } + + public override void Add(byte playerId) + { + PurchaseDone[playerId] = false; + + } + + + //===========================COMMANDS==============================\\ + public static bool EvolverCheckMsg(PlayerControl pc, string msg, bool isUI = false, bool isSystemMessage = false) + { + if (isSystemMessage || !AmongUsClient.Instance.AmHost) return false; // Skip if system message or not host + + // Skip messages tagged as "" to prevent reprocessing + if (msg.StartsWith("")) return false; + + var originMsg = msg; + Logger.Info($"Received command: {msg} from {pc.PlayerId}, Host: {AmongUsClient.Instance.AmHost}", "Evolver"); + + if (!GameStates.IsMeeting || pc == null || GameStates.IsExilling) return false; + if (!pc.Is(CustomRoles.Evolver) || !(pc.GetRoleClass() is Evolver evolverInstance)) return false; + + msg = msg.ToLower().Trim(); + bool isShop = false, isBuy = false; + string error = string.Empty; + + // Check for "/shop" or "/buy" commands + if (CheckCommand(ref msg, "shop")) isShop = true; + else if (CheckCommand(ref msg, "buy")) isBuy = true; + else return false; + + if (!pc.IsAlive()) + { + pc.ShowInfoMessage(isUI, "You cannot use commands when dead!"); + Logger.Info("Command failed: Player is dead.", "Evolver"); + return true; + } + + if (isShop) + { + Evolver.ShowShopOptions(pc); + Logger.Info("Showing shop options and exiting.", "Evolver"); + return true; + } + + if (isBuy && MsgToPlayerAndRole(msg, pc, out int effectId, out error)) + { + evolverInstance.PurchaseUpgrade(pc, effectId); + SendRPC(1, effectId); + Logger.Info($"Processed buy command: effectId {effectId}", "Evolver"); + return true; + } + + // Send error message if something went wrong + Utils.SendMessage(error, pc.PlayerId); + Logger.Info("Invalid option or error message sent.", "Evolver"); + return true; + } + + + + public static void SendMessage(string message, byte playerId, bool isSystemMessage = false) + { + // Use the isSystemMessage flag to tag the message or handle it in a way that avoids re-parsing + if (isSystemMessage) + { + message = "" + message; // Prefix or otherwise tag as a system message + } + + // Rest of the message sending code + } + + public void SetCatchCooldown(float cooldown, PlayerControl player, int cooldownLevel) + { + // Apply cooldown logic here + // Example: Main.AllPlayerKillCooldown[player.PlayerId] = cooldown; + Utils.SendMessage($"Catch cooldown set to {cooldown} seconds.", player.PlayerId); + } + private void AttemptCatch(PlayerControl killer, PlayerControl target) + { + bool isCatchSuccessful = UnityEngine.Random.value < GetCatchChance(); + + if (isCatchSuccessful) + { + int pointsGained = GetPointsPerCatch(); + evolverPoints += pointsGained; + + // Regular success message with current total points after catch + var variables = new Dictionary + { + { "points", pointsGained.ToString() }, + { "totalPoints", evolverPoints.ToString() } + }; + + string successMessage = GetString("EvolverCatchSuccess", variables) + $" You now have {evolverPoints} points."; + killer.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Evolver), successMessage)); + + // Separate check for MEGA evolution point chance to avoid overlap + if (UnityEngine.Random.value <= MEGA_POINT_CHANCE) + { + megaPoints++; + hasNewMegaPoint = true; // Set flag to true + + string megaPointMessage = GetString("EvolverMegaPointGain"); + killer.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Evolver), megaPointMessage)); + } + } + else + { + + + string failureMessage = GetString("EvolverCatchFailure"); + killer.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Evolver), failureMessage)); + } + + // Trigger shield animation without killing and set cooldown + if (!DisableShieldAnimations.GetBool()) + { + killer.RpcGuardAndKill(target); + } + } + + + + + private float GetUpgradeCatchChance() + { + // Example: +10% per upgrade level + return catchChanceLevel * 0.1f; + } + + private float GetUpgradeCooldownReduction() + { + // Example: -2 seconds per upgrade level + return cooldownReductionLevel * 2f; + } + + private int GetUpgradePointsOnCatch() + { + // Example: +1 point per upgrade level + return pointsOnCatchLevel; + } + + // Inside ShowShopOptions method + private static void ShowShopOptions(PlayerControl player) + { + Evolver evolverInstance = player.GetRoleClass() as Evolver; + if (evolverInstance == null) return; + + string shopMenu = "" + + " \n/buy 1: Increase catch chance (" + + $"{evolverInstance.catchChanceLevel}/{evolverInstance.catchChanceUpgradeCosts.Length}) " + + $"[{evolverInstance.catchChanceUpgradeCosts[Mathf.Min(evolverInstance.catchChanceLevel, evolverInstance.catchChanceUpgradeCosts.Length - 1)]} points]\n" + + "/buy 2: Increase points on catch (" + + $"{evolverInstance.pointsOnCatchLevel}/{evolverInstance.pointsOnCatchUpgradeCosts.Length}) " + + $"[{evolverInstance.pointsOnCatchUpgradeCosts[Mathf.Min(evolverInstance.pointsOnCatchLevel, evolverInstance.pointsOnCatchUpgradeCosts.Length - 1)]} points]\n" + + "/buy 3: Decrease catch cooldown (" + + $"{evolverInstance.cooldownReductionLevel}/{evolverInstance.cooldownReductionUpgradeCosts.Length}) " + + $"[{evolverInstance.cooldownReductionUpgradeCosts[Mathf.Min(evolverInstance.cooldownReductionLevel, evolverInstance.cooldownReductionUpgradeCosts.Length - 1)]} points]\n" + + "/buy 4: Increase votes (" + + $"{evolverInstance.voteLevel}/{evolverInstance.maxVoteLevel}) " + + $"[{evolverInstance.voteUpgradeCosts[Mathf.Min(evolverInstance.voteLevel, evolverInstance.maxVoteLevel - 1)]} points]\n"; + + if (!evolverInstance.isImmortalityActive) + { + shopMenu += "/buy 5: Immortality Shield (0/1) [20 points]\n"; + } + else + { + shopMenu += "/buy 5: Immortality Shield (1/1) [Purchased]\n"; + } + + + int evolverPoints = GetEvolverPoints(player.PlayerId); + shopMenu += $"\nYou currently have {evolverPoints} points."; + + Utils.SendMessage(shopMenu, player.PlayerId); + } + + + + + //===========================RPC METHODS==============================\\ + public static void SendRPC(int operate, int effectId = -1) + { + MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.SyncRoleSkill, SendOption.Reliable, -1); + writer.WriteNetObject(PlayerControl.LocalPlayer); + writer.Write(operate); + if (operate == 1) writer.Write(effectId); // Send effect ID if it's a purchase + AmongUsClient.Instance.FinishRpcImmediately(writer); + } + + public override void ReceiveRPC(MessageReader reader, PlayerControl pc) + { + int operate = reader.ReadInt32(); + if (operate == 1) + { + int effectId = reader.ReadInt32(); + ApplyEffect(pc, effectId); // Apply the upgrade effect to the Evolver player + } + } + + //===========================HELPER METHODS==============================\\ + private static bool MsgToPlayerAndRole(string msg, PlayerControl player, out int effectId, out string error) + { + if (msg.StartsWith("/")) + msg = msg.Replace("/", string.Empty); + + Regex r = new("\\d+"); + MatchCollection mc = r.Matches(msg); + string result = string.Empty; + for (int i = 0; i < mc.Count; i++) + result += mc[i]; + + if (int.TryParse(result, out int num)) + { + if (num < 1 || num > 6) + { + effectId = -1; + error = "/buy 1: Increase catch chance\n" + + "/buy 2: Increase points on catch\n" + + "/buy 3: Health increase\n" + + "/buy 4: Increase votes\n" + + "/buy 5: Decrease catch cooldown\n" + + "/buy 6: Immortality\n" + + $"\nYou currently have {evolverPoints} points."; + + return false; + } + effectId = num; + error = string.Empty; + return true; + } + else + { + effectId = -1; + + // Build the shop options message with current points + int evolverPoints = GetEvolverPoints(player.PlayerId); + error = "/buy 1: Increase catch chance\n" + + "/buy 2: Increase points on catch\n" + + "/buy 3: Health increase\n" + + "/buy 4: Increase votes\n" + + "/buy 5: Decrease catch cooldown\n" + + "/buy 6: Immortality\n" + + $"\nYou currently have {evolverPoints} points."; + + return false; + } + + } + + public static bool CheckCommand(ref string msg, string command) + { + var comList = command.Split('|'); + for (int i = 0; i < comList.Length; i++) + { + if (msg.StartsWith("/" + comList[i])) + { + msg = msg.Replace("/" + comList[i], string.Empty).Trim(); + return true; + } + } + return false; + } + public override int AddRealVotesNum(PlayerVoteArea ps) + { + return voteUpgradeLevel; // Each level grants an additional vote + } + + public override void AddVisualVotes(PlayerVoteArea votedPlayer, ref List statesList) + { + var additionalVotes = voteUpgradeLevel; + + for (var i = 0; i < additionalVotes; i++) + { + statesList.Add(new MeetingHud.VoterState() + { + VoterId = votedPlayer.TargetPlayerId, + VotedForId = votedPlayer.VotedFor + }); + } + } + + public void BuyImmortality(PlayerControl player) + { + // Check if ability is already bought + if (isImmortalityActive) return; + + // Activate immortality shield + isImmortalityActive = true; + + Utils.SendMessage("You have gained an immortality shield, but your abilities have been weakened!", player.PlayerId); + } + + + // Method to get the adjusted catch chance based on immortality status + + + public override bool OnCheckMurderAsTarget(PlayerControl killer, PlayerControl target) + { + // Check if target is Evolver and has shield active + if (target.Is(CustomRoles.Evolver) && isImmortalityActive) + { + // Block the attack and notify the player + Utils.SendMessage("Your immortality shield protected you from an attack!", target.PlayerId); + return false; // Cancels the kill + } + + + // Standard behavior if no shield or reflection is active + return base.OnCheckMurderAsTarget(killer, target); + } + + + + + + + + + public void PurchaseUpgrade(PlayerControl player, int effectId) + { + int currentPoints = GetEvolverPoints(player.PlayerId); + + switch (effectId) + { + case 1: // Increase Catch Chance + Logger.Info($"Attempting to upgrade Catch Chance: current level = {catchChanceLevel}, max level = {catchChanceUpgradeCosts.Length}", "Evolver", false, 0, "", false); + if (catchChanceLevel < catchChanceUpgradeCosts.Length && + currentPoints >= catchChanceUpgradeCosts[catchChanceLevel]) + { + DeductPoints(player.PlayerId, catchChanceUpgradeCosts[catchChanceLevel]); + catchChanceLevel++; + purchasedUpgrades++; + Utils.SendMessage($"Catch chance upgraded to {GetCatchChance() * 100}%! Cooldown is now {GetCatchCooldown()} seconds.", player.PlayerId); + } + else + { + Utils.SendMessage("Not enough points or max level reached for catch chance upgrade.", player.PlayerId); + } + break; + + case 2: // Increase Points on Catch + Logger.Info($"Attempting to upgrade Points on Catch: current level = {pointsOnCatchLevel}, max level = {pointsOnCatchUpgradeCosts.Length}", "Evolver", false, 0, "", false); + if (pointsOnCatchLevel < pointsOnCatchUpgradeCosts.Length && + currentPoints >= pointsOnCatchUpgradeCosts[pointsOnCatchLevel]) + { + DeductPoints(player.PlayerId, pointsOnCatchUpgradeCosts[pointsOnCatchLevel]); + pointsOnCatchLevel++; + purchasedUpgrades++; + Utils.SendMessage($"Points on catch upgraded to {GetPointsPerCatch()} points.", player.PlayerId); + } + else + { + Utils.SendMessage("Not enough points or max level reached for points on catch upgrade.", player.PlayerId); + } + break; + + case 3: // Decrease Catch Cooldown + Logger.Info($"Attempting to upgrade Catch Cooldown: current level = {cooldownReductionLevel}, max level = {cooldownReductionUpgradeCosts.Length}", "Evolver", false, 0, "", false); + if (cooldownReductionLevel < cooldownReductionUpgradeCosts.Length && + currentPoints >= cooldownReductionUpgradeCosts[cooldownReductionLevel]) + { + DeductPoints(player.PlayerId, cooldownReductionUpgradeCosts[cooldownReductionLevel]); + cooldownReductionLevel++; + purchasedUpgrades++; + Utils.SendMessage($"Catch cooldown reduced to {GetCatchCooldown()} seconds. Current catch chance is {GetCatchChance() * 100}%.", player.PlayerId); + } + else + { + Utils.SendMessage("Not enough points or max level reached for cooldown reduction upgrade.", player.PlayerId); + } + break; + + case 4: // Increase Votes + Logger.Info($"Attempting to upgrade Votes: current level = {voteUpgradeLevel}, max level = {voteUpgradeCosts.Length}", "Evolver", false, 0, "", false); + + if (voteUpgradeLevel < voteUpgradeCosts.Length && + currentPoints >= voteUpgradeCosts[voteUpgradeLevel]) + { + DeductPoints(player.PlayerId, voteUpgradeCosts[voteUpgradeLevel]); + voteUpgradeLevel++; + purchasedUpgrades++; + Utils.SendMessage($"Vote count increased to {GetVoteCount()}!", player.PlayerId); + } + else + { + Utils.SendMessage("Not enough points or max level reached for vote count upgrade.", player.PlayerId); + } + break; + + case 5: // Immortality Shield + Logger.Info("Attempting to purchase Immortality Shield", "Evolver", false, 0, "", false); + if (!isImmortalityActive && currentPoints >= 20) + { + DeductPoints(player.PlayerId, 20); + BuyImmortality(player); // Pass the player object here + purchasedUpgrades++; + Utils.SendMessage("Immortality shield purchased! You are now shielded from attacks, but catch chance and cooldown are affected.", player.PlayerId); + } + else + { + Utils.SendMessage("Not enough points or Immortality Shield already purchased.", player.PlayerId); + } + break; + + + + + + + default: + Utils.SendMessage("Invalid upgrade option.", player.PlayerId); + break; + } + } + + private int GetVoteCount() + { + // Base vote count is 1, and each level adds an additional vote + return 1 + voteUpgradeLevel; // Assuming 0 upgrades means 1 vote, level 4 means 5 votes + } + + + + + + // Other methods like EnableReflectionAbility() and EnableReflexiveCooldownReduction() will follow a similar structure + + private static void ApplyEffect(PlayerControl player, int effectId) + { + switch (effectId) + { + case 1: + Utils.SendMessage("Increased catch chance applied!", player.PlayerId); + // Apply catch chance increase logic + break; + case 2: + Utils.SendMessage("Increased points on catch applied!", player.PlayerId); + // Apply points increase logic + break; + case 3: + Utils.SendMessage("Health increase applied!", player.PlayerId); + // Apply health increase logic + break; + case 4: + Utils.SendMessage("Increased votes applied!", player.PlayerId); + // Apply vote increase logic + break; + case 5: + Utils.SendMessage("Decreased catch cooldown applied!", player.PlayerId); + // Apply cooldown reduction logic + break; + case 6: + Utils.SendMessage("Immortality applied!", player.PlayerId); + // Apply immortality logic + break; + } + } + + + private static int GetUpgradeCost(int effectId) => 1; // Example cost, can vary per upgrade + private static int GetEvolverPoints(byte playerId) => evolverPoints; + private static void DeductPoints(byte playerId, int cost) => evolverPoints -= cost; + + //===========================MEGA upgrades===========================================================================================================================================================================================================================================\\ + public void AttemptMegaPointGain(PlayerControl player) + { + if (megaPoints >= 1) return; // Limit to 1 MEGA point for simplicity + + if (UnityEngine.Random.value <= MEGA_POINT_CHANCE) + { + megaPoints++; + Utils.SendMessage("You earned a MEGA evolution point! It will be automatically converted to normal points in the next meeting.", player.PlayerId); + hasNewMegaPoint = true; // Set flag to notify during meeting + } + } + + public override void OnMeetingHudStart(PlayerControl pc) + { + if (hasNewMegaPoint) + { + hasNewMegaPoint = false; // Reset the flag after notifying + + if (megaPoints > 0) + { + // Convert MEGA points to normal points + int pointsToAdd = megaPoints * 5; // Conversion rate: 1 MEGA point = 5 normal points + AddNormalPoints(pc.PlayerId, pointsToAdd); + megaPoints = 0; // Clear MEGA points after conversion + + Utils.SendMessage($"Your MEGA evolution point has been converted to {pointsToAdd} normal points!", pc.PlayerId); + } + } + } + + private void AddNormalPoints(byte playerId, int points) + { + evolverPoints += points; + Utils.SendMessage($"You have been awarded {points} normal points!", playerId); + } + + public static void ClearEvolverCache() + { + evolverCache.Clear(); + } + + + } +} diff --git a/Roles/Vanilla/CrewmateTOHE.cs b/Roles/Vanilla/CrewmateTOHE.cs index c76263b74..710761164 100644 --- a/Roles/Vanilla/CrewmateTOHE.cs +++ b/Roles/Vanilla/CrewmateTOHE.cs @@ -4,9 +4,10 @@ namespace TOHE.Roles.Vanilla; internal class CrewmateTOHE : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.CrewmateTOHE; private const int Id = 6000; - + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateVanilla; //==================================================================\\ @@ -15,4 +16,13 @@ public override void SetupCustomOption() { Options.SetupRoleOptions(Id, TabGroup.CrewmateRoles, CustomRoles.CrewmateTOHE); } + + public override void Init() + { + playerIdList.Clear(); + } + public override void Add(byte playerId) + { + playerIdList.Add(playerId); + } } diff --git a/Roles/Vanilla/DefaultSetup.cs b/Roles/Vanilla/DefaultSetup.cs index 9c2c702e9..bcff96760 100644 --- a/Roles/Vanilla/DefaultSetup.cs +++ b/Roles/Vanilla/DefaultSetup.cs @@ -4,18 +4,19 @@ namespace TOHE; internal class DefaultSetup : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.NotAssigned; - + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; public override Custom_RoleType ThisRoleType => Custom_RoleType.None; //==================================================================\\ public override void Init() { - + playerIdList.Clear(); } public override void Add(byte playerId) { - + playerIdList.Add(playerId); } -} +} \ No newline at end of file diff --git a/Roles/Vanilla/EngineerTOHE.cs b/Roles/Vanilla/EngineerTOHE.cs index b76d1bb06..aa3d9fade 100644 --- a/Roles/Vanilla/EngineerTOHE.cs +++ b/Roles/Vanilla/EngineerTOHE.cs @@ -6,8 +6,10 @@ namespace TOHE.Roles.Vanilla; internal class EngineerTOHE : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.EngineerTOHE; private const int Id = 6100; + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Engineer; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateVanilla; //==================================================================\\ @@ -26,6 +28,15 @@ public override void SetupCustomOption() .SetValueFormat(OptionFormat.Seconds); } + public override void Init() + { + playerIdList.Clear(); + } + public override void Add(byte playerId) + { + playerIdList.Add(playerId); + } + public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.EngineerCooldown = VentUseCooldown.GetInt(); diff --git a/Roles/Vanilla/ImpostorTOHE.cs b/Roles/Vanilla/ImpostorTOHE.cs index e7846fc81..77a30b3c0 100644 --- a/Roles/Vanilla/ImpostorTOHE.cs +++ b/Roles/Vanilla/ImpostorTOHE.cs @@ -4,8 +4,10 @@ namespace TOHE.Roles.Vanilla; internal class ImpostorTOHE : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.ImpostorTOHE; private const int Id = 300; + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Impostor; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorVanilla; //==================================================================\\ @@ -14,4 +16,13 @@ public override void SetupCustomOption() { Options.SetupRoleOptions(Id, TabGroup.ImpostorRoles, CustomRoles.ImpostorTOHE); } + + public override void Init() + { + playerIdList.Clear(); + } + public override void Add(byte playerId) + { + playerIdList.Add(playerId); + } } diff --git a/Roles/Vanilla/NoisemakerTOHE.cs b/Roles/Vanilla/NoisemakerTOHE.cs index a2ad76a61..34b1b7acd 100644 --- a/Roles/Vanilla/NoisemakerTOHE.cs +++ b/Roles/Vanilla/NoisemakerTOHE.cs @@ -6,7 +6,6 @@ namespace TOHE.Roles.Vanilla; internal class NoisemakerTOHE : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.NoisemakerTOHE; private const int Id = 6230; private static readonly HashSet playerIdList = []; public static bool HasEnabled => playerIdList.Any(); diff --git a/Roles/Vanilla/PhantomTOHE.cs b/Roles/Vanilla/PhantomTOHE.cs index 4720a80b1..66e371b88 100644 --- a/Roles/Vanilla/PhantomTOHE.cs +++ b/Roles/Vanilla/PhantomTOHE.cs @@ -5,8 +5,10 @@ namespace TOHE.Roles.Vanilla; internal class PhantomTOHE : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.PhantomTOHE; private const int Id = 450; + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Phantom; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorVanilla; //==================================================================\\ @@ -25,6 +27,15 @@ public override void SetupCustomOption() .SetValueFormat(OptionFormat.Seconds); } + public override void Init() + { + playerIdList.Clear(); + } + public override void Add(byte playerId) + { + playerIdList.Add(playerId); + } + public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.PhantomCooldown = InvisCooldown.GetInt(); diff --git a/Roles/Vanilla/ScientistTOHE.cs b/Roles/Vanilla/ScientistTOHE.cs index d5c7e903f..4b8a26a66 100644 --- a/Roles/Vanilla/ScientistTOHE.cs +++ b/Roles/Vanilla/ScientistTOHE.cs @@ -6,8 +6,10 @@ namespace TOHE.Roles.Vanilla; internal class ScientistTOHE : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.ScientistTOHE; private const int Id = 6200; + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Scientist; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateVanilla; //==================================================================\\ @@ -26,6 +28,15 @@ public override void SetupCustomOption() .SetValueFormat(OptionFormat.Seconds); } + public override void Init() + { + playerIdList.Clear(); + } + public override void Add(byte playerId) + { + playerIdList.Add(playerId); + } + public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.ScientistCooldown = BatteryCooldown.GetInt(); diff --git a/Roles/Vanilla/ShapeshifterTOHE.cs b/Roles/Vanilla/ShapeshifterTOHE.cs index b3f1bbdb3..a1f899618 100644 --- a/Roles/Vanilla/ShapeshifterTOHE.cs +++ b/Roles/Vanilla/ShapeshifterTOHE.cs @@ -5,8 +5,10 @@ namespace TOHE.Roles.Vanilla; internal class ShapeshifterTOHE : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.ShapeshifterTOHE; private const int Id = 400; + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Shapeshifter; public override Custom_RoleType ThisRoleType => Custom_RoleType.ImpostorVanilla; //==================================================================\\ @@ -28,6 +30,15 @@ public override void SetupCustomOption() .SetParent(Options.CustomRoleSpawnChances[CustomRoles.ShapeshifterTOHE]); } + public override void Init() + { + playerIdList.Clear(); + } + public override void Add(byte playerId) + { + playerIdList.Add(playerId); + } + public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.ShapeshifterCooldown = ShapeshiftCooldown.GetInt(); diff --git a/Roles/Vanilla/TrackerTOHE.cs b/Roles/Vanilla/TrackerTOHE.cs index 92f0d7747..0cc184f71 100644 --- a/Roles/Vanilla/TrackerTOHE.cs +++ b/Roles/Vanilla/TrackerTOHE.cs @@ -5,8 +5,10 @@ namespace TOHE.Roles.Vanilla; internal class TrackerTOHE : RoleBase { //===========================SETUP================================\\ - public override CustomRoles Role => CustomRoles.TrackerTOHE; private const int Id = 6250; + private static readonly HashSet playerIdList = []; + public static bool HasEnabled => playerIdList.Any(); + public override CustomRoles ThisRoleBase => CustomRoles.Tracker; public override Custom_RoleType ThisRoleType => Custom_RoleType.CrewmateVanilla; //==================================================================\\ @@ -29,6 +31,15 @@ public override void SetupCustomOption() .SetValueFormat(OptionFormat.Seconds); } + public override void Init() + { + playerIdList.Clear(); + } + public override void Add(byte playerId) + { + playerIdList.Add(playerId); + } + public override void ApplyGameOptions(IGameOptions opt, byte playerId) { AURoleOptions.TrackerCooldown = TrackCooldown.GetInt(); diff --git a/Summoned.cs b/Summoned.cs new file mode 100644 index 000000000..5f282702b --- /dev/null +++ b/Summoned.cs @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/TOHE - Backup.csproj b/TOHE - Backup.csproj new file mode 100644 index 000000000..0d335c27e --- /dev/null +++ b/TOHE - Backup.csproj @@ -0,0 +1,50 @@ + + + net6.0 + false + false + false + Town Of Host Enhanced + Moe + preview + + Debug;Release;Canary + true + True + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + runtime; compile; build; native; contentfiles; analyzers; buildtransitive + all + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + + + \ No newline at end of file diff --git a/TOHE.csproj b/TOHE.csproj index 2d96cecc0..4f7e965ef 100644 --- a/TOHE.csproj +++ b/TOHE.csproj @@ -6,17 +6,15 @@ false Town Of Host Enhanced Moe - 12.0 + 12.0 Debug;Release;Canary true True - 65001 - @@ -40,8 +38,8 @@ - - + + diff --git a/main.cs b/main.cs index ef09c4845..d119fbbd8 100644 --- a/main.cs +++ b/main.cs @@ -7,11 +7,10 @@ using MonoMod.Utils; using System; using System.IO; -using System.Security.Cryptography; +using System.Reflection; using System.Text; using System.Text.Json; using TOHE.Modules; -using TOHE.Patches.Crowded; using TOHE.Roles.AddOns; using TOHE.Roles.Core; using TOHE.Roles.Double; @@ -25,8 +24,6 @@ namespace TOHE; [BepInPlugin(PluginGuid, "TOHE", PluginVersion)] [BepInIncompatibility("jp.ykundesu.supernewroles")] -[BepInIncompatibility("com.ten.thebetterroles")] -[BepInIncompatibility("xyz.crowdedmods.crowdedmod")] [BepInProcess("Among Us.exe")] public class Main : BasePlugin { @@ -41,19 +38,18 @@ public class Main : BasePlugin public static HashAuth DebugKeyAuth { get; private set; } public const string DebugKeyHash = "c0fd562955ba56af3ae20d7ec9e64c664f0facecef4b3e366e109306adeae29d"; public const string DebugKeySalt = "59687b"; - public static string FileHash { get; private set; } = ""; public static ConfigEntry DebugKeyInput { get; private set; } public const string PluginGuid = "com.0xdrmoe.townofhostenhanced"; - public const string PluginVersion = "2024.1220.220.00083"; // YEAR.MMDD.VERSION.CANARYDEV - public const string PluginDisplayVersion = "2.2.0 Alpha 8 Hotfix 3"; - public const string SupportedVersionAU = "2024.10.29"; // Changed becasue Dark theme works at this version. + public const string PluginVersion = "2024.1102.210.9999"; // YEAR.MMDD.VERSION.CANARYDEV + public const string PluginDisplayVersion = "2.1.0"; + public const string SupportedVersionAU = "2024.8.13"; // Also 2024.9.4 and 2024.10.29 /******************* Change one of the three variables to true before making a release. *******************/ - public static readonly bool devRelease = false; // Latest: V2.2.0 Alpha 4 Hotfix 1 - public static readonly bool canaryRelease = true; // Latest: V2.1.0 Beta 3 - public static readonly bool fullRelease = false; // Latest: V2.1.1 + public static readonly bool devRelease = false; // Latest: V2.1.0 Alpha 16 Hotfix 1 + public static readonly bool canaryRelease = false; // Latest: V2.1.0 Beta 3 + public static readonly bool fullRelease = true; // Latest: V2.1.0 public static bool hasAccess = true; @@ -67,7 +63,7 @@ public class Main : BasePlugin public static readonly bool ShowWebsiteButton = true; public static readonly string WebsiteInviteUrl = "https://weareten.ca/"; - + public static readonly bool ShowDonationButton = true; public static readonly string DonationInviteUrl = "https://weareten.ca/TOHE"; @@ -80,7 +76,6 @@ public class Main : BasePlugin public static bool AlreadyShowMsgBox = false; public static string credentialsText; public Coroutines coroutines; - public Dispatcher dispatcher; public static NormalGameOptionsV08 NormalOptions => GameOptionsManager.Instance.currentNormalGameOptions; public static HideNSeekGameOptionsV08 HideNSeekOptions => GameOptionsManager.Instance.currentHideNSeekGameOptions; //Client Options @@ -96,7 +91,6 @@ public class Main : BasePlugin public static ConfigEntry DisableLobbyMusic { get; private set; } public static ConfigEntry ShowTextOverlay { get; private set; } public static ConfigEntry HorseMode { get; private set; } - public static ConfigEntry LongMode { get; private set; } public static ConfigEntry ForceOwnLanguage { get; private set; } public static ConfigEntry ForceOwnLanguageRoleName { get; private set; } public static ConfigEntry EnableCustomButton { get; private set; } @@ -127,7 +121,7 @@ public class Main : BasePlugin public static ConfigEntry PlayerSpawnTimeOutCooldown { get; private set; } public static OptionBackupData RealOptionsData; - + public static Dictionary PlayerStates = []; public static readonly Dictionary AllPlayerNames = []; public static readonly Dictionary AllClientRealNames = []; @@ -138,10 +132,11 @@ public class Main : BasePlugin public static readonly Dictionary AfterMeetingDeathPlayers = []; public static readonly Dictionary roleColors = []; const string LANGUAGE_FOLDER_NAME = "Language"; - + public static bool IsFixedCooldown => CustomRoles.Vampire.IsEnable() || CustomRoles.Poisoner.IsEnable(); public static float RefixCooldownDelay = 0f; public static NetworkedPlayerInfo LastVotedPlayerInfo; + public static readonly HashSet ResetCamPlayerList = []; public static string LastVotedPlayer; public static readonly HashSet winnerList = []; public static readonly HashSet winnerNameList = []; @@ -163,14 +158,14 @@ public class Main : BasePlugin public static readonly Dictionary SayStartTimes = []; public static readonly Dictionary SayBanwordsTimes = []; public static readonly Dictionary AllPlayerSpeed = []; + public static readonly Dictionary LastAllPlayerSpeed = []; public static readonly HashSet PlayersDiedInMeeting = []; public static readonly Dictionary AllKillers = []; public static readonly Dictionary OvverideOutfit = []; public static readonly Dictionary CheckShapeshift = []; public static readonly Dictionary ShapeshiftTarget = []; - public static readonly HashSet UnShapeShifter = []; - public static readonly HashSet DeadPassedMeetingPlayers = []; + public static readonly HashSet UnShapeShifter = []; public static bool GameIsLoaded { get; set; } = false; public static bool isLoversDead = true; @@ -196,8 +191,7 @@ public class Main : BasePlugin public static int MadmateNum = 0; public static int BardCreations = 0; public static int MeetingsPassed = 0; - public static long LastMeetingEnded = Utils.GetTimeStamp(); - + public static PlayerControl[] AllPlayerControls { @@ -247,7 +241,7 @@ public static PlayerControl[] AllAlivePlayerControls public static List TName_Snacks_CN = ["冰激凌", "奶茶", "巧克力", "蛋糕", "甜甜圈", "可乐", "柠檬水", "冰糖葫芦", "果冻", "糖果", "牛奶", "抹茶", "烧仙草", "菠萝包", "布丁", "椰子冻", "曲奇", "红豆土司", "三彩团子", "艾草团子", "泡芙", "可丽饼", "桃酥", "麻薯", "鸡蛋仔", "马卡龙", "雪梅娘", "炒酸奶", "蛋挞", "松饼", "西米露", "奶冻", "奶酥", "可颂", "奶糖"]; public static List TName_Snacks_EN = ["Ice cream", "Milk tea", "Chocolate", "Cake", "Donut", "Coke", "Lemonade", "Candied haws", "Jelly", "Candy", "Milk", "Matcha", "Burning Grass Jelly", "Pineapple Bun", "Pudding", "Coconut Jelly", "Cookies", "Red Bean Toast", "Three Color Dumplings", "Wormwood Dumplings", "Puffs", "Can be Crepe", "Peach Crisp", "Mochi", "Egg Waffle", "Macaron", "Snow Plum Niang", "Fried Yogurt", "Egg Tart", "Muffin", "Sago Dew", "panna cotta", "soufflé", "croissant", "toffee"]; - public static string Get_TName_Snacks => TranslationController.Instance.currentLanguage.languageID is SupportedLangs.SChinese or SupportedLangs.TChinese + public static string Get_TName_Snacks => TranslationController.Instance.currentLanguage.languageID is SupportedLangs.SChinese or SupportedLangs.TChinese ? TName_Snacks_CN.RandomElement() : TName_Snacks_EN.RandomElement(); @@ -274,12 +268,12 @@ public static void LoadCustomRoleColor() { try { - if (Enum.TryParse(tmp[0], out CustomRoles role)) + if (Enum.TryParse(tmp[0], out CustomRoles role)) { var color = tmp[1].Trim().TrimStart('#'); if (Utils.CheckColorHex(color)) - { - roleColors[role] = "#" + color; + { + roleColors[role] = "#"+color; } else TOHE.Logger.Error($"Invalid Hexcolor #{color}", "LoadCustomRoleColor"); } @@ -332,7 +326,7 @@ public static void LoadRoleColors() if (stream != null) { using StreamReader reader = new(stream); - + string jsonData = reader.ReadToEnd(); Dictionary jsonDict = JsonSerializer.Deserialize>(jsonData); foreach (var kvp in jsonDict) @@ -365,12 +359,13 @@ public static void LoadRoleColors() break; } } + if (!Directory.Exists(LANGUAGE_FOLDER_NAME)) Directory.CreateDirectory(LANGUAGE_FOLDER_NAME); CreateTemplateRoleColorFile(); if (File.Exists(@$"./{LANGUAGE_FOLDER_NAME}/RoleColor.dat")) { UpdateCustomTranslation(); - LoadCustomRoleColor(); + LoadCustomRoleColor(); } } catch (ArgumentException ex) @@ -391,19 +386,18 @@ public static void LoadRoleClasses() .GetTypes() .Where(myType => myType.IsClass && !myType.IsAbstract && myType.IsSubclassOf(typeof(RoleBase))); - var roleInstances = RoleTypes.Select(x => (RoleBase)Activator.CreateInstance(x)).ToList(); - CustomRolesHelper.DuplicatedRoles = new Dictionary { { CustomRoles.NiceMini, typeof(Mini) }, { CustomRoles.EvilMini, typeof(Mini) } }; + foreach (var role in CustomRolesHelper.AllRoles.Where(x => x < CustomRoles.NotAssigned)) { if (!CustomRolesHelper.DuplicatedRoles.TryGetValue(role, out Type roleType)) { - roleType = roleInstances.FirstOrDefault(x => x.Role == role)?.GetType() ?? typeof(DefaultSetup); + roleType = RoleTypes.FirstOrDefault(x => x.Name.Equals(role.ToString(), StringComparison.OrdinalIgnoreCase)) ?? typeof(DefaultSetup); } CustomRoleManager.RoleClass.Add(role, (RoleBase)Activator.CreateInstance(roleType)); @@ -428,7 +422,7 @@ public static void LoadAddonClasses() .Where(t => IAddonType.IsAssignableFrom(t) && !t.IsInterface) .Select(x => (IAddon)Activator.CreateInstance(x)) .Where(x => x != null) - .ToDictionary(x => x.Role, x => x)); + .ToDictionary(x => Enum.Parse(x.GetType().Name, true), x => x)); TOHE.Logger.Info("AddonClasses Loaded Successfully", "LoadAddonClasses"); } @@ -490,19 +484,6 @@ public static void ExportCustomRoleColors() File.WriteAllText(@$"./{LANGUAGE_FOLDER_NAME}/export_RoleColor.dat", sb.ToString()); } - private void InitializeFileHash() - { - var file = Assembly.GetExecutingAssembly(); - using var stream = file.Location != null ? File.OpenRead(file.Location) : null; - if (stream != null) - { - using var sha256 = SHA256.Create(); - var hashBytes = sha256.ComputeHash(stream); - FileHash = BitConverter.ToString(hashBytes).Replace("-", "").ToLowerInvariant(); - TOHE.Logger.Msg("Assembly Hash: " + FileHash, "Plugin Load"); - } - } - public override void Load() { Instance = this; @@ -520,7 +501,6 @@ public override void Load() DisableLobbyMusic = Config.Bind("Client Options", "DisableLobbyMusic", false); ShowTextOverlay = Config.Bind("Client Options", "ShowTextOverlay", false); HorseMode = Config.Bind("Client Options", "HorseMode", false); - LongMode = Config.Bind("Client Options", "LongMode", false); ForceOwnLanguage = Config.Bind("Client Options", "ForceOwnLanguage", false); ForceOwnLanguageRoleName = Config.Bind("Client Options", "ForceOwnLanguageRoleName", false); EnableCustomButton = Config.Bind("Client Options", "EnableCustomButton", true); @@ -533,15 +513,8 @@ public override void Load() GodMode = Config.Bind("Client Options", "GodMode", false); AutoRehost = Config.Bind("Client Options", "AutoRehost", false); - if (!DebugModeManager.AmDebugger) - { - HorseMode.Value = false; - // Disable Horse Mode since it cause client crash - } - Logger = BepInEx.Logging.Logger.CreateLogSource("TOHE"); coroutines = AddComponent(); - dispatcher = AddComponent(); TOHE.Logger.Enable(); //TOHE.Logger.Disable("NotifyRoles"); TOHE.Logger.Disable("SwitchSystem"); @@ -618,25 +591,16 @@ public override void Load() handler.Info($"{nameof(ThisAssembly.Git.Tag)}: {ThisAssembly.Git.Tag}"); ClassInjector.RegisterTypeInIl2Cpp(); - ClassInjector.RegisterTypeInIl2Cpp(); - ClassInjector.RegisterTypeInIl2Cpp(); - ClassInjector.RegisterTypeInIl2Cpp(); - - NormalGameOptionsV08.RecommendedImpostors = NormalGameOptionsV08.MaxImpostors = Enumerable.Repeat(127, 127).ToArray(); - NormalGameOptionsV08.MinPlayers = Enumerable.Repeat(4, 127).ToArray(); - HideNSeekGameOptionsV08.MinPlayers = Enumerable.Repeat(4, 127).ToArray(); Harmony.PatchAll(); if (!DebugModeManager.AmDebugger) ConsoleManager.DetachConsole(); else ConsoleManager.CreateConsole(); - - InitializeFileHash(); TOHE.Logger.Msg("========= TOHE loaded! =========", "Plugin Load"); } } -[Obfuscation(Exclude = true)] + public enum CustomRoles { // Crewmate(Vanilla) @@ -671,7 +635,6 @@ public enum CustomRoles Possessor, //Impostor - Abyssbringer, Anonymous, AntiAdminer, Arrogance, @@ -746,6 +709,8 @@ public enum CustomRoles Witch, Zombie, + + //Crewmate Ghost Ghastly, Hawk, @@ -760,35 +725,35 @@ public enum CustomRoles Benefactor, Bodyguard, Captain, - Celebrity, + Celebrity, Chameleon, - ChiefOfPolice, + ChiefOfPolice, //police commisioner ///// UNUSED Cleanser, CopyCat, - Coroner, + Coroner, Crusader, - Deceiver, + Deceiver, Deputy, Detective, Dictator, Doctor, Enigma, - FortuneTeller, + FortuneTeller, Grenadier, Guardian, GuessMaster, - Inspector, + Inspector, Investigator, Jailer, Judge, Keeper, - Knight, + Knight, LazyGuy, Lighter, Lookout, Marshall, Mayor, - Mechanic, + Mechanic, Medic, Medium, Merchant, @@ -799,8 +764,8 @@ public enum CustomRoles NiceMini, Observer, Oracle, - Overseer, - Pacifist, + Overseer, + Pacifist, President, Psychic, Randomizer, @@ -834,15 +799,17 @@ public enum CustomRoles Berserker, BloodKnight, Collector, - Cultist, + Cultist, CursedSoul, Death, - Demon, + Demon, Doomsayer, Doppelganger, Executioner, + Evolver, Famine, Follower, + LingeringPresence, Glitch, God, Hater, @@ -874,15 +841,14 @@ public enum CustomRoles Pursuer, Pyromaniac, Quizmaster, - Revenant, Revolutionist, Romantic, RuthlessRomantic, SchrodingersCat, Seeker, SerialKiller, + Summoner, Shaman, - Shocker, Shroud, Sidekick, Solsticer, @@ -918,6 +884,7 @@ public enum CustomRoles // Add-ons Admired, + Allergic, Antidote, Autopsy, Avanger, @@ -941,6 +908,7 @@ public enum CustomRoles Flash, Fool, Fragile, + FadingLight, Ghoul, Glow, Gravestone, @@ -980,6 +948,7 @@ public enum CustomRoles Sloth, Soulless, Statue, + Summoned, Stubborn, Susceptible, Swift, @@ -994,10 +963,10 @@ public enum CustomRoles VoidBallot, Watcher, Workhorse, - Youtuber + Youtuber, + } //WinData -[Obfuscation(Exclude = true)] public enum CustomWinner { Draw = -1, @@ -1062,15 +1031,16 @@ public enum CustomWinner NiceMini = CustomRoles.Mini, Doppelganger = CustomRoles.Doppelganger, Solsticer = CustomRoles.Solsticer, - Shocker = CustomRoles.Shocker, Apocalypse = CustomRoles.Apocalypse, + Random = 581, } -[Obfuscation(Exclude = true)] public enum AdditionalWinners { None = -1, Lovers = CustomRoles.Lovers, Opportunist = CustomRoles.Opportunist, + Randomizer = CustomRoles.Randomizer, + Evolver = CustomRoles.Evolver, Executioner = CustomRoles.Executioner, Lawyer = CustomRoles.Lawyer, Hater = CustomRoles.Hater, @@ -1094,7 +1064,6 @@ public enum AdditionalWinners // NiceMini = CustomRoles.NiceMini, // Baker = CustomRoles.Baker, } -[Obfuscation(Exclude = true)] public enum SuffixModes { None = 0, @@ -1107,7 +1076,6 @@ public enum SuffixModes NoAndroidPlz, AutoHost } -[Obfuscation(Exclude = true)] public enum VoteMode { Default, @@ -1115,7 +1083,6 @@ public enum VoteMode SelfVote, Skip } -[Obfuscation(Exclude = true)] public enum TieMode { Default, diff --git a/summoner.cs b/summoner.cs new file mode 100644 index 000000000..9155fe5a6 --- /dev/null +++ b/summoner.cs @@ -0,0 +1,465 @@ +using TOHE.Roles.Core; +using UnityEngine; +using UnityEngine.Playables; +using static TOHE.Options; +using static TOHE.Utils; + +namespace TOHE.Roles.Neutral; + +internal class Summoner : RoleBase +{ + //===========================SETUP================================\\ + private const int Id = 92000; + private static readonly HashSet playerIdList = new(); // Initialize properly + public static bool HasEnabled => playerIdList.Any(); + public override bool IsDesyncRole => true; + public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; + public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralChaos; + //================================================================\\ + + private static OptionItem ReviveDelayOption; + private static OptionItem DeathTimerOption; + private static OptionItem KnowSummonedRoles; + private static OptionItem KillCooldownOption; + private static readonly Dictionary originalAddOns)> SavedStates = new(); + private static readonly Dictionary SummonedTimers = new(); + private static readonly Dictionary SummonedHealth = new(); + private static List<(PlayerControl, float)> PendingRevives = new(); + private static readonly Dictionary LastUpdateTimes = new(); + + private bool HasSummonedThisMeeting = false; + + public override void SetupCustomOption() + { + SetupRoleOptions(Id, TabGroup.NeutralRoles, CustomRoles.Summoner); + + // Revive Delay + ReviveDelayOption = FloatOptionItem.Create(Id + 10, "Revive Delay", new(1f, 30f, 1f), 5f, TabGroup.NeutralRoles, false) + .SetParent(CustomRoleSpawnChances[CustomRoles.Summoner]) + .SetValueFormat(OptionFormat.Seconds); + + // Death Timer + DeathTimerOption = FloatOptionItem.Create(Id + 11, "Summoned Player Duration", new(5f, 120f, 5f), 30f, TabGroup.NeutralRoles, false) + .SetParent(CustomRoleSpawnChances[CustomRoles.Summoner]) + .SetValueFormat(OptionFormat.Seconds); + + // Kill Cooldown + KillCooldownOption = FloatOptionItem.Create(Id + 12, "Summoned Player Kill Cooldown", new(5f, 60f, 1f), 15f, TabGroup.NeutralRoles, false) + .SetParent(CustomRoleSpawnChances[CustomRoles.Summoner]) + .SetValueFormat(OptionFormat.Seconds); + + KnowSummonedRoles = BooleanOptionItem.Create(Id + 13, "Know Summoner/Summoned Roles", true, TabGroup.NeutralRoles, false) + .SetParent(CustomRoleSpawnChances[CustomRoles.Summoner]); + } + + public override void Add(byte playerId) + { + base.Add(playerId); + CustomRoleManager.OnFixedUpdateOthers.Add(OnFixedUpdate); + var playerState = Main.PlayerStates[playerId]; + playerState.SetMainRole(CustomRoles.Summoner); + playerState.IsSummoner = true; + } + + public override void Init() + { + SummonedHealth.Clear(); + LastUpdateTimes.Clear(); + } + + public static bool SummonerCheckMsg(PlayerControl pc, string msg, bool isUI = false, bool isSystemMessage = false) + { + if (isSystemMessage || pc == null || !AmongUsClient.Instance.AmHost) return false; // Skip if system message or not host + if (!GameStates.IsMeeting || pc == null || GameStates.IsExilling) return false; // Only during meetings + if (!pc.Is(CustomRoles.Summoner) || !(pc.GetRoleClass() is Summoner summonerInstance)) return false; + + msg = msg.ToLower().Trim(); + Logger.Info($"Received command: {msg} from {pc.PlayerId}, Host: {AmongUsClient.Instance.AmHost}", "Summoner"); + + if (!CheckCommand(ref msg, "summon")) return false; + + if (!pc.IsAlive()) + { + Logger.Warn("Summoner is dead and cannot use commands.", "Summoner"); + return true; + } + + if (!byte.TryParse(msg, out var targetId)) + { + Logger.Warn("Invalid target ID for /summon command.", "Summoner"); + pc.Notify("Invalid target ID! Use /summon "); + return true; + } + + PlayerControl targetPlayer = null; + foreach (var player in PlayerControl.AllPlayerControls) + { + if (player.PlayerId == targetId) + { + targetPlayer = player; + break; // Exit the loop once the player is found + } + } + + if (targetPlayer == null || targetPlayer.IsAlive()) + { + Logger.Warn("Target player is invalid or alive.", "Summoner"); + pc.Notify("Target is invalid or not dead."); + return true; + } + + if (summonerInstance.HasSummonedThisMeeting) + { + Logger.Warn("Summoner has already summoned a player this meeting.", "Summoner"); + pc.Notify("You can only summon one player per meeting."); + return true; + } + + summonerInstance.RevivePlayer(targetPlayer); + summonerInstance.HasSummonedThisMeeting = true; + + Logger.Info($"Summoner {pc.PlayerId} has summoned player {targetPlayer.PlayerId}.", "Summoner"); + + return true; // Indicate the command was handled and suppress the message + } + + + public static bool CheckCommand(ref string msg, string command) + { + var comList = command.Split('|'); + for (int i = 0; i < comList.Length; i++) + { + if (msg.StartsWith("/" + comList[i])) + { + msg = msg.Replace("/" + comList[i], string.Empty).Trim(); + return true; + } + } + return false; + } + + public void RevivePlayer(PlayerControl targetPlayer) + { + if (targetPlayer == null || targetPlayer.Data == null || !targetPlayer.Data.IsDead) + { + Logger.Warn($"RevivePlayer: Invalid target or player is not dead.", "Summoner"); + return; + } + + float reviveDelay = ReviveDelayOption?.GetFloat() ?? 5f; + + new LateTask(() => + { + if (targetPlayer.IsAlive()) + { + Logger.Info($"Player {targetPlayer.PlayerId} is already alive. Revive skipped.", "Summoner"); + return; + } + + // Handle players already in the Summoned role + if (targetPlayer.Is(CustomRoles.Summoned)) + { + Summoned.RefreshTimer(targetPlayer.PlayerId); + Logger.Info($"Player {targetPlayer.PlayerId} re-summoned with a refreshed timer.", "Summoner"); + return; + } + + // Save current role and add-ons + SaveRoleAndAddons(targetPlayer); + + // Reset sub-roles and assign Summoned role + targetPlayer.ResetSubRoles(); // Clear all sub-roles and add-ons + targetPlayer.RpcSetCustomRole(CustomRoles.Summoned); + + Logger.Info($"Player {targetPlayer.PlayerId} summoned and their role was saved.", "Summoner"); + + }, reviveDelay, "SummonerRevive"); + } + + private void SaveRoleAndAddons(PlayerControl player) + { + var originalRole = player.GetCustomRole(); + var originalAddons = player.GetAddOns(); + SavedStates[player.PlayerId] = (originalRole, originalAddons); + Logger.Info($"Player {player.PlayerId}'s role and add-ons saved.", "Summoner"); + } + + private void RestoreRoleAndAddons(PlayerControl player) + { + if (SavedStates.TryGetValue(player.PlayerId, out var state)) + { + // Use RpcSetRole to restore the role + player.RpcSetRole((AmongUs.GameOptions.RoleTypes)state.originalRole); + + // Restore saved add-ons + foreach (var addon in state.originalAddOns) + { + player.AddAddOn(addon); + } + + SavedStates.Remove(player.PlayerId); + Logger.Info($"Player {player.PlayerId} restored to their original role and add-ons.", "Summoner"); + } + } + + public void OnRoleRemove(byte playerId) + { + foreach (var summonedId in SavedStates.Keys.ToList()) + { + var summonedPlayer = PlayerControl.GetPlayerById(summonedId); + if (summonedPlayer != null && summonedPlayer.IsAlive()) + { + summonedPlayer.RpcExileV2(); // Kill the summoned player + RestoreRoleAndAddons(summonedPlayer); // Restore original role and add-ons + } + } + + base.OnRoleRemove(playerId); + } +} + + public static bool CheckSummoned(PlayerControl player) + { + return player.Is(CustomRoles.Summoned); // Replace with your Summoned role check logic + } + + public override void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo bodyInfo) + { + foreach (var player in PlayerControl.AllPlayerControls) + { + if (player.HasSpecificSubRole(CustomRoles.Summoned) && player.IsAlive()) + { + + + // Trigger Summoned's custom death mechanics + KillSummonedPlayer(player); + } + } + } + + + + + + private void PerformRevive(PlayerControl targetPlayer, float reviveDelay) + { + if (targetPlayer.IsAlive()) return; + + new LateTask(() => + { + if (targetPlayer.IsAlive()) return; + + // Handle players already in the Summoned role + if (targetPlayer.Is(CustomRoles.Summoned)) + { + Summoned.RefreshTimer(targetPlayer.PlayerId); + Logger.Info($"Player {targetPlayer.PlayerId} re-summoned with a refreshed timer.", "Summoner"); + return; + } + + // Save the player's current role and replace with Summoned + SaveRoleAndAddons(targetPlayer); + targetPlayer.RpcSetCustomRole(CustomRoles.Summoned); + Logger.Info($"Player {targetPlayer.PlayerId} summoned and original role saved.", "Summoner"); + }, reviveDelay, "SummonerRevive"); + } + + + + + + + + + private void NotifySummonerAndSummoned(string message) + { + foreach (var player in PlayerControl.AllPlayerControls) + { + if (player.Is(CustomRoles.Summoner) || player.HasSpecificSubRole(CustomRoles.Summoned)) + { + Utils.SendMessage(message, player.PlayerId); + } + } + } + + private void StartDeathTimer(PlayerControl targetPlayer) + { + int deathTimer = Mathf.CeilToInt(DeathTimerOption.GetFloat()); + SummonedHealth[targetPlayer.PlayerId] = deathTimer; + LastUpdateTimes[targetPlayer.PlayerId] = Utils.GetTimeStamp(); + + Logger.Info($"Player {targetPlayer.GetRealName()} has been given a death timer of {deathTimer} seconds.", "Summoner"); + + // Notify the summoned player + NotifySummonedHealth(targetPlayer); + } + + + private void OnFixedUpdate(PlayerControl player, bool lowLoad, long nowTime) + { + if (lowLoad || GameStates.IsMeeting) return; + + foreach (var (playerId, health) in SummonedHealth.ToList()) // Avoid modification issues during iteration + { + PlayerControl targetPlayer = null; + + // Find the player with the given playerId + foreach (var p in PlayerControl.AllPlayerControls) + { + if (p.PlayerId == playerId) + { + targetPlayer = p; + break; + } + } + + if (targetPlayer == null) + { + ResetHealth(playerId); // Clean up invalid players + continue; + } + + // Skip timer updates if the player is dead + if (targetPlayer.Data.IsDead) + { + Logger.Info($"Skipping timer update for dead summoned player {playerId}.", "Summoner"); + continue; + } + + // Get the current time + var currentTime = (long)(System.DateTime.UtcNow - new System.DateTime(1970, 1, 1, 0, 0, 0, System.DateTimeKind.Utc)).TotalSeconds; + + if (!LastUpdateTimes.TryGetValue(playerId, out var lastUpdateTime)) + { + lastUpdateTime = currentTime; + } + + // Calculate time difference and update health + var deltaTime = currentTime - lastUpdateTime; + SummonedHealth[playerId] = Mathf.Clamp(SummonedHealth[playerId] - deltaTime, 0f, DeathTimerOption.GetFloat()); + + // Apply visual updates for health + NotifySummonedHealth(targetPlayer); + + if (SummonedHealth[playerId] <= 0) + { + KillSummonedPlayer(targetPlayer); + SummonedHealth.Remove(playerId); + LastUpdateTimes.Remove(playerId); + } + + // Update the last timestamp + LastUpdateTimes[playerId] = currentTime; + } + } + + public static bool KnowRole(PlayerControl player, PlayerControl target) + { + // Summoner can see Summoned, Summoned can see Summoner + if (player.Is(CustomRoles.Summoner) && target.HasSpecificSubRole(CustomRoles.Summoned)) return true; + if (player.HasSpecificSubRole(CustomRoles.Summoned) && target.Is(CustomRoles.Summoner)) return true; + + // Summoned can see other Summoned players if enabled + if (KnowSummonedRoles.GetBool() && + player.HasSpecificSubRole(CustomRoles.Summoned) && + target.HasSpecificSubRole(CustomRoles.Summoned)) + return true; + + return false; + } + + + private void NotifySummonedHealth(PlayerControl player) + { + if (player.Is(CustomRoles.Summoner) || player.HasSpecificSubRole(CustomRoles.Summoned)) + { + // Notify only Summoner and Summoned players + var health = Mathf.RoundToInt(SummonedHealth[player.PlayerId]); + player.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Summoned), $"Time Remaining: {health}s")); + } + } + + private static void KillSummonedPlayer(PlayerControl target) + { + target.SetDeathReason(PlayerState.DeathReason.SummonedExpired); + target.RpcExileV2(); // Kill the player without leaving a body + Logger.Info($"{target.GetRealName()} has died because their timer ran out.", "Summoner"); + } + + private void ResetHealth(byte playerId) + { + SummonedHealth.Remove(playerId); + LastUpdateTimes.Remove(playerId); + } + + + public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) + { + if (killer.Is(CustomRoles.Summoned) && (target.Is(CustomRoles.Summoner) || target.HasSpecificSubRole(CustomRoles.Summoned))) + { + string errorMessage = "You cannot kill the Summoner or other summoned players!"; + killer.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Summoner), errorMessage)); + return false; // Cancel the kill + } + + return true; // Allow other kills + } + + public override void AfterMeetingTasks() + { + base.AfterMeetingTasks(); + + // Reset Summoning flag to allow reviving in the next meeting + HasSummonedThisMeeting = false; + + // Handle pending revives queued during the meeting + if (PendingRevives.Count > 0) + { + foreach (var (player, delay) in PendingRevives.ToList()) + { + PerformRevive(player, delay); + } + PendingRevives.Clear(); + } + + // Process Summoned players + foreach (var player in PlayerControl.AllPlayerControls) + { + if (SummonedTimers.TryGetValue(player.PlayerId, out var remainingTime)) + { + if (player.Data.IsDead) + { + Logger.Info($"Player {player.GetRealName()} with remaining time will not automatically revive. Summoner must manually summon them again.", "Summoner"); + SummonedTimers.Remove(player.PlayerId); // Remove the expired timer + } + else + { + Logger.Warn($"Player {player.GetRealName()} is alive but had a timer. Timer will continue.", "Summoner"); + } + } + } + } + + + + + + public override string GetLowerTextOthers(PlayerControl seer, PlayerControl target = null, bool isForMeeting = false, bool isForHud = false) + { + if (target == null || !isForHud) return string.Empty; + + // Check if roles should be visible + if (KnowRole(seer, target)) + { + if (target.Is(CustomRoles.Summoner)) + return ColorString(GetRoleColor(CustomRoles.Summoner), "Summoner"); + if (target.HasSpecificSubRole(CustomRoles.Summoned)) + return ColorString(GetRoleColor(CustomRoles.Summoned), "Summoned"); + } + + // Default behavior + return string.Empty; + } +} + + From 25751c748fc522a8f0e25d20aeef0f612208cc21 Mon Sep 17 00:00:00 2001 From: frisk Date: Mon, 6 Jan 2025 10:58:21 -0500 Subject: [PATCH 06/11] randomizer --- Modules/ExtendedPlayerControl.cs | 4 +- Patches/ChatCommandPatch.cs | 4 +- Summoned.cs | 1 - TOHE - Backup.csproj | 50 ---- summoner.cs | 465 ------------------------------- 5 files changed, 4 insertions(+), 520 deletions(-) delete mode 100644 Summoned.cs delete mode 100644 TOHE - Backup.csproj delete mode 100644 summoner.cs diff --git a/Modules/ExtendedPlayerControl.cs b/Modules/ExtendedPlayerControl.cs index 913878997..882505c68 100644 --- a/Modules/ExtendedPlayerControl.cs +++ b/Modules/ExtendedPlayerControl.cs @@ -1290,7 +1290,7 @@ public static bool KnowRoleTarget(PlayerControl seer, PlayerControl target) if (Workaholic.OthersKnowWorka(target)) return true; if (Jackal.JackalKnowRole(seer, target)) return true; if (Cultist.KnowRole(seer, target)) return true; - if (Summoner.KnowRole(seer, target)) return true; + if (Infectious.KnowRole(seer, target)) return true; if (Virus.KnowRole(seer, target)) return true; @@ -1336,7 +1336,7 @@ public static bool KnowSubRoleTarget(PlayerControl seer, PlayerControl target) if (Admirer.HasEnabled && Admirer.CheckKnowRoleTarget(seer, target)) return true; if (Cultist.HasEnabled && Cultist.KnowRole(seer, target)) return true; - if (Summoner.HasEnabled && Summoner.KnowRole(seer, target)) return true; + if (Infectious.HasEnabled && Infectious.KnowRole(seer, target)) return true; if (Virus.HasEnabled && Virus.KnowRole(seer, target)) return true; if (Jackal.HasEnabled) diff --git a/Patches/ChatCommandPatch.cs b/Patches/ChatCommandPatch.cs index 9651787ce..69d6318eb 100644 --- a/Patches/ChatCommandPatch.cs +++ b/Patches/ChatCommandPatch.cs @@ -65,7 +65,7 @@ public static bool Prefix(ChatController __instance) if (Inspector.InspectCheckMsg(PlayerControl.LocalPlayer, text)) goto Canceled; if (Pirate.DuelCheckMsg(PlayerControl.LocalPlayer, text)) goto Canceled; if (Evolver.EvolverCheckMsg(PlayerControl.LocalPlayer, text)) goto Canceled; - if (Summoner.SummonerCheckMsg(PlayerControl.LocalPlayer, text)) goto Canceled; + if (PlayerControl.LocalPlayer.GetRoleClass() is Councillor cl && cl.MurderMsg(PlayerControl.LocalPlayer, text)) goto Canceled; if (Nemesis.NemesisMsgCheck(PlayerControl.LocalPlayer, text)) goto Canceled; if (Retributionist.RetributionistMsgCheck(PlayerControl.LocalPlayer, text)) goto Canceled; @@ -2043,7 +2043,7 @@ public static void OnReceiveChat(PlayerControl player, string text, out bool can if (Nemesis.NemesisMsgCheck(player, text)) { Logger.Info($"Is Nemesis Revenge command", "OnReceiveChat"); return; } if (Retributionist.RetributionistMsgCheck(player, text)) { Logger.Info($"Is Retributionist Revenge command", "OnReceiveChat"); return; } if (Evolver.EvolverCheckMsg(player, text)) { canceled = true; Logger.Info($"Is Evolver command", "OnReceiveChat"); return; } - if (Summoner.SummonerCheckMsg(player, text)) { canceled = true; Logger.Info($"Command handled for Summoner {player.PlayerId}.", "OnReceiveChat"); return;} + diff --git a/Summoned.cs b/Summoned.cs deleted file mode 100644 index 5f282702b..000000000 --- a/Summoned.cs +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/TOHE - Backup.csproj b/TOHE - Backup.csproj deleted file mode 100644 index 0d335c27e..000000000 --- a/TOHE - Backup.csproj +++ /dev/null @@ -1,50 +0,0 @@ - - - net6.0 - false - false - false - Town Of Host Enhanced - Moe - preview - - Debug;Release;Canary - true - True - - - - - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - runtime; compile; build; native; contentfiles; analyzers; buildtransitive - all - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - - - - - - \ No newline at end of file diff --git a/summoner.cs b/summoner.cs deleted file mode 100644 index 9155fe5a6..000000000 --- a/summoner.cs +++ /dev/null @@ -1,465 +0,0 @@ -using TOHE.Roles.Core; -using UnityEngine; -using UnityEngine.Playables; -using static TOHE.Options; -using static TOHE.Utils; - -namespace TOHE.Roles.Neutral; - -internal class Summoner : RoleBase -{ - //===========================SETUP================================\\ - private const int Id = 92000; - private static readonly HashSet playerIdList = new(); // Initialize properly - public static bool HasEnabled => playerIdList.Any(); - public override bool IsDesyncRole => true; - public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; - public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralChaos; - //================================================================\\ - - private static OptionItem ReviveDelayOption; - private static OptionItem DeathTimerOption; - private static OptionItem KnowSummonedRoles; - private static OptionItem KillCooldownOption; - private static readonly Dictionary originalAddOns)> SavedStates = new(); - private static readonly Dictionary SummonedTimers = new(); - private static readonly Dictionary SummonedHealth = new(); - private static List<(PlayerControl, float)> PendingRevives = new(); - private static readonly Dictionary LastUpdateTimes = new(); - - private bool HasSummonedThisMeeting = false; - - public override void SetupCustomOption() - { - SetupRoleOptions(Id, TabGroup.NeutralRoles, CustomRoles.Summoner); - - // Revive Delay - ReviveDelayOption = FloatOptionItem.Create(Id + 10, "Revive Delay", new(1f, 30f, 1f), 5f, TabGroup.NeutralRoles, false) - .SetParent(CustomRoleSpawnChances[CustomRoles.Summoner]) - .SetValueFormat(OptionFormat.Seconds); - - // Death Timer - DeathTimerOption = FloatOptionItem.Create(Id + 11, "Summoned Player Duration", new(5f, 120f, 5f), 30f, TabGroup.NeutralRoles, false) - .SetParent(CustomRoleSpawnChances[CustomRoles.Summoner]) - .SetValueFormat(OptionFormat.Seconds); - - // Kill Cooldown - KillCooldownOption = FloatOptionItem.Create(Id + 12, "Summoned Player Kill Cooldown", new(5f, 60f, 1f), 15f, TabGroup.NeutralRoles, false) - .SetParent(CustomRoleSpawnChances[CustomRoles.Summoner]) - .SetValueFormat(OptionFormat.Seconds); - - KnowSummonedRoles = BooleanOptionItem.Create(Id + 13, "Know Summoner/Summoned Roles", true, TabGroup.NeutralRoles, false) - .SetParent(CustomRoleSpawnChances[CustomRoles.Summoner]); - } - - public override void Add(byte playerId) - { - base.Add(playerId); - CustomRoleManager.OnFixedUpdateOthers.Add(OnFixedUpdate); - var playerState = Main.PlayerStates[playerId]; - playerState.SetMainRole(CustomRoles.Summoner); - playerState.IsSummoner = true; - } - - public override void Init() - { - SummonedHealth.Clear(); - LastUpdateTimes.Clear(); - } - - public static bool SummonerCheckMsg(PlayerControl pc, string msg, bool isUI = false, bool isSystemMessage = false) - { - if (isSystemMessage || pc == null || !AmongUsClient.Instance.AmHost) return false; // Skip if system message or not host - if (!GameStates.IsMeeting || pc == null || GameStates.IsExilling) return false; // Only during meetings - if (!pc.Is(CustomRoles.Summoner) || !(pc.GetRoleClass() is Summoner summonerInstance)) return false; - - msg = msg.ToLower().Trim(); - Logger.Info($"Received command: {msg} from {pc.PlayerId}, Host: {AmongUsClient.Instance.AmHost}", "Summoner"); - - if (!CheckCommand(ref msg, "summon")) return false; - - if (!pc.IsAlive()) - { - Logger.Warn("Summoner is dead and cannot use commands.", "Summoner"); - return true; - } - - if (!byte.TryParse(msg, out var targetId)) - { - Logger.Warn("Invalid target ID for /summon command.", "Summoner"); - pc.Notify("Invalid target ID! Use /summon "); - return true; - } - - PlayerControl targetPlayer = null; - foreach (var player in PlayerControl.AllPlayerControls) - { - if (player.PlayerId == targetId) - { - targetPlayer = player; - break; // Exit the loop once the player is found - } - } - - if (targetPlayer == null || targetPlayer.IsAlive()) - { - Logger.Warn("Target player is invalid or alive.", "Summoner"); - pc.Notify("Target is invalid or not dead."); - return true; - } - - if (summonerInstance.HasSummonedThisMeeting) - { - Logger.Warn("Summoner has already summoned a player this meeting.", "Summoner"); - pc.Notify("You can only summon one player per meeting."); - return true; - } - - summonerInstance.RevivePlayer(targetPlayer); - summonerInstance.HasSummonedThisMeeting = true; - - Logger.Info($"Summoner {pc.PlayerId} has summoned player {targetPlayer.PlayerId}.", "Summoner"); - - return true; // Indicate the command was handled and suppress the message - } - - - public static bool CheckCommand(ref string msg, string command) - { - var comList = command.Split('|'); - for (int i = 0; i < comList.Length; i++) - { - if (msg.StartsWith("/" + comList[i])) - { - msg = msg.Replace("/" + comList[i], string.Empty).Trim(); - return true; - } - } - return false; - } - - public void RevivePlayer(PlayerControl targetPlayer) - { - if (targetPlayer == null || targetPlayer.Data == null || !targetPlayer.Data.IsDead) - { - Logger.Warn($"RevivePlayer: Invalid target or player is not dead.", "Summoner"); - return; - } - - float reviveDelay = ReviveDelayOption?.GetFloat() ?? 5f; - - new LateTask(() => - { - if (targetPlayer.IsAlive()) - { - Logger.Info($"Player {targetPlayer.PlayerId} is already alive. Revive skipped.", "Summoner"); - return; - } - - // Handle players already in the Summoned role - if (targetPlayer.Is(CustomRoles.Summoned)) - { - Summoned.RefreshTimer(targetPlayer.PlayerId); - Logger.Info($"Player {targetPlayer.PlayerId} re-summoned with a refreshed timer.", "Summoner"); - return; - } - - // Save current role and add-ons - SaveRoleAndAddons(targetPlayer); - - // Reset sub-roles and assign Summoned role - targetPlayer.ResetSubRoles(); // Clear all sub-roles and add-ons - targetPlayer.RpcSetCustomRole(CustomRoles.Summoned); - - Logger.Info($"Player {targetPlayer.PlayerId} summoned and their role was saved.", "Summoner"); - - }, reviveDelay, "SummonerRevive"); - } - - private void SaveRoleAndAddons(PlayerControl player) - { - var originalRole = player.GetCustomRole(); - var originalAddons = player.GetAddOns(); - SavedStates[player.PlayerId] = (originalRole, originalAddons); - Logger.Info($"Player {player.PlayerId}'s role and add-ons saved.", "Summoner"); - } - - private void RestoreRoleAndAddons(PlayerControl player) - { - if (SavedStates.TryGetValue(player.PlayerId, out var state)) - { - // Use RpcSetRole to restore the role - player.RpcSetRole((AmongUs.GameOptions.RoleTypes)state.originalRole); - - // Restore saved add-ons - foreach (var addon in state.originalAddOns) - { - player.AddAddOn(addon); - } - - SavedStates.Remove(player.PlayerId); - Logger.Info($"Player {player.PlayerId} restored to their original role and add-ons.", "Summoner"); - } - } - - public void OnRoleRemove(byte playerId) - { - foreach (var summonedId in SavedStates.Keys.ToList()) - { - var summonedPlayer = PlayerControl.GetPlayerById(summonedId); - if (summonedPlayer != null && summonedPlayer.IsAlive()) - { - summonedPlayer.RpcExileV2(); // Kill the summoned player - RestoreRoleAndAddons(summonedPlayer); // Restore original role and add-ons - } - } - - base.OnRoleRemove(playerId); - } -} - - public static bool CheckSummoned(PlayerControl player) - { - return player.Is(CustomRoles.Summoned); // Replace with your Summoned role check logic - } - - public override void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo bodyInfo) - { - foreach (var player in PlayerControl.AllPlayerControls) - { - if (player.HasSpecificSubRole(CustomRoles.Summoned) && player.IsAlive()) - { - - - // Trigger Summoned's custom death mechanics - KillSummonedPlayer(player); - } - } - } - - - - - - private void PerformRevive(PlayerControl targetPlayer, float reviveDelay) - { - if (targetPlayer.IsAlive()) return; - - new LateTask(() => - { - if (targetPlayer.IsAlive()) return; - - // Handle players already in the Summoned role - if (targetPlayer.Is(CustomRoles.Summoned)) - { - Summoned.RefreshTimer(targetPlayer.PlayerId); - Logger.Info($"Player {targetPlayer.PlayerId} re-summoned with a refreshed timer.", "Summoner"); - return; - } - - // Save the player's current role and replace with Summoned - SaveRoleAndAddons(targetPlayer); - targetPlayer.RpcSetCustomRole(CustomRoles.Summoned); - Logger.Info($"Player {targetPlayer.PlayerId} summoned and original role saved.", "Summoner"); - }, reviveDelay, "SummonerRevive"); - } - - - - - - - - - private void NotifySummonerAndSummoned(string message) - { - foreach (var player in PlayerControl.AllPlayerControls) - { - if (player.Is(CustomRoles.Summoner) || player.HasSpecificSubRole(CustomRoles.Summoned)) - { - Utils.SendMessage(message, player.PlayerId); - } - } - } - - private void StartDeathTimer(PlayerControl targetPlayer) - { - int deathTimer = Mathf.CeilToInt(DeathTimerOption.GetFloat()); - SummonedHealth[targetPlayer.PlayerId] = deathTimer; - LastUpdateTimes[targetPlayer.PlayerId] = Utils.GetTimeStamp(); - - Logger.Info($"Player {targetPlayer.GetRealName()} has been given a death timer of {deathTimer} seconds.", "Summoner"); - - // Notify the summoned player - NotifySummonedHealth(targetPlayer); - } - - - private void OnFixedUpdate(PlayerControl player, bool lowLoad, long nowTime) - { - if (lowLoad || GameStates.IsMeeting) return; - - foreach (var (playerId, health) in SummonedHealth.ToList()) // Avoid modification issues during iteration - { - PlayerControl targetPlayer = null; - - // Find the player with the given playerId - foreach (var p in PlayerControl.AllPlayerControls) - { - if (p.PlayerId == playerId) - { - targetPlayer = p; - break; - } - } - - if (targetPlayer == null) - { - ResetHealth(playerId); // Clean up invalid players - continue; - } - - // Skip timer updates if the player is dead - if (targetPlayer.Data.IsDead) - { - Logger.Info($"Skipping timer update for dead summoned player {playerId}.", "Summoner"); - continue; - } - - // Get the current time - var currentTime = (long)(System.DateTime.UtcNow - new System.DateTime(1970, 1, 1, 0, 0, 0, System.DateTimeKind.Utc)).TotalSeconds; - - if (!LastUpdateTimes.TryGetValue(playerId, out var lastUpdateTime)) - { - lastUpdateTime = currentTime; - } - - // Calculate time difference and update health - var deltaTime = currentTime - lastUpdateTime; - SummonedHealth[playerId] = Mathf.Clamp(SummonedHealth[playerId] - deltaTime, 0f, DeathTimerOption.GetFloat()); - - // Apply visual updates for health - NotifySummonedHealth(targetPlayer); - - if (SummonedHealth[playerId] <= 0) - { - KillSummonedPlayer(targetPlayer); - SummonedHealth.Remove(playerId); - LastUpdateTimes.Remove(playerId); - } - - // Update the last timestamp - LastUpdateTimes[playerId] = currentTime; - } - } - - public static bool KnowRole(PlayerControl player, PlayerControl target) - { - // Summoner can see Summoned, Summoned can see Summoner - if (player.Is(CustomRoles.Summoner) && target.HasSpecificSubRole(CustomRoles.Summoned)) return true; - if (player.HasSpecificSubRole(CustomRoles.Summoned) && target.Is(CustomRoles.Summoner)) return true; - - // Summoned can see other Summoned players if enabled - if (KnowSummonedRoles.GetBool() && - player.HasSpecificSubRole(CustomRoles.Summoned) && - target.HasSpecificSubRole(CustomRoles.Summoned)) - return true; - - return false; - } - - - private void NotifySummonedHealth(PlayerControl player) - { - if (player.Is(CustomRoles.Summoner) || player.HasSpecificSubRole(CustomRoles.Summoned)) - { - // Notify only Summoner and Summoned players - var health = Mathf.RoundToInt(SummonedHealth[player.PlayerId]); - player.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Summoned), $"Time Remaining: {health}s")); - } - } - - private static void KillSummonedPlayer(PlayerControl target) - { - target.SetDeathReason(PlayerState.DeathReason.SummonedExpired); - target.RpcExileV2(); // Kill the player without leaving a body - Logger.Info($"{target.GetRealName()} has died because their timer ran out.", "Summoner"); - } - - private void ResetHealth(byte playerId) - { - SummonedHealth.Remove(playerId); - LastUpdateTimes.Remove(playerId); - } - - - public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) - { - if (killer.Is(CustomRoles.Summoned) && (target.Is(CustomRoles.Summoner) || target.HasSpecificSubRole(CustomRoles.Summoned))) - { - string errorMessage = "You cannot kill the Summoner or other summoned players!"; - killer.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Summoner), errorMessage)); - return false; // Cancel the kill - } - - return true; // Allow other kills - } - - public override void AfterMeetingTasks() - { - base.AfterMeetingTasks(); - - // Reset Summoning flag to allow reviving in the next meeting - HasSummonedThisMeeting = false; - - // Handle pending revives queued during the meeting - if (PendingRevives.Count > 0) - { - foreach (var (player, delay) in PendingRevives.ToList()) - { - PerformRevive(player, delay); - } - PendingRevives.Clear(); - } - - // Process Summoned players - foreach (var player in PlayerControl.AllPlayerControls) - { - if (SummonedTimers.TryGetValue(player.PlayerId, out var remainingTime)) - { - if (player.Data.IsDead) - { - Logger.Info($"Player {player.GetRealName()} with remaining time will not automatically revive. Summoner must manually summon them again.", "Summoner"); - SummonedTimers.Remove(player.PlayerId); // Remove the expired timer - } - else - { - Logger.Warn($"Player {player.GetRealName()} is alive but had a timer. Timer will continue.", "Summoner"); - } - } - } - } - - - - - - public override string GetLowerTextOthers(PlayerControl seer, PlayerControl target = null, bool isForMeeting = false, bool isForHud = false) - { - if (target == null || !isForHud) return string.Empty; - - // Check if roles should be visible - if (KnowRole(seer, target)) - { - if (target.Is(CustomRoles.Summoner)) - return ColorString(GetRoleColor(CustomRoles.Summoner), "Summoner"); - if (target.HasSpecificSubRole(CustomRoles.Summoned)) - return ColorString(GetRoleColor(CustomRoles.Summoned), "Summoned"); - } - - // Default behavior - return string.Empty; - } -} - - From 5f3c67d3ac22c72e0b11177a8f3114fc01672423 Mon Sep 17 00:00:00 2001 From: frisk11123 Date: Mon, 6 Jan 2025 11:43:57 -0500 Subject: [PATCH 07/11] Delete TOHE - Backup.csproj --- TOHE - Backup.csproj | 50 -------------------------------------------- 1 file changed, 50 deletions(-) delete mode 100644 TOHE - Backup.csproj diff --git a/TOHE - Backup.csproj b/TOHE - Backup.csproj deleted file mode 100644 index 0d335c27e..000000000 --- a/TOHE - Backup.csproj +++ /dev/null @@ -1,50 +0,0 @@ - - - net6.0 - false - false - false - Town Of Host Enhanced - Moe - preview - - Debug;Release;Canary - true - True - - - - - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - runtime; compile; build; native; contentfiles; analyzers; buildtransitive - all - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - - - - - - \ No newline at end of file From aee660f34e61e5c47cc8cd9f0b6b84b55649a883 Mon Sep 17 00:00:00 2001 From: frisk11123 Date: Mon, 6 Jan 2025 11:44:14 -0500 Subject: [PATCH 08/11] Delete summoner.cs --- summoner.cs | 465 ---------------------------------------------------- 1 file changed, 465 deletions(-) delete mode 100644 summoner.cs diff --git a/summoner.cs b/summoner.cs deleted file mode 100644 index 9155fe5a6..000000000 --- a/summoner.cs +++ /dev/null @@ -1,465 +0,0 @@ -using TOHE.Roles.Core; -using UnityEngine; -using UnityEngine.Playables; -using static TOHE.Options; -using static TOHE.Utils; - -namespace TOHE.Roles.Neutral; - -internal class Summoner : RoleBase -{ - //===========================SETUP================================\\ - private const int Id = 92000; - private static readonly HashSet playerIdList = new(); // Initialize properly - public static bool HasEnabled => playerIdList.Any(); - public override bool IsDesyncRole => true; - public override CustomRoles ThisRoleBase => CustomRoles.Crewmate; - public override Custom_RoleType ThisRoleType => Custom_RoleType.NeutralChaos; - //================================================================\\ - - private static OptionItem ReviveDelayOption; - private static OptionItem DeathTimerOption; - private static OptionItem KnowSummonedRoles; - private static OptionItem KillCooldownOption; - private static readonly Dictionary originalAddOns)> SavedStates = new(); - private static readonly Dictionary SummonedTimers = new(); - private static readonly Dictionary SummonedHealth = new(); - private static List<(PlayerControl, float)> PendingRevives = new(); - private static readonly Dictionary LastUpdateTimes = new(); - - private bool HasSummonedThisMeeting = false; - - public override void SetupCustomOption() - { - SetupRoleOptions(Id, TabGroup.NeutralRoles, CustomRoles.Summoner); - - // Revive Delay - ReviveDelayOption = FloatOptionItem.Create(Id + 10, "Revive Delay", new(1f, 30f, 1f), 5f, TabGroup.NeutralRoles, false) - .SetParent(CustomRoleSpawnChances[CustomRoles.Summoner]) - .SetValueFormat(OptionFormat.Seconds); - - // Death Timer - DeathTimerOption = FloatOptionItem.Create(Id + 11, "Summoned Player Duration", new(5f, 120f, 5f), 30f, TabGroup.NeutralRoles, false) - .SetParent(CustomRoleSpawnChances[CustomRoles.Summoner]) - .SetValueFormat(OptionFormat.Seconds); - - // Kill Cooldown - KillCooldownOption = FloatOptionItem.Create(Id + 12, "Summoned Player Kill Cooldown", new(5f, 60f, 1f), 15f, TabGroup.NeutralRoles, false) - .SetParent(CustomRoleSpawnChances[CustomRoles.Summoner]) - .SetValueFormat(OptionFormat.Seconds); - - KnowSummonedRoles = BooleanOptionItem.Create(Id + 13, "Know Summoner/Summoned Roles", true, TabGroup.NeutralRoles, false) - .SetParent(CustomRoleSpawnChances[CustomRoles.Summoner]); - } - - public override void Add(byte playerId) - { - base.Add(playerId); - CustomRoleManager.OnFixedUpdateOthers.Add(OnFixedUpdate); - var playerState = Main.PlayerStates[playerId]; - playerState.SetMainRole(CustomRoles.Summoner); - playerState.IsSummoner = true; - } - - public override void Init() - { - SummonedHealth.Clear(); - LastUpdateTimes.Clear(); - } - - public static bool SummonerCheckMsg(PlayerControl pc, string msg, bool isUI = false, bool isSystemMessage = false) - { - if (isSystemMessage || pc == null || !AmongUsClient.Instance.AmHost) return false; // Skip if system message or not host - if (!GameStates.IsMeeting || pc == null || GameStates.IsExilling) return false; // Only during meetings - if (!pc.Is(CustomRoles.Summoner) || !(pc.GetRoleClass() is Summoner summonerInstance)) return false; - - msg = msg.ToLower().Trim(); - Logger.Info($"Received command: {msg} from {pc.PlayerId}, Host: {AmongUsClient.Instance.AmHost}", "Summoner"); - - if (!CheckCommand(ref msg, "summon")) return false; - - if (!pc.IsAlive()) - { - Logger.Warn("Summoner is dead and cannot use commands.", "Summoner"); - return true; - } - - if (!byte.TryParse(msg, out var targetId)) - { - Logger.Warn("Invalid target ID for /summon command.", "Summoner"); - pc.Notify("Invalid target ID! Use /summon "); - return true; - } - - PlayerControl targetPlayer = null; - foreach (var player in PlayerControl.AllPlayerControls) - { - if (player.PlayerId == targetId) - { - targetPlayer = player; - break; // Exit the loop once the player is found - } - } - - if (targetPlayer == null || targetPlayer.IsAlive()) - { - Logger.Warn("Target player is invalid or alive.", "Summoner"); - pc.Notify("Target is invalid or not dead."); - return true; - } - - if (summonerInstance.HasSummonedThisMeeting) - { - Logger.Warn("Summoner has already summoned a player this meeting.", "Summoner"); - pc.Notify("You can only summon one player per meeting."); - return true; - } - - summonerInstance.RevivePlayer(targetPlayer); - summonerInstance.HasSummonedThisMeeting = true; - - Logger.Info($"Summoner {pc.PlayerId} has summoned player {targetPlayer.PlayerId}.", "Summoner"); - - return true; // Indicate the command was handled and suppress the message - } - - - public static bool CheckCommand(ref string msg, string command) - { - var comList = command.Split('|'); - for (int i = 0; i < comList.Length; i++) - { - if (msg.StartsWith("/" + comList[i])) - { - msg = msg.Replace("/" + comList[i], string.Empty).Trim(); - return true; - } - } - return false; - } - - public void RevivePlayer(PlayerControl targetPlayer) - { - if (targetPlayer == null || targetPlayer.Data == null || !targetPlayer.Data.IsDead) - { - Logger.Warn($"RevivePlayer: Invalid target or player is not dead.", "Summoner"); - return; - } - - float reviveDelay = ReviveDelayOption?.GetFloat() ?? 5f; - - new LateTask(() => - { - if (targetPlayer.IsAlive()) - { - Logger.Info($"Player {targetPlayer.PlayerId} is already alive. Revive skipped.", "Summoner"); - return; - } - - // Handle players already in the Summoned role - if (targetPlayer.Is(CustomRoles.Summoned)) - { - Summoned.RefreshTimer(targetPlayer.PlayerId); - Logger.Info($"Player {targetPlayer.PlayerId} re-summoned with a refreshed timer.", "Summoner"); - return; - } - - // Save current role and add-ons - SaveRoleAndAddons(targetPlayer); - - // Reset sub-roles and assign Summoned role - targetPlayer.ResetSubRoles(); // Clear all sub-roles and add-ons - targetPlayer.RpcSetCustomRole(CustomRoles.Summoned); - - Logger.Info($"Player {targetPlayer.PlayerId} summoned and their role was saved.", "Summoner"); - - }, reviveDelay, "SummonerRevive"); - } - - private void SaveRoleAndAddons(PlayerControl player) - { - var originalRole = player.GetCustomRole(); - var originalAddons = player.GetAddOns(); - SavedStates[player.PlayerId] = (originalRole, originalAddons); - Logger.Info($"Player {player.PlayerId}'s role and add-ons saved.", "Summoner"); - } - - private void RestoreRoleAndAddons(PlayerControl player) - { - if (SavedStates.TryGetValue(player.PlayerId, out var state)) - { - // Use RpcSetRole to restore the role - player.RpcSetRole((AmongUs.GameOptions.RoleTypes)state.originalRole); - - // Restore saved add-ons - foreach (var addon in state.originalAddOns) - { - player.AddAddOn(addon); - } - - SavedStates.Remove(player.PlayerId); - Logger.Info($"Player {player.PlayerId} restored to their original role and add-ons.", "Summoner"); - } - } - - public void OnRoleRemove(byte playerId) - { - foreach (var summonedId in SavedStates.Keys.ToList()) - { - var summonedPlayer = PlayerControl.GetPlayerById(summonedId); - if (summonedPlayer != null && summonedPlayer.IsAlive()) - { - summonedPlayer.RpcExileV2(); // Kill the summoned player - RestoreRoleAndAddons(summonedPlayer); // Restore original role and add-ons - } - } - - base.OnRoleRemove(playerId); - } -} - - public static bool CheckSummoned(PlayerControl player) - { - return player.Is(CustomRoles.Summoned); // Replace with your Summoned role check logic - } - - public override void OnReportDeadBody(PlayerControl reporter, NetworkedPlayerInfo bodyInfo) - { - foreach (var player in PlayerControl.AllPlayerControls) - { - if (player.HasSpecificSubRole(CustomRoles.Summoned) && player.IsAlive()) - { - - - // Trigger Summoned's custom death mechanics - KillSummonedPlayer(player); - } - } - } - - - - - - private void PerformRevive(PlayerControl targetPlayer, float reviveDelay) - { - if (targetPlayer.IsAlive()) return; - - new LateTask(() => - { - if (targetPlayer.IsAlive()) return; - - // Handle players already in the Summoned role - if (targetPlayer.Is(CustomRoles.Summoned)) - { - Summoned.RefreshTimer(targetPlayer.PlayerId); - Logger.Info($"Player {targetPlayer.PlayerId} re-summoned with a refreshed timer.", "Summoner"); - return; - } - - // Save the player's current role and replace with Summoned - SaveRoleAndAddons(targetPlayer); - targetPlayer.RpcSetCustomRole(CustomRoles.Summoned); - Logger.Info($"Player {targetPlayer.PlayerId} summoned and original role saved.", "Summoner"); - }, reviveDelay, "SummonerRevive"); - } - - - - - - - - - private void NotifySummonerAndSummoned(string message) - { - foreach (var player in PlayerControl.AllPlayerControls) - { - if (player.Is(CustomRoles.Summoner) || player.HasSpecificSubRole(CustomRoles.Summoned)) - { - Utils.SendMessage(message, player.PlayerId); - } - } - } - - private void StartDeathTimer(PlayerControl targetPlayer) - { - int deathTimer = Mathf.CeilToInt(DeathTimerOption.GetFloat()); - SummonedHealth[targetPlayer.PlayerId] = deathTimer; - LastUpdateTimes[targetPlayer.PlayerId] = Utils.GetTimeStamp(); - - Logger.Info($"Player {targetPlayer.GetRealName()} has been given a death timer of {deathTimer} seconds.", "Summoner"); - - // Notify the summoned player - NotifySummonedHealth(targetPlayer); - } - - - private void OnFixedUpdate(PlayerControl player, bool lowLoad, long nowTime) - { - if (lowLoad || GameStates.IsMeeting) return; - - foreach (var (playerId, health) in SummonedHealth.ToList()) // Avoid modification issues during iteration - { - PlayerControl targetPlayer = null; - - // Find the player with the given playerId - foreach (var p in PlayerControl.AllPlayerControls) - { - if (p.PlayerId == playerId) - { - targetPlayer = p; - break; - } - } - - if (targetPlayer == null) - { - ResetHealth(playerId); // Clean up invalid players - continue; - } - - // Skip timer updates if the player is dead - if (targetPlayer.Data.IsDead) - { - Logger.Info($"Skipping timer update for dead summoned player {playerId}.", "Summoner"); - continue; - } - - // Get the current time - var currentTime = (long)(System.DateTime.UtcNow - new System.DateTime(1970, 1, 1, 0, 0, 0, System.DateTimeKind.Utc)).TotalSeconds; - - if (!LastUpdateTimes.TryGetValue(playerId, out var lastUpdateTime)) - { - lastUpdateTime = currentTime; - } - - // Calculate time difference and update health - var deltaTime = currentTime - lastUpdateTime; - SummonedHealth[playerId] = Mathf.Clamp(SummonedHealth[playerId] - deltaTime, 0f, DeathTimerOption.GetFloat()); - - // Apply visual updates for health - NotifySummonedHealth(targetPlayer); - - if (SummonedHealth[playerId] <= 0) - { - KillSummonedPlayer(targetPlayer); - SummonedHealth.Remove(playerId); - LastUpdateTimes.Remove(playerId); - } - - // Update the last timestamp - LastUpdateTimes[playerId] = currentTime; - } - } - - public static bool KnowRole(PlayerControl player, PlayerControl target) - { - // Summoner can see Summoned, Summoned can see Summoner - if (player.Is(CustomRoles.Summoner) && target.HasSpecificSubRole(CustomRoles.Summoned)) return true; - if (player.HasSpecificSubRole(CustomRoles.Summoned) && target.Is(CustomRoles.Summoner)) return true; - - // Summoned can see other Summoned players if enabled - if (KnowSummonedRoles.GetBool() && - player.HasSpecificSubRole(CustomRoles.Summoned) && - target.HasSpecificSubRole(CustomRoles.Summoned)) - return true; - - return false; - } - - - private void NotifySummonedHealth(PlayerControl player) - { - if (player.Is(CustomRoles.Summoner) || player.HasSpecificSubRole(CustomRoles.Summoned)) - { - // Notify only Summoner and Summoned players - var health = Mathf.RoundToInt(SummonedHealth[player.PlayerId]); - player.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Summoned), $"Time Remaining: {health}s")); - } - } - - private static void KillSummonedPlayer(PlayerControl target) - { - target.SetDeathReason(PlayerState.DeathReason.SummonedExpired); - target.RpcExileV2(); // Kill the player without leaving a body - Logger.Info($"{target.GetRealName()} has died because their timer ran out.", "Summoner"); - } - - private void ResetHealth(byte playerId) - { - SummonedHealth.Remove(playerId); - LastUpdateTimes.Remove(playerId); - } - - - public override bool OnCheckMurderAsKiller(PlayerControl killer, PlayerControl target) - { - if (killer.Is(CustomRoles.Summoned) && (target.Is(CustomRoles.Summoner) || target.HasSpecificSubRole(CustomRoles.Summoned))) - { - string errorMessage = "You cannot kill the Summoner or other summoned players!"; - killer.Notify(Utils.ColorString(Utils.GetRoleColor(CustomRoles.Summoner), errorMessage)); - return false; // Cancel the kill - } - - return true; // Allow other kills - } - - public override void AfterMeetingTasks() - { - base.AfterMeetingTasks(); - - // Reset Summoning flag to allow reviving in the next meeting - HasSummonedThisMeeting = false; - - // Handle pending revives queued during the meeting - if (PendingRevives.Count > 0) - { - foreach (var (player, delay) in PendingRevives.ToList()) - { - PerformRevive(player, delay); - } - PendingRevives.Clear(); - } - - // Process Summoned players - foreach (var player in PlayerControl.AllPlayerControls) - { - if (SummonedTimers.TryGetValue(player.PlayerId, out var remainingTime)) - { - if (player.Data.IsDead) - { - Logger.Info($"Player {player.GetRealName()} with remaining time will not automatically revive. Summoner must manually summon them again.", "Summoner"); - SummonedTimers.Remove(player.PlayerId); // Remove the expired timer - } - else - { - Logger.Warn($"Player {player.GetRealName()} is alive but had a timer. Timer will continue.", "Summoner"); - } - } - } - } - - - - - - public override string GetLowerTextOthers(PlayerControl seer, PlayerControl target = null, bool isForMeeting = false, bool isForHud = false) - { - if (target == null || !isForHud) return string.Empty; - - // Check if roles should be visible - if (KnowRole(seer, target)) - { - if (target.Is(CustomRoles.Summoner)) - return ColorString(GetRoleColor(CustomRoles.Summoner), "Summoner"); - if (target.HasSpecificSubRole(CustomRoles.Summoned)) - return ColorString(GetRoleColor(CustomRoles.Summoned), "Summoned"); - } - - // Default behavior - return string.Empty; - } -} - - From 44d70e28ab837d9b5106bc70e7805a9358b31040 Mon Sep 17 00:00:00 2001 From: frisk11123 Date: Mon, 6 Jan 2025 11:44:24 -0500 Subject: [PATCH 09/11] Delete Summoned.cs --- Summoned.cs | 1 - 1 file changed, 1 deletion(-) delete mode 100644 Summoned.cs diff --git a/Summoned.cs b/Summoned.cs deleted file mode 100644 index 5f282702b..000000000 --- a/Summoned.cs +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file From 10e8ad4a6e6d08edd4804bb8bf94374fc0621200 Mon Sep 17 00:00:00 2001 From: frisk11123 Date: Mon, 6 Jan 2025 11:48:22 -0500 Subject: [PATCH 10/11] Delete .editorconfig --- .editorconfig | 78 --------------------------------------------------- 1 file changed, 78 deletions(-) delete mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig deleted file mode 100644 index 08a0260a4..000000000 --- a/.editorconfig +++ /dev/null @@ -1,78 +0,0 @@ -[*.cs] - -# CA2211: Non-constant fields should not be visible -dotnet_diagnostic.CA2211.severity = none -csharp_using_directive_placement = outside_namespace:silent -csharp_prefer_simple_using_statement = true:suggestion -csharp_prefer_braces = true:silent -csharp_style_namespace_declarations = block_scoped:silent -csharp_style_prefer_method_group_conversion = true:silent -csharp_style_prefer_top_level_statements = true:silent -csharp_style_prefer_primary_constructors = true:suggestion -csharp_prefer_system_threading_lock = true:suggestion -csharp_style_expression_bodied_methods = false:silent -csharp_style_expression_bodied_constructors = false:silent -csharp_style_expression_bodied_operators = false:silent -csharp_style_expression_bodied_properties = true:silent -csharp_style_expression_bodied_indexers = true:silent -csharp_style_expression_bodied_accessors = true:silent -csharp_style_expression_bodied_lambdas = true:silent -csharp_style_expression_bodied_local_functions = false:silent -csharp_indent_labels = one_less_than_current -csharp_space_around_binary_operators = before_and_after - -[*.{cs,vb}] -#### Naming styles #### - -# Naming rules - -dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion -dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface -dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i - -dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion -dotnet_naming_rule.types_should_be_pascal_case.symbols = types -dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case - -dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion -dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members -dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case - -# Symbol specifications - -dotnet_naming_symbols.interface.applicable_kinds = interface -dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected -dotnet_naming_symbols.interface.required_modifiers = - -dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum -dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected -dotnet_naming_symbols.types.required_modifiers = - -dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method -dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected -dotnet_naming_symbols.non_field_members.required_modifiers = - -# Naming styles - -dotnet_naming_style.begins_with_i.required_prefix = I -dotnet_naming_style.begins_with_i.required_suffix = -dotnet_naming_style.begins_with_i.word_separator = -dotnet_naming_style.begins_with_i.capitalization = pascal_case - -dotnet_naming_style.pascal_case.required_prefix = -dotnet_naming_style.pascal_case.required_suffix = -dotnet_naming_style.pascal_case.word_separator = -dotnet_naming_style.pascal_case.capitalization = pascal_case - -dotnet_naming_style.pascal_case.required_prefix = -dotnet_naming_style.pascal_case.required_suffix = -dotnet_naming_style.pascal_case.word_separator = -dotnet_naming_style.pascal_case.capitalization = pascal_case -dotnet_style_coalesce_expression = true:suggestion -dotnet_style_null_propagation = true:suggestion -dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion -dotnet_style_prefer_auto_properties = true:silent -dotnet_style_operator_placement_when_wrapping = beginning_of_line -tab_width = 4 -indent_size = 4 -end_of_line = crlf From 9b9954c7db44e8e6998d2eded61c7fdc8e6c7a81 Mon Sep 17 00:00:00 2001 From: frisk11123 Date: Mon, 6 Jan 2025 11:50:12 -0500 Subject: [PATCH 11/11] Create .editorconfig --- .editorconfig | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 000000000..0d271aea1 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,4 @@ +[*.cs] + +# CA2211: Non-constant fields should not be visible +dotnet_diagnostic.CA2211.severity = none