Decompiled source of ItemHopper v2.0.0

ValheimHopper.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using JetBrains.Annotations;
using Jotunn;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.GUI;
using Jotunn.Managers;
using Jotunn.Utils;
using MultiUserChest;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
using ValheimHopper.Logic;
using ValheimHopper.Logic.Helper;
using ValheimHopper.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("ValheimHopper")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ValheimHopper")]
[assembly: AssemblyCopyright("Copyright ©  2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("FE8B42E3-7082-4DFF-A5CC-6B62B0315ACA")]
[assembly: AssemblyFileVersion("2.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.0.0.0")]
[module: UnverifiableCode]
namespace ValheimHopper
{
	[BepInPlugin("com.maxsch.valheim.ItemHopper", "ItemHopper", "2.0.0")]
	[BepInDependency("com.jotunn.jotunn", "2.7.7")]
	[BepInDependency("com.maxsch.valheim.MultiUserChest", "0.4.0")]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		[PublicAPI]
		public const string ModName = "ItemHopper";

		[PublicAPI]
		public const string ModGuid = "com.maxsch.valheim.ItemHopper";

		[PublicAPI]
		public const string ModVersion = "2.0.0";

		private static ConfigEntry<bool> addSmelterSnappoints;

		private Harmony harmony;

		public static Plugin Instance { get; private set; }

		public static AssetBundle AssetBundle { get; private set; }

		private void Awake()
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			Instance = this;
			harmony = new Harmony("com.maxsch.valheim.ItemHopper");
			harmony.PatchAll();
			addSmelterSnappoints = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Add Smelter Snappoints", true, "Adds snappoints to inputs/outputs of the smelter, charcoal kiln, blastfurnace, windmill and spinning wheel. Requires a restart to take effect.");
			CustomLocalization localization = LocalizationManager.Instance.GetLocalization();
			localization.AddJsonFile("English", AssetUtils.LoadTextFromResources("Localization.English.json"));
			localization.AddJsonFile("German", AssetUtils.LoadTextFromResources("Localization.German.json"));
			localization.AddJsonFile("Russian", AssetUtils.LoadTextFromResources("Localization.Russian.json"));
			localization.AddJsonFile("Portuguese_Brazilian", AssetUtils.LoadTextFromResources("Localization.Portuguese_Brazilian.json"));
			AssetBundle = AssetUtils.LoadAssetBundleFromResources("ValheimHopper_AssetBundle");
			AddBronzePiece("HopperBronzeDown", 6, 4);
			AddBronzePiece("HopperBronzeSide", 6, 4);
			AddBronzePiece("MS_PipeBronzeSide", 4, 2);
			AddBronzePiece("MS_PipeBronzeSide_2m", 2, 1);
			AddBronzePiece("MS_PipeBronze_Vertical_Up_4m", 4, 2);
			AddBronzePiece("MS_PipeBronze_Vertical_Down_4m", 4, 2);
			AddBronzePiece("MS_PipeBronze_Vertical_Up_2m", 2, 1);
			AddBronzePiece("MS_PipeBronze_Vertical_Down_2m", 2, 1);
			AddBronzePiece("MS_PipeBronze_Diagonal_45_Up_4m", 4, 2);
			AddBronzePiece("MS_PipeBronze_Diagonal_45_Down_4m", 4, 2);
			AddBronzePiece("MS_PipeBronze_Diagonal_26_Up_4m", 4, 2);
			AddBronzePiece("MS_PipeBronze_Diagonal_26_Down_4m", 4, 2);
			AddIronPiece("HopperIronDown", 6, 2);
			AddIronPiece("HopperIronSide", 6, 2);
			PrefabManager.OnVanillaPrefabsAvailable += AddSnappoints;
			GUIManager.OnCustomGUIAvailable += HopperUI.Init;
		}

		private static void AddSnappoints()
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: 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_004f: 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_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: 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_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: 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_013f: 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_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			if (addSmelterSnappoints.Value)
			{
				SnappointHelper.AddSnappoints("smelter", (Vector3[])(object)new Vector3[2]
				{
					new Vector3(0f, 1.6f, -1.2f),
					new Vector3(0f, 1.6f, 1.2f)
				});
				SnappointHelper.AddSnappoints("charcoal_kiln", (Vector3[])(object)new Vector3[1]
				{
					new Vector3(0f, 1.1f, 2f)
				});
				SnappointHelper.AddSnappoints("blastfurnace", (Vector3[])(object)new Vector3[4]
				{
					new Vector3(-0.5f, 1.72001f, 1.55f),
					new Vector3(-0.6f, 1.72001f, 1.55f),
					new Vector3(0.57f, 1.72f, 1.55001f),
					new Vector3(0.73f, 1.72f, 1.55001f)
				});
				SnappointHelper.AddSnappoints("windmill", (Vector3[])(object)new Vector3[2]
				{
					new Vector3(0f, 1.55f, -1.55f),
					new Vector3(-0.05f, 0.83f, 2.3f)
				});
				SnappointHelper.AddSnappoints("piece_spinningwheel", (Vector3[])(object)new Vector3[2]
				{
					new Vector3(0.72f, 1.8f, 0f),
					new Vector3(0f, 0.95f, 1.75f)
				});
			}
			PrefabManager.OnVanillaPrefabsAvailable -= AddSnappoints;
		}

		private static void AddBronzePiece(string assetName, int wood, int nails)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Expected O, but got Unknown
			PieceConfig val = new PieceConfig();
			val.Requirements = (RequirementConfig[])(object)new RequirementConfig[2]
			{
				new RequirementConfig("Wood", wood, 0, true),
				new RequirementConfig("BronzeNails", nails, 0, true)
			};
			val.PieceTable = "Hammer";
			val.CraftingStation = "piece_workbench";
			val.Category = "Crafting";
			PieceConfig val2 = val;
			PieceManager.Instance.AddPiece(new CustomPiece(AssetBundle, assetName, true, val2));
		}

		private static void AddIronPiece(string assetName, int wood, int nails)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Expected O, but got Unknown
			PieceConfig val = new PieceConfig();
			val.Requirements = (RequirementConfig[])(object)new RequirementConfig[2]
			{
				new RequirementConfig("Wood", wood, 0, true),
				new RequirementConfig("IronNails", nails, 0, true)
			};
			val.PieceTable = "Hammer";
			val.CraftingStation = "piece_workbench";
			val.Category = "Crafting";
			PieceConfig val2 = val;
			PieceManager.Instance.AddPiece(new CustomPiece(AssetBundle, assetName, true, val2));
		}
	}
}
namespace ValheimHopper.UI
{
	public class HopperUI : MonoBehaviour
	{
		private static readonly Color WhiteShade = new Color(73f / 85f, 73f / 85f, 73f / 85f);

		[SerializeField]
		private Text title;

		[SerializeField]
		private Toggle filterHopper;

		[SerializeField]
		private Toggle dropItems;

		[SerializeField]
		private Toggle pickupItems;

		[SerializeField]
		private Toggle leaveLastItem;

		[SerializeField]
		private Button copyButton;

		[SerializeField]
		private Button pasteButton;

		[SerializeField]
		private Button resetButton;

		private static GameObject uiRoot;

		private Hopper target;

		private Hopper copy;

		public static HopperUI Instance { get; private set; }

		public static bool IsOpen { get; private set; }

		private void Awake()
		{
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Expected O, but got Unknown
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Expected O, but got Unknown
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Expected O, but got Unknown
			Instance = this;
			((UnityEvent<bool>)(object)dropItems.onValueChanged).AddListener((UnityAction<bool>)delegate(bool i)
			{
				target.DropItemsOption.Set(i);
			});
			((UnityEvent<bool>)(object)pickupItems.onValueChanged).AddListener((UnityAction<bool>)delegate(bool i)
			{
				target.PickupItemsOption.Set(i);
			});
			((UnityEvent<bool>)(object)leaveLastItem.onValueChanged).AddListener((UnityAction<bool>)delegate(bool i)
			{
				target.LeaveLastItemOption.Set(i);
			});
			((UnityEvent<bool>)(object)filterHopper.onValueChanged).AddListener((UnityAction<bool>)delegate(bool active)
			{
				target.FilterItemsOption.Set(active);
				if (active)
				{
					target.filter.Save();
				}
				else
				{
					target.filter.Clear();
				}
			});
			((UnityEvent)copyButton.onClick).AddListener((UnityAction)delegate
			{
				copy = target;
			});
			((UnityEvent)pasteButton.onClick).AddListener((UnityAction)delegate
			{
				target.PasteData(copy);
			});
			((UnityEvent)resetButton.onClick).AddListener((UnityAction)delegate
			{
				target.ResetValues();
			});
		}

		public static void Init()
		{
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = Plugin.AssetBundle.LoadAsset<GameObject>("HopperUI");
			HopperUI component = Object.Instantiate<GameObject>(val, GUIManager.CustomGUIFront.transform, false).GetComponent<HopperUI>();
			uiRoot = ((Component)((Component)component).transform.GetChild(0)).gameObject;
			ApplyAllComponents(uiRoot);
			GUIManager.Instance.ApplyTextStyle(component.title, GUIManager.Instance.AveriaSerifBold, GUIManager.Instance.ValheimOrange, 20, true);
			ApplyLocalization();
			uiRoot.AddComponent<DragWindowCntrl>();
			uiRoot.SetActive(false);
			PrefabExtension.FixReferences(uiRoot, true);
		}

		private void LateUpdate()
		{
			if (!Object.op_Implicit((Object)(object)Player.m_localPlayer))
			{
				target = null;
				SetGUIState(active: false);
				return;
			}
			InventoryGui instance = InventoryGui.instance;
			Hopper hopper = default(Hopper);
			if (!Object.op_Implicit((Object)(object)instance) || !instance.IsContainerOpen() || !Object.op_Implicit((Object)(object)instance.m_currentContainer))
			{
				target = null;
				SetGUIState(active: false);
			}
			else if (((Component)instance.m_currentContainer).TryGetComponent<Hopper>(ref hopper))
			{
				target = hopper;
				SetGUIState(active: true);
				UpdateText();
			}
			else
			{
				target = null;
				SetGUIState(active: false);
			}
		}

		private static void SetGUIState(bool active)
		{
			if (IsOpen != active)
			{
				IsOpen = active;
				uiRoot.SetActive(active);
			}
		}

		private void UpdateText()
		{
			title.text = Localization.instance.Localize(target.Piece.m_name);
			filterHopper.SetIsOnWithoutNotify(target.FilterItemsOption.Get());
			dropItems.SetIsOnWithoutNotify(target.DropItemsOption.Get());
			pickupItems.SetIsOnWithoutNotify(target.PickupItemsOption.Get());
			leaveLastItem.SetIsOnWithoutNotify(target.LeaveLastItemOption.Get());
		}

		private static void ApplyAllComponents(GameObject root)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			Text[] componentsInChildren = root.GetComponentsInChildren<Text>();
			foreach (Text val in componentsInChildren)
			{
				GUIManager.Instance.ApplyTextStyle(val, GUIManager.Instance.AveriaSerif, WhiteShade, 16, false);
			}
			InputField[] componentsInChildren2 = root.GetComponentsInChildren<InputField>();
			foreach (InputField val2 in componentsInChildren2)
			{
				GUIManager.Instance.ApplyInputFieldStyle(val2, 16);
			}
			Toggle[] componentsInChildren3 = root.GetComponentsInChildren<Toggle>();
			foreach (Toggle val3 in componentsInChildren3)
			{
				GUIManager.Instance.ApplyToogleStyle(val3);
			}
			Button[] componentsInChildren4 = root.GetComponentsInChildren<Button>();
			foreach (Button val4 in componentsInChildren4)
			{
				GUIManager.Instance.ApplyButtonStyle(val4, 16);
			}
		}

		private static void ApplyLocalization()
		{
			Text[] componentsInChildren = uiRoot.GetComponentsInChildren<Text>();
			foreach (Text val in componentsInChildren)
			{
				val.text = Localization.instance.Localize(val.text);
			}
		}
	}
}
namespace ValheimHopper.Patches
{
	[HarmonyPatch]
	public class ExtensionPatch
	{
		[HarmonyPatch(typeof(Container), "Awake")]
		[HarmonyPostfix]
		private static void ContainerAwakePostfix(Container __instance)
		{
			((Component)__instance).gameObject.AddComponent<ContainerTarget>();
		}

		[HarmonyPatch(typeof(ItemDrop), "Awake")]
		[HarmonyPostfix]
		private static void ItemDropAwakePostfix(ItemDrop __instance)
		{
			((Component)__instance).gameObject.AddComponent<ItemDropTarget>();
		}

		[HarmonyPatch(typeof(Smelter), "Awake")]
		[HarmonyPostfix]
		private static void SmelterAwakePostfix(Smelter __instance)
		{
			if (Object.op_Implicit((Object)(object)__instance.m_addWoodSwitch))
			{
				((Component)__instance).gameObject.AddComponent<SmelterFuelTarget>();
			}
			if (Object.op_Implicit((Object)(object)__instance.m_addOreSwitch))
			{
				((Component)__instance).gameObject.AddComponent<SmelterOreTarget>();
			}
		}

		[HarmonyPatch(typeof(Beehive), "Awake")]
		[HarmonyPostfix]
		private static void BeehiveAwakePostfix(Beehive __instance)
		{
			((Component)__instance).gameObject.AddComponent<BeehiveTarget>();
		}

		[HarmonyPatch(typeof(Turret), "Awake")]
		[HarmonyPostfix]
		private static void TurretAwakePostfix(Turret __instance)
		{
			((Component)__instance).gameObject.AddComponent<TurretTarget>();
		}
	}
	[HarmonyPatch]
	public static class InventoryGuiPatch
	{
		private static Color ghostColor = new Color(0.9f, 0.9f, 0.9f, 0.5f);

		[HarmonyPatch(typeof(InventoryGui), "UpdateContainer")]
		[HarmonyPostfix]
		public static void UpdateContainerPostfix(InventoryGui __instance)
		{
			Container currentContainer = __instance.m_currentContainer;
			Hopper hopper = default(Hopper);
			if (Object.op_Implicit((Object)(object)currentContainer) && ((Component)currentContainer).TryGetComponent<Hopper>(ref hopper) && hopper.FilterItemsOption.Get())
			{
				ShowContainerGridGhosts(hopper, __instance.m_containerGrid);
			}
		}

		private static void ShowContainerGridGhosts(Hopper hopper, InventoryGrid inventoryGrid)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			foreach (Element element in inventoryGrid.m_elements)
			{
				if (!((Behaviour)element.m_icon).enabled)
				{
					int itemHash = hopper.filter.GetItemHash(element.m_pos);
					GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(itemHash);
					if (Object.op_Implicit((Object)(object)itemPrefab))
					{
						ItemDrop component = itemPrefab.GetComponent<ItemDrop>();
						((Behaviour)element.m_icon).enabled = true;
						((Behaviour)element.m_amount).enabled = true;
						element.m_icon.sprite = component.m_itemData.GetIcon();
						((Graphic)element.m_icon).color = ghostColor;
						element.m_amount.text = $"0/{component.m_itemData.m_shared.m_maxStackSize}";
					}
				}
			}
		}
	}
	[HarmonyPatch]
	public class PlacementPatch
	{
		[HarmonyPatch(typeof(Player), "SetupPlacementGhost")]
		[HarmonyPostfix]
		public static void SetupPlacementGhostPatch(Player __instance)
		{
			if (Object.op_Implicit((Object)(object)__instance.m_placementGhost))
			{
				Hopper[] componentsInChildren = __instance.m_placementGhost.GetComponentsInChildren<Hopper>();
				foreach (Hopper hopper in componentsInChildren)
				{
					Object.Destroy((Object)(object)hopper);
				}
				Pipe[] componentsInChildren2 = __instance.m_placementGhost.GetComponentsInChildren<Pipe>();
				foreach (Pipe pipe in componentsInChildren2)
				{
					Object.Destroy((Object)(object)pipe);
				}
			}
		}
	}
}
namespace ValheimHopper.Logic
{
	[DefaultExecutionOrder(5)]
	public class Hopper : NetworkPiece, IPushTarget, ITarget, IEqualityComparer<ITarget>, IPullTarget
	{
		private Container container;

		private ContainerTarget containerTarget;

		[SerializeField]
		private Vector3 inPos = new Vector3(0f, 0.375f, 0f);

		[SerializeField]
		private Vector3 outPos = new Vector3(0f, -0.375f, 0f);

		[SerializeField]
		private Vector3 inSize = new Vector3(1f, 1f, 1f);

		[SerializeField]
		private Vector3 outSize = new Vector3(1f, 1f, 1f);

		[SerializeField]
		private Vector3 nearSize = new Vector3(1.5f, 1.5f, 1.5f);

		private List<IPushTarget> pushTo = new List<IPushTarget>();

		internal List<IPullTarget> pullFrom = new List<IPullTarget>();

		private List<Hopper> nearHoppers = new List<Hopper>();

		private const float TransferInterval = 0.2f;

		private const float ObjectSearchInterval = 3f;

		private int transferFrame;

		private int objectSearchFrame;

		private int frameOffset;

		private int pushCounter;

		private int pullCounter;

		public ItemFilter filter;

		public Piece Piece { get; private set; }

		public HopperPriority PushPriority { get; } = HopperPriority.HopperPull;


		public HopperPriority PullPriority { get; } = HopperPriority.HopperPull;


		public bool IsPickup { get; } = false;


		public ZBool FilterItemsOption { get; private set; }

		public ZBool DropItemsOption { get; private set; }

		public ZBool PickupItemsOption { get; private set; }

		public ZBool LeaveLastItemOption { get; private set; }

		protected override void Awake()
		{
			base.Awake();
			Piece = ((Component)this).GetComponent<Piece>();
			container = ((Component)this).GetComponent<Container>();
			containerTarget = ((Component)this).GetComponent<ContainerTarget>();
			FilterItemsOption = new ZBool("hopper_filter_items", defaultValue: false, zNetView);
			DropItemsOption = new ZBool("hopper_drop_items", defaultValue: false, zNetView);
			PickupItemsOption = new ZBool("hopper_pickup_items", defaultValue: true, zNetView);
			LeaveLastItemOption = new ZBool("hopper_leave_last_item", defaultValue: false, zNetView);
			transferFrame = Mathf.RoundToInt(1f / Time.fixedDeltaTime * 0.2f);
			objectSearchFrame = Mathf.RoundToInt(1f / Time.fixedDeltaTime * 3f);
			frameOffset = Mathf.Abs(((Object)this).GetInstanceID() % transferFrame);
		}

		private void Start()
		{
			filter = new ItemFilter(zNetView, container.GetInventory());
			Inventory inventory = container.GetInventory();
			inventory.m_onChanged = (Action)Delegate.Combine(inventory.m_onChanged, (Action)delegate
			{
				if (IsValid() && FilterItemsOption.Get())
				{
					filter.Save();
				}
			});
		}

		public void PasteData(Hopper copy)
		{
			FilterItemsOption.Set(copy.FilterItemsOption.Get());
			DropItemsOption.Set(copy.DropItemsOption.Get());
			PickupItemsOption.Set(copy.PickupItemsOption.Get());
			LeaveLastItemOption.Set(copy.LeaveLastItemOption.Get());
			filter.Copy(copy.filter);
		}

		public void ResetValues()
		{
			FilterItemsOption.Reset();
			DropItemsOption.Reset();
			PickupItemsOption.Reset();
			LeaveLastItemOption.Reset();
			filter.Clear();
		}

		private void FixedUpdate()
		{
			if (!IsValid() || !zNetView.IsOwner())
			{
				return;
			}
			int fixedFrameCount = HopperHelper.GetFixedFrameCount();
			int num = (fixedFrameCount + frameOffset) / transferFrame;
			if ((fixedFrameCount + frameOffset) % transferFrame == 0)
			{
				if (num % 2 == 0)
				{
					PullItems();
				}
				if (num % 2 == 1)
				{
					PushItems();
				}
			}
			if ((fixedFrameCount + frameOffset + 1) % objectSearchFrame == 0)
			{
				FindIO();
			}
		}

		private void PullItems()
		{
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			if (pullFrom.Count == 0)
			{
				return;
			}
			IPullTarget pullTarget = pullFrom[pullCounter % pullFrom.Count];
			pullCounter++;
			if (!pullTarget.IsValid() || (!PickupItemsOption.Get() && pullTarget.IsPickup))
			{
				return;
			}
			foreach (ItemData item in pullTarget.GetItems())
			{
				if (!FindFreeSlot(item, out var pos))
				{
					continue;
				}
				pullTarget.RemoveItem(item, container.GetInventory(), pos, zNetView.m_zdo.m_uid);
				break;
			}
		}

		private void PushItems()
		{
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			if (pushTo.Count == 0)
			{
				if (DropItemsOption.Get())
				{
					DropItem();
				}
				return;
			}
			IPushTarget to = pushTo[pushCounter % pushTo.Count];
			pushCounter++;
			if (to.IsValid())
			{
				ItemData val = container.GetInventory().FindLastItem((ItemData i) => to.CanAddItem(i) && CanPushItem(i));
				if (val != null)
				{
					to.AddItem(val, container.GetInventory(), zNetView.m_zdo.m_uid);
				}
			}
		}

		private void DropItem()
		{
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			ItemData val = container.GetInventory().FindLastItem(CanPushItem);
			if (val != null)
			{
				container.GetInventory().RemoveOneItem(val);
				float num = Random.Range(0f, (float)Math.PI * 2f);
				Vector3 val2 = new Vector3(Mathf.Cos(num), 0f, Mathf.Sin(num)) * 0.2f;
				Vector3 visualItemOffset = ItemHelper.GetVisualItemOffset(((Object)val.m_dropPrefab).name);
				Vector3 val3 = ((Component)this).transform.TransformPoint(outPos) + visualItemOffset + new Vector3(val2.x, 0f, val2.z);
				ItemDrop.DropItem(val, 1, val3, val.m_dropPrefab.transform.rotation);
			}
		}

		public bool CanAddItem(ItemData item)
		{
			Vector2i pos;
			return FindFreeSlot(item, out pos);
		}

		public void AddItem(ItemData item, Inventory source, ZDOID sender)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			FindFreeSlot(item, out var pos);
			ContainerHandler.AddItemToChest(container, item, source, pos, sender, 1);
		}

		public IEnumerable<ItemData> GetItems()
		{
			return containerTarget.GetItems();
		}

		public void RemoveItem(ItemData item, Inventory destination, Vector2i destinationPos, ZDOID sender)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			containerTarget.RemoveItem(item, destination, destinationPos, sender);
		}

		private bool FindFreeSlot(ItemData itemToAdd, out Vector2i pos)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: 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_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			pos = new Vector2i(0, 0);
			if (!container.GetInventory().CanAddItem(itemToAdd, 1))
			{
				return false;
			}
			int stableHashCode = StringExtensionMethods.GetStableHashCode(((Object)itemToAdd.m_dropPrefab).name);
			for (int i = 0; i < container.m_height; i++)
			{
				for (int j = 0; j < container.m_width; j++)
				{
					ItemData itemAt = container.GetInventory().GetItemAt(j, i);
					if (itemAt == null || (itemAt.m_stack + 1 <= itemAt.m_shared.m_maxStackSize && itemAt.m_shared.m_name == itemToAdd.m_shared.m_name))
					{
						if (!FilterItemsOption.Get())
						{
							pos = new Vector2i(j, i);
							return true;
						}
						int itemHash = filter.GetItemHash(j, i);
						if (itemHash == 0 || itemHash == stableHashCode)
						{
							pos = new Vector2i(j, i);
							return true;
						}
					}
				}
			}
			return false;
		}

		public bool InRange(Vector3 position)
		{
			return true;
		}

		private bool CanPushItem(ItemData item)
		{
			return (!LeaveLastItemOption.Get() || container.GetInventory().CountItems(item.m_shared.m_name, -1, true) > 1) && !nearHoppers.Any((Hopper hopper) => (Object)(object)hopper != (Object)(object)this && hopper.pullFrom.Contains(this) && hopper.CanAddItem(item));
		}

		private void FindIO()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			Quaternion rotation = ((Component)this).transform.rotation;
			pullFrom = HopperHelper.FindTargets(((Component)this).transform.TransformPoint(inPos), inSize, rotation, (IPullTarget i) => i.PullPriority, this);
			pushTo = HopperHelper.FindTargets(((Component)this).transform.TransformPoint(outPos), outSize, rotation, (IPushTarget i) => i.PushPriority, this);
			nearHoppers = HopperHelper.FindTargets(((Component)this).transform.position, nearSize, rotation, (Hopper i) => i.PullPriority, this);
			pullFrom.RemoveAll((IPullTarget pull) => pushTo.Exists((IPushTarget push) => push.NetworkHashCode() == pull.NetworkHashCode()));
		}

		private void OnDrawGizmos()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: 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_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Expected O, but got Unknown
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			Gizmos.color = Color.blue;
			Gizmos.DrawWireCube(((Component)this).transform.TransformPoint(inPos), inSize);
			Gizmos.color = Color.yellow;
			Gizmos.DrawWireCube(((Component)this).transform.TransformPoint(outPos), outSize);
			Gizmos.color = new Color(0f, 1f, 0f, 0.5f);
			Gizmos.DrawWireCube(((Component)this).transform.position, nearSize);
			Gizmos.color = Color.cyan;
			foreach (Transform item in ((Component)this).transform)
			{
				Transform val = item;
				if (((Component)val).CompareTag("snappoint"))
				{
					Gizmos.DrawSphere(val.position, 0.05f);
				}
			}
		}
	}
	public enum HopperPriority
	{
		ItemDropPull = 0,
		SmelterFuelPush = 10,
		SmelterOrePush = 10,
		ContainerPull = 20,
		ContainerPush = 20,
		HopperPull = 30,
		HopperPush = 30,
		PipePull = 40,
		PipePush = 40,
		BeehivePull = 50,
		TurretPush = 60
	}
	public interface IPullTarget : ITarget, IEqualityComparer<ITarget>
	{
		HopperPriority PullPriority { get; }

		bool IsPickup { get; }

		IEnumerable<ItemData> GetItems();

		void RemoveItem(ItemData item, Inventory destination, Vector2i destinationPos, ZDOID sender);
	}
	public interface IPushTarget : ITarget, IEqualityComparer<ITarget>
	{
		HopperPriority PushPriority { get; }

		bool CanAddItem(ItemData item);

		void AddItem(ItemData item, Inventory source, ZDOID sender);
	}
	public interface ITarget : IEqualityComparer<ITarget>
	{
		int NetworkHashCode();

		bool IsValid();

		bool InRange(Vector3 position);
	}
	public class ItemFilter
	{
		private ZNetView zNetView;

		private Inventory inventory;

		private Dictionary<string, ZInt> slots = new Dictionary<string, ZInt>();

		public ItemFilter(ZNetView zNetView, Inventory inventory)
		{
			this.zNetView = zNetView;
			this.inventory = inventory;
		}

		public void Save()
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			foreach (ItemData item in inventory.m_inventory)
			{
				Vector2i gridPos = item.m_gridPos;
				int stableHashCode = StringExtensionMethods.GetStableHashCode(((Object)item.m_dropPrefab).name);
				SetItemHash(gridPos, stableHashCode);
			}
		}

		public void Clear()
		{
			for (int i = 0; i < inventory.m_width; i++)
			{
				for (int j = 0; j < inventory.m_height; j++)
				{
					SetItemHash(i, j, 0);
				}
			}
		}

		public void Copy(ItemFilter other)
		{
			for (int i = 0; i < inventory.m_width; i++)
			{
				for (int j = 0; j < inventory.m_height; j++)
				{
					SetItemHash(i, j, other.GetItemHash(i, j));
				}
			}
		}

		public void SetItemHash(Vector2i gridPos, int itemHash)
		{
			//IL_0002: 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)
			SetItemHash(gridPos.x, gridPos.y, itemHash);
		}

		public int GetItemHash(Vector2i gridPos)
		{
			//IL_0002: 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)
			return GetItemHash(gridPos.x, gridPos.y);
		}

		public void SetItemHash(int x, int y, int itemHash)
		{
			GetSlot(x, y).Set(itemHash);
		}

		public int GetItemHash(int x, int y)
		{
			return GetSlot(x, y).Get();
		}

		private ZInt GetSlot(int x, int y)
		{
			string key = $"hopper_filter_{x}_{y}";
			if (slots.TryGetValue(key, out var value))
			{
				return value;
			}
			value = new ZInt(key, 0, zNetView);
			slots[key] = value;
			return value;
		}
	}
	public class NetworkPiece : MonoBehaviour
	{
		protected ZNetView zNetView;

		protected virtual void Awake()
		{
			zNetView = ((Component)this).GetComponentInParent<ZNetView>();
		}

		public bool IsValid()
		{
			return Object.op_Implicit((Object)(object)this) && Object.op_Implicit((Object)(object)zNetView) && HopperHelper.IsValidNetView(zNetView) && zNetView.HasOwner();
		}

		public int NetworkHashCode()
		{
			return HopperHelper.GetNetworkHashCode(zNetView);
		}

		public bool Equals(ITarget x, ITarget y)
		{
			return x == y || x?.NetworkHashCode() == y?.NetworkHashCode();
		}

		public int GetHashCode(ITarget obj)
		{
			return obj.NetworkHashCode();
		}
	}
	public class Pipe : NetworkPiece, IPushTarget, ITarget, IEqualityComparer<ITarget>, IPullTarget
	{
		[SerializeField]
		private Vector3 outPos = new Vector3(0f, 0f, -1f);

		[SerializeField]
		private Vector3 outSize = new Vector3(0.5f, 0.5f, 0.5f);

		private Container container;

		private ContainerTarget containerTarget;

		private List<IPushTarget> pushTo = new List<IPushTarget>();

		private List<Hopper> nearHoppers = new List<Hopper>();

		private const float TransferInterval = 0.2f;

		private const float ObjectSearchInterval = 3f;

		private int transferFrame;

		private int objectSearchFrame;

		private int frameOffset;

		private int pushCounter;

		public HopperPriority PushPriority { get; } = HopperPriority.PipePull;


		public HopperPriority PullPriority { get; } = HopperPriority.PipePull;


		public bool IsPickup { get; } = false;


		protected override void Awake()
		{
			base.Awake();
			zNetView = ((Component)this).GetComponent<ZNetView>();
			container = ((Component)this).GetComponent<Container>();
			containerTarget = ((Component)this).GetComponent<ContainerTarget>();
			transferFrame = Mathf.RoundToInt(1f / Time.fixedDeltaTime * 0.2f);
			objectSearchFrame = Mathf.RoundToInt(1f / Time.fixedDeltaTime * 3f);
			frameOffset = Mathf.Abs(((Object)this).GetInstanceID() % transferFrame);
		}

		private void FixedUpdate()
		{
			if (IsValid() && zNetView.IsOwner())
			{
				int fixedFrameCount = HopperHelper.GetFixedFrameCount();
				int num = (fixedFrameCount + frameOffset) / transferFrame;
				if ((fixedFrameCount + frameOffset) % transferFrame == 0 && num % 2 == 1)
				{
					PushItems();
				}
				if ((fixedFrameCount + frameOffset + 1) % objectSearchFrame == 0)
				{
					FindIO();
				}
			}
		}

		public bool InRange(Vector3 position)
		{
			return true;
		}

		public bool CanAddItem(ItemData item)
		{
			return containerTarget.CanAddItem(item);
		}

		public void AddItem(ItemData item, Inventory source, ZDOID sender)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			containerTarget.AddItem(item, source, sender);
		}

		public IEnumerable<ItemData> GetItems()
		{
			return containerTarget.GetItems();
		}

		public void RemoveItem(ItemData item, Inventory destination, Vector2i destinationPos, ZDOID sender)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			containerTarget.RemoveItem(item, destination, destinationPos, sender);
		}

		private bool CanPushItem(ItemData item)
		{
			return !nearHoppers.Any((Hopper hopper) => hopper.pullFrom.Contains(this) && hopper.CanAddItem(item));
		}

		private void PushItems()
		{
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			if (pushTo.Count == 0)
			{
				return;
			}
			IPushTarget to = pushTo[pushCounter % pushTo.Count];
			pushCounter++;
			if (to.IsValid())
			{
				ItemData val = container.GetInventory().FindLastItem((ItemData i) => to.CanAddItem(i) && CanPushItem(i));
				if (val != null)
				{
					to.AddItem(val, container.GetInventory(), zNetView.m_zdo.m_uid);
				}
			}
		}

		private void FindIO()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			Quaternion rotation = ((Component)this).transform.rotation;
			pushTo = HopperHelper.FindTargets(((Component)this).transform.TransformPoint(outPos), outSize, rotation, (IPushTarget i) => i.PushPriority, this);
			nearHoppers = HopperHelper.FindTargets(((Component)this).transform.position, Vector3.one * 1.5f, rotation, (Hopper i) => i.PullPriority, this);
		}

		private void OnDrawGizmos()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: 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_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Expected O, but got Unknown
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			Gizmos.color = Color.yellow;
			Gizmos.DrawWireCube(((Component)this).transform.TransformPoint(outPos), outSize);
			Gizmos.color = Color.cyan;
			foreach (Transform item in ((Component)this).transform)
			{
				Transform val = item;
				if (((Component)val).CompareTag("snappoint"))
				{
					Gizmos.DrawSphere(val.position, 0.05f);
				}
			}
		}
	}
	public class BeehiveTarget : NetworkPiece, IPullTarget, ITarget, IEqualityComparer<ITarget>
	{
		private Beehive beehive;

		private const string RequestOwnershipRPC = "VH_RequestOwnership";

		public HopperPriority PullPriority { get; } = HopperPriority.BeehivePull;


		public bool IsPickup { get; } = false;


		protected override void Awake()
		{
			base.Awake();
			beehive = ((Component)this).GetComponent<Beehive>();
			beehive.m_nview.Register("VH_RequestOwnership", (Action<long>)RPC_RequestOwnership);
		}

		public bool InRange(Vector3 position)
		{
			return true;
		}

		public IEnumerable<ItemData> GetItems()
		{
			if (Object.op_Implicit((Object)(object)beehive.m_honeyItem) && beehive.GetHoneyLevel() > 0)
			{
				ItemHelper.CheckDropPrefab(beehive.m_honeyItem);
				yield return beehive.m_honeyItem.m_itemData;
			}
		}

		public void RemoveItem(ItemData item, Inventory destination, Vector2i destinationPos, ZDOID sender)
		{
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			if (!beehive.m_nview.IsOwner())
			{
				beehive.m_nview.InvokeRPC("VH_RequestOwnership", Array.Empty<object>());
				return;
			}
			int honeyLevel = beehive.GetHoneyLevel();
			if (honeyLevel > 0)
			{
				beehive.m_nview.GetZDO().Set(ZDOVars.s_level, honeyLevel - 1, false);
				destination.AddItem(item.Clone(), 1, destinationPos.x, destinationPos.y);
			}
		}

		private void RPC_RequestOwnership(long sender)
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			if (beehive.m_nview.IsOwner())
			{
				beehive.m_nview.GetZDO().SetOwner(sender);
				ZDOMan.instance.ForceSendZDO(sender, beehive.m_nview.GetZDO().m_uid);
			}
		}
	}
	public class ContainerTarget : NetworkPiece, IPushTarget, ITarget, IEqualityComparer<ITarget>, IPullTarget
	{
		private Container container;

		public HopperPriority PushPriority { get; } = HopperPriority.ContainerPull;


		public HopperPriority PullPriority { get; } = HopperPriority.ContainerPull;


		public bool IsPickup { get; } = false;


		protected override void Awake()
		{
			base.Awake();
			container = ((Component)this).GetComponent<Container>();
		}

		public IEnumerable<ItemData> GetItems()
		{
			return container.GetInventory().GetItemInReverseOrder();
		}

		public void AddItem(ItemData item, Inventory source, ZDOID sender)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			ContainerHandler.AddItemToChest(container, item, source, new Vector2i(-1, -1), sender, 1);
		}

		public void RemoveItem(ItemData item, Inventory destination, Vector2i destinationPos, ZDOID sender)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			ContainerHandler.RemoveItemFromChest(container, item, destination, destinationPos, sender, 1, (ItemData)null);
		}

		public bool CanAddItem(ItemData item)
		{
			return container.GetInventory().CanAddItem(item, 1);
		}

		public bool InRange(Vector3 position)
		{
			return true;
		}
	}
	public class ItemDropTarget : NetworkPiece, IPullTarget, ITarget, IEqualityComparer<ITarget>
	{
		private ItemDrop itemDrop;

		public HopperPriority PullPriority { get; } = HopperPriority.ItemDropPull;


		public bool IsPickup { get; } = true;


		protected override void Awake()
		{
			base.Awake();
			itemDrop = ((Component)this).GetComponent<ItemDrop>();
		}

		public IEnumerable<ItemData> GetItems()
		{
			if (Object.op_Implicit((Object)(object)itemDrop))
			{
				ItemHelper.CheckDropPrefab(itemDrop);
				yield return itemDrop.m_itemData;
			}
		}

		public void RemoveItem(ItemData item, Inventory destination, Vector2i destinationPos, ZDOID sender)
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			if (!itemDrop.m_nview.IsOwner())
			{
				itemDrop.RequestOwn();
			}
			else if (itemDrop.RemoveOne())
			{
				ItemData val = itemDrop.m_itemData.Clone();
				destination.AddItem(val, 1, destinationPos.x, destinationPos.y);
			}
		}

		public bool InRange(Vector3 position)
		{
			return true;
		}
	}
	public class SmelterFuelTarget : NetworkPiece, IPushTarget, ITarget, IEqualityComparer<ITarget>
	{
		private Smelter smelter;

		public HopperPriority PushPriority { get; } = HopperPriority.SmelterFuelPush;


		protected override void Awake()
		{
			base.Awake();
			smelter = ((Component)this).GetComponent<Smelter>();
		}

		public bool CanAddItem(ItemData item)
		{
			return Object.op_Implicit((Object)(object)smelter.m_fuelItem) && smelter.m_fuelItem.m_itemData.m_shared.m_name == item.m_shared.m_name && smelter.GetFuel() < (float)(smelter.m_maxFuel - 1);
		}

		public void AddItem(ItemData item, Inventory source, ZDOID sender)
		{
			if (source.RemoveItem(item, 1))
			{
				smelter.m_nview.InvokeRPC("RPC_AddFuel", Array.Empty<object>());
			}
		}

		public bool InRange(Vector3 position)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			return HopperHelper.IsInRange(position, ((Component)smelter.m_addWoodSwitch).transform.position, 1f);
		}
	}
	public class SmelterOreTarget : NetworkPiece, IPushTarget, ITarget, IEqualityComparer<ITarget>
	{
		private Smelter smelter;

		public HopperPriority PushPriority { get; } = HopperPriority.SmelterFuelPush;


		protected override void Awake()
		{
			base.Awake();
			smelter = ((Component)this).GetComponent<Smelter>();
		}

		public bool CanAddItem(ItemData item)
		{
			return smelter.IsItemAllowed(item) && smelter.GetQueueSize() < smelter.m_maxOre;
		}

		public void AddItem(ItemData item, Inventory source, ZDOID sender)
		{
			source.RemoveItem(item, 1);
			smelter.m_nview.InvokeRPC("RPC_AddOre", new object[1] { ((Object)item.m_dropPrefab).name });
		}

		public bool InRange(Vector3 position)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			return HopperHelper.IsInRange(position, ((Component)smelter.m_addOreSwitch).transform.position, 1f);
		}
	}
	public class TurretTarget : NetworkPiece, IPushTarget, ITarget, IEqualityComparer<ITarget>
	{
		private Turret turret;

		public HopperPriority PushPriority { get; } = HopperPriority.TurretPush;


		protected override void Awake()
		{
			base.Awake();
			turret = ((Component)this).GetComponent<Turret>();
		}

		public void AddItem(ItemData item, Inventory source, ZDOID sender)
		{
			if (source.RemoveItem(item, 1))
			{
				turret.m_nview.InvokeRPC("RPC_AddAmmo", new object[1] { ((Object)item.m_dropPrefab).name });
			}
		}

		public bool CanAddItem(ItemData item)
		{
			if (!turret.IsItemAllowed(((Object)item.m_dropPrefab).name))
			{
				return false;
			}
			if (turret.GetAmmo() > 0 && turret.GetAmmoType() != ((Object)item.m_dropPrefab).name)
			{
				return false;
			}
			if (turret.GetAmmo() >= turret.m_maxAmmo)
			{
				return false;
			}
			return true;
		}

		public bool InRange(Vector3 position)
		{
			return true;
		}
	}
	public abstract class ZProperty<T>
	{
		public string Key { get; }

		public T DefaultValue { get; }

		protected ZNetView NetView { get; }

		protected int KeyHash { get; }

		private string RPCName { get; }

		protected ZProperty(string key, T defaultValue, ZNetView netView)
		{
			Key = key;
			RPCName = "RPC_" + key;
			KeyHash = StringExtensionMethods.GetStableHashCode(Key);
			DefaultValue = defaultValue;
			NetView = netView;
			NetView.Register<T>(RPCName, (Action<long, T>)RPCSet);
		}

		public void Set(T value)
		{
			if (NetView.IsValid() && NetView.IsOwner())
			{
				SetValue(value);
				return;
			}
			NetView.InvokeRPC(RPCName, new object[1] { value });
		}

		public void Reset()
		{
			Set(DefaultValue);
		}

		public abstract T Get();

		protected abstract void SetValue(T value);

		private void RPCSet(long sender, T value)
		{
			SetValue(value);
		}
	}
	public class ZBool : ZProperty<bool>
	{
		public ZBool(string key, bool defaultValue, ZNetView zNetView)
			: base(key, defaultValue, zNetView)
		{
		}

		public override bool Get()
		{
			return base.NetView.GetZDO().GetBool(base.KeyHash, base.DefaultValue);
		}

		protected override void SetValue(bool value)
		{
			base.NetView.GetZDO().Set(base.KeyHash, value);
		}
	}
	public class ZInt : ZProperty<int>
	{
		public ZInt(string key, int defaultValue, ZNetView zNetView)
			: base(key, defaultValue, zNetView)
		{
		}

		public override int Get()
		{
			return base.NetView.GetZDO().GetInt(base.KeyHash, base.DefaultValue);
		}

		protected override void SetValue(int value)
		{
			base.NetView.GetZDO().Set(base.KeyHash, value, false);
		}
	}
}
namespace ValheimHopper.Logic.Helper
{
	public static class HopperHelper
	{
		private static readonly Collider[] tempColliders = (Collider[])(object)new Collider[256];

		private static int PieceMask { get; } = LayerMask.GetMask(new string[2] { "piece", "piece_nonsolid" });


		private static int ItemMask { get; } = LayerMask.GetMask(new string[1] { "item" });


		public static bool IsInRange(Vector3 position, Vector3 target, float range)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			return Vector3.SqrMagnitude(target - position) < range * range;
		}

		public static bool IsInRange(Vector3 position, Collider collider, float range)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			Bounds bounds = collider.bounds;
			((Bounds)(ref bounds)).Expand(range);
			return ((Bounds)(ref bounds)).Contains(position);
		}

		public static bool IsValidNetView(ZNetView netView)
		{
			return Object.op_Implicit((Object)(object)netView) && netView.IsValid() && netView.m_zdo != null;
		}

		public static int GetNetworkHashCode(ZNetView netView)
		{
			return ((object)(ZDOID)(ref netView.m_zdo.m_uid)).GetHashCode();
		}

		public static int GetFixedFrameCount()
		{
			return Mathf.RoundToInt(Time.fixedTime / Time.fixedDeltaTime);
		}

		public static List<T> FindTargets<T>(Vector3 pos, Vector3 size, Quaternion rotation, Func<T, HopperPriority> orderBy, ITarget exclude) where T : ITarget
		{
			//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_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			List<T> list = new List<T>();
			int num = Physics.OverlapBoxNonAlloc(pos, size / 2f, tempColliders, rotation, PieceMask | ItemMask);
			for (int i = 0; i < num; i++)
			{
				List<T> collection = (from target in ((Component)tempColliders[i]).GetComponentsInParent<T>()
					where target.InRange(pos) && target.IsValid() && target.NetworkHashCode() != exclude.NetworkHashCode()
					select target).ToList();
				list.AddRange(collection);
			}
			return (from t in list.OrderByDescending(orderBy)
				group t by t.NetworkHashCode() into t
				select t.First()).ToList();
		}
	}
	public static class InventoryHelper
	{
		public static ItemData FindLastItem(this Inventory target, Func<ItemData, bool> predicate)
		{
			if (target.m_inventory.Count == 0)
			{
				return null;
			}
			for (int num = target.m_height - 1; num >= 0; num--)
			{
				for (int num2 = target.m_width - 1; num2 >= 0; num2--)
				{
					ItemData itemAt = target.GetItemAt(num2, num);
					if (itemAt != null && predicate(itemAt))
					{
						return itemAt;
					}
				}
			}
			return null;
		}

		public static IEnumerable<ItemData> GetItemInReverseOrder(this Inventory target)
		{
			if (target.m_inventory.Count == 0)
			{
				yield break;
			}
			for (int y = target.m_height - 1; y >= 0; y--)
			{
				for (int x = target.m_width - 1; x >= 0; x--)
				{
					ItemData item = target.GetItemAt(x, y);
					if (item != null)
					{
						yield return item;
					}
				}
			}
		}
	}
	public static class ItemHelper
	{
		private static readonly Dictionary<string, Vector3> ItemOffsetCache = new Dictionary<string, Vector3>();

		public static Vector3 GetVisualItemOffset(string name)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: 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_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: 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_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: 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)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//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_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			if (ItemOffsetCache.TryGetValue(name, out var value))
			{
				return value;
			}
			GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(StringExtensionMethods.GetStableHashCode(name));
			if (!Object.op_Implicit((Object)(object)itemPrefab))
			{
				Logger.LogWarning((object)("Could not find item " + name + " for offset calculation"));
				ItemOffsetCache[name] = Vector3.zero;
				return ItemOffsetCache[name];
			}
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor(1000f, 1000f, 1000f);
			Vector3 val2 = default(Vector3);
			((Vector3)(ref val2))..ctor(-1000f, -1000f, -1000f);
			Vector3 position = itemPrefab.transform.position;
			Renderer[] componentsInChildren = itemPrefab.GetComponentsInChildren<Renderer>();
			foreach (Renderer val3 in componentsInChildren)
			{
				if (!(val3 is ParticleSystemRenderer))
				{
					Vector3 val4 = val;
					Bounds bounds = val3.bounds;
					val = Vector3.Min(val4, position - ((Bounds)(ref bounds)).min);
					Vector3 val5 = val2;
					bounds = val3.bounds;
					val2 = Vector3.Max(val5, position - ((Bounds)(ref bounds)).max);
				}
			}
			value = (val + val2) / 2f;
			ItemOffsetCache[name] = value;
			return value;
		}

		public static void CheckDropPrefab(ItemDrop itemDrop)
		{
			if (!Object.op_Implicit((Object)(object)itemDrop.m_itemData.m_dropPrefab))
			{
				itemDrop.m_itemData.m_dropPrefab = ObjectDB.instance.GetItemPrefab(itemDrop.GetPrefabName(((Object)((Component)itemDrop).gameObject).name));
			}
		}
	}
	public static class SnappointHelper
	{
		public static void AddSnappoints(string name, Vector3[] points)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			GameObject prefab = PrefabManager.Instance.GetPrefab(name);
			if ((Object)(object)prefab == (Object)null)
			{
				Logger.LogWarning((object)(name + " not found. Cannot add snappoints"));
				return;
			}
			foreach (Vector3 pos in points)
			{
				CreateSnappoint(pos, prefab.transform);
			}
		}

		private static void CreateSnappoint(Vector3 pos, Transform parent)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("_snappoint");
			val.transform.parent = parent;
			val.transform.localPosition = pos;
			val.tag = "snappoint";
			val.SetActive(false);
		}

		public static void FixPiece(string name)
		{
			GameObject prefab = PrefabManager.Instance.GetPrefab(name);
			if ((Object)(object)prefab == (Object)null)
			{
				Logger.LogWarning((object)(name + " not found. Cannot fix piece snappoints"));
				return;
			}
			Collider[] componentsInChildren = prefab.GetComponentsInChildren<Collider>();
			foreach (Collider val in componentsInChildren)
			{
				((Component)val).gameObject.layer = LayerMask.NameToLayer("piece");
			}
		}
	}
}
namespace ValheimHopper.Debug
{
	public class UnityDebugEnv : MonoBehaviour
	{
		private void Awake()
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Expected O, but got Unknown
			ZNet.SetServer(true, false, false, "Server Name", "Test", World.GetDevWorld());
			ZNet.instance.m_players.Add(default(PlayerInfo));
			Game.instance.m_playerProfile = new PlayerProfile("Developer", (FileSource)1);
			Game.instance.m_playerProfile.SetName("Odev");
			Game.instance.m_playerProfile.Load();
		}
	}
}