Some mods target the Mono version of the game, which is available by opting into the Steam beta branch "alternate"
Decompiled source of NoLazyWorkers Il2Cpp v1.1.10
Mods/NoLazyWorkers_Standard.dll
Decompiled 2 months 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 Il2CppFishNet; using Il2CppFishNet.Connection; using Il2CppFishNet.Object; using Il2CppInterop.Runtime; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppNewtonsoft.Json; using Il2CppNewtonsoft.Json.Linq; using Il2CppScheduleOne.AvatarFramework; using Il2CppScheduleOne.DevUtilities; using Il2CppScheduleOne.Employees; using Il2CppScheduleOne.EntityFramework; using Il2CppScheduleOne.ItemFramework; using Il2CppScheduleOne.Management; using Il2CppScheduleOne.Management.SetterScreens; using Il2CppScheduleOne.Management.UI; using Il2CppScheduleOne.NPCs; using Il2CppScheduleOne.NPCs.Behaviour; using Il2CppScheduleOne.ObjectScripts; using Il2CppScheduleOne.Persistence; using Il2CppScheduleOne.Persistence.Datas; using Il2CppScheduleOne.Persistence.Loaders; using Il2CppScheduleOne.Product; using Il2CppScheduleOne.Quests; using Il2CppScheduleOne.UI.Management; using Il2CppSystem; using Il2CppSystem.Collections; using Il2CppSystem.Collections.Generic; using Il2CppTMPro; using MelonLoader; using MelonLoader.Utils; using Microsoft.CodeAnalysis; using NoLazyWorkers_IL2CPP; using NoLazyWorkers_IL2CPP.Botanists; using NoLazyWorkers_IL2CPP.Chemists; using NoLazyWorkers_IL2CPP.Settings; 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(NoLazyWorkersMod), "NoLazyWorkers_IL2CPP", "1.1.10", "Archie", null)] [assembly: MelonGame("TVGS", "Schedule I")] [assembly: HarmonyDontPatchAll] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: AssemblyCompany("NoLazyWorkers_IL2CPP")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+acd61ce48ea7a60ef2b5cdb684c5474ab047fa81")] [assembly: AssemblyProduct("NoLazyWorkers_IL2CPP")] [assembly: AssemblyTitle("NoLazyWorkers_IL2CPP")] [assembly: NeutralResourcesLanguage("en-US")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace NoLazyWorkers_IL2CPP { public static class DebugLogs { public static bool All; public static bool Core; public static bool Settings; public static bool Pot; public static bool MixingStation; public static bool Storage; public static bool Chemist; public static bool Botanist; public static bool Packager; public static bool Stacktrace; } public static class BuildInfo { public const string Name = "NoLazyWorkers_IL2CPP"; public const string Description = "Botanist's supply is moved to each pot and a supply is added to mixing stations. Botanists and Chemists will get items from their station's supply. Mixing Stations can have multiple recipes that loop the output. Multiple employee-related configurable settings."; public const string Author = "Archie"; public const string Version = "1.1.10"; } public class NoLazyWorkersMod : MelonMod { public static NoLazyWorkersMod Instance { get; private set; } public Default Config { get; private set; } public override void OnInitializeMelon() { try { ((MelonBase)this).HarmonyInstance.PatchAll(); MelonLogger.Msg("NoLazyWorkers_Standard loaded!"); MelonLogger.Warning("====================================================="); MelonLogger.Warning(" Please ignore the initial yellow errors "); MelonLogger.Warning("====================================================="); } catch (Exception value) { MelonLogger.Error($"Failed to initialize NoLazyWorkers_Standard: {value}"); } Instance = this; string text = Path.Combine(MelonEnvironment.UserDataDirectory, "NoLazyWorkers.cfg"); if (File.Exists(text)) { Config = Default.LoadFromFile(text); if (DebugLogs.All || DebugLogs.Core) { MelonLogger.Msg("Config loaded."); } } else { Config = new Default(); Config.SaveToFile(text); if (DebugLogs.All || DebugLogs.Core) { MelonLogger.Msg("Default config created."); } } ((MelonEventBase<LemonAction<int, string>>)(object)MelonEvents.OnSceneWasLoaded).Subscribe((LemonAction<int, string>)((MelonMod)this).OnSceneWasLoaded, 0, false); } public override void OnSceneWasLoaded(int buildIndex, string sceneName) { if (sceneName == "Main") { Configure configure = new Configure(); MelonCoroutines.Start(configure.ApplyOneShotSettingsRoutine()); if (DebugLogs.All || DebugLogs.Core) { MelonLogger.Msg("Applied Fixer and Misc settings on main scene load."); } MixingStationExtensions.InitializeStaticRouteListTemplate(); } } public override void OnSceneWasUnloaded(int buildIndex, string sceneName) { ConfigurationExtensions.NPCSupply.Clear(); SettingsExtensions.Configured.Clear(); if (DebugLogs.All || DebugLogs.Core) { MelonLogger.Msg("Cleared ConfigurationExtensions and SettingsExtensions on scene unload."); } } } public static class ConfigurationExtensions { public static Dictionary<Guid, ObjectField> NPCSupply = new Dictionary<Guid, ObjectField>(); private static readonly Dictionary<EntityConfiguration, float> lastInvokeTimes = new Dictionary<EntityConfiguration, float>(); private static readonly float debounceTime = 0.2f; public static void InvokeChanged(EntityConfiguration config) { try { if (config == null) { MelonLogger.Error("InvokeChanged: EntityConfiguration is null"); return; } float time = Time.time; if (lastInvokeTimes.TryGetValue(config, out var value) && time - value < debounceTime) { if (DebugLogs.All || DebugLogs.Core) { MelonLogger.Msg($"InvokeChanged debounced for config: {config}"); } return; } lastInvokeTimes[config] = time; if (DebugLogs.Stacktrace) { MelonLogger.Msg($"InvokeChanged called for config: {config}, StackTrace: {new StackTrace()}"); } config.InvokeChanged(); } catch (Exception value2) { MelonLogger.Error($"InvokeChanged failed: {value2}"); } } } public static class NoLazyUtilities { public static List<T> ConvertList<T>(List<T> systemList) where T : Object { if (systemList == null) { return new List<T>(); } List<T> val = new List<T>(systemList.Count); foreach (T system in systemList) { if (system != null) { val.Add(system); } } return val; } public static List<T> ConvertList<T>(List<T> il2cppList) where T : Object { if (il2cppList == null) { return new List<T>(); } List<T> list = new List<T>(il2cppList.Count); for (int i = 0; i < il2cppList.Count; i++) { T val = il2cppList[i]; if (val != null) { list.Add(val); } } return list; } public static int GetAmountInInventoryAndSupply(NPC npc, ItemDefinition item) { if ((Object)(object)npc == (Object)null || (Object)(object)item == (Object)null) { if (DebugLogs.All || DebugLogs.Core || DebugLogs.Chemist || DebugLogs.Botanist) { MelonLogger.Warning("GetAmountInInventoryAndSupply: NPC or item is null"); } return 0; } NPCInventory inventory = npc.Inventory; int num = ((inventory != null) ? inventory._GetItemAmount(item.ID) : 0); int amountInSupply = GetAmountInSupply(npc, item.GetDefaultInstance(1)); return num + amountInSupply; } public static int GetAmountInSupply(NPC npc, ItemInstance item) { //IL_00e7: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)npc == (Object)null || item == null || string.IsNullOrEmpty(item.ID)) { if (DebugLogs.All || DebugLogs.Core || DebugLogs.Chemist || DebugLogs.Botanist) { MelonLogger.Warning($"GetAmountInSupplies: NPC={npc}, item={item}, or item.ID={((item != null) ? item.ID : null)} is null for {((npc != null) ? npc.fullName : null) ?? "null"}"); } return 0; } if (!ConfigurationExtensions.NPCSupply.TryGetValue(npc.GUID, out var value) || (Object)(object)((value != null) ? value.SelectedObject : null) == (Object)null) { if (DebugLogs.All || DebugLogs.Core || DebugLogs.Chemist || DebugLogs.Botanist) { MelonLogger.Warning("GetAmountInSupplies: Supply or SelectedObject is null for " + npc.fullName); } return 0; } ITransitEntity val = ((Il2CppObjectBase)value.SelectedObject).TryCast<ITransitEntity>(); if (val == null) { if (DebugLogs.All || DebugLogs.Core || DebugLogs.Chemist || DebugLogs.Botanist) { MelonLogger.Warning("GetAmountInSupplies: Supply is not ITransitEntity for " + npc.fullName); } return 0; } if (!npc.Movement.CanGetTo(val, 1f)) { if (DebugLogs.All || DebugLogs.Core || DebugLogs.Chemist || DebugLogs.Botanist) { MelonLogger.Warning("GetAmountInSupplies: Cannot reach supply for " + npc.fullName); } return 0; } List<ItemSlot> val2 = new List<ItemSlot>(); if (val.OutputSlots != null) { for (int i = 0; i < val.OutputSlots.Count; i++) { ItemSlot val3 = val.OutputSlots[i]; if (val3 != null && val3.ItemInstance != null && val3.Quantity > 0 && !val2.Contains(val3)) { val2.Add(val3); } } } if (val.InputSlots != null) { for (int j = 0; j < val.InputSlots.Count; j++) { ItemSlot val4 = val.InputSlots[j]; if (val4 != null && val4.ItemInstance != null && val4.Quantity > 0 && !val2.Contains(val4)) { val2.Add(val4); } } } if (val2.Count == 0) { if (DebugLogs.All || DebugLogs.Core || DebugLogs.Chemist || DebugLogs.Botanist) { MelonLogger.Warning("GetAmountInSupplies: No valid slots in supply " + ((val != null) ? val.Name : null) + " for " + npc.fullName); } return 0; } int num = 0; string text = item.ID.ToLower(); Enumerator<ItemSlot> enumerator = val2.GetEnumerator(); while (enumerator.MoveNext()) { ItemSlot current = enumerator.Current; if (current.ItemInstance.ID.ToLower() == text) { num += current.Quantity; if (DebugLogs.All || DebugLogs.Core || DebugLogs.Chemist || DebugLogs.Botanist) { MelonLogger.Msg($"GetAmountInSupplies: Found {text} with quantity={current.Quantity} in slot {((Object)current).GetHashCode()} for {npc.fullName}"); } } else if (DebugLogs.All || DebugLogs.Core || DebugLogs.Chemist || DebugLogs.Botanist) { MelonLogger.Msg($"GetAmountInSupplies: Slot {((Object)current).GetHashCode()} contains {current.ItemInstance.ID} (quantity={current.Quantity}), not {text} for {npc.fullName}"); } } if (num == 0) { if (DebugLogs.All || DebugLogs.Core || DebugLogs.Chemist || DebugLogs.Botanist) { MelonLogger.Msg($"GetAmountInSupplies: No items of {item.ID} found in supply {((val != null) ? val.Name : null)} for {npc.fullName}"); } } else if (DebugLogs.All || DebugLogs.Core || DebugLogs.Chemist || DebugLogs.Botanist) { MelonLogger.Msg($"GetAmountInSupplies: Total quantity of {item.ID} is {num} in supply {((val != null) ? val.Name : null)} for {npc.fullName}"); } return num; } public static Transform GetTransformTemplateFromConfigPanel(EConfigurableType configType, string componentStr) { //IL_02e5: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown //IL_0038: 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_003b: 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_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Expected O, but got Unknown //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Invalid comparison between Unknown and I4 //IL_0129: 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) //IL_0094: Expected O, but got Unknown //IL_0187: 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_0050: Invalid comparison between Unknown and I4 //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Expected O, but got Unknown //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_025c: Unknown result type (might be due to invalid IL or missing references) //IL_02a0: Unknown result type (might be due to invalid IL or missing references) try { GameObject val = new GameObject($"Dummy{configType}"); EntityConfiguration val2 = null; GameObject val3 = null; ConfigurationReplicator val4 = new ConfigurationReplicator(); if ((int)configType != 0) { if ((int)configType != 4) { if ((int)configType != 10) { MelonLogger.Error($"Unsupported EConfigurableType: {configType}"); Object.Destroy((Object)(object)val); return null; } MixingStation val5 = val.AddComponent<MixingStation>(); val2 = (EntityConfiguration)new MixingStationConfiguration(val4, ((Il2CppObjectBase)val5).TryCast<IConfigurable>(), val5); val3 = GetPrefabGameObject("MixingStationPanel"); } else { Packager val6 = val.AddComponent<Packager>(); val2 = (EntityConfiguration)new PackagerConfiguration(val4, ((Il2CppObjectBase)val6).TryCast<IConfigurable>(), val6); val3 = GetPrefabGameObject("PackagerConfigPanel"); } } else { Pot val7 = val.AddComponent<Pot>(); val2 = (EntityConfiguration)new PotConfiguration(val4, ((Il2CppObjectBase)val7).TryCast<IConfigurable>(), val7); val3 = GetPrefabGameObject("PotConfigPanel"); } if ((Object)(object)val3 == (Object)null) { MelonLogger.Error($"No ConfigPanel prefab found for {configType}"); return null; } GameObject val8 = Object.Instantiate<GameObject>(val3); val8.SetActive(false); ConfigPanel component = val8.GetComponent<ConfigPanel>(); if ((Object)(object)component == (Object)null) { MelonLogger.Error($"Instantiated prefab for {configType} lacks ConfigPanel component"); Object.Destroy((Object)(object)val8); return null; } List<EntityConfiguration> list = new List<EntityConfiguration>(); list.Add(val2); component.Bind(NoLazyUtilities.ConvertList<EntityConfiguration>(list)); if (DebugLogs.All || DebugLogs.Core) { MelonLogger.Msg($"Bound temporary ConfigPanel for {configType} to initialize UI components"); } Transform val9 = ((Component)component).transform.Find(componentStr); if ((Object)(object)val9 == (Object)null) { MelonLogger.Error($"Failed to retrieve UI template from ConfigPanel for {configType}"); } else if (DebugLogs.All || DebugLogs.Core) { MelonLogger.Msg($"Successfully retrieved UI template from ConfigPanel for {configType}"); } Object.Destroy((Object)(object)val8); Object.Destroy((Object)(object)val); return val9; } catch (Exception value) { MelonLogger.Error($"Failed to get UI template from ConfigPanel for {configType}: {value}"); return null; } } public static GameObject GetPrefabGameObject(string id) { try { GameObject val = null; GameObject[] array = Il2CppArrayBase<GameObject>.op_Implicit(Resources.FindObjectsOfTypeAll<GameObject>()); GameObject[] array2 = array; foreach (GameObject val2 in array2) { if (((Object)val2).name.Contains(id)) { if (DebugLogs.All || DebugLogs.Core) { MelonLogger.Msg("Found prefab: " + ((Object)val2).name); } val = val2; break; } } if ((Object)(object)val != (Object)null) { GameObject val3 = Object.Instantiate<GameObject>(val); if (DebugLogs.All || DebugLogs.Core) { MelonLogger.Msg("Instantiated prefab: " + ((Object)val3).name); } return val3; } MelonLogger.Error("Prefab " + id + " not found in Resources."); return null; } catch (Exception value) { MelonLogger.Error($"Failed to find prefab: {value}"); return null; } } public static void LogItemFieldUIDetails(ItemFieldUI itemfieldUI) { if (DebugLogs.All || DebugLogs.Core) { MelonLogger.Msg("=== ItemFieldUI Details ==="); } if (DebugLogs.All || DebugLogs.Core) { MelonLogger.Msg("ItemFieldUI GameObject: " + (((Object)(object)((Component)itemfieldUI).gameObject != (Object)null) ? ((Object)((Component)itemfieldUI).gameObject).name : "null")); } if (DebugLogs.All || DebugLogs.Core) { DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(20, 1); defaultInterpolatedStringHandler.AppendLiteral("ItemFieldUI Active: "); GameObject gameObject = ((Component)itemfieldUI).gameObject; defaultInterpolatedStringHandler.AppendFormatted((gameObject != null) ? new bool?(gameObject.activeSelf) : null); MelonLogger.Msg(defaultInterpolatedStringHandler.ToStringAndClear()); } if (DebugLogs.All || DebugLogs.Core) { MelonLogger.Msg("ItemFieldUI Type: " + ((object)itemfieldUI).GetType().Name); } LogComponentDetails((Component)(object)itemfieldUI, 0); if (DebugLogs.All || DebugLogs.Core) { MelonLogger.Msg("--- Hierarchy and Components ---"); } if ((Object)(object)((Component)itemfieldUI).gameObject != (Object)null) { LogGameObjectDetails(((Component)itemfieldUI).gameObject, 0); } else if (DebugLogs.All || DebugLogs.Core) { MelonLogger.Warning("ItemFieldUI GameObject is null, cannot log hierarchy and components"); } } private static void LogGameObjectDetails(GameObject go, int indentLevel) { //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Expected O, but got Unknown if ((Object)(object)go == (Object)null) { if (DebugLogs.All || DebugLogs.Core) { MelonLogger.Msg(new string(' ', indentLevel * 2) + "GameObject: null"); } return; } if (DebugLogs.All || DebugLogs.Core) { MelonLogger.Msg(new string(' ', indentLevel * 2) + $"GameObject: {((Object)go).name}, Active: {go.activeSelf}"); } foreach (Component component in go.GetComponents<Component>()) { LogComponentDetails(component, indentLevel + 1); } IEnumerator enumerator2 = go.transform.GetEnumerator(); try { while (enumerator2.MoveNext()) { Transform val = (Transform)enumerator2.Current; LogGameObjectDetails(((Component)val).gameObject, indentLevel + 1); } } finally { if (enumerator2 is IDisposable disposable) { disposable.Dispose(); } } } private static void LogComponentDetails(Component component, int indentLevel) { if ((Object)(object)component == (Object)null) { if (DebugLogs.All || DebugLogs.Core) { MelonLogger.Msg(new string(' ', indentLevel * 2) + "Component: null"); } return; } if (DebugLogs.All || DebugLogs.Core) { MelonLogger.Msg(new string(' ', indentLevel * 2) + "Component: " + ((object)component).GetType().Name); } FieldInfo[] fields = ((object)component).GetType().GetFields(BindingFlags.Instance | BindingFlags.Public); FieldInfo[] array = fields; foreach (FieldInfo fieldInfo in array) { try { object value = fieldInfo.GetValue(component); string text = ValueToString(value); if (DebugLogs.All || DebugLogs.Core) { MelonLogger.Msg(new string(' ', indentLevel * 2) + " Field: " + fieldInfo.Name + " = " + text); } } catch (Exception ex) { MelonLogger.Error(new string(' ', indentLevel * 2) + " Failed to get field " + fieldInfo.Name + ": " + ex.Message); } } PropertyInfo[] properties = ((object)component).GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public); PropertyInfo[] array2 = properties; foreach (PropertyInfo propertyInfo in array2) { if (!propertyInfo.CanRead) { continue; } try { object value2 = propertyInfo.GetValue(component); string text2 = ValueToString(value2); if (DebugLogs.All || DebugLogs.Core) { MelonLogger.Msg(new string(' ', indentLevel * 2) + " Property: " + propertyInfo.Name + " = " + text2); } } catch (Exception ex2) { MelonLogger.Error(new string(' ', indentLevel * 2) + " Failed to get property " + propertyInfo.Name + ": " + ex2.Message); } } } private static string ValueToString(object value) { if (value == null) { return "null"; } GameObject val = (GameObject)((value is GameObject) ? value : null); if (val != null) { return "GameObject(" + ((Object)val).name + ")"; } Component val2 = (Component)((value is Component) ? value : null); if (val2 != null) { return ((object)val2).GetType().Name + " on " + ((Object)val2.gameObject).name; } if (value is IEnumerable enumerable && !(value is string)) { List<string> val3 = new List<string>(); foreach (object item in enumerable) { val3.Add(ValueToString(item)); } return "[" + string.Join(", ", val3) + "]"; } return value.ToString(); } } [HarmonyPatch(typeof(ItemSetterScreen), "Open")] public class ItemSetterScreenOpenPatch { private static void Prefix(ItemSetterScreen __instance, object option) { try { ItemField val = (ItemField)((option is ItemField) ? option : null); if (val != null) { if (DebugLogs.All || DebugLogs.Core) { ItemDefinition selectedItem = val.SelectedItem; MelonLogger.Msg("ItemSetterScreenOpenPatch: Opening for ItemField, SelectedItem: " + (((selectedItem != null) ? selectedItem.Name : null) ?? "null")); } if (val.Options != null) { if (DebugLogs.All || DebugLogs.Core) { MelonLogger.Msg($"ItemSetterScreenOpenPatch: ItemField options count: {val.Options.Count}"); } } else if (DebugLogs.All || DebugLogs.Core) { MelonLogger.Warning("ItemSetterScreenOpenPatch: ItemField Options is null"); } } else if (DebugLogs.All || DebugLogs.Core) { MelonLogger.Msg("ItemSetterScreenOpenPatch: Opening for " + (option?.GetType().Name ?? "null")); } } catch (Exception value) { MelonLogger.Error($"ItemSetterScreenOpenPatch: Prefix failed, error: {value}"); } } } [HarmonyPatch(typeof(EntityConfiguration), "Selected")] public class EntityConfigurationSelectedPatch { private static void Postfix(EntityConfiguration __instance) { //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) try { if (DebugLogs.All || DebugLogs.Core || DebugLogs.Pot || DebugLogs.Botanist || DebugLogs.Chemist || DebugLogs.MixingStation) { MelonLogger.Msg("EntityConfigurationSelectedPatch: " + ((object)__instance).GetType()?.Name + " selected"); } PotConfiguration val = (PotConfiguration)(object)((__instance is PotConfiguration) ? __instance : null); if (val != null && PotExtensions.SupplyRoute.TryGetValue(((BuildableItem)val.Pot).GUID, out var value)) { if (value != null) { if (DebugLogs.All || DebugLogs.Core || DebugLogs.Pot || DebugLogs.Botanist) { MelonLogger.Msg("EntityConfigurationSelectedPatch: Enabling visuals for Pot SourceRoute"); } value.SetVisualsActive(true); } else if (DebugLogs.All || DebugLogs.Core || DebugLogs.Botanist || DebugLogs.Pot) { MelonLogger.Warning("EntityConfigurationSelectedPatch: Pot SourceRoute is null"); } return; } MixingStationConfiguration val2 = (MixingStationConfiguration)(object)((__instance is MixingStationConfiguration) ? __instance : null); if (val2 == null || !MixingStationExtensions.SupplyRoute.TryGetValue(((BuildableItem)val2.station).GUID, out var value2)) { return; } if (value2 != null) { if (DebugLogs.All || DebugLogs.Core || DebugLogs.MixingStation || DebugLogs.Chemist) { MelonLogger.Msg("EntityConfigurationSelectedPatch: Enabling visuals for MixingStation SourceRoute"); } value2.SetVisualsActive(true); } else if (DebugLogs.All || DebugLogs.Core || DebugLogs.Chemist || DebugLogs.MixingStation) { MelonLogger.Warning("EntityConfigurationSelectedPatch: MixingStation SourceRoute is null"); } } catch (Exception value3) { MelonLogger.Error($"EntityConfigurationSelectedPatch: Failed for {((object)__instance)?.GetType().Name}, error: {value3}"); } } } [HarmonyPatch(typeof(EntityConfiguration), "Deselected")] public class EntityConfigurationDeselectedPatch { private static void Postfix(EntityConfiguration __instance) { //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) try { if (DebugLogs.All || DebugLogs.Core) { MelonLogger.Msg("EntityConfigurationDeselectedPatch: " + ((object)__instance).GetType().Name + " deselected"); } PotConfiguration val = (PotConfiguration)(object)((__instance is PotConfiguration) ? __instance : null); if (val != null && PotExtensions.SupplyRoute.TryGetValue(((BuildableItem)val.Pot).GUID, out var value)) { if (value != null) { if (DebugLogs.All || DebugLogs.Core) { MelonLogger.Msg("EntityConfigurationDeselectedPatch: Disabling visuals for Pot SourceRoute"); } value.SetVisualsActive(false); } else if (DebugLogs.All || DebugLogs.Core || DebugLogs.Chemist || DebugLogs.Botanist) { MelonLogger.Warning("EntityConfigurationDeselectedPatch: Pot SourceRoute is null"); } return; } MixingStationConfiguration val2 = (MixingStationConfiguration)(object)((__instance is MixingStationConfiguration) ? __instance : null); if (val2 == null || !MixingStationExtensions.SupplyRoute.TryGetValue(((BuildableItem)val2.station).GUID, out var value2)) { return; } if (value2 != null) { if (DebugLogs.All || DebugLogs.Core || DebugLogs.Chemist || DebugLogs.Botanist) { MelonLogger.Msg("EntityConfigurationDeselectedPatch: Disabling visuals for MixingStation SourceRoute"); } value2.SetVisualsActive(false); } else if (DebugLogs.All || DebugLogs.Core || DebugLogs.Chemist || DebugLogs.Botanist) { MelonLogger.Warning("EntityConfigurationDeselectedPatch: MixingStation SourceRoute is null"); } } catch (Exception value3) { MelonLogger.Error($"EntityConfigurationDeselectedPatch: Failed for {((object)__instance)?.GetType().Name}, error: {value3}"); } } } public static class UIExtensions { public static T GetField<T>(object obj, string fieldName) where T : Component { FieldInfo field = obj.GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.Public); if (field == null) { Debug.LogError(Object.op_Implicit("Field " + fieldName + " not found on " + obj.GetType().Name)); return default(T); } object? value = field.GetValue(obj); return (T)((value is T) ? value : null); } public static void SetField(object obj, string fieldName, object value) { FieldInfo field = obj.GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.Public); if (field == null) { Debug.LogError(Object.op_Implicit("Field " + fieldName + " not found on " + obj.GetType().Name)); } else { field.SetValue(obj, value); } } public static T CloneComponent<T>(T source, GameObject target) where T : Component { if ((Object)(object)source == (Object)null || (Object)(object)target == (Object)null) { return default(T); } T val = target.AddComponent<T>(); FieldInfo[] fields = typeof(T).GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { fieldInfo.SetValue(val, fieldInfo.GetValue(source)); } PropertyInfo[] properties = typeof(T).GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (PropertyInfo propertyInfo in properties) { if (propertyInfo.CanRead && propertyInfo.CanWrite) { propertyInfo.SetValue(val, propertyInfo.GetValue(source)); } } object obj = val; Button val2 = (Button)((obj is Button) ? obj : null); if (val2 != null) { Button sourceButton = default(Button); ref Button reference = ref sourceButton; object obj2 = source; reference = (Button)((obj2 is Button) ? obj2 : null); if (sourceButton != null) { ((UnityEvent)val2.onClick).AddListener(DelegateSupport.ConvertDelegate<UnityAction>((Delegate)(Action)delegate { ((UnityEvent)sourceButton.onClick).Invoke(); })); } } return val; } } [HarmonyPatch(typeof(LoadManager))] public class LoadManagerPatch { [HarmonyPostfix] [HarmonyPatch("Awake")] private static void Postfix(LoadManager __instance) { try { __instance.onLoadComplete.AddListener(DelegateSupport.ConvertDelegate<UnityAction>((Delegate)(Action)delegate { if (DebugLogs.All || DebugLogs.Core) { MelonLogger.Msg("onLoadComplete fired, restoring configurations"); } PotExtensions.RestoreConfigurations(); MixingStationExtensions.RestoreConfigurations(); })); } catch (Exception value) { MelonLogger.Error($"LoadManagerPatch.Awake failed: {value}"); } } } [HarmonyPatch(typeof(GridItemLoader), "LoadAndCreate")] public class GridItemLoaderPatch { public static Dictionary<string, GridItem> LoadedGridItems = new Dictionary<string, GridItem>(); private static void Postfix(string mainPath, GridItem __result) { try { if (DebugLogs.All || DebugLogs.Core) { MelonLogger.Msg("GridItemLoaderPatch: Processing LoadAndCreate for mainPath: " + mainPath); } if ((Object)(object)__result != (Object)null) { LoadedGridItems[mainPath] = __result; if (DebugLogs.All || DebugLogs.Core) { MelonLogger.Msg("GridItemLoaderPatch: Captured GridItem (type: " + ((object)__result).GetType().Name + ") for mainPath: " + mainPath); } } else if (DebugLogs.All || DebugLogs.Core) { MelonLogger.Warning("GridItemLoaderPatch: No GridItem returned for mainPath: " + mainPath); } } catch (Exception value) { MelonLogger.Error($"GridItemLoaderPatch: Postfix failed for mainPath: {mainPath}, error: {value}"); } } } [HarmonyPatch(typeof(ConfigurationReplicator), "RpcLogic___ReceiveItemField_2801973956")] public class ConfigurationReplicatorReceiveItemFieldPatch { private static bool Prefix(ConfigurationReplicator __instance, int fieldIndex, string value) { if (DebugLogs.All || DebugLogs.Core) { MelonLogger.Msg($"ConfigurationReplicatorReceiveItemFieldPatch: Received update for fieldIndex={fieldIndex}, value={value ?? "null"}"); MelonLogger.Msg($"ConfigurationReplicatorReceiveItemFieldPatch: Fields count={__instance.Configuration.Fields.Count}"); for (int i = 0; i < __instance.Configuration.Fields.Count; i++) { MelonLogger.Msg($"ConfigurationReplicatorReceiveItemFieldPatch: Fields[{i}]={((object)__instance.Configuration.Fields[i])?.GetType().Name ?? "null"}"); } } if (fieldIndex < 0 || fieldIndex >= __instance.Configuration.Fields.Count) { if (DebugLogs.All || DebugLogs.Core) { MelonLogger.Msg($"ConfigurationReplicatorReceiveItemFieldPatch: Invalid fieldIndex={fieldIndex}, Configuration.Fields.Count={__instance.Configuration.Fields.Count}, skipping"); } return false; } ConfigField obj = __instance.Configuration.Fields[fieldIndex]; ItemField val = (ItemField)(object)((obj is ItemField) ? obj : null); if (val == null) { if (DebugLogs.All || DebugLogs.Core) { MelonLogger.Msg($"ConfigurationReplicatorReceiveItemFieldPatch: No ItemField at fieldIndex={fieldIndex}, Fields[{fieldIndex}]={((object)__instance.Configuration.Fields[fieldIndex])?.GetType().Name ?? "null"}, skipping"); } return false; } if (string.IsNullOrEmpty(value) && !val.CanSelectNone) { if (DebugLogs.All || DebugLogs.Core) { DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(113, 2); defaultInterpolatedStringHandler.AppendLiteral("ConfigurationReplicatorReceiveItemFieldPatch: Blocked null update for ItemField with CanSelectNone="); defaultInterpolatedStringHandler.AppendFormatted(val.CanSelectNone); defaultInterpolatedStringHandler.AppendLiteral(", CurrentItem="); ItemDefinition selectedItem = val.SelectedItem; defaultInterpolatedStringHandler.AppendFormatted(((selectedItem != null) ? selectedItem.Name : null) ?? "null"); MelonLogger.Msg(defaultInterpolatedStringHandler.ToStringAndClear()); } return false; } if (DebugLogs.All || DebugLogs.Core) { MelonLogger.Msg($"ConfigurationReplicatorReceiveItemFieldPatch: Allowing update for ItemField, CanSelectNone={val.CanSelectNone}, value={value}"); } return true; } private static void Postfix(ConfigurationReplicator __instance, int fieldIndex, string value) { //IL_008e: 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_00e2: Unknown result type (might be due to invalid IL or missing references) try { if (DebugLogs.All || DebugLogs.Core || DebugLogs.Chemist || DebugLogs.Botanist) { MelonLogger.Msg($"ConfigurationReplicatorReceiveObjectFieldPatch: Received update for fieldIndex={fieldIndex}, value={value}"); } EntityConfiguration configuration = __instance.Configuration; PotConfiguration val = (PotConfiguration)(object)((configuration is PotConfiguration) ? configuration : null); if (val == null || fieldIndex != 6) { return; } if (PotExtensions.Supply.TryGetValue(((BuildableItem)val.Pot).GUID, out var _)) { if (DebugLogs.All || DebugLogs.Core || DebugLogs.Chemist || DebugLogs.Botanist) { MelonLogger.Msg($"ConfigurationReplicatorReceiveObjectFieldPatch: Updated supply for pot: {((BuildableItem)val.Pot).GUID}, SelectedObject: unknown because value is a string"); } } else if (DebugLogs.All || DebugLogs.Core || DebugLogs.Chemist || DebugLogs.Botanist) { MelonLogger.Warning($"ConfigurationReplicatorReceiveObjectFieldPatch: No supply found for pot: {((BuildableItem)val.Pot).GUID}"); } } catch (Exception value3) { MelonLogger.Error($"ConfigurationReplicatorReceiveObjectFieldPatch: Failed for fieldIndex={fieldIndex}, error: {value3}"); } } } [HarmonyPatch(typeof(ItemField), "SetItem", new Type[] { typeof(ItemDefinition), typeof(bool) })] public class ItemFieldSetItemPatch { private static bool Prefix(ItemField __instance, ItemDefinition item, bool network) { if (DebugLogs.Stacktrace) { DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(104, 5); defaultInterpolatedStringHandler.AppendLiteral("ItemFieldSetItemPatch: Called for ItemField, network="); defaultInterpolatedStringHandler.AppendFormatted(network); defaultInterpolatedStringHandler.AppendLiteral(", CanSelectNone="); defaultInterpolatedStringHandler.AppendFormatted(__instance.CanSelectNone); defaultInterpolatedStringHandler.AppendLiteral(", Item="); defaultInterpolatedStringHandler.AppendFormatted(((item != null) ? item.Name : null) ?? "null"); defaultInterpolatedStringHandler.AppendLiteral(", CurrentItem="); ItemDefinition selectedItem = __instance.SelectedItem; defaultInterpolatedStringHandler.AppendFormatted(((selectedItem != null) ? selectedItem.Name : null) ?? "null"); defaultInterpolatedStringHandler.AppendLiteral(", StackTrace: "); defaultInterpolatedStringHandler.AppendFormatted(new StackTrace().ToString()); MelonLogger.Msg(defaultInterpolatedStringHandler.ToStringAndClear()); } bool flag = __instance.Options != null && NoLazyUtilities.ConvertList<ItemDefinition>(__instance.Options).Any((ItemDefinition o) => ((IEnumerable<ItemDefinition>)NoLazyUtilities.ConvertList<ProductDefinition>(ProductManager.FavouritedProducts)).Contains(o)); if ((((Object)(object)item == (Object)null && __instance.CanSelectNone) || flag) && DebugLogs.Stacktrace) { DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(104, 3); defaultInterpolatedStringHandler.AppendLiteral("ItemFieldSetItemPatch: Blocked null update for Product field, CanSelectNone="); defaultInterpolatedStringHandler.AppendFormatted(__instance.CanSelectNone); defaultInterpolatedStringHandler.AppendLiteral(", CurrentItem="); ItemDefinition selectedItem2 = __instance.SelectedItem; defaultInterpolatedStringHandler.AppendFormatted(((selectedItem2 != null) ? selectedItem2.Name : null) ?? "null"); defaultInterpolatedStringHandler.AppendLiteral(", StackTrace: "); defaultInterpolatedStringHandler.AppendFormatted(new StackTrace().ToString()); MelonLogger.Msg(defaultInterpolatedStringHandler.ToStringAndClear()); } return true; } } } namespace NoLazyWorkers_IL2CPP.Settings { public class SettingsExtensions { public static readonly List<Guid> Configured = new List<Guid>(); } [Serializable] public class BaseEmployee { public string SigningFee { get; set; } public string DailyWage { get; set; } public string WalkSpeed { get; set; } public string MaxHealth { get; set; } } [Serializable] public class BotanistSettings : BaseEmployee { public string SoilPourTime { get; set; } public string SeedSowTime { get; set; } public string AdditivePourTime { get; set; } public string WaterPourTime { get; set; } public string WateringCriticalThreshold { get; set; } public string WateringThreshold { get; set; } public string WateringTargetMin { get; set; } public string WateringTargetMax { get; set; } public string HarvestTime { get; set; } } [Serializable] public class ChemistSettings : BaseEmployee { public string MixingPerIngredientTime { get; set; } public string PlaceIngredientsTime { get; set; } public string StirTime { get; set; } public string BurnerTime { get; set; } } [Serializable] public class CleanerSettings : BaseEmployee { } [Serializable] public class PackagerSettings : BaseEmployee { public string PackagingSpeedMultiplier { get; set; } } [Serializable] public class FixerSettings { public string AdditionalSigningFee1 { get; set; } public string AdditionalSigningFee2 { get; set; } public string MaxAdditionalFee { get; set; } public string AdditionalFeeThreshold { get; set; } } [Serializable] public class MiscSettings { public string StoreDeliveryFee { get; set; } } [Serializable] public class Default { public BotanistSettings Botanist { get; set; } = new BotanistSettings(); public ChemistSettings Chemist { get; set; } = new ChemistSettings(); public CleanerSettings Cleaner { get; set; } = new CleanerSettings(); public PackagerSettings Packager { get; set; } = new PackagerSettings(); public FixerSettings Fixer { get; set; } = new FixerSettings(); public MiscSettings Misc { get; set; } = new MiscSettings(); public static Default LoadFromFile(string filePath) { if (DebugLogs.All || DebugLogs.Settings) { MelonLogger.Msg("Settings: LoadFromFile"); } Default @default = new Default(); string text = ""; string[] array = File.ReadAllLines(filePath); foreach (string text2 in array) { string text3 = text2.Trim(); if (string.IsNullOrEmpty(text3) || text3.StartsWith("//")) { continue; } if (text3.StartsWith("#")) { text = text3.Substring(1).ToLower(); continue; } string[] array2 = (from p in text3.Split('=') select p.Trim()).ToArray(); if (array2.Length == 2) { string key = array2[0]; string value = array2[1]; switch (text) { case "botanist": SetProperty(@default.Botanist, key, value); break; case "chemist": SetProperty(@default.Chemist, key, value); break; case "cleaner": SetProperty(@default.Cleaner, key, value); break; case "packager": SetProperty(@default.Packager, key, value); break; case "fixer": SetProperty(@default.Fixer, key, value); break; case "misc": SetProperty(@default.Misc, key, value); break; } } } return @default; } private static void SetProperty(object target, string key, string value) { if (DebugLogs.All || DebugLogs.Settings) { MelonLogger.Msg("Settings: SetProperty"); } PropertyInfo property = target.GetType().GetProperty(key, BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Public); if (!(property == null) && !(property.PropertyType != typeof(string))) { if (DebugLogs.All || DebugLogs.Settings) { MelonLogger.Msg($"Settings: SetProperty {property} | {target}"); } property.SetValue(target, value); } } public void SaveToFile(string filePath) { if (DebugLogs.All || DebugLogs.Settings) { MelonLogger.Msg("Settings: SaveToFile"); } List<string> contents = new List<string> { "#botanist", "SigningFee = " + Botanist.SigningFee, "DailyWage = " + Botanist.DailyWage, "WalkSpeed = " + Botanist.WalkSpeed, "MaxHealth = " + Botanist.MaxHealth, "SoilPourTime = " + Botanist.SoilPourTime, "SeedSowTime = " + Botanist.SeedSowTime, "AdditivePourTime = " + Botanist.AdditivePourTime, "WaterPourTime = " + Botanist.WaterPourTime, "WateringCriticalThreshold = " + Botanist.WateringCriticalThreshold, "WateringThreshold = " + Botanist.WateringThreshold, "WateringTargetMin = " + Botanist.WateringTargetMin, "WateringTargetMax = " + Botanist.WateringTargetMax, "HarvestTime = " + Botanist.HarvestTime, "", "#chemist", "SigningFee = " + Chemist.SigningFee, "DailyWage = " + Chemist.DailyWage, "WalkSpeed = " + Chemist.WalkSpeed, "MaxHealth = " + Chemist.MaxHealth, "#MixingPerIngredientTime = " + Chemist.MixingPerIngredientTime + " #not implemented yet", "#PlaceIngredientsTime = " + Chemist.PlaceIngredientsTime + " #not implemented yet", "#StirTime = " + Chemist.StirTime + " #not implemented yet", "#BurnerTime = " + Chemist.BurnerTime + " #not implemented yet", "", "#cleaner", "SigningFee = " + Cleaner.SigningFee, "DailyWage = " + Cleaner.DailyWage, "WalkSpeed = " + Cleaner.WalkSpeed, "MaxHealth = " + Cleaner.MaxHealth, "", "#packager", "SigningFee = " + Packager.SigningFee, "DailyWage = " + Packager.DailyWage, "WalkSpeed = " + Packager.WalkSpeed, "MaxHealth = " + Packager.MaxHealth, "PackagingSpeedMultiplier = " + Packager.PackagingSpeedMultiplier, "", "#fixer", "#AdditionalSigningFee1 = " + Fixer.AdditionalSigningFee1 + " #not implemented yet", "#AdditionalSigningFee2 = " + Fixer.AdditionalSigningFee2 + " #not implemented yet", "#MaxAdditionalFee = " + Fixer.MaxAdditionalFee + " #not implemented yet", "#AdditionalFeeThreshold = " + Fixer.AdditionalFeeThreshold + " #not implemented yet", "", "#misc", "#StoreDeliveryFee = " + Misc.StoreDeliveryFee + " #not implemented yet" }; File.WriteAllLines(filePath, contents); } public Default() { if (DebugLogs.All || DebugLogs.Settings) { MelonLogger.Msg("Settings: Default"); } Botanist = new BotanistSettings { SigningFee = "1000", DailyWage = "200", WalkSpeed = "1.2", MaxHealth = "100", SoilPourTime = "10", SeedSowTime = "15", AdditivePourTime = "10", WaterPourTime = "10", WateringCriticalThreshold = "0.2", WateringThreshold = "0.3", WateringTargetMin = "0.75", WateringTargetMax = "1", HarvestTime = "15" }; Chemist = new ChemistSettings { SigningFee = "1500", DailyWage = "300", WalkSpeed = "1.2", MaxHealth = "100", MixingPerIngredientTime = "1", PlaceIngredientsTime = "8", StirTime = "6", BurnerTime = "6" }; Cleaner = new CleanerSettings { SigningFee = "500", DailyWage = "100", WalkSpeed = "1.2", MaxHealth = "100" }; Packager = new PackagerSettings { SigningFee = "1000", DailyWage = "200", WalkSpeed = "1.2", MaxHealth = "100", PackagingSpeedMultiplier = "2" }; Fixer = new FixerSettings { AdditionalSigningFee1 = "100", AdditionalSigningFee2 = "250", MaxAdditionalFee = "500", AdditionalFeeThreshold = "5" }; Misc = new MiscSettings { StoreDeliveryFee = "200" }; } } public class Configure { [CompilerGenerated] private sealed class <ApplyOneShotSettingsRoutine>d__10 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Configure <>4__this; private bool <settingsApplied>5__1; private float <elapsedTime>5__2; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <ApplyOneShotSettingsRoutine>d__10(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; if (DebugLogs.All || DebugLogs.Settings) { MelonLogger.Msg("Settings: ApplyOneShotSettingsRoutine started"); } <settingsApplied>5__1 = false; <elapsedTime>5__2 = 0f; break; case 1: <>1__state = -1; break; } if (<elapsedTime>5__2 < 30f && !<settingsApplied>5__1) { if (DebugLogs.All || DebugLogs.Settings) { MelonLogger.Msg($"Settings: ApplyOneShotSettingsRoutine attempt at {<elapsedTime>5__2} seconds"); } <>4__this.ApplyMiscSettings(); <settingsApplied>5__1 = true; <elapsedTime>5__2 += 1f; <>2__current = (object)new WaitForSeconds(1f); <>1__state = 1; return true; } if (<settingsApplied>5__1) { if (DebugLogs.All || DebugLogs.Settings) { MelonLogger.Msg("Settings: ApplyOneShotSettingsRoutine completed successfully"); } } else { MelonLogger.Error("Settings: ApplyOneShotSettingsRoutine failed to apply settings after 30 seconds"); } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <ConfigureRoutine>d__3 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Employee employee; public Configure <>4__this; private int <attempts>5__1; private int <objectId>5__2; private bool <isObjectIdValid>5__3; private string <guid>5__4; private bool <isGuidValid>5__5; private Exception <ex>5__6; private EEmployeeType <>s__7; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <ConfigureRoutine>d__3(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <guid>5__4 = null; <ex>5__6 = null; <>1__state = -2; } private bool MoveNext() { //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_02d7: Unknown result type (might be due to invalid IL or missing references) //IL_036b: 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_0372: Unknown result type (might be due to invalid IL or missing references) //IL_0374: Unknown result type (might be due to invalid IL or missing references) //IL_037a: Unknown result type (might be due to invalid IL or missing references) //IL_037f: Unknown result type (might be due to invalid IL or missing references) //IL_0381: Unknown result type (might be due to invalid IL or missing references) //IL_0398: Expected I4, but got Unknown //IL_0423: Unknown result type (might be due to invalid IL or missing references) switch (<>1__state) { default: return false; case 0: <>1__state = -1; if ((Object)(object)employee == (Object)null) { MelonLogger.Error("Settings: ConfigureRoutine: Employee is null"); return false; } <attempts>5__1 = 0; break; case 1: <>1__state = -1; <guid>5__4 = null; break; } if (<attempts>5__1 < 50) { <objectId>5__2 = 0; <isObjectIdValid>5__3 = false; try { <objectId>5__2 = ((NetworkBehaviour)employee).ObjectId; <isObjectIdValid>5__3 = <objectId>5__2 != 0; } catch (Exception ex) { <ex>5__6 = ex; if (DebugLogs.All || DebugLogs.Settings) { MelonLogger.Msg($"Settings: ConfigureRoutine: Error accessing ObjectId for {((NPC)employee).fullName} on attempt {<attempts>5__1 + 1}: {<ex>5__6.Message}"); } } Guid gUID = ((NPC)employee).GUID; <guid>5__4 = ((object)(Guid)(ref gUID)).ToString(); <isGuidValid>5__5 = !string.IsNullOrEmpty(<guid>5__4) && <guid>5__4 != "00000000-0000-0000-0000-000000000000"; if (DebugLogs.All || DebugLogs.Settings) { MelonLogger.Msg($"Settings: ConfigureRoutine: Waiting for valid ObjectId and GUID for {((NPC)employee).fullName} | Attempt {<attempts>5__1 + 1} | ObjectId: {(<isObjectIdValid>5__3 ? <objectId>5__2.ToString() : "Invalid")} | GUID: {<guid>5__4}"); } if (<isObjectIdValid>5__3 & <isGuidValid>5__5) { if (SettingsExtensions.Configured.Contains(((NPC)employee).GUID)) { if (DebugLogs.All || DebugLogs.Settings) { MelonLogger.Msg($"Settings: ConfigureRoutine: Skipping already configured employee {((NPC)employee).fullName} | ObjectId: {<objectId>5__2} | GUID: {<guid>5__4}"); } return false; } SettingsExtensions.Configured.Add(((NPC)employee).GUID); if (DebugLogs.All || DebugLogs.Settings) { MelonLogger.Msg($"Settings: ConfigureRoutine: Added ObjectId {<objectId>5__2} for {((NPC)employee).fullName} | GUID: {<guid>5__4}"); } EEmployeeType type = employee.Type; <>s__7 = type; EEmployeeType val = <>s__7; switch ((int)val) { case 0: <>4__this.ApplyBotanistSettings(((Il2CppObjectBase)employee).TryCast<Botanist>()); break; case 2: <>4__this.ApplyChemistSettings(((Il2CppObjectBase)employee).TryCast<Chemist>()); break; case 3: <>4__this.ApplyCleanerSettings(((Il2CppObjectBase)employee).TryCast<Cleaner>()); break; case 1: <>4__this.ApplyPackagerSettings(((Il2CppObjectBase)employee).TryCast<Packager>()); break; default: MelonLogger.Warning($"Settings: ConfigureRoutine: Unknown employee type {employee.Type} for {((NPC)employee).fullName}"); break; } return false; } <attempts>5__1++; <>2__current = null; <>1__state = 1; return true; } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private readonly Default config; public Configure() { if (DebugLogs.All || DebugLogs.Settings) { MelonLogger.Msg("Settings: Configure"); } config = NoLazyWorkersMod.Instance.Config; } public void StartCoroutine(Employee employee) { if ((Object)(object)employee == (Object)null) { MelonLogger.Error("Settings: StartCoroutine: Employee is null"); } else { MelonCoroutines.Start(ConfigureRoutine(employee)); } } [IteratorStateMachine(typeof(<ConfigureRoutine>d__3))] private IEnumerator ConfigureRoutine(Employee employee) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <ConfigureRoutine>d__3(0) { <>4__this = this, employee = employee }; } public void ApplyBotanistSettings(Botanist botanist) { //IL_0084: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)botanist == (Object)null) { MelonLogger.Error("Settings: ApplyBotanistSettings: Botanist is null"); return; } if (DebugLogs.All || DebugLogs.Settings) { MelonLogger.Msg($"Settings: ApplyBotanistSettings {((NPC)botanist).fullName} | {((NetworkBehaviour)botanist).ObjectId} | {((NPC)botanist).GUID}"); } if (int.TryParse(config.Botanist.SigningFee, out var result)) { ((Employee)botanist).SigningFee = result; } else { MelonLogger.Error("Invalid SigningFee for Botanist: " + config.Botanist.SigningFee); } if (int.TryParse(config.Botanist.DailyWage, out var result2)) { ((Employee)botanist).DailyWage = result2; } else { MelonLogger.Error("Invalid DailyWage for Botanist: " + config.Botanist.DailyWage); } if (float.TryParse(config.Botanist.WalkSpeed, out var result3)) { ((NPC)botanist).movement.WalkSpeed = result3; } else { MelonLogger.Error("Invalid WalkSpeed for Botanist: " + config.Botanist.WalkSpeed); } if (float.TryParse(config.Botanist.MaxHealth, out var result4)) { ((NPC)botanist).Health.MaxHealth = result4; } else { MelonLogger.Error("Invalid MaxHealth for Botanist: " + config.Botanist.MaxHealth); } if (float.TryParse(config.Botanist.SoilPourTime, out var result5)) { botanist.SOIL_POUR_TIME = result5; } else { MelonLogger.Error("Invalid SoilPourTime for Botanist: " + config.Botanist.SoilPourTime); } if (float.TryParse(config.Botanist.SeedSowTime, out var result6)) { botanist.SEED_SOW_TIME = result6; } else { MelonLogger.Error("Invalid SeedSowTime for Botanist: " + config.Botanist.SeedSowTime); } if (float.TryParse(config.Botanist.AdditivePourTime, out var result7)) { botanist.ADDITIVE_POUR_TIME = result7; } else { MelonLogger.Error("Invalid AdditivePourTime for Botanist: " + config.Botanist.AdditivePourTime); } if (float.TryParse(config.Botanist.WateringCriticalThreshold, out var result8)) { botanist.CRITICAL_WATERING_THRESHOLD = result8; } else { MelonLogger.Error("Invalid WateringCriticalThreshold for Botanist: " + config.Botanist.WateringCriticalThreshold); } if (float.TryParse(config.Botanist.WateringThreshold, out var result9)) { botanist.WATERING_THRESHOLD = result9; } else { MelonLogger.Error("Invalid WateringThreshold for Botanist: " + config.Botanist.WateringThreshold); } if (float.TryParse(config.Botanist.WateringTargetMin, out var result10)) { botanist.TARGET_WATER_LEVEL_MIN = result10; } else { MelonLogger.Error("Invalid WateringTargetMin for Botanist: " + config.Botanist.WateringTargetMin); } if (float.TryParse(config.Botanist.WateringTargetMax, out var result11)) { botanist.TARGET_WATER_LEVEL_MAX = result11; } else { MelonLogger.Error("Invalid WateringTargetMax for Botanist: " + config.Botanist.WateringTargetMax); } if (float.TryParse(config.Botanist.WaterPourTime, out var result12)) { botanist.WATER_POUR_TIME = result12; } else { MelonLogger.Error("Invalid WaterPourTime for Botanist: " + config.Botanist.WaterPourTime); } if (float.TryParse(config.Botanist.HarvestTime, out var result13)) { botanist.HARVEST_TIME = result13; } else { MelonLogger.Error("Invalid HarvestTime for Botanist: " + config.Botanist.HarvestTime); } } public void ApplyChemistSettings(Chemist chemist) { //IL_0084: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)chemist == (Object)null) { MelonLogger.Error("Settings: ApplyChemistSettings: Chemist is null"); return; } if (DebugLogs.All || DebugLogs.Settings) { MelonLogger.Msg($"Settings: ApplyChemistSettings {((NPC)chemist).fullName} | {((NetworkBehaviour)chemist).ObjectId} | {((NPC)chemist).GUID}"); } if (int.TryParse(config.Chemist.SigningFee, out var result)) { ((Employee)chemist).SigningFee = result; } else { MelonLogger.Error("Invalid SigningFee for Chemist: " + config.Chemist.SigningFee); } if (int.TryParse(config.Chemist.DailyWage, out var result2)) { ((Employee)chemist).DailyWage = result2; } else { MelonLogger.Error("Invalid DailyWage for Chemist: " + config.Chemist.DailyWage); } if (float.TryParse(config.Chemist.WalkSpeed, out var result3)) { ((NPC)chemist).movement.WalkSpeed = result3; } else { MelonLogger.Error("Invalid WalkSpeed for Chemist: " + config.Chemist.WalkSpeed); } if (float.TryParse(config.Chemist.MaxHealth, out var result4)) { ((NPC)chemist).Health.MaxHealth = result4; } else { MelonLogger.Error("Invalid MaxHealth for Chemist: " + config.Chemist.MaxHealth); } } public void ApplyCleanerSettings(Cleaner cleaner) { //IL_0084: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)cleaner == (Object)null) { MelonLogger.Error("Settings: ApplyCleanerSettings: Cleaner is null"); return; } if (DebugLogs.All || DebugLogs.Settings) { MelonLogger.Msg($"Settings: ApplyCleanerSettings {((NPC)cleaner).fullName} | {((NetworkBehaviour)cleaner).ObjectId} | {((NPC)cleaner).GUID}"); } if (int.TryParse(config.Cleaner.SigningFee, out var result)) { ((Employee)cleaner).SigningFee = result; } else { MelonLogger.Error("Invalid SigningFee for Cleaner: " + config.Cleaner.SigningFee); } if (int.TryParse(config.Cleaner.DailyWage, out var result2)) { ((Employee)cleaner).DailyWage = result2; } else { MelonLogger.Error("Invalid DailyWage for Cleaner: " + config.Cleaner.DailyWage); } if (float.TryParse(config.Cleaner.WalkSpeed, out var result3)) { ((NPC)cleaner).movement.WalkSpeed = result3; } else { MelonLogger.Error("Invalid WalkSpeed for Cleaner: " + config.Cleaner.WalkSpeed); } if (float.TryParse(config.Cleaner.MaxHealth, out var result4)) { ((NPC)cleaner).Health.MaxHealth = result4; } else { MelonLogger.Error("Invalid MaxHealth for Cleaner: " + config.Cleaner.MaxHealth); } } public void ApplyPackagerSettings(Packager packager) { //IL_0084: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)packager == (Object)null) { MelonLogger.Error("Settings: ApplyPackagerSettings: Packager is null"); return; } if (DebugLogs.All || DebugLogs.Settings) { MelonLogger.Msg($"Settings: ApplyPackagerSettings {((NPC)packager).fullName} | {((NetworkBehaviour)packager).ObjectId} | {((NPC)packager).GUID}"); } if (int.TryParse(config.Packager.SigningFee, out var result)) { ((Employee)packager).SigningFee = result; } else { MelonLogger.Error("Invalid SigningFee for Packager: " + config.Packager.SigningFee); } if (int.TryParse(config.Packager.DailyWage, out var result2)) { ((Employee)packager).DailyWage = result2; } else { MelonLogger.Error("Invalid DailyWage for Packager: " + config.Packager.DailyWage); } if ((Object)(object)((NPC)packager).movement != (Object)null && float.TryParse(config.Packager.WalkSpeed, out var result3)) { ((NPC)packager).movement.WalkSpeed = result3; } else { MelonLogger.Error("Invalid WalkSpeed for Packager: " + config.Packager.WalkSpeed + " or movement is null"); } if ((Object)(object)((NPC)packager).Health != (Object)null && float.TryParse(config.Packager.MaxHealth, out var result4)) { ((NPC)packager).Health.MaxHealth = result4; } else { MelonLogger.Error("Invalid MaxHealth for Packager: " + config.Packager.MaxHealth + " or Health is null"); } if (float.TryParse(config.Packager.PackagingSpeedMultiplier, out var result5)) { packager.PackagingSpeedMultiplier = result5; } else { MelonLogger.Error("Invalid PackagingSpeedMultiplier for Packager: " + config.Packager.PackagingSpeedMultiplier); } } public void ApplyFixerSettings() { } public void ApplyMiscSettings() { if (DebugLogs.All || DebugLogs.Settings) { MelonLogger.Msg("Settings: ApplyMiscSettings"); } if (!float.TryParse(config.Misc.StoreDeliveryFee, out var _)) { MelonLogger.Error("Invalid StoreDeliveryFee: " + config.Misc.StoreDeliveryFee); } } [IteratorStateMachine(typeof(<ApplyOneShotSettingsRoutine>d__10))] public IEnumerator ApplyOneShotSettingsRoutine() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <ApplyOneShotSettingsRoutine>d__10(0) { <>4__this = this }; } } [HarmonyPatch] public static class EmployeePatches { [HarmonyPostfix] [HarmonyPatch(typeof(Chemist), "NetworkInitialize___Early")] public static void ChemistNetworkInitializePostfix(Chemist __instance) { if (DebugLogs.All || DebugLogs.Settings) { MelonLogger.Msg("Settings: ChemistNetworkInitializePostfix"); } ConfigureEmployee((Employee)(object)__instance); } [HarmonyPostfix] [HarmonyPatch(typeof(Packager), "NetworkInitialize___Early")] public static void PackagerNetworkInitializePostfix(Packager __instance) { if (DebugLogs.All || DebugLogs.Settings) { MelonLogger.Msg("Settings: PackagerNetworkInitializePostfix"); } ConfigureEmployee((Employee)(object)__instance); } [HarmonyPostfix] [HarmonyPatch(typeof(Botanist), "NetworkInitialize___Early")] public static void BotanistNetworkInitializePostfix(Botanist __instance) { if (DebugLogs.All || DebugLogs.Settings) { MelonLogger.Msg("Settings: BotanistNetworkInitializePostfix"); } ConfigureEmployee((Employee)(object)__instance); } [HarmonyPostfix] [HarmonyPatch(typeof(Cleaner), "NetworkInitialize___Early")] public static void CleanerNetworkInitializePostfix(Cleaner __instance) { if (DebugLogs.All || DebugLogs.Settings) { MelonLogger.Msg("Settings: CleanerNetworkInitializePostfix"); } ConfigureEmployee((Employee)(object)__instance); } private static void ConfigureEmployee(Employee employee) { //IL_0023: 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) if ((Object)(object)employee == (Object)null) { MelonLogger.Error("Settings: ConfigureEmployee: Employee is null"); } else if (SettingsExtensions.Configured.Contains(((NPC)employee).GUID)) { if (DebugLogs.All || DebugLogs.Settings) { MelonLogger.Msg($"Settings: ConfigureEmployee: Skipping already configured employee {((NPC)employee).fullName} | ObjectId: {((NetworkBehaviour)employee).ObjectId} | GUID: {((NPC)employee).GUID}"); } } else { new Configure().StartCoroutine(employee); } } } } namespace NoLazyWorkers_IL2CPP.Handlers { public static class PackagerExtensions { } [HarmonyPatch(typeof(AdvancedTransitRoute))] public class AdvancedTransitRoutePatch { [HarmonyPatch("GetItemReadyToMove")] [HarmonyPrefix] private static bool GetItemReadyToMovePrefix(AdvancedTransitRoute __instance, ref ItemInstance __result) { //IL_0083: Unknown result type (might be due to invalid IL or missing references) MixingStation val = ((Il2CppObjectBase)((TransitRoute)__instance).Destination).TryCast<MixingStation>(); if (val == null) { return true; } if (((Il2CppObjectBase)val).TryCast<IUsable>().IsInUse || val.CurrentMixOperation != null || val.OutputSlot.Quantity > 0) { if (DebugLogs.All || DebugLogs.Packager) { MelonLogger.Msg($"Handlers: GetItemReadyToMovePrefix: Skipping {((BuildableItem)val).GUID} - Station in use, in operation, or output slot not empty (IsInUse={((Il2CppObjectBase)val).TryCast<IUsable>().IsInUse}, CurrentMixOperation={val.CurrentMixOperation != null}, OutputQuantity={val.OutputSlot.Quantity})"); } __result = null; return false; } if (DebugLogs.All || DebugLogs.Packager) { MelonLogger.Msg("Handlers: GetItemReadyToMovePrefix: resume"); } return true; } } } namespace NoLazyWorkers_IL2CPP.Chemists { public static class CauldronExtensions { public static Dictionary<Guid, ObjectField> Supply = new Dictionary<Guid, ObjectField>(); public static Dictionary<Guid, CauldronConfiguration> CauldronConfig = new Dictionary<Guid, CauldronConfiguration>(); public static Dictionary<Guid, TransitRoute> SupplyRoute = new Dictionary<Guid, TransitRoute>(); } public static class ChemistExtensions { public static ItemField GetMixerItemForProductSlot(MixingStation station) { //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0269: Unknown result type (might be due to invalid IL or missing references) //IL_030b: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)station == (Object)null) { if (DebugLogs.All || DebugLogs.MixingStation) { MelonLogger.Warning($"GetMixerItemForProductSlot: Product slot item is not a ProductDefinition for station={((station != null) ? new Guid?(((BuildableItem)station).GUID) : null)}"); } return null; } ItemInstance itemInstance = station.ProductSlot.ItemInstance; ProductDefinition val = ((itemInstance != null) ? ((Il2CppObjectBase)itemInstance.Definition).TryCast<ProductDefinition>() : null); if ((Object)(object)val == (Object)null) { if (DebugLogs.All || DebugLogs.MixingStation) { DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(86, 2); defaultInterpolatedStringHandler.AppendLiteral("GetMixerItemForProductSlot: Product slot "); ItemInstance itemInstance2 = station.ProductSlot.ItemInstance; defaultInterpolatedStringHandler.AppendFormatted<ItemDefinition>((itemInstance2 != null) ? itemInstance2.Definition : null); defaultInterpolatedStringHandler.AppendLiteral(" item is not a ProductDefinition for station="); defaultInterpolatedStringHandler.AppendFormatted((station != null) ? new Guid?(((BuildableItem)station).GUID) : null); MelonLogger.Warning(defaultInterpolatedStringHandler.ToStringAndClear()); } return null; } if (!MixingStationExtensions.MixingRoutes.TryGetValue(((BuildableItem)station).GUID, out var value) || value == null || value.Count == 0) { if (DebugLogs.All || DebugLogs.MixingStation) { MelonLogger.Msg($"GetMixerItemForProductSlot: No routes defined for station={((BuildableItem)station).GUID}"); } return null; } MixingRoute mixingRoute = null; foreach (MixingRoute item in value) { ItemField product = item.Product; if ((Object)(object)((product != null) ? product.SelectedItem : null) != (Object)null && (Object)(object)item.Product.SelectedItem == (Object)(object)val) { mixingRoute = item; break; } } if (mixingRoute == null) { if (DebugLogs.All || DebugLogs.MixingStation) { MelonLogger.Msg($"GetMixerItemForProductSlot: No route matches product={((ItemDefinition)val).Name} for station={((BuildableItem)station).GUID}"); } return null; } if (DebugLogs.All || DebugLogs.MixingStation) { DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(69, 3); defaultInterpolatedStringHandler.AppendLiteral("GetMixerItemForProductSlot: Found mixerItem="); ItemDefinition selectedItem = mixingRoute.MixerItem.SelectedItem; defaultInterpolatedStringHandler.AppendFormatted(((selectedItem != null) ? selectedItem.Name : null) ?? "null"); defaultInterpolatedStringHandler.AppendLiteral(" for product="); defaultInterpolatedStringHandler.AppendFormatted(((ItemDefinition)val).Name); defaultInterpolatedStringHandler.AppendLiteral(" in station="); defaultInterpolatedStringHandler.AppendFormatted<Guid>(((BuildableItem)station).GUID); MelonLogger.Msg(defaultInterpolatedStringHandler.ToStringAndClear()); } return mixingRoute.MixerItem; } public static ItemInstance GetItemInSupply(this Chemist chemist, MixingStation station, string id) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) ObjectField val = MixingStationExtensions.Supply[((BuildableItem)station).GUID]; List<ItemSlot> list = new List<ItemSlot>(); BuildableItem selectedObject = val.SelectedObject; if ((Object)(object)selectedObject != (Object)null && ((NPC)chemist).behaviour.Npc.Movement.CanGetTo(((Il2CppObjectBase)selectedObject).TryCast<ITransitEntity>(), 1f)) { list.AddRange(NoLazyUtilities.ConvertList<ItemSlot>(((Il2CppObjectBase)selectedObject).TryCast<ITransitEntity>().OutputSlots)); for (int i = 0; i < list.Count; i++) { if (list[i].Quantity > 0 && list[i].ItemInstance.ID.ToLower() == id.ToLower()) { return list[i].ItemInstance; } } } return null; } } [HarmonyPatch(typeof(Chemist))] public class ChemistPatch { [HarmonyPatch("GetMixingStationsReadyToStart")] [HarmonyPrefix] private static bool Prefix(Chemist __instance, ref List<MixingStation> __result) { //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_0156: 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_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_02ce: Unknown result type (might be due to invalid IL or missing references) //IL_030f: Unknown result type (might be due to invalid IL or missing references) try { List<MixingStation> val = new List<MixingStation>(); if (DebugLogs.All || DebugLogs.Chemist) { MelonLogger.Msg($"ChemistPatch.GetMixingStationsReadyToStart: Checking stations for {((__instance != null) ? ((Object)__instance).name : null) ?? "null"}, total stations={__instance.configuration.MixStations.Count}"); } Enumerator<MixingStation> enumerator = __instance.configuration.MixStations.GetEnumerator(); while (enumerator.MoveNext()) { MixingStation current = enumerator.Current; if (((Il2CppObjectBase)current).TryCast<IUsable>().IsInUse || current.CurrentMixOperation != null) { continue; } if (!MixingStationExtensions.Config.TryGetValue(((BuildableItem)current).GUID, out var value)) { if (DebugLogs.All || DebugLogs.Chemist) { MelonLogger.Warning($"ChemistPatch.GetMixingStationsReadyToStart: MixerConfig missing for station {((current != null) ? new Guid?(((BuildableItem)current).GUID) : null)}"); } value = ((Il2CppObjectBase)current.Configuration).TryCast<MixingStationConfiguration>(); MixingStationExtensions.Config[((BuildableItem)current).GUID] = value; } ItemField mixerItemForProductSlot = ChemistExtensions.GetMixerItemForProductSlot(current); if ((Object)(object)((mixerItemForProductSlot != null) ? mixerItemForProductSlot.SelectedItem : null) == (Object)null) { continue; } float value2 = value.StartThrehold.Value; int mixQuantity = current.GetMixQuantity(); bool flag = (float)mixQuantity >= value2 && (float)current.ProductSlot.Quantity >= value2 && current.OutputSlot.Quantity == 0; bool flag2 = false; bool flag3 = false; ObjectField val2 = MixingStationExtensions.Supply[((BuildableItem)current).GUID]; if (!flag && (Object)(object)((val2 != null) ? val2.SelectedObject : null) != (Object)null) { ConfigurationExtensions.NPCSupply[((NPC)__instance).GUID] = val2; object obj; if (mixerItemForProductSlot == null) { obj = null; } else { ItemDefinition selectedItem = mixerItemForProductSlot.SelectedItem; obj = ((selectedItem != null) ? selectedItem.GetDefaultInstance(1) : null); } ItemInstance item = (ItemInstance)obj; if ((Object)(object)mixerItemForProductSlot.SelectedItem != (Object)null) { item = mixerItemForProductSlot.SelectedItem.GetDefaultInstance(1); } flag3 = HasSufficientItems(__instance, value2, item); flag2 = current.OutputSlot.Quantity == 0 && (float)current.ProductSlot.Quantity >= value2 && flag3; } if (DebugLogs.All || DebugLogs.Chemist) { DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(193, 12); defaultInterpolatedStringHandler.AppendLiteral("ChemistPatch.GetMixingStationsReadyToStart: Station "); defaultInterpolatedStringHandler.AppendFormatted<Guid>(((BuildableItem)current).GUID); defaultInterpolatedStringHandler.AppendLiteral(", Supply="); Guid? value3; if (val2 == null) { value3 = null; } else { BuildableItem selectedObject = val2.SelectedObject; value3 = ((selectedObject != null) ? new Guid?(selectedObject.GUID) : null); } defaultInterpolatedStringHandler.AppendFormatted(value3); defaultInterpolatedStringHandler.AppendLiteral(", IsInUse="); defaultInterpolatedStringHandler.AppendFormatted(((Component)current).GetComponent<IUsable>().IsInUse); defaultInterpolatedStringHandler.AppendLiteral(", CurrentMixOperation="); defaultInterpolatedStringHandler.AppendFormatted(current.CurrentMixOperation != null); defaultInterpolatedStringHandler.AppendLiteral(", canStartMix="); defaultInterpolatedStringHandler.AppendFormatted(flag); defaultInterpolatedStringHandler.AppendLiteral(", canRestock="); defaultInterpolatedStringHandler.AppendFormatted(flag2); defaultInterpolatedStringHandler.AppendLiteral(", mixQuantity="); defaultInterpolatedStringHandler.AppendFormatted(mixQuantity); defaultInterpolatedStringHandler.AppendLiteral(", productQuantity="); defaultInterpolatedStringHandler.AppendFormatted(current.ProductSlot.Quantity); defaultInterpolatedStringHandler.AppendLiteral(", outputQuantity="); defaultInterpolatedStringHandler.AppendFormatted(current.OutputSlot.Quantity); defaultInterpolatedStringHandler.AppendLiteral(", threshold="); defaultInterpolatedStringHandler.AppendFormatted(value2); defaultInterpolatedStringHandler.AppendLiteral(", mixerItem="); ItemDefinition selectedItem2 = mixerItemForProductSlot.SelectedItem; defaultInterpolatedStringHandler.AppendFormatted(((selectedItem2 != null) ? selectedItem2.Name : null) ?? "null"); defaultInterpolatedStringHandler.AppendFormatted(flag2 ? $", hasSufficientItems={flag3}" : ""); MelonLogger.Msg(defaultInterpolatedStringHandler.ToStringAndClear()); } if (flag || flag2) { val.Add(current); } } __result = val; if (DebugLogs.All || DebugLogs.Chemist) { MelonLogger.Msg($"ChemistPatch.GetMixingStationsReadyToStart: Found {val.Count} stations ready for {((__instance != null) ? ((Object)__instance).name : null) ?? "null"}"); } return false; } catch (Exception value4) { MelonLogger.Error($"ChemistPatch.GetMixingStationsReadyToStart: Failed for chemist: {((__instance != null) ? ((Object)__instance).name : null) ?? "null"}, error: {value4}"); __result = new List<MixingStation>(); return false; } } public static ItemDefinition GetAnyMixer(ITransitEntity supply, float threshold, string preferredId = null) { if (supply == null || supply.OutputSlots == null) { if (DebugLogs.All || DebugLogs.Chemist) { MelonLogger.Warning("GetAnyMixer: Supply or OutputSlots is null"); } return null; } List<PropertyItemDefinition> validItems = NoLazyUtilities.ConvertList<PropertyItemDefinition>(NetworkSingleton<ProductManager>.Instance.ValidMixIngredients); IEnumerable<ItemSlot> source = NoLazyUtilities.ConvertList<ItemSlot>(supply.OutputSlots).Where(delegate(ItemSlot s) { ItemSlot obj = s; return ((obj != null) ? obj.ItemInstance : null) != null && validItems.Any((PropertyItemDefinition v) => ((ItemDefinition)v).ID.ToLower() == s.ItemInstance.ID.ToLower()) && (float)s.Quantity >= threshold; }); if (preferredId != null) { ItemSlot val = source.FirstOrDefault((Func<ItemSlot, bool>)((ItemSlot s) => s.ItemInstance.ID.ToLower() == preferredId.ToLower())); if (val != null) { if (DebugLogs.All || DebugLogs.Chemist) { MelonLogger.Msg($"GetAnyMixer: Selected preferred item {preferredId} with quantity={val.Quantity}"); } return val.ItemInstance.definition; } } ItemSlot val2 = source.FirstOrDefault(); if (val2 != null && (DebugLogs.All || DebugLogs.Chemist)) { MelonLogger.Msg($"GetAnyMixer: Selected first available item {val2.ItemInstance.ID} with quantity={val2.Quantity}"); } object result; if (val2 == null) { result = null; } else { ItemInstance itemInstance = val2.ItemInstance; result = ((itemInstance != null) ? itemInstance.definition : null); } return (ItemDefinition)result; } public static bool HasSufficientItems(Chemist chemist, float threshold, ItemInstance item) { return (float)NoLazyUtilities.GetAmountInInventoryAndSupply((NPC)(object)chemist, (item != null) ? item.definition : null) >= threshold; } } [HarmonyPatch(typeof(ChemistConfiguration))] public class ChemistConfigurationPatch { [HarmonyPostfix] [HarmonyPatch(/*Could not decode attribute arguments.*/)] private static void Postfix(ChemistConfiguration __instance) { try { Chemist chemist = __instance.chemist; } catch (Exception value) { MelonLogger.Error($"ChemistConfigurationPatch: Failed, error: {value}"); } } } [HarmonyPatch(typeof(StartMixingStationBehaviour))] public class StartMixingStationBehaviourPatch { private class StateData { public Coroutine WalkToSuppliesRoutine { get; set; } public Coroutine GrabRoutine { get; set; } public ItemDefinition TargetMixer { get; set; } public bool ClearMixerSlot { get; set; } public int QuantityToFetch { get; set; } public EState CurrentState { get; set; } public ObjectField LastSupply { get; set; } public bool CookPending { get; set; } public bool Any { get; set; } public float LastStateChangeTime { get; set; } } public enum EState { Idle, WalkingToSupplies, GrabbingSupplies, WalkingToStation, Cooking } [CompilerGenerated] private sealed class <GrabRoutine>d__13 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public StartMixingStationBehaviour __instance; public StateData state; private Chemist <chemist>5__1; private MixingStation <station>5__2; private ItemField <mixerItem>5__3; private ObjectField <mixerSupply>5__4; private string <reason>5__5; private Exception <e>5__6; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <GrabRoutine>d__13(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <chemist>5__1 = null; <station>5__2 = null; <mixerItem>5__3 = null; <mixerSupply>5__4 = null; <reason>5__5 = null; <e>5__6 = null; <>1__state = -2; } private bool MoveNext() { //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Expected O, but got Unknown //IL_0348: Unknown result type (might be due to invalid IL or missing references) //IL_0297: Unknown result type (might be due to invalid IL or missing references) //IL_02a1: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <chemist>5__1 = __instance.chemist; <station>5__2 = __instance.targetStation; <mixerItem>5__3 = ChemistExtensions.GetMixerItemForProductSlot(<station>5__2); <mixerSupply>5__4 = MixingStationExtensions.Supply[((BuildableItem)<station>5__2).GUID]; if (!IsStationValid(__instance, <station>5__2, <mixerItem>5__3, <mixerSupply>5__4, <chemist>5__1, out <reason>5__5)) { if (DebugLogs.All || DebugLogs.Chemist) { MelonLogger.Msg("StartMixingStationBehaviourPatch.GrabRoutine: Station invalid before grab (reason=" + <reason>5__5 + "), disabling"); } Disable(__instance); return false; } <>2__current = (object)new WaitForSeconds(0.1f); <>1__state = 1; return true; case 1: <>1__state = -1; try { Avatar avatar = ((NPC)<chemist>5__1).Avatar; if ((Object)(object)((avatar != null) ? avatar.Anim : null) != (Object)null) { ((NPC)<chemist>5__1).Avatar.Anim.ResetTrigger("GrabItem"); ((NPC)<chemist>5__1).Avatar.Anim.SetTrigger("GrabItem"); if (DebugLogs.All || DebugLogs.Chemist) { Chemist obj2 = <chemist>5__1; MelonLogger.Msg("StartMixingStationBehaviourPatch.GrabRoutine: Triggered GrabItem animation for " + ((obj2 != null) ? ((NPC)obj2).fullName : null)); } } else if (DebugLogs.All || DebugLogs.Chemist) { Chemist obj3 = <chemist>5__1; MelonLogger.Warning("StartMixingStationBehaviourPatch.GrabRoutine: Animator missing for " + ((obj3 != null) ? ((NPC)obj3).fullName : null) + ", skipping animation"); } } catch (Exception ex) { <e>5__6 = ex; DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(66, 2); defaultInterpolatedStringHandler.AppendLiteral("StartMixingStationBehaviourPatch.GrabRoutine: Failed for "); Chemist obj4 = <chemist>5__1; defaultInterpolatedStringHandler.AppendFormatted((obj4 != null) ? ((NPC)obj4).fullName : null); defaultInterpolatedStringHandler.AppendLiteral(", error: "); defaultInterpolatedStringHandler.AppendFormatted(<e>5__6); MelonLogger.Error(defaultInterpolatedStringHandler.ToStringAndClear()); Disable(__instance); if (DebugLogs.All || DebugLogs.Chemist) { Chemist obj5 = <chemist>5__1; MelonLogger.Warning("StartMixingStationBehaviourPatch.GrabRoutine: Reverted to Idle due to error for " + ((obj5 != null) ? ((NPC)obj5).fullName : null)); } return false; } <>2__current = (object)new WaitForSeconds(0.1f); <>1__state = 2; return true; case 2: <>1__state = -1; if (!IsStationValid(__instance, <station>5__2, <mixerItem>5__3, <mixerSupply>5__4, <chemist>5__1, out <reason>5__5)) { if (DebugLogs.All || DebugLogs.Chemist) { MelonLogger.Msg("StartMixingStationBehaviourPatch.GrabRoutine: Station invalid after grab (reason=" + <reason>5__5 + "), disabling"); } Disable(__instance); return false; } state.GrabRoutine = null; state.CurrentState = EState.WalkingToStation; ((Behaviour)__instance).SetDestination(GetStationAccessPoint(__instance), true); if (DebugLogs.All || DebugLogs.Chemist) { DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(102, 2); defaultInterpolatedStringHandler.AppendLiteral("StartMixingStationBehaviourPatch.GrabRoutine: Grab complete, walking to station for "); Chemist obj = <chemist>5__1; defaultInterpolatedStringHandler.AppendFormatted((obj != null) ? ((NPC)obj).fullName : null); defaultInterpolatedStringHandler.AppendLiteral(", productQuantity="); defaultInterpolatedStringHandler.AppendFormatted(<station>5__2.ProductSlot.Quantity); MelonLogger.Msg(defaultInterpolatedStringHandler.ToStringAndClear()); } return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <WalkRoutine>d__12 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public StartMixingStationBehaviour __instance; public ITransitEntity supply; public StateData state; private Chemist <chemist>5__1; private MixingStation <station>5__2; private Vector3 <startPos>5__3; private float <timeout>5__4; private float <elapsed>5__5; private ItemField <mixerItem>5__6; private ObjectField <mixerSupply>5__7; private string <reason>5__8; private bool <atSupplies>5__9; private Vector3 <chemistPos>5__10; private Vector3 <supplyPos>5__11; private float <distanceMoved>5__12; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <WalkRoutine>d__12(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <chemist>5__1 = null; <station>5__2 = null; <mixerItem>5__6 = null; <mixerSupply>5__7 = null; <reason>5__8 = null; <>1__state = -2; } private bool MoveNext() { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: 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_0102: Expected O, but got Unknown //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_02e0: Unknown result type (might be due to invalid IL or missing references) //IL_02e5: Unknown result type (might be due to invalid IL or missing references) //IL_030a: Unknown result type (might be due to invalid IL or missing references) //IL_02f3: Unknown result type (might be due to invalid IL or missing references) //IL_030f: Unknown result type (might be due to invalid IL or missing references) //IL_0316: Unknown result type (might be due to invalid IL or missing references) //IL_031c: Unknown result type (might be due to invalid IL or missing references) //IL_038a: Unknown result type (might be due to invalid IL or missing references) //IL_03a5: Unknown result type (might be due to invalid IL or missing references) switch (<>1__state) { default: return false; case 0: <>1__state = -1; <chemist>5__1 = __instance.chemist; <station>5__2 = __instance.targetStation; <startPos>5__3 = ((Component)<chemist>5__1).transform.position; ((Behaviour)__instance).SetDestination(supply, true); if (DebugLogs.All || DebugLogs.Chemist) { DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(77, 2); defaultInterpolatedStringHandler.AppendLiteral("StartMixingStationBehaviourPatch.WalkRoutine: Set destination for "); Chemist obj = <chemist>5__1; defaultInterpolatedStringHandler.AppendFormatted((obj != null) ? ((NPC)obj).fullName : null); defaultInterpolatedStringHandler.AppendLiteral(", IsMoving="); defaultInterpolatedStringHandler.AppendFormatted(((NPC)<chemist>5__1).Movement.IsMoving); MelonLogger.Msg(defaultInterpolatedStringHandler.ToStringAndClear()); } <>2__current = (object)new WaitForSeconds(0.1f); <>1__state = 1; return true; case 1: <>1__state = -1; <timeout>5__4 = 10f; <elapsed>5__5 = 0f; break; case 2: <>1__state = -1; <elapsed>5__5 += Time.deltaTime; <mixerItem>5__6 = null; <mixerSupply>5__7 = null; <reason>5__8 = null; break; } if (((NPC)<chemist>5__1).Movement.IsMoving && <elapsed>5__5 < <timeout>5__4) { <mixerItem>5__6 = ChemistExtensions.GetMixerItemForProductSlot(<station>5__2); <mixerSupply>5__7 = MixingStationExtensions.Supply[((BuildableItem)<station>5__2).GUID]; if (!IsStationValid(__instance, <station>5__2, <mixerItem>5__6, <mixerSupply>5__7, <chemist>5__1, out <reason>5__8)) { if (DebugLogs.All || DebugLogs.Chemist) { MelonLogger.Msg("StartMixingStationBehaviourPatch.WalkRoutine: Station invalid during walk (reason=" + <reason>5__8 + "), disabling"); } Disable(__instance); return false; } <>2__current = null; <>1__state = 2; return true; } if (<elapsed>5__5 >= <timeout>5__4) { Disable(__instance); if (DebugLogs.All || DebugLogs.Chemist) { Chemist obj2 = <chemist>5__1; MelonLogger.Warning("StartMixingStationBehaviourPatch.WalkRoutine: Timeout walking to supply for " + ((obj2 != null) ? ((NPC)obj2).fullName : null)); } } state.WalkToSuppliesRoutine = null; state.CurrentState = EState.Idle; if (DebugLogs.All || DebugLogs.Chemist) { <atSupplies>5__9 = IsAtSupplies(__instance); <chemistPos>5__10 = ((Component)<chemist>5__1).transform.position; <supplyPos>5__11 = ((supply != null) ? ((Component)((Il2CppObjectBase)supply).TryCast<BuildableItem>()).transform.position : Vector3.zero); <distanceMoved>5__12 = Vector3.Distance(<startPos>5__3, <chemistPos>5__10); DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(179, 8); defaultInterpolatedStringHandler.AppendLiteral("StartMixingStationBehaviourPatch.WalkRoutine: Completed walk to supply, reverting to Idle for "); Chemist obj3 = <chemist>5__1; defaultInterpolatedStringHandler.AppendFormatted((obj3 != null) ? ((NPC)obj3).fullName : null); defaultInterpolatedStringHandler.AppendLiteral(". AtSupplies="); defaultInterpolatedStringHandler.AppendFormatted(<atSupplies>5__9); defaultInterpolatedStringHandler.AppendLiteral(", ChemistPos="); defaultInterpolatedStringHandler.AppendFormatted<Vector3>(<chemistPos>5__10); defaultInterpolatedStringHandler.AppendLiteral(", SupplyPos="); defaultInterpolatedStringHandler.AppendFormatted<Vector3>(<supplyPos>5__11); defaultInterpolatedStringHandler.AppendLiteral(", DistanceMoved="); defaultInterpolatedStringHandler.AppendFormatted(<distanceMoved>5__12); defaultInterpolatedStringHandler.AppendLiteral(", Elapsed="); defaultInterpolatedStringHandler.AppendFormatted(<elapsed>5__5); defaultInterpolatedStringHandler.AppendLiteral(", Timeout="); defaultInterpolatedStringHandler.AppendFormatted(<elapsed>5__5 >= <timeout>5__4); defaultInterpolatedStringHandler.AppendLiteral(", IsMoving="); defaultInterpolatedStringHandler.AppendFormatted(((NPC)<chemist>5__1).Movement.IsMoving); MelonLogger.Msg(defaultInterpolatedStringHandler.ToStringAndClear()); } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static readonly Dictionary<StartMixingStationBehaviour, StateData> states = new Dictionary<StartMixingStationBehaviour, StateData>(); private static bool IsStationValid(StartMixingStationBehaviour __instance, MixingStation station, ItemField mixerItem, ObjectField mixerSupply, Chemist chemist, out string reason) { //IL_04b4: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_03dc: Unknown result type (might be due to invalid IL or missing references) reason = ""; try { if ((Object)(object)station == (Object)null || (Object)(object)chemist == (Object)null || mixerItem == null || mixerSupply == null) { reason = $"Invalid components: station={(Object)(object)station != (Object)null}, chemist={(Object)(object)chemist != (Object)null}, mixerItem={mixerItem != null}, mixerSupply={mixerSupply != null}"; return false; } if (station.ProductSlot == null || station.MixerSlot == null || station.OutputSlot == null) { reason = $"Invalid station slots: ProductSlot={station.ProductSlot != null}, MixerSlot={station.MixerSlot != null}, OutputSlot={station.OutputSlot != null}"; return false; } MixingStationConfiguration obj = MixingStationExtensions.Config[((BuildableItem)station).GUID]; float num = ((obj != null) ? obj.StartThrehold.Value : 0f); int quantity = station.MixerSlot.Quantity; int quantity2 = station.ProductSlot.Quantity; int quantity3 = station.OutputSlot.Quantity; bool flag = station.ProductSlot.ItemInstance != null && Object.op_Implicit((Object)(object)((Il2CppObjectBase)station.ProductSlot.ItemInstance.Definition).TryCast<ProductDefinition>()); bool flag2 = (float)quantity >= num && (float)quantity2 >= num && quantity3 == 0 && flag; bool flag3 = false; if (!flag2 && flag && quantity3 == 0 && (float)quantity2 >= num && (Object)(object)mixerItem.SelectedItem != (Object)null) { ItemInstance defaultInstance = mixerItem.SelectedItem.GetDefaultInstance(1); int num2 = ((NPC)chemist).Inventory._GetItemAmount(mixerItem.SelectedItem.ID); int num3 = (((Object)(object)mixerSupply.SelectedObject != (Object)null) ? NoLazyUtilities.GetAmountInSupply((NPC)(object)chemist, defaultInstance) : 0); bool flag4 = defaultInstance != null && (float)(num2 + num3) >= num; flag3 = flag4; if (DebugLogs.All || DebugLogs.Chemist) { MelonLogger.Msg($"StartMixingStationBehaviourPatch.IsStationValid: canRestock check: inventoryCount={num2}, supplyCount={num3}, hasSufficientItems={flag4}"); } } bool flag5 = flag2 || flag3; reason = (flag5 ? "Valid" : $"canStartMix={flag2} (mixQuantity={quantity}, productQuantity={quantity2}, outputQuantity={quantity3}, threshold={num}, productValid={flag}), canRestock={flag3}"); if (DebugLogs.All || DebugLogs.Chemist) { MelonLogger.Msg($"StartMixingStationBehaviourPatch.IsStationValid: Station={((BuildableItem)station).GUID}, chemist={((NPC)chemist).fullName}, isValid={flag5}, reason={reason}"); } return flag5; } catch (Exception ex) { reason = "Exception: " + ex.Message; MelonLogger.Error($"StartMixingStationBehaviourPatch.IsStationValid: Failed for chemist: {((chemist != null) ? ((NPC)chemist).fullName : null) ?? "null"}, station: {((station != null) ? new Guid?(((BuildableItem)station).GUID) : null)}, error: {ex}"); return false; } } [HarmonyPatch("Awake")] [HarmonyPostfix] private static void AwakePostfix(StartMixingStationBehaviour __instance) { try { states[__instance] = new StateData { CurrentState = EState.Idle, WalkToSuppliesRoutine = null, GrabRoutine = null, TargetMixer = null, ClearMixerSlot = false, QuantityToFetch = 0, LastSupply = null, CookPending = false, Any = false }; if (DebugLogs.All || DebugLogs.Chemist) { Chemist chemist = __instance.chemist; MelonLogger.Msg("StartMixingStationBehaviourPatch.Awake: Initialized state for " + (((chemist != null) ? ((NPC)chemist).fullName : null) ?? "null")); } } catch (Exception value) { DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(69, 2); defaultInterpolatedStringHandler.AppendLiteral("StartMixingStationBehaviourPatch.Awake: Failed for chemist: "); Chemist chemist2 = __instance.chemist; defaultInterpolatedStringHandler.AppendFormatted(((chemist2 != null) ? ((NPC)chemist2).fullName : null) ?? "null"); defaultInterpolatedStringHandler.AppendLiteral(", error: "); defaultInterpolatedStringHandler.AppendFormatted(value); MelonLogger.Error(defaultInterpolatedStringHandler.ToStringAndClear()); } } [HarmonyPatch("ActiveMinPass")] [HarmonyPrefix] private static bool Prefix(StartMixingStationBehaviour __instance) { //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0228: Unknown result type (might be due to invalid IL or missing references) //IL_03c0: Unknown result type (might be due to invalid IL or missing references) //IL_04f5: Unknown result type (might be due to invalid IL or missing references) //IL_16d8: Unknown result type (might be due to invalid IL or missing references) //IL_0914: Unknown result type (might be due to invalid IL or missing references) //IL_100c: Unknown result type (might be due to invalid IL or missing references) //IL_0c4d: Unknown result type (might be due to invalid IL or missing references) try { if (!InstanceFinder.IsServer) { if (DebugLogs.All || DebugLogs.Chemist) { MelonLogger.Msg("StartMixingStationBehaviourPatch.ActiveMinPass: Skipping, not server"); } return false; } Chemist chemist = __instance.chemist; MixingStation targetStation = __instance.targetStation; if ((Object)(object)targetStation == (Object)null || (Object)(object)chemist == (Object)null) { Disable(__instance); if (DebugLogs.All || DebugLogs.Chemist) { MelonLogger.Warning("StartMixingStationBehaviourPatch.ActiveMinPass: Station or Chemist null for chemist: " + (((chemist != null) ? ((NPC)chemist).fullName : null) ?? "null")); } return false; } if (!states.TryGetValue(__insta