using System; using System.Collections; using System.Collections.Generic; using System.Linq; using AmongUs.GameOptions; using BepInEx.Unity.IL2CPP.Utils.Collections; using HarmonyLib; using MiraAPI.GameModes; using MiraAPI.GameOptions; using MiraAPI.Networking; using MiraAPI.Roles; using MiraAPI.Utilities; using MiraAPI.Utilities.Assets; using Reactor.Localization.Utilities; using Reactor.Networking.Rpc; using Reactor.Utilities.Extensions; using TMPro; using UnityEngine; using UnityEngine.Events; using static UnityEngine.UI.Button; using Object = UnityEngine.Object; namespace MiraAPI.Patches.Options; [HarmonyPatch(typeof(RolesSettingsMenu))] public static class RoleSettingMenuPatches { private static Dictionary RoleGroupHidden { get; set; } = []; private static float ScrollerNum { get; set; } = 0.522f; private static RoleBehaviour? CurrentRole { get; set; } private static List? CurrentRoleOptions { get; set; } [HarmonyPostfix] [HarmonyPatch(nameof(RolesSettingsMenu.OnEnable))] public static void OpenPatch(RolesSettingsMenu __instance) { HudManager.Instance.PlayerCam.OverrideScreenShakeEnabled = false; } private static IEnumerator CoQuotaTabPatch(RolesSettingsMenu roleMenu) { CurrentRole = null; CurrentRoleOptions = null; roleMenu.QuotaTabSelectables.Clear(); roleMenu.roleChances.Clear(); roleMenu.advancedSettingChildren.Clear(); var maskBg = roleMenu.scrollBar.transform.FindChild("MaskBg"); var hitbox = roleMenu.scrollBar.transform.FindChild("Hitbox"); var dividerImage = roleMenu.transform.FindChild("HeaderButtons/DividerImage"); if (MenuState.Instance.CurrentModIdx == 0) { roleMenu.AllButton.transform.parent.gameObject.SetActive(true); roleMenu.AllButton.gameObject.SetActive(true); roleMenu.scrollBar.transform.localPosition = new Vector3(-1.4957f, 0.657f, -4); maskBg.localPosition = new Vector3(1.5353f, -.5734f, -.1f); maskBg.localScale = new Vector3(6.6811f, 3.3563f, 0.5598f); hitbox.localPosition = new Vector3(0.3297f, -.2333f, 4f); hitbox.localScale = new Vector3(1, 1, 1); dividerImage.gameObject.SetActive(true); } else { roleMenu.AllButton.transform.parent.gameObject.SetActive(false); roleMenu.AllButton.gameObject.SetActive(false); roleMenu.scrollBar.transform.localPosition = new Vector3(-1.4957f, 1.5261f, -4); maskBg.localPosition = new Vector3(1.5353f, -1.0607f, -.1f); maskBg.localScale = new Vector3(6.6811f, 4.1563f, 0.5598f); hitbox.localPosition = new Vector3(0.3297f, -.6333f, 4f); hitbox.localScale = new Vector3(1, 1.2f, 1); dividerImage.gameObject.SetActive(false); } var queuedRefresh = false; if (MenuState.Instance.QueuedRoleMenuRefresh.TryGetValue(MenuState.Instance.CurrentModIdx, out var queued) && queued) { queuedRefresh = true; var roleOptionSettings = roleMenu.scrollBar.Inner.GetComponentsInChildren(true); var headers = roleMenu.scrollBar.Inner.GetComponentsInChildren(true); foreach (var child in roleOptionSettings) { Object.Destroy(child.gameObject); } foreach (var child in headers) { Object.Destroy(child.gameObject); } yield return new WaitForEndOfFrame(); MenuState.Instance.QueuedRoleMenuRefresh[MenuState.Instance.CurrentModIdx] = false; } if (!queuedRefresh && MenuState.Instance.FinishedRoleMenus.TryGetValue(MenuState.Instance.CurrentModIdx, out var finished) && finished) { var roleOptionSettings = roleMenu.scrollBar.Inner.GetComponentsInChildren(true); foreach (var r in roleOptionSettings) { roleMenu.roleChances.Add(r); roleMenu.QuotaTabSelectables.AddRange(new Il2CppSystem.Collections.Generic.IEnumerable(r.ControllerSelectable.Pointer)); } Info($"Already created role options for {MenuState.Instance.CurrentModIdx}"); } else { if (MenuState.Instance.CurrentModIdx == 0) { var num = 0.662f; var list = CustomRoleManager.AllRoles.Where(r => !r.IsCustomRole() && !r.IsRoleBlacklisted() && r.TeamType == RoleTeamTypes.Crewmate && r.Role != RoleTypes.Crewmate && r.Role != RoleTypes.CrewmateGhost).ToList(); var list2 = CustomRoleManager.AllRoles.Where(r => !r.IsCustomRole() && !r.IsRoleBlacklisted() && r.TeamType == RoleTeamTypes.Impostor && r.Role != RoleTypes.Impostor && r.Role != RoleTypes.ImpostorGhost).ToList(); if (roleMenu.roleTabs == null || roleMenu.roleTabs.Count == 0) { var num2 = -1.928f; roleMenu.roleTabs = new(); roleMenu.roleTabs.Add(roleMenu.AllButton); foreach (var t in list) { roleMenu.AddRoleTab(t, ref num2); } foreach (var t in list2) { roleMenu.AddRoleTab(t, ref num2); } } var categoryHeaderEditRole = Object.Instantiate( roleMenu.categoryHeaderEditRoleOrigin, Vector3.zero, Quaternion.identity, roleMenu.RoleChancesSettings.transform); categoryHeaderEditRole.SetHeader(StringNames.CrewmateRolesHeader, 20); categoryHeaderEditRole.transform.localPosition = new Vector3(4.986f, num, -2f); num -= 0.522f; var num3 = 0; foreach (var t in list) { roleMenu.CreateQuotaOption(t, ref num, num3); num3++; } num -= 0.22f; var categoryHeaderEditRole2 = Object.Instantiate( roleMenu.categoryHeaderEditRoleOrigin, Vector3.zero, Quaternion.identity, roleMenu.RoleChancesSettings.transform); categoryHeaderEditRole2.SetHeader(StringNames.ImpostorRolesHeader, 20); categoryHeaderEditRole2.transform.localPosition = new Vector3(4.986f, num, -2f); num -= 0.522f; foreach (var t in list2) { roleMenu.CreateQuotaOption(t, ref num, num3); num3++; } Info($"Created {num3} role options for the default game."); } else { ScrollerNum = 0.522f; var num4 = 0; var roleOptionSettings = roleMenu.scrollBar.Inner.GetComponentsInChildren(false); var headers = roleMenu.scrollBar.Inner.GetComponentsInChildren(false); foreach (var child in roleOptionSettings) { Object.Destroy(child.gameObject); } foreach (var child in headers) { Object.Destroy(child.gameObject); } yield return new WaitForEndOfFrame(); var roleGroups = MenuState.Instance.CurrentMod.InternalRoles.Values.OfType() .ToLookup(x => x.RoleOptionsGroup); if (roleGroups.Count == 0) { Error("No role groups found for the selected mod."); } else { // sort the groups by priority var sortedRoleGroups = roleGroups .OrderBy(x => x.Key.Priority) .ThenBy(x => x.Key.Name); var quotaThing = roleMenu.categoryHeaderEditRoleOrigin.transform.FindChild("QuotaHeader"); var usingNewQuota = false; var template = roleMenu.transform.parent.parent.GetComponent().GameSettingsTab .categoryHeaderOrigin; foreach (var grouping in sortedRoleGroups) { if (!grouping.Any() || grouping.All(x=> x.Configuration.HideSettings || !x.VisibleInSettings() || !x.Configuration.AssociatedGameMode.IsInstanceOfType(CustomGameModeManager.ActiveMode))) { continue; } var group = grouping.Key; RoleGroupHidden.TryAdd(group, false); var name = group.Name switch { "Crewmate" => StringNames.CrewmateRolesHeader, "Impostor" => StringNames.ImpostorRolesHeader, _ => CustomStringName.CreateAndRegister(group.Name), }; var categoryHeaderMasked = Object.Instantiate( template, Vector3.zero, Quaternion.identity, roleMenu.RoleChancesSettings.transform); categoryHeaderMasked.SetHeader(name, 20); var quotaInst = Object.Instantiate(quotaThing, categoryHeaderMasked.transform); quotaInst.transform.localScale = new Vector3(1.3f, 1.3f, 1.3f); quotaInst.transform.localPosition = new Vector3(0.7f, -0.82f, 0); var chanceText = quotaInst.transform.FindChild("Chance Text"); chanceText.transform.localPosition = new Vector3(4.3f, 0.0993f, 0); var countText = quotaInst.transform.FindChild("# Text"); countText.transform.localPosition = new Vector3(1.9f, 0.0993f, 0f); if (!usingNewQuota) { var blankLabel = quotaInst.transform.FindChild("BlankLabel").gameObject; var chanceLabel = quotaInst.transform.FindChild("Chance Label").gameObject; var countLabel = quotaInst.transform.FindChild("# Label").gameObject; blankLabel.Destroy(); chanceLabel.Destroy(); countLabel.Destroy(); usingNewQuota = true; quotaThing = quotaInst; } 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); switch (name) { case StringNames.CrewmateRolesHeader: categoryHeaderMasked.Title.color = Palette.CrewmateRoleHeaderTextBlue; categoryHeaderMasked.Background.color = Palette.CrewmateRoleHeaderBlue; break; case StringNames.ImpostorRolesHeader: categoryHeaderMasked.Title.color = Palette.ImpostorRoleHeaderTextRed; categoryHeaderMasked.Background.color = Palette.ImpostorRoleHeaderRed; break; default: categoryHeaderMasked.Title.color = group.Color.Equals(MiraApiPlugin.DefaultHeaderColor) ? Color.white : group.Color.FindAlternateColor(); categoryHeaderMasked.Divider.color = group.Color; categoryHeaderMasked.Background.color = group.Color; break; } categoryHeaderMasked.Title.fontStyle = roleMenu.categoryHeaderEditRoleOrigin.Title.fontStyle; categoryHeaderMasked.Title.font = roleMenu.categoryHeaderEditRoleOrigin.Title.font; categoryHeaderMasked.Title.fontMaterial = roleMenu.categoryHeaderEditRoleOrigin.Title.fontMaterial; categoryHeaderMasked.Divider.color = categoryHeaderMasked.Background.color; categoryHeaderMasked.Background.transform.localPosition = new Vector3(0.55f, -0.1833f, 0); categoryHeaderMasked.Background.size = new Vector2( categoryHeaderMasked.Background.size.x + 1.5f, categoryHeaderMasked.Background.size.y); categoryHeaderMasked.transform.localScale = Vector3.one * 0.63f; categoryHeaderMasked.transform.localPosition = new Vector3(-0.44f, ScrollerNum, -2f); categoryHeaderMasked.gameObject.SetActive(true); quotaInst.gameObject.SetActive(!RoleGroupHidden[group]); var label = RoleGroupHidden[group] ? "(Click to open)" : "(Click to close)"; var newText = Object.Instantiate(categoryHeaderMasked.Title, categoryHeaderMasked.transform); newText.text = $"{label}"; newText.transform.localPosition = new Vector3(2.6249f, -0.165f, 0f); newText.gameObject.GetComponent().Destroy(); ScrollerNum -= 0.422f; if (!RoleGroupHidden[group]) { yield return grouping.CoLoopWithBudget(role => { if (role is not RoleBehaviour roleBehaviour) { return; } var option = CreateQuotaOption(roleMenu, roleBehaviour, num4); if (option is not null) { num4++; } }); } 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 = roleMenu.BackButton.GetComponent().ClickSound; headerBtn.OnMouseOver = new UnityEvent(); headerBtn.OnMouseOut = new UnityEvent(); headerBtn.OnClick.AddListener( (UnityAction)(() => { if (RoleGroupHidden.TryGetValue(group, out var groupHidden)) { RoleGroupHidden[group] = !groupHidden; } MenuState.Instance.QueuedRoleMenuRefresh[MenuState.Instance.CurrentModIdx] = false; MenuState.Instance.FinishedRoleMenus[MenuState.Instance.CurrentModIdx] = false; foreach (var child in roleMenu.RoleChancesSettings.transform) { var transform = child.Cast(); Object.Destroy(transform.gameObject); } roleMenu.OpenChancesTab(); })); headerBtn.SetButtonEnableState(true); if (RoleGroupHidden.TryGetValue(group, out var value) && !value) { ScrollerNum -= 0.4f; } } } } MenuState.Instance.QueuedRoleMenuRefresh[MenuState.Instance.CurrentModIdx] = false; MenuState.Instance.FinishedRoleMenus[MenuState.Instance.CurrentModIdx] = true; } roleMenu.SetScrollBounds(); _quotaTabCoroutine = null; } private static Coroutine? _quotaTabCoroutine; [HarmonyPrefix] [HarmonyPatch(nameof(RolesSettingsMenu.OpenChancesTab))] public static bool OpenChancesTabPatch(RolesSettingsMenu __instance, bool controllerSelected) { __instance.selectedRoleTab = 0; __instance.RoleChancesSettings.SetActive(true); __instance.AdvancedRolesSettings.SetActive(false); __instance.ControllerSelectable.Clear(); if (_quotaTabCoroutine != null) { GameSettingMenu.Instance.StopCoroutine(_quotaTabCoroutine); } __instance.QuotaTabSelectables ??= new(); __instance.roleChances ??= new(); __instance.advancedSettingChildren ??= new(); _quotaTabCoroutine = GameSettingMenu.Instance.StartCoroutine(CoOpenChancesTab().WrapToIl2Cpp()); return false; IEnumerator CoOpenChancesTab() { yield return CoQuotaTabPatch(__instance); if (controllerSelected) { __instance.ControllerSelectable.AddRange( new Il2CppSystem.Collections.Generic.IEnumerable( __instance.QuotaTabSelectables.Pointer)); } if (controllerSelected) { ControllerManager.Instance.CurrentUiState.SelectableUiElements = __instance.ControllerSelectable; if (__instance.ControllerSelectable.Count != 0) { ControllerManager.Instance.SetDefaultSelection(__instance.ControllerSelectable[0]); } } var passiveButton = __instance.currentTabButton; if (passiveButton) { passiveButton.SelectButton(false); } __instance.AllButton.SelectButton(true); __instance.currentTabButton = __instance.AllButton; } } private static void SetScrollBounds(this RolesSettingsMenu menu, bool isRolesConfig = false) { var scroller = menu.scrollBar; if (MenuState.Instance.CurrentModIdx == 0) { scroller.CalculateAndSetYBounds(menu.roleChances.Count + 3, 1f, 6f, 0.43f); return; } scroller.Inner = isRolesConfig ? menu.AdvancedRolesSettings.transform : menu.RoleChancesSettings.transform; scroller.SetYBoundsMax(-ScrollerNum - 2); } [HarmonyPrefix] // TODO: turn this into a fixed update [HarmonyPatch(nameof(RolesSettingsMenu.Update))] public static bool UpdatePatch(RolesSettingsMenu __instance) { if (MenuState.Instance.CurrentModIdx == 0) return true; if (CurrentRole == null || CurrentRoleOptions == null) return false; var hasImage = CurrentRole.RoleScreenshot != null; var num = hasImage ? -0.872f : -1; foreach (var opt in CurrentRoleOptions) { if (opt.OptionBehaviour == null) continue; if (!opt.Visible.Invoke()) { opt.OptionBehaviour.gameObject.SetActive(false); continue; } opt.OptionBehaviour.transform.localPosition = new Vector3(hasImage ? 2.17f : 1.1f, num, -2f); opt.OptionBehaviour.gameObject.SetActive(true); num += -0.45f; } __instance.scrollBar.SetYBoundsMax(-num - 3); return false; } private static void ValueChanged(OptionBehaviour obj) { var roleSetting = obj.Cast(); var role = roleSetting.Role as ICustomRole; if (role is null or { Configuration.HideSettings: true }) { return; } try { if (role.Configuration.MaxRoleCount != 0) { role.SetCount(roleSetting.RoleMaxCount); } if (role.Configuration.CanModifyChance) { role.SetChance(roleSetting.RoleChance); if (roleSetting.RoleChance == 0 && role.Configuration.MaxRoleCount != 0) { role.SetCount(0); } } } catch (Exception e) { Warning(e); } roleSetting.UpdateValuesAndText(GameOptionsManager.Instance.CurrentGameOptions.RoleOptions); HudManager.Instance.Notifier.AddRoleSettingsChangeMessage( roleSetting.Role.StringName, roleSetting.RoleMaxCount, roleSetting.RoleChance, roleSetting.Role.TeamType); if (AmongUsClient.Instance.AmHost) { Rpc.Instance.Send(PlayerControl.LocalPlayer, [role.GetNetData()], true); } GameOptionsManager.Instance.GameHostOptions = GameOptionsManager.Instance.CurrentGameOptions; } private static void CreateAdvancedSettings(RolesSettingsMenu __instance, RoleBehaviour role) { foreach (var optBehaviour in __instance.AdvancedRolesSettings.GetComponentsInChildren()) { optBehaviour.gameObject.Destroy(); } CurrentRole = role; __instance.advancedSettingChildren.Clear(); // TODO: create sub groups under the role settings. var filteredOptions = MenuState.Instance.CurrentMod.InternalOptionGroups .Where(x => x.GroupVisible() && x.OptionableType == role.GetType()) .SelectMany(x => x.Options) .ToList(); foreach (var option in filteredOptions) { var newOpt = option.CreateOption( __instance.checkboxOrigin, __instance.numberOptionOrigin, __instance.stringOptionOrigin, GameSettingMenu.Instance.GameSettingsTab.playerOptionOrigin, __instance.AdvancedRolesSettings.transform); newOpt.SetClickMask(__instance.ButtonClickMask); SpriteRenderer[] componentsInChildren = newOpt.GetComponentsInChildren(true); foreach (var renderer in componentsInChildren) { renderer.material.SetInt(PlayerMaterial.MaskLayer, 20); } foreach (var fontMat in newOpt.GetComponentsInChildren(true).Select(x => x.fontMaterial)) { fontMat.SetFloat(ShaderID.StencilComp, 3f); fontMat.SetFloat(ShaderID.Stencil, 20); } newOpt.LabelBackground.enabled = false; __instance.advancedSettingChildren.Add(newOpt); newOpt.gameObject.SetActive(false); newOpt.Initialize(); } CurrentRoleOptions = filteredOptions; } [HarmonyPrefix] [HarmonyPatch(nameof(RolesSettingsMenu.ChangeTab))] public static void ChangeTabPatch(RolesSettingsMenu __instance) { var categoryHeaderMasked = __instance.AdvancedRolesSettings.transform.Find("CategoryHeaderMasked").GetComponent(); categoryHeaderMasked.Title.text = TranslationController.Instance.GetString(StringNames.RoleSettingsLabel); var labelBg = __instance.AdvancedRolesSettings.transform.FindChild("InfoLabelBackground"); var imgBg = __instance.AdvancedRolesSettings.transform.FindChild("Imagebackground"); imgBg.gameObject.SetActive(true); __instance.roleScreenshot.gameObject.SetActive(true); __instance.roleDescriptionText.transform.parent.localPosition = new Vector3(2.5176f, -0.2731f, -1f); __instance.roleDescriptionText.transform.parent.localScale = new Vector3(0.0675f, 0.1494f, 0.5687f); labelBg.transform.localPosition = new Vector3(1.082f, 0.1054f, -2.5f); __instance.roleScreenshot.drawMode = SpriteDrawMode.Simple; foreach (var optBehaviour in __instance.AdvancedRolesSettings.GetComponentsInChildren()) { optBehaviour.gameObject.Destroy(); } } private static void ChangeTab(RoleBehaviour role, RolesSettingsMenu __instance) { if (role is not ICustomRole customRole) { Error($"Role {role.NiceName} is not a custom role."); return; } __instance.roleDescriptionText.text = customRole.RoleLongDescription; __instance.roleTitleText.text = role.GetRoleName(); var imgBg = __instance.AdvancedRolesSettings.transform.FindChild("Imagebackground"); var labelBg = __instance.AdvancedRolesSettings.transform.FindChild("InfoLabelBackground"); if (role.RoleScreenshot == null) { imgBg.gameObject.SetActive(false); __instance.roleScreenshot.gameObject.SetActive(false); __instance.roleDescriptionText.transform.parent.localPosition = new Vector3(1.5f, -0.2731f, -1); __instance.roleDescriptionText.transform.parent.localScale = new Vector3(0.09f, 0.2f, 0.5687f); labelBg.localPosition = new Vector3(-0.7f, 0.1054f, -2.5f); } else { imgBg.gameObject.SetActive(true); __instance.roleScreenshot.gameObject.SetActive(true); __instance.roleDescriptionText.transform.parent.localPosition = new Vector3(2.5176f, -0.2731f, -1f); __instance.roleDescriptionText.transform.parent.localScale = new Vector3(0.0675f, 0.1494f, 0.5687f); labelBg.transform.localPosition = new Vector3(1.082f, 0.1054f, -2.5f); __instance.roleScreenshot.sprite = role.RoleScreenshot; __instance.roleScreenshot.drawMode = SpriteDrawMode.Simple; } __instance.roleHeaderSprite.color = customRole.OptionsMenuColor; __instance.roleHeaderText.color = customRole.OptionsMenuColor.FindAlternateColor(); var categoryHeaderMasked = __instance.AdvancedRolesSettings.transform.Find("CategoryHeaderMasked").GetComponent(); if (categoryHeaderMasked.Title.gameObject.TryGetComponent(out var comp)) { comp.Destroy(); } categoryHeaderMasked.Title.text = "RETURN TO ROLE SETTINGS"; if (!categoryHeaderMasked.gameObject.TryGetComponent(out _)) { 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 = __instance.BackButton.GetComponent().ClickSound; headerBtn.OnMouseOver = new UnityEvent(); headerBtn.OnMouseOut = new UnityEvent(); headerBtn.OnClick.AddListener( (UnityAction)(() => { GameSettingMenu.Instance.StartCoroutine(CoReturnToRoleSettings().WrapToIl2Cpp()); })); headerBtn.SetButtonEnableState(true); IEnumerator CoReturnToRoleSettings() { // set gameobjects __instance.RoleChancesSettings.SetActive(true); __instance.AdvancedRolesSettings.SetActive(false); // wait a frame yield return null; // re-enable page yield return CoQuotaTabPatch(__instance); // set controller selected button __instance.AllButton.SelectButton(true); __instance.currentTabButton = __instance.AllButton; } } var bg = __instance.AdvancedRolesSettings.transform.Find("Background"); bg.localPosition = new Vector3(1.4041f, -7.08f, 0); bg.GetComponent().size = new Vector2(89.4628f, 100); CreateAdvancedSettings(__instance, role); foreach (var optionBehaviour in __instance.advancedSettingChildren) { if (optionBehaviour.IsCustom()) { continue; } optionBehaviour.OnValueChanged = new Action(__instance.ValueChanged); if (AmongUsClient.Instance && !AmongUsClient.Instance.AmHost) { optionBehaviour.SetAsPlayer(); } } __instance.RoleChancesSettings.SetActive(false); __instance.AdvancedRolesSettings.SetActive(true); __instance.SetScrollBounds(true); __instance.scrollBar.ScrollToTop(); __instance.RefreshChildren(); } private static RoleOptionSetting? CreateQuotaOption(RolesSettingsMenu __instance, RoleBehaviour role, int index) { if (role is not ICustomRole customRole) { Error($"Role {role.NiceName} is not a custom role."); return null; } if (customRole.Configuration.HideSettings) { return null; } var roleOptionSetting = Object.Instantiate( __instance.roleOptionSettingOrigin, Vector3.zero, Quaternion.identity, __instance.RoleChancesSettings.transform); roleOptionSetting.transform.localPosition = new Vector3(-0.1f, ScrollerNum, -2f); roleOptionSetting.SetRole(GameOptionsManager.Instance.CurrentGameOptions.RoleOptions, role, 20); roleOptionSetting.titleText.text = role.GetRoleName(); roleOptionSetting.labelSprite.color = customRole.OptionsMenuColor; roleOptionSetting.OnValueChanged = new Action(ValueChanged); roleOptionSetting.SetClickMask(__instance.ButtonClickMask); roleOptionSetting.ChanceMinusBtn.SetInteractable(true); roleOptionSetting.ChancePlusBtn.SetInteractable(true); roleOptionSetting.CountMinusBtn.SetInteractable(true); roleOptionSetting.CountPlusBtn.SetInteractable(true); __instance.roleChances.Add(roleOptionSetting); roleOptionSetting.titleText.transform.localPosition = new Vector3(-0.25f, -0.2923f, 0f); roleOptionSetting.titleText.color = customRole.OptionsMenuColor.FindAlternateColor(); roleOptionSetting.titleText.horizontalAlignment = HorizontalAlignmentOptions.Left; if (customRole.Configuration.Icon != null) { var roleIcon = new GameObject("RoleIcon"); roleIcon.transform.parent = roleOptionSetting.transform; roleIcon.transform.localScale = new(.25f, .25f, 1); roleIcon.layer = LayerMask.NameToLayer("UI"); roleIcon.transform.localPosition = new Vector3(-1.3f, -0.3f, -2f); var rend = roleIcon.AddComponent(); rend.sprite = customRole.Configuration.Icon.LoadAsset(); rend.maskInteraction = SpriteMaskInteraction.VisibleInsideMask; } if (MenuState.Instance.CurrentMod.InternalOptionGroups .Exists(x => x.GroupVisible() && x.OptionableType == role.GetType() && x.Options.Any(y => y.Visible()))) { var newButton = Object.Instantiate(roleOptionSetting.buttons[0], roleOptionSetting.transform); newButton.name = "ConfigButton"; newButton.transform.localPosition = new Vector3(0.4473f, -0.3f, -2f); newButton.transform.FindChild("Text_TMP").gameObject.Destroy(); newButton.activeSprites.Destroy(); var btnRend = newButton.transform.FindChild("ButtonSprite").GetComponent(); btnRend.sprite = MiraAssets.Cog.LoadAsset(); var passiveButton = newButton.GetComponent(); passiveButton.OnClick = new ButtonClickedEvent(); passiveButton.interactableColor = btnRend.color = customRole.OptionsMenuColor.FindAlternateColor(); passiveButton.interactableHoveredColor = Color.white; passiveButton.OnClick.AddListener((UnityAction)(() => { ChangeTab(role, __instance); })); } if (customRole.Configuration is { MaxRoleCount: 0 }) { roleOptionSetting.CountMinusBtn.gameObject.SetActive(false); roleOptionSetting.CountPlusBtn.gameObject.SetActive(false); } if (!customRole.Configuration.CanModifyChance) { roleOptionSetting.ChanceMinusBtn.gameObject.SetActive(false); roleOptionSetting.ChancePlusBtn.gameObject.SetActive(false); } if (index < MenuState.Instance.CurrentMod.InternalRoles.Count - 1) { ScrollerNum -= 0.43f; } return roleOptionSetting; } }