Decompiled source of ValuableList v1.4.0

ValuableList.dll

Decompiled 2 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using MenuLib;
using MenuLib.MonoBehaviors;
using MenuLib.Structs;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
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: IgnoresAccessChecksTo("")]
[assembly: AssemblyCompany("McHorse")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+52c50ee948840a40d8a1efc04054f479eeb051e2")]
[assembly: AssemblyProduct("ValuableList")]
[assembly: AssemblyTitle("ValuableList")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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 ValuableList
{
	internal static class MenuScrollReflection
	{
		internal static readonly FieldInfo ScrollerEndPosition = AccessTools.Field(typeof(MenuScrollBox), "scrollerEndPosition");

		internal static readonly FieldInfo ScrollerStartPosition = AccessTools.Field(typeof(MenuScrollBox), "scrollerStartPosition");

		internal static readonly FieldInfo ScrollHandleTargetPosition = AccessTools.Field(typeof(MenuScrollBox), "scrollHandleTargetPosition");

		internal static readonly FieldInfo ScrollAmount = AccessTools.Field(typeof(MenuScrollBox), "scrollAmount");
	}
	[HarmonyPatch(typeof(RoundDirector))]
	internal static class RoundDirectorPatch
	{
		private const float HudPrimaryFontSize = 16f;

		private const float HudLineStackSpacing = -6f;

		private static readonly float HudStatsFontSize = 24f;

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

		private static GameObject? labelObject;

		private static TextMeshProUGUI? currentRoomLineText;

		private static TextMeshProUGUI? mostExpensiveLineText;

		private static TextMeshProUGUI? statsLineText;

		[HarmonyPostfix]
		[HarmonyPatch("Update")]
		private static void UpdateHudLabel()
		{
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			if (!SemiFunc.RunIsLevel())
			{
				SetLabelActive(active: false);
				return;
			}
			EnsureLabel();
			if ((Object)(object)currentRoomLineText == (Object)null || (Object)(object)statsLineText == (Object)null)
			{
				return;
			}
			if (!ValuableList.Instance.ShowMostExpensiveHudLabelEnabled)
			{
				SetLabelActive(active: false);
				return;
			}
			string currentPlayerRoomName = ValuableUtils.GetCurrentPlayerRoomName();
			((TMP_Text)currentRoomLineText).text = (string.IsNullOrWhiteSpace(currentPlayerRoomName) ? "Unknown" : currentPlayerRoomName);
			((Graphic)currentRoomLineText).color = HudCurrentRoomColor;
			(ValuableEntry? Entry, int Count, float DistanceToBestMeters) mostExpensiveInCurrentRoom = ValuableUtils.GetMostExpensiveInCurrentRoom();
			ValuableEntry? item = mostExpensiveInCurrentRoom.Entry;
			int item2 = mostExpensiveInCurrentRoom.Count;
			float item3 = mostExpensiveInCurrentRoom.DistanceToBestMeters;
			(int CollectedCount, int TotalCount, int CollectedValue, int TotalValue) levelCollectionStats = ValuableUtils.GetLevelCollectionStats();
			int item4 = levelCollectionStats.CollectedCount;
			int item5 = levelCollectionStats.TotalCount;
			int item6 = levelCollectionStats.CollectedValue;
			int item7 = levelCollectionStats.TotalValue;
			(int InRoomCount, int TotalCount, Rarity? RoomDominantRarity) cosmeticBoxStats = ValuableUtils.GetCosmeticBoxStats();
			int item8 = cosmeticBoxStats.InRoomCount;
			int item9 = cosmeticBoxStats.TotalCount;
			Rarity? item10 = cosmeticBoxStats.RoomDominantRarity;
			string text = $"{item4}/{item5} - {ValuableUtils.FormatPrice(item6)}/{ValuableUtils.FormatPrice(item7)}";
			((TMP_Text)statsLineText).text = ((item9 > 0) ? (text + " - " + FormatCosmeticBoxesRichText(item8, item9, item10)) : text);
			((Graphic)statsLineText).color = ((item5 > 0 && item4 == item5) ? ValuablesMenu.HighlightValueLabelColor : Color.white);
			if ((Object)(object)mostExpensiveLineText != (Object)null)
			{
				if (item.HasValue)
				{
					((Component)mostExpensiveLineText).gameObject.SetActive(true);
					if (ValuableList.Instance.ShowDistanceInMenuEnabled)
					{
						string text2 = ValuableUtils.FormatDistanceMetersOneDecimal(item3);
						((TMP_Text)mostExpensiveLineText).text = $"{item.Value.Name} - {ValuableUtils.FormatPrice(item.Value.Price)}/{text2}m ({item2})";
					}
					else
					{
						((TMP_Text)mostExpensiveLineText).text = $"{item.Value.Name} - {ValuableUtils.FormatPrice(item.Value.Price)} ({item2})";
					}
				}
				else
				{
					((Component)mostExpensiveLineText).gameObject.SetActive(false);
				}
			}
			SetLabelActive(active: true);
		}

		private static void EnsureLabel()
		{
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Expected O, but got Unknown
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Expected O, but got Unknown
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Expected O, but got Unknown
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Expected O, but got Unknown
			//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0203: Expected O, but got Unknown
			//IL_025c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0273: Unknown result type (might be due to invalid IL or missing references)
			//IL_028a: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a1: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)labelObject != (Object)null && ((Object)(object)currentRoomLineText == (Object)null || (Object)(object)mostExpensiveLineText == (Object)null || (Object)(object)statsLineText == (Object)null))
			{
				Object.Destroy((Object)(object)labelObject);
				labelObject = null;
				currentRoomLineText = null;
				mostExpensiveLineText = null;
				statsLineText = null;
			}
			if ((Object)(object)labelObject != (Object)null)
			{
				return;
			}
			GameObject val = GameObject.Find("Game Hud");
			if (!((Object)(object)val == (Object)null))
			{
				labelObject = new GameObject("VL-ValuableList Most Expensive Valuable");
				labelObject.transform.SetParent(val.transform, false);
				VerticalLayoutGroup val2 = labelObject.AddComponent<VerticalLayoutGroup>();
				((LayoutGroup)val2).childAlignment = (TextAnchor)1;
				((HorizontalOrVerticalLayoutGroup)val2).spacing = -6f;
				((HorizontalOrVerticalLayoutGroup)val2).childControlWidth = true;
				((HorizontalOrVerticalLayoutGroup)val2).childControlHeight = true;
				((HorizontalOrVerticalLayoutGroup)val2).childForceExpandWidth = false;
				((HorizontalOrVerticalLayoutGroup)val2).childForceExpandHeight = false;
				((LayoutGroup)val2).padding = new RectOffset(0, 0, 0, 0);
				ContentSizeFitter val3 = labelObject.AddComponent<ContentSizeFitter>();
				val3.horizontalFit = (FitMode)2;
				val3.verticalFit = (FitMode)2;
				TMP_FontAsset font = null;
				GameObject val4 = GameObject.Find("Tax Haul");
				TMP_Text val5 = (((Object)(object)val4 != (Object)null) ? val4.GetComponent<TMP_Text>() : null);
				if ((Object)(object)val5 != (Object)null)
				{
					font = val5.font;
				}
				GameObject val6 = new GameObject("VL-Current room line");
				val6.transform.SetParent(labelObject.transform, false);
				currentRoomLineText = val6.AddComponent<TextMeshProUGUI>();
				ConfigureHudLine(currentRoomLineText, 16f, font);
				((Graphic)currentRoomLineText).color = HudCurrentRoomColor;
				GameObject val7 = new GameObject("VL-Most expensive line");
				val7.transform.SetParent(labelObject.transform, false);
				mostExpensiveLineText = val7.AddComponent<TextMeshProUGUI>();
				ConfigureHudLine(mostExpensiveLineText, 16f, font);
				GameObject val8 = new GameObject("VL-Stats line");
				val8.transform.SetParent(labelObject.transform, false);
				statsLineText = val8.AddComponent<TextMeshProUGUI>();
				ConfigureHudLine(statsLineText, HudStatsFontSize, font);
				((TMP_Text)statsLineText).richText = true;
				RectTransform component = labelObject.GetComponent<RectTransform>();
				component.anchorMin = new Vector2(0.5f, 1f);
				component.anchorMax = new Vector2(0.5f, 1f);
				component.pivot = new Vector2(0.5f, 1f);
				component.anchoredPosition = new Vector2(0f, 10f);
			}
		}

		private static void ConfigureHudLine(TextMeshProUGUI tmp, float fontSize, TMP_FontAsset? font)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			((TMP_Text)tmp).fontSize = fontSize;
			((Graphic)tmp).color = Color.white;
			((TMP_Text)tmp).richText = false;
			((TMP_Text)tmp).enableWordWrapping = false;
			((TMP_Text)tmp).alignment = (TextAlignmentOptions)514;
			((TMP_Text)tmp).lineSpacing = 0f;
			((TMP_Text)tmp).paragraphSpacing = 0f;
			((TMP_Text)tmp).margin = Vector4.zero;
			if ((Object)(object)font != (Object)null)
			{
				((TMP_Text)tmp).font = font;
			}
			ContentSizeFitter val = ((Component)tmp).gameObject.AddComponent<ContentSizeFitter>();
			val.horizontalFit = (FitMode)2;
			val.verticalFit = (FitMode)2;
		}

		private static string FormatCosmeticBoxesRichText(int inRoom, int total, Rarity? roomRarity)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			if (!roomRarity.HasValue)
			{
				return $"{inRoom}/{total}";
			}
			string arg = ValuableUtils.ToHtmlHex(ValuableUtils.GetCosmeticBoxRarityColor(roomRarity.Value));
			return $"<color={arg}>{inRoom}</color>/{total}";
		}

		private static void SetLabelActive(bool active)
		{
			if ((Object)(object)labelObject != (Object)null && labelObject.activeSelf != active)
			{
				labelObject.SetActive(active);
			}
		}
	}
	[HarmonyPatch(typeof(SemiFunc), "UIGetRectTransformPositionOnScreen")]
	internal static class SemiFuncPatch
	{
		private static readonly FieldInfo? MenuPageRectTransformField = AccessTools.Field(typeof(MenuPage), "rectTransform");

		private static readonly Vector2 OffScreen = new Vector2(float.NegativeInfinity, float.NegativeInfinity);

		[HarmonyPrefix]
		private static bool GuardAgainstMissingMenuPageRectTransform(RectTransform rectTransform, ref Vector2 __result)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: 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)
			if ((Object)(object)rectTransform == (Object)null)
			{
				__result = OffScreen;
				return false;
			}
			MenuPage componentInParent = ((Component)rectTransform).GetComponentInParent<MenuPage>();
			if ((Object)(object)componentInParent == (Object)null)
			{
				__result = OffScreen;
				return false;
			}
			object? obj = MenuPageRectTransformField?.GetValue(componentInParent);
			RectTransform val = (RectTransform)((obj is RectTransform) ? obj : null);
			if (val != null && (Object)(object)val != (Object)null)
			{
				return true;
			}
			__result = OffScreen;
			return false;
		}
	}
	[BepInPlugin("McHorse.ValuableList", "ValuableList", "1.4")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class ValuableList : BaseUnityPlugin
	{
		private ValuablesMenu? valuablesMenu;

		private ConfigEntry<KeyCode>? openMenuKeybind;

		private ConfigEntry<bool>? roundPrices;

		private ConfigEntry<bool>? showMostExpensiveValuable;

		private ConfigEntry<bool>? showDistanceInMenu;

		internal static ValuableList Instance { get; private set; }

		internal static ManualLogSource Logger => Instance._logger;

		private ManualLogSource _logger => ((BaseUnityPlugin)this).Logger;

		internal Harmony? Harmony { get; set; }

		internal bool RoundPricesEnabled => roundPrices?.Value ?? true;

		internal bool ShowMostExpensiveHudLabelEnabled => showMostExpensiveValuable?.Value ?? true;

		internal bool ShowDistanceInMenuEnabled => showDistanceInMenu?.Value ?? false;

		private void Awake()
		{
			Instance = this;
			((Component)this).gameObject.transform.parent = null;
			((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
			openMenuKeybind = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Controls", "Open Menu", (KeyCode)110, "Keyboard key used to open the valuables menu.");
			roundPrices = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "RoundPrices", true, "Round list prices to thousands with one decimal place (e.g. 15.4k).");
			showMostExpensiveValuable = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowMostExpensiveValuable", false, "Show a HUD label with the most expensive valuable in your current room.");
			showDistanceInMenu = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowDistanceInMenu", false, "When enabled, the valuables menu and HUD most-expensive line show distance from your player in meters.");
			Patch();
			valuablesMenu = new ValuablesMenu(Logger);
			Logger.LogInfo((object)$"{((BaseUnityPlugin)this).Info.Metadata.GUID} v{((BaseUnityPlugin)this).Info.Metadata.Version} has loaded!");
		}

		internal void Patch()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			//IL_0026: Expected O, but got Unknown
			if (Harmony == null)
			{
				Harmony val = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID);
				Harmony val2 = val;
				Harmony = val;
			}
			Harmony.PatchAll();
		}

		internal void Unpatch()
		{
			Harmony? harmony = Harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}

		private void Update()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			if (SemiFunc.RunIsLevel() && SemiFunc.NoTextInputsActive() && openMenuKeybind != null && Input.GetKeyDown(openMenuKeybind.Value))
			{
				valuablesMenu?.Toggle();
			}
		}
	}
	[HarmonyPatch(typeof(ValuableObject))]
	internal static class ValuableObjectPatch
	{
		internal static readonly List<ValuableObject> Tracked = new List<ValuableObject>();

		[HarmonyPostfix]
		[HarmonyPatch("Start")]
		private static void TrackInstance(ValuableObject __instance)
		{
			Tracked.Add(__instance);
		}
	}
	internal sealed class ValuablesMenu
	{
		private readonly struct ValuableRowVisual
		{
			internal REPOLabel Label { get; }

			internal string NameLower { get; }

			internal bool IsInCartOrExtraction { get; }

			internal int Price { get; }

			internal ValuableRowVisual(REPOLabel label, string name, bool isInCartOrExtraction, int price)
			{
				Label = label;
				NameLower = name.ToLowerInvariant();
				IsInCartOrExtraction = isInCartOrExtraction;
				Price = price;
			}
		}

		private sealed class RoomGroupVisual
		{
			internal string RoomName { get; }

			internal REPOLabel Header { get; }

			internal List<ValuableRowVisual> Rows { get; }

			internal REPOSpacer? Spacer { get; }

			internal float CachedTargetScrollerY { get; set; }

			internal RoomGroupVisual(string roomName, REPOLabel header, List<ValuableRowVisual> rows, REPOSpacer? spacer, float cachedTargetScrollerY)
			{
				RoomName = roomName;
				Header = header;
				Rows = rows;
				Spacer = spacer;
				CachedTargetScrollerY = cachedTargetScrollerY;
			}
		}

		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static ScrollViewBuilderDelegate <>9__17_1;

			public static Func<ValuableEntry, int> <>9__17_2;

			public static Func<IGrouping<string, ValuableEntry>, int> <>9__31_0;

			public static Func<ValuableEntry, bool> <>9__31_3;

			public static Func<IGrouping<string, ValuableEntry>, int> <>9__31_1;

			public static Func<ValuableEntry, bool> <>9__31_4;

			public static Func<ValuableEntry, int> <>9__31_5;

			public static Func<IGrouping<string, ValuableEntry>, int> <>9__31_2;

			public static Func<IGrouping<string, ValuableEntry>, int> <>9__32_0;

			public static Func<ValuableEntry, bool> <>9__32_2;

			public static Func<IGrouping<string, ValuableEntry>, int> <>9__32_1;

			internal RectTransform <AddGroupedValuables>b__17_1(Transform parent)
			{
				//IL_0009: Unknown result type (might be due to invalid IL or missing references)
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				//IL_003a: Unknown result type (might be due to invalid IL or missing references)
				REPOLabel val = MenuAPI.CreateREPOLabel("No valuables found.", parent, default(Vector2));
				((TMP_Text)val.labelTMP).fontStyle = (FontStyles)0;
				((TMP_Text)val.labelTMP).fontSize = 16f;
				((Graphic)val.labelTMP).color = ValueLabelColor;
				return ((REPOElement)val).rectTransform;
			}

			internal int <AddGroupedValuables>b__17_2(ValuableEntry entry)
			{
				return entry.Price;
			}

			internal int <BuildSummaryText>b__31_0(IGrouping<string, ValuableEntry> group)
			{
				return group.Count();
			}

			internal int <BuildSummaryText>b__31_1(IGrouping<string, ValuableEntry> group)
			{
				return group.Count((ValuableEntry entry) => entry.IsInCartOrExtraction);
			}

			internal bool <BuildSummaryText>b__31_3(ValuableEntry entry)
			{
				return entry.IsInCartOrExtraction;
			}

			internal int <BuildSummaryText>b__31_2(IGrouping<string, ValuableEntry> group)
			{
				return group.Where((ValuableEntry entry) => !entry.IsInCartOrExtraction).Sum((ValuableEntry entry) => entry.Price);
			}

			internal bool <BuildSummaryText>b__31_4(ValuableEntry entry)
			{
				return !entry.IsInCartOrExtraction;
			}

			internal int <BuildSummaryText>b__31_5(ValuableEntry entry)
			{
				return entry.Price;
			}

			internal int <SummaryColorForGrouped>b__32_0(IGrouping<string, ValuableEntry> group)
			{
				return group.Count();
			}

			internal int <SummaryColorForGrouped>b__32_1(IGrouping<string, ValuableEntry> group)
			{
				return group.Count((ValuableEntry entry) => entry.IsInCartOrExtraction);
			}

			internal bool <SummaryColorForGrouped>b__32_2(ValuableEntry entry)
			{
				return entry.IsInCartOrExtraction;
			}
		}

		[CompilerGenerated]
		private sealed class <ScrollToCurrentPlayerRoomAfterOpen>d__23 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public REPOPopupPage page;

			public ValuablesMenu <>4__this;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <ScrollToCurrentPlayerRoomAfterOpen>d__23(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = null;
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					<>2__current = null;
					<>1__state = 2;
					return true;
				case 2:
					<>1__state = -1;
					if (!<>4__this.isOpen || (Object)(object)<>4__this.currentPage != (Object)(object)page)
					{
						return false;
					}
					<>4__this.ApplySearchFilter(page, string.Empty);
					<>4__this.ScrollToCurrentPlayerRoom(page);
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		private static readonly Color ModuleHeaderColor = new Color(4f / 15f, 8f / 15f, 1f, 1f);

		private static readonly Color ValueLabelColor = Color.white;

		internal static readonly Color HighlightValueLabelColor = new Color(0f, 1f, 4f / 15f, 1f);

		private static readonly Color ActiveRoomHeaderColor = Color.Lerp(ModuleHeaderColor, HighlightValueLabelColor, 0.75f);

		private readonly ManualLogSource logger;

		private REPOPopupPage? currentPage;

		private bool isOpen;

		private readonly List<RoomGroupVisual> roomGroupVisuals = new List<RoomGroupVisual>();

		private REPOLabel? noResultsLabel;

		private REPOButton? toggleCollectedButton;

		private REPOLabel? summaryLabel;

		private bool hideCollectedValuables;

		private string currentSearchQuery = string.Empty;

		internal ValuablesMenu(ManualLogSource logger)
		{
			this.logger = logger;
		}

		internal void Toggle()
		{
			if (isOpen)
			{
				CloseCurrentPage();
			}
			else if (!SemiFunc.MenuLevel() && !IsAnotherMenuOpen())
			{
				Open();
			}
		}

		private void Open()
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Expected O, but got Unknown
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Expected O, but got Unknown
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: 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)
			try
			{
				CloseCurrentPage();
				REPOPopupPage val = MenuAPI.CreateREPOPopupPage("Valuables", (PresetSide)0, false, true, 0f);
				val.scrollView.scrollSpeed = 3f;
				val.onEscapePressed = (ShouldCloseMenuDelegate)Delegate.Combine((Delegate?)(object)val.onEscapePressed, (Delegate?)new ShouldCloseMenuDelegate(HandleEscapePressed));
				Padding maskPadding = val.maskPadding;
				maskPadding.top = 35f;
				val.maskPadding = maskPadding;
				currentSearchQuery = string.Empty;
				List<IGrouping<string, ValuableEntry>> groupedValuables = ValuableUtils.GetGroupedValuables();
				AddSearchBox(val);
				AddGroupedValuables(val, groupedValuables);
				AddCollectedButton(val);
				summaryLabel = AddCollectedSummaryLabel(val, groupedValuables);
				currentPage = val;
				isOpen = true;
				val.OpenPage(false);
				((MonoBehaviour)ValuableList.Instance).StartCoroutine(ScrollToCurrentPlayerRoomAfterOpen(val));
			}
			catch (Exception arg)
			{
				logger.LogError((object)$"Failed to open valuables menu: {arg}");
				isOpen = false;
				currentPage = null;
				summaryLabel = null;
			}
		}

		private bool HandleEscapePressed()
		{
			isOpen = false;
			currentPage = null;
			return true;
		}

		private void AddGroupedValuables(REPOPopupPage page, List<IGrouping<string, ValuableEntry>> grouped)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected O, but got Unknown
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Expected O, but got Unknown
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Expected O, but got Unknown
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Expected O, but got Unknown
			//IL_0229: Unknown result type (might be due to invalid IL or missing references)
			//IL_023d: Expected O, but got Unknown
			roomGroupVisuals.Clear();
			noResultsLabel = null;
			page.AddElementToScrollView((ScrollViewBuilderDelegate)delegate(Transform parent)
			{
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0015: Unknown result type (might be due to invalid IL or missing references)
				//IL_0062: Unknown result type (might be due to invalid IL or missing references)
				noResultsLabel = MenuAPI.CreateREPOLabel("No matching valuables found.", parent, default(Vector2));
				((TMP_Text)noResultsLabel.labelTMP).fontStyle = (FontStyles)0;
				((TMP_Text)noResultsLabel.labelTMP).fontSize = 16f;
				((Graphic)noResultsLabel.labelTMP).color = ValueLabelColor;
				SetLabelVisibility(noResultsLabel, visible: false);
				return ((REPOElement)noResultsLabel).rectTransform;
			}, 0f, 0f);
			string currentRoom = ValuableUtils.GetCurrentPlayerRoomName();
			if (grouped.Count == 0)
			{
				object obj = <>c.<>9__17_1;
				if (obj == null)
				{
					ScrollViewBuilderDelegate val = delegate(Transform parent)
					{
						//IL_0009: Unknown result type (might be due to invalid IL or missing references)
						//IL_000f: Unknown result type (might be due to invalid IL or missing references)
						//IL_003a: Unknown result type (might be due to invalid IL or missing references)
						REPOLabel val3 = MenuAPI.CreateREPOLabel("No valuables found.", parent, default(Vector2));
						((TMP_Text)val3.labelTMP).fontStyle = (FontStyles)0;
						((TMP_Text)val3.labelTMP).fontSize = 16f;
						((Graphic)val3.labelTMP).color = ValueLabelColor;
						return ((REPOElement)val3).rectTransform;
					};
					<>c.<>9__17_1 = val;
					obj = (object)val;
				}
				page.AddElementToScrollView((ScrollViewBuilderDelegate)obj, 0f, 0f);
				return;
			}
			for (int i = 0; i < grouped.Count; i++)
			{
				IGrouping<string, ValuableEntry> roomGroup = grouped[i];
				int rawPrice = roomGroup.Sum((ValuableEntry entry) => entry.Price);
				string roomHeaderText = ValuableUtils.TruncateRoomNameForMenuDisplay(roomGroup.Key) + " (" + ValuableUtils.FormatPrice(rawPrice) + ")";
				REPOLabel groupHeader = null;
				page.AddElementToScrollView((ScrollViewBuilderDelegate)delegate(Transform parent)
				{
					//IL_000b: Unknown result type (might be due to invalid IL or missing references)
					//IL_0011: Unknown result type (might be due to invalid IL or missing references)
					//IL_008b: Unknown result type (might be due to invalid IL or missing references)
					//IL_0084: Unknown result type (might be due to invalid IL or missing references)
					groupHeader = MenuAPI.CreateREPOLabel(roomHeaderText, parent, default(Vector2));
					((TMP_Text)groupHeader.labelTMP).fontStyle = (FontStyles)1;
					((TMP_Text)groupHeader.labelTMP).fontSize = 24f;
					bool flag = !string.IsNullOrWhiteSpace(currentRoom) && string.Equals(roomGroup.Key, currentRoom, StringComparison.OrdinalIgnoreCase);
					((Graphic)groupHeader.labelTMP).color = (flag ? ActiveRoomHeaderColor : ModuleHeaderColor);
					return ((REPOElement)groupHeader).rectTransform;
				}, 0f, 0f);
				List<ValuableRowVisual> list = new List<ValuableRowVisual>();
				foreach (ValuableEntry entry2 in roomGroup)
				{
					REPOLabel lineLabelRef = null;
					page.AddElementToScrollView((ScrollViewBuilderDelegate)delegate(Transform parent)
					{
						//IL_0014: Unknown result type (might be due to invalid IL or missing references)
						//IL_001a: Unknown result type (might be due to invalid IL or missing references)
						//IL_0057: Unknown result type (might be due to invalid IL or missing references)
						//IL_0068: Unknown result type (might be due to invalid IL or missing references)
						//IL_006d: 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)
						//IL_007a: Unknown result type (might be due to invalid IL or missing references)
						//IL_0086: Unknown result type (might be due to invalid IL or missing references)
						REPOLabel val2 = (lineLabelRef = MenuAPI.CreateREPOLabel(FormatValuableLine(entry2), parent, default(Vector2)));
						((TMP_Text)val2.labelTMP).fontStyle = (FontStyles)0;
						((TMP_Text)val2.labelTMP).fontSize = 16f;
						((Graphic)val2.labelTMP).color = ResolveRowColor(entry2);
						Vector2 sizeDelta = ((REPOElement)val2).rectTransform.sizeDelta;
						((REPOElement)val2).rectTransform.sizeDelta = new Vector2(sizeDelta.x, sizeDelta.y * 0.625f);
						return ((REPOElement)val2).rectTransform;
					}, 0f, 0f);
					if ((Object)(object)lineLabelRef != (Object)null)
					{
						list.Add(new ValuableRowVisual(lineLabelRef, entry2.Name, entry2.IsInCartOrExtraction, entry2.Price));
					}
				}
				REPOSpacer spacer = null;
				if (i < grouped.Count - 1)
				{
					page.AddElementToScrollView((ScrollViewBuilderDelegate)delegate(Transform parent)
					{
						//IL_0005: Unknown result type (might be due to invalid IL or missing references)
						//IL_000b: Unknown result type (might be due to invalid IL or missing references)
						//IL_0016: Unknown result type (might be due to invalid IL or missing references)
						spacer = MenuAPI.CreateREPOSpacer(parent, default(Vector2), new Vector2(0f, 8f));
						return ((REPOElement)spacer).rectTransform;
					}, 0f, 0f);
				}
				if ((Object)(object)groupHeader != (Object)null)
				{
					roomGroupVisuals.Add(new RoomGroupVisual(roomGroup.Key, groupHeader, list, spacer, 0f));
				}
			}
		}

		private static string FormatValuableLine(ValuableEntry entry)
		{
			string text = (ValuableList.Instance.ShowDistanceInMenuEnabled ? (" (" + ValuableUtils.FormatDistanceMetersOneDecimal(entry.DistanceFromPlayerMeters) + "m)") : string.Empty);
			if (entry.IsCosmeticBox)
			{
				return entry.Name + text;
			}
			return entry.Name + " - " + ValuableUtils.FormatPrice(entry.Price) + text;
		}

		private static Color ResolveRowColor(ValuableEntry entry)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: 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)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			if (entry.IsCosmeticBox && entry.CosmeticBoxRarity.HasValue)
			{
				return ValuableUtils.GetCosmeticBoxRarityColor(entry.CosmeticBoxRarity.Value);
			}
			return entry.IsInCartOrExtraction ? HighlightValueLabelColor : ValueLabelColor;
		}

		private void AddSearchBox(REPOPopupPage page)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			REPOPopupPage page2 = page;
			page2.AddElement((BuilderDelegate)delegate(Transform parent)
			{
				//IL_0030: Unknown result type (might be due to invalid IL or missing references)
				//IL_004a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0054: Unknown result type (might be due to invalid IL or missing references)
				((Component)MenuAPI.CreateREPOInputField("Search", (Action<string>)delegate(string query)
				{
					currentSearchQuery = query ?? string.Empty;
					ApplySearchFilter(page2, currentSearchQuery);
				}, parent, new Vector2(83f, 272f), false, "", "")).transform.localScale = Vector3.one * 0.95f;
			});
		}

		private void ApplySearchFilter(REPOPopupPage page, string query)
		{
			try
			{
				string value = (string.IsNullOrWhiteSpace(query) ? string.Empty : query.Trim().ToLowerInvariant());
				int num = 0;
				foreach (RoomGroupVisual roomGroupVisual in roomGroupVisuals)
				{
					bool flag = false;
					int num2 = 0;
					foreach (ValuableRowVisual row in roomGroupVisual.Rows)
					{
						bool flag2 = string.IsNullOrEmpty(value) || row.NameLower.Contains(value);
						bool flag3 = !hideCollectedValuables || !row.IsInCartOrExtraction;
						bool flag4 = flag2 && flag3;
						SetLabelVisibility(row.Label, flag4);
						flag = flag || flag4;
						if (flag4)
						{
							num2 += row.Price;
						}
					}
					SetLabelVisibility(roomGroupVisual.Header, flag);
					((TMP_Text)roomGroupVisual.Header.labelTMP).text = ValuableUtils.TruncateRoomNameForMenuDisplay(roomGroupVisual.RoomName) + " (" + ValuableUtils.FormatPrice(num2) + ")";
					if (flag)
					{
						num++;
					}
				}
				foreach (RoomGroupVisual roomGroupVisual2 in roomGroupVisuals)
				{
					if (!((Object)(object)roomGroupVisual2.Spacer == (Object)null))
					{
						SetSpacerVisibility(roomGroupVisual2.Spacer, IsLabelVisible(roomGroupVisual2.Header));
					}
				}
				SetLabelVisibility(noResultsLabel, roomGroupVisuals.Count > 0 && num == 0);
				UpdateToggleButtonVisual();
				UpdateSummaryLabelFromVisibleRows();
				page.scrollView.SetScrollPosition(0f);
			}
			catch (Exception arg)
			{
				logger.LogError((object)$"Search filter update failed: {arg}");
			}
		}

		private void ScrollToCurrentPlayerRoom(REPOPopupPage page)
		{
			MenuScrollBox menuScrollBox = page.menuScrollBox;
			page.scrollView.UpdateElements();
			TryRecalculateMenuScrollHeight(menuScrollBox);
			page.scrollView.UpdateElements();
			CacheRoomScrollTargets(page);
			if ((Object)(object)menuScrollBox == (Object)null || !menuScrollBox.scrollBar.activeSelf || roomGroupVisuals.Count == 0)
			{
				SnapMenuScrollToScrollerY(menuScrollBox, 0f);
				return;
			}
			string currentRoom = ValuableUtils.GetCurrentPlayerRoomName();
			if (string.IsNullOrWhiteSpace(currentRoom))
			{
				SnapMenuScrollToScrollerY(menuScrollBox, 0f);
				return;
			}
			int num = roomGroupVisuals.FindIndex((RoomGroupVisual group) => string.Equals(group.RoomName, currentRoom, StringComparison.OrdinalIgnoreCase));
			if (num < 0)
			{
				SnapMenuScrollToScrollerY(menuScrollBox, 0f);
				return;
			}
			SnapMenuScrollToScrollerY(menuScrollBox, roomGroupVisuals[num].CachedTargetScrollerY);
			page.scrollView.UpdateElements();
		}

		[IteratorStateMachine(typeof(<ScrollToCurrentPlayerRoomAfterOpen>d__23))]
		private IEnumerator ScrollToCurrentPlayerRoomAfterOpen(REPOPopupPage page)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <ScrollToCurrentPlayerRoomAfterOpen>d__23(0)
			{
				<>4__this = this,
				page = page
			};
		}

		private void CacheRoomScrollTargets(REPOPopupPage page)
		{
			MenuScrollBox menuScrollBox = page.menuScrollBox;
			if (roomGroupVisuals.Count == 0 || (Object)(object)menuScrollBox == (Object)null)
			{
				return;
			}
			if (!menuScrollBox.scrollBar.activeSelf)
			{
				foreach (RoomGroupVisual roomGroupVisual in roomGroupVisuals)
				{
					roomGroupVisual.CachedTargetScrollerY = 0f;
				}
				return;
			}
			foreach (RoomGroupVisual roomGroupVisual2 in roomGroupVisuals)
			{
				((Component)roomGroupVisual2.Header).gameObject.SetActive(true);
			}
			RectTransform maskRectTransform = page.maskRectTransform;
			float worldTopY = GetWorldTopY(maskRectTransform);
			SetScrollerLocalYRaw(menuScrollBox, 0f);
			float[] array = new float[roomGroupVisuals.Count];
			for (int i = 0; i < roomGroupVisuals.Count; i++)
			{
				array[i] = GetWorldTopY(((REPOElement)roomGroupVisuals[i].Header).rectTransform);
			}
			float num = (float)MenuScrollReflection.ScrollerStartPosition.GetValue(menuScrollBox);
			float num2 = ((Mathf.Abs(num) > 1f) ? (num * 0.5f) : 100f);
			SetScrollerLocalYRaw(menuScrollBox, num2);
			float worldTopY2 = GetWorldTopY(((REPOElement)roomGroupVisuals[0].Header).rectTransform);
			float num3 = worldTopY2 - array[0];
			float num4 = ((Mathf.Abs(num2) < 0.0001f) ? 0f : (num3 / num2));
			for (int j = 0; j < roomGroupVisuals.Count; j++)
			{
				if (Mathf.Abs(num4) < 0.0001f)
				{
					roomGroupVisuals[j].CachedTargetScrollerY = 0f;
				}
				else
				{
					roomGroupVisuals[j].CachedTargetScrollerY = (worldTopY - array[j]) / num4;
				}
			}
			SnapMenuScrollToScrollerY(menuScrollBox, 0f);
		}

		private static void TryRecalculateMenuScrollHeight(MenuScrollBox? menuScrollBox)
		{
			if (!((Object)(object)menuScrollBox == (Object)null))
			{
				AccessTools.Method(typeof(MenuScrollBox), "RecalculateScrollHeight", (Type[])null, (Type[])null)?.Invoke(menuScrollBox, null);
			}
		}

		private static float GetWorldTopY(RectTransform rectTransform)
		{
			Vector3[] array = (Vector3[])(object)new Vector3[4];
			rectTransform.GetWorldCorners(array);
			return Mathf.Max(Mathf.Max(array[0].y, array[1].y), Mathf.Max(array[2].y, array[3].y));
		}

		internal static void SnapMenuScrollToScrollerY(MenuScrollBox? menuScrollBox, float scrollerLocalY)
		{
			SetScrollerLocalYRaw(menuScrollBox, scrollerLocalY);
			SyncScrollBox(menuScrollBox);
		}

		private static void SetScrollerLocalYRaw(MenuScrollBox? msb, float y)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)msb?.scroller == (Object)null))
			{
				RectTransform scroller = msb.scroller;
				((Transform)scroller).localPosition = new Vector3(((Transform)scroller).localPosition.x, y, ((Transform)scroller).localPosition.z);
			}
		}

		private static void SyncScrollBox(MenuScrollBox? msb)
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: 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_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)msb == (Object)null) && msb.scrollBar.activeSelf)
			{
				float num = (float)MenuScrollReflection.ScrollerStartPosition.GetValue(msb);
				float num2 = (float)MenuScrollReflection.ScrollerEndPosition.GetValue(msb);
				float num3 = num2 - num;
				float y = ((Transform)msb.scroller).localPosition.y;
				float num4 = (Mathf.Approximately(num3, 0f) ? 1f : Mathf.Clamp01((y - num) / num3));
				Rect rect = msb.scrollBarBackground.rect;
				float height = ((Rect)(ref rect)).height;
				float num5 = msb.scrollHandle.sizeDelta.y / 2f;
				float num6 = num4 * height - num5;
				num6 = Mathf.Clamp(num6, num5, height - num5);
				float num7 = Mathf.Clamp01((num6 + num5) / height);
				((Transform)msb.scrollHandle).localPosition = new Vector3(((Transform)msb.scrollHandle).localPosition.x, num6, ((Transform)msb.scrollHandle).localPosition.z);
				MenuScrollReflection.ScrollHandleTargetPosition.SetValue(msb, num6);
				MenuScrollReflection.ScrollAmount.SetValue(msb, num7);
				float num8 = Mathf.Lerp(num, num2, num7);
				RectTransform scroller = msb.scroller;
				((Transform)scroller).localPosition = new Vector3(((Transform)scroller).localPosition.x, num8, ((Transform)scroller).localPosition.z);
			}
		}

		private REPOLabel? AddCollectedSummaryLabel(REPOPopupPage page, List<IGrouping<string, ValuableEntry>> grouped)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			List<IGrouping<string, ValuableEntry>> grouped2 = grouped;
			REPOLabel created = null;
			page.AddElement((BuilderDelegate)delegate(Transform parent)
			{
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				//IL_0060: Unknown result type (might be due to invalid IL or missing references)
				created = MenuAPI.CreateREPOLabel(BuildSummaryText(grouped2), parent, new Vector2(120f, 20f));
				((TMP_Text)created.labelTMP).fontStyle = (FontStyles)0;
				((TMP_Text)created.labelTMP).fontSize = 24f;
				((Graphic)created.labelTMP).color = SummaryColorForGrouped(grouped2);
				((TMP_Text)created.labelTMP).alignment = (TextAlignmentOptions)516;
			});
			return created;
		}

		private static string BuildSummaryText(IEnumerable<IGrouping<string, ValuableEntry>> grouped)
		{
			int num = grouped.Sum((IGrouping<string, ValuableEntry> group) => group.Count());
			int num2 = grouped.Sum((IGrouping<string, ValuableEntry> group) => group.Count((ValuableEntry entry) => entry.IsInCartOrExtraction));
			int rawPrice = grouped.Sum((IGrouping<string, ValuableEntry> group) => group.Where((ValuableEntry entry) => !entry.IsInCartOrExtraction).Sum((ValuableEntry entry) => entry.Price));
			return $"{num2}/{num}, {ValuableUtils.FormatPrice(rawPrice)}";
		}

		private static Color SummaryColorForGrouped(IEnumerable<IGrouping<string, ValuableEntry>> grouped)
		{
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: 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)
			int num = grouped.Sum((IGrouping<string, ValuableEntry> group) => group.Count());
			int num2 = grouped.Sum((IGrouping<string, ValuableEntry> group) => group.Count((ValuableEntry entry) => entry.IsInCartOrExtraction));
			return (num > 0 && num2 == num) ? HighlightValueLabelColor : ValueLabelColor;
		}

		private void UpdateSummaryLabelFromVisibleRows()
		{
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)summaryLabel?.labelTMP == (Object)null)
			{
				return;
			}
			int num = 0;
			int num2 = 0;
			int num3 = 0;
			foreach (RoomGroupVisual roomGroupVisual in roomGroupVisuals)
			{
				foreach (ValuableRowVisual row in roomGroupVisual.Rows)
				{
					num3 += row.Price;
					num2++;
					if (row.IsInCartOrExtraction)
					{
						num++;
					}
				}
			}
			((TMP_Text)summaryLabel.labelTMP).text = $"{num}/{num2} - {ValuableUtils.FormatPrice(num3)}";
			((Graphic)summaryLabel.labelTMP).color = ((num2 > 0 && num == num2) ? HighlightValueLabelColor : ValueLabelColor);
		}

		private void AddCollectedButton(REPOPopupPage page)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			REPOPopupPage page2 = page;
			page2.AddElement((BuilderDelegate)delegate(Transform parent)
			{
				//IL_0036: Unknown result type (might be due to invalid IL or missing references)
				toggleCollectedButton = MenuAPI.CreateREPOButton("Collected", (Action)delegate
				{
					hideCollectedValuables = !hideCollectedValuables;
					ApplySearchFilter(page2, currentSearchQuery);
				}, parent, new Vector2(66f, 18f));
				UpdateToggleButtonVisual();
			});
		}

		private void CloseCurrentPage()
		{
			if ((Object)(object)currentPage != (Object)null)
			{
				currentPage.ClosePage(true);
			}
			currentPage = null;
			isOpen = false;
			summaryLabel = null;
		}

		private static bool IsAnotherMenuOpen()
		{
			return Object.op_Implicit((Object)(object)MenuManager.instance) && Object.op_Implicit((Object)(object)MenuManager.instance.currentMenuPage);
		}

		private void UpdateToggleButtonVisual()
		{
			if (!((Object)(object)toggleCollectedButton?.labelTMP == (Object)null))
			{
				((TMP_Text)toggleCollectedButton.labelTMP).text = (hideCollectedValuables ? "Show Collected" : "Hide Collected");
			}
		}

		private static void SetLabelVisibility(REPOLabel? label, bool visible)
		{
			if (!((Object)(object)label == (Object)null) && !((Object)(object)((REPOElement)label).repoScrollViewElement == (Object)null))
			{
				((REPOElement)label).repoScrollViewElement.visibility = visible;
			}
		}

		private static bool IsLabelVisible(REPOLabel? label)
		{
			if ((Object)(object)label == (Object)null || (Object)(object)((REPOElement)label).repoScrollViewElement == (Object)null)
			{
				return false;
			}
			return ((REPOElement)label).repoScrollViewElement.visibility;
		}

		private static void SetSpacerVisibility(REPOSpacer? spacer, bool visible)
		{
			if (!((Object)(object)spacer == (Object)null) && !((Object)(object)((REPOElement)spacer).repoScrollViewElement == (Object)null))
			{
				((REPOElement)spacer).repoScrollViewElement.visibility = visible;
			}
		}
	}
	internal static class ValuableUtils
	{
		private sealed class MaterializedRoomGroup : IGrouping<string, ValuableEntry>, IEnumerable<ValuableEntry>, IEnumerable
		{
			private readonly List<ValuableEntry> _entries;

			public string Key { get; }

			internal MaterializedRoomGroup(string key, List<ValuableEntry> entries)
			{
				Key = key;
				_entries = entries;
			}

			public IEnumerator<ValuableEntry> GetEnumerator()
			{
				return _entries.GetEnumerator();
			}

			IEnumerator IEnumerable.GetEnumerator()
			{
				return GetEnumerator();
			}
		}

		private static readonly Regex RoomMetadataPrefixRegex = new Regex("^[^-]+?\\s*-\\s*[A-Z]+\\s*-\\s*\\d+\\s*-\\s*(.+)$", RegexOptions.Compiled);

		private static float hudCacheTime;

		private static (ValuableEntry? Entry, int Count, float DistanceToBestMeters) mostExpensiveCachedResult;

		private static (int CollectedCount, int TotalCount, int CollectedValue, int TotalValue) levelCollectionCachedResult;

		private static (int InRoomCount, int TotalCount, Rarity? RoomDominantRarity) cosmeticBoxesCachedResult;

		private const float HudCacheInterval = 0.5f;

		private static bool cosmeticBoxColorsResolved;

		private static Color cosmeticBoxColorCommon = new Color(0.31f, 0.85f, 0.31f, 1f);

		private static Color cosmeticBoxColorUncommon = new Color(0.4f, 0.7f, 1f, 1f);

		private static Color cosmeticBoxColorRare = new Color(1f, 0.08f, 0.58f, 1f);

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

		internal static List<IGrouping<string, ValuableEntry>> GetGroupedValuables()
		{
			List<ValuableEntry> source = GetValuableEntries().OrderBy<ValuableEntry, string>((ValuableEntry v) => v.Room, StringComparer.OrdinalIgnoreCase).ThenBy((ValuableEntry v) => (!v.IsCosmeticBox) ? 1 : 0).ThenBy((ValuableEntry v) => v.IsInCartOrExtraction)
				.ThenByDescending((ValuableEntry v) => (!v.CosmeticBoxRarity.HasValue) ? (-1) : ((int)v.CosmeticBoxRarity.Value))
				.ThenByDescending((ValuableEntry v) => v.Price)
				.ThenBy<ValuableEntry, string>((ValuableEntry v) => v.Name, StringComparer.OrdinalIgnoreCase)
				.ToList();
			List<MaterializedRoomGroup> list = (from v in source
				group v by v.Room into g
				select new MaterializedRoomGroup(g.Key, g.ToList())).ToList();
			list.Sort(delegate(MaterializedRoomGroup a, MaterializedRoomGroup b)
			{
				long value = SumPrices(a);
				int num = SumPrices(b).CompareTo(value);
				return (num != 0) ? num : string.Compare(a.Key, b.Key, StringComparison.OrdinalIgnoreCase);
			});
			return list.ConvertAll((Converter<MaterializedRoomGroup, IGrouping<string, ValuableEntry>>)((MaterializedRoomGroup g) => g));
		}

		private static long SumPrices(IEnumerable<ValuableEntry> entries)
		{
			long num = 0L;
			foreach (ValuableEntry entry in entries)
			{
				num += entry.Price;
			}
			return num;
		}

		internal static (ValuableEntry? Entry, int Count, float DistanceToBestMeters) GetMostExpensiveInCurrentRoom()
		{
			EnsureHudCaches();
			return mostExpensiveCachedResult;
		}

		internal static (int CollectedCount, int TotalCount, int CollectedValue, int TotalValue) GetLevelCollectionStats()
		{
			EnsureHudCaches();
			return levelCollectionCachedResult;
		}

		internal static (int InRoomCount, int TotalCount, Rarity? RoomDominantRarity) GetCosmeticBoxStats()
		{
			EnsureHudCaches();
			return cosmeticBoxesCachedResult;
		}

		internal static Color GetCosmeticBoxRarityColor(Rarity rarity)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected I4, but got Unknown
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			if (!cosmeticBoxColorsResolved)
			{
				TryResolveCosmeticBoxColors();
			}
			if (1 == 0)
			{
			}
			Color result = (Color)((int)rarity switch
			{
				0 => cosmeticBoxColorCommon, 
				1 => cosmeticBoxColorUncommon, 
				2 => cosmeticBoxColorRare, 
				3 => cosmeticBoxColorUltraRare, 
				_ => Color.white, 
			});
			if (1 == 0)
			{
			}
			return result;
		}

		internal static string ToHtmlHex(Color color)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			int num = Mathf.RoundToInt(Mathf.Clamp01(color.r) * 255f);
			int num2 = Mathf.RoundToInt(Mathf.Clamp01(color.g) * 255f);
			int num3 = Mathf.RoundToInt(Mathf.Clamp01(color.b) * 255f);
			return $"#{num:X2}{num2:X2}{num3:X2}";
		}

		private static void TryResolveCosmeticBoxColors()
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			CosmeticWorldObjectUI instance = CosmeticWorldObjectUI.instance;
			if (!((Object)(object)instance == (Object)null) && !((Object)(object)instance.elementPrefab == (Object)null))
			{
				CosmeticWorldObjectUIElement component = instance.elementPrefab.GetComponent<CosmeticWorldObjectUIElement>();
				if (!((Object)(object)component == (Object)null))
				{
					cosmeticBoxColorCommon = component.colorCommon;
					cosmeticBoxColorUncommon = component.colorUncommon;
					cosmeticBoxColorRare = component.colorRare;
					cosmeticBoxColorUltraRare = component.colorUltraRare;
					cosmeticBoxColorsResolved = true;
				}
			}
		}

		private static void EnsureHudCaches()
		{
			if (!(Time.time - hudCacheTime < 0.5f))
			{
				hudCacheTime = Time.time;
				ComputeHudCaches();
			}
		}

		private static void ComputeHudCaches()
		{
			string currentPlayerRoomName = GetCurrentPlayerRoomName();
			ValuableEntry? item = null;
			float item2 = 0f;
			int num = 0;
			int num2 = 0;
			int num3 = 0;
			int num4 = 0;
			int num5 = 0;
			foreach (ValuableObject allValuableObject in GetAllValuableObjects())
			{
				num2++;
				int num6 = FloorDollarValue(allValuableObject.dollarValueCurrent);
				num4 += num6;
				bool flag = IsInCartOrExtraction(allValuableObject);
				if (flag)
				{
					num3++;
					num5 += num6;
				}
				if (string.IsNullOrWhiteSpace(currentPlayerRoomName) || flag)
				{
					continue;
				}
				string roomName = GetRoomName(allValuableObject);
				if (string.Equals(roomName, currentPlayerRoomName, StringComparison.OrdinalIgnoreCase))
				{
					num++;
					if (!item.HasValue || num6 > item.Value.Price)
					{
						item = new ValuableEntry(CleanValuableName(((Object)((Component)allValuableObject).gameObject).name), num6, roomName, isInCartOrExtraction: false);
						item2 = GetDistanceFromPlayerMeters(((Component)allValuableObject).transform);
					}
				}
			}
			mostExpensiveCachedResult = (item, num, item2);
			levelCollectionCachedResult = (num3, num2, num5, num4);
			ComputeCosmeticBoxCaches(currentPlayerRoomName);
		}

		private static void ComputeCosmeticBoxCaches(string? currentRoom)
		{
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			int num = 0;
			int num2 = 0;
			Rarity? item = null;
			RoundDirector instance = RoundDirector.instance;
			if ((Object)(object)instance != (Object)null)
			{
				foreach (CosmeticWorldObject cosmeticWorldObject in instance.cosmeticWorldObjects)
				{
					if (!Object.op_Implicit((Object)(object)cosmeticWorldObject))
					{
						continue;
					}
					num2++;
					if (string.IsNullOrWhiteSpace(currentRoom))
					{
						continue;
					}
					string cosmeticRoomName = GetCosmeticRoomName(cosmeticWorldObject);
					if (string.Equals(cosmeticRoomName, currentRoom, StringComparison.OrdinalIgnoreCase))
					{
						num++;
						if (!item.HasValue || cosmeticWorldObject.rarity > item.Value)
						{
							item = cosmeticWorldObject.rarity;
						}
					}
				}
			}
			cosmeticBoxesCachedResult = (num, num2, item);
		}

		private static string GetCosmeticRoomName(CosmeticWorldObject cosmetic)
		{
			RoomVolume val = cosmetic.roomVolumeCheck?.CurrentRooms?.FirstOrDefault((Func<RoomVolume, bool>)((RoomVolume r) => (Object)(object)r != (Object)null && (Object)(object)r.Module != (Object)null));
			if ((Object)(object)val?.Module == (Object)null)
			{
				return "Unknown";
			}
			return CleanRoomName(((Object)val.Module).name);
		}

		internal static string? GetCurrentPlayerRoomName()
		{
			RoomVolume val = PlayerAvatar.instance?.RoomVolumeCheck?.CurrentRooms?.FirstOrDefault((Func<RoomVolume, bool>)((RoomVolume r) => (Object)(object)r != (Object)null && (Object)(object)r.Module != (Object)null));
			if ((Object)(object)val?.Module == (Object)null)
			{
				return null;
			}
			return CleanRoomName(((Object)val.Module).name);
		}

		private static string GetRoomName(ValuableObject valuable)
		{
			RoomVolume val = valuable.roomVolumeCheck?.CurrentRooms?.FirstOrDefault((Func<RoomVolume, bool>)((RoomVolume r) => (Object)(object)r != (Object)null && (Object)(object)r.Module != (Object)null));
			if ((Object)(object)val?.Module == (Object)null)
			{
				return "Unknown";
			}
			return CleanRoomName(((Object)val.Module).name);
		}

		private static bool IsInCartOrExtraction(ValuableObject valuable)
		{
			bool flag = (Object)(object)valuable.physGrabObject != (Object)null && (Object)(object)valuable.physGrabObject.impactDetector != (Object)null && valuable.physGrabObject.impactDetector.inCart;
			bool flag2 = (Object)(object)valuable.roomVolumeCheck != (Object)null && valuable.roomVolumeCheck.inExtractionPoint;
			return flag || flag2;
		}

		private static string CleanValuableName(string source)
		{
			string text = CleanBasicName(source);
			if (text.StartsWith("Valuable ", StringComparison.OrdinalIgnoreCase))
			{
				int num = text.IndexOf(' ');
				if (num >= 0)
				{
					int num2 = text.IndexOf(' ', num + 1);
					if (num2 >= 0 && num2 + 1 < text.Length)
					{
						return text.Substring(num2 + 1).Trim();
					}
				}
			}
			return text.Replace(" Valuable ", " ").Trim();
		}

		private static string CleanRoomName(string source)
		{
			string text = StripPrefix(CleanBasicName(source), "Module - ");
			if (text.IndexOf("Start Room", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				return "Start Room";
			}
			Match match = RoomMetadataPrefixRegex.Match(text);
			if (match.Success)
			{
				string text2 = match.Groups[1].Value.Trim();
				if (!string.IsNullOrWhiteSpace(text2))
				{
					return text2;
				}
			}
			return text;
		}

		private static string CleanBasicName(string source)
		{
			if (string.IsNullOrWhiteSpace(source))
			{
				return "Unknown";
			}
			return source.Replace("(Clone)", string.Empty).Trim();
		}

		private static string StripPrefix(string source, string prefix)
		{
			if (source.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
			{
				return source.Substring(prefix.Length).Trim();
			}
			return source;
		}

		private static IEnumerable<ValuableObject> GetAllValuableObjects()
		{
			List<ValuableObject> tracked = ValuableObjectPatch.Tracked;
			tracked.RemoveAll((ValuableObject v) => !Object.op_Implicit((Object)(object)v));
			return tracked.Where((ValuableObject v) => ((Component)v).gameObject.activeInHierarchy);
		}

		private static IEnumerable<ValuableEntry> GetValuableEntries()
		{
			bool includeDistance = ValuableList.Instance.ShowDistanceInMenuEnabled;
			IEnumerable<ValuableEntry> first = from v in GetAllValuableObjects()
				select new ValuableEntry(CleanValuableName(((Object)((Component)v).gameObject).name), FloorDollarValue(v.dollarValueCurrent), GetRoomName(v), IsInCartOrExtraction(v), includeDistance ? GetDistanceFromPlayerMeters(((Component)v).transform) : 0f);
			IEnumerable<ValuableEntry> second = from c in GetAllCosmeticBoxes()
				select new ValuableEntry(GetCosmeticBoxDisplayName(c), 0, GetCosmeticRoomName(c), IsInCartOrExtraction(c), includeDistance ? GetDistanceFromPlayerMeters(((Component)c).transform) : 0f, c.rarity);
			return first.Concat(second);
		}

		private static IEnumerable<CosmeticWorldObject> GetAllCosmeticBoxes()
		{
			RoundDirector instance = RoundDirector.instance;
			if ((Object)(object)instance == (Object)null)
			{
				return Enumerable.Empty<CosmeticWorldObject>();
			}
			return instance.cosmeticWorldObjects.Where((CosmeticWorldObject c) => Object.op_Implicit((Object)(object)c) && ((Component)c).gameObject.activeInHierarchy);
		}

		private static bool IsInCartOrExtraction(CosmeticWorldObject cosmetic)
		{
			bool flag = (Object)(object)cosmetic.physGrabObject != (Object)null && (Object)(object)cosmetic.physGrabObject.impactDetector != (Object)null && cosmetic.physGrabObject.impactDetector.inCart;
			bool flag2 = (Object)(object)cosmetic.roomVolumeCheck != (Object)null && cosmetic.roomVolumeCheck.inExtractionPoint;
			return flag || flag2;
		}

		private static string GetCosmeticBoxDisplayName(CosmeticWorldObject cosmetic)
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			string text = CleanBasicName(((Object)((Component)cosmetic).gameObject).name);
			if (string.IsNullOrWhiteSpace(text) || string.Equals(text, "Unknown", StringComparison.OrdinalIgnoreCase) || text.IndexOf("Cosmetic", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				return GetFallbackCosmeticBoxName(cosmetic.rarity);
			}
			return text;
		}

		private static string GetFallbackCosmeticBoxName(Rarity rarity)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected I4, but got Unknown
			if (1 == 0)
			{
			}
			string result = (int)rarity switch
			{
				0 => "Cosmetic box - Common", 
				1 => "Cosmetic box - Uncommon", 
				2 => "Cosmetic box - Rare", 
				3 => "Cosmetic box - Ultra-rare", 
				_ => "Cosmetic box", 
			};
			if (1 == 0)
			{
			}
			return result;
		}

		private static float GetDistanceFromPlayerMeters(Transform target)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			PlayerAvatar instance = PlayerAvatar.instance;
			if ((Object)(object)instance == (Object)null || (Object)(object)target == (Object)null)
			{
				return 0f;
			}
			return Vector3.Distance(((Component)instance).transform.position, target.position);
		}

		public static string FormatPrice(int rawPrice)
		{
			if (ValuableList.Instance.RoundPricesEnabled)
			{
				return "$" + (Mathf.Floor((float)rawPrice / 100f) / 10f).ToString("0.0", CultureInfo.InvariantCulture) + "K";
			}
			return $"${rawPrice}";
		}

		internal static string FormatDistanceMetersOneDecimal(float meters)
		{
			return (Mathf.Floor(Mathf.Max(0f, meters) * 10f) / 10f).ToString("0.0", CultureInfo.InvariantCulture);
		}

		internal static string TruncateRoomNameForMenuDisplay(string roomName)
		{
			if (string.IsNullOrEmpty(roomName) || roomName.Length <= 28)
			{
				return roomName;
			}
			return roomName.Substring(0, 25) + "...";
		}

		private static int FloorDollarValue(float dollarValueCurrent)
		{
			return Mathf.FloorToInt(dollarValueCurrent);
		}
	}
	internal readonly struct ValuableEntry
	{
		public string Name { get; }

		public int Price { get; }

		public string Room { get; }

		public bool IsInCartOrExtraction { get; }

		public float DistanceFromPlayerMeters { get; }

		public Rarity? CosmeticBoxRarity { get; }

		public bool IsCosmeticBox => CosmeticBoxRarity.HasValue;

		internal ValuableEntry(string name, int price, string room, bool isInCartOrExtraction, float distanceFromPlayerMeters = 0f, Rarity? cosmeticBoxRarity = null)
		{
			Name = name;
			Price = price;
			Room = room;
			IsInCartOrExtraction = isInCartOrExtraction;
			DistanceFromPlayerMeters = distanceFromPlayerMeters;
			CosmeticBoxRarity = cosmeticBoxRarity;
		}
	}
}