Files
MiraAPI/MiraAPI/Patches/Options/LobbyViewPanePatches.cs
T
2025-03-23 13:44:40 -04:00

462 lines
17 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using HarmonyLib;
using MiraAPI.GameOptions;
using MiraAPI.Modifiers;
using MiraAPI.PluginLoading;
using MiraAPI.Roles;
using MiraAPI.Utilities;
using MiraAPI.Utilities.Assets;
using Reactor.Localization.Utilities;
using Reactor.Utilities.Extensions;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
using Object = UnityEngine.Object;
namespace MiraAPI.Patches.Options;
[HarmonyPatch(typeof(LobbyViewSettingsPane))]
public static class LobbyViewPanePatches
{
private static int SelectedModIdx { get; set; }
private static MiraPluginInfo? SelectedMod => SelectedModIdx == 0
? null
: MiraPluginManager.Instance.RegisteredPlugins[SelectedModIdx - 1];
private static PassiveButton? ModifiersTabButton { get; set; }
private static StringNames ModifiersTabName { get; } = CustomStringName.CreateAndRegister("ModifiersTab");
[HarmonyPostfix]
[HarmonyPatch(nameof(LobbyViewSettingsPane.Awake))]
public static void AwakePatch(LobbyViewSettingsPane __instance)
{
__instance.gameModeText.transform.localPosition = new Vector3(-2.3f, 2.4f, -2);
__instance.gameModeText.GetComponent<TextTranslatorTMP>().Destroy();
// create modifiers button
ModifiersTabButton = Object.Instantiate(__instance.rolesTabButton, __instance.rolesTabButton.transform.parent);
ModifiersTabButton.buttonText.gameObject.GetComponent<TextTranslatorTMP>().Destroy();
ModifiersTabButton.name = "ModifiersTabButton";
var pos = ModifiersTabButton.transform.localPosition;
pos.x = 2.1f;
ModifiersTabButton.transform.localPosition = pos;
ModifiersTabButton.buttonText.text = "Modifiers";
ModifiersTabButton.OnClick = new Button.ButtonClickedEvent();
ModifiersTabButton.OnClick.AddListener(
(UnityAction)(() =>
{
__instance.ChangeTab(ModifiersTabName);
}));
ModifiersTabButton.gameObject.SetActive(SelectedModIdx!=0);
// Create the next button
var nextButton = Object.Instantiate(__instance.BackButton, __instance.BackButton.transform.parent).gameObject;
nextButton.GetComponent<BoxCollider2D>().size = new Vector2(0.2f, 0.3f);
nextButton.transform.localPosition = new Vector3(-5.4f, 2.4f, -2f);
nextButton.transform.localScale = new Vector3(3, 3, 2);
nextButton.name = "RightArrowButton";
var normal = nextButton.transform.FindChild("Normal").GetComponentInChildren<SpriteRenderer>();
normal.transform.localPosition = new Vector3(0, 0f, 0.3f);
normal.sprite = MiraAssets.NextButton.LoadAsset();
var hover = nextButton.transform.FindChild("Hover").GetComponentInChildren<SpriteRenderer>();
hover.transform.localPosition = new Vector3(0, 0f, 0.3f);
hover.sprite = MiraAssets.NextButtonActive.LoadAsset();
var passiveButton = nextButton.gameObject.GetComponent<PassiveButton>();
passiveButton.OnClick = new Button.ButtonClickedEvent();
passiveButton.OnClick.AddListener(
(UnityAction)(() =>
{
SelectedModIdx += 1;
if (SelectedModIdx > MiraPluginManager.Instance.RegisteredPlugins.Length)
{
SelectedModIdx = 0;
}
Refresh(__instance);
}));
// Create the back button
var backButton = Object.Instantiate(nextButton, __instance.BackButton.transform.parent).gameObject;
backButton.transform.localPosition = new Vector3(-6.3f, 2.4f, -2f);
backButton.name = "LeftArrowButton";
backButton.transform.FindChild("Normal").gameObject.GetComponentInChildren<SpriteRenderer>().flipX
= backButton.transform.FindChild("Hover").gameObject.GetComponentInChildren<SpriteRenderer>().flipX
= true;
var passiveButton2 = backButton.gameObject.GetComponent<PassiveButton>();
passiveButton2.OnClick = new Button.ButtonClickedEvent();
passiveButton2.OnClick.AddListener(
(UnityAction)(() =>
{
SelectedModIdx -= 1;
if (SelectedModIdx < 0)
{
SelectedModIdx = MiraPluginManager.Instance.RegisteredPlugins.Length;
}
Refresh(__instance);
}));
}
private static void Refresh(LobbyViewSettingsPane menu)
{
ModifiersTabButton?.gameObject.SetActive(SelectedModIdx != 0);
menu.gameModeText.text = SelectedMod?.PluginInfo.Metadata.Name ?? "Default";
menu.RefreshTab();
menu.scrollBar.ScrollToTop();
}
[HarmonyPrefix]
[HarmonyPatch(nameof(LobbyViewSettingsPane.SetTab))]
public static bool SetTabPatch(LobbyViewSettingsPane __instance)
{
if (__instance.currentTab != ModifiersTabName || SelectedMod == null)
{
ModifiersTabButton?.SelectButton(false);
return true;
}
__instance.taskTabButton.SelectButton(false);
__instance.rolesTabButton.SelectButton(false);
ModifiersTabButton?.SelectButton(true);
var filteredGroups = SelectedMod.InternalOptionGroups
.Where(x => x.GroupVisible() && (x.ShowInModifiersMenu || x.OptionableType?.IsAssignableTo(typeof(BaseModifier))==true));
DrawOptions(__instance, filteredGroups);
return false;
}
[HarmonyPrefix]
[HarmonyPatch(nameof(LobbyViewSettingsPane.DrawNormalTab))]
public static bool DrawNormalTabPatch(LobbyViewSettingsPane __instance)
{
if (SelectedModIdx == 0 || SelectedMod == null)
{
return true;
}
var filteredGroups = SelectedMod.InternalOptionGroups
.Where(x => x.OptionableType == null && x.GroupVisible.Invoke());
DrawOptions(__instance, filteredGroups);
return false;
}
[HarmonyPrefix]
[HarmonyPatch(nameof(LobbyViewSettingsPane.DrawRolesTab))]
public static bool DrawRolesTabPatch(LobbyViewSettingsPane __instance)
{
if (SelectedModIdx == 0)
{
return true;
}
DrawRolesTab(__instance);
return false;
}
private static void DrawOptions(LobbyViewSettingsPane menu, IEnumerable<AbstractOptionGroup> groups)
{
var num = 1.44f;
foreach (var group in groups)
{
var categoryHeaderMasked = Object.Instantiate(
menu.categoryHeaderOrigin,
menu.settingsContainer,
true);
categoryHeaderMasked.SetHeader(StringNames.Name, 61);
categoryHeaderMasked.Title.text = group.GroupName;
categoryHeaderMasked.transform.localScale = Vector3.one;
categoryHeaderMasked.transform.localPosition = new Vector3(-9.77f, num, -2f);
menu.settingsInfo.Add(categoryHeaderMasked.gameObject);
num -= 1.05f;
var i = 0;
foreach (var option in group.Options)
{
if (!option.Visible.Invoke())
{
continue;
}
var viewSettingsInfoPanel = Object.Instantiate(
menu.infoPanelOrigin,
menu.settingsContainer,
true);
viewSettingsInfoPanel.transform.localScale = Vector3.one;
float num2;
if (i % 2 == 0)
{
num2 = -8.95f;
if (i > 0)
{
num -= 0.85f;
}
}
else
{
num2 = -3f;
}
viewSettingsInfoPanel.transform.localPosition = new Vector3(num2, num, -2f);
var data = option.Data;
if (data.Type == OptionTypes.Checkbox)
{
viewSettingsInfoPanel.SetInfoCheckbox(
data.Title,
61,
Mathf.Approximately(option.GetFloatData(), 1));
}
else
{
viewSettingsInfoPanel.SetInfo(data.Title, data.GetValueString(option.GetFloatData()), 61);
}
menu.settingsInfo.Add(viewSettingsInfoPanel.gameObject);
i++;
}
num -= 0.85f;
}
menu.scrollBar.CalculateAndSetYBounds(menu.settingsInfo.Count + 10, 2f, 6f, 0.85f);
}
private static void DrawRolesTab(LobbyViewSettingsPane instance)
{
if (SelectedMod == null)
{
return;
}
var num = 0.95f;
var num2 = -6.53f;
var categoryHeaderMasked =
Object.Instantiate(instance.categoryHeaderOrigin, instance.settingsContainer, true);
categoryHeaderMasked.SetHeader(StringNames.RoleQuotaLabel, 61);
categoryHeaderMasked.transform.localScale = Vector3.one;
categoryHeaderMasked.transform.localPosition = new Vector3(-9.77f, 1.26f, -2f);
instance.settingsInfo.Add(categoryHeaderMasked.gameObject);
var list = new List<Type>();
var roleGroups = GameSettingMenuPatches.SelectedMod?.InternalRoles.Values.OfType<ICustomRole>()
.ToLookup(x => x.RoleOptionsGroup);
if (roleGroups is null)
{
return;
}
// sort the groups by priority
var sortedRoleGroups = roleGroups
.OrderBy(x => x.Key.Priority)
.ThenBy(x => x.Key.Name);
foreach (var grouping in sortedRoleGroups)
{
if (!grouping.Any())
{
continue;
}
var group = grouping.Key;
var name = group.Name switch
{
"Crewmate" => StringNames.CrewmateRolesHeader,
"Impostor" => StringNames.ImpostorRolesHeader,
_ => CustomStringName.CreateAndRegister(group.Name),
};
var categoryHeaderRoleVariant = Object.Instantiate(instance.categoryHeaderRoleOrigin, instance.settingsContainer, true);
categoryHeaderRoleVariant.SetHeader(name, 61);
if (name is not (StringNames.CrewmateRolesHeader or StringNames.ImpostorRolesHeader))
{
var veryDarkColor = group.Color.DarkenColor(.35f);
categoryHeaderRoleVariant.Title.color = veryDarkColor;
categoryHeaderRoleVariant.Background.color = group.Color;
}
categoryHeaderRoleVariant.transform.localScale = Vector3.one;
categoryHeaderRoleVariant.transform.localPosition = new Vector3(0.09f, num, -2f);
instance.settingsInfo.Add(categoryHeaderRoleVariant.gameObject);
num -= 0.696f;
foreach (var customRole in grouping)
{
var roleBehaviour = customRole as RoleBehaviour;
if (roleBehaviour == null)
{
continue;
}
var chancePerGame =
GameOptionsManager.Instance.CurrentGameOptions.RoleOptions.GetChancePerGame(roleBehaviour.Role);
var numPerGame =
GameOptionsManager.Instance.CurrentGameOptions.RoleOptions.GetNumPerGame(roleBehaviour.Role);
var viewSettingsInfoPanelRoleVariant =
Object.Instantiate(
instance.infoPanelRoleOrigin,
instance.settingsContainer,
true);
viewSettingsInfoPanelRoleVariant.transform.localScale = Vector3.one;
viewSettingsInfoPanelRoleVariant.transform.localPosition = new Vector3(num2, num, -2f);
var advancedRoleOptions = SelectedMod.InternalOptionGroups
.Where(x => x.OptionableType == customRole.GetType())
.SelectMany(x => x.Options)
.ToList();
if (numPerGame > 0 && advancedRoleOptions.Count > 0)
{
list.Add(customRole.GetType());
}
viewSettingsInfoPanelRoleVariant.SetInfo(
roleBehaviour.NiceName,
numPerGame,
chancePerGame,
61,
customRole.RoleColor,
customRole.Configuration.Icon?.LoadAsset() ?? MiraAssets.Empty.LoadAsset(),
true);
viewSettingsInfoPanelRoleVariant.iconSprite.transform.localScale = new Vector3(0.365f, 0.365f, 1f);
viewSettingsInfoPanelRoleVariant.iconSprite.transform.localPosition = new Vector3(0.7144f, -0.028f, -2);
viewSettingsInfoPanelRoleVariant.titleText.color =
viewSettingsInfoPanelRoleVariant.chanceTitle.color =
viewSettingsInfoPanelRoleVariant.chanceBackground.color =
viewSettingsInfoPanelRoleVariant.background.color =
customRole.RoleColor.GetAlternateColor();
instance.settingsInfo.Add(viewSettingsInfoPanelRoleVariant.gameObject);
num -= 0.664f;
}
}
if (list.Count > 0)
{
var categoryHeaderMasked2 =
Object.Instantiate(instance.categoryHeaderOrigin, instance.settingsContainer, true);
categoryHeaderMasked2.SetHeader(StringNames.RoleSettingsLabel, 61);
categoryHeaderMasked2.transform.localScale = Vector3.one;
categoryHeaderMasked2.transform.localPosition = new Vector3(-9.77f, num, -2f);
instance.settingsInfo.Add(categoryHeaderMasked2.gameObject);
num -= 1.7f;
var num3 = 0f;
for (var k = 0; k < list.Count; k++)
{
float num4;
if (k % 2 == 0)
{
num4 = -5.8f;
if (k > 0)
{
num -= num3 + 0.59f;
num3 = 0f;
}
}
else
{
num4 = 0.14999962f;
}
var advancedRoleViewPanel =
Object.Instantiate(instance.advancedRolePanelOrigin, instance.settingsContainer, true);
advancedRoleViewPanel.transform.localScale = Vector3.one;
advancedRoleViewPanel.transform.localPosition = new Vector3(num4, num, -2f);
var num5 = SetUpAdvancedRoleViewPanel(advancedRoleViewPanel, list[k], 0.59f, 61);
if (num5 > num3)
{
num3 = num5;
}
instance.settingsInfo.Add(advancedRoleViewPanel.gameObject);
}
}
instance.scrollBar.SetYBoundsMax(-num);
}
private static float SetUpAdvancedRoleViewPanel(
AdvancedRoleViewPanel viewPanel,
Type roleType,
float spacingY,
int maskLayer)
{
if (SelectedMod == null)
{
return 0;
}
var role = SelectedMod.InternalRoles.Values.FirstOrDefault(x => x.GetType() == roleType);
if (role == null)
{
return 0;
}
if (role is not ICustomRole customRole)
{
return 0;
}
viewPanel.header.SetHeader(
role.StringName,
maskLayer,
role.TeamType == RoleTeamTypes.Crewmate,
customRole.Configuration.Icon != null ? customRole.Configuration.Icon.LoadAsset() : MiraAssets.Empty.LoadAsset());
viewPanel.header.icon.transform.localScale = new Vector3(0.465f, 0.465f, 1f);
viewPanel.divider.material.SetInt(PlayerMaterial.MaskLayer, maskLayer);
var num = viewPanel.yPosStart;
var num2 = 1.08f;
var filteredOptions = SelectedMod.InternalOptionGroups
.Where(x => x.OptionableType == roleType)
.SelectMany(x=>x.Options)
.ToList();
for (var i = 0; i < filteredOptions.Count; i++)
{
var option = filteredOptions[i];
var baseGameSetting = option.Data;
var viewSettingsInfoPanel = Object.Instantiate(viewPanel.infoPanelOrigin, viewPanel.transform, true);
viewSettingsInfoPanel.transform.localScale = Vector3.one;
viewSettingsInfoPanel.transform.localPosition = new Vector3(viewPanel.xPosStart, num, -2f);
var value = option.GetFloatData();
if (baseGameSetting.Type == OptionTypes.Checkbox)
{
viewSettingsInfoPanel.SetInfoCheckbox(baseGameSetting.Title, maskLayer, value > 0f);
}
else
{
viewSettingsInfoPanel.SetInfo(baseGameSetting.Title, baseGameSetting.GetValueString(value), maskLayer);
}
num -= spacingY;
if (i > 0)
{
num2 += 0.8f;
}
}
return num2;
}
}