Decompiled source of CookBook v1.3.0

CookBook.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using CookBook;
using HG;
using Microsoft.CodeAnalysis;
using On.RoR2;
using On.RoR2.UI;
using RiskOfOptions;
using RiskOfOptions.OptionConfigs;
using RiskOfOptions.Options;
using RoR2;
using RoR2.ContentManagement;
using RoR2.Items;
using RoR2.UI;
using TMPro;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.Networking;
using UnityEngine.TextCore;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("CookBook")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+fefb1988c131394451d183c0c2b0ce006f1bb8aa")]
[assembly: AssemblyProduct("CookBook")]
[assembly: AssemblyTitle("CookBook")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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;
		}
	}
}
internal static class RecipeFilter
{
	public enum RecipeFilterCategory
	{
		All,
		Damage,
		Healing,
		Utility
	}

	public static RecipeFilterCategory CurrentCategory = RecipeFilterCategory.All;

	private static readonly Dictionary<RecipeFilterCategory, ItemTag> CategoryToTag = new Dictionary<RecipeFilterCategory, ItemTag>
	{
		{
			RecipeFilterCategory.Damage,
			(ItemTag)1
		},
		{
			RecipeFilterCategory.Healing,
			(ItemTag)2
		},
		{
			RecipeFilterCategory.Utility,
			(ItemTag)3
		}
	};

	public static void ApplyFiltersToUI(List<CraftUI.RecipeRowUI> rows, string searchTerm)
	{
		if (rows == null)
		{
			return;
		}
		string text = searchTerm?.Trim().ToLowerInvariant();
		foreach (CraftUI.RecipeRowUI row in rows)
		{
			if (!((Object)(object)row.RowGO == (Object)null))
			{
				bool flag = string.IsNullOrEmpty(text) || EntryMatchesSearch(row.Entry, text);
				bool flag2 = EntryMatchesFilter(row.Entry);
				row.RowGO.SetActive(flag && flag2);
			}
		}
	}

	public static void CycleCategory()
	{
		int num = (int)(CurrentCategory + 1);
		if (num > 3)
		{
			num = 0;
		}
		CurrentCategory = (RecipeFilterCategory)num;
	}

	public static string GetLabel()
	{
		return CurrentCategory switch
		{
			RecipeFilterCategory.Damage => "<size=150%><sprite name=\"icon\"></size> DMG", 
			RecipeFilterCategory.Healing => "<size=150%><sprite name=\"icon\"></size> HEAL", 
			RecipeFilterCategory.Utility => "<size=150%><sprite name=\"icon\"></size> UTIL", 
			_ => "ALL", 
		};
	}

	private static bool EntryMatchesFilter(CraftPlanner.CraftableEntry entry)
	{
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		if (entry == null)
		{
			return false;
		}
		if (CurrentCategory == RecipeFilterCategory.All)
		{
			return true;
		}
		int resultIndex = entry.ResultIndex;
		if (resultIndex < 0)
		{
			return false;
		}
		if (resultIndex >= ItemCatalog.itemCount)
		{
			return true;
		}
		ItemDef itemDef = ItemCatalog.GetItemDef((ItemIndex)resultIndex);
		if ((Object)(object)itemDef != (Object)null)
		{
			return itemDef.ContainsTag(CategoryToTag[CurrentCategory]);
		}
		return false;
	}

	private static bool EntryMatchesSearch(CraftPlanner.CraftableEntry entry, string term)
	{
		if (string.IsNullOrEmpty(term))
		{
			return true;
		}
		if (entry == null)
		{
			return false;
		}
		string entryDisplayName = CraftUI.GetEntryDisplayName(entry);
		if (!string.IsNullOrEmpty(entryDisplayName))
		{
			return entryDisplayName.IndexOf(term, StringComparison.OrdinalIgnoreCase) >= 0;
		}
		return false;
	}

	public static void PatchVanillaNRE(orig_FilterAvailableOptions orig, CraftingController self)
	{
		NetworkUIPromptController component = ((Component)self).GetComponent<NetworkUIPromptController>();
		if (!((Object)(object)component == (Object)null) && !((Object)(object)component.currentParticipantMaster == (Object)null))
		{
			orig.Invoke(self);
		}
	}
}
namespace CookBook
{
	internal static class ChatNetworkHandler
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static hook_AddMessage_string <0>__OnAddMessage;

			public static hook_OnProcessed <1>__OnUserChatMessageProcessed;
		}

		[CompilerGenerated]
		private sealed class <CheckAckTimeout>d__12 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public NetworkUser target;

			public int idx;

			public int qty;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <CheckAckTimeout>d__12(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: Expected O, but got Unknown
				//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)
				//IL_0061: Unknown result type (might be due to invalid IL or missing references)
				//IL_0066: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(2f);
					<>1__state = 1;
					return true;
				case 1:
				{
					<>1__state = -1;
					Dictionary<uint, float> pendingAcks = _pendingAcks;
					NetworkInstanceId netId = ((NetworkBehaviour)target).netId;
					if (pendingAcks.ContainsKey(((NetworkInstanceId)(ref netId)).Value))
					{
						Dictionary<uint, float> pendingAcks2 = _pendingAcks;
						netId = ((NetworkBehaviour)target).netId;
						pendingAcks2.Remove(((NetworkInstanceId)(ref netId)).Value);
						DebugLog.Trace(_log, "[Net] No ACK from " + target.userName + ". Falling back to raw text.");
						SendRawTextFallback(target, idx, qty);
					}
					return false;
				}
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		private const string NetPrefix = "CB_NET:";

		private static ManualLogSource _log;

		private static bool _enabled;

		private static readonly Dictionary<uint, float> _pendingAcks = new Dictionary<uint, float>();

		private const float AckTimeout = 2f;

		internal static event Action<NetworkUser, string, int, int> OnIncomingObjective;

		internal static void Init(ManualLogSource log)
		{
			//IL_0024: 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_002f: Expected O, but got Unknown
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Expected O, but got Unknown
			_log = log;
			if (!_enabled)
			{
				_enabled = true;
				object obj = <>O.<0>__OnAddMessage;
				if (obj == null)
				{
					hook_AddMessage_string val = OnAddMessage;
					<>O.<0>__OnAddMessage = val;
					obj = (object)val;
				}
				Chat.AddMessage_string += (hook_AddMessage_string)obj;
				object obj2 = <>O.<1>__OnUserChatMessageProcessed;
				if (obj2 == null)
				{
					hook_OnProcessed val2 = OnUserChatMessageProcessed;
					<>O.<1>__OnUserChatMessageProcessed = val2;
					obj2 = (object)val2;
				}
				UserChatMessage.OnProcessed += (hook_OnProcessed)obj2;
			}
		}

		internal static void ShutDown()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Expected O, but got Unknown
			if (_enabled)
			{
				_enabled = false;
				object obj = <>O.<0>__OnAddMessage;
				if (obj == null)
				{
					hook_AddMessage_string val = OnAddMessage;
					<>O.<0>__OnAddMessage = val;
					obj = (object)val;
				}
				Chat.AddMessage_string -= (hook_AddMessage_string)obj;
				object obj2 = <>O.<1>__OnUserChatMessageProcessed;
				if (obj2 == null)
				{
					hook_OnProcessed val2 = OnUserChatMessageProcessed;
					<>O.<1>__OnUserChatMessageProcessed = val2;
					obj2 = (object)val2;
				}
				UserChatMessage.OnProcessed -= (hook_OnProcessed)obj2;
			}
		}

		private static void OnUserChatMessageProcessed(orig_OnProcessed orig, UserChatMessage self)
		{
			if (self.text == null || !self.text.Contains("CB_NET:"))
			{
				orig.Invoke(self);
			}
		}

		public static void SendObjectiveRequest(NetworkUser target, string command, int unifiedIdx, int quantity)
		{
			//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)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			if (_enabled && !((Object)(object)target == (Object)null))
			{
				LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser();
				NetworkUser val = ((firstLocalUser != null) ? firstLocalUser.currentNetworkUser : null);
				if (Object.op_Implicit((Object)(object)val))
				{
					object[] obj = new object[6] { "CB_NET:", null, null, null, null, null };
					NetworkInstanceId netId = ((NetworkBehaviour)val).netId;
					obj[1] = ((NetworkInstanceId)(ref netId)).Value;
					netId = ((NetworkBehaviour)target).netId;
					obj[2] = ((NetworkInstanceId)(ref netId)).Value;
					obj[3] = command;
					obj[4] = unifiedIdx;
					obj[5] = quantity;
					string text = string.Format("{0}{1}:{2}:{3}:{4}:{5}", obj);
					DebugLog.Trace(_log, "[Net Out] Sending packet to " + target.userName + ": " + text);
					Console.instance.SubmitCmd(val, "say \"" + text + "\"", false);
					Dictionary<uint, float> pendingAcks = _pendingAcks;
					netId = ((NetworkBehaviour)target).netId;
					pendingAcks[((NetworkInstanceId)(ref netId)).Value] = Time.time;
					((MonoBehaviour)RoR2Application.instance).StopCoroutine("CheckAckTimeout");
					((MonoBehaviour)RoR2Application.instance).StartCoroutine(CheckAckTimeout(target, unifiedIdx, quantity));
				}
			}
		}

		[IteratorStateMachine(typeof(<CheckAckTimeout>d__12))]
		private static IEnumerator CheckAckTimeout(NetworkUser target, int idx, int qty)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <CheckAckTimeout>d__12(0)
			{
				target = target,
				idx = idx,
				qty = qty
			};
		}

		private static void SendRawTextFallback(NetworkUser target, int unifiedIdx, int qty)
		{
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Expected O, but got Unknown
			//IL_00b6: 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_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser();
			if (!Object.op_Implicit((Object)(object)((firstLocalUser != null) ? firstLocalUser.currentNetworkUser : null)) || (Object)(object)target == (Object)null)
			{
				return;
			}
			string text = "Unknown Item";
			string text2 = "ffffff";
			if (unifiedIdx < ItemCatalog.itemCount)
			{
				ItemDef itemDef = ItemCatalog.GetItemDef((ItemIndex)unifiedIdx);
				if ((Object)(object)itemDef != (Object)null)
				{
					text = Language.currentLanguage.GetLocalizedStringByToken(itemDef.nameToken);
					ItemTierDef itemTierDef = ItemTierCatalog.GetItemTierDef(itemDef.tier);
					ColorCatalog.GetColor(itemTierDef.colorIndex);
					if ((Object)(object)itemTierDef != (Object)null)
					{
						text2 = ColorCatalog.GetColorHexString(itemTierDef.colorIndex);
					}
				}
			}
			else
			{
				EquipmentDef equipmentDef = EquipmentCatalog.GetEquipmentDef((EquipmentIndex)(unifiedIdx - ItemCatalog.itemCount));
				if ((Object)(object)equipmentDef != (Object)null)
				{
					text = Language.currentLanguage.GetLocalizedStringByToken(equipmentDef.nameToken);
					text2 = ColorCatalog.GetColorHexString(equipmentDef.colorIndex);
				}
			}
			string text3 = $"<color=#d299ff>[CookBook]</color> @{target.userName}, I'm looking for ({qty}) <color=#{text2}>{text}</color>!";
			SimpleChatMessage val = new SimpleChatMessage();
			val.baseToken = "{0}";
			val.paramTokens = new string[1] { text3 };
			Chat.SendBroadcastChat((ChatMessageBase)(object)val);
		}

		private static void SendAck(uint senderID, string originalCmd)
		{
			//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)
			LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser();
			NetworkUser val = ((firstLocalUser != null) ? firstLocalUser.currentNetworkUser : null);
			object[] obj = new object[4] { "CB_NET:", null, null, null };
			NetworkInstanceId netId = ((NetworkBehaviour)val).netId;
			obj[1] = ((NetworkInstanceId)(ref netId)).Value;
			obj[2] = senderID;
			obj[3] = originalCmd;
			string text = string.Format("{0}{1}:{2}:ACK:{3}:0", obj);
			Console.instance.SubmitCmd(val, "say \"" + text + "\"", false);
		}

		public static void SendGlobalAbort()
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			if (_enabled)
			{
				LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser();
				NetworkUser val = ((firstLocalUser != null) ? firstLocalUser.currentNetworkUser : null);
				if (Object.op_Implicit((Object)(object)val))
				{
					NetworkInstanceId netId = ((NetworkBehaviour)val).netId;
					string text = string.Format("{0}{1}:0:ABORT:0:0", "CB_NET:", ((NetworkInstanceId)(ref netId)).Value);
					DebugLog.Trace(_log, "[Net Out] Sending Global Abort: " + text);
					Console.instance.SubmitCmd(val, "say \"" + text + "\"", false);
				}
			}
		}

		public static void SendObjectiveSuccess(NetworkUser target, int unifiedIdx)
		{
			//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)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			if (_enabled && !((Object)(object)target == (Object)null))
			{
				LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser();
				NetworkUser val = ((firstLocalUser != null) ? firstLocalUser.currentNetworkUser : null);
				if (Object.op_Implicit((Object)(object)val))
				{
					object[] obj = new object[4] { "CB_NET:", null, null, null };
					NetworkInstanceId netId = ((NetworkBehaviour)val).netId;
					obj[1] = ((NetworkInstanceId)(ref netId)).Value;
					netId = ((NetworkBehaviour)target).netId;
					obj[2] = ((NetworkInstanceId)(ref netId)).Value;
					obj[3] = unifiedIdx;
					string text = string.Format("{0}{1}:{2}:SUCCESS:{3}:0", obj);
					DebugLog.Trace(_log, $"[Net Out] Sending Success signal to {target.userName} for item {unifiedIdx}");
					Console.instance.SubmitCmd(val, "say \"" + text + "\"", false);
				}
			}
		}

		private static void OnAddMessage(orig_AddMessage_string orig, string message)
		{
			if (_enabled && message.Contains("CB_NET:"))
			{
				int num = message.IndexOf("CB_NET:");
				ParseAndProcess(message.Substring(num + "CB_NET:".Length));
			}
			else
			{
				orig.Invoke(message);
			}
		}

		private static void ParseAndProcess(string data)
		{
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				string text = data;
				int num = data.IndexOf('<');
				if (num != -1)
				{
					text = data.Substring(0, num);
				}
				string[] array = text.Split(':');
				if (array.Length < 5 || !uint.TryParse(array[0], out var senderID) || !uint.TryParse(array[1], out var result))
				{
					return;
				}
				string text2 = array[2].ToUpper();
				LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser();
				NetworkUser val = ((firstLocalUser != null) ? firstLocalUser.currentNetworkUser : null);
				if ((Object)(object)val == (Object)null)
				{
					return;
				}
				NetworkInstanceId netId;
				if (text2 == "ACK")
				{
					uint num2 = result;
					netId = ((NetworkBehaviour)val).netId;
					if (num2 == ((NetworkInstanceId)(ref netId)).Value)
					{
						DebugLog.Trace(_log, $"[Net In] ACK received from {senderID}. Request confirmed.");
						_pendingAcks.Remove(senderID);
						return;
					}
				}
				if (result != 0)
				{
					netId = ((NetworkBehaviour)val).netId;
					if (((NetworkInstanceId)(ref netId)).Value != result)
					{
						return;
					}
				}
				if (text2 != "ACK")
				{
					SendAck(senderID, text2);
				}
				int result3;
				int result4;
				if (text2 == "ABORT")
				{
					DebugLog.Trace(_log, $"[Net In] Global Abort received from Sender {senderID}");
					ObjectiveTracker.ClearObjectivesFromSender(senderID);
				}
				else if (text2 == "SUCCESS")
				{
					if (int.TryParse(array[3], out var result2))
					{
						ObjectiveTracker.ClearSpecificRequest(senderID, result2);
					}
				}
				else if (int.TryParse(array[3], out result3) && int.TryParse(array[4], out result4))
				{
					NetworkUser arg = ((IEnumerable<NetworkUser>)NetworkUser.readOnlyInstancesList).FirstOrDefault((Func<NetworkUser, bool>)delegate(NetworkUser u)
					{
						//IL_0001: Unknown result type (might be due to invalid IL or missing references)
						//IL_0006: Unknown result type (might be due to invalid IL or missing references)
						NetworkInstanceId netId2 = ((NetworkBehaviour)u).netId;
						return ((NetworkInstanceId)(ref netId2)).Value == senderID;
					});
					ChatNetworkHandler.OnIncomingObjective?.Invoke(arg, text2, result3, result4);
				}
			}
			catch (Exception ex)
			{
				_log.LogError((object)("[Net] Parse Error: " + ex.Message));
			}
		}
	}
	internal static class CraftingExecutionHandler
	{
		[CompilerGenerated]
		private sealed class <CraftChainRoutine>d__10 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public CraftPlanner.RecipeChain chain;

			public int repeatCount;

			private CharacterBody <body>5__2;

			private NetworkUser <localUser>5__3;

			private Dictionary<int, int> <startCounts>5__4;

			private Dictionary<int, int> <currentProgress>5__5;

			private Queue<ChefRecipe> <craftQueue>5__6;

			private PickupIndex <lastPickup>5__7;

			private int <lastQty>5__8;

			private int <totalSteps>5__9;

			private int <completedSteps>5__10;

			private CraftPlanner.DroneRequirement[] <>7__wrap10;

			private int <>7__wrap11;

			private CraftPlanner.DroneRequirement <req>5__13;

			private CraftPlanner.TradeRequirement[] <>7__wrap13;

			private CraftPlanner.TradeRequirement <req>5__15;

			private ChefRecipe <step>5__16;

			private string <stepName>5__17;

			private CraftingController <controller>5__18;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <CraftChainRoutine>d__10(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<body>5__2 = null;
				<localUser>5__3 = null;
				<startCounts>5__4 = null;
				<currentProgress>5__5 = null;
				<craftQueue>5__6 = null;
				<>7__wrap10 = null;
				<req>5__13 = default(CraftPlanner.DroneRequirement);
				<>7__wrap13 = null;
				<req>5__15 = default(CraftPlanner.TradeRequirement);
				<step>5__16 = null;
				<stepName>5__17 = null;
				<controller>5__18 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_06b6: Unknown result type (might be due to invalid IL or missing references)
				//IL_06bb: Unknown result type (might be due to invalid IL or missing references)
				//IL_071e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0723: Unknown result type (might be due to invalid IL or missing references)
				//IL_0779: Unknown result type (might be due to invalid IL or missing references)
				//IL_077e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0916: Unknown result type (might be due to invalid IL or missing references)
				//IL_0920: Expected O, but got Unknown
				//IL_0420: Unknown result type (might be due to invalid IL or missing references)
				//IL_0425: Unknown result type (might be due to invalid IL or missing references)
				//IL_0427: Unknown result type (might be due to invalid IL or missing references)
				//IL_06d0: Unknown result type (might be due to invalid IL or missing references)
				//IL_06d5: Unknown result type (might be due to invalid IL or missing references)
				//IL_05db: Unknown result type (might be due to invalid IL or missing references)
				//IL_05e0: Unknown result type (might be due to invalid IL or missing references)
				//IL_0970: Unknown result type (might be due to invalid IL or missing references)
				//IL_0975: Unknown result type (might be due to invalid IL or missing references)
				//IL_089e: Unknown result type (might be due to invalid IL or missing references)
				//IL_08a3: Unknown result type (might be due to invalid IL or missing references)
				//IL_0988: Unknown result type (might be due to invalid IL or missing references)
				//IL_0250: Unknown result type (might be due to invalid IL or missing references)
				//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
				//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
				//IL_0293: Unknown result type (might be due to invalid IL or missing references)
				//IL_0495: Unknown result type (might be due to invalid IL or missing references)
				//IL_08ea: Unknown result type (might be due to invalid IL or missing references)
				//IL_08f4: Expected O, but got Unknown
				//IL_05a2: Unknown result type (might be due to invalid IL or missing references)
				//IL_05a7: Unknown result type (might be due to invalid IL or missing references)
				//IL_0640: Unknown result type (might be due to invalid IL or missing references)
				//IL_0645: Unknown result type (might be due to invalid IL or missing references)
				//IL_09c1: Unknown result type (might be due to invalid IL or missing references)
				//IL_0652: Unknown result type (might be due to invalid IL or missing references)
				//IL_0323: Unknown result type (might be due to invalid IL or missing references)
				//IL_068b: Unknown result type (might be due to invalid IL or missing references)
				KeyboardShortcut value;
				List<PickupIndex> desired;
				List<ChefRecipe> list;
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
				{
					<>1__state = -1;
					CompleteCurrentObjective();
					StateController.BatchMode = false;
					LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser();
					<body>5__2 = ((firstLocalUser != null) ? firstLocalUser.cachedBody : null);
					LocalUser firstLocalUser2 = LocalUserManager.GetFirstLocalUser();
					<localUser>5__3 = ((firstLocalUser2 != null) ? firstLocalUser2.currentNetworkUser : null);
					Dictionary<int, int> dictionary = new Dictionary<int, int>();
					if (chain.DroneCostSparse != null)
					{
						CraftPlanner.DroneRequirement[] droneCostSparse = chain.DroneCostSparse;
						for (int i = 0; i < droneCostSparse.Length; i++)
						{
							CraftPlanner.DroneRequirement droneRequirement = droneCostSparse[i];
							if (!dictionary.ContainsKey(droneRequirement.ScrapIndex))
							{
								dictionary[droneRequirement.ScrapIndex] = 0;
							}
							dictionary[droneRequirement.ScrapIndex] += droneRequirement.Count;
						}
					}
					<startCounts>5__4 = new Dictionary<int, int>();
					<currentProgress>5__5 = new Dictionary<int, int>();
					if (chain.DroneCostSparse != null && chain.DroneCostSparse.Length != 0)
					{
						LocalUser firstLocalUser3 = LocalUserManager.GetFirstLocalUser();
						<localUser>5__3 = ((firstLocalUser3 != null) ? firstLocalUser3.currentNetworkUser : null);
						<>7__wrap10 = chain.DroneCostSparse;
						<>7__wrap11 = 0;
						goto IL_03a6;
					}
					goto IL_03c0;
				}
				case 1:
					<>1__state = -1;
					goto IL_038c;
				case 2:
					<>1__state = -1;
					ChatNetworkHandler.SendObjectiveSuccess(<req>5__13.Owner, <req>5__13.ScrapIndex);
					goto IL_038c;
				case 3:
					<>1__state = -1;
					ChatNetworkHandler.SendObjectiveSuccess(<req>5__15.Donor, <req>5__15.UnifiedIndex);
					<req>5__15 = default(CraftPlanner.TradeRequirement);
					<>7__wrap11++;
					goto IL_04f9;
				case 4:
					<>1__state = -1;
					CompleteCurrentObjective();
					<lastPickup>5__7 = PickupIndex.none;
					goto IL_06c0;
				case 5:
					<>1__state = -1;
					value = CookBook.AbortKey.Value;
					if (((KeyboardShortcut)(ref value)).IsPressed())
					{
						Abort();
						return false;
					}
					if (<step>5__16.HasB)
					{
						<>2__current = EnsureIfEquipment(<body>5__2, <step>5__16.IngB, <stepName>5__17);
						<>1__state = 6;
						return true;
					}
					goto IL_0790;
				case 6:
					<>1__state = -1;
					value = CookBook.AbortKey.Value;
					if (((KeyboardShortcut)(ref value)).IsPressed())
					{
						Abort();
						return false;
					}
					goto IL_0790;
				case 7:
					<>1__state = -1;
					goto IL_07b8;
				case 8:
					<>1__state = -1;
					if ((Object)(object)<controller>5__18 != (Object)null && <controller>5__18.AllSlotsFilled() && IngredientsMatchMultiset(<controller>5__18.ingredients, ResolveStepIngredients(<step>5__16)))
					{
						DebugLog.Trace(_log, "[Execution] " + <stepName>5__17 + " verified. Confirming craft...");
						<craftQueue>5__6.Dequeue();
						<completedSteps>5__10++;
						<lastQty>5__8 = <step>5__16.ResultCount;
						<lastPickup>5__7 = GetPickupIndex(<step>5__16);
						NetworkUIPromptController component = ((Component)<controller>5__18).GetComponent<NetworkUIPromptController>();
						if (!Object.op_Implicit((Object)(object)component) || (Object)(object)component.currentParticipantMaster == (Object)null)
						{
							_log.LogWarning((object)"[Execution] Not confirming: participant master is null.");
							return false;
						}
						<controller>5__18.ConfirmSelection();
						<>2__current = (object)new WaitForEndOfFrame();
						<>1__state = 9;
						return true;
					}
					if (Object.op_Implicit((Object)(object)StateController.ActiveCraftingController))
					{
						CraftUI.CloseCraftPanel(StateController.ActiveCraftingController);
					}
					<step>5__16 = null;
					<stepName>5__17 = null;
					<controller>5__18 = null;
					goto IL_095e;
				case 9:
					<>1__state = -1;
					CraftUI.CloseCraftPanel(<controller>5__18);
					<>2__current = (object)new WaitForSeconds(0.2f);
					<>1__state = 10;
					return true;
				case 10:
					<>1__state = -1;
					goto IL_095e;
				case 11:
					{
						<>1__state = -1;
						CompleteCurrentObjective();
						break;
					}
					IL_038c:
					<req>5__13 = default(CraftPlanner.DroneRequirement);
					<>7__wrap11++;
					goto IL_03a6;
					IL_0790:
					if ((Object)(object)StateController.ActiveCraftingController == (Object)null)
					{
						<>2__current = EnsureCraftingControllerOpen();
						<>1__state = 7;
						return true;
					}
					goto IL_07b8;
					IL_06c0:
					if (<step>5__16 != null)
					{
						value = CookBook.AbortKey.Value;
						if (((KeyboardShortcut)(ref value)).IsPressed())
						{
							Abort();
							return false;
						}
						<>2__current = EnsureIfEquipment(<body>5__2, <step>5__16.IngA, <stepName>5__17);
						<>1__state = 5;
						return true;
					}
					goto IL_0790;
					IL_07b8:
					<controller>5__18 = StateController.ActiveCraftingController;
					if (!Object.op_Implicit((Object)(object)<controller>5__18))
					{
						Cleanup(closeUi: true);
						return false;
					}
					desired = ResolveStepIngredients(<step>5__16);
					<>2__current = SubmitIngredientsClientSafe(<controller>5__18, desired);
					<>1__state = 8;
					return true;
					IL_03a6:
					if (<>7__wrap11 < <>7__wrap10.Length)
					{
						<req>5__13 = <>7__wrap10[<>7__wrap11];
						if (!<startCounts>5__4.ContainsKey(<req>5__13.ScrapIndex))
						{
							PickupIndex pickupIndexFromUnified = GetPickupIndexFromUnified(<req>5__13.ScrapIndex);
							<startCounts>5__4[<req>5__13.ScrapIndex] = GetOwnedCount(PickupCatalog.GetPickupDef(pickupIndexFromUnified), <body>5__2);
							<currentProgress>5__5[<req>5__13.ScrapIndex] = 0;
						}
						<currentProgress>5__5[<req>5__13.ScrapIndex] += <req>5__13.Count;
						int inventoryGoal = <startCounts>5__4[<req>5__13.ScrapIndex] + <currentProgress>5__5[<req>5__13.ScrapIndex];
						string droneName = GetDroneName(<req>5__13.DroneIdx);
						if ((Object)(object)<req>5__13.Owner == (Object)null || (Object)(object)<req>5__13.Owner == (Object)(object)<localUser>5__3)
						{
							<>2__current = HandleAcquisition(GetPickupIndexFromUnified(<req>5__13.ScrapIndex), inventoryGoal, "Scrap " + droneName + " for");
							<>1__state = 1;
							return true;
						}
						ChatNetworkHandler.SendObjectiveRequest(<req>5__13.Owner, "SCRAP", <req>5__13.ScrapIndex, <req>5__13.Count);
						string text = <req>5__13.Owner?.userName ?? "Teammate";
						<>2__current = HandleAcquisition(GetPickupIndexFromUnified(<req>5__13.ScrapIndex), inventoryGoal, "Wait for " + text + " to scrap " + droneName + " for");
						<>1__state = 2;
						return true;
					}
					<>7__wrap10 = null;
					goto IL_03c0;
					IL_095e:
					if (<craftQueue>5__6.Count > 0)
					{
						value = CookBook.AbortKey.Value;
						if (((KeyboardShortcut)(ref value)).IsPressed())
						{
							Abort();
							return false;
						}
						LocalUser firstLocalUser4 = LocalUserManager.GetFirstLocalUser();
						<body>5__2 = ((firstLocalUser4 != null) ? firstLocalUser4.cachedBody : null);
						if (!Object.op_Implicit((Object)(object)<body>5__2))
						{
							Abort();
							return false;
						}
						<step>5__16 = <craftQueue>5__6.Peek();
						<stepName>5__17 = GetStepName(<step>5__16);
						if (<lastPickup>5__7 != PickupIndex.none)
						{
							SetObjectiveText("Collect " + Language.GetString(PickupCatalog.GetPickupDef(<lastPickup>5__7)?.nameToken ?? "Result"));
							<>2__current = WaitForPendingPickup(<lastPickup>5__7, <lastQty>5__8);
							<>1__state = 4;
							return true;
						}
						goto IL_06c0;
					}
					if (<lastPickup>5__7 != PickupIndex.none)
					{
						StateController.BatchMode = false;
						SetObjectiveText("Collect " + Language.GetString(PickupCatalog.GetPickupDef(<lastPickup>5__7)?.nameToken ?? "Result"));
						<>2__current = WaitForPendingPickup(<lastPickup>5__7, <lastQty>5__8);
						<>1__state = 11;
						return true;
					}
					break;
					IL_0513:
					<craftQueue>5__6 = new Queue<ChefRecipe>();
					list = chain.Steps.Where((ChefRecipe s) => !(s is CraftPlanner.TradeRecipe)).ToList();
					for (int j = 0; j < repeatCount; j++)
					{
						foreach (ChefRecipe item in list)
						{
							<craftQueue>5__6.Enqueue(item);
						}
					}
					<lastPickup>5__7 = PickupIndex.none;
					<lastQty>5__8 = 0;
					<totalSteps>5__9 = <craftQueue>5__6.Count;
					<completedSteps>5__10 = 0;
					StateController.BatchMode = true;
					goto IL_095e;
					IL_03c0:
					if (chain.AlliedTradeSparse != null && chain.AlliedTradeSparse.Length != 0)
					{
						<>7__wrap13 = chain.AlliedTradeSparse;
						<>7__wrap11 = 0;
						goto IL_04f9;
					}
					goto IL_0513;
					IL_04f9:
					if (<>7__wrap11 < <>7__wrap13.Length)
					{
						<req>5__15 = <>7__wrap13[<>7__wrap11];
						PickupIndex pickupIndexFromUnified2 = GetPickupIndexFromUnified(<req>5__15.UnifiedIndex);
						int inventoryGoal2 = GetOwnedCount(PickupCatalog.GetPickupDef(pickupIndexFromUnified2), <body>5__2) + <req>5__15.TradesRequired;
						ChatNetworkHandler.SendObjectiveRequest(<req>5__15.Donor, "TRADE", <req>5__15.UnifiedIndex, <req>5__15.TradesRequired);
						string text2 = <req>5__15.Donor?.userName ?? "Ally";
						<>2__current = HandleAcquisition(pickupIndexFromUnified2, inventoryGoal2, "Wait for " + text2 + " to trade");
						<>1__state = 3;
						return true;
					}
					<>7__wrap13 = null;
					goto IL_0513;
				}
				DebugLog.Trace(_log, $"[ExecutionHandler] Finished {<completedSteps>5__10}/{<totalSteps>5__9} steps.");
				Cleanup(closeUi: true);
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <EnsureCraftingControllerOpen>d__13 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			private float <t>5__2;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <EnsureCraftingControllerOpen>d__13(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_002f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0034: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
				//IL_0140: Unknown result type (might be due to invalid IL or missing references)
				//IL_014a: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<t>5__2 = 0f;
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				if (!IsCraftingSessionReady(StateController.ActiveCraftingController))
				{
					KeyboardShortcut value = CookBook.AbortKey.Value;
					if (((KeyboardShortcut)(ref value)).IsPressed())
					{
						Abort();
						return false;
					}
					LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser();
					CharacterBody val = ((firstLocalUser != null) ? firstLocalUser.cachedBody : null);
					Interactor val2 = (Object.op_Implicit((Object)(object)val) ? ((Component)val).GetComponent<Interactor>() : null);
					if (!Object.op_Implicit((Object)(object)StateController.TargetCraftingObject) && Object.op_Implicit((Object)(object)val))
					{
						StateController.TargetCraftingObject = TryResolveChefStationObject(val);
					}
					if (!Object.op_Implicit((Object)(object)StateController.TargetCraftingObject) || !Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val2))
					{
						_log.LogWarning((object)"[Execution] Lost target/body/interactor while trying to open crafting UI. Aborting.");
						Abort();
						return false;
					}
					SetObjectiveText("Approach Wandering CHEF");
					float num = val2.maxInteractionDistance + 6f;
					Vector3 val3 = val.corePosition - StateController.TargetCraftingObject.transform.position;
					if (((Vector3)(ref val3)).sqrMagnitude <= num * num)
					{
						val2.AttemptInteraction(StateController.TargetCraftingObject);
					}
					<t>5__2 += Time.unscaledDeltaTime;
					if (<t>5__2 >= 12f)
					{
						_log.LogWarning((object)"[Execution] Timed out opening crafting UI.");
						Abort();
						return false;
					}
					<>2__current = (object)new WaitForSecondsRealtime(0.2f);
					<>1__state = 1;
					return true;
				}
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <EnsureEquipmentIsActive>d__23 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public CharacterBody body;

			public EquipmentIndex target;

			private Inventory <inv>5__2;

			private int <targetSlot>5__3;

			private int <targetSet>5__4;

			private GenericSkill <skill>5__5;

			private float <timeout>5__6;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <EnsureEquipmentIsActive>d__23(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<inv>5__2 = null;
				<skill>5__5 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0045: Unknown result type (might be due to invalid IL or missing references)
				//IL_004b: Invalid comparison between Unknown and I4
				//IL_013e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0148: Expected O, but got Unknown
				//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
				//IL_01bf: Expected O, but got Unknown
				//IL_02bf: Unknown result type (might be due to invalid IL or missing references)
				//IL_02c9: Expected O, but got Unknown
				//IL_026a: 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_00a3: Unknown result type (might be due to invalid IL or missing references)
				int num;
				int equipmentSetCount2;
				int num2;
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
				{
					<>1__state = -1;
					<inv>5__2 = body.inventory;
					if (!Object.op_Implicit((Object)(object)<inv>5__2) || (int)target == -1)
					{
						return false;
					}
					int activeEquipmentSlot = <inv>5__2.activeEquipmentSlot;
					int equipmentSlotCount = <inv>5__2.GetEquipmentSlotCount();
					<targetSlot>5__3 = -1;
					<targetSet>5__4 = -1;
					for (int i = 0; i < equipmentSlotCount; i++)
					{
						int equipmentSetCount = <inv>5__2.GetEquipmentSetCount((uint)i);
						for (int j = 0; j < equipmentSetCount; j++)
						{
							if (<inv>5__2.GetEquipment((uint)i, (uint)j).equipmentIndex == target)
							{
								<targetSlot>5__3 = i;
								<targetSet>5__4 = j;
								break;
							}
						}
						if (<targetSlot>5__3 != -1)
						{
							break;
						}
					}
					if (<targetSlot>5__3 == -1)
					{
						return false;
					}
					if (<targetSlot>5__3 != activeEquipmentSlot)
					{
						<skill>5__5 = body.skillLocator?.special;
						if (Object.op_Implicit((Object)(object)<skill>5__5))
						{
							if (Object.op_Implicit((Object)(object)StateController.ActiveCraftingController))
							{
								CraftUI.CloseCraftPanel(StateController.ActiveCraftingController);
							}
							goto IL_0158;
						}
						goto IL_01ef;
					}
					goto IL_01f6;
				}
				case 1:
					<>1__state = -1;
					goto IL_0158;
				case 2:
					<>1__state = -1;
					goto IL_01cf;
				case 3:
					{
						<>1__state = -1;
						goto IL_02d9;
					}
					IL_02d9:
					if (<inv>5__2.activeEquipmentSet[<inv>5__2.activeEquipmentSlot] != <targetSet>5__4 && <timeout>5__6 > 0f)
					{
						<timeout>5__6 -= 0.1f;
						<>2__current = (object)new WaitForSeconds(0.1f);
						<>1__state = 3;
						return true;
					}
					break;
					IL_01cf:
					if (<inv>5__2.activeEquipmentSlot != <targetSlot>5__3 && <timeout>5__6 > 0f)
					{
						<timeout>5__6 -= 0.1f;
						<>2__current = (object)new WaitForSeconds(0.1f);
						<>1__state = 2;
						return true;
					}
					goto IL_01ef;
					IL_01f6:
					num = <inv>5__2.activeEquipmentSet[<inv>5__2.activeEquipmentSlot];
					equipmentSetCount2 = <inv>5__2.GetEquipmentSetCount((uint)<inv>5__2.activeEquipmentSlot);
					if (<targetSet>5__4 == num)
					{
						break;
					}
					if (Object.op_Implicit((Object)(object)StateController.ActiveCraftingController))
					{
						CraftUI.CloseCraftPanel(StateController.ActiveCraftingController);
					}
					num2 = (<targetSet>5__4 - num + equipmentSetCount2) % equipmentSetCount2;
					DebugLog.Trace(_log, $"[Execution] Cycling sets ({num2} clicks) for {target}.");
					for (int k = 0; k < num2; k++)
					{
						<inv>5__2.CallCmdSwitchToNextEquipmentInSet();
					}
					<timeout>5__6 = 2f;
					goto IL_02d9;
					IL_01ef:
					<skill>5__5 = null;
					goto IL_01f6;
					IL_0158:
					if (!<skill>5__5.CanExecute())
					{
						<>2__current = (object)new WaitForSeconds(0.1f);
						<>1__state = 1;
						return true;
					}
					DebugLog.Trace(_log, $"[Execution] Retooling to Slot {<targetSlot>5__3}.");
					<skill>5__5.ExecuteIfReady();
					<timeout>5__6 = 1f;
					goto IL_01cf;
				}
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <EnsureIfEquipment>d__11 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public int unifiedIndex;

			public string stepName;

			public CharacterBody body;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <EnsureIfEquipment>d__11(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_001c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0021: Unknown result type (might be due to invalid IL or missing references)
				//IL_004e: 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_0053: Invalid comparison between Unknown and I4
				//IL_0076: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
				{
					<>1__state = -1;
					KeyboardShortcut value = CookBook.AbortKey.Value;
					if (((KeyboardShortcut)(ref value)).IsPressed())
					{
						return false;
					}
					int itemCount = ItemCatalog.itemCount;
					if (unifiedIndex < itemCount)
					{
						break;
					}
					int num = unifiedIndex - itemCount;
					if ((uint)num < (uint)EquipmentCatalog.equipmentCount)
					{
						EquipmentIndex val = (EquipmentIndex)num;
						if ((int)val != -1)
						{
							SetObjectiveText("Preparing " + stepName + "...");
							<>2__current = EnsureEquipmentIsActive(body, val);
							<>1__state = 1;
							return true;
						}
					}
					break;
				}
				case 1:
					<>1__state = -1;
					break;
				}
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <HandleAcquisition>d__25 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public PickupIndex pi;

			public int inventoryGoal;

			public string actionPrefix;

			private CharacterBody <body>5__2;

			private PickupDef <def>5__3;

			private string <itemName>5__4;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <HandleAcquisition>d__25(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<body>5__2 = null;
				<def>5__3 = null;
				<itemName>5__4 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0033: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
				//IL_00bf: Expected O, but got Unknown
				int num = <>1__state;
				if (num != 0)
				{
					if (num != 1)
					{
						return false;
					}
					<>1__state = -1;
				}
				else
				{
					<>1__state = -1;
					LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser();
					<body>5__2 = ((firstLocalUser != null) ? firstLocalUser.cachedBody : null);
					<def>5__3 = PickupCatalog.GetPickupDef(pi);
					if (!Object.op_Implicit((Object)(object)<body>5__2) || <def>5__3 == null)
					{
						return false;
					}
					<itemName>5__4 = Language.GetString(<def>5__3.nameToken);
				}
				int ownedCount = GetOwnedCount(<def>5__3, <body>5__2);
				int num2 = inventoryGoal - ownedCount;
				if (num2 > 0)
				{
					SetObjectiveText($"{actionPrefix} {<itemName>5__4} <style=cSub>(Need {num2})</style>");
					<>2__current = (object)new WaitForSeconds(0.1f);
					<>1__state = 1;
					return true;
				}
				CompleteCurrentObjective();
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <SubmitIngredientsClientSafe>d__18 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public CraftingController controller;

			public List<PickupIndex> desired;

			private NetworkUIPromptController <prompt>5__2;

			private float <t>5__3;

			private float <clearBudget>5__4;

			private float <syncBudget>5__5;

			private int <k>5__6;

			private PickupIndex <want>5__7;

			private bool <inserted>5__8;

			private float <insertBudget>5__9;

			private int <filledBefore>5__10;

			private int <wantCountBefore>5__11;

			private float <progressBudget>5__12;

			private bool <progressed>5__13;

			private float <settleBudget>5__14;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <SubmitIngredientsClientSafe>d__18(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<prompt>5__2 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0611: Unknown result type (might be due to invalid IL or missing references)
				//IL_04ea: Unknown result type (might be due to invalid IL or missing references)
				//IL_05a3: Unknown result type (might be due to invalid IL or missing references)
				//IL_0483: Unknown result type (might be due to invalid IL or missing references)
				//IL_0275: Unknown result type (might be due to invalid IL or missing references)
				//IL_027a: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
				//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
				//IL_0326: Unknown result type (might be due to invalid IL or missing references)
				//IL_033d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0384: Unknown result type (might be due to invalid IL or missing references)
				//IL_0389: 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_03b5: Unknown result type (might be due to invalid IL or missing references)
				//IL_03b7: Unknown result type (might be due to invalid IL or missing references)
				//IL_03bc: Unknown result type (might be due to invalid IL or missing references)
				//IL_03c9: Unknown result type (might be due to invalid IL or missing references)
				//IL_0403: Unknown result type (might be due to invalid IL or missing references)
				//IL_0425: Unknown result type (might be due to invalid IL or missing references)
				//IL_042f: Expected O, but got Unknown
				//IL_018b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0190: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					if (!Object.op_Implicit((Object)(object)controller) || desired == null)
					{
						return false;
					}
					<prompt>5__2 = ((Component)controller).GetComponent<NetworkUIPromptController>();
					<t>5__3 = 2f;
					goto IL_0098;
				case 1:
					<>1__state = -1;
					goto IL_0098;
				case 2:
					<>1__state = -1;
					goto IL_023d;
				case 3:
					<>1__state = -1;
					goto IL_05c9;
				case 4:
					<>1__state = -1;
					goto IL_05c9;
				case 5:
					<>1__state = -1;
					<progressBudget>5__12 = 1f;
					<progressed>5__13 = false;
					goto IL_04c7;
				case 6:
					<>1__state = -1;
					goto IL_04c7;
				case 7:
					<>1__state = -1;
					goto IL_0583;
				case 8:
					{
						<>1__state = -1;
						break;
					}
					IL_04c7:
					if (<progressBudget>5__12 > 0f)
					{
						if (!Object.op_Implicit((Object)(object)controller))
						{
							return false;
						}
						PickupIndex[] ingredients = controller.ingredients;
						if (CountFilled(ingredients) < <filledBefore>5__10 + 1 || CountOf(ingredients, <want>5__7) <= <wantCountBefore>5__11)
						{
							<progressBudget>5__12 -= Time.unscaledDeltaTime;
							<>2__current = null;
							<>1__state = 6;
							return true;
						}
						<progressed>5__13 = true;
					}
					if (!<progressed>5__13)
					{
						DebugLog.Trace(_log, $"[Crafting] No fill-progress observed for {<want>5__7}, retrying...");
						<insertBudget>5__9 -= 0.25f;
						goto IL_05c9;
					}
					<settleBudget>5__14 = 0.75f;
					goto IL_0583;
					IL_05c9:
					if (!<inserted>5__8 && <insertBudget>5__9 > 0f)
					{
						if (!Object.op_Implicit((Object)(object)controller))
						{
							return false;
						}
						if (controller.AllSlotsFilled() && !IngredientsMatchMultiset(controller.ingredients, desired))
						{
							_log.LogWarning((object)"[Crafting] Station became full with wrong ingredients. Aborting insert to avoid accidental confirm.");
							return false;
						}
						Option[] options = ((PickupPickerController)controller).options;
						if (options == null || options.Length == 0)
						{
							<insertBudget>5__9 -= Time.unscaledDeltaTime;
							<>2__current = null;
							<>1__state = 3;
							return true;
						}
						if (!TryFindChoiceIndex(controller, <want>5__7, out var choiceIndex) || !IsChoiceIndexStillValid(controller, choiceIndex, <want>5__7))
						{
							<insertBudget>5__9 -= Time.unscaledDeltaTime;
							<>2__current = null;
							<>1__state = 4;
							return true;
						}
						Option val = ((PickupPickerController)controller).options[choiceIndex];
						DebugLog.Trace(_log, $"[Crafting] Pick want={<want>5__7} choiceIndex={choiceIndex} optPickup={val.pickup.pickupIndex} available={val.available}");
						<filledBefore>5__10 = CountFilled(controller.ingredients);
						<wantCountBefore>5__11 = CountOf(controller.ingredients, <want>5__7);
						SubmitChoiceToCraftingController(controller, choiceIndex);
						<>2__current = (object)new WaitForSecondsRealtime(0.1f);
						<>1__state = 5;
						return true;
					}
					if (!<inserted>5__8)
					{
						_log.LogWarning((object)$"[Crafting] Failed to insert ingredient {<k>5__6 + 1}/{desired.Count}: {<want>5__7}");
						return false;
					}
					<k>5__6++;
					goto IL_0639;
					IL_0639:
					if (<k>5__6 < desired.Count)
					{
						if (!Object.op_Implicit((Object)(object)controller))
						{
							return false;
						}
						<want>5__7 = desired[<k>5__6];
						<inserted>5__8 = false;
						<insertBudget>5__9 = 2f;
						goto IL_05c9;
					}
					<syncBudget>5__5 = 2f;
					break;
					IL_0583:
					if (<settleBudget>5__14 > 0f)
					{
						if (!Object.op_Implicit((Object)(object)controller))
						{
							return false;
						}
						if (!IngredientsMatchPrefixMultiset(controller.ingredients, desired, <k>5__6 + 1))
						{
							<settleBudget>5__14 -= Time.unscaledDeltaTime;
							<>2__current = null;
							<>1__state = 7;
							return true;
						}
						<inserted>5__8 = true;
					}
					if (!<inserted>5__8)
					{
						DebugLog.Trace(_log, $"[Crafting] Change observed but state did not settle for {<want>5__7}, retrying...");
						<insertBudget>5__9 -= 0.25f;
					}
					goto IL_05c9;
					IL_024d:
					<k>5__6 = 0;
					goto IL_0639;
					IL_023d:
					if (<clearBudget>5__4 > 0f)
					{
						if (!Object.op_Implicit((Object)(object)controller))
						{
							return false;
						}
						PickupIndex[] ingredients2 = controller.ingredients;
						if (ingredients2 != null)
						{
							bool flag = false;
							for (int i = 0; i < ingredients2.Length; i++)
							{
								if (ingredients2[i] != PickupIndex.none)
								{
									flag = true;
									break;
								}
							}
							if (!flag)
							{
								goto IL_024d;
							}
						}
						<clearBudget>5__4 -= Time.unscaledDeltaTime;
						<>2__current = null;
						<>1__state = 2;
						return true;
					}
					goto IL_024d;
					IL_0098:
					if (<t>5__3 > 0f && (!Object.op_Implicit((Object)(object)controller) || !Object.op_Implicit((Object)(object)<prompt>5__2) || (Object)(object)<prompt>5__2.currentParticipantMaster == (Object)null))
					{
						<t>5__3 -= Time.unscaledDeltaTime;
						<>2__current = null;
						<>1__state = 1;
						return true;
					}
					if (!Object.op_Implicit((Object)(object)controller) || !Object.op_Implicit((Object)(object)<prompt>5__2) || (Object)(object)<prompt>5__2.currentParticipantMaster == (Object)null)
					{
						_log.LogError((object)"[Crafting] Participant Master not ready. Station not synced.");
						return false;
					}
					if (desired.Count != controller.ingredientCount)
					{
						_log.LogWarning((object)$"[Crafting] Ingredient count mismatch. step needs {desired.Count}, controller has {controller.ingredientCount} slots.");
						return false;
					}
					for (int j = 0; j < controller.ingredientCount; j++)
					{
						if (controller.ingredients != null && j < controller.ingredients.Length && controller.ingredients[j] != PickupIndex.none)
						{
							controller.ClearSlot(j);
						}
					}
					<clearBudget>5__4 = 1f;
					goto IL_023d;
				}
				if (<syncBudget>5__5 > 0f)
				{
					if (!Object.op_Implicit((Object)(object)controller))
					{
						return false;
					}
					if (IngredientsMatchMultiset(controller.ingredients, desired))
					{
						return false;
					}
					<syncBudget>5__5 -= Time.unscaledDeltaTime;
					<>2__current = null;
					<>1__state = 8;
					return true;
				}
				_log.LogWarning((object)"[Crafting] Timed out waiting for ingredient sync.");
				return false;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		[CompilerGenerated]
		private sealed class <WaitForPendingPickup>d__26 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public PickupIndex pickupIndex;

			public int expectedGain;

			private CharacterBody <body>5__2;

			private PickupDef <def>5__3;

			private int <targetCount>5__4;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <WaitForPendingPickup>d__26(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<body>5__2 = null;
				<def>5__3 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
				//IL_00da: Expected O, but got Unknown
				//IL_0054: Unknown result type (might be due to invalid IL or missing references)
				int num = <>1__state;
				if (num != 0)
				{
					if (num != 1)
					{
						return false;
					}
					<>1__state = -1;
				}
				else
				{
					<>1__state = -1;
					LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser();
					<body>5__2 = ((firstLocalUser != null) ? firstLocalUser.cachedBody : null);
					if (!Object.op_Implicit((Object)(object)<body>5__2) || !Object.op_Implicit((Object)(object)<body>5__2.inventory))
					{
						return false;
					}
					<def>5__3 = PickupCatalog.GetPickupDef(pickupIndex);
					if (<def>5__3 == null)
					{
						return false;
					}
					<targetCount>5__4 = GetOwnedCount(<def>5__3, <body>5__2) + expectedGain;
				}
				if (GetOwnedCount(<def>5__3, <body>5__2) >= <targetCount>5__4)
				{
					DebugLog.Trace(_log, "[Chain] Confirmed pickup of " + <def>5__3.internalName + ".");
					return false;
				}
				<>2__current = (object)new WaitForSeconds(0.1f);
				<>1__state = 1;
				return true;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		private static ManualLogSource _log;

		private static ObjectiveTracker.ObjectiveToken _currentObjective;

		private static Coroutine _craftingRoutine;

		private static MonoBehaviour _runner;

		public static bool IsAutoCrafting => _craftingRoutine != null;

		internal static void Init(ManualLogSource log, MonoBehaviour runner)
		{
			_log = log;
			_runner = runner;
		}

		public static void ExecuteChain(CraftPlanner.RecipeChain chain, int repeatCount)
		{
			if (CookBook.isDebugMode)
			{
				DumpChain(chain, repeatCount);
			}
			Abort();
			_craftingRoutine = _runner.StartCoroutine(CraftChainRoutine(chain, repeatCount));
		}

		private static void Cleanup(bool closeUi = false)
		{
			_craftingRoutine = null;
			StateController.BatchMode = false;
			CompleteCurrentObjective();
			if (closeUi && Object.op_Implicit((Object)(object)StateController.ActiveCraftingController))
			{
				CraftUI.CloseCraftPanel(StateController.ActiveCraftingController);
			}
		}

		public static void Abort()
		{
			if ((Object)(object)_runner != (Object)null && _craftingRoutine != null)
			{
				_runner.StopCoroutine(_craftingRoutine);
			}
			Cleanup(closeUi: true);
		}

		[IteratorStateMachine(typeof(<CraftChainRoutine>d__10))]
		private static IEnumerator CraftChainRoutine(CraftPlanner.RecipeChain chain, int repeatCount)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <CraftChainRoutine>d__10(0)
			{
				chain = chain,
				repeatCount = repeatCount
			};
		}

		[IteratorStateMachine(typeof(<EnsureIfEquipment>d__11))]
		private static IEnumerator EnsureIfEquipment(CharacterBody body, int unifiedIndex, string stepName)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <EnsureIfEquipment>d__11(0)
			{
				body = body,
				unifiedIndex = unifiedIndex,
				stepName = stepName
			};
		}

		private static bool IsCraftingSessionReady(CraftingController c)
		{
			if (!Object.op_Implicit((Object)(object)c))
			{
				return false;
			}
			NetworkUIPromptController component = ((Component)c).GetComponent<NetworkUIPromptController>();
			if (!Object.op_Implicit((Object)(object)component))
			{
				return false;
			}
			if ((Object)(object)component.currentParticipantMaster == (Object)null)
			{
				return false;
			}
			if (!component.isDisplaying)
			{
				return false;
			}
			CraftingPanel[] array = Object.FindObjectsOfType<CraftingPanel>();
			for (int i = 0; i < array.Length; i++)
			{
				if (Object.op_Implicit((Object)(object)array[i]) && (Object)(object)array[i].craftingController == (Object)(object)c)
				{
					return true;
				}
			}
			return false;
		}

		[IteratorStateMachine(typeof(<EnsureCraftingControllerOpen>d__13))]
		private static IEnumerator EnsureCraftingControllerOpen()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <EnsureCraftingControllerOpen>d__13(0);
		}

		private static List<PickupIndex> ResolveStepIngredients(ChefRecipe step)
		{
			if (step == null)
			{
				return new List<PickupIndex>(0);
			}
			int capacity = Mathf.Max(0, (int)step.CountA) + Mathf.Max(0, (int)step.CountB);
			List<PickupIndex> list = new List<PickupIndex>(capacity);
			int itemCount = ItemCatalog.itemCount;
			AddMany(step.IngA, Mathf.Max(0, (int)step.CountA));
			if (step.HasB)
			{
				AddMany(step.IngB, Mathf.Max(0, (int)step.CountB));
			}
			return list;
			void AddMany(int unifiedIndex, int count)
			{
				//IL_000a: Unknown result type (might be due to invalid IL or missing references)
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				//IL_001a: Unknown result type (might be due to invalid IL or missing references)
				//IL_001f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0034: Unknown result type (might be due to invalid IL or missing references)
				//IL_0039: Unknown result type (might be due to invalid IL or missing references)
				//IL_0043: Unknown result type (might be due to invalid IL or missing references)
				//IL_0044: Unknown result type (might be due to invalid IL or missing references)
				//IL_005b: Unknown result type (might be due to invalid IL or missing references)
				if (count > 0 && unifiedIndex >= 0)
				{
					PickupIndex val = PickupIndex.none;
					if (unifiedIndex < itemCount)
					{
						val = PickupCatalog.FindPickupIndex((ItemIndex)unifiedIndex);
					}
					else
					{
						int num = unifiedIndex - itemCount;
						if ((uint)num < (uint)EquipmentCatalog.equipmentCount)
						{
							val = PickupCatalog.FindPickupIndex((EquipmentIndex)num);
						}
					}
					if (((PickupIndex)(ref val)).isValid && !(val == PickupIndex.none))
					{
						for (int i = 0; i < count; i++)
						{
							list.Add(val);
						}
					}
				}
			}
		}

		private static bool TryFindChoiceIndex(CraftingController c, PickupIndex desired, out int choiceIndex)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			choiceIndex = -1;
			Option[] options = ((PickupPickerController)c).options;
			if (options == null)
			{
				return false;
			}
			for (int i = 0; i < options.Length; i++)
			{
				if (options[i].pickup.pickupIndex == desired)
				{
					choiceIndex = i;
					return true;
				}
			}
			return false;
		}

		private static bool IsChoiceIndexStillValid(CraftingController c, int idx, PickupIndex desired)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: 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_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			Option[] options = ((PickupPickerController)c).options;
			if (options == null)
			{
				return false;
			}
			if ((uint)idx >= (uint)options.Length)
			{
				return false;
			}
			Option val = options[idx];
			if (val.available)
			{
				return val.pickup.pickupIndex == desired;
			}
			return false;
		}

		private static void SubmitChoiceToCraftingController(CraftingController c, int choiceIndex)
		{
			NetworkUIPromptController component = ((Component)c).GetComponent<NetworkUIPromptController>();
			if (Object.op_Implicit((Object)(object)component))
			{
				NetworkWriter val = component.BeginMessageToServer();
				if (val != null)
				{
					val.Write((byte)0);
					val.Write(choiceIndex);
					component.FinishMessageToServer(val);
				}
			}
		}

		[IteratorStateMachine(typeof(<SubmitIngredientsClientSafe>d__18))]
		private static IEnumerator SubmitIngredientsClientSafe(CraftingController controller, List<PickupIndex> desired)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <SubmitIngredientsClientSafe>d__18(0)
			{
				controller = controller,
				desired = desired
			};
		}

		private static bool IngredientsMatchPrefixMultiset(PickupIndex[] current, List<PickupIndex> desired, int insertedCount)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: 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_005f: Unknown result type (might be due to invalid IL or missing references)
			if (current == null || desired == null)
			{
				return false;
			}
			Dictionary<int, int> dictionary = new Dictionary<int, int>();
			for (int i = 0; i < insertedCount; i++)
			{
				int value = desired[i].value;
				dictionary.TryGetValue(value, out var value2);
				dictionary[value] = value2 + 1;
			}
			Dictionary<int, int> dictionary2 = new Dictionary<int, int>();
			foreach (PickupIndex val in current)
			{
				if (!(val == PickupIndex.none))
				{
					int value3 = val.value;
					dictionary2.TryGetValue(value3, out var value4);
					dictionary2[value3] = value4 + 1;
				}
			}
			if (dictionary2.Count != dictionary.Count)
			{
				return false;
			}
			foreach (KeyValuePair<int, int> item in dictionary)
			{
				if (!dictionary2.TryGetValue(item.Key, out var value5))
				{
					return false;
				}
				if (value5 != item.Value)
				{
					return false;
				}
			}
			return true;
		}

		private static bool IngredientsMatchMultiset(PickupIndex[] actualSlots, List<PickupIndex> desired)
		{
			//IL_0024: 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_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			if (actualSlots == null)
			{
				return false;
			}
			if (actualSlots.Length != desired.Count)
			{
				return false;
			}
			Dictionary<PickupIndex, int> dictionary = new Dictionary<PickupIndex, int>();
			Dictionary<PickupIndex, int> dictionary2 = new Dictionary<PickupIndex, int>();
			foreach (PickupIndex val in actualSlots)
			{
				if (val == PickupIndex.none)
				{
					return false;
				}
				dictionary[val] = ((!dictionary.TryGetValue(val, out var value)) ? 1 : (value + 1));
			}
			for (int j = 0; j < desired.Count; j++)
			{
				PickupIndex key = desired[j];
				dictionary2[key] = ((!dictionary2.TryGetValue(key, out var value2)) ? 1 : (value2 + 1));
			}
			if (dictionary.Count != dictionary2.Count)
			{
				return false;
			}
			foreach (KeyValuePair<PickupIndex, int> item in dictionary)
			{
				if (!dictionary2.TryGetValue(item.Key, out var value3))
				{
					return false;
				}
				if (value3 != item.Value)
				{
					return false;
				}
			}
			return true;
		}

		private static int CountFilled(PickupIndex[] slots)
		{
			//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)
			if (slots == null)
			{
				return 0;
			}
			int num = 0;
			for (int i = 0; i < slots.Length; i++)
			{
				if (slots[i] != PickupIndex.none)
				{
					num++;
				}
			}
			return num;
		}

		private static int CountOf(PickupIndex[] slots, PickupIndex p)
		{
			//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)
			if (slots == null)
			{
				return 0;
			}
			int num = 0;
			for (int i = 0; i < slots.Length; i++)
			{
				if (slots[i] == p)
				{
					num++;
				}
			}
			return num;
		}

		[IteratorStateMachine(typeof(<EnsureEquipmentIsActive>d__23))]
		private static IEnumerator EnsureEquipmentIsActive(CharacterBody body, EquipmentIndex target)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <EnsureEquipmentIsActive>d__23(0)
			{
				body = body,
				target = target
			};
		}

		private static GameObject TryResolveChefStationObject(CharacterBody body)
		{
			//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_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)body))
			{
				return null;
			}
			MealPrepController[] array = Object.FindObjectsOfType<MealPrepController>();
			if (array == null || array.Length == 0)
			{
				return null;
			}
			MealPrepController val = null;
			float num = float.PositiveInfinity;
			Vector3 corePosition = body.corePosition;
			MealPrepController[] array2 = array;
			foreach (MealPrepController val2 in array2)
			{
				if (Object.op_Implicit((Object)(object)val2))
				{
					Vector3 val3 = ((Component)val2).transform.position - corePosition;
					float sqrMagnitude = ((Vector3)(ref val3)).sqrMagnitude;
					if (sqrMagnitude < num)
					{
						num = sqrMagnitude;
						val = val2;
					}
				}
			}
			if (!Object.op_Implicit((Object)(object)val))
			{
				return null;
			}
			IInteractable componentInChildren = ((Component)val).GetComponentInChildren<IInteractable>();
			Component val4 = (Component)(object)((componentInChildren is Component) ? componentInChildren : null);
			if (!Object.op_Implicit((Object)(object)val4))
			{
				return ((Component)val).gameObject;
			}
			return val4.gameObject;
		}

		[IteratorStateMachine(typeof(<HandleAcquisition>d__25))]
		private static IEnumerator HandleAcquisition(PickupIndex pi, int inventoryGoal, string actionPrefix)
		{
			//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)
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <HandleAcquisition>d__25(0)
			{
				pi = pi,
				inventoryGoal = inventoryGoal,
				actionPrefix = actionPrefix
			};
		}

		[IteratorStateMachine(typeof(<WaitForPendingPickup>d__26))]
		private static IEnumerator WaitForPendingPickup(PickupIndex pickupIndex, int expectedGain)
		{
			//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)
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <WaitForPendingPickup>d__26(0)
			{
				pickupIndex = pickupIndex,
				expectedGain = expectedGain
			};
		}

		private static int GetOwnedCount(PickupDef def, CharacterBody body)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Invalid comparison between Unknown and I4
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			if ((int)def.itemIndex != -1)
			{
				return body.inventory.GetItemCountPermanent(def.itemIndex);
			}
			if ((int)def.equipmentIndex != -1)
			{
				Inventory inventory = body.inventory;
				int equipmentSlotCount = inventory.GetEquipmentSlotCount();
				for (int i = 0; i < equipmentSlotCount; i++)
				{
					int equipmentSetCount = inventory.GetEquipmentSetCount((uint)i);
					for (int j = 0; j < equipmentSetCount; j++)
					{
						if (inventory.GetEquipment((uint)i, (uint)j).equipmentIndex == def.equipmentIndex)
						{
							return 1;
						}
					}
				}
			}
			return 0;
		}

		private static string GetStepName(ChefRecipe step)
		{
			string text = ((step.ResultIndex < ItemCatalog.itemCount) ? Language.GetString(ItemCatalog.GetItemDef((ItemIndex)step.ResultIndex)?.nameToken) : Language.GetString(EquipmentCatalog.GetEquipmentDef((EquipmentIndex)(step.ResultIndex - ItemCatalog.itemCount))?.nameToken));
			if (step is CraftPlanner.TradeRecipe)
			{
				return "<style=cIsUtility>Trade: " + text + "</style>";
			}
			return text;
		}

		private static PickupIndex GetPickupIndex(ChefRecipe step)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			if (step.ResultIndex < ItemCatalog.itemCount)
			{
				return PickupCatalog.FindPickupIndex((ItemIndex)step.ResultIndex);
			}
			return PickupCatalog.FindPickupIndex((EquipmentIndex)(step.ResultIndex - ItemCatalog.itemCount));
		}

		private static string GetDroneName(DroneIndex droneIdx)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			if ((int)droneIdx != -1)
			{
				GameObject val = DroneCatalog.GetDroneDef(droneIdx)?.bodyPrefab;
				if (Object.op_Implicit((Object)(object)val))
				{
					CharacterBody component = val.GetComponent<CharacterBody>();
					if (component != null)
					{
						return Language.GetString(component.baseNameToken);
					}
				}
			}
			return "Drone";
		}

		private static PickupIndex GetPickupIndexFromUnified(int unifiedIndex)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			if (unifiedIndex < ItemCatalog.itemCount)
			{
				return PickupCatalog.FindPickupIndex((ItemIndex)unifiedIndex);
			}
			return PickupCatalog.FindPickupIndex((EquipmentIndex)(unifiedIndex - ItemCatalog.itemCount));
		}

		private static void SetObjectiveText(string text)
		{
			if ((Object)(object)_currentObjective == (Object)null)
			{
				_currentObjective = ObjectiveTracker.CreateObjective(text);
			}
			else
			{
				_currentObjective.UpdateText(text);
			}
		}

		private static void CompleteCurrentObjective()
		{
			if ((Object)(object)_currentObjective != (Object)null)
			{
				_currentObjective.Complete();
				_currentObjective = null;
			}
		}

		private static void DumpChain(CraftPlanner.RecipeChain chain, int repeatCount)
		{
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			DebugLog.Trace(_log, "┌──────────────────────────────────────────────────────────┐");
			DebugLog.Trace(_log, $"│ CHAIN EXECUTION: {GetItemName(chain.ResultIndex)} (x{repeatCount})");
			DebugLog.Trace(_log, "├──────────────────────────────────────────────────────────┘");
			if (chain.DroneCostSparse.Length != 0)
			{
				DebugLog.Trace(_log, "│ [Resources] Drones Needed:");
				CraftPlanner.DroneRequirement[] droneCostSparse = chain.DroneCostSparse;
				for (int i = 0; i < droneCostSparse.Length; i++)
				{
					CraftPlanner.DroneRequirement droneRequirement = droneCostSparse[i];
					DebugLog.Trace(_log, "│   - " + GetDroneName(droneRequirement.DroneIdx) + " -> 1x " + GetItemName(droneRequirement.ScrapIndex));
				}
			}
			if (chain.AlliedTradeSparse.Length != 0)
			{
				DebugLog.Trace(_log, "│ [Resources] Allied Trades:");
				CraftPlanner.TradeRequirement[] alliedTradeSparse = chain.AlliedTradeSparse;
				for (int i = 0; i < alliedTradeSparse.Length; i++)
				{
					CraftPlanner.TradeRequirement tradeRequirement = alliedTradeSparse[i];
					DebugLog.Trace(_log, string.Format("│   - {0}: {1}x {2}", tradeRequirement.Donor?.userName ?? "Ally", tradeRequirement.TradesRequired, GetItemName(tradeRequirement.UnifiedIndex)));
				}
			}
			DebugLog.Trace(_log, "│ [Workflow] Sequence:");
			List<ChefRecipe> list = chain.Steps.Where((ChefRecipe s) => !(s is CraftPlanner.TradeRecipe)).ToList();
			for (int j = 0; j < list.Count; j++)
			{
				ChefRecipe chefRecipe = list[j];
				string text = FormatStepIngredients(chefRecipe);
				DebugLog.Trace(_log, $"│   Step {j + 1}: [{text}] —> {chefRecipe.ResultCount}x {GetItemName(chefRecipe.ResultIndex)}");
			}
			DebugLog.Trace(_log, "└──────────────────────────────────────────────────────────");
		}

		private static string FormatStepIngredients(ChefRecipe step)
		{
			if (step == null)
			{
				return string.Empty;
			}
			List<string> list = new List<string>(2);
			int num = Mathf.Max(0, (int)step.CountA);
			if (num > 0 && step.IngA >= 0)
			{
				list.Add($"{num}x {GetItemName(step.IngA)}");
			}
			int num2 = Mathf.Max(0, (int)step.CountB);
			if (step.HasB && num2 > 0 && step.IngB >= 0)
			{
				list.Add($"{num2}x {GetItemName(step.IngB)}");
			}
			return string.Join(", ", list);
		}

		private static string GetItemName(int unifiedIndex)
		{
			if (unifiedIndex < ItemCatalog.itemCount)
			{
				return Language.GetString(ItemCatalog.GetItemDef((ItemIndex)unifiedIndex)?.nameToken ?? "Unknown Item");
			}
			return Language.GetString(EquipmentCatalog.GetEquipmentDef((EquipmentIndex)(unifiedIndex - ItemCatalog.itemCount))?.nameToken ?? "Unknown Equip");
		}
	}
	internal static class ObjectiveTracker
	{
		public class ObjectiveToken : ScriptableObject
		{
			private class CancelWatcher : MonoBehaviour
			{
				public ObjectiveToken TargetToken;

				private float _holdTimer;

				private const float THRESHOLD = 0.6f;

				private void Update()
				{
					//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)
					KeyboardShortcut value = CookBook.AbortKey.Value;
					if (((KeyboardShortcut)(ref value)).IsPressed())
					{
						_holdTimer += Time.deltaTime;
						if (_holdTimer >= 0.6f)
						{
							TargetToken.Complete();
						}
					}
					else
					{
						_holdTimer = 0f;
					}
				}
			}

			public string RawText;

			public uint SenderNetID;

			public int TrackedItemIdx;

			private GameObject _inputWatcher;

			public void Init(string text, uint senderID = 0u, int itemIdx = -1)
			{
				//IL_001b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0025: Expected O, but got Unknown
				RawText = text;
				SenderNetID = senderID;
				TrackedItemIdx = itemIdx;
				_inputWatcher = new GameObject("CookBook_ObjectiveWatcher");
				_inputWatcher.AddComponent<CancelWatcher>().TargetToken = this;
			}

			public void UpdateText(string text)
			{
				RawText = text;
			}

			public void Complete()
			{
				if (Object.op_Implicit((Object)(object)_inputWatcher))
				{
					Object.Destroy((Object)(object)_inputWatcher);
				}
				RemoveToken(this);
				Object.Destroy((Object)(object)this);
			}
		}

		private class ChefObjectiveTracker : ObjectiveTracker
		{
			private ObjectiveToken MyToken => base.sourceDescriptor.source as ObjectiveToken;

			protected override bool IsDirty()
			{
				if ((Object)(object)MyToken != (Object)null)
				{
					return base.cachedString != ((ObjectiveTracker)this).GenerateString();
				}
				return false;
			}

			protected override string GenerateString()
			{
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0020: Unknown result type (might be due to invalid IL or missing references)
				//IL_0025: Unknown result type (might be due to invalid IL or missing references)
				if (!Object.op_Implicit((Object)(object)MyToken))
				{
					return string.Empty;
				}
				KeyboardShortcut value = CookBook.AbortKey.Value;
				KeyCode mainKey = ((KeyboardShortcut)(ref value)).MainKey;
				string text = ((object)(KeyCode)(ref mainKey)).ToString();
				return MyToken.RawText + " <style=cSub>[Hold " + text + " to Cancel]</style>";
			}
		}

		private static readonly List<ObjectiveToken> _activeObjectives = new List<ObjectiveToken>();

		internal static void Init()
		{
			ObjectivePanelController.collectObjectiveSources += OnCollectObjectiveSources;
		}

		internal static void Shutdown()
		{
			ObjectivePanelController.collectObjectiveSources -= OnCollectObjectiveSources;
			ClearAllObjectives();
		}

		internal static bool HasActiveObjectives()
		{
			return _activeObjectives.Count > 0;
		}

		internal static ObjectiveToken CreateObjective(string message, uint senderID = 0u, int itemIdx = -1)
		{
			ObjectiveToken objectiveToken = ScriptableObject.CreateInstance<ObjectiveToken>();
			objectiveToken.Init(message, senderID, itemIdx);
			_activeObjectives.Add(objectiveToken);
			return objectiveToken;
		}

		internal static void ClearSpecificRequest(uint senderID, int itemIdx)
		{
			for (int num = _activeObjectives.Count - 1; num >= 0; num--)
			{
				ObjectiveToken objectiveToken = _activeObjectives[num];
				if (objectiveToken.SenderNetID == senderID && objectiveToken.TrackedItemIdx == itemIdx)
				{
					objectiveToken.Complete();
				}
			}
		}

		internal static void ClearObjectivesFromSender(uint senderID)
		{
			for (int num = _activeObjectives.Count - 1; num >= 0; num--)
			{
				if (_activeObjectives[num].SenderNetID == senderID)
				{
					_activeObjectives[num].Complete();
				}
			}
		}

		internal static void AddAlliedRequest(NetworkUser sender, string command, int unifiedIdx, int quantity)
		{
			//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)
			if (!((Object)(object)sender == (Object)null))
			{
				string userName = sender.userName;
				string itemName = GetItemName(unifiedIdx);
				string text = string.Empty;
				if (command == "TRADE")
				{
					text = $"<style=cIsUtility>{userName} needs:</style> {quantity}x {itemName} <style=cStack>(Trade an Item)</style>";
				}
				else if (command == "SCRAP")
				{
					text = "<style=cIsUtility>" + userName + " needs:</style> " + itemName + " <style=cStack>(Scrap a Drone)</style>";
				}
				if (!string.IsNullOrEmpty(text))
				{
					string message = text;
					NetworkInstanceId netId = ((NetworkBehaviour)sender).netId;
					CreateObjective(message, ((NetworkInstanceId)(ref netId)).Value, unifiedIdx);
				}
			}
		}

		private static void RemoveToken(ObjectiveToken token)
		{
			if (_activeObjectives.Contains(token))
			{
				_activeObjectives.Remove(token);
			}
		}

		private static void OnCollectObjectiveSources(CharacterMaster viewerMaster, List<ObjectiveSourceDescriptor> output)
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser();
			if ((Object)(object)viewerMaster != (Object)(object)((firstLocalUser != null) ? firstLocalUser.cachedMaster : null))
			{
				return;
			}
			for (int num = _activeObjectives.Count - 1; num >= 0; num--)
			{
				ObjectiveToken objectiveToken = _activeObjectives[num];
				if (!Object.op_Implicit((Object)(object)objectiveToken))
				{
					_activeObjectives.RemoveAt(num);
				}
				else
				{
					output.Add(new ObjectiveSourceDescriptor
					{
						source = (Object)(object)objectiveToken,
						master = viewerMaster,
						objectiveType = typeof(ChefObjectiveTracker)
					});
				}
			}
		}

		internal static void ClearAllObjectives()
		{
			for (int num = _activeObjectives.Count - 1; num >= 0; num--)
			{
				if (Object.op_Implicit((Object)(object)_activeObjectives[num]))
				{
					_activeObjectives[num].Complete();
				}
			}
			_activeObjectives.Clear();
		}

		private static string GetItemName(int unifiedIdx)
		{
			int itemCount = ItemCatalog.itemCount;
			if (unifiedIdx < itemCount)
			{
				ItemDef itemDef = ItemCatalog.GetItemDef((ItemIndex)unifiedIdx);
				if (!Object.op_Implicit((Object)(object)itemDef))
				{
					return "Unknown Item";
				}
				return Language.GetString(itemDef.nameToken);
			}
			EquipmentDef equipmentDef = EquipmentCatalog.GetEquipmentDef((EquipmentIndex)(unifiedIdx - itemCount));
			if (!Object.op_Implicit((Object)(object)equipmentDef))
			{
				return "Unknown Equipment";
			}
			return Language.GetString(equipmentDef.nameToken);
		}
	}
	internal sealed class CraftPlanner
	{
		internal readonly struct StepDelta3
		{
			public readonly int I0;

			public readonly int V0;

			public readonly int I1;

			public readonly int V1;

			public readonly int I2;

			public readonly int V2;

			public StepDelta3(int i0, int v0, int i1, int v1, int i2, int v2)
			{
				I0 = i0;
				V0 = v0;
				I1 = i1;
				V1 = v1;
				I2 = i2;
				V2 = v2;
			}

			public int GetFor(int idx)
			{
				if (idx == I0)
				{
					return V0;
				}
				if (idx == I1)
				{
					return V1;
				}
				if (idx == I2)
				{
					return V2;
				}
				return 0;
			}
		}

		internal readonly struct CostShapeKey : IEquatable<CostShapeKey>
		{
			public readonly int Hash1;

			public readonly int Hash2;

			public readonly int PhysLen;

			public readonly int DroneLen;

			public readonly int TradeLen;

			public CostShapeKey(int hash1, int hash2, int physLen, int droneLen, int tradeLen)
			{
				Hash1 = hash1;
				Hash2 = hash2;
				PhysLen = physLen;
				DroneLen = droneLen;
				TradeLen = tradeLen;
			}

			public bool Equals(CostShapeKey other)
			{
				if (Hash1 == other.Hash1 && Hash2 == other.Hash2 && PhysLen == other.PhysLen && DroneLen == other.DroneLen)
				{
					return TradeLen == other.TradeLen;
				}
				return false;
			}

			public override int GetHashCode()
			{
				return (Hash1 * 397) ^ Hash2;
			}
		}

		internal readonly struct BestCostRecord
		{
			public readonly Ingredient[] Phys;

			public readonly (int scrapIdx, int need)[] Drone;

			public readonly TradeRequirement[] Trades;

			public BestCostRecord(Ingredient[] phys, (int scrapIdx, int need)[] drone, TradeRequirement[] trades)
			{
				Phys = phys ?? Array.Empty<Ingredient>();
				Drone = drone ?? Array.Empty<(int, int)>();
				Trades = trades ?? Array.Empty<TradeRequirement>();
			}
		}

		private readonly struct DroneKey : IEquatable<DroneKey>
		{
			public readonly uint OwnerNetId;

			public readonly int DroneIdx;

			public DroneKey(uint ownerNetId, int droneIdx)
			{
				OwnerNetId = ownerNetId;
				DroneIdx = droneIdx;
			}

			public bool Equals(DroneKey other)
			{
				if (OwnerNetId == other.OwnerNetId)
				{
					return DroneIdx == other.DroneIdx;
				}
				return false;
			}

			public override int GetHashCode()
			{
				return (int)(OwnerNetId * 397) ^ DroneIdx;
			}
		}

		internal sealed class TradeRecipe : ChefRecipe
		{
			public NetworkUser Donor;

			public int ItemUnifiedIndex;

			public TradeRecipe(NetworkUser donor, int itemIndex)
				: base(itemIndex, 1, -1, -1, 0, 0)
			{
				Donor = donor;
				ItemUnifiedIndex = itemIndex;
			}

			public override int GetHashCode()
			{
				//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)
				int num = 17 * 31;
				NetworkUser donor = Donor;
				int num2;
				if (donor == null)
				{
					num2 = 0;
				}
				else
				{
					NetworkInstanceId netId = ((NetworkBehaviour)donor).netId;
					num2 = ((object)(NetworkInstanceId)(ref netId)).GetHashCode();
				}
				return ((num ^ num2) * 31) ^ ItemUnifiedIndex;
			}
		}

		internal struct TradeRequirement
		{
			public NetworkUser Donor;

			public int UnifiedIndex;

			public int TradesRequired;
		}

		internal struct DroneRequirement
		{
			public NetworkUser Owner;

			public DroneIndex DroneIdx;

			public int Count;

			public int TotalUpgradeCount;

			public int ScrapIndex;
		}

		internal sealed class CraftableEntry
		{
			public int ResultIndex;

			public int ResultCount;

			public int MinDepth;

			public List<RecipeChain> Chains = new List<RecipeChain>();

			public bool IsItem => ResultIndex < ItemCatalog.itemCount;

			public ItemIndex ResultItem
			{
				get
				{
					if (IsItem)
					{
						return (ItemIndex)ResultIndex;
					}
					return (ItemIndex)(-1);
				}
			}

			public EquipmentIndex ResultEquipment
			{
				get
				{
					if (IsItem)
					{
						return (EquipmentIndex)(-1);
					}
					return (EquipmentIndex)(ResultIndex - ItemCatalog.itemCount);
				}
			}
		}

		internal sealed class RecipeChain
		{
			private List<ChefRecipe> _stepsCache;

			internal RecipeChain Parent { get; }

			internal ChefRecipe LastStep { get; }

			internal ChefRecipe FirstStep { get; }

			internal int Depth { get; }

			internal IReadOnlyList<ChefRecipe> Steps => MaterializeSteps();

			internal Ingredient[] PhysicalCostSparse { get; }

			internal DroneRequirement[] DroneCostSparse { get; }

			internal TradeRequirement[] AlliedTradeSparse { get; }

			internal int ResultIndex { get; }

			internal int ResultCount { get; }

			internal int ResultSurplus { get; }

			internal StepDelta3 Delta { get; }

			internal bool IsBridgeIntermediate { get; }

			private IReadOnlyList<ChefRecipe> MaterializeSteps()
			{
				if (_stepsCache != null)
				{
					return _stepsCache;
				}
				List<ChefRecipe> list = new List<ChefRecipe>(Depth);
				for (RecipeChain recipeChain = this; recipeChain != null; recipeChain = recipeChain.Parent)
				{
					list.Add(recipeChain.LastStep);
				}
				list.Reverse();
				_stepsCache = list;
				return list;
			}

			internal RecipeChain(ChefRecipe recipe, Ingredient[] phys, DroneRequirement[] drones, TradeRequirement[] trades)
			{
				Parent = null;
				LastStep = recipe;
				FirstStep = recipe;
				Depth = 1;
				ResultIndex = recipe.ResultIndex;
				ResultCount = recipe.ResultCount;
				PhysicalCostSparse = phys;
				DroneCostSparse = drones;
				AlliedTradeSparse = trades;
				int resultIndex = recipe.ResultIndex;
				int resultCount = recipe.ResultCount;
				int i = recipe.IngA;
				int num = ((recipe.CountA > 0 && recipe.IngA >= 0) ? (-recipe.CountA) : 0);
				int i2 = (recipe.HasB ? recipe.IngB : (-1));
				int num2 = ((recipe.HasB && recipe.CountB > 0 && recipe.IngB >= 0) ? (-recipe.CountB) : 0);
				if (num == 0)
				{
					i = -1;
				}
				if (num2 == 0)
				{
					i2 = -1;
				}
				Delta = new StepDelta3(resultIndex, resultCount, i, num, i2, num2);
				ResultSurplus = GetNetSurplusFor(recipe.ResultIndex);
				IsBridgeIntermediate = false;
			}

			internal RecipeChain(RecipeChain parent, ChefRecipe next, Ingredient[] phys, DroneRequirement[] drones, TradeRequirement[] trades, bool isIntermediate)
			{
				Parent = parent;
				LastStep = next;
				FirstStep = parent.FirstStep;
				Depth = parent.Depth + 1;
				ResultIndex = next.ResultIndex;
				ResultCount = next.ResultCount;
				PhysicalCostSparse = phys;
				DroneCostSparse = drones;
				AlliedTradeSparse = trades;
				int resultIndex = next.ResultIndex;
				int resultCount = next.ResultCount;
				int i = next.IngA;
				int num = ((next.CountA > 0 && next.IngA >= 0) ? (-next.CountA) : 0);
				int i2 = (next.HasB ? next.IngB : (-1));
				int num2 = ((next.HasB && next.CountB > 0 && next.IngB >= 0) ? (-next.CountB) : 0);
				if (num == 0)
				{
					i = -1;
				}
				if (num2 == 0)
				{
					i2 = -1;
				}
				Delta = new StepDelta3(resultIndex, resultCount, i, num, i2, num2);
				ResultSurplus = GetNetSurplusFor(next.ResultIndex);
				IsBridgeIntermediate = isIntermediate;
			}

			public int GetNetSurplusFor(int itemIndex)
			{
				int num = 0;
				for (RecipeChain recipeChain = this; recipeChain != null; recipeChain = recipeChain.Parent)
				{
					num += recipeChain.Delta.GetFor(itemIndex);
				}
				return num;
			}

			public int GetMaxAffordable(InventorySnapshot snap)
			{
				int[] physicalStacks = snap.PhysicalStacks;
				int[] dronePotential = snap.DronePotential;
				Dictionary<NetworkUser, int[]> alliedPhysicalStacks = snap.AlliedPhysicalStacks;
				Dictionary<NetworkUser, int> tradesRemaining = snap.TradesRemaining;
				int num = int.MaxValue;
				if (PhysicalCostSparse != null && physicalStacks != null)
				{
					Ingredient[] physicalCostSparse = PhysicalCostSparse;
					for (int i = 0; i < physicalCostSparse.Length; i++)
					{
						Ingredient ingredient = physicalCostSparse[i];
						if (ingredient.Count > 0)
						{
							int unifiedIndex = ingredient.UnifiedIndex;
							if ((uint)unifiedIndex >= (uint)physicalStacks.Length)
							{
								return 0;
							}
							num = Math.Min(num, physicalStacks[unifiedIndex] / ingredient.Count);
							if (num == 0)
							{
								return 0;
							}
						}
					}
				}
				if (DroneCostSparse != null && dronePotential != null && dronePotential.Length != 0)
				{
					int[] array = null;
					DroneRequirement[] droneCostSparse = DroneCostSparse;
					for (int i = 0; i < droneCostSparse.Length; i++)
					{
						DroneRequirement droneRequirement = droneCostSparse[i];
						if (droneRequirement.Count > 0)
						{
							int scrapIndex = droneRequirement.ScrapIndex;
							if ((uint)scrapIndex >= (uint)dronePotential.Length)
							{
								return 0;
							}
							if (array == null)
							{
								array = new int[dronePotential.Length];
							}
							array[scrapIndex] += droneRequirement.Count;
						}
					}
					if (array != null)
					{
						for (int j = 0; j < array.Length; j++)
						{
							int num2 = array[j];
							if (num2 > 0)
							{
								num = Math.Min(num, dronePotential[j] / num2);
								if (num == 0)
								{
									return 0;
								}
							}
						}
					}
				}
				if (AlliedTradeSparse != null)
				{
					if (alliedPhysicalStacks == null || tradesRemaining == null)
					{
						return 0;
					}
					TradeRequirement[] alliedTradeSparse = AlliedTradeSparse;
					for (int i = 0; i < alliedTradeSparse.Length; i++)
					{
						TradeRequirement tradeRequirement = alliedTradeSparse[i];
						if (tradeRequirement.TradesRequired > 0)
						{
							if ((Object)(object)tradeRequirement.Donor == (Object)null)
							{
								return 0;
							}
							if (!alliedPhysicalStacks.TryGetValue(tradeRequirement.Donor, out var value) || value == null)
							{
								return 0;
							}
							if (!tradesRemaining.TryGetValue(tradeRequirement.Donor, out var value2))
							{
								return 0;
							}
							int unifiedIndex2 = tradeRequirement.UnifiedIndex;
							if ((uint)unifiedIndex2 >= (uint)value.Length)
							{
								return 0;
							}
							int val = value[unifiedIndex2] / tradeRequirement.TradesRequired;
							int val2 = value2 / tradeRequirement.TradesRequired;
							num = Math.Min(num, Math.Min(val, val2));
							if (num == 0)
							{
								return 0;
							}
						}
					}
				}
				if (num != int.MaxValue)
				{
					return num;
				}
				return 0;
			}
		}

		private readonly ManualLogSource _log;

		private int _maxDepth;

		private readonly int _itemCount;

		internal readonly int _totalDefCount;

		private readonly HashSet<int> _allIngredientIndices = new HashSet<int>();

		private bool isPoolingEnabled;

		private bool canScrapDrones;

		private readonly int[] _maxDemand;

		private readonly int _maskWords;

		private ulong[] _haveMaskBuffer;

		private Dictionary<int, CraftableEntry> _entryCache = new Dictionary<int, CraftableEntry>();

		private readonly Dictionary<long, Dictionary<CostShapeKey, BestCostRecord>> _bestByOutputAndShape = new Dictionary<long, Dictionary<CostShapeKey, BestCostRecord>>();

		private readonly Dictionary<long, Dictionary<int, List<BestCostRecord>>> _frontierBucketsByOutput = new Dictionary<long, Dictionary<int, List<BestCostRecord>>>();

		private readonly Dictionary<int, HashSet<ulong>> _seenChainSigByResult = new Dictionary<int, HashSet<ulong>>();

		private int[] _candidateMark;

		private int _candidateStamp = 1;

		private int[] _candidatesScratch;

		private int _candidateCount;

		private int[] _candidateBridgeMark;

		private int _candidateBridgeStamp = 1;

		private int[] _missingMark;

		private int _missingStamp = 1;

		private int[] _missingScratch;

		private int _missingCount;

		private int[] _deficitsScratch;

		private bool[] _activeMasterRecipe;

		private ChefRecipe[] _activeRecipeByMaster;

		private int[] _droneNeedScratch;

		private int[]