Some mods target the Mono version of the game, which is available by opting into the Steam beta branch "alternate"
Decompiled source of Smarter Employees v0.1.4
SmarterEmployeesIL2CPP.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.InteropServices; using System.Runtime.Versioning; using System.Threading; using HarmonyLib; using Il2CppFishNet; using Il2CppFishNet.Connection; using Il2CppInterop.Runtime.InteropTypes; using Il2CppScheduleOne.Delivery; using Il2CppScheduleOne.Employees; using Il2CppScheduleOne.EntityFramework; using Il2CppScheduleOne.ItemFramework; using Il2CppScheduleOne.Management; using Il2CppScheduleOne.NPCs; using Il2CppScheduleOne.NPCs.Behaviour; using Il2CppScheduleOne.ObjectScripts; using Il2CppSystem.Collections.Generic; using MelonLoader; using Microsoft.CodeAnalysis; using OmniCorp; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: ComVisible(false)] [assembly: Guid("85757c3f-ac81-41df-9f87-815476c501d1")] [assembly: MelonGame("TVGS", "Schedule I")] [assembly: HarmonyDontPatchAll] [assembly: MelonInfo(typeof(Sched1Mod), "Schedule 1 Smart Employees IL2CPP", "0.1.4", "Olipro", null)] [assembly: MelonOptionalDependencies(new string[] { "Il2Cppmscorlib", "Il2CppInterop.Runtime", "Il2CppFishNet.Runtime" })] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("SmarterEmployeesIL2CPP")] [assembly: AssemblyConfiguration("ReleaseIL2Cpp")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("SmarterEmployeesIL2CPP")] [assembly: AssemblyTitle("SmarterEmployeesIL2CPP")] [assembly: AssemblyVersion("1.0.0.0")] 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; } } } namespace OmniCorp { internal static class Info { public const string NAME = "Schedule 1 Smart Employees"; public const string VERSION = "0.1.4"; public const string AUTHOR = "Olipro"; } [HarmonyPatch(typeof(Behaviour), "Disable_Networked")] public static class MoveItemEndPatch { private static HashSet<ITransitEntity> occupiedEntities = new HashSet<ITransitEntity>(ILEqualityComparer<ITransitEntity>.Instance); private static void TryRemoveEntity(ITransitEntity? entity) { if (entity != null) { occupiedEntities.Remove(entity); } } public static bool TryAddEntityPair(ITransitEntity entity, ITransitEntity entity2) { bool flag = occupiedEntities.Add(entity); if (flag && !occupiedEntities.Add(entity2)) { occupiedEntities.Remove(entity); return false; } return flag; } public static bool Contains(ITransitEntity entity) { return occupiedEntities.Contains(entity); } public static void Prefix(Behaviour __instance) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_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) MoveItemBehaviour obj = ((Il2CppObjectBase)__instance).TryCast<MoveItemBehaviour>(); TransitRoute val = ((obj != null) ? obj.assignedRoute : null); MoveItemBehaviour obj2 = ((Il2CppObjectBase)__instance).TryCast<MoveItemBehaviour>(); EState? val2 = ((obj2 != null) ? new EState?(obj2.currentState) : null); if (val != null && val2 == (EState?)0) { TryRemoveEntity(val.Source); TryRemoveEntity(val.Destination); } } } [HarmonyPatch(typeof(Employee), "SubmitNoWorkReason")] public static class EmployeeNoWorkReasonController { private static ThreadLocal<bool> shouldExecute = new ThreadLocal<bool>(() => true); private static ThreadLocal<bool> wasCalled = new ThreadLocal<bool>(() => false); private static ThreadLocal<string> reason_ = new ThreadLocal<string>(() => ""); private static ThreadLocal<string> fix_ = new ThreadLocal<string>(() => ""); private static ThreadLocal<int> priority_ = new ThreadLocal<int>(() => 0); internal static bool ShouldExecute { get { return shouldExecute.Value; } set { shouldExecute.Value = value; } } internal static bool WasCalled { get { return wasCalled.Value; } set { wasCalled.Value = value; } } public static bool Prefix(string reason, string fix, int priority) { if (shouldExecute.Value) { return true; } wasCalled.Value = true; reason_.Value = reason; fix_.Value = fix; priority_.Value = priority; return false; } internal static void RestoreCall(Employee inst) { shouldExecute.Value = true; if (wasCalled.Value) { inst.SubmitNoWorkReason(reason_.Value, fix_.Value, priority_.Value); } } } [HarmonyPatch(typeof(Employee), "SetIdle")] public static class EmployeeSetIdleController { private static ThreadLocal<bool> shouldExecute = new ThreadLocal<bool>(() => true); private static ThreadLocal<bool> wasCalled = new ThreadLocal<bool>(() => false); private static ThreadLocal<bool> idle_ = new ThreadLocal<bool>(() => true); internal static bool ShouldExecute { get { return shouldExecute.Value; } set { shouldExecute.Value = value; } } internal static bool WasCalled { get { return wasCalled.Value; } set { wasCalled.Value = value; } } public static bool Prefix(bool idle) { if (shouldExecute.Value) { return true; } idle_.Value = idle; wasCalled.Value = true; return false; } internal static void RestoreCall(Employee inst) { shouldExecute.Value = true; if (wasCalled.Value) { inst.SetIdle(idle_.Value); } } } public class IdleStateManager : IDisposable { internal bool shouldRestore = true; private Employee inst; private Action coroutine; private bool disposed; internal IdleStateManager(Employee inst, Action cleanupFunc) { this.inst = inst; coroutine = cleanupFunc; EmployeeNoWorkReasonController.WasCalled = false; EmployeeNoWorkReasonController.ShouldExecute = false; EmployeeSetIdleController.WasCalled = false; EmployeeSetIdleController.ShouldExecute = false; } public void Dispose() { if (!disposed) { disposed = true; coroutine(); if (!shouldRestore) { EmployeeNoWorkReasonController.WasCalled = false; EmployeeSetIdleController.WasCalled = false; } EmployeeNoWorkReasonController.RestoreCall(inst); EmployeeSetIdleController.RestoreCall(inst); } } } [HarmonyPatch(typeof(Packager))] [HarmonyPatch("StartPackaging")] [HarmonyPatch("StartPress")] [HarmonyPatch("StartMoveItem", new Type[] { typeof(BrickPress) })] [HarmonyPatch("StartMoveItem", new Type[] { typeof(PackagingStation) })] public static class PackagerBusyTracker { private static ThreadLocal<bool> isBusy = new ThreadLocal<bool>(() => false); internal static bool Busy { get { return isBusy.Value; } set { isBusy.Value = value; } } public static void Postfix() { isBusy.Value = true; } } [HarmonyPatch(typeof(Packager), "UpdateBehaviour")] public static class PackagerPatch { [Flags] private enum TransitType { None = 0, Source = 1, Destination = 2 } [CompilerGenerated] private sealed class <>c__DisplayClass7_0 { public Packager __instance; internal bool <FindItemsToMoveCoro>b__0() { if (CanWork((Employee)(object)__instance) && !((Behaviour)__instance.PackagingBehaviour).Active) { return !((Behaviour)((Employee)__instance).MoveItemBehaviour).Active; } return false; } } [CompilerGenerated] private sealed class <FindItemsToMoveCoro>d__7 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Packager __instance; public IdleStateManager __state; private <>c__DisplayClass7_0 <>8__1; private IdleStateManager <>7__wrap1; private List<RouteCandidate> <srcs>5__3; private List<RouteCandidate> <dsts>5__4; private IEnumerator[] <>7__wrap4; private int <>7__wrap5; private IEnumerator <coro>5__7; private List<RouteCandidate>.Enumerator <>7__wrap7; private RouteCandidate <dst>5__9; private ITransitEntity <dstEntity>5__10; private List<RouteCandidate>.Enumerator <>7__wrap10; private RouteCandidate <src>5__12; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <FindItemsToMoveCoro>d__7(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if ((uint)(num - -5) <= 2u || (uint)(num - 1) <= 3u) { try { if ((uint)(num - -5) <= 1u || num == 4) { try { if (num == -5 || num == 4) { try { } finally { <>m__Finally3(); } } } finally { <>m__Finally2(); } } } finally { <>m__Finally1(); } } <>8__1 = null; <>7__wrap1 = null; <srcs>5__3 = null; <dsts>5__4 = null; <>7__wrap4 = null; <coro>5__7 = null; <>7__wrap7 = default(List<RouteCandidate>.Enumerator); <dst>5__9 = null; <dstEntity>5__10 = null; <>7__wrap10 = default(List<RouteCandidate>.Enumerator); <src>5__12 = null; <>1__state = -2; } private bool MoveNext() { //IL_03e6: Unknown result type (might be due to invalid IL or missing references) //IL_03ec: Expected O, but got Unknown bool result; try { switch (<>1__state) { default: result = false; goto end_IL_0000; case 0: <>1__state = -1; <>8__1 = new <>c__DisplayClass7_0(); <>8__1.__instance = __instance; <>7__wrap1 = __state; <>1__state = -3; <>2__current = null; <>1__state = 1; result = true; goto end_IL_0000; case 1: { <>1__state = -3; Func<bool> func = () => CanWork((Employee)(object)<>8__1.__instance) && !((Behaviour)<>8__1.__instance.PackagingBehaviour).Active && !((Behaviour)((Employee)<>8__1.__instance).MoveItemBehaviour).Active; if (((Employee)<>8__1.__instance).TimeSinceLastWorked == 0 || ((Employee)<>8__1.__instance).Fired || PackagerBusyTracker.Busy || !func()) { result = false; break; } <srcs>5__3 = new List<RouteCandidate>(); <dsts>5__4 = new List<RouteCandidate>(); <>7__wrap4 = new IEnumerator[2] { PackagerPatch.PopulateSrcsDsts<BuildableItem>(<>8__1.__instance, (IList<BuildableItem>)new IlList<BuildableItem>(<>8__1.__instance.ParentProperty.BuildableItems), <srcs>5__3, <dsts>5__4), PackagerPatch.PopulateSrcsDsts<LoadingDock>(<>8__1.__instance, (IList<LoadingDock>)<>8__1.__instance.ParentProperty.LoadingDocks, <srcs>5__3, <dsts>5__4) }; <>7__wrap5 = 0; goto IL_01be; } case 2: <>1__state = -3; goto IL_019c; case 3: <>1__state = -3; <srcs>5__3.Sort(ReverseCompare<RouteCandidate>.Instance); <>7__wrap7 = <dsts>5__4.GetEnumerator(); <>1__state = -4; goto IL_0563; case 4: { <>1__state = -5; if (!((Il2CppObjectBase?)(object)<src>5__12.Entity).ReferenceEquals((Il2CppObjectBase?)(object)<dstEntity>5__10) && !<src>5__12.Slot.IsLocked && !<dst>5__9.Slot.IsLocked && !MoveItemEndPatch.Contains(<dstEntity>5__10) && !MoveItemEndPatch.Contains(<src>5__12.Entity) && <src>5__12.Slot.ItemInstance != null && (<dst>5__9.Slot.ItemInstance == null || <src>5__12.Slot.ItemInstance.CanStackWith(<dst>5__9.Slot.ItemInstance, false)) && <dst>5__9.Slot.PlayerFilter.DoesItemMatchFilter(<src>5__12.Slot.ItemInstance)) { TransitRoute val = new TransitRoute(<src>5__12.Entity, <dstEntity>5__10); int num = Mathf.Min(<src>5__12.Slot.Quantity, <src>5__12.Slot.ItemInstance.StackLimit - <dst>5__9.Slot.Quantity); if (((Employee)<>8__1.__instance).MoveItemBehaviour.IsTransitRouteValid(val, <src>5__12.Slot.ItemInstance.ID) && MoveItemEndPatch.TryAddEntityPair(<src>5__12.Entity, <dstEntity>5__10)) { ((Employee)<>8__1.__instance).MoveItemBehaviour.Initialize(val, <src>5__12.Slot.ItemInstance, num, false); ((Behaviour)((Employee)<>8__1.__instance).MoveItemBehaviour).Enable_Networked((NetworkConnection)null); __state.shouldRestore = false; Melon<Sched1Mod>.Logger.Msg("Moving " + <src>5__12.Slot.ItemInstance.Name + " from " + <src>5__12.Entity.Name + " to " + <dstEntity>5__10.Name); result = false; goto IL_0541; } } goto IL_0529; } IL_0563: if (<>7__wrap7.MoveNext()) { <dst>5__9 = <>7__wrap7.Current; <dstEntity>5__10 = <dst>5__9.Entity; <>7__wrap10 = <srcs>5__3.GetEnumerator(); <>1__state = -5; goto IL_0529; } <>m__Finally2(); <>7__wrap7 = default(List<RouteCandidate>.Enumerator); <srcs>5__3 = null; <dsts>5__4 = null; <>m__Finally1(); <>7__wrap1 = null; result = false; goto end_IL_0000; IL_0541: <>m__Finally3(); <>m__Finally2(); break; IL_0529: if (!<>7__wrap10.MoveNext()) { <>m__Finally3(); <>7__wrap10 = default(List<RouteCandidate>.Enumerator); <dstEntity>5__10 = null; <dst>5__9 = null; goto IL_0563; } <src>5__12 = <>7__wrap10.Current; if (((Behaviour)((Employee)<>8__1.__instance).MoveItemBehaviour).Active || ((Behaviour)<>8__1.__instance.PackagingBehaviour).Active) { result = false; goto IL_0541; } <>2__current = null; <>1__state = 4; result = true; goto end_IL_0000; IL_019c: if (!<coro>5__7.MoveNext()) { <coro>5__7 = null; <>7__wrap5++; goto IL_01be; } <>2__current = <coro>5__7.Current; <>1__state = 2; result = true; goto end_IL_0000; IL_01be: if (<>7__wrap5 < <>7__wrap4.Length) { <coro>5__7 = <>7__wrap4[<>7__wrap5]; goto IL_019c; } <>7__wrap4 = null; if (<dsts>5__4.Count == 0 || <srcs>5__3.Count == 0) { result = false; break; } <dsts>5__4.Sort(); <>2__current = null; <>1__state = 3; result = true; goto end_IL_0000; } <>m__Finally1(); end_IL_0000:; } catch { //try-fault ((IDisposable)this).Dispose(); throw; } return result; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; if (<>7__wrap1 != null) { ((IDisposable)<>7__wrap1).Dispose(); } } private void <>m__Finally2() { <>1__state = -3; ((IDisposable)<>7__wrap7).Dispose(); } private void <>m__Finally3() { <>1__state = -4; ((IDisposable)<>7__wrap10).Dispose(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <PopulateSrcsDsts>d__5<T> : IEnumerator<object>, IEnumerator, IDisposable where T : notnull, Il2CppObjectBase { private int <>1__state; private object <>2__current; public IList<T> entities; public Packager __instance; public List<RouteCandidate> srcs; public List<RouteCandidate> dsts; private int <i>5__2; private ITransitEntity <transitable>5__3; private List<ItemSlot> <slots>5__4; private TransitType <slotType>5__5; private int <j>5__6; private ItemSlot <slot>5__7; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <PopulateSrcsDsts>d__5(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <transitable>5__3 = null; <slots>5__4 = null; <slot>5__7 = null; <>1__state = -2; } private bool MoveNext() { //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Invalid comparison between Unknown and I4 int num = <>1__state; int num2; if (num != 0) { if (num != 1) { return false; } <>1__state = -1; if (!<slot>5__7.IsLocked) { ITransitEntity val = Util.ILCast<ITransitEntity>((Il2CppObjectBase?)(object)<transitable>5__3); if (<slotType>5__5.HasFlag(TransitType.Source) && <slot>5__7.PlayerFilter.IsDefault() && <slot>5__7.Quantity > 0 && !((IEnumerable<Transform>)<transitable>5__3.AccessPoints).Any((Transform point) => point == null) && ((NPC)__instance).Movement.CanGetTo(val, 1f)) { srcs.Add(new RouteCandidate(<slot>5__7, <transitable>5__3)); } else if (<slotType>5__5.HasFlag(TransitType.Destination) && (int)<slot>5__7.PlayerFilter.Type == 1 && !((IEnumerable<Transform>)<transitable>5__3.AccessPoints).Any((Transform point) => point == null) && !<slot>5__7.IsAtCapacity && ((NPC)__instance).Movement.CanGetTo(val, 1f) && (<slot>5__7.Quantity == 0 || <slot>5__7.PlayerFilter.DoesItemMatchFilter(<slot>5__7.ItemInstance))) { dsts.Add(new RouteCandidate(<slot>5__7, <transitable>5__3)); } <slot>5__7 = null; } num2 = <j>5__6 + 1; <j>5__6 = num2; goto IL_0274; } <>1__state = -1; <i>5__2 = 0; goto IL_02aa; IL_0274: if (<j>5__6 < <slots>5__4.Count) { <slot>5__7 = <slots>5__4[<j>5__6]; <>2__current = null; <>1__state = 1; return true; } <slots>5__4 = null; goto IL_0291; IL_0291: <transitable>5__3 = null; goto IL_0298; IL_0298: num2 = <i>5__2 + 1; <i>5__2 = num2; goto IL_02aa; IL_02aa: if (<i>5__2 < entities.Count) { T val2 = entities[<i>5__2]; <transitable>5__3 = Util.ILCast<ITransitEntity>((Il2CppObjectBase?)(object)val2); if (<transitable>5__3 == null || MoveItemEndPatch.Contains(<transitable>5__3)) { goto IL_0291; } (<slots>5__4, <slotType>5__5) = TryGetEntitySlots(<transitable>5__3); if (<slots>5__4 != null) { <j>5__6 = 0; goto IL_0274; } goto IL_0298; } 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 Dictionary<Packager, object> packagerCoroutines = new Dictionary<Packager, object>(ILEqualityComparer<Packager>.Instance); public static bool Prefix(Packager __instance, out IdleStateManager? __state) { Packager __instance2 = __instance; if (!packagerCoroutines.ContainsKey(__instance2)) { PackagerBusyTracker.Busy = false; __state = new IdleStateManager((Employee)(object)__instance2, delegate { packagerCoroutines.Remove(__instance2); }); return true; } __state = null; return !InstanceFinder.IsServer; } public static void Postfix(Packager __instance, IdleStateManager? __state) { if (__state != null) { packagerCoroutines.Add(__instance, MelonCoroutines.Start(FindItemsToMoveCoro(__instance, __state))); } } private static (List<ItemSlot>?, TransitType) TryGetEntitySlots(ITransitEntity entity) { if (Util.ILCast<LoadingDock>((Il2CppObjectBase?)(object)entity) != null) { return (entity.OutputSlots, TransitType.Source | TransitType.Destination); } if (Util.ILCast<PlaceableStorageEntity>((Il2CppObjectBase?)(object)entity) != null) { return (entity.OutputSlots, TransitType.Source | TransitType.Destination); } if (Util.ILCast<MixingStation>((Il2CppObjectBase?)(object)entity) != null || Util.ILCast<Cauldron>((Il2CppObjectBase?)(object)entity) != null || Util.ILCast<LabOven>((Il2CppObjectBase?)(object)entity) != null || Util.ILCast<DryingRack>((Il2CppObjectBase?)(object)entity) != null || Util.ILCast<PackagingStation>((Il2CppObjectBase?)(object)entity) != null || Util.ILCast<ChemistryStation>((Il2CppObjectBase?)(object)entity) != null) { return (entity.InputSlots, TransitType.Destination); } return (null, TransitType.None); } [IteratorStateMachine(typeof(<PopulateSrcsDsts>d__5<>))] private static IEnumerator PopulateSrcsDsts<T>(Packager __instance, IList<T> entities, List<RouteCandidate> srcs, List<RouteCandidate> dsts) where T : Il2CppObjectBase { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <PopulateSrcsDsts>d__5<T>(0) { __instance = __instance, entities = entities, srcs = srcs, dsts = dsts }; } private static bool CanWork(Employee inst) { return inst.CanWork(); } [IteratorStateMachine(typeof(<FindItemsToMoveCoro>d__7))] private static IEnumerator FindItemsToMoveCoro(Packager __instance, IdleStateManager __state) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <FindItemsToMoveCoro>d__7(0) { __instance = __instance, __state = __state }; } } public class Sched1Mod : MelonMod { public override void OnInitializeMelon() { List<int> list = Application.version.Split(' ')[0].Split('f')[0].Split('.').Select(int.Parse).ToList(); if (list[0] == 0 && list[1] <= 3 && list[2] < 6) { MelonLogger.Error("This mod is only compatible with >= v0.3.6 of the game"); ((MelonBase)this).Unregister((string)null, false); } else if (MelonUtils.IsGameIl2Cpp()) { ((MelonBase)this).HarmonyInstance.PatchAll(); } else { ((MelonBase)this).Unregister((string)null, false); } } } internal static class Extensions { public static bool ReferenceEquals(this Il2CppObjectBase? a, Il2CppObjectBase? b) { IntPtr? intPtr = ((a != null) ? new IntPtr?(a.Pointer) : null); IntPtr? intPtr2 = ((b != null) ? new IntPtr?(b.Pointer) : null); if (intPtr.HasValue != intPtr2.HasValue) { return false; } if (!intPtr.HasValue) { return true; } return intPtr.GetValueOrDefault() == intPtr2.GetValueOrDefault(); } public static int ILHashCode(this Il2CppObjectBase? obj) { if (obj == null) { return 0; } return obj.Pointer.GetHashCode(); } } internal class ILEqualityComparer<T> : IEqualityComparer<T> where T : Il2CppObjectBase { public static readonly ILEqualityComparer<T> Instance = new ILEqualityComparer<T>(); private ILEqualityComparer() { } public bool Equals(T? x, T? y) { return ((Il2CppObjectBase?)(object)x).ReferenceEquals((Il2CppObjectBase?)(object)y); } public int GetHashCode(T? obj) { return ((Il2CppObjectBase?)(object)obj).ILHashCode(); } } internal class ReverseCompare<T> : IComparer<T?> where T : class, IComparable<T?> { public static ReverseCompare<T> Instance = new ReverseCompare<T>(); private ReverseCompare() { } public int Compare(T? x, T? y) { return y?.CompareTo(x) ?? (-1); } } internal class RouteCandidate : IComparable<RouteCandidate?> { public ItemSlot Slot { get; } public ITransitEntity Entity { get; } public RouteCandidate(ItemSlot slot, ITransitEntity entity) { Slot = slot; Entity = entity; } public int CompareTo(RouteCandidate? rhs) { return Slot.Quantity.CompareTo((rhs != null) ? new int?(rhs.Slot.Quantity) : null); } } internal class IlList<T> : IList<T>, ICollection<T>, IEnumerable<T>, IEnumerable { private sealed class Enumerator : IEnumerator<T>, IEnumerator, IDisposable { private readonly Enumerator<T> _enumerator; public T Current => _enumerator.Current; object? IEnumerator.Current => Current; internal Enumerator(Enumerator<T> enumerator) { _enumerator = enumerator; } public void Dispose() { _enumerator.Dispose(); } public bool MoveNext() { return _enumerator.MoveNext(); } public void Reset() { throw new NotSupportedException(); } } private readonly List<T> _list; public T this[int index] { get { return _list[index]; } set { _list[index] = value; } } public int Count => _list.Count; public bool IsReadOnly => false; public IlList(List<T> list) { _list = list; } public void Add(T item) { _list.Add(item); } public void Clear() { _list.Clear(); } public bool Contains(T item) { return _list.Contains(item); } public void CopyTo(T[] array, int arrayIndex) { throw new NotSupportedException(); } public IEnumerator<T> GetEnumerator() { return new Enumerator(_list.GetEnumerator()); } public int IndexOf(T item) { return _list.IndexOf(item); } public void Insert(int index, T item) { _list.Insert(index, item); } public bool Remove(T item) { return _list.Remove(item); } public void RemoveAt(int index) { _list.RemoveAt(index); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } internal class Util { public static T? ILCast<T>(Il2CppObjectBase? instance) where T : Il2CppObjectBase { if (instance == null) { return default(T); } return instance.TryCast<T>(); } } }
SmarterEmployeesMono.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.InteropServices; using System.Runtime.Versioning; using System.Threading; using FishNet; using FishNet.Connection; using HarmonyLib; using MelonLoader; using Microsoft.CodeAnalysis; using OmniCorp; using ScheduleOne.Delivery; using ScheduleOne.Employees; using ScheduleOne.ItemFramework; using ScheduleOne.Management; using ScheduleOne.NPCs; using ScheduleOne.NPCs.Behaviour; using ScheduleOne.ObjectScripts; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: ComVisible(false)] [assembly: Guid("85757c3f-ac81-41df-9f87-815476c501d1")] [assembly: MelonGame("TVGS", "Schedule I")] [assembly: HarmonyDontPatchAll] [assembly: MelonInfo(typeof(Sched1Mod), "Schedule 1 Smart Employees Mono", "0.1.4", "Olipro", null)] [assembly: MelonOptionalDependencies(new string[] { "FishNet.Runtime" })] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("SmarterEmployeesMono")] [assembly: AssemblyConfiguration("ReleaseMono")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("SmarterEmployeesMono")] [assembly: AssemblyTitle("SmarterEmployeesMono")] [assembly: AssemblyVersion("1.0.0.0")] 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; } } } namespace OmniCorp { internal static class Info { public const string NAME = "Schedule 1 Smart Employees"; public const string VERSION = "0.1.4"; public const string AUTHOR = "Olipro"; } [HarmonyPatch(typeof(Behaviour), "Disable_Networked")] public static class MoveItemEndPatch { private static HashSet<ITransitEntity> occupiedEntities = new HashSet<ITransitEntity>(ILEqualityComparer<ITransitEntity>.Instance); private static void TryRemoveEntity(ITransitEntity? entity) { if (entity != null) { occupiedEntities.Remove(entity); } } public static bool TryAddEntityPair(ITransitEntity entity, ITransitEntity entity2) { bool flag = occupiedEntities.Add(entity); if (flag && !occupiedEntities.Add(entity2)) { occupiedEntities.Remove(entity); return false; } return flag; } public static bool Contains(ITransitEntity entity) { return occupiedEntities.Contains(entity); } public static void Prefix(Behaviour __instance) { //IL_005c: 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_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) Traverse obj = Traverse.Create((object)((__instance is MoveItemBehaviour) ? __instance : null)); TransitRoute val = ((obj == null) ? null : obj.Field<TransitRoute>("assignedRoute")?.Value); Traverse obj2 = Traverse.Create((object)((__instance is MoveItemBehaviour) ? __instance : null)); EState? val2 = ((obj2 == null) ? null : obj2.Field<EState>("currentState")?.Value); if (val != null && val2 == (EState?)0) { TryRemoveEntity(val.Source); TryRemoveEntity(val.Destination); } } } [HarmonyPatch(typeof(Employee), "SubmitNoWorkReason")] public static class EmployeeNoWorkReasonController { private static ThreadLocal<bool> shouldExecute = new ThreadLocal<bool>(() => true); private static ThreadLocal<bool> wasCalled = new ThreadLocal<bool>(() => false); private static ThreadLocal<string> reason_ = new ThreadLocal<string>(() => ""); private static ThreadLocal<string> fix_ = new ThreadLocal<string>(() => ""); private static ThreadLocal<int> priority_ = new ThreadLocal<int>(() => 0); internal static bool ShouldExecute { get { return shouldExecute.Value; } set { shouldExecute.Value = value; } } internal static bool WasCalled { get { return wasCalled.Value; } set { wasCalled.Value = value; } } public static bool Prefix(string reason, string fix, int priority) { if (shouldExecute.Value) { return true; } wasCalled.Value = true; reason_.Value = reason; fix_.Value = fix; priority_.Value = priority; return false; } internal static void RestoreCall(Employee inst) { shouldExecute.Value = true; if (wasCalled.Value) { inst.SubmitNoWorkReason(reason_.Value, fix_.Value, priority_.Value); } } } [HarmonyPatch(typeof(Employee), "SetIdle")] public static class EmployeeSetIdleController { private static ThreadLocal<bool> shouldExecute = new ThreadLocal<bool>(() => true); private static ThreadLocal<bool> wasCalled = new ThreadLocal<bool>(() => false); private static ThreadLocal<bool> idle_ = new ThreadLocal<bool>(() => true); internal static bool ShouldExecute { get { return shouldExecute.Value; } set { shouldExecute.Value = value; } } internal static bool WasCalled { get { return wasCalled.Value; } set { wasCalled.Value = value; } } public static bool Prefix(bool idle) { if (shouldExecute.Value) { return true; } idle_.Value = idle; wasCalled.Value = true; return false; } internal static void RestoreCall(Employee inst) { shouldExecute.Value = true; if (wasCalled.Value) { inst.SetIdle(idle_.Value); } } } public class IdleStateManager : IDisposable { internal bool shouldRestore = true; private Employee inst; private Action coroutine; private bool disposed; internal IdleStateManager(Employee inst, Action cleanupFunc) { this.inst = inst; coroutine = cleanupFunc; EmployeeNoWorkReasonController.WasCalled = false; EmployeeNoWorkReasonController.ShouldExecute = false; EmployeeSetIdleController.WasCalled = false; EmployeeSetIdleController.ShouldExecute = false; } public void Dispose() { if (!disposed) { disposed = true; coroutine(); if (!shouldRestore) { EmployeeNoWorkReasonController.WasCalled = false; EmployeeSetIdleController.WasCalled = false; } EmployeeNoWorkReasonController.RestoreCall(inst); EmployeeSetIdleController.RestoreCall(inst); } } } [HarmonyPatch(typeof(Packager))] [HarmonyPatch("StartPackaging")] [HarmonyPatch("StartPress")] [HarmonyPatch("StartMoveItem", new Type[] { typeof(BrickPress) })] [HarmonyPatch("StartMoveItem", new Type[] { typeof(PackagingStation) })] public static class PackagerBusyTracker { private static ThreadLocal<bool> isBusy = new ThreadLocal<bool>(() => false); internal static bool Busy { get { return isBusy.Value; } set { isBusy.Value = value; } } public static void Postfix() { isBusy.Value = true; } } [HarmonyPatch(typeof(Packager), "UpdateBehaviour")] public static class PackagerPatch { [Flags] private enum TransitType { None = 0, Source = 1, Destination = 2 } [CompilerGenerated] private sealed class <>c__DisplayClass7_0 { public Packager __instance; internal bool <FindItemsToMoveCoro>b__0() { if (CanWork((Employee)(object)__instance) && !((Behaviour)__instance.PackagingBehaviour).Active) { return !((Behaviour)((Employee)__instance).MoveItemBehaviour).Active; } return false; } } [CompilerGenerated] private sealed class <FindItemsToMoveCoro>d__7 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Packager __instance; public IdleStateManager __state; private <>c__DisplayClass7_0 <>8__1; private IdleStateManager <>7__wrap1; private List<RouteCandidate> <srcs>5__3; private List<RouteCandidate> <dsts>5__4; private IEnumerator[] <>7__wrap4; private int <>7__wrap5; private IEnumerator <coro>5__7; private List<RouteCandidate>.Enumerator <>7__wrap7; private RouteCandidate <dst>5__9; private ITransitEntity <dstEntity>5__10; private List<RouteCandidate>.Enumerator <>7__wrap10; private RouteCandidate <src>5__12; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <FindItemsToMoveCoro>d__7(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if ((uint)(num - -5) <= 2u || (uint)(num - 1) <= 3u) { try { if ((uint)(num - -5) <= 1u || num == 4) { try { if (num == -5 || num == 4) { try { } finally { <>m__Finally3(); } } } finally { <>m__Finally2(); } } } finally { <>m__Finally1(); } } <>8__1 = null; <>7__wrap1 = null; <srcs>5__3 = null; <dsts>5__4 = null; <>7__wrap4 = null; <coro>5__7 = null; <>7__wrap7 = default(List<RouteCandidate>.Enumerator); <dst>5__9 = null; <dstEntity>5__10 = null; <>7__wrap10 = default(List<RouteCandidate>.Enumerator); <src>5__12 = null; <>1__state = -2; } private bool MoveNext() { //IL_03e1: Unknown result type (might be due to invalid IL or missing references) //IL_03e7: Expected O, but got Unknown bool result; try { switch (<>1__state) { default: result = false; goto end_IL_0000; case 0: <>1__state = -1; <>8__1 = new <>c__DisplayClass7_0(); <>8__1.__instance = __instance; <>7__wrap1 = __state; <>1__state = -3; <>2__current = null; <>1__state = 1; result = true; goto end_IL_0000; case 1: { <>1__state = -3; Func<bool> func = () => CanWork((Employee)(object)<>8__1.__instance) && !((Behaviour)<>8__1.__instance.PackagingBehaviour).Active && !((Behaviour)((Employee)<>8__1.__instance).MoveItemBehaviour).Active; if (((Employee)<>8__1.__instance).TimeSinceLastWorked == 0 || ((Employee)<>8__1.__instance).Fired || PackagerBusyTracker.Busy || !func()) { result = false; break; } <srcs>5__3 = new List<RouteCandidate>(); <dsts>5__4 = new List<RouteCandidate>(); <>7__wrap4 = new IEnumerator[2] { PopulateSrcsDsts(<>8__1.__instance, <>8__1.__instance.ParentProperty.BuildableItems, <srcs>5__3, <dsts>5__4), PopulateSrcsDsts(<>8__1.__instance, <>8__1.__instance.ParentProperty.LoadingDocks, <srcs>5__3, <dsts>5__4) }; <>7__wrap5 = 0; goto IL_01b9; } case 2: <>1__state = -3; goto IL_0197; case 3: <>1__state = -3; <srcs>5__3.Sort(ReverseCompare<RouteCandidate>.Instance); <>7__wrap7 = <dsts>5__4.GetEnumerator(); <>1__state = -4; goto IL_055e; case 4: { <>1__state = -5; if (!<src>5__12.Entity.ReferenceEquals(<dstEntity>5__10) && !<src>5__12.Slot.IsLocked && !<dst>5__9.Slot.IsLocked && !MoveItemEndPatch.Contains(<dstEntity>5__10) && !MoveItemEndPatch.Contains(<src>5__12.Entity) && <src>5__12.Slot.ItemInstance != null && (<dst>5__9.Slot.ItemInstance == null || <src>5__12.Slot.ItemInstance.CanStackWith(<dst>5__9.Slot.ItemInstance, false)) && <dst>5__9.Slot.PlayerFilter.DoesItemMatchFilter(<src>5__12.Slot.ItemInstance)) { TransitRoute val = new TransitRoute(<src>5__12.Entity, <dstEntity>5__10); int num = Mathf.Min(<src>5__12.Slot.Quantity, <src>5__12.Slot.ItemInstance.StackLimit - <dst>5__9.Slot.Quantity); if (((Employee)<>8__1.__instance).MoveItemBehaviour.IsTransitRouteValid(val, <src>5__12.Slot.ItemInstance.ID) && MoveItemEndPatch.TryAddEntityPair(<src>5__12.Entity, <dstEntity>5__10)) { ((Employee)<>8__1.__instance).MoveItemBehaviour.Initialize(val, <src>5__12.Slot.ItemInstance, num, false); ((Behaviour)((Employee)<>8__1.__instance).MoveItemBehaviour).Enable_Networked((NetworkConnection)null); __state.shouldRestore = false; Melon<Sched1Mod>.Logger.Msg("Moving " + <src>5__12.Slot.ItemInstance.Name + " from " + <src>5__12.Entity.Name + " to " + <dstEntity>5__10.Name); result = false; goto IL_053c; } } goto IL_0524; } IL_055e: if (<>7__wrap7.MoveNext()) { <dst>5__9 = <>7__wrap7.Current; <dstEntity>5__10 = <dst>5__9.Entity; <>7__wrap10 = <srcs>5__3.GetEnumerator(); <>1__state = -5; goto IL_0524; } <>m__Finally2(); <>7__wrap7 = default(List<RouteCandidate>.Enumerator); <srcs>5__3 = null; <dsts>5__4 = null; <>m__Finally1(); <>7__wrap1 = null; result = false; goto end_IL_0000; IL_053c: <>m__Finally3(); <>m__Finally2(); break; IL_0524: if (!<>7__wrap10.MoveNext()) { <>m__Finally3(); <>7__wrap10 = default(List<RouteCandidate>.Enumerator); <dstEntity>5__10 = null; <dst>5__9 = null; goto IL_055e; } <src>5__12 = <>7__wrap10.Current; if (((Behaviour)((Employee)<>8__1.__instance).MoveItemBehaviour).Active || ((Behaviour)<>8__1.__instance.PackagingBehaviour).Active) { result = false; goto IL_053c; } <>2__current = null; <>1__state = 4; result = true; goto end_IL_0000; IL_0197: if (!<coro>5__7.MoveNext()) { <coro>5__7 = null; <>7__wrap5++; goto IL_01b9; } <>2__current = <coro>5__7.Current; <>1__state = 2; result = true; goto end_IL_0000; IL_01b9: if (<>7__wrap5 < <>7__wrap4.Length) { <coro>5__7 = <>7__wrap4[<>7__wrap5]; goto IL_0197; } <>7__wrap4 = null; if (<dsts>5__4.Count == 0 || <srcs>5__3.Count == 0) { result = false; break; } <dsts>5__4.Sort(); <>2__current = null; <>1__state = 3; result = true; goto end_IL_0000; } <>m__Finally1(); end_IL_0000:; } catch { //try-fault ((IDisposable)this).Dispose(); throw; } return result; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; if (<>7__wrap1 != null) { ((IDisposable)<>7__wrap1).Dispose(); } } private void <>m__Finally2() { <>1__state = -3; ((IDisposable)<>7__wrap7).Dispose(); } private void <>m__Finally3() { <>1__state = -4; ((IDisposable)<>7__wrap10).Dispose(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <PopulateSrcsDsts>d__5<T> : IEnumerator<object>, IEnumerator, IDisposable where T : notnull { private int <>1__state; private object <>2__current; public IList<T> entities; public Packager __instance; public List<RouteCandidate> srcs; public List<RouteCandidate> dsts; private int <i>5__2; private ITransitEntity <transitable>5__3; private List<ItemSlot> <slots>5__4; private TransitType <slotType>5__5; private int <j>5__6; private ItemSlot <slot>5__7; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <PopulateSrcsDsts>d__5(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <transitable>5__3 = null; <slots>5__4 = null; <slot>5__7 = null; <>1__state = -2; } private bool MoveNext() { //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Invalid comparison between Unknown and I4 int num = <>1__state; int num2; if (num != 0) { if (num != 1) { return false; } <>1__state = -1; if (!<slot>5__7.IsLocked) { ITransitEntity val = Util.ILCast<ITransitEntity>(<transitable>5__3); if (<slotType>5__5.HasFlag(TransitType.Source) && <slot>5__7.PlayerFilter.IsDefault() && <slot>5__7.Quantity > 0 && !<transitable>5__3.AccessPoints.Any((Transform point) => point == null) && ((NPC)__instance).Movement.CanGetTo(val, 1f)) { srcs.Add(new RouteCandidate(<slot>5__7, <transitable>5__3)); } else if (<slotType>5__5.HasFlag(TransitType.Destination) && (int)<slot>5__7.PlayerFilter.Type == 1 && !<transitable>5__3.AccessPoints.Any((Transform point) => point == null) && !<slot>5__7.IsAtCapacity && ((NPC)__instance).Movement.CanGetTo(val, 1f) && (<slot>5__7.Quantity == 0 || <slot>5__7.PlayerFilter.DoesItemMatchFilter(<slot>5__7.ItemInstance))) { dsts.Add(new RouteCandidate(<slot>5__7, <transitable>5__3)); } <slot>5__7 = null; } num2 = <j>5__6 + 1; <j>5__6 = num2; goto IL_0274; } <>1__state = -1; <i>5__2 = 0; goto IL_02aa; IL_0274: if (<j>5__6 < <slots>5__4.Count) { <slot>5__7 = <slots>5__4[<j>5__6]; <>2__current = null; <>1__state = 1; return true; } <slots>5__4 = null; goto IL_0291; IL_0291: <transitable>5__3 = null; goto IL_0298; IL_0298: num2 = <i>5__2 + 1; <i>5__2 = num2; goto IL_02aa; IL_02aa: if (<i>5__2 < entities.Count) { T val2 = entities[<i>5__2]; <transitable>5__3 = Util.ILCast<ITransitEntity>(val2); if (<transitable>5__3 == null || MoveItemEndPatch.Contains(<transitable>5__3)) { goto IL_0291; } (<slots>5__4, <slotType>5__5) = TryGetEntitySlots(<transitable>5__3); if (<slots>5__4 != null) { <j>5__6 = 0; goto IL_0274; } goto IL_0298; } 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 Dictionary<Packager, object> packagerCoroutines = new Dictionary<Packager, object>(ILEqualityComparer<Packager>.Instance); private static readonly Func<Employee, bool> CanWork = (Func<Employee, bool>)typeof(Employee).GetMethod("CanWork", BindingFlags.Instance | BindingFlags.NonPublic).CreateDelegate(typeof(Func<Employee, bool>)); public static bool Prefix(Packager __instance, out IdleStateManager? __state) { Packager __instance2 = __instance; if (!packagerCoroutines.ContainsKey(__instance2)) { PackagerBusyTracker.Busy = false; __state = new IdleStateManager((Employee)(object)__instance2, delegate { packagerCoroutines.Remove(__instance2); }); return true; } __state = null; return !InstanceFinder.IsServer; } public static void Postfix(Packager __instance, IdleStateManager? __state) { if (__state != null) { packagerCoroutines.Add(__instance, MelonCoroutines.Start(FindItemsToMoveCoro(__instance, __state))); } } private static (List<ItemSlot>?, TransitType) TryGetEntitySlots(ITransitEntity entity) { if (Util.ILCast<LoadingDock>(entity) != null) { return (entity.OutputSlots, TransitType.Source | TransitType.Destination); } if (Util.ILCast<PlaceableStorageEntity>(entity) != null) { return (entity.OutputSlots, TransitType.Source | TransitType.Destination); } if (Util.ILCast<MixingStation>(entity) != null || Util.ILCast<Cauldron>(entity) != null || Util.ILCast<LabOven>(entity) != null || Util.ILCast<DryingRack>(entity) != null || Util.ILCast<PackagingStation>(entity) != null || Util.ILCast<ChemistryStation>(entity) != null) { return (entity.InputSlots, TransitType.Destination); } return (null, TransitType.None); } [IteratorStateMachine(typeof(<PopulateSrcsDsts>d__5<>))] private static IEnumerator PopulateSrcsDsts<T>(Packager __instance, IList<T> entities, List<RouteCandidate> srcs, List<RouteCandidate> dsts) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <PopulateSrcsDsts>d__5<T>(0) { __instance = __instance, entities = entities, srcs = srcs, dsts = dsts }; } [IteratorStateMachine(typeof(<FindItemsToMoveCoro>d__7))] private static IEnumerator FindItemsToMoveCoro(Packager __instance, IdleStateManager __state) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <FindItemsToMoveCoro>d__7(0) { __instance = __instance, __state = __state }; } } public class Sched1Mod : MelonMod { public override void OnInitializeMelon() { List<int> list = Application.version.Split(' ')[0].Split('f')[0].Split('.').Select(int.Parse).ToList(); if (list[0] == 0 && list[1] <= 3 && list[2] < 6) { MelonLogger.Error("This mod is only compatible with >= v0.3.6 of the game"); ((MelonBase)this).Unregister((string)null, false); } else if (!MelonUtils.IsGameIl2Cpp()) { ((MelonBase)this).HarmonyInstance.PatchAll(); } else { ((MelonBase)this).Unregister((string)null, false); } } } internal static class Extensions { public new static bool ReferenceEquals(this object? a, object? b) { return a == b; } public static int ILHashCode(this object? obj) { return obj?.GetHashCode() ?? 0; } } internal class ILEqualityComparer<T> : IEqualityComparer<T> { public static readonly ILEqualityComparer<T> Instance = new ILEqualityComparer<T>(); private ILEqualityComparer() { } public bool Equals(T? x, T? y) { return x.ReferenceEquals(y); } public int GetHashCode(T? obj) { return obj.ILHashCode(); } } internal class ReverseCompare<T> : IComparer<T?> where T : class, IComparable<T?> { public static ReverseCompare<T> Instance = new ReverseCompare<T>(); private ReverseCompare() { } public int Compare(T? x, T? y) { return y?.CompareTo(x) ?? (-1); } } internal class RouteCandidate : IComparable<RouteCandidate?> { public ItemSlot Slot { get; } public ITransitEntity Entity { get; } public RouteCandidate(ItemSlot slot, ITransitEntity entity) { Slot = slot; Entity = entity; } public int CompareTo(RouteCandidate? rhs) { return Slot.Quantity.CompareTo((rhs != null) ? new int?(rhs.Slot.Quantity) : null); } } internal class Util { public static T? ILCast<T>(object? instance) where T : class { return instance as T; } } }