From f56649494f3a2050007fe6cf0226aba9ad331499 Mon Sep 17 00:00:00 2001 From: Gurge44 Date: Sun, 8 Dec 2024 22:51:18 +0100 Subject: [PATCH] lots of fixes still --- EHR.csproj | 2 +- GameMode/AllInOneGameMode.cs | 62 +-- Modules/CustomRoleSelector.cs | 39 +- Modules/CustomRolesHelper.cs | 2 +- Modules/OptionHolder.cs | 800 +++++++++++++++++----------------- Patches/ControlPatch.cs | 26 +- Patches/PlayerControlPatch.cs | 32 +- Patches/TextBoxPatch.cs | 49 ++- Resources/Lang/en_US.json | 3 +- Roles/Crewmate/President.cs | 5 +- Roles/Neutral/Curser.cs | 15 +- 11 files changed, 546 insertions(+), 489 deletions(-) diff --git a/EHR.csproj b/EHR.csproj index c7c0a547e..f8944e7e1 100644 --- a/EHR.csproj +++ b/EHR.csproj @@ -7,7 +7,7 @@ EHR Gurge44 preview - C:\Program Files\Epic Games\AmongUs + E:\Program Files\AmongUs true True $(MSBuildProjectName) diff --git a/GameMode/AllInOneGameMode.cs b/GameMode/AllInOneGameMode.cs index 257e60f1e..567c95d92 100644 --- a/GameMode/AllInOneGameMode.cs +++ b/GameMode/AllInOneGameMode.cs @@ -37,58 +37,58 @@ public static class AllInOneGameMode bool defaultValue = mode is CustomGameMode.HotPotato or CustomGameMode.MoveAndStop or CustomGameMode.NaturalDisasters or CustomGameMode.RoomRush or CustomGameMode.SoloKombat or CustomGameMode.Speedrun; GameModeIntegrationSettings[mode] = new BooleanOptionItem(id++, $"AllInOne.{mode}.Integration", defaultValue, TabGroup.GameSettings) - .SetHeader((int)mode == 2) - .SetGameMode(gameMode) - .SetColor(color); + .SetHeader((int)mode == 2) + .SetGameMode(gameMode) + .SetColor(color); } HotPotatoTimerMultiplier = new IntegerOptionItem(id++, "AllInOne.HotPotato.TimerMultiplier", new(1, 10, 1), 3, TabGroup.GameSettings) - .SetHeader(true) - .SetValueFormat(OptionFormat.Multiplier) - .SetGameMode(gameMode) - .SetColor(color); + .SetHeader(true) + .SetValueFormat(OptionFormat.Multiplier) + .SetGameMode(gameMode) + .SetColor(color); MoveAndStopMinGreenTimeBonus = new IntegerOptionItem(id++, "AllInOne.MoveAndStop.MinGreenTimeBonus", new(0, 60, 1), 5, TabGroup.GameSettings) - .SetValueFormat(OptionFormat.Seconds) - .SetGameMode(gameMode) - .SetColor(color); + .SetValueFormat(OptionFormat.Seconds) + .SetGameMode(gameMode) + .SetColor(color); MoveAndStopMaxGreenTimeBonus = new IntegerOptionItem(id++, "AllInOne.MoveAndStop.MaxGreenTimeBonus", new(0, 60, 1), 20, TabGroup.GameSettings) - .SetValueFormat(OptionFormat.Seconds) - .SetGameMode(gameMode) - .SetColor(color); + .SetValueFormat(OptionFormat.Seconds) + .SetGameMode(gameMode) + .SetColor(color); NaturalDisastersDisasterSpawnCooldownMultiplier = new IntegerOptionItem(id++, "AllInOne.NaturalDisasters.DisasterSpawnCooldownMultiplier", new(1, 10, 1), 4, TabGroup.GameSettings) - .SetValueFormat(OptionFormat.Multiplier) - .SetGameMode(gameMode) - .SetColor(color); + .SetValueFormat(OptionFormat.Multiplier) + .SetGameMode(gameMode) + .SetColor(color); NaturalDisastersWarningDurationMultiplier = new IntegerOptionItem(id++, "AllInOne.NaturalDisasters.WarningDurationMultiplier", new(1, 10, 1), 6, TabGroup.GameSettings) - .SetValueFormat(OptionFormat.Multiplier) - .SetGameMode(gameMode) - .SetColor(color); + .SetValueFormat(OptionFormat.Multiplier) + .SetGameMode(gameMode) + .SetColor(color); RoomRushTimeLimitMultiplier = new IntegerOptionItem(id++, "AllInOne.RoomRush.TimeLimitMultiplier", new(1, 10, 1), 3, TabGroup.GameSettings) - .SetValueFormat(OptionFormat.Multiplier) - .SetGameMode(gameMode) - .SetColor(color); + .SetValueFormat(OptionFormat.Multiplier) + .SetGameMode(gameMode) + .SetColor(color); RoomRushDontKillLastPlayer = new BooleanOptionItem(id++, "AllInOne.RoomRush.DontKillLastPlayer", true, TabGroup.GameSettings) - .SetGameMode(gameMode) - .SetColor(color); + .SetGameMode(gameMode) + .SetColor(color); RoomRushDontLowerTimeLimitWhenTwoPlayersEnterCorrectRoom = new BooleanOptionItem(id++, "AllInOne.RoomRush.DontLowerTimeLimitWhenTwoPlayersEnterCorrectRoom", true, TabGroup.GameSettings) - .SetGameMode(gameMode) - .SetColor(color); + .SetGameMode(gameMode) + .SetColor(color); RoomRushDontKillPlayersOutsideRoomWhenTimeRunsOut = new BooleanOptionItem(id++, "AllInOne.RoomRush.DontKillPlayersOutsideRoomWhenTimeRunsOut", true, TabGroup.GameSettings) - .SetGameMode(gameMode) - .SetColor(color); + .SetGameMode(gameMode) + .SetColor(color); SpeedrunTimeLimitMultiplier = new IntegerOptionItem(id, "AllInOne.Speedrun.TimeLimitMultiplier", new(1, 10, 1), 3, TabGroup.GameSettings) - .SetValueFormat(OptionFormat.Multiplier) - .SetGameMode(gameMode) - .SetColor(color); + .SetValueFormat(OptionFormat.Multiplier) + .SetGameMode(gameMode) + .SetColor(color); } public static void Init() diff --git a/Modules/CustomRoleSelector.cs b/Modules/CustomRoleSelector.cs index df123cb70..ea90040c3 100644 --- a/Modules/CustomRoleSelector.cs +++ b/Modules/CustomRoleSelector.cs @@ -142,21 +142,22 @@ internal static class CustomRoleSelector } var neutralLimits = Options.FactionMinMaxSettings[Team.Neutral]; + var numNeutrals = IRandom.Instance.Next(neutralLimits.MinSetting.GetInt(), neutralLimits.MaxSetting.GetInt() + 1); - if (Roles[RoleAssignType.Impostor].Count == 0 && neutralLimits.MaxSetting.GetInt() == 0 && !Main.SetRoles.Values.Any(x => x.IsImpostor() || x.IsNK())) + if (Roles[RoleAssignType.Impostor].Count == 0 && numNeutrals == 0 && !Main.SetRoles.Values.Any(x => x.IsImpostor() || x.IsNK())) { Roles[RoleAssignType.Impostor].Add(new(CustomRoles.ImpostorEHR, 100, optImpNum)); Logger.Warn("Adding Vanilla Impostor", "CustomRoleSelector"); } - if (Roles[RoleAssignType.Crewmate].Count == 0 && neutralLimits.MaxSetting.GetInt() == 0 && !Main.SetRoles.Values.Any(x => x.IsCrewmate())) + if (Roles[RoleAssignType.Crewmate].Count == 0 && numNeutrals == 0 && !Main.SetRoles.Values.Any(x => x.IsCrewmate())) { Roles[RoleAssignType.Crewmate].Add(new(CustomRoles.CrewmateEHR, 100, playerCount)); Logger.Warn("Adding Vanilla Crewmates", "CustomRoleSelector"); } Logger.Info($"Number of Impostors: {optImpNum}", "FactionLimits"); - Logger.Info($"Number of Neutrals: {neutralLimits.MinSetting.GetInt()} - {neutralLimits.MaxSetting.GetInt()}", "FactionLimits"); + Logger.Info($"Number of Neutrals: {neutralLimits.MinSetting.GetInt()} - {neutralLimits.MaxSetting.GetInt()} => {numNeutrals}", "FactionLimits"); Logger.Msg("=====================================================", "AllActiveRoles"); Logger.Info(string.Join(", ", Roles[RoleAssignType.Impostor].Select(x => $"{x.Role}: {x.SpawnChance}% - {x.MaxCount}")), "ImpRoles"); @@ -166,24 +167,17 @@ internal static class CustomRoleSelector Logger.Msg("=====================================================", "AllActiveRoles"); Dictionary subCategoryLimits = Options.RoleSubCategoryLimits - .Where(x => x.Value[0].GetBool()) + .Where(x => x.Key.GetTabFromOptionType() == TabGroup.NeutralRoles || x.Value[0].GetBool()) .ToDictionary(x => x.Key, x => IRandom.Instance.Next(x.Value[1].GetInt(), x.Value[2].GetInt() + 1)); if (subCategoryLimits.Count > 0) Logger.Info($"Sub-Category Limits: {string.Join(", ", subCategoryLimits.Select(x => $"{x.Key}: {x.Value}"))}", "SubCategoryLimits"); - - var nkHasLimit = subCategoryLimits.TryGetValue(RoleOptionType.Neutral_Killing, out var nkSetLimit); - var nkLimit = nkHasLimit ? nkSetLimit : neutralLimits.MaxSetting.GetInt(); - - var neHasLimit = subCategoryLimits.TryGetValue(RoleOptionType.Neutral_Evil, out var neLimit); - var nbHasLimit = subCategoryLimits.TryGetValue(RoleOptionType.Neutral_Benign, out var nbLimit); + int nkLimit = subCategoryLimits[RoleOptionType.Neutral_Killing]; + int nnkLimit = subCategoryLimits[RoleOptionType.Neutral_Evil] + subCategoryLimits[RoleOptionType.Neutral_Benign]; - int nnkLimit = neHasLimit && nbHasLimit ? neLimit + nbLimit : neHasLimit ? neLimit : nbHasLimit ? nbLimit : neutralLimits.MaxSetting.GetInt() - (nkHasLimit ? nkSetLimit : 0); - Logger.Info($"Number of Neutral Killing roles to select: {nkLimit}", "NeutralKillingLimit"); Logger.Info($"Number of Non-Killing Neutral roles to select: {nnkLimit}", "NonKillingNeutralLimit"); - - + foreach (RoleAssignType type in Roles.Keys.ToArray()) { Roles[type] = Roles[type] @@ -191,10 +185,10 @@ internal static class CustomRoleSelector .OrderBy(x => x.SpawnChance != 100) .DistinctBy(x => x.Role) .Select(x => ( - Info: x, - Limit: subCategoryLimits.TryGetValue(x.OptionType, out var limit) - ? (Exists: true, Value: limit) - : (Exists: false, Value: 0))) + Info: x, + Limit: subCategoryLimits.TryGetValue(x.OptionType, out var limit) + ? (Exists: true, Value: limit) + : (Exists: false, Value: 0))) .GroupBy(x => x.Info.OptionType) .Select(x => (Grouping: x, x.FirstOrDefault().Limit)) .SelectMany(x => x.Limit.Exists ? x.Grouping.Take(x.Limit.Value) : x.Grouping) @@ -211,9 +205,16 @@ internal static class CustomRoleSelector .ToList(); } + Logger.Msg("======================================================", "PreSelectedRoles"); + Logger.Info(string.Join(", ", Roles[RoleAssignType.Impostor].Select(x => x.Role.ToString())), "PreSelectedImpostorRoles"); + Logger.Info(string.Join(", ", Roles[RoleAssignType.NeutralKilling].Select(x => x.Role.ToString())), "PreSelectedNKRoles"); + Logger.Info(string.Join(", ", Roles[RoleAssignType.NonKillingNeutral].Select(x => x.Role.ToString())), "PreSelectedNNKRoles"); + Logger.Info(string.Join(", ", Roles[RoleAssignType.Crewmate].Select(x => x.Role.ToString())), "PreSelectedCrewRoles"); + Logger.Msg("======================================================", "PreSelectedRoles"); + int attempts = 0; - while (Roles[RoleAssignType.NeutralKilling].Count + Roles[RoleAssignType.NonKillingNeutral].Count > neutralLimits.MaxSetting.GetInt()) + while (Roles[RoleAssignType.NeutralKilling].Count + Roles[RoleAssignType.NonKillingNeutral].Count > numNeutrals) { if (attempts++ > 100) break; diff --git a/Modules/CustomRolesHelper.cs b/Modules/CustomRolesHelper.cs index e7174d523..59a8b18f5 100644 --- a/Modules/CustomRolesHelper.cs +++ b/Modules/CustomRolesHelper.cs @@ -591,7 +591,7 @@ internal static class CustomRolesHelper public static bool IsImpostor(this CustomRoles role) { - return role is + return (role == CustomRoles.DoubleAgent && !Main.IntroDestroyed) || role is CustomRoles.DoubleAgent or CustomRoles.Impostor or CustomRoles.ImpostorEHR or diff --git a/Modules/OptionHolder.cs b/Modules/OptionHolder.cs index a4a190977..c32b5b99e 100644 --- a/Modules/OptionHolder.cs +++ b/Modules/OptionHolder.cs @@ -875,9 +875,9 @@ public static class Options private static void GroupOptions() { GroupedOptions = OptionItem.AllOptions - .GroupBy(x => x.Tab) - .OrderBy(x => (int)x.Key) - .ToDictionary(x => x.Key, x => x.ToArray()); + .GroupBy(x => x.Tab) + .OrderBy(x => (int)x.Key) + .ToDictionary(x => x.Key, x => x.ToArray()); HnSManager.AllHnSRoles = HnSManager.GetAllHnsRoles(HnSManager.GetAllHnsRoleTypes()); } @@ -885,13 +885,13 @@ public static class Options private static void GroupAddons() { GroupedAddons = Assembly - .GetExecutingAssembly() - .GetTypes() - .Where(x => x.GetInterfaces().ToList().Contains(typeof(IAddon))) - .Select(x => (IAddon)Activator.CreateInstance(x)) - .Where(x => x != null) - .GroupBy(x => x.Type) - .ToDictionary(x => x.Key, x => x.Select(y => Enum.Parse(y.GetType().Name, true)).ToList()); + .GetExecutingAssembly() + .GetTypes() + .Where(x => x.GetInterfaces().ToList().Contains(typeof(IAddon))) + .Select(x => (IAddon)Activator.CreateInstance(x)) + .Where(x => x != null) + .GroupBy(x => x.Type) + .ToDictionary(x => x.Key, x => x.Select(y => Enum.Parse(y.GetType().Name, true)).ToList()); } public static VoteMode GetWhenSkipVote() @@ -990,13 +990,13 @@ public static class Options }; var minSetting = new IntegerOptionItem(id++, $"FactionLimits.{team}.Min", new(0, 15, 1), defaultNum.Min, tab) - .SetGameMode(CustomGameMode.Standard) - .SetHeader(true) - .SetColor(team.GetTeamColor()); + .SetGameMode(CustomGameMode.Standard) + .SetHeader(true) + .SetColor(team.GetTeamColor()); var maxSetting = new IntegerOptionItem(id++, $"FactionLimits.{team}.Max", new(0, 15, 1), defaultNum.Max, tab) - .SetGameMode(CustomGameMode.Standard) - .SetColor(team.GetTeamColor()); + .SetGameMode(CustomGameMode.Standard) + .SetColor(team.GetTeamColor()); FactionMinMaxSettings[team] = (minSetting, maxSetting); } @@ -1010,21 +1010,23 @@ public static class Options var options = new OptionItem[3]; options[0] = new BooleanOptionItem(id++, $"RoleSubCategoryLimitOptions.{roleOptionType}.EnableLimit", false, tab) - .SetGameMode(CustomGameMode.Standard) - .SetHeader(doneTabs.Add(tab)) - .SetColor(roleOptionTypeColor); + .SetGameMode(CustomGameMode.Standard) + .SetHeader(doneTabs.Add(tab)) + .SetColor(roleOptionTypeColor) + .SetHidden(tab == TabGroup.NeutralRoles); options[1] = new IntegerOptionItem(id++, $"RoleSubCategoryLimitOptions.{roleOptionType}.Min", new(0, 15, 1), 1, tab) - .SetParent(options[0]) - .SetGameMode(CustomGameMode.Standard) - .SetValueFormat(OptionFormat.Players) - .SetColor(roleOptionTypeColor); + .SetGameMode(CustomGameMode.Standard) + .SetValueFormat(OptionFormat.Players) + .SetColor(roleOptionTypeColor); options[2] = new IntegerOptionItem(id++, $"RoleSubCategoryLimitOptions.{roleOptionType}.Max", new(0, 15, 1), 1, tab) - .SetParent(options[0]) - .SetGameMode(CustomGameMode.Standard) - .SetValueFormat(OptionFormat.Players) - .SetColor(roleOptionTypeColor); + .SetGameMode(CustomGameMode.Standard) + .SetValueFormat(OptionFormat.Players) + .SetColor(roleOptionTypeColor); + + if (tab != TabGroup.NeutralRoles) options[1..].Do(x => x.SetParent(options[0])); + else options[1].SetHeader(true); RoleSubCategoryLimits[roleOptionType] = options; } @@ -1037,8 +1039,8 @@ public static class Options ImpKnowAlliesRole = new BooleanOptionItem(150, "ImpKnowAlliesRole", true, TabGroup.ImpostorRoles) - .SetGameMode(CustomGameMode.Standard) - .SetHeader(true); + .SetGameMode(CustomGameMode.Standard) + .SetHeader(true); ImpKnowWhosMadmate = new BooleanOptionItem(151, "ImpKnowWhosMadmate", false, TabGroup.ImpostorRoles) .SetGameMode(CustomGameMode.Standard); @@ -1047,8 +1049,8 @@ public static class Options .SetGameMode(CustomGameMode.Standard); MadmateKnowWhosMadmate = new BooleanOptionItem(153, "MadmateKnowWhosMadmate", false, TabGroup.ImpostorRoles) - .SetHeader(true) - .SetGameMode(CustomGameMode.Standard); + .SetHeader(true) + .SetGameMode(CustomGameMode.Standard); MadmateKnowWhosImp = new BooleanOptionItem(154, "MadmateKnowWhosImp", true, TabGroup.ImpostorRoles) .SetGameMode(CustomGameMode.Standard); @@ -1060,55 +1062,55 @@ public static class Options .SetGameMode(CustomGameMode.Standard); RefugeeKillCD = new FloatOptionItem(157, "RefugeeKillCD", new(0f, 180f, 2.5f), 25f, TabGroup.ImpostorRoles) - .SetGameMode(CustomGameMode.Standard) - .SetValueFormat(OptionFormat.Seconds); + .SetGameMode(CustomGameMode.Standard) + .SetValueFormat(OptionFormat.Seconds); DefaultShapeshiftCooldown = new FloatOptionItem(200, "DefaultShapeshiftCooldown", new(5f, 180f, 5f), 15f, TabGroup.ImpostorRoles) - .SetGameMode(CustomGameMode.Standard) - .SetHeader(true) - .SetValueFormat(OptionFormat.Seconds); + .SetGameMode(CustomGameMode.Standard) + .SetHeader(true) + .SetValueFormat(OptionFormat.Seconds); DeadImpCantSabotage = new BooleanOptionItem(201, "DeadImpCantSabotage", false, TabGroup.ImpostorRoles) .SetGameMode(CustomGameMode.Standard); NeutralRoleWinTogether = new BooleanOptionItem(208, "NeutralRoleWinTogether", false, TabGroup.NeutralRoles) - .SetGameMode(CustomGameMode.Standard) - .SetHeader(true); + .SetGameMode(CustomGameMode.Standard) + .SetHeader(true); NeutralWinTogether = new BooleanOptionItem(209, "NeutralWinTogether", false, TabGroup.NeutralRoles) - .SetParent(NeutralRoleWinTogether) - .SetGameMode(CustomGameMode.Standard); + .SetParent(NeutralRoleWinTogether) + .SetGameMode(CustomGameMode.Standard); NeutralsKnowEachOther = new BooleanOptionItem(212, "NeutralsKnowEachOther", false, TabGroup.NeutralRoles) .SetGameMode(CustomGameMode.Standard); NameDisplayAddons = new BooleanOptionItem(210, "NameDisplayAddons", true, TabGroup.Addons) - .SetGameMode(CustomGameMode.Standard) - .SetHeader(true); + .SetGameMode(CustomGameMode.Standard) + .SetHeader(true); NoLimitAddonsNumMax = new IntegerOptionItem(211, "NoLimitAddonsNumMax", new(1, 90, 1), 1, TabGroup.Addons) .SetGameMode(CustomGameMode.Standard); CharmedCanBeGuessed = new StringOptionItem(213, "ConvertedAddonCanBeGuessed", AddonGuessOptions, 2, TabGroup.Addons) - .SetHeader(true) - .SetGameMode(CustomGameMode.Standard) - .AddReplacement(("{role}", CustomRoles.Charmed.ToColoredString())); + .SetHeader(true) + .SetGameMode(CustomGameMode.Standard) + .AddReplacement(("{role}", CustomRoles.Charmed.ToColoredString())); RecruitCanBeGuessed = new StringOptionItem(214, "ConvertedAddonCanBeGuessed", AddonGuessOptions, 2, TabGroup.Addons) - .SetGameMode(CustomGameMode.Standard) - .AddReplacement(("{role}", CustomRoles.Recruit.ToColoredString())); + .SetGameMode(CustomGameMode.Standard) + .AddReplacement(("{role}", CustomRoles.Recruit.ToColoredString())); ContagiousCanBeGuessed = new StringOptionItem(215, "ConvertedAddonCanBeGuessed", AddonGuessOptions, 2, TabGroup.Addons) - .SetGameMode(CustomGameMode.Standard) - .AddReplacement(("{role}", CustomRoles.Contagious.ToColoredString())); + .SetGameMode(CustomGameMode.Standard) + .AddReplacement(("{role}", CustomRoles.Contagious.ToColoredString())); UndeadCanBeGuessed = new StringOptionItem(216, "ConvertedAddonCanBeGuessed", AddonGuessOptions, 2, TabGroup.Addons) - .SetGameMode(CustomGameMode.Standard) - .AddReplacement(("{role}", CustomRoles.Undead.ToColoredString())); + .SetGameMode(CustomGameMode.Standard) + .AddReplacement(("{role}", CustomRoles.Undead.ToColoredString())); EgoistCanBeGuessed = new StringOptionItem(217, "ConvertedAddonCanBeGuessed", AddonGuessOptions, 2, TabGroup.Addons) - .SetGameMode(CustomGameMode.Standard) - .AddReplacement(("{role}", CustomRoles.Egoist.ToColoredString())); + .SetGameMode(CustomGameMode.Standard) + .AddReplacement(("{role}", CustomRoles.Egoist.ToColoredString())); RoleLoadingText = "Add-ons\n."; @@ -1117,8 +1119,8 @@ public static class Options AddBracketsToAddons = new BooleanOptionItem(13500, "BracketAddons", false, TabGroup.Addons) - .SetGameMode(CustomGameMode.Standard) - .SetHeader(true); + .SetGameMode(CustomGameMode.Standard) + .SetHeader(true); #endregion @@ -1132,14 +1134,14 @@ public static class Options Type IAddonType = typeof(IAddon); Dictionary addonTypes = Assembly - .GetExecutingAssembly() - .GetTypes() - .Where(t => IAddonType.IsAssignableFrom(t) && !t.IsInterface) - .OrderBy(t => Translator.GetString(t.Name)) - .Select(type => (IAddon)Activator.CreateInstance(type)) - .Where(x => x != null) - .GroupBy(x => x.Type) - .ToDictionary(x => x.Key, x => x.ToArray()); + .GetExecutingAssembly() + .GetTypes() + .Where(t => IAddonType.IsAssignableFrom(t) && !t.IsInterface) + .OrderBy(t => Translator.GetString(t.Name)) + .Select(type => (IAddon)Activator.CreateInstance(type)) + .Where(x => x != null) + .GroupBy(x => x.Type) + .ToDictionary(x => x.Key, x => x.ToArray()); foreach (KeyValuePair addonType in addonTypes) { @@ -1202,10 +1204,10 @@ public static class Options .Do(x => x.SetupCustomOption()); Dictionary roleClassesDict = Main.AllRoleClasses - .Where(x => x.GetType().Name != "VanillaRole") - .GroupBy(x => ((CustomRoles)Enum.Parse(typeof(CustomRoles), ignoreCase: true, value: x.GetType().Name)).GetRoleOptionType()) - .OrderBy(x => (int)x.Key) - .ToDictionary(x => x.Key, x => x.ToArray()); + .Where(x => x.GetType().Name != "VanillaRole") + .GroupBy(x => ((CustomRoles)Enum.Parse(typeof(CustomRoles), ignoreCase: true, value: x.GetType().Name)).GetRoleOptionType()) + .OrderBy(x => (int)x.Key) + .ToDictionary(x => x.Key, x => x.ToArray()); foreach (KeyValuePair roleClasses in roleClassesDict) { @@ -1264,8 +1266,8 @@ public static class Options MainLoadingText = "Building EHR settings"; KickLowLevelPlayer = new IntegerOptionItem(19300, "KickLowLevelPlayer", new(0, 100, 1), 0, TabGroup.SystemSettings) - .SetValueFormat(OptionFormat.Level) - .SetHeader(true); + .SetValueFormat(OptionFormat.Level) + .SetHeader(true); KickAndroidPlayer = new BooleanOptionItem(19301, "KickAndroidPlayer", false, TabGroup.SystemSettings); KickPlayerFriendCodeNotExist = new BooleanOptionItem(19302, "KickPlayerFriendCodeNotExist", false, TabGroup.SystemSettings, true); @@ -1279,8 +1281,8 @@ public static class Options AutoKickStart = new BooleanOptionItem(19310, "AutoKickStart", false, TabGroup.SystemSettings); AutoKickStartTimes = new IntegerOptionItem(19311, "AutoKickStartTimes", new(0, 90, 1), 1, TabGroup.SystemSettings) - .SetParent(AutoKickStart) - .SetValueFormat(OptionFormat.Times); + .SetParent(AutoKickStart) + .SetValueFormat(OptionFormat.Times); AutoKickStartAsBan = new BooleanOptionItem(19312, "AutoKickStartAsBan", false, TabGroup.SystemSettings) .SetParent(AutoKickStart); @@ -1288,8 +1290,8 @@ public static class Options AutoKickStopWords = new BooleanOptionItem(19313, "AutoKickStopWords", false, TabGroup.SystemSettings); AutoKickStopWordsTimes = new IntegerOptionItem(19314, "AutoKickStopWordsTimes", new(0, 90, 1), 3, TabGroup.SystemSettings) - .SetParent(AutoKickStopWords) - .SetValueFormat(OptionFormat.Times); + .SetParent(AutoKickStopWords) + .SetValueFormat(OptionFormat.Times); AutoKickStopWordsAsBan = new BooleanOptionItem(19315, "AutoKickStopWordsAsBan", false, TabGroup.SystemSettings) .SetParent(AutoKickStopWords); @@ -1310,8 +1312,8 @@ public static class Options .SetParent(AutoPlayAgain); LowLoadMode = new BooleanOptionItem(19317, "LowLoadMode", true, TabGroup.SystemSettings) - .SetHeader(true) - .SetColor(Color.green); + .SetHeader(true) + .SetColor(Color.green); DeepLowLoad = new BooleanOptionItem(19325, "DeepLowLoad", false, TabGroup.SystemSettings) .SetColor(Color.red); @@ -1323,8 +1325,8 @@ public static class Options .SetColor(Color.yellow); EndWhenPlayerBug = new BooleanOptionItem(19318, "EndWhenPlayerBug", true, TabGroup.SystemSettings) - .SetHeader(true) - .SetColor(Color.blue); + .SetHeader(true) + .SetColor(Color.blue); RemovePetsAtDeadPlayers = new BooleanOptionItem(60294, "RemovePetsAtDeadPlayers", false, TabGroup.SystemSettings) .SetColor(Color.magenta); @@ -1355,7 +1357,7 @@ public static class Options SuffixMode = new StringOptionItem(19324, "SuffixMode", SuffixModes, 0, TabGroup.SystemSettings, true) .SetHeader(true); - HideGameSettings = new BooleanOptionItem(19400, "HideGameSettings", false, TabGroup.SystemSettings); + HideGameSettings = new BooleanOptionItem(19450, "HideGameSettings", false, TabGroup.SystemSettings); DIYGameSettings = new BooleanOptionItem(19401, "DIYGameSettings", false, TabGroup.SystemSettings); PlayerCanSetColor = new BooleanOptionItem(19402, "PlayerCanSetColor", false, TabGroup.SystemSettings); PlayerCanSetName = new BooleanOptionItem(19410, "PlayerCanSetName", false, TabGroup.SystemSettings); @@ -1383,8 +1385,8 @@ public static class Options .RegisterUpdateValueEvent((_, args) => IRandom.SetInstanceById(args.CurrentValue)); KPDCamouflageMode = new StringOptionItem(19500, "KPDCamouflageMode", CamouflageMode, 0, TabGroup.SystemSettings) - .SetHeader(true) - .SetColor(new Color32(255, 192, 203, byte.MaxValue)); + .SetHeader(true) + .SetColor(new Color32(255, 192, 203, byte.MaxValue)); LoadingPercentage = 64; @@ -1428,33 +1430,33 @@ public static class Options .SetColor(new Color32(255, 238, 232, byte.MaxValue)); CEMode = new StringOptionItem(19800, "ConfirmEjectionsMode", ConfirmEjectionsMode, 2, TabGroup.GameSettings) - .SetGameMode(CustomGameMode.Standard) - .SetHeader(true) - .SetColor(new Color32(255, 238, 232, byte.MaxValue)); + .SetGameMode(CustomGameMode.Standard) + .SetHeader(true) + .SetColor(new Color32(255, 238, 232, byte.MaxValue)); ShowImpRemainOnEject = new BooleanOptionItem(19810, "ShowImpRemainOnEject", true, TabGroup.GameSettings) - .SetGameMode(CustomGameMode.Standard) - .SetColor(new Color32(255, 238, 232, byte.MaxValue)); + .SetGameMode(CustomGameMode.Standard) + .SetColor(new Color32(255, 238, 232, byte.MaxValue)); ShowNKRemainOnEject = new BooleanOptionItem(19811, "ShowNKRemainOnEject", true, TabGroup.GameSettings) - .SetParent(ShowImpRemainOnEject) - .SetGameMode(CustomGameMode.Standard) - .SetColor(new Color32(255, 238, 232, byte.MaxValue)); + .SetParent(ShowImpRemainOnEject) + .SetGameMode(CustomGameMode.Standard) + .SetColor(new Color32(255, 238, 232, byte.MaxValue)); LoadingPercentage = 66; ShowTeamNextToRoleNameOnEject = new BooleanOptionItem(19812, "ShowTeamNextToRoleNameOnEject", true, TabGroup.GameSettings) - .SetGameMode(CustomGameMode.Standard) - .SetColor(new Color32(255, 238, 232, byte.MaxValue)); + .SetGameMode(CustomGameMode.Standard) + .SetColor(new Color32(255, 238, 232, byte.MaxValue)); ConfirmEgoistOnEject = new BooleanOptionItem(19813, "ConfirmEgoistOnEject", true, TabGroup.GameSettings) - .SetGameMode(CustomGameMode.Standard) - .SetColor(new Color32(255, 238, 232, byte.MaxValue)) - .SetHeader(true); + .SetGameMode(CustomGameMode.Standard) + .SetColor(new Color32(255, 238, 232, byte.MaxValue)) + .SetHeader(true); ConfirmLoversOnEject = new BooleanOptionItem(19815, "ConfirmLoversOnEject", true, TabGroup.GameSettings) - .SetGameMode(CustomGameMode.Standard) - .SetColor(new Color32(255, 238, 232, byte.MaxValue)); + .SetGameMode(CustomGameMode.Standard) + .SetColor(new Color32(255, 238, 232, byte.MaxValue)); LoadingPercentage = 67; @@ -1466,34 +1468,34 @@ public static class Options // Random Maps Mode RandomMapsMode = new BooleanOptionItem(19900, "RandomMapsMode", false, TabGroup.GameSettings) - .SetHeader(true) - .SetColor(new Color32(19, 188, 233, byte.MaxValue)); + .SetHeader(true) + .SetColor(new Color32(19, 188, 233, byte.MaxValue)); LoadingPercentage = 68; SkeldChance = new IntegerOptionItem(19910, "SkeldChance", new(0, 100, 5), 0, TabGroup.GameSettings) - .SetParent(RandomMapsMode) - .SetValueFormat(OptionFormat.Percent); + .SetParent(RandomMapsMode) + .SetValueFormat(OptionFormat.Percent); MiraChance = new IntegerOptionItem(19911, "MiraChance", new(0, 100, 5), 0, TabGroup.GameSettings) - .SetParent(RandomMapsMode) - .SetValueFormat(OptionFormat.Percent); + .SetParent(RandomMapsMode) + .SetValueFormat(OptionFormat.Percent); PolusChance = new IntegerOptionItem(19912, "PolusChance", new(0, 100, 5), 0, TabGroup.GameSettings) - .SetParent(RandomMapsMode) - .SetValueFormat(OptionFormat.Percent); + .SetParent(RandomMapsMode) + .SetValueFormat(OptionFormat.Percent); DleksChance = new IntegerOptionItem(19914, "DleksChance", new(0, 100, 5), 0, TabGroup.GameSettings) - .SetParent(RandomMapsMode) - .SetValueFormat(OptionFormat.Percent); + .SetParent(RandomMapsMode) + .SetValueFormat(OptionFormat.Percent); AirshipChance = new IntegerOptionItem(19913, "AirshipChance", new(0, 100, 5), 0, TabGroup.GameSettings) - .SetParent(RandomMapsMode) - .SetValueFormat(OptionFormat.Percent); + .SetParent(RandomMapsMode) + .SetValueFormat(OptionFormat.Percent); FungleChance = new IntegerOptionItem(19922, "FungleChance", new(0, 100, 5), 0, TabGroup.GameSettings) - .SetParent(RandomMapsMode) - .SetValueFormat(OptionFormat.Percent); + .SetParent(RandomMapsMode) + .SetValueFormat(OptionFormat.Percent); LoadingPercentage = 69; @@ -1507,8 +1509,8 @@ public static class Options // Airship Variable Electrical AirshipVariableElectrical = new BooleanOptionItem(22100, "AirshipVariableElectrical", false, TabGroup.GameSettings) - .SetGameMode(CustomGameMode.Standard) - .SetColor(new Color32(19, 188, 233, byte.MaxValue)); + .SetGameMode(CustomGameMode.Standard) + .SetColor(new Color32(19, 188, 233, byte.MaxValue)); // Disable Airship Moving Platform DisableAirshipMovingPlatform = new BooleanOptionItem(22110, "DisableAirshipMovingPlatform", false, TabGroup.GameSettings) @@ -1524,25 +1526,25 @@ public static class Options // Disable Zipline From Top DisableZiplineFromTop = new BooleanOptionItem(22308, "DisableZiplineFromTop", false, TabGroup.GameSettings) - .SetParent(DisableZiplineOnFungle) - .SetColor(new Color32(19, 188, 233, byte.MaxValue)); + .SetParent(DisableZiplineOnFungle) + .SetColor(new Color32(19, 188, 233, byte.MaxValue)); // Disable Zipline From Under DisableZiplineFromUnder = new BooleanOptionItem(22310, "DisableZiplineFromUnder", false, TabGroup.GameSettings) - .SetParent(DisableZiplineOnFungle) - .SetColor(new Color32(19, 188, 233, byte.MaxValue)); + .SetParent(DisableZiplineOnFungle) + .SetColor(new Color32(19, 188, 233, byte.MaxValue)); DisableZiplineForCrew = new BooleanOptionItem(22316, "DisableZiplineForCrew", false, TabGroup.GameSettings) - .SetParent(DisableZiplineOnFungle) - .SetColor(new Color32(19, 188, 233, byte.MaxValue)); + .SetParent(DisableZiplineOnFungle) + .SetColor(new Color32(19, 188, 233, byte.MaxValue)); DisableZiplineForImps = new BooleanOptionItem(22318, "DisableZiplineForImps", false, TabGroup.GameSettings) - .SetParent(DisableZiplineOnFungle) - .SetColor(new Color32(19, 188, 233, byte.MaxValue)); + .SetParent(DisableZiplineOnFungle) + .SetColor(new Color32(19, 188, 233, byte.MaxValue)); DisableZiplineForNeutrals = new BooleanOptionItem(22320, "DisableZiplineForNeutrals", false, TabGroup.GameSettings) - .SetParent(DisableZiplineOnFungle) - .SetColor(new Color32(19, 188, 233, byte.MaxValue)); + .SetParent(DisableZiplineOnFungle) + .SetColor(new Color32(19, 188, 233, byte.MaxValue)); ZiplineTravelTimeFromBottom = new FloatOptionItem(22312, "ZiplineTravelTimeFromBottom", new(0.5f, 10f, 0.5f), 4f, TabGroup.GameSettings) .SetColor(new Color32(19, 188, 233, byte.MaxValue)); @@ -1552,14 +1554,14 @@ public static class Options // Reset Doors After Meeting ResetDoorsEveryTurns = new BooleanOptionItem(22120, "ResetDoorsEveryTurns", false, TabGroup.GameSettings) - .SetGameMode(CustomGameMode.Standard) - .SetColor(new Color32(19, 188, 233, byte.MaxValue)); + .SetGameMode(CustomGameMode.Standard) + .SetColor(new Color32(19, 188, 233, byte.MaxValue)); // Reset Doors Mode DoorsResetMode = new StringOptionItem(22122, "DoorsResetMode", Enum.GetNames(), 2, TabGroup.GameSettings) - .SetColor(new Color32(19, 188, 233, byte.MaxValue)) - .SetGameMode(CustomGameMode.Standard) - .SetParent(ResetDoorsEveryTurns); + .SetColor(new Color32(19, 188, 233, byte.MaxValue)) + .SetGameMode(CustomGameMode.Standard) + .SetParent(ResetDoorsEveryTurns); // Change decontamination time on MiraHQ/Polus ChangeDecontaminationTime = new BooleanOptionItem(60503, "ChangeDecontaminationTime", false, TabGroup.GameSettings) @@ -1567,15 +1569,15 @@ public static class Options // Decontamination time on MiraHQ DecontaminationTimeOnMiraHQ = new FloatOptionItem(60504, "DecontaminationTimeOnMiraHQ", new(0.5f, 10f, 0.25f), 3f, TabGroup.GameSettings) - .SetParent(ChangeDecontaminationTime) - .SetValueFormat(OptionFormat.Multiplier) - .SetColor(new Color32(19, 188, 233, byte.MaxValue)); + .SetParent(ChangeDecontaminationTime) + .SetValueFormat(OptionFormat.Multiplier) + .SetColor(new Color32(19, 188, 233, byte.MaxValue)); // Decontamination time on Polus DecontaminationTimeOnPolus = new FloatOptionItem(60505, "DecontaminationTimeOnPolus", new(0.5f, 10f, 0.25f), 3f, TabGroup.GameSettings) - .SetParent(ChangeDecontaminationTime) - .SetValueFormat(OptionFormat.Multiplier) - .SetColor(new Color32(19, 188, 233, byte.MaxValue)); + .SetParent(ChangeDecontaminationTime) + .SetValueFormat(OptionFormat.Multiplier) + .SetColor(new Color32(19, 188, 233, byte.MaxValue)); LoadingPercentage = 70; @@ -1590,148 +1592,148 @@ public static class Options // CommsCamouflage CommsCamouflage = new BooleanOptionItem(22200, "CommsCamouflage", false, TabGroup.GameSettings) - .SetGameMode(CustomGameMode.Standard) - .SetHeader(true) - .SetColor(new Color32(243, 96, 96, byte.MaxValue)); + .SetGameMode(CustomGameMode.Standard) + .SetHeader(true) + .SetColor(new Color32(243, 96, 96, byte.MaxValue)); CommsCamouflageDisableOnFungle = new BooleanOptionItem(22202, "CommsCamouflageDisableOnFungle", true, TabGroup.GameSettings) - .SetGameMode(CustomGameMode.Standard) - .SetParent(CommsCamouflage) - .SetColor(new Color32(243, 96, 96, byte.MaxValue)); + .SetGameMode(CustomGameMode.Standard) + .SetParent(CommsCamouflage) + .SetColor(new Color32(243, 96, 96, byte.MaxValue)); CommsCamouflageLimit = new BooleanOptionItem(22203, "CommsCamouflageLimit", false, TabGroup.GameSettings) - .SetGameMode(CustomGameMode.Standard) - .SetParent(CommsCamouflage) - .SetColor(new Color32(243, 96, 96, byte.MaxValue)); + .SetGameMode(CustomGameMode.Standard) + .SetParent(CommsCamouflage) + .SetColor(new Color32(243, 96, 96, byte.MaxValue)); CommsCamouflageLimitSetChance = new BooleanOptionItem(22204, "CommsCamouflageLimitSetChance", false, TabGroup.GameSettings) - .SetGameMode(CustomGameMode.Standard) - .SetParent(CommsCamouflageLimit) - .SetColor(new Color32(243, 96, 96, byte.MaxValue)); + .SetGameMode(CustomGameMode.Standard) + .SetParent(CommsCamouflageLimit) + .SetColor(new Color32(243, 96, 96, byte.MaxValue)); CommsCamouflageLimitChance = new IntegerOptionItem(22205, "CommsCamouflageLimitChance", new(0, 100, 5), 50, TabGroup.GameSettings) - .SetGameMode(CustomGameMode.Standard) - .SetParent(CommsCamouflageLimitSetChance) - .SetValueFormat(OptionFormat.Percent) - .SetColor(new Color32(243, 96, 96, byte.MaxValue)); + .SetGameMode(CustomGameMode.Standard) + .SetParent(CommsCamouflageLimitSetChance) + .SetValueFormat(OptionFormat.Percent) + .SetColor(new Color32(243, 96, 96, byte.MaxValue)); CommsCamouflageLimitSetFrequency = new BooleanOptionItem(22206, "CommsCamouflageLimitSetFrequency", false, TabGroup.GameSettings) - .SetGameMode(CustomGameMode.Standard) - .SetParent(CommsCamouflageLimit) - .SetColor(new Color32(243, 96, 96, byte.MaxValue)); + .SetGameMode(CustomGameMode.Standard) + .SetParent(CommsCamouflageLimit) + .SetColor(new Color32(243, 96, 96, byte.MaxValue)); CommsCamouflageLimitFrequency = new IntegerOptionItem(22207, "CommsCamouflageLimitFrequency", new(1, 10, 1), 2, TabGroup.GameSettings) - .SetGameMode(CustomGameMode.Standard) - .SetParent(CommsCamouflageLimitSetFrequency) - .SetColor(new Color32(243, 96, 96, byte.MaxValue)); + .SetGameMode(CustomGameMode.Standard) + .SetParent(CommsCamouflageLimitSetFrequency) + .SetColor(new Color32(243, 96, 96, byte.MaxValue)); CommsCamouflageLimitSetMaxTimes = new BooleanOptionItem(22208, "CommsCamouflageLimitSetMaxTimes", false, TabGroup.GameSettings) - .SetGameMode(CustomGameMode.Standard) - .SetParent(CommsCamouflageLimit) - .SetColor(new Color32(243, 96, 96, byte.MaxValue)); + .SetGameMode(CustomGameMode.Standard) + .SetParent(CommsCamouflageLimit) + .SetColor(new Color32(243, 96, 96, byte.MaxValue)); CommsCamouflageLimitMaxTimesPerGame = new IntegerOptionItem(22209, "CommsCamouflageLimitMaxTimesPerGame", new(1, 30, 1), 3, TabGroup.GameSettings) - .SetGameMode(CustomGameMode.Standard) - .SetParent(CommsCamouflageLimitSetMaxTimes) - .SetColor(new Color32(243, 96, 96, byte.MaxValue)); + .SetGameMode(CustomGameMode.Standard) + .SetParent(CommsCamouflageLimitSetMaxTimes) + .SetColor(new Color32(243, 96, 96, byte.MaxValue)); CommsCamouflageLimitMaxTimesPerRound = new IntegerOptionItem(22210, "CommsCamouflageLimitMaxTimesPerRound", new(1, 10, 1), 1, TabGroup.GameSettings) - .SetGameMode(CustomGameMode.Standard) - .SetParent(CommsCamouflageLimitSetMaxTimes) - .SetColor(new Color32(243, 96, 96, byte.MaxValue)); + .SetGameMode(CustomGameMode.Standard) + .SetParent(CommsCamouflageLimitSetMaxTimes) + .SetColor(new Color32(243, 96, 96, byte.MaxValue)); DisableReportWhenCC = new BooleanOptionItem(22300, "DisableReportWhenCC", false, TabGroup.GameSettings) - .SetGameMode(CustomGameMode.Standard) - .SetColor(new Color32(243, 96, 96, byte.MaxValue)); + .SetGameMode(CustomGameMode.Standard) + .SetColor(new Color32(243, 96, 96, byte.MaxValue)); LoadingPercentage = 71; // Sabotage Cooldown Control SabotageCooldownControl = new BooleanOptionItem(22400, "SabotageCooldownControl", false, TabGroup.GameSettings) - .SetColor(new Color32(243, 96, 96, byte.MaxValue)) - .SetGameMode(CustomGameMode.Standard); + .SetColor(new Color32(243, 96, 96, byte.MaxValue)) + .SetGameMode(CustomGameMode.Standard); SabotageCooldown = new FloatOptionItem(22405, "SabotageCooldown", new(1f, 60f, 1f), 30f, TabGroup.GameSettings) - .SetParent(SabotageCooldownControl) - .SetValueFormat(OptionFormat.Seconds) - .SetGameMode(CustomGameMode.Standard); + .SetParent(SabotageCooldownControl) + .SetValueFormat(OptionFormat.Seconds) + .SetGameMode(CustomGameMode.Standard); // Sabotage Duration Control SabotageTimeControl = new BooleanOptionItem(22410, "SabotageTimeControl", false, TabGroup.GameSettings) - .SetColor(new Color32(243, 96, 96, byte.MaxValue)) - .SetGameMode(CustomGameMode.Standard); + .SetColor(new Color32(243, 96, 96, byte.MaxValue)) + .SetGameMode(CustomGameMode.Standard); // The Skeld SkeldReactorTimeLimit = new FloatOptionItem(22418, "SkeldReactorTimeLimit", new(5f, 90f, 1f), 30f, TabGroup.GameSettings) - .SetParent(SabotageTimeControl) - .SetValueFormat(OptionFormat.Seconds) - .SetGameMode(CustomGameMode.Standard); + .SetParent(SabotageTimeControl) + .SetValueFormat(OptionFormat.Seconds) + .SetGameMode(CustomGameMode.Standard); SkeldO2TimeLimit = new FloatOptionItem(22419, "SkeldO2TimeLimit", new(5f, 90f, 1f), 30f, TabGroup.GameSettings) - .SetParent(SabotageTimeControl) - .SetValueFormat(OptionFormat.Seconds) - .SetGameMode(CustomGameMode.Standard); + .SetParent(SabotageTimeControl) + .SetValueFormat(OptionFormat.Seconds) + .SetGameMode(CustomGameMode.Standard); // Mira HQ MiraReactorTimeLimit = new FloatOptionItem(22422, "MiraReactorTimeLimit", new(5f, 90f, 1f), 45f, TabGroup.GameSettings) - .SetParent(SabotageTimeControl) - .SetValueFormat(OptionFormat.Seconds) - .SetGameMode(CustomGameMode.Standard); + .SetParent(SabotageTimeControl) + .SetValueFormat(OptionFormat.Seconds) + .SetGameMode(CustomGameMode.Standard); MiraO2TimeLimit = new FloatOptionItem(22423, "MiraO2TimeLimit", new(5f, 90f, 1f), 45f, TabGroup.GameSettings) - .SetParent(SabotageTimeControl) - .SetValueFormat(OptionFormat.Seconds) - .SetGameMode(CustomGameMode.Standard); + .SetParent(SabotageTimeControl) + .SetValueFormat(OptionFormat.Seconds) + .SetGameMode(CustomGameMode.Standard); // Polus PolusReactorTimeLimit = new FloatOptionItem(22424, "PolusReactorTimeLimit", new(5f, 90f, 1f), 60f, TabGroup.GameSettings) - .SetParent(SabotageTimeControl) - .SetValueFormat(OptionFormat.Seconds) - .SetGameMode(CustomGameMode.Standard); + .SetParent(SabotageTimeControl) + .SetValueFormat(OptionFormat.Seconds) + .SetGameMode(CustomGameMode.Standard); // The Airship AirshipReactorTimeLimit = new FloatOptionItem(22425, "AirshipReactorTimeLimit", new(5f, 90f, 1f), 90f, TabGroup.GameSettings) - .SetParent(SabotageTimeControl) - .SetValueFormat(OptionFormat.Seconds) - .SetGameMode(CustomGameMode.Standard); + .SetParent(SabotageTimeControl) + .SetValueFormat(OptionFormat.Seconds) + .SetGameMode(CustomGameMode.Standard); // The Fungle FungleReactorTimeLimit = new FloatOptionItem(22426, "FungleReactorTimeLimit", new(5f, 90f, 1f), 60f, TabGroup.GameSettings) - .SetParent(SabotageTimeControl) - .SetValueFormat(OptionFormat.Seconds) - .SetGameMode(CustomGameMode.Standard); + .SetParent(SabotageTimeControl) + .SetValueFormat(OptionFormat.Seconds) + .SetGameMode(CustomGameMode.Standard); FungleMushroomMixupDuration = new FloatOptionItem(22427, "FungleMushroomMixupDuration", new(5f, 90f, 1f), 10f, TabGroup.GameSettings) - .SetParent(SabotageTimeControl) - .SetValueFormat(OptionFormat.Seconds) - .SetGameMode(CustomGameMode.Standard); + .SetParent(SabotageTimeControl) + .SetValueFormat(OptionFormat.Seconds) + .SetGameMode(CustomGameMode.Standard); LoadingPercentage = 72; LightsOutSpecialSettings = new BooleanOptionItem(22500, "LightsOutSpecialSettings", false, TabGroup.GameSettings) - .SetColor(new Color32(243, 96, 96, byte.MaxValue)) - .SetGameMode(CustomGameMode.Standard); + .SetColor(new Color32(243, 96, 96, byte.MaxValue)) + .SetGameMode(CustomGameMode.Standard); BlockDisturbancesToSwitches = new BooleanOptionItem(60551, "BlockDisturbancesToSwitches", false, TabGroup.GameSettings) - .SetParent(LightsOutSpecialSettings) - .SetGameMode(CustomGameMode.Standard); + .SetParent(LightsOutSpecialSettings) + .SetGameMode(CustomGameMode.Standard); DisableAirshipViewingDeckLightsPanel = new BooleanOptionItem(22510, "DisableAirshipViewingDeckLightsPanel", false, TabGroup.GameSettings) - .SetParent(LightsOutSpecialSettings) - .SetGameMode(CustomGameMode.Standard); + .SetParent(LightsOutSpecialSettings) + .SetGameMode(CustomGameMode.Standard); DisableAirshipGapRoomLightsPanel = new BooleanOptionItem(22511, "DisableAirshipGapRoomLightsPanel", false, TabGroup.GameSettings) - .SetParent(LightsOutSpecialSettings) - .SetGameMode(CustomGameMode.Standard); + .SetParent(LightsOutSpecialSettings) + .SetGameMode(CustomGameMode.Standard); DisableAirshipCargoLightsPanel = new BooleanOptionItem(22512, "DisableAirshipCargoLightsPanel", false, TabGroup.GameSettings) - .SetParent(LightsOutSpecialSettings) - .SetGameMode(CustomGameMode.Standard); + .SetParent(LightsOutSpecialSettings) + .SetGameMode(CustomGameMode.Standard); NKWinsBySabotageIfNoImpAlive = new BooleanOptionItem(22520, "NKWinsBySabotageIfNoImpAlive", false, TabGroup.GameSettings) - .SetColor(new Color32(243, 96, 96, byte.MaxValue)) - .SetGameMode(CustomGameMode.Standard); + .SetColor(new Color32(243, 96, 96, byte.MaxValue)) + .SetGameMode(CustomGameMode.Standard); LoadingPercentage = 73; @@ -1741,80 +1743,80 @@ public static class Options .SetColor(new Color32(255, 153, 153, byte.MaxValue)); DisableShieldAnimations = new BooleanOptionItem(22601, "DisableShieldAnimations", true, TabGroup.GameSettings) - .SetGameMode(CustomGameMode.Standard) - .SetHeader(true) - .SetColor(new Color32(255, 153, 153, byte.MaxValue)); + .SetGameMode(CustomGameMode.Standard) + .SetHeader(true) + .SetColor(new Color32(255, 153, 153, byte.MaxValue)); DisableKillAnimationOnGuess = new BooleanOptionItem(22602, "DisableKillAnimationOnGuess", true, TabGroup.GameSettings) - .SetGameMode(CustomGameMode.Standard) - .SetColor(new Color32(255, 153, 153, byte.MaxValue)); + .SetGameMode(CustomGameMode.Standard) + .SetColor(new Color32(255, 153, 153, byte.MaxValue)); DisableShapeshiftAnimations = new BooleanOptionItem(22604, "DisableShapeshiftAnimations", true, TabGroup.GameSettings) - .SetGameMode(CustomGameMode.Standard) - .SetColor(new Color32(255, 153, 153, byte.MaxValue)); + .SetGameMode(CustomGameMode.Standard) + .SetColor(new Color32(255, 153, 153, byte.MaxValue)); DisableAllShapeshiftAnimations = new BooleanOptionItem(22605, "DisableAllShapeshiftAnimations", false, TabGroup.GameSettings) - .SetParent(DisableShapeshiftAnimations) - .SetGameMode(CustomGameMode.Standard) - .SetColor(new Color32(255, 153, 153, byte.MaxValue)); + .SetParent(DisableShapeshiftAnimations) + .SetGameMode(CustomGameMode.Standard) + .SetColor(new Color32(255, 153, 153, byte.MaxValue)); DisableVanillaRoles = new BooleanOptionItem(22600, "DisableVanillaRoles", true, TabGroup.GameSettings) - .SetGameMode(CustomGameMode.Standard) - .SetColor(new Color32(255, 153, 153, byte.MaxValue)); + .SetGameMode(CustomGameMode.Standard) + .SetColor(new Color32(255, 153, 153, byte.MaxValue)); DisableTaskWin = new BooleanOptionItem(22650, "DisableTaskWin", false, TabGroup.GameSettings) - .SetGameMode(CustomGameMode.Standard) - .SetColor(new Color32(255, 153, 153, byte.MaxValue)); + .SetGameMode(CustomGameMode.Standard) + .SetColor(new Color32(255, 153, 153, byte.MaxValue)); DisableTaskWinIfAllCrewsAreDead = new BooleanOptionItem(22651, "DisableTaskWinIfAllCrewsAreDead", false, TabGroup.GameSettings) - .SetGameMode(CustomGameMode.Standard) - .SetColor(new Color32(255, 153, 153, byte.MaxValue)); + .SetGameMode(CustomGameMode.Standard) + .SetColor(new Color32(255, 153, 153, byte.MaxValue)); DisableTaskWinIfAllCrewsAreConverted = new BooleanOptionItem(22652, "DisableTaskWinIfAllCrewsAreConverted", false, TabGroup.GameSettings) - .SetGameMode(CustomGameMode.Standard) - .SetColor(new Color32(255, 153, 153, byte.MaxValue)); + .SetGameMode(CustomGameMode.Standard) + .SetColor(new Color32(255, 153, 153, byte.MaxValue)); LoadingPercentage = 74; DisableMeeting = new BooleanOptionItem(22700, "DisableMeeting", false, TabGroup.GameSettings) - .SetGameMode(CustomGameMode.Standard) - .SetColor(new Color32(255, 153, 153, byte.MaxValue)); + .SetGameMode(CustomGameMode.Standard) + .SetColor(new Color32(255, 153, 153, byte.MaxValue)); DisableSabotage = new BooleanOptionItem(22800, "DisableSabotage", false, TabGroup.GameSettings) .SetColor(new Color32(255, 153, 153, byte.MaxValue)); DisableReactorOnSkeldAndMira = new BooleanOptionItem(22801, "DisableReactorOnSkeldAndMira", false, TabGroup.GameSettings) - .SetParent(DisableSabotage) - .SetColor(new Color32(255, 153, 153, byte.MaxValue)); + .SetParent(DisableSabotage) + .SetColor(new Color32(255, 153, 153, byte.MaxValue)); DisableReactorOnPolus = new BooleanOptionItem(22802, "DisableReactorOnPolus", false, TabGroup.GameSettings) - .SetParent(DisableSabotage) - .SetColor(new Color32(255, 153, 153, byte.MaxValue)); + .SetParent(DisableSabotage) + .SetColor(new Color32(255, 153, 153, byte.MaxValue)); DisableReactorOnAirship = new BooleanOptionItem(22803, "DisableReactorOnAirship", false, TabGroup.GameSettings) - .SetParent(DisableSabotage) - .SetColor(new Color32(255, 153, 153, byte.MaxValue)); + .SetParent(DisableSabotage) + .SetColor(new Color32(255, 153, 153, byte.MaxValue)); DisableO2 = new BooleanOptionItem(22804, "DisableO2", false, TabGroup.GameSettings) - .SetParent(DisableSabotage) - .SetColor(new Color32(255, 153, 153, byte.MaxValue)); + .SetParent(DisableSabotage) + .SetColor(new Color32(255, 153, 153, byte.MaxValue)); DisableComms = new BooleanOptionItem(22805, "DisableComms", false, TabGroup.GameSettings) - .SetParent(DisableSabotage) - .SetColor(new Color32(255, 153, 153, byte.MaxValue)); + .SetParent(DisableSabotage) + .SetColor(new Color32(255, 153, 153, byte.MaxValue)); DisableLights = new BooleanOptionItem(22806, "DisableLights", false, TabGroup.GameSettings) - .SetParent(DisableSabotage) - .SetColor(new Color32(255, 153, 153, byte.MaxValue)); + .SetParent(DisableSabotage) + .SetColor(new Color32(255, 153, 153, byte.MaxValue)); DisableMushroomMixup = new BooleanOptionItem(22807, "DisableMushroomMixup", false, TabGroup.GameSettings) - .SetParent(DisableSabotage) - .SetColor(new Color32(255, 153, 153, byte.MaxValue)); + .SetParent(DisableSabotage) + .SetColor(new Color32(255, 153, 153, byte.MaxValue)); DisableCloseDoor = new BooleanOptionItem(22810, "DisableCloseDoor", false, TabGroup.GameSettings) - .SetParent(DisableSabotage) - .SetColor(new Color32(255, 153, 153, byte.MaxValue)); + .SetParent(DisableSabotage) + .SetColor(new Color32(255, 153, 153, byte.MaxValue)); DisableWhisperCommand = new BooleanOptionItem(22811, "DisableWhisperCommand", false, TabGroup.GameSettings) .SetColor(new Color32(255, 153, 153, byte.MaxValue)); @@ -1874,16 +1876,16 @@ public static class Options .SetParent(DisableAirshipDevices); DisableFungleDevices = new BooleanOptionItem(22925, "DisableFungleDevices", false, TabGroup.GameSettings) - .SetParent(DisableDevices) - .SetGameMode(CustomGameMode.Standard); + .SetParent(DisableDevices) + .SetGameMode(CustomGameMode.Standard); DisableFungleCamera = new BooleanOptionItem(22926, "DisableFungleCamera", false, TabGroup.GameSettings) - .SetParent(DisableFungleDevices) - .SetGameMode(CustomGameMode.Standard); + .SetParent(DisableFungleDevices) + .SetGameMode(CustomGameMode.Standard); DisableFungleVital = new BooleanOptionItem(22927, "DisableFungleVital", false, TabGroup.GameSettings) - .SetParent(DisableFungleDevices) - .SetGameMode(CustomGameMode.Standard); + .SetParent(DisableFungleDevices) + .SetGameMode(CustomGameMode.Standard); DisableDevicesIgnoreConditions = new BooleanOptionItem(22920, "IgnoreConditions", false, TabGroup.GameSettings) .SetParent(DisableDevices); @@ -1898,83 +1900,83 @@ public static class Options .SetParent(DisableDevicesIgnoreConditions); DisableDevicesIgnoreAfterAnyoneDied = new BooleanOptionItem(22924, "IgnoreAfterAnyoneDied", false, TabGroup.GameSettings) - .SetParent(DisableDevicesIgnoreConditions) - .SetGameMode(CustomGameMode.Standard); + .SetParent(DisableDevicesIgnoreConditions) + .SetGameMode(CustomGameMode.Standard); LoadingPercentage = 78; UsePets = new BooleanOptionItem(23850, "UsePets", false, TabGroup.TaskSettings) - .SetHeader(true) - .SetColor(new Color32(60, 0, 255, byte.MaxValue)); + .SetHeader(true) + .SetColor(new Color32(60, 0, 255, byte.MaxValue)); PetToAssignToEveryone = new StringOptionItem(23854, "PetToAssign", PetToAssign, 24, TabGroup.TaskSettings) - .SetParent(UsePets) - .SetColor(new Color32(60, 0, 255, byte.MaxValue)); - + .SetParent(UsePets) + .SetColor(new Color32(60, 0, 255, byte.MaxValue)); + AnonymousBodies = new BooleanOptionItem(23852, "AnonymousBodies", false, TabGroup.TaskSettings) - .SetGameMode(CustomGameMode.Standard) - .SetHeader(true) - .SetColor(new Color32(0, 165, 255, byte.MaxValue)); + .SetGameMode(CustomGameMode.Standard) + .SetHeader(true) + .SetColor(new Color32(0, 165, 255, byte.MaxValue)); UseUnshiftTrigger = new BooleanOptionItem(23871, "UseUnshiftTrigger", false, TabGroup.TaskSettings) - .SetGameMode(CustomGameMode.Standard) - .SetHeader(true) - .SetColor(new Color32(255, 44, 44, byte.MaxValue)); + .SetGameMode(CustomGameMode.Standard) + .SetHeader(true) + .SetColor(new Color32(255, 44, 44, byte.MaxValue)); UseUnshiftTriggerForNKs = new BooleanOptionItem(23872, "UseUnshiftTriggerForNKs", false, TabGroup.TaskSettings) - .SetParent(UseUnshiftTrigger) - .SetGameMode(CustomGameMode.Standard) - .SetColor(new Color32(255, 44, 44, byte.MaxValue)); + .SetParent(UseUnshiftTrigger) + .SetGameMode(CustomGameMode.Standard) + .SetColor(new Color32(255, 44, 44, byte.MaxValue)); UsePhantomBasis = new BooleanOptionItem(23851, "UsePhantomBasis", false, TabGroup.TaskSettings) - .SetGameMode(CustomGameMode.Standard) - .SetHeader(true) - .SetColor(new Color32(255, 255, 44, byte.MaxValue)); + .SetGameMode(CustomGameMode.Standard) + .SetHeader(true) + .SetColor(new Color32(255, 255, 44, byte.MaxValue)); UsePhantomBasisForNKs = new BooleanOptionItem(23864, "UsePhantomBasisForNKs", false, TabGroup.TaskSettings) - .SetGameMode(CustomGameMode.Standard) - .SetParent(UsePhantomBasis) - .SetColor(new Color32(255, 255, 44, byte.MaxValue)); + .SetGameMode(CustomGameMode.Standard) + .SetParent(UsePhantomBasis) + .SetColor(new Color32(255, 255, 44, byte.MaxValue)); EveryoneCanVent = new BooleanOptionItem(23853, "EveryoneCanVent", false, TabGroup.TaskSettings) - .SetGameMode(CustomGameMode.Standard) - .SetHeader(true) - .SetColor(Color.green); + .SetGameMode(CustomGameMode.Standard) + .SetHeader(true) + .SetColor(Color.green); OverrideScientistBasedRoles = new BooleanOptionItem(23855, "OverrideScientistBasedRoles", false, TabGroup.TaskSettings) - .SetGameMode(CustomGameMode.Standard) - .SetParent(EveryoneCanVent); + .SetGameMode(CustomGameMode.Standard) + .SetParent(EveryoneCanVent); WhackAMole = new BooleanOptionItem(23856, "WhackAMole", false, TabGroup.TaskSettings) - .SetGameMode(CustomGameMode.Standard) - .SetParent(EveryoneCanVent); + .SetGameMode(CustomGameMode.Standard) + .SetParent(EveryoneCanVent); SpawnAdditionalRefugeeOnImpsDead = new BooleanOptionItem(23857, "SpawnAdditionalRefugeeOnImpsDead", false, TabGroup.TaskSettings) - .SetGameMode(CustomGameMode.Standard) - .SetColor(Color.magenta) - .SetHeader(true); + .SetGameMode(CustomGameMode.Standard) + .SetColor(Color.magenta) + .SetHeader(true); SpawnAdditionalRefugeeWhenNKAlive = new BooleanOptionItem(23858, "SpawnAdditionalRefugeeWhenNKAlive", false, TabGroup.TaskSettings) - .SetGameMode(CustomGameMode.Standard) - .SetColor(Color.magenta) - .SetParent(SpawnAdditionalRefugeeOnImpsDead); + .SetGameMode(CustomGameMode.Standard) + .SetColor(Color.magenta) + .SetParent(SpawnAdditionalRefugeeOnImpsDead); SpawnAdditionalRefugeeMinAlivePlayers = new IntegerOptionItem(23859, "SpawnAdditionalRefugeeMinAlivePlayers", new(1, 14, 1), 7, TabGroup.TaskSettings) - .SetGameMode(CustomGameMode.Standard) - .SetColor(Color.magenta) - .SetParent(SpawnAdditionalRefugeeOnImpsDead); + .SetGameMode(CustomGameMode.Standard) + .SetColor(Color.magenta) + .SetParent(SpawnAdditionalRefugeeOnImpsDead); AprilFoolsMode = new BooleanOptionItem(23860, "AprilFoolsMode", Main.IsAprilFools, TabGroup.TaskSettings) - .SetGameMode(CustomGameMode.Standard) - .SetHeader(true) - .SetColor(new Color32(255, 153, 153, byte.MaxValue)); + .SetGameMode(CustomGameMode.Standard) + .SetHeader(true) + .SetColor(new Color32(255, 153, 153, byte.MaxValue)); // Disable Short Tasks DisableShortTasks = new BooleanOptionItem(23000, "DisableShortTasks", false, TabGroup.TaskSettings) - .SetHeader(true) - .SetColor(new Color32(239, 89, 175, byte.MaxValue)); + .SetHeader(true) + .SetColor(new Color32(239, 89, 175, byte.MaxValue)); DisableCleanVent = new BooleanOptionItem(23001, "DisableCleanVent", false, TabGroup.TaskSettings) .SetParent(DisableShortTasks); @@ -2242,9 +2244,9 @@ public static class Options .SetHeader(true); GuesserMode = new BooleanOptionItem(19700, "GuesserMode", false, TabGroup.TaskSettings) - .SetGameMode(CustomGameMode.Standard) - .SetColor(Color.yellow) - .SetHeader(true); + .SetGameMode(CustomGameMode.Standard) + .SetColor(Color.yellow) + .SetHeader(true); CrewmatesCanGuess = new BooleanOptionItem(19710, "CrewmatesCanGuess", false, TabGroup.TaskSettings) .SetParent(GuesserMode); @@ -2273,8 +2275,8 @@ public static class Options .SetParent(GuesserMode); HideGuesserCommands = new BooleanOptionItem(19717, "GuesserTryHideMsg", true, TabGroup.TaskSettings) - .SetParent(GuesserMode) - .SetColor(Color.green); + .SetParent(GuesserMode) + .SetColor(Color.green); GuesserDoesntDieOnMisguess = new BooleanOptionItem(19718, "GuesserDoesntDieOnMisguess", false, TabGroup.TaskSettings) .SetGameMode(CustomGameMode.Standard); @@ -2288,24 +2290,24 @@ public static class Options .SetColor(new Color32(147, 241, 240, byte.MaxValue)); SyncButtonMode = new BooleanOptionItem(23300, "SyncButtonMode", false, TabGroup.GameSettings) - .SetColor(new Color32(147, 241, 240, byte.MaxValue)) - .SetHeader(true) - .SetGameMode(CustomGameMode.Standard); + .SetColor(new Color32(147, 241, 240, byte.MaxValue)) + .SetHeader(true) + .SetGameMode(CustomGameMode.Standard); SyncedButtonCount = new IntegerOptionItem(23310, "SyncedButtonCount", new(0, 100, 1), 10, TabGroup.GameSettings) - .SetParent(SyncButtonMode) - .SetValueFormat(OptionFormat.Times) - .SetGameMode(CustomGameMode.Standard); + .SetParent(SyncButtonMode) + .SetValueFormat(OptionFormat.Times) + .SetGameMode(CustomGameMode.Standard); LoadingPercentage = 93; AllAliveMeeting = new BooleanOptionItem(23400, "AllAliveMeeting", false, TabGroup.GameSettings) - .SetGameMode(CustomGameMode.Standard) - .SetColor(new Color32(147, 241, 240, byte.MaxValue)); + .SetGameMode(CustomGameMode.Standard) + .SetColor(new Color32(147, 241, 240, byte.MaxValue)); AllAliveMeetingTime = new FloatOptionItem(23410, "AllAliveMeetingTime", new(1f, 300f, 1f), 10f, TabGroup.GameSettings) - .SetParent(AllAliveMeeting) - .SetValueFormat(OptionFormat.Seconds); + .SetParent(AllAliveMeeting) + .SetValueFormat(OptionFormat.Seconds); EnableKillerLeftCommand = new BooleanOptionItem(44428, "EnableKillerLeftCommand", true, TabGroup.GameSettings) .SetColor(new Color32(147, 241, 240, byte.MaxValue)); @@ -2315,18 +2317,18 @@ public static class Options foreach (GameStateInfo s in Enum.GetValues()) { GameStateSettings[s] = new BooleanOptionItem(44429 + i, $"GameStateCommand.Show{s}", true, TabGroup.GameSettings) - .SetGameMode(CustomGameMode.Standard) - .SetParent(EnableKillerLeftCommand) - .SetColor(new Color32(147, 241, 240, byte.MaxValue)); + .SetGameMode(CustomGameMode.Standard) + .SetParent(EnableKillerLeftCommand) + .SetColor(new Color32(147, 241, 240, byte.MaxValue)); i++; } MinPlayersForGameStateCommand = new IntegerOptionItem(44438, "MinPlayersForGameStateCommand", new(1, 15, 1), 1, TabGroup.GameSettings) - .SetParent(EnableKillerLeftCommand) - .SetGameMode(CustomGameMode.Standard) - .SetValueFormat(OptionFormat.Players) - .SetColor(new Color32(147, 241, 240, byte.MaxValue)); + .SetParent(EnableKillerLeftCommand) + .SetGameMode(CustomGameMode.Standard) + .SetValueFormat(OptionFormat.Players) + .SetColor(new Color32(147, 241, 240, byte.MaxValue)); SeeEjectedRolesInMeeting = new BooleanOptionItem(44439, "SeeEjectedRolesInMeeting", true, TabGroup.GameSettings) .SetColor(new Color32(147, 241, 240, byte.MaxValue)); @@ -2338,48 +2340,48 @@ public static class Options AdditionalEmergencyCooldown = new BooleanOptionItem(23500, "AdditionalEmergencyCooldown", false, TabGroup.GameSettings) - .SetGameMode(CustomGameMode.Standard) - .SetColor(new Color32(147, 241, 240, byte.MaxValue)); + .SetGameMode(CustomGameMode.Standard) + .SetColor(new Color32(147, 241, 240, byte.MaxValue)); AdditionalEmergencyCooldownThreshold = new IntegerOptionItem(23510, "AdditionalEmergencyCooldownThreshold", new(1, 15, 1), 1, TabGroup.GameSettings) - .SetParent(AdditionalEmergencyCooldown) - .SetGameMode(CustomGameMode.Standard) - .SetValueFormat(OptionFormat.Players); + .SetParent(AdditionalEmergencyCooldown) + .SetGameMode(CustomGameMode.Standard) + .SetValueFormat(OptionFormat.Players); AdditionalEmergencyCooldownTime = new FloatOptionItem(23511, "AdditionalEmergencyCooldownTime", new(1f, 60f, 1f), 1f, TabGroup.GameSettings) - .SetParent(AdditionalEmergencyCooldown) - .SetGameMode(CustomGameMode.Standard) - .SetValueFormat(OptionFormat.Seconds); + .SetParent(AdditionalEmergencyCooldown) + .SetGameMode(CustomGameMode.Standard) + .SetValueFormat(OptionFormat.Seconds); LoadingPercentage = 95; VoteMode = new BooleanOptionItem(23600, "VoteMode", false, TabGroup.GameSettings) - .SetColor(new Color32(147, 241, 240, byte.MaxValue)) - .SetGameMode(CustomGameMode.Standard); + .SetColor(new Color32(147, 241, 240, byte.MaxValue)) + .SetGameMode(CustomGameMode.Standard); WhenSkipVote = new StringOptionItem(23610, "WhenSkipVote", VoteModes[..3], 0, TabGroup.GameSettings) - .SetParent(VoteMode) - .SetGameMode(CustomGameMode.Standard); + .SetParent(VoteMode) + .SetGameMode(CustomGameMode.Standard); WhenSkipVoteIgnoreFirstMeeting = new BooleanOptionItem(23611, "WhenSkipVoteIgnoreFirstMeeting", false, TabGroup.GameSettings) - .SetParent(WhenSkipVote) - .SetGameMode(CustomGameMode.Standard); + .SetParent(WhenSkipVote) + .SetGameMode(CustomGameMode.Standard); WhenSkipVoteIgnoreNoDeadBody = new BooleanOptionItem(23612, "WhenSkipVoteIgnoreNoDeadBody", false, TabGroup.GameSettings) - .SetParent(WhenSkipVote) - .SetGameMode(CustomGameMode.Standard); + .SetParent(WhenSkipVote) + .SetGameMode(CustomGameMode.Standard); WhenSkipVoteIgnoreEmergency = new BooleanOptionItem(23613, "WhenSkipVoteIgnoreEmergency", false, TabGroup.GameSettings) - .SetParent(WhenSkipVote) - .SetGameMode(CustomGameMode.Standard); + .SetParent(WhenSkipVote) + .SetGameMode(CustomGameMode.Standard); WhenNonVote = new StringOptionItem(23700, "WhenNonVote", VoteModes, 0, TabGroup.GameSettings) - .SetParent(VoteMode) - .SetGameMode(CustomGameMode.Standard); + .SetParent(VoteMode) + .SetGameMode(CustomGameMode.Standard); WhenTie = new StringOptionItem(23750, "WhenTie", TieModes, 0, TabGroup.GameSettings) - .SetParent(VoteMode) - .SetGameMode(CustomGameMode.Standard); + .SetParent(VoteMode) + .SetGameMode(CustomGameMode.Standard); LoadingPercentage = 96; @@ -2390,8 +2392,8 @@ public static class Options .SetColor(new Color32(193, 255, 209, byte.MaxValue)); LadderDeath = new BooleanOptionItem(23800, "LadderDeath", false, TabGroup.GameSettings) - .SetHeader(true) - .SetColor(new Color32(193, 255, 209, byte.MaxValue)); + .SetHeader(true) + .SetColor(new Color32(193, 255, 209, byte.MaxValue)); LadderDeathChance = new StringOptionItem(23810, "LadderDeathChance", Rates[1..], 0, TabGroup.GameSettings) .SetParent(LadderDeath); @@ -2400,12 +2402,12 @@ public static class Options FixFirstKillCooldown = new BooleanOptionItem(23900, "FixFirstKillCooldown", false, TabGroup.GameSettings) - .SetGameMode(CustomGameMode.Standard) - .SetColor(new Color32(193, 255, 209, byte.MaxValue)); + .SetGameMode(CustomGameMode.Standard) + .SetColor(new Color32(193, 255, 209, byte.MaxValue)); StartingKillCooldown = new FloatOptionItem(23950, "StartingKillCooldown", new(1, 60, 1), 18, TabGroup.GameSettings) - .SetColor(new Color32(193, 255, 209, byte.MaxValue)) - .SetValueFormat(OptionFormat.Seconds); + .SetColor(new Color32(193, 255, 209, byte.MaxValue)) + .SetValueFormat(OptionFormat.Seconds); ShieldPersonDiedFirst = new BooleanOptionItem(24000, "ShieldPersonDiedFirst", false, TabGroup.GameSettings) .SetColor(new Color32(193, 255, 209, byte.MaxValue)); @@ -2414,13 +2416,13 @@ public static class Options KillFlashDuration = new FloatOptionItem(24100, "KillFlashDuration", new(0.1f, 0.45f, 0.05f), 0.3f, TabGroup.GameSettings) - .SetColor(new Color32(193, 255, 209, byte.MaxValue)) - .SetValueFormat(OptionFormat.Seconds) - .SetGameMode(CustomGameMode.Standard); + .SetColor(new Color32(193, 255, 209, byte.MaxValue)) + .SetValueFormat(OptionFormat.Seconds) + .SetGameMode(CustomGameMode.Standard); UniqueNeutralRevealScreen = new BooleanOptionItem(24450, "UniqueNeutralRevealScreen", false, TabGroup.GameSettings) - .SetGameMode(CustomGameMode.Standard) - .SetColor(new Color32(193, 255, 209, byte.MaxValue)); + .SetGameMode(CustomGameMode.Standard) + .SetColor(new Color32(193, 255, 209, byte.MaxValue)); new TextOptionItem(100029, "MenuTitle.Ghost", TabGroup.GameSettings) @@ -2432,17 +2434,17 @@ public static class Options GhostCanSeeOtherRoles = new BooleanOptionItem(24300, "GhostCanSeeOtherRoles", true, TabGroup.GameSettings) - .SetGameMode(CustomGameMode.Standard) - .SetHeader(true) - .SetColor(new Color32(217, 218, 255, byte.MaxValue)); + .SetGameMode(CustomGameMode.Standard) + .SetHeader(true) + .SetColor(new Color32(217, 218, 255, byte.MaxValue)); GhostCanSeeOtherVotes = new BooleanOptionItem(24400, "GhostCanSeeOtherVotes", true, TabGroup.GameSettings) - .SetGameMode(CustomGameMode.Standard) - .SetColor(new Color32(217, 218, 255, byte.MaxValue)); + .SetGameMode(CustomGameMode.Standard) + .SetColor(new Color32(217, 218, 255, byte.MaxValue)); GhostCanSeeDeathReason = new BooleanOptionItem(24500, "GhostCanSeeDeathReason", true, TabGroup.GameSettings) - .SetGameMode(CustomGameMode.Standard) - .SetColor(new Color32(217, 218, 255, byte.MaxValue)); + .SetGameMode(CustomGameMode.Standard) + .SetColor(new Color32(217, 218, 255, byte.MaxValue)); yield return null; @@ -2473,15 +2475,15 @@ public static class Options public static void SetupRoleOptions(int id, TabGroup tab, CustomRoles role, CustomGameMode customGameMode = CustomGameMode.Standard, bool zeroOne = false) { var spawnOption = new StringOptionItem(id, role.ToString(), zeroOne ? RatesZeroOne : Rates, 0, tab).SetColor(Utils.GetRoleColor(role)) - .SetHeader(true) - .SetGameMode(customGameMode) as StringOptionItem; + .SetHeader(true) + .SetGameMode(customGameMode) as StringOptionItem; CustomRoleSpawnChances.Add(role, spawnOption); OptionItem countOption = new IntegerOptionItem(id + 1, "Maximum", new(1, 15, 1), 1, tab) - .SetParent(spawnOption) - .SetValueFormat(OptionFormat.Players) - .SetGameMode(customGameMode); + .SetParent(spawnOption) + .SetValueFormat(OptionFormat.Players) + .SetGameMode(customGameMode); CustomRoleCounts.Add(role, countOption); } @@ -2489,41 +2491,41 @@ public static class Options public static void SetupAdtRoleOptions(int id, CustomRoles role, CustomGameMode customGameMode = CustomGameMode.Standard, bool canSetNum = false, TabGroup tab = TabGroup.Addons, bool canSetChance = true, bool teamSpawnOptions = false, bool allowZeroCount = false) { var spawnOption = new StringOptionItem(id, role.ToString(), RatesZeroOne, 0, tab).SetColor(Utils.GetRoleColor(role)) - .SetHeader(true) - .SetGameMode(customGameMode) as StringOptionItem; + .SetHeader(true) + .SetGameMode(customGameMode) as StringOptionItem; OptionItem countOption = new IntegerOptionItem(id + 1, "Maximum", new(allowZeroCount ? 0 : 1, canSetNum ? 15 : 1, 1), 1, tab) - .SetParent(spawnOption) - .SetValueFormat(OptionFormat.Players) - .SetHidden(!canSetNum) - .SetGameMode(customGameMode); + .SetParent(spawnOption) + .SetValueFormat(OptionFormat.Players) + .SetHidden(!canSetNum) + .SetGameMode(customGameMode); var spawnRateOption = new IntegerOptionItem(id + 2, "AdditionRolesSpawnRate", new(0, 100, 5), canSetChance ? 65 : 100, tab) - .SetParent(spawnOption) - .SetValueFormat(OptionFormat.Percent) - .SetHidden(!canSetChance) - .SetGameMode(customGameMode) as IntegerOptionItem; + .SetParent(spawnOption) + .SetValueFormat(OptionFormat.Percent) + .SetHidden(!canSetChance) + .SetGameMode(customGameMode) as IntegerOptionItem; OptionItem guessSetting = new StringOptionItem(id + 3, "AddonCanBeGuessed", AddonGuessOptions, 2, tab) - .SetParent(spawnOption) - .SetGameMode(customGameMode); + .SetParent(spawnOption) + .SetGameMode(customGameMode); if (teamSpawnOptions) { OptionItem impOption = new BooleanOptionItem(id + 4, "ImpCanBeRole", true, tab) - .SetParent(spawnOption) - .SetGameMode(customGameMode) - .AddReplacement(("{role}", role.ToColoredString())); + .SetParent(spawnOption) + .SetGameMode(customGameMode) + .AddReplacement(("{role}", role.ToColoredString())); OptionItem neutralOption = new BooleanOptionItem(id + 5, "NeutralCanBeRole", true, tab) - .SetParent(spawnOption) - .SetGameMode(customGameMode) - .AddReplacement(("{role}", role.ToColoredString())); + .SetParent(spawnOption) + .SetGameMode(customGameMode) + .AddReplacement(("{role}", role.ToColoredString())); OptionItem crewOption = new BooleanOptionItem(id + 6, "CrewCanBeRole", true, tab) - .SetParent(spawnOption) - .SetGameMode(customGameMode) - .AddReplacement(("{role}", role.ToColoredString())); + .SetParent(spawnOption) + .SetGameMode(customGameMode) + .AddReplacement(("{role}", role.ToColoredString())); AddonCanBeSettings.Add(role, (impOption, neutralOption, crewOption)); } @@ -2538,13 +2540,13 @@ public static class Options public static void SetupSingleRoleOptions(int id, TabGroup tab, CustomRoles role, int count = 1, CustomGameMode customGameMode = CustomGameMode.Standard, bool zeroOne = false, bool hideMaxSetting = true) { var spawnOption = new StringOptionItem(id, role.ToString(), zeroOne ? RatesZeroOne : Rates, 0, tab).SetColor(Utils.GetRoleColor(role)) - .SetHeader(true) - .SetGameMode(customGameMode) as StringOptionItem; + .SetHeader(true) + .SetGameMode(customGameMode) as StringOptionItem; OptionItem countOption = new IntegerOptionItem(id + 1, "Maximum", new(count, count, count), count, tab) - .SetParent(spawnOption) - .SetHidden(hideMaxSetting) - .SetGameMode(customGameMode); + .SetParent(spawnOption) + .SetHidden(hideMaxSetting) + .SetGameMode(customGameMode); CustomRoleSpawnChances.Add(role, spawnOption); CustomRoleCounts.Add(role, countOption); @@ -2554,22 +2556,22 @@ public static class Options public static OptionItem CreateCDSetting(int id, TabGroup tab, CustomRoles role, bool isKCD = false) { return new FloatOptionItem(id, isKCD ? "KillCooldown" : "AbilityCooldown", new(0f, 180f, 2.5f), 30f, tab) - .SetParent(CustomRoleSpawnChances[role]) - .SetValueFormat(OptionFormat.Seconds); + .SetParent(CustomRoleSpawnChances[role]) + .SetValueFormat(OptionFormat.Seconds); } public static OptionItem CreatePetUseSetting(int id, CustomRoles role) { return new BooleanOptionItem(id, "UsePetInsteadOfKillButton", false, TabGroup.CrewmateRoles) - .SetParent(CustomRoleSpawnChances[role]) - .SetColor(Color.magenta); + .SetParent(CustomRoleSpawnChances[role]) + .SetColor(Color.magenta); } public static OptionItem CreateVoteCancellingUseSetting(int id, CustomRoles role, TabGroup tab) { return new BooleanOptionItem(id, "UseVoteCancellingAfterVote", false, tab) - .SetParent(CustomRoleSpawnChances[role]) - .SetColor(Color.yellow); + .SetParent(CustomRoleSpawnChances[role]) + .SetColor(Color.yellow); } public class OverrideTasksData @@ -2585,26 +2587,26 @@ public static class Options Dictionary replacementDic = new() { { "%role%", role.ToColoredString() } }; DoOverride = new BooleanOptionItem(idStart++, "doOverride", false, tab) - .SetParent(CustomRoleSpawnChances[role]) - .SetValueFormat(OptionFormat.None); + .SetParent(CustomRoleSpawnChances[role]) + .SetValueFormat(OptionFormat.None); DoOverride.ReplacementDictionary = replacementDic; AssignCommonTasks = new BooleanOptionItem(idStart++, "assignCommonTasks", true, tab) - .SetParent(DoOverride) - .SetValueFormat(OptionFormat.None); + .SetParent(DoOverride) + .SetValueFormat(OptionFormat.None); AssignCommonTasks.ReplacementDictionary = replacementDic; NumLongTasks = new IntegerOptionItem(idStart++, "roleLongTasksNum", new(0, 90, 1), 3, tab) - .SetParent(DoOverride) - .SetValueFormat(OptionFormat.Pieces); + .SetParent(DoOverride) + .SetValueFormat(OptionFormat.Pieces); NumLongTasks.ReplacementDictionary = replacementDic; NumShortTasks = new IntegerOptionItem(idStart, "roleShortTasksNum", new(0, 90, 1), 3, tab) - .SetParent(DoOverride) - .SetValueFormat(OptionFormat.Pieces); + .SetParent(DoOverride) + .SetValueFormat(OptionFormat.Pieces); NumShortTasks.ReplacementDictionary = replacementDic; diff --git a/Patches/ControlPatch.cs b/Patches/ControlPatch.cs index 7a8fc8f26..bf1b8ed38 100644 --- a/Patches/ControlPatch.cs +++ b/Patches/ControlPatch.cs @@ -20,7 +20,7 @@ internal class ControllerManagerUpdatePatch public static void Postfix( /*ControllerManager __instance*/) { - if (GameStates.IsLobby) + if (GameStates.IsLobby && !HudManager.Instance.Chat.IsOpenOrOpening) { if (Input.GetKeyDown(KeyCode.Tab)) OptionShower.Next(); @@ -28,10 +28,12 @@ internal class ControllerManagerUpdatePatch if (OrGetKeysDown(KeyCode.Alpha1 + i, KeyCode.Keypad1 + i) && OptionShower.Pages.Count >= i + 1) OptionShower.CurrentPage = i; - if (KeysDown(KeyCode.Return) && GameSettingMenu.Instance != null && GameSettingMenu.Instance.isActiveAndEnabled) GameSettingMenuPatch.SearchForOptionsAction?.Invoke(); + if (KeysDown(KeyCode.Return) && GameSettingMenu.Instance != null && GameSettingMenu.Instance.isActiveAndEnabled) + GameSettingMenuPatch.SearchForOptionsAction?.Invoke(); } - if (KeysDown(KeyCode.LeftShift, KeyCode.LeftControl, KeyCode.X)) ExileController.Instance?.ReEnableGameplay(); + if (KeysDown(KeyCode.LeftShift, KeyCode.LeftControl, KeyCode.X)) + ExileController.Instance?.ReEnableGameplay(); if (KeysDown(KeyCode.LeftAlt, KeyCode.Return)) LateTask.New(SetResolutionManager.Postfix, 0.01f, "Fix Button Position"); @@ -172,7 +174,8 @@ internal class ControllerManagerUpdatePatch HudManager.Instance.StartCoroutine(DestroyableSingleton.Instance.CoShowIntro()); } - if (KeysDown(KeyCode.Return, KeyCode.V, KeyCode.LeftShift) && GameStates.IsMeeting) MeetingHud.Instance.RpcClearVote(AmongUsClient.Instance.ClientId); + if (KeysDown(KeyCode.Return, KeyCode.V, KeyCode.LeftShift) && GameStates.IsMeeting) + MeetingHud.Instance.RpcClearVote(AmongUsClient.Instance.ClientId); if (KeysDown(KeyCode.Return, KeyCode.D, KeyCode.LeftShift) && GameStates.IsInGame) { @@ -192,32 +195,32 @@ internal class ControllerManagerUpdatePatch foreach (PlayerTask task in PlayerControl.LocalPlayer.myTasks) PlayerControl.LocalPlayer.RpcCompleteTask(task.Id); - if (Input.GetKeyDown(KeyCode.Y) && !GameStates.IsMeeting) + if (Input.GetKeyDown(KeyCode.Y) && !GameStates.IsMeeting && !HudManager.Instance.Chat.IsOpenOrOpening) { RPC.SyncCustomSettingsRPC(); Logger.SendInGame(GetString("SyncCustomSettingsRPC")); } - if (Input.GetKeyDown(KeyCode.Equals) && !GameStates.IsMeeting) + if (Input.GetKeyDown(KeyCode.Equals) && !GameStates.IsMeeting && !HudManager.Instance.Chat.IsOpenOrOpening) { Main.VisibleTasksCount = !Main.VisibleTasksCount; DestroyableSingleton.Instance.Notifier.AddDisconnectMessage($"VisibleTaskCount changed to {Main.VisibleTasksCount}."); } - if (Input.GetKeyDown(KeyCode.I) && !GameStates.IsMeeting) + if (Input.GetKeyDown(KeyCode.I) && !GameStates.IsMeeting && !HudManager.Instance.Chat.IsOpenOrOpening) { Logger.SendInGame(PlayerControl.LocalPlayer.Pos().ToString()); Logger.SendInGame(PlayerControl.LocalPlayer.GetPlainShipRoom()?.RoomId.ToString() ?? "null"); } - if (Input.GetKeyDown(KeyCode.C) && !GameStates.IsMeeting) + if (Input.GetKeyDown(KeyCode.C) && !GameStates.IsMeeting && !HudManager.Instance.Chat.IsOpenOrOpening) { foreach (PlayerControl pc in PlayerControl.AllPlayerControls) if (!pc.AmOwner) pc.MyPhysics.RpcEnterVent(2); } - if (Input.GetKeyDown(KeyCode.V) && !GameStates.IsMeeting) + if (Input.GetKeyDown(KeyCode.V) && !GameStates.IsMeeting && !HudManager.Instance.Chat.IsOpenOrOpening) { Vector2 pos = PlayerControl.LocalPlayer.NetTransform.transform.position; @@ -231,14 +234,15 @@ internal class ControllerManagerUpdatePatch } } - if (Input.GetKeyDown(KeyCode.B) && !GameStates.IsMeeting) + if (Input.GetKeyDown(KeyCode.B) && !GameStates.IsMeeting && !HudManager.Instance.Chat.IsOpenOrOpening) { foreach (PlayerControl pc in PlayerControl.AllPlayerControls) if (!pc.AmOwner) pc.MyPhysics.RpcExitVent(2); } - if (Input.GetKeyDown(KeyCode.N) && !GameStates.IsMeeting) VentilationSystem.Update(VentilationSystem.Operation.StartCleaning, 0); + if (Input.GetKeyDown(KeyCode.N) && !GameStates.IsMeeting && !HudManager.Instance.Chat.IsOpenOrOpening) + VentilationSystem.Update(VentilationSystem.Operation.StartCleaning, 0); #endif } diff --git a/Patches/PlayerControlPatch.cs b/Patches/PlayerControlPatch.cs index 3f53f8383..f7db50355 100644 --- a/Patches/PlayerControlPatch.cs +++ b/Patches/PlayerControlPatch.cs @@ -227,10 +227,13 @@ internal static class CheckMurderPatch return false; case CustomGameMode.AllInOne: if (killer.Is(CustomRoles.Killer)) killer.Kill(target); + if (CustomGameMode.CaptureTheFlag.IsActiveOrIntegrated()) CTFManager.OnCheckMurder(killer, target); + if (CustomGameMode.HideAndSeek.IsActiveOrIntegrated()) HnSManager.OnCheckMurder(killer, target); + return false; case CustomGameMode.Speedrun: killer.Kill(target); @@ -278,9 +281,9 @@ internal static class CheckMurderPatch return false; case true when killer.GetCustomRole().GetDYRole() == RoleTypes.Impostor: if (killer.CheckDoubleTrigger(target, () => - { - if (CheckMurder()) killer.RpcCheckAndMurder(target); - })) + { + if (CheckMurder()) killer.RpcCheckAndMurder(target); + })) killer.RpcCheckAndMurder(target); return false; @@ -697,7 +700,7 @@ internal static class MurderPlayerPatch delay = Math.Max(delay, 0.15f); if (delay > 0.15f && Options.BaitDelayNotify.GetBool()) killer.Notify(ColorString(GetRoleColor(CustomRoles.Bait), string.Format(GetString("KillBaitNotify"), (int)delay)), delay); - Logger.Info($"{killer.GetNameWithRole().RemoveHtmlTags()} 击杀诱饵 => {target.GetNameWithRole().RemoveHtmlTags()}", "MurderPlayer"); + Logger.Info($"{killer.GetNameWithRole().RemoveHtmlTags()} killed Bait => {target.GetNameWithRole().RemoveHtmlTags()}", "MurderPlayer"); LateTask.New(() => { @@ -1614,9 +1617,9 @@ internal static class FixedUpdatePatch if (seer.IsDousedPlayer(target)) Mark.Append($"▲"); else if ( - Arsonist.CurrentDousingTarget != byte.MaxValue && - Arsonist.CurrentDousingTarget == target.PlayerId - ) + Arsonist.CurrentDousingTarget != byte.MaxValue && + Arsonist.CurrentDousingTarget == target.PlayerId + ) Mark.Append($"△"); break; @@ -1624,9 +1627,9 @@ internal static class FixedUpdatePatch if (seer.IsDrawPlayer(target)) Mark.Append($"●"); else if ( - Revolutionist.CurrentDrawTarget != byte.MaxValue && - Revolutionist.CurrentDrawTarget == target.PlayerId - ) + Revolutionist.CurrentDrawTarget != byte.MaxValue && + Revolutionist.CurrentDrawTarget == target.PlayerId + ) Mark.Append($"○"); break; @@ -2353,4 +2356,13 @@ internal static class ShouldProcessRpcPatch __result = true; return false; } +} + +[HarmonyPatch(typeof(PlayerPhysics), nameof(PlayerPhysics.RpcBootFromVent))] +static class BootFromVentPatch +{ + public static bool Prefix(PlayerPhysics __instance) + { + return !GameStates.IsInTask || ExileController.Instance || __instance == null || __instance.myPlayer == null || !__instance.myPlayer.IsAlive() || !__instance.myPlayer.Is(CustomRoles.Nimble); + } } \ No newline at end of file diff --git a/Patches/TextBoxPatch.cs b/Patches/TextBoxPatch.cs index fe8cbfdc9..b71879519 100644 --- a/Patches/TextBoxPatch.cs +++ b/Patches/TextBoxPatch.cs @@ -22,6 +22,7 @@ internal static class TextBoxTMPSetTextPatch { private static TextMeshPro PlaceHolderText; private static TextMeshPro CommandInfoText; + private static TextMeshPro AdditionalInfoText; public static bool IsInvalidCommand; @@ -130,10 +131,28 @@ internal static class TextBoxTMPSetTextPatch CommandInfoText.transform.SetAsLastSibling(); } + if (AdditionalInfoText == null) + { + HudManager hud = DestroyableSingleton.Instance; + AdditionalInfoText = Object.Instantiate(hud.KillButton.cooldownTimerText, hud.transform, true); + AdditionalInfoText.name = "AdditionalInfoText"; + AdditionalInfoText.alignment = TextAlignmentOptions.Left; + AdditionalInfoText.verticalAlignment = VerticalAlignmentOptions.Top; + AdditionalInfoText.transform.localPosition = new(-5f, 0f, 0f); + AdditionalInfoText.overflowMode = TextOverflowModes.Overflow; + AdditionalInfoText.enableWordWrapping = false; + AdditionalInfoText.color = Color.white; + AdditionalInfoText.fontSize = AdditionalInfoText.fontSizeMax = AdditionalInfoText.fontSizeMin = 1.8f; + AdditionalInfoText.sortingOrder = 1000; + AdditionalInfoText.transform.SetAsLastSibling(); + } + string inputForm = input.TrimStart('/'); string text = "/" + (exactMatch ? inputForm : command.CommandForms.Where(x => x.All(char.IsAscii) && x.StartsWith(inputForm)).MaxBy(x => x.Length)); var info = $"{command.Description}"; + string additionalInfo = string.Empty; + if (exactMatch && command.Arguments.Length > 0) { bool poll = command.CommandForms.Contains("poll"); @@ -151,7 +170,9 @@ internal static class TextBoxTMPSetTextPatch if (command.ArgsDescriptions.Length <= i) break; int skip = poll ? input.TakeWhile(x => x != '?').Count(x => x == ' ') - 1 : 0; - string arg = poll ? i == 0 ? args[..++skip].Join(delimiter: " ") : args[spaces - 1 < i ? skip + i + spaces : skip + i] : args[spaces > i ? i : i + spaces]; + string arg = say ? args[0] : poll ? i == 0 ? args[..++skip].Join(delimiter: " ") : args[spaces - 1 < i ? skip + i + spaces : skip + i] : args[spaces > i ? i : i + spaces]; + + string argName = command.Arguments.Split(' ')[i]; bool current = spaces - 1 == i, invalid = IsInvalidArg(), valid = IsValidArg(); info += "\n" + (invalid, current, valid) switch @@ -167,11 +188,18 @@ internal static class TextBoxTMPSetTextPatch info += $" - {arg}{GetExtraArgInfo()}: {command.ArgsDescriptions[i]}"; if (current || invalid || valid) info += ""; + if (additionalInfo.Length == 0 && argName.Replace('[', '{').Replace(']', '}') is "{id}" or "{id1}" or "{id2}") + { + var allIds = Main.AllPlayerControls.ToDictionary(x => x.PlayerId.ColoredPlayerName(), x => x.PlayerId); + additionalInfo = $"{Translator.GetString("PlayerIdList").TrimEnd(' ')}\n{string.Join('\n', allIds.Select(x => $"{x.Key} \uffeb {x.Value}"))}"; + OptionShower.CurrentPage = 0; + } + continue; bool IsInvalidArg() { - return arg != command.Arguments.Split(' ')[i] && command.Arguments.Split(' ')[i] switch + return arg != argName && argName switch { "{id}" or "{id1}" or "{id2}" => !byte.TryParse(arg, out byte id) || Main.AllPlayerControls.All(x => x.PlayerId != id), "{number}" or "{level}" or "{duration}" or "{number1}" or "{number2}" => !int.TryParse(arg, out int num) || num < 0, @@ -186,7 +214,7 @@ internal static class TextBoxTMPSetTextPatch bool IsValidArg() { - return command.Arguments.Split(' ')[i].Replace('[', '{').Replace(']', '}') switch + return argName switch { "{id}" or "{id1}" or "{id2}" => byte.TryParse(arg, out byte id) && Main.AllPlayerControls.Any(x => x.PlayerId == id), "{team}" => arg is "crew" or "imp", @@ -201,7 +229,7 @@ internal static class TextBoxTMPSetTextPatch { return !IsValidArg() ? string.Empty - : command.Arguments.Split(' ')[i] switch + : argName switch { "{id}" or "{id1}" or "{id2}" => $" ({byte.Parse(arg).ColoredPlayerName()})", "{role}" or "{addon}" when ChatCommands.GetRoleByName(arg, out CustomRoles role) => $" ({role.ToColoredString()})", @@ -213,11 +241,17 @@ internal static class TextBoxTMPSetTextPatch PlaceHolderText.text = text; CommandInfoText.text = info; + AdditionalInfoText.text = additionalInfo; PlaceHolderText.enabled = true; CommandInfoText.enabled = true; + AdditionalInfoText.enabled = true; + } + catch (Exception e) + { + Utils.ThrowException(e); + Destroy(); } - catch { Destroy(); } return; @@ -225,6 +259,7 @@ internal static class TextBoxTMPSetTextPatch { if (PlaceHolderText != null) PlaceHolderText.enabled = false; if (CommandInfoText != null) CommandInfoText.enabled = false; + if (AdditionalInfoText != null) AdditionalInfoText.enabled = false; } } @@ -234,6 +269,9 @@ internal static class TextBoxTMPSetTextPatch __instance.freeChatField.textArea.SetText(PlaceHolderText.text); __instance.freeChatField.textArea.compoText = ""; + + if (AdditionalInfoText != null && AdditionalInfoText.text != "") + OptionShower.CurrentPage = 0; } public static void Update() @@ -243,6 +281,7 @@ internal static class TextBoxTMPSetTextPatch bool open = HudManager.Instance?.Chat?.IsOpenOrOpening ?? false; PlaceHolderText?.gameObject.SetActive(open); CommandInfoText?.gameObject.SetActive(open); + AdditionalInfoText?.gameObject.SetActive(open); } catch { } } diff --git a/Resources/Lang/en_US.json b/Resources/Lang/en_US.json index f7aeeea7a..2c8415f76 100644 --- a/Resources/Lang/en_US.json +++ b/Resources/Lang/en_US.json @@ -2324,6 +2324,7 @@ "CommandDescription.Achievements": "See which achievements you have unlocked and which you haven't", "CommandDescription.DeathNote": "Guess someone's real name as the Note Killer.", "CommandDescription.Whisper": "Whisper a message to a player.", + "CommandDescription.Spectate": "Makes you a spectator for the next game. You should just enable Game Master as the host.", "CommandArgs.ChangeSetting.Name": "The setting's name to change (leave blank to view all settings)", "CommandArgs.ChangeSetting.UnknownValue": "(leave blank to view what to put here)", "CommandArgs.Rename.Name": "Your new name", @@ -4079,7 +4080,7 @@ "GuessBackstabber": "You cannot guess a revealed Backstabber.", "Curser": "Curser", "CurserInfo": "Make Others' Life Worse", - "CurserInfoLong": "(Neutrals):\\nAs the Curser, when you use your kill button on someone, they will get one of the following:\\n- -1 ability use\\n- +1 harmful add-on\\n- permanent low vision\\n- permanent low speed\\nYou win if crewmates lose.", + "CurserInfoLong": "(Neutrals):\\nAs the Curser, when you use your kill button on someone, you can single click on them to reveal their alignment, and double click to give them one of the following effects:\\n- -1 ability use\\n- +1 harmful add-on\\n- permanent low vision\\n- permanent low speed\\nYou win if crewmates lose.", "Curser.LowerVision": "Permanent Lower Vision", "Curser.LowerSpeed": "Permanent Lower Speed", "Curser.Notify.0": "You've removed an ability use from your target", diff --git a/Roles/Crewmate/President.cs b/Roles/Crewmate/President.cs index 0f8549c22..35e0d43ed 100644 --- a/Roles/Crewmate/President.cs +++ b/Roles/Crewmate/President.cs @@ -81,7 +81,7 @@ public class President : RoleBase break; case Decree.GovernmentRecruiting: DecreeSettings[decree].Add(new StringOptionItem(++id, "President.GovernmentRecruiting.RecruitedRole", GovernmentRecruitRoles.Select(x => x.ToColoredString()).ToArray(), 0, tab, noTranslation: true) - .SetParent(DecreeSettings[decree][0])); + .SetParent(DecreeSettings[decree][0])); break; } @@ -233,9 +233,10 @@ public class President : RoleBase } CustomRoles role = GovernmentRecruitRoles[DecreeSettings[Decree.GovernmentRecruiting][1].GetValue()]; - if (role.IsDesyncRole() && target.GetRoleTypes() != role.GetDYRole()) role = CustomRoles.NiceGuesser; target.RpcSetCustomRole(role); + target.RpcChangeRoleBasis(role); + Utils.SendMessage("\n", target.PlayerId, Translator.GetString("President.Recruit.TargetNotifyMessage")); Main.DontCancelVoteList.Add(voter.PlayerId); return true; diff --git a/Roles/Neutral/Curser.cs b/Roles/Neutral/Curser.cs index bd870f718..ac75ec761 100644 --- a/Roles/Neutral/Curser.cs +++ b/Roles/Neutral/Curser.cs @@ -73,10 +73,10 @@ public class Curser : RoleBase public override bool OnCheckMurder(PlayerControl killer, PlayerControl target) { if (killer.CheckDoubleTrigger(target, () => - { - KnownFactionPlayers.Add(target.PlayerId); - Utils.NotifyRoles(SpecifySeer: killer, SpecifyTarget: target); - })) + { + KnownFactionPlayers.Add(target.PlayerId); + Utils.NotifyRoles(SpecifySeer: killer, SpecifyTarget: target); + })) { int random = IRandom.Instance.Next(4); @@ -86,7 +86,7 @@ public class Curser : RoleBase target.RpcRemoveAbilityUse(); break; case 1: - var addons = Options.GroupedAddons[AddonTypes.Harmful].Where(x => !target.Is(x) && CustomRolesHelper.CheckAddonConflict(x, target)); + var addons = Options.GroupedAddons[AddonTypes.Harmful].Where(x => !target.Is(x) && !x.IsNotAssignableMidGame() && CustomRolesHelper.CheckAddonConflict(x, target)); target.RpcSetCustomRole(addons.RandomElement()); break; case 2: @@ -118,10 +118,7 @@ public class Curser : RoleBase opt.SetFloat(FloatOptionNames.ImpostorLightMod, vision); } - if (instance.LowerSpeedPlayers.Contains(playerId)) - { - Main.AllPlayerSpeed[playerId] = LowerSpeed.GetFloat(); - } + if (instance.LowerSpeedPlayers.Contains(playerId)) { Main.AllPlayerSpeed[playerId] = LowerSpeed.GetFloat(); } } }