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 ArcadeDrawers v1.0.4
ArcadeDrawers.dll
Decompiled 2 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Security; using System.Security.Permissions; using System.Text; using ArcadeDrawers.Visuals; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.Rendering; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyCompany("Arcade")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("ArcadeDrawers")] [assembly: AssemblyTitle("ArcadeDrawers")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.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 ArcadeDrawers { [BepInPlugin("arcade.valheim.arcadedrawers", "ArcadeDrawers", "1.0.4")] [BepInProcess("valheim.exe")] [BepInProcess("valheim_server.exe")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class ArcadeDrawersPlugin : BaseUnityPlugin { public const string PluginGuid = "arcade.valheim.arcadedrawers"; public const string PluginName = "ArcadeDrawers"; public const string PluginVersion = "1.0.4"; private Harmony _harmony; private FileSystemWatcher _watcher; private volatile bool _configChanged; internal static ManualLogSource Log { get; private set; } private void Awake() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; ModConfig.Bind(((BaseUnityPlugin)this).Config); _harmony = new Harmony("arcade.valheim.arcadedrawers"); Type[] typesFromAssembly = AccessTools.GetTypesFromAssembly(typeof(ArcadeDrawersPlugin).Assembly); Type[] array = typesFromAssembly; foreach (Type type in array) { try { _harmony.CreateClassProcessor(type).Patch(); } catch (Exception ex) { Log.LogError((object)("Patch " + type.Name + " failed: " + ex.Message)); } } WatchConfigFile(); Log.LogInfo((object)"ArcadeDrawers 1.0.4 loaded."); } private void WatchConfigFile() { _watcher = new FileSystemWatcher(Path.GetDirectoryName(((BaseUnityPlugin)this).Config.ConfigFilePath), Path.GetFileName(((BaseUnityPlugin)this).Config.ConfigFilePath)) { NotifyFilter = (NotifyFilters.FileName | NotifyFilters.Size | NotifyFilters.LastWrite), IncludeSubdirectories = false }; _watcher.Changed += delegate { _configChanged = true; }; _watcher.Created += delegate { _configChanged = true; }; _watcher.Renamed += delegate { _configChanged = true; }; _watcher.EnableRaisingEvents = true; } private void Update() { if (!_configChanged) { return; } _configChanged = false; try { ((BaseUnityPlugin)this).Config.Reload(); ConfigSync.ServerConfigChanged(); ConfigSync.Reapply(); Log.LogInfo((object)(ConfigSync.Synced ? "Config reloaded: the server's settings still apply, only your personal ones (fronts, keys) changed." : "Config reloaded (drawer health changes on the next world load).")); DrawerPrefabs.TryFinalize(); DrawerNetwork.Invalidate(); } catch (IOException) { _configChanged = true; } } private void OnDestroy() { _watcher?.Dispose(); Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } } internal static class BuildCategory { internal const string JotunnGuid = "com.jotunn.jotunn"; private static PieceCategory? _custom; private static string _customName; internal static PieceCategory Get() { //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: 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_004a: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Expected I4, but got Unknown //IL_0116: Unknown result type (might be due to invalid IL or missing references) string text = (ModConfig.HammerTab.Value ?? string.Empty).Trim(); if (text.Length == 0) { return (PieceCategory)4; } if (_customName == text) { return (PieceCategory)(((??)_custom) ?? 4); } _customName = text; _custom = null; try { Type type = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly a) => a.GetName().Name == "Jotunn")?.GetType("Jotunn.Managers.PieceManager"); object obj = type?.GetProperty("Instance", BindingFlags.Static | BindingFlags.Public)?.GetValue(null); MethodInfo methodInfo = type?.GetMethod("AddPieceCategory", new Type[1] { typeof(string) }); if (obj == null || methodInfo == null) { ArcadeDrawersPlugin.Log.LogInfo((object)"Jotunn is not installed: the drawers are in the Furniture tab of the hammer."); return (PieceCategory)4; } _custom = (PieceCategory)methodInfo.Invoke(obj, new object[1] { text }); ArcadeDrawersPlugin.Log.LogInfo((object)$"Hammer tab '{text}' added through Jotunn (category {(int)_custom.Value})."); } catch (Exception ex) { ArcadeDrawersPlugin.Log.LogWarning((object)("Could not add the hammer tab '" + text + "' through Jotunn, using Furniture: " + ex.GetBaseException().Message)); } return (PieceCategory)(((??)_custom) ?? 4); } } internal class ConfigSync : MonoBehaviour { private const string RpcRequest = "arcade_drawers_config_request"; private const string RpcValues = "arcade_drawers_config"; private const string LegacyRpcRequest = "ymiron_itemdrawers_config_request"; private const string LegacyRpcValues = "ymiron_itemdrawers_config"; private const float RequestInterval = 10f; private const int MaxRequests = 6; private static ConfigSync s_instance; private ZPackage _serverValues; private float _requestTimer = 3f; private int _requests; private bool _registered; internal static bool Synced { get { if ((Object)(object)s_instance != (Object)null) { return s_instance._serverValues != null; } return false; } } private void Awake() { s_instance = this; } private void Update() { if (ZRoutedRpc.instance == null || (Object)(object)ZNet.instance == (Object)null) { return; } if (!_registered) { _registered = true; ZRoutedRpc.instance.Register("arcade_drawers_config_request", (Action<long>)RPC_Request); ZRoutedRpc.instance.Register<ZPackage>("arcade_drawers_config", (Action<long, ZPackage>)RPC_Values); ZRoutedRpc.instance.Register("ymiron_itemdrawers_config_request", (Action<long>)RPC_Request); ZRoutedRpc.instance.Register<ZPackage>("ymiron_itemdrawers_config", (Action<long, ZPackage>)RPC_Values); } if (ZNet.instance.IsServer() || _serverValues != null || _requests >= 6 || ZNet.instance.GetServerPeer() == null) { return; } _requestTimer -= Time.deltaTime; if (!(_requestTimer > 0f)) { _requestTimer = 10f; _requests++; ZRoutedRpc.instance.InvokeRoutedRPC("arcade_drawers_config_request", Array.Empty<object>()); if (_requests == 6) { ArcadeDrawersPlugin.Log.LogWarning((object)"The server does not send its ArcadeDrawers settings (no mod there?): each player uses their own config file."); } } } private static void RPC_Request(long sender) { if (!((Object)(object)ZNet.instance == (Object)null) && ZNet.instance.IsServer()) { ZRoutedRpc.instance.InvokeRoutedRPC(sender, "arcade_drawers_config", new object[1] { Pack() }); } } internal static void ServerConfigChanged() { if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer() && ZRoutedRpc.instance != null) { ZRoutedRpc.instance.InvokeRoutedRPC(0L, "arcade_drawers_config", new object[1] { Pack() }); } } private static ZPackage Pack() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown ZPackage val = new ZPackage(); List<ConfigDefinition> list = ModConfig.File.Keys.Where((ConfigDefinition d) => !ModConfig.IsLocalOnly(d)).ToList(); val.Write(list.Count); foreach (ConfigDefinition item in list) { val.Write(item.Section); val.Write(item.Key); val.Write(ModConfig.File[item].GetSerializedValue()); } return val; } private void RPC_Values(long sender, ZPackage package) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown if (!((Object)(object)ZNet.instance == (Object)null) && !ZNet.instance.IsServer()) { _serverValues = new ZPackage(package.GetArray()); int num = Apply(_serverValues); DrawerPrefabs.TryFinalize(); DrawerNetwork.Invalidate(); ArcadeDrawersPlugin.Log.LogInfo((object)$"ArcadeDrawers settings received from the server: {num} applied (your file is unchanged)."); } } internal static void Reapply() { if (Synced) { Apply(s_instance._serverValues); } } private static int Apply(ZPackage package) { package.SetPos(0); ConfigFile file = ModConfig.File; file.SaveOnConfigSet = false; int num = 0; try { int num2 = package.ReadInt(); for (int i = 0; i < num2; i++) { string section = package.ReadString(); string key = package.ReadString(); string text = package.ReadString(); ConfigDefinition val = ((IEnumerable<ConfigDefinition>)file.Keys).FirstOrDefault((Func<ConfigDefinition, bool>)((ConfigDefinition d) => d.Section == section && d.Key == key)); if (!(val == (ConfigDefinition)null) && !ModConfig.IsLocalOnly(val)) { ConfigEntryBase val2 = file[val]; if (val2.GetSerializedValue() != text) { val2.SetSerializedValue(text); } num++; } } } catch (Exception ex) { ArcadeDrawersPlugin.Log.LogWarning((object)("ArcadeDrawers settings from the server not fully applied: " + ex.Message)); } return num; } private void OnDestroy() { if ((Object)(object)s_instance == (Object)(object)this) { s_instance = null; } if (_serverValues != null) { _serverValues = null; ModConfig.File.SaveOnConfigSet = true; ModConfig.File.Reload(); DrawerPrefabs.TryFinalize(); DrawerNetwork.Invalidate(); ArcadeDrawersPlugin.Log.LogInfo((object)"Left the server: ArcadeDrawers uses your own settings again."); } } } [HarmonyPatch(typeof(CookingStation), "OnInteract")] internal static class CookingStation_OnInteract_Patch { private static bool Prefix(CookingStation __instance, Humanoid user, ref bool __result) { //IL_0221: Unknown result type (might be due to invalid IL or missing references) //IL_0227: Invalid comparison between Unknown and I4 //IL_0236: Unknown result type (might be due to invalid IL or missing references) if (!ModConfig.CraftFromDrawers.Value) { return true; } Player val = (Player)(object)((user is Player) ? user : null); ZNetView component = ((Component)__instance).GetComponent<ZNetView>(); if ((Object)(object)val == (Object)null || (Object)(object)val != (Object)(object)Player.m_localPlayer || (Object)(object)component == (Object)null || !component.IsValid()) { return true; } Traverse val2 = Traverse.Create((object)__instance); if (val2.Method("HaveDoneItem", Array.Empty<object>()).GetValue<bool>()) { return true; } if (val2.Method("IsStationFull", Array.Empty<object>()).GetValue<bool>()) { return true; } if (val2.Method("FindCookableItem", new object[1] { ((Humanoid)val).GetInventory() }).GetValue<ItemData>() != null) { return true; } ItemConversion val3 = null; foreach (ItemConversion item in __instance.m_conversion) { if ((Object)(object)item.m_from != (Object)null && val2.Method("IsItemAllowed", new object[1] { item.m_from.m_itemData }).GetValue<bool>()) { string name = item.m_from.m_itemData.m_shared.m_name; if (DrawerNetwork.CraftCount(name) > 0) { val3 = item; break; } } } if (val3 == null || (Object)(object)val3.m_from == (Object)null) { return true; } string name2 = val3.m_from.m_itemData.m_shared.m_name; string name3 = ((Object)((Component)val3.m_from).gameObject).name; if (DrawerNetwork.TakeForCraft(name2, 1) > 0) { if (!component.HasOwner()) { component.ClaimOwnership(); } component.InvokeRPC("RPC_AddItem", new object[2] { name3, false }); if ((int)__instance.m_skill > 0) { ((Character)Player.m_localPlayer).RaiseSkill(__instance.m_skill, 0.4f); } __result = true; return false; } return true; } } internal static class CraftContext { private static int _depth; internal static bool Active { get { if (_depth > 0) { return ModConfig.CraftFromDrawers.Value; } return false; } } internal static bool Enter(Player player) { if ((Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)Player.m_localPlayer) { return false; } _depth++; return true; } internal static void Exit(bool entered) { if (entered && _depth > 0) { _depth--; } } internal static void Without(Action action) { int depth = _depth; _depth = 0; try { action(); } finally { _depth = depth; } } internal static bool IsLocalInventory(Inventory inventory) { if ((Object)(object)Player.m_localPlayer != (Object)null) { return inventory == ((Humanoid)Player.m_localPlayer).GetInventory(); } return false; } } internal enum Delivery { Inventory, Return, DropHere, Discard } public class Drawer : MonoBehaviour { private enum Op { Add, Remove, Clear } public int m_tier = 1; public int m_layout; public Transform[] m_faces; public Vector2 m_cellSize = new Vector2(0.8f, 0.8f); public float m_scale = 1f; internal static readonly List<Drawer> All = new List<Drawer>(); private const string RpcChange = "arcade_drawer_change"; private const string RpcGive = "arcade_drawer_give"; private const string LegacyRpcChange = "ymiron_drawer_change"; private const string LegacyRpcGive = "ymiron_drawer_give"; private const int MaxSlots = 4; private static readonly int[] ItemKeys = (from i in Enumerable.Range(0, 4) select StringExtensionMethods.GetStableHashCode($"arcade_drawer_item{i}")).ToArray(); private static readonly int[] CountKeys = (from i in Enumerable.Range(0, 4) select StringExtensionMethods.GetStableHashCode($"arcade_drawer_count{i}")).ToArray(); private static readonly int[] DataKeys = (from i in Enumerable.Range(0, 4) select StringExtensionMethods.GetStableHashCode($"arcade_drawer_data{i}")).ToArray(); private static readonly int[] LegacyItemKeys = (from i in Enumerable.Range(0, 4) select StringExtensionMethods.GetStableHashCode($"ymiron_drawer_item{i}")).ToArray(); private static readonly int[] LegacyCountKeys = (from i in Enumerable.Range(0, 4) select StringExtensionMethods.GetStableHashCode($"ymiron_drawer_count{i}")).ToArray(); private static readonly int[] LegacyDataKeys = (from i in Enumerable.Range(0, 4) select StringExtensionMethods.GetStableHashCode($"ymiron_drawer_data{i}")).ToArray(); private ZNetView _nview; private Piece _piece; private DrawerFace[] _faceViews; private uint _shownRevision = uint.MaxValue; private int _shownStacks = -1; private int _frontVersion; internal TierDef Tier => TierDef.All[Mathf.Clamp(m_tier - 1, 0, TierDef.All.Length - 1)]; internal LayoutDef Layout => LayoutDef.All[Mathf.Clamp(m_layout, 0, LayoutDef.All.Length - 1)]; internal int Slots => Layout.Slots; internal bool IsValid { get { if ((Object)(object)_nview != (Object)null) { return _nview.IsValid(); } return false; } } internal string DisplayName { get { if (!((Object)(object)_piece != (Object)null)) { return Layout.DisplayName(Tier); } return _piece.m_name; } } internal int StacksPerSlot => Mathf.Max(1, ModConfig.Tier(Tier).Stacks.Value / Slots); private void Awake() { _nview = ((Component)this).GetComponent<ZNetView>(); _piece = ((Component)this).GetComponent<Piece>(); if (!((Object)(object)_nview == (Object)null) && _nview.GetZDO() != null) { All.Add(this); _nview.Register<ZPackage>("arcade_drawer_change", (Action<long, ZPackage>)RPC_Change); _nview.Register<ZPackage>("arcade_drawer_give", (Action<long, ZPackage>)RPC_Give); _nview.Register<ZPackage>("ymiron_drawer_change", (Action<long, ZPackage>)RPC_Change); _nview.Register<ZPackage>("ymiron_drawer_give", (Action<long, ZPackage>)RPC_Give); WearNTear component = ((Component)this).GetComponent<WearNTear>(); if ((Object)(object)component != (Object)null) { component.m_onDestroyed = (Action)Delegate.Combine(component.m_onDestroyed, new Action(OnDestroyed)); } BuildFaces(); } } private void OnDestroy() { All.Remove(this); } private void Update() { if (!IsValid || _faceViews == null) { return; } if (_frontVersion != ModConfig.FrontVersion) { DrawerFace[] faceViews = _faceViews; for (int i = 0; i < faceViews.Length; i++) { faceViews[i]?.Destroy(); } BuildFaces(); _shownRevision = uint.MaxValue; } uint dataRevision = _nview.GetZDO().DataRevision; int stacksPerSlot = StacksPerSlot; if (dataRevision != _shownRevision || stacksPerSlot != _shownStacks) { _shownRevision = dataRevision; _shownStacks = stacksPerSlot; for (int j = 0; j < _faceViews.Length; j++) { ItemDrop val = ItemInfo.Get(GetItem(j)); _faceViews[j]?.Show(val, GetCount(j), ((Object)(object)val != (Object)null) ? CapacityFor(val) : 0); } } } internal static void Resize(GameObject root, float size) { //IL_001f: 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_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown //IL_006e: 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_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0091: 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_00c7: Unknown result type (might be due to invalid IL or missing references) Transform val = root.transform.Find("model"); if ((Object)(object)val != (Object)null) { val.localScale = Vector3.one * size; } foreach (Transform item in root.transform) { Transform val2 = item; if (!(((Object)val2).name != "_snappoint")) { Vector3 localPosition = val2.localPosition; val2.localPosition = new Vector3(Mathf.Sign(localPosition.x) * 1f * 0.5f * size, (localPosition.y > 0.001f) ? (1f * size) : 0f, Mathf.Sign(localPosition.z) * 0.5f * 0.5f * size); } } Drawer component = root.GetComponent<Drawer>(); if ((Object)(object)component != (Object)null) { component.m_scale = size; component._frontVersion = int.MinValue; } } internal string GetItem(int slot) { if (!IsValid || slot < 0 || slot >= Slots) { return string.Empty; } string text = _nview.GetZDO().GetString(ItemKeys[slot], ""); if (string.IsNullOrEmpty(text)) { text = _nview.GetZDO().GetString(LegacyItemKeys[slot], ""); } return text ?? string.Empty; } internal string GetData(int slot) { if (!IsValid || slot < 0 || slot >= Slots) { return string.Empty; } string text = _nview.GetZDO().GetString(DataKeys[slot], ""); if (string.IsNullOrEmpty(text)) { text = _nview.GetZDO().GetString(LegacyDataKeys[slot], ""); } return text ?? string.Empty; } internal int GetCount(int slot) { if (!IsValid || slot < 0 || slot >= Slots) { return 0; } int num = _nview.GetZDO().GetInt(CountKeys[slot], -1); if (num < 0) { num = _nview.GetZDO().GetInt(LegacyCountKeys[slot], 0); } return num; } internal bool IsFree(int slot) { return string.IsNullOrEmpty(GetItem(slot)); } internal bool Holds(int slot, string prefabName, string data) { if (IsFree(slot) || string.IsNullOrEmpty(prefabName)) { return false; } string item = GetItem(slot); if (string.IsNullOrEmpty(item)) { return false; } string text = ItemInfo.CleanPrefabName(prefabName); string text2 = ItemInfo.CleanPrefabName(item); if (string.Equals(text2, text, StringComparison.OrdinalIgnoreCase)) { return true; } string text3 = ItemInfo.SharedName(text2); string text4 = ItemInfo.SharedName(text); if (!string.IsNullOrEmpty(text3) && !string.IsNullOrEmpty(text4) && text3 == text4) { return true; } return false; } internal int CapacityFor(ItemDrop drop) { return StacksPerSlot * drop.m_itemData.m_shared.m_maxStackSize; } internal int RoomFor(int slot, string prefabName, string data) { string prefabName2 = ItemInfo.CleanPrefabName(prefabName); ItemDrop val = ItemInfo.Get(prefabName2); if ((Object)(object)val == (Object)null) { return 0; } if (IsFree(slot)) { return CapacityFor(val); } if (!Holds(slot, prefabName2, data)) { return 0; } return Mathf.Max(0, CapacityFor(val) - GetCount(slot)); } internal int RequestAdd(int slot, string prefabName, string data, int amount, Delivery overflow) { int num = Mathf.Min(amount, RoomFor(slot, prefabName, data)); if (num > 0) { Send(Op.Add, slot, prefabName, data, num, overflow); } return num; } internal int RequestRemove(int slot, int amount, Delivery delivery) { int num = Mathf.Min(amount, GetCount(slot)); if (num > 0) { Send(Op.Remove, slot, GetItem(slot), GetData(slot), num, delivery); } return num; } internal void RequestClear(int slot) { Send(Op.Clear, slot, string.Empty, string.Empty, 0, Delivery.Discard); } private void Send(Op op, int slot, string prefabName, string data, int amount, Delivery delivery) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown ZPackage val = new ZPackage(); val.Write((int)op); val.Write(slot); val.Write(prefabName ?? string.Empty); val.Write(data ?? string.Empty); val.Write(amount); val.Write((int)delivery); if (!_nview.IsOwner()) { long owner = _nview.GetZDO().GetOwner(); if (owner != 0L && ModNetwork.HasMod(owner)) { _nview.InvokeRPC(owner, "arcade_drawer_change", new object[1] { val }); return; } _nview.ClaimOwnership(); } val.SetPos(0); Apply(ZDOMan.GetSessionID(), val); } private void RPC_Change(long sender, ZPackage pkg) { Apply(sender, pkg); } private void Apply(long sender, ZPackage pkg) { if (!IsValid) { return; } Op op = (Op)pkg.ReadInt(); int num = pkg.ReadInt(); string prefabName = pkg.ReadString(); string data = pkg.ReadString(); int num2 = pkg.ReadInt(); Delivery delivery = (Delivery)pkg.ReadInt(); if (num < 0 || num >= Slots) { return; } if (!_nview.IsOwner()) { _nview.ClaimOwnership(); } switch (op) { case Op.Add: { int num3 = Add(num, prefabName, data, num2); if (num3 < num2) { Reply(sender, prefabName, data, num2 - num3, delivery); } break; } case Op.Remove: { int num4 = (Holds(num, prefabName, data) ? Remove(num, num2) : 0); if (num4 > 0 && delivery != Delivery.Discard) { Reply(sender, prefabName, data, num4, delivery); } break; } case Op.Clear: if (GetCount(num) <= 0) { Write(num, string.Empty, string.Empty, 0); } break; } } private int Add(int slot, string prefabName, string data, int amount) { string text = ItemInfo.CleanPrefabName(prefabName); int num = Mathf.Min(amount, RoomFor(slot, text, data)); if (num <= 0) { return 0; } int num2 = ((!IsFree(slot)) ? GetCount(slot) : 0); string data2 = ((!IsFree(slot) && string.IsNullOrEmpty(GetData(slot))) ? string.Empty : (data ?? string.Empty)); string item = GetItem(slot); string prefabName2 = ((!string.IsNullOrEmpty(item)) ? item : text); Write(slot, prefabName2, data2, num2 + num); return num; } private int Remove(int slot, int amount) { int count = GetCount(slot); int num = Mathf.Min(amount, count); if (num <= 0) { return 0; } Write(slot, GetItem(slot), GetData(slot), count - num); return num; } private void Write(int slot, string prefabName, string data, int count) { ZDO zDO = _nview.GetZDO(); string text = ItemInfo.CleanPrefabName(prefabName); string text2 = (string.IsNullOrEmpty(prefabName) ? string.Empty : (data ?? string.Empty)); int num = Mathf.Max(0, count); zDO.Set(ItemKeys[slot], text); zDO.Set(DataKeys[slot], text2); zDO.Set(CountKeys[slot], num, false); zDO.Set(LegacyItemKeys[slot], text); zDO.Set(LegacyDataKeys[slot], text2); zDO.Set(LegacyCountKeys[slot], num, false); DrawerNetwork.Invalidate(); } private void Reply(long target, string prefabName, string data, int amount, Delivery delivery) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown ZPackage val = new ZPackage(); val.Write(prefabName); val.Write(data); val.Write(amount); val.Write((int)delivery); if (target == ZDOMan.GetSessionID()) { val.SetPos(0); Receive(val); } else { _nview.InvokeRPC(target, "arcade_drawer_give", new object[1] { val }); } } private void RPC_Give(long sender, ZPackage pkg) { Receive(pkg); } private void Receive(ZPackage pkg) { //IL_0068: 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_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_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0098: 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_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) ItemDrop val = ItemInfo.Get(pkg.ReadString()); string data = pkg.ReadString(); int num = pkg.ReadInt(); Delivery delivery = (Delivery)pkg.ReadInt(); if ((Object)(object)val == (Object)null || num <= 0 || delivery == Delivery.Discard) { return; } Player localPlayer = Player.m_localPlayer; if (delivery == Delivery.DropHere || (Object)(object)localPlayer == (Object)null) { DropStacks(val, data, num, ((Component)this).transform.position + ((Component)this).transform.forward * (0.4f * m_scale) + Vector3.up * 0.3f); return; } Inventory inventory = ((Humanoid)localPlayer).GetInventory(); int num2 = Mathf.Min(num, ItemInfo.Room(inventory, val)); ItemInfo.Give(inventory, val, num2, data); if (num > num2) { DropStacks(val, data, num - num2, ((Component)localPlayer).transform.position + Vector3.up); } string name = val.m_itemData.m_shared.m_name; if (delivery == Delivery.Inventory) { ((Character)localPlayer).Message((MessageType)1, "$msg_added " + name, num, val.m_itemData.GetIcon(), false); return; } ((Character)localPlayer).Message((MessageType)1, Loc.T("MsgNoRoomDrawerBack", name), num, val.m_itemData.GetIcon(), false); } private static void DropStacks(ItemDrop drop, string data, int amount, Vector3 position) { //IL_002b: 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_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) int maxStackSize = drop.m_itemData.m_shared.m_maxStackSize; while (amount > 0) { int num = Mathf.Min(amount, maxStackSize); amount -= num; ItemDrop.DropItem(ItemInfo.NewStack(drop, num, data), num, position + Random.insideUnitSphere * 0.2f, Quaternion.Euler(0f, Random.Range(0f, 360f), 0f)); } } internal string GetHoverText(int slot) { //IL_00b7: Unknown result type (might be due to invalid IL or missing references) if (!IsValid) { return string.Empty; } StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append(DisplayName); ItemDrop val = ItemInfo.Get(GetItem(slot)); if ((Object)(object)val == (Object)null) { stringBuilder.Append("\n<color=#a0a0a0>" + Loc.T("HoverEmpty") + "</color>"); stringBuilder.Append("\n" + Loc.T("HoverStoreHotbar")); return ItemInfo.Localize(stringBuilder.ToString()); } int count = GetCount(slot); int num = CapacityFor(val); string text = KeyName(ModConfig.TakeOneKey.Value); stringBuilder.Append($"\n<color=orange>{val.m_itemData.m_shared.m_name}</color> {count} / {num}"); if (count > 0) { stringBuilder.Append("\n" + Loc.T("HoverTakeStack")); stringBuilder.Append("\n" + Loc.T("HoverTakeOne", text)); } stringBuilder.Append("\n" + Loc.T("HoverStoreAll")); if (count <= 0) { stringBuilder.Append("\n" + Loc.T("HoverFree", text)); } return ItemInfo.Localize(stringBuilder.ToString()); } internal bool Interact(int slot, Humanoid user, bool hold, bool alt) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown //IL_0030: 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_00b0: Unknown result type (might be due to invalid IL or missing references) if (!hold && IsValid) { Player val = (Player)((user is Player) ? user : null); if (val != null && PrivateArea.CheckAccess(((Component)this).transform.position, 0f, true, false)) { if (IsFree(slot)) { ((Character)val).Message((MessageType)2, Loc.T("MsgEmptyChoose"), 0, (Sprite)null, false); return false; } if (alt) { return StoreFromInventory(slot, val, GetItem(slot), GetData(slot)); } bool flag = (int)ModConfig.TakeOneKey.Value != 0 && Input.GetKey(ModConfig.TakeOneKey.Value); if (flag && GetCount(slot) <= 0) { RequestClear(slot); ((Character)val).Message((MessageType)2, Loc.T("MsgDrawerFreed"), 0, (Sprite)null, false); return true; } return Take(slot, val, flag ? 1 : (-1)); } } return false; } internal bool UseItem(int slot, Humanoid user, ItemData item) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown //IL_002d: Unknown result type (might be due to invalid IL or missing references) if (IsValid) { Player val = (Player)((user is Player) ? user : null); if (val != null && item != null && PrivateArea.CheckAccess(((Component)this).transform.position, 0f, true, false)) { if (!ItemInfo.CanStore(item)) { ((Character)val).Message((MessageType)2, item.m_equipped ? Loc.T("MsgUnequipFirst") : Loc.T("MsgOnlyStackable"), 0, (Sprite)null, false); return true; } string prefabName = ItemInfo.GetPrefabName(item); string data = ItemInfo.DataKey(item); if (!IsFree(slot) && !Holds(slot, prefabName, data)) { ((Character)val).Message((MessageType)2, Loc.T("MsgDrawerHoldsElse"), 0, (Sprite)null, false); return true; } StoreFromInventory(slot, val, prefabName, data); return true; } } return false; } private bool Take(int slot, Player player, int amount) { ItemDrop val = ItemInfo.Get(GetItem(slot)); if ((Object)(object)val == (Object)null) { return false; } if (GetCount(slot) <= 0) { ((Character)player).Message((MessageType)2, Loc.T("MsgNoLeft", val.m_itemData.m_shared.m_name), 0, (Sprite)null, false); return false; } if (amount < 0) { amount = val.m_itemData.m_shared.m_maxStackSize; } int num = Mathf.Min(amount, ItemInfo.Room(((Humanoid)player).GetInventory(), val)); if (num <= 0) { ((Character)player).Message((MessageType)2, "$inventory_full", 0, (Sprite)null, false); return false; } return RequestRemove(slot, num, Delivery.Inventory) > 0; } internal bool StoreFromInventory(int slot, Player player, string prefabName, string data) { string prefabName2 = ItemInfo.CleanPrefabName(prefabName); ItemDrop val = ItemInfo.Get(prefabName2); if ((Object)(object)val == (Object)null) { return false; } Inventory inventory = ((Humanoid)player).GetInventory(); List<ItemData> list = ItemInfo.Matching(inventory, prefabName2, data); if (list.Count == 0) { ((Character)player).Message((MessageType)2, Loc.T("MsgNotInInventory", val.m_itemData.m_shared.m_name), 0, (Sprite)null, false); return false; } int num = RoomFor(slot, prefabName2, data); if (num <= 0) { ((Character)player).Message((MessageType)2, Loc.T("MsgDrawerFull"), 0, (Sprite)null, false); return false; } int num2 = 0; foreach (ItemData item in list) { int num3 = Mathf.Min(num - num2, item.m_stack); if (num3 <= 0) { break; } inventory.RemoveItem(item, num3); num2 += num3; } RequestAdd(slot, prefabName2, data, num2, Delivery.Return); ((Character)player).Message((MessageType)1, Loc.T("MsgStored", val.m_itemData.m_shared.m_name), num2, val.m_itemData.GetIcon(), false); return true; } private unsafe static string KeyName(KeyCode key) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Expected I4, but got Unknown switch ((int)key) { case 305: case 306: return "Ctrl"; case 307: case 308: return "Alt"; case 303: case 304: return "Shift"; default: return ((object)(*(KeyCode*)(&key))/*cast due to .constrained prefix*/).ToString(); } } private void OnDestroyed() { //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: 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_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_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_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_015b: 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_0195: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) if (!IsValid || !_nview.IsOwner()) { return; } GameObject val = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.GetPrefab("CargoCrate") : null); Inventory val2 = null; for (int i = 0; i < Slots; i++) { ItemDrop val3 = ItemInfo.Get(GetItem(i)); int num = GetCount(i); string data = GetData(i); if ((Object)(object)val3 == (Object)null || num <= 0) { continue; } int maxStackSize = val3.m_itemData.m_shared.m_maxStackSize; while (num > 0) { int num2 = Mathf.Min(num, maxStackSize); num -= num2; ItemData val4 = ItemInfo.NewStack(val3, num2, data); Vector3 val5 = ((Component)this).transform.position + Vector3.up * 0.6f * m_scale + Random.insideUnitSphere * 0.4f; if ((Object)(object)val == (Object)null) { ItemDrop.DropItem(val4, num2, val5, Quaternion.Euler(0f, Random.Range(0f, 360f), 0f)); } else if (val2 == null || !val2.AddItem(val4)) { Container component = Object.Instantiate<GameObject>(val, val5, Random.rotation).GetComponent<Container>(); val2 = ((component != null) ? component.GetInventory() : null); if (val2 == null || !val2.AddItem(val4)) { ItemDrop.DropItem(val4, num2, val5, Quaternion.identity); } } } Write(i, string.Empty, string.Empty, 0); } } private void BuildFaces() { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Invalid comparison between Unknown and I4 //IL_0061: Unknown result type (might be due to invalid IL or missing references) if (m_faces == null || (int)SystemInfo.graphicsDeviceType == 4) { return; } _frontVersion = ModConfig.FrontVersion; _faceViews = new DrawerFace[m_faces.Length]; for (int i = 0; i < m_faces.Length; i++) { if ((Object)(object)m_faces[i] != (Object)null) { _faceViews[i] = DrawerFace.Create(m_faces[i], m_cellSize, m_scale); } } } } internal sealed class DrawerFace { private static Sprite _white; private static Material _outlined; private static TMP_FontAsset _outlinedFor; private static bool _loggedError; private GameObject _root; private SpriteRenderer _icon; private TextMeshPro _count; private SpriteRenderer _label; private SpriteRenderer _barBack; private SpriteRenderer _barFill; private float _iconSize; private float _barWidth; private float _barHeight; private static Sprite White { get { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_white == (Object)null) { Texture2D val = new Texture2D(4, 4, (TextureFormat)4, false); val.SetPixels(Enumerable.Repeat<Color>(Color.white, 16).ToArray()); val.Apply(); _white = Sprite.Create(val, new Rect(0f, 0f, 4f, 4f), new Vector2(0f, 0.5f), 4f); } return _white; } } private static Material Outlined(TMP_FontAsset font) { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Expected O, but got Unknown //IL_00d6: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)font == (Object)null || (Object)(object)((TMP_Asset)font).material == (Object)null) { return null; } if ((Object)(object)_outlined == (Object)null || (Object)(object)_outlinedFor != (Object)(object)font) { _outlinedFor = font; _outlined = new Material(((TMP_Asset)font).material) { name = "arcade_count_outlined" }; _outlined.EnableKeyword(ShaderUtilities.Keyword_Outline); SetIfPresent(_outlined, ShaderUtilities.ID_OutlineWidth, 0.28f); SetIfPresent(_outlined, ShaderUtilities.ID_FaceDilate, 0.15f); if (_outlined.HasProperty(ShaderUtilities.ID_OutlineColor)) { _outlined.SetColor(ShaderUtilities.ID_OutlineColor, new Color(0.05f, 0.03f, 0.02f, 1f)); } } return _outlined; } private static void SetIfPresent(Material material, int property, float value) { if (material.HasProperty(property)) { material.SetFloat(property, value); } } internal static DrawerFace Create(Transform anchor, Vector2 cell, float scale) { //IL_0019: 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_002b: Expected O, but got Unknown //IL_0059: 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_005f: 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_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: 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_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_0280: Unknown result type (might be due to invalid IL or missing references) //IL_02c6: Unknown result type (might be due to invalid IL or missing references) //IL_0349: Unknown result type (might be due to invalid IL or missing references) //IL_034e: Unknown result type (might be due to invalid IL or missing references) //IL_034f: Unknown result type (might be due to invalid IL or missing references) //IL_037b: Unknown result type (might be due to invalid IL or missing references) //IL_039e: Unknown result type (might be due to invalid IL or missing references) //IL_03a3: Unknown result type (might be due to invalid IL or missing references) //IL_03a4: Unknown result type (might be due to invalid IL or missing references) DrawerFace drawerFace = new DrawerFace(); int layer = ((Component)anchor).gameObject.layer; drawerFace._root = new GameObject("front") { layer = layer }; drawerFace._root.transform.SetParent(anchor, false); Transform transform = drawerFace._root.transform; Quaternion rotation = Quaternion.Euler(0f, 180f, 0f); float x = cell.x; float y = cell.y; float num = ModConfig.FrontDistance.Value / 100f / Mathf.Max(scale, 0.1f); float num2 = Mathf.Max(0.002f, num - 0.004f); float num3 = num; float num4 = num + 0.002f; drawerFace._iconSize = Mathf.Min(x, y) * ModConfig.PictureSize.Value; drawerFace._icon = Child(transform, "icon", layer, new Vector3(0f, y * ModConfig.PictureY.Value, num3), rotation).AddComponent<SpriteRenderer>(); ((Renderer)drawerFace._icon).sortingOrder = 1; float value = ModConfig.PictureBrightness.Value; drawerFace._icon.color = new Color(value, value, value, 1f); ((Renderer)drawerFace._icon).enabled = false; float num5 = x * ModConfig.LabelWidth.Value; float num6 = y * ModConfig.LabelHeight.Value; float num7 = y * ModConfig.LabelY.Value; drawerFace._label = Rect(transform, "label", layer, new Vector3(num5 * 0.5f, num7, num2), rotation, new Color(0.06f, 0.045f, 0.035f, ModConfig.LabelOpacity.Value), 0); ((Component)drawerFace._label).transform.localScale = new Vector3(num5, num6, 1f); ((Renderer)drawerFace._label).enabled = false; GameObject val = Child(transform, "count", layer, new Vector3(0f, num7, num4), rotation); val.SetActive(false); TextMeshPro val2 = val.AddComponent<TextMeshPro>(); TMP_FontAsset numbers = Fonts.Numbers; if ((Object)(object)numbers != (Object)null) { ((TMP_Text)val2).font = numbers; } val.SetActive(true); if ((Object)(object)numbers != (Object)null) { Material val3 = Outlined(numbers); if ((Object)(object)val3 != (Object)null) { ((TMP_Text)val2).fontSharedMaterial = val3; } } ((TMP_Text)val2).rectTransform.sizeDelta = new Vector2(num5 * 0.92f, num6 * ModConfig.NumberSize.Value); ((TMP_Text)val2).enableAutoSizing = true; ((TMP_Text)val2).fontSizeMin = 0.05f; ((TMP_Text)val2).fontSizeMax = 6f; ((TMP_Text)val2).alignment = (TextAlignmentOptions)514; ((TMP_Text)val2).fontStyle = (FontStyles)1; ((Graphic)val2).color = Palette.CountText; ((TMP_Text)val2).textWrappingMode = (TextWrappingModes)0; ((TMP_Text)val2).text = string.Empty; val2.renderer.sortingOrder = 3; drawerFace._count = val2; drawerFace._barWidth = num5; drawerFace._barHeight = Mathf.Max(0.008f, y * ModConfig.BarHeight.Value); float num8 = y * ModConfig.BarY.Value; drawerFace._barBack = Rect(transform, "bar_back", layer, new Vector3(drawerFace._barWidth * 0.5f, num8, num2), rotation, Palette.BarBack, 1); ((Component)drawerFace._barBack).transform.localScale = new Vector3(drawerFace._barWidth, drawerFace._barHeight, 1f); drawerFace._barFill = Rect(transform, "bar_fill", layer, new Vector3(drawerFace._barWidth * 0.5f, num8, num4), rotation, Palette.BarFill, 2); ((Renderer)drawerFace._barBack).enabled = false; ((Renderer)drawerFace._barFill).enabled = false; return drawerFace; } internal void Destroy() { if ((Object)(object)_root != (Object)null) { Object.Destroy((Object)(object)_root); } _root = null; } internal void Show(ItemDrop drop, int count, int capacity) { //IL_012c: 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_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_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: 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_00dc: 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_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)drop == (Object)null) { ((Renderer)_icon).enabled = false; ((Renderer)_label).enabled = false; ((TMP_Text)_count).text = string.Empty; ((Renderer)_barBack).enabled = false; ((Renderer)_barFill).enabled = false; return; } Sprite icon = drop.m_itemData.GetIcon(); if ((Object)(object)_icon.sprite != (Object)(object)icon) { _icon.sprite = icon; float num; if (!((Object)(object)icon != (Object)null)) { num = 1f; } else { Bounds bounds = icon.bounds; float x = ((Bounds)(ref bounds)).size.x; bounds = icon.bounds; num = Mathf.Max(x, ((Bounds)(ref bounds)).size.y); } float num2 = num; float num3 = num2; ((Component)_icon).transform.localScale = Vector3.one * (_iconSize / Mathf.Max(num3, 0.0001f)); } float value = ModConfig.PictureBrightness.Value; _icon.color = ((count > 0) ? new Color(value, value, value, 1f) : new Color(value, value, value, 0.35f)); ((Renderer)_icon).enabled = (Object)(object)icon != (Object)null; ((Renderer)_label).enabled = ModConfig.LabelOpacity.Value > 0f; ((TMP_Text)_count).text = ItemInfo.ShortCount(count); bool value2 = ModConfig.ShowBar.Value; float num4 = ((capacity > 0) ? Mathf.Clamp01((float)count / (float)capacity) : 0f); ((Renderer)_barBack).enabled = value2; ((Renderer)_barFill).enabled = value2 && num4 > 0f; _barFill.color = ((num4 >= 1f) ? Palette.BarFull : Palette.BarFill); ((Component)_barFill).transform.localScale = new Vector3(_barWidth * num4, _barHeight, 1f); } catch (Exception arg) { if (!_loggedError) { _loggedError = true; ArcadeDrawersPlugin.Log.LogError((object)string.Format("Drawer front for '{0}' x{1} failed: {2}", ((Object)(object)drop != (Object)null) ? ((Object)drop).name : "?", count, arg)); } } } private static GameObject Child(Transform parent, string name, int layer, Vector3 position, Quaternion rotation) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name); val.layer = layer; val.transform.SetParent(parent, false); val.transform.localPosition = position; val.transform.localRotation = rotation; return val; } private static SpriteRenderer Rect(Transform parent, string name, int layer, Vector3 position, Quaternion rotation, Color color, int order) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0005: 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) SpriteRenderer val = Child(parent, name, layer, position, rotation).AddComponent<SpriteRenderer>(); val.sprite = White; val.color = color; ((Renderer)val).sortingOrder = order; return val; } } internal sealed class DrawerKind { internal TierDef Tier; internal LayoutDef Layout; internal string PrefabName => "arcade_drawer_" + Tier.Key + "_" + Layout.Suffix; internal string LegacyPrefabName => "ymiron_drawer_" + Tier.Key + "_" + Layout.Suffix; internal string Name => Layout.DisplayName(Tier); internal static DrawerKind[] All() { List<DrawerKind> list = new List<DrawerKind>(); TierDef[] all = TierDef.All; TierDef[] array = all; foreach (TierDef tier in array) { LayoutDef[] all2 = LayoutDef.All; LayoutDef[] array2 = all2; foreach (LayoutDef layout in array2) { list.Add(new DrawerKind { Tier = tier, Layout = layout }); } } return list.ToArray(); } } internal static class DrawerNetwork { private static readonly Dictionary<string, int> CraftCounts = new Dictionary<string, int>(); private static int _craftFrame = -1; private static int _version; private static int _craftVersion = -1; internal static void Invalidate() { _version++; } internal static List<SlotRef> Slots(Vector3 center, float range, bool accessible) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) List<SlotRef> list = new List<SlotRef>(); float rangeSq = range * range; foreach (Drawer item in from t in Drawer.All.Where((Drawer d) => (Object)(object)d != (Object)null && d.IsValid).Select(delegate(Drawer d) { //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_0012: 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) Vector3 val = ((Component)d).transform.position - center; return (Drawer: d, DistSq: ((Vector3)(ref val)).sqrMagnitude); }) where t.DistSq <= rangeSq orderby t.DistSq select t.Drawer) { if (!accessible || PrivateArea.CheckAccess(((Component)item).transform.position, 0f, false, false)) { for (int num = 0; num < item.Slots; num++) { list.Add(new SlotRef(item, num)); } } } return list; } internal static int CraftCount(string sharedName) { //IL_0082: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || string.IsNullOrEmpty(sharedName) || !ModConfig.CraftFromDrawers.Value) { return 0; } if (_craftFrame != Time.frameCount || _craftVersion != _version) { _craftFrame = Time.frameCount; _craftVersion = _version; CraftCounts.Clear(); foreach (SlotRef item in Slots(((Component)localPlayer).transform.position, ModConfig.CraftRange.Value, accessible: true)) { int count = item.Count; string text = ((count > 0) ? ItemInfo.SharedName(item.Item) : null); if (text != null) { CraftCounts.TryGetValue(text, out var value); CraftCounts[text] = value + count; } } } if (!CraftCounts.TryGetValue(sharedName, out var value2)) { return 0; } return value2; } internal static int TakeForCraft(string sharedName, int amount) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || amount <= 0) { return 0; } int num = 0; foreach (SlotRef item in Slots(((Component)localPlayer).transform.position, ModConfig.CraftRange.Value, accessible: true)) { if (num >= amount) { break; } if (item.Count > 0 && ItemInfo.SharedName(item.Item) == sharedName) { num += item.Drawer.RequestRemove(item.Slot, amount - num, Delivery.Discard); } } return num; } internal static List<StockEntry> Stock(Vector3 center, float range, out int drawers, out int freeSlots) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) Dictionary<string, StockEntry> dictionary = new Dictionary<string, StockEntry>(); List<SlotRef> list = Slots(center, range, accessible: true); drawers = list.Select((SlotRef s) => s.Drawer).Distinct().Count(); freeSlots = 0; foreach (SlotRef item2 in list) { if (item2.IsFree) { freeSlots++; continue; } int count = item2.Count; if (count <= 0) { continue; } string item = item2.Item; string data = item2.Data; string key = item + "\n" + data; if (!dictionary.TryGetValue(key, out var value)) { ItemDrop val = ItemInfo.Get(item); if ((Object)(object)val == (Object)null) { continue; } StockEntry stockEntry = (dictionary[key] = new StockEntry { Prefab = item, Data = data, Drop = val, LocalName = ItemInfo.Localize(val.m_itemData.m_shared.m_name) }); StockEntry stockEntry3 = stockEntry; value = stockEntry3; } value.Count += count; value.Compartments++; } return dictionary.Values.OrderBy<StockEntry, string>((StockEntry e) => e.LocalName, StringComparer.CurrentCultureIgnoreCase).ToList(); } internal static int Withdraw(string prefab, string data, int amount, Vector3 center, float range) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) int num = 0; string cleanPrefab = ItemInfo.CleanPrefabName(prefab); foreach (SlotRef item in Slots(center, range, accessible: true).Where(delegate(SlotRef s) { SlotRef slotRef = s; if (slotRef.Holds(cleanPrefab, data)) { slotRef = s; return slotRef.Count > 0; } return false; }).OrderBy(delegate(SlotRef s) { SlotRef slotRef = s; return slotRef.Count; })) { if (num >= amount) { break; } num += item.Drawer.RequestRemove(item.Slot, amount - num, Delivery.Inventory); } return num; } internal static int Deposit(string prefab, string data, int amount, Vector3 center, float range, bool useFree, Delivery overflow) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) List<SlotRef> source = Slots(center, range, accessible: true); int num = 0; string cleanPrefab = ItemInfo.CleanPrefabName(prefab); foreach (SlotRef item in source.Where(delegate(SlotRef s) { SlotRef slotRef = s; return slotRef.Holds(cleanPrefab, data); }).OrderByDescending(delegate(SlotRef s) { SlotRef slotRef = s; return slotRef.Count; })) { if (num >= amount) { return num; } num += item.Drawer.RequestAdd(item.Slot, cleanPrefab, data, amount - num, overflow); } if (useFree) { foreach (SlotRef item2 in source.Where((SlotRef s) => s.IsFree)) { if (num >= amount) { break; } num += item2.Drawer.RequestAdd(item2.Slot, cleanPrefab, data, amount - num, overflow); } } return num; } internal static int AvailableWithReserve(string sharedName, string prefabName, int reserve, Vector3 center, float range) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) int num = 0; string b = ItemInfo.CleanPrefabName(prefabName); foreach (SlotRef item in Slots(center, range, accessible: true)) { if (item.Count > 0) { string text = ItemInfo.CleanPrefabName(item.Item); if (string.Equals(text, b, StringComparison.OrdinalIgnoreCase) || (!string.IsNullOrEmpty(sharedName) && ItemInfo.SharedName(text) == sharedName)) { num += item.Count; } } } return Mathf.Max(0, num - reserve); } internal static int TakeWithReserve(string sharedName, string prefabName, int amount, int reserve, Vector3 center, float range) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) if (amount <= 0) { return 0; } List<SlotRef> list = new List<SlotRef>(); int num = 0; string b = ItemInfo.CleanPrefabName(prefabName); foreach (SlotRef item in Slots(center, range, accessible: true)) { if (item.Count > 0) { string text = ItemInfo.CleanPrefabName(item.Item); if (string.Equals(text, b, StringComparison.OrdinalIgnoreCase) || (!string.IsNullOrEmpty(sharedName) && ItemInfo.SharedName(text) == sharedName)) { list.Add(item); num += item.Count; } } } int num2 = Mathf.Max(0, num - reserve); int num3 = Mathf.Min(amount, num2); if (num3 <= 0) { return 0; } int num4 = 0; foreach (SlotRef item2 in list.OrderBy((SlotRef s) => s.Count)) { if (num4 >= num3) { break; } int amount2 = num3 - num4; num4 += item2.Drawer.RequestRemove(item2.Slot, amount2, Delivery.Discard); } return num4; } internal static bool OutputDrawerIsFull(string outputPrefab, Vector3 center, float range) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(outputPrefab)) { return false; } string text = ItemInfo.CleanPrefabName(outputPrefab); bool flag = false; int num = 0; foreach (SlotRef item in Slots(center, range, accessible: true)) { if (item.Holds(text, null)) { flag = true; num += item.Drawer.RoomFor(item.Slot, text, null); } } return flag && num <= 0; } } internal sealed class DrawerPickup : MonoBehaviour { private static readonly FieldInfo InstancesField = AccessTools.Field(typeof(ItemDrop), "s_instances"); private static readonly MethodInfo SaveMethod = AccessTools.Method(typeof(ItemDrop), "Save", (Type[])null, (Type[])null); private static bool _loggedError; private float _timer; private void Update() { _timer -= Time.deltaTime; if (_timer > 0f) { return; } _timer = ModConfig.PickupInterval.Value; if (!ModConfig.PickupEnabled.Value || Drawer.All.Count == 0 || (Object)(object)Player.m_localPlayer == (Object)null || !(InstancesField?.GetValue(null) is List<ItemDrop> source)) { return; } foreach (ItemDrop item in source.ToList()) { try { TryStore(item); } catch (Exception arg) { if (!_loggedError) { _loggedError = true; ArcadeDrawersPlugin.Log.LogError((object)string.Format("Pickup of '{0}' failed: {1}", ((Object)(object)item != (Object)null) ? ((Object)item).name : "?", arg)); } } } } private static void TryStore(ItemDrop drop) { //IL_00c9: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)drop == (Object)null || drop.IsPiece()) { return; } ZNetView component = ((Component)drop).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid()) { return; } if (!component.IsOwner()) { component.ClaimOwnership(); } drop.Load(); ItemData itemData = drop.m_itemData; if (itemData == null || itemData.m_stack <= 0 || !ItemInfo.CanStore(itemData)) { return; } string text = ItemInfo.GetPrefabName(itemData); if (string.IsNullOrEmpty(text)) { text = ItemInfo.CleanPrefabName(((Object)((Component)drop).gameObject).name); } int num = DrawerNetwork.Deposit(text, string.Empty, itemData.m_stack, ((Component)drop).transform.position, ModConfig.PickupRange.Value, useFree: false, Delivery.DropHere); if (num > 0) { ArcadeDrawersPlugin.Log.LogInfo((object)$"[ArcadeDrawers] Ground pickup stored {num}x '{text}'!"); if (num >= itemData.m_stack) { component.Destroy(); return; } itemData.m_stack -= num; SaveMethod?.Invoke(drop, null); } } } internal static class DrawerPrefabs { internal const string LedgerPrefabName = "arcade_drawer_ledger"; internal const string LegacyLedgerPrefabName = "ymiron_drawer_ledger"; private const string FallbackSource = "piece_chest_wood"; private static readonly FieldInfo NamedPrefabsField = typeof(ZNetScene).GetField("m_namedPrefabs", BindingFlags.Instance | BindingFlags.NonPublic); private static readonly List<(DrawerKind Kind, GameObject Prefab)> Drawers = new List<(DrawerKind, GameObject)>(); private static GameObject _ledger; private static GameObject _holder; private static ZNetScene _scene; internal static void Build(ZNetScene scene) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown _scene = scene; Drawers.Clear(); _ledger = null; ModelKit.ReleaseCreated(); if ((Object)(object)_holder != (Object)null) { Object.Destroy((Object)(object)_holder); } _holder = new GameObject("ArcadeDrawers_Holder"); _holder.SetActive(false); Object.DontDestroyOnLoad((Object)(object)_holder); DrawerKind[] array = DrawerKind.All(); DrawerKind[] array2 = array; foreach (DrawerKind drawerKind in array2) { try { GameObject val = BuildDrawer(scene, drawerKind); if ((Object)(object)val != (Object)null) { RegisterInScene(scene, val, drawerKind.LegacyPrefabName); Drawers.Add((drawerKind, val)); } } catch (Exception arg) { ArcadeDrawersPlugin.Log.LogError((object)$"Building the {drawerKind.Name} failed: {arg}"); } } try { _ledger = BuildLedger(scene); if ((Object)(object)_ledger != (Object)null) { RegisterInScene(scene, _ledger, "ymiron_drawer_ledger"); } } catch (Exception arg2) { ArcadeDrawersPlugin.Log.LogError((object)$"Building the Drawer Ledger failed: {arg2}"); } ArcadeDrawersPlugin.Log.LogInfo((object)string.Format("{0} drawers and {1} ledger created.", Drawers.Count, ((Object)(object)_ledger != (Object)null) ? "the" : "no")); TryFinalize(); } private static GameObject Source(ZNetScene scene, string name) { GameObject prefab = scene.GetPrefab(name); if ((Object)(object)prefab == (Object)null || (Object)(object)prefab.GetComponent<Piece>() == (Object)null || (Object)(object)prefab.GetComponent<WearNTear>() == (Object)null) { prefab = scene.GetPrefab("piece_chest_wood"); } if (!((Object)(object)prefab != (Object)null) || !((Object)(object)prefab.GetComponent<Piece>() != (Object)null) || !((Object)(object)prefab.GetComponent<WearNTear>() != (Object)null)) { return null; } return prefab; } private static GameObject StrippedClone(GameObject source, string name, float health, MaterialType material, out Transform model) { //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) GameObject val = Object.Instantiate<GameObject>(source, _holder.transform, false); ((Object)val).name = name; Transform transform = val.transform; MonoBehaviour[] components = val.GetComponents<MonoBehaviour>(); MonoBehaviour[] array = components; foreach (MonoBehaviour val2 in array) { if (!(val2 is ZNetView) && !(val2 is Piece) && !(val2 is WearNTear)) { Object.DestroyImmediate((Object)(object)val2); } } for (int num = transform.childCount - 1; num >= 0; num--) { Object.DestroyImmediate((Object)(object)((Component)transform.GetChild(num)).gameObject); } Collider[] components2 = val.GetComponents<Collider>(); for (int j = 0; j < components2.Length; j++) { Object.DestroyImmediate((Object)(object)components2[j]); } WearNTear component = val.GetComponent<WearNTear>(); component.m_new = null; component.m_worn = null; component.m_broken = null; component.m_wet = null; component.m_snow = null; component.m_snowWorn = null; component.m_snowBroken = null; component.m_fragmentRoots = null; component.m_nonSolidRenderers?.Clear(); component.m_health = health; component.m_materialType = material; Piece component2 = val.GetComponent<Piece>(); component2.m_enabled = true; component2.m_category = (PieceCategory)4; component2.m_comfort = 0; component2.m_comfortGroup = (ComfortGroup)0; model = new GameObject("model") { layer = val.layer }.transform; model.SetParent(transform, false); return val; } private static GameObject BuildDrawer(ZNetScene scene, DrawerKind kind) { //IL_0061: 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_008c: 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_00d0: 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) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Expected O, but got Unknown //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_0294: Unknown result type (might be due to invalid IL or missing references) //IL_0299: Unknown result type (might be due to invalid IL or missing references) GameObject val = Source(scene, kind.Tier.SourcePrefab); if ((Object)(object)val == (Object)null) { ArcadeDrawersPlugin.Log.LogError((object)("No vanilla chest to build the " + kind.Name + " from.")); return null; } Transform model; GameObject val2 = StrippedClone(val, kind.PrefabName, kind.Tier.Health, kind.Tier.Material, out model); val2.GetComponent<WearNTear>().m_supports = true; float value = ModConfig.DrawerSize.Value; model.localScale = Vector3.one * value; List<DrawerModel.Cell> list = DrawerModel.Build(scene, model, kind.Tier, kind.Layout); ModelKit.AddBoxCollider(model, new Vector3(0f, 0.5f, -0.01f), new Vector3(1f, 1f, 0.46f), Quaternion.identity); for (int i = 0; i < list.Count; i++) { GameObject val3 = new GameObject($"compartment{i}"); val3.layer = val2.layer; val3.transform.SetParent(model, false); val3.transform.localPosition = new Vector3(list[i].Center.x, list[i].Center.y, 0.235f); val3.AddComponent<BoxCollider>().size = new Vector3(list[i].Size.x, list[i].Size.y, 0.03f); val3.AddComponent<DrawerSlot>().m_slot = i; } AddSnapPoints(val2.transform, value); Piece component = val2.GetComponent<Piece>(); component.m_name = kind.Name; component.m_description = ((kind.Layout.Slots == 1) ? Loc.T("DrawerDescSingle") : Loc.T("DrawerDescMulti", kind.Layout.Slots)); Drawer drawer = val2.AddComponent<Drawer>(); drawer.m_tier = kind.Tier.Number; drawer.m_layout = kind.Layout.Index; drawer.m_faces = list.Select((DrawerModel.Cell c) => c.Face).ToArray(); drawer.m_cellSize = list[0].Size; drawer.m_scale = value; return val2; } private static GameObject BuildLedger(ZNetScene scene) { //IL_003d: 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_0047: Unknown result type (might be due to invalid IL or missing references) GameObject val = Source(scene, "piece_chest_wood"); if ((Object)(object)val == (Object)null) { return null; } Transform model; GameObject val2 = StrippedClone(val, "arcade_drawer_ledger", 800f, (MaterialType)1, out model); LedgerModel.Build(scene, model); ModelKit.AddBoxCollider(model, LedgerModel.ColliderCenter, LedgerModel.ColliderSize, Quaternion.identity); Piece component = val2.GetComponent<Piece>(); component.m_name = Loc.T("LedgerName"); component.m_description = Loc.T("LedgerDesc"); val2.AddComponent<Ledger>(); return val2; } private static void AddSnapPoints(Transform root, float scale) { //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Expected O, but got Unknown //IL_00cf: Unknown result type (might be due to invalid IL or missing references) float num = 0.5f * scale; float num2 = 0.25f * scale; float[] array = new float[2] { 0f, 1f * scale }; float[] array2 = array; foreach (float num3 in array2) { float[] array3 = new float[2] { 0f - num, num }; float[] array4 = array3; foreach (float num4 in array4) { float[] array5 = new float[2] { 0f - num2, num2 }; float[] array6 = array5; foreach (float num5 in array6) { GameObject val = new GameObject("_snappoint"); val.layer = ((Component)root).gameObject.layer; val.tag = "snappoint"; val.transform.SetParent(root, false); val.transform.localPosition = new Vector3(num4, num3, num5); } } } } internal static void TryFinalize() { //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) if (Drawers.Count == 0 && (Object)(object)_ledger == (Object)null) { return; } ObjectDB instance = ObjectDB.instance; if ((Object)(object)instance == (Object)null || instance.m_items.Count == 0) { return; } GameObject itemPrefab = instance.GetItemPrefab("Hammer"); PieceTable table = ((!((Object)(object)itemPrefab != (Object)null)) ? null : itemPrefab.GetComponent<ItemDrop>()?.m_itemData?.m_shared?.m_buildPieces); if ((Object)(object)table == (Object)null) { return; } HashSet<string> ours = new HashSet<string>(Drawers.Select(((DrawerKind Kind, GameObject Prefab) d) => ((Object)d.Prefab).name)) { "arcade_drawer_ledger", "ymiron_drawer_ledger" }; table.m_pieces.RemoveAll((GameObject p) => (Object)(object)p == (Object)null || ours.Contains(((Object)p).name)); PieceCategory category = BuildCategory.Get(); foreach (GameObject item3 in from p in Drawers.Select(((DrawerKind Kind, GameObject Prefab) d) => d.Prefab).Concat((IEnumerable<GameObject>)(object)new GameObject[1] { _ledger }) where (Object)(object)p != (Object)null select p) { item3.GetComponent<Piece>().m_category = category; } int num = new string[3] { "piece_chest_blackmetal", "piece_chest", "piece_chest_wood" }.Select((string name) => table.m_pieces.FindIndex((GameObject p) => ((Object)p).name == name)).DefaultIfEmpty(-1).Max(); num = ((num >= 0) ? (num + 1) : table.m_pieces.Count); if ((Object)(object)_ledger != (Object)null) { Piece component = _ledger.GetComponent<Piece>(); component.m_resources = ParseRequirements(instance, ModConfig.LedgerRequirements.Value, "Wood:10,LeatherScraps:4,Resin:4", "Drawer Ledger"); component.m_craftingStation = FindStation(ModConfig.LedgerStation.Value, "Drawer Ledger"); table.m_pieces.Insert(num++, _ledger); } foreach (var drawer in Drawers) { DrawerKind item = drawer.Kind; GameObject item2 = drawer.Prefab; TierConfig tierConfig = ModConfig.Tier(item.Tier); Piece component2 = item2.GetComponent<Piece>(); bool flag = item.Layout == LayoutDef.Single; string text = item.Tier.Requirements[item.Layout.Index]; component2.m_resources = ParseRequirements(instance, flag ? tierConfig.Requirements.Value : text, text, item.Name); component2.m_craftingStation = FindStation(tierConfig.Station.Value, item.Name); if (flag && tierConfig.Enabled.Value) { table.m_pieces.Insert(num++, item2); } } } internal static void ApplySize() { float value = ModConfig.DrawerSize.Value; foreach (var drawer in Drawers) { GameObject item = drawer.Prefab; if ((Object)(object)item != (Object)null) { Drawer.Resize(item, value); } } foreach (Drawer item2 in Drawer.All.Where((Drawer d) => (Object)(object)d != (Object)null).ToList()) { Drawer.Resize(((Component)item2).gameObject, value); } } internal static void RenderIcons() { foreach (GameObject item in from p in Drawers.Select(((DrawerKind Kind, GameObject Prefab) d) => d.Prefab).Concat((IEnumerable<GameObject>)(object)new GameObject[1] { _ledger }) where (Object)(object)p != (Object)null select p) { Sprite val = IconRenderer.Render(item); if ((Object)(object)val != (Object)null) { item.GetComponent<Piece>().m_icon = val; } } } private static CraftingStation FindStation(string name, string what) { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Expected O, but got Unknown //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Expected O, but got Unknown name = (name ?? string.Empty).Trim(); if (name.Length == 0) { return null; } object obj; if (!((Object)(object)_scene != (Object)null)) { obj = null; } else { GameObject prefab = _scene.GetPrefab(name); obj = ((prefab != null) ? prefab.GetComponent<CraftingStation>() : null); } object obj2 = obj; if ((Object)obj2 == (Object)null) { ArcadeDrawersPlugin.Log.LogWarning((object)(what + ": crafting station '" + name + "' not found, none required.")); } return (CraftingStation)obj2; } private static Requirement[] ParseRequirements(ObjectDB odb, string raw, string fallback, string what) { //IL_0050: 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_006b: 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_007f: Expected O, but got Unknown List<Requirement> list = Parse(odb, raw, what); if (list.Count == 0 && raw != fallback) { ArcadeDrawersPlugin.Log.LogWarning((object)(what + ": no valid requirements, using the default cost.")); list = Parse(odb, fallback, what); } if (list.Count == 0) { list.Add(new Requirement { m_resItem = odb.GetItemPrefab("Wood").GetComponent<ItemDrop>(), m_amount = 10, m_recover = true }); } return list.ToArray(); } private static List<Requirement> Parse(ObjectDB odb, string raw, string what) { //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_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Expected O, but got Unknown List<Requirement> list = new List<Requirement>(); string[] array = (raw ?? string.Empty).Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries); string[] array2 = array; foreach (string text in array2) { string[] array3 = text.Trim().Split(':'); if (array3.Length != 2 || !int.TryParse(array3[1].Trim(), out var result) || result <= 0) { ArcadeDrawersPlugin.Log.LogWarning((object)(what + ": invalid requirement '" + text + "'. Expected format Prefab:Amount.")); continue; } GameObject itemPrefab = odb.GetItemPrefab(array3[0].Trim()); ItemDrop val = ((itemPrefab != null) ? itemPrefab.GetComponent<ItemDrop>() : null); if ((Object)(object)val == (Object)null) { ArcadeDrawersPlugin.Log.LogWarning((object)(what + ": item '" + array3[0].Trim() + "' not found in ObjectDB, skipped.")); continue; } list.Add(new Requirement { m_resItem = val, m_amount = result, m_recover = true }); } return list; } private static void RegisterInScene(ZNetScene scene, GameObject prefab, string legacyName = null) { scene.m_prefabs.RemoveAll((GameObject p) => (Object)(object)p == (Object)null || ((Object)(object)p != (Object)(object)prefab && ((Object)p).name == ((Object)prefab).name)); if (!scene.m_prefabs.Contains(prefab)) { scene.m_prefabs.Add(prefab); } if (NamedPrefabsField?.GetValue(scene) is Dictionary<int, GameObject> dictionary) { dictionary[StringExtensionMethods.GetStableHashCode(((Object)prefab).name)] = prefab; if (!string.IsNullOrEmpty(legacyName)) { dictionary[StringExtensionMethods.GetStableHashCode(legacyName)] = prefab; } } else { ArcadeDrawersPlugin.Log.LogError((object)("Cannot access ZNetScene.m_namedPrefabs: '" + ((Object)prefab).name + "' will not be buildable.")); } } } public class DrawerSlot : MonoBehaviour, Hoverable, Interactable { public int m_slot; private Drawer _drawer; private Drawer Owner { get { if ((Object)(object)_drawer == (Object)null) { _drawer = ((Component)this).GetComponentInParent<Drawer>(); } return _drawer; } } public string GetHoverText() { if (!((Object)(object)Owner != (Object)null)) { return string.Empty; } return Owner.GetHoverText(m_slot); } public string GetHoverName() { if (!((Object)(object)Owner != (Object)null)) { return string.Empty; } return Owner.DisplayName; } public float GetHoverOffset() { return 0f; } public bool Interact(Humanoid user, bool hold, bool alt) { if ((Object)(object)Owner != (Object)null) { return Owner.Interact(m_slot, user, hold, alt); } return false; } public bool UseItem(Humanoid user, ItemData item) { if ((Object)(object)Owner != (Object)null) { return Owner.UseItem(m_slot, user, item); } return false; } } [HarmonyPatch(typeof(Fireplace), "Interact")] internal static class Fireplace_Interact_Patch { private static bool Prefix(Fireplace __instance, Humanoid user, bool hold, bool alt, ref bool __result) { if (!ModConfig.CraftFromDrawers.Value) { return true; } Player val = (Player)(object)((user is Player) ? user : null); ZNetView component = ((Component)__instance).GetComponent<ZNetView>(); if ((Object)(object)val == (Object)null || (Object)(object)val != (Object)(object)Player.m_localPlayer || (Object)(object)component == (Object)null || !component.IsValid()) { return true; } if (hold) { if (__instance.m_holdRepeatInterval <= 0f) { return true; } float value = Traverse.Create((object)__instance).Field("m_lastUseTime").GetValue<float>(); if (Time.time - value < __instance.m_holdRepeatInterval) { return true; } } if (!component.HasOwner()) { component.ClaimOwnership(); } float num = component.GetZDO().GetFloat(ZDOVars.s_fuel, 0f); if (__instance.m_canTurnOff && !hold && !alt && num > 0f) { return true; } if (!__instance.m_canRefill || __instance.m_infiniteFuel) { return true; } if ((Object)(object)__instance.m_fuelItem == (Object)null) { return true; } string name = __instance.m_fuelItem.m_itemData.m_shared.m_name; bool flag = Input.GetKey((KeyCode)304) || Input.GetKey((KeyCode)303); if (((Humanoid)val).GetInventory().HaveItem(name, true) && !flag) { return true; } int num2 = Mathf.CeilToInt(__instance.m_maxFuel - num); if (num2 <= 0) { ((Character)user).Message((MessageType)2, Localization.instance.Localize("$msg_cantaddmore", new string[1] { name }), 0, (Sprite)null, false); __result = false; return false; } int num3 = ((!flag) ? 1 : num2); num3 = Mathf.Min(num3, num2); int num4 = 0; if (((Humanoid)val).GetInventory() != null) { num4 = Mathf.Min(num3, ((Humanoid)val).GetInventory().CountItems(name, -1, true)); if (num4 > 0) { ((Humanoid)val).GetInventory().RemoveItem(name, num4, -1, true); } } int num5 = num3 - num4; int num6 = 0; if (num5 > 0) { num6 = DrawerNetwork.TakeForCraft(name, num5); } int num7 = num4 + num6; if (num7 > 0) { ((Character)user).Message((MessageType)2, Localization.instance.Localize("$msg_fireadding", new string[1] { name }) + ((num7 > 1) ? (" x" + num7) : ""), 0, (Sprite)null, false); for (int i = 0; i < num7; i++) { component.InvokeRPC("RPC_AddFuel", Array.Empty<object>()); } __result = true; return false; } return true; } } internal static class Fonts { private static TMP_FontAsset _numbers; internal static TMP_FontAsset Numbers { get { if ((Object)(object)_numbers != (Object)null) { return _numbers; } TMP_FontAsset[] source = Resources.FindObjectsOfTypeAll<TMP_FontAsset>(); _numbers = ((IEnumerable<TMP_FontAsset>)source).FirstOrDefault((Func<TMP_FontAsset, bool>)((TMP_FontAsset f) => ((Object)f).name.IndexOf("Norse", StringComparison.OrdinalIgnoreCase) >= 0 && ((Object)f).name.IndexOf("Bold", StringComparison.OrdinalIgnoreCase) >= 0)) ?? ((IEnumerable<TMP_FontAsset>)source).FirstOrDefault((Func<TMP_FontAsset, bool>)((TMP_FontAsset f) => ((Object)f).name.IndexOf("Norse", StringComparison.OrdinalIgnoreCase) >= 0)) ?? (((Object)(object)InventoryGui.instance != (Object)null) ? InventoryGui.instance.m_containerName.font : null) ?? ((IEnumerable<TMP_FontAsset>)source).FirstOrDefault((Func<TMP_FontAsset, bool>)((TMP_FontAsset f) => ((Object)f).name.IndexOf("Averia", StringComparison.OrdinalIgnoreCase) >= 0)) ?? source.FirstOrDefault(); return _numbers; } } } [HarmonyPatch(typeof(Game), "Start")] internal static class Game_Start_Patch { private static void Postfix(Game __instance) { ((Component)__instance).gameObject.AddComponent<DrawerPickup>(); ((Component)__instance).gameObject.AddComponent<ModNetwork>(); ((Component)__instance).gameObject.AddComponent<ConfigSync>(); DrawerPrefabs.RenderIcons(); } } [HarmonyPatch(typeof(Hud), "SetupPieceInfo")] internal static class Hud_SetupPieceInfo_Patch { private static void Prefix(Piece piece, out bool __state) { __state = CraftContext.Enter(Player.m_localPlayer); } private static Exception Finalizer(Exception __exception, bool __state) { CraftContext.Exit(__state); return __exception; } } [HarmonyPatch(typeof(InventoryGui), "Hide")] internal static class InventoryGui_Hide_Patch { private static void Postfix() { LedgerPanel.Close(); } } [HarmonyPatch(typeof(InventoryGui), "OnSelectedItem")] internal static class InventoryGui_OnSelectedItem_Patch { private static bool Prefix(InventoryGui __instance, InventoryGrid grid, ItemData item, Modifier mod, GameObject ___m_dragGo) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Invalid comparison between Unknown and I4 if (!LedgerPanel.IsOpen || (int)mod != 2 || item == null || (Object)(object)___m_dragGo != (Object)null || (Object)(object)grid != (Object)(object)__instance.m_playerGrid) { return true; } LedgerPanel.StoreStack(item); return false; } } [HarmonyPatch(typeof(InventoryGui), "SetupRequirement")] internal static class InventoryGui_SetupRequirement_Patch { private static void Prefix(Player player, out bool __state) { __state = CraftContext.Enter(player); } private static Exception Finalizer(Exception __exception, bool __state) { CraftContext.Exit(__state); return __exception; } } [HarmonyPatch(typeof(InventoryGui), "Show")] internal static class InventoryGui_Show_Patch { private static void Postfix(Container container) { if ((Object)(object)container != (Object)null) { LedgerPanel.Close(); } } } [HarmonyPatch(typeof(Inventory), "CountItems")] internal static class Inventory_CountItems_Patch { private static void Postfix(Inventory __instance, string name, int quality, ref int __result) { if (CraftContext.Active && name != null && quality <= 1 && CraftContext.IsLocalInventory(__instance)) { __result += DrawerNetwork.CraftCount(name); } } } [HarmonyPatch(typeof(Inventory), "HaveItem", new Type[] { typeof(string), typeof(bool) })] internal static class Inventory_HaveItem_Patch { private static void Postfix(Inventory __instance, string name, ref bool __result) { if (!__result && CraftContext.Active && name != null && CraftContext.IsLocalInventory(__instance)) { __result = DrawerNetwork.CraftCount(name) > 0; } } } internal static class ItemInfo { private static readonly Dictionary<string, ItemDrop> Cache = new Dictionary<string, ItemDrop>(); private static ObjectDB _cachedFor; internal static string CleanPrefabName(string name) { if (string.IsNullOrEmpty(name)) { return string.Empty; } return name.Replace("(Clone)", "").Trim(); } internal static string GetPrefabName(ItemData item) { if (item == null) { return string.Empty; } if ((Object)(object)item.m_dropPrefab != (Object)null && !string.IsNullOrEmpty(((Object)item.m_dropPrefab).name)) { return CleanPrefabName(((Object)item.m_dropPrefab).name); } if ((Object)(object)ObjectDB.instance != (Object)null && item.m_shared != null) { GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(item.m_shared.m_name); if ((Object)(object)itemPrefab != (Object)null) { return CleanPrefabName(((Object)itemPrefab).name); } foreach (GameObject item2 in ObjectDB.instance.m_items) { if ((Object)(object)item2 != (Object)null) { ItemDrop component = item2.GetComponent<ItemDrop>(); if ((Object)(object)component != (Object)null && component.m_itemData != null && component.m_itemData.m_shared != null && component.m_itemData.m_shared.m_name == item.m_shared.m_name) { return CleanPrefabName(((Object)item2).name); } } } } return string.Empty; } internal static ItemDrop Get(string prefabName) { if (string.IsNullOrEmpty(prefabName) || (Object)(object)ObjectDB.instance == (Object)null) { return null; } string text = CleanPrefabName(prefabName); if ((Object)(object)_cachedFor != (Object)(object)ObjectDB.instance) { Cache.Clear(); _cachedFor = ObjectDB.instance; } if (!Cache.TryGetValue(text, out var value)) { GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(text); value = ((itemPrefab != null) ? itemPrefab.GetComponent<ItemDrop>() : null); if ((Object)(object)value == (Object)null) { foreach (GameObject item in ObjectDB.instance.m_items) { if ((Object)(object)item != (Object)null && (((Object)item).name == text || item.GetComponent<ItemDrop>()?.m_itemData?.m_shared?.m_name == text)) { value = item.GetComponent<ItemDrop>(); break; } } } Cache[text] = value; } return value; } internal static string SharedName(string prefabName) { return Get(prefabName)?.m_itemData?.m_shared?.m_name; } internal static bool CanStore(ItemData item) { if (item == null || item.m_shared == null) { return false; } string prefabName = GetPrefabName(item); if (string.IsNullOrEmpty(prefabName)) { return false; } if (item.m_shared.m_maxStackSize > 1 && !item.m_shared.m_questItem && !item.m_equipped && !ModConfig.IsBlacklisted(prefabName)) { return (Object)(object)Get(prefabName) != (Object)null; } return false; } internal static string DataKey(ItemData item) { //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Expected O, but got Unknown List<KeyValuePair<string, string>> list = item?.m_customData?.Where((KeyValuePair<string, string> p) => !string.IsNullOrEmpty(p.Value)).OrderBy<KeyValuePair<string, string>, string>((KeyValuePair<string, string> p) => p.Key, StringComparer.Ordinal).ToList(); if (list == null || list.Count == 0) { return string.Empty; } ZPackage val = new ZPackage(); val.Write(list.Count); foreach (KeyValuePair<string, string> item2 in list) { val.Write(item2.Key); val.Write(item2.Value); } return val.GetBase64(); } internal static Dictionary<string, string> ReadData(string key) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown Dictionary<string, string> dictionary = new Dictionary<string, string>(); if (string.IsNullOrEmpty(key)) { return dictionary; } try { ZPackage val = new ZPackage(key); int num = val.ReadInt(); for (int i = 0; i < num; i++) { string key2 = val.ReadString(); dictionary[key2] = val.ReadString(); } } catch (Exception ex) { ArcadeDrawersPlugin.Log.LogWarning((object)("Unreadable custom data in a drawer: " + ex.Message)); } return dictionary; } internal static ItemData NewStack(ItemDrop drop, int amount, string data) { ItemData val = drop.m_itemData.Clone(); val.m_dropPrefab = ((Component)drop).gameObject; val.m_stack = amount; val.m_quality = 1; val.m_worldLevel = (byte)Game.m_worldLevel; val.m_customData = ReadData(data); return val; } internal static int Room(Inventory inventory, ItemDrop drop) { SharedData shared = drop.m_itemData.m_shared; return inventory.FindFreeStackSpace(shared.m_name, (float)Game.m_worldLevel) + inventory.GetEmptySlots() * shared.m_maxStackSize; } internal static void Give(Inventory inventory, ItemDrop drop, int amount, string data) { int maxStackSize = drop.m_itemData.m_shared.m_maxStackSize; while (amount > 0) { int num = Mathf.Min(amount, maxStackSize); if (!inventory.AddItem(NewStack(drop, num, data))) { ArcadeDrawersPlugin.Log.LogWarning((object)$"Could not add {num} {((Object)drop).name} to the inventory."); break; } amount -= num; } } internal static List<ItemData> Matching(Inventory inventory, string prefabName, string data) { string cleanTarget = CleanPrefabName(prefabName); string targetShared = SharedName(cleanTarget); return (from i in inventory.GetAllItems() where CanStore(i) && (string.Equals(CleanPrefabName(GetPrefabName(i)), cleanTarget, StringComparison.OrdinalIgnoreCase) || (!string.IsNullOrEmpty(targetShared) && i.m_shared != null && i.m_shared.m_name == targetShared)) select i).ToList(); } internal static string Localize(string text) { if (Localization.instance == null) { return text; } return Localization.instance.Localize(text); } internal static string ShortCount(int count) { if (count < 10000) { return count.ToString(); } if (count < 1000000) { return ((float)count / 1000f).ToString((count < 100000) ? "0.#" : "0") + "k"; } return ((float)count / 1000000f).ToString("0.#") + "M"; } } internal sealed class LayoutDef { internal int Index; internal int Rows; internal int Columns; internal string Suffix; internal static readonly LayoutDef Single = new LayoutDef { Index = 0, Rows = 1, Columns = 1, Suffix = "x1" }; internal static readonly LayoutDef Double = new LayoutDef { Index = 1, Rows = 2, Columns = 1, Suffix = "x2" }; internal static readonly LayoutDef Quad = new LayoutDef { Index = 2, Rows = 2, Columns = 2, Suffix = "x4" }; internal static readonly LayoutDef[] All = new LayoutDef[3] { Single, Double, Quad }; internal int Slots => Rows * Columns; internal string DisplayName(TierDef tier) { if (Slots != 1) { return tier.Name + " " + Loc.T("CompartmentsSuffix", Slots); } return tier.Name; } } public class Ledger : MonoBehaviour, Hoverable, Interactable { private ZNetView _nview; private Piece _piece; internal string DisplayName => Loc.T("LedgerName"); private void Awake() { _nview = ((Component)this).GetComponent<ZNetView>(); _piece = ((Component)this).GetComponent<Piece>(); } public string GetHoverText() { if ((Object)(object)_nview == (Object)null || !_nview.IsValid()) { return string.Empty; } float range = ModConfig.LedgerRange.Value; int num = Drawer.All.Count((Drawer d) => (Object)(object)d != (Object)null && d.IsValid && Vector3.Distance(((Component)d).transform.position, ((Component)this).transform.position) <= range); return ItemInfo.Localize(DisplayName + "\n<color=#a0a0a0>" + Loc.T("LedgerHoverRange", num, range) + "</color>\n" + Loc.T("LedgerHoverOpen")); } public string GetHoverName() { return DisplayName; } public float GetHoverOffset() { return 0f; } public bool Interact(Humanoid user, bool hold, bool alt) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown //IL_0056: Unknown result type (might be due to invalid IL or missing references) if (!hold && !((Object)(object)_nview == (Object)null) && _nview.IsValid()) { Player val = (Player)((user is Player) ? user : null); if (val != null && !((Object)(object)val != (Object)(object)Player.m_localPlayer)) { if (!PrivateArea.CheckAccess(((Component)this).transform.position, 0f, true, false)) { return true; } LedgerPanel.Open(this); return true; } } return false; } public bool UseItem(Humanoid user, ItemData item) { return false; } } public class PanelDragger : MonoBehaviour, IBeginDragHandler, IEventSystemHandler, IDragHandler { private RectTransform _panel; private Vector2 _offset; public void Init(RectTransform panel) { _panel = panel; } public void OnBeginDrag(PointerEventData eventData) { //IL_002f: 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_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_panel == (Object)null)) { Transform parent = ((Transform)_panel).parent; RectTransform val = (RectTransform)(object)((parent is RectTransform) ? parent : null); Vector2 val2 = default(Vector2); if ((Object)(object)val != (Object)null && RectTransformUtility.ScreenPointToLocalPointInRectangle(val, eventData.position, eventData.pressEventCamera, ref val2)) { _offset = _panel.anchoredPosition - val2; } } } public void OnDrag(PointerEventData eventData) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_panel == (Object)null)) { Transform parent = ((Transform)_panel).parent; RectTransform val = (RectTransform)(object)((parent is RectTransform) ? parent : null); Vector2 val2 = default(Vector2); if ((Object)(object)val != (Object)null && RectTransformUtility.ScreenPointToLocalPointInRectangle(val, eventData.position, eventData.pressEventCamera, ref val2)) { _panel.anchoredPosition = val2 + _offset; } } } } public class LedgerPanel : MonoBehaviour { private class Tile { internal GameObject Go; internal InventoryElement Element; internal StockEntry Entry; } [CompilerGenerated] private static class <>O { public static UnityAction <0>__Close; } private const float RefreshInterval = 0.5f; private const float CloseDistance = 5f; private static LedgerPanel _instance; private Ledger _ledger; private RectTransform _panelRect; private ScrollRect _scrollRect; private TMP_Text _title; private TMP_Text _status; private TMP_Text _hint; private TMP_Text _empty; private TMP_Text _storeAllBtnText; private UITooltip _storeAllTooltip; private TMP_Text _autoFeedBtnText; private Image _autoFeedBtnImg; private Outline _autoFeedBtnOutline; private TextMeshProUGUI _searchPlaceholder; private TMP_InputField _search; private RectTransform _content; private GameObject _elementPrefab; private readonly List<Tile> _tiles = new List<Tile>(); private float _refreshTimer; private bool _dirty; private GameObject _settingsModal; private TMP_Text _modalTitle; private TMP_Text _masterTitle; private TMP_Text _masterDesc; private TMP_Text _masterBtnText; private Image _masterBtnImg; private Outline _masterBtnOutline; private TMP_Text _woodTitle; private TMP_Text _woodDesc; private TMP_Text _woodBtnText; private Image _woodBtnImg; private Outline _woodBtnOutline; private TMP_Text _oreTitle; private TMP_Text _oreDesc; private TMP_Text _oreBtnText; private Image _oreBtnImg; private Outline _oreBtnOutline; private TMP_Text _coalTitle; private TMP_Text _coalDesc; private TMP_Text _coalBtnTex