Decompiled source of TalentPace v1.0.1

BepInEx/plugins/Cjayride.TalentPace.dll

Decompiled 3 days ago
using System;
using System.Collections;
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.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("assembly_valheim")]
[assembly: TargetFramework(".NETFramework,Version=v4.8.1", FrameworkDisplayName = ".NET Framework 4.8.1")]
[assembly: AssemblyCompany("Cjayride.TalentPace")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyInformationalVersion("1.0.1+a6000ee7633b4415a16149e3a41f8e391f6a523f")]
[assembly: AssemblyProduct("Cjayride.TalentPace")]
[assembly: AssemblyTitle("Cjayride.TalentPace")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.1.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 Cjayride.TalentPace
{
	internal static class CapHint
	{
		private const string LabelName = "TalentPaceCap";

		private static FieldInfo _view;

		private static PropertyInfo _titleText;

		private static MethodInfo _getRuntime;

		private static MethodInfo _totalPoints;

		private static float _nextSample;

		private static bool _logged;

		public static void Apply(Harmony harmony)
		{
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Expected O, but got Unknown
			Type type = AccessTools.TypeByName("UI.TalentWindow");
			MethodInfo methodInfo = ((type == null) ? null : AccessTools.DeclaredMethod(type, "Refresh", (Type[])null, (Type[])null));
			MethodInfo methodInfo2 = ((type == null) ? null : AccessTools.DeclaredMethod(type, "Tick", (Type[])null, (Type[])null));
			if (methodInfo == null)
			{
				Plugin.Log("Talent window refresh was not found. The cap line is off.");
				return;
			}
			_view = AccessTools.Field(type, "_view");
			Type type2 = AccessTools.TypeByName("UI.TalentWindowView");
			_titleText = ((type2 == null) ? null : AccessTools.Property(type2, "TitleText"));
			Type type3 = AccessTools.TypeByName("Core.TalentRuntimeService");
			Type type4 = AccessTools.TypeByName("Core.TalentRuntime");
			Type type5 = AccessTools.TypeByName("Core.TalentPointBudgetService");
			_getRuntime = ((type3 == null) ? null : AccessTools.DeclaredMethod(type3, "Get", new Type[1] { typeof(Player) }, (Type[])null));
			_totalPoints = ((type5 == null || type4 == null) ? null : AccessTools.DeclaredMethod(type5, "GetTotalPoints", new Type[2]
			{
				typeof(Player),
				type4
			}, (Type[])null));
			HarmonyMethod val = new HarmonyMethod(typeof(CapHint), "AfterRefresh", (Type[])null);
			harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			if (methodInfo2 != null)
			{
				harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
		}

		private static void AfterRefresh()
		{
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			Text val = Title();
			if ((Object)(object)val == (Object)null || !((Component)val).gameObject.activeInHierarchy)
			{
				return;
			}
			Player localPlayer = Player.m_localPlayer;
			if (!((Object)(object)localPlayer == (Object)null))
			{
				if (Time.unscaledTime >= _nextSample)
				{
					_nextSample = Time.unscaledTime + 0.5f;
					Sample(localPlayer);
				}
				string text = Pace.Hint(localPlayer);
				if (string.IsNullOrEmpty(text))
				{
					text = "No talent cap.";
				}
				Text val2 = Ensure(val);
				val2.text = text;
				((Graphic)val2).color = (text.StartsWith("Talent cap reached", StringComparison.Ordinal) ? new Color(1f, 0.55f, 0.2f, 1f) : new Color(1f, 0.82f, 0.35f, 1f));
				((Component)val2).transform.SetAsLastSibling();
				if (!((Component)val2).gameObject.activeSelf)
				{
					((Component)val2).gameObject.SetActive(true);
				}
				if (!_logged)
				{
					_logged = true;
					Plugin.Log("Talent window cap line: " + text);
				}
			}
		}

		private static void Sample(Player player)
		{
			if (_getRuntime == null || _totalPoints == null)
			{
				return;
			}
			try
			{
				object obj = _getRuntime.Invoke(null, new object[1] { player });
				if (obj != null)
				{
					_totalPoints.Invoke(null, new object[2] { player, obj });
				}
			}
			catch (Exception)
			{
			}
		}

		private static Text Title()
		{
			if (_view == null || _titleText == null)
			{
				return null;
			}
			object value = _view.GetValue(null);
			if (value != null)
			{
				object? value2 = _titleText.GetValue(value, null);
				return (Text)((value2 is Text) ? value2 : null);
			}
			return null;
		}

		private static Text Ensure(Text title)
		{
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: 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_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: 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_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			Transform parent = ((Component)title).transform.parent;
			Transform val = parent.Find("TalentPaceCap");
			Text val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent<Text>() : null);
			if ((Object)(object)val2 == (Object)null)
			{
				GameObject val3 = new GameObject("TalentPaceCap");
				val3.transform.SetParent(parent, false);
				val2 = val3.AddComponent<Text>();
				val2.font = title.font;
				val2.alignment = (TextAnchor)1;
				val2.horizontalOverflow = (HorizontalWrapMode)1;
				val2.verticalOverflow = (VerticalWrapMode)1;
				((Graphic)val2).raycastTarget = false;
				val2.supportRichText = false;
			}
			RectTransform rectTransform = ((Graphic)title).rectTransform;
			RectTransform rectTransform2 = ((Graphic)val2).rectTransform;
			rectTransform2.anchorMin = rectTransform.anchorMin;
			rectTransform2.anchorMax = rectTransform.anchorMax;
			rectTransform2.pivot = new Vector2(0.5f, 1f);
			rectTransform2.sizeDelta = new Vector2(Mathf.Max(900f, rectTransform.sizeDelta.x), 36f);
			Rect rect = rectTransform.rect;
			float num;
			if (!(((Rect)(ref rect)).height > 1f))
			{
				num = rectTransform.sizeDelta.y;
			}
			else
			{
				rect = rectTransform.rect;
				num = ((Rect)(ref rect)).height;
			}
			float num2 = num;
			rectTransform2.anchoredPosition = rectTransform.anchoredPosition + new Vector2(0f, 0f - num2 - 2f);
			val2.fontSize = Mathf.Clamp(Mathf.RoundToInt((float)title.fontSize * 0.62f), 16, 22);
			return val2;
		}
	}
	[BepInPlugin("cjayride.talentpace", "Talent Pace", "1.0.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static ConsoleEvent <>9__11_0;

			internal void <Awake>b__11_0(ConsoleEventArgs args)
			{
				Player localPlayer = Player.m_localPlayer;
				if ((Object)(object)localPlayer == (Object)null)
				{
					args.Context.AddString("Talent Pace: no local player.");
					return;
				}
				Pace.Summary summary = Pace.Describe(localPlayer);
				args.Context.AddString(summary.Line);
			}
		}

		public const string PluginGUID = "cjayride.talentpace";

		public const string PluginName = "Talent Pace";

		public const string PluginVersion = "1.0.1";

		internal static Plugin Instance;

		internal static ConfigEntry<int> CapNone;

		internal static ConfigEntry<int> CapEikthyr;

		internal static ConfigEntry<int> CapElder;

		internal static ConfigEntry<int> CapBonemass;

		internal static ConfigEntry<int> CapModer;

		internal static ConfigEntry<int> CapYagluth;

		internal static ConfigEntry<bool> QueenRemovesCap;

		private void Awake()
		{
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Expected O, but got Unknown
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Expected O, but got Unknown
			Instance = this;
			CapNone = BindCap("Before any boss", 9);
			CapEikthyr = BindCap("After Eikthyr", 15);
			CapElder = BindCap("After the Elder", 21);
			CapBonemass = BindCap("After Bonemass", 36);
			CapModer = BindCap("After Moder", 54);
			CapYagluth = BindCap("After Yagluth", 75);
			QueenRemovesCap = ((BaseUnityPlugin)this).Config.Bind<bool>("Caps", "Queen or Fader removes the cap", true, "Personal defeat of the Queen or Fader removes the point cap. The saved talents were never deleted.");
			if (AccessTools.TypeByName("Core.TalentPointBudgetService") == null || AccessTools.TypeByName("Core.TalentRebuildService") == null)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)"Talent Tree types were not found. Talent Pace is off.");
				return;
			}
			Harmony val = new Harmony("cjayride.talentpace");
			val.PatchAll(typeof(BudgetPatch));
			val.PatchAll(typeof(RebuildPatch));
			val.PatchAll(typeof(BossKeyPatch));
			CapHint.Apply(val);
			object obj = <>c.<>9__11_0;
			if (obj == null)
			{
				ConsoleEvent val2 = delegate(ConsoleEventArgs args)
				{
					Player localPlayer = Player.m_localPlayer;
					if ((Object)(object)localPlayer == (Object)null)
					{
						args.Context.AddString("Talent Pace: no local player.");
					}
					else
					{
						Pace.Summary summary = Pace.Describe(localPlayer);
						args.Context.AddString(summary.Line);
					}
				};
				<>c.<>9__11_0 = val2;
				obj = (object)val2;
			}
			new ConsoleCommand("talentpace", "Print the Talent Pace cap for your character.", (ConsoleEvent)obj, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Talent Pace 1.0.1 loaded.");
		}

		private ConfigEntry<int> BindCap(string key, int value)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			return ((BaseUnityPlugin)this).Config.Bind<int>("Caps", key, value, new ConfigDescription("Talent points that apply once this player has that boss key. Outer nodes past the cap stay saved and turn back on after the next boss.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 500), Array.Empty<object>()));
		}

		internal static void Log(string message)
		{
			((BaseUnityPlugin)Instance).Logger.LogInfo((object)message);
		}
	}
	[HarmonyPatch]
	internal static class BudgetPatch
	{
		private static MethodBase TargetMethod()
		{
			return AccessTools.DeclaredMethod(AccessTools.TypeByName("Core.TalentPointBudgetService"), "GetTotalPoints", new Type[2]
			{
				typeof(Player),
				AccessTools.TypeByName("Core.TalentRuntime")
			}, (Type[])null);
		}

		private static void Postfix([HarmonyArgument(0)] Player player, ref int __result)
		{
			if (!((Object)(object)player == (Object)null))
			{
				Pace.RememberNatural(player, __result);
				int num = Pace.CapFor(player);
				if (num < int.MaxValue && __result > num)
				{
					__result = num;
				}
			}
		}
	}
	[HarmonyPatch]
	internal static class RebuildPatch
	{
		private static MethodBase TargetMethod()
		{
			return AccessTools.DeclaredMethod(AccessTools.TypeByName("Core.TalentRebuildService"), "Rebuild", new Type[1] { AccessTools.TypeByName("Core.TalentRuntime") }, (Type[])null);
		}

		private static void Postfix([HarmonyArgument(0)] object runtime)
		{
			Pace.TrimCache(runtime);
		}
	}
	[HarmonyPatch(typeof(Player), "AddUniqueKey")]
	internal static class BossKeyPatch
	{
		private static void Postfix(Player __instance, string name)
		{
			if (!((Object)(object)__instance == (Object)null) && !string.IsNullOrEmpty(name) && name.IndexOf("defeated_", StringComparison.Ordinal) >= 0)
			{
				Pace.MarkDirty(__instance);
			}
		}
	}
	internal static class Pace
	{
		internal struct Summary
		{
			public string Line;
		}

		private struct Node
		{
			public string Id;

			public int Ring;

			public int Cost;

			public int Rank;

			public Node(string id, int ring, int cost, int rank)
			{
				Id = id;
				Ring = ring;
				Cost = cost;
				Rank = rank;
			}
		}

		private const int Minor = 0;

		private const int Keystone = 1;

		private const int Mid = 2;

		private static readonly string[] BossOrder = new string[5] { "defeated_eikthyr", "defeated_gdking", "defeated_bonemass", "defeated_dragon", "defeated_goblinking" };

		private static MethodInfo _tryGet;

		private static MethodInfo _buildCache;

		private static MethodInfo _sync;

		private static MethodInfo _getRuntime;

		private static FieldInfo _runtimes;

		private static PropertyInfo _isDirty;

		private static bool _reflected;

		private static bool _reflectFailed;

		private static readonly string[] NextBoss = new string[5] { "Eikthyr", "the Elder", "Bonemass", "Moder", "Yagluth" };

		private static readonly Dictionary<long, int> _natural = new Dictionary<long, int>();

		internal static int CapFor(Player player)
		{
			if ((Object)(object)player == (Object)null)
			{
				return Plugin.CapNone.Value;
			}
			if (Plugin.QueenRemovesCap.Value && (((Humanoid)player).HaveUniqueKey("defeated_queen") || ((Humanoid)player).HaveUniqueKey("defeated_fader")))
			{
				return int.MaxValue;
			}
			int value = Plugin.CapNone.Value;
			if (((Humanoid)player).HaveUniqueKey(BossOrder[0]))
			{
				value = Plugin.CapEikthyr.Value;
			}
			if (((Humanoid)player).HaveUniqueKey(BossOrder[1]))
			{
				value = Plugin.CapElder.Value;
			}
			if (((Humanoid)player).HaveUniqueKey(BossOrder[2]))
			{
				value = Plugin.CapBonemass.Value;
			}
			if (((Humanoid)player).HaveUniqueKey(BossOrder[3]))
			{
				value = Plugin.CapModer.Value;
			}
			if (((Humanoid)player).HaveUniqueKey(BossOrder[4]))
			{
				value = Plugin.CapYagluth.Value;
			}
			return value;
		}

		internal static int NaturalFor(Player player)
		{
			if ((Object)(object)player == (Object)null)
			{
				return 0;
			}
			long playerID = player.GetPlayerID();
			if (!_natural.TryGetValue(playerID, out var value))
			{
				return 0;
			}
			return value;
		}

		internal static void RememberNatural(Player player, int points)
		{
			if (!((Object)(object)player == (Object)null))
			{
				_natural[player.GetPlayerID()] = points;
			}
		}

		internal static string Hint(Player player)
		{
			int num = CapFor(player);
			if (num == int.MaxValue)
			{
				return null;
			}
			int num2 = 0;
			if ((Object)(object)player != (Object)null && ((Humanoid)player).HaveUniqueKey(BossOrder[0]))
			{
				num2 = 1;
			}
			if ((Object)(object)player != (Object)null && ((Humanoid)player).HaveUniqueKey(BossOrder[1]))
			{
				num2 = 2;
			}
			if ((Object)(object)player != (Object)null && ((Humanoid)player).HaveUniqueKey(BossOrder[2]))
			{
				num2 = 3;
			}
			if ((Object)(object)player != (Object)null && ((Humanoid)player).HaveUniqueKey(BossOrder[3]))
			{
				num2 = 4;
			}
			if ((Object)(object)player != (Object)null && ((Humanoid)player).HaveUniqueKey(BossOrder[4]))
			{
				num2 = 5;
			}
			string text = ((NaturalFor(player) >= num) ? "Talent cap reached: " : "Talent cap: ");
			if (num2 >= 5)
			{
				if (!Plugin.QueenRemovesCap.Value)
				{
					return text + num + " points apply.";
				}
				return text + num + " points. Kill the Queen or Fader to remove the cap.";
			}
			int num3 = num2 switch
			{
				3 => Plugin.CapModer.Value, 
				2 => Plugin.CapBonemass.Value, 
				1 => Plugin.CapElder.Value, 
				0 => Plugin.CapEikthyr.Value, 
				_ => Plugin.CapYagluth.Value, 
			};
			return text + num + " points. Kill " + NextBoss[num2] + " to raise it to " + num3 + ".";
		}

		internal static Summary Describe(Player player)
		{
			string text = Hint(player);
			return new Summary
			{
				Line = (text ?? "Talent Pace: no cap.")
			};
		}

		internal static void MarkDirty(Player player)
		{
			if (EnsureReflection() && _runtimes.GetValue(null) is IDictionary dictionary)
			{
				long playerID = player.GetPlayerID();
				if (dictionary.Contains(playerID))
				{
					object obj = dictionary[playerID];
					_isDirty.SetValue(obj, true, null);
					_getRuntime.Invoke(null, new object[1] { player });
				}
			}
		}

		internal static void TrimCache(object runtime)
		{
			if (runtime == null || !EnsureReflection())
			{
				return;
			}
			object? value = runtime.GetType().GetProperty("Player").GetValue(runtime, null);
			Player val = (Player)((value is Player) ? value : null);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			int num = CapFor(val);
			if (num == int.MaxValue)
			{
				return;
			}
			object value2 = runtime.GetType().GetProperty("State").GetValue(runtime, null);
			if (!(value2.GetType().GetProperty("Ranks").GetValue(value2, null) is IDictionary { Count: not 0 } dictionary))
			{
				return;
			}
			List<Node> list = new List<Node>(dictionary.Count);
			foreach (DictionaryEntry item2 in dictionary)
			{
				string text = item2.Key as string;
				int num2 = ((item2.Value is int num3) ? num3 : 0);
				if (!string.IsNullOrEmpty(text) && num2 > 0)
				{
					object[] array = new object[2] { text, null };
					if ((bool)_tryGet.Invoke(null, array) && array[1] != null)
					{
						object obj = array[1];
						Type type = obj.GetType();
						int ring = (int)type.GetProperty("Ring").GetValue(obj, null);
						int tier = (int)type.GetProperty("Tier").GetValue(obj, null);
						list.Add(new Node(text, ring, Cost(tier), num2));
					}
				}
			}
			list.Sort(delegate(Node a, Node b)
			{
				int num8 = a.Ring.CompareTo(b.Ring);
				return (num8 == 0) ? string.CompareOrdinal(a.Id, b.Id) : num8;
			});
			Dictionary<string, int> kept = new Dictionary<string, int>(list.Count);
			int num4 = num;
			int num5 = 0;
			bool flag = false;
			for (int num6 = 0; num6 < list.Count; num6++)
			{
				Node node = list[num6];
				int val2 = ((node.Cost <= 0) ? node.Rank : (num4 / node.Cost));
				int num7 = Math.Min(node.Rank, Math.Max(0, val2));
				kept[node.Id] = num7;
				num4 -= num7 * node.Cost;
				num5 += num7 * node.Cost;
				if (num7 != node.Rank)
				{
					flag = true;
				}
			}
			if (!flag)
			{
				return;
			}
			List<string> list2 = new List<string>(dictionary.Count);
			foreach (DictionaryEntry item3 in dictionary)
			{
				if (item3.Key is string item)
				{
					list2.Add(item);
				}
			}
			int value4;
			Func<string, int> func = (string id) => kept.TryGetValue(id, out value4) ? value4 : 0;
			object value3 = _buildCache.Invoke(null, new object[2] { list2, func });
			runtime.GetType().GetProperty("Cache").SetValue(runtime, value3, null);
			_sync.Invoke(null, new object[1] { runtime });
			Plugin.Log(val.GetPlayerName() + " talent cap " + num + ", " + num5 + " points active.");
		}

		private static int Cost(int tier)
		{
			switch (tier)
			{
			case 0:
				return 1;
			case 2:
				return 2;
			default:
				_ = 1;
				return 3;
			}
		}

		private static bool EnsureReflection()
		{
			if (_reflected)
			{
				return !_reflectFailed;
			}
			_reflected = true;
			Type type = AccessTools.TypeByName("Core.TalentRegistry");
			Type type2 = AccessTools.TypeByName("Core.TalentDefinition");
			Type type3 = AccessTools.TypeByName("Core.TalentRebuildService");
			Type type4 = AccessTools.TypeByName("Core.TalentRuntime");
			Type type5 = AccessTools.TypeByName("Core.TalentRuntimeService");
			Type type6 = AccessTools.TypeByName("Core.TalentPassivesService");
			_tryGet = AccessTools.DeclaredMethod(type, "TryGet", new Type[2]
			{
				typeof(string),
				type2.MakeByRefType()
			}, (Type[])null);
			_buildCache = AccessTools.DeclaredMethod(type3, "BuildCache", (Type[])null, (Type[])null);
			_sync = AccessTools.DeclaredMethod(type6, "SyncToPlayer", new Type[1] { type4 }, (Type[])null);
			_getRuntime = AccessTools.DeclaredMethod(type5, "Get", new Type[1] { typeof(Player) }, (Type[])null);
			_runtimes = AccessTools.DeclaredField(type5, "_runtimes");
			_isDirty = AccessTools.DeclaredProperty(type4, "IsDirty");
			_reflectFailed = _tryGet == null || _buildCache == null || _sync == null || _getRuntime == null || _runtimes == null || _isDirty == null;
			if (_reflectFailed)
			{
				Plugin.Log("Talent Pace could not bind Talent Tree. Caps are off.");
			}
			return !_reflectFailed;
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}