using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using ExtendedEmployees; using HarmonyLib; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppScheduleOne.DevUtilities; using Il2CppScheduleOne.Dialogue; using Il2CppScheduleOne.Employees; using Il2CppScheduleOne.Messaging; using Il2CppScheduleOne.Money; using Il2CppScheduleOne.NPCs; using Il2CppScheduleOne.Property; using Il2CppScheduleOne.UI; using Il2CppScheduleOne.UI.Phone.ContactsApp; using Il2CppScheduleOne.UI.Phone.Messages; using Il2CppSystem; using Il2CppSystem.Collections.Generic; using MelonLoader; using MelonLoader.Utils; using Newtonsoft.Json; using UnityEngine; using UnityEngine.AI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: MelonInfo(typeof(Core), "Extended Employees", "1.0.2", "Anton Leigue", null)] [assembly: MelonGame(null, "Schedule I")] [assembly: AssemblyTitle("ExtendedEmployees")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("ExtendedEmployees")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("8c7c2273-d0b4-4ecd-af5b-2c29f40f2450")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("1.0.0.0")] namespace ExtendedEmployees; public class Core : MelonMod { [CompilerGenerated] private sealed class d__14 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public Core <>4__this; private NPC 5__1; private GameObject 5__2; private Message 5__3; private Enumerator <>s__4; private NPC 5__5; private Exception 5__6; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__14(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { 5__1 = null; 5__2 = null; 5__3 = null; <>s__4 = null; 5__5 = null; 5__6 = null; <>1__state = -2; } private bool MoveNext() { //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Expected O, but got Unknown //IL_0211: Unknown result type (might be due to invalid IL or missing references) //IL_021b: Expected O, but got Unknown //IL_02aa: Unknown result type (might be due to invalid IL or missing references) //IL_02b4: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; goto IL_0046; case 1: <>1__state = -1; goto IL_0046; case 2: { <>1__state = -1; if (<>4__this.contactCreated) { return false; } <>4__this.contactCreated = true; try { 5__1 = null; <>s__4 = NPCManager.NPCRegistry.GetEnumerator(); while (<>s__4.MoveNext()) { 5__5 = <>s__4.Current; if ((Object)(object)5__5 != (Object)null) { 5__1 = 5__5; break; } 5__5 = null; } <>s__4 = null; if ((Object)(object)5__1 == (Object)null) { MelonLogger.Error("Failed finding template NPC"); return false; } 5__2 = Object.Instantiate(((Component)5__1).gameObject); <>4__this.employeeContactNPC = 5__2.GetComponent(); <>4__this.employeeContactNPC.FirstName = "Extended"; <>4__this.employeeContactNPC.LastName = "Employees"; <>4__this.employeeContactNPC.BakedGUID = Guid.NewGuid().ToString(); <>4__this.employeeContactNPC.IsImportant = true; <>4__this.employeeContactNPC.ConversationCanBeHidden = false; <>4__this.employeeContactNPC.ShowRelationshipInfo = false; <>4__this.employeeContactNPC.MugshotSprite = ((App)(object)PlayerSingleton.Instance).AppIcon; <>4__this.employeeConversation = new MSGConversation(<>4__this.employeeContactNPC, "Extended Employees"); <>4__this.employeeConversation.messageHistory = new List(); <>4__this.employeeConversation.messageChainHistory = new List(); <>4__this.employeeConversation.bubbles = new List(); <>4__this.employeeConversation.EntryVisible = true; <>4__this.employeeContactNPC.MSGConversation = <>4__this.employeeConversation; NPCManager.NPCRegistry.Add(<>4__this.employeeContactNPC); 5__3 = new Message("Welcome to Extended Employees.", (ESenderType)1, true, -1); <>4__this.employeeConversation.SendMessage(5__3, true, false); <>4__this.OpenMainDialogue(); MelonLogger.Msg("Extended Employees contact created!"); 5__1 = null; 5__2 = null; 5__3 = null; } catch (Exception ex) { 5__6 = ex; MelonLogger.Error($"Phone contact failed: {5__6}"); } return false; } IL_0046: if (NPCManager.NPCRegistry == null || NPCManager.NPCRegistry.Count == 0) { <>2__current = null; <>1__state = 1; return true; } <>2__current = (object)new WaitForSeconds(2f); <>1__state = 2; return true; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class d__24 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public Property targetProperty; public HiringCandidate candidate; public List employeesBefore; public Core <>4__this; private Employee 5__1; private Employee[] 5__2; private string 5__3; private EmployeeUpgradeData 5__4; private Employee[] <>s__5; private int <>s__6; private Employee 5__7; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__24(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { 5__1 = null; 5__2 = null; 5__3 = null; 5__4 = null; <>s__5 = null; 5__7 = null; <>1__state = -2; } private bool MoveNext() { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Expected O, but got Unknown //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = null; <>1__state = 1; return true; case 1: <>1__state = -1; <>2__current = (object)new WaitForSeconds(0.2f); <>1__state = 2; return true; case 2: <>1__state = -1; 5__1 = null; 5__2 = Il2CppArrayBase.op_Implicit(Object.FindObjectsOfType()); <>s__5 = 5__2; for (<>s__6 = 0; <>s__6 < <>s__5.Length; <>s__6++) { 5__7 = <>s__5[<>s__6]; if (!((Object)(object)5__7 == (Object)null) && !employeesBefore.Contains(5__7) && 5__7.EmployeeType == candidate.EmployeeType) { 5__1 = 5__7; 5__7 = null; } } <>s__5 = null; if ((Object)(object)5__1 == (Object)null) { MelonLogger.Error("Failed finding newly hired employee."); return false; } if (string.IsNullOrEmpty(((NPC)5__1).BakedGUID)) { ((NPC)5__1).BakedGUID = Guid.NewGuid().ToString(); } ((Object)5__1).name = candidate.Name; 5__3 = ((Object)5__1).name; if (!EmployeeData.ContainsKey(5__3)) { EmployeeData[5__3] = new EmployeeUpgradeData(); } 5__4 = EmployeeData[5__3]; 5__4.CustomWage = candidate.Wage; 5__4.Traits = new List(candidate.Traits); 5__4.WorkSpeedMultiplier = 1f; 5__4.WalkSpeedMultiplier = 1f; if (5__4.Traits.Contains("motivated")) { 5__4.WorkSpeedMultiplier = 1.5f; 5__4.WalkSpeedMultiplier = 1.5f; } if (5__4.Traits.Contains("veteran")) { 5__4.WorkSpeedMultiplier = 2f; 5__4.WalkSpeedMultiplier = 2f; } SaveData(); return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class d__15 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public NavMeshAgent agent; public Core <>4__this; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__15(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(5f); <>1__state = 1; return true; case 1: <>1__state = -1; if ((Object)(object)agent != (Object)null) { agent.isStopped = false; } 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 NPC employeeContactNPC; private MSGConversation employeeConversation; private bool contactCreated = false; private Employee[] cachedEmployees = (Employee[])(object)new Employee[0]; private float refreshTimer = 0f; private Dictionary> HiringCandidates = new Dictionary>(); private static string SavePath = Path.Combine(MelonEnvironment.UserDataDirectory, "ExtendedEmployees.json"); public static bool AutoPayrollEnabled = false; public static bool HRUnlocked = false; public static List AllTraits = new List { new EmployeeTrait { Id = "hard_worker", Name = "Hard Worker", Description = "Maximum work speed increased to 7x", Type = TraitType.Positive }, new EmployeeTrait { Id = "efficient_walker", Name = "Efficient Walker", Description = "Maximum walk speed increased to 7x", Type = TraitType.Positive }, new EmployeeTrait { Id = "loyal", Name = "Loyal", Description = "-10% wages", Type = TraitType.Positive, WageModifier = -0.1f }, new EmployeeTrait { Id = "motivated", Name = "Motivated", Description = "Starts with 1.5x work and walk speed", Type = TraitType.Positive }, new EmployeeTrait { Id = "veteran", Name = "Veteran", Description = "Starts with 2x work and walk speed", Type = TraitType.Positive, WageModifier = 0.25f }, new EmployeeTrait { Id = "perfectionist", Name = "Perfectionist", Description = "Work upgrades give bigger bonuses", Type = TraitType.Positive }, new EmployeeTrait { Id = "lazy", Name = "Lazy", Description = "Maximum work speed capped at 2x", Type = TraitType.Negative }, new EmployeeTrait { Id = "slow_walker", Name = "Slow Walker", Description = "Maximum walk speed capped at 2x", Type = TraitType.Negative }, new EmployeeTrait { Id = "demanding", Name = "Demanding", Description = "+15% wages", Type = TraitType.Negative, WageModifier = 0.15f }, new EmployeeTrait { Id = "greedy", Name = "Greedy", Description = "+35% wages", Type = TraitType.Negative, WageModifier = 0.35f }, new EmployeeTrait { Id = "clumsy", Name = "Clumsy", Description = "Occasionally stops working", Type = TraitType.Negative } }; public static List FakeNames = new List { "John Miller", "Mike Carter", "Ryan Smith", "Alex Turner", "Chris Walker", "David Moore", "Jake Wilson", "Tyler Davis", "Kevin Brown", "Nick Taylor", "Ethan White", "Jason Hill", "Brandon Scott", "Aaron King", "Nathan Reed", "Lucas Gray", "Connor Adams", "Dylan Brooks", "Logan Price", "Hunter Ross" }; public static Dictionary EmployeeData = new Dictionary(); public override void OnInitializeMelon() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown Harmony val = new Harmony("extendedemployees"); val.PatchAll(); LoadData(); MelonLogger.Msg("Extended Employees Loaded!"); MelonCoroutines.Start(CreatePhoneContact()); } public override void OnUpdate() { refreshTimer += Time.deltaTime; if (employeeConversation == null || (Object)(object)employeeContactNPC == (Object)null) { contactCreated = false; MelonCoroutines.Start(CreatePhoneContact()); } if (refreshTimer >= 2f) { refreshTimer = 0f; cachedEmployees = Il2CppArrayBase.op_Implicit(Object.FindObjectsOfType()); } Employee[] array = cachedEmployees; foreach (Employee val in array) { if ((Object)(object)val == (Object)null) { continue; } string text = ((Object)val).name; if (string.IsNullOrEmpty(text)) { text = (((Object)val).name = Guid.NewGuid().ToString()); } if (!EmployeeData.ContainsKey(text)) { EmployeeUpgradeData employeeUpgradeData = new EmployeeUpgradeData(); GenerateTraits(employeeUpgradeData); float dailyWage = val.DailyWage; float num = 1f; foreach (string traitId in employeeUpgradeData.Traits) { EmployeeTrait employeeTrait = AllTraits.Find((EmployeeTrait x) => x.Id == traitId); if (employeeTrait != null) { num += employeeTrait.WageModifier; } } employeeUpgradeData.CustomWage = Mathf.Round(dailyWage * num); if (employeeUpgradeData.Traits.Contains("motivated")) { employeeUpgradeData.WorkSpeedMultiplier = 1.5f; employeeUpgradeData.WalkSpeedMultiplier = 1.5f; } if (employeeUpgradeData.Traits.Contains("veteran")) { employeeUpgradeData.WorkSpeedMultiplier = 2f; employeeUpgradeData.WalkSpeedMultiplier = 2f; } EmployeeData[text] = employeeUpgradeData; SaveData(); } EmployeeUpgradeData data = GetData(val); NavMeshAgent component = ((Component)val).GetComponent(); if ((Object)(object)component != (Object)null) { float walkSpeedMultiplier = data.WalkSpeedMultiplier; component.speed = 3.5f * walkSpeedMultiplier; } if (AutoPayrollEnabled && !val.PaidForToday) { PayEmployee(val); } if (Random.Range(0f, 1f) < 0.0005f && data.Traits.Contains("clumsy")) { NavMeshAgent component2 = ((Component)val).GetComponent(); if ((Object)(object)component2 != (Object)null) { component2.isStopped = true; MelonCoroutines.Start(ResumeEmployee(component2)); } } } } [IteratorStateMachine(typeof(d__14))] private IEnumerator CreatePhoneContact() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__14(0) { <>4__this = this }; } [IteratorStateMachine(typeof(d__15))] private IEnumerator ResumeEmployee(NavMeshAgent agent) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__15(0) { <>4__this = this, agent = agent }; } private void OpenMainDialogue() { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Expected O, but got Unknown //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Expected O, but got Unknown //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Expected O, but got Unknown //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Expected O, but got Unknown employeeConversation.ClearResponses(false); List val = new List(); val.Add(new Response("Manage Employees", "", Action.op_Implicit((Action)delegate { OpenEmployeesMenu(); }), true)); val.Add(new Response("Payroll", "", Action.op_Implicit((Action)delegate { OpenPayrollMenu(); }), true)); val.Add(new Response("Hire Employees", "", Action.op_Implicit((Action)delegate { OpenHirePropertiesMenu(); }), true)); val.Add(new Response("Upgrades", "", Action.op_Implicit((Action)delegate { OpenUpgradesMenu(); }), true)); val.Add(new Response("Statistics", "", Action.op_Implicit((Action)delegate { OpenStatsMenu(); }), true)); employeeConversation.ShowResponses(val, 0f, false); } private List GetPlayerOwnedProperties() { List list = new List(); Property[] array = Il2CppArrayBase.op_Implicit(Object.FindObjectsOfType()); Property[] array2 = array; foreach (Property val in array2) { if (!((Object)(object)val == (Object)null) && val.IsOwned && ((Component)val).gameObject.activeInHierarchy && !list.Contains(val)) { list.Add(val); } } return list; } private void OpenEmployeesMenu() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Expected O, but got Unknown //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Expected O, but got Unknown employeeConversation.ClearResponses(false); Message val = new Message("Select Property", (ESenderType)1, true, -1); employeeConversation.SendMessage(val, true, false); List val2 = new List(); List playerOwnedProperties = GetPlayerOwnedProperties(); foreach (Property item in playerOwnedProperties) { string propertyName = ((Object)item).name; val2.Add(new Response(propertyName, "", Action.op_Implicit((Action)delegate { OpenPropertyEmployees(propertyName); }), true)); } val2.Add(new Response("Back", "", Action.op_Implicit((Action)delegate { OpenMainDialogue(); }), true)); employeeConversation.ShowResponses(val2, 0f, false); } private void OpenHirePropertiesMenu() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Expected O, but got Unknown //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Expected O, but got Unknown employeeConversation.ClearResponses(false); Message val = new Message("Select Property To Hire For", (ESenderType)1, true, -1); employeeConversation.SendMessage(val, true, false); List val2 = new List(); List playerOwnedProperties = GetPlayerOwnedProperties(); foreach (Property item in playerOwnedProperties) { string propertyName = ((Object)item).name; val2.Add(new Response(propertyName, "", Action.op_Implicit((Action)delegate { OpenHireMenu(propertyName); }), true)); } val2.Add(new Response("Back", "", Action.op_Implicit((Action)delegate { OpenMainDialogue(); }), true)); employeeConversation.ShowResponses(val2, 0f, false); } private List GenerateCandidates(EEmployeeType employeeType) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Expected I4, but got Unknown //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) List list = new List(); HashSet hashSet = new HashSet(); for (int i = 0; i < 3; i++) { EmployeeUpgradeData employeeUpgradeData = new EmployeeUpgradeData(); GenerateTraits(employeeUpgradeData); float num = 200f; switch ((int)employeeType) { case 0: num = 200f; break; case 2: num = 350f; break; case 1: num = 250f; break; case 3: num = 180f; break; } float num2 = 1f; foreach (string traitId in employeeUpgradeData.Traits) { EmployeeTrait employeeTrait = AllTraits.Find((EmployeeTrait x) => x.Id == traitId); if (employeeTrait != null) { num2 += employeeTrait.WageModifier; } } HiringCandidate hiringCandidate = new HiringCandidate(); hiringCandidate.EmployeeType = employeeType; string text = ""; while (string.IsNullOrEmpty(text) || hashSet.Contains(text)) { text = FakeNames[Random.Range(0, FakeNames.Count)]; } hashSet.Add(text); hiringCandidate.Name = text; hiringCandidate.Traits = new List(employeeUpgradeData.Traits); hiringCandidate.Wage = Mathf.Round(num * num2); list.Add(hiringCandidate); } return list; } private void OpenHireMenu(string propertyName) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Expected O, but got Unknown //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Expected O, but got Unknown //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Expected O, but got Unknown //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Expected O, but got Unknown //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Expected O, but got Unknown employeeConversation.ClearResponses(false); Message val = new Message("Hire Employees For " + propertyName, (ESenderType)1, true, -1); employeeConversation.SendMessage(val, true, false); List val2 = new List(); val2.Add(new Response("Botanists", "", Action.op_Implicit((Action)delegate { OpenCandidateMenu(propertyName, (EEmployeeType)0); }), true)); val2.Add(new Response("Cleaners", "", Action.op_Implicit((Action)delegate { OpenCandidateMenu(propertyName, (EEmployeeType)3); }), true)); val2.Add(new Response("Packagers", "", Action.op_Implicit((Action)delegate { OpenCandidateMenu(propertyName, (EEmployeeType)1); }), true)); val2.Add(new Response("Chemists", "", Action.op_Implicit((Action)delegate { OpenCandidateMenu(propertyName, (EEmployeeType)2); }), true)); val2.Add(new Response("Back", "", Action.op_Implicit((Action)delegate { OpenHirePropertiesMenu(); }), true)); employeeConversation.ShowResponses(val2, 0f, false); } private void OpenCandidateMenu(string propertyName, EEmployeeType employeeType) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Expected O, but got Unknown //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0335: Unknown result type (might be due to invalid IL or missing references) //IL_033f: Expected O, but got Unknown //IL_035d: Unknown result type (might be due to invalid IL or missing references) //IL_0367: Expected O, but got Unknown //IL_0252: Unknown result type (might be due to invalid IL or missing references) //IL_02ef: Unknown result type (might be due to invalid IL or missing references) //IL_02f9: Expected O, but got Unknown employeeConversation.ClearResponses(false); string key = propertyName + "_" + ((object)(EEmployeeType)(ref employeeType)).ToString(); if (!HiringCandidates.ContainsKey(key)) { HiringCandidates[key] = GenerateCandidates(employeeType); } List list = HiringCandidates[key]; Message val = new Message($"Available {employeeType}s", (ESenderType)1, true, -1); employeeConversation.SendMessage(val, true, false); List val2 = new List(); foreach (HiringCandidate item in list) { string text = ""; List list2 = new List(); List list3 = new List(); foreach (string traitId in item.Traits) { EmployeeTrait employeeTrait = AllTraits.Find((EmployeeTrait x) => x.Id == traitId); if (employeeTrait != null) { if (employeeTrait.Type == TraitType.Positive) { list2.Add(employeeTrait); } else { list3.Add(employeeTrait); } } } if (list2.Count > 0) { text = text + "+ " + list2[0].Name + "\n"; } if (list3.Count > 0) { text = text + "- " + list3[0].Name + "\n"; } HiringCandidate captured = item; float value = (HRUnlocked ? 600f : 1200f); val2.Add(new Response($"{item.EmployeeType} [Hire: ${value}] [Wage: ${item.Wage}] | {text.Replace("\n", " | ")}", "", Action.op_Implicit((Action)delegate { HireCandidate(propertyName, captured); }), true)); } val2.Add(new Response("Reroll [$500]", "", Action.op_Implicit((Action)delegate { //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown //IL_0046: Unknown result type (might be due to invalid IL or missing references) if (NetworkSingleton.Instance.onlineBalance < 500f) { Message val3 = new Message("Not enough money.", (ESenderType)1, true, -1); employeeConversation.SendMessage(val3, true, false); OpenCandidateMenu(propertyName, employeeType); } else { NetworkSingleton.Instance.CreateOnlineTransaction("Candidate Reroll", -500f, 1f, "Extended Employees"); HiringCandidates[key] = GenerateCandidates(employeeType); OpenCandidateMenu(propertyName, employeeType); } }), true)); val2.Add(new Response("Back", "", Action.op_Implicit((Action)delegate { OpenHireMenu(propertyName); }), true)); employeeConversation.ShowResponses(val2, 0f, false); } private void HireCandidate(string propertyName, HiringCandidate candidate) { //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Expected O, but got Unknown //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Expected O, but got Unknown //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Expected O, but got Unknown Property val = null; Property[] array = Il2CppArrayBase.op_Implicit(Object.FindObjectsOfType()); Property[] array2 = array; foreach (Property val2 in array2) { if (!((Object)(object)val2 == (Object)null) && val2.IsOwned && ((Object)val2).name == propertyName) { val = val2; break; } } if ((Object)(object)val == (Object)null) { return; } int count = val.Employees.Count; int employeeCapacity = val.EmployeeCapacity; if (count >= employeeCapacity) { Message val3 = new Message(propertyName + " employee capacity reached.", (ESenderType)1, true, -1); employeeConversation.SendMessage(val3, true, false); return; } float num = 1200f; if (HRUnlocked) { num *= 0.5f; } if (NetworkSingleton.Instance.onlineBalance < num) { Message val4 = new Message("Not enough money.", (ESenderType)1, true, -1); employeeConversation.SendMessage(val4, true, false); return; } NetworkSingleton.Instance.CreateOnlineTransaction("Hire " + candidate.Name, 0f - num, 1f, "Extended Employees"); List employeesBefore = new List((IEnumerable)Object.FindObjectsOfType()); NetworkSingleton.Instance.CreateNewEmployee(val, candidate.EmployeeType); refreshTimer = 999f; MelonCoroutines.Start(FinishHireEmployee(val, candidate, employeesBefore)); Message val5 = new Message(candidate.Name + " hired.", (ESenderType)1, true, -1); employeeConversation.SendMessage(val5, true, false); string key = propertyName + "_" + ((object)(EEmployeeType)(ref candidate.EmployeeType)).ToString(); HiringCandidates.Remove(key); OpenCandidateMenu(propertyName, candidate.EmployeeType); } [IteratorStateMachine(typeof(d__24))] private IEnumerator FinishHireEmployee(Property targetProperty, HiringCandidate candidate, List employeesBefore) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__24(0) { <>4__this = this, targetProperty = targetProperty, candidate = candidate, employeesBefore = employeesBefore }; } private void OpenPropertyEmployees(string propertyName) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Expected O, but got Unknown //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Expected O, but got Unknown //IL_024c: Unknown result type (might be due to invalid IL or missing references) //IL_0256: Expected O, but got Unknown employeeConversation.ClearResponses(false); Message val = new Message(propertyName, (ESenderType)1, true, -1); employeeConversation.SendMessage(val, true, false); List val2 = new List(); List list = new List(); Employee[] array = cachedEmployees; foreach (Employee val3 in array) { if (!((Object)(object)val3 == (Object)null)) { string text = "Unknown"; if ((Object)(object)val3.AssignedProperty != (Object)null) { text = ((Object)val3.AssignedProperty).name; } if (!(text != propertyName)) { list.Add(val3); } } } list.Sort(delegate(Employee a, Employee b) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) EEmployeeType employeeType = a.EmployeeType; return ((Enum)(EEmployeeType)(ref employeeType)).CompareTo((object?)b.EmployeeType); }); if (list.Count == 0) { Message val4 = new Message("No employees hired.", (ESenderType)1, true, -1); employeeConversation.SendMessage(val4, true, false); } foreach (Employee employee in list) { val2.Add(new Response($"{((Object)employee).name} ({employee.EmployeeType}) | W:{GetData(employee).WorkSpeedMultiplier:F1}x | S:{GetData(employee).WalkSpeedMultiplier:F1}x", "", Action.op_Implicit((Action)delegate { OpenEmployeeSubmenu(employee); }), true)); } val2.Add(new Response("Back", "Back", Action.op_Implicit((Action)delegate { OpenEmployeesMenu(); }), true)); employeeConversation.ShowResponses(val2, 0f, false); } private void OpenEmployeeSubmenu(Employee employee) { //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Expected O, but got Unknown //IL_0259: Unknown result type (might be due to invalid IL or missing references) //IL_0263: Expected O, but got Unknown //IL_02c0: Unknown result type (might be due to invalid IL or missing references) //IL_02ca: Expected O, but got Unknown //IL_0321: Unknown result type (might be due to invalid IL or missing references) //IL_032b: Expected O, but got Unknown //IL_0349: Unknown result type (might be due to invalid IL or missing references) //IL_0353: Expected O, but got Unknown //IL_0371: Unknown result type (might be due to invalid IL or missing references) //IL_037b: Expected O, but got Unknown employeeConversation.ClearResponses(false); EmployeeUpgradeData data = GetData(employee); if (data == null) { return; } string text = ""; foreach (string traitId in data.Traits) { EmployeeTrait employeeTrait = AllTraits.Find((EmployeeTrait x) => x.Id == traitId); if (employeeTrait != null) { text = ((employeeTrait.Type != 0) ? (text + "- " + employeeTrait.Name + "\n") : (text + "+ " + employeeTrait.Name + "\n")); } } Message val = new Message($"{((Object)employee).name}\nWork Speed: {data.WorkSpeedMultiplier:F1}x\nWalk Speed: {data.WalkSpeedMultiplier:F1}x\nDaily Wage: ${GetEmployeeWage(employee)}\n\nTraits:\n{text}", (ESenderType)1, true, -1); employeeConversation.SendMessage(val, true, false); List val2 = new List(); val2.Add(new Response($"Work Upgrade [${GetUpgradePrice(data.WorkSpeedMultiplier)}]", "", Action.op_Implicit((Action)delegate { //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Expected O, but got Unknown //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Expected O, but got Unknown //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Expected O, but got Unknown float upgradePrice2 = GetUpgradePrice(data.WorkSpeedMultiplier); float maxWorkSpeed = GetMaxWorkSpeed(data); if (data.WorkSpeedMultiplier >= maxWorkSpeed) { Message val10 = new Message($"Maximum work speed reached ({maxWorkSpeed:F1}x).", (ESenderType)1, true, -1); employeeConversation.SendMessage(val10, true, false); OpenEmployeeSubmenu(employee); } else if (NetworkSingleton.Instance.onlineBalance < upgradePrice2) { Message val11 = new Message("Not enough money.", (ESenderType)1, true, -1); employeeConversation.SendMessage(val11, true, false); OpenEmployeeSubmenu(employee); } else { NetworkSingleton.Instance.CreateOnlineTransaction("Work Speed Upgrade", 0f - upgradePrice2, 1f, "Extended Employees"); float num = 0.5f; if (data.Traits.Contains("perfectionist")) { num = 0.75f; } data.WorkSpeedMultiplier += num; SaveData(); Message val12 = new Message($"{((Object)employee).name} work speed upgraded to {data.WorkSpeedMultiplier:F1}x", (ESenderType)1, true, -1); employeeConversation.SendMessage(val12, true, false); OpenEmployeeSubmenu(employee); } }), true)); val2.Add(new Response($"Speed Upgrade [${GetUpgradePrice(data.WalkSpeedMultiplier)}]", "", Action.op_Implicit((Action)delegate { //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Expected O, but got Unknown //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Expected O, but got Unknown //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Expected O, but got Unknown float upgradePrice = GetUpgradePrice(data.WalkSpeedMultiplier); float maxWalkSpeed = GetMaxWalkSpeed(data); if (data.WalkSpeedMultiplier >= maxWalkSpeed) { Message val7 = new Message($"Maximum walk speed reached ({maxWalkSpeed:F1}x).", (ESenderType)1, true, -1); employeeConversation.SendMessage(val7, true, false); OpenEmployeeSubmenu(employee); } else if (NetworkSingleton.Instance.onlineBalance < upgradePrice) { Message val8 = new Message("Not enough money.", (ESenderType)1, true, -1); employeeConversation.SendMessage(val8, true, false); OpenEmployeeSubmenu(employee); } else { NetworkSingleton.Instance.CreateOnlineTransaction("Walk Speed Upgrade", 0f - upgradePrice, 1f, "Extended Employees"); data.WalkSpeedMultiplier += 0.5f; SaveData(); Message val9 = new Message($"{((Object)employee).name} walk speed upgraded to {data.WalkSpeedMultiplier:F1}x", (ESenderType)1, true, -1); employeeConversation.SendMessage(val9, true, false); OpenEmployeeSubmenu(employee); } }), true)); val2.Add(new Response($"Pay [${GetEmployeeWage(employee)}]", "", Action.op_Implicit((Action)delegate { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Expected O, but got Unknown //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Expected O, but got Unknown if (employee.PaidForToday) { Message val4 = new Message(((Object)employee).name + " has already been paid today.", (ESenderType)1, true, -1); employeeConversation.SendMessage(val4, true, false); OpenEmployeeSubmenu(employee); } else { if (PayEmployee(employee)) { Message val5 = new Message($"You paid {((Object)employee).name} ${GetEmployeeWage(employee)}", (ESenderType)1, true, -1); employeeConversation.SendMessage(val5, true, false); } else { Message val6 = new Message("Not enough money.", (ESenderType)1, true, -1); employeeConversation.SendMessage(val6, true, false); } OpenEmployeeSubmenu(employee); } }), true)); val2.Add(new Response("Fire Employee", "", Action.op_Implicit((Action)delegate { //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Expected O, but got Unknown try { string name = ((Object)employee).name; if (EmployeeData.ContainsKey(name)) { EmployeeData.Remove(name); } ((Component)employee).SendMessage("Fire", (SendMessageOptions)1); ((Component)employee).SendMessage("Despawn", (SendMessageOptions)1); ((Component)employee).gameObject.SetActive(false); SaveData(); Message val3 = new Message(((Object)employee).name + " was fired.", (ESenderType)1, true, -1); employeeConversation.SendMessage(val3, true, false); OpenEmployeesMenu(); } catch (Exception value) { MelonLogger.Error($"Fire employee failed: {value}"); } }), true)); val2.Add(new Response("Back", "", Action.op_Implicit((Action)delegate { OpenEmployeesMenu(); }), true)); employeeConversation.ShowResponses(val2, 0f, false); } private void OpenPayrollMenu() { //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Expected O, but got Unknown //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Expected O, but got Unknown //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Expected O, but got Unknown //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Expected O, but got Unknown employeeConversation.ClearResponses(false); float num = 0f; Employee[] array = cachedEmployees; foreach (Employee val in array) { if (!((Object)(object)val == (Object)null) && !val.PaidForToday) { num += GetEmployeeWage(val); } } Message val2 = new Message($"Outstanding Payroll: ${num}", (ESenderType)1, true, -1); employeeConversation.SendMessage(val2, true, false); List val3 = new List(); val3.Add(new Response($"Pay All Employees (${num})", "", Action.op_Implicit((Action)delegate { PayAllEmployees(cachedEmployees); OpenPayrollMenu(); }), true)); val3.Add(new Response(AutoPayrollEnabled ? "Auto Payroll [ON]" : "Auto Payroll [OFF]", "", Action.op_Implicit((Action)delegate { AutoPayrollEnabled = !AutoPayrollEnabled; OpenPayrollMenu(); }), true)); val3.Add(new Response("Back", "", Action.op_Implicit((Action)delegate { OpenMainDialogue(); }), true)); employeeConversation.ShowResponses(val3, 0f, false); } private void OpenUpgradesMenu() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Expected O, but got Unknown //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Expected O, but got Unknown employeeConversation.ClearResponses(false); Message val = new Message("Company Upgrades", (ESenderType)1, true, -1); employeeConversation.SendMessage(val, true, false); List val2 = new List(); val2.Add(new Response(HRUnlocked ? "HR [OWNED]" : "HR [$10000]", "", Action.op_Implicit((Action)delegate { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Expected O, but got Unknown //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Expected O, but got Unknown if (HRUnlocked) { Message val3 = new Message("HR already purchased.", (ESenderType)1, true, -1); employeeConversation.SendMessage(val3, true, false); OpenUpgradesMenu(); } else if (NetworkSingleton.Instance.onlineBalance < 10000f) { Message val4 = new Message("Not enough money.", (ESenderType)1, true, -1); employeeConversation.SendMessage(val4, true, false); OpenUpgradesMenu(); } else { NetworkSingleton.Instance.CreateOnlineTransaction("HR Upgrade", -10000f, 1f, "Extended Employees"); HRUnlocked = true; SaveData(); Message val5 = new Message("Hiring costs reduced by 50%.", (ESenderType)1, true, -1); employeeConversation.SendMessage(val5, true, false); OpenUpgradesMenu(); } }), true)); val2.Add(new Response("Back", "", Action.op_Implicit((Action)delegate { OpenMainDialogue(); }), true)); employeeConversation.ShowResponses(val2, 0f, false); } private void OpenStatsMenu() { //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Expected O, but got Unknown //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Expected O, but got Unknown employeeConversation.ClearResponses(false); int num = 0; float num2 = 0f; Employee[] array = cachedEmployees; foreach (Employee val in array) { if (!((Object)(object)val == (Object)null)) { num++; num2 += GetEmployeeWage(val); } } Message val2 = new Message($"Employees: {num}\nPayroll: ${num2}\nAuto Payroll: {AutoPayrollEnabled}", (ESenderType)1, true, -1); employeeConversation.SendMessage(val2, true, false); List val3 = new List(); val3.Add(new Response("Back", "", Action.op_Implicit((Action)delegate { OpenMainDialogue(); }), true)); employeeConversation.ShowResponses(val3, 0f, false); } private float GetMaxWorkSpeed(EmployeeUpgradeData data) { float result = 5f; foreach (string trait in data.Traits) { if (trait == "hard_worker") { result = 7f; } if (trait == "lazy") { result = 2f; } } return result; } private float GetMaxWalkSpeed(EmployeeUpgradeData data) { float result = 5f; foreach (string trait in data.Traits) { if (trait == "efficient_walker") { result = 7f; } if (trait == "slow_walker") { result = 2f; } } return result; } private float GetUpgradePrice(float currentMultiplier) { return 500f * currentMultiplier; } public static void SaveData() { try { SaveContainer saveContainer = new SaveContainer(); saveContainer.EmployeeData = EmployeeData; saveContainer.HRUnlocked = HRUnlocked; saveContainer.AutoPayrollEnabled = AutoPayrollEnabled; string contents = JsonConvert.SerializeObject((object)saveContainer, (Formatting)1); File.WriteAllText(SavePath, contents); } catch (Exception value) { MelonLogger.Error($"Save failed: {value}"); } } public static void LoadData() { try { if (!File.Exists(SavePath)) { EmployeeData = new Dictionary(); return; } string text = File.ReadAllText(SavePath); SaveContainer saveContainer = JsonConvert.DeserializeObject(text); EmployeeData = saveContainer.EmployeeData; HRUnlocked = saveContainer.HRUnlocked; AutoPayrollEnabled = saveContainer.AutoPayrollEnabled; if (EmployeeData == null) { EmployeeData = new Dictionary(); } } catch (Exception value) { MelonLogger.Error($"Load failed: {value}"); EmployeeData = new Dictionary(); } } public static EmployeeUpgradeData GetData(Employee employee) { if ((Object)(object)employee == (Object)null) { return new EmployeeUpgradeData(); } string text = ((Object)employee).name; if (string.IsNullOrEmpty(text)) { text = (((Object)employee).name = Guid.NewGuid().ToString()); } if (!EmployeeData.ContainsKey(text)) { return null; } return EmployeeData[text]; } private static void GenerateTraits(EmployeeUpgradeData data) { if (data.Traits.Count <= 0) { List list = AllTraits.FindAll((EmployeeTrait x) => x.Type == TraitType.Positive); List list2 = AllTraits.FindAll((EmployeeTrait x) => x.Type == TraitType.Negative); EmployeeTrait positive1 = list[Random.Range(0, list.Count)]; data.Traits.Add(positive1.Id); List list3 = list.FindAll((EmployeeTrait x) => x.Id != positive1.Id && (!(x.Id == "loyal") || !(positive1.Id == "demanding")) && (!(x.Id == "motivated") || !(positive1.Id == "veteran")) && (!(x.Id == "veteran") || !(positive1.Id == "motivated"))); if (list3.Count > 0) { EmployeeTrait employeeTrait = list3[Random.Range(0, list3.Count)]; data.Traits.Add(employeeTrait.Id); } List list4 = list2.FindAll((EmployeeTrait x) => (!(x.Id == "slow_walker") || !data.Traits.Contains("efficient_walker")) && (!(x.Id == "demanding") || !data.Traits.Contains("loyal")) && (!(x.Id == "lazy") || !data.Traits.Contains("hard_worker")) && (!(x.Id == "greedy") || !data.Traits.Contains("loyal")) && (!(x.Id == "lazy") || !data.Traits.Contains("motivated")) && (!(x.Id == "clumsy") || !data.Traits.Contains("perfectionist"))); if (list4.Count > 0) { EmployeeTrait employeeTrait2 = list4[Random.Range(0, list4.Count)]; data.Traits.Add(employeeTrait2.Id); } } } private float GetEmployeeWage(Employee employee) { EmployeeUpgradeData data = GetData(employee); if (data == null) { return employee.DailyWage; } float num = ((data.CustomWage > 0f) ? data.CustomWage : employee.DailyWage); return Mathf.Round(num); } public static bool PayEmployee(Employee employee) { try { if ((Object)(object)employee == (Object)null) { return false; } if (employee.PaidForToday) { return false; } EmployeeUpgradeData data = GetData(employee); float num = ((data.CustomWage > 0f) ? data.CustomWage : employee.DailyWage); if (NetworkSingleton.Instance.onlineBalance < num) { return false; } NetworkSingleton.Instance.CreateOnlineTransaction("Employee Payment", 0f - num, 1f, "Extended Employees"); typeof(Employee).GetProperty("PaidForToday")?.SetValue(employee, true); ((Component)employee).SendMessage("Refresh", (SendMessageOptions)1); ((Component)employee).SendMessage("RefreshState", (SendMessageOptions)1); ((Component)employee).SendMessage("UpdateWorkState", (SendMessageOptions)1); ((Component)employee).SendMessage("BeginWork", (SendMessageOptions)1); return true; } catch (Exception value) { MelonLogger.Error($"PayEmployee failed: {value}"); return false; } } public static void PayAllEmployees(Employee[] employees) { foreach (Employee val in employees) { if (!((Object)(object)val == (Object)null)) { PayEmployee(val); } } } } public enum TraitType { Positive, Negative } public class EmployeeTrait { public string Id; public string Name; public string Description; public TraitType Type; public float WageModifier; } public class SaveContainer { public bool AutoPayrollEnabled = false; public bool HRUnlocked = false; public Dictionary EmployeeData = new Dictionary(); } public class HiringCandidate { public string Name; public EEmployeeType EmployeeType; public float Wage; public List Traits = new List(); } public class EmployeeUpgradeData { public float CustomWage = -1f; public float WorkSpeedMultiplier = 1f; public float WalkSpeedMultiplier = 1f; public List Traits = new List(); } [HarmonyPatch(typeof(Employee), "get_CurrentWorkSpeed")] public class EmployeeSpeedPatch { private static void Postfix(Employee __instance, ref float __result) { EmployeeUpgradeData data = Core.GetData(__instance); float workSpeedMultiplier = data.WorkSpeedMultiplier; __result *= workSpeedMultiplier; } } [HarmonyPatch(typeof(DialogueController_Fixer), "ModifyChoiceList")] public class MannyChoicesPatch { private static void Postfix(string dialogueLabel, ref List existingChoices) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Expected O, but got Unknown try { List val = new List(); DialogueChoiceData val2 = new DialogueChoiceData(); val2.Guid = Guid.NewGuid().ToString(); val2.ChoiceLabel = "Extended Employees"; val2.ChoiceText = "Use the Extended Employees app on your phone to hire and manage employees."; val2.ShowWorldspaceDialogue = true; val.Add(val2); existingChoices = val; MelonLogger.Msg("Manny choices replaced."); } catch (Exception value) { MelonLogger.Error($"Manny patch failed: {value}"); } } }