Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of ValheimStorage v1.3.2
ValheimStorage.dll
Decompiled a day agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.Rendering; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("ValheimStorage")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+a19f4b302348e8eadfcc58f94a7bd40d40e21ab3")] [assembly: AssemblyProduct("ValheimStorage")] [assembly: AssemblyTitle("ValheimStorage")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [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 ValheimStorage { public static class CraftFromContainers { internal static bool CraftingAllowed(Player player) { if (!Plugin.ModActive() || !Plugin.enableCrafting.Value) { return false; } CraftingStation currentCraftingStation = player.GetCurrentCraftingStation(); return (Object)(object)currentCraftingStation == (Object)null || Plugin.StationAllowed(((Component)currentCraftingStation).gameObject); } internal static bool BuildingAllowed(Piece piece) { return Plugin.ModActive() && Plugin.enableBuilding.Value && ((Object)(object)piece.m_craftingStation == (Object)null || Plugin.StationAllowed(((Component)piece.m_craftingStation).gameObject)); } } [HarmonyPatch(typeof(Player), "HaveRequirementItems")] public static class Player_HaveRequirementItems_Containers { private static void Postfix(Player __instance, Recipe piece, bool discover, int qualityLevel, int amount, ref bool __result) { if (__result || discover || (Object)(object)__instance != (Object)(object)Player.m_localPlayer || !CraftFromContainers.CraftingAllowed(__instance)) { return; } Requirement[] resources = piece.m_resources; foreach (Requirement val in resources) { if ((Object)(object)val.m_resItem == (Object)null) { continue; } string name = val.m_resItem.m_itemData.m_shared.m_name; int num = val.GetAmount(qualityLevel) * amount; int num2 = 0; for (int j = 1; j < val.m_resItem.m_itemData.m_shared.m_maxQuality + 1; j++) { int num3 = ((Humanoid)__instance).m_inventory.CountItems(name, j, true) + NearbyContainers.CountItems(__instance, name, j); if (num3 > num2) { num2 = num3; } } if (piece.m_requireOnlyOneIngredient) { if (num2 >= num) { __result = true; return; } } else if (num2 < num) { return; } } __result = !piece.m_requireOnlyOneIngredient; } } [HarmonyPatch(typeof(Player), "HaveRequirements", new Type[] { typeof(Piece), typeof(RequirementMode) })] public static class Player_HaveRequirementsPiece_Containers { private static void Postfix(Player __instance, Piece piece, RequirementMode mode, ref bool __result) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Invalid comparison between Unknown and I4 //IL_007d: Unknown result type (might be due to invalid IL or missing references) if (__result || (int)mode == 1 || (Object)(object)__instance != (Object)(object)Player.m_localPlayer || !CraftFromContainers.BuildingAllowed(piece)) { return; } if ((Object)(object)piece.m_craftingStation != (Object)null) { if ((int)mode == 2) { if (!__instance.m_knownStations.ContainsKey(piece.m_craftingStation.m_name)) { return; } } else if ((Object)(object)CraftingStation.HaveBuildStationInRange(piece.m_craftingStation.m_name, ((Component)__instance).transform.position) == (Object)null && !ZoneSystem.instance.GetGlobalKey((GlobalKeys)22)) { return; } } if (piece.m_dlc.Length > 0 && !DLCMan.instance.IsDLCInstalled(piece.m_dlc)) { return; } Requirement[] resources = piece.m_resources; foreach (Requirement val in resources) { if (!((Object)(object)val.m_resItem == (Object)null) && val.m_amount > 0) { string name = val.m_resItem.m_itemData.m_shared.m_name; int num = ((Humanoid)__instance).m_inventory.CountItems(name, -1, true) + NearbyContainers.CountItems(__instance, name); if (num < val.m_amount) { return; } } } __result = true; } } [HarmonyPatch(typeof(Player), "ConsumeResources")] public static class Player_ConsumeResources_Containers { private static bool Prefix(Player __instance, Requirement[] requirements, int qualityLevel, int itemQuality, int multiplier) { if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer || !Plugin.ModActive()) { return true; } bool flag = ((Character)__instance).InPlaceMode(); if (flag ? (!Plugin.enableBuilding.Value) : (!CraftFromContainers.CraftingAllowed(__instance))) { return true; } string context = (flag ? "building" : "crafting"); foreach (Requirement val in requirements) { if ((Object)(object)val.m_resItem == (Object)null) { continue; } int num = val.GetAmount(qualityLevel) * multiplier; if (num > 0) { string name = val.m_resItem.m_itemData.m_shared.m_name; int num2 = Math.Min(((Humanoid)__instance).m_inventory.CountItems(name, itemQuality, true), num); if (num2 > 0) { ((Humanoid)__instance).m_inventory.RemoveItem(name, num2, itemQuality, true); } if (num - num2 > 0) { NearbyContainers.RemoveItems(__instance, name, num - num2, itemQuality, context, ((Object)((Component)val.m_resItem).gameObject).name); } } } FlyingItems.Flush(); return false; } } [HarmonyPatch(typeof(InventoryGui), "SetupRequirement")] public static class InventoryGui_SetupRequirement_Containers { private static void Postfix(Transform elementRoot, Requirement req, Player player, int quality, int craftMultiplier, bool __result) { //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) if (!__result || (Object)(object)req?.m_resItem == (Object)null || (Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)Player.m_localPlayer || !CraftFromContainers.CraftingAllowed(player)) { return; } int num = req.GetAmount(quality) * craftMultiplier; if (num > 0) { string name = req.m_resItem.m_itemData.m_shared.m_name; int num2 = ((Humanoid)player).GetInventory().CountItems(name, -1, true); int num3 = NearbyContainers.CountItems(player, name); TMP_Text component = ((Component)elementRoot.Find("res_amount")).GetComponent<TMP_Text>(); if (Plugin.showAvailable.Value && num3 > 0) { component.text = $"{num} ({num2 + num3})"; } if (num2 < num && num2 + num3 >= num) { ((Graphic)component).color = ((Mathf.Sin(Time.time * 10f) > 0f) ? Plugin.flashColor.Value : Color.white); } } } } public static class FavoriteItems { private const string customDataKey = "vs_favorite"; private const string markerName = "VS_Favorite"; private static bool spriteLoadAttempted; private static Sprite? favoriteSprite; internal static bool IsFavorite(ItemData? item) { return item?.m_customData.ContainsKey("vs_favorite") ?? false; } internal static void Toggle(ItemData item) { if (!item.m_customData.Remove("vs_favorite")) { item.m_customData["vs_favorite"] = "1"; } Player localPlayer = Player.m_localPlayer; if (localPlayer != null) { ((Character)localPlayer).Message((MessageType)1, (IsFavorite(item) ? "Favorited " : "Unfavorited ") + item.m_shared.m_name, 0, (Sprite)null); } } internal static bool FavoriteKeyHeld() { //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_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) KeyboardShortcut value = Plugin.favoriteModifier.Value; if ((int)((KeyboardShortcut)(ref value)).MainKey == 0 || !ZInput.GetKey(((KeyboardShortcut)(ref value)).MainKey, true)) { return false; } foreach (KeyCode modifier in ((KeyboardShortcut)(ref value)).Modifiers) { if (!ZInput.GetKey(modifier, true)) { return false; } } return true; } internal static void UpdateMarkers(InventoryGrid grid) { if ((Object)(object)MarkerSprite() == (Object)null || grid.m_inventory == null) { return; } foreach (Element element in grid.m_elements) { Transform val = element.m_go.transform.Find("VS_Favorite"); if ((Object)(object)val != (Object)null) { ((Component)val).gameObject.SetActive(false); } } int width = grid.m_inventory.GetWidth(); foreach (ItemData allItem in grid.m_inventory.GetAllItems()) { if (IsFavorite(allItem)) { GetMarker(grid.GetElement(allItem.m_gridPos.x, allItem.m_gridPos.y, width)).SetActive(true); } } } private static GameObject GetMarker(Element element) { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Expected O, but got Unknown //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) Transform val = element.m_go.transform.Find("VS_Favorite"); if ((Object)(object)val != (Object)null) { return ((Component)val).gameObject; } GameObject val2 = new GameObject("VS_Favorite", new Type[1] { typeof(RectTransform) }); val2.transform.SetParent(element.m_go.transform, false); val2.transform.SetAsLastSibling(); RectTransform val3 = (RectTransform)val2.transform; val3.anchorMin = Vector2.zero; val3.anchorMax = Vector2.one; val3.offsetMin = Vector2.zero; val3.offsetMax = Vector2.zero; Image val4 = val2.AddComponent<Image>(); val4.sprite = MarkerSprite(); ((Graphic)val4).raycastTarget = false; return val2; } private static Sprite? MarkerSprite() { //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) if (spriteLoadAttempted) { return favoriteSprite; } spriteLoadAttempted = true; AssetBundle val = null; using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("ValheimStorage.assets.vs")) { if (stream != null) { using MemoryStream memoryStream = new MemoryStream(); stream.CopyTo(memoryStream); val = AssetBundle.LoadFromMemory(memoryStream.ToArray()); } } if ((Object)(object)val == (Object)null) { Debug.LogWarning((object)"[ValheimStorage] asset bundle 'vs' not found in mod DLL, favorite markers are invisible"); return null; } favoriteSprite = val.LoadAsset<Sprite>("VS_FavBackground"); if ((Object)(object)favoriteSprite == (Object)null) { Texture2D val2 = val.LoadAsset<Texture2D>("VS_FavBackground"); if ((Object)(object)val2 != (Object)null) { favoriteSprite = Sprite.Create(val2, new Rect(0f, 0f, (float)((Texture)val2).width, (float)((Texture)val2).height), new Vector2(0.5f, 0.5f)); } } if ((Object)(object)favoriteSprite == (Object)null) { Debug.LogWarning((object)"[ValheimStorage] VS_FavBackground missing from asset bundle, favorite markers are invisible"); } return favoriteSprite; } } [HarmonyPatch(typeof(InventoryGui), "OnSelectedItem")] public static class InventoryGui_OnSelectedItem_ToggleFavorite { private static bool Prefix(InventoryGui __instance, ItemData? item) { if (item == null || (Object)(object)__instance.m_dragGo != (Object)null || !FavoriteItems.FavoriteKeyHeld()) { return true; } FavoriteItems.Toggle(item); return false; } } [HarmonyPatch(typeof(InventoryGrid), "UpdateGui")] public static class InventoryGrid_UpdateGui_FavoriteMarkers { private static void Postfix(InventoryGrid __instance) { FavoriteItems.UpdateMarkers(__instance); } } [HarmonyPatch(typeof(Inventory), "StackAll")] public static class Inventory_StackAll_SkipFavorites { private static void Prefix(Inventory fromInventory, out List<ItemData> __state) { __state = fromInventory.m_inventory.FindAll((ItemData item) => FavoriteItems.IsFavorite(item)); foreach (ItemData item in __state) { fromInventory.m_inventory.Remove(item); } } private static void Postfix(Inventory fromInventory, List<ItemData> __state) { if (__state.Count > 0) { fromInventory.m_inventory.AddRange(__state); fromInventory.Changed(); } } } [HarmonyPatch(typeof(Humanoid), "DropItem")] public static class Humanoid_DropItem_BlockFavorites { private static bool Prefix(Humanoid __instance, ItemData item, ref bool __result) { if (!FavoriteItems.IsFavorite(item)) { return true; } ((Character)__instance).Message((MessageType)2, "Unmark the favorite first to drop it", 0, (Sprite)null); __result = false; return false; } } public static class FlyingItems { private const string rpcName = "VS_QuickStackFly"; private const int maxFlyersPerRun = 20; private const float flyerSize = 0.3f; private const float legSeconds = 0.7f; private const float staggerSeconds = 0.06f; private const float cullDistance = 200f; private static ZRoutedRpc? registeredOn; public static Func<Player, Vector3, List<Vector3>?>? routeResolver; private static readonly List<(string prefabName, Vector3[] path)> pending = new List<(string, Vector3[])>(); internal static void RegisterRpc() { ZRoutedRpc instance = ZRoutedRpc.instance; if (instance != null && instance != registeredOn) { instance.Register<ZPackage>("VS_QuickStackFly", (Action<long, ZPackage>)RPC_Fly); registeredOn = instance; } } internal static void Queue(ItemData item, Player player, Vector3 containerPos) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)item.m_dropPrefab != (Object)null) { Add(((Object)item.m_dropPrefab).name, BuildPath(player, containerPos, toChest: true)); } } internal static void QueueFromContainer(string prefabName, Player player, Vector3 containerPos) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) Add(prefabName, BuildPath(player, containerPos, toChest: false)); } private static Vector3[] BuildPath(Player player, Vector3 containerPos, bool toChest) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) List<Vector3> list = new List<Vector3> { containerPos + Vector3.up * 0.6f }; List<Vector3> list2 = routeResolver?.Invoke(player, containerPos); if (list2 != null) { list.AddRange(list2); } list.Add(((Character)player).GetCenterPoint()); if (toChest) { list.Reverse(); } return list.ToArray(); } private static void Add(string prefabName, Vector3[] path) { if (pending.Count < 20 && path.Length >= 2) { pending.Add((prefabName, path)); } } internal static void Flush() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: 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) if (pending.Count == 0) { return; } ZPackage val = new ZPackage(); val.Write(pending.Count); foreach (var (text, array) in pending) { val.Write(text); val.Write(array.Length); Vector3[] array2 = array; foreach (Vector3 val2 in array2) { val.Write(val2); } } pending.Clear(); if (ZRoutedRpc.instance != null) { ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "VS_QuickStackFly", new object[1] { val }); } else { val.SetPos(0); RPC_Fly(0L, val); } } private static void RPC_Fly(long sender, ZPackage package) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; int num = package.ReadInt(); for (int i = 0; i < num; i++) { string text = package.ReadString(); int num2 = package.ReadInt(); Vector3[] array = (Vector3[])(object)new Vector3[num2]; for (int j = 0; j < num2; j++) { array[j] = package.ReadVector3(); } if ((Object)(object)localPlayer == (Object)null || array.Length < 2) { continue; } bool flag = false; Vector3[] array2 = array; foreach (Vector3 val in array2) { if (Vector3.Distance(val, ((Component)localPlayer).transform.position) <= 200f) { flag = true; break; } } GameObject val2 = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetItemPrefab(text) : null); if (flag && (Object)(object)val2 != (Object)null) { SpawnVisual(val2, array, i); } } } private static void SpawnVisual(GameObject itemPrefab, Vector3[] path, int index) { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Expected O, but got Unknown //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) MeshFilter componentInChildren = itemPrefab.GetComponentInChildren<MeshFilter>(true); MeshRenderer val = (((Object)(object)componentInChildren != (Object)null) ? ((Component)componentInChildren).GetComponent<MeshRenderer>() : null); if (!((Object)(object)componentInChildren == (Object)null) && !((Object)(object)componentInChildren.sharedMesh == (Object)null) && !((Object)(object)val == (Object)null)) { GameObject val2 = new GameObject("VS_FlyingItem"); val2.AddComponent<MeshFilter>().sharedMesh = componentInChildren.sharedMesh; MeshRenderer val3 = val2.AddComponent<MeshRenderer>(); ((Renderer)val3).sharedMaterials = ((Renderer)val).sharedMaterials; ((Renderer)val3).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)val3).receiveShadows = false; Bounds bounds = componentInChildren.sharedMesh.bounds; float num = Mathf.Max(((Bounds)(ref bounds)).size.x, Mathf.Max(((Bounds)(ref bounds)).size.y, ((Bounds)(ref bounds)).size.z)); val2.transform.localScale = Vector3.one * ((num > 0.001f) ? (0.3f / num) : 1f); FlyingItemVisual flyingItemVisual = val2.AddComponent<FlyingItemVisual>(); flyingItemVisual.path = path; flyingItemVisual.legDuration = 0.7f; flyingItemVisual.delay = (float)index * 0.06f; val2.transform.position = path[0]; } } } public class FlyingItemVisual : MonoBehaviour { public Vector3[] path = Array.Empty<Vector3>(); public float legDuration = 0.7f; public float delay; private float progress; private void Update() { //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) Renderer component = ((Component)this).GetComponent<Renderer>(); if (delay > 0f) { delay -= Time.deltaTime; component.enabled = false; return; } int num = path.Length - 1; if (num < 1) { Object.Destroy((Object)(object)((Component)this).gameObject); return; } component.enabled = true; progress += Time.deltaTime / legDuration; if (progress >= (float)num) { Object.Destroy((Object)(object)((Component)this).gameObject); return; } int num2 = Mathf.Min((int)progress, num - 1); float num3 = progress - (float)num2; Vector3 position = Vector3.Lerp(path[num2], path[num2 + 1], num3); position.y += Mathf.Sin(num3 * (float)Math.PI) * 1.2f; ((Component)this).transform.position = position; ((Component)this).transform.Rotate(0f, 300f * Time.deltaTime, 120f * Time.deltaTime, (Space)0); } } public static class NearbyContainers { private static readonly List<Container> containers = new List<Container>(); public static Func<Vector3, float, List<Container>>? remoteSources; public static Func<Vector3, float, List<StorageSource>>? virtualSources; internal static void Register(Container container) { containers.Add(container); } internal static List<Container> Find(Vector3 point, float range) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) List<Container> list = FindLocal(point, range); if (remoteSources != null) { foreach (Container item in remoteSources(point, range)) { if ((Object)(object)item != (Object)null && !list.Contains(item)) { list.Add(item); } } } return list; } internal static List<StorageSource> FindSources(Vector3 point, float range) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) List<StorageSource> list = new List<StorageSource>(); HashSet<ZDOID> hashSet = new HashSet<ZDOID>(); foreach (Container item in Find(point, range)) { list.Add(new LiveContainerSource(item)); hashSet.Add(item.m_nview.GetZDO().m_uid); } if (virtualSources != null) { foreach (StorageSource item2 in virtualSources(point, range)) { if (item2 != null && hashSet.Add(item2.Id)) { list.Add(item2); } } } return list; } public static List<Container> FindLocal(Vector3 point, float range) { //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) containers.RemoveAll((Container c) => (Object)(object)c == (Object)null); List<Container> list = new List<Container>(); long num = (((Object)(object)Game.instance != (Object)null) ? Game.instance.GetPlayerProfile().GetPlayerID() : 0); foreach (Container container in containers) { if (!((Object)(object)container.m_nview == (Object)null) && container.m_nview.IsValid() && !(Vector3.Distance(((Component)container).transform.position, point) > range) && !container.IsInUse() && container.CheckAccess(num) && (!container.m_checkGuardStone || PrivateArea.CheckAccess(((Component)container).transform.position, 0f, false, false))) { container.Load(); list.Add(container); } } return list; } private static List<StorageSource> FindAroundPlayer(Player player) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) return FindSources(((Component)player).transform.position, Plugin.containerRange.Value); } internal static int CountItems(Player player, string sharedName, int quality = -1) { int num = 0; foreach (StorageSource item in FindAroundPlayer(player)) { num += item.Inventory.CountItems(sharedName, quality, true); } return num; } internal static int RemoveItems(Player player, string sharedName, int amount, int quality = -1, string context = "consume", string? visualPrefab = null) { //IL_00bf: Unknown result type (might be due to invalid IL or missing references) int num = amount; foreach (StorageSource item in FindAroundPlayer(player)) { if (num <= 0) { break; } Inventory inventory = item.Inventory; int num2 = inventory.CountItems(sharedName, quality, true); if (num2 > 0) { int num3 = Math.Min(num2, num); item.BeginChange(); inventory.RemoveItem(sharedName, num3, quality, true); item.CommitChange(); num -= num3; Plugin.LogPull($"took {num3}x {sharedName} from {Describe(item)} ({context})"); if (visualPrefab != null) { FlyingItems.QueueFromContainer(visualPrefab, player, item.Position); } } } return amount - num; } internal static int PullToPlayer(Player player, string sharedName, int amount, string context) { int num = amount; Inventory inventory = ((Humanoid)player).GetInventory(); foreach (StorageSource item in FindAroundPlayer(player)) { if (num <= 0) { break; } Inventory inventory2 = item.Inventory; bool flag = false; bool flag2 = false; foreach (ItemData item2 in new List<ItemData>(inventory2.GetAllItems())) { if (num <= 0) { break; } if (item2.m_shared.m_name != sharedName) { continue; } int num2 = Math.Min(item2.m_stack, num); item.BeginChange(); if (num2 >= item2.m_stack) { if (!inventory.AddItem(item2)) { flag2 = true; break; } inventory2.RemoveItem(item2); } else { ItemData val = item2.Clone(); val.m_stack = num2; if (!inventory.AddItem(val)) { flag2 = true; break; } item2.m_stack -= num2; inventory2.Changed(); } flag = true; num -= num2; Plugin.LogPull($"pulled {num2}x {sharedName} from {Describe(item)} ({context})"); } if (flag) { item.CommitChange(); } if (flag2) { return amount - num; } } return amount - num; } private static string Describe(StorageSource source) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) Vector3 position = source.Position; return $"{source.Name} at ({position.x:0},{position.y:0},{position.z:0})"; } } [HarmonyPatch(typeof(Container), "Awake")] public static class Container_Awake_RegisterNearby { private static void Postfix(Container __instance) { NearbyContainers.Register(__instance); } } [BepInPlugin("org.bepinex.plugins.valheimstorage", "Valheim Storage", "1.3.2")] public class Plugin : BaseUnityPlugin { private const string guid = "org.bepinex.plugins.valheimstorage"; private const string pluginName = "Valheim Storage"; private const string version = "1.3.2"; internal static Plugin instance; public static ConfigEntry<float> containerRange; public static ConfigEntry<bool> enableCrafting; public static ConfigEntry<bool> enableBuilding; public static ConfigEntry<bool> enableSmelters; public static ConfigEntry<bool> enableFireplaces; public static ConfigEntry<bool> enableCookingStations; public static ConfigEntry<bool> enableTurrets; public static ConfigEntry<string> stationDisallow; public static ConfigEntry<string> fuelDisallow; public static ConfigEntry<string> oreDisallow; public static ConfigEntry<KeyboardShortcut> fillModifier; public static ConfigEntry<KeyboardShortcut> pullModifier; public static ConfigEntry<KeyboardShortcut> preventModifier; public static ConfigEntry<bool> switchPrevent; public static ConfigEntry<KeyboardShortcut> favoriteModifier; public static ConfigEntry<bool> showAvailable; public static ConfigEntry<Color> flashColor; public static ConfigEntry<bool> logPulls; private void Awake() { //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_023b: Unknown result type (might be due to invalid IL or missing references) //IL_027f: 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) instance = this; containerRange = ((BaseUnityPlugin)this).Config.Bind<float>("General", "ContainerRange", 20f, "Radius in meters around the player in which chests (and placed backpacks) are used."); logPulls = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "LogPulls", true, "Write an info log entry for every resource pulled from a container, so you can retrace what happened."); enableCrafting = ((BaseUnityPlugin)this).Config.Bind<bool>("Stations", "Crafting", true, "Use containers when crafting and upgrading items at crafting stations."); enableBuilding = ((BaseUnityPlugin)this).Config.Bind<bool>("Stations", "Building", true, "Use containers when building pieces with the hammer."); enableSmelters = ((BaseUnityPlugin)this).Config.Bind<bool>("Stations", "Smelters", true, "Use containers when adding ore and fuel to smelters, kilns, blast furnaces, spinning wheels and windmills."); enableFireplaces = ((BaseUnityPlugin)this).Config.Bind<bool>("Stations", "Fireplaces", true, "Use containers when adding fuel to fires, standing torches, sconces and hearths."); enableCookingStations = ((BaseUnityPlugin)this).Config.Bind<bool>("Stations", "CookingStations", true, "Use containers when cooking food and fueling ovens."); enableTurrets = ((BaseUnityPlugin)this).Config.Bind<bool>("Stations", "Turrets", true, "Use containers when reloading ballista turrets."); stationDisallow = ((BaseUnityPlugin)this).Config.Bind<string>("Stations", "StationDisallow", "", "Comma separated list of station prefab names that never use containers, no spaces (e.g. piece_workbench,smelter)."); fuelDisallow = ((BaseUnityPlugin)this).Config.Bind<string>("Items", "FuelDisallowTypes", "", "Comma separated list of fuel item prefab names that are never pulled from containers, no spaces (e.g. RoundLog,FineWood). Does not apply to kilns, which treat wood as ore."); oreDisallow = ((BaseUnityPlugin)this).Config.Bind<string>("Items", "OreDisallowTypes", "", "Comma separated list of ore/cookable item prefab names (anything a station transforms) that are never pulled from containers, no spaces."); fillModifier = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Keys", "FillModifier", new KeyboardShortcut((KeyCode)304, Array.Empty<KeyCode>()), "While held, ore/fuel/ammo is pulled until the station is full instead of one at a time."); pullModifier = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Keys", "PullModifier", new KeyboardShortcut((KeyCode)306, Array.Empty<KeyCode>()), "While held, station interactions pull the resources into your inventory instead of feeding the station."); preventModifier = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Keys", "PreventModifier", new KeyboardShortcut((KeyCode)308, Array.Empty<KeyCode>()), "While held, the mod does nothing (vanilla behavior)."); switchPrevent = ((BaseUnityPlugin)this).Config.Bind<bool>("Keys", "SwitchPrevent", false, "Reverses PreventModifier: the mod only works WHILE the key is held."); favoriteModifier = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Keys", "FavoriteModifier", new KeyboardShortcut((KeyCode)308, Array.Empty<KeyCode>()), "Held while left-clicking an inventory item to mark/unmark it as favorite. Favorites are skipped by stack-all and cannot be dropped."); showAvailable = ((BaseUnityPlugin)this).Config.Bind<bool>("UI", "ShowAvailable", true, "Requirement amounts also show the total available including nearby containers, e.g. \"10 (34)\"."); flashColor = ((BaseUnityPlugin)this).Config.Bind<Color>("UI", "FlashColor", Color.yellow, "Requirement color when your inventory alone is short but nearby containers cover it."); new Harmony("org.bepinex.plugins.valheimstorage").PatchAll(Assembly.GetExecutingAssembly()); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Loading [Valheim Storage 1.3.2]"); } internal static void LogPull(string message) { if (logPulls.Value) { ((BaseUnityPlugin)instance).Logger.LogInfo((object)message); } } internal static bool ModActive() { //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) KeyboardShortcut value = preventModifier.Value; bool flag = ((KeyboardShortcut)(ref value)).IsPressed(); return switchPrevent.Value ? flag : (!flag); } internal static bool FillMode() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) KeyboardShortcut value = fillModifier.Value; return ((KeyboardShortcut)(ref value)).IsPressed(); } internal static bool PullMode() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) KeyboardShortcut value = pullModifier.Value; return ((KeyboardShortcut)(ref value)).IsPressed(); } internal static bool StationAllowed(GameObject stationObject) { return !ListContains(stationDisallow.Value, PrefabName(((Object)stationObject).name)); } internal static bool ItemDisallowed(ItemDrop? item, ConfigEntry<string> list) { return (Object)(object)item != (Object)null && ListContains(list.Value, ((Object)((Component)item).gameObject).name); } internal static string PrefabName(string gameObjectName) { int num = gameObjectName.IndexOf('('); return (num >= 0) ? gameObjectName.Substring(0, num) : gameObjectName; } private static bool ListContains(string commaSeparated, string name) { if (string.IsNullOrEmpty(commaSeparated)) { return false; } string[] array = commaSeparated.Split(new char[1] { ',' }); foreach (string text in array) { if (string.Equals(text.Trim(), name, StringComparison.OrdinalIgnoreCase)) { return true; } } return false; } } [HarmonyPatch(typeof(ZNetScene), "Awake")] public static class ZNetScene_Awake_RegisterStorageRpc { private static void Postfix() { FlyingItems.RegisterRpc(); } } public static class QuickStack { [CompilerGenerated] private static class <>O { public static UnityAction <0>__OnClick; } private static GameObject? button; internal static void CreateButton(InventoryGui gui) { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Expected O, but got Unknown //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Expected O, but got Unknown //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Expected O, but got Unknown //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Expected O, but got Unknown //IL_0204: Unknown result type (might be due to invalid IL or missing references) //IL_020b: Expected O, but got Unknown //IL_0217: Unknown result type (might be due to invalid IL or missing references) //IL_022e: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)button != (Object)null) && !((Object)(object)gui.m_takeAllButton == (Object)null)) { button = Object.Instantiate<GameObject>(((Component)gui.m_takeAllButton).gameObject, (Transform)(object)gui.m_player); ((Object)button).name = "VS_QuickStackButton"; RectTransform val = (RectTransform)button.transform; if (Chainloader.PluginInfos.ContainsKey("randyknapp.mods.equipmentandquickslots")) { val.anchorMin = new Vector2(0f, 1f); val.anchorMax = new Vector2(0f, 1f); val.pivot = new Vector2(0f, 0.5f); val.anchoredPosition = new Vector2(890f, -326f); } else { val.anchorMin = new Vector2(1f, 1f); val.anchorMax = new Vector2(1f, 1f); val.pivot = new Vector2(0f, 1f); val.anchoredPosition = new Vector2(12f, -80f); } Button component = button.GetComponent<Button>(); component.onClick = new ButtonClickedEvent(); ButtonClickedEvent onClick = component.onClick; object obj = <>O.<0>__OnClick; if (obj == null) { UnityAction val2 = OnClick; <>O.<0>__OnClick = val2; obj = (object)val2; } ((UnityEvent)onClick).AddListener((UnityAction)obj); TMP_Text componentInChildren = button.GetComponentInChildren<TMP_Text>(true); if ((Object)(object)componentInChildren != (Object)null) { componentInChildren.text = "Stack"; } Sprite val3 = ChestIcon(); if ((Object)(object)val3 != (Object)null) { GameObject val4 = new GameObject("Icon", new Type[1] { typeof(RectTransform) }); val4.transform.SetParent(button.transform, false); Image val5 = val4.AddComponent<Image>(); val5.sprite = val3; ((Graphic)val5).raycastTarget = false; RectTransform val6 = (RectTransform)val4.transform; val6.sizeDelta = new Vector2(24f, 24f); val6.anchoredPosition = new Vector2(0f, 18f); } } } private static Sprite? ChestIcon() { GameObject val = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.GetPrefab("piece_chest_wood") : null); Piece val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<Piece>() : null); return ((Object)(object)val2 != (Object)null) ? val2.m_icon : null; } private static void OnClick() { InventoryGui instance = InventoryGui.instance; if ((Object)(object)instance != (Object)null && (Object)(object)instance.m_dragGo != (Object)null && instance.m_dragItem != null) { RunSingle(Player.m_localPlayer, instance); } else { Run(Player.m_localPlayer); } } private static void RunSingle(Player? player, InventoryGui gui) { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) ItemData dragItem = gui.m_dragItem; gui.SetupDragItem((ItemData)null, (Inventory)null, 1); if ((Object)(object)player == (Object)null || dragItem == null) { return; } string name = dragItem.m_shared.m_name; Inventory inventory = ((Humanoid)player).GetInventory(); int num = inventory.CountItems(name, -1, true); foreach (StorageSource item in NearbyContainers.FindSources(((Component)player).transform.position, Plugin.containerRange.Value)) { Inventory inventory2 = item.Inventory; if (!inventory2.ContainsItemByName(name)) { continue; } item.BeginChange(); foreach (ItemData item2 in new List<ItemData>(inventory.GetAllItems())) { if (!(item2.m_shared.m_name != name) && !((Humanoid)player).IsItemEquiped(item2) && (!FavoriteItems.IsFavorite(item2) || item2 == dragItem) && inventory2.AddItem(item2)) { inventory.RemoveItem(item2); FlyingItems.Queue(item2, player, item.Position); } } inventory2.Changed(); item.CommitChange(); } FlyingItems.Flush(); inventory.Changed(); int num2 = num - inventory.CountItems(name, -1, true); ((Character)player).Message((MessageType)2, (num2 > 0) ? $"Stacked {num2} x {name} into nearby containers" : ("No nearby container holds " + name), 0, (Sprite)null); } internal static void Run(Player? player) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null) { return; } int num = ((Humanoid)player).GetInventory().CountItems((string)null, -1, true); List<ItemData> list = new List<ItemData>(((Humanoid)player).GetInventory().GetAllItems()); foreach (StorageSource item in NearbyContainers.FindSources(((Component)player).transform.position, Plugin.containerRange.Value)) { item.BeginChange(); item.Inventory.StackAll(((Humanoid)player).GetInventory(), false); item.CommitChange(); List<ItemData> allItems = ((Humanoid)player).GetInventory().GetAllItems(); foreach (ItemData item2 in list) { if (!allItems.Contains(item2)) { FlyingItems.Queue(item2, player, item.Position); } } list = new List<ItemData>(allItems); } FlyingItems.Flush(); int num2 = num - ((Humanoid)player).GetInventory().CountItems((string)null, -1, true); ((Character)player).Message((MessageType)2, (num2 > 0) ? $"Stacked {num2} items into nearby containers" : "Nothing to stack", 0, (Sprite)null); } } [HarmonyPatch(typeof(InventoryGui), "Awake")] public static class InventoryGui_Awake_QuickStackButton { private static void Postfix(InventoryGui __instance) { QuickStack.CreateButton(__instance); } } internal static class Feeding { internal static bool Allowed(ConfigEntry<bool> feature, Component station, Humanoid user) { return (Object)(object)user == (Object)(object)Player.m_localPlayer && Plugin.ModActive() && feature.Value && Plugin.StationAllowed(station.gameObject); } internal static string Label(Component station) { return Plugin.PrefabName(((Object)station.gameObject).name); } internal static int Borrow(Player player, string sharedName, int want, string context) { int num = ((Humanoid)player).GetInventory().CountItems(sharedName, -1, true); if (num < want) { num += NearbyContainers.PullToPlayer(player, sharedName, want - num, context); } return Math.Min(num, want); } internal static void PullInstead(Player player, ItemDrop item, string context) { int amount = ((!Plugin.FillMode()) ? 1 : item.m_itemData.m_shared.m_maxStackSize); int num = NearbyContainers.PullToPlayer(player, item.m_itemData.m_shared.m_name, amount, context); ((Character)player).Message((MessageType)2, (num > 0) ? $"Pulled {num}x {item.m_itemData.m_shared.m_name}" : ("$msg_donthaveany " + item.m_itemData.m_shared.m_name), 0, (Sprite)null); } } [HarmonyPatch(typeof(Fireplace), "Interact")] public static class Fireplace_Interact_Feed { private static bool Prefix(Fireplace __instance, Humanoid user, bool hold, ref bool __result) { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Expected O, but got Unknown if (hold || __instance.m_infiniteFuel || (Object)(object)__instance.m_fuelItem == (Object)null || !Feeding.Allowed(Plugin.enableFireplaces, (Component)(object)__instance, user) || Plugin.ItemDisallowed(__instance.m_fuelItem, Plugin.fuelDisallow)) { return true; } Player val = (Player)user; string name = __instance.m_fuelItem.m_itemData.m_shared.m_name; string context = "fuel for " + Feeding.Label((Component)(object)__instance); if (Plugin.PullMode()) { Feeding.PullInstead(val, __instance.m_fuelItem, context); __result = true; return false; } int num = (int)__instance.m_maxFuel - Mathf.CeilToInt(__instance.m_nview.GetZDO().GetFloat(ZDOVars.s_fuel, 0f)); if (num <= 0) { return true; } int num2 = Feeding.Borrow(val, name, (!Plugin.FillMode()) ? 1 : num, context); if (Plugin.FillMode() && num2 > 0) { for (int i = 0; i < num2; i++) { ((Humanoid)val).GetInventory().RemoveItem(name, 1, -1, true); __instance.m_nview.InvokeRPC("RPC_AddFuel", Array.Empty<object>()); } Plugin.LogPull($"added {num2}x {name} to {Feeding.Label((Component)(object)__instance)}"); ((Character)val).Message((MessageType)2, Localization.instance.Localize("$msg_fireadding", new string[1] { name }), 0, (Sprite)null); __result = true; return false; } return true; } } [HarmonyPatch(typeof(Smelter), "OnAddFuel")] public static class Smelter_OnAddFuel_Feed { private static bool Prefix(Smelter __instance, Humanoid user, ItemData item, ref bool __result) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown if (item != null || (Object)(object)__instance.m_fuelItem == (Object)null || !Feeding.Allowed(Plugin.enableSmelters, (Component)(object)__instance, user) || Plugin.ItemDisallowed(__instance.m_fuelItem, Plugin.fuelDisallow)) { return true; } Player val = (Player)user; string name = __instance.m_fuelItem.m_itemData.m_shared.m_name; string context = "fuel for " + Feeding.Label((Component)(object)__instance); if (Plugin.PullMode()) { Feeding.PullInstead(val, __instance.m_fuelItem, context); __result = true; return false; } int num = __instance.m_maxFuel - Mathf.CeilToInt(__instance.GetFuel()); if (num <= 0) { return true; } int num2 = Feeding.Borrow(val, name, (!Plugin.FillMode()) ? 1 : num, context); if (Plugin.FillMode() && num2 > 0) { for (int i = 0; i < num2; i++) { ((Humanoid)val).GetInventory().RemoveItem(name, 1, -1, true); __instance.m_nview.InvokeRPC("RPC_AddFuel", Array.Empty<object>()); } Plugin.LogPull($"added {num2}x {name} to {Feeding.Label((Component)(object)__instance)}"); __result = true; return false; } return true; } } [HarmonyPatch(typeof(Smelter), "OnAddOre")] public static class Smelter_OnAddOre_Feed { private static bool Prefix(Smelter __instance, Humanoid user, ItemData item, ref bool __result) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown if (!Feeding.Allowed(Plugin.enableSmelters, (Component)(object)__instance, user)) { return true; } Player val = (Player)user; ItemData val2 = item ?? __instance.FindCookableItem(((Humanoid)val).GetInventory()); ItemConversion val3 = null; if (val2 != null) { val3 = FindConversion(__instance, val2.m_shared.m_name); } else { foreach (ItemConversion item2 in __instance.m_conversion) { if ((Object)(object)item2.m_from != (Object)null && !Plugin.ItemDisallowed(item2.m_from, Plugin.oreDisallow) && NearbyContainers.CountItems(val, item2.m_from.m_itemData.m_shared.m_name) > 0) { val3 = item2; break; } } } if ((Object)(object)val3?.m_from == (Object)null || Plugin.ItemDisallowed(val3.m_from, Plugin.oreDisallow)) { return true; } string name = val3.m_from.m_itemData.m_shared.m_name; string name2 = ((Object)((Component)val3.m_from).gameObject).name; string context = "ore for " + Feeding.Label((Component)(object)__instance); if (Plugin.PullMode()) { Feeding.PullInstead(val, val3.m_from, context); __result = true; return false; } int num = __instance.m_maxOre - __instance.GetQueueSize(); if (num <= 0) { return true; } int num2 = Feeding.Borrow(val, name, (!Plugin.FillMode()) ? 1 : num, context); if (Plugin.FillMode() && num2 > 0) { for (int i = 0; i < num2; i++) { ((Humanoid)val).GetInventory().RemoveItem(name, 1, -1, true); __instance.m_nview.InvokeRPC("RPC_AddOre", new object[1] { name2 }); } Plugin.LogPull($"added {num2}x {name} to {Feeding.Label((Component)(object)__instance)}"); __result = true; return false; } return true; } private static ItemConversion? FindConversion(Smelter smelter, string sharedName) { foreach (ItemConversion item in smelter.m_conversion) { if ((Object)(object)item.m_from != (Object)null && item.m_from.m_itemData.m_shared.m_name == sharedName) { return item; } } return null; } } [HarmonyPatch(typeof(CookingStation), "OnAddFuelSwitch")] public static class CookingStation_OnAddFuelSwitch_Feed { private static bool reentrant; private static void Prefix(CookingStation __instance, Humanoid user, ItemData item, ref int __state) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Expected O, but got Unknown __state = 0; if (!reentrant && item == null && !((Object)(object)__instance.m_fuelItem == (Object)null) && Feeding.Allowed(Plugin.enableCookingStations, (Component)(object)__instance, user) && !Plugin.ItemDisallowed(__instance.m_fuelItem, Plugin.fuelDisallow)) { Player player = (Player)user; string name = __instance.m_fuelItem.m_itemData.m_shared.m_name; int num = __instance.m_maxFuel - Mathf.CeilToInt(__instance.GetFuel()); if (num > 0) { int num2 = Feeding.Borrow(player, name, (!Plugin.FillMode()) ? 1 : num, "fuel for " + Feeding.Label((Component)(object)__instance)); __state = (Plugin.FillMode() ? num2 : 0); } } } private static void Postfix(CookingStation __instance, Switch sw, Humanoid user, bool __result, int __state) { if (reentrant || !__result || __state <= 1) { return; } reentrant = true; for (int i = 1; i < __state; i++) { if (!__instance.OnAddFuelSwitch(sw, user, (ItemData)null)) { break; } } reentrant = false; } } [HarmonyPatch(typeof(CookingStation), "OnInteract")] public static class CookingStation_OnInteract_Feed { private static bool reentrant; private static void Prefix(CookingStation __instance, Humanoid user) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Expected O, but got Unknown if (!reentrant && Feeding.Allowed(Plugin.enableCookingStations, (Component)(object)__instance, user)) { BorrowCookable(__instance, (Player)user); } } private static void Postfix(CookingStation __instance, Humanoid user, bool __result) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown if (reentrant || !__result || !Plugin.FillMode() || !Feeding.Allowed(Plugin.enableCookingStations, (Component)(object)__instance, user)) { return; } reentrant = true; Player val = (Player)user; for (int i = 0; i < 16; i++) { if (__instance.GetFreeSlot() == -1) { break; } if (__instance.FindCookableItem(((Humanoid)val).GetInventory()) == null && !BorrowCookable(__instance, val)) { break; } if (!__instance.OnInteract(user)) { break; } } reentrant = false; } private static bool BorrowCookable(CookingStation station, Player player) { if (station.FindCookableItem(((Humanoid)player).GetInventory()) != null) { return true; } foreach (ItemConversion item in station.m_conversion) { if (!((Object)(object)item.m_from == (Object)null) && !Plugin.ItemDisallowed(item.m_from, Plugin.oreDisallow)) { string name = item.m_from.m_itemData.m_shared.m_name; if (NearbyContainers.PullToPlayer(player, name, 1, "food for " + Feeding.Label((Component)(object)station)) > 0) { return true; } } } return false; } } [HarmonyPatch(typeof(Turret), "Interact")] public static class Turret_Interact_Feed { private static bool Prefix(Turret __instance, Humanoid character, bool hold, ref bool __result) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) if (hold || !Feeding.Allowed(Plugin.enableTurrets, (Component)(object)__instance, character)) { return true; } Player val = (Player)character; foreach (AmmoType item in __instance.m_allowedAmmo) { if ((Object)(object)item.m_ammo == (Object)null) { continue; } string name = item.m_ammo.m_itemData.m_shared.m_name; if (NearbyContainers.CountItems(val, name) <= 0 && ((Humanoid)val).GetInventory().CountItems(name, -1, true) <= 0) { continue; } string context = "ammo for " + Feeding.Label((Component)(object)__instance); if (Plugin.PullMode()) { Feeding.PullInstead(val, item.m_ammo, context); __result = true; return false; } int num = ((__instance.m_maxAmmo <= 0) ? 1 : (__instance.m_maxAmmo - __instance.GetAmmo())); if (num <= 0) { return true; } Feeding.Borrow(val, name, (!Plugin.FillMode()) ? 1 : num, context); return true; } return true; } } public abstract class StorageSource { public abstract Inventory Inventory { get; } public abstract Vector3 Position { get; } public abstract string Name { get; } public abstract ZDOID Id { get; } public abstract void BeginChange(); public abstract void CommitChange(); } public sealed class LiveContainerSource : StorageSource { private readonly Container container; public override Inventory Inventory => container.GetInventory(); public override Vector3 Position => ((Component)container).transform.position; public override string Name => Plugin.PrefabName(((Object)((Component)container).gameObject).name); public override ZDOID Id => container.m_nview.GetZDO().m_uid; public LiveContainerSource(Container container) { this.container = container; } public override void BeginChange() { container.m_nview.ClaimOwnership(); } public override void CommitChange() { } } } namespace MovableValheimStorageStack { [BepInPlugin("valheimstorage.movablestackbutton", "Movable ValheimStorage Stack Button", "1.1.0")] public sealed class Plugin : BaseUnityPlugin { private const string PluginGuid = "valheimstorage.movablestackbutton"; private const string PluginName = "Movable ValheimStorage Stack Button"; private const string PluginVersion = "1.1.0"; private ConfigEntry<bool> _hasSavedPosition; private ConfigEntry<float> _savedX; private ConfigEntry<float> _savedY; private RectTransform _button; private bool _dragging; private Vector2 _lastMousePosition; private void Awake() { _hasSavedPosition = ((BaseUnityPlugin)this).Config.Bind<bool>("Position", "Saved", false, "Whether a custom Stack-button position has been saved."); _savedX = ((BaseUnityPlugin)this).Config.Bind<float>("Position", "X", 0f, "Saved X position of the ValheimStorage Stack button."); _savedY = ((BaseUnityPlugin)this).Config.Bind<float>("Position", "Y", 0f, "Saved Y position of the ValheimStorage Stack button."); } private void Update() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) EnsureButton(); if (!((Object)(object)_button == (Object)null)) { Vector2 val = Vector2.op_Implicit(Input.mousePosition); if (!_dragging && Input.GetMouseButtonDown(1) && IsMouseOverButton(val)) { _dragging = true; _lastMousePosition = val; } if (_dragging && Input.GetMouseButton(1)) { Vector2 val2 = val - _lastMousePosition; _lastMousePosition = val; Canvas componentInParent = ((Component)_button).GetComponentInParent<Canvas>(); float num = (((Object)(object)componentInParent != (Object)null && componentInParent.scaleFactor > 0f) ? componentInParent.scaleFactor : 1f); RectTransform button = _button; button.anchoredPosition += val2 / num; } if (_dragging && Input.GetMouseButtonUp(1)) { _dragging = false; Vector2 anchoredPosition = _button.anchoredPosition; _savedX.Value = anchoredPosition.x; _savedY.Value = anchoredPosition.y; _hasSavedPosition.Value = true; } } } private void EnsureButton() { if ((Object)(object)_button != (Object)null) { return; } Button[] array = Resources.FindObjectsOfTypeAll<Button>(); foreach (Button val in array) { if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).gameObject == (Object)null || !((Component)val).gameObject.activeInHierarchy) { continue; } string text = ((Object)((Component)val).gameObject).name ?? ""; if (text.IndexOf("stack", StringComparison.OrdinalIgnoreCase) >= 0) { SetButton(((Component)val).GetComponent<RectTransform>()); if ((Object)(object)_button != (Object)null) { break; } } Text[] componentsInChildren = ((Component)val).GetComponentsInChildren<Text>(true); for (int j = 0; j < componentsInChildren.Length; j++) { string text2 = (((Object)(object)componentsInChildren[j] != (Object)null) ? componentsInChildren[j].text : null); if (!string.IsNullOrEmpty(text2) && text2.IndexOf("stack", StringComparison.OrdinalIgnoreCase) >= 0) { SetButton(((Component)val).GetComponent<RectTransform>()); if ((Object)(object)_button != (Object)null) { return; } } } } } private void SetButton(RectTransform rect) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)rect == (Object)null)) { _button = rect; if (_hasSavedPosition.Value) { _button.anchoredPosition = new Vector2(_savedX.Value, _savedY.Value); } } } private bool IsMouseOverButton(Vector2 mousePosition) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) Canvas componentInParent = ((Component)_button).GetComponentInParent<Canvas>(); Camera val = null; if ((Object)(object)componentInParent != (Object)null && (int)componentInParent.renderMode != 0) { val = componentInParent.worldCamera; } return RectTransformUtility.RectangleContainsScreenPoint(_button, mousePosition, val); } } }