Please disclose if your mod was created primarily 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 CraftFromContainers v3.5.2
CraftFromContainers.dll
Decompiled 2 years agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using TMPro; using UnityEngine; 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: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyVersion("1.0.0.0")] namespace CraftFromContainers; [BepInPlugin("aedenthorn.CraftFromContainers", "Craft From Containers", "3.5.1")] public class BepInExPlugin : BaseUnityPlugin { public class ConnectionParams { public GameObject connection; public Vector3 stationPos; } [HarmonyPatch(typeof(FejdStartup), "Awake")] private static class FejdStartup_Awake_Patch { private static void Postfix(FejdStartup __instance) { if (modEnabled.Value) { CheckOdinsQOLConfig(); } } } [HarmonyPatch(typeof(Container), "Awake")] private static class Container_Awake_Patch { private static void Postfix(Container __instance, ZNetView ___m_nview) { ((MonoBehaviour)context).StartCoroutine(AddContainer(__instance, ___m_nview)); } } [HarmonyPatch(typeof(Container), "OnDestroyed")] private static class Container_OnDestroyed_Patch { private static void Prefix(Container __instance) { containerList.Remove(__instance); } } [HarmonyPatch(typeof(InventoryGui), "Update")] private static class InventoryGui_Update_Patch { private static void Prefix(InventoryGui __instance, Animator ___m_animator) { if (Object.op_Implicit((Object)(object)Player.m_localPlayer) && wasAllowed != AllowByKey() && ___m_animator.GetBool("visible")) { AccessTools.Method(typeof(InventoryGui), "UpdateCraftingPanel", (Type[])null, (Type[])null).Invoke(__instance, new object[1] { false }); } } } [HarmonyPatch(typeof(Fireplace), "Interact")] private static class Fireplace_Interact_Patch { private static bool Prefix(Fireplace __instance, Humanoid user, bool hold, ref bool __result, ZNetView ___m_nview) { //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_0266: Unknown result type (might be due to invalid IL or missing references) //IL_02e5: Unknown result type (might be due to invalid IL or missing references) __result = true; bool flag = CheckKeyHeld(fillAllModKey.Value); Inventory inventory = user.GetInventory(); if (!AllowByKey() || hold || inventory == null || (inventory.HaveItem(__instance.m_fuelItem.m_itemData.m_shared.m_name, true) && !flag)) { return true; } if (!___m_nview.HasOwner()) { ___m_nview.ClaimOwnership(); } if (flag && inventory.HaveItem(__instance.m_fuelItem.m_itemData.m_shared.m_name, true)) { int num = (int)Mathf.Min(__instance.m_maxFuel - (float)Mathf.CeilToInt(___m_nview.GetZDO().GetFloat("fuel", 0f)), (float)inventory.CountItems(__instance.m_fuelItem.m_itemData.m_shared.m_name, -1, true)); inventory.RemoveItem(__instance.m_fuelItem.m_itemData.m_shared.m_name, num, -1, true); typeof(Inventory).GetMethod("Changed", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(inventory, new object[0]); for (int i = 0; i < num; i++) { ___m_nview.InvokeRPC("RPC_AddFuel", new object[0]); } ((Character)user).Message((MessageType)2, Localization.instance.Localize("$msg_fireadding", new string[1] { __instance.m_fuelItem.m_itemData.m_shared.m_name }), 0, (Sprite)null); __result = false; } if (!inventory.HaveItem(__instance.m_fuelItem.m_itemData.m_shared.m_name, true) && (float)Mathf.CeilToInt(___m_nview.GetZDO().GetFloat("fuel", 0f)) < __instance.m_maxFuel) { foreach (Container nearbyContainer in GetNearbyContainers(((Component)__instance).transform.position)) { ItemData item = nearbyContainer.GetInventory().GetItem(__instance.m_fuelItem.m_itemData.m_shared.m_name, -1, false); if (item == null || !((float)Mathf.CeilToInt(___m_nview.GetZDO().GetFloat("fuel", 0f)) < __instance.m_maxFuel)) { continue; } if (fuelDisallowTypes.Value.Split(new char[1] { ',' }).Contains(((Object)item.m_dropPrefab).name)) { Dbgl($"container at {((Component)nearbyContainer).transform.position} has {item.m_stack} {((Object)item.m_dropPrefab).name} but it's forbidden by config"); continue; } int num2 = ((!flag) ? 1 : ((int)Mathf.Min(__instance.m_maxFuel - (float)Mathf.CeilToInt(___m_nview.GetZDO().GetFloat("fuel", 0f)), (float)item.m_stack))); Dbgl($"container at {((Component)nearbyContainer).transform.position} has {item.m_stack} {((Object)item.m_dropPrefab).name}, taking {num2}"); nearbyContainer.GetInventory().RemoveItem(__instance.m_fuelItem.m_itemData.m_shared.m_name, num2, -1, true); typeof(Container).GetMethod("Save", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(nearbyContainer, new object[0]); if (__result) { ((Character)user).Message((MessageType)2, Localization.instance.Localize("$msg_fireadding", new string[1] { __instance.m_fuelItem.m_itemData.m_shared.m_name }), 0, (Sprite)null); } for (int j = 0; j < num2; j++) { ___m_nview.InvokeRPC("RPC_AddFuel", new object[0]); } __result = false; if (flag && !((float)Mathf.CeilToInt(___m_nview.GetZDO().GetFloat("fuel", 0f)) >= __instance.m_maxFuel)) { continue; } return false; } } return __result; } } [HarmonyPatch(typeof(CookingStation), "OnAddFuelSwitch")] private static class CookingStation_OnAddFuelSwitch_Patch { private static bool Prefix(CookingStation __instance, ref bool __result, Humanoid user, ItemData item, ZNetView ___m_nview) { //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) Dbgl("looking for fuel"); if (modEnabled.Value && AllowByKey() && item == null && (float)((object)__instance).GetType().GetMethod("GetFuel", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(__instance, new object[0]) <= (float)(__instance.m_maxFuel - 1) && !user.GetInventory().HaveItem(__instance.m_fuelItem.m_itemData.m_shared.m_name, true)) { Dbgl("missing fuel in player inventory"); foreach (Container nearbyContainer in GetNearbyContainers(((Component)__instance).transform.position)) { ItemData item2 = nearbyContainer.GetInventory().GetItem(__instance.m_fuelItem.m_itemData.m_shared.m_name, -1, false); if (item2 != null) { if (!fuelDisallowTypes.Value.Split(new char[1] { ',' }).Contains(((Object)item2.m_dropPrefab).name)) { Dbgl($"container at {((Component)nearbyContainer).transform.position} has {item2.m_stack} {((Object)item2.m_dropPrefab).name}, taking one"); nearbyContainer.GetInventory().RemoveItem(__instance.m_fuelItem.m_itemData.m_shared.m_name, 1, -1, true); typeof(Container).GetMethod("Save", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(nearbyContainer, new object[0]); ((Character)user).Message((MessageType)2, "$msg_added " + __instance.m_fuelItem.m_itemData.m_shared.m_name, 0, (Sprite)null); ___m_nview.InvokeRPC("RPC_AddFuel", Array.Empty<object>()); __result = true; return false; } Dbgl($"container at {((Component)nearbyContainer).transform.position} has {item2.m_stack} {((Object)item2.m_dropPrefab).name} but it's forbidden by config"); } } return true; } return true; } } [HarmonyPatch(typeof(CookingStation), "FindCookableItem")] private static class CookingStation_FindCookableItem_Patch { private static void Postfix(CookingStation __instance, ref ItemData __result) { //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) Dbgl("looking for cookable"); if (!modEnabled.Value || !AllowByKey() || __result != null || (__instance.m_requireFire && !(bool)typeof(CookingStation).GetMethod("IsFireLit", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(__instance, new object[0])) || (int)typeof(CookingStation).GetMethod("GetFreeSlot", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(__instance, new object[0]) == -1) { return; } Dbgl("missing cookable in player inventory"); List<Container> nearbyContainers = GetNearbyContainers(((Component)__instance).transform.position); foreach (ItemConversion item2 in __instance.m_conversion) { foreach (Container item3 in nearbyContainers) { ItemData item = item3.GetInventory().GetItem(item2.m_from.m_itemData.m_shared.m_name, -1, false); if (item != null) { if (!oreDisallowTypes.Value.Split(new char[1] { ',' }).Contains(((Object)item.m_dropPrefab).name)) { Dbgl($"container at {((Component)item3).transform.position} has {item.m_stack} {((Object)item.m_dropPrefab).name}, taking one"); __result = item; item3.GetInventory().RemoveItem(item2.m_from.m_itemData.m_shared.m_name, 1, -1, true); typeof(Container).GetMethod("Save", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(item3, new object[0]); return; } Dbgl($"container at {((Component)item3).transform.position} has {item.m_stack} {((Object)item.m_dropPrefab).name} but it's forbidden by config"); } } } } } [HarmonyPatch(typeof(Smelter), "OnHoverAddFuel")] private static class Smelter_OnHoverAddFuel_Patch { private static void Postfix(Smelter __instance, ref string __result) { if (modEnabled.Value) { string value = fillAllModKey.Value; if (value != null && value.Length > 0) { __result += Localization.instance.Localize("\n[<color=yellow><b>" + fillAllModKey.Value + "+$KEY_Use</b></color>] $piece_smelter_add max"); } } } } [HarmonyPatch(typeof(Smelter), "OnHoverAddOre")] private static class Smelter_OnHoverAddOre_Patch { private static void Postfix(Smelter __instance, ref string __result) { if (modEnabled.Value) { string value = fillAllModKey.Value; if (value != null && value.Length > 0) { __result += Localization.instance.Localize("\n[<color=yellow><b>" + fillAllModKey.Value + "+$KEY_Use</b></color>] " + __instance.m_addOreTooltip + " max"); } } } } [HarmonyPatch(typeof(Smelter), "OnAddOre")] private static class Smelter_OnAddOre_Patch { private static bool Prefix(Smelter __instance, Humanoid user, ItemData item, ZNetView ___m_nview) { //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_031d: Unknown result type (might be due to invalid IL or missing references) //IL_03d8: Unknown result type (might be due to invalid IL or missing references) bool flag = CheckKeyHeld(fillAllModKey.Value); if (modEnabled.Value && (AllowByKey() || flag) && item == null && Traverse.Create((object)__instance).Method("GetQueueSize", Array.Empty<object>()).GetValue<int>() < __instance.m_maxOre) { Inventory inventory = user.GetInventory(); foreach (ItemConversion item4 in __instance.m_conversion) { if (inventory.HaveItem(item4.m_from.m_itemData.m_shared.m_name, true) && !flag) { return true; } } Dictionary<string, int> dictionary = new Dictionary<string, int>(); List<Container> nearbyContainers = GetNearbyContainers(((Component)__instance).transform.position); foreach (ItemConversion item5 in __instance.m_conversion) { if (Traverse.Create((object)__instance).Method("GetQueueSize", Array.Empty<object>()).GetValue<int>() >= __instance.m_maxOre || (dictionary.Any() && !flag)) { break; } string name = item5.m_from.m_itemData.m_shared.m_name; if (flag && inventory.HaveItem(name, true)) { ItemData item2 = inventory.GetItem(name, -1, false); if (oreDisallowTypes.Value.Split(new char[1] { ',' }).Contains(((Object)item2.m_dropPrefab).name)) { Dbgl($"player has {item2.m_stack} {((Object)item2.m_dropPrefab).name} but it's forbidden by config"); continue; } int num = ((!flag) ? 1 : Mathf.Min(__instance.m_maxOre - Traverse.Create((object)__instance).Method("GetQueueSize", Array.Empty<object>()).GetValue<int>(), inventory.CountItems(name, -1, true))); if (!dictionary.ContainsKey(name)) { dictionary[name] = 0; } dictionary[name] += num; inventory.RemoveItem(item5.m_from.m_itemData.m_shared.m_name, num, -1, true); for (int i = 0; i < num; i++) { ___m_nview.InvokeRPC("RPC_AddOre", new object[1] { ((Object)item2.m_dropPrefab).name }); } ((Character)user).Message((MessageType)1, $"$msg_added {num} {name}", 0, (Sprite)null); if (Traverse.Create((object)__instance).Method("GetQueueSize", Array.Empty<object>()).GetValue<int>() >= __instance.m_maxOre) { break; } } foreach (Container item6 in nearbyContainers) { ItemData item3 = item6.GetInventory().GetItem(name, -1, false); if (item3 == null) { continue; } if (oreDisallowTypes.Value.Split(new char[1] { ',' }).Contains(((Object)item3.m_dropPrefab).name)) { Dbgl($"container at {((Component)item6).transform.position} has {item3.m_stack} {((Object)item3.m_dropPrefab).name} but it's forbidden by config"); continue; } int num2 = ((!flag) ? 1 : Mathf.Min(__instance.m_maxOre - Traverse.Create((object)__instance).Method("GetQueueSize", Array.Empty<object>()).GetValue<int>(), item6.GetInventory().CountItems(name, -1, true))); if (!dictionary.ContainsKey(name)) { dictionary[name] = 0; } dictionary[name] += num2; Dbgl($"container at {((Component)item6).transform.position} has {item3.m_stack} {((Object)item3.m_dropPrefab).name}, taking {num2}"); item6.GetInventory().RemoveItem(name, num2, -1, true); typeof(Container).GetMethod("Save", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(item6, new object[0]); for (int j = 0; j < num2; j++) { ___m_nview.InvokeRPC("RPC_AddOre", new object[1] { ((Object)item3.m_dropPrefab).name }); } ((Character)user).Message((MessageType)1, $"$msg_added {num2} {name}", 0, (Sprite)null); if (Traverse.Create((object)__instance).Method("GetQueueSize", Array.Empty<object>()).GetValue<int>() < __instance.m_maxOre && flag) { continue; } break; } } if (!dictionary.Any()) { ((Character)user).Message((MessageType)2, "$msg_noprocessableitems", 0, (Sprite)null); } else { List<string> list = new List<string>(); foreach (KeyValuePair<string, int> item7 in dictionary) { list.Add($"$msg_added {item7.Value} {item7.Key}"); } ((Character)user).Message((MessageType)2, string.Join("\n", list), 0, (Sprite)null); } return false; } return true; } } [HarmonyPatch(typeof(Smelter), "OnAddFuel")] private static class Smelter_OnAddFuel_Patch { private static bool Prefix(Smelter __instance, ref bool __result, ZNetView ___m_nview, Humanoid user, ItemData item) { //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_02a7: Unknown result type (might be due to invalid IL or missing references) bool flag = CheckKeyHeld(fillAllModKey.Value); Inventory inventory = user.GetInventory(); if (!modEnabled.Value || (!AllowByKey() && !flag) || item != null || inventory == null || (inventory.HaveItem(__instance.m_fuelItem.m_itemData.m_shared.m_name, true) && !flag)) { return true; } __result = true; int num = 0; if ((float)typeof(Smelter).GetMethod("GetFuel", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(__instance, new object[0]) <= (float)(__instance.m_maxFuel - 1)) { if (flag && inventory.HaveItem(__instance.m_fuelItem.m_itemData.m_shared.m_name, true)) { int num2 = (int)Mathf.Min((float)__instance.m_maxFuel - (float)typeof(Smelter).GetMethod("GetFuel", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(__instance, new object[0]), (float)inventory.CountItems(__instance.m_fuelItem.m_itemData.m_shared.m_name, -1, true)); inventory.RemoveItem(__instance.m_fuelItem.m_itemData.m_shared.m_name, num2, -1, true); for (int i = 0; i < num2; i++) { ___m_nview.InvokeRPC("RPC_AddFuel", new object[0]); } num += num2; ((Character)user).Message((MessageType)1, Localization.instance.Localize("$msg_fireadding", new string[1] { __instance.m_fuelItem.m_itemData.m_shared.m_name }), 0, (Sprite)null); __result = false; } foreach (Container nearbyContainer in GetNearbyContainers(((Component)__instance).transform.position)) { ItemData item2 = nearbyContainer.GetInventory().GetItem(__instance.m_fuelItem.m_itemData.m_shared.m_name, -1, false); if (item2 == null) { continue; } if (fuelDisallowTypes.Value.Split(new char[1] { ',' }).Contains(((Object)item2.m_dropPrefab).name)) { Dbgl($"container at {((Component)nearbyContainer).transform.position} has {item2.m_stack} {((Object)item2.m_dropPrefab).name} but it's forbidden by config"); continue; } int num3 = ((!flag) ? 1 : ((int)Mathf.Min((float)__instance.m_maxFuel - (float)typeof(Smelter).GetMethod("GetFuel", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(__instance, new object[0]), (float)item2.m_stack))); Dbgl($"container at {((Component)nearbyContainer).transform.position} has {item2.m_stack} {((Object)item2.m_dropPrefab).name}, taking {num3}"); nearbyContainer.GetInventory().RemoveItem(__instance.m_fuelItem.m_itemData.m_shared.m_name, num3, -1, true); typeof(Container).GetMethod("Save", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(nearbyContainer, new object[0]); for (int j = 0; j < num3; j++) { ___m_nview.InvokeRPC("RPC_AddFuel", new object[0]); } num += num3; ((Character)user).Message((MessageType)1, "$msg_added " + __instance.m_fuelItem.m_itemData.m_shared.m_name, 0, (Sprite)null); __result = false; if (flag && Mathf.CeilToInt(___m_nview.GetZDO().GetFloat("fuel", 0f)) < __instance.m_maxFuel) { continue; } return false; } if (num == 0) { ((Character)user).Message((MessageType)2, "$msg_noprocessableitems", 0, (Sprite)null); } else { ((Character)user).Message((MessageType)2, $"$msg_added {num} {__instance.m_fuelItem.m_itemData.m_shared.m_name}", 0, (Sprite)null); } return __result; } ((Character)user).Message((MessageType)2, "$msg_itsfull", 0, (Sprite)null); __result = false; return false; } } [HarmonyPatch(typeof(InventoryGui), "SetupRequirement")] private static class InventoryGui_SetupRequirement_Patch { private static void Postfix(InventoryGui __instance, Transform elementRoot, Requirement req, Player player, bool craft, int quality) { //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) if (!modEnabled.Value || !AllowByKey() || !((Object)(object)req.m_resItem != (Object)null)) { return; } int num = ((Humanoid)player).GetInventory().CountItems(req.m_resItem.m_itemData.m_shared.m_name, -1, true); int amount = req.GetAmount(quality); if (amount <= 0) { return; } TMP_Text component = ((Component)((Component)elementRoot).transform.Find("res_amount")).GetComponent<TMP_Text>(); if (num < amount) { foreach (Container nearbyContainer in GetNearbyContainers(((Component)Player.m_localPlayer).transform.position)) { num += nearbyContainer.GetInventory().CountItems(req.m_resItem.m_itemData.m_shared.m_name, -1, true); } if (num >= amount) { ((Graphic)component).color = ((Mathf.Sin(Time.time * 10f) > 0f) ? flashColor.Value : unFlashColor.Value); } } if (resourceString.Value.Trim().Length > 0) { component.text = string.Format(resourceString.Value, num, amount); } else { component.text = amount.ToString(); } } } private static class InventoryGui_UpdateRecipeList_Patch { private static void Postfix(InventoryGui __instance, List<GameObject> ___m_recipeList) { if (!modEnabled.Value || !AllowByKey() || ___m_recipeList.Count == 0) { return; } foreach (GameObject ___m_recipe in ___m_recipeList) { _ = ___m_recipe; } } } [HarmonyPatch(typeof(Player), "HaveRequirementItems", new Type[] { typeof(Recipe), typeof(bool), typeof(int) })] private static class HaveRequirementItems_Patch { private static void Postfix(Player __instance, ref bool __result, Recipe piece, bool discover, int qualityLevel, HashSet<string> ___m_knownMaterial) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) if ((!modEnabled.Value | __result) || discover || !AllowByKey()) { return; } List<Container> nearbyContainers = GetNearbyContainers(((Component)__instance).transform.position); Requirement[] resources = piece.m_resources; foreach (Requirement val in resources) { if (!Object.op_Implicit((Object)(object)val.m_resItem)) { continue; } int amount = val.GetAmount(qualityLevel); int num = ((Humanoid)__instance).GetInventory().CountItems(val.m_resItem.m_itemData.m_shared.m_name, -1, true); if (num >= amount) { continue; } foreach (Container item in nearbyContainers) { num += item.GetInventory().CountItems(val.m_resItem.m_itemData.m_shared.m_name, -1, true); } if (num < amount) { return; } } __result = true; } } [HarmonyPatch(typeof(Player), "UpdateKnownRecipesList")] private static class UpdateKnownRecipesList_Patch { private static void Prefix() { skip = true; } private static void Postfix() { skip = false; } } [HarmonyPatch(typeof(Player), "HaveRequirements", new Type[] { typeof(Piece), typeof(RequirementMode) })] private static class HaveRequirements_Patch { private static void Postfix(Player __instance, ref bool __result, Piece piece, RequirementMode mode, HashSet<string> ___m_knownMaterial, Dictionary<string, int> ___m_knownStations) { //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Invalid comparison between Unknown and I4 //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Invalid comparison between Unknown and I4 //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Invalid comparison between Unknown and I4 //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Invalid comparison between Unknown and I4 //IL_01d9: Unknown result type (might be due to invalid IL or missing references) bool flag2; if (!(!modEnabled.Value | __result) && !skip) { bool flag; if ((Object)(object)__instance == (Object)null) { flag = true; } else { Transform transform = ((Component)__instance).transform; flag = !(((Object)(object)transform != (Object)null) ? new Vector3?(transform.position) : null).HasValue; } if (!flag) { flag2 = !AllowByKey(); goto IL_0069; } } flag2 = true; goto IL_0069; IL_0069: if (flag2) { return; } if (Object.op_Implicit((Object)(object)piece.m_craftingStation)) { if ((int)mode == 1 || (int)mode == 2) { if (!___m_knownStations.ContainsKey(piece.m_craftingStation.m_name)) { return; } } else if (!Object.op_Implicit((Object)(object)CraftingStation.HaveBuildStationInRange(piece.m_craftingStation.m_name, ((Component)__instance).transform.position))) { return; } } if (piece.m_dlc.Length > 0 && !DLCMan.instance.IsDLCInstalled(piece.m_dlc)) { return; } List<Container> nearbyContainers = GetNearbyContainers(((Component)__instance).transform.position); Requirement[] resources = piece.m_resources; foreach (Requirement val in resources) { if (!Object.op_Implicit((Object)(object)val.m_resItem) || val.m_amount <= 0) { continue; } if ((int)mode == 1) { if (!___m_knownMaterial.Contains(val.m_resItem.m_itemData.m_shared.m_name)) { return; } } else if ((int)mode == 2) { if (((Humanoid)__instance).GetInventory().HaveItem(val.m_resItem.m_itemData.m_shared.m_name, true)) { continue; } bool flag3 = false; foreach (Container item in nearbyContainers) { if (item.GetInventory().HaveItem(val.m_resItem.m_itemData.m_shared.m_name, true)) { flag3 = true; break; } } if (!flag3) { return; } } else { if ((int)mode != 0 || ((Humanoid)__instance).GetInventory().CountItems(val.m_resItem.m_itemData.m_shared.m_name, -1, true) >= val.m_amount) { continue; } int num = ((Humanoid)__instance).GetInventory().CountItems(val.m_resItem.m_itemData.m_shared.m_name, -1, true); foreach (Container item2 in nearbyContainers) { try { num += item2.GetInventory().CountItems(val.m_resItem.m_itemData.m_shared.m_name, -1, true); if (num >= val.m_amount) { break; } } catch { } } if (num < val.m_amount) { return; } } } __result = true; } } [HarmonyPatch(typeof(Player), "ConsumeResources")] private static class ConsumeResources_Patch { private static bool Prefix(Player __instance, Requirement[] requirements, int qualityLevel) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) if (!modEnabled.Value || !AllowByKey()) { return true; } Inventory inventory = ((Humanoid)__instance).GetInventory(); List<Container> nearbyContainers = GetNearbyContainers(((Component)__instance).transform.position); foreach (Requirement val in requirements) { if (!Object.op_Implicit((Object)(object)val.m_resItem)) { continue; } int amount = val.GetAmount(qualityLevel); if (amount <= 0) { continue; } string name = val.m_resItem.m_itemData.m_shared.m_name; int num = inventory.CountItems(name, -1, true); Dbgl($"have {num}/{amount} {name} in player inventory"); inventory.RemoveItem(name, Math.Min(num, amount), -1, true); if (num >= amount) { continue; } foreach (Container item2 in nearbyContainers) { Inventory val2 = (((Object)(object)item2 != (Object)null) ? item2.GetInventory() : null); if (val2 == null) { continue; } int num2 = Mathf.Min(val2.CountItems(name, -1, true), amount - num); Dbgl($"Container at {((Component)item2).transform.position} has {val2.CountItems(name, -1, true)}"); if (num2 == 0) { continue; } for (int j = 0; j < val2.GetAllItems().Count; j++) { ItemData item = val2.GetItem(j); string text = item?.m_shared?.m_name; if (text == name) { Dbgl($"Container has a total items count of {val2.GetAllItems().Count}"); Dbgl($"Got stack of {item.m_stack} {name}"); int num3 = Mathf.Min(item.m_stack, amount - num); if (num3 == item.m_stack) { val2.RemoveItem(j); j--; } else { item.m_stack -= num3; } num += num3; Dbgl($"total amount is now {num}/{amount} {name}"); if (num >= amount) { Dbgl("Got enough, breaking"); break; } } } Dbgl("Saving container"); typeof(Container).GetMethod("Save", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(item2, new object[0]); Dbgl("Setting inventory changed"); typeof(Inventory).GetMethod("Changed", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(val2, new object[0]); if (num >= amount) { Dbgl("consumed enough " + name); break; } } } return false; } } [HarmonyPatch(typeof(Player), "UpdatePlacementGhost")] private static class UpdatePlacementGhost_Patch { private static void Postfix(Player __instance, bool flashGuardStone) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_0208: Unknown result type (might be due to invalid IL or missing references) //IL_021b: Unknown result type (might be due to invalid IL or missing references) //IL_023f: Unknown result type (might be due to invalid IL or missing references) if (!modEnabled.Value || !showGhostConnections.Value) { return; } FieldInfo field = typeof(Player).GetField("m_placementGhost", BindingFlags.Instance | BindingFlags.NonPublic); GameObject val = ((!(field != null)) ? ((GameObject)null) : ((GameObject)field.GetValue(__instance))); if ((Object)(object)val == (Object)null || (Object)(object)val.GetComponent<Container>() == (Object)null) { return; } FieldInfo field2 = typeof(CraftingStation).GetField("m_allStations", BindingFlags.Static | BindingFlags.NonPublic); List<CraftingStation> list = ((field2 != null) ? ((List<CraftingStation>)field2.GetValue(null)) : null); if ((Object)(object)connectionVfxPrefab == (Object)null) { GameObject[] array = Resources.FindObjectsOfTypeAll(typeof(GameObject)) as GameObject[]; foreach (GameObject val2 in array) { if (((Object)val2).name == "vfx_ExtensionConnection") { connectionVfxPrefab = val2; break; } } } if ((Object)(object)connectionVfxPrefab == (Object)null || list == null) { return; } bool flag = false; foreach (CraftingStation item in list) { int num = ConnectionExists(item); bool flag2 = num != -1; if (Vector3.Distance(((Component)item).transform.position, val.transform.position) < m_range.Value) { flag = true; Vector3 connectionEffectPoint = item.GetConnectionEffectPoint(); Vector3 val3 = val.transform.position + Vector3.up * ghostConnectionStartOffset.Value; ConnectionParams connectionParams; if (!flag2) { connectionParams = new ConnectionParams(); connectionParams.stationPos = item.GetConnectionEffectPoint(); connectionParams.connection = Object.Instantiate<GameObject>(connectionVfxPrefab, connectionEffectPoint, Quaternion.identity); } else { connectionParams = containerConnections[num]; } if ((Object)(object)connectionParams.connection != (Object)null) { Vector3 val4 = val3 - connectionEffectPoint; Quaternion rotation = Quaternion.LookRotation(((Vector3)(ref val4)).normalized); connectionParams.connection.transform.position = connectionEffectPoint; connectionParams.connection.transform.rotation = rotation; connectionParams.connection.transform.localScale = new Vector3(1f, 1f, ((Vector3)(ref val4)).magnitude); } if (!flag2) { containerConnections.Add(connectionParams); } } else if (flag2) { Object.Destroy((Object)(object)containerConnections[num].connection); containerConnections.RemoveAt(num); } } if (flag && (Object)(object)context != (Object)null) { ((MonoBehaviour)context).CancelInvoke("StopConnectionEffects"); ((MonoBehaviour)context).Invoke("StopConnectionEffects", ghostConnectionRemovalDelay.Value); } } } [HarmonyPatch(typeof(InventoryGui), "OnCraftPressed")] private static class DoCrafting_Patch { private static bool Prefix(InventoryGui __instance, KeyValuePair<Recipe, ItemData> ___m_selectedRecipe, ItemData ___m_craftUpgradeItem) { if (!modEnabled.Value || !AllowByKey() || !CheckKeyHeld(pullItemsKey.Value) || (Object)(object)___m_selectedRecipe.Key == (Object)null) { return true; } int num = ((___m_craftUpgradeItem == null) ? 1 : (___m_craftUpgradeItem.m_quality + 1)); if (num > ___m_selectedRecipe.Key.m_item.m_itemData.m_shared.m_maxQuality) { return true; } Dbgl("pulling resources to player inventory for crafting item " + ___m_selectedRecipe.Key.m_item.m_itemData.m_shared.m_name); PullResources(Player.m_localPlayer, ___m_selectedRecipe.Key.m_resources, num); return false; } } [HarmonyPatch(typeof(Player), "UpdatePlacement")] private static class UpdatePlacement_Patch { private static bool Prefix(Player __instance, bool takeInput, float dt, PieceTable ___m_buildPieces, GameObject ___m_placementGhost) { if (!modEnabled.Value || !AllowByKey() || !CheckKeyHeld(pullItemsKey.Value) || !((Character)__instance).InPlaceMode() || !takeInput || Hud.IsPieceSelectionVisible()) { return true; } if (ZInput.GetButtonDown("Attack") || ZInput.GetButtonDown("JoyPlace")) { Piece selectedPiece = ___m_buildPieces.GetSelectedPiece(); if ((Object)(object)selectedPiece != (Object)null) { if (selectedPiece.m_repairPiece) { return true; } if ((Object)(object)___m_placementGhost != (Object)null && (int)typeof(Player).GetField("m_placementStatus", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(__instance) == 0) { Dbgl("pulling resources to player inventory for piece " + ((Object)selectedPiece).name); PullResources(__instance, selectedPiece.m_resources, 0); } } return false; } return true; } } [HarmonyPatch(typeof(Turret), "UseItem")] private static class Turret_UseItem_Patch { private static void Prefix(Turret __instance, Humanoid user, ref ItemData item) { //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Expected O, but got Unknown if (!modEnabled.Value || !AllowByKey() || item != null || !(user is Player)) { Dbgl($"Not allowed {AllowByKey()} {item == null} {user is Player}"); return; } item = user.GetInventory().GetAmmoItem(__instance.m_ammoType, (__instance.GetAmmo() > 0) ? __instance.GetAmmoType() : null); if (item == null) { Dbgl("No item found in inventory, checking containers for " + __instance.GetAmmoType()); GameObject prefab = ZNetScene.instance.GetPrefab(__instance.GetAmmoType()); if (!Object.op_Implicit((Object)(object)prefab)) { Dbgl("No prefab found for " + __instance.GetAmmoType()); ZLog.LogWarning((object)("Turret '" + ((Object)__instance).name + "' is trying to fire but has no ammo or default ammo!")); return; } PullResources((Player)(object)((user is Player) ? user : null), (Requirement[])(object)new Requirement[1] { new Requirement { m_amount = 1, m_resItem = prefab.GetComponent<ItemDrop>() } }, prefab.GetComponent<ItemDrop>().m_itemData.m_quality); } } } private static class HaveRequirements_Patch2_broken { private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator) { //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Expected O, but got Unknown //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Expected O, but got Unknown //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Expected O, but got Unknown //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Expected O, but got Unknown //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Expected O, but got Unknown //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Expected O, but got Unknown //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Expected O, but got Unknown //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Expected O, but got Unknown //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Expected O, but got Unknown List<CodeInstruction> list = new List<CodeInstruction>(instructions); for (int i = 0; i < list.Count; i++) { CodeInstruction val = list[i]; if (!(val.opcode == OpCodes.Callvirt) || !((object)val).ToString().Contains("IsDLCInstalled")) { continue; } int num = -1; for (int j = i + 1; j < i + 5; j++) { if (list[j].opcode == OpCodes.Ret) { num = j; break; } } if (num != -1) { int num2 = num + 1; List<Label> labels = list[num2].labels; list.RemoveRange(num2, list.Count - num2); list.Add(new CodeInstruction(OpCodes.Ldarg_0, (object)null) { labels = labels }); list.Add(new CodeInstruction(OpCodes.Ldarg_1, (object)null)); list.Add(new CodeInstruction(OpCodes.Ldarg_2, (object)null)); list.Add(new CodeInstruction(OpCodes.Ldarg_0, (object)null)); list.Add(new CodeInstruction(OpCodes.Ldfld, (object)AccessTools.Field(typeof(Humanoid), "m_inventory"))); list.Add(new CodeInstruction(OpCodes.Ldarg_0, (object)null)); list.Add(new CodeInstruction(OpCodes.Ldfld, (object)AccessTools.Field(typeof(Player), "m_knownMaterial"))); list.Add(new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(BepInExPlugin), "HaveRequiredItemCount", (Type[])null, (Type[])null))); list.Add(new CodeInstruction(OpCodes.Ret, (object)null)); break; } Dbgl(">>> FAILED to find targeted code for HaveRequirements transpiler patch!!! Mod will not work!"); } return list; } } [HarmonyPatch(typeof(Terminal), "InputText")] private static class InputText_Patch { private static bool Prefix(Terminal __instance) { if (!modEnabled.Value) { return true; } string text = ((TMP_InputField)__instance.m_input).text; if (text.ToLower().Equals("craftfromcontainers reset")) { ((BaseUnityPlugin)context).Config.Reload(); ((BaseUnityPlugin)context).Config.Save(); __instance.AddString(text); __instance.AddString("Craft From Containers config reloaded"); return false; } return true; } } private static bool wasAllowed; private static List<ConnectionParams> containerConnections; private static GameObject connectionVfxPrefab; public static ConfigEntry<bool> showGhostConnections; public static ConfigEntry<float> ghostConnectionStartOffset; public static ConfigEntry<float> ghostConnectionRemovalDelay; public static ConfigEntry<float> m_range; public static ConfigEntry<Color> flashColor; public static ConfigEntry<Color> unFlashColor; public static ConfigEntry<string> resourceString; public static ConfigEntry<string> pulledMessage; public static ConfigEntry<string> fuelDisallowTypes; public static ConfigEntry<string> oreDisallowTypes; public static ConfigEntry<string> pullItemsKey; public static ConfigEntry<string> preventModKey; public static ConfigEntry<string> fillAllModKey; public static ConfigEntry<bool> switchPrevent; public static ConfigEntry<bool> ignoreShipContainers; public static ConfigEntry<bool> ignoreWagonContainers; public static ConfigEntry<bool> ignoreWoodChests; public static ConfigEntry<bool> ignorePrivateChests; public static ConfigEntry<bool> ignoreBlackMetalChests; public static ConfigEntry<bool> ignoreReinforcedChests; public static ConfigEntry<bool> modEnabled; public static ConfigEntry<bool> isDebug; public static ConfigEntry<int> nexusID; public static List<Container> containerList; public static bool odinsQolInstalled; public static float itemStackSizeMultiplier; public static float itemWeightReduction; public static Vector3 lastPosition; public static List<Container> cachedContainerList; private static BepInExPlugin context; private static bool skip; public static void Dbgl(string str = "", bool pref = true) { if (isDebug.Value) { ((BaseUnityPlugin)context).Logger.Log((LogLevel)32, (object)((pref ? (typeof(BepInExPlugin).Namespace + " ") : "") + str)); } } private void Awake() { //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) context = this; modEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable this mod"); isDebug = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "IsDebug", true, "Show debug messages in log"); nexusID = ((BaseUnityPlugin)this).Config.Bind<int>("General", "NexusID", 40, "Nexus mod ID for updates"); m_range = ((BaseUnityPlugin)this).Config.Bind<float>("General", "ContainerRange", 10f, "The maximum range from which to pull items from"); resourceString = ((BaseUnityPlugin)this).Config.Bind<string>("General", "ResourceCostString", "{0}/{1}", "String used to show required and available resources. {0} is replaced by how much is available, and {1} is replaced by how much is required. Set to nothing to leave it as default."); flashColor = ((BaseUnityPlugin)this).Config.Bind<Color>("General", "FlashColor", Color.yellow, "Resource amounts will flash to this colour when coming from containers"); unFlashColor = ((BaseUnityPlugin)this).Config.Bind<Color>("General", "UnFlashColor", Color.white, "Resource amounts will flash from this colour when coming from containers (set both colors to the same color for no flashing)"); pulledMessage = ((BaseUnityPlugin)this).Config.Bind<string>("General", "PulledMessage", "Pulled items to inventory", "Message to show after pulling items to player inventory"); fuelDisallowTypes = ((BaseUnityPlugin)this).Config.Bind<string>("General", "FuelDisallowTypes", "RoundLog,FineWood", "Types of item to disallow as fuel (i.e. anything that is consumed), comma-separated."); oreDisallowTypes = ((BaseUnityPlugin)this).Config.Bind<string>("General", "OreDisallowTypes", "RoundLog,FineWood", "Types of item to disallow as ore (i.e. anything that is transformed), comma-separated)."); showGhostConnections = ((BaseUnityPlugin)this).Config.Bind<bool>("Station Connections", "ShowConnections", false, "If true, will display connections to nearby workstations within range when building containers"); ghostConnectionStartOffset = ((BaseUnityPlugin)this).Config.Bind<float>("Station Connections", "ConnectionStartOffset", 1.25f, "Height offset for the connection VFX start position"); ghostConnectionRemovalDelay = ((BaseUnityPlugin)this).Config.Bind<float>("Station Connections", "ConnectionRemoveDelay", 0.05f, ""); switchPrevent = ((BaseUnityPlugin)this).Config.Bind<bool>("Hot Keys", "SwitchPrevent", false, "if true, holding down the PreventModKey modifier key will allow this mod's behaviour; if false, holding down the key will prevent it."); preventModKey = ((BaseUnityPlugin)this).Config.Bind<string>("Hot Keys", "PreventModKey", "left alt", "Modifier key to toggle fuel and ore filling behaviour when down. Use https://docs.unity3d.com/Manual/ConventionalGameInput.html"); pullItemsKey = ((BaseUnityPlugin)this).Config.Bind<string>("Hot Keys", "PullItemsKey", "left ctrl", "Holding down this key while crafting or building will pull resources into your inventory instead of building. Use https://docs.unity3d.com/Manual/ConventionalGameInput.html"); fillAllModKey = ((BaseUnityPlugin)this).Config.Bind<string>("Hot Keys", "FillAllModKey", "left shift", "Modifier key to pull all available fuel or ore when down. Use https://docs.unity3d.com/Manual/ConventionalGameInput.html"); ignoreShipContainers = ((BaseUnityPlugin)this).Config.Bind<bool>("Container Types", "IgnoreShipContainers", false, "If true, will ignore this type of container."); ignoreWagonContainers = ((BaseUnityPlugin)this).Config.Bind<bool>("Container Types", "IgnoreWagonContainers", false, "If true, will ignore this type of container."); ignoreWoodChests = ((BaseUnityPlugin)this).Config.Bind<bool>("Container Types", "IgnoreWoodChests", false, "If true, will ignore this type of container."); ignorePrivateChests = ((BaseUnityPlugin)this).Config.Bind<bool>("Container Types", "IgnorePrivateChests", false, "If true, will ignore this type of container."); ignoreBlackMetalChests = ((BaseUnityPlugin)this).Config.Bind<bool>("Container Types", "IgnoreBlackMetalChests", false, "If true, will ignore this type of container."); ignoreReinforcedChests = ((BaseUnityPlugin)this).Config.Bind<bool>("Container Types", "IgnoreReinforcedChests", false, "If true, will ignore this type of container."); wasAllowed = !switchPrevent.Value; Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null); Dbgl("Mod awake"); } private void LateUpdate() { wasAllowed = AllowByKey(); skip = false; } private static bool AllowByKey() { if (CheckKeyHeld(preventModKey.Value)) { return switchPrevent.Value; } return !switchPrevent.Value; } private void OnDestroy() { StopConnectionEffects(); } private static bool CheckKeyHeld(string value, bool req = true) { try { return Input.GetKey(value.ToLower()); } catch { return !req; } } public static List<Container> GetNearbyContainers(Vector3 center) { //IL_001a: 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_0168: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) List<Container> list = new List<Container>(); if ((Object)(object)Player.m_localPlayer == (Object)null) { return list; } if (Vector3.Distance(center, lastPosition) < 0.5f) { return cachedContainerList; } MethodInfo methodInfo = AccessTools.Method(typeof(Container), "CheckAccess", (Type[])null, (Type[])null); foreach (Container container in containerList) { if ((Object)(object)container != (Object)null && (Object)(object)((Component)container).transform != (Object)null && (m_range.Value <= 0f || Vector3.Distance(center, ((Component)container).transform.position) < m_range.Value) && AllowContainerType(container) && (bool)methodInfo.Invoke(container, new object[1] { Player.m_localPlayer.GetPlayerID() }) && !container.IsInUse() && (Object)(object)((Component)container).GetComponentInParent<Piece>() != (Object)null && container.GetInventory() != null && (!container.m_checkGuardStone || PrivateArea.CheckAccess(((Component)container).transform.position, 0f, false, false))) { list.Add(container); } } Dbgl($"Got {list.Count} containers."); lastPosition = center; cachedContainerList = list; return list; } private static bool AllowContainerType(Container __instance) { Transform parent = ((Component)__instance).gameObject.transform.parent; Ship val = (((Object)(object)parent != (Object)null) ? ((Component)parent).GetComponent<Ship>() : null); if ((!ignoreShipContainers.Value || (Object)(object)val == (Object)null) && (!ignoreWagonContainers.Value || (Object)(object)__instance.m_wagon == (Object)null) && (!ignoreWoodChests.Value || !((Object)__instance).name.StartsWith("piece_chest_wood(")) && (!ignorePrivateChests.Value || !((Object)__instance).name.StartsWith("piece_chest_private(")) && (!ignoreBlackMetalChests.Value || !((Object)__instance).name.StartsWith("piece_chest_blackmetal("))) { if (ignoreReinforcedChests.Value) { return !((Object)__instance).name.StartsWith("piece_chest("); } return true; } return false; } public static IEnumerator AddContainer(Container container, ZNetView nview) { yield return null; try { if (container.GetInventory() != null && (((Object)(object)nview != (Object)null) ? nview.GetZDO() : null) != null && (((Object)container).name.StartsWith("piece_") || ((Object)container).name.StartsWith("Container") || nview.GetZDO().GetLong(StringExtensionMethods.GetStableHashCode("creator"), 0L) != 0L)) { Dbgl("Adding " + ((Object)container).name); containerList.Add(container); } } catch { } } public static int ConnectionExists(CraftingStation station) { //IL_0016: 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) foreach (ConnectionParams containerConnection in containerConnections) { if (Vector3.Distance(containerConnection.stationPos, station.GetConnectionEffectPoint()) < 0.1f) { return containerConnections.IndexOf(containerConnection); } } return -1; } public void StopConnectionEffects() { if (containerConnections.Count > 0) { foreach (ConnectionParams containerConnection in containerConnections) { Object.Destroy((Object)(object)containerConnection.connection); } } containerConnections.Clear(); } private static void PullResources(Player player, Requirement[] resources, int qualityLevel) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) Inventory inventory = ((Humanoid)Player.m_localPlayer).GetInventory(); List<Container> nearbyContainers = GetNearbyContainers(((Component)Player.m_localPlayer).transform.position); foreach (Requirement val in resources) { if (Object.op_Implicit((Object)(object)val.m_resItem)) { int amount = val.GetAmount(qualityLevel); if (amount <= 0) { continue; } string name = val.m_resItem.m_itemData.m_shared.m_name; int num = 0; foreach (Container item2 in nearbyContainers) { Inventory inventory2 = item2.GetInventory(); int num2 = Mathf.Min(inventory2.CountItems(name, -1, true), amount - num); Dbgl($"Container at {((Component)item2).transform.position} has {inventory2.CountItems(name, -1, true)}"); if (num2 == 0) { continue; } for (int j = 0; j < inventory2.GetAllItems().Count; j++) { ItemData item = inventory2.GetItem(j); if (!(item.m_shared.m_name == name)) { continue; } Dbgl($"Got stack of {item.m_stack} {name}"); int num3 = Mathf.Min(item.m_stack, amount - num); if (!inventory.HaveEmptySlot()) { num3 = Math.Min(Traverse.Create((object)inventory).Method("FindFreeStackSpace", new object[1] { item.m_shared.m_name }).GetValue<int>(), num3); } Dbgl($"Sending {num3} {name} to player"); ItemData val2 = item.Clone(); val2.m_stack = num3; if (odinsQolInstalled) { if (itemStackSizeMultiplier > 0f) { val2.m_shared.m_weight = ApplyModifierValue(val2.m_shared.m_weight, itemWeightReduction); if (val2.m_shared.m_maxStackSize > 1 && itemStackSizeMultiplier >= 1f) { val2.m_shared.m_maxStackSize = (int)ApplyModifierValue(val.m_resItem.m_itemData.m_shared.m_maxStackSize, itemStackSizeMultiplier); } } } else { val2.m_shared.m_maxStackSize = val.m_resItem.m_itemData.m_shared.m_maxStackSize; } inventory.AddItem(val2); if (num3 == item.m_stack) { inventory2.RemoveItem(j); } else { item.m_stack -= num3; } num += num3; Dbgl($"total amount is now {num}/{amount} {name}"); if (num >= amount) { break; } } ((object)item2).GetType().GetMethod("Save", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(item2, new object[0]); ((object)inventory2).GetType().GetMethod("Changed", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(inventory2, new object[0]); if (num >= amount) { Dbgl("pulled enough " + name); break; } } } string value = pulledMessage.Value; if (value != null && value.Length > 0) { ((Character)player).Message((MessageType)2, pulledMessage.Value, 0, (Sprite)null); } } } public static bool HaveRequiredItemCount(Player player, Piece piece, RequirementMode mode, Inventory inventory, HashSet<string> knownMaterial) { //IL_0006: 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_0051: Expected I4, but got Unknown List<Container> nearbyContainers = GetNearbyContainers(((Component)player).transform.position); Requirement[] resources = piece.m_resources; foreach (Requirement val in resources) { if (!Object.op_Implicit((Object)(object)val.m_resItem) || val.m_amount <= 0) { continue; } switch ((int)mode) { case 0: { int num = inventory.CountItems(val.m_resItem.m_itemData.m_shared.m_name, -1, true); if (num >= val.m_amount) { break; } bool flag2 = false; foreach (Container item in nearbyContainers) { try { num += item.GetInventory().CountItems(val.m_resItem.m_itemData.m_shared.m_name, -1, true); if (num >= val.m_amount) { flag2 = true; break; } } catch { } } if (!flag2) { return false; } break; } case 1: if (!knownMaterial.Contains(val.m_resItem.m_itemData.m_shared.m_name)) { return false; } break; case 2: { if (inventory.HaveItem(val.m_resItem.m_itemData.m_shared.m_name, true)) { break; } bool flag = false; foreach (Container item2 in nearbyContainers) { if (item2.GetInventory().HaveItem(val.m_resItem.m_itemData.m_shared.m_name, true)) { flag = true; break; } } if (!flag) { return false; } break; } } } return true; } public static void CheckOdinsQOLConfig() { itemStackSizeMultiplier = 0f; itemWeightReduction = 0f; foreach (PluginInfo value in Chainloader.PluginInfos.Values) { if (!(((value != null) ? value.Metadata.GUID : null) == "com.odinplusqol.mod")) { continue; } odinsQolInstalled = modEnabled.Value; Debug.Log((object)"Found OdinPlusQoL"); foreach (ConfigDefinition key in value.Instance.Config.Keys) { if (key.Key == "Item Stack Increase") { itemStackSizeMultiplier = (float)value.Instance.Config[key].BoxedValue; } if (key.Key == "Item Weight Increase") { itemWeightReduction = (float)value.Instance.Config[key].BoxedValue; } } } } public static float ApplyModifierValue(float targetValue, float value) { if (value <= -100f) { value = -100f; } if (value >= 0f) { return targetValue + targetValue / 100f * value; } return targetValue - targetValue / 100f * (value * -1f); } static BepInExPlugin() { //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) containerConnections = new List<ConnectionParams>(); connectionVfxPrefab = null; containerList = new List<Container>(); lastPosition = Vector3.positiveInfinity; cachedContainerList = new List<Container>(); context = null; } }