From 59b8e92c4876c9ada4b28860bdc1bbb220ddad88 Mon Sep 17 00:00:00 2001
From: Atony <75191600+AtonyGit@users.noreply.github.com>
Date: Wed, 13 May 2026 08:32:26 -0500
Subject: [PATCH] WIP option toggling
---
MiraAPI/GameModes/AbstractGameMode.cs | 5 ++
MiraAPI/GameModes/GameModeOption.cs | 76 ++++++++++++++++++-
MiraAPI/GameModes/HideAndSeekMode.cs | 1 +
MiraAPI/GameOptions/ModdedOptionsManager.cs | 6 ++
.../Patches/Options/GameOptionsMenuPatch.cs | 2 +-
5 files changed, 85 insertions(+), 5 deletions(-)
diff --git a/MiraAPI/GameModes/AbstractGameMode.cs b/MiraAPI/GameModes/AbstractGameMode.cs
index cd35deb..33d0af9 100644
--- a/MiraAPI/GameModes/AbstractGameMode.cs
+++ b/MiraAPI/GameModes/AbstractGameMode.cs
@@ -42,6 +42,11 @@ public abstract class AbstractGameMode : IOptionable
///
public virtual bool IsHideAndSeek => false;
+ ///
+ /// Gets a value indicating whether the gamemode removes the normal game settings.
+ ///
+ public virtual bool ShowNormalGameSettings => true;
+
///
/// Called on GameManager.GetBodyType().
///
diff --git a/MiraAPI/GameModes/GameModeOption.cs b/MiraAPI/GameModes/GameModeOption.cs
index 5622b5f..4f5a1fc 100644
--- a/MiraAPI/GameModes/GameModeOption.cs
+++ b/MiraAPI/GameModes/GameModeOption.cs
@@ -3,6 +3,7 @@ using System.Linq;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem;
+using MiraAPI.GameOptions;
using MiraAPI.Patches.GameModes;
using MiraAPI.Patches.Options;
using Reactor.Localization.Utilities;
@@ -54,16 +55,23 @@ public static class GameModeOption
if (!Values.ContainsKey(opt))
Values.Add(opt, CustomStringName.CreateAndRegister(opt));
}
+
+ private static List VanillaCategories = new();
+ private static List VanillaOptions = new();
+ private static List BaseCategories = new();
+ private static List BaseOptions = new();
[HarmonyPatch(typeof(GameOptionsMenu), nameof(GameOptionsMenu.CreateSettings))]
[HarmonyPostfix]
private static void CreateSettingsPatch(GameOptionsMenu __instance)
{
- if (GameSettingMenuPatches.SelectedModIdx != 0)
+ if (GameSettingMenuPatches.SelectedModIdx != 0 || GameManager.Instance.IsHideAndSeek() || CustomGameModeManager.ActiveMode == null)
{
return;
}
- if (GameManager.Instance.IsHideAndSeek())
- return;
+ VanillaCategories.Clear();
+ VanillaOptions.Clear();
+ BaseCategories.Clear();
+ BaseOptions.Clear();
float num = 0.713f;
foreach (var category in __instance.settingsContainer.GetComponentsInChildren())
{
@@ -71,6 +79,21 @@ public static class GameModeOption
category.gameObject.transform.localPosition -= new Vector3(0, 1.3f, 0);
}
+ var showOpts = CustomGameModeManager.ActiveMode.ShowNormalGameSettings;
+
+ var newList = __instance.Children.ToArray();
+ BaseOptions.Add(newList[0]);
+ foreach (var obj in newList.Skip(1))
+ {
+ VanillaOptions.Add(obj);
+ obj.gameObject.SetActive(showOpts);
+ }
+ foreach (var category in __instance.settingsContainer.GetComponentsInChildren())
+ {
+ VanillaCategories.Add(category);
+ category.gameObject.SetActive(showOpts);
+ }
+
CategoryHeaderMasked categoryHeaderMasked = Object.Instantiate(__instance.categoryHeaderOrigin, Vector3.zero, Quaternion.identity, __instance.settingsContainer);
categoryHeaderMasked.SetHeader(CustomName, 20);
categoryHeaderMasked.transform.localScale = Vector3.one * 0.63f;
@@ -95,15 +118,60 @@ public static class GameModeOption
_lastValue = opt.GetInt();
CustomGameModeManager.SetGameMode((uint)_lastValue);
HudPatches.SetGameModeText(Values.ElementAt(_lastValue).Key);
+ __instance.RefreshOptions(CustomGameModeManager.ActiveMode);
});
foreach (var optionBehaviour in __instance.Children.ToArray().Skip(1))
{
optionBehaviour.gameObject.transform.localPosition -= new Vector3(0, 1.3f, 0);
}
__instance.Children.Add(OptionBehaviour);
- __instance.scrollBar.SetYBoundsMax(__instance.scrollBar.GetYBounds().max + 1);
+ BaseCategories.Add(categoryHeaderMasked);
+ BaseOptions.Add(OptionBehaviour);
for (var i = 1; i < Values.Count; i++)
OptionBehaviour.Values = (Il2CppStructArray)OptionBehaviour.Values.Add(Values.ElementAt(i).Value);
+ __instance.RefreshOptions(CustomGameModeManager.ActiveMode);
+ }
+
+ private static void RefreshOptions(this GameOptionsMenu instance, AbstractGameMode mode)
+ {
+ instance.Children.Clear();
+ foreach (var group in BaseOptions)
+ {
+ instance.Children.Add(group);
+ }
+
+ var showOpts = mode.ShowNormalGameSettings;
+ var num = 0.083f;
+ foreach (var category in VanillaCategories)
+ {
+ category.gameObject.SetActive(showOpts);
+ }
+ if (showOpts)
+ {
+ foreach (var obj in VanillaOptions)
+ {
+ obj.gameObject.SetActive(true);
+ instance.Children.Add(obj);
+ }
+ instance.scrollBar.SetYBoundsMax(instance.scrollBar.GetYBounds().max + 1);
+ }
+ else
+ {
+ foreach (var obj in VanillaOptions)
+ {
+ obj.gameObject.SetActive(false);
+ }
+ /*var filteredGroups =
+ ModdedOptionsManager.GameModeOptionGroups
+ .Where(x => x.Key == mode.GetType()) ?? [];
+
+ foreach (var group in filteredGroups)
+ {
+ GameOptionsMenuPatch.UpdateGroup(group.Value, ref num);
+ }*/
+
+ instance.scrollBar.SetYBoundsMax(-num - 1.65f);
+ }
}
[HarmonyPatch(typeof(GameOptionsMenu), nameof(GameOptionsMenu.ValueChanged))]
diff --git a/MiraAPI/GameModes/HideAndSeekMode.cs b/MiraAPI/GameModes/HideAndSeekMode.cs
index 5645141..ae0e184 100644
--- a/MiraAPI/GameModes/HideAndSeekMode.cs
+++ b/MiraAPI/GameModes/HideAndSeekMode.cs
@@ -30,6 +30,7 @@ public class HideAndSeekMode : AbstractGameMode
public override bool ShowGameModeIntroCutscene => true;
public override bool GameModeBodyTypeOverride => true;
public override bool IsHideAndSeek => true;
+ public override bool ShowNormalGameSettings => false;
public override IEnumerator IntroCutscene(IntroCutscene __instance)
{
diff --git a/MiraAPI/GameOptions/ModdedOptionsManager.cs b/MiraAPI/GameOptions/ModdedOptionsManager.cs
index e89a272..65dc7c6 100644
--- a/MiraAPI/GameOptions/ModdedOptionsManager.cs
+++ b/MiraAPI/GameOptions/ModdedOptionsManager.cs
@@ -6,6 +6,7 @@ using System.Reflection;
using BepInEx.Configuration;
using HarmonyLib;
using Il2CppInterop.Runtime.Injection;
+using MiraAPI.GameModes;
using MiraAPI.GameOptions.Attributes;
using MiraAPI.GameOptions.OptionTypes;
using MiraAPI.Networking;
@@ -26,6 +27,7 @@ public static class ModdedOptionsManager
internal static readonly Dictionary CreatedPlayerOptions = [];
internal static readonly Dictionary CreatedStringOptions = [];
+ internal static readonly Dictionary GameModeOptionGroups = [];
internal static readonly Dictionary ModdedOptions = [];
internal static readonly List Groups = [];
@@ -70,6 +72,10 @@ public static class ModdedOptionsManager
Groups.Add(group);
TypeToGroup.Add(type, group);
+ if (group.OptionableType?.IsAssignableTo(typeof(AbstractGameMode)) == true)
+ {
+ GameModeOptionGroups.Add(group.OptionableType, group);
+ }
pluginInfo.InternalOptionGroups.Add(group);
typeof(OptionGroupSingleton<>).MakeGenericType(type)
diff --git a/MiraAPI/Patches/Options/GameOptionsMenuPatch.cs b/MiraAPI/Patches/Options/GameOptionsMenuPatch.cs
index c8ee3ce..62dae21 100644
--- a/MiraAPI/Patches/Options/GameOptionsMenuPatch.cs
+++ b/MiraAPI/Patches/Options/GameOptionsMenuPatch.cs
@@ -72,7 +72,7 @@ internal static class GameOptionsMenuPatch
__instance.scrollBar.SetYBoundsMax(-num - 1.65f);
}
- private static void UpdateGroup(AbstractOptionGroup group, ref float num)
+ internal static void UpdateGroup(AbstractOptionGroup group, ref float num)
{
if (group.Options.Count == 0 || group.Header is null)
{