Decompiled source of RunestoneRecords v1.3.1

plugins/RunestoneRecords.dll

Decompiled 14 hours ago
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
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;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Jotunn.Managers;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("RunestoneRecords")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.3.1.0")]
[assembly: AssemblyInformationalVersion("1.3.1")]
[assembly: AssemblyProduct("RunestoneRecords")]
[assembly: AssemblyTitle("RunestoneRecords")]
[assembly: AssemblyVersion("1.3.1.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 RunestoneRecords
{
	[BepInPlugin("local.runestonerecords", "Runestone Records", "1.3.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class Plugin : BaseUnityPlugin
	{
		public const string PluginGuid = "local.runestonerecords";

		public const string PluginName = "Runestone Records";

		public const string PluginVersion = "1.3.1";

		private const string PreviousPluginGuid = "local.valheimcito.achievements";

		internal static ConfigEntry<bool> Enabled;

		private static Plugin instance;

		private ConfigEntry<bool> windowEnabled;

		private ConfigEntry<KeyboardShortcut> toggleKey;

		private ConfigEntry<bool> hideLockedSecrets;

		private ConfigEntry<float> windowWidth;

		private ConfigEntry<float> windowHeight;

		private ConfigEntry<bool> trackerEnabled;

		private ConfigEntry<string> pinnedByCharacter;

		private ConfigEntry<float> trackerX;

		private ConfigEntry<float> trackerY;

		private ConfigEntry<float> trackerScale;

		private Harmony harmony;

		private readonly AchievementReader reader = new AchievementReader();

		private readonly List<string> trackedIds = new List<string>();

		private AchievementWindow window;

		private AchievementTracker tracker;

		private AchievementSnapshot snapshot = AchievementSnapshot.Waiting("Loading...");

		private long characterId;

		private Vector2 trackerPosition;

		private float trackerScaleValue;

		private bool inputBlocked;

		private bool readyLogged;

		private float nextRefresh;

		private int screenWidth;

		private int screenHeight;

		internal IReadOnlyList<string> TrackedIds => trackedIds;

		internal Vector2 TrackerPosition => trackerPosition;

		internal float TrackerScale => trackerScaleValue;

		internal bool ShowTracker
		{
			get
			{
				if (trackerEnabled != null && trackerEnabled.Value)
				{
					return trackedIds.Count > 0;
				}
				return false;
			}
		}

		internal bool HideLockedSecrets
		{
			get
			{
				if (hideLockedSecrets != null)
				{
					return hideLockedSecrets.Value;
				}
				return false;
			}
		}

		internal Vector2 WindowSize => new Vector2(windowWidth.Value, windowHeight.Value);

		private void Awake()
		{
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Unknown result type (might be due to invalid IL or missing references)
			//IL_021a: Expected O, but got Unknown
			//IL_0251: Unknown result type (might be due to invalid IL or missing references)
			//IL_025f: Expected O, but got Unknown
			//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c7: Expected O, but got Unknown
			//IL_02ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_030d: Expected O, but got Unknown
			instance = this;
			bool num = MigratePreviousSettings();
			Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "EnableAchievementsWithMods", true, "Allow achievement progress while BepInEx or other mods are installed.");
			windowEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Window", "Enabled", true, "Enable the full achievement window.");
			toggleKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Window", "ToggleKey", new KeyboardShortcut((KeyCode)288, Array.Empty<KeyCode>()), "Open or close the achievement window.");
			hideLockedSecrets = ((BaseUnityPlugin)this).Config.Bind<bool>("Window", "HideLockedSecrets", false, "Hide locked secret achievements. Completed secrets remain visible. Hidden secret pins are removed.");
			windowWidth = ((BaseUnityPlugin)this).Config.Bind<float>("Window", "Width", 1080f, "Achievement journal width in UI units. Drag its lower-right corner to change this.");
			windowHeight = ((BaseUnityPlugin)this).Config.Bind<float>("Window", "Height", 700f, "Achievement journal height in UI units. Drag its lower-right corner to change this.");
			trackerEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Tracker", "Enabled", true, "Show pinned achievements below the minimap.");
			pinnedByCharacter = ((BaseUnityPlugin)this).Config.Bind<string>("Tracker", "PinnedByCharacter", "", "Up to three achievement IDs per character. Maintained by the achievement window.");
			trackerX = ((BaseUnityPlugin)this).Config.Bind<float>("Tracker", "PositionX", -20f, "Tracker position from the right screen edge.");
			trackerY = ((BaseUnityPlugin)this).Config.Bind<float>("Tracker", "PositionY", -235f, "Tracker position from the top screen edge.");
			trackerScale = ((BaseUnityPlugin)this).Config.Bind<float>("Tracker", "Scale", 1f, "Tracker size multiplier. Drag its lower-right corner while the journal is open to change this.");
			if (num)
			{
				((BaseUnityPlugin)this).Config.Save();
			}
			trackerPosition = new Vector2(trackerX.Value, trackerY.Value);
			trackerScaleValue = trackerScale.Value;
			window = new AchievementWindow(this);
			tracker = new AchievementTracker(this);
			hideLockedSecrets.SettingChanged += OnHideLockedSecretsChanged;
			harmony = new Harmony("local.runestonerecords");
			MethodInfo methodInfo = AccessTools.Method(typeof(Achievements), "CanGetAchievements", (Type[])null, (Type[])null);
			if (methodInfo != null)
			{
				harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(Plugin), "AllowAchievementsPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Achievement progress is enabled for this modded client.");
			}
			else
			{
				((BaseUnityPlugin)this).Logger.LogError((object)"Valheim's achievement gate changed; achievement eligibility was not modified.");
			}
			MethodInfo methodInfo2 = AccessTools.Method(typeof(InventoryGui), "OnOpenAchievements", (Type[])null, (Type[])null);
			if (methodInfo2 != null)
			{
				harmony.Patch((MethodBase)methodInfo2, new HarmonyMethod(typeof(Plugin), "OpenInventoryAchievementsPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			MethodInfo methodInfo3 = AccessTools.Method(typeof(Menu), "Update", (Type[])null, (Type[])null);
			if (methodInfo3 != null)
			{
				harmony.Patch((MethodBase)methodInfo3, new HarmonyMethod(typeof(Plugin), "MenuUpdatePrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			GUIManager.OnCustomGUIAvailable += OnCustomGuiAvailable;
			SceneManager.activeSceneChanged += OnSceneChanged;
			EnsureUi();
		}

		private bool MigratePreviousSettings()
		{
			string text = Path.Combine(Paths.ConfigPath, "local.valheimcito.achievements.cfg");
			string configFilePath = ((BaseUnityPlugin)this).Config.ConfigFilePath;
			if (!File.Exists(text) || File.Exists(configFilePath))
			{
				return false;
			}
			try
			{
				File.Copy(text, configFilePath);
				((BaseUnityPlugin)this).Config.Reload();
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Imported settings from the previous achievement plugin.");
				return true;
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not import previous achievement settings: " + ex));
				return false;
			}
		}

		private void OnCustomGuiAvailable()
		{
			EnsureUi();
		}

		private void OnSceneChanged(Scene previous, Scene next)
		{
			CloseWindow();
			window?.Dispose();
			tracker?.Dispose();
			readyLogged = false;
			snapshot = AchievementSnapshot.Waiting("Loading...");
			characterId = 0L;
			trackedIds.Clear();
		}

		private bool EnsureUi()
		{
			if ((Object)(object)GUIManager.CustomGUIFront == (Object)null)
			{
				return false;
			}
			try
			{
				if (!window.Exists)
				{
					window.Create();
				}
				if (!tracker.Exists)
				{
					tracker.Create();
				}
				if (window.Exists && tracker.Exists && !readyLogged)
				{
					readyLogged = true;
					((BaseUnityPlugin)this).Logger.LogInfo((object)("Runestone Records ready | " + ((object)this).GetType().Assembly.GetName().Name));
				}
				return window.Exists && tracker.Exists;
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("Achievement window creation failed: " + ex));
				CloseWindow();
				window.Dispose();
				tracker.Dispose();
				return false;
			}
		}

		private void Update()
		{
			//IL_0217: Unknown result type (might be due to invalid IL or missing references)
			if (!windowEnabled.Value && window.IsOpen)
			{
				CloseWindow();
			}
			if (windowEnabled.Value && ShortcutPressed())
			{
				if (window.HasTextFocus || HasOtherTextFocus())
				{
					((BaseUnityPlugin)this).Logger.LogInfo((object)"Achievement shortcut ignored while a text field has focus.");
				}
				else if (window.IsOpen)
				{
					CloseWindow();
				}
				else if (CanOpen())
				{
					if (OpenWindow())
					{
						((BaseUnityPlugin)this).Logger.LogInfo((object)"Achievement shortcut opened the window.");
					}
				}
				else
				{
					((BaseUnityPlugin)this).Logger.LogInfo((object)"Achievement shortcut ignored while another game menu or text entry is active.");
				}
			}
			if (!window.Exists && inputBlocked)
			{
				CloseWindow();
			}
			if (Time.unscaledTime < nextRefresh)
			{
				return;
			}
			nextRefresh = Time.unscaledTime + 0.5f;
			try
			{
				if (windowEnabled.Value)
				{
					EnsureUi();
				}
				Game val = Game.instance;
				PlayerProfile val2 = (((Object)(object)val == (Object)null) ? null : val.GetPlayerProfile());
				long num = ((val2 == null) ? 0 : val2.GetPlayerID());
				if (num != characterId)
				{
					if (window.IsOpen)
					{
						CloseWindow();
					}
					characterId = num;
					LoadPins();
				}
				if (window.IsOpen || trackedIds.Count > 0 || snapshot.Items.Count == 0)
				{
					snapshot = reader.Read();
				}
				PruneHiddenPins();
				if (window.IsOpen)
				{
					window.SetSnapshot(snapshot);
				}
				tracker.Update(snapshot, window.IsOpen, trackerEnabled.Value);
				if (Screen.width != screenWidth || Screen.height != screenHeight || window.CanvasSizeChanged)
				{
					screenWidth = Screen.width;
					screenHeight = Screen.height;
					window.Resize();
					tracker.SetPosition(trackerPosition);
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("Achievement display refresh failed: " + ex));
				snapshot = AchievementSnapshot.Waiting("Achievement progress is temporarily unavailable.");
				if (window.IsOpen)
				{
					window.SetSnapshot(snapshot);
				}
			}
		}

		private static bool HasOtherTextFocus()
		{
			GameObject val = (((Object)(object)EventSystem.current == (Object)null) ? null : EventSystem.current.currentSelectedGameObject);
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			InputField componentInParent = val.GetComponentInParent<InputField>();
			TMP_InputField componentInParent2 = val.GetComponentInParent<TMP_InputField>();
			if (!((Object)(object)componentInParent != (Object)null) || !componentInParent.isFocused)
			{
				if ((Object)(object)componentInParent2 != (Object)null)
				{
					return componentInParent2.isFocused;
				}
				return false;
			}
			return true;
		}

		private bool ShortcutPressed()
		{
			//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)
			//IL_000e: 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_0038: Unknown result type (might be due to invalid IL or missing references)
			KeyboardShortcut value = toggleKey.Value;
			if ((int)((KeyboardShortcut)(ref value)).MainKey == 0)
			{
				return false;
			}
			bool flag = ZInput.GetKeyDown(((KeyboardShortcut)(ref value)).MainKey, true);
			if (flag)
			{
				foreach (KeyCode modifier in ((KeyboardShortcut)(ref value)).Modifiers)
				{
					if (!ZInput.GetKey(modifier, true))
					{
						flag = false;
						break;
					}
				}
			}
			if (!flag)
			{
				return ((KeyboardShortcut)(ref value)).IsDown();
			}
			return true;
		}

		private static bool CanOpen()
		{
			if ((Object)(object)Game.instance != (Object)null && (Object)(object)Player.m_localPlayer != (Object)null && !Menu.IsVisible() && !Console.IsVisible() && (!((Object)(object)Chat.instance != (Object)null) || !Chat.instance.HasFocus()))
			{
				return !TextInput.IsVisible();
			}
			return false;
		}

		internal bool OpenWindow()
		{
			if (!windowEnabled.Value || !EnsureUi())
			{
				return false;
			}
			PlayerProfile val = (((Object)(object)Game.instance == (Object)null) ? null : Game.instance.GetPlayerProfile());
			long num = ((val == null) ? 0 : val.GetPlayerID());
			if (num != characterId)
			{
				characterId = num;
				LoadPins();
			}
			try
			{
				snapshot = reader.Read();
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("Achievement progress is unavailable: " + ex));
				snapshot = AchievementSnapshot.Waiting("Achievement progress is temporarily unavailable.");
			}
			PruneHiddenPins();
			window.Open(snapshot);
			if (!window.IsOpen)
			{
				return false;
			}
			if (!inputBlocked)
			{
				GUIManager.BlockInput(true);
				inputBlocked = true;
			}
			InventoryGui val2 = InventoryGui.instance;
			if ((Object)(object)val2 != (Object)null && InventoryGui.IsVisible())
			{
				val2.Hide();
			}
			tracker.Update(snapshot, windowOpen: true, trackerEnabled.Value);
			return true;
		}

		internal void CloseWindow()
		{
			window?.Close();
			if (inputBlocked)
			{
				GUIManager.BlockInput(false);
				inputBlocked = false;
			}
			tracker?.CloseModal();
		}

		internal bool IsTracked(string id)
		{
			return trackedIds.Contains(id);
		}

		internal void SetHideLockedSecrets(bool value)
		{
			if (hideLockedSecrets.Value != value)
			{
				hideLockedSecrets.Value = value;
				((BaseUnityPlugin)this).Config.Save();
			}
		}

		private void OnHideLockedSecretsChanged(object sender, EventArgs args)
		{
			if (HideLockedSecrets)
			{
				try
				{
					snapshot = reader.Read();
				}
				catch (Exception ex)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not refresh secret achievement visibility: " + ex));
					snapshot = AchievementSnapshot.Waiting("Achievement progress is temporarily unavailable.");
				}
			}
			PruneHiddenPins();
			window?.SetSnapshot(snapshot);
			window?.Resize();
			window?.RenderList();
			tracker?.Update(snapshot, window != null && window.IsOpen, trackerEnabled.Value);
		}

		private void PruneHiddenPins()
		{
			if (HideLockedSecrets && characterId != 0L && snapshot.CharacterId == characterId && snapshot.Items.Count != 0 && AchievementVisibility.RemoveHiddenPins(trackedIds, snapshot, hideLockedSecrets: true) > 0)
			{
				SavePins();
			}
		}

		internal void ToggleTracked(string id)
		{
			if (trackedIds.Remove(id))
			{
				SavePins();
				window.Resize();
				tracker.Update(snapshot, window.IsOpen, trackerEnabled.Value);
			}
			else if (trackedIds.Count < 3)
			{
				trackedIds.Add(id);
				SavePins();
				window.Resize();
				tracker.Update(snapshot, window.IsOpen, trackerEnabled.Value);
			}
		}

		private void LoadPins()
		{
			trackedIds.Clear();
			if (characterId == 0L)
			{
				return;
			}
			string[] array = pinnedByCharacter.Value.Split(new char[1] { ';' }, StringSplitOptions.RemoveEmptyEntries);
			foreach (string text in array)
			{
				int num = text.IndexOf('|');
				if (num < 0 || text.Substring(0, num) != characterId.ToString(CultureInfo.InvariantCulture))
				{
					continue;
				}
				string[] array2 = text.Substring(num + 1).Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries);
				foreach (string item in array2)
				{
					if (trackedIds.Count < 3 && !trackedIds.Contains(item))
					{
						trackedIds.Add(item);
					}
				}
				break;
			}
		}

		private void SavePins()
		{
			if (characterId != 0L)
			{
				string id = characterId.ToString(CultureInfo.InvariantCulture) + "|";
				List<string> list = (from @group in pinnedByCharacter.Value.Split(new char[1] { ';' }, StringSplitOptions.RemoveEmptyEntries)
					where !@group.StartsWith(id, StringComparison.Ordinal)
					select @group).ToList();
				if (trackedIds.Count > 0)
				{
					list.Add(id + string.Join(",", trackedIds));
				}
				pinnedByCharacter.Value = string.Join(";", list);
				((BaseUnityPlugin)this).Config.Save();
			}
		}

		internal void SaveTrackerPosition(Vector2 value)
		{
			//IL_0001: 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)
			trackerPosition = value;
		}

		internal void SaveTrackerScale(float value)
		{
			trackerScaleValue = value;
		}

		internal void PersistWindowSize(Vector2 value)
		{
			//IL_0006: 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)
			windowWidth.Value = Mathf.Round(value.x);
			windowHeight.Value = Mathf.Round(value.y);
			((BaseUnityPlugin)this).Config.Save();
		}

		internal void PersistTrackerPosition()
		{
			trackerX.Value = trackerPosition.x;
			trackerY.Value = trackerPosition.y;
			((BaseUnityPlugin)this).Config.Save();
		}

		internal void PersistTrackerLayout()
		{
			trackerX.Value = trackerPosition.x;
			trackerY.Value = trackerPosition.y;
			trackerScale.Value = trackerScaleValue;
			((BaseUnityPlugin)this).Config.Save();
		}

		private void OnDestroy()
		{
			if (hideLockedSecrets != null)
			{
				hideLockedSecrets.SettingChanged -= OnHideLockedSecretsChanged;
			}
			GUIManager.OnCustomGUIAvailable -= OnCustomGuiAvailable;
			SceneManager.activeSceneChanged -= OnSceneChanged;
			CloseWindow();
			window?.Dispose();
			tracker?.Dispose();
			Harmony obj = harmony;
			if (obj != null)
			{
				obj.UnpatchSelf();
			}
			if ((Object)(object)instance == (Object)(object)this)
			{
				instance = null;
			}
		}

		private static bool AllowAchievementsPrefix(ref bool __result)
		{
			if (Enabled == null || !Enabled.Value)
			{
				return true;
			}
			__result = true;
			return false;
		}

		private static bool OpenInventoryAchievementsPrefix(InventoryGui __instance)
		{
			if ((Object)(object)instance == (Object)null || !instance.windowEnabled.Value)
			{
				return true;
			}
			if (!instance.OpenWindow())
			{
				return true;
			}
			return false;
		}

		private static bool MenuUpdatePrefix()
		{
			if ((Object)(object)instance == (Object)null || instance.window == null || !instance.window.IsOpen)
			{
				return true;
			}
			if (ZInput.GetKeyDown((KeyCode)27, true) || ZInput.GetButtonDown("JoyButtonB"))
			{
				instance.CloseWindow();
			}
			return false;
		}
	}
	internal sealed class CriterionProgress
	{
		internal readonly string Label;

		internal readonly string Value;

		internal readonly float Fraction;

		internal readonly bool Met;

		internal readonly bool CollectionEntry;

		internal CriterionProgress(string label, string value, float fraction, bool met, bool collectionEntry)
		{
			Label = label;
			Value = value;
			Fraction = Math.Max(0f, Math.Min(1f, fraction));
			Met = met;
			CollectionEntry = collectionEntry;
		}
	}
	internal sealed class AchievementProgress
	{
		internal readonly string Id;

		internal readonly string Name;

		internal readonly string Description;

		internal readonly bool IsSecret;

		internal readonly string Category;

		internal readonly string Difficulty;

		internal readonly Sprite Icon;

		internal readonly bool Unlocked;

		internal readonly ReadOnlyCollection<CriterionProgress> Criteria;

		internal readonly int GameOrder;

		internal readonly float Fraction;

		internal readonly int MetCount;

		internal string Summary
		{
			get
			{
				if (!Unlocked)
				{
					if (Criteria.Count != 0)
					{
						if (Criteria.Count != 1)
						{
							int metCount = MetCount;
							return metCount + " / " + Criteria.Count + " requirements";
						}
						return Criteria[0].Value;
					}
					return "No recorded requirements";
				}
				return "Completed";
			}
		}

		internal CriterionProgress NextIncomplete => Criteria.FirstOrDefault((CriterionProgress c) => !c.Met);

		internal AchievementProgress(string id, string name, string description, string category, string difficulty, Sprite icon, bool unlocked, IList<CriterionProgress> criteria, int order, bool isSecret = false)
		{
			Id = id;
			Name = name;
			Description = description;
			IsSecret = isSecret;
			Category = category;
			Difficulty = difficulty;
			Icon = icon;
			Unlocked = unlocked;
			Criteria = new ReadOnlyCollection<CriterionProgress>(new List<CriterionProgress>(criteria));
			GameOrder = order;
			MetCount = Criteria.Count((CriterionProgress c) => c.Met);
			Fraction = (unlocked ? 1f : ((Criteria.Count == 0) ? 0f : Criteria.Average((CriterionProgress c) => c.Fraction)));
		}
	}
	internal sealed class AchievementSnapshot
	{
		internal readonly ReadOnlyCollection<AchievementProgress> Items;

		internal readonly string State;

		internal readonly long CharacterId;

		internal readonly string CatalogKey;

		internal readonly Dictionary<string, AchievementProgress> ById;

		internal AchievementSnapshot(IList<AchievementProgress> items, string state, long characterId)
		{
			Items = new ReadOnlyCollection<AchievementProgress>(new List<AchievementProgress>(items));
			State = state;
			CharacterId = characterId;
			ById = new Dictionary<string, AchievementProgress>(StringComparer.Ordinal);
			foreach (AchievementProgress item in Items)
			{
				ById[item.Id] = item;
			}
			CatalogKey = string.Join("|", Items.Select((AchievementProgress i) => i.Id + ":" + i.Criteria.Count + ":" + (i.Unlocked ? "1" : "0")));
		}

		internal static AchievementSnapshot Waiting(string state)
		{
			return new AchievementSnapshot(new List<AchievementProgress>(), state, 0L);
		}
	}
	internal static class AchievementVisibility
	{
		internal static bool IsVisible(AchievementProgress item, bool hideLockedSecrets)
		{
			if (hideLockedSecrets && item.IsSecret)
			{
				return item.Unlocked;
			}
			return true;
		}

		internal static bool IsVisibleInList(AchievementProgress item, bool hideLockedSecrets, bool hideCompleted)
		{
			if (IsVisible(item, hideLockedSecrets))
			{
				if (hideCompleted)
				{
					return !item.Unlocked;
				}
				return true;
			}
			return false;
		}

		internal static bool ShouldUnpin(AchievementProgress item, bool hideLockedSecrets)
		{
			if (hideLockedSecrets && item.IsSecret)
			{
				return !item.Unlocked;
			}
			return false;
		}

		internal static int RemoveHiddenPins(List<string> ids, AchievementSnapshot snapshot, bool hideLockedSecrets)
		{
			AchievementProgress value;
			return ids.RemoveAll((string id) => snapshot.ById.TryGetValue(id, out value) && ShouldUnpin(value, hideLockedSecrets));
		}

		internal static List<int> VisibleCriterionIndexes(AchievementProgress item, bool missingOnly)
		{
			List<int> list = new List<int>();
			for (int i = 0; i < item.Criteria.Count; i++)
			{
				if (!missingOnly || !item.Criteria[i].Met)
				{
					list.Add(i);
				}
			}
			return list;
		}
	}
	internal static class AchievementMath
	{
		internal static bool Met(float current, float target, int operation, bool recorded)
		{
			if (!recorded || float.IsNaN(current))
			{
				return false;
			}
			return operation switch
			{
				0 => current >= target, 
				1 => current <= target, 
				2 => current == target, 
				3 => current != target, 
				_ => false, 
			};
		}

		internal static float Fraction(float current, float target, int operation, bool recorded)
		{
			if (!recorded || float.IsNaN(current))
			{
				return 0f;
			}
			if (Met(current, target, operation, recorded: true))
			{
				return 1f;
			}
			if (operation != 0 || !(target > 0f))
			{
				return 0f;
			}
			return Math.Max(0f, Math.Min(1f, current / target));
		}

		internal static string Operator(int operation)
		{
			return operation switch
			{
				0 => "/", 
				1 => "≤", 
				2 => "=", 
				3 => "≠", 
				_ => "?", 
			};
		}

		internal static float LenientFraction(IEnumerable<Tuple<float, float>> values)
		{
			float num = 0f;
			float num2 = 0f;
			foreach (Tuple<float, float> value in values)
			{
				if (!(value.Item2 <= 0f))
				{
					num += Math.Min(Math.Max(0f, value.Item1), value.Item2 * 1.15f);
					num2 += value.Item2;
				}
			}
			if (!(num2 <= 0f))
			{
				return Math.Max(0f, Math.Min(1f, num / num2));
			}
			return 0f;
		}

		internal static bool LenientMet(IEnumerable<Tuple<float, float>> values)
		{
			float num = 0f;
			float num2 = 0f;
			foreach (Tuple<float, float> value in values)
			{
				if (!(value.Item2 <= 0f))
				{
					num += Math.Min(Math.Max(0f, value.Item1), value.Item2 * 1.15f);
					num2 += value.Item2;
				}
			}
			if (num2 > 0f)
			{
				return num > num2;
			}
			return false;
		}
	}
	internal sealed class AchievementReader
	{
		private static readonly FieldInfo PlatformInitialized = AccessTools.Field(typeof(Achievements), "m_platformInitialized");

		internal AchievementSnapshot Read()
		{
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Expected I4, but got Unknown
			//IL_0273: 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_0281: Unknown result type (might be due to invalid IL or missing references)
			//IL_0283: Unknown result type (might be due to invalid IL or missing references)
			//IL_0294: Unknown result type (might be due to invalid IL or missing references)
			Game instance = Game.instance;
			PlayerProfile val = (((Object)(object)instance == (Object)null) ? null : instance.GetPlayerProfile());
			Achievements instance2 = Achievements.m_instance;
			if (val == null || (Object)(object)instance2 == (Object)null || instance2.m_achievementLists == null || PlatformInitialized == null || !(bool)PlatformInitialized.GetValue(null))
			{
				return AchievementSnapshot.Waiting("Waiting for the character and Valheim achievements...");
			}
			List<AchievementProgress> list = new List<AchievementProgress>();
			HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal);
			PlayerStats[] playerStats = val.m_playerStats;
			int num = 0;
			foreach (AchievementList achievementList in instance2.m_achievementLists)
			{
				if ((Object)(object)achievementList == (Object)null || achievementList.m_achievements == null)
				{
					continue;
				}
				foreach (Achievement achievement in achievementList.m_achievements)
				{
					if ((Object)(object)achievement == (Object)null || string.IsNullOrEmpty(achievement.m_id) || !hashSet.Add(achievement.m_id))
					{
						continue;
					}
					List<CriterionProgress> list2 = new List<CriterionProgress>();
					int num2 = (int)achievement.m_difficultyRequirement;
					PlayerStats val2 = ((playerStats != null && num2 >= 0 && num2 < playerStats.Length) ? playerStats[num2] : null);
					if (val2 == null)
					{
						list2.Add(new CriterionProgress("Character statistics unavailable", "—", 0f, met: false, collectionEntry: false));
					}
					else
					{
						AddPlayerStats(list2, achievement.m_statTrigger, val2.m_stats);
						AddDictionary(list2, achievement.m_knownWorldTriggers, val2.m_knownWorlds, "World", collection: false);
						AddDictionary(list2, achievement.m_knownWorldKeysTriggers, val2.m_knownWorldKeys, "World key", collection: false);
						AddDictionary(list2, achievement.m_knownCommandsTriggers, val2.m_knownCommands, "Command", collection: false);
						AddEnemy(list2, achievement.m_enemyStatsTriggers, val2.m_enemyStats);
						AddDictionary(list2, achievement.m_itemPickupTriggers, val2.m_itemPickupStats, "Find", collection: true);
						AddDictionary(list2, achievement.m_itemCraftTriggers, val2.m_itemCraftStats, "Craft", collection: true);
						AddDictionary(list2, achievement.m_foodEatenTriggers, val2.m_foodEatenStats, "Eat", collection: true);
						AddDictionary(list2, achievement.m_pickableTriggers, val2.m_pickableStats, "Gather", collection: true);
						AddDictionary(list2, achievement.m_piecePlacedTriggers, val2.m_piecesPlacedStats, "Build", collection: true);
						if (achievement.m_lenientBuildAchievement)
						{
							List<Tuple<float, float>> list3 = new List<Tuple<float, float>>();
							foreach (PlayerStatRequirement item in achievement.m_statTrigger)
							{
								val2.m_stats.TryGetValue(item.m_stat, out var value);
								list3.Add(Tuple.Create(value, item.m_amountAboveEquals));
							}
							float num3 = AchievementMath.LenientFraction(list3);
							bool flag = AchievementMath.LenientMet(list3);
							string text = (num3 * 100f).ToString("0", CultureInfo.InvariantCulture) + "%";
							if (num3 >= 1f && !flag)
							{
								text += " — exceed total";
							}
							list2.Add(new CriterionProgress("Construction allowance", text, num3, flag, collectionEntry: false));
						}
					}
					if (achievement.m_otherAchievementTriggers != null)
					{
						foreach (Achievement otherAchievementTrigger in achievement.m_otherAchievementTriggers)
						{
							if ((Object)(object)otherAchievementTrigger != (Object)null)
							{
								list2.Add(new CriterionProgress("Achievement: " + Localize(otherAchievementTrigger.m_name), otherAchievementTrigger.m_unlocked ? "Completed" : "Incomplete", otherAchievementTrigger.m_unlocked ? 1f : 0f, otherAchievementTrigger.m_unlocked, collectionEntry: false));
							}
						}
					}
					string difficulty = ((object)Unsafe.As<DifficultyRequirement, DifficultyRequirement>(ref achievement.m_difficultyRequirement)/*cast due to .constrained prefix*/).ToString();
					list.Add(new AchievementProgress(achievement.m_id, Localize(achievement.m_name), Localize(achievement.m_description), Classify(achievement), difficulty, achievement.m_icon, achievement.m_unlocked, list2, num++, achievement.m_isSecret));
				}
			}
			return new AchievementSnapshot(list, (list.Count == 0) ? "Waiting for Valheim's achievement catalog..." : null, val.GetPlayerID());
		}

		private unsafe static void AddPlayerStats(List<CriterionProgress> output, List<PlayerStatRequirement> requirements, Dictionary<PlayerStatType, float> recorded)
		{
			//IL_0012: 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_0022: 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_003c: 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_0045: 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)
			if (requirements == null)
			{
				return;
			}
			foreach (PlayerStatRequirement requirement in requirements)
			{
				float value = 0f;
				bool flag = recorded?.TryGetValue(requirement.m_stat, out value) ?? false;
				if (!flag)
				{
					value = 0f;
				}
				float amountAboveEquals = requirement.m_amountAboveEquals;
				PlayerStatType stat = requirement.m_stat;
				string text = ((object)(*(PlayerStatType*)(&stat))/*cast due to .constrained prefix*/).ToString();
				if (!ExplorerStatDisplay.TryFormat(text, value, amountAboveEquals, out var label, out var value2))
				{
					label = Humanize(text);
					value2 = Display(value) + " / " + Display(amountAboveEquals);
				}
				output.Add(new CriterionProgress(label, value2, AchievementMath.Fraction(value, amountAboveEquals, 0, flag), AchievementMath.Met(value, amountAboveEquals, 0, flag), collectionEntry: false));
			}
		}

		private static void AddDictionary(List<CriterionProgress> output, List<DictStatRequirement> requirements, Dictionary<string, float> recorded, string verb, bool collection)
		{
			//IL_0012: 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_0022: 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_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected I4, but got Unknown
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			if (requirements == null)
			{
				return;
			}
			foreach (DictStatRequirement requirement in requirements)
			{
				float value = 0f;
				bool flag = recorded?.TryGetValue(requirement.m_stat, out value) ?? false;
				if (!flag)
				{
					value = 0f;
				}
				int operation = (int)requirement.m_operator;
				string value2 = ((AchievementMath.Operator(operation) == "/") ? (Display(value) + " / " + Display(requirement.m_amount)) : (Display(value) + " " + AchievementMath.Operator(operation) + " " + Display(requirement.m_amount)));
				output.Add(new CriterionProgress(verb + " " + ResolveName(requirement.m_stat), value2, AchievementMath.Fraction(value, requirement.m_amount, operation, flag), AchievementMath.Met(value, requirement.m_amount, operation, flag), collection));
			}
		}

		private unsafe static void AddEnemy(List<CriterionProgress> output, List<EnemyStatRequirement> requirements, Dictionary<string, float>[] recorded)
		{
			//IL_0012: 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_0018: 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_001f: Expected I4, but got Unknown
			//IL_003e: 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_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Expected I4, but got Unknown
			//IL_00b2: 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_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			if (requirements == null)
			{
				return;
			}
			foreach (EnemyStatRequirement requirement in requirements)
			{
				int num = (int)requirement.m_modifier;
				Dictionary<string, float> dictionary = ((recorded != null && num >= 0 && num < recorded.Length) ? recorded[num] : null);
				float value = 0f;
				bool flag = dictionary?.TryGetValue(requirement.m_stat, out value) ?? false;
				if (!flag)
				{
					value = 0f;
				}
				int num2 = (int)requirement.m_operator;
				string value2 = ((num2 == 0) ? (Display(value) + " / " + Display(requirement.m_amount)) : (Display(value) + " " + AchievementMath.Operator(num2) + " " + Display(requirement.m_amount)));
				string text = ResolveName(requirement.m_stat);
				KillModifiers modifier = requirement.m_modifier;
				output.Add(new CriterionProgress(text + " — " + Humanize(((object)(*(KillModifiers*)(&modifier))/*cast due to .constrained prefix*/).ToString()), value2, AchievementMath.Fraction(value, requirement.m_amount, num2, flag), AchievementMath.Met(value, requirement.m_amount, num2, flag), collectionEntry: true));
			}
		}

		private static string Classify(Achievement achievement)
		{
			if (Count(achievement.m_enemyStatsTriggers) > 0 || HasStat(achievement, "Kill", "Hit", "Boss", "Arrow"))
			{
				return "Combat";
			}
			if (Count(achievement.m_piecePlacedTriggers) > 0 || HasStat(achievement, "Build", "Piece"))
			{
				return "Building";
			}
			if (Count(achievement.m_itemCraftTriggers) > 0 || HasStat(achievement, "Craft", "Upgrade"))
			{
				return "Crafting";
			}
			if (Count(achievement.m_knownWorldTriggers) > 0 || Count(achievement.m_knownWorldKeysTriggers) > 0 || HasStat(achievement, "Travel", "Walk", "Run", "Sail", "Portal", "World", "Explore"))
			{
				return "Exploration";
			}
			if (Count(achievement.m_foodEatenTriggers) > 0 || HasStat(achievement, "Food", "Death", "Sleep", "Tame"))
			{
				return "Survival";
			}
			if (Count(achievement.m_itemPickupTriggers) > 0 || Count(achievement.m_pickableTriggers) > 0 || Count(achievement.m_otherAchievementTriggers) > 0)
			{
				return "Collections";
			}
			return "General";
		}

		private static int Count<T>(List<T> values)
		{
			return values?.Count ?? 0;
		}

		private unsafe static bool HasStat(Achievement achievement, params string[] words)
		{
			//IL_001a: 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_002b: 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)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			if (achievement.m_statTrigger == null)
			{
				return false;
			}
			foreach (PlayerStatRequirement item in achievement.m_statTrigger)
			{
				foreach (string value in words)
				{
					PlayerStatType stat = item.m_stat;
					if (((object)(*(PlayerStatType*)(&stat))/*cast due to .constrained prefix*/).ToString().IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0)
					{
						return true;
					}
				}
			}
			return false;
		}

		private static string ResolveName(string key)
		{
			if (string.IsNullOrEmpty(key))
			{
				return "Unknown";
			}
			if (key[0] == '$')
			{
				return Localize(key);
			}
			try
			{
				GameObject val = (((Object)(object)ObjectDB.instance == (Object)null) ? null : ObjectDB.instance.GetItemPrefab(key));
				if ((Object)(object)val == (Object)null && (Object)(object)ZNetScene.instance != (Object)null)
				{
					val = ZNetScene.instance.GetPrefab(key);
				}
				if ((Object)(object)val != (Object)null)
				{
					ItemDrop component = val.GetComponent<ItemDrop>();
					if ((Object)(object)component != (Object)null && component.m_itemData != null)
					{
						return Localize(component.m_itemData.m_shared.m_name);
					}
					Piece component2 = val.GetComponent<Piece>();
					if ((Object)(object)component2 != (Object)null)
					{
						return Localize(component2.m_name);
					}
					Character component3 = val.GetComponent<Character>();
					if ((Object)(object)component3 != (Object)null)
					{
						return Localize(component3.m_name);
					}
				}
			}
			catch
			{
			}
			return Humanize(key);
		}

		private static string Localize(string value)
		{
			if (string.IsNullOrEmpty(value))
			{
				return "";
			}
			try
			{
				return (Localization.instance == null) ? value : Localization.instance.Localize(value);
			}
			catch
			{
				return value;
			}
		}

		private static string Humanize(string value)
		{
			if (string.IsNullOrEmpty(value))
			{
				return "Unknown";
			}
			StringBuilder stringBuilder = new StringBuilder();
			for (int i = 0; i < value.Length; i++)
			{
				char c = value[i];
				if (c == '_' || c == '-')
				{
					stringBuilder.Append(' ');
					continue;
				}
				if (i > 0 && char.IsUpper(c) && char.IsLower(value[i - 1]))
				{
					stringBuilder.Append(' ');
				}
				stringBuilder.Append(c);
			}
			return stringBuilder.ToString();
		}

		private static string Display(float value)
		{
			return value.ToString("0.##", CultureInfo.InvariantCulture);
		}
	}
	internal static class ExplorerStatDisplay
	{
		internal static bool TryFormat(string stat, float current, float target, out string label, out string value)
		{
			string text;
			bool flag;
			switch (stat)
			{
			case "ExploreNorth":
				text = "North";
				flag = false;
				break;
			case "ExploreSouth":
				text = "South";
				flag = false;
				break;
			case "ExploreEast":
				text = "West";
				flag = false;
				break;
			case "ExploreWest":
				text = "East";
				flag = false;
				break;
			case "ExploreNorthNoMap":
				text = "North";
				flag = true;
				break;
			case "ExploreSouthNoMap":
				text = "South";
				flag = true;
				break;
			case "ExploreEastNoMap":
				text = "West";
				flag = true;
				break;
			case "ExploreWestNoMap":
				text = "East";
				flag = true;
				break;
			default:
				label = null;
				value = null;
				return false;
			}
			label = "Explore " + text + (flag ? " without map" : "");
			value = ((current >= target) ? target : current).ToString("0.##", CultureInfo.InvariantCulture) + " / " + target.ToString("0.##", CultureInfo.InvariantCulture);
			return true;
		}
	}
	internal sealed class AchievementWindow : IDisposable
	{
		private sealed class CriteriaView
		{
			internal TextMeshProUGUI Label;

			internal TextMeshProUGUI Value;

			internal int Index;
		}

		private sealed class RowView
		{
			internal RectTransform Root;

			internal TextMeshProUGUI Name;

			internal TextMeshProUGUI Summary;

			internal Image Bar;

			internal Button Track;

			internal ScrollRect DetailsScroll;

			internal readonly List<CriteriaView> Criteria = new List<CriteriaView>();

			internal void Refresh(AchievementProgress item, bool tracked, bool pinsFull)
			{
				//IL_0026: 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_00a3: Unknown result type (might be due to invalid IL or missing references)
				//IL_009c: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
				//IL_0168: Unknown result type (might be due to invalid IL or missing references)
				//IL_0161: Unknown result type (might be due to invalid IL or missing references)
				((TMP_Text)Name).text = item.Name;
				((Graphic)Name).color = (item.Unlocked ? AchievementUi.Gold : AchievementUi.Ink);
				((TMP_Text)Summary).text = item.Summary + (item.Unlocked ? "  ✓" : ("  " + (item.Fraction * 100f).ToString("0") + "%"));
				AchievementUi.SetBar(Bar, item.Fraction);
				((Graphic)Bar).color = (item.Unlocked ? AchievementUi.Done : AchievementUi.Gold);
				((Selectable)Track).interactable = tracked || !pinsFull;
				AchievementUi.Caption(Track, tracked ? "Untrack" : (pinsFull ? "3/3 Full" : "Track"), AchievementUi.Gold);
				foreach (CriteriaView criterion in Criteria)
				{
					if (criterion.Index < item.Criteria.Count)
					{
						CriterionProgress criterionProgress = item.Criteria[criterion.Index];
						((TMP_Text)criterion.Label).text = (criterionProgress.Met ? "✓  " : "○  ") + criterionProgress.Label;
						((Graphic)criterion.Label).color = (criterionProgress.Met ? AchievementUi.Done : AchievementUi.Ink);
						((TMP_Text)criterion.Value).text = criterionProgress.Value;
					}
				}
			}
		}

		private static readonly string[] Categories = new string[8] { "All", "General", "Combat", "Exploration", "Crafting", "Building", "Survival", "Collections" };

		private static readonly string[] Filters = new string[4] { "All", "In Progress", "Completed", "Tracked" };

		private static readonly string[] Sorts = new string[3] { "Game Order", "Name", "Closest" };

		private static readonly Vector2 MinimumWindowSize = new Vector2(700f, 480f);

		private readonly Plugin owner;

		private readonly Dictionary<string, RowView> rows = new Dictionary<string, RowView>(StringComparer.Ordinal);

		private readonly Dictionary<string, Button> categoryButtons = new Dictionary<string, Button>();

		private readonly Dictionary<string, Button> filterButtons = new Dictionary<string, Button>();

		private GameObject root;

		private RectTransform panel;

		private ScrollRect scroll;

		private TextMeshProUGUI totalText;

		private TextMeshProUGUI stateText;

		private Image totalBar;

		private InputField search;

		private Button sortButton;

		private Button hideCompletedButton;

		private Button secretButton;

		private AchievementSnapshot snapshot = AchievementSnapshot.Waiting("Loading...");

		private string category = "All";

		private string filter = "All";

		private string expandedId;

		private int sortIndex;

		private bool missingOnly;

		private bool hideCompleted;

		private bool wasBesideTracker;

		private string lastCatalogKey = "";

		private float lastListWidth;

		private Vector2 lastCanvasSize;

		internal bool Exists => (Object)(object)root != (Object)null;

		internal bool IsOpen
		{
			get
			{
				if ((Object)(object)root != (Object)null)
				{
					return root.activeSelf;
				}
				return false;
			}
		}

		internal bool HasTextFocus
		{
			get
			{
				if (IsOpen && (Object)(object)search != (Object)null)
				{
					return search.isFocused;
				}
				return false;
			}
		}

		internal bool CanvasSizeChanged
		{
			get
			{
				//IL_002c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0031: Unknown result type (might be due to invalid IL or missing references)
				//IL_0034: Unknown result type (might be due to invalid IL or missing references)
				//IL_003a: Unknown result type (might be due to invalid IL or missing references)
				//IL_003f: 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)
				RectTransform val = (RectTransform)(((Object)(object)panel == (Object)null) ? null : /*isinst with value type is only supported in some contexts*/);
				if ((Object)(object)val != (Object)null)
				{
					Rect rect = val.rect;
					Vector2 val2 = ((Rect)(ref rect)).size - lastCanvasSize;
					return ((Vector2)(ref val2)).sqrMagnitude > 1f;
				}
				return false;
			}
		}

		internal AchievementWindow(Plugin plugin)
		{
			owner = plugin;
		}

		internal void Create()
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: 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_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: 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_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_0230: Unknown result type (might be due to invalid IL or missing references)
			//IL_0235: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Unknown result type (might be due to invalid IL or missing references)
			//IL_0253: Unknown result type (might be due to invalid IL or missing references)
			//IL_0285: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_031e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0350: Unknown result type (might be due to invalid IL or missing references)
			//IL_035f: Unknown result type (might be due to invalid IL or missing references)
			//IL_036e: Unknown result type (might be due to invalid IL or missing references)
			//IL_037d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0398: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a2: Expected O, but got Unknown
			//IL_03ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_03dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0414: Unknown result type (might be due to invalid IL or missing references)
			//IL_0423: Unknown result type (might be due to invalid IL or missing references)
			//IL_0432: Unknown result type (might be due to invalid IL or missing references)
			//IL_0441: Unknown result type (might be due to invalid IL or missing references)
			//IL_0450: Unknown result type (might be due to invalid IL or missing references)
			//IL_046b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0489: Unknown result type (might be due to invalid IL or missing references)
			//IL_048e: Unknown result type (might be due to invalid IL or missing references)
			//IL_049d: 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_04d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_04db: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_0576: Unknown result type (might be due to invalid IL or missing references)
			//IL_0580: Expected O, but got Unknown
			//IL_05d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_05fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_061a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0624: Expected O, but got Unknown
			//IL_0632: Unknown result type (might be due to invalid IL or missing references)
			//IL_0646: Unknown result type (might be due to invalid IL or missing references)
			//IL_0655: Unknown result type (might be due to invalid IL or missing references)
			//IL_0664: Unknown result type (might be due to invalid IL or missing references)
			//IL_0673: Unknown result type (might be due to invalid IL or missing references)
			//IL_069c: Unknown result type (might be due to invalid IL or missing references)
			//IL_06a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_06a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_06b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_06c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0712: Unknown result type (might be due to invalid IL or missing references)
			//IL_0721: Unknown result type (might be due to invalid IL or missing references)
			//IL_0730: Unknown result type (might be due to invalid IL or missing references)
			//IL_073f: Unknown result type (might be due to invalid IL or missing references)
			//IL_075b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0765: Expected O, but got Unknown
			//IL_0798: Unknown result type (might be due to invalid IL or missing references)
			//IL_079d: Unknown result type (might be due to invalid IL or missing references)
			//IL_07ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_07bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_07d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_07e1: Expected O, but got Unknown
			//IL_0855: Unknown result type (might be due to invalid IL or missing references)
			//IL_0861: Unknown result type (might be due to invalid IL or missing references)
			//IL_0870: Unknown result type (might be due to invalid IL or missing references)
			//IL_087f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0898: Unknown result type (might be due to invalid IL or missing references)
			//IL_08a2: Expected O, but got Unknown
			//IL_08f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_08f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0906: Unknown result type (might be due to invalid IL or missing references)
			//IL_0915: Unknown result type (might be due to invalid IL or missing references)
			//IL_0937: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)root != (Object)null || (Object)(object)GUIManager.CustomGUIFront == (Object)null)
			{
				return;
			}
			Transform transform = GUIManager.CustomGUIFront.transform;
			root = ((Component)AchievementUi.Fill(transform, "Runestone Records Window", Vector2.zero, Vector2.zero)).gameObject;
			AchievementUi.Box(root.transform, "Dim Background", new Color(0f, 0f, 0f, 0.69f), Vector2.zero, Vector2.one, Vector2.zero, Vector2.zero, raycast: true);
			GameObject val = GUIManager.Instance.CreateWoodpanel(root.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, 1080f, 700f, false);
			((Object)val).name = "Runestone Records";
			panel = val.GetComponent<RectTransform>();
			panel.pivot = new Vector2(0.5f, 0.5f);
			Image component = val.GetComponent<Image>();
			if ((Object)(object)component != (Object)null)
			{
				((Graphic)component).color = new Color(0.86f, 0.78f, 0.64f, 1f);
			}
			RectTransform val2 = AchievementUi.Box((Transform)(object)panel, "Resize Window", AchievementUi.Dark, new Vector2(1f, 0f), new Vector2(1f, 0f), new Vector2(-42f, 6f), new Vector2(-7f, 40f), raycast: true);
			TextMeshProUGUI obj = AchievementUi.Text((Transform)(object)val2, "Resize Grip", "///", 23, AchievementUi.Gold, (TextAlignmentOptions)514);
			((TMP_Text)obj).rectTransform.offsetMin = Vector2.zero;
			((TMP_Text)obj).rectTransform.offsetMax = Vector2.zero;
			AchievementResizeHandle achievementResizeHandle = ((Component)val2).gameObject.AddComponent<AchievementResizeHandle>();
			achievementResizeHandle.Target = panel;
			achievementResizeHandle.MinimumSize = MinimumWindowSize;
			achievementResizeHandle.MaximumSize = MaximumWindowSize;
			achievementResizeHandle.Finished = delegate
			{
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				owner.PersistWindowSize(panel.sizeDelta);
				Resize();
			};
			RectTransform val3 = AchievementUi.Box((Transform)(object)panel, "Drag Header", new Color(0.12f, 0.095f, 0.075f, 0.76f), new Vector2(0f, 1f), Vector2.one, new Vector2(12f, -83f), new Vector2(-12f, -12f), raycast: true);
			((Component)val3).gameObject.AddComponent<AchievementDragHandle>().Target = panel;
			TextMeshProUGUI obj2 = AchievementUi.Text((Transform)(object)val3, "Title", "RUNESTONE RECORDS", 32, AchievementUi.Gold, (TextAlignmentOptions)4097);
			((TMP_Text)obj2).rectTransform.offsetMin = new Vector2(18f, 29f);
			((TMP_Text)obj2).rectTransform.offsetMax = new Vector2(-82f, 0f);
			totalText = AchievementUi.Text((Transform)(object)val3, "Total", "Loading...", 18, AchievementUi.Ink, (TextAlignmentOptions)4097);
			((TMP_Text)totalText).rectTransform.offsetMin = new Vector2(18f, 5f);
			((TMP_Text)totalText).rectTransform.offsetMax = new Vector2(-85f, -42f);
			Button obj3 = AchievementUi.Button((Transform)(object)val3, "Close", "×", 27);
			Transform transform2 = ((Component)obj3).transform;
			SetRect((RectTransform)(object)((transform2 is RectTransform) ? transform2 : null), new Vector2(1f, 0.5f), new Vector2(1f, 0.5f), new Vector2(-60f, -24f), new Vector2(-12f, 24f));
			((UnityEvent)obj3.onClick).AddListener(new UnityAction(owner.CloseWindow));
			totalBar = AchievementUi.Bar((Transform)(object)panel, "Overall Progress", AchievementUi.Gold);
			Transform parent = ((Component)totalBar).transform.parent;
			SetRect((RectTransform)(object)((parent is RectTransform) ? parent : null), new Vector2(0f, 1f), Vector2.one, new Vector2(22f, -94f), new Vector2(-22f, -86f));
			RectTransform parent2 = AchievementUi.Box((Transform)(object)panel, "Category Sidebar", AchievementUi.Dark, new Vector2(0f, 0f), new Vector2(0f, 1f), new Vector2(14f, 14f), new Vector2(224f, -104f));
			SetRect(((TMP_Text)AchievementUi.Text((Transform)(object)parent2, "Category Heading", "CATEGORIES", 19, AchievementUi.Gold, (TextAlignmentOptions)4097)).rectTransform, new Vector2(0f, 1f), Vector2.one, new Vector2(14f, -38f), new Vector2(-10f, -8f));
			ScrollRect val4 = AchievementUi.Scroll((Transform)(object)parent2, "Category List", 180f);
			Transform transform3 = ((Component)val4).transform;
			SetRect((RectTransform)(object)((transform3 is RectTransform) ? transform3 : null), Vector2.zero, Vector2.one, new Vector2(8f, 104f), new Vector2(-8f, -43f));
			for (int num = 0; num < Categories.Length; num++)
			{
				string name = Categories[num];
				Button val5 = AchievementUi.Button((Transform)(object)val4.content, "Category " + name, name, 17);
				((Component)val5).gameObject.AddComponent<LayoutElement>().preferredHeight = 37f;
				((UnityEvent)val5.onClick).AddListener((UnityAction)delegate
				{
					category = name;
					RenderList(preservePosition: false);
				});
				categoryButtons[name] = val5;
			}
			secretButton = AchievementUi.Button((Transform)(object)parent2, "Hide Locked Secrets", "Hide Locked Secrets: Off", 14);
			Transform transform4 = ((Component)secretButton).transform;
			SetRect((RectTransform)(object)((transform4 is RectTransform) ? transform4 : null), Vector2.zero, new Vector2(1f, 0f), new Vector2(8f, 56f), new Vector2(-8f, 92f));
			((UnityEvent)secretButton.onClick).AddListener((UnityAction)delegate
			{
				owner.SetHideLockedSecrets(!owner.HideLockedSecrets);
			});
			SetRect(((TMP_Text)AchievementUi.Text((Transform)(object)parent2, "Hint", "F7  •  Esc to close", 14, AchievementUi.Muted, (TextAlignmentOptions)4097)).rectTransform, Vector2.zero, new Vector2(1f, 0f), new Vector2(12f, 12f), new Vector2(-10f, 38f));
			RectTransform val6 = AchievementUi.Box((Transform)(object)panel, "Main Content", new Color(0.095f, 0.075f, 0.06f, 0.93f), Vector2.zero, Vector2.one, new Vector2(234f, 14f), new Vector2(-14f, -104f));
			search = CreateSearch((Transform)(object)val6);
			sortButton = AchievementUi.Button((Transform)(object)val6, "Sort", "Sort: Game Order", 16);
			Transform transform5 = ((Component)sortButton).transform;
			SetRect((RectTransform)(object)((transform5 is RectTransform) ? transform5 : null), new Vector2(0.43f, 1f), new Vector2(0.69f, 1f), new Vector2(10f, -42f), new Vector2(-5f, -7f));
			((UnityEvent)sortButton.onClick).AddListener((UnityAction)delegate
			{
				sortIndex = (sortIndex + 1) % Sorts.Length;
				RenderList(preservePosition: false);
			});
			hideCompletedButton = AchievementUi.Button((Transform)(object)val6, "Hide Completed", "Hide Completed: Off", 13);
			Transform transform6 = ((Component)hideCompletedButton).transform;
			SetRect((RectTransform)(object)((transform6 is RectTransform) ? transform6 : null), new Vector2(0.69f, 1f), Vector2.one, new Vector2(2f, -42f), new Vector2(-10f, -7f));
			((UnityEvent)hideCompletedButton.onClick).AddListener((UnityAction)delegate
			{
				hideCompleted = !hideCompleted;
				if (hideCompleted && filter == "Completed")
				{
					filter = "All";
				}
				RenderList();
			});
			for (int num2 = 0; num2 < Filters.Length; num2++)
			{
				string name2 = Filters[num2];
				Button val7 = AchievementUi.Button((Transform)(object)val6, "Filter " + name2, name2, 16);
				float num3 = (float)num2 / 4f;
				float num4 = (float)(num2 + 1) / 4f;
				Transform transform7 = ((Component)val7).transform;
				SetRect((RectTransform)(object)((transform7 is RectTransform) ? transform7 : null), new Vector2(num3, 1f), new Vector2(num4, 1f), new Vector2(10f, -88f), new Vector2(-4f, -49f));
				((UnityEvent)val7.onClick).AddListener((UnityAction)delegate
				{
					filter = name2;
					if (name2 == "Completed")
					{
						hideCompleted = false;
					}
					RenderList(preservePosition: false);
				});
				filterButtons[name2] = val7;
			}
			scroll = AchievementUi.Scroll((Transform)(object)val6, "Achievement List");
			Transform transform8 = ((Component)scroll).transform;
			SetRect((RectTransform)(object)((transform8 is RectTransform) ? transform8 : null), Vector2.zero, Vector2.one, new Vector2(10f, 11f), new Vector2(-10f, -97f));
			stateText = AchievementUi.Text((Transform)(object)scroll.content, "State", "", 21, AchievementUi.Muted, (TextAlignmentOptions)514);
			((Component)stateText).gameObject.AddComponent<LayoutElement>().preferredHeight = 100f;
			((Transform)val2).SetAsLastSibling();
			root.SetActive(false);
			Resize();
		}

		private InputField CreateSearch(Transform main)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: 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_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			RectTransform obj = AchievementUi.Box(main, "Search", new Color(0.045f, 0.04f, 0.035f, 1f), new Vector2(0f, 1f), new Vector2(0.43f, 1f), new Vector2(10f, -42f), new Vector2(-4f, -7f), raycast: true);
			InputField val = ((Component)obj).gameObject.AddComponent<InputField>();
			Text val2 = LegacyText((Transform)(object)obj, "Input", "", AchievementUi.Ink);
			((Graphic)val2).rectTransform.offsetMin = new Vector2(10f, 2f);
			((Graphic)val2).rectTransform.offsetMax = new Vector2(-9f, -2f);
			Text val3 = LegacyText((Transform)(object)obj, "Placeholder", "Search achievements...", AchievementUi.Muted);
			((Graphic)val3).rectTransform.offsetMin = ((Graphic)val2).rectTransform.offsetMin;
			((Graphic)val3).rectTransform.offsetMax = ((Graphic)val2).rectTransform.offsetMax;
			val.textComponent = val2;
			val.placeholder = (Graphic)(object)val3;
			((UnityEvent<string>)(object)val.onValueChanged).AddListener((UnityAction<string>)delegate
			{
				RenderList(preservePosition: false);
			});
			return val;
		}

		private static Text LegacyText(Transform parent, string name, string value, Color color)
		{
			//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_003b: Unknown result type (might be due to invalid IL or missing references)
			Text obj = ((Component)AchievementUi.Fill(parent, name, Vector2.zero, Vector2.zero)).gameObject.AddComponent<Text>();
			obj.font = GUIManager.Instance.AveriaSerif;
			obj.fontSize = 17;
			obj.alignment = (TextAnchor)3;
			((Graphic)obj).color = color;
			obj.text = value;
			return obj;
		}

		internal void Resize()
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_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_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: 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_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: 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_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: 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_0219: Unknown result type (might be due to invalid IL or missing references)
			//IL_021e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)panel == (Object)null)
			{
				return;
			}
			Transform parent = ((Transform)panel).parent;
			RectTransform val = (RectTransform)(object)((parent is RectTransform) ? parent : null);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			Rect rect = val.rect;
			lastCanvasSize = ((Rect)(ref rect)).size;
			bool flag = owner.ShowTracker && IsOpen;
			Vector2 val2 = MaximumWindowSize();
			Vector2 windowSize = owner.WindowSize;
			if (float.IsNaN(windowSize.x) || float.IsInfinity(windowSize.x))
			{
				windowSize.x = 1080f;
			}
			if (float.IsNaN(windowSize.y) || float.IsInfinity(windowSize.y))
			{
				windowSize.y = 700f;
			}
			panel.sizeDelta = new Vector2(Mathf.Clamp(windowSize.x, Mathf.Min(MinimumWindowSize.x, val2.x), val2.x), Mathf.Clamp(windowSize.y, Mathf.Min(MinimumWindowSize.y, val2.y), val2.y));
			rect = val.rect;
			float width = ((Rect)(ref rect)).width;
			rect = panel.rect;
			float num = Mathf.Max(0f, (width - ((Rect)(ref rect)).width) * 0.5f);
			rect = val.rect;
			float height = ((Rect)(ref rect)).height;
			rect = panel.rect;
			float num2 = Mathf.Max(0f, (height - ((Rect)(ref rect)).height) * 0.5f);
			float num3 = ((flag == wasBesideTracker) ? panel.anchoredPosition.x : (flag ? (-170f) : 0f));
			panel.anchoredPosition = new Vector2(Mathf.Clamp(num3, 0f - num, num), Mathf.Clamp(panel.anchoredPosition.y, 0f - num2, num2));
			wasBesideTracker = flag;
			if (IsOpen && lastListWidth > 0f && (Object)(object)scroll != (Object)null)
			{
				Canvas.ForceUpdateCanvases();
				rect = scroll.viewport.rect;
				if (Mathf.Abs(((Rect)(ref rect)).width - lastListWidth) > 1f)
				{
					RenderList();
				}
			}
		}

		private Vector2 MaximumWindowSize()
		{
			//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_0056: 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_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = (RectTransform)(((Object)(object)panel == (Object)null) ? null : /*isinst with value type is only supported in some contexts*/);
			if ((Object)(object)val == (Object)null)
			{
				return Vector2.zero;
			}
			Rect rect = val.rect;
			float num = Mathf.Max(0f, ((Rect)(ref rect)).width - 32f);
			rect = val.rect;
			float num2 = Mathf.Max(0f, ((Rect)(ref rect)).width - 390f);
			if (owner.ShowTracker && IsOpen && num2 >= MinimumWindowSize.x)
			{
				num = num2;
			}
			float num3 = num;
			rect = val.rect;
			return new Vector2(num3, Mathf.Max(0f, ((Rect)(ref rect)).height - 32f));
		}

		internal void Open(AchievementSnapshot current)
		{
			if (!((Object)(object)root == (Object)null))
			{
				snapshot = current;
				root.SetActive(true);
				Resize();
				SetSnapshot(current);
				if ((Object)(object)EventSystem.current != (Object)null)
				{
					EventSystem.current.SetSelectedGameObject(((Component)categoryButtons[category]).gameObject);
				}
			}
		}

		internal void Close()
		{
			if (!((Object)(object)root == (Object)null))
			{
				GameObject val = (((Object)(object)EventSystem.current == (Object)null) ? null : EventSystem.current.currentSelectedGameObject);
				if ((Object)(object)val != (Object)null && val.transform.IsChildOf(root.transform))
				{
					EventSystem.current.SetSelectedGameObject((GameObject)null);
				}
				root.SetActive(false);
			}
		}

		internal void SetSnapshot(AchievementSnapshot current)
		{
			snapshot = current;
			if ((Object)(object)root == (Object)null)
			{
				return;
			}
			UpdateSummary();
			if (IsOpen && lastCatalogKey != current.CatalogKey)
			{
				RenderList();
			}
			else if (IsOpen && MissingCriteriaChanged(current))
			{
				RenderList();
			}
			else
			{
				if (!IsOpen)
				{
					return;
				}
				foreach (KeyValuePair<string, RowView> row in rows)
				{
					if (current.ById.TryGetValue(row.Key, out var value))
					{
						row.Value.Refresh(value, owner.IsTracked(value.Id), owner.TrackedIds.Count >= 3);
					}
				}
			}
		}

		private bool MissingCriteriaChanged(AchievementSnapshot current)
		{
			if (!missingOnly || expandedId == null || !rows.TryGetValue(expandedId, out var value) || !current.ById.TryGetValue(expandedId, out var value2))
			{
				return false;
			}
			List<int> list = AchievementVisibility.VisibleCriterionIndexes(value2, missingOnly: true);
			if (value.Criteria.Count != list.Count)
			{
				return true;
			}
			for (int i = 0; i < list.Count; i++)
			{
				if (value.Criteria[i].Index != list[i])
				{
					return true;
				}
			}
			return false;
		}

		private void UpdateSummary()
		{
			//IL_0200: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0267: Unknown result type (might be due to invalid IL or missing references)
			//IL_0260: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_032a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0323: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)totalText == (Object)null)
			{
				return;
			}
			List<AchievementProgress> list = snapshot.Items.Where((AchievementProgress a) => AchievementVisibility.IsVisible(a, owner.HideLockedSecrets)).ToList();
			int count = list.Count;
			int num = list.Count((AchievementProgress a) => a.Unlocked);
			((TMP_Text)totalText).text = ((count == 0) ? (snapshot.State ?? "No visible achievements") : ((owner.HideLockedSecrets ? "Visible completion: " : "") + num + " / " + count + " completed  •  " + (100f * (float)num / (float)count).ToString("0") + "%"));
			AchievementUi.SetBar(totalBar, (count == 0) ? 0f : ((float)num / (float)count));
			foreach (KeyValuePair<string, Button> pair in categoryButtons)
			{
				IEnumerable<AchievementProgress> enumerable;
				if (!(pair.Key == "All"))
				{
					enumerable = list.Where((AchievementProgress a) => a.Category == pair.Key);
				}
				else
				{
					IEnumerable<AchievementProgress> enumerable2 = list;
					enumerable = enumerable2;
				}
				IEnumerable<AchievementProgress> source = enumerable;
				AchievementUi.Caption(pair.Value, pair.Key + "  " + source.Count((AchievementProgress a) => a.Unlocked) + "/" + source.Count(), (category == pair.Key) ? AchievementUi.Gold : AchievementUi.Ink);
			}
			foreach (KeyValuePair<string, Button> filterButton in filterButtons)
			{
				AchievementUi.Caption(filterButton.Value, filterButton.Key, (filter == filterButton.Key) ? AchievementUi.Gold : AchievementUi.Ink);
			}
			AchievementUi.Caption(sortButton, "Sort: " + Sorts[sortIndex], AchievementUi.Ink);
			AchievementUi.Caption(hideCompletedButton, "Hide Completed: " + (hideCompleted ? "On" : "Off"), hideCompleted ? AchievementUi.Gold : AchievementUi.Ink);
			AchievementUi.Caption(secretButton, "Hide Locked Secrets: " + (owner.HideLockedSecrets ? "On" : "Off"), owner.HideLockedSecrets ? AchievementUi.Gold : AchievementUi.Ink);
		}

		internal void RenderList(bool preservePosition = true, string focusId = null)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Expected O, but got Unknown
			//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_03a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c7: 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_0414: Unknown result type (might be due to invalid IL or missing references)
			//IL_042c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0431: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)scroll == (Object)null || !IsOpen)
			{
				return;
			}
			Canvas.ForceUpdateCanvases();
			float num = (preservePosition ? scroll.content.anchoredPosition.y : 0f);
			float num2 = 1f;
			if (preservePosition && expandedId != null && rows.TryGetValue(expandedId, out var value) && (Object)(object)value.DetailsScroll != (Object)null)
			{
				num2 = value.DetailsScroll.verticalNormalizedPosition;
			}
			scroll.StopMovement();
			foreach (Transform item in (Transform)scroll.content)
			{
				Transform val = item;
				if ((Object)(object)val != (Object)(object)((TMP_Text)stateText).transform)
				{
					((Component)val).gameObject.SetActive(false);
					Object.Destroy((Object)(object)((Component)val).gameObject);
				}
			}
			rows.Clear();
			IEnumerable<AchievementProgress> source = snapshot.Items.Where((AchievementProgress a) => AchievementVisibility.IsVisibleInList(a, owner.HideLockedSecrets, hideCompleted));
			if (category != "All")
			{
				source = source.Where((AchievementProgress a) => a.Category == category);
			}
			if (filter == "In Progress")
			{
				source = source.Where((AchievementProgress a) => !a.Unlocked && a.Fraction > 0f);
			}
			if (filter == "Completed")
			{
				source = source.Where((AchievementProgress a) => a.Unlocked);
			}
			if (filter == "Tracked")
			{
				source = source.Where((AchievementProgress a) => owner.IsTracked(a.Id));
			}
			if (!string.IsNullOrWhiteSpace(search.text))
			{
				string term = search.text.Trim();
				source = source.Where((AchievementProgress a) => a.Name.IndexOf(term, StringComparison.OrdinalIgnoreCase) >= 0 || a.Description.IndexOf(term, StringComparison.OrdinalIgnoreCase) >= 0);
			}
			source = ((sortIndex == 1) ? source.OrderBy<AchievementProgress, string>((AchievementProgress a) => a.Name, StringComparer.CurrentCultureIgnoreCase) : ((sortIndex != 2) ? source.OrderBy((AchievementProgress a) => a.GameOrder) : (from a in source
				orderby a.Fraction descending, a.GameOrder
				select a)));
			List<AchievementProgress> list = source.ToList();
			foreach (AchievementProgress item2 in list)
			{
				rows[item2.Id] = CreateRow(item2);
			}
			((Component)stateText).gameObject.SetActive(list.Count == 0);
			if (list.Count == 0)
			{
				((TMP_Text)stateText).text = snapshot.State ?? "No achievements match these filters.";
			}
			lastCatalogKey = snapshot.CatalogKey;
			Rect rect = scroll.viewport.rect;
			lastListWidth = ((Rect)(ref rect)).width;
			UpdateSummary();
			Canvas.ForceUpdateCanvases();
			rect = scroll.content.rect;
			float height = ((Rect)(ref rect)).height;
			rect = scroll.viewport.rect;
			float num3 = Mathf.Max(0f, height - ((Rect)(ref rect)).height);
			if (focusId != null && rows.TryGetValue(focusId, out var value2))
			{
				Vector3[] array = (Vector3[])(object)new Vector3[4];
				value2.Root.GetWorldCorners(array);
				float y = ((Transform)scroll.viewport).InverseTransformPoint(array[1]).y;
				float num4 = num;
				rect = scroll.viewport.rect;
				num = num4 + (((Rect)(ref rect)).yMax - y - 8f);
			}
			float num5 = Mathf.Clamp(num, 0f, num3);
			scroll.verticalNormalizedPosition = ((num3 < 0.01f) ? 1f : (1f - num5 / num3));
			if (expandedId != null && rows.TryGetValue(expandedId, out var value3) && (Object)(object)value3.DetailsScroll != (Object)null)
			{
				value3.DetailsScroll.verticalNormalizedPosition = ((focusId == null) ? num2 : 1f);
			}
		}

		private RowView CreateRow(AchievementProgress item)
		{
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: 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_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Expected O, but got Unknown
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: 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_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: 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_0234: 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_025a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0289: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0355: Unknown result type (might be due to invalid IL or missing references)
			//IL_035a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0367: Unknown result type (might be due to invalid IL or missing references)
			//IL_036c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0387: Unknown result type (might be due to invalid IL or missing references)
			//IL_038c: Unknown result type (might be due to invalid IL or missing references)
			//IL_039e: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_03dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_0493: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_04cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_04da: Unknown result type (might be due to invalid IL or missing references)
			//IL_040d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0412: Unknown result type (might be due to invalid IL or missing references)
			//IL_0417: Unknown result type (might be due to invalid IL or missing references)
			//IL_0426: Unknown result type (might be due to invalid IL or missing references)
			//IL_0435: Unknown result type (might be due to invalid IL or missing references)
			//IL_044c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0461: Unknown result type (might be due to invalid IL or missing references)
			//IL_0470: Unknown result type (might be due to invalid IL or missing references)
			//IL_0504: Unknown result type (might be due to invalid IL or missing references)
			//IL_04fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_052b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0530: Unknown result type (might be due to invalid IL or missing references)
			//IL_0543: Unknown result type (might be due to invalid IL or missing references)
			//IL_0550: Unknown result type (might be due to invalid IL or missing references)
			//IL_0592: Unknown result type (might be due to invalid IL or missing references)
			//IL_0597: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_05dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_05f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ff: Expected O, but got Unknown
			//IL_0625: Unknown result type (might be due to invalid IL or missing references)
			//IL_067f: Unknown result type (might be due to invalid IL or missing references)
			//IL_068e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0693: Unknown result type (might be due to invalid IL or missing references)
			//IL_06a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_06bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_06e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0701: Unknown result type (might be due to invalid IL or missing references)
			//IL_0706: Unknown result type (might be due to invalid IL or missing references)
			//IL_0715: Unknown result type (might be due to invalid IL or missing references)
			//IL_0724: Unknown result type (might be due to invalid IL or missing references)
			//IL_0764: Unknown result type (might be due to invalid IL or missing references)
			//IL_0769: Unknown result type (might be due to invalid IL or missing references)
			//IL_0778: Unknown result type (might be due to invalid IL or missing references)
			//IL_0787: Unknown result type (might be due to invalid IL or missing references)
			//IL_079d: Unknown result type (might be due to invalid IL or missing references)
			//IL_07a7: Expected O, but got Unknown
			//IL_07ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_07cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_07de: Unknown result type (might be due to invalid IL or missing references)
			//IL_07ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_0808: Unknown result type (might be due to invalid IL or missing references)
			//IL_0812: Expected O, but got Unknown
			//IL_08b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_08d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_08d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_08e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_08f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_090f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0931: Unknown result type (might be due to invalid IL or missing references)
			//IL_0936: Unknown result type (might be due to invalid IL or missing references)
			//IL_0945: Unknown result type (might be due to invalid IL or missing references)
			//IL_0954: Unknown result type (might be due to invalid IL or missing references)
			//IL_0863: Unknown result type (might be due to invalid IL or missing references)
			bool expanded = item.Id == expandedId;
			List<int> list = AchievementVisibility.VisibleCriterionIndexes(item, missingOnly);
			float num = Mathf.Max(34f, Mathf.Min(252f, (float)list.Count * 31f));
			float num2 = (expanded ? (44f + num) : 0f);
			LayoutElement val = AchievementUi.Layout((Transform)(object)scroll.content, "Achievement " + item.Id, 104f + num2);
			Image obj = ((Component)val).gameObject.AddComponent<Image>();
			((Graphic)obj).color = AchievementUi.Row;
			((Graphic)obj).raycastTarget = false;
			Button val2 = AchievementUi.Button(((Component)val).transform, "Select", "", 16);
			Transform transform = ((Component)val2).transform;
			SetRect((RectTransform)(object)((transform is RectTransform) ? transform : null), new Vector2(0f, 1f), Vector2.one, new Vector2(0f, -104f), Vector2.zero);
			AchievementUi.Caption(val2, "", AchievementUi.Ink);
			((UnityEvent)val2.onClick).AddListener((UnityAction)delegate
			{
				expandedId = (expanded ? null : item.Id);
				RenderList(preservePosition: true, expanded ? null : item.Id);
			});
			Image component = ((Component)AchievementUi.Box(((Component)val2).transform, "Icon Back", AchievementUi.Dark, new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(9f, -70f), new Vector2(67f, -12f))).GetComponent<Image>();
			component.sprite = item.Icon;
			component.preserveAspect = true;
			((Graphic)component).color = (((Object)(object)item.Icon == (Object)null) ? AchievementUi.Gold : Color.white);
			((Graphic)component).raycastTarget = false;
			TextMeshProUGUI val3 = AchievementUi.Text(((Component)val2).transform, "Name", item.Name, 20, item.Unlocked ? AchievementUi.Gold : AchievementUi.Ink, (TextAlignmentOptions)4097);
			TextMeshProUGUI val4 = AchievementUi.Text(((Component)val2).transform, "Description", item.Description, 15, AchievementUi.Ink, (TextAlignmentOptions)4097);
			Rect rect = scroll.viewport.rect;
			float num3 = Mathf.Max(80f, ((Rect)(ref rect)).width - 220f);
			float num4 = Mathf.Max(26f, Mathf.Ceil(((TMP_Text)val3).GetPreferredValues(item.Name, num3, 0f).y) + 3f);
			float num5 = (string.IsNullOrWhiteSpace(item.Description) ? 0f : Mathf.Max(20f, Mathf.Ceil(((TMP_Text)val4).GetPreferredValues(item.Description, num3, 0f).y) + 4f));
			float num6 = 10f + num4 + 4f;
			float num7 = num6 + num5 + 5f;
			float num8 = num7 + 25f;
			float num9 = Mathf.Max(104f, num8 + 15f);
			val.preferredHeight = num9 + 4f + num2;
			Transform transform2 = ((Component)val2).transform;
			SetRect((RectTransform)(object)((transform2 is RectTransform) ? transform2 : null), new Vector2(0f, 1f), Vector2.one, new Vector2(0f, 0f - num9), Vector2.zero);
			SetRect(((TMP_Text)val3).rectTransform, new Vector2(0f, 1f), Vector2.one, new Vector2(77f, -10f - num4), new Vector2(-136f, -10f));
			SetRect(((TMP_Text)val4).rectTransform, new Vector2(0f, 1f), Vector2.one, new Vector2(77f, 0f - num6 - num5), new Vector2(-136f, 0f - num6));
			if (item.IsSecret)
			{
				TextMeshProUGUI obj2 = AchievementUi.Text((Transform)(object)AchievementUi.Box(((Component)val2).transform, "Secret Badge", AchievementUi.Dark, Vector2.one, Vector2.one, new Vector2(-119f, -33f), new Vector2(-10f, -10f)), "Secret", "SECRET", 13, AchievementUi.Gold, (TextAlignmentOptions)514);
				((TMP_Text)obj2).rectTransform.offsetMin = Vector2.zero;
				((TMP_Text)obj2).rectTransform.offsetMax = Vector2.zero;
			}
			TextMeshProUGUI val5 = AchievementUi.Text(((Component)val2).transform, "Progress", item.Summary, 15, AchievementUi.Muted, (TextAlignmentOptions)4097);
			SetRect(((TMP_Text)val5).rectTransform, new Vector2(0f, 1f), Vector2.one, new Vector2(77f, 0f - num7 - 21f), new Vector2(-138f, 0f - num7));
			Image val6 = AchievementUi.Bar(((Component)val2).transform, "Progress Bar", item.Unlocked ? AchievementUi.Done : AchievementUi.Gold);
			Transform parent = ((Component)val6).transform.parent;
			SetRect((RectTransform)(object)((parent is RectTransform) ? parent : null), new Vector2(0f, 1f), Vector2.one, new Vector2(77f, 0f - num8 - 7f), new Vector2(-136f, 0f - num8));
			AchievementUi.SetBar(val6, item.Fraction);
			Button val7 = AchievementUi.Button(((Component)val2).transform, "Track", "", 14);
			Transform transform3 = ((Component)val7).transform;
			SetRect((RectTransform)(object)((transform3 is RectTransform) ? transform3 : null), Vector2.one, Vector2.one, new Vector2(-121f, item.IsSecret ? (-76f) : (-48f)), new Vector2(-8f, item.IsSecret ? (-40f) : (-12f)));
			((UnityEvent)val7.onClick).AddListener((UnityAction)delegate
			{
				owner.ToggleTracked(item.Id);
				RenderList();
			});
			AchievementUi.Caption(val7, owner.IsTracked(item.Id) ? "Untrack" : "Track", AchievementUi.Gold);
			RowView rowView = new RowView
			{
				Root = (RectTransform)/*isinst with value type is only supported in some contexts*/,
				Name = val3,
				Summary = val5,
				Bar = val6,
				Track = val7
			};
			if (expanded)
			{
				RectTransform parent2 = AchievementUi.Box(((Component)val).transform, "Requirements", AchievementUi.Dark, new Vector2(0f, 1f), Vector2.one, new Vector2(7f, 0f - num9 - 4f - num2), new Vector2(-7f, 0f - num9 - 4f));
				SetRect(((TMP_Text)AchievementUi.Text((Transform)(object)parent2, "Difficulty", "Difficulty: " + item.Difficulty, 15, AchievementUi.Ink, (TextAlignmentOptions)4097)).rectTransform, new Vector2(0f, 1f), Vector2.one, new Vector2(14f, -32f), new Vector2(-171f, -3f));
				Button obj3 = AchievementUi.Button((Transform)(object)parent2, "Missing Requirements", "Missing Reqs: " + (missingOnly ? "On" : "Off"), 13);
				Transform transform4 = ((Component)obj3).transform;
				SetRect((RectTransform)(object)((transform4 is RectTransform) ? transform4 : null), Vector2.one, Vector2.one, new Vector2(-164f, -32f), new Vector2(-12f, -4f));
				((UnityEvent)obj3.onClick).AddListener((UnityAction)delegate
				{
					missingOnly = !missingOnly;
					RenderList();
				});
				ScrollRect val8 = AchievementUi.Scroll((Transform)(object)parent2, "Scrollable Requirements", 220f, scroll);
				Transform transform5 = ((Component)val8).transform;
				SetRect((RectTransform)(object)((transform5 is RectTransform) ? transform5 : null), Vector2.zero, Vector2.one, new Vector2(10f, 8f), new Vector2(-10f, -36f));
				VerticalLayoutGroup component2 = ((Component)val8.content).GetComponent<VerticalLayoutGroup>();
				((LayoutGroup)component2).padding = new RectOffset(0, 0, 0, 0);
				((HorizontalOrVerticalLayoutGroup)component2).spacing = 0f;
				rowView.DetailsScroll = val8;
				if (list.Count == 0)
				{
					AchievementUi.Text(((Component)AchievementUi.Layout((Transform)(object)val8.content, "No Requirements", 31f)).transform, "Message", missingOnly ? "No missing requirements." : "No requirements to display.", 15, AchievementUi.Muted, (TextAlignmentOptions)4097);
				}
				for (int num10 = 0; num10 < list.Count; num10++)
				{
					int index = list[num10];
					LayoutElement obj4 = AchievementUi.Layout((Transform)(object)val8.content, "Requirement " + num10, 31f);
					TextMeshProUGUI val9 = AchievementUi.Text(((Component)obj4).transform, "Requirement", "", 15, AchievementUi.Ink, (TextAlignmentOptions)4097);
					SetRect(((TMP_Text)val9).rectTransform, Vector2.zero, Vector2.one, new Vector2(6f, 0f), new Vector2(-150f, 0f));
					TextMeshProUGUI val10 = AchievementUi.Text(((Component)obj4).transform, "Value", "", 15, AchievementUi.Muted, (TextAlignmentOptions)4100);
					SetRect(((TMP_Text)val10).rectTransform, new Vector2(1f, 0f), Vector2.one, new Vector2(-145f, 0f), new Vector2(-7f, 0f));
					rowView.Criteria.Add(new CriteriaView
					{
						Label = val9,
						Value = val10,
						Index = index
					});
				}
			}
			rowView.Refresh(item, owner.IsTracked(item.Id), owner.TrackedIds.Count >= 3);
			return rowView;
		}

		private static void SetRect(RectTransform rect, Vector2 min, Vector2 max, Vector2 offsetMin, Vector2 offsetMax)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: 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)
			rect.anchorMin = min;
			rect.anchorMax = max;
			rect.offsetMin = offsetMin;
			rect.offsetMax = offsetMax;
		}

		public void Dispose()
		{
			if ((Object)(object)root != (Object)null)
			{
				Object.Destroy((Object)(object)root);
			}
			root = null;
			rows.Clear();
			categoryButtons.Clear();
			filterButtons.Clear();
		}
	}
	internal sealed class AchievementTracker : IDisposable
	{
		private sealed class Entry
		{
			internal GameObject Root;

			internal TextMeshProUGUI Name;

			internal TextMeshProUGUI Detail;

			internal Image Bar;
		}

		private readonly Plugin owner;

		private GameObject root;

		private RectTransform panel;

		private CanvasGroup group;

		private Canvas panelCanvas;

		private GraphicRaycaster panelRaycaster;

		private GameObject resizeGrip;

		private readonly List<Entry> entries = new List<Entry>();

		internal bool Exists => (Object)(object)root != (Object)null;

		internal AchievementTracker(Plugin plugin)
		{
			owner = plugin;
		}

		internal void Create()
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: 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)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_0213: 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_0231: Unknown result type (might be due to invalid IL or missing references)
			//IL_0240: Unknown result type (might be due to invalid IL or missing references)
			//IL_0265: Unknown result type (might be due to invalid IL or missing references)
			//IL_027a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0289: Unknown result type (might be due to invalid IL or missing references)
			//IL_0301: Unknown result type (might be due to invalid IL or missing references)
			//IL_0310: Unknown result type (might be due to invalid IL or missing references)
			//IL_0315: Unknown result type (might be due to invalid IL or missing references)
			//IL_032d: 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_0360: Unknown result type (might be due to invalid IL or missing references)
			//IL_0382: Unknown result type (might be due to invalid IL or missing references)
			//IL_0393: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c9