From 0458786cb521d6ccbb30b1e5ddb3890ade8c2dc5 Mon Sep 17 00:00:00 2001 From: mxyx0412 Date: Sat, 4 Jan 2025 06:28:44 +0800 Subject: [PATCH] Update v1.2.0.0 --- .editorconfig | 6 +- .github/workflows/build.yml | 4 +- Strings.xlsx | Bin 85431 -> 85915 bytes TheOtherRoles.sln | 3 - TheOtherRoles/Buttons/Buttons.cs | 31 +- TheOtherRoles/CustomCosmetics/CustomColors.cs | 33 + .../CustomHats/Patches/HatParentPatche.cs | 236 --- .../CustomHats/Patches/HatParentPatches.cs | 4 +- .../CustomHats/Patches/HatsTabPatches.cs | 13 +- .../CustomGameModes/GameModePatches.cs | 61 + TheOtherRoles/Helper/Helpers.cs | 59 +- TheOtherRoles/Main.cs | 10 +- TheOtherRoles/Modules/ChatCommands.cs | 4 +- TheOtherRoles/Modules/CrowdedPlayer.cs | 18 +- TheOtherRoles/Modules/KeyboardHandler.cs | 6 +- TheOtherRoles/Objects/Footprint.cs | 2 +- .../CreateModOptions.cs} | 113 +- TheOtherRoles/Options/CustomOptions.cs | 1411 +++++++++-------- TheOtherRoles/Options/ModOption.cs | 6 +- TheOtherRoles/Patches/CredentialsPatch.cs | 48 +- TheOtherRoles/Patches/EndGamePatch.cs | 224 ++- TheOtherRoles/Patches/ExileControllerPatch.cs | 42 +- .../Patches/GameStartManagerPatch.cs | 61 +- TheOtherRoles/Patches/GetStringPatch.cs | 24 + TheOtherRoles/Patches/LobbyBehaviourPatch.cs | 27 + TheOtherRoles/Patches/LobbyRoleList.cs | 20 +- TheOtherRoles/Patches/MeetingHudPatch.cs | 10 +- TheOtherRoles/Patches/PlayerControlPatch.cs | 2 +- TheOtherRoles/Patches/RoleAssignmentPatch.cs | 22 +- TheOtherRoles/Patches/ShipStatusPatch.cs | 2 +- .../Patches/TransportationToolPatches.cs | 6 +- TheOtherRoles/Patches/UsablesPatch.cs | 4 +- TheOtherRoles/RPC.cs | 15 +- TheOtherRoles/Resources/Copy.png | Bin 0 -> 17161 bytes TheOtherRoles/Resources/CopyActive.png | Bin 0 -> 14765 bytes TheOtherRoles/Resources/CopyPasteBG.png | Bin 0 -> 13064 bytes TheOtherRoles/Resources/Minus_Button.png | Bin 0 -> 6295 bytes .../Resources/Minus_ButtonActive.png | Bin 0 -> 6897 bytes TheOtherRoles/Resources/Paste.png | Bin 0 -> 14822 bytes TheOtherRoles/Resources/PasteActive.png | Bin 0 -> 14227 bytes TheOtherRoles/Resources/Plus_Button.png | Bin 0 -> 7047 bytes TheOtherRoles/Resources/Plus_ButtonActive.png | Bin 0 -> 7541 bytes TheOtherRoles/Resources/Settings_Button.png | Bin 0 -> 13493 bytes .../Resources/Settings_ButtonActive.png | Bin 0 -> 13826 bytes TheOtherRoles/Resources/stringData.json | 34 +- TheOtherRoles/Roles/Crewmate/Prosecutor.cs | 6 +- TheOtherRoles/TasksHandler.cs | 4 +- TheOtherRoles/TheOtherRoles.csproj | 15 +- TheOtherRoles/Utilities/CachedPlayer.cs | 6 +- TheOtherRoles/packages.lock.json | 135 +- 50 files changed, 1385 insertions(+), 1342 deletions(-) delete mode 100644 TheOtherRoles/CustomCosmetics/CustomHats/Patches/HatParentPatche.cs create mode 100644 TheOtherRoles/CustomGameModes/GameModePatches.cs rename TheOtherRoles/{Patches/ClientOptionsPatch.cs => Options/CreateModOptions.cs} (74%) create mode 100644 TheOtherRoles/Patches/GetStringPatch.cs create mode 100644 TheOtherRoles/Patches/LobbyBehaviourPatch.cs create mode 100644 TheOtherRoles/Resources/Copy.png create mode 100644 TheOtherRoles/Resources/CopyActive.png create mode 100644 TheOtherRoles/Resources/CopyPasteBG.png create mode 100644 TheOtherRoles/Resources/Minus_Button.png create mode 100644 TheOtherRoles/Resources/Minus_ButtonActive.png create mode 100644 TheOtherRoles/Resources/Paste.png create mode 100644 TheOtherRoles/Resources/PasteActive.png create mode 100644 TheOtherRoles/Resources/Plus_Button.png create mode 100644 TheOtherRoles/Resources/Plus_ButtonActive.png create mode 100644 TheOtherRoles/Resources/Settings_Button.png create mode 100644 TheOtherRoles/Resources/Settings_ButtonActive.png diff --git a/.editorconfig b/.editorconfig index 8d356572..35b791f3 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,10 +1,12 @@ [*.cs] +charset = utf-8 dotnet_diagnostic.IDE0007.severity = silent dotnet_diagnostic.IDE0022.severity = silent dotnet_diagnostic.IDE0023.severity = silent dotnet_diagnostic.IDE0028.severity = none dotnet_diagnostic.IDE0031.severity = silent dotnet_diagnostic.IDE0046.severity = silent +dotnet_diagnostic.IDE0058.severity = silent dotnet_diagnostic.IDE0061.severity = silent dotnet_diagnostic.IDE0305.severity = silent dotnet_diagnostic.IDE1006.severity = silent @@ -16,10 +18,6 @@ dotnet_analyzer_diagnostic.severity = suggestion [*.cs] #### 命名样式 #### - -# IDE0058: -dotnet_diagnostic.IDE0058.severity = silent - # 命名规则 dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index dac487e3..e8a81c16 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -37,7 +37,7 @@ jobs: - name: Download and Unzip BepInEx run: | - wget https://builds.bepinex.dev/projects/bepinex_be/697/BepInEx-Unity.IL2CPP-win-x86-6.0.0-be.697%2B5362580.zip -O BepInEx.zip + wget https://builds.bepinex.dev/projects/bepinex_be/725/BepInEx-Unity.IL2CPP-win-x86-6.0.0-be.725%2Be1974e2.zip -O BepInEx.zip unzip BepInEx.zip -d ./Release/ sudo chmod -R 777 ./Release @@ -47,7 +47,7 @@ jobs: unzip ExtraData.zip -d ./Release/ - name: Download Reactor - run: wget https://github.com/NuclearPowered/Reactor/releases/download/2.2.0/Reactor.dll -P ./Release/BepInEx/plugins + run: wget https://github.com/NuclearPowered/Reactor/releases/download/2.3.1/Reactor.dll -P ./Release/BepInEx/plugins - name: Set Build Configuration id: set-config diff --git a/Strings.xlsx b/Strings.xlsx index 3857c3a07489c4d6ea11b30ad5b6ca0bc87d3668..e5e297df6cb016907a69b6ca9ea508b430f2b608 100644 GIT binary patch delta 61455 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

2nC2Gg* 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 delta 61013 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 diff --git a/TheOtherRoles.sln b/TheOtherRoles.sln index 9d1b0064..d9e20ca6 100644 --- a/TheOtherRoles.sln +++ b/TheOtherRoles.sln @@ -18,7 +18,6 @@ Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Beta|Any CPU = Beta|Any CPU Debug|Any CPU = Debug|Any CPU - mxyx-club|Any CPU = mxyx-club|Any CPU Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution @@ -26,8 +25,6 @@ Global {11FBC798-BAF5-4EE5-9511-BE6DB0592F99}.Beta|Any CPU.Build.0 = Beta|Any CPU {11FBC798-BAF5-4EE5-9511-BE6DB0592F99}.Debug|Any CPU.ActiveCfg = Release|Any CPU {11FBC798-BAF5-4EE5-9511-BE6DB0592F99}.Debug|Any CPU.Build.0 = Release|Any CPU - {11FBC798-BAF5-4EE5-9511-BE6DB0592F99}.mxyx-club|Any CPU.ActiveCfg = mxyx-club|Any CPU - {11FBC798-BAF5-4EE5-9511-BE6DB0592F99}.mxyx-club|Any CPU.Build.0 = mxyx-club|Any CPU {11FBC798-BAF5-4EE5-9511-BE6DB0592F99}.Release|Any CPU.ActiveCfg = Release|Any CPU {11FBC798-BAF5-4EE5-9511-BE6DB0592F99}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection diff --git a/TheOtherRoles/Buttons/Buttons.cs b/TheOtherRoles/Buttons/Buttons.cs index 1b183796..5166264a 100644 --- a/TheOtherRoles/Buttons/Buttons.cs +++ b/TheOtherRoles/Buttons/Buttons.cs @@ -97,7 +97,6 @@ internal static class HudManagerStartPatch public static CustomButton terroristButton; public static CustomButton defuseButton; public static CustomButton zoomOutButton; - public static CustomButton roleSummaryButton; public static Dictionary> deputyHandcuffedButtons; public static PoolablePlayer targetDisplay; @@ -390,34 +389,6 @@ public static void createButtonsPostfix(HudManager __instance) // get map id, or raise error to wait... var mapId = GameOptionsManager.Instance.currentNormalGameOptions.MapId; - roleSummaryButton = new CustomButton( - () => - { - if (LobbyRoleInfo.RolesSummaryUI == null) - LobbyRoleInfo.RoleSummaryOnClick(); - else - { - Object.Destroy(LobbyRoleInfo.RolesSummaryUI); - LobbyRoleInfo.RolesSummaryUI = null; - } - }, - () => { return PlayerControl.LocalPlayer != null && LobbyBehaviour.Instance; }, - () => - { - if (PlayerCustomizationMenu.Instance || GameSettingMenu.Instance) - { - if (LobbyRoleInfo.RolesSummaryUI != null) - Object.Destroy(LobbyRoleInfo.RolesSummaryUI); - } - return true; - }, - () => { }, - new ResourceSprite("TheOtherRoles.Resources.HelpButton.png", 85f), - new Vector3(0.4f, 3f, 0), - __instance, - null - ); - zoomOutButton = new CustomButton( () => { toggleZoom(); }, () => @@ -430,7 +401,7 @@ public static void createButtonsPostfix(HudManager __instance) }, () => { return true; }, () => { }, - UnityHelper.loadSpriteFromResources("TheOtherRoles.Resources.ZoomOut.png", 85f), // Invisible button! + null, new Vector3(0.4f, 2.35f, 0f), __instance, KeyCode.KeypadPlus diff --git a/TheOtherRoles/CustomCosmetics/CustomColors.cs b/TheOtherRoles/CustomCosmetics/CustomColors.cs index a2049075..66be546f 100644 --- a/TheOtherRoles/CustomCosmetics/CustomColors.cs +++ b/TheOtherRoles/CustomCosmetics/CustomColors.cs @@ -147,6 +147,39 @@ public static bool Prefix(ref string __result, [HarmonyArgument(0)] StringNames } } + [HarmonyPatch(typeof(ChatNotification), nameof(ChatNotification.SetUp))] + private class ChatNotificationColorsPatch + { + public static bool Prefix(ChatNotification __instance, PlayerControl sender, string text) + { + if (ShipStatus.Instance && !ModOption.ShowChatNotifications) + { + return false; + } + __instance.timeOnScreen = 5f; + __instance.gameObject.SetActive(true); + __instance.SetCosmetics(sender.Data); + string str; + Color color; + try + { + str = ColorUtility.ToHtmlStringRGB(Palette.TextColors[__instance.player.ColorId]); + color = Palette.TextOutlineColors[__instance.player.ColorId]; + } + catch + { + Color32 c = Palette.PlayerColors[__instance.player.ColorId]; + str = ColorUtility.ToHtmlStringRGB(c); + color = c.r + c.g + c.b > 180 ? Palette.Black : Palette.White; + Message($"{c.r}, {c.g}, {c.b}"); + } + __instance.playerColorText.text = __instance.player.ColorBlindName; + __instance.playerNameText.text = "" + (string.IsNullOrEmpty(sender.Data.PlayerName) ? "..." : sender.Data.PlayerName); + __instance.playerNameText.outlineColor = color; + __instance.chatText.text = text; + return false; + } + } [HarmonyPatch(typeof(PlayerTab), nameof(PlayerTab.OnEnable))] private static class PlayerTabEnablePatch { diff --git a/TheOtherRoles/CustomCosmetics/CustomHats/Patches/HatParentPatche.cs b/TheOtherRoles/CustomCosmetics/CustomHats/Patches/HatParentPatche.cs deleted file mode 100644 index 1de05f3f..00000000 --- a/TheOtherRoles/CustomCosmetics/CustomHats/Patches/HatParentPatche.cs +++ /dev/null @@ -1,236 +0,0 @@ -#if MXYX_CLUB -using System; -using System.IO; -using System.Linq; -using PowerTools; -using UnityEngine; - -namespace TheOtherRoles.CustomCosmetics.CustomHats.Patches; - -[HarmonyPatch(typeof(HatParent))] -internal static class HatParentPatches -{ - [HarmonyPatch(nameof(HatParent.SetHat), typeof(int))] - [HarmonyPriority(Priority.High)] - [HarmonyPrefix] - private static void SetHatPrefix(HatParent __instance) - { - SetCustomHat(__instance); - } - - [HarmonyPatch(nameof(HatParent.SetHat), typeof(HatData), typeof(int))] - [HarmonyPrefix] - private static bool SetHatPrefix(HatParent __instance, HatData hat, int color) - { - if (SetCustomHat(__instance)) return true; - __instance.PopulateFromHatViewData(); - __instance.SetMaterialColor(color); - return false; - } - - [HarmonyPatch(nameof(HatParent.SetHat), typeof(int))] - [HarmonyPrefix] - private static bool SetHatPrefix(HatParent __instance, int color) - { - if (!__instance.IsCached()) return true; - __instance.hatDataAsset = null; - __instance.PopulateFromHatViewData(); - __instance.SetMaterialColor(color); - return false; - } - - [HarmonyPatch(nameof(HatParent.UpdateMaterial))] - [HarmonyPrefix] - private static bool UpdateMaterialPrefix(HatParent __instance) - { - if (!__instance.TryGetCached(out var asset)) return true; - if (asset && asset.AltShader) - { - __instance.FrontLayer.sharedMaterial = asset.AltShader; - if (__instance.BackLayer) __instance.BackLayer.sharedMaterial = asset.AltShader; - } - else - { - __instance.FrontLayer.sharedMaterial = DestroyableSingleton.Instance.DefaultShader; - if (__instance.BackLayer) - __instance.BackLayer.sharedMaterial = DestroyableSingleton.Instance.DefaultShader; - } - - var colorId = __instance.matProperties.ColorId; - PlayerMaterial.SetColors(colorId, __instance.FrontLayer); - if (__instance.BackLayer) PlayerMaterial.SetColors(colorId, __instance.BackLayer); - - __instance.FrontLayer.material.SetInt(PlayerMaterial.MaskLayer, __instance.matProperties.MaskLayer); - if (__instance.BackLayer) - __instance.BackLayer.material.SetInt(PlayerMaterial.MaskLayer, __instance.matProperties.MaskLayer); - - var maskType = __instance.matProperties.MaskType; - switch (maskType) - { - case PlayerMaterial.MaskType.ScrollingUI: - if (__instance.FrontLayer) - __instance.FrontLayer.maskInteraction = SpriteMaskInteraction.VisibleInsideMask; - - if (__instance.BackLayer) - __instance.BackLayer.maskInteraction = SpriteMaskInteraction.VisibleInsideMask; - - break; - case PlayerMaterial.MaskType.Exile: - if (__instance.FrontLayer) - __instance.FrontLayer.maskInteraction = SpriteMaskInteraction.VisibleOutsideMask; - - if (__instance.BackLayer) - __instance.BackLayer.maskInteraction = SpriteMaskInteraction.VisibleOutsideMask; - - break; - default: - if (__instance.FrontLayer) __instance.FrontLayer.maskInteraction = SpriteMaskInteraction.None; - - if (__instance.BackLayer) __instance.BackLayer.maskInteraction = SpriteMaskInteraction.None; - - break; - } - if (__instance.matProperties.MaskLayer > 0) return false; - PlayerMaterial.SetMaskLayerBasedOnLocalPlayer(__instance.FrontLayer, __instance.matProperties.IsLocalPlayer); - if (!__instance.BackLayer) return false; - PlayerMaterial.SetMaskLayerBasedOnLocalPlayer(__instance.BackLayer, __instance.matProperties.IsLocalPlayer); - return false; - } - - [HarmonyPatch(nameof(HatParent.LateUpdate))] - [HarmonyPrefix] - private static bool LateUpdatePrefix(HatParent __instance) - { - if (!__instance.Parent || !__instance.Hat) return false; - if (!__instance.TryGetCached(out var hatViewData)) return true; - if (__instance.FrontLayer.sprite != hatViewData.ClimbImage && - __instance.FrontLayer.sprite != hatViewData.FloorImage) - { - if ((__instance.Hat.InFront || hatViewData.BackImage) && hatViewData.LeftMainImage) - __instance.FrontLayer.sprite = - __instance.Parent.flipX ? hatViewData.LeftMainImage : hatViewData.MainImage; - - if (hatViewData.BackImage && hatViewData.LeftBackImage) - { - __instance.BackLayer.sprite = - __instance.Parent.flipX ? hatViewData.LeftBackImage : hatViewData.BackImage; - return false; - } - - if (!hatViewData.BackImage && !__instance.Hat.InFront && hatViewData.LeftMainImage) - { - __instance.BackLayer.sprite = - __instance.Parent.flipX ? hatViewData.LeftMainImage : hatViewData.MainImage; - return false; - } - } - else if (__instance.FrontLayer.sprite == hatViewData.ClimbImage || - __instance.FrontLayer.sprite == hatViewData.LeftClimbImage) - { - var spriteAnimNodeSync = __instance.SpriteSyncNode != null - ? __instance.SpriteSyncNode - : __instance.GetComponent(); - if (spriteAnimNodeSync) spriteAnimNodeSync.NodeId = 0; - } - - return false; - } - - [HarmonyPatch(nameof(HatParent.SetFloorAnim))] - [HarmonyPrefix] - private static bool SetFloorAnimPrefix(HatParent __instance) - { - if (!__instance.TryGetCached(out var hatViewData)) return true; - __instance.BackLayer.enabled = false; - __instance.FrontLayer.enabled = true; - __instance.FrontLayer.sprite = hatViewData.FloorImage; - return false; - } - - [HarmonyPatch(nameof(HatParent.SetIdleAnim))] - [HarmonyPrefix] - private static bool SetIdleAnimPrefix(HatParent __instance, int colorId) - { - if (!__instance.Hat) return false; - if (!__instance.IsCached()) return true; - __instance.hatDataAsset = null; - __instance.PopulateFromHatViewData(); - __instance.SetMaterialColor(colorId); - return false; - } - - [HarmonyPatch(nameof(HatParent.SetClimbAnim))] - [HarmonyPrefix] - private static bool SetClimbAnimPrefix(HatParent __instance) - { - if (!__instance.TryGetCached(out var hatViewData)) return true; - if (!__instance.options.ShowForClimb) return false; - __instance.BackLayer.enabled = false; - __instance.FrontLayer.enabled = true; - __instance.FrontLayer.sprite = hatViewData.ClimbImage; - return false; - } - - [HarmonyPatch(nameof(HatParent.PopulateFromHatViewData))] - [HarmonyPrefix] - private static bool PopulateFromHatViewDataPrefix(HatParent __instance) - { - if (!__instance.TryGetCached(out var asset)) return true; - __instance.UpdateMaterial(); - - var spriteAnimNodeSync = __instance.SpriteSyncNode - ? __instance.SpriteSyncNode - : __instance.GetComponent(); - if (spriteAnimNodeSync) spriteAnimNodeSync.NodeId = __instance.Hat.NoBounce ? 1 : 0; - - if (__instance.Hat.InFront) - { - __instance.BackLayer.enabled = false; - __instance.FrontLayer.enabled = true; - __instance.FrontLayer.sprite = asset.MainImage; - } - else if (asset.BackImage) - { - __instance.BackLayer.enabled = true; - __instance.FrontLayer.enabled = true; - __instance.BackLayer.sprite = asset.BackImage; - __instance.FrontLayer.sprite = asset.MainImage; - } - else - { - __instance.BackLayer.enabled = true; - __instance.FrontLayer.enabled = false; - __instance.FrontLayer.sprite = null; - __instance.BackLayer.sprite = asset.MainImage; - } - - if (!__instance.options.Initialized || !__instance.HideHat()) return false; - __instance.FrontLayer.enabled = false; - __instance.BackLayer.enabled = false; - return false; - } - - private static bool SetCustomHat(HatParent hatParent) - { - var dirPath = Path.Combine(CosmeticsManager.CustomHatsDir, "Test"); - if (!Directory.Exists(dirPath)) Directory.CreateDirectory(dirPath); - if (!DestroyableSingleton.InstanceExists) return true; - var d = new DirectoryInfo(dirPath); - var filePaths = d.GetFiles("*.png").Select(x => x.FullName).ToArray(); - var hats = CustomHatManager.CreateHatDetailsFromFileNames(filePaths, true); - if (hats.Count <= 0) return false; - try - { - hatParent.Hat = CustomHatManager.CreateHatBehaviour(hats[0], true); - } - catch (Exception err) - { - Warn($"Unable to create test hat \n{err}"); - return true; - } - - return false; - } -} - -#endif \ No newline at end of file diff --git a/TheOtherRoles/CustomCosmetics/CustomHats/Patches/HatParentPatches.cs b/TheOtherRoles/CustomCosmetics/CustomHats/Patches/HatParentPatches.cs index c39c7d8a..88f61eb3 100644 --- a/TheOtherRoles/CustomCosmetics/CustomHats/Patches/HatParentPatches.cs +++ b/TheOtherRoles/CustomCosmetics/CustomHats/Patches/HatParentPatches.cs @@ -1,4 +1,4 @@ -#if !MXYX_CLUB +#if !MXYX_CLUB using System; using System.IO; using System.Linq; @@ -216,7 +216,7 @@ private static bool PopulateFromHatViewDataPrefix(HatParent __instance) __instance.BackLayer.sprite = asset.MainImage; } - if (!__instance.options.Initialized || !__instance.HideHat()) return false; + if (/*!__instance.options.Initialized ||*/ !__instance.HideHat()) return false; __instance.FrontLayer.enabled = false; __instance.BackLayer.enabled = false; return false; diff --git a/TheOtherRoles/CustomCosmetics/CustomHats/Patches/HatsTabPatches.cs b/TheOtherRoles/CustomCosmetics/CustomHats/Patches/HatsTabPatches.cs index 74e8328d..22a46c0f 100644 --- a/TheOtherRoles/CustomCosmetics/CustomHats/Patches/HatsTabPatches.cs +++ b/TheOtherRoles/CustomCosmetics/CustomHats/Patches/HatsTabPatches.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using AmongUs.Data; @@ -8,14 +8,14 @@ namespace TheOtherRoles.CustomCosmetics.CustomHats.Patches; -[HarmonyPatch(typeof(HatsTab))] +[HarmonyPatch] internal static class HatsTabPatches { private static TextMeshPro textTemplate; - [HarmonyPatch(nameof(HatsTab.OnEnable))] - [HarmonyPostfix] - private static void OnEnablePostfix(HatsTab __instance) + [HarmonyPatch(typeof(HatsTab), nameof(HatsTab.OnEnable))] + [HarmonyPrefix] + private static bool OnEnablePrefix(HatsTab __instance) { for (var i = 0; i < __instance.scroller.Inner.childCount; i++) { @@ -60,6 +60,7 @@ private static void OnEnablePostfix(HatsTab __instance) } __instance.scroller.ContentYBounds.max = -(yOffset + 4.1f); + return false; } private static float CreateHatPackage(List> hats, string packageName, float yStart, @@ -99,7 +100,7 @@ private static float CreateHatPackage(List> hats, s colorChip.Button.OnClick.AddListener((Action)(() => hatsTab.SelectHat(hat))); } colorChip.Button.ClickMask = hatsTab.scroller.Hitbox; - colorChip.Inner.SetMaskType(PlayerMaterial.MaskType.ScrollingUI); + colorChip.Inner.SetMaskType(PlayerMaterial.MaskType.SimpleUI); hatsTab.UpdateMaterials(colorChip.Inner.FrontLayer, hat); var background = colorChip.transform.FindChild("Background"); var foreground = colorChip.transform.FindChild("ForeGround"); diff --git a/TheOtherRoles/CustomGameModes/GameModePatches.cs b/TheOtherRoles/CustomGameModes/GameModePatches.cs new file mode 100644 index 00000000..de8d063d --- /dev/null +++ b/TheOtherRoles/CustomGameModes/GameModePatches.cs @@ -0,0 +1,61 @@ +using System; +using Hazel; +using TheOtherRoles.Utilities; +using TMPro; +using UnityEngine; +using UnityEngine.Events; +using static UnityEngine.UI.Button; + +namespace TheOtherRoles.CustomGameModes; + +[HarmonyPatch] +internal class GameModePatches +{ + /* + Creates a button in the info pane in the lobby to cycle through the game modes of TOR. + */ + [HarmonyPatch(typeof(LobbyInfoPane), nameof(LobbyInfoPane.Update))] + private class LobbyInfoPanePatch + { + private static GameObject gameModeButton; + public static void Postfix(LobbyInfoPane __instance) + { + if (gameModeButton != null || !AmongUsClient.Instance.AmHost) { return; } + var template = GameObject.Find("PRIVATE BUTTON"); + var GameModeText = GameObject.Find("GameModeText"); + if (template == null || GameModeText == null) { return; } + gameModeButton = UnityEngine.Object.Instantiate(template, template.transform.parent); //, GameModeText.transform); + gameModeButton.transform.localPosition = template.transform.localPosition + new Vector3(0f, 0.65f, -2f); + gameModeButton.name = "TOR GameModeButton"; + var pButton = gameModeButton.GetComponent(); + pButton.buttonText.text = GameModeText.GetComponent().text; + pButton.OnClick.RemoveAllListeners(); + pButton.OnClick = new ButtonClickedEvent(); + __instance.StartCoroutine(Effects.Lerp(0.1f, new Action(p => { pButton.buttonText.text = cs(Color.yellow, GameModeText.GetComponent().text); }))); + gameModeButton.transform.GetChild(1).GetComponent().color = new Color(0.1f, 0.1f, 0.1f); + gameModeButton.transform.GetChild(2).GetComponent().color = new Color(0f, 0f, 0f); + pButton.OnClick.AddListener((Action)(() => + { + ModOption.gameMode = (CustomGamemodes)((int)(ModOption.gameMode + 1) % Enum.GetNames(typeof(CustomGamemodes)).Length); + __instance.StartCoroutine(Effects.Lerp(0.1f, new Action(p => { pButton.buttonText.text = cs(Color.yellow, GameModeText.GetComponent().text); }))); + MessageWriter writer = AmongUsClient.Instance.StartRpcImmediately(CachedPlayer.LocalPlayer.PlayerControl.NetId, + (byte)CustomRPC.ShareGameMode, SendOption.Reliable, -1); + writer.Write((byte)ModOption.gameMode); + AmongUsClient.Instance.FinishRpcImmediately(writer); + RPCProcedure.shareGameMode((byte)ModOption.gameMode); + })); + pButton.OnMouseOut = new UnityEvent(); + pButton.OnMouseOver = new UnityEvent(); + pButton.OnMouseOver.AddListener((Action)(() => + { + gameModeButton.transform.GetChild(1).gameObject.SetActive(true); + gameModeButton.transform.GetChild(2).gameObject.SetActive(false); + })); + pButton.OnMouseOut.AddListener((Action)(() => + { + gameModeButton.transform.GetChild(1).gameObject.SetActive(false); + gameModeButton.transform.GetChild(2).gameObject.SetActive(true); + })); + } + } +} diff --git a/TheOtherRoles/Helper/Helpers.cs b/TheOtherRoles/Helper/Helpers.cs index 95acdf3f..3ea2aa67 100644 --- a/TheOtherRoles/Helper/Helpers.cs +++ b/TheOtherRoles/Helper/Helpers.cs @@ -123,7 +123,7 @@ public static bool killingCrewAlive() ///

/// 红狼视野 /// - public static bool hasImpVision(GameData.PlayerInfo player) + public static bool hasImpVision(NetworkedPlayerInfo player) { return player.Role.IsImpostor || (Jackal.jackal.Any(p => p.PlayerId == player.PlayerId) && Jackal.hasImpostorVision) @@ -297,7 +297,7 @@ public static string teamString(PlayerControl player) !MeetingHud.Instance && !ExileController.Instance; - public static void NoCheckStartMeeting(this PlayerControl reporter, GameData.PlayerInfo target, bool force = false) + public static void NoCheckStartMeeting(this PlayerControl reporter, NetworkedPlayerInfo target, bool force = false) { if (InMeeting) return; @@ -598,6 +598,45 @@ public static bool Contains(this IEnumerable list, T item, Func keySelector(x).Equals(keySelector(item))); } + public static int Count(this Il2CppSystem.Collections.Generic.List list, Func func = null) + { + int count = 0; + foreach (T obj in list) + if (func == null || func(obj)) + count++; + return count; + } + + public static Color HexToColor(string hex) + { + ColorUtility.TryParseHtmlString("#" + hex, out var color); + return color; + } + + public static void AddModSettingsChangeMessage(this NotificationPopper popper, StringNames key, string value, string option, bool playSound = true) + { + string str = DestroyableSingleton.Instance.GetString(StringNames.LobbyChangeSettingNotification, "" + option + "", "" + value + ""); + popper.SettingsChangeMessageLogic(key, str, playSound); + } + + public static ExileController.InitProperties GenerateExileInitProperties(NetworkedPlayerInfo player, bool voteTie) + { + ExileController.InitProperties initProperties = new(); + if (player != null) + { + initProperties.outfit = player.Outfits[PlayerOutfitType.Default]; + initProperties.networkedPlayer = player; + initProperties.isImpostor = player.Role.IsImpostor; + } + initProperties.voteTie = voteTie; + initProperties.confirmImpostor = GameManager.Instance.LogicOptions.GetConfirmImpostor(); + initProperties.totalImpostorCount = GameData.Instance.AllPlayers.Count((NetworkedPlayerInfo p) => p.Role.IsImpostor); + initProperties.remainingImpostorCount = GameData.Instance.AllPlayers.Count((NetworkedPlayerInfo p) => p.Role.IsImpostor && !p.IsDead && !p.Disconnected); + if (player != null && player.Role.IsImpostor && !player.Disconnected) + initProperties.remainingImpostorCount--; + return initProperties; + } + public static string readTextFromResources(string path) { var assembly = Assembly.GetExecutingAssembly(); @@ -1056,10 +1095,10 @@ public static Il2CppSystem.Collections.Generic.List GetClosestPla { Il2CppSystem.Collections.Generic.List playerControlList = new Il2CppSystem.Collections.Generic.List(); float lightRadius = radius * ShipStatus.Instance.MaxLightRadius; - Il2CppSystem.Collections.Generic.List allPlayers = GameData.Instance.AllPlayers; + Il2CppSystem.Collections.Generic.List allPlayers = GameData.Instance.AllPlayers; for (int index = 0; index < allPlayers.Count; ++index) { - GameData.PlayerInfo playerInfo = allPlayers[index]; + NetworkedPlayerInfo playerInfo = allPlayers[index]; if (!playerInfo.Disconnected && (!playerInfo.Object.Data.IsDead || includeDead)) { Vector2 vector2 = new Vector2(playerInfo.Object.GetTruePosition().x - truePosition.x, playerInfo.Object.GetTruePosition().y - truePosition.y); @@ -1343,12 +1382,14 @@ public static void toggleZoom(bool reset = false) cam.orthographicSize = orthographicSize; // The UI is scaled too, else we cant click the buttons. Downside: map is super small. - if (HudManagerStartPatch.zoomOutButton != null) + var tzGO = GameObject.Find("TOGGLEZOOMBUTTON"); + if (tzGO != null) { - HudManagerStartPatch.zoomOutButton.Sprite = zoomOutStatus - ? new ResourceSprite("TheOtherRoles.Resources.ZoomIn.png", 21f) - : new ResourceSprite("TheOtherRoles.Resources.ZoomOut.png", 85f); - HudManagerStartPatch.zoomOutButton.PositionOffset = zoomOutStatus ? new Vector3(-0.82f, 11.5f, 0) : new(0.4f, 2.35f, 0f); + var rend = tzGO.transform.Find("Inactive").GetComponent(); + var rendActive = tzGO.transform.Find("Active").GetComponent(); + rend.sprite = zoomOutStatus ? UnityHelper.loadSpriteFromResources("TheOtherRoles.Resources.Plus_Button.png", 100f) : UnityHelper.loadSpriteFromResources("TheOtherRoles.Resources.Minus_Button.png", 100f); + rendActive.sprite = zoomOutStatus ? UnityHelper.loadSpriteFromResources("TheOtherRoles.Resources.Plus_ButtonActive.png", 100f) : UnityHelper.loadSpriteFromResources("TheOtherRoles.Resources.Minus_ButtonActive.png", 100f); + tzGO.transform.localScale = new Vector3(1.2f, 1.2f, 1f) * (zoomOutStatus ? 4 : 1); } // This will move button positions to the correct position. diff --git a/TheOtherRoles/Main.cs b/TheOtherRoles/Main.cs index cb311612..1561e27a 100644 --- a/TheOtherRoles/Main.cs +++ b/TheOtherRoles/Main.cs @@ -1,4 +1,4 @@ -using System; +using System; using AmongUs.Data; using BepInEx; using BepInEx.Configuration; @@ -35,6 +35,9 @@ public class TheOtherRolesPlugin : BasePlugin public static ConfigEntry ToggleCursor { get; set; } public static ConfigEntry ShowFPS { get; set; } public static ConfigEntry LocalHats { get; set; } + public static ConfigEntry MuteLobbyBGM { get; set; } + public static ConfigEntry ShowChatNotifications { get; set; } + public static ConfigEntry ForceUsePlus25Protocol { get; set; } public static ConfigEntry ShowKeyReminder { get; set; } public static ConfigEntry Ip { get; set; } public static ConfigEntry Port { get; set; } @@ -84,12 +87,17 @@ public override void Load() ShowFPS = Config.Bind("Custom", "Show FPS", true); ShowKeyReminder = Config.Bind("Custom", "ShowKeyReminder", true); LocalHats = Config.Bind("Custom", "Load Local Hats", false); + MuteLobbyBGM = Config.Bind("Custom", "Mute Lobby BGM", true); + ShowChatNotifications = Config.Bind("Custom", "Show Chat Notifications", true); + ForceUsePlus25Protocol = Config.Bind("Custom", "Force Use Plus 25 Protocol", false); Ip = Config.Bind("Custom", "Custom Server IP", "127.0.0.1"); Port = Config.Bind("Custom", "Custom Server Port", (ushort)22023); defaultRegions = ServerManager.DefaultRegions; UpdateRegions(); + // Removes vanilla Servers + ServerManager.DefaultRegions = new Il2CppReferenceArray(new IRegionInfo[0]); CrowdedPlayer.Start(); Harmony.PatchAll(); ModOption.reloadPluginOptions(); diff --git a/TheOtherRoles/Modules/ChatCommands.cs b/TheOtherRoles/Modules/ChatCommands.cs index f86b7851..88285494 100644 --- a/TheOtherRoles/Modules/ChatCommands.cs +++ b/TheOtherRoles/Modules/ChatCommands.cs @@ -260,8 +260,8 @@ public static void Postfix(ChatBubble __instance, [HarmonyArgument(0)] string pl var sourcePlayer = PlayerControl.AllPlayerControls.ToList() .FirstOrDefault(x => x.Data != null && x.Data.PlayerName.Equals(playerName, StringComparison.Ordinal)); - if (CachedPlayer.LocalPlayer != null && CachedPlayer.LocalPlayer.Data.Role.IsImpostor && __instance != null - && (Spy.spy != null && sourcePlayer.PlayerId == Spy.spy.PlayerId)) + if (sourcePlayer != null && CachedPlayer.LocalPlayer != null && CachedPlayer.LocalPlayer.Data?.Role?.IsImpostor == true + && Spy.spy != null && sourcePlayer.PlayerId == Spy.spy.PlayerId) { __instance.NameText.color = Palette.ImpostorRed; } diff --git a/TheOtherRoles/Modules/CrowdedPlayer.cs b/TheOtherRoles/Modules/CrowdedPlayer.cs index cf400040..188c3956 100644 --- a/TheOtherRoles/Modules/CrowdedPlayer.cs +++ b/TheOtherRoles/Modules/CrowdedPlayer.cs @@ -6,7 +6,6 @@ using Reactor.Utilities.Extensions; using TMPro; using UnityEngine; -using Object = UnityEngine.Object; namespace TheOtherRoles.Modules; @@ -22,8 +21,8 @@ public static class CrowdedPlayer public static void Start() { if (!Enable) return; - NormalGameOptionsV07.RecommendedImpostors = NormalGameOptionsV07.MaxImpostors = Enumerable.Repeat(MaxPlayer, MaxPlayer).ToArray(); - NormalGameOptionsV07.MinPlayers = Enumerable.Repeat(4, MaxPlayer).ToArray(); + NormalGameOptionsV08.RecommendedImpostors = NormalGameOptionsV08.MaxImpostors = Enumerable.Repeat(MaxPlayer, MaxPlayer).ToArray(); + NormalGameOptionsV08.MinPlayers = Enumerable.Repeat(4, MaxPlayer).ToArray(); } [HarmonyPatch(typeof(SecurityLogger), nameof(SecurityLogger.Awake))] @@ -34,13 +33,18 @@ public static void SecurityLoggerPatch_Postfix(ref SecurityLogger __instance) __instance.Timers = new float[MaxPlayer]; } - [HarmonyPatch(typeof(GameOptionsMenu), nameof(GameOptionsMenu.Start))] + [HarmonyPatch(typeof(GameOptionsMenu), nameof(GameOptionsMenu.Initialize))] [HarmonyPostfix] - public static void GameOptionsMenu_Start_Postfix(ref GameOptionsMenu __instance) + public static void GameOptionsMenu_Initialize_Postfix(GameOptionsMenu __instance) { if (!Enable) return; - var options = Object.FindObjectsOfType().FirstOrDefault(o => o.Title == StringNames.GameNumImpostors); - if (options != null) options.ValidRange = new FloatRange(0, MaxImpostor); + var numberOptions = __instance.GetComponentsInChildren(); + + var impostorsOption = numberOptions.FirstOrDefault(o => o.Title == StringNames.GameNumImpostors); + if (impostorsOption != null) + { + impostorsOption.ValidRange = new FloatRange(0, MaxImpostor); + } } [HarmonyPatch(typeof(GameOptionsData), nameof(GameOptionsData.AreInvalid))] diff --git a/TheOtherRoles/Modules/KeyboardHandler.cs b/TheOtherRoles/Modules/KeyboardHandler.cs index f3657f3e..a78f1e4f 100644 --- a/TheOtherRoles/Modules/KeyboardHandler.cs +++ b/TheOtherRoles/Modules/KeyboardHandler.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using TheOtherRoles.Buttons; @@ -21,7 +21,7 @@ private static void Postfix(KeyboardJoystick __instance) if (AmongUsClient.Instance && (AmongUsClient.Instance.AmHost || ModOption.DebugMode)) { // 生成假人 - if (Input.GetKey(KeyCode.LeftControl) && Input.GetKey(KeyCode.F) && Input.GetKeyDown(KeyCode.Return) + /*if (Input.GetKey(KeyCode.LeftControl) && Input.GetKey(KeyCode.F) && Input.GetKeyDown(KeyCode.Return) && AmongUsClient.Instance.NetworkMode != NetworkModes.OnlineGame && InGame) { var playerControl = UnityEngine.Object.Instantiate(AmongUsClient.Instance.PlayerPrefab); @@ -37,7 +37,7 @@ private static void Postfix(KeyboardJoystick __instance) playerControl.SetName(RandomString(6)); playerControl.SetColor((byte)random.Next(Palette.PlayerColors.Length)); GameData.Instance.RpcSetTasks(playerControl.PlayerId, Array.Empty()); - } + }*/ // 强制开始会议或结束会议 if (Input.GetKey(ModInputManager.metaControlInput.keyCode) && Input.GetKeyDown(ModInputManager.meetingInput.keyCode) && InGame) { diff --git a/TheOtherRoles/Objects/Footprint.cs b/TheOtherRoles/Objects/Footprint.cs index 49efdca5..cd71a880 100644 --- a/TheOtherRoles/Objects/Footprint.cs +++ b/TheOtherRoles/Objects/Footprint.cs @@ -35,7 +35,7 @@ private class Footprint public Transform Transform; public SpriteRenderer Renderer; public PlayerControl Owner; - public GameData.PlayerInfo Data; + public NetworkedPlayerInfo Data; public float Lifetime; public Footprint() diff --git a/TheOtherRoles/Patches/ClientOptionsPatch.cs b/TheOtherRoles/Options/CreateModOptions.cs similarity index 74% rename from TheOtherRoles/Patches/ClientOptionsPatch.cs rename to TheOtherRoles/Options/CreateModOptions.cs index 96763efa..e7e92277 100644 --- a/TheOtherRoles/Patches/ClientOptionsPatch.cs +++ b/TheOtherRoles/Options/CreateModOptions.cs @@ -9,7 +9,7 @@ using static UnityEngine.UI.Button; using Object = UnityEngine.Object; -namespace TheOtherRoles.Patches; +namespace TheOtherRoles.Options; [HarmonyPatch(typeof(OptionsMenuBehaviour), nameof(OptionsMenuBehaviour.Start))] public static class StartOptionMenuPatch @@ -19,50 +19,42 @@ public static void UpdateCustomText(this ToggleButtonBehaviour button, Color col button.onState = false; button.Background.color = color; if (text != null) - { button.Text.text = text; - } if (button.Rollover) - { button.Rollover.ChangeOutColor(color); - } } public static void UpdateToggleText(this ToggleButtonBehaviour button, bool on, string text) { button.onState = on; - Color color = on ? new Color(0f, 1f, 0.16470589f, 1f) : Color.white; + var color = on ? new Color(0f, 1f, 0.16470589f, 1f) : Color.white; button.Background.color = color; button.Text.text = text + ": " + DestroyableSingleton.Instance.GetString(button.onState ? StringNames.SettingsOn : StringNames.SettingsOff, new Il2CppReferenceArray(0)); if (button.Rollover) - { button.Rollover.ChangeOutColor(color); - } } public static void UpdateButtonText(this ToggleButtonBehaviour button, string text, string state) { button.onState = false; - Color color = Color.white; + var color = Color.white; button.Background.color = color; button.Text.text = text + ": " + state; if (button.Rollover) - { button.Rollover.ChangeOutColor(color); - } } - private static ToggleButtonBehaviour AddButton(Vector2 pos, string name, Action onClicked, GameObject nebulaTab, GameObject toggleButtonTemplate) + private static ToggleButtonBehaviour AddButton(int index, string name, Action onClicked, GameObject nebulaTab, GameObject toggleButtonTemplate) { - GameObject button = Object.Instantiate(toggleButtonTemplate, null); + var button = Object.Instantiate(toggleButtonTemplate, null); button.transform.SetParent(nebulaTab.transform); button.transform.localScale = new Vector3(1f, 1f, 1f); - button.transform.localPosition = new Vector3(1.3f * ((pos.x * 2f) - 1f), 1.6f - (0.5f * pos.y), 0f); + button.transform.localPosition = new Vector3(1.3f * (index % 2 * 2 - 1), 1.6f - 0.5f * (index / 2), 0f); button.name = name; - ToggleButtonBehaviour result = button.GetComponent(); - PassiveButton passiveButton = button.GetComponent(); + var result = button.GetComponent(); + var passiveButton = button.GetComponent(); passiveButton.OnClick = new ButtonClickedEvent(); passiveButton.OnClick.AddListener((UnityAction)onClicked); return result; @@ -73,6 +65,9 @@ private static ToggleButtonBehaviour AddButton(Vector2 pos, string name, Action private static ToggleButtonBehaviour showKeyReminder; private static ToggleButtonBehaviour showFPS; private static ToggleButtonBehaviour localHats; + private static ToggleButtonBehaviour showChatNotifications; + private static ToggleButtonBehaviour muteLobbyBGM; + private static ToggleButtonBehaviour forceUsePlus25Protocol; public static void Postfix(OptionsMenuBehaviour __instance) { @@ -80,7 +75,7 @@ public static void Postfix(OptionsMenuBehaviour __instance) PassiveButton passiveButton; - //OĿ׷Ӥ + //設定項目を追加する GameObject nebulaTab = new("NebulaTab"); nebulaTab.transform.SetParent(__instance.transform); @@ -92,18 +87,20 @@ public static void Postfix(OptionsMenuBehaviour __instance) keyBindingTab.transform.localScale = new Vector3(1f, 1f, 1f); keyBindingTab.SetActive(false); - GameObject applyButtonTemplate = tabs[1].Content.transform.GetChild(0).FindChild("ApplyButton").gameObject; - GameObject toggleButtonTemplate = tabs[0].Content.transform.FindChild("MiscGroup").FindChild("StreamerModeButton").gameObject; + var applyButtonTemplate = tabs[1].Content.transform.GetChild(0).FindChild("ApplyButton").gameObject; + var toggleButtonTemplate = tabs[0].Content.transform.FindChild("MiscGroup").FindChild("StreamerModeButton").gameObject; + + var buttonIndex = 0; //EnableSoundEffects - enableSoundEffects = AddButton(new Vector2(0, 0), "EnableSoundEffects", () => + enableSoundEffects = AddButton(buttonIndex++, "EnableSoundEffects", () => { enableSoundEffects.UpdateToggleText(!enableSoundEffects.onState, GetString("EnableSoundEffectsText")); ModOption.enableSoundEffects = Main.EnableSoundEffects.Value = enableSoundEffects.onState; }, nebulaTab, toggleButtonTemplate); //ToggleCursor - toggleCursor = AddButton(new Vector2(0, 1), "ToggleCursor", () => + toggleCursor = AddButton(buttonIndex++, "ToggleCursor", () => { enableCursor(false); toggleCursor.UpdateToggleText(!toggleCursor.onState, GetString("ToggleCursorText")); @@ -112,33 +109,54 @@ public static void Postfix(OptionsMenuBehaviour __instance) }, nebulaTab, toggleButtonTemplate); //ShowFPS - showKeyReminder = AddButton(new Vector2(1, 0), "ShowKeyReminder", () => + showFPS = AddButton(buttonIndex++, "ShowFPS", () => + { + showFPS.UpdateToggleText(!showFPS.onState, GetString("ShowFPS")); + ModOption.showFPS = Main.ShowFPS.Value = showFPS.onState; + }, nebulaTab, toggleButtonTemplate); + + //ShowKeyReminder + showKeyReminder = AddButton(buttonIndex++, "ShowKeyReminder", () => { showKeyReminder.UpdateToggleText(!showKeyReminder.onState, GetString("ShowKeyReminder")); ModOption.showKeyReminder = Main.ShowKeyReminder.Value = showKeyReminder.onState; }, nebulaTab, toggleButtonTemplate); - //ShowFPS - showFPS = AddButton(new Vector2(1, 1), "ShowFPS", () => + //Mute Lobby BGM + muteLobbyBGM = AddButton(buttonIndex++, "MuteLobbyBGM", () => { - showFPS.UpdateToggleText(!showFPS.onState, GetString("ShowFPS")); - ModOption.showFPS = Main.ShowFPS.Value = showFPS.onState; + muteLobbyBGM.UpdateToggleText(!muteLobbyBGM.onState, GetString("MuteLobbyBGM")); + ModOption.MuteLobbyBGM = Main.MuteLobbyBGM.Value = muteLobbyBGM.onState; + }, nebulaTab, toggleButtonTemplate); + + //Show Chat Notifications + showChatNotifications = AddButton(buttonIndex++, "ShowChatNotificationsText", () => + { + showChatNotifications.UpdateToggleText(!showChatNotifications.onState, GetString("ShowChatNotificationsText")); + ModOption.ShowChatNotifications = Main.ShowChatNotifications.Value = showChatNotifications.onState; }, nebulaTab, toggleButtonTemplate); //LocalHats - localHats = AddButton(new Vector2(0, 2), "LocalHats", () => + localHats = AddButton(buttonIndex++, "LocalHats", () => { localHats.UpdateToggleText(!localHats.onState, GetString("LocalHatsText")); ModOption.localHats = Main.LocalHats.Value = localHats.onState; }, nebulaTab, toggleButtonTemplate); - //`굱ƥܥ + //Force Use Plus 25 Protocol + forceUsePlus25Protocol = AddButton(buttonIndex++, "ForceUsePlus25Protocol", () => + { + forceUsePlus25Protocol.UpdateToggleText(!forceUsePlus25Protocol.onState, GetString("ForceUsePlus25Protocol")); + Main.ForceUsePlus25Protocol.Value = forceUsePlus25Protocol.onState; + }, nebulaTab, toggleButtonTemplate); + + //キー割り当てボタン GameObject TextObject; List allKeyBindingButtons = new(); - int selectedKeyBinding = -1; + var selectedKeyBinding = -1; - GameObject defaultButton = Object.Instantiate(applyButtonTemplate, null); + var defaultButton = Object.Instantiate(applyButtonTemplate, null); defaultButton.transform.SetParent(keyBindingTab.transform); defaultButton.transform.localScale = new Vector3(1f, 1f, 1f); defaultButton.transform.localPosition = new Vector3(0f, -2.5f, 0f); @@ -155,9 +173,9 @@ public static void Postfix(OptionsMenuBehaviour __instance) selectedKeyBinding = -1; //_ = SoundManager.Instance.PlaySound(Module.MetaScreen.getSelectClip(), false, 0.8f); - for (int i = 0; i < ModInputManager.allInputs.Count; i++) + for (var i = 0; i < ModInputManager.allInputs.Count; i++) { - ModInputManager.ModInput input = ModInputManager.allInputs[i]; + var input = ModInputManager.allInputs[i]; input.resetToDefault(); allKeyBindingButtons[i].UpdateCustomText(Color.white, GetString("keyBinding." + input.identifier) + ": " + ModInputManager.allKeyCodes[input.keyCode].displayKey); } @@ -166,14 +184,14 @@ public static void Postfix(OptionsMenuBehaviour __instance) foreach (var input in ModInputManager.allInputs) { - int index = allKeyBindingButtons.Count; + var index = allKeyBindingButtons.Count; - GameObject inputButton = Object.Instantiate(toggleButtonTemplate, null); + var inputButton = Object.Instantiate(toggleButtonTemplate, null); inputButton.transform.SetParent(keyBindingTab.transform); inputButton.transform.localScale = new Vector3(1f, 1f, 1f); - inputButton.transform.localPosition = new Vector3(1.3f * ((index % 2 * 2) - 1), 1.5f - (0.5f * (index / 2)), 0f); + inputButton.transform.localPosition = new Vector3(1.3f * (index % 2 * 2 - 1), 1.5f - 0.5f * (index / 2), 0f); inputButton.name = input.identifier; - ToggleButtonBehaviour inputToggleButton = inputButton.GetComponent(); + var inputToggleButton = inputButton.GetComponent(); inputToggleButton.BaseText = 0; inputToggleButton.Text.text = GetString("keyBinding." + input.identifier) + ": " + ModInputManager.allKeyCodes[input.keyCode].displayKey; passiveButton = inputButton.GetComponent(); @@ -197,7 +215,7 @@ public static void Postfix(OptionsMenuBehaviour __instance) allKeyBindingButtons.Add(inputToggleButton); } - GameObject keyBindingButton = Object.Instantiate(applyButtonTemplate, null); + var keyBindingButton = Object.Instantiate(applyButtonTemplate, null); keyBindingButton.transform.SetParent(nebulaTab.transform); keyBindingButton.transform.localScale = new Vector3(1f, 1f, 1f); keyBindingButton.transform.localPosition = new Vector3(0f, -1.5f, 0f); @@ -228,14 +246,12 @@ IEnumerator getEnumerator() if (keyBindingTab.gameObject.active && Input.anyKeyDown && selectedKeyBinding != -1) { - foreach (KeyValuePair entry in ModInputManager.allKeyCodes) + foreach (var entry in ModInputManager.allKeyCodes) { if (!Input.GetKeyDown(entry.Key)) - { continue; - } - ModInputManager.ModInput input = ModInputManager.allInputs[selectedKeyBinding]; + var input = ModInputManager.allInputs[selectedKeyBinding]; input.changeKeyCode(entry.Key); allKeyBindingButtons[selectedKeyBinding].UpdateCustomText(Color.white, GetString("keyBinding." + input.identifier) + ": " + ModInputManager.allKeyCodes[input.keyCode].displayKey); selectedKeyBinding = -1; @@ -256,20 +272,20 @@ IEnumerator getEnumerator() : __instance.StartCoroutine(getEnumerator().WrapToIl2Cpp()); - //֤׷Ӥ + //タブを追加する tabs[^1] = Object.Instantiate(tabs[1], null); - TabGroup nebulaButton = tabs[^1]; + var nebulaButton = tabs[^1]; nebulaButton.gameObject.name = "NebulaButton"; nebulaButton.transform.SetParent(tabs[0].transform.parent); nebulaButton.transform.localScale = new Vector3(1f, 1f, 1f); nebulaButton.Content = nebulaTab; - GameObject textObj = nebulaButton.transform.FindChild("Text_TMP").gameObject; + var textObj = nebulaButton.transform.FindChild("Text_TMP").gameObject; textObj.GetComponent().enabled = false; textObj.GetComponent().text = "modOptionsTitle".Translate(); tabs.Add(Object.Instantiate(tabs[1], null)); - TabGroup keyBindingTabButton = tabs[^1]; + var keyBindingTabButton = tabs[^1]; keyBindingTabButton.gameObject.name = "KeyBindingButton"; keyBindingTabButton.transform.SetParent(tabs[0].transform.parent); keyBindingTabButton.transform.localScale = new Vector3(1f, 1f, 1f); @@ -286,7 +302,10 @@ IEnumerator getEnumerator() enableSoundEffects.UpdateToggleText(Main.EnableSoundEffects.Value, GetString("EnableSoundEffectsText")); showKeyReminder.UpdateToggleText(Main.ShowKeyReminder.Value, GetString("ShowKeyReminder")); toggleCursor.UpdateToggleText(Main.ToggleCursor.Value, GetString("ToggleCursorText")); + showChatNotifications.UpdateToggleText(Main.ShowChatNotifications.Value, GetString("ShowChatNotificationsText")); + muteLobbyBGM.UpdateToggleText(Main.MuteLobbyBGM.Value, GetString("MuteLobbyBGM")); localHats.UpdateToggleText(Main.LocalHats.Value, GetString("LocalHatsText")); + forceUsePlus25Protocol.UpdateToggleText(Main.ForceUsePlus25Protocol.Value, GetString("ForceUsePlus25Protocol")); passiveButton.OnMouseOver.Invoke(); } @@ -295,14 +314,14 @@ IEnumerator getEnumerator() float y = tabs[0].transform.localPosition.y, z = tabs[0].transform.localPosition.z; if (tabs.Count == 4) { - for (int i = 0; i < 3; i++) + for (var i = 0; i < 3; i++) { tabs[i].transform.localPosition = new Vector3(1.7f * (i - 1), y, z); } } else if (tabs.Count == 5) { - for (int i = 0; i < 4; i++) + for (var i = 0; i < 4; i++) { tabs[i].transform.localPosition = new Vector3(1.62f * (i - 1.5f), y, z); } diff --git a/TheOtherRoles/Options/CustomOptions.cs b/TheOtherRoles/Options/CustomOptions.cs index 64af1343..cd71e5a4 100644 --- a/TheOtherRoles/Options/CustomOptions.cs +++ b/TheOtherRoles/Options/CustomOptions.cs @@ -7,16 +7,11 @@ using BepInEx.Configuration; using BepInEx.Unity.IL2CPP; using Hazel; -using Il2CppSystem.Linq; using Reactor.Utilities.Extensions; -using TheOtherRoles.Buttons; -using TheOtherRoles.Patches; using TheOtherRoles.Utilities; using TMPro; using UnityEngine; -using UnityEngine.UI; using static TheOtherRoles.Options.CustomOption; -using Object = UnityEngine.Object; namespace TheOtherRoles.Options; @@ -30,32 +25,34 @@ public enum CustomOptionType Crewmate, Modifier, Guesser, + HideNSeekMain, + HideNSeekRoles, + PropHunt, } public static List options = new(); public static int preset; public static ConfigEntry vanillaSettings; - public int defaultSelection; - public ConfigEntry entry; - public int id; - public bool isHeader; public string name; - public Action onChange; + public object[] selections; + + public int defaultSelection; + public ConfigEntry entry; + public int selection; public OptionBehaviour optionBehaviour; public CustomOption parent; - public int selection; - public object[] selections; + public bool isHeader; public CustomOptionType type; + public Action onChange; + public string heading = ""; // Option creation - public CustomOption(int id, CustomOptionType type, string name, object[] selections, object defaultValue, - CustomOption parent, bool isHeader, Action onChange = null) + public CustomOption(int id, CustomOptionType type, string name, object[] selections, object defaultValue, CustomOption parent, bool isHeader, Action onChange = null, string heading = "") { this.id = id; - //this.name = parent == null ? name : " - " + name; this.name = name; this.selections = selections; var index = Array.IndexOf(selections, defaultValue); @@ -64,34 +61,31 @@ public CustomOption(int id, CustomOptionType type, string name, object[] selecti this.isHeader = isHeader; this.type = type; this.onChange = onChange; + this.heading = heading; selection = 0; if (id != 0) { entry = Main.Instance.Config.Bind($"Preset{preset}", id.ToString(), defaultSelection); selection = Mathf.Clamp(entry.Value, 0, selections.Length - 1); } - options.Add(this); } - public static CustomOption Create(int id, CustomOptionType type, string name, string[] selections, - CustomOption parent = null, bool isHeader = false, Action onChange = null) + public static CustomOption Create(int id, CustomOptionType type, string name, string[] selections, CustomOption parent = null, bool isHeader = false, Action onChange = null, string heading = "") { - return new CustomOption(id, type, name, selections, "", parent, isHeader, onChange); + return new CustomOption(id, type, name, selections, "", parent, isHeader, onChange, heading); } - public static CustomOption Create(int id, CustomOptionType type, string name, float defaultValue, float min, - float max, float step, CustomOption parent = null, bool isHeader = false, Action onChange = null) + public static CustomOption Create(int id, CustomOptionType type, string name, float defaultValue, float min, float max, float step, CustomOption parent = null, bool isHeader = false, Action onChange = null, string heading = "") { List selections = new(); for (var s = min; s <= max; s += step) selections.Add(s); - return new CustomOption(id, type, name, selections.ToArray(), defaultValue, parent, isHeader, onChange); + return new CustomOption(id, type, name, selections.ToArray(), defaultValue, parent, isHeader, onChange, heading); } - public static CustomOption Create(int id, CustomOptionType type, string name, bool defaultValue, - CustomOption parent = null, bool isHeader = false, Action onChange = null) + public static CustomOption Create(int id, CustomOptionType type, string name, bool defaultValue, CustomOption parent = null, bool isHeader = false, Action onChange = null, string heading = "") { - return new CustomOption(id, type, name, ["optionOff", "optionOn"], defaultValue ? "optionOn" : "optionOff", parent, isHeader, onChange); + return new CustomOption(id, type, name, ["optionOff", "optionOn"], defaultValue ? "optionOn" : "optionOff", parent, isHeader, onChange, heading); } // Static behaviour @@ -106,9 +100,7 @@ public static void switchPreset(int newPreset) { if (option.id == 0) continue; - option.entry = - Main.Instance.Config.Bind($"Preset{preset}", option.id.ToString(), - option.defaultSelection); + option.entry = Main.Instance.Config.Bind($"Preset{preset}", option.id.ToString(), option.defaultSelection); option.selection = Mathf.Clamp(option.entry.Value, 0, option.selections.Length - 1); if (option.optionBehaviour != null && option.optionBehaviour is StringOption stringOption) { @@ -120,32 +112,31 @@ public static void switchPreset(int newPreset) public static void saveVanillaOptions() { - vanillaSettings.Value = - Convert.ToBase64String( -#if MXYX_CLUB - GameOptionsManager.Instance.gameOptionsFactory.ToBytes(GameManager.Instance.LogicOptions.currentGameOptions)); -#else - GameOptionsManager.Instance.gameOptionsFactory.ToBytes(GameManager.Instance.LogicOptions.currentGameOptions, false)); -#endif + vanillaSettings.Value = Convert.ToBase64String(GameOptionsManager.Instance.gameOptionsFactory.ToBytes(GameManager.Instance.LogicOptions.currentGameOptions, false)); } - public static void loadVanillaOptions() + public static bool loadVanillaOptions() { var optionsString = vanillaSettings.Value; - if (optionsString == "") return; - GameOptionsManager.Instance.GameHostOptions = - GameOptionsManager.Instance.gameOptionsFactory.FromBytes(Convert.FromBase64String(optionsString)); + if (optionsString == "") return false; + var gameOptions = GameOptionsManager.Instance.gameOptionsFactory.FromBytes(Convert.FromBase64String(optionsString)); + if (gameOptions.Version < 8) + { + Message("tried to paste old settings, not doing this!"); + return false; + } + GameOptionsManager.Instance.GameHostOptions = gameOptions; GameOptionsManager.Instance.CurrentGameOptions = GameOptionsManager.Instance.GameHostOptions; GameManager.Instance.LogicOptions.SetGameOptions(GameOptionsManager.Instance.CurrentGameOptions); GameManager.Instance.LogicOptions.SyncOptions(); + return true; } public static void ShareOptionChange(uint optionId) { var option = options.FirstOrDefault(x => x.id == optionId); if (option == null) return; - var writer = AmongUsClient.Instance!.StartRpcImmediately(CachedPlayer.LocalPlayer.PlayerControl.NetId, - (byte)CustomRPC.ShareOptions, SendOption.Reliable); + var writer = AmongUsClient.Instance!.StartRpcImmediately(CachedPlayer.LocalPlayer.PlayerControl.NetId, (byte)CustomRPC.ShareOptions, SendOption.Reliable, -1); writer.Write((byte)1); writer.WritePacked((uint)option.id); writer.WritePacked(Convert.ToUInt32(option.selection)); @@ -154,14 +145,12 @@ public static void ShareOptionChange(uint optionId) public static void ShareOptionSelections() { - if (CachedPlayer.AllPlayers.Count <= 1 || - (!AmongUsClient.Instance!.AmHost && CachedPlayer.LocalPlayer.PlayerControl == null)) return; + if (CachedPlayer.AllPlayers.Count <= 1 || AmongUsClient.Instance!.AmHost == false && CachedPlayer.LocalPlayer.PlayerControl == null) return; var optionsList = new List(options); while (optionsList.Any()) { var amount = (byte)Math.Min(optionsList.Count, 200); // takes less than 3 bytes per option on average - var writer = AmongUsClient.Instance!.StartRpcImmediately(CachedPlayer.LocalPlayer.PlayerControl.NetId, - (byte)CustomRPC.ShareOptions, SendOption.Reliable); + var writer = AmongUsClient.Instance!.StartRpcImmediately(CachedPlayer.LocalPlayer.PlayerControl.NetId, (byte)CustomRPC.ShareOptions, SendOption.Reliable, -1); writer.Write(amount); for (var i = 0; i < amount; i++) { @@ -170,7 +159,6 @@ public static void ShareOptionSelections() writer.WritePacked((uint)option.id); writer.WritePacked(Convert.ToUInt32(option.selection)); } - AmongUsClient.Instance.FinishRpcImmediately(writer); } } @@ -204,7 +192,7 @@ public int GetQuantity() public string getString() { - var sel = selections[selection].ToString(); + string sel = selections[selection].ToString(); if (sel is "optionOn") return "" + sel.Translate() + ""; @@ -221,41 +209,60 @@ public virtual string getName() return name.Translate(); } + public virtual string getHeading() + { + if (heading == "") return ""; + return GetString(heading); + } + // Option changes - public void updateSelection(int newSelection) + public void updateSelection(int newSelection, bool notifyUsers = true) { - selection = Mathf.Clamp((newSelection + selections.Length) % selections.Length, 0, selections.Length - 1); - try + newSelection = Mathf.Clamp((newSelection + selections.Length) % selections.Length, 0, selections.Length - 1); + + bool doNeedNotifier = AmongUsClient.Instance?.AmClient == true && notifyUsers && selection != newSelection; + if (doNeedNotifier) { - if (onChange != null) onChange(); + DestroyableSingleton.Instance.Notifier.AddSettingsChangeMessage((StringNames)(id + 6000), getString(), false); + try + { + if (GameStartManager.Instance != null && GameStartManager.Instance.LobbyInfoPane != null && GameStartManager.Instance.LobbyInfoPane.LobbyViewSettingsPane != null && GameStartManager.Instance.LobbyInfoPane.LobbyViewSettingsPane.gameObject.activeSelf) + LobbyViewSettingsPaneChangeTabPatch.Postfix(GameStartManager.Instance.LobbyInfoPane.LobbyViewSettingsPane, GameStartManager.Instance.LobbyInfoPane.LobbyViewSettingsPane.currentTab); + } + catch { } } - catch + selection = newSelection; + if (doNeedNotifier) + DestroyableSingleton.Instance.Notifier.AddModSettingsChangeMessage((StringNames)(this.id + 6000), getString(), getName().Replace("- ", ""), false); + try { - // ignored + onChange?.Invoke(); } - + catch { } if (optionBehaviour != null && optionBehaviour is StringOption stringOption) { stringOption.oldValue = stringOption.Value = selection; stringOption.ValueText.text = getString(); - if (AmongUsClient.Instance?.AmHost != true || !CachedPlayer.LocalPlayer.PlayerControl) return; - if (id == 0 && selection != preset) - { - switchPreset(selection); // Switch presets - ShareOptionSelections(); - } - else if (entry != null) + if (AmongUsClient.Instance?.AmHost == true && CachedPlayer.LocalPlayer.PlayerControl) { - entry.Value = selection; // Save selection to config - ShareOptionChange((uint)id); // Share single selection + if (id == 0 && selection != preset) + { + switchPreset(selection); // Switch presets + ShareOptionSelections(); + } + else if (entry != null) + { + entry.Value = selection; // Save selection to config + ShareOptionChange((uint)id);// Share single selection + } } } else if (id == 0 && AmongUsClient.Instance?.AmHost == true && PlayerControl.LocalPlayer) - { - // Share the preset switch for random maps, even if the menu isnt open! + { // Share the preset switch for random maps, even if the menu isnt open! switchPreset(selection); - ShareOptionSelections(); // Share all selections + ShareOptionSelections();// Share all selections } + } public static byte[] serializeOptions() @@ -274,7 +281,6 @@ public static byte[] serializeOptions() binaryWriter.Write((byte)(option.selection + (consecutive ? 128 : 0))); if (!consecutive) binaryWriter.Write((ushort)option.id); } - binaryWriter.Flush(); memoryStream.Position = 0L; return memoryStream.ToArray(); @@ -282,11 +288,14 @@ public static byte[] serializeOptions() } } - public static void deserializeOptions(byte[] inputValues) + public static int deserializeOptions(byte[] inputValues) { var reader = new BinaryReader(new MemoryStream(inputValues)); var lastId = -1; + var somethingApplied = false; + var errors = 0; while (reader.BaseStream.Position < inputValues.Length) + { try { int selection = reader.ReadByte(); @@ -301,489 +310,649 @@ public static void deserializeOptions(byte[] inputValues) { id = reader.ReadUInt16(); } - if (id == 0) continue; lastId = id; - var option = options.First(option => option.id == id); - option.updateSelection(selection); + CustomOption option = options.First(option => option.id == id); + option.entry = Main.Instance.Config.Bind($"Preset{preset}", option.id.ToString(), option.defaultSelection); + option.selection = selection; + if (option.optionBehaviour != null && option.optionBehaviour is StringOption stringOption) + { + stringOption.oldValue = stringOption.Value = option.selection; + stringOption.ValueText.text = option.getString(); + } + somethingApplied = true; } catch (Exception e) { - Warn($"{e}: 试图粘贴无效设置!"); + Warn($"id:{lastId}:{e}: while deserializing - tried to paste invalid settings!"); + errors++; } + } + return Convert.ToInt32(somethingApplied) + (errors > 0 ? 0 : 1); } // Copy to or paste from clipboard (as string) public static void copyToClipboard() { - GUIUtility.systemCopyBuffer = - $"{Main.VersionString}!{Convert.ToBase64String(serializeOptions())}!{vanillaSettings.Value}"; + GUIUtility.systemCopyBuffer = $"{Main.VersionString}!{Convert.ToBase64String(serializeOptions())}!{vanillaSettings.Value}"; } - public static bool pasteFromClipboard() + public static int pasteFromClipboard() { var allSettings = GUIUtility.systemCopyBuffer; + var torOptionsFine = 0; + var vanillaOptionsFine = false; try { var settingsSplit = allSettings.Split("!"); - var versionInfo = settingsSplit[0]; + var versionInfo = Version.Parse(settingsSplit[0]); var torSettings = settingsSplit[1]; var vanillaSettingsSub = settingsSplit[2]; - deserializeOptions(Convert.FromBase64String(torSettings)); - - vanillaSettings.Value = vanillaSettingsSub; - loadVanillaOptions(); - return true; + torOptionsFine = deserializeOptions(Convert.FromBase64String(torSettings)); + ShareOptionSelections(); + if (Main.Version > versionInfo && versionInfo < Version.Parse("4.6.0")) + { + vanillaOptionsFine = false; + FastDestroyableSingleton.Instance.Chat.AddChat(PlayerControl.LocalPlayer, "Host Info: Pasting vanilla settings failed, TOR Options applied!"); + } + else + { + vanillaSettings.Value = vanillaSettingsSub; + vanillaOptionsFine = loadVanillaOptions(); + } } catch (Exception e) { - Warn($"{e}: 尝试粘贴无效设置!"); + Warn($"{e}: tried to paste invalid settings!\n{allSettings}"); + var errorStr = allSettings.Length > 2 ? allSettings.Substring(0, 3) : "(empty clipboard) "; + FastDestroyableSingleton.Instance.Chat.AddChat(PlayerControl.LocalPlayer, $"Host Info: You tried to paste invalid settings: \"{errorStr}...\""); SoundEffectsManager.Load(); SoundEffectsManager.play("fail"); - return false; } + return Convert.ToInt32(vanillaOptionsFine) + torOptionsFine; } } -[HarmonyPatch(typeof(GameOptionsMenu), nameof(GameOptionsMenu.Start))] -internal class GameOptionsMenuStartPatch + + + +[HarmonyPatch(typeof(GameSettingMenu), nameof(GameSettingMenu.ChangeTab))] +internal class GameOptionsMenuChangeTabPatch { - public static void Postfix(GameOptionsMenu __instance) + public static void Postfix(GameSettingMenu __instance, int tabNum, bool previewOnly) { - switch (ModOption.gameMode) + if (previewOnly) return; + foreach (var tab in GameOptionsMenuStartPatch.currentTabs) { - case CustomGamemodes.Classic: - createClassicTabs(__instance); - break; - case CustomGamemodes.Guesser: - createGuesserTabs(__instance); - break; + if (tab != null) + tab.SetActive(false); } - - // create copy to clipboard and paste from clipboard buttons. - var template = GameObject.Find("CloseButton"); - var copyButton = Object.Instantiate(template, template.transform.parent); - copyButton.transform.localPosition += Vector3.down * 0.8f; - var copyButtonPassive = copyButton.GetComponent(); - var copyButtonRenderer = copyButton.GetComponent(); - copyButtonRenderer.sprite = new ResourceSprite("TheOtherRoles.Resources.CopyButton.png", 175f); - copyButtonPassive.OnClick.RemoveAllListeners(); - copyButtonPassive.OnClick = new Button.ButtonClickedEvent(); - copyButtonPassive.OnClick.AddListener((Action)(() => + foreach (var pbutton in GameOptionsMenuStartPatch.currentButtons) { - copyToClipboard(); - copyButtonRenderer.color = Color.green; - __instance.StartCoroutine(Effects.Lerp(1f, new Action(p => - { - if (p > 0.95) - copyButtonRenderer.color = Color.white; - }))); - })); - var pasteButton = Object.Instantiate(template, template.transform.parent); - pasteButton.transform.localPosition += Vector3.down * 1.6f; - var pasteButtonPassive = pasteButton.GetComponent(); - var pasteButtonRenderer = pasteButton.GetComponent(); - pasteButtonRenderer.sprite = UnityHelper.loadSpriteFromResources("TheOtherRoles.Resources.PasteButton.png", 175f); - pasteButtonPassive.OnClick.RemoveAllListeners(); - pasteButtonPassive.OnClick = new Button.ButtonClickedEvent(); - pasteButtonPassive.OnClick.AddListener((Action)(() => + pbutton.SelectButton(false); + } + if (tabNum > 2) { - pasteButtonRenderer.color = Color.yellow; - var success = pasteFromClipboard(); - pasteButtonRenderer.color = success ? Color.green : Color.red; - __instance.StartCoroutine(Effects.Lerp(1f, new Action(p => - { - if (p > 0.95) - pasteButtonRenderer.color = Color.white; - }))); - })); + tabNum -= 3; + GameOptionsMenuStartPatch.currentTabs[tabNum].SetActive(true); + GameOptionsMenuStartPatch.currentButtons[tabNum].SelectButton(true); + } } +} - private static void createClassicTabs(GameOptionsMenu __instance) +[HarmonyPatch(typeof(LobbyViewSettingsPane), nameof(LobbyViewSettingsPane.SetTab))] +internal class LobbyViewSettingsPaneRefreshTabPatch +{ + public static bool Prefix(LobbyViewSettingsPane __instance) { - var isReturn = setNames( - new Dictionary - { - ["TORSettings"] = "theOtherRolesSettings".Translate(), - ["ImpostorSettings"] = "impostorRolesSettings".Translate(), - ["NeutralSettings"] = "neutralRolesSettings".Translate(), - ["CrewmateSettings"] = "crewmateRolesSettings".Translate(), - ["ModifierSettings"] = "modifierSettings".Translate() - }); - - if (isReturn) return; - - // Setup TOR tab - var template = Object.FindObjectsOfType().FirstOrDefault(); - if (template == null) return; - var gameSettings = GameObject.Find("Game Settings"); - var gameSettingMenu = Object.FindObjectsOfType().FirstOrDefault(); + if ((int)__instance.currentTab < 15) + { + LobbyViewSettingsPaneChangeTabPatch.Postfix(__instance, __instance.currentTab); + return false; + } + return true; + } +} - var torSettings = Object.Instantiate(gameSettings, gameSettings.transform.parent); - var torMenu = getMenu(torSettings, "TORSettings"); +[HarmonyPatch(typeof(LobbyViewSettingsPane), nameof(LobbyViewSettingsPane.ChangeTab))] +internal class LobbyViewSettingsPaneChangeTabPatch +{ + public static void Postfix(LobbyViewSettingsPane __instance, StringNames category) + { + var tabNum = (int)category; - var impostorSettings = Object.Instantiate(gameSettings, gameSettings.transform.parent); - var impostorMenu = getMenu(impostorSettings, "ImpostorSettings"); + foreach (var pbutton in LobbyViewSettingsPatch.currentButtons) + { + pbutton.SelectButton(false); + } + if (tabNum > 20) // StringNames are in the range of 3000+ + return; + __instance.taskTabButton.SelectButton(false); - var neutralSettings = Object.Instantiate(gameSettings, gameSettings.transform.parent); - var neutralMenu = getMenu(neutralSettings, "NeutralSettings"); + if (tabNum > 2) + { + tabNum -= 3; + //GameOptionsMenuStartPatch.currentTabs[tabNum].SetActive(true); + LobbyViewSettingsPatch.currentButtons[tabNum].SelectButton(true); + LobbyViewSettingsPatch.drawTab(__instance, LobbyViewSettingsPatch.currentButtonTypes[tabNum]); + } + } +} - var crewmateSettings = Object.Instantiate(gameSettings, gameSettings.transform.parent); - var crewmateMenu = getMenu(crewmateSettings, "CrewmateSettings"); +[HarmonyPatch(typeof(LobbyViewSettingsPane), nameof(LobbyViewSettingsPane.Update))] +internal class LobbyViewSettingsPaneUpdatePatch +{ + public static void Postfix(LobbyViewSettingsPane __instance) + { + if (LobbyViewSettingsPatch.currentButtons.Count == 0) + { + LobbyViewSettingsPatch.gameModeChangedFlag = true; + LobbyViewSettingsPatch.Postfix(__instance); - var modifierSettings = Object.Instantiate(gameSettings, gameSettings.transform.parent); - var modifierMenu = getMenu(modifierSettings, "ModifierSettings"); + } + } +} - var roleTab = GameObject.Find("RoleTab"); - var gameTab = GameObject.Find("GameTab"); - var torTab = Object.Instantiate(roleTab, roleTab.transform.parent); - var torTabHighlight = getTabHighlight(torTab, "TheOtherRolesTab", "TheOtherRoles.Resources.TabIcon.png"); +[HarmonyPatch(typeof(LobbyViewSettingsPane), nameof(LobbyViewSettingsPane.Awake))] +internal class LobbyViewSettingsPatch +{ + public static List currentButtons = new(); + public static List currentButtonTypes = new(); + public static bool gameModeChangedFlag; - var impostorTab = Object.Instantiate(roleTab, torTab.transform); - var impostorTabHighlight = - getTabHighlight(impostorTab, "ImpostorTab", "TheOtherRoles.Resources.TabIconImpostor.png"); + public static void createCustomButton(LobbyViewSettingsPane __instance, int targetMenu, string buttonName, string buttonText, CustomOptionType optionType) + { + buttonName = "View" + buttonName; + var buttonTemplate = GameObject.Find("OverviewTab"); + var torSettingsButton = GameObject.Find(buttonName); + if (torSettingsButton == null) + { + torSettingsButton = UnityEngine.Object.Instantiate(buttonTemplate, buttonTemplate.transform.parent); + torSettingsButton.transform.localPosition += Vector3.right * 1.75f * (targetMenu - 2); + torSettingsButton.name = buttonName; + __instance.StartCoroutine(Effects.Lerp(2f, new Action(p => { torSettingsButton.transform.FindChild("FontPlacer").GetComponentInChildren().text = buttonText; }))); + var torSettingsPassiveButton = torSettingsButton.GetComponent(); + torSettingsPassiveButton.OnClick.RemoveAllListeners(); + torSettingsPassiveButton.OnClick.AddListener((Action)(() => + { + __instance.ChangeTab((StringNames)targetMenu); + })); + torSettingsPassiveButton.OnMouseOut.RemoveAllListeners(); + torSettingsPassiveButton.OnMouseOver.RemoveAllListeners(); + torSettingsPassiveButton.SelectButton(false); + currentButtons.Add(torSettingsPassiveButton); + currentButtonTypes.Add(optionType); + } + } - var neutralTab = Object.Instantiate(roleTab, impostorTab.transform); - var neutralTabHighlight = - getTabHighlight(neutralTab, "NeutralTab", "TheOtherRoles.Resources.TabIconNeutral.png"); + public static void Postfix(LobbyViewSettingsPane __instance) + { + currentButtons.ForEach(x => x?.Destroy()); + currentButtons.Clear(); + currentButtonTypes.Clear(); - var crewmateTab = Object.Instantiate(roleTab, neutralTab.transform); - var crewmateTabHighlight = - getTabHighlight(crewmateTab, "CrewmateTab", "TheOtherRoles.Resources.TabIconCrewmate.png"); + removeVanillaTabs(__instance); - var modifierTab = Object.Instantiate(roleTab, crewmateTab.transform); - var modifierTabHighlight = - getTabHighlight(modifierTab, "ModifierTab", "TheOtherRoles.Resources.TabIconModifier.png"); + createSettingTabs(__instance); - // Position of Tab Icons - gameTab.transform.position += Vector3.left * 3f; - roleTab.transform.position += Vector3.left * 3f; - torTab.transform.position += Vector3.left * 2f; - impostorTab.transform.localPosition = Vector3.right * 1f; - neutralTab.transform.localPosition = Vector3.right * 1f; - crewmateTab.transform.localPosition = Vector3.right * 1f; - modifierTab.transform.localPosition = Vector3.right * 1f; + } - var tabs = new[] { gameTab, roleTab, torTab, impostorTab, neutralTab, crewmateTab, modifierTab }; - var settingsHighlightMap = new Dictionary - { - [gameSettingMenu.RegularGameSettings] = gameSettingMenu.GameSettingsHightlight, - [gameSettingMenu.RolesSettings.gameObject] = gameSettingMenu.RolesSettingsHightlight, - [torSettings.gameObject] = torTabHighlight, - [impostorSettings.gameObject] = impostorTabHighlight, - [neutralSettings.gameObject] = neutralTabHighlight, - [crewmateSettings.gameObject] = crewmateTabHighlight, - [modifierSettings.gameObject] = modifierTabHighlight - }; - for (var i = 0; i < tabs.Length; i++) + public static void removeVanillaTabs(LobbyViewSettingsPane __instance) + { + GameObject.Find("RolesTabs")?.Destroy(); + var overview = GameObject.Find("OverviewTab"); + if (!gameModeChangedFlag) { - var button = tabs[i].GetComponentInChildren(); - if (button == null) continue; - var copiedIndex = i; - button.OnClick = new Button.ButtonClickedEvent(); - button.OnClick.AddListener((Action)(() => { setListener(settingsHighlightMap, copiedIndex); })); + overview.transform.localScale = new Vector3(0.5f * overview.transform.localScale.x, overview.transform.localScale.y, overview.transform.localScale.z); + overview.transform.localPosition += new Vector3(-1.2f, 0f, 0f); + } + overview.transform.Find("FontPlacer").transform.localScale = new Vector3(1.35f, 1f, 1f); + overview.transform.Find("FontPlacer").transform.localPosition = new Vector3(-0.6f, -0.1f, 0f); + gameModeChangedFlag = false; + } - destroyOptions(new List> - { - torMenu.GetComponentsInChildren().ToList(), - impostorMenu.GetComponentsInChildren().ToList(), - neutralMenu.GetComponentsInChildren().ToList(), - crewmateMenu.GetComponentsInChildren().ToList(), - modifierMenu.GetComponentsInChildren().ToList() - }); + public static void drawTab(LobbyViewSettingsPane __instance, CustomOptionType optionType) + { - var torOptions = new List(); - var impostorOptions = new List(); - var neutralOptions = new List(); - var crewmateOptions = new List(); - var modifierOptions = new List(); + var relevantOptions = options.Where(x => x.type == optionType || x.type == CustomOptionType.Guesser && optionType == CustomOptionType.General).ToList(); + if ((int)optionType == 99) + { + // Create 4 Groups with Role settings only + relevantOptions.Clear(); + relevantOptions.AddRange(options.Where(x => x.type == CustomOptionType.Impostor && x.isHeader)); + relevantOptions.AddRange(options.Where(x => x.type == CustomOptionType.Neutral && x.isHeader)); + relevantOptions.AddRange(options.Where(x => x.type == CustomOptionType.Crewmate && x.isHeader)); + relevantOptions.AddRange(options.Where(x => x.type == CustomOptionType.Modifier && x.isHeader)); + foreach (var option in options) + { + if (option.parent != null && option.parent.GetSelection() > 0) + { + if (option.id == 103) //Deputy + relevantOptions.Insert(relevantOptions.IndexOf(CustomOptionHolder.sheriffSpawnRate) + 1, option); + else if (option.id == 224) //Sidekick + relevantOptions.Insert(relevantOptions.IndexOf(CustomOptionHolder.jackalSpawnRate) + 1, option); + else if (option.id == 358) //Prosecutor + relevantOptions.Insert(relevantOptions.IndexOf(CustomOptionHolder.lawyerSpawnRate) + 1, option); + } + } + } + + if (ModOption.gameMode == CustomGamemodes.Guesser) // Exclude guesser options in neutral mode + relevantOptions = relevantOptions.Where(x => !new List { 310, 311, 312, 313, 314, 315, 316, 317, 318 }.Contains(x.id)).ToList(); - var menus = new List + for (var j = 0; j < __instance.settingsInfo.Count; j++) { - torMenu.transform, impostorMenu.transform, neutralMenu.transform, crewmateMenu.transform, - modifierMenu.transform - }; - var optionBehaviours = new List> - { torOptions, impostorOptions, neutralOptions, crewmateOptions, modifierOptions }; + __instance.settingsInfo[j].gameObject.Destroy(); + } + __instance.settingsInfo.Clear(); + + var num = 1.44f; + var i = 0; + var singles = 0; + var headers = 0; + var lines = 0; + var curType = CustomOptionType.Modifier; - for (var i = 0; i < options.Count; i++) + foreach (var option in relevantOptions) { - var option = options[i]; - if ((int)option.type > 4) continue; - if (option.optionBehaviour == null) + if (option.isHeader && (int)optionType != 99 || (int)optionType == 99 && curType != option.type) { - var stringOption = Object.Instantiate(template, menus[(int)option.type]); - optionBehaviours[(int)option.type].Add(stringOption); - stringOption.OnValueChanged = new Action(o => { }); - stringOption.TitleText.text = option.getName(); - stringOption.Value = stringOption.oldValue = option.selection; - stringOption.ValueText.text = option.getString(); + curType = option.type; + if (i != 0) num -= 0.59f; + if (i % 2 != 0) singles++; + headers++; // for header + var categoryHeaderMasked = UnityEngine.Object.Instantiate(__instance.categoryHeaderOrigin); + categoryHeaderMasked.SetHeader(StringNames.ImpostorsCategory, 61); + var titleText = option.heading != "" ? option.getHeading() : option.getName(); + categoryHeaderMasked.Title.text = titleText; + var color = titleText.Contains("() { + { CustomOptionType.Impostor, "ImpostorRolesText".Translate() }, + { CustomOptionType.Neutral, "NeutralRolesText".Translate() }, + { CustomOptionType.Crewmate, "CrewmateRolesText".Translate() }, + { CustomOptionType.Modifier, "ModifiersText".Translate() } }[curType]; + categoryHeaderMasked.Title.outlineColor = Color.white; + categoryHeaderMasked.Title.outlineWidth = 0.2f; + categoryHeaderMasked.transform.SetParent(__instance.settingsContainer); + categoryHeaderMasked.transform.localScale = Vector3.one; + categoryHeaderMasked.transform.localPosition = new Vector3(-9.77f, num, -2f); + __instance.settingsInfo.Add(categoryHeaderMasked.gameObject); + num -= 0.85f; + i = 0; + } - option.optionBehaviour = stringOption; + var viewSettingsInfoPanel = UnityEngine.Object.Instantiate(__instance.infoPanelOrigin); + viewSettingsInfoPanel.transform.SetParent(__instance.settingsContainer); + viewSettingsInfoPanel.transform.localScale = Vector3.one; + float num2; + if (i % 2 == 0) + { + lines++; + num2 = -8.95f; + if (i > 0) + num -= 0.59f; + } + else + { + num2 = -3f; } + viewSettingsInfoPanel.transform.localPosition = new Vector3(num2, num, -2f); + var value = option.GetSelection(); + viewSettingsInfoPanel.SetInfo(StringNames.ImpostorsCategory, option.getString(), 61); + viewSettingsInfoPanel.titleText.text = option.getName(); + if (option.isHeader && (int)optionType != 99 && option.heading == "" && (option.type == CustomOptionType.Neutral || option.type == CustomOptionType.Crewmate || option.type == CustomOptionType.Impostor || option.type == CustomOptionType.Modifier)) + viewSettingsInfoPanel.titleText.text = "optionSpawnChance".Translate(); + if ((int)optionType == 99) + { + var color = option.getName().Contains(" { torMenu, impostorMenu, neutralMenu, crewmateMenu, modifierMenu }, - new List> { torOptions, impostorOptions, neutralOptions, crewmateOptions, modifierOptions }, - new List { torSettings, impostorSettings, neutralSettings, crewmateSettings, modifierSettings } - ); - - adaptTaskCount(__instance); } - private static void createGuesserTabs(GameOptionsMenu __instance) + public static void createSettingTabs(LobbyViewSettingsPane __instance) { - var isReturn = setNames( - new Dictionary - { - ["TORSettings"] = "theOtherRolesSettings".Translate(), - ["GuesserSettings"] = "guesserSettings".Translate(), - ["ImpostorSettings"] = "impostorRolesSettings".Translate(), - ["NeutralSettings"] = "neutralRolesSettings".Translate(), - ["CrewmateSettings"] = "crewmateRolesSettings".Translate(), - ["ModifierSettings"] = "modifierSettings".Translate() - }); - - if (isReturn) return; - - // Setup TOR tab - var template = Object.FindObjectsOfType().FirstOrDefault(); - if (template == null) return; - var gameSettings = GameObject.Find("Game Settings"); - var gameSettingMenu = Object.FindObjectsOfType().FirstOrDefault(); - - var torSettings = Object.Instantiate(gameSettings, gameSettings.transform.parent); - var torMenu = getMenu(torSettings, "TORSettings"); - - var guesserSettings = Object.Instantiate(gameSettings, gameSettings.transform.parent); - var guesserMenu = getMenu(guesserSettings, "GuesserSettings"); - - var impostorSettings = Object.Instantiate(gameSettings, gameSettings.transform.parent); - var impostorMenu = getMenu(impostorSettings, "ImpostorSettings"); - - var neutralSettings = Object.Instantiate(gameSettings, gameSettings.transform.parent); - var neutralMenu = getMenu(neutralSettings, "NeutralSettings"); - - var crewmateSettings = Object.Instantiate(gameSettings, gameSettings.transform.parent); - var crewmateMenu = getMenu(crewmateSettings, "CrewmateSettings"); - - var modifierSettings = Object.Instantiate(gameSettings, gameSettings.transform.parent); - var modifierMenu = getMenu(modifierSettings, "ModifierSettings"); - - var roleTab = GameObject.Find("RoleTab"); - var gameTab = GameObject.Find("GameTab"); - - var torTab = Object.Instantiate(roleTab, gameTab.transform.parent); - var torTabHighlight = getTabHighlight(torTab, "TheOtherRolesTab", "TheOtherRoles.Resources.TabIcon.png"); - - var guesserTab = Object.Instantiate(roleTab, torTab.transform); - var guesserTabHighlight = - getTabHighlight(guesserTab, "GuesserTab", "TheOtherRoles.Resources.TabIconGuesserSettings.png"); - - var impostorTab = Object.Instantiate(roleTab, guesserTab.transform); - var impostorTabHighlight = - getTabHighlight(impostorTab, "ImpostorTab", "TheOtherRoles.Resources.TabIconImpostor.png"); - - var neutralTab = Object.Instantiate(roleTab, impostorTab.transform); - var neutralTabHighlight = - getTabHighlight(neutralTab, "NeutralTab", "TheOtherRoles.Resources.TabIconNeutral.png"); - - var crewmateTab = Object.Instantiate(roleTab, neutralTab.transform); - var crewmateTabHighlight = - getTabHighlight(crewmateTab, "CrewmateTab", "TheOtherRoles.Resources.TabIconCrewmate.png"); - - var modifierTab = Object.Instantiate(roleTab, crewmateTab.transform); - var modifierTabHighlight = - getTabHighlight(modifierTab, "ModifierTab", "TheOtherRoles.Resources.TabIconModifier.png"); - - roleTab.active = false; - // Position of Tab Icons - gameTab.transform.position += Vector3.left * 3f; - torTab.transform.position += Vector3.left * 3f; - guesserTab.transform.localPosition = Vector3.right * 1f; - impostorTab.transform.localPosition = Vector3.right * 1f; - neutralTab.transform.localPosition = Vector3.right * 1f; - crewmateTab.transform.localPosition = Vector3.right * 1f; - modifierTab.transform.localPosition = Vector3.right * 1f; - - var tabs = new[] { gameTab, torTab, impostorTab, neutralTab, crewmateTab, modifierTab, guesserTab }; - var settingsHighlightMap = new Dictionary - { - [gameSettingMenu.RegularGameSettings] = gameSettingMenu.GameSettingsHightlight, - [torSettings.gameObject] = torTabHighlight, - [impostorSettings.gameObject] = impostorTabHighlight, - [neutralSettings.gameObject] = neutralTabHighlight, - [crewmateSettings.gameObject] = crewmateTabHighlight, - [modifierSettings.gameObject] = modifierTabHighlight, - [guesserSettings.gameObject] = guesserTabHighlight - }; - for (var i = 0; i < tabs.Length; i++) + // Handle different gamemodes and tabs needed therein. + var next = 3; + if (ModOption.gameMode == CustomGamemodes.Guesser || ModOption.gameMode == CustomGamemodes.Classic) { - var button = tabs[i].GetComponentInChildren(); - if (button == null) continue; - var copiedIndex = i; - button.OnClick = new Button.ButtonClickedEvent(); - button.OnClick.AddListener((Action)(() => { setListener(settingsHighlightMap, copiedIndex); })); - } - destroyOptions(new List> - { - torMenu.GetComponentsInChildren().ToList(), - guesserMenu.GetComponentsInChildren().ToList(), - impostorMenu.GetComponentsInChildren().ToList(), - neutralMenu.GetComponentsInChildren().ToList(), - crewmateMenu.GetComponentsInChildren().ToList(), - modifierMenu.GetComponentsInChildren().ToList() - }); - - var torOptions = new List(); - var guesserOptions = new List(); - var impostorOptions = new List(); - var neutralOptions = new List(); - var crewmateOptions = new List(); - var modifierOptions = new List(); - - - var menus = new List - { - torMenu.transform, impostorMenu.transform, neutralMenu.transform, crewmateMenu.transform, - modifierMenu.transform, guesserMenu.transform - }; - var optionBehaviours = new List> - { torOptions, impostorOptions, neutralOptions, crewmateOptions, modifierOptions, guesserOptions }; - var exludedIds = new List { 10000, 10001, 10002, 10003, 10004, 10005, 10006, 10007, 10008, 30100, 30101, 30102, 30103, 30104 }; - - for (var i = 0; i < options.Count; i++) - { - var option = options[i]; - if (exludedIds.Contains(option.id)) continue; - if ((int)option.type > 5) continue; - if (option.optionBehaviour == null) - { - var stringOption = Object.Instantiate(template, menus[(int)option.type]); - optionBehaviours[(int)option.type].Add(stringOption); - stringOption.OnValueChanged = new Action(o => { }); - stringOption.TitleText.text = option.getName(); - stringOption.Value = stringOption.oldValue = option.selection; - stringOption.ValueText.text = option.getString(); + // create TOR settings + createCustomButton(__instance, next++, "TORSettings", "theOtherRolesSettings".Translate(), CustomOptionType.General); + // create TOR settings + createCustomButton(__instance, next++, "RoleOverview", "roleOverview".Translate(), (CustomOptionType)99); + // IMp + createCustomButton(__instance, next++, "ImpostorSettings", "impostorRolesSettings".Translate(), CustomOptionType.Impostor); - option.optionBehaviour = stringOption; - } + // Neutral + createCustomButton(__instance, next++, "NeutralSettings", "neutralRolesSettings".Translate(), CustomOptionType.Neutral); + // Crew + createCustomButton(__instance, next++, "CrewmateSettings", "crewmateRolesSettings".Translate(), CustomOptionType.Crewmate); + // Modifier + createCustomButton(__instance, next++, "ModifierSettings", "modifierSettings".Translate(), CustomOptionType.Modifier); - option.optionBehaviour.gameObject.SetActive(true); } + } +} - setOptions( - new List { torMenu, impostorMenu, neutralMenu, crewmateMenu, modifierMenu, guesserMenu }, - new List> - { torOptions, impostorOptions, neutralOptions, crewmateOptions, modifierOptions, guesserOptions }, - new List - { torSettings, impostorSettings, neutralSettings, crewmateSettings, modifierSettings, guesserSettings } - ); - adaptTaskCount(__instance); - } +[HarmonyPatch(typeof(GameOptionsMenu), nameof(GameOptionsMenu.Update))] +internal class GameOptionsMenuUpdatePatch +{ + /*private static float timer = 1f; - private static void setListener(Dictionary settingsHighlightMap, int index) + public static void Postfix(GameOptionsMenu __instance) { - foreach (var entry in settingsHighlightMap) + var gameSettingMenu = UnityEngine.Object.FindObjectsOfType().FirstOrDefault(); + if (gameSettingMenu.PresetsTab.gameObject.active || gameSettingMenu.RoleSettingsTab.gameObject.active) return; + + //__instance.GetComponentInParent().ContentYBounds.max = -0.5F + (__instance.Children.Count * 0.55F); + timer += Time.deltaTime; + if (timer < 0.1f) return; + timer = 0f; + + foreach (var option in options) { - entry.Key.SetActive(false); - entry.Value.enabled = false; + if (option?.optionBehaviour?.gameObject != null) + { + var enabled = true; + var parent = option.parent; + while (parent != null && enabled) + { + enabled = parent.selection != 0; + parent = parent.parent; + } + option.optionBehaviour.gameObject.SetActive(enabled); + } } + }*/ - settingsHighlightMap.ElementAt(index).Key.SetActive(true); - settingsHighlightMap.ElementAt(index).Value.enabled = true; - } +} - private static void destroyOptions(List> optionBehavioursList) + +[HarmonyPatch(typeof(GameOptionsMenu), nameof(GameOptionsMenu.CreateSettings))] +internal class GameOptionsMenuCreateSettingsPatch +{ + public static void Postfix(GameOptionsMenu __instance) { - foreach (var optionBehaviours in optionBehavioursList) - foreach (var option in optionBehaviours) - Object.Destroy(option.gameObject); + if (__instance.gameObject.name == "GAME SETTINGS TAB") + adaptTaskCount(__instance); } - private static bool setNames(Dictionary gameObjectNameDisplayNameMap) + private static void adaptTaskCount(GameOptionsMenu __instance) { - foreach (var entry in gameObjectNameDisplayNameMap) - if (GameObject.Find(entry.Key) != null) - { - // Settings setup has already been performed, fixing the title of the tab and returning - GameObject.Find(entry.Key).transform.FindChild("GameGroup").FindChild("Text") - .GetComponent().SetText(entry.Value); - return true; - } - - return false; + // Adapt task count for main options + var commonTasksOption = __instance.Children.ToArray().FirstOrDefault(x => x.TryCast()?.intOptionName == Int32OptionNames.NumCommonTasks).Cast(); + if (commonTasksOption != null) commonTasksOption.ValidRange = new FloatRange(0f, 4f); + var shortTasksOption = __instance.Children.ToArray().FirstOrDefault(x => x.TryCast()?.intOptionName == Int32OptionNames.NumShortTasks).TryCast(); + if (shortTasksOption != null) shortTasksOption.ValidRange = new FloatRange(0f, 23f); + var longTasksOption = __instance.Children.ToArray().FirstOrDefault(x => x.TryCast()?.intOptionName == Int32OptionNames.NumLongTasks).TryCast(); + if (longTasksOption != null) longTasksOption.ValidRange = new FloatRange(0f, 15f); } +} - private static GameOptionsMenu getMenu(GameObject setting, string settingName) + +[HarmonyPatch(typeof(GameSettingMenu), nameof(GameSettingMenu.Start))] +internal class GameOptionsMenuStartPatch +{ + public static List currentTabs = new(); + public static List currentButtons = new(); + + public static void Postfix(GameSettingMenu __instance) { - var menu = setting.transform.FindChild("GameGroup").FindChild("SliderInner").GetComponent(); - setting.name = settingName; + currentTabs.ForEach(x => x?.Destroy()); + currentButtons.ForEach(x => x?.Destroy()); + currentTabs = new(); + currentButtons = new(); + + if (GameOptionsManager.Instance.currentGameOptions.GameMode == GameModes.HideNSeek) return; + + removeVanillaTabs(__instance); - return menu; + createSettingTabs(__instance); + + var GOMGameObject = GameObject.Find("GAME SETTINGS TAB"); + + + // create copy to clipboard and paste from clipboard buttons. + var template = GameObject.Find("PlayerOptionsMenu(Clone)").transform.Find("CloseButton").gameObject; + var holderGO = new GameObject("copyPasteButtonParent"); + var bgrenderer = holderGO.AddComponent(); + bgrenderer.sprite = UnityHelper.loadSpriteFromResources("TheOtherRoles.Resources.CopyPasteBG.png", 175f); + holderGO.transform.SetParent(template.transform.parent, false); + holderGO.transform.localPosition = template.transform.localPosition + new Vector3(-8.3f, 0.73f, -2f); + holderGO.layer = template.layer; + holderGO.SetActive(true); + var copyButton = UnityEngine.Object.Instantiate(template, holderGO.transform); + copyButton.transform.localPosition = new Vector3(-0.3f, 0.02f, -2f); + var copyButtonPassive = copyButton.GetComponent(); + var copyButtonRenderer = copyButton.GetComponentInChildren(); + var copyButtonActiveRenderer = copyButton.transform.GetChild(1).GetComponent(); + copyButtonRenderer.sprite = UnityHelper.loadSpriteFromResources("TheOtherRoles.Resources.Copy.png", 100f); + copyButton.transform.GetChild(1).transform.localPosition = Vector3.zero; + copyButtonActiveRenderer.sprite = UnityHelper.loadSpriteFromResources("TheOtherRoles.Resources.CopyActive.png", 100f); + copyButtonPassive.OnClick.RemoveAllListeners(); + copyButtonPassive.OnClick = new UnityEngine.UI.Button.ButtonClickedEvent(); + copyButtonPassive.OnClick.AddListener((Action)(() => + { + copyToClipboard(); + copyButtonRenderer.color = Color.green; + copyButtonActiveRenderer.color = Color.green; + __instance.StartCoroutine(Effects.Lerp(1f, new Action((p) => + { + if (p > 0.95) + { + copyButtonRenderer.color = Color.white; + copyButtonActiveRenderer.color = Color.white; + } + }))); + })); + var pasteButton = UnityEngine.Object.Instantiate(template, holderGO.transform); + pasteButton.transform.localPosition = new Vector3(0.3f, 0.02f, -2f); + var pasteButtonPassive = pasteButton.GetComponent(); + var pasteButtonRenderer = pasteButton.GetComponentInChildren(); + var pasteButtonActiveRenderer = pasteButton.transform.GetChild(1).GetComponent(); + pasteButtonRenderer.sprite = UnityHelper.loadSpriteFromResources("TheOtherRoles.Resources.Paste.png", 100f); + pasteButtonActiveRenderer.sprite = UnityHelper.loadSpriteFromResources("TheOtherRoles.Resources.PasteActive.png", 100f); + pasteButtonPassive.OnClick.RemoveAllListeners(); + pasteButtonPassive.OnClick = new UnityEngine.UI.Button.ButtonClickedEvent(); + pasteButtonPassive.OnClick.AddListener((Action)(() => + { + pasteButtonRenderer.color = Color.yellow; + var success = pasteFromClipboard(); + pasteButtonRenderer.color = success == 3 ? Color.green : success == 0 ? Color.red : Color.yellow; + pasteButtonActiveRenderer.color = success == 3 ? Color.green : success == 0 ? Color.red : Color.yellow; + __instance.StartCoroutine(Effects.Lerp(1f, new Action((p) => + { + if (p > 0.95) + { + pasteButtonRenderer.color = Color.white; + pasteButtonActiveRenderer.color = Color.white; + } + }))); + })); } - private static SpriteRenderer getTabHighlight(GameObject tab, string tabName, string tabSpritePath) + private static void createSettings(GameOptionsMenu menu, List options) { - var tabHighlight = tab.transform.FindChild("Hat Button").FindChild("Tab Background") - .GetComponent(); - tab.transform.FindChild("Hat Button").FindChild("Icon").GetComponent().sprite = - UnityHelper.loadSpriteFromResources(tabSpritePath, 100f); - tab.name = "tabName"; + var num = 1.5f; + foreach (var option in options) + { + if (option.isHeader) + { + var categoryHeaderMasked = UnityEngine.Object.Instantiate(menu.categoryHeaderOrigin, Vector3.zero, Quaternion.identity, menu.settingsContainer); + categoryHeaderMasked.SetHeader(StringNames.ImpostorsCategory, 20); + + var titleText = option.heading != "" ? option.getHeading() : option.getName(); + var color = titleText.Contains("(true); + for (var i = 0; i < componentsInChildren.Length; i++) + { + componentsInChildren[i].material.SetInt(PlayerMaterial.MaskLayer, 20); + } + foreach (var textMeshPro in optionBehaviour.GetComponentsInChildren(true)) + { + textMeshPro.fontMaterial.SetFloat("_StencilComp", 3f); + textMeshPro.fontMaterial.SetFloat("_Stencil", 20); + } + + var stringOption = optionBehaviour as StringOption; + stringOption.OnValueChanged = new Action((o) => { }); + stringOption.TitleText.text = option.getName(); + if (option.isHeader && option.heading == "" && (option.type == CustomOptionType.Neutral || option.type == CustomOptionType.Crewmate || option.type == CustomOptionType.Impostor || option.type == CustomOptionType.Modifier)) + stringOption.TitleText.text = "optionSpawnChance".Translate(); + if (stringOption.TitleText.text.Length > 25) + stringOption.TitleText.fontSize = 2.2f; + if (stringOption.TitleText.text.Length > 40) + stringOption.TitleText.fontSize = 2f; + stringOption.Value = stringOption.oldValue = option.selection; + stringOption.ValueText.text = option.getString(); + option.optionBehaviour = stringOption; + + menu.Children.Add(optionBehaviour); + num -= 0.45f; + menu.scrollBar.SetYBoundsMax(-num - 1.65f); + } - return tabHighlight; + for (var i = 0; i < menu.Children.Count; i++) + { + var optionBehaviour = menu.Children[i]; + if (AmongUsClient.Instance && !AmongUsClient.Instance.AmHost) + optionBehaviour.SetAsPlayer(); + } } - private static void setOptions(List menus, List> options, - List settings) + private static void removeVanillaTabs(GameSettingMenu __instance) { - if (!(menus.Count == options.Count && options.Count == settings.Count)) + GameObject.Find("What Is This?")?.Destroy(); + GameObject.Find("GamePresetButton")?.Destroy(); + GameObject.Find("RoleSettingsButton")?.Destroy(); + __instance.ChangeTab(1, false); + } + public static void createCustomButton(GameSettingMenu __instance, int targetMenu, string buttonName, string buttonText) + { + var leftPanel = GameObject.Find("LeftPanel"); + var leftLabel = GameObject.Find("GameSettingsLabel"); + var buttonTemplate = GameObject.Find("GameSettingsButton"); + leftLabel.transform.localPosition += new Vector3(0f, 0.02f); + if (targetMenu == 3) { - Error("List counts are not equal"); - return; + buttonTemplate.transform.localPosition += Vector3.up * 2.15f; + buttonTemplate.transform.localScale *= Vector2.one * 0.75f; + } + var torSettingsButton = GameObject.Find(buttonName); + if (torSettingsButton == null) + { + torSettingsButton = UnityEngine.Object.Instantiate(buttonTemplate, leftPanel.transform); + torSettingsButton.transform.localPosition = buttonTemplate.transform.localPosition - Vector3.up * 0.5f * (targetMenu - 2); + torSettingsButton.name = buttonName; + __instance.StartCoroutine(Effects.Lerp(2f, new Action(p => { torSettingsButton.transform.FindChild("FontPlacer").GetComponentInChildren().text = buttonText; }))); + var torSettingsPassiveButton = torSettingsButton.GetComponent(); + torSettingsPassiveButton.OnClick.RemoveAllListeners(); + torSettingsPassiveButton.OnClick.AddListener((Action)(() => + { + __instance.ChangeTab(targetMenu, false); + })); + torSettingsPassiveButton.OnMouseOut.RemoveAllListeners(); + torSettingsPassiveButton.OnMouseOver.RemoveAllListeners(); + torSettingsPassiveButton.SelectButton(false); + currentButtons.Add(torSettingsPassiveButton); } + } + + public static void createGameOptionsMenu(GameSettingMenu __instance, CustomOptionType optionType, string settingName) + { + var tabTemplate = GameObject.Find("GAME SETTINGS TAB"); + currentTabs.RemoveAll(x => x == null); + + var torSettingsTab = UnityEngine.Object.Instantiate(tabTemplate, tabTemplate.transform.parent); + torSettingsTab.name = settingName; - for (var i = 0; i < menus.Count; i++) + var torSettingsGOM = torSettingsTab.GetComponent(); + foreach (var child in torSettingsGOM.Children) { - menus[i].Children = options[i].ToArray(); - settings[i].gameObject.SetActive(false); + child.Destroy(); } + torSettingsGOM.scrollBar.transform.FindChild("SliderInner").DestroyChildren(); + torSettingsGOM.Children.Clear(); + var relevantOptions = options.Where(x => x.type == optionType).ToList(); + if (ModOption.gameMode == CustomGamemodes.Guesser) // Exclude guesser options in neutral mode + relevantOptions = relevantOptions.Where(x => !new List { 310, 311, 312, 313, 314, 315, 316, 317, 318 }.Contains(x.id)).ToList(); + createSettings(torSettingsGOM, relevantOptions); + + currentTabs.Add(torSettingsTab); + torSettingsTab.SetActive(false); } - private static void adaptTaskCount(GameOptionsMenu __instance) + private static void createSettingTabs(GameSettingMenu __instance) { - // Adapt task count for main options - var commonTasksOption = - __instance.Children.FirstOrDefault(x => x.name == "NumCommonTasks").TryCast(); - if (commonTasksOption != null) commonTasksOption.ValidRange = new FloatRange(0f, 4f); + // Handle different gamemodes and tabs needed therein. + var next = 3; + if (ModOption.gameMode is CustomGamemodes.Guesser or CustomGamemodes.Classic) + { - var shortTasksOption = - __instance.Children.FirstOrDefault(x => x.name == "NumShortTasks").TryCast(); - if (shortTasksOption != null) shortTasksOption.ValidRange = new FloatRange(0f, 23f); + // create TOR settings + createCustomButton(__instance, next++, "TORSettings", "theOtherRolesSettings".Translate()); + createGameOptionsMenu(__instance, CustomOptionType.General, "TORSettings"); + // Guesser if applicable + if (ModOption.gameMode == CustomGamemodes.Guesser) + { + createCustomButton(__instance, next++, "GuesserSettings", "guesserSettings".Translate()); + createGameOptionsMenu(__instance, CustomOptionType.Guesser, "GuesserSettings"); + } + // IMp + createCustomButton(__instance, next++, "ImpostorSettings", "impostorRolesSettings".Translate()); + createGameOptionsMenu(__instance, CustomOptionType.Impostor, "ImpostorSettings"); + + // Neutral + createCustomButton(__instance, next++, "NeutralSettings", "neutralRolesSettings".Translate()); + createGameOptionsMenu(__instance, CustomOptionType.Neutral, "NeutralSettings"); + // Crew + createCustomButton(__instance, next++, "CrewmateSettings", "crewmateRolesSettings".Translate()); + createGameOptionsMenu(__instance, CustomOptionType.Crewmate, "CrewmateSettings"); + // Modifier + createCustomButton(__instance, next++, "ModifierSettings", "modifierSettings".Translate()); + createGameOptionsMenu(__instance, CustomOptionType.Modifier, "ModifierSettings"); - var longTasksOption = __instance.Children.FirstOrDefault(x => x.name == "NumLongTasks").TryCast(); - if (longTasksOption != null) longTasksOption.ValidRange = new FloatRange(0f, 15f); + } } } -[HarmonyPatch(typeof(StringOption), nameof(StringOption.OnEnable))] +[HarmonyPatch(typeof(StringOption), nameof(StringOption.Initialize))] public class StringOptionEnablePatch { public static bool Prefix(StringOption __instance) { - var option = options.FirstOrDefault(option => option.optionBehaviour == __instance); + CustomOption option = options.FirstOrDefault(option => option.optionBehaviour == __instance); if (option == null) return true; - __instance.OnValueChanged = new Action(o => { }); - __instance.TitleText.text = option.getName(); + __instance.OnValueChanged = new Action((o) => { }); + //__instance.TitleText.text = option.getName(); __instance.Value = __instance.oldValue = option.selection; __instance.ValueText.text = option.getString(); @@ -796,9 +965,16 @@ public class StringOptionIncreasePatch { public static bool Prefix(StringOption __instance) { - var option = options.FirstOrDefault(option => option.optionBehaviour == __instance); + CustomOption option = options.FirstOrDefault(option => option.optionBehaviour == __instance); if (option == null) return true; option.updateSelection(option.selection + 1); + /*if (CustomOptionHolder.isMapSelectionOption(option)) + { + var currentGameOptions = GameOptionsManager.Instance.CurrentGameOptions; + currentGameOptions.SetByte(ByteOptionNames.MapId, (byte)option.selection); + GameOptionsManager.Instance.GameHostOptions = GameOptionsManager.Instance.CurrentGameOptions; + GameManager.Instance.LogicOptions.SyncOptions(); + }*/ return false; } } @@ -808,9 +984,16 @@ public class StringOptionDecreasePatch { public static bool Prefix(StringOption __instance) { - var option = options.FirstOrDefault(option => option.optionBehaviour == __instance); + CustomOption option = options.FirstOrDefault(option => option.optionBehaviour == __instance); if (option == null) return true; option.updateSelection(option.selection - 1); + /*if (CustomOptionHolder.isMapSelectionOption(option)) + { + var currentGameOptions = GameOptionsManager.Instance.CurrentGameOptions; + currentGameOptions.SetByte(ByteOptionNames.MapId, (byte)option.selection); + GameOptionsManager.Instance.GameHostOptions = GameOptionsManager.Instance.CurrentGameOptions; + GameManager.Instance.LogicOptions.SyncOptions(); + }*/ return false; } } @@ -821,27 +1004,28 @@ public class StringOptionFixedUpdate public static void Postfix(StringOption __instance) { if (!IL2CPPChainloader.Instance.Plugins.TryGetValue("com.DigiWorm.LevelImposter", out var _)) return; - var option = options.FirstOrDefault(option => option.optionBehaviour == __instance); - if (option == null) return; + CustomOption option = options.FirstOrDefault(option => option.optionBehaviour == __instance); + //if (option == null || !CustomOptionHolder.isMapSelectionOption(option)) return; if (GameOptionsManager.Instance.CurrentGameOptions.MapId == 6) - if (option.optionBehaviour is not null and StringOption stringOption) + if (option.optionBehaviour != null && option.optionBehaviour is StringOption stringOption) { - stringOption.ValueText.text = option.selections[option.selection].ToString(); + stringOption.ValueText.text = option.getString(); } - else if (option.optionBehaviour is not null and StringOption stringOptionToo) + else if (option.optionBehaviour != null && option.optionBehaviour is StringOption stringOptionToo) { stringOptionToo.oldValue = stringOptionToo.Value = option.selection; - stringOptionToo.ValueText.text = option.selections[option.selection].ToString(); + stringOptionToo.ValueText.text = option.getString(); } } } + [HarmonyPatch(typeof(PlayerControl), nameof(PlayerControl.RpcSyncSettings))] public class RpcSyncSettingsPatch { public static void Postfix() { - ShareOptionSelections(); + //CustomOption.ShareOptionSelections(); saveVanillaOptions(); } } @@ -859,73 +1043,19 @@ public static void Postfix() } } -[HarmonyPatch(typeof(GameOptionsMenu), nameof(GameOptionsMenu.Update))] -internal class GameOptionsMenuUpdatePatch -{ - private static float timer = 1f; - - public static void Postfix(GameOptionsMenu __instance) - { - // Return Menu Update if in normal among us settings - var gameSettingMenu = Object.FindObjectsOfType().FirstOrDefault(); - if (gameSettingMenu.RegularGameSettings.active || gameSettingMenu.RolesSettings.gameObject.active) return; - - __instance.GetComponentInParent().ContentYBounds.max = -0.5F + (__instance.Children.Length * 0.55F); - timer += Time.deltaTime; - if (timer < 0.2f) return; - timer = 0f; - - var offset = 2.75f; - foreach (var option in options) - { - if (GameObject.Find("ImpostorSettings") && option.type != CustomOptionType.Impostor) - continue; - if (GameObject.Find("NeutralSettings") && option.type != CustomOptionType.Neutral) - continue; - if (GameObject.Find("CrewmateSettings") && option.type != CustomOptionType.Crewmate) - continue; - if (GameObject.Find("ModifierSettings") && option.type != CustomOptionType.Modifier) - continue; - if (GameObject.Find("GuesserSettings") && option.type != CustomOptionType.Guesser) - continue; - if (option?.optionBehaviour != null && option.optionBehaviour.gameObject != null) - { - var enabled = true; - var parent = option.parent; - while (parent != null && enabled) - { - enabled = parent.selection != 0; - parent = parent.parent; - } - - option.optionBehaviour.gameObject.SetActive(enabled); - if (enabled) - { - offset -= option.isHeader ? 0.75f : 0.5f; - option.optionBehaviour.transform.localPosition = new Vector3( - option.optionBehaviour.transform.localPosition.x, offset, - option.optionBehaviour.transform.localPosition.z); - } - } - } - } -} [HarmonyPatch] internal class GameOptionsDataPatch { - public static int maxPage = 7; - private static string buildRoleOptions() { - var impRoles = $"{"ImpostorRolesText".Translate()}{buildOptionsOfType(CustomOptionType.Impostor, true)}\n"; - var neutralRoles = $"{"NeutralRolesText".Translate()}{buildOptionsOfType(CustomOptionType.Neutral, true)}\n"; - var crewRoles = $"{"CrewmateRolesText".Translate()}{buildOptionsOfType(CustomOptionType.Crewmate, true)}\n"; - var modifiers = $"{"ModifierRolesText".Translate()}{buildOptionsOfType(CustomOptionType.Modifier, true)}"; + var impRoles = buildOptionsOfType(CustomOptionType.Impostor, true) + "\n"; + var neutralRoles = buildOptionsOfType(CustomOptionType.Neutral, true) + "\n"; + var crewRoles = buildOptionsOfType(CustomOptionType.Crewmate, true) + "\n"; + var modifiers = buildOptionsOfType(CustomOptionType.Modifier, true); return impRoles + neutralRoles + crewRoles + modifiers; } - - private static string buildModifierExtras(CustomOption customOption) + public static string buildModifierExtras(CustomOption customOption) { // find options children with quantity var children = options.Where(o => o.parent == customOption); @@ -933,7 +1063,7 @@ private static string buildModifierExtras(CustomOption customOption) if (customOption.GetSelection() == 0) return ""; if (quantity.Count == 1) return $" ({quantity[0].GetQuantity()})"; if (customOption == CustomOptionHolder.modifierLover) - return $" (1 {"EvilLove".Translate()}: {CustomOptionHolder.modifierLoverImpLoverRate.GetSelection() * 10}%)"; + return $" ({"EvilLove".Translate()} {CustomOptionHolder.modifierLoverImpLoverRate.GetSelection() * 10}%)"; return ""; } @@ -943,17 +1073,16 @@ private static string buildOptionsOfType(CustomOptionType type, bool headerOnly) var options = CustomOption.options.Where(o => o.type == type); if (ModOption.gameMode == CustomGamemodes.Guesser) { - if (type == CustomOptionType.General) options = CustomOption.options.Where(o => o.type == type || o.type == CustomOptionType.Guesser); + if (type == CustomOptionType.General) + options = CustomOption.options.Where(o => o.type == type || o.type == CustomOptionType.Guesser); var remove = new List { 10000, 10001, 10002, 10003, 10004, 10005, 10006, 10007, 10008, 30100, 30101, 30102, 30103, 30104 }; options = options.Where(x => !remove.Contains(x.id)); } else if (ModOption.gameMode == CustomGamemodes.Classic) - { - options = options.Where(x => - !(x.type == CustomOptionType.Guesser)); - } + options = options.Where(x => !(x.type == CustomOptionType.Guesser)); foreach (var option in options) + { if (option.parent == null) { var line = $"{option.getName()}: {option.getString()}"; @@ -969,18 +1098,17 @@ private static string buildOptionsOfType(CustomOptionType type, bool headerOnly) else if (option.id == 20135) //Sidekick sb.AppendLine($"- {cs(Jackal.color, "Sidekick".Translate())}: {option.getString()}"); } - + } if (headerOnly) return sb.ToString(); - sb = new StringBuilder(); + else sb = new StringBuilder(); foreach (var option in options) { if (option.parent != null) { - var isIrrelevant = option.parent.GetSelection() == 0 || - (option.parent.parent != null && option.parent.parent.GetSelection() == 0); + var isIrrelevant = option.parent.GetSelection() == 0 || option.parent.parent != null && option.parent.parent.GetSelection() == 0; - var c = isIrrelevant ? Color.grey : Color.white; // No use for now + var c = isIrrelevant ? Color.grey : Color.white; // No use for now if (isIrrelevant) continue; sb.AppendLine(cs(c, $"{option.getName()}: {option.getString()}")); } @@ -1039,18 +1167,17 @@ private static string buildOptionsOfType(CustomOptionType type, bool headerOnly) } } } - return sb.ToString(); } + + public static int maxPage = 7; public static string buildAllOptions(string vanillaSettings = "", bool hideExtras = false) { if (vanillaSettings == "") vanillaSettings = GameOptionsManager.Instance.CurrentGameOptions.ToHudString(PlayerControl.AllPlayerControls.Count); var counter = Main.optionsPage; - var hudString = counter != 0 && !hideExtras - ? cs(DateTime.Now.Second % 2 == 0 ? Color.white : Color.red, "useScrollWheel".Translate()) - : ""; + var hudString = counter != 0 && !hideExtras ? "\n" : ""; maxPage = 7; switch (counter) @@ -1059,26 +1186,26 @@ public static string buildAllOptions(string vanillaSettings = "", bool hideExtra hudString += (!hideExtras ? "" : "page1".Translate()) + vanillaSettings; break; case 1: - hudString += "page2".Translate() + buildOptionsOfType(CustomOptionType.General, false); + hudString += $"{"page2".Translate()}\n{buildOptionsOfType(CustomOptionType.General, false)}"; break; case 2: - hudString += "page3".Translate() + buildRoleOptions(); + hudString += $"{"page3".Translate()}\n{buildRoleOptions()}"; break; case 3: - hudString += "page4".Translate() + buildOptionsOfType(CustomOptionType.Impostor, false); + hudString += $"{"page4".Translate()}\n{buildOptionsOfType(CustomOptionType.Impostor, false)}"; break; case 4: - hudString += "page5".Translate() + buildOptionsOfType(CustomOptionType.Neutral, false); + hudString += $"{"page5".Translate()}\n{buildOptionsOfType(CustomOptionType.Neutral, false)}"; break; case 5: - hudString += "page6".Translate() + buildOptionsOfType(CustomOptionType.Crewmate, false); + hudString += $"{"page6".Translate()}\n{buildOptionsOfType(CustomOptionType.Crewmate, false)}"; break; case 6: - hudString += "page7".Translate() + buildOptionsOfType(CustomOptionType.Modifier, false); + hudString += $"{"page7".Translate()}\n{buildOptionsOfType(CustomOptionType.Modifier, false)}"; break; } - if (!hideExtras || counter != 0) hudString += string.Format("pressTabForMore".Translate(), counter + 1, maxPage); + if (!hideExtras || counter != 0) hudString += string.Format(GetString("pressTabForMore"), counter + 1, maxPage); return hudString; } @@ -1086,9 +1213,8 @@ public static string buildAllOptions(string vanillaSettings = "", bool hideExtra [HarmonyPatch(typeof(IGameOptionsExtensions), nameof(IGameOptionsExtensions.ToHudString))] private static void Postfix(ref string __result) { - if (GameOptionsManager.Instance.currentGameOptions.GameMode == GameModes.HideNSeek) - return; // Allow Vanilla Hide N Seek - __result = buildAllOptions(__result); + if (GameOptionsManager.Instance.currentGameOptions.GameMode == GameModes.HideNSeek) return; // Allow Vanilla Hide N Seek + __result = buildAllOptions(vanillaSettings: __result); } } @@ -1097,31 +1223,29 @@ public class AddToKillDistanceSetting { [HarmonyPatch(typeof(GameOptionsData), nameof(GameOptionsData.AreInvalid))] [HarmonyPrefix] + public static bool Prefix(GameOptionsData __instance, ref int maxExpectedPlayers) { //making the killdistances bound check higher since extra short is added return __instance.MaxPlayers > maxExpectedPlayers || __instance.NumImpostors < 1 - || __instance.NumImpostors > 3 || __instance.KillDistance < 0 - || __instance.KillDistance >= - GameOptionsData.KillDistances.Count - || __instance.PlayerSpeedMod <= 0f || - __instance.PlayerSpeedMod > 3f; + || __instance.NumImpostors > 3 || __instance.KillDistance < 0 + || __instance.KillDistance >= GameOptionsData.KillDistances.Count + || __instance.PlayerSpeedMod <= 0f || __instance.PlayerSpeedMod > 3f; } - [HarmonyPatch(typeof(NormalGameOptionsV07), nameof(NormalGameOptionsV07.AreInvalid))] + [HarmonyPatch(typeof(NormalGameOptionsV08), nameof(NormalGameOptionsV08.AreInvalid))] [HarmonyPrefix] - public static bool Prefix(NormalGameOptionsV07 __instance, ref int maxExpectedPlayers) + public static bool Prefix(NormalGameOptionsV08 __instance, ref int maxExpectedPlayers) { return __instance.MaxPlayers > maxExpectedPlayers || __instance.NumImpostors < 1 - || __instance.NumImpostors > 3 || __instance.KillDistance < 0 - || __instance.KillDistance >= - GameOptionsData.KillDistances.Count - || __instance.PlayerSpeedMod <= 0f || - __instance.PlayerSpeedMod > 3f; + || __instance.NumImpostors > 3 || __instance.KillDistance < 0 + || __instance.KillDistance >= GameOptionsData.KillDistances.Count + || __instance.PlayerSpeedMod <= 0f || __instance.PlayerSpeedMod > 3f; } - [HarmonyPatch(typeof(StringOption), nameof(StringOption.OnEnable))] + [HarmonyPatch(typeof(StringOption), nameof(StringOption.Initialize))] [HarmonyPrefix] + public static void Prefix(StringOption __instance) { //prevents indexoutofrange exception breaking the setting if long happens to be selected @@ -1134,20 +1258,19 @@ public static void Prefix(StringOption __instance) } } - [HarmonyPatch(typeof(StringOption), nameof(StringOption.OnEnable))] + [HarmonyPatch(typeof(StringOption), nameof(StringOption.Initialize))] [HarmonyPostfix] + public static void Postfix(StringOption __instance) { if (__instance.Title == StringNames.GameKillDistance && __instance.Values.Count == 3) - __instance.Values = new Il2CppStructArray( - new[] - { - (StringNames)49999, StringNames.SettingShort, StringNames.SettingMedium, StringNames.SettingLong - }); + { + __instance.Values = new([(StringNames)49999, StringNames.SettingShort, StringNames.SettingMedium, StringNames.SettingLong]); + } } [HarmonyPatch(typeof(IGameOptionsExtensions), nameof(IGameOptionsExtensions.AppendItem), - typeof(Il2CppSystem.Text.StringBuilder), typeof(StringNames), typeof(string))] + [typeof(Il2CppSystem.Text.StringBuilder), typeof(StringNames), typeof(string)])] [HarmonyPrefix] public static void Prefix(ref StringNames stringName, ref string value) { @@ -1164,9 +1287,10 @@ public static void Prefix(ref StringNames stringName, ref string value) } } - [HarmonyPatch(typeof(TranslationController), nameof(TranslationController.GetString), typeof(StringNames), - typeof(Il2CppReferenceArray))] + [HarmonyPatch(typeof(TranslationController), nameof(TranslationController.GetString), + new[] { typeof(StringNames), typeof(Il2CppReferenceArray) })] [HarmonyPriority(Priority.Last)] + public static bool Prefix(ref string __result, ref StringNames id) { if ((int)id == 49999) @@ -1174,14 +1298,13 @@ public static bool Prefix(ref string __result, ref StringNames id) __result = "KillDistancesVeryShort".Translate(); return false; } - return true; } public static void addKillDistance() { - GameOptionsData.KillDistances = new Il2CppStructArray([0.6f, 1f, 1.8f, 2.5f]); - GameOptionsData.KillDistanceStrings = new Il2CppStringArray(["Very Short", "Short", "Medium", "Long"]); + GameOptionsData.KillDistances = new([0.5f, 1f, 1.8f, 2.5f]); + GameOptionsData.KillDistanceStrings = new(["Very Short", "Short", "Medium", "Long"]); } } @@ -1191,75 +1314,54 @@ public static class GameOptionsNextPagePatch public static void Postfix(KeyboardJoystick __instance) { var page = Main.optionsPage; - if (Input.GetKeyDown(KeyCode.Tab)) Main.optionsPage = (Main.optionsPage + 1) % 7; - if (Input.GetKeyDown(KeyCode.Alpha1) || Input.GetKeyDown(KeyCode.Keypad1)) Main.optionsPage = 0; - if (Input.GetKeyDown(KeyCode.Alpha2) || Input.GetKeyDown(KeyCode.Keypad2)) Main.optionsPage = 1; - if (Input.GetKeyDown(KeyCode.Alpha3) || Input.GetKeyDown(KeyCode.Keypad3)) Main.optionsPage = 2; - if (Input.GetKeyDown(KeyCode.Alpha4) || Input.GetKeyDown(KeyCode.Keypad4)) Main.optionsPage = 3; - if (Input.GetKeyDown(KeyCode.Alpha5) || Input.GetKeyDown(KeyCode.Keypad5)) Main.optionsPage = 4; - if (Input.GetKeyDown(KeyCode.Alpha6) || Input.GetKeyDown(KeyCode.Keypad6)) Main.optionsPage = 5; - if (Input.GetKeyDown(KeyCode.Alpha7) || Input.GetKeyDown(KeyCode.Keypad7)) Main.optionsPage = 6; - if (Input.GetKeyDown(ModInputManager.showOptionPageInput.keyCode)) HudManagerUpdate.ToggleSettings(HudManager.Instance); + if (Input.GetKeyDown(KeyCode.Tab)) + Main.optionsPage = (Main.optionsPage + 1) % 7; + if (Input.GetKeyDown(KeyCode.Alpha1) || Input.GetKeyDown(KeyCode.Keypad1)) + Main.optionsPage = 0; + if (Input.GetKeyDown(KeyCode.Alpha2) || Input.GetKeyDown(KeyCode.Keypad2)) + Main.optionsPage = 1; + if (Input.GetKeyDown(KeyCode.Alpha3) || Input.GetKeyDown(KeyCode.Keypad3)) + Main.optionsPage = 2; + if (Input.GetKeyDown(KeyCode.Alpha4) || Input.GetKeyDown(KeyCode.Keypad4)) + Main.optionsPage = 3; + if (Input.GetKeyDown(KeyCode.Alpha5) || Input.GetKeyDown(KeyCode.Keypad5)) + Main.optionsPage = 4; + if (Input.GetKeyDown(KeyCode.Alpha6) || Input.GetKeyDown(KeyCode.Keypad6)) + Main.optionsPage = 5; + if (Input.GetKeyDown(KeyCode.Alpha7) || Input.GetKeyDown(KeyCode.Keypad7)) + Main.optionsPage = 6; + if (Input.GetKeyDown(ModInputManager.showOptionPageInput.keyCode)) + HudManagerUpdate.ToggleSettings(HudManager.Instance); if (Main.optionsPage >= GameOptionsDataPatch.maxPage) Main.optionsPage = 0; - - if (page != Main.optionsPage) - { - var position = (Vector3)FastDestroyableSingleton.Instance?.GameSettings?.transform.localPosition; - FastDestroyableSingleton.Instance.GameSettings.transform.localPosition = new Vector3(position.x, 2.9f, position.z); - } - - if (Input.GetKeyDown(ModInputManager.helpInput.keyCode)) - { - if (LobbyRoleInfo.RolesSummaryUI == null) - LobbyRoleInfo.RoleSummaryOnClick(); - else - { - Object.Destroy(LobbyRoleInfo.RolesSummaryUI); - LobbyRoleInfo.RolesSummaryUI = null; - } - } } } -[HarmonyPatch(typeof(HudManager), nameof(HudManager.Update))] -public class GameSettingsScalePatch -{ - public static void Prefix(HudManager __instance) - { - if (__instance.GameSettings != null) __instance.GameSettings.fontSize = 1.2f; - } -} -// This class is taken and adapted from Town of Us Reactivated, https://github.com/eDonnes124/Town-Of-Us-R/blob/master/source/Patches/CustomOption/Patches.cs, Licensed under GPLv3 +//This class is taken and adapted from Town of Us Reactivated, https://github.com/eDonnes124/Town-Of-Us-R/blob/master/source/Patches/CustomOption/Patches.cs, Licensed under GPLv3 [HarmonyPatch(typeof(HudManager), nameof(HudManager.Update))] public class HudManagerUpdate { +#pragma warning disable CS0649 + private static readonly TextMeshPro GameSettings; public static float - MinX, /*-5.3F*/ + MinX,/*-5.3F*/ OriginalY = 2.9F, MinY = 2.9F; - public static Scroller Scroller; private static Vector3 LastPosition; private static float lastAspect; private static bool setLastPosition; - private static readonly TextMeshPro[] settingsTMPs = new TextMeshPro[4]; - private static GameObject settingsBackground; - - private static PassiveButton toggleSettingsButton; - private static GameObject toggleSettingsButtonObject; - public static void Prefix(HudManager __instance) { - if (__instance.GameSettings?.transform == null) return; + if (GameSettings?.transform == null) return; // Sets the MinX position to the left edge of the screen + 0.1 units var safeArea = Screen.safeArea; var aspect = Mathf.Min(Camera.main.aspect, safeArea.width / safeArea.height); var safeOrthographicSize = CameraSafeArea.GetSafeOrthographicSize(Camera.main); - MinX = 0.1f - (safeOrthographicSize * aspect); + MinX = 0.1f - safeOrthographicSize * aspect; if (!setLastPosition || aspect != lastAspect) { @@ -1271,38 +1373,38 @@ public static void Prefix(HudManager __instance) CreateScroller(__instance); - Scroller.gameObject.SetActive(__instance.GameSettings.gameObject.activeSelf); + Scroller.gameObject.SetActive(GameSettings.gameObject.activeSelf); if (!Scroller.gameObject.active) return; - var rows = __instance.GameSettings.text.Count(c => c == '\n'); - var LobbyTextRowHeight = 0.12F; - var maxY = Mathf.Max(MinY, (rows * LobbyTextRowHeight) + ((rows - 38) * LobbyTextRowHeight)); + var rows = GameSettings.text.Count(c => c == '\n'); + var LobbyTextRowHeight = 0.06F; + var maxY = Mathf.Max(MinY, rows * LobbyTextRowHeight + (rows - 38) * LobbyTextRowHeight); Scroller.ContentYBounds = new FloatRange(MinY, maxY); // Prevent scrolling when the player is interacting with a menu if (CachedPlayer.LocalPlayer?.PlayerControl.CanMove != true) { - __instance.GameSettings.transform.localPosition = LastPosition; + GameSettings.transform.localPosition = LastPosition; return; } - if (__instance.GameSettings.transform.localPosition.x != MinX || - __instance.GameSettings.transform.localPosition.y < MinY) return; + if (GameSettings.transform.localPosition.x != MinX || + GameSettings.transform.localPosition.y < MinY) return; - LastPosition = __instance.GameSettings.transform.localPosition; + LastPosition = GameSettings.transform.localPosition; } private static void CreateScroller(HudManager __instance) { if (Scroller != null) return; - var target = __instance.GameSettings.transform; + var target = GameSettings.transform; Scroller = new GameObject("SettingsScroller").AddComponent(); - Scroller.transform.SetParent(__instance.GameSettings.transform.parent); + Scroller.transform.SetParent(GameSettings.transform.parent); Scroller.gameObject.layer = 5; Scroller.transform.localScale = Vector3.one; @@ -1324,7 +1426,7 @@ public static void Prefix2(HudManager __instance) if (!settingsTMPs[0]) return; foreach (var tmp in settingsTMPs) tmp.text = ""; var settingsString = GameOptionsDataPatch.buildAllOptions(hideExtras: true); - var blocks = settingsString.Split("\n\n", StringSplitOptions.RemoveEmptyEntries); + var blocks = settingsString.Split("\n\n", StringSplitOptions.RemoveEmptyEntries); ; var curString = ""; string curBlock; var j = 0; @@ -1346,19 +1448,22 @@ public static void Prefix2(HudManager __instance) if (j < settingsTMPs.Length) settingsTMPs[j].text = curString; var blockCount = 0; foreach (var tmp in settingsTMPs) + { if (tmp.text != "") blockCount++; + } for (var i = 0; i < blockCount; i++) + { settingsTMPs[i].transform.localPosition = new Vector3(-blockCount * 1.2f + 2.7f * i, 2.2f, -500f); + } } + private static TextMeshPro[] settingsTMPs = new TextMeshPro[4]; + private static GameObject settingsBackground; public static void OpenSettings(HudManager __instance) { - if (__instance.FullScreen == null || (MapBehaviour.Instance && MapBehaviour.Instance.IsOpen) - /*|| AmongUsClient.Instance.GameState != InnerNet.InnerNetClient.GameStates.Started*/ - || GameOptionsManager.Instance.currentGameOptions.GameMode == - GameModes.HideNSeek) return; - settingsBackground = Object.Instantiate(__instance.FullScreen.gameObject, __instance.transform); + if (__instance.FullScreen == null || MapBehaviour.Instance && MapBehaviour.Instance.IsOpen) return; + settingsBackground = UnityEngine.Object.Instantiate(__instance.FullScreen.gameObject, __instance.transform); settingsBackground.SetActive(true); var renderer = settingsBackground.GetComponent(); renderer.color = new Color(0.2f, 0.2f, 0.2f, 0.9f); @@ -1366,7 +1471,7 @@ public static void OpenSettings(HudManager __instance) for (var i = 0; i < settingsTMPs.Length; i++) { - settingsTMPs[i] = Object.Instantiate(__instance.KillButton.cooldownTimerText, __instance.transform); + settingsTMPs[i] = UnityEngine.Object.Instantiate(__instance.KillButton.cooldownTimerText, __instance.transform); settingsTMPs[i].alignment = TextAlignmentOptions.TopLeft; settingsTMPs[i].enableWordWrapping = false; settingsTMPs[i].transform.localScale = Vector3.one * 0.25f; @@ -1377,8 +1482,7 @@ public static void OpenSettings(HudManager __instance) public static void CloseSettings() { foreach (var tmp in settingsTMPs) - if (tmp) - tmp.gameObject.Destroy(); + if (tmp) tmp.gameObject.Destroy(); if (settingsBackground) settingsBackground.Destroy(); } @@ -1389,54 +1493,55 @@ public static void ToggleSettings(HudManager __instance) else OpenSettings(__instance); } + private static PassiveButton toggleSettingsButton; + private static GameObject toggleSettingsButtonObject; + private static GameObject toggleZoomButtonObject; + private static PassiveButton toggleZoomButton; + + [HarmonyPostfix] public static void Postfix(HudManager __instance) { + if (AmongUsClient.Instance.GameState != InnerNet.InnerNetClient.GameStates.Started) return; if (!toggleSettingsButton || !toggleSettingsButtonObject) { // add a special button for settings viewing: - toggleSettingsButtonObject = Object.Instantiate(__instance.MapButton.gameObject, __instance.MapButton.transform.parent); - toggleSettingsButtonObject.transform.localPosition = __instance.MapButton.transform.localPosition + new Vector3(0, -0.66f, -500f); - var renderer = toggleSettingsButtonObject.GetComponent(); - renderer.sprite = new ResourceSprite("TheOtherRoles.Resources.CurrentSettingsButton.png", 180f); + toggleSettingsButtonObject = UnityEngine.Object.Instantiate(__instance.MapButton.gameObject, __instance.MapButton.transform.parent); + toggleSettingsButtonObject.transform.localPosition = __instance.MapButton.transform.localPosition + new Vector3(0, -1.25f, -500f); + toggleSettingsButtonObject.name = "TOGGLESETTINGSBUTTON"; + var renderer = toggleSettingsButtonObject.transform.Find("Inactive").GetComponent(); + var rendererActive = toggleSettingsButtonObject.transform.Find("Active").GetComponent(); + toggleSettingsButtonObject.transform.Find("Background").localPosition = Vector3.zero; + renderer.sprite = UnityHelper.loadSpriteFromResources("TheOtherRoles.Resources.Settings_Button.png", 100f); + rendererActive.sprite = UnityHelper.loadSpriteFromResources("TheOtherRoles.Resources.Settings_ButtonActive.png", 100); toggleSettingsButton = toggleSettingsButtonObject.GetComponent(); toggleSettingsButton.OnClick.RemoveAllListeners(); toggleSettingsButton.OnClick.AddListener((Action)(() => ToggleSettings(__instance))); - _ = CustomButton.SetKeyGuideOnSmallButton(toggleSettingsButtonObject, ModInputManager.showOptionPageInput.keyCode); } + toggleSettingsButtonObject.SetActive(__instance.MapButton.gameObject.active && !(MapBehaviour.Instance && MapBehaviour.Instance.IsOpen) && GameOptionsManager.Instance.currentGameOptions.GameMode != GameModes.HideNSeek); + toggleSettingsButtonObject.transform.localPosition = __instance.MapButton.transform.localPosition + new Vector3(0, -0.8f, -500f); - toggleSettingsButtonObject.SetActive(__instance.MapButton.gameObject.active && !IsHideNSeek && !(MapBehaviour.Instance && MapBehaviour.Instance.IsOpen)); - toggleSettingsButtonObject.transform.localPosition = __instance.MapButton.transform.localPosition + new Vector3(0, -0.66f, -500f); - } - - private static PassiveButton rolesSummaryButton; - private static GameObject rolesSummaryButtonObject; - [HarmonyPostfix] - public static void Postfix2(HudManager __instance) - { - if (!rolesSummaryButton || !rolesSummaryButtonObject) + if (!toggleZoomButton || !toggleZoomButtonObject) { // add a special button for settings viewing: - rolesSummaryButtonObject = Object.Instantiate(__instance.MapButton.gameObject, __instance.MapButton.transform.parent); - rolesSummaryButtonObject.transform.localPosition = __instance.MapButton.transform.localPosition + new Vector3(0, -1.31f, -500f); - var renderer = rolesSummaryButtonObject.GetComponent(); - renderer.sprite = new ResourceSprite("TheOtherRoles.Resources.HelpButton.png", 100f); - rolesSummaryButton = rolesSummaryButtonObject.GetComponent(); - rolesSummaryButton.OnClick.RemoveAllListeners(); - rolesSummaryButton.OnClick.AddListener((Action)(() => - { - if (LobbyRoleInfo.RolesSummaryUI == null) - LobbyRoleInfo.RoleSummaryOnClick(); - else - { - Object.Destroy(LobbyRoleInfo.RolesSummaryUI); - LobbyRoleInfo.RolesSummaryUI = null; - } - })); - _ = CustomButton.SetKeyGuideOnSmallButton(rolesSummaryButtonObject, ModInputManager.helpInput.keyCode); + toggleZoomButtonObject = UnityEngine.Object.Instantiate(__instance.MapButton.gameObject, __instance.MapButton.transform.parent); + toggleZoomButtonObject.transform.localPosition = __instance.MapButton.transform.localPosition + new Vector3(0, -1.25f, -500f); + toggleZoomButtonObject.name = "TOGGLEZOOMBUTTON"; + var tZrenderer = toggleZoomButtonObject.transform.Find("Inactive").GetComponent(); + var tZArenderer = toggleZoomButtonObject.transform.Find("Active").GetComponent(); + toggleZoomButtonObject.transform.Find("Background").localPosition = Vector3.zero; + tZrenderer.sprite = UnityHelper.loadSpriteFromResources("TheOtherRoles.Resources.Minus_Button.png", 100f); + tZArenderer.sprite = UnityHelper.loadSpriteFromResources("TheOtherRoles.Resources.Minus_ButtonActive.png", 100); + toggleZoomButton = toggleZoomButtonObject.GetComponent(); + toggleZoomButton.OnClick.RemoveAllListeners(); + toggleZoomButton.OnClick.AddListener((Action)(() => toggleZoom())); } - - rolesSummaryButtonObject.SetActive(__instance.MapButton.gameObject.active && !IsHideNSeek && !(MapBehaviour.Instance && MapBehaviour.Instance.IsOpen)); - rolesSummaryButtonObject.transform.localPosition = __instance.MapButton.transform.transform.localPosition + new Vector3(0, -1.31f, -500f); + var (playerCompleted, playerTotal) = TasksHandler.taskInfo(CachedPlayer.LocalPlayer.Data); + var numberOfLeftTasks = playerTotal - playerCompleted; + var zoomButtonActive = !(CachedPlayer.LocalPlayer.PlayerControl == null || !CachedPlayer.LocalPlayer.Data.IsDead || CachedPlayer.LocalPlayer.Data.Role.IsImpostor && !CustomOptionHolder.deadImpsBlockSabotage.GetBool()); + zoomButtonActive &= numberOfLeftTasks <= 0 || !CustomOptionHolder.finishTasksBeforeHauntingOrZoomingOut.GetBool(); + toggleZoomButtonObject.SetActive(zoomButtonActive); + var posOffset = zoomOutStatus ? new Vector3(-1.27f, -7.92f, -52f) : new Vector3(0, -1.6f, -52f); + toggleZoomButtonObject.transform.localPosition = HudManager.Instance.MapButton.transform.localPosition + posOffset; } -} \ No newline at end of file +} diff --git a/TheOtherRoles/Options/ModOption.cs b/TheOtherRoles/Options/ModOption.cs index 74f58e5e..e3cbec2c 100644 --- a/TheOtherRoles/Options/ModOption.cs +++ b/TheOtherRoles/Options/ModOption.cs @@ -12,7 +12,7 @@ internal class ModOption public static int NumImpostors => GameOptionsManager.Instance.currentNormalGameOptions.NumImpostors; public static bool DebugMode => CustomOptionHolder.debugMode.GetBool(); public static bool DisableGameEnd => DebugMode && CustomOptionHolder.disableGameEnd.GetBool(); - public static NormalGameOptionsV07 NormalOptions => GameOptionsManager.Instance.currentNormalGameOptions; + public static NormalGameOptionsV08 NormalOptions => GameOptionsManager.Instance.currentNormalGameOptions; // Set values public static int maxNumberOfMeetings = 10; @@ -34,6 +34,8 @@ internal class ModOption public static bool randomLigherPlayer; public static bool disableMedscanWalking; public static bool isCanceled; + public static bool ShowChatNotifications = true; + public static bool MuteLobbyBGM; public static int restrictDevices; @@ -122,6 +124,8 @@ public static void reloadPluginOptions() enableSoundEffects = Main.EnableSoundEffects.Value; showKeyReminder = Main.ShowKeyReminder.Value; localHats = Main.LocalHats.Value; + ShowChatNotifications = Main.ShowChatNotifications.Value; + MuteLobbyBGM = Main.MuteLobbyBGM.Value; } public static void resetDeviceTimes() diff --git a/TheOtherRoles/Patches/CredentialsPatch.cs b/TheOtherRoles/Patches/CredentialsPatch.cs index 99177fca..f39e7725 100644 --- a/TheOtherRoles/Patches/CredentialsPatch.cs +++ b/TheOtherRoles/Patches/CredentialsPatch.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System.Collections.Generic; +using AmongUs.GameOptions; using InnerNet; using TMPro; using UnityEngine; @@ -23,34 +24,59 @@ internal static class PingTrackerPatch private static void Postfix(PingTracker __instance) { - DeltaTime += (Time.deltaTime - DeltaTime) * 0.1f; var fps = Mathf.Ceil(1f / DeltaTime); - var PingText = $"Ping: {AmongUsClient.Instance.Ping}ms{(ModOption.showFPS ? $" FPS: {fps}" : "")}"; - __instance.text.SetOutlineThickness(0.1f); + var pingText = $"Ping: {AmongUsClient.Instance.Ping}ms{(ModOption.showFPS ? $" FPS: {fps}" : "")}"; var host = $"{"Host".Translate()}: {GameData.Instance?.GetHost()?.PlayerName}"; - - __instance.text.alignment = TextAlignmentOptions.TopRight; + __instance.text.SetOutlineThickness(0.01f); var position = __instance.GetComponent(); var gameModeText = ModOption.gameMode switch { CustomGamemodes.Guesser => GetString("isGuesserGm"), + CustomGamemodes.Classic => GetString("isClassicGM"), _ => "" }; if (ModOption.DebugMode) gameModeText += "(Debug Mode)"; - if (gameModeText != "") gameModeText = cs(Color.yellow, gameModeText) + "\n"; + + if (!string.IsNullOrEmpty(gameModeText)) gameModeText = cs(Color.yellow, gameModeText) + "\n"; + if (AmongUsClient.Instance.GameState == InnerNetClient.GameStates.Started) { - __instance.text.text = $"{GetString("TouTitle")} v{Main.Version + "\n" + GetString("inGameTitle")}\n{PingText}\n{gameModeText}"; - position.DistanceFromEdge = new Vector3(2.25f, 0.1f, 0); + __instance.text.alignment = TextAlignmentOptions.TopRight; + position.Alignment = AspectPosition.EdgeAlignments.RightTop; + __instance.text.text = $"{GetString("TouTitle")} v{Main.Version}\n{GetString("inGameTitle")}\n{gameModeText}{pingText}"; + position.DistanceFromEdge = new Vector3(2.7f, 0.1f, 0); } else { - __instance.text.text = $"{fullCredentialsVersion}\n {PingText}\n {gameModeText + fullCredentials}\n {host}"; - position.DistanceFromEdge = new Vector3(2.85f, 0.1f, 0); + __instance.text.alignment = TextAlignmentOptions.TopLeft; + position.Alignment = AspectPosition.EdgeAlignments.LeftTop; + __instance.text.text = $"{fullCredentialsVersion}\n{pingText}\n{gameModeText}{fullCredentials}\n{host}"; + position.DistanceFromEdge = new(0.4f, 0.06f); + try + { + UpdateGameModeText(); + } + catch { } } position.AdjustPosition(); } + + private static void UpdateGameModeText() + { + var gameModeText = ModOption.gameMode switch + { + CustomGamemodes.Guesser => GetString("isGuesserGm"), + CustomGamemodes.Classic => GetString("isClassicGM"), + _ => "" + }; + gameModeText = cs(Color.yellow, gameModeText); + var GameModeText = GameObject.Find("GameModeText")?.GetComponent(); + GameModeText.text = string.IsNullOrEmpty(gameModeText) ? (GameOptionsManager.Instance.currentGameOptions.GameMode + == GameModes.HideNSeek ? "isVanHideNSeekGM".Translate() : "isClassicGM".Translate()) : gameModeText; + var modeLabel = GameObject.Find("ModeLabel")?.GetComponentInChildren(); + modeLabel.text = "GameMode".Translate(); + } } [HarmonyPatch(typeof(MainMenuManager), nameof(MainMenuManager.Start))] diff --git a/TheOtherRoles/Patches/EndGamePatch.cs b/TheOtherRoles/Patches/EndGamePatch.cs index c6ffdc88..9e088a8b 100644 --- a/TheOtherRoles/Patches/EndGamePatch.cs +++ b/TheOtherRoles/Patches/EndGamePatch.cs @@ -3,6 +3,7 @@ using System.Linq; using System.Text; using AmongUs.GameOptions; +using TheOtherRoles.Roles.Neutral; using TheOtherRoles.Utilities; using TMPro; using UnityEngine; @@ -106,6 +107,8 @@ public static void Prefix(AmongUsClient __instance, [HarmonyArgument(0)] ref End public static void Postfix(AmongUsClient __instance, [HarmonyArgument(0)] ref EndGameResult endGameResult) { + EndGameResult.CachedWinners = new Il2CppSystem.Collections.Generic.List(); + AdditionalTempData.clear(); List killRole = [ @@ -172,12 +175,6 @@ public static void Postfix(AmongUsClient __instance, [HarmonyArgument(0)] ref En notWinners.AddRange(Survivor.Player.Where(p => p != null)); if (Akujo.honmeiCannotFollowWin && Akujo.honmei != null) notWinners.Add(Akujo.honmei); - var winnersToRemove = new List(); - foreach (var winner in TempData.winners.GetFastEnumerator()) - if (notWinners.Any(x => x != null && x.Data.PlayerName == winner.PlayerName)) - winnersToRemove.Add(winner); - - foreach (var winner in winnersToRemove) TempData.winners.Remove(winner); var isCanceled = gameOverReason == (GameOverReason)CustomGameOverReason.Canceled; var everyoneDead = AdditionalTempData.playerRoles.All(x => !x.IsAlive); var miniLose = Mini.mini != null && gameOverReason == (GameOverReason)CustomGameOverReason.MiniLose; @@ -196,6 +193,8 @@ public static void Postfix(AmongUsClient __instance, [HarmonyArgument(0)] ref En (Jackal.jackal.Any(x => x.IsAlive()) || Jackal.sidekick.IsAlive()); var teamPavlovsWin = gameOverReason == (GameOverReason)CustomGameOverReason.TeamPavlovsWin && (Pavlovsdogs.pavlovsowner.IsAlive() || Pavlovsdogs.pavlovsdogs.Any(p => p.IsAlive())); + var crewmateWin = GameManager.Instance.DidHumansWin(gameOverReason) || + (gameOverReason is GameOverReason.HumansByVote or GameOverReason.HumansByTask); var vultureWin = Vulture.vulture != null && gameOverReason == (GameOverReason)CustomGameOverReason.VultureWin; var executionerWin = Executioner.executioner != null && gameOverReason == (GameOverReason)CustomGameOverReason.ExecutionerWin; var lawyerSoloWin = Lawyer.lawyer != null && gameOverReason == (GameOverReason)CustomGameOverReason.LawyerSoloWin; @@ -206,70 +205,55 @@ public static void Postfix(AmongUsClient __instance, [HarmonyArgument(0)] ref En : gameOverReason == (GameOverReason)CustomGameOverReason.AkujoWin); bool isPursurerLose = jesterWin || arsonistWin || miniLose || isCanceled || executionerWin; + var winners = new List(); + var isYou = true; + var isImpostor = false; + // Mini lose if (miniLose) { // If "no one is the Mini", it will display the Mini, but also show defeat to everyone - TempData.winners = new Il2CppSystem.Collections.Generic.List(); - var wpd = new WinningPlayerData(Mini.mini.Data) { IsYou = false }; - TempData.winners.Add(wpd); + winners.Add(Mini.mini.Data); + isYou = false; AdditionalTempData.winCondition = WinCondition.MiniLose; } - else if (isCanceled) + else if (isCanceled || everyoneDead) { - TempData.winners = new Il2CppSystem.Collections.Generic.List(); AdditionalTempData.winCondition = WinCondition.Canceled; } // Jester win - else if (jesterWin) + if (jesterWin) { - TempData.winners = new Il2CppSystem.Collections.Generic.List(); - var wpd = new WinningPlayerData(Jester.jester.Data); - TempData.winners.Add(wpd); + winners.Add(Jester.jester.Data); AdditionalTempData.winCondition = WinCondition.JesterWin; } // Witness win else if (witnessWin) { - TempData.winners = new Il2CppSystem.Collections.Generic.List(); - var wpd = new WinningPlayerData(Witness.Player.Data); - TempData.winners.Add(wpd); + winners.Add(Witness.Player.Data); AdditionalTempData.winCondition = WinCondition.WitnessWin; } // Arsonist win else if (arsonistWin) { - TempData.winners = new Il2CppSystem.Collections.Generic.List(); - var wpd = new WinningPlayerData(Arsonist.arsonist.Data); - TempData.winners.Add(wpd); + winners.Add(Arsonist.arsonist.Data); AdditionalTempData.winCondition = WinCondition.ArsonistWin; } - // Everyone Died - else if (everyoneDead) - { - TempData.winners = new Il2CppSystem.Collections.Generic.List(); - AdditionalTempData.winCondition = WinCondition.EveryoneDied; - } - // Vulture win else if (vultureWin) { - TempData.winners = new Il2CppSystem.Collections.Generic.List(); - var wpd = new WinningPlayerData(Vulture.vulture.Data); - TempData.winners.Add(wpd); + winners.Add(Vulture.vulture.Data); AdditionalTempData.winCondition = WinCondition.VultureWin; } // Jester win else if (executionerWin) { - TempData.winners = new Il2CppSystem.Collections.Generic.List(); - var wpd = new WinningPlayerData(Executioner.executioner.Data); - TempData.winners.Add(wpd); + winners.Add(Executioner.executioner.Data); AdditionalTempData.winCondition = WinCondition.ExecutionerWin; } @@ -280,106 +264,84 @@ public static void Postfix(AmongUsClient __instance, [HarmonyArgument(0)] ref En if (!Lovers.existingWithKiller()) { AdditionalTempData.winCondition = WinCondition.LoversTeamWin; - TempData.winners = new Il2CppSystem.Collections.Generic.List(); foreach (PlayerControl p in CachedPlayer.AllPlayers) { if (p == null) continue; if (p == Lovers.lover1 || p == Lovers.lover2) - TempData.winners.Add(new WinningPlayerData(p.Data)); + winners.Add(p.Data); else if (Pursuer.Player.Any(pc => pc == p) && Pursuer.Player.Any(pc => pc.IsAlive())) - TempData.winners.Add(new WinningPlayerData(p.Data)); + winners.Add(p.Data); else if (Survivor.Player.Any(pc => pc == p) && Survivor.Player.Any(pc => pc.IsAlive())) - TempData.winners.Add(new WinningPlayerData(p.Data)); + winners.Add(p.Data); else if (!notWinners.Contains(p) && !p.Data.Role.IsImpostor) - TempData.winners.Add(new WinningPlayerData(p.Data)); + winners.Add(p.Data); } } // Lovers solo win else { - AdditionalTempData.winCondition = WinCondition.LoversSoloWin; - TempData.winners = new Il2CppSystem.Collections.Generic.List(); - TempData.winners.Add(new WinningPlayerData(Lovers.lover1.Data)); - TempData.winners.Add(new WinningPlayerData(Lovers.lover2.Data)); + winners.Add(Lovers.lover1.Data); + winners.Add(Lovers.lover2.Data); + } + } + + else if (crewmateWin) + { + AdditionalTempData.winCondition = WinCondition.TaskerWin; + foreach (var player in CachedPlayer.AllPlayers) + { + if (player == null) continue; + if (!player.Data.Role.IsImpostor && !notWinners.Contains(player)) + winners.Add(player.Data); + } + } + + else if (impostorWin) + { + isImpostor = true; + foreach (NetworkedPlayerInfo player in GameData.Instance.AllPlayers) + { + if (player.Role.IsImpostor) + winners.Add(player); } } // Jackal win condition (should be implemented using a proper GameOverReason in the future) else if (teamJackalWin) { - // Jackal wins if nobody except jackal is alive AdditionalTempData.winCondition = WinCondition.JackalWin; - TempData.winners = new Il2CppSystem.Collections.Generic.List(); foreach (var player in Jackal.jackal) - { - var wpdFormerJackal = new WinningPlayerData(player.Data); - wpdFormerJackal.IsImpostor = false; - TempData.winners.Add(wpdFormerJackal); - } - // If there is a sidekick. The sidekick also wins + winners.Add(player.Data); if (Jackal.sidekick != null) - { - var wpdSidekick = new WinningPlayerData(Jackal.sidekick.Data); - wpdSidekick.IsImpostor = false; - TempData.winners.Add(wpdSidekick); - } + winners.Add(Jackal.sidekick.Data); } + else if (teamPavlovsWin) { - // Jackal wins if nobody except jackal is alive AdditionalTempData.winCondition = WinCondition.PavlovsWin; - TempData.winners = new Il2CppSystem.Collections.Generic.List(); - var wpd = new WinningPlayerData(Pavlovsdogs.pavlovsowner.Data); - wpd.IsImpostor = false; - TempData.winners.Add(wpd); + winners.Add(Pavlovsdogs.pavlovsowner.Data); foreach (var player in Pavlovsdogs.pavlovsdogs) - { - var wpdFormerPavlovs = new WinningPlayerData(player.Data); - wpdFormerPavlovs.IsImpostor = false; - TempData.winners.Add(wpdFormerPavlovs); - } + winners.Add(player.Data); } + else if (werewolfWin) { - // Werewolf wins if nobody except jackal is alive AdditionalTempData.winCondition = WinCondition.WerewolfWin; - TempData.winners = new Il2CppSystem.Collections.Generic.List(); - var wpd = new WinningPlayerData(Werewolf.werewolf.Data); - wpd.IsImpostor = false; - TempData.winners.Add(wpd); + winners.Add(Werewolf.werewolf.Data); } else if (juggernautWin) { // JuggernautWin wins if nobody except jackal is alive AdditionalTempData.winCondition = WinCondition.JuggernautWin; - TempData.winners = new Il2CppSystem.Collections.Generic.List(); - var wpd = new WinningPlayerData(Juggernaut.juggernaut.Data); - wpd.IsImpostor = false; - TempData.winners.Add(wpd); - } - - else if (impostorWin) - { - TempData.winners = new Il2CppSystem.Collections.Generic.List(); - foreach (GameData.PlayerInfo player in GameData.Instance.AllPlayers) - { - var wpd = new WinningPlayerData(player) { IsImpostor = true }; - if (player.Role.IsImpostor) - { - TempData.winners.Add(wpd); - } - } + winners.Add(Juggernaut.juggernaut.Data); } else if (doomsayerWin) { // DoomsayerWin wins if nobody except jackal is alive - AdditionalTempData.winCondition = WinCondition.DoomsayerWin; - TempData.winners = new Il2CppSystem.Collections.Generic.List(); - var wpd = new WinningPlayerData(Doomsayer.doomsayer.Data); - TempData.winners.Add(wpd); + winners.Add(Doomsayer.doomsayer.Data); AdditionalTempData.winCondition = WinCondition.DoomsayerWin; } @@ -388,10 +350,7 @@ public static void Postfix(AmongUsClient __instance, [HarmonyArgument(0)] ref En { // Swooper wins if nobody except jackal is alive AdditionalTempData.winCondition = WinCondition.SwooperWin; - TempData.winners = new Il2CppSystem.Collections.Generic.List(); - var wpd = new WinningPlayerData(Swooper.swooper.Data); - wpd.IsImpostor = false; - TempData.winners.Add(wpd); + winners.Add(Swooper.swooper.Data); } // Akujo win @@ -400,35 +359,31 @@ public static void Postfix(AmongUsClient __instance, [HarmonyArgument(0)] ref En if (Akujo.honmeiOptimizeWin && !Akujo.existingWithKiller()) { AdditionalTempData.winCondition = WinCondition.AkujoTeamWin; - TempData.winners = new Il2CppSystem.Collections.Generic.List(); foreach (PlayerControl p in CachedPlayer.AllPlayers) { if (p == null) continue; if (p == Akujo.akujo || p == Akujo.honmei) - TempData.winners.Add(new WinningPlayerData(p.Data)); + winners.Add(p.Data); else if (Pursuer.Player.Contains(p) && !p.Data.IsDead) - TempData.winners.Add(new WinningPlayerData(p.Data)); + winners.Add(p.Data); else if (Survivor.Player.Contains(p) && !p.Data.IsDead) - TempData.winners.Add(new WinningPlayerData(p.Data)); + winners.Add(p.Data); else if (!notWinners.Contains(p) && !p.Data.Role.IsImpostor) - TempData.winners.Add(new WinningPlayerData(p.Data)); + winners.Add(p.Data); } } else { AdditionalTempData.winCondition = WinCondition.AkujoSoloWin; - TempData.winners = new Il2CppSystem.Collections.Generic.List(); - TempData.winners.Add(new WinningPlayerData(Akujo.akujo.Data)); - TempData.winners.Add(new WinningPlayerData(Akujo.honmei.Data)); + winners.Add(Akujo.akujo.Data); + winners.Add(Akujo.honmei.Data); } } // Lawyer solo win else if (lawyerSoloWin) { - TempData.winners = new Il2CppSystem.Collections.Generic.List(); - WinningPlayerData wpd = new(Lawyer.lawyer.Data); - TempData.winners.Add(wpd); + winners.Add(Lawyer.lawyer.Data); AdditionalTempData.winCondition = WinCondition.LawyerSoloWin; } @@ -436,24 +391,26 @@ public static void Postfix(AmongUsClient __instance, [HarmonyArgument(0)] ref En if (!lawyerSoloWin && Lawyer.lawyer != null && Lawyer.target != null && (!Lawyer.target.Data.IsDead || Lawyer.target == Jester.jester) && !Lawyer.notAckedExiled) { - WinningPlayerData winningClient = null; - foreach (var winner in TempData.winners.GetFastEnumerator()) - if (winner.PlayerName == Lawyer.target.Data.PlayerName) - winningClient = winner; + NetworkedPlayerInfo winningClient = null; + foreach (var winner in winners.ToArray()) + if (winner.PlayerName == Lawyer.target.Data.PlayerName) winningClient = winner; + if (winningClient != null) { - if (!TempData.winners.ToArray().Any(x => x.PlayerName == Lawyer.lawyer.Data.PlayerName)) + if (!winners.ToArray().Any(x => x.PlayerId == Lawyer.lawyer.PlayerId)) { if (!Lawyer.lawyer.Data.IsDead && Lawyer.stolenWin) { - TempData.winners.Remove(winningClient); - TempData.winners.Add(new WinningPlayerData(Lawyer.lawyer.Data)); - AdditionalTempData.additionalWinConditions.Add(WinCondition.AdditionalLawyerStolenWin); // The Lawyer replaces the client's victory + // The Lawyer replaces the client's victory + winners.Remove(winningClient); + winners.Add(Lawyer.lawyer.Data); + AdditionalTempData.additionalWinConditions.Add(WinCondition.AdditionalLawyerStolenWin); } else { - TempData.winners.Add(new WinningPlayerData(Lawyer.lawyer.Data)); - AdditionalTempData.additionalWinConditions.Add(WinCondition.AdditionalLawyerBonusWin); // The Lawyer wins with the client + // The Lawyer wins with the client + winners.Add(Lawyer.lawyer.Data); + AdditionalTempData.additionalWinConditions.Add(WinCondition.AdditionalLawyerBonusWin); } } } @@ -464,8 +421,8 @@ public static void Postfix(AmongUsClient __instance, [HarmonyArgument(0)] ref En { foreach (var player in Pursuer.Player.Where(p => !p.Data.IsDead)) { - if (!TempData.winners.ToArray().Any(x => x.PlayerName == player.Data.PlayerName)) - TempData.winners.Add(new WinningPlayerData(player.Data)); + if (!winners.ToArray().Any(x => x.PlayerName == player.Data.PlayerName)) + winners.Add(player.Data); } AdditionalTempData.additionalWinConditions.Add(WinCondition.AdditionalAlivePursuerWin); } @@ -475,17 +432,23 @@ public static void Postfix(AmongUsClient __instance, [HarmonyArgument(0)] ref En { foreach (var player in Survivor.Player.Where(p => !p.Data.IsDead)) { - if (!TempData.winners.ToArray().Any(x => x.PlayerName == player.Data.PlayerName)) - TempData.winners.Add(new WinningPlayerData(player.Data)); + if (!winners.ToArray().Any(x => x.PlayerName == player.Data.PlayerName)) + winners.Add(player.Data); } AdditionalTempData.additionalWinConditions.Add(WinCondition.AdditionalAliveSurvivorWin); } - if (PartTimer.partTimer != null && PartTimer.target != null && TempData.winners.ToArray().Any(x => x.PlayerName == PartTimer.target.Data.PlayerName)) + if (PartTimer.partTimer != null && PartTimer.target != null && winners.ToArray().Any(x => x.PlayerId == PartTimer.target.Data.PlayerId)) { - TempData.winners.Add(new WinningPlayerData(PartTimer.partTimer.Data)); + winners.Add(PartTimer.partTimer.Data); AdditionalTempData.additionalWinConditions.Add(WinCondition.AdditionalPartTimerWin); } + + foreach (var data in winners.GroupBy(x => x.PlayerId).Select(g => g.First())) + { + EndGameResult.CachedWinners.Add(new CachedPlayerData(data) { IsYou = isYou, IsImpostor = isImpostor }); + } + Message($"游戏结束 {AdditionalTempData.winCondition}", "OnGameEnd"); // Reset Settings RPCProcedure.resetVariables(); @@ -498,10 +461,9 @@ public class EndGameManagerSetUpPatch public static void Postfix(EndGameManager __instance) { // Delete and readd PoolablePlayers always showing the name and role of the player - foreach (var pb in __instance.transform.GetComponentsInChildren()) - Object.Destroy(pb.gameObject); - var num = Mathf.CeilToInt(7.5f); - var list = TempData.winners.ToList().OrderBy(delegate (WinningPlayerData b) { return !b.IsYou ? 0 : -1; }).ToList(); + foreach (var pb in __instance.transform.GetComponentsInChildren()) Object.Destroy(pb.gameObject); + int num = Mathf.CeilToInt(7.5f); + var list = EndGameResult.CachedWinners.ToList().OrderBy(delegate (CachedPlayerData b) { return !b.IsYou ? 0 : -1; }).ToList(); for (var i = 0; i < list.Count; i++) { var winningPlayerData2 = list[i]; @@ -526,7 +488,7 @@ public static void Postfix(EndGameManager __instance) poolablePlayer.SetFlipX(i % 2 == 0); } - poolablePlayer.UpdateFromPlayerOutfit(winningPlayerData2, PlayerMaterial.MaskType.None, winningPlayerData2.IsDead, true); + poolablePlayer.UpdateFromPlayerOutfit(winningPlayerData2.Outfit, PlayerMaterial.MaskType.None, winningPlayerData2.IsDead, true); poolablePlayer.cosmetics.nameText.color = Color.white; poolablePlayer.cosmetics.nameText.transform.localScale = new Vector3(1f / vector.x, 1f / vector.y, 1f / vector.z); @@ -1051,7 +1013,7 @@ private static bool CheckAndEndGameForImpostorWin(ShipStatus __instance, PlayerS { //__instance.enabled = false; GameOverReason endReason; - switch (TempData.LastDeathReason) + switch (GameData.LastDeathReason) { case DeathReason.Exile: endReason = GameOverReason.ImpostorByVote; @@ -1102,7 +1064,7 @@ internal class RPCEndGamePatch { public static void Postfix(ref GameOverReason endReason) { - Message($"游戏结束 {(CustomGameOverReason)endReason}", "RpcEndGame"); + Message($"游戏结束 {(CustomGameOverReason)endReason} {endReason}", "RpcEndGame"); } } @@ -1131,7 +1093,7 @@ public PlayerStatistics(ShipStatus __instance) public int TeamJuggernautAlive { get; set; } public bool TeamJuggernautHasAliveLover { get; set; } - private static bool isLover(GameData.PlayerInfo p) + private static bool isLover(NetworkedPlayerInfo p) { return (Lovers.lover1 != null && Lovers.lover1.PlayerId == p.PlayerId) || (Lovers.lover2 != null && Lovers.lover2.PlayerId == p.PlayerId); diff --git a/TheOtherRoles/Patches/ExileControllerPatch.cs b/TheOtherRoles/Patches/ExileControllerPatch.cs index 9f5c286c..0d613a35 100644 --- a/TheOtherRoles/Patches/ExileControllerPatch.cs +++ b/TheOtherRoles/Patches/ExileControllerPatch.cs @@ -18,27 +18,28 @@ namespace TheOtherRoles.Patches; [HarmonyPriority(Priority.First)] internal class ExileControllerBeginPatch { - public static GameData.PlayerInfo lastExiled; + public static NetworkedPlayerInfo lastExiled; public static TextMeshPro confirmImpostorSecondText; private static bool IsSec; - public static bool Prefix(ExileController __instance, [HarmonyArgument(0)] ref GameData.PlayerInfo exiled, [HarmonyArgument(1)] bool tie) + public static bool Prefix(ExileController __instance, [HarmonyArgument(0)] ref ExileController.InitProperties init) { - lastExiled = exiled; - Message($"开始放逐: {exiled?.PlayerName ?? "null"}"); + lastExiled = init?.networkedPlayer; + var exiled = init?.networkedPlayer; + Message($"开始放逐: {init?.networkedPlayer?.PlayerName ?? "null"}"); if (Balancer.currentAbilityUser != null && Balancer.IsDoubleExile && !IsSec) { IsSec = true; - __instance.exiled = null; + __instance.initData.networkedPlayer = null; ExileController controller = Object.Instantiate(__instance, __instance.transform.parent); - controller.exiled = Balancer.targetplayerright.Data; - controller.Begin(controller.exiled, false); + controller.initData.networkedPlayer = Balancer.targetplayerright.Data; + controller.Begin(controller.initData); IsSec = false; controller.completeString = string.Empty; controller.Text.gameObject.SetActive(false); - controller.Player.UpdateFromEitherPlayerDataOrCache(controller.exiled, PlayerOutfitType.Default, PlayerMaterial.MaskType.Exile, includePet: false); + controller.Player.UpdateFromEitherPlayerDataOrCache(controller.initData.networkedPlayer, PlayerOutfitType.Default, PlayerMaterial.MaskType.Exile, includePet: false); controller.Player.ToggleName(active: false); - SkinViewData skin = ShipStatus.Instance.CosmeticsCache.GetSkin(controller.exiled.Outfits[PlayerOutfitType.Default].SkinId); + SkinViewData skin = ShipStatus.Instance.CosmeticsCache.GetSkin(controller.initData.networkedPlayer.Outfits[PlayerOutfitType.Default].SkinId); controller.Player.FixSkinSprite(skin.EjectFrame); AudioClip sound = null; if (controller.EjectSound != null) @@ -56,9 +57,10 @@ void createlate(int index) createlate(i); } _ = new LateTask(() => { controller.StopAllCoroutines(); controller.EjectSound = sound; controller.StartCoroutine(controller.Animate()); }, 0.6f); + ExileController.Instance = __instance; - __instance.exiled = Balancer.targetplayerleft.Data; - exiled = __instance.exiled; + init = GenerateExileInitProperties(Balancer.targetplayerleft.Data, false); + if (isFungle) { Helpers.SetActiveAllObject(controller.gameObject.GetChildren(), "RaftAnimation", false); @@ -168,7 +170,7 @@ public static void Postfix(ExileController __instance) confirmImpostorSecondText.text = changeStringBuilder.ToString(); confirmImpostorSecondText.gameObject.SetActive(true); - if (Balancer.currentAbilityUser != null && Balancer.IsDoubleExile && __instance.exiled?.PlayerId == Balancer.targetplayerleft.PlayerId) + if (Balancer.currentAbilityUser != null && Balancer.IsDoubleExile && __instance?.initData?.networkedPlayer?.PlayerId == Balancer.targetplayerleft?.PlayerId) { __instance.completeString = GetString("二者一同放逐"); } @@ -212,7 +214,7 @@ public static void Prefix(GameObject obj) } } - private static void WrapUpPostfix(GameData.PlayerInfo exiled) + private static void WrapUpPostfix(NetworkedPlayerInfo exiled) { Message("WrapUp"); if (CachedPlayer.LocalPlayer.IsDead) CanSeeRoleInfo = true; @@ -515,7 +517,7 @@ private class BaseExileControllerPatch public static void Postfix(ExileController __instance) { Message("ExileController.WrapUp", "WrapUpPostfix"); - WrapUpPostfix(__instance.exiled); + WrapUpPostfix(__instance.initData?.networkedPlayer); } } @@ -525,7 +527,7 @@ private class AirshipExileControllerPatch public static void Postfix(AirshipExileController __instance) { Message("AirshipExileController.WrapUpAndSpawn", "WrapUpPostfix"); - WrapUpPostfix(__instance.exiled); + WrapUpPostfix(__instance.initData?.networkedPlayer); } public static bool Prefix(AirshipExileController __instance) @@ -533,14 +535,14 @@ public static bool Prefix(AirshipExileController __instance) if (Balancer.currentAbilityUser != null && Balancer.IsDoubleExile && __instance != ExileController.Instance) { - if (__instance.exiled != null) + if (__instance.initData?.networkedPlayer != null) { - PlayerControl @object = __instance.exiled.Object; + PlayerControl @object = __instance.initData?.networkedPlayer.Object; if (@object) { @object.Exiled(); } - __instance.exiled.IsDead = true; + __instance.initData.networkedPlayer.IsDead = true; } Object.Destroy(__instance.gameObject); } @@ -568,9 +570,9 @@ private static void Postfix(ref string __result, [HarmonyArgument(0)] StringName { try { - if (ExileController.Instance != null && ExileController.Instance.exiled != null) + if (ExileController.Instance != null && ExileController.Instance.initData.networkedPlayer != null) { - var player = playerById(ExileController.Instance.exiled.Object.PlayerId); + var player = playerById(ExileController.Instance.initData.networkedPlayer.Object.PlayerId); if (player == null) return; // Exile role text if (id is StringNames.ExileTextPN or StringNames.ExileTextSN or StringNames.ExileTextPP or StringNames.ExileTextSP) diff --git a/TheOtherRoles/Patches/GameStartManagerPatch.cs b/TheOtherRoles/Patches/GameStartManagerPatch.cs index f16ec3e6..609f1e7b 100644 --- a/TheOtherRoles/Patches/GameStartManagerPatch.cs +++ b/TheOtherRoles/Patches/GameStartManagerPatch.cs @@ -25,6 +25,7 @@ public static void Postfix(AmongUsClient __instance) { shareGameVersion(); } + GameStartManagerUpdatePatch.sendGamemode = true; } } @@ -33,8 +34,9 @@ public static class ConstantsPatch { public static void Postfix(ref int __result) { - if (AmongUsClient.Instance.NetworkMode == NetworkModes.OnlineGame) - __result += 25; + if (!Main.ForceUsePlus25Protocol.Value) return; + if (AmongUsClient.Instance.NetworkMode == NetworkModes.OnlineGame) __result += 25; + Message("使用 +25 协议", "NetworkModes"); } } @@ -64,6 +66,7 @@ public class GameStartManagerUpdatePatch private static bool update; private static string currentText = ""; private static GameObject copiedStartButton; + public static bool sendGamemode = true; public static void Prefix(GameStartManager __instance) { @@ -124,14 +127,20 @@ public static void Postfix(GameStartManager __instance) { if (versionMismatch) { - __instance.StartButton.color = __instance.startLabelText.color = Palette.DisabledClear; __instance.GameStartText.text = message; - __instance.GameStartText.transform.localPosition = __instance.StartButton.transform.localPosition + Vector3.up * 2; + __instance.GameStartText.transform.localPosition = __instance.StartButton.transform.localPosition + Vector3.up * 5; + __instance.GameStartText.transform.localScale = new Vector3(2f, 2f, 1f); + __instance.GameStartTextParent.SetActive(true); } else { - __instance.StartButton.color = __instance.startLabelText.color = (__instance.LastPlayerCount >= __instance.MinPlayers) ? Palette.EnabledColor : Palette.DisabledClear; - __instance.GameStartText.transform.localPosition = __instance.StartButton.transform.localPosition; + __instance.GameStartText.transform.localPosition = Vector3.zero; + __instance.GameStartText.transform.localScale = new Vector3(1.2f, 1.2f, 1f); + if (!__instance.GameStartText.text.StartsWith(FastDestroyableSingleton.Instance.GetString(StringNames.GameStarting).Replace("{0}", "")) && CustomOptionHolder.anyPlayerCanStopStart.GetBool()) + { + __instance.GameStartText.text = string.Empty; + __instance.GameStartTextParent.SetActive(false); + } } if (__instance.startState != GameStartManager.StartingStates.Countdown) @@ -147,11 +156,10 @@ public static void Postfix(GameStartManager __instance) // Activate Stop-Button copiedStartButton = UnityEngine.Object.Instantiate(__instance.StartButton.gameObject, __instance.StartButton.gameObject.transform.parent); copiedStartButton.transform.localPosition = __instance.StartButton.transform.localPosition; - copiedStartButton.GetComponent().sprite = UnityHelper.loadSpriteFromResources("TheOtherRoles.Resources.StopClean.png", 180f); copiedStartButton.SetActive(true); var startButtonText = copiedStartButton.GetComponentInChildren(); - startButtonText.text = GetString("stopGameStartText"); - startButtonText.fontSize *= 0.62f; + startButtonText.text = ""; + startButtonText.fontSize *= 0.68f; startButtonText.fontSizeMax = startButtonText.fontSize; startButtonText.gameObject.transform.localPosition = Vector3.zero; PassiveButton startButtonPassiveButton = copiedStartButton.GetComponent(); @@ -165,11 +173,9 @@ void StopStartFunc() startButtonPassiveButton.OnClick.AddListener((Action)(() => StopStartFunc())); __instance.StartCoroutine(Effects.Lerp(.1f, new Action((p) => { - startButtonText.text = "STOP"; + startButtonText.text = ""; }))); } - if (__instance.startState == GameStartManager.StartingStates.Countdown) - __instance.GameStartText.transform.localPosition = __instance.StartButton.transform.localPosition + Vector3.up * 0.6f; } // Client update with handshake infos @@ -186,19 +192,26 @@ void StopStartFunc() } __instance.GameStartText.text = $"{string.Format(GetString("errorHostNoVersion"), Math.Round(10 - kickingTimer))}"; - __instance.GameStartText.transform.localPosition = __instance.StartButton.transform.localPosition + Vector3.up * 2; + __instance.GameStartText.transform.localPosition = __instance.StartButton.transform.localPosition + Vector3.up * 5; + __instance.GameStartText.transform.localScale = new Vector3(2f, 2f, 1f); + __instance.GameStartTextParent.SetActive(true); } else if (versionMismatch) { __instance.GameStartText.text = $"{GetString("errorDifferentVersion")}\n" + message; - __instance.GameStartText.transform.localPosition = __instance.StartButton.transform.localPosition + Vector3.up * 2; + __instance.GameStartText.transform.localPosition = __instance.StartButton.transform.localPosition + Vector3.up * 5; + __instance.GameStartText.transform.localScale = new Vector3(2f, 2f, 1f); + __instance.GameStartTextParent.SetActive(true); } else { __instance.GameStartText.transform.localPosition = __instance.StartButton.transform.localPosition; + __instance.GameStartText.transform.localPosition = Vector3.zero; + __instance.GameStartText.transform.localScale = new Vector3(1.2f, 1.2f, 1f); if (!__instance.GameStartText.text.StartsWith(FastDestroyableSingleton.Instance.GetString(StringNames.GameStarting).Replace("{0}", ""))) { __instance.GameStartText.text = string.Empty; + __instance.GameStartTextParent.SetActive(false); } } @@ -210,10 +223,9 @@ void StopStartFunc() // Activate Stop-Button copiedStartButton = UnityEngine.Object.Instantiate(__instance.StartButton.gameObject, __instance.StartButton.gameObject.transform.parent); copiedStartButton.transform.localPosition = __instance.StartButton.transform.localPosition; - copiedStartButton.GetComponent().sprite = UnityHelper.loadSpriteFromResources("TheOtherRoles.Resources.StopClean.png", 180f); copiedStartButton.SetActive(true); var startButtonText = copiedStartButton.GetComponentInChildren(); - startButtonText.text = "STOP"; + startButtonText.text = ""; startButtonText.fontSize *= 0.62f; startButtonText.fontSizeMax = startButtonText.fontSize; startButtonText.gameObject.transform.localPosition = Vector3.zero; @@ -221,8 +233,7 @@ void StopStartFunc() void StopStartFunc() { - var writer = AmongUsClient.Instance.StartRpcImmediately(CachedPlayer.LocalPlayer.PlayerControl.NetId, - (byte)CustomRPC.StopStart, SendOption.Reliable, AmongUsClient.Instance.HostId); + var writer = AmongUsClient.Instance.StartRpcImmediately(CachedPlayer.LocalPlayer.PlayerControl.NetId, (byte)CustomRPC.StopStart, SendOption.Reliable, AmongUsClient.Instance.HostId); writer.Write(PlayerControl.LocalPlayer.PlayerId); AmongUsClient.Instance.FinishRpcImmediately(writer); copiedStartButton.Destroy(); @@ -232,12 +243,9 @@ void StopStartFunc() startButtonPassiveButton.OnClick.AddListener((Action)(() => StopStartFunc())); __instance.StartCoroutine(Effects.Lerp(.1f, new Action((p) => { - startButtonText.text = "STOP"; + startButtonText.text = ""; }))); - } - if (__instance.GameStartText.text.StartsWith(FastDestroyableSingleton.Instance.GetString(StringNames.GameStarting).Replace("{0}", "")) && CustomOptionHolder.anyPlayerCanStopStart.GetBool()) - __instance.GameStartText.transform.localPosition = __instance.StartButton.transform.localPosition + Vector3.up * 0.6f; } // Start Timer @@ -246,7 +254,7 @@ void StopStartFunc() startingTimer -= Time.deltaTime; } // Lobby timer - if (!GameData.Instance) return; // No instance + if (!GameData.Instance || !__instance.PlayerCounter) return; // No instance if (update) currentText = __instance.PlayerCounter.text; @@ -255,16 +263,16 @@ void StopStartFunc() int seconds = (int)timer % 60; string suffix = $" ({minutes:00}:{seconds:00})"; - __instance.PlayerCounter.text = currentText + suffix; - __instance.PlayerCounter.autoSizeTextContainer = true; + if (!AmongUsClient.Instance) return; - if (AmongUsClient.Instance.AmHost) + if (AmongUsClient.Instance.AmHost && sendGamemode && CachedPlayer.LocalPlayer != null) { var writer = AmongUsClient.Instance.StartRpcImmediately(CachedPlayer.LocalPlayer.PlayerControl.NetId, (byte)CustomRPC.ShareGameMode, SendOption.Reliable, -1); writer.Write((byte)ModOption.gameMode); AmongUsClient.Instance.FinishRpcImmediately(writer); RPCProcedure.shareGameMode((byte)ModOption.gameMode); + sendGamemode = false; } } } @@ -303,6 +311,7 @@ public static bool Prefix(GameStartManager __instance) break; } } + if (CustomOptionHolder.dynamicMap.GetBool() && continueStart) { // 0 = Skeld diff --git a/TheOtherRoles/Patches/GetStringPatch.cs b/TheOtherRoles/Patches/GetStringPatch.cs new file mode 100644 index 00000000..a8a21949 --- /dev/null +++ b/TheOtherRoles/Patches/GetStringPatch.cs @@ -0,0 +1,24 @@ +using System.Linq; + +namespace TheOtherRoles.Patches; + +[HarmonyPatch] +public class GetStringPatch +{ + [HarmonyPatch(typeof(TranslationController), nameof(TranslationController.GetString), [typeof(StringNames), + typeof(Il2CppReferenceArray)])] + public static bool Prefix(TranslationController __instance, StringNames id, ref string __result) + { + if ((int)id < 6000) + { + return true; + } + string ourString = ""; + // For now only do this in custom options. + int idInt = (int)id - 6000; + CustomOption opt = CustomOption.options.FirstOrDefault(x => x.id == idInt); + ourString = opt?.name; + __result = ourString; + return false; + } +} diff --git a/TheOtherRoles/Patches/LobbyBehaviourPatch.cs b/TheOtherRoles/Patches/LobbyBehaviourPatch.cs new file mode 100644 index 00000000..129ca039 --- /dev/null +++ b/TheOtherRoles/Patches/LobbyBehaviourPatch.cs @@ -0,0 +1,27 @@ +namespace TheOtherRoles.Patches; + +[HarmonyPatch(typeof(LobbyBehaviour))] +public class LobbyBehaviourPatch +{ + public static int Frame; + + [HarmonyPatch(nameof(LobbyBehaviour.FixedUpdate)), HarmonyPostfix] + public static void UpdatePostfix(LobbyBehaviour __instance) + { + if (--Frame <= 0) + { + ISoundPlayer MapThemeSound = SoundManager.Instance.soundPlayers.Find(x => x.Name.Equals("MapTheme")); + if (ModOption.MuteLobbyBGM) + { + if (MapThemeSound == null) return; + SoundManager.Instance.StopNamedSound("MapTheme"); + } + else + { + if (MapThemeSound != null) return; + SoundManager.Instance.CrossFadeSound("MapTheme", __instance.MapTheme, 0.5f); + } + Frame = 15; + } + } +} \ No newline at end of file diff --git a/TheOtherRoles/Patches/LobbyRoleList.cs b/TheOtherRoles/Patches/LobbyRoleList.cs index 96ada38f..f8082b53 100644 --- a/TheOtherRoles/Patches/LobbyRoleList.cs +++ b/TheOtherRoles/Patches/LobbyRoleList.cs @@ -1,4 +1,4 @@ -using System; +/*using System; using System.Collections.Generic; using TheOtherRoles.Buttons; using TMPro; @@ -14,22 +14,6 @@ public static class LobbyRoleInfo private static TextMeshPro infoButtonText; private static TextMeshPro infoTitleText; - [HarmonyPatch(typeof(HudManager), nameof(HudManager.Update))] - public static class RoleSummaryButtonHudUpdate - { - public static void Postfix(HudManager __instance) - { - if (!LobbyBehaviour.Instance || AmongUsClient.Instance.GameState == InnerNet.InnerNetClient.GameStates.Started) return; - try - { - //if (HudManagerStartPatch.roleSummaryButton == null) HudManagerStartPatch.createRoleSummaryButton(__instance); - if (HudManagerStartPatch.roleSummaryButton.Timer > 0f) HudManagerStartPatch.roleSummaryButton.Timer = 0f; - HudManagerStartPatch.roleSummaryButton.Update(); - } - catch { } - } - } - public static void RoleSummaryOnClick() { if (RolesSummaryUI != null) return; @@ -281,4 +265,4 @@ public static void Prefix(ShipStatus __instance) { if (LobbyRoleInfo.RolesSummaryUI != null) LobbyRoleInfo.RolesSummaryUI.SetActive(false); } -} \ No newline at end of file +}*/ \ No newline at end of file diff --git a/TheOtherRoles/Patches/MeetingHudPatch.cs b/TheOtherRoles/Patches/MeetingHudPatch.cs index c8e21168..92409a3f 100644 --- a/TheOtherRoles/Patches/MeetingHudPatch.cs +++ b/TheOtherRoles/Patches/MeetingHudPatch.cs @@ -20,7 +20,7 @@ internal class MeetingHudPatch { private static bool[] selections; private static SpriteRenderer[] renderers; - private static GameData.PlayerInfo target; + private static NetworkedPlayerInfo target; private static PassiveButton[] swapperButtonList; private static TextMeshPro meetingExtraButtonLabel; public static GameObject MeetingExtraButton; @@ -506,7 +506,7 @@ private static bool Prefix(MeetingHud __instance) [HarmonyPatch(typeof(MeetingHud), nameof(MeetingHud.BloopAVoteIcon))] private class MeetingHudBloopAVoteIconPatch { - public static bool Prefix(MeetingHud __instance, GameData.PlayerInfo voterPlayer, int index, Transform parent) + public static bool Prefix(MeetingHud __instance, NetworkedPlayerInfo voterPlayer, int index, Transform parent) { var spriteRenderer = Object.Instantiate(__instance.PlayerVotePrefab); var showVoteColors = !GameManager.Instance.LogicOptions.GetAnonymousVotes() || shouldShowGhostInfo() || @@ -661,7 +661,7 @@ private static bool Prefix(MeetingHud __instance, Il2CppStructArray private class MeetingHudVotingCompletedPatch { private static void Postfix(MeetingHud __instance, [HarmonyArgument(0)] byte[] states, - [HarmonyArgument(1)] GameData.PlayerInfo exiled, [HarmonyArgument(2)] bool tie) + [HarmonyArgument(1)] NetworkedPlayerInfo exiled, [HarmonyArgument(2)] bool tie) { // Reset swapper values Swapper.playerId1 = byte.MaxValue; @@ -696,7 +696,7 @@ private static void Postfix(MeetingHud __instance, [HarmonyArgument(0)] byte[] s private static void Prefix(MeetingHud __instance, [HarmonyArgument(0)] Il2CppStructArray states, - [HarmonyArgument(1)] GameData.PlayerInfo exiled, + [HarmonyArgument(1)] NetworkedPlayerInfo exiled, [HarmonyArgument(2)] bool tie) { if (tie && Balancer.currentAbilityUser != null) @@ -738,7 +738,7 @@ private static void Postfix(MeetingHud __instance, [HarmonyArgument(0)] MessageR [HarmonyPatch(typeof(PlayerControl), nameof(PlayerControl.StartMeeting))] private class StartMeetingPatch { - public static void Prefix(PlayerControl __instance, [HarmonyArgument(0)] GameData.PlayerInfo meetingTarget) + public static void Prefix(PlayerControl __instance, [HarmonyArgument(0)] NetworkedPlayerInfo meetingTarget) { var roomTracker = FastDestroyableSingleton.Instance.roomTracker; var roomId = byte.MinValue; diff --git a/TheOtherRoles/Patches/PlayerControlPatch.cs b/TheOtherRoles/Patches/PlayerControlPatch.cs index 131cf4d7..411a4474 100644 --- a/TheOtherRoles/Patches/PlayerControlPatch.cs +++ b/TheOtherRoles/Patches/PlayerControlPatch.cs @@ -1962,7 +1962,7 @@ public static bool Prefix(PlayerControl __instance) return true; } - private static void Postfix(PlayerControl __instance, [HarmonyArgument(0)] GameData.PlayerInfo target) + private static void Postfix(PlayerControl __instance, [HarmonyArgument(0)] NetworkedPlayerInfo target) { Message($"报告玩家 {__instance.Data.PlayerName} 被报告尸体 {target?.PlayerName}", "CmdReportDeadBody"); // Medic or Detective report diff --git a/TheOtherRoles/Patches/RoleAssignmentPatch.cs b/TheOtherRoles/Patches/RoleAssignmentPatch.cs index 9df7ec89..68df4dc0 100644 --- a/TheOtherRoles/Patches/RoleAssignmentPatch.cs +++ b/TheOtherRoles/Patches/RoleAssignmentPatch.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using AmongUs.GameOptions; @@ -11,7 +11,7 @@ namespace TheOtherRoles.Patches; -[HarmonyPatch(typeof(RoleOptionsCollectionV07), nameof(RoleOptionsCollectionV07.GetNumPerGame))] +[HarmonyPatch(typeof(RoleOptionsCollectionV08), nameof(RoleOptionsCollectionV08.GetNumPerGame))] internal class RoleOptionsDataGetNumPerGamePatch { public static void Postfix(ref int __result) @@ -56,7 +56,7 @@ internal class RoleManagerSelectRolesPatch public static void Postfix() { - var writer = AmongUsClient.Instance.StartRpcImmediately(CachedPlayer.LocalPlayer.PlayerControl.NetId, + var writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.ResetVaribles, SendOption.Reliable); AmongUsClient.Instance.FinishRpcImmediately(writer); RPCProcedure.resetVariables(); @@ -447,7 +447,7 @@ private static void assignRoleTargets(RoleAssignmentData data) if (possibleTargets.Count == 0) { - var w = AmongUsClient.Instance.StartRpcImmediately(CachedPlayer.LocalPlayer.PlayerControl.NetId, + var w = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.LawyerPromotesToPursuer, SendOption.Reliable); AmongUsClient.Instance.FinishRpcImmediately(w); Lawyer.PromotesToPursuer(); @@ -455,7 +455,7 @@ private static void assignRoleTargets(RoleAssignmentData data) else { var target = possibleTargets[rnd.Next(0, possibleTargets.Count)]; - var writer = AmongUsClient.Instance.StartRpcImmediately(CachedPlayer.LocalPlayer.PlayerControl.NetId, + var writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.LawyerSetTarget, SendOption.Reliable); writer.Write(target.PlayerId); AmongUsClient.Instance.FinishRpcImmediately(writer); @@ -475,7 +475,7 @@ private static void assignRoleTargets(RoleAssignmentData data) if (possibleTargets.Count == 0) { - var w = AmongUsClient.Instance.StartRpcImmediately(CachedPlayer.LocalPlayer.PlayerControl.NetId, + var w = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.ExecutionerPromotesRole, SendOption.Reliable); AmongUsClient.Instance.FinishRpcImmediately(w); Executioner.PromotesRole(); @@ -483,7 +483,7 @@ private static void assignRoleTargets(RoleAssignmentData data) else { var target = possibleTargets[rnd.Next(0, possibleTargets.Count)]; - var writer = AmongUsClient.Instance.StartRpcImmediately(CachedPlayer.LocalPlayer.PlayerControl.NetId, + var writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.ExecutionerSetTarget, SendOption.Reliable); writer.Write(target.PlayerId); AmongUsClient.Instance.FinishRpcImmediately(writer); @@ -678,7 +678,7 @@ private static void assignGuesserGamemodeToPlayers(List playerLis playerList.Remove(player2); } - var writer = AmongUsClient.Instance.StartRpcImmediately(CachedPlayer.LocalPlayer.PlayerControl.NetId, + var writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.SetGuesserGm, SendOption.Reliable); writer.Write(playerId); AmongUsClient.Instance.FinishRpcImmediately(writer); @@ -694,7 +694,7 @@ private static byte setRoleToRandomPlayer(byte roleId, List playe playerRoleMap.Add(new Tuple(playerId, roleId)); - var writer = AmongUsClient.Instance.StartRpcImmediately(CachedPlayer.LocalPlayer.PlayerControl.NetId, + var writer = AmongUsClient.Instance.StartRpcImmediately(PlayerControl.LocalPlayer.NetId, (byte)CustomRPC.SetRole, SendOption.Reliable); writer.Write(roleId); writer.Write(playerId); @@ -710,7 +710,7 @@ private static byte setModifierToRandomPlayer(byte modifierId, List 0) { - hand.SetPlayerColor(Morphling.morphTarget.CurrentOutfit, PlayerMaterial.MaskType.None); + hand.SetPlayerColor(Morphling.morphTarget.CurrentOutfit, PlayerMaterial.MaskType.None, 1); // Also set hat color, cause the line destroys it... player.RawSetHat(Morphling.morphTarget.Data.DefaultOutfit.HatId, Morphling.morphTarget.Data.DefaultOutfit.ColorId); } else { - hand.SetPlayerColor(player.CurrentOutfit, PlayerMaterial.MaskType.None); + hand.SetPlayerColor(player.CurrentOutfit, PlayerMaterial.MaskType.None, 1); } } else diff --git a/TheOtherRoles/Patches/UsablesPatch.cs b/TheOtherRoles/Patches/UsablesPatch.cs index 75c1a495..8264bb78 100644 --- a/TheOtherRoles/Patches/UsablesPatch.cs +++ b/TheOtherRoles/Patches/UsablesPatch.cs @@ -18,7 +18,7 @@ namespace TheOtherRoles.Patches; [HarmonyPatch(typeof(Vent), nameof(Vent.CanUse))] public static class VentCanUsePatch { - public static bool Prefix(Vent __instance, ref float __result, [HarmonyArgument(0)] GameData.PlayerInfo pc, + public static bool Prefix(Vent __instance, ref float __result, [HarmonyArgument(0)] NetworkedPlayerInfo pc, [HarmonyArgument(1)] ref bool canUse, [HarmonyArgument(2)] ref bool couldUse) { if (GameOptionsManager.Instance.currentGameOptions.GameMode == GameModes.HideNSeek) return true; @@ -452,7 +452,7 @@ private static void Postfix(EmergencyMinigame __instance) [HarmonyPatch(typeof(Console), nameof(Console.CanUse))] public static class ConsoleCanUsePatch { - public static bool Prefix(ref float __result, Console __instance, [HarmonyArgument(0)] GameData.PlayerInfo pc, + public static bool Prefix(ref float __result, Console __instance, [HarmonyArgument(0)] NetworkedPlayerInfo pc, [HarmonyArgument(1)] out bool canUse, [HarmonyArgument(2)] out bool couldUse) { canUse = couldUse = false; diff --git a/TheOtherRoles/RPC.cs b/TheOtherRoles/RPC.cs index d38d5f8d..74e50320 100644 --- a/TheOtherRoles/RPC.cs +++ b/TheOtherRoles/RPC.cs @@ -141,7 +141,7 @@ public enum RoleId public enum CustomRPC { // Main Controls - ResetVaribles = 80, + ResetVaribles = 100, ShareOptions, WorkaroundSetRoles, SetRole, @@ -155,10 +155,10 @@ public enum CustomRPC DynamicMapOption, SetGameStarting, StopStart, - ShareGameMode = 95, + ShareGameMode = 120, // Role functionality - FixLights = 100, + FixLights = 121, FixSubmergedOxygen, CleanBody, DissectionBody, @@ -321,7 +321,7 @@ public static void HandleShareOptions(byte numberOfOptions, MessageReader reader var optionId = reader.ReadPackedUInt32(); var selection = reader.ReadPackedUInt32(); var option = CustomOption.options.First(option => option.id == (int)optionId); - option.updateSelection((int)selection); + option.updateSelection((int)selection, i == numberOfOptions - 1); } } catch (Exception e) @@ -333,6 +333,9 @@ public static void HandleShareOptions(byte numberOfOptions, MessageReader reader public static void shareGameMode(byte gm) { gameMode = (CustomGamemodes)gm; + LobbyViewSettingsPatch.currentButtons?.ForEach(x => x.gameObject?.Destroy()); + LobbyViewSettingsPatch.currentButtons?.Clear(); + LobbyViewSettingsPatch.currentButtonTypes?.Clear(); } public static void stopStart(byte playerId) @@ -584,7 +587,7 @@ public static void setRole(byte roleId, byte playerId) if (AmongUsClient.Instance.AmHost && Helpers.roleCanUseVents(player) && !player.Data.Role.IsImpostor) { player.RpcSetRole(RoleTypes.Engineer); - player.SetRole(RoleTypes.Engineer); + player.CoSetRole(RoleTypes.Engineer, true); } } } @@ -2129,7 +2132,7 @@ private static bool Prefix([HarmonyArgument(0)] byte callId, [HarmonyArgument(1) if (!RpcNames!.ContainsKey(packetId)) return true; - if (DebugMode && callId != 95) Info($"接收 PlayerControl CustomRpc RpcId{callId} Rpc {RpcNames?[(CustomRPC)callId] ?? nameof(packetId)} Message Size {reader.Length}"); + if (DebugMode && callId != 120) Info($"接收 PlayerControl CustomRpc RpcId{callId} Rpc {RpcNames?[(CustomRPC)callId] ?? nameof(packetId)} Message Size {reader.Length}"); switch (packetId) { // Main Controls diff --git a/TheOtherRoles/Resources/Copy.png b/TheOtherRoles/Resources/Copy.png new file mode 100644 index 0000000000000000000000000000000000000000..1db34bbf70cef738ff92b5ff32d2eebdeaa7f8ce GIT binary patch literal 17161 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 literal 0 HcmV?d00001 diff --git a/TheOtherRoles/Resources/CopyPasteBG.png b/TheOtherRoles/Resources/CopyPasteBG.png new file mode 100644 index 0000000000000000000000000000000000000000..c8f47cce48e9404ef115793e5d92db858d0bc9ea GIT binary patch literal 13064 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 FzX7Z8dvpK* literal 0 HcmV?d00001 diff --git a/TheOtherRoles/Resources/Minus_ButtonActive.png b/TheOtherRoles/Resources/Minus_ButtonActive.png new file mode 100644 index 0000000000000000000000000000000000000000..2cd4b5a09b5ffa4dc6f2f5f95c4b4dd9ab4d43e4 GIT binary patch literal 6897 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 literal 0 HcmV?d00001 diff --git a/TheOtherRoles/Resources/PasteActive.png b/TheOtherRoles/Resources/PasteActive.png new file mode 100644 index 0000000000000000000000000000000000000000..b80d73bf80b46baf6dcceb2d2c59a0e1687b1e7c GIT binary patch literal 14227 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 VzQ+mJJa2(evQkQtHR8sB{{#4B_QU`H literal 0 HcmV?d00001 diff --git a/TheOtherRoles/Resources/Plus_Button.png b/TheOtherRoles/Resources/Plus_Button.png new file mode 100644 index 0000000000000000000000000000000000000000..35335d5370f2768ac1f02008f61c86dd10b7221c GIT binary patch literal 7047 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 literal 0 HcmV?d00001 diff --git a/TheOtherRoles/Resources/Settings_ButtonActive.png b/TheOtherRoles/Resources/Settings_ButtonActive.png new file mode 100644 index 0000000000000000000000000000000000000000..813c937c11708ea37eb1d8ed0db7aa15fd430917 GIT binary patch literal 13826 zcmeHuWmH?;)-Ddk9ZHb^#VrI4#jUuv6mK8_f;S276fN$qMO&muaV<^@6nBb4u>wU3 zwVU>R&pGe8-*?Y<&lvaqJITmS_FB(;=3LL3bFIC{9*NS^xlcmKK!|~XL87jvY=HhY zM}G_n@X$xfmdCLe7`MZHj2@v3Af5m>gsUyw2?juUyTJf3FSsoRhSy?Mwp|+Ay@arz zjx_Z+-t~+NNL&2+Z`X<%+yw;|9n~%cB2<~ctJMS}haVq)3SP*48y5H8RvM}8E5F{1 z7HT|WJ@{O9Z2bItz)GNE*Ky|V0dMm`_;!+C=a2l&i*HA*EfQ|4y!mgGl&<%C8g}pW zTOIADhgZkt#0;H5%t=yTvf7Q4AjR~?8&LdU8J)t>&jJ2FGlBy(EN_;b9g!E8H-Y)D zRtd~evpRz?%c^=i44og|+q^7nHOp%X^>X;T-eSk%l*DIaIyVrb{TaS1T_MZN(+)#( zXP&UZeVV%b!+I;d@67QJ#)%?q5wk zhG~~_A8y>a7JkcVyzF-Sr~C3jv%@DF;kFNTZ3moFr$A{qN$l;@=A`tW8@o12j_N~q z*avb3`(xf}kb{U%bK1|SNhu_9Bng+goAT%6HjE?id&QBqArG3Sl!AfG}(_c+`+9Ug4|k-HGyTb&^9l=YO*7+0}8nNZ$ByvEqnTT}k+bho%Ab zhzU=`{4QY@g)xEGK2VXVcT>bM+k(R<8A-_LDWx$IE9P{EhTN)Rz{QNnCw8cK=h4FH z%=G|E^POok<*T7ZKt4cVs=QsMU*emi5Ai0?78z3T(O4=ehD$^SK>*xl_^d$ZO&{O9^n;IB+yR?8K1ThRp6~GR>n#`qVz1M zAV-}3)FMbReOP1@?y8v+{5UHz!2$U?OdevO&@ffzdC`Xd`@5>rz7sY_2WWZed5iO*T|sd<9ca`-<(! zL``N|BdUE&iNY&&=^D~BDQS@Q!S7Nr7+R{ebu?rFYLknH%5xlBqa*RP`W^I2V5pAm1v7*~nWuV&B0XG=6@vhAOmcV7(Y&q}$rL>0)B zFu2d`XiVdJ=L%P*@4?=0nLdQ%QV&tW3y%6vM9Sw@C&Tt4214gZ zC-Xq<++kMA=8qSlBQwFu8l-I%gUmW#DSv)gjDUB!voZm66L@bI2{2(qj();ZTa?*I zElu5uZ@Wb~eoT$2+G_7M5GKpocGY`3fYzIO(8YQe%pt+ERvD1{CeV(3YUT?3zB}`2 z@!=ff7_mpVFed5|K-zawR`Kr%K=-23F&cdcu> z9OwBjW_9~7RcjjLy+sI`-p|q78bFF&sZ?}=Ff}yA+jPITAK9LroQ8anAHrfOKc^;{ zR8g-}ylAQ|S;d{}>Pz#XGyh3xwr}C~UDK(;v*$t#pNAGXUHZU$^8IDCLI zwj15Axu3u&0*rcs(h@_)pqfm(7^HKeysLwY7^xH7X1918Y(Cv9pAnmAGGz)5xjk)0 zcn&^x!3wLVE9N?3sALiRNNFa97a1am&kea#$d4!1q32%nq(M%h?C}?)NZ5V8x>kgB zr1w~*%^mSKiYYybJEp6^pJ8Vq@hum*4>dHy{HZpNiOvcW^Q6g{>Sbaa$|HRj2O{1) z#9Vvcg5B<;;KfDI1(SQ-YW^+@WUH@BwfoXx@(B?jucG8aY1f)k48YTMU7t|uzC^UQ zDtpcuyhpXt8FH_du#S!}R^F7xtyARQUi5G|hnRY#@Pm%G$pE6EOli^1%*+buZd^&G zPbMr}eU`D|cG|3JBckuJ6vvIlc$j$~G><9WDB3m8Z$jU^>|MS^qhId9Xcf9={q(A? z9?Vcw(R)sMkiHrdlHVt}Y6PVs&C{IQ_b2G@pW=BDWG(k`A^9SX0c9*u3*LzZ6trjc z;^79CSsExra@@QETy*ERdQqRJ>T*+FOGLy=YBy?AM{{4>x7CT6ZS= zpo%+}tJB=}Y?ZJRzR#Lh-y9x#(z!7U;f}n)FhO=L8Hh!{6A6Fg^xpJvmIg1iN`khR zSlwV_HY;VH-XQ6=3EM~=P8V

mCJntpUuK(9&#l&u^q#Bvnk2S9yhx_nq0!BG#>p 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 by mxyx.club\nBased on TheOtherUs", "13": "模组修改:沫夏悠轩 " }, + "GameMode": { + "0": "Game Mode", + "13": "游戏模式" + }, + "isClassicGM": { + "0": "Classic", + "13": "经典模式" + }, + "isVanHideNSeekGM": { + "0": "Van. HideNSeek", + "13": "原版躲猫猫" + }, "isHideNSeekGM": { - "0": "HideNSeek", + "0": "TOU Hide N Seek", "13": "猎杀模式" }, "isGuesserGm": { diff --git a/TheOtherRoles/Roles/Crewmate/Prosecutor.cs b/TheOtherRoles/Roles/Crewmate/Prosecutor.cs index 1a7136d6..7f0e4b2f 100644 --- a/TheOtherRoles/Roles/Crewmate/Prosecutor.cs +++ b/TheOtherRoles/Roles/Crewmate/Prosecutor.cs @@ -1,4 +1,4 @@ -using Hazel; +using Hazel; using TheOtherRoles.Utilities; using TMPro; using UnityEngine; @@ -173,7 +173,7 @@ public static bool Prefix(PlayerVoteArea __instance) [HarmonyPatch(typeof(PlayerControl), nameof(PlayerControl.StartMeeting))] public class StartMeetingPatch { - private static void Prefix(PlayerControl __instance, [HarmonyArgument(0)] GameData.PlayerInfo meetingTarget) + private static void Prefix(PlayerControl __instance, [HarmonyArgument(0)] NetworkedPlayerInfo meetingTarget) { if (__instance == null) return; if (prosecutor != null) StartProsecute = false; @@ -201,7 +201,7 @@ public static void ExileControllerPostfix(ExileController __instance) { if (prosecutor != null && ProsecuteThisMeeting) { - var exiled = __instance.exiled?.Object; + var exiled = __instance.initData.networkedPlayer?.Object; if (exiled != null && exiled == exiled.isCrew() && diesOnIncorrectPros) { prosecutor.Exiled(); diff --git a/TheOtherRoles/TasksHandler.cs b/TheOtherRoles/TasksHandler.cs index 09c2e7e6..aebbeba6 100644 --- a/TheOtherRoles/TasksHandler.cs +++ b/TheOtherRoles/TasksHandler.cs @@ -6,7 +6,7 @@ namespace TheOtherRoles; [HarmonyPatch] public static class TasksHandler { - public static Tuple taskInfo(GameData.PlayerInfo playerInfo) + public static Tuple taskInfo(NetworkedPlayerInfo playerInfo) { var TotalTasks = 0; var CompletedTasks = 0; @@ -26,7 +26,7 @@ public static Tuple taskInfo(GameData.PlayerInfo playerInfo) [HarmonyPatch(typeof(GameData), nameof(GameData.RecomputeTaskCounts))] private static class GameDataRecomputeTaskCountsPatch { - private static bool ShouldCountTasks(GameData.PlayerInfo playerInfo) + private static bool ShouldCountTasks(NetworkedPlayerInfo playerInfo) { return !(playerInfo.Object && playerInfo.Object.hasAliveKillingLover()) && playerInfo.PlayerId != Thief.thief?.PlayerId diff --git a/TheOtherRoles/TheOtherRoles.csproj b/TheOtherRoles/TheOtherRoles.csproj index 146e8cb6..4e89a75a 100644 --- a/TheOtherRoles/TheOtherRoles.csproj +++ b/TheOtherRoles/TheOtherRoles.csproj @@ -1,30 +1,23 @@  net6.0 - 1.1.1.1 + 1.2.0.0 TheOtherUs mxyx-club latest true true embedded - Debug;Release;mxyx-club;Beta + Debug;Release;Beta - - - - - - - - - + + diff --git a/TheOtherRoles/Utilities/CachedPlayer.cs b/TheOtherRoles/Utilities/CachedPlayer.cs index 3259c070..af4d8450 100644 --- a/TheOtherRoles/Utilities/CachedPlayer.cs +++ b/TheOtherRoles/Utilities/CachedPlayer.cs @@ -12,7 +12,7 @@ public class CachedPlayer public static readonly Dictionary PlayerPtrs = new(); public static readonly List AllPlayers = new(); public static CachedPlayer LocalPlayer; - public GameData.PlayerInfo Data; + public NetworkedPlayerInfo Data => PlayerControl.Data; public CustomNetworkTransform NetTransform; public PlayerControl PlayerControl; public byte PlayerId; @@ -70,13 +70,12 @@ public static void RemoveCachedPlayerPatch(PlayerControl __instance) CachedPlayer.PlayerPtrs.Remove(__instance.Pointer); } - [HarmonyPatch(typeof(GameData), nameof(GameData.Deserialize))] + [HarmonyPatch(typeof(NetworkedPlayerInfo), nameof(NetworkedPlayerInfo.Deserialize))] [HarmonyPostfix] public static void AddCachedDataOnDeserialize() { foreach (var cachedPlayer in CachedPlayer.AllPlayers) { - cachedPlayer.Data = cachedPlayer.PlayerControl.Data; cachedPlayer.PlayerId = cachedPlayer.PlayerControl.PlayerId; } } @@ -87,7 +86,6 @@ public static void AddCachedDataOnAddPlayer() { foreach (var cachedPlayer in CachedPlayer.AllPlayers) { - cachedPlayer.Data = cachedPlayer.PlayerControl.Data; cachedPlayer.PlayerId = cachedPlayer.PlayerControl.PlayerId; } } diff --git a/TheOtherRoles/packages.lock.json b/TheOtherRoles/packages.lock.json index 1b08c43a..575c74e2 100644 --- a/TheOtherRoles/packages.lock.json +++ b/TheOtherRoles/packages.lock.json @@ -4,9 +4,9 @@ "net6.0": { "AmongUs.GameLibs.Steam": { "type": "Direct", - "requested": "[2024.6.4, )", - "resolved": "2024.6.4", - "contentHash": "WTu/h9xYZ3r4RZP4yJQq3YPF31HV6cg7NN9Cd2DbZHloYUhMsD//xdE0x3k6YDRy9zbfhlJoUFTFDRcLipZEDQ==" + "requested": "[2024.9.4, )", + "resolved": "2024.9.4", + "contentHash": "5ZzigeztB4Y3xBM84Xl4bLBS/GGVe7tyZB6RxvUXHZS0xUP3RxqTGLeiB+xZSBlwD77aMrkZK0uJEh+MYvDB/A==" }, "BepInEx.IL2CPP.MSBuild": { "type": "Direct", @@ -22,19 +22,19 @@ }, "BepInEx.Unity.IL2CPP": { "type": "Direct", - "requested": "[6.0.0-be.697, )", - "resolved": "6.0.0-be.697", - "contentHash": "+ahFT8WkKZ8m9NCdXgQI05M34/mdE1MXmLnLRKhqpjId6mqDQf9ORJ1bCPifdkbgYJjteIvey9EreCfmD9Vndw==", + "requested": "[6.0.0-be.725, )", + "resolved": "6.0.0-be.725", + "contentHash": "lb6atWrBnVnQVOlaLBF3irZlbnA8gI46Jw/YlLBaeGra14W0q4aPVjUO5ODaBFzq/U0e7iAxzUNzesp3WPJ/tA==", "dependencies": { - "BepInEx.Core": "6.0.0-be.697", - "BepInEx.Unity.Common": "6.0.0-be.697", + "BepInEx.Core": "6.0.0-be.725", + "BepInEx.Unity.Common": "6.0.0-be.725", "HarmonyX": "2.10.2", "Iced": "1.21.0", "Il2CppInterop.Generator": "1.4.6-ci.426", "Il2CppInterop.HarmonySupport": "1.4.6-ci.426", "Il2CppInterop.Runtime": "1.4.6-ci.426", - "MonoMod.RuntimeDetour": "22.5.1.1", - "Samboy063.Cpp2IL.Core": "2022.1.0-development.972" + "MonoMod.RuntimeDetour": "22.7.31.1", + "Samboy063.Cpp2IL.Core": "2022.1.0-pre-release.18" } }, "Reactor": { @@ -48,46 +48,45 @@ }, "AsmResolver": { "type": "Transitive", - "resolved": "5.5.0", - "contentHash": "IuOC+b/D/da4fohYVNwo/NL+8w+q89O9B32bLotegJ+hmFlBEpQEKgtyhxc9ZfEd+x0KzwzD52RISuyLgf/BAA==" + "resolved": "6.0.0-beta.1", + "contentHash": "M5btCR/rmrx32jZsoN6CLQ/VQk8lN8hvPb6lgojua7pjNoo7StAl92koMC8qz4vzZyH2CNqxLSDoswRvyyK/vA==" }, "AsmResolver.DotNet": { "type": "Transitive", - "resolved": "5.5.0", - "contentHash": "T19DazP0h4qKXwPspTEB0ZzwlftPuvVAd68HhsS8eNYd9lRd/rtppcBmM2QLQdZeGGNJc+QEzLiAW+wrA3nKAw==", + "resolved": "6.0.0-beta.1", + "contentHash": "PTq8nNQvhgTxF1iARCknffCsu7Iq9B0kN7TVC8iMaU7uEYog3xvVqH/0+TreY8GW74/+MqhZt/yEFsvS4oAduQ==", "dependencies": { - "AsmResolver.PE": "5.5.0", - "System.Text.Json": "6.0.8" + "AsmResolver.PE": "6.0.0-beta.1" } }, "AsmResolver.PE": { "type": "Transitive", - "resolved": "5.5.0", - "contentHash": "bSPe0A+z4iEAabpD9h7ACQ5dkcTirx4fx05P194u/+OIUqlexHf7Zq/PEPdOkesbqHoZmgVmJ1H0GWqqouvZfA==", + "resolved": "6.0.0-beta.1", + "contentHash": "KadLvx/zzFCJyF+E4jG6jPE1d0iJquzL6+hm8GBivBAs6nwHC8s6g4c857QwQCzXMWza6Vz5Q+3hFiNuOfKaWQ==", "dependencies": { - "AsmResolver.PE.File": "5.5.0" + "AsmResolver.PE.File": "6.0.0-beta.1" } }, "AsmResolver.PE.File": { "type": "Transitive", - "resolved": "5.5.0", - "contentHash": "XHWHnPQf0e0VEJPTaWMoiajuikF0n0fDXS2XWzEXM+/xcY+LABsp1p7ETlg+bFsDVITQRtNTa/xV8eSDlSZjNQ==", + "resolved": "6.0.0-beta.1", + "contentHash": "+lusB9UMHevI5aQsu73NQ1ctPMLFvyHAsEf8vjaJ/py+kX1DkU0JkbERtBRmaf58/hBZ7cyrE7gFnjoo7Bbg7A==", "dependencies": { - "AsmResolver": "5.5.0" + "AsmResolver": "6.0.0-beta.1" } }, "AssetRipper.CIL": { "type": "Transitive", - "resolved": "1.0.0", - "contentHash": "l639dKLllpJ5TcX+Z1OVYz+hsKVZyMpEm59Dl4Qd6YrCHPVj9yPtF/UNjn9nFxoDm7suEFP/0vlZD/bSeXjz6Q==", + "resolved": "1.1.0", + "contentHash": "nSz1cBjgVeKv+esfDtyQGC1mY9b4C4NFStytdoa9DMozDC8uth6930kAsuWZEivj9GqWSqENnaQUGnl23WpmnQ==", "dependencies": { - "AsmResolver.DotNet": "5.5.0" + "AsmResolver.DotNet": "6.0.0-beta.1" } }, "AssetRipper.Gee.External.Capstone": { "type": "Transitive", - "resolved": "2.3.1", - "contentHash": "WVujToXc2sB5nVEY4iMpjhsQaqGw5RjG3c0Hl1qT/pZMbfwtafpaOwAa0G/GS5gd2jcuJwrsG880Pkyjkhi3vQ==" + "resolved": "2.3.2", + "contentHash": "wOr5PQPL/2ZfD7+ebt6cpRbUhSzSY5nlHGHjjzuQRiU5zkQlqQNwWDLX0M3smrm5IkaDvONkmDjFMKTlZJmyuQ==" }, "AssetRipper.Primitives": { "type": "Transitive", @@ -96,27 +95,27 @@ }, "BepInEx.Core": { "type": "Transitive", - "resolved": "6.0.0-be.697", - "contentHash": "6p/zLtBja8BEA5+FwFwH1lUg8avO725mZKRw0P1JbuXj/XUZL8Qy5n0c7COiq/dJ58nCyW5J/ldeYUHM0c4vRA==", + "resolved": "6.0.0-be.725", + "contentHash": "xBqYH8OtmEfwe7ZRvQDkJF4cPRgyoykcYRXcuszeVWI+0e/7IYZ316wT3HhRU/GLQE6FijuMFGag73jTxMmoxA==", "dependencies": { "HarmonyX": "2.10.2", - "MonoMod.Utils": "22.5.1.1", + "MonoMod.Utils": "22.7.31.1", "SemanticVersioning": "2.0.2" } }, "BepInEx.Unity.Common": { "type": "Transitive", - "resolved": "6.0.0-be.697", - "contentHash": "6eTjN4vBy7veWUwCVWqfvL05fQ4MskpjD4wIsD0FF8g0kF/1lKjsK0Fmyb4N78vSrvm/tV1quhHChCh2SQU0GQ==", + "resolved": "6.0.0-be.725", + "contentHash": "2onnkxl2Ai88JwhxXXZld6bKjICwhLav/msfK9tIVJObCcxJkvWWGGXmUD+KquQtKjNj4hrExWwZa+zPnbUsTA==", "dependencies": { "AssetRipper.Primitives": "3.1.3", - "MonoMod.Utils": "22.5.1.1" + "MonoMod.Utils": "22.7.31.1" } }, "Disarm": { "type": "Transitive", - "resolved": "2022.1.0-master.26", - "contentHash": "YnZEbRGr0nG+N3G8WbRQ4Lkg8dTD3oso9iJlCVBmyhEyhLyqs+drBs1kWQbQqFPnb9mi/RJ++R9bPb+L3HF03Q==" + "resolved": "2022.1.0-master.34", + "contentHash": "sxzTci5eSdl+sFoaGsMZIp7X/eB5ZzplM3CppvD1CWoiZ8rSa43XGLC19G5e8n6mjutNBfN9yL+RER5PCspHFg==" }, "HarmonyX": { "type": "Transitive", @@ -191,11 +190,11 @@ }, "MonoMod.RuntimeDetour": { "type": "Transitive", - "resolved": "22.5.1.1", - "contentHash": "WG5zLRuAr8KJEnIkKTuIG1OJCrGIT3pjvnAD43E0FDchHf3Dp985MF/8tmIQvAzCZV87JNs6QKeGGqmwDmpXpw==", + "resolved": "22.7.31.1", + "contentHash": "nxVJTvQbWAujaogt5XX3eAy7d22t66Z88aWg9sirPLO9rR/6yNCHAyZpgxXrOsIobZVW0IEZPqNMOBhgke25/w==", "dependencies": { "Mono.Cecil": "0.11.4", - "MonoMod.Utils": "22.5.1.1", + "MonoMod.Utils": "22.7.31.1", "System.Collections.NonGeneric": "4.3.0", "System.ComponentModel.TypeConverter": "4.3.0", "System.IO.FileSystem.Primitives": "4.3.0", @@ -206,8 +205,8 @@ }, "MonoMod.Utils": { "type": "Transitive", - "resolved": "22.5.1.1", - "contentHash": "vBObO1atXxhi2C4AuC53y87Bqeogi9xIrD1Ym3YWr5uxc8Nrm8SrsFeD1i3x04R999+XQ3FdeHrbXScyWYEHqQ==", + "resolved": "22.7.31.1", + "contentHash": "nI0E1oadXS1iMbfwfCzYF08C1jRQR9cnnHv66a4BSPd4sGu2p6g4BmctCWsdAB6oGKkSJUhcfHfxcfTsDyB94Q==", "dependencies": { "Mono.Cecil": "0.11.4", "System.Collections.NonGeneric": "4.3.0", @@ -318,31 +317,31 @@ }, "Samboy063.Cpp2IL.Core": { "type": "Transitive", - "resolved": "2022.1.0-development.972", - "contentHash": "nCO5VGiZzMqdtf1yZZQwhJ+DHklSBqDxF25mTsfw8mP56wt4TBYiQyXnj2EASqbz2VN0+NqUB3jlcuOgD0gNHg==", + "resolved": "2022.1.0-pre-release.18", + "contentHash": "eX9d1IK05jWaEaeuMAE0L5WYHT7thtxz+aWLL/CAaCzZ0TzRPD+WFTjJ0KQO0YWBVO300CX3GwmPmf7TNO+wUg==", "dependencies": { - "AsmResolver.DotNet": "5.5.0", - "AssetRipper.CIL": "1.0.0", - "AssetRipper.Gee.External.Capstone": "2.3.1", - "Disarm": "2022.1.0-master.26", - "Iced": "1.20.0", - "Samboy063.LibCpp2IL": "2022.1.0-development.972", - "StableNameDotNet": "0.1.0-development.972" + "AsmResolver.DotNet": "6.0.0-beta.1", + "AssetRipper.CIL": "1.1.0", + "AssetRipper.Gee.External.Capstone": "2.3.2", + "Disarm": "2022.1.0-master.34", + "Iced": "1.21.0", + "Samboy063.LibCpp2IL": "2022.1.0-pre-release.18", + "StableNameDotNet": "0.1.0-pre-release.15" } }, "Samboy063.LibCpp2IL": { "type": "Transitive", - "resolved": "2022.1.0-development.972", - "contentHash": "8GtNi2i4CVXlunDyNhV1cZrxWNxlPejD5VPHgQ14bYrTjG8Rn7nGDt64B5cklGUT/FMADA9t/ZAALTMJ6UXpTA==", + "resolved": "2022.1.0-pre-release.18", + "contentHash": "9zJdTAeErpwJpYDHYwwI0MAC1OyBEfC1ce7dpAOYRUUYCfeaKVWxnSCcyaoY6HDzIoxPkhbfllbwOe49ZmUYuQ==", "dependencies": { - "AssetRipper.Primitives": "2.1.0", - "Samboy063.WasmDisassembler": "2022.1.0-development.972" + "AssetRipper.Primitives": "3.1.2", + "Samboy063.WasmDisassembler": "2022.1.0-pre-release.15" } }, "Samboy063.WasmDisassembler": { "type": "Transitive", - "resolved": "2022.1.0-development.972", - "contentHash": "lfbUsyjArvISK9oJBx+QmDwtjXg425K66BmLUoeqzJ11kt0EAUMM34qGEMDceNyNYfl5Op5RpS+krkq/sudM4g==" + "resolved": "2022.1.0-pre-release.15", + "contentHash": "e6qw81SHS+fS7iZ3qfqZBavVarYbkPElNgDCANF6dNFTYq5+hc80am+4FqQDl+ZVNS47bZDZobxIzHhmriCXGg==" }, "SemanticVersioning": { "type": "Transitive", @@ -351,8 +350,8 @@ }, "StableNameDotNet": { "type": "Transitive", - "resolved": "0.1.0-development.972", - "contentHash": "1G965uhTTEI5sKU/CFMGuhzuxDophrYS2otI3Ej+BAhbEOq//LFWpoEwhaWW5moKW0K56ZCqvB8YqnEKyk9kbA==" + "resolved": "0.1.0-pre-release.15", + "contentHash": "aIkEOo8V76vE+9CppHpTFLGXalBw6TAl4/tb6vadmS+gHJMshTVehzQv9cJXy4xZDdANV1uGMRaUFZERcDA2xQ==" }, "System.Collections": { "type": "Transitive", @@ -679,11 +678,6 @@ "Microsoft.NETCore.Targets": "1.1.0" } }, - "System.Runtime.CompilerServices.Unsafe": { - "type": "Transitive", - "resolved": "6.0.0", - "contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==" - }, "System.Runtime.Extensions": { "type": "Transitive", "resolved": "4.3.0", @@ -882,23 +876,6 @@ "System.Runtime": "4.3.0" } }, - "System.Text.Encodings.Web": { - "type": "Transitive", - "resolved": "6.0.0", - "contentHash": "Vg8eB5Tawm1IFqj4TVK1czJX89rhFxJo9ELqc/Eiq0eXy13RK00eubyU6TJE6y+GQXjyV5gSfiewDUZjQgSE0w==", - "dependencies": { - "System.Runtime.CompilerServices.Unsafe": "6.0.0" - } - }, - "System.Text.Json": { - "type": "Transitive", - "resolved": "6.0.8", - "contentHash": "WhW6zPEgRZoo+c1NEvSSmrME4+LqXmW6tcsRFsEiSMeco+qZ9rpLs7tT53EIkE/s9GNTYS4/STQoaGiKDSWifQ==", - "dependencies": { - "System.Runtime.CompilerServices.Unsafe": "6.0.0", - "System.Text.Encodings.Web": "6.0.0" - } - }, "System.Threading": { "type": "Transitive", "resolved": "4.3.0",