Merge branch 'dev' into cleanup

This commit is contained in:
Az committed 2026-08-16 03:33:09 -04:00
commit 907e4d4c34
8 files changed
+157 -15

No files matched your search

+2 -2
View File
@@ -11,7 +11,7 @@ namespace MiraAPI.Events.Mira;
/// <typeparam name="T">The <see cref="CustomActionButton"/> type.</typeparam>
/// <param name="button">The <see cref="CustomActionButton"/> that was clicked.</param>
/// <param name="genericClickEvent">The generic <see cref="MiraButtonClickEvent"/> invoked before button-specific events.</param>
public sealed class MiraButtonClickEvent<T>(T button, MiraButtonClickEvent genericClickEvent) : MiraCancelableEvent where T : CustomActionButton
public class MiraButtonClickEvent<T>(T button, MiraButtonClickEvent genericClickEvent) : MiraCancelableEvent where T : CustomActionButton
{
/// <summary>
/// Gets the <see cref="CustomActionButton"/> that was clicked.
@@ -31,7 +31,7 @@ public sealed class MiraButtonClickEvent<T>(T button, MiraButtonClickEvent gener
/// Do not use for vanilla <see cref="AbilityButton"/>s.
/// </remarks>
/// <param name="button">The <see cref="CustomActionButton"/> that was clicked.</param>
public sealed class MiraButtonClickEvent(CustomActionButton button) : MiraCancelableEvent
public class MiraButtonClickEvent(CustomActionButton button) : MiraCancelableEvent
{
/// <summary>
/// Gets the <see cref="CustomActionButton"/> that was clicked.
+14
View File
@@ -18,6 +18,20 @@ public static class CustomButtonManager
/// </summary>
public static ReadOnlyCollection<CustomActionButton> Buttons { get; internal set; } = new([]);
/// <summary>
/// Gets a list of all registered button-specific <see cref="MiraButtonClickEvent"/>s.
/// </summary>
public static ReadOnlyDictionary<Type, Type> EventTypes { get; internal set; } = new(
new Dictionary<Type, Type>
{ });
/// <summary>
/// Gets a list of all registered button-specific <see cref="MiraButtonCancelledEvent"/>s.
/// </summary>
public static ReadOnlyDictionary<Type, Type> CancelledEventTypes { get; internal set; } = new(
new Dictionary<Type, Type>
{ });
internal static readonly List<CustomActionButton> CustomButtons = [];
internal static readonly Dictionary<Type, Type> ButtonEventTypes = [];
internal static readonly Dictionary<Type, Type> ButtonCancelledEventTypes = [];
@@ -545,12 +545,8 @@ public static class RoleSettingMenuPatches
__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 = Sprite.Create(
role.RoleScreenshot.texture,
new Rect(0, 0, 370, 230),
Vector2.one / 2,
100);
__instance.roleScreenshot.drawMode = SpriteDrawMode.Sliced;
__instance.roleScreenshot.sprite = role.RoleScreenshot;
__instance.roleScreenshot.drawMode = SpriteDrawMode.Simple;
}
__instance.roleHeaderSprite.color = customRole.OptionsMenuColor;
@@ -139,6 +139,8 @@ public sealed class MiraPluginManager
{
// Save all buttons into a read-only collection for easy access
CustomButtonManager.Buttons = new ReadOnlyCollection<CustomActionButton>(CustomButtonManager.CustomButtons);
CustomButtonManager.EventTypes = new ReadOnlyDictionary<Type, Type>(CustomButtonManager.ButtonEventTypes);
CustomButtonManager.CancelledEventTypes = new ReadOnlyDictionary<Type, Type>(CustomButtonManager.ButtonCancelledEventTypes);
// Cache all the registered plugins into an array for easy access
RegisteredPlugins = [.. _registeredPlugins.Values];
+12 -5
View File
@@ -141,11 +141,18 @@ public static class CustomRoleManager
roleBehaviour.CanVent = customRole.Configuration.CanUseVent || customRole.Configuration.GetsVentData;
roleBehaviour.DefaultGhostRole = customRole.Configuration.GhostRole;
roleBehaviour.MaxCount = customRole.Configuration.MaxRoleCount;
roleBehaviour.RoleScreenshot = Sprite.Create(
customRole.Configuration.OptionsScreenshot?.LoadAsset().texture,
new Rect(0, 0, 370, 230),
Vector2.one / 2,
100);
if (customRole.Configuration.OptionsScreenshot != null)
{
roleBehaviour.RoleScreenshot = customRole.Configuration.OptionsScreenshot.LoadAsset();
}
else
{
roleBehaviour.RoleScreenshot = Sprite.Create(
null,
new Rect(0, 0, 370, 230),
Vector2.one / 2,
100);
}
_emptySettings ??= new(0);
_emptyKillAnimations ??= new(0);
@@ -0,0 +1,37 @@
using System;
using System.Linq;
using UnityEngine;
namespace MiraAPI.Utilities.Assets;
/// <summary>
/// A utility class for loading multiple assets from an <see cref="LoadableBundleSubAssetHolder"/>.
/// </summary>
/// <param name="name">The name of the asset.</param>
/// <param name="assetHolder">The <see cref="LoadableBundleSubAssetHolder"/> that contains the asset.</param>
public class LoadableBundleSubAsset(string name, LoadableBundleSubAssetHolder assetHolder) : LoadableAsset<Sprite>
{
/// <summary>
/// Loads the asset from the <see cref="LoadableBundleSubAssetHolder"/>.
/// </summary>
/// <returns>The asset.</returns>
/// <exception cref="Exception">The asset did not load properly.</exception>
public override Sprite LoadAsset()
{
if (LoadedAsset != null)
{
return LoadedAsset;
}
assetHolder.TryInit();
var loadedAsset = assetHolder.SubSprites.FirstOrDefault(x => x.name == name);
if (loadedAsset == null)
{
throw new InvalidOperationException($"INVALID ASSETS: {name}");
}
LoadedAsset = loadedAsset;
return LoadedAsset;
}
}
@@ -0,0 +1,86 @@
using System;
using System.Linq;
using HarmonyLib;
using Il2CppInterop.Runtime;
using Reactor.Utilities.Extensions;
using UnityEngine;
namespace MiraAPI.Utilities.Assets;
/// <summary>
/// A utility class for loading multiple assets from an <see cref="AssetBundle"/>.
/// </summary>
public class LoadableBundleSubAssetHolder
{
/// <summary>
/// Initializes a new instance of the <see cref="LoadableBundleSubAssetHolder"/> class.
/// </summary>
/// <param name="names">The name of the assets to pull from.</param>
/// <param name="bundle">The <see cref="AssetBundle"/> that contains the assets.</param>
public LoadableBundleSubAssetHolder(string[] names, AssetBundle bundle)
{
Bundle = bundle;
SpriteNames = names;
}
/// <summary>
/// Initializes a new instance of the <see cref="LoadableBundleSubAssetHolder"/> class.
/// </summary>
/// <param name="name">The name of the asset.</param>
/// <param name="bundle">The <see cref="AssetBundle"/> that contains the assets.</param>
public LoadableBundleSubAssetHolder(string name, AssetBundle bundle)
{
Bundle = bundle;
SpriteNames = [name];
}
internal string[] SpriteNames = [];
internal AssetBundle Bundle;
public Sprite[] SubSprites = [];
public void TryInit()
{
if (SubSprites.Length == 0)
{
var newSprites = Array.Empty<Sprite>();
foreach (var name in SpriteNames)
{
var loadedAssets = Bundle.LoadAssetWithSubAssets(name, Il2CppType.From(typeof(Sprite))).ToArray();
if (loadedAssets == null)
{
throw new InvalidOperationException($"INVALID ASSETS: {name}");
}
foreach (var obj in loadedAssets)
{
var img = obj.TryCast<Sprite>();
if (img != null)
{
img.DontDestroy().DontUnload();
newSprites = newSprites.AddToArray(img);
}
}
}
SubSprites = newSprites;
}
}
/// <summary>
/// Unloads an asset.
/// </summary>
/// <returns>True if the asset was unloaded, false otherwise.</returns>
public bool UnloadAsset()
{
if (SubSprites.Length == 0)
{
return false;
}
foreach (var sprite in SubSprites)
{
sprite.DestroyImmediate();
}
SubSprites = [];
return true;
}
}
+2 -2
View File
@@ -106,8 +106,8 @@ public static class TmpSpriteUtils
{
name = spriteName,
hashCode = TMP_TextUtilities.GetSimpleHashCode(spriteName),
x = 0,
y = 0,
x = rect.x,
y = rect.y,
width = rect.width,
height = rect.height,
xOffset = -(rect.width / 3) + (scale - 1) * (rect.width / 2),