improve lag issues in settings menu on 17.4

This commit is contained in:
XtraCube committed 2026-07-20 16:35:52 -04:00
1 parent eb18d82d8e
commit e541840da9
3 files changed
+244 -173

No files matched your search

+119 -113
View File
@@ -1,6 +1,10 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using AmongUs.GameOptions;
using BepInEx.Unity.IL2CPP.Utils.Collections;
using HarmonyLib;
using Il2CppInterop.Runtime.Attributes;
using MiraAPI.GameOptions;
@@ -178,7 +182,8 @@ internal static class GameOptionsMenuPatch
private static void ModifiersUpdate(ref float num)
{
var groups = GameSettingMenuPatches.SelectedMod?.InternalOptionGroups
.Where(x => x.ParentMenu is MenuCategory.Modifiers || x.OptionableType?.IsAssignableTo(typeof(BaseModifier)) == true) ?? [];
.Where(x => x.ParentMenu is MenuCategory.Modifiers ||
x.OptionableType?.IsAssignableTo(typeof(BaseModifier)) == true) ?? [];
foreach (var modGroup in groups)
{
@@ -189,7 +194,8 @@ internal static class GameOptionsMenuPatch
private static void ModifiersCreate(GameOptionsMenu menu)
{
var groups = GameSettingMenuPatches.SelectedMod?.InternalOptionGroups
.Where(x => x.ParentMenu is MenuCategory.Modifiers || x.OptionableType?.IsAssignableTo(typeof(BaseModifier)) == true) ?? [];
.Where(x => x.ParentMenu is MenuCategory.Modifiers ||
x.OptionableType?.IsAssignableTo(typeof(BaseModifier)) == true) ?? [];
foreach (var group in groups)
{
CreateGroup(menu, group);
@@ -208,20 +214,17 @@ internal static class GameOptionsMenuPatch
__instance.MapPicker.gameObject.SetActive(false);
if (__instance.name == "MODIFIERS TAB")
switch (__instance.name)
{
ModifiersCreate(__instance);
return false;
}
else if (__instance.name == "CUSTOM TAB 1")
{
CustomMenuOneCreate(__instance);
return false;
}
else if (__instance.name == "CUSTOM TAB 2")
{
CustomMenuTwoCreate(__instance);
return false;
case "MODIFIERS TAB":
ModifiersCreate(__instance);
return false;
case "CUSTOM TAB 1":
CustomMenuOneCreate(__instance);
return false;
case "CUSTOM TAB 2":
CustomMenuTwoCreate(__instance);
return false;
}
var filteredGroups = GameSettingMenuPatches.SelectedMod?.InternalOptionGroups
@@ -318,117 +321,120 @@ internal static class GameOptionsMenuPatch
defaultPreset = preset;
}
foreach (var newOpt in options)
{
newOpt.SetClickMask(menu.ButtonClickMask);
SpriteRenderer[] componentsInChildren = newOpt.GetComponentsInChildren<SpriteRenderer>(true);
foreach (var renderer in componentsInChildren)
menu.StartCoroutine(
options.CoLoopWithBudget((newOpt) =>
{
if (group.GroupColor != MiraApiPlugin.DefaultHeaderColor)
newOpt.SetClickMask(menu.ButtonClickMask);
SpriteRenderer[] componentsInChildren = newOpt.GetComponentsInChildren<SpriteRenderer>(true);
foreach (var renderer in componentsInChildren)
{
renderer.color = group.GroupColor.FindAlternateColor();
if (renderer.transform.parent.TryGetComponent<GameOptionButton>(out var btn))
if (group.GroupColor != MiraApiPlugin.DefaultHeaderColor)
{
btn.interactableColor = group.GroupColor.FindAlternateColor();
btn.interactableHoveredColor = Color.white;
renderer.color = group.GroupColor.FindAlternateColor();
if (renderer.transform.parent.TryGetComponent<GameOptionButton>(out var btn))
{
btn.interactableColor = group.GroupColor.FindAlternateColor();
btn.interactableHoveredColor = Color.white;
}
}
renderer.material.SetInt(PlayerMaterial.MaskLayer, 20);
}
renderer.material.SetInt(PlayerMaterial.MaskLayer, 20);
}
foreach (var textMeshPro in newOpt.GetComponentsInChildren<TextMeshPro>(true))
{
if (group.GroupColor != MiraApiPlugin.DefaultHeaderColor)
foreach (var textMeshPro in newOpt.GetComponentsInChildren<TextMeshPro>(true))
{
textMeshPro.color = group.GroupColor;
if (group.GroupColor != MiraApiPlugin.DefaultHeaderColor)
{
textMeshPro.color = group.GroupColor;
}
textMeshPro.fontMaterial.SetFloat(ShaderID.StencilComp, 3f);
textMeshPro.fontMaterial.SetFloat(ShaderID.Stencil, 20);
}
textMeshPro.fontMaterial.SetFloat(ShaderID.StencilComp, 3f);
textMeshPro.fontMaterial.SetFloat(ShaderID.Stencil, 20);
}
if (newOpt is ToggleOption toggle)
{
toggle.CheckMark.sprite = MiraAssets.Checkmark.LoadAsset();
toggle.CheckMark.color = group.GroupColor != MiraApiPlugin.DefaultHeaderColor
? group.GroupColor
: MiraAssets.AcceptedTeal;
var rend = toggle.CheckMark.transform.parent.FindChild("ActiveSprite")
.GetComponent<SpriteRenderer>();
rend.sprite = MiraAssets.CheckmarkBox.LoadAsset();
rend.color = group.GroupColor != MiraApiPlugin.DefaultHeaderColor
? group.GroupColor
: MiraAssets.AcceptedTeal;
}
menu.Children.Add(newOpt);
var resetBtn = new GameObject("ResetOption");
resetBtn.transform.parent = newOpt.transform;
resetBtn.transform.localScale = new(.5f, .5f, 1);
resetBtn.layer = LayerMask.NameToLayer("UI");
resetBtn.transform.localPosition = new Vector3(-3.1f, 0f, -2f);
var resetRend = resetBtn.AddComponent<SpriteRenderer>();
resetRend.sprite = MiraAssets.ResetButton.LoadAsset();
resetRend.maskInteraction = SpriteMaskInteraction.VisibleInsideMask;
resetRend.color = group.GroupColor.Equals(MiraApiPlugin.DefaultHeaderColor)
? Color.white
: group.GroupColor.FindAlternateColor();
var resetBoxCol = resetBtn.gameObject.AddComponent<BoxCollider2D>();
resetBoxCol.size = new Vector2(1f, 1f);
resetBoxCol.offset = new Vector2(0, 0);
var passiveButton = resetBtn.AddComponent<PassiveButton>();
passiveButton.OnClick = new Button.ButtonClickedEvent();
passiveButton.ClickSound = menu.BackButton.GetComponent<PassiveButton>().ClickSound;
passiveButton.OnMouseOver = new UnityEvent();
passiveButton.OnMouseOver.AddListener(
(UnityAction)(() =>
if (newOpt is ToggleOption toggle)
{
resetRend.color = group.GroupColor != MiraApiPlugin.DefaultHeaderColor
toggle.CheckMark.sprite = MiraAssets.Checkmark.LoadAsset();
toggle.CheckMark.color = group.GroupColor != MiraApiPlugin.DefaultHeaderColor
? group.GroupColor
: MiraAssets.AcceptedTeal;
}));
passiveButton.OnMouseOut = new UnityEvent();
passiveButton.OnMouseOut.AddListener(
(UnityAction)(() =>
{
resetRend.color = group.GroupColor.Equals(MiraApiPlugin.DefaultHeaderColor)
? Color.white
: group.GroupColor.FindAlternateColor();
}));
if (newOpt is ToggleOption toggleOpt)
{
passiveButton.OnClick.AddListener(
(UnityAction)(() =>
{
defaultPreset!.ResetOption(toggleOpt);
}));
}
else if (newOpt is NumberOption numOpt)
{
passiveButton.OnClick.AddListener(
(UnityAction)(() =>
{
defaultPreset!.ResetOption(numOpt);
}));
}
else if (newOpt is StringOption strOpt)
{
passiveButton.OnClick.AddListener(
(UnityAction)(() =>
{
defaultPreset!.ResetOption(strOpt);
}));
}
if (!defaultPreset!.IsOptionInPreset(newOpt))
{
resetBtn.Destroy();
}
var rend = toggle.CheckMark.transform.parent.FindChild("ActiveSprite")
.GetComponent<SpriteRenderer>();
rend.sprite = MiraAssets.CheckmarkBox.LoadAsset();
rend.color = group.GroupColor != MiraApiPlugin.DefaultHeaderColor
? group.GroupColor
: MiraAssets.AcceptedTeal;
}
newOpt.Initialize();
newOpt.gameObject.SetActive(false);
}
menu.Children.Add(newOpt);
var resetBtn = new GameObject("ResetOption");
resetBtn.transform.parent = newOpt.transform;
resetBtn.transform.localScale = new(.5f, .5f, 1);
resetBtn.layer = LayerMask.NameToLayer("UI");
resetBtn.transform.localPosition = new Vector3(-3.1f, 0f, -2f);
var resetRend = resetBtn.AddComponent<SpriteRenderer>();
resetRend.sprite = MiraAssets.ResetButton.LoadAsset();
resetRend.maskInteraction = SpriteMaskInteraction.VisibleInsideMask;
resetRend.color = group.GroupColor.Equals(MiraApiPlugin.DefaultHeaderColor)
? Color.white
: group.GroupColor.FindAlternateColor();
var resetBoxCol = resetBtn.gameObject.AddComponent<BoxCollider2D>();
resetBoxCol.size = new Vector2(1f, 1f);
resetBoxCol.offset = new Vector2(0, 0);
var passiveButton = resetBtn.AddComponent<PassiveButton>();
passiveButton.OnClick = new Button.ButtonClickedEvent();
passiveButton.ClickSound = menu.BackButton.GetComponent<PassiveButton>().ClickSound;
passiveButton.OnMouseOver = new UnityEvent();
passiveButton.OnMouseOver.AddListener(
(UnityAction)(() =>
{
resetRend.color = group.GroupColor != MiraApiPlugin.DefaultHeaderColor
? group.GroupColor
: MiraAssets.AcceptedTeal;
}));
passiveButton.OnMouseOut = new UnityEvent();
passiveButton.OnMouseOut.AddListener(
(UnityAction)(() =>
{
resetRend.color = group.GroupColor.Equals(MiraApiPlugin.DefaultHeaderColor)
? Color.white
: group.GroupColor.FindAlternateColor();
}));
if (newOpt is ToggleOption toggleOpt)
{
passiveButton.OnClick.AddListener(
(UnityAction)(() =>
{
defaultPreset!.ResetOption(toggleOpt);
}));
}
else if (newOpt is NumberOption numOpt)
{
passiveButton.OnClick.AddListener(
(UnityAction)(() =>
{
defaultPreset!.ResetOption(numOpt);
}));
}
else if (newOpt is StringOption strOpt)
{
passiveButton.OnClick.AddListener(
(UnityAction)(() =>
{
defaultPreset!.ResetOption(strOpt);
}));
}
if (!defaultPreset!.IsOptionInPreset(newOpt))
{
resetBtn.Destroy();
}
newOpt.Initialize();
newOpt.gameObject.SetActive(false);
}).WrapToIl2Cpp()
);
var boxCol = categoryHeaderMasked.gameObject.AddComponent<BoxCollider2D>();
boxCol.size = new Vector2(7, 0.7f);
@@ -1,9 +1,10 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using AmongUs.GameOptions;
using BepInEx.Unity.IL2CPP.Utils.Collections;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using MiraAPI.GameOptions;
using MiraAPI.Networking;
using MiraAPI.Roles;
@@ -11,7 +12,6 @@ using MiraAPI.Utilities;
using MiraAPI.Utilities.Assets;
using Reactor.Localization.Utilities;
using Reactor.Networking.Rpc;
using Reactor.Utilities;
using Reactor.Utilities.Extensions;
using TMPro;
using UnityEngine;
@@ -49,9 +49,7 @@ public static class RoleSettingMenuPatches
__instance.scrollBar.SetScrollBounds(__instance);
}
[HarmonyPrefix]
[HarmonyPatch(nameof(RolesSettingsMenu.SetQuotaTab))]
public static bool SetQuotaTabPatch(RolesSettingsMenu __instance)
private static IEnumerator CoQuotaTabPatch(RolesSettingsMenu roleMenu)
{
foreach (var obj in Headers)
{
@@ -59,8 +57,10 @@ public static class RoleSettingMenuPatches
{
continue;
}
obj.DeepDestroy(false);
}
Headers.Clear();
foreach (var obj in RoleOptionSettings)
{
@@ -68,24 +68,26 @@ public static class RoleSettingMenuPatches
{
continue;
}
obj.gameObject.DeepDestroy(false);
}
RoleOptionSettings.Clear();
CurrentRole = null;
CurrentRoleOptions = null;
__instance.roleChances = new Il2CppSystem.Collections.Generic.List<RoleOptionSetting>();
__instance.advancedSettingChildren = new Il2CppSystem.Collections.Generic.List<OptionBehaviour>();
roleMenu.roleChances = new Il2CppSystem.Collections.Generic.List<RoleOptionSetting>();
roleMenu.advancedSettingChildren = new Il2CppSystem.Collections.Generic.List<OptionBehaviour>();
var maskBg = __instance.scrollBar.transform.FindChild("MaskBg");
var hitbox = __instance.scrollBar.transform.FindChild("Hitbox");
var dividerImage = __instance.transform.FindChild("HeaderButtons/DividerImage");
var maskBg = roleMenu.scrollBar.transform.FindChild("MaskBg");
var hitbox = roleMenu.scrollBar.transform.FindChild("Hitbox");
var dividerImage = roleMenu.transform.FindChild("HeaderButtons/DividerImage");
if (GameSettingMenuPatches.SelectedModIdx == 0)
{
__instance.AllButton.transform.parent.gameObject.SetActive(true);
__instance.AllButton.gameObject.SetActive(true);
__instance.scrollBar.transform.localPosition = new Vector3(-1.4957f, 0.657f, -4);
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);
@@ -94,67 +96,70 @@ public static class RoleSettingMenuPatches
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();
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 (__instance.roleTabs == null || __instance.roleTabs.Count == 0)
if (roleMenu.roleTabs == null || roleMenu.roleTabs.Count == 0)
{
var num2 = -1.928f;
__instance.roleTabs = new();
__instance.roleTabs.Add(__instance.AllButton);
roleMenu.roleTabs = new();
roleMenu.roleTabs.Add(roleMenu.AllButton);
foreach (var t in list)
{
__instance.AddRoleTab(t, ref num2);
roleMenu.AddRoleTab(t, ref num2);
}
foreach (var t in list2)
{
__instance.AddRoleTab(t, ref num2);
roleMenu.AddRoleTab(t, ref num2);
}
}
var categoryHeaderEditRole = Object.Instantiate(
__instance.categoryHeaderEditRoleOrigin,
roleMenu.categoryHeaderEditRoleOrigin,
Vector3.zero,
Quaternion.identity,
__instance.RoleChancesSettings.transform);
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)
{
__instance.CreateQuotaOption(t, ref num, num3);
roleMenu.CreateQuotaOption(t, ref num, num3);
num3++;
}
num -= 0.22f;
var categoryHeaderEditRole2 = Object.Instantiate(
__instance.categoryHeaderEditRoleOrigin,
roleMenu.categoryHeaderEditRoleOrigin,
Vector3.zero,
Quaternion.identity,
__instance.RoleChancesSettings.transform);
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)
{
__instance.CreateQuotaOption(t, ref num, num3);
roleMenu.CreateQuotaOption(t, ref num, num3);
num3++;
}
return false;
Info($"Created {num3} role options for the default game.");
yield return null;
}
ScrollerNum = 0.522f;
__instance.AllButton.transform.parent.gameObject.SetActive(false);
__instance.AllButton.gameObject.SetActive(false);
__instance.scrollBar.transform.localPosition = new Vector3(-1.4957f, 1.5261f, -4);
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);
@@ -168,7 +173,8 @@ public static class RoleSettingMenuPatches
if (roleGroups is null)
{
return false;
Error("No role groups found for the selected mod.");
yield break;
}
// sort the groups by priority
@@ -176,13 +182,14 @@ public static class RoleSettingMenuPatches
.OrderBy(x => x.Key.Priority)
.ThenBy(x => x.Key.Name);
var quotaThing = __instance.categoryHeaderEditRoleOrigin.transform.FindChild("QuotaHeader");
var quotaThing = roleMenu.categoryHeaderEditRoleOrigin.transform.FindChild("QuotaHeader");
var usingNewQuota = false;
var template = __instance.transform.parent.parent.GetComponent<GameSettingMenu>().GameSettingsTab.categoryHeaderOrigin;
var template = roleMenu.transform.parent.parent.GetComponent<GameSettingMenu>().GameSettingsTab
.categoryHeaderOrigin;
foreach (var grouping in sortedRoleGroups)
{
if (!grouping.Any() || grouping.All(x=> x.Configuration.HideSettings || !x.VisibleInSettings()))
if (!grouping.Any() || grouping.All(x => x.Configuration.HideSettings || !x.VisibleInSettings()))
{
continue;
}
@@ -202,7 +209,7 @@ public static class RoleSettingMenuPatches
template,
Vector3.zero,
Quaternion.identity,
__instance.RoleChancesSettings.transform);
roleMenu.RoleChancesSettings.transform);
categoryHeaderMasked.SetHeader(name, 20);
@@ -245,19 +252,23 @@ public static class RoleSettingMenuPatches
categoryHeaderMasked.Background.color = Palette.ImpostorRoleHeaderRed;
break;
default:
categoryHeaderMasked.Title.color = group.Color.Equals(MiraApiPlugin.DefaultHeaderColor) ? Color.white : group.Color.FindAlternateColor();
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 = __instance.categoryHeaderEditRoleOrigin.Title.fontStyle;
categoryHeaderMasked.Title.font = __instance.categoryHeaderEditRoleOrigin.Title.font;
categoryHeaderMasked.Title.fontMaterial = __instance.categoryHeaderEditRoleOrigin.Title.fontMaterial;
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.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);
@@ -277,20 +288,21 @@ public static class RoleSettingMenuPatches
if (!RoleGroupHidden[group])
{
foreach (var role in grouping)
{
if (role is not RoleBehaviour roleBehaviour)
yield return
grouping.CoLoopWithBudget(role =>
{
continue;
}
if (role is not RoleBehaviour roleBehaviour)
{
return;
}
var option = CreateQuotaOption(__instance, roleBehaviour, num4);
if (option is not null)
{
RoleOptionSettings.Add(option);
num4++;
}
}
var option = CreateQuotaOption(roleMenu, roleBehaviour, num4);
if (option is not null)
{
RoleOptionSettings.Add(option);
num4++;
}
});
}
var boxCol = categoryHeaderMasked.gameObject.AddComponent<BoxCollider2D>();
@@ -298,25 +310,28 @@ public static class RoleSettingMenuPatches
boxCol.offset = new Vector2(1.5f, -0.3f);
var headerBtn = categoryHeaderMasked.gameObject.AddComponent<PassiveButton>();
headerBtn.ClickSound = __instance.BackButton.GetComponent<PassiveButton>().ClickSound;
headerBtn.ClickSound = roleMenu.BackButton.GetComponent<PassiveButton>().ClickSound;
headerBtn.OnMouseOver = new UnityEvent();
headerBtn.OnMouseOut = new UnityEvent();
headerBtn.OnClick.AddListener(
(UnityAction)(() =>
{
RolePositions[GameSettingMenuPatches.SelectedModIdx] = __instance.scrollBar.Inner.localPosition;
RolePositions[GameSettingMenuPatches.SelectedModIdx] = roleMenu.scrollBar.Inner.localPosition;
if (RoleGroupHidden.TryGetValue(group, out var groupHidden))
{
RoleGroupHidden[group] = !groupHidden;
}
foreach (var obj in Headers)
{
if (!obj)
{
continue;
}
obj.DeepDestroy(false);
}
Headers.Clear();
foreach (var obj in RoleOptionSettings)
{
@@ -324,10 +339,12 @@ public static class RoleSettingMenuPatches
{
continue;
}
obj.gameObject.DeepDestroy(false);
}
RoleOptionSettings.Clear();
__instance.SetQuotaTab();
roleMenu.SetQuotaTab();
}));
headerBtn.SetButtonEnableState(true);
@@ -337,7 +354,14 @@ public static class RoleSettingMenuPatches
}
}
__instance.scrollBar.SetScrollBounds(__instance);
roleMenu.scrollBar.SetScrollBounds(roleMenu);
}
[HarmonyPrefix]
[HarmonyPatch(nameof(RolesSettingsMenu.SetQuotaTab))]
public static bool SetQuotaTabPatch(RolesSettingsMenu __instance)
{
__instance.StartCoroutine(CoQuotaTabPatch(__instance).WrapToIl2Cpp());
return false;
}
@@ -362,6 +386,7 @@ public static class RoleSettingMenuPatches
}
[HarmonyPrefix]
// TODO: turn this into a fixed update
[HarmonyPatch(nameof(RolesSettingsMenu.Update))]
public static bool UpdatePatch(RolesSettingsMenu __instance)
{
+40
View File
@@ -1,10 +1,12 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Timers;
using HarmonyLib;
using MiraAPI.GameOptions;
using MiraAPI.Networking;
@@ -239,6 +241,44 @@ public static class Extensions
}
}
/// <summary>
/// Runs a given action in a loop with a frame budget based on the current target frame rate. Once the budget is hit, the loop continues on the next frame.
/// </summary>
/// <param name="collection">The collection to iterate over.</param>
/// <param name="action">The action to perform on each item.</param>
/// <typeparam name="T">The type of the collection.</typeparam>
/// <returns>Coroutine.</returns>
public static IEnumerator CoLoopWithBudget<T>(this IEnumerable<T> collection, Action<T> action)
{
var fps = Application.targetFrameRate > 0 ? Application.targetFrameRate : 60;
long budget = 1 / (fps * 2); // default is half of current frame time.
yield return collection.CoLoopWithBudget(budget, action);
}
/// <summary>
/// Runs a given action in a loop with a given frame budget. Once the budget is hit, the loop continues on the next frame.
/// </summary>
/// <param name="collection">The collection to iterate over.</param>
/// <param name="frameBudget">The # of milliseconds to spend in the loop.</param>
/// <param name="action">The action to perform on each item.</param>
/// <typeparam name="T">The type of the collection.</typeparam>
/// <returns>Coroutine.</returns>
public static IEnumerator CoLoopWithBudget<T>(this IEnumerable<T> collection, long frameBudget, Action<T> action)
{
var timer = new Stopwatch();
timer.Start();
foreach (var item in collection)
{
action(item);
if (timer.ElapsedMilliseconds > frameBudget)
{
timer.Restart();
yield return null;
}
}
}
private static IEnumerator Nuke(GameObject? go, bool clearGc)
{
if (go == null)