Some mods target the Mono version of the game, which is available by opting into the Steam beta branch "alternate"
Decompiled source of SkillTree Mono v1.1.3
SkillTree.dll
Decompiled 2 weeks ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Resources; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using FishNet; using HarmonyLib; using MelonLoader; using MelonLoader.Utils; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using Newtonsoft.Json.Converters; using ScheduleOne; using ScheduleOne.Delivery; using ScheduleOne.DevUtilities; using ScheduleOne.Economy; using ScheduleOne.Effects; using ScheduleOne.Employees; using ScheduleOne.GameTime; using ScheduleOne.Growing; using ScheduleOne.Interaction; using ScheduleOne.ItemFramework; using ScheduleOne.Levelling; using ScheduleOne.Management; using ScheduleOne.Messaging; using ScheduleOne.Money; using ScheduleOne.NPCs; using ScheduleOne.NPCs.Behaviour; using ScheduleOne.ObjectScripts; using ScheduleOne.Persistence; using ScheduleOne.PlayerScripts; using ScheduleOne.PlayerScripts.Health; using ScheduleOne.Product; using ScheduleOne.Property; using ScheduleOne.Quests; using ScheduleOne.Tools; using ScheduleOne.Trash; using ScheduleOne.UI; using ScheduleOne.UI.ATM; using ScheduleOne.UI.Management; using ScheduleOne.UI.Phone; using ScheduleOne.UI.Phone.Messages; using ScheduleOne.UI.Shop; using ScheduleOne.Variables; using SkillTree; using SkillTree.Json; using SkillTree.SkillActive; using SkillTree.SkillEffect; using SkillTree.SkillPatchOperations; using SkillTree.SkillPatchSocial; using SkillTree.SkillPatchStats; using SkillTree.SkillSpecial.SkillEmployee; using SkillTree.SkillsJson; using SkillTree.UI; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: MelonInfo(typeof(Core), "SkillTree", "1.0.0", "CrazyReizor", null)] [assembly: MelonGame("TVGS", "Schedule I")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("SkillTree")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+0b5a2515904621c5ba9db0b5716e9e5fcc1419d2")] [assembly: AssemblyProduct("SkillTree")] [assembly: AssemblyTitle("SkillTree")] [assembly: NeutralResourcesLanguage("en-US")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.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 SkillTree { public class Core : MelonMod { public static Core Instance; private TimeManager timeManager; private LevelManager levelManager; private PlayerMovement playerMovement; private Player localPlayer; private PlayerCamera playerCamera; private PlayerInventory playerInventory; private Customer[] customerList; private float timer = 2f; private SkillTreeData skillData; private SkillConfig skillConfig; private SkillTreeUI skillTreeUI; private int skillPointValid = 0; private int specialSkillPointValid = 0; private bool waiting = false; private bool firstTime = false; private int lastProcessedTier = -1; private ERank lastProcessedRank = (ERank)(-1); public override void OnInitializeMelon() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown ((MelonBase)this).LoggerInstance.Msg("SkillTree Initialized."); Instance = this; Harmony val = new Harmony("com.reizor.skilltree"); val.PatchAll(); ((MelonBase)this).LoggerInstance.Msg("Harmony patches applied."); } public void Init() { ((MelonBase)this).LoggerInstance.Msg("Init()"); if ((Object)(object)timeManager == (Object)null) { timeManager = NetworkSingleton<TimeManager>.Instance; } if ((Object)(object)levelManager == (Object)null) { levelManager = NetworkSingleton<LevelManager>.Instance; } if ((Object)(object)playerMovement == (Object)null) { playerMovement = PlayerSingleton<PlayerMovement>.Instance; } if ((Object)(object)playerCamera == (Object)null) { playerCamera = PlayerSingleton<PlayerCamera>.Instance; } if ((Object)(object)playerInventory == (Object)null) { playerInventory = PlayerSingleton<PlayerInventory>.Instance; } if ((Object)(object)localPlayer == (Object)null) { localPlayer = Player.Local; } if (customerList == null) { customerList = Object.FindObjectsOfType<Customer>(); } } public override void OnUpdate() { //IL_0059: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)NetworkSingleton<TimeManager>.Instance == (Object)null) && !((Object)(object)PlayerSingleton<PlayerMovement>.Instance == (Object)null) && !((Object)(object)PlayerSingleton<PlayerCamera>.Instance == (Object)null) && (waiting || WaitTime())) { bool flag = false; if (Input.GetKeyDown(skillConfig.MenuHotkey) && waiting) { skillTreeUI.Visible = !skillTreeUI.Visible; flag = true; } ActiveSkills(); if (skillTreeUI.Visible) { playerCamera.SetDoFActive(true, 0.06f); } if (!skillTreeUI.Visible) { playerCamera.SetDoFActive(false, 0f); } if (skillTreeUI.Visible && (Input.GetKeyDown((KeyCode)27) || Input.GetKeyDown((KeyCode)9) || Input.GetMouseButtonDown(1))) { skillTreeUI.Visible = !skillTreeUI.Visible; flag = true; } if (flag) { flag = false; Cursor.lockState = (CursorLockMode)((!skillTreeUI.Visible) ? 1 : 0); Cursor.visible = (skillTreeUI.Visible ? true : false); playerMovement.CanMove = !skillTreeUI.Visible; ((Behaviour)playerCamera).enabled = !skillTreeUI.Visible; ((Behaviour)Singleton<PlayerManager>.Instance).enabled = !skillTreeUI.Visible; playerInventory.SetInventoryEnabled(!skillTreeUI.Visible); } } } public void ActiveSkills() { SkillTree.SkillActive.SkillActive.ValidSkill(); if (Input.GetKeyDown((KeyCode)282) && waiting && SkillTree.SkillActive.SkillActive.SkillEnabled.enabledTrash) { SkillTree.SkillActive.SkillActive.ClearTrash(); } if (Input.GetKeyDown((KeyCode)283) && waiting && SkillTree.SkillActive.SkillActive.SkillEnabled.enabledHeal) { SkillTree.SkillActive.SkillActive.Heal(); } if (Input.GetKeyDown((KeyCode)284) && waiting && SkillTree.SkillActive.SkillActive.SkillEnabled.enabledGetCash) { SkillTree.SkillActive.SkillActive.GetCashDealer(); } } private bool WaitTime() { if (!firstTime) { if ((Object)(object)timeManager == (Object)null || (Object)(object)levelManager == (Object)null || (Object)(object)playerMovement == (Object)null) { Init(); } skillData = SkillTreeSaveManager.LoadOrCreate(); skillConfig = SkillTreeSaveManager.LoadConfig(); skillTreeUI = new SkillTreeUI(skillData, skillConfig); } firstTime = true; timer -= Time.deltaTime; if (timer <= 0f) { ItemUnlocker.UnlockSpecificItems(); ValidSave(); AttPoints(); waiting = true; return true; } return false; } public void AttPoints(bool levelUp = false) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected I4, but got Unknown //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_02b0: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)timeManager == (Object)null || (Object)(object)levelManager == (Object)null || (Object)(object)playerMovement == (Object)null) { Init(); } int num = (int)levelManager.Rank; int num2 = levelManager.Tier - 1; if ((num == 0 && num2 == 0) || (levelUp && num2 == lastProcessedTier - 1 && levelManager.Rank == lastProcessedRank)) { return; } if (levelUp) { MelonLogger.Msg("Level Up Detected! Skill points updated."); } if (levelUp) { skillPointValid = 1; if (lastProcessedTier == 5) { skillPointValid = 2; specialSkillPointValid = 1; } Singleton<NotificationsManager>.Instance.SendNotification("Level Up", $"<color=#16F01C>+ {skillPointValid} Skill Points</color>", NetworkSingleton<MoneyManager>.Instance.LaunderingNotificationIcon, 5f, true); if (specialSkillPointValid > 0) { Singleton<NotificationsManager>.Instance.SendNotification("Special Up", $"<color=#16F01C>+ {specialSkillPointValid} Special Points</color>", NetworkSingleton<MoneyManager>.Instance.LaunderingNotificationIcon, 5f, true); } } lastProcessedTier = levelManager.Tier; lastProcessedRank = levelManager.Rank; int num3 = skillData.StatsPoints + skillData.OperationsPoints + skillData.SocialPoints + skillData.UsedSkillPoints; if (skillPointValid <= 0) { return; } int num4 = 0; int num5 = 0; int num6 = 0; int num7 = 0; for (int i = 0; i < skillPointValid; i++) { switch ((num3 + i) % 3) { case 0: num4++; break; case 1: num5++; break; case 2: num6++; break; } } for (int j = 0; j < specialSkillPointValid; j++) { num7++; } if (specialSkillPointValid > 0) { specialSkillPointValid = 0; } if (skillTreeUI == null) { skillTreeUI = new SkillTreeUI(skillData, skillConfig); } if (skillTreeUI != null) { skillTreeUI.AddPoints(num4, num5, num6, num7); } MelonLogger.Msg($"[SkillTree] Processed: Rank {levelManager.Rank} Tier {levelManager.Tier}. Gains: Stats+{num4} Operations+{num5} Social+{num6} Special+{num7}"); } private void ValidSave() { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected I4, but got Unknown if ((Object)(object)timeManager == (Object)null || (Object)(object)levelManager == (Object)null || (Object)(object)playerMovement == (Object)null) { Init(); } int num = (int)levelManager.Rank; int num2 = levelManager.Tier - 1; int num3 = num * 7 + num2; int num4 = skillData.StatsPoints + skillData.OperationsPoints + skillData.SocialPoints + skillData.SpecialPoints + skillData.UsedSkillPoints; int num5 = num; if (num3 != num4) { MelonLogger.Msg("Desync detected! Synchronizing points with saved XP in the game..."); string dynamicPath = SkillTreeSaveManager.GetDynamicPath(); if (File.Exists(dynamicPath)) { File.Delete(dynamicPath); } skillData = SkillTreeSaveManager.LoadOrCreate(); skillConfig = SkillTreeSaveManager.LoadConfig(); skillTreeUI = new SkillTreeUI(skillData, skillConfig); skillPointValid = num3 - num; specialSkillPointValid = num; } SkillSystem.ApplyAll(skillData); } public override void OnGUI() { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Invalid comparison between Unknown and I4 if (skillTreeUI != null && skillTreeUI.Visible) { skillTreeUI.EnsureSkin(); GUI.skin = skillTreeUI.Skin; if ((int)Event.current.type == 0) { GUI.FocusControl((string)null); } skillTreeUI.Draw(); } } } [HarmonyPatch(typeof(LevelManager), "IncreaseTier")] public static class LevelUp_Patch { [HarmonyPostfix] public static void Postfix() { if (Core.Instance != null) { Core.Instance.AttPoints(levelUp: true); } } } public static class ItemUnlocker { private static readonly Dictionary<string, FullRank> TargetRanks = new Dictionary<string, FullRank> { { "moisturepreservingpot", new FullRank((ERank)1, 5) }, { "ledgrowlight", new FullRank((ERank)1, 3) }, { "plasticpot", new FullRank((ERank)0, 5) }, { "halogengrowlight", new FullRank((ERank)0, 5) }, { "suspensionrack", new FullRank((ERank)0, 5) }, { "airpot", new FullRank((ERank)2, 2) }, { "cauldron", new FullRank((ERank)4, 3) }, { "brickpress", new FullRank((ERank)4, 5) }, { "dryingrack", new FullRank((ERank)0, 5) } }; public static void UnlockSpecificItems() { //IL_00a5: 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_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) Registry instance = Singleton<Registry>.Instance; if ((Object)(object)instance == (Object)null) { return; } List<ItemDefinition> allItems = instance.GetAllItems(); if (allItems == null) { return; } int num = 0; foreach (ItemDefinition item in allItems) { if ((Object)(object)item == (Object)null || string.IsNullOrEmpty(item.ID)) { continue; } string text = item.ID.ToLowerInvariant(); if (TargetRanks.TryGetValue(text, out var value)) { StorableItemDefinition val = (StorableItemDefinition)(object)((item is StorableItemDefinition) ? item : null); if ((Object)(object)val != (Object)null) { val.RequiredRank = value; val.RequiresLevelToPurchase = true; num++; MelonLogger.Msg($"[SkillTree Unlocker] Item {text} updated to Rank: {value.Rank}, Tier: {value.Tier}"); } } } MelonLogger.Msg($"[SkillTree Unlocker] Total of {num} items successfully remapped."); } } [HarmonyPatch(typeof(ShopInterface), "Awake")] public static class ShopInjectionPatch { [HarmonyPatch] public static class SpeedEffect_SkillHarmony_Patch { [HarmonyPatch(typeof(Athletic), "ApplyToPlayer")] [HarmonyPostfix] public static void Athletic_Apply_Postfix() { float movespeedBase = PlayerMovespeed.MovespeedBase; PlayerSingleton<PlayerMovement>.Instance.MoveSpeedMultiplier = movespeedBase + 0.3f; } [HarmonyPatch(typeof(Energizing), "ApplyToPlayer")] [HarmonyPostfix] public static void Energizing_Apply_Postfix() { float movespeedBase = PlayerMovespeed.MovespeedBase; PlayerSingleton<PlayerMovement>.Instance.MoveSpeedMultiplier = movespeedBase + 0.15f; } [HarmonyPatch(typeof(Athletic), "ClearFromPlayer")] [HarmonyPostfix] public static void Athletic_Clear_Postfix() { PlayerSingleton<PlayerMovement>.Instance.MoveSpeedMultiplier = PlayerMovespeed.MovespeedBase; } [HarmonyPatch(typeof(Energizing), "ClearFromPlayer")] [HarmonyPostfix] public static void Energizing_Clear_Postfix() { PlayerSingleton<PlayerMovement>.Instance.MoveSpeedMultiplier = PlayerMovespeed.MovespeedBase; } } private static List<string> itemIdsToInject = new List<string> { "moisturepreservingpot", "ledgrowlight", "plasticpot", "halogengrowlight", "suspensionrack", "airpot", "dryingrack" }; [HarmonyPostfix] public static void Postfix(ShopInterface __instance) { //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Expected O, but got Unknown if (!__instance.ShopCode.ToLower().Contains("hardware") && !__instance.ShopCode.ToLower().Contains("handy_hanks")) { return; } StorableItemDefinition[] array = Resources.FindObjectsOfTypeAll<StorableItemDefinition>(); foreach (string id in itemIdsToInject) { if (__instance.Listings.Exists((ShopListing x) => (Object)(object)x.Item != (Object)null && ((ItemDefinition)x.Item).ID.ToLower() == id)) { continue; } StorableItemDefinition val = Array.Find(array, (StorableItemDefinition x) => ((ItemDefinition)x).ID.ToLower() == id); if ((Object)(object)val != (Object)null) { ShopListing val2 = new ShopListing(); val2.Item = val; Traverse val3 = Traverse.Create((object)val2); if (id == "moisturepreservingpot") { val3.Field("OverridePrice").SetValue((object)true); val3.Field("OverriddenPrice").SetValue((object)125f); } if (id == "ledgrowlight") { val3.Field("OverridePrice").SetValue((object)true); val3.Field("OverriddenPrice").SetValue((object)200f); } if (id == "plasticpot") { val3.Field("OverridePrice").SetValue((object)true); val3.Field("OverriddenPrice").SetValue((object)50f); } if (id == "halogengrowlight") { val3.Field("OverridePrice").SetValue((object)true); val3.Field("OverriddenPrice").SetValue((object)100f); } if (id == "suspensionrack") { val3.Field("OverridePrice").SetValue((object)true); val3.Field("OverriddenPrice").SetValue((object)100f); } if (id == "airpot") { val3.Field("OverridePrice").SetValue((object)true); val3.Field("OverriddenPrice").SetValue((object)300f); } if (id == "dryingrack") { val3.Field("OverridePrice").SetValue((object)true); val3.Field("OverriddenPrice").SetValue((object)400f); } Traverse val4 = Traverse.Create((object)val2); if (val4.Field("isUnlimitedStock").FieldExists()) { val4.Field("isUnlimitedStock").SetValue((object)true); } else if (val4.Field("_isUnlimitedStock").FieldExists()) { val4.Field("_isUnlimitedStock").SetValue((object)true); } __instance.Listings.Add(val2); val2.Initialize(__instance); Traverse.Create((object)__instance).Method("CreateListingUI", new object[1] { val2 }).GetValue(); MelonLogger.Msg("[SkillTree Shop] Item successfully injected: " + ((ItemDefinition)val).Name); } } } } public static class QuickPackagers { public static bool Add; } [HarmonyPatch] public static class RouteExpanderPatch { [HarmonyPatch(typeof(PackagingStation), "Awake")] [HarmonyPostfix] public static void Postfix_Speed(PackagingStation __instance) { if (QuickPackagers.Add) { __instance.PackagerEmployeeSpeedMultiplier = 2f; } } } public static class StackCache { public static Dictionary<string, int> ItemStack = new Dictionary<string, int>(); public static bool IsLoaded = false; public static void FillCache(List<ItemDefinition> business) { if (IsLoaded) { return; } foreach (ItemDefinition item in business) { string name = ((Object)item).name; if (!ItemStack.ContainsKey(name)) { ItemStack.Add(name, item.StackLimit); } } IsLoaded = true; MelonLogger.Msg("ItemStack Memory successfully stored!"); } } } namespace SkillTree.UI { public class SkillTreeUI { private class SkillField { public string Id; public string Name; public string Description; public string Parent; public SkillCategory Category; public FieldInfo Field; public int MaxLevel; } private Rect windowRect = new Rect(300f, 150f, 600f, 450f); private SkillTreeData originalData; private SkillTreeData editData; private SkillCategory? selectedCategory = null; private SkillConfig settings; public bool isRebinding = false; private List<SkillField> skillFields = new List<SkillField>(); private bool skinReady; private bool guiInitialized = false; public bool Visible { get; set; } public GUISkin Skin { get; private set; } public SkillTreeUI(SkillTreeData data, SkillConfig sharedConfig) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) originalData = data; editData = Clone(data); settings = sharedConfig; BuildSkillMap(); } public void Draw() { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Expected O, but got Unknown //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) if (Visible) { if (!guiInitialized) { CenterWindow(); guiInitialized = true; } windowRect = GUI.Window(9001, windowRect, new WindowFunction(DrawWindow), "Skill Tree"); } } private void DrawWindow(int id) { //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Invalid comparison between Unknown and I4 //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Invalid comparison between Unknown and I4 //IL_0208: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Invalid comparison between Unknown and I4 //IL_021f: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_0247: Unknown result type (might be due to invalid IL or missing references) GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Label("Skill Tree", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(120f) }); GUILayout.FlexibleSpace(); GUILayout.Label($"Stats: {editData.StatsPoints}", Array.Empty<GUILayoutOption>()); GUILayout.Space(10f); GUILayout.Label($"Operations: {editData.OperationsPoints}", Array.Empty<GUILayoutOption>()); GUILayout.Space(10f); GUILayout.Label($"Social: {editData.SocialPoints}", Array.Empty<GUILayoutOption>()); GUILayout.Space(10f); GUILayout.Label($"Special: {editData.SpecialPoints}", Array.Empty<GUILayoutOption>()); GUILayout.EndHorizontal(); GUILayout.Space(10f); if (!selectedCategory.HasValue) { DrawCategoryButtons(); } else { DrawCategoryHeader(); DrawTreeByCategory(selectedCategory.Value); } GUILayout.FlexibleSpace(); GUILayout.BeginVertical(GUIStyle.op_Implicit("box"), Array.Empty<GUILayoutOption>()); string text = (isRebinding ? "<Color=yellow>Press any key... (ESC to cancel)</Color>" : $"Menu Hotkey: {settings.MenuHotkey}"); if (GUILayout.Button(text, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(30f) })) { isRebinding = true; MelonLogger.Msg("[SkillTree] Rebinding started. Waiting for input..."); } GUILayout.EndVertical(); if (isRebinding) { Event current = Event.current; if (current.isKey && (int)current.type == 4) { if ((int)current.keyCode == 27) { isRebinding = false; MelonLogger.Msg("[SkillTree] Rebinding cancelled by user."); } else if ((int)current.keyCode > 0) { settings.MenuHotkey = current.keyCode; SkillTreeSaveManager.SaveConfig(settings); isRebinding = false; MelonLogger.Msg($"[SkillTree] Hotkey successfully changed to: {settings.MenuHotkey}"); } current.Use(); } } GUI.DragWindow(); } private void DrawCategoryButtons() { GUILayout.Label("Choose a category", Array.Empty<GUILayoutOption>()); GUILayout.Space(10f); if (GUILayout.Button("Stats", Array.Empty<GUILayoutOption>())) { selectedCategory = SkillCategory.Stats; } if (GUILayout.Button("Operations", Array.Empty<GUILayoutOption>())) { selectedCategory = SkillCategory.Operations; } if (GUILayout.Button("Social", Array.Empty<GUILayoutOption>())) { selectedCategory = SkillCategory.Social; } if (GUILayout.Button("Special", Array.Empty<GUILayoutOption>())) { selectedCategory = SkillCategory.Special; } } private void DrawCategoryHeader() { GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); if (GUILayout.Button("< Back", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(80f) })) { selectedCategory = null; } GUILayout.Label(selectedCategory.ToString(), Array.Empty<GUILayoutOption>()); GUILayout.EndHorizontal(); GUILayout.Space(10f); } private void DrawTreeByCategory(SkillCategory category) { foreach (SkillField skillField in skillFields) { if (skillField.Parent == null && skillField.Category == category) { DrawSkillNode(skillField, 0); } } } private int GetMaxLevelOfSkill(string skillId) { return skillFields.Find((SkillField s) => s.Id == skillId)?.MaxLevel ?? 1; } private void DrawSkillNode(SkillField skill, int depth) { //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) int num = (int)skill.Field.GetValue(editData); int maxLevel = skill.MaxLevel; bool flag = true; if (skill.Parent != null) { int skillValue = GetSkillValue(skill.Parent); int maxLevelOfSkill = GetMaxLevelOfSkill(skill.Parent); flag = skillValue >= maxLevelOfSkill; } bool enabled = flag && num < maxLevel && GetPoints(skill.Category) > 0; GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Space((float)(depth * 20)); GUILayout.Label($"{skill.Name} ({num}/{maxLevel})", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(370f) }); if (num < maxLevel) { GUI.enabled = enabled; if (GUILayout.Button("+", (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(24f), GUILayout.Height(20f) })) { int num2 = num + 1; skill.Field.SetValue(editData, num2); ConsumePoint(skill.Category); SkillSystem.ApplySkill(skill.Id, editData); SkillTreeSaveManager.Save(editData); } GUI.enabled = true; } else { GUILayout.Label("✔", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(24f) }); } GUILayout.EndHorizontal(); Rect lastRect = GUILayoutUtility.GetLastRect(); DrawTooltip(skill.Description, lastRect); if (num <= 0) { return; } foreach (SkillField skillField in skillFields) { if (skillField.Parent == skill.Id) { DrawSkillNode(skillField, depth + 1); } } } private void CenterWindow() { ((Rect)(ref windowRect)).x = ((float)Screen.width - ((Rect)(ref windowRect)).width) / 2f; ((Rect)(ref windowRect)).y = ((float)Screen.height - ((Rect)(ref windowRect)).height) / 2f; } private int GetPoints(SkillCategory category) { return category switch { SkillCategory.Stats => editData.StatsPoints, SkillCategory.Operations => editData.OperationsPoints, SkillCategory.Social => editData.SocialPoints, SkillCategory.Special => editData.SpecialPoints, _ => 0, }; } private void ConsumePoint(SkillCategory category) { switch (category) { case SkillCategory.Stats: editData.StatsPoints--; break; case SkillCategory.Operations: editData.OperationsPoints--; break; case SkillCategory.Social: editData.SocialPoints--; break; case SkillCategory.Special: editData.SpecialPoints--; break; } editData.UsedSkillPoints++; } private void DrawTree(string parent, int depth) { foreach (SkillField skillField in skillFields) { if (skillField.Parent == parent) { DrawSkill(skillField, depth); } } } private void DrawSkill(SkillField skill, int depth) { //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) if (skill.Parent == null || GetSkillValue(skill.Parent) != 0) { int num = (int)skill.Field.GetValue(editData); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Space((float)(depth * 30)); GUILayout.Label($"{skill.Name}: {num}/1", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(250f) }); bool flag = skill.Parent == null || GetSkillValue(skill.Parent) == 1; bool enabled = num == 0 && GetPoints(skill.Category) > 0 && flag; GUI.enabled = enabled; if (GUILayout.Button("+", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(30f) })) { skill.Field.SetValue(editData, 1); ConsumePoint(skill.Category); SkillTreeSaveManager.Save(editData); } GUI.enabled = true; GUILayout.EndHorizontal(); Rect lastRect = GUILayoutUtility.GetLastRect(); DrawTooltip(skill.Description, lastRect); DrawTree(skill.Id, depth); } } private void DrawTooltip(string text, Rect anchorRect) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown //IL_0029: 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_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) if (((Rect)(ref anchorRect)).Contains(Event.current.mousePosition)) { GUIContent val = new GUIContent(text); Vector2 val2 = GUI.skin.label.CalcSize(val); float num = 10f; float num2 = val2.x + num; float num3 = val2.y + num; Rect val3 = default(Rect); ((Rect)(ref val3))..ctor(((Rect)(ref anchorRect)).x + 20f, ((Rect)(ref anchorRect)).y - num3 - 5f, num2, num3); GUI.Box(val3, text); } } private void BuildSkillMap() { skillFields.Clear(); FieldInfo[] fields = typeof(SkillTreeData).GetFields(BindingFlags.Instance | BindingFlags.Public); FieldInfo[] array = fields; foreach (FieldInfo fieldInfo in array) { SkillAttribute customAttribute = fieldInfo.GetCustomAttribute<SkillAttribute>(); if (customAttribute != null) { skillFields.Add(new SkillField { Id = fieldInfo.Name, Name = customAttribute.Name, Description = customAttribute.Description, Parent = customAttribute.Parent, Category = customAttribute.Category, Field = fieldInfo, MaxLevel = customAttribute.MaxLevel }); } } } private int GetSkillValue(string fieldName) { FieldInfo field = typeof(SkillTreeData).GetField(fieldName); return (int)field.GetValue(editData); } private SkillTreeData Clone(SkillTreeData source) { string text = JsonUtility.ToJson((object)source); return JsonUtility.FromJson<SkillTreeData>(text); } private void Copy(SkillTreeData from, SkillTreeData to) { FieldInfo[] fields = typeof(SkillTreeData).GetFields(BindingFlags.Instance | BindingFlags.Public); foreach (FieldInfo fieldInfo in fields) { fieldInfo.SetValue(to, fieldInfo.GetValue(from)); } } public void EnsureSkin() { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Expected O, but got Unknown //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Unknown result type (might be due to invalid IL or missing references) //IL_0247: Unknown result type (might be due to invalid IL or missing references) //IL_025d: Unknown result type (might be due to invalid IL or missing references) //IL_0264: Expected O, but got Unknown //IL_030c: Unknown result type (might be due to invalid IL or missing references) //IL_0311: Unknown result type (might be due to invalid IL or missing references) //IL_0312: Unknown result type (might be due to invalid IL or missing references) //IL_031a: Unknown result type (might be due to invalid IL or missing references) //IL_031c: Unknown result type (might be due to invalid IL or missing references) //IL_031d: Unknown result type (might be due to invalid IL or missing references) //IL_0325: Unknown result type (might be due to invalid IL or missing references) //IL_0327: Unknown result type (might be due to invalid IL or missing references) //IL_0328: Unknown result type (might be due to invalid IL or missing references) //IL_0330: Unknown result type (might be due to invalid IL or missing references) //IL_0332: Unknown result type (might be due to invalid IL or missing references) //IL_0333: Unknown result type (might be due to invalid IL or missing references) //IL_033b: Unknown result type (might be due to invalid IL or missing references) //IL_033d: Unknown result type (might be due to invalid IL or missing references) //IL_033e: Unknown result type (might be due to invalid IL or missing references) //IL_0346: Unknown result type (might be due to invalid IL or missing references) //IL_0348: Unknown result type (might be due to invalid IL or missing references) //IL_0349: Unknown result type (might be due to invalid IL or missing references) //IL_0351: Unknown result type (might be due to invalid IL or missing references) //IL_0353: Unknown result type (might be due to invalid IL or missing references) //IL_0354: Unknown result type (might be due to invalid IL or missing references) //IL_035c: Unknown result type (might be due to invalid IL or missing references) //IL_03b2: Unknown result type (might be due to invalid IL or missing references) //IL_03cd: Unknown result type (might be due to invalid IL or missing references) if (!skinReady) { Skin = Object.Instantiate<GUISkin>(GUI.skin); Texture2D background = MakeTex(2, 2, new Color(0.15f, 0.15f, 0.15f, 1f)); Texture2D background2 = MakeTex(2, 2, new Color(0.25f, 0.25f, 0.25f, 1f)); Texture2D background3 = MakeTex(2, 2, new Color(0.35f, 0.35f, 0.35f, 1f)); Texture2D background4 = MakeTex(2, 2, new Color(0.2f, 0.2f, 0.2f, 1f)); Texture2D background5 = MakeTex(2, 2, new Color(0.1f, 0.1f, 0.1f, 1f)); GUIStyle val = new GUIStyle(Skin.window); Skin.window.normal.background = background; Skin.window.focused.background = background; val.normal.background = background; val.focused.background = background; val.active.background = background; val.hover.background = background; val.onNormal.background = background; val.onFocused.background = background; val.onActive.background = background; val.onHover.background = background; GUIStyleState normal = val.normal; GUIStyleState focused = val.focused; GUIStyleState active = val.active; GUIStyleState hover = val.hover; GUIStyleState onNormal = val.onNormal; GUIStyleState onFocused = val.onFocused; GUIStyleState onActive = val.onActive; Color val2 = (val.onHover.textColor = Color.white); Color val4 = (onActive.textColor = val2); Color val6 = (onFocused.textColor = val4); Color val8 = (onNormal.textColor = val6); Color val10 = (hover.textColor = val8); Color val12 = (active.textColor = val10); Color textColor = (focused.textColor = val12); normal.textColor = textColor; Skin.window = val; Skin.label.normal.textColor = Color.white; Skin.label.focused.textColor = Color.white; GUIStyle val14 = new GUIStyle(Skin.button); val14.normal.background = background2; val14.hover.background = background3; val14.active.background = background4; val14.focused.background = background2; val14.onNormal.background = background2; val14.onHover.background = background3; val14.onActive.background = background4; val14.onFocused.background = background2; GUIStyleState normal2 = val14.normal; GUIStyleState hover2 = val14.hover; GUIStyleState active2 = val14.active; GUIStyleState focused2 = val14.focused; GUIStyleState onNormal2 = val14.onNormal; GUIStyleState onHover = val14.onHover; GUIStyleState onActive2 = val14.onActive; val2 = (val14.onFocused.textColor = Color.white); val4 = (onActive2.textColor = val2); val6 = (onHover.textColor = val4); val8 = (onNormal2.textColor = val6); val10 = (focused2.textColor = val8); val12 = (active2.textColor = val10); textColor = (hover2.textColor = val12); normal2.textColor = textColor; Skin.button = val14; Skin.box.normal.background = background5; Skin.box.focused.background = background5; Skin.box.normal.textColor = Color.white; Skin.box.focused.textColor = Color.white; Skin.box.wordWrap = true; skinReady = true; } } private Texture2D MakeTex(int w, int h, Color col) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown Color[] array = (Color[])(object)new Color[w * h]; for (int i = 0; i < array.Length; i++) { array[i] = col; } Texture2D val = new Texture2D(w, h); val.SetPixels(array); val.Apply(); return val; } public void AddPoints(int stats, int ops, int social, int special) { editData.StatsPoints += stats; editData.OperationsPoints += ops; editData.SocialPoints += social; editData.SpecialPoints += special; originalData.StatsPoints += stats; originalData.OperationsPoints += ops; originalData.SocialPoints += social; originalData.SpecialPoints += special; SkillTreeSaveManager.Save(editData); } } } namespace SkillTree.SkillsJson { [Serializable] public class SkillConfig { [JsonConverter(typeof(StringEnumConverter))] public KeyCode MenuHotkey = (KeyCode)99; } } namespace SkillTree.Json { public enum SkillCategory { Stats, Operations, Social, Special } [AttributeUsage(AttributeTargets.Field)] public class SkillAttribute : Attribute { public string Name; public string Description; public string Parent; public SkillCategory Category; public int MaxLevel; public SkillAttribute(string name, string description, SkillCategory category, string parent = null, int maxLevel = 2) { Name = name; Description = description; Category = category; Parent = parent; MaxLevel = maxLevel; } } [Serializable] public class SkillTreeData { public int StatsPoints = 0; public int OperationsPoints = 0; public int SocialPoints = 0; public int SpecialPoints = 0; public int UsedSkillPoints = 0; [Skill("More Health", "Increase Max Health by +20", SkillCategory.Stats, null, 1)] public int Stats = 0; [Skill("More Movespeed", "Increase 10% by Movespeed", SkillCategory.Stats, "Stats", 3)] public int MoreMovespeed = 0; [Skill("More XP", "Increase XP Gain by 5%", SkillCategory.Stats, "Stats", 2)] public int MoreXP = 0; [Skill("More Item Stack (x2)", "Increase Item Stack (x2)", SkillCategory.Stats, "Stats", 1)] public int MoreStackItem = 0; [Skill("More XP Per Sell When Earn Money", "Earn 5% bonus XP based on item value when selling drugs", SkillCategory.Stats, "MoreXP", 1)] public int MoreXPWhenEarnMoney = 0; [Skill("Better Delivery", "Make Deliveries Faster (6H -> 2H)", SkillCategory.Stats, "Stats", 1)] public int BetterDelivery = 0; [Skill("Allow Sleep with Athletic or Energizing", "Allow sleeping while Athletic or Energizing effects are active", SkillCategory.Stats, "Stats", 1)] public int AllowSleepAthEne = 0; [Skill("Counteroffer Perception", "Allows you to see the chance of a customer making a counteroffer", SkillCategory.Stats, "Stats", 1)] public int AllowSeeCounteroffChance = 0; [Skill("Allow Use Bed to Skip the Current Schedule", "Skip Schedule Only Affect Plants (Plants Grow 33% of the time)", SkillCategory.Stats, "AllowSleepAthEne", 1)] public int SkipSchedule = 0; [Skill("More XP 2", "Increase XP Gain by an additional 5%", SkillCategory.Stats, "MoreXP", 4)] public int MoreXP2 = 0; [Skill("Better Grow Tent Quality", "Improve Grow Tent Quality (Trash -> Low)", SkillCategory.Operations, null, 1)] public int Operations = 0; [Skill("Increase Growth Speed", "Increase Growth Speed by 2.5%", SkillCategory.Operations, "Operations", 2)] public int GrowthSpeed = 0; [Skill("More Yield", "Increase Yield by 1 (Excludes Mushrooms/Grow Tents)", SkillCategory.Operations, "Operations", 1)] public int MoreYield = 0; [Skill("Advanced Pot Techniques", "+15% Quality. [Lvl 1] Plastic/Moisture Pots gain +1 Tier. [Max Lvl] Air Pot/Shroom gain +1 Tier.", SkillCategory.Operations, "Operations", 2)] public int MoreQuality = 0; [Skill("More Quality Meth/Coca", "Upgrade Meth/Coca Quality Tier When Shatter", SkillCategory.Operations, "Operations", 1)] public int MoreQualityMethCoca = 0; [Skill("Increase Growth Speed 2°", "Increase Growth Speed by 2.5%", SkillCategory.Operations, "MoreQuality", 2)] public int GrowthSpeed2 = 0; [Skill("Chemist Station Quick", "Increase the speed of ALL Chemistry Station (x2 or a little more)", SkillCategory.Operations, "Operations", 1)] public int ChemistStationQuick = 0; [Skill("More Mix and Drying Rack Output", "Double Mix and Drying Rack Output", SkillCategory.Operations, "Operations", 1)] public int MoreMixAndDryingRackOutput = 0; [Skill("AbsorbentSoil", "Preserve soil additives", SkillCategory.Operations, "Operations", 1)] public int AbsorbentSoil = 0; [Skill("More Cauldron Output", "Double Cauldron Output", SkillCategory.Operations, "ChemistStationQuick", 1)] public int MoreCauldronOutput = 0; [Skill("More sample chance", "Increase Sample Chance by 5%", SkillCategory.Social, null, 2)] public int Social = 0; [Skill("Civilian More Money per week", "Increase Citizens' weekly money by 10%", SkillCategory.Social, "Social", 2)] public int CityEvolving = 0; [Skill("More ATM Limit", "Increase ATM Deposit Limit by +2000", SkillCategory.Social, "Social", 2)] public int MoreATMLimit = 0; [Skill("Better Business", "Increase Max Money Laundering Capacity by 20%", SkillCategory.Social, "Social", 3)] public int BusinessEvolving = 0; [Skill("Dealer More Customer", "Increase Dealer Customers (+2)", SkillCategory.Social, "Social", 1)] public int DealerMoreCustomer = 0; [Skill("Less Dealer Cut", "Decrease Dealer's Cut by 5%", SkillCategory.Social, "DealerMoreCustomer", 2)] public int DealerCutLess = 0; [Skill("Better Supplier", "Increase Debt and Item Limits by 50%", SkillCategory.Social, "Social", 2)] public int BetterSupplier = 0; [Skill("Dealer Speed Up", "Increase Movespeed Speed of Dealers (2x)", SkillCategory.Social, "DealerMoreCustomer", 1)] public int DealerSpeedUp = 0; [Skill("Gain Ability To Destroy The Trash (F1)", "Allow you to destroy trash", SkillCategory.Special, null, 1)] public int Special = 0; [Skill("Gain Ability To Heal Yourself (F2)", "Allow you to heal you life", SkillCategory.Special, "Special", 1)] public int Heal = 0; [Skill("Gain Ability To Get Dealers Cash (F3)", "Allow you to get dealers cash", SkillCategory.Special, "Special", 1)] public int GetCashDealer = 0; [Skill("Better Botanists", "All action the botanists is 2 times faster", SkillCategory.Special, "Special", 1)] public int BetterBotanists = 0; [Skill("Employees Work 24h", "Employees don't stop at 4 AM", SkillCategory.Special, "Special", 1)] public int Employees24h = 0; [Skill("Make Employees Move Faster", "Employees move 3 times faster", SkillCategory.Special, "BetterBotanists", 1)] public int EmployeeMovespeed = 0; [Skill("Increase +2 Employees Max Station (Botanist/Chemist)", "Increase +2 The Base MaxStation Allowance For Employees", SkillCategory.Special, "BetterBotanists", 2)] public int EmployeeMaxStation = 0; } public static class SkillTreeSaveManager { private static string ConfigPath => Path.Combine(MelonEnvironment.UserDataDirectory, "SkillTree_Config.json"); public static string GetDynamicPath() { string currentSaveID = GetCurrentSaveID(); return Path.Combine(MelonEnvironment.UserDataDirectory, "SkillTree_" + currentSaveID + ".json"); } public static SkillTreeData LoadOrCreate() { string dynamicPath = GetDynamicPath(); if (!File.Exists(dynamicPath)) { MelonLogger.Msg("[SkillTree] Novo save detectado ou arquivo ausente: " + dynamicPath); CustomerCache.IsLoaded = false; CustomerCache.OriginalMinSpend.Clear(); CustomerCache.OriginalMaxSpend.Clear(); SkillTreeData skillTreeData = CreateDefault(); Save(skillTreeData); return skillTreeData; } string text = File.ReadAllText(dynamicPath); return JsonUtility.FromJson<SkillTreeData>(text); } public static void Save(SkillTreeData data) { string dynamicPath = GetDynamicPath(); string contents = JsonUtility.ToJson((object)data, true); File.WriteAllText(dynamicPath, contents); } private static SkillTreeData CreateDefault() { return new SkillTreeData(); } public static string GetCurrentSaveID() { string loadedGameFolderPath = Singleton<LoadManager>.Instance.LoadedGameFolderPath; if (string.IsNullOrEmpty(loadedGameFolderPath)) { return "DefaultPlayer"; } return Path.GetFileName(loadedGameFolderPath.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar)); } public static SkillConfig LoadConfig() { if (!File.Exists(ConfigPath)) { SkillConfig skillConfig = new SkillConfig(); SaveConfig(skillConfig); return skillConfig; } try { string text = File.ReadAllText(ConfigPath); return JsonConvert.DeserializeObject<SkillConfig>(text); } catch { return new SkillConfig(); } } public static void SaveConfig(SkillConfig config) { string contents = JsonConvert.SerializeObject((object)config, (Formatting)1); File.WriteAllText(ConfigPath, contents); } } } namespace SkillTree.SkillPatchStats { public static class PlayerMovespeed { public static float MovespeedBase = 1f; } public static class PlayerXpMoney { public static bool XpMoney; } public static class PlayerHealthConfig { public static float MaxHealth = 100f; } [HarmonyPatch(typeof(PlayerHealth))] public class PatchPlayerHealth { [HarmonyPatch("SetHealth")] [HarmonyPrefix] public static bool Prefix_SetHealth(PlayerHealth __instance, float health) { float value = Mathf.Clamp(health, 0f, PlayerHealthConfig.MaxHealth); SetInternalHealth(__instance, value); return false; } [HarmonyPatch("RecoverHealth")] [HarmonyPrefix] public static bool Prefix_RecoverHealth(PlayerHealth __instance, float recovery) { if (__instance.CurrentHealth <= 0f) { return false; } float value = Mathf.Clamp(__instance.CurrentHealth + recovery, 0f, PlayerHealthConfig.MaxHealth); SetInternalHealth(__instance, value); return false; } [HarmonyPatch("RpcLogic___TakeDamage_3505310624")] [HarmonyPrefix] public static bool Prefix_TakeDamage(PlayerHealth __instance, float damage) { if (!__instance.IsAlive || !__instance.CanTakeDamage) { return false; } float num = Mathf.Clamp(__instance.CurrentHealth - damage, 0f, PlayerHealthConfig.MaxHealth); SetInternalHealth(__instance, num); AccessTools.Field(typeof(PlayerHealth), "TimeSinceLastDamage").SetValue(__instance, 0f); if (num <= 0f) { __instance.SendDie(); } return false; } private static void SetInternalHealth(PlayerHealth instance, float value) { AccessTools.Field(typeof(PlayerHealth), "<CurrentHealth>k__BackingField")?.SetValue(instance, value); instance.onHealthChanged?.Invoke(value); } } public static class PlayerXPConfig { public static float XpBase = 100f; public static float XpBase2 = 100f; } [HarmonyPatch(typeof(LevelManager), "AddXP")] public class PatchLevelManager { private static bool _jaProcessado; [HarmonyPrefix] public static void Prefix(LevelManager __instance, ref int xp) { if (!_jaProcessado) { float num = PlayerXPConfig.XpBase / 100f; if (num != 1f) { _jaProcessado = true; int num2 = xp; xp = Mathf.CeilToInt((float)xp * num); MelonLogger.Msg($"[XP] Apply: {num2} -> {xp} (Base: {PlayerXPConfig.XpBase}%)"); MelonLogger.Msg("Total XP Now: " + (__instance.TotalXP + xp)); } } } [HarmonyPostfix] public static void Postfix() { _jaProcessado = false; } } [HarmonyPatch(typeof(Contract), "SubmitPayment")] public class PatchContractPayment { private static bool _jaProcessado; [HarmonyPrefix] public static void Prefix(Contract __instance, float bonusTotal) { if (_jaProcessado || !PlayerXpMoney.XpMoney) { return; } float num = __instance.Payment + bonusTotal; if (!(num > 0f)) { return; } int num2 = Mathf.RoundToInt(num * 0.05f); if (num2 > 0) { LevelManager instance = NetworkSingleton<LevelManager>.Instance; if ((Object)(object)instance != (Object)null) { MelonLogger.Msg($"[Contract] Payment of ${num} converted into {num2} base XP."); instance.AddXP(num2); _jaProcessado = true; } } } [HarmonyPostfix] public static void Postfix() { _jaProcessado = false; } } public static class SkipSchedule { public static bool Add; } public static class AllowSleepAthEne { public static bool Add; } public static class ScheduleLogic { [HarmonyPatch(typeof(Bed), "CanSleep")] public static class Bed_AlwaysAllow { [HarmonyPrefix] public static bool Prefix(ref bool __result) { float num = NetworkSingleton<TimeManager>.Instance.CurrentTime; if (!AllowSleepAthEne.Add) { return true; } if (num > 700f && num < 1800f && !SkipSchedule.Add) { return true; } __result = true; return false; } } [HarmonyPatch(typeof(Bed), "Hovered")] public static class Bed_Hovered_Patch { [HarmonyPrefix] public static bool Prefix(Bed __instance, ref InteractableObject ___intObj) { if (!SkipSchedule.Add) { return true; } if (Singleton<ManagementClipboard>.Instance.IsEquipped || (Object)(object)__instance.AssignedEmployee != (Object)null) { return true; } float num = NetworkSingleton<TimeManager>.Instance.CurrentTime; if (num >= 0f && num < 700f) { return true; } if (!CanUseBedSkill() && num <= 1800f) { ___intObj.SetMessage("You've already rested today! Use it only tomorrow."); } else { if (!CanUseBedSkill() || !(num < 2357f)) { return true; } string timeRemaining = GetTimeRemaining(num); ___intObj.SetMessage("Next Shift in: " + timeRemaining); } return false; } } [HarmonyPatch(typeof(Bed), "Interacted")] public static class Bed_Interacted_Patch { [HarmonyPrefix] public static bool Prefix() { //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Expected I4, but got Unknown if (!SkipSchedule.Add) { return true; } if (!CanUseBedSkill()) { MelonLogger.Msg("[BedSkill] You've already rested today! Use it only tomorrow."); return true; } float num = NetworkSingleton<TimeManager>.Instance.CurrentTime; if (num >= 700f) { int nextSchedule = GetNextSchedule(); int num2 = CalculateMinutesBetween(num, nextSchedule) / 3; if (num2 > 0) { GrowContainer[] array = Object.FindObjectsOfType<GrowContainer>(); foreach (GrowContainer obj in array) { AccessTools.Method(typeof(GrowContainer), "DrainMoisture", (Type[])null, (Type[])null)?.Invoke(obj, new object[1] { num2 * 3 }); } Plant[] array2 = Object.FindObjectsOfType<Plant>(); foreach (Plant val in array2) { val.MinPass(num2); } } lastDayUsed = (int)NetworkSingleton<TimeManager>.Instance.CurrentDay; NetworkSingleton<TimeManager>.Instance.SetTime(nextSchedule, false); MelonLogger.Msg($"[BedSkill] Interação detectada. Próximo schedule definido para: {nextSchedule}"); return false; } return true; } } private static int lastDayUsed = -1; public static bool CanUseBedSkill() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected I4, but got Unknown int num = (int)NetworkSingleton<TimeManager>.Instance.CurrentDay; return num != lastDayUsed; } public static string GetTimeRemaining(float currentTime) { int num = GetNextSchedule(); if (num == 0) { num = 2400; } int num2 = (int)currentTime / 100 * 60 + (int)currentTime % 100; int num3 = num / 100 * 60 + num % 100; int num4 = num3 - num2; int num5 = num4 / 60; int num6 = num4 % 60; return $"{num5:00}h {num6:00}m"; } public static int GetNextSchedule() { float num = NetworkSingleton<TimeManager>.Instance.CurrentTime; if (num >= 700f && num < 1200f) { return 1200; } if (num >= 1203f && num < 1800f) { return 1800; } if (num >= 1803f && num < 2357f) { return 2357; } return (int)num; } private static int CalculateMinutesBetween(float start, float end) { if (end == 0f) { end = 2400f; } int num = (int)start / 100; int num2 = (int)start % 100; int num3 = (int)end / 100; int num4 = (int)end % 100; int num5 = num * 60 + num2; int num6 = num3 * 60 + num4; return num6 - num5; } } public static class CounterofferHelper { [HarmonyPatch(typeof(CounterofferInterface), "Open")] public static class Counteroffer_Open_Patch { [HarmonyPostfix] public static void Postfix(CounterofferInterface __instance) { if (Counteroffer) { CreateSuccessLabel(__instance); UpdateSuccessLabel(__instance); } } } [HarmonyPatch(typeof(CounterofferInterface), "ChangeQuantity")] public static class Counteroffer_ChangeQuantity_Patch { [HarmonyPostfix] public static void Postfix(CounterofferInterface __instance) { if (Counteroffer) { UpdateSuccessLabel(__instance); } } } [HarmonyPatch(typeof(CounterofferInterface), "ChangePrice")] public static class Counteroffer_ChangePrice_Patch { [HarmonyPostfix] public static void Postfix(CounterofferInterface __instance) { if (Counteroffer) { UpdateSuccessLabel(__instance); } } } public static bool Counteroffer; public static Text SuccessLabel; public static float CalculateSuccessChance(CounterofferInterface instance) { //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) MSGConversation value = Traverse.Create((object)instance).Field<MSGConversation>("conversation").Value; float value2 = Traverse.Create((object)instance).Field<float>("price").Value; ProductDefinition value3 = Traverse.Create((object)instance).Field<ProductDefinition>("selectedProduct").Value; int value4 = Traverse.Create((object)instance).Field<int>("quantity").Value; Customer component = ((Component)value.sender).GetComponent<Customer>(); CustomerData customerData = component.CustomerData; NPC nPC = component.NPC; float adjustedWeeklySpend = customerData.GetAdjustedWeeklySpend(nPC.RelationData.RelationDelta / 5f); List<EDay> orderDays = customerData.GetOrderDays(component.CurrentAddiction, nPC.RelationData.RelationDelta / 5f); float num = adjustedWeeklySpend / (float)orderDays.Count; if (value2 >= num * 3f) { return 0f; } float valueProposition = Customer.GetValueProposition(Registry.GetItem<ProductDefinition>(component.OfferedContractInfo.Products.entries[0].ProductID), component.OfferedContractInfo.Payment / (float)component.OfferedContractInfo.Products.entries[0].Quantity); float productEnjoyment = component.GetProductEnjoyment(value3, StandardsMethod.GetCorrespondingQuality(customerData.Standards)); float num2 = Mathf.InverseLerp(-1f, 1f, productEnjoyment); float valueProposition2 = Customer.GetValueProposition(value3, value2 / (float)value4); float num3 = Mathf.Pow((float)value4 / (float)component.OfferedContractInfo.Products.entries[0].Quantity, 0.6f); float num4 = Mathf.Lerp(0f, 2f, num3 * 0.5f); float num5 = Mathf.Lerp(1f, 0f, Mathf.Abs(num4 - 1f)); if (valueProposition2 * num5 > valueProposition) { return 1f; } if (valueProposition2 < 0.12f) { return 0f; } float num6 = productEnjoyment * valueProposition; float num7 = num2 * num5 * valueProposition2; if (num7 > num6) { return 1f; } float num8 = num6 - num7; float num9 = Mathf.Lerp(0f, 1f, num8 / 0.2f); float num10 = Mathf.Max(component.CurrentAddiction, nPC.RelationData.NormalizedRelationDelta); float num11 = Mathf.Lerp(0f, 0.2f, num10); if (num9 <= num11) { return 1f; } if (num9 - num11 >= 0.9f) { return 0f; } float num12 = (0.9f + num11 - num9) / 0.9f; return Mathf.Clamp(num12, 0f, 1f); } public static void CreateSuccessLabel(CounterofferInterface instance) { //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)SuccessLabel != (Object)null)) { Text value = Traverse.Create((object)instance).Field<Text>("FairPriceLabel").Value; Transform parent = ((Component)value).transform.parent; GameObject val = Object.Instantiate<GameObject>(((Component)value).gameObject, parent); ((Object)val).name = "SuccessChanceLabel"; SuccessLabel = val.GetComponent<Text>(); SuccessLabel.font = value.font; SuccessLabel.fontSize = value.fontSize; SuccessLabel.fontStyle = (FontStyle)1; SuccessLabel.alignment = value.alignment; ((Graphic)SuccessLabel).color = Color.black; SuccessLabel.supportRichText = true; ((Behaviour)SuccessLabel).enabled = true; SuccessLabel.text = "Success chance: --%"; LayoutElement val2 = val.AddComponent<LayoutElement>(); val2.ignoreLayout = true; RectTransform rectTransform = ((Graphic)value).rectTransform; RectTransform rectTransform2 = ((Graphic)SuccessLabel).rectTransform; rectTransform2.anchorMin = rectTransform.anchorMin; rectTransform2.anchorMax = rectTransform.anchorMax; rectTransform2.pivot = rectTransform.pivot; rectTransform2.sizeDelta = rectTransform.sizeDelta; rectTransform2.anchoredPosition = rectTransform.anchoredPosition + new Vector2(0f, -23f); val.transform.SetAsLastSibling(); } } public static void UpdateSuccessLabel(CounterofferInterface instance) { if (!((Object)(object)SuccessLabel == (Object)null)) { float num = CalculateSuccessChance(instance); string arg = ((num >= 0.75f) ? "#4CAF50" : ((num >= 0.4f) ? "#FFC107" : "#F44336")); SuccessLabel.text = $"<color={arg}>Success chance: {num * 100f:0}%</color>"; } } } public static class BetterDelivery { public static bool Add; } [HarmonyPatch(typeof(DeliveryManager), "SendDelivery")] public static class DeliveryTime_Patch { [HarmonyPrefix] public static void Prefix(ref DeliveryInstance delivery) { if (BetterDelivery.Add && delivery != null && delivery.TimeUntilArrival > 120) { int timeUntilArrival = delivery.TimeUntilArrival; float num = Mathf.InverseLerp(60f, 360f, (float)timeUntilArrival); int num2 = Mathf.RoundToInt(Mathf.Lerp(30f, 120f, num)); delivery.TimeUntilArrival = num2; MelonLogger.Msg($"[DeliverySkill] Delivery scaling adjusted. Original: {timeUntilArrival}m | New: {num2}m"); } } } } namespace SkillTree.SkillPatchSocial { public static class CustomerCache { public static Dictionary<string, float> OriginalMinSpend = new Dictionary<string, float>(); public static Dictionary<string, float> OriginalMaxSpend = new Dictionary<string, float>(); public static bool IsLoaded = false; public static void FillCache(List<Customer> customers) { if (IsLoaded) { return; } foreach (Customer customer in customers) { string name = ((Object)customer.CustomerData).name; if (!OriginalMinSpend.ContainsKey(name)) { OriginalMinSpend.Add(name, customer.CustomerData.MinWeeklySpend); OriginalMaxSpend.Add(name, customer.CustomerData.MaxWeeklySpend); } } IsLoaded = true; MelonLogger.Msg("Customer spending history successfully stored!"); } } public static class BusinessCache { public static Dictionary<string, float> LaunderCapacity = new Dictionary<string, float>(); public static bool IsLoaded = false; public static void FillCache(List<Business> business) { if (IsLoaded) { return; } foreach (Business item in business) { string propertyName = ((Property)item).PropertyName; if (!LaunderCapacity.ContainsKey(propertyName)) { LaunderCapacity.Add(propertyName, item.LaunderCapacity); } } IsLoaded = true; MelonLogger.Msg("Business Laundering Memory successfully stored!"); } } public static class ATMConfig { public static float MaxWeeklyLimit = 10000f; } [HarmonyPatch(typeof(ATMInterface))] public static class ATMInterface_UnlockLimit_Patch { [HarmonyPatch(/*Could not decode attribute arguments.*/)] [HarmonyPrefix] public static bool PrefixRemaining(ref float __result) { __result = Mathf.Max(0f, ATMConfig.MaxWeeklyLimit - ATM.WeeklyDepositSum); return false; } [HarmonyPatch("Update")] [HarmonyPostfix] public static void PostfixUpdate(ATMInterface __instance, Button ___menu_DepositButton, Text ___depositLimitText) { //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) if (__instance.isOpen) { bool flag = ATM.WeeklyDepositSum >= ATMConfig.MaxWeeklyLimit; if ((Object)(object)___menu_DepositButton != (Object)null) { ((Selectable)___menu_DepositButton).interactable = !flag; } if ((Object)(object)___depositLimitText != (Object)null) { ___depositLimitText.text = MoneyManager.FormatAmount(ATM.WeeklyDepositSum, false, false) + " / " + MoneyManager.FormatAmount(ATMConfig.MaxWeeklyLimit, false, false); ((Graphic)___depositLimitText).color = (flag ? Color32.op_Implicit(new Color32(byte.MaxValue, (byte)75, (byte)75, byte.MaxValue)) : Color.white); } } } [HarmonyPatch("UpdateAvailableAmounts")] [HarmonyPrefix] public static bool PrefixUpdateAmounts(ATMInterface __instance, bool ___depositing, List<Button> ___amountButtons) { if (___depositing) { float cashBalance = NetworkSingleton<MoneyManager>.Instance.cashBalance; float num = Mathf.Max(0f, ATMConfig.MaxWeeklyLimit - ATM.WeeklyDepositSum); for (int i = 0; i < ATMInterface.amounts.Length && i < ___amountButtons.Count; i++) { if (i == ___amountButtons.Count - 1) { ((Selectable)___amountButtons[i]).interactable = cashBalance > 0f && num > 0f; continue; } float num2 = ATMInterface.amounts[i]; ((Selectable)___amountButtons[i]).interactable = cashBalance >= num2 && ATM.WeeklyDepositSum + num2 <= ATMConfig.MaxWeeklyLimit; } return false; } return true; } } public static class CustomerSample { public static float AddSampleChance; } [HarmonyPatch(typeof(Customer), "GetSampleSuccess")] public class PatchSampleSuccessUI { private static int _depth; [HarmonyPrefix] public static void Prefix() { _depth++; } [HarmonyPostfix] public static void Postfix(ref float __result, float __state) { if (_depth == 1) { if (CustomerSample.AddSampleChance <= 0f) { return; } float num = __result; __result = Mathf.Clamp(__result + CustomerSample.AddSampleChance, 0f, 1f); MelonLogger.Msg($"[Skill] Chance de Sample alterada de: {num:P0} para {__result:P0}"); } _depth--; } } public static class DealerUpCustomer { public static int MaxCustomer = 8; } [HarmonyPatch(typeof(DealerManagementApp))] public class DealerManagementPatch { private static int GetDynamicLimit() { return DealerUpCustomer.MaxCustomer; } [HarmonyPatch("Awake")] [HarmonyPostfix] public static void Awake_Postfix(DealerManagementApp __instance) { CheckAndExpandUI(__instance); if ((Object)(object)__instance.AssignCustomerButton != (Object)null) { ((Component)__instance.AssignCustomerButton).transform.SetSiblingIndex(1); } if ((Object)(object)__instance.CustomerTitleLabel != (Object)null) { ((Component)__instance.CustomerTitleLabel).transform.SetAsFirstSibling(); } LayoutRebuilder.ForceRebuildLayoutImmediate(__instance.Content); } [HarmonyPatch("SetDisplayedDealer")] [HarmonyPostfix] public static void SetDisplayedDealer_Postfix(DealerManagementApp __instance, Dealer dealer) { //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Expected O, but got Unknown CheckAndExpandUI(__instance); int dynamicLimit = GetDynamicLimit(); if ((Object)(object)__instance.CustomerTitleLabel != (Object)null) { __instance.CustomerTitleLabel.text = $"Assigned Customers ({dealer.AssignedCustomers.Count}/{dynamicLimit})"; } if ((Object)(object)__instance.AssignCustomerButton != (Object)null) { ((Component)__instance.AssignCustomerButton).gameObject.SetActive(dealer.AssignedCustomers.Count < dynamicLimit); ((Component)__instance.AssignCustomerButton).transform.SetSiblingIndex(1); } for (int i = 0; i < __instance.CustomerEntries.Length; i++) { if (dealer.AssignedCustomers.Count > i) { Customer customer = dealer.AssignedCustomers[i]; RectTransform val = __instance.CustomerEntries[i]; ((Component)((Transform)val).Find("Mugshot")).GetComponent<Image>().sprite = customer.NPC.MugshotSprite; ((Component)((Transform)val).Find("Name")).GetComponent<Text>().text = customer.NPC.fullName; Button component = ((Component)((Transform)val).Find("Remove")).GetComponent<Button>(); ((UnityEventBase)component.onClick).RemoveAllListeners(); ((UnityEvent)component.onClick).AddListener((UnityAction)delegate { dealer.SendRemoveCustomer(customer.NPC.ID); __instance.SetDisplayedDealer(dealer); }); ((Component)val).gameObject.SetActive(true); } else { ((Component)__instance.CustomerEntries[i]).gameObject.SetActive(false); } } } private static void CheckAndExpandUI(DealerManagementApp __instance) { int dynamicLimit = GetDynamicLimit(); if (__instance.CustomerEntries.Length < dynamicLimit) { List<RectTransform> list = __instance.CustomerEntries.ToList(); RectTransform val = list[0]; Transform parent = ((Transform)val).parent; while (list.Count < dynamicLimit) { RectTransform val2 = Object.Instantiate<RectTransform>(val, parent); ((Object)val2).name = "CustomerEntry_Mod_Slot_" + list.Count; list.Add(val2); } __instance.CustomerEntries = list.ToArray(); LayoutRebuilder.ForceRebuildLayoutImmediate(__instance.Content); } } } public static class SupplierUp { public static float SupplierInc = 1f; public static int SupplierLimit = 10; } [HarmonyPatch(typeof(PhoneShopInterface))] public class PhoneShopGlobalPatch { [HarmonyPatch("CanConfirmOrder")] [HarmonyPostfix] public static void CanConfirmOrder_Postfix(PhoneShopInterface __instance, ref bool __result) { if (__result) { return; } FieldInfo field = typeof(PhoneShopInterface).GetField("_cart", BindingFlags.Instance | BindingFlags.NonPublic); FieldInfo field2 = typeof(PhoneShopInterface).GetField("orderLimit", BindingFlags.Instance | BindingFlags.NonPublic); if (!(field != null) || !(field2 != null)) { return; } IEnumerable<CartEntry> enumerable = (IEnumerable<CartEntry>)field.GetValue(__instance); float num = (float)field2.GetValue(__instance); int num2 = 0; float num3 = 0f; foreach (CartEntry item in enumerable) { num2 += item.Quantity; num3 += item.Listing.Price * (float)item.Quantity; } if (num3 > 0f && num3 <= num && num2 <= SupplierUp.SupplierLimit) { __result = true; } } } [HarmonyPatch(typeof(Supplier), "GetDeadDropLimit")] public static class Supplier_GetDeadDropLimit_Patch { [HarmonyPrefix] public static bool Prefix(Supplier __instance, ref float __result) { if (SupplierUp.SupplierLimit == 10) { return true; } __result = __instance.MaxOrderLimit * SupplierUp.SupplierInc; return false; } } public static class BetterBusiness { public static float Add; } [HarmonyPatch] public static class BusinessLaunderingPatch { [HarmonyPatch(typeof(Business), "MinsPass")] [HarmonyPrefix] public static bool Prefix_MinsPass(Business __instance, int mins) { string text = Traverse.Create((object)__instance).Field("propertyName").GetValue<string>() ?? "Business"; for (int i = 0; i < __instance.LaunderingOperations.Count; i++) { LaunderingOperation val = __instance.LaunderingOperations[i]; int minutesSinceStarted = val.minutesSinceStarted; val.minutesSinceStarted += mins; if (val.minutesSinceStarted < val.completionTime_Minutes) { int num = minutesSinceStarted / 240; int num2 = val.minutesSinceStarted / 240; if (num2 > num) { float num3 = Mathf.Ceil(val.amount / 6f); if (InstanceFinder.IsServer) { NetworkSingleton<MoneyManager>.Instance.CreateOnlineTransaction("Partial Laundering (" + text + ")", num3, 1f, string.Empty); MelonLogger.Msg($"[LaunderingMod] Partial payout of {num3} processed for {text}"); } Singleton<NotificationsManager>.Instance.SendNotification(text, "<color=#16F01C>" + MoneyManager.FormatAmount(num3, false, false) + "</color> Laundered (Partial)", NetworkSingleton<MoneyManager>.Instance.LaunderingNotificationIcon, 5f, true); } } if (val.minutesSinceStarted >= val.completionTime_Minutes) { val.amount /= 6f; Traverse.Create((object)__instance).Method("CompleteOperation", new object[1] { val }).GetValue(); MelonLogger.Msg("[LaunderingMod] Operation completed for " + text + ". Final installment paid."); i--; } } return false; } } } namespace SkillTree.SkillPatchOperations { public static class AbsorbentSoil { public static bool Add; } [HarmonyPatch(typeof(Pot), "OnPlantFullyHarvested")] public static class Pot_OnPlantFullyHarvested_Patch { [CompilerGenerated] private sealed class <CleanUp>d__2 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public int id; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <CleanUp>d__2(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(2f); <>1__state = 1; return true; case 1: <>1__state = -1; processedIds.Remove(id); return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static readonly HashSet<int> processedIds = new HashSet<int>(); private static bool Prefix(Pot __instance) { if (!AbsorbentSoil.Add) { return true; } try { Traverse val = Traverse.Create((object)__instance); Traverse obj = val.Property("Plant", (object[])null); object obj2 = ((obj != null) ? obj.GetValue() : null); if (obj2 == null) { MelonLogger.Msg("OnPlantFullyHarvested skipped: Plant is null"); return false; } if (InstanceFinder.IsServer) { float value = NetworkSingleton<VariableDatabase>.Instance.GetValue<float>("HarvestedPlantCount"); NetworkSingleton<VariableDatabase>.Instance.SetVariableValue("HarvestedPlantCount", (value + 1f).ToString(), true); NetworkSingleton<LevelManager>.Instance.AddXP(5); MelonLogger.Msg("Server harvest processed"); } Traverse obj3 = val.Property("Plant", (object[])null); if (obj3 != null) { obj3.SetValue((object)null); } int instanceID = ((Object)__instance).GetInstanceID(); if (processedIds.Contains(instanceID)) { return false; } int num = val.Field("_remainingSoilUses").GetValue<int>() - 1; ((GrowContainer)__instance).SetRemainingSoilUses(num); __instance.SetSoilState((ESoilState)0); processedIds.Add(instanceID); if (num <= 0) { MelonLogger.Msg("Soil depleted: clearing soil and additives"); Traverse obj4 = val.Method("ClearAdditives", Array.Empty<object>()); if (obj4 != null) { obj4.GetValue(); } Traverse obj5 = val.Method("ClearSoil", Array.Empty<object>()); if (obj5 != null) { obj5.GetValue(); } } else { MelonLogger.Msg("Soil still usable: additives preserved"); } MelonCoroutines.Start(CleanUp(instanceID)); return false; } catch (Exception arg) { MelonLogger.Error($"OnPlantFullyHarvested patch failed: {arg}"); return true; } } [IteratorStateMachine(typeof(<CleanUp>d__2))] private static IEnumerator CleanUp(int id) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <CleanUp>d__2(0) { id = id }; } } public static class CauldronOutputAdd { public static int Add = 10; } [HarmonyPatch(typeof(Cauldron), "RpcLogic___FinishCookOperation_2166136261")] public static class Cauldron_Finish_Patch { [HarmonyPrefix] public static void Prefix(Cauldron __instance) { } } [HarmonyPatch(typeof(QualityItemDefinition), "GetDefaultInstance", new Type[] { typeof(int) })] public static class Cauldron_Double_Output_Patch { [HarmonyPrefix] public static void Prefix(QualityItemDefinition __instance, ref int quantity) { if (CauldronOutputAdd.Add != 10 && ((Object)__instance).name.Contains("CocaineBase") && quantity == 10) { quantity = CauldronOutputAdd.Add; } } } public static class StationTimeLess { public static float TimeAjust = 1f; } [HarmonyPatch(typeof(Cauldron), "MinPass")] public static class Cauldron_Speed_Patch { [HarmonyPrefix] public static void Prefix(Cauldron __instance) { if (__instance.RemainingCookTime > 0 && StationTimeLess.TimeAjust > 1f) { __instance.RemainingCookTime--; } } } [HarmonyPatch(typeof(ChemistryStation), "MinPass")] public static class ChemistryStation_MinPass_Mono_Patch { [HarmonyPrefix] public static void Prefix(ChemistryStation __instance) { if (StationTimeLess.TimeAjust > 1f) { __instance.CurrentCookOperation.Progress(1); } } } [HarmonyPatch(typeof(OvenCookOperation), "UpdateCookProgress")] public static class CookStation_Duration_Patch { [HarmonyPrefix] public static void Prefix(ref int change) { change = Mathf.CeilToInt(StationTimeLess.TimeAjust); } } public static class MixOutputAdd { public static int Add = 1; public static int TimeAjust = 1; } [HarmonyPatch(typeof(MixingStation))] public static class MixStationPatch { [HarmonyPatch("GetMixQuantity")] [HarmonyPostfix] public static void Postfix(MixingStation __instance, ref int __result) { if (__result > 0 && __instance.ProductSlot != null && __instance.MixerSlot != null) { int quantity = __instance.ProductSlot.Quantity; int quantity2 = __instance.MixerSlot.Quantity; int maxMixQuantity = __instance.MaxMixQuantity; int num = Mathf.Min(Mathf.Min(quantity, quantity2), __instance.MaxMixQuantity * MixOutputAdd.Add); __result = num; } } } [HarmonyPatch(typeof(MixingStation), "GetMixTimeForCurrentOperation")] public static class MixStation_Time_Patch { [HarmonyPostfix] public static void Postfix(MixingStation __instance, ref int __result) { if (MixOutputAdd.Add == 2) { MixOutputAdd.TimeAjust = 4; } if (__instance.CurrentMixOperation != null && __result > 0) { int num = __instance.MixTimePerItem * __instance.CurrentMixOperation.Quantity / MixOutputAdd.TimeAjust; __result = Mathf.Max(1, num); } } } public static class StackItem2xFix { private static bool _add; public static bool Add { get { return _add; } set { if (_add != value) { _add = value; UpdateAllRacks(); } } } public static void UpdateAllRacks() { DryingRack[] array = Object.FindObjectsOfType<DryingRack>(); DryingRack[] array2 = array; foreach (DryingRack _instance in array2) { DryingRack_Patch.ApplyCapacityUpdate(_instance); } MelonLogger.Msg($"[DryingRack] Capacity updated for all active {array.Length} racks."); } } [HarmonyPatch(typeof(DryingRack), "InitializeGridItem")] public static class DryingRack_Patch { [HarmonyPostfix] public static void Postfix(DryingRack __instance) { ApplyCapacityUpdate(__instance); } public static void ApplyCapacityUpdate(DryingRack __instance) { int num = (__instance.ItemCapacity = (StackItem2xFix.Add ? 40 : 20)); if (__instance.HangAlignments != null && __instance.HangAlignments.Length != num) { Transform[] componentsInChildren = ((Component)__instance).GetComponentsInChildren<Transform>(); Transform[] array = (Transform[])(object)new Transform[num]; for (int i = 0; i < num; i++) { array[i] = __instance.HangAlignments[i % __instance.HangAlignments.Length]; } __instance.HangAlignments = array; } FieldInfo fieldInfo = AccessTools.Field(typeof(DryingRack), "hangSlots"); Array array2 = (Array)fieldInfo.GetValue(__instance); if (array2 != null && array2.Length != num) { Type elementType = array2.GetType().GetElementType(); Array array3 = Array.CreateInstance(elementType, num); int length = Math.Min(array2.Length, num); Array.Copy(array2, array3, length); if (num > array2.Length) { for (int j = array2.Length; j < num; j++) { object value = Activator.CreateInstance(elementType); array3.SetValue(value, j); } } fieldInfo.SetValue(__instance, array3); } __instance.RefreshHangingVisuals(); } } public static class GrowthSpeedUp { public static float Add; } [HarmonyPatch(typeof(Plant), "MinPass")] public static class Plant_MinPass_Patch { [HarmonyPrefix] public static bool Prefix(Plant __instance, int mins) { if (__instance.NormalizedGrowthProgress >= 1f || NetworkSingleton<TimeManager>.Instance.IsEndOfDay) { return true; } float num = 1f / ((float)__instance.GrowthTime * 60f) * (float)mins; num *= ((GrowContainer)__instance.Pot).GetTemperatureGrowthMultiplier(); float num2 = default(float); num *= ((GrowContainer)__instance.Pot).GetAverageLightExposure(ref num2); num *= __instance.Pot.GrowSpeedMultiplier; num *= num2; num += num * GrowthSpeedUp.Add; if (GameManager.IS_TUTORIAL) { num *= 0.3f; } if (((GrowContainer)__instance.Pot).NormalizedMoistureAmount <= 0f) { num *= 0f; } num *= 1f + GrowthSpeedUp.Add; __instance.SetNormalizedGrowthProgress(__instance.NormalizedGrowthProgress + num); return false; } } [HarmonyPatch(typeof(ShroomColony), "ChangeGrowthPercentage")] public static class MushroomGrowthSpeedPatch { [HarmonyPrefix] public static void Prefix(ShroomColony __instance, ref float change) { if (change > 0f && GrowthSpeedUp.Add > 0f) { change += change * GrowthSpeedUp.Add; } } } public static class QualityMushroomUP { public static float Add; } [HarmonyPatch(typeof(ShroomColony), "GetHarvestedShroom")] public static class MushroomQualityPatch { [HarmonyPostfix] public static void Postfix(ShroomColony __instance, ref ShroomInstance __result) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) if (QualityMushroomUP.Add > 0f && __result != null) { float normalizedQuality = __instance.NormalizedQuality; float num = Mathf.Clamp01(normalizedQuality + QualityMushroomUP.Add); ((QualityItemInstance)__result).SetQuality(ItemQuality.GetQuality(num)); MelonLogger.Msg($"[Quality] Base: {normalizedQuality} | Boosted: {num}"); } } } public static class QualityUP { public static float Add; } public static class BetterGrowTent { public static float Add; } [HarmonyPatch(typeof(Plant), "Initialize")] public static class PlantQualityPatch { [HarmonyPostfix] public static void Postfix(Plant __instance) { if (!((Object)(object)__instance.Pot != (Object)null)) { return; } string text = ((GrowContainer)__instance.Pot).Name.ToString(); float num = 0.5f; float qualityLevel = __instance.QualityLevel; num = (text.Equals("Grow Tent") ? (0.1f + BetterGrowTent.Add) : (text.Equals("Plastic Pot") ? 0.36f : (text.Equals("Moisture-Preserving Pot") ? 0.36f : ((!text.Equals("Air Pot")) ? 0.1f : 0.5f)))); float num2 = num + QualityUP.Add; if (AbsorbentSoil.Add) { if ((Object)(object)__instance.Pot == (Object)null) { MelonLogger.Warning("Plant.Initialize Postfix: Pot is null"); } else { List<AdditiveDefinition> appliedAdditives = ((GrowContainer)__instance.Pot).AppliedAdditives; if (appliedAdditives == null || appliedAdditives.Count == 0) { MelonLogger.Msg("No initial additives found for instant growth"); } else { foreach (AdditiveDefinition item in appliedAdditives) { if (!((Object)(object)item == (Object)null)) { MelonLogger.Msg("Additive Name: " + ((ItemDefinition)item).Name.ToString().ToLower()); if (item.InstantGrowth > 0f && __instance.NormalizedGrowthProgress < 0.5f) { float normalizedGrowthProgress = __instance.NormalizedGrowthProgress; __instance.SetNormalizedGrowthProgress(normalizedGrowthProgress + item.InstantGrowth); MelonLogger.Msg($"Instant growth applied: +{item.InstantGrowth} (from {normalizedGrowthProgress} to {__instance.NormalizedGrowthProgress})"); } } } } } } Traverse val = Traverse.Create((object)__instance); val.Field("QualityLevel").SetValue((object)num2); val.Field("<QualityLevel>k__BackingField").SetValue((object)num2); val.Field("_qualityLevel").SetValue((object)num2); MelonLogger.Msg($"[SkillTree] Plant Init: {text} | Final: {num2} | Skill: {QualityUP.Add} | Total: {__instance.QualityLevel}"); } } public static class YieldAdd { public static int Add; } [HarmonyPatch(typeof(Plant), "GrowthDone")] public static class GrowthDone_SmartBasePatch { [HarmonyPrefix] public static void Prefix(Plant __instance) { if (InstanceFinder.IsServer) { Traverse val = Traverse.Create((object)__instance); float yieldMultiplier = __instance.YieldMultiplier; int num = (int)val.Field("BaseYieldQuantity").GetValue(); if (Mathf.Approximately(yieldMultiplier, 1f) && YieldAdd.Add != 0 && num == 12) { num = (int)val.Field("BaseYieldQuantity").GetValue(); int num2 = num + YieldAdd.Add; val.Field("BaseYieldQuantity").SetValue((object)num2); MelonLogger.Msg($"[Skill More Yield] No additives detected. Skill applied. New Base: {num2}"); } else { val.Field("BaseYieldQuantity").SetValue((object)12); } } } } public static class MethQualityAdd { public static bool Add; } [HarmonyPatch(typeof(LabOven), "Shatter")] public static class LabOven_QualityPatch { [CompilerGenerated] private sealed class <CleanUp>d__2 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public object id; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <CleanUp>d__2(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(1f); <>1__state = 1; return true; case 1: <>1__state = -1; processedOperations.Remove(id); return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static readonly HashSet<object> processedOperations = new HashSet<object>(); [HarmonyPrefix] public static void Prefix(LabOven __instance) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Invalid comparison between Unknown and I4 //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) if (__instance.CurrentOperation != null && MethQualityAdd.Add) { OvenCookOperation currentOperation = __instance.CurrentOperation; if (!processedOperations.Contains(currentOperation) && (int)currentOperation.IngredientQuality < 4) { MelonLogger.Msg($"__instance.CurrentOperation.IngredientQuality {__instance.CurrentOperation.IngredientQuality}"); OvenCookOperation currentOperation2 = __instance.CurrentOperation; currentOperation2.IngredientQuality = (EQuality)(currentOperation2.IngredientQuality + 1); processedOperations.Add(currentOperation); MelonLogger.Msg($"__instance.CurrentOperation.IngredientQuality {__instance.CurrentOperation.IngredientQuality}"); MelonCoroutines.Start(CleanUp(currentOperation)); } } } [IteratorStateMachine(typeof(<CleanUp>d__2))] private static IEnumerator CleanUp(object id) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <CleanUp>d__2(0) { id = id }; } } } namespace SkillTree.SkillSpecial.SkillEmployee { public static class BetterBotanist { public static bool Add; } [HarmonyPatch] public static class Patch_Botanist_Speeds { private static IEnumerable<MethodBase> TargetMethods() { List<MethodBase> list = new List<MethodBase>(); list.Add(AccessTools.Method(typeof(SowSeedInPotBehaviour), "GetActionDuration", (Type[])null, (Type[])null)); list.Add(AccessTools.Method(typeof(WaterPotBehaviour), "GetActionDuration", (Type[])null, (Type[])null)); list.Add(AccessTools.Method(typeof(HarvestPotBehaviour), "GetActionDuration", (Type[])null, (Type[])null)); list.Add(AccessTools.Method(typeof(AddSoilToGrowContainerBehaviour), "GetActionDuration", (Type[])null, (Type[])null)); list.Add(AccessTools.Method(typeof(ApplyAdditiveToGrowContainerBehaviour), "GetActionDuration", (Type[])null, (Type[])null)); list.Add(AccessTools.Method(typeof(HarvestMushroomBedBehaviour), "GetActionDuration", (Type[])null, (Type[])null)); list.Add(AccessTools.Method(typeof(ApplySpawnToMushroomBedBehaviour), "GetActionDuration", (Type[])null, (Type[])null)); return list; } [HarmonyPostfix] public static void Postfix(ref float __result, GrowContainerBehaviour __instance) { if (BetterBotanist.Add && __result > 0f) { __result /= 2f; } } } public static class CanWork { public static bool Add; } [HarmonyPatch(typeof(Employee), "CanWork")] public class Patch_Employee_CanWork { private static void Postfix(ref bool __result) { if (CanWork.Add) { __result = true; } } } [HarmonyPatch(typeof(ClipboardScreen), "Start")] public class Patch_ClipboardScreen_Fix { private static void Postfix(ClipboardScreen __instance) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)__instance.Container == (Object)null)) { ((Transform)__instance.Container).localScale = new Vector3(0.9f, 0.9f, 1f); } } } public static class EmployeeMovespeed { public static bool Add; } public static class EmployeeMoreStation { public static int Add; } [HarmonyPatch(typeof(Employee), "SetIsPaid")] public class Patch_Employee_ActiveNew { private static Packager[] packagerList; private static Chemist[] chemistList; private static Botanist[] botanistList; private static Cleaner[] cleanerList; private static void Postfix() { if (!BetterBotanist.Add) { return; } packagerList = Object.FindObjectsOfType<Packager>(); chemistList = Object.FindObjectsOfType<Chemist>(); botanistList = Object.FindObjectsOfType<Botanist>(); cleanerList = Object.FindObjectsOfType<Cleaner>(); if (EmployeeMoreStation.Add == 0) { return; } Packager[] array = packagerList; foreach (Packager val in array) { if (EmployeeMovespeed.Add) { ((NPC)val).Movement.MovementSpeedScale = 0.33f; } } Chemist[] array2 = chemistList; foreach (Chemist val2 in array2) { if (EmployeeMovespeed.Add) { ((NPC)val2).Movement.MovementSpeedScale = 0.33f; } if (EmployeeMoreStation.Add > 0) { EntityConfiguration configuration = val2.Configuration; ChemistConfiguration val3 = (ChemistConfiguration)(object)((configuration is ChemistConfiguration) ? configuration : null); val3.Stations.MaxItems = 4 + EmployeeMoreStation.Add; } } Botanist[] array3 = botanistList; foreach (Botanist val4 in array3) { if (EmployeeMovespeed.Add) { ((NPC)val4).Movement.MovementSpeedScale = 0.33f; } if (EmployeeMoreStation.Add > 0) { EntityConfiguration configuration2 = val4.Configuration; BotanistConfiguration val5 = (BotanistConfiguration)(object)((configuration2 is BotanistConfiguration) ? configuration2 : null); val5.Assigns.MaxItems = 8 + EmployeeMoreStation.Add * 2; } } Cleaner[] array4 = cleanerList; foreach (Cleaner val6 in array4) { if (EmployeeMovespeed.Add) { ((NPC)val6).Movement.MovementSpeedScale = 0.33f; } } } } } namespace SkillTree.SkillEffect { public static class SkillSystem { private static Player localPlayer; private static PlayerMovement playerMovement; private static Customer[] customerList; private static Business[] businessList; private static Dealer[] dealerList; private static Registry registry; private static Packager[] packagerList; private static Chemist[] chemistList; private static Botanist[] botanistList; private static Cleaner[] cleanerList; public static void ApplySkill(string skillId, SkillTreeData data) { localPlayer = Player.Local; playerMovement = PlayerSingleton<PlayerMovement>.Instance; registry = Singleton<Registry>.Instance; customerList = Object.FindObjectsOfType<Customer>(); dealerList = Object.FindObjectsOfType<Dealer>(); businessList = Object.FindObjectsOfType<Business>(); List<ItemDefinition> allItems = registry.GetAllItems(); switch (skillId) { case "Stats": MelonLogger.Msg("Player Health Before: " + localPlayer.Health.CurrentHealth); PlayerHealthConfig.MaxHealth = 100f + (float)data.Stats * 20f; localPlayer.Health.SetHealth(PlayerHealthConfig.MaxHealth); localPlayer.Health.RecoverHealth(PlayerHealthConfig.MaxHealth); MelonLogger.Msg("Player Health Now: " + localPlayer.Health.CurrentHealth); break; case "MoreMovespeed": MelonLogger.Msg("MoveSpeed Before: " + playerMovement.MoveSpeedMultiplier); PlayerMovespeed.MovespeedBase = 1f + (float)data.MoreMovespeed * 0.1f; playerMovement.MoveSpeedMultiplier = PlayerMovespeed.MovespeedBase; MelonLogger.Msg("MoveSpeed Now: " + playerMovement.MoveSpeedMultiplier); break; case "MoreStackItem": { QuickPackagers.Add = data.MoreStackItem == 1; if ((Object)(object)registry == (Object)null || data.MoreStackItem != 1) { break; } StackCache.FillCache(allItems); int num3 = 1 + data.MoreStackItem; if (num3 <= 1) { break; } foreach (ItemDefinition item in allItems) { string name2 = ((Object)item).name; if (StackCache.ItemStack.TryGetValue(name2, out var value4)) { item.StackLimit = value4 * num3; MelonLogger.Msg($"[MoreStackItem] {name2}: {value4} -> {item.StackLimit}"); } } MelonLogger.Msg("Skill Item Stack x2 Active"); break; } case "MoreXP": PlayerXPConfig.XpBase = 100f + (float)data.MoreXP * 5f; MelonLogger.Msg($"XP Base updated for: {PlayerXPConfig.XpBase}%"); break; case "MoreXP2": PlayerXPConfig.XpBase = 100f + (float)(data.MoreXP + data.MoreXP2) * 5f; MelonLogger.Msg($"XP Base updated for: {PlayerXPConfig.XpBase}%"); break; case "BetterDelivery": BetterDelivery.Add = data.BetterDelivery == 1; break; case "AllowSleepAthEne": AllowSleepAthEne.Add = data.AllowSleepAthEne == 1; break; case "AllowSeeCounteroffChance": CounterofferHelper.Counteroffer = data.AllowSeeCounteroffChance == 1; break; case "SkipSchedule": SkipSchedule.Add = data.SkipSchedule == 1; break; case "MoreXPWhenEarnMoney": PlayerXpMoney.XpMoney = data.MoreXPWhenEarnMoney == 1; break; case "Operations": BetterGrowTent.Add = (float)data.Operations * 0.16f; break; case "GrowthSpeed": GrowthSpeedUp.Add = (float)data.GrowthSpeed * 0.025f; break; case "GrowthSpeed2": GrowthSpeedUp.Add = (float)(data.GrowthSpeed + data.GrowthSpeed2) * 0.025f; break; case "MoreYield": YieldAdd.Add = data.MoreYield; break; case "MoreQuality": QualityUP.Add = (float)data.MoreQuality * 0.15f; QualityMushroomUP.Add = ((data.MoreQuality == 2) ? 0.3f : 0f); break; case "MoreQualityMethCoca": MethQualityAdd.Add = data.MoreQualityMethCoca == 1; break; case "AbsorbentSoil": AbsorbentSoil.Add = data.AbsorbentSoil == 1; break; case "MoreMixAndDryingRackOutput": StackItem2xFix.Add = data.MoreMixAndDryingRackOutput == 1; MixOutputAdd.Add = ((data.MoreMixAndDryingRackOutput * 2 == 0) ? 1 : (data.MoreMixAndDryingRackOutput * 2)); break; case "ChemistStationQuick": StationTimeLess.TimeAjust = (((float)data.ChemistStationQuick * 1.5f == 0f) ? 1f : ((float)data.ChemistStationQuick * 1.5f)); MixOutputAdd.TimeAjust = ((data.ChemistStationQuick * 2 == 0) ? 1 : (data.ChemistStationQuick * 2)); break; case "MoreCauldronOutput": { int add = CauldronOutputAdd.Add; int num4 = Mathf.FloorToInt((float)add * 1f * (float)data.MoreCauldronOutput); CauldronOutputAdd.Add = add + num4; break; } case "Social": CustomerSample.AddSampleChance = (float)data.Social * 0.05f; break; case "CityEvolving": { CustomerCache.FillCache(customerList.ToList()); float num2 = 1f + (float)data.CityEvolving * 0.1f; if (!(num2 > 1f)) { break; } Customer[] array4 = customerList; foreach (Customer val4 in array4) { string name = ((Object)val4.CustomerData).name; if (CustomerCache.OriginalMinSpend.TryGetValue(name, out var value2) && CustomerCache.OriginalMaxSpend.TryGetValue(name, out var value3)) { val4.CustomerData.MinWeeklySpend = value2 * num2; val4.CustomerData.MaxWeeklySpend = value3 * num2; } } MelonLogger.Msg($"Weekly spend incresed by {1f + (float)data.CityEvolving * 0.15f}%"); break; } case "BusinessEvolving": { BusinessCache.FillCache(businessList.ToList()); float num = 1f + (float)data.BusinessEvolving * 0.2f; if (!(num > 1f)) { break; } Business[] array3 = businessList; foreach (Business val3 in array3) { string propertyName = ((Property)val3).PropertyName; if (BusinessCache.LaunderCapacity.TryGetValue(propertyName, out var value)) { float launderCapacity = val3.LaunderCapacity; val3.LaunderCapacity = value * num; MelonLogger.Msg($"[BusinessEvolving] {propertyName}: {value} -> {val3.LaunderCapacity}"); } } MelonLogger.Msg($"LaunderCapacity incresed by {1f + (float)data.BusinessEvolving * 0.2f}%"); break; } case "MoreATMLimit": ATMConfig.MaxWeeklyLimit = 10000f + (float)(data.MoreATMLimit * 2000); MelonLogger.Msg($"ATM Deposit Weekly Limit: ${ATMConfig.MaxWeeklyLimit}"); break; case "DealerCutLess": { Dealer[] array2 = dealerList; foreach (Dealer val2 in array2) { if (ValidDealer(val2)) { float cut = val2.Cut; val2.Cut = 0.2f - (float)data.DealerCutLess * 0.05f; MelonLogger.Msg($"Dealer: {((Object)val2).name} decrease cut from {cut}% to {val2.Cut}"); }