Decompiled source of DynamicStoragePiles IngotExpansion v1.0.9

BepInEx/plugins/DynamicStoragePiles-IngotExpansion/DynamicStoragePiles-IngotExpansion.dll

Decompiled 2 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using DynamicStoragePiles.Compatibility;
using HarmonyLib;
using Jotunn;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("DynamicStoragePiles")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("DynamicStoragePiles")]
[assembly: AssemblyCopyright("Copyright ©  2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("e3243d22-4307-4008-ba36-9f326008cde5")]
[assembly: AssemblyFileVersion("0.8.1")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.8.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace DynamicStoragePiles
{
	public static class ConfigSettings
	{
		public enum RecipeSetting
		{
			AllStoragePiles,
			OnlyDynamicStoragePiles,
			OnlyOriginalStoragePiles
		}

		private static ConfigFile config;

		public static ConfigEntry<bool> azuAutoStoreCompat;

		public static ConfigEntry<bool> azuAutoStoreItemWhitelist;

		public static ConfigEntry<bool> restrictDynamicPiles;

		public static ConfigEntry<RecipeSetting> VanillaRecipeSetting { get; private set; }

		public static ConfigEntry<RecipeSetting> IngotStacksRecipeSetting { get; private set; }

		public static ConfigEntry<RecipeSetting> StackedBarsRecipeSetting { get; private set; }

		public static ConfigEntry<RecipeSetting> MoreStacksRecipeSetting { get; private set; }

		public static ConfigEntry<RecipeSetting> RefinedStonePiecesSetting { get; private set; }

		public static void Init(ConfigFile configFile)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Expected O, but got Unknown
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Expected O, but got Unknown
			config = configFile;
			ConfigurationManagerAttributes val = new ConfigurationManagerAttributes
			{
				IsAdminOnly = true
			};
			string text = "\nCheats or world modifiers can ignore this setting. Existing pieces in the world are not affected";
			string text2 = "\nRequires a restart to take effect";
			string text3 = "1 - General";
			VanillaRecipeSetting = config.Bind<RecipeSetting>(text3, "Vanilla Stack Recipes", RecipeSetting.AllStoragePiles, "Sets which pieces are placeable." + text);
			VanillaRecipeSetting.SettingChanged += delegate
			{
				DynamicStoragePiles.UpdateAllRecipes();
			};
			restrictDynamicPiles = config.Bind<bool>(text3, "Restrict Container Item Type", true, new ConfigDescription("Only allows the respective items to be stored in stack piles, so wood piles only accept wood etc.\nSynced with server", (AcceptableValueBase)null, new object[1] { val }));
			text3 = "2.0 - Compatibility AzuAutoStore";
			azuAutoStoreCompat = config.Bind<bool>(text3, "Enable Compatibility", true, "Enables compatibility with AzuAutoStore." + text2);
			azuAutoStoreItemWhitelist = config.Bind<bool>(text3, "Enable Item Whitelist", true, "Only allows the respective items to be stored in stack piles");
			text3 = "2.1 - Compatibility IngotStacks";
			IngotStacksRecipeSetting = config.Bind<RecipeSetting>(text3, "IngotStacks Stack Recipes", RecipeSetting.AllStoragePiles, "Sets which pieces are placeable." + text);
			IngotStacksRecipeSetting.SettingChanged += delegate
			{
				DynamicStoragePiles.UpdateAllRecipes();
			};
			text3 = "2.2 - Compatibility StackedBars";
			StackedBarsRecipeSetting = config.Bind<RecipeSetting>(text3, "StackedBars Stack Recipes", RecipeSetting.AllStoragePiles, "Sets which pieces are placeable." + text);
			StackedBarsRecipeSetting.SettingChanged += delegate
			{
				DynamicStoragePiles.UpdateAllRecipes();
			};
			text3 = "2.3 - Compatibility MoreStacks";
			MoreStacksRecipeSetting = config.Bind<RecipeSetting>(text3, "MoreStacks Stack Recipes", RecipeSetting.AllStoragePiles, "Sets which pieces are placeable." + text);
			MoreStacksRecipeSetting.SettingChanged += delegate
			{
				DynamicStoragePiles.UpdateAllRecipes();
			};
			text3 = "2.4 - Compatibility RefinedStonePieces";
			RefinedStonePiecesSetting = config.Bind<RecipeSetting>(text3, "RefinedStonePieces Stack Recipes", RecipeSetting.AllStoragePiles, "Sets which pieces are placeable." + text);
			RefinedStonePiecesSetting.SettingChanged += delegate
			{
				DynamicStoragePiles.UpdateAllRecipes();
			};
		}

		public static bool IsEnabled(this ConfigEntry<RecipeSetting> configEntry, bool isOriginal)
		{
			if (isOriginal)
			{
				if (configEntry.Value != RecipeSetting.AllStoragePiles)
				{
					return configEntry.Value == RecipeSetting.OnlyOriginalStoragePiles;
				}
				return true;
			}
			if (configEntry.Value != RecipeSetting.AllStoragePiles)
			{
				return configEntry.Value == RecipeSetting.OnlyDynamicStoragePiles;
			}
			return true;
		}
	}
	[BepInPlugin("com.maxsch.valheim.DynamicStoragePiles", "DynamicStoragePiles + IngotStacks", "0.8.1-IngotStacks")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	internal class DynamicStoragePiles : BaseUnityPlugin
	{
		public const string PluginName = "DynamicStoragePiles";

		public const string PluginGuid = "com.maxsch.valheim.DynamicStoragePiles";

		public const string PluginVersion = "0.8.1-IngotStacks";

		public const string PLUGIN_MORESTACKS_GUID = "ujhik.MoreStacks";

		public static Harmony harmony;

		private static AssetBundle assetBundle;

		private List<CustomPiece> renderSprites = new List<CustomPiece>();

		public static Dictionary<string, string> allowedItemsByStack = new Dictionary<string, string>();

		public static Dictionary<string, string> allowedItemsByContainer = new Dictionary<string, string>();

		private static List<string> vanillaStacks = new List<string>
		{
			"wood_stack", "wood_fine_stack", "wood_core_stack", "wood_yggdrasil_stack", "blackwood_stack", "stone_pile", "coal_pile", "blackmarble_pile", "grausten_pile", "skull_pile",
			"treasure_stack", "bone_stack"
		};

		private static List<string> dynamicStacks = new List<string>();

		public static DynamicStoragePiles Instance { get; private set; }

		private void Awake()
		{
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Expected O, but got Unknown
			Instance = this;
			assetBundle = AssetUtils.LoadAssetBundleFromResources("containerstacks");
			AddStackPiece("MS_container_wood_stack", "Wood");
			AddStackPiece("MS_container_finewood_stack", "FineWood");
			AddStackPiece("MS_container_corewood_stack", "RoundLog");
			AddStackPiece("MS_container_yggdrasil_wood_stack", "YggdrasilWood");
			AddStackPiece("MS_container_blackwood_stack", "Blackwood");
			AddStackPiece("MS_container_stone_pile", "Stone");
			AddStackPiece("MS_container_coal_pile", "Coal");
			AddStackPiece("MS_container_blackmarble_pile", "BlackMarble");
			AddStackPiece("MS_container_grausten_pile", "Grausten");
			AddStackPiece("MS_container_skull_pile", "Charredskull");
			AddStackPiece("MS_container_bone_stack", "BoneFragments");
			AddStackPiece("MS_container_coin_pile", "Coins");
			ConfigSettings.Init(((BaseUnityPlugin)this).Config);
			PrefabManager.OnPrefabsRegistered += OnPrefabsRegistered;
			PieceManager.OnPiecesRegistered += OnPiecesRegistered;
			harmony = new Harmony("com.maxsch.valheim.DynamicStoragePiles");
			harmony.PatchAll();
		}

		private void Start()
		{
			if (Chainloader.PluginInfos.ContainsKey("Azumatt.AzuAutoStore") && ConfigSettings.azuAutoStoreCompat.Value)
			{
				AzuAutoStore.Init();
			}
			IngotStacks.Init();
			if (Chainloader.PluginInfos.ContainsKey("Azumatt.StackedBars"))
			{
				StackedBars.Init();
			}
			if (Chainloader.PluginInfos.ContainsKey("blacks7ar.RefinedStonePieces"))
			{
				RefinedStonePieces.Init();
			}
		}

		public static void UpdateAllRecipes()
		{
			if ((Object)(object)ZNetScene.instance != (Object)null)
			{
				UpdateRecipes(vanillaStacks, dynamicStacks, ConfigSettings.VanillaRecipeSetting);
				UpdateRecipes(IngotStacks.ingotStacks, IngotStacks.dynamicIngotStacks, ConfigSettings.IngotStacksRecipeSetting);
				UpdateRecipes(StackedBars.stackedBars, StackedBars.dynamicStackedBars, ConfigSettings.StackedBarsRecipeSetting);
				UpdateRecipes(MoreStacks.staticStacks, MoreStacks.dynamicStacks, ConfigSettings.MoreStacksRecipeSetting);
				UpdateRecipes(RefinedStonePieces.staticStacks, RefinedStonePieces.dynamicStacks, ConfigSettings.RefinedStonePiecesSetting);
			}
		}

		private static void UpdateRecipes(List<string> originalStackNames, List<string> dynamicStackNames, ConfigEntry<ConfigSettings.RecipeSetting> config)
		{
			foreach (string originalStackName in originalStackNames)
			{
				EnablePieceRecipes(originalStackName, config.IsEnabled(isOriginal: true));
			}
			foreach (string dynamicStackName in dynamicStackNames)
			{
				EnablePieceRecipes(dynamicStackName, config.IsEnabled(isOriginal: false));
			}
		}

		public static void EnablePieceRecipes(string prefabName, bool enabled)
		{
			GameObject prefab = ZNetScene.instance.GetPrefab(prefabName);
			Piece val = default(Piece);
			if ((Object)(object)prefab != (Object)null && prefab.TryGetComponent<Piece>(ref val))
			{
				val.m_enabled = enabled;
			}
			else
			{
				Logger.LogWarning((object)("Could not find Piece " + prefabName + " to toggle recipes"));
			}
		}

		private void AddStackPiece(string pieceName, string craftItem)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			CustomPiece val = new CustomPiece(assetBundle, pieceName, true, StackConfig(craftItem, 10));
			renderSprites.Add(val);
			dynamicStacks.Add(pieceName);
			AddPiece(val, craftItem);
		}

		public void AddCompatPiece(GameObject prefab, string craftItem, int amount)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			CustomPiece piece = new CustomPiece(prefab, false, StackConfig(craftItem, amount));
			AddPiece(piece, craftItem);
		}

		public void AddCompatPiece(GameObject prefab, string craftItem, int amount, bool addGraphics)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			CustomPiece val = new CustomPiece(prefab, true, StackConfig(craftItem, amount));
			if (addGraphics)
			{
				renderSprites.Add(val);
			}
			AddPiece(val, craftItem);
		}

		private void AddPiece(CustomPiece piece, string craftItem)
		{
			PieceManager.Instance.AddPiece(piece);
			allowedItemsByStack.Add(((Object)piece.PiecePrefab).name, craftItem);
			allowedItemsByContainer.Add(piece.PiecePrefab.GetComponent<Container>().m_name, craftItem);
		}

		private void OnPrefabsRegistered()
		{
			if (Chainloader.PluginInfos.ContainsKey("ujhik.MoreStacks"))
			{
				MoreStacks.Init();
			}
		}

		private void OnPiecesRegistered()
		{
			PieceManager.OnPiecesRegistered -= OnPiecesRegistered;
			foreach (CustomPiece renderSprite in renderSprites)
			{
				((MonoBehaviour)this).StartCoroutine(RenderSprite(renderSprite));
			}
			UpdateAllRecipes();
		}

		private IEnumerator RenderSprite(CustomPiece piece)
		{
			yield return null;
			VisualStack[] componentsInChildren = ((Component)piece.Piece).GetComponentsInChildren<VisualStack>();
			VisualStack[] array = componentsInChildren;
			for (int i = 0; i < array.Length; i++)
			{
				array[i].SetVisualsActive(55f);
			}
			piece.Piece.m_icon = RenderManager.Instance.Render(new RenderRequest(piece.PiecePrefab)
			{
				Width = 64,
				Height = 64,
				Rotation = RenderManager.IsometricRotation * Quaternion.Euler(0f, -90f, 0f),
				UseCache = true,
				TargetPlugin = ((BaseUnityPlugin)this).Info.Metadata
			});
			array = componentsInChildren;
			for (int i = 0; i < array.Length; i++)
			{
				array[i].SetVisualsActive(100f);
			}
		}

		private PieceConfig StackConfig(string item, int amount)
		{
			//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)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			//IL_002b: Expected O, but got Unknown
			PieceConfig val = new PieceConfig
			{
				PieceTable = PieceTables.Hammer,
				Category = PieceCategories.Misc
			};
			val.AddRequirement(new RequirementConfig(item, amount, 0, true));
			return val;
		}

		public static bool IsStackPiece(string pieceName, out string allowedItem)
		{
			return allowedItemsByStack.TryGetValue(pieceName, out allowedItem);
		}
	}
	public static class InventoryHelper
	{
		public static string PrefabName(this ItemData item)
		{
			if ((Object)(object)item.m_dropPrefab != (Object)null)
			{
				return ((Object)item.m_dropPrefab).name;
			}
			Logger.LogWarning((object)("Item has missing prefab " + item.m_shared.m_name));
			return item.m_shared.m_name;
		}
	}
	public static class PieceHelper
	{
		public static GameObject PreparePiecePrefab(GameObject prefab, GameObject basePrefab, string nameToken)
		{
			Object.Destroy((Object)(object)prefab.GetComponent<Gibber>());
			Object.Destroy((Object)(object)prefab.GetComponent<Collider>());
			Transform val = prefab.transform.Find("collider");
			if ((Object)(object)val != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)val).gameObject);
			}
			prefab.GetComponent<ZNetView>().m_persistent = true;
			if ((Object)(object)prefab.GetComponent<Piece>() == (Object)null)
			{
				ExposedGameObjectExtension.AddComponentCopy<Piece>(prefab, basePrefab.GetComponent<Piece>());
			}
			Piece component = prefab.GetComponent<Piece>();
			if ((Object)(object)component != (Object)null && !string.IsNullOrEmpty(nameToken))
			{
				component.m_name = nameToken;
			}
			if ((Object)(object)prefab.GetComponent<WearNTear>() == (Object)null)
			{
				ExposedGameObjectExtension.AddComponentCopy<WearNTear>(prefab, basePrefab.GetComponent<WearNTear>());
			}
			Container obj = prefab.AddComponent<Container>();
			obj.m_name = nameToken;
			obj.m_width = 5;
			obj.m_height = 2;
			VisualStack visualStack = prefab.AddComponent<VisualStack>();
			MeshRenderer[] componentsInChildren = prefab.GetComponentsInChildren<MeshRenderer>();
			foreach (MeshRenderer val2 in componentsInChildren)
			{
				if ((Object)(object)((Component)val2).gameObject.GetComponent<Collider>() == (Object)null)
				{
					((Component)val2).gameObject.AddComponent<BoxCollider>();
				}
				visualStack.stackMeshes.Add(((Component)val2).transform);
			}
			return prefab;
		}

		public static GameObject FindDestroyVFX(GameObject prefab, string vfxName)
		{
			WearNTear component = prefab.GetComponent<WearNTear>();
			if ((Object)(object)component == (Object)null)
			{
				return null;
			}
			object obj = typeof(WearNTear).GetField("m_destroyedEffect", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(component);
			if (obj == null)
			{
				return null;
			}
			if (!(obj.GetType().GetField("m_effectPrefabs", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(obj) is Array array))
			{
				return null;
			}
			foreach (object item in array)
			{
				if (item != null)
				{
					object? obj2 = item.GetType().GetField("m_prefab", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(item);
					GameObject val = (GameObject)((obj2 is GameObject) ? obj2 : null);
					if ((Object)(object)val != (Object)null && ((Object)val).name == vfxName)
					{
						return val;
					}
				}
			}
			return null;
		}

		public static AssetBundle GetAssetBundle(string bundleName)
		{
			foreach (AssetBundle allLoadedAssetBundle in AssetBundle.GetAllLoadedAssetBundles())
			{
				if ((Object)(object)allLoadedAssetBundle != (Object)null && ((Object)allLoadedAssetBundle).name == bundleName)
				{
					return allLoadedAssetBundle;
				}
			}
			return null;
		}

		public static bool ApplyVisualFromPrefab(GameObject target, GameObject source)
		{
			if ((Object)(object)target == (Object)null || (Object)(object)source == (Object)null)
			{
				return false;
			}
			MeshRenderer val = null;
			MeshFilter val2 = null;
			MeshRenderer[] componentsInChildren = source.GetComponentsInChildren<MeshRenderer>(true);
			foreach (MeshRenderer val3 in componentsInChildren)
			{
				MeshFilter component = ((Component)val3).GetComponent<MeshFilter>();
				if ((Object)(object)component != (Object)null && (Object)(object)component.sharedMesh != (Object)null)
				{
					val = val3;
					val2 = component;
					break;
				}
			}
			if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null)
			{
				return false;
			}
			bool result = false;
			componentsInChildren = target.GetComponentsInChildren<MeshRenderer>(true);
			foreach (MeshRenderer val4 in componentsInChildren)
			{
				MeshFilter component2 = ((Component)val4).GetComponent<MeshFilter>();
				if (!((Object)(object)component2 == (Object)null))
				{
					component2.sharedMesh = val2.sharedMesh;
					((Renderer)val4).sharedMaterials = ((Renderer)val).sharedMaterials;
					result = true;
				}
			}
			return result;
		}
	}
	[HarmonyPatch]
	internal static class RestrictContainers
	{
		private static readonly Dictionary<Inventory, string> ContainerNameCache = new Dictionary<Inventory, string>();

		private static Inventory _loadingInventory;

		private static Inventory _targetInventory;

		private static string _allowedItem;

		private static string GetContainerName(Inventory inventory)
		{
			if (inventory == null)
			{
				return null;
			}
			if (ContainerNameCache.TryGetValue(inventory, out var value))
			{
				return value;
			}
			Container[] array = Object.FindObjectsOfType<Container>();
			foreach (Container val in array)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				try
				{
					if (val.GetInventory() == inventory)
					{
						ContainerNameCache[inventory] = val.m_name;
						return val.m_name;
					}
				}
				catch
				{
				}
			}
			return null;
		}

		private static bool CanAddItem(Inventory inventory, ItemData item)
		{
			if (inventory == null || item == null)
			{
				return false;
			}
			if (inventory == _loadingInventory)
			{
				return true;
			}
			string containerName = GetContainerName(inventory);
			if (IsRestrictedContainer(containerName, out var allowedItem))
			{
				bool num = item.PrefabName() == allowedItem;
				if (!num && (Object)(object)Player.m_localPlayer != (Object)null && (Object)(object)MessageHud.instance != (Object)null)
				{
					string text = containerName ?? "this container";
					MessageHud.instance.ShowMessage((MessageType)2, item.m_shared.m_name + " cannot be placed in " + text, 0, (Sprite)null, false, true);
				}
				return num;
			}
			return true;
		}

		public static bool IsRestrictedContainer(string containerName, out string allowedItem)
		{
			if (!ConfigSettings.restrictDynamicPiles.Value || string.IsNullOrEmpty(containerName))
			{
				allowedItem = null;
				return false;
			}
			return DynamicStoragePiles.allowedItemsByContainer.TryGetValue(containerName, out allowedItem);
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Inventory), "AddItem", new Type[] { typeof(ItemData) })]
		[HarmonyPatch(typeof(Inventory), "AddItem", new Type[]
		{
			typeof(ItemData),
			typeof(int),
			typeof(int),
			typeof(int),
			typeof(bool)
		})]
		[HarmonyPriority(800)]
		private static bool AddItemPrefix(Inventory __instance, ItemData item, ref bool __result)
		{
			if (!CanAddItem(__instance, item))
			{
				__result = false;
				return false;
			}
			return true;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Inventory), "MoveItemToThis", new Type[]
		{
			typeof(Inventory),
			typeof(ItemData)
		})]
		[HarmonyPatch(typeof(Inventory), "MoveItemToThis", new Type[]
		{
			typeof(Inventory),
			typeof(ItemData),
			typeof(int),
			typeof(int),
			typeof(int)
		})]
		[HarmonyPriority(800)]
		private static bool MoveItemToThisPrefix(Inventory __instance, Inventory fromInventory, ItemData item)
		{
			if (__instance != null && fromInventory != null && item != null)
			{
				return CanAddItem(__instance, item);
			}
			return false;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Inventory), "MoveAll", new Type[] { typeof(Inventory) })]
		[HarmonyPriority(800)]
		private static void MoveAllPrefix(Inventory __instance, Inventory fromInventory)
		{
			string containerName = GetContainerName(__instance);
			if (__instance != null && fromInventory != null && IsRestrictedContainer(containerName, out var allowedItem))
			{
				_targetInventory = __instance;
				_allowedItem = allowedItem;
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Inventory), "MoveAll", new Type[] { typeof(Inventory) })]
		private static void MoveAllPostfix()
		{
			_targetInventory = null;
			_allowedItem = null;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Inventory), "RemoveItem", new Type[] { typeof(ItemData) })]
		[HarmonyPatch(typeof(Inventory), "RemoveItem", new Type[]
		{
			typeof(ItemData),
			typeof(int)
		})]
		[HarmonyPriority(800)]
		private static bool RemoveItemPrefix(Inventory __instance, ItemData item)
		{
			return ShouldRemoveItem(__instance, item);
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Inventory), "RemoveOneItem", new Type[] { typeof(ItemData) })]
		[HarmonyPriority(800)]
		private static bool RemoveOneItemPrefix(Inventory __instance, ItemData item)
		{
			return ShouldRemoveItem(__instance, item);
		}

		private static bool ShouldRemoveItem(Inventory instance, ItemData item)
		{
			if (instance == null || item == null)
			{
				return false;
			}
			if (_targetInventory == instance && !string.IsNullOrEmpty(_allowedItem))
			{
				return item.PrefabName() != _allowedItem;
			}
			return true;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Inventory), "Load", new Type[] { typeof(ZPackage) })]
		[HarmonyPatch(typeof(Inventory), "Load", new Type[]
		{
			typeof(ZPackage),
			typeof(bool)
		})]
		private static void LoadPrefix(Inventory __instance)
		{
			_loadingInventory = __instance;
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Inventory), "Load", new Type[] { typeof(ZPackage) })]
		[HarmonyPatch(typeof(Inventory), "Load", new Type[]
		{
			typeof(ZPackage),
			typeof(bool)
		})]
		private static void LoadPostfix()
		{
			_loadingInventory = null;
		}
	}
	public class VisualStack : MonoBehaviour
	{
		public List<Transform> stackMeshes = new List<Transform>();

		private Container container;

		private Inventory inventory;

		private void Start()
		{
			container = ((Component)this).GetComponentInParent<Container>();
			if ((Object)(object)container != (Object)null)
			{
				inventory = container.GetInventory();
			}
			if (inventory != null)
			{
				Inventory obj = inventory;
				obj.m_onChanged = (Action)Delegate.Combine(obj.m_onChanged, new Action(UpdateVisuals));
				UpdateVisuals();
			}
		}

		private void UpdateVisuals()
		{
			SetVisualsActive(inventory.SlotsUsedPercentage());
		}

		public void SetVisualsActive(float fillPercentage)
		{
			float num = Mathf.Ceil(fillPercentage / 100f * (float)stackMeshes.Count);
			for (int i = 0; i < stackMeshes.Count; i++)
			{
				bool active = i == 0 || (float)i < num;
				((Component)stackMeshes[i]).gameObject.SetActive(active);
			}
		}
	}
}
namespace DynamicStoragePiles.Patches
{
	internal static class PlacementPatch
	{
	}
}
namespace DynamicStoragePiles.Compatibility
{
	public static class AzuAutoStore
	{
		private static class AzuAutoStore_After_2_0_0
		{
			[HarmonyPatch("AzuAutoStore.Util.Boxes, AzuAutoStore", "CanItemBeStored")]
			[HarmonyPostfix]
			private static void CanItemBeStoredPatch(string container, string prefab, ref bool __result)
			{
				if (__result && ConfigSettings.azuAutoStoreItemWhitelist.Value && DynamicStoragePiles.IsStackPiece(container, out var allowedItem) && prefab != allowedItem)
				{
					__result = false;
				}
			}
		}

		private static class AzuAutoStore_Before_2_0_0
		{
			[HarmonyPatch("AzuAutoStore.Util.Functions, AzuAutoStore", "CheckDisallowedItems")]
			[HarmonyPostfix]
			private static void CheckDisallowedItemsPatch(Container container, ItemData item, ref bool __result)
			{
				if (!__result && ConfigSettings.azuAutoStoreItemWhitelist.Value && (Object)(object)container != (Object)null && item != null && (Object)(object)item.m_dropPrefab != (Object)null && DynamicStoragePiles.IsStackPiece(Utils.GetPrefabName(((Object)container).name), out var allowedItem) && ((Object)item.m_dropPrefab).name != allowedItem)
				{
					__result = true;
				}
			}
		}

		public static void Init()
		{
			if (Chainloader.PluginInfos["Azumatt.AzuAutoStore"].Metadata.Version >= new Version(2, 0, 0))
			{
				DynamicStoragePiles.harmony.PatchAll(typeof(AzuAutoStore_After_2_0_0));
			}
			else
			{
				DynamicStoragePiles.harmony.PatchAll(typeof(AzuAutoStore_Before_2_0_0));
			}
		}
	}
	public static class IngotStacks
	{
		private static AssetBundle assetBundle;

		private static bool flametalVisualApplied;

		public static List<string> ingotStacks = new List<string>();

		public static List<string> dynamicIngotStacks = new List<string>();

		public static void Init()
		{
			assetBundle = AssetUtils.LoadAssetBundleFromResources("stackedingots");
			ConvertToPiece("ingot_copper_stack", "vfx_copper_stack_destroyed", "MS_IngotStacks_Copper", "Copper", "$piece_copperbarstack");
			ConvertToPiece("ingot_tin_stack", "vfx_tin_stack_destroyed", "MS_IngotStacks_Tin", "Tin", "$piece_tinbarstack");
			ConvertToPiece("ingot_bronze_stack", "vfx_bronze_stack_destroyed", "MS_IngotStacks_Bronze", "Bronze", "$piece_bronzebarstack");
			ConvertToPiece("ingot_iron_stack", "vfx_iron_stack_destroyed", "MS_IngotStacks_Iron", "Iron", "$piece_ironbarstack");
			ConvertToPiece("ingot_silver_stack", "vfx_silver_stack_destroyed", "MS_IngotStacks_Silver", "Silver", "$piece_silverbarstack");
			ConvertToPiece("ingot_blackmetal_stack", "vfx_blackmetal_stack_destroyed", "MS_IngotStacks_Blackmetal", "BlackMetal", "$piece_blackmetalbarstack");
			ConvertToPiece("ingot_flametal_stack", "vfx_flametal_stack_destroyed", "MS_IngotStacks_FlametalNew", "FlametalNew", "$piece_flametalbarstack");
			PrefabManager.OnPrefabsRegistered += OnPrefabsRegistered;
			TryApplyCurrentFlametalVisual();
		}

		private static void OnPrefabsRegistered()
		{
			TryApplyCurrentFlametalVisual();
			if (flametalVisualApplied)
			{
				PrefabManager.OnPrefabsRegistered -= OnPrefabsRegistered;
			}
		}

		private static void TryApplyCurrentFlametalVisual()
		{
			if (flametalVisualApplied || (Object)(object)ZNetScene.instance == (Object)null)
			{
				return;
			}
			GameObject prefab = ZNetScene.instance.GetPrefab("MS_IngotStacks_FlametalNew");
			GameObject prefab2 = ZNetScene.instance.GetPrefab("FlametalNew");
			if ((Object)(object)prefab == (Object)null || (Object)(object)prefab2 == (Object)null)
			{
				Logger.LogInfo((object)"Flametal Stack: waiting for current Flametal prefab before visual swap.");
				return;
			}
			if (!PieceHelper.ApplyVisualFromPrefab(prefab, prefab2))
			{
				Logger.LogError((object)"Flametal Stack: could not copy the current Flametal mesh/material visual.");
				return;
			}
			flametalVisualApplied = true;
			Logger.LogInfo((object)"Flametal Stack: current Flametal visual applied to registered DSP pile.");
			if ((Object)(object)DynamicStoragePiles.Instance != (Object)null)
			{
				((MonoBehaviour)DynamicStoragePiles.Instance).StartCoroutine(RenderFlametalIcon(prefab));
			}
		}

		private static IEnumerator RenderFlametalIcon(GameObject target)
		{
			yield return null;
			Piece piece = (((Object)(object)target != (Object)null) ? target.GetComponent<Piece>() : null);
			if ((Object)(object)piece == (Object)null)
			{
				Logger.LogError((object)"Flametal Stack: could not find Piece component for custom icon render.");
				yield break;
			}
			VisualStack[] visualStacks = target.GetComponentsInChildren<VisualStack>();
			VisualStack[] array = visualStacks;
			for (int i = 0; i < array.Length; i++)
			{
				array[i].SetVisualsActive(55f);
			}
			yield return null;
			piece.m_icon = RenderManager.Instance.Render(new RenderRequest(target)
			{
				Width = 64,
				Height = 64,
				Rotation = RenderManager.IsometricRotation * Quaternion.Euler(0f, -90f, 0f),
				UseCache = false,
				TargetPlugin = ((BaseUnityPlugin)DynamicStoragePiles.Instance).Info.Metadata
			});
			array = visualStacks;
			for (int i = 0; i < array.Length; i++)
			{
				array[i].SetVisualsActive(100f);
			}
			Logger.LogInfo((object)"Flametal Stack: custom dynamic-pile builder icon rendered.");
		}

		public static void ConvertToPiece(string baseAssetName, string vfxName, string newPrefabName, string resource, string nameToken)
		{
			ingotStacks.Add(baseAssetName);
			dynamicIngotStacks.Add(newPrefabName);
			GameObject val = assetBundle.LoadAsset<GameObject>(baseAssetName);
			GameObject val2 = PieceHelper.FindDestroyVFX(val, vfxName);
			GameObject prefab = PrefabManager.Instance.CreateClonedPrefab(newPrefabName, val2);
			prefab = PieceHelper.PreparePiecePrefab(prefab, val, nameToken);
			((Object)prefab).name = newPrefabName;
			DynamicStoragePiles.Instance.AddCompatPiece(prefab, resource, 30);
		}
	}
	public static class MoreStacks
	{
		public static List<string> staticStacks = new List<string>();

		public static List<string> dynamicStacks = new List<string>();

		private static BaseUnityPlugin moreStacksInstance = null;

		private static Dictionary<string, string> vanillaNameToDynamicStorageNameMap = new Dictionary<string, string>
		{
			{ "wood_fine_stack", "finewood_stack" },
			{ "wood_core_stack", "corewood_stack" },
			{ "wood_yggdrasil_stack", "yggdrasil_wood_stack" },
			{ "treasure_stack", "coin_pile" }
		};

		public static void Init()
		{
			if ((Object)(object)moreStacksInstance == (Object)null && Chainloader.PluginInfos.TryGetValue("ujhik.MoreStacks", out var value))
			{
				moreStacksInstance = value.Instance;
				if ((Object)(object)moreStacksInstance == (Object)null)
				{
					Logger.LogWarning((object)"Failed to cast mod instance for 'ujhik.MoreStacks'.");
					return;
				}
			}
			FieldInfo field = ((object)moreStacksInstance).GetType().GetField("stackInfoList", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field != null)
			{
				if (!(field.GetValue(moreStacksInstance) is IEnumerable enumerable))
				{
					return;
				}
				{
					foreach (object item in enumerable)
					{
						Type type = item.GetType();
						PropertyInfo property = type.GetProperty("idStackToDuplicate");
						PropertyInfo? property2 = type.GetProperty("idStackMaterial");
						string stackToCloneId = property?.GetValue(item) as string;
						string materialPrefabId = property2?.GetValue(item) as string;
						ConvertToPiece(stackToCloneId, materialPrefabId);
					}
					return;
				}
			}
			Logger.LogWarning((object)"ujhik.MoreStacks: Failed to retrieve stackInfoList field via reflection, dynamic piles could not be generated");
		}

		public static void ConvertToPiece(string stackToCloneId, string materialPrefabId)
		{
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			if (vanillaNameToDynamicStorageNameMap.TryGetValue(stackToCloneId, out var value))
			{
				stackToCloneId = value;
			}
			string text = (string)((object)moreStacksInstance).GetType().GetMethod("getStackName", BindingFlags.Static | BindingFlags.Public)?.Invoke(moreStacksInstance, new object[1] { materialPrefabId });
			string text2 = "MS_container_MoreStacks" + "_" + materialPrefabId + "_pile";
			string text3 = "MS_container_" + stackToCloneId;
			staticStacks.Add(text);
			dynamicStacks.Add(text2);
			GameObject prefab = PrefabManager.Instance.GetPrefab(text3);
			GameObject prefab2 = PrefabManager.Instance.GetPrefab(text);
			PrefabManager.Instance.GetPrefab(materialPrefabId);
			GameObject val = PrefabManager.Instance.CreateClonedPrefab(text2, prefab);
			Object.DestroyImmediate((Object)(object)val.GetComponent<Container>());
			val.transform.localScale = prefab2.transform.localScale;
			string name = prefab2.GetComponent<Piece>().m_name;
			val = PieceHelper.PreparePiecePrefab(val, prefab, name);
			val.GetComponent<Piece>().m_name = name;
			Material sharedMaterial = ((Renderer)prefab2.GetComponentInChildren<MeshRenderer>()).sharedMaterial;
			MeshRenderer[] componentsInChildren = val.GetComponentsInChildren<MeshRenderer>();
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				((Renderer)componentsInChildren[i]).sharedMaterial = sharedMaterial;
			}
			DynamicStoragePiles.Instance.AddCompatPiece(val, materialPrefabId, GetMaterialCostForPiece(materialPrefabId), addGraphics: true);
		}

		public static int GetMaterialCostForPiece(string materialPrefabId)
		{
			if (materialPrefabId.Contains("Ore") || materialPrefabId.Contains("Scrap"))
			{
				return 3;
			}
			return 10;
		}
	}
	public static class RefinedStonePieces
	{
		private static AssetBundle assetBundle;

		public static List<string> staticStacks = new List<string>();

		public static List<string> dynamicStacks = new List<string>();

		public static void Init()
		{
			assetBundle = PieceHelper.GetAssetBundle("refinedstonepieces");
			ConvertRefinedStoneStackToPiece("BRP_RefinedStone_Stack", "MS_RefinedStonePieces_RefinedStone_Stack", "BRP_RefinedStone");
		}

		public static void ConvertRefinedStoneStackToPiece(string baseAssetName, string newPrefabName, string resource)
		{
			staticStacks.Add(baseAssetName);
			dynamicStacks.Add(newPrefabName);
			GameObject val = assetBundle.LoadAsset<GameObject>(baseAssetName);
			GameObject prefab = PrefabManager.Instance.CreateClonedPrefab(newPrefabName, val);
			prefab = PieceHelper.PreparePiecePrefab(prefab, val, "$brp_refinedstone_stack");
			((Object)prefab).name = newPrefabName;
			List<Transform> source = prefab.GetComponent<VisualStack>().stackMeshes.OrderBy((Transform t) => t.position.y).ToList();
			IOrderedEnumerable<Transform> first = from t in source.Skip(0).Take(6)
				orderby t.position.z
				select t;
			IOrderedEnumerable<Transform> second = from t in source.Skip(6).Take(6)
				orderby t.position.x
				select t;
			IOrderedEnumerable<Transform> second2 = from t in source.Skip(12).Take(6)
				orderby t.position.z
				select t;
			prefab.GetComponent<VisualStack>().stackMeshes = first.Concat(second).Concat(second2).ToList();
			DynamicStoragePiles.Instance.AddCompatPiece(prefab, resource, 10, addGraphics: true);
		}
	}
	public static class StackedBars
	{
		private static AssetBundle assetBundle;

		public static List<string> stackedBars = new List<string>();

		public static List<string> dynamicStackedBars = new List<string>();

		public static void Init()
		{
			assetBundle = PieceHelper.GetAssetBundle("stackedbars");
			ConvertToPiece("stack_tinbars", "MS_StackedBars_Tin", "Tin");
			ConvertToPiece("stack_copperbars", "MS_StackedBars_Copper", "Copper");
			ConvertToPiece("stack_bronzebars", "MS_StackedBars_Bronze", "Bronze");
			ConvertToPiece("stack_ironbars", "MS_StackedBars_Iron", "Iron");
			ConvertToPiece("stack_silverbars", "MS_StackedBars_Silver", "Silver");
			ConvertToPiece("stack_blackmetalbars", "MS_StackedBars_BlackMetal", "BlackMetal");
			ConvertToPiece("stack_flametalbars", "MS_StackedBars_FlameMetalNew", "FlametalNew");
		}

		public static void ConvertToPiece(string baseAssetName, string newPrefabName, string resource)
		{
			stackedBars.Add(baseAssetName);
			dynamicStackedBars.Add(newPrefabName);
			GameObject val = assetBundle.LoadAsset<GameObject>(baseAssetName);
			GameObject prefab = PrefabManager.Instance.CreateClonedPrefab(newPrefabName, val);
			prefab = PieceHelper.PreparePiecePrefab(prefab, val, "$piece_" + baseAssetName);
			((Object)prefab).name = newPrefabName;
			DynamicStoragePiles.Instance.AddCompatPiece(prefab, resource, 3);
		}
	}
}