Decompiled source of HarrisonEpicClassSystem v0.0.21

BepInEx/plugins/HarrisonEpicClassSystem/HarrisonEpicClassSystem.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Runtime.Versioning;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using HarrisonEpicClassSystem.Altar;
using HarrisonEpicClassSystem.Assets;
using HarrisonEpicClassSystem.Compatibility;
using HarrisonEpicClassSystem.Config;
using HarrisonEpicClassSystem.Core;
using HarrisonEpicClassSystem.Items;
using HarrisonEpicClassSystem.Models;
using HarrisonEpicClassSystem.Persistence;
using HarrisonEpicClassSystem.Requirements;
using HarrisonEpicClassSystem.UI;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("Harrison")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Class progression and altar awakening system for Valheim integrated with WackyEpicMMOSystem.")]
[assembly: AssemblyFileVersion("0.0.21.0")]
[assembly: AssemblyInformationalVersion("0.0.21")]
[assembly: AssemblyProduct("HarrisonEpicClassSystem")]
[assembly: AssemblyTitle("HarrisonEpicClassSystem")]
[assembly: AssemblyVersion("0.0.21.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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 HarrisonEpicClassSystem
{
	[BepInPlugin("com.harrison.valheim.epicclasssystem", "HarrisonEpicClassSystem", "0.0.21")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class HarrisonEpicClassSystemPlugin : BaseUnityPlugin
	{
		public const string ModGuid = "com.harrison.valheim.epicclasssystem";

		public const string ModName = "HarrisonEpicClassSystem";

		public const string ModVersion = "0.0.21";

		public const string WackyEpicMmoGuid = "WackyMole.EpicMMOSystem";

		public const string ConfigFileName = "HarrisonEpicClassSystem.cfg";

		internal static ManualLogSource Log = null;

		internal static HarrisonEpicClassSystemPlugin Instance = null;

		private Harmony? _harmony;

		private ConfigFile? _classConfigFile;

		internal static string PluginDirectory { get; private set; } = string.Empty;

		private void Awake()
		{
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Expected O, but got Unknown
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			PluginDirectory = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location) ?? Paths.PluginPath;
			Log.LogInfo((object)"HarrisonEpicClassSystem 0.0.21 loading...");
			string text = Path.Combine(Paths.ConfigPath, "HarrisonEpicClassSystem.cfg");
			_classConfigFile = new ConfigFile(text, true, ((BaseUnityPlugin)this).Info.Metadata)
			{
				SaveOnConfigSet = true
			};
			ClassConfig.Initialize(_classConfigFile);
			_classConfigFile.Save();
			Log.LogInfo((object)("Config ready: " + text));
			if (!ClassConfig.Validate())
			{
				Log.LogError((object)"Promotion config is invalid. Awakening will remain unavailable until config is corrected.");
			}
			if (!WackyEpicMmoApi.Initialize())
			{
				Log.LogError((object)"Could not initialize the WackyEpicMMOSystem compatibility API.");
				return;
			}
			ClassRegistry.Initialize();
			bool saveOnConfigSet = _classConfigFile.SaveOnConfigSet;
			_classConfigFile.SaveOnConfigSet = false;
			try
			{
				ClassBalanceConfig.Initialize(_classConfigFile);
				ClassAwakeningMaterials.Initialize(_classConfigFile);
			}
			finally
			{
				_classConfigFile.SaveOnConfigSet = saveOnConfigSet;
			}
			_classConfigFile.Save();
			ClassRuntimeService.Initialize();
			ClassProgressionService.Initialize();
			VisualAssetService.Initialize(PluginDirectory);
			ClassAltarUI.Initialize();
			AltarRegistrar.Register();
			DivineLightItem.Initialize();
			AwakeningStoneItems.Initialize();
			_harmony = new Harmony("com.harrison.valheim.epicclasssystem");
			_harmony.PatchAll();
			Log.LogInfo((object)("HarrisonEpicClassSystem loaded. Awakening levels: " + $"First={ClassConfig.FirstPromotionLevelValue}, " + $"Second={ClassConfig.SecondPromotionLevelValue}, " + $"Mythic={ClassConfig.MythicPromotionLevelValue}"));
		}

		private void Update()
		{
			ClassRuntimeService.Update();
			ClassProgressionService.Update();
			ClassAltarUI.Update();
		}

		private void OnDestroy()
		{
			AltarRegistrar.Shutdown();
			DivineLightItem.Shutdown();
			AwakeningStoneItems.Shutdown();
			ClassAltarUI.Shutdown();
			VisualAssetService.Shutdown();
			ClassRuntimeService.Shutdown();
			Harmony? harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}
	}
}
namespace HarrisonEpicClassSystem.UI
{
	internal sealed class AltarButtonSound : MonoBehaviour
	{
		private MonoBehaviour? _source;

		private MethodInfo? _click;

		private bool _bound;

		private int _lastFrame = -1;

		public void Bind(Button button)
		{
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Expected O, but got Unknown
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Expected O, but got Unknown
			if (_bound)
			{
				return;
			}
			_bound = true;
			for (int i = 0; i < ((UnityEventBase)button.onClick).GetPersistentEventCount(); i++)
			{
				if (((object)((UnityEventBase)button.onClick).GetPersistentTarget(i))?.GetType().Name == "ButtonSfx")
				{
					((UnityEventBase)button.onClick).SetPersistentListenerState(i, (UnityEventCallState)0);
				}
			}
			MonoBehaviour[] componentsInChildren = ((Component)button).GetComponentsInChildren<MonoBehaviour>(true);
			foreach (MonoBehaviour val in componentsInChildren)
			{
				if (((object)val).GetType().Name != "ButtonSfx")
				{
					continue;
				}
				MethodInfo method = ((object)val).GetType().GetMethod("OnClick", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (!(method == null))
				{
					UnityAction val2 = (UnityAction)Delegate.CreateDelegate(typeof(UnityAction), val, method);
					((UnityEvent)button.onClick).RemoveListener(val2);
					((Behaviour)val).enabled = false;
					if ((Object)(object)_source == (Object)null)
					{
						_source = val;
						_click = method;
					}
				}
			}
			if ((Object)(object)_source != (Object)null)
			{
				((UnityEvent)button.onClick).AddListener(new UnityAction(Play));
			}
		}

		private void Play()
		{
			if (_lastFrame == Time.frameCount || (Object)(object)_source == (Object)null)
			{
				return;
			}
			_lastFrame = Time.frameCount;
			try
			{
				_click?.Invoke(_source, null);
			}
			catch (Exception ex)
			{
				HarrisonEpicClassSystemPlugin.Log.LogWarning((object)("Altar click sound failed: " + ex.Message));
			}
		}
	}
	public sealed class AltarGuiScale : MonoBehaviour
	{
		private Vector3 _designScale;

		private bool _initialized;

		private float _nextCheck;

		private static MethodInfo? _getFloat;

		private static bool _resolved;

		private static float ReadGuiScale()
		{
			if (!_resolved)
			{
				_resolved = true;
				Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
				foreach (Assembly assembly in assemblies)
				{
					Type type;
					try
					{
						type = assembly.GetTypes().FirstOrDefault((Type type2) => type2.Name == "PlatformPrefs");
					}
					catch (ReflectionTypeLoadException ex)
					{
						type = ex.Types.FirstOrDefault((Type type2) => type2?.Name == "PlatformPrefs");
					}
					if (!(type == null))
					{
						_getFloat = type.GetMethod("GetFloat", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[2]
						{
							typeof(string),
							typeof(float)
						}, null);
						if (_getFloat != null)
						{
							break;
						}
					}
				}
				if (_getFloat == null)
				{
					HarrisonEpicClassSystemPlugin.Log.LogWarning((object)"PlatformPrefs.GetFloat was not found; using legacy GUI Scale preference.");
				}
			}
			if (!(_getFloat != null))
			{
				return PlayerPrefs.GetFloat("GuiScale", 1f);
			}
			return Convert.ToSingle(_getFloat.Invoke(null, new object[2] { "GuiScale", 1f }));
		}

		private void OnEnable()
		{
			Apply();
		}

		public void Apply()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: 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_006a: Unknown result type (might be due to invalid IL or missing references)
			if (!_initialized)
			{
				_designScale = ((Component)this).transform.localScale;
				_initialized = true;
			}
			float num = ReadGuiScale();
			if (float.IsNaN(num) || float.IsInfinity(num) || num <= 0f)
			{
				num = 1f;
			}
			Vector3 val = _designScale * num;
			if (((Component)this).transform.localScale != val)
			{
				((Component)this).transform.localScale = val;
			}
			_nextCheck = Time.unscaledTime + 0.25f;
		}

		private void Update()
		{
			if (Time.unscaledTime >= _nextCheck)
			{
				Apply();
			}
		}
	}
	public static class ClassAltarUI
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static Action <0>__OnCustomGUIAvailable;

			public static Action<PlayerClassData> <1>__OnClassDataChanged;

			public static Action<PlayerClassData, ClassStage> <2>__OnAwakeningAvailable;

			public static Action<PlayerClassData, ClassStage> <3>__OnAwakeningCompleted;

			public static UnityAction <4>__Close;

			public static UnityAction <5>__OnAwakenClicked;

			public static UnityAction <6>__OnChangeClassClicked;

			public static UnityAction <7>__ShowPreviousBaseClassPage;

			public static UnityAction <8>__ShowNextBaseClassPage;

			public static UnityAction <9>__ChooseCurrentBaseClassPage;
		}

		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static UnityAction <>9__61_1;

			public static UnityAction <>9__77_0;

			public static UnityAction <>9__82_1;

			public static UnityAction <>9__83_0;

			public static UnityAction <>9__84_0;

			internal void <RenderBaseClassConfirmation>b__61_1()
			{
				_pendingBaseClass = null;
				Refresh();
			}

			internal void <RenderAwakeningBrowser>b__77_0()
			{
				_showAwakening = false;
				Refresh();
			}

			internal void <RenderCurrentClass>b__82_1()
			{
				_respecConfirmationPending = false;
				_showAwakening = true;
				Refresh();
			}

			internal void <RenderResetConfirmation>b__83_0()
			{
				_respecConfirmationPending = false;
				Refresh();
			}

			internal void <RenderAbilities>b__84_0()
			{
				_abilitiesClass = null;
				Refresh();
			}
		}

		private static GameObject? _panel;

		private static Player? _player;

		private static bool _polished;

		private static bool _respecConfirmationPending;

		private static BaseClass? _pendingBaseClass;

		private static int _escapeConsumedFrame = -1;

		private static readonly List<GameObject> DynamicObjects = new List<GameObject>();

		private static readonly BaseClass[] BaseClassPages = new BaseClass[5]
		{
			BaseClass.Warrior,
			BaseClass.Mage,
			BaseClass.Hunter,
			BaseClass.Rogue,
			BaseClass.Paladin
		};

		private static int _baseClassPageIndex;

		private static bool _showAwakening;

		private static ClassId? _abilitiesClass;

		private static GameObject? _currentClassText;

		private static GameObject? _currentLevelText;

		private static GameObject? _targetClassText;

		private static GameObject? _requirementsText;

		private static GameObject? _statusText;

		private static Image? _classIcon;

		private static Button? _awakenButton;

		private static Button? _changeClassButton;

		private static GameObject? _baseClassNameText;

		private static GameObject? _baseClassDescriptionText;

		private static GameObject? _baseClassPathsText;

		private static GameObject? _classPageText;

		private static Image? _baseClassPreviewImage;

		private static Button? _previousClassButton;

		private static Button? _nextClassButton;

		private static Button? _chooseClassButton;

		private static readonly Button?[] BranchButtons = (Button?[])(object)new Button[3];

		private static readonly GameObject?[] BranchLabels = (GameObject?[])(object)new GameObject[3];

		private static int _awakeningPage;

		private static string _awakeningContext = string.Empty;

		private static string _materialSnapshot = string.Empty;

		private static float _nextMaterialCheck;

		public static bool IsOpen
		{
			get
			{
				if ((Object)(object)_panel != (Object)null && _panel.activeSelf)
				{
					return (Object)(object)_player != (Object)null;
				}
				return false;
			}
		}

		public static bool ShouldSuppressVanillaMenuThisFrame
		{
			get
			{
				if (_escapeConsumedFrame != Time.frameCount)
				{
					if (IsOpen)
					{
						return Input.GetKeyDown((KeyCode)27);
					}
					return false;
				}
				return true;
			}
		}

		public static void Initialize()
		{
			GUIManager.OnCustomGUIAvailable += OnCustomGUIAvailable;
			ClassEvents.ClassChanged += OnClassDataChanged;
			ClassEvents.AwakeningAvailable += OnAwakeningAvailable;
			ClassEvents.AwakeningCompleted += OnAwakeningCompleted;
		}

		public static void Shutdown()
		{
			GUIManager.OnCustomGUIAvailable -= OnCustomGUIAvailable;
			ClassEvents.ClassChanged -= OnClassDataChanged;
			ClassEvents.AwakeningAvailable -= OnAwakeningAvailable;
			ClassEvents.AwakeningCompleted -= OnAwakeningCompleted;
			CloseImmediate();
			if ((Object)(object)_panel != (Object)null)
			{
				Object.Destroy((Object)(object)_panel);
			}
			_panel = null;
			NorseUiTheme.Shutdown();
		}

		public static void Update()
		{
			if (IsOpen)
			{
				CheckMaterialChanges();
				if (Input.GetKeyDown((KeyCode)27))
				{
					_escapeConsumedFrame = Time.frameCount;
					Close();
				}
			}
		}

		public static void Open(Player player)
		{
			_pendingBaseClass = null;
			_player = player;
			EnsurePanel();
			if (!((Object)(object)_panel == (Object)null))
			{
				(_panel.GetComponent<AltarGuiScale>() ?? _panel.AddComponent<AltarGuiScale>()).Apply();
				_respecConfirmationPending = false;
				_showAwakening = false;
				_abilitiesClass = null;
				PlayerClassData? current = ClassManager.Current;
				if (current != null && current.BaseClass == BaseClass.None)
				{
					_baseClassPageIndex = 0;
				}
				GetOrAddFade(_panel).Show();
				Refresh();
				GUIManager.BlockInput(true);
			}
		}

		public static void Close()
		{
			_pendingBaseClass = null;
			if ((Object)(object)_panel != (Object)null && _panel.activeSelf)
			{
				GetOrAddFade(_panel).Hide();
			}
			_player = null;
			_respecConfirmationPending = false;
			GUIManager.BlockInput(false);
		}

		internal static void CloseAfterSuccess()
		{
			CloseImmediate();
		}

		private static void CloseImmediate()
		{
			_pendingBaseClass = null;
			if ((Object)(object)_panel != (Object)null)
			{
				_panel.SetActive(false);
			}
			_player = null;
			_respecConfirmationPending = false;
			GUIManager.BlockInput(false);
		}

		private static void OnClassDataChanged(PlayerClassData data)
		{
			_showAwakening = false;
			_abilitiesClass = null;
			if (IsOpen)
			{
				Refresh();
			}
		}

		private static void OnAwakeningAvailable(PlayerClassData data, ClassStage stage)
		{
			if (IsOpen)
			{
				Refresh();
			}
		}

		private static void OnAwakeningCompleted(PlayerClassData data, ClassStage stage)
		{
			if (IsOpen)
			{
				CloseAfterSuccess();
			}
		}

		private static void OnCustomGUIAvailable()
		{
			_panel = null;
			_polished = false;
			ClearPolishedReferences();
			DynamicObjects.Clear();
			EnsurePanel();
		}

		private static void EnsurePanel()
		{
			if ((Object)(object)_panel != (Object)null || GUIManager.Instance == null || (Object)(object)GUIManager.CustomGUIFront == (Object)null)
			{
				return;
			}
			GameObject val = VisualAssetService.Load<GameObject>("HECS_ClassAltarCanvas");
			if ((Object)(object)val != (Object)null)
			{
				_panel = Object.Instantiate<GameObject>(val, GUIManager.CustomGUIFront.transform, false);
				((Object)_panel).name = "HECS_ClassAltarPanel";
				_panel.SetActive(false);
				_polished = BindPolishedUi(_panel);
				if (_polished)
				{
					Image val2 = FindComponent<Image>(_panel.transform, "NorseFrame");
					if ((Object)(object)val2 != (Object)null)
					{
						NorseUiTheme.ApplyBackground(val2);
					}
					HarrisonEpicClassSystemPlugin.Log.LogInfo((object)"Using polished AssetBundle Altar UI.");
					return;
				}
				HarrisonEpicClassSystemPlugin.Log.LogWarning((object)"HECS_ClassAltarCanvas was loaded but required named controls were missing. Falling back to generated UI.");
				Object.Destroy((Object)(object)_panel);
				_panel = null;
			}
			BuildFallbackPanel();
		}

		private static bool BindPolishedUi(GameObject root)
		{
			//IL_02e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ef: Expected O, but got Unknown
			//IL_031d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0322: Unknown result type (might be due to invalid IL or missing references)
			//IL_0328: Expected O, but got Unknown
			//IL_0356: Unknown result type (might be due to invalid IL or missing references)
			//IL_035b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0361: Expected O, but got Unknown
			//IL_038f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0394: Unknown result type (might be due to invalid IL or missing references)
			//IL_039a: Expected O, but got Unknown
			//IL_03c8: 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)
			//IL_03d3: Expected O, but got Unknown
			//IL_0401: Unknown result type (might be due to invalid IL or missing references)
			//IL_0406: Unknown result type (might be due to invalid IL or missing references)
			//IL_040c: Expected O, but got Unknown
			Button val = FindComponent<Button>(root.transform, "CloseButton");
			_awakenButton = FindComponent<Button>(root.transform, "AwakenButton");
			_changeClassButton = FindComponent<Button>(root.transform, "ChangeClassButton");
			_currentClassText = FindGameObject(root.transform, "CurrentClassText");
			_currentLevelText = FindGameObject(root.transform, "CurrentLevelText");
			_targetClassText = FindGameObject(root.transform, "TargetClassText");
			_requirementsText = FindGameObject(root.transform, "RequirementsText");
			_statusText = FindGameObject(root.transform, "StatusText");
			_classIcon = FindComponent<Image>(root.transform, "ClassIcon");
			_baseClassNameText = FindGameObject(root.transform, "BaseClassNameText");
			_baseClassDescriptionText = FindGameObject(root.transform, "BaseClassDescriptionText");
			_baseClassPathsText = FindGameObject(root.transform, "BaseClassPathsText");
			_classPageText = FindGameObject(root.transform, "ClassPageText");
			_baseClassPreviewImage = FindComponent<Image>(root.transform, "ClassPreviewImage");
			_previousClassButton = FindComponent<Button>(root.transform, "PreviousClassButton");
			_nextClassButton = FindComponent<Button>(root.transform, "NextClassButton");
			_chooseClassButton = FindComponent<Button>(root.transform, "ChooseClassButton");
			for (int i = 0; i < 3; i++)
			{
				BranchButtons[i] = FindComponent<Button>(root.transform, $"BranchButton{i + 1}");
				BranchLabels[i] = FindGameObject(root.transform, $"BranchLabel{i + 1}");
			}
			if ((Object)(object)val == (Object)null || (Object)(object)_awakenButton == (Object)null || (Object)(object)_changeClassButton == (Object)null || (Object)(object)_currentClassText == (Object)null || (Object)(object)_currentLevelText == (Object)null || (Object)(object)_targetClassText == (Object)null || (Object)(object)_requirementsText == (Object)null || (Object)(object)_statusText == (Object)null || (Object)(object)_classIcon == (Object)null || (Object)(object)_baseClassNameText == (Object)null || (Object)(object)_baseClassDescriptionText == (Object)null || (Object)(object)_baseClassPathsText == (Object)null || (Object)(object)_classPageText == (Object)null || (Object)(object)_baseClassPreviewImage == (Object)null || (Object)(object)_previousClassButton == (Object)null || (Object)(object)_nextClassButton == (Object)null || (Object)(object)_chooseClassButton == (Object)null)
			{
				return false;
			}
			Button[] componentsInChildren = root.GetComponentsInChildren<Button>(true);
			for (int j = 0; j < componentsInChildren.Length; j++)
			{
				NorseUiTheme.ApplyButton(componentsInChildren[j]);
			}
			((UnityEventBase)val.onClick).RemoveAllListeners();
			ButtonClickedEvent onClick = val.onClick;
			object obj = <>O.<4>__Close;
			if (obj == null)
			{
				UnityAction val2 = Close;
				<>O.<4>__Close = val2;
				obj = (object)val2;
			}
			((UnityEvent)onClick).AddListener((UnityAction)obj);
			((UnityEventBase)_awakenButton.onClick).RemoveAllListeners();
			ButtonClickedEvent onClick2 = _awakenButton.onClick;
			object obj2 = <>O.<5>__OnAwakenClicked;
			if (obj2 == null)
			{
				UnityAction val3 = OnAwakenClicked;
				<>O.<5>__OnAwakenClicked = val3;
				obj2 = (object)val3;
			}
			((UnityEvent)onClick2).AddListener((UnityAction)obj2);
			((UnityEventBase)_changeClassButton.onClick).RemoveAllListeners();
			ButtonClickedEvent onClick3 = _changeClassButton.onClick;
			object obj3 = <>O.<6>__OnChangeClassClicked;
			if (obj3 == null)
			{
				UnityAction val4 = OnChangeClassClicked;
				<>O.<6>__OnChangeClassClicked = val4;
				obj3 = (object)val4;
			}
			((UnityEvent)onClick3).AddListener((UnityAction)obj3);
			((UnityEventBase)_previousClassButton.onClick).RemoveAllListeners();
			ButtonClickedEvent onClick4 = _previousClassButton.onClick;
			object obj4 = <>O.<7>__ShowPreviousBaseClassPage;
			if (obj4 == null)
			{
				UnityAction val5 = ShowPreviousBaseClassPage;
				<>O.<7>__ShowPreviousBaseClassPage = val5;
				obj4 = (object)val5;
			}
			((UnityEvent)onClick4).AddListener((UnityAction)obj4);
			((UnityEventBase)_nextClassButton.onClick).RemoveAllListeners();
			ButtonClickedEvent onClick5 = _nextClassButton.onClick;
			object obj5 = <>O.<8>__ShowNextBaseClassPage;
			if (obj5 == null)
			{
				UnityAction val6 = ShowNextBaseClassPage;
				<>O.<8>__ShowNextBaseClassPage = val6;
				obj5 = (object)val6;
			}
			((UnityEvent)onClick5).AddListener((UnityAction)obj5);
			((UnityEventBase)_chooseClassButton.onClick).RemoveAllListeners();
			ButtonClickedEvent onClick6 = _chooseClassButton.onClick;
			object obj6 = <>O.<9>__ChooseCurrentBaseClassPage;
			if (obj6 == null)
			{
				UnityAction val7 = ChooseCurrentBaseClassPage;
				<>O.<9>__ChooseCurrentBaseClassPage = val7;
				obj6 = (object)val7;
			}
			((UnityEvent)onClick6).AddListener((UnityAction)obj6);
			SetOptionalNamedObject(root.transform, "WarriorButton", active: false);
			SetOptionalNamedObject(root.transform, "MageButton", active: false);
			SetOptionalNamedObject(root.transform, "HunterButton", active: false);
			SetOptionalNamedObject(root.transform, "RogueButton", active: false);
			SetOptionalNamedObject(root.transform, "PaladinButton", active: false);
			return true;
		}

		private static void BuildFallbackPanel()
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected O, but got Unknown
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: 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_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Expected O, but got Unknown
			_polished = false;
			_panel = new GameObject("HECS_ClassAltarPanel", new Type[3]
			{
				typeof(RectTransform),
				typeof(CanvasRenderer),
				typeof(Image)
			});
			_panel.transform.SetParent(GUIManager.CustomGUIFront.transform, false);
			RectTransform component = _panel.GetComponent<RectTransform>();
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(0.5f, 0.5f);
			component.pivot = val;
			Vector2 anchorMin = (component.anchorMax = val);
			component.anchorMin = anchorMin;
			component.anchoredPosition = Vector2.zero;
			component.sizeDelta = new Vector2(950f, 775f);
			NorseUiTheme.ApplyBackground(_panel.GetComponent<Image>());
			((Object)_panel).name = "HECS_ClassAltarPanel";
			_panel.SetActive(false);
			GameObject obj = GUIManager.Instance.CreateButton("X", _panel.transform, new Vector2(1f, 1f), new Vector2(1f, 1f), new Vector2(-30f, -30f), 45f, 45f);
			ButtonClickedEvent onClick = obj.GetComponent<Button>().onClick;
			object obj2 = <>O.<4>__Close;
			if (obj2 == null)
			{
				UnityAction val3 = Close;
				<>O.<4>__Close = val3;
				obj2 = (object)val3;
			}
			((UnityEvent)onClick).AddListener((UnityAction)obj2);
			NorseUiTheme.ApplyButton(obj.GetComponent<Button>());
		}

		private static void Refresh()
		{
			if (!((Object)(object)_panel == (Object)null) && !((Object)(object)_player == (Object)null))
			{
				if (_polished)
				{
					Object.Destroy((Object)(object)_panel);
					_panel = null;
					BuildFallbackPanel();
					(_panel.GetComponent<AltarGuiScale>() ?? _panel.AddComponent<AltarGuiScale>()).Apply();
					GetOrAddFade(_panel).Show();
				}
				if (_polished)
				{
					RefreshPolished();
				}
				else
				{
					RefreshFallback();
				}
			}
		}

		private static void RefreshPolished()
		{
			PlayerClassData current = ClassManager.Current;
			if (current == null)
			{
				TMProBridge.SetText(_statusText, "Class data is not loaded.");
				return;
			}
			int level = WackyEpicMmoApi.GetLevel();
			TMProBridge.SetText(_currentClassText, (current.CurrentClass == ClassId.None) ? "No Class" : current.CurrentClass.ToString());
			TMProBridge.SetText(_currentLevelText, $"Level: {level}");
			TMProBridge.SetText(_statusText, string.Empty);
			SetClassIcon(current.CurrentClass);
			SetNamedGroup("BaseClassSelection", current.BaseClass == BaseClass.None);
			SetNamedGroup("AwakeningPanel", current.BaseClass != BaseClass.None);
			if ((Object)(object)_changeClassButton != (Object)null)
			{
				((Component)_changeClassButton).gameObject.SetActive(current.BaseClass != BaseClass.None);
				((Selectable)_changeClassButton).interactable = current.BaseClass != BaseClass.None;
				TMProBridge.SetText(FindGameObject(((Component)_changeClassButton).transform, "Text") ?? ((Component)_changeClassButton).gameObject, _respecConfirmationPending ? "Confirm Reset Class" : "Change Class");
			}
			if (current.BaseClass == BaseClass.None)
			{
				TMProBridge.SetText(_targetClassText, "Choose a starting class");
				TMProBridge.SetText(_requirementsText, "Browse each class, review its role and promotion paths, then confirm your choice.");
				((Selectable)_awakenButton).interactable = false;
				SetBranches(Array.Empty<ClassProgressionPath>(), canAwaken: false);
				RefreshBaseClassPagePolished();
				return;
			}
			ClassStage? availableAwakening = ClassProgressionService.GetAvailableAwakening(current, level);
			if (!availableAwakening.HasValue)
			{
				SetBranches(Array.Empty<ClassProgressionPath>(), canAwaken: false);
				((Selectable)_awakenButton).interactable = false;
				if (current.CurrentStage == ClassStage.MythicPromotion)
				{
					TMProBridge.SetText(_targetClassText, "Mythic Awakening Complete");
					TMProBridge.SetText(_requirementsText, "No further awakening is available.");
					return;
				}
				ClassStage stage = current.CurrentStage + 1;
				int requiredLevel = ClassConfig.GetRequiredLevel(stage);
				TMProBridge.SetText(_targetClassText, stage.ToString());
				TMProBridge.SetText(_requirementsText, $"Required Level: {level}/{requiredLevel}");
				return;
			}
			AwakeningCheckResult awakeningCheckResult = AwakeningRequirementService.Check(_player, availableAwakening.Value);
			List<string> list = new List<string> { $"Level: {awakeningCheckResult.CurrentLevel}/{awakeningCheckResult.RequiredLevel}" };
			foreach (ResourceRequirement requirement in awakeningCheckResult.Requirements)
			{
				int playerItemCount = AwakeningRequirementService.GetPlayerItemCount(_player, requirement.PrefabName);
				list.Add($"{requirement.PrefabName}: {playerItemCount}/{requirement.Amount}");
			}
			TMProBridge.SetText(_requirementsText, string.Join("\n", list));
			if (availableAwakening == ClassStage.FirstPromotion)
			{
				IReadOnlyList<ClassProgressionPath> paths = ClassRegistry.GetPaths(current.BaseClass);
				TMProBridge.SetText(_targetClassText, "Choose First Promotion");
				SetBranches(paths, awakeningCheckResult.CanAwaken);
				((Selectable)_awakenButton).interactable = false;
			}
			else
			{
				SetBranches(Array.Empty<ClassProgressionPath>(), canAwaken: false);
				ClassId classId = ClassRegistry.GetPath(current.SelectedPathId)?.GetClassForStage(availableAwakening.Value) ?? ClassId.None;
				TMProBridge.SetText(_targetClassText, (classId == ClassId.None) ? availableAwakening.Value.ToString() : classId.ToString());
				((Selectable)_awakenButton).interactable = awakeningCheckResult.CanAwaken && classId != ClassId.None;
				TMProBridge.SetText(FindGameObject(((Component)_awakenButton).transform, "Text") ?? ((Component)_awakenButton).gameObject, $"Awaken to {classId}");
			}
		}

		private static void OnChangeClassClicked()
		{
			if ((Object)(object)_player == (Object)null || ClassManager.Current == null)
			{
				return;
			}
			if (!_respecConfirmationPending)
			{
				_respecConfirmationPending = true;
				TMProBridge.SetText(_statusText, "Changing class will reset all HECS class progression. Click Confirm Reset Class to continue.");
				if ((Object)(object)_changeClassButton != (Object)null)
				{
					TMProBridge.SetText(FindGameObject(((Component)_changeClassButton).transform, "Text") ?? ((Component)_changeClassButton).gameObject, "Confirm Reset Class");
				}
				Refresh();
			}
			else if (!ClassRespecService.ResetToUnassigned(_player))
			{
				((Character)_player).Message((MessageType)2, "Class reset requires Light of the God and coins. Check the required amounts.", 0, (Sprite)null, false);
				Refresh();
			}
		}

		private static void OnAwakenClicked()
		{
			if ((Object)(object)_player == (Object)null)
			{
				return;
			}
			PlayerClassData current = ClassManager.Current;
			if (current != null)
			{
				int level = WackyEpicMmoApi.GetLevel();
				ClassStage? availableAwakening = ClassProgressionService.GetAvailableAwakening(current, level);
				if (availableAwakening.HasValue && availableAwakening != ClassStage.FirstPromotion)
				{
					ClassAwakeningService.TryAwaken(_player, availableAwakening.Value);
				}
			}
		}

		private static void SetBranches(IReadOnlyList<ClassProgressionPath> paths, bool canAwaken)
		{
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Expected O, but got Unknown
			for (int i = 0; i < BranchButtons.Length; i++)
			{
				Button val = BranchButtons[i];
				GameObject val2 = BranchLabels[i];
				bool flag = i < paths.Count && (Object)(object)val != (Object)null;
				if ((Object)(object)val != (Object)null)
				{
					((Component)val).gameObject.SetActive(flag);
					((UnityEventBase)val.onClick).RemoveAllListeners();
				}
				if ((Object)(object)val2 != (Object)null)
				{
					val2.SetActive(flag);
				}
				if (!flag)
				{
					continue;
				}
				ClassProgressionPath classProgressionPath = paths[i];
				((Selectable)val).interactable = canAwaken;
				TMProBridge.SetText(val2 ?? ((Component)val).gameObject, classProgressionPath.FirstPromotionClass.ToString());
				string pathId = classProgressionPath.Id;
				((UnityEvent)val.onClick).AddListener((UnityAction)delegate
				{
					if ((Object)(object)_player != (Object)null)
					{
						ClassAwakeningService.TryAwaken(_player, ClassStage.FirstPromotion, pathId);
					}
				});
			}
		}

		private static void SetClassIcon(ClassId id)
		{
			if (!((Object)(object)_classIcon == (Object)null))
			{
				Sprite classIcon = VisualAssetService.GetClassIcon(id);
				_classIcon.sprite = classIcon;
				((Behaviour)_classIcon).enabled = (Object)(object)classIcon != (Object)null;
				_classIcon.preserveAspect = true;
			}
		}

		private static void SetNamedGroup(string name, bool active)
		{
			GameObject val = FindGameObject(_panel.transform, name);
			if ((Object)(object)val != (Object)null)
			{
				val.SetActive(active);
			}
		}

		private static void RefreshFallback()
		{
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_panel == (Object)null || (Object)(object)_player == (Object)null)
			{
				return;
			}
			foreach (GameObject dynamicObject in DynamicObjects)
			{
				if ((Object)(object)dynamicObject != (Object)null)
				{
					dynamicObject.SetActive(false);
					Object.Destroy((Object)(object)dynamicObject);
				}
			}
			DynamicObjects.Clear();
			AddText("HARRISON CLASS ALTAR", new Vector2(0f, 310f), 30, GUIManager.Instance.ValheimOrange, 800f, 50f);
			PlayerClassData current2 = ClassManager.Current;
			if (current2 == null)
			{
				AddText("Class data is not loaded.", new Vector2(0f, 100f), 22, Color.white, 600f, 40f);
			}
			else if (_abilitiesClass.HasValue)
			{
				RenderAbilities(_abilitiesClass.Value);
			}
			else if (current2.BaseClass == BaseClass.None)
			{
				if (_pendingBaseClass.HasValue)
				{
					RenderBaseClassConfirmation(_pendingBaseClass.Value);
				}
				else
				{
					RenderFallbackBaseClassSelection();
				}
			}
			else if (_showAwakening)
			{
				RenderFallbackAwakening(current2);
			}
			else
			{
				RenderCurrentClass(current2);
			}
		}

		private static void RenderFallbackBaseClassSelection()
		{
			//IL_0032: 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_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Expected O, but got Unknown
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: 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_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Expected O, but got Unknown
			//IL_021f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0200: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: Expected O, but got Unknown
			//IL_024d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0252: Unknown result type (might be due to invalid IL or missing references)
			//IL_0258: Expected O, but got Unknown
			BaseClass currentBaseClassPage = GetCurrentBaseClassPage();
			ClassId classId = ClassRegistry.GetBaseClassId(currentBaseClassPage);
			ClassDefinition? classDefinition = ClassRegistry.GetClass(classId);
			AddText("CHOOSE YOUR STARTING CLASS", new Vector2(0f, 205f), 24, Color.white, 650f, 42f);
			AddFallbackClassPreviewImage(classId, new Vector2(-225f, 70f), 200f, 200f);
			RenderEquipmentGuidance(classId);
			((UnityEvent)AddButton("Class Effects", new Vector2(0f, -175f), 220f, 36f).GetComponent<Button>().onClick).AddListener((UnityAction)delegate
			{
				ShowAbilities(classId);
			});
			AddText(classDefinition?.DisplayName ?? currentBaseClassPage.ToString(), new Vector2(110f, 120f), 28, GUIManager.Instance.ValheimOrange, 410f, 42f);
			AddText(classDefinition?.Description ?? string.Empty, new Vector2(110f, 65f), 17, Color.white, 410f, 90f);
			AddText(BuildPathSummary(currentBaseClassPage), new Vector2(110f, -45f), 16, Color.white, 410f, 125f);
			ButtonClickedEvent onClick = AddButton("< Previous", new Vector2(-225f, -225f), 190f, 48f).GetComponent<Button>().onClick;
			object obj = <>O.<7>__ShowPreviousBaseClassPage;
			if (obj == null)
			{
				UnityAction val = ShowPreviousBaseClassPage;
				<>O.<7>__ShowPreviousBaseClassPage = val;
				obj = (object)val;
			}
			((UnityEvent)onClick).AddListener((UnityAction)obj);
			ButtonClickedEvent onClick2 = AddButton($"Choose {currentBaseClassPage}", new Vector2(0f, -225f), 220f, 52f).GetComponent<Button>().onClick;
			object obj2 = <>O.<9>__ChooseCurrentBaseClassPage;
			if (obj2 == null)
			{
				UnityAction val2 = ChooseCurrentBaseClassPage;
				<>O.<9>__ChooseCurrentBaseClassPage = val2;
				obj2 = (object)val2;
			}
			((UnityEvent)onClick2).AddListener((UnityAction)obj2);
			ButtonClickedEvent onClick3 = AddButton("Next >", new Vector2(225f, -225f), 190f, 48f).GetComponent<Button>().onClick;
			object obj3 = <>O.<8>__ShowNextBaseClassPage;
			if (obj3 == null)
			{
				UnityAction val3 = ShowNextBaseClassPage;
				<>O.<8>__ShowNextBaseClassPage = val3;
				obj3 = (object)val3;
			}
			((UnityEvent)onClick3).AddListener((UnityAction)obj3);
		}

		private static void RenderFallbackAwakening(PlayerClassData data)
		{
			RenderAwakeningBrowser(data);
		}

		private static BaseClass GetCurrentBaseClassPage()
		{
			if (_baseClassPageIndex < 0 || _baseClassPageIndex >= BaseClassPages.Length)
			{
				_baseClassPageIndex = 0;
			}
			return BaseClassPages[_baseClassPageIndex];
		}

		private static void ShowPreviousBaseClassPage()
		{
			_baseClassPageIndex = (_baseClassPageIndex - 1 + BaseClassPages.Length) % BaseClassPages.Length;
			Refresh();
		}

		private static void ShowNextBaseClassPage()
		{
			_baseClassPageIndex = (_baseClassPageIndex + 1) % BaseClassPages.Length;
			Refresh();
		}

		private static void ChooseCurrentBaseClassPage()
		{
			_pendingBaseClass = GetCurrentBaseClassPage();
			Refresh();
		}

		private static void RenderBaseClassConfirmation(BaseClass selected)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: 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)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: 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_00f5: Expected O, but got Unknown
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Expected O, but got Unknown
			ClassId baseClassId = ClassRegistry.GetBaseClassId(selected);
			AddFallbackClassPreviewImage(baseClassId, new Vector2(-225f, 70f), 200f, 200f);
			RenderEquipmentGuidance(baseClassId);
			AddText($"Choose {selected}?", new Vector2(110f, 155f), 28, GUIManager.Instance.ValheimOrange, 410f, 50f);
			AddText("Choose carefully. Changing class later requires rare materials.\n\nConfirm this class or Cancel to keep browsing.", new Vector2(110f, 70f), 19, Color.white, 410f, 115f);
			((UnityEvent)AddButton($"Confirm {selected}", new Vector2(110f, -210f), 250f, 52f).GetComponent<Button>().onClick).AddListener((UnityAction)delegate
			{
				if (_pendingBaseClass == selected && (Object)(object)_player == (Object)(object)Player.m_localPlayer)
				{
					PlayerClassData? current = ClassManager.Current;
					if (current != null && current.BaseClass == BaseClass.None && !ClassProgressionService.SelectBaseClassAtAltar(selected))
					{
						_pendingBaseClass = null;
						Refresh();
					}
				}
			});
			ButtonClickedEvent onClick = AddButton("Cancel", new Vector2(-225f, -210f), 190f, 48f).GetComponent<Button>().onClick;
			object obj = <>c.<>9__61_1;
			if (obj == null)
			{
				UnityAction val = delegate
				{
					_pendingBaseClass = null;
					Refresh();
				};
				<>c.<>9__61_1 = val;
				obj = (object)val;
			}
			((UnityEvent)onClick).AddListener((UnityAction)obj);
		}

		private static string BuildPathSummary(BaseClass baseClass)
		{
			IReadOnlyList<ClassProgressionPath> paths = ClassRegistry.GetPaths(baseClass);
			if (paths.Count == 0)
			{
				return "No promotion paths are configured.";
			}
			List<string> list = new List<string> { "Promotion Paths:" };
			foreach (ClassProgressionPath item in paths)
			{
				list.Add($"• {item.FirstPromotionClass} → {item.SecondPromotionClass} → {item.MythicPromotionClass}");
			}
			return string.Join("\n", list);
		}

		private static void RefreshBaseClassPagePolished()
		{
			BaseClass currentBaseClassPage = GetCurrentBaseClassPage();
			ClassId baseClassId = ClassRegistry.GetBaseClassId(currentBaseClassPage);
			ClassDefinition classDefinition = ClassRegistry.GetClass(baseClassId);
			TMProBridge.SetText(_baseClassNameText, classDefinition?.DisplayName ?? currentBaseClassPage.ToString());
			TMProBridge.SetText(_baseClassDescriptionText, (classDefinition?.Description ?? string.Empty) + "\n\n" + SuggestedEquipmentText(baseClassId));
			TMProBridge.SetText(_baseClassPathsText, BuildPathSummary(currentBaseClassPage));
			TMProBridge.SetText(_classPageText, string.Empty);
			GameObject? classPageText = _classPageText;
			if (classPageText != null)
			{
				classPageText.SetActive(false);
			}
			TMProBridge.SetText(FindGameObject(((Component)_chooseClassButton).transform, "Text") ?? ((Component)_chooseClassButton).gameObject, $"Choose {currentBaseClassPage}");
			Sprite classIcon = VisualAssetService.GetClassIcon(baseClassId);
			_baseClassPreviewImage.sprite = classIcon;
			((Behaviour)_baseClassPreviewImage).enabled = (Object)(object)classIcon != (Object)null;
			_baseClassPreviewImage.preserveAspect = true;
		}

		private static void AddFallbackClassPreviewImage(ClassId classId, Vector2 position, float width, float height)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Expected O, but got Unknown
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			Sprite classIcon = VisualAssetService.GetClassIcon(classId);
			if ((Object)(object)classIcon == (Object)null || (Object)(object)_panel == (Object)null)
			{
				AddText("Class image unavailable", position, 15, Color.gray, width, 35f);
				return;
			}
			GameObject val = new GameObject("HECS_BaseClassPreview", new Type[3]
			{
				typeof(RectTransform),
				typeof(CanvasRenderer),
				typeof(Image)
			});
			val.transform.SetParent(_panel.transform, false);
			RectTransform component = val.GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0.5f, 0.5f);
			component.anchorMax = new Vector2(0.5f, 0.5f);
			component.pivot = new Vector2(0.5f, 0.5f);
			component.anchoredPosition = position;
			component.sizeDelta = new Vector2(width, height);
			Image component2 = val.GetComponent<Image>();
			component2.sprite = classIcon;
			component2.preserveAspect = true;
			((Graphic)component2).raycastTarget = false;
			DynamicObjects.Add(val);
		}

		private static void SetOptionalNamedObject(Transform root, string name, bool active)
		{
			GameObject val = FindGameObject(root, name);
			if ((Object)(object)val != (Object)null)
			{
				val.SetActive(active);
			}
		}

		private static GameObject AddButton(string text, Vector2 position, float width, float height)
		{
			//IL_001a: 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_002e: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = GUIManager.Instance.CreateButton(text, _panel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), position, width, height);
			NorseUiTheme.ApplyButton(val.GetComponent<Button>());
			DynamicObjects.Add(val);
			return val;
		}

		private static GameObject AddText(string text, Vector2 position, int fontSize, Color color, float width, float height)
		{
			//IL_001a: 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_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = GUIManager.Instance.CreateText(text, _panel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), position, GUIManager.Instance.AveriaSerifBold, fontSize, color, true, Color.black, width, height, false);
			DynamicObjects.Add(val);
			return val;
		}

		private static UiFadeController GetOrAddFade(GameObject target)
		{
			return target.GetComponent<UiFadeController>() ?? target.AddComponent<UiFadeController>();
		}

		private static T? FindComponent<T>(Transform root, string name) where T : Component
		{
			GameObject val = FindGameObject(root, name);
			if (!((Object)(object)val != (Object)null))
			{
				return default(T);
			}
			return val.GetComponent<T>();
		}

		private static GameObject? FindGameObject(Transform root, string name)
		{
			if (((Object)root).name == name)
			{
				return ((Component)root).gameObject;
			}
			for (int i = 0; i < root.childCount; i++)
			{
				GameObject val = FindGameObject(root.GetChild(i), name);
				if ((Object)(object)val != (Object)null)
				{
					return val;
				}
			}
			return null;
		}

		private static void ClearPolishedReferences()
		{
			_currentClassText = null;
			_currentLevelText = null;
			_targetClassText = null;
			_requirementsText = null;
			_statusText = null;
			_classIcon = null;
			_awakenButton = null;
			_changeClassButton = null;
			_baseClassNameText = null;
			_baseClassDescriptionText = null;
			_baseClassPathsText = null;
			_classPageText = null;
			_baseClassPreviewImage = null;
			_previousClassButton = null;
			_nextClassButton = null;
			_chooseClassButton = null;
			for (int i = 0; i < 3; i++)
			{
				BranchButtons[i] = null;
				BranchLabels[i] = null;
			}
		}

		private static IReadOnlyList<ClassProgressionPath> GetAwakeningPaths(PlayerClassData data)
		{
			if (data.CurrentStage == ClassStage.Base)
			{
				return ClassRegistry.GetPaths(data.BaseClass);
			}
			ClassProgressionPath path = ClassRegistry.GetPath(data.SelectedPathId);
			if (path == null || path.RootClass != data.BaseClass)
			{
				return Array.Empty<ClassProgressionPath>();
			}
			return new ClassProgressionPath[1] { path };
		}

		private static void RenderAwakeningBrowser(PlayerClassData data)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Expected O, but got Unknown
			//IL_00b8: 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_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_025f: Unknown result type (might be due to invalid IL or missing references)
			//IL_028d: 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_02bc: Expected O, but got Unknown
			//IL_02d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0375: Unknown result type (might be due to invalid IL or missing references)
			//IL_037c: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_041e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0457: Unknown result type (might be due to invalid IL or missing references)
			//IL_0461: Expected O, but got Unknown
			//IL_0480: Unknown result type (might be due to invalid IL or missing references)
			//IL_04bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c9: Expected O, but got Unknown
			//IL_04d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0511: Unknown result type (might be due to invalid IL or missing references)
			//IL_051b: Expected O, but got Unknown
			AddText($"Current Class: {data.CurrentClass}\nLevel: {WackyEpicMmoApi.GetLevel()}", new Vector2(-225f, 205f), 16, Color.white, 235f, 55f);
			ButtonClickedEvent onClick = AddButton("Back to Current Class", new Vector2(0f, -270f), 260f, 42f).GetComponent<Button>().onClick;
			object obj = <>c.<>9__77_0;
			if (obj == null)
			{
				UnityAction val = delegate
				{
					_showAwakening = false;
					Refresh();
				};
				<>c.<>9__77_0 = val;
				obj = (object)val;
			}
			((UnityEvent)onClick).AddListener((UnityAction)obj);
			if (data.CurrentStage == ClassStage.MythicPromotion)
			{
				AddFallbackClassPreviewImage(data.CurrentClass, new Vector2(-225f, 70f), 200f, 200f);
				RenderEquipmentGuidance(data.CurrentClass);
				AddText(data.CurrentClass.ToString(), new Vector2(110f, 135f), 28, GUIManager.Instance.ValheimOrange, 410f, 45f);
				AddText("Mythic awakening complete.\nNo further awakening is available.", new Vector2(110f, 45f), 20, Color.white, 410f, 100f);
				return;
			}
			ClassStage stage = data.CurrentStage + 1;
			IReadOnlyList<ClassProgressionPath> paths = GetAwakeningPaths(data);
			string text = $"{data.PlayerId}:{data.BaseClass}:{stage}:{data.SelectedPathId}";
			if (_awakeningContext != text)
			{
				_awakeningContext = text;
				_awakeningPage = 0;
			}
			if (paths.Count == 0)
			{
				AddText("No valid promotion path is available.", Vector2.zero, 20, Color.white, 650f, 50f);
				return;
			}
			_awakeningPage = Mathf.Clamp(_awakeningPage, 0, paths.Count - 1);
			ClassProgressionPath path = paths[_awakeningPage];
			ClassId target = path.GetClassForStage(stage);
			AwakeningCheckResult awakeningCheckResult = AwakeningRequirementService.Check(_player, stage, path.Id);
			AddFallbackClassPreviewImage(target, new Vector2(-225f, 70f), 200f, 200f);
			RenderEquipmentGuidance(target);
			((UnityEvent)AddButton("Class Effects", new Vector2(0f, -160f), 240f, 36f).GetComponent<Button>().onClick).AddListener((UnityAction)delegate
			{
				ShowAbilities(target);
			});
			AddText(target.ToString(), new Vector2(110f, 155f), 28, GUIManager.Instance.ValheimOrange, 410f, 45f);
			string text2 = ((stage == ClassStage.FirstPromotion) ? "First Promotion" : ((stage == ClassStage.SecondPromotion) ? "Second Promotion" : "Mythic Promotion"));
			AddText($"{text2}\n{path.FirstPromotionClass} → {path.SecondPromotionClass} → {path.MythicPromotionClass}", new Vector2(110f, 95f), 17, Color.white, 410f, 70f);
			AddText($"Required Level: {awakeningCheckResult.CurrentLevel} / {awakeningCheckResult.RequiredLevel}", new Vector2(110f, 40f), 18, awakeningCheckResult.LevelMet ? new Color(0.6f, 0.9f, 0.65f) : new Color(1f, 0.5f, 0.4f), 410f, 30f);
			RenderMaterialIcons(awakeningCheckResult.Requirements);
			Button component = AddButton("< Previous", new Vector2(-225f, -210f), 190f, 48f).GetComponent<Button>();
			((Selectable)component).interactable = paths.Count > 1;
			((UnityEvent)component.onClick).AddListener((UnityAction)delegate
			{
				ChangeAwakeningPage(-1, paths.Count);
			});
			Button component2 = AddButton($"Awaken to {target}", new Vector2(0f, -210f), 240f, 52f).GetComponent<Button>();
			((Selectable)component2).interactable = awakeningCheckResult.CanAwaken && target != ClassId.None;
			((UnityEvent)component2.onClick).AddListener((UnityAction)delegate
			{
				if ((Object)(object)_player != (Object)null && !ClassAwakeningService.TryAwaken(_player, stage, path.Id))
				{
					Refresh();
				}
			});
			Button component3 = AddButton("Next >", new Vector2(225f, -210f), 190f, 48f).GetComponent<Button>();
			((Selectable)component3).interactable = paths.Count > 1;
			((UnityEvent)component3.onClick).AddListener((UnityAction)delegate
			{
				ChangeAwakeningPage(1, paths.Count);
			});
			_materialSnapshot = BuildMaterialSnapshot();
		}

		private static void ChangeAwakeningPage(int delta, int count)
		{
			_awakeningPage = (_awakeningPage + delta + count) % count;
			Refresh();
		}

		private static void RenderEquipmentGuidance(ClassId id)
		{
			//IL_0010: 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)
			Text[] componentsInChildren = AddText(SuggestedEquipmentText(id), new Vector2(-225f, -90f), 16, Color.white, 200f, 115f).GetComponentsInChildren<Text>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				componentsInChildren[i].alignment = (TextAnchor)1;
			}
		}

		private static string SuggestedEquipmentText(ClassId id)
		{
			ClassEquipmentProfile profile = ClassEquipmentSuitability.GetProfile(id);
			if (profile == null)
			{
				return string.Empty;
			}
			return "Suggested Weapon:\n" + profile.Weapons + "\nSuggested Armor:\n" + (profile.HeavyArmor ? "Heavy chest + legs" : "Light chest + legs / robes");
		}

		private static void ShowAbilities(ClassId id)
		{
			_respecConfirmationPending = false;
			_abilitiesClass = id;
			Refresh();
		}

		private static void RenderCurrentClass(PlayerClassData data)
		{
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: 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_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_023f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0246: Unknown result type (might be due to invalid IL or missing references)
			//IL_0278: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f4: Expected O, but got Unknown
			//IL_0303: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b1: Expected O, but got Unknown
			//IL_034c: 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_0357: Expected O, but got Unknown
			if (_respecConfirmationPending)
			{
				RenderResetConfirmation(data);
				return;
			}
			ClassDefinition? classDefinition = ClassRegistry.GetClass(data.CurrentClass);
			AddText(_respecConfirmationPending ? "Reset class progression? Your level is kept. Click Confirm Reset." : $"CURRENT CLASS  |  Level {WackyEpicMmoApi.GetLevel()}", new Vector2(0f, 235f), 18, Color.white, 800f, 40f);
			AddFallbackClassPreviewImage(data.CurrentClass, new Vector2(-225f, 70f), 200f, 200f);
			RenderEquipmentGuidance(data.CurrentClass);
			AddText(classDefinition?.DisplayName ?? data.CurrentClass.ToString(), new Vector2(110f, 165f), 28, GUIManager.Instance.ValheimOrange, 410f, 45f);
			AddText("Stage: " + StageLabel(data.CurrentStage), new Vector2(110f, 115f), 18, Color.white, 410f, 35f);
			string text = classDefinition?.Description ?? string.Empty;
			if (string.IsNullOrEmpty(text))
			{
				text = ClassRegistry.GetClass(ClassRegistry.GetBaseClassId(data.BaseClass))?.Description ?? string.Empty;
			}
			ClassProgressionPath path = ClassRegistry.GetPath(data.SelectedPathId);
			AddText(text, new Vector2(110f, 40f), 18, Color.white, 410f, 95f);
			string text2 = ((data.CurrentStage == ClassStage.MythicPromotion) ? "Mythic awakening complete." : $"Next awakening: level {ClassConfig.GetRequiredLevel(data.CurrentStage + 1)}.\nSelect Awaken to review the next class and materials.");
			if (path != null)
			{
				text2 += $"\n{path.FirstPromotionClass} → {path.SecondPromotionClass} → {path.MythicPromotionClass}";
			}
			AddText(text2, new Vector2(110f, -85f), 17, Color.white, 410f, 105f);
			ButtonClickedEvent onClick = AddButton(_respecConfirmationPending ? "Confirm Reset Class" : "Change Class", new Vector2(-225f, -270f), 210f, 48f).GetComponent<Button>().onClick;
			object obj = <>O.<6>__OnChangeClassClicked;
			if (obj == null)
			{
				UnityAction val = OnChangeClassClicked;
				<>O.<6>__OnChangeClassClicked = val;
				obj = (object)val;
			}
			((UnityEvent)onClick).AddListener((UnityAction)obj);
			((UnityEvent)AddButton("Class Effects", new Vector2(0f, -270f), 200f, 48f).GetComponent<Button>().onClick).AddListener((UnityAction)delegate
			{
				ShowAbilities(data.CurrentClass);
			});
			Button component = AddButton("Awaken", new Vector2(225f, -270f), 210f, 48f).GetComponent<Button>();
			((Selectable)component).interactable = data.CurrentStage != ClassStage.MythicPromotion;
			ButtonClickedEvent onClick2 = component.onClick;
			object obj2 = <>c.<>9__82_1;
			if (obj2 == null)
			{
				UnityAction val2 = delegate
				{
					_respecConfirmationPending = false;
					_showAwakening = true;
					Refresh();
				};
				<>c.<>9__82_1 = val2;
				obj2 = (object)val2;
			}
			((UnityEvent)onClick2).AddListener((UnityAction)obj2);
		}

		private static void RenderResetConfirmation(PlayerClassData data)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: 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_0085: 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_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: 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_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: 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_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Expected O, but got Unknown
			//IL_0217: Unknown result type (might be due to invalid IL or missing references)
			//IL_021c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: Expected O, but got Unknown
			IReadOnlyList<ResourceRequirement> requirements = ClassRespecService.GetRequirements(data.CurrentStage);
			AddText("RESET CLASS", new Vector2(0f, 235f), 26, GUIManager.Instance.ValheimOrange, 800f, 40f);
			AddFallbackClassPreviewImage(data.CurrentClass, new Vector2(-225f, 65f), 200f, 200f);
			AddText(data.CurrentClass.ToString(), new Vector2(-225f, -85f), 22, Color.white, 260f, 45f);
			AddText(StageLabel(data.CurrentStage) + " reset\nYour class, branch and awakenings will be cleared.\nYour level and attributes are kept.", new Vector2(110f, 125f), 18, Color.white, 410f, 115f);
			AddText("Items consumed on confirmation:", new Vector2(110f, 40f), 18, Color.white, 410f, 35f);
			RenderMaterialIcons(requirements);
			bool flag = AwakeningRequirementService.HasAllRequirements(_player, requirements);
			Text[] componentsInChildren = AddText(flag ? "Ready to reset. Spent awakening materials are not refunded." : "Bring all required materials to reset your class.", new Vector2(0f, -175f), 17, (Color)(flag ? Color.white : new Color(1f, 0.5f, 0.4f)), 780f, 55f).GetComponentsInChildren<Text>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				componentsInChildren[i].alignment = (TextAnchor)4;
			}
			Button component = AddButton("Confirm Reset Class", new Vector2(-160f, -270f), 270f, 48f).GetComponent<Button>();
			((Selectable)component).interactable = flag;
			ButtonClickedEvent onClick = component.onClick;
			object obj = <>O.<6>__OnChangeClassClicked;
			if (obj == null)
			{
				UnityAction val = OnChangeClassClicked;
				<>O.<6>__OnChangeClassClicked = val;
				obj = (object)val;
			}
			((UnityEvent)onClick).AddListener((UnityAction)obj);
			ButtonClickedEvent onClick2 = AddButton("Cancel", new Vector2(160f, -270f), 210f, 48f).GetComponent<Button>().onClick;
			object obj2 = <>c.<>9__83_0;
			if (obj2 == null)
			{
				UnityAction val2 = delegate
				{
					_respecConfirmationPending = false;
					Refresh();
				};
				<>c.<>9__83_0 = val2;
				obj2 = (object)val2;
			}
			((UnityEvent)onClick2).AddListener((UnityAction)obj2);
			_materialSnapshot = BuildMaterialSnapshot();
		}

		private static void RenderAbilities(ClassId id)
		{
			//IL_001a: 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_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: 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_011b: Expected O, but got Unknown
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_021a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0221: 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)
			//IL_02b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f3: 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_032a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0330: Expected O, but got Unknown
			AddText($"CLASS EFFECTS: {id}", new Vector2(0f, 235f), 26, GUIManager.Instance.ValheimOrange, 800f, 45f);
			string text = ClassEquipmentSuitability.Describe(id);
			BaseClass family = ClassRegistry.GetClass(id)?.RootClass ?? BaseClass.None;
			text = text + "\n\nAttribute passive:\n" + ClassEffectsDescription.AttributePassive(family, id);
			GameObject val = MaterialImage("AbilityDetails", _panel.transform, new Vector2(0f, -5f), new Vector2(790f, 405f), null, raycast: true);
			((Graphic)val.GetComponent<Image>()).color = new Color(0.025f, 0.03f, 0.035f, 0.65f);
			val.AddComponent<RectMask2D>();
			ScrollRect val2 = val.AddComponent<ScrollRect>();
			val2.horizontal = false;
			val2.movementType = (MovementType)2;
			val2.scrollSensitivity = 80f;
			val2.inertia = false;
			val2.viewport = val.GetComponent<RectTransform>();
			GameObject val3 = new GameObject("EquipmentDetails", new Type[1] { typeof(RectTransform) });
			val3.transform.SetParent(val.transform, false);
			RectTransform component = val3.GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0f, 1f);
			component.anchorMax = Vector2.one;
			component.pivot = new Vector2(0.5f, 1f);
			int num = 0;
			string[] array = text.Split(new char[1] { '\n' });
			foreach (string text2 in array)
			{
				num += Mathf.Max(1, Mathf.CeilToInt((float)text2.Length / 70f));
			}
			float num2 = Mathf.Max(405f, (float)num * 24f + 25f);
			component.sizeDelta = new Vector2(0f, num2);
			component.anchoredPosition = Vector2.zero;
			val2.content = component;
			GameObject val4 = MaterialText(ClassEffectFormatting.HighlightNumbers(text), val3.transform, new Vector2(0f, (0f - num2) / 2f), 18, Color.white, 760f, num2 - 12f);
			Text[] componentsInChildren = val3.GetComponentsInChildren<Text>(true);
			foreach (Text val5 in componentsInChildren)
			{
				val5.alignment = (TextAnchor)0;
				val5.supportRichText = true;
				val5.horizontalOverflow = (HorizontalWrapMode)0;
				num2 = Mathf.Max(405f, val5.preferredHeight + 20f);
			}
			component.sizeDelta = new Vector2(0f, num2);
			RectTransform component2 = val4.GetComponent<RectTransform>();
			component2.sizeDelta = new Vector2(760f, num2 - 12f);
			component2.anchoredPosition = new Vector2(0f, (0f - num2) / 2f);
			DynamicObjects.Add(val);
			ButtonClickedEvent onClick = AddButton("Back", new Vector2(0f, -280f), 220f, 48f).GetComponent<Button>().onClick;
			object obj = <>c.<>9__84_0;
			if (obj == null)
			{
				UnityAction val6 = delegate
				{
					_abilitiesClass = null;
					Refresh();
				};
				<>c.<>9__84_0 = val6;
				obj = (object)val6;
			}
			((UnityEvent)onClick).AddListener((UnityAction)obj);
		}

		private static string StageLabel(ClassStage stage)
		{
			return stage switch
			{
				ClassStage.FirstPromotion => "First Promotion", 
				ClassStage.SecondPromotion => "Second Promotion", 
				ClassStage.MythicPromotion => "Mythic Promotion", 
				_ => "Base", 
			};
		}

		private static GameObject MaterialImage(string name, Transform parent, Vector2 position, Vector2 size, Sprite? sprite, bool raycast, bool top = false)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: 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_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Expected O, but got Unknown
			GameObject val = new GameObject(name, new Type[3]
			{
				typeof(RectTransform),
				typeof(CanvasRenderer),
				typeof(Image)
			});
			val.transform.SetParent(parent, false);
			RectTransform component = val.GetComponent<RectTransform>();
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor(0.5f, top ? 1f : 0.5f);
			component.anchorMax = val2;
			component.anchorMin = val2;
			component.pivot = new Vector2(0.5f, 0.5f);
			component.anchoredPosition = position;
			component.sizeDelta = size;
			Image component2 = val.GetComponent<Image>();
			component2.sprite = sprite;
			component2.preserveAspect = (Object)(object)sprite != (Object)null;
			((Graphic)component2).raycastTarget = raycast;
			return val;
		}

		private static GameObject MaterialText(string text, Transform parent, Vector2 position, int size, Color color, float width, float height)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = GUIManager.Instance.CreateText(text, parent, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), position, GUIManager.Instance.AveriaSerifBold, size, color, true, Color.black, width, height, false);
			Graphic[] componentsInChildren = val.GetComponentsInChildren<Graphic>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				componentsInChildren[i].raycastTarget = false;
			}
			return val;
		}

		private static void RenderMaterialIcons(IReadOnlyList<ResourceRequirement> requirements)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Expected O, but got Unknown
			//IL_00d6: 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_00f6: 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_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: 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_0218: Unknown result type (might be due to invalid IL or missing references)
			//IL_021f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0297: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b8: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = MaterialImage("AwakeningMaterials", _panel.transform, new Vector2(110f, -55f), new Vector2(410f, 145f), null, raycast: true);
			((Graphic)val.GetComponent<Image>()).color = new Color(0.025f, 0.03f, 0.035f, 0.65f);
			val.AddComponent<RectMask2D>();
			ScrollRect val2 = val.AddComponent<ScrollRect>();
			val2.horizontal = false;
			val2.movementType = (MovementType)2;
			val2.scrollSensitivity = 100f;
			val2.inertia = false;
			val2.viewport = val.GetComponent<RectTransform>();
			GameObject val3 = new GameObject("MaterialRows", new Type[1] { typeof(RectTransform) });
			val3.transform.SetParent(val.transform, false);
			RectTransform component = val3.GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0f, 1f);
			component.anchorMax = Vector2.one;
			component.pivot = new Vector2(0.5f, 1f);
			component.sizeDelta = new Vector2(0f, Mathf.Max(145f, (float)requirements.Count * 44f));
			component.anchoredPosition = Vector2.zero;
			val2.content = component;
			DynamicObjects.Add(val);
			if (requirements.Count == 0)
			{
				MaterialText("No materials required.", val3.transform, new Vector2(0f, -25f), 17, Color.white, 390f, 40f);
				return;
			}
			for (int i = 0; i < requirements.Count; i++)
			{
				ResourceRequirement resourceRequirement = requirements[i];
				float num = -24f - (float)i * 44f;
				Sprite itemIcon = AwakeningRequirementService.GetItemIcon(resourceRequirement.PrefabName);
				((Behaviour)MaterialImage("Material_" + resourceRequirement.PrefabName, val3.transform, new Vector2(-175f, num), new Vector2(32f, 32f), itemIcon, raycast: false, top: true).GetComponent<Image>()).enabled = (Object)(object)itemIcon != (Object)null;
				if ((Object)(object)itemIcon == (Object)null)
				{
					MaterialText("?", val3.transform, new Vector2(-175f, num), 20, Color.gray, 32f, 32f);
				}
				int playerItemCount = AwakeningRequirementService.GetPlayerItemCount(_player, resourceRequirement.PrefabName);
				MaterialText(string.Format("{0}   {1} / {2}", (resourceRequirement.PrefabName == "HECS_LightOfTheGod") ? "Light of the God" : AwakeningStonePolicy.ItemName(resourceRequirement.PrefabName), playerItemCount, resourceRequirement.Amount), val3.transform, new Vector2(20f, num), 17, (playerItemCount >= resourceRequirement.Amount) ? new Color(0.6f, 0.9f, 0.65f) : new Color(1f, 0.5f, 0.4f), 330f, 38f);
			}
		}

		private static string? SnapshotPathId(PlayerClassData data)
		{
			IReadOnlyList<ClassProgressionPath> awakeningPaths = GetAwakeningPaths(data);
			if (awakeningPaths.Count <= 0)
			{
				return null;
			}
			return awakeningPaths[Mathf.Clamp(_awakeningPage, 0, awakeningPaths.Count - 1)].Id;
		}

		private static string BuildMaterialSnapshot()
		{
			PlayerClassData current = ClassManager.Current;
			if ((Object)(object)_player == (Object)null || current == null || current.BaseClass == BaseClass.None || (!_respecConfirmationPending && current.CurrentStage == ClassStage.MythicPromotion))
			{
				return string.Empty;
			}
			ClassStage stage = current.CurrentStage + 1;
			List<string> list = new List<string> { WackyEpicMmoApi.GetLevel().ToString() };
			foreach (ResourceRequirement item in _respecConfirmationPending ? ClassRespecService.GetRequirements(current.CurrentStage) : AwakeningRequirementService.GetRequirements(stage, SnapshotPathId(current)))
			{
				list.Add($"{item.PrefabName}:{item.Amount}:{AwakeningRequirementService.GetPlayerItemCount(_player, item.PrefabName)}");
			}
			return string.Join("|", list);
		}

		private static void CheckMaterialChanges()
		{
			if (!(Time.unscaledTime < _nextMaterialCheck))
			{
				_nextMaterialCheck = Time.unscaledTime + 0.5f;
				string text = BuildMaterialSnapshot();
				if (text != _materialSnapshot)
				{
					_materialSnapshot = text;
					Refresh();
				}
			}
		}
	}
	public static class ClassHudUI
	{
		public static void Initialize()
		{
		}

		public static void Shutdown()
		{
		}
	}
	internal static class NorseUiTheme
	{
		private static Sprite? _background;

		private static Texture2D? _texture;

		private static bool _attempted;

		private static Sprite? _buttonSprite;

		private static Texture2D? _buttonTexture;

		private static bool _buttonAttempted;

		public static void ApplyButton(Button button)
		{
			//IL_0214: Unknown result type (might be due to invalid IL or missing references)
			//IL_022f: Unknown result type (might be due to invalid IL or missing references)
			//IL_024b: Unknown result type (might be due to invalid IL or missing references)
			//IL_026b: Unknown result type (might be due to invalid IL or missing references)
			//IL_028b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ed: 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_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Expected O, but got Unknown
			//IL_0366: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: 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)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			(((Component)button).GetComponent<AltarButtonSound>() ?? ((Component)button).gameObject.AddComponent<AltarButtonSound>()).Bind(button);
			if (!_buttonAttempted)
			{
				_buttonAttempted = true;
				try
				{
					using Stream stream = typeof(NorseUiTheme).Assembly.GetManifestResourceStream("HECS.altar_button.png");
					if (stream != null)
					{
						using MemoryStream memoryStream = new MemoryStream();
						stream.CopyTo(memoryStream);
						_buttonTexture = new Texture2D(2, 2, (TextureFormat)4, false);
						object obj = Type.GetType("UnityEngine.ImageConversion, UnityEngine.ImageConversionModule")?.GetMethod("LoadImage", new Type[3]
						{
							typeof(Texture2D),
							typeof(byte[]),
							typeof(bool)
						})?.Invoke(null, new object[3]
						{
							_buttonTexture,
							memoryStream.ToArray(),
							true
						});
						if (!(obj is bool) || !(bool)obj)
						{
							throw new InvalidDataException("Could not decode button PNG.");
						}
						((Texture)_buttonTexture).wrapMode = (TextureWrapMode)1;
						Rect val = new Rect(0f, (float)((Texture)_buttonTexture).height * 0.16f, (float)((Texture)_buttonTexture).width, (float)((Texture)_buttonTexture).height * 0.68f);
						_buttonSprite = Sprite.Create(_buttonTexture, val, new Vector2(0.5f, 0.5f), 100f, 0u, (SpriteMeshType)0, new Vector4(((Rect)(ref val)).width * 0.11f, ((Rect)(ref val)).height * 0.11f, ((Rect)(ref val)).width * 0.11f, ((Rect)(ref val)).height * 0.11f));
					}
				}
				catch (Exception ex)
				{
					HarrisonEpicClassSystemPlugin.Log.LogWarning((object)("Could not load Norse button texture: " + ex.Message));
				}
			}
			Image component = ((Component)button).GetComponent<Image>();
			if (!((Object)(object)component == (Object)null))
			{
				if ((Object)(object)_buttonSprite != (Object)null)
				{
					component.sprite = _buttonSprite;
					component.type = (Type)1;
					component.pixelsPerUnitMultiplier = 10f;
				}
				((Graphic)component).color = Color.white;
				((Selectable)button).targetGraphic = (Graphic)(object)component;
				((Selectable)button).transition = (Transition)1;
				ColorBlock colors = default(ColorBlock);
				((ColorBlock)(ref colors)).normalColor = new Color(0.88f, 0.85f, 0.78f, 1f);
				((ColorBlock)(ref colors)).highlightedColor = new Color(1.18f, 1.1f, 0.9f, 1f);
				((ColorBlock)(ref colors)).selectedColor = new Color(1.12f, 1.04f, 0.86f, 1f);
				((ColorBlock)(ref colors)).pressedColor = new Color(0.65f, 0.58f, 0.45f, 1f);
				((ColorBlock)(ref colors)).disabledColor = new Color(0.38f, 0.38f, 0.38f, 0.65f);
				((ColorBlock)(ref colors)).colorMultiplier = 1f;
				((ColorBlock)(ref colors)).fadeDuration = 0.12f;
				((Selectable)button).colors = colors;
				Text[] componentsInChildren = ((Component)button).GetComponentsInChildren<Text>(true);
				foreach (Text obj2 in componentsInChildren)
				{
					((Graphic)obj2).color = new Color(0.96f, 0.88f, 0.69f, 1f);
					((Graphic)obj2).raycastTarget = false;
				}
				Transform[] componentsInChildren2 = ((Component)button).GetComponentsInChildren<Transform>(true);
				for (int i = 0; i < componentsInChildren2.Length; i++)
				{
					TMProBridge.SetColor(((Component)componentsInChildren2[i]).gameObject, new Color(0.96f, 0.88f, 0.69f, 1f));
				}
			}
		}

		public static void ApplyBackground(Image image)
		{
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: 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_004b: Expected O, but got Unknown
			//IL_010e: 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)
			if (!_attempted)
			{
				_attempted = true;
				try
				{
					using Stream stream = typeof(NorseUiTheme).Assembly.GetManifestResourceStream("HECS.altar_background.png");
					if (stream != null)
					{
						using MemoryStream memoryStream = new MemoryStream();
						stream.CopyTo(memoryStream);
						_texture = new Texture2D(2, 2, (TextureFormat)4, false);
						object obj = Type.GetType("UnityEngine.ImageConversion, UnityEngine.ImageConversionModule")?.GetMethod("LoadImage", new Type[3]
						{
							typeof(Texture2D),
							typeof(byte[]),
							typeof(bool)
						})?.Invoke(null, new object[3]
						{
							_texture,
							memoryStream.ToArray(),
							true
						});
						if (!(obj is bool) || !(bool)obj)
						{
							throw new InvalidDataException("Could not decode altar background PNG.");
						}
						((Texture)_texture).wrapMode = (TextureWrapMode)1;
						_background = Sprite.Create(_texture, new Rect(0f, 0f, (float)((Texture)_texture).width, (float)((Texture)_texture).height), new Vector2(0.5f, 0.5f));
					}
				}
				catch (Exception ex)
				{
					HarrisonEpicClassSystemPlugin.Log.LogWarning((object)("Could not load Norse UI background: " + ex.Message));
				}
			}
			image.sprite = _background;
			image.type = (Type)0;
			image.preserveAspect = false;
			((Graphic)image).color = (Color)(((Object)(object)_background != (Object)null) ? Color.white : new Color(0.07f, 0.08f, 0.09f, 0.98f));
		}

		public static void Shutdown()
		{
			if ((Object)(object)_buttonSprite != (Object)null)
			{
				Object.Destroy((Object)(object)_buttonSprite);
			}
			if ((Object)(object)_buttonTexture != (Object)null)
			{
				Object.Destroy((Object)(object)_buttonTexture);
			}
			_buttonSprite = null;
			_buttonTexture = null;
			_buttonAttempted = false;
			if ((Object)(object)_background != (Object)null)
			{
				Object.Destroy((Object)(object)_background);
			}
			if ((Object)(object)_texture != (Object)null)
			{
				Object.Destroy((Object)(object)_texture);
			}
			_background = null;
			_texture = null;
			_attempted = false;
		}
	}
	internal static class TMProBridge
	{
		private static readonly Type? TmpTextType = ResolveTmpType();

		private static readonly PropertyInfo? TmpTextProperty = TmpTextType?.GetProperty("text", BindingFlags.Instance | BindingFlags.Public);

		private static readonly PropertyInfo? TmpColorProperty = TmpTextType?.GetProperty("color", BindingFlags.Instance | BindingFlags.Public);

		public static bool SetText(GameObject? target, string value)
		{
			if ((Object)(object)target == (Object)null)
			{
				return false;
			}
			Text component = target.GetComponent<Text>();
			if ((Object)(object)component != (Object)null)
			{
				component.text = value;
				return true;
			}
			Component tmpComponent = GetTmpComponent(target);
			if ((Object)(object)tmpComponent == (Object)null || TmpTextProperty == null)
			{
				return false;
			}
			TmpTextProperty.SetValue(tmpComponent, value, null);
			return true;
		}

		public static void SetColor(GameObject? target, Color color)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)target == (Object)null)
			{
				return;
			}
			Text component = target.GetComponent<Text>();
			if ((Object)(object)component != (Object)null)
			{
				((Graphic)component).color = color;
				return;
			}
			Component tmpComponent = GetTmpComponent(target);
			if ((Object)(object)tmpComponent != (Object)null && TmpColorProperty != null)
			{
				TmpColorProperty.SetValue(tmpComponent, color, null);
			}
		}

		private static Component? GetTmpComponent(GameObject target)
		{
			if (TmpTextType == null)
			{
				return null;
			}
			return target.GetComponent(TmpTextType);
		}

		private static Type? ResolveTmpType()
		{
			return Type.GetType("TMPro.TMP_Text, Unity.TextMeshPro") ?? Type.GetType("TMPro.TextMeshProUGUI, Unity.TextMeshPro") ?? Type.GetType("TMPro.TMP_Text, TMPro") ?? Type.GetType("TMPro.TextMeshProUGUI, TMPro");
		}
	}
	public sealed class UiFadeController : MonoBehaviour
	{
		private CanvasGroup? _group;

		private Coroutine? _routine;

		private void Awake()
		{
			EnsureCanvasGroup();
		}

		private void EnsureCanvasGroup()
		{
			_group = ((Component)this).GetComponent<CanvasGroup>();
			if ((Object)(object)_group == (Object)null)
			{
				_group = ((Component)this).gameObject.AddComponent<CanvasGroup>();
			}
		}

		public void Show(float duration = 0.18f)
		{
			((Component)this).gameObject.SetActive(true);
			EnsureCanvasGroup();
			StartFade(1f, duration, disableWhenDone: false);
		}

		public void Hide(float duration = 0.14f)
		{
			EnsureCanvasGroup();
			StartFade(0f, duration, disableWhenDone: true);
		}

		private void StartFade(float target, float duration, bool disableWhenDone)
		{
			if (_routine != null)
			{
				((MonoBehaviour)this).StopCoroutine(_routine);
			}
			_routine = ((MonoBehaviour)this).StartCoroutine(Fade(target, duration, disableWhenDone));
		}

		private IEnumerator Fade(float target, float duration, bool disableWhenDone)
		{
			if (!((Object)(object)_group == (Object)null))
			{
				_group.interactable = target > 0.5f;
				_group.blocksRaycasts = target > 0.5f;
				float start = _group.alpha;
				float elapsed = 0f;
				duration = Mathf.Max(0.01f, duration);
				while (elapsed < duration)
				{
					elapsed += Time.unscaledDeltaTime;
					float num = Mathf.SmoothStep(0f, 1f, elapsed / duration);
					_group.alpha = Mathf.Lerp(start, target, num);
					yield return null;
				}
				_group.alpha = target;
				_routine = null;
				if (disableWhenDone)
				{
					((Component)this).gameObject.SetActive(false);
				}
			}
		}
	}
}
namespace HarrisonEpicClassSystem.Requirements
{
	public sealed class AwakeningCheckResult
	{
		public int CurrentLevel { get; set; }

		public int RequiredLevel { get; set; }

		public bool LevelMet { get; set; }

		public bool MaterialsMet { get; set; }

		public IReadOnlyList<ResourceRequirement> Requirements { get; set; } = Array.Empty<ResourceRequirement>();

		public bool CanAwaken
		{
			get
			{
				if (LevelMet)
				{
					return MaterialsMet;
				}
				return false;
			}
		}
	}
	public static class AwakeningRequirementService
	{
		public static IReadOnlyList<ResourceRequirement> GetRequirements(ClassStage stage, string? selectedPathId = null)
		{
			string text = stage switch
			{
				ClassStage.FirstPromotion => ClassConfig.FirstPromotionRequirements.Value, 
				ClassStage.SecondPromotion => ClassConfig.SecondPromotionRequirements.Value, 
				ClassStage.MythicPromotion => ClassConfig.MythicPromotionRequirements.Value, 
				_ => string.Empty, 
			};
			int num = AwakeningStonePolicy.Amount(stage, ClassConfig.FirstAwakeningStones.Value, ClassConfig.SecondAwakeningStones.Value, ClassConfig.MythicAwakeningStones.Value);
			string text2 = AwakeningStonePolicy.PrefabName(ClassManager.Current?.BaseClass ?? BaseClass.None);
			string text3 = ((num > 0 && text2.Length > 0) ? $"{text2}:{num}" : string.Empty);
			PlayerClassData current = ClassManager.Current;
			ClassProgressionPath path = ClassRegistry.GetPath((stage == ClassStage.FirstPromotion) ? (selectedPathId ?? string.Empty) : (current?.SelectedPathId ?? string.Empty));
			if (path != null && path.RootClass == current?.BaseClass)
			{
				string text4 = ClassAwakeningMaterials.Get(path.GetClassForStage(stage));
				if (!string.IsNullOrWhiteSpace(text4))
				{
					text3 = text3 + ((text3.Length > 0) ? "," : string.Empty) + text4;
				}
			}
			if (ClassConfig.IncludeExtraAwakeningMaterials.Value && !string.IsNullOrWhiteSpace(text))
			{
				text3 = text3 + ((text3.Length > 0) ? "," : string.Empty) + text;
			}
			return RequirementParser.Parse(text3);
		}

		public static AwakeningCheckResult Check(Player player, ClassStage stage, string? selectedPathId = null)
		{
			int level = WackyEpicMmoApi.GetLevel();
			int requiredLevel = ClassConfig.GetRequiredLevel(stage);
			IReadOnlyList<ResourceRequirement> requirements = GetRequirements(stage, selectedPathId);
			AwakeningCheckResult obj = new AwakeningCheckResult
			{
				CurrentLevel = level,
				RequiredLevel = requiredLevel,
				LevelMet = (level >= requiredLevel),
				Requirements = requirements
			};
			int materialsMet;
			if ((Object)(object)player == (Object)(object)Player.m_localPlayer)
			{
				BaseClass? baseClass = ClassManager.Current?.BaseClass;
				if ((baseClass ?? BaseClass.None) != BaseClass.None)
				{
					materialsMet = (HasAllRequirements(player, requirements) ? 1 : 0);
					goto IL_0089;
				}
			}
			materialsMet = 0;
			goto IL_0089;
			IL_0089:
			obj.MaterialsMet = (byte)materialsMet != 0;
			return obj;
		}

		public static bool HasAllRequirements(Player player, IReadOnlyList<ResourceRequirement> requirements)
		{
			foreach (ResourceRequirement requirement in requirements)
			{
				if (GetPlayerItemCount(player, requirement.PrefabName) < requirement.Amount)
				{
					return false;
				}
			}
			return true;
		}

		public static int GetPlayerItemCount(Player player, string prefabName)
		{
			string text = ResolveSharedItemName(prefabName);
			if (string.IsNullOrEmpty(text))
			{
				return 0;
			}
			return ((Humanoid)player).GetInventory().CountItems(text, -1, true);
		}

		public static bool ConsumeRequirements(Player player, IReadOnlyList<ResourceRequirement> requirements)
		{
			if (!HasAllRequirements(player, requirements))
			{
				return false;
			}
			Inventory inventory = ((Humanoid)player).GetInventory();
			foreach (ResourceRequirement requirement in requirements)
			{
				string text = ResolveSharedItemName(requirement.PrefabName);
				if (string.IsNullOrEmpty(text))
				{
					return false;
				}
				inventory.RemoveItem(text, requirement.Amount, -1, true);
			}
			return true;
		}

		public static Sprite? GetItemIcon(string prefabName)
		{
			ObjectDB instance = ObjectDB.instance;
			GameObject obj = ((instance != null) ? instance.GetItemPrefab(prefabName) : null);
			ItemDrop obj2 = ((obj != null) ? obj.GetComponent<ItemDrop>() : null);
			if (obj2 == null)
			{
				return null;
			}
			return obj2.m_itemData.GetIcon();
		}

		private static string? ResolveSharedItemName(string prefabName)
		{
			ObjectDB instance = ObjectDB.instance;
			GameObject obj = ((instance != null) ? instance.GetItemPrefab(prefabName) : null);
			return ((obj != null) ? obj.GetComponent<ItemDrop>() : null)?.m_itemData?.m_shared?.m_name;
		}
	}
	public static class RequirementParser
	{
		public static IReadOnlyList<ResourceRequirement> Parse(string? raw)
		{
			if (string.IsNullOrWhiteSpace(raw))
			{
				return Array.Empty<ResourceRequirement>();
			}
			string? obj = raw ?? string.Empty;
			List<ResourceRequirement> list = new List<ResourceRequirement>();
			string[] array = obj.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries);
			for (int i = 0; i < array.Length; i++)
			{
				string text = array[i].Trim();
				string[] array2 = text.Split(new char[1] { ':' });
				if (array2.Length != 2)
				{
					HarrisonEpicClassSystemPlugin.Log.LogWarning((object)("Invalid requirement '" + text + "'. Expected PrefabName:Amount."));
					continue;
				}
				string text2 = array2[0].Trim();
				if (string.IsNullOrWhiteSpace(text2) || !int.TryParse(array2[1].Trim(), out var result) || result <= 0)
				{
					HarrisonEpicClassSystemPlugin.Log.LogWarning((object)("Invalid requirement '" + text + "'. Amount must be a positive integer."));
				}
				else
				{
					list.Add(new ResourceRequirement(text2, result));
				}
			}
			return (from g in list.GroupBy<ResourceRequirement, string>((ResourceRequirement x) => x.PrefabName, StringComparer.OrdinalIgnoreCase)
				select new ResourceRequirement(g.Key, g.Sum((ResourceRequirement x) => x.Amount))).ToList();
		}
	}
	public sealed class ResourceRequirement
	{
		public string PrefabName { get; }

		public int Amount { get; }

		public ResourceRequirement(string prefabName, int amount)
		{
			PrefabName = prefabName;
			Amount = amount;
		}

		public override string ToString()
		{
			return $"{PrefabName}:{Amount}";
		}
	}
}
namespace HarrisonEpicClassSystem.Persistence
{
	public interface IClassPersistence
	{
		PlayerClassData Load(Player player);

		void Save(Player player, PlayerClassData data);
	}
	public sealed class JsonClassPersistence : IClassPersistence
	{
		private readonly string _directory;

		public JsonClassPersistence()
		{
			_directory = Path.Combine(Paths.ConfigPath, "HarrisonEpicClassSystem", "players");
			Directory.CreateDirectory(_directory);
		}

		public PlayerClassData Load(Player player)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			long playerID = player.GetPlayerID();
			string path = GetPath(playerID);
			if (!File.Exists(path))
			{
				return CreateNew(player);
			}
			try
			{
				using FileStream fileStream = File.OpenRead(path);
				return (((XmlObjectSerializer)new DataContractJsonSerializer(typeof(PlayerClassData))).ReadObject((Stream)fileStream) as PlayerClassData) ?? CreateNew(player);
			}
			catch (Exception arg)
			{
				HarrisonEpicClassSystemPlugin.Log.LogError((object)$"Failed to load class save '{path}': {arg}");
				return CreateNew(player);
			}
		}

		public void Save(Player player, PlayerClassData data)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			string path = GetPath(player.GetPlayerID());
			string text = path + ".tmp";
			try
			{
				using (FileStream fileStream = File.Create(text))
				{
					((XmlObjectSerializer)new DataContractJsonSerializer(typeof(PlayerClassData))).WriteObject((Stream)fileStream, (object)data);
				}
				if (File.Exists(path))
				{
					File.Delete(path);
				}
				File.Move(text, path);
			}
			catch (Exception arg)
			{
				HarrisonEpicClassSystemPlugin.Log.LogError((object)$"Failed to save class data '{path}': {arg}");
			}
			finally
			{
				if (File.Exists(text))
				{
					try
					{
						File.Delete(text);
					}
					catch
					{
					}
				}
			}
		}

		private string GetPath(long playerId)
		{
			return Path.Combine(_directory, $"{playerId}.json");
		}

		private static PlayerClassData CreateNew(Player player)
		{
			return new PlayerClassData
			{
				PlayerId = player.GetPlayerID(),
				CharacterName = player.GetPlayerName(),
				BaseClass = BaseClass.None,
				CurrentClass = ClassId.None,
				CurrentStage = ClassStage.Base
			};
		}
	}
}
namespace HarrisonEpicClassSystem.Patches
{
	[HarmonyPatch]
	internal static class CharacterDamagePatch
	{
		private static MethodBase? TargetMethod()
		{
			return AccessTools.Method(typeof(Character), "Damage", new Type[1] { typeof(HitData) }, (Type[])null);
		}

		private static bool Prepare()
		{
			if (TargetMethod() == null)
			{
				HarrisonEpicClassSystemPlugin.Log.LogWarning((object)"Character.Damage(HitData) was not found. Class combat modifiers are disabled, progression remains active.");
				return false;
			}
			return true;
		}

		[HarmonyPrefix]
		private static void Prefix(ref HitData hit)
		{
			try
			{
				if (hit != null)
				{
					Character attacker = hit.GetAttacker();
					Player val = (Player)(object)((attacker is Player) ? attacker : null);
					if (val != null && !((Object)(object)val != (Object)(object)Player.m_localPlayer))
					{
						hit = hit.Clone();
						ClassCombatModifier.Apply(val, hit);
					}
				}
			}
			catch (Exception arg)
			{
				HarrisonEpicClassSystemPlugin.Log.LogError((object)$"Class damage modifier failed: {arg}");
			}
		}
	}
	[HarmonyPatch(typeof(TextsDialog), "AddActiveEffects")]
	internal static class ClassCompendiumPatch
	{
		[HarmonyPostfix]
		private static void Postfix(List<TextInfo> ___m_texts)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			try
			{
				___m_texts.RemoveAll((TextInfo entry) => entry.m_topic == "Class Effects");
				___m_texts.Add(new TextInfo("Class Effects", ClassEffectsDescription.Build(Player.m_localPlayer)));
			}
			catch (Exception ex)
			{
				HarrisonE