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.3.0
ValuableList.dll
Decompiled 3 weeks 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+f6dfe470e385fe94ae49ee6638ae567c8e685853")] [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 { [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_0124: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) 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) mostExpensiveInCurrentRoom = ValuableUtils.GetMostExpensiveInCurrentRoom(); ValuableEntry? item = mostExpensiveInCurrentRoom.Entry; int item2 = mostExpensiveInCurrentRoom.Count; (int CollectedCount, int TotalCount, int CollectedValue, int TotalValue) levelCollectionStats = ValuableUtils.GetLevelCollectionStats(); int item3 = levelCollectionStats.CollectedCount; int item4 = levelCollectionStats.TotalCount; int item5 = levelCollectionStats.CollectedValue; int item6 = levelCollectionStats.TotalValue; string text = $"{item3}/{item4} - {ValuableUtils.FormatPrice(item5)}/{ValuableUtils.FormatPrice(item6)}"; ((TMP_Text)statsLineText).text = text; ((Graphic)statsLineText).color = ((item4 > 0 && item3 == item4) ? ValuablesMenu.HighlightValueLabelColor : Color.white); if ((Object)(object)mostExpensiveLineText != (Object)null) { if (item.HasValue) { ((Component)mostExpensiveLineText).gameObject.SetActive(true); ((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_0250: Unknown result type (might be due to invalid IL or missing references) //IL_0267: Unknown result type (might be due to invalid IL or missing references) //IL_027e: Unknown result type (might be due to invalid IL or missing references) //IL_0295: Unknown result type (might be due to invalid IL or missing references) 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); 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 void SetLabelActive(bool active) { if ((Object)(object)labelObject != (Object)null && labelObject.activeSelf != active) { labelObject.SetActive(active); } } } [BepInPlugin("McHorse.ValuableList", "ValuableList", "1.3")] [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 appends distance from your player in meters to each line (HUD unchanged)."); 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 readonly struct RoomGroupVisual { internal string RoomName { get; } internal REPOLabel Header { get; } internal List<ValuableRowVisual> Rows { get; } internal REPOSpacer? Spacer { get; } internal RoomGroupVisual(string roomName, REPOLabel header, List<ValuableRowVisual> rows, REPOSpacer? spacer) { RoomName = roomName; Header = header; Rows = rows; Spacer = spacer; } } [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__24_0; public static Func<ValuableEntry, bool> <>9__24_3; public static Func<IGrouping<string, ValuableEntry>, int> <>9__24_1; public static Func<ValuableEntry, bool> <>9__24_4; public static Func<ValuableEntry, int> <>9__24_5; public static Func<IGrouping<string, ValuableEntry>, int> <>9__24_2; public static Func<IGrouping<string, ValuableEntry>, int> <>9__25_0; public static Func<ValuableEntry, bool> <>9__25_2; public static Func<IGrouping<string, ValuableEntry>, int> <>9__25_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__24_0(IGrouping<string, ValuableEntry> group) { return group.Count(); } internal int <BuildSummaryText>b__24_1(IGrouping<string, ValuableEntry> group) { return group.Count((ValuableEntry entry) => entry.IsInCartOrExtraction); } internal bool <BuildSummaryText>b__24_3(ValuableEntry entry) { return entry.IsInCartOrExtraction; } internal int <BuildSummaryText>b__24_2(IGrouping<string, ValuableEntry> group) { return group.Where((ValuableEntry entry) => !entry.IsInCartOrExtraction).Sum((ValuableEntry entry) => entry.Price); } internal bool <BuildSummaryText>b__24_4(ValuableEntry entry) { return !entry.IsInCartOrExtraction; } internal int <BuildSummaryText>b__24_5(ValuableEntry entry) { return entry.Price; } internal int <SummaryColorForGrouped>b__25_0(IGrouping<string, ValuableEntry> group) { return group.Count(); } internal int <SummaryColorForGrouped>b__25_1(IGrouping<string, ValuableEntry> group) { return group.Count((ValuableEntry entry) => entry.IsInCartOrExtraction); } internal bool <SummaryColorForGrouped>b__25_2(ValuableEntry entry) { return entry.IsInCartOrExtraction; } } 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, groupedValuables)); } 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_0065: 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_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) 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 = (entry2.IsInCartOrExtraction ? HighlightValueLabelColor : ValueLabelColor); 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)); } } } private static string FormatValuableLine(ValuableEntry entry) { string text = ValuableUtils.FormatPrice(entry.Price); if (!ValuableList.Instance.ShowDistanceInMenuEnabled) { return entry.Name + " - " + text; } string text2 = ValuableUtils.FormatDistanceMetersOneDecimal(entry.DistanceFromPlayerMeters); return entry.Name + " - " + text + " (" + text2 + "m)"; } 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 static void ScrollToCurrentPlayerRoom(REPOPopupPage page, List<IGrouping<string, ValuableEntry>> grouped) { if (grouped.Count == 0) { return; } string currentRoom = ValuableUtils.GetCurrentPlayerRoomName(); if (string.IsNullOrWhiteSpace(currentRoom)) { page.scrollView.SetScrollPosition(0f); return; } int num = grouped.FindIndex((IGrouping<string, ValuableEntry> group) => string.Equals(group.Key, currentRoom, StringComparison.OrdinalIgnoreCase)); if (num < 0) { page.scrollView.SetScrollPosition(0f); return; } if (num == 0) { page.scrollView.SetScrollPosition(0f); return; } float scrollPosition = (float)num / (float)Math.Max(1, grouped.Count - 1); page.scrollView.SetScrollPosition(scrollPosition); } private IEnumerator ScrollToCurrentPlayerRoomAfterOpen(REPOPopupPage page, List<IGrouping<string, ValuableEntry>> grouped) { yield return null; yield return null; if (isOpen && !((Object)(object)currentPage != (Object)(object)page)) { ApplySearchFilter(page, string.Empty); ScrollToCurrentPlayerRoom(page, grouped); } } 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) mostExpensiveCachedResult; private static (int CollectedCount, int TotalCount, int CollectedValue, int TotalValue) levelCollectionCachedResult; private const float HudCacheInterval = 0.5f; internal static List<IGrouping<string, ValuableEntry>> GetGroupedValuables() { List<ValuableEntry> source = GetValuableEntries().OrderBy<ValuableEntry, string>((ValuableEntry v) => v.Room, StringComparer.OrdinalIgnoreCase).ThenBy((ValuableEntry v) => v.IsInCartOrExtraction).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) GetMostExpensiveInCurrentRoom() { EnsureHudCaches(); return mostExpensiveCachedResult; } internal static (int CollectedCount, int TotalCount, int CollectedValue, int TotalValue) GetLevelCollectionStats() { EnsureHudCaches(); return levelCollectionCachedResult; } private static void EnsureHudCaches() { if (!(Time.time - hudCacheTime < 0.5f)) { hudCacheTime = Time.time; ComputeHudCaches(); } } private static void ComputeHudCaches() { string currentPlayerRoomName = GetCurrentPlayerRoomName(); ValuableEntry? item = null; 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); } } } mostExpensiveCachedResult = (item, num); levelCollectionCachedResult = (num3, num2, num5, num4); } 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; return from v in GetAllValuableObjects() select new ValuableEntry(CleanValuableName(((Object)((Component)v).gameObject).name), FloorDollarValue(v.dollarValueCurrent), GetRoomName(v), IsInCartOrExtraction(v), includeDistance ? GetDistanceFromPlayerMeters(v) : 0f); } private static float GetDistanceFromPlayerMeters(ValuableObject valuable) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) PlayerAvatar instance = PlayerAvatar.instance; if ((Object)(object)instance == (Object)null) { return 0f; } return Vector3.Distance(((Component)instance).transform.position, ((Component)valuable).transform.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; } internal ValuableEntry(string name, int price, string room, bool isInCartOrExtraction, float distanceFromPlayerMeters = 0f) { Name = name; Price = price; Room = room; IsInCartOrExtraction = isInCartOrExtraction; DistanceFromPlayerMeters = distanceFromPlayerMeters; } } }