Merge remote-tracking branch 'origin/dev' into dev

This commit is contained in:
XtraCube committed 2025-06-28 22:57:09 -04:00
commit 00377c7926
21 files changed
+422 -30

No files matched your search

+4 -1
View File
@@ -6,7 +6,10 @@ namespace MiraAPI.Example;
[RegisterCustomColors]
public static class ExampleColors
{
public static CustomColor Cerulean { get; } = new("Cerulean", new Color(0.0f, 0.48f, 0.65f));
public static CustomColor Cerulean { get; } = new("Cerulean", new Color(0.0f, 0.48f, 0.65f))
{
ColorBrightness = CustomColorBrightness.Lighter,
};
public static CustomColor Rose { get; } = new("Rose", new Color(0.98f, 0.26f, 0.62f));
@@ -10,6 +10,8 @@ public class ExampleOptions2 : AbstractOptionGroup
public override uint GroupPriority => 0; // This group will be displayed first. The default value is uint.MaxValue.
public ModdedPlayerOption PlayerOption2 { get; } = new("YOU MUST CHOSE A PLAYER", false);
public ModdedPlayerOption PlayerOption { get; } = new("Eh whatever");
public ModdedToggleOption ToggleOpt1 { get; } = new("Toggle Option 1", false);
public ModdedToggleOption ToggleOpt2 { get; } = new("Toggle Option 2", false)
+27 -6
View File
@@ -13,19 +13,24 @@ namespace MiraAPI.Colors;
public sealed class CustomColor(StringNames name, Color32 mainColor, Color32 shadowColor)
{
/// <summary>
/// Gets the main color.
/// Gets or sets the main color.
/// </summary>
public Color32 MainColor { get; } = mainColor;
public Color32 MainColor { get; set; } = mainColor;
/// <summary>
/// Gets the shadow color.
/// Gets or sets the shadow color.
/// </summary>
public Color32 ShadowColor { get; } = shadowColor;
public Color32 ShadowColor { get; set; } = shadowColor;
/// <summary>
/// Gets the name of the color.
/// Gets or sets the name of the color.
/// </summary>
public StringNames Name { get; } = name;
public StringNames Name { get; set; } = name;
/// <summary>
/// Gets or sets whether the color is lighter or darker. Can be used to help with colorblind stuff.
/// </summary>
public CustomColorBrightness ColorBrightness { get; set; } = CustomColorBrightness.Darker;
/// <inheritdoc />
public CustomColor(StringNames name, Color32 mainColor) : this(name, mainColor, mainColor.GetShadowColor(60))
@@ -42,3 +47,19 @@ public sealed class CustomColor(StringNames name, Color32 mainColor, Color32 sha
{
}
}
/// <summary>
/// Can be used to help with colorblind stuff.
/// </summary>
public enum CustomColorBrightness
{
/// <summary>
/// A lighter color.
/// </summary>
Lighter,
/// <summary>
/// A darker color.
/// </summary>
Darker,
}
+2 -1
View File
@@ -62,9 +62,10 @@ public interface IModdedOption
/// <param name="toggleOpt">The ToggleOption template.</param>
/// <param name="numberOpt">The NumberOption template.</param>
/// <param name="stringOpt">The StringOption template.</param>
/// <param name="playerOpt">The PlayerOption template.</param>
/// <param name="container">>The Transform container for the option.</param>
/// <returns>>The created OptionBehaviour object.</returns>
OptionBehaviour CreateOption(ToggleOption toggleOpt, NumberOption numberOpt, StringOption stringOpt, Transform container);
OptionBehaviour CreateOption(ToggleOption toggleOpt, NumberOption numberOpt, StringOption stringOpt, PlayerOption playerOpt, Transform container);
/// <summary>
/// Gets the value as a float.
@@ -6,6 +6,7 @@ using System.Reflection;
using BepInEx.Configuration;
using HarmonyLib;
using MiraAPI.GameOptions.Attributes;
using MiraAPI.GameOptions.OptionTypes;
using MiraAPI.Networking;
using MiraAPI.PluginLoading;
using MiraAPI.Utilities;
@@ -22,6 +23,7 @@ public static class ModdedOptionsManager
private static readonly Dictionary<PropertyInfo, ModdedOptionAttribute> OptionAttributes = [];
private static readonly Dictionary<Type, AbstractOptionGroup> TypeToGroup = [];
internal static readonly Dictionary<OptionBehaviour, ModdedPlayerOption> CreatedPlayerOptions = [];
internal static readonly Dictionary<uint, IModdedOption> ModdedOptions = [];
internal static readonly List<AbstractOptionGroup> Groups = [];
@@ -44,7 +44,7 @@ public class ModdedEnumOption : ModdedOption<int>
}
/// <inheritdoc />
public override OptionBehaviour CreateOption(ToggleOption toggleOpt, NumberOption numberOpt, StringOption stringOpt, Transform container)
public override OptionBehaviour CreateOption(ToggleOption toggleOpt, NumberOption numberOpt, StringOption stringOpt, PlayerOption playerOpt, Transform container)
{
var stringOption = Object.Instantiate(stringOpt, container);
@@ -135,7 +135,7 @@ public class ModdedEnumOption<T> : ModdedOption<T> where T : Enum
}
/// <inheritdoc />
public override OptionBehaviour CreateOption(ToggleOption toggleOpt, NumberOption numberOpt, StringOption stringOpt, Transform container)
public override OptionBehaviour CreateOption(ToggleOption toggleOpt, NumberOption numberOpt, StringOption stringOpt, PlayerOption playerOpt, Transform container)
{
var stringOption = Object.Instantiate(stringOpt, container);
@@ -93,6 +93,7 @@ public class ModdedNumberOption : ModdedOption<float>
ToggleOption toggleOpt,
NumberOption numberOpt,
StringOption stringOpt,
PlayerOption playerOpt,
Transform container)
{
var numberOption = Object.Instantiate(numberOpt, Vector3.zero, Quaternion.identity, container);
@@ -37,6 +37,7 @@ public abstract class ModdedOption<T> : IModdedOption
{
if (_parentMod != null || value == null) return;
_parentMod = value;
var entry = _parentMod.GetConfigFile().Bind(ConfigDefinition, DefaultValue);
Value = entry.Value;
}
@@ -177,6 +178,7 @@ public abstract class ModdedOption<T> : IModdedOption
ToggleOption toggleOpt,
NumberOption numberOpt,
StringOption stringOpt,
PlayerOption playerOpt,
Transform container);
/// <summary>
@@ -0,0 +1,134 @@
using System;
using System.Linq;
using Il2CppSystem.Collections.Generic;
using MiraAPI.Networking;
using MiraAPI.Utilities;
using UnityEngine;
using Object = UnityEngine.Object;
namespace MiraAPI.GameOptions.OptionTypes;
/// <summary>
/// An option for selecting an ingame player. It returns an index of the values list, NOT A PLAYER ID. To get a player out of this, index the Values list.
/// </summary>
public class ModdedPlayerOption : ModdedOption<int>
{
/// <summary>
/// Gets or sets the included players.
/// </summary>
public List<NetworkedPlayerInfo> Values { get; set; }
/// <summary>
/// Gets or sets a filter for the players included in the option.
/// </summary>
public Func<NetworkedPlayerInfo, bool>? PlayerFilter { get; set; }
/// <summary>
/// Gets or sets a value indicating whether the option includes a "None" option. If None is selected, value will return -1.
/// </summary>
public bool AllowNone { get; set; }
/// <summary>
/// Initializes a new instance of the <see cref="ModdedPlayerOption"/> class.
/// </summary>
/// <param name="title">The title of the option.</param>
/// <param name="allowNone">Whether the option includes a none option. If None is selected, value will return -1.</param>
public ModdedPlayerOption(string title, bool allowNone = true) : base(title, allowNone ? -1 : 0, false)
{
Data = ScriptableObject.CreateInstance<PlayerSelectionGameSetting>();
var data = (PlayerSelectionGameSetting)Data;
data.Title = StringName;
data.Type = global::OptionTypes.Player;
Values = new List<NetworkedPlayerInfo>();
AllowNone = allowNone;
Value = DefaultValue;
}
/// <inheritdoc />
public override OptionBehaviour CreateOption(ToggleOption toggleOpt, NumberOption numberOpt, StringOption stringOpt,
PlayerOption playerOpt, Transform container)
{
var playerOption = Object.Instantiate(playerOpt, container);
var filteredList = GetFilteredPlayers();
Values = filteredList.ToIl2CppList();
playerOption.SetUpFromData(Data, 20);
playerOption.OnValueChanged = (Il2CppSystem.Action<OptionBehaviour>)ValueChanged;
playerOption.Title = StringName;
playerOption.TitleText.text = TranslationController.Instance.GetString(StringName);
playerOption.Values = Values;
playerOption.Value = Value;
playerOption.playerIndex = filteredList.FindIndex(p => p.PlayerId == Value);
OptionBehaviour = playerOption;
ModdedOptionsManager.CreatedPlayerOptions.TryAdd(playerOption, this);
playerOption.SetValueText();
playerOption.AdjustButtonsActiveState();
return playerOption;
}
/// <summary>
/// Returns a player ran through the filter.
/// </summary>
/// <returns>A list of filtered players.</returns>
public System.Collections.Generic.List<NetworkedPlayerInfo> GetFilteredPlayers()
{
return GameData.Instance.AllPlayers.ToArray()
.Where(x => PlayerFilter?.Invoke(x) ?? true)
.ToList();
}
/// <summary>
/// Returns a player from the value. If AllowNone is enabled and none is enabled this will return null.
/// </summary>
/// <returns>A player or null if chosen none.</returns>
public NetworkedPlayerInfo? GetPlayerValue()
{
return Value < 0 ? null : Values[Value];
}
/// <inheritdoc />
public override float GetFloatData()
{
return Value;
}
/// <inheritdoc />
public override NetData GetNetData()
{
return new NetData(Id, BitConverter.GetBytes(Value));
}
/// <inheritdoc />
public override void HandleNetData(byte[] data)
{
SetValue(BitConverter.ToInt32(data));
}
/// <inheritdoc />
public override int GetValueFromOptionBehaviour(OptionBehaviour optionBehaviour)
{
return optionBehaviour.GetInt();
}
/// <inheritdoc />
protected override void OnValueChanged(int newValue)
{
HudManager.Instance.Notifier.AddSettingsChangeMessage(StringName, Data.GetValueString(newValue), false);
if (!OptionBehaviour)
{
return;
}
if (OptionBehaviour is PlayerOption opt)
{
opt.Value = newValue;
}
}
}
@@ -26,7 +26,7 @@ public class ModdedToggleOption : ModdedOption<bool>
}
/// <inheritdoc />
public override OptionBehaviour CreateOption(ToggleOption toggleOpt, NumberOption numberOpt, StringOption stringOpt, Transform container)
public override OptionBehaviour CreateOption(ToggleOption toggleOpt, NumberOption numberOpt, StringOption stringOpt, PlayerOption playerOpt, Transform container)
{
var toggleOption = Object.Instantiate(toggleOpt, Vector3.zero, Quaternion.identity, container);
+34
View File
@@ -0,0 +1,34 @@
using HarmonyLib;
using UnityEngine;
namespace MiraAPI.Patches;
/// <summary>
/// Allows players to paste text into chat.
/// Source: https://github.com/CallOfCreator/NewMod/blob/main/NewMod/Patches/ClipboardPatch.cs
/// </summary>
[HarmonyPatch(typeof(ChatController), nameof(ChatController.Update))]
public static class ChatControllerPatch
{
public static void Prefix(ChatController __instance)
{
if (!HudManager.Instance.Chat.IsOpenOrOpening) return;
var ctrlPressed = Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl);
if (!ctrlPressed || !Input.GetKeyDown(KeyCode.V)) return;
var clipboard = GUIUtility.systemCopyBuffer;
if (string.IsNullOrWhiteSpace(clipboard)) return;
clipboard = clipboard.Replace("<", string.Empty)
.Replace(">", string.Empty)
.Replace("\r", string.Empty);
if (!Input.GetKey(KeyCode.LeftShift) && !Input.GetKey(KeyCode.RightShift))
clipboard = clipboard.Replace("\n", string.Empty);
__instance.freeChatField.textArea.SetText(__instance.freeChatField.textArea.text + clipboard);
}
}
+1 -1
View File
@@ -114,7 +114,7 @@ public static class HatsTabPatches
yield return null;
}
__instance.scroller.ContentYBounds.max = -(__instance.YStart - (hatIndex + 1) / __instance.NumPerRow * __instance.YOffset) - 3f;
__instance.SetScrollerBounds();
yield return new WaitForSeconds(0.01f);
}
__instance.currentHatIsEquipped = true;
+1 -1
View File
@@ -91,7 +91,7 @@ public static class NameplatesTabPatches
hatIndex += 1;
}
__instance.scroller.ContentYBounds.max = -(__instance.YStart - (hatIndex + 1) / __instance.NumPerRow * __instance.YOffset) - 3f;
__instance.SetScrollerBounds();
__instance.currentNameplateIsEquipped = true;
}
+1 -1
View File
@@ -94,7 +94,7 @@ public static class SkinsTabPatches
hatIndex += 1;
}
__instance.scroller.ContentYBounds.max = -(__instance.YStart - (hatIndex + 1) / __instance.NumPerRow * __instance.YOffset) - 3f;
__instance.SetScrollerBounds();
__instance.currentSkinIsEquipped = true;
}
+1 -1
View File
@@ -90,7 +90,7 @@ public static class VisorsTabPatches
hatIndex += 1;
}
__instance.scroller.ContentYBounds.max = -(__instance.YStart - (hatIndex + 1) / __instance.NumPerRow * __instance.YOffset) - 3f;
__instance.SetScrollerBounds();
__instance.currentVisorIsEquipped = true;
}
@@ -220,6 +220,7 @@ internal static class GameOptionsMenuPatch
menu.checkboxOrigin,
menu.numberOptionOrigin,
menu.stringOptionOrigin,
menu.playerOptionOrigin,
menu.settingsContainer));
foreach (var newOpt in options)
@@ -288,7 +288,7 @@ internal static class GameSettingMenuPatches
{
if (_text is not null && SelectedModIdx == 0)
{
_text.text = "Default";
_text.text = $"<size=40%>(Page 0/{MiraPluginManager.Instance.RegisteredPlugins.Length})</size>\nDefault";
_text.fontSizeMax = 3.2f;
SelectedMod = null;
}
@@ -298,7 +298,7 @@ internal static class GameSettingMenuPatches
SelectedMod = MiraPluginManager.Instance.RegisteredPlugins[SelectedModIdx - 1];
var name = SelectedMod.MiraPlugin.OptionsTitleText;
_text.text = name[..Math.Min(name.Length, 25)];
_text.text = $"<size=50%>(Page {SelectedModIdx}/{MiraPluginManager.Instance.RegisteredPlugins.Length})</size>\n" + name[..Math.Min(name.Length, 25)];
}
bool replaceWithModifiers = true;
+20 -3
View File
@@ -1,7 +1,13 @@
using HarmonyLib;
using System.Collections.Generic;
using System.Linq;
using HarmonyLib;
using Il2CppSystem;
using MiraAPI.GameOptions;
using MiraAPI.GameOptions.OptionTypes;
using MiraAPI.Roles;
using MiraAPI.Utilities;
using UnityEngine;
using Object = Il2CppSystem.Object;
namespace MiraAPI.Patches.Options;
@@ -22,7 +28,9 @@ public static class OptionsPatches
__instance.roleMaxCount = 1;
}
__instance.roleChance += 10;
var increment = Input.GetKey(KeyCode.LeftShift) ? 5 : 10;
__instance.roleChance += increment;
if (__instance.roleChance > 100)
{
__instance.roleChance = 0;
@@ -46,7 +54,9 @@ public static class OptionsPatches
__instance.roleMaxCount = 1;
}
__instance.roleChance -= 10;
var increment = Input.GetKey(KeyCode.LeftShift) ? 5 : 10;
__instance.roleChance -= increment;
if (__instance.roleChance < 0)
{
__instance.roleChance = 100;
@@ -107,6 +117,7 @@ public static class OptionsPatches
[HarmonyPrefix]
[HarmonyPatch(typeof(NumberOption), nameof(NumberOption.AdjustButtonsActiveState))]
[HarmonyPatch(typeof(StringOption), nameof(StringOption.AdjustButtonsActiveState))]
[HarmonyPatch(typeof(PlayerOption), nameof(PlayerOption.AdjustButtonsActiveState))]
[HarmonyPatch(typeof(RoleOptionSetting), nameof(RoleOptionSetting.AdjustChanceButtonsActiveState))]
[HarmonyPatch(typeof(RoleOptionSetting), nameof(RoleOptionSetting.AdjustCountButtonsActiveState))]
public static bool AdjustButtonsPrefix(OptionBehaviour __instance)
@@ -123,6 +134,11 @@ public static class OptionsPatches
stringOption.MinusBtn.SetInteractable(true);
stringOption.PlusBtn.SetInteractable(true);
}
if (__instance.TryCast<PlayerOption>() is { } playerOption)
{
playerOption.MinusBtn.SetInteractable(true);
playerOption.PlusBtn.SetInteractable(true);
}
return false;
}
@@ -172,6 +188,7 @@ public static class OptionsPatches
[HarmonyPrefix]
[HarmonyPatch(typeof(StringOption), nameof(StringOption.UpdateValue))]
[HarmonyPatch(typeof(NumberOption), nameof(NumberOption.UpdateValue))]
[HarmonyPatch(typeof(PlayerOption), nameof(PlayerOption.UpdateValue))]
public static bool UpdateValuePrefix(OptionBehaviour __instance)
{
return !__instance.IsCustom();
@@ -0,0 +1,128 @@
using System;
using System.Linq;
using HarmonyLib;
using MiraAPI.GameOptions;
using MiraAPI.GameOptions.OptionTypes;
using MiraAPI.Utilities;
using Reactor.Utilities;
using UnityEngine;
using Object = Il2CppSystem.Object;
namespace MiraAPI.Patches.Options;
[HarmonyPatch(typeof(PlayerOption))]
public static class PlayerOptionPatches
{
// Updates the list of players according to the filter.
[HarmonyPrefix]
[HarmonyPatch(nameof(PlayerOption.FixedUpdate))]
public static bool PlayerOptionUpdatePatch(PlayerOption __instance)
{
if (!__instance.IsCustom())
{
return true;
}
if (!ModdedOptionsManager.CreatedPlayerOptions.TryGetValue(__instance, out var moddedPlrOpt)) return false;
var filteredPlayers = moddedPlrOpt.GetFilteredPlayers();
if (filteredPlayers.Count != __instance.Values.Count)
{
filteredPlayers.Sort((a, b) => a.PlayerId.CompareTo(b.PlayerId));
__instance.Values = filteredPlayers.ToIl2CppList();
moddedPlrOpt.Values = __instance.Values;
__instance.playerIndex = filteredPlayers.FindIndex(p => p.PlayerId == __instance.Value);
__instance.SetValueText();
}
__instance.CheckValueChanged();
return false;
}
// Disable going under 0 if you aren't allowed to choose None.
[HarmonyPrefix]
[HarmonyPatch(nameof(PlayerOption.UpdatePlayerIndex))]
public static bool UpdatePlayerIndexPatch(PlayerOption __instance, int index)
{
if (!__instance.IsCustom() || ModdedOptionsManager.CreatedPlayerOptions[__instance].AllowNone)
{
return true;
}
var newIndex = Mathf.Clamp(index, 0, __instance.Values.Count - 1);
__instance.playerIndex = newIndex;
__instance.Value = __instance.Values[newIndex].PlayerId;
return false;
}
// Replace "Round Robin" with "None" in the Host Options Menu.
[HarmonyPostfix]
[HarmonyPatch(nameof(PlayerOption.SetValueText))]
public static void SetValueTextPatch(PlayerOption __instance)
{
if (__instance.playerIndex < 0)
{
__instance.ValueText.text = TranslationController.Instance.GetString(StringNames.FilterNone);
}
}
// Innersloth hardcode literally replaces the value with the HNS impostor option OnEnable, so I have to patch that out. Smh.
[HarmonyPrefix]
[HarmonyPatch(nameof(PlayerOption.OnEnable))]
public static bool OnEnablePatch(PlayerOption __instance)
{
return !__instance.IsCustom();
}
[HarmonyPrefix]
[HarmonyPatch(nameof(PlayerOption.GetInt))]
public static bool GetIntPatch(PlayerOption __instance, ref int __result)
{
if (!__instance.IsCustom())
{
return true;
}
__result = __instance.Value;
return false;
}
// Used to replace "Round Robin" with "None" for option notification & view pane.
[HarmonyPrefix]
[HarmonyPatch(typeof(PlayerSelectionGameSetting), nameof(PlayerSelectionGameSetting.GetValueString))]
public static bool GetStringPatch(PlayerSelectionGameSetting __instance, float value, ref string __result)
{
var option = ModdedOptionsManager.ModdedOptions.FirstOrDefault(x => x.Value.Data == __instance).Value;
if (option == null) return true;
var networkedPlayerInfo = GameData.Instance.AllPlayers.ToArray().FirstOrDefault(p => p.PlayerId == (int)value);
if (networkedPlayerInfo != null)
{
__result = networkedPlayerInfo.PlayerName;
return false;
}
__result = TranslationController.Instance.GetString(StringNames.FilterNone);
return false;
}
// "UpdateValue" was inlined and I needed to replace it, so I just rewrote the method where it's called from.
[HarmonyPrefix]
[HarmonyPatch(nameof(PlayerOption.CheckValueChanged))]
public static bool UpdateValuePatch(PlayerOption __instance)
{
if (!__instance.IsCustom())
{
return true;
}
if (__instance.oldValue == __instance.Value) return false;
__instance.oldValue = __instance.Value;
__instance.SetValueText();
return false;
}
}
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using MiraAPI.GameOptions;
using MiraAPI.Networking;
using MiraAPI.Roles;
using MiraAPI.Utilities;
@@ -30,6 +31,9 @@ public static class RoleSettingMenuPatches
private static float ScrollerNum { get; set; } = 0.522f;
private static RoleBehaviour? CurrentRole { get; set; }
private static List<IModdedOption>? CurrentRoleOptions { get; set; }
[HarmonyPostfix]
[HarmonyPatch(nameof(RolesSettingsMenu.SetQuotaTab))]
public static void SetQuotaTabPostfix(RolesSettingsMenu __instance)
@@ -45,6 +49,8 @@ public static class RoleSettingMenuPatches
RoleOptionSettings.ForEach(Object.Destroy);
Headers.Clear();
RoleOptionSettings.Clear();
CurrentRole = null;
CurrentRoleOptions = null;
__instance.roleChances = new Il2CppSystem.Collections.Generic.List<RoleOptionSetting>();
__instance.advancedSettingChildren = new Il2CppSystem.Collections.Generic.List<OptionBehaviour>();
@@ -262,9 +268,31 @@ public static class RoleSettingMenuPatches
[HarmonyPrefix]
[HarmonyPatch(nameof(RolesSettingsMenu.Update))]
public static bool UpdatePatch()
public static bool UpdatePatch(RolesSettingsMenu __instance)
{
return GameSettingMenuPatches.SelectedModIdx == 0;
if (GameSettingMenuPatches.SelectedModIdx == 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;
}
[HarmonyPostfix]
@@ -276,6 +304,8 @@ public static class RoleSettingMenuPatches
return;
}
CurrentRole = null;
CurrentRoleOptions = null;
__instance.scrollBar.SetScrollBounds(__instance);
}
@@ -328,27 +358,26 @@ public static class RoleSettingMenuPatches
optBehaviour.gameObject.DestroyImmediate();
}
CurrentRole = role;
__instance.advancedSettingChildren.Clear();
var hasImage = role.RoleScreenshot != null;
var num = hasImage ? -0.872f : -1;
// TODO: create sub groups under the role settings.
var filteredOptions = GameSettingMenuPatches.SelectedMod?.InternalOptionGroups
.Where(x => x.GroupVisible() && x.OptionableType == role.GetType())
.SelectMany(x => x.Options)
.Where(x => x.Visible())
.ToList() ?? [];
CurrentRoleOptions = filteredOptions;
foreach (var option in filteredOptions)
{
var newOpt = option.CreateOption(
__instance.checkboxOrigin,
__instance.numberOptionOrigin,
__instance.stringOptionOrigin,
GameSettingMenu.Instance.GameSettingsTab.playerOptionOrigin,
__instance.AdvancedRolesSettings.transform);
newOpt.transform.localPosition = new Vector3(hasImage ? 2.17f : 1.1f, num, -2f);
newOpt.SetClickMask(__instance.ButtonClickMask);
SpriteRenderer[] componentsInChildren = newOpt.GetComponentsInChildren<SpriteRenderer>(true);
@@ -366,11 +395,10 @@ public static class RoleSettingMenuPatches
newOpt.LabelBackground.enabled = false;
__instance.advancedSettingChildren.Add(newOpt);
num += -0.45f;
newOpt.gameObject.SetActive(false);
newOpt.Initialize();
}
__instance.scrollBar.SetYBoundsMax(-num - 3);
__instance.scrollBar.ScrollToTop();
}
@@ -506,7 +534,7 @@ public static class RoleSettingMenuPatches
if (GameSettingMenuPatches.SelectedMod is null ||
GameSettingMenuPatches.SelectedMod.InternalOptionGroups
.Exists(x => x.OptionableType == role.GetType()))
.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";
+18
View File
@@ -154,6 +154,24 @@ public static class Extensions
return TutorialManager.InstanceExists || AmongUsClient.Instance.HostId == playerControl.OwnerId;
}
/// <summary>
/// Used to convert a System.Collections.Generic.List to Il2cppSystem.
/// </summary>
/// <param name="systemList">The list.</param>
/// <typeparam name="T">The type in the list.</typeparam>
/// <returns>The converted list.</returns>
public static Il2CppSystem.Collections.Generic.List<T> ToIl2CppList<T>(this List<T> systemList)
{
var il2cppList = new Il2CppSystem.Collections.Generic.List<T>();
foreach (var item in systemList)
{
il2cppList.Add(item);
}
return il2cppList;
}
/// <summary>
/// Determines if a float is an integer.
/// </summary>