Some mods target the Mono version of the game, which is available by opting into the Steam beta branch "alternate"
Decompiled source of LateShiftMono v1.1.0
Mods/LateShiftMono.dll
Decompiled a day agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Resources; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using FishNet; using FishNet.Object; using HarmonyLib; using LateShift; using MelonLoader; using MelonLoader.Preferences; using Microsoft.CodeAnalysis; using ScheduleOne; using ScheduleOne.DevUtilities; using ScheduleOne.Dialogue; using ScheduleOne.Employees; using ScheduleOne.GameTime; using ScheduleOne.Growing; using ScheduleOne.ItemFramework; using ScheduleOne.Management; using ScheduleOne.Money; using ScheduleOne.NPCs; using ScheduleOne.NPCs.Behaviour; using ScheduleOne.ObjectScripts; using ScheduleOne.StationFramework; using UnityEngine; using UnityEngine.Events; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: MelonInfo(typeof(LateShiftMod), "LateShift", "1.1.0", "lasersquid", null)] [assembly: MelonGame("TVGS", "Schedule I")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("LateShiftMono")] [assembly: AssemblyConfiguration("Mono")] [assembly: AssemblyFileVersion("1.1.0.0")] [assembly: AssemblyInformationalVersion("1.1.0+3f3798563723f4efe41e885c6586bd08d8e4915b")] [assembly: AssemblyProduct("LateShiftMono")] [assembly: AssemblyTitle("LateShiftMono")] [assembly: NeutralResourcesLanguage("en-US")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.1.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace LateShift { public class LateShiftMod : MelonMod { public MelonPreferences_Category melonPrefs; public Harmony harmony = new Harmony("com.lasersquid.lateshift"); public override void OnInitializeMelon() { CreateMelonPreferences(); Utils.Initialize(this); ((MelonBase)this).LoggerInstance.Msg("Initialized."); } private void CreateMelonPreferences() { melonPrefs = MelonPreferences.CreateCategory("LateShift"); melonPrefs.SetFilePath("UserData/LateShift.cfg", true, false); melonPrefs.CreateEntry<bool>("employeesAlwaysWork", true, "Employees always work", "Employees keep working at 4am", false, false, (ValueValidator)null, (string)null); melonPrefs.CreateEntry<bool>("workWithoutBeds", true, "Employees work without beds", "Employees work without beds or lockers", false, false, (ValueValidator)null, (string)null); melonPrefs.CreateEntry<bool>("payEmployeesFromBank", false, "Autopay employees from bank account", "Autopay employees from bank account if true; otherwise pay with cash", false, false, (ValueValidator)null, (string)null); melonPrefs.SaveToFile(false); } } public static class Utils { public class UnityObjectComparer : IEqualityComparer<Object> { public bool Equals(Object a, Object b) { return a.GetInstanceID() == b.GetInstanceID(); } public int GetHashCode(Object item) { return item.GetInstanceID(); } } private static LateShiftMod Mod; private static Assembly S1Assembly; public static void Initialize(LateShiftMod mod) { Mod = mod; } public static Treturn GetField<Ttarget, Treturn>(string fieldName, object target) where Treturn : class { return (Treturn)GetField<Ttarget>(fieldName, target); } public static object GetField<Ttarget>(string fieldName, object target) { return AccessTools.Field(typeof(Ttarget), fieldName).GetValue(target); } public static Treturn GetProperty<Ttarget, Treturn>(string fieldName, object target) { return (Treturn)GetProperty<Ttarget>(fieldName, target); } public static object GetProperty<Ttarget>(string fieldName, object target) { return AccessTools.Property(typeof(Ttarget), fieldName).GetValue(target); } public static void SetProperty<Ttarget>(string fieldName, object target, object value) { AccessTools.Property(typeof(Ttarget), fieldName).SetValue(target, value); } public static Treturn CallMethod<Ttarget, Treturn>(string methodName, object target) { return (Treturn)CallMethod<Ttarget>(methodName, target, Array.Empty<object>()); } public static Treturn CallMethod<Ttarget, Treturn>(string methodName, object target, object[] args) { return (Treturn)CallMethod<Ttarget>(methodName, target, args); } public static Treturn CallMethod<Ttarget, Treturn>(string methodName, Type[] argTypes, object target, object[] args) { return (Treturn)CallMethod<Ttarget>(methodName, argTypes, target, args); } public static object CallMethod<Ttarget>(string methodName, object target) { return AccessTools.Method(typeof(Ttarget), methodName, (Type[])null, (Type[])null).Invoke(target, Array.Empty<object>()); } public static object CallMethod<Ttarget>(string methodName, object target, object[] args) { return AccessTools.Method(typeof(Ttarget), methodName, (Type[])null, (Type[])null).Invoke(target, args); } public static object CallMethod<Ttarget>(string methodName, Type[] argTypes, object target, object[] args) { return AccessTools.Method(typeof(Ttarget), methodName, argTypes, (Type[])null).Invoke(target, args); } public static T CastTo<T>(object o) { if (!(o is T result)) { return default(T); } return result; } public static bool Is<T>(object o) { return o is T; } public static T ToInterface<T>(object o) { return (T)o; } public static Type GetType(object o) { return o?.GetType(); } public static UnityAction ToUnityAction(Action action) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Expected O, but got Unknown return new UnityAction(action.Invoke); } public static UnityAction<T> ToUnityAction<T>(Action<T> action) { return action.Invoke; } public static Predicate<T> ToPredicate<T>(Func<T, bool> func) { return func.Invoke; } public static void Log(string message) { ((MelonBase)Mod).LoggerInstance.Msg(message); } public static void Warn(string message) { ((MelonBase)Mod).LoggerInstance.Warning(message); } public static void PrintException(Exception e) { Warn("Exception: " + e.GetType().Name + " - " + e.Message); Warn("Source: " + e.Source); Warn(e.StackTrace ?? ""); if (e.InnerException != null) { Warn("Inner exception: " + e.InnerException.GetType().Name + " - " + e.InnerException.Message); Warn("Source: " + e.InnerException.Source); Warn(e.InnerException.StackTrace ?? ""); if (e.InnerException.InnerException != null) { Warn("Inner inner exception: " + e.InnerException.InnerException.GetType().Name + " - " + e.InnerException.InnerException.Message); Warn("Source: " + e.InnerException.InnerException.Source); Warn(e.InnerException.InnerException.StackTrace ?? ""); } } } public static MelonPreferences_Category GetMelonPrefs() { return Mod.melonPrefs; } public static T GetMelonPrefEntry<T>(string entryName) { return GetMelonPrefs().GetEntry<T>(entryName).Value; } public static void Debug(string message) { if (GetMelonPrefEntry<bool>("debugLogs")) { ((MelonBase)Mod).LoggerInstance.Msg("DEBUG: " + message); } } public static void VerboseLog(string message) { if (GetMelonPrefEntry<bool>("verboseLogs")) { ((MelonBase)Mod).LoggerInstance.Msg(message); } } } [HarmonyPatch] public class NoBedsPatches { [HarmonyPatch(typeof(Employee), "IsPayAvailable")] [HarmonyPrefix] public static bool IsPayAvailablePrefix(Employee __instance, ref bool __result) { MoneyManager instance = NetworkSingleton<MoneyManager>.Instance; EmployeeHome home = __instance.GetHome(); if (Utils.GetMelonPrefEntry<bool>("payEmployeesFromBank")) { __result = instance.onlineBalance >= __instance.DailyWage; return false; } if (Utils.GetMelonPrefEntry<bool>("workWithoutBeds")) { if ((Object)(object)home == (Object)null) { __result = instance.cashBalance >= __instance.DailyWage; } else { __result = home.GetCashSum() >= __instance.DailyWage; } } else if ((Object)(object)home == (Object)null) { __result = false; } else { __result = home.GetCashSum() >= __instance.DailyWage; } return false; } [HarmonyPatch(typeof(Employee), "RemoveDailyWage")] [HarmonyPrefix] public static bool RemoveDailyWagePrefix(Employee __instance) { if (!InstanceFinder.IsServer) { return false; } MoneyManager instance = NetworkSingleton<MoneyManager>.Instance; EmployeeHome home = __instance.GetHome(); if (Utils.GetMelonPrefEntry<bool>("payEmployeesFromBank")) { if (instance.onlineBalance >= __instance.DailyWage) { instance.CreateOnlineTransaction("Employee Pay", 0f - __instance.DailyWage, 1f, ((NPC)__instance).fullName + ", employeetype, location"); } } else if (Utils.GetMelonPrefEntry<bool>("workWithoutBeds")) { if ((Object)(object)home == (Object)null) { if (instance.cashBalance >= __instance.DailyWage) { instance.ChangeCashBalance(0f - __instance.DailyWage, true, false); } } else if (home.GetCashSum() >= __instance.DailyWage) { instance.ChangeCashBalance(0f - __instance.DailyWage, true, false); home.RemoveCash(__instance.DailyWage); } } else { if ((Object)(object)home == (Object)null) { return false; } if (home.GetCashSum() >= __instance.DailyWage) { instance.ChangeCashBalance(0f - __instance.DailyWage, true, false); home.RemoveCash(__instance.DailyWage); } } return false; } [HarmonyPatch(typeof(Employee), "GetWorkIssue")] [HarmonyPrefix] public static bool GetWorkIssuePrefix(Employee __instance, ref bool __result, ref DialogueContainer notWorkingReason) { if ((Object)(object)__instance.GetHome() == (Object)null && !Utils.GetMelonPrefEntry<bool>("workWithoutBeds")) { notWorkingReason = __instance.BedNotAssignedDialogue; __result = true; return false; } if (!__instance.PaidForToday) { notWorkingReason = __instance.NotPaidDialogue; __result = true; return false; } List<NoWorkReason> field = Utils.GetField<Employee, List<NoWorkReason>>("WorkIssues", __instance); if (__instance.TicksSinceLastWork >= 5 && field.Count > 0) { notWorkingReason = Object.Instantiate<DialogueContainer>(__instance.WorkIssueDialogueTemplate); notWorkingReason.GetDialogueNodeByLabel("ENTRY").DialogueText = field[0].Reason; if (!string.IsNullOrEmpty(field[0].Fix)) { notWorkingReason.GetDialogueNodeByLabel("FIX").DialogueText = field[0].Fix; } else { notWorkingReason.GetDialogueNodeByLabel("ENTRY").choices = (DialogueChoiceData[])(object)new DialogueChoiceData[0]; } __result = true; return false; } notWorkingReason = null; __result = false; return false; } [HarmonyPatch(typeof(Employee), "CanWork")] [HarmonyPostfix] public static void CanWorkPostfix(Employee __instance, ref bool __result) { bool flag = (Object)(object)__instance.GetHome() != (Object)null; bool melonPrefEntry = Utils.GetMelonPrefEntry<bool>("workWithoutBeds"); bool melonPrefEntry2 = Utils.GetMelonPrefEntry<bool>("employeesAlwaysWork"); bool isEndOfDay = NetworkSingleton<TimeManager>.Instance.IsEndOfDay; bool paidForToday = __instance.PaidForToday; if (!__result && !flag && paidForToday && !isEndOfDay && melonPrefEntry) { __result = true; } if (!__result && flag && paidForToday && isEndOfDay && melonPrefEntry2) { __result = true; } if (!__result && !flag && paidForToday && isEndOfDay && melonPrefEntry && melonPrefEntry2) { __result = true; } } [HarmonyPatch(typeof(Employee), "UpdateBehaviour")] [HarmonyPrefix] public static bool UpdateBehaviourPrefix(Employee __instance) { bool melonPrefEntry = Utils.GetMelonPrefEntry<bool>("workWithoutBeds"); bool melonPrefEntry2 = Utils.GetMelonPrefEntry<bool>("employeesAlwaysWork"); bool isEndOfDay = NetworkSingleton<TimeManager>.Instance.IsEndOfDay; bool flag = (Object)(object)__instance.GetHome() != (Object)null; if (!flag && melonPrefEntry) { if (__instance.Fired) { return true; } bool flag2 = false; bool flag3 = false; if (isEndOfDay && !melonPrefEntry2) { flag2 = true; __instance.SubmitNoWorkReason("Sorry boss, my shift ends at 4AM.", string.Empty, 0); } else if (!__instance.PaidForToday) { if (__instance.IsPayAvailable()) { flag3 = true; } else { flag2 = true; __instance.SubmitNoWorkReason("I haven't been paid yet", "You can place cash in my locker.", 0); } } if (flag2) { Utils.CallMethod<Employee>("SetWaitOutside", __instance, new object[1] { true }); return false; } if (InstanceFinder.IsServer && flag3 && __instance.IsPayAvailable()) { __instance.RemoveDailyWage(); __instance.SetIsPaid(); } return false; } return true; } [HarmonyPatch(typeof(Botanist), "UpdateBehaviour")] [HarmonyPostfix] public static void BotanistUpdateBehaviourPostfix(Botanist __instance) { //IL_081b: Unknown result type (might be due to invalid IL or missing references) //IL_0822: Expected O, but got Unknown //IL_0826: Unknown result type (might be due to invalid IL or missing references) //IL_082d: Expected O, but got Unknown //IL_0850: Unknown result type (might be due to invalid IL or missing references) //IL_0857: Expected O, but got Unknown bool melonPrefEntry = Utils.GetMelonPrefEntry<bool>("workWithoutBeds"); bool melonPrefEntry2 = Utils.GetMelonPrefEntry<bool>("employeesAlwaysWork"); bool isEndOfDay = NetworkSingleton<TimeManager>.Instance.IsEndOfDay; bool flag = (Object)(object)((Employee)__instance).GetHome() != (Object)null; if (!(bool)Utils.CallMethod<Botanist>("CanWork", __instance) || (!(isEndOfDay && melonPrefEntry2) && !(!flag && melonPrefEntry)) || Utils.GetField<Botanist, List<Behaviour>>("_workBehaviours", __instance).Exists(Utils.ToPredicate((Behaviour b) => b.Active)) || ((Employee)__instance).Fired || !((NetworkBehaviour)__instance).IsServer || (isEndOfDay && !melonPrefEntry2) || (!flag && !melonPrefEntry)) { return; } BotanistConfiguration property = Utils.GetProperty<Botanist, BotanistConfiguration>("configuration", __instance); if (property.Assigns.SelectedObjects.Count == 0) { ((Employee)__instance).SubmitNoWorkReason("I haven't been assigned anything", "You can use your management clipboards to assign me pots, growing racks, etc.", 0); ((Employee)__instance).SetIdle(true); } else { if (!InstanceFinder.IsServer) { return; } Pot val = Utils.CallMethod<Botanist, Pot>("GetPotForWatering", __instance, new object[1] { 0.2f }); if ((Object)(object)val != (Object)null) { ((GrowContainerBehaviour)Utils.GetField<Botanist, WaterPotBehaviour>("_waterPotBehaviour", __instance)).AssignAndEnable((GrowContainer)(object)val); return; } MushroomBed val2 = Utils.CallMethod<Botanist, MushroomBed>("GetMushroomBedForMisting", __instance, new object[1] { 0.2f }); if ((Object)(object)val2 != (Object)null) { ((GrowContainerBehaviour)Utils.GetField<Botanist, MistMushroomBedBehaviour>("_mistMushroomBedBehaviour", __instance)).AssignAndEnable((GrowContainer)(object)val2); return; } foreach (GrowContainer item in Utils.CallMethod<Botanist, List<GrowContainer>>("GetGrowContainersForAdditives", __instance)) { ApplyAdditiveToGrowContainerBehaviour field = Utils.GetField<Botanist, ApplyAdditiveToGrowContainerBehaviour>("_applyAdditiveToGrowContainerBehaviour", __instance); if ((Object)(object)item != (Object)null && ((GrowContainerBehaviour)field).DoesBotanistHaveAccessToRequiredSupplies(item)) { ((GrowContainerBehaviour)field).AssignAndEnable(item); return; } } foreach (GrowContainer item2 in Utils.CallMethod<Botanist, List<GrowContainer>>("GetGrowContainersForSoilPour", __instance)) { AddSoilToGrowContainerBehaviour field2 = Utils.GetField<Botanist, AddSoilToGrowContainerBehaviour>("_addSoilToGrowContainerBehaviour", __instance); if (((GrowContainerBehaviour)field2).DoesBotanistHaveAccessToRequiredSupplies(item2)) { ((GrowContainerBehaviour)field2).AssignAndEnable(item2); return; } string text = "Make sure there's soil in my supplies stash."; if ((Object)(object)property.Supplies.SelectedObject == (Object)null) { text = "Use your management clipboard to assign a supplies stash to me, then make sure there's soil in it."; } ((Employee)__instance).SubmitNoWorkReason("There are empty pots, but I don't have any soil to pour.", text, 0); } bool flag2 = false; foreach (Pot item3 in Utils.CallMethod<Botanist, List<Pot>>("GetPotsReadyForSeed", __instance)) { SowSeedInPotBehaviour field3 = Utils.GetField<Botanist, SowSeedInPotBehaviour>("_sowSeedInPotBehaviour", __instance); if (!((GrowContainerBehaviour)field3).DoesBotanistHaveAccessToRequiredSupplies((GrowContainer)(object)item3)) { if (!flag2) { flag2 = true; string text2 = "Make sure I have the right seeds in my supplies stash."; if ((Object)(object)property.Supplies.SelectedObject == (Object)null) { text2 = "Use your management clipboards to assign a supplies stash to me, and make sure it contains the right seeds."; } ((Employee)__instance).SubmitNoWorkReason("There is a pot ready for sowing, but I don't have any seeds for it.", text2, 1); } } else if ((bool)Utils.CallMethod<Botanist>("IsEntityAccessible", __instance, new object[1] { Utils.ToInterface<ITransitEntity>(item3) })) { ((GrowContainerBehaviour)field3).AssignAndEnable((GrowContainer)(object)item3); return; } } flag2 = false; foreach (MushroomBed item4 in Utils.CallMethod<Botanist, List<MushroomBed>>("GetBedsReadyForSpawn", __instance)) { ApplySpawnToMushroomBedBehaviour field4 = Utils.GetField<Botanist, ApplySpawnToMushroomBedBehaviour>("_applySpawnToMushroomBedBehaviour", __instance); if (!((GrowContainerBehaviour)field4).DoesBotanistHaveAccessToRequiredSupplies((GrowContainer)(object)item4)) { if (!flag2) { flag2 = true; string text3 = "Make sure I have shroom spawn my supplies stash."; if ((Object)(object)property.Supplies.SelectedObject == (Object)null) { text3 = "Use your management clipboards to assign a supplies stash to me, and make sure it contains shroom spawn."; } ((Employee)__instance).SubmitNoWorkReason("I don't have any shroom spawn to mix into my assigned mushroom beds.", text3, 1); } } else if ((bool)Utils.CallMethod<Botanist>("IsEntityAccessible", __instance, new object[1] { Utils.ToInterface<ITransitEntity>(item4) })) { ((GrowContainerBehaviour)field4).AssignAndEnable((GrowContainer)(object)item4); return; } } List<Pot> list = Utils.CallMethod<Botanist, List<Pot>>("GetPotsForHarvest", __instance); if (list != null && list.Count > 0) { ((GrowContainerBehaviour)Utils.GetField<Botanist, HarvestPotBehaviour>("_harvestPotBehaviour", __instance)).AssignAndEnable((GrowContainer)(object)list[0]); return; } List<MushroomBed> list2 = Utils.CallMethod<Botanist, List<MushroomBed>>("GetMushroomBedsForHarvest", __instance); if (list2 != null && list2.Count > 0) { ((GrowContainerBehaviour)Utils.GetField<Botanist, HarvestMushroomBedBehaviour>("_harvestMushroomBedBehaviour", __instance)).AssignAndEnable((GrowContainer)(object)list2[0]); return; } foreach (DryingRack item5 in Utils.CallMethod<Botanist, List<DryingRack>>("GetRacksToStop", __instance)) { if ((bool)Utils.CallMethod<Botanist>("IsEntityAccessible", __instance, new object[1] { Utils.ToInterface<ITransitEntity>(item5) })) { Utils.CallMethod<Botanist>("StopDryingRack", __instance, new object[1] { item5 }); return; } } foreach (DryingRack item6 in Utils.CallMethod<Botanist, List<DryingRack>>("GetRacksReadyToMove", __instance)) { if ((bool)Utils.CallMethod<Botanist>("IsEntityAccessible", __instance, new object[1] { Utils.ToInterface<ITransitEntity>(item6) })) { ((Employee)__instance).MoveItemBehaviour.Initialize(Utils.CastTo<DryingRackConfiguration>(item6.Configuration).DestinationRoute, item6.OutputSlot.ItemInstance, -1, false); ((Behaviour)((Employee)__instance).MoveItemBehaviour).Enable_Networked(); return; } } foreach (MushroomSpawnStation item7 in Utils.CallMethod<Botanist, List<MushroomSpawnStation>>("GetSpawnStationsReadyToUse", __instance)) { if ((bool)Utils.CallMethod<Botanist>("IsEntityAccessible", __instance, new object[1] { Utils.ToInterface<ITransitEntity>(item7) })) { UseSpawnStationBehaviour field5 = Utils.GetField<Botanist, UseSpawnStationBehaviour>("_useSpawnStationBehaviour", __instance); field5.AssignStation(item7); ((Behaviour)field5).Enable_Networked(); return; } } foreach (MushroomSpawnStation item8 in Utils.CallMethod<Botanist, List<MushroomSpawnStation>>("GetSpawnStationsReadyToMove", __instance)) { if ((bool)Utils.CallMethod<Botanist>("IsEntityAccessible", __instance, new object[1] { Utils.ToInterface<ITransitEntity>(item8) })) { ? val3 = ((Employee)__instance).MoveItemBehaviour; EntityConfiguration configuration = item8.Configuration; ((MoveItemBehaviour)val3).Initialize(((SpawnStationConfiguration)((configuration is SpawnStationConfiguration) ? configuration : null)).DestinationRoute, item8.OutputSlot.ItemInstance, -1, false); ((Behaviour)((Employee)__instance).MoveItemBehaviour).Enable_Networked(); return; } } Pot val4 = Utils.CallMethod<Botanist, Pot>("GetPotForWatering", __instance, new object[1] { 0.3f }); if ((Object)(object)val4 != (Object)null) { ((GrowContainerBehaviour)Utils.GetField<Botanist, WaterPotBehaviour>("_waterPotBehaviour", __instance)).AssignAndEnable((GrowContainer)(object)val4); return; } MushroomBed val5 = Utils.CallMethod<Botanist, MushroomBed>("GetMushroomBedForMisting", __instance, new object[1] { 0.3f }); if ((Object)(object)val5 != (Object)null) { ((GrowContainerBehaviour)Utils.GetField<Botanist, MistMushroomBedBehaviour>("_mistMushroomBedBehaviour", __instance)).AssignAndEnable((GrowContainer)(object)val5); return; } object[] array = new object[3] { null, null, 0 }; if ((bool)Utils.CallMethod<Botanist>("CanMoveDryableToRack", __instance, array)) { QualityItemInstance val6 = (QualityItemInstance)array[0]; DryingRack o = (DryingRack)array[1]; int num = (int)array[2]; TransitRoute val7 = new TransitRoute(Utils.ToInterface<ITransitEntity>(property.Supplies.SelectedObject), Utils.ToInterface<ITransitEntity>(o)); if (((Employee)__instance).MoveItemBehaviour.IsTransitRouteValid(val7, ((ItemInstance)val6).ID)) { ((Employee)__instance).MoveItemBehaviour.Initialize(val7, (ItemInstance)(object)val6, num, false); ((Behaviour)((Employee)__instance).MoveItemBehaviour).Enable_Networked(); Console.Log((object)("Moving " + num + " " + ((ItemInstance)val6).ID + " to drying rack"), (Object)null); return; } } foreach (DryingRack item9 in Utils.CallMethod<Botanist, List<DryingRack>>("GetRacksToStart", __instance)) { if ((bool)Utils.CallMethod<Botanist>("IsEntityAccessible", __instance, new object[1] { Utils.ToInterface<ITransitEntity>(item9) })) { Utils.CallMethod<Botanist>("StartDryingRack", __instance, new object[1] { item9 }); return; } } ((Employee)__instance).SubmitNoWorkReason("There's nothing for me to do right now.", string.Empty, 0); ((Employee)__instance).SetIdle(true); } } [HarmonyPatch(typeof(Packager), "UpdateBehaviour")] [HarmonyPostfix] public static void PackagerUpdateBehaviourPostfix(Packager __instance) { bool melonPrefEntry = Utils.GetMelonPrefEntry<bool>("workWithoutBeds"); bool melonPrefEntry2 = Utils.GetMelonPrefEntry<bool>("employeesAlwaysWork"); bool isEndOfDay = NetworkSingleton<TimeManager>.Instance.IsEndOfDay; bool flag = (Object)(object)((Employee)__instance).GetHome() != (Object)null; if ((bool)Utils.CallMethod<Packager>("CanWork", __instance) && ((isEndOfDay && melonPrefEntry2) || (!flag && melonPrefEntry))) { if (((Behaviour)__instance.PackagingBehaviour).Active || ((Behaviour)((Employee)__instance).MoveItemBehaviour).Active || ((Employee)__instance).Fired || (isEndOfDay && !melonPrefEntry2) || (!flag && !melonPrefEntry)) { return; } PackagerConfiguration property = Utils.GetProperty<Packager, PackagerConfiguration>("configuration", __instance); if (property.AssignedStationCount + property.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); return; } if (!InstanceFinder.IsServer) { return; } PackagingStation val = Utils.CallMethod<Packager, PackagingStation>("GetStationToAttend", __instance); if ((Object)(object)val != (Object)null) { Utils.CallMethod<Packager>("StartPackaging", __instance, new object[1] { val }); return; } BrickPress val2 = Utils.CallMethod<Packager, BrickPress>("GetBrickPress", __instance); if ((Object)(object)val2 != (Object)null) { Utils.CallMethod<Packager>("StartPress", __instance, new object[1] { val2 }); return; } PackagingStation val3 = Utils.CallMethod<Packager, PackagingStation>("GetStationMoveItems", __instance); if ((Object)(object)val3 != (Object)null) { Utils.CallMethod<Packager>("StartMoveItem", new Type[1] { typeof(PackagingStation) }, __instance, new object[1] { val3 }); return; } BrickPress val4 = Utils.CallMethod<Packager, BrickPress>("GetBrickPressMoveItems", __instance); if ((Object)(object)val4 != (Object)null) { Utils.CallMethod<Packager>("StartMoveItem", new Type[1] { typeof(BrickPress) }, __instance, new object[1] { val4 }); return; } object[] array = new object[1]; AdvancedTransitRoute val5 = Utils.CallMethod<Packager, AdvancedTransitRoute>("GetTransitRouteReady", __instance, array); ItemInstance val6 = Utils.CastTo<ItemInstance>(array[0]); if (val5 != null) { ((Employee)__instance).MoveItemBehaviour.Initialize((TransitRoute)(object)val5, val6, val6.Quantity, false); ((Behaviour)((Employee)__instance).MoveItemBehaviour).Enable_Networked(); return; } } ((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); } [HarmonyPatch(typeof(Chemist), "UpdateBehaviour")] [HarmonyPostfix] public static void ChemistUpdateBehaviourPostfix(Chemist __instance) { bool melonPrefEntry = Utils.GetMelonPrefEntry<bool>("workWithoutBeds"); bool melonPrefEntry2 = Utils.GetMelonPrefEntry<bool>("employeesAlwaysWork"); bool isEndOfDay = NetworkSingleton<TimeManager>.Instance.IsEndOfDay; bool flag = (Object)(object)((Employee)__instance).GetHome() != (Object)null; if ((bool)Utils.CallMethod<Chemist>("CanWork", __instance) && ((isEndOfDay && melonPrefEntry2) || (!flag && melonPrefEntry)) && !(bool)Utils.CallMethod<Chemist>("AnyWorkInProgress", __instance) && !((Employee)__instance).Fired && InstanceFinder.IsServer && (!isEndOfDay || melonPrefEntry2) && (flag || melonPrefEntry)) { if (Utils.GetProperty<Chemist, ChemistConfiguration>("configuration", __instance).TotalStations == 0) { ((Employee)__instance).SubmitNoWorkReason("I haven't been assigned any stations", "You can use your management clipboards to assign stations to me.", 0); ((Employee)__instance).SetIdle(true); } else if (InstanceFinder.IsServer) { Utils.CallMethod<Chemist>("TryStartNewTask", __instance); } } } [HarmonyPatch(typeof(Cleaner), "UpdateBehaviour")] [HarmonyPostfix] public static void CleanerUpdateBehaviourPostfix(Cleaner __instance) { bool melonPrefEntry = Utils.GetMelonPrefEntry<bool>("workWithoutBeds"); bool melonPrefEntry2 = Utils.GetMelonPrefEntry<bool>("employeesAlwaysWork"); bool isEndOfDay = NetworkSingleton<TimeManager>.Instance.IsEndOfDay; bool flag = (Object)(object)((Employee)__instance).GetHome() != (Object)null; if ((bool)Utils.CallMethod<Cleaner>("CanWork", __instance) && ((isEndOfDay && melonPrefEntry2) || (!flag && melonPrefEntry)) && !(bool)Utils.CallMethod<Cleaner>("AnyWorkInProgress", __instance) && !((Employee)__instance).Fired && (!isEndOfDay || melonPrefEntry2) && (flag || melonPrefEntry)) { if (Utils.GetProperty<Cleaner, CleanerConfiguration>("configuration", __instance).binItems.Count == 0) { ((Employee)__instance).SubmitNoWorkReason("I haven't been assigned any trash cans", "You can use your management clipboards to assign trash cans to me.", 0); ((Employee)__instance).SetIdle(true); } else if (InstanceFinder.IsServer) { Utils.CallMethod<Cleaner>("TryStartNewTask", __instance); } } } } }