Decompiled source of KCM Deck Builder v2.0.0

plugins/KCMDeckBuilder.dll

Decompiled 11 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using DiskCardGame;
using GBC;
using HarmonyLib;
using InscryptionAPI.Ascension;
using InscryptionAPI.Card;
using InscryptionAPI.Saves;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("KCMDeckBuilder")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+6d1ebea822c0f8140f8ef9362024369ff04d66fd")]
[assembly: AssemblyProduct("KCMDeckBuilder")]
[assembly: AssemblyTitle("KCMDeckBuilder")]
[assembly: AssemblyVersion("1.0.0.0")]
[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 KCMDeckBuilder
{
	internal static class CardFace
	{
		private class Info
		{
			internal Texture2D bg;

			internal Color tint;

			internal Texture2D portrait;

			internal Rect portraitUv;

			internal bool portraitScaled;

			internal List<Texture> decals;

			internal Texture cost;

			internal List<Texture> sigils;

			internal Texture statIcon;

			internal string name;

			internal string attack;

			internal string health;

			internal int nameSize = -1;

			internal int nameFit;
		}

		internal const float W = 125f;

		internal const float H = 190f;

		internal const float Aspect = 25f / 38f;

		private static readonly Color Ink = new Color(0.1f, 0.09f, 0.12f);

		private static readonly Color Paper = new Color(1f, 0.86f, 0.72f);

		private static Texture2D bg;

		private static Texture2D bgRare;

		private static Texture2D bgTerrain;

		private static readonly Color Gold = new Color(1f, 0.78f, 0.22f);

		private static Font font;

		private static bool loaded;

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

		private static readonly Dictionary<Ability, Texture> sigilCache = new Dictionary<Ability, Texture>();

		private static GUIStyle text;

		private static readonly Dictionary<CardInfo, Info> infoCache = new Dictionary<CardInfo, Info>();

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

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

		internal static bool Available
		{
			get
			{
				Load();
				return (Object)(object)bg != (Object)null;
			}
		}

		internal static void ClearCache()
		{
			infoCache.Clear();
		}

		internal static void Report(CardInfo c, string what, Exception e)
		{
			string item = (((Object)(object)c != (Object)null) ? ((Object)c).name : "?") + ":" + what;
			if (reported.Add(item))
			{
				Plugin.Log.LogWarning((object)("Card '" + (((Object)(object)c != (Object)null) ? ((Object)c).name : "?") + "': could not read " + what + " (" + e.GetType().Name + ": " + e.Message + ")"));
			}
		}

		private static void Try(CardInfo c, string what, Action a)
		{
			try
			{
				a();
			}
			catch (Exception e)
			{
				Report(c, what, e);
			}
		}

		internal static string Name(CardInfo c)
		{
			return Get(c).name;
		}

		private static Info Get(CardInfo c)
		{
			//IL_0049: 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)
			if (infoCache.TryGetValue(c, out var i))
			{
				return i;
			}
			i = new Info
			{
				decals = new List<Texture>(),
				sigils = new List<Texture>(),
				tint = Paper,
				bg = bg
			};
			Try(c, "background", delegate
			{
				i.bg = Background(c, out i.tint);
			});
			Try(c, "portrait", delegate
			{
				//IL_0077: 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)
				//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
				Sprite portraitTex = c.portraitTex;
				if ((Object)(object)portraitTex != (Object)null && (Object)(object)portraitTex.texture != (Object)null)
				{
					i.portrait = portraitTex.texture;
					i.portraitScaled = ((Texture)i.portrait).width > 128 || ((Texture)i.portrait).height > 128;
					Rect textureRect = portraitTex.textureRect;
					i.portraitUv = new Rect(((Rect)(ref textureRect)).x / (float)((Texture)i.portrait).width, ((Rect)(ref textureRect)).y / (float)((Texture)i.portrait).height, ((Rect)(ref textureRect)).width / (float)((Texture)i.portrait).width, ((Rect)(ref textureRect)).height / (float)((Texture)i.portrait).height);
				}
				else
				{
					i.portrait = FallbackPortrait(c);
				}
			});
			Try(c, "decals", delegate
			{
				i.decals = Decals(c).ToList();
			});
			Try(c, "cost", delegate
			{
				i.cost = Cost(c);
			});
			Try(c, "sigils", delegate
			{
				i.sigils = (from t in (c.Abilities ?? new List<Ability>()).Distinct().Select(Sigil)
					where (Object)(object)t != (Object)null
					select t).ToList();
			});
			Try(c, "stat icon", delegate
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_0016: 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)
				StatIconInfo val = (((int)c.SpecialStatIcon != 0) ? StatIconInfo.GetIconInfo(c.SpecialStatIcon) : null);
				if ((Object)(object)val != (Object)null && (Object)(object)val.iconGraphic != (Object)null && StatIconInfo.IconAppliesToAttack(c.SpecialStatIcon))
				{
					i.statIcon = val.iconGraphic;
				}
			});
			i.name = Plugin.DisplayName(c).ToUpperInvariant();
			i.attack = "?";
			i.health = "?";
			Try(c, "stats", delegate
			{
				i.attack = c.Attack.ToString();
				i.health = c.Health.ToString();
			});
			infoCache[c] = i;
			return i;
		}

		private static void Load()
		{
			if (!loaded)
			{
				loaded = true;
				bg = Resources.Load<Texture2D>("art/cards/card_empty");
				bgRare = Resources.Load<Texture2D>("art/cards/card_empty_rare");
				bgTerrain = Resources.Load<Texture2D>("art/cards/card_terrain_empty");
				font = FindFont();
				Plugin.Log.LogInfo((object)string.Format("Card face: background={0}, font={1}", (Object)(object)bg != (Object)null, ((Object)(object)font != (Object)null) ? ((Object)font).name : "fallback"));
			}
		}

		private static Font FindFont()
		{
			Font val = Resources.Load<Font>("fonts/3d scene fonts/heavyweight");
			if ((Object)(object)val != (Object)null)
			{
				return val;
			}
			val = ((IEnumerable<Font>)Resources.FindObjectsOfTypeAll<Font>()).FirstOrDefault((Func<Font, bool>)((Font x) => ((Object)x).name == "HEAVYWEIGHT"));
			if ((Object)(object)val != (Object)null)
			{
				return val;
			}
			try
			{
				TMP_FontAsset val2 = Resources.Load<TMP_FontAsset>("fonts/3d scene fonts/heavyweight");
				if ((Object)(object)val2 != (Object)null && (Object)(object)val2.sourceFontFile != (Object)null)
				{
					return val2.sourceFontFile;
				}
			}
			catch
			{
			}
			return ((IEnumerable<Font>)Resources.FindObjectsOfTypeAll<Font>()).FirstOrDefault((Func<Font, bool>)((Font x) => ((Object)x).name == "HEAVYWEIGHT"));
		}

		private static bool Has(CardInfo c, Appearance a)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return c.appearanceBehaviour.Contains(a);
		}

		private static Texture2D Background(CardInfo c, out Color tint)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			tint = (Has(c, (Appearance)6) ? Gold : Paper);
			if (Has(c, (Appearance)2) && (Object)(object)bgTerrain != (Object)null)
			{
				return bgTerrain;
			}
			if ((Has(c, (Appearance)7) || Plugin.IsRare(c)) && (Object)(object)bgRare != (Object)null)
			{
				return bgRare;
			}
			return bg;
		}

		private static Texture Cost(CardInfo c)
		{
			string text = ((c.BloodCost > 0) ? $"cost_{c.BloodCost}blood" : ((c.BonesCost > 0) ? $"cost_{c.BonesCost}bone" : null));
			if (text == null)
			{
				return null;
			}
			if (!costCache.TryGetValue(text, out var value))
			{
				value = (costCache[text] = Resources.Load<Texture>("art/cards/costs/" + text));
			}
			return value;
		}

		internal static Texture2D FallbackPortrait(CardInfo c)
		{
			if (!portraitCache.TryGetValue(((Object)c).name, out var value))
			{
				value = (portraitCache[((Object)c).name] = Resources.Load<Texture2D>("art/cards/portraits/portrait_" + ((Object)c).name.ToLowerInvariant()));
			}
			return value;
		}

		private static IEnumerable<Texture> Decals(CardInfo c)
		{
			List<Texture> list;
			try
			{
				list = c.Decals.Where((Texture t) => (Object)(object)t != (Object)null).ToList();
			}
			catch
			{
				list = new List<Texture>();
			}
			if (c.appearanceBehaviour.Contains((Appearance)4))
			{
				Texture val = Resources.Load<Texture>("art/cards/decals/decal_snelk_main");
				if ((Object)(object)val != (Object)null)
				{
					list.Add(val);
				}
			}
			return list;
		}

		private unsafe static Texture Sigil(Ability a)
		{
			//IL_0005: 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)
			if (!sigilCache.TryGetValue(a, out var value))
			{
				try
				{
					value = AbilitiesUtil.LoadAbilityIcon(((object)(*(Ability*)(&a))/*cast due to .constrained prefix*/).ToString(), false, false);
				}
				catch
				{
					value = null;
				}
				sigilCache[a] = value;
			}
			return value;
		}

		internal static void DrawPortraitBox(Rect r, CardInfo c)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			Load();
			Info info = Get(c);
			Rect val = default(Rect);
			((Rect)(ref val))..ctor(0.04f, 32f / 95f, 0.912f, 47f / 95f);
			if ((Object)(object)info.bg != (Object)null)
			{
				Color color = GUI.color;
				GUI.color = info.tint;
				GUI.DrawTextureWithTexCoords(r, (Texture)(object)info.bg, val);
				GUI.color = color;
			}
			if ((Object)(object)info.portrait != (Object)null)
			{
				if (info.portraitScaled)
				{
					GUI.DrawTextureWithTexCoords(r, (Texture)(object)info.portrait, info.portraitUv);
				}
				else
				{
					GUI.DrawTexture(r, (Texture)(object)info.portrait);
				}
			}
			foreach (Texture decal in info.decals)
			{
				GUI.DrawTextureWithTexCoords(r, decal, val);
			}
		}

		internal static void Draw(Rect r, CardInfo c)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: 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_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: 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_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0247: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: Expected O, but got Unknown
			//IL_01f9: 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_0208: Expected O, but got Unknown
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_0214: Expected O, but got Unknown
			//IL_0301: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ab: Expected O, but got Unknown
			//IL_02a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_038e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0366: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c4: Unknown result type (might be due to invalid IL or missing references)
			Load();
			float k = ((Rect)(ref r)).width / 125f;
			Info info = Get(c);
			Color color = GUI.color;
			GUI.color = info.tint;
			GUI.DrawTexture(r, (Texture)(object)info.bg);
			GUI.color = color;
			if ((Object)(object)info.portrait != (Object)null)
			{
				if (info.portraitScaled)
				{
					GUI.DrawTextureWithTexCoords(P(5f, 32f, 114f, 94f), (Texture)(object)info.portrait, info.portraitUv);
				}
				else
				{
					GUI.DrawTexture(P(5f, 32f, ((Texture)info.portrait).width, ((Texture)info.portrait).height), (Texture)(object)info.portrait);
				}
			}
			foreach (Texture decal in info.decals)
			{
				GUI.DrawTexture(r, decal);
			}
			if ((Object)(object)info.cost != (Object)null)
			{
				GUI.DrawTexture(P(59f, 14f, 64f, 64f), info.cost);
			}
			List<Texture> sigils = info.sigils;
			if (sigils.Count == 1)
			{
				GUI.DrawTexture(P(38f, 133f, 49f, 49f), sigils[0]);
			}
			else if (sigils.Count >= 2)
			{
				GUI.DrawTexture(P(28f, 140f, 34f, 34f), sigils[0]);
				GUI.DrawTexture(P(63f, 140f, 34f, 34f), sigils[1]);
			}
			if (text == null)
			{
				text = new GUIStyle(GUI.skin.label)
				{
					alignment = (TextAnchor)0,
					padding = new RectOffset(0, 0, 0, 0),
					margin = new RectOffset(0, 0, 0, 0),
					wordWrap = false
				};
				if ((Object)(object)font != (Object)null)
				{
					text.font = font;
				}
				else
				{
					text.fontStyle = (FontStyle)1;
				}
			}
			text.normal.textColor = Ink;
			int num = Mathf.Max(1, Mathf.RoundToInt(22f * k));
			text.alignment = (TextAnchor)4;
			if (info.nameSize != num)
			{
				text.fontSize = num;
				float num2 = 115f * k;
				float x = text.CalcSize(new GUIContent(info.name)).x;
				info.nameSize = num;
				info.nameFit = ((x > num2) ? Mathf.Max(1, Mathf.FloorToInt((float)num * num2 / x)) : num);
			}
			text.fontSize = info.nameFit;
			GUI.Label(P(5f, 4f, 115f, 28f), info.name, text);
			text.fontSize = Mathf.Max(1, Mathf.RoundToInt(40f * k));
			text.alignment = (TextAnchor)3;
			if ((Object)(object)info.statIcon != (Object)null)
			{
				GUI.DrawTexture(P(4f, 138f, 40f, 40f), info.statIcon);
			}
			else
			{
				GUI.Label(P(10f, 136f, 40f, 50f), info.attack, text);
			}
			text.alignment = (TextAnchor)4;
			GUI.Label(P(92f, 146f, 30f, 46f), info.health, text);
			Rect P(float num3, float y, float w, float h)
			{
				//IL_003e: Unknown result type (might be due to invalid IL or missing references)
				return new Rect(((Rect)(ref r)).x + num3 * k, ((Rect)(ref r)).y + y * k, w * k, h * k);
			}
		}
	}
	internal class DeckBuilderUI : MonoBehaviour
	{
		private struct Ghost
		{
			public Vector2 Pos;

			public Sprite Sprite;

			public float Born;
		}

		private enum Page
		{
			Cards,
			Decks,
			Settings
		}

		internal static AscensionMenuScreens Menu;

		private static readonly string[] Sorts = DeckLogic.Sorts;

		private static readonly Color Red = new Color(0.8f, 0.16f, 0.19f);

		private static readonly Color RedDim = new Color(0.42f, 0.08f, 0.1f);

		private static readonly Color RedBright = new Color(1f, 0.32f, 0.34f);

		private static readonly Color Bg = new Color(0.075f, 0.06f, 0.07f, 1f);

		private bool open;

		private Vector2 outerMouse;

		private float guiScale = 1f;

		private Rect? clipView;

		private string hoverKey;

		private string lastHoverKey;

		private float hoverSince;

		private float blinkFrequency = 0.2f;

		private List<Sprite> cursorSprites;

		private List<Sprite> cursorDownSprites;

		private float cursorScale;

		private float trailFrequency = 0.03f;

		private float trailTimer;

		private float trailBrightness = 0.9f;

		private bool cursorReady;

		private bool cursorTried;

		private readonly List<Ghost> ghosts = new List<Ghost>();

		private const float GhostLife = 0.115f;

		private Page page;

		private string deckName = "";

		private List<KeyValuePair<string, string>> savedDecks = new List<KeyValuePair<string, string>>();

		private Vector2 savedScroll;

		private readonly Random rng = new Random();

		private List<CardInfo> pool = new List<CardInfo>();

		private List<CardInfo> deck = new List<CardInfo>();

		private HashSet<string> starterNames = new HashSet<string>();

		private string[] filters = DeckLogic.BaseFilters;

		private string filter = "ALL";

		private int sort;

		private string search = "";

		private List<CardInfo> visibleCache;

		private string visibleFilter;

		private string visibleSearch;

		private int visibleSort = -1;

		private readonly Dictionary<CardInfo, string> searchCache = new Dictionary<CardInfo, string>();

		private readonly Dictionary<CardInfo, string> describeCache = new Dictionary<CardInfo, string>();

		private readonly Dictionary<string, List<CardInfo>> savedCardsCache = new Dictionary<string, List<CardInfo>>();

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

		private float measureU;

		private Vector2 poolScroll;

		private Vector2 deckScroll;

		private string message = "";

		private float messageUntil;

		private CardInfo hovered;

		private float vw;

		private float vh;

		private float u;

		private GUISkin skin;

		private Font pixelFont;

		private GUIStyle text;

		private GUIStyle frame;

		private GUIStyle frameHover;

		private GUIStyle frameFilled;

		private GUIStyle frameFilledHover;

		private Texture2D texBg;

		private Texture2D texRed;

		private Texture2D texRedBright;

		private Texture2D texDash;

		private Texture2D texScan;

		private Texture2D texFrame;

		private Texture2D texFrameHover;

		private Texture2D texFrameFilled;

		private Texture2D texFrameFilledHover;

		private Texture texBack;

		private Texture texContinue;

		private int errorsLogged;

		private bool forcedPointer;

		internal static DeckBuilderUI Instance;

		private bool OnDeckScreen
		{
			get
			{
				//IL_001e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0025: Invalid comparison between Unknown and I4
				if ((Object)(object)Menu != (Object)null && ((Behaviour)Menu).isActiveAndEnabled)
				{
					return (int)Menu.CurrentScreen == 14;
				}
				return false;
			}
		}

		private void Awake()
		{
			Instance = this;
			((MonoBehaviour)this).useGUILayout = false;
		}

		private void Update()
		{
			try
			{
				Tick();
			}
			catch (Exception e)
			{
				Fail(e);
			}
		}

		private void Fail(Exception e)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			if (errorsLogged++ < 3)
			{
				Plugin.Log.LogError((object)("Deck builder error, closing it: " + e));
			}
			GUI.matrix = Matrix4x4.identity;
			try
			{
				if (open)
				{
					Close(save: false);
				}
			}
			catch
			{
				open = false;
			}
		}

		private void Tick()
		{
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			if (open && cursorReady)
			{
				Cursor.visible = false;
				trailTimer += Time.unscaledDeltaTime;
				if (trailTimer > trailFrequency)
				{
					trailTimer = 0f;
					ghosts.Add(new Ghost
					{
						Pos = new Vector2(Input.mousePosition.x, (float)Screen.height - Input.mousePosition.y),
						Sprite = CurrentCursorSprite(),
						Born = Time.unscaledTime
					});
				}
			}
			if (!open && !OnDeckScreen && forcedPointer)
			{
				SetGameCursorPointer(on: false);
				lastHoverKey = null;
			}
			if (open && !OnDeckScreen)
			{
				Close(save: false);
			}
			if (open && Input.GetKeyDown((KeyCode)27))
			{
				Close(save: false);
			}
		}

		private void OnGUI()
		{
			if (!OnDeckScreen)
			{
				return;
			}
			try
			{
				DrawUI();
			}
			catch (Exception ex) when (!(ex is ExitGUIException))
			{
				Fail(ex);
			}
		}

		private void DrawUI()
		{
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Invalid comparison between Unknown and I4
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			InitStyles();
			GUI.skin = skin;
			float num = (guiScale = Mathf.Max(1f, Mathf.Floor((float)Screen.height / 700f)));
			vw = (float)Screen.width / num;
			vh = (float)Screen.height / num;
			u = vh / 720f;
			GUI.matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(num, num, 1f));
			outerMouse = Event.current.mousePosition;
			clipView = null;
			bool flag = (int)Event.current.type == 7;
			if (flag)
			{
				hoverKey = null;
			}
			if (!open && OpenButtonPatch.Added)
			{
				return;
			}
			if (!open)
			{
				bool flag2 = AscensionSaveData.Data.currentStarterDeck == "emre.inscryption.kcmdeckbuilder_Custom";
				Rect r = R(vw / u / 2f - 150f, 116f, 300f, 34f);
				if (FrameButton(r, flag2 ? "CUSTOM DECK [SELECTED]" : "BUILD CUSTOM DECK", primary: false, 16))
				{
					Open();
				}
			}
			else
			{
				DrawPanel();
			}
			if (!flag)
			{
				return;
			}
			if (hoverKey != lastHoverKey)
			{
				if (hoverKey != null)
				{
					CommandLineTextDisplayer.PlayCommandLineClickSound();
				}
				lastHoverKey = hoverKey;
				hoverSince = Time.unscaledTime;
				if (!open)
				{
					SetGameCursorPointer(hoverKey != null);
				}
			}
			if (open)
			{
				DrawGameCursor();
			}
		}

		private void SetGameCursorPointer(bool on)
		{
			InteractionCursor instance = Singleton<InteractionCursor>.Instance;
			if (!((Object)(object)instance == (Object)null) && on != forcedPointer)
			{
				if (on)
				{
					instance.ForceCursorType((CursorType)10);
				}
				else
				{
					instance.ClearForcedCursorType();
				}
				forcedPointer = on;
			}
		}

		private bool Over(Rect r)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			if (((Rect)(ref r)).Contains(Event.current.mousePosition))
			{
				if (clipView.HasValue)
				{
					Rect value = clipView.Value;
					return ((Rect)(ref value)).Contains(outerMouse);
				}
				return true;
			}
			return false;
		}

		private bool Hover(Rect r, string id)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Invalid comparison between Unknown and I4
			if (!Over(r))
			{
				return false;
			}
			if ((int)Event.current.type == 7)
			{
				hoverKey = id;
			}
			return true;
		}

		private static string PosKey(Rect r)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			Vector2 val = GUIUtility.GUIToScreenPoint(((Rect)(ref r)).position);
			return (int)val.x + "," + (int)val.y;
		}

		private bool BlinkOn(string id)
		{
			if (id == lastHoverKey)
			{
				return (int)((Time.unscaledTime - hoverSince) / blinkFrequency) % 2 == 0;
			}
			return false;
		}

		private void InitCursor()
		{
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			if (cursorTried)
			{
				return;
			}
			cursorTried = true;
			try
			{
				Traverse val = Traverse.Create((object)Singleton<InteractionCursor>.Instance);
				cursorSprites = val.Field("cursorTextures").GetValue<List<Sprite>>();
				cursorDownSprites = val.Field("cursorDownTextures").GetValue<List<Sprite>>();
				SpriteRenderer value = val.Field("mainCursor").GetValue<SpriteRenderer>();
				Camera value2 = val.Field("rayCamera").GetValue<Camera>();
				CursorTrailEffect value3 = val.Field("trailEffect").GetValue<CursorTrailEffect>();
				if ((Object)(object)value3 != (Object)null)
				{
					if (((TimedBehaviour)value3).originalFrequency > 0f)
					{
						trailFrequency = ((TimedBehaviour)value3).originalFrequency;
					}
					trailBrightness = Traverse.Create((object)value3).Field("cloneBrightness").GetValue<float>();
				}
				AscensionMenuBlinkEffect val2 = ((IEnumerable<AscensionMenuBlinkEffect>)Resources.FindObjectsOfTypeAll<AscensionMenuBlinkEffect>()).FirstOrDefault((Func<AscensionMenuBlinkEffect, bool>)((AscensionMenuBlinkEffect b) => ((TimedBehaviour)b).originalFrequency > 0f));
				if ((Object)(object)val2 != (Object)null)
				{
					blinkFrequency = ((TimedBehaviour)val2).originalFrequency;
				}
				Sprite val3 = ((cursorSprites != null && cursorSprites.Count > 0) ? cursorSprites[0] : null);
				if ((Object)(object)val3 != (Object)null && (Object)(object)value != (Object)null && (Object)(object)value2 != (Object)null && value2.orthographic)
				{
					cursorScale = ((Component)value).transform.lossyScale.x * (float)Screen.height / (2f * value2.orthographicSize * val3.pixelsPerUnit);
				}
				if (cursorScale <= 0.5f || cursorScale > 20f)
				{
					cursorScale = Mathf.Max(1f, Mathf.Round((float)Screen.height / 360f));
				}
				cursorReady = (Object)(object)val3 != (Object)null;
				Plugin.Log.LogInfo((object)string.Format("Game cursor: {0}, scale {1:0.##}, trail {2:0.###}s, blink {3:0.###}s", cursorReady ? "ok" : "not found", cursorScale, trailFrequency, blinkFrequency));
			}
			catch (Exception ex)
			{
				cursorReady = false;
				Plugin.Log.LogWarning((object)("Game cursor unavailable, using the system cursor: " + ex.Message));
			}
		}

		private Sprite CurrentCursorSprite()
		{
			int num = Mathf.Min(cursorSprites.Count - 1, (lastHoverKey != null) ? 10 : 0);
			return ((Input.GetMouseButton(0) && cursorDownSprites != null && cursorDownSprites.Count > num) ? cursorDownSprites : cursorSprites)[num];
		}

		private void DrawSprite(Sprite sp, Vector2 mouse, Color color)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: 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_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			Texture2D texture = sp.texture;
			Rect textureRect = sp.textureRect;
			Rect val = new Rect(mouse.x - sp.pivot.x * cursorScale, mouse.y - (((Rect)(ref textureRect)).height - sp.pivot.y) * cursorScale, ((Rect)(ref textureRect)).width * cursorScale, ((Rect)(ref textureRect)).height * cursorScale);
			Color color2 = GUI.color;
			GUI.color = color;
			GUI.DrawTextureWithTexCoords(val, (Texture)(object)texture, new Rect(((Rect)(ref textureRect)).x / (float)((Texture)texture).width, ((Rect)(ref textureRect)).y / (float)((Texture)texture).height, ((Rect)(ref textureRect)).width / (float)((Texture)texture).width, ((Rect)(ref textureRect)).height / (float)((Texture)texture).height));
			GUI.color = color2;
		}

		private void DrawGameCursor()
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			if (!cursorReady)
			{
				return;
			}
			Matrix4x4 matrix = GUI.matrix;
			GUI.matrix = Matrix4x4.identity;
			float unscaledTime = Time.unscaledTime;
			for (int num = ghosts.Count - 1; num >= 0; num--)
			{
				if (unscaledTime - ghosts[num].Born > 0.115f)
				{
					ghosts.RemoveAt(num);
				}
			}
			foreach (Ghost ghost in ghosts)
			{
				float num2 = 0.5f * (1f - (unscaledTime - ghost.Born) / 0.115f);
				DrawSprite(ghost.Sprite, ghost.Pos, new Color(trailBrightness, trailBrightness, trailBrightness, num2));
			}
			Vector2 mouse = default(Vector2);
			((Vector2)(ref mouse))..ctor(Input.mousePosition.x, (float)Screen.height - Input.mousePosition.y);
			DrawSprite(CurrentCursorSprite(), mouse, Color.white);
			GUI.matrix = matrix;
		}

		private Rect R(float x, float y, float w, float h)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			return new Rect(x * u, y * u, w * u, h * u);
		}

		private int F(int size)
		{
			return Mathf.Max(8, Mathf.RoundToInt((float)size * u));
		}

		internal void Open()
		{
			Stopwatch stopwatch = Stopwatch.StartNew();
			((BaseUnityPlugin)Plugin.Instance).Config.Reload();
			RebuildPool();
			deck = (from n in Plugin.ParseDeck(Plugin.Deck.Value)
				select pool.Find((CardInfo c) => string.Equals(((Object)c).name, n, StringComparison.OrdinalIgnoreCase)) into c
				where (Object)(object)c != (Object)null
				select c).ToList();
			savedDecks = Plugin.LoadSavedDecks();
			Plugin.WriteCardList(pool);
			page = Page.Cards;
			open = true;
			Plugin.Log.LogInfo((object)$"Deck builder opened in {stopwatch.Elapsed.TotalMilliseconds:0.0} ms ({pool.Count} cards).");
			CommandLineTextDisplayer.PlayCommandLineClickSound();
			SetInteraction(disabled: true);
		}

		private void RebuildPool()
		{
			starterNames = Plugin.StarterCardNames();
			CardFace.ClearCache();
			visibleCache = null;
			describeCache.Clear();
			savedCardsCache.Clear();
			searchCache.Clear();
			pool = DeckLogic.BuildPool(starterNames);
			filters = DeckLogic.Filters(pool);
			if (Array.IndexOf(filters, filter) < 0)
			{
				filter = "ALL";
			}
		}

		private void Close(bool save)
		{
			if (save)
			{
				DeckLogic.SaveDeck(deck);
				Plugin.Log.LogInfo((object)("Deck saved: " + Plugin.Deck.Value));
			}
			open = false;
			hovered = null;
			SetInteraction(disabled: false);
		}

		private void StartWithDeck()
		{
			Close(save: false);
			DeckLogic.StartWithDeck(deck);
		}

		private void SetInteraction(bool disabled)
		{
			InteractionCursor instance = Singleton<InteractionCursor>.Instance;
			if (!((Object)(object)instance == (Object)null))
			{
				instance.InteractionDisabled = disabled;
				SetGameCursorPointer(on: false);
				if (disabled)
				{
					InitCursor();
				}
				bool visible = (instance.OSCursorShown = disabled && !cursorReady);
				Cursor.visible = visible;
				ghosts.Clear();
				lastHoverKey = (hoverKey = null);
			}
		}

		private void Flash(string msg)
		{
			message = msg;
			messageUntil = Time.unscaledTime + 2.5f;
		}

		private void DrawPanel()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_039d: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0220: 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_0252: Unknown result type (might be due to invalid IL or missing references)
			//IL_0257: Unknown result type (might be due to invalid IL or missing references)
			//IL_0259: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_034a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0318: Unknown result type (might be due to invalid IL or missing references)
			//IL_0324: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_0426: Unknown result type (might be due to invalid IL or missing references)
			//IL_04dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_04bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0513: Unknown result type (might be due to invalid IL or missing references)
			//IL_051c: 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_0505: Unknown result type (might be due to invalid IL or missing references)
			//IL_0557: Unknown result type (might be due to invalid IL or missing references)
			//IL_057d: Unknown result type (might be due to invalid IL or missing references)
			float num = vw / u;
			GUI.DrawTexture(new Rect(0f, 0f, vw, vh), (Texture)(object)texBg);
			Dash(R(0f, 12f, num, 2f));
			if (IconButton(R(30f, 24f, 36f, 36f), texBack))
			{
				Close(save: false);
			}
			Label(R(0f, 22f, num, 40f), "BUILD YOUR DECK", 30, Red, (TextAnchor)4);
			if (FrameButton(R(num - 24f - 150f, 27f, 150f, 32f), (page == Page.Settings) ? "CARDS" : "SETTINGS", primary: false, 15))
			{
				page = ((page != Page.Settings) ? Page.Settings : Page.Cards);
			}
			Dash(R(0f, 70f, num, 2f));
			float num2 = 330f;
			float num3 = num - num2 - 72f;
			float num4 = 84f;
			float num5 = 24f;
			for (int i = 0; i < filters.Length; i++)
			{
				float num6 = Mathf.Max(60f, Measure(filters[i], 16) / u + 24f);
				if (TabButton(R(num5, num4, num6, 28f), filters[i], page == Page.Cards && filters[i] == filter))
				{
					filter = filters[i];
					page = Page.Cards;
				}
				num5 += num6 + 8f;
			}
			float num7 = num4 + 40f;
			if (page == Page.Cards)
			{
				float num8 = Measure("SEARCH", 15) / u + 10f;
				Label(R(24f, num7, num8, 28f), "SEARCH", 15, RedDim, (TextAnchor)3);
				Rect val = R(24f + num8 + 6f, num7, 240f, 28f);
				GUI.Box(val, GUIContent.none, frame);
				Rect inner;
				Matrix4x4 matrix = BeginText(new Rect(((Rect)(ref val)).x + 6f * u, ((Rect)(ref val)).y, ((Rect)(ref val)).width - 12f * u, ((Rect)(ref val)).height), 15, RedBright, (TextAnchor)3, out inner);
				search = GUI.TextField(inner, search, this.text);
				GUI.matrix = matrix;
				if (search.Length == 0)
				{
					Label(new Rect(((Rect)(ref val)).x + 8f * u, ((Rect)(ref val)).y, ((Rect)(ref val)).width - 16f * u, ((Rect)(ref val)).height), "NAME OR SIGIL", 15, RedDim, (TextAnchor)3);
				}
				if (FrameButton(R(24f + num3 - 200f, num7, 200f, 28f), "SORT: " + Sorts[sort], primary: false, 15))
				{
					sort = (sort + 1) % Sorts.Length;
				}
				num7 += 38f;
			}
			Rect val2 = R(24f, num7, num3, 0f);
			((Rect)(ref val2)).height = vh - ((Rect)(ref val2)).y - 92f * u;
			hovered = null;
			if (page == Page.Decks)
			{
				DrawSavedDecks(val2);
			}
			else if (page == Page.Settings)
			{
				DrawSettings(val2);
			}
			else
			{
				DrawGrid(val2);
			}
			Dash(new Rect(0f, vh - 84f * u, vw, 2f * u));
			Rect r = default(Rect);
			((Rect)(ref r))..ctor(24f * u, vh - 76f * u, (num3 + 24f) * u, 70f * u);
			this.text.wordWrap = true;
			if ((Object)(object)hovered != (Object)null)
			{
				if (!describeCache.TryGetValue(hovered, out var value))
				{
					value = (describeCache[hovered] = DeckLogic.Describe(hovered));
				}
				Label(r, value, 14, Red, (TextAnchor)0);
			}
			else if (page == Page.Decks)
			{
				Label(r, "SAVE YOUR DECK UNDER A NAME, OR SHARE IT: COPY CODE PUTS IT IN YOUR CLIPBOARD, PASTE CODE LOADS ONE.", 14, RedDim, (TextAnchor)0);
			}
			else if (page == Page.Settings)
			{
				Label(r, "CHANGES ARE SAVED RIGHT AWAY.", 14, RedDim, (TextAnchor)0);
			}
			else
			{
				Label(r, "CLICK A CARD TO ADD IT.  ESC OR X TO GO BACK.", 14, RedDim, (TextAnchor)0);
			}
			this.text.wordWrap = false;
			DrawDeckPanel(num, num2, 24f, num4);
			GUI.DrawTextureWithTexCoords(new Rect(0f, 0f, vw, vh), (Texture)(object)texScan, new Rect(0f, 0f, 1f, vh / 3f));
		}

		private void DrawGrid(Rect view)
		{
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: 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_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: Unknown result type (might be due to invalid IL or missing references)
			if (visibleCache == null || visibleFilter != filter || visibleSearch != search || visibleSort != sort)
			{
				visibleCache = DeckLogic.Sort(pool.Where((CardInfo c) => DeckLogic.Matches(c, filter, search, starterNames, searchCache)), Sorts[sort]).ToList();
				visibleFilter = filter;
				visibleSearch = search;
				visibleSort = sort;
			}
			List<CardInfo> list = visibleCache;
			float num = Mathf.Max(1f, Mathf.Floor(u));
			float num2 = 125f * num;
			float num3 = 190f * num;
			float num4 = 14f * u;
			int num5 = Mathf.Max(1, (int)((((Rect)(ref view)).width - 24f * u) / (num2 + num4)));
			int num6 = (list.Count + num5 - 1) / num5;
			float num7 = 6f * u + Mathf.Max(0f, ((Rect)(ref view)).width - 20f * u - 12f * u - ((float)num5 * (num2 + num4) - num4)) / 2f;
			Rect val = default(Rect);
			((Rect)(ref val))..ctor(0f, 0f, ((Rect)(ref view)).width - 20f * u, (float)num6 * (num3 + num4) + 10f * u);
			clipView = view;
			poolScroll = GUI.BeginScrollView(view, poolScroll, val, false, true);
			int num8 = Mathf.Max(0, Mathf.FloorToInt((poolScroll.y - 8f * u) / (num3 + num4)) - 1);
			int num9 = Mathf.CeilToInt((poolScroll.y + ((Rect)(ref view)).height) / (num3 + num4)) + 1;
			Rect r = default(Rect);
			for (int num10 = num8 * num5; num10 < list.Count && num10 / num5 <= num9; num10++)
			{
				((Rect)(ref r))..ctor(num7 + (float)(num10 % num5) * (num2 + num4), 8f * u + (float)(num10 / num5) * (num3 + num4), num2, num3);
				DrawTile(r, list[num10]);
			}
			GUI.EndScrollView();
			clipView = null;
		}

		private void DrawDeckPanel(float lw, float rightW, float pad, float y)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: 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_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: 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_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: 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_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: Unknown result type (might be due to invalid IL or missing references)
			//IL_028c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0291: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d8: 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_03b1: 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_02f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_04eb: 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_04fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_050a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0535: Unknown result type (might be due to invalid IL or missing references)
			//IL_053e: Unknown result type (might be due to invalid IL or missing references)
			//IL_051c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0527: Unknown result type (might be due to invalid IL or missing references)
			//IL_0576: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_0479: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0603: Unknown result type (might be due to invalid IL or missing references)
			//IL_064f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0685: Unknown result type (might be due to invalid IL or missing references)
			//IL_06bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_06c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_06c4: Unknown result type (might be due to invalid IL or missing references)
			float num = lw - rightW - pad;
			Rect val = R(num, y, rightW, 0f);
			((Rect)(ref val)).height = vh - ((Rect)(ref val)).y - 96f * u;
			GUI.Box(val, GUIContent.none, frame);
			Label(R(num + 14f, y + 8f, rightW - 28f, 28f), "YOUR DECK", 22, Red, (TextAnchor)3);
			int value = Plugin.MaxCards.Value;
			Label(R(num + 14f, y + 8f, rightW - 28f, 28f), (value > 0) ? $"{deck.Count}/{value}" : deck.Count.ToString(), 22, (value > 0 && deck.Count >= value) ? RedBright : RedDim, (TextAnchor)5);
			Dash(R(num + 14f, y + 42f, rightW - 28f, 2f));
			float num2 = 54f;
			Rect val2 = R(num + 8f, y + 52f, rightW - 16f, 0f);
			((Rect)(ref val2)).height = ((Rect)(ref val)).yMax - ((Rect)(ref val2)).y - 216f * u;
			Rect val3 = default(Rect);
			((Rect)(ref val3))..ctor(0f, 0f, ((Rect)(ref val2)).width - 20f * u, (float)deck.Count * num2 * u);
			clipView = val2;
			deckScroll = GUI.BeginScrollView(val2, deckScroll, val3, false, false);
			Rect val4 = default(Rect);
			for (int i = 0; i < deck.Count; i++)
			{
				CardInfo c = deck[i];
				((Rect)(ref val4))..ctor(0f, (float)i * num2 * u, ((Rect)(ref val2)).width - 20f * u, (num2 - 6f) * u);
				bool flag = Over(val4);
				if (flag)
				{
					GUI.Box(val4, GUIContent.none, frameHover);
				}
				Rect val5 = new Rect(((Rect)(ref val4)).x + 4f * u, ((Rect)(ref val4)).y + 2f * u, 55f * u, 45f * u);
				DrawPortraitBox(val5, c);
				GUI.Box(val5, GUIContent.none, frame);
				Label(new Rect(((Rect)(ref val4)).x + 68f * u, ((Rect)(ref val4)).y, 190f * u, ((Rect)(ref val4)).height), CardFace.Name(c), 15, flag ? RedBright : Red, (TextAnchor)3);
				if (IconButton(new Rect(((Rect)(ref val4)).xMax - 30f * u, ((Rect)(ref val4)).y + 6f * u, 26f * u, 26f * u), texBack))
				{
					deck.RemoveAt(i);
					break;
				}
			}
			GUI.EndScrollView();
			clipView = null;
			if (deck.Count == 0)
			{
				Label(R(num + 14f, y + 60f, rightW - 28f, 60f), "EMPTY.\nPICK CARDS ON THE LEFT.", 14, RedDim, (TextAnchor)0);
			}
			float num3 = ((Rect)(ref val)).yMax / u - 180f;
			if (deck.Count > 0)
			{
				int num4 = 0;
				int num5 = 0;
				int num6 = 0;
				int num7 = 0;
				foreach (CardInfo item in deck)
				{
					num4 += item.BloodCost;
					num5 += item.BonesCost;
					num6 += item.Attack;
					num7 += item.Health;
				}
				Label(R(num + 14f, num3 - 30f, rightW - 28f, 26f), $"{num4} BLOOD  {num5} BONES  {num6} ATK  {num7} HP", 15, RedDim, (TextAnchor)3);
			}
			string text = Plugin.Validate(deck);
			Rect r = R(num + 14f, num3, rightW - 28f, 30f);
			if (Time.unscaledTime < messageUntil)
			{
				Label(r, message.ToUpperInvariant(), 14, RedBright, (TextAnchor)3);
			}
			else if (text != null)
			{
				Label(r, text.ToUpperInvariant(), 14, RedDim, (TextAnchor)3);
			}
			else
			{
				Label(r, "DECK READY.", 14, Red, (TextAnchor)3);
			}
			float num8 = (rightW - 28f - 16f) / 3f;
			if (FrameButton(R(num + 14f, num3 + 36f, num8, 32f), "RANDOM", primary: false, 15))
			{
				Randomize();
			}
			if (FrameButton(R(num + 22f + num8, num3 + 36f, num8, 32f), (page == Page.Decks) ? "CARDS" : "DECKS", primary: false, 15))
			{
				page = ((page != Page.Decks) ? Page.Decks : Page.Cards);
			}
			if (FrameButton(R(num + 30f + num8 * 2f, num3 + 36f, num8, 32f), "CLEAR", primary: false, 15))
			{
				deck.Clear();
			}
			float num9 = (rightW - 28f - 8f) / 2f;
			if (FrameButton(R(num + 14f, num3 + 74f, num9, 32f), "CANCEL", primary: false, 15))
			{
				Close(save: false);
			}
			if (FrameButton(R(num + 22f + num9, num3 + 74f, num9, 32f), "SAVE", primary: false, 15))
			{
				Close(save: true);
			}
			Rect r2 = R(num + 14f, num3 + 116f, rightW - 28f, 44f);
			if (FrameButton(r2, "START WITH THIS DECK", primary: true, 17))
			{
				if (text != null)
				{
					Flash("Invalid deck: " + text);
				}
				else
				{
					StartWithDeck();
				}
			}
		}

		private void Randomize()
		{
			List<CardInfo> list = DeckLogic.RandomDeck(pool, rng);
			if (list == null)
			{
				Flash("Not enough unlocked cards to randomize.");
				return;
			}
			deck = list;
			page = Page.Cards;
		}

		private void DrawSavedDecks(Rect view)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: 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_00d8: 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_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_022b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02be: Unknown result type (might be due to invalid IL or missing references)
			//IL_035f: Unknown result type (might be due to invalid IL or missing references)
			//IL_036b: Unknown result type (might be due to invalid IL or missing references)
			//IL_036d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0372: Unknown result type (might be due to invalid IL or missing references)
			//IL_0376: Unknown result type (might be due to invalid IL or missing references)
			//IL_037b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0304: Unknown result type (might be due to invalid IL or missing references)
			//IL_0310: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_040e: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_042c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0425: Unknown result type (might be due to invalid IL or missing references)
			//IL_05aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_052a: Unknown result type (might be due to invalid IL or missing references)
			//IL_050f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0519: Unknown result type (might be due to invalid IL or missing references)
			//IL_060e: Unknown result type (might be due to invalid IL or missing references)
			Rect r = default(Rect);
			((Rect)(ref r))..ctor(((Rect)(ref view)).x, ((Rect)(ref view)).y, 70f * u, 30f * u);
			Label(r, "NAME", 15, RedDim, (TextAnchor)3);
			Rect val = default(Rect);
			((Rect)(ref val))..ctor(((Rect)(ref view)).x + 72f * u, ((Rect)(ref view)).y, 260f * u, 30f * u);
			GUI.Box(val, GUIContent.none, frame);
			Rect inner;
			Matrix4x4 matrix = BeginText(new Rect(((Rect)(ref val)).x + 6f * u, ((Rect)(ref val)).y, ((Rect)(ref val)).width - 12f * u, ((Rect)(ref val)).height), 15, RedBright, (TextAnchor)3, out inner);
			deckName = GUI.TextField(inner, deckName, 24, text);
			GUI.matrix = matrix;
			if (FrameButton(new Rect(((Rect)(ref val)).xMax + 10f * u, ((Rect)(ref view)).y, 200f * u, 30f * u), "SAVE CURRENT DECK", primary: false, 15))
			{
				SaveCurrentAs();
			}
			Label(new Rect(((Rect)(ref view)).x, ((Rect)(ref view)).y + 38f * u, 70f * u, 30f * u), "SHARE", 15, RedDim, (TextAnchor)3);
			if (FrameButton(new Rect(((Rect)(ref view)).x + 72f * u, ((Rect)(ref view)).y + 38f * u, 160f * u, 30f * u), "COPY CODE", primary: false, 15))
			{
				CopyCode();
			}
			if (FrameButton(new Rect(((Rect)(ref view)).x + 242f * u, ((Rect)(ref view)).y + 38f * u, 160f * u, 30f * u), "PASTE CODE", primary: false, 15))
			{
				PasteCode();
			}
			Rect val2 = default(Rect);
			((Rect)(ref val2))..ctor(((Rect)(ref view)).x, ((Rect)(ref view)).y + 84f * u, ((Rect)(ref view)).width, ((Rect)(ref view)).height - 84f * u);
			Dash(new Rect(((Rect)(ref val2)).x, ((Rect)(ref val2)).y - 6f * u, ((Rect)(ref val2)).width - 20f * u, 2f * u));
			if (savedDecks.Count == 0)
			{
				Label(new Rect(((Rect)(ref val2)).x, ((Rect)(ref val2)).y + 10f * u, ((Rect)(ref val2)).width, 30f * u), "NO SAVED DECKS YET.", 15, RedDim, (TextAnchor)3);
				return;
			}
			float num = 64f * u;
			Rect val3 = default(Rect);
			((Rect)(ref val3))..ctor(0f, 0f, ((Rect)(ref val2)).width - 20f * u, (float)savedDecks.Count * num);
			clipView = val2;
			savedScroll = GUI.BeginScrollView(val2, savedScroll, val3, false, true);
			Rect val4 = default(Rect);
			Rect val5 = default(Rect);
			for (int i = 0; i < savedDecks.Count; i++)
			{
				KeyValuePair<string, string> d = savedDecks[i];
				((Rect)(ref val4))..ctor(0f, (float)i * num, ((Rect)(ref val3)).width, num - 8f * u);
				bool flag = Over(val4);
				if (flag)
				{
					GUI.Box(val4, GUIContent.none, frameHover);
				}
				Label(new Rect(((Rect)(ref val4)).x + 8f * u, ((Rect)(ref val4)).y, 220f * u, ((Rect)(ref val4)).height), d.Key.ToUpperInvariant(), 16, flag ? RedBright : Red, (TextAnchor)3);
				if (!savedCardsCache.TryGetValue(d.Value, out var value))
				{
					value = (savedCardsCache[d.Value] = (from n in Plugin.ParseDeck(d.Value)
						select pool.Find((CardInfo c) => string.Equals(((Object)c).name, n, StringComparison.OrdinalIgnoreCase))).ToList());
				}
				float num2 = ((Rect)(ref val4)).x + 236f * u;
				foreach (CardInfo item in value)
				{
					((Rect)(ref val5))..ctor(num2, ((Rect)(ref val4)).y + 4f * u, 59f * u, 48f * u);
					if (((Rect)(ref val5)).xMax > ((Rect)(ref val4)).xMax - 170f * u)
					{
						break;
					}
					if ((Object)(object)item != (Object)null)
					{
						DrawPortraitBox(val5, item);
						if (Over(val5))
						{
							hovered = item;
						}
					}
					GUI.Box(val5, GUIContent.none, frame);
					num2 += 65f * u;
				}
				if (FrameButton(new Rect(((Rect)(ref val4)).xMax - 160f * u, ((Rect)(ref val4)).y + 12f * u, 100f * u, 32f * u), "LOAD", primary: false, 15))
				{
					LoadSaved(d, value);
					break;
				}
				if (IconButton(new Rect(((Rect)(ref val4)).xMax - 44f * u, ((Rect)(ref val4)).y + 14f * u, 28f * u, 28f * u), texBack))
				{
					savedDecks.RemoveAt(i);
					Plugin.WriteSavedDecks(savedDecks);
					Flash("Deleted '" + d.Key + "'.");
					break;
				}
			}
			GUI.EndScrollView();
			clipView = null;
		}

		private void SaveCurrentAs()
		{
			string name = deckName.Replace("|", "").Replace("\n", " ").Trim();
			if (name.Length == 0)
			{
				Flash("Type a name first.");
				return;
			}
			if (deck.Count == 0)
			{
				Flash("Deck is empty.");
				return;
			}
			KeyValuePair<string, string> keyValuePair = new KeyValuePair<string, string>(name, string.Join(", ", deck.Select((CardInfo c) => ((Object)c).name).ToArray()));
			int num = savedDecks.FindIndex((KeyValuePair<string, string> d) => string.Equals(d.Key, name, StringComparison.OrdinalIgnoreCase));
			if (num >= 0)
			{
				savedDecks[num] = keyValuePair;
			}
			else
			{
				savedDecks.Add(keyValuePair);
			}
			Plugin.WriteSavedDecks(savedDecks);
			Flash((num >= 0) ? ("Updated '" + name + "'.") : ("Saved '" + name + "'."));
		}

		private void LoadSaved(KeyValuePair<string, string> d, List<CardInfo> cards)
		{
			deck = cards.Where((CardInfo c) => (Object)(object)c != (Object)null).ToList();
			deckName = d.Key;
			int num = cards.Count((CardInfo c) => (Object)(object)c == (Object)null);
			Flash((num > 0) ? $"Loaded '{d.Key}' ({num} locked or missing card(s) skipped)." : ("Loaded '" + d.Key + "'."));
			page = Page.Cards;
		}

		private void CopyCode()
		{
			if (deck.Count == 0)
			{
				Flash("Deck is empty.");
				return;
			}
			GUIUtility.systemCopyBuffer = Plugin.DeckCode(deck);
			Flash("Deck code copied to the clipboard.");
		}

		private void PasteCode()
		{
			List<string> list = Plugin.ParseDeckCode(GUIUtility.systemCopyBuffer);
			if (list == null)
			{
				Flash("No deck code in the clipboard.");
				return;
			}
			List<CardInfo> source = list.Select((string n) => pool.Find((CardInfo c) => string.Equals(((Object)c).name, n, StringComparison.OrdinalIgnoreCase))).ToList();
			deck = source.Where((CardInfo c) => (Object)(object)c != (Object)null).ToList();
			int num = source.Count((CardInfo c) => (Object)(object)c == (Object)null);
			Flash((num > 0) ? $"Deck loaded ({num} locked or missing card(s) skipped)." : "Deck loaded from the code.");
			page = Page.Cards;
		}

		private void DrawSettings(Rect v)
		{
			float y = ((Rect)(ref v)).y + 4f * u;
			if (Stepper(((Rect)(ref v)).x, ref y, "MAX CARDS IN DECK", "HOW MANY CARDS YOU CAN PICK. 0 = NO LIMIT.", Plugin.MaxCards.Value, out var result))
			{
				SetRule(Plugin.MaxCards, result, rebuild: false);
			}
			if (Stepper(((Rect)(ref v)).x, ref y, "MAX COPIES OF A CARD", "HOW MANY OF THE SAME CARD YOU CAN PICK. 0 = NO LIMIT.", Plugin.MaxCopies.Value, out var result2))
			{
				SetRule(Plugin.MaxCopies, result2, rebuild: false);
			}
			if (Toggle(((Rect)(ref v)).x, ref y, "ONLY UNLOCKED CARDS", "ONLY CARDS YOU HAVE UNLOCKED IN KAYCEE'S MOD.", Plugin.OnlyUnlocked.Value))
			{
				SetRule(Plugin.OnlyUnlocked, !Plugin.OnlyUnlocked.Value, rebuild: true);
			}
			if (Toggle(((Rect)(ref v)).x, ref y, "BOSS AND SPECIAL CARDS", "BOSS CARDS, TERRAIN AND OTHER CARDS YOU CAN'T NORMALLY DRAFT.", Plugin.AllowSpecial.Value))
			{
				SetRule(Plugin.AllowSpecial, !Plugin.AllowSpecial.Value, rebuild: true);
			}
		}

		private void SetRule<T>(ConfigEntry<T> entry, T value, bool rebuild)
		{
			entry.Value = value;
			((BaseUnityPlugin)Plugin.Instance).Config.Save();
			if (rebuild)
			{
				RebuildPool();
				int count = deck.Count;
				deck = deck.Where(pool.Contains).ToList();
				if (deck.Count < count)
				{
					Flash($"Removed {count - deck.Count} card(s) that are no longer allowed.");
				}
			}
		}

		private bool Stepper(float x, ref float y, string label, string hint, int value, out int result)
		{
			//IL_003c: 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_00d4: Unknown result type (might be due to invalid IL or missing references)
			SettingLabel(x, y, label, hint);
			float num = x + 360f * u;
			result = value;
			if (FrameButton(new Rect(num, y, 34f * u, 34f * u), "-", primary: false, 24))
			{
				result = Mathf.Max(0, value - 1);
			}
			Label(new Rect(num + 40f * u, y, 130f * u, 34f * u), (value > 0) ? value.ToString() : "NO LIMIT", 16, RedBright, (TextAnchor)4);
			if (FrameButton(new Rect(num + 176f * u, y, 34f * u, 34f * u), "+", primary: false, 24))
			{
				result = Mathf.Min(99, value + 1);
			}
			y += 76f * u;
			return result != value;
		}

		private bool Toggle(float x, ref float y, string label, string hint, bool value)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			SettingLabel(x, y, label, hint);
			bool result = FrameButton(new Rect(x + 360f * u, y, 210f * u, 34f * u), value ? "[X] ON" : "[ ] OFF", primary: false, 16);
			y += 76f * u;
			return result;
		}

		private void SettingLabel(float x, float y, string label, string hint)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			Label(new Rect(x, y, 350f * u, 34f * u), label, 17, Red, (TextAnchor)3);
			Label(new Rect(x, y + 36f * u, 800f * u, 26f * u), hint, 15, RedDim, (TextAnchor)3);
		}

		private void DrawTile(Rect r, CardInfo c)
		{
			//IL_000e: 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_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: 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_01a7: 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_007c: 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)
			bool flag = Hover(r, "card:" + ((Object)c).name);
			if (flag)
			{
				hovered = c;
			}
			int num = deck.Count((CardInfo d) => ((Object)d).name == ((Object)c).name);
			if (GUI.Button(r, GUIContent.none, GUIStyle.none))
			{
				TryAdd(c);
			}
			if (CardFace.Available)
			{
				Rect r2 = (Rect)(flag ? new Rect(((Rect)(ref r)).x - 3f * u, ((Rect)(ref r)).y - 5f * u, ((Rect)(ref r)).width + 6f * u, ((Rect)(ref r)).height + 9f * u) : r);
				try
				{
					CardFace.Draw(r2, c);
				}
				catch (Exception e)
				{
					CardFace.Report(c, "card face", e);
					GUI.Box(r, GUIContent.none, frame);
				}
			}
			else
			{
				GUI.Box(r, GUIContent.none, frame);
				DrawPortrait(new Rect(((Rect)(ref r)).x + 8f, ((Rect)(ref r)).y + 8f, ((Rect)(ref r)).width - 16f, ((Rect)(ref r)).height * 0.5f), c);
				Label(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).y + ((Rect)(ref r)).height * 0.55f, ((Rect)(ref r)).width, 30f * u), CardFace.Name(c), 13, Red, (TextAnchor)4);
			}
			if (num > 0)
			{
				float num2 = ((Rect)(ref r)).width / 125f;
				Rect val = default(Rect);
				((Rect)(ref val))..ctor(((Rect)(ref r)).x + 5f * num2, ((Rect)(ref r)).y + 32f * num2, 32f * u, 24f * u);
				GUI.DrawTexture(val, (Texture)(object)texRed);
				Label(val, "x" + num, 15, Bg, (TextAnchor)4);
			}
		}

		private void TryAdd(CardInfo c)
		{
			string text = DeckLogic.CannotAdd(deck, c);
			if (text != null)
			{
				Flash(text);
				return;
			}
			deck.Add(c);
			CommandLineTextDisplayer.PlayCommandLineClickSound();
		}

		private int TextScale(int size)
		{
			if ((Object)(object)pixelFont == (Object)null || pixelFont.dynamic)
			{
				return 1;
			}
			int num = ((pixelFont.lineHeight > 0) ? pixelFont.lineHeight : 10);
			return Mathf.Max(1, Mathf.RoundToInt((float)F(size) / (float)num));
		}

		private Matrix4x4 BeginText(Rect r, int size, Color color, TextAnchor anchor, out Rect inner)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: 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_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			Matrix4x4 matrix = GUI.matrix;
			int num = TextScale(size);
			text.fontSize = ((num == 1) ? F(size) : 0);
			text.normal.textColor = color;
			text.alignment = anchor;
			inner = r;
			if (num > 1)
			{
				GUIUtility.ScaleAroundPivot(new Vector2((float)num, (float)num), ((Rect)(ref r)).position);
				inner = new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).y, ((Rect)(ref r)).width / (float)num, ((Rect)(ref r)).height / (float)num);
			}
			return matrix;
		}

		private void Label(Rect r, string s, int size, Color color, TextAnchor anchor)
		{
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: 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_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Invalid comparison between Unknown and I4
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Invalid comparison between Unknown and I4
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: 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_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Invalid comparison between Unknown and I4
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: 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_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Invalid comparison between Unknown and I4
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Invalid comparison between Unknown and I4
			if (clipView.HasValue)
			{
				float num = (float)F(size) * 1.2f * (float)(s.Count((char ch) => ch == '\n') + 1);
				float num2 = ((Rect)(ref r)).y;
				float num3 = ((Rect)(ref r)).yMax;
				if ((int)anchor == 3 || (int)anchor == 4 || (int)anchor == 5)
				{
					num2 = ((Rect)(ref r)).center.y - num / 2f;
					num3 = ((Rect)(ref r)).center.y + num / 2f;
				}
				else if ((int)anchor == 0 || (int)anchor == 1 || (int)anchor == 2)
				{
					num3 = Mathf.Min(((Rect)(ref r)).yMax, ((Rect)(ref r)).y + num);
				}
				float num4 = GUIUtility.GUIToScreenPoint(new Vector2(((Rect)(ref r)).x, num2)).y / guiScale;
				float num5 = GUIUtility.GUIToScreenPoint(new Vector2(((Rect)(ref r)).x, num3)).y / guiScale;
				Rect value = clipView.Value;
				if (num4 < ((Rect)(ref value)).y - 1f)
				{
					return;
				}
				value = clipView.Value;
				if (num5 > ((Rect)(ref value)).yMax + 1f)
				{
					return;
				}
			}
			Rect inner;
			Matrix4x4 matrix = BeginText(r, size, color, anchor, out inner);
			GUI.Label(inner, s, text);
			GUI.matrix = matrix;
		}

		private float Measure(string s, int size)
		{
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Expected O, but got Unknown
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			if (measureU != u)
			{
				measureCache.Clear();
				measureU = u;
			}
			string key = size + ":" + s;
			if (measureCache.TryGetValue(key, out var value))
			{
				return value;
			}
			int num = TextScale(size);
			text.fontSize = ((num == 1) ? F(size) : 0);
			return measureCache[key] = text.CalcSize(new GUIContent(s)).x * (float)num;
		}

		private void Dash(Rect r)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			GUI.DrawTextureWithTexCoords(r, (Texture)(object)texDash, new Rect(0f, 0f, ((Rect)(ref r)).width / (8f * u), 1f));
		}

		private bool FrameButton(Rect r, string label, bool primary, int size)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: 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)
			string id = "btn:" + label + PosKey(r);
			bool flag = Hover(r, id);
			bool flag2 = flag && BlinkOn(id);
			GUIStyle val = ((!primary) ? (flag2 ? frameFilledHover : (flag ? frameHover : frame)) : (flag2 ? frameFilledHover : frameFilled));
			bool num = GUI.Button(r, GUIContent.none, val);
			Label(r, label, size, (primary || flag2) ? Bg : (flag ? RedBright : Red), (TextAnchor)4);
			if (primary && (Object)(object)texContinue != (Object)null)
			{
				Color color = GUI.color;
				GUI.color = Bg;
				GUI.DrawTexture(new Rect(((Rect)(ref r)).xMax - ((Rect)(ref r)).height * 0.8f, ((Rect)(ref r)).y + ((Rect)(ref r)).height * 0.2f, ((Rect)(ref r)).height * 0.6f, ((Rect)(ref r)).height * 0.6f), texContinue);
				GUI.color = color;
			}
			if (num)
			{
				CommandLineTextDisplayer.PlayCommandLineClickSound();
			}
			return num;
		}

		private bool TabButton(Rect r, string label, bool active)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: 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_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			string id = "tab:" + label;
			bool flag = Hover(r, id);
			bool flag2 = flag && !active && BlinkOn(id);
			if (active || flag2)
			{
				GUI.DrawTexture(r, (Texture)(object)(flag2 ? texRedBright : texRed));
			}
			bool num = GUI.Button(r, GUIContent.none, (active || flag2) ? GUIStyle.none : (flag ? frameHover : GUIStyle.none));
			Label(r, label, 16, (active || flag2) ? Bg : (flag ? RedBright : Red), (TextAnchor)4);
			if (num)
			{
				CommandLineTextDisplayer.PlayCommandLineClickSound();
			}
			return num;
		}

		private bool IconButton(Rect r, Texture icon)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			string id = "icon:" + PosKey(r);
			bool flag = Hover(r, id);
			bool num = GUI.Button(r, GUIContent.none, GUIStyle.none);
			Color color = GUI.color;
			GUI.color = ((flag && BlinkOn(id)) ? Color.white : (flag ? RedBright : Red));
			if ((Object)(object)icon != (Object)null)
			{
				GUI.DrawTexture(r, icon);
			}
			else
			{
				Label(r, "X", 20, GUI.color, (TextAnchor)4);
			}
			GUI.color = color;
			if (num)
			{
				CommandLineTextDisplayer.PlayCommandLineClickSound();
			}
			return num;
		}

		private static void DrawPortraitBox(Rect r, CardInfo c)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				CardFace.DrawPortraitBox(r, c);
			}
			catch (Exception e)
			{
				CardFace.Report(c, "portrait", e);
			}
		}

		private static void DrawPortrait(Rect r, CardInfo c)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: 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_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			Sprite val = (((Object)(object)c.portraitTex != (Object)null) ? c.portraitTex : c.pixelPortrait);
			if (!((Object)(object)val == (Object)null) && !((Object)(object)val.texture == (Object)null))
			{
				Rect textureRect = val.textureRect;
				Texture2D texture = val.texture;
				GUI.DrawTextureWithTexCoords(Fit(r, ((Rect)(ref textureRect)).width / ((Rect)(ref textureRect)).height), (Texture)(object)texture, new Rect(((Rect)(ref textureRect)).x / (float)((Texture)texture).width, ((Rect)(ref textureRect)).y / (float)((Texture)texture).height, ((Rect)(ref textureRect)).width / (float)((Texture)texture).width, ((Rect)(ref textureRect)).height / (float)((Texture)texture).height));
			}
		}

		private static Rect Fit(Rect r, float aspect)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: 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)
			Rect result = r;
			if (((Rect)(ref r)).width / ((Rect)(ref r)).height > aspect)
			{
				((Rect)(ref result)).width = ((Rect)(ref r)).height * aspect;
				((Rect)(ref result)).x = ((Rect)(ref result)).x + (((Rect)(ref r)).width - ((Rect)(ref result)).width) / 2f;
			}
			else
			{
				((Rect)(ref result)).height = ((Rect)(ref r)).width / aspect;
				((Rect)(ref result)).y = ((Rect)(ref result)).y + (((Rect)(ref r)).height - ((Rect)(ref result)).height) / 2f;
			}
			return result;
		}

		private static Texture2D Tex(int w, int h, Func<int, int, Color> px, TextureWrapMode wrap = (TextureWrapMode)1)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(w, h, (TextureFormat)4, false)
			{
				filterMode = (FilterMode)0,
				wrapMode = wrap,
				hideFlags = (HideFlags)61
			};
			for (int i = 0; i < w; i++)
			{
				for (int j = 0; j < h; j++)
				{
					val.SetPixel(i, j, px(i, j));
				}
			}
			val.Apply();
			return val;
		}

		private static Texture2D FrameTex(Color border, Color fill)
		{
			//IL_0007: 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)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			return Tex(3, 3, (int x, int y) => (x != 1 || y != 1) ? border : fill, (TextureWrapMode)1);
		}

		private static GUIStyle FrameStyle(Texture2D t)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			//IL_0021: Expected O, but got Unknown
			GUIStyle val = new GUIStyle();
			val.normal.background = t;
			val.border = new RectOffset(1, 1, 1, 1);
			return val;
		}

		private static Font FindPixelFont()
		{
			try
			{
				PixelText[] componentsInChildren = ((Component)Menu).GetComponentsInChildren<PixelText>(true);
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					Font value = Traverse.Create((object)componentsInChildren[i]).Field("defaultFont").GetValue<Font>();
					if ((Object)(object)value != (Object)null)
					{
						return value;
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Pixel font lookup failed: " + ex.Message));
			}
			return Resources.Load<Font>("fonts/pixel art fonts/marksman crisp/marksman (crisp)");
		}

		private void InitStyles()
		{
			//IL_0038: 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_00fe: 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_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_0299: Unknown result type (might be due to invalid IL or missing references)
			//IL_029e: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02db: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ea: Expected O, but got Unknown
			//IL_02ef: Expected O, but got Unknown
			//IL_02f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fa: 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_031b: Expected O, but got Unknown
			//IL_0346: Unknown result type (might be due to invalid IL or missing references)
			//IL_037e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0389: Unknown result type (might be due to invalid IL or missing references)
			//IL_038e: Unknown result type (might be due to invalid IL or missing references)
			//IL_039a: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a1: 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_03b4: Expected O, but got Unknown
			if (!((Object)(object)skin != (Object)null) || !((Object)(object)texBg != (Object)null))
			{
				Color clear = new Color(0f, 0f, 0f, 0f);
				texBg = Tex(1, 1, (int x, int y) => Bg, (TextureWrapMode)1);
				texRed = Tex(1, 1, (int x, int y) => Red, (TextureWrapMode)1);
				texRedBright = Tex(1, 1, (int x, int y) => RedBright, (TextureWrapMode)1);
				texDash = Tex(8, 1, (int x, int y) => (x >= 5) ? clear : Red, (TextureWrapMode)0);
				texScan = Tex(1, 3, (int x, int y) => (Color)((y != 0) ? clear : new Color(0f, 0f, 0f, 0.22f)), (TextureWrapMode)0);
				texFrame = FrameTex(Red, clear);
				texFrameHover = FrameTex(RedBright, new Color(Red.r, Red.g, Red.b, 0.15f));
				texFrameFilled = FrameTex(Red, Red);
				texFrameFilledHover = FrameTex(RedBright, RedBright);
				frame = FrameStyle(texFrame);
				frameHover = FrameStyle(texFrameHover);
				frameFilled = FrameStyle(texFrameFilled);
				frameFilledHover = FrameStyle(texFrameFilledHover);
				texBack = Resources.Load<Texture>("art/ui/ascension/ascensionmenu_back");
				texContinue = Resources.Load<Texture>("art/ui/ascension/ascensionmenu_continue");
				pixelFont = FindPixelFont();
				Plugin.Log.LogInfo((object)("Menu font: " + (((Object)(object)pixelFont != (Object)null) ? $"{((Object)pixelFont).name} (dynamic={pixelFont.dynamic}, size={pixelFont.fontSize}, lineHeight={pixelFont.lineHeight})" : "default")));
				skin = Object.Instantiate<GUISkin>(GUI.skin);
				if ((Object)(object)pixelFont != (Object)null)
				{
					skin.font = pixelFont;
				}
				GUISkin obj = skin;
				GUIStyle val = new GUIStyle();
				val.normal.background = Tex(1, 1, (int x, int y) => new Color(Red.r, Red.g, Red.b, 0.15f), (TextureWrapMode)1);
				val.fixedWidth = 8f;
				val.margin = new RectOffset(6, 0, 0, 0);
				obj.verticalScrollbar = val;
				GUISkin obj2 = skin;
				GUIStyle val2 = new GUIStyle();
				val2.normal.background = texRed;
				val2.fixedWidth = 8f;
				obj2.verticalScrollbarThumb = val2;
				skin.verticalScrollbarUpButton = GUIStyle.none;
				skin.verticalScrollbarDownButton = GUIStyle.none;
				skin.settings.cursorColor = Red;
				skin.settings.selectionColor = new Color(Red.r, Red.g, Red.b, 0.4f);
				text = new GUIStyle
				{
					font = pixelFont,
					richText = false,
					wordWrap = false,
					clipping = (TextClipping)1
				};
			}
		}
	}
	[HarmonyPatch(typeof(AscensionChooseStarterDeckScreen), "Start")]
	internal static class OpenButtonPatch
	{
		internal static bool Added;

		private static void Postfix(AscensionChooseStarterDeckScreen __instance)
		{
			//IL_005e: 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_00c9: 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_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: 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)
			try
			{
				GameObject obj = Object.Instantiate<GameObject>(((Component)Traverse.Create((object)Singleton<AscensionMenuScreens>.Instance).Field("unlockSummaryScreen").GetValue<GameObject>()
					.transform.Find("Stats/ScreenAnchor").GetChild(0)).gameObject, ((Component)__instance).transform);
				((Object)obj).name = "KCM_BuildDeckButton";
				obj.transform.localPosition = new Vector3(0f, 0.82f, 0f);
				PixelText componentInChildren = obj.GetComponentInChildren<PixelText>(true);
				componentInChildren.SetText("- BUILD CUSTOM DECK -", false);
				Text componentInChildren2 = ((Component)componentInChildren).GetComponentInChildren<Text>(true);
				float num = (((Object)(object)componentInChildren2 != (Object)null) ? (componentInChildren2.preferredWidth * ((Component)componentInChildren).transform.localScale.x) : 1.3f) + 0.04f;
				BoxCollider2D component = obj.GetComponent<BoxCollider2D>();
				if ((Object)(object)component != (Object)null)
				{
					component.size = new Vector2(num, 0.1f);
					((Collider2D)component).offset = Vector2.zero;
				}
				Transform val = ((Component)componentInChildren).transform.Find("Text/Back");
				if ((Object)(object)val != (Object)null)
				{
					val.localScale = new Vector3(num / ((Component)componentInChildren).transform.localScale.x, val.localScale.y, 1f);
				}
				((MainInputInteractable)obj.GetComponent<AscensionMenuInteractable>()).CursorSelectStarted = delegate
				{
					if ((Object)(object)DeckBuilderUI.Instance != (Object)null)
					{
						DeckBuilderUI.Instance.Open();
					}
				};
				obj.SetActive(true);
				Added = true;
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("Could not add the BUILD CUSTOM DECK button, using the fallback one: " + ex));
			}
		}
	}
	[HarmonyPatch(typeof(AscensionMenuScreens), "Start")]
	internal static class MenuTrackPatch
	{
		private static void Postfix(AscensionMenuScreens __instance)
		{
			DeckBuilderUI.Menu = __instance;
		}
	}
	internal static class DeckLogic
	{
		internal static readonly string[] BaseFilters = new string[8] { "ALL", "PELTS", "BOSS", "OTHER", "BLOOD", "BONES", "FREE", "RARE" };

		internal static readonly string[] Sorts = new string[5] { "DEFAULT", "COST", "ATTACK", "HEALTH", "NAME" };

		internal static List<CardInfo> BuildPool(HashSet<string> starterNames)
		{
			return (from c in Plugin.CardPool()
				orderby (!Plugin.IsPelt(c)) ? ((!Plugin.IsModded(c)) ? ((!Plugin.IsBossCard(c) && !Plugin.IsOtherCard(c, starterNames)) ? ((c.BloodCost > 0) ? 1 : ((c.BonesCost <= 0) ? 3 : 2)) : 5) : 4) : 0, c.BloodCost + c.BonesCost
				select c).ThenBy(Plugin.DisplayName).ToList();
		}

		internal static string[] Filters(List<CardInfo> pool)
		{
			if (!pool.Exists(Plugin.IsModded))
			{
				return BaseFilters;
			}
			return BaseFilters.Concat(new string[1] { "MODDED" }).ToArray();
		}

		internal static bool Matches(CardInfo c, string filter, string search, HashSet<string> starterNames, Dictionary<CardInfo, string> searchCache)
		{
			search = search?.Trim() ?? "";
			if (search.Length > 0 && SearchText(c, searchCache).IndexOf(search, StringComparison.OrdinalIgnoreCase) < 0)
			{
				return false;
			}
			switch (filter)
			{
			case "PELTS":
				return Plugin.IsPelt(c);
			case "BOSS":
				return Plugin.IsBossCard(c);
			case "OTHER":
				if (Plugin.IsOtherCard(c, starterNames))
				{
					return !Plugin.IsModded(c);
				}
				return false;
			case "BLOOD":
				return c.BloodCost > 0;
			case "BONES":
				return c.BonesCost > 0;
			case "FREE":
				if (c.BloodCost == 0)
				{
					return c.BonesCost == 0;
				}
				return false;
			case "RARE":
				return Plugin.IsRare(c);
			case "MODDED":
				return Plugin.IsModded(c);
			default:
				return true;
			}
		}

		private static string SearchText(CardInfo c, Dictionary<CardInfo, string> cache)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			if (!cache.TryGetValue(c, out var value))
			{
				value = ((Object)c).name + "\n" + Plugin.DisplayName(c);
				try
				{
					foreach (Ability item in c.Abilities.Distinct())
					{
						value = value + "\n" + AbilityName(item);
					}
				}
				catch
				{
				}
				cache[c] = value;
			}
			return value;
		}

		internal static IEnumerable<CardInfo> Sort(IEnumerable<CardInfo> cards, string sort)
		{
			return sort switch
			{
				"COST" => from c in cards
					orderby c.BloodCost, c.BonesCost
					select c, 
				"ATTACK" => from c in cards
					orderby c.Attack descending, c.Health descending
					select c, 
				"HEALTH" => from c in cards
					orderby c.Health descending, c.Attack descending
					select c, 
				"NAME" => cards.OrderBy(Plugin.DisplayName), 
				_ => cards, 
			};
		}

		internal static List<CardInfo> RandomDeck(List<CardInfo> pool, Random rng)
		{
			List<CardInfo> list = pool.Where(Plugin.IsRegularChoice).ToList();
			List<CardInfo> list2 = list.Where((CardInfo val2) => val2.BloodCost == 1).ToList();
			if (list2.Count == 0 || list.Select((CardInfo val2) => ((Object)val2).name).Distinct().Count() < 3)
			{
				return null;
			}
			List<CardInfo> list3 = new List<CardInfo> { list2[rng.Next(list2.Count)] };
			while (list3.Count < 3)
			{
				CardInfo c = list[rng.Next(list.Count)];
				if (!list3.Exists((CardInfo p) => ((Object)p).name == ((Object)c).name))
				{
					list3.Add(c);
				}
			}
			list3 = list3.OrderBy((CardInfo _) => rng.Next()).ToList();
			CardInfo val = pool.Find((CardInfo val2) => ((Object)val2).name == "PeltHare");
			if ((Object)(object)val != (Object)null)
			{
				list3.Add(val);
				list3.Add(val);
			}
			return list3;
		}

		internal static string CannotAdd(List<CardInfo> deck, CardInfo c)
		{
			if (Plugin.MaxCards.Value > 0 && deck.Count + 1 > Plugin.MaxCards.Value)
			{
				return $"At most {Plugin.MaxCards.Value} cards.";
			}
			if (Plugin.MaxCopies.Value > 0 && deck.Count((CardInfo d) => ((Object)d).name == ((Object)c).name) + 1 > Plugin.MaxCopies.Value)
			{
				return $"At most {Plugin.MaxCopies.Value} copies of a card.";
			}
			return null;
		}

		internal static List<CardInfo> Resolve(IEnumerable<string> names, List<CardInfo> pool)
		{
			return names.Select((string n) => pool.Find((CardInfo c) => string.Equals(((Object)c).name, n, StringComparison.OrdinalIgnoreCase))).ToList();
		}

		internal static string Cost(CardInfo c)
		{
			if (c.BloodCost > 0)
			{
				return $"{c.BloodCost} blood";
			}
			if (c.BonesCost > 0)
			{
				return $"{c.BonesCost} bones";
			}
			return "free";
		}

		internal unsafe static string AbilityName(Ability a)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				return AbilitiesUtil.GetInfo(a)?.rulebookName ?? ((object)(*(Ability*)(&a))/*cast due to .constrained prefix*/).ToString();
			}
			catch
			{
				return ((object)(*(Ability*)(&a))/*cast due to .constrained prefix*/).ToString();
			}
		}

		internal static string Describe(CardInfo c)
		{
			//IL_00a6: 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_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			string text = Plugin.DisplayName(c);
			string text2;
			try
			{
				text2 = $"{text.ToUpperInvariant()} - {Cost(c)}, {c.Attack}/{c.Health}";
			}
			catch
			{
				text2 = text.ToUpperInvariant();
			}
			try
			{
				foreach (Ability ability in c.Abilities)
				{
					string text3;
					try
					{
						AbilityInfo info = AbilitiesUtil.GetInfo(ability);
						text3 = ((info != null) ? info.LocalizedRulebookDescription : null) ?? "";
					}
					catch
					{
						text3 = "";
					}
					text2 = text2 + "\n" + AbilityName(ability).ToUpperInvariant() + ": " + text3.Replace("[creature]", text);
				}
			}
			catch (Exception e)
			{
				CardFace.Report(c, "sigils", e);
			}
			return text2;
		}

		internal static void Totals(List<CardInfo> deck, out int blood, out int bones, out int atk, out int hp)
		{
			blood = (bones = (atk = (hp = 0)));
			foreach (CardInfo item in deck)
			{
				blood += item.BloodCost;
				bones += item.BonesCost;
				atk += item.Attack;
				hp += item.Health;
			}
		}

		internal static void SaveDeck(List<CardInfo> deck)
		{
			Plugin.Deck.Value = string.Join(", ", deck.Select((CardInfo c) => ((Object)c).name).ToArray());
			((BaseUnityPlugin)Plugin.Instance).Config.Save();
			Plugin.UpdateDeckInfo(deck);
		}

		internal static void StartWithDeck(List<CardInfo> deck)
		{
			SaveDeck(deck);
			AscensionSaveData.Data.currentStarterDeck = "emre.inscryption.kcmdeckbuilder_Custom";
			Plugin.Log.LogInfo((object)("Custom deck selected: " + Plugin.Deck.Value));
			Singleton<AscensionMenuScreens>.Instance.SwitchToScreen((Screen)1);
		}
	}
	[BepInPlugin("emre.inscryption.kcmdeckbuilder", "KCM Deck Builder", "2.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public const string Guid = "emre.inscryption.kcmdeckbuilder";

		public const string CustomDeckId = "emre.inscryption.kcmdeckbuilder_Custom";

		private const string SelectedKey = "CustomDeckSelected";

		internal static Plugin Instance;

		internal static ManualLogSource Log;

		internal static ConfigEntry<string> Deck;

		internal static ConfigEntry<int> MaxCards;

		internal static ConfigEntry<int> MaxCopies;

		internal static ConfigEntry<bool> OnlyUnlocked;

		internal static ConfigEntry<bool> AllowSpecial;

		private static ConfigEntry<bool> legacySelected;

		private static FullStarterDeck apiDeck;

		internal static string CardListPath;

		internal static string SavedDecksPath;

		private static readonly HashSet<string> BossCandidates = new HashSet<string>
		{
			"Shark", "BaitBucket", "Snapper", "Kingfisher", "SkeletonPirate", "SkeletonParrot", "Mule", "Bloodhound", "Grizzly", "Coyote",
			"GoldNugget", "TrapFrog", "Trap", "Urayuli", "Amalgam"
		};

		private static readonly HashSet<string> Excluded = new HashSet<string> { "CardMergeStones", "Ijiraq_UnlockScreen", "Stoat_Talking", "Wolf_Talking", "Stinkbug_Talking" };

		private static HashSet<string> baseGameNames;

		private const string CodePrefix = "KCM:";

		private static string lastCardList;

		internal static bool CustomSelected
		{
			get
			{
				ModdedSaveData saveData = ModdedSaveManager.SaveData;
				string text = ((saveData != null) ? saveData.GetValue("emre.inscryption.kcmdeckbuilder", "CustomDeckSelected") : null);
				if (text == null)
				{
					return legacySelected.Value;
				}
				return text == bool.TrueString;
			}
			set
			{
				ModdedSaveData saveData = ModdedSaveManager.SaveData;
				if (saveData != null)
				{
					saveData.SetValue("emre.inscryption.kcmdeckbuilder", "CustomDeckSelected", (object)value);
				}
			}
		}

		private void Awake()
		{
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			Stopwatch stopwatch = Stopwatch.StartNew();
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			Deck = ((BaseUnityPlugin)this).Config.Bind<string>("Deck", "Cards", "Stoat, Bullfrog, Wolf", "Comma-separated card IDs. Usually edited from the in-game builder; see BepInEx/config/KCMDeckBuilder_cards.txt for valid IDs.");
			MaxCards = ((BaseUnityPlugin)this).Config.Bind<int>("Rules", "MaxCards", 5, "Maximum number of chosen cards. 0 = no limit.");
			MaxCopies = ((BaseUnityPlugin)this).Config.Bind<int>("Rules", "MaxCopiesPerCard", 0, "Maximum copies of the same card. 0 = no limit.");
			OnlyUnlocked = ((BaseUnityPlugin)this).Config.Bind<bool>("Rules", "OnlyUnlockedCards", true, "Only allow cards you have unlocked.");
			AllowSpecial = ((BaseUnityPlugin)this).Config.Bind<bool>("Rules", "AllowBossAndSpecialCards", true, "Allow boss-only cards and other cards you can't normally draft (terrain, Dam, ...).");
			legacySelected = ((BaseUnityPlugin)this).Config.Bind<bool>("Internal", "CustomDeckSelected", false, "Only read when upgrading from 1.x. The choice is now kept in the API's ModdedSaveFile.gwsave.");
			CardListPath = Path.Combine(Paths.ConfigPath, "KCMDeckBuilder_cards.txt");
			SavedDecksPath = Path.Combine(Paths.ConfigPath, "KCMDeckBuilder_decks.txt");
			apiDeck = StarterDeckManager.New("emre.inscryption.kcmdeckbuilder", "Custom", "Custom Deck", LoadTexture("deck_icon.png"), ParseDeck(Deck.Value).ToArray(), 0);
			((Component)this).gameObject.AddComponent<DeckBuilderUI>();
			new Harmony("emre.inscryption.kcmdeckbuilder").PatchAll();
			Log.LogInfo((object)$"KCM Deck Builder loaded in {stopwatch.Elapsed.TotalMilliseconds:0.0} ms.");
		}

		internal static void UpdateDeckInfo(List<CardInfo> deck)
		{
			try
			{
				apiDeck.CardNames = deck.Select((CardInfo c) => ((Object)c).name).ToList();
				FullStarterDeck? obj = ((IEnumerable<FullStarterDeck>)StarterDeckManager.AllDecks).FirstOrDefault((Func<FullStarterDeck, bool>)((FullStarterDeck d) => ((Object)d.Info).name == "emre.inscryption.kcmdeckbuilder_Custom"));
				StarterDeckInfo val = ((obj != null) ? obj.Info : null);
				StarterDeckInfo info = StarterDecksUtil.GetInfo("emre.inscryption.kcmdeckbuilder_Custom");
				foreach (StarterDeckInfo item in ((IEnumerable<StarterDeckInfo>)(object)new StarterDeckInfo[2] { val, info }).Where((StarterDeckInfo i) => (Object)(object)i != (Object)null).Distinct())
				{
					item.cards = deck.Select((CardInfo c) => CardLoader.GetCardByName(((Object)c).name)).ToList();
				}
			}
			catch (Exception ex)
			{
				Log.LogError((object)("Could not update the deck shown on the deck screen: " + ex.Message));
			}
		}

		private static Texture2D LoadTexture(string name)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false)
			{
				filterMode = (FilterMode)0
			};
			try
			{
				using Stream stream = typeof(Plugin).Assembly.GetManifestResourceStream(name);
				using MemoryStream memoryStream = new MemoryStream();
				stream.CopyTo(memoryStream);
				ImageConversion.LoadImage(val, memoryStream.ToArray());
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)("Could not load " + name + ": " + ex.Message));
			}
			return val;
		}

		internal static bool IsRare(CardInfo c)
		{
			return c.metaCategories.Contains((CardMetaCategory)3);
		}

		private static bool Draftable(CardInfo c)
		{
			if (!c.metaCategories.Contains((CardMetaCategory)0))
			{
				return IsRare(c);
			}
			return true;
		}

		private static bool Readable(CardInfo c)
		{
			if ((Object)(object)c == (Object)null || string.IsNullOrEmpty(((Object)c).name) || c.metaCategories == null || c.appearanceBehaviour == null)
			{
				return false;
			}
			_ = c.BloodCost;
			_ = c.BonesCost;
			_ = c.Attack;
			_ = c.Health;
			return c.Abilities != null;
		}

		private static bool Usable(CardInfo c)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)c).name.StartsWith("!") && !Excluded.Contains(((Object)c).name) && (int)c.temple == 0 && !c.appearanceBe