Decompiled source of AchievementTracker v0.1.0

plugins/AchievementTracker.dll

Decompiled a week ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Splatform;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("AchievementTracker")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.0.0")]
[assembly: AssemblyInformationalVersion("0.1.0+481c8b8578f5d75163cf0921886db388efdaba08")]
[assembly: AssemblyProduct("AchievementTracker")]
[assembly: AssemblyTitle("AchievementTracker")]
[assembly: AssemblyVersion("0.1.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 AchievementTracker
{
	internal class Requirement
	{
		public string Category;

		public string Key;

		public string Label;

		public float Current;

		public float Needed;

		public RequirementOperator Op;

		public bool Met;

		public float Fraction
		{
			get
			{
				//IL_0009: Unknown result type (might be due to invalid IL or missing references)
				if (!Met)
				{
					if ((int)Op != 0 || !(Needed > 0f))
					{
						return 0f;
					}
					return Math.Min(Current / Needed, 1f);
				}
				return 1f;
			}
		}
	}
	internal class AchievementEntry
	{
		public Achievement Source;

		public string Name;

		public string Description;

		public string Difficulty;

		public int Tier;

		public int Order;

		public bool Secret;

		public bool Done;

		public bool? SteamDone;

		public float Progress;

		public int Met;

		public readonly List<Requirement> Requirements = new List<Requirement>();

		public bool Hidden
		{
			get
			{
				if (Secret && !Done && SteamDone != true)
				{
					return !Plugin.RevealSecrets.Value;
				}
				return false;
			}
		}

		public bool Started
		{
			get
			{
				if (!Done)
				{
					return Progress > 0f;
				}
				return true;
			}
		}
	}
	internal static class AchievementData
	{
		private static readonly Dictionary<string, string> LabelCache = new Dictionary<string, string>();

		public static bool CanEarn;

		public static string CurrentDifficulty;

		public unsafe static List<AchievementEntry> Build()
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Invalid comparison between Unknown and I4
			List<AchievementEntry> list = new List<AchievementEntry>();
			Game instance = Game.instance;
			PlayerProfile val = ((instance != null) ? instance.GetPlayerProfile() : null);
			if (val == null || (Object)(object)Achievements.m_instance == (Object)null)
			{
				return list;
			}
			CanEarn = Achievements.CanGetAchievements(false);
			DifficultyRequirement currentAchievementDifficulty = Achievements.GetCurrentAchievementDifficulty();
			CurrentDifficulty = (((int)currentAchievementDifficulty == 1) ? null : ((object)(*(DifficultyRequirement*)(&currentAchievementDifficulty))/*cast due to .constrained prefix*/).ToString());
			int num = 0;
			foreach (AchievementList achievementList in Achievements.m_instance.m_achievementLists)
			{
				foreach (Achievement achievement in achievementList.m_achievements)
				{
					if (!((Object)(object)achievement == (Object)null))
					{
						list.Add(BuildEntry(achievement, val, num++));
					}
				}
			}
			QuerySteam(list);
			return list;
		}

		private unsafe static AchievementEntry BuildEntry(Achievement ach, PlayerProfile profile, int order)
		{
			//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_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Invalid comparison between Unknown and I4
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Expected I4, but got Unknown
			//IL_0098: 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)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: 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_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_033b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: 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_01a6: Expected I4, but got Unknown
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: 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_01dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			AchievementEntry achievementEntry = new AchievementEntry
			{
				Source = ach,
				Name = Localize(ach.m_name),
				Description = Localize(ach.m_description),
				Secret = ach.m_isSecret,
				Order = order,
				Tier = 99
			};
			if ((Object)(object)ach.m_iconLocked != (Object)null && ((Object)ach.m_iconLocked).name.Length >= 2 && int.TryParse(((Object)ach.m_iconLocked).name.Substring(0, 2), out var result))
			{
				achievementEntry.Tier = result;
			}
			DifficultyRequirement difficultyRequirement = ach.m_difficultyRequirement;
			if ((int)difficultyRequirement != 1 && (int)difficultyRequirement != 0)
			{
				achievementEntry.Difficulty = ((object)(*(DifficultyRequirement*)(&difficultyRequirement))/*cast due to .constrained prefix*/).ToString();
			}
			int num = (int)difficultyRequirement;
			PlayerStats val = ((num >= 0 && num < profile.m_playerStats.Length) ? profile.m_playerStats[num] : null);
			if (val != null)
			{
				foreach (PlayerStatRequirement item in ach.m_statTrigger)
				{
					float value;
					bool flag = val.m_stats.TryGetValue(item.m_stat, out value);
					achievementEntry.Requirements.Add(new Requirement
					{
						Category = "Stat",
						Label = StatLabel(item.m_stat),
						Current = value,
						Needed = item.m_amountAboveEquals,
						Op = (RequirementOperator)0,
						Met = (flag && value >= item.m_amountAboveEquals)
					});
				}
				foreach (EnemyStatRequirement enemyStatsTrigger in ach.m_enemyStatsTriggers)
				{
					int num2 = (int)enemyStatsTrigger.m_modifier;
					Dictionary<string, float> dict = ((num2 >= 0 && num2 < val.m_enemyStats.Length) ? val.m_enemyStats[num2] : null);
					AddDictRequirement(achievementEntry, KillCategory(enemyStatsTrigger.m_modifier), dict, enemyStatsTrigger.m_stat, enemyStatsTrigger.m_amount, enemyStatsTrigger.m_operator);
				}
				AddDict(achievementEntry, "Eat", val.m_foodEatenStats, ach.m_foodEatenTriggers);
				AddDict(achievementEntry, "Craft", val.m_itemCraftStats, ach.m_itemCraftTriggers);
				AddDict(achievementEntry, "Pick up", val.m_itemPickupStats, ach.m_itemPickupTriggers);
				AddDict(achievementEntry, "Harvest", val.m_pickableStats, ach.m_pickableTriggers);
				AddDict(achievementEntry, "Build", val.m_piecesPlacedStats, ach.m_piecePlacedTriggers);
				AddDict(achievementEntry, "Command", val.m_knownCommands, ach.m_knownCommandsTriggers);
				AddDict(achievementEntry, "World", val.m_knownWorlds, ach.m_knownWorldTriggers);
				AddDict(achievementEntry, "World key", val.m_knownWorldKeys, ach.m_knownWorldKeysTriggers);
			}
			foreach (Achievement otherAchievementTrigger in ach.m_otherAchievementTriggers)
			{
				if (!((Object)(object)otherAchievementTrigger == (Object)null))
				{
					achievementEntry.Requirements.Add(new Requirement
					{
						Category = "Achievement",
						Label = Localize(otherAchievementTrigger.m_name),
						Current = (otherAchievementTrigger.m_unlocked ? 1f : 0f),
						Needed = 1f,
						Op = (RequirementOperator)0,
						Met = otherAchievementTrigger.m_unlocked
					});
				}
			}
			float num3 = 0f;
			foreach (Requirement requirement in achievementEntry.Requirements)
			{
				num3 += requirement.Fraction;
				if (requirement.Met)
				{
					achievementEntry.Met++;
				}
			}
			int count = achievementEntry.Requirements.Count;
			achievementEntry.Done = ach.m_unlocked || (count > 0 && achievementEntry.Met == count);
			achievementEntry.Progress = (achievementEntry.Done ? 1f : ((count > 0) ? (num3 / (float)count) : 0f));
			achievementEntry.Requirements.Sort((Requirement a, Requirement b) => (a.Met == b.Met) ? b.Fraction.CompareTo(a.Fraction) : a.Met.CompareTo(b.Met));
			return achievementEntry;
		}

		private static void AddDict(AchievementEntry e, string category, Dictionary<string, float> dict, List<DictStatRequirement> triggers)
		{
			//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_0014: 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_0020: 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)
			foreach (DictStatRequirement trigger in triggers)
			{
				AddDictRequirement(e, category, dict, trigger.m_stat, trigger.m_amount, trigger.m_operator);
			}
		}

		private static void AddDictRequirement(AchievementEntry e, string category, Dictionary<string, float> dict, string stat, float amount, RequirementOperator op)
		{
			//IL_0091: 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_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected I4, but got Unknown
			float value = 0f;
			bool num = dict != null && stat != null && dict.TryGetValue(stat, out value);
			bool met = false;
			if (num)
			{
				switch ((int)op)
				{
				case 0:
					met = value >= amount;
					break;
				case 1:
					met = value <= amount;
					break;
				case 2:
					met = value == amount;
					break;
				case 3:
					met = value != amount;
					break;
				}
			}
			e.Requirements.Add(new Requirement
			{
				Category = category,
				Key = stat,
				Label = Localize(stat),
				Current = value,
				Needed = amount,
				Op = op,
				Met = met
			});
		}

		private static void QuerySteam(List<AchievementEntry> list)
		{
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Expected O, but got Unknown
			IDistributionPlatform distributionPlatform;
			IAchievementManager val;
			try
			{
				distributionPlatform = PlatformManager.DistributionPlatform;
				val = ((distributionPlatform != null) ? distributionPlatform.AchievementManager : null);
			}
			catch (Exception ex)
			{
				Plugin.Log.LogDebug((object)("No platform achievements: " + ex.Message));
				return;
			}
			if (val == null || !val.IsInitialized)
			{
				return;
			}
			foreach (AchievementEntry item in list)
			{
				AchievementEntry entry = item;
				try
				{
					val.IsUnlocked(PlatformId(entry.Source, distributionPlatform), (AsyncOperationCompletedHandler)delegate(bool unlocked)
					{
						entry.SteamDone = unlocked;
					});
				}
				catch (Exception ex2)
				{
					Plugin.Log.LogDebug((object)("Steam lookup failed for " + entry.Source.m_id + ": " + ex2.Message));
				}
			}
		}

		private static string PlatformId(Achievement ach, IDistributionPlatform platform)
		{
			//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_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)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			foreach (DictAchievementPlatformInternalId platformInternalId in ach.m_platformInternalIds)
			{
				Platform platform2 = platform.Platform;
				if (((Platform)(ref platform2)).Equals(platformInternalId.m_platform))
				{
					return platformInternalId.m_internalPlatformId;
				}
			}
			return ach.m_id;
		}

		private static string KillCategory(KillModifiers modifier)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected I4, but got Unknown
			return (modifier - 1) switch
			{
				0 => "Kill (unarmed)", 
				1 => "Kill (magic)", 
				2 => "Kill (ranged)", 
				3 => "Kill (melee)", 
				_ => "Kill", 
			};
		}

		private unsafe static string StatLabel(PlayerStatType stat)
		{
			string text = "$stat_" + ((object)(*(PlayerStatType*)(&stat))/*cast due to .constrained prefix*/).ToString();
			string text2 = Localize(text);
			if (!(text2 == text))
			{
				return text2;
			}
			return Pretty(((object)(*(PlayerStatType*)(&stat))/*cast due to .constrained prefix*/).ToString());
		}

		internal static string Localize(string key)
		{
			if (string.IsNullOrEmpty(key))
			{
				return "";
			}
			if (LabelCache.TryGetValue(key, out var value))
			{
				return value;
			}
			string text = key;
			try
			{
				if (key.IndexOf('$') >= 0 && Localization.instance != null)
				{
					text = Localization.instance.Localize(key);
				}
			}
			catch (Exception)
			{
			}
			if (string.IsNullOrEmpty(text) || text.StartsWith("["))
			{
				text = Pretty(key);
			}
			LabelCache[key] = text;
			return text;
		}

		private static string Pretty(string key)
		{
			string text = key.TrimStart(new char[1] { '$' });
			int num = text.IndexOf('_');
			if (key.StartsWith("$") && num >= 0)
			{
				text = text.Substring(num + 1);
			}
			StringBuilder stringBuilder = new StringBuilder(text.Length + 8);
			for (int i = 0; i < text.Length; i++)
			{
				char c = text[i];
				if (c == '_')
				{
					stringBuilder.Append(' ');
					continue;
				}
				if (i > 0 && char.IsUpper(c) && char.IsLower(text[i - 1]))
				{
					stringBuilder.Append(' ');
				}
				stringBuilder.Append((stringBuilder.Length == 0) ? char.ToUpperInvariant(c) : ((i > 0) ? char.ToLowerInvariant(c) : c));
			}
			return stringBuilder.ToString();
		}
	}
	internal class NativeWindow
	{
		private enum Filter
		{
			All,
			Active,
			Done
		}

		internal class Panel
		{
			public GameObject Root;

			public RectTransform Frame;

			public RectTransform ListContainer;

			public RectTransform ListRoot;

			public ScrollRect Scroll;

			public Scrollbar Scrollbar;

			public RectTransform TooltipAnchor;

			public GameObject ElementPrefab;

			public GameObject TooltipPrefab;

			public TMP_Text Title;

			public TMP_Text TextTemplate;

			public Button Close;

			public Button Backdrop;

			public float Spacing;

			public float BaseListHeight;

			public readonly List<Row> Rows = new List<Row>();

			public float ListWidth
			{
				get
				{
					//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)
					Rect rect = ListContainer.rect;
					return ((Rect)(ref rect)).width;
				}
			}

			public static Panel Clone(SkillsDialog template, Transform parent, string name, bool keepBackdrop)
			{
				//IL_02b6: Unknown result type (might be due to invalid IL or missing references)
				//IL_02bd: Expected O, but got Unknown
				//IL_0331: Unknown result type (might be due to invalid IL or missing references)
				//IL_0336: Unknown result type (might be due to invalid IL or missing references)
				GameObject val = Object.Instantiate<GameObject>(((Component)template).gameObject, parent, false);
				((Object)val).name = name;
				val.SetActive(false);
				SkillsDialog component = val.GetComponent<SkillsDialog>();
				Panel panel = new Panel
				{
					Root = val,
					ListRoot = component.m_listRoot,
					TooltipAnchor = component.m_tooltipAnchor,
					ElementPrefab = component.m_elementPrefab,
					TextTemplate = component.m_totalSkillText,
					Spacing = component.m_spacing,
					Scroll = (ScrollRect)/*isinst with value type is only supported in some contexts*/,
					Scrollbar = (Scrollbar)/*isinst with value type is only supported in some contexts*/,
					Frame = (RectTransform)/*isinst with value type is only supported in some contexts*/
				};
				Object.DestroyImmediate((Object)(object)component);
				UIGroupHandler[] componentsInChildren = val.GetComponentsInChildren<UIGroupHandler>(true);
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					Object.DestroyImmediate((Object)(object)componentsInChildren[i]);
				}
				CanvasGroup component2 = val.GetComponent<CanvasGroup>();
				if ((Object)(object)component2 != (Object)null)
				{
					component2.alpha = 1f;
					component2.interactable = true;
					component2.blocksRaycasts = true;
				}
				if ((Object)(object)panel.Frame == (Object)null || (Object)(object)panel.Scroll == (Object)null || (Object)(object)panel.ListRoot == (Object)null || (Object)(object)panel.ElementPrefab == (Object)null)
				{
					Object.Destroy((Object)(object)val);
					return null;
				}
				ref RectTransform listContainer = ref panel.ListContainer;
				Transform parent2 = ((Component)panel.Scroll).transform.parent;
				listContainer = (RectTransform)(object)((parent2 is RectTransform) ? parent2 : null);
				Transform obj = ((Transform)panel.Frame).Find("Closebutton");
				panel.Close = ((obj != null) ? ((Component)obj).GetComponent<Button>() : null);
				if ((Object)(object)panel.ListContainer == (Object)null || (Object)(object)panel.Close == (Object)null)
				{
					Object.Destroy((Object)(object)val);
					return null;
				}
				Transform obj2 = ((Transform)panel.Frame).Find("topic");
				panel.Title = ((obj2 != null) ? ((Component)obj2).GetComponent<TMP_Text>() : null);
				Transform val2 = val.transform.Find("Closebutton");
				Transform val3 = val.transform.Find("darken");
				Transform val4 = val.transform.Find("blur");
				if (keepBackdrop)
				{
					panel.Backdrop = ((val2 != null) ? ((Component)val2).GetComponent<Button>() : null);
				}
				else
				{
					if (val2 != null)
					{
						((Component)val2).gameObject.SetActive(false);
					}
					if (val3 != null)
					{
						((Component)val3).gameObject.SetActive(false);
					}
					if (val4 != null)
					{
						((Component)val4).gameObject.SetActive(false);
					}
				}
				Transform obj3 = ((Transform)panel.Frame).Find("totalskills_topic");
				if (obj3 != null)
				{
					((Component)obj3).gameObject.SetActive(false);
				}
				TMP_Text textTemplate = panel.TextTemplate;
				if (textTemplate != null)
				{
					((Component)textTemplate).gameObject.SetActive(false);
				}
				List<GameObject> list = new List<GameObject>();
				foreach (Transform item in (Transform)panel.ListRoot)
				{
					Transform val5 = item;
					if ((Object)(object)val5 != (Object)(object)panel.TooltipAnchor)
					{
						list.Add(((Component)val5).gameObject);
					}
				}
				foreach (GameObject item2 in list)
				{
					Object.DestroyImmediate((Object)(object)item2);
				}
				Rect rect = panel.ListRoot.rect;
				panel.BaseListHeight = ((Rect)(ref rect)).height;
				if ((Object)(object)panel.Title != (Object)null)
				{
					panel.Title.enableAutoSizing = true;
					panel.Title.fontSizeMin = 14f;
					panel.Title.fontSizeMax = panel.Title.fontSize;
				}
				return panel;
			}

			public float ReserveTop(float height)
			{
				//IL_0006: 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_0023: Unknown result type (might be due to invalid IL or missing references)
				//IL_0028: Unknown result type (might be due to invalid IL or missing references)
				//IL_0039: Unknown result type (might be due to invalid IL or missing references)
				//IL_0044: Unknown result type (might be due to invalid IL or missing references)
				//IL_0049: Unknown result type (might be due to invalid IL or missing references)
				float result = 0f - ListContainer.anchoredPosition.y;
				RectTransform listContainer = ListContainer;
				listContainer.anchoredPosition -= new Vector2(0f, height);
				RectTransform listContainer2 = ListContainer;
				listContainer2.sizeDelta -= new Vector2(0f, height);
				BaseListHeight = Mathf.Max(0f, BaseListHeight - height);
				return result;
			}

			public TMP_Text NewText(string name, float x, float top, float width, float height, float size, TextAlignmentOptions align)
			{
				//IL_0020: Unknown result type (might be due to invalid IL or missing references)
				//IL_0025: Unknown result type (might be due to invalid IL or missing references)
				//IL_0037: 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_00a8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b8: Expected O, but got Unknown
				//IL_0061: Unknown result type (might be due to invalid IL or missing references)
				TMP_Text val = ButtonLabel(Close);
				GameObject val2 = new GameObject(name, new Type[1] { typeof(RectTransform) });
				val2.transform.SetParent((Transform)(object)Frame, false);
				TextMeshProUGUI val3 = val2.AddComponent<TextMeshProUGUI>();
				if ((Object)(object)val != (Object)null)
				{
					((TMP_Text)val3).font = val.font;
					((TMP_Text)val3).fontSharedMaterial = val.fontSharedMaterial;
					((Graphic)val3).color = ((Graphic)val).color;
				}
				((TMP_Text)val3).fontSize = size;
				((TMP_Text)val3).enableAutoSizing = true;
				((TMP_Text)val3).fontSizeMin = 10f;
				((TMP_Text)val3).fontSizeMax = size;
				((TMP_Text)val3).alignment = align;
				((TMP_Text)val3).textWrappingMode = (TextWrappingModes)0;
				((Graphic)val3).raycastTarget = false;
				Place((RectTransform)val2.transform, x, top, width, height);
				return (TMP_Text)(object)val3;
			}

			public static void Place(RectTransform rt, float x, float top, float width, float height)
			{
				//IL_0013: 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)
				//IL_002a: 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_004f: Unknown result type (might be due to invalid IL or missing references)
				//IL_005a: Unknown result type (might be due to invalid IL or missing references)
				Vector2 val = default(Vector2);
				((Vector2)(ref val))..ctor(0.5f, 1f);
				rt.anchorMax = val;
				rt.anchorMin = val;
				rt.pivot = new Vector2(0.5f, 0.5f);
				rt.sizeDelta = new Vector2(width, height);
				rt.anchoredPosition = new Vector2(x, 0f - (top + height / 2f));
				((Transform)rt).localScale = Vector3.one;
			}

			public void SetTitle(string text)
			{
				if ((Object)(object)Title != (Object)null)
				{
					Title.text = text;
				}
			}

			public void SetRowCount(int count)
			{
				while (Rows.Count < count)
				{
					Rows.Add(Row.Create(this, Rows.Count));
				}
				for (int i = 0; i < Rows.Count; i++)
				{
					bool flag = i < count;
					if (Rows[i].Go.activeSelf != flag)
					{
						Rows[i].Go.SetActive(flag);
					}
				}
				ListRoot.SetSizeWithCurrentAnchors((Axis)1, Mathf.Max(BaseListHeight, (float)count * Spacing));
			}

			public void UpdateScrollbar()
			{
				//IL_0023: Unknown result type (might be due to invalid IL or missing references)
				//IL_0028: Unknown result type (might be due to invalid IL or missing references)
				//IL_004a: Unknown result type (might be due to invalid IL or missing references)
				//IL_004f: 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)
				if (!((Object)(object)Scrollbar == (Object)null) && !((Object)(object)Scroll == (Object)null))
				{
					Rect rect = ListRoot.rect;
					float height = ((Rect)(ref rect)).height;
					if (height > 0f)
					{
						Scrollbar scrollbar = Scrollbar;
						rect = ((RectTransform)((Component)Scroll).transform).rect;
						scrollbar.size = Mathf.Clamp01(((Rect)(ref rect)).height / height);
					}
				}
			}
		}

		internal class Row
		{
			public static readonly Color DoneColor = new Color(0.56f, 0.86f, 0.45f);

			public GameObject Go;

			public string Id;

			public Action OnClick;

			private Image _icon;

			private TMP_Text _name;

			private TMP_Text _level;

			private GuiBar _bar;

			private GuiBar _barTotal;

			private UITooltip _tooltip;

			private Color _nameColor;

			private Selectable _selectable;

			public static Row Create(Panel panel, int index)
			{
				//IL_0129: Unknown result type (might be due to invalid IL or missing references)
				//IL_012e: Unknown result type (might be due to invalid IL or missing references)
				//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
				//IL_01be: Expected O, but got Unknown
				//IL_0207: Unknown result type (might be due to invalid IL or missing references)
				//IL_021b: Unknown result type (might be due to invalid IL or missing references)
				GameObject val = Object.Instantiate<GameObject>(panel.ElementPrefab, (Transform)(object)panel.ListRoot, false);
				((Object)val).name = "Row";
				val.SetActive(true);
				Row obj = new Row
				{
					Go = val
				};
				Transform obj2 = Find(val, "icon");
				obj._icon = ((obj2 != null) ? ((Component)obj2).GetComponent<Image>() : null);
				Transform obj3 = Find(val, "name");
				obj._name = ((obj3 != null) ? ((Component)obj3).GetComponent<TMP_Text>() : null);
				Transform obj4 = Find(val, "leveltext");
				obj._level = ((obj4 != null) ? ((Component)obj4).GetComponent<TMP_Text>() : null);
				Transform obj5 = Find(val, "levelbar");
				obj._bar = ((obj5 != null) ? ((Component)obj5).GetComponent<GuiBar>() : null);
				Transform obj6 = Find(val, "levelbar_total");
				obj._barTotal = ((obj6 != null) ? ((Component)obj6).GetComponent<GuiBar>() : null);
				obj._tooltip = val.GetComponentInChildren<UITooltip>(true);
				obj._selectable = val.GetComponent<Selectable>();
				Row row = obj;
				Transform obj7 = Find(val, "currentlevel");
				if (obj7 != null)
				{
					((Component)obj7).gameObject.SetActive(false);
				}
				Transform obj8 = Find(val, "bonustext");
				if (obj8 != null)
				{
					((Component)obj8).gameObject.SetActive(false);
				}
				if ((Object)(object)row._name != (Object)null)
				{
					row._nameColor = ((Graphic)row._name).color;
					row._name.enableAutoSizing = true;
					row._name.fontSizeMin = 11f;
					row._name.fontSizeMax = row._name.fontSize;
				}
				if ((Object)(object)row._level != (Object)null)
				{
					row._level.enableAutoSizing = true;
					row._level.fontSizeMin = 10f;
					row._level.fontSizeMax = row._level.fontSize;
				}
				Button[] componentsInChildren = val.GetComponentsInChildren<Button>(true);
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					componentsInChildren[i].onClick = new ButtonClickedEvent();
				}
				if ((Object)(object)row._tooltip != (Object)null && (Object)(object)panel.TooltipPrefab != (Object)null)
				{
					row._tooltip.m_tooltipPrefab = panel.TooltipPrefab;
				}
				val.AddComponent<RowClick>().Row = row;
				((RectTransform)val.transform).anchoredPosition = new Vector2(0f, (float)(-index) * panel.Spacing);
				return row;
			}

			public void SetIcon(Sprite sprite, float alpha)
			{
				//IL_0043: Unknown result type (might be due to invalid IL or missing references)
				if (!((Object)(object)_icon == (Object)null))
				{
					_icon.sprite = sprite;
					((Behaviour)_icon).enabled = (Object)(object)sprite != (Object)null;
					((Graphic)_icon).color = new Color(1f, 1f, 1f, alpha);
				}
			}

			public void SetName(string text, Color? color)
			{
				//IL_0036: 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)
				if (!((Object)(object)_name == (Object)null))
				{
					_name.text = text;
					((Graphic)_name).color = (Color)(((??)color) ?? _nameColor);
				}
			}

			public void SetLevel(string text)
			{
				if ((Object)(object)_level != (Object)null)
				{
					_level.text = text;
				}
			}

			public void SetBar(float value)
			{
				GuiBar bar = _bar;
				if (bar != null)
				{
					bar.SetValue(value);
				}
				GuiBar barTotal = _barTotal;
				if (barTotal != null)
				{
					barTotal.SetValue(value);
				}
			}

			public void SetTooltip(string topic, string text)
			{
				//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)
				UITooltip tooltip = _tooltip;
				if (tooltip != null)
				{
					tooltip.Set(topic, text, (RectTransform)null, default(Vector2));
				}
			}

			public void SetSelected(bool selected)
			{
				EventSystem current = EventSystem.current;
				if (selected && !((Object)(object)_selectable == (Object)null) && !((Object)(object)current == (Object)null))
				{
					GameObject currentSelectedGameObject = current.currentSelectedGameObject;
					if (!((Object)(object)currentSelectedGameObject == (Object)(object)Go) && (!((Object)(object)currentSelectedGameObject != (Object)null) || !((Object)(object)currentSelectedGameObject.GetComponent<TMP_InputField>() != (Object)null)))
					{
						current.SetSelectedGameObject(Go);
					}
				}
			}

			private static Transform Find(GameObject go, string name)
			{
				Transform[] componentsInChildren = go.GetComponentsInChildren<Transform>(true);
				foreach (Transform val in componentsInChildren)
				{
					if (((Object)val).name == name)
					{
						return val;
					}
				}
				return null;
			}
		}

		internal class RowClick : MonoBehaviour, IPointerClickHandler, IEventSystemHandler
		{
			public Row Row;

			public void OnPointerClick(PointerEventData eventData)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				if ((int)eventData.button == 0 && Row?.OnClick != null)
				{
					Row.OnClick();
				}
			}
		}

		private const float FrameGap = 12f;

		private const float RefreshSeconds = 2f;

		private const float SearchHeaderHeight = 36f;

		private const float DetailHeaderHeight = 64f;

		private static readonly Color Orange = new Color(1f, 0.65f, 0.1f);

		private Panel _main;

		private Panel _detail;

		private readonly List<Button> _filterButtons = new List<Button>();

		private Button _toggleDoneButton;

		private TMP_InputField _search;

		private TMP_Text _summary;

		private TMP_Text _description;

		private Color _labelColor = Color.white;

		private List<AchievementEntry> _entries = new List<AchievementEntry>();

		private readonly List<AchievementEntry> _visible = new List<AchievementEntry>();

		private readonly List<Requirement> _visibleReqs = new List<Requirement>();

		private string _selectedId;

		private Filter _filter;

		private bool _showDone;

		private float _refreshTimer;

		private readonly Dictionary<string, Sprite> _icons = new Dictionary<string, Sprite>();

		public bool Exists
		{
			get
			{
				if ((Object)(object)_main?.Root != (Object)null)
				{
					return (Object)(object)_detail?.Root != (Object)null;
				}
				return false;
			}
		}

		public bool Show()
		{
			if (!Exists && !Build())
			{
				return false;
			}
			_main.Root.SetActive(true);
			_detail.Root.SetActive(true);
			_main.Root.transform.SetAsLastSibling();
			_detail.Root.transform.SetAsLastSibling();
			Refresh();
			_main.Scroll.verticalNormalizedPosition = 1f;
			return true;
		}

		public void Hide()
		{
			UITooltip.HideTooltip();
			if ((Object)(object)_search != (Object)null)
			{
				_search.DeactivateInputField(false);
			}
			if ((Object)(object)_main?.Root != (Object)null)
			{
				_main.Root.SetActive(false);
			}
			if ((Object)(object)_detail?.Root != (Object)null)
			{
				_detail.Root.SetActive(false);
			}
		}

		public void Tick()
		{
			if (Exists)
			{
				_refreshTimer += Time.unscaledDeltaTime;
				if (_refreshTimer >= 2f)
				{
					Refresh();
				}
				_main.UpdateScrollbar();
				_detail.UpdateScrollbar();
			}
		}

		private bool Build()
		{
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			SkillsDialog val = (((Object)(object)InventoryGui.instance != (Object)null) ? InventoryGui.instance.m_skillsDialog : null);
			Canvas val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponentInParent<Canvas>(true) : null);
			if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null)
			{
				Plugin.Log.LogWarning((object)"Skills dialog not found; can't build the tracker window yet.");
				return false;
			}
			Transform transform = ((Component)val2.rootCanvas).transform;
			_main = Panel.Clone(val, transform, "AchievementTracker_List", keepBackdrop: true);
			_detail = Panel.Clone(val, transform, "AchievementTracker_Detail", keepBackdrop: false);
			if (_main == null || _detail == null)
			{
				Plugin.Log.LogError((object)"The Skills dialog layout changed; can't build the tracker window.");
				Object.Destroy((Object)(object)_main?.Root);
				Object.Destroy((Object)(object)_detail?.Root);
				_main = (_detail = null);
				return false;
			}
			Rect rect = _main.Frame.rect;
			float num = ((Rect)(ref rect)).width / 2f + 6f;
			_main.Frame.anchoredPosition = new Vector2(0f - num, 0f);
			_detail.Frame.anchoredPosition = new Vector2(num, 0f);
			if ((Object)(object)_main.Backdrop != (Object)null)
			{
				Rebind(_main.Backdrop, Plugin.RequestClose);
			}
			_main.SetTitle("Achievements");
			TMP_Text obj = ButtonLabel(_main.Close);
			_labelColor = ((obj != null) ? ((Graphic)obj).color : Color.white);
			BuildFilterButtons();
			BuildSearchHeader();
			BuildDetailHeader();
			_toggleDoneButton = _detail.Close;
			Rebind(_toggleDoneButton, delegate
			{
				_showDone = !_showDone;
				RefreshDetail();
			});
			InventoryGrid playerGrid = InventoryGui.instance.m_playerGrid;
			object obj2;
			if (playerGrid == null)
			{
				obj2 = null;
			}
			else
			{
				GameObject elementPrefab = playerGrid.m_elementPrefab;
				obj2 = ((elementPrefab == null) ? null : elementPrefab.GetComponentInChildren<UITooltip>(true)?.m_tooltipPrefab);
			}
			GameObject tooltipPrefab = (GameObject)obj2;
			_main.TooltipPrefab = (_detail.TooltipPrefab = tooltipPrefab);
			HideInputHints(_main.Root);
			HideInputHints(_detail.Root);
			BuildIconLookup();
			return true;
		}

		private static void HideInputHints(GameObject root)
		{
			Component[] componentsInChildren = root.GetComponentsInChildren<Component>(true);
			foreach (Component val in componentsInChildren)
			{
				if ((Object)(object)val != (Object)null && ((object)val).GetType().Name == "UIInputHint")
				{
					val.gameObject.SetActive(false);
				}
			}
		}

		private void BuildFilterButtons()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			//IL_005e: 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_009e: 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_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)
			Button close = _main.Close;
			RectTransform val = (RectTransform)((Component)close).transform;
			string[] array = new string[4] { "All", "Active", "Done", "Close" };
			float num = (_main.ListWidth - 6f * (float)(array.Length - 1)) / (float)array.Length;
			Vector2 anchoredPosition = val.anchoredPosition;
			for (int i = 0; i < array.Length; i++)
			{
				Button val2 = ((i == array.Length - 1) ? close : Object.Instantiate<GameObject>(((Component)close).gameObject, ((Component)close).transform.parent, false).GetComponent<Button>());
				RectTransform val3 = (RectTransform)((Component)val2).transform;
				val3.SetSizeWithCurrentAnchors((Axis)0, num);
				val3.anchoredPosition = new Vector2(((float)i - (float)(array.Length - 1) / 2f) * (num + 6f), anchoredPosition.y);
				TMP_Text val4 = ButtonLabel(val2);
				if ((Object)(object)val4 != (Object)null)
				{
					val4.text = array[i];
					val4.enableAutoSizing = true;
					val4.fontSizeMin = 12f;
					val4.fontSizeMax = val4.fontSize;
				}
				if (i == array.Length - 1)
				{
					Rebind(val2, Plugin.RequestClose);
					continue;
				}
				Filter f = (Filter)i;
				Rebind(val2, delegate
				{
					_filter = f;
					RefreshMain();
				});
				_filterButtons.Add(val2);
			}
		}

		private void BuildSearchHeader()
		{
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Expected O, but got Unknown
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Expected O, but got Unknown
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Expected O, but got Unknown
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Expected O, but got Unknown
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Expected O, but got Unknown
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Expected O, but got Unknown
			float top = _main.ReserveTop(36f);
			float listWidth = _main.ListWidth;
			_summary = _main.NewText("Summary", (0f - listWidth) / 2f + (listWidth - 150f) + 75f, top, 150f, 36f, 16f, (TextAlignmentOptions)4100);
			Component val = (Component)(((Object)(object)Hud.instance != (Object)null) ? /*isinst with value type is only supported in some contexts*/: null);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			GameObject val2 = Object.Instantiate<GameObject>(val.gameObject, (Transform)(object)_main.Frame, false);
			((Object)val2).name = "Search";
			val2.SetActive(true);
			_search = val2.GetComponent<TMP_InputField>();
			if ((Object)(object)_search == (Object)null)
			{
				Object.Destroy((Object)(object)val2);
				return;
			}
			float num = listWidth - 150f - 8f;
			Panel.Place((RectTransform)val2.transform, (0f - listWidth) / 2f + num / 2f, top, num, 32f);
			_search.text = "";
			Graphic placeholder = _search.placeholder;
			TMP_Text val3 = (TMP_Text)(object)((placeholder is TMP_Text) ? placeholder : null);
			if (val3 != null)
			{
				val3.text = "Search...";
			}
			_search.onValueChanged = new OnChangeEvent();
			_search.onSelect = new SelectionEvent();
			_search.onDeselect = new SelectionEvent();
			_search.onEndEdit = new SubmitEvent();
			_search.onSubmit = new SubmitEvent();
			((UnityEvent<string>)(object)_search.onValueChanged).AddListener((UnityAction<string>)delegate
			{
				RefreshMain();
			});
		}

		private void BuildDetailHeader()
		{
			float top = _detail.ReserveTop(64f);
			_description = _detail.NewText("Description", 0f, top, _detail.ListWidth, 64f, 16f, (TextAlignmentOptions)257);
			_description.textWrappingMode = (TextWrappingModes)1;
		}

		private void BuildIconLookup()
		{
			_icons.Clear();
			if ((Object)(object)ObjectDB.instance == (Object)null)
			{
				return;
			}
			foreach (GameObject item in ObjectDB.instance.m_items)
			{
				SharedData val = (((Object)(object)item != (Object)null) ? item.GetComponent<ItemDrop>() : null)?.m_itemData?.m_shared;
				if (val != null && !string.IsNullOrEmpty(val.m_name) && val.m_icons != null && val.m_icons.Length != 0 && !_icons.ContainsKey(val.m_name))
				{
					_icons[val.m_name] = val.m_icons[0];
				}
			}
			try
			{
				foreach (Piece allBuildPiece in ObjectDB.instance.GetAllBuildPieces(true))
				{
					if ((Object)(object)allBuildPiece != (Object)null && (Object)(object)allBuildPiece.m_icon != (Object)null && !string.IsNullOrEmpty(allBuildPiece.m_name) && !_icons.ContainsKey(allBuildPiece.m_name))
					{
						_icons[allBuildPiece.m_name] = allBuildPiece.m_icon;
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogDebug((object)("Piece icons unavailable: " + ex.Message));
			}
		}

		private void Refresh()
		{
			_refreshTimer = 0f;
			_entries = AchievementData.Build();
			RefreshMain();
		}

		private void RefreshMain()
		{
			//IL_013c: 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)
			string text = (((Object)(object)_search != (Object)null) ? _search.text.Trim() : "");
			_visible.Clear();
			foreach (AchievementEntry entry in _entries)
			{
				if ((_filter != Filter.Active || !entry.Done) && (_filter != Filter.Done || entry.Done) && (text.Length <= 0 || Matches(entry, text)))
				{
					_visible.Add(entry);
				}
			}
			if (_filter == Filter.Active)
			{
				_visible.Sort((AchievementEntry a, AchievementEntry b) => (b.Progress == a.Progress) ? a.Order.CompareTo(b.Order) : b.Progress.CompareTo(a.Progress));
			}
			else
			{
				_visible.Sort((AchievementEntry a, AchievementEntry b) => (a.Tier == b.Tier) ? a.Order.CompareTo(b.Order) : a.Tier.CompareTo(b.Tier));
			}
			for (int num = 0; num < _filterButtons.Count; num++)
			{
				TMP_Text val = ButtonLabel(_filterButtons[num]);
				if ((Object)(object)val != (Object)null)
				{
					((Graphic)val).color = ((num == (int)_filter) ? Orange : _labelColor);
				}
			}
			int num2 = 0;
			int num3 = 0;
			bool flag = false;
			foreach (AchievementEntry entry2 in _entries)
			{
				if (entry2.Done)
				{
					num2++;
				}
				if (entry2.SteamDone.HasValue)
				{
					flag = true;
					if (entry2.SteamDone.Value)
					{
						num3++;
					}
				}
			}
			if ((Object)(object)_summary != (Object)null)
			{
				StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.Append(AchievementData.CanEarn ? $"<color=orange>{num2}</color> / {_entries.Count}" : "<color=#ff7040>Not recording</color>");
				if (flag)
				{
					stringBuilder.Append($"\n<size=75%>Steam <color=#8cc0ff>{num3}</color> / {_entries.Count}</size>");
				}
				_summary.text = stringBuilder.ToString();
			}
			_main.SetRowCount(_visible.Count);
			for (int num4 = 0; num4 < _visible.Count; num4++)
			{
				FillAchievementRow(_main.Rows[num4], _visible[num4]);
			}
			if (_selectedId == null || _entries.Find((AchievementEntry e) => e.Source.m_id == _selectedId) == null)
			{
				_selectedId = ((_visible.Count > 0) ? _visible[0].Source.m_id : null);
			}
			RefreshDetail();
		}

		private void FillAchievementRow(Row row, AchievementEntry e)
		{
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			bool hidden = e.Hidden;
			string text = ((e.SteamDone == true && !e.Done) ? "  <size=70%><color=#8cc0ff>Steam</color></size>" : "");
			row.SetIcon((e.Done || e.SteamDone == true) ? e.Source.m_icon : e.Source.m_iconLocked, 1f);
			row.SetName((hidden ? "???" : e.Name) + text, e.Done ? new Color?(Row.DoneColor) : ((Color?)null));
			row.SetLevel(e.Done ? "Done" : $"{Mathf.FloorToInt(e.Progress * 100f)}%");
			row.SetBar(e.Progress);
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append(hidden ? "Secret achievement. Keep playing to discover it." : e.Description);
			if (!hidden && e.Requirements.Count > 0)
			{
				stringBuilder.Append($"\n\n{e.Met} / {e.Requirements.Count} requirements met");
			}
			if (e.Difficulty != null)
			{
				stringBuilder.Append("\nCounts on " + e.Difficulty + " difficulty worlds");
			}
			if (e.SteamDone == true)
			{
				stringBuilder.Append("\n<color=#8cc0ff>Unlocked on your Steam account</color>");
			}
			row.SetTooltip(hidden ? "???" : e.Name, stringBuilder.ToString());
			string id = e.Source.m_id;
			row.Id = id;
			row.OnClick = delegate
			{
				_selectedId = id;
				_showDone = false;
				RefreshDetail();
				_detail.Scroll.verticalNormalizedPosition = 1f;
			};
		}

		private void RefreshDetail()
		{
			//IL_0324: Unknown result type (might be due to invalid IL or missing references)
			AchievementEntry achievementEntry = ((_selectedId != null) ? _entries.Find((AchievementEntry x) => x.Source.m_id == _selectedId) : null);
			foreach (Row row2 in _main.Rows)
			{
				row2.SetSelected(row2.Go.activeSelf && _selectedId != null && row2.Id == _selectedId);
			}
			if (achievementEntry == null || achievementEntry.Hidden)
			{
				_detail.SetTitle((achievementEntry == null) ? "Details" : "???");
				if ((Object)(object)_description != (Object)null)
				{
					_description.text = ((achievementEntry == null) ? "Select an achievement." : "Secret achievement.");
				}
				_detail.SetRowCount(0);
				((Component)_toggleDoneButton).gameObject.SetActive(false);
				return;
			}
			_detail.SetTitle(achievementEntry.Name);
			string text = (achievementEntry.Done ? "<color=#8fdc72>Complete</color>" : ((achievementEntry.Requirements.Count > 0) ? $"<color=orange>{achievementEntry.Met}</color> / {achievementEntry.Requirements.Count} done" : "Special condition"));
			if (achievementEntry.Difficulty != null)
			{
				text = text + "  <color=#a89f8c>(" + achievementEntry.Difficulty + " difficulty)</color>";
			}
			if ((Object)(object)_description != (Object)null)
			{
				_description.text = achievementEntry.Description + "\n<size=85%>" + text + "</size>";
			}
			_visibleReqs.Clear();
			int num = 0;
			foreach (Requirement requirement2 in achievementEntry.Requirements)
			{
				if (requirement2.Met)
				{
					num++;
					if (!_showDone)
					{
						continue;
					}
				}
				_visibleReqs.Add(requirement2);
			}
			((Component)_toggleDoneButton).gameObject.SetActive(num > 0);
			TMP_Text val = ButtonLabel(_toggleDoneButton);
			if ((Object)(object)val != (Object)null)
			{
				val.text = (_showDone ? "Hide done" : $"Show done ({num})");
			}
			Sprite val2 = (achievementEntry.Done ? achievementEntry.Source.m_icon : achievementEntry.Source.m_iconLocked);
			_detail.SetRowCount(_visibleReqs.Count);
			for (int num2 = 0; num2 < _visibleReqs.Count; num2++)
			{
				Requirement requirement = _visibleReqs[num2];
				Row row = _detail.Rows[num2];
				Sprite value;
				bool flag = _icons.TryGetValue(requirement.Key ?? "", out value);
				row.SetIcon(flag ? value : val2, flag ? 1f : 0.35f);
				row.SetName("<size=70%><color=#a89f8c>" + requirement.Category + "</color></size>  " + requirement.Label, requirement.Met ? new Color?(Row.DoneColor) : ((Color?)null));
				row.SetLevel(LevelText(requirement));
				row.SetBar(requirement.Fraction);
				row.SetTooltip(requirement.Label, requirement.Category + ": " + requirement.Label + "\n" + LevelText(requirement));
				row.OnClick = null;
				row.Id = null;
			}
		}

		private static string LevelText(Requirement r)
		{
			//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: Expected I4, but got Unknown
			RequirementOperator op = r.Op;
			return (int)op switch
			{
				0 => Num(Mathf.Min(r.Current, r.Needed)) + "/" + Num(r.Needed), 
				1 => "<=" + Num(r.Needed), 
				2 => "=" + Num(r.Needed), 
				_ => "!=" + Num(r.Needed), 
			};
		}

		private static string Num(float v)
		{
			return v.ToString((v % 1f == 0f) ? "0" : "0.#");
		}

		private static bool Matches(AchievementEntry e, string q)
		{
			if (e.Hidden)
			{
				return false;
			}
			if (Contains(e.Name, q) || Contains(e.Description, q))
			{
				return true;
			}
			foreach (Requirement requirement in e.Requirements)
			{
				if (Contains(requirement.Label, q))
				{
					return true;
				}
			}
			return false;
		}

		private static bool Contains(string s, string q)
		{
			if (s != null)
			{
				return s.IndexOf(q, StringComparison.OrdinalIgnoreCase) >= 0;
			}
			return false;
		}

		private static void Rebind(Button b, Action action)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected O, but got Unknown
			b.onClick = new ButtonClickedEvent();
			((UnityEvent)b.onClick).AddListener((UnityAction)delegate
			{
				action();
			});
		}

		private static TMP_Text ButtonLabel(Button b)
		{
			object obj2;
			if (!((Object)(object)b == (Object)null))
			{
				Transform obj = ((Component)b).transform.Find("Text");
				obj2 = ((obj != null) ? ((Component)obj).GetComponent<TMP_Text>() : null);
				if (obj2 == null)
				{
					return ((Component)b).GetComponentInChildren<TMP_Text>(true);
				}
			}
			else
			{
				obj2 = null;
			}
			return (TMP_Text)obj2;
		}
	}
	[BepInPlugin("Dirtsnack.AchievementTracker", "Achievement Tracker", "0.1.0")]
	public class Plugin : BaseUnityPlugin
	{
		public const string ModGuid = "Dirtsnack.AchievementTracker";

		public const string ModName = "Achievement Tracker";

		public const string ModVersion = "0.1.0";

		internal static ManualLogSource Log;

		internal static ConfigEntry<KeyboardShortcut> ToggleKey;

		internal static ConfigEntry<bool> RevealSecrets;

		internal static bool IsOpen;

		private readonly NativeWindow _window = new NativeWindow();

		private static bool _closeRequested;

		private void Awake()
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			ToggleKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "ToggleKey", new KeyboardShortcut((KeyCode)288, Array.Empty<KeyCode>()), "Opens and closes the tracker.");
			RevealSecrets = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "RevealSecrets", false, "Show the names and requirements of secret achievements before you unlock them.");
			new Harmony("Dirtsnack.AchievementTracker").PatchAll();
			Log.LogInfo((object)string.Format("{0} {1} loaded. Press {2} in game.", "Achievement Tracker", "0.1.0", ToggleKey.Value));
		}

		private void Update()
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Player.m_localPlayer == (Object)null || (Object)(object)Achievements.m_instance == (Object)null)
			{
				if (IsOpen)
				{
					Close();
				}
				return;
			}
			if (IsOpen && ZInput.GetKeyDown((KeyCode)27, false))
			{
				_closeRequested = true;
			}
			else if (IsShortcutDown(ToggleKey.Value) && (IsOpen || !IsTyping()))
			{
				if (IsOpen)
				{
					_closeRequested = true;
				}
				else
				{
					Open();
				}
			}
			if (IsOpen)
			{
				_window.Tick();
			}
		}

		private void LateUpdate()
		{
			if (_closeRequested)
			{
				_closeRequested = false;
				Close();
			}
		}

		internal static void RequestClose()
		{
			_closeRequested = true;
		}

		private void Open()
		{
			IsOpen = _window.Show();
		}

		private void Close()
		{
			IsOpen = false;
			_window.Hide();
		}

		private static bool IsTyping()
		{
			if ((!((Object)(object)Chat.instance != (Object)null) || !Chat.instance.HasFocus()) && !Console.IsVisible() && !TextInput.IsVisible() && !Minimap.InTextInput())
			{
				if ((Object)(object)Hud.instance != (Object)null)
				{
					return Hud.instance.m_buildUi.SearchFieldFocused;
				}
				return false;
			}
			return true;
		}

		private static bool IsShortcutDown(KeyboardShortcut shortcut)
		{
			//IL_0002: 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)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			if ((int)((KeyboardShortcut)(ref shortcut)).MainKey == 0 || !ZInput.GetKeyDown(((KeyboardShortcut)(ref shortcut)).MainKey, false))
			{
				return false;
			}
			foreach (KeyCode modifier in ((KeyboardShortcut)(ref shortcut)).Modifiers)
			{
				if (!ZInput.GetKey(modifier, false))
				{
					return false;
				}
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(TextInput), "IsVisible")]
	internal static class TextInput_IsVisible_Patch
	{
		private static void Postfix(ref bool __result)
		{
			__result |= Plugin.IsOpen;
		}
	}
	[HarmonyPatch(typeof(ZInput), "GetMouseScrollWheel")]
	internal static class ZInput_GetMouseScrollWheel_Patch
	{
		private static void Postfix(ref float __result)
		{
			if (Plugin.IsOpen)
			{
				__result = 0f;
			}
		}
	}
}