From cd559fdde1e289fb474a9aceeae5baa68d2bbf52 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 +- CHANGELOG.md | 12 +- Strings.xlsx | Bin 85431 -> 85907 bytes TheOtherRoles.sln | 3 - TheOtherRoles/Buttons/Buttons.cs | 34 +- TheOtherRoles/CustomCosmetics/CustomColors.cs | 44 +- .../CustomHats/CustomHatManager.cs | 9 +- .../CustomCosmetics/CustomHats/HatsLoader.cs | 12 +- .../CustomHats/Patches/HatParentPatche.cs | 236 --- .../CustomHats/Patches/HatParentPatches.cs | 21 +- .../CustomHats/Patches/HatsTabPatches.cs | 13 +- .../CustomGameModes/GameModePatches.cs | 61 + TheOtherRoles/Helper/Helpers.cs | 53 +- TheOtherRoles/Main.cs | 11 +- TheOtherRoles/Modules/ChatCommands.cs | 4 +- TheOtherRoles/Modules/CrowdedPlayer.cs | 18 +- TheOtherRoles/Modules/DynamicLobbies.cs | 5 - TheOtherRoles/Modules/KeyboardHandler.cs | 20 +- TheOtherRoles/Objects/Footprint.cs | 2 +- .../CreateModOptions.cs} | 113 +- TheOtherRoles/Options/CustomOptionHolder.cs | 4 +- TheOtherRoles/Options/CustomOptions.cs | 1448 ++++++++--------- TheOtherRoles/Options/ModOption.cs | 6 +- TheOtherRoles/Patches/CredentialsPatch.cs | 47 +- TheOtherRoles/Patches/EndGamePatch.cs | 387 ++--- TheOtherRoles/Patches/ExileControllerPatch.cs | 44 +- .../Patches/GameStartManagerPatch.cs | 61 +- TheOtherRoles/Patches/GetStringPatch.cs | 24 + TheOtherRoles/Patches/LobbyBehaviourPatch.cs | 27 + TheOtherRoles/Patches/LobbyRoleList.cs | 18 +- TheOtherRoles/Patches/MeetingHudPatch.cs | 10 +- TheOtherRoles/Patches/PlayerControlPatch.cs | 6 +- TheOtherRoles/Patches/RoleAssignmentPatch.cs | 22 +- TheOtherRoles/Patches/ShipStatusPatch.cs | 2 +- .../Patches/TransportationToolPatches.cs | 6 +- TheOtherRoles/Patches/UsablesPatch.cs | 4 +- TheOtherRoles/RPC.cs | 19 +- 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/Roles/RoleHelpers.cs | 1 - TheOtherRoles/TasksHandler.cs | 4 +- TheOtherRoles/TheOtherRoles.csproj | 15 +- TheOtherRoles/Utilities/CachedPlayer.cs | 6 +- TheOtherRoles/packages.lock.json | 135 +- 56 files changed, 1440 insertions(+), 1577 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/CHANGELOG.md b/CHANGELOG.md index 82c91968..87478c5b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,6 @@ -v1.1.1.1更新日志 +v1.2.0.0 - Beta更新日志 -* 新增伪装者职业:狼之主 -* 新增附加能力:迷乱旋涡 -* 修复巨人的体型在其他玩家不可见的问题 -* 修复分散者的坐标问题 - -注:本次仅更新Lite分支 \ No newline at end of file +* 适配Among Us最新版本(2024.8.13~2024.11.26) +* 新增模组选项:游戏内显示聊天气泡 +* 新增模组选项:静音大厅BGM +* 新增模组选项:强制使用+25协议(目前启用该选项后,无法进入房间) diff --git a/Strings.xlsx b/Strings.xlsx index 3857c3a07489c4d6ea11b30ad5b6ca0bc87d3668..df4c3f2d73787b265ed19ebd80def80375ff1f42 100644 GIT binary patch delta 61865 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 BO^N^j 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..b5537061 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,47 +389,18 @@ 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(); }, () => { - if (!CanSeeRoleInfo) return false; - if (PlayerControl.LocalPlayer.IsAlive()) return false; + if (!shouldShowGhostInfo() || InMeeting) return false; var (playerCompleted, playerTotal) = TasksHandler.taskInfo(CachedPlayer.LocalPlayer.Data); var numberOfLeftTasks = playerTotal - playerCompleted; return numberOfLeftTasks <= 0 || !CustomOptionHolder.finishTasksBeforeHauntingOrZoomingOut.GetBool(); }, () => { 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..499ca5dd 100644 --- a/TheOtherRoles/CustomCosmetics/CustomColors.cs +++ b/TheOtherRoles/CustomCosmetics/CustomColors.cs @@ -104,7 +104,7 @@ public static void Load() var colorlist = Palette.PlayerColors.ToList(); var shadowlist = Palette.ShadowColors.ToList(); - var id = 50000; + var id = 60000; foreach (var entry in CustomColorData.OrderBy(entry => (int)entry.Key)) { var colorType = entry.Key; @@ -133,20 +133,56 @@ private class ColorStringPatch [HarmonyPriority(Priority.Last)] public static bool Prefix(ref string __result, [HarmonyArgument(0)] StringNames name) { - if ((int)name >= 50000) + if ((int)name >= 60000) { - var text = ColorStrings[(int)name]; - if (text != null) + if (ColorStrings.TryGetValue((int)name, out var text)) { __result = $"color{text}".Translate(); return false; } + else + { + Error($"Key '{(int)name}' not found in ColorStrings."); + } } return true; } } + [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/CustomHatManager.cs b/TheOtherRoles/CustomCosmetics/CustomHats/CustomHatManager.cs index dbcd0e3a..4d2bb066 100644 --- a/TheOtherRoles/CustomCosmetics/CustomHats/CustomHatManager.cs +++ b/TheOtherRoles/CustomCosmetics/CustomHats/CustomHatManager.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.IO; using System.Security.Cryptography; @@ -78,15 +78,12 @@ internal static HatData CreateHatBehaviour(CustomHatConfig ch, bool testOnly = f hat.name = ch.Name; hat.displayOrder = 99; - hat.ProductId = "hat_" + ch.Name.Replace(' ', '_'); + hat.ProductId = "Mod_" + ch.Name.Replace(' ', '_'); hat.InFront = !ch.Behind; hat.NoBounce = !ch.Bounce; hat.ChipOffset = new Vector2(0f, 0.2f); hat.Free = true; -#if MXYX_CLUB - if (ch.Adaptive && cachedShader != null) - viewData.AltShader = cachedShader; -#endif + var extend = new HatExtension { Author = ch.Author ?? "Unknown", diff --git a/TheOtherRoles/CustomCosmetics/CustomHats/HatsLoader.cs b/TheOtherRoles/CustomCosmetics/CustomHats/HatsLoader.cs index 154d1892..bdc8dc3a 100644 --- a/TheOtherRoles/CustomCosmetics/CustomHats/HatsLoader.cs +++ b/TheOtherRoles/CustomCosmetics/CustomHats/HatsLoader.cs @@ -1,5 +1,6 @@ -using System; +using System; using System.Collections; +using System.Collections.Generic; using System.IO; using System.Text.Json; using BepInEx.Unity.IL2CPP.Utils; @@ -124,9 +125,14 @@ private void ProcessHatsData(HatsConfigFile response) Message($"准备下载 {toDownload.Count} 项帽子文件"); + this.StartCoroutine(CoDownloadHats(toDownload)); + } + + private static IEnumerator CoDownloadHats(List toDownload) + { foreach (var fileName in toDownload) { - this.StartCoroutine(CoDownloadHatAsset(fileName)); + yield return CoDownloadHatAsset(fileName); } } @@ -146,7 +152,7 @@ private static IEnumerator CoDownloadHatAsset(string fileName) if (www.isNetworkError || www.isHttpError) { - Error(www.error); + Error($"{www.error} {fileName}"); yield break; } 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..8bd7e84d 100644 --- a/TheOtherRoles/CustomCosmetics/CustomHats/Patches/HatParentPatches.cs +++ b/TheOtherRoles/CustomCosmetics/CustomHats/Patches/HatParentPatches.cs @@ -1,4 +1,3 @@ -#if !MXYX_CLUB using System; using System.IO; using System.Linq; @@ -7,7 +6,6 @@ namespace TheOtherRoles.CustomCosmetics.CustomHats.Patches; - [HarmonyPatch(typeof(HatParent))] internal static class HatParentPatches { @@ -162,7 +160,7 @@ private static bool SetFloorAnimPrefix(HatParent __instance) [HarmonyPrefix] private static bool SetIdleAnimPrefix(HatParent __instance, int colorId) { - if (!__instance.Hat) return false; + if (__instance.Hat == null || !__instance.Hat.ProductId.StartsWith("MOD_")) return true; if (!__instance.IsCached()) return true; __instance.viewAsset = null; __instance.PopulateFromViewData(); @@ -174,11 +172,13 @@ private static bool SetIdleAnimPrefix(HatParent __instance, int colorId) [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; + if (__instance.Hat == null || !__instance.Hat.ProductId.StartsWith("MOD_")) return true; + if (__instance.TryGetCached(out var hatViewData) && __instance.options.ShowForClimb) + { + __instance.BackLayer.enabled = false; + __instance.FrontLayer.enabled = true; + __instance.FrontLayer.sprite = hatViewData.ClimbImage; + } return false; } @@ -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; @@ -243,5 +243,4 @@ private static bool SetCustomHat(HatParent hatParent) return false; } -} -#endif \ No newline at end of file +} \ No newline at end of file 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..e93ae7df 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,39 @@ 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 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 +1089,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 +1376,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..fa27dd5e 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(); @@ -101,7 +109,6 @@ public override void Load() SubmergedCompatibility.Initialize(); MainMenuPatch.addSceneChangeCallbacks(); - AddToKillDistanceSetting.addKillDistance(); Info($"\n---------------\n Loading TheOtherUs completed!\n TheOtherUs-Edited v{VersionString}-Lite\n---------------"); } } 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/DynamicLobbies.cs b/TheOtherRoles/Modules/DynamicLobbies.cs index 2f635c5c..0dd5172a 100644 --- a/TheOtherRoles/Modules/DynamicLobbies.cs +++ b/TheOtherRoles/Modules/DynamicLobbies.cs @@ -39,12 +39,7 @@ private static bool Prefix(ChatController __instance) GameOptionsManager.Instance.currentNormalGameOptions.MaxPlayers = LobbyLimit; FastDestroyableSingleton.Instance.LastPlayerCount = LobbyLimit; CachedPlayer.LocalPlayer.PlayerControl.RpcSyncSettings( -#if MXYX_CLUB - // TODO Maybe simpler?? - GameOptionsManager.Instance.gameOptionsFactory.ToBytes(GameOptionsManager.Instance.currentGameOptions)); -#else GameOptionsManager.Instance.gameOptionsFactory.ToBytes(GameOptionsManager.Instance.currentGameOptions, false)); -#endif __instance.AddChat(CachedPlayer.LocalPlayer.PlayerControl, $"Lobby Size changed to {LobbyLimit} players"); } diff --git a/TheOtherRoles/Modules/KeyboardHandler.cs b/TheOtherRoles/Modules/KeyboardHandler.cs index f3657f3e..5e4e97d9 100644 --- a/TheOtherRoles/Modules/KeyboardHandler.cs +++ b/TheOtherRoles/Modules/KeyboardHandler.cs @@ -1,19 +1,15 @@ -using System; using System.Collections.Generic; using System.Linq; using TheOtherRoles.Buttons; using TheOtherRoles.Patches; using TheOtherRoles.Utilities; using UnityEngine; -using Random = System.Random; namespace TheOtherRoles.Modules; [HarmonyPatch(typeof(KeyboardJoystick), nameof(KeyboardJoystick.Update))] public class KeyboardHandler { - //private static readonly string passwordHash = "d1f51dfdfd8d38027fd2ca9dfeb299399b5bdee58e6c0b3b5e9a45cd4e502848"; - private static readonly Random random = new((int)DateTime.Now.Ticks); private static readonly List bots = new(); private static void Postfix(KeyboardJoystick __instance) @@ -21,7 +17,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 +33,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) { @@ -59,11 +55,21 @@ private static void Postfix(KeyboardJoystick __instance) GameStartManager.Instance.countDownTimer = 0; } } + + if (Input.GetKeyDown(ModInputManager.helpInput.keyCode)) + { + if (LobbyRoleInfo.RolesSummaryUI == null) LobbyRoleInfo.RoleSummaryOnClick(); + else + { + Object.Destroy(LobbyRoleInfo.RolesSummaryUI); + LobbyRoleInfo.RolesSummaryUI = null; + } + } } public static string RandomString(int length) { const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; - return new string(Enumerable.Repeat(chars, length).Select(s => s[random.Next(s.Length)]).ToArray()); + return new string(Enumerable.Repeat(chars, length).Select(s => s[rnd.Next(s.Length)]).ToArray()); } } 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/CustomOptionHolder.cs b/TheOtherRoles/Options/CustomOptionHolder.cs index 053c383d..2a8d6937 100644 --- a/TheOtherRoles/Options/CustomOptionHolder.cs +++ b/TheOtherRoles/Options/CustomOptionHolder.cs @@ -828,7 +828,7 @@ public static void Load() eraserCanEraseAnyone = Create(10162, Types.Impostor, "eraserCanEraseAnyone", false, eraserSpawnRate); erasercanEraseGuess = Create(10163, Types.Impostor, "erasercanEraseGuess", false, eraserSpawnRate); - poucherSpawnRate = Create(10320, Types.Impostor, cs(Palette.ImpostorRed, "Poucher"), rates, null, true, () => + poucherSpawnRate = Create(10320, Types.Impostor, cs(Palette.ImpostorRed, "Poucher"), rates, null, true, false, () => { if (modifierPoucher.selection > 0) poucherSpawnRate.selection = 0; }); @@ -1272,7 +1272,7 @@ public static void Load() modifierDisperser = Create(40100, Types.Modifier, cs(Palette.ImpostorRed, "Disperser"), rates, null, true); modifierDisperserDispersesToVent = Create(40101, Types.Modifier, "modifierDisperserDispersesToVent", true, modifierDisperser); - modifierPoucher = Create(40370, Types.Modifier, cs(Palette.ImpostorRed, "Poucher"), rates, null, true, () => + modifierPoucher = Create(40370, Types.Modifier, cs(Palette.ImpostorRed, "Poucher"), rates, null, true, false, () => { poucherSpawnRate.selection = 0; }); diff --git a/TheOtherRoles/Options/CustomOptions.cs b/TheOtherRoles/Options/CustomOptions.cs index 64af1343..1761f752 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; @@ -36,26 +31,26 @@ public enum CustomOptionType 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 = ""; + public bool isHidden; // 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, bool isHidden = false, 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 +59,32 @@ public CustomOption(int id, CustomOptionType type, string name, object[] selecti this.isHeader = isHeader; this.type = type; this.onChange = onChange; + this.heading = heading; + this.isHidden = isHidden; 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, bool isHidden = 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, isHidden, 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, bool isHidden = 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, isHidden, 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, bool isHidden = 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, isHidden, onChange, heading); } // Static behaviour @@ -102,13 +95,11 @@ public static void switchPreset(int newPreset) preset = newPreset; vanillaSettings = Main.Instance.Config.Bind($"Preset{preset}", "GameOptions", ""); loadVanillaOptions(); - foreach (var option in options) + foreach (var option in options.Where(x => !x.IsHidden() && x.IsEnbaled())) { 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 +111,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 +144,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 +158,6 @@ public static void ShareOptionSelections() writer.WritePacked((uint)option.id); writer.WritePacked(Convert.ToUInt32(option.selection)); } - AmongUsClient.Instance.FinishRpcImmediately(writer); } } @@ -204,7 +191,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,40 +208,76 @@ public virtual string getName() return name.Translate(); } + public virtual string getHeading() + { + if (heading == "") return ""; + return heading.Translate(); + } + // 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) + { + 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 { } + } + + selection = newSelection; + if (doNeedNotifier) { - if (onChange != null) onChange(); + DestroyableSingleton.Instance.Notifier + .AddModSettingsChangeMessage((StringNames)(id + 6000), getString(), getName().Replace("- ", ""), false); } - catch + + try { - // ignored + onChange?.Invoke(); } + catch { } - if (optionBehaviour != null && optionBehaviour is StringOption stringOption) + if (optionBehaviour is not null and 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 + } + // test + if (AmongUsClient.Instance?.AmClient == true) + { + try + { + if (GameStartManager.Instance != null && GameStartManager.Instance.LobbyInfoPane != null && GameStartManager.Instance.LobbyInfoPane.LobbyViewSettingsPane != null) + { + LobbyViewSettingsPaneChangeTabPatch.Postfix(GameStartManager.Instance.LobbyInfoPane.LobbyViewSettingsPane, GameStartManager.Instance.LobbyInfoPane.LobbyViewSettingsPane.currentTab); + } + } + catch { } } } @@ -274,7 +297,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 +304,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 +326,611 @@ 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 +public static class CustomOptionsExtensions { - public static void Postfix(GameOptionsMenu __instance) + 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 bool IsHidden(this CustomOption option) + { + return option.isHidden; + } + + public static bool IsEnbaled(this CustomOption option) { - switch (ModOption.gameMode) + var enabled = true; + var parent = option.parent; + while (parent != null && enabled) { - case CustomGamemodes.Classic: - createClassicTabs(__instance); - break; - case CustomGamemodes.Guesser: - createGuesserTabs(__instance); - break; + enabled = parent.selection != 0; + parent = parent.parent; } - // 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)(() => + return !option.IsHidden() && enabled; + } +} + + +[HarmonyPatch(typeof(GameSettingMenu), nameof(GameSettingMenu.ChangeTab))] +internal class GameOptionsMenuChangeTabPatch +{ + public static void Postfix(GameSettingMenu __instance, int tabNum, bool previewOnly) + { + if (previewOnly) return; + foreach (var tab in GameOptionsMenuStartPatch.currentTabs) { - 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)(() => + if (tab != null) + tab.SetActive(false); + } + foreach (var pbutton in GameOptionsMenuStartPatch.currentButtons) { - 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; - }))); - })); + pbutton.SelectButton(false); + } + if (tabNum > 2) + { + 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(); - - var torSettings = Object.Instantiate(gameSettings, gameSettings.transform.parent); - var torMenu = getMenu(torSettings, "TORSettings"); + if ((int)__instance.currentTab < 15) + { + LobbyViewSettingsPaneChangeTabPatch.Postfix(__instance, __instance.currentTab); + return false; + } + return true; + } +} - var impostorSettings = Object.Instantiate(gameSettings, gameSettings.transform.parent); - var impostorMenu = getMenu(impostorSettings, "ImpostorSettings"); +[HarmonyPatch(typeof(LobbyViewSettingsPane), nameof(LobbyViewSettingsPane.ChangeTab))] +internal class LobbyViewSettingsPaneChangeTabPatch +{ + public static void Postfix(LobbyViewSettingsPane __instance, StringNames category) + { + var tabNum = (int)category; - var neutralSettings = Object.Instantiate(gameSettings, gameSettings.transform.parent); - var neutralMenu = getMenu(neutralSettings, "NeutralSettings"); + 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 crewmateSettings = Object.Instantiate(gameSettings, gameSettings.transform.parent); - var crewmateMenu = getMenu(crewmateSettings, "CrewmateSettings"); + if (tabNum > 2) + { + tabNum -= 3; + //GameOptionsMenuStartPatch.currentTabs[tabNum].SetActive(true); + LobbyViewSettingsPatch.currentButtons[tabNum].SelectButton(true); + LobbyViewSettingsPatch.drawTab(__instance, LobbyViewSettingsPatch.currentButtonTypes[tabNum]); + } + } +} - var modifierSettings = Object.Instantiate(gameSettings, gameSettings.transform.parent); - var modifierMenu = getMenu(modifierSettings, "ModifierSettings"); +[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 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"); - var impostorTab = Object.Instantiate(roleTab, torTab.transform); - var impostorTabHighlight = - getTabHighlight(impostorTab, "ImpostorTab", "TheOtherRoles.Resources.TabIconImpostor.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 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); + createSettingTabs(__instance); + } - var modifierTab = Object.Instantiate(roleTab, crewmateTab.transform); - var modifierTabHighlight = - getTabHighlight(modifierTab, "ModifierTab", "TheOtherRoles.Resources.TabIconModifier.png"); + public static void removeVanillaTabs(LobbyViewSettingsPane __instance) + { + GameObject.Find("RolesTabs")?.Destroy(); + var overview = GameObject.Find("OverviewTab"); + if (!gameModeChangedFlag) + { + overview.transform.localScale = new Vector3(0.58f * overview.transform.localScale.x, overview.transform.localScale.y, overview.transform.localScale.z); + overview.transform.localPosition += new Vector3(-1.05f, 0f, 0f); - // 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; + } + overview.transform.Find("FontPlacer").transform.localScale = new Vector3(1.2f, 1f, 1f); + overview.transform.Find("FontPlacer").transform.localPosition = new Vector3(-0.1f, -0.1f, 0f); + gameModeChangedFlag = false; + } - 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 createSettingTabs(LobbyViewSettingsPane __instance) + { + // Handle different gamemodes and tabs needed therein. + var next = 3; + if (ModOption.gameMode is CustomGamemodes.Guesser or 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); })); + // create TOR settings + createCustomButton(__instance, next++, "TORSettings", "theOtherRolesSettings".Translate(), CustomOptionType.General); + // IMp + createCustomButton(__instance, next++, "ImpostorSettings", "impostorRolesSettings".Translate(), CustomOptionType.Impostor); + // 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); + } + } - destroyOptions(new List> + 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) { - torMenu.GetComponentsInChildren().ToList(), - impostorMenu.GetComponentsInChildren().ToList(), - neutralMenu.GetComponentsInChildren().ToList(), - crewmateMenu.GetComponentsInChildren().ToList(), - modifierMenu.GetComponentsInChildren().ToList() - }); + torSettingsButton = UnityEngine.Object.Instantiate(buttonTemplate, buttonTemplate.transform.parent); + torSettingsButton.transform.localPosition += Vector3.right * 2.06f * (targetMenu - 2); + torSettingsButton.name = buttonName; + //torSettingsButton.transform.localScale += Vector3.right * 0.09f; + __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 torOptions = new List(); - var impostorOptions = new List(); - var neutralOptions = new List(); - var crewmateOptions = new List(); - var modifierOptions = new List(); + public static void drawTab(LobbyViewSettingsPane __instance, CustomOptionType optionType) + { + var relevantOptions = options.Where(x => !x.IsHidden() && x.IsEnbaled() && + (x.type == optionType || (x.type == CustomOptionType.Guesser && optionType == CustomOptionType.General))).ToList(); + // Exclude guesser options in neutral mode + if (ModOption.gameMode == CustomGamemodes.Guesser) + relevantOptions = relevantOptions.Where(x => !new List + { 10000, 10001, 10002, 10003, 10004, 10005, 10006, 10007, 10008, 30100, 30101, 30102, 30103, 30104 }.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(); - for (var i = 0; i < options.Count; i++) + var num = 1.44f; + var i = 0; + var singles = 0; + var headers = 0; + var lines = 0; + var curType = CustomOptionType.Modifier; + + foreach (var option in relevantOptions.Where(x => !x.IsHidden() && x.IsEnbaled())) { - var option = options[i]; - if ((int)option.type > 4) continue; - if (option.optionBehaviour == null) + if (option.isHeader || 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 } - ); + } +} + +[HarmonyPatch(typeof(GameOptionsMenu), nameof(GameOptionsMenu.CreateSettings))] +internal class GameOptionsMenuCreateSettingsPatch +{ + public static void Postfix(GameOptionsMenu __instance) + { + if (__instance.gameObject.name == "GAME SETTINGS TAB") + adaptTaskCount(__instance); + } - adaptTaskCount(__instance); + private static void adaptTaskCount(GameOptionsMenu __instance) + { + // 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 void createGuesserTabs(GameOptionsMenu __instance) + +[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 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++) - { - var button = tabs[i].GetComponentInChildren(); - if (button == null) continue; - var copiedIndex = i; - button.OnClick = new Button.ButtonClickedEvent(); - button.OnClick.AddListener((Action)(() => { setListener(settingsHighlightMap, copiedIndex); })); - } + currentTabs.ForEach(x => x?.Destroy()); + currentButtons.ForEach(x => x?.Destroy()); + currentTabs = new(); + currentButtons = new(); - 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(); + if (GameOptionsManager.Instance.currentGameOptions.GameMode == GameModes.HideNSeek) return; - option.optionBehaviour = stringOption; - } + removeVanillaTabs(__instance); - option.optionBehaviour.gameObject.SetActive(true); - } + createSettingTabs(__instance); - 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 } - ); + var GOMGameObject = GameObject.Find("GAME SETTINGS TAB"); - adaptTaskCount(__instance); + // 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 void setListener(Dictionary settingsHighlightMap, int index) + private static void createSettingTabs(GameSettingMenu __instance) { - foreach (var entry in settingsHighlightMap) + // Handle different gamemodes and tabs needed therein. + var next = 3; + if (ModOption.gameMode is CustomGamemodes.Guesser or CustomGamemodes.Classic) { - entry.Key.SetActive(false); - entry.Value.enabled = false; + // 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"); } - - settingsHighlightMap.ElementAt(index).Key.SetActive(true); - settingsHighlightMap.ElementAt(index).Value.enabled = true; } - private static void destroyOptions(List> optionBehavioursList) + private static void removeVanillaTabs(GameSettingMenu __instance) { - foreach (var optionBehaviours in optionBehavioursList) - foreach (var option in optionBehaviours) - Object.Destroy(option.gameObject); + GameObject.Find("What Is This?")?.Destroy(); + GameObject.Find("GamePresetButton")?.Destroy(); + GameObject.Find("RoleSettingsButton")?.Destroy(); + __instance.ChangeTab(1, false); } - - private static bool setNames(Dictionary gameObjectNameDisplayNameMap) + public static void createCustomButton(GameSettingMenu __instance, int targetMenu, string buttonName, string buttonText) { - foreach (var entry in gameObjectNameDisplayNameMap) - if (GameObject.Find(entry.Key) != null) + 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) + { + 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)(() => { - // 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; + __instance.ChangeTab(targetMenu, false); + })); + torSettingsPassiveButton.OnMouseOut.RemoveAllListeners(); + torSettingsPassiveButton.OnMouseOver.RemoveAllListeners(); + torSettingsPassiveButton.SelectButton(false); + currentButtons.Add(torSettingsPassiveButton); + } } - private static GameOptionsMenu getMenu(GameObject setting, string settingName) + public static void createGameOptionsMenu(GameSettingMenu __instance, CustomOptionType optionType, string settingName) { - var menu = setting.transform.FindChild("GameGroup").FindChild("SliderInner").GetComponent(); - setting.name = settingName; + var tabTemplate = GameObject.Find("GAME SETTINGS TAB"); + currentTabs.RemoveAll(x => x == null); - return menu; - } - - private static SpriteRenderer getTabHighlight(GameObject tab, string tabName, string tabSpritePath) - { - 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 torSettingsTab = UnityEngine.Object.Instantiate(tabTemplate, tabTemplate.transform.parent); + torSettingsTab.name = settingName; - return tabHighlight; + var torSettingsGOM = torSettingsTab.GetComponent(); + foreach (var child in torSettingsGOM.Children) + { + 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 + { 10000, 10001, 10002, 10003, 10004, 10005, 10006, 10007, 10008, 30100, 30101, 30102, 30103, 30104 }.Contains(x.id)).ToList(); + createSettings(torSettingsGOM, relevantOptions); + + currentTabs.Add(torSettingsTab); + torSettingsTab.SetActive(false); } - private static void setOptions(List menus, List> options, - List settings) + public static void createSettings(GameOptionsMenu menu, List options) { - if (!(menus.Count == options.Count && options.Count == settings.Count)) + var num = 1.5f; + foreach (var option in options) { - Error("List counts are not equal"); - return; + 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); } - for (var i = 0; i < menus.Count; i++) + for (var i = 0; i < menu.Children.Count; i++) { - menus[i].Children = options[i].ToArray(); - settings[i].gameObject.SetActive(false); + var optionBehaviour = menu.Children[i]; + if (AmongUsClient.Instance && !AmongUsClient.Instance.AmHost) + optionBehaviour.SetAsPlayer(); } } - - private static void adaptTaskCount(GameOptionsMenu __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); - - var shortTasksOption = - __instance.Children.FirstOrDefault(x => x.name == "NumShortTasks").TryCast(); - if (shortTasksOption != null) shortTasksOption.ValidRange = new FloatRange(0f, 23f); - - 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 +943,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 +962,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 +982,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 +1021,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,27 +1041,26 @@ 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 ""; } private static string buildOptionsOfType(CustomOptionType type, bool headerOnly) { var sb = new StringBuilder("\n"); - var options = CustomOption.options.Where(o => o.type == type); + var options = CustomOption.options.Where(o => o.type == type && !o.IsHidden()); 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,9 +1076,9 @@ 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) { @@ -1039,18 +1146,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 +1165,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,102 +1192,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); - } -} - -[HarmonyPatch] -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; - } - - [HarmonyPatch(typeof(NormalGameOptionsV07), nameof(NormalGameOptionsV07.AreInvalid))] - [HarmonyPrefix] - public static bool Prefix(NormalGameOptionsV07 __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; - } - - [HarmonyPatch(typeof(StringOption), nameof(StringOption.OnEnable))] - [HarmonyPrefix] - public static void Prefix(StringOption __instance) - { - //prevents indexoutofrange exception breaking the setting if long happens to be selected - //when host opens the laptop - if (__instance.Title == StringNames.GameKillDistance && __instance.Value == 3) - { - __instance.Value = 1; - GameOptionsManager.Instance.currentNormalGameOptions.KillDistance = 1; - GameManager.Instance.LogicOptions.SyncOptions(); - } - } - - [HarmonyPatch(typeof(StringOption), nameof(StringOption.OnEnable))] - [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 - }); - } - - [HarmonyPatch(typeof(IGameOptionsExtensions), nameof(IGameOptionsExtensions.AppendItem), - typeof(Il2CppSystem.Text.StringBuilder), typeof(StringNames), typeof(string))] - [HarmonyPrefix] - public static void Prefix(ref StringNames stringName, ref string value) - { - if (stringName == StringNames.GameKillDistance) - { - int index; - if (GameOptionsManager.Instance.currentGameMode == GameModes.Normal) - index = GameOptionsManager.Instance.currentNormalGameOptions.KillDistance; - else - { - index = GameOptionsManager.Instance.currentHideNSeekGameOptions.KillDistance; - } - value = GameOptionsData.KillDistanceStrings[index]; - } - } - - [HarmonyPatch(typeof(TranslationController), nameof(TranslationController.GetString), typeof(StringNames), - typeof(Il2CppReferenceArray))] - [HarmonyPriority(Priority.Last)] - public static bool Prefix(ref string __result, ref StringNames id) - { - if ((int)id == 49999) - { - __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"]); + if (GameOptionsManager.Instance.currentGameOptions.GameMode == GameModes.HideNSeek) return; // Allow Vanilla Hide N Seek + __result = buildAllOptions(vanillaSettings: __result); } } @@ -1191,75 +1203,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 +1262,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 +1315,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 +1337,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 +1360,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 +1371,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 +1382,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..d7b83fff 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,14 +24,11 @@ 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 { @@ -38,19 +36,46 @@ private static void Postfix(PingTracker __instance) _ => "" }; 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..3a220b79 100644 --- a/TheOtherRoles/Patches/EndGamePatch.cs +++ b/TheOtherRoles/Patches/EndGamePatch.cs @@ -106,6 +106,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 +174,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 +192,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 +204,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 +263,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 +349,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,60 +358,57 @@ 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; } // Possible Additional winner: Lawyer - if (!lawyerSoloWin && Lawyer.lawyer != null && Lawyer.target != null && - (!Lawyer.target.Data.IsDead || Lawyer.target == Jester.jester) && !Lawyer.notAckedExiled) + if (!lawyerSoloWin && Lawyer.lawyer.IsAlive() && Lawyer.target != null && 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.PlayerId == Lawyer.target.PlayerId) 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 +419,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 +430,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 +459,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 +486,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); @@ -543,7 +503,39 @@ public static void Postfix(EndGameManager __instance) } } - // Additional code + // Create a dictionary for win conditions + var winConditionTexts = new Dictionary + { + { WinCondition.Canceled, (Color.gray, "CanceledEnd") }, + { WinCondition.EveryoneDied, (Palette.DisabledGrey, "EveryoneDied") }, + { WinCondition.JesterWin, (Jester.color, "JesterWin") }, + { WinCondition.DoomsayerWin, (Doomsayer.color, "DoomsayerWin") }, + { WinCondition.ArsonistWin, (Arsonist.color, "ArsonistWin") }, + { WinCondition.VultureWin, (Vulture.color, "VultureWin") }, + { WinCondition.LawyerSoloWin, (Lawyer.color, "LawyerSoloWin") }, + { WinCondition.WerewolfWin, (Werewolf.color, "WerewolfWin") }, + { WinCondition.WitnessWin, (Witness.color, "WitnessWin") }, + { WinCondition.JuggernautWin, (Juggernaut.color, "JuggernautWin") }, + { WinCondition.SwooperWin, (Swooper.color, "SwooperWin") }, + { WinCondition.ExecutionerWin, (Executioner.color, "ExecutionerWin") }, + { WinCondition.LoversTeamWin, (Lovers.color, "LoversTeamWin") }, + { WinCondition.LoversSoloWin, (Lovers.color, "LoversSoloWin") }, + { WinCondition.JackalWin, (Jackal.color, "JackalWin") }, + { WinCondition.PavlovsWin, (Pavlovsdogs.color, "PavlovsWin") }, + { WinCondition.AkujoSoloWin, (Akujo.color, "AkujoSoloWin") }, + { WinCondition.AkujoTeamWin, (Akujo.color, "AkujoTeamWin") }, + { WinCondition.MiniLose, (Mini.color, "MiniLose") }, + }; + + var winConditionMappings = new Dictionary + { + { WinCondition.AdditionalLawyerStolenWin, (Lawyer.color, "LawyerStolenWin") }, + { WinCondition.AdditionalLawyerBonusWin, (Lawyer.color, "LawyerBonusWin") }, + { WinCondition.AdditionalPartTimerWin, (PartTimer.color, "PartTimerWin") }, + { WinCondition.AdditionalAlivePursuerWin, (Pursuer.color, "起诉人存活") }, + { WinCondition.AdditionalAliveSurvivorWin, (Survivor.color, "幸存者存活") } + }; + var bonusText = Object.Instantiate(__instance.WinText.gameObject); var position1 = __instance.WinText.transform.position; bonusText.transform.position = new Vector3(position1.x, position1.y - 0.5f, position1.z); @@ -551,102 +543,11 @@ public static void Postfix(EndGameManager __instance) var textRenderer = bonusText.GetComponent(); textRenderer.text = ""; - switch (AdditionalTempData.winCondition) + if (winConditionTexts.TryGetValue(AdditionalTempData.winCondition, out var winText)) { - case WinCondition.Canceled: - textRenderer.text = "CanceledEnd".Translate(); - textRenderer.color = Color.gray; - __instance.BackgroundBar.material.SetColor("_Color", Color.gray); - break; - case WinCondition.EveryoneDied: - textRenderer.text = "EveryoneDied".Translate(); - textRenderer.color = Palette.DisabledGrey; - __instance.BackgroundBar.material.SetColor("_Color", Palette.DisabledGrey); - break; - case WinCondition.JesterWin: - textRenderer.text = "JesterWin".Translate(); - textRenderer.color = Jester.color; - __instance.BackgroundBar.material.SetColor("_Color", Jester.color); - break; - case WinCondition.DoomsayerWin: - textRenderer.text = "DoomsayerWin".Translate(); - textRenderer.color = Doomsayer.color; - __instance.BackgroundBar.material.SetColor("_Color", Doomsayer.color); - break; - case WinCondition.ArsonistWin: - textRenderer.text = "ArsonistWin".Translate(); - textRenderer.color = Arsonist.color; - __instance.BackgroundBar.material.SetColor("_Color", Arsonist.color); - break; - case WinCondition.VultureWin: - textRenderer.text = "VultureWin".Translate(); - textRenderer.color = Vulture.color; - __instance.BackgroundBar.material.SetColor("_Color", Vulture.color); - break; - case WinCondition.LawyerSoloWin: - textRenderer.text = "LawyerSoloWin".Translate(); - textRenderer.color = Lawyer.color; - __instance.BackgroundBar.material.SetColor("_Color", Lawyer.color); - break; - case WinCondition.WerewolfWin: - textRenderer.text = "WerewolfWin".Translate(); - textRenderer.color = Werewolf.color; - __instance.BackgroundBar.material.SetColor("_Color", Werewolf.color); - break; - case WinCondition.WitnessWin: - textRenderer.text = "WitnessWin".Translate(); - textRenderer.color = Witness.color; - __instance.BackgroundBar.material.SetColor("_Color", Witness.color); - break; - case WinCondition.JuggernautWin: - textRenderer.text = "JuggernautWin".Translate(); - textRenderer.color = Juggernaut.color; - __instance.BackgroundBar.material.SetColor("_Color", Juggernaut.color); - break; - case WinCondition.SwooperWin: - textRenderer.text = "SwooperWin".Translate(); - textRenderer.color = Swooper.color; - __instance.BackgroundBar.material.SetColor("_Color", Swooper.color); - break; - case WinCondition.ExecutionerWin: - textRenderer.text = "ExecutionerWin".Translate(); - textRenderer.color = Executioner.color; - __instance.BackgroundBar.material.SetColor("_Color", Executioner.color); - break; - case WinCondition.LoversTeamWin: - textRenderer.text = "LoversTeamWin".Translate(); - textRenderer.color = Lovers.color; - __instance.BackgroundBar.material.SetColor("_Color", Lovers.color); - break; - case WinCondition.LoversSoloWin: - textRenderer.text = "LoversSoloWin".Translate(); - textRenderer.color = Lovers.color; - __instance.BackgroundBar.material.SetColor("_Color", Lovers.color); - break; - case WinCondition.JackalWin: - textRenderer.text = "JackalWin".Translate(); - textRenderer.color = Jackal.color; - __instance.BackgroundBar.material.SetColor("_Color", Jackal.color); - break; - case WinCondition.PavlovsWin: - textRenderer.text = "PavlovsWin".Translate(); - textRenderer.color = Pavlovsdogs.color; - __instance.BackgroundBar.material.SetColor("_Color", Pavlovsdogs.color); - break; - case WinCondition.AkujoSoloWin: - textRenderer.text = "AkujoSoloWin".Translate(); - textRenderer.color = Akujo.color; - __instance.BackgroundBar.material.SetColor("_Color", Akujo.color); - break; - case WinCondition.AkujoTeamWin: - textRenderer.text = "AkujoTeamWin".Translate(); - textRenderer.color = Akujo.color; - __instance.BackgroundBar.material.SetColor("_Color", Akujo.color); - break; - case WinCondition.MiniLose: - textRenderer.text = "MiniLose".Translate(); - textRenderer.color = Mini.color; - break; + textRenderer.text = winText.Item2.Translate(); + textRenderer.color = winText.Item1; + __instance.BackgroundBar.material.SetColor("_Color", winText.Item1); } var winConditionsTexts = new List(); @@ -654,26 +555,22 @@ public static void Postfix(EndGameManager __instance) var survivorAlive = false; foreach (var cond in AdditionalTempData.additionalWinConditions) { - switch (cond) + if (winConditionMappings.TryGetValue(cond, out var mapping)) { - case WinCondition.AdditionalLawyerStolenWin: - winConditionsTexts.Add(cs(Lawyer.color, "LawyerStolenWin".Translate())); - break; - case WinCondition.AdditionalLawyerBonusWin: - winConditionsTexts.Add(cs(Lawyer.color, "LawyerBonusWin".Translate())); - break; - case WinCondition.AdditionalPartTimerWin: - winConditionsTexts.Add(cs(PartTimer.color, "PartTimerWin".Translate())); - break; - case WinCondition.AdditionalAlivePursuerWin: + if (cond == WinCondition.AdditionalAlivePursuerWin) + { pursuerAlive = true; - break; - case WinCondition.AdditionalAliveSurvivorWin: + } + else if (cond == WinCondition.AdditionalAliveSurvivorWin) + { survivorAlive = true; - break; + } + else + { + winConditionsTexts.Add(cs(mapping.Item1, mapping.Item2.Translate())); + } } } - if (pursuerAlive && survivorAlive) { winConditionsTexts.Add($"{cs(Pursuer.color, "起诉人")} & {cs(Survivor.color, "幸存者存活")}"); @@ -709,9 +606,7 @@ public static void Postfix(EndGameManager __instance) roleSummaryText.AppendLine("游戏总结:"); foreach (var data in AdditionalTempData.playerRoles) { - //var roles = string.Join(" ", data.Roles.Select(x => Helpers.cs(x.color, x.name))); var roles = data.RoleNames; - //if (data.IsGuesser) roles += " (Guesser)"; var taskInfo = data.TasksTotal > 0 ? $" - ({data.TasksCompleted}/{data.TasksTotal})" : ""; @@ -1051,7 +946,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 +997,7 @@ internal class RPCEndGamePatch { public static void Postfix(ref GameOverReason endReason) { - Message($"游戏结束 {(CustomGameOverReason)endReason}", "RpcEndGame"); + Message($"游戏结束 {(CustomGameOverReason)endReason} {endReason}", "RpcEndGame"); } } @@ -1131,7 +1026,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..e964ea02 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; @@ -262,7 +264,7 @@ private static void WrapUpPostfix(GameData.PlayerInfo exiled) } Witness.target = Witness.killerTarget = null; - if (Vortox.Player.IsAlive()) + if (Vortox.Player.IsAlive() && exiled == null) { Vortox.skipCount++; if (Vortox.skipCount == Vortox.skipMeetingNum) Vortox.triggerImpWin = 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..ef32bf32 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..d40e4cd1 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; 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..c0db3ce6 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 @@ -1984,8 +1984,8 @@ private static void Postfix(PlayerControl __instance, [HarmonyArgument(0)] GameD float timer = (float)Math.Round(timeSinceDeath / 1000); if (Vortox.Reversal) { - timer += rnd.Next(-2, 3); - if (timer < 0) timer = 1; + timer += rnd.Next(-3, 4); + timer = Math.Max(0, timer); } if (isMedicReport) { 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..46145f32 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,13 @@ public static void HandleShareOptions(byte numberOfOptions, MessageReader reader public static void shareGameMode(byte gm) { gameMode = (CustomGamemodes)gm; + try + { + LobbyViewSettingsPatch.currentButtons?.ForEach(x => x.gameObject?.Destroy()); + LobbyViewSettingsPatch.currentButtons?.Clear(); + LobbyViewSettingsPatch.currentButtonTypes?.Clear(); + } + catch { } } public static void stopStart(byte playerId) @@ -584,7 +591,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 +2136,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 zcmeHuWmH_-)+O!`2=0Xwpm28&?k+(K*P;mS?(QDk-Q6L$2ZD#7ArK%qNt4|B?z^x1 z>#zHb(f#k$7*%!l-gC{h_S|djQ)ir05h_Zr(NTy{prD}8Wo0DQp1*aU-%3cZ&!651 zay?K`WKo_PIuJDzH-Hn^(Zbpe1b}!rfdC+PYYQkS_qFOQYp_9UOYu)L94@%4DW_TK zMKqh+??8a8e8b)e{#hh<(xgHz>=z3zsQE8HZ~Wr!L>?Kd-Lcin+dtdg;p^M=TuL;b z8TD@E#N0eQrL7%s-CSPMew{(hErp5OdD6Q)cru#lJVWgYn^rywLtVP_FnN3wkIFk) zF=D=ISDg(P6sejCSvwH#@5Ns~fO%4!*w>nfQzytH^#1W9B;aRE&y-KC{l%zGY0d2ib{U4c?uESI_j2bVV7Fcxe z-jCPHBHwino)69RPj1Ea`fL_&A#SZ>{&YHE6%o11%iG$lHY&aR{*$jV)8#tLFfJp0 zf2OFXu#nvS6JT%Whwgsmx!>*qxR=OiNu@g}nML4q+qPq0(3+3A<8z0A!`A2#twgl% z!$9Fp()wXLQKX|Uf~}0jVwyltFdm-nrAgvuU*iuirmvf=8y^+5+rNRk76h30HBh9t zeh?e^bALrcTQNZsH$=o6(5mplT8gzfjv&yNFV~ zClIIQTRPc%RCK=S7QVaTOqZg38KWtqh?-*{#ht{ z9Q(0Vq4ImnkqnDmkQT?sFB7$OeGw_zx~|Pjtsj%;V+BsTCTcoQed(LAl?0FW)Rlxz zug|vp*-Zu@kgj9<`mVKc%$iU09et8hxJf15MMr{*0LsJX zC4)OXi=w$8&<6IjRX)R)R6l!*ZhHTdb5HD)dn)B-IQ^iEb7}$HjNkX6ioi&8rCrlYmFLQxsvEoiGTE8piQ)H_QxiXp%$9^k=}FQlkqi-9 zpv!wK!P;^bLSqiU@*uV*5Jb`*rD$@ZZm}~wuoVb2?h7{6e^GfYlX=V^aO3!?-$Ot> z<892+id{eYt??j2w>!@OY0PPt^zjBt2C^M>K&ca|CW(BBW!V=&RY80FZ6x9Mla}g2 zA@w1KcPSoC!%#sJo%dF5S2-dVQ%fFrW`@PpTnhX?+77L>=t(XWCM-N-41R;f83BnT zqompsow!eud>fYU9Uv^tXkr!)b#exv$t0NK6}o5{^RUf_UC+XbI=c4-{sTvn_cqCR z^!Ht!>lSyj(@b7N%Pxi)Jv1YH(^#h9WMo`dMv2Um7jZ!_T#^Hyp$lI&?rSMpVgO8O zc}nqx4kU>x$lp3%fCEo#A+$-6CmC>8+Eyh#OS>~}$4y$VR%e996<0kJzX}LOVC_Rm z6!>H5!lknt+NC>ujF8(6ZHfDEgmlY4m8(_G*z9?|S$VNno+0CCN}lNeN9Jn$`Ia@4 z$49zVJvm!-2U?pmIj)G40<~)q%9EM#k;A3lFf&nQy84@3V~V6QXCvYFwI8>nNgG|W zO6lv&Z5#7NjtuCTnYJ2Y0`T8?>5AtxByhMR5HJ%W%MvIFVW_JGOVra?-|;ORn$>u; z2k_3Py4I>|>M97|v|U64XT43PKZOx$*wK~=me=zB>_AoA9Qf*?!j&W)S&IK2F*NR6 zlBPYEHmfE3LumnF0KwNe>2;U^aghZ_h=^>wsAq}-8%$-EKDEEAHe%hf5dDDJgVOLG ztwC;gY|`rw5I%U#7G+Tmk7!N3*wO*$+p2tHYOWligmqQll*&bJG}72$DzP9U9=SAm>6n;6ZyzkG-yd&l9eJ@Yvv>2ffB;e2pa4| zohL8Hi@pc{J-rI$JP8Ocoq2<$8aB}7gkSceG*6l9!m%qR;|XN z-xCuFbdR#rW9|?G+ha0mwT|~7xbk~9eqAa|CZaI;%kT2jJXzh4KB({#EfT+cs;%Vf z_%uK5kbKI2b8IGsBWh)Qw#5Rw@WVSJh89Yw+>Rdh355v6fR*W*BD{m1QYl5$jVs^B z;e_wlp};F4D0VKn7VBBF=%ZBMLSRABvrNZ|1;=Mf6Bro1De7Bp&Az#NxyqI$EzC2e zYL;m&rh7H8r*xPZFPm;7yl`D_xdq7D*!WmSs4y5r(2|P_ajufVq>LjwjLg* zp9T3yGzYx`JGg5y2q?+;J@L%GOtDv=8O~3sj_F&l3I~mB!$pCeOh#|IQ;2_fAa%~V zT0^x}sGngY84Rn&?O4}}G%oJZ3{;eZ_+rs6_T=6;f=nCQ76Q*^>^x|QQw$A ztnaE;6JYEQ*`sTQY=WiR`c)>Mob{t2L#zr!p2Q`Y7c z<*meH7e23=!Iif7b(QO?rQeoS&;EQ2%9W$Bx`rLXy0X6*)>G5>OpaahbcOiVjLsX4 zxeW9b4diK{=G?N8+}I->+X&LIKGE5jo8F*0*dXWF2ub4Nbx$mxk)1?c22!|Ic_)r< z5$5+3DlE#MCsBE63gj^1{xs|0BR6Ud)R#9L^z@Da&6655akB}hdSpQ>k&lRTl3Tn% z7yBiRtax*kkQ&8Y0+ET2e)MVD=P7YyWLNf5Di#5Tx#B8n#__W z*9QhortVmT<{_JikB3W=6N#|ulP^ACqc^fa76&`#Z2FBIHzc||Lu5P5g+d!-ihU!| z>O>pj&e-MsPM|Mmrr0LXSGKau2D8$>FOnT&Ty9yta1Fc5YZ*QK`XNhw5oZ0x)n;@S zcJ-LTU2QTn0ZGxTw={-bQ>ue#-A;UJXBlRp9THt)wy=vM-Iy038S;08*v%Z$Fi7IS zhi$6{65;#ms~?A9VWd>*;6)m|GD)`uL9|v zQ{M^9o_8fVNlw+;b~(X(crlv-T2g}425>Ynv^t!q355Y8x|6s!^u>DRe0SsX_e&9O zeGAzFsXV5@VxuD-Ej5;!35QL2WhVZlKzzSZC;E>(F*DTboccMp?a+6#hiqpCJ11ux zRr0p^iB3%Qg-eXpp@qn(W(e~=b?GxS*go0~=88p8SkdTiE(obTDul0K0?T+KYdc9< z;vScfTG7!YW;k>FxeP&Y2sbzTw7c)ZYTr-lLFAs;^sDAUw$8SBuBjm zEF$u0hf$2a91y4d)ahqMI&Xu44(GEY9XC%1cBZaLJ0;*`_u8DJ`Brn#pqGBvB{S2T zb{3UM)FN6q10~$x=^NL*JTpt}>g8k4me+R|flps=HsUi#g-BKq=F#9w5dvU9kJKuB zciatSNY}sN_H<}i)VMq%$p0`BKToZUyh+00`XUwn{N*CUXB(|AmP2{lDtXQH$9?yQ zCgmgVtaY*|^qmAT#lGIZlLBC?IPWQ1eK+BF zGE_v%7}q?xAp$5C#u1AID1Jg+DOFwH3t7)Js)^HL5pw#ovfrX9xvOTSUJNZnfA;G# zzEt$@QLzpoK$im|!cBMKgMai(s?cmQVrtc}88oH~4)Kv7)~EUyW^N}ap$>BWkQ9)S@iW{oxX@^0bk(L6F>a_XCfV{sc>d1w3)O-K>-n34P< z>~JutO6j-7oON1sST0KSpE93I@i#BcRAw7%^514Ef1CV~dStw_Z!Tjl+=HVpKXX$k zzf;5LqDS$~_m$YWaMXkc?3{p3}np@XB{Oi4GI` zPu-p(?+R7Zrf$t4fz`wBbFX{mPsZIGFHa^VWD1z$G?p{3z^tl~#6UEL?O_Ys;qQBu zX_mG5&^Ckwp03H+$Eg?sIAdikTNyv+i?6IAD?mpUHf2TEhLcNDm$hk&ZyKN0ZFbEg z7&Au}zwOE2pI!vq{A}~a%-@w@3tMOPB|M!Z_D56P9aKDWUU*})zW9Y@{VK|ct(S|5 zT>5^+9+fUbUM?;P(;u4`8u&m)C~)Kmi+B2-m$~t=jWkFp-3^+%OySzlSE?RpO;7Tn z1n}|A;ZKrcXpUGs7JHf$2i#KZk0*mOFk5pY&R?0|8YM=MnofANhEBcqSH*KIaJatk z?ylIKKvyMjw1526w?&zo`Xe}AMGIA#c=NMJNWQPuhVM_k5AEE*K4^pjLnaQtwu#PY z!Kh{C{G3Lk^X5arU`-`ojr((EG$ktFQ}Cx5maYS0q(>jKiW4^z1lj{pOH0~_;4es$ zPKEcB_8*pSh9KXsYJLor7g8rN#ixek$xe3@#%X-JC{smYdmwE>4k7p!t;l&3*7M-> zsWp*PS?&$Z-I>smBiU3KA+RNId6_5ze&$;nYIPLR%^JJt=Jx=V5%e9hEFm@lYOq_I znEgYNBuA5lI(Ys^*fKu$ZtVhYZlc^&B}Gp0%h#=4C`~1rWeca^%a5>ciP4YMIUK6B zx}Mu(YIob2$ox>Tt zP@%l3HbCu$6Q;oqN=8|8%l!KkcQ_j@*bOCL^o?Fx<2P;|(>Y$Jofq*}Cy}J2XwvZg zm3c1L9?GV;xlD(J*n)b=lX6L}vnb!b*yj`mu@~;w#+pzDUxhPO8|Uo0#QmF~~e zvah!w<|hej)RE~`4;)nkAk8n!b)#J@qo8@7^mlioE-1Sq_8qzOlCm5&b+T3xl;c8g zE)^AUx2F4Bt<=m69l>H6Z!W?e7(%43ZaMX0`rAc44eTpn$t=t}I(bo{IwP1DoCEPj z?f6N=?VF&a7vd9243BZPD%)6W9!!ALZmF+q`U|#A_zGO;aF6QigK5&X2hc?Z=bXfS$GD zV^UDO`$XP)D&6jta;tXGoV$7IO4xZsfcK>U8(L;*FL-tERT^w=VBk9i+RXYV54%Kf zDI(af!3Gr8ghtyBO1dKGAIAPWpAg@gC7{LVty%R0P9B^W?l;TOM&eP`6SG zLR*-=Uu&gje5D8KDE;yYqW0rrY-9|ot1#DPQSMwwPN^GCG zanmJ+05|Tbi(yoFX7py{G38L&?uLyE=P{CtX|*v5$y0tap|WE)tU3jnsO(wv!>?V^d?Cf1qrL{ z>({^KPMEr6Q&JF~_xY(-tgvXO2g1!kbF_A?tFXM-u9%AOLW_qt7JtCN+$Aa{;y9aN zJTlI7b`oM<#v_&2RZg&9$+oTZtdn>%QWI(ZjnN+#1F>h^2i1fJs`};Knkg5tYsfN_ z6k>sv8PZa?TLhTO<`NZ^QnQgh8qnMF{sLEH33vdMccq)4&1V*AEX85A3d?*&4}0 zHUUy}6LdU+o9hd6t}o}X3#2NlUT>Z0K`f%ngwp~T^7k(&n@eOQERb?^5!hB%2UMer zYY#KGVKsM}z>3vkNrbPU-DpO3FwYb`E)D8nyXK|Ui*jYkVpq3K1%WWZAS3IxcP`(~>s!Rm_B_2(hVH*~QT`T<04Ki# zuPFPLXbeEwnsvw=wPC!;$fd&+`dLA0PMVN_MxbXfY3E@gkh_sOv}#2aDb*U7OCniv+8QlS0b8GN6pw zWv!BWPgTs;O23m*6gv=Q6)=q1Y44tS7OS|p9kUhLNyZG%`_Tg8t2M#FE33DB#QSM} z*-MoTw)~9%K<_j3Br?rY*!-}!Rg&0*$hMWFb734#MhOw&iQGUq+5mc zsTceux0`4hI$#f9gUnkB$o@mp zbuk9J5@lUli5HIkk?M1|9vc$yq#kweNx1kE@Qx`d889iNEF!={4Y1YXJs%n;J{eRl z8GB+Gz6q*cXh!}fK}nQEiMKX1x8^l>q*|q{1HVtepB2*|=1S0;D%c)Hfgya#6as#6 zD3G&7T|<~v)ExhH9E~4fQF@tv^GF50sPV-^-f_ksC?PCQseUm-FF~D0H#)l}F$x3I zcOTUC;~sW1ZaZ1N(Y~aWx3ZW^U5!M4I_icW$d84E@DeUnZ^1dzCvxXhZn0AbF~`LE zRRhVFkzz0YdES&1p9#1%(F)Gqq>nT`#PNU`(^okVa)-6pd6IiHOk6u;Brd_and{l7 z`gxRDq~-WkvC>Y?&g$#8jECKjOvI9pHM{W52;-7I*W9lUF938ESFu@lF+`>zB+<~gUja=u^fv?QsS8oCtM)} z;?#qCF#A;)-l5**xVLHsfBR-I+>QQ%yhCfJ=_O6>ETx_5s_o}KUL4nB8}jpUtWm{x zZT=XcpEFaHc(xDhmax!?i$vZVUeavqG3I{qz%C5&1U~9`ab-y3VAV3l})0m1W4kFk_R>}e8?loI{q|upV3dawy3t(qcxKX&7^b8!~ znGX_cMpv-rvjx<<6hQ?*9mujTePj-2Wdgdbr&ERk?!(X+pighv8c^PjwM2d?OThWc z9x8k+syR74TX>vpAWn{#Ggp^!`$}F7i<Va!w6w#e);2@I_Bw4k6YqN)|hg;dz!;K8mP(`bkZ!k_oUgqrMIsH_9?!-xKZb6 zmxIj0FT&3%$?uzh-K9)wdwWI&H)9XwsD)u_F{x@`k^(-Q->)wcyld&3Y-$?}MjmA6 z7Xh(B*dC&j&s9giSQjT)WEM{PFK^)+d)w0r1LiHd#zD`EjgQC0(hCp7Nkm9I@&dZZb$vXYa{}z!CYN5S!rF zwIXl$CJLOFbJHl{2`>i_NP4piBHOpy)fB=W(NVpfwN@N;XM3~Pvt)}E4qhC+2*vOX z$PUE2!(Gev>ZrQ(5i$>QqRA4=tIUv6^NFjBF_<56s-06;biXf*doQkwztbX|-_P5e zuC;Rs7;d4F$Y5g^#GIIa)xpPFd`^Mz8oMsn_e76rRV*(+3|8%_TzwQe4&hNtolOVc zPWsqPsmT|a7>;xyAh*E5_~l(>nfM1f0xZH!^K8kF#yrTtKIhprq;6uo_t6oD63Wm= zpAOzbxR?_wdxGft8n3}Jx-~1>>SvRr1Xy&nCRW$cAuL16qx2AJOT`?(K%W*2`Xpzk zhNi6!X4ub)J{UKeq}PwLzOw=SguSp9d$0s`60hB&T1F64bFCG;rJzk4$nTg7w@tT8q$uEJ)Pohw8rCP#aBtl-m{U#74?c2+;oX#B; z6*)x43npZGpF4%Gg+90P0p%CjWt8Z!yNjjxgfblG_^C?E**)Pm9M}O@GIQiP2%JC3 znO`ZV_ibsaLqS1@SW8H#$Vy23TS1@qab zE;o#u4Me0E6!obZWYHxis+{ns_Qyy9cc~YlWu{2-lZ#0iAxwfRD?;Ahy-^oTXI_3a zzQxAueRMBp*f;9JS0YMzfH{}K&fzIEA-CD?>-h)~CfW4i&Z;UODK|>~%{PBhF%rcXbVux%$@9dN5NAf~ZV|=S+`-g`Q zEm?H_KMC9B*M8W*rr%L_Z!S~5?(5@ra^6_p6WRtN68O&3NPwwDQdF2=&MdDKJ&e!s z4)t9Rmib4IVB?E*fg4bWVSPFg4J(418z1>v{mz>9Z(wUm!M&J+m2*%~FS4zlpA*ng zRNyyrv}ZOkcQgetyW2ZGKSuxsB`D(VWMXCuf&ffGmevkJlxLm2lmKgUAxdp7MOH;8 z36Pbwj3*eR?y00<=4orjXHF?1j3VgH|4d*Hf|vl@?d=>~_}zslfAjJ`AOGrRp#=Pf zKx~C5bre+q5{_UHfRmY%nH4DIZvB>>QWymw2sXFiSCf?flj6B0L}>+qIPtTvxVgD8 zyKyi(f-PCt`1tr(SlL#k# z75}n!aQRckXFXZmO`KTRm|0ou?f=EX1tRtKpZ@+!3m1*&$2C~gKrW81U^9@^TaW{U z>hDgS>|9;`?$gx;^sDQ4+;-*`EYCsx_WXC7*RqN#f7$$!(bC%9>9@r%^xu)@W`E(F zT)}p~G3I70AUlx#b099y%xwRHhge(ubAkS4KEFo(mq4D~{l)(;=zr+-JC@(N@=H3J zx&Cr0D=9?zD_(wcM>A`4{@;gu7Q7a0e9w!*1>)caa1WWqm#}1DTnyn}E2v zcsMwIQ~g>8elZnUAxd^;)_?Y>*qJ~q9KrU_=<{f5-Dr=wB>iV2GO|*j5>=Y-$5CgZ%eA{}uQz zCbj3?&IJPYko`YQ>VLus{*kaU&$f2RZ-I`eRG7v;Hj=0PuSo;5RY*Lw*;N zx1c{#?ODe^hRm!?94tZ4`|Y2__K$w+|00o1d006)%sKdg92UHMKu%L$ZlI|tI~S0Z zhs)HAkIl@Cm*mcN~do@4%_@A(Axe7xB7dmOLx||MT@{_Wl2K0Ra5R$-kxVf8_d)T>q8= z{}%W^+4Uc}{w)RmE%1M`>;IWtDF3|V201+c?sI#-pdPz^bqWOqqobmrA@zJwp0d0e zzqn%3)2Gxb)#=Oblg4ruW3O_rz4x{1S0;3PMm2l#dU3L}bA9Y~=jni>N4QUthAc zG~2;posLe8wsxu7dRTvd^0aixnmUS%Ov##B-HtA+fuZoZ1?A=zy!Zt8z(DNSScbfO zij0h)nK{nl5~lnDo53Od&TfvPV!?_^P~U+4(1?0#yIO0T;IKvifJ99#Qb-6* zc24ZVGEq`8N?4fx)GTInblB_yZhSmtW|l?&pk`Y;%ez9v;NZaNx!{?3-qJGBs_MY$ z+0fZ}u9DK1F|l05rTpa;N=+>|adD)nX|L-W!6DMM^{!*@-;Pc2l$K#cM!o6oG4AQ}ot#Dq4MPqM^_!Z( zh>SGt?KAG_6{@HdsjQNzZ$u3XPgq(>Tw0NBXyh-e5Gb$YDlVbP&i0v{<}WL!&dR3B z%mR;$;U^>zCM8A8EvhuPzRJzRjf>|lDP=1x;wvi`D6eoIpET?3M~{erjEm47V>6%J1- z^V~polF@a6g2EX5^@bjGEHi)ZM1;sHN+BL1;39C*D=NBmK|#Uo$x4c8=nQse#2Be- z5{&XiPsLzKHpQe1*eSdTb;JyZeisnHj}x9CE3x_BT^8)G)*)F?<}bNv@vc}_Iz!4P zGg$WQ$xvvfotXSXx82QHPVY?HjK>q$E!Snb`#@JiLjxxwn73`Nf}lAR5!hN_5u{Zb zvy{X;JU(Of2|IU*mce6Yh9*BTmxlnEjixs~kgxHj`IB@Gyp($NP^yKc^#<*e=UB^C z^yK7ZG!x=?Mz70M(fN8;;${08510nFn_)pBrH)4?be7eYK_yVRF&*6<4TE-wG&49M z^?QSWXrf?MU1M!AaG&yQKsYsV<4DTuO{%!Q+(hJckJ_7nBOk%NC&cp>cHK2Su~SMu zM%^5g9B-8wF<}jOp^8tzDF*8IHg$5XX7G#4;sV;Fht^dYuTU)YqfA+Sdov0f&{9ge_i_!?KS% zMvd!>pOM*v#}Tmj_&D2re9YxDiwp$!f)e)--mS7EhC-a;-Q<#1bk07X&^;e)?NE># z1sSZSkQLR)fyT~`B^k6syENT)gC{-*qCWIV9qdq*R*Th~eMQ#le!2GsUXXzAVw_8w zYDdE;e(}sX;bfVT9M_)UZ5+FK+~=nye#3-HwAHt?uXHSE#!%eP!*5yF#$e*Cf2izshapkIbMm2YL;(emFCy09T zuDRYh@T4eWlA7HGKAJ^iv~u1B$dpkwYatn^&;#`Vk{mNLu1&~3sh?6`ZLa?DzSf&( zWX*!b2fd~T`MXkHT+D}Co+M3|tlkva>xO{o5|6Eo%s}9GnC1R)7RQ=%N{odYUml}? z-H%E(JjHY5zR6Nw#j@lx57hJRu#4Tzeh<2hv8zd-rM#isW{YM0#E!OCKj83XkqzD9l! zNzPeVl`c>avF~w&cGO>#;N_S=-4||ZJbux*PoEyl zlgQax8{yl<=vRe;7o45p3F$)8EQ^^&Klyi2dtZ)T>ZHPD(4M~&ZCQ=hlLLxZS@-C3 z6PD@=Qt&*P-wWUo(dSS}!h(3h$wqqN)NCFN_pZn(zP7_<&4ngnP-3z3A@hp?(@^b-yP{)e8fA@EXq zS4dJq3owM};4|V!uuORg0_*@i+RwD|)N2gH;~!6s`xPRq-KRTshhdd6LI^(*9gtD1 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/Roles/RoleHelpers.cs b/TheOtherRoles/Roles/RoleHelpers.cs index a58510ce..6896665e 100644 --- a/TheOtherRoles/Roles/RoleHelpers.cs +++ b/TheOtherRoles/Roles/RoleHelpers.cs @@ -16,7 +16,6 @@ public static bool CanSeeRoleInfo { if (PlayerControl.LocalPlayer == Specter.Player) _CanSeeRoleInfo = false; else if (Specter.Player.isLover() && Lovers.otherLover(Specter.Player) == PlayerControl.LocalPlayer) _CanSeeRoleInfo = false; - else if (Akujo.isAkujoTeam(Specter.Player) && Akujo.otherLover(Specter.Player) == PlayerControl.LocalPlayer) _CanSeeRoleInfo = false; else _CanSeeRoleInfo = value; } } 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",