using 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> cachedMembers = new Dictionary>(); private static readonly Dictionary trackedValuables = new Dictionary(); private static readonly HashSet extractionValuables = new HashSet(); private static readonly HashSet trackedCarts = new HashSet(); 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 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(); 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(); 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(); 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 list = new List(); foreach (KeyValuePair 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(); } 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(); } return 0; } private static bool GetRoundDirectorBool(string fieldName) { if ((Object)(object)RoundDirector.instance != (Object)null) { return Traverse.Create((object)RoundDirector.instance).Field(fieldName).GetValue(); } 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 hashSet = new HashSet(); List list = new List(); foreach (PhysGrabCart trackedCart in trackedCarts) { if ((Object)(object)trackedCart == (Object)null) { list.Add(trackedCart); continue; } if (!TryGetCartItemsInCart(trackedCart, out List 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(); 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 items) { items = null; if ((Object)(object)cart == (Object)null) { return false; } if (cartItemsInCartField == null) { LogMissingCartFieldWarning("itemsInCart"); return false; } if (cartItemsInCartField.GetValue(cart) is List 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 value)) { value = new Dictionary(); 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 { 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() : 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(); if ((Object)(object)component != (Object)null) { MapValueTracker.UnregisterCart(component); } ValuableObject component2 = ((Component)__instance).GetComponent(); 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(); 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()); 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(); ((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(); ((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 "" + label.ToUpperInvariant() + " " + value + ""; } 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 AlwaysOn = null; public static ConfigEntry ClosedMapDisplayMode = null; public static ConfigEntry OpenMapDisplayMode = null; public static ConfigEntry SyncHudPositions = null; public static ConfigEntry UiPositionPreset = null; public static ConfigEntry CustomOffsetX = null; public static ConfigEntry CustomOffsetY = null; public static ConfigEntry OpenMapPositionPreset = null; public static ConfigEntry OpenMapCustomOffsetX = null; public static ConfigEntry OpenMapCustomOffsetY = null; public static ConfigEntry HideAfterFinalExtraction = null; public static ConfigEntry RefreshIntervalSeconds = null; public static ConfigEntry RuntimeEnabled = null; public static ConfigEntry 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("Closed Map HUD", "Show Closed Map HUD", true, new ConfigDescription("Show the compact valuables readout while the map is closed.", (AcceptableValueBase)null, Array.Empty())); ClosedMapDisplayMode = config.Bind("Closed Map HUD", "Closed Map Display", "Remaining", new ConfigDescription("Choose which value the closed-map HUD shows.", (AcceptableValueBase)(object)new AcceptableValueList(new string[2] { "Map", "Remaining" }), Array.Empty())); OpenMapDisplayMode = config.Bind("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(new string[2] { "Summary", "FullBreakdown" }), Array.Empty())); SyncHudPositions = config.Bind("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())); UiPositionPreset = config.Bind("Closed Map Position", "Position Preset", "Default", new ConfigDescription("Choose the closed-map HUD position.", (AcceptableValueBase)(object)new AcceptableValueList(new string[2] { "Default", "Custom" }), Array.Empty())); CustomOffsetX = config.Bind("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())); CustomOffsetY = config.Bind("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())); OpenMapPositionPreset = config.Bind("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(new string[2] { "Default", "Custom" }), Array.Empty())); OpenMapCustomOffsetX = config.Bind("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())); OpenMapCustomOffsetY = config.Bind("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())); HideAfterFinalExtraction = config.Bind("Advanced", "Hide After Final Extraction", true, new ConfigDescription("Hide the valuables HUD after the last extraction is finished.", (AcceptableValueBase)null, Array.Empty())); RefreshIntervalSeconds = config.Bind("Advanced", "Refresh Interval Seconds", 1f, new ConfigDescription("How often the valuables totals refresh during a run.", (AcceptableValueBase)(object)new AcceptableValueRange(0.1f, 5f), Array.Empty())); RuntimeEnabled = config.Bind("Debug", "Disable", true, new ConfigDescription("Enable or disable all Map Value Tracker Plus logic.", (AcceptableValueBase)null, Array.Empty())); DebugLogging = config.Bind("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; } } }