Decompiled source of NoLazyWorkers v1.1.1

NoLazyWorkers.dll

Decompiled 3 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using FishNet;
using FishNet.Connection;
using FishNet.Object;
using HarmonyLib;
using MelonLoader;
using Microsoft.CodeAnalysis;
using NoLazyWorkers;
using ScheduleOne;
using ScheduleOne.DevUtilities;
using ScheduleOne.Employees;
using ScheduleOne.EntityFramework;
using ScheduleOne.ItemFramework;
using ScheduleOne.Management;
using ScheduleOne.Management.SetterScreens;
using ScheduleOne.Management.UI;
using ScheduleOne.NPCs;
using ScheduleOne.NPCs.Behaviour;
using ScheduleOne.ObjectScripts;
using ScheduleOne.Persistence;
using ScheduleOne.Persistence.Datas;
using ScheduleOne.Persistence.Loaders;
using ScheduleOne.Product;
using ScheduleOne.Quests;
using ScheduleOne.UI.Management;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: MelonInfo(typeof(global::NoLazyWorkers.NoLazyWorkers), "NoLazyWorkers", "1.1.1", "Archie", null)]
[assembly: MelonGame("TVGS", "Schedule I")]
[assembly: HarmonyDontPatchAll]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("NoLazyWorkers")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+bed3552323ceb153c985b5d62069d72cbc927016")]
[assembly: AssemblyProduct("NoLazyWorkers")]
[assembly: AssemblyTitle("NoLazyWorkers")]
[assembly: NeutralResourcesLanguage("en-US")]
[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;
		}
	}
}
namespace NoLazyWorkers
{
	public static class BotanistExtensions
	{
	}
	[HarmonyPatch(typeof(BotanistConfigPanel), "Bind")]
	public class BotanistConfigPanelBindPatch
	{
		private static void Postfix(BotanistConfigPanel __instance, List<EntityConfiguration> configs)
		{
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
				{
					MelonLogger.Msg($"BotanistConfigPanelBindPatch: Processing configs, count: {configs?.Count ?? 0}");
				}
				if ((Object)(object)__instance == (Object)null)
				{
					MelonLogger.Error("BotanistConfigPanelBindPatch: __instance is null");
					return;
				}
				if ((Object)(object)__instance.SuppliesUI == (Object)null)
				{
					MelonLogger.Error("BotanistConfigPanelBindPatch: SuppliesUI is null");
					return;
				}
				if ((Object)(object)__instance.PotsUI == (Object)null)
				{
					MelonLogger.Error("BotanistConfigPanelBindPatch: PotsUI is null");
					return;
				}
				((Component)__instance.SuppliesUI).gameObject.SetActive(false);
				if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
				{
					MelonLogger.Msg("BotanistConfigPanelBindPatch: Hid SuppliesUI");
				}
				RectTransform component = ((Component)__instance.SuppliesUI).GetComponent<RectTransform>();
				RectTransform component2 = ((Component)__instance.PotsUI).GetComponent<RectTransform>();
				if ((Object)(object)component == (Object)null || (Object)(object)component2 == (Object)null)
				{
					MelonLogger.Error("BotanistConfigPanelBindPatch: SuppliesUI or PotsUI RectTransform is null");
					return;
				}
				float y = component.anchoredPosition.y;
				component2.anchoredPosition = new Vector2(component2.anchoredPosition.x, y);
				if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
				{
					MelonLogger.Msg($"BotanistConfigPanelBindPatch: Moved PotsUI to y={y}");
				}
			}
			catch (Exception arg)
			{
				MelonLogger.Error($"BotanistConfigPanelBindPatch: Failed, error: {arg}");
			}
		}
	}
	[HarmonyPatch(typeof(Quest_Botanists), "MinPass")]
	public static class QuestBotanistsMinPassPatch
	{
		[HarmonyPrefix]
		public static bool Prefix(Quest_Botanists __instance)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Invalid comparison between Unknown and I4
			try
			{
				if ((int)__instance.AssignSuppliesEntry.State == 1)
				{
					foreach (Employee employee in ((Quest_Employees)__instance).GetEmployees())
					{
						Botanist val = (Botanist)(object)((employee is Botanist) ? employee : null);
						if (!((Object)(object)val != (Object)null))
						{
							continue;
						}
						EntityConfiguration configuration = val.Configuration;
						BotanistConfiguration val2 = (BotanistConfiguration)(object)((configuration is BotanistConfiguration) ? configuration : null);
						if (val2 == null)
						{
							continue;
						}
						foreach (Pot assignedPot in val2.AssignedPots)
						{
							if (ConfigurationExtensions.PotSupply.TryGetValue(assignedPot, out var value) && value != null)
							{
								__instance.AssignSuppliesEntry.Complete();
								if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
								{
									MelonLogger.Msg("QuestBotanistsMinPassPatch: Completed AssignSuppliesEntry for botanist " + ((Object)val).name + ", pot " + ((Object)assignedPot).name);
								}
								return true;
							}
						}
					}
				}
				return true;
			}
			catch (Exception arg)
			{
				MelonLogger.Error($"QuestBotanistsMinPassPatch: Failed, error: {arg}");
				return true;
			}
		}
	}
	[HarmonyPatch(typeof(BotanistConfiguration), "GetSaveString")]
	public static class BotanistConfigurationGetSaveStringPatch
	{
		[HarmonyPrefix]
		public static void Prefix(BotanistConfiguration __instance)
		{
			__instance.Supplies.SelectedObject = null;
		}
	}
	[HarmonyPatch(typeof(Botanist), "GetDryableInSupplies")]
	public static class BotanistGetDryableInSuppliesPatch
	{
		[HarmonyPrefix]
		public static bool Prefix(Botanist __instance, ref QualityItemInstance __result)
		{
			try
			{
				EntityConfiguration configuration = __instance.Configuration;
				BotanistConfiguration val = (BotanistConfiguration)(object)((configuration is BotanistConfiguration) ? configuration : null);
				if (val == null)
				{
					MelonLogger.Warning("BotanistGetDryableInSuppliesPatch: BotanistConfiguration is null");
					__result = null;
					return false;
				}
				foreach (Pot assignedPot in val.AssignedPots)
				{
					if (!ConfigurationExtensions.PotSupply.TryGetValue(assignedPot, out var value) || (Object)(object)value.SelectedObject == (Object)null)
					{
						continue;
					}
					val.Supplies.SelectedObject = value.SelectedObject;
					? val2 = ((NPC)__instance).Movement;
					BuildableItem selectedObject = value.SelectedObject;
					if (!((NPCMovement)val2).CanGetTo((ITransitEntity)(object)((selectedObject is ITransitEntity) ? selectedObject : null), 1f))
					{
						continue;
					}
					List<ItemSlot> list = new List<ItemSlot>();
					BuildableItem selectedObject2 = value.SelectedObject;
					list.AddRange(((ITransitEntity)((selectedObject2 is ITransitEntity) ? selectedObject2 : null)).OutputSlots);
					foreach (ItemSlot item in list)
					{
						if (item.Quantity > 0 && ItemFilter_Dryable.IsItemDryable(item.ItemInstance))
						{
							ItemInstance itemInstance = item.ItemInstance;
							__result = (QualityItemInstance)(object)((itemInstance is QualityItemInstance) ? itemInstance : null);
							if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
							{
								MelonLogger.Msg("BotanistGetDryableInSuppliesPatch: Found dryable " + (((ItemInstance)(__result?)).ID ?? "null") + " in pot " + ((Object)assignedPot).name + "'s supply");
							}
							return false;
						}
					}
				}
				__result = null;
				return false;
			}
			catch (Exception arg)
			{
				MelonLogger.Error($"BotanistGetDryableInSuppliesPatch: Failed, error: {arg}");
				__result = null;
				return false;
			}
		}
	}
	[HarmonyPatch(typeof(PotActionBehaviour), "CanGetToSupplies")]
	public static class PotActionBehaviourCanGetToSuppliesPatch
	{
		[HarmonyPrefix]
		public static bool Prefix(PotActionBehaviour __instance, ref bool __result)
		{
			try
			{
				if ((Object)(object)__instance.AssignedPot == (Object)null)
				{
					MelonLogger.Warning("PotActionBehaviourCanGetToSuppliesPatch: AssignedPot is null");
					__result = false;
					return false;
				}
				NPC npc = ((Behaviour)__instance).Npc;
				Botanist val = (Botanist)(object)((npc is Botanist) ? npc : null);
				if ((Object)(object)val == (Object)null)
				{
					MelonLogger.Warning("PotActionBehaviourCanGetToSuppliesPatch: Botanist is null");
					__result = false;
					return false;
				}
				__result = ((NPC)val).Movement.CanGetTo((ITransitEntity)(object)__instance.AssignedPot, 1f);
				return false;
			}
			catch (Exception arg)
			{
				MelonLogger.Error($"PotActionBehaviourCanGetToSuppliesPatch: Failed, error: {arg}");
				__result = false;
				return false;
			}
		}
	}
	[HarmonyPatch(typeof(PotActionBehaviour), "StartAction")]
	public static class PotActionBehaviourStartActionPatch
	{
		[HarmonyPrefix]
		public static void Prefix(PotActionBehaviour __instance)
		{
			try
			{
				if ((Object)(object)__instance.AssignedPot == (Object)null)
				{
					MelonLogger.Warning("PotActionBehaviourStartActionPatch: AssignedPot is null");
					return;
				}
				NPC npc = ((Behaviour)__instance).Npc;
				Botanist val = (Botanist)(object)((npc is Botanist) ? npc : null);
				if (!((Object)(object)val == (Object)null))
				{
					EntityConfiguration configuration = val.Configuration;
					BotanistConfiguration val2 = (BotanistConfiguration)(object)((configuration is BotanistConfiguration) ? configuration : null);
					if (val2 != null)
					{
						if (!ConfigurationExtensions.PotSupply.TryGetValue(__instance.AssignedPot, out var value) || (Object)(object)value.SelectedObject == (Object)null)
						{
							MelonLogger.Warning("PotActionBehaviourStartActionPatch: Pot supply not found or null for pot " + ((Object)__instance.AssignedPot).name);
							val2.Supplies.SelectedObject = null;
							return;
						}
						val2.Supplies.SelectedObject = value.SelectedObject;
						if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
						{
							BuildableItem selectedObject = value.SelectedObject;
							MelonLogger.Msg("PotActionBehaviourStartActionPatch: Set Botanist.Supplies to " + (((selectedObject != null) ? ((Object)selectedObject).name : null) ?? "null") + " for pot " + ((Object)__instance.AssignedPot).name);
						}
						return;
					}
				}
				MelonLogger.Warning("PotActionBehaviourStartActionPatch: Botanist or BotanistConfiguration is null");
			}
			catch (Exception arg)
			{
				MelonLogger.Error($"PotActionBehaviourStartActionPatch: Failed, error: {arg}");
			}
		}
	}
	public static class ChemistExtensions
	{
		public static ItemInstance GetItemInSupply(this Chemist chemist, MixingStation station, string id)
		{
			MixingStationConfiguration val = ConfigurationExtensions.MixingConfig[station];
			ObjectField val2 = ConfigurationExtensions.MixingSupply[station];
			List<ItemSlot> list = new List<ItemSlot>();
			BuildableItem selectedObject = val2.SelectedObject;
			if ((Object)(object)selectedObject != (Object)null && ((NPC)chemist).behaviour.Npc.Movement.CanGetTo((ITransitEntity)(object)((selectedObject is ITransitEntity) ? selectedObject : null), 1f))
			{
				list.AddRange(((ITransitEntity)((selectedObject is ITransitEntity) ? selectedObject : null)).OutputSlots);
				for (int i = 0; i < list.Count; i++)
				{
					if (list[i].Quantity > 0 && list[i].ItemInstance.ID.ToLower() == id.ToLower())
					{
						return list[i].ItemInstance;
					}
				}
			}
			return null;
		}
	}
	[HarmonyPatch(typeof(Chemist))]
	public class ChemistPatch
	{
		[HarmonyPatch("GetMixingStationsReadyToStart")]
		[HarmonyPrefix]
		private static bool GetMixingStationsReadyToStartPrefix(Chemist __instance, ref List<MixingStation> __result)
		{
			try
			{
				List<MixingStation> list = new List<MixingStation>();
				if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
				{
					MelonLogger.Msg(string.Format("ChemistPatch.GetMixingStationsReadyToStart: Checking stations for {0}, total stations={1}", ((__instance != null) ? ((Object)__instance).name : null) ?? "null", __instance.configuration.MixStations.Count));
				}
				foreach (MixingStation mixStation in __instance.configuration.MixStations)
				{
					if (((IUsable)mixStation).IsInUse || mixStation.CurrentMixOperation != null)
					{
						continue;
					}
					if (!ConfigurationExtensions.MixingConfig.TryGetValue(mixStation, out var value))
					{
						if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
						{
							MelonLogger.Warning("ChemistPatch.GetMixingStationsReadyToStart: MixerConfig missing for station " + (((mixStation != null) ? ((NetworkBehaviour)mixStation).ObjectId.ToString() : null) ?? "null"));
						}
						continue;
					}
					ItemField mixerItemForProductSlot = NoLazyUtilities.GetMixerItemForProductSlot(mixStation);
					if ((Object)(object)((mixerItemForProductSlot != null) ? mixerItemForProductSlot.SelectedItem : null) == (Object)null)
					{
						continue;
					}
					float value2 = value.StartThrehold.Value;
					int mixQuantity = mixStation.GetMixQuantity();
					bool flag = (float)mixQuantity >= value2 && (float)mixStation.ProductSlot.Quantity >= value2 && mixStation.OutputSlot.Quantity == 0;
					bool flag2 = false;
					bool flag3 = false;
					ObjectField val = ConfigurationExtensions.MixingSupply[mixStation];
					if (!flag && (Object)(object)val?.SelectedObject != (Object)null)
					{
						ConfigurationExtensions.NPCSupply[(NPC)(object)__instance] = val;
						object obj;
						if (mixerItemForProductSlot == null)
						{
							obj = null;
						}
						else
						{
							ItemDefinition selectedItem = mixerItemForProductSlot.SelectedItem;
							obj = ((selectedItem != null) ? selectedItem.GetDefaultInstance(1) : null);
						}
						ItemInstance item = (ItemInstance)obj;
						if ((Object)(object)mixerItemForProductSlot.SelectedItem != (Object)null)
						{
							item = mixerItemForProductSlot.SelectedItem.GetDefaultInstance(1);
						}
						flag3 = HasSufficientItems(__instance, value2, item);
						flag2 = mixStation.OutputSlot.Quantity == 0 && (float)mixStation.ProductSlot.Quantity >= value2 && flag3;
					}
					if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
					{
						object[] obj2 = new object[12]
						{
							((NetworkBehaviour)mixStation).ObjectId,
							null,
							null,
							null,
							null,
							null,
							null,
							null,
							null,
							null,
							null,
							null
						};
						object obj3;
						if (val == null)
						{
							obj3 = null;
						}
						else
						{
							BuildableItem selectedObject = val.SelectedObject;
							obj3 = ((selectedObject != null) ? ((NetworkBehaviour)selectedObject).ObjectId.ToString() : null);
						}
						if (obj3 == null)
						{
							obj3 = "null";
						}
						obj2[1] = obj3;
						obj2[2] = ((IUsable)mixStation).IsInUse;
						obj2[3] = mixStation.CurrentMixOperation != null;
						obj2[4] = flag;
						obj2[5] = flag2;
						obj2[6] = mixQuantity;
						obj2[7] = mixStation.ProductSlot.Quantity;
						obj2[8] = mixStation.OutputSlot.Quantity;
						obj2[9] = value2;
						obj2[10] = mixerItemForProductSlot.SelectedItem?.Name ?? "null";
						obj2[11] = (flag2 ? $", hasSufficientItems={flag3}" : "");
						MelonLogger.Msg(string.Format("ChemistPatch.GetMixingStationsReadyToStart: Station {0}, Supply={1}, IsInUse={2}, CurrentMixOperation={3}, canStartMix={4}, canRestock={5}, mixQuantity={6}, productQuantity={7}, outputQuantity={8}, threshold={9}, mixerItem={10}{11}", obj2));
					}
					if (flag || flag2)
					{
						list.Add(mixStation);
					}
				}
				__result = list;
				if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
				{
					MelonLogger.Msg(string.Format("ChemistPatch.GetMixingStationsReadyToStart: Found {0} stations ready for {1}", list.Count, ((__instance != null) ? ((Object)__instance).name : null) ?? "null"));
				}
				return false;
			}
			catch (Exception arg)
			{
				MelonLogger.Error(string.Format("ChemistPatch.GetMixingStationsReadyToStart: Failed for chemist: {0}, error: {1}", ((__instance != null) ? ((Object)__instance).name : null) ?? "null", arg));
				__result = new List<MixingStation>();
				return false;
			}
		}

		public static ItemDefinition GetAnyMixer(ITransitEntity supply, float threshold, string preferredId = null)
		{
			if (supply == null || supply.OutputSlots == null)
			{
				if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
				{
					MelonLogger.Warning("GetAnyMixer: Supply or OutputSlots is null");
				}
				return null;
			}
			List<PropertyItemDefinition> validItems = NetworkSingleton<ProductManager>.Instance.ValidMixIngredients;
			IEnumerable<ItemSlot> source = supply.OutputSlots.Where(delegate(ItemSlot s)
			{
				ItemSlot obj = s;
				return ((obj != null) ? obj.ItemInstance : null) != null && validItems.Any((PropertyItemDefinition v) => ((ItemDefinition)v).ID.ToLower() == s.ItemInstance.ID.ToLower()) && (float)s.Quantity >= threshold;
			});
			if (preferredId != null)
			{
				ItemSlot val = source.FirstOrDefault((Func<ItemSlot, bool>)((ItemSlot s) => s.ItemInstance.ID.ToLower() == preferredId.ToLower()));
				if (val != null)
				{
					if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
					{
						MelonLogger.Msg($"GetAnyMixer: Selected preferred item {preferredId} with quantity={val.Quantity}");
					}
					return val.ItemInstance.definition;
				}
			}
			ItemSlot val2 = source.FirstOrDefault();
			if (val2 != null && (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs))
			{
				MelonLogger.Msg($"GetAnyMixer: Selected first available item {val2.ItemInstance.ID} with quantity={val2.Quantity}");
			}
			return (val2 == null) ? null : val2.ItemInstance?.definition;
		}

		public static bool HasSufficientItems(Chemist chemist, float threshold, ItemInstance item)
		{
			return (float)NoLazyUtilities.GetAmountInInventoryAndSupply((NPC)(object)chemist, item?.definition) > threshold;
		}
	}
	[HarmonyPatch(typeof(ChemistConfiguration))]
	public class ChemistConfigurationPatch
	{
		[HarmonyPostfix]
		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		private static void Postfix(ChemistConfiguration __instance)
		{
			try
			{
				Chemist chemist = __instance.chemist;
				ConfigurationExtensions.NPCConfig[(NPC)(object)chemist] = (EntityConfiguration)(object)__instance;
			}
			catch (Exception arg)
			{
				MelonLogger.Error($"ChemistConfigurationPatch: Failed, error: {arg}");
			}
		}
	}
	[HarmonyPatch(typeof(StartMixingStationBehaviour))]
	public class StartMixingStationBehaviourPatch
	{
		private class StateData
		{
			public Coroutine WalkToSuppliesRoutine { get; set; }

			public Coroutine GrabRoutine { get; set; }

			public ItemDefinition TargetMixer { get; set; }

			public bool ClearMixerSlot { get; set; }

			public int QuantityToFetch { get; set; }

			public EState CurrentState { get; set; }

			public ObjectField LastSupply { get; set; }

			public bool CookPending { get; set; }

			public bool Any { get; set; }
		}

		public enum EState
		{
			Idle,
			WalkingToSupplies,
			GrabbingSupplies,
			WalkingToStation,
			Cooking
		}

		private static readonly Dictionary<StartMixingStationBehaviour, StateData> states = new Dictionary<StartMixingStationBehaviour, StateData>();

		[HarmonyPatch("Awake")]
		[HarmonyPostfix]
		private static void AwakePostfix(StartMixingStationBehaviour __instance)
		{
			try
			{
				states[__instance] = new StateData
				{
					CurrentState = EState.Idle,
					WalkToSuppliesRoutine = null,
					GrabRoutine = null,
					TargetMixer = null,
					ClearMixerSlot = false,
					QuantityToFetch = 0,
					LastSupply = null,
					CookPending = false,
					Any = false
				};
				if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
				{
					Chemist chemist = __instance.chemist;
					MelonLogger.Msg("StartMixingStationBehaviourPatch.Awake: Initialized state for " + (((chemist != null) ? ((NPC)chemist).fullName : null) ?? "null"));
				}
			}
			catch (Exception arg)
			{
				Chemist chemist2 = __instance.chemist;
				MelonLogger.Error(string.Format("StartMixingStationBehaviourPatch.Awake: Failed for chemist: {0}, error: {1}", ((chemist2 != null) ? ((NPC)chemist2).fullName : null) ?? "null", arg));
			}
		}

		[HarmonyPatch("ActiveMinPass")]
		[HarmonyPrefix]
		private static bool Prefix(StartMixingStationBehaviour __instance)
		{
			//IL_05b9: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (!InstanceFinder.IsServer)
				{
					if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
					{
						MelonLogger.Msg("StartMixingStationBehaviourPatch.ActiveMinPass: Skipping, not server");
					}
					return false;
				}
				Chemist chemist = __instance.chemist;
				MixingStation targetStation = __instance.targetStation;
				if ((Object)(object)targetStation == (Object)null || (Object)(object)chemist == (Object)null || !ConfigurationExtensions.NPCConfig.TryGetValue((NPC)(object)chemist, out var _))
				{
					Disable(__instance);
					if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
					{
						MelonLogger.Warning("StartMixingStationBehaviourPatch.ActiveMinPass: Station, Chemist, or ChemistConfig null for chemist: " + (((chemist != null) ? ((NPC)chemist).fullName : null) ?? "null"));
					}
					return false;
				}
				if (!states.TryGetValue(__instance, out var value2))
				{
					if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
					{
						MelonLogger.Warning("StartMixingStationBehaviourPatch.ActiveMinPass: State missing for " + ((chemist != null) ? ((NPC)chemist).fullName : null) + ", initializing");
					}
					states[__instance] = new StateData
					{
						CurrentState = EState.Idle
					};
					value2 = states[__instance];
				}
				MixingStationConfiguration val = ConfigurationExtensions.MixingConfig[targetStation];
				ObjectField val2 = ConfigurationExtensions.MixingSupply[targetStation];
				if (val == null || val2 == null)
				{
					Disable(__instance);
					if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
					{
						MelonLogger.Warning("StartMixingStationBehaviourPatch.ActiveMinPass: MixerConfig or MixerSupply not found for station: " + (((targetStation != null) ? ((NetworkBehaviour)targetStation).ObjectId.ToString() : null) ?? "null"));
					}
					return false;
				}
				ItemField mixerItemForProductSlot = NoLazyUtilities.GetMixerItemForProductSlot(targetStation);
				if (mixerItemForProductSlot == null)
				{
					return false;
				}
				float value3 = val.StartThrehold.Value;
				if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
				{
					MelonLogger.Msg($"StartMixingStationBehaviourPatch.ActiveMinPass: State={value2.CurrentState}, station={((NetworkBehaviour)targetStation).ObjectId}, chemist={((NPC)chemist).fullName}");
				}
				switch (value2.CurrentState)
				{
				case EState.Idle:
				{
					int quantity = targetStation.ProductSlot.Quantity;
					int quantity2 = targetStation.OutputSlot.Quantity;
					int mixQuantity = targetStation.GetMixQuantity();
					if (quantity2 > 0 || (float)quantity < value3)
					{
						Disable(__instance);
						if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
						{
							MelonLogger.Warning($"StartMixingStationBehaviourPatch.ActiveMinPass: Idle - Disabling for {((NPC)chemist).fullName}, outputQuantity={quantity2}, productQuantity={quantity}, threshold={value3}");
						}
						return false;
					}
					ConfigurationExtensions.NPCSupply[(NPC)(object)chemist] = val2;
					if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
					{
						BuildableItem selectedObject = val2.SelectedObject;
						MelonLogger.Msg("StartMixingStationBehaviourPatch.ActiveMinPass: Idle - Copied station supply " + ((selectedObject != null) ? ((Object)selectedObject).name : null) + " to chemist");
					}
					float threshold = value3 - (float)mixQuantity;
					ItemDefinition selectedItem = mixerItemForProductSlot.SelectedItem;
					bool flag = ChemistPatch.HasSufficientItems(chemist, threshold, (selectedItem != null) ? selectedItem.GetDefaultInstance(1) : null);
					if (!flag && (float)mixQuantity < value3)
					{
						Disable(__instance);
						if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
						{
							MelonLogger.Warning($"StartMixingStationBehaviourPatch.ActiveMinPass: Idle - Disabling for {((NPC)chemist).fullName}, hasSufficientItems={flag}, mixQuantity={mixQuantity}, threshold={value3}");
						}
						return false;
					}
					if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
					{
						MelonLogger.Msg(string.Format("StartMixingStationBehaviourPatch.ActiveMinPass: Idle - mixQuantity={0}, productQuantity={1}, outputQuantity={2}, threshold={3}, mixerItem={4}, cookPending={5}, mixOperation={6}", mixQuantity, quantity, quantity2, value3, mixerItemForProductSlot.SelectedItem?.Name ?? "null", value2.CookPending, targetStation.CurrentMixOperation != null));
					}
					if (!value2.CookPending && targetStation.CurrentMixOperation == null && (float)mixQuantity >= value3 && (float)targetStation.ProductSlot.Quantity >= value3 && targetStation.OutputSlot.Quantity == 0)
					{
						if (mixQuantity < quantity && (Object)(object)mixerItemForProductSlot.SelectedItem != (Object)null)
						{
							int num = quantity - mixQuantity;
							int amountInInventoryAndSupply = NoLazyUtilities.GetAmountInInventoryAndSupply((NPC)(object)chemist, mixerItemForProductSlot.SelectedItem);
							bool flag2 = amountInInventoryAndSupply >= 0;
							if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
							{
								MelonLogger.Msg($"StartMixingStationBehaviourPatch.ActiveMinPass: Cooking conditions met, checking mixer: mixQuantity={mixQuantity}, productQuantity={quantity}, additionalMixerNeeded={num}, supplyCount={amountInInventoryAndSupply}, canFetchMore={flag2}");
							}
							if (flag2)
							{
								PrepareToFetchItem(__instance, value2, mixerItemForProductSlot, quantity, mixQuantity, value3, val2, targetStation);
								return false;
							}
						}
						if (IsAtStation(__instance))
						{
							value2.CurrentState = EState.Cooking;
							value2.CookPending = true;
							__instance.StartCook();
							if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
							{
								MelonLogger.Msg("StartMixingStationBehaviourPatch.ActiveMinPass: Idle - Starting cook for " + ((NPC)chemist).fullName);
							}
						}
						else
						{
							value2.CurrentState = EState.WalkingToStation;
							((Behaviour)__instance).SetDestination(GetStationAccessPoint(__instance), true);
							if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
							{
								MelonLogger.Msg("StartMixingStationBehaviourPatch.ActiveMinPass: Idle - Walking to station for " + ((NPC)chemist).fullName);
							}
						}
					}
					else
					{
						if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
						{
							MelonLogger.Msg("StartMixingStationBehaviourPatch.ActiveMinPass: Idle - Preparing to fetch for " + ((NPC)chemist).fullName + ", reason=" + (value2.CookPending ? "cook pending" : ((targetStation.CurrentMixOperation != null) ? "mix operation active" : (((float)mixQuantity < value3) ? "low mixQuantity" : "other"))));
						}
						PrepareToFetchItem(__instance, value2, mixerItemForProductSlot, quantity, mixQuantity, value3, val2, targetStation);
					}
					break;
				}
				case EState.WalkingToStation:
					if (((NPC)chemist).Movement.IsMoving)
					{
						break;
					}
					if (IsAtStation(__instance))
					{
						int num2 = InsertItemsFromInventory(__instance, value2, targetStation);
						if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
						{
							MelonLogger.Msg($"StartMixingStationBehaviourPatch.ActiveMinPass: WalkingToStation - Inserted {num2} items to station for {((NPC)chemist).fullName}");
						}
						int mixQuantity2 = targetStation.GetMixQuantity();
						if (num2 > 0 && !value2.CookPending && targetStation.CurrentMixOperation == null && (float)mixQuantity2 >= value3)
						{
							value2.CurrentState = EState.Cooking;
							value2.CookPending = true;
							__instance.StartCook();
							if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
							{
								MelonLogger.Msg($"StartMixingStationBehaviourPatch.ActiveMinPass: WalkingToStation - Arrived at station, starting cook for {((NPC)chemist).fullName}, updatedMixQuantity={mixQuantity2}");
							}
						}
						else
						{
							value2.CurrentState = EState.Idle;
							if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
							{
								MelonLogger.Msg(string.Format("StartMixingStationBehaviourPatch.ActiveMinPass: WalkingToStation - Arrived at station, returning to Idle for {0}, reason={1}, updatedMixQuantity={2}", ((NPC)chemist).fullName, (num2 == 0) ? "no items inserted" : (value2.CookPending ? "cook pending" : ((targetStation.CurrentMixOperation != null) ? "mix operation active" : (((float)mixQuantity2 < value3) ? "low mixQuantity" : "other"))), mixQuantity2));
							}
						}
					}
					else
					{
						value2.CurrentState = EState.Idle;
						if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
						{
							MelonLogger.Warning("StartMixingStationBehaviourPatch.ActiveMinPass: WalkingToStation - Not at station after walking, returning to Idle for " + ((NPC)chemist).fullName);
						}
					}
					break;
				case EState.Cooking:
					if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
					{
						MelonLogger.Msg($"StartMixingStationBehaviourPatch.ActiveMinPass: Cooking - Waiting for mix operation for {((NPC)chemist).fullName}, station={((NetworkBehaviour)targetStation).ObjectId}");
					}
					break;
				}
				return false;
			}
			catch (Exception arg)
			{
				Chemist chemist2 = __instance.chemist;
				MelonLogger.Error(string.Format("StartMixingStationBehaviourPatch.ActiveMinPass: Failed for chemist: {0}, error: {1}", ((chemist2 != null) ? ((NPC)chemist2).fullName : null) ?? "null", arg));
				Disable(__instance);
				return false;
			}
		}

		private static void PrepareToFetchItem(StartMixingStationBehaviour __instance, StateData state, ItemField mixerItem, int productQuantity, int mixQuantity, float threshold, ObjectField mixerSupply, MixingStation station)
		{
			Chemist chemist = __instance.chemist;
			state.ClearMixerSlot = false;
			state.QuantityToFetch = Mathf.Max(productQuantity - mixQuantity, 0);
			state.TargetMixer = mixerItem.SelectedItem;
			state.Any = (Object)(object)state.TargetMixer == (Object)null;
			if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
			{
				MelonLogger.Msg(string.Format("StartMixingStationBehaviourPatch.PrepareToFetchItem: mixQuantity={0}, threshold={1}, targetMixerId={2}, quantityToFetch={3}, any={4}", mixQuantity, threshold, state.TargetMixer?.ID ?? "null", state.QuantityToFetch, state.Any));
			}
			if ((Object)(object)state.TargetMixer != (Object)null)
			{
				int num = ((NPC)chemist).Inventory._GetItemAmount(state.TargetMixer.ID);
				if (num >= state.QuantityToFetch)
				{
					HandleInventorySufficient(__instance, state, station, num);
					return;
				}
				if (num > 0)
				{
					state.QuantityToFetch -= num;
					if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
					{
						MelonLogger.Msg($"StartMixingStationBehaviourPatch.PrepareToFetchItem: Using {num} from inventory, still need {state.QuantityToFetch} for {((chemist != null) ? ((NPC)chemist).fullName : null)}");
					}
				}
			}
			BuildableItem obj = mixerSupply?.SelectedObject;
			ITransitEntity val = (ITransitEntity)(object)((obj is ITransitEntity) ? obj : null);
			if (val == null || val.OutputSlots == null)
			{
				Disable(__instance);
				if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
				{
					MelonLogger.Warning("StartMixingStationBehaviourPatch.PrepareToFetchItem: Invalid supply entity for " + ((chemist != null) ? ((NPC)chemist).fullName : null));
				}
				return;
			}
			int quantityToFetch = 0;
			if ((Object)(object)state.TargetMixer != (Object)null)
			{
				int amountInSupply = NoLazyUtilities.GetAmountInSupply((NPC)(object)chemist, state.TargetMixer.GetDefaultInstance(1));
				quantityToFetch = ((amountInSupply < state.QuantityToFetch) ? amountInSupply : state.QuantityToFetch);
			}
			if (state.Any && (Object)(object)state.TargetMixer == (Object)null)
			{
				ProductManager instance = NetworkSingleton<ProductManager>.Instance;
				if ((Object)(object)instance == (Object)null)
				{
					Disable(__instance);
					if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
					{
						MelonLogger.Warning("StartMixingStationBehaviourPatch.PrepareToFetchItem: ProductManager is null");
					}
					return;
				}
				HashSet<string> hashSet = instance.ValidMixIngredients.Select((PropertyItemDefinition i) => ((ItemDefinition)i).ID).ToHashSet();
				foreach (ItemSlot outputSlot in val.OutputSlots)
				{
					if (((outputSlot != null) ? outputSlot.ItemInstance : null) == null || !hashSet.Contains(outputSlot.ItemInstance.ID))
					{
						continue;
					}
					int num2 = ((NPC)chemist).Inventory._GetItemAmount(outputSlot.ItemInstance.ID);
					int num3 = 0;
					if (num2 < state.QuantityToFetch)
					{
						num3 = NoLazyUtilities.GetAmountInSupply((NPC)(object)chemist, outputSlot.ItemInstance);
					}
					if (!((float)(num3 + num2) >= threshold))
					{
						continue;
					}
					state.TargetMixer = outputSlot.ItemInstance.definition;
					quantityToFetch = Mathf.Min(productQuantity - num2, num3);
					if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
					{
						MelonLogger.Msg($"StartMixingStationBehaviourPatch.PrepareToFetchItem: Selected mixer {state.TargetMixer.ID}, quantityToFetch={state.QuantityToFetch}");
					}
					break;
				}
			}
			if ((Object)(object)state.TargetMixer == (Object)null)
			{
				Disable(__instance);
				if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
				{
					MelonLogger.Warning("StartMixingStationBehaviourPatch.PrepareToFetchItem: No suitable mixer available for " + ((chemist != null) ? ((NPC)chemist).fullName : null));
				}
				return;
			}
			state.QuantityToFetch = quantityToFetch;
			if (IsAtSupplies(__instance))
			{
				state.CurrentState = EState.GrabbingSupplies;
				if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
				{
					MelonLogger.Msg("StartMixingStationBehaviourPatch.PrepareToFetchItem: At supplies, grabbing " + state.TargetMixer.ID);
				}
				GrabItem(__instance, state);
			}
			else
			{
				state.CurrentState = EState.WalkingToSupplies;
				if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
				{
					MelonLogger.Msg("StartMixingStationBehaviourPatch.PrepareToFetchItem: Walking to supplies for " + state.TargetMixer.ID);
				}
				WalkToSupplies(__instance, state);
			}
		}

		private static void HandleInventorySufficient(StartMixingStationBehaviour __instance, StateData state, MixingStation station, int inventoryCount)
		{
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			Chemist chemist = __instance.chemist;
			if (IsAtStation(__instance))
			{
				int num = InsertItemsFromInventory(__instance, state, station);
				if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
				{
					MelonLogger.Msg($"StartMixingStationBehaviourPatch.PrepareToFetchItem: Inserted {num} items from inventory for {((chemist != null) ? ((NPC)chemist).fullName : null)}");
				}
				state.CurrentState = EState.Idle;
			}
			else
			{
				state.CurrentState = EState.WalkingToStation;
				((Behaviour)__instance).SetDestination(GetStationAccessPoint(__instance), true);
				if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
				{
					MelonLogger.Msg($"StartMixingStationBehaviourPatch.PrepareToFetchItem: Walking to station with {inventoryCount} inventory items for {((chemist != null) ? ((NPC)chemist).fullName : null)}");
				}
			}
		}

		[HarmonyPatch("StartCook")]
		[HarmonyPrefix]
		private static bool StartCookPrefix(StartMixingStationBehaviour __instance)
		{
			try
			{
				if (!states.TryGetValue(__instance, out var value))
				{
					states[__instance] = new StateData
					{
						CurrentState = EState.Idle
					};
					value = states[__instance];
					if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
					{
						Chemist chemist = __instance.chemist;
						MelonLogger.Warning("StartMixingStationBehaviourPatch.StartCook: State missing, initialized for " + (((chemist != null) ? ((NPC)chemist).fullName : null) ?? "null"));
					}
				}
				if (value.CurrentState != EState.Cooking || !value.CookPending || __instance.targetStation.CurrentMixOperation != null)
				{
					if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
					{
						object[] obj = new object[4]
						{
							value.CurrentState,
							value.CookPending,
							__instance.targetStation.CurrentMixOperation != null,
							null
						};
						Chemist chemist2 = __instance.chemist;
						obj[3] = ((chemist2 != null) ? ((NPC)chemist2).fullName : null) ?? "null";
						MelonLogger.Warning(string.Format("StartMixingStationBehaviourPatch.StartCook: Invalid state {0}, cookPending={1}, mixOperation={2} for {3}", obj));
					}
					return false;
				}
				if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
				{
					Chemist chemist3 = __instance.chemist;
					MelonLogger.Msg("StartMixingStationBehaviourPatch.StartCook: Starting cook for " + (((chemist3 != null) ? ((NPC)chemist3).fullName : null) ?? "null"));
				}
				value.CurrentState = EState.Cooking;
				return true;
			}
			catch (Exception arg)
			{
				Chemist chemist4 = __instance.chemist;
				MelonLogger.Error(string.Format("StartMixingStationBehaviourPatch.StartCook: Failed for chemist: {0}, error: {1}", ((chemist4 != null) ? ((NPC)chemist4).fullName : null) ?? "null", arg));
				return false;
			}
		}

		[HarmonyPatch("StartCook")]
		[HarmonyPostfix]
		private static void StartCookPostfix(StartMixingStationBehaviour __instance)
		{
			try
			{
				if (states.TryGetValue(__instance, out var value))
				{
					((MonoBehaviour)__instance).StartCoroutine(MonitorMixOperation(__instance, value));
				}
			}
			catch (Exception arg)
			{
				Chemist chemist = __instance.chemist;
				MelonLogger.Error(string.Format("StartMixingStationBehaviourPatch.StartCookPostfix: Failed for chemist: {0}, error: {1}", ((chemist != null) ? ((NPC)chemist).fullName : null) ?? "null", arg));
			}
		}

		private static IEnumerator MonitorMixOperation(StartMixingStationBehaviour __instance, StateData state)
		{
			Chemist chemist = __instance.chemist;
			MixingStation station = __instance.targetStation;
			if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
			{
				MelonLogger.Msg("StartMixingStationBehaviourPatch.MonitorMixOperation: Waiting for CurrentMixOperation for " + (((chemist != null) ? ((NPC)chemist).fullName : null) ?? "null") + ", station=" + (((station != null) ? ((NetworkBehaviour)station).ObjectId.ToString() : null) ?? "null"));
			}
			float timeout = 30f;
			float elapsed = 0f;
			while (station.CurrentMixOperation == null && elapsed < timeout)
			{
				yield return null;
				elapsed += Time.deltaTime;
			}
			if (station.CurrentMixOperation != null)
			{
				if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
				{
					MelonLogger.Msg(string.Format("StartMixingStationBehaviourPatch.MonitorMixOperation: CurrentMixOperation started, station {0} disabled, chemist reset to Idle for {1}", ((NetworkBehaviour)station).ObjectId, ((chemist != null) ? ((NPC)chemist).fullName : null) ?? "null"));
				}
			}
			else if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
			{
				MelonLogger.Warning("StartMixingStationBehaviourPatch.MonitorMixOperation: Timeout waiting for CurrentMixOperation for " + (((chemist != null) ? ((NPC)chemist).fullName : null) ?? "null") + ", station=" + (((station != null) ? ((NetworkBehaviour)station).ObjectId.ToString() : null) ?? "null"));
			}
			Disable(__instance);
		}

		private static bool IsAtSupplies(StartMixingStationBehaviour __instance)
		{
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: 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_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			Chemist chemist = __instance.chemist;
			ChemistConfiguration configuration = chemist.configuration;
			ObjectField val = ConfigurationExtensions.NPCSupply[(NPC)(object)chemist];
			bool flag = configuration != null && val != null && (Object)(object)val.SelectedObject != (Object)null && NavMeshUtility.IsAtTransitEntity((ITransitEntity)/*isinst with value type is only supported in some contexts*/, (NPC)(object)chemist, 0.4f);
			if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
			{
				Vector3 position = ((Component)chemist).transform.position;
				Vector3 val2 = (((Object)(object)val?.SelectedObject != (Object)null) ? ((Component)val.SelectedObject).transform.position : Vector3.zero);
				float num = Vector3.Distance(position, val2);
				MelonLogger.Msg(string.Format("StartMixingStationBehaviourPatch.IsAtSupplies: Result={0}, chemist={1}, ChemistPos={2}, SupplyPos={3}, Distance={4}", flag, ((chemist != null) ? ((NPC)chemist).fullName : null) ?? "null", position, val2, num));
			}
			return flag;
		}

		private static void WalkToSupplies(StartMixingStationBehaviour __instance, StateData state)
		{
			Chemist chemist = __instance.chemist;
			if (!ConfigurationExtensions.NPCSupply.TryGetValue((NPC)(object)chemist, out var value) || (Object)(object)value.SelectedObject == (Object)null)
			{
				Disable(__instance);
				if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
				{
					MelonLogger.Warning("StartMixingStationBehaviourPatch.WalkToSupplies: Supply not found for " + (((chemist != null) ? ((NPC)chemist).fullName : null) ?? "null"));
				}
				return;
			}
			BuildableItem selectedObject = value.SelectedObject;
			ITransitEntity val = (ITransitEntity)(object)((selectedObject is ITransitEntity) ? selectedObject : null);
			if (!((NPC)chemist).Movement.CanGetTo(val, 1f))
			{
				Disable(__instance);
				if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
				{
					MelonLogger.Warning("StartMixingStationBehaviourPatch.WalkToSupplies: Cannot reach supply for " + (((chemist != null) ? ((NPC)chemist).fullName : null) ?? "null"));
				}
			}
			else
			{
				if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
				{
					MelonLogger.Msg("StartMixingStationBehaviourPatch.WalkToSupplies: Walking to supply " + val.Name + " for " + ((chemist != null) ? ((NPC)chemist).fullName : null));
				}
				state.WalkToSuppliesRoutine = ((MonoBehaviour)__instance).StartCoroutine(WalkRoutine(__instance, val, state));
			}
		}

		private static void GrabItem(StartMixingStationBehaviour __instance, StateData state)
		{
			Chemist chemist = __instance.chemist;
			MixingStation targetStation = __instance.targetStation;
			try
			{
				if (targetStation.OutputSlot.Quantity > 0)
				{
					if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
					{
						MelonLogger.Warning($"StartMixingStationBehaviourPatch.GrabItem: Output quantity {targetStation.OutputSlot.Quantity} > 0, disabling for {((chemist != null) ? ((NPC)chemist).fullName : null)}");
					}
					Disable(__instance);
					return;
				}
				if (!ConfigurationExtensions.NPCSupply.TryGetValue((NPC)(object)chemist, out var value) || (Object)(object)value.SelectedObject == (Object)null)
				{
					Disable(__instance);
					if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
					{
						MelonLogger.Warning("StartMixingStationBehaviourPatch.GrabItem: Supply not found for " + (((chemist != null) ? ((NPC)chemist).fullName : null) ?? "null"));
					}
					return;
				}
				BuildableItem selectedObject = value.SelectedObject;
				ITransitEntity val = (ITransitEntity)(object)((selectedObject is ITransitEntity) ? selectedObject : null);
				if (state.ClearMixerSlot && targetStation.MixerSlot.ItemInstance != null)
				{
					int quantity = targetStation.MixerSlot.Quantity;
					((NPC)chemist).Inventory.InsertItem(targetStation.MixerSlot.ItemInstance.GetCopy(quantity), true);
					targetStation.MixerSlot.SetQuantity(0, false);
					if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
					{
						MelonLogger.Msg($"StartMixingStationBehaviourPatch.GrabItem: Cleared MixerSlot ({quantity} items returned to inventory) for {((chemist != null) ? ((NPC)chemist).fullName : null)}");
					}
				}
				IEnumerable<ItemSlot> outputSlots = val.OutputSlots;
				IEnumerable<ItemSlot> first = outputSlots ?? Enumerable.Empty<ItemSlot>();
				outputSlots = val.InputSlots;
				List<ItemSlot> list = (from s in first.Concat(outputSlots ?? Enumerable.Empty<ItemSlot>())
					where ((s != null) ? s.ItemInstance : null) != null && s.Quantity > 0 && s.ItemInstance.ID.ToLower() == state.TargetMixer.ID.ToLower()
					select s).Distinct().ToList();
				if (!list.Any())
				{
					Disable(__instance);
					if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
					{
						MelonLogger.Warning("StartMixingStationBehaviourPatch.GrabItem: No slots containing " + state.TargetMixer.ID + " in supply for " + ((chemist != null) ? ((NPC)chemist).fullName : null));
					}
					return;
				}
				int num = list.Sum((ItemSlot s) => s.Quantity);
				int num2 = Mathf.Min(state.QuantityToFetch, num);
				if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
				{
					MelonLogger.Warning($"StartMixingStationBehaviourPatch.GrabItem: Availability: {num}/{state.QuantityToFetch} for {state.TargetMixer.ID}");
				}
				if (num2 <= 0)
				{
					Disable(__instance);
					return;
				}
				int num3 = num2;
				foreach (ItemSlot item in list)
				{
					if (item == null)
					{
						continue;
					}
					int num4 = Mathf.Min(item.Quantity, num3);
					if (num4 > 0)
					{
						((NPC)chemist).Inventory.InsertItem(item.ItemInstance.GetCopy(num4), true);
						item.ChangeQuantity(-num4, false);
						num3 -= num4;
						if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
						{
							MelonLogger.Msg($"StartMixingStationBehaviourPatch.GrabItem: Took {num4} of {state.TargetMixer.ID} from slot {((object)item).GetHashCode()}, remainingToFetch={num3} for {((chemist != null) ? ((NPC)chemist).fullName : null)}");
						}
					}
					if (num3 > 0)
					{
						continue;
					}
					break;
				}
				if (num3 > 0 && (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs))
				{
					MelonLogger.Warning($"StartMixingStationBehaviourPatch.GrabItem: Could not fetch full quantity, still need {num3} of {state.TargetMixer.ID} for {((chemist != null) ? ((NPC)chemist).fullName : null)}");
				}
				if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
				{
					MelonLogger.Msg($"StartMixingStationBehaviourPatch.GrabItem: Grabbed {num2 - num3} of {state.TargetMixer.ID} into inventory for {((chemist != null) ? ((NPC)chemist).fullName : null)}");
				}
				state.GrabRoutine = ((MonoBehaviour)__instance).StartCoroutine(GrabRoutine(__instance, state));
			}
			catch (Exception arg)
			{
				MelonLogger.Error($"StartMixingStationBehaviourPatch.GrabItem: Failed for {((chemist != null) ? ((NPC)chemist).fullName : null)}, error: {arg}");
				Disable(__instance);
			}
		}

		private static IEnumerator WalkRoutine(StartMixingStationBehaviour __instance, ITransitEntity supply, StateData state)
		{
			Chemist chemist = __instance.chemist;
			Vector3 startPos = ((Component)chemist).transform.position;
			((Behaviour)__instance).SetDestination(supply, true);
			if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
			{
				MelonLogger.Msg($"StartMixingStationBehaviourPatch.WalkRoutine: Set destination for {((chemist != null) ? ((NPC)chemist).fullName : null)}, IsMoving={((NPC)chemist).Movement.IsMoving}");
			}
			yield return (object)new WaitForSeconds(0.2f);
			float timeout = 10f;
			float elapsed = 0f;
			while (((NPC)chemist).Movement.IsMoving && elapsed < timeout)
			{
				yield return null;
				elapsed += Time.deltaTime;
			}
			if (elapsed >= timeout)
			{
				Disable(__instance);
				if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
				{
					MelonLogger.Warning("StartMixingStationBehaviourPatch.WalkRoutine: Timeout walking to supply for " + ((chemist != null) ? ((NPC)chemist).fullName : null));
				}
			}
			state.WalkToSuppliesRoutine = null;
			state.CurrentState = EState.Idle;
			if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
			{
				bool atSupplies = IsAtSupplies(__instance);
				Vector3 chemistPos = ((Component)chemist).transform.position;
				Vector3 supplyPos = ((supply != null) ? ((Component)(MonoBehaviour)supply).transform.position : Vector3.zero);
				float distanceMoved = Vector3.Distance(startPos, chemistPos);
				object[] array = new object[8];
				array[0] = ((chemist != null) ? ((NPC)chemist).fullName : null);
				array[1] = atSupplies;
				array[2] = chemistPos;
				array[3] = supplyPos;
				array[4] = distanceMoved;
				array[5] = elapsed;
				array[6] = elapsed >= timeout;
				array[7] = ((NPC)chemist).Movement.IsMoving;
				MelonLogger.Msg(string.Format("StartMixingStationBehaviourPatch.WalkRoutine: Completed walk to supply, reverting to Idle for {0}. AtSupplies={1}, ChemistPos={2}, SupplyPos={3}, DistanceMoved={4}, Elapsed={5}, Timeout={6}, IsMoving={7}", array));
			}
		}

		private static IEnumerator GrabRoutine(StartMixingStationBehaviour __instance, StateData state)
		{
			Chemist chemist = __instance.chemist;
			yield return (object)new WaitForSeconds(0.5f);
			try
			{
				if ((Object)(object)((NPC)chemist).Avatar?.Anim != (Object)null)
				{
					((NPC)chemist).Avatar.Anim.ResetTrigger("GrabItem");
					((NPC)chemist).Avatar.Anim.SetTrigger("GrabItem");
					if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
					{
						MelonLogger.Msg("StartMixingStationBehaviourPatch.GrabRoutine: Triggered GrabItem animation for " + ((chemist != null) ? ((NPC)chemist).fullName : null));
					}
				}
				else if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
				{
					MelonLogger.Warning("StartMixingStationBehaviourPatch.GrabRoutine: Animator missing for " + ((chemist != null) ? ((NPC)chemist).fullName : null) + ", skipping animation");
				}
			}
			catch (Exception e)
			{
				MelonLogger.Error($"StartMixingStationBehaviourPatch.GrabRoutine: Failed for {((chemist != null) ? ((NPC)chemist).fullName : null)}, error: {e}");
				state.GrabRoutine = null;
				state.CurrentState = EState.Idle;
				if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
				{
					MelonLogger.Warning("StartMixingStationBehaviourPatch.GrabRoutine: Reverted to Idle due to error for " + ((chemist != null) ? ((NPC)chemist).fullName : null));
				}
			}
			yield return (object)new WaitForSeconds(0.5f);
			state.GrabRoutine = null;
			state.CurrentState = EState.WalkingToStation;
			((Behaviour)__instance).SetDestination(GetStationAccessPoint(__instance), true);
			if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
			{
				MelonLogger.Msg("StartMixingStationBehaviourPatch.GrabRoutine: Grab complete, walking to station for " + ((chemist != null) ? ((NPC)chemist).fullName : null));
			}
		}

		private static int InsertItemsFromInventory(StartMixingStationBehaviour __instance, StateData state, MixingStation station)
		{
			Chemist chemist = __instance.chemist;
			int num = 0;
			try
			{
				if ((Object)(object)state.TargetMixer == (Object)null)
				{
					if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
					{
						MelonLogger.Warning("StartMixingStationBehaviourPatch.InsertItemsFromInventory: TargetMixer is null for " + ((chemist != null) ? ((NPC)chemist).fullName : null));
					}
					return 0;
				}
				if (station.MixerSlot == null)
				{
					if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
					{
						MelonLogger.Warning($"StartMixingStationBehaviourPatch.InsertItemsFromInventory: MixerSlot is null for station {((station != null) ? new int?(((NetworkBehaviour)station).ObjectId) : null)}");
					}
					return 0;
				}
				num = ((NPC)chemist).Inventory._GetItemAmount(state.TargetMixer.ID);
				if (num <= 0)
				{
					if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
					{
						MelonLogger.Warning("StartMixingStationBehaviourPatch.InsertItemsFromInventory: No items of " + state.TargetMixer.ID + " in inventory for " + ((chemist != null) ? ((NPC)chemist).fullName : null));
					}
					return 0;
				}
				ItemInstance defaultInstance = state.TargetMixer.GetDefaultInstance(1);
				if (defaultInstance == null)
				{
					if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
					{
						MelonLogger.Warning("StartMixingStationBehaviourPatch.InsertItemsFromInventory: Failed to get default instance for " + state.TargetMixer.ID);
					}
					return 0;
				}
				if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
				{
					MelonLogger.Msg($"StartMixingStationBehaviourPatch.InsertItemsFromInventory: Attempting to insert {num} of {state.TargetMixer.ID} for {((chemist != null) ? ((NPC)chemist).fullName : null)}");
				}
				int quantity = station.MixerSlot.Quantity;
				station.MixerSlot.InsertItem(defaultInstance.GetCopy(num));
				int quantity2 = station.MixerSlot.Quantity;
				int num2 = num;
				List<(ItemSlot, int)> list = new List<(ItemSlot, int)>();
				foreach (ItemSlot itemSlot in ((NPC)chemist).Inventory.ItemSlots)
				{
					if (((itemSlot != null) ? itemSlot.ItemInstance : null) != null && itemSlot.ItemInstance.ID == state.TargetMixer.ID && itemSlot.Quantity > 0)
					{
						int num3 = Mathf.Min(itemSlot.Quantity, num2);
						list.Add((itemSlot, num3));
						num2 -= num3;
						if (num2 <= 0)
						{
							break;
						}
					}
				}
				foreach (var (val, num4) in list)
				{
					val.SetQuantity(val.Quantity - num4, false);
				}
				if (num2 > 0)
				{
					if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
					{
						MelonLogger.Warning($"StartMixingStationBehaviourPatch.InsertItemsFromInventory: Failed to remove {num2} of {state.TargetMixer.ID}, inventory may be inconsistent for {((chemist != null) ? ((NPC)chemist).fullName : null)}");
					}
					station.MixerSlot.SetQuantity(quantity, false);
					return 0;
				}
				if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
				{
					MelonLogger.Msg($"StartMixingStationBehaviourPatch.InsertItemsFromInventory: Successfully inserted {num} of {state.TargetMixer.ID}, MixerSlot quantity changed from {quantity} to {quantity2} for {((chemist != null) ? ((NPC)chemist).fullName : null)}");
				}
				return num;
			}
			catch (Exception ex)
			{
				MelonLogger.Error(string.Format("StartMixingStationBehaviourPatch.InsertItemsFromInventory: Failed for {0}, item={1}, quantity={2}, error: {3}", (chemist != null) ? ((NPC)chemist).fullName : null, state.TargetMixer?.ID ?? "null", num, ex));
				return 0;
			}
		}

		private static void Disable(StartMixingStationBehaviour __instance)
		{
			if (states.TryGetValue(__instance, out var value))
			{
				if (value.WalkToSuppliesRoutine != null)
				{
					((MonoBehaviour)__instance).StopCoroutine(value.WalkToSuppliesRoutine);
					value.WalkToSuppliesRoutine = null;
				}
				if (value.GrabRoutine != null)
				{
					((MonoBehaviour)__instance).StopCoroutine(value.GrabRoutine);
					value.GrabRoutine = null;
				}
				value.TargetMixer = null;
				value.ClearMixerSlot = false;
				value.QuantityToFetch = 0;
				value.CookPending = false;
				value.CurrentState = EState.Idle;
				value.LastSupply = null;
				value.Any = false;
			}
			states.Remove(__instance);
			((Behaviour)__instance).Disable();
			if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
			{
				Chemist chemist = __instance.chemist;
				MelonLogger.Msg("StartMixingStationBehaviourPatch.Disable: Disabled behaviour for " + (((chemist != null) ? ((NPC)chemist).fullName : null) ?? "null"));
			}
		}

		private static bool IsAtStation(StartMixingStationBehaviour __instance)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			bool flag = (Object)(object)__instance.targetStation != (Object)null && Vector3.Distance(((Component)__instance.chemist).transform.position, GetStationAccessPoint(__instance)) < 1f;
			if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugBehaviorLogs)
			{
				object arg = flag;
				Chemist chemist = __instance.chemist;
				MelonLogger.Msg(string.Format("StartMixingStationBehaviourPatch.IsAtStation: Result={0}, chemist={1}", arg, ((chemist != null) ? ((NPC)chemist).fullName : null) ?? "null"));
			}
			return flag;
		}

		private static Vector3 GetStationAccessPoint(StartMixingStationBehaviour __instance)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			return Object.op_Implicit((Object)(object)__instance.targetStation) ? ((ITransitEntity)__instance.targetStation).AccessPoints[0].position : ((Component)__instance.chemist).transform.position;
		}
	}
	[HarmonyPatch(typeof(Chemist), "GetMixStationsReadyToMove")]
	public class ChemistGetMixStationsReadyToMovePatch
	{
		[HarmonyPrefix]
		private static bool Prefix(Chemist __instance, ref List<MixingStation> __result)
		{
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Expected O, but got Unknown
			List<MixingStation> list = new List<MixingStation>();
			ProductDefinition outputProduct = default(ProductDefinition);
			foreach (MixingStation mixStation in __instance.configuration.MixStations)
			{
				ItemSlot outputSlot = mixStation.OutputSlot;
				if (outputSlot.Quantity <= 0)
				{
					continue;
				}
				ref ProductDefinition reference = ref outputProduct;
				ItemDefinition definition = outputSlot.ItemInstance.Definition;
				reference = (ProductDefinition)(object)((definition is ProductDefinition) ? definition : null);
				MixingRoute mixingRoute = ConfigurationExtensions.MixingRoutes[mixStation].FirstOrDefault((MixingRoute r) => (Object)(object)r.Product.SelectedItem == (Object)(object)outputProduct);
				if (mixingRoute != null)
				{
					TransitRoute val = new TransitRoute((ITransitEntity)(object)mixStation, (ITransitEntity)(object)mixStation);
					if (((Employee)__instance).MoveItemBehaviour.IsTransitRouteValid(val, mixStation.OutputSlot.ItemInstance.ID))
					{
						((Employee)__instance).MoveItemBehaviour.Initialize(val, mixStation.OutputSlot.ItemInstance, -1, false);
						((Behaviour)((Employee)__instance).MoveItemBehaviour).Enable_Networked((NetworkConnection)null);
						return false;
					}
				}
				? val2 = ((Employee)__instance).MoveItemBehaviour;
				EntityConfiguration configuration = mixStation.Configuration;
				if (((MoveItemBehaviour)val2).IsTransitRouteValid(((MixingStationConfiguration)((configuration is MixingStationConfiguration) ? configuration : null)).DestinationRoute, outputSlot.ItemInstance.ID))
				{
					list.Add(mixStation);
				}
			}
			__result = list;
			return false;
		}
	}
	public static class SelectionHelper
	{
		public static Action<ProductDefinition> ProductSelectionCallback { get; set; }
	}
	[Serializable]
	public class ExtendedMixingStationConfigurationData : MixingStationConfigurationData
	{
		public ObjectFieldData Supply;

		public string MixingRoutes;

		public ExtendedMixingStationConfigurationData(ObjectFieldData destination, NumberFieldData threshold)
			: base(destination, threshold)
		{
			Supply = null;
			MixingRoutes = "[]";
		}
	}
	public class MixingRoute
	{
		public ItemField Product { get; set; }

		public ItemField MixerItem { get; set; }

		public MixingRoute(MixingStationConfiguration config)
		{
			//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_001b: Expected O, but got Unknown
			//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_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Expected O, but got Unknown
			Product = new ItemField((EntityConfiguration)(object)config)
			{
				CanSelectNone = false
			};
			ItemField val = new ItemField((EntityConfiguration)(object)config)
			{
				CanSelectNone = false
			};
			List<ItemDefinition> list = new List<ItemDefinition>();
			list.AddRange(NetworkSingleton<ProductManager>.Instance.ValidMixIngredients.Cast<ItemDefinition>());
			val.Options = list;
			MixerItem = val;
		}

		public void SetData(MixingRouteData data)
		{
			Product.Load(data.Product);
			MixerItem.Load(data.MixerItem);
		}
	}
	[Serializable]
	public class MixingRouteData
	{
		public ItemFieldData Product;

		public ItemFieldData MixerItem;

		public MixingRouteData(ItemFieldData product, ItemFieldData mixerItem)
		{
			Product = product;
			MixerItem = mixerItem;
		}
	}
	[HarmonyPatch(typeof(MixingStationConfiguration))]
	public class MixingStationConfigurationPatch
	{
		[HarmonyPostfix]
		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		private static void Postfix(MixingStationConfiguration __instance, MixingStation station)
		{
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Expected O, but got Unknown
			try
			{
				__instance.StartThrehold.Configure(1f, 20f, true);
				if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugMixingLogs)
				{
					MixingStation obj = station;
					MelonLogger.Msg(string.Format("MixingStationConfigurationPatch: Initializing for station: {0}, configHash={1}", ((obj != null) ? ((NetworkBehaviour)obj).ObjectId.ToString() : null) ?? "null", ((object)__instance).GetHashCode()));
				}
				ObjectField val = new ObjectField((EntityConfiguration)(object)__instance);
				val.TypeRequirements = new List<Type>(1) { typeof(PlaceableStorageEntity) };
				val.DrawTransitLine = true;
				ObjectField Supply = val;
				((UnityEventBase)Supply.onObjectChanged).RemoveAllListeners();
				Supply.onObjectChanged.AddListener((UnityAction<BuildableItem>)delegate
				{
					ConfigurationExtensions.InvokeChanged((EntityConfiguration)(object)__instance);
					if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugMixingLogs)
					{
						MixingStation obj4 = station;
						string obj5 = ((obj4 != null) ? ((NetworkBehaviour)obj4).ObjectId.ToString() : null) ?? "null";
						BuildableItem selectedObject = Supply.SelectedObject;
						MelonLogger.Msg("MixingStationConfigurationPatch: Supply changed for station " + obj5 + ", newSupply=" + (((selectedObject != null) ? ((NetworkBehaviour)selectedObject).ObjectId.ToString() : null) ?? "null"));
					}
				});
				Supply.onObjectChanged.AddListener((UnityAction<BuildableItem>)delegate(BuildableItem item)
				{
					__instance.SourceChanged(item);
				});
				ConfigurationExtensions.MixingSupply[station] = Supply;
				ConfigurationExtensions.MixingConfig[station] = __instance;
				if (!ConfigurationExtensions.MixingRoutes.ContainsKey(station))
				{
					ConfigurationExtensions.MixingRoutes[station] = new List<MixingRoute>();
				}
				if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugMixingLogs)
				{
					MixingStation obj2 = station;
					MelonLogger.Msg(string.Format("MixingStationConfigurationPatch: Registered supply and config for station: {0}, supplyHash={1}", ((obj2 != null) ? ((NetworkBehaviour)obj2).ObjectId.ToString() : null) ?? "null", ((object)Supply).GetHashCode()));
				}
			}
			catch (Exception arg)
			{
				MixingStation obj3 = station;
				MelonLogger.Error(string.Format("MixingStationConfigurationPatch: Failed for station: {0}, error: {1}", ((obj3 != null) ? ((NetworkBehaviour)obj3).ObjectId.ToString() : null) ?? "null", arg));
			}
		}
	}
	[HarmonyPatch(typeof(MixingStationConfiguration), "GetSaveString")]
	public class MixingStationConfigurationGetSaveStringPatch
	{
		private static void Postfix(MixingStationConfiguration __instance, ref string __result)
		{
			try
			{
				string text = "";
				if (ConfigurationExtensions.MixingRoutes.TryGetValue(__instance.station, out var value) && value.Any())
				{
					List<string> list = new List<string>();
					foreach (MixingRoute item2 in value)
					{
						string text2 = item2.Product.GetData()?.ItemID ?? "null";
						string text3 = item2.MixerItem.GetData()?.ItemID ?? "null";
						string item = "{\"Product\":\"" + text2 + "\",\"MixerItem\":\"" + text3 + "\"}";
						list.Add(item);
					}
					text = string.Join(",", list);
				}
				ExtendedMixingStationConfigurationData extendedMixingStationConfigurationData = new ExtendedMixingStationConfigurationData(__instance.Destination.GetData(), __instance.StartThrehold.GetData())
				{
					Supply = ConfigurationExtensions.MixingSupply[__instance.station].GetData(),
					MixingRoutes = text
				};
				__result = JsonUtility.ToJson((object)extendedMixingStationConfigurationData, true);
				if (!DebugConfig.EnableDebugLogs && !DebugConfig.EnableDebugMixingLogs)
				{
					return;
				}
				MelonLogger.Msg($"MixingStationConfigurationGetSaveStringPatch: Saved JSON for station={((NetworkBehaviour)__instance.station).ObjectId}: {__result}");
				MelonLogger.Msg("MixingStationConfigurationGetSaveStringPatch: Routes JSON=" + text);
				if (value == null)
				{
					return;
				}
				MelonLogger.Msg($"MixingStationConfigurationGetSaveStringPatch: Routes count={value.Count}");
				foreach (MixingRoute item3 in value)
				{
					MelonLogger.Msg("MixingStationConfigurationGetSaveStringPatch: Route Product.ItemID=" + (item3.Product.GetData()?.ItemID ?? "null") + ", MixerItem.ItemID=" + (item3.MixerItem.GetData()?.ItemID ?? "null"));
				}
			}
			catch (Exception arg)
			{
				MelonLogger.Error($"MixingStationConfigurationGetSaveStringPatch: Failed for configHash={((object)__instance).GetHashCode()}, error: {arg}");
			}
		}
	}
	[HarmonyPatch(typeof(MixingStationConfiguration), "ShouldSave")]
	public class MixingStationConfigurationShouldSavePatch
	{
		private static void Postfix(MixingStationConfiguration __instance, ref bool __result)
		{
			try
			{
				ObjectField val = ConfigurationExtensions.MixingSupply[__instance.station];
				List<MixingRoute> value;
				bool flag = ConfigurationExtensions.MixingRoutes.TryGetValue(__instance.station, out value) && value.Any((MixingRoute r) => (Object)(object)r.Product.SelectedItem != (Object)null || (Object)(object)r.MixerItem.SelectedItem != (Object)null);
				__result |= (Object)(object)val.SelectedObject != (Object)null || flag;
			}
			catch (Exception arg)
			{
				MelonLogger.Error($"MixingStationConfigurationShouldSavePatch failed: {arg}");
			}
		}
	}
	public class MixingRouteListFieldUI : MonoBehaviour
	{
		public string FieldText = "Recipes";

		public TextMeshProUGUI FieldLabel;

		public MixingRouteEntryUI[] RouteEntries;

		public RectTransform MultiEditBlocker;

		public Button AddButton;

		public static readonly int MaxRoutes = 7;

		private List<MixingRoute> Routes;

		private MixingStationConfiguration Config;

		private UnityAction OnChanged;

		private void Start()
		{
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Expected O, but got Unknown
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Expected O, but got Unknown
			Transform obj = ((Component)this).transform.Find("Title");
			FieldLabel = ((obj != null) ? ((Component)obj).GetComponent<TextMeshProUGUI>() : null);
			if ((Object)(object)FieldLabel != (Object)null)
			{
				((TMP_Text)FieldLabel).text = FieldText;
			}
			Transform obj2 = ((Component)this).transform.Find("Blocker");
			MultiEditBlocker = ((obj2 != null) ? ((Component)obj2).GetComponent<RectTransform>() : null);
			RectTransform multiEditBlocker = MultiEditBlocker;
			if (multiEditBlocker != null)
			{
				((Component)multiEditBlocker).gameObject.SetActive(false);
			}
			Transform obj3 = ((Component)this).transform.Find("Contents/AddNew");
			AddButton = ((obj3 != null) ? ((Component)obj3).GetComponent<Button>() : null);
			if ((Object)(object)AddButton != (Object)null)
			{
				((UnityEvent)AddButton.onClick).AddListener(new UnityAction(AddClicked));
			}
			RouteEntries = ((Component)((Component)this).transform.Find("Contents")).GetComponentsInChildren<MixingRouteEntryUI>(true);
			for (int i = 0; i < RouteEntries.Length; i++)
			{
				int index = i;
				RouteEntries[i].onDeleteClicked.AddListener((UnityAction)delegate
				{
					EntryDeleteClicked(index);
				});
			}
			Refresh();
		}

		public void Bind(MixingStationConfiguration config, List<MixingRoute> routes, UnityAction onChangedCallback)
		{
			Config = config;
			Routes = routes ?? new List<MixingRoute>();
			OnChanged = onChangedCallback;
			Refresh();
		}

		private void Refresh()
		{
			for (int i = 0; i < RouteEntries.Length; i++)
			{
				if (i < Routes.Count)
				{
					((Component)RouteEntries[i]).gameObject.SetActive(true);
					RouteEntries[i].Bind(Config, Routes[i]);
				}
				else
				{
					((Component)RouteEntries[i]).gameObject.SetActive(false);
				}
			}
			if ((Object)(object)AddButton != (Object)null)
			{
				((Component)AddButton).gameObject.SetActive(Routes.Count < MaxRoutes);
				if (DebugConfig.EnableDebugLogs)
				{
					MelonLogger.Msg($"MixingRouteListFieldUI: Refresh(): AddButton active={((Component)AddButton).gameObject.activeSelf}");
				}
			}
		}

		private void AddClicked()
		{
			if (Routes.Count < MaxRoutes)
			{
				Routes.Add(new MixingRoute(Config));
			}
			Refresh();
			UnityAction onChanged = OnChanged;
			if (onChanged != null)
			{
				onChanged.Invoke();
			}
		}

		private void EntryDeleteClicked(int index)
		{
			if (index >= 0 && index < Routes.Count)
			{
				Routes.RemoveAt(index);
			}
			Refresh();
			UnityAction onChanged = OnChanged;
			if (onChanged != null)
			{
				onChanged.Invoke();
			}
		}
	}
	public class MixingRouteEntryUI : MonoBehaviour
	{
		public TextMeshProUGUI ProductLabel;

		public TextMeshProUGUI MixerLabel;

		public Button ProductButton;

		public Button MixerButton;

		public UnityEvent onDeleteClicked = new UnityEvent();

		public MixingRoute Route;

		public MixingStationConfiguration Config;

		private void Awake()
		{
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Expected O, but got Unknown
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Expected O, but got Unknown
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Expected O, but got Unknown
			Transform obj = ((Component)this).transform.Find("ProductIMGUI");
			ProductButton = ((obj != null) ? ((Component)obj).GetComponent<Button>() : null);
			Transform obj2 = ((Component)this).transform.Find("MixerItemIMGUI");
			MixerButton = ((obj2 != null) ? ((Component)obj2).GetComponent<Button>() : null);
			Transform obj3 = ((Component)this).transform.Find("ProductIMGUI/Label");
			ProductLabel = ((obj3 != null) ? ((Component)obj3).GetComponent<TextMeshProUGUI>() : null);
			Transform obj4 = ((Component)this).transform.Find("MixerItemIMGUI/Label");
			MixerLabel = ((obj4 != null) ? ((Component)obj4).GetComponent<TextMeshProUGUI>() : null);
			Button productButton = ProductButton;
			if (productButton != null)
			{
				((UnityEvent)productButton.onClick).AddListener(new UnityAction(ProductClicked));
			}
			Button mixerButton = MixerButton;
			if (mixerButton != null)
			{
				((UnityEvent)mixerButton.onClick).AddListener(new UnityAction(MixerClicked));
			}
			Transform obj5 = ((Component)this).transform.Find("Remove");
			if (obj5 != null)
			{
				Button component = ((Component)obj5).GetComponent<Button>();
				if (component != null)
				{
					((UnityEvent)component.onClick).AddListener(new UnityAction(DeleteClicked));
				}
			}
		}

		public void Bind(MixingStationConfiguration config, MixingRoute route)
		{
			Config = config;
			Route = route;
			TextMeshProUGUI productLabel = ProductLabel;
			ItemField product = Route.Product;
			((TMP_Text)productLabel).text = ((product == null) ? null : product.SelectedItem?.Name) ?? "Product";
			TextMeshProUGUI mixerLabel = MixerLabel;
			ItemField mixerItem = Route.MixerItem;
			((TMP_Text)mixerLabel).text = ((mixerItem == null) ? null : mixerItem.SelectedItem?.Name) ?? "Mixer";
			((UnityEventBase)Route.Product.onItemChanged).RemoveAllListeners();
			Route.Product.onItemChanged.AddListener((UnityAction<ItemDefinition>)delegate(ItemDefinition item)
			{
				((TMP_Text)ProductLabel).text = item?.Name ?? "Product";
				ConfigurationExtensions.InvokeChanged((EntityConfiguration)(object)Config);
			});
			((UnityEventBase)Route.MixerItem.onItemChanged).RemoveAllListeners();
			Route.MixerItem.onItemChanged.AddListener((UnityAction<ItemDefinition>)delegate(ItemDefinition item)
			{
				((TMP_Text)MixerLabel).text = item?.Name ?? "Mixer";
				ConfigurationExtensions.InvokeChanged((EntityConfiguration)(object)Config);
			});
		}

		public void ProductClicked()
		{
			ItemField product = Route.Product;
			List<ItemDefinition> list = new List<ItemDefinition>();
			list.AddRange(ProductManager.FavouritedProducts.Cast<ItemDefinition>());
			product.Options = list;
			OpenItemSelectorScreen(Route.Product, "Favorites", ProductLabel);
		}

		public void MixerClicked()
		{
			OpenItemSelectorScreen(Route.MixerItem, "Mixers", MixerLabel);
		}

		public void DeleteClicked()
		{
			onDeleteClicked.Invoke();
		}

		private void OpenItemSelectorScreen(ItemField itemField, string fieldName, TextMeshProUGUI label)
		{
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Expected O, but got Unknown
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Expected O, but got Unknown
			if (DebugConfig.EnableDebugLogs)
			{
				MelonLogger.Msg("MixingRouteEntryUI: OpenItemSelectorScreen");
			}
			List<Option> list = new List<Option>();
			Option val = null;
			if (itemField.CanSelectNone)
			{
				list.Add(new Option("None", (ItemDefinition)null));
				if ((Object)(object)itemField.SelectedItem == (Object)null)
				{
					val = list[0];
				}
			}
			else
			{
				Option item = new Option("None", (ItemDefinition)null);
				if (list.IndexOf(item) != -1)
				{
					list.Remove(item);
				}
			}
			foreach (ItemDefinition option in itemField.Options)
			{
				Option val2 = new Option(option.Name, option);
				list.Add(val2);
				if ((Object)(object)itemField.SelectedItem == (Object)(object)option)
				{
					val = val2;
				}
			}
			Singleton<ManagementInterface>.Instance.ItemSelectorScreen.Initialize(fieldName, list, val, (Action<Option>)delegate(Option selected)
			{
				if (DebugConfig.EnableDebugLogs)
				{
					MelonLogger.Msg("MixingRouteEntryUI: ItemSelectorScreen selected " + (selected?.Item?.Name ?? "null") + " for " + fieldName);
				}
				itemField.SelectedItem = selected.Item;
				((TMP_Text)label).text = ((Object)selected.Item).name;
			});
			((ClipboardScreen)Singleton<ManagementInterface>.Instance.ItemSelectorScreen).Open();
		}
	}
	[HarmonyPatch(typeof(MixingStationConfigPanel), "Bind")]
	public class MixingStationConfigPanelBindPatch
	{
		private static GameObject MixingRouteListTemplate { get; set; }

		private static void InitializeStaticTemplate(RouteListFieldUI routeListTemplate)
		{
			if ((Object)(object)MixingRouteListTemplate != (Object)null)
			{
				if (DebugConfig.EnableDebugLogs)
				{
					MelonLogger.Msg("MixingStationConfigPanelBindPatch: MixingRouteListTemplate already initialized, skipping");
				}
				return;
			}
			if ((Object)(object)routeListTemplate == (Object)null)
			{
				MelonLogger.Error("MixingStationConfigPanelBindPatch: routeListTemplate is null");
				return;
			}
			try
			{
				if (DebugConfig.EnableDebugLogs)
				{
					MelonLogger.Msg("MixingStationConfigPanelBindPatch: Initializing MixingRouteListTemplate");
				}
				GameObject val = Object.Instantiate<GameObject>(((Component)routeListTemplate).gameObject);
				val.AddComponent<CanvasRenderer>();
				((Object)val).name = "MixingRouteListTemplate";
				val.SetActive(false);
				RouteListFieldUI component = val.GetComponent<RouteListFieldUI>();
				if ((Object)(object)component != (Object)null)
				{
					Object.Destroy((Object)(object)component);
				}
				if ((Object)(object)val.GetComponent<MixingRouteListFieldUI>() == (Object)null)
				{
					val.AddComponent<MixingRouteListFieldUI>();
				}
				Transform obj = val.transform.Find("Contents/AddNew/Label");
				TextMeshProUGUI val2 = ((obj != null) ? ((Component)obj).GetComponent<TextMeshProUGUI>() : null);
				if ((Object)(object)val2 != (Object)null)
				{
					((TMP_Text)val2).text = "  Add Recipe";
				}
				Transform transformTemplateFromConfigPanel = NoLazyUtilities.GetTransformTemplateFromConfigPanel((EConfigurableType)4, "RouteListFieldUI/Contents/Entry");
				if ((Object)(object)transformTemplateFromConfigPanel == (Object)null)
				{
					MelonLogger.Error("MixingStationConfigPanelBindPatch: Failed to retrieve Entry template from Packager config panel");
					return;
				}
				Transform val3 = val.transform.Find("Contents");
				for (int i = 0; i < MixingRouteListFieldUI.MaxRoutes; i++)
				{
					Transform val4 = val3.Find($"Entry ({i})") ?? ((i == 0) ? val3.Find("Entry") : null);
					if (DebugConfig.EnableDebugLogs)
					{
						MelonLogger.Msg($"MixingStationConfigPanelBindPatch: Processing Entry ({i})");
					}
					if ((Object)(object)val4 == (Object)null)
					{
						GameObject val5 = Object.Instantiate<GameObject>(((Component)transformTemplateFromConfigPanel).gameObject, val3, false);
						((Object)val5).name = $"Entry ({i})";
						val5.AddComponent<CanvasRenderer>();
						val4 = val5.transform;
						Transform val6 = val4.Find("Source");
						if ((Object)(object)val6 != (Object)null)
						{
							((Object)val6).name = "ProductIMGUI";
						}
						else
						{
							MelonLogger.Warning($"MixingStationConfigPanelBindPatch: Source not found in Entry ({i})");
						}
						Transform val7 = val4.Find("Destination");
						if ((Object)(object)val7 != (Object)null)
						{
							((Object)val7).name = "MixerItemIMGUI";
						}
						else
						{
							MelonLogger.Warning($"MixingStationConfigPanelBindPatch: Destination not found in Entry ({i})");
						}
						val5.transform.SetSiblingIndex(i);
					}
					else
					{
						Transform val8 = val4.Find("Source");
						if ((Object)(object)val8 != (Object)null)
						{
							((Object)val8).name = "ProductIMGUI";
						}
						Transform val9 = val4.Find("Destination");
						if ((Object)(object)val9 != (Object)null)
						{
							((Object)val9).name = "MixerItemIMGUI";
						}
					}
					RouteEntryUI component2 = ((Component)val4).GetComponent<RouteEntryUI>();
					if ((Object)(object)component2 != (Object)null)
					{
						Object.Destroy((Object)(object)component2);
					}
					if ((Object)(object)((Component)val4).GetComponent<MixingRouteEntryUI>() == (Object)null)
					{
						((Component)val4).gameObject.AddComponent<MixingRouteEntryUI>();
					}
				}
				val3.Find("AddNew").SetAsLastSibling();
				if (DebugConfig.EnableDebugLogs)
				{
					MelonLogger.Msg("MixingStationConfigPanelBindPatch: SetAsLastSibling");
				}
				Transform obj2 = val.transform.Find("Title");
				if (obj2 != null)
				{
					((Component)obj2).gameObject.SetActive(false);
				}
				Transform obj3 = val.transform.Find("From");
				if (obj3 != null)
				{
					((Component)obj3).gameObject.SetActive(false);
				}
				Transform obj4 = val.transform.Find("To");
				if (obj4 != null)
				{
					((Component)obj4).gameObject.SetActive(false);
				}
				MixingRouteListTemplate = val;
				if (DebugConfig.EnableDebugLogs)
				{
					MelonLogger.Msg("MixingStationConfigPanelBindPatch: Static MixingRouteListTemplate initialized successfully");
				}
			}
			catch (Exception arg)
			{
				MelonLogger.Error($"MixingStationConfigPanelBindPatch: Failed to initialize MixingRouteListTemplate, error: {arg}");
			}
		}

		private static void Postfix(MixingStationConfigPanel __instance, List<EntityConfiguration> configs)
		{
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Expected O, but got Unknown
			//IL_0370: Unknown result type (might be due to invalid IL or missing references)
			//IL_037a: Expected O, but got Unknown
			//IL_0388: Unknown result type (might be due to invalid IL or missing references)
			//IL_0397: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03da: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e9: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (DebugConfig.EnableDebugLogs)
				{
					MelonLogger.Msg($"MixingStationConfigPanelBindPatch: Binding configs, count: {configs?.Count ?? 0}");
				}
				if ((Object)(object)__instance == (Object)null || (Object)(object)__instance.DestinationUI == (Object)null)
				{
					MelonLogger.Error("MixingStationConfigPanelBindPatch: __instance or DestinationUI is null");
					return;
				}
				foreach (Transform item in ((Component)__instance).transform)
				{
					Transform val = item;
					if (((Object)val).name.Contains("SupplyUI") || ((Object)val).name.Contains("RouteListFieldUI"))
					{
						Object.Destroy((Object)(object)((Component)val).gameObject);
					}
				}
				RouteListFieldUI componentTemplateFromConfigPanel = NoLazyUtilities.GetComponentTemplateFromConfigPanel<RouteListFieldUI>((EConfigurableType)4, (Func<ConfigPanel, RouteListFieldUI>)((ConfigPanel panel) => ((Component)panel).GetComponentInChildren<RouteListFieldUI>()));
				if ((Object)(object)componentTemplateFromConfigPanel == (Object)null)
				{
					MelonLogger.Error("MixingStationConfigPanelBindPatch: Failed to retrieve RouteListFieldUI template");
					return;
				}
				InitializeStaticTemplate(componentTemplateFromConfigPanel);
				foreach (MixingStationConfiguration config in configs.OfType<MixingStationConfiguration>())
				{
					GameObject val2 = Object.Instantiate<GameObject>(((Component)__instance.DestinationUI).gameObject, ((Component)__instance).transform, false);
					((Object)val2).name = $"SupplyUI_{((Object)config.station).GetInstanceID()}";
					ObjectFieldUI component = val2.GetComponent<ObjectFieldUI>();
					TextMeshProUGUI[] componentsInChildren = val2.GetComponentsInChildren<TextMeshProUGUI>();
					foreach (TextMeshProUGUI val3 in componentsInChildren)
					{
						if (((Object)((Component)val3).gameObject).name == "Title")
						{
							((TMP_Text)val3).text = "Supplies";
						}
						else if (((Object)((Component)val3).gameObject).name == "Description")
						{
							((Component)val3).gameObject.SetActive(false);
						}
					}
					if (ConfigurationExtensions.MixingSupply.TryGetValue(config.station, out var value))
					{
						component.Bind(new List<ObjectField>(1) { value });
					}
					TextMeshProUGUI[] componentsInChildren2 = ((Component)__instance.DestinationUI).GetComponentsInChildren<TextMeshProUGUI>();
					foreach (TextMeshProUGUI val4 in componentsInChildren2)
					{
						if (((Object)((Component)val4).gameObject).name == "Title")
						{
							((TMP_Text)val4).text = "Destination";
						}
						else if (((Object)((Component)val4).gameObject).name == "Description")
						{
							((Component)val4).gameObject.SetActive(false);
						}
					}
					GameObject val5 = Object.Instantiate<GameObject>(MixingRouteListTemplate, ((Component)__instance).transform, false);
					((Object)val5).name = $"RouteListFieldUI_{((Object)config.station).GetInstanceID()}";
					val5.SetActive(true);
					MixingRouteListFieldUI component2 = val5.GetComponent<MixingRouteListFieldUI>();
					if (!ConfigurationExtensions.MixingRoutes.ContainsKey(config.station))
					{
						ConfigurationExtensions.MixingRoutes[config.station] = new List<MixingRoute>();
					}
					List<MixingRoute> routes = ConfigurationExtensions.MixingRoutes[config.station];
					component2.Bind(config, routes, (UnityAction)delegate
					{
						ConfigurationExtensions.InvokeChanged((EntityConfiguration)(object)config);
					});
					RectTransform component3 = val2.GetComponent<RectTransform>();
					component3.anchoredPosition = new Vector2(component3.anchoredPosition.x, -135.76f);
					RectTransform component4 = ((Component)__instance.DestinationUI).GetComponent<RectTransform>();
					component4.anchoredPosition = new Vector2(component4.anchoredPosition.x, -195.76f);
					RectTransform component5 = val5.GetComponent<RectTransform>();
					component5.anchoredPosition = new Vector2(component5.anchoredPosition.x, -290.76f);
				}
			}
			catch (Exception arg)
			{
				MelonLogger.Error($"MixingStationConfigPanelBindPatch: Postfix failed, error: {arg}");
			}
		}
	}
	[HarmonyPatch(typeof(MixingStationConfiguration), "Destroy")]
	public class MixingStationConfigurationDestroyPatch
	{
		private static void Postfix(MixingStationConfiguration __instance)
		{
			try
			{
				ConfigurationExtensions.MixingSupply.Remove(__instance.station);
				ConfigurationExtensions.MixingRoutes.Remove(__instance.station);
				foreach (KeyValuePair<MixingStation, MixingStationConfiguration> item in ConfigurationExtensions.MixingConfig.Where((KeyValuePair<MixingStation, MixingStationConfiguration> p) => p.Value == __instance).ToList())
				{
					ConfigurationExtensions.MixingConfig.Remove(item.Key);
				}
			}
			catch (Exception arg)
			{
				MelonLogger.Error($"MixingStationConfigurationDestroyPatch: Failed for configHash={((object)__instance).GetHashCode()}, error: {arg}");
			}
		}
	}
	public static class DebugConfig
	{
		public static bool EnableDebugLogs;

		public static bool EnableDebugCoreLogs;

		public static bool EnableDebugPotLogs;

		public static bool EnableDebugMixingLogs;

		public static bool EnableDebugBehaviorLogs;
	}
	public static class BuildInfo
	{
		public const string Name = "NoLazyWorkers";

		public const string Description = "Botanist supply is moved to each pot and added to mixing stations. Botanists and Chemists will get items from their station's supply. Mixing Stations can have multiple recipes that loop the output.";

		public const string Author = "Archie";

		public const string Company = null;

		public const string Version = "1.1.0";

		public const string DownloadLink = null;
	}
	public class NoLazyWorkers : MelonMod
	{
		public override void OnInitializeMelon()
		{
			try
			{
				((MelonBase)this).HarmonyInstance.PatchAll();
				MelonLogger.Msg("NoLazyWorkers loaded!");
			}
			catch (Exception arg)
			{
				MelonLogger.Error($"Failed to initialize NoLazyWorkers: {arg}");
			}
		}

		public override void OnSceneWasUnloaded(int buildIndex, string sceneName)
		{
			ConfigurationExtensions.PotSupply.Clear();
			ConfigurationExtensions.PotSupplyData.Clear();
			ConfigurationExtensions.PotConfig.Clear();
			ConfigurationExtensions.PotSourceRoute.Clear();
			ConfigurationExtensions.MixingSupply.Clear();
			ConfigurationExtensions.MixingConfig.Clear();
			ConfigurationExtensions.MixingSourceRoute.Clear();
			ConfigurationExtensions.MixingRoutes.Clear();
			ConfigurationExtensions.NPCSupply.Clear();
			ConfigurationExtensions.NPCConfig.Clear();
			if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugCoreLogs)
			{
				MelonLogger.Msg("Cleared ConfigurationExtensions dictionaries on scene unload.");
			}
		}
	}
	public static class ConfigurationExtensions
	{
		public static Dictionary<Pot, ObjectField> PotSupply = new Dictionary<Pot, ObjectField>();

		public static Dictionary<Pot, PotConfiguration> PotConfig = new Dictionary<Pot, PotConfiguration>();

		public static Dictionary<Pot, TransitRoute> PotSourceRoute = new Dictionary<Pot, TransitRoute>();

		public static Dictionary<Pot, ObjectFieldData> PotSupplyData = new Dictionary<Pot, ObjectFieldData>();

		public static Dictionary<MixingStation, ObjectField> MixingSupply = new Dictionary<MixingStation, ObjectField>();

		public static Dictionary<MixingStation, MixingStationConfiguration> MixingConfig = new Dictionary<MixingStation, MixingStationConfiguration>();

		public static Dictionary<MixingStation, TransitRoute> MixingSourceRoute = new Dictionary<MixingStation, TransitRoute>();

		public static Dictionary<MixingStation, List<MixingRoute>> MixingRoutes = new Dictionary<MixingStation, List<MixingRoute>>();

		public static Dictionary<NPC, ObjectField> NPCSupply = new Dictionary<NPC, ObjectField>();

		public static Dictionary<NPC, EntityConfiguration> NPCConfig = new Dictionary<NPC, EntityConfiguration>();

		private static readonly Dictionary<EntityConfiguration, float> lastInvokeTimes = new Dictionary<EntityConfiguration, float>();

		private static readonly float debounceTime = 0.2f;

		public static void InvokeChanged(EntityConfiguration config)
		{
			try
			{
				if (config == null)
				{
					MelonLogger.Error("InvokeChanged: EntityConfiguration is null");
					return;
				}
				MethodInfo method = typeof(EntityConfiguration).GetMethod("InvokeChanged", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (method == null)
				{
					MelonLogger.Error("InvokeChanged: Method not found on EntityConfiguration");
					return;
				}
				float time = Time.time;
				if (lastInvokeTimes.TryGetValue(config, out var value) && time - value < debounceTime)
				{
					if (DebugConfig.EnableDebugLogs)
					{
						MelonLogger.Msg($"InvokeChanged debounced for config: {config}");
					}
					return;
				}
				lastInvokeTimes[config] = time;
				if (DebugConfig.EnableDebugLogs)
				{
					MelonLogger.Msg($"InvokeChanged called for config: {config}, StackTrace: {new StackTrace()}");
				}
				method.Invoke(config, null);
			}
			catch (Exception arg)
			{
				MelonLogger.Error($"InvokeChanged failed: {arg}");
			}
		}

		public static void SourceChanged(this PotConfiguration potConfig, BuildableItem item)
		{
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Expected O, but got Unknown
			try
			{
				if (potConfig == null)
				{
					MelonLogger.Error("SourceChanged(Pot): PotConfiguration is null");
					return;
				}
				Pot pot = potConfig.Pot;
				if (!PotSupply.ContainsKey(pot))
				{
					if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugCoreLogs)
					{
						MelonLogger.Warning($"SourceChanged(Pot): PotSupply does not contain key for PotConfig: {pot}");
					}
					return;
				}
				if (!PotSourceRoute.ContainsKey(pot))
				{
					PotSourceRoute[pot] = null;
				}
				TransitRoute val = PotSourceRoute[pot];
				if (val != null)
				{
					val.Destroy();
					PotSourceRoute[pot] = null;
				}
				ObjectField val2 = PotSupply[pot];
				if ((Object)(object)val2.SelectedObject != (Object)null)
				{
					BuildableItem selectedObject = val2.SelectedObject;
					val = new TransitRoute((ITransitEntity)(object)((selectedObject is ITransitEntity) ? selectedObject : null), (ITransitEntity)(object)pot);
					PotSourceRoute[pot] = val;
					if (((EntityConfiguration)potConfig).IsSelected)
					{
						val.SetVisualsActive(true);
					}
				}
				else
				{
					PotSourceRoute[pot] = null;
				}
				if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugCoreLogs)
				{
					object obj;
					if (val2 == null)
					{
						obj = null;
					}
					else
					{
						BuildableItem selectedObject2 = val2.SelectedObject;
						obj = ((selectedObject2 != null) ? ((Object)selectedObject2).name : null);
					}
					if (obj == null)
					{
						obj = "null";
					}
					MelonLogger.Msg($"SourceChanged(Pot): Updated for PotConfig: {potConfig}, Supply: {obj}");
				}
			}
			catch (Exception arg)
			{
				MelonLogger.Error($"SourceChanged(Pot): Failed for PotConfig: {potConfig}, error: {arg}");
			}
		}

		public static void SourceChanged(this MixingStationConfiguration mixerConfig, BuildableItem item)
		{
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Expected O, but got Unknown
			try
			{
				if (mixerConfig == null)
				{
					MelonLogger.Error("SourceChanged(MixingStation): MixingStationConfiguration is null");
					return;
				}
				MixingStation station = mixerConfig.station;
				if (!MixingSupply.ContainsKey(station))
				{
					if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugCoreLogs)
					{
						MelonLogger.Warning($"SourceChanged(MixingStation): MixerSupply does not contain key for MixerConfig: {mixerConfig}");
					}
					return;
				}
				if (!MixingSourceRoute.ContainsKey(station))
				{
					MixingSourceRoute[station] = null;
				}
				TransitRoute val = MixingSourceRoute[station];
				if (val != null)
				{
					val.Destroy();
					MixingSourceRoute[station] = null;
				}
				ObjectField val2 = MixingSupply[station];
				if ((Object)(object)val2.SelectedObject != (Object)null)
				{
					BuildableItem selectedObject = val2.SelectedObject;
					val = new TransitRoute((ITransitEntity)(object)((selectedObject is ITransitEntity) ? selectedObject : null), (ITransitEntity)(object)station);
					MixingSourceRoute[station] = val;
					if (station.Configuration.IsSelected)
					{
						val.SetVisualsActive(true);
						return;
					}
				}
				else
				{
					MixingSourceRoute[station] = null;
				}
				if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugCoreLogs)
				{
					object obj;
					if (val2 == null)
					{
						obj = null;
					}
					else
					{
						BuildableItem selectedObject2 = val2.SelectedObject;
						obj = ((selectedObject2 != null) ? ((Object)selectedObject2).name : null);
					}
					if (obj == null)
					{
						obj = "null";
					}
					MelonLogger.Msg($"SourceChanged(MixingStation): Updated for MixerConfig: {mixerConfig}, Supply: {obj}");
				}
			}
			catch (Exception arg)
			{
				MelonLogger.Error($"SourceChanged(MixingStation): Failed for MixerConfig: {mixerConfig}, error: {arg}");
			}
		}

		public static void SourceChanged(this PotConfiguration potConfig, TransitRoute SourceRoute, ObjectField Supply, Pot pot)
		{
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Expected O, but got Unknown
			try
			{
				if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugCoreLogs)
				{
					string arg = ((pot != null) ? ((Object)pot).name : null) ?? "null";
					object obj;
					if (Supply == null)
					{
						obj = null;
					}
					else
					{
						BuildableItem selectedObject = Supply.SelectedObject;
						obj = ((selectedObject != null) ? ((Object)selectedObject).name : null);
					}
					if (obj == null)
					{
						obj = "null";
					}
					MelonLogger.Msg($"SourceChanged(Pot): Called for PotConfig: {potConfig}, Pot: {arg}, Supply: {obj}");
				}
				if (potConfig == null || (Object)(object)pot == (Object)null)
				{
					MelonLogger.Error("SourceChanged(Pot): PotConfig or Pot is null");
					return;
				}
				if (!PotSupply.ContainsKey(pot))
				{
					PotSupply[pot] = Supply;
					if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugCoreLogs)
					{
						MelonLogger.Warning($"SourceChanged(Pot): Registered missing PotSupply for PotConfig: {potConfig}");
					}
				}
				if (SourceRoute != null)
				{
					if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugCoreLogs)
					{
						MelonLogger.Msg("SourceChanged(Pot): Destroying existing SourceRoute");
					}
					SourceRoute.Destroy();
					PotSourceRoute[pot] = null;
				}
				if ((Object)(object)Supply.SelectedObject != (Object)null)
				{
					if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugCoreLogs)
					{
						MelonLogger.Msg("SourceChanged(Pot): Creating new TransitRoute from " + ((Object)Supply.SelectedObject).name + " to Pot");
					}
					BuildableItem selectedObject2 = Supply.SelectedObject;
					SourceRoute = new TransitRoute((ITransitEntity)(object)((selectedObject2 is ITransitEntity) ? selectedObject2 : null), (ITransitEntity)(object)pot);
					PotSourceRoute[pot] = SourceRoute;
					if (pot.Configuration.IsSelected)
					{
						if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugCoreLogs)
						{
							MelonLogger.Msg("SourceChanged(Pot): Pot is selected, enabling TransitRoute visuals");
						}
						SourceRoute.SetVisualsActive(true);
					}
				}
				else
				{
					if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugCoreLogs)
					{
						MelonLogger.Msg("SourceChanged(Pot): Supply.SelectedObject is null, setting SourceRoute to null");
					}
					PotSourceRoute[pot] = null;
				}
			}
			catch (Exception arg2)
			{
				MelonLogger.Error($"SourceChanged(Pot): Failed for PotConfig: {potConfig}, error: {arg2}");
			}
		}

		public static void SourceChanged(this MixingStationConfiguration mixerConfig, TransitRoute SourceRoute, ObjectField Supply, MixingStation station)
		{
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Expected O, but got Unknown
			try
			{
				if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugCoreLogs)
				{
					string arg = ((station != null) ? ((Object)station).name : null) ?? "null";
					object obj;
					if (Supply == null)
					{
						obj = null;
					}
					else
					{
						BuildableItem selectedObject = Supply.SelectedObject;
						obj = ((selectedObject != null) ? ((Object)selectedObject).name : null);
					}
					if (obj == null)
					{
						obj = "null";
					}
					MelonLogger.Msg($"SourceChanged(MixingStation): Called for MixerConfig: {mixerConfig}, Station: {arg}, Supply: {obj}");
				}
				if (mixerConfig == null || (Object)(object)station == (Object)null)
				{
					MelonLogger.Error("SourceChanged(MixingStation): MixerConfig or Station is null");
					return;
				}
				if (!MixingSupply.ContainsKey(station))
				{
					MixingSupply[station] = Supply;
					if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugCoreLogs)
					{
						MelonLogger.Warning($"SourceChanged(MixingStation): Registered missing MixerSupply for MixerConfig: {mixerConfig}");
					}
				}
				if (SourceRoute != null)
				{
					if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugCoreLogs)
					{
						MelonLogger.Msg("SourceChanged(MixingStation): Destroying existing SourceRoute");
					}
					SourceRoute.Destroy();
					MixingSourceRoute[station] = null;
				}
				if ((Object)(object)Supply.SelectedObject != (Object)null)
				{
					if (DebugConfig.EnableDebugLogs || DebugConfig.EnableDebugCoreLogs)
					{
						MelonLogger.Msg("SourceChanged(MixingStation): Creating new TransitRoute from " + ((Object)S