Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added Mods/RespriteHero.dll
Binary file not shown.
Binary file added RespriteHero.zip
Binary file not shown.
7 changes: 3 additions & 4 deletions RespriteHero/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using MelonLoader;

Expand All @@ -14,7 +13,7 @@
[assembly: AssemblyCopyright("Copyright © 2022")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: MelonInfo(typeof(RespriteHero.RespriteHero), "RespriteHero", "0.3.0", "Ignacio Zevallos")]
[assembly: MelonInfo(typeof(RespriteHero.RespriteHero), "RespriteHero", "0.3.2", "Ignacio Zevallos")]
[assembly: MelonGame("TheJaspel", "Backpack Hero")]

// Setting ComVisible to false makes the types in this assembly not visible
Expand All @@ -35,5 +34,5 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("0.3.0")]
[assembly: AssemblyFileVersion("0.3.0")]
[assembly: AssemblyVersion("0.3.2")]
[assembly: AssemblyFileVersion("0.3.2")]
136 changes: 63 additions & 73 deletions RespriteHero/RespriteHero.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,42 +4,26 @@
using System.IO;
using UnityEngine;
using System.Linq;
using System;

namespace RespriteHero {

public class RespriteHero : MelonMod {
public static string TEXTURE_DIRECTORY = "/../ModConfig/RespriteHero/";
//Cache of all the used sprites
public static Dictionary<string, Sprite> SPRITE_CACHE = new Dictionary<string, Sprite>();
//Cache of all unused sprites, so we don't have to call
//IO operations every time we want to use a sprite
public static List<string> UNUSED_CACHE = new List<string>();
public static string TEXTURE_DIRECTORY = @"\ModConfig\RespriteHero\";

public override void OnApplicationLateStart() {
LoggerInstance.Msg("Texture Pack Mod Initialized");

UnityEngine.SceneManagement.SceneManager.sceneLoaded += OnSceneLoad;
string path = Application.dataPath + TEXTURE_DIRECTORY;
if (!Directory.Exists(path)) {
LoggerInstance.Msg("ModConfig/RespriteHero folder doesn't exist. Creating one...");
Directory.CreateDirectory(path);
}
}

public static Sprite LoadPNGCache(string filePath, Item2 item) {
if (SPRITE_CACHE.ContainsKey(filePath)) {
return SPRITE_CACHE[filePath];
}
else {
Sprite sprite = LoadPNG(filePath, item);
SPRITE_CACHE.Add(filePath, sprite);
return sprite;
}
}

public static Sprite LoadPNG(string filePath, Item2 item) {
Texture2D tex = null;
byte[] fileData;

float PPU = 16f;

if (File.Exists(filePath)) {
Expand All @@ -65,13 +49,15 @@ public static Sprite LoadPNG(string filePath, Item2 item) {

if (PPU % 2 != 0)
PPU += 1;
else if (PPU == 0)
return null;

return Sprite.Create(
tex,
new Rect(0, 0, tex.width, tex.height),
new Vector2(0.5f, 0.5f),
PPU, //Calculated value based on image dimensions and item size
0,
0,
SpriteMeshType.FullRect
);
}
Expand All @@ -81,70 +67,74 @@ public static int[] _BPTGetGridBounds(List<BoxCollider2D> colliders, Item2 item)
Vector2 max = new Vector2 { x = 0, y = 0 };
Vector2 min = new Vector2 { x = 0, y = 0 };
if (colliders.Count > 0) {

foreach (BoxCollider2D collider in colliders) {
max.x = collider.bounds.max.x + collider.offset.x - item.gameObject.transform.position.x;
max.y = collider.bounds.max.y + collider.offset.y - item.gameObject.transform.position.y;
min.x = collider.bounds.min.x + collider.offset.x - item.gameObject.transform.position.x;
min.y = collider.bounds.min.y + collider.offset.y - item.gameObject.transform.position.y;
max.x = collider.size.x/2 + collider.offset.x - item.gameObject.transform.position.x;
max.y = collider.size.y/2 + collider.offset.y - item.gameObject.transform.position.y;
min.x = -collider.size.x/2 + collider.offset.x - item.gameObject.transform.position.x;
min.y = -collider.size.y/2 + collider.offset.y - item.gameObject.transform.position.y;
}
}
gridNum[0] = Mathf.RoundToInt(Mathf.Abs(max.x) + Mathf.Abs(min.x));
gridNum[1] = Mathf.RoundToInt(Mathf.Abs(max.y) + Mathf.Abs(min.y));

gridNum[0] = Mathf.RoundToInt(Mathf.Clamp(Mathf.Abs(max.x) + Mathf.Abs(min.x), 1, Mathf.Infinity));
gridNum[1] = Mathf.RoundToInt(Mathf.Clamp(Mathf.Abs(max.y) + Mathf.Abs(min.y), 1, Mathf.Infinity));

return gridNum;
}
}

//Every time an item is instantiated:
//Checks if the sprite exists in the cache
//If not, check if the expr
//This is not very efficient. But performance doesn't matter in
//the current context
[HarmonyPatch(typeof(Item2), "Start")]
class Item2_Start_Patch {
static void Postfix(ref Item2 __instance) {
string name = __instance.gameObject.name;
name = name.Replace("(Clone)", "");
name = name.Replace("Variant", "");
name = name.Replace("variant", "");
name = name.Trim();
string filename;

ItemSpriteChanger itemSpriteChanger = __instance.GetComponent<ItemSpriteChanger>();
if (itemSpriteChanger != null) {
List<Sprite> sprites = typeof(ItemSpriteChanger).GetField(
"sprites",
System.Reflection.BindingFlags.NonPublic |
System.Reflection.BindingFlags.Instance
).GetValue(itemSpriteChanger) as List<Sprite>;

for (int i = 0; i < sprites.Count; i++) {
filename = Application.dataPath + RespriteHero.TEXTURE_DIRECTORY + name + "_" + i + ".png";
MelonLogger.Msg($"[ItemSpriteChanger]: Opening filename[{filename}]");

if (RespriteHero.SPRITE_CACHE.ContainsKey(filename) || File.Exists(filename)) {
Sprite newSprite = RespriteHero.LoadPNGCache(filename, __instance);
sprites[i] = newSprite;
void OnSceneLoad(UnityEngine.SceneManagement.Scene scene, UnityEngine.SceneManagement.LoadSceneMode scenemode) {
if (scene.name == "Game") {
List<GameObject> prefabs = GameObject.FindObjectOfType<GameManager>().defaultItems;
List<string> files = Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory + TEXTURE_DIRECTORY).ToList<string>();
GameObject item = null;
foreach (string file in files) {
string[] split0 = file.Split(@"\".ToCharArray());
string itemName = split0[split0.Length - 1].Replace(".png", "").Trim();
if (file.Contains("_")) {
split0 = file.Split(@"\".ToCharArray());
string[] split1 = split0[split0.Length - 1].Split('_');
split1[1] = split1[1].Replace(".png", "").Trim();
itemName = split1[0];
if (file.Contains("Variant"))
item = prefabs.Find(x => x.name.Replace("Variant", "").Replace("variant", "").Replace("1", "").Trim() + " Variant" == itemName);
else
item = prefabs.Find(x => x.name.Replace("Variant", "").Replace("variant", "").Replace("1", "").Trim() == itemName && !x.name.Contains("Variant Variant"));
ItemSpriteChanger itemSpriteChanger = item.GetComponent<ItemSpriteChanger>();
if (itemSpriteChanger != null) {
List<Sprite> sprites = typeof(ItemSpriteChanger).GetField(
"sprites",
System.Reflection.BindingFlags.NonPublic |
System.Reflection.BindingFlags.Instance
).GetValue(itemSpriteChanger) as List<Sprite>;

Sprite newSprite = RespriteHero.LoadPNG(file, item.GetComponent<Item2>());
if (newSprite != null) {
int index;
if (int.TryParse(split1[1], out index)) {
sprites[index] = newSprite;
if (index == 0) {
item.GetComponent<SpriteRenderer>().sprite = newSprite;
item.GetComponent<SpriteRenderer>().material.mainTexture = newSprite.texture;
}
}
}
}
}
else {
RespriteHero.UNUSED_CACHE.Add(filename);
if (itemName.Contains("Variant")) {
item = prefabs.Find(x => x.name.Replace("Variant", "").Replace("variant", "").Replace("1", "").Trim() + " Variant" == itemName);
}
else {
item = prefabs.Find(x => x.name.Replace("Variant", "").Replace("variant", "").Replace("1", "").Trim() == itemName && !x.name.Contains("Variant Variant"));
}
if (item != null) {
Sprite newSprite = LoadPNG(file, item.GetComponent<Item2>());
if (newSprite != null) {
item.GetComponent<SpriteRenderer>().sprite = newSprite;
item.GetComponent<SpriteRenderer>().material.mainTexture = newSprite.texture;
}
}
}
}

return;
}

filename = Application.dataPath + RespriteHero.TEXTURE_DIRECTORY + name + ".png";

if (RespriteHero.SPRITE_CACHE.ContainsKey(filename) || File.Exists(filename)) {
MelonLogger.Msg($"[SpriteRenderer]: Opening filename[{filename}]");
Sprite newSprite = RespriteHero.LoadPNGCache(filename, __instance);
SpriteRenderer spriteRenderer = __instance.gameObject.GetComponent<SpriteRenderer>();
spriteRenderer.sprite = newSprite;
}
else {
RespriteHero.UNUSED_CACHE.Add(filename);
}
}
}
Expand Down
18 changes: 9 additions & 9 deletions RespriteHero/RespriteHero.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -43,44 +43,44 @@
<ItemGroup>
<Reference Include="0Harmony, Version=2.0.2.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>E:\SteamLibrary\steamapps\common\Backpack Hero\MelonLoader\0Harmony.dll</HintPath>
<HintPath>..\..\..\..\..\..\..\Programs\Steam\steamapps\common\Backpack Hero\MelonLoader\0Harmony.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="Assembly-CSharp">
<HintPath>E:\SteamLibrary\steamapps\common\Backpack Hero\Backpack Hero_Data\Managed\Assembly-CSharp.dll</HintPath>
<HintPath>..\..\..\..\..\..\..\Programs\Steam\steamapps\common\Backpack Hero\Backpack Hero_Data\Managed\Assembly-CSharp.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="MelonLoader">
<HintPath>E:\SteamLibrary\steamapps\common\Backpack Hero\MelonLoader\MelonLoader.dll</HintPath>
<HintPath>..\..\..\..\..\..\..\Programs\Steam\steamapps\common\Backpack Hero\MelonLoader\MelonLoader.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<Reference Include="Unity.TextMeshPro, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>E:\SteamLibrary\steamapps\common\Backpack Hero\Backpack Hero_Data\Managed\Unity.TextMeshPro.dll</HintPath>
<HintPath>..\..\..\..\..\..\..\Programs\Steam\steamapps\common\Backpack Hero\Backpack Hero_Data\Managed\Unity.TextMeshPro.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="UnityEngine">
<HintPath>E:\SteamLibrary\steamapps\common\Backpack Hero\Backpack Hero_Data\Managed\UnityEngine.dll</HintPath>
<HintPath>..\..\..\..\..\..\..\Programs\Steam\steamapps\common\Backpack Hero\Backpack Hero_Data\Managed\UnityEngine.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="UnityEngine.ImageConversionModule">
<HintPath>E:\SteamLibrary\steamapps\common\Backpack Hero\Backpack Hero_Data\Managed\UnityEngine.ImageConversionModule.dll</HintPath>
<HintPath>..\..\..\..\..\..\..\Programs\Steam\steamapps\common\Backpack Hero\Backpack Hero_Data\Managed\UnityEngine.ImageConversionModule.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="UnityEngine.CoreModule">
<HintPath>E:\SteamLibrary\steamapps\common\Backpack Hero\Backpack Hero_Data\Managed\UnityEngine.CoreModule.dll</HintPath>
<HintPath>..\..\..\..\..\..\..\Programs\Steam\steamapps\common\Backpack Hero\Backpack Hero_Data\Managed\UnityEngine.CoreModule.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="UnityEngine.Physics2DModule">
<HintPath>E:\SteamLibrary\steamapps\common\Backpack Hero\Backpack Hero_Data\Managed\UnityEngine.Physics2DModule.dll</HintPath>
<HintPath>..\..\..\..\..\..\..\Programs\Steam\steamapps\common\Backpack Hero\Backpack Hero_Data\Managed\UnityEngine.Physics2DModule.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="RespriteHero.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
</Project>
Binary file added RespriteHero/RespriteHero.dll
Binary file not shown.