From bf795a2e366dada33d237ee75a6b817e07c50af4 Mon Sep 17 00:00:00 2001 From: ang-xd Date: Sat, 15 Mar 2025 23:47:05 -0400 Subject: [PATCH] Bug fixes with option screen & modifiers options --- .../Patches/Options/GameOptionsMenuPatch.cs | 5 +- .../Patches/Options/GameSettingMenuPatches.cs | 295 +++++++++++++----- .../Patches/Options/RoleSettingMenuPatches.cs | 7 +- MiraAPI/Resources/CategoryHeader.png | Bin 1221 -> 872 bytes 4 files changed, 227 insertions(+), 80 deletions(-) diff --git a/MiraAPI/Patches/Options/GameOptionsMenuPatch.cs b/MiraAPI/Patches/Options/GameOptionsMenuPatch.cs index 05de7f6..8034eff 100644 --- a/MiraAPI/Patches/Options/GameOptionsMenuPatch.cs +++ b/MiraAPI/Patches/Options/GameOptionsMenuPatch.cs @@ -203,7 +203,10 @@ public static class GameOptionsMenuPatch categoryHeaderMasked.Title.color = group.GroupColor.Equals(MiraApiPlugin.DefaultHeaderColor) ? Color.white : group.GroupColor.FindAlternateColor(); categoryHeaderMasked.Background.sprite = MiraAssets.CategoryHeader.LoadAsset(); - categoryHeaderMasked.Background.transform.localPosition = new Vector3(0.55f, -0.1833f, 0); + categoryHeaderMasked.Background.sprite.texture.filterMode = FilterMode.Bilinear; + categoryHeaderMasked.Background.sprite.texture.wrapMode = TextureWrapMode.Clamp; + + categoryHeaderMasked.Background.transform.localPosition = new Vector3(0.5f, -0.1833f, 0); categoryHeaderMasked.Background.size = new Vector2( categoryHeaderMasked.Background.size.x + 1.5f, categoryHeaderMasked.Background.size.y); diff --git a/MiraAPI/Patches/Options/GameSettingMenuPatches.cs b/MiraAPI/Patches/Options/GameSettingMenuPatches.cs index 7781bf8..9e05f58 100644 --- a/MiraAPI/Patches/Options/GameSettingMenuPatches.cs +++ b/MiraAPI/Patches/Options/GameSettingMenuPatches.cs @@ -1,8 +1,10 @@ using System; +using System.Linq; using HarmonyLib; using MiraAPI.Modifiers; using MiraAPI.PluginLoading; using MiraAPI.Utilities.Assets; +using Reactor.Utilities; using Reactor.Utilities.Extensions; using TMPro; using UnityEngine; @@ -22,6 +24,8 @@ internal static class GameSettingMenuPatches private static TextMeshPro? _text; private static Vector3 _roleBtnOgPos; + private static Vector3 _smallRoleBtnOgPos; + private static Vector3 _modifierBtnOgPos; private static GameOptionsMenu? _modifiersTab; private static PassiveButton? _modifiersButton; @@ -33,9 +37,20 @@ internal static class GameSettingMenuPatches { if ((previewOnly && Controller.currentTouchType == Controller.TouchType.Joystick) || !previewOnly) { - if (_modifiersTab) _modifiersTab?.gameObject.SetActive(tabNum == 3); + if (_modifiersTab) _modifiersTab!.gameObject.SetActive(tabNum == 3); _modifiersButton?.SelectButton(tabNum == 3); _smallRolesButton?.SelectButton(tabNum == 2); + if (tabNum == 3) + { + if (__instance.RoleSettingsButton.gameObject.active) + { + __instance.RoleSettingsButton.SelectButton(true); + } + else + { + _modifiersButton?.SelectButton(true); + } + } } if (previewOnly) @@ -45,6 +60,17 @@ internal static class GameSettingMenuPatches _modifiersButton?.SelectButton(tabNum == 3); _smallRolesButton?.SelectButton(tabNum == 2); + + if (tabNum != 3) return; + + if (__instance.RoleSettingsButton.gameObject.active) + { + __instance.RoleSettingsButton.SelectButton(true); + } + else + { + _modifiersButton?.SelectButton(true); + } } /// @@ -117,6 +143,7 @@ internal static class GameSettingMenuPatches _modifiersTab.name = "MODIFIERS TAB"; // create button for modifiers + __instance.RoleSettingsButton.buttonText.gameObject.GetComponent().Destroy(); __instance.RoleSettingsButton.gameObject.SetActive(false); _smallRolesButton = Object.Instantiate( __instance.RoleSettingsButton, @@ -137,6 +164,8 @@ internal static class GameSettingMenuPatches __instance.ChangeTab(2, true); })); + _smallRoleBtnOgPos = _smallRolesButton.transform.localPosition; + var roleText = _smallRolesButton.buttonText; roleText.text = "Roles"; roleText.GetComponent().Destroy(); @@ -178,9 +207,45 @@ internal static class GameSettingMenuPatches _modifiersButton.transform.localPosition = pos; _modifiersButton.name = "ModifiersButton"; + _modifierBtnOgPos = _modifiersButton.transform.localPosition; + UpdateText(__instance, __instance.GameSettingsTab, __instance.RoleSettingsTab); } + private static void ChangeRoleSettingButton(bool replace, GameSettingMenu __instance) + { + __instance.RoleSettingsButton.OnClick = new ButtonClickedEvent(); + __instance.RoleSettingsButton.OnMouseOver = new UnityEvent(); + + if (replace) + { + __instance.RoleSettingsButton.buttonText.text = "Modifiers Settings"; + __instance.RoleSettingsButton.OnClick.AddListener( + (UnityAction)(() => + { + __instance.ChangeTab(3, false); + })); + __instance.RoleSettingsButton.OnMouseOver.AddListener( + (UnityAction)(() => + { + __instance.ChangeTab(3, true); + })); + } + else + { + __instance.RoleSettingsButton.buttonText.text = "Roles Settings"; + __instance.RoleSettingsButton.OnClick.AddListener( + (UnityAction)(() => + { + __instance.ChangeTab(2, false); + })); + __instance.RoleSettingsButton.OnMouseOver.AddListener( + (UnityAction)(() => + { + __instance.ChangeTab(2, true); + })); + } + } private static void UpdateText(GameSettingMenu menu, GameOptionsMenu settings, RolesSettingsMenu roles) { if (_text is not null && SelectedModIdx == 0) @@ -197,106 +262,182 @@ internal static class GameSettingMenuPatches _text.text = name[..Math.Min(name.Length, 25)]; } - _modifiersButton.gameObject.SetActive(false); - _smallRolesButton.gameObject.SetActive(false); - menu.RoleSettingsButton.gameObject.SetActive(false); - if (SelectedModIdx != 0 && - SelectedMod?.OptionGroups.Exists(x => x.ShowInModifiersMenu || x.OptionableType?.IsAssignableTo(typeof(BaseModifier)) == true) == true) + bool replaceWithModifiers = true; + _smallRolesButton!.transform.localPosition = _smallRoleBtnOgPos; + _modifiersButton!.transform.localPosition = _modifierBtnOgPos; + menu.RoleSettingsButton.transform.localPosition = _roleBtnOgPos; + + if (SelectedModIdx != 0) { + var modHasRoles = SelectedMod!.CustomRoles.Count != 0; + var modHasModifiers = SelectedMod.OptionGroups.Exists(x => x.ShowInModifiersMenu || x.OptionableType?.IsAssignableTo(typeof(BaseModifier)) == true); + var modHasOptions = SelectedMod.OptionGroups.Exists(x => x.OptionableType == null && !x.ShowInModifiersMenu); + _modifiersButton.gameObject.SetActive(true); _smallRolesButton.gameObject.SetActive(true); + menu.GameSettingsButton.gameObject.SetActive(true); + menu.RoleSettingsButton.gameObject.SetActive(false); + + // If there are no registered custom roles in the selected mod, hide the button. + if (!modHasRoles) + { + _smallRolesButton.gameObject.SetActive(false); + + if (roles.gameObject.active) + { + menu.ChangeTab(0, false); + } + + // If the mod has modifiers, we can disable the smaller modifier button and enable the bigger one. + if (modHasModifiers) + { + _modifiersButton.gameObject.SetActive(false); + menu.RoleSettingsButton.gameObject.SetActive(true); + + if (_modifiersTab!.gameObject.active) + { + menu.RoleSettingsButton.SelectButton(true); + } + } + } + + // If there are no modifiers in the selected mod, hide the modifiers button. + if (!modHasModifiers) + { + replaceWithModifiers = false; + _modifiersButton.gameObject.SetActive(false); + + if (_modifiersTab!.gameObject.active) + { + menu.ChangeTab(0, false); + } + // If the mod has roles, we can enable the bigger role button and disable the small one. + if (modHasRoles) + { + menu.RoleSettingsButton.gameObject.SetActive(true); + _smallRolesButton.gameObject.SetActive(false); + } + } + + // If there are no custom game options registered (that aren't modifier options), hide game settings button. + if (!modHasOptions) + { + menu.GameSettingsButton.gameObject.SetActive(false); + + if (settings.gameObject.active) + { + menu.ChangeTab(0, false); + } + + // If the mod has roles and modifiers, we can move their buttons to the game settings button position, since nothing is there. + if (menu.RoleSettingsButton.gameObject.active) + { + menu.RoleSettingsButton.transform.localPosition = menu.GameSettingsButton.transform.localPosition; + } + else if (_modifiersButton.gameObject.active && _smallRolesButton.gameObject.active) + { + _modifiersButton.transform.localPosition = new Vector3( + _modifiersButton.transform.localPosition.x, + menu.GameSettingsButton.transform.localPosition.y, + _modifiersButton.transform.localPosition.z); + + _smallRolesButton.transform.localPosition = new Vector3( + _smallRolesButton.transform.localPosition.x, + menu.GameSettingsButton.transform.localPosition.y, + _smallRolesButton.transform.localPosition.z); + } + } } else { + _modifiersButton.gameObject.SetActive(false); + _smallRolesButton.gameObject.SetActive(false); menu.RoleSettingsButton.gameObject.SetActive(true); - if (SelectedModIdx == 0 && _modifiersTab.gameObject.active) + menu.GameSettingsButton.gameObject.SetActive(true); + replaceWithModifiers = false; + + if (_modifiersTab!.gameObject.active) { menu.ChangeTab(0, false); } } - //menu.RoleSettingsButton.transform.localPosition = _roleBtnOgPos; - //menu.GameSettingsButton.gameObject.SetActive(true); - //menu.RoleSettingsButton.gameObject.SetActive(true); - - // TODO: reimplement this - /* - if (SelectedModIdx != 0) + if (menu.RoleSettingsButton.gameObject.active) { - if (SelectedMod?.Options.Where(x=>x.AdvancedRole==null).ToList().Count == 0) - { - menu.GameSettingsButton.gameObject.SetActive(false); - } - - if (SelectedMod?.CustomRoles.Count == 0) - { - menu.RoleSettingsButton.gameObject.SetActive(false); - } - - if (!menu.GameSettingsButton.gameObject.active && menu.RoleSettingsButton.gameObject.active) - { - menu.RoleSettingsButton.transform.localPosition = menu.GameSettingsButton.transform.localPosition; - } - }*/ - - if (roles.roleChances != null && SelectedMod != null && SelectedMod.CustomRoles.Count != 0) - { - if (roles.advancedSettingChildren is not null) - { - foreach (var child in roles.advancedSettingChildren) - { - child.gameObject.DestroyImmediate(); - } - - roles.advancedSettingChildren.Clear(); - roles.advancedSettingChildren = null; - } - - foreach (var header in roles.RoleChancesSettings.transform - .GetComponentsInChildren()) - { - header.gameObject.DestroyImmediate(); - } - - foreach (var roleChance in roles.roleChances) - { - roleChance.gameObject.DestroyImmediate(); - } - - roles.roleChances.Clear(); - roles.AdvancedRolesSettings.gameObject.SetActive(false); - roles.RoleChancesSettings.gameObject.SetActive(true); - roles.SetQuotaTab(); - roles.scrollBar.ScrollToTop(); + ChangeRoleSettingButton(replaceWithModifiers, menu); } - if (settings.Children != null && SelectedMod?.OptionGroups.Count != 0) + CleanupTab(settings, roles); + } + + private static void ClearOptions(Il2CppSystem.Collections.Generic.List options) + { + foreach (var child in options) { - foreach (var child in settings.Children) + if (child.TryCast() || !child.gameObject) { - if (child.TryCast()) - { - continue; - } + continue; + } + child.gameObject.DestroyImmediate(); + } + options.Clear(); + } - if (!child.gameObject) - { - continue; - } - - child.gameObject.DestroyImmediate(); + private static void CleanupTab(GameOptionsMenu settings, RolesSettingsMenu roles) + { + void CleanupRoleSettings(RolesSettingsMenu rolesMenu) + { + if (rolesMenu.advancedSettingChildren != null) + { + ClearOptions(rolesMenu.advancedSettingChildren); + rolesMenu.advancedSettingChildren = null; } - foreach (var header in settings.settingsContainer.GetComponentsInChildren()) + rolesMenu.RoleChancesSettings + .transform + .GetComponentsInChildren() + .ToList() + .ForEach(header => header.gameObject.DestroyImmediate()); + + foreach (var role in rolesMenu.roleChances) { - header.gameObject.DestroyImmediate(); + role.gameObject.DestroyImmediate(); } + rolesMenu.roleChances?.Clear(); - settings.Children.Clear(); - settings.Children = null; + rolesMenu.AdvancedRolesSettings.gameObject.SetActive(false); + rolesMenu.RoleChancesSettings.gameObject.SetActive(true); + rolesMenu.SetQuotaTab(); + rolesMenu.scrollBar.ScrollToTop(); + } - settings.Initialize(); - settings.scrollBar.ScrollToTop(); + void CleanupSettings(GameOptionsMenu gameOptMenu) + { + ClearOptions(gameOptMenu.Children); + gameOptMenu.Children = null; + + gameOptMenu.settingsContainer + .GetComponentsInChildren() + .ToList() + .ForEach(header => header.gameObject.DestroyImmediate()); + + gameOptMenu.Initialize(); + gameOptMenu.scrollBar.ScrollToTop(); + } + + if (roles.roleChances != null && SelectedMod?.CustomRoles.Count > 0) + { + CleanupRoleSettings(roles); + } + + if (settings.Children != null && SelectedMod?.OptionGroups.Count > 0) + { + CleanupSettings(settings); + } + + if (_modifiersTab?.Children?.Count > 0) + { + CleanupSettings(_modifiersTab); } } } diff --git a/MiraAPI/Patches/Options/RoleSettingMenuPatches.cs b/MiraAPI/Patches/Options/RoleSettingMenuPatches.cs index e4984fd..9fe48d7 100644 --- a/MiraAPI/Patches/Options/RoleSettingMenuPatches.cs +++ b/MiraAPI/Patches/Options/RoleSettingMenuPatches.cs @@ -128,7 +128,10 @@ public static class RoleSettingMenuPatches countLabel.Destroy(); categoryHeaderMasked.Background.sprite = MiraAssets.CategoryHeader.LoadAsset(); - categoryHeaderMasked.Background.transform.localPosition = new Vector3(0.55f, -0.1833f, 0); + categoryHeaderMasked.Background.sprite.texture.filterMode = FilterMode.Bilinear; + categoryHeaderMasked.Background.sprite.texture.wrapMode = TextureWrapMode.Clamp; + + categoryHeaderMasked.Background.transform.localPosition = new Vector3(0.5f, -0.1833f, 0); switch (name) { @@ -243,7 +246,7 @@ public static class RoleSettingMenuPatches [HarmonyPatch(nameof(RolesSettingsMenu.OpenChancesTab))] public static void OpenChancesTabPostfix(RolesSettingsMenu __instance) { - if (GameSettingMenuPatches.SelectedModIdx == 0) + if (GameSettingMenuPatches.SelectedModIdx == 0 || !__instance.scrollBar) { return; } diff --git a/MiraAPI/Resources/CategoryHeader.png b/MiraAPI/Resources/CategoryHeader.png index 3d2a4bfaf12c74008a375e85c21720685b4bfaae..0fb58e8c6475343b637f141e7016da395d698206 100644 GIT binary patch literal 872 zcmeAS@N?(olHy`uVBq!ia0y~yV2S{;BRQCXiD!+d&cwv>oy3$Xq zg@+b(m?j1u+O7}^p0q`syuB2$7*+-#EGT9v-fg!udt4P z6&m4^Te}XZdh6enajmXb&K<836$>o4zp{FR$FA>nI|Ri%cfW6wPMm0BQ!XwRdAPVd zapG0U+!oh>?-g5w#T=Id&GfL6-Pq!K=_Syjreh#Gr1~QcDP`Csadt2G2ox+*a|7CG z{Oj#SyF|g_|8Fbwb&}-vNWO1%J$3lHu=ydS)JG!T5l?*P05#0{mf~|rDdiJT;D`xG z+a(F0*)&3D{-n?lJh*iv8c}6Y-zH!_9eJ$GY$+U|MAGboFyt=akR{0Q@4tng9R* literal 1221 zcmeAS@N?(olHy`uVBq!ia0y~yV2S{;BRSZBylDJ>JydH zPiC^)b32sCcJq;cKPCscIv zkG9**|6^{uJDoT``Do=|);g=_d#|rOm|(!cz_2OOlbwM<$1Q=8Aw_Ki1A|fa&4Ww~ zCl=p+J1;ISZk{EGv*h~gzkBxY|G)77kn`l)+Gu^HM=>A`mtL0mDLtAA683=`APn@o ze2~(F^78MVUn5a8aBH3Zbo~|QApxM~?&#Rq z+8A3$2_|lagu>OUSO5L>AH-z*Tem-YzZ?(Hpbay+ySv}NzTOP7L2UEx-M>xda_TTN zoM91Ta7Y6w_DhYFTgv?oB>!yt)~#O+Vhi};E&w_9OyZq?p&URxKYMQP=YmVEF_qw9 zdnv%s@NwO`b^kK9-+nLdT3Az2F{AD+3((lG>C>m%_d+xn?B2R{>*bO#b)X$-TlVh# zYcuyMsw3DY-+K@z2=tQij4y28yHLVODr-}{DA1(~cB=gj2L}`=;AVmhV4L+Wz7?oA zW7$iH6aT=y)wM}yzUf`Cdktb&U;VWUs^X=Yxq1AO&7N?DO_BHNLqS#x@2UIyt3C4D zdMBW#eXapx?9xpWpuGylKtCHCvw>KCZ1&Ud?62XvTVB6@J^gbGe;d#h5^L|jx1aaC z$^a;PAmj6%c?*?*9v1p+XBz=Bzq7ZuSO585aI}2bwn?WyEG%rF*YnL8yll;mRxAt= zN%KWqKPt#BTzep}tIr1a?W_idNg=K&)+;iXU4Y6;F3K*paE=lWcsuvbyfBbFjvbPbw z${QFOmImzS%Ml6_1*JL(JJ}ygZf*7|U*qN)Iu{t;9UY*+|6BLJaQS7+mHHcw7aY%u z3IV08gv_OZq5IilN|tAZ0b}sT{mQSeuFikHfBye%-_G6Ax3;!E-}bn9Z_@jUTQ8@8 zV(#IaH*db2`#1Nu;K#eb&~VdR)Bic1{o4KK@f+?g4nBJkSoAP>y85}Sb4q9e0AN<~ AcK`qY