Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of ItemHopper Valheim1Compat v1.0.1
plugins/ItemHopper_Valheim1Compat/ValheimHopper.dll
Decompiled a week ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; 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 Microsoft.CodeAnalysis; using MultiUserChest; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; using ValheimHopper.Logic; using ValheimHopper.Logic.Helper; using ValheimHopper.UI; using ValheimPipes; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("ValheimPipes")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("ValheimPipes")] [assembly: AssemblyCopyright("Copyright \ufffd 2021")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("FE8B42E3-7082-4DFF-A5CC-6B62B0315ACA")] [assembly: AssemblyFileVersion("1.0.1")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.1.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace 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; private Toggle blacklistMode; private Toggle stackMode; [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_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Expected O, but got Unknown //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: 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 Instance = this; ((UnityEvent<bool>)(object)dropItems.onValueChanged).AddListener((UnityAction<bool>)delegate(bool i) { if ((Object)(object)target != (Object)null) { target.DropItemsOption.Set(i); } }); ((UnityEvent<bool>)(object)pickupItems.onValueChanged).AddListener((UnityAction<bool>)delegate(bool i) { if ((Object)(object)target != (Object)null) { target.PickupItemsOption.Set(i); } }); ((UnityEvent<bool>)(object)leaveLastItem.onValueChanged).AddListener((UnityAction<bool>)delegate(bool i) { if ((Object)(object)target != (Object)null) { target.LeaveLastItemOption.Set(i); } }); ((UnityEvent<bool>)(object)filterHopper.onValueChanged).AddListener((UnityAction<bool>)delegate(bool active) { if (!((Object)(object)target == (Object)null)) { target.FilterItemsOption.Set(active); if (active) { target.filter.Save(); } else { target.filter.Clear(); } } }); ((UnityEvent)copyButton.onClick).AddListener((UnityAction)delegate { if ((Object)(object)target != (Object)null) { copy = target; } }); ((UnityEvent)pasteButton.onClick).AddListener((UnityAction)delegate { if ((Object)(object)target != (Object)null && (Object)(object)copy != (Object)null && copy.IsValid()) { target.PasteData(copy); } }); ((UnityEvent)resetButton.onClick).AddListener((UnityAction)delegate { if ((Object)(object)target != (Object)null) { target.ResetValues(); } }); } private void SetupNewToggles() { ((UnityEvent<bool>)(object)blacklistMode.onValueChanged).AddListener((UnityAction<bool>)delegate(bool i) { if ((Object)(object)target != (Object)null) { target.BlacklistModeOption.Set(i); } }); ((UnityEvent<bool>)(object)stackMode.onValueChanged).AddListener((UnityAction<bool>)delegate(bool i) { if ((Object)(object)target != (Object)null) { target.StackModeOption.Set(i); } }); } public static void Init() { //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) GameObject obj = Object.Instantiate<GameObject>(Plugin.AssetBundle.LoadAsset<GameObject>("HopperUI"), GUIManager.CustomGUIFront.transform, false); uiRoot = ((Component)obj.transform.GetChild(0)).gameObject; HopperUI component = obj.GetComponent<HopperUI>(); if ((Object)(object)component == (Object)null) { Logger.LogWarning((object)"HopperUI component missing on prefab! If you renamed the namespace, you must restore it to ValheimHopper.UI for AssetBundle compatibility."); uiRoot.SetActive(false); return; } ApplyAllComponents(uiRoot); GUIManager.Instance.ApplyTextStyle(component.title, GUIManager.Instance.AveriaSerifBold, GUIManager.Instance.ValheimOrange, 20, true); ApplyLocalization(); component.blacklistMode = CreateToggle(component.filterHopper, "BlacklistMode", "$hopper_options_blacklist", new Vector2(0f, -110f)); component.stackMode = CreateToggle(component.filterHopper, "StackMode", "$hopper_options_stack", new Vector2(0f, -140f)); component.SetupNewToggles(); 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()); blacklistMode.SetIsOnWithoutNotify(target.BlacklistModeOption.Get()); stackMode.SetIsOnWithoutNotify(target.StackModeOption.Get()); bool active = ((Object)target).name.Contains("Iron"); ((Component)stackMode).gameObject.SetActive(active); } private static void ApplyAllComponents(GameObject root) { //IL_001f: 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); } } private static Toggle CreateToggle(Toggle source, string name, string label, Vector2 offset) { //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_0026: 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) Toggle val = Object.Instantiate<Toggle>(source, ((Component)source).transform.parent); ((Object)val).name = name; Transform transform = ((Component)val).transform; transform.localPosition += Vector2.op_Implicit(offset); ((Component)val).GetComponentInChildren<Text>().text = Localization.instance.Localize(label); GUIManager.Instance.ApplyToogleStyle(val); return val; } } } 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, 0.5f, 1f); [SerializeField] private Vector3 outSize = new Vector3(1f, 1f, 1f); private List<IPushTarget> pushTo = new List<IPushTarget>(); internal List<IPullTarget> pullFrom = new List<IPullTarget>(); private BoxVisualizer inVisualizer; private BoxVisualizer outVisualizer; private int lastPullFrame = -1; private const float ObjectSearchInterval = 3f; private int transferFrame; private int objectSearchFrame; private int frameOffset; 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; } public Vector3 InPos => inPos; public Vector3 InSize => inSize; public ZBool FilterItemsOption { get; private set; } public ZBool BlacklistModeOption { get; private set; } public ZBool StackModeOption { get; private set; } public ZBool DropItemsOption { get; private set; } public ZBool PickupItemsOption { get; private set; } public ZBool LeaveLastItemOption { get; private set; } private string DbgId { get { //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) Vector3 position = ((Component)this).transform.position; return "Hopper@" + ((Vector3)(ref position)).ToString("F1"); } } protected override void Awake() { //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013e: 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) 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); BlacklistModeOption = new ZBool("hopper_blacklist_mode", defaultValue: false, zNetView); StackModeOption = new ZBool("hopper_stack_mode", 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); UpdateTransferRate(); objectSearchFrame = Mathf.RoundToInt(1f / Time.fixedDeltaTime * 3f); frameOffset = Mathf.Abs(((Object)this).GetInstanceID() % transferFrame); inVisualizer = ((Component)this).gameObject.AddComponent<BoxVisualizer>(); inVisualizer.SetData(inPos, inSize, Color.blue, Plugin.ShowHopperInputBox); outVisualizer = ((Component)this).gameObject.AddComponent<BoxVisualizer>(); outVisualizer.SetData(outPos, outSize, Color.yellow, Plugin.ShowHopperOutputBox); } private void UpdateTransferRate() { float num = (((Object)this).name.Contains("Iron") ? Plugin.IronTransferRate.Value : Plugin.BronzeTransferRate.Value); float num2 = 30f / Mathf.Max(1f, num); transferFrame = Mathf.RoundToInt(num2 / Time.fixedDeltaTime); if (transferFrame < 1) { transferFrame = 1; } } private void Start() { filter = new ItemFilter(zNetView, container.GetInventory()); Inventory inventory = container.GetInventory(); inventory.m_onChanged = (Action)Delegate.Combine(inventory.m_onChanged, new Action(OnInventoryChanged)); HopperHelper.OnTargetChanged += OnTargetChanged; } private void OnDestroy() { HopperHelper.OnTargetChanged -= OnTargetChanged; } private void OnInventoryChanged() { WakeUp(); if (IsValid() && FilterItemsOption.Get()) { filter.Save(); } } private void OnTargetChanged(ITarget target) { if (base.IsPushBlocked && pushTo.Any((IPushTarget t) => t.NetworkHashCode() == target.NetworkHashCode())) { base.IsPushBlocked = false; } if (base.IsPullBlocked && pullFrom.Any((IPullTarget t) => t.NetworkHashCode() == target.NetworkHashCode())) { base.IsPullBlocked = false; } } public void PasteData(Hopper copy) { FilterItemsOption.Set(copy.FilterItemsOption.Get()); BlacklistModeOption.Set(copy.BlacklistModeOption.Get()); StackModeOption.Set(copy.StackModeOption.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(); BlacklistModeOption.Reset(); StackModeOption.Reset(); DropItemsOption.Reset(); PickupItemsOption.Reset(); LeaveLastItemOption.Reset(); filter.Clear(); } private void FixedUpdate() { if (!IsValid() || !zNetView.IsOwner() || Plugin.DisableAllSystems.Value) { return; } int fixedFrameCount = HopperHelper.GetFixedFrameCount(); int num = (fixedFrameCount + frameOffset) / transferFrame; if ((fixedFrameCount + frameOffset) % transferFrame == 0) { if (num % 2 == 0 && !base.IsPullBlocked) { PullItems(); } if (num % 2 == 1 && !base.IsPushBlocked) { PushItems(); } } if ((fixedFrameCount + frameOffset + 1) % objectSearchFrame == 0) { FindIO(); } } private void PullItems() { //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) if (pullFrom.Count == 0) { base.IsPullBlocked = true; return; } int num = pullCounter % pullFrom.Count; IPullTarget pullTarget = pullFrom[num]; pullCounter++; if (!pullTarget.IsValid()) { Plugin.Debug($"[{DbgId}] Pull source [{num}] invalid, skipping"); } else { if (!PickupItemsOption.Get() && pullTarget.IsPickup) { return; } foreach (ItemData item in pullTarget.GetItems()) { if (!FindFreeSlot(item, out var pos)) { Plugin.Debug($"[{DbgId}] No free slot for '{item.m_shared.m_name}' from source [{num}]"); base.IsPullBlocked = true; continue; } int num2 = 1; if (StackModeOption.Get() && ((Object)this).name.Contains("Iron")) { int maxStackSize = item.m_shared.m_maxStackSize; int stack = item.m_stack; int roomForItem = container.GetInventory().GetRoomForItem(item); num2 = Mathf.Min(new int[3] { maxStackSize, stack, roomForItem }); } object[] obj = new object[6] { DbgId, num2, item.m_shared.m_name, pullTarget.GetType().Name, null, null }; IPullTarget obj2 = ((pullTarget is MonoBehaviour) ? pullTarget : null); obj[4] = ((obj2 != null) ? ((Object)((Component)obj2).gameObject).name : null); obj[5] = pullCounter; Plugin.Debug(string.Format("[{0}] Pulling {1}x '{2}' <- {3} ({4}) (counter={5})", obj)); pullTarget.RemoveItem(item, container.GetInventory(), pos, zNetView.m_zdo.m_uid, num2); HopperHelper.NotifyChange(this); HopperHelper.NotifyChange(pullTarget); return; } base.IsPullBlocked = true; } } private void PushItems() { //IL_01ad: Unknown result type (might be due to invalid IL or missing references) if (pushTo.Count == 0) { if (DropItemsOption.Get()) { DropItem(); } else { base.IsPushBlocked = true; } return; } int num = OutputCounter % pushTo.Count; IPushTarget to = pushTo[num]; OutputCounter++; if (!to.IsValid()) { Plugin.Debug($"[{DbgId}] Push target [{num}] invalid, skipping"); return; } ItemData val = container.GetInventory().FindLastItem((ItemData i) => to.CanAddItem(i) && CanPushItem(i)); if (val != null) { int num2 = 1; if (StackModeOption.Get() && ((Object)this).name.Contains("Iron")) { int maxStackSize = val.m_shared.m_maxStackSize; int num3 = container.GetInventory().CountItems(val.m_shared.m_name, -1, true); if (LeaveLastItemOption.Get()) { num3--; } num2 = Mathf.Min(maxStackSize, num3); } object[] obj = new object[6] { DbgId, num2, val.m_shared.m_name, to.GetType().Name, null, null }; IPushTarget pushTarget = to; IPushTarget obj2 = ((pushTarget is MonoBehaviour) ? pushTarget : null); obj[4] = ((obj2 != null) ? ((Object)((Component)obj2).gameObject).name : null); obj[5] = OutputCounter; Plugin.Debug(string.Format("[{0}] Pushing {1}x '{2}' -> {3} ({4}) (counter={5})", obj)); to.AddItem(val, container.GetInventory(), zNetView.m_zdo.m_uid, num2); HopperHelper.NotifyChange(this); HopperHelper.NotifyChange(to); } else { Plugin.Debug($"[{DbgId}] No pushable item for target [{num}] ({to.GetType().Name}) (full, filtered, or leave-last)"); base.IsPushBlocked = true; } } private void DropItem() { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0060: 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_0071: 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_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0099: 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_00a4: 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_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) 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, int amount = 1) { //IL_0012: 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) FindFreeSlot(item, out var pos); ContainerHandler.AddItemToChest(container, item, source, pos, sender, amount); } public IEnumerable<ItemData> GetItems() { if (HopperHelper.GetFixedFrameCount() == lastPullFrame) { return Enumerable.Empty<ItemData>(); } return containerTarget.GetItems(); } public void RemoveItem(ItemData item, Inventory destination, Vector2i destinationPos, ZDOID sender, int amount = 1) { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) Plugin.Debug("[" + DbgId + "] RemoveItem '" + item.m_shared.m_name + "' pulled by upstream"); lastPullFrame = HopperHelper.GetFixedFrameCount(); containerTarget.RemoveItem(item, destination, destinationPos, sender, amount); } private bool FindFreeSlot(ItemData itemToAdd, out Vector2i pos) { //IL_0003: 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_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: 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_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: 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))) { continue; } if (FilterItemsOption.Get()) { if (BlacklistModeOption.Get()) { if (filter.Contains(stableHashCode)) { return false; } 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; } continue; } pos = new Vector2i(j, i); return true; } } return false; } public bool InRange(Vector3 position) { return true; } private bool CanPushItem(ItemData item) { if (LeaveLastItemOption.Get()) { return container.GetInventory().CountItems(item.m_shared.m_name, -1, true) > 1; } return true; } private void FindIO() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: 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) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: 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); int count = pullFrom.Count; pullFrom.RemoveAll((IPullTarget i) => i is Pipe); if (pullFrom.Count < count) { Plugin.Debug($"[{DbgId}] Ignored {count - pullFrom.Count} Upstream Pipes (Hoppers cannot pull from Pipes)"); } pushTo = HopperHelper.FindTargets(((Component)this).transform.TransformPoint(outPos), outSize, rotation, (IPushTarget i) => i.PushPriority, this); Plugin.Debug(string.Format("[{0}] Targets: Pull[{1}] {2}", DbgId, pullFrom.Count, string.Join(", ", pullFrom.Select(delegate(IPullTarget t) { IPullTarget obj = ((t is MonoBehaviour) ? t : null); return ((obj != null) ? ((Object)((Component)obj).gameObject).name : null) ?? t.GetType().Name; })))); Plugin.Debug(string.Format("[{0}] Targets: Push[{1}] {2}", DbgId, pushTo.Count, string.Join(", ", pushTo.Select(delegate(IPushTarget t) { IPushTarget obj = ((t is MonoBehaviour) ? t : null); return ((obj != null) ? ((Object)((Component)obj).gameObject).name : null) ?? t.GetType().Name; })))); pullFrom.RemoveAll((IPullTarget pull) => pushTo.Exists((IPushTarget push) => push.NetworkHashCode() == pull.NetworkHashCode())); WakeUp(); } private void OnDrawGizmos() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0011: 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_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0026: 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) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Expected O, but got Unknown //IL_007e: 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 = 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, int amount = 1); } public interface IPushTarget : ITarget, IEqualityComparer<ITarget> { HopperPriority PushPriority { get; } bool CanAddItem(ItemData item); void AddItem(ItemData item, Inventory source, ZDOID sender, int amount = 1); } 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_001b: 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_0032: 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_0001: 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) SetItemHash(gridPos.x, gridPos.y, itemHash); } public int GetItemHash(Vector2i gridPos) { //IL_0001: 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) 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 bool Contains(int itemHash) { for (int i = 0; i < inventory.m_width; i++) { for (int j = 0; j < inventory.m_height; j++) { if (GetItemHash(i, j) == itemHash) { return true; } } } return false; } } public class NetworkPiece : MonoBehaviour { protected ZNetView zNetView; protected int OutputCounter; public bool IsPushBlocked { get; protected set; } public bool IsPullBlocked { get; protected set; } protected virtual void Awake() { zNetView = ((Component)this).GetComponentInParent<ZNetView>(); } public void WakeUp() { IsPushBlocked = false; IsPullBlocked = false; } public bool IsValid() { if (Object.op_Implicit((Object)(object)this) && Object.op_Implicit((Object)(object)zNetView) && HopperHelper.IsValidNetView(zNetView)) { return zNetView.HasOwner(); } return false; } public int NetworkHashCode() { if (Object.op_Implicit((Object)(object)zNetView) && zNetView.m_zdo != null) { return HopperHelper.GetNetworkHashCode(zNetView); } return ((Object)this).GetInstanceID(); } public bool Equals(ITarget x, ITarget y) { if (x != y) { return x?.NetworkHashCode() == y?.NetworkHashCode(); } return true; } 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.25f, 0.5f, 0.5f); private Container container; private ContainerTarget containerTarget; private List<IPushTarget> pushTo = new List<IPushTarget>(); private BoxVisualizer outVisualizer; private int lastPullFrame = -1; private const float ObjectSearchInterval = 3f; private int transferFrame; private int objectSearchFrame; private int frameOffset; public HopperPriority PushPriority { get; } = HopperPriority.PipePull; public HopperPriority PullPriority { get; } = HopperPriority.PipePull; public bool IsPickup { get; } private string DbgId { get { //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) Vector3 position = ((Component)this).transform.position; return "Pipe@" + ((Vector3)(ref position)).ToString("F1"); } } protected override void Awake() { //IL_0070: 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) base.Awake(); container = ((Component)this).GetComponent<Container>(); containerTarget = ((Component)this).GetComponent<ContainerTarget>(); UpdateTransferRate(); objectSearchFrame = Mathf.RoundToInt(1f / Time.fixedDeltaTime * 3f); frameOffset = Mathf.Abs(((Object)this).GetInstanceID() % transferFrame); outVisualizer = ((Component)this).gameObject.AddComponent<BoxVisualizer>(); outVisualizer.SetData(outPos, outSize, Color.yellow, Plugin.ShowPipeOutputBox); } private void Start() { Inventory inventory = container.GetInventory(); inventory.m_onChanged = (Action)Delegate.Combine(inventory.m_onChanged, new Action(base.WakeUp)); HopperHelper.OnTargetChanged += OnTargetChanged; } private void OnDestroy() { HopperHelper.OnTargetChanged -= OnTargetChanged; } private void OnTargetChanged(ITarget target) { if (base.IsPushBlocked && pushTo.Any((IPushTarget t) => t.NetworkHashCode() == target.NetworkHashCode())) { base.IsPushBlocked = false; } } private void UpdateTransferRate() { float num = (((Object)this).name.Contains("Iron") ? Plugin.IronTransferRate.Value : Plugin.BronzeTransferRate.Value); float num2 = 30f / Mathf.Max(1f, num); transferFrame = Mathf.RoundToInt(num2 / Time.fixedDeltaTime); if (transferFrame < 1) { transferFrame = 1; } } private void FixedUpdate() { if (IsValid() && zNetView.IsOwner() && !Plugin.DisableAllSystems.Value) { int fixedFrameCount = HopperHelper.GetFixedFrameCount(); int num = (fixedFrameCount + frameOffset) / transferFrame; if ((fixedFrameCount + frameOffset) % transferFrame == 0 && num % 2 == 1 && !base.IsPushBlocked) { 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, int amount = 1) { //IL_005d: Unknown result type (might be due to invalid IL or missing references) Plugin.Debug("[" + DbgId + "] AddItem '" + (item?.m_shared?.m_name ?? "null") + "' pushed by upstream"); containerTarget.AddItem(item, source, sender, amount); } public IEnumerable<ItemData> GetItems() { if (HopperHelper.GetFixedFrameCount() == lastPullFrame) { return Enumerable.Empty<ItemData>(); } return containerTarget.GetItems(); } public void RemoveItem(ItemData item, Inventory destination, Vector2i destinationPos, ZDOID sender, int amount = 1) { //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) Plugin.Debug("[" + DbgId + "] RemoveItem '" + (item?.m_shared?.m_name ?? "null") + "' pulled by hopper"); lastPullFrame = HopperHelper.GetFixedFrameCount(); containerTarget.RemoveItem(item, destination, destinationPos, sender, amount); } private void PushItems() { //IL_012f: Unknown result type (might be due to invalid IL or missing references) if (pushTo.Count == 0 || container.GetInventory().NrOfItems() == 0) { base.IsPushBlocked = true; return; } int num = OutputCounter % pushTo.Count; IPushTarget to = pushTo[num]; OutputCounter++; if (!to.IsValid()) { Plugin.Debug($"[{DbgId}] Push target [{num}] invalid, skipping"); return; } ItemData val = container.GetInventory().FindLastItem((ItemData i) => to.CanAddItem(i)); if (val != null) { Plugin.Debug(string.Format("[{0}] Pushing '{1}' -> target [{2}] ({3}) (counter={4})", DbgId, val.m_shared?.m_name ?? "null", num, to.GetType().Name, OutputCounter)); to.AddItem(val, container.GetInventory(), zNetView.m_zdo.m_uid); HopperHelper.NotifyChange(this); HopperHelper.NotifyChange(to); } else { Plugin.Debug($"[{DbgId}] No pushable item for target [{num}] ({to.GetType().Name}) (full or filtered)"); base.IsPushBlocked = true; } } private void FindIO() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_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_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011d: 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_0130: Unknown result type (might be due to invalid IL or missing references) Quaternion rotation = ((Component)this).transform.rotation; List<IPushTarget> list = HopperHelper.FindTargets(((Component)this).transform.TransformPoint(outPos), outSize, rotation, (IPushTarget i) => i.PushPriority, this); Collider[] array = Physics.OverlapSphere(((Component)this).transform.position, 2.5f, LayerMask.GetMask(new string[2] { "piece", "piece_nonsolid" })); foreach (Collider val in array) { Hopper hopper = ((Component)val).GetComponentInParent<Hopper>(); if ((Object)(object)hopper != (Object)null && !list.Any((IPushTarget t) => t.NetworkHashCode() == hopper.NetworkHashCode())) { list.Add(hopper); } } List<IPushTarget> list2 = new List<IPushTarget>(); Collider[] componentsInChildren = ((Component)this).GetComponentsInChildren<Collider>(); foreach (IPushTarget item in list) { if (item is Hopper hopper2) { if (HopperHelper.BoxIntersectsColliders(((Component)hopper2).transform.TransformPoint(hopper2.InPos), hopper2.InSize, ((Component)hopper2).transform.rotation, componentsInChildren)) { list2.Add(item); Plugin.Debug("[" + DbgId + "] Added Hopper output via body-overlap: " + ((Object)((Component)hopper2).gameObject).name); } else { Plugin.Debug("[" + DbgId + "] Skipped Hopper (no body-overlap): " + ((Object)((Component)hopper2).gameObject).name); } continue; } list2.Add(item); MonoBehaviour val2 = (MonoBehaviour)((item is MonoBehaviour) ? item : null); if (val2 != null) { Plugin.Debug("[" + DbgId + "] Added standard output target: " + ((Object)((Component)val2).gameObject).name); } } pushTo = list2; Plugin.Debug("[" + DbgId + "] Output list: [" + string.Join(", ", pushTo.Select((IPushTarget t) => t.GetType().Name)) + "]"); WakeUp(); } private void OnDrawGizmos() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0011: 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_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown //IL_0058: 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; } 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, int amount = 1) { //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0073: 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(); int num = Mathf.Min(honeyLevel, amount); if (num > 0) { beehive.m_nview.GetZDO().Set(ZDOVars.s_level, honeyLevel - num, false); destination.AddItem(item.Clone(), num, destinationPos.x, destinationPos.y, false); } } private void RPC_RequestOwnership(long sender) { //IL_003f: 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 ClayCollectorTarget : NetworkPiece, IPullTarget, ITarget, IEqualityComparer<ITarget> { private Component collectorComponent; private MethodInfo getTarLevelMethod; private MethodInfo resetLevelMethod; private FieldInfo clayItemField; private const string RequestOwnershipRPC = "VH_RequestOwnership_Clay"; public HopperPriority PullPriority { get; } = HopperPriority.BeehivePull; public bool IsPickup { get; } protected override void Awake() { base.Awake(); collectorComponent = ((Component)this).GetComponent("ClayCollector"); if ((Object)(object)collectorComponent != (Object)null) { Type type = ((object)collectorComponent).GetType(); getTarLevelMethod = type.GetMethod("GetTarLevel", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); resetLevelMethod = type.GetMethod("ResetLevel", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); clayItemField = type.GetField("m_clayItem", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); Plugin.Debug($"[ClayCollector] Found component. Methods: GetTarLevel={getTarLevelMethod != null}, ResetLevel={resetLevelMethod != null}, m_clayItem={clayItemField != null}"); } else { Plugin.Debug("[ClayCollector] Critical: 'ClayCollector' component not found on this object!"); } if ((Object)(object)zNetView != (Object)null) { zNetView.Register("VH_RequestOwnership_Clay", (Action<long>)RPC_RequestOwnership); } } public bool InRange(Vector3 position) { return true; } public IEnumerable<ItemData> GetItems() { if ((Object)(object)zNetView == (Object)null || !zNetView.IsValid() || (Object)(object)collectorComponent == (Object)null || GetCurrentLevel() <= 0) { yield break; } GameObject clayPrefab = GetClayPrefab(); if (Object.op_Implicit((Object)(object)clayPrefab)) { ItemDrop component = clayPrefab.GetComponent<ItemDrop>(); if (Object.op_Implicit((Object)(object)component)) { yield return component.m_itemData; } } } public void RemoveItem(ItemData item, Inventory destination, Vector2i destinationPos, ZDOID sender, int amount = 1) { //IL_00b0: 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) if ((Object)(object)zNetView == (Object)null || !zNetView.IsValid() || (Object)(object)collectorComponent == (Object)null) { return; } if (!zNetView.IsOwner()) { zNetView.InvokeRPC("VH_RequestOwnership_Clay", Array.Empty<object>()); return; } int currentLevel = GetCurrentLevel(); if (currentLevel > 0) { if (resetLevelMethod != null) { resetLevelMethod.Invoke(collectorComponent, null); } else { zNetView.GetZDO().Set("Produced", 0); zNetView.GetZDO().Set("level", 0); } destination.AddItem(item.Clone(), currentLevel, destinationPos.x, destinationPos.y, false); } } private int GetCurrentLevel() { if (getTarLevelMethod != null) { return (int)getTarLevelMethod.Invoke(collectorComponent, null); } int num = zNetView.GetZDO().GetInt("Produced", 0); if (num == 0) { num = zNetView.GetZDO().GetInt("level", 0); } return num; } private GameObject GetClayPrefab() { if (clayItemField != null) { object? value = clayItemField.GetValue(collectorComponent); GameObject val = (GameObject)((value is GameObject) ? value : null); if (Object.op_Implicit((Object)(object)val)) { return val; } } GameObject itemPrefab = ObjectDB.instance.GetItemPrefab("BFP_Clay"); if (!Object.op_Implicit((Object)(object)itemPrefab)) { itemPrefab = ObjectDB.instance.GetItemPrefab("Clay"); } return itemPrefab; } private void RPC_RequestOwnership(long sender) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)zNetView == (Object)null) && zNetView.IsOwner()) { zNetView.GetZDO().SetOwner(sender); ZDOMan.instance.ForceSendZDO(sender, zNetView.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; } protected override void Awake() { base.Awake(); container = ((Component)this).GetComponent<Container>(); } private void Start() { if ((Object)(object)container != (Object)null && container.GetInventory() != null) { Inventory inventory = container.GetInventory(); inventory.m_onChanged = (Action)Delegate.Combine(inventory.m_onChanged, new Action(OnInventoryChanged)); } } private void OnInventoryChanged() { HopperHelper.NotifyChange(this); } public IEnumerable<ItemData> GetItems() { return container.GetInventory().GetItemInReverseOrder(); } public void AddItem(ItemData item, Inventory source, ZDOID sender, int amount = 1) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) ContainerHandler.AddItemToChest(container, item, source, new Vector2i(-1, -1), sender, amount); } public void RemoveItem(ItemData item, Inventory destination, Vector2i destinationPos, ZDOID sender, int amount = 1) { //IL_0008: 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) ContainerHandler.RemoveItemFromChest(container, item, destination, destinationPos, sender, amount, (ItemData)null); } public bool CanAddItem(ItemData item) { return container.GetInventory().CanAddItem(item, 1); } public bool InRange(Vector3 position) { return true; } } public class CookingStationTarget : NetworkPiece, IPushTarget, ITarget, IEqualityComparer<ITarget>, IPullTarget { private CookingStation cookingStation; private static FieldInfo cookableField; private static bool fieldDetected; public HopperPriority PushPriority { get; } = HopperPriority.SmelterFuelPush; public HopperPriority PullPriority { get; } = HopperPriority.HopperPull; public bool IsPickup { get; } protected override void Awake() { base.Awake(); cookingStation = ((Component)this).GetComponent<CookingStation>(); FieldInfo[] fields = typeof(CookingStation).GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { Plugin.Debug($"CookingStation field: {fieldInfo.FieldType} {fieldInfo.Name}"); } if (!fieldDetected) { cookableField = typeof(CookingStation).GetField("m_cookable", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (cookableField == null) { cookableField = typeof(CookingStation).GetField("m_conversion", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); } Plugin.Debug("Checking " + ((object)this).GetType().Name); Plugin.Debug("cookableField resolved to: " + (cookableField?.Name ?? "NULL")); fieldDetected = true; } } private void Start() { string[] array = new string[11] { "RPC_AddFuel", "RPC_AddItem", "RPC_RemoveDoneItem", "RPC_SetSlotVisual", "RPC_RequestOwn", "RPC_Pick", "RPC_RemoveItem", "RPC_ClearSlot", "RPC_SetCookingStation", "RPC_AddItemToSlot", "RPC_RemoveSlot" }; foreach (string text in array) { int stableHashCode = StringExtensionMethods.GetStableHashCode(text); if (cookingStation.m_nview.m_functions.ContainsKey(stableHashCode)) { Plugin.Debug($"MATCHED: '{text}' = {stableHashCode}"); } } foreach (int key in cookingStation.m_nview.m_functions.Keys) { Plugin.Debug($"Registered hash: {key}"); } } private bool IsFuelItem(ItemData item) { if ((Object)(object)cookingStation.m_fuelItem == (Object)null) { return false; } return cookingStation.m_fuelItem.m_itemData.m_shared.m_name == item.m_shared.m_name; } private bool IsCookableItem(ItemData item) { if (cookableField == null) { Plugin.Debug("cookableField is null — reflection failed at Awake"); return false; } if (!(cookableField.GetValue(cookingStation) is IEnumerable enumerable)) { Plugin.Debug("cookableList cast failed on field: " + cookableField.Name); return false; } foreach (object item2 in enumerable) { FieldInfo field = item2.GetType().GetField("m_from", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field == null) { continue; } object? value = field.GetValue(item2); ItemDrop val = (ItemDrop)((value is ItemDrop) ? value : null); if (!((Object)(object)val == (Object)null)) { Plugin.Debug("Comparing incoming '" + item.m_shared.m_name + "' vs conversion '" + val.m_itemData.m_shared.m_name + "'"); if (val.m_itemData.m_shared.m_name == item.m_shared.m_name) { return true; } } } return false; } private bool IsIncompatibleItem(ItemData item) { FieldInfo field = typeof(CookingStation).GetField("m_incompatibleItems", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field == null) { return false; } if (!(field.GetValue(cookingStation) is IEnumerable enumerable)) { return false; } foreach (object item2 in enumerable) { FieldInfo field2 = item2.GetType().GetField("m_item", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (!(field2 == null)) { object? value = field2.GetValue(item2); ItemDrop val = (ItemDrop)((value is ItemDrop) ? value : null); if ((Object)(object)val != (Object)null && val.m_itemData.m_shared.m_name == item.m_shared.m_name) { return true; } } } return false; } private bool CanAddFuel() { if ((Object)(object)cookingStation.m_fuelItem == (Object)null) { return false; } return cookingStation.GetFuel() < (float)cookingStation.m_maxFuel; } public bool CanAddItem(ItemData item) { if (IsIncompatibleItem(item)) { return false; } if ((Object)(object)cookingStation == (Object)null) { Plugin.Debug(((object)this).GetType().Name + " cookingStation is null"); return false; } if (IsFuelItem(item)) { Plugin.Debug(((object)this).GetType().Name + "'s " + item.m_shared.m_name + " is fuel"); return CanAddFuel(); } if (cookableField != null) { if (IsCookableItem(item)) { Plugin.Debug(((object)this).GetType().Name + "'s " + item.m_shared.m_name + " is cookable"); return cookingStation.GetFreeSlot() != -1; } Plugin.Debug(((object)this).GetType().Name + "'s " + item.m_shared.m_name + " is unknown"); return false; } Plugin.Debug("cookableField null, falling back to slot check for '" + item.m_shared.m_name + "'"); return cookingStation.GetFreeSlot() != -1; } public void AddItem(ItemData item, Inventory source, ZDOID sender, int amount = 1) { if (source.RemoveItem(item, amount)) { if (IsFuelItem(item)) { cookingStation.m_nview.InvokeRPC("RPC_AddFuel", Array.Empty<object>()); return; } cookingStation.m_nview.InvokeRPC("RPC_AddItem", new object[2] { ((Object)item.m_dropPrefab).name, item.m_cheated }); } } public bool InRange(Vector3 position) { return true; } public IEnumerable<ItemData> GetItems() { List<ItemData> list = new List<ItemData>(); if ((Object)(object)cookingStation == (Object)null) { return list; } int num = cookingStation.m_slots.Length; for (int i = 0; i < num; i++) { string text = cookingStation.m_nview.GetZDO().GetString($"slot{i}", ""); if (string.IsNullOrEmpty(text) || text == "0") { continue; } bool num2 = GetConversionForCooked(text) != null; ItemDrop overCookedItem = cookingStation.m_overCookedItem; bool flag = text == ((overCookedItem != null) ? ((Object)overCookedItem).name : null); if (!num2 && !flag) { continue; } GameObject prefab = ZNetScene.instance.GetPrefab(text); if (!((Object)(object)prefab == (Object)null)) { ItemDrop component = prefab.GetComponent<ItemDrop>(); if (!((Object)(object)component == (Object)null)) { list.Add(component.m_itemData.Clone()); } } } return list; } public void RemoveItem(ItemData item, Inventory destination, Vector2i destinationPos, ZDOID sender, int amount = 1) { //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) int num = cookingStation.m_slots.Length; ZDO zDO = cookingStation.m_nview.GetZDO(); for (int i = 0; i < num; i++) { string text = zDO.GetString($"slot{i}", ""); GameObject prefab = ZNetScene.instance.GetPrefab(text); if (!((Object)(object)prefab == (Object)null)) { ItemDrop component = prefab.GetComponent<ItemDrop>(); if (!((Object)(object)component == (Object)null) && !(component.m_itemData.m_shared.m_name != item.m_shared.m_name)) { cookingStation.m_nview.ClaimOwnership(); zDO.Set($"slot{i}", ""); zDO.Set($"slot{i}_ct", 0f); cookingStation.m_nview.InvokeRPC(ZNetView.Everybody, "RPC_SetSlotVisual", new object[2] { i, "" }); destination.AddItem(item.Clone(), 1, destinationPos.x, destinationPos.y, false); Plugin.Debug($"RemoveItem: cleared slot {i} ({text}) via ZDO write"); return; } } } Plugin.Debug("RemoveItem: no slot found for '" + item.m_shared.m_name + "'"); } private ItemConversion GetConversionForCooked(string cookedItemName) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown if (cookableField == null) { return null; } if (!(cookableField.GetValue(cookingStation) is IEnumerable enumerable)) { return null; } foreach (ItemConversion item in enumerable) { ItemConversion val = item; ItemDrop to = val.m_to; if (((to != null) ? ((Object)to).name : null) == cookedItemName) { return val; } } return null; } } public class FermenterTarget : NetworkPiece, IPullTarget, ITarget, IEqualityComparer<ITarget> { private Fermenter fermenter; private const string RequestOwnershipRPC = "VH_RequestOwnership"; public HopperPriority PullPriority { get; } = HopperPriority.BeehivePull; public bool IsPickup { get; } protected override void Awake() { base.Awake(); fermenter = ((Component)this).GetComponent<Fermenter>(); fermenter.m_nview.Register("VH_RequestOwnership", (Action<long>)RPC_RequestOwnership); } public bool InRange(Vector3 position) { return true; } public IEnumerable<ItemData> GetItems() { if ((int)fermenter.GetStatus() != 3) { yield break; } string text = fermenter.m_nview.GetZDO().GetString("item", ""); if (string.IsNullOrEmpty(text)) { yield break; } GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(text); if (Object.op_Implicit((Object)(object)itemPrefab)) { ItemDrop component = itemPrefab.GetComponent<ItemDrop>(); if (Object.op_Implicit((Object)(object)component)) { yield return component.m_itemData; } } } public void RemoveItem(ItemData item, Inventory destination, Vector2i destinationPos, ZDOID sender, int amount = 1) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Invalid comparison between Unknown and I4 //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) if (!fermenter.m_nview.IsOwner()) { fermenter.m_nview.InvokeRPC("VH_RequestOwnership", Array.Empty<object>()); } else if ((int)fermenter.GetStatus() == 3) { fermenter.m_nview.GetZDO().Set("status", 0); fermenter.m_nview.GetZDO().Set("item", ""); fermenter.m_nview.GetZDO().Set("startTime", 0L); int num = ((!item.m_shared.m_name.Contains("mead")) ? 1 : 6); destination.AddItem(item.Clone(), num, destinationPos.x, destinationPos.y, false); } } private void RPC_RequestOwnership(long sender) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) if (fermenter.m_nview.IsOwner()) { fermenter.m_nview.GetZDO().SetOwner(sender); ZDOMan.instance.ForceSendZDO(sender, fermenter.m_nview.GetZDO().m_uid); } } } public class FireplaceFuelTarget : NetworkPiece, IPushTarget, ITarget, IEqualityComparer<ITarget> { private Fireplace fireplace; public HopperPriority PushPriority { get; } = HopperPriority.SmelterFuelPush; protected override void Awake() { base.Awake(); fireplace = ((Component)this).GetComponent<Fireplace>(); } public bool CanAddItem(ItemData item) { bool num = Object.op_Implicit((Object)(object)fireplace.m_fuelItem) && fireplace.m_fuelItem.m_itemData.m_shared.m_name == item.m_shared.m_name; float num2 = fireplace.m_nview.GetZDO().GetFloat(ZDOVars.s_fuel, 0f); if (num) { return num2 < fireplace.m_maxFuel - 1f; } return false; } public void AddItem(ItemData item, Inventory source, ZDOID sender, int amount = 1) { float num = fireplace.m_nview.GetZDO().GetFloat(ZDOVars.s_fuel, 0f); int num2 = Mathf.FloorToInt(fireplace.m_maxFuel - num); int num3 = Mathf.Min(amount, num2); if (num3 > 0 && source.RemoveItem(item, num3)) { for (int i = 0; i < num3; i++) { fireplace.m_nview.InvokeRPC("RPC_AddFuel", Array.Empty<object>()); } } } public bool InRange(Vector3 position) { return true; } } public class ItemDropTarget : NetworkPiece, IPullTarget, ITarget, IEqualityComparer<ITarget> { private ItemDrop itemDrop; public HopperPriority PullPriority { get; } 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, int amount = 1) { //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) if (!itemDrop.m_nview.IsOwner()) { itemDrop.RequestOwn(); return; } int stack = itemDrop.m_itemData.m_stack; int num = Mathf.Min(stack, amount); if (num > 0) { if (num >= stack) { itemDrop.m_nview.Destroy(); } else { ItemData itemData = itemDrop.m_itemData; itemData.m_stack -= num; itemDrop.m_nview.GetZDO().Set(ZDOVars.s_stack, itemDrop.m_itemData.m_stack, false); } destination.AddItem(item.Clone(), num, destinationPos.x, destinationPos.y, false); } } 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) { if (Object.op_Implicit((Object)(object)smelter.m_fuelItem) && smelter.m_fuelItem.m_itemData.m_shared.m_name == item.m_shared.m_name) { return smelter.GetFuel() < (float)(smelter.m_maxFuel - 1); } return false; } public void AddItem(ItemData item, Inventory source, ZDOID sender, int amount = 1) { float fuel = smelter.GetFuel(); int num = Mathf.FloorToInt((float)smelter.m_maxFuel - fuel); int num2 = Mathf.Min(amount, num); if (num2 > 0 && source.RemoveItem(item, num2)) { for (int i = 0; i < num2; i++) { smelter.m_nview.InvokeRPC("RPC_AddFuel", Array.Empty<object>()); } } } public bool InRange(Vector3 position) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0011: 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) { if (smelter.IsItemAllowed(item)) { return smelter.GetQueueSize() < smelter.m_maxOre; } return false; } public void AddItem(ItemData item, Inventory source, ZDOID sender, int amount = 1) { int queueSize = smelter.GetQueueSize(); int num = smelter.m_maxOre - queueSize; int num2 = Mathf.Min(amount, num); if (num2 <= 0) { return; } string name = ((Object)item.m_dropPrefab).name; bool cheated = item.m_cheated; if (!source.RemoveItem(item, num2)) { Plugin.Debug($"SmelterOreTarget: failed to remove {num2}x '{item.m_shared.m_name}'"); return; } for (int i = 0; i < num2; i++) { smelter.m_nview.InvokeRPC("RPC_AddOre", new object[2] { name, cheated }); } } public bool InRange(Vector3 position) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0011: 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, int amount = 1) { int ammo = turret.GetAmmo(); int num = turret.m_maxAmmo - ammo; int num2 = Mathf.Min(amount, num); if (num2 > 0 && source.RemoveItem(item, num2)) { for (int i = 0; i < num2; i++) { 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 class WindmillTarget : NetworkPiece, IPullTarget, ITarget, IEqualityComparer<ITarget> { private Smelter smelter; public HopperPriority PullPriority { get; } = HopperPriority.HopperPull; public bool IsPickup { get; } protected override void Awake() { base.Awake(); smelter = ((Component)this).GetComponent<Smelter>(); FieldInfo[] fields = typeof(Smelter).GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { Plugin.Debug($"Smelter field: {fieldInfo.FieldType} {fieldInfo.Name}"); } } private void Start() { ZDO zDO = smelter.m_nview.GetZDO(); Plugin.Debug(string.Format("Windmill ZDO - SpawnAmount: {0}", zDO.GetInt("SpawnAmount", -999))); Plugin.Debug(string.Format("Windmill ZDO - queued: {0}", zDO.GetInt("queued", -999))); Plugin.Debug(string.Format("Windmill ZDO - items: {0}", zDO.GetInt("items", -999))); Plugin.Debug("Windmill ZDO - SpawnOre: " + zDO.GetString("SpawnOre", "NULL")); } public bool InRange(Vector3 position) { //IL_0021: 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) if (!Object.op_Implicit((Object)(object)smelter) || !Object.op_Implicit((Object)(object)smelter.m_emptyOreSwitch)) { return false; } return HopperHelper.IsInRange(position, ((Component)smelter.m_emptyOreSwitch).transform.position, 1.5f); } public IEnumerable<ItemData> GetItems() { List<ItemData> list = new List<ItemData>(); if (!Object.op_Implicit((Object)(object)smelter)) { return list; } int num = smelter.m_nview.GetZDO().GetInt("SpawnAmount", 0); if (num <= 0) { return list; } ItemConversion val = ((smelter.m_conversion.Count > 0) ? smelter.m_conversion[0] : null); if ((Object)(object)val?.m_to == (Object)null) { return list; } for (int i = 0; i < num; i++) { list.Add(val.m_to.m_itemData.Clone()); } return list; } public void RemoveItem(ItemData item, Inventory destination, Vector2i destinationPos, ZDOID sender, int amount = 1) { //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) ZDO zDO = smelter.m_nview.GetZDO(); int num = zDO.GetInt("SpawnAmount", 0); int num2 = Mathf.Min(num, amount); if (num2 > 0) { smelter.m_nview.ClaimOwnership(); zDO.Set("SpawnAmount", num - num2); destination.AddItem(item.Clone(), num2, destinationPos.x, destinationPos.y, false); Plugin.Debug($"RemoveItem: removed {num2} {item.m_shared.m_name} from Windmill via ZDO write"); } } } 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() { if ((Object)(object)base.NetView == (Object)null || !base.NetView.IsValid()) { return base.DefaultValue; } ZDO zDO = base.NetView.GetZDO(); if (zDO == null) { return base.DefaultValue; } return zDO.GetBool(base.KeyHash, base.DefaultValue); } protected override void SetValue(bool value) { if (!((Object)(object)base.NetView == (Object)null) && base.NetView.IsValid()) { ZDO zDO = base.NetView.GetZDO(); if (zDO != null) { zDO.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() { if ((Object)(object)base.NetView == (Object)null || !base.NetView.IsValid()) { return base.DefaultValue; } ZDO zDO = base.NetView.GetZDO(); if (zDO == null) { return base.DefaultValue; } return zDO.GetInt(base.KeyHash, base.DefaultValue); } protected override void SetValue(int value) { if (!((Object)(object)base.NetView == (Object)null) && base.NetView.IsValid()) { ZDO zDO = base.NetView.GetZDO(); if (zDO != null) { zDO.Set(base.KeyHash, value, false); } } } } } namespace ValheimHopper.Logic.Helper { public class BoxVisualizer : MonoBehaviour { private LineRenderer lineRenderer; private Vector3 boxCenter; private Vector3 boxSize; private ConfigEntry<bool> config; public void SetData(Vector3 center, Vector3 size, Color color, ConfigEntry<bool> configEntry) { //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_0008: 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_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0032: 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 boxCenter = center; boxSize = size; config = configEntry; if ((Object)(object)lineRenderer == (Object)null) { GameObject val = new GameObject("BoxVisualizerLine"); val.transform.SetParent(((Component)this).transform, false); lineRenderer = val.AddComponent<LineRenderer>(); lineRenderer.startWidth = 0.02f; lineRenderer.endWidth = 0.02f; lineRenderer.useWorldSpace = false; Shader val2 = Shader.Find("Sprites/Default"); if ((Object)(object)val2 == (Object)null) { val2 = Shader.Find("Standard"); } if ((Object)(object)val2 != (Object)null) { ((Renderer)lineRenderer).material = new Material(val2); } lineRenderer.positionCount = 16; } lineRenderer.startColor = color; lineRenderer.endColor = color; UpdateVisual(); } private void Update() { if (config != null && (Object)(object)lineRenderer != (Object)null) { bool value = config.Value; if (((Component)lineRenderer).gameObject.activeSelf != value) { ((Component)lineRenderer).gameObject.SetActive(value); } } } private void UpdateVisual() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0055: 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_0061: 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_0067: 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_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0074: 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_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0086: 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_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_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) //IL_00a7: 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_00af: 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_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: 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) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0100: 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_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010e: 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) //IL_011a: 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_012d: 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_0147: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0198: 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_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)lineRenderer == (Object)null)) { Vector3 val = boxSize / 2f; Vector3 val2 = boxCenter; Vector3 val3 = val2 + new Vector3(0f - val.x, 0f - val.y, 0f - val.z); Vector3 val4 = val2 + new Vector3(val.x, 0f - val.y, 0f - val.z); Vector3 val5 = val2 + new Vector3(val.x, val.y, 0f - val.z); Vector3 val6 = val2 + new Vector3(0f - val.x, val.y, 0f - val.z); Vector3 val7 = val2 + new Vector3(0f - val.x, 0f - val.y, val.z); Vector3 val8 = val2 + new Vector3(val.x, 0f - val.y, val.z); Vector3 val9 = val2 + new Vector3(val.x, val.y, val.z); Vector3 val10 = val2 + new Vector3(0f - val.x, val.y, val.z); lineRenderer.SetPosition(0, val3); lineRenderer.SetPosition(1, val4); lineRenderer.SetPosition(2, val5); lineRenderer.SetPosition(3, val6); lineRenderer.SetPosition(4, val3); lineRenderer.SetPosition(5, val7); lineRenderer.SetPosition(6, val8); lineRenderer.SetPosition(7, val4); lineRenderer.SetPosition(8, val8); lineRenderer.SetPosition(9, val9); lineRenderer.SetPosition(10, val5); lineRenderer.SetPosition(11, val9); lineRenderer.SetPosition(12, val10); lineRenderer.SetPosition(13, val6); lineRenderer.SetPosition(14, val10); lineRenderer.SetPosition(15, val7); } } } public static class HopperHelper { private static readonly Collider[] tempColliders = (Collider[])(object)new Collider[256]; private static int PieceMask { get; } = LayerMask.GetMask(new string[6] { "piece", "piece_nonsolid", "Default", "static_solid", "viewblock", "vehicle" }); private static int ItemMask { get; } = LayerMask.GetMask(new string[1] { "item" }); public static event Action<ITarget> OnTargetChanged; public static void NotifyChange(ITarget target) { HopperHelper.OnTargetChanged?.Invoke(target); } public static bool IsInRange(Vector3 position, Vector3 target, float range) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //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) return Vector3.SqrMagnitude(target - position) < range * range; } public static bool IsInRange(Vector3 position, Collider collider, float range) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0011: 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) { if (Object.op_Implicit((Object)(object)netView) && netView.IsValid()) { return netView.m_zdo != null; } return false; } public static int GetNetworkHashCode(ZNetView netView) { return ((object)Unsafe.As<ZDOID, ZDOID>(ref netView.m_zdo.m_uid)/*cast due to .constrained prefix*/).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_0006: 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_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_007b: 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); HashSet<int> hashSet = new HashSet<int>(); for (int i = 0; i < num; i++) { GameObject gameObject = ((Component)tempColliders[i]).gameObject; int instanceID = ((Object)gameObject).GetInstanceID(); if (hashSet.Contains(instanceID)) { continue; } hashSet.Add(instanceID); T[] componentsInParent = gameObject.GetComponentsInParent<T>(); for (int j = 0; j < componentsInParent.Length; j++) { T item = componentsInParent[j]; if (item.InRange(pos) && item.IsValid() && item.NetworkHashCode() != exclude.NetworkHashCode()) { list.Add(item); } } } if (list.Count == 0 && num > 0) { for (int k = 0; k < num; k++) { Plugin.Debug("[" + exclude.GetType().Name + "] Physical hit: " + ((Object)((Component)tempColliders[k]).gameObject).name + " (Layer: " + LayerMask.LayerToName(((Component)tempColliders[k]).gameObject.layer) + ")"); } } return (from t in list.OrderByDescending(orderBy) group t by t.NetworkHashCode() into t select t.First()).ToList(); } public static bool BoxIntersectsColliders(Vector3 boxPos, Vector3 boxSize, Quaternion boxRot, Collider[] targetColliders) { //IL_0051: 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_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006f: 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_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0073: 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) int num = 3; Vector3 val = default(Vector3); for (int i = 0; i < num; i++) { for (int j = 0; j < num; j++) { for (int k = 0; k < num; k++) { float num2 = ((float)i + 0.5f) / (float)num - 0.5f; float num3 = ((float)j + 0.5f) / (float)num - 0.5f; float num4 = ((float)k + 0.5f) / (float)num - 0.5f; ((Vector3)(ref val))..ctor(num2 * boxSize.x, num3 * boxSize.y, num4 * boxSize.z); if (IsPointInAnyCollider(boxPos + boxRot * val, targetColliders)) { return true; } } } } return false; } private static bool IsPointInAnyCollider(Vector3 point, Collider[] colliders) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) foreach (Collider collider in colliders) { if (IsPointInCollider(point, collider)) { return true; } } return false; } private static bool IsPointInCollider(Vector3 point, Collider collider) { //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: 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) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: 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_002e: 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_004c: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) BoxCollider val = (BoxCollider)(object)((collider is BoxCollider) ? collider : null); if (val != null) { Vector3 val2 = ((Component)val).transform.InverseTransformPoint(point) - val.center; if (Mathf.Abs(val2.x) <= val.size.x / 2f && Mathf.Abs(val2.y) <= val.size.y / 2f) { return Mathf.Abs(val2.z) <= val.size.z / 2f; } return false; } return collider.ClosestPoint(point) == point; } } 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 itemAt = target.GetItemAt(x, y); if (itemAt != null) { yield return itemAt; } } } } public static int GetRoomForItem(this Inventory target, ItemData itemData) { int num = 0; foreach (ItemData item in target.m_inventory) { if (item.m_shared.m_name == itemData.m_shared.m_name) { num += Math.Max(0, item.m_shared.m_maxStackSize - item.m_stack); } } return num + target.GetEmptySlots() * itemData.m_shared.m_maxStackSize; } } public static class ItemHelper { private static readonly Dictionary<string, Vector3> ItemOffsetCache = new Dictionary<string, Vector3>(); public static Vector3 GetVisualItemOffset(string name) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: 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_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_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_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: 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_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_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) 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_002e: 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; } for (int i = 0; i < points.Length; i++) { CreateSnappoint(points[i], prefab.transform); } } private static void CreateSnappoint(Vector3 pos, Transform parent) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_001d: 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_004b: 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_0062: 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); if (Plugin.ShowSnappointHighlights.Value) { GameObject val2 = new GameObject("_snappoint_visual"); val2.transform.parent = val.transform; val2.transform.localPosition = Vector3.zero; val2.AddComponent<SnappointVisualizer>(); } } 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; } int num = LayerMask.NameToLayer("piece_nonsolid"); if (num == -1) { Logger.LogError((object)"Layer 'piece_nonsolid' not found!"); return; } Transform[] componentsInChildren = prefab.GetComponentsInChildren<Transform>(); foreach (Transform val in componentsInChildren) { if (((Component)val).CompareTag("snappoint")) { ((Component)val).gameObject.layer = num; } } } } public class SnappointVisualizer : MonoBehaviour { private LineRenderer lineRenderer; private static Material lineMaterial; private void Awake() { //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_009d: 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_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: 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_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0132: 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_0142: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: 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_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Expected O, but got Unknown lineRenderer = ((Component)this).gameObject.AddComponent<LineRenderer>(); lineRenderer.startWidth = 0.02f; lineRenderer.endWidth = 0.02f; lineRenderer.useWorldSpace = false; lineRenderer.loop = true; lineRenderer.positionCount = 16; if ((Object)(object)lineMaterial == (Object)null) { lineMaterial = new Material(Shader.Find("Sprites/Default")); } ((Renderer)lineRenderer).material = lineMaterial; lineRenderer.startColor = Color.cyan; lineRenderer.endColor = Color.cyan; float num = 0.1f; Vector3[] array = (Vector3[])(object)new Vector3[16]; array[0] = new Vector3(0f - num, 0f - num, 0f - num); array[1] = new Vector3(num, 0f - num, 0f - num); array[2] = new Vector3(num, 0f - num, num); array[3] = new Vector3(0f - num, 0f - num, num); array[4] = array[0]; array[5] = new Vector3(0f - num, num, 0f - num); array[6] = new Vector3(num, num, 0f - num); array[7] = new Vector3(num, num, num); array[8] = new Vector3(0f - num, num, num); array[9] = array[5]; array[10] = new Vector3(0f - num, num, num); array[11] = new Vector3(0f - num, 0f - num, num); array[12] = new Vector3(num, 0f - num, num); array[13] = new Vector3(num, num, num); array[14] = new Vector