Decompiled source of SkillTree Mono v1.1.3

SkillTree.dll

Decompiled 2 weeks ago
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}");
					}