Decompiled source of MT2StartPicker v1.0.0

plugins/MT2StartPicker/MT2StartPicker.dll

Decompiled 20 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using I2.Loc;
using Microsoft.CodeAnalysis;
using ShinyShoe;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("MT2StartPicker")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("MT2StartPicker")]
[assembly: AssemblyTitle("MT2StartPicker")]
[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 MT2StartPicker
{
	internal static class Patches
	{
		[HarmonyPatch(typeof(RelicManager), "ApplyStartOfRunRelicEffects")]
		private static class StartOfRun
		{
			private static void Prefix()
			{
				inStartOfRun = true;
			}

			private static Exception Finalizer(Exception __exception)
			{
				inStartOfRun = false;
				return __exception;
			}
		}

		[HarmonyPatch(typeof(CardPull), "CollectCards")]
		private static class CardPullPatch
		{
			private static void Prefix(List<CardData> collectedCards, out int __state)
			{
				__state = collectedCards?.Count ?? 0;
			}

			private static void Postfix(CardPull __instance, List<CardData> collectedCards, SaveManager saveManager, int __state)
			{
				if (!inStartOfRun || !__instance.ShowcaseAtRunStart || collectedCards == null || collectedCards.Count <= __state)
				{
					return;
				}
				try
				{
					List<string> list = Picks.Lookup(RunContext(saveManager), Picks.ScopeOfPull(__instance), ((Object)__instance).name);
					if (list.Count == 0)
					{
						return;
					}
					CardData val = saveManager.GetAllGameData().FindCardData(list[0]);
					if (!((Object)(object)val == (Object)null))
					{
						for (int i = __state; i < collectedCards.Count; i++)
						{
							collectedCards[i] = val;
						}
						Plugin.Log.LogInfo((object)("start card " + ((Object)__instance).name + ": " + ((Object)val).name));
					}
				}
				catch (Exception ex)
				{
					Plugin.Log.LogError((object)("start card pick failed: " + ex));
				}
			}
		}

		[HarmonyPatch(typeof(RelicDraftRewardData), "PregenerateRelicRewards")]
		private static class PregenPatch
		{
			private static void Prefix(Location location)
			{
				pregenDistance = location.Distance;
			}

			private static Exception Finalizer(Exception __exception)
			{
				pregenDistance = -1;
				return __exception;
			}
		}

		[HarmonyPatch(typeof(RelicDraftRewardData), "GetRelicsFromClasses")]
		private static class DraftPatch
		{
			private static void Postfix(RelicDraftRewardData __instance, SaveManager saveManager, List<CollectableRelicData> outList, PregeneratedRewardID pregenId)
			{
				int num = ((pregenId != null) ? pregenId.location.Distance : pregenDistance);
				if (num != 0 || outList == null || outList.Count == 0 || (Object)(object)saveManager == (Object)null)
				{
					return;
				}
				try
				{
					List<string> list = Picks.Lookup(RunContext(saveManager), Scope.Both, ((Object)__instance).name);
					if (list.Count == 0)
					{
						return;
					}
					RelicPool pool = default(RelicPool);
					ref RelicPool reference = ref pool;
					object? value = Picks.DraftPool.GetValue(__instance);
					reference = (RelicPool)((value is RelicPool) ? value : null);
					List<CollectableRelicData> want = (from r in list.Select(delegate(string id)
						{
							RelicPool obj = pool;
							return (obj == null) ? null : obj.FindRelic(id);
						})
						where (Object)(object)r != (Object)null && !saveManager.GetHasRelic((RelicData)(object)r) && !saveManager.IsRelicReserved(((GameData)r).GetID())
						select r).Distinct().ToList();
					if (want.Count != 0)
					{
						int count = outList.Count;
						List<CollectableRelicData> list2 = want.Concat(outList.Where((CollectableRelicData r) => !want.Contains(r))).Take(count).ToList();
						outList.Clear();
						outList.AddRange(list2);
						Plugin.Log.LogInfo((object)string.Format("start artifacts {0}@{1}: {2}", ((Object)__instance).name, num, string.Join(", ", list2.Select((CollectableRelicData r) => ((Object)r).name))));
					}
				}
				catch (Exception ex)
				{
					Plugin.Log.LogError((object)("start artifact pick failed: " + ex));
				}
			}
		}

		[HarmonyPatch(typeof(CardUpgradeTreeData), "GetRandomChoices")]
		private static class UpgradePatch
		{
			private static void Postfix(CardUpgradeTreeData __instance, CardState championCard, ref List<CardUpgradeData> __result)
			{
				if (__result == null || __result.Count == 0 || championCard == null)
				{
					return;
				}
				try
				{
					SaveManager sM = Plugin.SM;
					ClassData val = ((sM != null) ? sM.GetMainClass() : null);
					if ((Object)(object)val == (Object)null || (Object)(object)val.GetUpgradeTree(sM.GetMainChampionIndex()) != (Object)(object)__instance)
					{
						return;
					}
					List<string> list = Picks.Lookup(RunContext(sM), Scope.Champion, "upgrade");
					if (list.Count == 0)
					{
						return;
					}
					List<CardUpgradeState> cardUpgrades = championCard.GetCardStateModifiers().GetCardUpgrades();
					List<CardUpgradeData> want = new List<CardUpgradeData>();
					foreach (string id in list)
					{
						UpgradeTree val2 = ((IEnumerable<UpgradeTree>)__instance.GetUpgradeTrees()).FirstOrDefault((Func<UpgradeTree, bool>)delegate(UpgradeTree t)
						{
							CardUpgradeData firstUpgrade = t.GetFirstUpgrade();
							return ((firstUpgrade != null) ? ((GameData)firstUpgrade).GetID() : null) == id;
						});
						if (val2 == null)
						{
							continue;
						}
						CardUpgradeData val3 = null;
						bool flag = false;
						bool flag2 = false;
						foreach (CardUpgradeState item in cardUpgrades)
						{
							if (val2.GetNextUpgradeIfHasUpgrade(item, ref val3))
							{
								flag = true;
								break;
							}
							if (val2.UpgradeIsMaxedOut(item))
							{
								flag2 = true;
								break;
							}
						}
						if (!flag && !flag2)
						{
							val3 = val2.GetFirstUpgrade();
						}
						if ((Object)(object)val3 != (Object)null && !flag2)
						{
							want.Add(val3);
						}
					}
					if (want.Count != 0)
					{
						int count = __result.Count;
						__result = want.Concat(__result.Where((CardUpgradeData u) => !want.Contains(u))).Take(count).ToList();
					}
				}
				catch (Exception ex)
				{
					Plugin.Log.LogError((object)("champion upgrade pick failed: " + ex));
				}
			}
		}

		private static bool inStartOfRun;

		private static int pregenDistance = -1;

		private static Context RunContext(SaveManager sm)
		{
			ClassData mainClass = sm.GetMainClass();
			string main = ((mainClass != null) ? ((GameData)mainClass).GetID() : null);
			int mainChampionIndex = sm.GetMainChampionIndex();
			ClassData subClass = sm.GetSubClass();
			return new Context(main, mainChampionIndex, (subClass != null) ? ((GameData)subClass).GetID() : null);
		}
	}
	internal enum SlotKind
	{
		Card,
		Artifact,
		Upgrade
	}
	internal enum Scope
	{
		Main,
		Sub,
		Champion,
		Both
	}
	internal sealed class Option
	{
		public string id;

		public string name;

		public string info;

		public string sub;

		public object data;

		public Sprite icon;
	}
	internal sealed class Slot
	{
		public SlotKind kind;

		public string key;

		public string label;

		public int picks;

		public Scope scope;

		public List<Option> options = new List<Option>();
	}
	internal readonly struct Context
	{
		public const string Any = "*";

		public readonly string main;

		public readonly string sub;

		public readonly int champion;

		public string Key => $"{main}:{champion}|{sub}";

		public bool HasMain => main != "*";

		public bool HasSub => sub != "*";

		public Context(string main, int champion, string sub)
		{
			this.main = (string.IsNullOrEmpty(main) ? "*" : main);
			this.champion = champion;
			this.sub = (string.IsNullOrEmpty(sub) ? "*" : sub);
		}

		public string ScopeKey(Scope scope)
		{
			return scope switch
			{
				Scope.Main => "main:" + main, 
				Scope.Sub => "sub:" + sub, 
				Scope.Champion => $"champion:{main}:{champion}", 
				_ => "both:" + main + "|" + sub, 
			};
		}

		public IEnumerable<string> LookupKeys(Scope scope)
		{
			if (scope != Scope.Both)
			{
				yield return ScopeKey(scope);
				yield break;
			}
			yield return "both:" + main + "|" + sub;
			yield return "both:" + main + "|*";
			yield return "both:*|" + sub;
			yield return "both:*|*";
		}
	}
	internal static class Picks
	{
		private static readonly Dictionary<string, Dictionary<string, List<string>>> byContext = new Dictionary<string, Dictionary<string, List<string>>>();

		private static string file;

		private static readonly FieldInfo PullsField = AccessTools.Field(typeof(CardSetBuilder), "paramCardPulls");

		private static readonly FieldInfo PullPool = AccessTools.Field(typeof(CardPull), "cardPool");

		private static readonly FieldInfo PullClass = AccessTools.Field(typeof(CardPull), "classType");

		private static readonly FieldInfo PullCopies = AccessTools.Field(typeof(CardPull), "numCopies");

		private static readonly FieldInfo PullRarity = AccessTools.Field(typeof(CardPull), "cardRarity");

		private static readonly FieldInfo PullHasRarity = AccessTools.Field(typeof(CardPull), "hasRarityCondition");

		internal static readonly FieldInfo DraftPool = AccessTools.Field(typeof(RelicDraftRewardData), "draftPool");

		private static readonly FieldInfo DraftClass = AccessTools.Field(typeof(RelicDraftRewardData), "classType");

		private static readonly FieldInfo DraftIgnoreClass = AccessTools.Field(typeof(RelicDraftRewardData), "ignoreClassFilter");

		private static readonly FieldInfo DraftCount = AccessTools.Field(typeof(RelicDraftRewardData), "draftOptionsCount");

		internal const string StartDraftName = "BlessingDraftReward";

		public static void Load(string path)
		{
			file = path;
			byContext.Clear();
			if (!File.Exists(path))
			{
				return;
			}
			string[] array = File.ReadAllLines(path);
			for (int i = 0; i < array.Length; i++)
			{
				string[] array2 = array[i].Split('\t');
				if (array2.Length >= 3)
				{
					Get(array2[0])[array2[1]] = array2[2].Split(new char[1] { ' ' }, StringSplitOptions.RemoveEmptyEntries).ToList();
				}
			}
		}

		private static void Save()
		{
			if (file == null)
			{
				return;
			}
			List<string> list = new List<string>();
			foreach (KeyValuePair<string, Dictionary<string, List<string>>> item in byContext)
			{
				foreach (KeyValuePair<string, List<string>> item2 in item.Value)
				{
					if (item2.Value.Count > 0)
					{
						list.Add(item.Key + "\t" + item2.Key + "\t" + string.Join(" ", item2.Value));
					}
				}
			}
			try
			{
				File.WriteAllLines(file, list);
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("could not save picks: " + ex.Message));
			}
		}

		private static Dictionary<string, List<string>> Get(string ctx)
		{
			if (!byContext.TryGetValue(ctx, out var value))
			{
				value = (byContext[ctx] = new Dictionary<string, List<string>>());
			}
			return value;
		}

		public static List<string> For(string scopeKey, string slot)
		{
			if (!byContext.TryGetValue(scopeKey, out var value) || !value.TryGetValue(slot, out var value2))
			{
				return new List<string>();
			}
			return value2;
		}

		public static void Set(string scopeKey, string slot, List<string> ids)
		{
			Get(scopeKey)[slot] = ids.Where((string x) => !string.IsNullOrEmpty(x)).ToList();
			Save();
		}

		public static List<string> Lookup(Context run, Scope scope, string slot)
		{
			foreach (string item in run.LookupKeys(scope))
			{
				List<string> list = For(item, slot);
				if (list.Any((string x) => !string.IsNullOrEmpty(x)))
				{
					return list;
				}
			}
			return new List<string>();
		}

		public static Scope ScopeOfPull(CardPull p)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: 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_0019: Unknown result type (might be due to invalid IL or missing references)
			ClassType val = PullClassType(p);
			bool flag = ((Enum)val).HasFlag((Enum)(object)(ClassType)1);
			bool flag2 = ((Enum)val).HasFlag((Enum)(object)(ClassType)2);
			if (!flag || flag2)
			{
				if (!flag2 || flag)
				{
					return Scope.Both;
				}
				return Scope.Sub;
			}
			return Scope.Main;
		}

		public static void FindStartSources(AllGameData gd, out List<CardPull> pulls, out RelicDraftRewardData draft)
		{
			pulls = new List<CardPull>();
			draft = null;
			foreach (CovenantData allCovenantData in gd.GetAllCovenantDatas())
			{
				if ((Object)(object)allCovenantData == (Object)null)
				{
					continue;
				}
				foreach (RelicEffectData item in ((RelicData)allCovenantData).GetEffects() ?? new List<RelicEffectData>())
				{
					CardSetBuilder val = null;
					try
					{
						val = item.GetParamCardSetBuilder();
					}
					catch
					{
					}
					if ((Object)(object)val != (Object)null && PullsField?.GetValue(val) is List<CardPull> list)
					{
						foreach (CardPull item2 in list)
						{
							if ((Object)(object)item2 != (Object)null && item2.ShowcaseAtRunStart && !pulls.Contains(item2))
							{
								pulls.Add(item2);
							}
						}
					}
					GrantableRewardData val2 = null;
					try
					{
						val2 = item.GetParamGrantableReward();
					}
					catch
					{
					}
					if ((Object)(object)draft == (Object)null)
					{
						RelicDraftRewardData val3 = (RelicDraftRewardData)(object)((val2 is RelicDraftRewardData) ? val2 : null);
						if (val3 != null)
						{
							draft = val3;
						}
					}
				}
				if (pulls.Count > 0 && (Object)(object)draft != (Object)null)
				{
					break;
				}
			}
			if ((Object)(object)draft == (Object)null)
			{
				draft = ((IEnumerable<RelicDraftRewardData>)Resources.FindObjectsOfTypeAll<RelicDraftRewardData>()).FirstOrDefault((Func<RelicDraftRewardData, bool>)((RelicDraftRewardData r) => (Object)(object)r != (Object)null && ((Object)r).name == "BlessingDraftReward"));
			}
		}

		public static int DraftSize(RelicDraftRewardData d)
		{
			try
			{
				return (int)(uint)DraftCount.GetValue(d);
			}
			catch
			{
				return 2;
			}
		}

		public static uint Copies(CardPull p)
		{
			try
			{
				return (uint)PullCopies.GetValue(p);
			}
			catch
			{
				return 1u;
			}
		}

		public static ClassType PullClassType(CardPull p)
		{
			//IL_000b: 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_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				return (ClassType)PullClass.GetValue(p);
			}
			catch
			{
				return (ClassType)1;
			}
		}

		public static List<Slot> BuildSlots(SaveManager sm, ClassData main, int champion, ClassData sub)
		{
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Expected O, but got Unknown
			//IL_008e: 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_00bd: 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_02bc: 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_02d2: 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)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0351: Unknown result type (might be due to invalid IL or missing references)
			//IL_0358: Expected O, but got Unknown
			//IL_0364: Unknown result type (might be due to invalid IL or missing references)
			//IL_0369: Unknown result type (might be due to invalid IL or missing references)
			//IL_0327: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_039c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0407: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d4: Unknown result type (might be due to invalid IL or missing references)
			List<Slot> list = new List<Slot>();
			FindStartSources(sm.GetAllGameData(), out var pulls, out var draft);
			if ((Object)(object)draft != (Object)null)
			{
				Slot slot = new Slot
				{
					kind = SlotKind.Artifact,
					scope = Scope.Both,
					key = ((Object)draft).name,
					picks = DraftSize(draft),
					label = Plugin.T("开局神器(二选一的选项)", "Starting artifact (the draft options)")
				};
				List<CollectableRelicData> list2 = new List<CollectableRelicData>();
				try
				{
					RelicPool val = (RelicPool)DraftPool.GetValue(draft);
					List<string> list3 = new List<string>();
					ClassType val2 = (ClassType)DraftClass.GetValue(draft);
					if ((bool)DraftIgnoreClass.GetValue(draft))
					{
						list2.AddRange(RelicPoolHelper.GetAllRelics(val, sm, list3));
					}
					else
					{
						if (((Enum)val2).HasFlag((Enum)(object)(ClassType)1) && (Object)(object)main != (Object)null)
						{
							list2.AddRange(RelicPoolHelper.GetNonStartingRelicsForClass(val, sm, main, list3));
						}
						if (((Enum)val2).HasFlag((Enum)(object)(ClassType)2) && (Object)(object)sub != (Object)null)
						{
							list2.AddRange(RelicPoolHelper.GetNonStartingRelicsForClass(val, sm, sub, list3));
						}
						if (((Enum)val2).HasFlag((Enum)(object)(ClassType)4))
						{
							list2.AddRange(RelicPoolHelper.GetNonClassRelics(val, sm, list3));
						}
					}
				}
				catch (Exception ex)
				{
					Plugin.Log.LogWarning((object)("artifact candidates: " + ex));
				}
				foreach (CollectableRelicData r in list2.Distinct())
				{
					Sprite icon = null;
					try
					{
						icon = ((RelicData)r).GetIcon();
					}
					catch
					{
					}
					slot.options.Add(new Option
					{
						id = ((GameData)r).GetID(),
						data = r,
						icon = icon,
						name = Text.Clean(Text.Safe((Func<string>)((RelicData)r).GetName)),
						sub = ClanPrefix(r.GetLinkedClass(), main, sub) + Text.Safe(() => Text.RarityName(r.GetRarity())),
						info = Text.Clean(Text.Safe((Func<string>)((RelicData)r).GetDescription))
					});
				}
				slot.options.Sort((Option a, Option b) => string.CompareOrdinal(a.name, b.name));
				list.Add(slot);
			}
			foreach (CardPull item in pulls)
			{
				ClassType val3 = PullClassType(item);
				bool flag = ((Enum)val3).HasFlag((Enum)(object)(ClassType)1);
				bool flag2 = ((Enum)val3).HasFlag((Enum)(object)(ClassType)2);
				Scope scope = ScopeOfPull(item);
				if ((scope == Scope.Main && (Object)(object)main == (Object)null) || (scope == Scope.Sub && (Object)(object)sub == (Object)null) || (scope == Scope.Both && (Object)(object)main == (Object)null && (Object)(object)sub == (Object)null && !((Enum)val3).HasFlag((Enum)(object)(ClassType)4)))
				{
					continue;
				}
				List<CardData> list4 = new List<CardData>();
				try
				{
					CardPool val4 = (CardPool)PullPool.GetValue(item);
					CollectableRarity val5 = (CollectableRarity)PullRarity.GetValue(item);
					bool flag3 = (bool)PullHasRarity.GetValue(item);
					if (flag && (Object)(object)main != (Object)null)
					{
						list4.AddRange(CardPoolHelper.GetCardsForClass(val4, main, sm.GetClassLevelInMetagame(((GameData)main).GetID()), val5, (CollectableRarity?)null, sm, (RarityCondition)null, flag3));
					}
					if (flag2 && (Object)(object)sub != (Object)null)
					{
						list4.AddRange(CardPoolHelper.GetCardsForClass(val4, sub, sm.GetClassLevelInMetagame(((GameData)sub).GetID()), val5, (CollectableRarity?)null, sm, (RarityCondition)null, flag3));
					}
					if (((Enum)val3).HasFlag((Enum)(object)(ClassType)4))
					{
						list4.AddRange(CardPoolHelper.GetCardsForClass(val4, (ClassData)null, val5, (CollectableRarity?)null, sm, (RarityCondition)null, flag3, false));
					}
				}
				catch (Exception ex2)
				{
					Plugin.Log.LogWarning((object)("card candidates for " + ((Object)item).name + ": " + ex2));
				}
				bool num = list4.Count > 0 && list4.All((CardData c) => (int)c.GetCardType() == 1);
				string arg = ((flag && flag2) ? Plugin.T("主/副氏族", "main/allied clan") : (flag ? Plugin.T("主氏族", "main clan") : (flag2 ? Plugin.T("副氏族", "allied clan") : Plugin.T("无派系", "clanless"))));
				string arg2 = (num ? Plugin.T("单位", "unit") : Plugin.T("卡", "card"));
				Slot slot2 = new Slot
				{
					kind = SlotKind.Card,
					scope = scope,
					key = ((Object)item).name,
					picks = 1,
					label = Plugin.T($"开局{arg}{arg2}({Copies(item)} 张)", $"Starting {arg} {arg2} (x{Copies(item)})")
				};
				foreach (CardData item2 in list4.Distinct())
				{
					slot2.options.Add(new Option
					{
						id = ((GameData)item2).GetID(),
						data = item2,
						name = Text.Clean(Text.Safe((Func<string>)item2.GetName)),
						info = Text.CardInfo(item2)
					});
				}
				slot2.options.Sort((Option a, Option b) => string.CompareOrdinal(a.name, b.name));
				list.Add(slot2);
			}
			CardUpgradeTreeData val6 = null;
			try
			{
				val6 = ((main != null) ? main.GetUpgradeTree(champion) : null);
			}
			catch
			{
			}
			if ((Object)(object)val6 != (Object)null)
			{
				Slot slot3 = new Slot
				{
					kind = SlotKind.Upgrade,
					scope = Scope.Champion,
					key = "upgrade",
					picks = 2,
					label = Plugin.T("勇者升级路线(升级时给的两个选项)", "Champion upgrade paths (the two options offered)")
				};
				foreach (UpgradeTree upgradeTree in val6.GetUpgradeTrees())
				{
					CardUpgradeData firstUpgrade = upgradeTree.GetFirstUpgrade();
					if (!((Object)(object)firstUpgrade == (Object)null))
					{
						slot3.options.Add(new Option
						{
							id = ((GameData)firstUpgrade).GetID(),
							data = upgradeTree,
							name = Text.UpgradeName(firstUpgrade),
							info = Text.UpgradeDesc(firstUpgrade)
						});
					}
				}
				list.Add(slot3);
			}
			return list;
		}

		private static string ClanPrefix(ClassData linked, ClassData main, ClassData sub)
		{
			if ((Object)(object)linked == (Object)null)
			{
				return Plugin.T("通用 · ", "Any clan · ");
			}
			return Text.Clean(Text.Safe((Func<string>)linked.GetTitle)) + " · ";
		}
	}
	[BepInPlugin("jiesi.mt2.startpicker", "MT2 Start Picker", "1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		private class Runner : MonoBehaviour
		{
			public Plugin owner;

			private void Update()
			{
				owner?.Tick();
			}

			private void OnGUI()
			{
				owner?.DrawGUI();
			}
		}

		internal static ManualLogSource Log;

		internal static Plugin Instance;

		private ConfigEntry<KeyboardShortcut> toggleKey;

		private ConfigEntry<float> uiScale;

		private static readonly BindingFlags AnyStatic = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;

		private static readonly FieldInfo SaveManagerField = typeof(CheatManager).GetField("saveManager", AnyStatic);

		private static readonly FieldInfo AllGameManagersField = typeof(CheatManager).GetField("allGameManagers", AnyStatic);

		private static readonly FieldInfo I2Lang = typeof(LocalizationManager).GetField("mCurrentLanguage", BindingFlags.Static | BindingFlags.NonPublic);

		private bool show;

		private Context ctx;

		private string ctxTitle = "";

		private List<Slot> slots = new List<Slot>();

		private int section;

		private ClassData ctxMain;

		private Action pending;

		private float nextCtxCheck;

		private bool stylesReady;

		private GUIStyle sTitle;

		private GUIStyle sLabel;

		private GUIStyle sSmall;

		private GUIStyle sHeader;

		private GUIStyle sButton;

		private GUIStyle sBig;

		private GUIStyle sSide;

		private GUIStyle sSideOn;

		private GUIStyle sTile;

		private GUIStyle sFrameSel;

		private GUIStyle sFrameHover;

		private GUIStyle sBadge;

		private GUIStyle sCardName;

		private GUIStyle sTip;

		private GUIStyle sTipName;

		private GUIStyle sBar;

		private GUIStyle sBox;

		private GUIStyle sPathName;

		private Rect btnRect;

		private const float TopH = 58f;

		private const float SideW = 320f;

		private const float Pad = 10f;

		private const float Gap = 14f;

		private GameObject canvasGo;

		private RectTransform dim;

		private RectTransform cardRoot;

		private RectTransform btnBlock;

		private CardUI cardPrefab;

		private Vector2 cardNative = new Vector2(255f, 450f);

		private string cardsSig;

		private List<CardData> cardDatas;

		private List<CardState> cardStates;

		private readonly Dictionary<int, CardUI> cardUIs = new Dictionary<int, CardUI>();

		private readonly Dictionary<CardData, float> artRequested = new Dictionary<CardData, float>();

		private Rect[] cardRects = (Rect[])(object)new Rect[0];

		private TooltipSide[] cardSides = (TooltipSide[])(object)new TooltipSide[0];

		private float cardK = 0.5f;

		private int hoverCard = -1;

		private int focusedCard = -1;

		internal int forceHoverCard = -1;

		private Option hoverOption;

		internal Option forceHover;

		private Vector2 artScroll;

		internal List<Slot> Slots => slots;

		internal Context CurrentContext => ctx;

		internal static SaveManager SM
		{
			get
			{
				object? obj = SaveManagerField?.GetValue(null);
				return (SaveManager)((obj is SaveManager) ? obj : null);
			}
		}

		internal static AllGameManagers AGM
		{
			get
			{
				object? obj = AllGameManagersField?.GetValue(null);
				return (AllGameManagers)((obj is AllGameManagers) ? obj : null);
			}
		}

		internal static bool IsZh
		{
			get
			{
				string text = null;
				try
				{
					text = I2Lang?.GetValue(null) as string;
				}
				catch
				{
				}
				if (!string.IsNullOrEmpty(text))
				{
					return text.StartsWith("Chinese", StringComparison.OrdinalIgnoreCase);
				}
				return CultureInfo.CurrentUICulture.Name.StartsWith("zh", StringComparison.OrdinalIgnoreCase);
			}
		}

		private Slot CurrentSlot
		{
			get
			{
				if (section < 0 || section >= slots.Count)
				{
					return null;
				}
				return slots[section];
			}
		}

		private void Awake()
		{
			//IL_002c: 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_0092: 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_009d: Expected O, but got Unknown
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			Instance = this;
			toggleKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "ToggleKey", new KeyboardShortcut((KeyCode)285, Array.Empty<KeyCode>()), "在选氏族界面打开/关闭开局定制 / Opens the start picker on the run setup screen");
			uiScale = ((BaseUnityPlugin)this).Config.Bind<float>("General", "UIScale", 0f, "界面缩放,0 = 自动 / UI scale, 0 = automatic");
			Picks.Load(Path.Combine(Paths.ConfigPath, "MT2StartPicker.picks.txt"));
			new Harmony("jiesi.mt2.startpicker").PatchAll(Assembly.GetExecutingAssembly());
			GameObject val = new GameObject("MT2StartPicker_Runner");
			Object.DontDestroyOnLoad((Object)val);
			((Object)val).hideFlags = (HideFlags)61;
			val.AddComponent<Runner>().owner = this;
			((BaseUnityPlugin)this).Logger.LogInfo((object)("MT2 Start Picker loaded. Press " + ((object)toggleKey.Value/*cast due to .constrained prefix*/).ToString() + " on the run setup screen."));
		}

		internal static string T(string zh, string en)
		{
			if (!IsZh)
			{
				return en;
			}
			return zh;
		}

		private bool OnRunSetup()
		{
			try
			{
				return (Object)(object)SM != (Object)null && AGM.GetScreenManager().GetScreenActive((ScreenName)42) && !SM.IsInActiveGameplay();
			}
			catch
			{
				return false;
			}
		}

		private void Tick()
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			if (pending != null)
			{
				Action action = pending;
				pending = null;
				action();
			}
			if (!OnRunSetup())
			{
				if (show)
				{
					CloseView();
				}
				return;
			}
			KeyboardShortcut value = toggleKey.Value;
			if (((KeyboardShortcut)(ref value)).IsDown())
			{
				if (show)
				{
					CloseView();
				}
				else
				{
					show = true;
				}
			}
			UpdateCards();
			if (Time.unscaledTime >= nextCtxCheck)
			{
				nextCtxCheck = Time.unscaledTime + 0.3f;
				RefreshContext();
			}
		}

		internal void RefreshContext(bool force = false)
		{
			ClassData main = null;
			ClassData val = null;
			int champ = 0;
			string main2 = "";
			string sub = "";
			try
			{
				IScreen screen = AGM.GetScreenManager().GetScreen((ScreenName)42);
				Traverse obj = Traverse.Create((object)((screen is RunSetupScreen) ? screen : null));
				RunSetupClassLevelInfoUI value = obj.Field("mainClassInfo").GetValue<RunSetupClassLevelInfoUI>();
				RunSetupClassLevelInfoUI value2 = obj.Field("subClassInfo").GetValue<RunSetupClassLevelInfoUI>();
				main = ((!string.IsNullOrEmpty((value != null) ? value.RandomId : null)) ? null : ((value != null) ? value.ClassData : null));
				val = ((!string.IsNullOrEmpty((value2 != null) ? value2.RandomId : null)) ? null : ((value2 != null) ? value2.ClassData : null));
				champ = ((value != null) ? value.ChampionIndex : 0);
				main2 = (((Object)(object)main != (Object)null) ? ((GameData)main).GetID() : "*");
				sub = (((Object)(object)val != (Object)null) ? ((GameData)val).GetID() : "*");
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("reading run setup: " + ex.Message));
			}
			Context context = new Context(main2, champ, sub);
			if (force || !(context.Key == ctx.Key) || slots.Count <= 0)
			{
				ctx = context;
				ctxMain = main;
				section = 0;
				cardsSig = null;
				slots = new List<Slot>();
				try
				{
					slots = Picks.BuildSlots(SM, main, champ, val);
				}
				catch (Exception ex2)
				{
					((BaseUnityPlugin)this).Logger.LogError((object)("building slots: " + ex2));
				}
				string text = T("随机", "random");
				string text2 = (((Object)(object)main == (Object)null) ? text : (Text.Clean(Text.Safe((Func<string>)main.GetTitle)) + T("(", " (") + Text.Clean(Text.Safe(() => main.GetChampionCard(champ).GetName())) + T(")", ")")));
				string text3 = (((Object)(object)val == (Object)null) ? text : Text.Clean(Text.Safe((Func<string>)val.GetTitle)));
				ctxTitle = T("主氏族:" + text2 + "   副氏族:" + text3, "Main: " + text2 + "   Allied: " + text3);
			}
		}

		private List<string> Current(Slot s)
		{
			List<string> list = Picks.For(ctx.ScopeKey(s.scope), s.key).ToList();
			while (list.Count < s.picks)
			{
				list.Add("");
			}
			return list.Take(s.picks).ToList();
		}

		internal void SetPick(Slot s, int index, string id)
		{
			List<string> list = Current(s);
			if (!string.IsNullOrEmpty(id))
			{
				for (int i = 0; i < list.Count; i++)
				{
					if (i != index && list[i] == id)
					{
						list[i] = "";
					}
				}
			}
			list[index] = id ?? "";
			Picks.Set(ctx.ScopeKey(s.scope), s.key, list);
		}

		internal bool HasAnyPick()
		{
			return slots.Any((Slot s) => Current(s).Any((string x) => x.Length > 0));
		}

		internal void ClearAll()
		{
			foreach (Slot slot in slots)
			{
				Picks.Set(ctx.ScopeKey(slot.scope), slot.key, new List<string>());
			}
		}

		private string NameOf(Slot s, string id)
		{
			return s.options.FirstOrDefault((Option o) => o.id == id)?.name ?? T("(这些氏族用不了)", "(not available for these clans)");
		}

		private float Scale()
		{
			if (!(uiScale.Value > 0f))
			{
				return Mathf.Clamp((float)Screen.height / 1080f, 0.75f, 2.5f);
			}
			return uiScale.Value;
		}

		private static Texture2D Tex(Color c)
		{
			//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_000a: 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: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			Texture2D val = new Texture2D(1, 1);
			val.SetPixel(0, 0, c);
			val.Apply();
			((Object)val).hideFlags = (HideFlags)61;
			return val;
		}

		private static Texture2D FrameTex(Color c, int border)
		{
			//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_0012: Expected O, but got Unknown
			//IL_003a: 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)
			Texture2D val = new Texture2D(16, 16)
			{
				hideFlags = (HideFlags)61
			};
			for (int i = 0; i < 16; i++)
			{
				for (int j = 0; j < 16; j++)
				{
					val.SetPixel(i, j, (i < border || j < border || i >= 16 - border || j >= 16 - border) ? c : Color.clear);
				}
			}
			val.Apply();
			return val;
		}

		private void BuildStyles()
		{
			//IL_005f: 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_006b: 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_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Expected O, but got Unknown
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Expected O, but got Unknown
			//IL_00b9: 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_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Expected O, but got Unknown
			//IL_00ee: 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_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Expected O, but got Unknown
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Expected O, but got Unknown
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Expected O, but got Unknown
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Expected O, but got Unknown
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0200: Unknown result type (might be due to invalid IL or missing references)
			//IL_0207: Unknown result type (might be due to invalid IL or missing references)
			//IL_020e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			//IL_021c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0226: Expected O, but got Unknown
			//IL_022b: Expected O, but got Unknown
			//IL_024a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0278: Unknown result type (might be due to invalid IL or missing references)
			//IL_028e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0298: Expected O, but got Unknown
			//IL_02c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_030c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0316: Expected O, but got Unknown
			//IL_0335: Unknown result type (might be due to invalid IL or missing references)
			//IL_0345: 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_034f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0359: Expected O, but got Unknown
			//IL_035e: Expected O, but got Unknown
			//IL_0369: 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_0380: Unknown result type (might be due to invalid IL or missing references)
			//IL_038a: Expected O, but got Unknown
			//IL_038f: Expected O, but got Unknown
			//IL_03ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ec: Expected O, but got Unknown
			//IL_040b: 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_0436: Unknown result type (might be due to invalid IL or missing references)
			//IL_043b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0443: Unknown result type (might be due to invalid IL or missing references)
			//IL_044f: Expected O, but got Unknown
			//IL_045a: Unknown result type (might be due to invalid IL or missing references)
			//IL_045f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0468: Unknown result type (might be due to invalid IL or missing references)
			//IL_0472: Expected O, but got Unknown
			//IL_0477: Expected O, but got Unknown
			//IL_0496: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_04be: Expected O, but got Unknown
			//IL_04c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d3: Expected O, but got Unknown
			//IL_04f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_050c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0516: Expected O, but got Unknown
			//IL_0535: Unknown result type (might be due to invalid IL or missing references)
			if (!stylesReady)
			{
				Font font = null;
				try
				{
					font = Font.CreateDynamicFontFromOSFont(new string[4] { "Microsoft YaHei UI", "Microsoft YaHei", "SimHei", "Arial" }, 16);
				}
				catch
				{
				}
				Color val = default(Color);
				((Color)(ref val))..ctor(1f, 0.8f, 0.45f);
				sLabel = new GUIStyle(GUI.skin.label)
				{
					font = font,
					fontSize = 15,
					richText = true,
					wordWrap = true
				};
				sSmall = new GUIStyle(sLabel)
				{
					fontSize = 13
				};
				sSmall.normal.textColor = new Color(0.72f, 0.72f, 0.78f);
				sHeader = new GUIStyle(sLabel)
				{
					fontSize = 16,
					fontStyle = (FontStyle)1
				};
				sHeader.normal.textColor = val;
				sTitle = new GUIStyle(sHeader)
				{
					fontSize = 22,
					wordWrap = false
				};
				sPathName = new GUIStyle(sHeader)
				{
					fontSize = 17,
					alignment = (TextAnchor)1
				};
				sButton = new GUIStyle(GUI.skin.button)
				{
					font = font,
					fontSize = 15
				};
				sBig = new GUIStyle(sButton)
				{
					fontSize = 18,
					fontStyle = (FontStyle)1
				};
				GUIStyleState normal = sBig.normal;
				Texture2D background = (sBig.hover.background = Tex(new Color(0.55f, 0.35f, 0.12f, 1f)));
				normal.background = background;
				GUIStyleState normal2 = sBig.normal;
				Color textColor = (sBig.hover.textColor = Color.white);
				normal2.textColor = textColor;
				sSide = new GUIStyle(GUI.skin.button)
				{
					font = font,
					fontSize = 14,
					alignment = (TextAnchor)0,
					richText = true,
					wordWrap = true,
					padding = new RectOffset(10, 10, 8, 8)
				};
				sSide.normal.background = Tex(new Color(1f, 1f, 1f, 0.06f));
				sSide.hover.background = Tex(new Color(1f, 1f, 1f, 0.12f));
				sSideOn = new GUIStyle(sSide);
				GUIStyleState normal3 = sSideOn.normal;
				background = (sSideOn.hover.background = Tex(new Color(0.55f, 0.35f, 0.12f, 0.9f)));
				normal3.background = background;
				GUIStyleState normal4 = sSideOn.normal;
				textColor = (sSideOn.hover.textColor = Color.white);
				normal4.textColor = textColor;
				sTile = new GUIStyle(GUI.skin.box);
				sTile.normal.background = Tex(new Color(1f, 1f, 1f, 0.06f));
				sFrameSel = new GUIStyle
				{
					border = new RectOffset(5, 5, 5, 5)
				};
				sFrameSel.normal.background = FrameTex(val, 5);
				sFrameHover = new GUIStyle
				{
					border = new RectOffset(3, 3, 3, 3)
				};
				sFrameHover.normal.background = FrameTex(new Color(1f, 1f, 1f, 0.7f), 3);
				sBadge = new GUIStyle(sLabel)
				{
					fontSize = 15,
					fontStyle = (FontStyle)1,
					alignment = (TextAnchor)4,
					wordWrap = false
				};
				sBadge.normal.background = Tex(new Color(0.55f, 0.35f, 0.12f, 1f));
				sBadge.normal.textColor = Color.white;
				sCardName = new GUIStyle(sLabel)
				{
					fontSize = 14,
					alignment = (TextAnchor)1
				};
				sTip = new GUIStyle(GUI.skin.box)
				{
					padding = new RectOffset(14, 14, 12, 12)
				};
				sTip.normal.background = Tex(new Color(0.06f, 0.06f, 0.09f, 0.98f));
				sTipName = new GUIStyle(sHeader)
				{
					fontSize = 19
				};
				sBar = new GUIStyle(GUI.skin.box);
				sBar.normal.background = Tex(new Color(0.09f, 0.09f, 0.13f, 1f));
				sBox = new GUIStyle(GUI.skin.box);
				sBox.normal.background = Tex(new Color(1f, 1f, 1f, 0.04f));
				stylesReady = true;
			}
		}

		private void TogglePick(Slot sl, string id)
		{
			List<string> list = Current(sl);
			int num = list.IndexOf(id);
			if (num >= 0)
			{
				list[num] = "";
			}
			else
			{
				int num2 = list.IndexOf("");
				if (num2 >= 0)
				{
					list[num2] = id;
				}
				else
				{
					list.RemoveAt(0);
					list.Add(id);
				}
			}
			Picks.Set(ctx.ScopeKey(sl.scope), sl.key, list);
		}

		private void CloseView()
		{
			show = false;
			DestroyCards();
		}

		private void DestroyCards()
		{
			foreach (CardUI value in cardUIs.Values)
			{
				if ((Object)(object)value != (Object)null)
				{
					Object.Destroy((Object)(object)((Component)value).gameObject);
				}
			}
			cardUIs.Clear();
			focusedCard = (hoverCard = -1);
			cardDatas = null;
			cardStates = null;
			cardsSig = null;
		}

		private CardUI GetCardPrefab()
		{
			if ((Object)(object)cardPrefab != (Object)null)
			{
				return cardPrefab;
			}
			try
			{
				IScreen screen = AGM.GetScreenManager().GetScreen((ScreenName)3);
				DeckScreen val = (DeckScreen)(object)((screen is DeckScreen) ? screen : null);
				if ((Object)(object)val != (Object)null)
				{
					ref CardUI reference = ref cardPrefab;
					object? obj = typeof(DeckScreen).GetField("cardPrefab", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(val);
					reference = (CardUI)((obj is CardUI) ? obj : null);
				}
			}
			catch
			{
			}
			if ((Object)(object)cardPrefab == (Object)null)
			{
				cardPrefab = ((IEnumerable<CardUI>)Resources.FindObjectsOfTypeAll<CardUI>()).FirstOrDefault((Func<CardUI, bool>)delegate(CardUI c)
				{
					//IL_0006: Unknown result type (might be due to invalid IL or missing references)
					//IL_000b: Unknown result type (might be due to invalid IL or missing references)
					Scene scene = ((Component)c).gameObject.scene;
					return !((Scene)(ref scene)).IsValid();
				});
			}
			return cardPrefab;
		}

		private static bool ArtReady(CardData cd)
		{
			try
			{
				GameObject val = default(GameObject);
				return cd.GetCardArtPrefabVariant(ref val);
			}
			catch
			{
				return false;
			}
		}

		private void UpdateCards()
		{
			//IL_0218: Unknown result type (might be due to invalid IL or missing references)
			//IL_021f: Expected O, but got Unknown
			//IL_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_0226: Unknown result type (might be due to invalid IL or missing references)
			//IL_0238: Unknown result type (might be due to invalid IL or missing references)
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_029f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0250: Unknown result type (might be due to invalid IL or missing references)
			//IL_0255: 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_025e: Unknown result type (might be due to invalid IL or missing references)
			if (!show)
			{
				return;
			}
			Slot currentSlot = CurrentSlot;
			string text = ctx.Key + "|" + section;
			if (text != cardsSig)
			{
				if (cardsSig == null || !cardsSig.StartsWith(ctx.Key + "|"))
				{
					PreloadAllArt();
				}
				DestroyCards();
				cardsSig = text;
				if (currentSlot != null && currentSlot.kind != SlotKind.Artifact)
				{
					BuildCardStates(currentSlot);
				}
			}
			if (cardStates == null || cardDatas == null)
			{
				return;
			}
			float now = Time.realtimeSinceStartup;
			float value;
			List<CardData> list = cardDatas.Where((CardData cd) => (Object)(object)cd != (Object)null && !ArtReady(cd) && (!artRequested.TryGetValue(cd, out value) || now - value > 3f)).Distinct().ToList();
			if (list.Count > 0)
			{
				foreach (CardData item in list)
				{
					artRequested[item] = Time.realtimeSinceStartup;
				}
				RequestArt(list);
			}
			UpdateFocus();
			CardUI val = GetCardPrefab();
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			int num = 6;
			for (int num2 = 0; num2 < cardStates.Count; num2++)
			{
				if (num <= 0)
				{
					break;
				}
				if (cardUIs.ContainsKey(num2) || (Object)(object)cardDatas[num2] == (Object)null || !ArtReady(cardDatas[num2]))
				{
					continue;
				}
				if (cardStates[num2] == null)
				{
					cardStates[num2] = MakeCardState(currentSlot, currentSlot.options[num2], cardDatas[num2]);
				}
				if (cardStates[num2] == null)
				{
					continue;
				}
				CardUI val2 = Object.Instantiate<CardUI>(val, (Transform)(object)cardRoot, false);
				((Object)val2).name = "StartPickerCard" + num2;
				((Component)val2).gameObject.SetActive(true);
				RectTransform val3 = (RectTransform)((Component)val2).transform;
				Rect rect = val3.rect;
				if (((Rect)(ref rect)).width > 10f)
				{
					rect = val3.rect;
					if (((Rect)(ref rect)).height > 10f)
					{
						rect = val3.rect;
						cardNative = ((Rect)(ref rect)).size;
					}
				}
				try
				{
					val2.SetCardVisibleAndInteractable(true, (HandUI)null);
					val2.SetUIState((CardUIState)3);
					val2.ApplyStateToUI(cardStates[num2], (CardStatistics)null, (MonsterManager)null, (HeroManager)null, (RelicManager)null, SM, SM.GetMastery(cardStates[num2]), true, false, (List<CardUpgradeState>)null, (CardArtPool)null, (CardEdgeVfxPool)null);
				}
				catch (Exception ex)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)("render card failed: " + ex.Message));
				}
				cardUIs[num2] = val2;
				PlaceCard(num2, val2);
				num--;
			}
		}

		private void RequestArt(List<CardData> cards)
		{
			try
			{
				AssetLoadingManager inst = AssetLoadingManager.GetInst();
				if (inst != null)
				{
					inst.LoadCardsForCompendium((IEnumerable<CardData>)cards, (DoesOwnerPassFilter)null, (Action)null);
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("card art load failed: " + ex.Message));
			}
		}

		private void PreloadAllArt()
		{
			List<CardData> list = new List<CardData>();
			foreach (Slot slot in slots)
			{
				if (slot.kind == SlotKind.Card)
				{
					list.AddRange(slot.options.Select(delegate(Option o)
					{
						object data = o.data;
						return (CardData)((data is CardData) ? data : null);
					}));
				}
			}
			CardData val = null;
			try
			{
				ClassData obj = ctxMain;
				val = ((obj != null) ? obj.GetChampionCard(ctx.champion) : null);
			}
			catch
			{
			}
			if ((Object)(object)val != (Object)null)
			{
				list.Add(val);
			}
			list = list.Where((CardData c) => (Object)(object)c != (Object)null && !ArtReady(c)).Distinct().ToList();
			if (list.Count == 0)
			{
				return;
			}
			foreach (CardData item in list)
			{
				artRequested[item] = Time.realtimeSinceStartup;
			}
			RequestArt(list);
		}

		private void UpdateFocus()
		{
			int num = ((forceHoverCard >= 0) ? forceHoverCard : hoverCard);
			if (num == focusedCard)
			{
				return;
			}
			if (focusedCard >= 0 && cardUIs.TryGetValue(focusedCard, out var value) && (Object)(object)value != (Object)null)
			{
				try
				{
					value.ResetFocus();
				}
				catch
				{
				}
				PlaceCard(focusedCard, value);
			}
			focusedCard = -1;
			if (num < 0 || !cardUIs.TryGetValue(num, out var value2) || (Object)(object)value2 == (Object)null || cardStates == null || cardStates[num] == null)
			{
				return;
			}
			focusedCard = num;
			try
			{
				if (num < cardSides.Length)
				{
					value2.SetTooltipSide(cardSides[num]);
				}
				((Component)value2).transform.SetAsLastSibling();
				value2.SetFocus(cardStates[num], true, (LoreTooltipSetting)0, false, (Action)null);
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("card tooltip failed: " + ex.Message));
			}
			PlaceCard(num, value2);
		}

		private void BuildCardStates(Slot sl)
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Expected O, but got Unknown
			cardDatas = new List<CardData>();
			cardStates = new List<CardState>();
			foreach (Option option in sl.options)
			{
				CardData item = null;
				try
				{
					object obj;
					if (sl.kind == SlotKind.Card)
					{
						obj = (object)(CardData)option.data;
					}
					else
					{
						ClassData obj2 = ctxMain;
						obj = ((obj2 != null) ? obj2.GetChampionCard(ctx.champion) : null);
					}
					item = (CardData)obj;
				}
				catch
				{
				}
				cardDatas.Add(item);
				cardStates.Add(null);
			}
		}

		private CardState MakeCardState(Slot sl, Option o, CardData cd)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Expected O, but got Unknown
			try
			{
				SaveManager sM = SM;
				CardState val = new CardState(cd, sM, true, false);
				val.RefetchAssets(cd);
				if (sl.kind == SlotKind.Upgrade)
				{
					object data = o.data;
					UpgradeTree val2 = (UpgradeTree)((data is UpgradeTree) ? data : null);
					if (val2 != null && (Object)(object)val2.GetFirstUpgrade() != (Object)null)
					{
						CardUpgradeState val3 = new CardUpgradeState();
						val3.Setup(val2.GetFirstUpgrade(), false, false);
						val.ApplyPermanentUpgrade(val3, sM, true, (string)null);
					}
				}
				val.RefreshCardBodyTextLocalization();
				return val;
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("card state for " + o.name + ": " + ex.Message));
				return null;
			}
		}

		private void PlaceCard(int i, CardUI ui)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: 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_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			if (i < cardRects.Length)
			{
				Rect val = cardRects[i];
				RectTransform val2 = (RectTransform)((Component)ui).transform;
				Vector2 val3 = default(Vector2);
				((Vector2)(ref val3))..ctor(0f, 1f);
				val2.anchorMax = val3;
				val2.anchorMin = val3;
				val2.pivot = new Vector2(0.5f, 0.5f);
				val2.anchoredPosition = new Vector2(((Rect)(ref val)).center.x, 0f - ((Rect)(ref val)).center.y);
				float num = ((i == focusedCard) ? (cardK * 1.06f) : cardK);
				((Transform)val2).localScale = new Vector3(num, num, 1f);
			}
		}

		private RectTransform NewChild(string name, params Type[] comps)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Expected O, but got Unknown
			GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) }.Concat(comps).ToArray());
			val.transform.SetParent(canvasGo.transform, false);
			return (RectTransform)val.transform;
		}

		private void SyncCanvas(float s, bool onSetup)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			//IL_007e: 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)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: 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_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: 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_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f0: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)canvasGo == (Object)null)
			{
				canvasGo = new GameObject("MT2StartPicker_Canvas");
				Object.DontDestroyOnLoad((Object)(object)canvasGo);
				Canvas obj = canvasGo.AddComponent<Canvas>();
				obj.renderMode = (RenderMode)0;
				obj.sortingOrder = 31990;
				canvasGo.AddComponent<GraphicRaycaster>();
				dim = NewChild("Backdrop", typeof(Image));
				dim.anchorMin = Vector2.zero;
				dim.anchorMax = Vector2.one;
				RectTransform obj2 = dim;
				Vector2 offsetMin = (dim.offsetMax = Vector2.zero);
				obj2.offsetMin = offsetMin;
				Image component = ((Component)dim).GetComponent<Image>();
				((Graphic)component).color = new Color(0.035f, 0.035f, 0.055f, 1f);
				((Graphic)component).raycastTarget = true;
				cardRoot = NewChild("Cards", typeof(CanvasGroup));
				cardRoot.anchorMin = Vector2.zero;
				cardRoot.anchorMax = Vector2.one;
				RectTransform obj3 = cardRoot;
				offsetMin = (cardRoot.offsetMax = Vector2.zero);
				obj3.offsetMin = offsetMin;
				CanvasGroup component2 = ((Component)cardRoot).GetComponent<CanvasGroup>();
				component2.interactable = false;
				component2.blocksRaycasts = false;
				btnBlock = NewChild("ButtonBlocker", typeof(Image));
				RectTransform obj4 = btnBlock;
				RectTransform obj5 = btnBlock;
				RectTransform obj6 = btnBlock;
				Vector2 val = default(Vector2);
				((Vector2)(ref val))..ctor(0f, 1f);
				obj6.pivot = val;
				offsetMin = (obj5.anchorMax = val);
				obj4.anchorMin = offsetMin;
				Image component3 = ((Component)btnBlock).GetComponent<Image>();
				((Graphic)component3).color = new Color(0f, 0f, 0f, 0.004f);
				((Graphic)component3).raycastTarget = true;
			}
			canvasGo.GetComponent<Canvas>().scaleFactor = s;
			int num = GuiLayer();
			if (canvasGo.layer != num)
			{
				Transform[] componentsInChildren = canvasGo.GetComponentsInChildren<Transform>(true);
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					((Component)componentsInChildren[i]).gameObject.layer = num;
				}
			}
			bool flag = onSetup && show;
			((Component)dim).gameObject.SetActive(flag);
			((Component)cardRoot).gameObject.SetActive(flag && CurrentSlot != null && CurrentSlot.kind != SlotKind.Artifact);
			((Component)btnBlock).gameObject.SetActive(onSetup && !show);
			btnBlock.anchoredPosition = new Vector2(((Rect)(ref btnRect)).x, 0f - ((Rect)(ref btnRect)).y);
			btnBlock.sizeDelta = new Vector2(((Rect)(ref btnRect)).width, ((Rect)(ref btnRect)).height);
		}

		private static int GuiLayer()
		{
			//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)
			int num = 0;
			try
			{
				LayerMask currentGuiLayers = CoreInput.currentGuiLayers;
				num = ((LayerMask)(ref currentGuiLayers)).value;
			}
			catch
			{
			}
			int num2 = LayerMask.NameToLayer("UI");
			if (num2 >= 0 && (num & (1 << num2)) != 0)
			{
				return num2;
			}
			for (int i = 0; i < 32; i++)
			{
				if ((num & (1 << i)) != 0)
				{
					return i;
				}
			}
			if (num2 < 0)
			{
				return 5;
			}
			return num2;
		}

		private void DrawGUI()
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: 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_0061: 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_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			bool flag = OnRunSetup();
			float num = Scale();
			float num2 = (float)Screen.width / num;
			float h = (float)Screen.height / num;
			btnRect = new Rect(num2 - 200f, 14f, 180f, 44f);
			SyncCanvas(num, flag);
			if (!flag)
			{
				return;
			}
			BuildStyles();
			Matrix4x4 matrix = GUI.matrix;
			GUI.matrix = Matrix4x4.Scale(new Vector3(num, num, 1f));
			try
			{
				if (!show)
				{
					if (GUI.Button(btnRect, T("开局定制", "Start picker") + (HasAnyPick() ? " ●" : ""), sBig))
					{
						pending = delegate
						{
							show = true;
						};
					}
				}
				else
				{
					DrawView(num2, h);
				}
			}
			catch (Exception ex)
			{
				if (!(ex is ArgumentException))
				{
					((BaseUnityPlugin)this).Logger.LogError((object)ex);
				}
			}
			GUI.matrix = matrix;
		}

		private void DrawView(float W, float H)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: 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_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_04bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_025d: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_063f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0634: Unknown result type (might be due to invalid IL or missing references)
			//IL_040f: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b3: Unknown result type (might be due to invalid IL or missing references)
			hoverOption = null;
			GUI.Box(new Rect(0f, 0f, W, 58f), GUIContent.none, sBar);
			GUI.Label(new Rect(16f, 14f, 160f, 32f), T("开局定制", "Start picker"), sTitle);
			GUI.Label(new Rect(170f, 19f, W - 600f, 28f), ctxTitle, sHeader);
			if (GUI.Button(new Rect(W - 116f, 11f, 104f, 36f), T("✕ 关闭", "✕ Close"), sButton))
			{
				pending = CloseView;
			}
			if (slots.Count > 0 && GUI.Button(new Rect(W - 356f, 11f, 230f, 36f), T("清空这里显示的全部设置", "Clear everything shown"), sButton))
			{
				pending = ClearAll;
			}
			if (slots.Count == 0)
			{
				GUI.Label(new Rect(40f, 98f, W - 80f, 60f), T("现在没有能定制的项目。", "Nothing to set right now."), sHeader);
				return;
			}
			float num = 68f;
			Rect val = default(Rect);
			Rect val2 = default(Rect);
			for (int i = 0; i < slots.Count; i++)
			{
				Slot slot = slots[i];
				List<string> cur = Current(slot);
				bool flag = slot.kind == SlotKind.Artifact;
				float num2 = (flag ? 40 : 24);
				float num3 = 34f + (float)slot.picks * num2 + 6f;
				((Rect)(ref val))..ctor(10f, num, 310f, num3);
				int idx = i;
				if (GUI.Button(val, GUIContent.none, (i == section) ? sSideOn : sSide))
				{
					pending = delegate
					{
						//IL_0017: Unknown result type (might be due to invalid IL or missing references)
						//IL_001c: Unknown result type (might be due to invalid IL or missing references)
						section = idx;
						artScroll = Vector2.zero;
					};
				}
				GUI.Label(new Rect(((Rect)(ref val)).x + 10f, ((Rect)(ref val)).y + 6f, ((Rect)(ref val)).width - 20f, 24f), slot.label, (i == section) ? sLabel : sHeader);
				int k;
				for (k = 0; k < slot.picks; k++)
				{
					((Rect)(ref val2))..ctor(((Rect)(ref val)).x + 14f, ((Rect)(ref val)).y + 32f + (float)k * num2, ((Rect)(ref val)).width - 24f, num2);
					Option option = (string.IsNullOrEmpty(cur[k]) ? null : slot.options.FirstOrDefault((Option x) => x.id == cur[k]));
					string text = ((option != null) ? option.name : (string.IsNullOrEmpty(cur[k]) ? T("<color=#9a9aa5>随机(不指定)</color>", "<color=#9a9aa5>Random (not set)</color>") : NameOf(slot, cur[k])));
					if (flag && (Object)(object)option?.icon != (Object)null)
					{
						DrawSprite(new Rect(((Rect)(ref val2)).x, ((Rect)(ref val2)).y + 2f, 36f, 36f), option.icon);
						((Rect)(ref val2)).x = ((Rect)(ref val2)).x + 44f;
						((Rect)(ref val2)).width = ((Rect)(ref val2)).width - 44f;
					}
					GUI.Label(new Rect(((Rect)(ref val2)).x, ((Rect)(ref val2)).y + (float)(flag ? 9 : 2), ((Rect)(ref val2)).width, 22f), ((slot.picks > 1 && !flag) ? (k + 1 + ". ") : "") + text, sLabel);
				}
				num += num3 + 8f;
			}
			GUI.Label(new Rect(14f, num + 4f, 300f, H - num - 10f), T("没选的照常随机。每项只跟它相关的氏族绑定:主氏族卡跟主氏族,勇者升级跟主氏族+勇者,副氏族卡跟副氏族,单位和神器跟两边(某边选随机时,对那边任意氏族都生效)。" + ((ctx.HasMain && ctx.HasSub) ? "" : "\n\n有氏族是随机的:只显示不依赖它的项目,单位和神器只列已确定那边的和通用的。"), "Anything not set stays random. Each pick is tied only to what it depends on: main-clan card to the main clan, champion upgrades to main clan + champion, allied card to the allied clan, unit and artifacts to both (a side left random matches any clan)." + ((ctx.HasMain && ctx.HasSub) ? "" : "\n\nA clan is random: only picks that don't need it are shown.")), sSmall);
			Slot currentSlot = CurrentSlot;
			if (currentSlot != null)
			{
				Rect val3 = default(Rect);
				((Rect)(ref val3))..ctor(334f, 68f, W - 320f - 14f - 10f, H - 58f - 20f);
				string text2 = ((currentSlot.kind == SlotKind.Artifact) ? T($"点神器选中(最多 {currentSlot.picks} 个,就是开局二选一的选项),再点一次取消。鼠标停在神器上看大图和说明。", $"Click to pick (up to {currentSlot.picks}: the starting draft options), click again to un-pick. Hover for details.") : ((currentSlot.kind == SlotKind.Upgrade) ? T("每张卡是勇者走这条路线第一级后的样子。选 2 条,升级时给的两个选项就是它们,再点一次取消。", "Each card shows the champion after the path's first upgrade. Pick 2: the upgrade options offered.") : T("点卡选中,开局随机塞进牌组的那张就换成它;再点一次取消。", "Click a card to make it the starting card; click again to un-pick.")));
				GUI.Label(new Rect(((Rect)(ref val3)).x, ((Rect)(ref val3)).y, ((Rect)(ref val3)).width, 24f), text2, sSmall);
				Rect area = default(Rect);
				((Rect)(ref area))..ctor(((Rect)(ref val3)).x, ((Rect)(ref val3)).y + 30f, ((Rect)(ref val3)).width, ((Rect)(ref val3)).height - 30f);
				if (currentSlot.kind == SlotKind.Artifact)
				{
					DrawArtifacts(area, currentSlot);
				}
				else
				{
					DrawCards(area, currentSlot);
				}
				if (forceHover != null)
				{
					hoverOption = forceHover;
				}
				if (hoverOption != null && currentSlot.kind == SlotKind.Artifact)
				{
					DrawArtifactTip(hoverOption, W, H);
				}
			}
		}

		private void DrawCards(Rect area, Slot sl)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0203: Invalid comparison between Unknown and I4
			//IL_021d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0494: Unknown result type (might be due to invalid IL or missing references)
			//IL_0477: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0413: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0480: Unknown result type (might be due to invalid IL or missing references)
			int count = sl.options.Count;
			if (count == 0)
			{
				GUI.Label(area, T("这个位置没有可选的卡", "No options here"), sHeader);
				return;
			}
			bool flag = sl.kind == SlotKind.Upgrade;
			float num = (flag ? 34 : 8);
			float num2 = cardNative.x / cardNative.y;
			int num3 = 1;
			int num4 = int.MaxValue;
			float num5 = 0f;
			for (int i = 1; i <= count; i++)
			{
				int num6 = Mathf.CeilToInt((float)count / (float)i);
				float num7 = (((Rect)(ref area)).height - (float)num6 * (num + 14f)) / (float)num6;
				float num8 = (((Rect)(ref area)).width - (float)(i - 1) * 14f) / (float)i / (num2 * 1.08f) - 4f;
				float num9 = Mathf.Min(new float[3] { num7, num8, 430f });
				if (num9 > num5 + 0.5f || (num9 > num5 - 0.5f && num6 < num4))
				{
					num5 = Mathf.Max(num9, num5);
					num3 = i;
					num4 = num6;
				}
			}
			float num10 = num5;
			float num11 = num10 * num2 * 1.08f;
			int num12 = num3;
			int num13 = Mathf.CeilToInt((float)count / (float)num12);
			float num14 = (float)num12 * num11 + (float)(num12 - 1) * 14f;
			float num15 = (float)num13 * (num10 + num + 14f);
			float num16 = ((Rect)(ref area)).x + (((Rect)(ref area)).width - num14) / 2f;
			float num17 = ((Rect)(ref area)).y + Mathf.Max(0f, (((Rect)(ref area)).height - num15) / 2f);
			cardK = num10 / (cardNative.y * 1.08f);
			if (cardRects.Length != count)
			{
				cardRects = (Rect[])(object)new Rect[count];
				cardSides = (TooltipSide[])(object)new TooltipSide[count];
			}
			bool flag2 = (int)Event.current.type == 7;
			int num18 = -1;
			List<string> list = Current(sl);
			Vector2 mousePosition = Event.current.mousePosition;
			Rect val = default(Rect);
			Rect val2 = default(Rect);
			for (int j = 0; j < count; j++)
			{
				int num19 = j / num12;
				int num20 = j % num12;
				int num21 = Mathf.Min(num12, count - num19 * num12);
				float num22 = num16 + (num14 - ((float)num21 * num11 + (float)(num21 - 1) * 14f)) / 2f;
				((Rect)(ref val))..ctor(num22 + (float)num20 * (num11 + 14f), num17 + (float)num19 * (num10 + num + 14f), num11, num10);
				cardRects[j] = val;
				cardSides[j] = (TooltipSide)((num20 == num12 - 1 && num12 > 1) ? 3 : 4);
				Option option = sl.options[j];
				if (!cardUIs.ContainsKey(j))
				{
					GUI.Box(val, option.name + "\n" + T("加载中…", "loading…"), sTile);
				}
				((Rect)(ref val2))..ctor(((Rect)(ref val)).x - 4f, ((Rect)(ref val)).y - 4f, ((Rect)(ref val)).width + 8f, ((Rect)(ref val)).height + num + 8f);
				int num23 = list.IndexOf(option.id);
				int num24 = ((focusedCard >= 0 && focusedCard < count) ? ((j - focusedCard) * (((int)cardSides[focusedCard] != 3) ? 1 : (-1))) : 0);
				if (num24 < 1 || num24 > 2 || j / num12 != focusedCard / num12)
				{
					if (num23 >= 0)
					{
						GUI.Box(val2, GUIContent.none, sFrameSel);
						GUI.Label(new Rect(((Rect)(ref val)).x + ((Rect)(ref val)).width / 2f - 45f, ((Rect)(ref val)).y - 2f, 90f, 26f), (sl.picks > 1) ? T($"已选 {num23 + 1}", $"Pick {num23 + 1}") : T("已选", "Picked"), sBadge);
					}
					else if (((Rect)(ref val2)).Contains(mousePosition))
					{
						GUI.Box(val2, GUIContent.none, sFrameHover);
					}
				}
				if (((Rect)(ref val2)).Contains(mousePosition))
				{
					num18 = j;
				}
				if (flag)
				{
					GUI.Label(new Rect(((Rect)(ref val)).x - 20f, ((Rect)(ref val)).yMax + 8f, ((Rect)(ref val)).width + 40f, 26f), option.name, sPathName);
				}
				string pickId = option.id;
				if (GUI.Button(val2, GUIContent.none, GUIStyle.none))
				{
					pending = delegate
					{
						TogglePick(sl, pickId);
					};
				}
			}
			if (flag2)
			{
				hoverCard = num18;
			}
			foreach (KeyValuePair<int, CardUI> cardUI in cardUIs)
			{
				PlaceCard(cardUI.Key, cardUI.Value);
			}
		}

		private void DrawArtifacts(Rect area, Slot sl)
		{
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_0203: Unknown result type (might be due to invalid IL or missing references)
			//IL_0211: 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_026a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0296: Unknown result type (might be due to invalid IL or missing references)
			int num = Mathf.Max(1, Mathf.FloorToInt((((Rect)(ref area)).width - 20f + 14f) / 164f));
			int num2 = Mathf.CeilToInt((float)sl.options.Count / (float)num);
			float num3 = (float)num * 150f + (float)(num - 1) * 14f;
			float num4 = Mathf.Max(0f, (((Rect)(ref area)).width - 20f - num3) / 2f);
			List<string> list = Current(sl);
			artScroll = GUI.BeginScrollView(area, artScroll, new Rect(0f, 0f, ((Rect)(ref area)).width - 20f, (float)num2 * 164f));
			try
			{
				Vector2 mousePosition = Event.current.mousePosition;
				Rect val = default(Rect);
				for (int i = 0; i < sl.options.Count; i++)
				{
					((Rect)(ref val))..ctor(num4 + (float)(i % num) * 164f, (float)(i / num) * 164f, 150f, 150f);
					if (((Rect)(ref val)).yMax < artScroll.y || ((Rect)(ref val)).y > artScroll.y + ((Rect)(ref area)).height)
					{
						continue;
					}
					Option option = sl.options[i];
					GUI.Box(val, GUIContent.none, sTile);
					DrawSprite(new Rect(((Rect)(ref val)).x + 33f, ((Rect)(ref val)).y + 10f, 84f, 84f), option.icon);
					GUI.Label(new Rect(((Rect)(ref val)).x + 6f, ((Rect)(ref val)).y + 84f + 14f, 138f, 50f), option.name, sCardName);
					int num5 = list.IndexOf(option.id);
					bool flag = ((Rect)(ref val)).Contains(mousePosition);
					if (num5 >= 0)
					{
						GUI.Box(val, GUIContent.none, sFrameSel);
						GUI.Label(new Rect(((Rect)(ref val)).x + 4f, ((Rect)(ref val)).y + 4f, 30f, 26f), (num5 + 1).ToString(), sBadge);
					}
					else if (flag)
					{
						GUI.Box(val, GUIContent.none, sFrameHover);
					}
					if (flag)
					{
						hoverOption = option;
					}
					string pickId = option.id;
					if (GUI.Button(val, GUIContent.none, GUIStyle.none))
					{
						pending = delegate
						{
							TogglePick(sl, pickId);
						};
					}
				}
			}
			finally
			{
				GUI.EndScrollView();
			}
		}

		private void DrawArtifactTip(Option o, float W, float H)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Expected O, but got Unknown
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: 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_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: 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)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Expected O, but got Unknown
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			float num = 266f;
			float num2 = Mathf.Max(174f, 24f + sTipName.CalcHeight(new GUIContent(o.name), num) + 24f + sLabel.CalcHeight(new GUIContent(o.info), num) + 20f);
			Vector2 mousePosition = Event.current.mousePosition;
			float num3 = ((mousePosition.x + 24f + 460f > W) ? (mousePosition.x - 460f - 16f) : (mousePosition.x + 24f));
			float num4 = Mathf.Clamp(mousePosition.y - 20f, 58f, H - num2 - 6f);
			Rect val = default(Rect);
			((Rect)(ref val))..ctor(num3, num4, 460f, num2);
			GUI.Box(val, GUIContent.none, sTip);
			GUI.Box(val, GUIContent.none, sFrameHover);
			DrawSprite(new Rect(((Rect)(ref val)).x + 14f, ((Rect)(ref val)).y + 12f, 150f, 150f), o.icon);
			float num5 = ((Rect)(ref val)).x + 150f + 30f;
			float num6 = sTipName.CalcHeight(new GUIContent(o.name), num);
			GUI.Label(new Rect(num5, ((Rect)(ref val)).y + 12f, num, num6), o.name, sTipName);
			GUI.Label(new Rect(num5, ((Rect)(ref val)).y + 14f + num6, num, 22f), o.sub, sSmall);
			GUI.Label(new Rect(num5, ((Rect)(ref val)).y + 40f + num6, num, num2 - num6 - 46f), o.info, sLabel);
		}

		private static void DrawSprite(Rect r, Sprite sp)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: 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)
			if (!((Object)(object)sp == (Object)null) && !((Object)(object)sp.texture == (Object)null))
			{
				Rect textureRect = sp.textureRect;
				Texture texture = (Texture)(object)sp.texture;
				Rect val = default(Rect);
				((Rect)(ref val))..ctor(((Rect)(ref textureRect)).x / (float)texture.width, ((Rect)(ref textureRect)).y / (float)texture.height, ((Rect)(ref textureRect)).width / (float)texture.width, ((Rect)(ref textureRect)).height / (float)texture.height);
				float num = ((Rect)(ref textureRect)).width / ((Rect)(ref textureRect)).height;
				GUI.DrawTextureWithTexCoords((num >= 1f) ? new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).y + (((Rect)(ref r)).height - ((Rect)(ref r)).width / num) / 2f, ((Rect)(ref r)).width, ((Rect)(ref r)).width / num) : new Rect(((Rect)(ref r)).x + (((Rect)(ref r)).width - ((Rect)(ref r)).height * num) / 2f, ((Rect)(ref r)).y, ((Rect)(ref r)).height * num, ((Rect)(ref r)).height), texture, val, true);
			}
		}
	}
	internal static class Text
	{
		private static readonly Regex Tags = new Regex("<[^>]+>", RegexOptions.Compiled);

		public static string Clean(string s)
		{
			if (!string.IsNullOrEmpty(s))
			{
				return Tags.Replace(s, "").Replace("\n", " ").Trim();
			}
			return "";
		}

		public static string Safe(Func<string> f)
		{
			try
			{
				return f() ?? "";
			}
			catch
			{
				return "";
			}
		}

		public static string CardInfo(CardData c)
		{
			string text = Safe(() => TypeName(c.GetCardType()));
			string text2 = Safe(() => RarityName(c.GetRarity()));
			string text3 = Safe(() => (!(((object)c.GetCostType()/*cast due to .constrained prefix*/).ToString() == "ConsumeRemainingEnergy")) ? c.GetCost().ToString() : "X");
			return Plugin.T(text + " · " + text3 + "费 · " + text2, text + " · cost " + text3 + " · " + text2);
		}

		public static string UpgradeName(CardUpgradeData u)
		{
			return Clean(Safe(() => LocalizationExtensions.Localize(u.GetUpgradeTitleKey(), (ILocalizationParameterContext)null)));
		}

		public static string UpgradeDesc(CardUpgradeData u)
		{
			return Clean(Safe(() => LocalizationExtensions.Localize(u.GetUpgradeDescriptionKey(), (ILocalizationParameterContext)new CardEffectLocalizationContext((ILocalizationEffectPower)(object)u, (CharacterState)null, (CardState)null, (IRoomStateModifier)null, (CharacterStatusEffectAdjustments)null))));
		}

		private unsafe static string TypeName(CardType t)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Invalid comparison between Unknown and I4
			//IL_0004: 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_0013: Invalid comparison between Unknown and I4
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Invalid comparison between Unknown and I4
			if ((int)t <= 1)
			{
				if ((int)t == 0)
				{
					return Term("Compendium_Filter_CardType_Spell", Plugin.T("法术", "Spell"));
				}
				if ((int)t == 1)
				{
					return Term("Compendium_Filter_CardType_Monster", Plugin.T("单位", "Unit"));
				}
			}
			else
			{
				if ((int)t == 7)
				{
					return Term("Compendium_Filter_CardType_Equipment", Plugin.T("装备", "Equipment"));
				}
				if ((int)t == 8)
				{
					return Term("Compendium_Filter_CardType_TrainRoomAttachment", Plugin.T("房间", "Room"));
				}
			}
			return ((object)(*(CardType*)(&t))/*cast due to .constrained prefix*/).ToString();
		}

		internal unsafe static string RarityName(CollectableRarity r)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected I4, but got Unknown
			return (int)r switch
			{
				0 => Term("CardRarity_Common", Plugin.T("普通", "Common")), 
				1 => Term("CardRarity_Uncommon", Plugin.T("罕见", "Uncommon")), 
				2 => Term("CardRarity_Rare", Plugin.T("稀有", "Rare")), 
				3 => Term("CardRarity_Champion", Plugin.T("勇者", "Champion")), 
				_ => ((object)(*(CollectableRarity*)(&r))/*cast due to .constrained prefix*/).ToString(), 
			};
		}

		private static string Term(string key, string fallback)
		{
			try
			{
				if (LocalizationExtensions.HasTranslation(key))
				{
					string text = LocalizationExtensions.Localize(key, (ILocalizationParameterContext)null);
					if (!string.IsNullOrWhiteSpace(text) && !text.Contains(">>"))
					{
						return text;
					}
				}
			}
			catch
			{
			}
			return fallback;
		}
	}
}