using 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;
}
}