Decompiled source of LateShiftMono v1.1.0

Mods/LateShiftMono.dll

Decompiled a day ago
using 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);
				}
			}
		}
	}
}