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.1
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+ebb8de5e0fbc5f57240db951782b2cee1bb8ce7d")] [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.1")] 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.1"; private const float SnapshotRefreshResetTime = -100000f; 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? cartItemsInCartField = AccessTools.Field(typeof(PhysGrabCart), "itemsInCart"); 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 HashSet<ValuableObject> extractionValuables = new HashSet<ValuableObject>(); private static readonly HashSet<PhysGrabCart> trackedCarts = new HashSet<PhysGrabCart>(); private static bool cartFieldWarningLogged; private static bool snapshotDirty = true; private static bool forceBreakdownRefresh = 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(forceBreakdown: true); } public static bool IsRuntimeEnabled() { return Configuration.RuntimeEnabled.Value; } public static bool IsTrackingActive() { if (IsRuntimeEnabled()) { return IsRunActive(); } return false; } public static void HandleRuntimeEnabledChanged() { if (IsRuntimeEnabled()) { RequestFullResync(); return; } currentSnapshot = default(ValueBreakdownSnapshot); snapshotDirty = false; forceBreakdownRefresh = false; lastSnapshotRefreshTime = -100000f; } public static void ResetValues() { trackedValuables.Clear(); extractionValuables.Clear(); trackedCarts.Clear(); totalValue = 0f; currentSnapshot = default(ValueBreakdownSnapshot); RequestFullResync(); Logger.LogDebug((object)"Reset tracker state."); } public static void CheckForItems(ValuableObject? ignoreThis = null) { RebuildTrackedState(ignoreThis); } public static void RequestFullResync() { fullResyncRequested = true; MarkDirty(forceBreakdown: true); } public static void MarkDirty(bool forceBreakdown = false) { snapshotDirty = true; if (forceBreakdown) { forceBreakdownRefresh = true; lastSnapshotRefreshTime = -100000f; } } 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()) { float valuableCurrent = GetValuableCurrent(valuable); if (trackedValuables.TryGetValue(valuable, out var value)) { totalValue += valuableCurrent - value; trackedValuables[valuable] = valuableCurrent; } else { trackedValuables[valuable] = valuableCurrent; totalValue += valuableCurrent; } MarkDirty(forceBreakdown: true); } } public static void UnregisterValuable(ValuableObject? valuable) { if (!((Object)(object)valuable == (Object)null)) { if (trackedValuables.TryGetValue(valuable, out var value)) { trackedValuables.Remove(valuable); totalValue -= value; } extractionValuables.Remove(valuable); MarkDirty(forceBreakdown: true); } } public static void AddExtractionValuable(ValuableObject? valuable) { if (!((Object)(object)valuable == (Object)null) && IsRuntimeEnabled()) { extractionValuables.Add(valuable); RegisterOrRefreshValuable(valuable); MarkDirty(forceBreakdown: true); } } public static void RemoveExtractionValuable(ValuableObject? valuable) { if (!((Object)(object)valuable == (Object)null)) { extractionValuables.Remove(valuable); RegisterOrRefreshValuable(valuable); MarkDirty(forceBreakdown: true); } } public static void SyncExtractionState() { extractionValuables.Clear(); if ((Object)(object)RoundDirector.instance == (Object)null || RoundDirector.instance.dollarHaulList == null) { return; } List<GameObject> dollarHaulList = RoundDirector.instance.dollarHaulList; for (int i = 0; i < dollarHaulList.Count; i++) { GameObject val = dollarHaulList[i]; if (!((Object)(object)val == (Object)null)) { ValuableObject component = val.GetComponent<ValuableObject>(); if (!((Object)(object)component == (Object)null)) { extractionValuables.Add(component); RegisterOrRefreshValuable(component); } } } } internal static ValueBreakdownSnapshot GetSnapshot() { if (!IsRuntimeEnabled()) { return default(ValueBreakdownSnapshot); } bool mapOpen = IsMapOpen(); float unscaledTime = Time.unscaledTime; if (ShouldRefreshSnapshot(mapOpen, unscaledTime)) { EnsureSynchronizedState(); currentSnapshot = BuildSnapshot(mapOpen); lastSnapshotRefreshTime = unscaledTime; snapshotDirty = false; forceBreakdownRefresh = false; } lastMapOpen = mapOpen; return currentSnapshot; } private static void EnsureSynchronizedState() { if (IsRunActive()) { if (fullResyncRequested || trackedValuables.Count == 0) { RebuildTrackedState(); } else { CleanupTrackedCollections(); } } } private static void RebuildTrackedState(ValuableObject? ignoreThis = null) { trackedValuables.Clear(); extractionValuables.Clear(); trackedCarts.Clear(); totalValue = 0f; if (!IsRunActive()) { fullResyncRequested = false; MarkDirty(forceBreakdown: true); return; } ValuableObject[] array = Object.FindObjectsOfType<ValuableObject>(); foreach (ValuableObject val in array) { if (!((Object)(object)val == (Object)null) && !((Object)(object)val == (Object)(object)ignoreThis)) { float valuableCurrent = GetValuableCurrent(val); trackedValuables[val] = valuableCurrent; totalValue += valuableCurrent; } } PhysGrabCart[] array2 = Object.FindObjectsOfType<PhysGrabCart>(); foreach (PhysGrabCart val2 in array2) { if ((Object)(object)val2 != (Object)null) { trackedCarts.Add(val2); } } SyncExtractionState(); CleanupTrackedCollections(); fullResyncRequested = false; MarkDirty(forceBreakdown: true); Logger.LogDebug((object)$"Rebuilt tracked state for {trackedValuables.Count} valuables 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); } } if (list.Count > 0) { for (int i = 0; i < list.Count; i++) { ValuableObject key = list[i]; if (trackedValuables.TryGetValue(key, out var value)) { trackedValuables.Remove(key); totalValue -= value; } } } extractionValuables.RemoveWhere((ValuableObject valuable) => (Object)(object)valuable == (Object)null || !trackedValuables.ContainsKey(valuable)); trackedCarts.RemoveWhere((PhysGrabCart cart) => (Object)(object)cart == (Object)null); totalValue = Mathf.Max(0f, totalValue); } 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 cartsValue, out var extractionValue); result.MapValue = Mathf.Max(0f, totalValue); result.CartsValue = Mathf.Max(0f, cartsValue); result.ExtractionValue = Mathf.Max(0f, extractionValue); result.RemainingValue = Mathf.Max(0f, result.MapValue - result.CartsValue - result.ExtractionValue); result.HaulGoal = Mathf.Max(0, roundDirectorInt); result.CurrentHaul = Mathf.Max(0, GetRoundDirectorInt("currentHaul")); result.HideAfterCompletion = flag; result.UseRemainingForPrimary = Configuration.IsClosedModeRemaining(); result.IsVisible = flag2 && !flag; result.ShowCompactHud = result.IsVisible && !mapOpen && Configuration.AlwaysOn.Value; result.ShowMapPanel = result.IsVisible && mapOpen; 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 && !forceBreakdownRefresh && !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 cartsValue, out float extractionValue) { extractionValue = Mathf.Max(0f, (float)GetRoundDirectorInt("currentHaul")); cartsValue = ComputeValueInTrackedCarts(); } private static float ComputeValueInTrackedCarts() { if (trackedCarts.Count == 0) { return 0f; } float num = 0f; HashSet<ValuableObject> hashSet = new HashSet<ValuableObject>(); List<PhysGrabCart> list = new List<PhysGrabCart>(); foreach (PhysGrabCart trackedCart in trackedCarts) { if ((Object)(object)trackedCart == (Object)null) { list.Add(trackedCart); continue; } if (!TryGetCartItemsInCart(trackedCart, out List<PhysGrabObject> items)) { if (TryGetCartHaulCurrent(trackedCart, out var value)) { num += (float)value; } continue; } for (int i = 0; i < items.Count; i++) { PhysGrabObject val = items[i]; if (!((Object)(object)val == (Object)null)) { ValuableObject component = ((Component)val).GetComponent<ValuableObject>(); if (!((Object)(object)component == (Object)null) && !extractionValuables.Contains(component) && hashSet.Add(component)) { num += GetTrackedValuableValue(component); } } } } if (list.Count > 0) { for (int j = 0; j < list.Count; j++) { trackedCarts.Remove(list[j]); } } return num; } private static float GetTrackedValuableValue(ValuableObject valuable) { if (trackedValuables.TryGetValue(valuable, out var value)) { return value; } float valuableCurrent = GetValuableCurrent(valuable); trackedValuables[valuable] = valuableCurrent; totalValue += valuableCurrent; return valuableCurrent; } 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 bool TryGetCartItemsInCart(PhysGrabCart cart, out List<PhysGrabObject> items) { items = null; if ((Object)(object)cart == (Object)null) { return false; } if (cartItemsInCartField == null) { LogMissingCartFieldWarning("itemsInCart"); return false; } if (cartItemsInCartField.GetValue(cart) is List<PhysGrabObject> list) { items = list; return true; } 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"); } public static float GetValuableOriginal(ValuableObject vo) { float num = TryGetFloat(vo, "dollarValueOriginal", "dollarValueStart", "originalValue", "OriginalValue", "baseValue", "BaseValue"); if (num <= 0f) { num = GetValuableCurrent(vo); } return num; } 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 ExtractionValue; public float RemainingValue; public int HaulGoal; public int CurrentHaul; 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(ExtractionValue - other.ExtractionValue) < 0.01f && Math.Abs(RemainingValue - other.RemainingValue) < 0.01f && HaulGoal == other.HaulGoal) { return CurrentHaul == other.CurrentHaul; } 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) ^ ExtractionValue.GetHashCode()) * 397) ^ RemainingValue.GetHashCode()) * 397) ^ HaulGoal) * 397) ^ CurrentHaul; } } } namespace MapValueTracker.Patches { [HarmonyPatch(typeof(LevelGenerator))] internal static class LevelGeneratorPatches { [HarmonyPatch("StartRoomGeneration")] [HarmonyPrefix] private static void StartRoomGenerationPrefix() { MapValueTracker.Logger.LogDebug((object)"Generating Started. Resetting to zero."); MapValueTracker.ResetValues(); MapValueTracker.Logger.LogDebug((object)("Room generation started. Now val is " + MapValueTracker.totalValue)); } [HarmonyPatch("GenerateDone")] [HarmonyPrefix] private static void GenerateDonePrefix() { MapValueTracker.Logger.LogDebug((object)"Generating Started. Resetting to zero."); if (MapValueTracker.IsRuntimeEnabled()) { MapValueTracker.CheckForItems(); } MapValueTracker.Logger.LogDebug((object)("Generation done. Now val is " + 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()) { ValuableObject val = ((__instance != null) ? ((Component)__instance).GetComponent<ValuableObject>() : null); MapValueTracker.Logger.LogDebug((object)("BreakRPC - Current Value: " + MapValueTracker.totalValue)); MapValueTracker.Logger.LogDebug((object)("BreakRPC - Valuable Object current value: " + (((Object)(object)val == (Object)null) ? 0f : MapValueTracker.GetValuableCurrent(val)))); MapValueTracker.Logger.LogDebug((object)("BreakRPC - Value lost: " + valueLost)); MapValueTracker.RegisterOrRefreshValuable(val); MapValueTracker.Logger.LogDebug((object)("BreakRPC - After Break Value: " + 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)) { MapValueTracker.Logger.LogDebug((object)"Destroying (DPGO)!"); float valuableCurrent = MapValueTracker.GetValuableCurrent(component2); MapValueTracker.Logger.LogDebug((object)("Destroyed Valuable Object! " + ((Object)component2).name + " Val: " + valuableCurrent)); MapValueTracker.UnregisterValuable(component2); MapValueTracker.Logger.LogDebug((object)("After DPGO Map Remaining Val: " + 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 through RoundDirector patch."); 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 FormatHaul(int currentHaul, int haulGoal) { return "$" + SemiFunc.DollarGetString(currentHaul) + " / $" + SemiFunc.DollarGetString(haulGoal); } private static string BuildOpenMapLabels() { if (Configuration.IsFullBreakdown()) { return "MAP\nCARTS\nEXTRACTION\nREMAINING"; } return "MAP\nREMAINING\nHAUL"; } private static string BuildOpenMapValues(ValueBreakdownSnapshot snapshot) { if (Configuration.IsFullBreakdown()) { return string.Join("\n", FormatCurrency(snapshot.MapValue), FormatCurrency(snapshot.CartsValue), FormatCurrency(snapshot.ExtractionValue), FormatCurrency(snapshot.RemainingValue)); } return string.Join("\n", FormatCurrency(snapshot.MapValue), FormatCurrency(snapshot.RemainingValue), FormatHaul(snapshot.CurrentHaul, snapshot.HaulGoal)); } 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)("Checked after Extraction. Val is " + MapValueTracker.totalValue)); } } [HarmonyPatch("HaulCheck")] [HarmonyPostfix] public static void HaulCheckPostfix() { if (MapValueTracker.IsRuntimeEnabled()) { MapValueTracker.SyncExtractionState(); MapValueTracker.MarkDirty(forceBreakdown: true); } } [HarmonyPatch("ExtractionCompletedAllRPC")] [HarmonyPostfix] public static void ExtractionCompletedAllPostfix() { if (MapValueTracker.IsRuntimeEnabled()) { MapValueTracker.MarkDirty(forceBreakdown: true); } } [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("After dollar value set Total Val: "); } } [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("After dollar value set Total Val: "); } } [HarmonyPatch("AddToDollarHaulList")] [HarmonyPostfix] private static void AddToDollarHaulListDirectPostfix(ValuableObject __instance) { if (MapValueTracker.IsRuntimeEnabled()) { MapValueTracker.AddExtractionValuable(__instance); } } [HarmonyPatch("AddToDollarHaulListRPC")] [HarmonyPostfix] private static void AddToDollarHaulListPostfix(ValuableObject __instance) { if (MapValueTracker.IsRuntimeEnabled()) { MapValueTracker.AddExtractionValuable(__instance); } } [HarmonyPatch("RemoveFromDollarHaulList")] [HarmonyPostfix] private static void RemoveFromDollarHaulListDirectPostfix(ValuableObject __instance) { if (MapValueTracker.IsRuntimeEnabled()) { MapValueTracker.RemoveExtractionValuable(__instance); } } [HarmonyPatch("RemoveFromDollarHaulListRPC")] [HarmonyPostfix] private static void RemoveFromDollarHaulListPostfix(ValuableObject __instance) { if (MapValueTracker.IsRuntimeEnabled()) { MapValueTracker.RemoveExtractionValuable(__instance); } } private static void LogValueCreated(string objectName, float value) { MapValueTracker.Logger.LogDebug((object)("Created Valuable Object! " + objectName + " Val: " + 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; } } }