using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Jotunn;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("MoreStacks")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("MoreStacks")]
[assembly: AssemblyCopyright("Copyright © 2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("e3243d22-4307-4008-ba36-9f326008cde5")]
[assembly: AssemblyFileVersion("1.0.3")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.3.0")]
namespace MoreStacks;
public class StackInfo
{
public string idStackToDuplicate { get; set; }
public string idStackMaterial { get; set; }
public Vector3 localScale { get; set; }
public StackInfo(string idStackToDuplicate, string idStackMaterial)
: this(idStackToDuplicate, idStackMaterial, Vector3.zero)
{
}//IL_0003: Unknown result type (might be due to invalid IL or missing references)
public StackInfo(string idStackToDuplicate, string idStackMaterial, float uniformScale)
: this(idStackToDuplicate, idStackMaterial, new Vector3(uniformScale, uniformScale, uniformScale))
{
}//IL_0006: Unknown result type (might be due to invalid IL or missing references)
public StackInfo(string idStackToDuplicate, string idStackMaterial, Vector3 localScale)
{
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
this.idStackToDuplicate = idStackToDuplicate;
this.idStackMaterial = idStackMaterial;
this.localScale = localScale;
}
}
[BepInPlugin("ujhik.MoreStacks", "MoreStacks", "1.0.3")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
internal class MoreStacks : BaseUnityPlugin
{
public const string PluginGUID = "ujhik.MoreStacks";
public const string PluginName = "MoreStacks";
public const string PluginVersion = "1.0.3";
private static bool firstExecution = false;
public List<StackInfo> stackInfoList = new List<StackInfo>();
private List<CustomPiece> renderSprites = new List<CustomPiece>();
private Harmony _harmony;
public static CustomLocalization Localization = LocalizationManager.Instance.GetLocalization();
private static ConfigEntry<bool> isSkipNight;
private static ConfigEntry<float> testingSlider1;
private static ConfigEntry<float> testingSlider2;
private static ConfigEntry<float> testingSlider3;
private static ConfigEntry<float> testingSlider4;
public static event Action OnPrefabsRegistered;
private void Awake()
{
_harmony = Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "ujhik.MoreStacks");
InitializeStacks();
PrefabManager.OnVanillaPrefabsAvailable += onVanillaPrefabsAvailable;
PieceManager.OnPiecesRegistered += OnPiecesRegistered;
}
private void InitializeStacks()
{
//IL_0120: Unknown result type (might be due to invalid IL or missing references)
//IL_0163: Unknown result type (might be due to invalid IL or missing references)
//IL_018c: Unknown result type (might be due to invalid IL or missing references)
//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
stackInfoList = new List<StackInfo>
{
new StackInfo("coal_pile", "CopperOre"),
new StackInfo("coal_pile", "IronOre"),
new StackInfo("coal_pile", "TinOre"),
new StackInfo("coal_pile", "SilverOre"),
new StackInfo("stone_pile", "FlametalOre"),
new StackInfo("stone_pile", "FlametalOreNew"),
new StackInfo("blackmarble_pile", "CopperScrap", 0.6f),
new StackInfo("blackmarble_pile", "BronzeScrap", 0.6f),
new StackInfo("blackmarble_pile", "IronScrap", 0.6f),
new StackInfo("blackmarble_pile", "BlackMetalScrap", 0.6f),
new StackInfo("blackmarble_pile", "Resin", 0.5f),
new StackInfo("stone_pile", "BeechSeeds", new Vector3(0.25f, 0.35f, 0.25f)),
new StackInfo("grausten_pile", "Flint", 0.5f),
new StackInfo("wood_fine_stack", "ElderBark", new Vector3(0.4f, 0.3f, 0.4f)),
new StackInfo("stone_pile", "GreydwarfEye", new Vector3(0.15f, 0.25f, 0.15f)),
new StackInfo("blackmarble_pile", "Honey", 0.5f),
new StackInfo("bone_stack", "WitheredBone", 1.5f),
new StackInfo("stone_pile", "Ooze", new Vector3(0.75f, 0.8f, 0.75f))
};
}
private void CreateConfigValues()
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
new ConfigurationManagerAttributes().IsAdminOnly = true;
new AcceptableValueRange<float>(0f, 1f);
new AcceptableValueRange<float>(0f, 1f);
}
private void OnDestroy()
{
Harmony harmony = _harmony;
if (harmony != null)
{
harmony.UnpatchSelf();
}
}
private void onVanillaPrefabsAvailable()
{
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
foreach (StackInfo stackInfo in stackInfoList)
{
generateNewStack(stackInfo.idStackToDuplicate, stackInfo.idStackMaterial, stackInfo.localScale);
}
}
public static string getStackName(string materialPrefabId)
{
return "MoreStacks_" + materialPrefabId + "_pile";
}
private void generateNewStack(string prefabToDuplicateId, string materialPrefabId)
{
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
generateNewStack(prefabToDuplicateId, materialPrefabId, getStackName(materialPrefabId), Vector3.zero);
}
private void generateNewStack(string prefabToDuplicateId, string materialPrefabId, float newLocalScale)
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
generateNewStack(prefabToDuplicateId, materialPrefabId, getStackName(materialPrefabId), new Vector3(newLocalScale, newLocalScale, newLocalScale));
}
private void generateNewStack(string prefabToDuplicateId, string materialPrefabId, Vector3 newLocalScale)
{
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
generateNewStack(prefabToDuplicateId, materialPrefabId, getStackName(materialPrefabId), newLocalScale);
}
private void generateNewStack(string prefabToDuplicateId, string materialPrefabId, string newStackId, Vector3 newLocalScale)
{
//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
//IL_00d6: Expected O, but got Unknown
//IL_0123: Unknown result type (might be due to invalid IL or missing references)
//IL_0129: Expected O, but got Unknown
//IL_0130: Unknown result type (might be due to invalid IL or missing references)
//IL_0137: Expected O, but got Unknown
//IL_0139: Unknown result type (might be due to invalid IL or missing references)
//IL_007d: Unknown result type (might be due to invalid IL or missing references)
//IL_0087: Expected O, but got Unknown
//IL_014b: Unknown result type (might be due to invalid IL or missing references)
GameObject prefab = PrefabManager.Instance.GetPrefab(prefabToDuplicateId);
if ((Object)(object)prefab == (Object)null)
{
Logger.LogError((object)("Prefab to duplicate not found!: " + prefabToDuplicateId));
}
else
{
if ((Object)(object)PrefabManager.Instance.GetPrefab(newStackId) != (Object)null)
{
return;
}
GameObject val = PrefabManager.Instance.CreateClonedPrefab(newStackId, prefab);
MeshRenderer componentInChildren = val.GetComponentInChildren<MeshRenderer>();
GameObject prefab2 = PrefabManager.Instance.GetPrefab(materialPrefabId);
if ((Object)(object)prefab2 != (Object)null)
{
MeshRenderer componentInChildren2 = prefab2.GetComponentInChildren<MeshRenderer>();
if ((Object)(object)componentInChildren2 != (Object)null)
{
((Renderer)componentInChildren).sharedMaterial = new Material(((Renderer)componentInChildren2).sharedMaterial);
Material sharedMaterial = ((Renderer)componentInChildren).sharedMaterial;
adjustMaterial(sharedMaterial, materialPrefabId);
}
else
{
Logger.LogError((object)"MeshRenderer not found!");
}
}
else
{
Logger.LogError((object)(materialPrefabId + " prefab not found!"));
}
string name = prefab2.GetComponent<ItemDrop>().m_itemData.m_shared.m_name;
PieceConfig val2 = new PieceConfig();
val2.Name = name + " Pile";
val2.Description = "A pile of " + name;
val2.PieceTable = "Hammer";
val2.Category = "Misc";
val2.Requirements = (RequirementConfig[])(object)new RequirementConfig[1]
{
new RequirementConfig(materialPrefabId, 50, 0, true)
};
CustomPiece val3 = new CustomPiece(val, true, val2);
if (!((Vector3)(ref newLocalScale)).Equals(Vector3.zero))
{
val.transform.localScale = newLocalScale;
changeCullingDistanceLOD(val);
}
PieceManager.Instance.AddPiece(val3);
renderSprites.Add(val3);
}
}
private static void logMaterialProperties(Material material)
{
Logger.LogError((object)("Material: " + ((Object)material).name + ": Shader Name: " + ((Object)material.shader).name));
for (int i = 0; i < material.shader.GetPropertyCount(); i++)
{
string propertyName = material.shader.GetPropertyName(i);
Logger.LogError((object)("Property: " + propertyName));
}
}
private static void changeCullingDistanceLOD(GameObject gameObject)
{
float newScreenRelativeTransitionHeight = 0.01f;
changeCullingDistanceLOD(gameObject, newScreenRelativeTransitionHeight);
}
private static void changeCullingDistanceLOD(GameObject gameObject, float newScreenRelativeTransitionHeight)
{
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
LODGroup val = gameObject.GetComponentInChildren<LODGroup>();
Renderer componentInChildren = gameObject.GetComponentInChildren<Renderer>();
if ((Object)(object)val == (Object)null)
{
val = gameObject.AddComponent<LODGroup>();
val.SetLODs((LOD[])(object)new LOD[1]
{
new LOD(0.1f, (Renderer[])(object)new Renderer[1] { componentInChildren })
});
}
gameObject.SetActive(true);
LOD[] lODs = val.GetLODs();
lODs[^1].screenRelativeTransitionHeight = newScreenRelativeTransitionHeight;
lODs[^1].renderers = (Renderer[])(object)new Renderer[1] { componentInChildren };
val.SetLODs(lODs);
val.RecalculateBounds();
}
private static void logGameobject(GameObject gameObject)
{
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
//IL_004b: Expected O, but got Unknown
string name = ((Object)gameObject).name;
Transform parent = gameObject.transform.parent;
Logger.LogInfo((object)("Logging gameobject: " + name + " from: " + ((parent != null) ? ((Object)parent).name : null)));
foreach (Transform item in gameObject.transform)
{
Transform val = item;
Logger.LogInfo((object)$"{((Object)gameObject).name} Child: {((Object)val).name} type: {((object)val).GetType()}");
logGameobject(((Component)val).gameObject);
}
}
private void LogLodAndRenderer(GameObject original, GameObject clone)
{
LODGroup component = original.GetComponent<LODGroup>();
LODGroup component2 = clone.GetComponent<LODGroup>();
Renderer componentInChildren = original.GetComponentInChildren<Renderer>();
Renderer componentInChildren2 = clone.GetComponentInChildren<Renderer>();
MeshRenderer componentInChildren3 = original.GetComponentInChildren<MeshRenderer>();
MeshRenderer componentInChildren4 = clone.GetComponentInChildren<MeshRenderer>();
MeshFilter componentInChildren5 = original.GetComponentInChildren<MeshFilter>();
MeshFilter componentInChildren6 = clone.GetComponentInChildren<MeshFilter>();
Logger.LogError((object)$"Original LODGroup: {((component != null) ? new int?(((Object)component).GetInstanceID()) : null)} | Clone LODGroup: {((component2 != null) ? new int?(((Object)component2).GetInstanceID()) : null)}");
Logger.LogError((object)$"Same LODGroup? {(Object)(object)component == (Object)(object)component2}");
Logger.LogError((object)$"Original Renderer: {((componentInChildren != null) ? new int?(((Object)componentInChildren).GetInstanceID()) : null)} | Clone Renderer: {((componentInChildren2 != null) ? new int?(((Object)componentInChildren2).GetInstanceID()) : null)}");
Logger.LogError((object)$"Same Renderer? {(Object)(object)componentInChildren == (Object)(object)componentInChildren2}");
Logger.LogError((object)$"Original MeshRenderer: {((componentInChildren3 != null) ? new int?(((Object)componentInChildren3).GetInstanceID()) : null)} | Clone Renderer: {((componentInChildren4 != null) ? new int?(((Object)componentInChildren4).GetInstanceID()) : null)}");
Logger.LogError((object)$"Same MeshRenderer? {(Object)(object)componentInChildren3 == (Object)(object)componentInChildren4}");
Logger.LogError((object)$"Original MeshFilter: {((componentInChildren5 != null) ? new int?(((Object)componentInChildren5).GetInstanceID()) : null)} | Clone MeshFilter: {((componentInChildren6 != null) ? new int?(((Object)componentInChildren6).GetInstanceID()) : null)}");
Logger.LogError((object)$"Same MeshFilter? {((componentInChildren5 != null) ? new int?(((Object)componentInChildren5).GetInstanceID()) : null) == ((componentInChildren6 != null) ? new int?(((Object)componentInChildren6).GetInstanceID()) : null)}");
Logger.LogError((object)("Original Renderer name: " + ((componentInChildren != null) ? ((Object)componentInChildren).name : null) + " | Clone Renderer name: " + ((componentInChildren2 != null) ? ((Object)componentInChildren2).name : null)));
Component[] components = original.GetComponents<Component>();
for (int i = 0; i < components.Length; i++)
{
Debug.Log((object)((object)components[i]).GetType().Name);
}
}
private void adjustMaterial(Material material, string materialPrefabId)
{
//IL_03eb: Unknown result type (might be due to invalid IL or missing references)
//IL_0405: Unknown result type (might be due to invalid IL or missing references)
//IL_028c: Unknown result type (might be due to invalid IL or missing references)
//IL_0291: Unknown result type (might be due to invalid IL or missing references)
//IL_0298: Unknown result type (might be due to invalid IL or missing references)
//IL_029e: Unknown result type (might be due to invalid IL or missing references)
//IL_02a4: Unknown result type (might be due to invalid IL or missing references)
//IL_02af: Unknown result type (might be due to invalid IL or missing references)
//IL_032a: Unknown result type (might be due to invalid IL or missing references)
//IL_0344: Unknown result type (might be due to invalid IL or missing references)
//IL_02e5: Unknown result type (might be due to invalid IL or missing references)
//IL_02ff: Unknown result type (might be due to invalid IL or missing references)
//IL_03a9: Unknown result type (might be due to invalid IL or missing references)
//IL_03c3: Unknown result type (might be due to invalid IL or missing references)
//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
//IL_0224: Unknown result type (might be due to invalid IL or missing references)
switch (materialPrefabId)
{
case "FlametalOreNew":
break;
case "TinOre":
if (material.HasProperty("_Glossiness"))
{
material.SetFloat("_Glossiness", 0.5f);
}
if (material.HasProperty("_Metallic"))
{
material.SetFloat("_Metallic", 0.5f);
}
if (material.HasProperty("_MetalGloss"))
{
material.SetFloat("_MetalGloss", 1f);
}
if (material.HasProperty("_UseGlossMap"))
{
material.SetFloat("_UseGlossMap", 1f);
}
break;
case "SilverOre":
if (material.HasProperty("_Glossiness"))
{
material.SetFloat("_Glossiness", 0.9f);
}
if (material.HasProperty("_Metallic"))
{
material.SetFloat("_Metallic", 0.6f);
}
if (material.HasProperty("_MetalGloss"))
{
material.SetFloat("_MetalGloss", 1f);
}
if (material.HasProperty("_UseGlossMap"))
{
material.SetFloat("_UseGlossMap", 1f);
}
if (material.HasProperty("_Color"))
{
material.SetColor("_Color", new Color(1.3f, 1.3f, 1.3f));
}
if (material.HasProperty("_EmissionColor"))
{
material.SetColor("_EmissionColor", new Color(0.01f, 0.01f, 0.01f));
}
break;
case "Resin":
material.SetFloat("_Mode", 3f);
material.SetInt("_SrcBlend", 5);
material.SetInt("_DstBlend", 10);
material.DisableKeyword("_ALPHATEST_ON");
material.EnableKeyword("_ALPHABLEND_ON");
material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
if (material.HasProperty("_Color"))
{
Color color = material.GetColor("_Color");
material.SetColor("_Color", new Color(color.r, color.g, color.b, 0.9f));
}
material.renderQueue = 3000;
break;
case "BeechSeeds":
if (material.HasProperty("_MainTex"))
{
material.SetTextureScale("_MainTex", new Vector2(0.7f, 1.5f));
material.SetTextureOffset("_MainTex", new Vector2(0.75f, 0.75f));
}
break;
case "ElderBark":
if (material.HasProperty("_MainTex"))
{
material.SetTextureScale("_MainTex", new Vector2(1.12f, 0.75f));
material.SetTextureOffset("_MainTex", new Vector2(0.67f, 0.14f));
}
break;
case "Honey":
if (material.HasProperty("_Glossiness"))
{
material.SetFloat("_Glossiness", 0.9f);
}
if (material.HasProperty("_Metallic"))
{
material.SetFloat("_Metallic", 0.3f);
}
if (material.HasProperty("_MainTex"))
{
material.SetTextureScale("_MainTex", new Vector2(0.4f, 0.34f));
material.SetTextureOffset("_MainTex", new Vector2(0f, 0.05f));
}
break;
case "LeatherScraps":
if (material.HasProperty("_MainTex"))
{
material.SetTextureScale("_MainTex", new Vector2(0.69f, 0.82f));
material.SetTextureOffset("_MainTex", new Vector2(0.21f, 0.3f));
}
if (material.HasProperty("_Cutoff"))
{
material.SetFloat("_Cutoff", 0.001f);
}
break;
}
}
private void OnPiecesRegistered()
{
PieceManager.OnPiecesRegistered -= OnPiecesRegistered;
foreach (CustomPiece renderSprite in renderSprites)
{
((MonoBehaviour)this).StartCoroutine(RenderSprite(renderSprite));
}
}
private IEnumerator RenderSprite(CustomPiece piece)
{
yield return null;
piece.Piece.m_icon = RenderManager.Instance.Render(new RenderRequest(piece.PiecePrefab)
{
Width = 64,
Height = 64,
Rotation = RenderManager.IsometricRotation * Quaternion.Euler(0f, -45f, 0f),
UseCache = false,
TargetPlugin = ((BaseUnityPlugin)this).Info.Metadata
});
}
private static void LogAllLODGroups()
{
LODGroup[] array = Object.FindObjectsOfType<LODGroup>();
Debug.Log((object)$"[LOD Logger] Found {array.Length} LODGroups in the scene.");
LODGroup[] array2 = array;
foreach (LODGroup val in array2)
{
if ((!((Object)(object)((Component)val).gameObject != (Object)null) || !((Object)((Component)val).gameObject).name.Contains("OreStacks_Honey_pile")) && !((Object)((Component)val).gameObject).name.Contains("New"))
{
continue;
}
GameObject gameObject = ((Component)val).gameObject;
Debug.Log((object)("[LOD Logger] LODGroup on '" + ((gameObject != null) ? ((Object)gameObject).name : null) + "':"));
LOD[] lODs = val.GetLODs();
int num = 0;
while (lODs != null && num < lODs.Length)
{
Debug.Log((object)$" LOD {num}: Screen Relative Transition Height = {lODs[num].screenRelativeTransitionHeight}");
Renderer[] renderers = lODs[num].renderers;
foreach (Renderer val2 in renderers)
{
object arg = ((val2 != null) ? new int?(((Object)val2).GetInstanceID()) : null);
object arg2;
if (val2 == null)
{
arg2 = null;
}
else
{
GameObject gameObject2 = ((Component)val2).gameObject;
arg2 = ((gameObject2 != null) ? ((Object)gameObject2).name : null);
}
Debug.Log((object)$" Renderer ID: {arg} | Object: {arg2}");
int? obj;
if (val2 == null)
{
obj = null;
}
else
{
GameObject gameObject3 = ((Component)val2).gameObject;
obj = ((gameObject3 != null) ? new int?(((Object)gameObject3).GetInstanceID()) : null);
}
object arg3 = obj;
object arg4;
if (val2 == null)
{
arg4 = null;
}
else
{
GameObject gameObject4 = ((Component)val2).gameObject;
arg4 = ((gameObject4 != null) ? ((Object)gameObject4).name : null);
}
Debug.Log((object)$" Owner of Renderer ID : {arg3} | Object: {arg4}");
object obj2;
if (val2 == null)
{
obj2 = null;
}
else
{
Transform transform = ((Component)val2).transform;
obj2 = ((transform != null) ? transform.parent : null);
}
Transform val3 = (Transform)obj2;
if ((Object)(object)val3 != (Object)null)
{
GameObject gameObject5 = ((Component)val3).gameObject;
object arg5 = ((gameObject5 != null) ? new int?(((Object)gameObject5).GetInstanceID()) : null);
GameObject gameObject6 = ((Component)val3).gameObject;
Debug.Log((object)$" Parent Object ID: {arg5} | Object: {((gameObject6 != null) ? ((Object)gameObject6).name : null)}");
Debug.Log((object)$" Parent is a Component: {((object)((Component)val3).gameObject)?.GetType()}");
Transform val4 = ((val3 != null) ? val3.parent : null);
if ((Object)(object)val4 != (Object)null)
{
GameObject gameObject7 = ((Component)val4).gameObject;
object arg6 = ((gameObject7 != null) ? new int?(((Object)gameObject7).GetInstanceID()) : null);
GameObject gameObject8 = ((Component)val4).gameObject;
Debug.Log((object)$" Grandparent Object ID: {arg6} | Object: {((gameObject8 != null) ? ((Object)gameObject8).name : null)}");
}
}
}
num++;
}
}
}
}