Some mods target the Mono version of the game, which is available by opting into the Steam beta branch "alternate"
Decompiled source of EmployeeTweaks v1.0.1
EmployeeTweaks-IL2CPP.dll
Decompiled a day 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.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using EmployeeTweaks; using EmployeeTweaks.Helpers; using EmployeeTweaks.Patches.EmployeeArea; using EmployeeTweaks.Patches.FilterItemApply; using EmployeeTweaks.Patches.Unpackaging; using EmployeeTweaks.Persistence; using HarmonyLib; using Il2CppFishNet; using Il2CppFishNet.Connection; using Il2CppFishNet.Object; using Il2CppInterop.Runtime; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppScheduleOne; using Il2CppScheduleOne.Core.Items.Framework; using Il2CppScheduleOne.Effects; using Il2CppScheduleOne.Employees; using Il2CppScheduleOne.EntityFramework; using Il2CppScheduleOne.Growing; using Il2CppScheduleOne.ItemFramework; using Il2CppScheduleOne.Management; using Il2CppScheduleOne.NPCs; using Il2CppScheduleOne.NPCs.Behaviour; using Il2CppScheduleOne.ObjectScripts; using Il2CppScheduleOne.PlayerScripts; using Il2CppScheduleOne.Product; using Il2CppScheduleOne.Property; using Il2CppScheduleOne.Tiles; using Il2CppScheduleOne.Tools; using Il2CppScheduleOne.UI.Items; using Il2CppScheduleOne.UI.Management; using Il2CppSystem; using Il2CppSystem.Collections.Generic; using Il2CppTMPro; using MelonLoader; using MelonLoader.Preferences; using Microsoft.CodeAnalysis; using S1API.Entities; using S1API.Internal.Abstraction; using S1API.Saveables; 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(global::EmployeeTweaks.EmployeeTweaks), "EmployeeTweaks", "1.0.1", "k073l", null)] [assembly: MelonColor(1, 217, 131, 36)] [assembly: MelonGame("TVGS", "Schedule I")] [assembly: MelonPlatformDomain(/*Could not decode attribute arguments.*/)] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("EmployeeTweaks-IL2CPP")] [assembly: AssemblyConfiguration("IL2CPP")] [assembly: AssemblyDescription("Various employee tweaks - unpackaging, sprinkler/pourer use and more")] [assembly: AssemblyFileVersion("1.0.1.0")] [assembly: AssemblyInformationalVersion("1.0.1+43b19f4c286c6c638d50bfc07f2457e9ad1f5e07")] [assembly: AssemblyProduct("EmployeeTweaks-IL2CPP")] [assembly: AssemblyTitle("EmployeeTweaks-IL2CPP")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.1.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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [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 EmployeeTweaks { public static class BuildInfo { public const string Name = "EmployeeTweaks"; public const string Description = "Various employee tweaks - unpackaging, sprinkler/pourer use and more"; public const string Author = "k073l"; public const string Version = "1.0.1"; } public class EmployeeTweaks : MelonMod { private static Instance Logger; private DebugAreaDrawer debugAreaDrawer; private bool _lastShift; private bool _lastCtrl; internal static MelonPreferences_Category EmployeeCapacityCategory = MelonPreferences.CreateCategory("EmployeeTweaksEmployeeCapacity", "Employee Capacities"); internal static MelonPreferences_Entry<bool> EnableCapacityAndDebug = EmployeeCapacityCategory.CreateEntry<bool>("EmployeeTweaksEnableCapacityAndDebug", true, "Enable Category", "Enables employee capacity tweaks and drawing employee idle points area", false, false, (ValueValidator)null, (string)null); internal static MelonPreferences_Entry<bool> DrawDebugArea = EmployeeCapacityCategory.CreateEntry<bool>("EmployeeTweaksDrawDebugArea", false, "Draw Debug Area", "Draws a debug area where employee idle points are contained", false, false, (ValueValidator)null, (string)null); internal static HashSet<MelonPreferences_Entry<int>> EmployeeCapacities = new HashSet<MelonPreferences_Entry<int>>(); public override void OnInitializeMelon() { Logger = ((MelonBase)this).LoggerInstance; Logger.Msg("EmployeeTweaks initialized"); MoveItemBehaviourPatches.ManualPatchDestinationValid(((MelonBase)this).HarmonyInstance); debugAreaDrawer = new DebugAreaDrawer(); Player.LocalPlayerSpawned += delegate { debugAreaDrawer.Draw(); }; ((MelonEventBase<LemonAction<bool, bool>>)(object)DrawDebugArea.OnEntryValueChanged).Subscribe((LemonAction<bool, bool>)delegate { debugAreaDrawer.Draw(); }, 0, false); } public override void OnLateUpdate() { TextMeshProUGUI applyItemAsFilterButtonText = FilterConfigPanelPatches.ApplyItemAsFilterButtonText; if (!((Object)(object)applyItemAsFilterButtonText == (Object)null)) { bool flag = Input.GetKey((KeyCode)304) || Input.GetKey((KeyCode)303); bool flag2 = Input.GetKey((KeyCode)306) || Input.GetKey((KeyCode)305); if (flag != _lastShift || flag2 != _lastCtrl) { _lastShift = flag; _lastCtrl = flag2; FilterConfigPanelPatches.AllSlots = flag; FilterConfigPanelPatches.DenyListMode = flag2; ((TMP_Text)applyItemAsFilterButtonText).text = (flag ? "Apply All As Filters" : "Apply Item As Filter"); } } } } } namespace EmployeeTweaks.Persistence { public class UnpackageSave : Saveable { [SaveableField("UnpackageStations")] public Dictionary<Guid, bool> UnpackageStations = new Dictionary<Guid, bool>(); private static UnpackageSave _instance; public static UnpackageSave Instance => _instance ?? (_instance = new UnpackageSave()); public UnpackageSave() { _instance = this; } public bool TryGetValue(Guid guid, out bool value) { Guid key = Guid.Parse(((object)(Guid)(ref guid)).ToString()); return UnpackageStations.TryGetValue(key, out value); } public bool TryGetValue(Guid guid, out bool value) { return UnpackageStations.TryGetValue(guid, out value); } } } namespace EmployeeTweaks.Patches.Unpackaging { [HarmonyPatch(typeof(AdvancedTransitRoute))] internal static class AdvancedTransitRoutePatch { [HarmonyPatch("GetItemReadyToMove")] [HarmonyPrefix] private static bool GetItemReadyToMove(AdvancedTransitRoute __instance, ref ItemInstance __result) { //IL_009e: Unknown result type (might be due to invalid IL or missing references) if (((TransitRoute)__instance).Source == null || ((TransitRoute)__instance).Destination == null) { return true; } if (((TransitRoute)__instance).Destination == null) { return true; } ITransitEntity destination = ((TransitRoute)__instance).Destination; PackagingStation result; bool flag = Utils.Is2<PackagingStation>((object)destination, out result) && (Object)(object)result != (Object)null; ITransitEntity source = ((TransitRoute)__instance).Source; PackagingStation result2; bool flag2 = Utils.Is2<PackagingStation>((object)source, out result2) && (Object)(object)result2 != (Object)null; if (!flag && !flag2) { return true; } PackagingStation val = (flag ? result : result2); UnpackageSave.Instance.TryGetValue(((BuildableItem)val).GUID, out var value); if (!value) { return true; } if (flag) { Enumerator<ItemSlot> enumerator = ((TransitRoute)__instance).Source.OutputSlots.GetEnumerator(); while (enumerator.MoveNext()) { ItemSlot current = enumerator.Current; if (current.ItemInstance != null && __instance.Filter.DoesItemMeetFilter(current.ItemInstance)) { int outputCapacityForItem = destination.GetOutputCapacityForItem(current.ItemInstance, (NPC)null); if (outputCapacityForItem > 0) { __result = current.ItemInstance.GetCopy(Mathf.Min(outputCapacityForItem, ((BaseItemInstance)current.ItemInstance).Quantity)); return false; } } } } else { Enumerator<ItemSlot> enumerator2 = ((TransitRoute)__instance).Source.InputSlots.GetEnumerator(); while (enumerator2.MoveNext()) { ItemSlot current2 = enumerator2.Current; if (current2.ItemInstance != null && __instance.Filter.DoesItemMeetFilter(current2.ItemInstance)) { int inputCapacityForItem = destination.GetInputCapacityForItem(current2.ItemInstance, (NPC)null, true); if (inputCapacityForItem > 0) { __result = current2.ItemInstance.GetCopy(Mathf.Min(inputCapacityForItem, ((BaseItemInstance)current2.ItemInstance).Quantity)); return false; } } } } __result = null; return false; } } [HarmonyPatch(typeof(MoveItemBehaviour))] internal static class MoveItemBehaviourPatches { [CompilerGenerated] private sealed class <>c__DisplayClass7_0 { public MoveItemBehaviour __instance; } [CompilerGenerated] private sealed class <>c__DisplayClass9_0 { public MoveItemBehaviour __instance; public bool destIsStation; public ITransitEntity dest; } private static Dictionary<MoveItemBehaviour, object> customGrabRunning = new Dictionary<MoveItemBehaviour, object>(); private static Dictionary<MoveItemBehaviour, object> customPlaceRunning = new Dictionary<MoveItemBehaviour, object>(); internal static void ManualPatchDestinationValid(Harmony harmony) { //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Expected O, but got Unknown //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Expected O, but got Unknown MethodInfo methodInfo = AccessTools.Method(typeof(MoveItemBehaviour), "IsDestinationValid", new Type[3] { typeof(TransitRoute), typeof(ItemInstance), typeof(string).MakeByRefType() }, (Type[])null); if (methodInfo == null) { MelonLogger.Error("Failed to find IsDestinationValid method!"); return; } harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(MoveItemBehaviourPatches), "IsDestinationValid", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); MethodInfo methodInfo2 = AccessTools.Method(typeof(MoveItemBehaviour), "IsTransitRouteValid", new Type[3] { typeof(TransitRoute), typeof(string), typeof(string).MakeByRefType() }, (Type[])null); if (methodInfo2 == null) { MelonLogger.Error("Failed to find IsTransitRouteValid method!"); } else { harmony.Patch((MethodBase)methodInfo2, new HarmonyMethod(typeof(MoveItemBehaviourPatches), "IsTransitRouteValidID", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } private static bool IsDestinationValid(MoveItemBehaviour __instance, TransitRoute route, ItemInstance item, ref string invalidReason, ref bool __result) { //IL_0093: Unknown result type (might be due to invalid IL or missing references) invalidReason = string.Empty; if (((route != null) ? route.Destination : null) == null) { __result = false; return true; } ITransitEntity destination = route.Destination; PackagingStation result; bool flag = Utils.Is2<PackagingStation>((object)destination, out result) && (Object)(object)result != (Object)null; ITransitEntity source = route.Source; PackagingStation result2; bool flag2 = Utils.Is2<PackagingStation>((object)source, out result2) && (Object)(object)result2 != (Object)null; if (!flag && !flag2) { __result = false; return true; } PackagingStation val = (flag ? result : result2); UnpackageSave.Instance.TryGetValue(((BuildableItem)val).GUID, out var value); if (!value) { __result = false; return true; } if (!__instance.CanGetToDestination(route)) { invalidReason = "Cannot get to destination!"; __result = false; return false; } if (!__instance.CanGetToSource(route)) { invalidReason = "Cannot get to source!"; __result = false; return false; } if ((flag ? destination.GetOutputCapacityForItem(item, ((Behaviour)__instance).Npc) : destination.GetInputCapacityForItem(item, ((Behaviour)__instance).Npc, true)) == 0) { invalidReason = "Destination has no capacity for item!"; __result = false; return false; } __result = true; return false; } private static bool IsTransitRouteValidID(MoveItemBehaviour __instance, TransitRoute route, string itemID, ref string invalidReason, ref bool __result) { //IL_0099: Unknown result type (might be due to invalid IL or missing references) invalidReason = string.Empty; if (((route != null) ? route.Destination : null) == null || route.Source == null) { __result = false; return true; } ITransitEntity destination = route.Destination; PackagingStation result; bool flag = Utils.Is2<PackagingStation>((object)destination, out result) && (Object)(object)result != (Object)null; ITransitEntity source = route.Source; PackagingStation result2; bool flag2 = Utils.Is2<PackagingStation>((object)source, out result2) && (Object)(object)result2 != (Object)null; if (!flag && !flag2) { return true; } PackagingStation val = (flag ? result : result2); UnpackageSave.Instance.TryGetValue(((BuildableItem)val).GUID, out var value); if (!value) { __result = false; return true; } if (!route.AreEntitiesNonNull()) { invalidReason = "Entities are null!"; __result = false; return false; } ItemSlot firstSlotContainingItem = source.GetFirstSlotContainingItem(itemID, (ESlotType)((!flag2) ? 1 : 0)); ItemInstance val2 = ((firstSlotContainingItem != null) ? firstSlotContainingItem.ItemInstance : null); if (val2 == null || ((BaseItemInstance)val2).Quantity <= 0) { invalidReason = "Item is null or quantity is 0!"; __result = false; return false; } if (!__instance.IsDestinationValid(route, val2, ref invalidReason)) { __result = false; return false; } __result = true; return false; } [HarmonyPatch("IsNpcInventoryItemValid")] [HarmonyPrefix] private static bool CheckNpcInventoryItemValid(MoveItemBehaviour __instance, ItemInstance item, ref bool __result) { //IL_0092: Unknown result type (might be due to invalid IL or missing references) TransitRoute assignedRoute = __instance.assignedRoute; if (((assignedRoute != null) ? assignedRoute.Destination : null) == null) { return true; } ITransitEntity destination = __instance.assignedRoute.Destination; PackagingStation result; bool flag = Utils.Is2<PackagingStation>((object)destination, out result) && (Object)(object)result != (Object)null; ITransitEntity source = __instance.assignedRoute.Source; PackagingStation result2; bool flag2 = Utils.Is2<PackagingStation>((object)source, out result2) && (Object)(object)result2 != (Object)null; if (!flag && !flag2) { return true; } PackagingStation val = (flag ? result : result2); UnpackageSave.Instance.TryGetValue(((BuildableItem)val).GUID, out var value); if (!value) { return true; } if (flag) { if (destination.GetOutputCapacityForItem(item, ((Behaviour)__instance).Npc) == 0) { __result = false; return false; } } else if (destination.GetInputCapacityForItem(item, ((Behaviour)__instance).Npc, true) == 0) { __result = false; return false; } __result = true; return false; } [HarmonyPatch("GetAmountToGrab")] [HarmonyPrefix] private static bool GetAmountToGrab(MoveItemBehaviour __instance, ref int __result) { //IL_0092: Unknown result type (might be due to invalid IL or missing references) TransitRoute assignedRoute = __instance.assignedRoute; if (((assignedRoute != null) ? assignedRoute.Destination : null) == null) { return true; } ITransitEntity destination = __instance.assignedRoute.Destination; PackagingStation result; bool flag = Utils.Is2<PackagingStation>((object)destination, out result) && (Object)(object)result != (Object)null; ITransitEntity source = __instance.assignedRoute.Source; PackagingStation result2; bool flag2 = Utils.Is2<PackagingStation>((object)source, out result2) && (Object)(object)result2 != (Object)null; if (!flag && !flag2) { return true; } PackagingStation val = (flag ? result : result2); UnpackageSave.Instance.TryGetValue(((BuildableItem)val).GUID, out var value); if (!value) { return true; } ItemSlot firstSlotContainingTemplateItem = __instance.assignedRoute.Source.GetFirstSlotContainingTemplateItem(__instance.itemToRetrieveTemplate, (ESlotType)(flag ? 1 : 0)); ItemInstance val2 = ((firstSlotContainingTemplateItem != null) ? firstSlotContainingTemplateItem.ItemInstance : null); if (val2 == null) { __result = 0; return false; } int num = ((BaseItemInstance)val2).Quantity; if (__instance.maxMoveAmount > 0) { num = Mathf.Min(__instance.maxMoveAmount, num); } int num2 = (flag ? destination.GetOutputCapacityForItem(val2, ((Behaviour)__instance).Npc) : destination.GetInputCapacityForItem(val2, ((Behaviour)__instance).Npc, true)); __result = Mathf.Min(num, num2); return false; } [HarmonyPatch("GrabItem")] [HarmonyPrefix] private static bool GrabItem(MoveItemBehaviour __instance) { //IL_00b0: Unknown result type (might be due to invalid IL or missing references) <>c__DisplayClass7_0 CS$<>8__locals0 = new <>c__DisplayClass7_0(); CS$<>8__locals0.__instance = __instance; TransitRoute assignedRoute = CS$<>8__locals0.__instance.assignedRoute; if (((assignedRoute != null) ? assignedRoute.Source : null) == null) { return true; } ITransitEntity destination = CS$<>8__locals0.__instance.assignedRoute.Destination; PackagingStation result; bool flag = Utils.Is2<PackagingStation>((object)destination, out result) && (Object)(object)result != (Object)null; ITransitEntity source = CS$<>8__locals0.__instance.assignedRoute.Source; PackagingStation result2; bool flag2 = Utils.Is2<PackagingStation>((object)source, out result2) && (Object)(object)result2 != (Object)null; if (!flag && !flag2) { return true; } PackagingStation val = (flag ? result : result2); UnpackageSave.Instance.TryGetValue(((BuildableItem)val).GUID, out var value); if (!value) { return true; } if (flag) { return true; } if (((Behaviour)CS$<>8__locals0.__instance).beh.DEBUG_MODE) { Console.Log(Object.op_Implicit("MoveItemBehaviour.GrabItem"), (Object)null); } CS$<>8__locals0.__instance.currentState = (EState)2; CS$<>8__locals0.__instance.grabRoutine = null; object value2 = MelonCoroutines.Start(Routine()); customGrabRunning[CS$<>8__locals0.__instance] = value2; return false; [IteratorStateMachine(typeof(<>c__DisplayClass7_0.<<GrabItem>g__Routine|0>d))] IEnumerator Routine() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <>c__DisplayClass7_0.<<GrabItem>g__Routine|0>d(0) { <>4__this = CS$<>8__locals0 }; } } [HarmonyPatch("TakeItem")] [HarmonyPrefix] private static bool TakeItem(MoveItemBehaviour __instance) { //IL_0092: Unknown result type (might be due to invalid IL or missing references) TransitRoute assignedRoute = __instance.assignedRoute; if (((assignedRoute != null) ? assignedRoute.Destination : null) == null) { return true; } ITransitEntity destination = __instance.assignedRoute.Destination; PackagingStation result; bool flag = Utils.Is2<PackagingStation>((object)destination, out result) && (Object)(object)result != (Object)null; ITransitEntity source = __instance.assignedRoute.Source; PackagingStation result2; bool flag2 = Utils.Is2<PackagingStation>((object)source, out result2) && (Object)(object)result2 != (Object)null; if (!flag && !flag2) { return true; } PackagingStation val = (flag ? result : result2); UnpackageSave.Instance.TryGetValue(((BuildableItem)val).GUID, out var value); if (!value) { return true; } if (((Behaviour)__instance).beh.DEBUG_MODE) { Console.Log(Object.op_Implicit("MoveItemBehaviour.TakeItem"), (Object)null); } int amountToGrab = __instance.GetAmountToGrab(); if (amountToGrab == 0) { Console.LogWarning(Object.op_Implicit("Amount to grab is 0!"), (Object)null); return false; } ItemSlot firstSlotContainingTemplateItem = __instance.assignedRoute.Source.GetFirstSlotContainingTemplateItem(__instance.itemToRetrieveTemplate, (ESlotType)(flag ? 1 : 0)); if (((firstSlotContainingTemplateItem != null) ? firstSlotContainingTemplateItem.ItemInstance : null) == null) { return false; } ItemInstance copy = firstSlotContainingTemplateItem.ItemInstance.GetCopy(amountToGrab); __instance.grabbedAmount = amountToGrab; firstSlotContainingTemplateItem.ChangeQuantity(-amountToGrab, false); ((Behaviour)__instance).Npc.Inventory.InsertItem(copy, true); if (flag) { destination.ReserveOutputSlotsForItem(copy, ((NetworkBehaviour)((Behaviour)__instance).Npc).NetworkObject); } else { destination.ReserveInputSlotsForItem(copy, ((NetworkBehaviour)((Behaviour)__instance).Npc).NetworkObject); } return false; } [HarmonyPatch("PlaceItem")] [HarmonyPrefix] private static bool PlaceItem(MoveItemBehaviour __instance) { //IL_00c5: Unknown result type (might be due to invalid IL or missing references) <>c__DisplayClass9_0 CS$<>8__locals0 = new <>c__DisplayClass9_0(); CS$<>8__locals0.__instance = __instance; TransitRoute assignedRoute = CS$<>8__locals0.__instance.assignedRoute; if (((assignedRoute != null) ? assignedRoute.Destination : null) == null) { return true; } CS$<>8__locals0.dest = CS$<>8__locals0.__instance.assignedRoute.Destination; CS$<>8__locals0.destIsStation = Utils.Is2<PackagingStation>((object)CS$<>8__locals0.dest, out PackagingStation result) && (Object)(object)result != (Object)null; ITransitEntity source = CS$<>8__locals0.__instance.assignedRoute.Source; PackagingStation result2; bool flag = Utils.Is2<PackagingStation>((object)source, out result2) && (Object)(object)result2 != (Object)null; if (!CS$<>8__locals0.destIsStation && !flag) { return true; } PackagingStation val = (CS$<>8__locals0.destIsStation ? result : result2); UnpackageSave.Instance.TryGetValue(((BuildableItem)val).GUID, out var value); if (!value) { return true; } if (((Behaviour)CS$<>8__locals0.__instance).beh.DEBUG_MODE) { Console.Log(Object.op_Implicit("MoveItemBehaviour.PlaceItem"), (Object)null); } CS$<>8__locals0.__instance.currentState = (EState)4; CS$<>8__locals0.__instance.placingRoutine = null; object value2 = MelonCoroutines.Start(Routine()); customPlaceRunning[CS$<>8__locals0.__instance] = value2; return false; [IteratorStateMachine(typeof(<>c__DisplayClass9_0.<<PlaceItem>g__Routine|0>d))] IEnumerator Routine() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <>c__DisplayClass9_0.<<PlaceItem>g__Routine|0>d(0) { <>4__this = CS$<>8__locals0 }; } } [HarmonyPatch("StopCurrentActivity")] [HarmonyPrefix] private static bool StopCurrentActivity(MoveItemBehaviour __instance) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Invalid comparison between Unknown and I4 //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Invalid comparison between Unknown and I4 EState currentState = __instance.currentState; EState val = currentState; if ((int)val != 2) { if ((int)val == 4) { if (customPlaceRunning.TryGetValue(__instance, out var value)) { MelonCoroutines.Stop(value); customPlaceRunning.Remove(__instance); return false; } return true; } return true; } if (customGrabRunning.TryGetValue(__instance, out var value2)) { MelonCoroutines.Stop(value2); customGrabRunning.Remove(__instance); return false; } return true; } [HarmonyPatch("OnActiveTick")] [HarmonyPrefix] private static bool OnActiveTick(MoveItemBehaviour __instance) { //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Invalid comparison between Unknown and I4 //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) if (!InstanceFinder.IsServer) { return false; } if (!__instance.assignedRoute.AreEntitiesNonNull()) { Console.LogWarning(Object.op_Implicit("Transit route entities are null!"), (Object)null); ((Behaviour)__instance).Disable_Networked((NetworkConnection)null); return false; } if (((Behaviour)__instance).beh.DEBUG_MODE) { EState currentState = __instance.currentState; Console.Log(Object.op_Implicit("State: " + ((object)(EState)(ref currentState)).ToString()), (Object)null); Console.Log(Object.op_Implicit("Moving: " + ((Behaviour)__instance).Npc.Movement.IsMoving), (Object)null); } if ((int)__instance.currentState > 0) { return false; } if (((Behaviour)__instance).Npc.Inventory.GetIdenticalItemAmount(__instance.itemToRetrieveTemplate) > 0 && __instance.grabbedAmount > 0) { if (__instance.IsAtDestination()) { __instance.PlaceItem(); } else { __instance.WalkToDestination(); } } else if (__instance.skipPickup) { __instance.TakeItem(); __instance.skipPickup = false; } else if (__instance.IsAtSource()) { __instance.GrabItem(); } else { __instance.WalkToSource(); } return false; } [HarmonyPatch("StartTransit")] [HarmonyPrefix] private static bool StartTransit(MoveItemBehaviour __instance) { ITransitEntity destination = __instance.assignedRoute.Destination; PackagingStation result; bool flag = Utils.Is2<PackagingStation>((object)destination, out result) && (Object)(object)result != (Object)null; ITransitEntity source = __instance.assignedRoute.Source; PackagingStation result2; bool flag2 = Utils.Is2<PackagingStation>((object)source, out result2) && (Object)(object)result2 != (Object)null; if (!flag && !flag2) { return true; } DefaultInterpolatedStringHandler defaultInterpolatedStringHandler = new DefaultInterpolatedStringHandler(9, 4); defaultInterpolatedStringHandler.AppendFormatted(__instance.assignedRoute.Source.Name); defaultInterpolatedStringHandler.AppendLiteral(" -> "); defaultInterpolatedStringHandler.AppendFormatted(__instance.assignedRoute.Destination.Name); defaultInterpolatedStringHandler.AppendLiteral(" ("); ItemInstance itemToRetrieveTemplate = __instance.itemToRetrieveTemplate; defaultInterpolatedStringHandler.AppendFormatted((itemToRetrieveTemplate != null) ? ((BaseItemInstance)itemToRetrieveTemplate).ID : null); defaultInterpolatedStringHandler.AppendLiteral("x"); ItemInstance itemToRetrieveTemplate2 = __instance.itemToRetrieveTemplate; defaultInterpolatedStringHandler.AppendFormatted((itemToRetrieveTemplate2 != null) ? new int?(((BaseItemInstance)itemToRetrieveTemplate2).Quantity) : null); defaultInterpolatedStringHandler.AppendLiteral(")"); Console.Log(Object.op_Implicit(defaultInterpolatedStringHandler.ToStringAndClear()), (Object)null); if (!InstanceFinder.IsServer) { return false; } if (((Behaviour)__instance).Npc.Inventory.GetIdenticalItemAmount(__instance.itemToRetrieveTemplate) == 0) { ItemInstance itemToRetrieveTemplate3 = __instance.itemToRetrieveTemplate; if (((itemToRetrieveTemplate3 != null) ? ((BaseItemInstance)itemToRetrieveTemplate3).ID : null) == null) { return false; } string text = default(string); if (!__instance.IsTransitRouteValid(__instance.assignedRoute, ((BaseItemInstance)__instance.itemToRetrieveTemplate).ID, ref text)) { Console.LogWarning(Object.op_Implicit("Invalid transit route for move item behaviour by checking transit route!. Reason: " + text), (Object)null); ((Behaviour)__instance).Disable_Networked((NetworkConnection)null); return false; } } else { ItemFilter val = DelegateSupport.ConvertDelegate<ItemFilter>((Delegate)new Func<ItemInstance, bool>(__instance.IsNpcInventoryItemValid)); ItemInstance firstIdenticalItem = ((Behaviour)__instance).Npc.Inventory.GetFirstIdenticalItem(__instance.itemToRetrieveTemplate, val); if (((Behaviour)__instance).Npc.Behaviour.DEBUG_MODE) { Console.Log(Object.op_Implicit("Moving item: " + (object)firstIdenticalItem), (Object)null); } string text2 = default(string); if (!__instance.IsDestinationValid(__instance.assignedRoute, firstIdenticalItem, ref text2)) { Console.LogWarning(Object.op_Implicit("Invalid transit route for move item behaviour by checking destination! Reason: " + text2), (Object)null); ((Behaviour)__instance).Disable_Networked((NetworkConnection)null); return false; } } __instance.currentState = (EState)0; return false; } } [HarmonyPatch(typeof(Packager))] internal static class PackagerPatches { [HarmonyWrapSafe] [HarmonyPatch("GetStationMoveItems")] [HarmonyPrefix] private static bool GetStationMoveItems(Packager __instance, ref PackagingStation __result) { //IL_0054: Unknown result type (might be due to invalid IL or missing references) Enumerator<PackagingStation> enumerator = __instance.configuration.AssignedStations.GetEnumerator(); PackagingStation result = default(PackagingStation); bool value = default(bool); while (enumerator.MoveNext()) { PackagingStation current = enumerator.Current; if ((Object)(object)current != (Object)null && Utils.Is<PackagingStation>((object)current, out result) && (Object)(object)result != (Object)null && UnpackageSave.Instance.TryGetValue(((BuildableItem)result).GUID, out value) && value) { List<ItemSlot> inputSlots = result.InputSlots; if (Utils.Is<PackagingStationConfiguration>((object)current.Configuration, out PackagingStationConfiguration config) && config != null) { bool flag = (from x in inputSlots.AsEnumerable<ItemSlot>() where x != null select x.ItemInstance into x where ((x != null) ? ((BaseItemInstance)x).ID : null) != null select x).Any((ItemInstance x) => ((Employee)__instance).MoveItemBehaviour.IsTransitRouteValid(config.DestinationRoute, ((BaseItemInstance)x).ID)); if (inputSlots.AsEnumerable<ItemSlot>().Sum((ItemSlot x) => x.Quantity) != 0 && flag) { __result = current; return false; } } } else { ItemSlot outputSlot = current.OutputSlot; if (Utils.Is<PackagingStationConfiguration>((object)current.Configuration, out PackagingStationConfiguration result2) && result2 != null && outputSlot.Quantity != 0 && ((Employee)__instance).MoveItemBehaviour.IsTransitRouteValid(result2.DestinationRoute, ((BaseItemInstance)outputSlot.ItemInstance).ID)) { __result = current; return false; } } } __result = null; return false; } [HarmonyPatch("StartMoveItem", new Type[] { typeof(PackagingStation) })] [HarmonyPrefix] private static bool StartMoveItem(Packager __instance, PackagingStation station) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) UnpackageSave.Instance.TryGetValue(((BuildableItem)station).GUID, out var value); if (!value) { return true; } if (!Utils.Is<PackagingStationConfiguration>((object)station.Configuration, out PackagingStationConfiguration config) || config == null) { return true; } ItemSlot val = station.InputSlots.AsEnumerable<ItemSlot>().FirstOrDefault((Func<ItemSlot, bool>)delegate(ItemSlot x) { if (x.ItemInstance == null) { return false; } string text = default(string); bool flag = ((Employee)__instance).MoveItemBehaviour.IsTransitRouteValid(config.DestinationRoute, ((BaseItemInstance)x.ItemInstance).ID, ref text); if (!flag) { Console.Log(Object.op_Implicit("[Unpacked] Rejected item " + ((BaseItemInstance)x.ItemInstance).ID + ": " + text), (Object)null); } return flag; }); if (val == null) { return true; } Console.Log(Object.op_Implicit("[Unpacked] Starting moving items from " + ((Object)((Component)station).gameObject).name), (Object)null); ((Employee)__instance).MoveItemBehaviour.InitializeMoveItemBehaviourWithID(config.DestinationRoute, val.ItemInstance); ((Behaviour)((Employee)__instance).MoveItemBehaviour).Enable_Networked(); return false; } private static void InitializeMoveItemBehaviourWithID(this MoveItemBehaviour moveItemBehaviour, TransitRoute route, ItemInstance _itemToRetrieveTemplate, int _maxMoveAmount = -1, bool _skipPickup = false) { if (((_itemToRetrieveTemplate != null) ? ((BaseItemInstance)_itemToRetrieveTemplate).ID : null) == null) { return; } string text = default(string); if (!moveItemBehaviour.IsTransitRouteValid(route, ((BaseItemInstance)_itemToRetrieveTemplate).ID, ref text)) { Console.LogError(Object.op_Implicit("Invalid transit route for move item behaviour! Reason: " + text), (Object)(object)((Component)moveItemBehaviour).gameObject); return; } moveItemBehaviour.assignedRoute = route; moveItemBehaviour.itemToRetrieveTemplate = _itemToRetrieveTemplate; moveItemBehaviour.maxMoveAmount = _maxMoveAmount; if (((Behaviour)moveItemBehaviour).Npc.Behaviour.DEBUG_MODE) { Console.Log(Object.op_Implicit($"MoveItemBehaviour initialized with route: {route.Source.Name} -> {route.Destination.Name} for item: {((BaseItemInstance)_itemToRetrieveTemplate).ID}"), (Object)null); } moveItemBehaviour.skipPickup = _skipPickup; } [HarmonyReversePatch(/*Could not decode attribute arguments.*/)] [HarmonyPatch(typeof(Employee), "UpdateBehaviour")] private static void UpdateEmployeeBehaviour(Employee __instance) { throw new NotImplementedException(); } [HarmonyPatch("UpdateBehaviour")] [HarmonyPrefix] private static bool UpdateBehaviour(Packager __instance) { UpdateEmployeeBehaviour((Employee)(object)__instance); if (((Behaviour)__instance.PackagingBehaviour).Active) { ((Employee)__instance).MarkIsWorking(); } else if (((Behaviour)((Employee)__instance).MoveItemBehaviour).Active) { ((Employee)__instance).MarkIsWorking(); } else { if (!InstanceFinder.IsServer) { return false; } if (((Employee)__instance).Fired) { ((Employee)__instance).LeavePropertyAndDespawn(); } else { if (!((Employee)__instance).CanWork()) { return false; } if (__instance.configuration.AssignedStationCount + __instance.configuration.Routes.Routes.Count == 0) { ((Employee)__instance).SubmitNoWorkReason("I haven't been assigned to any stations or routes.", "You can use your management clipboards to assign stations or routes to me.", 0); ((Employee)__instance).SetIdle(true); } else { if (!InstanceFinder.IsServer) { return false; } PackagingStation stationToAttend = __instance.GetStationToAttend(); if ((Object)(object)stationToAttend != (Object)null) { __instance.StartPackaging(stationToAttend); return false; } BrickPress brickPress = __instance.GetBrickPress(); if ((Object)(object)brickPress != (Object)null) { __instance.StartPress(brickPress); return false; } PackagingStation stationMoveItems = __instance.GetStationMoveItems(); if ((Object)(object)stationMoveItems != (Object)null) { __instance.StartMoveItem(stationMoveItems); return false; } BrickPress brickPressMoveItems = __instance.GetBrickPressMoveItems(); if ((Object)(object)brickPressMoveItems != (Object)null) { __instance.StartMoveItem(brickPressMoveItems); return false; } ItemInstance val = default(ItemInstance); AdvancedTransitRoute transitRouteReady = __instance.GetTransitRouteReady(ref val); if (transitRouteReady != null) { ((Employee)__instance).MoveItemBehaviour.Initialize((TransitRoute)(object)transitRouteReady, val, ((BaseItemInstance)val).Quantity, false); ((Behaviour)((Employee)__instance).MoveItemBehaviour).Enable_Networked(); } else { ((Employee)__instance).SubmitNoWorkReason("There's nothing for me to do right now.", "I need one of my assigned stations to have enough product and packaging to get to work.", 0); ((Employee)__instance).SetIdle(true); } } } } return false; } } public static class PackagingStationConfigPatches { public static Dictionary<Guid, StringField> UnpackageFields = new Dictionary<Guid, StringField>(); public static void InitializeField(PackagingStationConfiguration config, PackagingStation station) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected O, but got Unknown Guid gUID = ((BuildableItem)station).GUID; Guid key = Guid.Parse(((object)(Guid)(ref gUID)).ToString()); if (!UnpackageFields.ContainsKey(key)) { StringField value = new StringField((EntityConfiguration)(object)config, "false"); UnpackageFields[key] = value; } else { ((EntityConfiguration)config).Fields.Add((ConfigField)(object)UnpackageFields[key]); } } } [HarmonyPatch(typeof(PackagingStationConfiguration))] public class PackagingStationConfigurationPatch { [HarmonyPostfix] [HarmonyPatch(/*Could not decode attribute arguments.*/)] public static void ConstructorPostfix(PackagingStationConfiguration __instance, PackagingStation station) { if (__instance != null && !((Object)(object)station == (Object)null)) { PackagingStationConfigPatches.InitializeField(__instance, station); } } } [HarmonyPatch(typeof(PackagingStationConfigPanel))] public class PackagingStationConfigPanelPatch { [HarmonyPostfix] [HarmonyPatch("BindInternal")] public static void BindInternalPostfix(PackagingStationConfigPanel __instance, List<EntityConfiguration> configs) { //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Expected O, but got Unknown //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Expected O, but got Unknown //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0215: Expected O, but got Unknown //IL_023f: Unknown result type (might be due to invalid IL or missing references) //IL_0256: Unknown result type (might be due to invalid IL or missing references) //IL_026d: Unknown result type (might be due to invalid IL or missing references) //IL_0284: Unknown result type (might be due to invalid IL or missing references) //IL_029b: Unknown result type (might be due to invalid IL or missing references) //IL_0315: Unknown result type (might be due to invalid IL or missing references) //IL_030e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null || (Object)(object)__instance.DestinationUI == (Object)null) { return; } try { PackagingStationConfiguration val = null; Enumerator<EntityConfiguration> enumerator = configs.GetEnumerator(); while (enumerator.MoveNext()) { EntityConfiguration current = enumerator.Current; if (!Utils.Is<PackagingStationConfiguration>((object)current, out PackagingStationConfiguration result) || result == null) { continue; } val = result; break; } if ((Object)(object)((val != null) ? val.Station : null) == (Object)null) { return; } Guid gUID = ((BuildableItem)val.Station).GUID; Guid stationGuid = Guid.Parse(((object)(Guid)(ref gUID)).ToString()); if (!PackagingStationConfigPatches.UnpackageFields.TryGetValue(stationGuid, out var _)) { PackagingStationConfigPatches.InitializeField(val, val.Station); } Transform parent = ((Component)__instance.DestinationUI).transform.parent; GameObject val2 = new GameObject("UnpackageToggle"); val2.transform.SetParent(parent, false); RectTransform val3 = val2.AddComponent<RectTransform>(); RectTransform component = ((Component)__instance.DestinationUI).GetComponent<RectTransform>(); val3.sizeDelta = new Vector2(400f, 50f); GameObject val4 = new GameObject("Title"); val4.transform.SetParent(val2.transform, false); RectTransform val5 = val4.AddComponent<RectTransform>(); val5.anchorMin = new Vector2(0f, 0.5f); val5.anchorMax = new Vector2(0f, 0.5f); val5.pivot = new Vector2(0f, 0.5f); val5.anchoredPosition = new Vector2(0f, 0f); val5.sizeDelta = new Vector2(150f, 30f); TextMeshProUGUI val6 = val4.AddComponent<TextMeshProUGUI>(); ((TMP_Text)val6).fontSize = 24f; ((TMP_Text)val6).alignment = (TextAlignmentOptions)513; ((TMP_Text)val6).text = "Set Unpackage"; ((Graphic)val6).color = Color.black; GameObject val7 = new GameObject("Value"); val7.transform.SetParent(val2.transform, false); RectTransform val8 = val7.AddComponent<RectTransform>(); val8.anchorMin = new Vector2(1f, 0.5f); val8.anchorMax = new Vector2(1f, 0.5f); val8.pivot = new Vector2(1f, 0.5f); val8.anchoredPosition = new Vector2(0f, 0f); val8.sizeDelta = new Vector2(80f, 30f); TextMeshProUGUI valueTmpro = val7.AddComponent<TextMeshProUGUI>(); ((TMP_Text)valueTmpro).fontSize = 24f; ((TMP_Text)valueTmpro).alignment = (TextAlignmentOptions)516; UnpackageSave.Instance.TryGetValue(stationGuid, out var value2); ((TMP_Text)valueTmpro).text = (value2 ? "On" : "Off"); ((Graphic)valueTmpro).color = (value2 ? Color.green : Color.gray); Button val9 = val7.AddComponent<Button>(); ((UnityEventBase)val9.onClick).RemoveAllListeners(); string s = ""; EventHelper.AddListener((Action)delegate { //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) s = s; MelonLogger.Msg("Button clicked"); UnpackageSave instance = UnpackageSave.Instance; if (instance?.UnpackageStations != null) { if (!instance.UnpackageStations.TryAdd(stationGuid, value: true)) { instance.UnpackageStations[stationGuid] = !instance.UnpackageStations[stationGuid]; } bool flag = instance.UnpackageStations[stationGuid]; ((TMP_Text)valueTmpro).text = (flag ? "On" : "Off"); ((Graphic)valueTmpro).color = (flag ? Color.green : Color.gray); } }, (UnityEvent)(object)val9.onClick); UIContentPanel component2 = ((Component)__instance).GetComponent<UIContentPanel>(); if ((Object)(object)component2 != (Object)null) { UISelectable val10 = val7.GetComponent<UISelectable>(); if ((Object)(object)val10 == (Object)null) { val10 = val7.AddComponent<UISelectable>(); } ((UIPanel)component2).AddSelectable(val10); } } catch (Exception value3) { MelonLogger.Error($"BindInternalPostfix failed: {value3}"); } } } [HarmonyPatch(typeof(PackagingStation))] internal static class PackagingStationPatches { [HarmonyPatch("PackSingleInstance")] [HarmonyPrefix] private static bool UnpackIfConfigured(PackagingStation __instance) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) if (__instance != null) { _ = ((BuildableItem)__instance).GUID; if (0 == 0) { UnpackageSave.Instance.TryGetValue(((BuildableItem)__instance).GUID, out var value); if (!value) { return true; } __instance.Unpack(); return false; } } return true; } } [HarmonyPatch(typeof(PackagingStationBehaviour))] internal static class PackagingStationBehaviourPatches { [HarmonyPatch("IsStationReady")] [HarmonyPrefix] private static bool IsStationReady(PackagingStationBehaviour __instance, PackagingStation station, ref bool __result) { //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Invalid comparison between Unknown and I4 if ((Object)(object)station == (Object)null) { __result = false; return false; } NPC npc = ((Behaviour)__instance).Npc; Utils.Is2<IUsable>((object)station, out IUsable result); if (result != null && result.IsInUse && (Object)(object)station.NPCUserObject != (Object)(object)((NetworkBehaviour)npc).NetworkObject) { __result = false; return false; } if (!npc.Movement.CanGetTo(station.StandPoint.position, 1f)) { __result = false; return false; } UnpackageSave.Instance.TryGetValue(((BuildableItem)station).GUID, out var value); EMode val = (EMode)(value ? 1 : 0); if ((int)station.GetState(val) > 0) { __result = false; return false; } __result = true; return false; } } public static class TransitEntityExtensions { public static List<ItemSlot> ReserveOutputSlotsForItem(this ITransitEntity entity, ItemInstance item, NetworkObject locker) { List<ItemSlot> list = new List<ItemSlot>(); int num = ((BaseItemInstance)item).Quantity; for (int i = 0; i < entity.OutputSlots.Count; i++) { int capacityForItem = entity.OutputSlots[i].GetCapacityForItem(item, false); if (capacityForItem != 0) { int num2 = Mathf.Min(capacityForItem, num); num -= num2; entity.OutputSlots[i].ApplyLock(locker, "Employee is about to place an item here", false); list.Add(entity.OutputSlots[i]); if (num <= 0) { break; } } } return list; } public static void RemoveOutputSlotLocks(this ITransitEntity entity, NetworkObject locker) { for (int i = 0; i < entity.OutputSlots.Count; i++) { if (entity.OutputSlots[i].ActiveLock != null && (Object)(object)entity.OutputSlots[i].ActiveLock.LockOwner == (Object)(object)locker) { entity.OutputSlots[i].RemoveLock(false); } } } } } namespace EmployeeTweaks.Patches.QualityEmployeeWorkSpeed { [HarmonyPatch] internal static class EffectPatches { private static Instance _logger = new Instance("EmployeeTweaks.QualityEmployeeWorkSpeed"); [HarmonyPatch(typeof(ProductItemInstance), "ApplyEffectsToNPC")] [HarmonyPrefix] private static bool ApplyEffectsToEmployee(ProductItemInstance __instance, NPC npc) { //IL_0107: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)((__instance != null) ? ((ItemInstance)__instance).Definition : null) == (Object)null) { return true; } if ((Object)(object)npc == (Object)null) { return true; } if (!Utils.Is<Employee>((object)npc, out Employee result) || (Object)(object)result == (Object)null) { return true; } if (!Utils.Is<ProductDefinition>((object)((ItemInstance)__instance).Definition, out ProductDefinition result2) || (Object)(object)result2 == (Object)null) { return true; } List<Effect> list = new List<Effect>(); list.AddRange(((PropertyItemDefinition)result2).Properties.AsEnumerable<Effect>()); list = list.OrderBy((Effect x) => x.Tier).ToList(); StackEntry val = default(StackEntry); foreach (Effect item in list) { item.ApplyToEmployee(result); if (result.WorkSpeedController.TryGetEntry(item.Name, ref val)) { float value = ApplyQuality(val.Value, GetQualityMult(((QualityItemInstance)__instance).Quality)); _logger.Msg($"Applying quality transformation to {item.Name}: was {val.Value}, is {value}"); val.Value = value; result.WorkSpeedController.Recalculate(); } } return false; } private static float GetQualityMult(EQuality quality) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected I4, but got Unknown if (1 == 0) { } float result = (int)quality switch { 0 => 0.4f, 1 => 0.7f, 2 => 1f, 3 => 1.2f, 4 => 1.5f, _ => 1f, }; if (1 == 0) { } return result; } private static float ApplyQuality(float baseValue, float m) { float num = 1f + (m - 1f) * 1.2f; float num2 = baseValue * 0.9f; float num3 = baseValue * 1.2f; return Mathf.Lerp(num2, num3, Mathf.InverseLerp(0.4f, 1.5f, num)); } } } namespace EmployeeTweaks.Patches.FilterItemApply { [HarmonyPatch(typeof(FilterConfigPanel))] internal class FilterConfigPanelPatches { private static Instance _logger = new Instance("EmployeeTweaks.FilterItemApply"); internal const string Filter1 = "Apply Item As Filter"; internal const string Filter2 = "Apply All As Filters"; internal static bool AllSlots; internal static bool DenyListMode; internal static TextMeshProUGUI ApplyItemAsFilterButtonText; private static Button _applyItemAsFilterButton; [HarmonyPatch("Awake")] [HarmonyPostfix] private static void AddButton(FilterConfigPanel __instance) { Button applyToSiblingsButton = __instance.ApplyToSiblingsButton; if ((Object)(object)applyToSiblingsButton == (Object)null) { return; } GameObject val = Object.Instantiate<GameObject>(((Component)applyToSiblingsButton).gameObject, ((Component)applyToSiblingsButton).transform.parent); _applyItemAsFilterButton = val.GetComponent<Button>(); ApplyItemAsFilterButtonText = ((Component)_applyItemAsFilterButton).GetComponentInChildren<TextMeshProUGUI>(); ((TMP_Text)ApplyItemAsFilterButtonText).text = "Apply Item As Filter"; ((UnityEventBase)_applyItemAsFilterButton.onClick).RemoveAllListeners(); string s = ""; EventHelper.AddListener((Action)delegate { s = s; if (AllSlots) { ApplyItemsAsFilters(__instance.OpenSlot); } else { ApplyItemAsFilter(__instance.OpenSlot); } }, (UnityEvent)(object)_applyItemAsFilterButton.onClick); } private static void ApplyItemAsFilter(ItemSlot itemSlot) { if (!AllSlots) { _logger.Msg("Applying item as filter"); } ItemInstance itemInstance = itemSlot.ItemInstance; if (((itemInstance != null) ? ((BaseItemInstance)itemInstance).ID : null) == null) { _logger.Warning("No item in slot to apply as filter."); return; } SlotFilter playerFilter = itemSlot.PlayerFilter; if (((playerFilter != null) ? playerFilter.ItemIDs : null) == null) { _logger.Warning("Player filter is null or does not have an ItemIDs list."); return; } playerFilter.ItemIDs.Clear(); playerFilter.ItemIDs.Add(((BaseItemInstance)itemInstance).ID); playerFilter.Type = (EType)((!DenyListMode) ? 1 : 2); itemSlot.SetPlayerFilter(playerFilter, false); } private static void ApplyItemsAsFilters(ItemSlot itemSlot) { _logger.Msg("Applying all items in sibling slots as filters."); Enumerator<ItemSlot> enumerator = itemSlot.SiblingSet.Slots.GetEnumerator(); while (enumerator.MoveNext()) { ItemSlot current = enumerator.Current; ApplyItemAsFilter(current); } } } } namespace EmployeeTweaks.Patches.EmployeeArea { internal class DebugAreaDrawer { private Instance Logger = new Instance("EmployeeTweaks.DebugAreaDrawer"); private List<GameObject> _areas = new List<GameObject>(); internal void Draw() { //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) foreach (GameObject area in _areas) { if ((Object)(object)area != (Object)null) { Object.DestroyImmediate((Object)(object)area); } } _areas.Clear(); if (!EmployeeTweaks.EnableCapacityAndDebug.Value || !EmployeeTweaks.DrawDebugArea.Value) { return; } Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(0f, 0.1f, 0f); foreach (var value in PropertyPatch._propertyIdlePointRects.Values) { Logger.Msg($"Drawing Employee Area at {value.Item1 + val}, {value.Item2 + val}"); GameObject item = DrawDebugArea(value.Item1 + val, value.Item2 + val, new Color(1f, 0f, 0f, 0.2f)); _areas.Add(item); } } private static GameObject DrawDebugArea(Vector3 a, Vector3 b, Color color) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Expected O, but got Unknown //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) GameObject val = GameObject.CreatePrimitive((PrimitiveType)5); ((Object)val).name = "DebugArea"; Object.Destroy((Object)(object)val.GetComponent<Collider>()); Vector3 val2 = Vector3.Min(a, b); Vector3 val3 = Vector3.Max(a, b); Vector3 val4 = (val2 + val3) * 0.5f; Vector3 val5 = val3 - val2; val.transform.position = val4 + Vector3.up * 0.01f; val.transform.rotation = Quaternion.Euler(90f, 0f, 0f); val.transform.localScale = new Vector3(val5.x, val5.z, 1f); MeshRenderer component = val.GetComponent<MeshRenderer>(); Shader val6 = Shader.Find("Universal Render Pipeline/Lit"); if ((Object)(object)val6 == (Object)null) { return val; } Material val7 = new Material(val6); if (val7.HasProperty("_Surface")) { val7.SetFloat("_Surface", 1f); } if (color.a <= 0f) { color.a = 0.2f; } if (val7.HasProperty("_BaseColor")) { val7.SetColor("_BaseColor", color); } if (val7.HasProperty("_EmissionColor")) { val7.EnableKeyword("_EMISSION"); val7.SetColor("_EmissionColor", new Color(color.r, color.g, color.b) * 1.5f); } val7.SetInt("_ZWrite", 0); val7.renderQueue = 3000; ((Renderer)component).material = val7; return val; } } [HarmonyPatch(typeof(Property))] internal class PropertyPatch { private static Instance Logger = new Instance("EmployeeTweaks.PropertyPatch"); internal static Dictionary<Property, (Vector3, Vector3)> _propertyIdlePointRects = new Dictionary<Property, (Vector3, Vector3)>(); [HarmonyPatch("NetworkInitialize___Early")] [HarmonyPriority(-100)] [HarmonyPrefix] private static void StorePointRectAndAddCapacity(Property __instance) { //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) if (!EmployeeTweaks.EnableCapacityAndDebug.Value) { return; } Il2CppReferenceArray<Transform> employeeIdlePoints = __instance.EmployeeIdlePoints; if (employeeIdlePoints != null && ((Il2CppArrayBase<Transform>)(object)employeeIdlePoints).Length > 0) { var (val, val2) = MinMaxPoints(((IEnumerable<Transform>)employeeIdlePoints).AsEnumerable().ToList()); if (val == val2) { val2 = val + new Vector3(0.5f, 0f, 0.5f); } _propertyIdlePointRects[__instance] = (val, val2); } if (__instance.EmployeeCapacity <= 0) { return; } MelonPreferences_Entry<int> entry = EmployeeTweaks.EmployeeCapacityCategory.GetOrCreateEntry("EmployeeTweaks_" + __instance.propertyCode + "_EmpCap", __instance.EmployeeCapacity, __instance.propertyName + " Employee Capacity", "Max amount of employees you can hire for this property", isHidden: false, dontSaveDefault: false, (ValueValidator)(object)new ValueRange<int>(1, Mathf.CeilToInt((float)__instance.EmployeeCapacity * 1.5f) + 1)); EmployeeTweaks.EmployeeCapacities.Add(entry); ((MelonEventBase<LemonAction<int, int>>)(object)entry.OnEntryValueChanged).Subscribe((LemonAction<int, int>)delegate(int oldVal, int newVal) { if (oldVal != newVal) { AddCapacity(__instance, newVal); } }, 0, false); AddCapacity(__instance, entry.Value); void AddCapacity(Property prop, int target) { //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_02f8: Unknown result type (might be due to invalid IL or missing references) //IL_02fd: Unknown result type (might be due to invalid IL or missing references) //IL_0310: Unknown result type (might be due to invalid IL or missing references) //IL_0317: Expected O, but got Unknown //IL_0338: Unknown result type (might be due to invalid IL or missing references) //IL_034e: Unknown result type (might be due to invalid IL or missing references) int num = prop.Employees?.AsEnumerable<Employee>().Count() ?? 0; (Vector3, Vector3) value; if (target < num) { Logger.Warning($"Cannot set capacity of {prop.propertyName} to {target} because it currently has {num} employees"); entry.Value = prop.EmployeeCapacity; } else if (!_propertyIdlePointRects.TryGetValue(prop, out value)) { Logger.Warning("Could not find idle point rect for " + prop.propertyName + ", cannot add capacity"); entry.Value = prop.EmployeeCapacity; } else { int num2 = ((Il2CppArrayBase<Transform>)(object)prop.EmployeeIdlePoints)?.Length ?? 0; int num3 = target - num2; if (num3 <= 0) { if (num2 <= 0) { entry.Value = prop.EmployeeCapacity; } else { List<Transform> list = ((IEnumerable<Transform>)prop.EmployeeIdlePoints).AsEnumerable().ToList(); list = list.GetRange(0, target); prop.EmployeeIdlePoints = Il2CppReferenceArray<Transform>.op_Implicit(list.ToArray()); prop.EmployeeCapacity = list.Count; } } else { List<Vector3> list2 = PoissonDiskSampler2D.SampleAdaptive(value.Item1, value.Item2, (((IEnumerable<Transform>)prop.EmployeeIdlePoints)?.AsEnumerable() ?? Array.Empty<Transform>()).ToList(), num3, 1f, 0.01f, prop.propertyCode.GetHashCode()); if (list2.Count + (((Il2CppArrayBase<Transform>)(object)prop.EmployeeIdlePoints)?.Length ?? 0) < target) { Logger.Warning($"Generated {list2.Count} new points for {prop.propertyName} but needed {num3}, cannot add capacity"); entry.Value = prop.EmployeeCapacity; } else { List<Transform> list3 = new List<Transform>(); Transform val3 = ((IEnumerable<Transform>)prop.EmployeeIdlePoints)?.FirstOrDefault(); if ((Object)(object)val3 == (Object)null) { Logger.Warning("Property " + prop.propertyName + " has no idle points, cannot add capacity"); entry.Value = prop.EmployeeCapacity; } else { foreach (Vector3 item in list2) { GameObject val4 = new GameObject(prop.propertyName + "_EmployeeIdlePoint"); val4.transform.SetParent(((Component)val3).transform.parent, false); val4.transform.position = item; val4.transform.rotation = ((Component)val3).transform.rotation; list3.Add(val4.transform); } foreach (Transform item2 in (Il2CppArrayBase<Transform>)(object)prop.EmployeeIdlePoints) { list3.Add(item2); } prop.EmployeeIdlePoints = Il2CppReferenceArray<Transform>.op_Implicit(list3.ToArray()); prop.EmployeeCapacity = list3.Count; } } } } } } private static (Vector3 min, Vector3 max) MinMaxPoints(List<Transform> transforms) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) if (transforms == null || transforms.Count == 0) { throw new ArgumentException("Empty list"); } Vector3 position = transforms[0].position; Vector3 val = position; Vector3 val2 = position; for (int i = 1; i < transforms.Count; i++) { Vector3 position2 = transforms[i].position; val = Vector3.Min(val, position2); val2 = Vector3.Max(val2, position2); } return (val, val2); } } public static class PoissonDiskSampler2D { private static Random _rng; public static List<Vector3> SampleAdaptive(Vector3 min, Vector3 max, List<Transform> blocked, int targetCount, float preferredRadius, float minRadius, int seed, int maxIterations = 5, int k = 30) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) _rng = new Random(seed); float num = preferredRadius; List<Vector3> list = new List<Vector3>(); for (int i = 0; i < maxIterations; i++) { List<Vector3> list2 = Sample(min, max, blocked, num, k); if (list2.Count >= targetCount) { return list2.GetRange(0, targetCount); } if (list2.Count > list.Count) { list = list2; } num *= 0.7f; if (num < minRadius) { break; } } if (list.Count < targetCount) { list.AddRange(Fill(min, max, blocked, list, targetCount - list.Count, minRadius)); } return list; } private static List<Vector3> Sample(Vector3 min, Vector3 max, List<Transform> blocked, float radius, int k) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) float num = radius / Mathf.Sqrt(2f); int num2 = Mathf.CeilToInt((max.x - min.x) / num); int num3 = Mathf.CeilToInt((max.z - min.z) / num); Vector3?[,] grid = new Vector3?[num2, num3]; List<Vector3> list = new List<Vector3>(); List<Vector3> list2 = new List<Vector3>(); Vector3 val = RandomPoint(min, max); list.Add(val); list2.Add(val); Set(grid, min, num, val); while (list.Count > 0) { int index = _rng.Next(list.Count); Vector3 p = list[index]; bool flag = false; for (int i = 0; i < k; i++) { Vector3 val2 = GenerateAround(p, radius); if (IsValid(val2, min, max, radius, grid, blocked, num)) { list.Add(val2); list2.Add(val2); Set(grid, min, num, val2); flag = true; break; } } if (!flag) { list.RemoveAt(index); } } return list2; } private static List<Vector3> Fill(Vector3 min, Vector3 max, List<Transform> blocked, List<Vector3> current, int needed, float epsilon) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0019: 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_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) List<Vector3> list = new List<Vector3>(); float epsSqr = epsilon * epsilon; int num = 0; int num2 = needed * 20; while (list.Count < needed && num++ < num2) { Vector3 val = RandomPoint(min, max); if (!TooClose(val, blocked, current, list, epsSqr)) { list.Add(val); } } return list; } private static Vector3 RandomPoint(Vector3 min, Vector3 max) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) return new Vector3(Lerp(min.x, max.x), min.y, Lerp(min.z, max.z)); } private static Vector3 GenerateAround(Vector3 p, float radius) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) float num = (float)(_rng.NextDouble() * 3.1415927410125732 * 2.0); float num2 = Lerp(radius, radius * 2f); return new Vector3(p.x + Mathf.Cos(num) * num2, p.y, p.z + Mathf.Sin(num) * num2); } private static bool IsValid(Vector3 p, Vector3 min, Vector3 max, float radius, Vector3?[,] grid, List<Transform> blocked, float cellSize) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: 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_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) if (p.x < min.x || p.x > max.x || p.z < min.z || p.z > max.z) { return false; } float num = radius * radius; if (TooClose(p, blocked, null, null, num)) { return false; } int num2 = (int)((p.x - min.x) / cellSize); int num3 = (int)((p.z - min.z) / cellSize); for (int i = -2; i <= 2; i++) { for (int j = -2; j <= 2; j++) { int num4 = num2 + i; int num5 = num3 + j; if (num4 >= 0 && num5 >= 0 && num4 < grid.GetLength(0) && num5 < grid.GetLength(1) && grid[num4, num5].HasValue) { Vector3 val = grid[num4, num5].Value - p; if (((Vector3)(ref val)).sqrMagnitude < num) { return false; } } } } return true; } private static void Set(Vector3?[,] grid, Vector3 min, float cellSize, Vector3 p) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) int num = (int)((p.x - min.x) / cellSize); int num2 = (int)((p.z - min.z) / cellSize); grid[num, num2] = p; } private static bool TooClose(Vector3 p, List<Transform> blocked, List<Vector3> a, List<Vector3> b, float epsSqr) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: 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_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) Vector3 val; foreach (Transform item in blocked) { val = item.position - p; if (((Vector3)(ref val)).sqrMagnitude < epsSqr) { return true; } } if (a != null) { foreach (Vector3 item2 in a) { val = item2 - p; if (((Vector3)(ref val)).sqrMagnitude < epsSqr) { return true; } } } if (b != null) { foreach (Vector3 item3 in b) { val = item3 - p; if (((Vector3)(ref val)).sqrMagnitude < epsSqr) { return true; } } } return false; } private static float Lerp(float a, float b) { return a + (float)_rng.NextDouble() * (b - a); } } } namespace EmployeeTweaks.Patches.BotanistSprinklersPourer { [HarmonyPatch(typeof(GrowContainerBehaviour))] internal class GrowContainerBehaviourPatch { [CompilerGenerated] private sealed class <PourerRoutine>d__2 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public AddSoilToGrowContainerBehaviour addSoilToGrowContainerBehaviour; public SoilPourer soilPourer; public ItemSlot slot; public SoilDefinition soilDefinition; private float <waitTime>5__1; private ItemInstance <usedItem>5__2; private Botanist <botanist>5__3; private Exception <e>5__4; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <PourerRoutine>d__2(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <usedItem>5__2 = null; <botanist>5__3 = null; <e>5__4 = null; <>1__state = -2; } private bool MoveNext() { //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <waitTime>5__1 = ((GrowContainerBehaviour)addSoilToGrowContainerBehaviour).GetActionDuration() / ((Employee)((GrowContainerBehaviour)addSoilToGrowContainerBehaviour)._botanist).CurrentWorkSpeed; <waitTime>5__1 *= 0.25f; soilPourer.SetSoil((NetworkConnection)null, ((BaseItemDefinition)soilDefinition).ID); <>2__current = (object)new WaitForSeconds(<waitTime>5__1); <>1__state = 1; return true; case 1: <>1__state = -1; if (!soilPourer.isDispensing) { soilPourer.PourSoil(); } <usedItem>5__2 = null; try { ItemSlot obj = slot; <usedItem>5__2 = ((obj != null) ? obj.ItemInstance.GetCopy(1) : null); } catch (Exception ex) { <e>5__4 = ex; return false; } ((GrowContainerBehaviour)addSoilToGrowContainerBehaviour).OnStopPerformAction(); ((GrowContainerBehaviour)addSoilToGrowContainerBehaviour).OnActionSuccess(<usedItem>5__2); if (slot != null && slot.Quantity > 0) { slot.ChangeQuantity(-1, false); } ((Behaviour)addSoilToGrowContainerBehaviour).Disable_Networked((NetworkConnection)null); if (Utils.Is<Botanist>((object)((Behaviour)addSoilToGrowContainerBehaviour).Npc, out <botanist>5__3)) { Botanist obj2 = <botanist>5__3; if (obj2 != null) { ((Employee)obj2).SetIdle(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(); } } [HarmonyPatch("OnActiveTick")] [HarmonyPostfix] private static void UseSprinklerOrPourer(GrowContainerBehaviour __instance) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Invalid comparison between Unknown and I4 if (!InstanceFinder.IsServer || (int)__instance._currentState != 3 || !__instance.IsAtGrowContainer()) { return; } if (Utils.Is<WaterPotBehaviour>((object)__instance, out WaterPotBehaviour result) && (Object)(object)result != (Object)null) { if (!Utils.Is<Pot>((object)((GrowContainerBehaviour)result)._growContainer, out Pot pot2)) { return; } HashSet<GridItem> itemsAroundItem = GetItemsAroundItem((GridItem)(object)pot2); MelonDebug.Msg("Found " + itemsAroundItem.Count + " items around the pot"); foreach (GridItem item in itemsAroundItem) { if (!Utils.Is<Sprinkler>((object)item, out Sprinkler result2) || (Object)(object)result2 == (Object)null) { continue; } List<Pot> pots = result2.GetPots(); if ((Object)(object)pots.AsEnumerable<Pot>().FirstOrDefault((Func<Pot, bool>)((Pot x) => (Object)(object)x != (Object)null && (Object)(object)x == (Object)(object)pot2)) == (Object)null) { continue; } MelonDebug.Msg("It's an eligible sprinkler, activating it"); if (!result2.IsSprinkling) { result2.Interacted(); } ((GrowContainerBehaviour)result).OnStopPerformAction(); ((GrowContainerBehaviour)result).OnActionSuccess((ItemInstance)null); ((Behaviour)result).Disable_Networked((NetworkConnection)null); if (Utils.Is<Botanist>((object)((Behaviour)result).Npc, out Botanist result3) && result3 != null) { ((Employee)result3).SetIdle(true); } break; } } if (!Utils.Is<AddSoilToGrowContainerBehaviour>((object)__instance, out AddSoilToGrowContainerBehaviour result4) || !((Object)(object)result4 != (Object)null)) { return; } if (!Utils.Is<Pot>((object)((GrowContainerBehaviour)result4)._growContainer, out Pot pot)) { return; } HashSet<GridItem> itemsAroundItem2 = GetItemsAroundItem((GridItem)(object)pot); MelonDebug.Msg("Found " + itemsAroundItem2.Count + " items around the pot"); Il2CppStringArray val2 = default(Il2CppStringArray); foreach (GridItem item2 in itemsAroundItem2) { if (!Utils.Is<SoilPourer>((object)item2, out SoilPourer result5) || (Object)(object)result5 == (Object)null) { continue; } List<Pot> pots2 = result5.GetPots(); if ((Object)(object)pots2.AsEnumerable<Pot>().FirstOrDefault((Func<Pot, bool>)((Pot x) => (Object)(object)x != (Object)null && (Object)(object)x == (Object)(object)pot)) == (Object)null) { continue; } MelonDebug.Msg("It's a eligible soil pourer, activating it"); if (!((GrowContainerBehaviour)result4).AreTaskConditionsMetForContainer((GrowContainer)(object)pot)) { MelonDebug.Msg("Conditions not met"); ((Behaviour)result4).Disable_Networked((NetworkConnection)null); break; } ItemSlot val = null; if (((GrowContainerBehaviour)result4).DoesTaskRequireItem((GrowContainer)(object)pot, ref val2)) { if (!Utils.Is2<IItemSlotOwner>((object)((NPC)((GrowContainerBehaviour)result4)._botanist).Inventory, out IItemSlotOwner result6)) { MelonDebug.Error("Botanist inventory does not implement IItemSlotOwner"); ((Behaviour)result4).Disable_Networked((NetworkConnection)null); break; } val = ((GrowContainerBehaviour)result4).GetItemSlotContainingRequiredItem(result6, val2); } ItemInstance val3 = ((val != null) ? val.ItemInstance.GetCopy(1) : null); if (val3 == null) { break; } if (!Utils.Is<SoilDefinition>((object)val3.Definition, out SoilDefinition result7) || (Object)(object)result7 == (Object)null) { MelonDebug.Msg("No soil in inventory"); ((Behaviour)result4).Disable_Networked((NetworkConnection)null); break; } if (((GrowContainerBehaviour)result4).CheckSuccess(val3)) { MelonCoroutines.Start(PourerRoutine(result4, result5, val, result7)); } else { ((Behaviour)result4).Disable_Networked((NetworkConnection)null); } } } private static HashSet<GridItem> GetItemsAroundItem(GridItem item) { //IL_0015: 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_0024: Expected O, but got Unknown //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Expected O, but got Unknown //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Expected O, but got Unknown //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Expected O, but got Unknown Coordinate origin = new Coordinate(item._originCoordinate); List<Coordinate> list = new List<Coordinate>(); for (int i = -1; i <= 2; i++) { list.Add(new Coordinate(i, -1)); list.Add(new Coordinate(i, 2)); } for (int j = 0; j <= 1; j++) { list.Add(new Coordinate(-1, j)); list.Add(new Coordinate(2, j)); } List<Coordinate> list2 = list.Select((Coordinate offset) => origin + Coordinate.RotateCoordinates(offset, (float)item._rotation)).ToList(); HashSet<GridItem> hashSet = new HashSet<GridItem>(); foreach (Coordinate item2 in list2) { Tile tile = item.OwnerGrid.GetTile(item2); if (!((Object)(object)tile == (Object)null)) { Enumerator<GridItem> enumerator2 = tile.BuildableOccupants.GetEnumerator(); while (enumerator2.MoveNext()) { GridItem current2 = enumerator2.Current; hashSet.Add(current2); } } } return hashSet; } [IteratorStateMachine(typeof(<PourerRoutine>d__2))] private static IEnumerator PourerRoutine(AddSoilToGrowContainerBehaviour addSoilToGrowContainerBehaviour, SoilPourer soilPourer, ItemSlot slot, SoilDefinition soilDefinition) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <PourerRoutine>d__2(0) { addSoilToGrowContainerBehaviour = addSoilToGrowContainerBehaviour, soilPourer = soilPourer, slot = slot, soilDefinition = soilDefinition }; } } } namespace EmployeeTweaks.Helpers { public static class MelonExtensions { public static void Debug(this Instance logger, string message, bool stacktrace = true) { MelonDebug.Msg(stacktrace ? ("[" + GetCallerInfo() + "] " + message) : message); } private static string GetCallerInfo() { StackTrace stackTrace = new StackTrace(); for (int i = 2; i < stackTrace.FrameCount; i++) { StackFrame frame = stackTrace.GetFrame(i); MethodBase method = frame.GetMethod(); if (!(method?.DeclaringType == null)) { return method.DeclaringType.FullName + "." + method.Name; } } return "unknown"; } public static MelonPreferences_Entry<T> GetOrCreateEntry<T>(this MelonPreferences_Category category, string identifier, T defaultValue, string displayName = null, string description = null, bool isHidden = false, bool dontSaveDefault = false, ValueValidator validator = null, string oldIdentifier = null) { if (category.HasEntry(identifier)) { return category.GetEntry<T>(identifier); } return category.CreateEntry<T>(identifier, defaultValue, displayName, description, isHidden, dontSaveDefault, validator, oldIdentifier); } } public static class Il2CppListExtensions { public static IEnumerable<T> AsEnumerable<T>(this List<T> list) { return list ?? new List<T>(); } public static object ToNativeList<T>(this List<T> source) { return source.ToIl2CppList(); } public static List<T> ToIl2CppList<T>(this IEnumerable<T> source) { List<T> val = new List<T>(); foreach (T item in source) { val.Add(item); } return val; } public static List<T> ConvertToList<T>(List<T> il2CppList) { List<T> list = new List<T>(); T[] collection = Il2CppArrayBase<T>.op_Implicit(il2CppList.ToArray()); list.AddRange(collection); return list; } public static IEnumerable<T> AsEnumerable<T>(this List<T> list) { IEnumerable<T> result; if (list != null) { result = ((IEnumerable<T>)list._items).Take(list._size); } else { IEnumerable<T> enumerable = Array.Empty<T>(); result = enumerable; } return result; } public static object ToNativeList<T>(this List<T> source) { return source; } } public static class Utils { [CompilerGenerated] private sealed class <WaitForCondition>d__7 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Func<bool> condition; public float timeout; public Action onTimeout; public Action onFinish; private float <startTime>5__1; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <WaitForCondition>d__7(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <startTime>5__1 = Time.time; break; case 1: <>1__state = -1; break; } if (!condition()) { if (!float.IsNaN(timeout) && Time.time - <startTime>5__1 > timeout) { onTimeout?.Invoke(); return false; } <>2__current = null; <>1__state = 1; return true; } onFinish?.Invoke(); 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 <WaitForNetwork>d__6 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public IEnumerator routine; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <WaitForNetwork>d__6(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; break; case 1: <>1__state = -1; break; } if (!InstanceFinder.IsServer && !InstanceFinder.IsClient) { <>2__current = null; <>1__state = 1; return true; } MelonCoroutines.Start(routine); 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 <WaitForPlayer>d__5 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public IEnumerator routine; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <WaitForPlayer>d__5(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; break; case 1: <>1__state = -1; break; } if ((Object)(object)Player.Local == (Object)null || (Object)(object)((Component)Player.Local).gameObject == (Object)null) { <>2__current = null; <>1__state = 1; return true; } MelonCoroutines.Start(routine); 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 Instance Logger = new Instance("EmployeeTweaks-Utils"); public static T? FindObjectByName<T>(string objectName) where T : Object { try { foreach (T item in Resources.FindObjectsOfTypeAll<T>()) { if (((Object)item).name != objectName) { continue; } Logger.Debug($"Found {typeof(T).Name} '{objectName}' directly in loaded objects"); return item; } return default(T); } catch (Exception ex) { Logger.Error($"Error finding {typeof(T).Name} '{objectName}': {ex.Message}"); return default(T); } } public static List<T> GetAllComponentsInChildrenRecursive<T>(GameObject obj) where T : Component { List<T> list = new List<T>(); if ((Object)(object)obj == (Object)null) { return list; } T[] array = Il2CppArrayBase<T>.op_Implicit(obj.GetComponents<T>()); if (array.Length != 0) { list.AddRange(array); } for (int i = 0; i < obj.transform.childCount; i++) { Transform child = obj.transform.GetChild(i); list.AddRange(GetAllComponentsInChildrenRecursive<T>(((Component)child).gameObject)); } return list; } public static bool Is<T>(object obj, out T? result) where T : Object { Object val = (Object)((obj is Object) ? obj : null); if (val != null) { Type val2 = Il2CppType.Of<T>(); Type il2CppType = val.GetIl2CppType(); if (val2.IsAssignableFrom(il2CppType)) { result = ((Il2CppObjectBase)val).TryCast<T>(); return result != null; } } result = default(T); return false; } public static bool Is2<T>(object obj, out T? result) where T : Il2CppObjectBase { object obj2 = ((obj is Il2CppObjectBase) ? obj : null); result = ((obj2 != null) ? ((Il2CppObjectBase)obj2).TryCast<T>() : default(T)); return result != null; } [IteratorStateMachine(typeof(<WaitForPlayer>d__5))] public static IEnumerator WaitForPlayer(IEnumerator routine) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <WaitForPlayer>d__5(0) { routine = routine }; } [IteratorStateMachine(typeof(<WaitForNetwork>d__6))] public static IEnumerator WaitForNetwork(IEnumerator routine) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <WaitForNetwork>d__6(0) { routine = routine }; } [IteratorStateMachine(typeof(<WaitForCondition>d__7))] public static IEnumerator WaitForCondition(Func<bool> condition, float timeout = float.NaN, Action? onTimeout = null, Action? onFinish = null) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <WaitForCondition>d__7(0) { condition = condition, timeout = timeout, onTimeout = onTimeout, onFinish = onFinish }; } public static string GetHierarchyPath(this Transform transform) { if ((Object)(object)transform == (Object)null) { return "null"; } string text = ((Object)transform).name; Transform parent = transform.parent; while ((Object)(object)parent != (Object)null) { text = ((Object)parent).name + "/" + text; parent = parent.parent; } return text; } public static T GetOrAddComponent<T>(this GameObject gameObject) where T : Component { T component = gameObject.GetComponent<T>(); if ((Object)(object)component != (Object)null) { return component; } component = gameObject.AddComponent<T>(); Logger.Debug("Added component " + typeof(T).Name + " to GameObject " + ((Object)gameObject).name); return component; } public static Material? DrawDebugVisuals(this GameObject gameObject, Color? color = null) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Expected O, but got Unknown //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) Renderer component = gameObject.GetComponent<Renderer>(); if ((Object)(object)com
EmployeeTweaks-Mono.dll
Decompiled a day agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using EmployeeTweaks; using EmployeeTweaks.Helpers; using EmployeeTweaks.Patches.EmployeeArea; using EmployeeTweaks.Patches.FilterItemApply; using EmployeeTweaks.Patches.Unpackaging; using EmployeeTweaks.Persistence; using FishNet; using FishNet.Connection; using FishNet.Object; using HarmonyLib; using MelonLoader; using MelonLoader.Preferences; using Microsoft.CodeAnalysis; using S1API.Entities; using S1API.Internal.Abstraction; using S1API.Saveables; using ScheduleOne; using ScheduleOne.Core.Items.Framework; using ScheduleOne.Effects; using ScheduleOne.Employees; using ScheduleOne.EntityFramework; using ScheduleOne.Growing; using ScheduleOne.ItemFramework; using ScheduleOne.Management; using ScheduleOne.NPCs; using ScheduleOne.NPCs.Behaviour; using ScheduleOne.ObjectScripts; using ScheduleOne.PlayerScripts; using ScheduleOne.Product; using ScheduleOne.Property; using ScheduleOne.Tiles; using ScheduleOne.Tools; using ScheduleOne.UI.Items; using ScheduleOne.UI.Management; using TMPro; 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(global::EmployeeTweaks.EmployeeTweaks), "EmployeeTweaks", "1.0.1", "k073l", null)] [assembly: MelonColor(1, 217, 131, 36)] [assembly: MelonGame("TVGS", "Schedule I")] [assembly: MelonPlatformDomain(/*Could not decode attribute arguments.*/)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: AssemblyCompany("EmployeeTweaks-Mono")] [assembly: AssemblyConfiguration("Mono")] [assembly: AssemblyDescription("Various employee tweaks - unpackaging, sprinkler/pourer use and more")] [assembly: AssemblyFileVersion("1.0.1.0")] [assembly: AssemblyInformationalVersion("1.0.1+43b19f4c286c6c638d50bfc07f2457e9ad1f5e07")] [assembly: AssemblyProduct("EmployeeTweaks-Mono")] [assembly: AssemblyTitle("EmployeeTweaks-Mono")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.1.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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [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 EmployeeTweaks { public static class BuildInfo { public const string Name = "EmployeeTweaks"; public const string Description = "Various employee tweaks - unpackaging, sprinkler/pourer use and more"; public const string Author = "k073l"; public const string Version = "1.0.1"; } public class EmployeeTweaks : MelonMod { private static Instance Logger; private DebugAreaDrawer debugAreaDrawer; private bool _lastShift; private bool _lastCtrl; internal static MelonPreferences_Category EmployeeCapacityCategory = MelonPreferences.CreateCategory("EmployeeTweaksEmployeeCapacity", "Employee Capacities"); internal static MelonPreferences_Entry<bool> EnableCapacityAndDebug = EmployeeCapacityCategory.CreateEntry<bool>("EmployeeTweaksEnableCapacityAndDebug", true, "Enable Category", "Enables employee capacity tweaks and drawing employee idle points area", false, false, (ValueValidator)null, (string)null); internal static MelonPreferences_Entry<bool> DrawDebugArea = EmployeeCapacityCategory.CreateEntry<bool>("EmployeeTweaksDrawDebugArea", false, "Draw Debug Area", "Draws a debug area where employee idle points are contained", false, false, (ValueValidator)null, (string)null); internal static HashSet<MelonPreferences_Entry<int>> EmployeeCapacities = new HashSet<MelonPreferences_Entry<int>>(); public override void OnInitializeMelon() { Logger = ((MelonBase)this).LoggerInstance; Logger.Msg("EmployeeTweaks initialized"); MoveItemBehaviourPatches.ManualPatchDestinationValid(((MelonBase)this).HarmonyInstance); debugAreaDrawer = new DebugAreaDrawer(); Player.LocalPlayerSpawned += delegate { debugAreaDrawer.Draw(); }; ((MelonEventBase<LemonAction<bool, bool>>)(object)DrawDebugArea.OnEntryValueChanged).Subscribe((LemonAction<bool, bool>)delegate { debugAreaDrawer.Draw(); }, 0, false); } public override void OnLateUpdate() { TextMeshProUGUI applyItemAsFilterButtonText = FilterConfigPanelPatches.ApplyItemAsFilterButtonText; if (!((Object)(object)applyItemAsFilterButtonText == (Object)null)) { bool flag = Input.GetKey((KeyCode)304) || Input.GetKey((KeyCode)303); bool flag2 = Input.GetKey((KeyCode)306) || Input.GetKey((KeyCode)305); if (flag != _lastShift || flag2 != _lastCtrl) { _lastShift = flag; _lastCtrl = flag2; FilterConfigPanelPatches.AllSlots = flag; FilterConfigPanelPatches.DenyListMode = flag2; ((TMP_Text)applyItemAsFilterButtonText).text = (flag ? "Apply All As Filters" : "Apply Item As Filter"); } } } } } namespace EmployeeTweaks.Persistence { public class UnpackageSave : Saveable { [SaveableField("UnpackageStations")] public Dictionary<Guid, bool> UnpackageStations = new Dictionary<Guid, bool>(); private static UnpackageSave _instance; public static UnpackageSave Instance => _instance ?? (_instance = new UnpackageSave()); public UnpackageSave() { _instance = this; } public bool TryGetValue(Guid guid, out bool value) { return UnpackageStations.TryGetValue(guid, out value); } } } namespace EmployeeTweaks.Patches.Unpackaging { [HarmonyPatch(typeof(AdvancedTransitRoute))] internal static class AdvancedTransitRoutePatch { [HarmonyPatch("GetItemReadyToMove")] [HarmonyPrefix] private static bool GetItemReadyToMove(AdvancedTransitRoute __instance, ref ItemInstance __result) { if (((TransitRoute)__instance).Source == null || ((TransitRoute)__instance).Destination == null) { return true; } if (((TransitRoute)__instance).Destination == null) { return true; } ITransitEntity destination = ((TransitRoute)__instance).Destination; PackagingStation result; bool flag = Utils.Is2<PackagingStation>(destination, out result) && (Object)(object)result != (Object)null; ITransitEntity source = ((TransitRoute)__instance).Source; PackagingStation result2; bool flag2 = Utils.Is2<PackagingStation>(source, out result2) && (Object)(object)result2 != (Object)null; if (!flag && !flag2) { return true; } PackagingStation val = (flag ? result : result2); UnpackageSave.Instance.TryGetValue(((BuildableItem)val).GUID, out var value); if (!value) { return true; } if (flag) { foreach (ItemSlot outputSlot in ((TransitRoute)__instance).Source.OutputSlots) { if (outputSlot.ItemInstance != null && __instance.Filter.DoesItemMeetFilter(outputSlot.ItemInstance)) { int outputCapacityForItem = destination.GetOutputCapacityForItem(outputSlot.ItemInstance, (NPC)null); if (outputCapacityForItem > 0) { __result = outputSlot.ItemInstance.GetCopy(Mathf.Min(outputCapacityForItem, ((BaseItemInstance)outputSlot.ItemInstance).Quantity)); return false; } } } } else { foreach (ItemSlot inputSlot in ((TransitRoute)__instance).Source.InputSlots) { if (inputSlot.ItemInstance != null && __instance.Filter.DoesItemMeetFilter(inputSlot.ItemInstance)) { int inputCapacityForItem = destination.GetInputCapacityForItem(inputSlot.ItemInstance, (NPC)null, true); if (inputCapacityForItem > 0) { __result = inputSlot.ItemInstance.GetCopy(Mathf.Min(inputCapacityForItem, ((BaseItemInstance)inputSlot.ItemInstance).Quantity)); return false; } } } } __result = null; return false; } } [HarmonyPatch(typeof(MoveItemBehaviour))] internal static class MoveItemBehaviourPatches { [CompilerGenerated] private sealed class <>c__DisplayClass7_0 { public MoveItemBehaviour __instance; } [CompilerGenerated] private sealed class <>c__DisplayClass9_0 { public MoveItemBehaviour __instance; public bool destIsStation; public ITransitEntity dest; } private static Dictionary<MoveItemBehaviour, object> customGrabRunning = new Dictionary<MoveItemBehaviour, object>(); private static Dictionary<MoveItemBehaviour, object> customPlaceRunning = new Dictionary<MoveItemBehaviour, object>(); internal static void ManualPatchDestinationValid(Harmony harmony) { //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Expected O, but got Unknown //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Expected O, but got Unknown MethodInfo methodInfo = AccessTools.Method(typeof(MoveItemBehaviour), "IsDestinationValid", new Type[3] { typeof(TransitRoute), typeof(ItemInstance), typeof(string).MakeByRefType() }, (Type[])null); if (methodInfo == null) { MelonLogger.Error("Failed to find IsDestinationValid method!"); return; } harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(MoveItemBehaviourPatches), "IsDestinationValid", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); MethodInfo methodInfo2 = AccessTools.Method(typeof(MoveItemBehaviour), "IsTransitRouteValid", new Type[3] { typeof(TransitRoute), typeof(string), typeof(string).MakeByRefType() }, (Type[])null); if (methodInfo2 == null) { MelonLogger.Error("Failed to find IsTransitRouteValid method!"); } else { harmony.Patch((MethodBase)methodInfo2, new HarmonyMethod(typeof(MoveItemBehaviourPatches), "IsTransitRouteValidID", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } private static bool IsDestinationValid(MoveItemBehaviour __instance, TransitRoute route, ItemInstance item, ref string invalidReason, ref bool __result) { invalidReason = string.Empty; if (((route != null) ? route.Destination : null) == null) { __result = false; return true; } ITransitEntity destination = route.Destination; PackagingStation result; bool flag = Utils.Is2<PackagingStation>(destination, out result) && (Object)(object)result != (Object)null; ITransitEntity source = route.Source; PackagingStation result2; bool flag2 = Utils.Is2<PackagingStation>(source, out result2) && (Object)(object)result2 != (Object)null; if (!flag && !flag2) { __result = false; return true; } PackagingStation val = (flag ? result : result2); UnpackageSave.Instance.TryGetValue(((BuildableItem)val).GUID, out var value); if (!value) { __result = false; return true; } if (!__instance.CanGetToDestination(route)) { invalidReason = "Cannot get to destination!"; __result = false; return false; } if (!__instance.CanGetToSource(route)) { invalidReason = "Cannot get to source!"; __result = false; return false; } if ((flag ? destination.GetOutputCapacityForItem(item, ((Behaviour)__instance).Npc) : destination.GetInputCapacityForItem(item, ((Behaviour)__instance).Npc, true)) == 0) { invalidReason = "Destination has no capacity for item!"; __result = false; return false; } __result = true; return false; } private static bool IsTransitRouteValidID(MoveItemBehaviour __instance, TransitRoute route, string itemID, ref string invalidReason, ref bool __result) { invalidReason = string.Empty; if (((route != null) ? route.Destination : null) == null || route.Source == null) { __result = false; return true; } ITransitEntity destination = route.Destination; PackagingStation result; bool flag = Utils.Is2<PackagingStation>(destination, out result) && (Object)(object)result != (Object)null; ITransitEntity source = route.Source; PackagingStation result2; bool flag2 = Utils.Is2<PackagingStation>(source, out result2) && (Object)(object)result2 != (Object)null; if (!flag && !flag2) { return true; } PackagingStation val = (flag ? result : result2); UnpackageSave.Instance.TryGetValue(((BuildableItem)val).GUID, out var value); if (!value) { __result = false; return true; } if (!route.AreEntitiesNonNull()) { invalidReason = "Entities are null!"; __result = false; return false; } ItemSlot firstSlotContainingItem = source.GetFirstSlotContainingItem(itemID, (ESlotType)((!flag2) ? 1 : 0)); ItemInstance val2 = ((firstSlotContainingItem != null) ? firstSlotContainingItem.ItemInstance : null); if (val2 == null || ((BaseItemInstance)val2).Quantity <= 0) { invalidReason = "Item is null or quantity is 0!"; __result = false; return false; } if (!__instance.IsDestinationValid(route, val2, ref invalidReason)) { __result = false; return false; } __result = true; return false; } [HarmonyPatch("IsNpcInventoryItemValid")] [HarmonyPrefix] private static bool CheckNpcInventoryItemValid(MoveItemBehaviour __instance, ItemInstance item, ref bool __result) { TransitRoute assignedRoute = __instance.assignedRoute; if (((assignedRoute != null) ? assignedRoute.Destination : null) == null) { return true; } ITransitEntity destination = __instance.assignedRoute.Destination; PackagingStation result; bool flag = Utils.Is2<PackagingStation>(destination, out result) && (Object)(object)result != (Object)null; ITransitEntity source = __instance.assignedRoute.Source; PackagingStation result2; bool flag2 = Utils.Is2<PackagingStation>(source, out result2) && (Object)(object)result2 != (Object)null; if (!flag && !flag2) { return true; } PackagingStation val = (flag ? result : result2); UnpackageSave.Instance.TryGetValue(((BuildableItem)val).GUID, out var value); if (!value) { return true; } if (flag) { if (destination.GetOutputCapacityForItem(item, ((Behaviour)__instance).Npc) == 0) { __result = false; return false; } } else if (destination.GetInputCapacityForItem(item, ((Behaviour)__instance).Npc, true) == 0) { __result = false; return false; } __result = true; return false; } [HarmonyPatch("GetAmountToGrab")] [HarmonyPrefix] private static bool GetAmountToGrab(MoveItemBehaviour __instance, ref int __result) { TransitRoute assignedRoute = __instance.assignedRoute; if (((assignedRoute != null) ? assignedRoute.Destination : null) == null) { return true; } ITransitEntity destination = __instance.assignedRoute.Destination; PackagingStation result; bool flag = Utils.Is2<PackagingStation>(destination, out result) && (Object)(object)result != (Object)null; ITransitEntity source = __instance.assignedRoute.Source; PackagingStation result2; bool flag2 = Utils.Is2<PackagingStation>(source, out result2) && (Object)(object)result2 != (Object)null; if (!flag && !flag2) { return true; } PackagingStation val = (flag ? result : result2); UnpackageSave.Instance.TryGetValue(((BuildableItem)val).GUID, out var value); if (!value) { return true; } ItemSlot firstSlotContainingTemplateItem = __instance.assignedRoute.Source.GetFirstSlotContainingTemplateItem(__instance.itemToRetrieveTemplate, (ESlotType)(flag ? 1 : 0)); ItemInstance val2 = ((firstSlotContainingTemplateItem != null) ? firstSlotContainingTemplateItem.ItemInstance : null); if (val2 == null) { __result = 0; return false; } int num = ((BaseItemInstance)val2).Quantity; if (__instance.maxMoveAmount > 0) { num = Mathf.Min(__instance.maxMoveAmount, num); } int num2 = (flag ? destination.GetOutputCapacityForItem(val2, ((Behaviour)__instance).Npc) : destination.GetInputCapacityForItem(val2, ((Behaviour)__instance).Npc, true)); __result = Mathf.Min(num, num2); return false; } [HarmonyPatch("GrabItem")] [HarmonyPrefix] private static bool GrabItem(MoveItemBehaviour __instance) { //IL_0102: Unknown result type (might be due to invalid IL or missing references) <>c__DisplayClass7_0 CS$<>8__locals0 = new <>c__DisplayClass7_0(); CS$<>8__locals0.__instance = __instance; TransitRoute assignedRoute = CS$<>8__locals0.__instance.assignedRoute; if (((assignedRoute != null) ? assignedRoute.Source : null) == null) { return true; } ITransitEntity destination = CS$<>8__locals0.__instance.assignedRoute.Destination; PackagingStation result; bool flag = Utils.Is2<PackagingStation>(destination, out result) && (Object)(object)result != (Object)null; ITransitEntity source = CS$<>8__locals0.__instance.assignedRoute.Source; PackagingStation result2; bool flag2 = Utils.Is2<PackagingStation>(source, out result2) && (Object)(object)result2 != (Object)null; if (!flag && !flag2) { return true; } PackagingStation val = (flag ? result : result2); UnpackageSave.Instance.TryGetValue(((BuildableItem)val).GUID, out var value); if (!value) { return true; } if (flag) { return true; } if (((Behaviour)CS$<>8__locals0.__instance).beh.DEBUG_MODE) { Console.Log((object)"MoveItemBehaviour.GrabItem", (Object)null); } CS$<>8__locals0.__instance.currentState = (EState)2; CS$<>8__locals0.__instance.grabRoutine = null; object value2 = MelonCoroutines.Start(Routine()); customGrabRunning[CS$<>8__locals0.__instance] = value2; return false; [IteratorStateMachine(typeof(<>c__DisplayClass7_0.<<GrabItem>g__Routine|0>d))] IEnumerator Routine() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <>c__DisplayClass7_0.<<GrabItem>g__Routine|0>d(0) { <>4__this = CS$<>8__locals0 }; } } [HarmonyPatch("TakeItem")] [HarmonyPrefix] private static bool TakeItem(MoveItemBehaviour __instance) { TransitRoute assignedRoute = __instance.assignedRoute; if (((assignedRoute != null) ? assignedRoute.Destination : null) == null) { return true; } ITransitEntity destination = __instance.assignedRoute.Destination; PackagingStation result; bool flag = Utils.Is2<PackagingStation>(destination, out result) && (Object)(object)result != (Object)null; ITransitEntity source = __instance.assignedRoute.Source; PackagingStation result2; bool flag2 = Utils.Is2<PackagingStation>(source, out result2) && (Object)(object)result2 != (Object)null; if (!flag && !flag2) { return true; } PackagingStation val = (flag ? result : result2); UnpackageSave.Instance.TryGetValue(((BuildableItem)val).GUID, out var value); if (!value) { return true; } if (((Behaviour)__instance).beh.DEBUG_MODE) { Console.Log((object)"MoveItemBehaviour.TakeItem", (Object)null); } int amountToGrab = __instance.GetAmountToGrab(); if (amountToGrab == 0) { Console.LogWarning((object)"Amount to grab is 0!", (Object)null); return false; } ItemSlot firstSlotContainingTemplateItem = __instance.assignedRoute.Source.GetFirstSlotContainingTemplateItem(__instance.itemToRetrieveTemplate, (ESlotType)(flag ? 1 : 0)); if (((firstSlotContainingTemplateItem != null) ? firstSlotContainingTemplateItem.ItemInstance : null) == null) { return false; } ItemInstance copy = firstSlotContainingTemplateItem.ItemInstance.GetCopy(amountToGrab); __instance.grabbedAmount = amountToGrab; firstSlotContainingTemplateItem.ChangeQuantity(-amountToGrab, false); ((Behaviour)__instance).Npc.Inventory.InsertItem(copy, true); if (flag) { destination.ReserveOutputSlotsForItem(copy, ((NetworkBehaviour)((Behaviour)__instance).Npc).NetworkObject); } else { destination.ReserveInputSlotsForItem(copy, ((NetworkBehaviour)((Behaviour)__instance).Npc).NetworkObject); } return false; } [HarmonyPatch("PlaceItem")] [HarmonyPrefix] private static bool PlaceItem(MoveItemBehaviour __instance) { //IL_010b: Unknown result type (might be due to invalid IL or missing references) <>c__DisplayClass9_0 CS$<>8__locals0 = new <>c__DisplayClass9_0(); CS$<>8__locals0.__instance = __instance; TransitRoute assignedRoute = CS$<>8__locals0.__instance.assignedRoute; if (((assignedRoute != null) ? assignedRoute.Destination : null) == null) { return true; } CS$<>8__locals0.dest = CS$<>8__locals0.__instance.assignedRoute.Destination; CS$<>8__locals0.destIsStation = Utils.Is2<PackagingStation>(CS$<>8__locals0.dest, out PackagingStation result) && (Object)(object)result != (Object)null; ITransitEntity source = CS$<>8__locals0.__instance.assignedRoute.Source; PackagingStation result2; bool flag = Utils.Is2<PackagingStation>(source, out result2) && (Object)(object)result2 != (Object)null; if (!CS$<>8__locals0.destIsStation && !flag) { return true; } PackagingStation val = (CS$<>8__locals0.destIsStation ? result : result2); UnpackageSave.Instance.TryGetValue(((BuildableItem)val).GUID, out var value); if (!value) { return true; } if (((Behaviour)CS$<>8__locals0.__instance).beh.DEBUG_MODE) { Console.Log((object)"MoveItemBehaviour.PlaceItem", (Object)null); } CS$<>8__locals0.__instance.currentState = (EState)4; CS$<>8__locals0.__instance.placingRoutine = null; object value2 = MelonCoroutines.Start(Routine()); customPlaceRunning[CS$<>8__locals0.__instance] = value2; return false; [IteratorStateMachine(typeof(<>c__DisplayClass9_0.<<PlaceItem>g__Routine|0>d))] IEnumerator Routine() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <>c__DisplayClass9_0.<<PlaceItem>g__Routine|0>d(0) { <>4__this = CS$<>8__locals0 }; } } [HarmonyPatch("StopCurrentActivity")] [HarmonyPrefix] private static bool StopCurrentActivity(MoveItemBehaviour __instance) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Invalid comparison between Unknown and I4 //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Invalid comparison between Unknown and I4 EState currentState = __instance.currentState; EState val = currentState; if ((int)val != 2) { if ((int)val == 4) { if (customPlaceRunning.TryGetValue(__instance, out var value)) { MelonCoroutines.Stop(value); customPlaceRunning.Remove(__instance); return false; } return true; } return true; } if (customGrabRunning.TryGetValue(__instance, out var value2)) { MelonCoroutines.Stop(value2); customGrabRunning.Remove(__instance); return false; } return true; } [HarmonyPatch("OnActiveTick")] [HarmonyPrefix] private static bool OnActiveTick(MoveItemBehaviour __instance) { //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Invalid comparison between Unknown and I4 if (!InstanceFinder.IsServer) { return false; } if (!__instance.assignedRoute.AreEntitiesNonNull()) { Console.LogWarning((object)"Transit route entities are null!", (Object)null); ((Behaviour)__instance).Disable_Networked((NetworkConnection)null); return false; } if (((Behaviour)__instance).beh.DEBUG_MODE) { Console.Log((object)("State: " + ((object)(EState)(ref __instance.currentState)).ToString()), (Object)null); Console.Log((object)("Moving: " + ((Behaviour)__instance).Npc.Movement.IsMoving), (Object)null); } if ((int)__instance.currentState > 0) { return false; } if (((Behaviour)__instance).Npc.Inventory.GetIdenticalItemAmount(__instance.itemToRetrieveTemplate) > 0 && __instance.grabbedAmount > 0) { if (__instance.IsAtDestination()) { __instance.PlaceItem(); } else { __instance.WalkToDestination(); } } else if (__instance.skipPickup) { __instance.TakeItem(); __instance.skipPickup = false; } else if (__instance.IsAtSource()) { __instance.GrabItem(); } else { __instance.WalkToSource(); } return false; } [HarmonyPatch("StartTransit")] [HarmonyPrefix] private static bool StartTransit(MoveItemBehaviour __instance) { //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Expected O, but got Unknown //IL_0217: Unknown result type (might be due to invalid IL or missing references) ITransitEntity destination = __instance.assignedRoute.Destination; PackagingStation result; bool flag = Utils.Is2<PackagingStation>(destination, out result) && (Object)(object)result != (Object)null; ITransitEntity source = __instance.assignedRoute.Source; PackagingStation result2; bool flag2 = Utils.Is2<PackagingStation>(source, out result2) && (Object)(object)result2 != (Object)null; if (!flag && !flag2) { return true; } object[] obj = new object[4] { __instance.assignedRoute.Source.Name, __instance.assignedRoute.Destination.Name, null, null }; ItemInstance itemToRetrieveTemplate = __instance.itemToRetrieveTemplate; obj[2] = ((itemToRetrieveTemplate != null) ? ((BaseItemInstance)itemToRetrieveTemplate).ID : null); ItemInstance itemToRetrieveTemplate2 = __instance.itemToRetrieveTemplate; obj[3] = ((itemToRetrieveTemplate2 != null) ? new int?(((BaseItemInstance)itemToRetrieveTemplate2).Quantity) : null); Console.Log((object)string.Format("{0} -> {1} ({2}x{3})", obj), (Object)null); if (!InstanceFinder.IsServer) { return false; } if (((Behaviour)__instance).Npc.Inventory.GetIdenticalItemAmount(__instance.itemToRetrieveTemplate) == 0) { ItemInstance itemToRetrieveTemplate3 = __instance.itemToRetrieveTemplate; if (((itemToRetrieveTemplate3 != null) ? ((BaseItemInstance)itemToRetrieveTemplate3).ID : null) == null) { return false; } string text = default(string); if (!__instance.IsTransitRouteValid(__instance.assignedRoute, ((BaseItemInstance)__instance.itemToRetrieveTemplate).ID, ref text)) { Console.LogWarning((object)("Invalid transit route for move item behaviour by checking transit route!. Reason: " + text), (Object)null); ((Behaviour)__instance).Disable_Networked((NetworkConnection)null); return false; } } else { ItemInstance firstIdenticalItem = ((Behaviour)__instance).Npc.Inventory.GetFirstIdenticalItem(__instance.itemToRetrieveTemplate, new ItemFilter(__instance.IsNpcInventoryItemValid)); if (((Behaviour)__instance).Npc.Behaviour.DEBUG_MODE) { Console.Log((object)("Moving item: " + (object)firstIdenticalItem), (Object)null); } string text2 = default(string); if (!__instance.IsDestinationValid(__instance.assignedRoute, firstIdenticalItem, ref text2)) { Console.LogWarning((object)("Invalid transit route for move item behaviour by checking destination! Reason: " + text2), (Object)null); ((Behaviour)__instance).Disable_Networked((NetworkConnection)null); return false; } } __instance.currentState = (EState)0; return false; } } [HarmonyPatch(typeof(Packager))] internal static class PackagerPatches { [HarmonyWrapSafe] [HarmonyPatch("GetStationMoveItems")] [HarmonyPrefix] private static bool GetStationMoveItems(Packager __instance, ref PackagingStation __result) { PackagingStation result = default(PackagingStation); bool value = default(bool); foreach (PackagingStation assignedStation in __instance.configuration.AssignedStations) { if ((Object)(object)assignedStation != (Object)null && Utils.Is<PackagingStation>(assignedStation, out result) && (Object)(object)result != (Object)null && UnpackageSave.Instance.TryGetValue(((BuildableItem)result).GUID, out value) && value) { List<ItemSlot> inputSlots = result.InputSlots; if (Utils.Is<PackagingStationConfiguration>(assignedStation.Configuration, out PackagingStationConfiguration config) && config != null) { bool flag = (from x in inputSlots.AsEnumerable() where x != null select x.ItemInstance into x where ((x != null) ? ((BaseItemInstance)x).ID : null) != null select x).Any((ItemInstance x) => ((Employee)__instance).MoveItemBehaviour.IsTransitRouteValid(config.DestinationRoute, ((BaseItemInstance)x).ID)); if (inputSlots.AsEnumerable().Sum((ItemSlot x) => x.Quantity) != 0 && flag) { __result = assignedStation; return false; } } } else { ItemSlot outputSlot = assignedStation.OutputSlot; if (Utils.Is<PackagingStationConfiguration>(assignedStation.Configuration, out PackagingStationConfiguration result2) && result2 != null && outputSlot.Quantity != 0 && ((Employee)__instance).MoveItemBehaviour.IsTransitRouteValid(result2.DestinationRoute, ((BaseItemInstance)outputSlot.ItemInstance).ID)) { __result = assignedStation; return false; } } } __result = null; return false; } [HarmonyPatch("StartMoveItem", new Type[] { typeof(PackagingStation) })] [HarmonyPrefix] private static bool StartMoveItem(Packager __instance, PackagingStation station) { UnpackageSave.Instance.TryGetValue(((BuildableItem)station).GUID, out var value); if (!value) { return true; } if (!Utils.Is<PackagingStationConfiguration>(station.Configuration, out PackagingStationConfiguration config) || config == null) { return true; } ItemSlot val = station.InputSlots.AsEnumerable().FirstOrDefault((Func<ItemSlot, bool>)delegate(ItemSlot x) { if (x.ItemInstance == null) { return false; } string text = default(string); bool flag = ((Employee)__instance).MoveItemBehaviour.IsTransitRouteValid(config.DestinationRoute, ((BaseItemInstance)x.ItemInstance).ID, ref text); if (!flag) { Console.Log((object)("[Unpacked] Rejected item " + ((BaseItemInstance)x.ItemInstance).ID + ": " + text), (Object)null); } return flag; }); if (val == null) { return true; } Console.Log((object)("[Unpacked] Starting moving items from " + ((Object)((Component)station).gameObject).name), (Object)null); ((Employee)__instance).MoveItemBehaviour.InitializeMoveItemBehaviourWithID(config.DestinationRoute, val.ItemInstance); ((Behaviour)((Employee)__instance).MoveItemBehaviour).Enable_Networked(); return false; } private static void InitializeMoveItemBehaviourWithID(this MoveItemBehaviour moveItemBehaviour, TransitRoute route, ItemInstance _itemToRetrieveTemplate, int _maxMoveAmount = -1, bool _skipPickup = false) { if (((_itemToRetrieveTemplate != null) ? ((BaseItemInstance)_itemToRetrieveTemplate).ID : null) == null) { return; } string text = default(string); if (!moveItemBehaviour.IsTransitRouteValid(route, ((BaseItemInstance)_itemToRetrieveTemplate).ID, ref text)) { Console.LogError((object)("Invalid transit route for move item behaviour! Reason: " + text), (Object)(object)((Component)moveItemBehaviour).gameObject); return; } moveItemBehaviour.assignedRoute = route; moveItemBehaviour.itemToRetrieveTemplate = _itemToRetrieveTemplate; moveItemBehaviour.maxMoveAmount = _maxMoveAmount; if (((Behaviour)moveItemBehaviour).Npc.Behaviour.DEBUG_MODE) { Console.Log((object)("MoveItemBehaviour initialized with route: " + route.Source.Name + " -> " + route.Destination.Name + " for item: " + ((BaseItemInstance)_itemToRetrieveTemplate).ID), (Object)null); } moveItemBehaviour.skipPickup = _skipPickup; } [HarmonyReversePatch(/*Could not decode attribute arguments.*/)] [HarmonyPatch(typeof(Employee), "UpdateBehaviour")] private static void UpdateEmployeeBehaviour(Employee __instance) { throw new NotImplementedException(); } [HarmonyPatch("UpdateBehaviour")] [HarmonyPrefix] private static bool UpdateBehaviour(Packager __instance) { UpdateEmployeeBehaviour((Employee)(object)__instance); if (((Behaviour)__instance.PackagingBehaviour).Active) { ((Employee)__instance).MarkIsWorking(); } else if (((Behaviour)((Employee)__instance).MoveItemBehaviour).Active) { ((Employee)__instance).MarkIsWorking(); } else { if (!InstanceFinder.IsServer) { return false; } if (((Employee)__instance).Fired) { ((Employee)__instance).LeavePropertyAndDespawn(); } else { if (!((Employee)__instance).CanWork()) { return false; } if (__instance.configuration.AssignedStationCount + __instance.configuration.Routes.Routes.Count == 0) { ((Employee)__instance).SubmitNoWorkReason("I haven't been assigned to any stations or routes.", "You can use your management clipboards to assign stations or routes to me.", 0); ((Employee)__instance).SetIdle(true); } else { if (!InstanceFinder.IsServer) { return false; } PackagingStation stationToAttend = __instance.GetStationToAttend(); if ((Object)(object)stationToAttend != (Object)null) { __instance.StartPackaging(stationToAttend); return false; } BrickPress brickPress = __instance.GetBrickPress(); if ((Object)(object)brickPress != (Object)null) { __instance.StartPress(brickPress); return false; } PackagingStation stationMoveItems = __instance.GetStationMoveItems(); if ((Object)(object)stationMoveItems != (Object)null) { __instance.StartMoveItem(stationMoveItems); return false; } BrickPress brickPressMoveItems = __instance.GetBrickPressMoveItems(); if ((Object)(object)brickPressMoveItems != (Object)null) { __instance.StartMoveItem(brickPressMoveItems); return false; } ItemInstance val = default(ItemInstance); AdvancedTransitRoute transitRouteReady = __instance.GetTransitRouteReady(ref val); if (transitRouteReady != null) { ((Employee)__instance).MoveItemBehaviour.Initialize((TransitRoute)(object)transitRouteReady, val, ((BaseItemInstance)val).Quantity, false); ((Behaviour)((Employee)__instance).MoveItemBehaviour).Enable_Networked(); } else { ((Employee)__instance).SubmitNoWorkReason("There's nothing for me to do right now.", "I need one of my assigned stations to have enough product and packaging to get to work.", 0); ((Employee)__instance).SetIdle(true); } } } } return false; } } public static class PackagingStationConfigPatches { public static Dictionary<Guid, StringField> UnpackageFields = new Dictionary<Guid, StringField>(); public static void InitializeField(PackagingStationConfiguration config, PackagingStation station) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected O, but got Unknown Guid key = Guid.Parse(((BuildableItem)station).GUID.ToString()); if (!UnpackageFields.ContainsKey(key)) { StringField value = new StringField((EntityConfiguration)(object)config, "false"); UnpackageFields[key] = value; } else { ((EntityConfiguration)config).Fields.Add((ConfigField)(object)UnpackageFields[key]); } } } [HarmonyPatch(typeof(PackagingStationConfiguration))] public class PackagingStationConfigurationPatch { [HarmonyPostfix] [HarmonyPatch(/*Could not decode attribute arguments.*/)] public static void ConstructorPostfix(PackagingStationConfiguration __instance, PackagingStation station) { if (__instance != null && !((Object)(object)station == (Object)null)) { PackagingStationConfigPatches.InitializeField(__instance, station); } } } [HarmonyPatch(typeof(PackagingStationConfigPanel))] public class PackagingStationConfigPanelPatch { [HarmonyPostfix] [HarmonyPatch("BindInternal")] public static void BindInternalPostfix(PackagingStationConfigPanel __instance, List<EntityConfiguration> configs) { //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Expected O, but got Unknown //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Expected O, but got Unknown //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Unknown result type (might be due to invalid IL or missing references) //IL_021f: Unknown result type (might be due to invalid IL or missing references) //IL_0226: Expected O, but got Unknown //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_0267: Unknown result type (might be due to invalid IL or missing references) //IL_027e: Unknown result type (might be due to invalid IL or missing references) //IL_0295: Unknown result type (might be due to invalid IL or missing references) //IL_02ac: Unknown result type (might be due to invalid IL or missing references) //IL_0326: Unknown result type (might be due to invalid IL or missing references) //IL_031f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null || (Object)(object)__instance.DestinationUI == (Object)null) { return; } try { PackagingStationConfiguration val = null; foreach (EntityConfiguration config in configs) { if (!Utils.Is<PackagingStationConfiguration>(config, out PackagingStationConfiguration result) || result == null) { continue; } val = result; break; } if ((Object)(object)((val != null) ? val.Station : null) == (Object)null) { return; } Guid stationGuid = Guid.Parse(((BuildableItem)val.Station).GUID.ToString()); if (!PackagingStationConfigPatches.UnpackageFields.TryGetValue(stationGuid, out var _)) { PackagingStationConfigPatches.InitializeField(val, val.Station); } Transform parent = ((Component)__instance.DestinationUI).transform.parent; GameObject val2 = new GameObject("UnpackageToggle"); val2.transform.SetParent(parent, false); RectTransform val3 = val2.AddComponent<RectTransform>(); RectTransform component = ((Component)__instance.DestinationUI).GetComponent<RectTransform>(); val3.sizeDelta = new Vector2(400f, 50f); GameObject val4 = new GameObject("Title"); val4.transform.SetParent(val2.transform, false); RectTransform val5 = val4.AddComponent<RectTransform>(); val5.anchorMin = new Vector2(0f, 0.5f); val5.anchorMax = new Vector2(0f, 0.5f); val5.pivot = new Vector2(0f, 0.5f); val5.anchoredPosition = new Vector2(0f, 0f); val5.sizeDelta = new Vector2(150f, 30f); TextMeshProUGUI val6 = val4.AddComponent<TextMeshProUGUI>(); ((TMP_Text)val6).fontSize = 24f; ((TMP_Text)val6).alignment = (TextAlignmentOptions)513; ((TMP_Text)val6).text = "Set Unpackage"; ((Graphic)val6).color = Color.black; GameObject val7 = new GameObject("Value"); val7.transform.SetParent(val2.transform, false); RectTransform val8 = val7.AddComponent<RectTransform>(); val8.anchorMin = new Vector2(1f, 0.5f); val8.anchorMax = new Vector2(1f, 0.5f); val8.pivot = new Vector2(1f, 0.5f); val8.anchoredPosition = new Vector2(0f, 0f); val8.sizeDelta = new Vector2(80f, 30f); TextMeshProUGUI valueTmpro = val7.AddComponent<TextMeshProUGUI>(); ((TMP_Text)valueTmpro).fontSize = 24f; ((TMP_Text)valueTmpro).alignment = (TextAlignmentOptions)516; UnpackageSave.Instance.TryGetValue(stationGuid, out var value2); ((TMP_Text)valueTmpro).text = (value2 ? "On" : "Off"); ((Graphic)valueTmpro).color = (value2 ? Color.green : Color.gray); Button val9 = val7.AddComponent<Button>(); ((UnityEventBase)val9.onClick).RemoveAllListeners(); string s = ""; EventHelper.AddListener((Action)delegate { //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) s = s; MelonLogger.Msg("Button clicked"); UnpackageSave instance = UnpackageSave.Instance; if (instance?.UnpackageStations != null) { if (!instance.UnpackageStations.TryAdd(stationGuid, value: true)) { instance.UnpackageStations[stationGuid] = !instance.UnpackageStations[stationGuid]; } bool flag = instance.UnpackageStations[stationGuid]; ((TMP_Text)valueTmpro).text = (flag ? "On" : "Off"); ((Graphic)valueTmpro).color = (flag ? Color.green : Color.gray); } }, (UnityEvent)(object)val9.onClick); UIContentPanel component2 = ((Component)__instance).GetComponent<UIContentPanel>(); if ((Object)(object)component2 != (Object)null) { UISelectable val10 = val7.GetComponent<UISelectable>(); if ((Object)(object)val10 == (Object)null) { val10 = val7.AddComponent<UISelectable>(); } ((UIPanel)component2).AddSelectable(val10); } } catch (Exception arg) { MelonLogger.Error($"BindInternalPostfix failed: {arg}"); } } } [HarmonyPatch(typeof(PackagingStation))] internal static class PackagingStationPatches { [HarmonyPatch("PackSingleInstance")] [HarmonyPrefix] private static bool UnpackIfConfigured(PackagingStation __instance) { if (__instance != null) { _ = ((BuildableItem)__instance).GUID; if (0 == 0) { UnpackageSave.Instance.TryGetValue(((BuildableItem)__instance).GUID, out var value); if (!value) { return true; } __instance.Unpack(); return false; } } return true; } } [HarmonyPatch(typeof(PackagingStationBehaviour))] internal static class PackagingStationBehaviourPatches { [HarmonyPatch("IsStationReady")] [HarmonyPrefix] private static bool IsStationReady(PackagingStationBehaviour __instance, PackagingStation station, ref bool __result) { //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Invalid comparison between Unknown and I4 if ((Object)(object)station == (Object)null) { __result = false; return false; } NPC npc = ((Behaviour)__instance).Npc; Utils.Is2<IUsable>(station, out IUsable result); if (result != null && result.IsInUse && (Object)(object)station.NPCUserObject != (Object)(object)((NetworkBehaviour)npc).NetworkObject) { __result = false; return false; } if (!npc.Movement.CanGetTo(station.StandPoint.position, 1f)) { __result = false; return false; } UnpackageSave.Instance.TryGetValue(((BuildableItem)station).GUID, out var value); EMode val = (EMode)(value ? 1 : 0); if ((int)station.GetState(val) > 0) { __result = false; return false; } __result = true; return false; } } public static class TransitEntityExtensions { public static List<ItemSlot> ReserveOutputSlotsForItem(this ITransitEntity entity, ItemInstance item, NetworkObject locker) { List<ItemSlot> list = new List<ItemSlot>(); int num = ((BaseItemInstance)item).Quantity; for (int i = 0; i < entity.OutputSlots.Count; i++) { int capacityForItem = entity.OutputSlots[i].GetCapacityForItem(item, false); if (capacityForItem != 0) { int num2 = Mathf.Min(capacityForItem, num); num -= num2; entity.OutputSlots[i].ApplyLock(locker, "Employee is about to place an item here", false); list.Add(entity.OutputSlots[i]); if (num <= 0) { break; } } } return list; } public static void RemoveOutputSlotLocks(this ITransitEntity entity, NetworkObject locker) { for (int i = 0; i < entity.OutputSlots.Count; i++) { if (entity.OutputSlots[i].ActiveLock != null && (Object)(object)entity.OutputSlots[i].ActiveLock.LockOwner == (Object)(object)locker) { entity.OutputSlots[i].RemoveLock(false); } } } } } namespace EmployeeTweaks.Patches.QualityEmployeeWorkSpeed { [HarmonyPatch] internal static class EffectPatches { private static Instance _logger = new Instance("EmployeeTweaks.QualityEmployeeWorkSpeed"); [HarmonyPatch(typeof(ProductItemInstance), "ApplyEffectsToNPC")] [HarmonyPrefix] private static bool ApplyEffectsToEmployee(ProductItemInstance __instance, NPC npc) { //IL_0104: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)((__instance != null) ? ((ItemInstance)__instance).Definition : null) == (Object)null) { return true; } if ((Object)(object)npc == (Object)null) { return true; } if (!Utils.Is<Employee>(npc, out Employee result) || (Object)(object)result == (Object)null) { return true; } if (!Utils.Is<ProductDefinition>(((ItemInstance)__instance).Definition, out ProductDefinition result2) || (Object)(object)result2 == (Object)null) { return true; } List<Effect> list = new List<Effect>(); list.AddRange(((PropertyItemDefinition)result2).Properties.AsEnumerable()); list = list.OrderBy((Effect x) => x.Tier).ToList(); StackEntry val = default(StackEntry); foreach (Effect item in list) { item.ApplyToEmployee(result); if (result.WorkSpeedController.TryGetEntry(item.Name, ref val)) { float num = ApplyQuality(val.Value, GetQualityMult(((QualityItemInstance)__instance).Quality)); _logger.Msg($"Applying quality transformation to {item.Name}: was {val.Value}, is {num}"); val.Value = num; result.WorkSpeedController.Recalculate(); } } return false; } private static float GetQualityMult(EQuality quality) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected I4, but got Unknown if (1 == 0) { } float result = (int)quality switch { 0 => 0.4f, 1 => 0.7f, 2 => 1f, 3 => 1.2f, 4 => 1.5f, _ => 1f, }; if (1 == 0) { } return result; } private static float ApplyQuality(float baseValue, float m) { float num = 1f + (m - 1f) * 1.2f; float num2 = baseValue * 0.9f; float num3 = baseValue * 1.2f; return Mathf.Lerp(num2, num3, Mathf.InverseLerp(0.4f, 1.5f, num)); } } } namespace EmployeeTweaks.Patches.FilterItemApply { [HarmonyPatch(typeof(FilterConfigPanel))] internal class FilterConfigPanelPatches { private static Instance _logger = new Instance("EmployeeTweaks.FilterItemApply"); internal const string Filter1 = "Apply Item As Filter"; internal const string Filter2 = "Apply All As Filters"; internal static bool AllSlots; internal static bool DenyListMode; internal static TextMeshProUGUI ApplyItemAsFilterButtonText; private static Button _applyItemAsFilterButton; [HarmonyPatch("Awake")] [HarmonyPostfix] private static void AddButton(FilterConfigPanel __instance) { Button applyToSiblingsButton = __instance.ApplyToSiblingsButton; if ((Object)(object)applyToSiblingsButton == (Object)null) { return; } GameObject val = Object.Instantiate<GameObject>(((Component)applyToSiblingsButton).gameObject, ((Component)applyToSiblingsButton).transform.parent); _applyItemAsFilterButton = val.GetComponent<Button>(); ApplyItemAsFilterButtonText = ((Component)_applyItemAsFilterButton).GetComponentInChildren<TextMeshProUGUI>(); ((TMP_Text)ApplyItemAsFilterButtonText).text = "Apply Item As Filter"; ((UnityEventBase)_applyItemAsFilterButton.onClick).RemoveAllListeners(); string s = ""; EventHelper.AddListener((Action)delegate { s = s; if (AllSlots) { ApplyItemsAsFilters(__instance.OpenSlot); } else { ApplyItemAsFilter(__instance.OpenSlot); } }, (UnityEvent)(object)_applyItemAsFilterButton.onClick); } private static void ApplyItemAsFilter(ItemSlot itemSlot) { //IL_00a3: Unknown result type (might be due to invalid IL or missing references) if (!AllSlots) { _logger.Msg("Applying item as filter"); } ItemInstance itemInstance = itemSlot.ItemInstance; if (((itemInstance != null) ? ((BaseItemInstance)itemInstance).ID : null) == null) { _logger.Warning("No item in slot to apply as filter."); return; } SlotFilter playerFilter = itemSlot.PlayerFilter; if (playerFilter?.ItemIDs == null) { _logger.Warning("Player filter is null or does not have an ItemIDs list."); return; } playerFilter.ItemIDs.Clear(); playerFilter.ItemIDs.Add(((BaseItemInstance)itemInstance).ID); playerFilter.Type = (EType)((!DenyListMode) ? 1 : 2); itemSlot.SetPlayerFilter(playerFilter, false); } private static void ApplyItemsAsFilters(ItemSlot itemSlot) { _logger.Msg("Applying all items in sibling slots as filters."); foreach (ItemSlot slot in itemSlot.SiblingSet.Slots) { ApplyItemAsFilter(slot); } } } } namespace EmployeeTweaks.Patches.EmployeeArea { internal class DebugAreaDrawer { private Instance Logger = new Instance("EmployeeTweaks.DebugAreaDrawer"); private List<GameObject> _areas = new List<GameObject>(); internal void Draw() { //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: 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_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) foreach (GameObject area in _areas) { if ((Object)(object)area != (Object)null) { Object.DestroyImmediate((Object)(object)area); } } _areas.Clear(); if (!EmployeeTweaks.EnableCapacityAndDebug.Value || !EmployeeTweaks.DrawDebugArea.Value) { return; } Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(0f, 0.1f, 0f); foreach (var value in PropertyPatch._propertyIdlePointRects.Values) { Logger.Msg($"Drawing Employee Area at {value.Item1 + val}, {value.Item2 + val}"); GameObject item = DrawDebugArea(value.Item1 + val, value.Item2 + val, new Color(1f, 0f, 0f, 0.2f)); _areas.Add(item); } } private static GameObject DrawDebugArea(Vector3 a, Vector3 b, Color color) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Expected O, but got Unknown //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) GameObject val = GameObject.CreatePrimitive((PrimitiveType)5); ((Object)val).name = "DebugArea"; Object.Destroy((Object)(object)val.GetComponent<Collider>()); Vector3 val2 = Vector3.Min(a, b); Vector3 val3 = Vector3.Max(a, b); Vector3 val4 = (val2 + val3) * 0.5f; Vector3 val5 = val3 - val2; val.transform.position = val4 + Vector3.up * 0.01f; val.transform.rotation = Quaternion.Euler(90f, 0f, 0f); val.transform.localScale = new Vector3(val5.x, val5.z, 1f); MeshRenderer component = val.GetComponent<MeshRenderer>(); Shader val6 = Shader.Find("Universal Render Pipeline/Lit"); if ((Object)(object)val6 == (Object)null) { return val; } Material val7 = new Material(val6); if (val7.HasProperty("_Surface")) { val7.SetFloat("_Surface", 1f); } if (color.a <= 0f) { color.a = 0.2f; } if (val7.HasProperty("_BaseColor")) { val7.SetColor("_BaseColor", color); } if (val7.HasProperty("_EmissionColor")) { val7.EnableKeyword("_EMISSION"); val7.SetColor("_EmissionColor", new Color(color.r, color.g, color.b) * 1.5f); } val7.SetInt("_ZWrite", 0); val7.renderQueue = 3000; ((Renderer)component).material = val7; return val; } } [HarmonyPatch(typeof(Property))] internal class PropertyPatch { private static Instance Logger = new Instance("EmployeeTweaks.PropertyPatch"); internal static Dictionary<Property, (Vector3, Vector3)> _propertyIdlePointRects = new Dictionary<Property, (Vector3, Vector3)>(); [HarmonyPatch("NetworkInitialize___Early")] [HarmonyPriority(-100)] [HarmonyPrefix] private static void StorePointRectAndAddCapacity(Property __instance) { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) if (!EmployeeTweaks.EnableCapacityAndDebug.Value) { return; } Transform[] employeeIdlePoints = __instance.EmployeeIdlePoints; if (employeeIdlePoints != null && employeeIdlePoints.Length > 0) { var (val, val2) = MinMaxPoints(employeeIdlePoints.AsEnumerable().ToList()); if (val == val2) { val2 = val + new Vector3(0.5f, 0f, 0.5f); } _propertyIdlePointRects[__instance] = (val, val2); } if (__instance.EmployeeCapacity <= 0) { return; } MelonPreferences_Entry<int> entry = EmployeeTweaks.EmployeeCapacityCategory.GetOrCreateEntry("EmployeeTweaks_" + __instance.propertyCode + "_EmpCap", __instance.EmployeeCapacity, __instance.propertyName + " Employee Capacity", "Max amount of employees you can hire for this property", isHidden: false, dontSaveDefault: false, (ValueValidator)(object)new ValueRange<int>(1, Mathf.CeilToInt((float)__instance.EmployeeCapacity * 1.5f) + 1)); EmployeeTweaks.EmployeeCapacities.Add(entry); ((MelonEventBase<LemonAction<int, int>>)(object)entry.OnEntryValueChanged).Subscribe((LemonAction<int, int>)delegate(int oldVal, int newVal) { if (oldVal != newVal) { AddCapacity(__instance, newVal); } }, 0, false); AddCapacity(__instance, entry.Value); void AddCapacity(Property prop, int target) { //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0253: Unknown result type (might be due to invalid IL or missing references) //IL_0258: Unknown result type (might be due to invalid IL or missing references) //IL_026b: Unknown result type (might be due to invalid IL or missing references) //IL_0272: Expected O, but got Unknown //IL_0293: Unknown result type (might be due to invalid IL or missing references) //IL_02a9: Unknown result type (might be due to invalid IL or missing references) int num = prop.Employees?.AsEnumerable().Count() ?? 0; (Vector3, Vector3) value; if (target < num) { Logger.Warning($"Cannot set capacity of {prop.propertyName} to {target} because it currently has {num} employees"); entry.Value = prop.EmployeeCapacity; } else if (!_propertyIdlePointRects.TryGetValue(prop, out value)) { Logger.Warning("Could not find idle point rect for " + prop.propertyName + ", cannot add capacity"); entry.Value = prop.EmployeeCapacity; } else { Transform[] employeeIdlePoints2 = prop.EmployeeIdlePoints; int num2 = ((employeeIdlePoints2 != null) ? employeeIdlePoints2.Length : 0); int num3 = target - num2; if (num3 <= 0) { if (num2 <= 0) { entry.Value = prop.EmployeeCapacity; } else { List<Transform> list = prop.EmployeeIdlePoints.AsEnumerable().ToList(); list = list.GetRange(0, target); prop.EmployeeIdlePoints = list.ToArray(); prop.EmployeeCapacity = list.Count; } } else { List<Vector3> list2 = PoissonDiskSampler2D.SampleAdaptive(value.Item1, value.Item2, (prop.EmployeeIdlePoints?.AsEnumerable() ?? Array.Empty<Transform>()).ToList(), num3, 1f, 0.01f, prop.propertyCode.GetHashCode()); int count = list2.Count; Transform[] employeeIdlePoints3 = prop.EmployeeIdlePoints; if (count + ((employeeIdlePoints3 != null) ? employeeIdlePoints3.Length : 0) < target) { Logger.Warning($"Generated {list2.Count} new points for {prop.propertyName} but needed {num3}, cannot add capacity"); entry.Value = prop.EmployeeCapacity; } else { List<Transform> list3 = new List<Transform>(); Transform val3 = prop.EmployeeIdlePoints?.FirstOrDefault(); if ((Object)(object)val3 == (Object)null) { Logger.Warning("Property " + prop.propertyName + " has no idle points, cannot add capacity"); entry.Value = prop.EmployeeCapacity; } else { foreach (Vector3 item2 in list2) { GameObject val4 = new GameObject(prop.propertyName + "_EmployeeIdlePoint"); val4.transform.SetParent(((Component)val3).transform.parent, false); val4.transform.position = item2; val4.transform.rotation = ((Component)val3).transform.rotation; list3.Add(val4.transform); } Transform[] employeeIdlePoints4 = prop.EmployeeIdlePoints; foreach (Transform item in employeeIdlePoints4) { list3.Add(item); } prop.EmployeeIdlePoints = list3.ToArray(); prop.EmployeeCapacity = list3.Count; } } } } } } private static (Vector3 min, Vector3 max) MinMaxPoints(List<Transform> transforms) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) if (transforms == null || transforms.Count == 0) { throw new ArgumentException("Empty list"); } Vector3 position = transforms[0].position; Vector3 val = position; Vector3 val2 = position; for (int i = 1; i < transforms.Count; i++) { Vector3 position2 = transforms[i].position; val = Vector3.Min(val, position2); val2 = Vector3.Max(val2, position2); } return (val, val2); } } public static class PoissonDiskSampler2D { private static Random _rng; public static List<Vector3> SampleAdaptive(Vector3 min, Vector3 max, List<Transform> blocked, int targetCount, float preferredRadius, float minRadius, int seed, int maxIterations = 5, int k = 30) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) _rng = new Random(seed); float num = preferredRadius; List<Vector3> list = new List<Vector3>(); for (int i = 0; i < maxIterations; i++) { List<Vector3> list2 = Sample(min, max, blocked, num, k); if (list2.Count >= targetCount) { return list2.GetRange(0, targetCount); } if (list2.Count > list.Count) { list = list2; } num *= 0.7f; if (num < minRadius) { break; } } if (list.Count < targetCount) { list.AddRange(Fill(min, max, blocked, list, targetCount - list.Count, minRadius)); } return list; } private static List<Vector3> Sample(Vector3 min, Vector3 max, List<Transform> blocked, float radius, int k) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) float num = radius / Mathf.Sqrt(2f); int num2 = Mathf.CeilToInt((max.x - min.x) / num); int num3 = Mathf.CeilToInt((max.z - min.z) / num); Vector3?[,] grid = new Vector3?[num2, num3]; List<Vector3> list = new List<Vector3>(); List<Vector3> list2 = new List<Vector3>(); Vector3 val = RandomPoint(min, max); list.Add(val); list2.Add(val); Set(grid, min, num, val); while (list.Count > 0) { int index = _rng.Next(list.Count); Vector3 p = list[index]; bool flag = false; for (int i = 0; i < k; i++) { Vector3 val2 = GenerateAround(p, radius); if (IsValid(val2, min, max, radius, grid, blocked, num)) { list.Add(val2); list2.Add(val2); Set(grid, min, num, val2); flag = true; break; } } if (!flag) { list.RemoveAt(index); } } return list2; } private static List<Vector3> Fill(Vector3 min, Vector3 max, List<Transform> blocked, List<Vector3> current, int needed, float epsilon) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0019: 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_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) List<Vector3> list = new List<Vector3>(); float epsSqr = epsilon * epsilon; int num = 0; int num2 = needed * 20; while (list.Count < needed && num++ < num2) { Vector3 val = RandomPoint(min, max); if (!TooClose(val, blocked, current, list, epsSqr)) { list.Add(val); } } return list; } private static Vector3 RandomPoint(Vector3 min, Vector3 max) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) return new Vector3(Lerp(min.x, max.x), min.y, Lerp(min.z, max.z)); } private static Vector3 GenerateAround(Vector3 p, float radius) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) float num = (float)(_rng.NextDouble() * 3.1415927410125732 * 2.0); float num2 = Lerp(radius, radius * 2f); return new Vector3(p.x + Mathf.Cos(num) * num2, p.y, p.z + Mathf.Sin(num) * num2); } private static bool IsValid(Vector3 p, Vector3 min, Vector3 max, float radius, Vector3?[,] grid, List<Transform> blocked, float cellSize) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: 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_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) if (p.x < min.x || p.x > max.x || p.z < min.z || p.z > max.z) { return false; } float num = radius * radius; if (TooClose(p, blocked, null, null, num)) { return false; } int num2 = (int)((p.x - min.x) / cellSize); int num3 = (int)((p.z - min.z) / cellSize); for (int i = -2; i <= 2; i++) { for (int j = -2; j <= 2; j++) { int num4 = num2 + i; int num5 = num3 + j; if (num4 >= 0 && num5 >= 0 && num4 < grid.GetLength(0) && num5 < grid.GetLength(1) && grid[num4, num5].HasValue) { Vector3 val = grid[num4, num5].Value - p; if (((Vector3)(ref val)).sqrMagnitude < num) { return false; } } } } return true; } private static void Set(Vector3?[,] grid, Vector3 min, float cellSize, Vector3 p) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) int num = (int)((p.x - min.x) / cellSize); int num2 = (int)((p.z - min.z) / cellSize); grid[num, num2] = p; } private static bool TooClose(Vector3 p, List<Transform> blocked, List<Vector3> a, List<Vector3> b, float epsSqr) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: 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_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) Vector3 val; foreach (Transform item in blocked) { val = item.position - p; if (((Vector3)(ref val)).sqrMagnitude < epsSqr) { return true; } } if (a != null) { foreach (Vector3 item2 in a) { val = item2 - p; if (((Vector3)(ref val)).sqrMagnitude < epsSqr) { return true; } } } if (b != null) { foreach (Vector3 item3 in b) { val = item3 - p; if (((Vector3)(ref val)).sqrMagnitude < epsSqr) { return true; } } } return false; } private static float Lerp(float a, float b) { return a + (float)_rng.NextDouble() * (b - a); } } } namespace EmployeeTweaks.Patches.BotanistSprinklersPourer { [HarmonyPatch(typeof(GrowContainerBehaviour))] internal class GrowContainerBehaviourPatch { [CompilerGenerated] private sealed class <PourerRoutine>d__2 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public AddSoilToGrowContainerBehaviour addSoilToGrowContainerBehaviour; public SoilPourer soilPourer; public ItemSlot slot; public SoilDefinition soilDefinition; private float <waitTime>5__1; private ItemInstance <usedItem>5__2; private Botanist <botanist>5__3; private Exception <e>5__4; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <PourerRoutine>d__2(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <usedItem>5__2 = null; <botanist>5__3 = null; <e>5__4 = null; <>1__state = -2; } private bool MoveNext() { //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <waitTime>5__1 = ((GrowContainerBehaviour)addSoilToGrowContainerBehaviour).GetActionDuration() / ((Employee)((GrowContainerBehaviour)addSoilToGrowContainerBehaviour)._botanist).CurrentWorkSpeed; <waitTime>5__1 *= 0.25f; soilPourer.SetSoil((NetworkConnection)null, ((BaseItemDefinition)soilDefinition).ID); <>2__current = (object)new WaitForSeconds(<waitTime>5__1); <>1__state = 1; return true; case 1: <>1__state = -1; if (!soilPourer.isDispensing) { soilPourer.PourSoil(); } <usedItem>5__2 = null; try { ItemSlot obj = slot; <usedItem>5__2 = ((obj != null) ? obj.ItemInstance.GetCopy(1) : null); } catch (Exception ex) { <e>5__4 = ex; return false; } ((GrowContainerBehaviour)addSoilToGrowContainerBehaviour).OnStopPerformAction(); ((GrowContainerBehaviour)addSoilToGrowContainerBehaviour).OnActionSuccess(<usedItem>5__2); if (slot != null && slot.Quantity > 0) { slot.ChangeQuantity(-1, false); } ((Behaviour)addSoilToGrowContainerBehaviour).Disable_Networked((NetworkConnection)null); if (Utils.Is<Botanist>(((Behaviour)addSoilToGrowContainerBehaviour).Npc, out <botanist>5__3)) { Botanist obj2 = <botanist>5__3; if (obj2 != null) { ((Employee)obj2).SetIdle(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(); } } [HarmonyPatch("OnActiveTick")] [HarmonyPostfix] private static void UseSprinklerOrPourer(GrowContainerBehaviour __instance) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Invalid comparison between Unknown and I4 if (!InstanceFinder.IsServer || (int)__instance._currentState != 3 || !__instance.IsAtGrowContainer()) { return; } if (Utils.Is<WaterPotBehaviour>(__instance, out WaterPotBehaviour result) && (Object)(object)result != (Object)null) { if (!Utils.Is<Pot>(((GrowContainerBehaviour)result)._growContainer, out Pot pot2)) { return; } HashSet<GridItem> itemsAroundItem = GetItemsAroundItem((GridItem)(object)pot2); MelonDebug.Msg("Found " + itemsAroundItem.Count + " items around the pot"); foreach (GridItem item in itemsAroundItem) { if (!Utils.Is<Sprinkler>(item, out Sprinkler result2) || (Object)(object)result2 == (Object)null) { continue; } List<Pot> pots = result2.GetPots(); if ((Object)(object)pots.AsEnumerable().FirstOrDefault((Func<Pot, bool>)((Pot x) => (Object)(object)x != (Object)null && (Object)(object)x == (Object)(object)pot2)) == (Object)null) { continue; } MelonDebug.Msg("It's an eligible sprinkler, activating it"); if (!result2.IsSprinkling) { result2.Interacted(); } ((GrowContainerBehaviour)result).OnStopPerformAction(); ((GrowContainerBehaviour)result).OnActionSuccess((ItemInstance)null); ((Behaviour)result).Disable_Networked((NetworkConnection)null); if (Utils.Is<Botanist>(((Behaviour)result).Npc, out Botanist result3) && result3 != null) { ((Employee)result3).SetIdle(true); } break; } } if (!Utils.Is<AddSoilToGrowContainerBehaviour>(__instance, out AddSoilToGrowContainerBehaviour result4) || !((Object)(object)result4 != (Object)null)) { return; } if (!Utils.Is<Pot>(((GrowContainerBehaviour)result4)._growContainer, out Pot pot)) { return; } HashSet<GridItem> itemsAroundItem2 = GetItemsAroundItem((GridItem)(object)pot); MelonDebug.Msg("Found " + itemsAroundItem2.Count + " items around the pot"); string[] array = default(string[]); foreach (GridItem item2 in itemsAroundItem2) { if (!Utils.Is<SoilPourer>(item2, out SoilPourer result5) || (Object)(object)result5 == (Object)null) { continue; } List<Pot> pots2 = result5.GetPots(); if (!((Object)(object)pots2.AsEnumerable().FirstOrDefault((Func<Pot, bool>)((Pot x) => (Object)(object)x != (Object)null && (Object)(object)x == (Object)(object)pot)) == (Object)null)) { MelonDebug.Msg("It's a eligible soil pourer, activating it"); if (!((GrowContainerBehaviour)result4).AreTaskConditionsMetForContainer((GrowContainer)(object)pot)) { MelonDebug.Msg("Conditions not met"); ((Behaviour)result4).Disable_Networked((NetworkConnection)null); break; } ItemSlot val = null; if (((GrowContainerBehaviour)result4).DoesTaskRequireItem((GrowContainer)(object)pot, ref array)) { val = ((GrowContainerBehaviour)result4).GetItemSlotContainingRequiredItem((IItemSlotOwner)(object)((NPC)((GrowContainerBehaviour)result4)._botanist).Inventory, array); } ItemInstance val2 = ((val != null) ? val.ItemInstance.GetCopy(1) : null); if (val2 == null) { break; } if (!Utils.Is<SoilDefinition>(val2.Definition, out SoilDefinition result6) || (Object)(object)result6 == (Object)null) { MelonDebug.Msg("No soil in inventory"); ((Behaviour)result4).Disable_Networked((NetworkConnection)null); break; } if (((GrowContainerBehaviour)result4).CheckSuccess(val2)) { MelonCoroutines.Start(PourerRoutine(result4, result5, val, result6)); } else { ((Behaviour)result4).Disable_Networked((NetworkConnection)null); } } } } private static HashSet<GridItem> GetItemsAroundItem(GridItem item) { //IL_0015: 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_0024: Expected O, but got Unknown //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Expected O, but got Unknown //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Expected O, but got Unknown //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Expected O, but got Unknown Coordinate origin = new Coordinate(item._originCoordinate); List<Coordinate> list = new List<Coordinate>(); for (int i = -1; i <= 2; i++) { list.Add(new Coordinate(i, -1)); list.Add(new Coordinate(i, 2)); } for (int j = 0; j <= 1; j++) { list.Add(new Coordinate(-1, j)); list.Add(new Coordinate(2, j)); } List<Coordinate> list2 = list.Select((Coordinate offset) => origin + Coordinate.RotateCoordinates(offset, (float)item._rotation)).ToList(); HashSet<GridItem> hashSet = new HashSet<GridItem>(); foreach (Coordinate item2 in list2) { Tile tile = item.OwnerGrid.GetTile(item2); if ((Object)(object)tile == (Object)null) { continue; } foreach (GridItem buildableOccupant in tile.BuildableOccupants) { hashSet.Add(buildableOccupant); } } return hashSet; } [IteratorStateMachine(typeof(<PourerRoutine>d__2))] private static IEnumerator PourerRoutine(AddSoilToGrowContainerBehaviour addSoilToGrowContainerBehaviour, SoilPourer soilPourer, ItemSlot slot, SoilDefinition soilDefinition) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <PourerRoutine>d__2(0) { addSoilToGrowContainerBehaviour = addSoilToGrowContainerBehaviour, soilPourer = soilPourer, slot = slot, soilDefinition = soilDefinition }; } } } namespace EmployeeTweaks.Helpers { public static class MelonExtensions { public static void Debug(this Instance logger, string message, bool stacktrace = true) { MelonDebug.Msg(stacktrace ? ("[" + GetCallerInfo() + "] " + message) : message); } private static string GetCallerInfo() { StackTrace stackTrace = new StackTrace(); for (int i = 2; i < stackTrace.FrameCount; i++) { StackFrame frame = stackTrace.GetFrame(i); MethodBase method = frame.GetMethod(); if (!(method?.DeclaringType == null)) { return method.DeclaringType.FullName + "." + method.Name; } } return "unknown"; } public static MelonPreferences_Entry<T> GetOrCreateEntry<T>(this MelonPreferences_Category category, string identifier, T defaultValue, string displayName = null, string description = null, bool isHidden = false, bool dontSaveDefault = false, ValueValidator validator = null, string oldIdentifier = null) { if (category.HasEntry(identifier)) { return category.GetEntry<T>(identifier); } return category.CreateEntry<T>(identifier, defaultValue, displayName, description, isHidden, dontSaveDefault, validator, oldIdentifier); } } public static class Il2CppListExtensions { public static IEnumerable<T> AsEnumerable<T>(this List<T> list) { return list ?? new List<T>(); } public static object ToNativeList<T>(this List<T> source) { return source ?? new List<T>(); } } public static class Utils { [CompilerGenerated] private sealed class <WaitForCondition>d__7 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Func<bool> condition; public float timeout; public Action onTimeout; public Action onFinish; private float <startTime>5__1; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <WaitForCondition>d__7(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <startTime>5__1 = Time.time; break; case 1: <>1__state = -1; break; } if (!condition()) { if (!float.IsNaN(timeout) && Time.time - <startTime>5__1 > timeout) { onTimeout?.Invoke(); return false; } <>2__current = null; <>1__state = 1; return true; } onFinish?.Invoke(); 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 <WaitForNetwork>d__6 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public IEnumerator routine; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <WaitForNetwork>d__6(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; break; case 1: <>1__state = -1; break; } if (!InstanceFinder.IsServer && !InstanceFinder.IsClient) { <>2__current = null; <>1__state = 1; return true; } MelonCoroutines.Start(routine); 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 <WaitForPlayer>d__5 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public IEnumerator routine; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <WaitForPlayer>d__5(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; break; case 1: <>1__state = -1; break; } if ((Object)(object)Player.Local == (Object)null || (Object)(object)((Component)Player.Local).gameObject == (Object)null) { <>2__current = null; <>1__state = 1; return true; } MelonCoroutines.Start(routine); 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 Instance Logger = new Instance("EmployeeTweaks-Utils"); public static T? FindObjectByName<T>(string objectName) where T : Object { try { T[] array = Resources.FindObjectsOfTypeAll<T>(); foreach (T val in array) { if (!(((Object)val).name != objectName)) { Logger.Debug("Found " + typeof(T).Name + " '" + objectName + "' directly in loaded objects"); return val; } } return default(T); } catch (Exception ex) { Logger.Error("Error finding " + typeof(T).Name + " '" + objectName + "': " + ex.Message); return default(T); } } public static List<T> GetAllComponentsInChildrenRecursive<T>(GameObject obj) where T : Component { List<T> list = new List<T>(); if ((Object)(object)obj == (Object)null) { return list; } T[] components = obj.GetComponents<T>(); if (components.Length != 0) { list.AddRange(components); } for (int i = 0; i < obj.transform.childCount; i++) { Transform child = obj.transform.GetChild(i); list.AddRange(GetAllComponentsInChildrenRecursive<T>(((Component)child).gameObject)); } return list; } public static bool Is<T>(object obj, out T? result) where T : class { if (obj is T val) { result = val; return true; } result = null; return false; } public static bool Is2<T>(object obj, out T? result) where T : class { result = obj as T; return result != null; } [IteratorStateMachine(typeof(<WaitForPlayer>d__5))] public static IEnumerator WaitForPlayer(IEnumerator routine) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <WaitForPlayer>d__5(0) { routine = routine }; } [IteratorStateMachine(typeof(<WaitForNetwork>d__6))] public static IEnumerator WaitForNetwork(IEnumerator routine) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <WaitForNetwork>d__6(0) { routine = routine }; } [IteratorStateMachine(typeof(<WaitForCondition>d__7))] public static IEnumerator WaitForCondition(Func<bool> condition, float timeout = float.NaN, Action? onTimeout = null, Action? onFinish = null) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <WaitForCondition>d__7(0) { condition = condition, timeout = timeout, onTimeout = onTimeout, onFinish = onFinish }; } public static string GetHierarchyPath(this Transform transform) { if ((Object)(object)transform == (Object)null) { return "null"; } string text = ((Object)transform).name; Transform parent = transform.parent; while ((Object)(object)parent != (Object)null) { text = ((Object)parent).name + "/" + text; parent = parent.parent; } return text; } public static T GetOrAddComponent<T>(this GameObject gameObject) where T : Component { T component = gameObject.GetComponent<T>(); if ((Object)(object)component != (Object)null) { return component; } component = gameObject.AddComponent<T>(); Logger.Debug("Added component " + typeof(T).Name + " to GameObject " + ((Object)gameObject).name); return component; } public static Material? DrawDebugVisuals(this GameObject gameObject, Color? color = null) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Expected O, but got Unknown //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) Renderer component = gameObject.GetComponent<Renderer>(); if ((Object)(object)component == (Object)null) { Logger.Error("GameObject " + ((Object)gameObject).name + " has no Renderer component"); return null; } Color valueOrDefault = color.GetValueOrDefault(); if (!color.HasValue) { ((Color)(ref valueOrDefault))..ctor(1f, 0f, 1f, 0.5f); color = valueOrDefault; } Shader val = Shader.Find("Universal Render Pipeline/Lit"); if ((Object)(object)val == (Object)null) { return null; } Material val2 = new Material(val); if (val2.HasProperty("_Surface")) { val2.SetFloat("_Surface", 1f); } Color value = color.Value; if (value.a <= 0f) { value.a = 0.2f; } if (val2.HasProperty("_BaseColor")) { val2.SetColor("_BaseColor", value); } if (val2.HasProperty("_EmissionColor")) { val2.EnableKeyword("_EMISSION"); val2.SetColor("_EmissionColor", new Color(value.r, value.g, value.b) * 1.5f); } val2.SetInt("_ZWrite", 0); val2.renderQueue = 3000; Material material = component.material; component.material = val2; return material; } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { internal IgnoresAccessChecksToAttribute(string assemblyName) { } } }