diff --git a/MiraAPI/GameModes/GameModeOption.cs b/MiraAPI/GameModes/GameModeOption.cs index 784d9b9..9eb78ef 100644 --- a/MiraAPI/GameModes/GameModeOption.cs +++ b/MiraAPI/GameModes/GameModeOption.cs @@ -132,187 +132,6 @@ public static class GameModeOption return true; } - private static void CreateGroup(GameOptionsMenu menu, AbstractOptionGroup group) - { - var categoryHeaderMasked = Object.Instantiate( - menu.categoryHeaderOrigin, - Vector3.zero, - Quaternion.identity, - menu.settingsContainer); - - categoryHeaderMasked.SetHeader(CustomStringName.CreateAndRegister(group.GroupName), 20); - categoryHeaderMasked.Background.color = group.GroupColor; - categoryHeaderMasked.Divider.color = group.GroupColor; - categoryHeaderMasked.Title.color = group.GroupColor.Equals(MiraApiPlugin.DefaultHeaderColor) - ? Color.white - : group.GroupColor.FindAlternateColor(); - - categoryHeaderMasked.Background.sprite = MiraAssets.CategoryHeader.LoadAsset(); - 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); - - categoryHeaderMasked.gameObject.SetActive(false); - group.Header = categoryHeaderMasked; - categoryHeaderMasked.transform.localPosition += Vector3.down; - - var newText = Object.Instantiate(categoryHeaderMasked.Title, categoryHeaderMasked.transform); - newText.text = group.AllOptionsHidden - ? "(Click to open)" - : "(Click to close)"; - newText.transform.localPosition = new Vector3(2.6249f, -0.165f, 0f); - newText.gameObject.GetComponent().Destroy(); - - var options = group.Options.Select(opt => opt.CreateOption( - menu.checkboxOrigin, - menu.numberOptionOrigin, - menu.stringOptionOrigin, - menu.playerOptionOrigin, - menu.settingsContainer)); - - /*OptionPreset? defaultPreset = null; - if (GameSettingMenuPatches.SelectedMod != null && PresetManager.DefaultPresets.TryGetValue( - GameSettingMenuPatches.SelectedMod, - out var preset)) - { - defaultPreset = preset; - }*/ - - foreach (var newOpt in options) - { - newOpt.SetClickMask(menu.ButtonClickMask); - SpriteRenderer[] componentsInChildren = newOpt.GetComponentsInChildren(true); - foreach (var renderer in componentsInChildren) - { - if (group.GroupColor != MiraApiPlugin.DefaultHeaderColor) - { - renderer.color = group.GroupColor.FindAlternateColor(); - if (renderer.transform.parent.TryGetComponent(out var btn)) - { - btn.interactableColor = group.GroupColor.FindAlternateColor(); - btn.interactableHoveredColor = Color.white; - } - } - - renderer.material.SetInt(PlayerMaterial.MaskLayer, 20); - } - - foreach (var textMeshPro in newOpt.GetComponentsInChildren(true)) - { - if (group.GroupColor != MiraApiPlugin.DefaultHeaderColor) - { - textMeshPro.color = group.GroupColor; - } - - textMeshPro.fontMaterial.SetFloat(ShaderID.StencilComp, 3f); - textMeshPro.fontMaterial.SetFloat(ShaderID.Stencil, 20); - } - - if (newOpt is ToggleOption toggle) - { - toggle.CheckMark.sprite = MiraAssets.Checkmark.LoadAsset(); - toggle.CheckMark.color = group.GroupColor != MiraApiPlugin.DefaultHeaderColor - ? group.GroupColor - : MiraAssets.AcceptedTeal; - var rend = toggle.CheckMark.transform.parent.FindChild("ActiveSprite") - .GetComponent(); - rend.sprite = MiraAssets.CheckmarkBox.LoadAsset(); - rend.color = group.GroupColor != MiraApiPlugin.DefaultHeaderColor - ? group.GroupColor - : MiraAssets.AcceptedTeal; - } - - menu.Children.Add(newOpt); - - /*var resetBtn = new GameObject("ResetOption"); - resetBtn.transform.parent = newOpt.transform; - resetBtn.transform.localScale = new(.5f, .5f, 1); - resetBtn.layer = LayerMask.NameToLayer("UI"); - resetBtn.transform.localPosition = new Vector3(-3.1f, 0f, -2f); - var resetRend = resetBtn.AddComponent(); - resetRend.sprite = MiraAssets.ResetButton.LoadAsset(); - resetRend.maskInteraction = SpriteMaskInteraction.VisibleInsideMask; - resetRend.color = group.GroupColor.Equals(MiraApiPlugin.DefaultHeaderColor) - ? Color.white - : group.GroupColor.FindAlternateColor(); - var resetBoxCol = resetBtn.gameObject.AddComponent(); - resetBoxCol.size = new Vector2(1f, 1f); - resetBoxCol.offset = new Vector2(0, 0); - var passiveButton = resetBtn.AddComponent(); - passiveButton.OnClick = new Button.ButtonClickedEvent(); - passiveButton.ClickSound = menu.BackButton.GetComponent().ClickSound; - passiveButton.OnMouseOver = new UnityEvent(); - passiveButton.OnMouseOver.AddListener( - (UnityAction)(() => - { - resetRend.color = group.GroupColor != MiraApiPlugin.DefaultHeaderColor - ? group.GroupColor - : MiraAssets.AcceptedTeal; - })); - passiveButton.OnMouseOut = new UnityEvent(); - passiveButton.OnMouseOut.AddListener( - (UnityAction)(() => - { - resetRend.color = group.GroupColor.Equals(MiraApiPlugin.DefaultHeaderColor) - ? Color.white - : group.GroupColor.FindAlternateColor(); - })); - if (newOpt is ToggleOption toggleOpt) - { - passiveButton.OnClick.AddListener( - (UnityAction)(() => - { - defaultPreset!.ResetOption(toggleOpt); - })); - } - else if (newOpt is NumberOption numOpt) - { - passiveButton.OnClick.AddListener( - (UnityAction)(() => - { - defaultPreset!.ResetOption(numOpt); - })); - } - else if (newOpt is StringOption strOpt) - { - passiveButton.OnClick.AddListener( - (UnityAction)(() => - { - defaultPreset!.ResetOption(strOpt); - })); - } - if (!defaultPreset!.IsOptionInPreset(newOpt)) - { - resetBtn.Destroy(); - }*/ - - newOpt.Initialize(); - newOpt.gameObject.SetActive(false); - } - - var boxCol = categoryHeaderMasked.gameObject.AddComponent(); - boxCol.size = new Vector2(7, 0.7f); - boxCol.offset = new Vector2(1.5f, -0.3f); - - var headerBtn = categoryHeaderMasked.gameObject.AddComponent(); - headerBtn.ClickSound = menu.BackButton.GetComponent().ClickSound; - headerBtn.OnMouseOver = new UnityEvent(); - headerBtn.OnMouseOut = new UnityEvent(); - headerBtn.OnClick.AddListener( - (UnityAction)(() => - { - group.AllOptionsHidden = !group.AllOptionsHidden; - newText.text = group.AllOptionsHidden - ? "(Click to open)" - : "(Click to close)"; - })); - headerBtn.SetButtonEnableState(true); - } - [MethodRpc((uint) MiraRpc.SyncGamemodeOption)] internal static void RpcSyncGamemode(PlayerControl host, int data) { diff --git a/MiraAPI/Patches/Options/GameOptionsMenuPatch.cs b/MiraAPI/Patches/Options/GameOptionsMenuPatch.cs index a54dfca..1da222a 100644 --- a/MiraAPI/Patches/Options/GameOptionsMenuPatch.cs +++ b/MiraAPI/Patches/Options/GameOptionsMenuPatch.cs @@ -28,8 +28,9 @@ internal static class GameOptionsMenuPatch private static List _vanillaHeaders = new(); private static List _vanillaOptions = new(); private static List _mainOptions = new(); - private static Dictionary _gameModeOptions = new(); - private static Dictionary _gameModeHeaders = new(); + private static System.Collections.Generic.Dictionary> _gameModeGroups = new(); + private static System.Collections.Generic.Dictionary> _gameModeOptions = new(); + private static System.Collections.Generic.Dictionary> _gameModeHeaders = new(); [HarmonyPrefix] [HarmonyPatch(nameof(GameOptionsMenu.Initialize))] // ReSharper disable once InconsistentNaming @@ -73,6 +74,7 @@ internal static class GameOptionsMenuPatch return false; } + public static float AdditionalVanillaScrollNum; internal static void ToggleGamemodeOptions(AbstractGameMode gameMode, GameOptionsMenu instance) { float num = -1.217f; @@ -106,6 +108,41 @@ internal static class GameOptionsMenuPatch opt.gameObject.SetActive(false); } } + + foreach (var pair in _gameModeGroups) + { + if (pair.Value.Count != 0) + { + if (gameMode == pair.Key) + { + foreach (var opt in _gameModeHeaders[gameMode]) + { + num -= 0.63f; + opt.gameObject.SetActive(true); + } + + foreach (var opt in _gameModeOptions[gameMode]) + { + opt.gameObject.SetActive(true); + instance.Children.Add(opt); + num -= 0.45f; + } + } + else + { + foreach (var opt in _gameModeHeaders[pair.Key]) + { + opt.gameObject.SetActive(false); + } + + foreach (var opt in _gameModeOptions[pair.Key]) + { + opt.gameObject.SetActive(false); + } + } + } + } + instance.ControllerSelectable.Clear(); foreach (var obj in instance.scrollBar.GetComponentsInChildren()) { @@ -124,6 +161,7 @@ internal static class GameOptionsMenuPatch _mainOptions.Clear(); _gameModeHeaders.Clear(); _gameModeOptions.Clear(); + _gameModeGroups.Clear(); CategoryHeaderMasked gmCategory = Object.Instantiate(instance.categoryHeaderOrigin, Vector3.zero, Quaternion.identity, container); gmCategory.SetHeader(GameModeOption.CustomName, 20); @@ -158,7 +196,7 @@ internal static class GameOptionsMenuPatch } num -= 1.3f; - + AdditionalVanillaScrollNum = 0f; foreach (RulesCategory rulesCategory in GameManager.Instance.GameSettingsList.AllCategories) { CategoryHeaderMasked categoryHeaderMasked = Object.Instantiate( @@ -171,6 +209,7 @@ internal static class GameOptionsMenuPatch categoryHeaderMasked.transform.localPosition = new Vector3(-0.903f, num, -2f); _vanillaHeaders.Add(categoryHeaderMasked); num -= 0.63f; + AdditionalVanillaScrollNum -= 0.63f; foreach (BaseGameSetting baseGameSetting in rulesCategory.AllGameSettings) { switch (baseGameSetting.Type) @@ -231,6 +270,7 @@ internal static class GameOptionsMenuPatch } num -= 0.45f; + AdditionalVanillaScrollNum -= 0.45f; } } foreach (var optionBehaviour in _vanillaOptions) @@ -247,6 +287,24 @@ internal static class GameOptionsMenuPatch optionBehaviour.OnValueChanged = new Action(instance.ValueChanged); } + foreach (var mode in CustomGameModeManager.IdToModeMap.Values) + { + var filteredGroups = + ModdedOptionsManager.GameModeOptionGroups + .Where(x => x.Key == mode.GetType()).Select(y => y.Value).SelectMany(y => y) ?? []; + _gameModeGroups.Add(mode, filteredGroups.ToList()); + + var optionBehaviours = new System.Collections.Generic.List(); + var categoryHeaders = new System.Collections.Generic.List(); + var newNum = mode.ShowNormalGameSettings ? num : num - AdditionalVanillaScrollNum; + foreach (var group in filteredGroups) + { + CreateGroup(instance, group, container, ref newNum, ref optionBehaviours, ref categoryHeaders); + } + _gameModeHeaders.Add(mode, categoryHeaders); + _gameModeOptions.Add(mode, optionBehaviours); + } + instance.ControllerSelectable.Clear(); foreach (var obj in instance.scrollBar.GetComponentsInChildren()) { @@ -278,7 +336,6 @@ internal static class GameOptionsMenuPatch { return; } - var num = 2.1f; switch (MenuState.Instance.CurrentMenu) @@ -308,6 +365,98 @@ internal static class GameOptionsMenuPatch __instance.scrollBar.SetYBoundsMax(-num - 1.65f); } + private static void CreateGroup(GameOptionsMenu menu, AbstractOptionGroup group, Transform container, ref float num, ref System.Collections.Generic.List optionBehaviours, ref System.Collections.Generic.List categoryHeaders) + { + var categoryHeaderMasked = Object.Instantiate( + menu.categoryHeaderOrigin, + Vector3.zero, + Quaternion.identity, + container); + categoryHeaderMasked.transform.localPosition = new Vector3(-0.903f, num + 1, -2f); + categoryHeaderMasked.transform.localScale = Vector3.one * 0.63f; + categoryHeaders.Add(categoryHeaderMasked); + + num -= 0.58f; + + categoryHeaderMasked.SetHeader(CustomStringName.CreateAndRegister(group.GroupName), 20); + categoryHeaderMasked.Background.color = group.GroupColor; + categoryHeaderMasked.Divider.color = group.GroupColor; + categoryHeaderMasked.Title.color = group.GroupColor.Equals(MiraApiPlugin.DefaultHeaderColor) + ? Color.white + : group.GroupColor.FindAlternateColor(); + + categoryHeaderMasked.Background.sprite = MiraAssets.CategoryHeader.LoadAsset(); + 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); + + categoryHeaderMasked.gameObject.SetActive(true); + group.Header = categoryHeaderMasked; + categoryHeaderMasked.transform.localPosition += Vector3.down; + + var options = group.Options.Select(opt => opt.CreateOption( + menu.checkboxOrigin, + menu.numberOptionOrigin, + menu.stringOptionOrigin, + menu.playerOptionOrigin, + container)); + + foreach (var newOpt in options) + { + newOpt.SetClickMask(menu.ButtonClickMask); + SpriteRenderer[] componentsInChildren = newOpt.GetComponentsInChildren(true); + foreach (var renderer in componentsInChildren) + { + if (group.GroupColor != MiraApiPlugin.DefaultHeaderColor) + { + renderer.color = group.GroupColor.FindAlternateColor(); + if (renderer.transform.parent.TryGetComponent(out var btn)) + { + btn.interactableColor = group.GroupColor.FindAlternateColor(); + btn.interactableHoveredColor = Color.white; + } + } + + renderer.material.SetInt(PlayerMaterial.MaskLayer, 20); + } + + foreach (var textMeshPro in newOpt.GetComponentsInChildren(true)) + { + if (group.GroupColor != MiraApiPlugin.DefaultHeaderColor) + { + textMeshPro.color = group.GroupColor; + } + + textMeshPro.fontMaterial.SetFloat(ShaderID.StencilComp, 3f); + textMeshPro.fontMaterial.SetFloat(ShaderID.Stencil, 20); + } + + if (newOpt is ToggleOption toggle) + { + toggle.CheckMark.sprite = MiraAssets.Checkmark.LoadAsset(); + toggle.CheckMark.color = group.GroupColor != MiraApiPlugin.DefaultHeaderColor + ? group.GroupColor + : MiraAssets.AcceptedTeal; + var rend = toggle.CheckMark.transform.parent.FindChild("ActiveSprite") + .GetComponent(); + rend.sprite = MiraAssets.CheckmarkBox.LoadAsset(); + rend.color = group.GroupColor != MiraApiPlugin.DefaultHeaderColor + ? group.GroupColor + : MiraAssets.AcceptedTeal; + } + + optionBehaviours.Add(newOpt); + newOpt.transform.localPosition = new Vector3(0.952f, num, -2f); + num -= 0.45f; + + newOpt.Initialize(); + newOpt.gameObject.SetActive(true); + } + } internal static void UpdateGroup(AbstractOptionGroup? group, ref float num) {