diff --git a/Modules/CustomWinnerHolder.cs b/Modules/CustomWinnerHolder.cs index c4625cc25..2858c14cd 100644 --- a/Modules/CustomWinnerHolder.cs +++ b/Modules/CustomWinnerHolder.cs @@ -57,17 +57,17 @@ public static void ResetAndSetWinner(CustomWinner winner) public static MessageWriter WriteTo(MessageWriter writer) { - writer.Write((int)WinnerTeam); + writer.WritePacked((int)WinnerTeam); - writer.Write(AdditionalWinnerRoles.Count); + writer.WritePacked(AdditionalWinnerRoles.Count); foreach (var wr in AdditionalWinnerRoles) - writer.Write((int)wr); + writer.WritePacked((int)wr); - writer.Write(WinnerRoles.Count); + writer.WritePacked(WinnerRoles.Count); foreach (var wr in WinnerRoles) - writer.Write((int)wr); + writer.WritePacked((int)wr); - writer.Write(WinnerIds.Count); + writer.WritePacked(WinnerIds.Count); foreach (var id in WinnerIds) writer.Write(id); @@ -75,20 +75,20 @@ public static MessageWriter WriteTo(MessageWriter writer) } public static void ReadFrom(MessageReader reader) { - WinnerTeam = (CustomWinner)reader.ReadInt32(); + WinnerTeam = (CustomWinner)reader.ReadPackedInt32(); AdditionalWinnerRoles = new(); - int AdditionalWinnerRolesCount = reader.ReadInt32(); + int AdditionalWinnerRolesCount = reader.ReadPackedInt32(); for (int i = 0; i < AdditionalWinnerRolesCount; i++) - AdditionalWinnerRoles.Add((CustomRoles)reader.ReadInt32()); + AdditionalWinnerRoles.Add((CustomRoles)reader.ReadPackedInt32()); WinnerRoles = new(); - int WinnerRolesCount = reader.ReadInt32(); + int WinnerRolesCount = reader.ReadPackedInt32(); for (int i = 0; i < WinnerRolesCount; i++) - WinnerRoles.Add((CustomRoles)reader.ReadInt32()); + WinnerRoles.Add((CustomRoles)reader.ReadPackedInt32()); WinnerIds = new(); - int WinnerIdsCount = reader.ReadInt32(); + int WinnerIdsCount = reader.ReadPackedInt32(); for (int i = 0; i < WinnerIdsCount; i++) WinnerIds.Add(reader.ReadByte()); } diff --git a/Modules/ErrorText.cs b/Modules/ErrorText.cs index 2332f6a95..63895075c 100644 --- a/Modules/ErrorText.cs +++ b/Modules/ErrorText.cs @@ -152,6 +152,7 @@ public enum ErrorCode // ========== // 001 Main Main_DictionaryError = 0010003, // 001-000-3 Main Dictionary Error + OptionIDDuplicate = 001_010_3, // 001-010-3 オプションIDが重複している(DEBUGビルド時のみ) // 002 サポート関連 UnsupportedVersion = 002_000_1, // 002-000-1 AmongUsのバージョンが古い // ========== diff --git a/Modules/ExtendedPlayerControl.cs b/Modules/ExtendedPlayerControl.cs index 34cc1522b..c4de7424c 100644 --- a/Modules/ExtendedPlayerControl.cs +++ b/Modules/ExtendedPlayerControl.cs @@ -32,11 +32,14 @@ public static void RpcSetCustomRole(this PlayerControl player, CustomRoles role) } if (AmongUsClient.Instance.AmHost) { - var roleClass = player.GetRoleClass(); - if (roleClass != null) + if (role < CustomRoles.NotAssigned) { - roleClass.Dispose(); - CustomRoleManager.CreateInstance(role, player); + var roleClass = player.GetRoleClass(); + if (roleClass != null) + { + roleClass.Dispose(); + CustomRoleManager.CreateInstance(role, player); + } } MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.SetCustomRole, Hazel.SendOption.Reliable, -1); @@ -567,6 +570,19 @@ public static PlainShipRoom GetPlainShipRoom(this PlayerControl pc) } return null; } + public static void RpcSnapTo(this PlayerControl pc, Vector2 position) + { + pc.NetTransform.RpcSnapTo(position); + } + public static void RpcSnapToDesync(this PlayerControl pc, PlayerControl target, Vector2 position) + { + var net = pc.NetTransform; + var num = (ushort)(net.lastSequenceId + 2); + MessageWriter messageWriter = AmongUsClient.Instance.StartRpcImmediately(net.NetId, (byte)RpcCalls.SnapTo, SendOption.None, target.GetClientId()); + NetHelpers.WriteVector2(position, messageWriter); + messageWriter.Write(num); + AmongUsClient.Instance.FinishRpcImmediately(messageWriter); + } public static bool IsProtected(this PlayerControl self) => self.protectedByGuardianId > -1; //汎用 diff --git a/Modules/OptionHolder.cs b/Modules/OptionHolder.cs index 377d10ed9..ed89244c6 100644 --- a/Modules/OptionHolder.cs +++ b/Modules/OptionHolder.cs @@ -281,6 +281,8 @@ public static CustomGameMode CurrentGameMode public static OptionItem SabotageTimeControl; public static OptionItem PolusReactorTimeLimit; public static OptionItem AirshipReactorTimeLimit; + public static OptionItem FungleReactorTimeLimit; + public static OptionItem FungleMushroomMixupDuration; // サボタージュのクールダウン変更 public static OptionItem ModifySabotageCooldown; @@ -456,6 +458,12 @@ public static void Load() AirshipReactorTimeLimit = FloatOptionItem.Create(100802, "AirshipReactorTimeLimit", new(1f, 90f, 1f), 60f, TabGroup.MainSettings, false).SetParent(SabotageTimeControl) .SetValueFormat(OptionFormat.Seconds) .SetGameMode(CustomGameMode.Standard); + FungleReactorTimeLimit = FloatOptionItem.Create(100803, "FungleReactorTimeLimit", new(1f, 90f, 1f), 60f, TabGroup.MainSettings, false).SetParent(SabotageTimeControl) + .SetValueFormat(OptionFormat.Seconds) + .SetGameMode(CustomGameMode.Standard); + FungleMushroomMixupDuration = FloatOptionItem.Create(100804, "FungleMushroomMixupDuration", new(1f, 20f, 1f), 10f, TabGroup.MainSettings, false).SetParent(SabotageTimeControl) + .SetValueFormat(OptionFormat.Seconds) + .SetGameMode(CustomGameMode.Standard); // サボタージュのクールダウン変更 ModifySabotageCooldown = BooleanOptionItem.Create(100810, "ModifySabotageCooldown", false, TabGroup.MainSettings, false) diff --git a/Modules/OptionItem/OptionItem.cs b/Modules/OptionItem/OptionItem.cs index 2a1f9482d..dd5a604f6 100644 --- a/Modules/OptionItem/OptionItem.cs +++ b/Modules/OptionItem/OptionItem.cs @@ -14,6 +14,9 @@ public abstract class OptionItem public static IReadOnlyDictionary FastOptions => _fastOptions; private static Dictionary _fastOptions = new(1024); public static int CurrentPreset { get; set; } +#if DEBUG + public static bool IdDuplicated { get; private set; } = false; +#endif #endregion // 必須情報 (コンストラクタで必ず設定させる必要がある値) @@ -105,6 +108,9 @@ public OptionItem(int id, string name, int defaultValue, TabGroup tab, bool isSi } else { +#if DEBUG + IdDuplicated = true; +#endif Logger.Error($"ID:{id}が重複しています", "OptionItem"); } } @@ -179,7 +185,7 @@ public virtual void Refresh() opt.oldValue = opt.Value = CurrentValue; } } - public void SetValue(int afterValue, bool doSave, bool doSync = true) + public virtual void SetValue(int afterValue, bool doSave, bool doSync = true) { int beforeValue = CurrentValue; if (IsSingleValue) diff --git a/Modules/OptionItem/PresetOptionItem.cs b/Modules/OptionItem/PresetOptionItem.cs index 9b62ff297..90b141e41 100644 --- a/Modules/OptionItem/PresetOptionItem.cs +++ b/Modules/OptionItem/PresetOptionItem.cs @@ -40,5 +40,10 @@ public override void SetValue(int value, bool doSync = true) base.SetValue(Rule.RepeatIndex(value), doSync); SwitchPreset(Rule.RepeatIndex(value)); } + 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/Utils.cs b/Modules/Utils.cs index 362ef7cdc..ee3462609 100644 --- a/Modules/Utils.cs +++ b/Modules/Utils.cs @@ -543,24 +543,68 @@ public static void ShowActiveSettings(byte PlayerId = byte.MaxValue) if (RoleAssignManager.OptionAssignMode.GetBool()) { ShowChildrenSettings(RoleAssignManager.OptionAssignMode, ref sb); + CheckPageChange(PlayerId, sb); } foreach (var role in Options.CustomRoleCounts) { if (!role.Key.IsEnable()) continue; + if (role.Key is CustomRoles.HASFox or CustomRoles.HASTroll) continue; + sb.Append($"\n【{GetRoleName(role.Key)}×{role.Key.GetCount()}】\n"); ShowChildrenSettings(Options.CustomRoleSpawnChances[role.Key], ref sb); + CheckPageChange(PlayerId, sb); } foreach (var opt in OptionItem.AllOptions.Where(x => x.GetBool() && x.Parent == null && x.Id >= 80000 && !x.IsHiddenOn(Options.CurrentGameMode))) { - if (opt.Name is "KillFlashDuration" or "RoleAssigningAlgorithm") - sb.Append($"\n【{opt.GetName(true)}: {opt.GetString()}】\n"); + if (opt.Name is "RandomSpawn") + { + foreach (var randomOpt in opt.Children) + { + if ((randomOpt.Id / 100) % 10 != mapId) continue; + //現在のマップのみ表示する + if (randomOpt.GetBool()) + { + //Onの時は頭に改ページを入れる + CheckPageChange(PlayerId, sb, true); + sb.Append($"\n【{opt.GetName(true)}】"); + sb.Append($"\n {randomOpt.GetName(true)}: {randomOpt.GetString()}\n"); + + ShowChildrenSettings(randomOpt, ref sb, 1); + } + else + { + //オフならそのままで大丈夫 + sb.Append($"\n【{opt.GetName(true)}】"); + sb.Append($"\n {randomOpt.GetName(true)}: {randomOpt.GetString()}\n"); + } + } + CheckPageChange(PlayerId, sb); + } else - sb.Append($"\n【{opt.GetName(true)}】\n"); - ShowChildrenSettings(opt, ref sb); + { + if (opt.Name is "KillFlashDuration" or "RoleAssigningAlgorithm") + sb.Append($"\n【{opt.GetName(true)}: {opt.GetString()}】\n"); + else + sb.Append($"\n【{opt.GetName(true)}】\n"); + ShowChildrenSettings(opt, ref sb); + CheckPageChange(PlayerId, sb); + } } } SendMessage(sb.ToString(), PlayerId, removeTags: false); } + + private static void CheckPageChange(byte PlayerId, StringBuilder sb, bool force = false) + { + //2Byte文字想定で1000byt越えるならページを変える + if (force || sb.Length > 500) + { + SendMessage(sb.ToString(), PlayerId, removeTags: false); + sb.Clear(); + sb.AppendFormat("", ActiveSettingsSize); + } + } + public static void CopyCurrentSettings() { var sb = new StringBuilder(); @@ -1020,27 +1064,39 @@ public static void OpenDirectory(string path) } public static string SummaryTexts(byte id, bool isForChat) { - // 全プレイヤー中最長の名前の長さからプレイヤー名の後の水平位置を計算する - // 1em ≒ 半角2文字 - // 空白は0.5emとする - // SJISではアルファベットは1バイト,日本語は基本的に2バイト - var longestNameByteCount = Main.AllPlayerNames.Values.Select(name => name.GetByteCount()).OrderByDescending(byteCount => byteCount).FirstOrDefault(); - //最大11.5emとする(★+日本語10文字分+半角空白) - var pos = Math.Min(((float)longestNameByteCount / 2) + 1.5f /* ★+末尾の半角空白 */ , 11.5f); var builder = new StringBuilder(); - builder.Append(isForChat ? Main.AllPlayerNames[id] : ColorString(Main.PlayerColors[id], Main.AllPlayerNames[id])); - builder.AppendFormat("", pos).Append(isForChat ? GetProgressText(id).RemoveColorTags() : GetProgressText(id)).Append(""); - // "(00/00) " = 4em - pos += 4f; - builder.AppendFormat("", pos).Append(GetVitalText(id)).Append(""); - // "Lover's Suicide " = 8em - // "回線切断 " = 4.5em - pos += DestroyableSingleton.Instance.currentLanguage.languageID == SupportedLangs.English ? 8f : 4.5f; - builder.AppendFormat("", pos); - builder.Append(isForChat ? GetTrueRoleName(id, false).RemoveColorTags() : GetTrueRoleName(id, false)); - builder.Append(isForChat ? GetSubRolesText(id).RemoveColorTags() : GetSubRolesText(id)); - builder.Append(""); + // チャットならposタグを使わない(文字数削減) + if (isForChat) + { + builder.Append(Main.AllPlayerNames[id]); + builder.Append(": ").Append(GetProgressText(id).RemoveColorTags()); + builder.Append(' ').Append(GetVitalText(id)); + builder.Append(' ').Append(GetTrueRoleName(id, false).RemoveColorTags()); + builder.Append(' ').Append(GetSubRolesText(id).RemoveColorTags()); + } + else + { + // 全プレイヤー中最長の名前の長さからプレイヤー名の後の水平位置を計算する + // 1em ≒ 半角2文字 + // 空白は0.5emとする + // SJISではアルファベットは1バイト,日本語は基本的に2バイト + var longestNameByteCount = Main.AllPlayerNames.Values.Select(name => name.GetByteCount()).OrderByDescending(byteCount => byteCount).FirstOrDefault(); + //最大11.5emとする(★+日本語10文字分+半角空白) + var pos = Math.Min(((float)longestNameByteCount / 2) + 1.5f /* ★+末尾の半角空白 */ , 11.5f); + builder.Append(ColorString(Main.PlayerColors[id], Main.AllPlayerNames[id])); + builder.AppendFormat("", pos).Append(GetProgressText(id)).Append(""); + // "(00/00) " = 4em + pos += 4f; + builder.AppendFormat("", pos).Append(GetVitalText(id)).Append(""); + // "Lover's Suicide " = 8em + // "回線切断 " = 4.5em + pos += DestroyableSingleton.Instance.currentLanguage.languageID == SupportedLangs.English ? 8f : 4.5f; + builder.AppendFormat("", pos); + builder.Append(GetTrueRoleName(id, false)); + builder.Append(GetSubRolesText(id)); + builder.Append(""); + } return builder.ToString(); } public static string RemoveHtmlTags(this string str) => Regex.Replace(str, "<[^>]*?>", ""); diff --git a/Patches/AirshipStatus.cs b/Patches/AirshipStatus.cs index a76b74591..fa7744024 100644 --- a/Patches/AirshipStatus.cs +++ b/Patches/AirshipStatus.cs @@ -10,7 +10,14 @@ public static class AirshipStatusPrespawnStepPatch { public static bool Prefix() { - return !PlayerControl.LocalPlayer.Is(CustomRoles.GM); // GMは湧き画面をスキップ + if (PlayerControl.LocalPlayer.Is(CustomRoles.GM)) + { + RandomSpawn.hostReady = true; + RandomSpawn.AirshipSpawn(PlayerControl.LocalPlayer); + // GMは湧き画面をスキップ + return false; + } + return true; } } } \ No newline at end of file diff --git a/Patches/CheckGameEndPatch.cs b/Patches/CheckGameEndPatch.cs index 5886b88ed..008870575 100644 --- a/Patches/CheckGameEndPatch.cs +++ b/Patches/CheckGameEndPatch.cs @@ -1,8 +1,11 @@ +using System.Collections; using System.Collections.Generic; using System.Linq; using AmongUs.GameOptions; +using BepInEx.Unity.IL2CPP.Utils.Collections; using HarmonyLib; using Hazel; +using UnityEngine; using TownOfHost.Roles.Core; using TownOfHost.Roles.Core.Interfaces; @@ -82,11 +85,13 @@ public static bool Prefix() } public static void StartEndGame(GameOverReason reason) { - var sender = new CustomRpcSender("EndGameSender", SendOption.Reliable, true); - sender.StartMessage(-1); // 5: GameData - MessageWriter writer = sender.stream; + AmongUsClient.Instance.StartCoroutine(CoEndGame(AmongUsClient.Instance, reason).WrapToIl2Cpp()); + } + private static IEnumerator CoEndGame(AmongUsClient self, GameOverReason reason) + { + // サーバー側のパケットサイズ制限によりCustomRpcSenderが利用できないため,遅延を挟むことで順番の整合性を保つ. - //ゴーストロール化 + // バニラ画面でのアウトロを正しくするためのゴーストロール化 List ReviveRequiredPlayerIds = new(); var winner = CustomWinnerHolder.WinnerTeam; foreach (var pc in Main.AllPlayerControls) @@ -107,58 +112,45 @@ void SetGhostRole(bool ToGhostImpostor) if (ToGhostImpostor) { Logger.Info($"{pc.GetNameWithRole()}: ImpostorGhostに変更", "ResetRoleAndEndGame"); - sender.StartRpc(pc.NetId, RpcCalls.SetRole) - .Write((ushort)RoleTypes.ImpostorGhost) - .EndRpc(); - pc.SetRole(RoleTypes.ImpostorGhost); + pc.RpcSetRole(RoleTypes.ImpostorGhost); } else { Logger.Info($"{pc.GetNameWithRole()}: CrewmateGhostに変更", "ResetRoleAndEndGame"); - sender.StartRpc(pc.NetId, RpcCalls.SetRole) - .Write((ushort)RoleTypes.CrewmateGhost) - .EndRpc(); - pc.SetRole(RoleTypes.Crewmate); + pc.RpcSetRole(RoleTypes.CrewmateGhost); } } } // CustomWinnerHolderの情報の同期 - sender.StartRpc(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.EndGame); - CustomWinnerHolder.WriteTo(sender.stream); - sender.EndRpc(); + var winnerWriter = self.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.EndGame, SendOption.Reliable); + CustomWinnerHolder.WriteTo(winnerWriter); + self.FinishRpcImmediately(winnerWriter); + + // 蘇生を確実にゴーストロール設定の後に届けるための遅延 + yield return new WaitForSeconds(EndGameDelay); - // GameDataによる蘇生処理 - writer.StartMessage(1); // Data + if (ReviveRequiredPlayerIds.Count > 0) { - writer.WritePacked(GameData.Instance.NetId); // NetId - foreach (var info in GameData.Instance.AllPlayers) + // 蘇生 パケットが膨れ上がって死ぬのを防ぐため,1送信につき1人ずつ蘇生する + for (int i = 0; i < ReviveRequiredPlayerIds.Count; i++) { - if (ReviveRequiredPlayerIds.Contains(info.PlayerId)) - { - // 蘇生&メッセージ書き込み - info.IsDead = false; - writer.StartMessage(info.PlayerId); - info.Serialize(writer); - writer.EndMessage(); - } + var playerId = ReviveRequiredPlayerIds[i]; + var playerInfo = GameData.Instance.GetPlayerById(playerId); + // 蘇生 + playerInfo.IsDead = false; + // 送信 + GameData.Instance.SetDirtyBit(0b_1u << playerId); + AmongUsClient.Instance.SendAllStreamedObjects(); } - writer.EndMessage(); - } - - sender.EndMessage(); - - // バニラ側のゲーム終了RPC - writer.StartMessage(8); //8: EndGame - { - writer.Write(AmongUsClient.Instance.GameId); //GameId - writer.Write((byte)reason); //GameoverReason - writer.Write(false); //showAd + // ゲーム終了を確実に最後に届けるための遅延 + yield return new WaitForSeconds(EndGameDelay); } - writer.EndMessage(); - sender.SendMessage(); + // ゲーム終了 + GameManager.Instance.RpcEndGame(reason, false); } + private const float EndGameDelay = 0.2f; public static void SetPredicateToNormal() => predicate = new NormalGameEndPredicate(); public static void SetPredicateToHideAndSeek() => predicate = new HideAndSeekGameEndPredicate(); diff --git a/Patches/CredentialsPatch.cs b/Patches/CredentialsPatch.cs index b89234ddb..2128c3f79 100644 --- a/Patches/CredentialsPatch.cs +++ b/Patches/CredentialsPatch.cs @@ -74,6 +74,12 @@ static void Postfix(VersionShower __instance) } VersionChecker.Check(); +#if DEBUG + if (OptionItem.IdDuplicated) + { + ErrorText.Instance.AddError(ErrorCode.OptionIDDuplicate); + } +#endif if (SpecialEventText == null && TohLogo != null) { diff --git a/Patches/ISystemType/MushroomMixupSabotageSystemPatch.cs b/Patches/ISystemType/MushroomMixupSabotageSystemPatch.cs index e1e6ad2f3..98c3df467 100644 --- a/Patches/ISystemType/MushroomMixupSabotageSystemPatch.cs +++ b/Patches/ISystemType/MushroomMixupSabotageSystemPatch.cs @@ -1,12 +1,28 @@ using HarmonyLib; +using Hazel; namespace TownOfHost.Patches.ISystemType; [HarmonyPatch(typeof(MushroomMixupSabotageSystem), nameof(MushroomMixupSabotageSystem.UpdateSystem))] public static class MushroomMixupSabotageSystemUpdateSystemPatch { - public static void Postfix() + public static void Prefix([HarmonyArgument(1)] MessageReader msgReader, ref byte __state /* amount */) { + byte amount; + { + var newReader = MessageReader.Get(msgReader); + amount = newReader.ReadByte(); + newReader.Recycle(); + } + __state = amount; + } + public static void Postfix(MushroomMixupSabotageSystem __instance, byte __state /* amount */) + { + var operation = (MushroomMixupSabotageSystem.Operation)__state; + if (operation == MushroomMixupSabotageSystem.Operation.TriggerSabotage && Options.SabotageTimeControl.GetBool()) + { + __instance.currentSecondsUntilHeal = Options.FungleMushroomMixupDuration.GetFloat(); + } // Desyncインポスター目線のプレイヤー名の表示/非表示を反映 Utils.NotifyRoles(ForceLoop: true); } diff --git a/Patches/ISystemType/ReactorSystemTypePatch.cs b/Patches/ISystemType/ReactorSystemTypePatch.cs index 433405b0b..7f0717179 100644 --- a/Patches/ISystemType/ReactorSystemTypePatch.cs +++ b/Patches/ISystemType/ReactorSystemTypePatch.cs @@ -8,7 +8,7 @@ namespace TownOfHost.Patches.ISystemType; [HarmonyPatch(typeof(ReactorSystemType), nameof(ReactorSystemType.UpdateSystem))] public static class ReactorSystemTypeUpdateSystemPatch { - public static bool Prefix(ReactorSystemType __instance, [HarmonyArgument(0)] PlayerControl player, [HarmonyArgument(1)] MessageReader msgReader) + public static bool Prefix(ReactorSystemType __instance, [HarmonyArgument(0)] PlayerControl player, [HarmonyArgument(1)] MessageReader msgReader, ref byte __state /* amount */) { byte amount; { @@ -16,6 +16,7 @@ public static bool Prefix(ReactorSystemType __instance, [HarmonyArgument(0)] Pla amount = newReader.ReadByte(); newReader.Recycle(); } + __state = amount; if (player.GetRoleClass() is ISystemTypeUpdateHook systemTypeUpdateHook && !systemTypeUpdateHook.UpdateReactorSystem(__instance, amount)) { @@ -23,24 +24,25 @@ public static bool Prefix(ReactorSystemType __instance, [HarmonyArgument(0)] Pla } return true; } -} - -//参考 -//https://github.com/Koke1024/Town-Of-Moss/blob/main/TownOfMoss/Patches/MeltDownBoost.cs - -[HarmonyPatch(typeof(ReactorSystemType), nameof(ReactorSystemType.Deteriorate))] -public static class ReactorSystemDetetiorateTypePatch -{ - public static void Prefix(ReactorSystemType __instance) + public static void Postfix(ReactorSystemType __instance, byte __state /* amount */ ) { - if (!__instance.IsActive || !Options.SabotageTimeControl.GetBool()) - return; - if (ShipStatus.Instance.Type == ShipStatus.MapType.Pb) + // サボタージュ発動時 + if (__state == ReactorSystemType.StartCountdown) { - if (__instance.Countdown >= Options.PolusReactorTimeLimit.GetFloat()) - __instance.Countdown = Options.PolusReactorTimeLimit.GetFloat(); - return; + if (!Options.SabotageTimeControl.GetBool()) + { + return; + } + var duration = (MapNames)Main.NormalOptions.MapId switch + { + MapNames.Polus => Options.PolusReactorTimeLimit.GetFloat(), + MapNames.Fungle => Options.FungleReactorTimeLimit.GetFloat(), + _ => float.NaN, + }; + if (!float.IsNaN(duration)) + { + __instance.Countdown = duration; + } } - return; } } diff --git a/Patches/MeetingHudPatch.cs b/Patches/MeetingHudPatch.cs index 7197ffc7a..f80e27b75 100644 --- a/Patches/MeetingHudPatch.cs +++ b/Patches/MeetingHudPatch.cs @@ -195,7 +195,8 @@ public static void Postfix() if (AmongUsClient.Instance.AmHost) { AntiBlackout.SetIsDead(); - Main.AllPlayerControls.Do(pc => RandomSpawn.CustomNetworkTransformPatch.FirstTP[pc.PlayerId] = false); + Main.AllPlayerControls.Do(pc => RandomSpawn.FirstTP[pc.PlayerId] = true); + RandomSpawn.FastSpawnPosition.Clear(); } // MeetingVoteManagerを通さずに会議が終了した場合の後処理 MeetingVoteManager.Instance?.Destroy(); diff --git a/Patches/RandomSpawnPatch.cs b/Patches/RandomSpawnPatch.cs index d4544a37a..d957d982e 100644 --- a/Patches/RandomSpawnPatch.cs +++ b/Patches/RandomSpawnPatch.cs @@ -68,47 +68,70 @@ public enum SpawnPoint } class RandomSpawn { - [HarmonyPatch(typeof(CustomNetworkTransform), nameof(CustomNetworkTransform.SnapTo), typeof(Vector2), typeof(ushort))] - public class CustomNetworkTransformPatch + public static Dictionary FirstTP = new(); + public static Dictionary FastSpawnPosition = new(); + public static bool hostReady; + [HarmonyPatch(typeof(CustomNetworkTransform), nameof(CustomNetworkTransform.RpcSnapTo))] + public class RpcSnapToPatch { - public static Dictionary FirstTP = new(); - public static void Postfix(CustomNetworkTransform __instance, Vector2 position, ushort minSid) + public static void Postfix(CustomNetworkTransform __instance, Vector2 position) { - var player = Main.AllPlayerControls.Where(p => p.NetTransform == __instance).FirstOrDefault(); - if (player == null) + var player = __instance.myPlayer; + //Logger.Info($"RpcSnapToPost:{player.name} pos:{position}", "RandomSpawn"); + if (!AmongUsClient.Instance.AmHost) return; + if (Main.NormalOptions.MapId != 4) return;//AirShip以外無効 + if (FirstTP.TryGetValue(player.PlayerId, out var first) && first) { - Logger.Warn("プレイヤーがnullです", "RandomSpawn"); - return; + hostReady = true; + //ホスト用処理 + //他視点へRPCを最初に送るのはスポーン位置選択後のため + //クライアントへRPCを発行するときにはすでにクライアントの初期配置は終わっている。 + AirshipSpawn(player); } - //Logger.Info($"{player.name} pos:{position} minSid={minSid}", "SnapTo"); + } + } + [HarmonyPatch(typeof(CustomNetworkTransform), nameof(CustomNetworkTransform.HandleRpc))] + public class HandleRpcPatch + { + public static void Postfix(CustomNetworkTransform __instance) + { + var player = __instance.myPlayer; + //Logger.Info($"HandleRpcPost:{player.name}", "RandomSpawn"); + if (!AmongUsClient.Instance.AmHost) return; + if (Main.NormalOptions.MapId != 4) return;//AirShip以外無効 - if (GameStates.IsInTask) + if (FirstTP.TryGetValue(player.PlayerId, out var first) && first) { - if (player.Is(CustomRoles.GM)) return; //GMは対象外に - - if (Main.NormalOptions.MapId != 4) return;//AirShip以外無効 - - if (position == new Vector2(-25f, 40f)) - { - //最初の湧き地点なら次回スポーン - FirstTP[player.PlayerId] = true; - return; - } - - if (FirstTP[player.PlayerId]) - { - FirstTP[player.PlayerId] = false; - //ランダムスポーンをvanillaの初期スポーンより後の判定とする - __instance.lastSequenceId++; - AirshipSpawn(player); - __instance.lastSequenceId--; - } + //クライアント用処理 + //他視点へRPCを最初に送るのはスポーン位置選択後のため + //ランダムスポーン発生 + AirshipSpawn(player); } } } + [HarmonyPatch(typeof(CustomNetworkTransform), nameof(CustomNetworkTransform.SnapTo), typeof(Vector2), typeof(ushort))] + public class SnapToPatch + { + public static void Postfix(CustomNetworkTransform __instance, Vector2 position, ushort minSid) + { + var player = __instance.myPlayer; + //Logger.Info($"SnapTo:{player.name} pos:{position} minSid={minSid}", "RandomSpawn"); + } + } + [HarmonyPatch(typeof(SpawnInMinigame), nameof(SpawnInMinigame.Begin))] + public class SpawnInMinigamePatch + { + public static void Postfix() + { + Logger.Info($"BeginPost", "SpawnInMinigame"); + if (!AmongUsClient.Instance.AmHost) return; + hostReady = true; + } + } public static void AirshipSpawn(PlayerControl player) { + FirstTP[player.PlayerId] = false; if (player.Is(CustomRoles.Penguin)) { var penguin = player.GetRoleClass() as Penguin; @@ -116,8 +139,24 @@ public static void AirshipSpawn(PlayerControl player) } player.RpcResetAbilityCooldown(); if (Options.FixFirstKillCooldown.GetBool() && !MeetingStates.MeetingCalled) player.SetKillCooldown(Main.AllPlayerKillCooldown[player.PlayerId]); - if (!IsRandomSpawn()) return; //ランダムスポーンが無効ならreturn - new AirshipSpawnMap().RandomTeleport(player); + if (IsRandomSpawn()) + { + new AirshipSpawnMap().RandomTeleport(player); + } + else if (player.Is(CustomRoles.GM)) + { + new AirshipSpawnMap().FirstTeleport(player); + } + foreach (var (sp, pos) in FastSpawnPosition) + { + //早湧きした人を船外から初期位置に戻す + sp.RpcSnapToDesync(player, pos); + } + if (!hostReady) + { + //ホストのSpawnMiniGame開始までに湧いたプレイヤーを記録 + FastSpawnPosition[player] = player.transform.position; + } } public static bool IsRandomSpawn() { @@ -139,11 +178,6 @@ public static bool IsRandomSpawn() return false; } } - public static void TP(CustomNetworkTransform nt, Vector2 location) - { - nt.RpcSnapTo(location); - } - public static void SetupCustomOption() { // Skeld @@ -245,16 +279,25 @@ public abstract class SpawnMap public abstract Dictionary Positions { get; } public virtual void RandomTeleport(PlayerControl player) { - var location = GetLocation(); + Teleport(player, true); + } + public virtual void FirstTeleport(PlayerControl player) + { + Teleport(player, false); + } + + private void Teleport(PlayerControl player, bool isRadndom) + { + var location = GetLocation(!isRadndom); Logger.Info($"{player.Data.PlayerName}:{location}", "RandomSpawn"); - TP(player.NetTransform, location); + player.RpcSnapTo(location); } - public Vector2 GetLocation() + + public Vector2 GetLocation(Boolean first = false) { - var locations = - Positions.ToArray().Where(o => o.Key.GetBool()).Any() - ? Positions.ToArray().Where(o => o.Key.GetBool()) - : Positions.ToArray(); + var EnableLocations = Positions.Where(o => o.Key.GetBool()).ToArray(); + var locations = EnableLocations.Length != 0 ? EnableLocations : Positions.ToArray(); + if (first) return locations[0].Value; var location = locations.OrderBy(_ => Guid.NewGuid()).Take(1).FirstOrDefault(); return location.Value; } diff --git a/Patches/onGameStartedPatch.cs b/Patches/onGameStartedPatch.cs index a3325e6fb..36b4f5563 100644 --- a/Patches/onGameStartedPatch.cs +++ b/Patches/onGameStartedPatch.cs @@ -40,7 +40,9 @@ public static void Postfix(AmongUsClient __instance) Main.introDestroyed = false; - RandomSpawn.CustomNetworkTransformPatch.FirstTP = new(); + RandomSpawn.FirstTP = new(); + RandomSpawn.FastSpawnPosition = new(); + RandomSpawn.hostReady = false; Main.DefaultCrewmateVision = Main.RealOptionsData.GetFloat(FloatOptionNames.CrewLightMod); Main.DefaultImpostorVision = Main.RealOptionsData.GetFloat(FloatOptionNames.ImpostorLightMod); @@ -83,7 +85,7 @@ public static void Postfix(AmongUsClient __instance) ReportDeadBodyPatch.WaitReport[pc.PlayerId] = new(); pc.cosmetics.nameText.text = pc.name; - RandomSpawn.CustomNetworkTransformPatch.FirstTP.Add(pc.PlayerId, false); + RandomSpawn.FirstTP.Add(pc.PlayerId, true); var outfit = pc.Data.DefaultOutfit; Camouflage.PlayerSkins[pc.PlayerId] = new GameData.PlayerOutfit().Set(outfit.PlayerName, outfit.ColorId, outfit.HatId, outfit.SkinId, outfit.VisorId, outfit.PetId); Main.clientIdList.Add(pc.GetClientId()); diff --git a/README-EN.md b/README-EN.md index 2cd24f96e..f879bfa14 100644 --- a/README-EN.md +++ b/README-EN.md @@ -15,7 +15,7 @@ This mod is not affiliated with Among Us or Innersloth LLC, and the content cont ## Releases -AmongUs Version: **2023.10.24** +AmongUs Version: **2023.11.28** **Latest Version: [Here](https://github.com/tukasa0001/TownOfHost/releases/latest)** @@ -1244,11 +1244,13 @@ Various devices can be disabled. The time limit for some sabotage can be modified. -| Name | -| --------------------------- | -| Modify Sabotage TimeLimit | -| ┣ Polus Reactor TimeLimit | -| ┗ Airship Reactor TimeLimit | +| Name | +| ------------------------------- | +| Modify Sabotage TimeLimit | +| ┣ Polus Reactor TimeLimit | +| ┣ Airship Reactor TimeLimit | +| ┣Fungle Reactor Duration | +| ┗Fungle Mushroom Mixup Duration | ## Sabotage Cooldown Control diff --git a/README.md b/README.md index f7bda1da3..fb313dfbb 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ ## リリース -AmongUsバージョン : **2023.10.24** +AmongUsバージョン : **2023.11.28** **最新版は[こちら](https://github.com/tukasa0001/TownOfHost/releases/latest)** @@ -1216,11 +1216,13 @@ Polus や The Airship のドアを開けるとその部屋の全てのドアが 一部サボタージュの制限時間を変更することができます。
-| 設定名 | -| -------------------------------- | -| サボタージュの時間制御 | -| ┣ ポーラスのリアクター制限時間 | -| ┗ エアシップのリアクター制限時間 | +| 設定名 | +| ---------------------------------- | +| サボタージュの時間制御 | +| ┣ ポーラスのリアクター制限時間 | +| ┣ エアシップのリアクター制限時間 | +| ┣ ファングルのリアクター制限時間 | +| ┗ ファングルのキノコカオス効果時間 | ## サボタージュのクールダウン制御 diff --git a/Resources/string.csv b/Resources/string.csv index 442a698e2..ca511e732 100644 --- a/Resources/string.csv +++ b/Resources/string.csv @@ -5,14 +5,14 @@ "#14 TChinese: NetherDragon_Tw (Edit: Soukunsandesu)" "## 役職" -"Neutral","Neutral","ニュートラル","独立阵营","中立陣營","Нейтрал","Neutro","" +"Neutral","Neutral","ニュートラル","独立","中立陣營","Нейтралов","Neutro","" "# バニラ役職" "Crewmate","Crewmate","クルーメイト","船员","船員","Член Экипажа","Tripulante","Tripulante" "Engineer","Engineer","エンジニア","工程师","工程師","Инженер","Engenheiro","Engenheiro" "Scientist","Scientist","科学者","科学家","科學家","Ученый","Cientista","Cientista" "GuardianAngel","Guardian Angel","守護天使","守护天使","守護天使","Ангел-хранитель","Anjo da Guarda","Anjo da Guarda" -"Impostor","Impostor","インポスター","内鬼","偽裝者","Предатель","Impostor","Impostor" +"Impostor","Impostor","インポスター","内鬼","偽裝者","Предателей","Impostor","Impostor" "Shapeshifter","Shapeshifter","シェイプシフター","变形者","變形者","Оборотень","Metamorfo","Metamorfo" "# 特殊インポスター役職" @@ -29,11 +29,11 @@ "TimeThief","Time Thief","タイムシーフ","蚀时者","時間竊賊","Вор Времени","Ladrão de Tempo","Ladrão Temporal" "Sniper","Sniper","スナイパー","狙击手","狙擊手","Снайпер","Sniper","Sniper" "EvilTracker","Evil Tracker","イビルトラッカー","邪恶的追踪者","邪惡的追蹤者","Злой Следопыт","Rastreador do Mal","Rastreador do Mal" -"Stealth","Stealth","ステルス","","","Хитрец","Furtivo","" -"NekoKabocha","Neko-Kabocha","ネコカボチャ","","","Неко-Кабоча","Neko-Kabocha","" -"EvilHacker","Evil Hacker","イビルハッカー","","","Злой Хакер","Hacker do Mal","" -"Penguin","Penguin","ペンギン","","","Пингвин","Pinguim","" -"Insider","Insider","インサイダー","","","Инсайдер","Informante","" +"Stealth","Stealth","ステルス","暗杀者","","Хитрец","Furtivo","" +"NekoKabocha","Neko-Kabocha","ネコカボチャ","猫又","","Неко-Кабоча","Neko-Kabocha","" +"EvilHacker","Evil Hacker","イビルハッカー","邪恶黑客","","Злой Хакер","Hacker do Mal","" +"Penguin","Penguin","ペンギン","企鹅","","Пингвин","Pinguim","" +"Insider","Insider","インサイダー","内幕人","","Инсайдер","Informante","" "# マッドメイト系役職" "Madmate","Madmate","マッドメイト","叛徒","叛徒","Безумец","Tripulante Louco","Tripulante Louco" @@ -65,14 +65,14 @@ "Egoist","Egoist","エゴイスト","野心家","利己主義者","Эгоист","Egoísta","Egoísta" "Lovers","Lovers","恋人","恋人","戀人","Любовники","Amantes","Amantes" "Jackal","Jackal","ジャッカル","豺狼","豺狼","Шакал","Lobo-Guará","Chacal" -"PlagueDoctor","Plague Doctor","ペスト医師","","","Чумной Доктор","Médico da Peste","" +"PlagueDoctor","Plague Doctor","ペスト医師","瘟疫医生","","Чумной Доктор","Médico da Peste","" "# HideAndSeek" "HASFox","Fox","狐","狐狸","狐妖","Лис","Raposa","Raposa" "HASTroll","Troll","トロール","猎人","誘捕者","Тролль","Troll","Troll" "# GM" -"GM","GM","GM","GM(管理员)","GM(遊戲大師)","Мастер Игры","MJ(Mestre de Jogo)","GM(Fantasma)" +"GM","GM","GM","GM(管理员)","GM(遊戲大師)","Мастер Игры","MJ(Mestre de Jogo)","MJ(Mestre do Jogo)" "# 属性" "LastImpostor","Last Impostor","ラストインポスター","绝境者","絕境者","Последний Предатель","Último Impostor","Último Impostor" @@ -80,10 +80,10 @@ "Workhorse","Workhorse","ワークホース","实干家","加班狂","Работник","Burro de Carga","" "# その他" -"Team","Team","陣営","","","","","" +"Team","Team","陣営","阵营","","Команда","","" "CustomRoleTypes.Crewmate","Crewmate","クルー","船员","","Членов Экипажа","Tripulante","" -"CustomRoleTypes.Impostor","Impostor","インポスター","内鬼","","Предателей","Impostor","" -"CustomRoleTypes.Neutral","Neutral","ニュートラル","独立","","Нейтралов","Neutro","" +"CustomRoleTypes.Impostor","Impostor","インポスター","内鬼","偽裝者","Предателей","Impostor","Impostor" +"CustomRoleTypes.Neutral","Neutral","ニュートラル","独立","中立陣營","Нейтралов","Neutro","" "CustomRoleTypes.Madmate","Mad","マッド","叛徒","","Безумцев","Louco","" "TeamCrewmate","Team Crewmates","クルー陣営","船员阵营","","Команда Членов Экипажа","Time Tripulantes","" "TeamImpostor","Team Impostors","インポスター陣営","内鬼阵营","幫助偽裝者","Команда Предателей","Time Impostor","Time Impostor" @@ -103,7 +103,7 @@ "VampireInfo","Bite and annihilate","クルーを噛んで全滅させよう","吸干他们的血","吸取他們的血","Прокусите всех Членов Экипажа","Morda e aniquile","Morda e aniquile" "WarlockInfo","Cast your curses","敵を呪い殺そう","给你的敌人下咒","借刀殺人","Прокляните всех Членов Экипажа","Lance sua maldição","Lance sua maldição" "WitchInfo","Cast your spells","敵に魔術をかけよう","诅咒你的敌人","施展你的魔法來讓你的敵人死亡","Заклинайте Членов Экипажа","Lance o seu feitiço","Lance o seu feitiço" -"MafiaInfo","Support the imposters and kill","インポスターの援助をしよう","帮助其他内鬼杀掉所有人","幫助偽裝者們殺死所有人","Помогите Предателям убить всех","Ajude os impostores e mate","Ajude os impostores e mate" +"MafiaInfo","Help the Impostors","インポスターの援助をしよう","帮助内鬼","幫助偽裝者","Помогите Предателям","Ajude os Impostores","Ajude os Impostores" "BeforeMafiaInfo","You can't kill yet","今はキルをすることができない","潜伏以等候时机","潛伏以等待時機","Вы еще не можете убивать","Você ainda não pode matar","Você ainda não pode matar" "AfterMafiaInfo","It's time to kill","サボを活用して皆殺しにしよう","杀光所有人","殺光所有人吧","Время убивать","Está na hora de matar","Está na hora de matar" "PuppeteerInfo","Force the Crewmate to kill","敵を操って皆殺しにしよう","操纵敌人,杀光船员","操控對象並殺光所有人","Заставьте Члена Экипажа убить","Force os tripulantes a matar","Force os tripulantes a matar" @@ -111,21 +111,21 @@ "SniperInfo","Snipe","狙い撃つぜ","瞄准敌人,射击!","讓你的敵人在你的狙擊下死亡","Стреляйте в Членов Экипажа на расстоянии","Hora de atirar","Hora de atirar" "LastImpostorInfo","You are the last of us","残ったのはあなただけ","你是狼村最后的希望…","你是狼村最後的希望...","Ты последний предатель","Você é o último Impostor","Você é o último Impostor" "EvilTrackerInfo","Track others","プレイヤーを追跡しろ","让我看看,我的小目标在哪","你不要過來啊啊阿","Отслеживайте Игроков","Localize os outros","Localize os outros" -"StealthInfo","Act unseen in the dark world...","闇の世界で暗躍せよ","","","Действуйте незаметно в темноте","Tabalhe sem ser visto no mundo escuro...","" -"NekoKabochaInfo","Take your killer to your grave","死なばもろとも","","","Отведи своего убийцу в могилу","Leve seu assassino para o túmulo","" -"EvilHackerInfo","Hack systems","システムをハッキングせよ","","","Взломайте систему","Hackeie sistemas","" -"PenguinInfo","Let's drag and kill!","ぺちぺち!","","","Давайте тащить и убивать!","Vamos arrastar e matar!","" -"InsiderInfo","Knowledge is power","知は力なり","","","Знание - сила!","Conhecimento é poder","" +"StealthInfo","Act unseen in the dark world...","闇の世界で暗躍せよ","降下黑暗!","","Действуйте незаметно в темноте","Tabalhe sem ser visto no mundo escuro...","" +"NekoKabochaInfo","Take your killer to your grave","死なばもろとも","带走杀死你的人","","Отведи своего убийцу в могилу","Leve seu assassino para o túmulo","" +"EvilHackerInfo","Hack systems","システムをハッキングせよ","破解系统","","Взломайте систему","Hackeie sistemas","" +"PenguinInfo","Let's drag and kill!","ぺちぺち!","扑哧扑哧!","","Давайте тащить и убивать!","Vamos arrastar e matar!","" +"InsiderInfo","Knowledge is power","知は力なり","知识就是力量","","Знание - сила!","Conhecimento é poder","" "# マッドメイト系役職" -"MadmateInfo","Help the Impostors","インポスターの援助をしよう","帮助内鬼","幫助偽裝者","Помогите Предателям","Ajude os Impostores","Ajude os Impostores" +"MadmateInfo","","インポスターの援助をしよう","帮助其他内鬼杀掉所有人","幫助偽裝者","Помогите Предателям убить всех","Ajude os Impostores","Ajude os Impostores" "BeforeMadmateInfo","Finish your tasks","タスクを済ませろ","完成你的任务","完成你的任務","Завершите свои задания","Termine as suas tarefas","Termine as suas tarefas" "MadGuardianInfo","Finish your tasks and help the Impostors","タスクを済ませ、インポスターの援助をしよう","完成任务后来帮助内鬼","完成你的任務並幫助偽裝者","Завершите свои задания чтобы помочь Предателям","Termine as suas tarefas e ajude os Impostores","Termine as suas tarefas e ajude os Impostores" -"MadSnitchInfo","Finish your tasks and help the Impostors","タスクを済ませ、インポスターの援助をしよう","完成任务后来帮助内鬼","完成你的任務並幫助偽裝者","Завершите свои задания чтобы помочь Предателям","Termine as suas tarefas e ajude os Impostores","Termine as suas tarefas e ajude os Impostores" +"MadSnitchInfo","","タスクを済ませ、インポスターの援助をしよう","完成任务后来帮助内鬼","完成你的任務並幫助偽裝者","Завершите свои задания, чтобы помочь Предателям","Termine as suas tarefas e ajude os Impostores","Termine as suas tarefas e ajude os Impostores" "SKMadmateInfo","You are now on Team Impostors","サイドキックにされた","你是内鬼的好帮手","你現在屬於偽裝者們了,盡你所能幫助他們","Теперь вы в команде Предателя","Você agora está no Time Impostor","Você agora está no Time Impostor" "# 特殊クルー役職" -"BaitInfo","Bait your enemies","敵を罠にはめよう","诱骗敌人,让敌人落入你的陷阱","犧牲小我,完成大我","Убийца моментально зарепортит ваш труп","Engane os seus inimigos","Engane os seus inimigos" +"BaitInfo","Trap your enemies","敵を罠にはめよう","引诱敌人落入你的陷阱当中","誘捕你的敵人","Ловите своих врагов","Prenda os seus inimigos","Prenda os seus inimigos" "LighterInfo","Light 'em up","すべてを照らそう","驱散黑暗,照亮前路","夜空中最亮的星","Увеличьте свой обзор выполнив свои задания","Luz para todo lado","Luz para todo lado" "MayorInfo","Your vote has more influence","自分の票が何倍もの力を持っている","你的投票更有分量","你的票數更多更有料","У вас больше голосов","O seu voto tem mais influência","O seu voto tem mais influência" "SabotageMasterInfo","Fix sabotages faster","より早くサボタージュを直そう","你是一个修理匠,修理本领强","更快的修理破壞","Устраните саботаж в одиночку","Conserte as sabotagens mais rápido","Conserte as sabotagens mais rápido" @@ -133,7 +133,7 @@ "SnitchInfo","Finish your tasks to find the Impostors","タスクを早く済ませよう","完成任务 揪出内鬼","完成你的所有任務來找到偽裝者","Завершите свои задания чтобы узнать Предателей","Termine as suas tarefas para dedurar os Impostores","Termine as suas tarefas para dedurar os Impostores" "SpeedBoosterInfo","Boost others' speed","走らせろ","让其他人跑起来吧","讓其他人跑得更快","Ускорьте случайного игрока","Impulsione a velocidade dos jogadores","Impulsione a velocidade dos jogadores" "DoctorInfo","And thus they died...","斯くして奴は死んだ","调查他人死因","查看他們的死因","Вы знаете причину смерти игроков","Veja os sinais vitais e causa da morte","Veja os sinais vitais e causa da morte" -"TrapperInfo","Trap your enemies","敵を罠にはめよう","引诱敌人落入你的陷阱当中","誘捕你的敵人","Ловите своих врагов","Prenda os seus inimigos","Prenda os seus inimigos" +"TrapperInfo","","敵を罠にはめよう","诱骗敌人,让敌人落入你的陷阱","誘捕你的敵人","Убийца моментально зарепортит ваш труп","Prenda os seus inimigos","Prenda os seus inimigos" "DictatorInfo","Decide who to eject","独裁政治をしよう","让我统治世界,拥有无上的权利","讓所有人臣服於你","Повесьте своего врага на страх и риск","Escolha quem será exilado","Escolha quem será exilado" "SeerInfo","You see the moment someone dies","他人の死んだ瞬間がわかる","你能感知死亡","你擁有陰陽眼","Вы видите когда умирают игроки","Veja o momento em que alguém morre","Veja o momento em que alguém morre" "TimeManagerInfo","Do the tasks and extend meeting time","タスクをして会議時間を延ばそう","任务搞快点,不就有时间开会了嘛","完成你的任務來延長會議時間","Выполняйте задания чтобы увеличить время встречи","Faça as tarefas e aumente o tempo de reunião","" @@ -141,7 +141,7 @@ "# ニュートラル役職" "ArsonistInfo","Burn them to crisps","燃やせ","火焰给我燃烧起来吧!","燒吧,燒吧,燃燒吧","Облейте и подожгите всех игроков","Queime tudo em pedacinhos","Queime tudo em pedacinhos" "JesterInfo","Get voted out","追放されよう","让他们把你这个假货投出去","想個辦法讓你被投出去","Заставь игроков изгнать себя","Seja exilado","Seja exilado" -"OpportunistInfo","Just stay alive","とにかく生き残りましょう","苟着吧,苟也是个不错的选择","盡你所能地活下去吧!","Останьтесь в живых","Sobreviva a qualquer custo","Sobreviva a qualquer custo" +"OpportunistInfo","Just stay alive","とにかく生き残りましょう","活下去吧!活到最后你就成为了赢家!","盡你所能地活下去吧!","Останьтесь в живых","Sobreviva a qualquer custo","Sobreviva a qualquer custo" "SchrodingerCatInfo","Get killed and join your killer's team","殺されて陣営に所属しろ","加入击杀者的阵营","打不過就加入","Дайте убить себя и присоединитесь к команде убийц","Ao morrer entre para o time que lhe matou","Ao morrer entre para o time que lhe matou" "CSchrodingerCatInfo","You are now on Team Crewmate","クルーの味方になった","你加入了船员阵营,帮助船员找出内鬼","你現在變成船員了, 幫助船員們找出偽裝者們和中立帶刀者","Теперь вы за Членов Экипажа","Você agora é do Time Tripulante","" "MSchrodingerCatInfo","You are now on Team Impostor","インポスターの味方になった","你加入了内鬼阵营,掩护自己的内鬼同伴,并且一起胜利","你現在變成偽裝者了,但是你不能殺人,盡量掩護你的隊友的身分","Теперь вы за Предателей","Você agora é do Time Impostor","Você agora é do Time Impostor" @@ -152,10 +152,10 @@ "EgoistInfo","Take over the Impostors' victory","インポスター勝利を独占しよう","夺走内鬼的胜利","讓我們來奪取偽裝者的勝利","Не дай Предателям победить","Ganhe no lugar do Impostor","Ganhe no lugar do Impostor" "LoversInfo","Live happily ever after, together","恋人と生きて幸せを掴もう","你们坠入了爱河,成为了一对恋人,一起活到最后吧!","你墜入了愛河","Выживите со своим Любовником","Vivam felizes para sempre, juntos","Vivam felizes para sempre, juntos" "JackalInfo","Kill Everyone","すべてを殺せ","快去杀光所有人,一只苍蝇都不要剩下!","殺光所有人不留活口","Убей всех игроков","Mate todos","Mate todos" -"PlagueDoctorInfo","Spread disease to wipe out the crew","ペストをばらまけ","","","Распространите чуму","Espalhe doenças para acabar com a tripulação","" +"PlagueDoctorInfo","Spread disease to wipe out the crew","ペストをばらまけ","在船员之中散布瘟疫","","Распространите чуму","Espalhe doenças para acabar com a tripulação","" "# HideAndSeek" -"HASFoxInfo","Just stay alive","とにかく生き残りましょう","活下去吧!活到最后你就成为了赢家!","盡你所能地活下去吧!","Останьтесь в живых","Sobreviva a qualquer custo","Sobreviva a qualquer custo" +"HASFoxInfo","","とにかく生き残りましょう","苟着吧,苟也是个不错的选择","","Останьтесь в живых","Sobreviva a qualquer custo","Sobreviva a qualquer custo" "HASTrollInfo","Get killed","自爆しよう","轰!你为了同伴牺牲了!","盡可能讓獵人殺死你","Будьте убитым","Seja morto","Seja morto" "# GM" @@ -181,11 +181,11 @@ "TimeThiefInfoLong","Every kill reduces discussion and voting time in meeting.\nIf you are voted out or killed, the lost time returns to meetings.","キルを行うと会議時間が減少する。\nタイムシーフが追放または殺害されると、失われた会議時間が返ってきます。","蚀时者每击杀一个人,会议时间就将减少一定时间。\n如果蚀时者死亡,被偷取的时间的会议时间将返还。","時間竊賊每殺死一個人,那麼會議時間就會減少一定時間,如果時間竊賊死亡,那麼會議時間將會恢復。","Каждое убийство Вора Времени сокращает время обсуждения и голосования на собраниях. \nВ зависимости от настроек потерянное время возвращается после того, как он будет убит или изгнан.","Cada morte reduz tempo de votação e discussão.\nSe você for exilado ou morto, o tempo perdido retorna para as reuniões.","Cada morte reduz tempo de votação e discussão.\nSe você for exilado ou morto, o tempo perdido retorna para as reuniões." "SniperInfoLong","You can shoot players from afar.\nYour line of fire continues as a straight line in the direction of the spot where you shapeshift to where you unshift.\nYou cannot perform normal kills until you use up all of your ammo.","遠くの敵を狙撃できるインポスター。\nシェイプシフトした地点から解除した地点の延長線上の敵を一人撃ち抜く。\n撃ちきるまで通常キル出来ない。","狙击手拥有远距离射杀的能力。\n方法为:变形的位置及解除变形位置的连线及其延长线上的一名玩家将被射杀。\n在狙击手的子弹耗尽前,狙击手无法进行常规击杀。","狙擊手擁有遠距離狙殺的技能,當狙擊手變形時會標記一個點(標記A),解除變形時也會標記一個點(標記B),標記A到標記B即為彈道,\n子彈將由標記A穿越彈道後再從標記B打出,並狙殺離這條彈道上最近的人(若有人處於彈道中則不會被狙殺),狙擊手在子彈用完之後可以正常殺人。","Снайпер может стрелять в игроков на расстоянии. \nОн убивает игрока который, находится с ним на одной линии, от точки Морфа до точки возвращения в свой облик. \nОн может совершать обычные убийства после того, как все его патроны закончатся.","Você pode atirar em jogadores de longe.\nSua linha de fogo continua numa linha reta, do ponto que você se metamorfa ao ponto que você volta ao normal.\nVocê não pode fazer mortes normais até usar toda a sua munição.","Você pode atirar em jogadores de longe.\nSua linha de fogo continua numa linha reta, do ponto que você se metamorfa ao ponto que você volta ao normal.\nVocê não pode fazer mortes normais até usar toda a sua munição." "EvilTrackerInfoLong","You can see where others are.\nYou will see arrows pointing to the other impostors and anyone you shapeshift into.\nYou will see a ""kill flash"" when your fellow impostors kill.","他人の位置が分かるインポスター。\n味方のインポスターとシェイプシフトで選んだ一人の位置が矢印で表示される。\n味方インポスターのキルによるキルフラッシュも見える。","邪恶追踪者可以追踪其他内鬼以及其所变形的玩家。\n玩家名称下面的箭头代表着目标的方向。\n当内鬼队友杀人时,邪恶追踪者将会看到击杀闪烁提示。","邪惡追蹤者可以通過變形來指定一個追蹤目標,變形後將會立刻解除變形,並且玩家名稱會出現一個箭頭指向目標,當隊友殺人時,邪惡追蹤者將會看到螢幕閃爍為提示。","Злой Следопыт может отслеживать других игроков. \nОн может видеть стрелки, которые указывают на Предателей или на того, в кого он превратился. \nОн может видеть когда было совершено убийство с помощью вспышки убийства.","Você consegue ver a posição de outros.\nÉ possível ver setas apontando para outros Impostores e qualquer um em que você se transforme.\nVocê também verá uma piscada de tela quando um aliado Impostor matar alguém.","Você consegue ver a posição de outros.\nÉ possível ver setas apontando para outros Impostores e qualquer um em que você se transforme.\nVocê também verá uma piscada de tela quando um aliado Impostor matar alguém." -"StealthInfoLong","When the Stealth kills, players in the same room are blinded for a short while.","キルを行うと、同じ部屋にいる他のプレイヤーの視界が少しの間暗転する。","","","Когда Хитрец убивает, игроки в одной локации будут ненадолго ослеплены","Quando o Furtivo mata, os jogadores na mesma sala ficam cegos por um curto período.","" -"NekoKabochaInfoLong","The Neko-Kabocha kills back their killer.","キルされた際、自分を殺してきたプレイヤーを殺し返す。","","","Неко-Кабоча убивает своего убийцу","O Neko-Kabocha mata de volta o seu assassino.","" -"EvilHackerInfoLong","The EvilHacker 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.\ne.g.)★Cafeteria: 3(DEAD×1)","会議直前のアドミン情報を見ることができる。\n誰もいない部屋は省略される。\nインポスターがいる部屋には★印が付く。\n死体がある部屋には死体数が表記される。\n例)★カフェテリア: 3(死体×1)","","","Злой Хакер может получить последнюю информацию на админке в начале встречи.\nНезанятые локации не показаны.\nA '★' Помечает локации с Предателями.\nЛокации с трупами помечаются количеством трупом) \nНапример: \n★Кафетерия: 3 (Мертвы×1)""","O Hacker do Mal pode obter as informações recentes do admin no início da reunião.\nAs salas desocupadas não são mostradas.\nUm '★' marca as salas com impostores.\nAs salas com mortos são marcadas com o número de corpos.\nEx:)★Cafeteria: 3( MORTO×1)","" -"PenguinInfoLong","Penguins can restrain target by pressing the kill button, and drag around.\While dragging, the target dies by pressing the kill button again or after a certain period of time.\nPress the kill button twice for a direct kill.","キルボタン一回で相手を拘束して連れまわすことが出来る。\nもう一度キルボタンを押すか一定時間経過でキルする。\nキルボタン2回で直接キル可能。","","","Пингвины могут удерживать цель, нажимая кнопку убийства, и перетаскивать ее.\Во время перетаскивания цель умирает, нажав кнопку убийства еще раз или через определенный промежуток времени.\nНажмите кнопку убийства дважды, чтобы убить напрямую.","Os Pinguins podem prender o alvo pressionando o botão de matar e arrastá-lo.\nEnquanto estiver arrastando, o alvo morre ao pressionar o botão de matar novamente ou após um determinado período de tempo.\nPressione o botão de matar duas vezes para matar imediatamente.","" -"InsiderInfoLong","You can see roles whose you killed.\nYou can also see roles and abilities of all Impostors.\nKIlling specified times tells you Madmate as well.","キルした相手の役職が分かる。\nまた、味方インポスターの役職と能力が見える。\nさらに、特定回数キルするとマッドメイトも分かる。","","","Вы можете увидеть роли, которых Вы убили\nВы также можете увидеть роли и способности всех Предателей.\nУбийство в указанное время также сообщает вам о Безумце.","Você pode ver as classes de quem matou.\nVocê também pode ver as classes e as habilidades de todos os Impostores.\nAo matar em horários específicos, você verá o Tripulante Louco.","" +"StealthInfoLong","When the Stealth kills, players in the same room are blinded for a short while.","キルを行うと、同じ部屋にいる他のプレイヤーの視界が少しの間暗転する。","当暗杀者完成击杀后,与暗杀者处于同一房间内的玩家会短暂失明。","","Когда Хитрец убивает, игроки в одной локации будут ненадолго ослеплены","Quando o Furtivo mata, os jogadores na mesma sala ficam cegos por um curto período.","" +"NekoKabochaInfoLong","The Neko-Kabocha kills back their killer.","キルされた際、自分を殺してきたプレイヤーを殺し返す。","当猫又被击杀时,猫又也会击杀凶手。","","Неко-Кабоча убивает своего убийцу","O Neko-Kabocha mata de volta o seu assassino.","" +"EvilHackerInfoLong","The EvilHacker 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.\ne.g.)★Cafeteria: 3(DEAD×1)","会議直前のアドミン情報を見ることができる。\n誰もいない部屋は省略される。\nインポスターがいる部屋には★印が付く。\n死体がある部屋には死体数が表記される。\n例)★カフェテリア: 3(死体×1)","邪恶黑客可以在会议上看到会议前的管理信息。\n无人的房间将被省略。\n有内鬼的房间标有★。\n有尸体的房间显示尸体数量\n例:★大厅: 3(尸体×1)","","Злой Хакер может получить последнюю информацию на админке в начале встречи.\nНезанятые локации не показаны.\nA '★' Помечает локации с Предателями.\nЛокации с трупами помечаются количеством трупом) \nНапример: \n★Кафетерия: 3 (Мертвы×1)""","O Hacker do Mal pode obter as informações recentes do admin no início da reunião.\nAs salas desocupadas não são mostradas.\nUm '★' marca as salas com impostores.\nAs salas com mortos são marcadas com o número de corpos.\nEx:)★Cafeteria: 3( MORTO×1)","" +"PenguinInfoLong","Penguins can restrain target by pressing the kill button, and drag around.\While dragging, the target dies by pressing the kill button again or after a certain period of time.\nPress the kill button twice for a direct kill.","キルボタン一回で相手を拘束して連れまわすことが出来る。\nもう一度キルボタンを押すか一定時間経過でキルする。\nキルボタン2回で直接キル可能。","企鹅使用击杀键可以拖拽目标。\n等到倒计时结束或再次按下击杀键则可以正常击杀目标。","","Пингвины могут удерживать цель, нажимая кнопку убийства, и перетаскивать ее.\Во время перетаскивания цель умирает, нажав кнопку убийства еще раз или через определенный промежуток времени.\nНажмите кнопку убийства дважды, чтобы убить напрямую.","Os Pinguins podem prender o alvo pressionando o botão de matar e arrastá-lo.\nEnquanto estiver arrastando, o alvo morre ao pressionar o botão de matar novamente ou após um determinado período de tempo.\nPressione o botão de matar duas vezes para matar imediatamente.","" +"InsiderInfoLong","You can see roles whose you killed.\nYou can also see roles and abilities of all Impostors.\nKIlling specified times tells you Madmate as well.","キルした相手の役職が分かる。\nまた、味方インポスターの役職と能力が見える。\nさらに、特定回数キルするとマッドメイトも分かる。","内幕人可以看到自己击杀的人的职业。\n还可以看到队友的位置和能力。\n此外,如果内幕人完成了指定的击杀数,则可以看到谁是叛徒。","","Вы можете увидеть роли, которых Вы убили\nВы также можете увидеть роли и способности всех Предателей.\nУбийство в указанное время также сообщает вам о Безумце.","Você pode ver as classes de quem matou.\nVocê também pode ver as classes e as habilidades de todos os Impostores.\nAo matar em horários específicos, você verá o Tripulante Louco.","" "# マッドメイト系役職" @@ -218,7 +218,7 @@ "OpportunistInfoLong","So long as you are alive at the end of the game, you will win alongside whoever the victor is.","試合終了時に生存していれば追加勝利となる。","若投机者在游戏结束时存活,则投机者跟随获胜玩家一同获得胜利。","如果投機主義者活到最後,他將跟著遊戲結束獲勝的陣營一起獲勝。","Выживший выигрывает игру с любыми другими ролями, но только если он выжил.","Contanto que você esteja vivo no final do jogo, você dividirá a vitória ao lado do vencedor.","" "EgoistInfoLong","When all impostors are dead, you solo victory by fulfilling impostor victory conditions.\nYou and the impostors know who each other are.","味方がすべて死んだ状態でインポスターが勝つと単独勝利する。\nインポスターは誰がエゴイストか分かる。エゴイストも、誰がインポスターか分かる。","原则上野心家属于内鬼阵营。野心家与内鬼阵营玩家互认但不可以击杀对方。\n当其他内鬼阵营玩家全部死亡后,若野心家存活且内鬼阵营达成胜利条件,则野心家单独获得胜利。","如果所有的偽裝者都死亡,且利己主義者存活,利己主義者將獨自獲勝。\n(偽裝者和利己主義者互相知道對方但是不可以互刀對方)","После того, как все Предатели умрут то Эгоист побеждает вместо Предателей. \nПредатели и Эгоист видят друг друга.","Quando todos os Impostores morrerem, você ganha sozinho assumindo o papel de Impostor. \nVocê e os Impostores sabem quem são uns aos outros.","" "JackalInfoLong","Jackal can kill all Crewmates, Impostors and Neutrals.\nTeam Jackal wins when living Jackal outnumbers living Crewmates and when there are no Impostors alive.","ジャッカルはすべてのプレイヤーを殺すことができる。\nインポスターが残っておらず、生き残っているジャッカルの人数がクルーと同じかそれ以上でジャッカルが勝利する。","豺狼需要击杀所有人。\n存活的玩家只剩豺狼和一名其他船员时,豺狼获得胜利。","豺狼需要殺死所有人來獲得勝利,\n如果場上存活的玩家只剩下豺狼和另一名不帶刀職業時,豺狼將獲勝。","Шакал может убить всех Членов Экипажа, Нейтралов и Предателей тоже. \nШакал может победить, когда в живых остался только 1 Шакал и 1 Член Экипажа.","Você pode matar todos os jogadores. \nGanhe quando não existirem mais Impostores, e o número de Guarás for maior que o de Tripulantes.","" -"PlagueDoctorInfoLong","The Plague Doctor's goal is to infect every living player.\nThey start by choosing one player to infect, after which anyone who spends a set\namount of time in range of the infected player becomes infected themselves.\nInfection progress is cumulative, and does not reset with distance or after meetings.","ペスト医師ははすべてのプレイヤーに感染を広げることが目的。\nキルで最初の感染者を選ぶ。接触感染していきすべてのプレイヤーに感染させたら勝利。会議では感染はリセットされない","","","Цель Чумного Доктора - заразить всех живых игроков.\nОн выбирает одного игрока для заражения с помощью кнопки 'Убить', после чего игрок который будет в радиусе зараженного игрока в течении X времени, станет зараженным.\nПрогресс заражения не сбрасывается после встреч и т.д.","O objetivo do Médico da Peste é infectar todos os jogadores vivos.\nEles começam escolhendo um jogador para infectar e, depois disso, qualquer pessoa que passar um período de tempo definido próxima do jogador infectado será infectada também.\nO progresso da infecção é cumulativo e não é reiniciado com a distância ou após reuniões.","" +"PlagueDoctorInfoLong","The Plague Doctor's goal is to infect every living player.\nThey start by choosing one player to infect, after which anyone who spends a set\namount of time in range of the infected player becomes infected themselves.\nInfection progress is cumulative, and does not reset with distance or after meetings.","ペスト医師ははすべてのプレイヤーに感染を広げることが目的。\nキルで最初の感染者を選ぶ。接触感染していきすべてのプレイヤーに感染させたら勝利。会議では感染はリセットされない","瘟疫医生的目标是感染所有玩家。\n使用击杀键选择第一个要感染的人。瘟疫通过接触传染,并且不会因为会议打断进度。","","Цель Чумного Доктора - заразить всех живых игроков.\nОн выбирает одного игрока для заражения с помощью кнопки 'Убить', после чего игрок который будет в радиусе зараженного игрока в течении X времени, станет зараженным.\nПрогресс заражения не сбрасывается после встреч и т.д.","O objetivo do Médico da Peste é infectar todos os jogadores vivos.\nEles começam escolhendo um jogador para infectar e, depois disso, qualquer pessoa que passar um período de tempo definido próxima do jogador infectado será infectada também.\nO progresso da infecção é cumulativo e não é reiniciado com a distância ou após reuniões.","" "# HideAndSeek" "HASFoxInfoLong","(HideAndSeek):\nThey win the game with other Roles (except Troll) only if they are alive at the game end.","(かくれんぼ):\nトロールを除くいずれかの陣営が勝利したときに生き残っていれば、勝利した陣営に追加で勝利することができる。","(躲猫猫):\n狐狸活到最后便与获胜阵营一同获胜。","(躲貓貓):\n除了其他的中立陣營以外,只要狐妖活下來即可獲勝\n他們將跟著遊戲結束的獲勝陣營一起獲勝。","(Прятки):\nЕсли какая-либо роль, кроме Тролля побеждает и выживает, то победившая роль может одержать дополнительную победу.","(Esconde-Esconde): \nEles ganham adicionalmente com qualquer classe (exceto Troll), se estiverem vivos no final.","" @@ -233,7 +233,7 @@ "WorkhorseInfoLong","(Add-ons):\nAn Add-on granted to the first living Crewmate finishing all the tasks.\nYou are assigned additional tasks necessary for the tasks win.\nNot granted to roles with no tasks or with abilities triggered by finishing tasks.","(属性):\n最初に生きてタスクを終えたクルーに付与される属性。\n追加タスクが割り当てられる。\nクルーメイト以外にも割り当てる設定でもタスクが無い、タスク完了で能力が発動する役職には付与されない。","(附加效果):\n该附加效果赋予给第一个完成所有任务并存活的船员。\n你需要完成额外的任务来达成任务胜利。\n此效果不会赋予那些没有任务或者通过完成任务才能使用能力的诸多职业。","(屬性):\n此效果會被賦予在第一個完成任務且存活的船員。\n實習生必須做完附加任務來獲勝,\n此效果不會賦予在那些需要通過完成任務來觸發技能的職業上。","(Атрибут):\nДополнительные задания присваиваются первому живому Члену Экипажа, который выполнит все задания. \nЕму назначаются дополнительные задания, необходимые для победы с помощью заданий. \nНе может присваиваться ролям которые не имеют заданий, или ролям со способностями которые активируются после выполнения заданий.","(Atributos):\nUm atributo dado ao primeiro tripulante que finalizar todas as tarefas.\nVocê recebe tarefas adicionais necessárias para vencer. \nNão é dado a classes quem não têm tarefas, ou com habilidades ativadas ao finalizar todas as tarefas.","" "# ヘルプ" -"Basis","Basis","判定","","","","","" +"Basis","Basis","判定","基于","","Вердикт","","" "#モードオプション" "HideAndSeek","Hide and Seek","かくれんぼ","躲猫猫","躲貓貓","Прятки","Esconde-Esconde","" @@ -241,11 +241,11 @@ "SyncButtonMode","Sync Button Mode","ボタン回数同期モード","所有船员共享会议次数","全場拍桌數同步模式","Общая кнопка встречи","Modo de Botão Sincronizado","" "RandomMapsMode","Random Maps Mode","ランダムマップモード","随机地图模式","隨機地圖模式","Случайная карта","Modo de Mapas Aleatórios","" "SyncedButtonCount","Max Number of Buttons Allowed","合計ボタン使用可能回数","紧急会议可用次数","全場最大拍桌數量","Максимальное количество нажатий на Кнопку","Número Máximo de Usos do Botão","" -"AddedTheSkeld","Include TheSkeld","TheSkeldを追加","添加骷髅舰地图","將The Skeld地圖列入選項","Добавить TheSkeld","Incluir TheSkeld","" -"AddedMIRAHQ","Include MIRAHQ","MIRAHQを追加","添加米拉总部地图","將MIRA HQ地圖列入選項","Добавить MiraHQ","Incluir MIRAHQ","" +"AddedTheSkeld","Include TheSkeld","TheSkeldを追加","添加骷髅舰地图","將The Skeld地圖列入選項","Добавить The Skeld","Incluir TheSkeld","" +"AddedMIRAHQ","Include MIRAHQ","MIRAHQを追加","添加米拉总部地图","將MIRA HQ地圖列入選項","Добавить MIRA HQ","Incluir MIRAHQ","" "AddedPolus","Include Polus","Polusを追加","添加波鲁斯地图","將Polus地圖列入選項","Добавить Polus","Incluir Polus","" -"AddedTheAirShip","Include TheAirShip","TheAirShipを追加","添加飞艇地图","將The AirShip列入選項","Добавить TheAirship","Incluir TheAirShip","" -"AddedTheFungle","Include TheFungle","TheFungleを追加","","","","","" +"AddedTheAirShip","Include TheAirShip","TheAirShipを追加","添加飞艇地图","將The AirShip列入選項","Добавить The Airship","Incluir TheAirShip","" +"AddedTheFungle","Include TheFungle","TheFungleを追加","添加蘑菇岛地图","","Добавить The Fungle","","" "AllAliveMeeting","Meeting When No One is Dead","全員生存時の会議","全员存活时的会议设定","全員存活會議","Все живые на собрании","Reunião Com Todos Vivos","" "AllAliveMeetingTime","Meeting Time When No One is Dead","全員生存時の会議時間","全员存活时的会议时间","全員存活會議時間","Время когда все живы на собрании","Tempo de Reunião Com Todos Vivos","" "AdditionalEmergencyCooldown","Additional Emergency Cooldown","追加の緊急ボタンクールダウン","附加紧急会议冷却时间","附加緊急會議冷卻時間","Дополнительный откат собраний","Tempo de Emergência Adicional","" @@ -261,7 +261,7 @@ "DisableStartReactorTask","Disable StartReactor Tasks","原子炉起動タスク","禁用启动反应堆任务","禁用啟動反應堆任務","Отключить задание ''Запустить Реактор''","Desativar Tarefas de Acionar Reator","" "DisableResetBreakerTask","Disable ResetBreaker Tasks","ブレーカーリセットタスク","禁用重置反应堆任务","禁用重置斷路器任務","Отключить задание ''Рычаги(Airship)''","Desativar Reiniciar Disjuntores","" "SuffixMode","Suffix","名前の二行目","附加标签","名字標籤","Суффикс","Sufixo","" -"SuffixMode.None","None","なし","无","無","Ничего","Nenhum","" +"SuffixMode.None","Never","なし","不更换","關閉","Никогда","Nunca","" "SuffixMode.Version","Version","バージョン","版本","版本","Версия","Versão","" "SuffixMode.Streaming","Streaming","配信中","直播中","直播中","Стримит","Ao Vivo","" "SuffixMode.Recording","Recording","録画中","录制中","錄影中","Записывает","Gravando","" @@ -286,32 +286,32 @@ "WhenSkipVoteIgnoreNoDeadBody","Ignore When No DeadBody","死体がない時を除く","无尸体时忽略","沒有屍體時無法選擇","Игнорировать когда Нет Трупов","Ignorar Se Não Tiver Corpo","" "WhenSkipVoteIgnoreEmergency","Ignore When Emergency Button","緊急ボタンを除く","忽略紧急会议按钮","緊急會議中無法選擇","Игнорировать кнопку собраний","Ignorar Se Tiver Botão de Emergência","" "WhenNonVote","When No Votes","無投票時","不投票相当于投给自己","沒有投票時","Когда никто не Голосовал","Quando Sem Votos","" -"Default","Default","デフォルト","默认","預設","Обычное","Padrão","" -"Suicide","Suicide","自殺","自杀","自殺","Самоубийство","Suicídio","" +"Default","Default","デフォルト","默认随机算法","預設算法","По умолчанию","Padrão","" +"Suicide","Suicide","自殺","自杀","自殺","Суицид","Suicídio","" "SelfVote","Self Vote","自投票","自票","投自己","Само Голос","Votar Em Si","" "Skip","Skip","スキップ","跳过","跳過","Пропуск","Pular","" "WhenTie","When Tied Vote","同数投票時","平票时","平票時","Когда ничья","Quando Empatar Votos","" -"TieMode.Default","Default","デフォルト","默认","預設","Обычное","Padrão","" +"TieMode.Default","","デフォルト","默认随机算法","預設","По умолчанию","","" "TieMode.All","Eject All","全員追放","全体放逐","全員放逐","Изгнать всех","Exilar Todos","" "TieMode.Random","Eject Random","ランダムに追放","随机放逐","隨機放逐","Изгнать случайно","Exilar Aleatório","" "DisableDevices","Disable Devices","デバイスを無効化","禁用设备","禁用裝置","Отключить устройства","Desativar Dispositivos","" -"DisableSkeldDevices","Disable Skeld Devices","スケルドのデバイス無効化","禁用骷髅舰设备","禁用The Skeld中的設備","Отключить устройства на TheSkeld","Desativar Dispositivos de Skeld","" -"DisableMiraHQDevices","Disable MiraHQ Device","ミラHQのデバイス無効化","禁用米拉总部设备","禁用Mira HQ中的設備","Отключить устройства на MiraHQ","Desativar Dispositivos de MiraHQ","" +"DisableSkeldDevices","Disable Skeld Devices","スケルドのデバイス無効化","禁用骷髅舰设备","禁用The Skeld中的設備","Отключить устройства на The Skeld","Desativar Dispositivos de Skeld","" +"DisableMiraHQDevices","Disable MiraHQ Device","ミラHQのデバイス無効化","禁用米拉总部设备","禁用Mira HQ中的設備","Отключить устройства на MIRA HQ","Desativar Dispositivos de MiraHQ","" "DisablePolusDevices","Disable Polus Device","ポーラスのデバイス無効化","禁用波鲁斯设备","禁用Polus中的設備","Отключить устройства на Polus","Desativar Dispositivos de Polus","" -"DisableAirshipDevices","Disable Airship Device","エアシップのデバイス無効化","禁用飞艇设备","禁用The Airship中的設備","Отключить устройства на Airship","Desativar Dispositivos de Airship","" -"DisableFungleDevices","Disable Fungle Devices","ファングルのデバイス無効化","","","","","" +"DisableAirshipDevices","Disable Airship Device","エアシップのデバイス無効化","禁用飞艇设备","禁用The Airship中的設備","Отключить устройства на The Airship","Desativar Dispositivos de Airship","" +"DisableFungleDevices","Disable Fungle Devices","ファングルのデバイス無効化","禁用蘑菇岛设备","","Отключить устройства на The Fangle","","" "DisableSkeldAdmin","Disable Admin","アドミン無効化","禁用管理室地图","禁用管理室地圖","Отключить стол администратора","Desativar Admin","" -"DisableMiraHQAdmin","Disable Admin","アドミン無効化","禁用管理室地图","禁用管理室地圖","Отключить стол администратора","Desativar Admin","" -"DisablePolusAdmin","Disable Admin","アドミン無効化","禁用管理室地图","禁用管理室地圖","Отключить стол администратора","Desativar Admin","" +"DisableMiraHQAdmin","","アドミン無効化","禁用管理室地图","禁用管理室地圖","Отключить стол администратора","","" +"DisablePolusAdmin","","アドミン無効化","禁用管理室地图","禁用管理室地圖","Отключить стол администратора","","" "DisableAirshipCockpitAdmin","Disable Cockpit Admin","アドミン無効化(コックピット)","禁用飞艇(驾驶舱)管理室地图","禁用The Airship(駕駛艙)的管理室地圖","Отключить стол администратора в ''Кабине''","Desativar Admin da Cabine","" "DisableAirshipRecordsAdmin","Disable Records Admin","アドミン無効化(アーカイブ)","禁用飞艇(档案室)管理室地图","禁用The Airship(檔案室)的管理室地圖","Отключить стол администратора в ''Архиве''","Desativar Admin da Sala de Arquivos","" -"DisableSkeldCamera","Disable Camera","カメラ無効化","禁用骷髅舰监控","禁用骷髅舰监控设备","Отключить камеры","Desativar Câmeras","" -"DisablePolusCamera","Disable Camera","カメラ無効化","禁用波鲁斯监控设备","禁用波鲁斯监控设备","Отключить камеры","Desativar Câmeras","" -"DisableAirshipCamera","Disable Camera","カメラ無効化","禁用飞艇监控","禁用飞艇监控设备","Отключить камеры","Desativar Câmeras","" +"DisableSkeldCamera","Disable Camera","カメラ無効化","禁用飞艇监控","禁用飞艇监控设备","Отключить камеры","Desativar Câmeras","" +"DisablePolusCamera","","カメラ無効化","禁用监控","禁用波鲁斯监控设备","Отключить камеры","Desativar Câmeras","" +"DisableAirshipCamera","","カメラ無効化","禁用监控","禁用飞艇监控设备","Отключить камеры","Desativar Câmeras","" "DisableMiraHQDoorLog","Disable DoorLog","ドアログ無効化","禁用米拉总部门禁记录","禁用米拉总部门禁日志","Отключить журналы","Desativar Portaria","" -"DisablePolusVital","Disable Vital","バイタル無効化","禁用波鲁斯生命监测装置","禁用波鲁斯生命监测装置","Отключить пульсы","Desativar Vitais","" -"DisableAirshipVital","Disable Vital","バイタル無効化","禁用飞艇生命监测装置","禁用飞艇生命监测装置","Отключить пульсы","Desativar Vitais","" -"DisableFungleVital","Disable Vital","バイタル無効化","","","","","" +"DisablePolusVital","Disable Vital","バイタル無効化","禁用飞艇生命监测装置","禁用飞艇生命监测装置","Отключить пульсы","Desativar Vitais","" +"DisableAirshipVital","","バイタル無効化","禁用蘑菇岛生命监测装置","","Отключить пульсы","Desativar Vitais","" +"DisableFungleVital","","バイタル無効化","禁用生命监测装置","","Отключить пульсы","","" "IgnoreConditions","Ignore Conditions","除外条件","忽略条件","忽略條件","Игнорируют условия","Ignorar Condições","" "IgnoreImpostors","Ignore Impostors","インポスターを除く","忽略内鬼","偽裝者陣營除外","Игнорируют Предатели","Ignorar Impostores","" "IgnoreMadmates","Ignore Madmates","マッドメイト系を除く","忽略叛徒","叛徒職業除外","Игнорируют Безумцы","Ignorar Tripulantes Loucos","" @@ -322,26 +322,26 @@ "DisableAirshipViewingDeckLightsPanel","Disable Viewing Deck Lights Panel(Airship)","展望の配電盤を無効化(エアシップ)","禁用瞭望台配电箱(飞艇地图)","關閉觀景台的配電箱 (Airship)","Отключить починку света на ''Смотровой Палубе'' (Airship)","Desativar Painel de Luzes do Deck Panorâmico(Airship)","" "DisableAirshipGapRoomLightsPanel","Disable Gap Room Lights Panel(Airship)","昇降機の配電盤を無効化(エアシップ)","禁用升降机配电箱(飞艇地图)","關閉間隙室右側的配電箱 (Airship)","Отключить починку света в ''Комнате Пролета'' (Airship)","Desativar Painel de Luzes da Sala Suspensa(Airship)","" "DisableAirshipCargoLightsPanel","Disable Cargo Lights Panel(Airship)","貨物室の配電盤を無効化(エアシップ)","禁用货舱配电箱(飞艇地图)","關閉貨艙的配電箱 (Airship)","Отключить починку света в ''Грузовом Отсеке'' (Airship)","Desativar Painel de Luzes das Cargas(Airship)","" -"BlockDisturbancesToSwitches","Block Switches When They Are Up","配電盤妨害を無効化","","","Блокировать переключатели когда они подняты","Interruptores Sempre Ligados","" +"BlockDisturbancesToSwitches","Block Switches When They Are Up","配電盤妨害を無効化","禁用电力破坏","","Блокировать переключатели когда они подняты","Interruptores Sempre Ligados","" "MapModification","Map Modifications","マップ改造","地图修改","","Модификации для карт","Modificações do Mapa","" "DisableAirshipMovingPlatform","Disable Moving Platform(Airship)","昇降機のリフトを無効化(エアシップ)","禁用升降机(飞艇地图)","","Отключить движущуюся платформу (Airship)","Desativar Plataformas Voadoras(Airship)","" "AirShipVariableElectrical","Variable Electrical(AirShip)","電気室の構造変化(エアシップ)","改变配电室构造(飞艇地图)","電力室構造變化 (Airship)","Двери в Электрощитовой меняются случайно (Airship)","Elétrica Varia(AirShip)","" -"ResetDoorsEveryTurns","Reset Doors After Meeting(Airship/Polus/Fungle)","会議後にドア状況をリセットする(エアシップ・ポーラス・ファングル)","","","Сбросить статус дверей после собраний","Redefinir Portas Após Reunião(Airship/Polus)","" -"DoorsResetMode","Reset Mode","リセットモード","","","Режим сброса дверей","Modo de Redefinição","" -"AllOpen","All Open","全て開放","","","Все Открыты","Todas Abertas","" -"AllClosed","All Closed","全て閉鎖","","","Все Закрыты","Todas Fechadas","" -"RandomByDoor","Random By Door","ドアごとにランダム","","","Случайно для каждой двери","Aleatoriamente Por Porta","" -"DisableFungleSporeTrigger","Prevent Spores Trigger(Fungle)","きのこの胞子を無効化(ファングル)","","","","","" +"ResetDoorsEveryTurns","Reset Doors After Meeting(Airship/Polus/Fungle)","会議後にドア状況をリセットする(エアシップ・ポーラス・ファングル)","每次会议后重置门的状态(飞艇/波鲁斯/蘑菇岛)","","Сбросить статус дверей после собраний","Redefinir Portas Após Reunião(Airship/Polus)","" +"DoorsResetMode","Reset Mode","リセットモード","重置门状态为","","Режим сброса дверей","Modo de Redefinição","" +"AllOpen","All Open","全て開放","全部开启","","Все Открыты","Todas Abertas","" +"AllClosed","All Closed","全て閉鎖","全部关闭","","Все Закрыты","Todas Fechadas","" +"RandomByDoor","Random By Door","ドアごとにランダム","随机开启或关闭","","Случайно для каждой двери","Aleatoriamente Por Porta","" +"DisableFungleSporeTrigger","Prevent Spores Trigger(Fungle)","きのこの胞子を無効化(ファングル)","禁用蘑菇混合(蘑菇岛地图)","","Отключить триггер спор (Fungle)","","" "RandomSpawn","Random Spawn","ランダムスポーン","随机出生点","隨機出生點","Случайный спавн","Spawn Aleatório","" "CommsCamouflage","Camouflage During Comms Sabotage","コミュサボ時のカモフラージュ","通信破坏时伪装","通訊破壞時所有玩家變成小灰人","Камуфляж при Саботаже Связи","Camuflagem Durante Comunicação","" "EnableDebugMode","Enable Debug Mode","デバッグモードを有効化する","开启调试模式","啟用偵錯模式","Включить режим отладки","Ativar Modo de Depuração","" "ChangeNameToRoleInfo","Show Role Descriptions to Unmodded Client","役職説明を非modクライアントにも表示する","对未安装本mod的玩家显示职业说明","對未安裝本模組的玩家顯示職業說明","Показать краткую информацию о роли в начале игры","Mostrar Descrição de Classe para Clientes Sem Mod","" "RoleAssigningAlgorithm","Role Assigning Algorithm","役職割り当てのアルゴリズム","职业分配算法","職業分配算法","Алгоритм назначения Ролей","Algoritmo de Atribuição de Classes","" -"RoleAssigningAlgorithm.Default","Default","デフォルト","默认随机算法","預設算法","По умолчанию","Padrão","" -"RoleAssigningAlgorithm.NetRandom",".NET System.Random",".NET System.Random",".NET 系统随机算法","NET系統隨機算法","Случайный","Sistema Aleatório .NET","" -"RoleAssigningAlgorithm.HashRandom","HashRandom","HashRandom","哈希随机算法","Hash值隨機算法","HashRandom","HashRandom","" -"RoleAssigningAlgorithm.Xorshift","Xorshift","Xorshift","Xorshift随机算法","Xorshift隨機算法","Xorshift","Xorshift","" -"RoleAssigningAlgorithm.MersenneTwister","Mersenne Twister","Mersenne Twister","Mersenne Twister随机算法","Mersenne Twister隨機算法","MersenneTwister","Mersenne Twister","" +"RoleAssigningAlgorithm.Default","","デフォルト","默认","預設算法","По умолчанию","Padrão","" +"RoleAssigningAlgorithm.NetRandom","",".NET System.Random",".NET 系统随机算法","NET系統隨機算法","Случайный","Sistema Aleatório .NET","" +"RoleAssigningAlgorithm.HashRandom","","HashRandom","哈希随机算法","Hash值隨機算法","HashRandom","","" +"RoleAssigningAlgorithm.Xorshift","","Xorshift","Xorshift随机算法","Xorshift隨機算法","Xorshift","","" +"RoleAssigningAlgorithm.MersenneTwister","","Mersenne Twister","Mersenne Twister随机算法","Mersenne Twister隨機算法","MersenneTwister","","" "ApplyDenyNameList","Apply DenyName List","DenyNameリストを適用する","启用违禁昵称名单","自動禁止具有不良名字的人加入","Применить файл запрещённых имён (DenyName)","Aplicar Lista de Nomes Proibidos (DenyName)","" "KickPlayerFriendCodeNotExist","Kick Players Whose Friend Code Does Not Exist","フレンドコードが存在しないプレイヤーをキックする","踢出好友编号无效的玩家","將沒有好友代碼的玩家自動踢出","Кикнуть игроков у которых нет Кода Друга","Expulsar Jogadores Sem Código de Amigo","" "ApplyBanList","Apply BanList","BANリストを適用する","启用封禁名单","啟用封禁名單","Применить файл с забаненными игроками (BanList)","Aplicar Lista de Banimentos (BanList)","" @@ -370,7 +370,7 @@ "RoleTypeMax","Maximum %roleType% Roles","%roleType%役職の最大人数","%roleType%职业的最大人数","","Максимум ролей для %roleType%","Máximo de Classes %roleType%","" "%roleTypes%Maximum","Max Players In %roleTypes%","%roleTypes%の最大アサイン数","%roleTypes%最大玩家数","","Максимум для %roleTypes%","Máximo de Jogadores em %roleTypes%","" "FixedRole","Fixed Role","役職を固定","固定职业","","Фиксированная Роль","Classe Fixa","" -"Role","Role","役職","职业","","Роль","Classe","" +"Role","Roles","役職","职业","職業","Роли","Classes","" "BountyTargetChangeTime","Time Until Target Swaps","ターゲット変更時間","赏金目标切换时间","賞金目標切換時間","Время смены цели","Tempo Para Troca de Alvos","" "BountySuccessKillCooldown","Kill Cooldown After Killing Bounty","ターゲット殺害時のキルクール","赏金猎人击杀赏金目标的奖励冷却时间","賞金獵人殺死賞金目標冷卻","Перезарядка после убийства цели","Tempo de Recarga ao Matar Alvo","" @@ -378,13 +378,13 @@ "BountyShowTargetArrow","Show Arrow Pointing To Target","ターゲットへの矢印を表示する","赏金猎人的目标以箭头显示位置","賞金獵人獲得指向目標的箭頭","Показывать стрелку указывающую на Цель","Mostrar Seta Apontando ao Alvo","" "DefaultShapeshiftCooldown","Default Shapeshift Cooldown","デフォルトの変身クールダウン","默认变形冷却时间","預設變身時間","Обычная перезарядка Оборотня","Tempo de Recarga Padrão (Mutar)","" "VampireKillDelay","Kill Delay","殺害までの時間(秒)","吸血目标延迟死亡时间","殺人延遲","Длительность укуса(Секунды)","Atraso do Abate (S)","" -"MareAddSpeedInLightsOut","Add Mare Speed With Lights Out","停電時のメアーの加速値","梦魇熄灯时的额外速度","關燈時黑暗博士的額外速度","Скорость Ночного при Саботаже Света","Velocidade Adicional do Mare em Apagão","" +"MareAddSpeedInLightsOut","Add Mare Speed With Lights Out","停電時のメアーの加速値","梦魇熄灯时的额外速度","關燈時黑暗博士的額外速度","Добавить скорость Ночному при саботаже света","Velocidade Adicional do Mare em Apagão","" "MareKillCooldownInLightsOut","Kill Cooldown During Fix Lights","停電時のメアーのキルクール","梦魇熄灯时的击杀冷却","關燈時黑暗博士的殺人冷卻","Откат убийства Ночного при Саботаже Света","Tempo de Recarga (abate) Durante Apagão","" "SabotageMasterSkillLimit","Ability Use Count(Excluding Doors)","修理能力を使用できる回数(ドア閉鎖は除く)","修理大师修理破坏的最大次数","修理工修理破壞次數上限","Лимит способности (Кроме открытия дверей)","Máximo de Usos da Habilidade (Menos Portas)","" "CanMakeMadmateCount","Sidekick Madmate Max Count","サイドキックマッドメイト(人)","变形者可以招募叛徒的数量","變形者招募叛徒最大人數","Максимум союзников Безумца","Máximo de Tripulantes Loucos Ajudantes","" "MadSnitchTasks","Mad Snitch Tasks","マッドスニッチのタスク数","背叛的告密者任务数","背叛告密者任務數量","Задания Безумного Стукача","Tarefas do Dedo-Duro Louco","" "MadSnitchCanAlsoBeExposedToImpostor","Known to Impostors","インポスターからも視認できる","对内鬼同样可见","對偽裝者同樣可見","Также не защищен от Предателей","Visível Para Impostor","" -"MadSnitchTaskTrigger","Tasks Until Boost Activated","効果を発動するタスク数","","","Количество задач повышающие скорость","Tarefas Para Ativar Impulso","" +"MadSnitchTaskTrigger","Tasks Until Boost Activated","効果を発動するタスク数","效果发动所需任务数","效果發動所需任務數","Задачи повышающие скорость","Tarefas Para Ativar Impulso","" "MadGuardianCanSeeWhoTriedToKill","Can See Attempted Murderer","自身の殺害未遂者を知ることができる","背叛的守卫可以得知尝试对其击杀的玩家","背叛天使可以看到是誰嘗試殺害自己","Может видеть кто пытался его убить","Pode Ver Quem Tentou Matar","" "MadmateCanFixLightsOut","Mad Roles Can Fix Lights","マッドメイト系役職が停電を直せる","叛徒系职业可以修理照明破坏","叛徒職業的玩家可以修理電燈","Безумцы могут чинить Свет","Loucos Podem Consertar Luzes","" "MadmateCanFixComms","Mad Roles Can Fix Comms","マッドメイト系役職が通信障害を直せる","叛徒系职业可以修理通讯","叛徒職業的玩家可以修理通訊","Безумцы могут чинить Связь","Loucos Podem Consertar Comunicações","" @@ -397,8 +397,8 @@ "MadmateVentMaxTime","Mad Roles Max Vent Duration","マッドメイト系役職のベント内での最大時間","叛徒系职业在管道中停留的最大时间","叛徒職業的玩家在管道中可以停留的最大時間","Время использования вентиляции Безумцев","Tempo Máximo de Loucos nos Dutos","" "LighterMaxVision","Max Vision","最大視界","完成任务后的视野","做完任務的視野","Дальность обзора","Aumento de Visão","" "LighterTaskCompletedDisableLightOut","Ignore Fix Lights Effect","タスク完了時に停電を無効にする","完成任务的执灯人不受熄灯影响","完成任務的小燈人視野不受關燈影響","Имеет дальность Обзора Предателя","Ignorar Efeitos do Apagão","" -"LighterTriggerType","Ability Activation Condition","能力発動条件","","","Условие активации способности","Condição de Ativação da Habilidade","" -"LighterTaskTrigger","Tasks Until Boost Activated","効果を発動するタスク数","","","Количество задач повышающие скорость","Tarefas Para Ativar Impulso","" +"LighterTriggerType","Ability Activation Condition","能力発動条件","技能发动条件","","Условие активации способности","Condição de Ativação da Habilidade","" +"LighterTaskTrigger","","効果を発動するタスク数","加速所需任务数","","Задачи повышающие скорость","Tarefas Para Ativar Impulso","" "SabotageMasterFixesDoors","Can Open Multiple Doors","1度に複数のドアを開けられる","修理大师打开多扇关闭的门","修理工可以一次性修理多扇門","Может открыть все двери","Pode Abrir Múltiplas Portas","" "SabotageMasterFixesReactors","Can Fix Both Reactors","リアクターに対して能力を使える","修理大师可以一人修理核反应堆","修理工可以獨自修理兩邊的反應堆","Может починить саботаж Реактора","Pode Consertar Reatores","" "SabotageMasterFixesOxygens","Can Fix Both O2","酸素妨害に対して能力を使える","修理大师修理氧气破坏时另一边的氧气设备将会被同时修理","修理工可以獨自修理兩邊的氧氣","Может починить саботаж O2","Pode Consertar Ambos O2","" @@ -418,7 +418,7 @@ "SnitchCanFindNeutralKiller","Can Find Neutral Killers","ニュートラルのキル可能役職を見つけることが出来る","告密者也可以和拥有击杀能力的独立阵营玩家互相发现","告密者也可以和中立陣營帶刀職業互認","Может видеть Нейтральных Убийц","Pode Achar Assassinos Neutros","" "SnitchRemainingTaskFound","Remaining tasks to be found","敵陣営に見つかるタスク残量","剩余任务数对敌对阵营可见","帶刀職業可見告密者剩餘任務數","Оставшиеся задания при которых он будет виден","Tarefas restantes para encontrar","" "SpeedBoosterUpSpeed","Random Player's Speed Boost","加速値","增速者加速时的移动速度","被加速器加速的玩家的移動速度","Повысить скорость игрока на","Impulso de Velocidade","" -"SpeedBoosterTaskTrigger","Tasks Until Boost Activated","効果を発動するタスク数","效果发动所需任务数","效果發動所需任務數","Задачи повышающие скорость","Tarefas Para Ativar Impulso","" +"SpeedBoosterTaskTrigger","","効果を発動するタスク数","发动技能所需完成任务数量","效果發動所需任務數","Задачи повышающие скорость","Tarefas Para Ativar Impulso","" "MayorAdditionalVote","Additional Votes Count","追加投票の個数","附加票数","附加票數","Дополнительные голоса","Votos Adicionais","" "MayorHasPortableButton","Mayor Has Mobile Emergency Button","ポータブルボタンを持っている","市长跳通风管触发紧急会议","可以隨時拍桌","У Мэра есть портативная Кнопка","Botão Móvel de Emergência","" "MayorNumOfUseButton","Number Of Mobile Emergency Button","ポータブルボタンの使用可能回数","市长紧急会议最大次数","隨時拍桌最大次數","Количество портативных Кнопок","Número de Botões de Emergência","" @@ -444,14 +444,14 @@ "TimeThiefReturnStolenTimeUponDeath","Return Stolen Time After Death","死亡後に盗んだ時間を返す","蚀时者死亡后会议时间重置","時間小偷死亡後將會議時間重設","Вернуть украденное время после его смерти","Devolver Tempo Roubado ao Morrer","" "EvilTrackerCanSeeKillFlash","Can See ''Kill Flash''","インポスターキル時にフラッシュが見える","内鬼进行击杀时邪恶的追踪者可见击杀闪光","當狼人隊友殺人時邪惡的追蹤者可以看到閃光","Может видеть ''Вспышку Убийства''","Pode Ver ""Clarão"" Quando Impostor Matar","" "EvilTrackerTargetMode","Can Set Target","ターゲットの設定タイミング","目标更换时点","可以更換目標","Может установить цель","Pode Definir Alvos","" -"EvilTrackerTargetMode.Never","Never","なし","不更换","關閉","Никогда","Nunca","" +"EvilTrackerTargetMode.Never","","なし","无","關閉","Никто","Nunca","" "EvilTrackerTargetMode.OnceInGame","Once In Game","試合毎","每局游戏一次","每局遊戲一次","В каждой игре","Uma Vez no Jogo","" "EvilTrackerTargetMode.EveryMeeting","Every Meeting","ターン毎","每次会议","每回合","На каждой встрече","Toda Reunião","" "EvilTrackerTargetMode.Always","Always","常時","一直","隨時","Всегда","Sempre","" "EvilTrackerCanSeeLastRoomInMeeting","Can See Target's Last Room In Meeting","会議中、追跡対象の最終位置を表示する","可以在会议时知晓追踪目标的最后停留房间","可以在會議中看到目標最後位置","Может видеть местоположение Целей во время Собрания","Pode Ver a Última Posição do Alvo na Reunião","" "KillFlashDuration","""Kill Flash"" Duration","キルフラッシュの長さ","击杀闪烁持续时间","殺人閃光持續時間","Длительность ""Вспышки Убийства""","Duração do ""Clarão de Abate""","" "WitchModeSwitchAction","Mode Switch Action","モード変更アクション","切换击杀模式","切換模式操作","Действие для Смены Режима","Trocar de Modo","" -"TriggerKill","Kill","キル","击杀","殺人鍵","Убийство","Matar","" +"TriggerKill","Kill","キル","被杀","殺死","Убить","Abatido","" "TriggerVent","Vent","ベント","通风管","通風口","Вентиляция","Duto","" "TimeManagerIncreaseMeetingTime","Increase voting time","伸びる会議時間","延长投票的时间","延長時間","Увеличить время встреч на","Aumentar Tempo de Votação","" "TimeManagerLimitMeetingTime","Increase limit","会議時間の伸びる限界","增加限制","會議時間延長上限","Лимит увеличения времени встреч","Aumentar Limite","" @@ -459,44 +459,44 @@ "AssignOnlyTo%role%","Assign Only To %role%","%role%のみに割り当てる","只赋予%role%","","Назначить только для %role%","Atribuir Apenas a %role%","" "WorkhorseNumLongTasks","Additional Long Tasks","追加ロングタスクの個数","额外长任务数","增加的長任務數量","Дополнительные долгие задания","Adicionar Tarefas Longas","" "WorkhorseNumShortTasks","Additional Short Tasks","追加ショートタスクの個数","额外短任务数","增加的短任務數量","Дополнительные короткие задания","Adicionar Tarefas Curtas","" -"StealthExcludeImpostors","Exclude Impostors From Blindness","暗転効果の対象からインポスターを除外する","","","Исключить Предателей из слепоты","Excluir Impostores da Cegueira","" -"StealthDarkenDuration","Blindness Duration","暗転の持続時間","","","Длительность слепоты","Duração da Cegueira","" -"NekoKabochaImpostorsGetRevenged","Impostors Get Revenged","インポスターを道連れにする","","","Предатели могут мстить","Impostores São Vingados","" -"NekoKabochaMadmatesGetRevenged","Madmates Get Revenged","マッドメイトを道連れにする","","","Безумцы могут мстить","Tripulantes Loucos São Vingados","" -"NekoKabochaRevengeOnExile","Revenge When Exiled","追放された時に誰かを道連れにする","","","Месть во время изгнания","Vinagança Quando Exilado","" -"EvilHackerCanSeeDeadMark","Can See The Location of Dead-bodies","死体位置がわかる","","","Может видеть местоположение трупов","Pode Ver Local dos Corpos","" -"EvilHackerCanSeeImpostorMark","Can See The Location of Other Impostors","他のインポスターの位置がわかる","","","Может видеть местоположение других Предателей","Pode Ver o Local de Outros Impostores","" -"EvilHackerCanSeeKillFlash","Can See ''Kill Flash''","インポスターキル時にフラッシュが見える","","","Может видеть ''Вспышку Убийства''","Pode Ver ""Clarão"" Quando Impostor Matar","" -"EvilHackerCanSeeMurderRoom","Can See The Murder Location","キルの発生場所がわかる","","","Может увидеть место убийства","Pode Ver Localidade do Assassinato","" -"PenguinAbductTimerLimit","Dragging Time","引き摺れる時間","","","Время перетаскивания","Tempo Para Arrastar","" -"PenguinMeetingKill","Kill If Meeting Starts During Dragging","会議開始時に引き摺り中ならキルする","","","Убить если встреча начнется во время перетаскивания","Matar Se Reunião Começar Enquanto Arrasta","" -"InsiderCanSeeImpostorAbilities","Can See Impostor Abilities","味方インポスターの能力が分かる","","","Может видеть роли других Предателей","Pode Ver Habilidades de Impostor","" -"InsiderCanSeeAllGhostsRoles","Can See All Ghost's Roles","幽霊全員の役職が分かる","","","Может видеть все роли Призраков","Pode Ver Todas As Classes dos Fantasmas","" -"InsiderCanSeeMadmates","Can See Madmates","マッドメイトが分かる","","","Может видеть Безумцев","Pode Ver Tripulantes Loucos","" -"InsiderKillCountToSeeMadmates","Kill Count To See Madmates","必要なキル数","","","Количество убийств при котором будет виден Безумец","Quantas Kills Para Ver Tripulante Louco","" -"PlagueDoctorInfectLimit","Infect Count","感染回数","","","Количество заражений","Limite de Infectados","" -"PlagueDoctorInfectWhenKilled","Infect When Killed","キルされた時に感染させる","","","Заразить убийцу при смерти заражённого","Infectar Ao Ser Morto","" -"PlagueDoctorInfectTime","Infect Time","感染に必要な時間","","","Время заражения","Tempo de Infecção","" -"PlagueDoctorInfectDistance","Infect Distance","感染する距離","","","Радиус заражения","Distância de Infecção","" -"PlagueDoctorInfectInactiveTime","Infect Invalid Time","行動開始から感染しない時間","","","Недействительное время заражения","Tempo Inativo da Infecção","" -"PlagueDoctorCanInfectSelf","Can Infect Self","自身も感染する","","","Может заразить себя","Pode Infectar A Si Mesmo","" -"PlagueDoctorCanInfectVent","Can Infect in Vent","ベント内外でも感染する","","","Может заразить в вентиляции","Pode Infectar no Duto","" +"StealthExcludeImpostors","Exclude Impostors From Blindness","暗転効果の対象からインポスターを除外する","内鬼不会失明","","Исключить Предателей из слепоты","Excluir Impostores da Cegueira","" +"StealthDarkenDuration","Blindness Duration","暗転の持続時間","失明持续时间","","Длительность слепоты","Duração da Cegueira","" +"NekoKabochaImpostorsGetRevenged","Impostors Get Revenged","インポスターを道連れにする","内鬼可以被反杀","","Предатели могут мстить","Impostores São Vingados","" +"NekoKabochaMadmatesGetRevenged","Madmates Get Revenged","マッドメイトを道連れにする","叛徒可以被反杀","","Безумцы могут мстить","Tripulantes Loucos São Vingados","" +"NekoKabochaRevengeOnExile","Revenge When Exiled","追放された時に誰かを道連れにする","被驱逐时复仇","","Месть во время изгнания","Vinagança Quando Exilado","" +"EvilHackerCanSeeDeadMark","Can See The Location of Dead-bodies","死体位置がわかる","可以知道尸体的位置","","Может видеть местоположение трупов","Pode Ver Local dos Corpos","" +"EvilHackerCanSeeImpostorMark","Can See The Location of Other Impostors","他のインポスターの位置がわかる","可以知道内鬼的位置","","Может видеть местоположение других Предателей","Pode Ver o Local de Outros Impostores","" +"EvilHackerCanSeeKillFlash","","インポスターキル時にフラッシュが見える","当内鬼击杀时你可以看到杀戮闪烁","","Может видеть ''Вспышку Убийства''","","" +"EvilHackerCanSeeMurderRoom","Can See The Murder Location","キルの発生場所がわかる","可以知道某个房间发生了击杀","","Может увидеть место убийства","Pode Ver Localidade do Assassinato","" +"PenguinAbductTimerLimit","Dragging Time","引き摺れる時間","最长拖拽时间","","Время перетаскивания","Tempo Para Arrastar","" +"PenguinMeetingKill","Kill If Meeting Starts During Dragging","会議開始時に引き摺り中ならキルする","拖拽时开会将立刻击杀目标","","Убить если встреча начнется во время перетаскивания","Matar Se Reunião Começar Enquanto Arrasta","" +"InsiderCanSeeImpostorAbilities","Can See Impostor Abilities","味方インポスターの能力が分かる","可以看到内鬼技能状态","","Может видеть роли других Предателей","Pode Ver Habilidades de Impostor","" +"InsiderCanSeeAllGhostsRoles","Can See All Ghost's Roles","幽霊全員の役職が分かる","可以看到所有幽灵的职业","","Может видеть все роли Призраков","Pode Ver Todas As Classes dos Fantasmas","" +"InsiderCanSeeMadmates","Can See Madmates","マッドメイトが分かる","可以看到叛徒","","Может видеть Безумцев","Pode Ver Tripulantes Loucos","" +"InsiderKillCountToSeeMadmates","Kill Count To See Madmates","必要なキル数","看到叛徒所需击杀数","","Количество убийств при котором будет виден Безумец","Quantas Kills Para Ver Tripulante Louco","" +"PlagueDoctorInfectLimit","Infect Count","感染回数","可主动感染次数","","Количество заражений","Limite de Infectados","" +"PlagueDoctorInfectWhenKilled","Infect When Killed","キルされた時に感染させる","被击杀时感染凶手","","Заразить убийцу при смерти заражённого","Infectar Ao Ser Morto","" +"PlagueDoctorInfectTime","Infect Time","感染に必要な時間","感染所需时间","","Время заражения","Tempo de Infecção","" +"PlagueDoctorInfectDistance","Infect Distance","感染する距離","感染有效传播距离","","Радиус заражения","Distância de Infecção","" +"PlagueDoctorInfectInactiveTime","Infect Invalid Time","行動開始から感染しない時間","主动感染冷却时间","","Недействительное время заражения","Tempo Inativo da Infecção","" +"PlagueDoctorCanInfectSelf","Can Infect Self","自身も感染する","可以感染自己","","Может заразить себя","Pode Infectar A Si Mesmo","" +"PlagueDoctorCanInfectVent","Can Infect in Vent","ベント内外でも感染する","可以感染管道内的玩家","","Может заразить в вентиляции","Pode Infectar no Duto","" "## ランダムスポーンポイント" -"Junction","Junction","三叉路","","","","","" -"OfficeLeft","Office Left","オフィス左","","","","","" -"OfficeRight","Office Right","オフィス右","","","","","" -"Rocket","Rocket","ロケット","","","","","" -"Toilet","Toilet","トイレ","","","","","" -"NapRoom","Nap Room","仮眠室","","","","","" -"Bonfire","Bonfire","焚き火","","","","","" -"JungleTop","Jungle Top","ジャングル上","","","","","" -"JungleBottom","Jungle Bottom","ジャングル下","","","","","" -"Precipice","Precipice","崖","","","","","" +"Junction","Junction","三叉路","三岔路","","Перекресток","","" +"OfficeLeft","Office Left","オフィス左","办公室(左)","","Левый Офис","","" +"OfficeRight","Office Right","オフィス右","办公室(右)","","Правый Офис","","" +"Rocket","Rocket","ロケット","火箭","","Ракета","","" +"Toilet","Toilet","トイレ","厕所","","Туалет","","" +"NapRoom","Nap Room","仮眠室","休息室","","Комната для сна","","" +"Bonfire","Bonfire","焚き火","篝火","","Костер","","" +"JungleTop","Jungle Top","ジャングル上","丛林上","","Вершина Джунглей","","" +"JungleBottom","Jungle Bottom","ジャングル下","丛林下","","Дно Джунглей","","" +"Precipice","Precipice","崖","悬崖","","Скала","","" "## 能力発動条件" -"TaskProgressRate","Task Progress","タスク進捗率","","","Прогресс заданий","Progresso das Tarefas","" -"TaskCount","Task Count","タスク数","","","Количество заданий","Número de Tarefas","" +"TaskProgressRate","Task Progress","タスク進捗率","任务进度","","Прогресс заданий","Progresso das Tarefas","" +"TaskCount","Task Count","タスク数","任务数量","","Количество заданий","Número de Tarefas","" "## かくれんぼ設定" "HideAndSeekOptions","Hide and Seek Settings","かくれんぼの設定","躲猫猫设置","躲貓貓設定","Настройки Пряток","Configurações do Esconde-Esconde","" @@ -507,21 +507,21 @@ "HideAndSeekRoles","Hide and Seek Roles","かくれんぼの役職","躲猫猫职业","躲貓貓職業","Роли в Прятках","Classes do Esconde-Esconde","" "## 死因" -"DeathReason.Kill","Kill","キル","被杀","被殺","Убит","Abatido","" +"DeathReason.Kill","","キル","击杀","被殺","Убит","Abatido","" "DeathReason.Vote","Ejected","追放","放逐","被丟","Изгнан","Exilado","" -"DeathReason.Suicide","Suicide","自殺","自杀","自殺","Суицид","Suicídio","" +"DeathReason.Suicide","","自殺","自杀","自殺","Суицид","Suicídio","" "DeathReason.Spell","Spell","呪殺","咒杀","咒殺","Заколдован","Feitiço","" "DeathReason.Bite","Bitten","噛殺","吸血","咬死","Укушен","Mordido","" "DeathReason.FollowingSuicide","Lover's Suicide","後追い","为爱而死","戀人共死","♡Суицид♡","Suicídio por Amor","" "DeathReason.Bombed","Explosion","爆死","炸死","炸死","Взорван","Explosão","" "DeathReason.Misfire","Misfire","誤爆","走火","走火","Убился","Alvo Incorreto","" "DeathReason.Torched","Torched","焼殺","烧死","燒死","Сожжён","Queimado","" -"DeathReason.Sniped","Sniped","狙撃","狙杀","被狙","Застрелен","Baleado","" +"DeathReason.Sniped","Snipe","狙撃","狙击","狙擊","Застрелить","Atirar","" "DeathReason.Execution","Execution","処刑","处决","處刑","Казнен","Executado","" "DeathReason.Disconnected","Disconnected","回線切断","断连","斷線","Вышел","Desconectado","" "DeathReason.Fall","Fall","転落","摔死","摔死","Упал","Queda","" "DeathReason.Revenge","Revenge","道連れ","复仇","復仇","Месть","Vingança","" -"DeathReason.Infected","Infected","感染","","","Заражён","Infectado","" +"DeathReason.Infected","Infected","感染","感染","","Заражён","Infectado","" "DeathReason.etc","Other","その他","其他","其他","Другое","Outros","" "Alive","Alive","生存","存活","存活","Выжил","Vivo","" "Win"," Wins","勝利","胜利","勝利"," Победили","Vitória","" @@ -531,10 +531,12 @@ "SabotageTimeControl","Sabotage Duration Control","サボタージュの時間制御","更改修理时限","重新設定緊急任務時間","Изменить время саботажа","Controle da Duração de Sabotagem","" "PolusReactorTimeLimit","Polus Reactor Duration","ポーラスのリアクター制限時間","波鲁斯抗震稳定器修理时限","Polus地震抑制器破壞最大時間","Polus время саботажа Реактора","Duração do Reator em Polus","" "AirshipReactorTimeLimit","Airship Reactor Duration","エアシップのリアクター制限時間","飞艇坠毁路线修理时限","Airship間隙室破壞最大時間","Airship время саботажа Реактора","Duração do Reator em Airship","" +"FungleReactorTimeLimit","Fungle Reactor Duration","ファングルのリアクター制限時間","反应堆时间限制(蘑菇岛地图)","","Время саботажа Реактора на The Fungle","","" +"FungleMushroomMixupDuration","Fungle Mushroom Mixup Duration","ファングルのキノコカオス効果時間","蘑菇混合持续时间(蘑菇岛地图)","","Длительность грибного переполоха на The Fungle","","" "## サボタージュのクールダウン変更" -"ModifySabotageCooldown","Sabotage Cooldown Control","サボタージュのクールダウン制御","","","Контролировать откат саботажа","Controle do Tepo de Recarga da Sabotagem","" -"SabotageCooldown","Sabotage Cooldown","サボタージュのクールダウン","","","Откат саботажа","Tempo de Recarga da Sabotagem","" +"ModifySabotageCooldown","Sabotage Cooldown Control","サボタージュのクールダウン制御","修改破坏冷却时间","","Контролировать откат саботажа","Controle do Tepo de Recarga da Sabotagem","" +"SabotageCooldown","Sabotage Cooldown","サボタージュのクールダウン","破坏冷却时间","","Откат саботажа","Tempo de Recarga da Sabotagem","" "## クライアント設定" "Close","Close","閉じる","关闭","","Закрыть","Fechar","" @@ -577,15 +579,15 @@ "Message.BanedByBanList","{0} has been banned because it has been banned in the past.","{0}は過去にBAN済みのためBANされました。","{0} 已被封禁,因其之前就被封禁过","因為{0}在被記錄在黑名單中,所以禁止了{0}再次進入此房間。","{0} был заблокирован, потому что он был заблокирован в прошлый раз","{0} foi banido por já ter sido banido antes.","" "Message.KickedByNoFriendCode","{0} was kicked because the friend code does not exist.","{0}はフレンドコードが存在しないためキックされました。","{0}被踢出,因其好友编号无效。","{0}因為沒有好友代碼,所以踢出了他。","{0} был кикнут, так как у него нет кода друга","{0} foi expulso, pois o código de amigo não existe.","" "Message.AddedPlayerToBanList","Added {0} to the ban list.","{0}をBANリストに追記しました。","{0}已被添加到封禁名单","已將 {0} 加入到黑名單中,此玩家將無法再進入你的房間。(需安裝TOH模組)","{0} был добавлен в список забаненых игроков","{0} foi adicionado a lista de banidos.","" -"Message.FailedToLoadOptions","Failed to load options","オプションの読み込みに失敗しました","","","Не удалось загрузить настройки","Erro ao carregar as opções","" -"Message.CopiedOptions","Copied options","オプションデータをコピーしました","","","Скопированные настройки","Opções copiadas","" -"Message.ExportedOptions","Exported options","オプションデータを出力しました","","","Экспортированные настройки","Opções exportadas","" -"Message.LoadedOptions","Loaded options","オプションデータを読み込みました","","","Загруженные настройки","Opções carregadas","" -"Message.OnlyHostCanLoadOptions","Only the host can load options","ホストのみがオプションを読み込めます","","","Только хост может загружать настройки","Apenas o anfitrião pode carregar opções","" +"Message.FailedToLoadOptions","Failed to load options","オプションの読み込みに失敗しました","加载选项数据失败","","Не удалось загрузить настройки","Erro ao carregar as opções","" +"Message.CopiedOptions","Copied options","オプションデータをコピーしました","已将选项数据复制到剪辑版","","Скопированные настройки","Opções copiadas","" +"Message.ExportedOptions","Exported options","オプションデータを出力しました","输出选项数据到文件","","Экспортированные настройки","Opções exportadas","" +"Message.LoadedOptions","Loaded options","オプションデータを読み込みました","数据选项已加载","","Загруженные настройки","Opções carregadas","" +"Message.OnlyHostCanLoadOptions","Only the host can load options","ホストのみがオプションを読み込めます","只有房主可以加载数据选项","","Только хост может загружать настройки","Apenas o anfitrião pode carregar opções","" "## 警告" "Warning.EgoistCannotWin","Egoist cannot win","エゴイストが勝利できません","野心家无法获胜","利己主義者無法獲勝","Эгоист не может победить!","Egoísta não pode vencer","" -"Warning.OverrideExiledPlayer","All ejects will be displayed as a tie since the jackals are in effect.","ジャッカルがいるため、追放はすべて同数投票として表示されます。","","","Из-за того что в игре есть Шакал(ы) все изгнания будут видны как ничья (но только визуально, на результат голосования это не влияет)","Todas as ejeções serão exibidas como empate, já que os chacais estão em vigor.","" +"Warning.OverrideExiledPlayer","All ejects will be displayed as a tie since the jackals are in effect.","ジャッカルがいるため、追放はすべて同数投票として表示されます。","由于开启了豺狼,所有驱逐动画将显示为平票(只影响视觉,不影响结果)","","Из-за того что в игре есть Шакал(ы) все изгнания будут видны как ничья (но только визуально, на результат голосования это не влияет)","Todas as ejeções serão exibidas como empate, já que os chacais estão em vigor.","" "Warning.InvalidRpc","Kicked {0} because an invalid RPC was received.\nPlease check that no mods other than TOH installed.","不正なRPCを受信したため{0}をキックしました。\nTOH以外のMODが入っていないか確認してください。","{0} 被踢出,因其 RPC 无效。 \n请确保没有 TOH 以外的模组。","{0}因為收到無效的RPC,所以踢出了他,\n請確保遊戲除了TOH之外沒有其他模組系統被載入","{0} Был кикнут так как получен недопустимый RPC. \nУбедитесь что в системе нет других модов кроме TOH.","{0} Foi expulso, porque um RPC inválido foi recebido. \nPor favor verifique se nenhum outro mod além de TOH está instalado.","" "Warning.NoModHost","No mod installed on the host","ホストにMODが導入されていません","该房主并未安装mod","該房房主沒有安裝Town Of Host模組","У Хоста Лобби не установлен Town of Host","O anfitrião não tem o mod instalado","" "Warning.MismatchedVersion","{0}\nhave a different version of {1}","{0} の\n{1} のバージョンがホストと合致しません。","{0} \n的游戏版本为{1},与主机版本不符。","","{0} Версия \nне соответствует версии Хоста лобби {1}","{0}\ntem uma versão diferente de {1}","" @@ -613,8 +615,9 @@ "ERR-000-804-1","TownOfHost does not support the Vanilla HnS, so unloaded.","現在バニラのHide And Seekはサポートされていません。modを無効化しました。","TOH不支持原版躲猫猫, mod因此失效","Town Of Host模組尚未支援原版的Hide And Seek模式,所以模組將暫時卸載。","Мод не поддерживает обычные Прятки. Мод был отключён","TownOfHost não suporta o Esconde-Esconde padrão, então foi descarregado.","" "#### 001 Main" "ERR-001-000-3","Main dictionary has duplicated keys.","MainのDictonaryでKeyの重複が発生しています。","在主目录出现重复密钥","在主目錄出現重複密鑰","Дублирование ключей происходит в основном словаре.","Dicionário principal tem chaves duplicadas.","" +"ERR-001-010-3","Duplicate Options ID","オプションIDが重複しています","选项ID重复","","Повторяющийся идентификатор настроек","","" "#### 002 Support" -"ERR-002-000-1","Unsupported AmongUs version. Please update.","サポートされていないAmongUsバージョンです。ゲームをアップデートしてください。","","","Неподдерживаемая версия AmongUs. Пожалуйста, обновите игру","Versão não suportada do Among Us. Por favor, atualize.","" +"ERR-002-000-1","Unsupported AmongUs version. Please update.","サポートされていないAmongUsバージョンです。ゲームをアップデートしてください。","不支持的 AmongUs 版本,请更新","","Неподдерживаемая версия AmongUs. Пожалуйста, обновите игру","Versão não suportada do Among Us. Por favor, atualize.","" "## その他" "DefaultSystemMessageTitle","【===== System Message =====】","【===== システムメッセージ ======】","【===== 系统信息 ======】","【===== 系統訊息 ======】","【=== Системное сообщение ===】","【===== Mensagem do Sistema ======】","" @@ -623,14 +626,14 @@ "TabGroup.CrewmateRoles","Crewmate Roles","クルー役職","船员阵营职业","船員職業","Роли Членов Экипажа","Classes de Tripulante","" "TabGroup.NeutralRoles","Neutral Roles","ニュートラル役職","独立阵营职业","中立職業設定","Нейтральные Роли","Classes Neutras","" "TabGroup.ImpostorRoles","Impostor Roles","インポスター役職","内鬼阵营职业","偽裝者職業設定","Роли Предателей","Classes de Impostor","" -"TabGroup.Addons","Add-Ons","属性","附加效果","副職業設定","Атрибуты","Atributos","" +"TabGroup.Addons","Add-Ons","属性","附加效果","屬性","Атрибут","Atributos","" "ActiveRolesList","Active Roles List","有効な役職一覧","有效职业一览","已開啟職業列表","Список Активных Ролей","Lista de Classes Ativas","" "ForExample","Example Use","使用例","使用例子","使用例子","Например","Exemplo de Uso","" "ForceEnd","Aborted","廃村","强制结束游戏","遊戲已被強制結束","Игра Окончена","Abortado","" "EveryoneDied","No One Left","誰もいなくなった","没有人存活","沒有人存活","Все Мертвы","Não Sobrou Ninguém","" "ForceEndText","Host has aborted the game","ホストから強制終了コマンドが入力されました","房主强制结束了游戏","房主已強制結束遊戲","Хост завершил игру","Anfitrião abortou o jogo","" -"ShowResults","Show Results","結果を表示","","","Показать результаты","Mostrar Resultados","" -"HideResults","Hide Results","結果を隠す","","","Скрыть результаты","Esconder Resultados","" +"ShowResults","Show Results","結果を表示","显示复盘信息","","Показать результаты","Mostrar Resultados","" +"HideResults","Hide Results","結果を隠す","隐藏复盘信息","","Скрыть результаты","Esconder Resultados","" "HideGameCodes","Hide Game Code","ゲームコードを隠す","直播模式","隱藏遊戲代碼","Скрыть Игровой Код","Esconder Código do Jogo","" "updateButton","Update","アップデート","更新","更新","Обновление","Atualizar","" "updatePleaseWait","Please Wait...","しばらくお待ちください...","请稍候……","請稍後...","Пожалуйста, подождите...","Por favor aguarde...","" @@ -643,9 +646,9 @@ "onSetPublicNoLatest","Public rooms are only available in the latest version.\nPlease update.","最新版以外で公開ルームにはできません。\nアップデートをしてください。","不可以在未安装最新模组的前提下创建公开房间。\n请更新本模组。","無法建立一個公共房間,因為使用的不是最新版本的模組\n請更新本模組。","Публичные лобби запрещены за исключением последней версии.\nПожалуйста обновите.","Salas públicas estão disponíveis apenas na última versão.\nPor favor atualize.","" "CanNotJoinPublicRoomNoLatest","You can't join public rooms without the latest version.\nPlease update.","最新版以外で公開ルームには参加できません。\nアップデートをしてください。","不可以在未安装最新模组的前提下进入公开房间。\n请更新本模组。","無法在未安裝最新版本的前提下進入公開房間\n請更新本模組","Вы не можете присоединяться к публичным лобби за исключением последней версии.\nПожалуйста обновите.","Você não pode entrar em salas públicas sem a última versão.\nPor favor atualize.","" "ModBrokenMessage","The MOD file is damaged.\nPlease reinstall.","MODを構成するファイルが破損しています。\nもう一度導入しなおしてください。","模组文件损坏。\n请重新安装本模组。","模組檔案損壞\n請重新安裝模組","Мод был поврежден.\nПожалуйста переустановите его снова.","Os arquivos do MOD estão danificados.\nPor favor reinstale.","" -"UnsupportedVersion","Unsupported AmongUs version.\nPlease update.","サポートされていないAmongUsバージョンです。\nゲームをアップデートしてください。","","","Неподдерживаемая версия AmongUs.\nПожалуйста, обновите игру","Versão não suportada do Among Us. \nPor favor, atualize.","" +"UnsupportedVersion","Unsupported AmongUs version.\nPlease update.","サポートされていないAmongUsバージョンです。\nゲームをアップデートしてください。","不支持的 AmongUs 版本。\n请更新","","Неподдерживаемая версия AmongUs.\nПожалуйста, обновите игру","Versão não suportada do Among Us. \nPor favor, atualize.","" "DisabledByProgram","Public rooms have been disabled by the program","公開ルームはプログラムによって無効化されています","公开房间的操作已被程序禁用","公開房間的操作已經被程式禁用","Создание публичного лобби отключена программой","Salas públicas foram desativadas pelo programa","" -"PublicNotAvailableOnThisVersion","Public lobbies are not available on this version.\nPlease visit our Discord 'modアナウンス' channel for details.","このバージョンでは公開ルームは使用できません。\n詳しくはDiscordの「modアナウンス」チャンネルを参照してください。","","","","","" +"PublicNotAvailableOnThisVersion","Public lobbies are not available on this version.\nPlease visit our Discord 'modアナウンス' channel for details.","このバージョンでは公開ルームは使用できません。\n詳しくはDiscordの「modアナウンス」チャンネルを参照してください。","此版本不支持公开。\n请访问TownOfHost的Discord的「modアナウンス」频道获取更多信息","","Публичные лобби недоступны в этой версии.\nПожалуйста, обратитесь к каналу Discord «「modアナウンス」» для получения дополнительной информации","","" "EnterVentToWin","Enter Vent to Win!!","ベントに入って勝利しろ!!","跳管道来获得胜利!","跳管道來獲得勝利!!","Запрыгните в вентиляцию чтобы победить!!","Entre no Duto Para Ganhar!!!","" "FireworksPutPhase","{0} Fireworks Left","あと{0}個置け","还要安放{0}枚烟花","還需要安裝{0}枚煙火","Осталось {0} Фейерверков","Restam {0} Fogos de Artifício","" "FireworksWaitPhase","Wait for it...","時を待て...","耐心等待....","等待時機...","Подожди время...","Espere o momento certo...","" @@ -659,14 +662,14 @@ "ColoredOff","OFF","オフ","关闭","關閉","ВЫКЛ","Desativado","" "CurrentActiveSettingsHelp","Current Active Settings Help","現在有効な設定の説明","当前启用设置及帮助","現在設定的模式和職業說明","Справка по текущим активным настройкам","Ajuda com Configurações Ativas","" "WitchCurrentMode","Current Mode:","現在のモード:","当前模式:","現在模式:","Текущий Режим: ","Modo Atual:","" -"WitchModeKill","Kill","キル","击杀","殺人","Убить","Matar","" -"WitchModeSpell","Spell","スペル","诅咒","下咒","Заклясть","Feitiço","" +"WitchModeKill","","キル","击杀","殺人","Убит","Matar","" +"WitchModeSpell","Spell","スペル","诅咒","下咒","Заклинать","Feitiço","" "WitchModeDouble","Double Enable","ダブル有効","双重有效","兩個模式同時啟用","Двойной","Duplo Ativado","" "BountyCurrentTarget","Current Target","現在のターゲット","当前目标","目標","Текущая цель","Alvo Atual","" -"StealthDarkened","Darkened: {0}","暗転中: {0}","","","Затемнено: {0}","Escurecidos: {0}","" -"Roles","Roles","役職","职业","職業","Роли","Classes","" +"StealthDarkened","Darkened: {0}","暗転中: {0}","失明:{0}","","Затемнено: {0}","Escurecidos: {0}","" +"Roles","Roles","役職","职业","職業","Роль","Classes","" "Settings","Settings","設定","设定","設定","Настройки","Configurações","" -"Addons","Add-Ons","属性","附加效果","屬性","Атрибут","Atributos","" +"Addons","Add-Ons","属性","附加职业","屬性","Атрибут","","" "LastResult","Match Results","試合結果","游戏结果","上一局的遊戲結果","Результат матча","Resultados da Partida","" "KillLog","Kill Log","キル履歴","击杀日志","擊殺紀錄","История убийств","Log de Mortes","" "Maximum","Max","最大数","最多人数","最大數量","Максимум","Máximo","" @@ -709,7 +712,7 @@ "FireWorksInstallAtionButtonText","Set","設置","设置","安裝","Установить","Colocar","" "SerialKillerSuicideButtonText","Suicide Timer","自殺まで","自杀倒计时","自殺倒數","До Суицида","Suicídio Em","" "WarlockCurseButtonText","Curse","呪う","下咒","詛咒","Проклинать","Amaldiçoar","" -"WitchSpellButtonText","Spell","スペル","诅咒","下咒","Заклинать","Feitiço","" +"WitchSpellButtonText","Spell","スペル","下咒","下咒","Заклясть","Feitiço","" "VampireBiteButtonText","Bite","噛む","吸血","吸血","Укусить","Morder","" "ArsonistDouseButtonText","Douse","塗る","涂油","澆油","Облить","Encharcar","" "PuppeteerOperateButtonText","Manipulate","操る","操控","操控","Управлять","Manipular","" @@ -719,9 +722,9 @@ "DisabledBySettings","Disabled by Settings","設定で無効化されています","已在设置被中禁用","在設定中被禁用","Отключено настройкой","Desativado Pelas Configurações","" "Disabled","Disabled","無効","禁用","已被禁用","Отключено","Desativado","" "FailToTrack","Failed To Track","追跡失敗","追踪失败","無法追蹤","Не удалось отследить","Falha ao Rastrear","" -"LastAdminInfo","Last-minute admin information","直前のアドミン情報","","","Актуальная информация администратора","Informações administrativas recentes","" -"MurderNotify","Murder","キル発生","","","Убийство","Assassinato","" -"Deadbody","DEAD","死体","","","Труп","MORTO","" -"PenguinKillButtonText","Drag","拉致","","","ПЕРЕТАСКИВАТЬ","Arrastar","" -"PenguinTimerText","Drag Timer","残り時間","","","Время перетаскивания","Tempo para Arrastar","" -"Infected","Infected","感染","","","Заражён","Infectado","" \ No newline at end of file +"LastAdminInfo","Last-minute admin information","直前のアドミン情報","一分钟内的管理信息","","Актуальная информация администратора","Informações administrativas recentes","" +"MurderNotify","Murder","キル発生","击杀发生","","Убийство","Assassinato","" +"Deadbody","DEAD","死体","尸体","","Труп","MORTO","" +"PenguinKillButtonText","Drag","拉致","拖拽","","ПЕРЕТАСКИВАТЬ","Arrastar","" +"PenguinTimerText","Drag Timer","残り時間","剩余时间","","Время перетаскивания","Tempo para Arrastar","" +"Infected","","感染","感染","","Заражён","Infectado","" \ No newline at end of file diff --git a/Roles/Crewmate/SabotageMaster.cs b/Roles/Crewmate/SabotageMaster.cs index 4be66e125..ecbd65344 100644 --- a/Roles/Crewmate/SabotageMaster.cs +++ b/Roles/Crewmate/SabotageMaster.cs @@ -61,7 +61,7 @@ enum OptionName public int UsedSkillCount; private bool DoorsProgressing = false; - private bool fixedComms = false; + private bool fixedSabotage; public static void SetupOptionItem() { @@ -90,12 +90,19 @@ bool ISystemTypeUpdateHook.UpdateHeliSabotageSystem(HeliSabotageSystem heliSabot if (!IsSkillAvailable()) return true; if (!FixesReactors) return true; var tags = (HeliSabotageSystem.Tags)(amount & HeliSabotageSystem.TagMask); - if (tags == HeliSabotageSystem.Tags.FixBit) + if (tags == HeliSabotageSystem.Tags.ActiveBit) + { + //パネル開いたタイミング + fixedSabotage = false; + } + if (!fixedSabotage && tags == HeliSabotageSystem.Tags.FixBit) { //片方の入力が正解したタイミング + fixedSabotage = true; + //ヘリサボは16,17がそろったとき完了。 var consoleId = amount & HeliSabotageSystem.IdMask; var otherConsoleId = (consoleId + 1) % 2; - ShipStatus.Instance.UpdateSystem(SystemTypes.HeliSabotage, Player, (byte)(consoleId | (int)HeliSabotageSystem.Tags.FixBit)); + //もう一方のパネルの完了報告 ShipStatus.Instance.UpdateSystem(SystemTypes.HeliSabotage, Player, (byte)(otherConsoleId | (int)HeliSabotageSystem.Tags.FixBit)); UsedSkillCount++; } @@ -121,12 +128,12 @@ bool ISystemTypeUpdateHook.UpdateHqHudSystem(HqHudSystemType hqHudSystemType, by if (tags == HqHudSystemType.Tags.ActiveBit) { //パネル開いたタイミング - fixedComms = false; + fixedSabotage = false; } - if (!fixedComms && tags == HqHudSystemType.Tags.FixBit) + if (!fixedSabotage && tags == HqHudSystemType.Tags.FixBit) { //片方の入力が正解したタイミング - fixedComms = true; + fixedSabotage = true; //MiraHQのコミュは16,17がそろったとき完了。 var consoleId = amount & HqHudSystemType.IdMask; var otherConsoleId = (consoleId + 1) % 2; diff --git a/Roles/Impostor/Penguin.cs b/Roles/Impostor/Penguin.cs index 368d5860f..5980ede79 100644 --- a/Roles/Impostor/Penguin.cs +++ b/Roles/Impostor/Penguin.cs @@ -238,14 +238,14 @@ public override void OnFixedUpdate(PlayerControl player) var position = Player.transform.position; if (Player.PlayerId != 0) { - RandomSpawn.TP(AbductVictim.NetTransform, position); + AbductVictim.RpcSnapTo(position); } else { _ = new LateTask(() => { if (AbductVictim != null) - RandomSpawn.TP(AbductVictim.NetTransform, position); + AbductVictim.RpcSnapTo(position); } , 0.25f, ""); } diff --git a/Roles/Neutral/Egoist.cs b/Roles/Neutral/Egoist.cs index 18bb5d692..f4a4a89f3 100644 --- a/Roles/Neutral/Egoist.cs +++ b/Roles/Neutral/Egoist.cs @@ -23,6 +23,7 @@ public sealed class Egoist : RoleBase, ISidekickable, IKiller, ISchrodingerCatOw countType: CountTypes.Impostor, assignInfo: new RoleAssignInfo(CustomRoles.Egoist, CustomRoleTypes.Neutral) { + AssignRoleType = CustomRoleTypes.Impostor, IsInitiallyAssignableCallBack = () => Main.RealOptionsData.GetInt(Int32OptionNames.NumImpostors) > 1, AssignCountRule = new(1, 1, 1) diff --git a/Roles/RoleAssignManager.cs b/Roles/RoleAssignManager.cs index dd9a870d7..8d26f8c4b 100644 --- a/Roles/RoleAssignManager.cs +++ b/Roles/RoleAssignManager.cs @@ -154,7 +154,7 @@ private static void SetFixedAssignRole() foreach (var roleType in CustomRolesHelper.AllRoleTypes) { - var count = AssignRoleList.Count(role => role.GetCustomRoleTypes() == roleType); + var count = AssignRoleList.Count(role => role.GetAssignRoleType() == roleType); AssignCount.Add(roleType, count); } } @@ -230,13 +230,13 @@ private static void SetRandomAssignRoleList() //アサイン枠が足りてない場合 if (CustomRolesHelper.AllRoleTypes.Any( type => assignCount.TryGetValue(type, out var count) && - targetRoles.Count(role => role.GetCustomRoleTypes() == type) > count + targetRoles.Count(role => role.GetAssignRoleType() == type) > count )) continue; foreach (var targetRole in targetRoles) { AssignRoleList.Add(targetRole); - var targetRoleType = targetRole.GetCustomRoleTypes(); + var targetRoleType = targetRole.GetAssignRoleType(); if (assignCount.ContainsKey(targetRoleType)) assignCount[targetRoleType]--; } @@ -264,12 +264,12 @@ private static void SetRandomAssignRoleList() var selectedTicket = randomRoleTicketPool[rand.Next(randomRoleTicketPool.Count)]; var targetRoles = selectedTicket.Item1.GetAssignUnitRolesArray(); //アサイン枠が足りていれば追加 - if (CustomRolesHelper.AllRoleTypes.All(type => targetRoles.Count(role => role.GetCustomRoleTypes() == type) <= assignCount[type])) + if (CustomRolesHelper.AllRoleTypes.All(type => targetRoles.Count(role => role.GetAssignRoleType() == type) <= assignCount[type])) { foreach (var targetRole in targetRoles) { AssignRoleList.Add(targetRole); - assignCount[targetRole.GetCustomRoleTypes()]--; + assignCount[targetRole.GetAssignRoleType()]--; } } //1-9個ある同じチケットを削除 @@ -309,6 +309,8 @@ private static List GetCandidateRoleList(int availableRate) } private static RoleAssignInfo GetRoleAssignInfo(this CustomRoles role) => CustomRoleManager.GetRoleInfo(role)?.AssignInfo; + private static CustomRoleTypes GetAssignRoleType(this CustomRoles role) => + role.GetRoleAssignInfo()?.AssignRoleType ?? role.GetCustomRoleTypes(); private static bool IsAssignable(this CustomRoles role) => role.GetRoleAssignInfo()?.IsInitiallyAssignable ?? true; /// @@ -343,6 +345,7 @@ public class RoleAssignInfo { public RoleAssignInfo(CustomRoles role, CustomRoleTypes roleType) { + AssignRoleType = roleType; IsInitiallyAssignableCallBack = () => true; AssignCountRule = roleType == CustomRoleTypes.Impostor ? new(1, 3, 1) : new(1, 15, 1); @@ -350,6 +353,10 @@ public RoleAssignInfo(CustomRoles role, CustomRoleTypes roleType) Enumerable.Repeat(role, AssignCountRule.Step).ToArray(); } /// + /// どのアサイン枠を消費するか + /// + public CustomRoleTypes AssignRoleType { get; init; } + /// /// 試合開始時にアサインされるかどうかのデリゲート /// public Func IsInitiallyAssignableCallBack { get; init; } diff --git a/main.cs b/main.cs index 875bc4086..fb8abbc42 100644 --- a/main.cs +++ b/main.cs @@ -50,7 +50,7 @@ public class Main : BasePlugin // ========== //Sorry for many Japanese comments. public const string PluginGuid = "com.emptybottle.townofhost"; - public const string PluginVersion = "5.1.3"; + public const string PluginVersion = "5.1.4"; // サポートされている最低のAmongUsバージョン public static readonly string LowestSupportedVersion = "2023.10.24"; // このバージョンのみで公開ルームを無効にする場合