-
using HarmonyLib;
using UnityEngine;
-using System.Collections.Generic;
-using Hazel;
using System;
-using UnityEngine.UI;
+using System.Collections.Generic;
+using TMPro;
using UnityEngine.Events;
-
-namespace TheOtherRoles.Patches {
- [HarmonyPatch(typeof(OptionsMenuBehaviour), nameof(OptionsMenuBehaviour.Start))]
- public class OptionsMenuBehaviourStartPatch {
- private static Vector3? origin;
- private static ToggleButtonBehaviour streamerModeButton;
- private static ToggleButtonBehaviour ghostsSeeTasksButton;
- private static ToggleButtonBehaviour ghostsSeeRolesButton;
- private static ToggleButtonBehaviour ghostsSeeVotesButton;
- private static ToggleButtonBehaviour showRoleSummaryButton;
-
- public static float xOffset = 1.75f;
- public static float yOffset = -0.25f;
-
- private static void updateToggle(ToggleButtonBehaviour button, string text, bool on) {
- if (button == null || button.gameObject == null) return;
-
- Color color = on ? new Color(0f, 1f, 0.16470589f, 1f) : Color.white;
- button.Background.color = color;
- button.Text.text = $"{text}{(on ? "On" : "Off")}";
- if (button.Rollover) button.Rollover.ChangeOutColor(color);
+using UnityEngine.SceneManagement;
+using static UnityEngine.UI.Button;
+using Object = UnityEngine.Object;
+
+namespace TheOtherRoles.Patches
+{
+ [HarmonyPatch]
+ public static class ClientOptionsPatch
+ {
+ private static SelectionBehaviour[] AllOptions = {
+ new SelectionBehaviour("Streamer Mode", () => TheOtherRolesPlugin.StreamerMode.Value = !TheOtherRolesPlugin.StreamerMode.Value, TheOtherRolesPlugin.StreamerMode.Value),
+ new SelectionBehaviour("Ghosts See Tasks", () => TheOtherRolesPlugin.GhostsSeeTasks.Value = !TheOtherRolesPlugin.GhostsSeeTasks.Value, TheOtherRolesPlugin.GhostsSeeTasks.Value),
+ new SelectionBehaviour("Vote Visible For Ghosts", () => TheOtherRolesPlugin.GhostsSeeVotes.Value = !TheOtherRolesPlugin.GhostsSeeVotes.Value, TheOtherRolesPlugin.GhostsSeeVotes.Value),
+ new SelectionBehaviour("Ghosts Can See Roles", () => TheOtherRolesPlugin.GhostsSeeRoles.Value = !TheOtherRolesPlugin.GhostsSeeRoles.Value, TheOtherRolesPlugin.GhostsSeeRoles.Value),
+ new SelectionBehaviour("Show Role Summary", () => TheOtherRolesPlugin.ShowRoleSummary.Value = !TheOtherRolesPlugin.ShowRoleSummary.Value, TheOtherRolesPlugin.ShowRoleSummary.Value),
+ };
+
+ private static GameObject popUp;
+ private static TextMeshPro titleText;
+
+ private static ToggleButtonBehaviour buttonPrefab;
+ private static Vector3? _origin;
+
+ [HarmonyPostfix]
+ [HarmonyPatch(typeof(MainMenuManager), nameof(MainMenuManager.Start))]
+ public static void MainMenuManager_StartPostfix(MainMenuManager __instance)
+ {
+ // Prefab for the title
+ var tmp = __instance.Announcement.transform.Find("Title_Text").gameObject.GetComponent<TextMeshPro>();
+ tmp.alignment = TextAlignmentOptions.Center;
+ tmp.transform.localPosition += Vector3.left * 0.2f;
+ titleText = Object.Instantiate(tmp);
+ Object.Destroy(titleText.GetComponent<TextTranslatorTMP>());
+ titleText.gameObject.SetActive(false);
+ Object.DontDestroyOnLoad(titleText);
}
- private static ToggleButtonBehaviour createCustomToggle(string text, bool on, Vector3 offset, UnityEngine.Events.UnityAction onClick, OptionsMenuBehaviour __instance) {
- if (__instance.CensorChatButton != null) {
- var button = UnityEngine.Object.Instantiate(__instance.CensorChatButton, __instance.CensorChatButton.transform.parent);
- button.transform.localPosition = (origin ?? Vector3.zero) + offset;
- PassiveButton passiveButton = button.GetComponent<PassiveButton>();
- passiveButton.OnClick = new Button.ButtonClickedEvent();
- passiveButton.OnClick.AddListener(onClick);
- updateToggle(button, text, on);
-
- return button;
+ [HarmonyPostfix]
+ [HarmonyPatch(typeof(OptionsMenuBehaviour), nameof(OptionsMenuBehaviour.Start))]
+ public static void OptionsMenuBehaviour_StartPostfix(OptionsMenuBehaviour __instance)
+ {
+ if (!__instance.CensorChatButton) return;
+
+ if (!popUp)
+ {
+ CreateCustom(__instance);
}
- return null;
- }
- public static void Postfix(OptionsMenuBehaviour __instance) {
- if (__instance.CensorChatButton != null) {
- if (origin == null) origin = __instance.CensorChatButton.transform.localPosition + Vector3.up * 0.075f;
- __instance.CensorChatButton.transform.localPosition = origin.Value + Vector3.left * xOffset;
- __instance.CensorChatButton.transform.localScale = Vector3.one * 0.5f;
+ if (!buttonPrefab)
+ {
+ buttonPrefab = Object.Instantiate(__instance.CensorChatButton);
+ Object.DontDestroyOnLoad(buttonPrefab);
+ buttonPrefab.name = "CensorChatPrefab";
+ buttonPrefab.gameObject.SetActive(false);
}
+
+ SetUpOptions();
+ InitializeMoreButton(__instance);
+ }
- if ((streamerModeButton == null || streamerModeButton.gameObject == null)) {
- streamerModeButton = createCustomToggle("Streamer Mode: ", TheOtherRolesPlugin.StreamerMode.Value, Vector3.zero, (UnityEngine.Events.UnityAction)streamerModeToggle, __instance);
+ private static void CreateCustom(OptionsMenuBehaviour prefab)
+ {
+ popUp = Object.Instantiate(prefab.gameObject);
+ Object.DontDestroyOnLoad(popUp);
+ var transform = popUp.transform;
+ var pos = transform.localPosition;
+ pos.z = -810f;
+ transform.localPosition = pos;
+
+ Object.Destroy(popUp.GetComponent<OptionsMenuBehaviour>());
+ foreach (var gObj in popUp.gameObject.GetAllChilds())
+ {
+ if (gObj.name != "Background" && gObj.name != "CloseButton")
+ Object.Destroy(gObj);
+ }
+
+ popUp.SetActive(false);
+ }
- void streamerModeToggle() {
- TheOtherRolesPlugin.StreamerMode.Value = !TheOtherRolesPlugin.StreamerMode.Value;
- updateToggle(streamerModeButton, "Streamer Mode: ", TheOtherRolesPlugin.StreamerMode.Value);
+ private static void InitializeMoreButton(OptionsMenuBehaviour __instance)
+ {
+ var moreOptions = Object.Instantiate(buttonPrefab, __instance.CensorChatButton.transform.parent);
+ var transform = __instance.CensorChatButton.transform;
+ _origin ??= transform.localPosition;
+
+ transform.localPosition = _origin.Value + Vector3.left * 1.3f;
+ moreOptions.transform.localPosition = _origin.Value + Vector3.right * 1.3f;
+
+ moreOptions.gameObject.SetActive(true);
+ moreOptions.Text.text = "More Options...";
+ var moreOptionsButton = moreOptions.GetComponent<PassiveButton>();
+ moreOptionsButton.OnClick = new ButtonClickedEvent();
+ moreOptionsButton.OnClick.AddListener((Action) (() =>
+ {
+ if (!popUp) return;
+
+ if (__instance.transform.parent && __instance.transform.parent == HudManager.Instance.transform)
+ {
+ popUp.transform.SetParent(HudManager.Instance.transform);
+ popUp.transform.localPosition = new Vector3(0, 0, -800f);
}
- }
+ else
+ {
+ popUp.transform.SetParent(null);
+ Object.DontDestroyOnLoad(popUp);
+ }
+
+ CheckSetTitle();
+ RefreshOpen();
+ }));
+ }
- if ((ghostsSeeTasksButton == null || ghostsSeeTasksButton.gameObject == null)) {
- ghostsSeeTasksButton = createCustomToggle("Ghosts See Remaining Tasks: ", TheOtherRolesPlugin.GhostsSeeTasks.Value, Vector3.right * xOffset, (UnityEngine.Events.UnityAction)ghostsSeeTaskToggle, __instance);
+ private static void RefreshOpen()
+ {
+ popUp.gameObject.SetActive(false);
+ popUp.gameObject.SetActive(true);
+ SetUpOptions();
+ }
+
+ private static void CheckSetTitle()
+ {
+ if (!popUp || popUp.GetComponentInChildren<TextMeshPro>() || !titleText) return;
+
+ var title = Object.Instantiate(titleText, popUp.transform);
+ title.GetComponent<RectTransform>().localPosition = Vector3.up * 2.3f;
+ title.gameObject.SetActive(true);
+ title.text = "More Options...";
+ title.name = "TitleText";
+ }
- void ghostsSeeTaskToggle() {
- TheOtherRolesPlugin.GhostsSeeTasks.Value = !TheOtherRolesPlugin.GhostsSeeTasks.Value;
- MapOptions.ghostsSeeTasks = TheOtherRolesPlugin.GhostsSeeTasks.Value;
- updateToggle(ghostsSeeTasksButton, "Ghosts See Remaining Tasks: ", TheOtherRolesPlugin.GhostsSeeTasks.Value);
- }
- }
+ private static void SetUpOptions()
+ {
+ if (popUp.transform.GetComponentInChildren<ToggleButtonBehaviour>()) return;
+
+ for (var i = 0; i < AllOptions.Length; i++)
+ {
+ var info = AllOptions[i];
+
+ var button = Object.Instantiate(buttonPrefab, popUp.transform);
+ var pos = new Vector3(i % 2 == 0 ? -1.17f : 1.17f, 1.3f - i / 2 * 0.8f, -.5f);
- if ((ghostsSeeRolesButton == null || ghostsSeeRolesButton.gameObject == null)) {
- ghostsSeeRolesButton = createCustomToggle("Ghosts See Roles: ", TheOtherRolesPlugin.GhostsSeeRoles.Value, new Vector2(-xOffset, yOffset), (UnityEngine.Events.UnityAction)ghostsSeeRolesToggle, __instance);
+ var transform = button.transform;
+ transform.localPosition = pos;
- void ghostsSeeRolesToggle() {
- TheOtherRolesPlugin.GhostsSeeRoles.Value = !TheOtherRolesPlugin.GhostsSeeRoles.Value;
- MapOptions.ghostsSeeRoles = TheOtherRolesPlugin.GhostsSeeRoles.Value;
- updateToggle(ghostsSeeRolesButton, "Ghosts See Roles: ", TheOtherRolesPlugin.GhostsSeeRoles.Value);
- }
- }
+ button.onState = info.DefaultValue;
+ button.Background.color = button.onState ? Color.green : Palette.ImpostorRed;
+
+ button.Text.text = info.Title;
+ button.Text.fontSizeMin = button.Text.fontSizeMax = 2.5f;
+ button.Text.font = Object.Instantiate(titleText.font);
+ button.Text.GetComponent<RectTransform>().sizeDelta = new Vector2(2, 2);
- if ((ghostsSeeVotesButton == null || ghostsSeeVotesButton.gameObject == null)) {
- ghostsSeeVotesButton = createCustomToggle("Ghosts See Votes: ", TheOtherRolesPlugin.GhostsSeeVotes.Value, new Vector2(0, yOffset), (UnityEngine.Events.UnityAction)ghostsSeeVotesToggle, __instance);
+ button.name = info.Title.Replace(" ", "") + "Toggle";
+ button.gameObject.SetActive(true);
+
+ var passiveButton = button.GetComponent<PassiveButton>();
+ var colliderButton = button.GetComponent<BoxCollider2D>();
+
+ colliderButton.size = new Vector2(2.2f, .7f);
+
+ passiveButton.OnClick = new ButtonClickedEvent();
+ passiveButton.OnMouseOut = new UnityEvent();
+ passiveButton.OnMouseOver = new UnityEvent();
+
+ passiveButton.OnClick.AddListener((Action) (() =>
+ {
+ button.onState = info.OnClick();
+ button.Background.color = button.onState ? Color.green : Palette.ImpostorRed;
+ }));
+
+ passiveButton.OnMouseOver.AddListener((Action) (() => button.Background.color = new Color32(34 ,139, 34, byte.MaxValue)));
+ passiveButton.OnMouseOut.AddListener((Action) (() => button.Background.color = button.onState ? Color.green : Palette.ImpostorRed));
- void ghostsSeeVotesToggle() {
- TheOtherRolesPlugin.GhostsSeeVotes.Value = !TheOtherRolesPlugin.GhostsSeeVotes.Value;
- MapOptions.ghostsSeeVotes = TheOtherRolesPlugin.GhostsSeeVotes.Value;
- updateToggle(ghostsSeeVotesButton, "Ghosts See Votes: ", TheOtherRolesPlugin.GhostsSeeVotes.Value);
- }
+ foreach (var spr in button.gameObject.GetComponentsInChildren<SpriteRenderer>())
+ spr.size = new Vector2(2.2f, .7f);
}
-
- if ((showRoleSummaryButton == null || showRoleSummaryButton.gameObject == null)) {
- showRoleSummaryButton = createCustomToggle("Role Summary: ", TheOtherRolesPlugin.ShowRoleSummary.Value, new Vector2(xOffset, yOffset), (UnityEngine.Events.UnityAction)showRoleSummaryToggle, __instance);
-
- void showRoleSummaryToggle() {
- TheOtherRolesPlugin.ShowRoleSummary.Value = !TheOtherRolesPlugin.ShowRoleSummary.Value;
- MapOptions.showRoleSummary = TheOtherRolesPlugin.ShowRoleSummary.Value;
- updateToggle(showRoleSummaryButton, "Role Summary: ", TheOtherRolesPlugin.ShowRoleSummary.Value);
- }
+ }
+
+ private static IEnumerable<GameObject> GetAllChilds(this GameObject Go)
+ {
+ for (var i = 0; i< Go.transform.childCount; i++)
+ {
+ yield return Go.transform.GetChild(i).gameObject;
+ }
+ }
+
+ private class SelectionBehaviour
+ {
+ public string Title;
+ public Func<bool> OnClick;
+ public bool DefaultValue;
+
+ public SelectionBehaviour(string title, Func<bool> onClick, bool defaultValue)
+ {
+ Title = title;
+ OnClick = onClick;
+ DefaultValue = defaultValue;
}
}
}
-
+
[HarmonyPatch(typeof(TextBoxTMP), nameof(TextBoxTMP.SetText))]
public static class HiddenTextPatch
{