Decompiled source of UnicornsCustomSeeds v2.0.0

UnicornsCustomSeeds_Mono_2.0.0.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using FishNet;
using FishNet.Connection;
using FishNet.Managing.Server;
using FishNet.Serializing;
using FluffyUnderware.DevTools.Extensions;
using HarmonyLib;
using MelonLoader;
using MelonLoader.Preferences;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using S1API.Quests;
using S1API.Saveables;
using ScheduleOne;
using ScheduleOne.AvatarFramework.Equipping;
using ScheduleOne.Core.Items.Framework;
using ScheduleOne.DevUtilities;
using ScheduleOne.Dialogue;
using ScheduleOne.Economy;
using ScheduleOne.EntityFramework;
using ScheduleOne.Equipping;
using ScheduleOne.Growing;
using ScheduleOne.ItemFramework;
using ScheduleOne.Management;
using ScheduleOne.Messaging;
using ScheduleOne.Money;
using ScheduleOne.NPCs;
using ScheduleOne.NPCs.CharacterClasses;
using ScheduleOne.NPCs.Relation;
using ScheduleOne.ObjectScripts;
using ScheduleOne.Persistence;
using ScheduleOne.PlayerScripts;
using ScheduleOne.PlayerTasks;
using ScheduleOne.Product;
using ScheduleOne.Quests;
using ScheduleOne.StationFramework;
using ScheduleOne.Storage;
using ScheduleOne.UI;
using ScheduleOne.UI.MainMenu;
using ScheduleOne.UI.Phone;
using ScheduleOne.UI.Phone.Delivery;
using ScheduleOne.UI.Phone.Messages;
using ScheduleOne.UI.Phone.ProductManagerApp;
using ScheduleOne.UI.Shop;
using ScheduleOne.UI.Stations;
using TMPro;
using UnicornsCustomSeeds;
using UnicornsCustomSeeds.Managers;
using UnicornsCustomSeeds.Patches;
using UnicornsCustomSeeds.SeedQuests;
using UnicornsCustomSeeds.Seeds;
using UnicornsCustomSeeds.TemplateUtils;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: MelonInfo(typeof(Core), "Unicorns Custom Seeds", "2.0.0", "OverweightUnicorn", null)]
[assembly: MelonColor(255, 191, 0, 255)]
[assembly: MelonGame("TVGS", "Schedule I")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("ScheduleOne.Core")]
[assembly: AssemblyCompany("UnicornsCustomSeeds_Mono_2.0.0")]
[assembly: AssemblyConfiguration("MONO")]
[assembly: AssemblyFileVersion("2.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+944875e616eabfb2a5ccce7b3ee0d6be3e0f1252")]
[assembly: AssemblyProduct("UnicornsCustomSeeds_Mono_2.0.0")]
[assembly: AssemblyTitle("UnicornsCustomSeeds_Mono_2.0.0")]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace UnicornsCustomSeeds
{
	public static class BuildInfo
	{
		public const string Name = "Unicorns Custom Seeds";

		public const string Description = "Your good buddy Unicorn can help you synthesize seeds";

		public const string Author = "OverweightUnicorn";

		public const string Company = "UnicornsCanMod";

		public const string Version = "2.0.0";

		public const string DownloadLink = null;
	}
	public class Core : MelonMod
	{
		public static bool ModInitialized;

		public override void OnInitializeMelon()
		{
			StashManager.InitializeConfig();
			AssetBundleUtils.Initialize(this);
		}

		public override void OnLateInitializeMelon()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			SeedVisualsManager.LoadSeedMaterial();
			Singleton<LoadManager>.Instance.onLoadComplete.AddListener(new UnityAction(InitMod));
			Singleton<SaveManager>.Instance.onSaveComplete.AddListener(new UnityAction(SaveData));
		}

		public void SaveData()
		{
			TrySaveData();
		}

		public bool TrySaveData()
		{
			try
			{
				string loadedGameFolderPath = Singleton<LoadManager>.Instance.LoadedGameFolderPath;
				if (string.IsNullOrEmpty(loadedGameFolderPath) || !Directory.Exists(loadedGameFolderPath))
				{
					Utility.Error("Core.TrySaveData: save folder unavailable ('" + loadedGameFolderPath + "') — nothing written.");
					return false;
				}
				List<UnicornSeedData> list = new List<UnicornSeedData>();
				list.AddRange(CustomSeedsManager.DiscoveredSeeds.Values);
				list.AddRange(CustomShroomsManager.DiscoveredShrooms.Values);
				list.AddRange(CustomCocaSeedsManager.DiscoveredCocaSeeds.Values);
				list.AddRange(CustomPseudoManager.DiscoveredPseudoSeeds.Values);
				string contents = JsonConvert.SerializeObject((object)list, (Formatting)1);
				File.WriteAllText(Path.Combine(loadedGameFolderPath, "DiscoveredCustomSeeds.json"), contents);
				List<ActiveCookingEntry> list2 = new List<ActiveCookingEntry>();
				foreach (KeyValuePair<string, string> item in ActiveCookingRegistry.GuidToMixId)
				{
					list2.Add(new ActiveCookingEntry
					{
						stationGuid = item.Key,
						mixId = item.Value
					});
				}
				string contents2 = JsonConvert.SerializeObject((object)list2, (Formatting)1);
				File.WriteAllText(Path.Combine(loadedGameFolderPath, "UnicornsActiveCooking.json"), contents2);
				return true;
			}
			catch (Exception e)
			{
				Utility.PrintException(e);
				return false;
			}
		}

		public void InitMod()
		{
			Utility.Log($"InitMod: start (IsServer={InstanceFinder.IsServer}, IsClientOnly={InstanceFinder.IsClientOnly}).");
			CustomSeedsManager.Initialize();
			CustomShroomsManager.Initialize();
			CustomCocaSeedsManager.Initialize();
			CustomPseudoManager.Initialize();
			StashManager.GetAlbertsStash();
			if (CustomSeedsManager.letsMigrate)
			{
				bool flag = CustomSeedsManager.DiscoveredSeeds.Count > 0 || CustomShroomsManager.DiscoveredShrooms.Count > 0 || CustomCocaSeedsManager.DiscoveredCocaSeeds.Count > 0;
				int num = CustomSeedsManager.DiscoveredSeeds.Count + CustomShroomsManager.DiscoveredShrooms.Count + CustomCocaSeedsManager.DiscoveredCocaSeeds.Count + CustomPseudoManager.DiscoveredPseudoSeeds.Count;
				if (!flag)
				{
					Utility.Error("[MIGRATE] flagged but nothing loaded — skipping the save so the existing file isn't overwritten with an empty list.");
				}
				else if (!TrySaveData())
				{
					Utility.Error("[MIGRATE] rewrite FAILED — legacy file untouched, will retry on next load.");
				}
				else if (!LoadManager_StartGame_Patch.VerifyMigratedFile())
				{
					Utility.Error("[MIGRATE] save reported success but the file on disk is still legacy — will retry on next load.");
				}
				else
				{
					Utility.Success($"[MIGRATE] {num} record(s) converted and rewritten in the new format.");
					CustomSeedsManager.letsMigrate = false;
				}
			}
			DeferredCookOpsManager.TryReplayAll();
			MelonCoroutines.Start(StashManager.WaitForAllStashesAndSubscribe());
		}

		public override void OnSceneWasLoaded(int buildIndex, string sceneName)
		{
			SeedDefinition item = Registry.GetItem<SeedDefinition>("ogkushseed");
			if (CustomSeedsManager.factory == null && (Object)(object)item != (Object)null)
			{
				CustomSeedsManager.factory = new SeedFactory(item);
			}
			SporeSyringeDefinition item2 = Registry.GetItem<SporeSyringeDefinition>("sporesyringe");
			if (CustomShroomsManager.factory == null && (Object)(object)item2 != (Object)null)
			{
				CustomShroomsManager.factory = new SyringeFactory(item2);
			}
			Dictionary<int, ItemRegister> itemDictionary = Singleton<Registry>.Instance.ItemDictionary;
			SeedDefinition item3 = Registry.GetItem<SeedDefinition>("cocaseed");
			QualityItemDefinition item4 = Registry.GetItem<QualityItemDefinition>("cocaleaf");
			QualityItemDefinition item5 = Registry.GetItem<QualityItemDefinition>("cocainebase");
			if (CustomCocaSeedsManager.factory == null && (Object)(object)item3 != (Object)null && (Object)(object)item4 != (Object)null && (Object)(object)item5 != (Object)null)
			{
				CustomCocaSeedsManager.factory = new CocaFactory(item3, item4, item5);
			}
			else if (CustomCocaSeedsManager.factory == null)
			{
				Utility.Critical("Unicorns Custom Seeds: coca seeds are unavailable — CocaFactory could not initialize.");
				Utility.Error($"Core: CocaFactory init failed — cocaseed={(Object)(object)item3 != (Object)null}, cocaleaf={(Object)(object)item4 != (Object)null}, cocainebase={(Object)(object)item5 != (Object)null}");
			}
			if (sceneName.ToLower() != "main")
			{
				CustomSeedsManager.ClearAll();
				CustomShroomsManager.ClearAll();
				CustomCocaSeedsManager.ClearAll();
				CustomPseudoManager.ClearAll();
				ActiveCookingRegistry.Clear();
				ProductManagerAppPatches.ClearPendingIndicators();
				StashManager.ClearCaches();
				DeferredSlotsManager.ClearAll();
				DeferredCookOpsManager.ClearAll();
				ModInitialized = false;
			}
			else
			{
				if ((Object)(object)SeedVisualsManager.baseQuestIconSprite == (Object)null || (Object)(object)SeedVisualsManager.baseSeedSprite == (Object)null)
				{
					SeedVisualsManager.LoadSeedMaterial();
				}
				if (CustomPseudoManager.factory == null)
				{
					MelonCoroutines.Start(InitPseudoFactoryWhenReady());
				}
			}
		}

		private IEnumerator InitPseudoFactoryWhenReady()
		{
			int timeoutFrames = 1800;
			while (timeoutFrames-- > 0)
			{
				bool ready = false;
				try
				{
					ChemistryStationInterface instance = Singleton<ChemistryStationInterface>.Instance;
					ready = instance != null && instance.Recipes?.Count > 0;
				}
				catch
				{
				}
				if (ready)
				{
					break;
				}
				yield return null;
			}
			if (timeoutFrames <= 0)
			{
				Utility.Critical("Unicorns Custom Seeds: custom meth is unavailable — timed out waiting for the chemistry station's recipe list.");
				Utility.Error("Core: Timed out waiting for ChemistryStationInterface.Recipes — PseudoFactory not initialized.");
				yield break;
			}
			try
			{
				QualityItemDefinition basePseudo = Registry.GetItem<QualityItemDefinition>("pseudo");
				QualityItemDefinition lowPseudo = Registry.GetItem<QualityItemDefinition>("lowqualitypseudo");
				QualityItemDefinition highPseudo = Registry.GetItem<QualityItemDefinition>("highqualitypseudo");
				ItemDefinition rawLiquidMeth = Registry.GetItem("liquidmeth");
				LiquidMethDefinition baseLiquidMeth = (LiquidMethDefinition)(object)((rawLiquidMeth is LiquidMethDefinition) ? rawLiquidMeth : null);
				StationRecipe baseRecipe = null;
				foreach (StationRecipe r in Singleton<ChemistryStationInterface>.Instance.Recipes)
				{
					if (((BaseItemDefinition)(r.Product?.Item?)).ID == "liquidmeth")
					{
						baseRecipe = r;
						break;
					}
				}
				if ((Object)(object)basePseudo != (Object)null && (Object)(object)lowPseudo != (Object)null && (Object)(object)highPseudo != (Object)null && (Object)(object)baseLiquidMeth != (Object)null && (Object)(object)baseRecipe != (Object)null)
				{
					CustomPseudoManager.factory = new PseudoFactory(basePseudo, lowPseudo, highPseudo, baseLiquidMeth, baseRecipe);
					Utility.Log("Core: PseudoFactory initialized.");
					yield break;
				}
				Utility.Critical("Unicorns Custom Seeds: custom meth is unavailable — PseudoFactory could not initialize.");
				Utility.Error($"Core: PseudoFactory init failed — pseudo={(Object)(object)basePseudo != (Object)null}, lowPseudo={(Object)(object)lowPseudo != (Object)null}, highPseudo={(Object)(object)highPseudo != (Object)null}, liquidmeth={(Object)(object)baseLiquidMeth != (Object)null}, recipe={(Object)(object)baseRecipe != (Object)null}");
			}
			catch (Exception e)
			{
				Utility.PrintException(e);
			}
		}
	}
}
namespace UnicornsCustomSeeds.TemplateUtils
{
	public static class AssetBundleUtils
	{
		private static Core mod;

		private static MelonAssembly melonAssembly;

		private static Dictionary<string, AssetBundle> assetBundles = new Dictionary<string, AssetBundle>();

		private static string DataFolderName = "UnicornsCanBundle";

		private static string ModFolderName = "UnicornsCustomSeeds";

		public static void Initialize(Core coreMod)
		{
			mod = coreMod;
			melonAssembly = ((MelonBase)mod).MelonAssembly;
		}

		public static AssetBundle LoadAssetBundle(string bundleFileName)
		{
			if (assetBundles.TryGetValue(bundleFileName, out var value) && (Object)(object)value != (Object)null)
			{
				return value;
			}
			try
			{
				string text = typeof(Core).Namespace + ".Assets." + bundleFileName;
				Stream manifestResourceStream = melonAssembly.Assembly.GetManifestResourceStream(text ?? "");
				if (manifestResourceStream == null)
				{
					((MelonBase)mod).Unregister("AssetBundle resource '" + text + "' not found.", false);
					return null;
				}
				byte[] array;
				using (manifestResourceStream)
				{
					using MemoryStream memoryStream = new MemoryStream();
					manifestResourceStream.CopyTo(memoryStream);
					array = memoryStream.ToArray();
				}
				if (array.Length == 0)
				{
					((MelonBase)mod).Unregister("AssetBundle '" + bundleFileName + "' is empty.", false);
					return null;
				}
				AssetBundle val = AssetBundle.LoadFromMemory(array);
				if ((Object)(object)val == (Object)null)
				{
					((MelonBase)mod).Unregister("Failed to load required AssetBundle '" + bundleFileName + "'.", false);
					return null;
				}
				assetBundles[bundleFileName] = val;
				return val;
			}
			catch (Exception arg)
			{
				((MelonBase)mod).Unregister($"Failed to load required AssetBundle '{bundleFileName}': {arg}", false);
				return null;
			}
		}

		public static void ClearCache()
		{
			assetBundles.Clear();
		}

		public static AssetBundle GetLoadedAssetBundle(string bundleName)
		{
			if (assetBundles.ContainsKey(bundleName))
			{
				return assetBundles[bundleName];
			}
			Utility.Warn("Asset bundle '" + bundleName + "' is not loaded.");
			return null;
		}

		public static T LoadAssetFromBundle<T>(string assetName, string bundleName) where T : Object
		{
			AssetBundle loadedAssetBundle = GetLoadedAssetBundle(bundleName);
			if ((Object)(object)loadedAssetBundle == (Object)null)
			{
				Utility.Error("Couldn't find loaded bundle '" + bundleName + "'.");
				return default(T);
			}
			T val = default(T);
			try
			{
				val = loadedAssetBundle.LoadAsset<T>(assetName);
			}
			catch (Exception arg)
			{
				Utility.Error($"Failed loading asset '{assetName}' from bundle '{bundleName}'. The bundle may be invalid or have a zero internal pointer. {arg}");
				return default(T);
			}
			if ((Object)(object)val == (Object)null)
			{
				Utility.Error("Asset '" + assetName + "' not found in bundle '" + bundleName + "'.");
				return default(T);
			}
			return val;
		}

		public static Texture2D LoadTextureContaining(string bundleName, params string[] contains)
		{
			AssetBundle loadedAssetBundle = GetLoadedAssetBundle(bundleName);
			if ((Object)(object)loadedAssetBundle == (Object)null)
			{
				return null;
			}
			string[] allAssetNames = loadedAssetBundle.GetAllAssetNames();
			for (int i = 0; i < allAssetNames.Length; i++)
			{
				string text = allAssetNames[i].ToLowerInvariant();
				bool flag = true;
				for (int j = 0; j < contains.Length; j++)
				{
					if (!text.Contains(contains[j].ToLowerInvariant()))
					{
						flag = false;
						break;
					}
				}
				if (!flag)
				{
					continue;
				}
				try
				{
					Texture2D val = loadedAssetBundle.LoadAsset<Texture2D>(allAssetNames[i]);
					if ((Object)(object)val != (Object)null)
					{
						return val;
					}
				}
				catch (Exception ex)
				{
					Utility.Warn("Failed loading texture '" + allAssetNames[i] + "' from bundle '" + bundleName + "': " + ex.Message);
				}
			}
			return null;
		}
	}
	public static class Utility
	{
		public static MelonPreferences_Entry<bool> DebugEntry;

		public static bool IsDebug => DebugEntry != null && DebugEntry.Value;

		public static void Critical(string msg)
		{
			MelonLogger.Msg(ConsoleColor.Red, msg + " (enable DebugLogging in this mod's MelonPreferences for details)");
		}

		public static void PrintException(Exception e, string source, bool handled = true)
		{
			if (IsDebug)
			{
				MelonLogger.Msg(handled ? ConsoleColor.DarkYellow : ConsoleColor.Red, handled ? ("Caught in " + source + " — handled by the mod, the game did not halt:") : ("Unhandled in " + source + ":"));
				PrintException(e);
			}
		}

		public static void PrintException(Exception e)
		{
			if (!IsDebug)
			{
				return;
			}
			MelonLogger.Msg(ConsoleColor.Red, e.GetType().FullName);
			MelonLogger.Msg(ConsoleColor.DarkRed, e.Message);
			if (!string.IsNullOrWhiteSpace(e.StackTrace))
			{
				MelonLogger.Msg(ConsoleColor.DarkRed, "StackTrace:");
				string[] array = e.StackTrace.Split('\n');
				foreach (string text in array)
				{
					MelonLogger.Msg(ConsoleColor.DarkRed, "    " + text.Trim());
				}
			}
			if (e.InnerException != null)
			{
				MelonLogger.Msg(ConsoleColor.DarkRed, "  -- Inner Exception --");
				PrintException(e.InnerException);
			}
		}

		public static void Error(string msg)
		{
			if (IsDebug)
			{
				MelonLogger.Msg(ConsoleColor.Red, msg);
			}
		}

		public static void Warn(string msg)
		{
			if (IsDebug)
			{
				MelonLogger.Msg(ConsoleColor.Yellow, msg);
			}
		}

		public static void Log(string msg)
		{
			if (IsDebug)
			{
				MelonLogger.Msg(ConsoleColor.DarkMagenta, msg);
			}
		}

		public static void Success(string msg)
		{
			if (IsDebug)
			{
				MelonLogger.Msg(ConsoleColor.Green, msg);
			}
		}
	}
}
namespace UnicornsCustomSeeds.Seeds
{
	public class CocaFactory
	{
		private const float CocaIconRotation = 45f;

		public static readonly Dictionary<string, string> CustomLeafIdToBaseId = new Dictionary<string, string>();

		public static readonly Dictionary<string, string> CustomBaseIdToMixId = new Dictionary<string, string>();

		private Transform rootGameObject;

		private SeedDefinition baseSeedDefinition;

		private CocaPlant baseCocaPlantPrefab;

		private PlantHarvestable baseHarvestable;

		private FunctionalSeed baseFunctionalSeedPrefab;

		private Equippable_Seed baseEquippableSeedPrefab;

		private AvatarEquippable baseAvatarEquippablePrefab;

		private StoredItem baseStoredItem;

		private QualityItemDefinition baseCocaLeafDefinition;

		private QualityItemDefinition baseCocaineBaseDefinition;

		public CocaFactory(SeedDefinition baseSeed, QualityItemDefinition baseCocaLeaf, QualityItemDefinition baseCocaineBase)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Expected O, but got Unknown
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Expected O, but got Unknown
			baseSeedDefinition = baseSeed;
			baseCocaLeafDefinition = baseCocaLeaf;
			baseCocaineBaseDefinition = baseCocaineBase;
			baseCocaPlantPrefab = (CocaPlant)baseSeed.PlantPrefab;
			if ((Object)(object)baseCocaPlantPrefab == (Object)null)
			{
				Utility.Error("CocaFactory: Failed to cast PlantPrefab to CocaPlant.");
			}
			baseHarvestable = baseCocaPlantPrefab?.Harvestable;
			baseFunctionalSeedPrefab = baseSeed.FunctionSeedPrefab;
			baseStoredItem = ((StorableItemDefinition)baseSeed).StoredItem;
			baseEquippableSeedPrefab = (Equippable_Seed)((ItemDefinition)baseSeed).Equippable;
			if ((Object)(object)baseEquippableSeedPrefab == (Object)null)
			{
				Utility.Error("CocaFactory: Failed to cast Equippable to Equippable_Seed.");
			}
			baseAvatarEquippablePrefab = ((Equippable_Viewmodel)(baseEquippableSeedPrefab?)).AvatarEquippable;
			GameObject val = new GameObject(((BaseItemDefinition)baseSeedDefinition).ID + "_CustomCocaSeeds");
			val.SetActive(false);
			Object.DontDestroyOnLoad((Object)(object)val);
			rootGameObject = val.transform;
		}

		public void DeleteChildren()
		{
			TransformExt.DeleteChildren(rootGameObject, true, false);
			CustomLeafIdToBaseId.Clear();
			CustomBaseIdToMixId.Clear();
		}

		public SeedDefinition CreateCocaSeedDefinition(ProductDefinition cocaineDef)
		{
			if ((Object)(object)baseSeedDefinition == (Object)null)
			{
				throw new InvalidOperationException("Base seed definition not initialized.");
			}
			CocaineAppearanceSettings val = ResolveCocaAppearance(cocaineDef);
			QualityItemDefinition val2 = CloneCustomCocaineBase(cocaineDef, val);
			QualityItemDefinition val3 = CloneCustomCocaLeaf(val2, cocaineDef, val);
			CocaPlant plantPrefab = CloneCocaPlant(val3);
			SeedDefinition val4 = Object.Instantiate<SeedDefinition>(baseSeedDefinition);
			((BaseItemDefinition)val4).ID = ((BaseItemDefinition)cocaineDef).ID + "_customcocaseed";
			((Object)val4).name = ((BaseItemDefinition)val4).ID;
			((BaseItemDefinition)val4).Name = ((Object)cocaineDef).name + " Coca Seed";
			((BaseItemDefinition)val4).Description = "A custom coca seed that produces " + ((Object)cocaineDef).name + ".";
			((BaseItemDefinition)val4).Icon = ((BaseItemDefinition)baseSeedDefinition).Icon;
			SeedVisualsManager.cocaAppearanceMap[((BaseItemDefinition)val4).ID] = val;
			val4.PlantPrefab = (Plant)(object)plantPrefab;
			val4.PlantPrefab.SeedDefinition = val4;
			val4.FunctionSeedPrefab = CloneFunctionalSeedPrefab(((BaseItemDefinition)val4).ID);
			((Object)val4.FunctionSeedPrefab).name = ((BaseItemDefinition)cocaineDef).ID + "CocaSeed_Functional";
			((ItemDefinition)val4).Equippable = (Equippable)(object)CloneEquippableSeedPrefab(val4);
			((StorableItemDefinition)val4).StoredItem = CloneStoredItem(((BaseItemDefinition)val4).ID);
			AssignCocaIcon(val4, val);
			Singleton<Registry>.Instance.AddToRegistry((ItemDefinition)(object)val3);
			Singleton<Registry>.Instance.AddToRegistry((ItemDefinition)(object)val2);
			return val4;
		}

		private CocaineAppearanceSettings ResolveCocaAppearance(ProductDefinition cocaineDef)
		{
			CocaineDefinition val = (CocaineDefinition)(object)((cocaineDef is CocaineDefinition) ? cocaineDef : null);
			if ((Object)(object)val == (Object)null)
			{
				Utility.Error("CocaFactory: '" + ((BaseItemDefinition)cocaineDef).ID + "' is not a CocaineDefinition — no appearance available.");
				return null;
			}
			CocaineAppearanceSettings appearanceSettings = val.AppearanceSettings;
			if (appearanceSettings == null || appearanceSettings.IsUnintialized())
			{
				appearanceSettings = CocaineDefinition.GetAppearanceSettings(((PropertyItemDefinition)val).Properties);
			}
			if (appearanceSettings == null)
			{
				Utility.Error("CocaFactory: No appearance settings for '" + ((BaseItemDefinition)cocaineDef).ID + "'.");
			}
			return appearanceSettings;
		}

		private void AssignCocaIcon(SeedDefinition newSeed, CocaineAppearanceSettings appearance)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)SeedVisualsManager.baseSeedSprite == (Object)null || appearance == null)
			{
				return;
			}
			try
			{
				(Color top, Color bottom) tuple = SeedVisualsManager.BoostContrastIfSimilar(Color32.op_Implicit(appearance.MainColor), Color32.op_Implicit(appearance.SecondaryColor));
				Color item = tuple.top;
				Color item2 = tuple.bottom;
				Sprite val = SeedVisualsManager.GenerateIconWithKeyColorFill(SeedVisualsManager.baseCocaSeedSprite, item, item2);
				((Object)val).name = ((Object)newSeed).name + "_icon";
				SeedVisualsManager.seedIcons[((BaseItemDefinition)newSeed).ID] = val;
				((BaseItemDefinition)newSeed).Icon = val;
			}
			catch (Exception e)
			{
				((BaseItemDefinition)newSeed).Icon = SeedVisualsManager.baseSeedSprite;
				Utility.PrintException(e);
			}
		}

		private void AssignCocaIntermediateIcon(QualityItemDefinition clone, Sprite baseIcon, CocaineAppearanceSettings appearance)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)baseIcon == (Object)null || appearance == null)
			{
				return;
			}
			try
			{
				(Color top, Color bottom) tuple = SeedVisualsManager.BoostContrastIfSimilar(Color32.op_Implicit(appearance.MainColor), Color32.op_Implicit(appearance.SecondaryColor));
				Color item = tuple.top;
				Color item2 = tuple.bottom;
				Sprite val = SeedVisualsManager.GenerateIconWithKeyColorFill(baseIcon, item, item2);
				if (!((Object)(object)val == (Object)null))
				{
					((Object)val).name = ((Object)clone).name + "_icon";
					SeedVisualsManager.seedIcons[((BaseItemDefinition)clone).ID] = val;
					((BaseItemDefinition)clone).Icon = val;
				}
			}
			catch (Exception e)
			{
				((BaseItemDefinition)clone).Icon = baseIcon;
				Utility.PrintException(e);
			}
		}

		private void GrowLabel(Transform root, string seedDefId)
		{
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			Transform val = null;
			Transform[] componentsInChildren = ((Component)root).GetComponentsInChildren<Transform>();
			Transform[] array = componentsInChildren;
			foreach (Transform val2 in array)
			{
				if (((Object)val2).name == "Label")
				{
					val = ((Component)val2).transform;
				}
			}
			if ((Object)(object)val != (Object)null)
			{
				val.localScale = new Vector3(1.05f, 1.05f, 2f);
				val.position = new Vector3(0f, -0.05f, 0f);
				if ((Object)(object)SeedVisualsManager.customMat == (Object)null)
				{
					SeedVisualsManager.LoadSeedMaterial();
				}
				if ((Object)(object)SeedVisualsManager.customMat != (Object)null)
				{
					Renderer component = ((Component)val).GetComponent<Renderer>();
					component.material = SeedVisualsManager.customMat;
					((Component)val).gameObject.AddComponent<SeedVialLabel>();
					((Object)val).name = ((Object)val).name + ":" + seedDefId;
				}
				else
				{
					Utility.Log("MATERIAL NOT LOADED!!!");
				}
			}
		}

		private QualityItemDefinition CloneCustomCocaineBase(ProductDefinition cocaineDef, CocaineAppearanceSettings appearance)
		{
			QualityItemDefinition val = Object.Instantiate<QualityItemDefinition>(baseCocaineBaseDefinition);
			((BaseItemDefinition)val).ID = ((BaseItemDefinition)cocaineDef).ID + "_customcocainebase";
			((Object)val).name = ((BaseItemDefinition)val).ID;
			((BaseItemDefinition)val).Name = ((Object)cocaineDef).name + " Base";
			if ((Object)(object)((StorableItemDefinition)baseCocaineBaseDefinition).StationItem != (Object)null)
			{
				StationItem val2 = Object.Instantiate<StationItem>(((StorableItemDefinition)baseCocaineBaseDefinition).StationItem, rootGameObject);
				((Object)val2).name = ((BaseItemDefinition)cocaineDef).ID + "_CocaineBaseStationItem";
				CookableModule module = val2.GetModule<CookableModule>();
				if ((Object)(object)module != (Object)null)
				{
					module.Product = (StorableItemDefinition)(object)cocaineDef;
				}
				else
				{
					Utility.Error("CocaFactory: No CookableModule on StationItem for " + ((BaseItemDefinition)cocaineDef).ID + ". LabOven will output vanilla product.");
				}
				((StorableItemDefinition)val).StationItem = val2;
			}
			else
			{
				Utility.Error("CocaFactory: baseCocaineBaseDefinition.StationItem is null.");
			}
			AssignCocaIntermediateIcon(val, SeedVisualsManager.baseCocaBaseSprite, appearance);
			CustomBaseIdToMixId[((BaseItemDefinition)val).ID] = ((BaseItemDefinition)cocaineDef).ID;
			return val;
		}

		private QualityItemDefinition CloneCustomCocaLeaf(QualityItemDefinition customBase, ProductDefinition cocaineDef, CocaineAppearanceSettings appearance)
		{
			QualityItemDefinition val = Object.Instantiate<QualityItemDefinition>(baseCocaLeafDefinition);
			((BaseItemDefinition)val).ID = ((BaseItemDefinition)cocaineDef).ID + "_customcocaleaf";
			((Object)val).name = ((BaseItemDefinition)val).ID;
			((BaseItemDefinition)val).Name = "Coca Leaf (" + ((Object)cocaineDef).name + ")";
			((StorableItemDefinition)val).StationItem = ((StorableItemDefinition)baseCocaLeafDefinition).StationItem;
			AssignCocaIntermediateIcon(val, SeedVisualsManager.baseCocaLeafSprite, appearance);
			CustomLeafIdToBaseId[((BaseItemDefinition)val).ID] = ((BaseItemDefinition)customBase).ID;
			return val;
		}

		private CocaPlant CloneCocaPlant(QualityItemDefinition customLeaf)
		{
			CocaPlant val = Object.Instantiate<CocaPlant>(baseCocaPlantPrefab, rootGameObject);
			((Object)((Component)val).gameObject).name = ((BaseItemDefinition)customLeaf).ID + "_CocaPlant";
			PlantHarvestable val2 = Object.Instantiate<PlantHarvestable>(baseHarvestable, rootGameObject);
			((Object)((Component)val2).gameObject).name = ((BaseItemDefinition)customLeaf).ID + "_Harvestable";
			val2.Product = (StorableItemDefinition)(object)customLeaf;
			val.Harvestable = val2;
			PlantHarvestable[] componentsInChildren = ((Component)val).GetComponentsInChildren<PlantHarvestable>();
			foreach (PlantHarvestable val3 in componentsInChildren)
			{
				val3.Product = (StorableItemDefinition)(object)customLeaf;
			}
			return val;
		}

		private FunctionalSeed CloneFunctionalSeedPrefab(string seedDefId)
		{
			if ((Object)(object)baseFunctionalSeedPrefab == (Object)null)
			{
				throw new InvalidOperationException("Base functional seed prefab not initialized.");
			}
			FunctionalSeed val = Object.Instantiate<FunctionalSeed>(baseFunctionalSeedPrefab, rootGameObject);
			((Object)((Component)val).gameObject).name = seedDefId + "_Functional";
			GrowLabel(((Component)val).transform, seedDefId);
			return val;
		}

		private Equippable_Seed CloneEquippableSeedPrefab(SeedDefinition newDef)
		{
			if ((Object)(object)baseEquippableSeedPrefab == (Object)null)
			{
				throw new InvalidOperationException("Base equippable seed prefab not initialized.");
			}
			Equippable_Seed val = Object.Instantiate<Equippable_Seed>(baseEquippableSeedPrefab, rootGameObject);
			GrowLabel(((Component)val).transform, ((BaseItemDefinition)newDef).ID);
			((Object)((Component)val).gameObject).name = ((BaseItemDefinition)newDef).ID + "_Equippable";
			((Component)val).gameObject.layer = ((Component)baseEquippableSeedPrefab).gameObject.layer;
			val.Seed = newDef;
			((Equippable_Viewmodel)val).AvatarEquippable = CloneAvatarEquippablePrefab(((BaseItemDefinition)newDef).ID);
			((Object)((Equippable_Viewmodel)val).AvatarEquippable).name = ((BaseItemDefinition)newDef).ID + "_AvatarEquippable";
			return val;
		}

		private AvatarEquippable CloneAvatarEquippablePrefab(string newDefId)
		{
			if ((Object)(object)baseAvatarEquippablePrefab == (Object)null)
			{
				throw new InvalidOperationException("Base avatar equippable prefab not initialized.");
			}
			AvatarEquippable val = Object.Instantiate<AvatarEquippable>(baseAvatarEquippablePrefab, rootGameObject);
			GrowLabel(((Component)val).transform, newDefId);
			((Object)((Component)val).gameObject).name = newDefId + "_AvatarEquippable";
			return val;
		}

		private StoredItem CloneStoredItem(string newDefId)
		{
			if ((Object)(object)baseStoredItem == (Object)null)
			{
				throw new InvalidOperationException("Base stored item not initialized.");
			}
			StoredItem val = Object.Instantiate<StoredItem>(baseStoredItem, rootGameObject);
			GrowLabel(((Component)val).transform, newDefId);
			((Object)((Component)val).gameObject).name = newDefId + "_StoredItem";
			return val;
		}

		public static void AddLeafToCauldrons(QualityItemDefinition customLeaf)
		{
			Cauldron[] array = Object.FindObjectsOfType<Cauldron>();
			int num = 0;
			Cauldron[] array2 = array;
			foreach (Cauldron val in array2)
			{
				ItemSlot[] ingredientSlots = val.IngredientSlots;
				foreach (ItemSlot val2 in ingredientSlots)
				{
					foreach (ItemFilter hardFilter in val2.HardFilters)
					{
						ItemFilter_ID val3 = (ItemFilter_ID)(object)((hardFilter is ItemFilter_ID) ? hardFilter : null);
						if (val3 != null && !val3.IDs.Contains(((BaseItemDefinition)customLeaf).ID))
						{
							val3.IDs.Add(((BaseItemDefinition)customLeaf).ID);
							num++;
						}
					}
				}
			}
		}
	}
	public class PseudoFactory
	{
		public static readonly Dictionary<string, string> CustomPseudoIdToLiquidMethId = new Dictionary<string, string>();

		private readonly Dictionary<string, Sprite> pseudoIconCache = new Dictionary<string, Sprite>();

		private readonly Dictionary<string, QualityItemDefinition> basePseudoDefinitions;

		private readonly LiquidMethDefinition baseLiquidMethDefinition;

		private readonly StationRecipe baseStationRecipe;

		private readonly Transform rootGameObject;

		public PseudoFactory(QualityItemDefinition basePseudo, QualityItemDefinition lowPseudo, QualityItemDefinition highPseudo, LiquidMethDefinition baseLiquidMeth, StationRecipe baseRecipe)
		{
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Expected O, but got Unknown
			basePseudoDefinitions = new Dictionary<string, QualityItemDefinition>
			{
				["pseudo"] = basePseudo,
				["lowqualitypseudo"] = lowPseudo,
				["highqualitypseudo"] = highPseudo
			};
			baseLiquidMethDefinition = baseLiquidMeth;
			baseStationRecipe = baseRecipe;
			GameObject val = new GameObject(((BaseItemDefinition)basePseudo).ID + "_CustomPseudoChains");
			val.SetActive(false);
			Object.DontDestroyOnLoad((Object)(object)val);
			rootGameObject = val.transform;
		}

		public void DeleteChildren()
		{
			TransformExt.DeleteChildren(rootGameObject, true, false);
			CustomPseudoIdToLiquidMethId.Clear();
			pseudoIconCache.Clear();
		}

		public QualityItemDefinition CreatePseudoChain(MethDefinition methDef, string pseudoBaseId)
		{
			QualityItemDefinition val = ResolvePseudoBaseDefinition(pseudoBaseId);
			if ((Object)(object)val == (Object)null)
			{
				throw new InvalidOperationException("PseudoFactory: Base pseudo definition '" + pseudoBaseId + "' not initialized.");
			}
			if ((Object)(object)baseLiquidMethDefinition == (Object)null)
			{
				throw new InvalidOperationException("PseudoFactory: Base liquid meth definition not initialized.");
			}
			if ((Object)(object)baseStationRecipe == (Object)null)
			{
				throw new InvalidOperationException("PseudoFactory: Base station recipe not initialized.");
			}
			LiquidMethDefinition val2 = ResolveOrCreateCustomLiquidMeth(methDef);
			QualityItemDefinition val3 = ResolveOrCreateCustomPseudo(val, val2, methDef);
			if ((Object)(object)val2 == (Object)null || (Object)(object)val3 == (Object)null)
			{
				return null;
			}
			Utility.Log("PseudoFactory: " + ((BaseItemDefinition)methDef).ID + " → pseudo:" + ((BaseItemDefinition)val3).ID + " → liquidmeth:" + ((BaseItemDefinition)val2).ID + " → meth:" + ((BaseItemDefinition)methDef).ID);
			return val3;
		}

		public void InjectRecipeForMix(UnicornSeedData data, string methId)
		{
			ItemDefinition item = Registry.GetItem(methId + "_customliquidmeth");
			LiquidMethDefinition val = (LiquidMethDefinition)(object)((item is LiquidMethDefinition) ? item : null);
			if (data == null || (Object)(object)val == (Object)null)
			{
				Utility.Error("PseudoFactory.InjectRecipeForMix: Cannot resolve assets for '" + methId + "' — " + $"data={data != null}, liquidmeth={(Object)(object)val != (Object)null}.");
				return;
			}
			List<QualityItemDefinition> list = new List<QualityItemDefinition>();
			foreach (VariantSeedData variant in data.variants)
			{
				QualityItemDefinition item2 = Registry.GetItem<QualityItemDefinition>(variant.seedId);
				if ((Object)(object)item2 != (Object)null)
				{
					list.Add(item2);
				}
			}
			if (list.Count == 0)
			{
				Utility.Error("PseudoFactory.InjectRecipeForMix: No pseudo variants resolved for '" + methId + "'.");
			}
			else
			{
				InjectCustomRecipeInternal(list, val, methId);
			}
		}

		private LiquidMethDefinition CloneCustomLiquidMeth(MethDefinition methDef)
		{
			LiquidMethDefinition val = Object.Instantiate<LiquidMethDefinition>(baseLiquidMethDefinition);
			((BaseItemDefinition)val).ID = ((BaseItemDefinition)methDef).ID + "_customliquidmeth";
			((Object)val).name = ((BaseItemDefinition)val).ID;
			((BaseItemDefinition)val).Name = "Liquid " + ((Object)methDef).name;
			if ((Object)(object)((StorableItemDefinition)baseLiquidMethDefinition).StationItem != (Object)null)
			{
				StationItem val2 = Object.Instantiate<StationItem>(((StorableItemDefinition)baseLiquidMethDefinition).StationItem, rootGameObject);
				((Object)val2).name = ((BaseItemDefinition)methDef).ID + "_LiquidMethStationItem";
				CookableModule module = val2.GetModule<CookableModule>();
				if ((Object)(object)module != (Object)null)
				{
					module.Product = (StorableItemDefinition)(object)methDef;
					Utility.Log("PseudoFactory: Set CookableModule.Product = '" + ((BaseItemDefinition)methDef).ID + "'.");
				}
				else
				{
					Utility.Error("PseudoFactory: No CookableModule on liquidmeth StationItem for '" + ((BaseItemDefinition)methDef).ID + "'.");
				}
				((StorableItemDefinition)val).StationItem = val2;
			}
			else
			{
				Utility.Error("PseudoFactory: baseLiquidMethDefinition.StationItem is null.");
			}
			AssignLiquidMethIcon(val, methDef);
			return val;
		}

		private void AssignLiquidMethIcon(LiquidMethDefinition clone, MethDefinition methDef)
		{
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)SeedVisualsManager.baseLiquidMethSprite == (Object)null)
			{
				return;
			}
			MethAppearanceSettings appearanceSettings = methDef.AppearanceSettings;
			if (appearanceSettings == null || appearanceSettings.IsUnintialized())
			{
				appearanceSettings = MethDefinition.GetAppearanceSettings(((PropertyItemDefinition)methDef).Properties);
			}
			if (appearanceSettings == null)
			{
				Utility.Error("PseudoFactory: No appearance settings for '" + ((BaseItemDefinition)methDef).ID + "' — keeping base liquid meth icon.");
				return;
			}
			try
			{
				(Color top, Color bottom) tuple = SeedVisualsManager.BoostContrastIfSimilar(Color32.op_Implicit(appearanceSettings.MainColor), Color32.op_Implicit(appearanceSettings.SecondaryColor));
				Color item = tuple.top;
				Color item2 = tuple.bottom;
				Sprite val = SeedVisualsManager.GenerateIconWithKeyColorFill(SeedVisualsManager.baseLiquidMethSprite, item, item2);
				if (!((Object)(object)val == (Object)null))
				{
					((Object)val).name = ((Object)clone).name + "_icon";
					SeedVisualsManager.seedIcons[((BaseItemDefinition)clone).ID] = val;
					((BaseItemDefinition)clone).Icon = val;
				}
			}
			catch (Exception e)
			{
				((BaseItemDefinition)clone).Icon = SeedVisualsManager.baseLiquidMethSprite;
				Utility.PrintException(e);
			}
		}

		private LiquidMethDefinition ResolveOrCreateCustomLiquidMeth(MethDefinition methDef)
		{
			string text = ((BaseItemDefinition)methDef).ID + "_customliquidmeth";
			ItemDefinition item = Registry.GetItem(text);
			LiquidMethDefinition val = (LiquidMethDefinition)(object)((item is LiquidMethDefinition) ? item : null);
			if ((Object)(object)val != (Object)null)
			{
				return val;
			}
			LiquidMethDefinition val2 = CloneCustomLiquidMeth(methDef);
			if ((Object)(object)val2 != (Object)null)
			{
				Singleton<Registry>.Instance.AddToRegistry((ItemDefinition)(object)val2);
			}
			return val2;
		}

		private QualityItemDefinition CloneCustomPseudo(QualityItemDefinition basePseudoDefinition, LiquidMethDefinition customLiquidMeth, MethDefinition methDef)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Expected I4, but got Unknown
			QualityItemDefinition val = Object.Instantiate<QualityItemDefinition>(basePseudoDefinition);
			((BaseItemDefinition)val).ID = ((BaseItemDefinition)methDef).ID + "_" + ((BaseItemDefinition)basePseudoDefinition).ID + "_custompseudo";
			((Object)val).name = ((BaseItemDefinition)val).ID;
			EQuality defaultQuality = basePseudoDefinition.DefaultQuality;
			EQuality val2 = defaultQuality;
			switch ((int)val2)
			{
			case 0:
				((BaseItemDefinition)val).Name = "Lo-Quality " + ((Object)methDef).name;
				break;
			case 2:
				((BaseItemDefinition)val).Name = "Mid-Quality " + ((Object)methDef).name;
				break;
			case 3:
				((BaseItemDefinition)val).Name = "Hi-Quality " + ((Object)methDef).name;
				break;
			default:
				((BaseItemDefinition)val).Name = ((Object)methDef).name;
				break;
			}
			((BaseItemDefinition)val).Description = ((BaseItemDefinition)basePseudoDefinition).Description;
			((StorableItemDefinition)val).StationItem = ((StorableItemDefinition)basePseudoDefinition).StationItem;
			AssignPseudoIcon(val, methDef);
			CustomPseudoIdToLiquidMethId[((BaseItemDefinition)val).ID] = ((BaseItemDefinition)customLiquidMeth).ID;
			return val;
		}

		private void AssignPseudoIcon(QualityItemDefinition clone, MethDefinition methDef)
		{
			if ((Object)(object)SeedVisualsManager.basePseudoSprite == (Object)null)
			{
				return;
			}
			if (!pseudoIconCache.TryGetValue(((BaseItemDefinition)methDef).ID, out var value))
			{
				value = GeneratePseudoIcon(methDef);
				if ((Object)(object)value == (Object)null)
				{
					return;
				}
				pseudoIconCache[((BaseItemDefinition)methDef).ID] = value;
			}
			SeedVisualsManager.seedIcons[((BaseItemDefinition)clone).ID] = value;
			((BaseItemDefinition)clone).Icon = value;
		}

		private Sprite GeneratePseudoIcon(MethDefinition methDef)
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			MethAppearanceSettings appearanceSettings = methDef.AppearanceSettings;
			if (appearanceSettings == null || appearanceSettings.IsUnintialized())
			{
				appearanceSettings = MethDefinition.GetAppearanceSettings(((PropertyItemDefinition)methDef).Properties);
			}
			if (appearanceSettings == null)
			{
				Utility.Error("PseudoFactory: No appearance settings for '" + ((BaseItemDefinition)methDef).ID + "' — keeping base icon.");
				return null;
			}
			try
			{
				(Color top, Color bottom) tuple = SeedVisualsManager.BoostContrastIfSimilar(Color32.op_Implicit(appearanceSettings.MainColor), Color32.op_Implicit(appearanceSettings.SecondaryColor));
				Color item = tuple.top;
				Color item2 = tuple.bottom;
				Sprite val = SeedVisualsManager.GenerateIconWithKeyColorFill(SeedVisualsManager.basePseudoSprite, item, item2);
				if ((Object)(object)val != (Object)null)
				{
					((Object)val).name = ((BaseItemDefinition)methDef).ID + "_pseudo_icon";
				}
				return val;
			}
			catch (Exception e)
			{
				Utility.PrintException(e);
				return SeedVisualsManager.basePseudoSprite;
			}
		}

		private QualityItemDefinition ResolveOrCreateCustomPseudo(QualityItemDefinition basePseudoDefinition, LiquidMethDefinition customLiquidMeth, MethDefinition methDef)
		{
			string text = CustomPseudoManager.BuildPseudoSeedId(((BaseItemDefinition)methDef).ID, ((BaseItemDefinition)basePseudoDefinition).ID);
			QualityItemDefinition item = Registry.GetItem<QualityItemDefinition>(text);
			if ((Object)(object)item != (Object)null)
			{
				CustomPseudoIdToLiquidMethId[((BaseItemDefinition)item).ID] = ((BaseItemDefinition)customLiquidMeth).ID;
				return item;
			}
			QualityItemDefinition val = CloneCustomPseudo(basePseudoDefinition, customLiquidMeth, methDef);
			if ((Object)(object)val != (Object)null)
			{
				Singleton<Registry>.Instance.AddToRegistry((ItemDefinition)(object)val);
			}
			return val;
		}

		private void InjectCustomRecipeInternal(List<QualityItemDefinition> customPseudoVariants, LiquidMethDefinition customLiquidMeth, string methId)
		{
			ChemistryStationInterface instance = Singleton<ChemistryStationInterface>.Instance;
			string text = methId + "_customrecipe";
			foreach (StationRecipe recipe in instance.Recipes)
			{
				if (((Object)recipe).name == text)
				{
					Utility.Log("PseudoFactory: Recipe '" + text + "' already in canvas — skipping.");
					return;
				}
			}
			StationRecipe val = Object.Instantiate<StationRecipe>(baseStationRecipe);
			((Object)val).name = text;
			val.RecipeTitle = ((BaseItemDefinition)customLiquidMeth).Name ?? "";
			val.Unlocked = true;
			val.IsDiscovered = true;
			QualityItemDefinition val2 = null;
			foreach (QualityItemDefinition customPseudoVariant in customPseudoVariants)
			{
				if ((Object)(object)customPseudoVariant != (Object)null && ((BaseItemDefinition)customPseudoVariant).ID == CustomPseudoManager.BuildPseudoSeedId(methId, "pseudo"))
				{
					val2 = customPseudoVariant;
					break;
				}
			}
			if ((Object)(object)val2 == (Object)null)
			{
				val2 = customPseudoVariants[0];
			}
			foreach (IngredientQuantity ingredient in val.Ingredients)
			{
				bool flag = false;
				foreach (ItemDefinition item in ingredient.Items)
				{
					if ((Object)(object)item != (Object)null && basePseudoDefinitions.ContainsKey(((BaseItemDefinition)item).ID))
					{
						flag = true;
						break;
					}
				}
				if (!flag)
				{
					continue;
				}
				ingredient.Items.Clear();
				ingredient.Items.Add((ItemDefinition)(object)val2);
				foreach (QualityItemDefinition customPseudoVariant2 in customPseudoVariants)
				{
					if ((Object)(object)customPseudoVariant2 != (Object)null && !ingredient.Items.Contains((ItemDefinition)(object)customPseudoVariant2))
					{
						ingredient.Items.Add((ItemDefinition)(object)customPseudoVariant2);
					}
				}
				break;
			}
			val.Product.Item = (ItemDefinition)(object)customLiquidMeth;
			val.Product.Quantity = 1;
			StationRecipeEntry component = ((Component)Object.Instantiate<StationRecipeEntry>(instance.RecipeEntryPrefab, (Transform)(object)instance.RecipeContainer)).GetComponent<StationRecipeEntry>();
			component.AssignRecipe(val);
			instance.Recipes.Add(val);
			instance.recipeEntries.Add(component);
			Utility.Log($"PseudoFactory: Injected recipe '{text}' (Unlocked={val.Unlocked}, IsDiscovered={val.IsDiscovered}) into ChemistryStationInterface.");
		}

		private QualityItemDefinition ResolvePseudoBaseDefinition(string pseudoBaseId)
		{
			QualityItemDefinition value;
			return basePseudoDefinitions.TryGetValue(pseudoBaseId, out value) ? value : null;
		}
	}
	public class SyringeFactory
	{
		private Transform rootGameObject;

		private SporeSyringeDefinition baseSyringeDef;

		private ShroomSpawnDefinition baseSpawnDefinition;

		private ShroomColony baseColonyPrefab;

		private ShroomDefinition baseShroomDef;

		private SpawnChunk baseChunkPrefab;

		public SyringeFactory(SporeSyringeDefinition baseSyringe)
		{
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Expected O, but got Unknown
			baseSyringeDef = baseSyringe;
			baseSpawnDefinition = baseSyringe.SpawnDefinition;
			baseColonyPrefab = baseSpawnDefinition.ColonyPrefab;
			baseShroomDef = baseSpawnDefinition.Shroom;
			baseChunkPrefab = baseSpawnDefinition.ChunkPrefab;
			GameObject val = new GameObject(((BaseItemDefinition)baseSyringeDef).ID + "_CustomSyringes");
			val.SetActive(false);
			Object.DontDestroyOnLoad((Object)(object)val);
			rootGameObject = val.transform;
		}

		public SporeSyringeDefinition CreateSyringeDefinition(ShroomDefinition shroomDef)
		{
			if ((Object)(object)baseSyringeDef == (Object)null)
			{
				throw new InvalidOperationException("Base syringe definition not initialized.");
			}
			SporeSyringeDefinition val = Object.Instantiate<SporeSyringeDefinition>(baseSyringeDef);
			((BaseItemDefinition)val).ID = ((BaseItemDefinition)shroomDef).ID + "_customsyringedefinition";
			((Object)val).name = ((BaseItemDefinition)val).ID;
			((BaseItemDefinition)val).Name = ((Object)shroomDef).name + " Spore Syringe";
			ShroomSpawnDefinition val2 = (val.SpawnDefinition = CloneSpawnDefinition(((BaseItemDefinition)shroomDef).ID, shroomDef));
			Singleton<Registry>.Instance.AddToRegistry((ItemDefinition)(object)val2);
			Utility.Log("Registered ShroomSpawnDefinition: " + ((BaseItemDefinition)val2).ID);
			AssignShroomIcons(val, val2, shroomDef);
			return val;
		}

		private void AssignShroomIcons(SporeSyringeDefinition syringe, ShroomSpawnDefinition spawnDef, ShroomDefinition shroomDef)
		{
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			ShroomAppearanceSettings appearanceSettings = shroomDef.AppearanceSettings;
			if (appearanceSettings == null || appearanceSettings.IsUnintialized())
			{
				appearanceSettings = ShroomDefinition.GetAppearanceSettings(((PropertyItemDefinition)shroomDef).Properties);
			}
			if (appearanceSettings == null)
			{
				Utility.Error("SyringeFactory: No appearance settings for '" + ((BaseItemDefinition)shroomDef).ID + "' — keeping base icons.");
				return;
			}
			var (topColor, bottomColor) = PickMostDistinctPair(appearanceSettings);
			if ((Object)(object)SeedVisualsManager.baseSyringeSprite != (Object)null)
			{
				try
				{
					Sprite val = SeedVisualsManager.GenerateIconWithKeyColorFill(SeedVisualsManager.baseSyringeSprite, topColor, bottomColor);
					if ((Object)(object)val != (Object)null)
					{
						((Object)val).name = ((Object)syringe).name + "_icon";
						SeedVisualsManager.seedIcons[((BaseItemDefinition)syringe).ID] = val;
						((BaseItemDefinition)syringe).Icon = val;
					}
				}
				catch (Exception e)
				{
					((BaseItemDefinition)syringe).Icon = SeedVisualsManager.baseSyringeSprite;
					Utility.PrintException(e);
				}
			}
			if (!((Object)(object)SeedVisualsManager.baseShroomSpawnSprite != (Object)null))
			{
				return;
			}
			try
			{
				Sprite val2 = SeedVisualsManager.GenerateIconWithKeyColorFill(SeedVisualsManager.baseShroomSpawnSprite, topColor, bottomColor);
				if ((Object)(object)val2 != (Object)null)
				{
					((Object)val2).name = ((Object)spawnDef).name + "_icon";
					SeedVisualsManager.seedIcons[((BaseItemDefinition)spawnDef).ID] = val2;
					((BaseItemDefinition)spawnDef).Icon = val2;
				}
			}
			catch (Exception e2)
			{
				((BaseItemDefinition)spawnDef).Icon = SeedVisualsManager.baseShroomSpawnSprite;
				Utility.PrintException(e2);
			}
		}

		private (Color top, Color bottom) PickMostDistinctPair(ShroomAppearanceSettings appearance)
		{
			//IL_0002: 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_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: 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)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: 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_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			Color val = Color32.op_Implicit(appearance.PrimaryColor);
			Color val2 = Color32.op_Implicit(appearance.SecondaryColor);
			if (!appearance.HasSpots)
			{
				return (top: val, bottom: val2);
			}
			Color val3 = Color32.op_Implicit(appearance.SpotsColor);
			float num = SeedVisualsManager.ColorDistanceRgb(val, val2);
			float num2 = SeedVisualsManager.ColorDistanceRgb(val, val3);
			float num3 = SeedVisualsManager.ColorDistanceRgb(val2, val3);
			float num4 = Mathf.Max(num, Mathf.Max(num2, num3));
			if (num4 == num2)
			{
				return (top: val, bottom: val3);
			}
			if (num4 == num3)
			{
				return (top: val2, bottom: val3);
			}
			return (top: val, bottom: val2);
		}

		private ShroomSpawnDefinition CloneSpawnDefinition(string shroomId, ShroomDefinition shroomDef)
		{
			ShroomSpawnDefinition val = Object.Instantiate<ShroomSpawnDefinition>(baseSpawnDefinition);
			((BaseItemDefinition)val).ID = shroomId + "_customspawndefinition";
			((Object)val).name = ((BaseItemDefinition)val).ID;
			((BaseItemDefinition)val).Name = ((Object)shroomDef).name + " Spawn";
			val.Shroom = shroomDef;
			ShroomColony val2 = Object.Instantiate<ShroomColony>(baseColonyPrefab, rootGameObject);
			((Object)((Component)val2).gameObject).name = shroomId + "_Colony";
			val2._spawnDefinition = val;
			val.ColonyPrefab = val2;
			return val;
		}

		public void DeleteChildren()
		{
			TransformExt.DeleteChildren(rootGameObject, true, false);
		}
	}
	[Serializable]
	internal class LegacySeedData
	{
		public string seedId { get; set; }

		public string weedId { get; set; }

		public string baseSeedId { get; set; }

		public float price { get; set; }
	}
	[Serializable]
	internal class LegacyUnicornSeedData
	{
		public string seedId { get; set; }

		public string mixId { get; set; }

		public EDrugType drugType { get; set; }

		public float price { get; set; }
	}
	[Serializable]
	public class VariantSeedData
	{
		public string baseItemId { get; set; }

		public string seedId { get; set; }

		public float price { get; set; }
	}
	[Serializable]
	public class UnicornSeedData
	{
		public string mixId { get; set; }

		public EDrugType drugType { get; set; }

		public List<VariantSeedData> variants { get; set; } = new List<VariantSeedData>();

		[JsonIgnore]
		public string seedId => variants.FirstOrDefault()?.seedId;

		[JsonIgnore]
		public float price => variants.FirstOrDefault()?.price ?? 0f;

		public VariantSeedData GetVariant(string baseItemId)
		{
			return variants.FirstOrDefault((VariantSeedData v) => v.baseItemId == baseItemId);
		}

		public void SetSingleVariant(string baseItemId, string itemSeedId, float variantPrice)
		{
			variants = new List<VariantSeedData>
			{
				new VariantSeedData
				{
					baseItemId = baseItemId,
					seedId = itemSeedId,
					price = variantPrice
				}
			};
		}
	}
	public class SeedFactory
	{
		private Transform rootGameObject;

		private WeedPlant basePlantPrefab;

		private PlantHarvestable baseBranchPrefab;

		private FunctionalSeed baseFunctionalSeedPrefab;

		private Equippable_Seed baseEquippableSeedPrefab;

		private AvatarEquippable baseAvatarEquippablePrefab;

		private StoredItem baseStorableItem;

		public SeedDefinition baseSeedDefinition;

		public SeedFactory(SeedDefinition seedDefinition)
		{
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Expected O, but got Unknown
			baseSeedDefinition = seedDefinition;
			baseFunctionalSeedPrefab = seedDefinition.FunctionSeedPrefab;
			baseStorableItem = ((StorableItemDefinition)seedDefinition).StoredItem;
			InitializeBasePlant(seedDefinition);
			InitializeEquippable(seedDefinition);
			if ((Object)(object)rootGameObject == (Object)null)
			{
				GameObject val = new GameObject(((BaseItemDefinition)baseSeedDefinition).ID + "_CustomSeeds");
				val.SetActive(false);
				Object.DontDestroyOnLoad((Object)(object)val);
				rootGameObject = val.transform;
			}
		}

		private void InitializeBasePlant(SeedDefinition seedDefinition)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			WeedPlant val = (WeedPlant)seedDefinition.PlantPrefab;
			if ((Object)(object)val != (Object)null)
			{
				basePlantPrefab = val;
				if ((Object)(object)basePlantPrefab != (Object)null)
				{
					baseBranchPrefab = basePlantPrefab.BranchPrefab;
				}
			}
			else
			{
				Utility.Log("Failed to cast PlantPrefab to WeedPlant.");
			}
		}

		private void InitializeEquippable(SeedDefinition seedDefinition)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			Equippable_Seed val = (Equippable_Seed)((ItemDefinition)seedDefinition).Equippable;
			if ((Object)(object)val != (Object)null)
			{
				baseEquippableSeedPrefab = val;
				baseAvatarEquippablePrefab = ((Equippable_Viewmodel)val).AvatarEquippable;
			}
			else
			{
				Utility.Log("Failed to cast Equippable to Equippable_Seed.");
			}
		}

		public void DeleteChildren()
		{
			TransformExt.DeleteChildren(rootGameObject, true, false);
		}

		private void GrowLabel(Transform root, string seedDefId)
		{
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			Transform val = null;
			Transform[] componentsInChildren = ((Component)root).GetComponentsInChildren<Transform>();
			Transform[] array = componentsInChildren;
			foreach (Transform val2 in array)
			{
				if (((Object)val2).name == "Label")
				{
					val = ((Component)val2).transform;
				}
			}
			if ((Object)(object)val != (Object)null)
			{
				val.localScale = new Vector3(1.05f, 1.05f, 2f);
				val.position = new Vector3(0f, -0.05f, 0f);
				if ((Object)(object)SeedVisualsManager.customMat == (Object)null)
				{
					SeedVisualsManager.LoadSeedMaterial();
				}
				if ((Object)(object)SeedVisualsManager.customMat != (Object)null)
				{
					Renderer component = ((Component)val).GetComponent<Renderer>();
					component.material = SeedVisualsManager.customMat;
					((Component)val).gameObject.AddComponent<SeedVialLabel>();
					((Object)val).name = ((Object)val).name + ":" + seedDefId;
				}
				else
				{
					Utility.Log("MATERIAL NOT LOADED!!!");
				}
			}
		}

		public WeedPlant ClonePlantPrefab(WeedDefinition newDef)
		{
			if ((Object)(object)basePlantPrefab == (Object)null)
			{
				throw new InvalidOperationException("Base plant prefab not initialized.");
			}
			WeedPlant val = Object.Instantiate<WeedPlant>(basePlantPrefab, rootGameObject);
			SetPlantAppearance(newDef, val);
			PlantHarvestable val2 = CloneBranchPrefab(newDef);
			SetBranchAppearance(((Component)val2).transform, newDef);
			val.BranchPrefab = val2;
			PlantHarvestable[] componentsInChildren = ((Component)val).GetComponentsInChildren<PlantHarvestable>();
			PlantHarvestable[] array = componentsInChildren;
			foreach (PlantHarvestable val3 in array)
			{
				val3.Product = (StorableItemDefinition)(object)newDef;
			}
			return val;
		}

		public void SetPlantAppearance(WeedDefinition newDef, WeedPlant plant)
		{
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			PlantGrowthStage[] growthStages = ((Plant)plant).GrowthStages;
			foreach (PlantGrowthStage val in growthStages)
			{
				WeedAppearanceSettings val2 = newDef.appearance;
				if (val2 == null)
				{
					val2 = WeedDefinition.GetAppearanceSettings(((PropertyItemDefinition)newDef).Properties);
				}
				if ((Object)(object)val != (Object)null && val2 != null)
				{
					for (int j = 0; j < ((Component)val).transform.childCount; j++)
					{
						Transform child = ((Component)val).transform.GetChild(j);
						if ((Object)(object)child == (Object)null)
						{
							continue;
						}
						MeshRenderer component = ((Component)child).GetComponent<MeshRenderer>();
						if ((Object)(object)component == (Object)null)
						{
							continue;
						}
						Material material = ((Renderer)component).material;
						if ((Object)(object)material == (Object)null)
						{
							continue;
						}
						if (((Object)child).name == "Stem")
						{
							material.color = Color32.op_Implicit(val2.StemColor);
						}
						if (((Object)child).name == "BigLeaves")
						{
							material.color = Color32.op_Implicit(val2.LeafColor);
						}
						if (((Object)child).name == "SmallLeaves")
						{
							material.color = Color32.op_Implicit(val2.LeafColor);
						}
						Transform[] growthSites = val.GrowthSites;
						foreach (Transform val3 in growthSites)
						{
							if ((Object)(object)val3 != (Object)null)
							{
								Transform child2 = val3.GetChild(0);
								if (Object.op_Implicit((Object)(object)child2))
								{
									SetBranchAppearance(child2, val2);
								}
							}
						}
					}
				}
				else
				{
					Utility.Error("Plant Stage is NULL! Thats impossible");
				}
			}
		}

		public void SetBranchAppearance(Transform branchTransform, WeedDefinition weedDef)
		{
			WeedAppearanceSettings val = weedDef.appearance;
			if (val == null)
			{
				val = WeedDefinition.GetAppearanceSettings(((PropertyItemDefinition)weedDef).Properties);
			}
			if (val != null && (Object)(object)branchTransform != (Object)null)
			{
				SetBranchAppearance(branchTransform, val);
			}
		}

		public void SetBranchAppearance(Transform branchTransform, WeedAppearanceSettings weedAppearance)
		{
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			Transform child = branchTransform.GetChild(0);
			Transform val = ((child != null) ? child.GetChild(0) : null);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			for (int i = 0; i < val.childCount; i++)
			{
				Transform child2 = val.GetChild(i);
				if ((Object)(object)child2 == (Object)null)
				{
					continue;
				}
				MeshRenderer component = ((Component)child2).GetComponent<MeshRenderer>();
				if ((Object)(object)component == (Object)null)
				{
					continue;
				}
				Material material = ((Renderer)component).material;
				if (!((Object)(object)material == (Object)null))
				{
					if (((Object)child2).name == "Stem")
					{
						material.color = Color32.op_Implicit(weedAppearance.StemColor);
					}
					if (((Object)child2).name == "Leaves")
					{
						material.color = Color32.op_Implicit(weedAppearance.LeafColor);
					}
					if (((Object)child2).name == "Main")
					{
						material.color = Color32.op_Implicit(weedAppearance.MainColor);
					}
					if (((Object)child2).name == "Secondary")
					{
						material.color = Color32.op_Implicit(weedAppearance.SecondaryColor);
					}
				}
			}
		}

		public PlantHarvestable CloneBranchPrefab(WeedDefinition newDef)
		{
			if ((Object)(object)baseBranchPrefab == (Object)null)
			{
				throw new InvalidOperationException("Base branch prefab not initialized.");
			}
			PlantHarvestable val = Object.Instantiate<PlantHarvestable>(baseBranchPrefab, rootGameObject);
			((Object)((Component)val).gameObject).name = ((BaseItemDefinition)newDef).ID + "_Harvestable";
			((Component)val).gameObject.layer = ((Component)baseBranchPrefab).gameObject.layer;
			val.Product = (StorableItemDefinition)(object)newDef;
			return val;
		}

		public FunctionalSeed CloneFunctionalSeedPrefab(string seedDefId)
		{
			if ((Object)(object)baseFunctionalSeedPrefab == (Object)null)
			{
				throw new InvalidOperationException("Base functional seed prefab not initialized.");
			}
			FunctionalSeed val = Object.Instantiate<FunctionalSeed>(baseFunctionalSeedPrefab, rootGameObject);
			GrowLabel(((Component)val).transform, seedDefId);
			return val;
		}

		public Equippable_Seed CloneEquippableSeedPrefab(SeedDefinition newDef, WeedAppearanceSettings weedAppearance)
		{
			if ((Object)(object)baseEquippableSeedPrefab == (Object)null)
			{
				throw new InvalidOperationException("Base equippable seed prefab not initialized.");
			}
			Equippable_Seed val = Object.Instantiate<Equippable_Seed>(baseEquippableSeedPrefab, rootGameObject);
			GrowLabel(((Component)val).transform, ((BaseItemDefinition)newDef).ID);
			((Object)((Component)val).gameObject).name = ((BaseItemDefinition)newDef).ID + "_Equippable";
			((Component)val).gameObject.layer = ((Component)baseEquippableSeedPrefab).gameObject.layer;
			val.Seed = newDef;
			((Equippable_Viewmodel)val).AvatarEquippable = CloneAvatarEquippablePrefab(((BaseItemDefinition)newDef).ID);
			((Object)((Equippable_Viewmodel)val).AvatarEquippable).name = ((BaseItemDefinition)newDef).ID + "_AvatarEquippable";
			return val;
		}

		public AvatarEquippable CloneAvatarEquippablePrefab(string newDefId)
		{
			if ((Object)(object)baseAvatarEquippablePrefab == (Object)null)
			{
				throw new InvalidOperationException("Base avatar equippable prefab not initialized.");
			}
			AvatarEquippable val = Object.Instantiate<AvatarEquippable>(baseAvatarEquippablePrefab, rootGameObject);
			GrowLabel(((Component)val).transform, newDefId);
			return val;
		}

		public StoredItem CloneStoredItem(string newDefId)
		{
			if ((Object)(object)baseStorableItem == (Object)null)
			{
				throw new InvalidOperationException("Base Stored Item not initialized.");
			}
			StoredItem val = Object.Instantiate<StoredItem>(baseStorableItem, rootGameObject);
			GrowLabel(((Component)val).transform, newDefId);
			return val;
		}

		public SeedDefinition CreateSeedDefinition(WeedDefinition weedDef)
		{
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)baseSeedDefinition == (Object)null)
			{
				throw new InvalidOperationException("Base seed definition not initialized.");
			}
			SeedDefinition val = Object.Instantiate<SeedDefinition>(baseSeedDefinition);
			WeedAppearanceSettings val2 = weedDef.appearance;
			if (val2 == null)
			{
				val2 = WeedDefinition.GetAppearanceSettings(((PropertyItemDefinition)weedDef).Properties);
			}
			((Object)val).name = ((BaseItemDefinition)weedDef).ID + "_customseeddefinition";
			((BaseItemDefinition)val).ID = ((BaseItemDefinition)weedDef).ID + "_customseeddefinition";
			((BaseItemDefinition)val).Name = ((Object)weedDef).name + " Seed";
			((BaseItemDefinition)val).Description = ((Object)weedDef).name + " Seed";
			((BaseItemDefinition)val).Icon = ((BaseItemDefinition)baseSeedDefinition).Icon;
			SeedVisualsManager.weedAppearanceMap[((BaseItemDefinition)val).ID] = val2;
			((ItemDefinition)val).Equippable = (Equippable)(object)CloneEquippableSeedPrefab(val, val2);
			val.PlantPrefab = (Plant)(object)ClonePlantPrefab(weedDef);
			val.PlantPrefab.SeedDefinition = val;
			val.FunctionSeedPrefab = CloneFunctionalSeedPrefab(((BaseItemDefinition)val).ID);
			((Object)val.FunctionSeedPrefab).name = ((BaseItemDefinition)weedDef).ID + "Seed_Functional";
			((StorableItemDefinition)val).StoredItem = CloneStoredItem(((BaseItemDefinition)val).ID);
			if ((Object)(object)SeedVisualsManager.baseSeedSprite != (Object)null)
			{
				try
				{
					Sprite val3 = SeedVisualsManager.GenerateIconWithKeyColorFill(SeedVisualsManager.baseSeedSprite, Color32.op_Implicit(val2.MainColor), Color32.op_Implicit(val2.SecondaryColor));
					((Object)val3).name = ((Object)val).name + "_icon";
					SeedVisualsManager.seedIcons.Add(((BaseItemDefinition)val).ID, val3);
					((BaseItemDefinition)val).Icon = val3;
				}
				catch (Exception e)
				{
					((BaseItemDefinition)val).Icon = SeedVisualsManager.baseSeedSprite;
					Utility.PrintException(e);
				}
			}
			return val;
		}
	}
	[RegisterTypeInIl2Cpp]
	public class SeedVialLabel : MonoBehaviour
	{
		private Renderer rend;

		private MaterialPropertyBlock block;

		public Color colorA;

		public Color colorB;

		public bool useRandomColors = false;

		private void Start()
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			if (useRandomColors)
			{
				colorA = Random.ColorHSV();
				colorB = Random.ColorHSV();
			}
			rend = ((Component)this).GetComponent<Renderer>();
			block = new MaterialPropertyBlock();
			SetupLabel();
		}

		public void SetupLabel()
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)rend == (Object)null)
			{
				return;
			}
			MeshFilter component = ((Component)this).GetComponent<MeshFilter>();
			if (!((Object)(object)component == (Object)null))
			{
				string text = ((Object)this).name.Split(':')[1];
				if (SeedVisualsManager.TryGetLabelColors(text, out var main, out var secondary))
				{
					colorA = main;
					colorB = secondary;
				}
				else if (!useRandomColors)
				{
					Utility.Error("SeedVialLabel: no appearance registered for '" + text + "' — leaving the label uncoloured.");
					return;
				}
				Bounds bounds = component.sharedMesh.bounds;
				rend.GetPropertyBlock(block);
				block.SetColor("_ColorA", colorA);
				block.SetColor("_ColorB", colorB);
				block.SetFloat("_MinZ", ((Bounds)(ref bounds)).min.z);
				block.SetFloat("_MaxZ", ((Bounds)(ref bounds)).max.z);
				rend.SetPropertyBlock(block);
			}
		}
	}
}
namespace UnicornsCustomSeeds.SeedQuests
{
	public abstract class CustomSynthesisQuest : Quest
	{
		[SaveableField("SynthesisQuestData")]
		private CustomSynthesisQuestData _data = new CustomSynthesisQuestData();

		public QuestEntry dropoffEntry;

		protected abstract string NpcName { get; }

		protected abstract string ItemName { get; }

		protected abstract SupplierStash Stash { get; }

		protected override string Description => $"Take {StashManager.StashQtyEntry.Value}x of your {ItemName} and ${StashManager.StashCostEntry.Value} to {NpcName}'s supply stash";

		public void SetDrugType(EDrugType drugType)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			_data.drugType = drugType;
		}

		protected override void OnCreated()
		{
			if (base.QuestEntries.Count == 0)
			{
				AddDropoffEntry();
			}
		}

		protected override void OnLoaded()
		{
			if (base.QuestEntries.Count == 0)
			{
				AddDropoffEntry();
			}
		}

		private void AddDropoffEntry()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			SupplierStash stash = Stash;
			Vector3 value = (((Object)(object)stash != (Object)null) ? ((Component)stash).transform.position : Vector3.zero);
			dropoffEntry = ((Quest)this).AddEntry($"Give {NpcName} {StashManager.StashQtyEntry.Value}x of a {ItemName} and ${StashManager.StashCostEntry.Value}", (Vector3?)value);
			Utility.Log("[" + ((object)this).GetType().Name + "] dropoff entry added (npc=" + NpcName + ", stash=" + (((Object)(object)stash != (Object)null) ? "found" : "null") + ").");
		}
	}
	[Serializable]
	public class CustomSynthesisQuestData
	{
		public EDrugType drugType { get; set; } = (EDrugType)0;
	}
	public class WeedSynthesisQuest : CustomSynthesisQuest
	{
		protected override string Title => "Drop off the Mix";

		protected override string NpcName => "Albert";

		protected override string ItemName => "weed mix";

		protected override SupplierStash Stash => StashManager.GetSupplierStash();

		protected override Sprite QuestIcon => SeedVisualsManager.weedQuestIconSprite ?? SeedVisualsManager.baseQuestIconSprite;
	}
	public class ShroomSynthesisQuest : CustomSynthesisQuest
	{
		protected override string Title => "Drop off the Shroom Mix";

		protected override string NpcName => "Phil";

		protected override string ItemName => "shroom mix";

		protected override SupplierStash Stash => PhilStashManager.GetSupplierStash();

		protected override Sprite QuestIcon => SeedVisualsManager.shroomQuestIconSprite ?? SeedVisualsManager.baseQuestIconSprite;
	}
	public class CocaSynthesisQuest : CustomSynthesisQuest
	{
		protected override string Title => "Drop off the Cocaine Mix";

		protected override string NpcName => "Salvador";

		protected override string ItemName => "cocaine mix";

		protected override SupplierStash Stash => SalvadorStashManager.GetSupplierStash();

		protected override Sprite QuestIcon => SeedVisualsManager.cocaineQuestIconSprite ?? SeedVisualsManager.baseQuestIconSprite;
	}
	public class PseudoSynthesisQuest : CustomSynthesisQuest
	{
		protected override string Title => "Drop off the Meth Mix";

		protected override string NpcName => "Shirley";

		protected override string ItemName => "meth mix";

		protected override SupplierStash Stash => ShirleyStashManager.GetSupplierStash();

		protected override Sprite QuestIcon => SeedVisualsManager.methQuestIconSprite ?? SeedVisualsManager.baseQuestIconSprite;
	}
}
namespace UnicornsCustomSeeds.Patches
{
	public static class CauldronBaseSwap
	{
		public static readonly Dictionary<Cauldron, QualityItemDefinition> OriginalBase = new Dictionary<Cauldron, QualityItemDefinition>();
	}
	[HarmonyPatch(typeof(Cauldron), "Start")]
	public class CauldronStartPatch
	{
		[HarmonyPostfix]
		public static void Postfix(Cauldron __instance)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			if (((BuildableItem)__instance).isGhost)
			{
				return;
			}
			try
			{
				Cauldron cauldron = __instance;
				cauldron.onCookEnd.AddListener((UnityAction)delegate
				{
					try
					{
						if (CauldronBaseSwap.OriginalBase.TryGetValue(cauldron, out var value))
						{
							cauldron.CocaineBaseDefinition = value;
							CauldronBaseSwap.OriginalBase.Remove(cauldron);
						}
						string text2 = ((BuildableItem)cauldron).GUID.ToString();
						if (ActiveCookingRegistry.GuidToMixId.ContainsKey(text2))
						{
							ActiveCookingRegistry.Unregister(text2);
						}
					}
					catch (Exception e2)
					{
						Utility.PrintException(e2);
					}
				});
				string stationGuid = ((BuildableItem)__instance).GUID.ToString();
				string mixId = ActiveCookingRegistry.GetMixId(stationGuid);
				if (mixId == null)
				{
					return;
				}
				string text = mixId + "_customcocainebase";
				ItemDefinition item = Registry.GetItem(text);
				QualityItemDefinition val = (QualityItemDefinition)(object)((item is QualityItemDefinition) ? item : null);
				if ((Object)(object)val == (Object)null)
				{
					Utility.Error("CauldronStartPatch: Could not resolve '" + text + "' — cauldron will finish with vanilla base.");
					return;
				}
				if (!CauldronBaseSwap.OriginalBase.ContainsKey(__instance))
				{
					CauldronBaseSwap.OriginalBase[__instance] = __instance.CocaineBaseDefinition;
				}
				__instance.CocaineBaseDefinition = val;
			}
			catch (Exception e)
			{
				Utility.PrintException(e);
			}
		}
	}
	[HarmonyPatch(typeof(Cauldron), "RemoveIngredients")]
	public static class Patch_Cauldron_RemoveIngredients
	{
		private static bool Prefix(Cauldron __instance, ref EQuality __result)
		{
			//IL_02cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a4: Expected I4, but got Unknown
			//IL_0345: Unknown result type (might be due to invalid IL or missing references)
			//IL_034a: 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_035e: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				List<string> list = new List<string>();
				Dictionary<string, int> dictionary = new Dictionary<string, int>();
				for (int i = 0; i < __instance.IngredientSlots.Length; i++)
				{
					ItemSlot val = __instance.IngredientSlots[i];
					if (((val != null) ? val.ItemInstance : null) != null && val.Quantity > 0)
					{
						string iD = ((BaseItemInstance)val.ItemInstance).ID;
						if (!dictionary.ContainsKey(iD))
						{
							list.Add(iD);
							dictionary[iD] = 0;
						}
						dictionary[iD] += val.Quantity;
					}
				}
				if (list.Count == 0)
				{
					Utility.Error("CauldronPatches: RemoveIngredients called with empty slots.");
					return true;
				}
				string text;
				if (list.Count == 1)
				{
					text = list[0];
				}
				else
				{
					int num = 0;
					foreach (KeyValuePair<string, int> item2 in dictionary)
					{
						if (item2.Value > num)
						{
							num = item2.Value;
						}
					}
					text = null;
					foreach (string item3 in list)
					{
						if (dictionary[item3] == num)
						{
							text = item3;
							break;
						}
					}
				}
				QualityItemDefinition value3;
				if (CocaFactory.CustomLeafIdToBaseId.TryGetValue(text, out var value))
				{
					ItemDefinition item = Registry.GetItem(value);
					QualityItemDefinition val2 = (QualityItemDefinition)(object)((item is QualityItemDefinition) ? item : null);
					if ((Object)(object)val2 != (Object)null)
					{
						if (!CauldronBaseSwap.OriginalBase.ContainsKey(__instance))
						{
							CauldronBaseSwap.OriginalBase[__instance] = __instance.CocaineBaseDefinition;
						}
						__instance.CocaineBaseDefinition = val2;
						if (CocaFactory.CustomBaseIdToMixId.TryGetValue(value, out var value2))
						{
							ActiveCookingRegistry.Register(((BuildableItem)__instance).GUID.ToString(), value2);
							if (!InstanceFinder.IsServer)
							{
								NetworkSyncManager.BroadcastCauldronCook(((BuildableItem)__instance).GUID.ToString(), value2);
							}
						}
					}
					else
					{
						Utility.Error("CauldronPatches: Could not resolve '" + value + "' as QualityItemDefinition — vanilla base will be used.");
					}
				}
				else if (CauldronBaseSwap.OriginalBase.TryGetValue(__instance, out value3))
				{
					__instance.CocaineBaseDefinition = value3;
					CauldronBaseSwap.OriginalBase.Remove(__instance);
					ActiveCookingRegistry.Unregister(((BuildableItem)__instance).GUID.ToString());
				}
				__instance.LiquidSlot.ChangeQuantity(-1, false);
				EQuality val3 = (EQuality)4;
				int num2 = 20;
				int num3 = __instance.IngredientSlots.Length - 1;
				while (num3 >= 0 && num2 > 0)
				{
					ItemSlot val4 = __instance.IngredientSlots[num3];
					if (((val4 != null) ? val4.ItemInstance : null) != null && val4.Quantity > 0 && !(((BaseItemInstance)val4.ItemInstance).ID != text))
					{
						ItemInstance itemInstance = val4.ItemInstance;
						QualityItemInstance val5 = (QualityItemInstance)(object)((itemInstance is QualityItemInstance) ? itemInstance : null);
						if (val5 != null && val5.Quality < val3)
						{
							val3 = val5.Quality;
						}
						int num4 = Mathf.Min(num2, val4.Quantity);
						val4.ChangeQuantity(-num4, false);
						num2 -= num4;
					}
					num3--;
				}
				__result = (EQuality)(int)val3;
				return false;
			}
			catch (Exception e)
			{
				Utility.PrintException(e);
				return true;
			}
		}
	}
	[HarmonyPatch(typeof(Cauldron), "RpcLogic___FinishCookOperation_2166136261")]
	public static class Patch_Cauldron_FinishCookOperation
	{
		public static void Postfix(Cauldron __instance)
		{
			Utility.Log("CauldronPatches: RpcLogic___FinishCookOperation fired on '" + ((Object)__instance).name + "' — cleanup handled by onCookEnd listener.");
		}
	}
	[HarmonyPatch(typeof(ItemSerializers), "ReadItemInstance")]
	public static class ItemStreamGuard
	{
		private static int rescued;

		private const string CustomSeedsManagerBaseSeedId = "ogkushseed";

		public static int RescuedCount => rescued;

		public static string LastSkippedId { get; private set; }

		public static ItemInstance LastSkippedStandIn { get; private set; }

		public static int LastSkippedQuantity { get; private set; }

		public static void ClearLastSkipped()
		{
			LastSkippedId = null;
			LastSkippedStandIn = null;
			LastSkippedQuantity = 0;
		}

		public static bool Prefix(Reader reader, ref ItemInstance __result)
		{
			int position = reader.Position;
			string text;
			try
			{
				text = reader.ReadString();
			}
			catch (Exception)
			{
				reader.Position = position;
				return true;
			}
			if (string.IsNullOrEmpty(text) || Registry.ItemExists(text))
			{
				reader.Position = position;
				return true;
			}
			try
			{
				ClearLastSkipped();
				LastSkippedStandIn = DrainRemainder(reader, text);
				LastSkippedId = text;
				if (LastSkippedStandIn != null)
				{
					LastSkippedQuantity = ((BaseItemInstance)LastSkippedStandIn).Quantity;
				}
				rescued++;
				Utility.Error("[ITEMGUARD] '" + text + "' is not registered on this client — slot left empty, " + $"stream kept aligned ({rescued} rescued).");
			}
			catch (Exception e)
			{
				Utility.Critical("Unicorns Custom Seeds: could not safely skip the unknown item '" + text + "'. If a player is stuck on the loading screen, this is why.");
				Utility.Error("[ITEMGUARD] drain failed for '" + text + "' — stream may be misaligned.");
				Utility.PrintException(e);
			}
			__result = null;
			return false;
		}

		private static ItemInstance DrainRemainder(Reader reader, string id)
		{
			string text = ResolveBaseId(id);
			if (!string.IsNullOrEmpty(text))
			{
				ItemDefinition item = Registry.GetItem(text);
				if ((Object)(object)item != (Object)null)
				{
					ItemInstance defaultInstance = item.GetDefaultInstance(1);
					if (defaultInstance != null)
					{
						defaultInstance.Read(reader);
						return defaultInstance;
					}
				}
				Utility.Error("[ITEMGUARD] stand-in '" + text + "' for '" + id + "' unavailable — falling back to a plain quantity read.");
			}
			LastSkippedQuantity = reader.ReadUInt16();
			return null;
		}

		private static string ResolveBaseId(string id)
		{
			if (id.EndsWith("_customseeddefinition"))
			{
				return "ogkushseed";
			}
			if (id.EndsWith("_customcocaseed"))
			{
				return "cocaseed";
			}
			if (id.EndsWith("_customcocaleaf"))
			{
				return "cocaleaf";
			}
			if (id.EndsWith("_customcocainebase"))
			{
				return "cocainebase";
			}
			if (id.EndsWith("_customliquidmeth"))
			{
				return "liquidmeth";
			}
			if (id.EndsWith("_customsyringedefinition"))
			{
				return "sporesyringe";
			}
			if (id.EndsWith("_customspawndefinition"))
			{
				return ResolveSpawnBaseId();
			}
			if (id.EndsWith("_custompseudo"))
			{
				string text = id.Substring(0, id.Length - "_custompseudo".Length);
				int num = text.LastIndexOf('_');
				if (num >= 0 && num < text.Length - 1)
				{
					return text.Substring(num + 1);
				}
			}
			return null;
		}

		private static string ResolveSpawnBaseId()
		{
			try
			{
				SporeSyringeDefinition item = Registry.GetItem<SporeSyringeDefinition>("sporesyringe");
				if ((Object)(object)item != (Object)null && (Object)(object)item.SpawnDefinition != (Object)null)
				{
					return ((BaseItemDefinition)item.SpawnDefinition).ID;
				}
			}
			catch (Exception)
			{
			}
			return null;
		}
	}
	internal static class SlotReaderGuard
	{
		private static int pendingSlotIndex = -1;

		public static void Before(PooledReader reader)
		{
			pendingSlotIndex = -1;
			ItemStreamGuard.ClearLastSkipped();
			if (!InstanceFinder.IsClient || InstanceFinder.IsServer || reader == null)
			{
				return;
			}
			int position = ((Reader)reader).Position;
			try
			{
				pendingSlotIndex = ((Reader)reader).ReadInt32((AutoPackType)1);
			}
			catch (Exception)
			{
				pendingSlotIndex = -1;
			}
			finally
			{
				((Reader)reader).Position = position;
			}
		}

		public static void After(string containerName, List<ItemSlot> slots)
		{
			try
			{
				if (pendingSlotIndex >= 0)
				{
					string lastSkippedId = ItemStreamGuard.LastSkippedId;
					if (!string.IsNullOrEmpty(lastSkippedId))
					{
						DeferredSlotsManager.Park(containerName, slots, pendingSlotIndex, lastSkippedId, ItemStreamGuard.LastSkippedQuantity, ItemStreamGuard.LastSkippedStandIn);
					}
				}
			}
			catch (Exception e)
			{
				Utility.PrintException(e);
			}
			finally
			{
				pendingSlotIndex = -1;
				ItemStreamGuard.ClearLastSkipped();
			}
		}
	}
	[HarmonyPatch(typeof(ChemistryStation), "RpcReader___Target_SetStoredInstance_Internal_2652194801")]
	public static class Patch_ChemistryStation_TargetSlotReader
	{
		public static void Prefix(PooledReader PooledReader0)
		{
			SlotReaderGuard.Before(PooledReader0);
		}

		public static void Postfix(ChemistryStation __instance)
		{
			SlotReaderGuard.After(((Object)__instance).name, __instance.ItemSlots);
		}
	}
	[HarmonyPatch(typeof(LabOven), "RpcReader___Target_SetStoredInstance_Internal_2652194801")]
	public static class Patch_LabOven_TargetSlotReader
	{
		public static void Prefix(PooledReader PooledReader0)
		{
			SlotReaderGuard.Before(PooledReader0);
		}

		public static void Postfix(LabOven __instance)
		{
			SlotReaderGuard.After(((Object)__instance).name, __instance.ItemSlots);
		}
	}
	[HarmonyPatch(typeof(MixingStation), "RpcReader___Target_SetStoredInstance_Internal_2652194801")]
	public static class Patch_MixingStation_TargetSlotReader
	{
		public static void Prefix(PooledReader PooledReader0)
		{
			SlotReaderGuard.Before(PooledReader0);
		}

		public static void Postfix(MixingStation __instance)
		{
			SlotReaderGuard.After(((Object)__instance).name, __instance.ItemSlots);
		}
	}
	[HarmonyPatch(typeof(StorageEntity), "RpcReader___Target_SetStoredInstance_Internal_2652194801")]
	public static class Patch_StorageEntity_TargetSlotReader
	{
		public static void Prefix(PooledReader PooledReader0)
		{
			SlotReaderGuard.Before(PooledReader0);
		}

		public static void Postfix(StorageEntity __instance)
		{
			SlotReaderGuard.After(((Object)__instance).name, __instance.ItemSlots);
		}
	}
	[HarmonyPatch(typeof(Cauldron), "RpcReader___Target_SetStoredInstance_Internal_2652194801")]
	public static class Patch_Cauldron_TargetSlotReader
	{
		public static void Prefix(PooledReader PooledReader0)
		{
			SlotReaderGuard.Before(PooledReader0);
		}

		public static void Postfix(Cauldron __instance)
		{
			SlotReaderGuard.After(((Object)__instance).name, __instance.ItemSlots);
		}
	}
	[HarmonyPatch(typeof(NPCInventory), "RpcReader___Target_SetStoredInstance_Internal_2652194801")]
	public static class Patch_NPCInventory_TargetSlotReader
	{
		public static void Prefix(PooledReader PooledReader0)
		{
			SlotReaderGuard.Before(PooledReader0);
		}

		public static void Postfix(NPCInventory __instance)
		{
			SlotReaderGuard.After(((Object)__instance).name, __instance.ItemSlots);
		}
	}
	[HarmonyPatch(typeof(DryingRack), "RpcReader___Target_SetStoredInstance_Internal_2652194801")]
	public static class Patch_DryingRack_TargetSlotReader
	{
		public static void Prefix(PooledReader PooledReader0)
		{
			SlotReaderGuard.Before(PooledReader0);
		}

		public static void Postfix(DryingRack __instance)
		{
			SlotReaderGuard.After(((Object)__instance).name, __instance.ItemSlots);
		}
	}
	[HarmonyPatch(typeof(MushroomSpawnStation), "RpcReader___Target_SetStoredInstance_Internal_2652194801")]
	public static class Patch_MushroomSpawnStation_TargetSlotReader
	{
		public static void Prefix(PooledReader PooledReader0)
		{
			SlotReaderGuard.Before(PooledReader0);
		}

		public static void Postfix(MushroomSpawnStation __instance)
		{
			SlotReaderGuard.After(((Object)__instance).name, __instance.ItemSlots);
		}
	}
	[HarmonyPatch(typeof(ChemistryStation), "RpcLogic___SetCookOperation_1024887225")]
	public static class Patch_ChemistryStation_SetCookOperation
	{
		public static bool Prefix(ChemistryStation __instance, NetworkConnection conn, ChemistryCookOperation operation)
		{
			try
			{
				if (DeferredCookOpsManager.IsReplaying)
				{
					return true;
				}
				if (!InstanceFinder.IsClient || InstanceFinder.IsServer)
				{
					return true;
				}
				if (operation == null)
				{
					return true;
				}
				if (DeferredCookOpsManager.IsChemistryOpReady(operation))
				{
					return true;
				}
				DeferredCookOpsManager.ParkChemistry(__instance, operation);
				return false;
			}
			catch (Exception e)
			{
				Utility.PrintException(e);
				return false;
			}
		}

		public static Exception Finalizer(Exception __exception, ChemistryStation __instance, ChemistryCookOperation operation)
		{
			if (__exception == null)
			{
				return null;
			}
			bool flag = !InstanceFinder.IsClient || InstanceFinder.IsServer;
			DeferredCookOpsManager.HandleChemistryFailure(__instance, operation, __exception, !flag);
			return null;
		}
	}
	[HarmonyPatch(typeof(LabOven), "RpcLogic___SetCookOperation_2611294368")]
	public static class Patch_LabOven_SetCookOperation
	{
		public static bool Prefix(LabOven __instance, NetworkConnection conn, OvenCookOperation operation, bool playButtonPress)
		{
			try
			{
				if (DeferredCookOpsManager.IsReplaying)
				{
					return true;
				}
				if (!InstanceFinder.IsClient || InstanceFinder.IsServer)
				{
					return true;
				}
				if (operation == null)
				{
					return true;
				}
				if (DeferredCookOpsManager.IsOvenOpReady(operation))
				{
					return true;
				}
				DeferredCookOpsManager.ParkOven(__instance, operation, playButtonPress);
				return false;
			}
			catch (Exception e)
			{
				Utility.PrintException(e);
				return false;
			}
		}

		public static Exception Finalizer(Exception __exception, LabOven __instance, OvenCookOperation operation, bool playButtonPress)
		{
			if (__exception == null)
			{
				return null;
			}
			bool flag = !InstanceFinder.IsClient || InstanceFinder.IsServer;
			DeferredCookOpsManager.HandleOvenFailure(__instance, operation, playButtonPress, __exception, !flag);
			return null;
		}
	}
	[HarmonyPatch(typeof(Cauldron), "OnSpawnServer")]
	public static class Patch_Cauldron_OnSpawnServer
	{
		public static void Postfix(Cauldron __instance, NetworkConnection connection)
		{
			try
			{
				if (connection == (NetworkConnection)null || !InstanceFinder.IsServer || connection.IsHost || __instance.ItemSlots == null)
				{
					return;
				}
				int num = 0;
				for (int i = 0; i < __instance.ItemSlots.Count; i++)
				{
					ItemSlot val = __instance.ItemSlots[i];
					if (val != null)
					{
						if (val.ItemInstance != null)
						{
							__instance.SetStoredInstance(connection, i, val.ItemInstance);
							num++;
						}
						if (val.IsLocked && val.ActiveLock != null)
						{
							__instance.SetSlotLocked(connection, i, true, val.ActiveLock.LockOwner, val.ActiveLock.LockReason);
						}
					}
				}
				if (num > 0)
				{
					Utility.Log($"[CAULDRONSYNC] sent {num} slot(s) of '{((Object)__instance).name}' " + $"to client {connection.ClientId}.");
				}
			}
			catch (Exception e)
			{
				Utility.Error("[CAULDRONSYNC] slot send failed for '" + ((Object)__instance).name + "'.");
				Utility.PrintException(e);
			}
		}
	}
	[HarmonyPatch(typeof(QuestManager), "OnSpawnServer")]
	public static class QuestManager_OnSpawnServer_Patch
	{
		public static void Postfix(NetworkConnection connection)
		{
			if (InstanceFinder.IsServer)
			{
				if (QuestManager.GetQuestByName("Drop off the Mix") is CustomSynthesisQuest)
				{
					NetworkSyncManager.BroadcastQuestConfig((EDrugType)0);
				}
				if (QuestManager.GetQuestByName("Drop off the Shroom Mix") is CustomSynthesisQuest)
				{
					NetworkSyncManager.BroadcastQuestConfig((EDrugType)4);
				}
				if (QuestManager.GetQuestByName("Drop off the Cocaine Mix") is CustomSynthesisQuest)
				{
					NetworkSyncManager.BroadcastQuestConfig((EDrugType)2);
				}
				if (QuestManager.GetQuestByName("Drop off the Meth Mix") is CustomSynthesisQuest)
				{
					NetworkSyncManager.BroadcastQuestConfig((EDrugType)1);
				}
			}
		}
	}
	[HarmonyPatch(typeof(ProductManager), "OnSpawnServer")]
	public static class ProductManager_OnSpawnServer_NetTest
	{
		public static void Postfix(ProductManager __instance, NetworkConnection connection)
		{
			if (!(connection == (NetworkConnection)null) && InstanceFinder.IsServer && !connection.IsHost)
			{
				NetworkSyncManager.BroadcastAllDiscovered();
			}
		}
	}
	[HarmonyPatch(typeof(ProductManager), "RpcLogic___CreateCocaine_1327282946")]
	public static class Patch_ProductManager_RpcLogic_CreateCocaine_Sync
	{
		public static bool Prefix(string name, string id)
		{
			if (!NetworkSyncManager.TryParsePayload(name, id, "cocaseed", out var data))
			{
				return true;
			}
			NetworkSyncManager.RebuildFromNetwork(data);
			return false;
		}
	}
	[HarmonyPatch(typeof(ProductManager), "RpcLogic___CreateShroom_Client_812995776")]
	public static class Patch_ProductManager_RpcLogic_CreateShroom_Sync
	{
		public static bool Prefix(string name, string id)
		{
			if (!NetworkSyncManager.TryParsePayload(name, id, "sporesyringe", out var data))
			{
				return true;
			}
			NetworkSyncManager.RebuildFromNetwork(data);
			return false;
		}
	}
	[HarmonyPatch(typeof(ProductManager), "RpcLogic___CreateMeth_1869045686")]
	public static class Patch_ProductManager_RpcLogic_CreateMeth_Sync
	{
		public static bool Prefix(string name, string id)
		{
			if (!NetworkSyncManager.TryParsePayload(name, id, "liquidmeth", out var data))
			{
				return true;
			}
			NetworkSyncManager.RebuildFromNetwork(data);
			return false;
		}
	}
	[HarmonyPatch(typeof(ProductManager), "RpcLogic___CreateWeed_1777266891")]
	public static class ProductManager_RpcLogic_CreateWeed_NetTest
	{
		public static void Postfix(ProductManager __instance, NetworkConnection conn, string name, string id, EDrugType type, List<string> properties, WeedAppearanceSettings appearance)
		{
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Expected I4, but got Unknown
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			if (id != "ogkushseed")
			{
				DeferredSeedRebuildManager.TryRebuild(id);
			}
			else
			{
				if (name == null)
				{
					return;
				}
				if (name.StartsWith("[NET-COOK]"))
				{
					if (InstanceFinder.IsServer)
					{
						NetworkSyncManager.HandleCauldronCook(name);
					}
				}
				else if (name.StartsWith("[NET-QUEST]") && InstanceFinder.IsClientOnly)
				{
					string text = name.Replace("[NET-QUEST]", "");
					EDrugType val = (EDrugType)0;
					try
					{
						string[] array = text.Split(',');
						if (array.Length == 4)
						{
							if (int.TryParse(array[0], out var result))
							{
								val = (EDrugType)result;
							}
							if (int.TryParse(array[1], o

UnicornsCustomSeeds_IL2Cpp_2.0.0.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using HarmonyLib;
using Il2Cpp;
using Il2CppFishNet;
using Il2CppFishNet.Connection;
using Il2CppFishNet.Managing.Server;
using Il2CppFishNet.Serializing;
using Il2CppFluffyUnderware.DevTools.Extensions;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppScheduleOne;
using Il2CppScheduleOne.AvatarFramework.Equipping;
using Il2CppScheduleOne.Core.Items.Framework;
using Il2CppScheduleOne.DevUtilities;
using Il2CppScheduleOne.Dialogue;
using Il2CppScheduleOne.Economy;
using Il2CppScheduleOne.EntityFramework;
using Il2CppScheduleOne.Equipping;
using Il2CppScheduleOne.Growing;
using Il2CppScheduleOne.ItemFramework;
using Il2CppScheduleOne.Management;
using Il2CppScheduleOne.Messaging;
using Il2CppScheduleOne.Money;
using Il2CppScheduleOne.NPCs;
using Il2CppScheduleOne.NPCs.CharacterClasses;
using Il2CppScheduleOne.NPCs.Relation;
using Il2CppScheduleOne.ObjectScripts;
using Il2CppScheduleOne.Persistence;
using Il2CppScheduleOne.PlayerScripts;
using Il2CppScheduleOne.PlayerTasks;
using Il2CppScheduleOne.Product;
using Il2CppScheduleOne.Product.Packaging;
using Il2CppScheduleOne.Quests;
using Il2CppScheduleOne.StationFramework;
using Il2CppScheduleOne.Storage;
using Il2CppScheduleOne.UI;
using Il2CppScheduleOne.UI.MainMenu;
using Il2CppScheduleOne.UI.Phone;
using Il2CppScheduleOne.UI.Phone.Delivery;
using Il2CppScheduleOne.UI.Phone.Messages;
using Il2CppScheduleOne.UI.Phone.ProductManagerApp;
using Il2CppScheduleOne.UI.Shop;
using Il2CppScheduleOne.UI.Stations;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using Il2CppTMPro;
using MelonLoader;
using MelonLoader.Preferences;
using MelonLoader.Utils;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using S1API.Quests;
using S1API.Saveables;
using UnicornsCustomSeeds;
using UnicornsCustomSeeds.Managers;
using UnicornsCustomSeeds.Patches;
using UnicornsCustomSeeds.SeedQuests;
using UnicornsCustomSeeds.Seeds;
using UnicornsCustomSeeds.TemplateUtils;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: MelonInfo(typeof(Core), "Unicorns Custom Seeds", "2.0.0", "OverweightUnicorn", null)]
[assembly: MelonColor(255, 191, 0, 255)]
[assembly: MelonGame("TVGS", "Schedule I")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: IgnoresAccessChecksTo("")]
[assembly: AssemblyCompany("UnicornsCustomSeeds_IL2Cpp_2.0.0")]
[assembly: AssemblyConfiguration("IL2CPP")]
[assembly: AssemblyFileVersion("2.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+e461a7660e01a07343e77de06ce6dba4d64452ad")]
[assembly: AssemblyProduct("UnicornsCustomSeeds_IL2Cpp_2.0.0")]
[assembly: AssemblyTitle("UnicornsCustomSeeds_IL2Cpp_2.0.0")]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace UnicornsCustomSeeds
{
	public static class BuildInfo
	{
		public const string Name = "Unicorns Custom Seeds";

		public const string Description = "Your good buddy Unicorn can help you synthesize seeds";

		public const string Author = "OverweightUnicorn";

		public const string Company = "UnicornsCanMod";

		public const string Version = "2.0.0";

		public const string DownloadLink = null;
	}
	public class Core : MelonMod
	{
		public static bool ModInitialized;

		public override void OnInitializeMelon()
		{
			StashManager.InitializeConfig();
			AssetBundleUtils.Initialize(this);
		}

		public override void OnLateInitializeMelon()
		{
			SeedVisualsManager.LoadSeedMaterial();
			Singleton<LoadManager>.Instance.onLoadComplete.AddListener(UnityAction.op_Implicit((Action)InitMod));
			Singleton<SaveManager>.Instance.onSaveComplete.AddListener(UnityAction.op_Implicit((Action)SaveData));
		}

		public void SaveData()
		{
			TrySaveData();
		}

		public bool TrySaveData()
		{
			try
			{
				string loadedGameFolderPath = Singleton<LoadManager>.Instance.LoadedGameFolderPath;
				if (string.IsNullOrEmpty(loadedGameFolderPath) || !Directory.Exists(loadedGameFolderPath))
				{
					Utility.Error("Core.TrySaveData: save folder unavailable ('" + loadedGameFolderPath + "') — nothing written.");
					return false;
				}
				List<UnicornSeedData> list = new List<UnicornSeedData>();
				list.AddRange(CustomSeedsManager.DiscoveredSeeds.Values);
				list.AddRange(CustomShroomsManager.DiscoveredShrooms.Values);
				list.AddRange(CustomCocaSeedsManager.DiscoveredCocaSeeds.Values);
				list.AddRange(CustomPseudoManager.DiscoveredPseudoSeeds.Values);
				string contents = JsonConvert.SerializeObject((object)list, (Formatting)1);
				File.WriteAllText(Path.Combine(loadedGameFolderPath, "DiscoveredCustomSeeds.json"), contents);
				List<ActiveCookingEntry> list2 = new List<ActiveCookingEntry>();
				foreach (KeyValuePair<string, string> item in ActiveCookingRegistry.GuidToMixId)
				{
					list2.Add(new ActiveCookingEntry
					{
						stationGuid = item.Key,
						mixId = item.Value
					});
				}
				string contents2 = JsonConvert.SerializeObject((object)list2, (Formatting)1);
				File.WriteAllText(Path.Combine(loadedGameFolderPath, "UnicornsActiveCooking.json"), contents2);
				return true;
			}
			catch (Exception e)
			{
				Utility.PrintException(e);
				return false;
			}
		}

		public void InitMod()
		{
			Utility.Log($"InitMod: start (IsServer={InstanceFinder.IsServer}, IsClientOnly={InstanceFinder.IsClientOnly}).");
			CustomSeedsManager.Initialize();
			CustomShroomsManager.Initialize();
			CustomCocaSeedsManager.Initialize();
			CustomPseudoManager.Initialize();
			StashManager.GetAlbertsStash();
			if (CustomSeedsManager.letsMigrate)
			{
				bool flag = CustomSeedsManager.DiscoveredSeeds.Count > 0 || CustomShroomsManager.DiscoveredShrooms.Count > 0 || CustomCocaSeedsManager.DiscoveredCocaSeeds.Count > 0;
				int value = CustomSeedsManager.DiscoveredSeeds.Count + CustomShroomsManager.DiscoveredShrooms.Count + CustomCocaSeedsManager.DiscoveredCocaSeeds.Count + CustomPseudoManager.DiscoveredPseudoSeeds.Count;
				if (!flag)
				{
					Utility.Error("[MIGRATE] flagged but nothing loaded — skipping the save so the existing file isn't overwritten with an empty list.");
				}
				else if (!TrySaveData())
				{
					Utility.Error("[MIGRATE] rewrite FAILED — legacy file untouched, will retry on next load.");
				}
				else if (!LoadManager_StartGame_Patch.VerifyMigratedFile())
				{
					Utility.Error("[MIGRATE] save reported success but the file on disk is still legacy — will retry on next load.");
				}
				else
				{
					Utility.Success($"[MIGRATE] {value} record(s) converted and rewritten in the new format.");
					CustomSeedsManager.letsMigrate = false;
				}
			}
			DeferredCookOpsManager.TryReplayAll();
			MelonCoroutines.Start(StashManager.WaitForAllStashesAndSubscribe());
		}

		public override void OnSceneWasLoaded(int buildIndex, string sceneName)
		{
			SeedDefinition item = Registry.GetItem<SeedDefinition>("ogkushseed");
			if (CustomSeedsManager.factory == null && (Object)(object)item != (Object)null)
			{
				CustomSeedsManager.factory = new SeedFactory(item);
			}
			SporeSyringeDefinition item2 = Registry.GetItem<SporeSyringeDefinition>("sporesyringe");
			if (CustomShroomsManager.factory == null && (Object)(object)item2 != (Object)null)
			{
				CustomShroomsManager.factory = new SyringeFactory(item2);
			}
			Dictionary<int, ItemRegister> itemDictionary = Singleton<Registry>.Instance.ItemDictionary;
			SeedDefinition item3 = Registry.GetItem<SeedDefinition>("cocaseed");
			QualityItemDefinition item4 = Registry.GetItem<QualityItemDefinition>("cocaleaf");
			QualityItemDefinition item5 = Registry.GetItem<QualityItemDefinition>("cocainebase");
			if (CustomCocaSeedsManager.factory == null && (Object)(object)item3 != (Object)null && (Object)(object)item4 != (Object)null && (Object)(object)item5 != (Object)null)
			{
				CustomCocaSeedsManager.factory = new CocaFactory(item3, item4, item5);
			}
			else if (CustomCocaSeedsManager.factory == null)
			{
				Utility.Critical("Unicorns Custom Seeds: coca seeds are unavailable — CocaFactory could not initialize.");
				Utility.Error($"Core: CocaFactory init failed — cocaseed={(Object)(object)item3 != (Object)null}, cocaleaf={(Object)(object)item4 != (Object)null}, cocainebase={(Object)(object)item5 != (Object)null}");
			}
			if (sceneName.ToLower() != "main")
			{
				CustomSeedsManager.ClearAll();
				CustomShroomsManager.ClearAll();
				CustomCocaSeedsManager.ClearAll();
				CustomPseudoManager.ClearAll();
				ActiveCookingRegistry.Clear();
				ProductManagerAppPatches.ClearPendingIndicators();
				StashManager.ClearCaches();
				DeferredSlotsManager.ClearAll();
				DeferredCookOpsManager.ClearAll();
				ModInitialized = false;
			}
			else
			{
				if ((Object)(object)SeedVisualsManager.baseQuestIconSprite == (Object)null || (Object)(object)SeedVisualsManager.baseSeedSprite == (Object)null)
				{
					SeedVisualsManager.LoadSeedMaterial();
				}
				if (CustomPseudoManager.factory == null)
				{
					MelonCoroutines.Start(InitPseudoFactoryWhenReady());
				}
			}
		}

		private IEnumerator InitPseudoFactoryWhenReady()
		{
			int timeoutFrames = 1800;
			while (timeoutFrames-- > 0)
			{
				bool ready = false;
				try
				{
					ChemistryStationInterface instance = Singleton<ChemistryStationInterface>.Instance;
					ready = instance != null && instance.Recipes?.Count > 0;
				}
				catch
				{
				}
				if (ready)
				{
					break;
				}
				yield return null;
			}
			if (timeoutFrames <= 0)
			{
				Utility.Critical("Unicorns Custom Seeds: custom meth is unavailable — timed out waiting for the chemistry station's recipe list.");
				Utility.Error("Core: Timed out waiting for ChemistryStationInterface.Recipes — PseudoFactory not initialized.");
				yield break;
			}
			try
			{
				QualityItemDefinition basePseudo = Registry.GetItem<QualityItemDefinition>("pseudo");
				QualityItemDefinition lowPseudo = Registry.GetItem<QualityItemDefinition>("lowqualitypseudo");
				QualityItemDefinition highPseudo = Registry.GetItem<QualityItemDefinition>("highqualitypseudo");
				ItemDefinition rawLiquidMeth = Registry.GetItem("liquidmeth");
				LiquidMethDefinition baseLiquidMeth = ((rawLiquidMeth != null) ? ((Il2CppObjectBase)rawLiquidMeth).TryCast<LiquidMethDefinition>() : null);
				StationRecipe baseRecipe = null;
				Enumerator<StationRecipe> enumerator = Singleton<ChemistryStationInterface>.Instance.Recipes.GetEnumerator();
				while (enumerator.MoveNext())
				{
					StationRecipe r = enumerator.Current;
					ItemQuantity product = r.Product;
					object obj2;
					if (product == null)
					{
						obj2 = null;
					}
					else
					{
						ItemDefinition item = product.Item;
						obj2 = ((item != null) ? ((BaseItemDefinition)item).ID : null);
					}
					if ((string?)obj2 == "liquidmeth")
					{
						baseRecipe = r;
						break;
					}
				}
				if ((Object)(object)basePseudo != (Object)null && (Object)(object)lowPseudo != (Object)null && (Object)(object)highPseudo != (Object)null && (Object)(object)baseLiquidMeth != (Object)null && (Object)(object)baseRecipe != (Object)null)
				{
					CustomPseudoManager.factory = new PseudoFactory(basePseudo, lowPseudo, highPseudo, baseLiquidMeth, baseRecipe);
					Utility.Log("Core: PseudoFactory initialized.");
					yield break;
				}
				Utility.Critical("Unicorns Custom Seeds: custom meth is unavailable — PseudoFactory could not initialize.");
				Utility.Error($"Core: PseudoFactory init failed — pseudo={(Object)(object)basePseudo != (Object)null}, lowPseudo={(Object)(object)lowPseudo != (Object)null}, highPseudo={(Object)(object)highPseudo != (Object)null}, liquidmeth={(Object)(object)baseLiquidMeth != (Object)null}, recipe={(Object)(object)baseRecipe != (Object)null}");
			}
			catch (Exception e)
			{
				Utility.PrintException(e);
			}
		}
	}
}
namespace UnicornsCustomSeeds.TemplateUtils
{
	public static class AssetBundleUtils
	{
		private static Core mod;

		private static MelonAssembly melonAssembly;

		private static Dictionary<string, Il2CppAssetBundle> assetBundles = new Dictionary<string, Il2CppAssetBundle>();

		private static string DataFolderName = "UnicornsCanBundle";

		private static string ModFolderName = "UnicornsCustomSeeds";

		private static string GetBundleCachePath(string bundleFileName)
		{
			string text = Path.Combine(MelonEnvironment.UserDataDirectory, DataFolderName, ModFolderName);
			Directory.CreateDirectory(text);
			return Path.Combine(text, bundleFileName + "_2.0.0");
		}

		private static byte[] ReadEmbeddedBundleBytes(string bundleFileName)
		{
			string text = typeof(Core).Namespace + ".Assets." + bundleFileName;
			using Stream stream = melonAssembly.Assembly.GetManifestResourceStream(text);
			if (stream == null)
			{
				Utility.Critical("Unicorns Custom Seeds: asset bundle '" + bundleFileName + "' is missing from the mod DLL — icons and shaders will not load.");
				Utility.Error($"AssetBundle resource '{text}' not found. Check EmbeddedResource entry for '{bundleFileName}'.");
				return null;
			}
			using MemoryStream memoryStream = new MemoryStream();
			stream.CopyTo(memoryStream);
			byte[] array = memoryStream.ToArray();
			if (array.Length == 0)
			{
				Utility.Critical("Unicorns Custom Seeds: asset bundle '" + bundleFileName + "' is empty — icons and shaders will not load.");
				return null;
			}
			return array;
		}

		public static bool EnsureBundleCached(string bundleFileName)
		{
			string bundleCachePath = GetBundleCachePath(bundleFileName);
			if (File.Exists(bundleCachePath))
			{
				return true;
			}
			byte[] array = ReadEmbeddedBundleBytes(bundleFileName);
			if (array == null)
			{
				return false;
			}
			try
			{
				File.WriteAllBytes(bundleCachePath, array);
				Utility.Log($"Cached AssetBundle '{bundleFileName}' to '{bundleCachePath}'.");
				return true;
			}
			catch (Exception value)
			{
				Utility.Error($"Failed writing AssetBundle cache '{bundleFileName}': {value}");
				return false;
			}
		}

		private static Il2CppAssetBundle LoadBundleFromFile(string bundleFileName)
		{
			string bundleCachePath = GetBundleCachePath(bundleFileName);
			try
			{
				Il2CppAssetBundle val = Il2CppAssetBundleManager.LoadFromFile(bundleCachePath);
				if (val == null)
				{
					Utility.Critical("Unicorns Custom Seeds: asset bundle '" + bundleFileName + "' failed to load — icons and shaders will be missing.");
					Utility.Error($"LoadFromFile returned null for bundle '{bundleFileName}' at '{bundleCachePath}'.");
				}
				return val;
			}
			catch (Exception value)
			{
				Utility.Error($"LoadFromFile failed for bundle '{bundleFileName}' at '{bundleCachePath}': {value}");
				return null;
			}
		}

		public static void Initialize(Core coreMod)
		{
			mod = coreMod;
			melonAssembly = ((MelonBase)mod).MelonAssembly;
		}

		public static Il2CppAssetBundle LoadAssetBundle(string bundleFileName)
		{
			if (assetBundles.TryGetValue(bundleFileName, out var value) && value != null)
			{
				return value;
			}
			try
			{
				string bundleCachePath = GetBundleCachePath(bundleFileName);
				Il2CppAssetBundle val;
				if (File.Exists(bundleCachePath))
				{
					val = LoadBundleFromFile(bundleFileName);
				}
				else
				{
					byte[] array = ReadEmbeddedBundleBytes(bundleFileName);
					if (array == null)
					{
						((MelonBase)mod).Unregister("Failed to read required AssetBundle '" + bundleFileName + "' from embedded resources.", false);
						return null;
					}
					try
					{
						Il2CppAssetBundle val2 = Il2CppAssetBundleManager.LoadFromMemory(Il2CppStructArray<byte>.op_Implicit(array));
						if (val2 == null)
						{
							((MelonBase)mod).Unregister("Failed to validate required AssetBundle '" + bundleFileName + "' from memory.", false);
							return null;
						}
						try
						{
							File.WriteAllBytes(bundleCachePath, array);
							Utility.Log($"Cached AssetBundle '{bundleFileName}' to '{bundleCachePath}'.");
						}
						catch (Exception value2)
						{
							try
							{
								val2.Unload(false);
							}
							catch
							{
							}
							((MelonBase)mod).Unregister($"Failed writing required AssetBundle '{bundleFileName}' to cache: {value2}", false);
							return null;
						}
						try
						{
							val2.Unload(false);
						}
						catch (Exception ex)
						{
							Utility.Warn("Failed to unload memory validation bundle '" + bundleFileName + "': " + ex.Message);
						}
						val = LoadBundleFromFile(bundleFileName);
					}
					catch (Exception value3)
					{
						((MelonBase)mod).Unregister($"Failed to validate required AssetBundle '{bundleFileName}' from memory: {value3}", false);
						return null;
					}
				}
				if (val == null)
				{
					((MelonBase)mod).Unregister("Failed to load required AssetBundle '" + bundleFileName + "'.", false);
					return null;
				}
				assetBundles[bundleFileName] = val;
				return val;
			}
			catch (Exception value4)
			{
				((MelonBase)mod).Unregister($"Failed to load required AssetBundle '{bundleFileName}': {value4}", false);
				return null;
			}
		}

		public static void ClearCache()
		{
			assetBundles.Clear();
		}

		public static Il2CppAssetBundle GetLoadedAssetBundle(string bundleName)
		{
			if (assetBundles.ContainsKey(bundleName))
			{
				return assetBundles[bundleName];
			}
			Utility.Warn("Asset bundle '" + bundleName + "' is not loaded.");
			return null;
		}

		public static T LoadAssetFromBundle<T>(string assetName, string bundleName) where T : Object
		{
			Il2CppAssetBundle loadedAssetBundle = GetLoadedAssetBundle(bundleName);
			if (loadedAssetBundle == null)
			{
				Utility.Error("Couldn't find loaded bundle '" + bundleName + "'.");
				return default(T);
			}
			T val = default(T);
			try
			{
				val = loadedAssetBundle.LoadAsset<T>(assetName);
			}
			catch (Exception value)
			{
				Utility.Error($"Failed loading asset '{assetName}' from bundle '{bundleName}'. The bundle may be invalid or have a zero internal pointer. {value}");
				return default(T);
			}
			if ((Object)(object)val == (Object)null)
			{
				Utility.Error($"Asset '{assetName}' not found in bundle '{bundleName}'.");
				return default(T);
			}
			return val;
		}

		public static Texture2D LoadTextureContaining(string bundleName, params string[] contains)
		{
			Il2CppAssetBundle loadedAssetBundle = GetLoadedAssetBundle(bundleName);
			if (loadedAssetBundle == null)
			{
				return null;
			}
			Il2CppStringArray allAssetNames = loadedAssetBundle.GetAllAssetNames();
			for (int i = 0; i < ((Il2CppArrayBase<string>)(object)allAssetNames).Length; i++)
			{
				string text = ((Il2CppArrayBase<string>)(object)allAssetNames)[i].ToLowerInvariant();
				bool flag = true;
				for (int j = 0; j < contains.Length; j++)
				{
					if (!text.Contains(contains[j].ToLowerInvariant()))
					{
						flag = false;
						break;
					}
				}
				if (!flag)
				{
					continue;
				}
				try
				{
					Texture2D val = loadedAssetBundle.LoadAsset<Texture2D>(((Il2CppArrayBase<string>)(object)allAssetNames)[i]);
					if ((Object)(object)val != (Object)null)
					{
						return val;
					}
				}
				catch (Exception ex)
				{
					Utility.Warn($"Failed loading texture '{((Il2CppArrayBase<string>)(object)allAssetNames)[i]}' from bundle '{bundleName}': {ex.Message}");
				}
			}
			return null;
		}
	}
	public static class Utility
	{
		public static MelonPreferences_Entry<bool> DebugEntry;

		public static bool IsDebug => DebugEntry != null && DebugEntry.Value;

		public static void Critical(string msg)
		{
			MelonLogger.Msg(ConsoleColor.Red, msg + " (enable DebugLogging in this mod's MelonPreferences for details)");
		}

		public static void PrintException(Exception e, string source, bool handled = true)
		{
			if (IsDebug)
			{
				MelonLogger.Msg(handled ? ConsoleColor.DarkYellow : ConsoleColor.Red, handled ? ("Caught in " + source + " — handled by the mod, the game did not halt:") : ("Unhandled in " + source + ":"));
				PrintException(e);
			}
		}

		public static void PrintException(Exception e)
		{
			if (!IsDebug)
			{
				return;
			}
			MelonLogger.Msg(ConsoleColor.Red, e.GetType().FullName);
			MelonLogger.Msg(ConsoleColor.DarkRed, e.Message);
			if (!string.IsNullOrWhiteSpace(e.StackTrace))
			{
				MelonLogger.Msg(ConsoleColor.DarkRed, "StackTrace:");
				string[] array = e.StackTrace.Split('\n');
				foreach (string text in array)
				{
					MelonLogger.Msg(ConsoleColor.DarkRed, "    " + text.Trim());
				}
			}
			if (e.InnerException != null)
			{
				MelonLogger.Msg(ConsoleColor.DarkRed, "  -- Inner Exception --");
				PrintException(e.InnerException);
			}
		}

		public static void Error(string msg)
		{
			if (IsDebug)
			{
				MelonLogger.Msg(ConsoleColor.Red, msg);
			}
		}

		public static void Warn(string msg)
		{
			if (IsDebug)
			{
				MelonLogger.Msg(ConsoleColor.Yellow, msg);
			}
		}

		public static void Log(string msg)
		{
			if (IsDebug)
			{
				MelonLogger.Msg(ConsoleColor.DarkMagenta, msg);
			}
		}

		public static void Success(string msg)
		{
			if (IsDebug)
			{
				MelonLogger.Msg(ConsoleColor.Green, msg);
			}
		}
	}
}
namespace UnicornsCustomSeeds.Seeds
{
	public class CocaFactory
	{
		private const float CocaIconRotation = 45f;

		public static readonly Dictionary<string, string> CustomLeafIdToBaseId = new Dictionary<string, string>();

		public static readonly Dictionary<string, string> CustomBaseIdToMixId = new Dictionary<string, string>();

		private Transform rootGameObject;

		private SeedDefinition baseSeedDefinition;

		private CocaPlant baseCocaPlantPrefab;

		private PlantHarvestable baseHarvestable;

		private FunctionalSeed baseFunctionalSeedPrefab;

		private Equippable_Seed baseEquippableSeedPrefab;

		private AvatarEquippable baseAvatarEquippablePrefab;

		private StoredItem baseStoredItem;

		private QualityItemDefinition baseCocaLeafDefinition;

		private QualityItemDefinition baseCocaineBaseDefinition;

		public CocaFactory(SeedDefinition baseSeed, QualityItemDefinition baseCocaLeaf, QualityItemDefinition baseCocaineBase)
		{
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Expected O, but got Unknown
			baseSeedDefinition = baseSeed;
			baseCocaLeafDefinition = baseCocaLeaf;
			baseCocaineBaseDefinition = baseCocaineBase;
			baseCocaPlantPrefab = ((Il2CppObjectBase)baseSeed.PlantPrefab).TryCast<CocaPlant>();
			if ((Object)(object)baseCocaPlantPrefab == (Object)null)
			{
				Utility.Error("CocaFactory: Failed to cast PlantPrefab to CocaPlant.");
			}
			CocaPlant obj = baseCocaPlantPrefab;
			baseHarvestable = ((obj != null) ? obj.Harvestable : null);
			baseFunctionalSeedPrefab = baseSeed.FunctionSeedPrefab;
			baseStoredItem = ((StorableItemDefinition)baseSeed).StoredItem;
			baseEquippableSeedPrefab = ((Il2CppObjectBase)((ItemDefinition)baseSeed).Equippable).TryCast<Equippable_Seed>();
			if ((Object)(object)baseEquippableSeedPrefab == (Object)null)
			{
				Utility.Error("CocaFactory: Failed to cast Equippable to Equippable_Seed.");
			}
			Equippable_Seed obj2 = baseEquippableSeedPrefab;
			baseAvatarEquippablePrefab = ((obj2 != null) ? ((Equippable_Viewmodel)obj2).AvatarEquippable : null);
			GameObject val = new GameObject(((BaseItemDefinition)baseSeedDefinition).ID + "_CustomCocaSeeds");
			val.SetActive(false);
			Object.DontDestroyOnLoad((Object)(object)val);
			rootGameObject = val.transform;
		}

		public void DeleteChildren()
		{
			TransformExt.DeleteChildren(rootGameObject, true, false);
			CustomLeafIdToBaseId.Clear();
			CustomBaseIdToMixId.Clear();
		}

		public SeedDefinition CreateCocaSeedDefinition(ProductDefinition cocaineDef)
		{
			if ((Object)(object)baseSeedDefinition == (Object)null)
			{
				throw new InvalidOperationException("Base seed definition not initialized.");
			}
			CocaineAppearanceSettings val = ResolveCocaAppearance(cocaineDef);
			QualityItemDefinition val2 = CloneCustomCocaineBase(cocaineDef, val);
			QualityItemDefinition val3 = CloneCustomCocaLeaf(val2, cocaineDef, val);
			CocaPlant plantPrefab = CloneCocaPlant(val3);
			SeedDefinition val4 = Object.Instantiate<SeedDefinition>(baseSeedDefinition);
			((BaseItemDefinition)val4).ID = ((BaseItemDefinition)cocaineDef).ID + "_customcocaseed";
			((Object)val4).name = ((BaseItemDefinition)val4).ID;
			((BaseItemDefinition)val4).Name = ((Object)cocaineDef).name + " Coca Seed";
			((BaseItemDefinition)val4).Description = "A custom coca seed that produces " + ((Object)cocaineDef).name + ".";
			((BaseItemDefinition)val4).Icon = ((BaseItemDefinition)baseSeedDefinition).Icon;
			SeedVisualsManager.cocaAppearanceMap[((BaseItemDefinition)val4).ID] = val;
			val4.PlantPrefab = (Plant)(object)plantPrefab;
			val4.PlantPrefab.SeedDefinition = val4;
			val4.FunctionSeedPrefab = CloneFunctionalSeedPrefab(((BaseItemDefinition)val4).ID);
			((Object)val4.FunctionSeedPrefab).name = ((BaseItemDefinition)cocaineDef).ID + "CocaSeed_Functional";
			((ItemDefinition)val4).Equippable = (Equippable)(object)CloneEquippableSeedPrefab(val4);
			((StorableItemDefinition)val4).StoredItem = CloneStoredItem(((BaseItemDefinition)val4).ID);
			AssignCocaIcon(val4, val);
			Singleton<Registry>.Instance.AddToRegistry((ItemDefinition)(object)val3);
			Singleton<Registry>.Instance.AddToRegistry((ItemDefinition)(object)val2);
			return val4;
		}

		private CocaineAppearanceSettings ResolveCocaAppearance(ProductDefinition cocaineDef)
		{
			CocaineDefinition val = ((Il2CppObjectBase)cocaineDef).TryCast<CocaineDefinition>();
			if ((Object)(object)val == (Object)null)
			{
				Utility.Error("CocaFactory: '" + ((BaseItemDefinition)cocaineDef).ID + "' is not a CocaineDefinition — no appearance available.");
				return null;
			}
			CocaineAppearanceSettings appearanceSettings = val.AppearanceSettings;
			if (appearanceSettings == null || appearanceSettings.IsUnintialized())
			{
				appearanceSettings = CocaineDefinition.GetAppearanceSettings(((PropertyItemDefinition)val).Properties);
			}
			if (appearanceSettings == null)
			{
				Utility.Error("CocaFactory: No appearance settings for '" + ((BaseItemDefinition)cocaineDef).ID + "'.");
			}
			return appearanceSettings;
		}

		private void AssignCocaIcon(SeedDefinition newSeed, CocaineAppearanceSettings appearance)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)SeedVisualsManager.baseSeedSprite == (Object)null || appearance == null)
			{
				return;
			}
			try
			{
				(Color top, Color bottom) tuple = SeedVisualsManager.BoostContrastIfSimilar(Color32.op_Implicit(appearance.MainColor), Color32.op_Implicit(appearance.SecondaryColor));
				Color item = tuple.top;
				Color item2 = tuple.bottom;
				Sprite val = SeedVisualsManager.GenerateIconWithKeyColorFill(SeedVisualsManager.baseCocaSeedSprite, item, item2);
				((Object)val).name = ((Object)newSeed).name + "_icon";
				SeedVisualsManager.seedIcons[((BaseItemDefinition)newSeed).ID] = val;
				((BaseItemDefinition)newSeed).Icon = val;
			}
			catch (Exception e)
			{
				((BaseItemDefinition)newSeed).Icon = SeedVisualsManager.baseSeedSprite;
				Utility.PrintException(e);
			}
		}

		private void AssignCocaIntermediateIcon(QualityItemDefinition clone, Sprite baseIcon, CocaineAppearanceSettings appearance)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)baseIcon == (Object)null || appearance == null)
			{
				return;
			}
			try
			{
				(Color top, Color bottom) tuple = SeedVisualsManager.BoostContrastIfSimilar(Color32.op_Implicit(appearance.MainColor), Color32.op_Implicit(appearance.SecondaryColor));
				Color item = tuple.top;
				Color item2 = tuple.bottom;
				Sprite val = SeedVisualsManager.GenerateIconWithKeyColorFill(baseIcon, item, item2);
				if (!((Object)(object)val == (Object)null))
				{
					((Object)val).name = ((Object)clone).name + "_icon";
					SeedVisualsManager.seedIcons[((BaseItemDefinition)clone).ID] = val;
					((BaseItemDefinition)clone).Icon = val;
				}
			}
			catch (Exception e)
			{
				((BaseItemDefinition)clone).Icon = baseIcon;
				Utility.PrintException(e);
			}
		}

		private void GrowLabel(Transform root, string seedDefId)
		{
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			Transform val = null;
			Il2CppArrayBase<Transform> componentsInChildren = ((Component)root).GetComponentsInChildren<Transform>();
			foreach (Transform item in componentsInChildren)
			{
				if (((Object)item).name == "Label")
				{
					val = ((Component)item).transform;
				}
			}
			if ((Object)(object)val != (Object)null)
			{
				val.localScale = new Vector3(1.05f, 1.05f, 2f);
				val.position = new Vector3(0f, -0.05f, 0f);
				if ((Object)(object)SeedVisualsManager.customMat == (Object)null)
				{
					SeedVisualsManager.LoadSeedMaterial();
				}
				if ((Object)(object)SeedVisualsManager.customMat != (Object)null)
				{
					Renderer component = ((Component)val).GetComponent<Renderer>();
					component.material = SeedVisualsManager.customMat;
					((Component)val).gameObject.AddComponent<SeedVialLabel>();
					((Object)val).name = ((Object)val).name + ":" + seedDefId;
				}
				else
				{
					Utility.Log("MATERIAL NOT LOADED!!!");
				}
			}
		}

		private QualityItemDefinition CloneCustomCocaineBase(ProductDefinition cocaineDef, CocaineAppearanceSettings appearance)
		{
			QualityItemDefinition val = Object.Instantiate<QualityItemDefinition>(baseCocaineBaseDefinition);
			((BaseItemDefinition)val).ID = ((BaseItemDefinition)cocaineDef).ID + "_customcocainebase";
			((Object)val).name = ((BaseItemDefinition)val).ID;
			((BaseItemDefinition)val).Name = ((Object)cocaineDef).name + " Base";
			if ((Object)(object)((StorableItemDefinition)baseCocaineBaseDefinition).StationItem != (Object)null)
			{
				StationItem val2 = Object.Instantiate<StationItem>(((StorableItemDefinition)baseCocaineBaseDefinition).StationItem, rootGameObject);
				((Object)val2).name = ((BaseItemDefinition)cocaineDef).ID + "_CocaineBaseStationItem";
				CookableModule module = val2.GetModule<CookableModule>();
				if ((Object)(object)module != (Object)null)
				{
					module.Product = (StorableItemDefinition)(object)cocaineDef;
				}
				else
				{
					Utility.Error("CocaFactory: No CookableModule on StationItem for " + ((BaseItemDefinition)cocaineDef).ID + ". LabOven will output vanilla product.");
				}
				((StorableItemDefinition)val).StationItem = val2;
			}
			else
			{
				Utility.Error("CocaFactory: baseCocaineBaseDefinition.StationItem is null.");
			}
			AssignCocaIntermediateIcon(val, SeedVisualsManager.baseCocaBaseSprite, appearance);
			CustomBaseIdToMixId[((BaseItemDefinition)val).ID] = ((BaseItemDefinition)cocaineDef).ID;
			return val;
		}

		private QualityItemDefinition CloneCustomCocaLeaf(QualityItemDefinition customBase, ProductDefinition cocaineDef, CocaineAppearanceSettings appearance)
		{
			QualityItemDefinition val = Object.Instantiate<QualityItemDefinition>(baseCocaLeafDefinition);
			((BaseItemDefinition)val).ID = ((BaseItemDefinition)cocaineDef).ID + "_customcocaleaf";
			((Object)val).name = ((BaseItemDefinition)val).ID;
			((BaseItemDefinition)val).Name = "Coca Leaf (" + ((Object)cocaineDef).name + ")";
			((StorableItemDefinition)val).StationItem = ((StorableItemDefinition)baseCocaLeafDefinition).StationItem;
			AssignCocaIntermediateIcon(val, SeedVisualsManager.baseCocaLeafSprite, appearance);
			CustomLeafIdToBaseId[((BaseItemDefinition)val).ID] = ((BaseItemDefinition)customBase).ID;
			return val;
		}

		private CocaPlant CloneCocaPlant(QualityItemDefinition customLeaf)
		{
			CocaPlant val = Object.Instantiate<CocaPlant>(baseCocaPlantPrefab, rootGameObject);
			((Object)((Component)val).gameObject).name = ((BaseItemDefinition)customLeaf).ID + "_CocaPlant";
			PlantHarvestable val2 = Object.Instantiate<PlantHarvestable>(baseHarvestable, rootGameObject);
			((Object)((Component)val2).gameObject).name = ((BaseItemDefinition)customLeaf).ID + "_Harvestable";
			val2.Product = (StorableItemDefinition)(object)customLeaf;
			val.Harvestable = val2;
			foreach (PlantHarvestable componentsInChild in ((Component)val).GetComponentsInChildren<PlantHarvestable>())
			{
				componentsInChild.Product = (StorableItemDefinition)(object)customLeaf;
			}
			return val;
		}

		private FunctionalSeed CloneFunctionalSeedPrefab(string seedDefId)
		{
			if ((Object)(object)baseFunctionalSeedPrefab == (Object)null)
			{
				throw new InvalidOperationException("Base functional seed prefab not initialized.");
			}
			FunctionalSeed val = Object.Instantiate<FunctionalSeed>(baseFunctionalSeedPrefab, rootGameObject);
			((Object)((Component)val).gameObject).name = seedDefId + "_Functional";
			GrowLabel(((Component)val).transform, seedDefId);
			return val;
		}

		private Equippable_Seed CloneEquippableSeedPrefab(SeedDefinition newDef)
		{
			if ((Object)(object)baseEquippableSeedPrefab == (Object)null)
			{
				throw new InvalidOperationException("Base equippable seed prefab not initialized.");
			}
			Equippable_Seed val = Object.Instantiate<Equippable_Seed>(baseEquippableSeedPrefab, rootGameObject);
			GrowLabel(((Component)val).transform, ((BaseItemDefinition)newDef).ID);
			((Object)((Component)val).gameObject).name = ((BaseItemDefinition)newDef).ID + "_Equippable";
			((Component)val).gameObject.layer = ((Component)baseEquippableSeedPrefab).gameObject.layer;
			val.Seed = newDef;
			((Equippable_Viewmodel)val).AvatarEquippable = CloneAvatarEquippablePrefab(((BaseItemDefinition)newDef).ID);
			((Object)((Equippable_Viewmodel)val).AvatarEquippable).name = ((BaseItemDefinition)newDef).ID + "_AvatarEquippable";
			return val;
		}

		private AvatarEquippable CloneAvatarEquippablePrefab(string newDefId)
		{
			if ((Object)(object)baseAvatarEquippablePrefab == (Object)null)
			{
				throw new InvalidOperationException("Base avatar equippable prefab not initialized.");
			}
			AvatarEquippable val = Object.Instantiate<AvatarEquippable>(baseAvatarEquippablePrefab, rootGameObject);
			GrowLabel(((Component)val).transform, newDefId);
			((Object)((Component)val).gameObject).name = newDefId + "_AvatarEquippable";
			return val;
		}

		private StoredItem CloneStoredItem(string newDefId)
		{
			if ((Object)(object)baseStoredItem == (Object)null)
			{
				throw new InvalidOperationException("Base stored item not initialized.");
			}
			StoredItem val = Object.Instantiate<StoredItem>(baseStoredItem, rootGameObject);
			GrowLabel(((Component)val).transform, newDefId);
			((Object)((Component)val).gameObject).name = newDefId + "_StoredItem";
			return val;
		}

		public static void AddLeafToCauldrons(QualityItemDefinition customLeaf)
		{
			Cauldron[] array = Il2CppArrayBase<Cauldron>.op_Implicit(Object.FindObjectsOfType<Cauldron>());
			int num = 0;
			Cauldron[] array2 = array;
			foreach (Cauldron val in array2)
			{
				foreach (ItemSlot item in (Il2CppArrayBase<ItemSlot>)(object)val.IngredientSlots)
				{
					Enumerator<ItemFilter> enumerator2 = item.HardFilters.GetEnumerator();
					while (enumerator2.MoveNext())
					{
						ItemFilter current2 = enumerator2.Current;
						ItemFilter_ID val2 = ((Il2CppObjectBase)current2).TryCast<ItemFilter_ID>();
						if (val2 != null && !val2.IDs.Contains(((BaseItemDefinition)customLeaf).ID))
						{
							val2.IDs.Add(((BaseItemDefinition)customLeaf).ID);
							num++;
						}
					}
				}
			}
		}
	}
	public class PseudoFactory
	{
		public static readonly Dictionary<string, string> CustomPseudoIdToLiquidMethId = new Dictionary<string, string>();

		private readonly Dictionary<string, Sprite> pseudoIconCache = new Dictionary<string, Sprite>();

		private readonly Dictionary<string, QualityItemDefinition> basePseudoDefinitions;

		private readonly LiquidMethDefinition baseLiquidMethDefinition;

		private readonly StationRecipe baseStationRecipe;

		private readonly Transform rootGameObject;

		public PseudoFactory(QualityItemDefinition basePseudo, QualityItemDefinition lowPseudo, QualityItemDefinition highPseudo, LiquidMethDefinition baseLiquidMeth, StationRecipe baseRecipe)
		{
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Expected O, but got Unknown
			basePseudoDefinitions = new Dictionary<string, QualityItemDefinition>
			{
				["pseudo"] = basePseudo,
				["lowqualitypseudo"] = lowPseudo,
				["highqualitypseudo"] = highPseudo
			};
			baseLiquidMethDefinition = baseLiquidMeth;
			baseStationRecipe = baseRecipe;
			GameObject val = new GameObject(((BaseItemDefinition)basePseudo).ID + "_CustomPseudoChains");
			val.SetActive(false);
			Object.DontDestroyOnLoad((Object)(object)val);
			rootGameObject = val.transform;
		}

		public void DeleteChildren()
		{
			TransformExt.DeleteChildren(rootGameObject, true, false);
			CustomPseudoIdToLiquidMethId.Clear();
			pseudoIconCache.Clear();
		}

		public QualityItemDefinition CreatePseudoChain(MethDefinition methDef, string pseudoBaseId)
		{
			QualityItemDefinition val = ResolvePseudoBaseDefinition(pseudoBaseId);
			if ((Object)(object)val == (Object)null)
			{
				throw new InvalidOperationException("PseudoFactory: Base pseudo definition '" + pseudoBaseId + "' not initialized.");
			}
			if ((Object)(object)baseLiquidMethDefinition == (Object)null)
			{
				throw new InvalidOperationException("PseudoFactory: Base liquid meth definition not initialized.");
			}
			if ((Object)(object)baseStationRecipe == (Object)null)
			{
				throw new InvalidOperationException("PseudoFactory: Base station recipe not initialized.");
			}
			LiquidMethDefinition val2 = ResolveOrCreateCustomLiquidMeth(methDef);
			QualityItemDefinition val3 = ResolveOrCreateCustomPseudo(val, val2, methDef);
			if ((Object)(object)val2 == (Object)null || (Object)(object)val3 == (Object)null)
			{
				return null;
			}
			Utility.Log($"PseudoFactory: {((BaseItemDefinition)methDef).ID} → pseudo:{((BaseItemDefinition)val3).ID} → liquidmeth:{((BaseItemDefinition)val2).ID} → meth:{((BaseItemDefinition)methDef).ID}");
			return val3;
		}

		public void InjectRecipeForMix(UnicornSeedData data, string methId)
		{
			ItemDefinition item = Registry.GetItem(methId + "_customliquidmeth");
			LiquidMethDefinition val = ((item != null) ? ((Il2CppObjectBase)item).TryCast<LiquidMethDefinition>() : null);
			if (data == null || (Object)(object)val == (Object)null)
			{
				Utility.Error($"PseudoFactory.InjectRecipeForMix: Cannot resolve assets for '{methId}' — data={data != null}, liquidmeth={(Object)(object)val != (Object)null}.");
				return;
			}
			List<QualityItemDefinition> list = new List<QualityItemDefinition>();
			foreach (VariantSeedData variant in data.variants)
			{
				QualityItemDefinition item2 = Registry.GetItem<QualityItemDefinition>(variant.seedId);
				if ((Object)(object)item2 != (Object)null)
				{
					list.Add(item2);
				}
			}
			if (list.Count == 0)
			{
				Utility.Error("PseudoFactory.InjectRecipeForMix: No pseudo variants resolved for '" + methId + "'.");
			}
			else
			{
				InjectCustomRecipeInternal(list, val, methId);
			}
		}

		private LiquidMethDefinition CloneCustomLiquidMeth(MethDefinition methDef)
		{
			LiquidMethDefinition val = Object.Instantiate<LiquidMethDefinition>(baseLiquidMethDefinition);
			((BaseItemDefinition)val).ID = ((BaseItemDefinition)methDef).ID + "_customliquidmeth";
			((Object)val).name = ((BaseItemDefinition)val).ID;
			((BaseItemDefinition)val).Name = "Liquid " + ((Object)methDef).name;
			if ((Object)(object)((StorableItemDefinition)baseLiquidMethDefinition).StationItem != (Object)null)
			{
				StationItem val2 = Object.Instantiate<StationItem>(((StorableItemDefinition)baseLiquidMethDefinition).StationItem, rootGameObject);
				((Object)val2).name = ((BaseItemDefinition)methDef).ID + "_LiquidMethStationItem";
				CookableModule module = val2.GetModule<CookableModule>();
				if ((Object)(object)module != (Object)null)
				{
					module.Product = (StorableItemDefinition)(object)methDef;
					Utility.Log("PseudoFactory: Set CookableModule.Product = '" + ((BaseItemDefinition)methDef).ID + "'.");
				}
				else
				{
					Utility.Error("PseudoFactory: No CookableModule on liquidmeth StationItem for '" + ((BaseItemDefinition)methDef).ID + "'.");
				}
				((StorableItemDefinition)val).StationItem = val2;
			}
			else
			{
				Utility.Error("PseudoFactory: baseLiquidMethDefinition.StationItem is null.");
			}
			AssignLiquidMethIcon(val, methDef);
			return val;
		}

		private void AssignLiquidMethIcon(LiquidMethDefinition clone, MethDefinition methDef)
		{
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)SeedVisualsManager.baseLiquidMethSprite == (Object)null)
			{
				return;
			}
			MethAppearanceSettings appearanceSettings = methDef.AppearanceSettings;
			if (appearanceSettings == null || appearanceSettings.IsUnintialized())
			{
				appearanceSettings = MethDefinition.GetAppearanceSettings(((PropertyItemDefinition)methDef).Properties);
			}
			if (appearanceSettings == null)
			{
				Utility.Error("PseudoFactory: No appearance settings for '" + ((BaseItemDefinition)methDef).ID + "' — keeping base liquid meth icon.");
				return;
			}
			try
			{
				(Color top, Color bottom) tuple = SeedVisualsManager.BoostContrastIfSimilar(Color32.op_Implicit(appearanceSettings.MainColor), Color32.op_Implicit(appearanceSettings.SecondaryColor));
				Color item = tuple.top;
				Color item2 = tuple.bottom;
				Sprite val = SeedVisualsManager.GenerateIconWithKeyColorFill(SeedVisualsManager.baseLiquidMethSprite, item, item2);
				if (!((Object)(object)val == (Object)null))
				{
					((Object)val).name = ((Object)clone).name + "_icon";
					SeedVisualsManager.seedIcons[((BaseItemDefinition)clone).ID] = val;
					((BaseItemDefinition)clone).Icon = val;
				}
			}
			catch (Exception e)
			{
				((BaseItemDefinition)clone).Icon = SeedVisualsManager.baseLiquidMethSprite;
				Utility.PrintException(e);
			}
		}

		private LiquidMethDefinition ResolveOrCreateCustomLiquidMeth(MethDefinition methDef)
		{
			string text = ((BaseItemDefinition)methDef).ID + "_customliquidmeth";
			ItemDefinition item = Registry.GetItem(text);
			LiquidMethDefinition val = ((item != null) ? ((Il2CppObjectBase)item).TryCast<LiquidMethDefinition>() : null);
			if ((Object)(object)val != (Object)null)
			{
				return val;
			}
			LiquidMethDefinition val2 = CloneCustomLiquidMeth(methDef);
			if ((Object)(object)val2 != (Object)null)
			{
				Singleton<Registry>.Instance.AddToRegistry((ItemDefinition)(object)val2);
			}
			return val2;
		}

		private QualityItemDefinition CloneCustomPseudo(QualityItemDefinition basePseudoDefinition, LiquidMethDefinition customLiquidMeth, MethDefinition methDef)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Expected I4, but got Unknown
			QualityItemDefinition val = Object.Instantiate<QualityItemDefinition>(basePseudoDefinition);
			((BaseItemDefinition)val).ID = ((BaseItemDefinition)methDef).ID + "_" + ((BaseItemDefinition)basePseudoDefinition).ID + "_custompseudo";
			((Object)val).name = ((BaseItemDefinition)val).ID;
			EQuality defaultQuality = basePseudoDefinition.DefaultQuality;
			EQuality val2 = defaultQuality;
			switch ((int)val2)
			{
			case 0:
				((BaseItemDefinition)val).Name = "Lo-Quality " + ((Object)methDef).name;
				break;
			case 2:
				((BaseItemDefinition)val).Name = "Mid-Quality " + ((Object)methDef).name;
				break;
			case 3:
				((BaseItemDefinition)val).Name = "Hi-Quality " + ((Object)methDef).name;
				break;
			default:
				((BaseItemDefinition)val).Name = ((Object)methDef).name;
				break;
			}
			((BaseItemDefinition)val).Description = ((BaseItemDefinition)basePseudoDefinition).Description;
			((StorableItemDefinition)val).StationItem = ((StorableItemDefinition)basePseudoDefinition).StationItem;
			AssignPseudoIcon(val, methDef);
			CustomPseudoIdToLiquidMethId[((BaseItemDefinition)val).ID] = ((BaseItemDefinition)customLiquidMeth).ID;
			return val;
		}

		private void AssignPseudoIcon(QualityItemDefinition clone, MethDefinition methDef)
		{
			if ((Object)(object)SeedVisualsManager.basePseudoSprite == (Object)null)
			{
				return;
			}
			if (!pseudoIconCache.TryGetValue(((BaseItemDefinition)methDef).ID, out var value))
			{
				value = GeneratePseudoIcon(methDef);
				if ((Object)(object)value == (Object)null)
				{
					return;
				}
				pseudoIconCache[((BaseItemDefinition)methDef).ID] = value;
			}
			SeedVisualsManager.seedIcons[((BaseItemDefinition)clone).ID] = value;
			((BaseItemDefinition)clone).Icon = value;
		}

		private Sprite GeneratePseudoIcon(MethDefinition methDef)
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			MethAppearanceSettings appearanceSettings = methDef.AppearanceSettings;
			if (appearanceSettings == null || appearanceSettings.IsUnintialized())
			{
				appearanceSettings = MethDefinition.GetAppearanceSettings(((PropertyItemDefinition)methDef).Properties);
			}
			if (appearanceSettings == null)
			{
				Utility.Error("PseudoFactory: No appearance settings for '" + ((BaseItemDefinition)methDef).ID + "' — keeping base icon.");
				return null;
			}
			try
			{
				(Color top, Color bottom) tuple = SeedVisualsManager.BoostContrastIfSimilar(Color32.op_Implicit(appearanceSettings.MainColor), Color32.op_Implicit(appearanceSettings.SecondaryColor));
				Color item = tuple.top;
				Color item2 = tuple.bottom;
				Sprite val = SeedVisualsManager.GenerateIconWithKeyColorFill(SeedVisualsManager.basePseudoSprite, item, item2);
				if ((Object)(object)val != (Object)null)
				{
					((Object)val).name = ((BaseItemDefinition)methDef).ID + "_pseudo_icon";
				}
				return val;
			}
			catch (Exception e)
			{
				Utility.PrintException(e);
				return SeedVisualsManager.basePseudoSprite;
			}
		}

		private QualityItemDefinition ResolveOrCreateCustomPseudo(QualityItemDefinition basePseudoDefinition, LiquidMethDefinition customLiquidMeth, MethDefinition methDef)
		{
			string text = CustomPseudoManager.BuildPseudoSeedId(((BaseItemDefinition)methDef).ID, ((BaseItemDefinition)basePseudoDefinition).ID);
			QualityItemDefinition item = Registry.GetItem<QualityItemDefinition>(text);
			if ((Object)(object)item != (Object)null)
			{
				CustomPseudoIdToLiquidMethId[((BaseItemDefinition)item).ID] = ((BaseItemDefinition)customLiquidMeth).ID;
				return item;
			}
			QualityItemDefinition val = CloneCustomPseudo(basePseudoDefinition, customLiquidMeth, methDef);
			if ((Object)(object)val != (Object)null)
			{
				Singleton<Registry>.Instance.AddToRegistry((ItemDefinition)(object)val);
			}
			return val;
		}

		private void InjectCustomRecipeInternal(List<QualityItemDefinition> customPseudoVariants, LiquidMethDefinition customLiquidMeth, string methId)
		{
			ChemistryStationInterface instance = Singleton<ChemistryStationInterface>.Instance;
			string text = methId + "_customrecipe";
			Enumerator<StationRecipe> enumerator = instance.Recipes.GetEnumerator();
			while (enumerator.MoveNext())
			{
				StationRecipe current = enumerator.Current;
				if (((Object)current).name == text)
				{
					Utility.Log("PseudoFactory: Recipe '" + text + "' already in canvas — skipping.");
					return;
				}
			}
			StationRecipe val = Object.Instantiate<StationRecipe>(baseStationRecipe);
			((Object)val).name = text;
			val.RecipeTitle = ((BaseItemDefinition)customLiquidMeth).Name ?? "";
			val.Unlocked = true;
			val.IsDiscovered = true;
			QualityItemDefinition val2 = null;
			foreach (QualityItemDefinition customPseudoVariant in customPseudoVariants)
			{
				if ((Object)(object)customPseudoVariant != (Object)null && ((BaseItemDefinition)customPseudoVariant).ID == CustomPseudoManager.BuildPseudoSeedId(methId, "pseudo"))
				{
					val2 = customPseudoVariant;
					break;
				}
			}
			if ((Object)(object)val2 == (Object)null)
			{
				val2 = customPseudoVariants[0];
			}
			Enumerator<IngredientQuantity> enumerator3 = val.Ingredients.GetEnumerator();
			while (enumerator3.MoveNext())
			{
				IngredientQuantity current3 = enumerator3.Current;
				bool flag = false;
				Enumerator<ItemDefinition> enumerator4 = current3.Items.GetEnumerator();
				while (enumerator4.MoveNext())
				{
					ItemDefinition current4 = enumerator4.Current;
					if ((Object)(object)current4 != (Object)null && basePseudoDefinitions.ContainsKey(((BaseItemDefinition)current4).ID))
					{
						flag = true;
						break;
					}
				}
				if (!flag)
				{
					continue;
				}
				current3.Items.Clear();
				current3.Items.Add((ItemDefinition)(object)val2);
				foreach (QualityItemDefinition customPseudoVariant2 in customPseudoVariants)
				{
					if ((Object)(object)customPseudoVariant2 != (Object)null && !current3.Items.Contains((ItemDefinition)(object)customPseudoVariant2))
					{
						current3.Items.Add((ItemDefinition)(object)customPseudoVariant2);
					}
				}
				break;
			}
			val.Product.Item = (ItemDefinition)(object)customLiquidMeth;
			val.Product.Quantity = 1;
			StationRecipeEntry component = ((Component)Object.Instantiate<StationRecipeEntry>(instance.RecipeEntryPrefab, (Transform)(object)instance.RecipeContainer)).GetComponent<StationRecipeEntry>();
			component.AssignRecipe(val);
			instance.Recipes.Add(val);
			instance.recipeEntries.Add(component);
			Utility.Log($"PseudoFactory: Injected recipe '{text}' (Unlocked={val.Unlocked}, IsDiscovered={val.IsDiscovered}) into ChemistryStationInterface.");
		}

		private QualityItemDefinition ResolvePseudoBaseDefinition(string pseudoBaseId)
		{
			QualityItemDefinition value;
			return basePseudoDefinitions.TryGetValue(pseudoBaseId, out value) ? value : null;
		}
	}
	public class SyringeFactory
	{
		private Transform rootGameObject;

		private SporeSyringeDefinition baseSyringeDef;

		private ShroomSpawnDefinition baseSpawnDefinition;

		private ShroomColony baseColonyPrefab;

		private ShroomDefinition baseShroomDef;

		private SpawnChunk baseChunkPrefab;

		public SyringeFactory(SporeSyringeDefinition baseSyringe)
		{
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Expected O, but got Unknown
			baseSyringeDef = baseSyringe;
			baseSpawnDefinition = baseSyringe.SpawnDefinition;
			baseColonyPrefab = baseSpawnDefinition.ColonyPrefab;
			baseShroomDef = baseSpawnDefinition.Shroom;
			baseChunkPrefab = baseSpawnDefinition.ChunkPrefab;
			GameObject val = new GameObject(((BaseItemDefinition)baseSyringeDef).ID + "_CustomSyringes");
			val.SetActive(false);
			Object.DontDestroyOnLoad((Object)(object)val);
			rootGameObject = val.transform;
		}

		public SporeSyringeDefinition CreateSyringeDefinition(ShroomDefinition shroomDef)
		{
			if ((Object)(object)baseSyringeDef == (Object)null)
			{
				throw new InvalidOperationException("Base syringe definition not initialized.");
			}
			SporeSyringeDefinition val = Object.Instantiate<SporeSyringeDefinition>(baseSyringeDef);
			((BaseItemDefinition)val).ID = ((BaseItemDefinition)shroomDef).ID + "_customsyringedefinition";
			((Object)val).name = ((BaseItemDefinition)val).ID;
			((BaseItemDefinition)val).Name = ((Object)shroomDef).name + " Spore Syringe";
			ShroomSpawnDefinition val2 = (val.SpawnDefinition = CloneSpawnDefinition(((BaseItemDefinition)shroomDef).ID, shroomDef));
			Singleton<Registry>.Instance.AddToRegistry((ItemDefinition)(object)val2);
			Utility.Log("Registered ShroomSpawnDefinition: " + ((BaseItemDefinition)val2).ID);
			AssignShroomIcons(val, val2, shroomDef);
			return val;
		}

		private void AssignShroomIcons(SporeSyringeDefinition syringe, ShroomSpawnDefinition spawnDef, ShroomDefinition shroomDef)
		{
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			ShroomAppearanceSettings appearanceSettings = shroomDef.AppearanceSettings;
			if (appearanceSettings == null || appearanceSettings.IsUnintialized())
			{
				appearanceSettings = ShroomDefinition.GetAppearanceSettings(((PropertyItemDefinition)shroomDef).Properties);
			}
			if (appearanceSettings == null)
			{
				Utility.Error("SyringeFactory: No appearance settings for '" + ((BaseItemDefinition)shroomDef).ID + "' — keeping base icons.");
				return;
			}
			var (topColor, bottomColor) = PickMostDistinctPair(appearanceSettings);
			if ((Object)(object)SeedVisualsManager.baseSyringeSprite != (Object)null)
			{
				try
				{
					Sprite val = SeedVisualsManager.GenerateIconWithKeyColorFill(SeedVisualsManager.baseSyringeSprite, topColor, bottomColor);
					if ((Object)(object)val != (Object)null)
					{
						((Object)val).name = ((Object)syringe).name + "_icon";
						SeedVisualsManager.seedIcons[((BaseItemDefinition)syringe).ID] = val;
						((BaseItemDefinition)syringe).Icon = val;
					}
				}
				catch (Exception e)
				{
					((BaseItemDefinition)syringe).Icon = SeedVisualsManager.baseSyringeSprite;
					Utility.PrintException(e);
				}
			}
			if (!((Object)(object)SeedVisualsManager.baseShroomSpawnSprite != (Object)null))
			{
				return;
			}
			try
			{
				Sprite val2 = SeedVisualsManager.GenerateIconWithKeyColorFill(SeedVisualsManager.baseShroomSpawnSprite, topColor, bottomColor);
				if ((Object)(object)val2 != (Object)null)
				{
					((Object)val2).name = ((Object)spawnDef).name + "_icon";
					SeedVisualsManager.seedIcons[((BaseItemDefinition)spawnDef).ID] = val2;
					((BaseItemDefinition)spawnDef).Icon = val2;
				}
			}
			catch (Exception e2)
			{
				((BaseItemDefinition)spawnDef).Icon = SeedVisualsManager.baseShroomSpawnSprite;
				Utility.PrintException(e2);
			}
		}

		private (Color top, Color bottom) PickMostDistinctPair(ShroomAppearanceSettings appearance)
		{
			//IL_0002: 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_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: 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)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: 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_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			Color val = Color32.op_Implicit(appearance.PrimaryColor);
			Color val2 = Color32.op_Implicit(appearance.SecondaryColor);
			if (!appearance.HasSpots)
			{
				return (top: val, bottom: val2);
			}
			Color val3 = Color32.op_Implicit(appearance.SpotsColor);
			float num = SeedVisualsManager.ColorDistanceRgb(val, val2);
			float num2 = SeedVisualsManager.ColorDistanceRgb(val, val3);
			float num3 = SeedVisualsManager.ColorDistanceRgb(val2, val3);
			float num4 = Mathf.Max(num, Mathf.Max(num2, num3));
			if (num4 == num2)
			{
				return (top: val, bottom: val3);
			}
			if (num4 == num3)
			{
				return (top: val2, bottom: val3);
			}
			return (top: val, bottom: val2);
		}

		private ShroomSpawnDefinition CloneSpawnDefinition(string shroomId, ShroomDefinition shroomDef)
		{
			ShroomSpawnDefinition val = Object.Instantiate<ShroomSpawnDefinition>(baseSpawnDefinition);
			((BaseItemDefinition)val).ID = shroomId + "_customspawndefinition";
			((Object)val).name = ((BaseItemDefinition)val).ID;
			((BaseItemDefinition)val).Name = ((Object)shroomDef).name + " Spawn";
			val.Shroom = shroomDef;
			ShroomColony val2 = Object.Instantiate<ShroomColony>(baseColonyPrefab, rootGameObject);
			((Object)((Component)val2).gameObject).name = shroomId + "_Colony";
			val2._spawnDefinition = val;
			val.ColonyPrefab = val2;
			return val;
		}

		public void DeleteChildren()
		{
			TransformExt.DeleteChildren(rootGameObject, true, false);
		}
	}
	[Serializable]
	internal class LegacySeedData
	{
		public string seedId { get; set; }

		public string weedId { get; set; }

		public string baseSeedId { get; set; }

		public float price { get; set; }
	}
	[Serializable]
	internal class LegacyUnicornSeedData
	{
		public string seedId { get; set; }

		public string mixId { get; set; }

		public EDrugType drugType { get; set; }

		public float price { get; set; }
	}
	[Serializable]
	public class VariantSeedData
	{
		public string baseItemId { get; set; }

		public string seedId { get; set; }

		public float price { get; set; }
	}
	[Serializable]
	public class UnicornSeedData
	{
		public string mixId { get; set; }

		public EDrugType drugType { get; set; }

		public List<VariantSeedData> variants { get; set; } = new List<VariantSeedData>();

		[JsonIgnore]
		public string seedId => variants.FirstOrDefault()?.seedId;

		[JsonIgnore]
		public float price => variants.FirstOrDefault()?.price ?? 0f;

		public VariantSeedData GetVariant(string baseItemId)
		{
			return variants.FirstOrDefault((VariantSeedData v) => v.baseItemId == baseItemId);
		}

		public void SetSingleVariant(string baseItemId, string itemSeedId, float variantPrice)
		{
			variants = new List<VariantSeedData>
			{
				new VariantSeedData
				{
					baseItemId = baseItemId,
					seedId = itemSeedId,
					price = variantPrice
				}
			};
		}
	}
	public class SeedFactory
	{
		private Transform rootGameObject;

		private WeedPlant basePlantPrefab;

		private PlantHarvestable baseBranchPrefab;

		private FunctionalSeed baseFunctionalSeedPrefab;

		private Equippable_Seed baseEquippableSeedPrefab;

		private AvatarEquippable baseAvatarEquippablePrefab;

		private StoredItem baseStorableItem;

		public SeedDefinition baseSeedDefinition;

		public SeedFactory(SeedDefinition seedDefinition)
		{
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Expected O, but got Unknown
			baseSeedDefinition = seedDefinition;
			baseFunctionalSeedPrefab = seedDefinition.FunctionSeedPrefab;
			baseStorableItem = ((StorableItemDefinition)seedDefinition).StoredItem;
			InitializeBasePlant(seedDefinition);
			InitializeEquippable(seedDefinition);
			if ((Object)(object)rootGameObject == (Object)null)
			{
				GameObject val = new GameObject(((BaseItemDefinition)baseSeedDefinition).ID + "_CustomSeeds");
				val.SetActive(false);
				Object.DontDestroyOnLoad((Object)(object)val);
				rootGameObject = val.transform;
			}
		}

		private void InitializeBasePlant(SeedDefinition seedDefinition)
		{
			WeedPlant val = ((Il2CppObjectBase)seedDefinition.PlantPrefab).TryCast<WeedPlant>();
			if ((Object)(object)val != (Object)null)
			{
				basePlantPrefab = val;
				if ((Object)(object)basePlantPrefab != (Object)null)
				{
					baseBranchPrefab = basePlantPrefab.BranchPrefab;
				}
			}
			else
			{
				Utility.Log("Failed to cast PlantPrefab to WeedPlant.");
			}
		}

		private void InitializeEquippable(SeedDefinition seedDefinition)
		{
			Equippable_Seed val = ((Il2CppObjectBase)((ItemDefinition)seedDefinition).Equippable).TryCast<Equippable_Seed>();
			if ((Object)(object)val != (Object)null)
			{
				baseEquippableSeedPrefab = val;
				baseAvatarEquippablePrefab = ((Equippable_Viewmodel)val).AvatarEquippable;
			}
			else
			{
				Utility.Log("Failed to cast Equippable to Equippable_Seed.");
			}
		}

		public void DeleteChildren()
		{
			TransformExt.DeleteChildren(rootGameObject, true, false);
		}

		private void GrowLabel(Transform root, string seedDefId)
		{
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			Transform val = null;
			Il2CppArrayBase<Transform> componentsInChildren = ((Component)root).GetComponentsInChildren<Transform>();
			foreach (Transform item in componentsInChildren)
			{
				if (((Object)item).name == "Label")
				{
					val = ((Component)item).transform;
				}
			}
			if ((Object)(object)val != (Object)null)
			{
				val.localScale = new Vector3(1.05f, 1.05f, 2f);
				val.position = new Vector3(0f, -0.05f, 0f);
				if ((Object)(object)SeedVisualsManager.customMat == (Object)null)
				{
					SeedVisualsManager.LoadSeedMaterial();
				}
				if ((Object)(object)SeedVisualsManager.customMat != (Object)null)
				{
					Renderer component = ((Component)val).GetComponent<Renderer>();
					component.material = SeedVisualsManager.customMat;
					((Component)val).gameObject.AddComponent<SeedVialLabel>();
					((Object)val).name = ((Object)val).name + ":" + seedDefId;
				}
				else
				{
					Utility.Log("MATERIAL NOT LOADED!!!");
				}
			}
		}

		public WeedPlant ClonePlantPrefab(WeedDefinition newDef)
		{
			if ((Object)(object)basePlantPrefab == (Object)null)
			{
				throw new InvalidOperationException("Base plant prefab not initialized.");
			}
			WeedPlant val = Object.Instantiate<WeedPlant>(basePlantPrefab, rootGameObject);
			SetPlantAppearance(newDef, val);
			PlantHarvestable val2 = CloneBranchPrefab(newDef);
			SetBranchAppearance(((Component)val2).transform, newDef);
			val.BranchPrefab = val2;
			Il2CppArrayBase<PlantHarvestable> componentsInChildren = ((Component)val).GetComponentsInChildren<PlantHarvestable>();
			foreach (PlantHarvestable item in componentsInChildren)
			{
				item.Product = (StorableItemDefinition)(object)newDef;
			}
			return val;
		}

		public void SetPlantAppearance(WeedDefinition newDef, WeedPlant plant)
		{
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: 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_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)
			foreach (PlantGrowthStage item in (Il2CppArrayBase<PlantGrowthStage>)(object)((Plant)plant).GrowthStages)
			{
				WeedAppearanceSettings val = newDef.appearance;
				if (val == null)
				{
					val = WeedDefinition.GetAppearanceSettings(((PropertyItemDefinition)newDef).Properties);
				}
				if ((Object)(object)item != (Object)null && val != null)
				{
					for (int i = 0; i < ((Component)item).transform.childCount; i++)
					{
						Transform child = ((Component)item).transform.GetChild(i);
						if ((Object)(object)child == (Object)null)
						{
							continue;
						}
						MeshRenderer component = ((Component)child).GetComponent<MeshRenderer>();
						if ((Object)(object)component == (Object)null)
						{
							continue;
						}
						Material material = ((Renderer)component).material;
						if ((Object)(object)material == (Object)null)
						{
							continue;
						}
						if (((Object)child).name == "Stem")
						{
							material.color = Color32.op_Implicit(val.StemColor);
						}
						if (((Object)child).name == "BigLeaves")
						{
							material.color = Color32.op_Implicit(val.LeafColor);
						}
						if (((Object)child).name == "SmallLeaves")
						{
							material.color = Color32.op_Implicit(val.LeafColor);
						}
						foreach (Transform item2 in (Il2CppArrayBase<Transform>)(object)item.GrowthSites)
						{
							if ((Object)(object)item2 != (Object)null)
							{
								Transform child2 = item2.GetChild(0);
								if (Object.op_Implicit((Object)(object)child2))
								{
									SetBranchAppearance(child2, val);
								}
							}
						}
					}
				}
				else
				{
					Utility.Error("Plant Stage is NULL! Thats impossible");
				}
			}
		}

		public void SetBranchAppearance(Transform branchTransform, WeedDefinition weedDef)
		{
			WeedAppearanceSettings val = weedDef.appearance;
			if (val == null)
			{
				val = WeedDefinition.GetAppearanceSettings(((PropertyItemDefinition)weedDef).Properties);
			}
			if (val != null && (Object)(object)branchTransform != (Object)null)
			{
				SetBranchAppearance(branchTransform, val);
			}
		}

		public void SetBranchAppearance(Transform branchTransform, WeedAppearanceSettings weedAppearance)
		{
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			Transform child = branchTransform.GetChild(0);
			Transform val = ((child != null) ? child.GetChild(0) : null);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			for (int i = 0; i < val.childCount; i++)
			{
				Transform child2 = val.GetChild(i);
				if ((Object)(object)child2 == (Object)null)
				{
					continue;
				}
				MeshRenderer component = ((Component)child2).GetComponent<MeshRenderer>();
				if ((Object)(object)component == (Object)null)
				{
					continue;
				}
				Material material = ((Renderer)component).material;
				if (!((Object)(object)material == (Object)null))
				{
					if (((Object)child2).name == "Stem")
					{
						material.color = Color32.op_Implicit(weedAppearance.StemColor);
					}
					if (((Object)child2).name == "Leaves")
					{
						material.color = Color32.op_Implicit(weedAppearance.LeafColor);
					}
					if (((Object)child2).name == "Main")
					{
						material.color = Color32.op_Implicit(weedAppearance.MainColor);
					}
					if (((Object)child2).name == "Secondary")
					{
						material.color = Color32.op_Implicit(weedAppearance.SecondaryColor);
					}
				}
			}
		}

		public PlantHarvestable CloneBranchPrefab(WeedDefinition newDef)
		{
			if ((Object)(object)baseBranchPrefab == (Object)null)
			{
				throw new InvalidOperationException("Base branch prefab not initialized.");
			}
			PlantHarvestable val = Object.Instantiate<PlantHarvestable>(baseBranchPrefab, rootGameObject);
			((Object)((Component)val).gameObject).name = ((BaseItemDefinition)newDef).ID + "_Harvestable";
			((Component)val).gameObject.layer = ((Component)baseBranchPrefab).gameObject.layer;
			val.Product = (StorableItemDefinition)(object)newDef;
			return val;
		}

		public FunctionalSeed CloneFunctionalSeedPrefab(string seedDefId)
		{
			if ((Object)(object)baseFunctionalSeedPrefab == (Object)null)
			{
				throw new InvalidOperationException("Base functional seed prefab not initialized.");
			}
			FunctionalSeed val = Object.Instantiate<FunctionalSeed>(baseFunctionalSeedPrefab, rootGameObject);
			GrowLabel(((Component)val).transform, seedDefId);
			return val;
		}

		public Equippable_Seed CloneEquippableSeedPrefab(SeedDefinition newDef, WeedAppearanceSettings weedAppearance)
		{
			if ((Object)(object)baseEquippableSeedPrefab == (Object)null)
			{
				throw new InvalidOperationException("Base equippable seed prefab not initialized.");
			}
			Equippable_Seed val = Object.Instantiate<Equippable_Seed>(baseEquippableSeedPrefab, rootGameObject);
			GrowLabel(((Component)val).transform, ((BaseItemDefinition)newDef).ID);
			((Object)((Component)val).gameObject).name = ((BaseItemDefinition)newDef).ID + "_Equippable";
			((Component)val).gameObject.layer = ((Component)baseEquippableSeedPrefab).gameObject.layer;
			val.Seed = newDef;
			((Equippable_Viewmodel)val).AvatarEquippable = CloneAvatarEquippablePrefab(((BaseItemDefinition)newDef).ID);
			((Object)((Equippable_Viewmodel)val).AvatarEquippable).name = ((BaseItemDefinition)newDef).ID + "_AvatarEquippable";
			return val;
		}

		public AvatarEquippable CloneAvatarEquippablePrefab(string newDefId)
		{
			if ((Object)(object)baseAvatarEquippablePrefab == (Object)null)
			{
				throw new InvalidOperationException("Base avatar equippable prefab not initialized.");
			}
			AvatarEquippable val = Object.Instantiate<AvatarEquippable>(baseAvatarEquippablePrefab, rootGameObject);
			GrowLabel(((Component)val).transform, newDefId);
			return val;
		}

		public StoredItem CloneStoredItem(string newDefId)
		{
			if ((Object)(object)baseStorableItem == (Object)null)
			{
				throw new InvalidOperationException("Base Stored Item not initialized.");
			}
			StoredItem val = Object.Instantiate<StoredItem>(baseStorableItem, rootGameObject);
			GrowLabel(((Component)val).transform, newDefId);
			return val;
		}

		public SeedDefinition CreateSeedDefinition(WeedDefinition weedDef)
		{
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)baseSeedDefinition == (Object)null)
			{
				throw new InvalidOperationException("Base seed definition not initialized.");
			}
			SeedDefinition val = Object.Instantiate<SeedDefinition>(baseSeedDefinition);
			WeedAppearanceSettings val2 = weedDef.appearance;
			if (val2 == null)
			{
				val2 = WeedDefinition.GetAppearanceSettings(((PropertyItemDefinition)weedDef).Properties);
			}
			((Object)val).name = ((BaseItemDefinition)weedDef).ID + "_customseeddefinition";
			((BaseItemDefinition)val).ID = ((BaseItemDefinition)weedDef).ID + "_customseeddefinition";
			((BaseItemDefinition)val).Name = ((Object)weedDef).name + " Seed";
			((BaseItemDefinition)val).Description = ((Object)weedDef).name + " Seed";
			((BaseItemDefinition)val).Icon = ((BaseItemDefinition)baseSeedDefinition).Icon;
			SeedVisualsManager.weedAppearanceMap[((BaseItemDefinition)val).ID] = val2;
			((ItemDefinition)val).Equippable = (Equippable)(object)CloneEquippableSeedPrefab(val, val2);
			val.PlantPrefab = (Plant)(object)ClonePlantPrefab(weedDef);
			val.PlantPrefab.SeedDefinition = val;
			val.FunctionSeedPrefab = CloneFunctionalSeedPrefab(((BaseItemDefinition)val).ID);
			((Object)val.FunctionSeedPrefab).name = ((BaseItemDefinition)weedDef).ID + "Seed_Functional";
			((StorableItemDefinition)val).StoredItem = CloneStoredItem(((BaseItemDefinition)val).ID);
			if ((Object)(object)SeedVisualsManager.baseSeedSprite != (Object)null)
			{
				try
				{
					Sprite val3 = SeedVisualsManager.GenerateIconWithKeyColorFill(SeedVisualsManager.baseSeedSprite, Color32.op_Implicit(val2.MainColor), Color32.op_Implicit(val2.SecondaryColor));
					((Object)val3).name = ((Object)val).name + "_icon";
					SeedVisualsManager.seedIcons.Add(((BaseItemDefinition)val).ID, val3);
					((BaseItemDefinition)val).Icon = val3;
				}
				catch (Exception e)
				{
					((BaseItemDefinition)val).Icon = SeedVisualsManager.baseSeedSprite;
					Utility.PrintException(e);
				}
			}
			return val;
		}
	}
	[RegisterTypeInIl2Cpp]
	public class SeedVialLabel : MonoBehaviour
	{
		private Renderer rend;

		private MaterialPropertyBlock block;

		public Color colorA;

		public Color colorB;

		public bool useRandomColors = false;

		private void Start()
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			if (useRandomColors)
			{
				colorA = Random.ColorHSV();
				colorB = Random.ColorHSV();
			}
			rend = ((Component)this).GetComponent<Renderer>();
			block = new MaterialPropertyBlock();
			SetupLabel();
		}

		public void SetupLabel()
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)rend == (Object)null)
			{
				return;
			}
			MeshFilter component = ((Component)this).GetComponent<MeshFilter>();
			if (!((Object)(object)component == (Object)null))
			{
				string text = ((Object)this).name.Split(':')[1];
				if (SeedVisualsManager.TryGetLabelColors(text, out var main, out var secondary))
				{
					colorA = main;
					colorB = secondary;
				}
				else if (!useRandomColors)
				{
					Utility.Error("SeedVialLabel: no appearance registered for '" + text + "' — leaving the label uncoloured.");
					return;
				}
				Bounds bounds = component.sharedMesh.bounds;
				rend.GetPropertyBlock(block);
				block.SetColor("_ColorA", colorA);
				block.SetColor("_ColorB", colorB);
				block.SetFloat("_MinZ", ((Bounds)(ref bounds)).min.z);
				block.SetFloat("_MaxZ", ((Bounds)(ref bounds)).max.z);
				rend.SetPropertyBlock(block);
			}
		}
	}
}
namespace UnicornsCustomSeeds.SeedQuests
{
	public abstract class CustomSynthesisQuest : Quest
	{
		[SaveableField("SynthesisQuestData")]
		private CustomSynthesisQuestData _data = new CustomSynthesisQuestData();

		public QuestEntry dropoffEntry;

		protected abstract string NpcName { get; }

		protected abstract string ItemName { get; }

		protected abstract SupplierStash Stash { get; }

		protected override string Description => $"Take {StashManager.StashQtyEntry.Value}x of your {ItemName} and ${StashManager.StashCostEntry.Value} to {NpcName}'s supply stash";

		public void SetDrugType(EDrugType drugType)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			_data.drugType = drugType;
		}

		protected override void OnCreated()
		{
			if (base.QuestEntries.Count == 0)
			{
				AddDropoffEntry();
			}
		}

		protected override void OnLoaded()
		{
			if (base.QuestEntries.Count == 0)
			{
				AddDropoffEntry();
			}
		}

		private void AddDropoffEntry()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			SupplierStash stash = Stash;
			Vector3 value = (((Object)(object)stash != (Object)null) ? ((Component)stash).transform.position : Vector3.zero);
			dropoffEntry = ((Quest)this).AddEntry($"Give {NpcName} {StashManager.StashQtyEntry.Value}x of a {ItemName} and ${StashManager.StashCostEntry.Value}", (Vector3?)value);
			Utility.Log($"[{((object)this).GetType().Name}] dropoff entry added (npc={NpcName}, stash={(((Object)(object)stash != (Object)null) ? "found" : "null")}).");
		}
	}
	[Serializable]
	public class CustomSynthesisQuestData
	{
		public EDrugType drugType { get; set; } = (EDrugType)0;
	}
	public class WeedSynthesisQuest : CustomSynthesisQuest
	{
		protected override string Title => "Drop off the Mix";

		protected override string NpcName => "Albert";

		protected override string ItemName => "weed mix";

		protected override SupplierStash Stash => StashManager.GetSupplierStash();

		protected override Sprite QuestIcon => SeedVisualsManager.weedQuestIconSprite ?? SeedVisualsManager.baseQuestIconSprite;
	}
	public class ShroomSynthesisQuest : CustomSynthesisQuest
	{
		protected override string Title => "Drop off the Shroom Mix";

		protected override string NpcName => "Phil";

		protected override string ItemName => "shroom mix";

		protected override SupplierStash Stash => PhilStashManager.GetSupplierStash();

		protected override Sprite QuestIcon => SeedVisualsManager.shroomQuestIconSprite ?? SeedVisualsManager.baseQuestIconSprite;
	}
	public class CocaSynthesisQuest : CustomSynthesisQuest
	{
		protected override string Title => "Drop off the Cocaine Mix";

		protected override string NpcName => "Salvador";

		protected override string ItemName => "cocaine mix";

		protected override SupplierStash Stash => SalvadorStashManager.GetSupplierStash();

		protected override Sprite QuestIcon => SeedVisualsManager.cocaineQuestIconSprite ?? SeedVisualsManager.baseQuestIconSprite;
	}
	public class PseudoSynthesisQuest : CustomSynthesisQuest
	{
		protected override string Title => "Drop off the Meth Mix";

		protected override string NpcName => "Shirley";

		protected override string ItemName => "meth mix";

		protected override SupplierStash Stash => ShirleyStashManager.GetSupplierStash();

		protected override Sprite QuestIcon => SeedVisualsManager.methQuestIconSprite ?? SeedVisualsManager.baseQuestIconSprite;
	}
}
namespace UnicornsCustomSeeds.Patches
{
	public static class CauldronBaseSwap
	{
		public static readonly Dictionary<Cauldron, QualityItemDefinition> OriginalBase = new Dictionary<Cauldron, QualityItemDefinition>();
	}
	[HarmonyPatch(typeof(Cauldron), "Start")]
	public class CauldronStartPatch
	{
		[HarmonyPostfix]
		public static void Postfix(Cauldron __instance)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			if (((BuildableItem)__instance).isGhost)
			{
				return;
			}
			try
			{
				Cauldron cauldron = __instance;
				cauldron.onCookEnd.AddListener(UnityAction.op_Implicit((Action)delegate
				{
					//IL_003e: Unknown result type (might be due to invalid IL or missing references)
					//IL_0043: Unknown result type (might be due to invalid IL or missing references)
					try
					{
						if (CauldronBaseSwap.OriginalBase.TryGetValue(cauldron, out var value))
						{
							cauldron.CocaineBaseDefinition = value;
							CauldronBaseSwap.OriginalBase.Remove(cauldron);
						}
						string text2 = ((object)((BuildableItem)cauldron).GUID/*cast due to .constrained prefix*/).ToString();
						if (ActiveCookingRegistry.GuidToMixId.ContainsKey(text2))
						{
							ActiveCookingRegistry.Unregister(text2);
						}
					}
					catch (Exception e2)
					{
						Utility.PrintException(e2);
					}
				}));
				string stationGuid = ((object)((BuildableItem)__instance).GUID/*cast due to .constrained prefix*/).ToString();
				string mixId = ActiveCookingRegistry.GetMixId(stationGuid);
				if (mixId == null)
				{
					return;
				}
				string text = mixId + "_customcocainebase";
				ItemDefinition item = Registry.GetItem(text);
				QualityItemDefinition val = ((item != null) ? ((Il2CppObjectBase)item).TryCast<QualityItemDefinition>() : null);
				if ((Object)(object)val == (Object)null)
				{
					Utility.Error("CauldronStartPatch: Could not resolve '" + text + "' — cauldron will finish with vanilla base.");
					return;
				}
				if (!CauldronBaseSwap.OriginalBase.ContainsKey(__instance))
				{
					CauldronBaseSwap.OriginalBase[__instance] = __instance.CocaineBaseDefinition;
				}
				__instance.CocaineBaseDefinition = val;
			}
			catch (Exception e)
			{
				Utility.PrintException(e);
			}
		}
	}
	[HarmonyPatch(typeof(Cauldron), "RemoveIngredients")]
	public static class Patch_Cauldron_RemoveIngredients
	{
		private static bool Prefix(Cauldron __instance, ref EQuality __result)
		{
			//IL_02b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0220: Unknown result type (might be due to invalid IL or missing references)
			//IL_0225: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bb: Expected I4, but got Unknown
			//IL_024b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0250: Unknown result type (might be due to invalid IL or missing references)
			//IL_035c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0361: Unknown result type (might be due to invalid IL or missing references)
			//IL_0370: Unknown result type (might be due to invalid IL or missing references)
			//IL_0375: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				List<string> list = new List<string>();
				Dictionary<string, int> dictionary = new Dictionary<string, int>();
				for (int i = 0; i < ((Il2CppArrayBase<ItemSlot>)(object)__instance.IngredientSlots).Length; i++)
				{
					ItemSlot val = ((Il2CppArrayBase<ItemSlot>)(object)__instance.IngredientSlots)[i];
					if (((val != null) ? val.ItemInstance : null) != null && val.Quantity > 0)
					{
						string iD = ((BaseItemInstance)val.ItemInstance).ID;
						if (!dictionary.ContainsKey(iD))
						{
							list.Add(iD);
							dictionary[iD] = 0;
						}
						dictionary[iD] += val.Quantity;
					}
				}
				if (list.Count == 0)
				{
					Utility.Error("CauldronPatches: RemoveIngredients called with empty slots.");
					return true;
				}
				string text;
				if (list.Count == 1)
				{
					text = list[0];
				}
				else
				{
					int num = 0;
					foreach (KeyValuePair<string, int> item2 in dictionary)
					{
						if (item2.Value > num)
						{
							num = item2.Value;
						}
					}
					text = null;
					foreach (string item3 in list)
					{
						if (dictionary[item3] == num)
						{
							text = item3;
							break;
						}
					}
				}
				QualityItemDefinition value3;
				if (CocaFactory.CustomLeafIdToBaseId.TryGetValue(text, out var value))
				{
					ItemDefinition item = Registry.GetItem(value);
					QualityItemDefinition val2 = ((item != null) ? ((Il2CppObjectBase)item).TryCast<QualityItemDefinition>() : null);
					if ((Object)(object)val2 != (Object)null)
					{
						if (!CauldronBaseSwap.OriginalBase.ContainsKey(__instance))
						{
							CauldronBaseSwap.OriginalBase[__instance] = __instance.CocaineBaseDefinition;
						}
						__instance.CocaineBaseDefinition = val2;
						if (CocaFactory.CustomBaseIdToMixId.TryGetValue(value, out var value2))
						{
							ActiveCookingRegistry.Register(((object)((BuildableItem)__instance).GUID/*cast due to .constrained prefix*/).ToString(), value2);
							if (!InstanceFinder.IsServer)
							{
								NetworkSyncManager.BroadcastCauldronCook(((object)((BuildableItem)__instance).GUID/*cast due to .constrained prefix*/).ToString(), value2);
							}
						}
					}
					else
					{
						Utility.Error("CauldronPatches: Could not resolve '" + value + "' as QualityItemDefinition — vanilla base will be used.");
					}
				}
				else if (CauldronBaseSwap.OriginalBase.TryGetValue(__instance, out value3))
				{
					__instance.CocaineBaseDefinition = value3;
					CauldronBaseSwap.OriginalBase.Remove(__instance);
					ActiveCookingRegistry.Unregister(((object)((BuildableItem)__instance).GUID/*cast due to .constrained prefix*/).ToString());
				}
				__instance.LiquidSlot.ChangeQuantity(-1, false);
				EQuality val3 = (EQuality)4;
				int num2 = 20;
				int num3 = ((Il2CppArrayBase<ItemSlot>)(object)__instance.IngredientSlots).Length - 1;
				while (num3 >= 0 && num2 > 0)
				{
					ItemSlot val4 = ((Il2CppArrayBase<ItemSlot>)(object)__instance.IngredientSlots)[num3];
					if (((val4 != null) ? val4.ItemInstance : null) != null && val4.Quantity > 0 && !(((BaseItemInstance)val4.ItemInstance).ID != text))
					{
						QualityItemInstance val5 = ((Il2CppObjectBase)val4.ItemInstance).TryCast<QualityItemInstance>();
						if (val5 != null && val5.Quality < val3)
						{
							val3 = val5.Quality;
						}
						int num4 = Mathf.Min(num2, val4.Quantity);
						val4.ChangeQuantity(-num4, false);
						num2 -= num4;
					}
					num3--;
				}
				__result = (EQuality)(int)val3;
				return false;
			}
			catch (Exception e)
			{
				Utility.PrintException(e);
				return true;
			}
		}
	}
	[HarmonyPatch(typeof(Cauldron), "RpcLogic___FinishCookOperation_2166136261")]
	public static class Patch_Cauldron_FinishCookOperation
	{
		public static void Postfix(Cauldron __instance)
		{
			Utility.Log("CauldronPatches: RpcLogic___FinishCookOperation fired on '" + ((Object)__instance).name + "' — cleanup handled by onCookEnd listener.");
		}
	}
	[HarmonyPatch(typeof(ItemSerializers), "ReadItemInstance")]
	public static class ItemStreamGuard
	{
		private static int rescued;

		private const string CustomSeedsManagerBaseSeedId = "ogkushseed";

		public static int RescuedCount => rescued;

		public static string LastSkippedId { get; private set; }

		public static ItemInstance LastSkippedStandIn { get; private set; }

		public static int LastSkippedQuantity { get; private set; }

		public static void ClearLastSkipped()
		{
			LastSkippedId = null;
			LastSkippedStandIn = null;
			LastSkippedQuantity = 0;
		}

		public static bool Prefix(Reader reader, ref ItemInstance __result)
		{
			int position = reader.Position;
			string text;
			try
			{
				text = reader.ReadString();
			}
			catch (Exception)
			{
				reader.Position = position;
				return true;
			}
			if (string.IsNullOrEmpty(text) || Registry.ItemExists(text))
			{
				reader.Position = position;
				return true;
			}
			try
			{
				ClearLastSkipped();
				LastSkippedStandIn = DrainRemainder(reader, text);
				LastSkippedId = text;
				if (LastSkippedStandIn != null)
				{
					LastSkippedQuantity = ((BaseItemInstance)LastSkippedStandIn).Quantity;
				}
				rescued++;
				Utility.Error($"[ITEMGUARD] '{text}' is not registered on this client — slot left empty, stream kept aligned ({rescued} rescued).");
			}
			catch (Exception e)
			{
				Utility.Critical("Unicorns Custom Seeds: could not safely skip the unknown item '" + text + "'. If a player is stuck on the loading screen, this is why.");
				Utility.Error("[ITEMGUARD] drain failed for '" + text + "' — stream may be misaligned.");
				Utility.PrintException(e);
			}
			__result = null;
			return false;
		}

		private static ItemInstance DrainRemainder(Reader reader, string id)
		{
			string text = ResolveBaseId(id);
			if (!string.IsNullOrEmpty(text))
			{
				ItemDefinition item = Registry.GetItem(text);
				if ((Object)(object)item != (Object)null)
				{
					ItemInstance defaultInstance = item.GetDefaultInstance(1);
					if (defaultInstance != null)
					{
						defaultInstance.Read(reader);
						return defaultInstance;
					}
				}
				Utility.Error($"[ITEMGUARD] stand-in '{text}' for '{id}' unavailable — " + "falling back to a plain quantity read.");
			}
			LastSkippedQuantity = reader.ReadUInt16();
			return null;
		}

		private static string ResolveBaseId(string id)
		{
			if (id.EndsWith("_customseeddefinition"))
			{
				return "ogkushseed";
			}
			if (id.EndsWith("_customcocaseed"))
			{
				return "cocaseed";
			}
			if (id.EndsWith("_customcocaleaf"))
			{
				return "cocaleaf";
			}
			if (id.EndsWith("_customcocainebase"))
			{
				return "cocainebase";
			}
			if (id.EndsWith("_customliquidmeth"))
			{
				return "liquidmeth";
			}
			if (id.EndsWith("_customsyringedefinition"))
			{
				return "sporesyringe";
			}
			if (id.EndsWith("_customspawndefinition"))
			{
				return ResolveSpawnBaseId();
			}
			if (id.EndsWith("_custompseudo"))
			{
				string text = id.Substring(0, id.Length - "_custompseudo".Length);
				int num = text.LastIndexOf('_');
				if (num >= 0 && num < text.Length - 1)
				{
					return text.Substring(num + 1);
				}
			}
			return null;
		}

		private static string ResolveSpawnBaseId()
		{
			try
			{
				SporeSyringeDefinition item = Registry.GetItem<SporeSyringeDefinition>("sporesyringe");
				if ((Object)(object)item != (Object)null && (Object)(object)item.SpawnDefinition != (Object)null)
				{
					return ((BaseItemDefinition)item.SpawnDefinition).ID;
				}
			}
			catch (Exception)
			{
			}
			return null;
		}
	}
	internal static class SlotReaderGuard
	{
		private static int pendingSlotIndex = -1;

		public static void Before(PooledReader reader)
		{
			pendingSlotIndex = -1;
			ItemStreamGuard.ClearLastSkipped();
			if (!InstanceFinder.IsClient || InstanceFinder.IsServer || reader == null)
			{
				return;
			}
			int position = ((Reader)reader).Position;
			try
			{
				pendingSlotIndex = ((Reader)reader).ReadInt32((AutoPackType)1);
			}
			catch (Exception)
			{
				pendingSlotIndex = -1;
			}
			finally
			{
				((Reader)reader).Position = position;
			}
		}

		public static void After(string containerName, List<ItemSlot> slots)
		{
			try
			{
				if (pendingSlotIndex >= 0)
				{
					string lastSkippedId = ItemStreamGuard.LastSkippedId;
					if (!string.IsNullOrEmpty(lastSkippedId))
					{
						DeferredSlotsManager.Park(containerName, slots, pendingSlotIndex, lastSkippedId, ItemStreamGuard.LastSkippedQuantity, ItemStreamGuard.LastSkippedStandIn);
					}
				}
			}
			catch (Exception e)
			{
				Utility.PrintException(e);
			}
			finally
			{
				pendingSlotIndex = -1;
				ItemStreamGuard.ClearLastSkipped();
			}
		}
	}
	[HarmonyPatch(typeof(ChemistryStation), "RpcReader___Target_SetStoredInstance_Internal_2652194801")]
	public static class Patch_ChemistryStation_TargetSlotReader
	{
		public static void Prefix(PooledReader PooledReader0)
		{
			SlotReaderGuard.Before(PooledReader0);
		}

		public static void Postfix(ChemistryStation __instance)
		{
			SlotReaderGuard.After(((Object)__instance).name, __instance.ItemSlots);
		}
	}
	[HarmonyPatch(typeof(LabOven), "RpcReader___Target_SetStoredInstance_Internal_2652194801")]
	public static class Patch_LabOven_TargetSlotReader
	{
		public static void Prefix(PooledReader PooledReader0)
		{
			SlotReaderGuard.Before(PooledReader0);
		}

		public static void Postfix(LabOven __instance)
		{
			SlotReaderGuard.After(((Object)__instance).name, __instance.ItemSlots);
		}
	}
	[HarmonyPatch(typeof(MixingStation), "RpcReader___Target_SetStoredInstance_Internal_2652194801")]
	public static class Patch_MixingStation_TargetSlotReader
	{
		public static void Prefix(PooledReader PooledReader0)
		{
			SlotReaderGuard.Before(PooledReader0);
		}

		public static void Postfix(MixingStation __instance)
		{
			SlotReaderGuard.After(((Object)__instance).name, __instance.ItemSlots);
		}
	}
	[HarmonyPatch(typeof(StorageEntity), "RpcReader___Target_SetStoredInstance_Internal_2652194801")]
	public static class Patch_StorageEntity_TargetSlotReader
	{
		public static void Prefix(PooledReader PooledReader0)
		{
			SlotReaderGuard.Before(PooledReader0);
		}

		public static void Postfix(StorageEntity __instance)
		{
			SlotReaderGuard.After(((Object)__instance).name, __instance.ItemSlots);
		}
	}
	[HarmonyPatch(typeof(Cauldron), "RpcReader___Target_SetStoredInstance_Internal_2652194801")]
	public static class Patch_Cauldron_TargetSlotReader
	{
		public static void Prefix(PooledReader PooledReader0)
		{
			SlotReaderGuard.Before(PooledReader0);
		}

		public static void Postfix(Cauldron __instance)
		{
			SlotReaderGuard.After(((Object)__instance).name, __instance.ItemSlots);
		}
	}
	[HarmonyPatch(typeof(NPCInventory), "RpcReader___Target_SetStoredInstance_Internal_2652194801")]
	public static class Patch_NPCInventory_TargetSlotReader
	{
		public static void Prefix(PooledReader PooledReader0)
		{
			SlotReaderGuard.Before(PooledReader0);
		}

		public static void Postfix(NPCInventory __instance)
		{
			SlotReaderGuard.After(((Object)__instance).name, __instance.ItemSlots);
		}
	}
	[HarmonyPatch(typeof(DryingRack), "RpcReader___Target_SetStoredInstance_Internal_2652194801")]
	public static class Patch_DryingRack_TargetSlotReader
	{
		public static void Prefix(PooledReader PooledReader0)
		{
			SlotReaderGuard.Before(PooledReader0);
		}

		public static void Postfix(DryingRack __instance)
		{
			SlotReaderGuard.After(((Object)__instance).name, __instance.ItemSlots);
		}
	}
	[HarmonyPatch(typeof(MushroomSpawnStation), "RpcReader___Target_SetStoredInstance_Internal_2652194801")]
	public static class Patch_MushroomSpawnStation_TargetSlotReader
	{
		public static void Prefix(PooledReader PooledReader0)
		{
			SlotReaderGuard.Before(PooledReader0);
		}

		public static void Postfix(MushroomSpawnStation __instance)
		{
			SlotReaderGuard.After(((Object)__instance).name, __instance.ItemSlots);
		}
	}
	[HarmonyPatch(typeof(ChemistryStation), "RpcLogic___SetCookOperation_1024887225")]
	public static class Patch_ChemistryStation_SetCookOperation
	{
		public static bool Prefix(ChemistryStation __instance, NetworkConnection conn, ChemistryCookOperation operation)
		{
			try
			{
				if (DeferredCookOpsManager.IsReplaying)
				{
					return true;
				}
				if (!InstanceFinder.IsClient || InstanceFinder.IsServer)
				{
					return true;
				}
				if (operation == null)
				{
					return true;
				}
				if (DeferredCookOpsManager.IsChemistryOpReady(operation))
				{
					return true;
				}
				DeferredCookOpsManager.ParkChemistry(__instance, operation);
				return false;
			}
			catch (Exception e)
			{
				Utility.PrintException(e);
				return false;
			}
		}

		public static Exception Finalizer(Exception __exception, ChemistryStation __instance, ChemistryCookOperation operation)
		{
			if (__exception == null)
			{
				return null;
			}
			bool flag = !InstanceFinder.IsClient || InstanceFinder.IsServer;
			DeferredCookOpsManager.HandleChemistryFailure(__instance, operation, __exception, !flag);
			return null;
		}
	}
	[HarmonyPatch(typeof(LabOven), "RpcLogic___SetCookOperation_2611294368")]
	public static class Patch_LabOven_SetCookOperation
	{
		public static bool Prefix(LabOven __instance, NetworkConnection conn, OvenCookOperation operation, bool playButtonPress)
		{
			try
			{
				if (DeferredCookOpsManager.IsReplaying)
				{
					return true;
				}
				if (!InstanceFinder.IsClient || InstanceFinder.IsServer)
				{
					return true;
				}
				if (operation == null)
				{
					return true;
				}
				if (DeferredCookOpsManager.IsOvenOpReady(operation))
				{
					return true;
				}
				DeferredCookOpsManager.ParkOven(__instance, operation, playButtonPress);
				return false;
			}
			catch (Exception e)
			{
				Utility.PrintException(e);
				return false;
			}
		}

		public static Exception Finalizer(Exception __exception, LabOven __instance, OvenCookOperation operation, bool playButtonPress)
		{
			if (__exception == null)
			{
				return null;
			}
			bool flag = !InstanceFinder.IsClient || InstanceFinder.IsServer;
			DeferredCookOpsManager.HandleOvenFailure(__instance, operation, playButtonPress, __exception, !flag);
			return null;
		}
	}
	[HarmonyPatch(typeof(Cauldron), "OnSpawnServer")]
	public static class Patch_Cauldron_OnSpawnServer
	{
		public static void Postfix(Cauldron __instance, NetworkConnection connection)
		{
			try
			{
				if (connection == (NetworkConnection)null || !InstanceFinder.IsServer || connection.IsHost || __instance.ItemSlot