Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of ValuableList v1.4.0
ValuableList.dll
Decompiled 2 months agousing 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; } } }