mirror of
https://github.com/D1GQ/BetterAmongUs.git
synced 2026-10-19 15:51:52 +00:00
Add pages to client options
This commit is contained in:
1 parent
e644537355
commit
55391e7d4e
2 files changed
+113
-116
No files matched your search
+100
-103
@@ -2,7 +2,6 @@
|
||||
using BetterAmongUs.Helpers;
|
||||
using BetterAmongUs.Patches.Client;
|
||||
using UnityEngine;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace BetterAmongUs.Modules;
|
||||
|
||||
@@ -24,24 +23,23 @@ internal sealed class ClientOptionItem
|
||||
/// <summary>
|
||||
/// Gets the list of all created client option items.
|
||||
/// </summary>
|
||||
internal static readonly List<ClientOptionItem> ClientOptions = [];
|
||||
internal static readonly Dictionary<int, List<ClientOptionItem>> ClientOptions = [];
|
||||
|
||||
/// <summary>
|
||||
/// Creates a toggle option with configuration binding.
|
||||
/// </summary>
|
||||
/// <param name="name">The display name of the option.</param>
|
||||
/// <param name="config">The configuration entry to bind to.</param>
|
||||
/// <param name="optionsMenuBehaviour">The options menu behavior instance.</param>
|
||||
/// <param name="onToggle">Optional action to execute when the toggle is changed.</param>
|
||||
/// <param name="toggleCheck">Optional function to check if the toggle can be changed.</param>
|
||||
/// <returns>A new ClientOptionItem instance.</returns>
|
||||
public static ClientOptionItem CreateToggle(string name, ConfigEntry<bool> config, OptionsMenuBehaviour optionsMenuBehaviour, Action? onToggle = null, Func<bool>? toggleCheck = null)
|
||||
public static ClientOptionItem CreateToggle(string name, ConfigEntry<bool> config, int page, OptionsMenuBehaviour optionsMenuBehaviour, Action? onToggle = null, Func<bool>? toggleCheck = null)
|
||||
{
|
||||
var toggleButton = CreateToggleButton(name, config.Value, optionsMenuBehaviour);
|
||||
var toggleButton = CreateToggleButton(name, optionsMenuBehaviour, GetOrCreatePage(page, optionsMenuBehaviour).transform);
|
||||
toggleButton.transform.localPosition = CalculateButtonPosition(page);
|
||||
var item = new ClientOptionItem(name, config, toggleButton);
|
||||
|
||||
item.SetupToggleButton(onToggle, toggleCheck);
|
||||
ClientOptions.Add(item);
|
||||
if (!ClientOptions.TryGetValue(page, out var options))
|
||||
{
|
||||
options = ClientOptions[page] = [];
|
||||
}
|
||||
options.Add(item);
|
||||
|
||||
return item;
|
||||
}
|
||||
@@ -49,38 +47,18 @@ internal sealed class ClientOptionItem
|
||||
/// <summary>
|
||||
/// Creates a button option without toggle state.
|
||||
/// </summary>
|
||||
/// <param name="name">The display name of the button.</param>
|
||||
/// <param name="optionsMenuBehaviour">The options menu behavior instance.</param>
|
||||
/// <param name="onClick">The action to execute when the button is clicked.</param>
|
||||
/// <param name="clickCheck">Optional function to check if the button can be clicked.</param>
|
||||
/// <returns>A new ClientOptionItem instance.</returns>
|
||||
public static ClientOptionItem CreateButton(string name, OptionsMenuBehaviour optionsMenuBehaviour, Action onClick, Func<bool>? clickCheck = null)
|
||||
public static ClientOptionItem CreateButton(string name, int page, OptionsMenuBehaviour optionsMenuBehaviour, Action onClick, Func<bool>? clickCheck = null)
|
||||
{
|
||||
var toggleButton = CreateToggleButton(name, false, optionsMenuBehaviour);
|
||||
var toggleButton = CreateToggleButton(name, optionsMenuBehaviour, GetOrCreatePage(page, optionsMenuBehaviour).transform);
|
||||
toggleButton.transform.localPosition = CalculateButtonPosition(page);
|
||||
var item = new ClientOptionItem(name, null, toggleButton);
|
||||
|
||||
item.SetupButton(onClick, clickCheck);
|
||||
ClientOptions.Add(item);
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a toggle option without configuration binding (manual state management).
|
||||
/// </summary>
|
||||
/// <param name="name">The display name of the option.</param>
|
||||
/// <param name="initialState">The initial state of the toggle.</param>
|
||||
/// <param name="optionsMenuBehaviour">The options menu behavior instance.</param>
|
||||
/// <param name="onToggle">The action to execute when the toggle is changed, receiving the new state.</param>
|
||||
/// <param name="toggleCheck">Optional function to check if the toggle can be changed.</param>
|
||||
/// <returns>A new ClientOptionItem instance.</returns>
|
||||
public static ClientOptionItem CreateManualToggle(string name, bool initialState, OptionsMenuBehaviour optionsMenuBehaviour, Action<bool> onToggle, Func<bool>? toggleCheck = null)
|
||||
{
|
||||
var toggleButton = CreateToggleButton(name, initialState, optionsMenuBehaviour);
|
||||
var item = new ClientOptionItem(name, null, toggleButton);
|
||||
|
||||
item.SetupManualToggle(initialState, onToggle, toggleCheck);
|
||||
ClientOptions.Add(item);
|
||||
if (!ClientOptions.TryGetValue(page, out var options))
|
||||
{
|
||||
options = ClientOptions[page] = [];
|
||||
}
|
||||
options.Add(item);
|
||||
|
||||
return item;
|
||||
}
|
||||
@@ -88,10 +66,7 @@ internal sealed class ClientOptionItem
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the ClientOptionItem class.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the option.</param>
|
||||
/// <param name="config">The configuration entry, or null for non-config options.</param>
|
||||
/// <param name="toggleButton">The toggle button behavior instance.</param>
|
||||
private ClientOptionItem(string name, ConfigEntry<bool>? config, ToggleButtonBehaviour toggleButton)
|
||||
internal ClientOptionItem(string name, ConfigEntry<bool>? config, ToggleButtonBehaviour toggleButton)
|
||||
{
|
||||
Config = config;
|
||||
ToggleButton = toggleButton;
|
||||
@@ -101,21 +76,10 @@ internal sealed class ClientOptionItem
|
||||
/// <summary>
|
||||
/// Creates a toggle button GameObject for the options menu.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the toggle button.</param>
|
||||
/// <param name="initialState">The initial state of the toggle.</param>
|
||||
/// <param name="optionsMenuBehaviour">The options menu behavior instance.</param>
|
||||
/// <returns>A new ToggleButtonBehaviour instance.</returns>
|
||||
private static ToggleButtonBehaviour CreateToggleButton(string name, bool initialState, OptionsMenuBehaviour optionsMenuBehaviour)
|
||||
private static ToggleButtonBehaviour CreateToggleButton(string name, OptionsMenuBehaviour optionsMenuBehaviour, Transform parent)
|
||||
{
|
||||
if (OptionsMenuBehaviourPatch.BetterOptionsTab?.Content == null)
|
||||
{
|
||||
throw new InvalidOperationException("BetterOptionsTab is not initialized");
|
||||
}
|
||||
|
||||
var mouseMoveToggle = optionsMenuBehaviour.DisableMouseMovement;
|
||||
var toggleButton = Object.Instantiate(mouseMoveToggle, OptionsMenuBehaviourPatch.BetterOptionsTab.Content.transform);
|
||||
|
||||
toggleButton.transform.localPosition = CalculateButtonPosition();
|
||||
var toggleButton = UnityEngine.Object.Instantiate(mouseMoveToggle, parent);
|
||||
toggleButton.name = name;
|
||||
toggleButton.Text.text = name;
|
||||
|
||||
@@ -125,12 +89,15 @@ internal sealed class ClientOptionItem
|
||||
/// <summary>
|
||||
/// Calculates the position for a new button based on the current number of options.
|
||||
/// </summary>
|
||||
/// <returns>A Vector3 representing the button position.</returns>
|
||||
private static Vector3 CalculateButtonPosition()
|
||||
private static Vector3 CalculateButtonPosition(int page)
|
||||
{
|
||||
if (!ClientOptions.TryGetValue(page, out var options))
|
||||
{
|
||||
options = ClientOptions[page] = [];
|
||||
}
|
||||
return new Vector3(
|
||||
ClientOptions.Count % 2 == 0 ? -1.3f : 1.3f,
|
||||
1.8f - 0.5f * (ClientOptions.Count / 2),
|
||||
options.Count % 2 == 0 ? -1.3f : 1.3f,
|
||||
1.8f - 0.5f * (options.Count / 2),
|
||||
-6f
|
||||
);
|
||||
}
|
||||
@@ -138,9 +105,7 @@ internal sealed class ClientOptionItem
|
||||
/// <summary>
|
||||
/// Sets up a configuration-bound toggle button with click handler.
|
||||
/// </summary>
|
||||
/// <param name="onToggle">Optional action to execute when toggled.</param>
|
||||
/// <param name="toggleCheck">Optional function to check if the toggle can be changed.</param>
|
||||
private void SetupToggleButton(Action? onToggle, Func<bool>? toggleCheck)
|
||||
internal void SetupToggleButton(Action? onToggle, Func<bool>? toggleCheck)
|
||||
{
|
||||
var passiveButton = ToggleButton.GetComponent<PassiveButton>();
|
||||
passiveButton.OnClick = new();
|
||||
@@ -163,9 +128,7 @@ internal sealed class ClientOptionItem
|
||||
/// <summary>
|
||||
/// Sets up a button (non-toggle) with click handler.
|
||||
/// </summary>
|
||||
/// <param name="onClick">The action to execute when clicked.</param>
|
||||
/// <param name="clickCheck">Optional function to check if the button can be clicked.</param>
|
||||
private void SetupButton(Action onClick, Func<bool>? clickCheck)
|
||||
internal void SetupButton(Action onClick, Func<bool>? clickCheck)
|
||||
{
|
||||
var passiveButton = ToggleButton.GetComponent<PassiveButton>();
|
||||
passiveButton.OnClick = new();
|
||||
@@ -182,31 +145,6 @@ internal sealed class ClientOptionItem
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets up a manually managed toggle button with state tracking.
|
||||
/// </summary>
|
||||
/// <param name="initialState">The initial state of the toggle.</param>
|
||||
/// <param name="onToggle">The action to execute when toggled, receiving the new state.</param>
|
||||
/// <param name="toggleCheck">Optional function to check if the toggle can be changed.</param>
|
||||
private void SetupManualToggle(bool initialState, Action<bool> onToggle, Func<bool>? toggleCheck)
|
||||
{
|
||||
var passiveButton = ToggleButton.GetComponent<PassiveButton>();
|
||||
passiveButton.OnClick = new();
|
||||
|
||||
bool currentState = initialState;
|
||||
|
||||
passiveButton.OnClick.AddListener(() =>
|
||||
{
|
||||
if (toggleCheck?.Invoke() == false) return;
|
||||
|
||||
currentState = !currentState;
|
||||
UpdateManualToggle(currentState);
|
||||
onToggle?.Invoke(currentState);
|
||||
});
|
||||
|
||||
UpdateManualToggle(initialState);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the visual state of a config-bound toggle button.
|
||||
/// </summary>
|
||||
@@ -217,21 +155,9 @@ internal sealed class ClientOptionItem
|
||||
UpdateToggleVisuals(Config.Value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the visual state of a manually managed toggle button.
|
||||
/// </summary>
|
||||
/// <param name="isEnabled">The current enabled state of the toggle.</param>
|
||||
internal void UpdateManualToggle(bool isEnabled)
|
||||
{
|
||||
if (ToggleButton == null) return;
|
||||
|
||||
UpdateToggleVisuals(isEnabled);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the visual appearance of a toggle button based on its state.
|
||||
/// </summary>
|
||||
/// <param name="isEnabled">Whether the toggle is enabled.</param>
|
||||
private void UpdateToggleVisuals(bool isEnabled)
|
||||
{
|
||||
var color = isEnabled ?
|
||||
@@ -247,4 +173,75 @@ internal sealed class ClientOptionItem
|
||||
ToggleButton.Text.color = textColor;
|
||||
ToggleButton.Text.text = $"{ToggleButton.name}: {(isEnabled ? "On" : "Off")}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves an existing page GameObject or creates a new one with navigation buttons.
|
||||
/// </summary>
|
||||
private static GameObject? GetOrCreatePage(int page, OptionsMenuBehaviour optionsMenuBehaviour, bool doNotCreate = false)
|
||||
{
|
||||
string name = "Page " + page;
|
||||
var currentPage = OptionsMenuBehaviourPatch.BetterOptionsTab.Content.transform.Find(name)?.gameObject;
|
||||
if (currentPage == null)
|
||||
{
|
||||
if (doNotCreate)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
currentPage = new GameObject(name);
|
||||
currentPage.SetActive(page == 1);
|
||||
currentPage.transform.SetParent(OptionsMenuBehaviourPatch.BetterOptionsTab.Content.transform);
|
||||
currentPage.transform.localPosition = Vector3.zero;
|
||||
currentPage.transform.localScale = Vector3.one;
|
||||
|
||||
int previous = page - 1;
|
||||
if (previous > 0)
|
||||
{
|
||||
var previousPage = GetOrCreatePage(previous, optionsMenuBehaviour, true);
|
||||
if (previousPage != null)
|
||||
{
|
||||
CreatePreviousButton(currentPage, previousPage, optionsMenuBehaviour);
|
||||
CreateNextButton(previousPage, currentPage, optionsMenuBehaviour);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return currentPage;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a "Next" navigation button that switches to the specified next page.
|
||||
/// </summary>
|
||||
private static void CreateNextButton(GameObject page, GameObject nextPage, OptionsMenuBehaviour optionsMenuBehaviour)
|
||||
{
|
||||
var button = CreateToggleButton("Next >", optionsMenuBehaviour, page.transform);
|
||||
button.transform.localPosition = new Vector3(2f, -2.5f, 0f);
|
||||
button.transform.Find("Background")?.localScale = new Vector3(0.5f, 1f, 1f);
|
||||
button.transform.Find("ButtonHighlight")?.localScale = new Vector3(0.5f, 0.95f, 1f);
|
||||
var passiveButton = button.GetComponent<PassiveButton>();
|
||||
passiveButton.OnClick = new();
|
||||
passiveButton.OnClick.AddListener(() =>
|
||||
{
|
||||
page.SetActive(false);
|
||||
nextPage.SetActive(true);
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a "Previous" navigation button that switches to the specified previous page.
|
||||
/// </summary>
|
||||
private static void CreatePreviousButton(GameObject page, GameObject previousPage, OptionsMenuBehaviour optionsMenuBehaviour)
|
||||
{
|
||||
var button = CreateToggleButton("< Prev", optionsMenuBehaviour, page.transform);
|
||||
button.transform.localPosition = new Vector3(-2f, -2.5f, 0f);
|
||||
button.transform.Find("Background")?.localScale = new Vector3(0.5f, 1f, 1f);
|
||||
button.transform.Find("ButtonHighlight")?.localScale = new Vector3(0.5f, 0.95f, 1f);
|
||||
var passiveButton = button.GetComponent<PassiveButton>();
|
||||
passiveButton.OnClick = new();
|
||||
passiveButton.OnClick.AddListener(() =>
|
||||
{
|
||||
page.SetActive(false);
|
||||
previousPage.SetActive(true);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
using BepInEx;
|
||||
using BepInEx;
|
||||
using BetterAmongUs.Data;
|
||||
using BetterAmongUs.Helpers;
|
||||
using BetterAmongUs.Managers;
|
||||
@@ -39,19 +39,19 @@ internal static class OptionsMenuBehaviourPatch
|
||||
ClientOptionItem.ClientOptions.Clear();
|
||||
|
||||
// Toggle options with config binding
|
||||
ClientOptionItem.CreateToggle(Translator.GetString("BetterOption.AntiCheat"), BAUPlugin.AntiCheat, __instance);
|
||||
ClientOptionItem.CreateToggle(Translator.GetString("BetterOption.SendBetterRpc"), BAUPlugin.SendBetterRpc, __instance, SendBetterRpcAction);
|
||||
ClientOptionItem.CreateToggle(Translator.GetString("BetterOption.BetterNotifications"), BAUPlugin.BetterNotifications, __instance, ClearNotifications);
|
||||
ClientOptionItem.CreateToggle(Translator.GetString("BetterOption.ForceOwnLanguage"), BAUPlugin.ForceOwnLanguage, __instance);
|
||||
ClientOptionItem.CreateToggle(Translator.GetString("BetterOption.ChatDarkMode"), BAUPlugin.ChatDarkMode, __instance, ChatPatch.SetChatTheme);
|
||||
ClientOptionItem.CreateToggle(Translator.GetString("BetterOption.ChatInGame"), BAUPlugin.ChatInGameplay, __instance);
|
||||
ClientOptionItem.CreateToggle(Translator.GetString("BetterOption.LobbyInfo"), BAUPlugin.LobbyPlayerInfo, __instance);
|
||||
ClientOptionItem.CreateToggle(Translator.GetString("BetterOption.LobbyTheme"), BAUPlugin.DisableLobbyTheme, __instance, ToggleLobbyTheme);
|
||||
ClientOptionItem.CreateToggle(Translator.GetString("BetterOption.UnlockFPS"), BAUPlugin.UnlockFPS, __instance, UpdateFrameRate);
|
||||
ClientOptionItem.CreateToggle(Translator.GetString("BetterOption.ShowFPS"), BAUPlugin.ShowFPS, __instance);
|
||||
ClientOptionItem.CreateToggle(Translator.GetString("BetterOption.AntiCheat"), BAUPlugin.AntiCheat, 1, __instance);
|
||||
ClientOptionItem.CreateToggle(Translator.GetString("BetterOption.SendBetterRpc"), BAUPlugin.SendBetterRpc, 1, __instance, SendBetterRpcAction);
|
||||
ClientOptionItem.CreateToggle(Translator.GetString("BetterOption.BetterNotifications"), BAUPlugin.BetterNotifications, 1, __instance, ClearNotifications);
|
||||
ClientOptionItem.CreateToggle(Translator.GetString("BetterOption.ForceOwnLanguage"), BAUPlugin.ForceOwnLanguage, 1, __instance);
|
||||
ClientOptionItem.CreateToggle(Translator.GetString("BetterOption.ChatDarkMode"), BAUPlugin.ChatDarkMode, 1, __instance, ChatPatch.SetChatTheme);
|
||||
ClientOptionItem.CreateToggle(Translator.GetString("BetterOption.ChatInGame"), BAUPlugin.ChatInGameplay, 1, __instance);
|
||||
ClientOptionItem.CreateToggle(Translator.GetString("BetterOption.LobbyInfo"), BAUPlugin.LobbyPlayerInfo, 1, __instance);
|
||||
ClientOptionItem.CreateToggle(Translator.GetString("BetterOption.LobbyTheme"), BAUPlugin.DisableLobbyTheme, 1, __instance, ToggleLobbyTheme);
|
||||
ClientOptionItem.CreateToggle(Translator.GetString("BetterOption.UnlockFPS"), BAUPlugin.UnlockFPS, 1, __instance, UpdateFrameRate);
|
||||
ClientOptionItem.CreateToggle(Translator.GetString("BetterOption.ShowFPS"), BAUPlugin.ShowFPS, 1, __instance);
|
||||
|
||||
// Button options (no toggle)
|
||||
ClientOptionItem.CreateButton(Translator.GetString("BetterOption.SaveData"), __instance, OpenSaveData, () =>
|
||||
ClientOptionItem.CreateButton(Translator.GetString("BetterOption.SaveData"), 1, __instance, OpenSaveData, () =>
|
||||
{
|
||||
// Only allow opening save data in lobby/main menu, not during gameplay
|
||||
bool cannotOpen = GameState.IsInGame && !GameState.IsLobby;
|
||||
@@ -62,7 +62,7 @@ internal static class OptionsMenuBehaviourPatch
|
||||
return !cannotOpen;
|
||||
});
|
||||
|
||||
ClientOptionItem.CreateButton(Translator.GetString("BetterOption.ToVanilla"), __instance, SwitchToVanilla, () =>
|
||||
ClientOptionItem.CreateButton(Translator.GetString("BetterOption.ToVanilla"), 1, __instance, SwitchToVanilla, () =>
|
||||
{
|
||||
// Prevent switching to vanilla while in a game
|
||||
bool cannotSwitch = GameState.IsInGame;
|
||||
|
||||
Reference in new issue
Block a user