Decompiled source of MoreSkillTrees v1.0.0

BepInEx/plugins/MoreSkillTrees.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Sparroh")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("MoreSkillTrees")]
[assembly: AssemblyTitle("MoreSkillTrees")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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 MoreSkillTrees
{
	[HarmonyPatch(typeof(GearData), "AddXP")]
	internal static class GearDataAddXPPatch
	{
		private static void Prefix(GearData __instance, out int __state)
		{
			__state = __instance.Level;
		}

		private static void Postfix(GearData __instance, int __state)
		{
			try
			{
				int level = __instance.Level;
				if (level <= __state)
				{
					return;
				}
				IUpgradable gear = __instance.Gear;
				if (gear == null || gear is Character || (Object)(object)gear.Info == (Object)null || !gear.Info.CanGainXP)
				{
					return;
				}
				int num = level - __state;
				int num2 = 0;
				if (level <= __instance.MaxLevel)
				{
					num2 = ((level > 10) ? (num * 2) : num);
				}
				if (num2 > 0 && PlayerData.Instance != null && !((Object)(object)Global.Instance == (Object)null))
				{
					PlayerData.Instance.AddResource(Global.Instance.SkillPointResource, num2, true);
					ManualLogSource log = Plugin.Log;
					if (log != null)
					{
						log.LogInfo((object)($"[MoreSkillTrees] {gear.Info.Name} leveled {__state}->{level}, " + $"granted {num2} skill point(s)."));
					}
				}
			}
			catch (Exception arg)
			{
				ManualLogSource log2 = Plugin.Log;
				if (log2 != null)
				{
					log2.LogError((object)$"[MoreSkillTrees] AddXP postfix failed: {arg}");
				}
			}
		}
	}
	[HarmonyPatch(typeof(GearDetailsWindow))]
	internal static class GearDetailsWindowPatches
	{
		private static readonly FieldInfo SkillTreeButtonField = AccessTools.Field(typeof(GearDetailsWindow), "skillTreeButton");

		private static readonly FieldInfo SkillTreePointsTextField = AccessTools.Field(typeof(GearDetailsWindow), "skillTreePointsText");

		[HarmonyPostfix]
		[HarmonyPatch("Setup")]
		private static void Setup_Postfix(GearDetailsWindow __instance, IUpgradable upgradable)
		{
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (upgradable is Character)
				{
					return;
				}
				object? obj = SkillTreeButtonField?.GetValue(__instance);
				Component val = (Component)((obj is Component) ? obj : null);
				object? obj2 = SkillTreePointsTextField?.GetValue(__instance);
				Component val2 = (Component)((obj2 is Component) ? obj2 : null);
				bool flag = MoreSkillTreeData.HasTree(upgradable);
				if ((Object)(object)val != (Object)null)
				{
					val.gameObject.SetActive(flag);
				}
				if (!flag)
				{
					if ((Object)(object)val2 != (Object)null)
					{
						val2.gameObject.SetActive(false);
					}
					return;
				}
				int resource = PlayerData.Instance.GetResource(Global.Instance.SkillPointResource);
				bool flag2 = resource > 0 && HasAnyUnclaimedNode(upgradable);
				if ((Object)(object)val2 != (Object)null)
				{
					TextMeshProUGUI component = val2.GetComponent<TextMeshProUGUI>();
					if ((Object)(object)component != (Object)null)
					{
						if (flag2)
						{
							Color uIColor = Global.UIColor;
							((Graphic)component).color = uIColor;
							((TMP_Text)component).text = ((resource == 1) ? string.Format("{0} {1}", resource, TextBlocks.GetString("skillpoint", 0)) : string.Format("{0} {1}", resource, TextBlocks.GetString("skillpoints")));
							((Component)component).gameObject.SetActive(true);
						}
						else
						{
							((Component)component).gameObject.SetActive(false);
						}
					}
				}
				if (!((Object)(object)val != (Object)null))
				{
					return;
				}
				Graphic[] componentsInChildren = val.GetComponentsInChildren<Graphic>(true);
				foreach (Graphic val3 in componentsInChildren)
				{
					if (!((Object)(object)val3 == (Object)null))
					{
						if (flag2 && (Object)(object)Global.Instance.UIShimmerClipMat != (Object)null)
						{
							val3.material = Global.Instance.UIShimmerClipMat;
						}
						else
						{
							val3.material = null;
						}
						break;
					}
				}
			}
			catch (Exception arg)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogError((object)$"[MoreSkillTrees] GearDetails Setup postfix failed: {arg}");
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("ToggleSkillAndCraftingUI")]
		private static void ToggleSkillAndCraftingUI_Postfix(GearDetailsWindow __instance, bool enable)
		{
			try
			{
				IUpgradable upgradablePrefab = __instance.UpgradablePrefab;
				if (!(upgradablePrefab is Character) && upgradablePrefab != null)
				{
					object? obj = SkillTreeButtonField?.GetValue(__instance);
					Component val = (Component)((obj is Component) ? obj : null);
					object? obj2 = SkillTreePointsTextField?.GetValue(__instance);
					Component val2 = (Component)((obj2 is Component) ? obj2 : null);
					bool flag = enable && MoreSkillTreeData.HasTree(upgradablePrefab);
					if ((Object)(object)val != (Object)null)
					{
						val.gameObject.SetActive(flag);
					}
					if ((Object)(object)val2 != (Object)null)
					{
						int resource = PlayerData.Instance.GetResource(Global.Instance.SkillPointResource);
						bool active = flag && resource > 0 && HasAnyUnclaimedNode(upgradablePrefab);
						val2.gameObject.SetActive(active);
					}
				}
			}
			catch (Exception arg)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogError((object)$"[MoreSkillTrees] ToggleSkillAndCraftingUI postfix failed: {arg}");
				}
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch("ShowSkillTree")]
		private static bool ShowSkillTree_Prefix(GearDetailsWindow __instance)
		{
			try
			{
				IUpgradable upgradablePrefab = __instance.UpgradablePrefab;
				if (upgradablePrefab is Character)
				{
					return true;
				}
				if (!MoreSkillTreeData.HasTree(upgradablePrefab))
				{
					return false;
				}
				MoreSkillTreeUI.Open(__instance, upgradablePrefab);
				return false;
			}
			catch (Exception arg)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogError((object)$"[MoreSkillTrees] ShowSkillTree prefix failed: {arg}");
				}
				return true;
			}
		}

		private static bool HasAnyUnclaimedNode(IUpgradable gear)
		{
			MoreSkillTreeData.Tree tree = MoreSkillTreeData.FindTreeForGear(gear);
			if (tree == null)
			{
				return false;
			}
			List<ResolvedNode> list = MoreSkillTreeService.ResolveTree(gear, tree);
			for (int i = 0; i < list.Count; i++)
			{
				if (list[i].State == NodeState.Available || list[i].State == NodeState.CannotAfford)
				{
					return true;
				}
			}
			return false;
		}
	}
	public static class MoreSkillTreeData
	{
		public sealed class Branch
		{
			public readonly int Layer;

			public readonly string[] NodeNames;

			public Branch(int layer, params string[] nodeNames)
			{
				Layer = layer;
				NodeNames = nodeNames ?? Array.Empty<string>();
			}
		}

		public sealed class Tree
		{
			public readonly Branch[] Branches;

			public readonly string[] WeaponApiNames;

			public readonly string WeaponDisplayName;

			public Tree(string weaponDisplayName, string[] weaponApiNames, params Branch[] branches)
			{
				WeaponDisplayName = weaponDisplayName;
				WeaponApiNames = weaponApiNames ?? Array.Empty<string>();
				Branches = branches ?? Array.Empty<Branch>();
			}
		}

		private static Dictionary<string, Tree> _byDisplayName;

		public static int MinSpentForLayer(int layer)
		{
			if (layer <= 0)
			{
				return 0;
			}
			return 2 + (layer - 1) * 5;
		}

		public static bool TryGetTree(string weaponDisplayName, out Tree tree)
		{
			EnsureIndex();
			return _byDisplayName.TryGetValue(weaponDisplayName, out tree);
		}

		public static Tree FindTreeForGear(IUpgradable gear)
		{
			if ((Object)(object)((gear != null) ? gear.Info : null) == (Object)null)
			{
				return null;
			}
			EnsureIndex();
			string name = gear.Info.Name;
			if (!string.IsNullOrEmpty(name) && _byDisplayName.TryGetValue(name, out var value))
			{
				return value;
			}
			string aPIName = gear.Info.APIName;
			if (!string.IsNullOrEmpty(aPIName))
			{
				if (_byDisplayName.TryGetValue(aPIName, out var value2))
				{
					return value2;
				}
				string text = NameNormalize.Normalize(aPIName, stripRichTextTags: false);
				Tree[] allTrees = SkillTreeCatalog.AllTrees;
				foreach (Tree tree in allTrees)
				{
					if (NameNormalize.Normalize(tree.WeaponDisplayName, stripRichTextTags: false) == text)
					{
						return tree;
					}
					string[] weaponApiNames = tree.WeaponApiNames;
					foreach (string text2 in weaponApiNames)
					{
						if (string.Equals(text2, aPIName, StringComparison.OrdinalIgnoreCase))
						{
							return tree;
						}
						if (NameNormalize.Normalize(text2, stripRichTextTags: false) == text)
						{
							return tree;
						}
					}
				}
			}
			string name2 = ((object)gear).GetType().Name;
			if (!string.IsNullOrEmpty(name2))
			{
				string text3 = NameNormalize.Normalize(name2, stripRichTextTags: false);
				Tree[] allTrees = SkillTreeCatalog.AllTrees;
				foreach (Tree tree2 in allTrees)
				{
					if (NameNormalize.Normalize(tree2.WeaponDisplayName, stripRichTextTags: false) == text3)
					{
						return tree2;
					}
					string[] weaponApiNames = tree2.WeaponApiNames;
					for (int j = 0; j < weaponApiNames.Length; j++)
					{
						if (NameNormalize.Normalize(weaponApiNames[j], stripRichTextTags: false) == text3)
						{
							return tree2;
						}
					}
				}
			}
			return null;
		}

		public static bool HasTree(IUpgradable gear)
		{
			return FindTreeForGear(gear) != null;
		}

		private static void EnsureIndex()
		{
			if (_byDisplayName != null)
			{
				return;
			}
			_byDisplayName = new Dictionary<string, Tree>(StringComparer.OrdinalIgnoreCase);
			Tree[] allTrees = SkillTreeCatalog.AllTrees;
			foreach (Tree tree in allTrees)
			{
				_byDisplayName[tree.WeaponDisplayName] = tree;
				string[] weaponApiNames = tree.WeaponApiNames;
				foreach (string text in weaponApiNames)
				{
					if (!string.IsNullOrEmpty(text) && !_byDisplayName.ContainsKey(text))
					{
						_byDisplayName[text] = tree;
					}
				}
			}
			if (_byDisplayName.TryGetValue("Shock Grenade", out var value))
			{
				_byDisplayName["Voltaic Grenade"] = value;
			}
		}
	}
	public static class MoreSkillTreeService
	{
		private static readonly Dictionary<int, Dictionary<string, Upgrade>> UpgradeCache = new Dictionary<int, Dictionary<string, Upgrade>>();

		private static readonly HashSet<string> LoggedMissing = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

		public static ManualLogSource Log { get; set; }

		public static bool IsClaimed(IUpgradable gear, Upgrade upgrade)
		{
			if (gear == null || (Object)(object)upgrade == (Object)null)
			{
				return false;
			}
			UpgradeInfo upgradeInfo = PlayerData.GetUpgradeInfo(gear, upgrade);
			if (upgradeInfo != null)
			{
				return upgradeInfo.TotalInstancesCollected > 0;
			}
			return false;
		}

		public static int GetMinSpentForLayer(int layer)
		{
			return MoreSkillTreeData.MinSpentForLayer(layer);
		}

		public static bool IsLayerUnlocked(int layer)
		{
			if (PlayerData.Instance == null)
			{
				return false;
			}
			return PlayerData.Instance.TotalSkillPointsSpent >= GetMinSpentForLayer(layer);
		}

		public static NodeState GetNodeState(IUpgradable gear, Upgrade upgrade, int layer)
		{
			if ((Object)(object)upgrade == (Object)null)
			{
				return NodeState.Unresolved;
			}
			if (IsClaimed(gear, upgrade))
			{
				return NodeState.Claimed;
			}
			if (!IsLayerUnlocked(layer))
			{
				return NodeState.LayerLocked;
			}
			if (PlayerData.Instance.GetResource(Global.Instance.SkillPointResource) <= 0)
			{
				return NodeState.CannotAfford;
			}
			return NodeState.Available;
		}

		public static bool TryUnlock(IUpgradable gear, Upgrade upgrade, int layer, out string message)
		{
			message = null;
			if (gear == null || (Object)(object)upgrade == (Object)null)
			{
				message = "Invalid upgrade.";
				return false;
			}
			if (IsClaimed(gear, upgrade))
			{
				message = "Already owned.";
				return true;
			}
			if (!IsLayerUnlocked(layer))
			{
				int num = GetMinSpentForLayer(layer) - PlayerData.Instance.TotalSkillPointsSpent;
				message = $"Spend {num} more skill point(s) first.";
				return false;
			}
			if (!PlayerData.Instance.TryRemoveResources(Global.Instance.SkillPointUnlockCost))
			{
				message = "Not enough skill points.";
				return false;
			}
			UpgradeInstance val = PlayerData.CollectInstance(gear, upgrade, (UnlockFlags)0);
			if (val != null)
			{
				val.Seed = upgrade.NumberID;
				val.Unlock(false);
			}
			PlayerData instance = PlayerData.Instance;
			int totalSkillPointsSpent = instance.TotalSkillPointsSpent;
			instance.TotalSkillPointsSpent = totalSkillPointsSpent + 1;
			message = "Unlocked.";
			ManualLogSource log = Log;
			if (log != null)
			{
				string[] obj = new string[6] { "[MoreSkillTrees] Unlocked '", upgrade.Name, "' on '", null, null, null };
				GearInfo info = gear.Info;
				obj[3] = ((info != null) ? info.Name : null);
				obj[4] = "' ";
				obj[5] = $"(spent total now {PlayerData.Instance.TotalSkillPointsSpent}).";
				log.LogInfo((object)string.Concat(obj));
			}
			return true;
		}

		public static List<ResolvedNode> ResolveTree(IUpgradable gear, MoreSkillTreeData.Tree tree)
		{
			List<ResolvedNode> list = new List<ResolvedNode>();
			if (gear == null || tree == null)
			{
				return list;
			}
			Dictionary<string, Upgrade> upgradeMap = GetUpgradeMap(gear);
			MoreSkillTreeData.Branch[] branches = tree.Branches;
			foreach (MoreSkillTreeData.Branch branch in branches)
			{
				string[] nodeNames = branch.NodeNames;
				foreach (string text in nodeNames)
				{
					upgradeMap.TryGetValue(NameNormalize.Normalize(text), out var value);
					if ((Object)(object)value == (Object)null)
					{
						value = FuzzyFind(upgradeMap, text);
					}
					if ((Object)(object)value == (Object)null && LoggedMissing.Add(tree.WeaponDisplayName + "::" + text))
					{
						ManualLogSource log = Log;
						if (log != null)
						{
							string[] obj = new string[7] { "[MoreSkillTrees] Could not resolve '", text, "' on '", null, null, null, null };
							GearInfo info = gear.Info;
							obj[3] = ((info != null) ? info.Name : null);
							obj[4] = "' (API: ";
							GearInfo info2 = gear.Info;
							obj[5] = ((info2 != null) ? info2.APIName : null);
							obj[6] = ").";
							log.LogWarning((object)string.Concat(obj));
						}
					}
					ResolvedNode item = new ResolvedNode
					{
						DisplayName = text,
						Layer = branch.Layer,
						Upgrade = value,
						MinSpentRequired = GetMinSpentForLayer(branch.Layer),
						State = (((Object)(object)value == (Object)null) ? NodeState.Unresolved : GetNodeState(gear, value, branch.Layer))
					};
					list.Add(item);
				}
			}
			return list;
		}

		public static void RefreshStates(IUpgradable gear, List<ResolvedNode> nodes)
		{
			if (nodes == null)
			{
				return;
			}
			foreach (ResolvedNode node in nodes)
			{
				if ((Object)(object)node.Upgrade == (Object)null)
				{
					node.State = NodeState.Unresolved;
				}
				else
				{
					node.State = GetNodeState(gear, node.Upgrade, node.Layer);
				}
			}
		}

		public static Upgrade FindUpgrade(IUpgradable gear, string displayName)
		{
			if (gear == null || string.IsNullOrEmpty(displayName))
			{
				return null;
			}
			Dictionary<string, Upgrade> upgradeMap = GetUpgradeMap(gear);
			if (upgradeMap.TryGetValue(NameNormalize.Normalize(displayName), out var value))
			{
				return value;
			}
			return FuzzyFind(upgradeMap, displayName);
		}

		public static void ClearCache()
		{
			UpgradeCache.Clear();
		}

		private static Dictionary<string, Upgrade> GetUpgradeMap(IUpgradable gear)
		{
			int iD = gear.Info.ID;
			if (UpgradeCache.TryGetValue(iD, out var value))
			{
				return value;
			}
			Dictionary<string, Upgrade> dictionary = new Dictionary<string, Upgrade>(StringComparer.OrdinalIgnoreCase);
			List<Upgrade> upgrades = gear.Info.Upgrades;
			if (upgrades != null)
			{
				for (int i = 0; i < upgrades.Count; i++)
				{
					Upgrade val = upgrades[i];
					if (!((Object)(object)val == (Object)null) && !val.IsSkin())
					{
						AddKey(dictionary, val.Name, val);
						AddKey(dictionary, val.APIName, val);
						AddKey(dictionary, NameNormalize.Normalize(val.Name), val);
						AddKey(dictionary, NameNormalize.Normalize(val.APIName), val);
					}
				}
			}
			UpgradeCache[iD] = dictionary;
			return dictionary;
		}

		private static void AddKey(Dictionary<string, Upgrade> map, string key, Upgrade u)
		{
			if (!string.IsNullOrEmpty(key))
			{
				if (!map.ContainsKey(key))
				{
					map[key] = u;
				}
				string key2 = NameNormalize.Normalize(key);
				if (!map.ContainsKey(key2))
				{
					map[key2] = u;
				}
			}
		}

		private static Upgrade FuzzyFind(Dictionary<string, Upgrade> map, string displayName)
		{
			string text = NameNormalize.Normalize(displayName);
			Upgrade result = null;
			foreach (KeyValuePair<string, Upgrade> item in map)
			{
				string text2 = NameNormalize.Normalize(item.Key);
				if (text2 == text)
				{
					return item.Value;
				}
				if (text2.Contains(text) || text.Contains(text2))
				{
					result = item.Value;
				}
			}
			return result;
		}
	}
	public class MoreSkillTreeUI : MonoBehaviour
	{
		private static MoreSkillTreeUI _instance;

		private readonly List<SkillTreeNodeButton> _buttons = new List<SkillTreeNodeButton>();

		private Transform _content;

		private IUpgradable _gear;

		private List<ResolvedNode> _nodes;

		private GearDetailsWindow _parentWindow;

		private TextMeshProUGUI _pointsText;

		private RectTransform _root;

		private TextMeshProUGUI _statusText;

		private TextMeshProUGUI _titleText;

		private MoreSkillTreeData.Tree _tree;

		private void Update()
		{
			if (((Component)this).gameObject.activeSelf)
			{
				Keyboard current = Keyboard.current;
				if (current != null && ((ButtonControl)current.escapeKey).wasPressedThisFrame)
				{
					Hide();
				}
			}
		}

		public static void Open(GearDetailsWindow parent, IUpgradable gear)
		{
			//IL_0044: 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_0059: Expected O, but got Unknown
			MoreSkillTreeData.Tree tree = MoreSkillTreeData.FindTreeForGear(gear);
			if (tree == null)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogWarning((object)"[MoreSkillTrees] Open called with no tree.");
				}
				return;
			}
			if ((Object)(object)_instance == (Object)null)
			{
				GameObject val = new GameObject("MoreSkillTreeUI", new Type[1] { typeof(RectTransform) });
				_instance = val.AddComponent<MoreSkillTreeUI>();
				Object.DontDestroyOnLoad((Object)val);
				_instance.BuildShell();
			}
			_instance._parentWindow = parent;
			_instance._gear = gear;
			_instance._tree = tree;
			_instance._nodes = MoreSkillTreeService.ResolveTree(gear, tree);
			_instance.Show();
		}

		public static void CloseIfOpen()
		{
			if ((Object)(object)_instance != (Object)null && ((Component)_instance).gameObject.activeSelf)
			{
				_instance.Hide();
			}
		}

		private void BuildShell()
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Expected O, but got Unknown
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_020e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_0238: Unknown result type (might be due to invalid IL or missing references)
			//IL_024c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0288: Unknown result type (might be due to invalid IL or missing references)
			//IL_029d: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02db: Unknown result type (might be due to invalid IL or missing references)
			//IL_0317: Unknown result type (might be due to invalid IL or missing references)
			//IL_032c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0341: Unknown result type (might be due to invalid IL or missing references)
			//IL_0356: Unknown result type (might be due to invalid IL or missing references)
			//IL_036a: Unknown result type (might be due to invalid IL or missing references)
			//IL_038e: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_0402: Unknown result type (might be due to invalid IL or missing references)
			//IL_042d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0455: Unknown result type (might be due to invalid IL or missing references)
			//IL_045f: Expected O, but got Unknown
			//IL_04a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_04df: Unknown result type (might be due to invalid IL or missing references)
			//IL_053d: Unknown result type (might be due to invalid IL or missing references)
			//IL_057b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0591: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c9: 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_0087: Expected O, but got Unknown
			GameObject gameObject = ((Component)this).gameObject;
			Canvas obj = gameObject.AddComponent<Canvas>();
			obj.renderMode = (RenderMode)0;
			obj.sortingOrder = 5000;
			gameObject.AddComponent<CanvasScaler>().uiScaleMode = (ScaleMode)1;
			gameObject.GetComponent<CanvasScaler>().referenceResolution = new Vector2(1920f, 1080f);
			gameObject.AddComponent<GraphicRaycaster>();
			if ((Object)(object)EventSystem.current == (Object)null)
			{
				Object.DontDestroyOnLoad((Object)new GameObject("EventSystem", new Type[2]
				{
					typeof(EventSystem),
					typeof(StandaloneInputModule)
				}));
			}
			_root = gameObject.GetComponent<RectTransform>();
			_root.anchorMin = Vector2.zero;
			_root.anchorMax = Vector2.one;
			_root.offsetMin = Vector2.zero;
			_root.offsetMax = Vector2.zero;
			RectTransform obj2 = SkillTreeUIHelpers.CreateUIObject("Dim", (Transform)(object)_root);
			((Graphic)((Component)obj2).gameObject.AddComponent<Image>()).color = new Color(0f, 0f, 0f, 0.72f);
			SkillTreeUIHelpers.Stretch(obj2);
			Button obj3 = ((Component)obj2).gameObject.AddComponent<Button>();
			((Selectable)obj3).transition = (Transition)0;
			((UnityEvent)obj3.onClick).AddListener(new UnityAction(Hide));
			RectTransform val = SkillTreeUIHelpers.CreateUIObject("Panel", (Transform)(object)_root);
			val.anchorMin = new Vector2(0.5f, 0.5f);
			val.anchorMax = new Vector2(0.5f, 0.5f);
			val.pivot = new Vector2(0.5f, 0.5f);
			val.sizeDelta = new Vector2(1100f, 720f);
			((Graphic)((Component)val).gameObject.AddComponent<Image>()).color = new Color(0.07f, 0.08f, 0.1f, 0.97f);
			_titleText = SkillTreeUIHelpers.CreateText((Transform)(object)val, "Title", 32f, (FontStyles)1, (TextAlignmentOptions)514);
			RectTransform rectTransform = ((TMP_Text)_titleText).rectTransform;
			rectTransform.anchorMin = new Vector2(0f, 1f);
			rectTransform.anchorMax = new Vector2(1f, 1f);
			rectTransform.pivot = new Vector2(0.5f, 1f);
			rectTransform.anchoredPosition = new Vector2(0f, -16f);
			rectTransform.sizeDelta = new Vector2(-40f, 44f);
			_pointsText = SkillTreeUIHelpers.CreateText((Transform)(object)val, "Points", 22f, (FontStyles)0, (TextAlignmentOptions)514);
			RectTransform rectTransform2 = ((TMP_Text)_pointsText).rectTransform;
			rectTransform2.anchorMin = new Vector2(0f, 1f);
			rectTransform2.anchorMax = new Vector2(1f, 1f);
			rectTransform2.pivot = new Vector2(0.5f, 1f);
			rectTransform2.anchoredPosition = new Vector2(0f, -58f);
			rectTransform2.sizeDelta = new Vector2(-40f, 30f);
			_statusText = SkillTreeUIHelpers.CreateText((Transform)(object)val, "Status", 18f, (FontStyles)2, (TextAlignmentOptions)514);
			RectTransform rectTransform3 = ((TMP_Text)_statusText).rectTransform;
			rectTransform3.anchorMin = new Vector2(0f, 0f);
			rectTransform3.anchorMax = new Vector2(1f, 0f);
			rectTransform3.pivot = new Vector2(0.5f, 0f);
			rectTransform3.anchoredPosition = new Vector2(0f, 12f);
			rectTransform3.sizeDelta = new Vector2(-40f, 28f);
			((Graphic)_statusText).color = new Color(0.75f, 0.75f, 0.75f, 1f);
			RectTransform obj4 = SkillTreeUIHelpers.CreateUIObject("Close", (Transform)(object)val);
			obj4.anchorMin = new Vector2(1f, 1f);
			obj4.anchorMax = new Vector2(1f, 1f);
			obj4.pivot = new Vector2(1f, 1f);
			obj4.anchoredPosition = new Vector2(-10f, -10f);
			obj4.sizeDelta = new Vector2(40f, 40f);
			Image val2 = ((Component)obj4).gameObject.AddComponent<Image>();
			((Graphic)val2).color = new Color(0.35f, 0.12f, 0.12f, 1f);
			Button obj5 = ((Component)obj4).gameObject.AddComponent<Button>();
			((Selectable)obj5).targetGraphic = (Graphic)(object)val2;
			((UnityEvent)obj5.onClick).AddListener(new UnityAction(Hide));
			TextMeshProUGUI obj6 = SkillTreeUIHelpers.CreateText((Transform)(object)obj4, "X", 22f, (FontStyles)1, (TextAlignmentOptions)514);
			SkillTreeUIHelpers.Stretch(((TMP_Text)obj6).rectTransform);
			((TMP_Text)obj6).text = "X";
			RectTransform val3 = SkillTreeUIHelpers.CreateUIObject("Scroll", (Transform)(object)val);
			val3.anchorMin = new Vector2(0f, 0f);
			val3.anchorMax = new Vector2(1f, 1f);
			val3.offsetMin = new Vector2(20f, 50f);
			val3.offsetMax = new Vector2(-20f, -100f);
			ScrollRect obj7 = ((Component)val3).gameObject.AddComponent<ScrollRect>();
			obj7.horizontal = true;
			obj7.vertical = true;
			obj7.movementType = (MovementType)2;
			RectTransform val4 = SkillTreeUIHelpers.CreateUIObject("Viewport", (Transform)(object)val3);
			SkillTreeUIHelpers.Stretch(val4);
			((Graphic)((Component)val4).gameObject.AddComponent<Image>()).color = new Color(1f, 1f, 1f, 0.02f);
			((Component)val4).gameObject.AddComponent<Mask>().showMaskGraphic = false;
			obj7.viewport = val4;
			RectTransform val5 = SkillTreeUIHelpers.CreateUIObject("Content", (Transform)(object)val4);
			val5.anchorMin = new Vector2(0f, 1f);
			val5.anchorMax = new Vector2(0f, 1f);
			val5.pivot = new Vector2(0f, 1f);
			val5.anchoredPosition = Vector2.zero;
			val5.sizeDelta = new Vector2(1040f, 560f);
			obj7.content = val5;
			_content = (Transform)(object)val5;
			((Component)this).gameObject.SetActive(false);
		}

		private void Show()
		{
			RebuildNodes();
			RefreshHeader();
			((Component)this).gameObject.SetActive(true);
			((TMP_Text)_statusText).text = "Click a node to unlock. Owned upgrades are free. Still equip on hex grid.";
		}

		private void Hide()
		{
			((Component)this).gameObject.SetActive(false);
		}

		private void RefreshHeader()
		{
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			IUpgradable gear = _gear;
			object obj;
			if (gear == null)
			{
				obj = null;
			}
			else
			{
				GearInfo info = gear.Info;
				obj = ((info != null) ? info.Name : null);
			}
			if (obj == null)
			{
				obj = _tree.WeaponDisplayName;
			}
			string text = (string)obj;
			((TMP_Text)_titleText).text = text + " Skill Tree";
			int num = ((PlayerData.Instance != null) ? PlayerData.Instance.GetResource(Global.Instance.SkillPointResource) : 0);
			PlayerData instance = PlayerData.Instance;
			int num2 = ((instance != null) ? instance.TotalSkillPointsSpent : 0);
			((TMP_Text)_pointsText).text = $"Skill Points: {num}   |   Total Spent: {num2}   |   Branch locks: 0 / 2 / 7";
			((Graphic)_pointsText).color = ((num > 0) ? new Color(0.55f, 0.9f, 1f) : new Color(0.7f, 0.7f, 0.7f));
		}

		private void RebuildNodes()
		{
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_030b: 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_022e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			//IL_0290: Unknown result type (might be due to invalid IL or missing references)
			//IL_029a: Expected O, but got Unknown
			for (int num = _content.childCount - 1; num >= 0; num--)
			{
				Object.Destroy((Object)(object)((Component)_content.GetChild(num)).gameObject);
			}
			_buttons.Clear();
			Dictionary<int, List<ResolvedNode>> dictionary = new Dictionary<int, List<ResolvedNode>>();
			foreach (ResolvedNode node in _nodes)
			{
				if (!dictionary.TryGetValue(node.Layer, out var value))
				{
					value = new List<ResolvedNode>();
					dictionary[node.Layer] = value;
				}
				value.Add(node);
			}
			int num2 = 0;
			foreach (KeyValuePair<int, List<ResolvedNode>> item2 in dictionary)
			{
				if (item2.Value.Count > num2)
				{
					num2 = item2.Value.Count;
				}
			}
			int num3 = 0;
			foreach (int item3 in SortedLayers(dictionary.Keys))
			{
				float num4 = 10f + (float)num3 * 360f;
				List<ResolvedNode> list = dictionary[item3];
				Transform content = _content;
				TextMeshProUGUI obj = SkillTreeUIHelpers.CreateText((content is RectTransform) ? content : null, $"Branch {item3 + 1}", 20f, (FontStyles)1, (TextAlignmentOptions)514);
				RectTransform rectTransform = ((TMP_Text)obj).rectTransform;
				rectTransform.anchorMin = new Vector2(0f, 1f);
				rectTransform.anchorMax = new Vector2(0f, 1f);
				rectTransform.pivot = new Vector2(0f, 1f);
				rectTransform.anchoredPosition = new Vector2(num4, -10f);
				rectTransform.sizeDelta = new Vector2(340f, 36f);
				int num5 = MoreSkillTreeData.MinSpentForLayer(item3);
				bool flag = MoreSkillTreeService.IsLayerUnlocked(item3);
				((TMP_Text)obj).text = (flag ? $"Branch {item3 + 1}" : $"Branch {item3 + 1}  (need {num5} spent)");
				((Graphic)obj).color = (Color)(flag ? Color.white : new Color(1f, 1f, 1f, 0.35f));
				for (int i = 0; i < list.Count; i++)
				{
					float y = -54f - (float)i * 72f;
					ResolvedNode captured = list[i];
					SkillTreeNodeButton item = SkillTreeUIHelpers.CreateNodeButton(_content, captured, num4, y, 340f, 64f, (UnityAction)delegate
					{
						OnNodeClicked(captured);
					});
					_buttons.Add(item);
				}
				num3++;
			}
			float num6 = 10f + (float)num3 * 360f + 10f;
			float num7 = 56f + (float)num2 * 72f + 20f;
			((RectTransform)_content).sizeDelta = new Vector2(Mathf.Max(num6, 1040f), Mathf.Max(num7, 560f));
		}

		private void OnNodeClicked(ResolvedNode node)
		{
			if ((Object)(object)node.Upgrade == (Object)null)
			{
				((TMP_Text)_statusText).text = "Could not resolve '" + node.DisplayName + "' to an upgrade.";
				return;
			}
			node.State = MoreSkillTreeService.GetNodeState(_gear, node.Upgrade, node.Layer);
			if (node.State == NodeState.Claimed)
			{
				((TMP_Text)_statusText).text = "'" + node.Upgrade.Name + "' is already owned.";
				RefreshAll();
				return;
			}
			if (node.State != NodeState.Available)
			{
				((TMP_Text)_statusText).text = ((node.State == NodeState.LayerLocked) ? $"Branch locked. Need {node.MinSpentRequired} total skill points spent." : "Not enough skill points.");
				RefreshAll();
				return;
			}
			if (MoreSkillTreeService.TryUnlock(_gear, node.Upgrade, node.Layer, out var message))
			{
				((TMP_Text)_statusText).text = "Unlocked " + node.Upgrade.Name + ". Equip it on the hex grid to use.";
			}
			else
			{
				((TMP_Text)_statusText).text = message ?? "Unlock failed.";
			}
			RefreshAll();
		}

		private void RefreshAll()
		{
			MoreSkillTreeService.RefreshStates(_gear, _nodes);
			RebuildNodes();
			RefreshHeader();
		}

		private static List<int> SortedLayers(IEnumerable<int> keys)
		{
			List<int> list = new List<int>(keys);
			list.Sort();
			return list;
		}
	}
	internal static class NameNormalize
	{
		public static string Normalize(string s, bool stripRichTextTags = true)
		{
			if (string.IsNullOrEmpty(s))
			{
				return string.Empty;
			}
			char[] array = new char[s.Length];
			int length = 0;
			bool flag = false;
			foreach (char c in s)
			{
				if (stripRichTextTags)
				{
					switch (c)
					{
					case '<':
						flag = true;
						continue;
					case '>':
						flag = false;
						continue;
					}
					if (flag)
					{
						continue;
					}
				}
				if (char.IsLetterOrDigit(c))
				{
					array[length++] = char.ToLowerInvariant(c);
				}
			}
			return new string(array, 0, length);
		}
	}
	public enum NodeState
	{
		Claimed,
		LayerLocked,
		Available,
		CannotAfford,
		Unresolved
	}
	public sealed class ResolvedNode
	{
		public string DisplayName;

		public int Layer;

		public int MinSpentRequired;

		public NodeState State;

		public Upgrade Upgrade;
	}
	[BepInPlugin("sparroh.moreskilltrees", "MoreSkillTrees", "1.0.0")]
	[MycoMod(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public const string PluginGUID = "sparroh.moreskilltrees";

		public const string PluginName = "MoreSkillTrees";

		public const string PluginVersion = "1.0.0";

		internal static ManualLogSource Log;

		private Harmony _harmony;

		private void Awake()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			MoreSkillTreeService.Log = ((BaseUnityPlugin)this).Logger;
			try
			{
				_harmony = new Harmony("sparroh.moreskilltrees");
				_harmony.PatchAll(typeof(Plugin).Assembly);
				Log.LogInfo((object)"MoreSkillTrees v1.0.0 loaded.");
			}
			catch (Exception arg)
			{
				Log.LogError((object)$"Failed to patch: {arg}");
			}
		}

		private void OnDestroy()
		{
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}
	}
	public static class SkillTreeCatalog
	{
		public static readonly MoreSkillTreeData.Tree[] AllTrees = new MoreSkillTreeData.Tree[16]
		{
			new MoreSkillTreeData.Tree("Cycler", new string[4] { "cycler", "cartridgesmg", "cartridge_smg", "smg" }, new MoreSkillTreeData.Branch(0, "Bigazine", "Bulging Cartridge", "Doublestack Cartridge", "Compact Cartridge", "Mass Acceleration", "Dump Charge", "Infinity Burn", "Cycling Repairs", "Equipment Siphon", "Extralight Frame"), new MoreSkillTreeData.Branch(1, "Charged Cartridges", "Corrosive Plasma", "Heated Battery", "Decay Energy", "Intense Reaction", "Superheat Reaction", "Toxin Recycling", "Corrode Siphon", "Shock Recursion", "Scorching Detonation", "Violent Ignition", "Energy Convergence"), new MoreSkillTreeData.Branch(2, "Adrenaline Reload", "Smart Slide", "Rocket Burst", "Full Range", "Focused Lenses", "Precision Fire", "Stability Module", "Charge Shield", "Elemental Discharge", "Condensed Ejection", "Overclocked Firing Mechanism", "Double Shot", "Ricochet", "Momentum Overload")),
			new MoreSkillTreeData.Tree("Jackrabbit", new string[4] { "jackrabbit", "bounceshotgun", "bounce_shotgun", "shotgun" }, new MoreSkillTreeData.Branch(0, "Reinforced Coating", "Power Ricochet", "Friction Compensators", "Ghosting", "Opening Charge", "Shell Packer", "Double Barrel", "Double Time", "Slam Fire", "Pummeler"), new MoreSkillTreeData.Branch(1, "Melting Point", "Wild Fire", "Heavy", "Hot Potato", "Hot Reload", "Reactive Coating", "Fire In My Heart", "Stand the Heat", "Immolator", "Molotov", "Pesticide", "Delicious Cores"), new MoreSkillTreeData.Branch(2, "Mag Extender", "Simplest Solution", "Focus Spread", "Steadier Aim", "Steady Aim", "Stable Grip", "Slideshot", "All Powdered Up")),
			new MoreSkillTreeData.Tree("Swarm Launcher", new string[4] { "swarmgun", "swarm_launcher", "swarmlauncher", "swarm" }, new MoreSkillTreeData.Branch(0, "Autoswarm", "Guidance Array", "Remote Control", "Wait Charging", "High Caliber Pellets", "Quick Grouping", "Scatterburst", "Explosive Pellets", "Electrified Pellets", "Mitosis"), new MoreSkillTreeData.Branch(1, "Atmospheric Energizers", "Large Energy Storage", "Swarm Reserves", "The Hive Must Grow", "Tool for the Job", "Breeding Season", "Cross Pollination", "Portable Solar Array", "Munition Siphon"), new MoreSkillTreeData.Branch(2, "Blitz Planting", "Quick Release", "Migration", "Crop Duster", "Power Redistribution", "Over Extended", "Sprinkler", "Tight Planting", "Rapid Pollination", "Precise Targeting", "Static Reload", "Overload Contingency")),
			new MoreSkillTreeData.Tree("DMLR", new string[4] { "dmlr", "chargesniper", "charge_sniper", "sniper" }, new MoreSkillTreeData.Branch(0, "Heavy Hitting", "Kinetic Amplifier", "Shredder", "Trifecta", "Triple", "Long Scope", "Overcharge Cycling", "Aux Reserves", "Quickswap Cartridge"), new MoreSkillTreeData.Branch(1, "Beam Amplifier", "Feedback Amplifier", "Rapid Charge", "Coronal Ejection", "Two Way Charging", "Arc Lightning", "Concussive Wave", "Power Core", "Hard-Light Bypass", "Corrosive Laser", "Incendiary Laser", "Shocking Laser", "Tainted Exhaust"), new MoreSkillTreeData.Branch(2, "Hot Swap", "Autocycler", "Kinetic Impossibility", "Photon Surge", "Sturdy", "Engineering Nanites", "Assist Charge", "Hazard Recycling", "Reorganized Reserves", "Voltaic Battery", "Demonstrator's Trick")),
			new MoreSkillTreeData.Tree("Lead Flinger", new string[3] { "leadflinger", "lead_flinger", "revolver" }, new MoreSkillTreeData.Branch(0, "Hallucinated Space", "Bandolier", "Feeling Lucky", "Self Storage", "Practice Makes Perfect", "Fresh Bullet Frenzy", "Modded Auto", "Phantom Limb", "Lucky Bastard", "Lucky Last"), new MoreSkillTreeData.Branch(1, "Lead Poisoning", "High Caliber", "Just Add More Gunpowder", "Fan Fire", "Shrapnel Loading", "Double Action", "Big Fat Doobie", "Residue", "Volatile Munitions", "Blood-Rush", "Juiced Up"), new MoreSkillTreeData.Branch(2, "Adrenaline Rush", "Delirium", "Outlaw", "Ride the High", "Burning Tips", "Chemical Symbiosis", "Controlled Substance", "Home Cooking", "Ralph's Conundrum", "Unnatural Focus", "Breathe Deep")),
			new MoreSkillTreeData.Tree("Plate Launcher", new string[3] { "platelauncher", "plate_launcher", "plate" }, new MoreSkillTreeData.Branch(0, "Aerodynamic Plates", "Rail-Tuning", "Weight Rebalanced", "Simple Inertia", "Tungsten Cube", "Sharper Edges", "Shish Kebab", "Decay Plates", "Electrified Plates", "Bouncy Plates", "Salad Plates"), new MoreSkillTreeData.Branch(1, "Pole Alignment", "Power Recall", "Auto-Demolition", "Compressed Plate Storage", "Fencing Construction", "Damage Arc", "Clearing Plasma", "Becall", "Shockwave", "Improvised Explosives"), new MoreSkillTreeData.Branch(2, "Double A", "Storage Surplus", "High Ground", "Impulse Redirection", "Nice Catch", "Charge Recycling", "Painter's Attachment", "Slap-Job")),
			new MoreSkillTreeData.Tree("Gunship Cannon", new string[4] { "gunshipcannon", "gunship_cannon", "gunship", "minigun" }, new MoreSkillTreeData.Branch(0, "Industrial Feed Mechanism", "Overclocked Firing Chamber", "Thumper", "Safety \"Regulations\"", "Frantic Fingers", "Adaptive Stabilizers", "Stabilizers", "Blowback Redirect", "Magnetic Loader", "Cargo Storage"), new MoreSkillTreeData.Branch(1, "Higher Caliber", "Heavy Munitions", "Hull Piercer", "Point Demolition", "Elemental Munitions", "Missile Bay", "Ballistic Charger", "Tinderbox", "Drag Caps", "Sawed Off"), new MoreSkillTreeData.Branch(2, "Gunship", "Firmly Planted", "Hold-Plating", "Unarmored", "Lagrange Halo", "Hard Ricochet")),
			new MoreSkillTreeData.Tree("Trident", new string[1] { "trident" }, new MoreSkillTreeData.Branch(0, "Compressed Ammunition", "Increased Load", "Top Deck Storage", "Squadron", "Broadside", "Lone Cannoneer", "Gunner's Precision", "Energy Condenser", "Shredify", "Ungovernable"), new MoreSkillTreeData.Branch(1, "Fire Shot", "Acid Shot", "Fire in the Hold", "Corrosive Reaction", "Rot Advantage", "Heaven's Fury", "Compatible Ammunition", "Plunder", "Gunpowder Finale"), new MoreSkillTreeData.Branch(2, "Cargo Hold", "Bottom Heavy", "Discount Marksman", "Spyglass", "Line er' Up", "Cross-Deck", "Tailwind", "Hornet Hunting", "Thrill of the Fight", "Bailing Water", "Tread the Line")),
			new MoreSkillTreeData.Tree("Globbler", new string[3] { "globbler", "acidthrower", "acid_thrower" }, new MoreSkillTreeData.Branch(0, "Forceful Expulsion", "Gunpowder Packing", "Heavy Globs", "Instant Detonation", "The Glob", "Triagon", "Volatile Acid", "Glob Balloons", "Flood", "Flash Flood"), new MoreSkillTreeData.Branch(1, "Auto-Replicator", "Glorb", "Improved Replication", "Globulous Excitement", "Globulous Siphon", "Pressure Cooker", "Impact Funnel", "Volatile Element", "Replicator Resistance"), new MoreSkillTreeData.Branch(2, "Pocket Replication", "Slipper Shoes", "Full Spectrum", "Pack Eater", "Shrunken Container")),
			new MoreSkillTreeData.Tree("Carver", new string[1] { "carver" }, new MoreSkillTreeData.Branch(0, "Aim For The Liver", "Swinging Technique", "Blade Extenders", "Overheat System", "Safety Warning", "Rush", "Blood Rampage", "Rage"), new MoreSkillTreeData.Branch(1, "Blood Efficiency", "Blood Bucket", "Blood Coating", "Bloody Jumping", "Slippery Blood", "Blood Lightning", "Super Magnet", "Lockdown"), new MoreSkillTreeData.Branch(2, "Deflector", "Big Deflector", "Nutrition Sampler", "Sharing Lunch", "Repairing Exhaust", "Ignition Recharge", "Shocking Adrenaline", "Corrosive Coating", "Additional RAM Stick", "RAM Storage", "Greedy Fuck", "Heavy Pockets")),
			new MoreSkillTreeData.Tree("Shocklance", new string[2] { "shocklance", "shock_lance" }, new MoreSkillTreeData.Branch(0, "Skewer", "Swing Through", "Railshot", "Splintered Lance", "Compressor", "Coil Extension", "Coated Coils", "Crescendo", "Micro Detonators", "Fester", "Fwoosh"), new MoreSkillTreeData.Branch(1, "Ready and Waiting", "Flurrying Configuration", "Half Cocked", "Battery Recursion", "Black Market Battery", "Auxiliary Chargers", "Extra Capacitors", "Forward Charge"), new MoreSkillTreeData.Branch(2, "Auger Subroutine", "Centripetal Cornering", "Gearshift", "Killing Field", "Subway", "Storm's Eye", "Laying Cable", "Fisticuffs", "Triple A", "Gladiator's Pockets", "Squire Supplier")),
			new MoreSkillTreeData.Tree("Accelerator", new string[2] { "accelerator", "acceleratorgun" }, new MoreSkillTreeData.Branch(0, "Full-Auto Trigger", "Number 5 To Go", "Three-In-One", "Ruptured Spleen", "Hair Trigger", "Feedback Loop", "Size Them Up", "Inertia Accelerant", "Momentum Impact"), new MoreSkillTreeData.Branch(1, "Payload Amplifier", "Kinetic Optimization", "Wasp Gun", "Awaken The Hive", "Honey Sweet", "Requeening", "Sweet Heavens", "Combustive Rounds", "Queen's Cannons", "Oxythane's Promise", "Slipspace Bullet Transfer"), new MoreSkillTreeData.Branch(2, "Shake The Nest", "Quick Reset", "Shocker", "Remote Charging", "The Royal Jelly of Hazaran", "Miniaturized Warp Core", "Payback", "Energy Cohesion", "Flash Charge", "Shaved Projectiles")),
			new MoreSkillTreeData.Tree("Incendiary Grenade", new string[5] { "incendiarygrenade", "incendiary_grenade", "incendiary", "firegrenade", "fire_grenade" }, new MoreSkillTreeData.Branch(0, "Large Ignition", "Home Brew Combustion", "Volatile Explosives", "Cluster Bomb", "Napalm", "Violent Reaction", "Give and Take", "Maniac Maneuver"), new MoreSkillTreeData.Branch(1, "Heat Sink", "Internal Combustion", "Hearth & Home", "Cheap Material", "Fire Gel", "Restoration Protocol", "Impact Cascade", "Hot Boxing"), new MoreSkillTreeData.Branch(2, "Heated Charge", "Two's Company", "Gambler's Bargain", "In for a Penny", "Grenade Belt", "Welding Heat")),
			new MoreSkillTreeData.Tree("Shock Grenade", new string[6] { "shockgrenade", "shock_grenade", "voltaicgrenade", "voltaic_grenade", "voltaic", "electricgrenade" }, new MoreSkillTreeData.Branch(0, "Engorge", "Higher Voltage", "Flash Storm", "Excited Plasma", "Stun", "Electromagnet", "Phase Housing"), new MoreSkillTreeData.Branch(1, "Live Wire", "Livelier", "Launch Charge", "Thunder Pressure", "Cloud Skip", "Marathon", "Static Charge", "System Overload", "Emergency Evac"), new MoreSkillTreeData.Branch(2, "Fastball", "Insulated Gloves", "Shock Funnel", "In for a Penny", "Grenade Belt", "Illegal Pocket Grenade")),
			new MoreSkillTreeData.Tree("Acid Grenade", new string[4] { "acidgrenade", "acid_grenade", "acid nade", "acidnade" }, new MoreSkillTreeData.Branch(0, "Gas Puddle", "Deteriorate", "Universal Solvent", "Odd Cocktail", "Exothermic Reaction", "Vacuum Tube", "Overcharge"), new MoreSkillTreeData.Branch(1, "Gas Valves", "Defensive Spurt", "Sloth's Day Out", "Cooling System", "Base Coating", "Polymer Coating", "Greased Mixture"), new MoreSkillTreeData.Branch(2, "Glub Glub", "Saxonite Coating", "Lightspeed Material Transfer", "In for a Penny", "Connected Systems", "Heavy Support", "Grenade Belt", "Overclock")),
			new MoreSkillTreeData.Tree("Photon Disc", new string[6] { "photondisc", "photon_disc", "photon", "disc", "photondisk", "photon_disk" }, new MoreSkillTreeData.Branch(0, "Enhanced Spooling", "Steel Frame", "Magnetic Shard", "Linked List", "Splinter", "Molecular Inversion", "Explosive Packing", "Photon Lattice", "Disc Array"), new MoreSkillTreeData.Branch(1, "Perfectly Attuned", "Elemental Obsession", "Erratic Systems", "Harmonizer", "Syzygy", "Reactive Overload"), new MoreSkillTreeData.Branch(2, "USB C", "Flurry", "Reflex Override", "Propulsion Drive", "Stimulus Package", "In For A Penny", "Grenade Belt", "Pocket Grenade (Wait Why is This One Legal?)", "Bullet Time"))
		};
	}
	internal static class SkillTreeUIHelpers
	{
		public static RectTransform CreateUIObject(string name, Transform parent)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) });
			val.transform.SetParent(parent, false);
			return (RectTransform)val.transform;
		}

		public static TextMeshProUGUI CreateText(Transform parent, string name, float size, FontStyles style, TextAlignmentOptions align)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Invalid comparison between Unknown and I4
			TextMeshProUGUI val = ((Component)CreateUIObject(name, parent)).gameObject.AddComponent<TextMeshProUGUI>();
			((TMP_Text)val).fontSize = size;
			((TMP_Text)val).fontStyle = style;
			((TMP_Text)val).alignment = align;
			((Graphic)val).color = Color.white;
			((Graphic)val).raycastTarget = false;
			((TMP_Text)val).enableWordWrapping = true;
			((TMP_Text)val).overflowMode = (TextOverflowModes)1;
			try
			{
				if ((Object)(object)Global.Instance != (Object)null)
				{
					if ((int)style == 1 && (Object)(object)Global.Instance.BoldFont != (Object)null)
					{
						((TMP_Text)val).font = Global.Instance.BoldFont;
					}
					else if ((Object)(object)Global.Instance.NormalFont != (Object)null)
					{
						((TMP_Text)val).font = Global.Instance.NormalFont;
					}
				}
			}
			catch
			{
			}
			return val;
		}

		public static void Stretch(RectTransform rt)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			rt.anchorMin = Vector2.zero;
			rt.anchorMax = Vector2.one;
			rt.offsetMin = Vector2.zero;
			rt.offsetMax = Vector2.zero;
		}

		public static void ApplyNodeVisual(SkillTreeNodeButton nb)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			bool interactable = false;
			((Graphic)nb.Label).color = Color.white;
			Color color = default(Color);
			string text;
			switch (nb.Node.State)
			{
			case NodeState.Claimed:
				((Color)(ref color))..ctor(0.15f, 0.45f, 0.22f, 1f);
				text = "Claimed";
				break;
			case NodeState.Available:
				((Color)(ref color))..ctor(0.18f, 0.32f, 0.55f, 1f);
				text = "Click to unlock (1 SP)";
				interactable = true;
				break;
			case NodeState.CannotAfford:
				((Color)(ref color))..ctor(0.35f, 0.28f, 0.12f, 1f);
				text = "Need skill point";
				break;
			case NodeState.LayerLocked:
				((Color)(ref color))..ctor(0.18f, 0.18f, 0.2f, 1f);
				text = $"Locked — spend {nb.Node.MinSpentRequired} total first";
				((Graphic)nb.Label).color = new Color(1f, 1f, 1f, 0.35f);
				break;
			default:
				((Color)(ref color))..ctor(0.4f, 0.1f, 0.1f, 1f);
				text = "Unresolved name";
				((Graphic)nb.Label).color = new Color(1f, 0.6f, 0.6f, 1f);
				break;
			}
			((Graphic)nb.Background).color = color;
			((TMP_Text)nb.SubLabel).text = text;
			((Graphic)nb.SubLabel).color = new Color(1f, 1f, 1f, 0.7f);
			((Selectable)nb.Button).interactable = interactable;
		}

		public static SkillTreeNodeButton CreateNodeButton(Transform content, ResolvedNode node, float x, float y, float w, float h, UnityAction onClick)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: 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_00ad: 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_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			RectTransform obj = CreateUIObject("Node", content);
			obj.anchorMin = new Vector2(0f, 1f);
			obj.anchorMax = new Vector2(0f, 1f);
			obj.pivot = new Vector2(0f, 1f);
			obj.anchoredPosition = new Vector2(x, y);
			obj.sizeDelta = new Vector2(w, h);
			Image val = ((Component)obj).gameObject.AddComponent<Image>();
			Button val2 = ((Component)obj).gameObject.AddComponent<Button>();
			((Selectable)val2).targetGraphic = (Graphic)(object)val;
			TextMeshProUGUI val3 = CreateText((Transform)(object)obj, "Label", 18f, (FontStyles)1, (TextAlignmentOptions)513);
			RectTransform rectTransform = ((TMP_Text)val3).rectTransform;
			rectTransform.anchorMin = new Vector2(0f, 0.4f);
			rectTransform.anchorMax = new Vector2(1f, 1f);
			rectTransform.offsetMin = new Vector2(12f, 0f);
			rectTransform.offsetMax = new Vector2(-12f, -6f);
			((TMP_Text)val3).text = (((Object)(object)node.Upgrade != (Object)null) ? node.Upgrade.Name : node.DisplayName);
			((Graphic)val3).color = Color.white;
			TextMeshProUGUI val4 = CreateText((Transform)(object)obj, "Sub", 14f, (FontStyles)0, (TextAlignmentOptions)513);
			RectTransform rectTransform2 = ((TMP_Text)val4).rectTransform;
			rectTransform2.anchorMin = new Vector2(0f, 0f);
			rectTransform2.anchorMax = new Vector2(1f, 0.45f);
			rectTransform2.offsetMin = new Vector2(12f, 6f);
			rectTransform2.offsetMax = new Vector2(-12f, 0f);
			SkillTreeNodeButton obj2 = new SkillTreeNodeButton
			{
				Node = node,
				Button = val2,
				Background = val,
				Label = val3,
				SubLabel = val4
			};
			ApplyNodeVisual(obj2);
			((UnityEvent)val2.onClick).AddListener(onClick);
			return obj2;
		}
	}
	internal sealed class SkillTreeNodeButton
	{
		public Image Background;

		public Button Button;

		public TextMeshProUGUI Label;

		public ResolvedNode Node;

		public TextMeshProUGUI SubLabel;
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "MoreSkillTrees";

		public const string PLUGIN_NAME = "MoreSkillTrees";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}