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 Map Value Tracker Plus v1.2.3
MapValueTrackerPlus.dll
Decompiled 2 days agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using MapValueTracker.Config; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("MapValueTrackerPlus")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+4fd7a68438857c4d53908419869742676e2fa405")] [assembly: AssemblyProduct("MapValueTrackerPlus")] [assembly: AssemblyTitle("MapValueTrackerPlus")] [assembly: AssemblyVersion("1.0.0.0")] [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 MapValueTracker { [BepInPlugin("MapValueTrackerPlus", "Map Value Tracker Plus", "1.2.3")] public class MapValueTracker : BaseUnityPlugin { public const string PLUGIN_GUID = "MapValueTrackerPlus"; public const string PLUGIN_NAME = "Map Value Tracker Plus"; public const string PLUGIN_VERSION = "1.2.3"; private const float SnapshotRefreshResetTime = -100000f; private const float PendingValuableSettleSeconds = 0.05f; public static ManualLogSource Logger = null; private readonly Harmony harmony = new Harmony("MapValueTrackerPlus.REPO"); public static MapValueTracker? instance; public static GameObject? textInstance; public static TextMeshProUGUI? valueText; public static float totalValue; private static readonly FieldInfo? cartHaulCurrentField = AccessTools.Field(typeof(PhysGrabCart), "haulCurrent"); private static readonly FieldInfo? roomVolumeCheckInExtractionPointField = AccessTools.Field(typeof(RoomVolumeCheck), "inExtractionPoint"); private static readonly Dictionary<Type, Dictionary<string, MemberInfo?>> cachedMembers = new Dictionary<Type, Dictionary<string, MemberInfo>>(); private static readonly Dictionary<ValuableObject, float> trackedValuables = new Dictionary<ValuableObject, float>(); private static readonly Dictionary<ValuableObject, float> pendingValuables = new Dictionary<ValuableObject, float>(); private static readonly Dictionary<ItemValuableBox, float> trackedValuableBoxes = new Dictionary<ItemValuableBox, float>(); private static readonly HashSet<PhysGrabCart> trackedCarts = new HashSet<PhysGrabCart>(); private static bool cartFieldWarningLogged; private static bool snapshotDirty = true; private static bool fullResyncRequested = true; private static float lastSnapshotRefreshTime = -100000f; private static bool lastMapOpen; private static ValueBreakdownSnapshot currentSnapshot; public void Awake() { Logger = ((BaseUnityPlugin)this).Logger; Logger.LogInfo((object)"Plugin MapValueTrackerPlus is loaded!"); if ((Object)(object)instance == (Object)null) { instance = this; } Configuration.Init(((BaseUnityPlugin)this).Config); Configuration.RuntimeEnabled.SettingChanged += delegate { HandleRuntimeEnabledChanged(); }; harmony.PatchAll(); MarkDirty(); } public static bool IsRuntimeEnabled() { return Configuration.RuntimeEnabled.Value; } public static void HandleRuntimeEnabledChanged() { if (IsRuntimeEnabled()) { RequestFullResync(); return; } currentSnapshot = default(ValueBreakdownSnapshot); snapshotDirty = false; lastSnapshotRefreshTime = -100000f; pendingValuables.Clear(); } public static void ResetValues() { trackedValuables.Clear(); pendingValuables.Clear(); trackedValuableBoxes.Clear(); trackedCarts.Clear(); totalValue = 0f; currentSnapshot = default(ValueBreakdownSnapshot); RequestFullResync(); Logger.LogDebug((object)"Reset tracker state."); } public static void CheckForItems() { RebuildTrackedState(); } public static void RequestFullResync() { fullResyncRequested = true; MarkDirty(); } public static void MarkDirty() { snapshotDirty = true; } public static void RegisterCart(PhysGrabCart? cart) { if (!((Object)(object)cart == (Object)null) && IsRuntimeEnabled()) { trackedCarts.Add(cart); MarkDirty(); } } public static void UnregisterCart(PhysGrabCart? cart) { if (!((Object)(object)cart == (Object)null)) { trackedCarts.Remove(cart); MarkDirty(); } } public static void RegisterOrRefreshValuable(ValuableObject? valuable) { if ((Object)(object)valuable == (Object)null || !IsRuntimeEnabled()) { return; } if (trackedValuables.TryGetValue(valuable, out var value)) { float valuableCurrent = GetValuableCurrent(valuable); totalValue += valuableCurrent - value; trackedValuables[valuable] = valuableCurrent; MarkDirty(); return; } float unscaledTime = Time.unscaledTime; if (pendingValuables.TryGetValue(valuable, out var value2) && unscaledTime >= value2) { float valuableCurrent2 = GetValuableCurrent(valuable); pendingValuables.Remove(valuable); trackedValuables[valuable] = valuableCurrent2; totalValue += valuableCurrent2; MarkDirty(); } else { pendingValuables[valuable] = unscaledTime + 0.05f; MarkDirty(); } } public static void UnregisterValuable(ValuableObject? valuable) { if (!((Object)(object)valuable == (Object)null)) { pendingValuables.Remove(valuable); if (trackedValuables.TryGetValue(valuable, out var value)) { trackedValuables.Remove(valuable); totalValue -= value; } MarkDirty(); } } public static void RegisterOrRefreshValuableBox(ItemValuableBox? valuableBox) { if (!((Object)(object)valuableBox == (Object)null) && IsRuntimeEnabled()) { float num = (((Component)valuableBox).gameObject.activeInHierarchy ? valuableBox.CurrentValue : 0f); if (trackedValuableBoxes.TryGetValue(valuableBox, out var value)) { totalValue += num - value; trackedValuableBoxes[valuableBox] = num; } else { trackedValuableBoxes[valuableBox] = num; totalValue += num; } MarkDirty(); } } public static void UnregisterValuableBox(ItemValuableBox? valuableBox) { if (!((Object)(object)valuableBox == (Object)null)) { if (trackedValuableBoxes.TryGetValue(valuableBox, out var value)) { trackedValuableBoxes.Remove(valuableBox); totalValue -= value; } MarkDirty(); } } internal static ValueBreakdownSnapshot GetSnapshot() { if (!IsRuntimeEnabled()) { return default(ValueBreakdownSnapshot); } float unscaledTime = Time.unscaledTime; EnsureSynchronizedState(); ProcessPendingValuables(unscaledTime); bool mapOpen = IsMapOpen(); if (ShouldRefreshSnapshot(mapOpen, unscaledTime)) { currentSnapshot = BuildSnapshot(mapOpen); lastSnapshotRefreshTime = unscaledTime; snapshotDirty = false; } lastMapOpen = mapOpen; return currentSnapshot; } private static void EnsureSynchronizedState() { if (!IsRunActive()) { return; } if (fullResyncRequested) { RebuildTrackedState(); return; } CleanupTrackedCollections(); trackedCarts.RemoveWhere((PhysGrabCart cart) => (Object)(object)cart == (Object)null); } private static void RebuildTrackedState() { trackedValuables.Clear(); trackedValuableBoxes.Clear(); trackedCarts.Clear(); totalValue = 0f; if (!IsRunActive()) { fullResyncRequested = false; MarkDirty(); return; } ValuableObject[] array = Object.FindObjectsOfType<ValuableObject>(); foreach (ValuableObject val in array) { if (!((Object)(object)val == (Object)null) && !pendingValuables.ContainsKey(val)) { float valuableCurrent = GetValuableCurrent(val); trackedValuables[val] = valuableCurrent; totalValue += valuableCurrent; } } ItemValuableBox[] array2 = Object.FindObjectsOfType<ItemValuableBox>(); foreach (ItemValuableBox val2 in array2) { if (!((Object)(object)val2 == (Object)null)) { float num = (((Component)val2).gameObject.activeInHierarchy ? val2.CurrentValue : 0f); trackedValuableBoxes[val2] = num; totalValue += num; } } PhysGrabCart[] array3 = Object.FindObjectsOfType<PhysGrabCart>(); foreach (PhysGrabCart val3 in array3) { if ((Object)(object)val3 != (Object)null) { trackedCarts.Add(val3); } } fullResyncRequested = false; MarkDirty(); Logger.LogDebug((object)$"Rebuilt tracked state for {trackedValuables.Count} valuables, {trackedValuableBoxes.Count} valuable boxes, and {trackedCarts.Count} carts."); } private static void CleanupTrackedCollections() { List<ValuableObject> list = new List<ValuableObject>(); foreach (KeyValuePair<ValuableObject, float> trackedValuable in trackedValuables) { if ((Object)(object)trackedValuable.Key == (Object)null) { list.Add(trackedValuable.Key); } } for (int i = 0; i < list.Count; i++) { ValuableObject key = list[i]; if (trackedValuables.TryGetValue(key, out var value)) { trackedValuables.Remove(key); totalValue -= value; } } List<ItemValuableBox> list2 = new List<ItemValuableBox>(); foreach (KeyValuePair<ItemValuableBox, float> trackedValuableBox in trackedValuableBoxes) { if ((Object)(object)trackedValuableBox.Key == (Object)null) { list2.Add(trackedValuableBox.Key); } } for (int j = 0; j < list2.Count; j++) { ItemValuableBox key2 = list2[j]; if (trackedValuableBoxes.TryGetValue(key2, out var value2)) { trackedValuableBoxes.Remove(key2); totalValue -= value2; } } totalValue = Mathf.Max(0f, totalValue); } private static void ProcessPendingValuables(float now) { if (pendingValuables.Count == 0) { return; } List<ValuableObject> list = null; foreach (KeyValuePair<ValuableObject, float> pendingValuable in pendingValuables) { ValuableObject key = pendingValuable.Key; if ((Object)(object)key == (Object)null) { if (list == null) { list = new List<ValuableObject>(); } list.Add(key); } else if (now >= pendingValuable.Value) { if (list == null) { list = new List<ValuableObject>(); } list.Add(key); } } if (list == null) { return; } bool flag = false; for (int i = 0; i < list.Count; i++) { ValuableObject val = list[i]; if ((Object)(object)val == (Object)null) { pendingValuables.Remove(val); continue; } pendingValuables.Remove(val); if (!trackedValuables.ContainsKey(val)) { float valuableCurrent = GetValuableCurrent(val); trackedValuables[val] = valuableCurrent; totalValue += valuableCurrent; flag = true; } } if (flag) { totalValue = Mathf.Max(0f, totalValue); MarkDirty(); } } private static ValueBreakdownSnapshot BuildSnapshot(bool mapOpen) { ValueBreakdownSnapshot valueBreakdownSnapshot = default(ValueBreakdownSnapshot); valueBreakdownSnapshot.MapOpen = mapOpen; ValueBreakdownSnapshot result = valueBreakdownSnapshot; if (!IsRunActive()) { return result; } int roundDirectorInt = GetRoundDirectorInt("extractionHaulGoal"); bool roundDirectorBool = GetRoundDirectorBool("allExtractionPointsCompleted"); bool flag = Configuration.HideAfterFinalExtraction.Value && roundDirectorBool; bool flag2 = roundDirectorInt != 0 || !roundDirectorBool; ComputeBreakdownValues(out var mapValue, out var cartsValue, out var cartsValueOutsideExtraction, out var haulerValue, out var haulerValueOutsideExtraction, out var extractionValue); result.MapValue = Mathf.Max(0f, mapValue); result.CartsValue = Mathf.Max(0f, cartsValue); result.HaulerValue = Mathf.Max(0f, haulerValue); extractionValue = Mathf.Max(0f, extractionValue); result.RemainingValue = Mathf.Max(0f, result.MapValue - cartsValueOutsideExtraction - haulerValueOutsideExtraction - extractionValue); result.HideAfterCompletion = flag; result.UseRemainingForPrimary = Configuration.IsClosedModeRemaining(); result.IsVisible = flag2 && !flag; result.ShowCompactHud = result.IsVisible && !mapOpen && Configuration.AlwaysOn.Value; result.ShowMapPanel = result.IsVisible && mapOpen; totalValue = result.MapValue; return result; } public static bool IsMapOpen() { bool flag = false; if ((Object)(object)MapToolController.instance != (Object)null) { try { flag = Traverse.Create((object)MapToolController.instance).Field("mapToggled").GetValue<bool>(); } catch { flag = false; } } return SemiFunc.InputHold((InputKey)8) || flag; } private static bool IsRunActive() { if (SemiFunc.RunIsLevel()) { return (Object)(object)RoundDirector.instance != (Object)null; } return false; } private static bool ShouldRefreshSnapshot(bool mapOpen, float now) { float num = Math.Max(0.1f, Configuration.RefreshIntervalSeconds.Value); if (!snapshotDirty && !fullResyncRequested && mapOpen == lastMapOpen) { return now - lastSnapshotRefreshTime >= num; } return true; } private static int GetRoundDirectorInt(string fieldName) { if (!((Object)(object)RoundDirector.instance == (Object)null)) { return Traverse.Create((object)RoundDirector.instance).Field(fieldName).GetValue<int>(); } return 0; } private static bool GetRoundDirectorBool(string fieldName) { if ((Object)(object)RoundDirector.instance != (Object)null) { return Traverse.Create((object)RoundDirector.instance).Field(fieldName).GetValue<bool>(); } return false; } private static void ComputeBreakdownValues(out float mapValue, out float cartsValue, out float cartsValueOutsideExtraction, out float haulerValue, out float haulerValueOutsideExtraction, out float extractionValue) { mapValue = Mathf.Max(0f, totalValue); ComputeHaulerValues(out haulerValue, out haulerValueOutsideExtraction); extractionValue = Mathf.Max(0f, (float)GetRoundDirectorInt("currentHaul")); ComputeCartValues(out cartsValue, out cartsValueOutsideExtraction); } private static void ComputeCartValues(out float cartsValue, out float cartsValueOutsideExtraction) { cartsValue = 0f; cartsValueOutsideExtraction = 0f; if (trackedCarts.Count == 0) { return; } List<PhysGrabCart> list = new List<PhysGrabCart>(); foreach (PhysGrabCart trackedCart in trackedCarts) { int value; if ((Object)(object)trackedCart == (Object)null) { list.Add(trackedCart); } else if (TryGetCartHaulCurrent(trackedCart, out value)) { cartsValue += value; if (!IsRoomVolumeCheckInExtraction(((Component)trackedCart).GetComponent<RoomVolumeCheck>())) { cartsValueOutsideExtraction += value; } } } if (list.Count > 0) { for (int i = 0; i < list.Count; i++) { trackedCarts.Remove(list[i]); } } } private static bool IsRoomVolumeCheckInExtraction(RoomVolumeCheck? roomVolumeCheck) { if ((Object)(object)roomVolumeCheck == (Object)null || roomVolumeCheckInExtractionPointField == null) { return false; } object value = roomVolumeCheckInExtractionPointField.GetValue(roomVolumeCheck); bool flag = default(bool); int num; if (value is bool) { flag = (bool)value; num = 1; } else { num = 0; } return (byte)((uint)num & (flag ? 1u : 0u)) != 0; } private static void ComputeHaulerValues(out float haulerValue, out float haulerValueOutsideExtraction) { haulerValue = 0f; haulerValueOutsideExtraction = 0f; if (trackedValuableBoxes.Count == 0) { return; } HashSet<ItemValuableBox> hashSet = null; if ((Object)(object)RoundDirector.instance != (Object)null && RoundDirector.instance.valuableBoxHaulList != null && RoundDirector.instance.valuableBoxHaulList.Count > 0) { hashSet = new HashSet<ItemValuableBox>(RoundDirector.instance.valuableBoxHaulList); } foreach (KeyValuePair<ItemValuableBox, float> trackedValuableBox in trackedValuableBoxes) { ItemValuableBox key = trackedValuableBox.Key; if (!((Object)(object)key == (Object)null)) { haulerValue += trackedValuableBox.Value; if (hashSet == null || !hashSet.Contains(key)) { haulerValueOutsideExtraction += trackedValuableBox.Value; } } } } private static bool TryGetCartHaulCurrent(PhysGrabCart cart, out int value) { value = 0; if ((Object)(object)cart == (Object)null) { return false; } if (cartHaulCurrentField == null) { LogMissingCartFieldWarning("haulCurrent"); return false; } object value2 = cartHaulCurrentField.GetValue(cart); if (value2 is int num) { value = num; return true; } if (value2 is IConvertible value3) { try { value = Convert.ToInt32(value3); return true; } catch { return false; } } return false; } private static void LogMissingCartFieldWarning(string fieldName) { if (!cartFieldWarningLogged) { cartFieldWarningLogged = true; Logger.LogWarning((object)("Unable to access PhysGrabCart." + fieldName + ". Cart values may be inaccurate.")); } } public static void LogDebug(string message) { if (Configuration.DebugLogging.Value) { Logger.LogDebug((object)message); } } public static float GetValuableCurrent(ValuableObject vo) { return TryGetFloat(vo, "dollarValueCurrent", "dollarValue", "value", "Value", "currentValue", "CurrentValue"); } private static float TryGetFloat(object obj, params string[] names) { if (obj == null) { return 0f; } Type type = obj.GetType(); for (int i = 0; i < names.Length; i++) { MemberInfo cachedMember = GetCachedMember(type, names[i]); if (!(cachedMember == null)) { object value = ((cachedMember is FieldInfo fieldInfo) ? fieldInfo.GetValue(obj) : ((!(cachedMember is PropertyInfo propertyInfo)) ? null : propertyInfo.GetValue(obj, null))); if (TryConvertToFloat(value, out var result)) { return result; } } } return 0f; } private static MemberInfo? GetCachedMember(Type type, string name) { if (!cachedMembers.TryGetValue(type, out Dictionary<string, MemberInfo> value)) { value = new Dictionary<string, MemberInfo>(); cachedMembers[type] = value; } if (value.TryGetValue(name, out var value2)) { return value2; } object obj = ((object)AccessTools.Field(type, name)) ?? ((object)AccessTools.Property(type, name)); return value[name] = (MemberInfo)obj; } private static bool TryConvertToFloat(object? value, out float result) { if (value == null) { result = 0f; return false; } if (value is float num) { result = num; return true; } if (value is int num2) { result = num2; return true; } if (value is double num3) { result = (float)num3; return true; } if (value is long num4) { result = num4; return true; } if (value is IConvertible) { try { result = Convert.ToSingle(value); return true; } catch { result = 0f; return false; } } result = 0f; return false; } } public struct ValueBreakdownSnapshot : IEquatable<ValueBreakdownSnapshot> { public bool IsVisible; public bool ShowCompactHud; public bool ShowMapPanel; public bool MapOpen; public bool HideAfterCompletion; public bool UseRemainingForPrimary; public float MapValue; public float CartsValue; public float HaulerValue; public float RemainingValue; public float PrimaryValue { get { if (!UseRemainingForPrimary) { return MapValue; } return RemainingValue; } } public string PrimaryLabel { get { if (!UseRemainingForPrimary) { return "Map"; } return "Remaining"; } } public bool Equals(ValueBreakdownSnapshot other) { if (IsVisible == other.IsVisible && ShowCompactHud == other.ShowCompactHud && ShowMapPanel == other.ShowMapPanel && MapOpen == other.MapOpen && HideAfterCompletion == other.HideAfterCompletion && UseRemainingForPrimary == other.UseRemainingForPrimary && Math.Abs(MapValue - other.MapValue) < 0.01f && Math.Abs(CartsValue - other.CartsValue) < 0.01f && Math.Abs(HaulerValue - other.HaulerValue) < 0.01f) { return Math.Abs(RemainingValue - other.RemainingValue) < 0.01f; } return false; } public override bool Equals(object obj) { if (obj is ValueBreakdownSnapshot other) { return Equals(other); } return false; } public override int GetHashCode() { return (((((((((((((((((IsVisible.GetHashCode() * 397) ^ ShowCompactHud.GetHashCode()) * 397) ^ ShowMapPanel.GetHashCode()) * 397) ^ MapOpen.GetHashCode()) * 397) ^ HideAfterCompletion.GetHashCode()) * 397) ^ UseRemainingForPrimary.GetHashCode()) * 397) ^ MapValue.GetHashCode()) * 397) ^ CartsValue.GetHashCode()) * 397) ^ HaulerValue.GetHashCode()) * 397) ^ RemainingValue.GetHashCode(); } } } namespace MapValueTracker.Patches { [HarmonyPatch(typeof(ItemValuableBox))] internal static class ItemValuableBoxPatches { [HarmonyPatch("Start")] [HarmonyPostfix] private static void StartPostfix(ItemValuableBox __instance) { if (MapValueTracker.IsRuntimeEnabled()) { MapValueTracker.RegisterOrRefreshValuableBox(__instance); } } [HarmonyPatch("UpdateValueRPC")] [HarmonyPostfix] private static void UpdateValueRpcPostfix(ItemValuableBox __instance) { if (MapValueTracker.IsRuntimeEnabled()) { MapValueTracker.RegisterOrRefreshValuableBox(__instance); } } [HarmonyPatch("ExplodeValuableBox")] [HarmonyPostfix] private static void ExplodeValuableBoxPostfix(ItemValuableBox __instance) { if (MapValueTracker.IsRuntimeEnabled()) { MapValueTracker.RegisterOrRefreshValuableBox(__instance); } } [HarmonyPatch("OnDisable")] [HarmonyPostfix] private static void OnDisablePostfix(ItemValuableBox __instance) { if (MapValueTracker.IsRuntimeEnabled()) { MapValueTracker.RegisterOrRefreshValuableBox(__instance); } } } [HarmonyPatch(typeof(LevelGenerator))] internal static class LevelGeneratorPatches { [HarmonyPatch("StartRoomGeneration")] [HarmonyPrefix] private static void StartRoomGenerationPrefix() { MapValueTracker.Logger.LogDebug((object)"Resetting value tracker for a new level."); MapValueTracker.ResetValues(); MapValueTracker.Logger.LogDebug((object)("Tracker reset complete. Total value: " + MapValueTracker.totalValue)); } [HarmonyPatch("GenerateDone")] [HarmonyPrefix] private static void GenerateDonePrefix() { if (MapValueTracker.IsRuntimeEnabled()) { MapValueTracker.CheckForItems(); } MapValueTracker.Logger.LogDebug((object)("Level generation finished. Total value: " + MapValueTracker.totalValue)); } } [HarmonyPatch(typeof(PhysGrabCart))] internal static class PhysGrabCartPatches { [HarmonyPatch("Start")] [HarmonyPostfix] private static void StartPostfix(PhysGrabCart __instance) { MapValueTracker.RegisterCart(__instance); } [HarmonyPatch("ObjectsInCart")] [HarmonyPostfix] private static void ObjectsInCartPostfix() { if (SemiFunc.RunIsLevel() && MapValueTracker.IsRuntimeEnabled()) { MapValueTracker.MarkDirty(); } } } [HarmonyPatch(typeof(PhysGrabObjectImpactDetector))] internal static class PhysGrabObjectImpactDetectorPatches { [HarmonyPatch("BreakRPC")] [HarmonyPostfix] private static void BreakRpcPostfix(float valueLost, PhysGrabObjectImpactDetector? __instance, bool _loseValue) { if (_loseValue && MapValueTracker.IsRuntimeEnabled()) { MapValueTracker.RegisterOrRefreshValuable((__instance != null) ? ((Component)__instance).GetComponent<ValuableObject>() : null); MapValueTracker.Logger.LogDebug((object)("Updated tracked value after break. Lost: " + valueLost + ", total: " + MapValueTracker.totalValue)); } } [HarmonyPatch(typeof(PhysGrabObject), "DestroyPhysGrabObjectRPC")] [HarmonyPostfix] private static void DestroyPhysGrabObjectPostfix(PhysGrabObject __instance) { if (SemiFunc.RunIsLevel() && MapValueTracker.IsRuntimeEnabled()) { PhysGrabCart component = ((Component)__instance).GetComponent<PhysGrabCart>(); if ((Object)(object)component != (Object)null) { MapValueTracker.UnregisterCart(component); } ValuableObject component2 = ((Component)__instance).GetComponent<ValuableObject>(); if (!((Object)(object)component2 == (Object)null)) { float valuableCurrent = MapValueTracker.GetValuableCurrent(component2); MapValueTracker.UnregisterValuable(component2); MapValueTracker.Logger.LogDebug((object)("Removed destroyed valuable from tracking: " + ((Object)component2).name + " (" + valuableCurrent + "). Total: " + MapValueTracker.totalValue)); } } } } [HarmonyPatch(typeof(RoundDirector))] public static class RoundDirectorPatches { private const float CompactHudWidth = 220f; private const float CompactHudHeight = 38f; private const float CompactHudFontSize = 21f; private const float CompactHudLineSpacing = -10f; private const float OpenPanelFontSize = 16f; private const float OpenPanelLineSpacing = -6f; private static readonly Color HudValueColor = new Color(0.7882f, 0.9137f, 0.902f, 1f); private static readonly Color HudLabelColor = new Color(0.7882f, 0.9137f, 0.902f, 0.86f); private static readonly Color HudPanelColor = new Color(0.035f, 0.05f, 0.06f, 0.3f); private static TextMeshProUGUI? openLabelsText; private static TextMeshProUGUI? openValuesText; private static GameObject? openPanel; private static Image? openPanelImage; private static ValueBreakdownSnapshot lastRenderedSnapshot; private static bool hasRenderedSnapshot; private static string lastOpenLabels = string.Empty; private static string lastOpenValues = string.Empty; private static string lastClosedMapText = string.Empty; private const float OpenPanelPaddingX = 10f; private const float OpenPanelPaddingY = 8f; private const float OpenPanelColumnGap = 16f; private static void SetContainerCoordinates(RectTransform rect) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //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) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) rect.anchorMin = Vector2.zero; rect.anchorMax = Vector2.one; rect.pivot = new Vector2(0.5f, 0.5f); rect.anchoredPosition = Vector2.zero; rect.offsetMin = Vector2.zero; rect.offsetMax = Vector2.zero; } private static void SetOverlayCoordinates(RectTransform rect, Vector2 position) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: 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_0040: Unknown result type (might be due to invalid IL or missing references) rect.anchorMin = new Vector2(1f, 0f); rect.anchorMax = new Vector2(1f, 0f); rect.pivot = new Vector2(1f, 1f); rect.anchoredPosition = position; } private static void ResetHudReferences() { MapValueTracker.textInstance = null; MapValueTracker.valueText = null; openPanel = null; openPanelImage = null; openLabelsText = null; openValuesText = null; hasRenderedSnapshot = false; lastOpenLabels = string.Empty; lastOpenValues = string.Empty; lastClosedMapText = string.Empty; } private static bool EnsureHud() { //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Expected O, but got Unknown //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Expected O, but got Unknown //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0222: Unknown result type (might be due to invalid IL or missing references) //IL_0241: Unknown result type (might be due to invalid IL or missing references) //IL_026f: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)MapValueTracker.textInstance) && Object.op_Implicit((Object)(object)MapValueTracker.valueText) && Object.op_Implicit((Object)(object)openPanel) && Object.op_Implicit((Object)(object)openPanelImage) && Object.op_Implicit((Object)(object)openLabelsText) && Object.op_Implicit((Object)(object)openValuesText)) { return true; } ResetHudReferences(); GameObject val = GameObject.Find("Game Hud"); GameObject val2 = GameObject.Find("Tax Haul"); if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null) { return false; } TMP_Text component = val2.GetComponent<TMP_Text>(); if ((Object)(object)component == (Object)null) { return false; } MapValueTracker.textInstance = new GameObject("Value HUD", new Type[1] { typeof(RectTransform) }); MapValueTracker.textInstance.SetActive(false); MapValueTracker.textInstance.transform.SetParent(val.transform, false); SetContainerCoordinates(MapValueTracker.textInstance.GetComponent<RectTransform>()); MapValueTracker.valueText = CreatePanelText("Compact Value Text", component, MapValueTracker.textInstance.transform, (TextAlignmentOptions)260, HudValueColor, 0.24f, 0.18f); RectTransform rectTransform = ((TMP_Text)MapValueTracker.valueText).rectTransform; SetOverlayCoordinates(rectTransform, Configuration.GetCompactOffset()); rectTransform.sizeDelta = new Vector2(220f, 38f); ((TMP_Text)MapValueTracker.valueText).fontSize = 21f; ((TMP_Text)MapValueTracker.valueText).lineSpacing = -10f; openPanel = new GameObject("Open Map Panel", new Type[2] { typeof(RectTransform), typeof(CanvasRenderer) }); openPanel.transform.SetParent(MapValueTracker.textInstance.transform, false); openPanelImage = openPanel.AddComponent<Image>(); ((Graphic)openPanelImage).color = HudPanelColor; ((Graphic)openPanelImage).raycastTarget = false; RectTransform rectTransform2 = ((Graphic)openPanelImage).rectTransform; rectTransform2.anchorMin = new Vector2(1f, 0f); rectTransform2.anchorMax = new Vector2(1f, 0f); rectTransform2.pivot = new Vector2(1f, 0f); rectTransform2.anchoredPosition = Configuration.GetOpenMapOffset(); rectTransform2.sizeDelta = new Vector2(178f, 86f); openLabelsText = CreatePanelText("Open Map Labels", component, openPanel.transform, (TextAlignmentOptions)257, HudLabelColor, 0.2f, 0.16f); openValuesText = CreatePanelText("Open Map Values", component, openPanel.transform, (TextAlignmentOptions)260, HudValueColor, 0.2f, 0.16f); MapValueTracker.LogDebug("Created value HUD."); return true; } private static Material CreateHudMaterial(Material sourceMaterial, float underlayDilate, float underlaySoftness) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_002e: Unknown result type (might be due to invalid IL or missing references) Material val = new Material(sourceMaterial); if (val.HasProperty(ShaderUtilities.ID_UnderlayColor)) { val.SetColor(ShaderUtilities.ID_UnderlayColor, new Color(0f, 0f, 0f, 0.72f)); } if (val.HasProperty(ShaderUtilities.ID_UnderlayOffsetX)) { val.SetFloat(ShaderUtilities.ID_UnderlayOffsetX, 0f); } if (val.HasProperty(ShaderUtilities.ID_UnderlayOffsetY)) { val.SetFloat(ShaderUtilities.ID_UnderlayOffsetY, -0.18f); } if (val.HasProperty(ShaderUtilities.ID_UnderlayDilate)) { val.SetFloat(ShaderUtilities.ID_UnderlayDilate, underlayDilate); } if (val.HasProperty(ShaderUtilities.ID_UnderlaySoftness)) { val.SetFloat(ShaderUtilities.ID_UnderlaySoftness, underlaySoftness); } return val; } private static TextMeshProUGUI CreatePanelText(string name, TMP_Text haulText, Transform parent, TextAlignmentOptions alignment, Color color, float underlayDilate, float underlaySoftness) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Invalid comparison between Unknown and I4 GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) }); val.transform.SetParent(parent, false); TextMeshProUGUI obj = val.AddComponent<TextMeshProUGUI>(); ((TMP_Text)obj).font = haulText.font; ((TMP_Text)obj).fontSharedMaterial = CreateHudMaterial(haulText.fontSharedMaterial, underlayDilate, underlaySoftness); ((Graphic)obj).color = color; ((TMP_Text)obj).fontSize = 16f; ((TMP_Text)obj).enableWordWrapping = false; ((TMP_Text)obj).alignment = alignment; ((TMP_Text)obj).horizontalAlignment = (HorizontalAlignmentOptions)(((int)alignment != 260) ? 1 : 4); ((TMP_Text)obj).verticalAlignment = (VerticalAlignmentOptions)256; ((TMP_Text)obj).overflowMode = (TextOverflowModes)0; ((Graphic)obj).raycastTarget = false; ((TMP_Text)obj).richText = true; ((TMP_Text)obj).lineSpacing = -6f; return obj; } private static string ColorTag(Color color) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return ColorUtility.ToHtmlStringRGBA(color); } private static string FormatLabelValueLine(string label, string value) { //IL_0000: 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) string text = ColorTag(HudLabelColor); string text2 = ColorTag(HudValueColor); return "<size=76%><color=#" + text + ">" + label.ToUpperInvariant() + "</color></size> <color=#" + text2 + ">" + value + "</color>"; } private static string FormatCurrency(float value) { return "$" + value.ToString("N0"); } private static string BuildOpenMapLabels() { if (Configuration.IsFullBreakdown()) { return "MAP\nCARTS\nHAULER\nREMAINING"; } return "MAP\nREMAINING"; } private static string BuildOpenMapValues(ValueBreakdownSnapshot snapshot) { if (Configuration.IsFullBreakdown()) { return string.Join("\n", FormatCurrency(snapshot.MapValue), FormatCurrency(snapshot.CartsValue), FormatCurrency(snapshot.HaulerValue), FormatCurrency(snapshot.RemainingValue)); } return string.Join("\n", FormatCurrency(snapshot.MapValue), FormatCurrency(snapshot.RemainingValue)); } private static string BuildClosedMapText(ValueBreakdownSnapshot snapshot) { return FormatLabelValueLine(snapshot.PrimaryLabel, FormatCurrency(snapshot.PrimaryValue)); } private static void UpdateOpenPanelLayout() { //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)openPanelImage == (Object)null) && !((Object)(object)openLabelsText == (Object)null) && !((Object)(object)openValuesText == (Object)null)) { ((TMP_Text)openLabelsText).ForceMeshUpdate(false, false); ((TMP_Text)openValuesText).ForceMeshUpdate(false, false); float num = Mathf.Ceil(((TMP_Text)openLabelsText).preferredWidth); float num2 = Mathf.Ceil(((TMP_Text)openValuesText).preferredWidth); float num3 = Mathf.Ceil(((TMP_Text)openLabelsText).preferredHeight); float num4 = Mathf.Ceil(((TMP_Text)openValuesText).preferredHeight); float num5 = Mathf.Max(num3, num4); ((Graphic)openPanelImage).rectTransform.sizeDelta = new Vector2(20f + num + 16f + num2, 16f + num5); RectTransform rectTransform = ((TMP_Text)openLabelsText).rectTransform; rectTransform.anchorMin = new Vector2(0f, 1f); rectTransform.anchorMax = new Vector2(0f, 1f); rectTransform.pivot = new Vector2(0f, 1f); rectTransform.anchoredPosition = new Vector2(10f, -8f); rectTransform.sizeDelta = new Vector2(num, num5); RectTransform rectTransform2 = ((TMP_Text)openValuesText).rectTransform; rectTransform2.anchorMin = new Vector2(1f, 1f); rectTransform2.anchorMax = new Vector2(1f, 1f); rectTransform2.pivot = new Vector2(1f, 1f); rectTransform2.anchoredPosition = new Vector2(-10f, -8f); rectTransform2.sizeDelta = new Vector2(num2, num5); } } private static void HideHud() { GameObject textInstance = MapValueTracker.textInstance; if ((Object)(object)textInstance != (Object)null) { textInstance.SetActive(false); } else { ResetHudReferences(); } hasRenderedSnapshot = false; } private static void UpdateCompactHud(ValueBreakdownSnapshot snapshot) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)MapValueTracker.valueText == (Object)null)) { SetOverlayCoordinates(((TMP_Text)MapValueTracker.valueText).rectTransform, Configuration.GetCompactOffset()); ((TMP_Text)MapValueTracker.valueText).fontSize = 21f; string text = BuildClosedMapText(snapshot); if (!string.Equals(lastClosedMapText, text)) { ((TMP_Text)MapValueTracker.valueText).SetText(text, true); lastClosedMapText = text; } } } private static void UpdateOpenMapHud(ValueBreakdownSnapshot snapshot) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)openPanelImage == (Object)null) && !((Object)(object)openLabelsText == (Object)null) && !((Object)(object)openValuesText == (Object)null)) { SetOverlayCoordinates(((Graphic)openPanelImage).rectTransform, Configuration.GetOpenMapOffset()); string text = BuildOpenMapLabels(); string text2 = BuildOpenMapValues(snapshot); if (!string.Equals(lastOpenLabels, text) || !string.Equals(lastOpenValues, text2)) { ((TMP_Text)openLabelsText).SetText(text, true); ((TMP_Text)openValuesText).SetText(text2, true); lastOpenLabels = text; lastOpenValues = text2; UpdateOpenPanelLayout(); } } } [HarmonyPatch("ExtractionCompleted")] [HarmonyPostfix] public static void ExtractionComplete() { if (SemiFunc.RunIsLevel() && MapValueTracker.IsRuntimeEnabled()) { MapValueTracker.Logger.LogDebug((object)"Extraction completed."); MapValueTracker.CheckForItems(); MapValueTracker.Logger.LogDebug((object)("Rebuilt tracked values after extraction. Total: " + MapValueTracker.totalValue)); } } [HarmonyPatch("HaulCheck")] [HarmonyPostfix] public static void HaulCheckPostfix() { if (MapValueTracker.IsRuntimeEnabled()) { MapValueTracker.MarkDirty(); } } [HarmonyPatch("ExtractionCompletedAllRPC")] [HarmonyPostfix] public static void ExtractionCompletedAllPostfix() { if (MapValueTracker.IsRuntimeEnabled()) { MapValueTracker.MarkDirty(); } } [HarmonyPatch("Update")] [HarmonyPostfix] public static void UpdateHud() { if (!MapValueTracker.IsRuntimeEnabled() || !SemiFunc.RunIsLevel() || (Object)(object)RoundDirector.instance == (Object)null) { HideHud(); } else { if (!EnsureHud()) { return; } ValueBreakdownSnapshot snapshot = MapValueTracker.GetSnapshot(); if (!snapshot.ShowCompactHud && !snapshot.ShowMapPanel) { HideHud(); return; } bool mapOpen = snapshot.MapOpen; if ((Object)(object)MapValueTracker.valueText == (Object)null || (Object)(object)openPanel == (Object)null || (Object)(object)openPanelImage == (Object)null || (Object)(object)openLabelsText == (Object)null || (Object)(object)openValuesText == (Object)null) { return; } openPanel.SetActive(mapOpen); ((Component)MapValueTracker.valueText).gameObject.SetActive(!mapOpen); bool flag = !hasRenderedSnapshot || !snapshot.Equals(lastRenderedSnapshot); if (mapOpen) { if (flag || !openPanel.activeSelf) { UpdateOpenMapHud(snapshot); } } else if (flag || !((Component)MapValueTracker.valueText).gameObject.activeSelf) { UpdateCompactHud(snapshot); } GameObject? textInstance = MapValueTracker.textInstance; if (textInstance != null) { textInstance.SetActive(true); } lastRenderedSnapshot = snapshot; hasRenderedSnapshot = true; } } } [HarmonyPatch(typeof(ValuableObject))] internal static class ValuableObjectPatches { [HarmonyPatch("DollarValueSetRPC")] [HarmonyPostfix] private static void DollarValueSetRpcPostfix(ValuableObject __instance, float value) { if (MapValueTracker.IsRuntimeEnabled()) { LogValueCreated(((Object)__instance).name, value); MapValueTracker.RegisterOrRefreshValuable(__instance); LogTotalValue("Total value after setup: "); } } [HarmonyPatch("DollarValueSetLogic")] [HarmonyPostfix] private static void DollarValueSetLogicPostfix(ValuableObject __instance) { if (SemiFunc.IsMasterClientOrSingleplayer() && MapValueTracker.IsRuntimeEnabled()) { float valuableCurrent = MapValueTracker.GetValuableCurrent(__instance); LogValueCreated(((Object)__instance).name, valuableCurrent); MapValueTracker.RegisterOrRefreshValuable(__instance); LogTotalValue("Total value after setup: "); } } [HarmonyPatch("AddToDollarHaulList")] [HarmonyPostfix] private static void AddToDollarHaulListDirectPostfix(ValuableObject __instance) { if (MapValueTracker.IsRuntimeEnabled()) { MapValueTracker.MarkDirty(); } } [HarmonyPatch("AddToDollarHaulListRPC")] [HarmonyPostfix] private static void AddToDollarHaulListPostfix(ValuableObject __instance) { if (MapValueTracker.IsRuntimeEnabled()) { MapValueTracker.MarkDirty(); } } [HarmonyPatch("RemoveFromDollarHaulList")] [HarmonyPostfix] private static void RemoveFromDollarHaulListDirectPostfix(ValuableObject __instance) { if (MapValueTracker.IsRuntimeEnabled()) { MapValueTracker.MarkDirty(); } } [HarmonyPatch("RemoveFromDollarHaulListRPC")] [HarmonyPostfix] private static void RemoveFromDollarHaulListPostfix(ValuableObject __instance) { if (MapValueTracker.IsRuntimeEnabled()) { MapValueTracker.MarkDirty(); } } private static void LogValueCreated(string objectName, float value) { MapValueTracker.Logger.LogDebug((object)("Tracking valuable: " + objectName + " (" + value + ")")); } private static void LogTotalValue(string prefix) { MapValueTracker.Logger.LogDebug((object)(prefix + MapValueTracker.totalValue)); } } } namespace MapValueTracker.Config { internal static class Configuration { private const string HideFromRepoConfig = "HideFromREPOConfig"; private static readonly Vector2 DefaultHudOffset = new Vector2(-10f, 125f); public static ConfigEntry<bool> AlwaysOn = null; public static ConfigEntry<string> ClosedMapDisplayMode = null; public static ConfigEntry<string> OpenMapDisplayMode = null; public static ConfigEntry<bool> SyncHudPositions = null; public static ConfigEntry<string> UiPositionPreset = null; public static ConfigEntry<string> CustomOffsetX = null; public static ConfigEntry<string> CustomOffsetY = null; public static ConfigEntry<string> OpenMapPositionPreset = null; public static ConfigEntry<string> OpenMapCustomOffsetX = null; public static ConfigEntry<string> OpenMapCustomOffsetY = null; public static ConfigEntry<bool> HideAfterFinalExtraction = null; public static ConfigEntry<float> RefreshIntervalSeconds = null; public static ConfigEntry<bool> RuntimeEnabled = null; public static ConfigEntry<bool> DebugLogging = null; public static void Init(ConfigFile config) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Expected O, but got Unknown //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Expected O, but got Unknown //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Expected O, but got Unknown //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Expected O, but got Unknown //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Expected O, but got Unknown //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Expected O, but got Unknown //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Expected O, but got Unknown //IL_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Expected O, but got Unknown //IL_0238: Unknown result type (might be due to invalid IL or missing references) //IL_0242: Expected O, but got Unknown //IL_025e: Unknown result type (might be due to invalid IL or missing references) //IL_0268: Expected O, but got Unknown //IL_0296: Unknown result type (might be due to invalid IL or missing references) //IL_02a0: Expected O, but got Unknown //IL_02bc: Unknown result type (might be due to invalid IL or missing references) //IL_02c6: Expected O, but got Unknown //IL_02eb: Unknown result type (might be due to invalid IL or missing references) //IL_02f5: Expected O, but got Unknown config.SaveOnConfigSet = false; AlwaysOn = config.Bind<bool>("Closed Map HUD", "Show Closed Map HUD", true, new ConfigDescription("Show the compact valuables readout while the map is closed.", (AcceptableValueBase)null, Array.Empty<object>())); ClosedMapDisplayMode = config.Bind<string>("Closed Map HUD", "Closed Map Display", "Remaining", new ConfigDescription("Choose which value the closed-map HUD shows.", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[2] { "Map", "Remaining" }), Array.Empty<object>())); OpenMapDisplayMode = config.Bind<string>("Open Map HUD", "Open Map Display", "Summary", new ConfigDescription("Choose whether the map-open HUD shows a summary or the full breakdown.", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[2] { "Summary", "FullBreakdown" }), Array.Empty<object>())); SyncHudPositions = config.Bind<bool>("Open Map HUD", "Match Closed Map Position", true, new ConfigDescription("Use the same position for the open-map HUD as the closed-map HUD.", (AcceptableValueBase)null, Array.Empty<object>())); UiPositionPreset = config.Bind<string>("Closed Map Position", "Position Preset", "Default", new ConfigDescription("Choose the closed-map HUD position.", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[2] { "Default", "Custom" }), Array.Empty<object>())); CustomOffsetX = config.Bind<string>("Closed Map Position", "Custom Offset X", DefaultHudOffset.x.ToString(CultureInfo.InvariantCulture), new ConfigDescription("Horizontal offset in pixels for the closed-map HUD. Negative moves left, positive moves right.", (AcceptableValueBase)null, Array.Empty<object>())); CustomOffsetY = config.Bind<string>("Closed Map Position", "Custom Offset Y", DefaultHudOffset.y.ToString(CultureInfo.InvariantCulture), new ConfigDescription("Vertical offset in pixels for the closed-map HUD. Positive moves up, negative moves down.", (AcceptableValueBase)null, Array.Empty<object>())); OpenMapPositionPreset = config.Bind<string>("Open Map Position", "Position Preset", "Default", new ConfigDescription("Choose the open-map HUD position when Match Closed Map Position is off.", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[2] { "Default", "Custom" }), Array.Empty<object>())); OpenMapCustomOffsetX = config.Bind<string>("Open Map Position", "Custom Offset X", DefaultHudOffset.x.ToString(CultureInfo.InvariantCulture), new ConfigDescription("Horizontal offset in pixels for the open-map HUD when Match Closed Map Position is off.", (AcceptableValueBase)null, Array.Empty<object>())); OpenMapCustomOffsetY = config.Bind<string>("Open Map Position", "Custom Offset Y", DefaultHudOffset.y.ToString(CultureInfo.InvariantCulture), new ConfigDescription("Vertical offset in pixels for the open-map HUD when Match Closed Map Position is off.", (AcceptableValueBase)null, Array.Empty<object>())); HideAfterFinalExtraction = config.Bind<bool>("Advanced", "Hide After Final Extraction", true, new ConfigDescription("Hide the valuables HUD after the last extraction is finished.", (AcceptableValueBase)null, Array.Empty<object>())); RefreshIntervalSeconds = config.Bind<float>("Advanced", "Refresh Interval Seconds", 1f, new ConfigDescription("How often the valuables totals refresh during a run.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 5f), Array.Empty<object>())); RuntimeEnabled = config.Bind<bool>("Debug", "Disable", true, new ConfigDescription("Enable or disable all Map Value Tracker Plus logic.", (AcceptableValueBase)null, Array.Empty<object>())); DebugLogging = config.Bind<bool>("Internal", "Debug Logging", false, new ConfigDescription("Enable extra debug logging for HUD creation and placement.", (AcceptableValueBase)null, new object[1] { "HideFromREPOConfig" })); config.Save(); config.SaveOnConfigSet = true; } public static bool IsClosedModeRemaining() { return ClosedMapDisplayMode.Value == "Remaining"; } public static bool IsFullBreakdown() { return OpenMapDisplayMode.Value == "FullBreakdown"; } public static Vector2 GetCompactOffset() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) return ResolveOffset(UiPositionPreset.Value, CustomOffsetX.Value, CustomOffsetY.Value); } public static Vector2 GetOpenMapOffset() { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) if (SyncHudPositions.Value) { return GetCompactOffset(); } return ResolveOffset(OpenMapPositionPreset.Value, OpenMapCustomOffsetX.Value, OpenMapCustomOffsetY.Value); } private static Vector2 ResolveOffset(string preset, string xText, string yText) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) if (preset != "Custom") { return DefaultHudOffset; } return new Vector2(ParseCoordinate(xText, DefaultHudOffset.x), ParseCoordinate(yText, DefaultHudOffset.y)); } private static float ParseCoordinate(string value, float fallback) { if (!float.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out var result)) { return fallback; } return result; } } }