Some mods target the Mono version of the game, which is available by opting into the Steam beta branch "alternate"
Decompiled source of UnicornsCustomSeeds v2.0.0
UnicornsCustomSeeds_Mono_2.0.0.dll
Decompiled a week ago
The result has been truncated due to the large size, download it to view full contents!
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
The result has been truncated due to the large size, download it to view full contents!
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