Decompiled source of SkillTree ILC2cpp v1.0.6

SkillTree_IL2cpp.dll

Decompiled a week 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 HarmonyLib;
using Il2CppFishNet;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppScheduleOne;
using Il2CppScheduleOne.Delivery;
using Il2CppScheduleOne.DevUtilities;
using Il2CppScheduleOne.Economy;
using Il2CppScheduleOne.Effects;
using Il2CppScheduleOne.GameTime;
using Il2CppScheduleOne.Growing;
using Il2CppScheduleOne.Interaction;
using Il2CppScheduleOne.ItemFramework;
using Il2CppScheduleOne.Levelling;
using Il2CppScheduleOne.Messaging;
using Il2CppScheduleOne.Money;
using Il2CppScheduleOne.NPCs;
using Il2CppScheduleOne.ObjectScripts;
using Il2CppScheduleOne.Persistence;
using Il2CppScheduleOne.PlayerScripts;
using Il2CppScheduleOne.PlayerScripts.Health;
using Il2CppScheduleOne.Product;
using Il2CppScheduleOne.Property;
using Il2CppScheduleOne.Quests;
using Il2CppScheduleOne.Tools;
using Il2CppScheduleOne.UI;
using Il2CppScheduleOne.UI.ATM;
using Il2CppScheduleOne.UI.Phone;
using Il2CppScheduleOne.UI.Phone.Messages;
using Il2CppScheduleOne.UI.Shop;
using Il2CppScheduleOne.Variables;
using Il2CppSystem.Collections.Generic;
using MelonLoader;
using MelonLoader.Utils;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using SkillTree;
using SkillTree.Json;
using SkillTree.SkillEffect;
using SkillTree.SkillPatchOperations;
using SkillTree.SkillPatchSocial;
using SkillTree.SkillPatchStats;
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(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("SkillTree_IL2cpp")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("SkillTree_IL2cpp")]
[assembly: AssemblyTitle("SkillTree_IL2cpp")]
[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 SkillTreeUI skillTreeUI;

		private int skillPointValid = 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 = Il2CppArrayBase<Customer>.op_Implicit(Object.FindObjectsOfType<Customer>());
			}
		}

		public override void OnUpdate()
		{
			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((KeyCode)99) && waiting)
				{
					skillTreeUI.Visible = !skillTreeUI.Visible;
					flag = true;
				}
				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);
					PlayerSingleton<PlayerMovement>.Instance.CanMove = !skillTreeUI.Visible;
					((Behaviour)PlayerSingleton<PlayerCamera>.Instance).enabled = !skillTreeUI.Visible;
					((Behaviour)Singleton<PlayerManager>.Instance).enabled = !skillTreeUI.Visible;
					playerInventory.SetInventoryEnabled(!skillTreeUI.Visible);
				}
			}
		}

		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();
				skillTreeUI = new SkillTreeUI(skillData);
				SkillSystem.ApplyAll(skillData);
			}
			firstTime = true;
			timer -= Time.deltaTime;
			if (timer <= 0f)
			{
				ItemUnlocker.UnlockSpecificItems();
				AttPoints();
				waiting = true;
				return true;
			}
			return false;
		}

		public void AttPoints(bool levelUp = false)
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Expected I4, but got Unknown
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0298: 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;
			int num3 = num * 6 + num2;
			int num4 = skillData.StatsPoints + skillData.OperationsPoints + skillData.SocialPoints + skillData.UsedSkillPoints;
			if (num3 != num4 && !levelUp)
			{
				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();
				skillTreeUI = new SkillTreeUI(skillData);
				SkillSystem.ApplyAll(skillData);
				skillPointValid = num3;
			}
			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;
				}
			}
			lastProcessedTier = levelManager.Tier;
			lastProcessedRank = levelManager.Rank;
			int num5 = skillData.StatsPoints + skillData.OperationsPoints + skillData.SocialPoints + skillData.UsedSkillPoints;
			if (skillPointValid <= 0)
			{
				return;
			}
			int num6 = 0;
			int num7 = 0;
			int num8 = 0;
			for (int i = 0; i < skillPointValid; i++)
			{
				switch ((num5 + i) % 3)
				{
				case 0:
					num6++;
					break;
				case 1:
					num7++;
					break;
				case 2:
					num8++;
					break;
				}
			}
			if (skillTreeUI == null)
			{
				skillTreeUI = new SkillTreeUI(skillData);
			}
			if (skillTreeUI != null)
			{
				skillTreeUI.AddPoints(num6, num7, num8);
			}
			MelonLogger.Msg($"[SkillTree] Processed: Rank {levelManager.Rank} Tier {levelManager.Tier}. Gains: Stats+{num6} Operations+{num7} Social+{num8}");
		}

		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_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: 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;
			Enumerator<ItemDefinition> enumerator = allItems.GetEnumerator();
			while (enumerator.MoveNext())
			{
				ItemDefinition current = enumerator.Current;
				if ((Object)(object)current == (Object)null || string.IsNullOrEmpty(current.ID))
				{
					continue;
				}
				string text = current.ID.ToLowerInvariant();
				if (TargetRanks.TryGetValue(text, out var value))
				{
					StorableItemDefinition val = (StorableItemDefinition)(object)((current is StorableItemDefinition) ? current : 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_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Expected O, but got Unknown
			if (!__instance.ShopCode.ToLower().Contains("hardware") && !__instance.ShopCode.ToLower().Contains("handy_hanks"))
			{
				return;
			}
			StorableItemDefinition[] array = Il2CppArrayBase<StorableItemDefinition>.op_Implicit(Resources.FindObjectsOfTypeAll<StorableItemDefinition>());
			foreach (string id in itemIdsToInject)
			{
				bool flag = false;
				Enumerator<ShopListing> enumerator2 = __instance.Listings.GetEnumerator();
				while (enumerator2.MoveNext())
				{
					ShopListing current = enumerator2.Current;
					if ((Object)(object)current.Item != (Object)null && ((ItemDefinition)current.Item).ID.ToLower() == id.ToLower())
					{
						flag = true;
						break;
					}
				}
				if (flag)
				{
					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;
					if (id == "moisturepreservingpot")
					{
						val2.OverridePrice = true;
						val2.OverriddenPrice = 125f;
					}
					if (id == "ledgrowlight")
					{
						val2.OverridePrice = true;
						val2.OverriddenPrice = 200f;
					}
					if (id == "plasticpot")
					{
						val2.OverridePrice = true;
						val2.OverriddenPrice = 50f;
					}
					if (id == "halogengrowlight")
					{
						val2.OverridePrice = true;
						val2.OverriddenPrice = 100f;
					}
					if (id == "suspensionrack")
					{
						val2.OverridePrice = true;
						val2.OverriddenPrice = 100f;
					}
					if (id == "airpot")
					{
						val2.OverridePrice = true;
						val2.OverriddenPrice = 300f;
					}
					if (id == "dryingrack")
					{
						val2.OverridePrice = true;
						val2.OverriddenPrice = 400f;
					}
					Traverse val3 = Traverse.Create((object)val2);
					if (val2.IsUnlimitedStock)
					{
						val3.Field("isUnlimitedStock").SetValue((object)true);
					}
					else if (val3.Field("_isUnlimitedStock").FieldExists())
					{
						val3.Field("_isUnlimitedStock").SetValue((object)true);
					}
					__instance.Listings.Add(val2);
					val2.Initialize(__instance);
					__instance.CreateListingUI(val2);
					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;
			}
			Enumerator<ItemDefinition> enumerator = business.GetEnumerator();
			while (enumerator.MoveNext())
			{
				ItemDefinition current = enumerator.Current;
				string name = ((Object)current).name;
				if (!ItemStack.ContainsKey(name))
				{
					ItemStack.Add(name, current.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 List<SkillField> skillFields = new List<SkillField>();

		private bool skinReady;

		private bool guiInitialized = false;

		private float currentY;

		public bool Visible { get; set; }

		public GUISkin Skin { get; private set; }

		public SkillTreeUI(SkillTreeData data)
		{
			//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);
			BuildSkillMap();
		}

		public void Draw()
		{
			//IL_0034: 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)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			if (Visible)
			{
				if (!guiInitialized)
				{
					CenterWindow();
					guiInitialized = true;
				}
				windowRect = GUI.Window(9001, windowRect, WindowFunction.op_Implicit((Action<int>)DrawWindow), "Skill Tree");
			}
		}

		private void DrawWindow(int id)
		{
			try
			{
				currentY = 80f;
				GUILayout.BeginHorizontal((Il2CppReferenceArray<GUILayoutOption>)null);
				GUILayout.Label("Skill Tree", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(120f) });
				GUILayout.FlexibleSpace();
				GUILayout.Label($"Stats: {editData.StatsPoints}", (Il2CppReferenceArray<GUILayoutOption>)null);
				GUILayout.Space(10f);
				GUILayout.Label($"Operations: {editData.OperationsPoints}", (Il2CppReferenceArray<GUILayoutOption>)null);
				GUILayout.Space(10f);
				GUILayout.Label($"Social: {editData.SocialPoints}", (Il2CppReferenceArray<GUILayoutOption>)null);
				GUILayout.EndHorizontal();
				GUILayout.Space(10f);
				if (!selectedCategory.HasValue)
				{
					DrawCategoryButtons();
				}
				else
				{
					DrawCategoryHeader();
					DrawTreeByCategory(selectedCategory.Value);
				}
				GUILayout.FlexibleSpace();
				GUILayout.BeginHorizontal((Il2CppReferenceArray<GUILayoutOption>)null);
				GUILayout.EndHorizontal();
				GUI.DragWindow();
			}
			catch (Exception ex)
			{
				MelonLogger.Msg("SytemNullable shutup " + ex.Message);
			}
		}

		private void DrawCategoryButtons()
		{
			GUILayout.Label("Escolha uma categoria", (Il2CppReferenceArray<GUILayoutOption>)null);
			GUILayout.Space(10f);
			if (GUILayout.Button("Stats", (Il2CppReferenceArray<GUILayoutOption>)null))
			{
				selectedCategory = SkillCategory.Stats;
			}
			if (GUILayout.Button("Operations", (Il2CppReferenceArray<GUILayoutOption>)null))
			{
				selectedCategory = SkillCategory.Operations;
			}
			if (GUILayout.Button("Social", (Il2CppReferenceArray<GUILayoutOption>)null))
			{
				selectedCategory = SkillCategory.Social;
			}
		}

		private void DrawCategoryHeader()
		{
			GUILayout.BeginHorizontal((Il2CppReferenceArray<GUILayoutOption>)null);
			if (GUILayout.Button("< Voltar", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(80f) }))
			{
				selectedCategory = null;
				GUILayout.EndHorizontal();
				GUILayout.Space(10f);
				return;
			}
			if (selectedCategory.HasValue)
			{
				GUILayout.Label(selectedCategory.Value.ToString(), (Il2CppReferenceArray<GUILayoutOption>)null);
			}
			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_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: 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)
			float num = 20f + (float)depth * 20f;
			float num2 = 25f;
			int num3 = (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 && num3 < maxLevel && GetPoints(skill.Category) > 0;
			Rect val = default(Rect);
			((Rect)(ref val))..ctor(num, currentY, 250f, 20f);
			GUI.Label(val, $"{skill.Name} ({num3}/{maxLevel})");
			Rect val2 = default(Rect);
			((Rect)(ref val2))..ctor(num + 270f, currentY, 24f, 20f);
			if (num3 < maxLevel)
			{
				GUI.enabled = enabled;
				if (GUI.Button(val2, "+"))
				{
					int num4 = num3 + 1;
					skill.Field.SetValue(editData, num4);
					ConsumePoint(skill.Category);
					SkillSystem.ApplySkill(skill.Id, editData);
					SkillTreeSaveManager.Save(editData);
				}
				GUI.enabled = true;
			}
			else
			{
				GUI.Label(val2, "✔");
			}
			if (((Rect)(ref val)).Contains(Event.current.mousePosition))
			{
				DrawTooltip(skill.Description, val);
			}
			currentY += num2;
			if (num3 <= 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, 
				_ => 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;
			}
			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_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: 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);
				float num2 = 20 + depth * 30;
				float num3 = 22f;
				Rect val = default(Rect);
				((Rect)(ref val))..ctor(num2, currentY, 250f, 20f);
				GUI.Label(val, $"{skill.Name}: {num}/1");
				bool flag = skill.Parent == null || GetSkillValue(skill.Parent) == 1;
				bool enabled = num == 0 && GetPoints(skill.Category) > 0 && flag;
				Rect val2 = default(Rect);
				((Rect)(ref val2))..ctor(num2 + 260f, currentY, 30f, 20f);
				GUI.enabled = enabled;
				if (GUI.Button(val2, "+"))
				{
					skill.Field.SetValue(editData, 1);
					ConsumePoint(skill.Category);
					SkillTreeSaveManager.Save(editData);
				}
				GUI.enabled = true;
				DrawTooltip(skill.Description, val);
				currentY += num3;
				DrawTree(skill.Id, depth);
			}
		}

		private void DrawTooltip(string text, Rect anchorRect)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			//IL_0021: 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_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			if (!string.IsNullOrEmpty(text))
			{
				GUIContent val = new GUIContent(text);
				Vector2 val2 = GUI.skin.box.CalcSize(val);
				float num = 10f;
				Rect val3 = default(Rect);
				((Rect)(ref val3))..ctor(30f, ((Rect)(ref anchorRect)).y - 20f, val2.x + num, val2.y + num);
				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)
		{
			if (source == null)
			{
				return null;
			}
			string text = JsonConvert.SerializeObject((object)source);
			return JsonConvert.DeserializeObject<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(Il2CppStructArray<Color>.op_Implicit(array));
			val.Apply();
			return val;
		}

		public void AddPoints(int stats, int ops, int social)
		{
			editData.StatsPoints += stats;
			editData.OperationsPoints += ops;
			editData.SocialPoints += social;
			originalData.StatsPoints += stats;
			originalData.OperationsPoints += ops;
			originalData.SocialPoints += social;
			SkillTreeSaveManager.Save(editData);
		}
	}
}
namespace SkillTree.Json
{
	public enum SkillCategory
	{
		Stats,
		Operations,
		Social
	}
	[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 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, "MoreXP", 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 More Fast (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, "GrowthSpeed", 1)]
		public int MoreYield = 0;

		[Skill("Advanced Pot Techniques", "+15% Quality. [Lvl 1] Moisture Pots gain +1 Tier. [Max Lvl] All Pots gain +1 Tier.", SkillCategory.Operations, "MoreYield", 2)]
		public int MoreQuality = 0;

		[Skill("More Quality Mushroom", "Upgrade Mushroom Quality Tier", SkillCategory.Operations, "MoreQuality", 1)]
		public int MoreQualityMushroom = 0;

		[Skill("More Quality Meth", "Upgrade Meth Quality Tier", SkillCategory.Operations, "MoreYield", 1)]
		public int MoreQualityMeth = 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, "MoreYield", 1)]
		public int ChemistStationQuick = 0;

		[Skill("More Mix and Drying Rack Output", "Double Mix and Drying Rack Output", SkillCategory.Operations, "ChemistStationQuick", 1)]
		public int MoreMixAndDryingRackOutput = 0;

		[Skill("AbsorbentSoil", "Preserve soil additives", SkillCategory.Operations, "ChemistStationQuick", 1)]
		public int AbsorbentSoil = 0;

		[Skill("More Cauldron Output", "Double Cauldron Output", SkillCategory.Operations, "MoreMixAndDryingRackOutput", 1)]
		public int MoreCauldronOutput = 0;

		[Skill("More sample chance", "Increase Sample Chance by 5%", SkillCategory.Social, null, 2)]
		public int Social = 0;

		[Skill("Civil 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 +1500", SkillCategory.Social, "Social", 4)]
		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;
	}
	public static class SkillTreeSaveManager
	{
		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;
			}
			try
			{
				string text = File.ReadAllText(dynamicPath);
				return JsonConvert.DeserializeObject<SkillTreeData>(text);
			}
			catch (Exception value)
			{
				MelonLogger.Error($"[SkillTree] Save corrupted, recreating.\n{value}");
				SkillTreeData skillTreeData2 = CreateDefault();
				Save(skillTreeData2);
				return skillTreeData2;
			}
		}

		public static void Save(SkillTreeData data)
		{
			string dynamicPath = GetDynamicPath();
			string contents = JsonConvert.SerializeObject((object)data, (Formatting)1);
			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));
		}
	}
}
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("TakeDamage")]
		[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);
			__instance.TimeSinceLastDamage = 0f;
			if (num <= 0f)
			{
				__instance.SendDie();
			}
			return false;
		}

		private static void SetInternalHealth(PlayerHealth instance, float value)
		{
			float currentHealth_k__BackingField = instance._CurrentHealth_k__BackingField;
			instance._CurrentHealth_k__BackingField = 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 value = xp;
					xp = Mathf.CeilToInt((float)xp * num);
					MelonLogger.Msg($"[XP] Apply: {value} -> {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 payment = __instance.Payment;
			if (!(payment > 0f))
			{
				return;
			}
			int num = Mathf.RoundToInt(payment * 0.05f);
			if (num > 0)
			{
				LevelManager instance = NetworkSingleton<LevelManager>.Instance;
				if ((Object)(object)instance != (Object)null)
				{
					MelonLogger.Msg($"[Contract] Payment of ${payment} converted into {num} base XP.");
					instance.AddXP(num);
					_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)
			{
				if (!SkipSchedule.Add)
				{
					return true;
				}
				InteractableObject intObj = __instance.intObj;
				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_011d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0127: 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)
					{
						foreach (GrowContainer item in Object.FindObjectsOfType<GrowContainer>())
						{
							AccessTools.Method(typeof(GrowContainer), "DrainMoisture", (Type[])null, (Type[])null)?.Invoke(item, new object[1] { num2 * 3 });
						}
						foreach (Plant item2 in Object.FindObjectsOfType<Plant>())
						{
							item2.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 value = num4 / 60;
			int value2 = num4 % 60;
			return $"{value:00}h {value2: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_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			MSGConversation conversation = instance.conversation;
			float price = instance.price;
			ProductDefinition selectedProduct = instance.selectedProduct;
			int quantity = instance.quantity;
			Customer component = ((Component)conversation.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 (price >= 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(selectedProduct, StandardsMethod.GetCorrespondingQuality(customerData.Standards));
			float num2 = Mathf.InverseLerp(-1f, 1f, productEnjoyment);
			float valueProposition2 = Customer.GetValueProposition(selectedProduct, price / (float)quantity);
			float num3 = Mathf.Pow((float)quantity / (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_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: 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_013c: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)SuccessLabel != (Object)null))
			{
				Text fairPriceLabel = instance.FairPriceLabel;
				Transform parent = ((Component)fairPriceLabel).transform.parent;
				GameObject val = Object.Instantiate<GameObject>(((Component)fairPriceLabel).gameObject, parent);
				((Object)val).name = "SuccessChanceLabel";
				SuccessLabel = val.GetComponent<Text>();
				SuccessLabel.font = fairPriceLabel.font;
				SuccessLabel.fontSize = fairPriceLabel.fontSize;
				SuccessLabel.fontStyle = (FontStyle)1;
				SuccessLabel.alignment = fairPriceLabel.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)fairPriceLabel).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 value = ((num >= 0.75f) ? "#4CAF50" : ((num >= 0.4f) ? "#FFC107" : "#F44336"));
				SuccessLabel.text = $"<color={value}>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 ATM_DynamicLimit_IL2CPP_Final_Patch
	{
		[HarmonyPatch("get_remainingAllowedDeposit")]
		[HarmonyPrefix]
		public static bool PrefixGetRemaining(ref float __result)
		{
			__result = Mathf.Max(0f, ATMConfig.MaxWeeklyLimit - ATM.WeeklyDepositSum);
			return false;
		}

		[HarmonyPatch("GetAmountFromIndex")]
		[HarmonyPrefix]
		public static bool PrefixGetAmount(int index, bool depositing, ref float __result)
		{
			if (index == -1 || index >= ((Il2CppArrayBase<int>)(object)ATMInterface.amounts).Length)
			{
				__result = 0f;
				return false;
			}
			if (depositing && index == ((Il2CppArrayBase<int>)(object)ATMInterface.amounts).Length - 1)
			{
				float num = Mathf.Max(0f, ATMConfig.MaxWeeklyLimit - ATM.WeeklyDepositSum);
				__result = Mathf.Min(NetworkSingleton<MoneyManager>.Instance.cashBalance, num);
				return false;
			}
			__result = ((Il2CppArrayBase<int>)(object)ATMInterface.amounts)[index];
			return false;
		}

		[HarmonyPatch("SetSelectedAmount")]
		[HarmonyPrefix]
		public static bool PrefixSetSelected(ATMInterface __instance, float amount)
		{
			float num = Mathf.Max(0f, ATMConfig.MaxWeeklyLimit - ATM.WeeklyDepositSum);
			float num2 = NetworkSingleton<MoneyManager>.Instance.sync___get_value_onlineBalance();
			float num3 = ((!__instance.depositing) ? num2 : Mathf.Min(NetworkSingleton<MoneyManager>.Instance.cashBalance, num));
			__instance.selectedAmount = Mathf.Clamp(amount, 0f, num3);
			if ((Object)(object)__instance.amountLabelText != (Object)null)
			{
				__instance.amountLabelText.text = MoneyManager.FormatAmount(__instance.selectedAmount, false, false);
			}
			return false;
		}

		[HarmonyPatch("Update")]
		[HarmonyPostfix]
		public static void PostfixUpdate(ATMInterface __instance)
		{
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			if (__instance.isOpen)
			{
				bool flag = ATM.WeeklyDepositSum >= ATMConfig.MaxWeeklyLimit;
				if ((Object)(object)__instance.menu_DepositButton != (Object)null)
				{
					((Selectable)__instance.menu_DepositButton).interactable = !flag;
				}
				if ((Object)(object)__instance.depositLimitText != (Object)null)
				{
					__instance.depositLimitText.text = MoneyManager.FormatAmount(ATM.WeeklyDepositSum, false, false) + " / " + MoneyManager.FormatAmount(ATMConfig.MaxWeeklyLimit, false, false);
					((Graphic)__instance.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)
		{
			if (__instance.depositing)
			{
				float cashBalance = NetworkSingleton<MoneyManager>.Instance.cashBalance;
				float num = Mathf.Max(0f, ATMConfig.MaxWeeklyLimit - ATM.WeeklyDepositSum);
				List<Button> amountButtons = __instance.amountButtons;
				for (int i = 0; i < ((Il2CppArrayBase<int>)(object)ATMInterface.amounts).Length && i < amountButtons.Count; i++)
				{
					float num2 = ((Il2CppArrayBase<int>)(object)ATMInterface.amounts)[i];
					if (i == ((Il2CppArrayBase<int>)(object)ATMInterface.amounts).Length - 1)
					{
						((Selectable)amountButtons[i]).interactable = cashBalance > 0f && num > 0f;
					}
					else
					{
						((Selectable)amountButtons[i]).interactable = cashBalance >= num2 && num2 <= num;
					}
				}
				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 value = __result;
				__result = Mathf.Clamp(__result + CustomerSample.AddSampleChance, 0f, 1f);
				MelonLogger.Msg($"[Skill] Chance de Sample alterada de: {value: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)
		{
			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 < ((Il2CppArrayBase<RectTransform>)(object)__instance.CustomerEntries).Length; i++)
			{
				if (dealer.AssignedCustomers.Count > i)
				{
					Customer customer = dealer.AssignedCustomers[i];
					RectTransform val = ((Il2CppArrayBase<RectTransform>)(object)__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.op_Implicit((Action)delegate
					{
						dealer.SendRemoveCustomer(customer.NPC.ID);
						__instance.SetDisplayedDealer(dealer);
					}));
					((Component)val).gameObject.SetActive(true);
				}
				else
				{
					((Component)((Il2CppArrayBase<RectTransform>)(object)__instance.CustomerEntries)[i]).gameObject.SetActive(false);
				}
			}
		}

		private static void CheckAndExpandUI(DealerManagementApp __instance)
		{
			int dynamicLimit = GetDynamicLimit();
			if (((Il2CppArrayBase<RectTransform>)(object)__instance.CustomerEntries).Length < dynamicLimit)
			{
				List<RectTransform> list = ((IEnumerable<RectTransform>)__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 = Il2CppReferenceArray<RectTransform>.op_Implicit(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("CartChanged")]
		[HarmonyPrefix]
		public static bool CartChanged_Prefix(PhoneShopInterface __instance)
		{
			MelonLogger.Msg(" 1 ");
			if ((Object)(object)__instance == (Object)null)
			{
				return true;
			}
			int num = default(int);
			float orderTotal = __instance.GetOrderTotal(ref num);
			__instance.UpdateOrderTotal();
			MelonLogger.Msg($"Order Total: {orderTotal} | Items: {num}");
			if (orderTotal > 0f && orderTotal <= __instance.orderLimit)
			{
				((Selectable)__instance.ConfirmButton).interactable = num <= SupplierUp.SupplierLimit;
				MelonLogger.Msg($"Can Confirm: {((Selectable)__instance.ConfirmButton).interactable} (Limit: {10 + SupplierUp.SupplierLimit})");
			}
			return false;
		}
	}
	[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 propertyName = ((Property)__instance).propertyName;
			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 (" + propertyName + ")", num3, 1f, string.Empty);
							MelonLogger.Msg($"[LaunderingMod] Partial payout of {num3} processed for {propertyName}");
						}
						Singleton<NotificationsManager>.Instance.SendNotification(propertyName, "<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;
					__instance.CompleteOperation(val);
					MelonLogger.Msg("[LaunderingMod] Operation completed for " + propertyName + ". 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
	{
		private static bool Prefix(Pot __instance)
		{
			if (!AbsorbentSoil.Add)
			{
				return true;
			}
			try
			{
				Plant plant = __instance.Plant;
				if ((Object)(object)plant == (Object)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");
				}
				int num = ((GrowContainer)__instance)._remainingSoilUses - 1;
				((GrowContainer)__instance).SetRemainingSoilUses(num);
				__instance.SetSoilState((ESoilState)0);
				if (num <= 0)
				{
					MelonLogger.Msg("Soil depleted: clearing soil and additives");
					((GrowContainer)__instance).ClearAdditives();
					((GrowContainer)__instance).ClearSoil();
				}
				else
				{
					MelonLogger.Msg("Soil still usable: additives preserved");
				}
				return false;
			}
			catch (Exception value2)
			{
				MelonLogger.Error($"OnPlantFullyHarvested patch failed: {value2}");
				return true;
			}
		}
	}
	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)
			{
				int remainingCookTime = __instance.RemainingCookTime;
				__instance.RemainingCookTime = remainingCookTime - 1;
			}
		}
	}
	[HarmonyPatch(typeof(ChemistryStation), "MinPass")]
	public static class ChemistryStation_MinPass_IL2CPP_Patch
	{
		[HarmonyPrefix]
		public static void Prefix(ChemistryStation __instance)
		{
			if (StationTimeLess.TimeAjust > 1f && __instance.CurrentCookOperation != null)
			{
				__instance.CurrentCookOperation.Progress(1);
			}
		}
	}
	[HarmonyPatch(typeof(LabOven), "MinPass")]
	public static class Oven_FastProgress_IL2CPP_Patch
	{
		[HarmonyPostfix]
		public static void Prefix(LabOven __instance)
		{
			if (StationTimeLess.TimeAjust > 1f && __instance.CurrentOperation != null)
			{
				OvenCookOperation currentOperation = __instance.CurrentOperation;
				int cookProgress = currentOperation.CookProgress;
				currentOperation.CookProgress = cookProgress + 1;
			}
		}
	}
	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 num = Mathf.Min(Mathf.Min(quantity, quantity2), __instance.MaxMixQuantity * MixOutputAdd.Add);
				__result = num;
			}
		}
	}
	[HarmonyPatch(typeof(MixingStation), "MinPass")]
	public static class MixStation_Time_Patch
	{
		[HarmonyPostfix]
		public static void Postfix(MixingStation __instance)
		{
			if (!((Object)(object)__instance == (Object)null) && __instance.CurrentMixTime < __instance.GetMixTimeForCurrentOperation() / 2)
			{
				__instance.CurrentMixTime = __instance.GetMixTimeForCurrentOperation() / 2;
				if (MixOutputAdd.Add == 2)
				{
					__instance.CurrentMixTime += __instance.GetMixTimeForCurrentOperation() / 4;
				}
			}
		}
	}
	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 = Il2CppArrayBase<DryingRack>.op_Implicit(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 num2 = (__instance.ItemCapacity = (StackItem2xFix.Add ? 40 : 20));
			if (__instance.HangAlignments != null && ((Il2CppArrayBase<Transform>)(object)__instance.HangAlignments).Length != num2)
			{
				Transform[] array = Il2CppArrayBase<Transform>.op_Implicit(((Component)__instance).GetComponentsInChildren<Transform>());
				Transform[] array2 = (Transform[])(object)new Transform[num2];
				for (int i = 0; i < num2; i++)
				{
					array2[i] = ((Il2CppArrayBase<Transform>)(object)__instance.HangAlignments)[i % ((Il2CppArrayBase<Transform>)(object)__instance.HangAlignments).Length];
				}
				__instance.HangAlignments = Il2CppReferenceArray<Transform>.op_Implicit(array2);
			}
			Array array3 = Il2CppArrayBase<ItemSlot>.op_Implicit((Il2CppArrayBase<ItemSlot>)(object)__instance.hangSlots);
			if (array3 != null && array3.Length != num2)
			{
				Type elementType = array3.GetType().GetElementType();
				Array array4 = Array.CreateInstance(elementType, num2);
				int length = Math.Min(array3.Length, num2);
				Array.Copy(array3, array4, length);
				if (num2 > array3.Length)
				{
					for (int j = array3.Length; j < num2; j++)
					{
						object value = Activator.CreateInstance(elementType);
						array4.SetValue(value, j);
					}
				}
				__instance.hangSlots = Il2CppReferenceArray<ItemSlot>.op_Implicit((ItemSlot[])array4);
			}
			__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;
			}
			MelonLogger.Msg($" Before Growth Plant  {__instance.NormalizedGrowthProgress}");
			MelonLogger.Msg($" Add Growth Plant  {__instance.NormalizedGrowthProgress}");
			__instance.SetNormalizedGrowthProgress(__instance.NormalizedGrowthProgress + num);
			MelonLogger.Msg($" After Growth Plant {__instance.NormalizedGrowthProgress}");
			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)
			{
				MelonLogger.Msg($" Growth Shroom {__instance.GrowthProgress}");
				MelonLogger.Msg($" Before Shroom change {change}");
				change += change * GrowthSpeedUp.Add;
				MelonLogger.Msg($" After Shroom change {change}");
			}
		}
	}
	public static class QualityMushroomUP
	{
		public static float Add;
	}
	[HarmonyPatch(typeof(ShroomColony), "GetHarvestedShroom")]
	public static class MushroomQualityPatch
	{
		[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(120f);
					<>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>();

		[HarmonyPostfix]
		public static void Postfix(ShroomColony __instance, ref ShroomInstance __result)
		{
			if (!(QualityMushroomUP.Add <= 0f) && __result != null)
			{
				int instanceID = ((Object)__instance).GetInstanceID();
				if (!processedIds.Contains(instanceID))
				{
					float normalizedQuality = __instance.NormalizedQuality;
					__instance.ChangeQuality(QualityMushroomUP.Add);
					processedIds.Add(instanceID);
					float normalizedQuality2 = __instance.NormalizedQuality;
					MelonCoroutines.Start(CleanUp(instanceID));
				}
			}
		}

		[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 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.26f : (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
					{
						float num3 = 0f;
						Enumerator<AdditiveDefinition> enumerator = appliedAdditives.GetEnumerator();
						while (enumerator.MoveNext())
						{
							AdditiveDefinition current = enumerator.Current;
							if (!((Object)(object)current == (Object)null))
							{
								MelonLogger.Msg("Additive Name: " + ((ItemDefinition)current).Name.ToString().ToLower());
								if (current.InstantGrowth > 0f && __instance.NormalizedGrowthProgress < 0.5f)
								{
									float normalizedGrowthProgress = __instance.NormalizedGrowthProgress;
									__instance.SetNormalizedGrowthProgress(normalizedGrowthProgress + current.InstantGrowth);
									MelonLogger.Msg($"Instant growth applied: +{current.InstantGrowth} (from {normalizedGrowthProgress} to {__instance.NormalizedGrowthProgress})");
								}
								if (num2 < 0.27f && num2 > 0.17f)
								{
									num2 = 0.27f;
								}
							}
						}
					}
				}
			}
			__instance.QualityLevel = num2;
			MelonLogger.Msg($"[SkillTree] Plant Init: {text} | Final: {num2} | Skill: {QualityUP.Add} | Total: {__instance.QualityLevel}");
		}
	}
	[HarmonyPatch(typeof(Plant), "Initialize")]
	public static class Plant_Initialize_Patch
	{
		private static void Postfix(Plant __instance)
		{
			try
			{
				if (!AbsorbentSoil.Add)
				{
					return;
				}
				if ((Object)(object)__instance.Pot == (Object)null)
				{
					MelonLogger.Warning("Plant.Initialize Postfix: Pot is null");
					return;
				}
				List<AdditiveDefinition> appliedAdditives = ((GrowContainer)__instance.Pot).AppliedAdditives;
				if (appliedAdditives == null || appliedAdditives.Count == 0)
				{
					MelonLogger.Msg("No initial additives found for instant growth");
					return;
				}
				Enumerator<AdditiveDefinition> enumerator = appliedAdditives.GetEnumerator();
				while (enumerator.MoveNext())
				{
					AdditiveDefinition current = enumerator.Current;
					if (!((Object)(object)current == (Object)null) && current.InstantGrowth > 0f && __instance.NormalizedGrowthProgress < 0.5f)
					{
						float normalizedGrowthProgress = __instance.NormalizedGrowthProgress;
						__instance.SetNormalizedGrowthProgress(normalizedGrowthProgress + current.InstantGrowth);
						MelonLogger.Msg($"Instant growth applied: +{current.InstantGrowth} (from {normalizedGrowthProgress} to {__instance.NormalizedGrowthProgress})");
					}
				}
			}
			catch (Exception value)
			{
				MelonLogger.Error($"Plant.Initialize Postfix failed: {value}");
			}
		}
	}
	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)
			{
				float yieldMultiplier = __instance.YieldMultiplier;
				int baseYieldQuantity = __instance.BaseYieldQuantity;
				if (Mathf.Approximately(yieldMultiplier, 1f) && YieldAdd.Add != 0 && baseYieldQuantity == 12)
				{
					int value = (__instance.BaseYieldQuantity = baseYieldQuantity + YieldAdd.Add);
					MelonLogger.Msg($"[Skill More Yield] No additives detected. Skill applied. New Base: {value}");
				}
			}
		}
	}
	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_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Invalid comparison between Unknown and I4
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			if (__instance.CurrentOperation != null)
			{
				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.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;

		public static void ApplySkill(string skillId, SkillTreeData data)
		{
			localPlayer = Player.Local;
			playerMovement = PlayerSingleton<PlayerMovement>.Instance;
			registry = Singleton<Registry>.Instance;
			customerList = Il2CppArrayBase<Customer>.op_Implicit(Object.FindObjectsOfType<Customer>());
			dealerList = Il2CppArrayBase<Dealer>.op_Implicit(Object.FindObjectsOfType<Dealer>());
			businessList = Il2CppArrayBase<Business>.op_Implicit(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 = true;
				if ((Object)(object)registry == (Object)null)
				{
					break;
				}
				StackCache.FillCache(allItems);
				int num = 1 + data.MoreStackItem;
				Enumerator<ItemDefinition> enumerator = allItems.GetEnumerator();
				while (enumerator.MoveNext())
				{
					ItemDefinition current = enumerator.Current;
					string name = ((Object)current).name;
					if (StackCache.ItemStack.TryGetValue(name, out var value))
					{
						int stackLimit = current.StackLimit;
						current.StackLimit = value * num;
						MelonLogger.Msg($"[MoreStackItem] {name}: {value} -> {current.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 = true;
				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;
				break;
			case "MoreQualityMeth":
				MethQualityAdd.Add = data.MoreQualityMeth == 1;
				break;
			case "MoreQualityMushroom":
				QualityMushroomUP.Add = ((data.MoreQualityMushroom == 1) ? 0.3f : 0f);
				break;
			case "AbsorbentSoil":
				AbsorbentSoil.Add = data.AbsorbentSoil == 1;
				break;
			case "MoreMixAndDryingRackOutput":
				StackItem2xFix.Add = true;
				MixOutputAdd.Add = ((data.MoreMixAndDryingRackOutput * 2 == 0) ? 1 : (data.MoreMixAndDryingRackOutput * 2));
				break;
			case "ChemistStationQuick":
				StationTimeLess.TimeAjust = (((float)data.ChemistStationQuick * 1.5f == 0f) ? 1 : (data.ChemistStationQuick * 2));
				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 num3 = 1f + (float)data.CityEvolving * 0.1f;
				Customer[] array4 = customerList;
				foreach (Customer val4 in array4)
				{
					string name2 = ((Object)val4.CustomerData).name;
					if (CustomerCache.OriginalMinSpend.TryGetValue(name2, out var value3) && CustomerCache.OriginalMaxSpend.TryGetValue(name2, out var value4))
					{
						val4.CustomerData.MinWeeklySpend = value3 * num3;
						val4.CustomerData.MaxWeeklySpend = value4 * num3;
					}
				}
				MelonLogger.Msg($"Weekly spend incresed by {1f + (float)data.CityEvolving * 0.15f}%");
				break;
			}
			case "BusinessEvolving":
			{
				BusinessCache.FillCache(businessList.ToList());
				float num2 = 1f + (float)data.BusinessEvolving * 0.2f;
				Business[] array3 = businessList;
				foreach (Business val3 in array3)
				{
					string propertyName = ((Property)val3).PropertyName;
					if (BusinessCache.LaunderCapacity.TryGetValue(propertyName, out var value2))
					{
						float launderCapacity = val3.LaunderCapacity;
						val3.LaunderCapacity = value2 * num2;
						MelonLogger.Msg($"[BusinessEvolving] {propertyName}: {value2} -> {val3.LaunderCapacity}");
					}
				}
				MelonLogger.Msg($"LaunderCapacity incresed by {1f + (float)data.BusinessEvolving * 0.2f}%");
				break;
			}
			case "MoreATMLimit":
				ATMConfig.MaxWeeklyLimit = 10000f + (float)(data.MoreATMLimit * 1500);
				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}");
					}
				}
				break;
			}
			case "DealerSpeedUp":
			{
				Dealer[] array = dealerList;
				foreach (Dealer val in array)
				{
					if (ValidDealer(val))
					{
						float moveSpeedMultiplier = ((NPC)val).Movement.MoveSpeedMultiplier;
						((NPC)val).Movement.MoveSpeedMultiplier = 1f + (float)data.DealerSpeedUp;
						MelonLogger.Msg($"Dealer: {((Object)val).name} movespeed increase from {moveSpeedMultiplier}% to {((NPC)val).Movement.MoveSpeedMultiplier}");
					}
				}
				break;
			}
			case "DealerMoreCustomer":
				DealerUpCustomer.MaxCustomer += data.DealerMoreCustomer * 2;
				MelonLogger.Msg($"Dealer MaxCustomer: {DealerUpCustomer.MaxCustomer}");
				break;
			case "BetterSupplier":
				SupplierUp.SupplierInc = 1f + 1f * ((float)data.BetterSupplier * 0.675f);
				SupplierUp.SupplierLimit = (int)(10f + 10f * ((float)data.BetterSupplier * 0.5f));
				break;
			}
		}

		public static void ApplyAll(SkillTreeData data)
		{
			FieldInfo[] fields = typeof(SkillTreeData).GetFields(BindingFlags.Instance | BindingFlags.Public);
			foreach (FieldInfo fieldInfo in fields)
			{
				ApplySkill(fieldInfo.Name, data);
			}
		}

		private static bool ValidDealer(Dealer dealer)
		{
			if (((Object)dealer).name.ToLower().Contains("carteldealer"))
			{
				return false;
			}
			return true;
		}
	}
}