Decompiled source of NachoAchievementsGlobalSave v2.3.3

NachoAchievementsGlobalSave.dll

Decompiled 10 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("NachoAchievementsGlobalSave")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Global Save Addon for NachoAchievements")]
[assembly: AssemblyFileVersion("1.0.5.0")]
[assembly: AssemblyInformationalVersion("1.0.5")]
[assembly: AssemblyProduct("NachoAchievementsGlobalSave")]
[assembly: AssemblyTitle("NachoAchievementsGlobalSave")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.5.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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 NachoAchievementsGlobalSave
{
	[BepInPlugin("NachoAchievementsGlobalSave", "Nacho Achievements Global Save", "2.3.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class GlobalSavePlugin : BaseUnityPlugin
	{
		public const string GUID = "NachoAchievementsGlobalSave";

		public const string NAME = "Nacho Achievements Global Save";

		public const string VERSION = "2.3.0";

		private const string RESET_VERSION = "2.0.3";

		private const string VersionKey = "NachoGlobalSave_Version";

		internal static ManualLogSource Logger;

		private static Harmony _harmony;

		internal static FieldInfo AchievementsField;

		internal static MethodInfo ES3SaveMethod;

		internal static MethodInfo ES3LoadMethod;

		internal static MethodInfo ES3KeyExistsMethod;

		internal static MethodInfo ES3DeleteKeyMethod;

		internal static ulong CachedSteamId;

		internal static bool IsInitialized;

		private const string SaveFileName = "LCGeneralSaveData";

		private void Awake()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_0307: Unknown result type (might be due to invalid IL or missing references)
			//IL_0314: Expected O, but got Unknown
			//IL_035c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0369: Expected O, but got Unknown
			//IL_03d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e4: Expected O, but got Unknown
			//IL_04b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c0: Expected O, but got Unknown
			//IL_0453: Unknown result type (might be due to invalid IL or missing references)
			//IL_0460: Expected O, but got Unknown
			Logger = ((BaseUnityPlugin)this).Logger;
			_harmony = new Harmony("NachoAchievementsGlobalSave");
			Logger.LogInfo((object)"Initializing Global Save Add-on v2.3.0 (Steam ID Mode)...");
			Type type = AccessTools.TypeByName("NachoAchievements.NachoAchievements");
			if (type == null)
			{
				Logger.LogError((object)"Could not find NachoAchievements. Is the mod installed?");
				return;
			}
			AchievementsField = AccessTools.Field(type, "Achievements");
			Type type2 = AccessTools.TypeByName("ES3");
			if (type2 != null)
			{
				List<MethodInfo> declaredMethods = AccessTools.GetDeclaredMethods(type2);
				foreach (MethodInfo item in declaredMethods)
				{
					ParameterInfo[] parameters = item.GetParameters();
					if (item.Name == "Save" && item.IsGenericMethod && parameters.Length == 3 && parameters[2].ParameterType == typeof(string))
					{
						ES3SaveMethod = item;
					}
					if (item.Name == "Load" && item.IsGenericMethod && parameters.Length == 3 && parameters[1].ParameterType == typeof(string) && parameters[2].ParameterType.IsGenericParameter)
					{
						ES3LoadMethod = item;
					}
					if (item.Name == "KeyExists" && !item.IsGenericMethod && parameters.Length == 2 && parameters[0].ParameterType == typeof(string) && parameters[1].ParameterType == typeof(string))
					{
						ES3KeyExistsMethod = item;
					}
					if (item.Name == "DeleteKey" && !item.IsGenericMethod && parameters.Length == 2 && parameters[0].ParameterType == typeof(string) && parameters[1].ParameterType == typeof(string))
					{
						ES3DeleteKeyMethod = item;
					}
				}
				Logger.LogInfo((object)"Applying patches manually...");
				MethodInfo methodInfo = AccessTools.Method(type, "CreateAchievements", (Type[])null, (Type[])null);
				MethodInfo methodInfo2 = AccessTools.Method(type, "WriteAchievements", (Type[])null, (Type[])null);
				MethodInfo methodInfo3 = AccessTools.Method(typeof(SavePatches), "PostCreateAchievements", (Type[])null, (Type[])null);
				MethodInfo methodInfo4 = AccessTools.Method(typeof(SavePatches), "PostWriteAchievements", (Type[])null, (Type[])null);
				if (methodInfo != null && methodInfo3 != null)
				{
					_harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(methodInfo3), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					Logger.LogInfo((object)"Hooked CreateAchievements successfully.");
				}
				else
				{
					Logger.LogError((object)"Failed to hook CreateAchievements.");
				}
				if (methodInfo2 != null && methodInfo4 != null)
				{
					_harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, new HarmonyMethod(methodInfo4), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					Logger.LogInfo((object)"Hooked WriteAchievements successfully.");
				}
				Type type3 = AccessTools.TypeByName("QuickMenuManager");
				if (type3 != null)
				{
					MethodInfo methodInfo5 = AccessTools.Method(type3, "Update", (Type[])null, (Type[])null);
					if (methodInfo5 != null)
					{
						MethodInfo methodInfo6 = AccessTools.Method(typeof(MenuPatches), "PostQuickMenuUpdate", (Type[])null, (Type[])null);
						_harmony.Patch((MethodBase)methodInfo5, (HarmonyMethod)null, new HarmonyMethod(methodInfo6), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
						Logger.LogInfo((object)"Hooked QuickMenuManager.Update for controller support.");
					}
				}
				Type type4 = AccessTools.TypeByName("GameNetcodeStuff.PlayerControllerB");
				if (type4 != null)
				{
					MethodInfo methodInfo7 = AccessTools.Method(type4, "ConnectClientToPlayerObject", (Type[])null, (Type[])null);
					if (methodInfo7 != null)
					{
						MethodInfo methodInfo8 = AccessTools.Method(typeof(SavePatches), "PostPlayerConnect", (Type[])null, (Type[])null);
						_harmony.Patch((MethodBase)methodInfo7, (HarmonyMethod)null, new HarmonyMethod(methodInfo8), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
						Logger.LogInfo((object)"Hooked PlayerControllerB.ConnectClientToPlayerObject for Steam ID caching.");
					}
				}
				MethodInfo methodInfo9 = AccessTools.Method(type, "CreateAchievementGetText", (Type[])null, (Type[])null);
				if (methodInfo9 != null)
				{
					MethodInfo methodInfo10 = AccessTools.Method(typeof(AchievementPopupPatches), "CreateEnhancedAchievementPopup", (Type[])null, (Type[])null);
					_harmony.Patch((MethodBase)methodInfo9, new HarmonyMethod(methodInfo10), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					Logger.LogInfo((object)"Hooked CreateAchievementGetText for enhanced popup UI.");
				}
				Logger.LogInfo((object)"Global Save loaded successfully.");
			}
			else
			{
				Logger.LogError((object)"Could not find ES3. Is Lethal Company loaded correctly?");
			}
		}

		private void Update()
		{
			if (Keyboard.current != null && ((ButtonControl)Keyboard.current.f9Key).wasPressedThisFrame && DebugMenu.IsAuthorizedUser())
			{
				DebugMenu.ToggleDebugMenu();
			}
		}

		internal static string GetSaveKey()
		{
			if (CachedSteamId != 0)
			{
				return $"NachoAchievements_Player_{CachedSteamId}";
			}
			return "NachoAchievements_GlobalData";
		}

		internal static void CheckVersionAndReset()
		{
			try
			{
				if (ES3LoadMethod == null || ES3SaveMethod == null)
				{
					return;
				}
				MethodInfo methodInfo = ES3LoadMethod.MakeGenericMethod(typeof(string));
				string text = methodInfo.Invoke(null, new object[3] { "NachoGlobalSave_Version", "LCGeneralSaveData", "" }) as string;
				if (text != "2.0.3")
				{
					Logger.LogWarning((object)("Version mismatch detected. Saved: '" + text + "', Current: '2.0.3'"));
					Logger.LogWarning((object)"Performing one-time achievement data reset for data integrity...");
					string text2 = "NachoAchievements_GlobalData";
					if (ES3KeyExistsMethod != null && (bool)ES3KeyExistsMethod.Invoke(null, new object[2] { text2, "LCGeneralSaveData" }) && ES3DeleteKeyMethod != null)
					{
						ES3DeleteKeyMethod.Invoke(null, new object[2] { text2, "LCGeneralSaveData" });
						Logger.LogInfo((object)("Deleted old global data key: " + text2));
					}
					string saveKey = GetSaveKey();
					if (ES3KeyExistsMethod != null && saveKey != text2 && (bool)ES3KeyExistsMethod.Invoke(null, new object[2] { saveKey, "LCGeneralSaveData" }) && ES3DeleteKeyMethod != null)
					{
						ES3DeleteKeyMethod.Invoke(null, new object[2] { saveKey, "LCGeneralSaveData" });
						Logger.LogInfo((object)("Deleted player data key: " + saveKey));
					}
					ResetAchievementsInMemory();
					MethodInfo methodInfo2 = ES3SaveMethod.MakeGenericMethod(typeof(string));
					methodInfo2.Invoke(null, new object[3] { "NachoGlobalSave_Version", "2.0.3", "LCGeneralSaveData" });
					Logger.LogInfo((object)"Saved new version marker: 2.0.3");
				}
			}
			catch (Exception arg)
			{
				Logger.LogError((object)$"Version check failed: {arg}");
			}
		}

		internal static void ResetAchievementsInMemory()
		{
			try
			{
				if (AchievementsField == null)
				{
					return;
				}
				object value = AchievementsField.GetValue(null);
				if (!(value is Dictionary<string, Dictionary<string, string>> dictionary) || dictionary.Count == 0)
				{
					return;
				}
				int num = 0;
				int num2 = 0;
				foreach (KeyValuePair<string, Dictionary<string, string>> item in dictionary)
				{
					string key = item.Key;
					if (ES3KeyExistsMethod != null && ES3DeleteKeyMethod != null)
					{
						try
						{
							if ((bool)ES3KeyExistsMethod.Invoke(null, new object[2] { key, "LCGeneralSaveData" }))
							{
								ES3DeleteKeyMethod.Invoke(null, new object[2] { key, "LCGeneralSaveData" });
								num2++;
							}
						}
						catch
						{
						}
					}
					if (item.Value.ContainsKey("progress"))
					{
						item.Value["progress"] = "0";
					}
					if (item.Value.ContainsKey("completed"))
					{
						item.Value["completed"] = "False";
					}
					num++;
				}
				Logger.LogInfo((object)$"Reset {num} achievements in memory. Deleted {num2} ES3 keys.");
				try
				{
					string text = null;
					Type type = AccessTools.TypeByName("NachoAchievements.Util.Paths");
					if (type != null)
					{
						PropertyInfo propertyInfo = AccessTools.Property(type, "DataFolder");
						if (propertyInfo != null)
						{
							text = propertyInfo.GetValue(null) as string;
						}
					}
					if (string.IsNullOrEmpty(text))
					{
						string directoryName = Path.GetDirectoryName(Application.dataPath);
						text = Path.Combine(directoryName, "BepInEx", "config", "NachosAchievements");
					}
					if (!string.IsNullOrEmpty(text) && Directory.Exists(text))
					{
						Directory.Delete(text, recursive: true);
						Logger.LogInfo((object)("Deleted NachosAchievements folder: " + text));
					}
					else
					{
						Logger.LogInfo((object)"NachosAchievements folder does not exist, skipping deletion.");
					}
				}
				catch (Exception ex)
				{
					Logger.LogWarning((object)("Could not delete NachosAchievements folder: " + ex.Message));
				}
				Type type2 = AccessTools.TypeByName("NachoAchievements.NachoAchievements");
				if (type2 != null)
				{
					AccessTools.Method(type2, "WriteAchievements", (Type[])null, (Type[])null)?.Invoke(null, null);
					Logger.LogInfo((object)"Wrote fresh achievements to file.");
				}
			}
			catch (Exception arg)
			{
				Logger.LogError((object)$"Failed to reset achievements in memory: {arg}");
			}
		}
	}
	public static class SavePatches
	{
		private const string SaveFileName = "LCGeneralSaveData";

		public static void PostPlayerConnect(object __instance)
		{
			try
			{
				FieldInfo fieldInfo = AccessTools.Field(__instance.GetType(), "playerSteamId");
				if (!(fieldInfo != null))
				{
					return;
				}
				ulong num = (ulong)fieldInfo.GetValue(__instance);
				if (num != 0)
				{
					GlobalSavePlugin.CachedSteamId = num;
					GlobalSavePlugin.Logger.LogInfo((object)$"Cached Steam ID: {num}");
					if (!GlobalSavePlugin.IsInitialized)
					{
						GlobalSavePlugin.CheckVersionAndReset();
						GlobalSavePlugin.IsInitialized = true;
						LoadAchievementsFromGlobal();
					}
				}
			}
			catch (Exception arg)
			{
				GlobalSavePlugin.Logger.LogError((object)$"Failed to cache Steam ID: {arg}");
			}
		}

		public static void PostCreateAchievements()
		{
			if (GlobalSavePlugin.CachedSteamId == 0)
			{
				GlobalSavePlugin.Logger.LogInfo((object)"Steam ID not yet available, will load achievements after player connects.");
			}
			else
			{
				LoadAchievementsFromGlobal();
			}
		}

		private static void LoadAchievementsFromGlobal()
		{
			try
			{
				if (GlobalSavePlugin.AchievementsField == null || GlobalSavePlugin.ES3LoadMethod == null)
				{
					return;
				}
				object value = GlobalSavePlugin.AchievementsField.GetValue(null);
				if (!(value is Dictionary<string, Dictionary<string, string>> dictionary))
				{
					return;
				}
				string saveKey = GlobalSavePlugin.GetSaveKey();
				MethodInfo methodInfo = GlobalSavePlugin.ES3LoadMethod.MakeGenericMethod(dictionary.GetType());
				object obj = Activator.CreateInstance(dictionary.GetType());
				if (methodInfo.Invoke(null, new object[3] { saveKey, "LCGeneralSaveData", obj }) is Dictionary<string, Dictionary<string, string>> dictionary2 && dictionary2.Count > 0)
				{
					int num = 0;
					foreach (KeyValuePair<string, Dictionary<string, string>> item in dictionary2)
					{
						if (dictionary.ContainsKey(item.Key))
						{
							if (item.Value.ContainsKey("progress"))
							{
								dictionary[item.Key]["progress"] = item.Value["progress"];
							}
							if (item.Value.ContainsKey("completed"))
							{
								dictionary[item.Key]["completed"] = item.Value["completed"];
							}
							num++;
						}
					}
					GlobalSavePlugin.Logger.LogInfo((object)$"[Steam ID: {GlobalSavePlugin.CachedSteamId}] Restored {num} achievements from Global Save.");
				}
				else
				{
					GlobalSavePlugin.Logger.LogInfo((object)$"[Steam ID: {GlobalSavePlugin.CachedSteamId}] No saved achievement data found, starting fresh.");
				}
			}
			catch (Exception arg)
			{
				GlobalSavePlugin.Logger.LogError((object)$"Failed to load achievements: {arg}");
			}
		}

		public static void PostWriteAchievements()
		{
			try
			{
				if (!(GlobalSavePlugin.AchievementsField == null) && !(GlobalSavePlugin.ES3SaveMethod == null))
				{
					object value = GlobalSavePlugin.AchievementsField.GetValue(null);
					if (value != null)
					{
						string saveKey = GlobalSavePlugin.GetSaveKey();
						MethodInfo methodInfo = GlobalSavePlugin.ES3SaveMethod.MakeGenericMethod(value.GetType());
						methodInfo.Invoke(null, new object[3] { saveKey, value, "LCGeneralSaveData" });
						GlobalSavePlugin.Logger.LogInfo((object)$"[Steam ID: {GlobalSavePlugin.CachedSteamId}] Saved achievements to Global Save.");
					}
				}
			}
			catch (Exception arg)
			{
				GlobalSavePlugin.Logger.LogError((object)$"Failed to save achievements: {arg}");
			}
		}
	}
	public static class MenuPatches
	{
		private static bool _wasStartPressed = false;

		private static bool _wasBPressed = false;

		private static bool _wasDPadUpPressed = false;

		private static bool _wasDPadDownPressed = false;

		private static float _stickScrollCooldown = 0f;

		private const float STICK_SCROLL_DELAY = 0.12f;

		private static bool _wasUpArrowPressed = false;

		private static bool _wasDownArrowPressed = false;

		private static bool _wasEscapePressed = false;

		private static float _keyboardScrollCooldown = 0f;

		private static bool _isControllerMode = false;

		private static float _lastControllerInput = 0f;

		private static float _lastMouseInput = 0f;

		private static bool _wasMouseLeftPressed = false;

		private static bool _isDraggingScrollbar = false;

		private static int _selectedIndex = 0;

		private static TMP_FontAsset _gameFont = null;

		private static bool _fontLoaded = false;

		private static GameObject _uiContainer = null;

		private static GameObject _backgroundPanel = null;

		private static GameObject _contentArea = null;

		private static GameObject _titleBar = null;

		private static GameObject _progressBar = null;

		private static GameObject _scrollbarBg = null;

		private static GameObject _scrollbarHandle = null;

		private static GameObject _selectionHighlight = null;

		private static GameObject _descriptionPanel = null;

		private static TextMeshProUGUI _descriptionText = null;

		private static TextMeshProUGUI _titleText = null;

		private static TextMeshProUGUI _progressText = null;

		private static bool _cacheInitialized = false;

		private static Type _nachoType;

		private static FieldInfo _achievementsTextField;

		private static FieldInfo _achievementsField;

		private static FieldInfo _tmpField;

		private static FieldInfo _prevTextField;

		private static Type _gameNetworkManagerType;

		private static PropertyInfo _gnmInstanceProp;

		private static FieldInfo _localPlayerField;

		private static FieldInfo _quickMenuField;

		private static FieldInfo _mainButtonsField;

		private static readonly Color PANEL_BG_COLOR = new Color(0.08f, 0.08f, 0.12f, 0.95f);

		private static readonly Color TITLE_BAR_COLOR = new Color(0.15f, 0.12f, 0.08f, 1f);

		private static readonly Color ACCENT_COLOR = new Color(1f, 0.8f, 0.2f, 1f);

		private static readonly Color COMPLETED_COLOR = new Color(0.3f, 0.9f, 0.3f, 1f);

		private static readonly Color LOCKED_COLOR = new Color(0.5f, 0.5f, 0.5f, 1f);

		private static readonly Color HIGHLIGHT_COLOR = new Color(1f, 0.8f, 0.2f, 0.25f);

		private static Dictionary<int, Sprite> _badgeSprites = new Dictionary<int, Sprite>();

		private static Sprite _unlockedOverlay = null;

		private static Sprite _lockedOverlay = null;

		private static bool _badgesLoaded = false;

		private static string _badgesPath = null;

		private static AssetBundle _badgeBundle = null;

		public static int GetBadgeCount()
		{
			LoadBadgeImages();
			return _badgeSprites.Count;
		}

		public static bool HasBadgeSprite(int index)
		{
			LoadBadgeImages();
			return _badgeSprites.ContainsKey(index);
		}

		public static Sprite GetBadgeSprite(int index)
		{
			LoadBadgeImages();
			return _badgeSprites.ContainsKey(index) ? _badgeSprites[index] : null;
		}

		private static void LoadBadgeImages()
		{
			if (_badgesLoaded)
			{
				return;
			}
			_badgesLoaded = true;
			try
			{
				string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
				string text = Path.Combine(directoryName, "nachoachievementsbadges");
				if (File.Exists(text))
				{
					LoadFromAssetBundle(text);
					if (_badgeSprites.Count > 0)
					{
						GlobalSavePlugin.Logger.LogInfo((object)$"Loaded {_badgeSprites.Count} badges from AssetBundle");
						return;
					}
				}
				_badgesPath = Path.Combine(directoryName, "Badges");
				if (!Directory.Exists(_badgesPath))
				{
					_badgesPath = Path.Combine(Directory.GetParent(directoryName)?.FullName ?? directoryName, "Badges");
				}
				if (!Directory.Exists(_badgesPath))
				{
					GlobalSavePlugin.Logger.LogWarning((object)"No AssetBundle or Badges folder found");
				}
				else
				{
					LoadFromPngFolder();
				}
			}
			catch (Exception arg)
			{
				GlobalSavePlugin.Logger.LogError((object)$"Failed to load badges: {arg}");
			}
		}

		private static void LoadFromAssetBundle(string bundlePath)
		{
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				_badgeBundle = AssetBundle.LoadFromFile(bundlePath);
				if ((Object)(object)_badgeBundle == (Object)null)
				{
					GlobalSavePlugin.Logger.LogWarning((object)"Failed to load AssetBundle");
					return;
				}
				Sprite[] array = _badgeBundle.LoadAllAssets<Sprite>();
				GlobalSavePlugin.Logger.LogInfo((object)$"AssetBundle contains {array.Length} sprites");
				if (array.Length != 0)
				{
					Sprite[] array2 = array;
					foreach (Sprite val in array2)
					{
						MatchAndStoreBadge(((Object)val).name, val);
					}
					return;
				}
				Texture2D[] array3 = _badgeBundle.LoadAllAssets<Texture2D>();
				GlobalSavePlugin.Logger.LogInfo((object)$"AssetBundle contains {array3.Length} textures");
				Texture2D[] array4 = array3;
				foreach (Texture2D val2 in array4)
				{
					try
					{
						Sprite sprite = Sprite.Create(val2, new Rect(0f, 0f, (float)((Texture)val2).width, (float)((Texture)val2).height), new Vector2(0.5f, 0.5f));
						MatchAndStoreBadge(((Object)val2).name, sprite);
					}
					catch (Exception ex)
					{
						GlobalSavePlugin.Logger.LogWarning((object)("Failed to create sprite from " + ((Object)val2).name + ": " + ex.Message));
					}
				}
			}
			catch (Exception ex2)
			{
				GlobalSavePlugin.Logger.LogError((object)("AssetBundle load error: " + ex2.Message));
			}
		}

		private static void MatchAndStoreBadge(string name, Sprite sprite)
		{
			for (int i = 1; i <= 32; i++)
			{
				string value = $"{i:D2}_";
				if (name.StartsWith(value))
				{
					_badgeSprites[i] = sprite;
					GlobalSavePlugin.Logger.LogInfo((object)$"Loaded badge {i}: {name}");
					return;
				}
			}
			if (name.StartsWith("Overlay_Unlocked"))
			{
				_unlockedOverlay = sprite;
				GlobalSavePlugin.Logger.LogInfo((object)("Loaded overlay: " + name));
			}
			else if (name.StartsWith("Overlay_Locked"))
			{
				_lockedOverlay = sprite;
				GlobalSavePlugin.Logger.LogInfo((object)("Loaded overlay: " + name));
			}
		}

		private static void LoadFromPngFolder()
		{
			try
			{
				GlobalSavePlugin.Logger.LogInfo((object)("Loading badges from " + _badgesPath));
				for (int i = 1; i <= 32; i++)
				{
					string searchPattern = $"{i:D2}_*.png";
					string[] files = Directory.GetFiles(_badgesPath, searchPattern);
					if (files.Length != 0)
					{
						Sprite val = LoadSpriteFromFile(files[0]);
						if ((Object)(object)val != (Object)null)
						{
							_badgeSprites[i] = val;
						}
					}
				}
				string text = Path.Combine(_badgesPath, "Overlay_Unlocked.png");
				string text2 = Path.Combine(_badgesPath, "Overlay_Locked.png");
				if (File.Exists(text))
				{
					_unlockedOverlay = LoadSpriteFromFile(text);
				}
				if (File.Exists(text2))
				{
					_lockedOverlay = LoadSpriteFromFile(text2);
				}
				GlobalSavePlugin.Logger.LogInfo((object)$"Loaded {_badgeSprites.Count} badge images from PNG");
			}
			catch (Exception ex)
			{
				GlobalSavePlugin.Logger.LogError((object)("PNG folder load error: " + ex.Message));
			}
		}

		private static Sprite LoadSpriteFromFile(string filePath)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				byte[] array = File.ReadAllBytes(filePath);
				Texture2D val = new Texture2D(2, 2);
				if (ImageConversion.LoadImage(val, array))
				{
					((Texture)val).filterMode = (FilterMode)1;
					return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f));
				}
			}
			catch
			{
			}
			return null;
		}

		private static void LoadGameFont()
		{
			if (_fontLoaded)
			{
				return;
			}
			_fontLoaded = true;
			try
			{
				if (_nachoType != null)
				{
					FieldInfo fieldInfo = AccessTools.Field(_nachoType, "AchievementsFont");
					if (fieldInfo != null)
					{
						object? value = fieldInfo.GetValue(null);
						_gameFont = (TMP_FontAsset)((value is TMP_FontAsset) ? value : null);
						if ((Object)(object)_gameFont != (Object)null)
						{
							GlobalSavePlugin.Logger.LogInfo((object)"Using NachoAchievements font");
							return;
						}
					}
				}
				TMP_FontAsset[] array = Resources.FindObjectsOfTypeAll<TMP_FontAsset>();
				TMP_FontAsset[] array2 = array;
				foreach (TMP_FontAsset val in array2)
				{
					if (((Object)val).name.Contains("3270"))
					{
						_gameFont = val;
						GlobalSavePlugin.Logger.LogInfo((object)("Found game font: " + ((Object)val).name));
						return;
					}
				}
				if (array.Length != 0)
				{
					_gameFont = array[0];
					GlobalSavePlugin.Logger.LogInfo((object)("Using fallback font: " + ((Object)_gameFont).name));
				}
			}
			catch (Exception arg)
			{
				GlobalSavePlugin.Logger.LogError((object)$"Failed to load game font: {arg}");
			}
		}

		private static void InitializeCache()
		{
			if (!_cacheInitialized)
			{
				_nachoType = AccessTools.TypeByName("NachoAchievements.NachoAchievements");
				if (_nachoType != null)
				{
					_achievementsTextField = AccessTools.Field(_nachoType, "AchievementsText");
					_achievementsField = AccessTools.Field(_nachoType, "Achievements");
					_tmpField = AccessTools.Field(_nachoType, "TMP");
					_prevTextField = AccessTools.Field(_nachoType, "prevText");
				}
				_gameNetworkManagerType = AccessTools.TypeByName("GameNetworkManager");
				if (_gameNetworkManagerType != null)
				{
					_gnmInstanceProp = AccessTools.Property(_gameNetworkManagerType, "Instance");
					_localPlayerField = AccessTools.Field(_gameNetworkManagerType, "localPlayerController");
				}
				_cacheInitialized = true;
			}
		}

		public static void PostQuickMenuUpdate(object __instance)
		{
			try
			{
				if (!_cacheInitialized)
				{
					InitializeCache();
				}
				if (_nachoType == null || _achievementsTextField == null)
				{
					return;
				}
				if (!(_achievementsTextField.GetValue(null) is IList list) || list.Count == 0)
				{
					CleanupUI();
					return;
				}
				if ((Object)(object)_uiContainer == (Object)null)
				{
					CreateEnhancedUI(list);
					_selectedIndex = 0;
				}
				DetectInputMode();
				Gamepad current = Gamepad.current;
				if (current != null)
				{
					HandleGamepadInput(current, list);
				}
				Keyboard current2 = Keyboard.current;
				if (current2 != null)
				{
					HandleKeyboardInput(current2, list);
				}
				ClearMouseDescription();
				UpdateUI(list);
			}
			catch (Exception arg)
			{
				GlobalSavePlugin.Logger.LogError((object)$"Menu update failed: {arg}");
			}
		}

		private static void DetectInputMode()
		{
			//IL_0102: 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)
			Gamepad current = Gamepad.current;
			if (current != null && (current.dpad.up.isPressed || current.dpad.down.isPressed || Mathf.Abs(((InputControl<float>)(object)((Vector2Control)current.leftStick).y).ReadValue()) > 0.3f || current.buttonSouth.isPressed || current.buttonEast.isPressed))
			{
				_lastControllerInput = Time.time;
				_isControllerMode = true;
			}
			Keyboard current2 = Keyboard.current;
			if (current2 != null && (((ButtonControl)current2.upArrowKey).isPressed || ((ButtonControl)current2.downArrowKey).isPressed || ((ButtonControl)current2.wKey).isPressed || ((ButtonControl)current2.sKey).isPressed))
			{
				_lastControllerInput = Time.time;
				_isControllerMode = true;
			}
			Mouse current3 = Mouse.current;
			if (current3 == null)
			{
				return;
			}
			Vector2 val = ((InputControl<Vector2>)(object)((Pointer)current3).delta).ReadValue();
			if (((Vector2)(ref val)).magnitude > 5f)
			{
				_lastMouseInput = Time.time;
				if (_isControllerMode && Time.time - _lastControllerInput > 0.5f)
				{
					_isControllerMode = false;
				}
			}
		}

		private static void ClearMouseDescription()
		{
			try
			{
				if (_tmpField != null)
				{
					object value = _tmpField.GetValue(null);
					if (value != null)
					{
						Object.Destroy((Object)((value is Object) ? value : null));
						_tmpField.SetValue(null, null);
					}
				}
				if (_prevTextField != null)
				{
					_prevTextField.SetValue(null, string.Empty);
				}
				if (!(_achievementsTextField != null) || !(_achievementsTextField.GetValue(null) is IList list))
				{
					return;
				}
				foreach (object item in list)
				{
					GameObject val = (GameObject)((item is GameObject) ? item : null);
					if ((Object)(object)val != (Object)null && val.activeSelf)
					{
						val.SetActive(false);
					}
				}
			}
			catch
			{
			}
		}

		private static void HandleGamepadInput(Gamepad gamepad, IList achievementsText)
		{
			bool isPressed = gamepad.startButton.isPressed;
			bool isPressed2 = gamepad.buttonEast.isPressed;
			bool isPressed3 = gamepad.dpad.up.isPressed;
			bool isPressed4 = gamepad.dpad.down.isPressed;
			float num = ((InputControl<float>)(object)((Vector2Control)gamepad.leftStick).y).ReadValue();
			if (_wasStartPressed && !isPressed)
			{
				CloseAchievementsMenu(achievementsText);
			}
			else if (_wasBPressed && !isPressed2)
			{
				CloseAchievementsMenu(achievementsText);
			}
			if (isPressed3 && !_wasDPadUpPressed)
			{
				NavigateUp(achievementsText);
			}
			if (isPressed4 && !_wasDPadDownPressed)
			{
				NavigateDown(achievementsText);
			}
			_stickScrollCooldown -= Time.deltaTime;
			if (_stickScrollCooldown <= 0f)
			{
				if (num > 0.5f)
				{
					NavigateUp(achievementsText);
					_stickScrollCooldown = 0.12f;
				}
				else if (num < -0.5f)
				{
					NavigateDown(achievementsText);
					_stickScrollCooldown = 0.12f;
				}
			}
			_wasStartPressed = isPressed;
			_wasBPressed = isPressed2;
			_wasDPadUpPressed = isPressed3;
			_wasDPadDownPressed = isPressed4;
		}

		private static void HandleKeyboardInput(Keyboard keyboard, IList achievementsText)
		{
			bool flag = ((ButtonControl)keyboard.upArrowKey).isPressed || ((ButtonControl)keyboard.wKey).isPressed;
			bool flag2 = ((ButtonControl)keyboard.downArrowKey).isPressed || ((ButtonControl)keyboard.sKey).isPressed;
			bool isPressed = ((ButtonControl)keyboard.escapeKey).isPressed;
			if (_wasEscapePressed && !isPressed)
			{
				CloseAchievementsMenu(achievementsText);
			}
			if (flag && !_wasUpArrowPressed)
			{
				NavigateUp(achievementsText);
				_keyboardScrollCooldown = 0.4f;
			}
			else if (flag2 && !_wasDownArrowPressed)
			{
				NavigateDown(achievementsText);
				_keyboardScrollCooldown = 0.4f;
			}
			else if (_keyboardScrollCooldown > 0f)
			{
				_keyboardScrollCooldown -= Time.deltaTime;
			}
			else if (_keyboardScrollCooldown <= 0f)
			{
				if (flag && _wasUpArrowPressed)
				{
					NavigateUp(achievementsText);
					_keyboardScrollCooldown = 0.12f;
				}
				else if (flag2 && _wasDownArrowPressed)
				{
					NavigateDown(achievementsText);
					_keyboardScrollCooldown = 0.12f;
				}
			}
			_wasUpArrowPressed = flag;
			_wasDownArrowPressed = flag2;
			_wasEscapePressed = isPressed;
		}

		private static void NavigateUp(IList achievementsText)
		{
			if (_selectedIndex > 0)
			{
				_selectedIndex--;
				ScrollToSelectedItem(achievementsText);
				UpdateDescription();
			}
		}

		private static void NavigateDown(IList achievementsText)
		{
			if (_selectedIndex < achievementsText.Count - 1)
			{
				_selectedIndex++;
				ScrollToSelectedItem(achievementsText);
				UpdateDescription();
			}
		}

		private static void ScrollToSelectedItem(IList achievementsText)
		{
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			if (achievementsText.Count == 0 || (Object)(object)_contentArea == (Object)null)
			{
				return;
			}
			Transform val = _contentArea.transform.Find($"Card_{_selectedIndex}");
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			RectTransform component = ((Component)val).GetComponent<RectTransform>();
			if (!((Object)(object)component == (Object)null))
			{
				float y = component.anchoredPosition.y;
				float num = 200f;
				float num2 = -200f;
				if (y > num)
				{
					float num3 = y - num + 20f;
					ScrollAllCards(0f - num3);
				}
				else if (y < num2)
				{
					float delta = num2 - y + 20f;
					ScrollAllCards(delta);
				}
			}
		}

		private static void ScrollAllCards(float delta)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_contentArea == (Object)null)
			{
				return;
			}
			foreach (Transform item in _contentArea.transform)
			{
				Transform val = item;
				if (!(((Object)val).name == "SelectionHighlight"))
				{
					RectTransform component = ((Component)val).GetComponent<RectTransform>();
					if ((Object)(object)component != (Object)null)
					{
						component.anchoredPosition += new Vector2(0f, delta);
					}
				}
			}
		}

		private static void ScrollAllItems(IList achievementsText, float delta)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			foreach (object item in achievementsText)
			{
				GameObject val = (GameObject)((item is GameObject) ? item : null);
				if ((Object)(object)val != (Object)null)
				{
					RectTransform component = val.GetComponent<RectTransform>();
					if ((Object)(object)component != (Object)null)
					{
						component.anchoredPosition += new Vector2(0f, delta);
					}
				}
			}
		}

		private static void CreateEnhancedUI(IList achievementsText)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Expected O, but got Unknown
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: 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_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: 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_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0209: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Expected O, but got Unknown
			//IL_0287: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0306: Unknown result type (might be due to invalid IL or missing references)
			//IL_031f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0330: Unknown result type (might be due to invalid IL or missing references)
			//IL_0337: Expected O, but got Unknown
			//IL_0357: Unknown result type (might be due to invalid IL or missing references)
			//IL_0377: Unknown result type (might be due to invalid IL or missing references)
			//IL_038e: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03dd: Expected O, but got Unknown
			//IL_0444: Unknown result type (might be due to invalid IL or missing references)
			//IL_045a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0467: Unknown result type (might be due to invalid IL or missing references)
			//IL_0474: 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_0498: Expected O, but got Unknown
			//IL_04cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_050f: Unknown result type (might be due to invalid IL or missing references)
			//IL_055e: Unknown result type (might be due to invalid IL or missing references)
			//IL_056d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0586: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_05bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_05f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0612: Unknown result type (might be due to invalid IL or missing references)
			//IL_0626: Unknown result type (might be due to invalid IL or missing references)
			//IL_062d: Expected O, but got Unknown
			//IL_06bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_06d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_06de: Unknown result type (might be due to invalid IL or missing references)
			//IL_06eb: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				object? obj = AccessTools.Field(_nachoType, "AchievementsCanvas")?.GetValue(null);
				Canvas val = (Canvas)((obj is Canvas) ? obj : null);
				if (!((Object)(object)val == (Object)null))
				{
					_uiContainer = new GameObject("EnhancedAchievementsUI");
					_uiContainer.transform.SetParent(((Component)val).transform, false);
					RectTransform val2 = _uiContainer.AddComponent<RectTransform>();
					val2.anchorMin = new Vector2(0.5f, 0.5f);
					val2.anchorMax = new Vector2(0.5f, 0.5f);
					val2.pivot = new Vector2(0.5f, 0.5f);
					val2.anchoredPosition = Vector2.zero;
					val2.sizeDelta = new Vector2(750f, 700f);
					_backgroundPanel = CreatePanel(_uiContainer.transform, "BackgroundPanel", Vector2.zero, new Vector2(700f, 680f), new Color(0.05f, 0.05f, 0.08f, 0.97f));
					GameObject val3 = CreatePanel(_backgroundPanel.transform, "OuterBorder", Vector2.zero, new Vector2(704f, 684f), new Color(0.4f, 0.35f, 0.15f, 1f));
					val3.transform.SetAsFirstSibling();
					GameObject val4 = CreatePanel(_backgroundPanel.transform, "InnerBorder", Vector2.zero, new Vector2(702f, 682f), new Color(0.2f, 0.18f, 0.08f, 1f));
					val4.transform.SetSiblingIndex(1);
					GameObject val5 = CreatePanel(_backgroundPanel.transform, "Header", new Vector2(0f, 300f), new Vector2(680f, 70f), new Color(0.12f, 0.1f, 0.06f, 1f));
					LoadGameFont();
					GameObject val6 = new GameObject("TitleText");
					val6.transform.SetParent(val5.transform, false);
					_titleText = val6.AddComponent<TextMeshProUGUI>();
					((TMP_Text)_titleText).text = "★ 도 전 과 제 ★";
					if ((Object)(object)_gameFont != (Object)null)
					{
						((TMP_Text)_titleText).font = _gameFont;
					}
					((TMP_Text)_titleText).fontSize = 36f;
					((TMP_Text)_titleText).alignment = (TextAlignmentOptions)514;
					((Graphic)_titleText).color = ACCENT_COLOR;
					((TMP_Text)_titleText).fontStyle = (FontStyles)1;
					((TMP_Text)_titleText).characterSpacing = 8f;
					RectTransform component = val6.GetComponent<RectTransform>();
					component.anchorMin = Vector2.zero;
					component.anchorMax = Vector2.one;
					component.sizeDelta = Vector2.zero;
					GameObject val7 = CreatePanel(_backgroundPanel.transform, "ProgressBg", new Vector2(0f, 255f), new Vector2(660f, 25f), new Color(0.15f, 0.15f, 0.18f, 1f));
					GameObject val8 = new GameObject("ProgressFill");
					val8.transform.SetParent(val7.transform, false);
					Image val9 = val8.AddComponent<Image>();
					((Graphic)val9).color = ACCENT_COLOR;
					RectTransform component2 = val8.GetComponent<RectTransform>();
					component2.anchorMin = new Vector2(0f, 0f);
					component2.anchorMax = new Vector2(0f, 1f);
					component2.pivot = new Vector2(0f, 0.5f);
					component2.offsetMin = Vector2.zero;
					component2.offsetMax = Vector2.zero;
					float maxWidth = 660f;
					GameObject val10 = new GameObject("ProgressText");
					val10.transform.SetParent(val7.transform, false);
					_progressText = val10.AddComponent<TextMeshProUGUI>();
					if ((Object)(object)_gameFont != (Object)null)
					{
						((TMP_Text)_progressText).font = _gameFont;
					}
					((TMP_Text)_progressText).fontSize = 16f;
					((TMP_Text)_progressText).alignment = (TextAlignmentOptions)514;
					((Graphic)_progressText).color = Color.white;
					RectTransform component3 = val10.GetComponent<RectTransform>();
					component3.anchorMin = Vector2.zero;
					component3.anchorMax = Vector2.one;
					component3.sizeDelta = Vector2.zero;
					UpdateProgressBar(val8, maxWidth);
					_contentArea = new GameObject("ContentArea");
					_contentArea.transform.SetParent(_backgroundPanel.transform, false);
					RectTransform val11 = _contentArea.AddComponent<RectTransform>();
					val11.anchoredPosition = new Vector2(0f, -30f);
					val11.sizeDelta = new Vector2(670f, 500f);
					Image val12 = _contentArea.AddComponent<Image>();
					((Graphic)val12).color = new Color(0f, 0f, 0f, 0.01f);
					Mask val13 = _contentArea.AddComponent<Mask>();
					val13.showMaskGraphic = false;
					CreateAchievementCards(achievementsText, _contentArea.transform, 650f);
					_scrollbarBg = CreatePanel(_backgroundPanel.transform, "ScrollbarBg", new Vector2(335f, -30f), new Vector2(8f, 480f), new Color(0.2f, 0.2f, 0.25f, 0.6f));
					_scrollbarHandle = CreatePanel(_scrollbarBg.transform, "ScrollbarHandle", new Vector2(0f, 200f), new Vector2(8f, 60f), ACCENT_COLOR);
					_descriptionPanel = CreatePanel(_backgroundPanel.transform, "DescriptionPanel", new Vector2(0f, -305f), new Vector2(680f, 60f), new Color(0.08f, 0.08f, 0.1f, 1f));
					GameObject val14 = new GameObject("DescriptionText");
					val14.transform.SetParent(_descriptionPanel.transform, false);
					_descriptionText = val14.AddComponent<TextMeshProUGUI>();
					((TMP_Text)_descriptionText).text = "▲ ▼ 도전과제를 선택하세요";
					if ((Object)(object)_gameFont != (Object)null)
					{
						((TMP_Text)_descriptionText).font = _gameFont;
					}
					((TMP_Text)_descriptionText).fontSize = 18f;
					((TMP_Text)_descriptionText).alignment = (TextAlignmentOptions)514;
					((Graphic)_descriptionText).color = new Color(0.7f, 0.7f, 0.7f, 1f);
					RectTransform component4 = val14.GetComponent<RectTransform>();
					component4.anchorMin = Vector2.zero;
					component4.anchorMax = Vector2.one;
					component4.sizeDelta = Vector2.zero;
					HideOriginalItems(achievementsText);
					if (achievementsText.Count > 0)
					{
						_selectedIndex = 0;
						UpdateDescription();
					}
				}
			}
			catch (Exception arg)
			{
				GlobalSavePlugin.Logger.LogError((object)$"Failed to create enhanced UI: {arg}");
			}
		}

		private static void UpdateProgressBar(GameObject progressFill, float maxWidth)
		{
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0291: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (!(_achievementsField?.GetValue(null) is Dictionary<string, Dictionary<string, string>> dictionary))
				{
					return;
				}
				int count = dictionary.Count;
				int num = dictionary.Values.Count((Dictionary<string, string> a) => a.ContainsKey("completed") && a["completed"] == "True");
				float num2 = ((count > 0) ? ((float)num / (float)count) : 0f);
				bool flag = num == count && count > 0;
				RectTransform component = progressFill.GetComponent<RectTransform>();
				Image component2 = progressFill.GetComponent<Image>();
				component.anchorMin = new Vector2(0f, 0f);
				component.anchorMax = new Vector2(num2, 1f);
				component.offsetMin = Vector2.zero;
				component.offsetMax = Vector2.zero;
				if (flag)
				{
					RainbowGradientAnimator component3 = progressFill.GetComponent<RainbowGradientAnimator>();
					if ((Object)(object)component3 == (Object)null)
					{
						component3 = progressFill.AddComponent<RainbowGradientAnimator>();
						component3.speed = 0.4f;
						component3.waveLength = 0.6f;
						component3.saturation = 0.65f;
						component3.brightness = 0.95f;
					}
					ProgressGlowAnimator component4 = progressFill.GetComponent<ProgressGlowAnimator>();
					if ((Object)(object)component4 != (Object)null)
					{
						Object.Destroy((Object)(object)component4);
					}
				}
				else if ((Object)(object)component2 != (Object)null)
				{
					RainbowGradientAnimator component5 = progressFill.GetComponent<RainbowGradientAnimator>();
					if ((Object)(object)component5 != (Object)null)
					{
						Object.Destroy((Object)(object)component5);
					}
					((Graphic)component2).color = ACCENT_COLOR;
					if (num2 > 0.01f)
					{
						ProgressGlowAnimator component6 = progressFill.GetComponent<ProgressGlowAnimator>();
						if ((Object)(object)component6 == (Object)null)
						{
							component6 = progressFill.AddComponent<ProgressGlowAnimator>();
							component6.pulseSpeed = 3f;
							component6.minAlpha = 0.4f;
							component6.maxAlpha = 0.9f;
							component6.glowWidth = 12f;
						}
					}
				}
				if ((Object)(object)_progressText != (Object)null)
				{
					if (flag)
					{
						((TMP_Text)_progressText).text = $"★ {num}/{count} (100%) - 완전 정복! ★";
						((Graphic)_progressText).color = new Color(0.15f, 0.1f, 0f, 1f);
						((TMP_Text)_progressText).fontStyle = (FontStyles)1;
					}
					else
					{
						((TMP_Text)_progressText).text = $"{num}/{count} ({num2 * 100f:F1}%)";
						((Graphic)_progressText).color = Color.white;
						((TMP_Text)_progressText).fontStyle = (FontStyles)0;
					}
				}
			}
			catch
			{
			}
		}

		private static void CreateAchievementCards(IList achievementsText, Transform parent, float cardWidth)
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: 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_00f8: 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_0115: 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_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: 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_0209: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0231: Expected O, but got Unknown
			//IL_0281: Unknown result type (might be due to invalid IL or missing references)
			//IL_028e: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c8: Expected O, but got Unknown
			//IL_0304: Unknown result type (might be due to invalid IL or missing references)
			//IL_030b: Expected O, but got Unknown
			//IL_0387: 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_03b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_047a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0473: Unknown result type (might be due to invalid IL or missing references)
			//IL_04aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04da: Expected O, but got Unknown
			//IL_057d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0562: Unknown result type (might be due to invalid IL or missing references)
			//IL_059d: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b6: Unknown result type (might be due to invalid IL or missing references)
			if (!(_achievementsField?.GetValue(null) is Dictionary<string, Dictionary<string, string>> dictionary))
			{
				return;
			}
			LoadBadgeImages();
			LoadGameFont();
			string[] array = dictionary.Keys.ToArray();
			float num = 220f;
			float num2 = 70f;
			float num3 = 8f;
			_selectionHighlight = CreatePanel(parent, "SelectionHighlight", new Vector2(0f, num), new Vector2(cardWidth, num2), HIGHLIGHT_COLOR);
			_selectionHighlight.transform.SetAsFirstSibling();
			for (int i = 0; i < achievementsText.Count && i < array.Length; i++)
			{
				string text = array[i];
				Dictionary<string, string> dictionary2 = dictionary[text];
				bool flag = dictionary2.ContainsKey("completed") && dictionary2["completed"] == "True";
				float num4 = num - (float)i * (num2 + num3);
				GameObject val = CreatePanel(parent, $"Card_{i}", new Vector2(0f, num4), new Vector2(cardWidth, num2), flag ? new Color(0.12f, 0.18f, 0.12f, 0.9f) : new Color(0.1f, 0.1f, 0.12f, 0.9f));
				GameObject val2 = CreatePanel(val.transform, "Border", Vector2.zero, new Vector2(cardWidth + 2f, num2 + 2f), flag ? new Color(0.4f, 0.6f, 0.3f, 0.5f) : new Color(0.3f, 0.3f, 0.35f, 0.5f));
				val2.transform.SetAsFirstSibling();
				int key = i + 1;
				bool flag2 = _badgeSprites.ContainsKey(key);
				bool flag3 = flag2 && flag;
				GameObject val3 = CreatePanel(val.transform, "IconBg", new Vector2(0f - cardWidth / 2f + 45f, 0f), new Vector2(75f, 75f), flag3 ? Color.clear : (flag ? ACCENT_COLOR : LOCKED_COLOR));
				if (flag3)
				{
					GameObject val4 = new GameObject("BadgeImage");
					val4.transform.SetParent(val3.transform, false);
					Image val5 = val4.AddComponent<Image>();
					val5.sprite = _badgeSprites[key];
					val5.preserveAspect = true;
					RectTransform component = val4.GetComponent<RectTransform>();
					component.sizeDelta = new Vector2(70f, 70f);
					component.anchoredPosition = Vector2.zero;
				}
				else
				{
					GameObject val6 = CreatePanel(val3.transform, "IconInner", Vector2.zero, new Vector2(65f, 65f), flag ? new Color(0.2f, 0.15f, 0.05f, 1f) : new Color(0.25f, 0.25f, 0.28f, 1f));
					GameObject val7 = new GameObject("Symbol");
					val7.transform.SetParent(val3.transform, false);
					TextMeshProUGUI val8 = val7.AddComponent<TextMeshProUGUI>();
					((TMP_Text)val8).text = (flag ? "✓" : "?");
					((TMP_Text)val8).fontSize = (flag ? 28f : 32f);
					((TMP_Text)val8).alignment = (TextAlignmentOptions)514;
					((Graphic)val8).color = (Color)(flag ? ACCENT_COLOR : new Color(0.5f, 0.5f, 0.5f, 1f));
					((TMP_Text)val8).fontStyle = (FontStyles)1;
					RectTransform component2 = val7.GetComponent<RectTransform>();
					component2.sizeDelta = new Vector2(55f, 55f);
				}
				GameObject val9 = new GameObject("Title");
				val9.transform.SetParent(val.transform, false);
				TextMeshProUGUI val10 = val9.AddComponent<TextMeshProUGUI>();
				object? obj = achievementsText[i];
				GameObject val11 = (GameObject)((obj is GameObject) ? obj : null);
				TextMeshProUGUI val12 = ((val11 != null) ? val11.GetComponent<TextMeshProUGUI>() : null);
				((TMP_Text)val10).text = ((val12 != null) ? ((TMP_Text)val12).text : null) ?? text;
				if ((Object)(object)_gameFont != (Object)null)
				{
					((TMP_Text)val10).font = _gameFont;
				}
				((TMP_Text)val10).fontSize = 20f;
				((TMP_Text)val10).alignment = (TextAlignmentOptions)513;
				((Graphic)val10).color = (Color)(flag ? COMPLETED_COLOR : new Color(0.85f, 0.85f, 0.85f, 1f));
				((TMP_Text)val10).fontStyle = (FontStyles)(flag ? 1 : 0);
				RectTransform component3 = val9.GetComponent<RectTransform>();
				component3.anchoredPosition = new Vector2(40f, 8f);
				component3.sizeDelta = new Vector2(cardWidth - 100f, 30f);
				GameObject val13 = new GameObject("Status");
				val13.transform.SetParent(val.transform, false);
				TextMeshProUGUI val14 = val13.AddComponent<TextMeshProUGUI>();
				((TMP_Text)val14).text = (flag ? "★ 달성 완료" : "○ 미달성");
				if ((Object)(object)_gameFont != (Object)null)
				{
					((TMP_Text)val14).font = _gameFont;
				}
				((TMP_Text)val14).fontSize = 14f;
				((TMP_Text)val14).alignment = (TextAlignmentOptions)513;
				((Graphic)val14).color = (flag ? new Color(0.7f, 0.7f, 0.4f, 1f) : new Color(0.5f, 0.5f, 0.5f, 1f));
				RectTransform component4 = val13.GetComponent<RectTransform>();
				component4.anchoredPosition = new Vector2(40f, -15f);
				component4.sizeDelta = new Vector2(cardWidth - 100f, 20f);
			}
		}

		private static void HideOriginalItems(IList achievementsText)
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Expected O, but got Unknown
			foreach (object item in achievementsText)
			{
				GameObject val = (GameObject)((item is GameObject) ? item : null);
				if ((Object)(object)val != (Object)null)
				{
					val.SetActive(false);
					RectTransform component = val.GetComponent<RectTransform>();
					if ((Object)(object)component != (Object)null)
					{
						component.anchoredPosition = new Vector2(-9999f, -9999f);
					}
				}
			}
			try
			{
				object? obj = AccessTools.Field(_nachoType, "AchievementsCanvas")?.GetValue(null);
				Canvas val2 = (Canvas)((obj is Canvas) ? obj : null);
				if (!((Object)(object)val2 != (Object)null))
				{
					return;
				}
				foreach (Transform item2 in ((Component)val2).transform)
				{
					Transform val3 = item2;
					if (((Object)((Component)val3).gameObject).name.StartsWith("AchievementsText"))
					{
						((Component)val3).gameObject.SetActive(false);
					}
				}
			}
			catch
			{
			}
		}

		private static void ReparentAchievementItems(IList achievementsText, Transform parent)
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			float num = 250f;
			float num2 = 75f;
			for (int i = 0; i < achievementsText.Count; i++)
			{
				object? obj = achievementsText[i];
				GameObject val = (GameObject)((obj is GameObject) ? obj : null);
				if (!((Object)(object)val == (Object)null))
				{
					val.transform.SetParent(parent, false);
					RectTransform component = val.GetComponent<RectTransform>();
					if ((Object)(object)component != (Object)null)
					{
						component.anchoredPosition = new Vector2(-50f, num - (float)i * num2);
					}
				}
			}
		}

		private static GameObject CreatePanel(Transform parent, string name, Vector2 position, Vector2 size, Color color)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name);
			val.transform.SetParent(parent, false);
			Image val2 = val.AddComponent<Image>();
			((Graphic)val2).color = color;
			RectTransform component = val.GetComponent<RectTransform>();
			component.anchoredPosition = position;
			component.sizeDelta = size;
			return val;
		}

		private static void StyleAchievementItems(IList achievementsText)
		{
		}

		private static void UpdateProgressText()
		{
			try
			{
				if (!((Object)(object)_progressText == (Object)null) && _achievementsField?.GetValue(null) is Dictionary<string, Dictionary<string, string>> dictionary)
				{
					int count = dictionary.Count;
					int num = dictionary.Values.Count((Dictionary<string, string> a) => a.ContainsKey("completed") && a["completed"] == "True");
					float num2 = ((count > 0) ? ((float)num / (float)count * 100f) : 0f);
					((TMP_Text)_progressText).text = $"진행률: {num}/{count} ({num2:F1}%)";
				}
			}
			catch
			{
			}
		}

		private static void UpdateDescription()
		{
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if ((Object)(object)_descriptionText == (Object)null || !(_achievementsField?.GetValue(null) is Dictionary<string, Dictionary<string, string>> dictionary))
				{
					return;
				}
				string[] array = dictionary.Keys.ToArray();
				if (_selectedIndex >= 0 && _selectedIndex < array.Length)
				{
					string key = array[_selectedIndex];
					if (dictionary[key].ContainsKey("description"))
					{
						((TMP_Text)_descriptionText).text = dictionary[key]["description"];
						((TMP_Text)_descriptionText).fontStyle = (FontStyles)0;
						((Graphic)_descriptionText).color = Color.white;
					}
				}
			}
			catch
			{
			}
		}

		private static void DetectMouseClick(IList achievementsText)
		{
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Invalid comparison between Unknown and I4
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: 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_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_contentArea == (Object)null)
			{
				return;
			}
			Mouse current = Mouse.current;
			if (current == null)
			{
				return;
			}
			bool isPressed = current.leftButton.isPressed;
			bool flag = isPressed && !_wasMouseLeftPressed;
			_wasMouseLeftPressed = isPressed;
			if (!flag)
			{
				return;
			}
			Vector2 val = ((InputControl<Vector2>)(object)((Pointer)current).position).ReadValue();
			for (int i = 0; i < achievementsText.Count; i++)
			{
				Transform val2 = _contentArea.transform.Find($"Card_{i}");
				if ((Object)(object)val2 == (Object)null)
				{
					continue;
				}
				RectTransform component = ((Component)val2).GetComponent<RectTransform>();
				if (!((Object)(object)component == (Object)null))
				{
					Vector3[] array = (Vector3[])(object)new Vector3[4];
					component.GetWorldCorners(array);
					Camera val3 = null;
					object? obj = AccessTools.Field(_nachoType, "AchievementsCanvas")?.GetValue(null);
					Canvas val4 = (Canvas)((obj is Canvas) ? obj : null);
					if ((Object)(object)val4 != (Object)null && (int)val4.renderMode > 0)
					{
						val3 = val4.worldCamera ?? Camera.main;
					}
					Vector2 val5;
					Vector2 val6;
					if ((Object)(object)val3 != (Object)null)
					{
						val5 = RectTransformUtility.WorldToScreenPoint(val3, array[0]);
						val6 = RectTransformUtility.WorldToScreenPoint(val3, array[2]);
					}
					else
					{
						val5 = Vector2.op_Implicit(array[0]);
						val6 = Vector2.op_Implicit(array[2]);
					}
					if (val.x >= val5.x && val.x <= val6.x && val.y >= val5.y && val.y <= val6.y)
					{
						_selectedIndex = i;
						_isControllerMode = false;
						UpdateDescription();
						break;
					}
				}
			}
		}

		private static void HandleMouseScroll(IList achievementsText)
		{
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_contentArea == (Object)null)
			{
				return;
			}
			Mouse current = Mouse.current;
			if (current == null)
			{
				return;
			}
			float num = ((InputControl<float>)(object)((Vector2Control)current.scroll).y).ReadValue();
			if (Mathf.Abs(num) < 1f)
			{
				return;
			}
			float num2 = 0.5f;
			float num3 = num * num2;
			float num4 = 70f;
			float num5 = 8f;
			float num6 = 220f;
			float num7 = (float)achievementsText.Count * (num4 + num5);
			float num8 = 500f;
			float num9 = Mathf.Max(0f, num7 - num8);
			Transform val = _contentArea.transform.Find("Card_0");
			if (!((Object)(object)val == (Object)null))
			{
				RectTransform component = ((Component)val).GetComponent<RectTransform>();
				if (!((Object)(object)component == (Object)null))
				{
					float y = component.anchoredPosition.y;
					float num10 = y - num6;
					float num11 = Mathf.Clamp(num10 - num3, 0f, num9);
					float delta = num11 - num10;
					ScrollAllCards(delta);
				}
			}
		}

		private static void HandleScrollbarClick(IList achievementsText)
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: 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_0150: 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_01d7: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_scrollbarBg == (Object)null || (Object)(object)_contentArea == (Object)null)
			{
				return;
			}
			Mouse current = Mouse.current;
			if (current == null)
			{
				return;
			}
			bool isPressed = current.leftButton.isPressed;
			Vector2 val = ((InputControl<Vector2>)(object)((Pointer)current).position).ReadValue();
			RectTransform component = _scrollbarBg.GetComponent<RectTransform>();
			if ((Object)(object)component == (Object)null)
			{
				return;
			}
			Vector3[] array = (Vector3[])(object)new Vector3[4];
			component.GetWorldCorners(array);
			Vector2 val2 = Vector2.op_Implicit(array[0]);
			Vector2 val3 = Vector2.op_Implicit(array[2]);
			bool flag = val.x >= val2.x && val.x <= val3.x && val.y >= val2.y && val.y <= val3.y;
			if (isPressed && flag && !_isDraggingScrollbar)
			{
				_isDraggingScrollbar = true;
			}
			if (!isPressed)
			{
				_isDraggingScrollbar = false;
			}
			if (_isDraggingScrollbar && isPressed)
			{
				float num = Mathf.Clamp(val.y, val2.y, val3.y);
				float num2 = 1f - (num - val2.y) / (val3.y - val2.y);
				float num3 = 70f;
				float num4 = 8f;
				float num5 = 220f;
				float num6 = (float)achievementsText.Count * (num3 + num4);
				float num7 = 500f;
				float num8 = Mathf.Max(0f, num6 - num7);
				float num9 = num2 * num8;
				Transform val4 = _contentArea.transform.Find("Card_0");
				if (!((Object)(object)val4 == (Object)null))
				{
					RectTransform component2 = ((Component)val4).GetComponent<RectTransform>();
					float y = component2.anchoredPosition.y;
					float num10 = y - num5;
					float delta = num9 - num10;
					ScrollAllCards(delta);
				}
			}
		}

		private static void UpdateUI(IList achievementsText)
		{
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			HandleMouseScroll(achievementsText);
			HandleScrollbarClick(achievementsText);
			DetectMouseClick(achievementsText);
			if ((Object)(object)_selectionHighlight != (Object)null && (Object)(object)_contentArea != (Object)null && _selectedIndex >= 0 && _selectedIndex < achievementsText.Count)
			{
				_selectionHighlight.SetActive(true);
				Transform val = _contentArea.transform.Find($"Card_{_selectedIndex}");
				if ((Object)(object)val != (Object)null)
				{
					RectTransform component = ((Component)val).GetComponent<RectTransform>();
					RectTransform component2 = _selectionHighlight.GetComponent<RectTransform>();
					if ((Object)(object)component != (Object)null && (Object)(object)component2 != (Object)null)
					{
						component2.anchoredPosition = component.anchoredPosition;
					}
				}
				Image component3 = _selectionHighlight.GetComponent<Image>();
				if ((Object)(object)component3 != (Object)null)
				{
					((Graphic)component3).color = (_isControllerMode ? new Color(1f, 0.8f, 0.2f, 0.35f) : new Color(1f, 0.8f, 0.2f, 0.15f));
				}
			}
			UpdateScrollbar(achievementsText);
		}

		private static void UpdateScrollbar(IList achievementsText)
		{
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_scrollbarHandle == (Object)null || (Object)(object)_contentArea == (Object)null || achievementsText.Count == 0)
			{
				return;
			}
			try
			{
				int count = achievementsText.Count;
				float num = 70f;
				float num2 = 8f;
				float num3 = (float)count * (num + num2);
				float num4 = 500f;
				float num5 = Mathf.Max(0f, num3 - num4);
				if (num5 <= 0f)
				{
					_scrollbarHandle.SetActive(false);
					return;
				}
				_scrollbarHandle.SetActive(true);
				Transform val = _contentArea.transform.Find("Card_0");
				if (!((Object)(object)val == (Object)null))
				{
					RectTransform component = ((Component)val).GetComponent<RectTransform>();
					float num6 = 220f;
					float y = component.anchoredPosition.y;
					float num7 = y - num6;
					float num8 = Mathf.Clamp01(num7 / num5);
					RectTransform component2 = _scrollbarHandle.GetComponent<RectTransform>();
					float num9 = num4 - 40f;
					float num10 = Mathf.Max(40f, num9 * (num4 / num3));
					component2.sizeDelta = new Vector2(8f, num10);
					float num11 = (num9 - num10) / 2f - num8 * (num9 - num10);
					component2.anchoredPosition = new Vector2(0f, num11);
				}
			}
			catch
			{
			}
		}

		private static void CleanupUI()
		{
			if ((Object)(object)_uiContainer != (Object)null)
			{
				Object.Destroy((Object)(object)_uiContainer);
				_uiContainer = null;
				_backgroundPanel = null;
				_contentArea = null;
				_titleBar = null;
				_progressBar = null;
				_scrollbarBg = null;
				_scrollbarHandle = null;
				_selectionHighlight = null;
				_descriptionPanel = null;
				_descriptionText = null;
				_titleText = null;
				_progressText = null;
			}
			_selectedIndex = 0;
			_isControllerMode = false;
			_wasUpArrowPressed = false;
			_wasDownArrowPressed = false;
			_wasEscapePressed = false;
		}

		private static void CloseAchievementsMenu(IList achievementsText)
		{
			try
			{
				CleanupUI();
				ClearMouseDescription();
				foreach (object item in achievementsText)
				{
					GameObject val = (GameObject)((item is GameObject) ? item : null);
					if ((Object)(object)val != (Object)null)
					{
						Object.Destroy((Object)(object)val);
					}
				}
				achievementsText.Clear();
				if (_gnmInstanceProp != null && _localPlayerField != null)
				{
					object value = _gnmInstanceProp.GetValue(null);
					if (value != null)
					{
						object value2 = _localPlayerField.GetValue(value);
						if (value2 != null)
						{
							if (_quickMenuField == null)
							{
								_quickMenuField = AccessTools.Field(value2.GetType(), "quickMenuManager");
							}
							object obj = _quickMenuField?.GetValue(value2);
							if (obj != null)
							{
								if (_mainButtonsField == null)
								{
									_mainButtonsField = AccessTools.Field(obj.GetType(), "mainButtonsPanel");
								}
								object? obj2 = _mainButtonsField?.GetValue(obj);
								GameObject val2 = (GameObject)((obj2 is GameObject) ? obj2 : null);
								if (val2 != null)
								{
									val2.SetActive(true);
								}
							}
						}
					}
				}
				GlobalSavePlugin.Logger.LogInfo((object)"Closed achievements menu.");
			}
			catch (Exception arg)
			{
				GlobalSavePlugin.Logger.LogError((object)$"Failed to close achievements menu: {arg}");
			}
		}
	}
	public static class AchievementPopupPatches
	{
		private static GameObject _popupContainer = null;

		private const float POPUP_DURATION = 4f;

		private const float SLIDE_DURATION = 0.4f;

		private static readonly Color POPUP_BG_COLOR = new Color(0.05f, 0.05f, 0.08f, 0.95f);

		private static readonly Color GOLD_COLOR = new Color(1f, 0.85f, 0.2f, 1f);

		private static int _currentBadgeIndex = -1;

		private static Queue<string> _popupQueue = new Queue<string>();

		private static bool _isShowingPopup = false;

		private static float _nextPopupDelay = 0f;

		private static int FindBadgeIndex(string achievementKey)
		{
			try
			{
				Type type = AccessTools.TypeByName("NachoAchievements.NachoAchievements");
				if (AccessTools.Field(type, "Achievements")?.GetValue(null) is Dictionary<string, Dictionary<string, string>> dictionary)
				{
					int num = 1;
					foreach (string key in dictionary.Keys)
					{
						if (key == achievementKey)
						{
							GlobalSavePlugin.Logger.LogInfo((object)$"Found badge index {num} for achievement key: {achievementKey}");
							return num;
						}
						num++;
					}
				}
				GlobalSavePlugin.Logger.LogWarning((object)("Badge not found for achievement key: " + achievementKey));
			}
			catch (Exception ex)
			{
				GlobalSavePlugin.Logger.LogError((object)("FindBadgeIndex error: " + ex.Message));
			}
			return -1;
		}

		private static string GetAchievementName(string achievementKey)
		{
			try
			{
				Type type = AccessTools.TypeByName("NachoAchievements.NachoAchievements");
				if (AccessTools.Field(type, "Achievements")?.GetValue(null) is Dictionary<string, Dictionary<string, string>> dictionary && dictionary.ContainsKey(achievementKey))
				{
					Dictionary<string, string> dictionary2 = dictionary[achievementKey];
					if (dictionary2.ContainsKey("name"))
					{
						return dictionary2["name"];
					}
				}
			}
			catch
			{
			}
			return achievementKey;
		}

		public static bool CreateEnhancedAchievementPopup(string text)
		{
			try
			{
				if (_isShowingPopup && (Object)(object)_popupContainer != (Object)null)
				{
					_popupQueue.Enqueue(text);
					GlobalSavePlugin.Logger.LogInfo((object)$"Achievement queued: {text} (Queue size: {_popupQueue.Count})");
					SetOriginalFields();
					return false;
				}
				ShowPopup(text);
				return false;
			}
			catch (Exception arg)
			{
				GlobalSavePlugin.Logger.LogError((object)$"Enhanced popup failed: {arg}");
				return true;
			}
		}

		private static void ShowPopup(string achievementKey)
		{
			try
			{
				CleanupPopup();
				_isShowingPopup = true;
				_currentBadgeIndex = FindBadgeIndex(achievementKey);
				string achievementName = GetAchievementName(achievementKey);
				Type type = AccessTools.TypeByName("NachoAchievements.NachoAchievements");
				FieldInfo fieldInfo = AccessTools.Field(type, "AchievementsCanvas");
				object? obj = fieldInfo?.GetValue(null);
				Canvas val = (Canvas)((obj is Canvas) ? obj : null);
				if ((Object)(object)val == (Object)null)
				{
					AccessTools.Method(type, "CreateAchievementsCanvas", (Type[])null, (Type[])null)?.Invoke(null, null);
					object? obj2 = fieldInfo?.GetValue(null);
					val = (Canvas)((obj2 is Canvas) ? obj2 : null);
				}
				if ((Object)(object)val == (Object)null)
				{
					_isShowingPopup = false;
					return;
				}
				CreatePopupUI(val, achievementName);
				PlayAchievementSound();
				AccessTools.Field(type, "destroyTimer")?.SetValue(null, 0f);
				SetOriginalFields();
				StartPopupAnimation();
				GlobalSavePlugin.Logger.LogInfo((object)("Showing popup for: " + achievementKey + " (" + achievementName + ")"));
			}
			catch (Exception arg)
			{
				GlobalSavePlugin.Logger.LogError((object)$"ShowPopup failed: {arg}");
				_isShowingPopup = false;
			}
		}

		private static void SetOriginalFields()
		{
			try
			{
				Type type = AccessTools.TypeByName("NachoAchievements.NachoAchievements");
				FieldInfo fieldInfo = AccessTools.Field(type, "achievementGetText");
				FieldInfo fieldInfo2 = AccessTools.Field(type, "achievementGetTextSubtitle");
				if ((Object)(object)_popupContainer != (Object)null)
				{
					fieldInfo?.SetValue(null, _popupContainer);
					fieldInfo2?.SetValue(null, _popupContainer);
				}
			}
			catch
			{
			}
		}

		public static void OnPopupComplete()
		{
			_isShowingPopup = false;
			_popupContainer = null;
			if (_popupQueue.Count > 0)
			{
				string text = _popupQueue.Dequeue();
				GlobalSavePlugin.Logger.LogInfo((object)$"Showing next queued popup: {text} (Remaining: {_popupQueue.Count})");
				ShowPopup(text);
			}
		}

		private static void CreatePopupUI(Canvas canvas, string achievementName)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: 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_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Expected O, but got Unknown
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Expected O, but got Unknown
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Expected O, but got Unknown
			//IL_0213: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_024a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0261: 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_0285: Unknown result type (might be due to invalid IL or missing references)
			//IL_0295: Unknown result type (might be due to invalid IL or missing references)
			//IL_029c: Expected O, but got Unknown
			//IL_0307: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0328: Unknown result type (might be due to invalid IL or missing references)
			//IL_033f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0356: Unknown result type (might be due to invalid IL or missing references)
			//IL_036d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0384: Unknown result type (might be due to invalid IL or missing references)
			//IL_039d: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a4: Expected O, but got Unknown
			//IL_03f7: 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_042e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0445: Unknown result type (might be due to invalid IL or missing references)
			//IL_045c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0473: Unknown result type (might be due to invalid IL or missing references)
			//IL_0483: Unknown result type (might be due to invalid IL or missing references)
			//IL_048a: Expected O, but got Unknown
			//IL_04d9: 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_0510: Unknown result type (might be due to invalid IL or missing references)
			//IL_0527: Unknown result type (might be due to invalid IL or missing references)
			//IL_053e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0555: Unknown result type (might be due to invalid IL or missing references)
			//IL_0565: Unknown result type (might be due to invalid IL or missing references)
			//IL_056c: Expected O, but got Unknown
			//IL_05a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_05da: Unknown result type (might be due to invalid IL or missing references)
			//IL_05f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0608: Unknown result type (might be due to invalid IL or missing references)
			//IL_061f: Unknown result type (might be due to invalid IL or missing references)
			//IL_062f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0636: Expected O, but got Unknown
			//IL_0656: Unknown result type (might be due to invalid IL or missing references)
			//IL_0676: Unknown result type (might be due to invalid IL or missing references)
			//IL_068d: Unknown result type (might be due to invalid IL or missing references)
			//IL_06a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_06b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_06be: Unknown result type (might be due to invalid IL or missing references)
			_popupContainer = new GameObject("EnhancedAchievementPopup");
			_popupContainer.transform.SetParent(((Component)canvas).transform, false);
			RectTransform val = _popupContainer.AddComponent<RectTransform>();
			val.anchorMin = new Vector2(0.5f, 1f);
			val.anchorMax = new Vector2(0.5f, 1f);
			val.pivot = new Vector2(0.5f, 1f);
			val.anchoredPosition = new Vector2(0f, 200f);
			val.sizeDelta = new Vector2(700f, 140f);
			GameObject val2 = new GameObject("Background");
			val2.transform.SetParent(_popupContainer.transform, false);
			Image val3 = val2.AddComponent<Image>();
			((Graphic)val3).color = POPUP_BG_COLOR;
			RectTransform component = val2.GetComponent<RectTransform>();
			component.anchorMin = Vector2.zero;
			component.anchorMax = Vector2.one;
			component.sizeDelta = Vector2.zero;
			component.anchoredPosition = Vector2.zero;
			Outline val4 = val2.AddComponent<Outline>();
			((Shadow)val4).effectColor = GOLD_COLOR;
			((Shadow)val4).effectDistance = new Vector2(3f, 3f);
			GameObject val5 = new GameObject("TopLine");
			val5.transform.SetParent(_popupContainer.transform, false);
			Image val6 = val5.AddComponent<Image>();
			((Graphic)val6).color = GOLD_COLOR;
			RectTransform component2 = val5.GetComponent<RectTransform>();
			component2.anchorMin = new Vector2(0f, 1f);
			component2.anchorMax = new Vector2(1f, 1f);
			component2.pivot = new Vector2(0.5f, 1f);
			component2.sizeDelta = new Vector2(0f, 4f);
			component2.anchoredPosition = Vector2.zero;
			GameObject val7 = new GameObject("BottomLine");
			val7.transform.SetParent(_popupContainer.transform, false);
			Image val8 = val7.AddComponent<Image>();
			((Graphic)val8).color = GOLD_COLOR;
			RectTransform component3 = val7.GetComponent<RectTransform>();
			component3.anchorMin = new Vector2(0f, 0f);
			component3.anchorMax = new Vector2(1f, 0f);
			component3.pivot = new Vector2(0.5f, 0f);
			component3.sizeDelta = new Vector2(0f, 4f);
			component3.anchoredPosition = Vector2.zero;
			GameObject val9 = new GameObject("TrophyIcon");
			val9.transform.SetParent(_popupContainer.transform, false);
			Image val10 = val9.AddComponent<Image>();
			if (_currentBadgeIndex > 0 && MenuPatches.HasBadgeSprite(_currentBadgeIndex))
			{
				val10.sprite = MenuPatches.GetBadgeSprite(_currentBadgeIndex);
				val10.preserveAspect = true;
				((Graphic)val10).color = Color.white;
			}
			else
			{
				((Graphic)val10).color = GOLD_COLOR;
			}
			RectTransform component4 = val9.GetComponent<RectTransform>();
			component4.anchorMin = new Vector2(0f, 0.5f);
			component4.anchorMax = new Vector2(0f, 0.5f);
			component4.pivot = new Vector2(0f, 0.5f);
			component4.anchoredPosition = new Vector2(25f, 0f);
			component4.sizeDelta = new Vector2(90f, 90f);
			BadgeBounceAnimator badgeBounceAnimator = val9.AddComponent<BadgeBounceAnimator>();
			GameObject val11 = new GameObject("Title");
			val11.transform.SetParent(_popupContainer.transform, false);
			TextMeshProUGUI val12 = val11.AddComponent<TextMeshProUGUI>();
			((TMP_Text)val12).text = "★ 도전과제 달성! ★";
			((TMP_Text)val12).fontSize = 28f;
			((TMP_Text)val12).fontStyle = (FontStyles)1;
			((TMP_Text)val12).alignment = (TextAlignmentOptions)513;
			((Graphic)val12).color = GOLD_COLOR;
			RectTransform component5 = val11.GetComponent<RectTransform>();
			component5.anchorMin = new Vector2(0f, 0.5f);
			component5.anchorMax = new Vector2(1f, 1f);
			component5.pivot = new Vector2(0f, 0.5f);
			component5.anchoredPosition = new Vector2(120f, -15f);
			component5.sizeDelta = new Vector2(-140f, 50f);
			GameObject val13 = new GameObject("AchievementName");
			val13.transform.SetParent(_popupContainer.transform, false);
			TextMeshProUGUI val14 = val13.AddComponent<TextMeshProUGUI>();
			((TMP_Text)val14).text = achievementName;
			((TMP_Text)val14).fontSize = 24f;
			((TMP_Text)val14).fontStyle = (FontStyles)0;
			((TMP_Text)val14).alignment = (TextAlignmentOptions)513;
			((Graphic)val14).color = Color.white;
			RectTransform component6 = val13.GetComponent<RectTransform>();
			component6.anchorMin = new Vector2(0f, 0f);
			component6.anchorMax = new Vector2(1f, 0.5f);
			component6.pivot = new Vector2(0f, 0.5f);
			component6.anchoredPosition = new Vector2(120f, 15f);
			component6.sizeDelta = new Vector2(-140f, 50f);
			GameObject val15 = new GameObject("ProgressBg");
			val15.transform.SetParent(_popupContainer.transform, false);
			Image val16 = val15.AddComponent<Image>();
			((Graphic)val16).color = new Color(0.2f, 0.2f, 0.2f, 1f);
			RectTransform component7 = val15.GetComponent<RectTransform>();
			component7.anchorMin = new Vector2(0f, 0f);
			component7.anchorMax = new Vector2(1f, 0f);
			component7.pivot = new Vector2(0f, 0f);
			component7.anchoredPosition = new Vector2(0f, 4f);
			component7.sizeDelta = new Vector2(0f, 3f);
			GameObject val17 = new GameObject("ProgressFill");
			val17.transform.SetParent(val15.transform, false);
			Image val18 = val17.AddComponent<Image>();
			((Graphic)val18).color = GOLD_COLOR;
			RectTransform component8 = val17.GetComponent<RectTransform>();
			component8.anchorMin = new Vector2(0f, 0f);
			component8.anchorMax = new Vector2(1f, 1f);
			component8.pivot = new Vector2(0f, 0.5f);
			component8.anchoredPosition = Vector2.zero;
			component8.sizeDelta = Vector2.zero;
			PopupProgressAnimator popupProgressAnimator = val17.AddComponent<PopupProgressAnimator>();
			popupProgressAnimator.duration = 4f;
		}

		private static void PlayAchievementSound()
		{
			try
			{
				Type type = AccessTools.TypeByName("HUDManager");
				object obj = AccessTools.Property(type, "Instance")?.GetValue(null);
				if (obj != null)
				{
					FieldInfo fieldInfo = AccessTools.Field(type, "UIAudio");
					FieldInfo fieldInfo2 = AccessTools.Field(type, "levelIncreaseSFX");
					object? obj2 = fieldInfo?.GetValue(obj);
					AudioSource val = (AudioSource)((obj2 is AudioSource) ? obj2 : null);
					object? obj3 = fieldInfo2?.GetValue(obj);
					AudioClip val2 = (AudioClip)((obj3 is AudioClip) ? obj3 : null);
					if (val != null)
					{
						val.PlayOneShot(val2);
					}
				}
			}
			catch
			{
			}
		}

		private static void StartPopupAnimation()
		{
			if (!((Object)(object)_popupContainer == (Object)null))
			{
				PopupAnimator popupAnimator = _popupContainer.AddComponent<PopupAnimator>();
				popupAnimator.slideInDuration = 0.4f;
				popupAnimator.displayDuration = 4f;
				popupAnimator.slideOutDuration = 0.4f;
				popupAnimator.targetY = -20f;
				popupAnimator.startY = 200f;
			}
		}

		private static void CleanupPopup()
		{
			if ((Object)(object)_popupContainer != (Object)null)
			{
				Object.Destroy((Object)(object)_popupContainer);
				_popupContainer = null;
			}
		}
	}
	public class PopupAnimator : MonoBehaviour
	{
		private enum AnimState
		{
			SlideIn,
			Display,
			SlideOut,
			Done
		}

		public float slideInDuration = 0.5f;

		public float displayDuration = 5f;

		public float slideOutDuration = 0.5f;

		public float targetY = -20f;

		public float startY = 200f;

		private float _timer = 0f;

		private RectTransform _rect;

		private AnimState _state = AnimState.SlideIn;

		private void Start()
		{
			_rect = ((Component)this).GetComponent<RectTransform>();
		}

		private void Update()
		{
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			_timer += Time.deltaTime;
			switch (_state)
			{
			case AnimState.SlideIn:
			{
				float num5 = Mathf.Clamp01(_timer / slideInDuration);
				float num6 = EaseOutBack(num5);
				float num7 = Mathf.Lerp(startY, targetY, num6);
				_rect.anchoredPosition = new Vector2(0f, num7);
				if (num5 >= 1f)
				{
					_state = AnimState.Display;
					_timer = 0f;
				}
				break;
			}
			case AnimState.Display:
			{
				float num4 = Mathf.Sin(_timer * 2f) * 2f;
				_rect.anchoredPosition = new Vector2(0f, targetY + num4);
				if (_timer >= displayDuration)
				{
					_state = AnimState.SlideOut;
					_timer = 0f;
				}
				break;
			}
			case AnimState.SlideOut:
			{
				float num = Mathf.Clamp01(_timer / slideOutDuration);
				float num2 = EaseInBack(num);
				float num3 = Mathf.Lerp(targetY, startY, num2);
				_rect.anchoredPosition = new Vector2(0f, num3);
				CanvasGroup val = ((Component)this).GetComponent<CanvasGroup>();
				if ((Object)(object)val == (Object)null)
				{
					val = ((Component)this).gameObject.AddComponent<CanvasGroup>();
				}
				val.alpha = 1f - num;
				if (num >= 1f)
				{
					_state = AnimState.Done;
					AchievementPopupPatches.OnPopupComplete();
					Object.Destroy((Object)(object)((Component)this).gameObject);
				}
				break;
			}
			}
		}

		private float EaseOutBack(float t)
		{
			return 1f + 2.70158f * Mathf.Pow(t - 1f, 3f) + 1.70158f * Mathf.Pow(t - 1f, 2f);
		}

		private float EaseInBack(float t)
		{
			return 2.70158f * t * t * t - 1.70158f * t * t;
		}
	}
	public class PopupProgressAnimator : MonoBehaviour
	{
		public float duration = 5f;

		private float _timer = 0f;

		private RectTransform _rect;

		private void Start()
		{
			_rect = ((Component)this).GetComponent<RectTransform>();
		}

		private void Update()
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			_timer += Time.deltaTime;
			float num = Mathf.Clamp01(_timer / duration);
			_rect.anchorMax = new Vector2(1f - num, 1f);
		}
	}
	public class BadgeBounceAnimator : MonoBehaviour
	{
		public float bounceDuration = 0.6f;

		public float bounceScale = 1.3f;

		public float rotationAmount = 15f;

		private float _timer = 0f;

		private RectTransform _rect;

		private Vector3 _originalScale;

		private bool _animationComplete = false;

		private void Start()
		{
			//IL_0014: 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_0024: Unknown result type (might be due to invalid IL or missing references)
			_rect = ((Component)this).GetComponent<RectTransform>();
			_originalScale = ((Transform)_rect).localScale;
			((Transform)_rect).localScale = Vector3.zero;
		}

		private void Update()
		{
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			if (!_animationComplete)
			{
				_timer += Time.deltaTime;
				float num = Mathf.Clamp01(_timer / bounceDuration);
				if (num < 0.5f)
				{
					float num2 = num * 2f;
					float num3 = EaseOutBack(num2) * bounceScale;
					float num4 = Mathf.Sin(num2 * MathF.PI) * rotationAmount;
					((Transform)_rect).localScale = _originalScale * num3;
					((Transform)_rect).localRotation = Quaternion.Euler(0f, 0f, num4);
				}
				else
				{
					float num5 = (num - 0.5f) * 2f;
					float num6 = Mathf.Lerp(bounceScale, 1f, EaseOutBounce(num5));
					float num7 = Mathf.Sin((1f - num5) * MathF.PI * 0.5f) * rotationAmount * 0.3f;
					((Transform)_rect).localScale = _originalScale * num6;
					((Transform)_rect).localRotation = Quaternion.Euler(0f, 0f, num7);
				}
				if (num >= 1f)
				{
					_animationComplete = true;
					((Transform)_rect).localScale = _originalScale;
					((Transform)_rect).localRotation = Quaternion.identity;
				}
			}
		}

		private float EaseOutBack(float t)
		{
			return 1f + 2.70158f * Mathf.Pow(t - 1f, 3f) + 1.70158f * Mathf.Pow(t - 1f, 2f);
		}

		private float EaseOutBounce(float t)
		{
			if (t < 0.36363637f)
			{
				return 7.5625f * t * t;
			}
			if (t < 0.72727275f)
			{
				return 7.5625f * (t -= 0.54545456f) * t + 0.75f;
			}
			if (t < 0.90909094f)
			{
				return 7.5625f * (t -= 0.8181818f) * t + 0.9375f;
			}
			return 7.5625f * (t -= 21f / 22f) * t + 63f / 64f;
		}
	}
	public class RainbowGradientAnimator : MonoBehaviour
	{
		public float speed = 0.15f;

		public float waveLength = 1.5f;

		public float saturation = 0.55f;

		public float brightness = 0.92f;

		private Image _image;

		private float _timeOffset = 0f;

		private List<Image> _segments = new List<Image>();

		private const int SEGMENT_COUNT = 128;

		private bool _initialized = false;

		private static Color[] _colorLUT;

		private const int LUT_SIZE = 256;

		private int _frameCounter = 0;

		private const int UPDATE_INTERVAL = 3;

		static RainbowGradientAnimator()
		{
			_colorLUT = null;
			BuildColorLUT(0.55f, 0.92f);
		}

		private static void BuildColorLUT(float sat, float bright)
		{
			//IL_0027: 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)
			_colorLUT = (Color[])(object)new Color[256];
			for (int i = 0; i < 256; i++)
			{
				float num = (float)i / 256f;
				_colorLUT[i] = Color.HSVToRGB(num, sat, bright);
			}
		}

		private void Start()
		{
			InitializeIfNeeded();
		}

		private void InitializeIfNeeded()
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			if (!_initialized)
			{
				_initialized = true;
				_image = ((Component)this).GetComponent<Image>();
				if ((Object)(object)_image != (Object)null)
				{
					((Graphic)_image).color = new Color(0f, 0f, 0f, 0f);
					CreateSegments();
				}
			}
		}

		private void CreateSegments()
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//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_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			if (_segments.Count <= 0)
			{
				for (int i = 0; i < 128; i++)
				{
					GameObject val = new GameObject($"Seg{i}");
					val.transform.SetParent(((Component)this).transform, false);
					Image item = val.AddComponent<Image>();
					RectTransform component = val.GetComponent<RectTransform>();
					float num = 1f / 128f;
					float num2 = 0.003f;
					component.anchorMin = new Vector2(Mathf.Max(0f, num * (float)i - num2), 0f);
					component.anchorMax = new Vector2(Mathf.Min(1f, num * (float)(i + 1) + num2), 1f);
					component.offsetMin = Vector2.zero;
					component.offsetMax = Vector2.zero;
					_segments.Add(item);
				}
				UpdateColors();
			}
		}

		private void Update()
		{
			if (!_initialized || _segments.Count == 0)
			{
				return;
			}
			_frameCounter++;
			if (_frameCounter >= 3)
			{
				_frameCounter = 0;
				_timeOffset += Time.deltaTime * speed * 3f;
				if (_timeOffset > 1f)
				{
					_timeOffset -= 1f;
				}
				UpdateColors();
			}
		}

		private void UpdateColors()
		{
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < _segments.Count; i++)
			{
				if (!((Object)(object)_segments[i] == (Object)null))
				{
					float num = (float)i / 128f;
					float num2 = (num * waveLength - _timeOffset) % 1f;
					if (num2 < 0f)
					{
						num2 += 1f;
					}
					int num3 = (int)(num2 * 255f);
					((Graphic)_segments[i]).color = _colorLUT[num3];
				}
			}
		}

		private void OnDestroy()
		{
			for (int num = _segments.Count - 1; num >= 0; num--)
			{
				if ((Object)(object)_segments[num] != (Object)null && (Object)(object)((Component)_segments[num]).gameObject != (Object)null)
				{
					Object.DestroyImmediate((Object)(object)((Component)_segments[num]).gameObject);
				}
			}
			_segments.Clear();
			_initialized = false;
		}
	}
	public class ProgressGlowAnimator : MonoBehaviour
	{
		public float pulseSpeed = 2.5f;

		public float minAlpha = 0.3f;

		public float maxAlpha = 0.8f;

		public float glowWidth = 15f;

		private Image _glowImage;

		private RectTransform _glowRect;

		private float _timer = 0f;

		private bool _initialized = false;

		private void Start()
		{
			InitializeIfNeeded();
		}

		private void InitializeIfNeeded()
		{
			if (!_initialized)
			{
				_initialized = true;
				CreateGlow();
			}
		}

		private void CreateGlow()
		{
			//IL_001b: Unknown result type (might