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.0.3
MapValueTrackerPlus.dll
Decompiled a week agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; 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+ba090020af186764a02b9edf42b50bd32aab5907")] [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.0.3")] public class MapValueTracker : BaseUnityPlugin { public const string PLUGIN_GUID = "MapValueTrackerPlus"; public const string PLUGIN_NAME = "Map Value Tracker Plus"; public const string PLUGIN_VERSION = "1.0.3"; public static ManualLogSource Logger; private readonly Harmony harmony = new Harmony("MapValueTrackerPlus.REPO"); public static MapValueTracker instance; public static GameObject textInstance; public static TextMeshProUGUI valueText; public static float totalValue = 0f; public static float totalValueInit = 0f; public static float cachedCartsValue = 0f; public static float cachedExtractionValue = 0f; private static float lastBreakdownTime = -100000f; private static bool lastMapOpen = false; private static readonly FieldInfo cartHaulCurrentField = AccessTools.Field(typeof(PhysGrabCart), "haulCurrent"); private static readonly FieldInfo cartItemsInCartField = AccessTools.Field(typeof(PhysGrabCart), "itemsInCart"); private static bool cartFieldWarningLogged; 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); harmony.PatchAll(); } public static void ResetValues() { if (!SemiFunc.RunIsLevel()) { totalValue = 0f; } Logger.LogDebug((object)"In ResetValues()"); Logger.LogDebug((object)("Total Map Value: " + totalValue)); } public static void CheckForItems(ValuableObject? ignoreThis = null) { if (!Traverse.Create((object)RoundDirector.instance).Field("allExtractionPointsCompleted").GetValue<bool>()) { totalValue = 0f; List<ValuableObject> list = Object.FindObjectsOfType<ValuableObject>().ToList(); if ((Object)(object)ignoreThis != (Object)null) { list.Remove(ignoreThis); } for (int i = 0; i < list.Count; i++) { totalValue += GetValuableCurrent(list[i]); } Logger.LogDebug((object)("After CheckForItems Total Val: " + totalValue)); } } public static float GetDisplayedMapValue() { if (!Configuration.StartingValueOnly.Value) { return totalValue; } return totalValueInit; } public static float ComputeValueInExtraction() { if ((Object)(object)RoundDirector.instance == (Object)null) { return 0f; } GetExtractionSets(out HashSet<ValuableObject> extractionValuables, out HashSet<GameObject> _); float num = 0f; foreach (ValuableObject item in extractionValuables) { num += GetValuableCurrent(item); } return num; } public static float ComputeValueInCarts() { GetExtractionSets(out HashSet<ValuableObject> extractionValuables, out HashSet<GameObject> _); return ComputeValueInCarts(extractionValuables); } private static void ComputeBreakdownValues(bool needCarts, bool needExtraction, out float cartsValue, out float extractionValue) { cartsValue = 0f; extractionValue = 0f; if (!needCarts && !needExtraction) { return; } GetExtractionSets(out HashSet<ValuableObject> extractionValuables, out HashSet<GameObject> _); if (needExtraction) { foreach (ValuableObject item in extractionValuables) { extractionValue += GetValuableCurrent(item); } } if (needCarts) { cartsValue = ComputeValueInCarts(extractionValuables); } } private static float ComputeValueInCarts(HashSet<ValuableObject> extractionValuables) { PhysGrabCart[] array = Object.FindObjectsOfType<PhysGrabCart>(); if (array == null || array.Length == 0) { return 0f; } if (extractionValuables == null || extractionValuables.Count == 0) { float num = 0f; for (int i = 0; i < array.Length; i++) { if (TryGetCartHaulCurrent(array[i], out var value)) { num += (float)value; } } return num; } float num2 = 0f; HashSet<ValuableObject> hashSet = new HashSet<ValuableObject>(); for (int j = 0; j < array.Length; j++) { if (!TryGetCartItemsInCart(array[j], out List<PhysGrabObject> items)) { continue; } for (int k = 0; k < items.Count; k++) { PhysGrabObject val = items[k]; if (!((Object)(object)val == (Object)null)) { ValuableObject component = ((Component)val).GetComponent<ValuableObject>(); if (!((Object)(object)component == (Object)null) && hashSet.Add(component) && !extractionValuables.Contains(component)) { num2 += GetValuableCurrent(component); } } } } return num2; } 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 will be treated as $0.")); } } public static void UpdateBreakdownCache(bool mapOpen, bool allowWhenClosed, bool needCarts, bool needExtraction) { float num = Math.Max(0.1f, Configuration.BreakdownUpdateIntervalSeconds.Value); float unscaledTime = Time.unscaledTime; bool flag = mapOpen && !lastMapOpen; if (!mapOpen && !allowWhenClosed) { lastMapOpen = false; return; } if (!flag && unscaledTime - lastBreakdownTime < num) { lastMapOpen = true; return; } ComputeBreakdownValues(needCarts, needExtraction, out cachedCartsValue, out cachedExtractionValue); lastBreakdownTime = unscaledTime; lastMapOpen = mapOpen; } private static void GetExtractionSets(out HashSet<ValuableObject> extractionValuables, out HashSet<GameObject> extractionObjects) { extractionValuables = new HashSet<ValuableObject>(); extractionObjects = new HashSet<GameObject>(); 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)) { extractionObjects.Add(val); ValuableObject component = val.GetComponent<ValuableObject>(); if ((Object)(object)component != (Object)null) { extractionValuables.Add(component); } } } } 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(); foreach (string text in names) { FieldInfo fieldInfo = AccessTools.Field(type, text); if (fieldInfo != null && TryConvertToFloat(fieldInfo.GetValue(obj), out var result)) { return result; } PropertyInfo propertyInfo = AccessTools.Property(type, text); if (propertyInfo != null && TryConvertToFloat(propertyInfo.GetValue(obj, null), out var result2)) { return result2; } } return 0f; } 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 class MyOnDestroy : MonoBehaviour { private void OnDestroy() { MapValueTracker.Logger.LogDebug((object)"Destroying!"); ValuableObject component = ((Component)this).GetComponent<ValuableObject>(); float valuableCurrent = MapValueTracker.GetValuableCurrent(component); MapValueTracker.Logger.LogDebug((object)("Destroyed Valuable Object! " + ((Object)component).name + " Val: " + valuableCurrent)); MapValueTracker.totalValue -= valuableCurrent; MapValueTracker.Logger.LogDebug((object)("Total Val: " + MapValueTracker.totalValue)); } } } namespace MapValueTracker.Patches { [HarmonyPatch(typeof(LevelGenerator))] internal static class LevelGeneratorPatches { [HarmonyPatch("StartRoomGeneration")] [HarmonyPrefix] public static void StartRoomGeneration() { 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] public static void GenerateDonePostfix() { MapValueTracker.Logger.LogDebug((object)"Generating Started. Resetting to zero."); MapValueTracker.CheckForItems(); MapValueTracker.totalValueInit = MapValueTracker.totalValue; MapValueTracker.Logger.LogDebug((object)("Generation done. Now val is " + MapValueTracker.totalValue + ". Init Value: " + MapValueTracker.totalValueInit)); } } [HarmonyPatch(typeof(PhysGrabObjectImpactDetector))] public static class PhysGrabObjectImpactDetectorPatches { [HarmonyPatch("BreakRPC")] [HarmonyPostfix] private static void StartPostFix(float valueLost, PhysGrabObjectImpactDetector? __instance, bool _loseValue) { if (_loseValue) { MapValueTracker.Logger.LogDebug((object)("BreakRPC - Current Value: " + MapValueTracker.totalValue)); ValuableObject val = ((__instance != null) ? ((Component)__instance).GetComponent<ValuableObject>() : null); 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.totalValue -= valueLost; MapValueTracker.Logger.LogDebug((object)("BreakRPC - After Break Value: " + MapValueTracker.totalValue)); } } [HarmonyPatch(typeof(PhysGrabObject), "DestroyPhysGrabObjectRPC")] [HarmonyPostfix] public static void DestroyPhysGrabObjectPostfix(PhysGrabObject __instance) { if (!SemiFunc.RunIsLevel()) { return; } ValuableObject component = ((Component)__instance).GetComponent<ValuableObject>(); if (!((Object)(object)component == (Object)null)) { MapValueTracker.Logger.LogDebug((object)"Destroying (DPGO)!"); float valuableCurrent = MapValueTracker.GetValuableCurrent(component); float valuableOriginal = MapValueTracker.GetValuableOriginal(component); MapValueTracker.Logger.LogDebug((object)("Destroyed Valuable Object! " + ((Object)component).name + " Val: " + valuableCurrent)); if (valuableCurrent < valuableOriginal * 0.15f) { MapValueTracker.totalValue -= 0f; } else { MapValueTracker.totalValue -= valuableCurrent; } MapValueTracker.Logger.LogDebug((object)("After DPGO Map Remaining Val: " + MapValueTracker.totalValue)); } } } [HarmonyPatch(typeof(RoundDirector))] public static class RoundDirectorPatches { private static void SetCoordinates(RectTransform component) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00af: 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_0119: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0143: 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_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_0217: Unknown result type (might be due to invalid IL or missing references) //IL_022c: 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_0251: Unknown result type (might be due to invalid IL or missing references) //IL_0261: Unknown result type (might be due to invalid IL or missing references) //IL_0277: Unknown result type (might be due to invalid IL or missing references) //IL_028c: Unknown result type (might be due to invalid IL or missing references) //IL_02a1: Unknown result type (might be due to invalid IL or missing references) //IL_02b6: Unknown result type (might be due to invalid IL or missing references) //IL_02cb: Unknown result type (might be due to invalid IL or missing references) //IL_02e0: Unknown result type (might be due to invalid IL or missing references) //IL_02f5: Unknown result type (might be due to invalid IL or missing references) switch (Configuration.UIPosition.Value) { case Positions.Default: component.pivot = new Vector2(1f, 1f); component.anchoredPosition = new Vector2(1f, -1f); component.anchorMin = new Vector2(0f, 0f); component.anchorMax = new Vector2(1f, 0f); component.sizeDelta = new Vector2(0f, 0f); component.offsetMax = new Vector2(0f, 225f); component.offsetMin = new Vector2(0f, 225f); break; case Positions.LowerRight: component.pivot = new Vector2(1f, 1f); component.anchoredPosition = new Vector2(1f, -1f); component.anchorMin = new Vector2(0f, 0f); component.anchorMax = new Vector2(1f, 0f); component.sizeDelta = new Vector2(0f, 0f); component.offsetMax = new Vector2(0f, 125f); component.offsetMin = new Vector2(0f, 125f); break; case Positions.BottomRight: component.pivot = new Vector2(1f, 1f); component.anchoredPosition = new Vector2(1f, -1f); component.anchorMin = new Vector2(0f, 0f); component.anchorMax = new Vector2(1f, 0f); component.sizeDelta = new Vector2(0f, 0f); component.offsetMax = new Vector2(0f, 0f); component.offsetMin = new Vector2(0f, 0f); break; case Positions.Custom: component.pivot = new Vector2(1f, 1f); component.anchoredPosition = new Vector2(1f, -1f); component.anchorMin = new Vector2(0f, 0f); component.anchorMax = new Vector2(1f, 0f); component.sizeDelta = new Vector2(0f, 0f); component.offsetMax = Configuration.CustomPositionCoords.Value; component.offsetMin = Configuration.CustomPositionCoords.Value; break; default: component.pivot = new Vector2(1f, 1f); component.anchoredPosition = new Vector2(1f, -1f); component.anchorMin = new Vector2(0f, 0f); component.anchorMax = new Vector2(1f, 0f); component.sizeDelta = new Vector2(0f, 0f); component.offsetMax = new Vector2(0f, 225f); component.offsetMin = new Vector2(0f, 225f); break; } } [HarmonyPatch("ExtractionCompleted")] [HarmonyPostfix] public static void ExtractionComplete() { if (SemiFunc.RunIsLevel()) { MapValueTracker.Logger.LogDebug((object)"Extraction Completed!"); MapValueTracker.CheckForItems(); MapValueTracker.Logger.LogDebug((object)("Checked after Extraction. Val is " + MapValueTracker.totalValue)); } } [HarmonyPatch(typeof(RoundDirector), "Update")] [HarmonyPostfix] public static void UpdateUI() { //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Expected O, but got Unknown //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) int? num = Traverse.Create((object)RoundDirector.instance).Field("extractionHaulGoal").GetValue<int>(); Traverse.Create((object)RoundDirector.instance).Field("extractionPointActive").GetValue<bool>(); bool value = Traverse.Create((object)RoundDirector.instance).Field("allExtractionPointsCompleted").GetValue<bool>(); if (!SemiFunc.RunIsLevel()) { return; } if ((Object)(object)MapValueTracker.textInstance == (Object)null) { GameObject val = GameObject.Find("Game Hud"); GameObject val2 = GameObject.Find("Tax Haul"); if (!((Object)(object)val == (Object)null) && !((Object)(object)val2 == (Object)null)) { TMP_FontAsset font = val2.GetComponent<TMP_Text>().font; MapValueTracker.textInstance = new GameObject(); MapValueTracker.textInstance.SetActive(false); ((Object)MapValueTracker.textInstance).name = "Value HUD"; MapValueTracker.textInstance.AddComponent<TextMeshProUGUI>(); MapValueTracker.valueText = MapValueTracker.textInstance.GetComponent<TextMeshProUGUI>(); ((TMP_Text)MapValueTracker.valueText).font = font; ((Graphic)MapValueTracker.valueText).color = Color.op_Implicit(new Vector4(0.7882f, 0.9137f, 0.902f, 1f)); ((TMP_Text)MapValueTracker.valueText).fontSize = 24f; ((TMP_Text)MapValueTracker.valueText).enableWordWrapping = false; ((TMP_Text)MapValueTracker.valueText).alignment = (TextAlignmentOptions)2052; ((TMP_Text)MapValueTracker.valueText).horizontalAlignment = (HorizontalAlignmentOptions)4; ((TMP_Text)MapValueTracker.valueText).verticalAlignment = (VerticalAlignmentOptions)2048; MapValueTracker.textInstance.transform.SetParent(val.transform, false); SetCoordinates(MapValueTracker.textInstance.GetComponent<RectTransform>()); } } else if ((Object)(object)MapValueTracker.valueText != (Object)null && ((num.HasValue && num != 0) || !value)) { bool value2 = Traverse.Create((object)MapToolController.instance).Field("mapToggled").GetValue<bool>(); SetCoordinates(MapValueTracker.textInstance.GetComponent<RectTransform>()); float displayedMapValue = MapValueTracker.GetDisplayedMapValue(); bool flag = SemiFunc.InputHold((InputKey)8) || value2; bool needCarts = Configuration.ShowCartsValue.Value || Configuration.ShowRemainingValue.Value; bool needExtraction = Configuration.ShowExtractionValue.Value || Configuration.ShowRemainingValue.Value; float num2 = displayedMapValue; if (!flag && Configuration.ReplaceHudMapWithRemaining.Value) { MapValueTracker.UpdateBreakdownCache(mapOpen: false, allowWhenClosed: true, needCarts: true, needExtraction: true); num2 = Mathf.Max(0f, displayedMapValue - MapValueTracker.cachedCartsValue - MapValueTracker.cachedExtractionValue); } string text = "Map: $" + num2.ToString("N0"); if (flag && Configuration.ShowBreakdownOnMap.Value) { MapValueTracker.UpdateBreakdownCache(flag, allowWhenClosed: false, needCarts, needExtraction); float num3 = 0f; float num4 = 0f; if (Configuration.ShowCartsValue.Value) { num3 = MapValueTracker.cachedCartsValue; text = text + "\nCarts: $" + num3.ToString("N0"); } if (Configuration.ShowExtractionValue.Value) { num4 = MapValueTracker.cachedExtractionValue; text = text + "\nExtraction: $" + num4.ToString("N0"); } if (Configuration.ShowRemainingValue.Value) { text = text + "\nRemaining: $" + Mathf.Max(0f, displayedMapValue - num3 - num4).ToString("N0"); } } ((TMP_Text)MapValueTracker.valueText).SetText(text, true); if (Configuration.AlwaysOn.Value) { MapValueTracker.textInstance.SetActive(true); } else if (flag) { MapValueTracker.textInstance.SetActive(true); } else { MapValueTracker.textInstance.SetActive(false); } } else { MapValueTracker.textInstance.SetActive(false); } } } [HarmonyPatch(typeof(ValuableObject))] internal static class ValuableObjectPatches { [HarmonyPatch("Start")] [HarmonyPostfix] private static void Start(ValuableObject __instance) { } [HarmonyPatch("DollarValueSetRPC")] [HarmonyPostfix] private static void DollarValueSet(ValuableObject __instance, float value) { MapValueTracker.Logger.LogDebug((object)("Created Valuable Object! " + ((Object)__instance).name + " Val: " + value)); MapValueTracker.totalValue += value; MapValueTracker.Logger.LogDebug((object)("After dollar value set Total Val: " + MapValueTracker.totalValue)); } [HarmonyPatch("DollarValueSetLogic")] [HarmonyPostfix] private static void DollarValueSetLogic(ValuableObject __instance) { if (SemiFunc.IsMasterClientOrSingleplayer()) { float valuableCurrent = MapValueTracker.GetValuableCurrent(__instance); MapValueTracker.Logger.LogDebug((object)("Created Valuable Object! " + ((Object)__instance).name + " Val: " + valuableCurrent)); MapValueTracker.totalValue += valuableCurrent; MapValueTracker.Logger.LogDebug((object)("After dollar value set Total Val: " + MapValueTracker.totalValue)); } } } } namespace MapValueTracker.Config { public enum Positions { Default, LowerRight, BottomRight, Custom } internal class Configuration { public static ConfigEntry<bool> AlwaysOn; public static ConfigEntry<bool> StartingValueOnly; public static ConfigEntry<Positions> UIPosition; public static ConfigEntry<Vector2> CustomPositionCoords; public static ConfigEntry<bool> ShowBreakdownOnMap; public static ConfigEntry<bool> ShowCartsValue; public static ConfigEntry<bool> ShowExtractionValue; public static ConfigEntry<bool> ShowRemainingValue; public static ConfigEntry<float> BreakdownUpdateIntervalSeconds; public static ConfigEntry<bool> ReplaceHudMapWithRemaining; public static void Init(ConfigFile config) { //IL_006d: Unknown result type (might be due to invalid IL or missing references) config.SaveOnConfigSet = false; AlwaysOn = config.Bind<bool>("Default", "AlwaysOn", true, "Toggle to always display map value when an extraction goal is active. If false, use the menu key to pull up the tracker (Tab by default)."); StartingValueOnly = config.Bind<bool>("Default", "StartingValueOnly", false, "Toggle to keep the Map Value fixed to the level's initially generated value. Will not update value in real time from breaking items, killing enemies, or extracting loot. Should not be used with UseValueRatio set to true."); UIPosition = config.Bind<Positions>("UIPosition", "UIPosition", Positions.Default, "Preset Position of the Value Tracker UI element. Default is on the right side, below the extraction targets."); CustomPositionCoords = config.Bind<Vector2>("UIPosition", "CustomPositionCoords", new Vector2(0f, 0f), "Custom X,Y coordates of the Value Tracker UI element. Bottom Right corner is 0,0. Default position is 0,225."); ShowBreakdownOnMap = config.Bind<bool>("Breakdown", "ShowBreakdownOnMap", true, "When true, shows extra value lines (Carts/Extraction/Remaining) while the map is open."); ShowCartsValue = config.Bind<bool>("Breakdown", "ShowCartsValue", true, "When true, shows the total value currently inside carts."); ShowExtractionValue = config.Bind<bool>("Breakdown", "ShowExtractionValue", true, "When true, shows the total value currently staged in extraction."); ShowRemainingValue = config.Bind<bool>("Breakdown", "ShowRemainingValue", true, "When true, shows remaining value (Map minus Carts/Extraction)."); BreakdownUpdateIntervalSeconds = config.Bind<float>("Breakdown", "BreakdownUpdateIntervalSeconds", 1f, "How often (in seconds) the breakdown values refresh while the map is open. Lower is more accurate, higher is lighter."); ReplaceHudMapWithRemaining = config.Bind<bool>("Breakdown", "ReplaceHudMapWithRemaining", false, "When true, the always-on HUD line shows Remaining value instead of Map value."); ClearOrphanedEntries(config); config.Save(); config.SaveOnConfigSet = true; } private static void ClearOrphanedEntries(ConfigFile cfg) { ((Dictionary<ConfigDefinition, string>)AccessTools.Property(typeof(ConfigFile), "OrphanedEntries").GetValue(cfg)).Clear(); } } }