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 NishinkusSmelterLink v0.3.0
NishinkusSmelterLink.dll
Decompiled a week agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.Rendering; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: IgnoresAccessChecksTo("assembly_valheim")] [assembly: AssemblyCompany("NishinkusSmelterLink")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.3.0.0")] [assembly: AssemblyInformationalVersion("0.3.0+9dba42ac7f84a166829eb6bceee3e7cfa2775a79")] [assembly: AssemblyProduct("NishinkusSmelterLink")] [assembly: AssemblyTitle("NishinkusSmelterLink")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.3.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 SmelterLink { [BepInPlugin("nishinku.smelterlink", "Nishinku's SmelterLink", "0.3.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { public const string PluginId = "nishinku.smelterlink"; public const string Version = "0.3.0"; internal static ManualLogSource Log; internal static ConfigEntry<KeyboardShortcut> LinkKey; internal static ConfigEntry<float> TickInterval; internal static ConfigEntry<float> MaxCatchupSeconds; internal static ConfigEntry<bool> OfflineSmelting; internal static ConfigEntry<float> ToolRange; internal static ConfigEntry<bool> BlockInputWhileMarking; internal static ConfigEntry<bool> CancelMarkingOnDamage; internal static ConfigEntry<bool> Verbose; private Harmony _harmony; private static readonly List<ZDOID> _tickBuffer = new List<ZDOID>(); private void Awake() { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Expected O, but got Unknown //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Expected O, but got Unknown //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Expected O, but got Unknown //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; LinkKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "LinkKey", new KeyboardShortcut((KeyCode)103, Array.Empty<KeyCode>()), "Look at a smelter and press this to start marking storage; then look at a chest and press it again."); TickInterval = ((BaseUnityPlugin)this).Config.Bind<float>("General", "TickInterval", 2f, new ConfigDescription("Seconds between background passes over linked smelters.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 30f), Array.Empty<object>())); OfflineSmelting = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "OfflineSmelting", true, "Keep linked smelters running while you are away from them. Requires an output chest to be linked."); MaxCatchupSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("General", "MaxCatchupSeconds", 86400f, new ConfigDescription("Most in-game seconds of production a single smelter can catch up at once. Vanilla clamps this to 3600, which is why smelters appear to stall when you travel.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(60f, 604800f), Array.Empty<object>())); ToolRange = ((BaseUnityPlugin)this).Config.Bind<float>("Linker rod", "Range", 64f, new ConfigDescription("How far the linker rod reveals links, in metres.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(8f, 256f), Array.Empty<object>())); BlockInputWhileMarking = ((BaseUnityPlugin)this).Config.Bind<bool>("Marking", "BlockInputWhileMarking", true, "While marking storage, allow only movement. The marking keys otherwise also trigger hotbar slots, sitting down and the menu."); CancelMarkingOnDamage = ((BaseUnityPlugin)this).Config.Bind<bool>("Marking", "CancelOnDamage", true, "Stop marking when you take damage."); Verbose = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Verbose", false, "Log every transfer."); LinkerTool.Register(); _harmony = new Harmony("nishinku.smelterlink"); _harmony.PatchAll(); ((MonoBehaviour)this).StartCoroutine(TickLoop()); Log.LogInfo((object)"Nishinku's SmelterLink 0.3.0 loaded."); } private void OnDestroy() { ((MonoBehaviour)this).StopAllCoroutines(); LinkMode.Shutdown(); LinkLines.Shutdown(); if (_harmony != null) { _harmony.UnpatchSelf(); } } private void Update() { LinkMode.Update(); LinkLines.Begin(); LinkerTool.Draw(); LinkMode.Draw(); LinkLines.End(); } private void OnGUI() { LinkMode.DrawGui(); } private IEnumerator TickLoop() { while (true) { yield return (object)new WaitForSeconds(TickInterval.Value); if (!InWorld()) { if (Registry.Ready) { Registry.Reset(); } continue; } if (!Registry.Ready) { Registry.Rebuild(); } if (ZNet.instance.IsServer()) { try { Tick(); } catch (Exception ex) { Log.LogError((object)("Tick failed: " + ex)); } } } } private static bool InWorld() { if ((Object)(object)ZNet.instance != (Object)null && ZDOMan.instance != null && (Object)(object)ZNetScene.instance != (Object)null && (Object)(object)ObjectDB.instance != (Object)null) { return (Object)(object)Player.m_localPlayer != (Object)null; } return false; } private static void Tick() { //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_0024: 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_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) Registry.CopyInto(_tickBuffer); List<ZDOID> tickBuffer = _tickBuffer; for (int i = 0; i < tickBuffer.Count; i++) { ZDOID val = tickBuffer[i]; ZDO zDO = ZDOMan.instance.GetZDO(val); if (zDO == null || !zDO.IsValid()) { Registry.Forget(val); continue; } Smelter val2 = Registry.PrefabFor(zDO); if ((Object)(object)val2 == (Object)null) { Registry.Forget(val); } else if (!Links.HasAny(zDO)) { Registry.Forget(val); } else if (!ZNetScene.instance.m_instances.ContainsKey(zDO) && !Links.OwnedByOther(zDO)) { int num = SmelterOps.FeedFuel(zDO, val2); int num2 = SmelterOps.FeedOre(zDO, val2); SmelterOps.FlushPendingOutput(zDO, val2); int num3 = 0; if (OfflineSmelting.Value) { num3 = SmelterOps.Simulate(zDO, val2); } if (Verbose.Value && (num > 0 || num2 > 0 || num3 > 0)) { ManualLogSource log = Log; string[] obj = new string[10] { val2.m_name, " @ ", null, null, null, null, null, null, null, null }; Vector3 position = zDO.GetPosition(); obj[2] = ((Vector3)(ref position)).ToString("0"); obj[3] = " +"; obj[4] = num.ToString(); obj[5] = " fuel, +"; obj[6] = num2.ToString(); obj[7] = " ore, "; obj[8] = num3.ToString(); obj[9] = " produced"; log.LogInfo((object)string.Concat(obj)); } } } } } internal static class ChestIndex { private static readonly Dictionary<long, ZDOID> _byCid = new Dictionary<long, ZDOID>(); private static float _nextScan; public static int Count => _byCid.Count; public static void Reset() { _byCid.Clear(); _nextScan = 0f; } public static void Register(long cid, ZDOID id) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) if (cid != 0L) { _byCid[cid] = id; } } public static ZDO Find(long cid) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) if (cid == 0L || ZDOMan.instance == null) { return null; } if (_byCid.TryGetValue(cid, out var value)) { ZDO zDO = ZDOMan.instance.GetZDO(value); if (zDO != null && zDO.IsValid() && zDO.GetLong("slink_cid", 0L) == cid) { return zDO; } _byCid.Remove(cid); } Rescan(); if (!_byCid.TryGetValue(cid, out value)) { return null; } return ZDOMan.instance.GetZDO(value); } public static void Rescan(bool force = false) { //IL_0078: Unknown result type (might be due to invalid IL or missing references) if (ZDOMan.instance == null || (!force && Time.time < _nextScan)) { return; } _nextScan = Time.time + 10f; _byCid.Clear(); foreach (KeyValuePair<ZDOID, ZDO> item in ZDOMan.instance.m_objectsByID) { ZDO value = item.Value; if (value != null && value.IsValid()) { long num = value.GetLong("slink_cid", 0L); if (num != 0L) { _byCid[num] = item.Key; } } } } } internal static class ContainerIO { private struct Cached { public uint Revision; public Inventory Inventory; } private static readonly Dictionary<ZDOID, Cached> _cache = new Dictionary<ZDOID, Cached>(); private static readonly Dictionary<int, Container> _prefabs = new Dictionary<int, Container>(); public static void Reset() { _cache.Clear(); _prefabs.Clear(); } public static Container PrefabFor(ZDO zdo) { if (zdo == null || (Object)(object)ZNetScene.instance == (Object)null) { return null; } int prefab = zdo.GetPrefab(); if (_prefabs.TryGetValue(prefab, out var value)) { return value; } GameObject prefab2 = ZNetScene.instance.GetPrefab(prefab); if ((Object)(object)prefab2 == (Object)null) { return null; } value = prefab2.GetComponent<Container>(); if ((Object)(object)value != (Object)null) { _prefabs[prefab] = value; } return value; } public static Container LiveInstance(ZDO zdo) { if ((Object)(object)ZNetScene.instance == (Object)null) { return null; } if (!ZNetScene.instance.m_instances.TryGetValue(zdo, out var value)) { return null; } if (!((Object)(object)value == (Object)null)) { return ((Component)value).GetComponentInChildren<Container>(); } return null; } public static bool Open(ZDO zdo, bool forPut, out Inventory inventory, out Action commit) { //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Expected O, but got Unknown //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Expected O, but got Unknown inventory = null; commit = null; if (zdo == null || !zdo.IsValid()) { return false; } if (Links.OwnedByOther(zdo)) { return false; } Container live = LiveInstance(zdo); if ((Object)(object)live != (Object)null) { if (live.IsInUse() && (!forPut || !zdo.IsOwner())) { return false; } Inventory inventory2 = live.GetInventory(); if (inventory2 == null) { return false; } inventory = inventory2; commit = delegate { //IL_0016: Unknown result type (might be due to invalid IL or missing references) live.Save(); _cache.Remove(zdo.m_uid); }; return true; } Container val = PrefabFor(zdo); if ((Object)(object)val == (Object)null) { return false; } if (zdo.GetInt(ZDOVars.s_inUse, 0) == 1) { return false; } if (_cache.TryGetValue(zdo.m_uid, out var value) && value.Revision == zdo.DataRevision) { inventory = value.Inventory; } else { inventory = new Inventory(val.m_name, val.m_bkg, val.m_width, val.m_height); byte[] byteArray = zdo.GetByteArray(ZDOVars.s_items, (byte[])null); if (byteArray != null) { inventory.Load(new ZPackage(byteArray)); } _cache[zdo.m_uid] = new Cached { Revision = zdo.DataRevision, Inventory = inventory }; } Inventory toSave = inventory; commit = delegate { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown //IL_003e: Unknown result type (might be due to invalid IL or missing references) ZPackage val2 = new ZPackage(); toSave.Save(val2); Links.Claim(zdo); zdo.Set(ZDOVars.s_items, val2.GetArray()); _cache[zdo.m_uid] = new Cached { Revision = zdo.DataRevision, Inventory = toSave }; }; return true; } public static int Take(ZDO zdo, string prefabName, int want) { if (want <= 0) { return 0; } if (!Open(zdo, forPut: false, out var inventory, out var commit)) { return 0; } int num = 0; List<ItemData> allItems = inventory.GetAllItems(); int num2 = allItems.Count - 1; while (num2 >= 0 && num < want) { ItemData val = allItems[num2]; if (val != null && !((Object)(object)val.m_dropPrefab == (Object)null) && !(((Object)val.m_dropPrefab).name != prefabName)) { int num3 = Mathf.Min(val.m_stack, want - num); inventory.RemoveItem(val, num3); num += num3; } num2--; } if (num > 0) { commit(); } return num; } public static bool Put(ZDO zdo, string prefabName, int amount) { //IL_0055: Unknown result type (might be due to invalid IL or missing references) if (amount <= 0) { return true; } if ((Object)(object)ObjectDB.instance == (Object)null) { return false; } GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(prefabName); if ((Object)(object)itemPrefab == (Object)null) { return false; } if (!Open(zdo, forPut: true, out var inventory, out var commit)) { return false; } if (!inventory.CanAddItem(itemPrefab, amount)) { return false; } if (inventory.AddItem(prefabName, amount, 1, 0, 0L, "", new Vector2i(-1, -1), false, false, false) == null) { return false; } commit(); return true; } } internal static class LinkerTool { public const string PrefabName = "SmelterLinkRod"; private static readonly List<ZDOID> _nearby = new List<ZDOID>(); private static readonly List<ZDOID> _usage = new List<ZDOID>(); public static void Register() { PrefabManager.OnVanillaPrefabsAvailable += Create; } private static void Create() { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Expected O, but got Unknown //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Expected O, but got Unknown //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Expected O, but got Unknown //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Expected O, but got Unknown //IL_00f9: Unknown result type (might be due to invalid IL or missing references) PrefabManager.OnVanillaPrefabsAvailable -= Create; ItemConfig val = new ItemConfig(); val.Name = "Linking Rod"; val.Description = "Reveals smelter storage links. Point at a smelter and press " + LinkMode.KeyName() + " to change them."; val.CraftingStation = CraftingStations.Workbench; val.Requirements = (RequirementConfig[])(object)new RequirementConfig[3] { new RequirementConfig("Wood", 5, 0, true), new RequirementConfig("SurtlingCore", 1, 0, true), new RequirementConfig("Resin", 2, 0, true) }; ItemConfig val2 = val; CustomItem val3 = new CustomItem("SmelterLinkRod", "Club", val2); if ((Object)(object)val3.ItemDrop == (Object)null) { Plugin.Log.LogWarning((object)"Could not clone the base prefab; linker rod unavailable."); return; } SharedData shared = val3.ItemDrop.m_itemData.m_shared; shared.m_maxStackSize = 1; shared.m_weight = 1f; shared.m_maxQuality = 1; shared.m_useDurability = false; shared.m_damages = default(DamageTypes); shared.m_toolTier = 0; ItemManager.Instance.AddItem(val3); Plugin.Log.LogInfo((object)"Registered linker rod."); } public static bool InHand() { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return false; } ItemData rightItem = ((Humanoid)localPlayer).GetRightItem(); if (rightItem != null && (Object)(object)rightItem.m_dropPrefab != (Object)null) { return ((Object)rightItem.m_dropPrefab).name == "SmelterLinkRod"; } return false; } public static void Draw() { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_008c: 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_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: 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_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) if (!InHand() || ZDOMan.instance == null || !Registry.Ready) { return; } Player localPlayer = Player.m_localPlayer; Vector3 position = ((Component)localPlayer).transform.position; float value = Plugin.ToolRange.Value; float num = value * value; long num2 = FocusedChest(localPlayer); Registry.CopyInto(_nearby); for (int i = 0; i < _nearby.Count; i++) { ZDO zDO = ZDOMan.instance.GetZDO(_nearby[i]); if (zDO == null || !zDO.IsValid()) { continue; } Vector3 val = zDO.GetPosition() + Vector3.up; Vector3 val2 = val - position; if (((Vector3)(ref val2)).sqrMagnitude > num) { continue; } for (int j = 0; j < 3; j++) { Slot slot = (Slot)j; ZDO val3 = Links.Resolve(zDO, slot); if (val3 != null) { Color colour = Links.Tint(slot); bool flag = num2 != 0L && Links.GetCid(zDO, slot) != num2; colour.a = (flag ? 0.12f : 0.85f); LinkLines.Add(val, val3.GetPosition() + Vector3.up * 0.5f, colour, flag ? 0.05f : 0.1f); } } } } private static long FocusedChest(Player player) { GameObject hoverObject = ((Humanoid)player).GetHoverObject(); if ((Object)(object)hoverObject == (Object)null) { return 0L; } Container componentInParent = hoverObject.GetComponentInParent<Container>(); if ((Object)(object)componentInParent == (Object)null) { return 0L; } ZDO val = Links.ZdoOf(componentInParent); if (val != null) { return val.GetLong("slink_cid", 0L); } return 0L; } public static string DescribeChestUsage(long chest) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) if (chest == 0L || !Registry.Ready || ZDOMan.instance == null) { return null; } int num = 0; int num2 = 0; int num3 = 0; Registry.CopyInto(_usage); for (int i = 0; i < _usage.Count; i++) { ZDO zDO = ZDOMan.instance.GetZDO(_usage[i]); if (zDO != null && zDO.IsValid()) { if (Links.GetCid(zDO, Slot.Input) == chest) { num++; } if (Links.GetCid(zDO, Slot.Fuel) == chest) { num2++; } if (Links.GetCid(zDO, Slot.Output) == chest) { num3++; } } } if (num == 0 && num2 == 0 && num3 == 0) { return null; } List<string> list = new List<string>(); if (num > 0) { list.Add(Part(num, Slot.Input)); } if (num2 > 0) { list.Add(Part(num2, Slot.Fuel)); } if (num3 > 0) { list.Add(Part(num3, Slot.Output)); } return string.Join(" ", list.ToArray()); } private static string Part(int count, Slot slot) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) return "<color=#" + ColorUtility.ToHtmlStringRGB(Links.Tint(slot)) + ">" + count + " " + Links.Label(slot) + "</color>"; } } internal static class LinkLines { private static readonly List<LineRenderer> _pool = new List<LineRenderer>(); private static GameObject _root; private static Material _material; private static int _used; public static void Begin() { _used = 0; } public static void Add(Vector3 from, Vector3 to, Color colour, float width) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_002e: 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) LineRenderer val = Rent(); if (!((Object)(object)val == (Object)null)) { ((Renderer)val).enabled = true; val.startColor = colour; val.endColor = colour; val.widthMultiplier = width; val.SetPosition(0, from); val.SetPosition(1, to); } } public static void End() { for (int i = _used; i < _pool.Count; i++) { if ((Object)(object)_pool[i] != (Object)null) { ((Renderer)_pool[i]).enabled = false; } } } private static LineRenderer Rent() { //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Expected O, but got Unknown if (_used < _pool.Count) { LineRenderer result = _pool[_used]; _used++; return result; } if ((Object)(object)_root == (Object)null) { _root = new GameObject("SmelterLinkLines"); Object.DontDestroyOnLoad((Object)(object)_root); _material = new Material(Shader.Find("Sprites/Default")); } GameObject val = new GameObject("link" + _pool.Count); val.transform.SetParent(_root.transform); LineRenderer val2 = val.AddComponent<LineRenderer>(); ((Renderer)val2).material = _material; val2.positionCount = 2; val2.useWorldSpace = true; val2.numCapVertices = 4; val2.textureMode = (LineTextureMode)1; ((Renderer)val2).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)val2).receiveShadows = false; ((Renderer)val2).enabled = false; _pool.Add(val2); _used++; return val2; } public static void Shutdown() { _pool.Clear(); _used = 0; if ((Object)(object)_root != (Object)null) { Object.Destroy((Object)(object)_root); _root = null; } } } internal static class LinkMode { private static ZDOID _smelter = ZDOID.None; private static string _smelterName = ""; private static Slot _slot = Slot.Input; private static string _flash = ""; private static float _flashUntil; private static GUIStyle _panel; private static GUIStyle _title; private static GUIStyle _line; public static bool Selecting => !((ZDOID)(ref _smelter)).IsNone(); public static Slot ActiveSlot => _slot; public static string SmelterName => _smelterName; public static void Update() { //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || (Object)(object)ZNetScene.instance == (Object)null || ZDOMan.instance == null) { if (Selecting) { Cancel(); } } else { if (TypingOrInMenu()) { return; } if (Selecting) { if (Input.GetKeyDown((KeyCode)27)) { Cancel(); return; } if (Input.GetKeyDown((KeyCode)49)) { SetSlot(Slot.Input); } if (Input.GetKeyDown((KeyCode)50)) { SetSlot(Slot.Fuel); } if (Input.GetKeyDown((KeyCode)51)) { SetSlot(Slot.Output); } if (Input.GetKeyDown((KeyCode)120)) { ClearSlot(); } } KeyboardShortcut value = Plugin.LinkKey.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { HandleKey(localPlayer); } } } public static void Draw() { //IL_0014: 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) //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_0040: 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_005a: 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_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: 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_0093: Unknown result type (might be due to invalid IL or missing references) if (!Selecting || ZDOMan.instance == null) { return; } ZDO zDO = ZDOMan.instance.GetZDO(_smelter); if (zDO == null || !zDO.IsValid()) { Cancel(); return; } Vector3 val = zDO.GetPosition() + Vector3.up; for (int i = 0; i < 3; i++) { Slot slot = (Slot)i; ZDO val2 = Links.Resolve(zDO, slot); if (val2 != null) { Color colour = Links.Tint(slot); colour.a = ((slot == _slot) ? 1f : 0.3f); LinkLines.Add(val, val2.GetPosition() + Vector3.up * 0.5f, colour, (slot == _slot) ? 0.14f : 0.08f); } } } private static bool TypingOrInMenu() { if ((Object)(object)Chat.instance != (Object)null && Chat.instance.HasFocus()) { return true; } if (Menu.IsVisible()) { return true; } if (InventoryGui.IsVisible()) { return true; } if (TextInput.IsVisible()) { return true; } return false; } private static void HandleKey(Player player) { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) GameObject hoverObject = ((Humanoid)player).GetHoverObject(); if (Selecting) { if ((Object)(object)hoverObject != (Object)null) { Container componentInParent = hoverObject.GetComponentInParent<Container>(); if ((Object)(object)componentInParent != (Object)null) { Bind(componentInParent); return; } } Cancel(); } else { if ((Object)(object)hoverObject == (Object)null) { return; } Smelter componentInParent2 = hoverObject.GetComponentInParent<Smelter>(); if (!((Object)(object)componentInParent2 == (Object)null)) { ZDO val = Links.ZdoOf(componentInParent2); if (val != null) { _smelter = val.m_uid; _smelterName = Localization.instance.Localize(componentInParent2.m_name); _slot = SlotForHover(componentInParent2, hoverObject); Flash("Select " + Links.Label(_slot).ToUpper() + " chest"); } } } } public static Slot SlotForHover(Smelter smelter, GameObject hovering) { Switch val = (((Object)(object)hovering == (Object)null) ? null : hovering.GetComponentInParent<Switch>()); if ((Object)(object)val != (Object)null) { if ((Object)(object)smelter.m_addWoodSwitch != (Object)null && (Object)(object)val == (Object)(object)smelter.m_addWoodSwitch) { return Slot.Fuel; } if ((Object)(object)smelter.m_emptyOreSwitch != (Object)null && (Object)(object)val == (Object)(object)smelter.m_emptyOreSwitch) { return Slot.Output; } } return Slot.Input; } private static void Bind(Container container) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0058: 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) ZDO zDO = ZDOMan.instance.GetZDO(_smelter); if (zDO == null || !zDO.IsValid()) { Cancel(); return; } ZDO val = Links.ZdoOf(container); if (val != null && !(val.m_uid == _smelter)) { Links.Set(zDO, _slot, val); Registry.Track(zDO); Patches.CacheEnvironment(zDO); float num = Vector3.Distance(zDO.GetPosition(), val.GetPosition()); string text = Localization.instance.Localize(container.m_name); Message(Links.Label(_slot).ToUpper() + " set to " + text + " (" + num.ToString("0") + "m)"); Flash(Links.Label(_slot).ToUpper() + " set"); } } private static void SetSlot(Slot slot) { _slot = slot; Flash("Select " + Links.Label(slot).ToUpper() + " chest"); } private static void ClearSlot() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) ZDO zDO = ZDOMan.instance.GetZDO(_smelter); if (zDO != null) { Links.Clear(zDO, _slot); if (!Links.HasAny(zDO)) { Registry.Forget(zDO.m_uid); } Message(Links.Label(_slot).ToUpper() + " cleared"); Flash(Links.Label(_slot).ToUpper() + " cleared"); } } private static void Cancel() { //IL_0000: 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) _smelter = ZDOID.None; _smelterName = ""; } public static void CancelFromOutside() { if (Selecting) { Cancel(); Message("Marking cancelled"); } } public static string KeyName() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //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) KeyboardShortcut value = Plugin.LinkKey.Value; return ((object)((KeyboardShortcut)(ref value)).MainKey/*cast due to .constrained prefix*/).ToString(); } private static void Message(string text) { if ((Object)(object)MessageHud.instance != (Object)null) { MessageHud.instance.ShowMessage((MessageType)2, text, 0, (Sprite)null, false, true); } } private static void Flash(string text) { _flash = text; _flashUntil = Time.time + 2f; } public static void DrawGui() { //IL_0019: 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_009a: Unknown result type (might be due to invalid IL or missing references) //IL_0204: Unknown result type (might be due to invalid IL or missing references) //IL_0116: 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_015a: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) if (!Selecting) { return; } EnsureStyles(); ZDO val = ((ZDOMan.instance == null) ? null : ZDOMan.instance.GetZDO(_smelter)); if (val == null) { return; } float num = 520f; float num2 = 150f; float num3 = ((float)Screen.width - num) * 0.5f; Rect val2 = default(Rect); ((Rect)(ref val2))..ctor(num3, 60f, num, num2); GUI.Box(val2, GUIContent.none, _panel); GUILayout.BeginArea(new Rect(((Rect)(ref val2)).x + 16f, ((Rect)(ref val2)).y + 12f, ((Rect)(ref val2)).width - 32f, ((Rect)(ref val2)).height - 24f)); GUILayout.Label("Marking storage for " + _smelterName, _title, Array.Empty<GUILayoutOption>()); for (int i = 0; i < 3; i++) { Slot slot = (Slot)i; ZDO val3 = Links.Resolve(val, slot); string text; if (val3 == null) { text = "not set"; } else { Container val4 = ContainerIO.PrefabFor(val3); text = (((Object)(object)val4 == (Object)null) ? "chest" : Localization.instance.Localize(val4.m_name)) + " (" + Vector3.Distance(val.GetPosition(), val3.GetPosition()).ToString("0") + "m)"; } string text2 = ((slot == _slot) ? "> " : " "); Color textColor = Links.Tint(slot); if (slot != _slot) { textColor.a = 0.55f; } _line.normal.textColor = textColor; GUILayout.Label(text2 + "[" + (i + 1) + "] " + Links.Label(slot) + ": " + text, _line, Array.Empty<GUILayoutOption>()); } _line.normal.textColor = new Color(0.85f, 0.85f, 0.85f); string text3 = "Look at a chest and press " + KeyName() + " · [X] clear · [Esc] cancel"; if (Time.time < _flashUntil) { text3 = _flash + " — " + text3; } GUILayout.Label(text3, _line, Array.Empty<GUILayoutOption>()); GUILayout.EndArea(); } private static void EnsureStyles() { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Expected O, but got Unknown //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Expected O, but got Unknown //IL_0090: 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_00ae: Expected O, but got Unknown if (_panel == null) { Texture2D val = new Texture2D(1, 1); val.SetPixel(0, 0, new Color(0f, 0f, 0f, 0.75f)); val.Apply(); _panel = new GUIStyle(GUI.skin.box); _panel.normal.background = val; _title = new GUIStyle(GUI.skin.label); _title.fontSize = 16; _title.fontStyle = (FontStyle)1; _title.normal.textColor = Color.white; _line = new GUIStyle(GUI.skin.label); _line.fontSize = 14; } } public static void Shutdown() { Cancel(); } } internal enum Slot { Input, Fuel, Output } internal static class Links { public const string ChestId = "slink_cid"; public const string HaveRoof = "slink_roof"; public const string BlockedSmoke = "slink_smoke"; public const string WindPower = "slink_wind"; private const string LegacyInput = "slink_in"; private const string LegacyFuel = "slink_fuel"; private const string LegacyOutput = "slink_out"; public static string Label(Slot slot) { return slot switch { Slot.Input => "input", Slot.Fuel => "fuel", _ => "output", }; } public static Color Tint(Slot slot) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_002d: 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) return (Color)(slot switch { Slot.Input => new Color(0.35f, 0.75f, 1f), Slot.Fuel => new Color(1f, 0.6f, 0.2f), _ => new Color(0.45f, 0.95f, 0.5f), }); } private static string CidKey(Slot slot) { return slot switch { Slot.Input => "slink_in_cid", Slot.Fuel => "slink_fuel_cid", _ => "slink_out_cid", }; } public static bool OwnedByOther(ZDO zdo) { if (zdo != null && zdo.HasOwner()) { return !zdo.IsOwner(); } return false; } public static void Claim(ZDO zdo) { if (zdo != null && !zdo.IsOwner() && !zdo.HasOwner()) { zdo.SetOwner(ZDOMan.instance.m_sessionID); } } public static long GetCid(ZDO smelter, Slot slot) { if (smelter != null) { return smelter.GetLong(CidKey(slot), 0L); } return 0L; } public static bool HasAny(ZDO zdo) { if (zdo == null) { return false; } if (GetCid(zdo, Slot.Input) == 0L && GetCid(zdo, Slot.Fuel) == 0L) { return GetCid(zdo, Slot.Output) != 0; } return true; } public static bool HasLegacyOnly(ZDO zdo) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) if (zdo == null || HasAny(zdo)) { return false; } ZDOID zDOID = zdo.GetZDOID("slink_in"); if (((ZDOID)(ref zDOID)).IsNone()) { zDOID = zdo.GetZDOID("slink_fuel"); if (((ZDOID)(ref zDOID)).IsNone()) { zDOID = zdo.GetZDOID("slink_out"); return !((ZDOID)(ref zDOID)).IsNone(); } } return true; } public static long EnsureChestId(ZDO chest) { //IL_0013: 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) long num = chest.GetLong("slink_cid", 0L); if (num != 0L) { ChestIndex.Register(num, chest.m_uid); return num; } num = Utils.GenerateUID(); if (num == 0L) { num = 1L; } if (!chest.IsOwner()) { chest.SetOwner(ZDOMan.instance.m_sessionID); } chest.Set("slink_cid", num); ChestIndex.Register(num, chest.m_uid); return num; } public static void Set(ZDO smelter, Slot slot, ZDO chest) { if (smelter != null && chest != null) { long num = EnsureChestId(chest); Claim(smelter); smelter.Set(CidKey(slot), num); } } public static void Clear(ZDO smelter, Slot slot) { if (smelter != null) { Claim(smelter); smelter.Set(CidKey(slot), 0L); } } public static ZDO Resolve(ZDO smelter, Slot slot) { long cid = GetCid(smelter, slot); if (cid == 0L) { return null; } ZDO val = ChestIndex.Find(cid); if (val == null) { return null; } if (!((Object)(object)ContainerIO.PrefabFor(val) == (Object)null)) { return val; } return null; } public static ZDO ZdoOf(Container container) { if ((Object)(object)container == (Object)null || (Object)(object)container.m_nview == (Object)null) { return null; } if (!container.m_nview.IsValid()) { return null; } return container.m_nview.GetZDO(); } public static ZDO ZdoOf(Smelter smelter) { if ((Object)(object)smelter == (Object)null || (Object)(object)smelter.m_nview == (Object)null) { return null; } if (!smelter.m_nview.IsValid()) { return null; } return smelter.m_nview.GetZDO(); } } [HarmonyPatch] internal static class Patches { public static void CacheEnvironment(ZDO zdo) { if (ZNetScene.instance.m_instances.TryGetValue(zdo, out var value) && !((Object)(object)value == (Object)null)) { Smelter componentInChildren = ((Component)value).GetComponentInChildren<Smelter>(); if ((Object)(object)componentInChildren != (Object)null) { CacheEnvironment(componentInChildren, zdo); } } } private static void CacheEnvironment(Smelter smelter, ZDO zdo) { zdo.Set("slink_roof", smelter.m_haveRoof); zdo.Set("slink_smoke", smelter.m_blockedSmoke); if ((Object)(object)smelter.m_windmill != (Object)null) { zdo.Set("slink_wind", smelter.m_windmill.GetPowerOutput()); } } [HarmonyPostfix] [HarmonyPatch(typeof(Smelter), "UpdateSmelter")] private static void SmelterTicked(Smelter __instance) { ZNetView nview = __instance.m_nview; if (!((Object)(object)nview == (Object)null) && nview.IsValid() && nview.IsOwner()) { ZDO zDO = nview.GetZDO(); if (Links.HasAny(zDO)) { Registry.Track(zDO); CacheEnvironment(__instance, zDO); SmelterOps.FeedFuel(zDO, __instance); SmelterOps.FeedOre(zDO, __instance); } } } [HarmonyPrefix] [HarmonyPatch(typeof(Smelter), "Spawn")] private static bool SmelterSpawn(Smelter __instance, string ore, int stack) { //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) ZNetView nview = __instance.m_nview; if ((Object)(object)nview == (Object)null || !nview.IsValid()) { return true; } ZDO val = Links.Resolve(nview.GetZDO(), Slot.Output); if (val == null) { return true; } ItemConversion val2 = SmelterOps.ConversionFor(__instance, ore); if (val2 == null || (Object)(object)val2.m_to == (Object)null) { return true; } if (!ContainerIO.Put(val, ((Object)((Component)val2.m_to).gameObject).name, stack)) { return true; } __instance.m_produceEffects.Create(((Component)__instance).transform.position, ((Component)__instance).transform.rotation, (Transform)null, 1f, -1, default(ZDOID)); return false; } [HarmonyPostfix] [HarmonyPatch(typeof(Smelter), "OnHoverAddOre")] private static void HoverOre(Smelter __instance, ref string __result) { __result = Append(__instance, __result, Slot.Input); } [HarmonyPostfix] [HarmonyPatch(typeof(Smelter), "OnHoverAddFuel")] private static void HoverFuel(Smelter __instance, ref string __result) { __result = Append(__instance, __result, Slot.Fuel); } [HarmonyPostfix] [HarmonyPatch(typeof(Smelter), "OnHoverEmptyOre")] private static void HoverEmpty(Smelter __instance, ref string __result) { __result = Append(__instance, __result, Slot.Output); } private static string Append(Smelter smelter, string text, Slot slot) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) ZNetView nview = smelter.m_nview; if ((Object)(object)nview == (Object)null || !nview.IsValid()) { return text; } ZDO zDO = nview.GetZDO(); ZDO val = Links.Resolve(zDO, slot); string text2 = LinkMode.KeyName(); string text3 = Links.Label(slot); string text4 = ColorUtility.ToHtmlStringRGB(Links.Tint(slot)); if (val == null) { return text + "\n[<color=yellow><b>" + text2 + "</b></color>] Select " + text3 + " chest"; } Container val2 = ContainerIO.PrefabFor(val); string text5 = (((Object)(object)val2 == (Object)null) ? "chest" : Localization.instance.Localize(val2.m_name)); float num = Vector3.Distance(zDO.GetPosition(), val.GetPosition()); string text6 = "\n<color=#" + text4 + ">" + text3 + ": " + text5 + " (" + num.ToString("0") + "m)</color>"; text6 = text6 + "\n[<color=yellow><b>" + text2 + "</b></color>] Change " + text3 + " chest"; if (slot == Slot.Output) { return text + text6; } if (Links.Resolve(zDO, Slot.Output) == null) { text6 += "\n<color=#b0b0b0>No output chest — will not run while you are away</color>"; } return text + text6; } [HarmonyPostfix] [HarmonyPatch(typeof(Container), "GetHoverText")] private static void HoverContainer(Container __instance, ref string __result) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) if (LinkMode.Selecting) { string text = Links.Label(LinkMode.ActiveSlot).ToUpper(); string text2 = ColorUtility.ToHtmlStringRGB(Links.Tint(LinkMode.ActiveSlot)); __result = __result + "\n[<color=yellow><b>" + LinkMode.KeyName() + "</b></color>] Set as <color=#" + text2 + ">" + text + "</color> for " + LinkMode.SmelterName; } else if (LinkerTool.InHand()) { ZDO val = Links.ZdoOf(__instance); if (val != null) { string text3 = LinkerTool.DescribeChestUsage(val.GetLong("slink_cid", 0L)); __result += ((text3 == null) ? "\n<color=#808080>Not linked to any smelter</color>" : ("\nFeeds: " + text3)); } } } [HarmonyPostfix] [HarmonyPatch(typeof(Player), "TakeInput")] private static void BlockActionsWhileMarking(ref bool __result) { if (Plugin.BlockInputWhileMarking.Value && LinkMode.Selecting) { __result = false; } } [HarmonyPrefix] [HarmonyPatch(typeof(Menu), "Update")] private static bool BlockMenuWhileMarking() { if (Plugin.BlockInputWhileMarking.Value) { return !LinkMode.Selecting; } return true; } [HarmonyPostfix] [HarmonyPatch(typeof(Character), "Damage")] private static void CancelMarkingOnDamage(Character __instance) { if (Plugin.CancelMarkingOnDamage.Value && LinkMode.Selecting && (Object)(object)__instance != (Object)null && (Object)(object)__instance == (Object)(object)Player.m_localPlayer) { LinkMode.CancelFromOutside(); } } [HarmonyPostfix] [HarmonyPatch(typeof(ZNet), "Shutdown")] private static void NetShutdown() { Registry.Reset(); LinkMode.Shutdown(); } } internal static class Registry { private static readonly HashSet<ZDOID> _linked = new HashSet<ZDOID>(); private static readonly Dictionary<int, Smelter> _smelterPrefabs = new Dictionary<int, Smelter>(); public static bool Ready { get; private set; } public static int Count => _linked.Count; public static void Reset() { _linked.Clear(); _smelterPrefabs.Clear(); ContainerIO.Reset(); ChestIndex.Reset(); Ready = false; } public static Smelter PrefabFor(ZDO zdo) { if (zdo == null || (Object)(object)ZNetScene.instance == (Object)null) { return null; } int prefab = zdo.GetPrefab(); if (_smelterPrefabs.TryGetValue(prefab, out var value)) { return value; } GameObject prefab2 = ZNetScene.instance.GetPrefab(prefab); if ((Object)(object)prefab2 == (Object)null) { return null; } value = prefab2.GetComponent<Smelter>(); if ((Object)(object)value != (Object)null) { _smelterPrefabs[prefab] = value; } return value; } public static void Track(ZDO zdo) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) if (zdo != null && zdo.IsValid()) { _linked.Add(zdo.m_uid); } } public static void Forget(ZDOID id) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) _linked.Remove(id); } public static void Rebuild() { //IL_0081: Unknown result type (might be due to invalid IL or missing references) _linked.Clear(); ContainerIO.Reset(); if (ZDOMan.instance == null || (Object)(object)ZNetScene.instance == (Object)null) { return; } ChestIndex.Rescan(force: true); int num = 0; int num2 = 0; foreach (KeyValuePair<ZDOID, ZDO> item in ZDOMan.instance.m_objectsByID) { ZDO value = item.Value; if (value == null || !value.IsValid()) { continue; } num++; if (!((Object)(object)PrefabFor(value) == (Object)null)) { if (Links.HasAny(value)) { _linked.Add(item.Key); } else if (Links.HasLegacyOnly(value)) { num2++; } } } Ready = true; Plugin.Log.LogInfo((object)("Scanned " + num + " ZDOs: " + _linked.Count + " linked smelter(s), " + ChestIndex.Count + " marked chest(s).")); if (num2 > 0) { Plugin.Log.LogWarning((object)(num2 + " smelter(s) still carry 0.2.0 links. Those were stored in a form that does not survive a world reload and cannot be converted safely — mark those smelters again.")); } } public static void CopyInto(List<ZDOID> target) { target.Clear(); target.AddRange(_linked); } } internal static class SmelterOps { public static int QueueSize(ZDO zdo) { return zdo.GetInt(ZDOVars.s_queued, 0); } public static string QueuedOre(ZDO zdo) { if (QueueSize(zdo) != 0) { return zdo.GetString(ZDOVars.s_item0, ""); } return ""; } public static void QueueOre(ZDO zdo, string prefabName) { int num = QueueSize(zdo); zdo.Set("item" + num, prefabName); zdo.Set(ZDOVars.s_queued, num + 1, false); } public static void RemoveOneOre(ZDO zdo) { int num = QueueSize(zdo); if (num != 0) { for (int i = 0; i < num; i++) { zdo.Set("item" + i, zdo.GetString("item" + (i + 1), "")); } zdo.Set(ZDOVars.s_queued, num - 1, false); } } public static ItemConversion ConversionFor(Smelter prefab, string oreName) { for (int i = 0; i < prefab.m_conversion.Count; i++) { ItemConversion val = prefab.m_conversion[i]; if ((Object)(object)val.m_from != (Object)null && ((Object)((Component)val.m_from).gameObject).name == oreName) { return val; } } return null; } public static int FeedFuel(ZDO zdo, Smelter prefab) { if (prefab.m_maxFuel <= 0 || (Object)(object)prefab.m_fuelItem == (Object)null) { return 0; } ZDO val = Links.Resolve(zdo, Slot.Fuel); if (val == null) { return 0; } float num = zdo.GetFloat(ZDOVars.s_fuel, 0f); int num2 = Mathf.FloorToInt((float)prefab.m_maxFuel - num); if (num2 <= 0) { return 0; } int num3 = ContainerIO.Take(val, ((Object)((Component)prefab.m_fuelItem).gameObject).name, num2); if (num3 > 0) { Links.Claim(zdo); zdo.Set(ZDOVars.s_fuel, num + (float)num3); } return num3; } public static int FeedOre(ZDO zdo, Smelter prefab) { if (prefab.m_maxOre <= 0) { return 0; } ZDO val = Links.Resolve(zdo, Slot.Input); if (val == null) { return 0; } int num = prefab.m_maxOre - QueueSize(zdo); if (num <= 0) { return 0; } int num2 = 0; for (int i = 0; i < prefab.m_conversion.Count; i++) { if (num <= 0) { break; } ItemConversion val2 = prefab.m_conversion[i]; if ((Object)(object)val2.m_from == (Object)null) { continue; } string name = ((Object)((Component)val2.m_from).gameObject).name; int num3 = ContainerIO.Take(val, name, num); if (num3 > 0) { Links.Claim(zdo); for (int j = 0; j < num3; j++) { QueueOre(zdo, name); } num -= num3; num2 += num3; } } return num2; } public static bool FlushPendingOutput(ZDO zdo, Smelter prefab) { int num = zdo.GetInt(ZDOVars.s_spawnAmount, 0); if (num <= 0) { return false; } ZDO val = Links.Resolve(zdo, Slot.Output); if (val == null) { return false; } string oreName = zdo.GetString(ZDOVars.s_spawnOre, ""); ItemConversion val2 = ConversionFor(prefab, oreName); if (val2 == null || (Object)(object)val2.m_to == (Object)null) { return false; } if (!ContainerIO.Put(val, ((Object)((Component)val2.m_to).gameObject).name, num)) { return false; } Links.Claim(zdo); zdo.Set(ZDOVars.s_spawnOre, ""); zdo.Set(ZDOVars.s_spawnAmount, 0, false); return true; } public static int Simulate(ZDO zdo, Smelter prefab) { if (prefab.m_secPerProduct <= 0f) { return 0; } ZDO val = Links.Resolve(zdo, Slot.Output); if (val == null) { return 0; } DateTime time = ZNet.instance.GetTime(); long ticks = zdo.GetLong(ZDOVars.s_startTime, time.Ticks); double totalSeconds = (time - new DateTime(ticks)).TotalSeconds; if (totalSeconds <= 0.0) { return 0; } Links.Claim(zdo); zdo.Set(ZDOVars.s_startTime, time.Ticks); float num = zdo.GetFloat(ZDOVars.s_accTime, 0f) + (float)totalSeconds; float value = Plugin.MaxCatchupSeconds.Value; if (num > value) { num = value; } bool flag = zdo.GetBool("slink_roof", true); bool flag2 = zdo.GetBool("slink_smoke", false); float num2 = (Object.op_Implicit((Object)(object)prefab.m_windmill) ? zdo.GetFloat("slink_wind", 1f) : 1f); int num3 = 0; while (num >= 1f) { num -= 1f; float num4 = zdo.GetFloat(ZDOVars.s_fuel, 0f); string text = QueuedOre(zdo); if ((prefab.m_maxFuel != 0 && !(num4 > 0f)) || (prefab.m_maxOre != 0 && text == "") || (prefab.m_requiresRoof && !flag) || flag2) { continue; } ItemConversion val2 = ConversionFor(prefab, text); if (val2 == null || (Object)(object)val2.m_to == (Object)null) { num += 1f; break; } float num5 = 1f * num2; float num6 = zdo.GetFloat(ZDOVars.s_bakeTimer, 0f) + num5; if (num6 >= prefab.m_secPerProduct) { if (!ContainerIO.Put(val, ((Object)((Component)val2.m_to).gameObject).name, 1)) { num += 1f; break; } zdo.Set(ZDOVars.s_bakeTimer, 0f); RemoveOneOre(zdo); num3++; } else { zdo.Set(ZDOVars.s_bakeTimer, num6); } if (prefab.m_maxFuel > 0) { float num7 = prefab.m_secPerProduct / (float)prefab.m_fuelPerProduct; num4 -= num5 / num7; if (num4 < 0.0001f) { num4 = 0f; } zdo.Set(ZDOVars.s_fuel, num4); } } zdo.Set(ZDOVars.s_accTime, num); return num3; } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { internal IgnoresAccessChecksToAttribute(string assemblyName) { } } }