Decompiled source of SuperGrow v1.3.4

SuperGrow_Il2Cpp.dll

Decompiled 15 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppScheduleOne;
using Il2CppScheduleOne.Core.Items.Framework;
using Il2CppScheduleOne.DevUtilities;
using Il2CppScheduleOne.Equipping;
using Il2CppScheduleOne.Growing;
using Il2CppScheduleOne.ItemFramework;
using Il2CppScheduleOne.ObjectScripts;
using Il2CppScheduleOne.PlayerScripts;
using Il2CppScheduleOne.PlayerTasks;
using Il2CppScheduleOne.PlayerTasks.Tasks;
using Il2CppScheduleOne.StationFramework;
using Il2CppScheduleOne.Storage;
using Il2CppScheduleOne.Trash;
using Il2CppScheduleOne.UI.Stations;
using Il2CppSystem.Collections.Generic;
using Il2CppTMPro;
using MelonLoader;
using MelonLoader.Preferences;
using Microsoft.CodeAnalysis;
using SuperGrow;
using SuperGrow.Features;
using SuperGrow.Patches;
using SuperGrow.Utils;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: MelonInfo(typeof(Core), "SuperGrow", "1.3.4", "HazDS", null)]
[assembly: MelonGame("TVGS", "Schedule I")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("SuperGrow_Il2Cpp")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+22bbaa0cd7f8c88418ee8cc3f9785971198326d8")]
[assembly: AssemblyProduct("SuperGrow_Il2Cpp")]
[assembly: AssemblyTitle("SuperGrow_Il2Cpp")]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace SuperGrow
{
	internal static class SuperGrowSettings
	{
		private static bool _initialized;

		private static MelonPreferences_Category? _prefsCategory;

		public static MelonPreferences_Entry<int> PgrRequired { get; private set; }

		public static MelonPreferences_Entry<int> SpeedGrowRequired { get; private set; }

		public static MelonPreferences_Entry<int> FertilizerRequired { get; private set; }

		public static MelonPreferences_Entry<int> OutputQuantity { get; private set; }

		public static MelonPreferences_Entry<int> CookTimeMinutes { get; private set; }

		public static MelonPreferences_Entry<float> YieldMultiplier { get; private set; }

		public static MelonPreferences_Entry<float> InstantGrowth { get; private set; }

		public static MelonPreferences_Entry<float> QualityChange { get; private set; }

		public static void Initialize()
		{
			if (!_initialized)
			{
				_prefsCategory = MelonPreferences.CreateCategory("SuperGrow", "SuperGrow Settings");
				PgrRequired = _prefsCategory.CreateEntry<int>("PgrRequired", 1, "PGR Required", "Amount of PGR needed per craft", false, false, (ValueValidator)null, (string)null);
				SpeedGrowRequired = _prefsCategory.CreateEntry<int>("SpeedGrowRequired", 1, "Speed Grow Required", "Amount of Speed Grow needed per craft", false, false, (ValueValidator)null, (string)null);
				FertilizerRequired = _prefsCategory.CreateEntry<int>("FertilizerRequired", 1, "Fertilizer Required", "Amount of Fertilizer needed per craft", false, false, (ValueValidator)null, (string)null);
				OutputQuantity = _prefsCategory.CreateEntry<int>("OutputQuantity", 3, "Output Quantity", "Amount of SuperGrow produced per craft", false, false, (ValueValidator)null, (string)null);
				CookTimeMinutes = _prefsCategory.CreateEntry<int>("CookTimeMinutes", 30, "Cook Time (Minutes)", "Chemistry Station cook time in in-game minutes", false, false, (ValueValidator)null, (string)null);
				YieldMultiplier = _prefsCategory.CreateEntry<float>("YieldMultiplier", 1.5f, "Yield Multiplier", "Yield multiplier applied to plants (1.5 = 50% more yield)", false, false, (ValueValidator)null, (string)null);
				InstantGrowth = _prefsCategory.CreateEntry<float>("InstantGrowth", 0.5f, "Instant Growth", "Instant growth progress (0.5 = 50% instant growth)", false, false, (ValueValidator)null, (string)null);
				QualityChange = _prefsCategory.CreateEntry<float>("QualityChange", 1f, "Quality Change", "Quality modifier applied to plants", false, false, (ValueValidator)null, (string)null);
				Clamp(PgrRequired, 1, 10);
				Clamp(SpeedGrowRequired, 1, 10);
				Clamp(FertilizerRequired, 1, 10);
				Clamp(OutputQuantity, 1, 10);
				Clamp(CookTimeMinutes, 1, 240);
				Clamp(YieldMultiplier, 0.1f, 10f);
				Clamp(InstantGrowth, 0f, 1f);
				Clamp(QualityChange, -1f, 1f);
				_initialized = true;
			}
		}

		private static void Clamp(MelonPreferences_Entry<int> entry, int min, int max)
		{
			if (entry.Value < min)
			{
				entry.Value = min;
			}
			if (entry.Value > max)
			{
				entry.Value = max;
			}
		}

		private static void Clamp(MelonPreferences_Entry<float> entry, float min, float max)
		{
			if (entry.Value < min)
			{
				entry.Value = min;
			}
			if (entry.Value > max)
			{
				entry.Value = max;
			}
		}
	}
	public class Core : MelonMod
	{
		private bool _itemsInitialized;

		private int _nextInitAttemptTick;

		private const int InitAttemptIntervalMs = 250;

		public static Core Instance { get; private set; }

		public override void OnInitializeMelon()
		{
			Instance = this;
			SuperGrowSettings.Initialize();
			MelonLogger.Msg("[SuperGrow v1.3.4] Initialized.");
		}

		public override void OnSceneWasLoaded(int buildIndex, string sceneName)
		{
			if (sceneName == "Menu")
			{
				_itemsInitialized = false;
				_nextInitAttemptTick = 0;
				ChemistryStationPatches.Reset();
			}
		}

		public override void OnUpdate()
		{
			ChemistryStationPatches.DumpStationItemInitializePatchesOnce("OnUpdate");
			if (_itemsInitialized && (Object)(object)Registry.GetItem("supergrow") != (Object)null)
			{
				return;
			}
			if ((Object)(object)Registry.GetItem("supergrow") != (Object)null)
			{
				ChemistryStationPatches.EnsureAdditiveStationItemPrefabs();
				_itemsInitialized = true;
			}
			else if (ShouldAttemptInitNow())
			{
				_itemsInitialized = false;
				if (SuperGrowWorldState.IsRegistryReady())
				{
					SuperGrowCreator.CreateSuperGrowItem();
					ChemistryStationPatches.EnsureAdditiveStationItemPrefabs();
					_itemsInitialized = (Object)(object)Registry.GetItem("supergrow") != (Object)null;
				}
			}
		}

		private bool ShouldAttemptInitNow()
		{
			int tickCount = Environment.TickCount;
			if (tickCount - _nextInitAttemptTick < 0)
			{
				return false;
			}
			_nextInitAttemptTick = tickCount + 250;
			return true;
		}
	}
	internal static class SuperGrowAssets
	{
		private const string IconResourceName = "SuperGrow.Assets.SuperGrow_Icon.png";

		private const string LabelResourceName = "SuperGrow.Assets.SuperGrow_Label.png";

		private static Sprite? _icon;

		private static Texture2D? _labelTexture;

		private static bool _loggedIconLoadException;

		private static bool _loggedLabelLoadException;

		private static bool _loggedImageLoadException;

		public static Sprite? GetIconSprite()
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Expected O, but got Unknown
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_icon != (Object)null)
			{
				return _icon;
			}
			try
			{
				byte[] array = LoadEmbeddedResourceBytes("SuperGrow.Assets.SuperGrow_Icon.png");
				if (array == null)
				{
					return null;
				}
				Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
				if (!TryLoadImage(val, array))
				{
					MelonLogger.Warning("Failed to decode SuperGrow.Assets.SuperGrow_Icon.png");
					return null;
				}
				((Object)val).name = "SuperGrow_Icon";
				_icon = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f);
				return _icon;
			}
			catch (Exception ex)
			{
				if (!_loggedIconLoadException)
				{
					_loggedIconLoadException = true;
					MelonLogger.Warning("Failed to load icon: " + ex.Message);
					MelonLogger.Warning(ex.StackTrace ?? "<no stack trace>");
				}
				return null;
			}
		}

		public static Texture2D? GetLabelTexture()
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Expected O, but got Unknown
			if ((Object)(object)_labelTexture != (Object)null)
			{
				return _labelTexture;
			}
			try
			{
				byte[] array = LoadEmbeddedResourceBytes("SuperGrow.Assets.SuperGrow_Label.png");
				if (array == null)
				{
					return null;
				}
				_labelTexture = new Texture2D(2, 2, (TextureFormat)4, false);
				if (!TryLoadImage(_labelTexture, array))
				{
					MelonLogger.Warning("Failed to decode SuperGrow.Assets.SuperGrow_Label.png");
					_labelTexture = null;
					return null;
				}
				((Object)_labelTexture).name = "SuperGrow_Label";
				return _labelTexture;
			}
			catch (Exception ex)
			{
				if (!_loggedLabelLoadException)
				{
					_loggedLabelLoadException = true;
					MelonLogger.Error("Failed to load SuperGrow label texture: " + ex.Message);
					MelonLogger.Error(ex.StackTrace ?? "<no stack trace>");
				}
				_labelTexture = null;
				return null;
			}
		}

		private static byte[]? LoadEmbeddedResourceBytes(string resourceName)
		{
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			using Stream stream = executingAssembly.GetManifestResourceStream(resourceName);
			if (stream == null)
			{
				MelonLogger.Warning("Could not find embedded resource: " + resourceName);
				return null;
			}
			using MemoryStream memoryStream = new MemoryStream();
			stream.CopyTo(memoryStream);
			return memoryStream.ToArray();
		}

		private static bool TryLoadImage(Texture2D texture, byte[] bytes)
		{
			try
			{
				Type type = Type.GetType("UnityEngine.ImageConversion, UnityEngine.ImageConversionModule") ?? typeof(Texture2D).Assembly.GetType("UnityEngine.ImageConversion");
				if (type == null)
				{
					return false;
				}
				MethodInfo[] methods = type.GetMethods(BindingFlags.Static | BindingFlags.Public);
				MethodInfo[] array = methods;
				bool flag = default(bool);
				foreach (MethodInfo methodInfo in array)
				{
					if (methodInfo.Name != "LoadImage")
					{
						continue;
					}
					ParameterInfo[] parameters = methodInfo.GetParameters();
					if ((parameters.Length != 2 && parameters.Length != 3) || parameters[0].ParameterType != typeof(Texture2D))
					{
						continue;
					}
					Type parameterType = parameters[1].ParameterType;
					object obj;
					if (parameterType == typeof(byte[]))
					{
						obj = bytes;
					}
					else
					{
						if (!parameterType.IsGenericType || !(parameterType.GetGenericTypeDefinition() == typeof(Il2CppStructArray<>)))
						{
							continue;
						}
						Il2CppStructArray<byte> val = new Il2CppStructArray<byte>((long)bytes.Length);
						for (int j = 0; j < bytes.Length; j++)
						{
							((Il2CppArrayBase<byte>)(object)val)[j] = bytes[j];
						}
						obj = val;
					}
					object obj2 = ((parameters.Length != 3) ? methodInfo.Invoke(null, new object[2] { texture, obj }) : methodInfo.Invoke(null, new object[3] { texture, obj, false }));
					int num;
					if (obj2 is bool)
					{
						flag = (bool)obj2;
						num = 1;
					}
					else
					{
						num = 0;
					}
					return (byte)((uint)num & (flag ? 1u : 0u)) != 0;
				}
				return false;
			}
			catch (Exception ex)
			{
				if (!_loggedImageLoadException)
				{
					_loggedImageLoadException = true;
					MelonLogger.Warning("Failed to decode embedded image bytes via ImageConversion.LoadImage: " + ex.Message);
					MelonLogger.Warning(ex.StackTrace ?? "<no stack trace>");
				}
				return false;
			}
		}
	}
	internal static class SuperGrowWorldState
	{
		private static bool _loggedReady;

		private static bool _ready;

		private static bool _loggedRegistryReadyException;

		public static bool IsRegistryReady()
		{
			try
			{
				if (_ready)
				{
					return true;
				}
				ItemDefinition item = Registry.GetItem("pgr");
				AdditiveDefinition val = ((item != null) ? ((Il2CppObjectBase)item).TryCast<AdditiveDefinition>() : null);
				ItemDefinition item2 = Registry.GetItem("speedgrow");
				AdditiveDefinition val2 = ((item2 != null) ? ((Il2CppObjectBase)item2).TryCast<AdditiveDefinition>() : null);
				ItemDefinition item3 = Registry.GetItem("fertilizer");
				AdditiveDefinition val3 = ((item3 != null) ? ((Il2CppObjectBase)item3).TryCast<AdditiveDefinition>() : null);
				if ((Object)(object)val == (Object)null && (Object)(object)val2 == (Object)null && (Object)(object)val3 == (Object)null)
				{
					return false;
				}
				_ready = true;
				if (!_loggedReady)
				{
					_loggedReady = true;
					MelonLogger.Msg("Registry appears ready; initializing item.");
				}
				return true;
			}
			catch (Exception ex)
			{
				if (!_loggedRegistryReadyException)
				{
					_loggedRegistryReadyException = true;
					MelonLogger.Warning("Registry readiness check failed: " + ex.Message);
					MelonLogger.Warning(ex.StackTrace ?? "<no stack trace>");
				}
				return false;
			}
		}
	}
}
namespace SuperGrow.Utils
{
	public static class Constants
	{
		public static class Game
		{
			public const string GAME_STUDIO = "TVGS";

			public const string GAME_NAME = "Schedule I";
		}

		public static class Additives
		{
			public const string PGR = "pgr";

			public const string SPEED_GROW = "speedgrow";

			public const string FERTILIZER = "fertilizer";
		}

		public static class ItemIds
		{
			public const string SUPER_GROW = "supergrow";
		}

		public static class DefaultEffects
		{
			public const float YIELD_MULTIPLIER = 1.5f;

			public const float INSTANT_GROWTH = 0.5f;

			public const float QUALITY_CHANGE = 1f;
		}

		public const string MOD_NAME = "SuperGrow";

		public const string MOD_VERSION = "1.3.4";

		public const string MOD_AUTHOR = "HazDS";

		public const string PREFERENCES_CATEGORY = "SuperGrow";
	}
	internal static class SuperGrowVisuals
	{
		internal static readonly Color PourColor = new Color(0.4f, 0.2f, 0.6f, 1f);

		internal static readonly Color LidTint = new Color(0.6f, 0.4f, 0.8f, 1f);

		internal static void ApplySuperGrowMaterialsToRenderers(Renderer[]? renderers)
		{
			//IL_024b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0270: Unknown result type (might be due to invalid IL or missing references)
			//IL_0296: Unknown result type (might be due to invalid IL or missing references)
			if (renderers == null)
			{
				return;
			}
			Texture2D labelTexture = SuperGrowAssets.GetLabelTexture();
			if ((Object)(object)labelTexture == (Object)null)
			{
				MelonLogger.Warning("SuperGrow label texture is null, cannot apply");
				return;
			}
			try
			{
				foreach (Renderer val in renderers)
				{
					if ((Object)(object)val == (Object)null)
					{
						continue;
					}
					string text = ((Object)val).name.ToLowerInvariant();
					bool flag = text.Contains("label");
					if (!flag)
					{
						foreach (Material item in (Il2CppArrayBase<Material>)(object)val.sharedMaterials)
						{
							if ((Object)(object)item != (Object)null && ((Object)item).name.ToLowerInvariant().Contains("label"))
							{
								flag = true;
								break;
							}
						}
					}
					bool flag2 = text.Contains("lid");
					if (!flag2)
					{
						foreach (Material item2 in (Il2CppArrayBase<Material>)(object)val.sharedMaterials)
						{
							if ((Object)(object)item2 != (Object)null && ((Object)item2).name.ToLowerInvariant().Contains("lid"))
							{
								flag2 = true;
								break;
							}
						}
					}
					if (flag)
					{
						Il2CppReferenceArray<Material> materials = val.materials;
						for (int j = 0; j < ((Il2CppArrayBase<Material>)(object)materials).Length; j++)
						{
							Material val2 = ((Il2CppArrayBase<Material>)(object)materials)[j];
							if (!((Object)(object)val2 == (Object)null))
							{
								val2.mainTexture = (Texture)(object)labelTexture;
								if (val2.HasProperty("_BaseMap"))
								{
									val2.SetTexture("_BaseMap", (Texture)(object)labelTexture);
								}
								if (val2.HasProperty("_MainTex"))
								{
									val2.SetTexture("_MainTex", (Texture)(object)labelTexture);
								}
							}
						}
						val.materials = materials;
					}
					else
					{
						if (!flag2)
						{
							continue;
						}
						Il2CppReferenceArray<Material> materials2 = val.materials;
						for (int k = 0; k < ((Il2CppArrayBase<Material>)(object)materials2).Length; k++)
						{
							Material val3 = ((Il2CppArrayBase<Material>)(object)materials2)[k];
							if (!((Object)(object)val3 == (Object)null))
							{
								val3.color = LidTint;
								if (val3.HasProperty("_BaseColor"))
								{
									val3.SetColor("_BaseColor", LidTint);
								}
								if (val3.HasProperty("_Color"))
								{
									val3.SetColor("_Color", LidTint);
								}
							}
						}
						val.materials = materials2;
					}
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Error("Failed to apply SuperGrow materials: " + ex.Message);
				MelonLogger.Error(ex.StackTrace);
			}
		}
	}
}
namespace SuperGrow.Patches
{
	[HarmonyPatch]
	internal static class ChemistryStationPatches
	{
		private readonly struct PendingTrashReskin
		{
			public string TrashId { get; }

			public string AdditiveId { get; }

			public PendingTrashReskin(string trashId, string additiveId)
			{
				TrashId = trashId;
				AdditiveId = additiveId;
			}
		}

		private static StationRecipe? _superGrowRecipe;

		private static bool _additivesPatched;

		private static bool _loggedMissingStationItemTemplate;

		private static bool _loggedRegistryStart;

		private static bool _loggedRecipeNotReady;

		private static int _superGrowBeginAuditUntilTick;

		private static int _superGrowBeginAuditSeq;

		private static ChemistryStation? _superGrowBeginStation;

		private static int _superGrowBeginStationSeq;

		private static string? _lastSelectedRecipeProductId;

		private static string? _lastSelectedRecipeTitle;

		private static string? _lastSelectedRecipeId;

		private static int _lastSelectedAtTick;

		private static bool _stationItemInitializePatchInfoDumped;

		private static readonly Dictionary<int, int> _chemCanvasDumpMaskByInstanceId = new Dictionary<int, int>();

		private const int TrashAuditWindowMs = 60000;

		private const int TrashAuditMaxLogs = 50;

		private static int _trashAuditUntilTick;

		private static int _trashAuditSeq;

		private static int _trashAuditTrashManagerLogged;

		private static int _trashAuditGetTrashPrefabLogged;

		private static int _trashAuditTrashItemStartLogged;

		private static bool _trashAuditHasStationPos;

		private static Vector3 _trashAuditStationPos;

		private static readonly HashSet<string> _trashAuditSeenTrashIds = new HashSet<string>();

		private static readonly HashSet<string> _trashAuditSeenGetTrashPrefabIds = new HashSet<string>();

		private static bool _trashAuditTrashPrefabsDumped;

		private static TrashManager? _trashAuditManager;

		private const int BeakerAuditWindowMs = 30000;

		private const int BeakerAuditMaxLogs = 80;

		private const float BeakerAuditMinLoggedLevelDelta = 0.05f;

		private const float BeakerAuditLevelEdgeEpsilon = 0.01f;

		private const float BeakerAuditMinLoggedColorDelta = 0.02f;

		private const int BeakerContentsAuditMaxLogs = 120;

		private const int BeakerContentsAuditMinIntervalMs = 250;

		private const float BeakerContentsAuditMinTotalDelta = 0.02f;

		private static int _beakerAuditUntilTick;

		private static int _beakerAuditSeq;

		private static int _beakerAuditLiquidColorLogged;

		private static int _beakerAuditLiquidLevelLogged;

		private static int _beakerContentsAuditLogged;

		private static bool _beakerAuditHasStationPos;

		private static Vector3 _beakerAuditStationPos;

		private static readonly HashSet<int> _beakerAuditSeenContainerIds = new HashSet<int>();

		private static readonly HashSet<int> _beakerAuditTrackedContainerIds = new HashSet<int>();

		private static readonly Dictionary<int, float> _beakerAuditLastLoggedLevel = new Dictionary<int, float>();

		private static readonly Dictionary<int, Color> _beakerAuditLastLoggedColor = new Dictionary<int, Color>();

		private static readonly Dictionary<int, int> _beakerContentsAuditLastTickByFillableId = new Dictionary<int, int>();

		private static readonly Dictionary<int, float> _beakerContentsAuditLastTotalByFillableId = new Dictionary<int, float>();

		private static readonly Dictionary<int, string> _beakerContentsAuditLastLabelByFillableId = new Dictionary<int, string>();

		private static bool _beakerAuditExpiredLogged;

		private const int ChemCanvasDump_AwakePostfix = 1;

		private const int ChemCanvasDump_OpenPrefix = 2;

		private const int ChemCanvasDump_UiAwakePostfix = 4;

		private const int ChemCanvasDump_UiOpenPrefix = 8;

		private const string PgrBottleTrashId = "supergrow_pgr_bottle";

		private const string SpeedGrowBottleTrashId = "supergrow_speedgrow_bottle";

		private const string FertilizerBottleTrashId = "supergrow_fertilizer_bottle";

		private const string SuperGrowBottleTrashId = "supergrow_bottle";

		private static GameObject? _prefabCacheRoot;

		private static bool _baseStationItemPrefabsEnsured;

		private static readonly Dictionary<string, StationItem> _stationItemPrefabByAdditiveId = new Dictionary<string, StationItem>();

		private static int _il2cppTrashPrefabsEnsuredForManagerId;

		private static readonly Dictionary<string, TrashItem> _il2cppBottleTrashPrefabByAdditiveId = new Dictionary<string, TrashItem>(StringComparer.OrdinalIgnoreCase);

		private static bool _loggedIl2CppTrashPrefabInjectionException;

		private static bool _loggedIl2CppTrashPrefabEnsureException;

		private static int _pendingStationTrashReskinExpireTick;

		private static readonly List<PendingTrashReskin> _pendingStationTrashReskins = new List<PendingTrashReskin>();

		private static readonly Dictionary<string, GameObject> _pourablePrefabs = new Dictionary<string, GameObject>();

		private static readonly Dictionary<string, Color> _additiveColors = new Dictionary<string, Color>
		{
			{
				"pgr",
				new Color(1f, 0.506f, 0.506f, 1f)
			},
			{
				"speedgrow",
				new Color(0.506f, 0.812f, 1f, 1f)
			},
			{
				"fertilizer",
				new Color(0.639f, 1f, 0.506f, 1f)
			},
			{
				"supergrow",
				SuperGrowVisuals.PourColor
			}
		};

		private const float LiquidScale = 0.65f;

		public static void Reset()
		{
			_superGrowRecipe = null;
			_additivesPatched = false;
			_loggedMissingStationItemTemplate = false;
			_loggedRegistryStart = false;
			_loggedRecipeNotReady = false;
			_chemCanvasDumpMaskByInstanceId.Clear();
			_baseStationItemPrefabsEnsured = false;
			_il2cppTrashPrefabsEnsuredForManagerId = 0;
		}

		private static void BeginBeakerAuditWindow(int seq, ChemistryStation? station)
		{
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			_beakerAuditSeq = seq;
			_beakerAuditUntilTick = Environment.TickCount + 30000;
			_beakerAuditLiquidColorLogged = 0;
			_beakerAuditLiquidLevelLogged = 0;
			_beakerContentsAuditLogged = 0;
			_beakerAuditSeenContainerIds.Clear();
			_beakerAuditTrackedContainerIds.Clear();
			_beakerAuditLastLoggedLevel.Clear();
			_beakerAuditLastLoggedColor.Clear();
			_beakerContentsAuditLastTickByFillableId.Clear();
			_beakerContentsAuditLastTotalByFillableId.Clear();
			_beakerContentsAuditLastLabelByFillableId.Clear();
			_beakerAuditExpiredLogged = false;
			if ((Object)(object)station != (Object)null && (Object)(object)((Component)station).transform != (Object)null)
			{
				_beakerAuditHasStationPos = true;
				_beakerAuditStationPos = ((Component)station).transform.position;
			}
			else
			{
				_beakerAuditHasStationPos = false;
				_beakerAuditStationPos = Vector3.zero;
			}
			string value = (_beakerAuditHasStationPos ? ((object)Unsafe.As<Vector3, Vector3>(ref _beakerAuditStationPos)/*cast due to .constrained prefix*/).ToString() : "<unknown>");
			MelonLogger.Msg($"SuperGrow beaker audit #{seq}: enabled for {30000}ms stationPos={value}");
			try
			{
				if ((Object)(object)station != (Object)null)
				{
					DumpNearbyLiquidContainersOnce(station, "BeginBeakerAuditWindow");
				}
			}
			catch
			{
			}
		}

		private static bool IsBeakerAuditActive()
		{
			if (_beakerAuditUntilTick == 0)
			{
				return false;
			}
			if (Environment.TickCount - _beakerAuditUntilTick < 0)
			{
				return true;
			}
			if (!_beakerAuditExpiredLogged)
			{
				_beakerAuditExpiredLogged = true;
				try
				{
					MelonLogger.Msg($"SuperGrow beaker audit #{_beakerAuditSeq}: expired (levelLogs={_beakerAuditLiquidLevelLogged}/{80} colorLogs={_beakerAuditLiquidColorLogged}/{80} trackedIds={_beakerAuditTrackedContainerIds.Count})");
				}
				catch
				{
				}
			}
			_beakerAuditUntilTick = 0;
			return false;
		}

		private static bool IsNearBeakerAuditedStation(Vector3 position)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			if (!_beakerAuditHasStationPos)
			{
				return true;
			}
			return Vector3.Distance(position, _beakerAuditStationPos) <= 35f;
		}

		private static string GetTransformPath(Transform? transform)
		{
			if ((Object)(object)transform == (Object)null)
			{
				return "<null>";
			}
			StringBuilder stringBuilder = new StringBuilder();
			Transform val = transform;
			while ((Object)(object)val != (Object)null)
			{
				stringBuilder.Insert(0, "/" + ((Object)val).name);
				val = val.parent;
			}
			return (stringBuilder.Length == 0) ? "<empty>" : stringBuilder.ToString();
		}

		private static bool ShouldTrackLiquidContainer(string goName, string path)
		{
			if (goName == "Liquid" && path.Contains("/Beaker(") && path.EndsWith("/Beaker/Liquid"))
			{
				return true;
			}
			if (goName == "Pourable" && path.EndsWith("/Pourable") && path.Contains("/ItemContainer/"))
			{
				return true;
			}
			return false;
		}

		private static bool ColorsApproximatelyEqual(Color a, Color b)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			return Mathf.Abs(a.r - b.r) < 0.02f && Mathf.Abs(a.g - b.g) < 0.02f && Mathf.Abs(a.b - b.b) < 0.02f && Mathf.Abs(a.a - b.a) < 0.02f;
		}

		private static void DumpNearbyLiquidContainersOnce(ChemistryStation station, string reason)
		{
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_023f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0265: Unknown result type (might be due to invalid IL or missing references)
			//IL_028b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b1: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Il2CppArrayBase<LiquidContainer> componentsInChildren = ((Component)station).GetComponentsInChildren<LiquidContainer>(true);
				if (componentsInChildren == null || componentsInChildren.Length == 0)
				{
					MelonLogger.Msg($"SuperGrow beaker audit #{_beakerAuditSeq}: no LiquidContainers found ({reason})");
					return;
				}
				MelonLogger.Msg($"SuperGrow beaker audit #{_beakerAuditSeq}: LiquidContainers near station ({reason}) count={componentsInChildren.Length}");
				int num = 0;
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					if (num >= 25)
					{
						break;
					}
					LiquidContainer val = componentsInChildren[i];
					if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).gameObject == (Object)null || (Object)(object)((Component)val).transform == (Object)null)
					{
						continue;
					}
					Vector3 position = ((Component)val).transform.position;
					if (IsNearBeakerAuditedStation(position))
					{
						int instanceID = ((Object)val).GetInstanceID();
						string text = ((Object)((Component)val).gameObject).name ?? "<unnamed>";
						string transformPath = GetTransformPath(((Component)val).transform);
						string value = (_beakerAuditHasStationPos ? Vector3.Distance(position, _beakerAuditStationPos).ToString("0.0") : "<n/a>");
						MelonLogger.Msg($"  - containerId={instanceID} name={text} dist={value} level={val.CurrentLiquidLevel:0.###}/{val.MaxLevel:0.###} color=({val.LiquidColor.r:0.###},{val.LiquidColor.g:0.###},{val.LiquidColor.b:0.###},{val.LiquidColor.a:0.###}) path={transformPath}");
						if (ShouldTrackLiquidContainer(text, transformPath))
						{
							_beakerAuditTrackedContainerIds.Add(instanceID);
						}
						num++;
					}
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Error("SuperGrow beaker audit: failed to dump LiquidContainers (" + reason + "): " + ex.Message);
			}
		}

		[HarmonyPatch(typeof(Fillable), "ResetContents")]
		[HarmonyPostfix]
		private static void Fillable_ResetContents_DebugPostfix(Fillable __instance)
		{
			if (!IsBeakerAuditActive() || _beakerContentsAuditLogged >= 120)
			{
				return;
			}
			try
			{
				if (!((Object)(object)__instance == (Object)null) && IsChemistryBeakerFillable(__instance))
				{
					int instanceID = ((Object)__instance).GetInstanceID();
					_beakerContentsAuditLastTickByFillableId.Remove(instanceID);
					_beakerContentsAuditLastTotalByFillableId.Remove(instanceID);
					_beakerContentsAuditLastLabelByFillableId.Remove(instanceID);
					_beakerContentsAuditLogged++;
					MelonLogger.Msg($"SuperGrow beaker audit #{_beakerAuditSeq}: Fillable.ResetContents fillableId={instanceID}");
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Error("SuperGrow beaker audit: Fillable.ResetContents logging failed: " + ex.Message);
			}
		}

		[HarmonyPatch(typeof(Fillable), "AddLiquid", new Type[]
		{
			typeof(string),
			typeof(float),
			typeof(Color)
		})]
		[HarmonyPostfix]
		private static void Fillable_AddLiquid_DebugPostfix(Fillable __instance, string label, float volume, Color color)
		{
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0214: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Unknown result type (might be due to invalid IL or missing references)
			//IL_0254: Unknown result type (might be due to invalid IL or missing references)
			//IL_0338: Unknown result type (might be due to invalid IL or missing references)
			//IL_0359: Unknown result type (might be due to invalid IL or missing references)
			//IL_037a: Unknown result type (might be due to invalid IL or missing references)
			//IL_039b: Unknown result type (might be due to invalid IL or missing references)
			if (!IsBeakerAuditActive() || _beakerContentsAuditLogged >= 120)
			{
				return;
			}
			try
			{
				if (!((Object)(object)__instance == (Object)null) && IsChemistryBeakerFillable(__instance))
				{
					int instanceID = ((Object)__instance).GetInstanceID();
					int tickCount = Environment.TickCount;
					float totalLiquidVolume = __instance.GetTotalLiquidVolume();
					int value;
					bool flag = _beakerContentsAuditLastTickByFillableId.TryGetValue(instanceID, out value);
					float value2;
					bool flag2 = _beakerContentsAuditLastTotalByFillableId.TryGetValue(instanceID, out value2);
					string value3;
					bool flag3 = _beakerContentsAuditLastLabelByFillableId.TryGetValue(instanceID, out value3) && string.Equals(value3, label, StringComparison.Ordinal);
					bool flag4 = flag2 && Mathf.Abs(totalLiquidVolume - value2) < 0.02f;
					bool flag5 = flag && tickCount - value < 250;
					if (!(flag3 && flag4 && flag5))
					{
						_beakerContentsAuditLastTickByFillableId[instanceID] = tickCount;
						_beakerContentsAuditLastTotalByFillableId[instanceID] = totalLiquidVolume;
						_beakerContentsAuditLastLabelByFillableId[instanceID] = label;
						float liquidVolume = __instance.GetLiquidVolume("pgr");
						float liquidVolume2 = __instance.GetLiquidVolume("speedgrow");
						float liquidVolume3 = __instance.GetLiquidVolume("fertilizer");
						float liquidVolume4 = __instance.GetLiquidVolume("supergrow");
						float value4 = (string.IsNullOrWhiteSpace(label) ? 0f : __instance.GetLiquidVolume(label));
						float liquidCapacity_L = __instance.LiquidCapacity_L;
						LiquidContainer liquidContainer = __instance.LiquidContainer;
						Color val = (((Object)(object)liquidContainer != (Object)null) ? liquidContainer.LiquidColor : Color.clear);
						_beakerContentsAuditLogged++;
						MelonLogger.Msg($"SuperGrow beaker audit #{_beakerAuditSeq}: Fillable.AddLiquid label={label} delta={volume:0.###} addColor=({color.r:0.###},{color.g:0.###},{color.b:0.###},{color.a:0.###}) total={totalLiquidVolume:0.###}/{liquidCapacity_L:0.###} pgr={liquidVolume:0.###} speedgrow={liquidVolume2:0.###} fertilizer={liquidVolume3:0.###} supergrow={liquidVolume4:0.###} labelVol={value4:0.###} beakerColor=({val.r:0.###},{val.g:0.###},{val.b:0.###},{val.a:0.###}) fillableId={instanceID}");
					}
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Error("SuperGrow beaker audit: Fillable.AddLiquid logging failed: " + ex.Message);
			}
		}

		private static StationRecipe? GetCachedSelectedRecipe(ChemistryStationInterface canvas)
		{
			try
			{
				RectTransform recipeContainer = canvas.RecipeContainer;
				if ((Object)(object)recipeContainer == (Object)null)
				{
					return null;
				}
				Il2CppArrayBase<StationRecipeEntry> componentsInChildren = ((Component)recipeContainer).GetComponentsInChildren<StationRecipeEntry>(true);
				if (componentsInChildren == null || componentsInChildren.Length == 0)
				{
					return null;
				}
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					StationRecipeEntry val = componentsInChildren[i];
					if ((Object)(object)val == (Object)null)
					{
						continue;
					}
					StationRecipe recipe = val.Recipe;
					if (!((Object)(object)recipe == (Object)null))
					{
						string text = SafeGetProductId(recipe);
						if (text == "supergrow")
						{
							return recipe;
						}
					}
				}
			}
			catch
			{
			}
			return null;
		}

		private static string SafeGetItemDefinitionId(ItemDefinition? def)
		{
			try
			{
				return ((def != null) ? ((BaseItemDefinition)def).ID : null) ?? "<null>";
			}
			catch
			{
				return "<error>";
			}
		}

		private static void LogRecipeIngredients(StationRecipe? recipe, int seq)
		{
			try
			{
				if ((Object)(object)recipe == (Object)null)
				{
					MelonLogger.Msg($"SuperGrow Begin audit #{seq}: recipe=<null>");
					return;
				}
				string value = SafeGetStationRecipeId(recipe);
				List<IngredientQuantity> ingredients = recipe.Ingredients;
				int value2 = ingredients?.Count ?? (-1);
				MelonLogger.Msg($"SuperGrow Begin audit #{seq}: recipeId={value} ingredientCount={value2}");
				if (ingredients == null)
				{
					return;
				}
				for (int i = 0; i < ingredients.Count; i++)
				{
					IngredientQuantity val = ingredients[i];
					if (val == null)
					{
						MelonLogger.Msg($"SuperGrow Begin audit #{seq}: ingredient[{i}]=<null>");
						continue;
					}
					int quantity = val.Quantity;
					List<ItemDefinition> items = val.Items;
					int value3 = items?.Count ?? (-1);
					string value4 = ((items != null && items.Count > 0) ? SafeGetItemDefinitionId(items[0]) : "<none>");
					MelonLogger.Msg($"SuperGrow Begin audit #{seq}: ingredient[{i}] qty={quantity} items={value3} first={value4}");
					if (items == null)
					{
						continue;
					}
					for (int j = 0; j < items.Count; j++)
					{
						ItemDefinition val2 = items[j];
						if (!((Object)(object)val2 == (Object)null))
						{
							string value5 = SafeGetItemDefinitionId(val2);
							LogItemDefinitionPrefabState(val2, seq, $"ingredient[{i}].items[{j}] ({value5})");
						}
					}
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Error($"SuperGrow Begin audit #{seq}: failed to log recipe ingredients: {ex.Message}");
				MelonLogger.Error(ex.StackTrace ?? "<no stack trace>");
			}
		}

		private static void LogItemDefinitionPrefabState(ItemDefinition def, int seq, string label)
		{
			try
			{
				StorableItemDefinition val = ((Il2CppObjectBase)def).TryCast<StorableItemDefinition>();
				if ((Object)(object)val == (Object)null)
				{
					MelonLogger.Msg($"SuperGrow Begin audit #{seq}: {label} type={((object)def).GetType().FullName} storable=<null>");
					return;
				}
				StationItem stationItem = val.StationItem;
				StoredItem storedItem = val.StoredItem;
				Equippable equippable = def.Equippable;
				string value = (((Object)(object)stationItem == (Object)null) ? "<null>" : $"{((Object)((Component)stationItem).gameObject).name} activeSelf={((Component)stationItem).gameObject.activeSelf} modules={SafeGetStationItemModuleCount(stationItem)}");
				string value2 = (((Object)(object)storedItem == (Object)null) ? "<null>" : ((Object)storedItem).name);
				string value3 = (((Object)(object)equippable == (Object)null) ? "<null>" : ((Object)equippable).name);
				MelonLogger.Msg($"SuperGrow Begin audit #{seq}: {label} type={((object)def).GetType().FullName} stationItem={value} storedItem={value2} equippable={value3}");
			}
			catch (Exception ex)
			{
				MelonLogger.Error($"SuperGrow Begin audit #{seq}: failed to inspect {label}: {ex.Message}");
			}
		}

		private static int SafeGetStationItemModuleCount(StationItem stationItem)
		{
			try
			{
				return stationItem.Modules?.Count ?? (-1);
			}
			catch
			{
				return -1;
			}
		}

		private static void LogChemistryStationSlotState(ChemistryStation? station, int seq, string tag)
		{
			try
			{
				if ((Object)(object)station == (Object)null)
				{
					MelonLogger.Msg($"SuperGrow Begin audit #{seq} ({tag}): station=<null>");
					return;
				}
				ChemistryCookOperation currentCookOperation = station.CurrentCookOperation;
				string value = ((currentCookOperation == null) ? "<null>" : (currentCookOperation.RecipeID ?? "<null>"));
				MelonLogger.Msg($"SuperGrow Begin audit #{seq} ({tag}): cookOpId={value}");
				if (station.IngredientSlots != null)
				{
					for (int i = 0; i < ((Il2CppArrayBase<ItemSlot>)(object)station.IngredientSlots).Length; i++)
					{
						ItemSlot val = ((Il2CppArrayBase<ItemSlot>)(object)station.IngredientSlots)[i];
						ItemInstance val2 = ((val != null) ? val.ItemInstance : null);
						ItemDefinition val3 = ((val2 != null) ? val2.Definition : null);
						string value2 = (((Object)(object)val3 == (Object)null) ? "<null>" : SafeGetItemDefinitionId(val3));
						int value3 = ((val2 != null) ? ((BaseItemInstance)val2).Quantity : 0);
						MelonLogger.Msg($"SuperGrow Begin audit #{seq} ({tag}): slot[{i}] id={value2} qty={value3}");
					}
				}
				else
				{
					MelonLogger.Msg($"SuperGrow Begin audit #{seq} ({tag}): IngredientSlots=<null>");
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Error($"SuperGrow Begin audit #{seq} ({tag}) failed: {ex.Message}");
			}
		}

		private static void LogChemistryStationIngredientTransforms(ChemistryStation station, int seq, string tag)
		{
			try
			{
				Il2CppReferenceArray<Transform> ingredientTransforms = station.IngredientTransforms;
				int value = ((Il2CppArrayBase<Transform>)(object)ingredientTransforms)?.Length ?? (-1);
				MelonLogger.Msg($"SuperGrow Begin audit #{seq} ({tag}): ingredientTransforms={value}");
				if (ingredientTransforms == null)
				{
					return;
				}
				for (int i = 0; i < ((Il2CppArrayBase<Transform>)(object)ingredientTransforms).Length; i++)
				{
					Transform val = ((Il2CppArrayBase<Transform>)(object)ingredientTransforms)[i];
					if ((Object)(object)val == (Object)null)
					{
						MelonLogger.Msg($"SuperGrow Begin audit #{seq} ({tag}): transform[{i}]=<null>");
						continue;
					}
					int childCount = val.childCount;
					MelonLogger.Msg($"SuperGrow Begin audit #{seq} ({tag}): transform[{i}] name={((Object)val).name} childCount={childCount}");
					for (int j = 0; j < childCount && j < 6; j++)
					{
						Transform child = val.GetChild(j);
						MelonLogger.Msg($"SuperGrow Begin audit #{seq} ({tag}):  - child[{j}] name={((Object)child).name} activeSelf={((Component)child).gameObject.activeSelf}");
					}
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Error($"SuperGrow Begin audit #{seq} ({tag}): failed to inspect ingredient transforms: {ex.Message}");
			}
		}

		private static void DumpChemistryStationInterfaceStateOnce(ChemistryStationInterface canvas, string tag, int stageMask)
		{
			if (!((Object)(object)canvas == (Object)null))
			{
				int instanceID = ((Object)canvas).GetInstanceID();
				if (!_chemCanvasDumpMaskByInstanceId.TryGetValue(instanceID, out var value) || (value & stageMask) == 0)
				{
					_chemCanvasDumpMaskByInstanceId[instanceID] = value | stageMask;
					DumpChemistryStationInterfaceState(canvas, tag);
				}
			}
		}

		private static void DumpChemistryStationInterfaceUiStateOnce(ChemistryStationInterface canvas, string tag, int stageMask)
		{
			if (!((Object)(object)canvas == (Object)null))
			{
				int instanceID = ((Object)canvas).GetInstanceID();
				if (!_chemCanvasDumpMaskByInstanceId.TryGetValue(instanceID, out var value) || (value & stageMask) == 0)
				{
					_chemCanvasDumpMaskByInstanceId[instanceID] = value | stageMask;
					DumpChemistryStationInterfaceUiState(canvas, tag);
				}
			}
		}

		private static void DumpChemistryStationInterfaceState(ChemistryStationInterface canvas, string tag)
		{
			try
			{
				int instanceID = ((Object)canvas).GetInstanceID();
				object recipes = canvas.Recipes;
				int? num = TryGetCount(recipes);
				bool value = ListContainsSuperGrowRecipe(recipes);
				Type typeFromHandle = typeof(ChemistryStationInterface);
				FieldInfo field = typeFromHandle.GetField("recipeEntries", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				PropertyInfo propertyInfo = ((field == null) ? typeFromHandle.GetProperty("recipeEntries", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) : null);
				object obj = null;
				if (field != null)
				{
					obj = field.GetValue(canvas);
				}
				else if (propertyInfo != null)
				{
					obj = propertyInfo.GetValue(canvas);
				}
				int? num2 = TryGetCount(obj);
				bool value2 = ListContainsSuperGrowRecipeEntry(obj);
				MelonLogger.Msg($"ChemistryStationInterface audit ({tag}): canvasId={instanceID} recipes={((recipes == null) ? "<null>" : (num?.ToString() ?? "<unknown>"))} hasSuperGrowRecipe={value} recipeEntriesField={((field != null) ? "ok" : ((propertyInfo != null) ? "ok(prop)" : "<missing>"))} recipeEntries={((obj == null) ? "<null>" : (num2?.ToString() ?? "<unknown>"))} hasSuperGrowEntry={value2}");
			}
			catch (Exception ex)
			{
				MelonLogger.Error("ChemistryStationInterface audit failed (" + tag + "): " + ex.Message);
				MelonLogger.Error(ex.StackTrace ?? "<no stack trace>");
			}
		}

		private static void DumpChemistryStationInterfaceUiState(ChemistryStationInterface canvas, string tag)
		{
			try
			{
				int instanceID = ((Object)canvas).GetInstanceID();
				RectTransform recipeContainer = canvas.RecipeContainer;
				if ((Object)(object)recipeContainer == (Object)null)
				{
					MelonLogger.Msg($"ChemistryStationInterface UI audit ({tag}): canvasId={instanceID} RecipeContainer=<null>");
					return;
				}
				Il2CppArrayBase<StationRecipeEntry> componentsInChildren = ((Component)recipeContainer).GetComponentsInChildren<StationRecipeEntry>(true);
				int value = componentsInChildren?.Length ?? 0;
				MelonLogger.Msg($"ChemistryStationInterface UI audit ({tag}): canvasId={instanceID} recipeContainerChildren={((Transform)recipeContainer).childCount} entryComponents={value}");
				if (componentsInChildren == null || componentsInChildren.Length == 0)
				{
					return;
				}
				int num = 0;
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					if (num >= 12)
					{
						break;
					}
					StationRecipeEntry val = componentsInChildren[i];
					if (!((Object)(object)val == (Object)null))
					{
						string value2;
						try
						{
							value2 = (((Object)(object)val.TitleLabel == (Object)null) ? "<null>" : (((TMP_Text)val.TitleLabel).text ?? "<null>"));
						}
						catch
						{
							value2 = "<error>";
						}
						string value3 = SafeGetProductId(val.Recipe);
						MelonLogger.Msg($"ChemistryStationInterface UI entry ({tag}): idx={i} title={value2} productId={value3}");
						num++;
					}
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Error("ChemistryStationInterface UI audit failed (" + tag + "): " + ex.Message);
				MelonLogger.Error(ex.StackTrace ?? "<no stack trace>");
			}
		}

		public static void DumpStationItemInitializePatchesOnce(string reason)
		{
			if (!_stationItemInitializePatchInfoDumped)
			{
				_stationItemInitializePatchInfoDumped = true;
				DumpStationItemInitializePatchInfo(reason);
			}
		}

		private static void DumpStationItemInitializePatchInfo(string reason)
		{
			try
			{
				MethodInfo methodInfo = AccessTools.Method(typeof(StationItem), "Initialize", new Type[1] { typeof(StorableItemDefinition) }, (Type[])null) ?? AccessTools.Method(typeof(StationItem), "Initialize", (Type[])null, (Type[])null);
				if (methodInfo == null)
				{
					MelonLogger.Warning("Could not resolve StationItem.Initialize method for patch audit (" + reason + ")");
					return;
				}
				Patches patchInfo = Harmony.GetPatchInfo((MethodBase)methodInfo);
				if (patchInfo == null)
				{
					MelonLogger.Msg("StationItem.Initialize patch audit (" + reason + "): no Harmony patches found");
					return;
				}
				string text = ((patchInfo.Owners != null && patchInfo.Owners.Count > 0) ? string.Join(", ", patchInfo.Owners) : "<none>");
				MelonLogger.Msg("StationItem.Initialize patch audit (" + reason + "): owners=" + text);
				LogPatchList("prefix", patchInfo.Prefixes);
				LogPatchList("postfix", patchInfo.Postfixes);
				LogPatchList("transpiler", patchInfo.Transpilers);
				LogPatchList("finalizer", patchInfo.Finalizers);
			}
			catch (Exception ex)
			{
				MelonLogger.Error("Failed to dump StationItem.Initialize patch audit (" + reason + "): " + ex.Message);
				MelonLogger.Error(ex.StackTrace ?? "<no stack trace>");
			}
		}

		private static void LogPatchList(string kind, IReadOnlyCollection<Patch> patches)
		{
			if (patches == null || patches.Count == 0)
			{
				MelonLogger.Msg("StationItem.Initialize " + kind + ": <none>");
				return;
			}
			MelonLogger.Msg($"StationItem.Initialize {kind}: count={patches.Count}");
			foreach (Patch patch in patches)
			{
				MethodInfo patchMethod = patch.PatchMethod;
				string value = ((patchMethod == null) ? "<null>" : ((patchMethod.DeclaringType == null) ? patchMethod.Name : (patchMethod.DeclaringType.FullName + "." + patchMethod.Name)));
				MelonLogger.Msg($"  - owner={patch.owner} prio={patch.priority} idx={patch.index} method={value}");
			}
		}

		private static int? TryGetCount(object? listObj)
		{
			if (listObj == null)
			{
				return null;
			}
			Type type = listObj.GetType();
			PropertyInfo property = type.GetProperty("Count");
			if (property != null && property.PropertyType == typeof(int))
			{
				return (int?)property.GetValue(listObj);
			}
			MethodInfo method = type.GetMethod("get_Count", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (method != null && method.ReturnType == typeof(int))
			{
				return (int?)method.Invoke(listObj, null);
			}
			return null;
		}

		private static object? TryGetListItem(object? listObj, int index)
		{
			if (listObj == null)
			{
				return null;
			}
			Type type = listObj.GetType();
			PropertyInfo property = type.GetProperty("Item");
			if (property != null)
			{
				try
				{
					return property.GetValue(listObj, new object[1] { index });
				}
				catch
				{
				}
			}
			MethodInfo method = type.GetMethod("get_Item", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (method != null)
			{
				try
				{
					return method.Invoke(listObj, new object[1] { index });
				}
				catch
				{
				}
			}
			return null;
		}

		private static bool ListContainsSuperGrowRecipe(object? recipesObj)
		{
			if (recipesObj == null)
			{
				return false;
			}
			int? num = TryGetCount(recipesObj);
			bool flag;
			if (num.HasValue)
			{
				int valueOrDefault = num.GetValueOrDefault();
				if (valueOrDefault > 0)
				{
					flag = false;
					goto IL_0037;
				}
			}
			flag = true;
			goto IL_0037;
			IL_0037:
			if (flag)
			{
				return false;
			}
			for (int i = 0; i < num; i++)
			{
				object obj = TryGetListItem(recipesObj, i);
				if (obj != null && TryGetStationRecipeProductId(obj, out string productId) && productId == "supergrow")
				{
					return true;
				}
			}
			return false;
		}

		private static bool ListContainsSuperGrowRecipeEntry(object? entriesObj)
		{
			if (entriesObj == null)
			{
				return false;
			}
			int? num = TryGetCount(entriesObj);
			bool flag;
			if (num.HasValue)
			{
				int valueOrDefault = num.GetValueOrDefault();
				if (valueOrDefault > 0)
				{
					flag = false;
					goto IL_0037;
				}
			}
			flag = true;
			goto IL_0037;
			IL_0037:
			if (flag)
			{
				return false;
			}
			for (int i = 0; i < num; i++)
			{
				object obj = TryGetListItem(entriesObj, i);
				if (obj != null)
				{
					object obj2 = obj.GetType().GetProperty("Recipe", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(obj);
					if (obj2 != null && TryGetStationRecipeProductId(obj2, out string productId) && productId == "supergrow")
					{
						return true;
					}
				}
			}
			return false;
		}

		private static bool TryGetStationRecipeProductId(object recipeObj, out string? productId)
		{
			productId = null;
			try
			{
				MemberInfo memberInfo = (MemberInfo)(((object)recipeObj.GetType().GetProperty("Product", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) ?? ((object)recipeObj.GetType().GetField("Product", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)));
				if (1 == 0)
				{
				}
				object obj = ((memberInfo is PropertyInfo propertyInfo) ? propertyInfo.GetValue(recipeObj) : ((!(memberInfo is FieldInfo fieldInfo)) ? null : fieldInfo.GetValue(recipeObj)));
				if (1 == 0)
				{
				}
				object obj2 = obj;
				if (obj2 == null)
				{
					return false;
				}
				MemberInfo memberInfo2 = (MemberInfo)(((object)obj2.GetType().GetProperty("Item", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) ?? ((object)obj2.GetType().GetField("Item", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)));
				if (1 == 0)
				{
				}
				obj = ((memberInfo2 is PropertyInfo propertyInfo2) ? propertyInfo2.GetValue(obj2) : ((!(memberInfo2 is FieldInfo fieldInfo2)) ? null : fieldInfo2.GetValue(obj2)));
				if (1 == 0)
				{
				}
				object obj3 = obj;
				if (obj3 == null)
				{
					return false;
				}
				PropertyInfo property = obj3.GetType().GetProperty("ID", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (property != null && property.PropertyType == typeof(string))
				{
					productId = property.GetValue(obj3) as string;
					return productId != null;
				}
				FieldInfo field = obj3.GetType().GetField("ID", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (field != null && field.FieldType == typeof(string))
				{
					productId = field.GetValue(obj3) as string;
					return productId != null;
				}
				MethodInfo method = obj3.GetType().GetMethod("get_ID", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (method != null && method.ReturnType == typeof(string))
				{
					productId = method.Invoke(obj3, null) as string;
					return productId != null;
				}
			}
			catch
			{
			}
			return false;
		}

		private static void BeginTrashAuditWindow(int seq, ChemistryStation? station)
		{
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			_trashAuditSeq = seq;
			_trashAuditUntilTick = Environment.TickCount + 60000;
			_trashAuditTrashManagerLogged = 0;
			_trashAuditGetTrashPrefabLogged = 0;
			_trashAuditTrashItemStartLogged = 0;
			_trashAuditSeenTrashIds.Clear();
			_trashAuditSeenGetTrashPrefabIds.Clear();
			_trashAuditTrashPrefabsDumped = false;
			if ((Object)(object)station != (Object)null && (Object)(object)((Component)station).transform != (Object)null)
			{
				_trashAuditHasStationPos = true;
				_trashAuditStationPos = ((Component)station).transform.position;
			}
			else
			{
				_trashAuditHasStationPos = false;
				_trashAuditStationPos = Vector3.zero;
			}
			string value = (_trashAuditHasStationPos ? ((object)Unsafe.As<Vector3, Vector3>(ref _trashAuditStationPos)/*cast due to .constrained prefix*/).ToString() : "<unknown>");
			MelonLogger.Msg($"SuperGrow trash audit #{seq}: enabled for {60000}ms stationPos={value}");
			try
			{
				if ((Object)(object)_trashAuditManager == (Object)null)
				{
					_trashAuditManager = Object.FindObjectOfType<TrashManager>();
				}
				DumpTrashPrefabsOnce("BeginTrashAuditWindow", _trashAuditManager);
			}
			catch
			{
			}
		}

		private static bool IsTrashAuditActive()
		{
			return _trashAuditUntilTick != 0 && Environment.TickCount - _trashAuditUntilTick < 0;
		}

		private static bool IsNearAuditedStation(Vector3 position)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			if (!_trashAuditHasStationPos)
			{
				return true;
			}
			return Vector3.Distance(position, _trashAuditStationPos) <= 35f;
		}

		private static void DumpTrashPrefabsOnce(string reason, TrashManager? manager)
		{
			if (_trashAuditTrashPrefabsDumped)
			{
				return;
			}
			if ((Object)(object)manager == (Object)null)
			{
				MelonLogger.Msg($"SuperGrow trash audit #{_trashAuditSeq}: TrashManager not found for TrashPrefabs dump ({reason})");
				return;
			}
			_trashAuditTrashPrefabsDumped = true;
			try
			{
				Il2CppReferenceArray<TrashItem> trashPrefabs = manager.TrashPrefabs;
				int value = ((Il2CppArrayBase<TrashItem>)(object)trashPrefabs)?.Length ?? 0;
				MelonLogger.Msg($"SuperGrow trash audit #{_trashAuditSeq}: TrashPrefabs dump ({reason}) total={value}");
				if (trashPrefabs != null)
				{
					for (int i = 0; i < ((Il2CppArrayBase<TrashItem>)(object)trashPrefabs).Length; i++)
					{
						TrashItem val = ((Il2CppArrayBase<TrashItem>)(object)trashPrefabs)[i];
						string value2 = (((Object)(object)val == (Object)null) ? "<null>" : (val.ID ?? "<null-id>"));
						string value3 = (((Object)(object)val == (Object)null || (Object)(object)((Component)val).gameObject == (Object)null) ? "<null>" : (((Object)((Component)val).gameObject).name ?? "<unnamed>"));
						MelonLogger.Msg($"  - [{i}] id={value2} name={value3}");
					}
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Error("SuperGrow trash audit: TrashPrefabs dump failed (" + reason + "): " + ex.Message);
			}
		}

		[HarmonyPatch(typeof(ChemistryStation), "CreateTrash")]
		[HarmonyPrefix]
		private static void ChemistryStation_CreateTrash_DebugPrefix(ChemistryStation __instance, List<StationItem> mixerItems)
		{
			if (!IsTrashAuditActive())
			{
				return;
			}
			try
			{
				ChemistryCookOperation val = ((__instance != null) ? __instance.CurrentCookOperation : null);
				string value = ((val == null) ? "<null-op>" : (val.RecipeID ?? "<null>"));
				int value2 = mixerItems?.Count ?? (-1);
				MelonLogger.Msg($"SuperGrow trash audit #{_trashAuditSeq}: ChemistryStation.CreateTrash recipeId={value} mixerItems={value2}");
				if (mixerItems == null)
				{
					return;
				}
				int num = Math.Min(8, mixerItems.Count);
				for (int i = 0; i < num; i++)
				{
					StationItem val2 = mixerItems[i];
					if ((Object)(object)val2 == (Object)null || (Object)(object)((Component)val2).gameObject == (Object)null)
					{
						MelonLogger.Msg($"  - mixer[{i}]=<null>");
						continue;
					}
					string value3 = ((Object)((Component)val2).gameObject).name ?? "<unnamed>";
					string value4 = (((Object)(object)val2.TrashPrefab == (Object)null) ? "<null>" : (val2.TrashPrefab.ID ?? "<null-id>"));
					MelonLogger.Msg($"  - mixer[{i}] name={value3} trashId={value4}");
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Error("SuperGrow trash audit: ChemistryStation.CreateTrash logging failed: " + ex.Message);
			}
		}

		[HarmonyPatch(typeof(TrashManager), "Start")]
		[HarmonyPostfix]
		private static void TrashManager_Start_DebugPostfix(TrashManager __instance)
		{
			_trashAuditManager = __instance;
			if (IsTrashAuditActive())
			{
				DumpTrashPrefabsOnce("TrashManager.Start", __instance);
			}
		}

		[HarmonyPatch(typeof(TrashManager), "CreateTrashItem", new Type[]
		{
			typeof(string),
			typeof(Vector3),
			typeof(Quaternion),
			typeof(Vector3),
			typeof(string),
			typeof(bool)
		})]
		[HarmonyPrefix]
		private static void TrashManager_CreateTrashItem_DebugPrefix(string id, Vector3 posiiton, Quaternion rotation, Vector3 initialVelocity, string guid, bool startKinematic)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			if (!IsTrashAuditActive() || _trashAuditTrashManagerLogged >= 50 || !IsNearAuditedStation(posiiton))
			{
				return;
			}
			try
			{
				string text = id ?? "<null>";
				if (_trashAuditSeenTrashIds.Add(text))
				{
					_trashAuditTrashManagerLogged++;
					string value = (_trashAuditHasStationPos ? Vector3.Distance(posiiton, _trashAuditStationPos).ToString("0.0") : "<n/a>");
					MelonLogger.Msg($"SuperGrow trash audit #{_trashAuditSeq}: TrashManager.CreateTrashItem id={text} pos={posiiton} dist={value}");
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Error("SuperGrow trash audit: TrashManager.CreateTrashItem logging failed: " + ex.Message);
			}
		}

		[HarmonyPatch(typeof(TrashManager), "GetTrashPrefab", new Type[] { typeof(string) })]
		[HarmonyPostfix]
		private static void TrashManager_GetTrashPrefab_DebugPostfix(TrashManager __instance, string id, TrashItem __result)
		{
			if (!IsTrashAuditActive() || _trashAuditGetTrashPrefabLogged >= 50)
			{
				return;
			}
			try
			{
				string text = id ?? "<null>";
				if (!_trashAuditSeenGetTrashPrefabIds.Add(text))
				{
					return;
				}
				string value = (((Object)(object)__result == (Object)null) ? "<null>" : (__result.ID ?? "<null-id>"));
				string value2 = (((Object)(object)__result == (Object)null || (Object)(object)((Component)__result).gameObject == (Object)null) ? "<null>" : (((Object)((Component)__result).gameObject).name ?? "<unnamed>"));
				Il2CppReferenceArray<TrashItem> val = (((Object)(object)__instance == (Object)null) ? null : __instance.TrashPrefabs);
				int value3 = ((Il2CppArrayBase<TrashItem>)(object)val)?.Length ?? 0;
				int value4 = -1;
				if (val != null)
				{
					for (int i = 0; i < ((Il2CppArrayBase<TrashItem>)(object)val).Length; i++)
					{
						TrashItem val2 = ((Il2CppArrayBase<TrashItem>)(object)val)[i];
						if ((Object)(object)val2 != (Object)null && val2.ID == text)
						{
							value4 = i;
							break;
						}
					}
				}
				_trashAuditGetTrashPrefabLogged++;
				MelonLogger.Msg($"SuperGrow trash audit #{_trashAuditSeq}: TrashManager.GetTrashPrefab id={text} -> resultId={value} resultName={value2} trashPrefabsIndex={value4} total={value3}");
			}
			catch (Exception ex)
			{
				MelonLogger.Error("SuperGrow trash audit: TrashManager.GetTrashPrefab logging failed: " + ex.Message);
			}
		}

		[HarmonyPatch(typeof(TrashItem), "Start")]
		[HarmonyPostfix]
		private static void TrashItem_Start_DebugPostfix(TrashItem __instance)
		{
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: 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_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			if (!IsTrashAuditActive() || _trashAuditTrashItemStartLogged >= 50)
			{
				return;
			}
			try
			{
				if (!((Object)(object)__instance == (Object)null) && !((Object)(object)((Component)__instance).gameObject == (Object)null))
				{
					Vector3 val = (((Object)(object)((Component)__instance).transform != (Object)null) ? ((Component)__instance).transform.position : Vector3.zero);
					if (IsNearAuditedStation(val))
					{
						_trashAuditTrashItemStartLogged++;
						string value = __instance.ID ?? "<null>";
						string value2 = ((Object)((Component)__instance).gameObject).name ?? "<unnamed>";
						string value3 = (_trashAuditHasStationPos ? Vector3.Distance(val, _trashAuditStationPos).ToString("0.0") : "<n/a>");
						MelonLogger.Msg($"SuperGrow trash audit #{_trashAuditSeq}: TrashItem.Start id={value} name={value2} pos={val} dist={value3}");
					}
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Error("SuperGrow trash audit: TrashItem.Start logging failed: " + ex.Message);
			}
		}

		private static Transform GetOrCreatePrefabCacheRoot()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			if ((Object)(object)_prefabCacheRoot != (Object)null)
			{
				return _prefabCacheRoot.transform;
			}
			_prefabCacheRoot = new GameObject("SuperGrow_PrefabCache");
			Object.DontDestroyOnLoad((Object)(object)_prefabCacheRoot);
			_prefabCacheRoot.SetActive(false);
			return _prefabCacheRoot.transform;
		}

		private static bool TryGetBottleTrashId(string additiveId, out string trashId)
		{
			trashId = null;
			if (string.Equals(additiveId, "pgr", StringComparison.OrdinalIgnoreCase))
			{
				trashId = "supergrow_pgr_bottle";
				return true;
			}
			if (string.Equals(additiveId, "speedgrow", StringComparison.OrdinalIgnoreCase))
			{
				trashId = "supergrow_speedgrow_bottle";
				return true;
			}
			if (string.Equals(additiveId, "fertilizer", StringComparison.OrdinalIgnoreCase))
			{
				trashId = "supergrow_fertilizer_bottle";
				return true;
			}
			return false;
		}

		private static void EnsureIl2CppBottleTrashPrefabsInjected(TrashManager manager)
		{
			if ((Object)(object)manager == (Object)null)
			{
				return;
			}
			int instanceID = ((Object)manager).GetInstanceID();
			if (instanceID != 0 && instanceID == _il2cppTrashPrefabsEnsuredForManagerId)
			{
				return;
			}
			try
			{
				CachePourablePrefab("pgr", "growing/pgr/PGR_Pourable");
				CachePourablePrefab("speedgrow", "growing/speedgrow/SpeedGrow_Pourable");
				CachePourablePrefab("fertilizer", "growing/fertilizer/Fertilizer_Pourable");
				TrashItem baseTrash = manager.GetTrashPrefab("acid");
				TrashItem pgrTrash = manager.GetTrashPrefab("pgr");
				if ((Object)(object)baseTrash == (Object)null || (Object)(object)((Component)baseTrash).gameObject == (Object)null)
				{
					return;
				}
				List<TrashItem> additions = new List<TrashItem>();
				Ensure("pgr", "supergrow_pgr_bottle");
				Ensure("speedgrow", "supergrow_speedgrow_bottle");
				Ensure("fertilizer", "supergrow_fertilizer_bottle");
				Ensure("supergrow", "supergrow_bottle");
				if (additions.Count == 0)
				{
					_il2cppTrashPrefabsEnsuredForManagerId = instanceID;
					return;
				}
				Il2CppReferenceArray<TrashItem> trashPrefabs = manager.TrashPrefabs;
				int num = ((Il2CppArrayBase<TrashItem>)(object)trashPrefabs)?.Length ?? 0;
				TrashItem[] array = (TrashItem[])(object)new TrashItem[num + additions.Count];
				for (int i = 0; i < num; i++)
				{
					array[i] = ((Il2CppArrayBase<TrashItem>)(object)trashPrefabs)[i];
				}
				for (int j = 0; j < additions.Count; j++)
				{
					array[num + j] = additions[j];
				}
				manager.TrashPrefabs = new Il2CppReferenceArray<TrashItem>(array);
				_il2cppTrashPrefabsEnsuredForManagerId = instanceID;
				void Ensure(string additiveId, string newId)
				{
					try
					{
						if (!((Object)(object)manager.GetTrashPrefab(newId) != (Object)null))
						{
							if (_il2cppBottleTrashPrefabByAdditiveId.TryGetValue(additiveId, out TrashItem value) && (Object)(object)value != (Object)null)
							{
								value.ID = newId;
								additions.Add(value);
							}
							else
							{
								Transform orCreatePrefabCacheRoot = GetOrCreatePrefabCacheRoot();
								GameObject val = ((string.Equals(additiveId, "supergrow", StringComparison.OrdinalIgnoreCase) && (Object)(object)pgrTrash != (Object)null && (Object)(object)((Component)pgrTrash).gameObject != (Object)null) ? ((Component)pgrTrash).gameObject : ((Component)baseTrash).gameObject);
								GameObject val2 = Object.Instantiate<GameObject>(val);
								((Object)val2).name = "SuperGrow_" + additiveId + "_TrashPrefab";
								val2.SetActive(val.activeSelf);
								val2.transform.SetParent(orCreatePrefabCacheRoot, false);
								Object.DontDestroyOnLoad((Object)(object)val2);
								TrashItem component = val2.GetComponent<TrashItem>();
								if ((Object)(object)component == (Object)null)
								{
									Object.Destroy((Object)(object)val2);
								}
								else
								{
									component.ID = newId;
									SwapTrashItemVisualsById(additiveId, component);
									_il2cppBottleTrashPrefabByAdditiveId[additiveId] = component;
									additions.Add(component);
								}
							}
						}
					}
					catch (Exception ex2)
					{
						if (!_loggedIl2CppTrashPrefabEnsureException)
						{
							_loggedIl2CppTrashPrefabEnsureException = true;
							MelonLogger.Warning("Failed to create SuperGrow trash prefab for '" + additiveId + "' (IL2CPP): " + ex2.Message);
							MelonLogger.Warning(ex2.StackTrace ?? "<no stack trace>");
						}
					}
				}
			}
			catch (Exception ex)
			{
				if (!_loggedIl2CppTrashPrefabInjectionException)
				{
					_loggedIl2CppTrashPrefabInjectionException = true;
					MelonLogger.Warning("Failed to inject SuperGrow trash prefabs (IL2CPP): " + ex.Message);
					MelonLogger.Warning(ex.StackTrace ?? "<no stack trace>");
				}
			}
		}

		private static void TryAssignIl2CppBottleTrashPrefab(string additiveId, StationItem stationItem)
		{
			if ((Object)(object)stationItem == (Object)null || !TryGetBottleTrashId(additiveId, out string trashId))
			{
				return;
			}
			try
			{
				TrashManager val = Object.FindObjectOfType<TrashManager>();
				if ((Object)(object)val == (Object)null)
				{
					return;
				}
				EnsureIl2CppBottleTrashPrefabsInjected(val);
				if (_il2cppBottleTrashPrefabByAdditiveId.TryGetValue(additiveId, out TrashItem value) && (Object)(object)value != (Object)null)
				{
					stationItem.TrashPrefab = value;
					return;
				}
				TrashItem trashPrefab = val.GetTrashPrefab(trashId);
				if ((Object)(object)trashPrefab != (Object)null)
				{
					stationItem.TrashPrefab = trashPrefab;
				}
			}
			catch
			{
			}
		}

		private static void DebugLogIl2CppAdditiveTrashIds(string tag)
		{
			try
			{
				string[] array = new string[3] { "pgr", "speedgrow", "fertilizer" };
				foreach (string text in array)
				{
					_stationItemPrefabByAdditiveId.TryGetValue(text, out StationItem value);
					string value2 = (((Object)(object)((value != null) ? value.TrashPrefab : null) != (Object)null) ? value.TrashPrefab.ID : "<null>");
					MelonLogger.Msg($"[SuperGrow] IL2CPP additive trash ids ({tag}): {text} -> {value2}");
				}
			}
			catch
			{
			}
		}

		private static void ApplyIl2CppBottleTrashPrefabsToCachedStationItems(TrashManager manager)
		{
			if ((Object)(object)manager == (Object)null)
			{
				return;
			}
			try
			{
				EnsureIl2CppBottleTrashPrefabsInjected(manager);
				string[] array = new string[3] { "pgr", "speedgrow", "fertilizer" };
				foreach (string text in array)
				{
					if (_stationItemPrefabByAdditiveId.TryGetValue(text, out StationItem value) && (Object)(object)value != (Object)null)
					{
						TryAssignIl2CppBottleTrashPrefab(text, value);
					}
				}
			}
			catch
			{
			}
		}

		public static bool EnsureAdditiveStationItemPrefabs()
		{
			if (!TryGetStationItemTemplate(out StationItem templateStationItem))
			{
				return false;
			}
			CachePourablePrefab("pgr", "growing/pgr/PGR_Pourable");
			CachePourablePrefab("speedgrow", "growing/speedgrow/SpeedGrow_Pourable");
			CachePourablePrefab("fertilizer", "growing/fertilizer/Fertilizer_Pourable");
			TrashManager val = Object.FindObjectOfType<TrashManager>();
			if ((Object)(object)val != (Object)null)
			{
				EnsureIl2CppBottleTrashPrefabsInjected(val);
			}
			if (!_baseStationItemPrefabsEnsured)
			{
				_baseStationItemPrefabsEnsured = true;
				EnsureStationItemPrefabForAdditive("pgr", templateStationItem, overrideIfPresent: true);
				EnsureStationItemPrefabForAdditive("speedgrow", templateStationItem, overrideIfPresent: true);
				EnsureStationItemPrefabForAdditive("fertilizer", templateStationItem, overrideIfPresent: true);
			}
			EnsureStationItemPrefabForAdditive("supergrow", templateStationItem, overrideIfPresent: true);
			return true;
		}

		private static void EnsureStationItemPrefabForAdditive(string additiveId, StationItem templateStationItem, bool overrideIfPresent)
		{
			ItemDefinition item = Registry.GetItem(additiveId);
			StorableItemDefinition val = ((item != null) ? ((Il2CppObjectBase)item).TryCast<StorableItemDefinition>() : null);
			if ((Object)(object)val == (Object)null || (!overrideIfPresent && (Object)(object)val.StationItem != (Object)null))
			{
				return;
			}
			if (_stationItemPrefabByAdditiveId.TryGetValue(additiveId, out StationItem value) && (Object)(object)value != (Object)null)
			{
				val.StationItem = value;
				TryAssignIl2CppBottleTrashPrefab(additiveId, value);
				return;
			}
			Transform orCreatePrefabCacheRoot = GetOrCreatePrefabCacheRoot();
			GameObject val2 = Object.Instantiate<GameObject>(((Component)templateStationItem).gameObject);
			((Object)val2).name = "SuperGrow_StationItemPrefab_" + additiveId;
			val2.SetActive(true);
			val2.transform.SetParent(orCreatePrefabCacheRoot, false);
			Object.DontDestroyOnLoad((Object)(object)val2);
			StationItem component = val2.GetComponent<StationItem>();
			if ((Object)(object)component == (Object)null)
			{
				Object.Destroy((Object)(object)val2);
				return;
			}
			TryAssignIl2CppBottleTrashPrefab(additiveId, component);
			_stationItemPrefabByAdditiveId[additiveId] = component;
			val.StationItem = component;
			SwapStationItemVisualsById(additiveId, component);
		}

		[HarmonyPatch(typeof(TrashManager), "Start")]
		[HarmonyPostfix]
		private static void TrashManager_Start_Postfix_Il2Cpp(TrashManager __instance)
		{
			EnsureIl2CppBottleTrashPrefabsInjected(__instance);
			ApplyIl2CppBottleTrashPrefabsToCachedStationItems(__instance);
			DebugLogIl2CppAdditiveTrashIds("TrashManager.Start");
		}

		[HarmonyPatch(typeof(ChemistryStationInterface), "Awake")]
		[HarmonyPrefix]
		private static void ChemistryStationInterface_Awake_Prefix(ChemistryStationInterface __instance)
		{
			try
			{
				if ((Object)(object)__instance == (Object)null)
				{
					return;
				}
				SuperGrowCreator.CreateSuperGrowItem();
				if ((Object)(object)_superGrowRecipe == (Object)null)
				{
					CreateSuperGrowRecipe();
				}
				if ((Object)(object)_superGrowRecipe == (Object)null)
				{
					if (!_loggedRecipeNotReady)
					{
						_loggedRecipeNotReady = true;
						MelonLogger.Warning("SuperGrow recipe is null; cannot add to chemistry station yet");
					}
					return;
				}
				List<StationRecipe> recipes = __instance.Recipes;
				if (recipes == null)
				{
					if (!_loggedRecipeNotReady)
					{
						_loggedRecipeNotReady = true;
						MelonLogger.Warning("ChemistryStationInterface.Recipes is null; cannot add SuperGrow recipe");
					}
				}
				else if (!recipes.Contains(_superGrowRecipe))
				{
					recipes.Add(_superGrowRecipe);
					MelonLogger.Msg("Added SuperGrow recipe to Chemistry Station");
					SetupAdditiveStationItems();
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Error("Failed to add SuperGrow recipe: " + ex.Message);
				MelonLogger.Error(ex.StackTrace ?? "<no stack trace>");
			}
		}

		[HarmonyPatch(typeof(ChemistryStationInterface), "Awake")]
		[HarmonyPostfix]
		private static void ChemistryStationInterface_Awake_Postfix(ChemistryStationInterface __instance)
		{
			DumpChemistryStationInterfaceStateOnce(__instance, "Awake_Postfix", 1);
			DumpChemistryStationInterfaceUiStateOnce(__instance, "Awake_Postfix", 4);
		}

		[HarmonyPatch(typeof(ChemistryStationInterface), "Open")]
		[HarmonyPrefix]
		private static void ChemistryStationInterface_Open_PrefixAudit(ChemistryStationInterface __instance, ChemistryStation station)
		{
			DumpChemistryStationInterfaceStateOnce(__instance, "Open_Prefix", 2);
			DumpChemistryStationInterfaceUiStateOnce(__instance, "Open_Prefix", 8);
		}

		[HarmonyPatch(typeof(ChemistryStationInterface), "SetSelectedRecipe")]
		[HarmonyPrefix]
		private static void ChemistryStationInterface_SetSelectedRecipe_Prefix(ChemistryStationInterface __instance, StationRecipeEntry entry)
		{
			try
			{
				StationRecipe val = ((entry != null) ? entry.Recipe : null);
				string text = SafeGetProductId(val);
				if (!(text == "<null>") && !(text == "<error>"))
				{
					_lastSelectedRecipeProductId = text;
					_lastSelectedRecipeTitle = SafeGetRecipeEntryTitle(entry);
					_lastSelectedRecipeId = (((Object)(object)val == (Object)null) ? "<null>" : SafeGetStationRecipeId(val));
					_lastSelectedAtTick = Environment.TickCount;
				}
			}
			catch
			{
			}
		}

		[HarmonyPatch(typeof(ChemistryStationInterface), "BeginTask")]
		[HarmonyPrefix]
		private static void ChemistryStationInterface_BeginTask_Prefix(ChemistryStationInterface __instance)
		{
			try
			{
				if (!((Object)(object)__instance == (Object)null))
				{
					StationRecipeEntry val = TryGetSelectedRecipeEntry(__instance);
					StationRecipe val2 = ((val != null) ? val.Recipe : null);
					string text = SafeGetProductId(val2);
					if (text == "<null>" || text == "<error>")
					{
						text = _lastSelectedRecipeProductId ?? text;
					}
					if (!(text != "supergrow"))
					{
						_superGrowBeginAuditSeq++;
						_superGrowBeginAuditUntilTick = Environment.TickCount + 10000;
						_superGrowBeginStation = __instance.ChemistryStation;
						_superGrowBeginStationSeq = _superGrowBeginAuditSeq;
						int superGrowBeginAuditSeq = _superGrowBeginAuditSeq;
						string value = (((Object)(object)val != (Object)null) ? SafeGetRecipeEntryTitle(val) : (_lastSelectedRecipeTitle ?? "<unknown>"));
						string value2 = (((Object)(object)val2 != (Object)null) ? SafeGetStationRecipeId(val2) : (_lastSelectedRecipeId ?? "<unknown>"));
						MelonLogger.Msg($"SuperGrow Begin audit #{superGrowBeginAuditSeq}: selectedTitle={value} productId={text} recipeId={value2} beginInteractable={SafeGetBeginInteractable(__instance)}");
						BeginTrashAuditWindow(superGrowBeginAuditSeq, __instance.ChemistryStation);
						BeginBeakerAuditWindow(superGrowBeginAuditSeq, __instance.ChemistryStation);
						LogRecipeIngredients(val2 ?? GetCachedSelectedRecipe(__instance), superGrowBeginAuditSeq);
						LogChemistryStationSlotState(_superGrowBeginStation, superGrowBeginAuditSeq, "Begin_Prefix");
					}
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Error("SuperGrow Begin audit failed (Prefix): " + ex.Message);
				MelonLogger.Error(ex.StackTrace ?? "<no stack trace>");
			}
		}

		[HarmonyPatch(typeof(ChemistryStationInterface), "BeginTask")]
		[HarmonyPostfix]
		private static void ChemistryStationInterface_BeginTask_Postfix(ChemistryStationInterface __instance)
		{
			try
			{
				if (!((Object)(object)__instance == (Object)null) && !TickExpired(_superGrowBeginAuditUntilTick))
				{
					int superGrowBeginAuditSeq = _superGrowBeginAuditSeq;
					ChemistryStation val = __instance.ChemistryStation;
					if ((Object)(object)val == (Object)null && _superGrowBeginStationSeq == superGrowBeginAuditSeq)
					{
						val = _superGrowBeginStation;
					}
					LogChemistryStationSlotState(val, superGrowBeginAuditSeq, "Begin_Postfix");
					if ((Object)(object)val != (Object)null)
					{
						MelonCoroutines.Start(DelayedChemistryIngredientAudit(superGrowBeginAuditSeq, val));
					}
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Error("SuperGrow Begin audit failed (Postfix): " + ex.Message);
				MelonLogger.Error(ex.StackTrace ?? "<no stack trace>");
			}
		}

		private static bool TickExpired(int untilTick)
		{
			return Environment.TickCount - untilTick >= 0;
		}

		private static IEnumerator DelayedChemistryIngredientAudit(int seq, ChemistryStation station)
		{
			yield return (object)new WaitForSeconds(0.1f);
			LogChemistryStationIngredientTransforms(station, seq, "Begin+0.1s");
			yield return (object)new WaitForSeconds(0.4f);
			LogChemistryStationIngredientTransforms(station, seq, "Begin+0.5s");
			yield return (object)new WaitForSeconds(0.5f);
			LogChemistryStationIngredientTransforms(station, seq, "Begin+1.0s");
		}

		private static StationRecipeEntry? TryGetSelectedRecipeEntry(ChemistryStationInterface canvas)
		{
			try
			{
				Type typeFromHandle = typeof(ChemistryStationInterface);
				FieldInfo field = typeFromHandle.GetField("selectedRecipe", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (field != null)
				{
					object? value = field.GetValue(canvas);
					return (StationRecipeEntry?)((value is StationRecipeEntry) ? value : null);
				}
				PropertyInfo property = typeFromHandle.GetProperty("selectedRecipe", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (property != null)
				{
					object? value2 = property.GetValue(canvas);
					return (StationRecipeEntry?)((value2 is StationRecipeEntry) ? value2 : null);
				}
				FieldInfo[] fields = typeFromHandle.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				FieldInfo[] array = fields;
				foreach (FieldInfo fieldInfo in array)
				{
					if (!(fieldInfo.FieldType != typeof(StationRecipeEntry)) && !(fieldInfo.Name == "RecipeEntryPrefab") && !(fieldInfo.Name == "InProgressRecipeEntry"))
					{
						object? value3 = fieldInfo.GetValue(canvas);
						StationRecipeEntry val = (StationRecipeEntry)((value3 is StationRecipeEntry) ? value3 : null);
						if ((Object)(object)((val != null) ? val.Recipe : null) != (Object)null)
						{
							return val;
						}
					}
				}
			}
			catch
			{
			}
			return null;
		}

		private static string SafeGetRecipeEntryTitle(StationRecipeEntry? entry)
		{
			try
			{
				return ((Object)(object)((entry != null) ? entry.TitleLabel : null) == (Object)null) ? "<null>" : (((TMP_Text)entry.TitleLabel).text ?? "<null>");
			}
			catch
			{
				return "<error>";
			}
		}

		private static bool SafeGetBeginInteractable(ChemistryStationInterface canvas)
		{
			try
			{
				return (Object)(object)canvas.BeginButton != (Object)null && ((Selectable)canvas.BeginButton).interactable;
			}
			catch
			{
				return false;
			}
		}

		private static string SafeGetProductId(StationRecipe? recipe)
		{
			try
			{
				object obj;
				if (recipe == null)
				{
					obj = null;
				}
				else
				{
					ItemQuantity product = recipe.Product;
					if (product == null)
					{
						obj = null;
					}
					else
					{
						ItemDefinition item = product.Item;
						obj = ((item != null) ? ((BaseItemDefinition)item).ID : null);
					}
				}
				if (obj == null)
				{
					obj = "<null>";
				}
				return (string)obj;
			}
			catch
			{
				return "<error>";
			}
		}

		private static string SafeGetStationRecipeId(StationRecipe recipe)
		{
			try
			{
				return recipe.RecipeID ?? "<null>";
			}
			catch
			{
				return "<error>";
			}
		}

		private static void CreateSuperGrowRecipe()
		{
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Expected O, but got Unknown
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Expected O, but got Unknown
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Expected O, but got Unknown
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Expected O, but got Unknown
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			ItemDefinition item = Registry.GetItem("pgr");
			ItemDefinition item2 = Registry.GetItem("speedgrow");
			ItemDefinition item3 = Registry.GetItem("fertilizer");
			ItemDefinition item4 = Registry.GetItem("supergrow");
			if ((Object)(object)item == (Object)null || (Object)(object)item2 == (Object)null || (Object)(object)item3 == (Object)null)
			{
				MelonLogger.Error("Could not find one or more base additive definitions");
				return;
			}
			if ((Object)(object)item4 == (Object)null)
			{
				SuperGrowCreator.CreateSuperGrowItem();
				item4 = Registry.GetItem("supergrow");
				if ((Object)(object)item4 == (Object)null)
				{
					MelonLogger.Warning("Could not find SuperGrow definition; will retry when registry is ready");
					return;
				}
			}
			_superGrowRecipe = ScriptableObject.CreateInstance<StationRecipe>();
			_superGrowRecipe.IsDiscovered = true;
			_superGrowRecipe.RecipeTitle = "SuperGrow";
			_superGrowRecipe.CookTime_Mins = SuperGrowSettings.CookTimeMinutes.Value;
			_superGrowRecipe.Unlocked = true;
			List<IngredientQuantity> val = new List<IngredientQuantity>();
			IngredientQuantity val2 = new IngredientQuantity();
			List<ItemDefinition> val3 = new List<ItemDefinition>();
			val3.Add(item);
			val2.Items = val3;
			val2.Quantity = SuperGrowSettings.PgrRequired.Value;
			val.Add(val2);
			IngredientQuantity val4 = new IngredientQuantity();
			List<ItemDefinition> val5 = new List<ItemDefinition>();
			val5.Add(item2);
			val4.Items = val5;
			val4.Quantity = SuperGrowSettings.SpeedGrowRequired.Value;
			val.Add(val4);
			IngredientQuantity val6 = new IngredientQuantity();
			List<ItemDefinition> val7 = new List<ItemDefinition>();
			val7.Add(item3);
			val6.Items = val7;
			val6.Quantity = SuperGrowSettings.FertilizerRequired.Value;
			val.Add(val6);
			_superGrowRecipe.Ingredients = val;
			_superGrowRecipe.Product = new ItemQuantity
			{
				Item = item4,
				Quantity = SuperGrowSettings.OutputQuantity.Value
			};
			_superGrowRecipe.FinalLiquidColor = SuperGrowVisuals.PourColor;
		}

		private static bool TryGetStationItemTemplate(out StationItem templateStationItem)
		{
			templateStationItem = null;
			string[] array = new string[4] { "acid", "pgr", "speedgrow", "fertilizer" };
			string[] array2 = array;
			foreach (string text in array2)
			{
				ItemDefinition item = Registry.GetItem(text);
				StorableItemDefinition val = ((item != null) ? ((Il2CppObjectBase)item).TryCast<StorableItemDefinition>() : null);
				if ((Object)(object)((val != null) ? val.StationItem : null) != (Object)null)
				{
					templateStationItem = val.StationItem;
					return true;
				}
			}
			if (!_loggedMissingStationItemTemplate)
			{
				_loggedMissingStationItemTemplate = true;
				MelonLogger.Warning("Could not find any StationItem template (acid/pgr/speedgrow/fertilizer)");
				string[] array3 = array;
				foreach (string text2 in array3)
				{
					ItemDefinition item2 = Registry.GetItem(text2);
					StorableItemDefinition val2 = ((item2 != null) ? ((Il2CppObjectBase)item2).TryCast<StorableItemDefinition>() : null);
					MelonLogger.Warning($"{text2}: def={(((Object)(object)val2 == (Object)null) ? "<null>" : ((object)val2).GetType().FullName)} stationItem={(((Object)(object)((val2 != null) ? val2.StationItem : null) == (Object)null) ? "<null>" : ((object)val2.StationItem).GetType().FullName)}");
				}
			}
			return false;
		}

		[HarmonyPatch(typeof(Registry), "Start")]
		[HarmonyPostfix]
		private static void Registry_Start_Postfix()
		{
			if (_loggedRegistryStart)
			{
				return;
			}
			_loggedRegistryStart = true;
			try
			{
				SuperGrowCreator.CreateSuperGrowItem();
				EnsureAdditiveStationItemPrefabs();
			}
			catch (Exception ex)
			{
				MelonLogger.Error("Registry.Start hook failed: " + ex.Message);
				MelonLogger.Error(ex.StackTrace ?? "<no stack trace>");
			}
		}

		public static void SetupAdditiveStationItems()
		{
			if (_additivesPatched)
			{
				return;
			}
			try
			{
				CachePourablePrefab("pgr", "growing/pgr/PGR_Pourable");
				CachePourablePrefab("speedgrow", "growing/speedgrow/SpeedGrow_Pourable");
				CachePourablePrefab("fertilizer", "growing/fertilizer/Fertilizer_Pourable");
				if (EnsureAdditiveStationItemPrefabs())
				{
					_additivesPatched = true;
					MelonLogger.Msg("Set up StationItem on base additives for chemistry station compatibility");
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Error("Failed to set up additive StationItems: " + ex.Message);
				MelonLogger.Error(ex.StackTrace);
			}
		}

		[HarmonyPatch(typeof(StoredItem), "InitializeStoredItem")]
		[HarmonyPostfix]
		private static void StoredItem_InitializeStoredItem_Postfix(StoredItem __instance, StorableItemInstance _item)
		{
			try
			{
				object obj;
				if (_item == null)
				{
					obj = null;
				}
				else
				{
					ItemDefinition definition = ((ItemInstance)_item).Definition;
					obj = ((definition != null) ? ((BaseItemDefinition)definition).ID : null);
				}
				string text = (string)obj;
				if (!(text != "supergrow"))
				{
					ApplySuperGrowMaterialsToRenderers(Il2CppArrayBase<Renderer>.op_Implicit(((Component)__instance).GetComponentsInChildren<Renderer>(true)));
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Error("Failed to apply SuperGrow visuals to stored item: " + ex.Message);
				MelonLogger.Error(ex.StackTrace ?? "<no stack trace>");
			}
		}

		private static void SetPendingStationTrashReskins(List<PendingTrashReskin> reskins)
		{
			_pendingStationTrashReskins.Clear();
			if (reskins.Count > 0)
			{
				_pendingStationTrashReskins.AddRange(reskins);
				_pendingStationTrashReskinExpireTick = Environment.TickCount + 5000;
			}
			else
			{
				_pendingStationTrashReskinExpireTick = 0;
			}
		}

		[HarmonyPatch(typeof(ChemistryStation), "CreateTrash")]
		[HarmonyPrefix]
		private static void ChemistryStation_CreateTrash_Prefix(ChemistryStation __instance, List<StationItem> mixerItems)
		{
			try
			{
				if (mixerItems == null)
				{
					return;
				}
				List<PendingTrashReskin> list = new List<PendingTrashReskin>();
				for (int i = 0; i < mixerItems.Count; i++)
				{
					StationItem val = mixerItems[i];
					if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).gameObject == (Object)null)
					{
						continue;
					}
					string text = TryParseAdditiveIdFromStationItemName(((Object)((Component)val).gameObject).name);
					if (text != null)
					{
						string text2 = (((Object)(object)val.TrashPrefab != (Object)null) ? val.TrashPrefab.ID : null);
						if (!string.IsNullOrEmpty(text2))
						{
							list.Add(new PendingTrashReskin(text2, text));
						}
					}
				}
				SetPendingStationTrashReskins(list);
			}
			catch
			{
			}
		}

		private static string? TryParseAdditiveIdFromStationItemName(string? stationItemName)
		{
			if (string.IsNullOrEmpty(stationItemName))
			{
				return null;
			}
			int num = stationItemName.IndexOf("SuperGrow_StationItemPrefab_", StringComparison.OrdinalIgnoreCase);
			if (num < 0)
			{
				return null;
			}
			num += "SuperGrow_StationItemPrefab_".Length;
			if (num >= stationItemName.Length)
			{
				return null;
			}
			int num2 = stationItemName.IndexOf('(', num);
			if (num2 < 0)
			{
				num2 = stationItemName.Length;
			}
			string text = stationItemName.Substring(num, num2 - num).Trim();
			if (text.Length == 0)
			{
				return null;
			}
			text = text.ToLowerInvariant();
			object result;
			switch (text)
			{
			default:
				result = null;
				break;
			case "pgr":
			case "speedgrow":
			case "fertilizer":
			case "supergrow":
				result = text;
				break;
			}
			return (string?)result;
		}

		[HarmonyPatch(typeof(TrashItem), "Start")]
		[HarmonyPostfix]
		private static void TrashItem_Start_Postfix(TrashItem __instance)
		{
			try
			{
				if (_pendingStationTrashReskins.Count == 0)
				{
					return;
				}
				if (_pendingStationTrashReskinExpireTick != 0 && Environment.TickCount - _pendingStationTrashReskinExpireTick >= 0)
				{
					_pendingStationTrashReskins.Clear();
					_pendingStationTrashReskinExpireTick = 0;
					return;
				}
				string iD = __instance.ID;
				if (string.IsNullOrEmpty(iD))
				{
					return;
				}
				for (int i = 0; i < _pendingStationTrashReskins.Count; i++)
				{
					PendingTrashReskin pendingTrashReskin = _pendingStationTrashReskins[i];
					if (!(pendingTrashReskin.TrashId != iD))
					{
						_pendingStationTrashReskins.RemoveAt(i);
						SwapTrashItemVisualsById(pendingTrashReskin.AdditiveId, __instance);
						break;
					}
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Error("Failed to apply SuperGrow visuals to trash item: " + ex.Message);
				MelonLogger.Error(ex.StackTrace ?? "<no stack trace>");
			}
		}

		private static bool IsChemistryBeakerFillable(Fillable fillable)
		{
			if ((Object)(object)fillable == (Object)null)
			{
				return false;
			}
			LiquidContainer liquidContainer = fillable.LiquidContainer;
			if ((Object)(object)liquidContainer == (Object)null || (Object)(object)((Component)liquidContainer).transform == (Object)null)
			{
				return false;
			}
			Transform transform = ((Component)liquidContainer).transform;
			if (!string.Equals(((Object)transform).name, "Liquid", StringComparison.OrdinalIgnoreCase))
			{
				return false;
			}
			Transform parent = transform.parent;
			if ((Object)(object)parent == (Object)null || !string.Equals(((Object)parent).name, "Beaker", StringComparison.OrdinalIgnoreCase))
			{
				return false;
			}
			Transform parent2 = parent.parent;
			if ((Object)(object)parent2 == (Object)null || !((Object)parent2).name.StartsWith("Beaker", StringComparison.OrdinalIgnoreCase))
			{
				return false;
			}
			Transform val = parent2;
			while ((Object)(object)val != (Object)null)
			{
				if (((Object)val).name != null && ((Object)val).name.IndexOf("ChemistryStation", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					return true;
				}
				val = val.parent;
			}
			return false;
		}

		private static void CachePourablePrefab(string additiveId, string pourablePath)
		{
			if (!_pourablePrefabs.ContainsKey(additiveId))
			{
				GameObject val = Resources.Load<GameObject>(pourablePath);
				if ((Object)(object)val != (Object)null)
				{
					_pourablePrefabs[additiveId] = val;
					MelonLogger.Msg("Cached pourable prefab for " + additiveId);
				}
				else
				{
					MelonLogger.Warning("Could not load pourable prefab for " + additiveId + " at " + pourablePath);
				}
			}
		}

		private static Transform? FindStationItemBottleContainer(StationItem stationItem)
		{
			Transform val = ((Component)stationItem).transform.Find("Pourable");
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			Transform result = null;
			int childCount = val.childCount;
			for (int i = 0; i < childCount; i++)
			{
				Transform child = val.GetChild(i);
				if ((Object)(object)child != (Object)null && ((Object)child).name.IndexOf("Bottle", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					result = child;
					break;
				}
			}
			return result;
		}

		private static void SwapBottleMeshesAndMaterials(GameObject templatePrefab, Transform targetRoot)
		{
			Il2CppArrayBase<MeshFilter> componentsInChildren = templatePrefab.GetComponentsInChildren<MeshFilter>(true);
			Il2CppArrayBase<MeshFilter> componentsInChildren2 = ((Component)targetRoot).GetComponentsInChildren<MeshFilter>(true);
			foreach (MeshFilter item in componentsInChildren2)
			{
				if ((Object)(object)item == (Object)null)
				{
					continue;
				}
				string text = ((Object)item).name.ToLowerInvariant();
				foreach (MeshFilter item2 in componentsInChildren)
				{
					if ((Object)(object)item2 == (Object)null)
					{
						continue;
					}
					string text2 = ((Object)item2).name.ToLowerInvariant();
					if ((!text.Contains("body") || !text2.Contains("body")) && (!text.Contains("label") || !text2.Contains("label")) && (!text.Contains("lid") || !text2.Contains("lid")))
					{
						continue;
					}
					item.sharedMesh = item2.sharedMesh;
					MeshRenderer component = ((Component)item).GetComponent<MeshRenderer>();
					MeshRenderer component2 = ((Component)item2).GetComponent<MeshRenderer>();
					if ((Object)(object)component != (Object)null && (Object)(object)component2 != (Object)null)
					{
						((Renderer)component).sharedMaterials = ((Renderer)component2).sharedMaterials;
					}
					break;
				}
			}
		}

		private static void ApplySuperGrowMaterialsToRenderers(Renderer[]? renderers)
		{
			SuperGrowVisuals.ApplySuperGrowMaterialsToRenderers(renderers);
		}

		private static void SetupAdditiveStationItem(string additiveId, StationItem templateStationItem)
		{
			ItemDefinition item = Registry.GetItem(additiveId);
			StorableItemDefinition val = ((item != null) ? ((Il2CppObjectBase)item).TryCast<StorableItemDefinition>() : null);
			if ((Object)(object)val == (Object)null)
			{
				MelonLogger.Warning("Could not find additive: " + additiveId);
			}
			else if (!((Object)(object)val.StationItem != (Object)null))
			{
				val.StationItem = templateStationItem;
			}
		}

		private static void SwapTrashItemVisualsById(string id, TrashItem trashItem)
		{
			if ((Object)(object)trashItem == (Object)null || string.IsNullOrEmpty(id))
			{
				return;
			}
			bool flag = id == "supergrow";
			if (!flag && id != "pgr" && id != "speedgrow" && id != "fertilizer")
			{
				return;
			}
			GameObject value = null;
			if (flag)
			{
				_pourablePrefabs.TryGetValue("pgr", out value);
			}
			else
			{
				_pourablePrefabs.TryGetValue(id, out value);
			}
			if ((Object)(object)value == (Object)null)
			{
				return;
			}
			try
			{
				if (!((Object)(object)((Component)trashItem).transform == (Object)null))
				{
					SwapBottleMeshesAndMaterials(value, ((Component)trashItem).transform);
					if (flag)
					{
						ApplySuperGrowMaterialsToRenderers(Il2CppArrayBase<Renderer>.op_Implicit(((Component)trashItem).GetComponentsInChildren<Renderer>(true)));
					}
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Error("Failed to swap trash visuals for " + id + ": " + ex.Message);
				MelonLogger.Error(ex.StackTrace);
			}
		}

		private static void SwapStationItemVisualsById(string id, StationItem stationItem)
		{
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)stationItem == (Object)null || string.IsNullOrEmpty(id))
			{
				return;
			}
			bool flag = id == "supergrow";
			if (!flag && id != "pgr" && id != "speedgrow" && id != "fertilizer")
			{
				return;
			}
			GameObject value = null;
			if (flag)
			{
				_pourablePrefabs.TryGetValue("pgr", out value);
			}
			else
			{
				_pourablePrefabs.TryGetValue(id, out value);
			}
			if ((Object)(object)value == (Object)null)
			{
				return;
			}
			try
			{
				Transform val = FindStationItemBottleContainer(stationItem);
				if ((Object)(object)val == (Object)null)
				{
					return;
				}
				SwapBottleMeshesAndMaterials(value, val);
				if (flag)
				{
					ApplySuperGrowMaterialsToRenderers(Il2CppArrayBase<Renderer>.op_Implicit(((Component)val).GetComponentsInChildren<Renderer>(true)));
				}
				object obj;
				if (!((Object)(object)((Component)stationItem).transform != (Object)null))
				{
					obj = null;
				}
				else
				{
					Transform obj2 = ((Component)stationItem).transform.Find("Pourable");
					obj = ((obj2 != null) ? ((Component)obj2).GetComponent<PourableModule>() : null);
				}
				PourableModule val2 = (PourableModule)obj;
				if ((Object)(object)val2 != (Object)null && (Object)(object)val2.LiquidContainer != (Object)null)
				{
					LiquidContainer liquidContainer = val2.LiquidContainer;
					if ((Object)(object)liquidContainer.LiquidVolume != (Object)null)
					{
						Transform transform = ((Component)liquidContainer.LiquidVolume).transform;
						transform.localScale *= 0.65f;
					}
					liquidContainer.MaxLevel *= 0.65f;
					if (_additiveColors.TryGetValue(id, out var value2))
					{
						val2.LiquidType = id;
						val2.LiquidColor = value2;
						val2.PourParticlesColor = value2;
					}
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Error("Failed to swap station item visuals for " + id + ": " + ex.Message);
				MelonLogger.Error(ex.StackTrace);
			}
		}

		private static void SwapStationItemVisualsById(string id, StationItem stationItem, StorableItemDefinition itemDef)
		{
			if (!((Object)(object)stationItem == (Object)null) && !((Object)(object)itemDef == (Object)null))
			{
				SwapStationItemVisualsById(id, stationItem);
			}
		}
	}
	[HarmonyPatch]
	internal static class GrowContainerPatches
	{
		private static readonly string[] SuperGrowSupersededAdditiveIds = new string[3] { "pgr", "speedgrow", "fertilizer" };

		private const string SuperGrowBottleTrashId = "supergrow_bottle";

		private static bool _loggedGrowContainerTrashPrefabAssignException;

		private static readonly Vector3 HiddenPrefabPosition = new Vector3(100000f, 100000f, 100000f);

		private static Pourable? _superGrowPourablePrefab;

		private const int MaxTaskLogs = 50;

		private const int MaxTrashLogs = 200;

		private const int TrashLogWindowSize = 40;

		private 

SuperGrow_Mono.dll

Decompiled 15 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using HarmonyLib;
using MelonLoader;
using MelonLoader.Preferences;
using Microsoft.CodeAnalysis;
using ScheduleOne;
using ScheduleOne.Core.Items.Framework;
using ScheduleOne.DevUtilities;
using ScheduleOne.Equipping;
using ScheduleOne.Growing;
using ScheduleOne.ItemFramework;
using ScheduleOne.ObjectScripts;
using ScheduleOne.PlayerScripts;
using ScheduleOne.PlayerTasks;
using ScheduleOne.PlayerTasks.Tasks;
using ScheduleOne.StationFramework;
using ScheduleOne.Storage;
using ScheduleOne.Trash;
using ScheduleOne.UI.Stations;
using SuperGrow;
using SuperGrow.Features;
using SuperGrow.Patches;
using SuperGrow.Utils;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: MelonInfo(typeof(Core), "SuperGrow", "1.3.4", "HazDS", null)]
[assembly: MelonGame("TVGS", "Schedule I")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("SuperGrow")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+22bbaa0cd7f8c88418ee8cc3f9785971198326d8")]
[assembly: AssemblyProduct("SuperGrow")]
[assembly: AssemblyTitle("SuperGrow")]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace SuperGrow
{
	internal static class SuperGrowSettings
	{
		private static bool _initialized;

		private static MelonPreferences_Category? _prefsCategory;

		public static MelonPreferences_Entry<int> PgrRequired { get; private set; }

		public static MelonPreferences_Entry<int> SpeedGrowRequired { get; private set; }

		public static MelonPreferences_Entry<int> FertilizerRequired { get; private set; }

		public static MelonPreferences_Entry<int> OutputQuantity { get; private set; }

		public static MelonPreferences_Entry<int> CookTimeMinutes { get; private set; }

		public static MelonPreferences_Entry<float> YieldMultiplier { get; private set; }

		public static MelonPreferences_Entry<float> InstantGrowth { get; private set; }

		public static MelonPreferences_Entry<float> QualityChange { get; private set; }

		public static void Initialize()
		{
			if (!_initialized)
			{
				_prefsCategory = MelonPreferences.CreateCategory("SuperGrow", "SuperGrow Settings");
				PgrRequired = _prefsCategory.CreateEntry<int>("PgrRequired", 1, "PGR Required", "Amount of PGR needed per craft", false, false, (ValueValidator)null, (string)null);
				SpeedGrowRequired = _prefsCategory.CreateEntry<int>("SpeedGrowRequired", 1, "Speed Grow Required", "Amount of Speed Grow needed per craft", false, false, (ValueValidator)null, (string)null);
				FertilizerRequired = _prefsCategory.CreateEntry<int>("FertilizerRequired", 1, "Fertilizer Required", "Amount of Fertilizer needed per craft", false, false, (ValueValidator)null, (string)null);
				OutputQuantity = _prefsCategory.CreateEntry<int>("OutputQuantity", 3, "Output Quantity", "Amount of SuperGrow produced per craft", false, false, (ValueValidator)null, (string)null);
				CookTimeMinutes = _prefsCategory.CreateEntry<int>("CookTimeMinutes", 30, "Cook Time (Minutes)", "Chemistry Station cook time in in-game minutes", false, false, (ValueValidator)null, (string)null);
				YieldMultiplier = _prefsCategory.CreateEntry<float>("YieldMultiplier", 1.5f, "Yield Multiplier", "Yield multiplier applied to plants (1.5 = 50% more yield)", false, false, (ValueValidator)null, (string)null);
				InstantGrowth = _prefsCategory.CreateEntry<float>("InstantGrowth", 0.5f, "Instant Growth", "Instant growth progress (0.5 = 50% instant growth)", false, false, (ValueValidator)null, (string)null);
				QualityChange = _prefsCategory.CreateEntry<float>("QualityChange", 1f, "Quality Change", "Quality modifier applied to plants", false, false, (ValueValidator)null, (string)null);
				Clamp(PgrRequired, 1, 10);
				Clamp(SpeedGrowRequired, 1, 10);
				Clamp(FertilizerRequired, 1, 10);
				Clamp(OutputQuantity, 1, 10);
				Clamp(CookTimeMinutes, 1, 240);
				Clamp(YieldMultiplier, 0.1f, 10f);
				Clamp(InstantGrowth, 0f, 1f);
				Clamp(QualityChange, -1f, 1f);
				_initialized = true;
			}
		}

		private static void Clamp(MelonPreferences_Entry<int> entry, int min, int max)
		{
			if (entry.Value < min)
			{
				entry.Value = min;
			}
			if (entry.Value > max)
			{
				entry.Value = max;
			}
		}

		private static void Clamp(MelonPreferences_Entry<float> entry, float min, float max)
		{
			if (entry.Value < min)
			{
				entry.Value = min;
			}
			if (entry.Value > max)
			{
				entry.Value = max;
			}
		}
	}
	public class Core : MelonMod
	{
		private bool _itemsInitialized;

		private int _nextInitAttemptTick;

		private const int InitAttemptIntervalMs = 250;

		public static Core Instance { get; private set; }

		public override void OnInitializeMelon()
		{
			Instance = this;
			SuperGrowSettings.Initialize();
			MelonLogger.Msg("[SuperGrow v1.3.4] Initialized.");
		}

		public override void OnSceneWasLoaded(int buildIndex, string sceneName)
		{
			if (sceneName == "Menu")
			{
				_itemsInitialized = false;
				_nextInitAttemptTick = 0;
				ChemistryStationPatches.Reset();
			}
		}

		public override void OnUpdate()
		{
			ChemistryStationPatches.DumpStationItemInitializePatchesOnce("OnUpdate");
			if (_itemsInitialized && (Object)(object)Registry.GetItem("supergrow") != (Object)null)
			{
				return;
			}
			if ((Object)(object)Registry.GetItem("supergrow") != (Object)null)
			{
				_itemsInitialized = true;
			}
			else if (ShouldAttemptInitNow())
			{
				_itemsInitialized = false;
				if (SuperGrowWorldState.IsRegistryReady())
				{
					SuperGrowCreator.CreateSuperGrowItem();
					_itemsInitialized = (Object)(object)Registry.GetItem("supergrow") != (Object)null;
				}
			}
		}

		private bool ShouldAttemptInitNow()
		{
			int tickCount = Environment.TickCount;
			if (tickCount - _nextInitAttemptTick < 0)
			{
				return false;
			}
			_nextInitAttemptTick = tickCount + 250;
			return true;
		}
	}
	internal static class SuperGrowAssets
	{
		private const string IconResourceName = "SuperGrow.Assets.SuperGrow_Icon.png";

		private const string LabelResourceName = "SuperGrow.Assets.SuperGrow_Label.png";

		private static Sprite? _icon;

		private static Texture2D? _labelTexture;

		private static bool _loggedIconLoadException;

		private static bool _loggedLabelLoadException;

		private static bool _loggedImageLoadException;

		public static Sprite? GetIconSprite()
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Expected O, but got Unknown
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_icon != (Object)null)
			{
				return _icon;
			}
			try
			{
				byte[] array = LoadEmbeddedResourceBytes("SuperGrow.Assets.SuperGrow_Icon.png");
				if (array == null)
				{
					return null;
				}
				Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
				if (!TryLoadImage(val, array))
				{
					MelonLogger.Warning("Failed to decode SuperGrow.Assets.SuperGrow_Icon.png");
					return null;
				}
				((Object)val).name = "SuperGrow_Icon";
				_icon = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f);
				return _icon;
			}
			catch (Exception ex)
			{
				if (!_loggedIconLoadException)
				{
					_loggedIconLoadException = true;
					MelonLogger.Warning("Failed to load icon: " + ex.Message);
					MelonLogger.Warning(ex.StackTrace ?? "<no stack trace>");
				}
				return null;
			}
		}

		public static Texture2D? GetLabelTexture()
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Expected O, but got Unknown
			if ((Object)(object)_labelTexture != (Object)null)
			{
				return _labelTexture;
			}
			try
			{
				byte[] array = LoadEmbeddedResourceBytes("SuperGrow.Assets.SuperGrow_Label.png");
				if (array == null)
				{
					return null;
				}
				_labelTexture = new Texture2D(2, 2, (TextureFormat)4, false);
				if (!TryLoadImage(_labelTexture, array))
				{
					MelonLogger.Warning("Failed to decode SuperGrow.Assets.SuperGrow_Label.png");
					_labelTexture = null;
					return null;
				}
				((Object)_labelTexture).name = "SuperGrow_Label";
				return _labelTexture;
			}
			catch (Exception ex)
			{
				if (!_loggedLabelLoadException)
				{
					_loggedLabelLoadException = true;
					MelonLogger.Error("Failed to load SuperGrow label texture: " + ex.Message);
					MelonLogger.Error(ex.StackTrace ?? "<no stack trace>");
				}
				_labelTexture = null;
				return null;
			}
		}

		private static byte[]? LoadEmbeddedResourceBytes(string resourceName)
		{
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			using Stream stream = executingAssembly.GetManifestResourceStream(resourceName);
			if (stream == null)
			{
				MelonLogger.Warning("Could not find embedded resource: " + resourceName);
				return null;
			}
			using MemoryStream memoryStream = new MemoryStream();
			stream.CopyTo(memoryStream);
			return memoryStream.ToArray();
		}

		private static bool TryLoadImage(Texture2D texture, byte[] bytes)
		{
			try
			{
				Type type = Type.GetType("UnityEngine.ImageConversion, UnityEngine.ImageConversionModule") ?? typeof(Texture2D).Assembly.GetType("UnityEngine.ImageConversion");
				if (type == null)
				{
					return false;
				}
				MethodInfo[] methods = type.GetMethods(BindingFlags.Static | BindingFlags.Public);
				MethodInfo[] array = methods;
				bool flag = default(bool);
				foreach (MethodInfo methodInfo in array)
				{
					if (methodInfo.Name != "LoadImage")
					{
						continue;
					}
					ParameterInfo[] parameters = methodInfo.GetParameters();
					if ((parameters.Length != 2 && parameters.Length != 3) || parameters[0].ParameterType != typeof(Texture2D))
					{
						continue;
					}
					Type parameterType = parameters[1].ParameterType;
					if (parameterType == typeof(byte[]))
					{
						object obj = ((parameters.Length != 3) ? methodInfo.Invoke(null, new object[2] { texture, bytes }) : methodInfo.Invoke(null, new object[3] { texture, bytes, false }));
						int num;
						if (obj is bool)
						{
							flag = (bool)obj;
							num = 1;
						}
						else
						{
							num = 0;
						}
						return (byte)((uint)num & (flag ? 1u : 0u)) != 0;
					}
				}
				return false;
			}
			catch (Exception ex)
			{
				if (!_loggedImageLoadException)
				{
					_loggedImageLoadException = true;
					MelonLogger.Warning("Failed to decode embedded image bytes via ImageConversion.LoadImage: " + ex.Message);
					MelonLogger.Warning(ex.StackTrace ?? "<no stack trace>");
				}
				return false;
			}
		}
	}
	internal static class SuperGrowWorldState
	{
		private static bool _loggedReady;

		private static bool _ready;

		private static bool _loggedRegistryReadyException;

		public static bool IsRegistryReady()
		{
			try
			{
				if (_ready)
				{
					return true;
				}
				ItemDefinition item = Registry.GetItem("pgr");
				AdditiveDefinition val = (AdditiveDefinition)(object)((item is AdditiveDefinition) ? item : null);
				ItemDefinition item2 = Registry.GetItem("speedgrow");
				AdditiveDefinition val2 = (AdditiveDefinition)(object)((item2 is AdditiveDefinition) ? item2 : null);
				ItemDefinition item3 = Registry.GetItem("fertilizer");
				AdditiveDefinition val3 = (AdditiveDefinition)(object)((item3 is AdditiveDefinition) ? item3 : null);
				if ((Object)(object)val == (Object)null && (Object)(object)val2 == (Object)null && (Object)(object)val3 == (Object)null)
				{
					return false;
				}
				_ready = true;
				if (!_loggedReady)
				{
					_loggedReady = true;
					MelonLogger.Msg("Registry appears ready; initializing item.");
				}
				return true;
			}
			catch (Exception ex)
			{
				if (!_loggedRegistryReadyException)
				{
					_loggedRegistryReadyException = true;
					MelonLogger.Warning("Registry readiness check failed: " + ex.Message);
					MelonLogger.Warning(ex.StackTrace ?? "<no stack trace>");
				}
				return false;
			}
		}
	}
}
namespace SuperGrow.Utils
{
	public static class Constants
	{
		public static class Game
		{
			public const string GAME_STUDIO = "TVGS";

			public const string GAME_NAME = "Schedule I";
		}

		public static class Additives
		{
			public const string PGR = "pgr";

			public const string SPEED_GROW = "speedgrow";

			public const string FERTILIZER = "fertilizer";
		}

		public static class ItemIds
		{
			public const string SUPER_GROW = "supergrow";
		}

		public static class DefaultEffects
		{
			public const float YIELD_MULTIPLIER = 1.5f;

			public const float INSTANT_GROWTH = 0.5f;

			public const float QUALITY_CHANGE = 1f;
		}

		public const string MOD_NAME = "SuperGrow";

		public const string MOD_VERSION = "1.3.4";

		public const string MOD_AUTHOR = "HazDS";

		public const string PREFERENCES_CATEGORY = "SuperGrow";
	}
	internal static class SuperGrowVisuals
	{
		internal static readonly Color PourColor = new Color(0.4f, 0.2f, 0.6f, 1f);

		internal static readonly Color LidTint = new Color(0.6f, 0.4f, 0.8f, 1f);

		internal static void ApplySuperGrowMaterialsToRenderers(Renderer[]? renderers)
		{
			//IL_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_0246: Unknown result type (might be due to invalid IL or missing references)
			//IL_026c: Unknown result type (might be due to invalid IL or missing references)
			if (renderers == null)
			{
				return;
			}
			Texture2D labelTexture = SuperGrowAssets.GetLabelTexture();
			if ((Object)(object)labelTexture == (Object)null)
			{
				MelonLogger.Warning("SuperGrow label texture is null, cannot apply");
				return;
			}
			try
			{
				foreach (Renderer val in renderers)
				{
					if ((Object)(object)val == (Object)null)
					{
						continue;
					}
					string text = ((Object)val).name.ToLowerInvariant();
					bool flag = text.Contains("label");
					if (!flag)
					{
						Material[] sharedMaterials = val.sharedMaterials;
						foreach (Material val2 in sharedMaterials)
						{
							if ((Object)(object)val2 != (Object)null && ((Object)val2).name.ToLowerInvariant().Contains("label"))
							{
								flag = true;
								break;
							}
						}
					}
					bool flag2 = text.Contains("lid");
					if (!flag2)
					{
						Material[] sharedMaterials2 = val.sharedMaterials;
						foreach (Material val3 in sharedMaterials2)
						{
							if ((Object)(object)val3 != (Object)null && ((Object)val3).name.ToLowerInvariant().Contains("lid"))
							{
								flag2 = true;
								break;
							}
						}
					}
					if (flag)
					{
						Material[] materials = val.materials;
						foreach (Material val4 in materials)
						{
							if (!((Object)(object)val4 == (Object)null))
							{
								val4.mainTexture = (Texture)(object)labelTexture;
								if (val4.HasProperty("_BaseMap"))
								{
									val4.SetTexture("_BaseMap", (Texture)(object)labelTexture);
								}
								if (val4.HasProperty("_MainTex"))
								{
									val4.SetTexture("_MainTex", (Texture)(object)labelTexture);
								}
							}
						}
						val.materials = materials;
					}
					else
					{
						if (!flag2)
						{
							continue;
						}
						Material[] materials2 = val.materials;
						foreach (Material val5 in materials2)
						{
							if (!((Object)(object)val5 == (Object)null))
							{
								val5.color = LidTint;
								if (val5.HasProperty("_BaseColor"))
								{
									val5.SetColor("_BaseColor", LidTint);
								}
								if (val5.HasProperty("_Color"))
								{
									val5.SetColor("_Color", LidTint);
								}
							}
						}
						val.materials = materials2;
					}
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Error("Failed to apply SuperGrow materials: " + ex.Message);
				MelonLogger.Error(ex.StackTrace);
			}
		}
	}
}
namespace SuperGrow.Patches
{
	[HarmonyPatch]
	internal static class ChemistryStationPatches
	{
		private readonly struct PendingTrashReskin
		{
			public string TrashId { get; }

			public string AdditiveId { get; }

			public PendingTrashReskin(string trashId, string additiveId)
			{
				TrashId = trashId;
				AdditiveId = additiveId;
			}
		}

		private static StationRecipe? _superGrowRecipe;

		private static bool _additivesPatched;

		private static bool _loggedMissingStationItemTemplate;

		private static bool _loggedRegistryStart;

		private static bool _loggedRecipeNotReady;

		private static int _superGrowBeginAuditUntilTick;

		private static int _superGrowBeginAuditSeq;

		private static ChemistryStation? _superGrowBeginStation;

		private static int _superGrowBeginStationSeq;

		private static string? _lastSelectedRecipeProductId;

		private static string? _lastSelectedRecipeTitle;

		private static string? _lastSelectedRecipeId;

		private static int _lastSelectedAtTick;

		private static bool _stationItemInitializePatchInfoDumped;

		private static readonly Dictionary<int, int> _chemCanvasDumpMaskByInstanceId = new Dictionary<int, int>();

		private const int TrashAuditWindowMs = 60000;

		private const int TrashAuditMaxLogs = 50;

		private static int _trashAuditUntilTick;

		private static int _trashAuditSeq;

		private static int _trashAuditTrashManagerLogged;

		private static int _trashAuditGetTrashPrefabLogged;

		private static int _trashAuditTrashItemStartLogged;

		private static bool _trashAuditHasStationPos;

		private static Vector3 _trashAuditStationPos;

		private static readonly HashSet<string> _trashAuditSeenTrashIds = new HashSet<string>();

		private static readonly HashSet<string> _trashAuditSeenGetTrashPrefabIds = new HashSet<string>();

		private static bool _trashAuditTrashPrefabsDumped;

		private static TrashManager? _trashAuditManager;

		private const int BeakerAuditWindowMs = 30000;

		private const int BeakerAuditMaxLogs = 80;

		private const float BeakerAuditMinLoggedLevelDelta = 0.05f;

		private const float BeakerAuditLevelEdgeEpsilon = 0.01f;

		private const float BeakerAuditMinLoggedColorDelta = 0.02f;

		private const int BeakerContentsAuditMaxLogs = 120;

		private const int BeakerContentsAuditMinIntervalMs = 250;

		private const float BeakerContentsAuditMinTotalDelta = 0.02f;

		private static int _beakerAuditUntilTick;

		private static int _beakerAuditSeq;

		private static int _beakerAuditLiquidColorLogged;

		private static int _beakerAuditLiquidLevelLogged;

		private static int _beakerContentsAuditLogged;

		private static bool _beakerAuditHasStationPos;

		private static Vector3 _beakerAuditStationPos;

		private static readonly HashSet<int> _beakerAuditSeenContainerIds = new HashSet<int>();

		private static readonly HashSet<int> _beakerAuditTrackedContainerIds = new HashSet<int>();

		private static readonly Dictionary<int, float> _beakerAuditLastLoggedLevel = new Dictionary<int, float>();

		private static readonly Dictionary<int, Color> _beakerAuditLastLoggedColor = new Dictionary<int, Color>();

		private static readonly Dictionary<int, int> _beakerContentsAuditLastTickByFillableId = new Dictionary<int, int>();

		private static readonly Dictionary<int, float> _beakerContentsAuditLastTotalByFillableId = new Dictionary<int, float>();

		private static readonly Dictionary<int, string> _beakerContentsAuditLastLabelByFillableId = new Dictionary<int, string>();

		private static bool _beakerAuditExpiredLogged;

		private const int ChemCanvasDump_AwakePostfix = 1;

		private const int ChemCanvasDump_OpenPrefix = 2;

		private const int ChemCanvasDump_UiAwakePostfix = 4;

		private const int ChemCanvasDump_UiOpenPrefix = 8;

		private const string PgrBottleTrashId = "supergrow_pgr_bottle";

		private const string SpeedGrowBottleTrashId = "supergrow_speedgrow_bottle";

		private const string FertilizerBottleTrashId = "supergrow_fertilizer_bottle";

		private const string SuperGrowBottleTrashId = "supergrow_bottle";

		private static bool _monoTrashPrefabsInjected;

		private static readonly Dictionary<string, TrashItem> _monoBottleTrashPrefabByAdditiveId = new Dictionary<string, TrashItem>();

		private static bool _loggedMonoTrashPrefabInjectionException;

		private static int _pendingStationTrashReskinExpireTick;

		private static readonly List<PendingTrashReskin> _pendingStationTrashReskins = new List<PendingTrashReskin>();

		private static readonly Dictionary<string, GameObject> _pourablePrefabs = new Dictionary<string, GameObject>();

		private static readonly Dictionary<string, Color> _additiveColors = new Dictionary<string, Color>
		{
			{
				"pgr",
				new Color(1f, 0.506f, 0.506f, 1f)
			},
			{
				"speedgrow",
				new Color(0.506f, 0.812f, 1f, 1f)
			},
			{
				"fertilizer",
				new Color(0.639f, 1f, 0.506f, 1f)
			},
			{
				"supergrow",
				SuperGrowVisuals.PourColor
			}
		};

		private const float LiquidScale = 0.65f;

		public static void Reset()
		{
			_superGrowRecipe = null;
			_additivesPatched = false;
			_loggedMissingStationItemTemplate = false;
			_loggedRegistryStart = false;
			_loggedRecipeNotReady = false;
			_chemCanvasDumpMaskByInstanceId.Clear();
		}

		private static void BeginBeakerAuditWindow(int seq, ChemistryStation? station)
		{
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			_beakerAuditSeq = seq;
			_beakerAuditUntilTick = Environment.TickCount + 30000;
			_beakerAuditLiquidColorLogged = 0;
			_beakerAuditLiquidLevelLogged = 0;
			_beakerContentsAuditLogged = 0;
			_beakerAuditSeenContainerIds.Clear();
			_beakerAuditTrackedContainerIds.Clear();
			_beakerAuditLastLoggedLevel.Clear();
			_beakerAuditLastLoggedColor.Clear();
			_beakerContentsAuditLastTickByFillableId.Clear();
			_beakerContentsAuditLastTotalByFillableId.Clear();
			_beakerContentsAuditLastLabelByFillableId.Clear();
			_beakerAuditExpiredLogged = false;
			if ((Object)(object)station != (Object)null && (Object)(object)((Component)station).transform != (Object)null)
			{
				_beakerAuditHasStationPos = true;
				_beakerAuditStationPos = ((Component)station).transform.position;
			}
			else
			{
				_beakerAuditHasStationPos = false;
				_beakerAuditStationPos = Vector3.zero;
			}
			string arg = (_beakerAuditHasStationPos ? ((object)Unsafe.As<Vector3, Vector3>(ref _beakerAuditStationPos)/*cast due to .constrained prefix*/).ToString() : "<unknown>");
			MelonLogger.Msg($"SuperGrow beaker audit #{seq}: enabled for {30000}ms stationPos={arg}");
			try
			{
				if ((Object)(object)station != (Object)null)
				{
					DumpNearbyLiquidContainersOnce(station, "BeginBeakerAuditWindow");
				}
			}
			catch
			{
			}
		}

		private static bool IsBeakerAuditActive()
		{
			if (_beakerAuditUntilTick == 0)
			{
				return false;
			}
			if (Environment.TickCount - _beakerAuditUntilTick < 0)
			{
				return true;
			}
			if (!_beakerAuditExpiredLogged)
			{
				_beakerAuditExpiredLogged = true;
				try
				{
					MelonLogger.Msg($"SuperGrow beaker audit #{_beakerAuditSeq}: expired (levelLogs={_beakerAuditLiquidLevelLogged}/{80} colorLogs={_beakerAuditLiquidColorLogged}/{80} trackedIds={_beakerAuditTrackedContainerIds.Count})");
				}
				catch
				{
				}
			}
			_beakerAuditUntilTick = 0;
			return false;
		}

		private static bool IsNearBeakerAuditedStation(Vector3 position)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			if (!_beakerAuditHasStationPos)
			{
				return true;
			}
			return Vector3.Distance(position, _beakerAuditStationPos) <= 35f;
		}

		private static string GetTransformPath(Transform? transform)
		{
			if ((Object)(object)transform == (Object)null)
			{
				return "<null>";
			}
			StringBuilder stringBuilder = new StringBuilder();
			Transform val = transform;
			while ((Object)(object)val != (Object)null)
			{
				stringBuilder.Insert(0, "/" + ((Object)val).name);
				val = val.parent;
			}
			return (stringBuilder.Length == 0) ? "<empty>" : stringBuilder.ToString();
		}

		private static bool ShouldTrackLiquidContainer(string goName, string path)
		{
			if (goName == "Liquid" && path.Contains("/Beaker(") && path.EndsWith("/Beaker/Liquid"))
			{
				return true;
			}
			if (goName == "Pourable" && path.EndsWith("/Pourable") && path.Contains("/ItemContainer/"))
			{
				return true;
			}
			return false;
		}

		private static bool ColorsApproximatelyEqual(Color a, Color b)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			return Mathf.Abs(a.r - b.r) < 0.02f && Mathf.Abs(a.g - b.g) < 0.02f && Mathf.Abs(a.b - b.b) < 0.02f && Mathf.Abs(a.a - b.a) < 0.02f;
		}

		private static void DumpNearbyLiquidContainersOnce(ChemistryStation station, string reason)
		{
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				LiquidContainer[] componentsInChildren = ((Component)station).GetComponentsInChildren<LiquidContainer>(true);
				if (componentsInChildren == null || componentsInChildren.Length == 0)
				{
					MelonLogger.Msg($"SuperGrow beaker audit #{_beakerAuditSeq}: no LiquidContainers found ({reason})");
					return;
				}
				MelonLogger.Msg($"SuperGrow beaker audit #{_beakerAuditSeq}: LiquidContainers near station ({reason}) count={componentsInChildren.Length}");
				int num = 0;
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					if (num >= 25)
					{
						break;
					}
					LiquidContainer val = componentsInChildren[i];
					if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).gameObject == (Object)null || (Object)(object)((Component)val).transform == (Object)null)
					{
						continue;
					}
					Vector3 position = ((Component)val).transform.position;
					if (IsNearBeakerAuditedStation(position))
					{
						int instanceID = ((Object)val).GetInstanceID();
						string text = ((Object)((Component)val).gameObject).name ?? "<unnamed>";
						string transformPath = GetTransformPath(((Component)val).transform);
						string text2 = (_beakerAuditHasStationPos ? Vector3.Distance(position, _beakerAuditStationPos).ToString("0.0") : "<n/a>");
						MelonLogger.Msg($"  - containerId={instanceID} name={text} dist={text2} level={val.CurrentLiquidLevel:0.###}/{val.MaxLevel:0.###} color=({val.LiquidColor.r:0.###},{val.LiquidColor.g:0.###},{val.LiquidColor.b:0.###},{val.LiquidColor.a:0.###}) path={transformPath}");
						if (ShouldTrackLiquidContainer(text, transformPath))
						{
							_beakerAuditTrackedContainerIds.Add(instanceID);
						}
						num++;
					}
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Error("SuperGrow beaker audit: failed to dump LiquidContainers (" + reason + "): " + ex.Message);
			}
		}

		[HarmonyPatch(typeof(Fillable), "ResetContents")]
		[HarmonyPostfix]
		private static void Fillable_ResetContents_DebugPostfix(Fillable __instance)
		{
			if (!IsBeakerAuditActive() || _beakerContentsAuditLogged >= 120)
			{
				return;
			}
			try
			{
				if (!((Object)(object)__instance == (Object)null) && IsChemistryBeakerFillable(__instance))
				{
					int instanceID = ((Object)__instance).GetInstanceID();
					_beakerContentsAuditLastTickByFillableId.Remove(instanceID);
					_beakerContentsAuditLastTotalByFillableId.Remove(instanceID);
					_beakerContentsAuditLastLabelByFillableId.Remove(instanceID);
					_beakerContentsAuditLogged++;
					MelonLogger.Msg($"SuperGrow beaker audit #{_beakerAuditSeq}: Fillable.ResetContents fillableId={instanceID}");
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Error("SuperGrow beaker audit: Fillable.ResetContents logging failed: " + ex.Message);
			}
		}

		[HarmonyPatch(typeof(Fillable), "AddLiquid", new Type[]
		{
			typeof(string),
			typeof(float),
			typeof(Color)
		})]
		[HarmonyPostfix]
		private static void Fillable_AddLiquid_DebugPostfix(Fillable __instance, string label, float volume, Color color)
		{
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_0238: 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_0258: Unknown result type (might be due to invalid IL or missing references)
			//IL_0268: Unknown result type (might be due to invalid IL or missing references)
			if (!IsBeakerAuditActive() || _beakerContentsAuditLogged >= 120)
			{
				return;
			}
			try
			{
				if (!((Object)(object)__instance == (Object)null) && IsChemistryBeakerFillable(__instance))
				{
					int instanceID = ((Object)__instance).GetInstanceID();
					int tickCount = Environment.TickCount;
					float totalLiquidVolume = __instance.GetTotalLiquidVolume();
					int value;
					bool flag = _beakerContentsAuditLastTickByFillableId.TryGetValue(instanceID, out value);
					float value2;
					bool flag2 = _beakerContentsAuditLastTotalByFillableId.TryGetValue(instanceID, out value2);
					string value3;
					bool flag3 = _beakerContentsAuditLastLabelByFillableId.TryGetValue(instanceID, out value3) && string.Equals(value3, label, StringComparison.Ordinal);
					bool flag4 = flag2 && Mathf.Abs(totalLiquidVolume - value2) < 0.02f;
					bool flag5 = flag && tickCount - value < 250;
					if (!(flag3 && flag4 && flag5))
					{
						_beakerContentsAuditLastTickByFillableId[instanceID] = tickCount;
						_beakerContentsAuditLastTotalByFillableId[instanceID] = totalLiquidVolume;
						_beakerContentsAuditLastLabelByFillableId[instanceID] = label;
						float liquidVolume = __instance.GetLiquidVolume("pgr");
						float liquidVolume2 = __instance.GetLiquidVolume("speedgrow");
						float liquidVolume3 = __instance.GetLiquidVolume("fertilizer");
						float liquidVolume4 = __instance.GetLiquidVolume("supergrow");
						float num = (string.IsNullOrWhiteSpace(label) ? 0f : __instance.GetLiquidVolume(label));
						float liquidCapacity_L = __instance.LiquidCapacity_L;
						LiquidContainer liquidContainer = __instance.LiquidContainer;
						Color val = (((Object)(object)liquidContainer != (Object)null) ? liquidContainer.LiquidColor : Color.clear);
						_beakerContentsAuditLogged++;
						MelonLogger.Msg($"SuperGrow beaker audit #{_beakerAuditSeq}: Fillable.AddLiquid label={label} delta={volume:0.###} addColor=({color.r:0.###},{color.g:0.###},{color.b:0.###},{color.a:0.###}) total={totalLiquidVolume:0.###}/{liquidCapacity_L:0.###} pgr={liquidVolume:0.###} speedgrow={liquidVolume2:0.###} fertilizer={liquidVolume3:0.###} supergrow={liquidVolume4:0.###} labelVol={num:0.###} beakerColor=({val.r:0.###},{val.g:0.###},{val.b:0.###},{val.a:0.###}) fillableId={instanceID}");
					}
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Error("SuperGrow beaker audit: Fillable.AddLiquid logging failed: " + ex.Message);
			}
		}

		private static StationRecipe? GetCachedSelectedRecipe(ChemistryStationInterface canvas)
		{
			try
			{
				RectTransform recipeContainer = canvas.RecipeContainer;
				if ((Object)(object)recipeContainer == (Object)null)
				{
					return null;
				}
				StationRecipeEntry[] componentsInChildren = ((Component)recipeContainer).GetComponentsInChildren<StationRecipeEntry>(true);
				if (componentsInChildren == null || componentsInChildren.Length == 0)
				{
					return null;
				}
				foreach (StationRecipeEntry val in componentsInChildren)
				{
					if ((Object)(object)val == (Object)null)
					{
						continue;
					}
					StationRecipe recipe = val.Recipe;
					if (!((Object)(object)recipe == (Object)null))
					{
						string text = SafeGetProductId(recipe);
						if (text == "supergrow")
						{
							return recipe;
						}
					}
				}
			}
			catch
			{
			}
			return null;
		}

		private static string SafeGetItemDefinitionId(ItemDefinition? def)
		{
			try
			{
				return ((BaseItemDefinition)(def?)).ID ?? "<null>";
			}
			catch
			{
				return "<error>";
			}
		}

		private static void LogRecipeIngredients(StationRecipe? recipe, int seq)
		{
			try
			{
				if ((Object)(object)recipe == (Object)null)
				{
					MelonLogger.Msg($"SuperGrow Begin audit #{seq}: recipe=<null>");
					return;
				}
				string arg = SafeGetStationRecipeId(recipe);
				List<IngredientQuantity> ingredients = recipe.Ingredients;
				int num = ingredients?.Count ?? (-1);
				MelonLogger.Msg($"SuperGrow Begin audit #{seq}: recipeId={arg} ingredientCount={num}");
				if (ingredients == null)
				{
					return;
				}
				for (int i = 0; i < ingredients.Count; i++)
				{
					IngredientQuantity val = ingredients[i];
					if (val == null)
					{
						MelonLogger.Msg($"SuperGrow Begin audit #{seq}: ingredient[{i}]=<null>");
						continue;
					}
					int quantity = val.Quantity;
					List<ItemDefinition> items = val.Items;
					int num2 = items?.Count ?? (-1);
					string text = ((items != null && items.Count > 0) ? SafeGetItemDefinitionId(items[0]) : "<none>");
					MelonLogger.Msg($"SuperGrow Begin audit #{seq}: ingredient[{i}] qty={quantity} items={num2} first={text}");
					if (items == null)
					{
						continue;
					}
					for (int j = 0; j < items.Count; j++)
					{
						ItemDefinition val2 = items[j];
						if (!((Object)(object)val2 == (Object)null))
						{
							string arg2 = SafeGetItemDefinitionId(val2);
							LogItemDefinitionPrefabState(val2, seq, $"ingredient[{i}].items[{j}] ({arg2})");
						}
					}
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Error($"SuperGrow Begin audit #{seq}: failed to log recipe ingredients: {ex.Message}");
				MelonLogger.Error(ex.StackTrace ?? "<no stack trace>");
			}
		}

		private static void LogItemDefinitionPrefabState(ItemDefinition def, int seq, string label)
		{
			try
			{
				StorableItemDefinition val = (StorableItemDefinition)(object)((def is StorableItemDefinition) ? def : null);
				if ((Object)(object)val == (Object)null)
				{
					MelonLogger.Msg($"SuperGrow Begin audit #{seq}: {label} type={((object)def).GetType().FullName} storable=<null>");
					return;
				}
				StationItem stationItem = val.StationItem;
				StoredItem storedItem = val.StoredItem;
				Equippable equippable = def.Equippable;
				string text = (((Object)(object)stationItem == (Object)null) ? "<null>" : $"{((Object)((Component)stationItem).gameObject).name} activeSelf={((Component)stationItem).gameObject.activeSelf} modules={SafeGetStationItemModuleCount(stationItem)}");
				string text2 = (((Object)(object)storedItem == (Object)null) ? "<null>" : ((Object)storedItem).name);
				string text3 = (((Object)(object)equippable == (Object)null) ? "<null>" : ((Object)equippable).name);
				MelonLogger.Msg($"SuperGrow Begin audit #{seq}: {label} type={((object)def).GetType().FullName} stationItem={text} storedItem={text2} equippable={text3}");
			}
			catch (Exception ex)
			{
				MelonLogger.Error($"SuperGrow Begin audit #{seq}: failed to inspect {label}: {ex.Message}");
			}
		}

		private static int SafeGetStationItemModuleCount(StationItem stationItem)
		{
			try
			{
				return stationItem.Modules?.Count ?? (-1);
			}
			catch
			{
				return -1;
			}
		}

		private static void LogChemistryStationSlotState(ChemistryStation? station, int seq, string tag)
		{
			try
			{
				if ((Object)(object)station == (Object)null)
				{
					MelonLogger.Msg($"SuperGrow Begin audit #{seq} ({tag}): station=<null>");
					return;
				}
				ChemistryCookOperation currentCookOperation = station.CurrentCookOperation;
				string arg = ((currentCookOperation == null) ? "<null>" : (currentCookOperation.RecipeID ?? "<null>"));
				MelonLogger.Msg($"SuperGrow Begin audit #{seq} ({tag}): cookOpId={arg}");
				if (station.IngredientSlots != null)
				{
					for (int i = 0; i < station.IngredientSlots.Length; i++)
					{
						ItemSlot val = station.IngredientSlots[i];
						ItemInstance val2 = ((val != null) ? val.ItemInstance : null);
						ItemDefinition val3 = ((val2 != null) ? val2.Definition : null);
						string text = (((Object)(object)val3 == (Object)null) ? "<null>" : SafeGetItemDefinitionId(val3));
						int num = ((val2 != null) ? ((BaseItemInstance)val2).Quantity : 0);
						MelonLogger.Msg($"SuperGrow Begin audit #{seq} ({tag}): slot[{i}] id={text} qty={num}");
					}
				}
				else
				{
					MelonLogger.Msg($"SuperGrow Begin audit #{seq} ({tag}): IngredientSlots=<null>");
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Error($"SuperGrow Begin audit #{seq} ({tag}) failed: {ex.Message}");
			}
		}

		private static void LogChemistryStationIngredientTransforms(ChemistryStation station, int seq, string tag)
		{
			try
			{
				Transform[] ingredientTransforms = station.IngredientTransforms;
				int num = ((ingredientTransforms == null) ? (-1) : ingredientTransforms.Length);
				MelonLogger.Msg($"SuperGrow Begin audit #{seq} ({tag}): ingredientTransforms={num}");
				if (ingredientTransforms == null)
				{
					return;
				}
				for (int i = 0; i < ingredientTransforms.Length; i++)
				{
					Transform val = ingredientTransforms[i];
					if ((Object)(object)val == (Object)null)
					{
						MelonLogger.Msg($"SuperGrow Begin audit #{seq} ({tag}): transform[{i}]=<null>");
						continue;
					}
					int childCount = val.childCount;
					MelonLogger.Msg($"SuperGrow Begin audit #{seq} ({tag}): transform[{i}] name={((Object)val).name} childCount={childCount}");
					for (int j = 0; j < childCount && j < 6; j++)
					{
						Transform child = val.GetChild(j);
						MelonLogger.Msg($"SuperGrow Begin audit #{seq} ({tag}):  - child[{j}] name={((Object)child).name} activeSelf={((Component)child).gameObject.activeSelf}");
					}
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Error($"SuperGrow Begin audit #{seq} ({tag}): failed to inspect ingredient transforms: {ex.Message}");
			}
		}

		private static void DumpChemistryStationInterfaceStateOnce(ChemistryStationInterface canvas, string tag, int stageMask)
		{
			if (!((Object)(object)canvas == (Object)null))
			{
				int instanceID = ((Object)canvas).GetInstanceID();
				if (!_chemCanvasDumpMaskByInstanceId.TryGetValue(instanceID, out var value) || (value & stageMask) == 0)
				{
					_chemCanvasDumpMaskByInstanceId[instanceID] = value | stageMask;
					DumpChemistryStationInterfaceState(canvas, tag);
				}
			}
		}

		private static void DumpChemistryStationInterfaceUiStateOnce(ChemistryStationInterface canvas, string tag, int stageMask)
		{
			if (!((Object)(object)canvas == (Object)null))
			{
				int instanceID = ((Object)canvas).GetInstanceID();
				if (!_chemCanvasDumpMaskByInstanceId.TryGetValue(instanceID, out var value) || (value & stageMask) == 0)
				{
					_chemCanvasDumpMaskByInstanceId[instanceID] = value | stageMask;
					DumpChemistryStationInterfaceUiState(canvas, tag);
				}
			}
		}

		private static void DumpChemistryStationInterfaceState(ChemistryStationInterface canvas, string tag)
		{
			try
			{
				int instanceID = ((Object)canvas).GetInstanceID();
				object recipes = canvas.Recipes;
				int? num = TryGetCount(recipes);
				bool flag = ListContainsSuperGrowRecipe(recipes);
				Type typeFromHandle = typeof(ChemistryStationInterface);
				FieldInfo field = typeFromHandle.GetField("recipeEntries", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				PropertyInfo propertyInfo = ((field == null) ? typeFromHandle.GetProperty("recipeEntries", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) : null);
				object obj = null;
				if (field != null)
				{
					obj = field.GetValue(canvas);
				}
				else if (propertyInfo != null)
				{
					obj = propertyInfo.GetValue(canvas);
				}
				int? num2 = TryGetCount(obj);
				bool flag2 = ListContainsSuperGrowRecipeEntry(obj);
				MelonLogger.Msg(string.Format("ChemistryStationInterface audit ({0}): canvasId={1} recipes={2} hasSuperGrowRecipe={3} recipeEntriesField={4} recipeEntries={5} hasSuperGrowEntry={6}", tag, instanceID, (recipes == null) ? "<null>" : (num?.ToString() ?? "<unknown>"), flag, (field != null) ? "ok" : ((propertyInfo != null) ? "ok(prop)" : "<missing>"), (obj == null) ? "<null>" : (num2?.ToString() ?? "<unknown>"), flag2));
			}
			catch (Exception ex)
			{
				MelonLogger.Error("ChemistryStationInterface audit failed (" + tag + "): " + ex.Message);
				MelonLogger.Error(ex.StackTrace ?? "<no stack trace>");
			}
		}

		private static void DumpChemistryStationInterfaceUiState(ChemistryStationInterface canvas, string tag)
		{
			try
			{
				int instanceID = ((Object)canvas).GetInstanceID();
				RectTransform recipeContainer = canvas.RecipeContainer;
				if ((Object)(object)recipeContainer == (Object)null)
				{
					MelonLogger.Msg($"ChemistryStationInterface UI audit ({tag}): canvasId={instanceID} RecipeContainer=<null>");
					return;
				}
				StationRecipeEntry[] componentsInChildren = ((Component)recipeContainer).GetComponentsInChildren<StationRecipeEntry>(true);
				int num = ((componentsInChildren != null) ? componentsInChildren.Length : 0);
				MelonLogger.Msg($"ChemistryStationInterface UI audit ({tag}): canvasId={instanceID} recipeContainerChildren={((Transform)recipeContainer).childCount} entryComponents={num}");
				if (componentsInChildren == null || componentsInChildren.Length == 0)
				{
					return;
				}
				int num2 = 0;
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					if (num2 >= 12)
					{
						break;
					}
					StationRecipeEntry val = componentsInChildren[i];
					if (!((Object)(object)val == (Object)null))
					{
						string text;
						try
						{
							text = (((Object)(object)val.TitleLabel == (Object)null) ? "<null>" : (((TMP_Text)val.TitleLabel).text ?? "<null>"));
						}
						catch
						{
							text = "<error>";
						}
						string text2 = SafeGetProductId(val.Recipe);
						MelonLogger.Msg($"ChemistryStationInterface UI entry ({tag}): idx={i} title={text} productId={text2}");
						num2++;
					}
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Error("ChemistryStationInterface UI audit failed (" + tag + "): " + ex.Message);
				MelonLogger.Error(ex.StackTrace ?? "<no stack trace>");
			}
		}

		public static void DumpStationItemInitializePatchesOnce(string reason)
		{
			if (!_stationItemInitializePatchInfoDumped)
			{
				_stationItemInitializePatchInfoDumped = true;
				DumpStationItemInitializePatchInfo(reason);
			}
		}

		private static void DumpStationItemInitializePatchInfo(string reason)
		{
			try
			{
				MethodInfo methodInfo = AccessTools.Method(typeof(StationItem), "Initialize", new Type[1] { typeof(StorableItemDefinition) }, (Type[])null) ?? AccessTools.Method(typeof(StationItem), "Initialize", (Type[])null, (Type[])null);
				if (methodInfo == null)
				{
					MelonLogger.Warning("Could not resolve StationItem.Initialize method for patch audit (" + reason + ")");
					return;
				}
				Patches patchInfo = Harmony.GetPatchInfo((MethodBase)methodInfo);
				if (patchInfo == null)
				{
					MelonLogger.Msg("StationItem.Initialize patch audit (" + reason + "): no Harmony patches found");
					return;
				}
				string text = ((patchInfo.Owners != null && patchInfo.Owners.Count > 0) ? string.Join(", ", patchInfo.Owners) : "<none>");
				MelonLogger.Msg("StationItem.Initialize patch audit (" + reason + "): owners=" + text);
				LogPatchList("prefix", patchInfo.Prefixes);
				LogPatchList("postfix", patchInfo.Postfixes);
				LogPatchList("transpiler", patchInfo.Transpilers);
				LogPatchList("finalizer", patchInfo.Finalizers);
			}
			catch (Exception ex)
			{
				MelonLogger.Error("Failed to dump StationItem.Initialize patch audit (" + reason + "): " + ex.Message);
				MelonLogger.Error(ex.StackTrace ?? "<no stack trace>");
			}
		}

		private static void LogPatchList(string kind, IReadOnlyCollection<Patch> patches)
		{
			if (patches == null || patches.Count == 0)
			{
				MelonLogger.Msg("StationItem.Initialize " + kind + ": <none>");
				return;
			}
			MelonLogger.Msg($"StationItem.Initialize {kind}: count={patches.Count}");
			foreach (Patch patch in patches)
			{
				MethodInfo patchMethod = patch.PatchMethod;
				string text = ((patchMethod == null) ? "<null>" : ((patchMethod.DeclaringType == null) ? patchMethod.Name : (patchMethod.DeclaringType.FullName + "." + patchMethod.Name)));
				MelonLogger.Msg($"  - owner={patch.owner} prio={patch.priority} idx={patch.index} method={text}");
			}
		}

		private static int? TryGetCount(object? listObj)
		{
			if (listObj == null)
			{
				return null;
			}
			Type type = listObj.GetType();
			PropertyInfo property = type.GetProperty("Count");
			if (property != null && property.PropertyType == typeof(int))
			{
				return (int?)property.GetValue(listObj);
			}
			MethodInfo method = type.GetMethod("get_Count", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (method != null && method.ReturnType == typeof(int))
			{
				return (int?)method.Invoke(listObj, null);
			}
			return null;
		}

		private static object? TryGetListItem(object? listObj, int index)
		{
			if (listObj == null)
			{
				return null;
			}
			Type type = listObj.GetType();
			PropertyInfo property = type.GetProperty("Item");
			if (property != null)
			{
				try
				{
					return property.GetValue(listObj, new object[1] { index });
				}
				catch
				{
				}
			}
			MethodInfo method = type.GetMethod("get_Item", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (method != null)
			{
				try
				{
					return method.Invoke(listObj, new object[1] { index });
				}
				catch
				{
				}
			}
			return null;
		}

		private static bool ListContainsSuperGrowRecipe(object? recipesObj)
		{
			if (recipesObj == null)
			{
				return false;
			}
			int? num = TryGetCount(recipesObj);
			bool flag;
			if (num.HasValue)
			{
				int valueOrDefault = num.GetValueOrDefault();
				if (valueOrDefault > 0)
				{
					flag = false;
					goto IL_0037;
				}
			}
			flag = true;
			goto IL_0037;
			IL_0037:
			if (flag)
			{
				return false;
			}
			for (int i = 0; i < num; i++)
			{
				object obj = TryGetListItem(recipesObj, i);
				if (obj != null && TryGetStationRecipeProductId(obj, out string productId) && productId == "supergrow")
				{
					return true;
				}
			}
			return false;
		}

		private static bool ListContainsSuperGrowRecipeEntry(object? entriesObj)
		{
			if (entriesObj == null)
			{
				return false;
			}
			int? num = TryGetCount(entriesObj);
			bool flag;
			if (num.HasValue)
			{
				int valueOrDefault = num.GetValueOrDefault();
				if (valueOrDefault > 0)
				{
					flag = false;
					goto IL_0037;
				}
			}
			flag = true;
			goto IL_0037;
			IL_0037:
			if (flag)
			{
				return false;
			}
			for (int i = 0; i < num; i++)
			{
				object obj = TryGetListItem(entriesObj, i);
				if (obj != null)
				{
					object obj2 = obj.GetType().GetProperty("Recipe", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(obj);
					if (obj2 != null && TryGetStationRecipeProductId(obj2, out string productId) && productId == "supergrow")
					{
						return true;
					}
				}
			}
			return false;
		}

		private static bool TryGetStationRecipeProductId(object recipeObj, out string? productId)
		{
			productId = null;
			try
			{
				MemberInfo memberInfo = (MemberInfo)(((object)recipeObj.GetType().GetProperty("Product", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) ?? ((object)recipeObj.GetType().GetField("Product", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)));
				if (1 == 0)
				{
				}
				object obj = ((memberInfo is PropertyInfo propertyInfo) ? propertyInfo.GetValue(recipeObj) : ((!(memberInfo is FieldInfo fieldInfo)) ? null : fieldInfo.GetValue(recipeObj)));
				if (1 == 0)
				{
				}
				object obj2 = obj;
				if (obj2 == null)
				{
					return false;
				}
				MemberInfo memberInfo2 = (MemberInfo)(((object)obj2.GetType().GetProperty("Item", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) ?? ((object)obj2.GetType().GetField("Item", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)));
				if (1 == 0)
				{
				}
				obj = ((memberInfo2 is PropertyInfo propertyInfo2) ? propertyInfo2.GetValue(obj2) : ((!(memberInfo2 is FieldInfo fieldInfo2)) ? null : fieldInfo2.GetValue(obj2)));
				if (1 == 0)
				{
				}
				object obj3 = obj;
				if (obj3 == null)
				{
					return false;
				}
				PropertyInfo property = obj3.GetType().GetProperty("ID", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (property != null && property.PropertyType == typeof(string))
				{
					productId = property.GetValue(obj3) as string;
					return productId != null;
				}
				FieldInfo field = obj3.GetType().GetField("ID", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (field != null && field.FieldType == typeof(string))
				{
					productId = field.GetValue(obj3) as string;
					return productId != null;
				}
				MethodInfo method = obj3.GetType().GetMethod("get_ID", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (method != null && method.ReturnType == typeof(string))
				{
					productId = method.Invoke(obj3, null) as string;
					return productId != null;
				}
			}
			catch
			{
			}
			return false;
		}

		private static void BeginTrashAuditWindow(int seq, ChemistryStation? station)
		{
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			_trashAuditSeq = seq;
			_trashAuditUntilTick = Environment.TickCount + 60000;
			_trashAuditTrashManagerLogged = 0;
			_trashAuditGetTrashPrefabLogged = 0;
			_trashAuditTrashItemStartLogged = 0;
			_trashAuditSeenTrashIds.Clear();
			_trashAuditSeenGetTrashPrefabIds.Clear();
			_trashAuditTrashPrefabsDumped = false;
			if ((Object)(object)station != (Object)null && (Object)(object)((Component)station).transform != (Object)null)
			{
				_trashAuditHasStationPos = true;
				_trashAuditStationPos = ((Component)station).transform.position;
			}
			else
			{
				_trashAuditHasStationPos = false;
				_trashAuditStationPos = Vector3.zero;
			}
			string arg = (_trashAuditHasStationPos ? ((object)Unsafe.As<Vector3, Vector3>(ref _trashAuditStationPos)/*cast due to .constrained prefix*/).ToString() : "<unknown>");
			MelonLogger.Msg($"SuperGrow trash audit #{seq}: enabled for {60000}ms stationPos={arg}");
			try
			{
				if ((Object)(object)_trashAuditManager == (Object)null)
				{
					_trashAuditManager = Object.FindObjectOfType<TrashManager>();
				}
				DumpTrashPrefabsOnce("BeginTrashAuditWindow", _trashAuditManager);
			}
			catch
			{
			}
		}

		private static bool IsTrashAuditActive()
		{
			return _trashAuditUntilTick != 0 && Environment.TickCount - _trashAuditUntilTick < 0;
		}

		private static bool IsNearAuditedStation(Vector3 position)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			if (!_trashAuditHasStationPos)
			{
				return true;
			}
			return Vector3.Distance(position, _trashAuditStationPos) <= 35f;
		}

		private static void DumpTrashPrefabsOnce(string reason, TrashManager? manager)
		{
			if (_trashAuditTrashPrefabsDumped)
			{
				return;
			}
			if ((Object)(object)manager == (Object)null)
			{
				MelonLogger.Msg($"SuperGrow trash audit #{_trashAuditSeq}: TrashManager not found for TrashPrefabs dump ({reason})");
				return;
			}
			_trashAuditTrashPrefabsDumped = true;
			try
			{
				TrashItem[] trashPrefabs = manager.TrashPrefabs;
				int num = ((trashPrefabs != null) ? trashPrefabs.Length : 0);
				MelonLogger.Msg($"SuperGrow trash audit #{_trashAuditSeq}: TrashPrefabs dump ({reason}) total={num}");
				if (trashPrefabs != null)
				{
					for (int i = 0; i < trashPrefabs.Length; i++)
					{
						TrashItem val = trashPrefabs[i];
						string arg = (((Object)(object)val == (Object)null) ? "<null>" : (val.ID ?? "<null-id>"));
						string arg2 = (((Object)(object)val == (Object)null || (Object)(object)((Component)val).gameObject == (Object)null) ? "<null>" : (((Object)((Component)val).gameObject).name ?? "<unnamed>"));
						MelonLogger.Msg($"  - [{i}] id={arg} name={arg2}");
					}
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Error("SuperGrow trash audit: TrashPrefabs dump failed (" + reason + "): " + ex.Message);
			}
		}

		[HarmonyPatch(typeof(ChemistryStation), "CreateTrash")]
		[HarmonyPrefix]
		private static void ChemistryStation_CreateTrash_DebugPrefix(ChemistryStation __instance, List<StationItem> mixerItems)
		{
			if (!IsTrashAuditActive())
			{
				return;
			}
			try
			{
				ChemistryCookOperation val = ((__instance != null) ? __instance.CurrentCookOperation : null);
				string arg = ((val == null) ? "<null-op>" : (val.RecipeID ?? "<null>"));
				int num = mixerItems?.Count ?? (-1);
				MelonLogger.Msg($"SuperGrow trash audit #{_trashAuditSeq}: ChemistryStation.CreateTrash recipeId={arg} mixerItems={num}");
				if (mixerItems == null)
				{
					return;
				}
				int num2 = Math.Min(8, mixerItems.Count);
				for (int i = 0; i < num2; i++)
				{
					StationItem val2 = mixerItems[i];
					if ((Object)(object)val2 == (Object)null || (Object)(object)((Component)val2).gameObject == (Object)null)
					{
						MelonLogger.Msg($"  - mixer[{i}]=<null>");
						continue;
					}
					string arg2 = ((Object)((Component)val2).gameObject).name ?? "<unnamed>";
					string arg3 = (((Object)(object)val2.TrashPrefab == (Object)null) ? "<null>" : (val2.TrashPrefab.ID ?? "<null-id>"));
					MelonLogger.Msg($"  - mixer[{i}] name={arg2} trashId={arg3}");
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Error("SuperGrow trash audit: ChemistryStation.CreateTrash logging failed: " + ex.Message);
			}
		}

		[HarmonyPatch(typeof(TrashManager), "Start")]
		[HarmonyPostfix]
		private static void TrashManager_Start_DebugPostfix(TrashManager __instance)
		{
			_trashAuditManager = __instance;
			if (IsTrashAuditActive())
			{
				DumpTrashPrefabsOnce("TrashManager.Start", __instance);
			}
		}

		[HarmonyPatch(typeof(TrashManager), "CreateTrashItem", new Type[]
		{
			typeof(string),
			typeof(Vector3),
			typeof(Quaternion),
			typeof(Vector3),
			typeof(string),
			typeof(bool)
		})]
		[HarmonyPrefix]
		private static void TrashManager_CreateTrashItem_DebugPrefix(string id, Vector3 posiiton, Quaternion rotation, Vector3 initialVelocity, string guid, bool startKinematic)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			if (!IsTrashAuditActive() || _trashAuditTrashManagerLogged >= 50 || !IsNearAuditedStation(posiiton))
			{
				return;
			}
			try
			{
				string text = id ?? "<null>";
				if (_trashAuditSeenTrashIds.Add(text))
				{
					_trashAuditTrashManagerLogged++;
					string text2 = (_trashAuditHasStationPos ? Vector3.Distance(posiiton, _trashAuditStationPos).ToString("0.0") : "<n/a>");
					MelonLogger.Msg($"SuperGrow trash audit #{_trashAuditSeq}: TrashManager.CreateTrashItem id={text} pos={posiiton} dist={text2}");
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Error("SuperGrow trash audit: TrashManager.CreateTrashItem logging failed: " + ex.Message);
			}
		}

		[HarmonyPatch(typeof(TrashManager), "GetTrashPrefab", new Type[] { typeof(string) })]
		[HarmonyPostfix]
		private static void TrashManager_GetTrashPrefab_DebugPostfix(TrashManager __instance, string id, TrashItem __result)
		{
			if (!IsTrashAuditActive() || _trashAuditGetTrashPrefabLogged >= 50)
			{
				return;
			}
			try
			{
				string text = id ?? "<null>";
				if (!_trashAuditSeenGetTrashPrefabIds.Add(text))
				{
					return;
				}
				string text2 = (((Object)(object)__result == (Object)null) ? "<null>" : (__result.ID ?? "<null-id>"));
				string text3 = (((Object)(object)__result == (Object)null || (Object)(object)((Component)__result).gameObject == (Object)null) ? "<null>" : (((Object)((Component)__result).gameObject).name ?? "<unnamed>"));
				TrashItem[] array = (((Object)(object)__instance == (Object)null) ? null : __instance.TrashPrefabs);
				int num = ((array != null) ? array.Length : 0);
				int num2 = -1;
				if (array != null)
				{
					for (int i = 0; i < array.Length; i++)
					{
						TrashItem val = array[i];
						if ((Object)(object)val != (Object)null && val.ID == text)
						{
							num2 = i;
							break;
						}
					}
				}
				_trashAuditGetTrashPrefabLogged++;
				MelonLogger.Msg($"SuperGrow trash audit #{_trashAuditSeq}: TrashManager.GetTrashPrefab id={text} -> resultId={text2} resultName={text3} trashPrefabsIndex={num2} total={num}");
			}
			catch (Exception ex)
			{
				MelonLogger.Error("SuperGrow trash audit: TrashManager.GetTrashPrefab logging failed: " + ex.Message);
			}
		}

		[HarmonyPatch(typeof(TrashItem), "Start")]
		[HarmonyPostfix]
		private static void TrashItem_Start_DebugPostfix(TrashItem __instance)
		{
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: 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_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			if (!IsTrashAuditActive() || _trashAuditTrashItemStartLogged >= 50)
			{
				return;
			}
			try
			{
				if (!((Object)(object)__instance == (Object)null) && !((Object)(object)((Component)__instance).gameObject == (Object)null))
				{
					Vector3 val = (((Object)(object)((Component)__instance).transform != (Object)null) ? ((Component)__instance).transform.position : Vector3.zero);
					if (IsNearAuditedStation(val))
					{
						_trashAuditTrashItemStartLogged++;
						string text = __instance.ID ?? "<null>";
						string text2 = ((Object)((Component)__instance).gameObject).name ?? "<unnamed>";
						string text3 = (_trashAuditHasStationPos ? Vector3.Distance(val, _trashAuditStationPos).ToString("0.0") : "<n/a>");
						MelonLogger.Msg($"SuperGrow trash audit #{_trashAuditSeq}: TrashItem.Start id={text} name={text2} pos={val} dist={text3}");
					}
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Error("SuperGrow trash audit: TrashItem.Start logging failed: " + ex.Message);
			}
		}

		[HarmonyPatch(typeof(ChemistryStationInterface), "Awake")]
		[HarmonyPrefix]
		private static void ChemistryStationInterface_Awake_Prefix(ChemistryStationInterface __instance)
		{
			try
			{
				if ((Object)(object)__instance == (Object)null)
				{
					return;
				}
				SuperGrowCreator.CreateSuperGrowItem();
				if ((Object)(object)_superGrowRecipe == (Object)null)
				{
					CreateSuperGrowRecipe();
				}
				if ((Object)(object)_superGrowRecipe == (Object)null)
				{
					if (!_loggedRecipeNotReady)
					{
						_loggedRecipeNotReady = true;
						MelonLogger.Warning("SuperGrow recipe is null; cannot add to chemistry station yet");
					}
					return;
				}
				List<StationRecipe> recipes = __instance.Recipes;
				if (recipes == null)
				{
					if (!_loggedRecipeNotReady)
					{
						_loggedRecipeNotReady = true;
						MelonLogger.Warning("ChemistryStationInterface.Recipes is null; cannot add SuperGrow recipe");
					}
				}
				else if (!recipes.Contains(_superGrowRecipe))
				{
					recipes.Add(_superGrowRecipe);
					MelonLogger.Msg("Added SuperGrow recipe to Chemistry Station");
					SetupAdditiveStationItems();
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Error("Failed to add SuperGrow recipe: " + ex.Message);
				MelonLogger.Error(ex.StackTrace ?? "<no stack trace>");
			}
		}

		[HarmonyPatch(typeof(ChemistryStationInterface), "Awake")]
		[HarmonyPostfix]
		private static void ChemistryStationInterface_Awake_Postfix(ChemistryStationInterface __instance)
		{
			DumpChemistryStationInterfaceStateOnce(__instance, "Awake_Postfix", 1);
			DumpChemistryStationInterfaceUiStateOnce(__instance, "Awake_Postfix", 4);
		}

		[HarmonyPatch(typeof(ChemistryStationInterface), "Open")]
		[HarmonyPrefix]
		private static void ChemistryStationInterface_Open_PrefixAudit(ChemistryStationInterface __instance, ChemistryStation station)
		{
			DumpChemistryStationInterfaceStateOnce(__instance, "Open_Prefix", 2);
			DumpChemistryStationInterfaceUiStateOnce(__instance, "Open_Prefix", 8);
		}

		[HarmonyPatch(typeof(ChemistryStationInterface), "SetSelectedRecipe")]
		[HarmonyPrefix]
		private static void ChemistryStationInterface_SetSelectedRecipe_Prefix(ChemistryStationInterface __instance, StationRecipeEntry entry)
		{
			try
			{
				StationRecipe val = ((entry != null) ? entry.Recipe : null);
				string text = SafeGetProductId(val);
				if (!(text == "<null>") && !(text == "<error>"))
				{
					_lastSelectedRecipeProductId = text;
					_lastSelectedRecipeTitle = SafeGetRecipeEntryTitle(entry);
					_lastSelectedRecipeId = (((Object)(object)val == (Object)null) ? "<null>" : SafeGetStationRecipeId(val));
					_lastSelectedAtTick = Environment.TickCount;
				}
			}
			catch
			{
			}
		}

		[HarmonyPatch(typeof(ChemistryStationInterface), "BeginTask")]
		[HarmonyPrefix]
		private static void ChemistryStationInterface_BeginTask_Prefix(ChemistryStationInterface __instance)
		{
			try
			{
				if (!((Object)(object)__instance == (Object)null))
				{
					StationRecipeEntry val = TryGetSelectedRecipeEntry(__instance);
					StationRecipe val2 = ((val != null) ? val.Recipe : null);
					string text = SafeGetProductId(val2);
					if (text == "<null>" || text == "<error>")
					{
						text = _lastSelectedRecipeProductId ?? text;
					}
					if (!(text != "supergrow"))
					{
						_superGrowBeginAuditSeq++;
						_superGrowBeginAuditUntilTick = Environment.TickCount + 10000;
						_superGrowBeginStation = __instance.ChemistryStation;
						_superGrowBeginStationSeq = _superGrowBeginAuditSeq;
						int superGrowBeginAuditSeq = _superGrowBeginAuditSeq;
						string text2 = (((Object)(object)val != (Object)null) ? SafeGetRecipeEntryTitle(val) : (_lastSelectedRecipeTitle ?? "<unknown>"));
						string text3 = (((Object)(object)val2 != (Object)null) ? SafeGetStationRecipeId(val2) : (_lastSelectedRecipeId ?? "<unknown>"));
						MelonLogger.Msg($"SuperGrow Begin audit #{superGrowBeginAuditSeq}: selectedTitle={text2} productId={text} recipeId={text3} beginInteractable={SafeGetBeginInteractable(__instance)}");
						BeginTrashAuditWindow(superGrowBeginAuditSeq, __instance.ChemistryStation);
						BeginBeakerAuditWindow(superGrowBeginAuditSeq, __instance.ChemistryStation);
						LogRecipeIngredients(val2 ?? GetCachedSelectedRecipe(__instance), superGrowBeginAuditSeq);
						LogChemistryStationSlotState(_superGrowBeginStation, superGrowBeginAuditSeq, "Begin_Prefix");
					}
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Error("SuperGrow Begin audit failed (Prefix): " + ex.Message);
				MelonLogger.Error(ex.StackTrace ?? "<no stack trace>");
			}
		}

		[HarmonyPatch(typeof(ChemistryStationInterface), "BeginTask")]
		[HarmonyPostfix]
		private static void ChemistryStationInterface_BeginTask_Postfix(ChemistryStationInterface __instance)
		{
			try
			{
				if (!((Object)(object)__instance == (Object)null) && !TickExpired(_superGrowBeginAuditUntilTick))
				{
					int superGrowBeginAuditSeq = _superGrowBeginAuditSeq;
					ChemistryStation val = __instance.ChemistryStation;
					if ((Object)(object)val == (Object)null && _superGrowBeginStationSeq == superGrowBeginAuditSeq)
					{
						val = _superGrowBeginStation;
					}
					LogChemistryStationSlotState(val, superGrowBeginAuditSeq, "Begin_Postfix");
					if ((Object)(object)val != (Object)null)
					{
						MelonCoroutines.Start(DelayedChemistryIngredientAudit(superGrowBeginAuditSeq, val));
					}
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Error("SuperGrow Begin audit failed (Postfix): " + ex.Message);
				MelonLogger.Error(ex.StackTrace ?? "<no stack trace>");
			}
		}

		private static bool TickExpired(int untilTick)
		{
			return Environment.TickCount - untilTick >= 0;
		}

		private static IEnumerator DelayedChemistryIngredientAudit(int seq, ChemistryStation station)
		{
			yield return (object)new WaitForSeconds(0.1f);
			LogChemistryStationIngredientTransforms(station, seq, "Begin+0.1s");
			yield return (object)new WaitForSeconds(0.4f);
			LogChemistryStationIngredientTransforms(station, seq, "Begin+0.5s");
			yield return (object)new WaitForSeconds(0.5f);
			LogChemistryStationIngredientTransforms(station, seq, "Begin+1.0s");
		}

		private static StationRecipeEntry? TryGetSelectedRecipeEntry(ChemistryStationInterface canvas)
		{
			try
			{
				Type typeFromHandle = typeof(ChemistryStationInterface);
				FieldInfo field = typeFromHandle.GetField("selectedRecipe", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (field != null)
				{
					object? value = field.GetValue(canvas);
					return (StationRecipeEntry?)((value is StationRecipeEntry) ? value : null);
				}
				PropertyInfo property = typeFromHandle.GetProperty("selectedRecipe", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (property != null)
				{
					object? value2 = property.GetValue(canvas);
					return (StationRecipeEntry?)((value2 is StationRecipeEntry) ? value2 : null);
				}
				FieldInfo[] fields = typeFromHandle.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				FieldInfo[] array = fields;
				foreach (FieldInfo fieldInfo in array)
				{
					if (!(fieldInfo.FieldType != typeof(StationRecipeEntry)) && !(fieldInfo.Name == "RecipeEntryPrefab") && !(fieldInfo.Name == "InProgressRecipeEntry"))
					{
						object? value3 = fieldInfo.GetValue(canvas);
						StationRecipeEntry val = (StationRecipeEntry)((value3 is StationRecipeEntry) ? value3 : null);
						if ((Object)(object)((val != null) ? val.Recipe : null) != (Object)null)
						{
							return val;
						}
					}
				}
			}
			catch
			{
			}
			return null;
		}

		private static string SafeGetRecipeEntryTitle(StationRecipeEntry? entry)
		{
			try
			{
				return ((Object)(object)entry?.TitleLabel == (Object)null) ? "<null>" : (((TMP_Text)entry.TitleLabel).text ?? "<null>");
			}
			catch
			{
				return "<error>";
			}
		}

		private static bool SafeGetBeginInteractable(ChemistryStationInterface canvas)
		{
			try
			{
				return (Object)(object)canvas.BeginButton != (Object)null && ((Selectable)canvas.BeginButton).interactable;
			}
			catch
			{
				return false;
			}
		}

		private static string SafeGetProductId(StationRecipe? recipe)
		{
			try
			{
				return ((BaseItemDefinition)(recipe?.Product?.Item?)).ID ?? "<null>";
			}
			catch
			{
				return "<error>";
			}
		}

		private static string SafeGetStationRecipeId(StationRecipe recipe)
		{
			try
			{
				return recipe.RecipeID ?? "<null>";
			}
			catch
			{
				return "<error>";
			}
		}

		private static void CreateSuperGrowRecipe()
		{
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Expected O, but got Unknown
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Expected O, but got Unknown
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Expected O, but got Unknown
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Expected O, but got Unknown
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			ItemDefinition item = Registry.GetItem("pgr");
			ItemDefinition item2 = Registry.GetItem("speedgrow");
			ItemDefinition item3 = Registry.GetItem("fertilizer");
			ItemDefinition item4 = Registry.GetItem("supergrow");
			if ((Object)(object)item == (Object)null || (Object)(object)item2 == (Object)null || (Object)(object)item3 == (Object)null)
			{
				MelonLogger.Error("Could not find one or more base additive definitions");
				return;
			}
			if ((Object)(object)item4 == (Object)null)
			{
				SuperGrowCreator.CreateSuperGrowItem();
				item4 = Registry.GetItem("supergrow");
				if ((Object)(object)item4 == (Object)null)
				{
					MelonLogger.Warning("Could not find SuperGrow definition; will retry when registry is ready");
					return;
				}
			}
			_superGrowRecipe = ScriptableObject.CreateInstance<StationRecipe>();
			_superGrowRecipe.IsDiscovered = true;
			_superGrowRecipe.RecipeTitle = "SuperGrow";
			_superGrowRecipe.CookTime_Mins = SuperGrowSettings.CookTimeMinutes.Value;
			_superGrowRecipe.Unlocked = true;
			List<IngredientQuantity> list = new List<IngredientQuantity>();
			IngredientQuantity val = new IngredientQuantity();
			List<ItemDefinition> list2 = new List<ItemDefinition>();
			list2.Add(item);
			val.Items = list2;
			val.Quantity = SuperGrowSettings.PgrRequired.Value;
			list.Add(val);
			IngredientQuantity val2 = new IngredientQuantity();
			List<ItemDefinition> list3 = new List<ItemDefinition>();
			list3.Add(item2);
			val2.Items = list3;
			val2.Quantity = SuperGrowSettings.SpeedGrowRequired.Value;
			list.Add(val2);
			IngredientQuantity val3 = new IngredientQuantity();
			List<ItemDefinition> list4 = new List<ItemDefinition>();
			list4.Add(item3);
			val3.Items = list4;
			val3.Quantity = SuperGrowSettings.FertilizerRequired.Value;
			list.Add(val3);
			_superGrowRecipe.Ingredients = list;
			_superGrowRecipe.Product = new ItemQuantity
			{
				Item = item4,
				Quantity = SuperGrowSettings.OutputQuantity.Value
			};
			_superGrowRecipe.FinalLiquidColor = SuperGrowVisuals.PourColor;
		}

		private static bool TryGetStationItemTemplate(out StationItem templateStationItem)
		{
			templateStationItem = null;
			string[] array = new string[4] { "acid", "pgr", "speedgrow", "fertilizer" };
			string[] array2 = array;
			foreach (string text in array2)
			{
				ItemDefinition item = Registry.GetItem(text);
				StorableItemDefinition val = (StorableItemDefinition)(object)((item is StorableItemDefinition) ? item : null);
				if ((Object)(object)val?.StationItem != (Object)null)
				{
					templateStationItem = val.StationItem;
					return true;
				}
			}
			if (!_loggedMissingStationItemTemplate)
			{
				_loggedMissingStationItemTemplate = true;
				MelonLogger.Warning("Could not find any StationItem template (acid/pgr/speedgrow/fertilizer)");
				string[] array3 = array;
				foreach (string text2 in array3)
				{
					ItemDefinition item2 = Registry.GetItem(text2);
					StorableItemDefinition val2 = (StorableItemDefinition)(object)((item2 is StorableItemDefinition) ? item2 : null);
					MelonLogger.Warning(text2 + ": def=" + (((Object)(object)val2 == (Object)null) ? "<null>" : ((object)val2).GetType().FullName) + " stationItem=" + (((Object)(object)val2?.StationItem == (Object)null) ? "<null>" : ((object)val2.StationItem).GetType().FullName));
				}
			}
			return false;
		}

		[HarmonyPatch(typeof(Registry), "Start")]
		[HarmonyPostfix]
		private static void Registry_Start_Postfix()
		{
			if (_loggedRegistryStart)
			{
				return;
			}
			_loggedRegistryStart = true;
			try
			{
				SuperGrowCreator.CreateSuperGrowItem();
			}
			catch (Exception ex)
			{
				MelonLogger.Error("Registry.Start hook failed: " + ex.Message);
				MelonLogger.Error(ex.StackTrace ?? "<no stack trace>");
			}
		}

		public static void SetupAdditiveStationItems()
		{
			if (_additivesPatched)
			{
				return;
			}
			try
			{
				CachePourablePrefab("pgr", "growing/pgr/PGR_Pourable");
				CachePourablePrefab("speedgrow", "growing/speedgrow/SpeedGrow_Pourable");
				CachePourablePrefab("fertilizer", "growing/fertilizer/Fertilizer_Pourable");
				if (TryGetStationItemTemplate(out StationItem templateStationItem))
				{
					SetupAdditiveStationItem("pgr", templateStationItem);
					SetupAdditiveStationItem("speedgrow", templateStationItem);
					SetupAdditiveStationItem("fertilizer", templateStationItem);
					_additivesPatched = true;
					MelonLogger.Msg("Set up StationItem on base additives for chemistry station compatibility");
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Error("Failed to set up additive StationItems: " + ex.Message);
				MelonLogger.Error(ex.StackTrace);
			}
		}

		[HarmonyPatch(typeof(StoredItem), "InitializeStoredItem")]
		[HarmonyPostfix]
		private static void StoredItem_InitializeStoredItem_Postfix(StoredItem __instance, StorableItemInstance _item)
		{
			try
			{
				string text = ((_item == null) ? null : ((BaseItemDefinition)(((ItemInstance)_item).Definition?)).ID);
				if (!(text != "supergrow"))
				{
					ApplySuperGrowMaterialsToRenderers(((Component)__instance).GetComponentsInChildren<Renderer>(true));
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Error("Failed to apply SuperGrow visuals to stored item: " + ex.Message);
				MelonLogger.Error(ex.StackTrace ?? "<no stack trace>");
			}
		}

		private static bool TrashPrefabsContainsId(TrashItem[]? prefabs, string id)
		{
			if (prefabs == null)
			{
				return false;
			}
			foreach (TrashItem val in prefabs)
			{
				if ((Object)(object)val != (Object)null && val.ID == id)
				{
					return true;
				}
			}
			return false;
		}

		private static bool TryGetMonoBottleTrashPrefab(string additiveId, out TrashItem prefab)
		{
			prefab = null;
			if (_monoBottleTrashPrefabByAdditiveId.TryGetValue(additiveId, out TrashItem value) && (Object)(object)value != (Object)null)
			{
				prefab = value;
				return true;
			}
			TrashManager val = Object.FindObjectOfType<TrashManager>();
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			EnsureMonoBottleTrashPrefabsInjected(val);
			if (_monoBottleTrashPrefabByAdditiveId.TryGetValue(additiveId, out value) && (Object)(object)value != (Object)null)
			{
				prefab = value;
				return true;
			}
			return false;
		}

		private static void EnsureMonoBottleTrashPrefabsInjected(TrashManager manager)
		{
			if (_monoTrashPrefabsInjected || (Object)(object)manager == (Object)null)
			{
				return;
			}
			try
			{
				CachePourablePrefab("pgr", "growing/pgr/PGR_Pourable");
				CachePourablePrefab("speedgrow", "growing/speedgrow/SpeedGrow_Pourable");
				CachePourablePrefab("fertilizer", "growing/fertilizer/Fertilizer_Pourable");
				TrashItem baseTrash = manager.GetTrashPrefab("acid");
				TrashItem pgrTrash = manager.GetTrashPrefab("pgr");
				if ((Object)(object)baseTrash == (Object)null || (Object)(object)((Component)baseTrash).gameObject == (Object)null)
				{
					return;
				}
				TrashItem[] prefabs = manager.TrashPrefabs ?? Array.Empty<TrashItem>();
				List<TrashItem> additions = new List<TrashItem>();
				Ensure("pgr", "supergrow_pgr_bottle");
				Ensure("speedgrow", "supergrow_speedgrow_bottle");
				Ensure("fertilizer", "supergrow_fertilizer_bottle");
				Ensure("supergrow", "supergrow_bottle");
				if (additions.Count > 0)
				{
					TrashItem[] array = (TrashItem[])(object)new TrashItem[prefabs.Length + additions.Count];
					Array.Copy(prefabs, array, prefabs.Length);
					for (int i = 0; i < additions.Count; i++)
					{
						array[prefabs.Length + i] = additions[i];
					}
					manager.TrashPrefabs = array;
				}
				_monoTrashPrefabsInjected = true;
				void Ensure(string additiveId, string newId)
				{
					if (!TrashPrefabsContainsId(prefabs, newId))
					{
						GameObject val = ((string.Equals(additiveId, "supergrow", StringComparison.OrdinalIgnoreCase) && (Object)(object)pgrTrash != (Object)null && (Object)(object)((Component)pgrTrash).gameObject != (Object)null) ? ((Component)pgrTrash).gameObject : ((Component)baseTrash).gameObject);
						GameObject val2 = Object.Instantiate<GameObject>(val);
						((Object)val2).name = "SuperGrow_" + additiveId + "_TrashPrefab";
						val2.SetActive(val.activeSelf);
						Object.DontDestroyOnLoad((Object)(object)val2);
						TrashItem component = val2.GetComponent<TrashItem>();
						if ((Object)(object)component == (Object)null)
						{
							Object.Destroy((Object)(object)val2);
						}
						else
						{
							component.ID = newId;
							SwapTrashItemVisualsById(additiveId, component);
							_monoBottleTrashPrefabByAdditiveId[additiveId] = component;
							additions.Add(component);
						}
					}
				}
			}
			catch (Exception ex)
			{
				if (!_loggedMonoTrashPrefabInjectionException)
				{
					_loggedMonoTrashPrefabInjectionException = true;
					MelonLogger.Warning("Failed to inject SuperGrow trash prefabs (Mono): " + ex.Message);
					MelonLogger.Warning(ex.StackTrace ?? "<no stack trace>");
				}
			}
		}

		[HarmonyPatch(typeof(TrashManager), "Start")]
		[HarmonyPostfix]
		private static void TrashManager_Start_Postfix_Mono(TrashManager __instance)
		{
			EnsureMonoBottleTrashPrefabsInjected(__instance);
		}

		private static void SetPendingStationTrashReskins(List<PendingTrashReskin> reskins)
		{
			_pendingStationTrashReskins.Clear();
			if (reskins.Count > 0)
			{
				_pendingStationTrashReskins.AddRange(reskins);
				_pendingStationTrashReskinExpireTick = Environment.TickCount + 5000;
			}
			else
			{
				_pendingStationTrashReskinExpireTick = 0;
			}
		}

		[HarmonyPatch(typeof(TrashItem), "Start")]
		[HarmonyPostfix]
		private static void TrashItem_Start_Postfix(TrashItem __instance)
		{
			try
			{
				if (_pendingStationTrashReskins.Count == 0)
				{
					return;
				}
				if (_pendingStationTrashReskinExpireTick != 0 && Environment.TickCount - _pendingStationTrashReskinExpireTick >= 0)
				{
					_pendingStationTrashReskins.Clear();
					_pendingStationTrashReskinExpireTick = 0;
					return;
				}
				string iD = __instance.ID;
				if (string.IsNullOrEmpty(iD))
				{
					return;
				}
				for (int i = 0; i < _pendingStationTrashReskins.Count; i++)
				{
					PendingTrashReskin pendingTrashReskin = _pendingStationTrashReskins[i];
					if (!(pendingTrashReskin.TrashId != iD))
					{
						_pendingStationTrashReskins.RemoveAt(i);
						SwapTrashItemVisualsById(pendingTrashReskin.AdditiveId, __instance);
						break;
					}
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Error("Failed to apply SuperGrow visuals to trash item: " + ex.Message);
				MelonLogger.Error(ex.StackTrace ?? "<no stack trace>");
			}
		}

		private static bool IsChemistryBeakerFillable(Fillable fillable)
		{
			if ((Object)(object)fillable == (Object)null)
			{
				return false;
			}
			LiquidContainer liquidContainer = fillable.LiquidContainer;
			if ((Object)(object)liquidContainer == (Object)null || (Object)(object)((Component)liquidContainer).transform == (Object)null)
			{
				return false;
			}
			Transform transform = ((Component)liquidContainer).transform;
			if (!string.Equals(((Object)transform).name, "Liquid", StringComparison.OrdinalIgnoreCase))
			{
				return false;
			}
			Transform parent = transform.parent;
			if ((Object)(object)parent == (Object)null || !string.Equals(((Object)parent).name, "Beaker", StringComparison.OrdinalIgnoreCase))
			{
				return false;
			}
			Transform parent2 = parent.parent;
			if ((Object)(object)parent2 == (Object)null || !((Object)parent2).name.StartsWith("Beaker", StringComparison.OrdinalIgnoreCase))
			{
				return false;
			}
			Transform val = parent2;
			while ((Object)(object)val != (Object)null)
			{
				if (((Object)val).name != null && ((Object)val).name.IndexOf("ChemistryStation", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					return true;
				}
				val = val.parent;
			}
			return false;
		}

		private static void CachePourablePrefab(string additiveId, string pourablePath)
		{
			if (!_pourablePrefabs.ContainsKey(additiveId))
			{
				GameObject val = Resources.Load<GameObject>(pourablePath);
				if ((Object)(object)val != (Object)null)
				{
					_pourablePrefabs[additiveId] = val;
					MelonLogger.Msg("Cached pourable prefab for " + additiveId);
				}
				else
				{
					MelonLogger.Warning("Could not load pourable prefab for " + additiveId + " at " + pourablePath);
				}
			}
		}

		private static Transform? FindStationItemBottleContainer(StationItem stationItem)
		{
			Transform val = ((Component)stationItem).transform.Find("Pourable");
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			Transform result = null;
			int childCount = val.childCount;
			for (int i = 0; i < childCount; i++)
			{
				Transform child = val.GetChild(i);
				if ((Object)(object)child != (Object)null && ((Object)child).name.IndexOf("Bottle", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					result = child;
					break;
				}
			}
			return result;
		}

		private static void SwapBottleMeshesAndMaterials(GameObject templatePrefab, Transform targetRoot)
		{
			MeshFilter[] componentsInChildren = templatePrefab.GetComponentsInChildren<MeshFilter>(true);
			MeshFilter[] componentsInChildren2 = ((Component)targetRoot).GetComponentsInChildren<MeshFilter>(true);
			MeshFilter[] array = componentsInChildren2;
			foreach (MeshFilter val in array)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				string text = ((Object)val).name.ToLowerInvariant();
				MeshFilter[] array2 = componentsInChildren;
				foreach (MeshFilter val2 in array2)
				{
					if ((Object)(object)val2 == (Object)null)
					{
						continue;
					}
					string text2 = ((Object)val2).name.ToLowerInvariant();
					if ((text.Contains("body") && text2.Contains("body")) || (text.Contains("label") && text2.Contains("label")) || (text.Contains("lid") && text2.Contains("lid")))
					{
						val.sharedMesh = val2.sharedMesh;
						MeshRenderer component = ((Component)val).GetComponent<MeshRenderer>();
						MeshRenderer component2 = ((Component)val2).GetComponent<MeshRenderer>();
						if ((Object)(object)component != (Object)null && (Object)(object)component2 != (Object)null)
						{
							((Renderer)component).sharedMaterials = ((Renderer)component2).sharedMaterials;
						}
						break;
					}
				}
			}
		}

		private static void ApplySuperGrowMaterialsToRenderers(Renderer[]? renderers)
		{
			SuperGrowVisuals.ApplySuperGrowMaterialsToRenderers(renderers);
		}

		private static void SetupAdditiveStationItem(string additiveId, StationItem templateStationItem)
		{
			ItemDefinition item = Registry.GetItem(additiveId);
			StorableItemDefinition val = (StorableItemDefinition)(object)((item is StorableItemDefinition) ? item : null);
			if ((Object)(object)val == (Object)null)
			{
				MelonLogger.Warning("Could not find additive: " + additiveId);
			}
			else if (!((Object)(object)val.StationItem != (Object)null))
			{
				val.StationItem = templateStationItem;
			}
		}

		private static void SwapTrashItemVisualsById(string id, TrashItem trashItem)
		{
			if ((Object)(object)trashItem == (Object)null || string.IsNullOrEmpty(id))
			{
				return;
			}
			bool flag = id == "supergrow";
			if (!flag && id != "pgr" && id != "speedgrow" && id != "fertilizer")
			{
				return;
			}
			GameObject value = null;
			if (flag)
			{
				_pourablePrefabs.TryGetValue("pgr", out value);
			}
			else
			{
				_pourablePrefabs.TryGetValue(id, out value);
			}
			if ((Object)(object)value == (Object)null)
			{
				return;
			}
			try
			{
				if (!((Object)(object)((Component)trashItem).transform == (Object)null))
				{
					SwapBottleMeshesAndMaterials(value, ((Component)trashItem).transform);
					if (flag)
					{
						ApplySuperGrowMaterialsToRenderers(((Component)trashItem).GetComponentsInChildren<Renderer>(true));
					}
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Error("Failed to swap trash visuals for " + id + ": " + ex.Message);
				MelonLogger.Error(ex.StackTrace);
			}
		}

		private static void SwapStationItemVisualsById(string id, StationItem stationItem)
		{
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)stationItem == (Object)null || string.IsNullOrEmpty(id))
			{
				return;
			}
			bool flag = id == "supergrow";
			if (!flag && id != "pgr" && id != "speedgrow" && id != "fertilizer")
			{
				return;
			}
			GameObject value = null;
			if (flag)
			{
				_pourablePrefabs.TryGetValue("pgr", out value);
			}
			else
			{
				_pourablePrefabs.TryGetValue(id, out value);
			}
			if ((Object)(object)value == (Object)null)
			{
				return;
			}
			try
			{
				Transform val = FindStationItemBottleContainer(stationItem);
				if ((Object)(object)val == (Object)null)
				{
					return;
				}
				SwapBottleMeshesAndMaterials(value, val);
				if (flag)
				{
					ApplySuperGrowMaterialsToRenderers(((Component)val).GetComponentsInChildren<Renderer>(true));
				}
				object obj;
				if (!((Object)(object)((Component)stationItem).transform != (Object)null))
				{
					obj = null;
				}
				else
				{
					Transform obj2 = ((Component)stationItem).transform.Find("Pourable");
					obj = ((obj2 != null) ? ((Component)obj2).GetComponent<PourableModule>() : null);
				}
				PourableModule val2 = (PourableModule)obj;
				if ((Object)(object)val2 != (Object)null && (Object)(object)val2.LiquidContainer != (Object)null)
				{
					LiquidContainer liquidContainer = val2.LiquidContainer;
					if ((Object)(object)liquidContainer.LiquidVolume != (Object)null)
					{
						Transform transform = ((Component)liquidContainer.LiquidVolume).transform;
						transform.localScale *= 0.65f;
					}
					liquidContainer.MaxLevel *= 0.65f;
					if (_additiveColors.TryGetValue(id, out var value2))
					{
						val2.LiquidType = id;
						val2.LiquidColor = value2;
						val2.PourParticlesColor = value2;
						liquidContainer.SetLiquidColor(value2, true, true);
					}
				}
				if (!flag && (id == "pgr" || id == "speedgrow" || id == "fertilizer") && TryGetMonoBottleTrashPrefab(id, out TrashItem prefab))
				{
					stationItem.TrashPrefab = prefab;
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Error("Failed to swap station item visuals for " + id + ": " + ex.Message);
				MelonLogger.Error(ex.StackTrace);
			}
		}

		private static void SwapStationItemVisualsById(string id, StationItem stationItem, StorableItemDefinition itemDef)
		{
			if (!((Object)(object)stationItem == (Object)null) && !((Object)(object)itemDef == (Object)null))
			{
				SwapStationItemVisualsById(id, stationItem);
			}
		}

		private static void SwapStationItemVisuals(StationItem stationItem, StorableItemDefinition itemDef)
		{
			string iD = ((BaseItemDefinition)itemDef).ID;
			SwapStationItemVisualsById(iD, stationItem, itemDef);
		}

		[HarmonyPatch(typeof(StationItem), "Initialize")]
		[HarmonyPostfix]
		private static void StationItem_Initialize_Postfix(StationItem __instance, StorableItemDefinition itemDefinition)
		{
			SwapStationItemVisuals(__instance, itemDefinition);
		}
	}
	[HarmonyPatch]
	internal static class GrowContainerPatches
	{
		private static readonly string[] SuperGrowSupersededAdditiveIds = new string[3] { "pgr", "speedgrow", "fertilizer" };

		private const string SuperGrowBottleTrashId = "supergrow_bottle";

		private static bool _loggedGrowContainerTrashPrefabAssignException;

		private static readonly Vector3 HiddenPrefabPosition = new Vector3(100000f, 100000f, 100000f);

		private static Pourable? _superGrowPourablePrefab;

		private const int MaxTaskLogs = 50;

		private const int MaxTrashLogs = 200;

		private const int TrashLogWindowSize = 40;

		private static int _taskLogCount;

		private static int _trashLogCount;

		private static int _trashLogWindowRemaining;

		private static readonly HashSet<string> _loggedOnceKeys = new HashSet<string>();

		private static int _removeItemDepth;

		private static bool _shouldReskinNextTrashSpawn;

		private static readonly HashSet<string> _loggedReskinnedTrashIds = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

		[HarmonyPatch(typeof(GrowContainer), "CanApplyAdditive")]
		[HarmonyPrefix]
		private static bool GrowContainer_CanApplyAdditive_Prefix(GrowContainer __instance, AdditiveDefinition additiveDef, out string invalidReason, ref bool __result)
		{
			invalidReason = string.Empty;
			try
			{
				if ((Object)(object)__instance != (Object)null && (Object)(object)additiveDef != (Object)null && Array.IndexOf(SuperGrowSupersededAdditiveIds, ((BaseItemDefinition)additiveDef).ID) >= 0 && __instance.IsAdditiveApplied("supergrow"))
				{
					invalidReason = "Already contains SuperGrow";
					__result = false;
					return false;
				}
			}
			catch (Exception ex)
			{
				MelonLogger.Error("SuperGrow additive exclusivity check failed: " + ex.Message);
			}
			return true;
		}

		private static void InjectSuperGrowIntoAllowedAdditives(GrowContainer container)
		{
			try
			{
				ItemDefinition item = Registry.GetItem("supergrow");
				AdditiveDefinition val = (AdditiveDefinition)(object)((item is AdditiveDefinition) ? item : null);
				if ((Object)(object)val == (Object)null)
				{
					return;
				}
				if (container.AllowedAdditives != null)
				{
					AdditiveDefinition[] allowedAdditives = container.AllowedAdditives;
					foreach (AdditiveDefinition val2 in allowedAdditives)
					{
						if ((Object)(object)val2 != (Object)null && ((BaseItemDefinition)val2).ID == "supergrow")
						{
							return;
						}
					}
				}
				AdditiveDefinition[] array = container.AllowedAdditives ?? Array.Empty<AdditiveDefinition>();
				AdditiveDefinition[] array2 = (AdditiveDefinition[])(object)new AdditiveDefinition[array.Length + 1];
				array.CopyTo(array2, 0);
				array2[^1] = val;
				container.AllowedAdditives = array2;
			}
			catch (Exception ex)
			{
				MelonLogger.Error("Failed to inject SuperGrow into AllowedAdditives: " + ex.Message);
			}
		}

		[HarmonyPatch(typeof(GrowContainer), "InitializeGridItem")]
		[HarmonyPrefix]
		private static void GrowContainer_InitializeGridItem_Prefix(GrowContainer __instance)
		{
			InjectSuperGrowIntoAllowedAdditives(__instance);
		}

		private static Pourable? GetOrCreateSuperGrowPourablePrefab(Pourable basePrefab)
		{
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_superGrowPourablePrefab != (Object)null && (Object)(object)((Component)_superGrowPourablePrefab).gameObject != (Object)null)
			{
				return _superGrowPourablePrefab;
			}
			if ((Object)(object)basePrefab == (Object)null || (Object)(object)((Component)basePrefab).gameObject == (Object)null)
			{
				return null;
			}
			try
			{
				GameObject val = Object.Instantiate<GameObject>(((Component)basePrefab).gameObject);
				((Object)val).name = "SuperGrow_PourablePrefab";
				((Object)val).hideFlags = (HideFlags)61;
				Object.DontDestroyOnLoad((Object)(object)val);
				val.transform.position = HiddenPrefabPosition;
				if (!val.activeSelf)
				{
					val.SetActive(true);
				}
				Pourable component = val.GetComponent<Pourable>();
				if ((Object)(object)component == (Object)null)
				{
					Object.Destroy((Object)(object)val);
					return null;
				}
				PourableAdditive component2 = val.GetComponent<PourableAdditive>();
				if ((Object)(object)component2 != (Object)null)
				{
					component2.LiquidColor = SuperGrowVisuals.PourColor;
				}
				ParticleSystem[] componentsInChildren = val.GetComponentsInChildren<ParticleSystem>(true);
				foreach (ParticleSystem val2 in componentsInChildren)
				{
					if (!((Object)(object)val2 == (Object)null))
					{
						MainModule main = val2.main;
						((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(SuperGrowVisuals.PourColor);
					}
				}
				SuperGrowVisuals.ApplySuperGrowMaterialsToRenderers(val.GetComponentsInChildren<Renderer>(true));
				try
				{
					TrashManager val3 = Object.FindObjectOfType<TrashManager>();
					if ((Object)(object)val3 != (Object)null)
					{
						TrashItem trashPrefab = val3.GetTrashPrefab("supergrow_bottle");
						if ((Object)(object)trashPrefab != (Object)null)
						{
							component.TrashItem = trashPrefab;
						}
					}
				}
				catch (Exception ex)
				{
					if (!_loggedGrowContainerTrashPrefabAssignException)
					{
						_loggedGrowContainerTrashPrefabAssignException = true;
						MelonLogger.Warning("Failed to assign SuperGrow trash prefab to grow-container pourable: " + ex.Message);
						MelonLogger.Warning(ex.StackTrace ?? "<no stack trace>");
					}
				}
				_superGrowPourablePrefab = component;
				return _superGrowPourablePrefab;
			}
			catch (Exception ex2)
			{
				MelonLogger.Error("Failed to create SuperGrow pourable prefab: " + ex2.Message);
				MelonLogger.Error(ex2.StackTrace);
				return null;
			}
		}

		private static void LogOnce(string key, string message)
		{
			if (_loggedOnceKeys.Add(key))
			{
				LogImportant(message);
			}
		}

		private static void LogImportant(string message)
		{
			MelonLogger.Msg("[GrowContainerPatches.Diagnostics] " + message);
		}

		private static void LogTask(string message)
		{
			if (_taskLogCount < 50)
			{
				_taskLogCount++;
				MelonLogger.Msg("[GrowContainerPatches.Diagnostics] " + message);
			}
		}

		private static void LogTrash(string message)
		{
			if (_trashLogCount < 200)
			{
				_trashLogCount++;
				MelonLogger.Msg("[GrowContainerPatches.Diagnostics] " + message);
			}
		}

		private static void OpenTrashLogWindow()
		{
			_trashLogWindowRemaining = 40;
		}

		private static bool ShouldLogTrash(string requestedId)
		{
			if (_trashLogWindowRemaining > 0)
			{
				_trashLogWindowRemaining--;
				return true;
			}
			if (string.IsNullOrWhiteSpace(requestedId))
			{
				return false;
			}
			string text = requestedId.Trim();
			if (text.Equals("pgr", StringComparison.OrdinalIgnoreCase) || text.Equals("acid", StringComparison.OrdinalIgnoreCase) || text.Contains("supergrow", StringComparison.OrdinalIgnoreCase))
			{
				return true;
			}
			return false;
		}

		private static void DumpTaskState(string hook, object task)
		{
			if (task == null)
			{
				LogTask(hook + ": <null task>");
				return;
			}
			Type type = task.GetType();
			string text = type.FullName ?? type.Name;
			string text2 = "<unknown>";
			string text3 = "<unknown>";
			string text4 = "<unknown>";
			try
			{
				FieldInfo field = type.GetField("item", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				PropertyInfo propertyInfo = ((field == null) ? type.GetProperty("item", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) : null);
				object obj = field?.GetValue(task) ?? propertyInfo?.GetValue(task);
				if (obj != null)
				{
					Type type2 = obj.GetType();
					object obj2 = AccessTools.Property(type2, "Definition")?.GetValue(obj);
					if (obj2 != null)
					{
						text2 = (AccessTools.Property(obj2.GetType(), "ID")?.GetValue(obj2) as string) ?? text2;
					}
					text2 = (AccessTools.Property(type2, "ID")?.GetValue(obj) as string) ?? text2;
				}
				FieldInfo field2 = type.GetField("pourable", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				PropertyInfo propertyInfo2 = ((field2 == null) ? type.GetProperty("pourable", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) : null);
				object obj3 = field2?.GetValue(task) ?? propertyInfo2?.GetValue(task);
				if (obj3 != null)
				{
					Type type3 = obj3.GetType();
					text3 = type3.FullName ?? type3.Name;
					object obj4 = AccessTools.Property(type3, "TrashItem")?.GetValue(obj3);
					if (obj4 != null)
					{
						Type type4 = obj4.GetType();
						text4 = (type4.GetField("ID", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(obj4) as string) ?? text4;
						text4 = (type4.GetProperty("ID", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(obj4) as string) ?? text4;
					}
				}
			}
			catch (Exception ex)
			{
				LogOnce("DumpTaskStateError:" + text, hook + ": error dumping task state for " + text + ": " + ex.GetType().Name + ": " + ex.Message);
			}
			LogTask(hook + ": task=" + text + " itemId=" + text2 + " pourable=" + text3 + " trashId=" + text4);
		}

		[HarmonyPatch(typeof(GrowContainerPourTask), "OnInitialPour")]
		[HarmonyPostfix]
		private static void GrowContainerPourTask_OnIni