Decompiled source of Map Value Tracker Plus v1.2.1

MapValueTrackerPlus.dll

Decompiled 2 days ago
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<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;
		}
	}
}