Decompiled source of Icewindheim v0.1.0

plugins/TenthWorld.dll

Decompiled 10 hours 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.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using TMPro;
using TenthWorld.Bestiary;
using TenthWorld.Bestiary.Mimic;
using TenthWorld.Bestiary.Npcs;
using TenthWorld.Core;
using TenthWorld.Effects;
using TenthWorld.Features;
using TenthWorld.Rules;
using TenthWorld.Spells;
using TenthWorld.UI;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.Rendering;
using UnityEngine.UI;
using Valheim.SettingsGui;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("assembly_valheim")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("TenthWorld")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.0.1.0")]
[assembly: AssemblyInformationalVersion("0.0.1")]
[assembly: AssemblyProduct("TenthWorld")]
[assembly: AssemblyTitle("TenthWorld")]
[assembly: InternalsVisibleTo("TenthWorld.Tests")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace TenthWorld
{
	[BepInPlugin("arcatio.tenthworld", "TenthWorld", "0.1.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	public class TenthWorldPlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "arcatio.tenthworld";

		public const string PluginName = "TenthWorld";

		public const string PluginVersion = "0.1.0";

		internal static TenthWorldPlugin Instance;

		private Harmony _harmony;

		private void Awake()
		{
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Expected O, but got Unknown
			Instance = this;
			TWLog.Source = ((BaseUnityPlugin)this).Logger;
			TWConfig.File = ((BaseUnityPlugin)this).Config;
			TWLog.Info("TenthWorld 0.1.0 starting (Jotunn 2.30.2)");
			Init("Faith", Faith.Register);
			Init("Core", CoreModule.Init);
			Init("Spells", SpellsModule.Init);
			Init("Features", FeaturesModule.Init);
			Init("UI", UiModule.Init);
			Init("Bestiary", BestiaryModule.Init);
			_harmony = new Harmony("arcatio.tenthworld");
			PatchEachClass(_harmony, typeof(TenthWorldPlugin).Assembly);
			TWLog.Info("TenthWorld Awake complete");
		}

		private static void PatchEachClass(Harmony harmony, Assembly asm)
		{
			int num = 0;
			int num2 = 0;
			List<string> list = new List<string>();
			Type[] typesFromAssembly = AccessTools.GetTypesFromAssembly(asm);
			foreach (Type type in typesFromAssembly)
			{
				try
				{
					List<MethodInfo> list2 = harmony.CreateClassProcessor(type).Patch();
					if (list2 != null)
					{
						if (list2.Count == 0)
						{
							num2++;
							TWLog.Info("[Harmony] patch class " + type.FullName + " skipped (Prepare returned false)");
						}
						else
						{
							num++;
						}
					}
				}
				catch (Exception arg)
				{
					list.Add(type.FullName);
					TWLog.Error($"[Harmony] patch class {type.FullName} FAILED to apply: {arg}");
				}
			}
			string text = $"[Harmony] patch classes: {num} ok / {list.Count} failed" + ((num2 > 0) ? $" / {num2} skipped (Prepare)" : "");
			if (list.Count == 0)
			{
				TWLog.Info(text);
			}
			else
			{
				TWLog.Error(text + " - failed: " + string.Join(", ", list));
			}
		}

		private static void Init(string name, Action init)
		{
			try
			{
				init();
				TWLog.Info("[" + name + "] initialised");
			}
			catch (Exception arg)
			{
				TWLog.Error($"[{name}] init failed: {arg}");
			}
		}

		private void OnDestroy()
		{
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}
	}
}
namespace TenthWorld.UI
{
	internal enum SheetView
	{
		Creation,
		Summary,
		Spells,
		Picks
	}
	internal static class CharacterSheet
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static UnityAction <0>__Close;

			public static Func<string, string> <1>__FeatureName;

			public static UnityAction <2>__ApplySuggested;

			public static Func<SkillType, string> <3>__DisplayName;

			public static UnityAction <4>__GoToSpellStep;

			public static UnityAction <5>__ConfirmCreate;

			public static UnityAction <6>__BackToBuild;

			public static UnityAction <7>__LearnSelected;
		}

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

			public static UnityAction <>9__37_0;

			public static UnityAction <>9__37_1;

			public static UnityAction <>9__37_2;

			public static Func<RaceDef, int> <>9__47_0;

			public static Func<KeyValuePair<SkillType, int>, SkillType> <>9__47_3;

			public static Func<KeyValuePair<SkillType, int>, int> <>9__47_4;

			public static UnityAction <>9__47_5;

			public static Func<ClassDef, string> <>9__47_6;

			public static Func<string, bool> <>9__48_0;

			public static UnityAction <>9__49_0;

			public static Func<string> <>9__49_1;

			public static Action<int> <>9__49_2;

			public static Func<string> <>9__49_3;

			public static Action<int> <>9__49_4;

			public static Func<Stat, string> <>9__49_7;

			public static Func<SpellDef, string> <>9__74_0;

			public static Func<FeatureInfo, bool> <>9__80_0;

			public static Func<FeatureInfo, int> <>9__80_1;

			public static Func<FeatureInfo, bool> <>9__80_2;

			public static UnityAction <>9__81_0;

			public static Comparison<SpellDef> <>9__86_0;

			public static Comparison<SpellDef> <>9__87_0;

			public static Func<SpellDef, string> <>9__89_0;

			public static Predicate<string> <>9__92_0;

			internal void <EnsurePanel>b__37_0()
			{
				SwitchView(SheetView.Spells);
			}

			internal void <EnsurePanel>b__37_1()
			{
				SwitchView(SheetView.Summary);
			}

			internal void <EnsurePanel>b__37_2()
			{
				SwitchView(SheetView.Picks);
			}

			internal int <BuildCreation>b__47_0(RaceDef r)
			{
				return (int)r.Id;
			}

			internal SkillType <BuildCreation>b__47_3(KeyValuePair<SkillType, int> kv)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				return kv.Key;
			}

			internal int <BuildCreation>b__47_4(KeyValuePair<SkillType, int> kv)
			{
				return kv.Value;
			}

			internal void <BuildCreation>b__47_5()
			{
				_dHorns = RaceCreatorRules.StepHorns(_dHorns);
				_dirty = true;
			}

			internal string <BuildCreation>b__47_6(ClassDef c)
			{
				return c.Name;
			}

			internal bool <EnsureChoiceDefaults>b__48_0(string o)
			{
				return o != _dInv1;
			}

			internal void <BuildBuildColumn>b__49_0()
			{
				for (int i = 0; i < 4; i++)
				{
					DStats[i] = 8;
				}
				_dirty = true;
			}

			internal string <BuildBuildColumn>b__49_1()
			{
				return _dInv1;
			}

			internal void <BuildBuildColumn>b__49_2(int d)
			{
				_dInv1 = CycleInvocation(_dInv1, _dInv2, d);
			}

			internal string <BuildBuildColumn>b__49_3()
			{
				return _dInv2;
			}

			internal void <BuildBuildColumn>b__49_4(int d)
			{
				_dInv2 = CycleInvocation(_dInv2, _dInv1, d);
			}

			internal string <BuildBuildColumn>b__49_7(Stat s)
			{
				return UiText.StatName(s);
			}

			internal string <NormalizeSelection>b__74_0(SpellDef o)
			{
				return o.Id;
			}

			internal bool <BuildSummary>b__80_0(FeatureInfo f)
			{
				return f.Level > 0;
			}

			internal int <BuildSummary>b__80_1(FeatureInfo f)
			{
				return f.Level;
			}

			internal bool <BuildSummary>b__80_2(FeatureInfo f)
			{
				return f.Level <= 0;
			}

			internal void <AddLearnPanel>b__81_0()
			{
				SwitchView(SheetView.Picks);
			}

			internal int <AvailableSpells>b__86_0(SpellDef a, SpellDef b)
			{
				if (a.Level == b.Level)
				{
					return string.CompareOrdinal(a.Name, b.Name);
				}
				return a.Level.CompareTo(b.Level);
			}

			internal int <KnownSpellList>b__87_0(SpellDef a, SpellDef b)
			{
				if (a.Level == b.Level)
				{
					return string.CompareOrdinal(a.Name, b.Name);
				}
				return a.Level.CompareTo(b.Level);
			}

			internal string <BuildSpells>b__89_0(SpellDef x)
			{
				return x.Id;
			}

			internal bool <AutoFill>b__92_0(string s)
			{
				return string.IsNullOrEmpty(s);
			}
		}

		private static RectTransform _overlay;

		private static RectTransform _panel;

		private static RectTransform _body;

		private static RectTransform _viewRoot;

		private static Text _title;

		private static Button _tabSummary;

		private static Button _tabSpells;

		private static Button _tabLearn;

		private static GameObject _tabsRoot;

		private static SheetView _view = SheetView.Summary;

		private static bool _open;

		private static bool _dirty;

		private static bool _blocking;

		private static int _unblockFrame = -1;

		private static Vector2 _canvasSize;

		private static float _slowTimer;

		private static readonly List<UiList> Lists = new List<UiList>();

		private static readonly Dictionary<string, float> ScrollMemory = new Dictionary<string, float>();

		private static RaceId _dRace = RaceId.None;

		private static TieflingHorns _dHorns = TieflingHorns.Pointed;

		private static ClassId _dClass = ClassId.None;

		private static readonly int[] DStats = new int[4] { 8, 8, 8, 8 };

		private static readonly Dictionary<string, string> DChoices = new Dictionary<string, string>();

		private static string _dInv1;

		private static string _dInv2;

		private static string _dError;

		private static int _dStep;

		private static readonly HashSet<string> PickSel = new HashSet<string>();

		private static string _pickMsg;

		private static Text _restText;

		private static int _selSlot;

		internal static bool IsOpen
		{
			get
			{
				if (_open)
				{
					return (Object)(object)_overlay != (Object)null;
				}
				return false;
			}
		}

		internal static bool Open()
		{
			if (IsOpen)
			{
				return true;
			}
			CharacterRecord local = CharacterApi.Local;
			if (local == null || (Object)(object)Player.m_localPlayer == (Object)null)
			{
				return false;
			}
			if (!EnsurePanel())
			{
				return false;
			}
			_open = true;
			((Component)_overlay).gameObject.SetActive(true);
			if (!_blocking)
			{
				GUIManager.BlockInput(true);
				_blocking = true;
			}
			_unblockFrame = -1;
			_view = (local.Confirmed ? ((_view == SheetView.Creation) ? SheetView.Summary : _view) : SheetView.Creation);
			ApplySize();
			_dirty = false;
			Rebuild();
			return true;
		}

		internal static void Close()
		{
			if (_open)
			{
				_open = false;
				if ((Object)(object)_overlay != (Object)null)
				{
					((Component)_overlay).gameObject.SetActive(false);
				}
				_unblockFrame = Time.frameCount + 2;
				UiTip.HideAll();
			}
		}

		internal static void Toggle()
		{
			if (IsOpen)
			{
				Close();
			}
			else
			{
				Open();
			}
		}

		internal static void Destroy()
		{
			_open = false;
			if ((Object)(object)_overlay != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)_overlay).gameObject);
			}
			_overlay = null;
			_panel = null;
			_body = null;
			_viewRoot = null;
			_title = null;
			_tabSummary = null;
			_tabSpells = null;
			_tabLearn = null;
			_tabsRoot = null;
			UiTip.Reset();
			Lists.Clear();
			if (_blocking)
			{
				_blocking = false;
				try
				{
					GUIManager.BlockInput(false);
				}
				catch
				{
				}
			}
			_unblockFrame = -1;
			_restText = null;
		}

		internal static void ResetDraft()
		{
			_dRace = RaceId.None;
			_dClass = ClassId.None;
			_dHorns = TieflingHorns.Pointed;
			for (int i = 0; i < 4; i++)
			{
				DStats[i] = 8;
			}
			DChoices.Clear();
			_dInv1 = (_dInv2 = null);
			_dError = null;
			_dStep = 0;
			PickSel.Clear();
			_pickMsg = null;
			ScrollMemory.Clear();
		}

		internal static void MarkDirty()
		{
			_dirty = true;
		}

		internal static void Tick(float dt)
		{
			//IL_00c6: 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_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (!_open && _blocking && _unblockFrame >= 0 && Time.frameCount >= _unblockFrame)
				{
					_blocking = false;
					_unblockFrame = -1;
					GUIManager.BlockInput(false);
				}
				if (!_open)
				{
					return;
				}
				if ((Object)(object)_overlay == (Object)null)
				{
					_open = false;
					return;
				}
				Player localPlayer = Player.m_localPlayer;
				if ((Object)(object)localPlayer == (Object)null || CharacterApi.Local == null || ((Character)localPlayer).IsDead())
				{
					Close();
					return;
				}
				if (!UiInput.TextUiOpen() && (ZInput.GetKeyDown((KeyCode)27, false) || ZInput.GetButtonDown("JoyButtonB")))
				{
					Close();
					return;
				}
				GameObject customGUIFront = GUIManager.CustomGUIFront;
				if ((Object)(object)customGUIFront != (Object)null)
				{
					Transform transform = customGUIFront.transform;
					RectTransform val = (RectTransform)(object)((transform is RectTransform) ? transform : null);
					if (val != null)
					{
						Rect rect = val.rect;
						Vector2 size = ((Rect)(ref rect)).size;
						if (Mathf.Abs(size.x - _canvasSize.x) > 1f || Mathf.Abs(size.y - _canvasSize.y) > 1f)
						{
							ApplySize();
							_dirty = true;
						}
					}
				}
				if (_dirty)
				{
					_dirty = false;
					Rebuild();
				}
				UiTip.Tick();
				_slowTimer += dt;
				if (_slowTimer >= 0.5f)
				{
					_slowTimer = 0f;
					UpdateDynamic();
				}
			}
			catch (Exception ex)
			{
				TWLog.Error("[UI] sheet tick failed: " + ex);
				Close();
			}
		}

		private static bool EnsurePanel()
		{
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Expected O, but got Unknown
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Expected O, but got Unknown
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Expected O, but got Unknown
			//IL_021f: Unknown result type (might be due to invalid IL or missing references)
			//IL_022e: Unknown result type (might be due to invalid IL or missing references)
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_025b: Expected O, but got Unknown
			//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_029f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02db: Expected O, but got Unknown
			//IL_0280: Unknown result type (might be due to invalid IL or missing references)
			//IL_0285: Unknown result type (might be due to invalid IL or missing references)
			//IL_028b: Expected O, but got Unknown
			//IL_031f: Unknown result type (might be due to invalid IL or missing references)
			//IL_032e: Unknown result type (might be due to invalid IL or missing references)
			//IL_033d: Unknown result type (might be due to invalid IL or missing references)
			//IL_035b: Expected O, but got Unknown
			//IL_0365: Unknown result type (might be due to invalid IL or missing references)
			//IL_0383: Expected O, but got Unknown
			//IL_03c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0300: Unknown result type (might be due to invalid IL or missing references)
			//IL_0305: Unknown result type (might be due to invalid IL or missing references)
			//IL_030b: Expected O, but got Unknown
			if ((Object)(object)_overlay != (Object)null && (Object)(object)_panel != (Object)null)
			{
				return true;
			}
			GameObject customGUIFront = GUIManager.CustomGUIFront;
			if ((Object)(object)customGUIFront == (Object)null)
			{
				return false;
			}
			try
			{
				Destroy();
				_overlay = UiKit.NewRect("TW_Sheet", customGUIFront.transform);
				UiKit.Stretch(_overlay);
				Image obj = ((Component)_overlay).gameObject.AddComponent<Image>();
				((Graphic)obj).color = new Color(0f, 0f, 0f, 0.45f);
				((Graphic)obj).raycastTarget = true;
				GameObject obj2 = GUIManager.Instance.CreateWoodpanel((Transform)(object)_overlay, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, 1200f, 800f, false);
				((Object)obj2).name = "TW_SheetPanel";
				_panel = (RectTransform)obj2.transform;
				_title = UiKit.NewText((Transform)(object)_panel, "Title", "", 28, P.Orange, (TextAnchor)3, outline: true, wrap: false);
				UiKit.Pin(((Graphic)_title).rectTransform, new Vector2(0f, 1f), new Vector2(0f, 1f), 40f, -22f, 640f, 44f);
				RectTransform panel = _panel;
				object obj3 = <>O.<0>__Close;
				if (obj3 == null)
				{
					UnityAction val = Close;
					<>O.<0>__Close = val;
					obj3 = (object)val;
				}
				UiKit.Pin((RectTransform)((Component)UiKit.NewButton((Transform)(object)panel, "X", 20, (UnityAction)obj3)).transform, new Vector2(1f, 1f), new Vector2(1f, 1f), -38f, -26f, 38f, 38f);
				_tabsRoot = ((Component)UiKit.NewRect("Tabs", (Transform)(object)_panel)).gameObject;
				Transform transform = _tabsRoot.transform;
				object obj4 = <>c.<>9__37_0;
				if (obj4 == null)
				{
					UnityAction val2 = delegate
					{
						SwitchView(SheetView.Spells);
					};
					<>c.<>9__37_0 = val2;
					obj4 = (object)val2;
				}
				_tabSpells = UiKit.NewButton(transform, "Spells", 18, (UnityAction)obj4);
				UiKit.Pin((RectTransform)((Component)_tabSpells).transform, new Vector2(1f, 1f), new Vector2(1f, 1f), -88f, -26f, 130f, 38f);
				Transform transform2 = _tabsRoot.transform;
				object obj5 = <>c.<>9__37_1;
				if (obj5 == null)
				{
					UnityAction val3 = delegate
					{
						SwitchView(SheetView.Summary);
					};
					<>c.<>9__37_1 = val3;
					obj5 = (object)val3;
				}
				_tabSummary = UiKit.NewButton(transform2, "Summary", 18, (UnityAction)obj5);
				UiKit.Pin((RectTransform)((Component)_tabSummary).transform, new Vector2(1f, 1f), new Vector2(1f, 1f), -226f, -26f, 130f, 38f);
				Transform transform3 = _tabsRoot.transform;
				object obj6 = <>c.<>9__37_2;
				if (obj6 == null)
				{
					UnityAction val4 = delegate
					{
						SwitchView(SheetView.Picks);
					};
					<>c.<>9__37_2 = val4;
					obj6 = (object)val4;
				}
				_tabLearn = UiKit.NewButton(transform3, "Learn", 18, (UnityAction)obj6);
				UiKit.Pin((RectTransform)((Component)_tabLearn).transform, new Vector2(1f, 1f), new Vector2(1f, 1f), -364f, -26f, 130f, 38f);
				UiKit.Stretch((RectTransform)_tabsRoot.transform);
				_body = UiKit.NewRect("Body", (Transform)(object)_panel);
				UiKit.Stretch(_body, 38f, 30f, 38f, 80f);
				UiKit.Pin(((Graphic)UiKit.NewText((Transform)(object)_panel, "Credits", "Credits: tw_credits  |  SRD 5.1 / 5.2.1  CC-BY-4.0", 12, P.Gray, (TextAnchor)4, outline: false, wrap: false)).rectTransform, new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), 0f, 7f, 560f, 20f);
				UiTip.Attach(_overlay);
				return true;
			}
			catch (Exception ex)
			{
				TWLog.Error("[UI] could not build the character sheet panel: " + ex);
				Destroy();
				return false;
			}
		}

		private static void ApplySize()
		{
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: 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_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_panel == (Object)null)
			{
				return;
			}
			Vector2 size = default(Vector2);
			((Vector2)(ref size))..ctor(1920f, 1080f);
			GameObject customGUIFront = GUIManager.CustomGUIFront;
			if ((Object)(object)customGUIFront != (Object)null)
			{
				Transform transform = customGUIFront.transform;
				RectTransform val = (RectTransform)(object)((transform is RectTransform) ? transform : null);
				if (val != null)
				{
					Rect rect = val.rect;
					if (((Rect)(ref rect)).width > 200f)
					{
						rect = val.rect;
						if (((Rect)(ref rect)).height > 200f)
						{
							rect = val.rect;
							size = ((Rect)(ref rect)).size;
						}
					}
				}
			}
			_canvasSize = size;
			float num = Mathf.Min(1220f, size.x - 60f);
			float num2 = Mathf.Min(810f, size.y - 60f);
			_panel.sizeDelta = new Vector2(num, num2);
			_panel.anchoredPosition = Vector2.zero;
		}

		private static void SwitchView(SheetView v)
		{
			CharacterRecord local = CharacterApi.Local;
			if (local != null && local.Confirmed)
			{
				if (v == SheetView.Picks && _view != SheetView.Picks)
				{
					PickSel.Clear();
					_pickMsg = null;
				}
				_view = v;
				UiTip.HideAll();
				_dirty = true;
			}
		}

		private static void SaveScroll()
		{
			foreach (UiList list in Lists)
			{
				if (list != null && (Object)(object)list.Scroll != (Object)null)
				{
					float verticalNormalizedPosition = list.Scroll.verticalNormalizedPosition;
					if (!float.IsNaN(verticalNormalizedPosition))
					{
						ScrollMemory[list.Key] = verticalNormalizedPosition;
					}
				}
			}
		}

		private static void Rebuild()
		{
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			if (!_open || (Object)(object)_panel == (Object)null || (Object)(object)_body == (Object)null)
			{
				return;
			}
			CharacterRecord local = CharacterApi.Local;
			if (local == null)
			{
				Close();
				return;
			}
			if (!local.Confirmed)
			{
				_view = SheetView.Creation;
				ValidateDraftStep();
			}
			else if (_view == SheetView.Creation)
			{
				_view = SheetView.Summary;
			}
			if (_view == SheetView.Picks && SpendableTotal(local) <= 0)
			{
				_view = SheetView.Summary;
			}
			UiTip.HideAll();
			SaveScroll();
			Lists.Clear();
			_restText = null;
			if ((Object)(object)_viewRoot != (Object)null)
			{
				((Component)_viewRoot).gameObject.SetActive(false);
				Object.Destroy((Object)(object)((Component)_viewRoot).gameObject);
			}
			_viewRoot = UiKit.NewRect("View_" + _view, (Transform)(object)_body);
			UiKit.Stretch(_viewRoot);
			UpdateHeader(local);
			try
			{
				switch (_view)
				{
				case SheetView.Creation:
					BuildCreation(_viewRoot, local);
					break;
				case SheetView.Summary:
					BuildSummary(_viewRoot, local);
					break;
				case SheetView.Picks:
					BuildPicks(_viewRoot, local);
					break;
				default:
					BuildSpells(_viewRoot, local);
					break;
				}
			}
			catch (Exception ex)
			{
				TWLog.Error("[UI] building the " + _view.ToString() + " view failed: " + ex);
				UiKit.Stretch(((Graphic)UiKit.NewText((Transform)(object)_viewRoot, "Error", "Something went wrong building this page. Check the BepInEx log.", 18, P.Red, (TextAnchor)0)).rectTransform, 10f, 10f, 10f, 10f);
			}
		}

		private static void UpdateHeader(CharacterRecord rec)
		{
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			bool confirmed = rec.Confirmed;
			_tabsRoot.SetActive(confirmed);
			if (confirmed)
			{
				RaceDef raceDef = CharacterApi.GetRaceDef(rec.Race);
				ClassDef classDef = CharacterApi.GetClassDef(rec.Class);
				_title.text = "Level " + rec.Level + " " + ((raceDef != null) ? raceDef.Name : "?") + " " + ((classDef != null) ? classDef.Name : "?");
				UiKit.SetButtonLabel(_tabSummary, (_view == SheetView.Summary) ? P.Rich("Summary", P.Yellow) : "Summary");
				UiKit.SetButtonLabel(_tabSpells, (_view == SheetView.Spells) ? P.Rich("Spells", P.Yellow) : "Spells");
				int num = SpendableTotal(rec);
				bool flag = num > 0 || _view == SheetView.Picks;
				UiKit.SetActive((Component)(object)_tabLearn, flag);
				if (flag)
				{
					UiKit.SetButtonLabel(_tabLearn, (_view == SheetView.Picks) ? P.Rich("Learn (" + num + ")", P.Yellow) : P.Rich("Learn (" + num + ")", P.Green));
				}
			}
			else
			{
				_title.text = ((_dStep == 1) ? "Create your character: choose your spells" : "Create your character");
			}
		}

		private static UiList Column(RectTransform view, string key, float x0, float x1, string title, float padBottom = 0f)
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = UiKit.NewRect("Col_" + key, (Transform)(object)view);
			UiKit.Frac(val, x0, 0f, x1, 1f, 3f, 0f, 3f);
			float t = 0f;
			if (!string.IsNullOrEmpty(title))
			{
				UiKit.Pin(((Graphic)UiKit.NewText((Transform)(object)val, "Title", title, 21, P.Orange, (TextAnchor)3, outline: true, wrap: false)).rectTransform, new Vector2(0f, 1f), new Vector2(0f, 1f), 4f, 0f, 400f, 28f);
				t = 32f;
			}
			UiList uiList = UiList.Create((Transform)(object)val, key);
			UiKit.Stretch(uiList.Root, 0f, padBottom, 0f, t);
			Lists.Add(uiList);
			return uiList;
		}

		private static void FinishLists()
		{
			foreach (UiList list in Lists)
			{
				ScrollMemory.TryGetValue(list.Key, out var value);
				if (!ScrollMemory.ContainsKey(list.Key))
				{
					value = 1f;
				}
				list.Finish(value);
			}
		}

		private static string StatBonusText(RaceDef rd)
		{
			List<string> list = new List<string>();
			for (int i = 0; i < 4; i++)
			{
				if (rd.StatBonus[i] != 0)
				{
					list.Add(UiText.Signed(rd.StatBonus[i]) + " " + UiText.StatName((Stat)i));
				}
			}
			if (list.Count != 0)
			{
				return string.Join("  ", list);
			}
			return "";
		}

		private static string TraitText(string[] ids)
		{
			if (ids == null || ids.Length == 0)
			{
				return "";
			}
			return string.Join(", ", ids.Select(UiText.FeatureName));
		}

		private static void BuildCreation(RectTransform view, CharacterRecord rec)
		{
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0249: Unknown result type (might be due to invalid IL or missing references)
			//IL_027f: Unknown result type (might be due to invalid IL or missing references)
			//IL_047e: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0307: Unknown result type (might be due to invalid IL or missing references)
			//IL_0530: Unknown result type (might be due to invalid IL or missing references)
			//IL_05af: Unknown result type (might be due to invalid IL or missing references)
			//IL_05d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0608: Unknown result type (might be due to invalid IL or missing references)
			//IL_036f: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b3: Expected O, but got Unknown
			EnsureChoiceDefaults();
			if (_dStep == 1)
			{
				CharacterRecord draft = DraftRecord();
				DraftCaps(draft, out var cantrips, out var spells);
				BuildDraftSpellStep(view, draft, cantrips, spells);
				return;
			}
			RaceId creatorRace = rec?.Race ?? RaceId.None;
			if (creatorRace != RaceId.None)
			{
				_dRace = creatorRace;
				if (rec.HornStyle != TieflingHorns.Auto)
				{
					_dHorns = rec.HornStyle;
				}
			}
			UiList uiList = Column(view, "create.race", 0f, 0.3f, (creatorRace != RaceId.None) ? "1. Race (chosen in the creator)" : "1. Pick a race");
			UiList uiList2 = Column(view, "create.class", 0.3f, 0.62f, "2. Pick a class");
			foreach (RaceDef item in from r in CharacterApi.AllRaces
				orderby (int)r.Id
				where creatorRace == RaceId.None || r.Id == creatorRace
				select r)
			{
				RaceDef rdLocal = item;
				HoverEntry hoverEntry = uiList.AddEntry(70f, 10, (creatorRace != RaceId.None) ? null : ((Action)delegate
				{
					_dRace = rdLocal.Id;
					_dError = null;
					_dirty = true;
				}));
				hoverEntry.SetSelected(_dRace == item.Id);
				RectTransform obj = UiKit.NewRect("Head", ((Component)hoverEntry).transform);
				UiKit.Elem(((Component)obj).gameObject, 24f, 24f);
				UiKit.Frac(((Graphic)UiKit.NewText((Transform)(object)obj, "Name", item.Name, 19, P.Orange, (TextAnchor)3, outline: true, wrap: false)).rectTransform, 0f, 0f, 0.5f, 1f);
				UiKit.Frac(((Graphic)UiKit.NewText((Transform)(object)obj, "Bonus", StatBonusText(item), 15, P.Green, (TextAnchor)5, outline: true, wrap: false)).rectTransform, 0.4f, 0f, 1f, 1f);
				UiKit.NewText(((Component)hoverEntry).transform, "Summary", item.Summary, 14, P.Beige, (TextAnchor)0);
				string text = TraitText(item.TraitIds);
				if (text.Length > 0)
				{
					UiKit.NewText(((Component)hoverEntry).transform, "Traits", text, 13, P.Gray, (TextAnchor)0);
				}
				string text2 = SkillData.Describe(SkillData.RaceSkills(item.Id).ToDictionary((KeyValuePair<SkillType, int> kv) => kv.Key, (KeyValuePair<SkillType, int> kv) => kv.Value));
				if (text2.Length > 0)
				{
					UiKit.NewText(((Component)hoverEntry).transform, "Skills", "Starting skills: " + text2, 13, P.Blue, (TextAnchor)0);
				}
				if (item.Id != RaceId.Tiefling || _dRace != RaceId.Tiefling)
				{
					continue;
				}
				string text3 = "Horns: " + ((_dHorns == TieflingHorns.Curled) ? "Curled" : "Pointed");
				if (creatorRace != RaceId.None)
				{
					UiKit.NewText(((Component)hoverEntry).transform, "Horns", text3 + " (chosen in the creator)", 14, P.Beige, (TextAnchor)0);
					continue;
				}
				Transform transform = ((Component)hoverEntry).transform;
				string label = text3 + "  (click to change)";
				object obj2 = <>c.<>9__47_5;
				if (obj2 == null)
				{
					UnityAction val = delegate
					{
						_dHorns = RaceCreatorRules.StepHorns(_dHorns);
						_dirty = true;
					};
					<>c.<>9__47_5 = val;
					obj2 = (object)val;
				}
				UiKit.Elem(((Component)UiKit.NewButton(transform, label, 15, (UnityAction)obj2)).gameObject, 28f, 28f);
			}
			foreach (ClassDef item2 in CharacterApi.AllClasses.OrderBy((ClassDef c) => c.Name))
			{
				ClassDef cdLocal = item2;
				HoverEntry hoverEntry2 = uiList2.AddEntry(70f, 66, delegate
				{
					if (_dClass != cdLocal.Id)
					{
						_dClass = cdLocal.Id;
						PickSel.Clear();
						_dStep = 0;
					}
					_dError = null;
					_dirty = true;
				});
				hoverEntry2.SetSelected(_dClass == item2.Id);
				Image obj3 = UiKit.NewImage(((Component)hoverEntry2).transform, "Icon", Color.white);
				obj3.preserveAspect = true;
				UiKit.Elem(((Component)obj3).gameObject, -1f, -1f, -1f, -1f, ignore: true);
				UiKit.Pin(((Graphic)obj3).rectTransform, new Vector2(0f, 1f), new Vector2(0f, 1f), 10f, -9f, 46f, 46f);
				Sprite val2 = (obj3.sprite = IconLibrary.ForClass(item2.Id) ?? IconLibrary.Placeholder);
				((Behaviour)obj3).enabled = (Object)(object)val2 != (Object)null;
				UiKit.Elem(((Component)UiKit.NewText(((Component)hoverEntry2).transform, "Name", item2.Name, 19, P.Orange, (TextAnchor)3, outline: true, wrap: false)).gameObject, 24f, 24f);
				UiKit.NewText(((Component)hoverEntry2).transform, "Meta", CoreUtil.HpPerLevelText(item2, withCon: false) + " HP per level  |  " + UiText.CasterName(item2.Caster) + "  |  " + UiText.ArmorText(item2.Armor), 13, P.Gray, (TextAnchor)0);
				UiKit.NewText(((Component)hoverEntry2).transform, "Summary", item2.Summary, 14, P.Beige, (TextAnchor)0);
				if (SpellPickData.HasPicks(item2.Id))
				{
					UiKit.NewText(((Component)hoverEntry2).transform, "Picks", SpellPickData.Describe(item2.Id), 13, P.Blue, (TextAnchor)0);
				}
			}
			BuildBuildColumn(view);
			FinishLists();
		}

		private static void EnsureChoiceDefaults()
		{
			foreach (string item in CharacterApi.ChoiceKeysFor(_dClass, _dRace))
			{
				string value;
				if (item == "invocations")
				{
					string[] array = ClassData.ChoiceDefaults[item].Split(new char[1] { ',' });
					string[] array2 = ClassData.ChoiceOptions[item];
					if (string.IsNullOrEmpty(_dInv1) || Array.IndexOf(array2, _dInv1) < 0)
					{
						_dInv1 = array[0];
					}
					if (string.IsNullOrEmpty(_dInv2) || Array.IndexOf(array2, _dInv2) < 0 || _dInv2 == _dInv1)
					{
						_dInv2 = ((array.Length > 1 && array[1] != _dInv1) ? array[1] : array2.First((string o) => o != _dInv1));
					}
				}
				else if (!DChoices.TryGetValue(item, out value) || Array.IndexOf(ClassData.AllowedValues(item), value) < 0)
				{
					DChoices[item] = (ClassData.ChoiceDefaults.TryGetValue(item, out var value2) ? value2 : ClassData.AllowedValues(item).FirstOrDefault());
				}
			}
		}

		private static void BuildBuildColumn(RectTransform view)
		{
			//IL_0047: 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_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: 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_0175: 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_0204: Expected O, but got Unknown
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Expected O, but got Unknown
			//IL_0234: Unknown result type (might be due to invalid IL or missing references)
			//IL_0266: Expected O, but got Unknown
			//IL_021f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0224: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: Expected O, but got Unknown
			//IL_02a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0632: Unknown result type (might be due to invalid IL or missing references)
			//IL_0647: Unknown result type (might be due to invalid IL or missing references)
			//IL_0652: Unknown result type (might be due to invalid IL or missing references)
			//IL_0680: Unknown result type (might be due to invalid IL or missing references)
			//IL_0679: Unknown result type (might be due to invalid IL or missing references)
			//IL_049a: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0599: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0585: Unknown result type (might be due to invalid IL or missing references)
			//IL_03de: Unknown result type (might be due to invalid IL or missing references)
			//IL_071f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0751: Expected O, but got Unknown
			//IL_0709: Unknown result type (might be due to invalid IL or missing references)
			//IL_070e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0714: Expected O, but got Unknown
			//IL_06ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_06f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_06f7: Expected O, but got Unknown
			RectTransform val = UiKit.NewRect("Col_build", (Transform)(object)view);
			UiKit.Frac(val, 0.62f, 0f, 1f, 1f, 3f);
			UiKit.Pin(((Graphic)UiKit.NewText((Transform)(object)val, "Title", "3. Ability scores", 21, P.Orange, (TextAnchor)3, outline: true, wrap: false)).rectTransform, new Vector2(0f, 1f), new Vector2(0f, 1f), 4f, 0f, 400f, 28f);
			UiList uiList = UiList.Create((Transform)(object)val, "create.build");
			UiKit.Stretch(uiList.Root, 0f, 112f, 0f, 32f);
			Lists.Add(uiList);
			RaceDef raceDef = CharacterApi.GetRaceDef(_dRace);
			ClassDef classDef = CharacterApi.GetClassDef(_dClass);
			int pointBuyBudget = CharacterApi.PointBuyBudget;
			int num = CharacterApi.PointBuySpent(DStats);
			int num2 = pointBuyBudget - num;
			string text = "Points left: " + num2 + " / " + pointBuyBudget;
			uiList.AddText(P.Rich(text, (num2 == 0) ? P.Green : P.Yellow) + "  (scores " + RulesParams.PointBuyMin + " to " + RulesParams.PointBuyMax + " before racial bonuses)", 16, P.Beige, (TextAnchor)0);
			for (int i = 0; i < 4; i++)
			{
				AddStatRow(uiList, (Stat)i, raceDef);
			}
			RectTransform parent = uiList.AddRow(40f);
			object obj = <>O.<2>__ApplySuggested;
			if (obj == null)
			{
				UnityAction val2 = ApplySuggested;
				<>O.<2>__ApplySuggested = val2;
				obj = (object)val2;
			}
			UiKit.Frac((RectTransform)((Component)UiKit.NewButton((Transform)(object)parent, "Suggested", 16, (UnityAction)obj)).transform, 0f, 0.08f, 0.48f, 0.92f);
			object obj2 = <>c.<>9__49_0;
			if (obj2 == null)
			{
				UnityAction val3 = delegate
				{
					for (int j = 0; j < 4; j++)
					{
						DStats[j] = 8;
					}
					_dirty = true;
				};
				<>c.<>9__49_0 = val3;
				obj2 = (object)val3;
			}
			UiKit.Frac((RectTransform)((Component)UiKit.NewButton((Transform)(object)parent, "Reset", 16, (UnityAction)obj2)).transform, 0.52f, 0.08f, 1f, 0.92f);
			List<string> list = CharacterApi.ChoiceKeysFor(_dClass, _dRace);
			if (list.Count > 0)
			{
				uiList.AddSpace(4f);
				uiList.AddHeader("Choices");
				uiList.AddText("Click to cycle, right-click to go back.", 13, P.Gray, (TextAnchor)0);
				foreach (string item in list)
				{
					if (item == "invocations")
					{
						AddCycleRow(uiList, "Invocation 1", () => _dInv1, delegate(int d)
						{
							_dInv1 = CycleInvocation(_dInv1, _dInv2, d);
						});
						AddCycleRow(uiList, "Invocation 2", () => _dInv2, delegate(int d)
						{
							_dInv2 = CycleInvocation(_dInv2, _dInv1, d);
						});
						continue;
					}
					string k = item;
					AddCycleRow(uiList, UiText.Pretty(k), () => (!DChoices.TryGetValue(k, out var value2)) ? "" : value2, delegate(int d)
					{
						Cycle(k, d);
					});
					string value;
					string text2 = FeatureText.ChoiceText(k, DChoices.TryGetValue(k, out value) ? value : null);
					if (!string.IsNullOrEmpty(text2))
					{
						uiList.AddText(text2, 14, P.Beige, (TextAnchor)0);
					}
				}
			}
			if (raceDef != null && classDef != null)
			{
				uiList.AddSpace(4f);
				uiList.AddText("Hit points per level: " + CoreUtil.HpPerLevelText(classDef, withCon: true) + ". Primary stats: " + string.Join(", ", classDef.PrimaryStats.Select((Stat s) => UiText.StatName(s))) + ". " + UiText.CasterName(classDef.Caster) + ".", 14, P.Gray, (TextAnchor)0);
				uiList.AddSpace(4f);
				uiList.AddHeader("Starting skills");
				string text3 = SkillData.Describe(SkillData.StartingLevels(_dRace, _dClass));
				uiList.AddText((text3.Length > 0) ? text3 : "None.", 14, P.Beige, (TextAnchor)0);
				SkillType[] array = SkillData.CoreSkills(_dClass);
				if (array.Length != 0)
				{
					uiList.AddText("Core skills of the class (+" + SkillData.ClassCoreStart + " each, trained x" + SkillData.ClassCoreXpMultiplier.ToString("0.#") + " faster): " + string.Join(", ", array.Select(SkillData.DisplayName)) + ".", 13, P.Gray, (TextAnchor)0);
				}
				uiList.AddText("Skills are only raised to these levels, never lowered.", 13, P.Gray, (TextAnchor)0);
				if (SpellPickData.HasPicks(_dClass) || SpellPickData.FreeSpells(_dClass).Length != 0)
				{
					uiList.AddSpace(4f);
					uiList.AddHeader("Spells");
					uiList.AddText(SpellPickData.Describe(_dClass), 14, P.Beige, (TextAnchor)0);
				}
			}
			RectTransform obj3 = UiKit.NewRect("Footer", (Transform)(object)val);
			UiKit.Frac(obj3, 0f, 0f, 1f, 0f);
			obj3.pivot = new Vector2(0.5f, 0f);
			obj3.sizeDelta = new Vector2(0f, 106f);
			obj3.anchoredPosition = Vector2.zero;
			UiKit.Frac(((Graphic)UiKit.NewText((Transform)(object)obj3, "Error", _dError ?? HintText(), 15, (_dError != null) ? P.Red : P.Gray, (TextAnchor)6)).rectTransform, 0f, 0.42f, 1f, 1f, 4f, 2f, 4f);
			bool flag = DraftHasSpellStep();
			string label = (flag ? "Next: choose spells" : "Create character");
			object obj4;
			if (!flag)
			{
				obj4 = <>O.<5>__ConfirmCreate;
				if (obj4 == null)
				{
					UnityAction val4 = ConfirmCreate;
					<>O.<5>__ConfirmCreate = val4;
					obj4 = (object)val4;
				}
			}
			else
			{
				obj4 = <>O.<4>__GoToSpellStep;
				if (obj4 == null)
				{
					UnityAction val5 = GoToSpellStep;
					<>O.<4>__GoToSpellStep = val5;
					obj4 = (object)val5;
				}
			}
			Button obj5 = UiKit.NewButton((Transform)(object)obj3, label, 20, (UnityAction)obj4);
			UiKit.Frac((RectTransform)((Component)obj5).transform, 0f, 0f, 1f, 0.38f, 0f, 2f, 0f, 2f);
			((Selectable)obj5).interactable = _dRace != RaceId.None && _dClass != ClassId.None;
		}

		private static string HintText()
		{
			if (_dRace == RaceId.None && _dClass == ClassId.None)
			{
				return "Pick a race and a class, spend your points, then create the character.";
			}
			if (_dRace == RaceId.None)
			{
				return "Pick a race.";
			}
			if (_dClass == ClassId.None)
			{
				return "Pick a class.";
			}
			return "Ready.";
		}

		private static void AddStatRow(UiList list, Stat s, RaceDef rd)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Expected O, but got Unknown
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Expected O, but got Unknown
			//IL_0101: 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_0159: Expected O, but got Unknown
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Expected O, but got Unknown
			//IL_01e1: 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)
			int i = (int)s;
			RectTransform parent = list.AddRow(50f);
			UiKit.Frac(((Graphic)UiKit.NewText((Transform)(object)parent, "Label", UiText.StatName(s) + "\n<size=11>" + UiText.StatBlurb(s) + "</size>", 19, P.Beige, (TextAnchor)3, outline: true, wrap: false)).rectTransform, 0f, 0f, 0.4f, 1f);
			Button obj = UiKit.NewButton((Transform)(object)parent, "-", 22, (UnityAction)delegate
			{
				AdjustStat(i, -1);
			});
			UiKit.Frac((RectTransform)((Component)obj).transform, 0.41f, 0.12f, 0.49f, 0.88f);
			((Selectable)obj).interactable = DStats[i] > RulesParams.PointBuyMin;
			UiKit.Frac(((Graphic)UiKit.NewText((Transform)(object)parent, "Base", DStats[i].ToString(), 22, P.Yellow, (TextAnchor)4, outline: true, wrap: false)).rectTransform, 0.49f, 0f, 0.58f, 1f);
			Button obj2 = UiKit.NewButton((Transform)(object)parent, "+", 22, (UnityAction)delegate
			{
				AdjustStat(i, 1);
			});
			UiKit.Frac((RectTransform)((Component)obj2).transform, 0.58f, 0.12f, 0.66f, 0.88f);
			((Selectable)obj2).interactable = CanRaise(i);
			int num = ((rd != null) ? rd.StatBonus[i] : 0);
			int score = DndMath.ClampScore(DStats[i] + num);
			string text = ((num != 0) ? (P.Rich(UiText.Signed(num), P.Green) + " = ") : "") + score + " (" + UiText.Signed(DndMath.Mod(score)) + ")";
			UiKit.Frac(((Graphic)UiKit.NewText((Transform)(object)parent, "Result", text, 17, P.Beige, (TextAnchor)5, outline: true, wrap: false)).rectTransform, 0.67f, 0f, 1f, 1f);
		}

		private static bool CanRaise(int i)
		{
			if (DStats[i] >= RulesParams.PointBuyMax)
			{
				return false;
			}
			int[] obj = (int[])DStats.Clone();
			obj[i]++;
			return CharacterApi.PointBuySpent(obj) <= CharacterApi.PointBuyBudget;
		}

		private static void AdjustStat(int i, int d)
		{
			if ((d <= 0 || CanRaise(i)) && (d >= 0 || DStats[i] > RulesParams.PointBuyMin))
			{
				DStats[i] += d;
				_dError = null;
				_dirty = true;
			}
		}

		private static void ApplySuggested()
		{
			ClassDef classDef = CharacterApi.GetClassDef(_dClass);
			List<Stat> list = new List<Stat>();
			if (classDef != null)
			{
				list.AddRange(classDef.PrimaryStats);
			}
			Stat[] array = new Stat[4]
			{
				Stat.CON,
				Stat.DEX,
				Stat.STR,
				Stat.MAG
			};
			foreach (Stat item in array)
			{
				if (!list.Contains(item))
				{
					list.Add(item);
				}
			}
			int[] array2 = new int[4] { 14, 13, 12, 10 };
			int[] array3 = new int[4] { 8, 8, 8, 8 };
			for (int j = 0; j < 4; j++)
			{
				array3[(int)list[j]] = Math.Min(array2[j], RulesParams.PointBuyMax);
			}
			if (CharacterApi.PointBuySpent(array3) > CharacterApi.PointBuyBudget)
			{
				array3 = new int[4] { 8, 8, 8, 8 };
				bool flag = true;
				while (flag)
				{
					flag = false;
					foreach (Stat item2 in list)
					{
						if (array3[(int)item2] < RulesParams.PointBuyMax)
						{
							array3[(int)item2]++;
							if (CharacterApi.PointBuySpent(array3) > CharacterApi.PointBuyBudget)
							{
								array3[(int)item2]--;
							}
							else
							{
								flag = true;
							}
						}
					}
				}
			}
			for (int k = 0; k < 4; k++)
			{
				DStats[k] = array3[k];
			}
			_dError = null;
			_dirty = true;
		}

		private static void AddCycleRow(UiList list, string label, Func<string> get, Action<int> cycle)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Expected O, but got Unknown
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Expected O, but got Unknown
			RectTransform parent = list.AddRow(60f);
			UiKit.Frac(((Graphic)UiKit.NewText((Transform)(object)parent, "Label", label, 15, P.Gray, (TextAnchor)3, outline: true, wrap: false)).rectTransform, 0f, 0.55f, 1f, 1f);
			Button obj = UiKit.NewButton((Transform)(object)parent, UiText.Pretty(get() ?? ""), 18, (UnityAction)delegate
			{
				cycle(1);
			});
			UiKit.Frac((RectTransform)((Component)obj).transform, 0f, 0f, 1f, 0.55f);
			((Component)obj).gameObject.AddComponent<RightClickRelay>().OnRight = delegate
			{
				cycle(-1);
			};
		}

		private static void Cycle(string key, int dir)
		{
			string[] array = ClassData.AllowedValues(key);
			if (array.Length != 0)
			{
				DChoices.TryGetValue(key, out var value);
				int num = Array.IndexOf(array, value);
				num = (((num >= 0) ? num : 0) + dir + array.Length) % array.Length;
				DChoices[key] = array[num];
				_dError = null;
				_dirty = true;
			}
		}

		private static string CycleInvocation(string cur, string other, int dir)
		{
			string[] array = ClassData.AllowedValues("invocations");
			if (array.Length == 0)
			{
				return cur;
			}
			int num = Array.IndexOf(array, cur);
			for (int i = 0; i < array.Length; i++)
			{
				num = (((num >= 0) ? num : 0) + dir + array.Length) % array.Length;
				if (array[num] != other)
				{
					break;
				}
			}
			_dError = null;
			_dirty = true;
			return array[num];
		}

		private static void ConfirmCreate()
		{
			try
			{
				Dictionary<string, string> dictionary = new Dictionary<string, string>();
				foreach (string item in CharacterApi.ChoiceKeysFor(_dClass, _dRace))
				{
					string value;
					if (item == "invocations")
					{
						dictionary[item] = _dInv1 + "," + _dInv2;
					}
					else if (DChoices.TryGetValue(item, out value))
					{
						dictionary[item] = value;
					}
				}
				List<string> chosen = (DraftHasSpellStep() ? PickSel.ToList() : new List<string>());
				if (CharacterApi.ConfirmCreation(_dRace, _dClass, (int[])DStats.Clone(), dictionary, out var error, _dHorns))
				{
					_dError = null;
					RaceDef raceDef = CharacterApi.GetRaceDef(_dRace);
					ClassDef classDef = CharacterApi.GetClassDef(_dClass);
					UiApi.Toast("Welcome, " + ((raceDef != null) ? raceDef.Name : "") + " " + ((classDef != null) ? classDef.Name : "") + "!");
					_view = SheetView.Summary;
					ResetDraft();
					SpendChosen(chosen);
				}
				else
				{
					_dError = (string.IsNullOrEmpty(error) ? "Could not create the character." : error);
				}
			}
			catch (Exception ex)
			{
				_dError = "Error: " + ex.Message;
				TWLog.Error("[UI] ConfirmCreation failed: " + ex);
			}
			_dirty = true;
		}

		private static CharacterRecord DraftRecord()
		{
			return new CharacterRecord
			{
				Confirmed = true,
				Race = _dRace,
				Class = _dClass,
				Level = 1,
				BaseStats = (int[])DStats.Clone(),
				AsiBonus = new int[4],
				KnownSpells = new List<string>(),
				SpellBar = new string[8],
				Choices = new Dictionary<string, string>()
			};
		}

		private static void DraftCaps(CharacterRecord draft, out int cantrips, out int spells)
		{
			cantrips = 0;
			spells = 0;
			if (draft != null && draft.Class != ClassId.None)
			{
				PickCount pickCount = SpellPickData.PicksAt(draft.Class, 1);
				cantrips = Math.Min(pickCount.Cantrips, SpellEngine.PickableFor(draft, cantrip: true).Count());
				spells = Math.Min(pickCount.Spells, SpellEngine.PickableFor(draft, cantrip: false).Count());
			}
		}

		private static bool DraftHasSpellStep()
		{
			if (_dRace == RaceId.None || _dClass == ClassId.None)
			{
				return false;
			}
			DraftCaps(DraftRecord(), out var cantrips, out var spells);
			return cantrips + spells > 0;
		}

		private static void ValidateDraftStep()
		{
			if (_dStep == 1 && !DraftHasSpellStep())
			{
				_dStep = 0;
				PickSel.Clear();
			}
		}

		private static void GoToSpellStep()
		{
			if (!DraftHasSpellStep())
			{
				ConfirmCreate();
				return;
			}
			_dStep = 1;
			_dError = null;
			_pickMsg = null;
			UiTip.HideAll();
			_dirty = true;
		}

		private static void BackToBuild()
		{
			_dStep = 0;
			_pickMsg = null;
			UiTip.HideAll();
			_dirty = true;
		}

		private static void BuildDraftSpellStep(RectTransform view, CharacterRecord draft, int capC, int capS)
		{
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Expected O, but got Unknown
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Expected O, but got Unknown
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Expected O, but got Unknown
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Expected O, but got Unknown
			RaceDef raceDef = CharacterApi.GetRaceDef(_dRace);
			ClassDef classDef = CharacterApi.GetClassDef(_dClass);
			string intro = "Choose your starting spells as a " + ((raceDef != null) ? raceDef.Name : "") + " " + ((classDef != null) ? classDef.Name : "") + ": " + SpellPickData.Describe(new PickCount(capC, capS)) + ". Click a spell to choose it, click it again to undo. Hover a spell for its numbers. " + SpellPickData.Describe(_dClass);
			BuildPickColumns(view, draft, capC, capS, intro, draft: true);
			RectTransform parent = PickFooter(view);
			object obj = <>O.<6>__BackToBuild;
			if (obj == null)
			{
				UnityAction val = BackToBuild;
				<>O.<6>__BackToBuild = val;
				obj = (object)val;
			}
			UiKit.Frac((RectTransform)((Component)UiKit.NewButton((Transform)(object)parent, "Back", 18, (UnityAction)obj)).transform, 0f, 0.1f, 0.18f, 0.9f);
			UiKit.Frac(((Graphic)UiKit.NewText((Transform)(object)parent, "Msg", PickStatus(capC, capS), 16, (_pickMsg != null) ? P.Red : P.Beige, (TextAnchor)3)).rectTransform, 0.2f, 0f, 0.64f, 1f, 4f, 0f, 4f);
			object obj2 = <>O.<5>__ConfirmCreate;
			if (obj2 == null)
			{
				UnityAction val2 = ConfirmCreate;
				<>O.<5>__ConfirmCreate = val2;
				obj2 = (object)val2;
			}
			Button obj3 = UiKit.NewButton((Transform)(object)parent, "Create character", 20, (UnityAction)obj2);
			UiKit.Frac((RectTransform)((Component)obj3).transform, 0.66f, 0.1f, 1f, 0.9f);
			((Selectable)obj3).interactable = SelectedCount(cantrip: true) == capC && SelectedCount(cantrip: false) == capS;
			FinishLists();
		}

		private static void SpendChosen(List<string> chosen)
		{
			if (chosen == null || chosen.Count == 0)
			{
				return;
			}
			int num = 0;
			foreach (string item in chosen)
			{
				if (SpellEngine.TryPick(item, out var message))
				{
					num++;
				}
				else
				{
					TWLog.Debug("[UI] creation pick '" + item + "' refused: " + message);
				}
			}
			CharacterRecord local = CharacterApi.Local;
			if (local != null && SpendableTotal(local) > 0)
			{
				_view = SheetView.Picks;
				PickSel.Clear();
				_pickMsg = null;
			}
			TWLog.Info("[UI] creation spells learned: " + num + " of " + chosen.Count);
		}

		internal static int SpendableTotal(CharacterRecord rec)
		{
			if (rec == null || !rec.Confirmed || rec.PendingCantripPicks + rec.PendingSpellPicks <= 0)
			{
				return 0;
			}
			try
			{
				SpellEngine.SpendablePicks(rec, out var cantrips, out var spells);
				return cantrips + spells;
			}
			catch
			{
				return 0;
			}
		}

		private static void BuildPicks(RectTransform view, CharacterRecord rec)
		{
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: 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_0164: Expected O, but got Unknown
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Expected O, but got Unknown
			SpellEngine.SpendablePicks(rec, out var cantrips, out var spells);
			string text = "You can learn " + SpellPickData.Describe(new PickCount(cantrips, spells)) + ". Click a spell to choose it, click it again to undo, then press Learn. Hover a spell for its numbers.";
			int num = rec.PendingCantripPicks - cantrips;
			int num2 = rec.PendingSpellPicks - spells;
			if (num > 0 || num2 > 0)
			{
				text = text + " " + SpellPickData.Describe(new PickCount(Math.Max(0, num), Math.Max(0, num2))) + " more stay saved: nothing else on your class list fits your spell slots yet.";
			}
			BuildPickColumns(view, rec, cantrips, spells, text, draft: false);
			RectTransform parent = PickFooter(view);
			UiKit.Frac(((Graphic)UiKit.NewText((Transform)(object)parent, "Msg", PickStatus(cantrips, spells), 16, (_pickMsg != null) ? P.Red : P.Beige, (TextAnchor)3)).rectTransform, 0f, 0f, 0.62f, 1f, 4f, 0f, 4f);
			int num3 = SelectedCount(cantrip: true) + SelectedCount(cantrip: false);
			string label = ((num3 > 0) ? ("Learn selected (" + num3 + ")") : "Learn");
			object obj = <>O.<7>__LearnSelected;
			if (obj == null)
			{
				UnityAction val = LearnSelected;
				<>O.<7>__LearnSelected = val;
				obj = (object)val;
			}
			Button obj2 = UiKit.NewButton((Transform)(object)parent, label, 20, (UnityAction)obj);
			UiKit.Frac((RectTransform)((Component)obj2).transform, 0.64f, 0.1f, 1f, 0.9f);
			((Selectable)obj2).interactable = num3 > 0;
			FinishLists();
		}

		private static void LearnSelected()
		{
			try
			{
				int num = 0;
				string text = null;
				foreach (string item in PickSel.ToList())
				{
					if (SpellEngine.TryPick(item, out var message))
					{
						num++;
					}
					else if (text == null)
					{
						text = message;
					}
				}
				PickSel.Clear();
				_pickMsg = text;
				if (num > 0)
				{
					UiApi.Notify((num == 1) ? "You learned a new spell." : ("You learned " + num + " new spells."));
				}
			}
			catch (Exception ex)
			{
				TWLog.Error("[UI] learning spells failed: " + ex);
			}
			UiTip.HideAll();
			_dirty = true;
		}

		private static RectTransform PickFooter(RectTransform view)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: 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)
			RectTransform obj = UiKit.NewRect("PickFooter", (Transform)(object)view);
			UiKit.Frac(obj, 0f, 0f, 1f, 0f);
			obj.pivot = new Vector2(0.5f, 0f);
			obj.sizeDelta = new Vector2(0f, 58f);
			obj.anchoredPosition = Vector2.zero;
			return obj;
		}

		private static string PickStatus(int capC, int capS)
		{
			if (_pickMsg != null)
			{
				return _pickMsg;
			}
			List<string> list = new List<string>();
			if (capC > 0)
			{
				list.Add(SelectedCount(cantrip: true) + " / " + capC + ((capC == 1) ? " cantrip" : " cantrips"));
			}
			if (capS > 0)
			{
				list.Add(SelectedCount(cantrip: false) + " / " + capS + ((capS == 1) ? " spell" : " spells"));
			}
			if (list.Count != 0)
			{
				return "Chosen: " + string.Join(", ", list);
			}
			return "";
		}

		private static int SelectedCount(bool cantrip)
		{
			int num = 0;
			foreach (string item in PickSel)
			{
				SpellDef spellDef = SpellEngine.Get(item);
				if (spellDef != null && spellDef.Level == 0 == cantrip)
				{
					num++;
				}
			}
			return num;
		}

		private static bool NormalizeSelection(List<SpellDef> options, bool cantrip, int cap)
		{
			HashSet<string> hashSet = new HashSet<string>(options.Select((SpellDef o) => o.Id));
			foreach (string item in PickSel.ToList())
			{
				SpellDef spellDef = SpellEngine.Get(item);
				if (spellDef == null)
				{
					PickSel.Remove(item);
				}
				else if (spellDef.Level == 0 == cantrip && (cap <= 0 || !hashSet.Contains(item)))
				{
					PickSel.Remove(item);
				}
			}
			if (cap > 0 && cap >= options.Count)
			{
				foreach (SpellDef option in options)
				{
					PickSel.Add(option.Id);
				}
				return true;
			}
			int num = 0;
			foreach (SpellDef option2 in options)
			{
				if (PickSel.Contains(option2.Id))
				{
					if (num < cap)
					{
						num++;
					}
					else
					{
						PickSel.Remove(option2.Id);
					}
				}
			}
			return false;
		}

		private static void BuildPickColumns(RectTransform view, CharacterRecord rec, int capC, int capS, string intro, bool draft)
		{
			//IL_0036: 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_00a0: 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_01d7: Unknown result type (might be due to invalid IL or missing references)
			List<SpellDef> options = SpellEngine.PickableFor(rec, cantrip: true).ToList();
			List<SpellDef> options2 = SpellEngine.PickableFor(rec, cantrip: false).ToList();
			bool all = NormalizeSelection(options, cantrip: true, capC);
			bool all2 = NormalizeSelection(options2, cantrip: false, capS);
			Text obj = UiKit.NewText((Transform)(object)view, "Intro", intro, 15, P.Beige, (TextAnchor)0);
			UiKit.Frac(((Graphic)obj).rectTransform, 0f, 1f, 1f, 1f);
			((Graphic)obj).rectTransform.pivot = new Vector2(0.5f, 1f);
			((Graphic)obj).rectTransform.offsetMin = new Vector2(4f, -70f);
			((Graphic)obj).rectTransform.offsetMax = new Vector2(-4f, 0f);
			RectTransform val = UiKit.NewRect("PickRegion", (Transform)(object)view);
			UiKit.Stretch(val, 0f, 64f, 0f, 74f);
			bool flag = capC > 0 && capS > 0;
			if (capC > 0)
			{
				FillPickList(Column(val, "picks.cantrips", 0f, flag ? 0.5f : 1f, "Cantrips: " + SelectedCount(cantrip: true) + " / " + capC), rec, options, cantrip: true, capC, all, draft);
			}
			if (capS > 0)
			{
				FillPickList(Column(val, "picks.spells", flag ? 0.5f : 0f, 1f, "Spells: " + SelectedCount(cantrip: false) + " / " + capS), rec, options2, cantrip: false, capS, all2, draft);
			}
			if (capC + capS <= 0)
			{
				Column(val, "picks.none", 0f, 1f, null).AddText("Nothing to learn right now.", 18, P.Gray, (TextAnchor)0);
			}
		}

		private static void FillPickList(UiList list, CharacterRecord rec, List<SpellDef> options, bool cantrip, int cap, bool all, bool draft)
		{
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0302: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_023a: 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_0218: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c8: Unknown result type (might be due to invalid IL or missing references)
			if (all)
			{
				list.AddText("Every " + (cantrip ? "cantrip" : "spell") + " you can still pick is chosen.", 14, P.Gray, (TextAnchor)0);
			}
			int num = -1;
			foreach (SpellDef option in options)
			{
				if (!cantrip && option.Level != num)
				{
					num = option.Level;
					list.AddHeader("Level " + option.Level + " spells");
				}
				SpellDef spell = option;
				bool flag = PickSel.Contains(option.Id);
				HoverEntry hoverEntry = list.AddEntry(60f, 66, delegate
				{
					TogglePick(spell, cantrip, cap, all);
				});
				hoverEntry.SetSelected(flag);
				hoverEntry.Tip = () => SpellEngine.Tooltip(spell, draft ? rec : CharacterApi.Local);
				AddSpellIcon(((Component)hoverEntry).transform, option.Id, 46f, new Vector2(0f, 1f), new Vector2(0f, 1f), 10f, -9f, ignoreLayout: true);
				RectTransform obj = UiKit.NewRect("Head", ((Component)hoverEntry).transform);
				UiKit.Elem(((Component)obj).gameObject, 24f, 24f);
				UiKit.Frac(((Graphic)UiKit.NewText((Transform)(object)obj, "Name", option.Name, 19, flag ? P.Yellow : P.Orange, (TextAnchor)3, outline: true, wrap: false)).rectTransform, 0f, 0f, 0.6f, 1f);
				List<string> list2 = new List<string>();
				if (option.Concentration)
				{
					list2.Add(P.Rich("Concentration", P.Blue));
				}
				if (flag)
				{
					list2.Add(P.Rich("Chosen", P.Green));
				}
				UiKit.Frac(((Graphic)UiKit.NewText((Transform)(object)obj, "Tags", string.Join("   ", list2), 14, P.Gray, (TextAnchor)5, outline: true, wrap: false)).rectTransform, 0.4f, 0f, 1f, 1f);
				UiKit.NewText(((Component)hoverEntry).transform, "Meta", UiText.SpellMeta(option), 13, P.Gray, (TextAnchor)0);
				string text = SpellEngine.Describe(option, rec);
				if (!string.IsNullOrEmpty(text))
				{
					UiKit.NewText(((Component)hoverEntry).transform, "Desc", text, 14, P.Beige, (TextAnchor)0);
				}
			}
			if (options.Count == 0)
			{
				list.AddText("Nothing left to choose here.", 15, P.Gray, (TextAnchor)0);
			}
		}

		private static void TogglePick(SpellDef sp, bool cantrip, int cap, bool all)
		{
			if (all || sp == null)
			{
				return;
			}
			_pickMsg = null;
			if (PickSel.Contains(sp.Id))
			{
				PickSel.Remove(sp.Id);
			}
			else if (SelectedCount(cantrip) < cap)
			{
				PickSel.Add(sp.Id);
			}
			else if (cap == 1)
			{
				foreach (string item in PickSel.ToList())
				{
					SpellDef spellDef = SpellEngine.Get(item);
					if (spellDef != null && spellDef.Level == 0 == cantrip)
					{
						PickSel.Remove(item);
					}
				}
				PickSel.Add(sp.Id);
			}
			else
			{
				_pickMsg = "You can only choose " + cap + (cantrip ? " cantrips" : " spells") + ". Click a chosen one to take it back first.";
			}
			UiTip.HideAll();
			_dirty = true;
		}

		private static void BuildSummary(RectTransform view, CharacterRecord rec)
		{
			//IL_0492: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_0577: Unknown result type (might be due to invalid IL or missing references)
			//IL_0521: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_0653: Unknown result type (might be due to invalid IL or missing references)
			//IL_066f: Unknown result type (might be due to invalid IL or missing references)
			//IL_069c: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0207: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e7: 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_0280: Unknown result type (might be due to invalid IL or missing references)
			//IL_0761: Unknown result type (might be due to invalid IL or missing references)
			//IL_0766: Unknown result type (might be due to invalid IL or missing references)
			//IL_07b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0905: Unknown result type (might be due to invalid IL or missing references)
			//IL_0380: Unknown result type (might be due to invalid IL or missing references)
			//IL_086a: Unknown result type (might be due to invalid IL or missing references)
			//IL_08cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0849: Unknown result type (might be due to invalid IL or missing references)
			//IL_0422: Unknown result type (might be due to invalid IL or missing references)
			//IL_0433: Unknown result type (might be due to invalid IL or missing references)
			UiList uiList = Column(view, "sum.left", 0f, 0.49f, null);
			UiList uiList2 = Column(view, "sum.right", 0.49f, 1f, "Features and traits");
			Player localPlayer = Player.m_localPlayer;
			RaceDef raceDef = CharacterApi.GetRaceDef(rec.Race);
			ClassDef classDef = CharacterApi.GetClassDef(rec.Class);
			uiList.AddText(((raceDef != null) ? raceDef.Name : "?") + " " + ((classDef != null) ? classDef.Name : "?") + ", level " + rec.Level, 24, P.Orange, (TextAnchor)0);
			int num = CharacterApi.LevelCap();
			bool flag = rec.Level >= num;
			int num2 = CharacterApi.XpForLevel(rec.Level);
			int num3 = CharacterApi.XpForLevel(rec.Level + 1);
			float num4 = ((num3 > num2) ? Mathf.Clamp01((float)(rec.Xp - num2) / (float)(num3 - num2)) : 1f);
			RectTransform parent = uiList.AddRow(24f);
			UiKit.Stretch(((Graphic)UiKit.NewImage((Transform)(object)parent, "Bg", new Color(0f, 0f, 0f, 0.6f))).rectTransform);
			Image obj = UiKit.NewImage((Transform)(object)parent, "Fill", flag ? new Color(0.45f, 0.72f, 1f, 1f) : new Color(0.93f, 0.66f, 0.16f, 1f), UiKit.White);
			UiKit.Stretch(((Graphic)obj).rectTransform, 2f, 2f, 2f, 2f);
			((Graphic)obj).rectTransform.anchorMax = new Vector2(num4, 1f);
			UiKit.Stretch(((Graphic)UiKit.NewText((Transform)(object)parent, "Label", rec.Xp + " / " + num3 + " XP", 15, Color.white, (TextAnchor)4, outline: true, wrap: false)).rectTransform);
			if (flag)
			{
				if (rec.Level >= UiText.ConfiguredMaxLevel())
				{
					uiList.AddText("Maximum level of this version reached.", 15, P.Yellow, (TextAnchor)0);
				}
				else
				{
					string text = UiText.NextBossName();
					uiList.AddText("Level cap reached - defeat " + (text ?? "the next boss") + " to raise it.", 15, P.Yellow, (TextAnchor)0);
				}
			}
			else
			{
				uiList.AddText(num3 - rec.Xp + " XP to level " + (rec.Level + 1) + " (level cap is " + num + ").", 14, P.Gray, (TextAnchor)0);
			}
			AddLearnPanel(uiList, rec);
			uiList.AddSpace(2f);
			uiList.AddHeader("Ability scores");
			for (int i = 0; i < 4; i++)
			{
				AddSummaryStat(uiList, rec, (Stat)i, raceDef);
			}
			if (rec.PendingAsi > 0)
			{
				uiList.AddText("You have " + rec.PendingAsi + " ability point" + ((rec.PendingAsi == 1) ? "" : "s") + " to spend: press + next to a stat.", 15, P.Yellow, (TextAnchor)0);
			}
			uiList.AddText("Proficiency bonus " + UiText.Signed(CharacterApi.ProficiencyBonus(rec.Level)) + "    Spell save DC " + CharacterApi.SpellSaveDC(rec), 16, P.Beige, (TextAnchor)0);
			AddSkillLines(uiList, rec, localPlayer);
			uiList.AddSpace(2f);
			uiList.AddHeader("Armor and rest");
			ArmorCategory c = (((Object)(object)localPlayer != (Object)null) ? CharacterApi.WornArmorCategory(localPlayer) : ArmorCategory.None);
			if ((Object)(object)localPlayer == (Object)null || CharacterApi.IsArmorProficient(localPlayer))
			{
				uiList.AddText("Wearing: " + UiText.ArmorCategoryName(c) + P.Rich("  (proficient)", P.Green), 15, P.Beige, (TextAnchor)0);
			}
			else
			{
				string text2 = "can't cast leveled spells";
				try
				{
					text2 = text2 + ", +" + Mathf.RoundToInt(CoreConfig.NonProfArmorStamina.Value * 100f) + "% stamina use";
				}
				catch
				{
				}
				uiList.AddText("Wearing: " + UiText.ArmorCategoryName(c), 15, P.Beige, (TextAnchor)0);
				uiList.AddText("NOT proficient with this armor: " + text2 + ".", 15, P.Red, (TextAnchor)0);
			}
			_restText = uiList.AddText(RestText(), 15, P.Beige, (TextAnchor)0);
			uiList.AddSpace(2f);
			uiList.AddHeader("Spell points");
			int num5 = SpellPoints.MaxFor(rec.Class, rec.Level);
			if (num5 <= 0)
			{
				uiList.AddText((classDef != null && classDef.Caster == CasterType.None) ? "This class does not cast spells." : "No spell points at this level.", 15, P.Gray, (TextAnchor)0);
			}
			else
			{
				int num6 = CharacterApi.HighestSlotLevel(rec);
				uiList.AddText(SpellPoints.Current(rec) + " / " + num5 + ((classDef != null && classDef.Caster == CasterType.Pact) ? "  (refills on a short rest)" : "  (refills on a long rest)"), 16, P.Beige, (TextAnchor)0);
				List<string> list = new List<string>();
				for (int j = 1; j <= num6; j++)
				{
					list.Add(SpellPoints.Ordinal(j) + " " + SpellPoints.Cost(j));
				}
				uiList.AddText("Cost by spell level: " + string.Join(", ", list) + ". Cantrips are free.", 15, P.Gray, (TextAnchor)0);
			}
			uiList.AddSpace(6f);
			uiList.AddText("[" + UiInput.SheetKeyLabel() + "] sheet   [" + UiInput.KeyLabel(FeatureKey.Feature1) + "] [" + UiInput.KeyLabel(FeatureKey.Feature2) + "] class features   [" + UiInput.KeyLabel(FeatureKey.Racial) + "] racial   [" + UiInput.Label(UiConfig.SpellRadial.Value) + "] spell radial; staff click or " + UiInput.Label(UiConfig.SpellCastClickModifier.Value) + "+click cast; hold [" + UiInput.ModifierLabel() + "] + 1-8 cast", 13, P.Gray, (TextAnchor)0);
			List<FeatureInfo> list2 = UiText.FeaturesFor(rec);
			foreach (FeatureInfo item in (from f in list2
				where f.Level > 0
				orderby f.Level
				select f).Concat(list2.Where((FeatureInfo f) => f.Level <= 0)))
			{
				HoverEntry hoverEntry = uiList2.AddEntry(40f);
				hoverEntry.Normal = new Color(0.14f, 0.095f, 0.055f, 0.65f);
				hoverEntry.SetSelected(on: false);
				RectTransform obj3 = UiKit.NewRect("Head", ((Component)hoverEntry).transform);
				UiKit.Elem(((Component)obj3).gameObject, 22f, 22f);
				UiKit.Frac(((Graphic)UiKit.NewText((Transform)(object)obj3, "Name", item.Name, 18, P.Orange, (TextAnchor)3, outline: true, wrap: false)).rectTransform, 0f, 0f, 0.7f, 1f);
				string text3 = ((item.Level > 0) ? ("Lv " + item.Level) : "Racial");
				if (item.Active && item.Key != FeatureKey.None)
				{
					text3 = P.Rich("[" + UiInput.KeyLabel(item.Key) + "]", P.Green) + "  " + text3;
				}
				UiKit.Frac(((Graphic)UiKit.NewText((Transform)(object)obj3, "Tag", text3, 14, P.Gray, (TextAnchor)5, outline: true, wrap: false)).rectTransform, 0.5f, 0f, 1f, 1f);
				if (!string.IsNullOrEmpty(item.Description))
				{
					UiKit.NewText(((Component)hoverEntry).transform, "Desc", item.Description, 14, P.Beige, (TextAnchor)0);
				}
			}
			if (list2.Count == 0)
			{
				uiList2.AddText("No features yet.", 15, P.Gray, (TextAnchor)0);
			}
			FinishLists();
		}

		private static void AddLearnPanel(UiList list, CharacterRecord rec)
		{
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Expected O, but got Unknown
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Expected O, but got Unknown
			if (rec.PendingCantripPicks + rec.PendingSpellPicks <= 0)
			{
				return;
			}
			int cantrips = 0;
			int spells = 0;
			try
			{
				SpellEngine.SpendablePicks(rec, out cantrips, out spells);
			}
			catch (Exception ex)
			{
				TWLog.Debug("[UI] SpendablePicks failed: " + ex.Message);
			}
			int num = cantrips + spells;
			list.AddSpace(2f);
			HoverEntry hoverEntry = list.AddEntry(70f, 12);
			hoverEntry.Normal = new Color(0.3f, 0.2f, 0.07f, 0.85f);
			hoverEntry.SetSelected(on: false);
			string text = ((num > 0) ? ("You can learn " + SpellPickData.Describe(new PickCount(cantrips, spells)) + ".") : ("You have " + SpellPickData.Describe(new PickCount(rec.PendingCantripPicks, rec.PendingSpellPicks)) + " saved, but nothing on your class list fits your spell slots yet. They open up as you level."));
			UiKit.NewText(((Component)hoverEntry).transform, "Text", text, 16, (num > 0) ? P.Yellow : P.Gray, (TextAnchor)0);
			RectTransform obj = UiKit.NewRect("ButtonRow", ((Component)hoverEntry).transform);
			UiKit.Elem(((Component)obj).gameObject, 36f, 36f);
			string label = "Learn spells (" + num + ")";
			object obj2 = <>c.<>9__81_0;
			if (obj2 == null)
			{
				UnityAction val = delegate
				{
					SwitchView(SheetView.Picks);
				};
				<>c.<>9__81_0 = val;
				obj2 = (object)val;
			}
			Button obj3 = UiKit.NewButton((Transform)(object)obj, label, 18, (UnityAction)obj2);
			UiKit.Frac((RectTransform)((Component)obj3).transform, 0f, 0f, 0.55f, 1f);
			((Selectable)obj3).interactable = num > 0;
		}

		private static void AddSkillLines(UiList list, CharacterRecord rec, Player p)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: 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)
			try
			{
				SkillType[] array = SkillData.CoreSkills(rec.Class);
				if (array.Length != 0 && !((Object)(object)p == (Object)null))
				{
					List<string> list2 = new List<string>();
					SkillType[] array2 = array;
					foreach (SkillType val in array2)
					{
						list2.Add(SkillData.DisplayName(val) + " " + Mathf.FloorToInt(((Character)p).GetSkillLevel(val)));
					}
					list.AddText("Core skills (train x" + SkillData.ClassCoreXpMultiplier.ToString("0.#") + " faster): " + string.Join(", ", list2), 14, P.Gray, (TextAnchor)0);
				}
			}
			catch (Exception ex)
			{
				TWLog.Debug("[UI] core skill line failed: " + ex.Message);
			}
		}

		private static void AddSummaryStat(UiList list, CharacterRecord rec, Stat s, RaceDef rd)
		{
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: 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_01d6: Expected O, but got Unknown
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_020d: Expected O, but got Unknown
			int num = (int)s;
			int num2 = CharacterApi.Score(rec, s);
			int v = CharacterApi.Mod(rec, s);
			int num3 = ((rd != null) ? rd.StatBonus[num] : 0);
			int num4 = ((rec.AsiBonus != null && num < rec.AsiBonus.Length) ? rec.AsiBonus[num] : 0);
			RectTransform parent = list.AddRow(32f);
			UiKit.Frac(((Graphic)UiKit.NewText((Transform)(object)parent, "Main", UiText.StatName(s) + "   " + num2 + "   (" + UiText.Signed(v) + ")", 20, P.Beige, (TextAnchor)3, outline: true, wrap: false)).rectTransform, 0f, 0f, 0.46f, 1f);
			List<string> list2 = new List<string> { "base " + rec.BaseStats[num] };
			if (num3 != 0)
			{
				list2.Add(UiText.Signed(num3) + " race");
			}
			if (num4 != 0)
			{
				list2.Add(UiText.Signed(num4) + " ASI");
			}
			UiKit.Frac(((Graphic)UiKit.NewText((Transform)(object)parent, "Detail", string.Join(", ", list2), 13, P.Gray, (TextAnchor)3, outline: true, wrap: false)).rectTransform, 0.46f, 0f, 0.84f, 1f);
			if (rec.PendingAsi > 0 && num2 < RulesParams.ScoreCap)
			{
				UiKit.Frac((RectTransform)((Component)UiKit.NewButton((Transform)(object)parent, "+", 22, (UnityAction)delegate
				{
					CharacterApi.SpendAsiPoint(s);
					_dirty = true;
				})).transform, 0.86f, 0.05f, 1f, 0.95f);
			}
		}

		private static string RestText()
		{
			//IL_0066: 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)
			try
			{
				float shortRestProgress = CharacterApi.ShortRestProgress;
				if (shortRestProgress > 0.005f)
				{
					return "Short rest: resting by the fire... " + Mathf.RoundToInt(shortRestProgress * 100f) + "%";
				}
				if (CharacterApi.ShortRestAvailableToday())
				{
					return "Short rest: " + P.Rich("available today", P.Green) + " (sit by a burning fire while Rested)";
				}
				return "Short rest: " + P.Rich("already used today", P.Yellow) + " (available again at dawn)";
			}
			catch
			{
				return "";
			}
		}

		private static void UpdateDynamic()
		{
			if ((Object)(object)_restText != (Object)null)
			{
				_restText.text = RestText();
			}
		}

		private static List<SpellDef> AvailableSpells(CharacterRecord rec)
		{
			List<SpellDef> list = new List<SpellDef>();
			try
			{
				IEnumerable<SpellDef> enumerable = SpellEngine.AvailableTo(rec);
				if (enumerable != null)
				{
					foreach (SpellDef item in enumerable)
					{
						if (item != null && !string.IsNullOrEmpty(item.Id))
						{
							list.Add(item);
						}
					}
				}
			}
			catch (Exception ex)
			{
				TWLog.Debug("[UI] SpellEngine.AvailableTo failed: " + ex.Message);
			}
			list.Sort((SpellDef a, SpellDef b) => (a.Level == b.Level) ? string.CompareOrdinal(a.Name, b.Name) : a.Level.CompareTo(b.Level));
			return list;
		}

		private static List<SpellDef> KnownSpellList(CharacterRecord rec)
		{
			List<SpellDef> list = new List<SpellDef>();
			try
			{
				IEnumerable<SpellDef> enumerable = SpellEngine.KnownTo(rec);
				if (enumerable != null)
				{
					foreach (SpellDef item in enumerable)
					{
						if (item != null && !string.IsNullOrEmpty(item.Id))
						{
							list.Add(item);
						}
					}
				}
			}
			catch (Exception ex)
			{
				TWLog.Debug("[UI] SpellEngine.KnownTo failed: " + ex.Message);
			}
			list.Sort((SpellDef a, SpellDef b) => (a.Level == b.Level) ? string.CompareOrdinal(a.Name, b.Name) : a.Level.CompareTo(b.Level));
			return list;
		}

		private static int SlotOf(CharacterRecord rec, string id)
		{
			if (rec.SpellBar == null)
			{
				return -1;
			}
			for (int i = 0; i < rec.SpellBar.Length; i++)
			{
				if (rec.SpellBar[i] == id)
				{
					return i;
				}
			}
			return -1;
		}

		private static void BuildSpells(RectTransform view, CharacterRecord rec)
		{
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: 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_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: 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_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0209: Expected O, but got Unknown
			//IL_020e: Unknown result type (might be due to invalid IL or missing references)
			//IL_021d: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_024a: Expected O, but got Unknown
			//IL_0259: Unknown result type (might be due to invalid IL or missing references)
			//IL_0263: Expected O, but got Unknown
			//IL_0268: Unknown result type (might be due to invalid IL or missing references)
			//IL_0277: Unknown result type (might be due to invalid IL or missing references)
			//IL_0286: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a4: Expected O, but got Unknown
			//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d3: 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_02ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_030b: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0439: Unknown result type (might be due to invalid IL or missing references)
			//IL_0458: Unknown result type (might be due to invalid IL or missing references)
			//IL_0473: Unknown result type (might be due to invalid IL or missing references)
			//IL_048e: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_04fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0639: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0543: Unknown result type (might be due to invalid IL or missing references)
			//IL_0552: Unknown result type (might be due to invalid IL or missing references)
			//IL_0577: Unknown result type (might be due to invalid IL or missing references)
			//IL_0692: Unknown result type (might be due to invalid IL or missing references)
			//IL_066d: Unknown result type (might be due to invalid IL or missing references)
			//IL_07b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_07c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0826: Unknown result type (might be due to invalid IL or missing references)
			//IL_081f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0892: Unknown result type (might be due to invalid IL or missing references)
			//IL_08b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_091a: Unknown result type (might be due to invalid IL or missing references)
			//IL_096e: Unknown result type (might be due to invalid IL or missing references)
			//IL_08f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_09ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_09b3: Unknown result type (might be due to invalid IL or missing references)
			if (rec.SpellBar == null || rec.SpellBar.Length != 8)
			{
				Array.Resize(ref rec.SpellBar, 8);
			}
			_selSlot = Mathf.Clamp(_selSlot, 0, 7);
			List<SpellDef> spells = AvailableSpells(rec);
			List<SpellDef> list = KnownSpellList(rec);
			HashSet<string> hashSet = new HashSet<string>(spells.Select((SpellDef x) => x.Id));
			RectTransform val = UiKit.NewRect("BarEditor", (Transform)(object)view);
			val.anchorMin = new Vector2(0f, 1f);
			val.anchorMax = new Vector2(1f, 1f);
			val.pivot = new Vector2(0.5f, 1f);
			val.sizeDelta = new Vector2(0f, 168f);
			val.anchoredPosition = Vector2.zero;
			Text obj = UiKit.NewText((Transform)(object)val, "Hint", "Spell bar: " + UiInput.Label(UiConfig.SpellRadial.Value) + " opens the spell radial; staff left click or " + UiInput.Label(UiConfig.SpellCastClickModifier.Value) + "+left click casts. Hold " + UiInput.ModifierLabel() + " and press 1-8 in the world to cast. Click a slot, then click a spell to put it there. Right-click a slot to empty it.", 15, P.Beige, (TextAnchor)0);
			UiKit.Frac(((Graphic)obj).rectTransform, 0f, 1f, 0.7f, 1f);
			((Graphic)obj).rectTransform.pivot = new Vector2(0f, 1f);
			((Graphic)obj).rectTransform.offsetMin = new Vector2(4f, -44f);
			((Graphic)obj).rectTransform.offsetMax = new Vector2(-4f, 0f);
			UiKit.Pin((RectTransform)((Component)UiKit.NewButton((Transform)(object)val, "Auto-fill", 16, (UnityAction)delegate
			{
				AutoFill(rec, spells);
			})).transform, new Vector2(1f, 1f), new Vector2(1f, 1f), -150f, -4f, 130f, 34f);
			UiKit.Pin((RectTransform)((Component)UiKit.NewButton((Transform)(object)val, "Clear all", 16, (UnityAction)delegate
			{
				for (int i = 0; i < 8; i++)
				{
					rec.SpellBar[i] = null;
				}
				CharacterApi.MarkDirty();
			})).transform, new Vector2(1f, 1f), new Vector2(1f, 1f), -4f, -4f, 140f, 34f);
			RectTransform val2 = UiKit.NewRect("Slots", (Transform)(object)val);
			val2.anchorMin = new Vector2(0f, 0f);
			val2.anchorMax = new Vector2(1f, 0f);
			val2.pivot = new Vector2(0.5f, 0f);
			val2.sizeDelta = new Vector2(0f, 112f);
			val2.anchoredPosition = Vector2.zero;
			for (int num = 0; num < 8; num++)
			{
				int idx = num;
				string text = rec.SpellBar[num];
				RectTransform val3 = UiKit.NewRect("Slot" + (num + 1), (Transform)(object)val2);
				UiKit.Frac(val3, (float)num / 8f, 0f, (float)(num + 1) / 8f, 1f, 3f, 0f, 3f);
				Image val4 = ((Component)val3).gameObject.AddComponent<Image>();
				((Graphic)val4).color = P.Entry;
				((Graphic)val4).raycastTarget = true;
				HoverEntry hoverEntry = ((Component)val3).gameObject.AddComponent<HoverEntry>();
				hoverEntry.Background = val4;
				if (!string.IsNullOrEmpty(text))
				{
					string tipId = text;
					hoverEntry.Tip = () => SpellEngine.Tooltip(SpellEngine.Get(tipId), CharacterApi.Local);
				}
				hoverEntry.OnLeft = delegate
				{
					_selSlot = idx;
					_dirty = true;
				};
				hoverEntry.OnRight = delegate
				{
					rec.SpellBar[idx] = null;
					CharacterApi.MarkDirty();
				};
				Image val5 = UiKit.NewImage((Transform)(object)val3, "Accent", P.Gold);
				((Graphic)val5).rectTransform.anchorMin = new Vector2(0f, 0f);
				((Graphic)val5).rectTransform.anchorMax = new Vector2(1f, 0f);
				((Graphic)val5).rectTransform.pivot = new Vector2(0.5f, 0f);
				((Graphic)val5).rectTransform.sizeDelta = new Vector2(0f, 4f);
				((Graphic)val5).rectTransform.anchoredPosition = Vector2.zero;
				((Component)val5).gameObject.SetActive(false);
				hoverEntry.Accent = val5;
				hoverEntry.SetSelected(num == _selSlot);
				UiKit.Stretch(((Graphic)UiKit.NewText((Transform)(object)val3, "Num", NumStr.Of(num + 1), 17, P.Gold, (TextAnchor)0, outline: true, wrap: false)).rectTransform, 6f, 4f, 4f, 3f);
				if (!string.IsNullOrEmpty(text))
				{
					AddSpellIcon((Transform)(object)val3, text, 46f, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), 0f, -10f);
					UiKit.Stretch(((Graphic)UiKit.NewText((Transform)(object)val3, "Name", UiText.SpellName(text), 13, Color.white, (TextAnchor)7)).rectTransform, 3f, 4f, 3f, 62f);
				}
				else
				{
					UiKit.Stretch(((Graphic)UiKit.NewText((Transform)(object)val3, "Empty", "empty", 14, P.Gray, (TextAnchor)4, outline: true, wrap: false)).rectTransform);
				}
			}
			UiList uiList = Column(view, "spells.list", 0f, 1f, null);
			UiKit.Stretch(uiList.Root, 0f, 0f, 0f, 176f);
			if (list.Count == 0)
			{
				uiList.AddText("You do not know any spells yet.", 18, P.Gray, (TextAnchor)0);
				ClassDef classDef = CharacterApi.GetClassDef(rec.Class);
				if (classDef != null && classDef.Caster == CasterType.None)
				{
					uiList.AddText("Your class does not cast spells.", 15, P.Gray, (TextAnchor)0);
				}
				else if (SpendableTotal(rec) > 0)
				{
					uiList.AddText("Open the Learn tab to choose your spells.", 15, P.Yellow, (TextAnchor)0);
				}
			}
			int num2 = -1;
			foreach (SpellDef item in list)
			{
				if (item.Level != num2)
				{
					num2 = item.Level;
					uiList.AddHeader((item.Level <= 0) ? "Cantrips (free, cooldown)" : ("Level " + item.Level + " spells (" + SpellPoints.Cost(item.Level) + " points)"));
				}
				SpellDef spell = item;
				bool usable = hashSet.Contains(item.Id);
				HoverEntry hoverEntry2 = uiList.AddEntry(62f, 66, delegate
				{
					if (usable)
					{
						AssignSpell(rec, spell.Id);
					}
				});
				hoverEntry2.Tip = () => SpellEngine.Tooltip(spell, CharacterApi.Local);
				hoverEntry2.SetSelected(on: false);
				AddSpellIcon(((Component)hoverEntry2).transform, item.Id, 46f, new Vector2(0f, 1f), new Vector2(0f, 1f), 10f, -9f, ignoreLayout: true);
				RectTransform obj2 = UiKit.NewRect("Head", ((Component)hoverEntry2).transform);
				UiKit.Elem(((Component)obj2).gameObject, 24f, 24f);
				UiKit.Frac(((Graphic)UiKit.NewText((Transform)(object)obj2, "Name", item.Name, 19, usable ? P.Orange : P.Gray, (TextAnchor)3, outline: true, wrap: false)).rectTransform, 0f, 0f, 0.6f, 1f);
				List<string> list2 = new List<string>();
				if (!usable)
				{
					list2.Add(P.Rich("Needs " + SpellPoints.Ordinal(item.Level) + "-level spells", P.Red));
				}
				if (item.Concentration)
				{
					list2.Add(P.Rich("Concentration", P.Blue));
				}
				int num3 = SlotOf(rec, item.Id);
				if (num3 >= 0)
				{
					list2.Add(P.Rich("Slot " + (num3 + 1), P.Green));
				}
				UiKit.Frac(((Graphic)UiKit.NewText((Transform)(object)obj2, "Tags", string.Join("   ", list2), 14, P.Gray, (TextAnchor)5, outline: true, wrap: false)).rectTransform, 0.4f, 0f, 1f, 1f);
				UiKit.NewText(((Component)hoverEntry2).transform, "Meta", UiText.SpellMeta(item), 13, P.Gray, (TextAnchor)0);
				string text2 = SpellEngine.Describe(item, rec);
				if (!string.IsNullOrEmpty(text2))
				{
					UiKit.NewText(((Component)hoverEntry2).transform, "Desc", text2, 14, usable ? P.Beige : P.Gray, (TextAnchor)0);
				}
			}
			FinishLists();
		}

		private static void AddSpellIcon(Transform parent, string id, float size, Vector2 anchor, Vector2 pivot, float x, float y, bool ignoreLayout = false)
		{
			//IL_0032: 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_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = UiKit.NewRect("IconHolder", parent);
			if (ignoreLayout)
			{
				UiKit.Elem(((Component)val).gameObject, -1f, -1f, -1f, -1f, ignore: true);
			}
			UiKit.Pin(val, anchor, pivot, x, y, size, size);
			Sprite obj = IconLibrary.Spell(id);
			Sprite val2 = obj ?? IconLibrary.Placeholder;
			Image obj2 = UiKit.NewImage((Transform)(object)val, "Icon", Color.white);
			obj2.preserveAspect = true;
			UiKit.Stretch(((Graphic)obj2).rectTransform);
			obj2.sprite = val2;
			((Behaviour)obj2).enabled = (Object)(object)val2 != (Object)null;
			if ((Object)(object)obj == (Object)null)
			{
				UiKit.Stretch(((Graphic)UiKit.NewText((Transform)(object)val, "Abbr", IconLibrary.Initials(UiText.SpellName(id)), Mathf.RoundToInt(size * 0.38f), P.Beige, (TextAnchor)4, outline: true, wrap: false)).rectTransform);
			}
		}

		private static void AssignSpell(CharacterRecord rec, string id)
		{
			if (rec.SpellBar == null || rec.SpellBar.Length != 8)
			{
				Array.Resize(ref rec.SpellBar, 8);
			}
			for (int i = 0; i < 8; i++)
			{
				if (rec.SpellBar[i] == id)
				{
					rec.SpellBar[i] = null;
				}
			}
			rec.SpellBar[_selSlot] = id;
			int selSlot = _selSlot;
			for (int j = 1; j <= 8; j++)
			{
				int num = (_selSlot + j) % 8;
				if (string.IsNullOrEmpty(rec.SpellBar[num]))
				{
					selSlot = num;
					break;
				}
			}
			_selSlot = selSlot;
			CharacterApi.MarkDirty();
		}

		private static void AutoFill(CharacterRecord rec, List<SpellDef> spells)
		{
			if (rec.SpellBar == null || rec.SpellBar.Length != 8)
			{
				Array.Resize(ref rec.SpellBar, 8);
			}
			foreach (SpellDef spell in spells)
			{
				if (SlotOf(rec, spell.Id) < 0)
				{
					int num = Array.FindIndex(rec.SpellBar, (string s) => string.IsNullOrEmpty(s));
					if (num < 0)
					{
						break;
					}
					rec.SpellBar[num] = spell.Id;
				}
			}
			CharacterApi.MarkDirty();
		}
	}
	internal static class ControlSettings
	{
		private static readonly Func<KeyCode, bool, string> KeyPath = (Func<KeyCode, bool, string>)Delegate.CreateDelegate(typeof(Func<KeyCode, bool, string>), AccessTools.Method(typeof(ZInput), "KeyCodeToPath", new Type[2]
		{
			typeof(KeyCode),
			typeof(bool)
		}, (Type[])null));

		private static readonly MethodInfo AddButton = AccessTools.Method(typeof(ZInput), "AddButton", new Type[7]
		{
			typeof(string),
			typeof(string),
			typeof(bool),
			typeof(bool),
			typeof(bool),
			typeof(float),
			typeof(float)
		}, (Type[])null);

		private static Dictionary<string, KeyCode> _keys;

		private static string Path(KeyCode key)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			if ((int)key != 0)
			{
				return KeyPath(key, arg2: false);
			}
			return "";
		}

		private static bool TryKey(string path, out KeyCode key)
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Invalid comparison between Unknown and I4
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			path = RadialRules.NormalizePath(path);
			key = (KeyCode)0;
			if (path.Length == 0)
			{
				return true;
			}
			if (_keys == null)
			{
				_keys = new Dictionary<string, KeyCode>(StringComparer.OrdinalIgnoreCase);
				foreach (KeyCode value in Enum.GetValues(typeof(KeyCode)))
				{
					if ((int)value != 0 && (int)value < 330)
					{
						string text = Path(value);
						if (!string.IsNullOrEmpty(text))
						{
							_keys[RadialRules.NormalizePath(text)] = value;
						}
					}
				}
			}
			return _keys.TryGetValue(path, out key);
		}

		internal static void Restore(bool defaults = false)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			ZInput instance = ZInput.instance;
			if (instance == null)
			{
				return;
			}
			foreach (UiInput.Binding binding in UiInput.Bindings)
			{
				string text = Path((KeyCode)(defaults ? ((KeyCode)((ConfigEntryBase)binding.Key).DefaultValue) : binding.Key.Value));
				if (instance.GetButtonDef(binding.Name) == null)
				{
					AddButton.Invoke(instance, new object[7] { binding.Name, text, false, true, true, 0f, 0f });
				}
				else
				{
					instance.GetButtonDef(binding.Name).Rebind(text);
				}
			}
		}

		internal static void Save()
		{
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			ZInput instance = ZInput.instance;
			if (instance == null || UiInput.Bindings.Count == 0)
			{
				return;
			}
			List<KeyValuePair<UiInput.Binding, KeyCode>> list = new List<KeyValuePair<UiInput.Binding, KeyCode>>();
			foreach (UiInput.Binding binding in UiInput.Bindings)
			{
				ButtonDef buttonDef = instance.GetButtonDef(binding.Name);
				if (buttonDef != null)
				{
					if (!TryKey(buttonDef.GetActionPath(true), out var key))
					{
						throw new InvalidOperationException("Unsupported key path for " + binding.Label);
					}
					list.Add(new KeyValuePair<UiInput.Binding, KeyCode>(binding, key));
				}
			}
			foreach (KeyValuePair<UiInput.Binding, KeyCode> item in list)
			{
				item.Key.Key.Value = item.Value;
			}
			TWConfig.File.Save();
		}

		internal static void AddRows(KeyboardMouseSettings settings)
		{
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (mig