Decompiled source of ProduceMoreIL2CPP v1.1.3

Mods/ProduceMoreIL2CPP.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
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 HarmonyLib;
using Il2CppFishNet;
using Il2CppFishNet.Connection;
using Il2CppFishNet.Object;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppScheduleOne;
using Il2CppScheduleOne.DevUtilities;
using Il2CppScheduleOne.Employees;
using Il2CppScheduleOne.EntityFramework;
using Il2CppScheduleOne.GameTime;
using Il2CppScheduleOne.Growing;
using Il2CppScheduleOne.ItemFramework;
using Il2CppScheduleOne.Lighting;
using Il2CppScheduleOne.Management;
using Il2CppScheduleOne.Money;
using Il2CppScheduleOne.NPCs;
using Il2CppScheduleOne.NPCs.Behaviour;
using Il2CppScheduleOne.ObjectScripts;
using Il2CppScheduleOne.Packaging;
using Il2CppScheduleOne.Persistence;
using Il2CppScheduleOne.PlayerScripts;
using Il2CppScheduleOne.Product;
using Il2CppScheduleOne.Product.Packaging;
using Il2CppScheduleOne.StationFramework;
using Il2CppScheduleOne.Trash;
using Il2CppScheduleOne.UI;
using Il2CppScheduleOne.UI.Items;
using Il2CppScheduleOne.UI.Management;
using Il2CppScheduleOne.UI.Phone.Delivery;
using Il2CppScheduleOne.UI.Shop;
using Il2CppScheduleOne.UI.Stations;
using Il2CppScheduleOne.UI.Stations.Drying_rack;
using Il2CppScheduleOne.Variables;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using Il2CppTMPro;
using MelonLoader;
using Microsoft.CodeAnalysis;
using ProduceMore;
using UnityEngine;
using UnityEngine.Events;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: MelonInfo(typeof(ProduceMoreMod), "ProduceMore", "1.1.3", "lasersquid", null)]
[assembly: MelonGame("TVGS", "Schedule I")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("ProduceMoreIL2CPP")]
[assembly: AssemblyConfiguration("IL2CPP")]
[assembly: AssemblyFileVersion("1.1.3.0")]
[assembly: AssemblyInformationalVersion("1.1.3+f9a7239564a117040269e88ed8ba5e960d9ff8f0")]
[assembly: AssemblyProduct("ProduceMoreIL2CPP")]
[assembly: AssemblyTitle("ProduceMoreIL2CPP")]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.3.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 ProduceMore
{
	public class ProduceMoreMod : MelonMod
	{
		public MelonPreferences_Category stationSpeeds;

		public MelonPreferences_Category stationCapacities;

		public MelonPreferences_Category employeeAnimation;

		public MelonPreferences_Category stackSizes;

		public MelonPreferences_Category stackOverrides;

		public IEqualityComparer<Object> unityComparer;

		public HashSet<GridItem> processedStationCapacities;

		public HashSet<GridItem> processedStationSpeeds;

		public HashSet<GridItem> processedStationTimes;

		public HashSet<ItemDefinition> processedItemDefs;

		public HashSet<StationRecipe> processedRecipes;

		public Dictionary<string, int> originalStackLimits;

		public Dictionary<string, int> originalStationCapacities;

		public Dictionary<string, int> originalStationTimes;

		public Dictionary<StationRecipe, int> originalRecipeTimes;

		public HashSet<NPC> registeredEmployees;

		public List<object> runningCoroutines;

		public bool plantsAlwaysGrowPresent = false;

		public bool checkedMelons = false;

		public Harmony harmony = new Harmony("com.lasersquid.producemore");

		public ProduceMoreMod()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			unityComparer = new Utils.UnityObjectComparer();
			processedStationCapacities = new HashSet<GridItem>((IEqualityComparer<GridItem>?)unityComparer);
			processedStationSpeeds = new HashSet<GridItem>((IEqualityComparer<GridItem>?)unityComparer);
			processedStationTimes = new HashSet<GridItem>((IEqualityComparer<GridItem>?)unityComparer);
			processedItemDefs = new HashSet<ItemDefinition>((IEqualityComparer<ItemDefinition>?)unityComparer);
			processedRecipes = new HashSet<StationRecipe>((IEqualityComparer<StationRecipe>?)unityComparer);
			originalStackLimits = new Dictionary<string, int>();
			originalStationCapacities = new Dictionary<string, int>();
			originalStationTimes = new Dictionary<string, int>();
			originalRecipeTimes = new Dictionary<StationRecipe, int>((IEqualityComparer<StationRecipe>?)unityComparer);
			registeredEmployees = new HashSet<NPC>((IEqualityComparer<NPC>?)unityComparer);
			runningCoroutines = new List<object>();
		}

		public override void OnInitializeMelon()
		{
			InitializeMelonPreferences();
			Utils.Initialize(this);
			((MelonBase)this).LoggerInstance.Msg("Initialized.");
		}

		public override void OnSceneWasLoaded(int buildIndex, string sceneName)
		{
			((MelonMod)this).OnSceneWasLoaded(buildIndex, sceneName);
			if (sceneName.ToLower().Contains("main") || sceneName.ToLower().Contains("tutorial"))
			{
				if (!checkedMelons)
				{
					plantsAlwaysGrowPresent = Utils.OtherModIsLoaded("PlantsAlwaysGrowMod");
					checkedMelons = true;
				}
				Utils.LateInitialize();
			}
		}

		public override void OnSceneWasUnloaded(int buildIndex, string sceneName)
		{
			((MelonMod)this).OnSceneWasUnloaded(buildIndex, sceneName);
			if (sceneName.ToLower().Contains("main") || sceneName.ToLower().Contains("tutorial"))
			{
				ResetState();
			}
		}

		public void StopCoroutines()
		{
			foreach (object runningCoroutine in runningCoroutines)
			{
				if (runningCoroutine != null)
				{
					MelonCoroutines.Stop(runningCoroutine);
				}
			}
			runningCoroutines.Clear();
		}

		public override void OnPreferencesSaved()
		{
			((MelonBase)this).OnPreferencesSaved();
			ResetState();
		}

		private void ResetState()
		{
			processedStationCapacities = new HashSet<GridItem>((IEqualityComparer<GridItem>?)unityComparer);
			processedStationSpeeds = new HashSet<GridItem>((IEqualityComparer<GridItem>?)unityComparer);
			processedStationTimes = new HashSet<GridItem>((IEqualityComparer<GridItem>?)unityComparer);
			processedItemDefs = new HashSet<ItemDefinition>((IEqualityComparer<ItemDefinition>?)unityComparer);
			processedRecipes = new HashSet<StationRecipe>((IEqualityComparer<StationRecipe>?)unityComparer);
		}

		private void InitializeMelonPreferences()
		{
			stationSpeeds = MelonPreferences.CreateCategory("ProduceMore_01_station_speeds", "Station Speeds (1=normal, 2=double, 0.5=half)");
			employeeAnimation = MelonPreferences.CreateCategory("ProduceMore_02_employee_animation", "Employee Speed (1=normal, 2=double, 0.5=half)");
			stationCapacities = MelonPreferences.CreateCategory("ProduceMore_03_station_capacities", "Station Capacities");
			stackSizes = MelonPreferences.CreateCategory("ProduceMore_04_stack_sizes", "Stack Limits (by category)");
			stackOverrides = MelonPreferences.CreateCategory("ProduceMore_05_stack_overrides", "Stack Limit Overrides");
			stationSpeeds.SetFilePath("UserData/ProduceMore.cfg", true, false);
			stationCapacities.SetFilePath("UserData/ProduceMore.cfg", true, false);
			employeeAnimation.SetFilePath("UserData/ProduceMore.cfg", true, false);
			stackSizes.SetFilePath("UserData/ProduceMore.cfg", true, false);
			stackOverrides.SetFilePath("UserData/ProduceMore.cfg", true, false);
			stationSpeeds.CreateEntry<float>("LabOven", 1f, "Lab Oven", false);
			stationSpeeds.CreateEntry<float>("Cauldron", 1f, "Cauldron", false);
			stationSpeeds.CreateEntry<float>("BrickPress", 1f, "Brick Press", false);
			stationSpeeds.CreateEntry<float>("ChemistryStation", 1f, "Chemistry Station", false);
			stationSpeeds.CreateEntry<float>("DryingRack", 1f, "Drying Rack", false);
			stationSpeeds.CreateEntry<float>("MixingStation", 1f, "Mixing Station", false);
			stationSpeeds.CreateEntry<float>("MixingStationMk2", 1f, "Mixing Station Mk2", false);
			stationSpeeds.CreateEntry<float>("PackagingStation", 1f, "Packaging Station", false);
			stationSpeeds.CreateEntry<float>("PackagingStationMk2", 1f, "Packaging Station Mk2", false);
			stationSpeeds.CreateEntry<float>("Pot", 1f, "Pot", false);
			stationSpeeds.CreateEntry<float>("MushroomBed", 1f, "Mushroom Bed", false);
			stationCapacities.CreateEntry<int>("DryingRack", 20, "Drying Rack", false);
			stationCapacities.CreateEntry<int>("MixingStation", 10, "Mixing Station", false);
			stationCapacities.CreateEntry<int>("MixingStationMk2", 20, "Mixing Station Mk2", false);
			stationCapacities.CreateEntry<int>("PackagingStation", 20, "Packaging Station", false);
			stationCapacities.CreateEntry<int>("PackagingStationMk2", 20, "Packaging Station Mk2", false);
			employeeAnimation.CreateEntry<float>("employeeWalkAcceleration", 1f, "Employee walk speed modifier", false);
			employeeAnimation.CreateEntry<float>("LabOvenAcceleration", 1f, "Lab Oven animation speed modifier", false);
			employeeAnimation.CreateEntry<float>("CauldronAcceleration", 1f, "Cauldron animation speed modifier", false);
			employeeAnimation.CreateEntry<float>("BrickPressAcceleration", 1f, "Brick Press animation speed modifier", false);
			employeeAnimation.CreateEntry<float>("ChemistryStationAcceleration", 1f, "Chemistry Station animation speed modifier", false);
			employeeAnimation.CreateEntry<float>("DryingRackAcceleration", 1f, "Drying Rack animation speed modifier", false);
			employeeAnimation.CreateEntry<float>("MixingStationAcceleration", 1f, "Mixing Station animation speed modifier", false);
			employeeAnimation.CreateEntry<float>("MixingStationMk2Acceleration", 1f, "Mixing Station Mk2 animation speed modifier", false);
			employeeAnimation.CreateEntry<float>("MushroomBedAcceleration", 1f, "Mushroom Bed animation speed modifier", false);
			employeeAnimation.CreateEntry<float>("PackagingStationAcceleration", 1f, "Packaging Station animation speed modifier", false);
			employeeAnimation.CreateEntry<float>("PackagingStationMk2Acceleration", 1f, "Packaging Station Mk2 animation speed modifier", false);
			employeeAnimation.CreateEntry<float>("PotAcceleration", 1f, "Pot animation speed modifier", false);
			employeeAnimation.CreateEntry<float>("SpawnStationAcceleration", 1f, "Spawn Station animation speed modifier", false);
			stackSizes.CreateEntry<int>("Agriculture", 10, "Agriculture", false);
			stackSizes.CreateEntry<int>("Cash", 1000, "Cash", false);
			stackSizes.CreateEntry<int>("Clothing", 1, "Clothing", false);
			stackSizes.CreateEntry<int>("Consumable", 20, "Consumable", false);
			stackSizes.CreateEntry<int>("Decoration", 1, "Decoration", false);
			stackSizes.CreateEntry<int>("Equipment", 10, "Equipment", false);
			stackSizes.CreateEntry<int>("Furniture", 10, "Furniture", false);
			stackSizes.CreateEntry<int>("Ingredient", 20, "Ingredient", false);
			stackSizes.CreateEntry<int>("Lighting", 10, "Lighting", false);
			stackSizes.CreateEntry<int>("Packaging", 20, "Packaging", false);
			stackSizes.CreateEntry<int>("Product", 20, "Product", false);
			stackSizes.CreateEntry<int>("Storage", 10, "Storage", false);
			stackSizes.CreateEntry<int>("Tools", 1, "Tools", false);
			stackOverrides.CreateEntry<int>("Acid", 10, "Acid", false);
			stackOverrides.CreateEntry<int>("Phosphorus", 10, "Phosphorus", false);
			stackOverrides.CreateEntry<int>("Low-Quality Pseudo", 10, "Low-Quality Pseudo", false);
			stackOverrides.CreateEntry<int>("Pseudo", 10, "Pseudo", false);
			stackOverrides.CreateEntry<int>("High-Quality Pseudo", 10, "High-Quality Pseudo", false);
			stackOverrides.CreateEntry<int>("Shotgun Shell", 10, "Shotgun Shell", false);
			stackOverrides.CreateEntry<int>("M1911 Magazine", 10, "M1911 Magazine", false);
			stackOverrides.CreateEntry<int>("Revolver Cylinder", 10, "Revolver Cylinder", false);
			stackOverrides.CreateEntry<int>("Spray Paint", 10, "Spray Paint", false);
			stackOverrides.CreateEntry<int>("Graffiti Cleaner", 10, "Graffiti Cleaner", false);
			stationSpeeds.SaveToFile(false);
			stationCapacities.SaveToFile(false);
			employeeAnimation.SaveToFile(false);
			stackSizes.SaveToFile(false);
			stackOverrides.SaveToFile(false);
		}

		public int GetStackLimit(ItemInstance item)
		{
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			int result = 10;
			if (item == null)
			{
				return 0;
			}
			if (stackOverrides.GetEntry<int>(item.Name) != null)
			{
				result = stackOverrides.GetEntry<int>(item.Name).Value;
			}
			else
			{
				EItemCategory value = ((!(item.Definition.Name == "Speed Grow")) ? item.Category : ((EItemCategory)2));
				if (stackSizes.GetEntry<int>(((object)(EItemCategory)(ref value)).ToString()) != null)
				{
					result = stackSizes.GetEntry<int>(((object)(EItemCategory)(ref value)).ToString()).Value;
				}
				else
				{
					MelonLogger.Msg($"Couldn't find stack size for item {item.Name} with category {value}, assuming 10");
				}
			}
			return result;
		}

		public int GetStackLimit(ItemDefinition itemDef)
		{
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			int result = 10;
			if (stackOverrides.GetEntry<int>(itemDef.Name) != null)
			{
				result = stackOverrides.GetEntry<int>(itemDef.Name).Value;
			}
			else
			{
				EItemCategory value = ((!(itemDef.Name == "Speed Grow")) ? itemDef.Category : ((EItemCategory)2));
				if (stackSizes.GetEntry<int>(((object)(EItemCategory)(ref value)).ToString()) != null)
				{
					result = stackSizes.GetEntry<int>(((object)(EItemCategory)(ref value)).ToString()).Value;
				}
				else
				{
					MelonLogger.Msg($"Couldn't find stack size for item {itemDef.Name} with category {value}");
				}
			}
			return result;
		}

		public int GetStackLimit(string itemName, EItemCategory category)
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			int result = 10;
			if (stackOverrides.GetEntry<int>(itemName) != null)
			{
				result = stackOverrides.GetEntry<int>(itemName).Value;
			}
			else
			{
				EItemCategory value = ((!(itemName == "Speed Grow")) ? category : ((EItemCategory)2));
				if (stackSizes.GetEntry<int>(((object)(EItemCategory)(ref value)).ToString()) != null)
				{
					result = stackSizes.GetEntry<int>(((object)(EItemCategory)(ref value)).ToString()).Value;
				}
				else
				{
					MelonLogger.Msg($"Couldn't find stack size for item {itemName} with category {value}");
				}
			}
			return result;
		}

		public int GetStackLimit(EItemCategory category)
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			int result = 10;
			if (stackSizes.GetEntry<int>(((object)(EItemCategory)(ref category)).ToString()) != null)
			{
				result = stackSizes.GetEntry<int>(((object)(EItemCategory)(ref category)).ToString()).Value;
			}
			else
			{
				MelonLogger.Msg($"Couldn't find stack size for category {category}");
			}
			return result;
		}

		public int GetStationCapacity(string station)
		{
			int result = 10;
			if (stationCapacities.GetEntry<int>(station) != null)
			{
				result = stationCapacities.GetEntry<int>(station).Value;
			}
			else
			{
				MelonLogger.Msg("Couldn't find station capacity for " + station);
			}
			return result;
		}

		public float GetStationSpeed(string station)
		{
			float result = 1f;
			if (stationSpeeds.GetEntry<float>(station) != null)
			{
				result = stationSpeeds.GetEntry<float>(station).Value;
			}
			else
			{
				MelonLogger.Msg("Couldn't find station speed modifier for " + station);
			}
			return result;
		}

		public float GetStationWorkSpeed(string station)
		{
			float result = 1f;
			if (employeeAnimation.GetEntry<float>(station + "Acceleration") != null)
			{
				result = employeeAnimation.GetEntry<float>(station + "Acceleration").Value;
			}
			else
			{
				MelonLogger.Msg("Couldn't find employee work speed modifier for " + station);
			}
			return result;
		}
	}
	public class Utils
	{
		public class UnityObjectComparer : IEqualityComparer<Object>
		{
			public bool Equals(Object a, Object b)
			{
				return a.GetInstanceID() == b.GetInstanceID();
			}

			public int GetHashCode(Object item)
			{
				return item.GetInstanceID();
			}
		}

		public static ProduceMoreMod Mod;

		private static Assembly S1Assembly;

		public static Dictionary<Type, string> typeStrings = new Dictionary<Type, string>
		{
			{
				typeof(DryingRack),
				"DryingRack"
			},
			{
				typeof(LabOven),
				"LabOven"
			},
			{
				typeof(ChemistryStation),
				"ChemistryStation"
			},
			{
				typeof(MixingStationMk2),
				"MixingStationMk2"
			},
			{
				typeof(MixingStation),
				"MixingStation"
			},
			{
				typeof(BrickPress),
				"BrickPress"
			},
			{
				typeof(Cauldron),
				"Cauldron"
			},
			{
				typeof(PackagingStationMk2),
				"PackagingStationMk2"
			},
			{
				typeof(PackagingStation),
				"PackagingStation"
			},
			{
				typeof(Pot),
				"Pot"
			},
			{
				typeof(MushroomBed),
				"MushroomBed"
			},
			{
				typeof(MushroomSpawnStation),
				"SpawnStation"
			}
		};

		public static void Initialize(ProduceMoreMod mod)
		{
			Mod = mod;
			S1Assembly = AppDomain.CurrentDomain.GetAssemblies().First((Assembly a) => a.GetName().Name == "Assembly-CSharp");
		}

		public static void LateInitialize()
		{
			Singleton<LoadManager>.Instance.onPreSceneChange.AddListener(ToUnityAction(OnPreSceneChange));
		}

		private static void OnPreSceneChange()
		{
			Mod.StopCoroutines();
		}

		public static Treturn GetField<Ttarget, Treturn>(string fieldName, object target) where Treturn : class
		{
			return (Treturn)GetField<Ttarget>(fieldName, target);
		}

		public static object GetField<Ttarget>(string fieldName, object target)
		{
			return AccessTools.Property(typeof(Ttarget), fieldName).GetValue(target);
		}

		public static void SetField<Ttarget>(string fieldName, object target, object value)
		{
			AccessTools.Property(typeof(Ttarget), fieldName).SetValue(target, value);
		}

		public static Treturn GetProperty<Ttarget, Treturn>(string fieldName, object target)
		{
			return (Treturn)GetProperty<Ttarget>(fieldName, target);
		}

		public static object GetProperty<Ttarget>(string fieldName, object target)
		{
			return AccessTools.Property(typeof(Ttarget), fieldName).GetValue(target);
		}

		public static void SetProperty<Ttarget>(string fieldName, object target, object value)
		{
			AccessTools.Property(typeof(Ttarget), fieldName).SetValue(target, value);
		}

		public static Treturn CallMethod<Ttarget, Treturn>(string methodName, object target)
		{
			return (Treturn)CallMethod<Ttarget>(methodName, target, Array.Empty<object>());
		}

		public static Treturn CallMethod<Ttarget, Treturn>(string methodName, object target, object[] args)
		{
			return (Treturn)CallMethod<Ttarget>(methodName, target, args);
		}

		public static Treturn CallMethod<Ttarget, Treturn>(string methodName, Type[] argTypes, object target, object[] args)
		{
			return (Treturn)CallMethod<Ttarget>(methodName, argTypes, target, args);
		}

		public static object CallMethod<Ttarget>(string methodName, object target)
		{
			return AccessTools.Method(typeof(Ttarget), methodName, (Type[])null, (Type[])null).Invoke(target, Array.Empty<object>());
		}

		public static object CallMethod<Ttarget>(string methodName, object target, object[] args)
		{
			return AccessTools.Method(typeof(Ttarget), methodName, (Type[])null, (Type[])null).Invoke(target, args);
		}

		public static object CallMethod<Ttarget>(string methodName, Type[] argTypes, object target, object[] args)
		{
			return AccessTools.Method(typeof(Ttarget), methodName, argTypes, (Type[])null).Invoke(target, args);
		}

		public static T CastTo<T>(Il2CppObjectBase o) where T : Il2CppObjectBase
		{
			if (typeof(T).IsAssignableFrom(GetType(o)))
			{
				return (T)Activator.CreateInstance(typeof(T), o.Pointer);
			}
			return default(T);
		}

		public static bool Is<T>(Il2CppObjectBase o) where T : Il2CppObjectBase
		{
			return typeof(T).IsAssignableFrom(GetType(o));
		}

		public static T ToInterface<T>(Il2CppObjectBase o) where T : Il2CppObjectBase
		{
			return (T)Activator.CreateInstance(typeof(T), o.Pointer);
		}

		public static Type GetType(Il2CppObjectBase o)
		{
			string fullName = Il2CppType.TypeFromPointer(o.ObjectClass, "<unknown type>").FullName;
			return S1Assembly.GetType("Il2Cpp" + fullName);
		}

		public static UnityAction ToUnityAction(Action action)
		{
			return DelegateSupport.ConvertDelegate<UnityAction>((Delegate)action);
		}

		public static UnityAction<T> ToUnityAction<T>(Action<T> action)
		{
			return DelegateSupport.ConvertDelegate<UnityAction<T>>((Delegate)action);
		}

		public static Predicate<T> ConvertToPredicate<T>(Func<T, bool> func)
		{
			return DelegateSupport.ConvertDelegate<Predicate<T>>((Delegate)func);
		}

		public static void Log(string message)
		{
			((MelonBase)Mod).LoggerInstance.Msg(message);
		}

		public static void Warn(string message)
		{
			((MelonBase)Mod).LoggerInstance.Warning(message);
		}

		public static void PrintException(Exception e)
		{
			Warn("Exception: " + e.GetType().Name + " - " + e.Message);
			Warn("Source: " + e.Source);
			Warn(e.StackTrace ?? "");
			if (e.InnerException != null)
			{
				Warn("Inner exception: " + e.InnerException.GetType().Name + " - " + e.InnerException.Message);
				Warn("Source: " + e.InnerException.Source);
				Warn(e.InnerException.StackTrace ?? "");
				if (e.InnerException.InnerException != null)
				{
					Warn("Inner inner exception: " + e.InnerException.InnerException.GetType().Name + " - " + e.InnerException.InnerException.Message);
					Warn("Source: " + e.InnerException.InnerException.Source);
					Warn(e.InnerException.InnerException.StackTrace ?? "");
				}
			}
		}

		public static bool OtherModIsLoaded(string modName)
		{
			List<MelonBase> list = new List<MelonBase>(MelonBase.RegisteredMelons);
			MelonBase val = list.Find((MelonBase m) => m.Info.Name == modName);
			return val != null;
		}

		public static object StartCoroutine(IEnumerator func)
		{
			object obj = MelonCoroutines.Start(func);
			Mod.runningCoroutines.Add(obj);
			return obj;
		}

		public static void StopCoroutine(object coroutine)
		{
			try
			{
				Mod.runningCoroutines.Remove(coroutine);
			}
			catch (Exception e)
			{
				PrintException(e);
			}
			try
			{
				MelonCoroutines.Stop(coroutine);
			}
			catch (Exception e2)
			{
				PrintException(e2);
			}
		}

		public static void AddStationCapacity(GridItem station, int capacity)
		{
			string valueOrDefault = typeStrings.GetValueOrDefault(GetType((Il2CppObjectBase)(object)station));
			if (!Mod.processedStationCapacities.Contains(station))
			{
				if (!Mod.originalStationCapacities.ContainsKey(valueOrDefault))
				{
					Mod.originalStationCapacities.Add(valueOrDefault, capacity);
				}
				Mod.processedStationCapacities.Add(station);
			}
		}

		public static void AddOriginalStationTime(GridItem station, int time)
		{
			string valueOrDefault = typeStrings.GetValueOrDefault(GetType((Il2CppObjectBase)(object)station));
			if (!Mod.processedStationTimes.Contains(station))
			{
				if (!Mod.originalStationTimes.ContainsKey(valueOrDefault))
				{
					Mod.originalStationTimes.Add(valueOrDefault, time);
				}
				Mod.processedStationTimes.Add(station);
			}
		}

		public static void AddOriginalStationTime(string stationString, int time)
		{
			if (!Mod.originalStationTimes.ContainsKey(stationString))
			{
				Mod.originalStationTimes.TryAdd(stationString, time);
			}
		}

		public static void ModItemStackLimit(ItemDefinition itemDefinition)
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			if (!Mod.processedItemDefs.Contains(itemDefinition) && itemDefinition.Name.ToLower() != "cash")
			{
				EItemCategory val = ((!(itemDefinition.Name == "Speed Grow")) ? itemDefinition.Category : ((EItemCategory)2));
				if (!Mod.originalStackLimits.ContainsKey(((object)(EItemCategory)(ref val)).ToString()))
				{
					Mod.originalStackLimits[((object)(EItemCategory)(ref val)).ToString()] = itemDefinition.StackLimit;
				}
				itemDefinition.StackLimit = Mod.GetStackLimit(itemDefinition.GetDefaultInstance(1));
				Mod.processedItemDefs.Add(itemDefinition);
			}
		}

		public static void ModRecipeTime(StationRecipe recipe, float stationSpeed)
		{
			if (!Mod.processedRecipes.Contains(recipe))
			{
				if (!Mod.originalRecipeTimes.ContainsKey(recipe))
				{
					Mod.originalRecipeTimes[recipe] = recipe.CookTime_Mins;
				}
				int cookTime_Mins = Mathf.Max((int)((float)recipe.CookTime_Mins / stationSpeed), 1);
				recipe.CookTime_Mins = cookTime_Mins;
				Mod.processedRecipes.Add(recipe);
			}
		}

		public static int GetStationCapacity(GridItem station)
		{
			if ((Object)(object)station == (Object)null)
			{
				return 10;
			}
			return Mod.GetStationCapacity(typeStrings[GetType((Il2CppObjectBase)(object)station)]);
		}

		public static float GetStationSpeed(GridItem station)
		{
			if ((Object)(object)station == (Object)null)
			{
				return 1f;
			}
			return Mod.GetStationSpeed(typeStrings[GetType((Il2CppObjectBase)(object)station)]);
		}

		public static float GetStationWorkSpeed(GridItem station)
		{
			if ((Object)(object)station == (Object)null)
			{
				return 1f;
			}
			return Mod.GetStationWorkSpeed(typeStrings[GetType((Il2CppObjectBase)(object)station)]);
		}

		public static int GetOriginalStationTime(GridItem station)
		{
			int result = 10;
			if ((Object)(object)station != (Object)null)
			{
				string text = typeStrings[GetType((Il2CppObjectBase)(object)station)];
				if (Mod.originalStationTimes.ContainsKey(text))
				{
					result = Mod.originalStationTimes[text];
				}
				else
				{
					Warn("Tried to get original station time for " + text + ", but there wasn't one in the index?");
				}
			}
			return result;
		}

		public static int GetOriginalStationTime(string stationString)
		{
			int result = 1;
			if (!Mod.originalStationTimes.ContainsKey(stationString))
			{
				Warn("Tried to get original station time for " + stationString + ", but there wasn't one in the index?");
			}
			else
			{
				result = Mod.originalStationTimes[stationString];
			}
			return result;
		}
	}
	[HarmonyPatch]
	public class ItemCapacityPatches
	{
		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		[HarmonyPrefix]
		public static void StackLimitPrefix(ItemInstance __instance)
		{
			Utils.ModItemStackLimit(__instance.Definition);
		}

		[HarmonyPatch(typeof(ListingEntry), "Initialize")]
		[HarmonyPrefix]
		public static void InitializePrefix(ShopListing match)
		{
			if (match != null && (Object)(object)match.Item != (Object)null)
			{
				Utils.ModItemStackLimit((ItemDefinition)(object)match.Item);
			}
		}

		[HarmonyPatch(typeof(ItemSlotUI), "UpdateUI")]
		[HarmonyPostfix]
		public static void UpdateUIPostfix(ItemSlotUI __instance)
		{
			if (__instance.assignedSlot != null && __instance.assignedSlot.ItemInstance != null)
			{
				Utils.ModItemStackLimit(__instance.assignedSlot.ItemInstance.Definition);
			}
		}

		[HarmonyPatch(typeof(ItemSlot), "GetCapacityForItem")]
		[HarmonyPostfix]
		public static void GetCapacityForItemPostfix(ItemSlot __instance, ref int __result, ItemInstance item, bool checkPlayerFilters)
		{
			if (item != null)
			{
				Utils.ModItemStackLimit(item.Definition);
			}
			if (__instance.ItemInstance != null)
			{
				Utils.ModItemStackLimit(__instance.ItemInstance.Definition);
			}
			if (!__instance.DoesItemMatchHardFilters(item))
			{
				__result = 0;
			}
			else if (checkPlayerFilters && !__instance.DoesItemMatchPlayerFilters(item))
			{
				__result = 0;
			}
			else if (__instance.ItemInstance == null || __instance.ItemInstance.CanStackWith(item, false))
			{
				__result = Mathf.Max(item.StackLimit - __instance.Quantity, 0);
			}
			else
			{
				__result = 0;
			}
		}

		[HarmonyPatch(typeof(NPCInventory), "GetCapacityForItem")]
		[HarmonyPrefix]
		public static void NPCGetCapacityForItemPrefix(NPCInventory __instance, ItemInstance item, ref int __result)
		{
			if (item != null)
			{
				Utils.ModItemStackLimit(item.Definition);
			}
		}

		[HarmonyPatch(typeof(NPCInventory), "GetCapacityForItem")]
		[HarmonyPostfix]
		public static void NPCGetCapacityForItemPostfix(NPCInventory __instance, ItemInstance item, ref int __result)
		{
			if (item == null)
			{
				return;
			}
			int num = 0;
			for (int i = 0; i < __instance.ItemSlots.Count; i++)
			{
				if (__instance.ItemSlots[i] != null && !__instance.ItemSlots[i].IsLocked && !__instance.ItemSlots[i].IsAddLocked)
				{
					if (__instance.ItemSlots[i].ItemInstance == null)
					{
						num += item.StackLimit;
					}
					else if (__instance.ItemSlots[i].ItemInstance.CanStackWith(item, true))
					{
						num += Mathf.Max(0, item.StackLimit - __instance.ItemSlots[i].ItemInstance.Quantity);
					}
				}
			}
			__result = num;
		}

		[HarmonyPatch(typeof(NPCInventory), "CanItemFit")]
		[HarmonyPostfix]
		public static void NPCCanItemFitPrefix(NPCInventory __instance, ItemInstance item, ref bool __result)
		{
			__result = item != null && __instance.GetCapacityForItem(item) >= item.Quantity;
		}
	}
	[HarmonyPatch]
	public class RegistryPatches
	{
		[HarmonyTargetMethod]
		public static MethodBase TargetMethod()
		{
			return AccessTools.FirstMethod(typeof(Registry), (Func<MethodInfo, bool>)((MethodInfo method) => method.Name == "GetItem" && method.ReturnType == typeof(ItemDefinition)));
		}

		[HarmonyPatch]
		[HarmonyPostfix]
		public static void GetItemPostfix(ref ItemDefinition __result)
		{
			if ((Object)(object)__result != (Object)null)
			{
				Utils.ModItemStackLimit(__result);
			}
		}
	}
	[HarmonyPatch]
	public class DryingRackPatches
	{
		[CompilerGenerated]
		private sealed class <BeginActionCoroutine>d__6 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public StartDryingRackBehaviour behaviour;

			private float <workSpeed>5__1;

			private float <originalTimePerItem>5__2;

			private float <waitTimePerItem>5__3;

			private int <inputQuantity>5__4;

			private int <outputCapacity>5__5;

			private int <quantityToDry>5__6;

			private float <waitTime>5__7;

			private int <lastWholeSecond>5__8;

			private object <workRoutine>5__9;

			private float <i>5__10;

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

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

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

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

			private bool MoveNext()
			{
				//IL_002f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0039: Expected O, but got Unknown
				//IL_0151: Unknown result type (might be due to invalid IL or missing references)
				//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
				//IL_01b4: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForEndOfFrame();
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					<workSpeed>5__1 = Utils.GetStationWorkSpeed((GridItem)(object)behaviour.Rack);
					<originalTimePerItem>5__2 = StartDryingRackBehaviour.TIME_PER_ITEM;
					<waitTimePerItem>5__3 = <originalTimePerItem>5__2 / <workSpeed>5__1;
					<inputQuantity>5__4 = behaviour.Rack.InputSlot.Quantity;
					<outputCapacity>5__5 = behaviour.Rack.ItemCapacity - behaviour.Rack.GetTotalDryingItems();
					<quantityToDry>5__6 = Mathf.Min(<inputQuantity>5__4, <outputCapacity>5__5);
					<waitTime>5__7 = Mathf.Max(0.1f, <waitTimePerItem>5__3 * (float)<quantityToDry>5__6);
					<lastWholeSecond>5__8 = 0;
					((Behaviour)behaviour).Npc.Avatar.Animation.SetTrigger("GrabItem");
					<i>5__10 = 0f;
					break;
				case 2:
					<>1__state = -1;
					<i>5__10 += Time.deltaTime;
					break;
				}
				if (<i>5__10 < <waitTime>5__7)
				{
					((Behaviour)behaviour).Npc.Avatar.LookController.OverrideLookTarget(behaviour.Rack.uiPoint.position, 0, false);
					if (<i>5__10 - (float)<lastWholeSecond>5__8 >= 1f)
					{
						((Behaviour)behaviour).Npc.Avatar.Animation.SetTrigger("GrabItem");
						<lastWholeSecond>5__8 = (int)<i>5__10;
					}
					<>2__current = (object)new WaitForEndOfFrame();
					<>1__state = 2;
					return true;
				}
				((Behaviour)behaviour).Npc.Avatar.Animation.ResetTrigger("GrabItem");
				if (InstanceFinder.IsServer)
				{
					behaviour.Rack.StartOperation();
				}
				Utils.SetProperty<StartDryingRackBehaviour>("WorkInProgress", behaviour, false);
				<workRoutine>5__9 = Utils.GetField<StartDryingRackBehaviour>("workRoutine", behaviour);
				Utils.StopCoroutine(<workRoutine>5__9);
				Utils.SetField<StartDryingRackBehaviour>("workRoutine", behaviour, null);
				return false;
			}

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

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

		[HarmonyPatch(typeof(StartDryingRackBehaviour), "IsRackReady")]
		[HarmonyPrefix]
		public static void IsRackReadyPrefix(DryingRack rack, ref bool __result)
		{
			Utils.AddStationCapacity((GridItem)(object)rack, rack.ItemCapacity);
			rack.ItemCapacity = Utils.GetStationCapacity((GridItem)(object)rack);
		}

		[HarmonyPatch(typeof(DryingRack), "CanStartOperation")]
		[HarmonyPostfix]
		public static void CanStartOperationPostfix(DryingRack __instance, ref bool __result)
		{
			Utils.AddStationCapacity((GridItem)(object)__instance, 20);
			__instance.ItemCapacity = Utils.GetStationCapacity((GridItem)(object)__instance);
			__result = __instance.GetTotalDryingItems() < __instance.ItemCapacity && __instance.InputSlot.Quantity != 0 && !__instance.InputSlot.IsLocked && !__instance.InputSlot.IsRemovalLocked;
		}

		[HarmonyPatch(typeof(DryingOperationUI), "UpdatePosition")]
		[HarmonyPostfix]
		public static void UpdatePositionPostfix(DryingOperationUI __instance)
		{
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			DryingRack rack = Singleton<DryingRackCanvas>.Instance.Rack;
			Utils.AddOriginalStationTime((GridItem)(object)rack, DryingRack.DRY_MINS_PER_TIER);
			int originalStationTime = Utils.GetOriginalStationTime((GridItem)(object)rack);
			float stationSpeed = Utils.GetStationSpeed((GridItem)(object)rack);
			float num = (float)originalStationTime / stationSpeed;
			float num2 = Mathf.Clamp01((float)__instance.AssignedOperation.Time / num);
			int num3 = Mathf.Clamp((int)num - __instance.AssignedOperation.Time, 0, (int)num);
			int num4 = num3 / 60;
			int num5 = num3 % 60;
			__instance.Tooltip.text = num4 + "h " + num5 + "m until next tier";
			float num6 = -62.5f;
			float num7 = 0f - num6;
			__instance.Rect.anchoredPosition = new Vector2(Mathf.Lerp(num6, num7, num2), 0f);
		}

		[HarmonyPatch(typeof(DryingOperation), "GetQuality")]
		[HarmonyPostfix]
		public static void GetQualityPostfix(DryingOperation __instance, ref EQuality __result)
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Expected I4, but got Unknown
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Expected I4, but got Unknown
			Utils.AddOriginalStationTime("DryingRack", DryingRack.DRY_MINS_PER_TIER);
			int originalStationTime = Utils.GetOriginalStationTime("DryingRack");
			float stationSpeed = Utils.Mod.GetStationSpeed("DryingRack");
			int num = (int)((float)originalStationTime / stationSpeed);
			if (__instance.Time >= num)
			{
				__result = (EQuality)(__instance.StartQuality + 1);
			}
			else
			{
				__result = (EQuality)(int)__instance.StartQuality;
			}
		}

		[HarmonyPatch(typeof(DryingRack), "MinPass")]
		[HarmonyPrefix]
		public static bool MinPassPrefix(DryingRack __instance)
		{
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Invalid comparison between Unknown and I4
			if ((Object)(object)__instance == (Object)null)
			{
				return false;
			}
			Utils.AddOriginalStationTime((GridItem)(object)__instance, DryingRack.DRY_MINS_PER_TIER);
			int originalStationTime = Utils.GetOriginalStationTime((GridItem)(object)__instance);
			float stationSpeed = Utils.GetStationSpeed((GridItem)(object)__instance);
			int num = (int)((float)originalStationTime / stationSpeed);
			foreach (DryingOperation item in __instance.DryingOperations.ToArray())
			{
				int time = item.Time;
				item.Time = time + 1;
				if (item.Time < num)
				{
					continue;
				}
				if ((int)item.StartQuality >= 3)
				{
					if (InstanceFinder.IsServer && __instance.GetOutputCapacityForOperation(item, (EQuality)4) >= item.Quantity)
					{
						__instance.TryEndOperation(__instance.DryingOperations.IndexOf(item), false, (EQuality)4, Random.Range(int.MinValue, int.MaxValue));
					}
				}
				else
				{
					item.IncreaseQuality();
				}
			}
			return false;
		}

		[HarmonyPatch(typeof(StartDryingRackBehaviour), "RpcLogic___BeginAction_2166136261")]
		[HarmonyPrefix]
		public static bool Rpc_BeginActionPrefix(StartDryingRackBehaviour __instance)
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Expected O, but got Unknown
			if (__instance.WorkInProgress)
			{
				return false;
			}
			if ((Object)(object)__instance.Rack == (Object)null)
			{
				return false;
			}
			Utils.SetProperty<StartDryingRackBehaviour>("WorkInProgress", __instance, true);
			((Behaviour)__instance).Npc.Movement.FacePoint(__instance.Rack.uiPoint.position, 0.5f);
			object obj = Utils.StartCoroutine(BeginActionCoroutine(__instance));
			Utils.SetField<StartDryingRackBehaviour>("workRoutine", __instance, (object)(Coroutine)obj);
			return false;
		}

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

		[HarmonyPatch(typeof(StartDryingRackBehaviour), "StopCauldron")]
		[HarmonyPrefix]
		public static void StopCauldronPrefix(StartDryingRackBehaviour __instance)
		{
			object field = Utils.GetField<StartDryingRackBehaviour>("workRoutine", __instance);
			if (field != null)
			{
				Utils.StopCoroutine(field);
				Utils.SetField<StartDryingRackBehaviour>("workRoutine", __instance, null);
			}
			Utils.SetProperty<StartDryingRackBehaviour>("WorkInProgress", __instance, false);
		}
	}
	[HarmonyPatch]
	public class LabOvenPatches
	{
		[CompilerGenerated]
		private sealed class <FinishCookCoroutine>d__7 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public FinishLabOvenBehaviour behaviour;

			private float <stationSpeed>5__1;

			private ItemInstance <productItem>5__2;

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

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

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

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

			private bool MoveNext()
			{
				//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ee: Expected O, but got Unknown
				//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
				//IL_0205: Expected O, but got Unknown
				//IL_0247: Unknown result type (might be due to invalid IL or missing references)
				//IL_0251: Expected O, but got Unknown
				//IL_0290: Unknown result type (might be due to invalid IL or missing references)
				//IL_029a: Expected O, but got Unknown
				//IL_0323: Unknown result type (might be due to invalid IL or missing references)
				//IL_032d: Expected O, but got Unknown
				//IL_019f: Unknown result type (might be due to invalid IL or missing references)
				//IL_01a9: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<stationSpeed>5__1 = Utils.GetStationWorkSpeed((GridItem)(object)behaviour.targetOven);
					behaviour.targetOven.SetNPCUser(((NetworkBehaviour)((Behaviour)behaviour).Npc).NetworkObject);
					((Behaviour)behaviour).Npc.Movement.FacePoint(((Component)behaviour.targetOven).transform.position, Mathf.Max(0.1f, 0.5f / <stationSpeed>5__1));
					<>2__current = (object)new WaitForSeconds(Mathf.Max(0.1f, 0.5f / <stationSpeed>5__1));
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					if (!(bool)Utils.CallMethod<FinishLabOvenBehaviour>("CanActionStart", behaviour))
					{
						Utils.CallMethod<FinishLabOvenBehaviour>("StopAction", behaviour);
						((Behaviour)behaviour).Deactivate_Networked((NetworkConnection)null);
						return false;
					}
					((Behaviour)behaviour).Npc.SetEquippable_Networked((NetworkConnection)null, "Avatar/Equippables/Hammer");
					behaviour.targetOven.Door.SetPosition(1f);
					behaviour.targetOven.WireTray.SetPosition(1f);
					<>2__current = (object)new WaitForSeconds(Mathf.Max(0.1f, 0.5f / <stationSpeed>5__1));
					<>1__state = 2;
					return true;
				case 2:
					<>1__state = -1;
					behaviour.targetOven.SquareTray.SetParent(((Component)behaviour.targetOven).transform);
					behaviour.targetOven.RemoveTrayAnimation.Play();
					<>2__current = (object)new WaitForSeconds(0.1f);
					<>1__state = 3;
					return true;
				case 3:
					<>1__state = -1;
					behaviour.targetOven.Door.SetPosition(0f);
					<>2__current = (object)new WaitForSeconds(Mathf.Max(0.1f, 1f / <stationSpeed>5__1));
					<>1__state = 4;
					return true;
				case 4:
					<>1__state = -1;
					((Behaviour)behaviour).Npc.SetAnimationBool_Networked((NetworkConnection)null, "UseHammer", true);
					<>2__current = (object)new WaitForSeconds(Mathf.Max(0.1f, 10f / <stationSpeed>5__1));
					<>1__state = 5;
					return true;
				case 5:
					<>1__state = -1;
					((Behaviour)behaviour).Npc.SetAnimationBool_Networked((NetworkConnection)null, "UseHammer", false);
					behaviour.targetOven.Shatter(behaviour.targetOven.CurrentOperation.Cookable.ProductQuantity, ((Component)behaviour.targetOven.CurrentOperation.Cookable.ProductShardPrefab).gameObject);
					<>2__current = (object)new WaitForSeconds(Mathf.Max(0.1f, 1f / <stationSpeed>5__1));
					<>1__state = 6;
					return true;
				case 6:
					<>1__state = -1;
					<productItem>5__2 = behaviour.targetOven.CurrentOperation.GetProductItem(behaviour.targetOven.CurrentOperation.Cookable.ProductQuantity * behaviour.targetOven.CurrentOperation.IngredientQuantity);
					behaviour.targetOven.OutputSlot.AddItem(<productItem>5__2, false);
					behaviour.targetOven.SendCookOperation((OvenCookOperation)null);
					Utils.CallMethod<FinishLabOvenBehaviour>("StopAction", behaviour);
					((Behaviour)behaviour).Deactivate_Networked((NetworkConnection)null);
					return false;
				}
			}

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

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

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

			private object <>2__current;

			public StartLabOvenBehaviour behaviour;

			private float <workSpeed>5__1;

			private ItemInstance <itemInstance>5__2;

			private int <num>5__3;

			private StorableItemDefinition <storableItemDef>5__4;

			private CookableModule <cookable>5__5;

			private string <productId>5__6;

			private EQuality <ingredientQuality>5__7;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<itemInstance>5__2 = null;
				<storableItemDef>5__4 = null;
				<cookable>5__5 = null;
				<productId>5__6 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_009a: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
				//IL_00dc: Expected O, but got Unknown
				//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
				//IL_01b1: Expected O, but got Unknown
				//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
				//IL_01fd: Expected O, but got Unknown
				//IL_015b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0165: Expected O, but got Unknown
				//IL_028f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0295: Invalid comparison between Unknown and I4
				//IL_02ed: Unknown result type (might be due to invalid IL or missing references)
				//IL_0332: Unknown result type (might be due to invalid IL or missing references)
				//IL_0343: Unknown result type (might be due to invalid IL or missing references)
				//IL_034d: Expected O, but got Unknown
				//IL_0310: Unknown result type (might be due to invalid IL or missing references)
				//IL_0315: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<workSpeed>5__1 = Utils.GetStationWorkSpeed((GridItem)(object)behaviour.targetOven);
					behaviour.targetOven.SetNPCUser(((NetworkBehaviour)((Behaviour)behaviour).Npc).NetworkObject);
					((Behaviour)behaviour).Npc.Movement.FacePoint(((Component)behaviour.targetOven).transform.position, Mathf.Max(0.1f, 0.5f / <workSpeed>5__1));
					<>2__current = (object)new WaitForSeconds(Mathf.Max(0.1f, 0.5f / <workSpeed>5__1));
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					if (!(bool)Utils.CallMethod<StartLabOvenBehaviour>("CanCookStart", behaviour))
					{
						Utils.CallMethod<StartLabOvenBehaviour>("StopCook", behaviour);
						((Behaviour)behaviour).Deactivate_Networked((NetworkConnection)null);
						return false;
					}
					behaviour.targetOven.Door.SetPosition(1f);
					<>2__current = (object)new WaitForSeconds(Mathf.Max(0.1f, 0.5f / <workSpeed>5__1));
					<>1__state = 2;
					return true;
				case 2:
					<>1__state = -1;
					behaviour.targetOven.WireTray.SetPosition(1f);
					<>2__current = (object)new WaitForSeconds(Mathf.Max(0.1f, 5f / <workSpeed>5__1));
					<>1__state = 3;
					return true;
				case 3:
					<>1__state = -1;
					behaviour.targetOven.Door.SetPosition(0f);
					<>2__current = (object)new WaitForSeconds(Mathf.Max(0.1f, 1f / <workSpeed>5__1));
					<>1__state = 4;
					return true;
				case 4:
					<>1__state = -1;
					<itemInstance>5__2 = behaviour.targetOven.IngredientSlot.ItemInstance;
					if (<itemInstance>5__2 == null)
					{
						Utils.CallMethod<StartLabOvenBehaviour>("StopCook", behaviour);
						((Behaviour)behaviour).Deactivate_Networked((NetworkConnection)null);
						return false;
					}
					<num>5__3 = 1;
					<storableItemDef>5__4 = Utils.CastTo<StorableItemDefinition>((Il2CppObjectBase)(object)<itemInstance>5__2.Definition);
					<cookable>5__5 = <storableItemDef>5__4.StationItem.GetModule<CookableModule>();
					if ((int)<cookable>5__5.CookType == 1)
					{
						<num>5__3 = Mathf.Min(behaviour.targetOven.IngredientSlot.Quantity, LabOven.SOLID_INGREDIENT_COOK_LIMIT);
					}
					<itemInstance>5__2.ChangeQuantity(-<num>5__3);
					<productId>5__6 = ((ItemDefinition)<cookable>5__5.Product).ID;
					<ingredientQuality>5__7 = (EQuality)2;
					if (Utils.Is<QualityItemInstance>((Il2CppObjectBase)(object)<itemInstance>5__2))
					{
						<ingredientQuality>5__7 = Utils.CastTo<QualityItemInstance>((Il2CppObjectBase)(object)<itemInstance>5__2).Quality;
					}
					behaviour.targetOven.SendCookOperation(new OvenCookOperation(<itemInstance>5__2.ID, <ingredientQuality>5__7, <num>5__3, <productId>5__6));
					Utils.CallMethod<StartLabOvenBehaviour>("StopCook", behaviour);
					((Behaviour)behaviour).Deactivate_Networked((NetworkConnection)null);
					return false;
				}
			}

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

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

		[HarmonyPatch(typeof(OvenCookOperation), "GetCookDuration")]
		[HarmonyPostfix]
		public static void GetCookDurationPostfix(OvenCookOperation __instance, ref int __result)
		{
			StorableItemDefinition ingredient = __instance.Ingredient;
			int cookTime = ingredient.StationItem.GetModule<CookableModule>().CookTime;
			float stationSpeed = Utils.Mod.GetStationSpeed("LabOven");
			int num = (int)((float)cookTime / stationSpeed);
			__result = num;
		}

		[HarmonyPatch(typeof(OvenCookOperation), "IsReady")]
		[HarmonyPostfix]
		public static void IsReadyPostfix(OvenCookOperation __instance, ref bool __result)
		{
			__result = __instance.CookProgress >= __instance.GetCookDuration();
		}

		[HarmonyPatch(typeof(LabOvenCanvas), "DoesOvenOutputHaveSpace")]
		[HarmonyPostfix]
		public static void DoesOvenOutputHaveSpacePostfix(LabOvenCanvas __instance, ref bool __result)
		{
			ItemInstance productItem = __instance.Oven.CurrentOperation.GetProductItem(1);
			int productQuantity = __instance.Oven.CurrentOperation.Cookable.ProductQuantity;
			int capacityForItem = __instance.Oven.OutputSlot.GetCapacityForItem(productItem, false);
			__result = capacityForItem >= productQuantity;
		}

		[HarmonyPatch(typeof(StartLabOvenBehaviour), "RpcLogic___StartCook_2166136261")]
		[HarmonyPrefix]
		public static bool Rpc_StartCookPrefix(StartLabOvenBehaviour __instance)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Expected O, but got Unknown
			if (Utils.GetField<StartLabOvenBehaviour>("cookRoutine", __instance) != null || (Object)(object)__instance.targetOven == (Object)null)
			{
				return false;
			}
			object obj = Utils.StartCoroutine(StartCookCoroutine(__instance));
			Utils.SetField<StartLabOvenBehaviour>("cookRoutine", __instance, (object)(Coroutine)obj);
			return false;
		}

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

		[HarmonyPatch(typeof(StartLabOvenBehaviour), "StopCook")]
		[HarmonyPrefix]
		public static void StopCookPrefix(StartLabOvenBehaviour __instance)
		{
			object field = Utils.GetField<StartLabOvenBehaviour>("cookRoutine", __instance);
			if (field != null)
			{
				Utils.StopCoroutine(field);
				Utils.SetField<StartLabOvenBehaviour>("cookRoutine", __instance, null);
			}
		}

		[HarmonyPatch(typeof(FinishLabOvenBehaviour), "RpcLogic___StartAction_2166136261")]
		[HarmonyPrefix]
		public static bool Rpc_StartFinishCookPrefix(FinishLabOvenBehaviour __instance)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			if (Utils.GetField<FinishLabOvenBehaviour>("actionRoutine", __instance) != null)
			{
				return false;
			}
			if ((Object)(object)__instance.targetOven == (Object)null)
			{
				return false;
			}
			object obj = Utils.StartCoroutine(FinishCookCoroutine(__instance));
			Utils.SetField<FinishLabOvenBehaviour>("actionRoutine", __instance, (object)(Coroutine)obj);
			return false;
		}

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

		[HarmonyPatch(typeof(FinishLabOvenBehaviour), "StopAction")]
		[HarmonyPrefix]
		public static void StopActionPrefix(FinishLabOvenBehaviour __instance)
		{
			object field = Utils.GetField<FinishLabOvenBehaviour>("actionRoutine", __instance);
			if (field != null)
			{
				Utils.StopCoroutine(field);
				Utils.SetField<FinishLabOvenBehaviour>("actionRoutine", __instance, null);
			}
		}
	}
	[HarmonyPatch]
	public class MixingStationPatches
	{
		[CompilerGenerated]
		private sealed class <StartMixCoroutine>d__8 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public StartMixingStationBehaviour behaviour;

			private float <workSpeed>5__1;

			private int <originalMixTimePerItem>5__2;

			private float <mixTimePerItem>5__3;

			private int <mixQuantity>5__4;

			private float <totalMixTime>5__5;

			private QualityItemInstance <product>5__6;

			private ItemInstance <mixer>5__7;

			private float <i>5__8;

			private MixOperation <operation>5__9;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<product>5__6 = null;
				<mixer>5__7 = null;
				<operation>5__9 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0067: Unknown result type (might be due to invalid IL or missing references)
				//IL_009f: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a9: Expected O, but got Unknown
				//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
				//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ce: Expected O, but got Unknown
				//IL_0299: Unknown result type (might be due to invalid IL or missing references)
				//IL_02af: Unknown result type (might be due to invalid IL or missing references)
				//IL_02b9: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<workSpeed>5__1 = Utils.GetStationWorkSpeed((GridItem)(object)behaviour.targetStation);
					((Behaviour)behaviour).Npc.Movement.FacePoint(((Component)behaviour.targetStation).transform.position, Mathf.Max(0.1f, 0.5f / <workSpeed>5__1));
					<>2__current = (object)new WaitForSeconds(Mathf.Max(0.1f, 0.5f / <workSpeed>5__1));
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					if (!(bool)Utils.CallMethod<StartMixingStationBehaviour>("CanCookStart", behaviour))
					{
						Utils.CallMethod<StartMixingStationBehaviour>("StopCook", behaviour);
						((Behaviour)behaviour).Deactivate_Networked((NetworkConnection)null);
						return false;
					}
					behaviour.targetStation.SetNPCUser(((NetworkBehaviour)((Behaviour)behaviour).Npc).NetworkObject);
					((Behaviour)behaviour).Npc.SetAnimationBool_Networked((NetworkConnection)null, "UseChemistryStation", true);
					<originalMixTimePerItem>5__2 = behaviour.targetStation.MixTimePerItem;
					<mixTimePerItem>5__3 = (float)<originalMixTimePerItem>5__2 / <workSpeed>5__1;
					<mixQuantity>5__4 = behaviour.targetStation.GetMixQuantity();
					<totalMixTime>5__5 = <mixTimePerItem>5__3 * (float)<mixQuantity>5__4;
					<i>5__8 = 0f;
					break;
				case 2:
					<>1__state = -1;
					<i>5__8 += Time.deltaTime;
					break;
				}
				if (<i>5__8 < <totalMixTime>5__5)
				{
					((Behaviour)behaviour).Npc.Avatar.LookController.OverrideLookTarget(behaviour.targetStation.uiPoint.position, 0, false);
					<>2__current = (object)new WaitForEndOfFrame();
					<>1__state = 2;
					return true;
				}
				<product>5__6 = Utils.CastTo<QualityItemInstance>((Il2CppObjectBase)(object)behaviour.targetStation.ProductSlot.ItemInstance);
				<mixer>5__7 = behaviour.targetStation.MixerSlot.ItemInstance;
				if (InstanceFinder.IsServer)
				{
					behaviour.targetStation.ProductSlot.ChangeQuantity(-<mixQuantity>5__4, false);
					behaviour.targetStation.MixerSlot.ChangeQuantity(-<mixQuantity>5__4, false);
					<operation>5__9 = new MixOperation(((ItemInstance)<product>5__6).ID, <product>5__6.Quality, <mixer>5__7.ID, <mixQuantity>5__4);
					behaviour.targetStation.SendMixingOperation(<operation>5__9, 0);
					<operation>5__9 = null;
				}
				Utils.CallMethod<StartMixingStationBehaviour>("StopCook", behaviour);
				((Behaviour)behaviour).Deactivate_Networked((NetworkConnection)null);
				return false;
			}

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

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

		[HarmonyPatch(typeof(MixingStation), "GetMixQuantity")]
		[HarmonyPostfix]
		public static void GetMixQuantityPostfix(MixingStation __instance, ref int __result)
		{
			Utils.AddStationCapacity((GridItem)(object)__instance, __instance.MaxMixQuantity);
			__instance.MaxMixQuantity = Utils.GetStationCapacity((GridItem)(object)__instance);
			if ((Object)(object)__instance.GetProduct() == (Object)null || (Object)(object)__instance.GetMixer() == (Object)null)
			{
				__result = 0;
				return;
			}
			__result = Mathf.Min(new int[3]
			{
				__instance.ProductSlot.Quantity,
				__instance.MixerSlot.Quantity,
				__instance.MaxMixQuantity
			});
		}

		[HarmonyPatch(typeof(MixingStation), "CanStartMix")]
		[HarmonyPostfix]
		public static void CanStartMixPostfix(MixingStation __instance, ref bool __result)
		{
			__result = __instance.GetMixQuantity() > 0 && __instance.OutputSlot.Quantity == 0;
		}

		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		[HarmonyPostfix]
		public static void IsMixingDonePostfix(MixingStation __instance, ref bool __result)
		{
			__result = __instance.CurrentMixOperation != null && __instance.CurrentMixTime >= __instance.GetMixTimeForCurrentOperation();
		}

		[HarmonyPatch(typeof(MixingStation), "GetMixTimeForCurrentOperation")]
		[HarmonyPostfix]
		public static void GetMixTimePostfix(MixingStation __instance, ref int __result)
		{
			if (__instance.CurrentMixOperation != null)
			{
				float stationSpeed = Utils.GetStationSpeed((GridItem)(object)__instance);
				int mixTimePerItem = __instance.MixTimePerItem;
				int quantity = __instance.CurrentMixOperation.Quantity;
				float num = (float)mixTimePerItem / stationSpeed;
				float num2 = num * (float)quantity;
				__result = (int)Mathf.Max(1f, num2);
			}
		}

		[HarmonyPatch(typeof(Chemist), "GetMixStationsReadyToMove")]
		[HarmonyPostfix]
		public static void GetMixStationsReadyToMovePrefix(Chemist __instance, ref List<MixingStation> __result)
		{
			List<MixingStation> val = new List<MixingStation>();
			Enumerator<MixingStation> enumerator = Utils.GetProperty<Chemist, ChemistConfiguration>("configuration", __instance).MixStations.GetEnumerator();
			while (enumerator.MoveNext())
			{
				MixingStation current = enumerator.Current;
				ItemSlot outputSlot = current.OutputSlot;
				MixingStationConfiguration property = Utils.GetProperty<MixingStation, MixingStationConfiguration>("stationConfiguration", current);
				BuildableItem selectedObject = property.Destination.SelectedObject;
				if (outputSlot.Quantity == 0 || !((Employee)__instance).MoveItemBehaviour.IsTransitRouteValid(property.DestinationRoute, outputSlot.ItemInstance.ID))
				{
					continue;
				}
				if (Utils.Is<PackagingStation>((Il2CppObjectBase)(object)selectedObject) || Utils.Is<PackagingStationMk2>((Il2CppObjectBase)(object)selectedObject))
				{
					PackagingStation val2 = Utils.CastTo<PackagingStation>((Il2CppObjectBase)(object)selectedObject);
					if (val2.ProductSlot.ItemInstance == null)
					{
						val.Add(current);
					}
					else if (val2.ProductSlot.ItemInstance.CanStackWith(outputSlot.ItemInstance, true))
					{
						int stackLimit = val2.ProductSlot.ItemInstance.StackLimit;
						if (stackLimit - val2.ProductSlot.Quantity > stackLimit / 2)
						{
							val.Add(current);
						}
					}
				}
				else
				{
					val.Add(current);
				}
			}
			__result = val;
		}

		[HarmonyPatch(typeof(StartMixingStationBehaviour), "StartCook")]
		[HarmonyPrefix]
		public static void StartCookPrefix(StartMixingStationBehaviour __instance)
		{
			if (Utils.Is<MixingStationMk2>((Il2CppObjectBase)(object)__instance.targetStation))
			{
				Utils.AddStationCapacity((GridItem)(object)__instance.targetStation, 20);
			}
			else if (Utils.Is<MixingStation>((Il2CppObjectBase)(object)__instance.targetStation))
			{
				Utils.AddStationCapacity((GridItem)(object)__instance.targetStation, 10);
			}
			__instance.targetStation.MaxMixQuantity = Utils.GetStationCapacity((GridItem)(object)__instance.targetStation);
		}

		[HarmonyPatch(typeof(MixingStation), "MinPass")]
		[HarmonyPrefix]
		public static void MinPassPrefix(MixingStation __instance)
		{
			if ((__instance.CurrentMixOperation != null || __instance.OutputSlot.Quantity > 0) && __instance.CurrentMixOperation != null)
			{
				int mixTimeForCurrentOperation = __instance.GetMixTimeForCurrentOperation();
				if (__instance.CurrentMixTime + 1 >= mixTimeForCurrentOperation && InstanceFinder.IsServer)
				{
					NetworkSingleton<VariableDatabase>.Instance.SetVariableValue("Mixing_Operations_Completed", (NetworkSingleton<VariableDatabase>.Instance.GetValue<float>("Mixing_Operations_Completed") + 1f).ToString(), true);
					__instance.MixingDone_Networked();
				}
			}
		}

		[HarmonyPatch(typeof(StartMixingStationBehaviour), "RpcLogic___StartCook_2166136261")]
		[HarmonyPrefix]
		public static bool Rpc_StartCookPrefix(StartMixingStationBehaviour __instance)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			if (Utils.GetField<StartMixingStationBehaviour>("startRoutine", __instance) != null)
			{
				return false;
			}
			if ((Object)(object)__instance.targetStation == (Object)null)
			{
				return false;
			}
			object obj = Utils.StartCoroutine(StartMixCoroutine(__instance));
			Utils.SetField<StartMixingStationBehaviour>("startRoutine", __instance, (object)(Coroutine)obj);
			return false;
		}

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

		[HarmonyPatch(typeof(StartMixingStationBehaviour), "StopCook")]
		[HarmonyPrefix]
		public static void StopCookPrefix(StartMixingStationBehaviour __instance)
		{
			object field = Utils.GetField<StartMixingStationBehaviour>("startRoutine", __instance);
			if (field != null)
			{
				Utils.StopCoroutine(field);
				Utils.SetField<StartMixingStationBehaviour>("startRoutine", __instance, null);
			}
		}

		[HarmonyPatch(typeof(MixingStationUIElement), "Initialize")]
		[HarmonyPrefix]
		public static void InitializeUIPrefix(MixingStation station)
		{
			int stationCapacity = Utils.GetStationCapacity((GridItem)(object)station);
			Utils.GetProperty<MixingStation, MixingStationConfiguration>("stationConfiguration", station).StartThrehold.Configure(1f, (float)stationCapacity, true);
			station.MaxMixQuantity = stationCapacity;
		}
	}
	[HarmonyPatch]
	public class BrickPressPatches
	{
		[CompilerGenerated]
		private sealed class <PackagingCoroutine>d__1 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public BrickPressBehaviour behaviour;

			private float <workSpeed>5__1;

			private float <originalDuration>5__2;

			private float <employeeMultiplier>5__3;

			private float <duration>5__4;

			private ProductItemInstance <product>5__5;

			private object <workRoutine>5__6;

			private float <i>5__7;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<product>5__5 = null;
				<workRoutine>5__6 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0058: Unknown result type (might be due to invalid IL or missing references)
				//IL_0062: Expected O, but got Unknown
				//IL_020f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0219: Expected O, but got Unknown
				//IL_0128: Unknown result type (might be due to invalid IL or missing references)
				//IL_0136: Unknown result type (might be due to invalid IL or missing references)
				//IL_0140: Expected O, but got Unknown
				//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
				//IL_01b7: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					Utils.AddOriginalStationTime((GridItem)(object)behaviour.Press, (int)BrickPressBehaviour.BASE_PACKAGING_TIME);
					<>2__current = (object)new WaitForEndOfFrame();
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					((Behaviour)behaviour).Npc.Avatar.Animation.SetBool("UsePackagingStation", true);
					<workSpeed>5__1 = Utils.GetStationWorkSpeed((GridItem)(object)behaviour.Press);
					<originalDuration>5__2 = Utils.GetOriginalStationTime((GridItem)(object)behaviour.Press);
					<employeeMultiplier>5__3 = Utils.CastTo<Packager>((Il2CppObjectBase)(object)((Behaviour)behaviour).Npc).PackagingSpeedMultiplier;
					<duration>5__4 = <originalDuration>5__2 / (<employeeMultiplier>5__3 * <workSpeed>5__1);
					<i>5__7 = 0f;
					goto IL_0163;
				case 2:
					<>1__state = -1;
					<i>5__7 += Time.deltaTime;
					goto IL_0163;
				case 3:
					<>1__state = -1;
					((Behaviour)behaviour).Npc.Avatar.Animation.SetTrigger("GrabItem");
					behaviour.Press.PlayPressAnim();
					<>2__current = (object)new WaitForSeconds(Mathf.Max(0.1f, 1f / <workSpeed>5__1));
					<>1__state = 4;
					return true;
				case 4:
					{
						<>1__state = -1;
						if (InstanceFinder.IsServer && behaviour.Press.HasSufficientProduct(ref <product>5__5))
						{
							behaviour.Press.CompletePress(<product>5__5);
						}
						Utils.SetProperty<BrickPressBehaviour>("PackagingInProgress", behaviour, false);
						<workRoutine>5__6 = Utils.GetField<BrickPressBehaviour>("packagingRoutine", behaviour);
						Utils.StopCoroutine(<workRoutine>5__6);
						Utils.SetField<BrickPressBehaviour>("packagingRoutine", behaviour, null);
						return false;
					}
					IL_0163:
					if (<i>5__7 < <duration>5__4)
					{
						((Behaviour)behaviour).Npc.Avatar.LookController.OverrideLookTarget(behaviour.Press.uiPoint.position, 0, false);
						<>2__current = (object)new WaitForEndOfFrame();
						<>1__state = 2;
						return true;
					}
					((Behaviour)behaviour).Npc.Avatar.Animation.SetBool("UsePackagingStation", false);
					<>2__current = (object)new WaitForSeconds(Mathf.Max(0.1f, 0.2f / <workSpeed>5__1));
					<>1__state = 3;
					return true;
				}
			}

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

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

		[HarmonyPatch(typeof(BrickPressBehaviour), "RpcLogic___BeginPackaging_2166136261")]
		[HarmonyPrefix]
		public static bool Rpc_BeginPackagingPrefix(BrickPressBehaviour __instance)
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Expected O, but got Unknown
			if (__instance.PackagingInProgress)
			{
				return false;
			}
			if ((Object)(object)__instance.Press == (Object)null)
			{
				return false;
			}
			Utils.SetProperty<BrickPressBehaviour>("PackagingInProgress", __instance, true);
			((Behaviour)__instance).Npc.Movement.FaceDirection(__instance.Press.StandPoint.forward, 0.5f);
			object obj = Utils.StartCoroutine(PackagingCoroutine(__instance));
			Utils.SetField<BrickPressBehaviour>("packagingRoutine", __instance, (object)(Coroutine)obj);
			return false;
		}

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

		[HarmonyPatch(typeof(BrickPressBehaviour), "StopPackaging")]
		[HarmonyPrefix]
		public static void StopPackagingPrefix(BrickPressBehaviour __instance)
		{
			object field = Utils.GetField<BrickPressBehaviour>("packagingRoutine", __instance);
			if (field != null)
			{
				Utils.StopCoroutine(field);
				Utils.SetField<BrickPressBehaviour>("packagingRoutine", __instance, null);
			}
			Utils.SetField<BrickPressBehaviour>("PackagingInProgress", __instance, false);
		}
	}
	[HarmonyPatch]
	public class CauldronPatches
	{
		[CompilerGenerated]
		private sealed class <BeginCauldronCoroutine>d__4 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public StartCauldronBehaviour behaviour;

			private float <stationSpeed>5__1;

			private float <originalWorkTime>5__2;

			private float <workSpeed>5__3;

			private float <workTime>5__4;

			private object <workRoutine>5__5;

			private float <i>5__6;

			private EQuality <quality>5__7;

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

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

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

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

			private bool MoveNext()
			{
				//IL_002f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0039: Expected O, but got Unknown
				//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
				//IL_0109: Expected O, but got Unknown
				//IL_0175: Unknown result type (might be due to invalid IL or missing references)
				//IL_017a: Unknown result type (might be due to invalid IL or missing references)
				//IL_019c: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForEndOfFrame();
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					((Behaviour)behaviour).Npc.Avatar.Animation.SetBool("UseChemistryStation", true);
					<stationSpeed>5__1 = Utils.GetStationWorkSpeed((GridItem)(object)behaviour.Station);
					<originalWorkTime>5__2 = StartCauldronBehaviour.START_CAULDRON_TIME;
					<workSpeed>5__3 = Utils.GetStationWorkSpeed((GridItem)(object)behaviour.Station);
					<workTime>5__4 = Mathf.Max(0.1f, <originalWorkTime>5__2 / <workSpeed>5__3);
					<i>5__6 = 0f;
					break;
				case 2:
					<>1__state = -1;
					<i>5__6 += Time.deltaTime;
					break;
				}
				if (<i>5__6 < <workTime>5__4)
				{
					((Behaviour)behaviour).Npc.Avatar.LookController.OverrideLookTarget(behaviour.Station.LinkOrigin.position, 0, false);
					<>2__current = (object)new WaitForEndOfFrame();
					<>1__state = 2;
					return true;
				}
				((Behaviour)behaviour).Npc.Avatar.Animation.SetBool("UseChemistryStation", false);
				if (InstanceFinder.IsServer)
				{
					<quality>5__7 = behaviour.Station.RemoveIngredients();
					behaviour.Station.StartCookOperation((NetworkConnection)null, behaviour.Station.CookTime, <quality>5__7);
				}
				Utils.SetProperty<StartCauldronBehaviour>("WorkInProgress", behaviour, false);
				<workRoutine>5__5 = Utils.GetField<StartCauldronBehaviour>("workRoutine", behaviour);
				Utils.StopCoroutine(<workRoutine>5__5);
				Utils.SetField<StartCauldronBehaviour>("workRoutine", behaviour, null);
				return false;
			}

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

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

		[HarmonyPatch(typeof(Cauldron), "StartCookOperation")]
		[HarmonyPrefix]
		public static void StartCookOperationPrefix(Cauldron __instance, ref int remainingCookTime)
		{
			Utils.AddOriginalStationTime((GridItem)(object)__instance, 360);
			int originalStationTime = Utils.GetOriginalStationTime((GridItem)(object)__instance);
			float stationSpeed = Utils.GetStationSpeed((GridItem)(object)__instance);
			int num2 = (__instance.CookTime = (int)Mathf.Max((float)originalStationTime / stationSpeed, 1f));
			remainingCookTime = num2;
		}

		[HarmonyPatch(typeof(Cauldron), "HasOutputSpace")]
		[HarmonyPostfix]
		public static void HasOutputSpacePostfix(Cauldron __instance, ref bool __result)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			QualityItemInstance val = Utils.CastTo<QualityItemInstance>((Il2CppObjectBase)(object)((ItemDefinition)__instance.CocaineBaseDefinition).GetDefaultInstance(1));
			val.Quality = __instance.InputQuality;
			__result = __instance.OutputSlot.GetCapacityForItem((ItemInstance)(object)val, false) >= 10;
		}

		[HarmonyPatch(typeof(Cauldron), "GetState")]
		[HarmonyPostfix]
		public static void GetStatePostfix(Cauldron __instance, ref EState __result)
		{
			if ((bool)Utils.GetProperty<Cauldron>("isCooking", __instance))
			{
				__result = (EState)2;
			}
			else if (!__instance.HasIngredients())
			{
				__result = (EState)0;
			}
			else if (!__instance.HasOutputSpace())
			{
				__result = (EState)3;
			}
			else
			{
				__result = (EState)1;
			}
		}

		[HarmonyPatch(typeof(StartCauldronBehaviour), "RpcLogic___BeginCauldron_2166136261")]
		[HarmonyPrefix]
		public static bool Rpc_BeginCauldronPrefix(StartCauldronBehaviour __instance)
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Expected O, but got Unknown
			if (__instance.WorkInProgress)
			{
				return false;
			}
			if ((Object)(object)__instance.Station == (Object)null)
			{
				return false;
			}
			Utils.SetProperty<StartCauldronBehaviour>("WorkInProgress", __instance, true);
			((Behaviour)__instance).Npc.Movement.FaceDirection(__instance.Station.StandPoint.forward, 0.5f);
			object obj = Utils.StartCoroutine(BeginCauldronCoroutine(__instance));
			Utils.SetField<StartCauldronBehaviour>("workRoutine", __instance, (object)(Coroutine)obj);
			return false;
		}

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

		[HarmonyPatch(typeof(StartCauldronBehaviour), "StopCauldron")]
		[HarmonyPrefix]
		public static void StopCauldronPrefix(StartCauldronBehaviour __instance)
		{
			object field = Utils.GetField<StartCauldronBehaviour>("workRoutine", __instance);
			if (field != null)
			{
				Utils.StopCoroutine(field);
				Utils.SetField<StartCauldronBehaviour>("workRoutine", __instance, null);
			}
		}
	}
	[HarmonyPatch]
	public class PackagingStationPatches
	{
		[CompilerGenerated]
		private sealed class <BeginPackagingCoroutine>d__1 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public PackagingStationBehaviour behaviour;

			private ProductItemInstance <packagedInstance>5__1;

			private PackagingDefinition <packagingDefinition>5__2;

			private float <workSpeed>5__3;

			private int <outputSpace>5__4;

			private int <productPerPackage>5__5;

			private int <productQuantity>5__6;

			private int <packagingQuantity>5__7;

			private int <numPackages>5__8;

			private int <numBatchPackages>5__9;

			private object <workRoutine>5__10;

			private float <basePackagingTime>5__11;

			private float <employeeMultiplier>5__12;

			private float <stationMultiplier>5__13;

			private float <packageTime>5__14;

			private float <i>5__15;

			private float <value>5__16;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<packagedInstance>5__1 = null;
				<packagingDefinition>5__2 = null;
				<workRoutine>5__10 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_002f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0039: Expected O, but got Unknown
				//IL_023a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0248: Unknown result type (might be due to invalid IL or missing references)
				//IL_0252: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForEndOfFrame();
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					((Behaviour)behaviour).Npc.Avatar.Animation.SetBool("UsePackagingStation", true);
					<packagedInstance>5__1 = Utils.CastTo<ProductItemInstance>((Il2CppObjectBase)(object)behaviour.Station.ProductSlot.ItemInstance.GetCopy(-1));
					<packagingDefinition>5__2 = Utils.CastTo<PackagingDefinition>((Il2CppObjectBase)(object)behaviour.Station.PackagingSlot.ItemInstance.Definition);
					<packagedInstance>5__1.SetPackaging(<packagingDefinition>5__2);
					<workSpeed>5__3 = Utils.GetStationWorkSpeed((GridItem)(object)behaviour.Station);
					<outputSpace>5__4 = behaviour.Station.OutputSlot.GetCapacityForItem((ItemInstance)(object)<packagedInstance>5__1, false);
					<productPerPackage>5__5 = <packagingDefinition>5__2.Quantity;
					<productQuantity>5__6 = behaviour.Station.ProductSlot.Quantity;
					<packagingQuantity>5__7 = behaviour.Station.PackagingSlot.Quantity;
					<numPackages>5__8 = Mathf.Min(new int[3]
					{
						<packagingQuantity>5__7,
						<productQuantity>5__6 / <productPerPackage>5__5,
						<outputSpace>5__4
					});
					<numBatchPackages>5__9 = <numPackages>5__8 - 1;
					if (<numPackages>5__8 <= 0)
					{
						break;
					}
					<basePackagingTime>5__11 = PackagingStationBehaviour.BASE_PACKAGING_TIME;
					<employeeMultiplier>5__12 = Utils.CastTo<Packager>((Il2CppObjectBase)(object)((Behaviour)behaviour).Npc).PackagingSpeedMultiplier;
					<stationMultiplier>5__13 = behaviour.Station.PackagerEmployeeSpeedMultiplier;
					<packageTime>5__14 = Mathf.Max(0.1f, (float)<numPackages>5__8 * <basePackagingTime>5__11 / (<stationMultiplier>5__13 * <employeeMultiplier>5__12 * <workSpeed>5__3));
					<i>5__15 = 0f;
					goto IL_0275;
				case 2:
					{
						<>1__state = -1;
						<i>5__15 += Time.deltaTime;
						goto IL_0275;
					}
					IL_0275:
					if (<i>5__15 < <packageTime>5__14)
					{
						((Behaviour)behaviour).Npc.Avatar.LookController.OverrideLookTarget(behaviour.Station.Container.position, 0, false);
						<>2__current = (object)new WaitForEndOfFrame();
						<>1__state = 2;
						return true;
					}
					if (!InstanceFinder.IsServer)
					{
						break;
					}
					if (<numBatchPackages>5__9 > 0)
					{
						<value>5__16 = NetworkSingleton<VariableDatabase>.Instance.GetValue<float>("PackagedProductCount");
						NetworkSingleton<VariableDatabase>.Instance.SetVariableValue("PackagedProductCount", (<value>5__16 + (float)(<numBatchPackages>5__9 * <productPerPackage>5__5)).ToString(), true);
						if (behaviour.Station.OutputSlot.ItemInstance == null)
						{
							behaviour.Station.OutputSlot.SetStoredItem((ItemInstance)(object)<packagedInstance>5__1, false);
							behaviour.Station.OutputSlot.SetQuantity(<numBatchPackages>5__9, false);
						}
						else
						{
							behaviour.Station.OutputSlot.ChangeQuantity(<numBatchPackages>5__9, false);
						}
						behaviour.Station.PackagingSlot.ChangeQuantity(-<numBatchPackages>5__9, false);
						behaviour.Station.ProductSlot.ChangeQuantity(-<numBatchPackages>5__9 * <productPerPackage>5__5, false);
					}
					behaviour.Station.PackSingleInstance();
					break;
				}
				((Behaviour)behaviour).Npc.Avatar.Animation.SetBool("UsePackagingStation", false);
				Utils.SetProperty<PackagingStationBehaviour>("PackagingInProgress", behaviour, false);
				<workRoutine>5__10 = Utils.GetField<PackagingStationBehaviour>("packagingRoutine", behaviour);
				Utils.StopCoroutine(<workRoutine>5__10);
				Utils.SetField<PackagingStationBehaviour>("packagingRoutine", behaviour, null);
				return false;
			}

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

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

		[HarmonyPatch(typeof(PackagingStationBehaviour), "RpcLogic___BeginPackaging_2166136261")]
		[HarmonyPrefix]
		public static bool RpcLogic_BeginPackagingPrefix(PackagingStationBehaviour __instance)
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Expected O, but got Unknown
			if (__instance.PackagingInProgress || (Object)(object)__instance.Station == (Object)null)
			{
				return false;
			}
			Utils.SetProperty<PackagingStationBehaviour>("PackagingInProgress", __instance, true);
			((Behaviour)__instance).Npc.Movement.FaceDirection(__instance.Station.StandPoint.forward, 0.5f);
			object obj = Utils.StartCoroutine(BeginPackagingCoroutine(__instance));
			Utils.SetField<PackagingStationBehaviour>("packagingRoutine", __instance, (object)(Coroutine)obj);
			return false;
		}

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

		[HarmonyPatch(typeof(PackagingStationBehaviour), "StopPackaging")]
		[HarmonyPrefix]
		public static void StopPackagingPrefix(PackagingStationBehaviour __instance)
		{
			object field = Utils.GetField<PackagingStationBehaviour>("packagingRoutine", __instance);
			if (field != null)
			{
				Utils.StopCoroutine(field);
				Utils.SetField<PackagingStationBehaviour>("packagingRoutine", __instance, null);
			}
		}
	}
	[HarmonyPatch]
	public class GrowablePatches
	{
		[HarmonyPatch(typeof(Plant), "MinPass")]
		[HarmonyPostfix]
		public static void MinPassPostfix(Plant __instance, int mins)
		{
			if (!NetworkSingleton<TimeManager>.Instance.IsEndOfDay || Utils.Mod.plantsAlwaysGrowPresent)
			{
				float num = 1f / ((float)__instance.GrowthTime * 60f) * (float)mins;
				num *= ((GrowContainer)__instance.Pot).GetTemperatureGrowthMultiplier();
				num *= GetAverageLightExposure((GrowContainer)(object)__instance.Pot, out var growSpeedMultiplier);
				num *= __instance.Pot.GrowSpeedMultiplier;
				num *= growSpeedMultiplier;
				if (GameManager.IS_TUTORIAL)
				{
					num *= 0.3f;
				}
				if (((GrowContainer)__instance.Pot).NormalizedMoistureAmount <= 0f)
				{
					num *= 0f;
				}
				float stationSpeed = Utils.Mod.GetStationSpeed("MushroomBed");
				__instance.SetNormalizedGrowthProgress(__instance.NormalizedGrowthProgress + num * (stationSpeed - 1f));
			}
		}

		private static float GetAverageLightExposure(GrowContainer container, out float growSpeedMultiplier)
		{
			growSpeedMultiplier = 1f;
			UsableLightSource field = Utils.GetField<GrowContainer, UsableLightSource>("_lightSourceOverride", container);
			if ((Object)(object)field != (Object)null)
			{
				return field.GrowSpeedMultiplier;
			}
			float num = 0f;
			float num2 = default(float);
			for (int i = 0; i < ((GridItem)container).CoordinatePairs.Count; i++)
			{
				num += ((GridItem)container).OwnerGrid.GetTile(((GridItem)container).CoordinatePairs[i].coord2).LightExposureNode.GetTotalExposure(ref num2);
				growSpeedMultiplier += num2;
			}
			growSpeedMultiplier /= ((GridItem)container).CoordinatePairs.Count;
			return num / (float)((GridItem)container).CoordinatePairs.Count;
		}

		[HarmonyPatch(typeof(ShroomColony), "OnMinPass")]
		[HarmonyPostfix]
		public static void OnMinPassPostfix(ShroomColony __instance)
		{
			if (!NetworkSingleton<TimeManager>.Instance.IsEndOfDay || Utils.Mod.plantsAlwaysGrowPresent)
			{
				float num = (float)Utils.CallMethod<ShroomColony>("GetCurrentGrowthRate", __instance) * Utils.Mod.GetStationSpeed("MushroomBed");
				int num2 = (int)Utils.GetField<ShroomColony>("_growTime", __instance);
				float num3 = num / ((float)num2 * 60f);
				Utils.CallMethod<ShroomColony>("ChangeGrowthPercentage", __instance, new object[1] { num3 });
			}
		}
	}
	[HarmonyPatch]
	public class SpawnStationPatches
	{
		[CompilerGenerated]
		private sealed class <SpawnStationCoroutine>d__1 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public UseSpawnStationBehaviour behaviour;

			private float <originalDuration>5__1;

			private float <workSpeed>5__2;

			private float <progress>5__3;

			private float <duration>5__4;

			private SporeSyringeDefinition <sporeSyringeDefinition>5__5;

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

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

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

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

			private bool MoveNext()
			{
				//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<originalDuration>5__1 = (float)Utils.GetField<UseSpawnStationBehaviour>("TaskDuration", behaviour);
					<workSpeed>5__2 = Utils.GetStationWorkSpeed((GridItem)(object)behaviour.Station);
					<progress>5__3 = 0f;
					<duration>5__4 = Mathf.Max(0.1f, <originalDuration>5__1 / <workSpeed>5__2);
					((Behaviour)behaviour).Npc.SetAnimationBool("UsePackagingStation", true);
					break;
				case 1:
					<>1__state = -1;
					break;
				}
				if (<progress>5__3 < <duration>5__4)
				{
					<progress>5__3 += Time.deltaTime;
					((Behaviour)behaviour).Npc.Avatar.LookController.OverrideLookTarget(behaviour.Station.UIPoint.position, 0, true);
					<>2__current = null;
					<>1__state = 1;
					return true;
				}
				if (InstanceFinder.IsServer && (Object)(object)behaviour.Station != (Object)null && behaviour.Station.DoesStationContainRequiredItems() && behaviour.Station.DoesStationHaveOutputSpace())
				{
					<sporeSyringeDefinition>5__5 = Utils.CastTo<SporeSyringeDefinition>((Il2CppObjectBase)(object)behaviour.Station.SyringeSlot.ItemInstance.Definition);
					behaviour.Station.SyringeSlot.ChangeQuantity(-1, false);
					behaviour.Station.GrainBagSlot.ChangeQuantity(-1, false);
					behaviour.Station.OutputSlot.AddItem(((ItemDefinition)<sporeSyringeDefinition>5__5.SpawnDefinition).GetDefaultInstance(1), false);
					<sporeSyringeDefinition>5__5 = null;
				}
				Utils.CallMethod<UseSpawnStationBehaviour>("StopWork", behaviour);
				((Behaviour)behaviour).Disable_Networked((NetworkConnection)null);
				return false;
			}

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

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

		[HarmonyPatch(typeof(UseSpawnStationBehaviour), "RpcLogic___BeginWork_2166136261")]
		[HarmonyPrefix]
		public static bool RpcLogicBeginWorkPrefix(UseSpawnStationBehaviour __instance)
		{
			if ((bool)Utils.GetField<UseSpawnStationBehaviour>("_currentlyUsingStation", __instance))
			{
				return false;
			}
			if (!__instance.IsStationReady(__instance.Station))
			{
				return false;
			}
			Utils.SetField<UseSpawnStationBehaviour>("_currentlyUsingStation", __instance, true);
			if (InstanceFinder.IsServer)
			{
				__instance.Station.SetNPCUser(((NetworkBehaviour)((Behaviour)__instance).Npc).NetworkObject);
			}
			object value = Utils.StartCoroutine(SpawnStationCoroutine(__instance));
			Utils.SetField<UseSpawnStationBehaviour>("_workRoutine", __instance, value);
			return false;
		}

		[IteratorStateMachine(typeof(<SpawnStationCoroutine>d__1))]
		public static IEnumerator SpawnStationCoroutine(UseSpawnStationBehaviour behaviour)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <SpawnStationCoroutine>d__1(0)
			{
				behaviour = behaviour
			};
		}

		[HarmonyPatch(typeof(UseSpawnStationBehaviour), "StopWork")]
		[HarmonyPrefix]
		public static void StopWorkPrefix(UseSpawnStationBehaviour __instance)
		{
			object field = Utils.GetField<UseSpawnStationBehaviour>("_workRoutine", __instance);
			Utils.StopCoroutine(field);
			Utils.SetField<UseSpawnStationBehaviour>("_workRoutine", __instance, null);
		}
	}
	[HarmonyPatch]
	public class GrowContainerPatches
	{
		private enum EState
		{
			Idle,
			Walking,
			GrabbingSupplies,
			PerformingAction
		}

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

			private object <>2__current;

			public GrowContainerBehaviour behaviour;

			private GrowContainer <growContainer>5__1;

			private float <workSpeed>5__2;

			private float <waitTime>5__3;

			private Vector3 <targetPosition>5__4;

			private object[] <args>5__5;

			private bool <taskRequiresItem>5__6;

			private Il2CppStringArray <suitableItemIDs>5__7;

			private ItemSlot <itemSlot>5__8;

			private ItemInstance <usedItem>5__9;

			private object <workRoutine>5__10;

			private float <i>5__11;

			private Botanist <botanist>5__12;

			private IItemSlotOwner <slotOwner>5__13;

			private TrashItem <trashPrefab>5__14;

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

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

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

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<growContainer>5__1 = null;
				<args>5__5 = null;
				<suitableItemIDs>5__7 = null;
				<itemSlot>5__8 = null;
				<usedItem>5__9 = null;
				<workRoutine>5__10 = null;
				<botanist>5__12 = null;
				<slotOwner>5__13 = null;
				<trashPrefab>5__14 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0084: Unknown result type (might be due to invalid IL or missing references)
				//IL_0089: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ca: Expected O, but got Unknown
				//IL_0177: Unknown result type (might be due to invalid IL or missing references)
				//IL_0181: Expected O, but got Unknown
				//IL_02f3: Unknown result type (might be due to invalid IL or missing references)
				//IL_02f8: Unknown result type (might be due to invalid IL or missing references)
				//IL_0302: Unknown result type (might be due to invalid IL or missing references)
				//IL_0307: Unknown result type (might be due to invalid IL or missing references)
				//IL_030c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0313: Unknown result type (might be due to invalid IL or missing references)
				//IL_0319: Unknown result type (might be due to invalid IL or missing references)
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					Utils.CallMethod<GrowContainerBehaviour>("OnStartPerformAction", behaviour);
					<growContainer>5__1 = Utils.GetProperty<GrowContainerBehaviour, GrowContainer>("_growContainer", behaviour);
					<workSpeed>5__2 = Utils.GetStationWorkSpeed((GridItem)(object)<growContainer>5__1);
					<waitTime>5__3 = GetActionDuration(behaviour) / <workSpeed>5__2;
					<targetPosition>5__4 = (Vector3)Utils.CallMethod<GrowContainerBehaviour>("GetGrowContainerLookPoint", behaviour);
					<i>5__11 = 0f;
					break;
				case 1:
					<>1__state = -1;
					<i>5__11 += Time.deltaTime;
					break;
				}
				if (<i>5__11 < <waitTime>5__3)
				{
					((Behaviour)behaviour).Npc.Avatar.LookController.OverrideLookTarget(<targetPosition>5__4, 0, false);
					<>2__current = (object)new WaitForEndOfFrame();
					<>1__state = 1;
					return true;
				}
				if (!behaviour.AreTaskConditionsMetForContainer(<growContainer>5__1))
				{
					((Behaviour)behaviour).Disable_Networked((NetworkConnection)null);
					return false;
				}
				Utils.CallMethod<GrowContainerBehaviour>("OnStopPerformAction", behaviour);
				<args>5__5 = new object[2] { <growContainer>5__1, null };
				<taskRequiresItem>5__6 = (bool)Utils.CallMethod<GrowContainerBehaviour>("DoesTaskRequireItem", behaviour, <args>5__5);
				<suitableItemIDs>5__7 = (Il2CppStringArray)<args>5__5[1];
				<itemSlot>5__8 = null;
				if (<taskRequiresItem>5__6)
				{
					<botanist>5__12 = Utils.GetProperty<GrowContainerBehaviour, Botanist>("_botanist", behaviour);
					<slotOwner>5__13 = Utils.ToInterface<IItemSlotOwner>((Il2CppObjectBase)(object)((NPC)<botanist>5__12).Inventory);
					<itemSlot>5__8 = Utils.CallMethod<GrowContainerBehaviour, ItemSlot>("GetItemSlotContainingRequiredItem", behaviour, new object[2] { <slotOwner>5__13, <suitableItemIDs>5__7 });
					<botanist>5__12 = null;
					<slotOwner>5__13 = null;
				}
				<usedItem>5__9 = ((<itemSlot>5__8 != null) ? <itemSlot>5__8.ItemInstance.GetCopy(1) : null);
				if ((bool)Utils.CallMethod<GrowContainerBehaviour>("CheckSuccess", behaviour, new object[1] { <usedItem>5__9 }))
				{
					Utils.CallMethod<GrowContainerBehaviour>("OnActionSuccess", behaviour, new object[1] { <usedItem>5__9 });
					if (<itemSlot>5__8 != null && <itemSlot>5__8.Quantity > 0)
					{
						<itemSlot>5__8.ChangeQuantity(-1, false);
					}
					<trashPrefab>5__14 = Utils.CallMethod<GrowContainerBehaviour, TrashItem>("GetTrashPrefab", behaviour, new object[1] { <usedItem>5__9 });
					if ((Object)(object)<trashPrefab>5__14 != (Object)null)
					{
						NetworkSingleton<TrashManager>.Instance.CreateTrashItem(<trashPrefab>5__14.ID, ((Component)((Behaviour)behaviour).Npc).transform.position + Vector3.up * 0.3f, Random.rotation, default(Vector3), "", false);
					}
					<trashPrefab>5__14 = null;
				}
				<workRoutine>5__10 = Utils.GetField<GrowContainerBehaviour>("_performActionRoutine", behaviour);
				Utils.StopCoroutine(<workRoutine>5__10);
				Utils.SetField<GrowContainerBehaviour>("_performActionRoutine", behaviour, null);
				((Behaviour)behaviour).Disable_Networked((NetworkConnection)null);
				return false;
			}

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

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

		private static Dictionary<Type, float> behaviourDurations = new Dictionary<Type, float>
		{
			{
				typeof(AddSoilToGrowContainerBehaviour),
				15f
			},
			{
				typeof(ApplyAdditiveToGrowContainerBehaviour),
				10f
			},
			{
				typeof(HarvestPotBehaviour),
				10f
			},
			{
				typeof(SowSeedInPotBehaviour),
				10f
			},
			{
				typeof(WaterPotBehaviour),
				10f
			},
			{
				typeof(ApplySpawnToMushroomBedBehaviour),
				15f
			},
			{
				typeof(HarvestMushroomBedBehaviour),
				10f
			},
			{
				typeof(MistMushroomBedBehaviour),
				10f
			}
		};

		private static List<Type> harvestBehaviours = new List<Type>
		{
			typeof(HarvestPotBehaviour),
			typeof(HarvestMushroomBedBehaviour)
		};

		private static void PerformAction(GrowContainerBehaviour __instance)
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Expected O, but got Unknown
			if (!__instance.AreTaskConditionsMetForContainer(Utils.GetProperty<GrowContainerBehaviour, GrowContainer>("_growContainer", __instance)))
			{
				((Behaviour)__instance).Disable_Networked((NetworkConnection)null);
				return;
			}
			Utils.SetProperty<GrowContainerBehaviour>("_currentState", __instance, 3);
			object obj = Utils.StartCoroutine(PerformActionCoroutine(__instance));
			Utils.SetField<GrowContainerBehaviour>("_performActionRoutine", __instance, (object)(Coroutine)obj);
		}

		private static float GetActionDuration(GrowContainerBehaviour behaviour)
		{
			Type type = Utils.GetType((Il2CppObjectBase)(object)behaviour);
			if (harvestBehaviours.Contains(type))
			{
				return Botanist.IndividualHarvestTime * (float)GetQuantityToHarvest(behaviour);
			}
			if (behaviourDurations.ContainsKey(type))
			{
				return behaviourDurations[type];
			}
			Utils.Warn($"Couldn't find action duration for behaviour \"{((Object)behaviour).name}\" ({type.Name})");
			return 10f;
		}

		private static int GetQuantityToHarvest(GrowContainerBehaviour behaviour)
		{
			if (Utils.Is<HarvestPotBehaviour>((Il2CppObjectBase)(object)behaviour))
			{
				HarvestPotBehaviour target = Utils.CastTo<HarvestPotBehaviour>((Il2CppObjectBase)(object)behaviour);
				return (int)Utils.CallMethod<HarvestPotBehaviour>("GetQuantityToHarvest", target);
			}
			if (Utils.Is<HarvestMushroomBedBehaviour>((Il2CppObjectBase)(object)behaviour))
			{
				HarvestMushroomBedBehaviour target2 = Utils.CastTo<HarvestMushroomBedBehaviour>((Il2CppObjectBase)(object)behaviour);
				return (int)Utils.C