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 v0.2.6
files/plugins/CraftFromContainers/CraftFromContainers.dll
Decompiled 8 months 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+34e94375a79a7b0266285020ddbd9627e475f565")] [assembly: AssemblyVersion("1.0.0.0")] namespace CraftFromContainers; [BepInPlugin("aedenthorn.CraftFromContainers", "Craft From Containers", "3.8.3")] public class BepInExPlugin : BaseUnityPlugin { public class ConnectionParams { public GameObject connection = null; public Vector3 stationPos; } [HarmonyPatch(typeof(FejdStartup), "Awake")] public static class FejdStartup_Awake_Patch { public static void Postfix(FejdStartup __instance) { if (modEnabled.Value) { CheckOdinsQOLConfig(); } } } [HarmonyPatch(typeof(Container), "Awake")] public static class Container_Awake_Patch { public static void Postfix(Container __instance, ZNetView ___m_nview) { ((MonoBehaviour)context).StartCoroutine(AddContainer(__instance, ___m_nview)); } } [HarmonyPatch(typeof(Container), "OnDestroyed")] public static class Container_OnDestroyed_Patch { public static void Prefix(Container __instance) { containerList.Remove(__instance); } } [HarmonyPatch(typeof(InventoryGui), "Update")] public static class InventoryGui_Update_Patch { public 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")] public static class Fireplace_Interact_Patch { public static bool Prefix(Fireplace __instance, Humanoid user, bool hold, ref bool __result, ZNetView ___m_nview) { //IL_01ea: 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) //IL_0357: 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) { List<Container> nearbyContainers = GetNearbyContainers(((Component)__instance).transform.position); foreach (Container item2 in nearbyContainers) { ItemData item = item2.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)item2).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))); if (num2 > 0) { num2 -= (leaveOne.Value ? 1 : 0); } if (num2 != 0) { Dbgl($"container at {((Component)item2).transform.position} has {item.m_stack} {((Object)item.m_dropPrefab).name}, taking {num2}"); item2.GetInventory().RemoveItem(__instance.m_fuelItem.m_itemData.m_shared.m_name, num2, -1, true); typeof(Container).GetMethod("Save", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(item2, 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) { return false; } } } } return __result; } } [HarmonyPatch(typeof(CookingStation), "OnAddFuelSwitch")] public static class CookingStation_OnAddFuelSwitch_Patch { public 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_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0141: 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)) { return true; } Dbgl("missing fuel in player inventory"); List<Container> nearbyContainers = GetNearbyContainers(((Component)__instance).transform.position); foreach (Container item3 in nearbyContainers) { ItemData item2 = item3.GetInventory().GetItem(__instance.m_fuelItem.m_itemData.m_shared.m_name, -1, false); if (item2 != null && (!leaveOne.Value || item2.m_stack > 1)) { if (!fuelDisallowTypes.Value.Split(new char[1] { ',' }).Contains(((Object)item2.m_dropPrefab).name)) { Dbgl($"container at {((Component)item3).transform.position} has {item2.m_stack} {((Object)item2.m_dropPrefab).name}, taking one"); item3.GetInventory().RemoveItem(__instance.m_fuelItem.m_itemData.m_shared.m_name, 1, -1, true); typeof(Container).GetMethod("Save", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(item3, 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)item3).transform.position} has {item2.m_stack} {((Object)item2.m_dropPrefab).name} but it's forbidden by config"); } } return true; } } [HarmonyPatch(typeof(CookingStation), "FindCookableItem")] public static class CookingStation_FindCookableItem_Patch { public static void Postfix(CookingStation __instance, ref ItemData __result) { //IL_009d: 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_0168: 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 && (!leaveOne.Value || item.m_stack > 1)) { 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")] public static class Smelter_OnHoverAddFuel_Patch { public 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")] public static class Smelter_OnHoverAddOre_Patch { public 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")] public static class Smelter_OnAddOre_Patch { public static bool Prefix(Smelter __instance, Humanoid user, ItemData item, ZNetView ___m_nview) { //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_036f: Unknown result type (might be due to invalid IL or missing references) //IL_045c: 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) { return true; } 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 (num2 > 0) { num2 -= (leaveOne.Value ? 1 : 0); } if (num2 != 0) { 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) { 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; } } [HarmonyPatch(typeof(Smelter), "OnAddFuel")] public static class Smelter_OnAddFuel_Patch { public static bool Prefix(Smelter __instance, ref bool __result, ZNetView ___m_nview, Humanoid user, ItemData item) { //IL_01d4: Unknown result type (might be due to invalid IL or missing references) //IL_0269: Unknown result type (might be due to invalid IL or missing references) //IL_0325: 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)) { ((Character)user).Message((MessageType)2, "$msg_itsfull", 0, (Sprite)null); __result = false; return false; } 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; } List<Container> nearbyContainers = GetNearbyContainers(((Component)__instance).transform.position); foreach (Container item3 in nearbyContainers) { ItemData item2 = item3.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)item3).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))); if (num3 > 0) { num3 -= (leaveOne.Value ? 1 : 0); } if (num3 != 0) { Dbgl($"container at {((Component)item3).transform.position} has {item2.m_stack} {((Object)item2.m_dropPrefab).name}, taking {num3}"); item3.GetInventory().RemoveItem(__instance.m_fuelItem.m_itemData.m_shared.m_name, num3, -1, true); typeof(Container).GetMethod("Save", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(item3, 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) { 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; } } [HarmonyPatch(typeof(InventoryGui), "SetupRequirement")] public static class InventoryGui_SetupRequirement_Patch { public static void Postfix(InventoryGui __instance, Transform elementRoot, Requirement req, Player player, bool craft, int quality, int craftMultiplier) { //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_012e: 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 num2 = req.GetAmount(quality) * craftMultiplier; if (num2 <= 0) { return; } TMP_Text component = ((Component)((Component)elementRoot).transform.Find("res_amount")).GetComponent<TMP_Text>(); if (num < num2) { 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 >= num2) { ((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, num2); } else { component.text = num2.ToString(); } } } public static class InventoryGui_UpdateRecipeList_Patch { public 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) { } } } [HarmonyPatch(typeof(Player), "HaveRequirementItems")] public static class HaveRequirementItems_Patch { public static void Postfix(Player __instance, ref bool __result, Recipe piece, bool discover, int qualityLevel, HashSet<string> ___m_knownMaterial, int amount) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) if ((!modEnabled.Value | __result) || discover || !AllowByKey()) { return; } int num = (leaveOne.Value ? 1 : 0); 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 num2 = val.GetAmount(qualityLevel) * amount; int num3 = ((Humanoid)__instance).GetInventory().CountItems(val.m_resItem.m_itemData.m_shared.m_name, -1, true); if (num3 >= num2) { continue; } foreach (Container item in nearbyContainers) { num3 += Math.Max(0, item.GetInventory().CountItems(val.m_resItem.m_itemData.m_shared.m_name, -1, true) - num); } if (num3 < num2) { return; } } __result = true; } } [HarmonyPatch(typeof(Player), "UpdateKnownRecipesList")] public static class UpdateKnownRecipesList_Patch { public static void Prefix() { skip = true; } public static void Postfix() { skip = false; } } [HarmonyPatch(typeof(Player), "HaveRequirements", new Type[] { typeof(Piece), typeof(RequirementMode) })] public static class HaveRequirements_Patch { public static void Postfix(Player __instance, ref bool __result, Piece piece, RequirementMode mode, HashSet<string> ___m_knownMaterial, Dictionary<string, int> ___m_knownStations) { //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Invalid comparison between Unknown and I4 //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Invalid comparison between Unknown and I4 //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: 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_016a: Invalid comparison between Unknown and I4 //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Invalid comparison between Unknown and I4 //IL_0258: Unknown result type (might be due to invalid IL or missing references) if ((!modEnabled.Value | __result) || skip || __instance == null) { return; } Transform transform = ((Component)__instance).transform; if (!((transform != null) ? new Vector3?(transform.position) : null).HasValue || !AllowByKey()) { 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); int num = (leaveOne.Value ? 1 : 0); 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 flag = false; foreach (Container item in nearbyContainers) { if (item.GetInventory().HaveItem(val.m_resItem.m_itemData.m_shared.m_name, true)) { flag = true; break; } } if (!flag) { 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 num2 = ((Humanoid)__instance).GetInventory().CountItems(val.m_resItem.m_itemData.m_shared.m_name, -1, true); foreach (Container item2 in nearbyContainers) { try { num2 += Math.Max(0, item2.GetInventory().CountItems(val.m_resItem.m_itemData.m_shared.m_name, -1, true) - num); if (num2 >= val.m_amount) { break; } } catch { } } if (num2 < val.m_amount) { return; } } } __result = true; } } [HarmonyPatch(typeof(Player), "ConsumeResources")] public static class ConsumeResources_Patch { public static bool Prefix(Player __instance, Requirement[] requirements, int qualityLevel, int multiplier) { //IL_0030: 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) 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 num = val.GetAmount(qualityLevel) * multiplier; if (num <= 0) { continue; } string name = val.m_resItem.m_itemData.m_shared.m_name; int num2 = inventory.CountItems(name, -1, true); Dbgl($"have {num2}/{num} {name} in player inventory"); inventory.RemoveItem(name, Math.Min(num2, num), -1, true); if (num2 >= num) { continue; } foreach (Container item2 in nearbyContainers) { Inventory val2 = ((item2 != null) ? item2.GetInventory() : null); if (val2 == null) { continue; } int num3 = Mathf.Min(val2.CountItems(name, -1, true), num - num2); Dbgl($"Container at {((Component)item2).transform.position} has {val2.CountItems(name, -1, true)}"); for (int j = 0; j < val2.GetAllItems().Count; j++) { ItemData item = val2.GetItem(j); if (!(item?.m_shared?.m_name == name)) { continue; } Dbgl($"Container has a total items count of {val2.GetAllItems().Count}"); Dbgl($"Got stack of {item.m_stack} {name}"); int num4 = Mathf.Min(item.m_stack, num - num2); if (num4 == item.m_stack) { if (leaveOne.Value && val2.CountItems(name, -1, true) == item.m_stack) { num4--; item.m_stack -= num4; } else { val2.RemoveItem(j); j--; } } else { item.m_stack -= num4; } num2 += num4; Dbgl($"total amount is now {num2}/{num} {name}"); if (num2 >= num) { 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 (num2 < num) { continue; } Dbgl("consumed enough " + name); break; } } return false; } } [HarmonyPatch(typeof(Player), "UpdatePlacementGhost")] public static class UpdatePlacementGhost_Patch { public static void Postfix(Player __instance, bool flashGuardStone) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_0204: Unknown result type (might be due to invalid IL or missing references) //IL_023a: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Unknown result type (might be due to invalid IL or missing references) //IL_023e: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_0247: Unknown result type (might be due to invalid IL or missing references) //IL_024c: Unknown result type (might be due to invalid IL or missing references) //IL_0251: Unknown result type (might be due to invalid IL or missing references) //IL_025f: Unknown result type (might be due to invalid IL or missing references) //IL_0273: 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) 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) { return; } Container component = val.GetComponent<Container>(); if ((Object)(object)component == (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) < maxRange.Value) { flag = true; Vector3 connectionEffectPoint = item.GetConnectionEffectPoint(); Vector3 val3 = val.transform.position + Vector3.up * ghostConnectionStartOffset.Value; ConnectionParams connectionParams = null; 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")] public static class DoCrafting_Patch { public static bool Prefix(InventoryGui __instance, KeyValuePair<Recipe, ItemData> ___m_selectedRecipe, ItemData ___m_craftUpgradeItem, bool ___m_multiCrafting, int ___m_multiCraftAmount) { 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); int multiple = ((!___m_multiCrafting) ? 1 : ___m_multiCraftAmount); PullResources(Player.m_localPlayer, ___m_selectedRecipe.Key.m_resources, num, multiple); return false; } } [HarmonyPatch(typeof(Player), "UpdatePlacement")] public static class UpdatePlacement_Patch { public 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, 1); } } return false; } return true; } } [HarmonyPatch(typeof(Turret), "UseItem")] public static class Turret_UseItem_Patch { public static void Prefix(Turret __instance, Humanoid user, ref ItemData item) { //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0127: 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, 1); } } } public static class HaveRequirements_Patch2_broken { public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator) { //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Expected O, but got Unknown //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Expected O, but got Unknown //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Expected O, but got Unknown //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Expected O, but got Unknown //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Expected O, but got Unknown //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Expected O, but got Unknown //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Expected O, but got Unknown //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Expected O, but got Unknown //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: 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)) { continue; } string text = ((object)val).ToString(); if (!text.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); CodeInstruction val2 = new CodeInstruction(OpCodes.Ldarg_0, (object)null); val2.labels = labels; list.Add(val2); 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")] public static class InputText_Patch { public 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; } } [CompilerGenerated] private sealed class <AddContainer>d__47 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public Container container; public ZNetView nview; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <AddContainer>d__47(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = null; <>1__state = 1; return true; case 1: <>1__state = -1; try { if (container.GetInventory() != null) { ZNetView obj = nview; if (((obj != null) ? obj.GetZDO() : null) != null && (((Object)container).name.StartsWith("piece_") || ((Object)container).name.StartsWith("Container") || nview.GetZDO().GetLong(StringExtensionMethods.GetStableHashCode("creator"), 0L) != 0)) { Dbgl("Adding " + ((Object)container).name); containerList.Add(container); } } } catch { } return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public static bool wasAllowed; public static List<ConnectionParams> containerConnections = new List<ConnectionParams>(); public static GameObject connectionVfxPrefab = null; public static ConfigEntry<bool> showGhostConnections; public static ConfigEntry<float> ghostConnectionStartOffset; public static ConfigEntry<float> ghostConnectionRemovalDelay; public static ConfigEntry<float> maxRange; 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<bool> leaveOne; public static ConfigEntry<bool> pullByDistance; 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 = new List<Container>(); public static bool odinsQolInstalled; public static float itemStackSizeMultiplier; public static float itemWeightReduction; public static Vector3 lastPosition = Vector3.positiveInfinity; public static List<Container> cachedContainerList = new List<Container>(); public static BepInExPlugin context = null; public 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)); } } public void Awake() { //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: 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"); maxRange = ((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)."); leaveOne = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "LeaveOne", false, "Always leave the last of an item in a container."); pullByDistance = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "PullByDistance", false, "When pulling, pull from closest containers first."); 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"); } public void LateUpdate() { wasAllowed = AllowByKey(); skip = false; } public static bool AllowByKey() { if (CheckKeyHeld(preventModKey.Value)) { return switchPrevent.Value; } return !switchPrevent.Value; } public void OnDestroy() { StopConnectionEffects(); } public 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_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_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: 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) //IL_0138: Unknown result type (might be due to invalid IL or missing references) List<Container> list = new List<Container>(); if (Player.m_localPlayer == 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 && (maxRange.Value <= 0f || Vector3.Distance(center, ((Component)container).transform.position) < maxRange.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; if (pullByDistance.Value) { list.Sort((Container a, Container b) => Vector3.Distance(center, ((Component)a).transform.position).CompareTo(Vector3.Distance(center, ((Component)b).transform.position))); } cachedContainerList = list; return list; } public static bool AllowContainerType(Container __instance) { Transform parent = ((Component)__instance).gameObject.transform.parent; Ship val = ((parent != null) ? ((Component)parent).GetComponent<Ship>() : null); return (!ignoreShipContainers.Value || val == null) && (!ignoreWagonContainers.Value || __instance.m_wagon == 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(")) && (!ignoreReinforcedChests.Value || !((Object)__instance).name.StartsWith("piece_chest(")); } [IteratorStateMachine(typeof(<AddContainer>d__47))] public static IEnumerator AddContainer(Container container, ZNetView nview) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <AddContainer>d__47(0) { container = container, nview = nview }; } public static int ConnectionExists(CraftingStation station) { //IL_0019: 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) 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(); } public static void PullResources(Player player, Requirement[] resources, int qualityLevel, int multiple) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: 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 num = val.GetAmount(qualityLevel) * multiple; if (num <= 0) { continue; } string name = val.m_resItem.m_itemData.m_shared.m_name; int num2 = 0; foreach (Container item2 in nearbyContainers) { Inventory inventory2 = item2.GetInventory(); int num3 = Mathf.Min(inventory2.CountItems(name, -1, true), num - num2); Dbgl($"Container at {((Component)item2).transform.position} has {inventory2.CountItems(name, -1, true)}"); if (num3 == 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 num4 = Mathf.Min(item.m_stack, num - num2); if (!inventory.HaveEmptySlot()) { num4 = Math.Min(Traverse.Create((object)inventory).Method("FindFreeStackSpace", new object[1] { item.m_shared.m_name }).GetValue<int>(), num4); } Dbgl($"Sending {num4} {name} to player"); ItemData val2 = item.Clone(); val2.m_stack = num4; 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 (num4 == item.m_stack) { if (leaveOne.Value && inventory2.CountItems(name, -1, true) == item.m_stack) { num4--; item.m_stack -= num4; } else { inventory2.RemoveItem(j); j--; } } else { item.m_stack -= num4; } num2 += num4; Dbgl($"total amount is now {num2}/{num} {name}"); if (num2 >= num) { 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 (num2 < num) { continue; } 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_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0049: 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) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0063: 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); int num2 = num; if (num2 >= val.m_amount) { break; } bool flag2 = false; foreach (Container item in nearbyContainers) { try { num2 += item.GetInventory().CountItems(val.m_resItem.m_itemData.m_shared.m_name, -1, true); if (num2 >= 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; Dictionary<string, PluginInfo> pluginInfos = Chainloader.PluginInfos; foreach (PluginInfo value in 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); } }