From 6f61a75bb7711876d03b73a00dfd29da39db2ccf Mon Sep 17 00:00:00 2001
From: Atony <75191600+AtonyGit@users.noreply.github.com>
Date: Sat, 15 Aug 2026 13:18:05 -0500
Subject: [PATCH] Add BundleSubAssetHolder for packed spritesheets
---
.../Patches/Options/RoleSettingMenuPatches.cs | 1 -
.../Assets/LoadableBundleSubAsset.cs | 37 ++++++++
.../Assets/LoadableBundleSubAssetHolder.cs | 86 +++++++++++++++++++
MiraAPI/Utilities/Assets/TmpSpriteUtils.cs | 4 +-
4 files changed, 125 insertions(+), 3 deletions(-)
create mode 100644 MiraAPI/Utilities/Assets/LoadableBundleSubAsset.cs
create mode 100644 MiraAPI/Utilities/Assets/LoadableBundleSubAssetHolder.cs
diff --git a/MiraAPI/Patches/Options/RoleSettingMenuPatches.cs b/MiraAPI/Patches/Options/RoleSettingMenuPatches.cs
index 0dc8721..65c64f6 100644
--- a/MiraAPI/Patches/Options/RoleSettingMenuPatches.cs
+++ b/MiraAPI/Patches/Options/RoleSettingMenuPatches.cs
@@ -550,7 +550,6 @@ public static class RoleSettingMenuPatches
new Rect(0, 0, 370, 230),
Vector2.one / 2,
100);
- __instance.roleScreenshot.drawMode = SpriteDrawMode.Sliced;
}
__instance.roleHeaderSprite.color = customRole.OptionsMenuColor;
diff --git a/MiraAPI/Utilities/Assets/LoadableBundleSubAsset.cs b/MiraAPI/Utilities/Assets/LoadableBundleSubAsset.cs
new file mode 100644
index 0000000..ef7aea3
--- /dev/null
+++ b/MiraAPI/Utilities/Assets/LoadableBundleSubAsset.cs
@@ -0,0 +1,37 @@
+using System;
+using System.Linq;
+using UnityEngine;
+
+namespace MiraAPI.Utilities.Assets;
+
+///
+/// A utility class for loading multiple assets from an .
+///
+/// The name of the asset.
+/// The that contains the asset.
+public class LoadableBundleSubAsset(string name, LoadableBundleSubAssetHolder assetHolder) : LoadableAsset
+{
+ ///
+ /// Loads the asset from the .
+ ///
+ /// The asset.
+ /// The asset did not load properly.
+ 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;
+ }
+}
diff --git a/MiraAPI/Utilities/Assets/LoadableBundleSubAssetHolder.cs b/MiraAPI/Utilities/Assets/LoadableBundleSubAssetHolder.cs
new file mode 100644
index 0000000..1599398
--- /dev/null
+++ b/MiraAPI/Utilities/Assets/LoadableBundleSubAssetHolder.cs
@@ -0,0 +1,86 @@
+using System;
+using System.Linq;
+using HarmonyLib;
+using Il2CppInterop.Runtime;
+using Reactor.Utilities.Extensions;
+using UnityEngine;
+
+namespace MiraAPI.Utilities.Assets;
+
+///
+/// A utility class for loading multiple assets from an .
+///
+public class LoadableBundleSubAssetHolder
+{
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The name of the assets to pull from.
+ /// The that contains the assets.
+ public LoadableBundleSubAssetHolder(string[] names, AssetBundle bundle)
+ {
+ Bundle = bundle;
+ SpriteNames = names;
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The name of the asset.
+ /// The that contains the assets.
+ public LoadableBundleSubAssetHolder(string name, AssetBundle bundle)
+ {
+ Bundle = bundle;
+ SpriteNames = [name];
+ }
+ internal string[] SpriteNames = [];
+ internal AssetBundle Bundle;
+ public Sprite[] SubSprites = [];
+
+ public virtual void TryInit()
+ {
+ if (SubSprites.Length == 0)
+ {
+ var newSprites = Array.Empty();
+ 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();
+ if (img != null)
+ {
+ img.DontDestroy().DontUnload();
+ newSprites = newSprites.AddToArray(img);
+ }
+ }
+ }
+
+ SubSprites = newSprites;
+ }
+ }
+
+ ///
+ /// Unloads an asset.
+ ///
+ /// True if the asset was unloaded, false otherwise.
+ public bool UnloadAsset()
+ {
+ if (SubSprites.Length == 0)
+ {
+ return false;
+ }
+
+ foreach (var sprite in SubSprites)
+ {
+ sprite.DestroyImmediate();
+ }
+ SubSprites = [];
+ return true;
+ }
+}
diff --git a/MiraAPI/Utilities/Assets/TmpSpriteUtils.cs b/MiraAPI/Utilities/Assets/TmpSpriteUtils.cs
index 518e4ac..6160a01 100644
--- a/MiraAPI/Utilities/Assets/TmpSpriteUtils.cs
+++ b/MiraAPI/Utilities/Assets/TmpSpriteUtils.cs
@@ -71,8 +71,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),