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 v1.3.1
MapValueTracker.dll
Decompiled a month agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using MapValueTracker.Config; using MapValueTracker.Upgrades; using Microsoft.CodeAnalysis; using REPOLib.Modules; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("MapValueTracker")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.3.1.0")] [assembly: AssemblyInformationalVersion("1.3.1+f852abc0eff393f2ca1c018c01ccac3447444cd4")] [assembly: AssemblyProduct("MapValueTracker")] [assembly: AssemblyTitle("MapValueTracker")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.3.1.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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("MapValueTracker", "MapValueTracker", "1.3.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class MapValueTracker : BaseUnityPlugin { public const string PLUGIN_GUID = "MapValueTracker"; public const string PLUGIN_NAME = "MapValueTracker"; public const string PLUGIN_VERSION = "1.3.1"; public static ManualLogSource Logger; private readonly Harmony harmony = new Harmony("Tansinator.REPO.MapValueTracker"); public static MapValueTracker instance; public static GameObject textInstance; public static TextMeshProUGUI valueText; public static float totalValue = 0f; public static float totalValueInit = 0f; public static readonly HashSet<int> destroyedIds = new HashSet<int>(); public static readonly HashSet<int> absorbedInBoxIds = new HashSet<int>(); public void Awake() { Logger = ((BaseUnityPlugin)this).Logger; Logger.LogInfo((object)"Plugin MapValueTracker is loaded!"); if ((Object)(object)instance == (Object)null) { instance = this; } Configuration.Init(((BaseUnityPlugin)this).Config); if (Chainloader.PluginInfos.ContainsKey("Zehs.REPOLib")) { InitShopUpgrade(); } else { Logger.LogInfo((object)"[MapValueTracker] REPOLib not detected. Shop upgrade registration skipped."); } harmony.PatchAll(); } [MethodImpl(MethodImplOptions.NoInlining)] private void InitShopUpgrade() { MapValueTrackerUpgradeManager.Initialize(); } public static void ResetValues() { totalValue = 0f; totalValueInit = 0f; destroyedIds.Clear(); absorbedInBoxIds.Clear(); Logger.LogDebug((object)"In ResetValues() - Reset totalValue and totalValueInit to 0"); } public static void CheckForItems(ValuableObject ignoreThis = null) { if (!((Object)(object)RoundDirector.instance == (Object)null) && RoundDirector.instance.allExtractionPointsCompleted) { return; } totalValue = 0f; ValuableObject[] array = Object.FindObjectsOfType<ValuableObject>(); foreach (ValuableObject val in array) { if ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)ignoreThis && ((Component)val).gameObject.activeInHierarchy && !IsPendingDestroy(val.physGrabObject)) { totalValue += val.dollarValueCurrent; } } ItemValuableBox[] array2 = Object.FindObjectsOfType<ItemValuableBox>(); foreach (ItemValuableBox val2 in array2) { if ((Object)(object)val2 != (Object)null && ((Component)val2).gameObject.activeInHierarchy && !IsPendingDestroy(((Component)val2).GetComponent<PhysGrabObject>())) { totalValue += val2.CurrentValue; } } Logger.LogDebug((object)("After CheckForItems Total Val: " + totalValue)); } private static bool IsPendingDestroy(PhysGrabObject pgo) { if ((Object)(object)pgo != (Object)null) { return destroyedIds.Contains(((Object)pgo).GetInstanceID()); } return false; } } public static class MyPluginInfo { public const string PLUGIN_GUID = "MapValueTracker"; public const string PLUGIN_NAME = "MapValueTracker"; public const string PLUGIN_VERSION = "1.3.1"; } } namespace MapValueTracker.Upgrades { public class ItemUpgradeMapValueTracker : MonoBehaviour { private ItemToggle itemToggle; private void Start() { itemToggle = ((Component)this).GetComponent<ItemToggle>(); } public void Upgrade() { string text = null; if ((Object)(object)itemToggle != (Object)null) { PlayerAvatar val = SemiFunc.PlayerAvatarGetFromPhotonID(itemToggle.playerTogglePhotonID); if ((Object)(object)val != (Object)null) { text = SemiFunc.PlayerGetSteamID(val); } } if (string.IsNullOrEmpty(text) && (Object)(object)SemiFunc.PlayerAvatarLocal() != (Object)null) { text = SemiFunc.PlayerGetSteamID(SemiFunc.PlayerAvatarLocal()); } MapValueTrackerUpgradeManager.UnlockForPlayer(text); } } public static class MapValueTrackerUpgradeManager { public const string ItemName = "Item Upgrade Map Value Tracker"; public const string DisplayName = "Map Value Tracker"; public static readonly Dictionary<string, int> playerUpgradeMapValueTracker = new Dictionary<string, int>(); private static bool isInitialized = false; private static Texture2D cachedIconTexture = null; public static void Initialize() { //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Expected O, but got Unknown if (isInitialized) { return; } isInitialized = true; try { Item val = Resources.Load<Item>("Items/Item Upgrade Map Player Count"); if ((Object)(object)val == (Object)null) { Item[] array = Resources.LoadAll<Item>("Items"); foreach (Item val2 in array) { if ((Object)(object)val2 != (Object)null && (((Object)val2).name == "Item Upgrade Map Player Count" || val2.itemName == "Map Player Count")) { val = val2; break; } } } if ((Object)(object)val == (Object)null) { MapValueTracker.Logger.LogWarning((object)"[MapValueTracker] Could not find vanilla 'Item Upgrade Map Player Count' to clone."); return; } GameObject val3 = ((val.prefab != null && (Object)(object)((PrefabRef<GameObject>)(object)val.prefab).Prefab != (Object)null) ? ((PrefabRef<GameObject>)(object)val.prefab).Prefab : Resources.Load<GameObject>("Items/Item Upgrade Map Player Count")); if ((Object)(object)val3 == (Object)null) { MapValueTracker.Logger.LogWarning((object)"[MapValueTracker] Could not find vanilla prefab for 'Item Upgrade Map Player Count'."); return; } Item val4 = Object.Instantiate<Item>(val); ((Object)val4).name = "Item Upgrade Map Value Tracker"; val4.itemName = "Map Value Tracker"; val4.description = "Displays the total value of valuables remaining on the map."; val4.minPlayerCount = 1; val4.maxAmountInShop = 1; val4.maxPurchase = true; val4.maxPurchaseAmount = 1; Value val5 = ScriptableObject.CreateInstance<Value>(); val5.valueMin = 4000f; val5.valueMax = 7000f; val4.value = val5; GameObject obj = Object.Instantiate<GameObject>(val3); ((Object)obj).name = "Item Upgrade Map Value Tracker"; Object.DontDestroyOnLoad((Object)(object)obj); ((Object)obj).hideFlags = (HideFlags)61; ApplyCustomMaterials(obj); ItemUpgradeMapPlayerCount component = obj.GetComponent<ItemUpgradeMapPlayerCount>(); if ((Object)(object)component != (Object)null) { Object.DestroyImmediate((Object)(object)component); } ItemUpgradeMapValueTracker itemUpgradeMapValueTracker = obj.AddComponent<ItemUpgradeMapValueTracker>(); ItemUpgrade component2 = obj.GetComponent<ItemUpgrade>(); if ((Object)(object)component2 != (Object)null) { ((UnityEventBase)component2.upgradeEvent).RemoveAllListeners(); component2.upgradeEvent.AddListener(new UnityAction(itemUpgradeMapValueTracker.Upgrade)); } ItemAttributes component3 = obj.GetComponent<ItemAttributes>(); if ((Object)(object)component3 != (Object)null) { component3.item = val4; } Items.RegisterItem(component3); MapValueTracker.Logger.LogInfo((object)"[MapValueTracker] Successfully registered 'Map Value Tracker' shop upgrade ($4,000 - $7,000) with REPOLib."); } catch (Exception arg) { MapValueTracker.Logger.LogError((object)$"[MapValueTracker] Failed to register shop upgrade: {arg}"); } } public static Texture2D GetIconTexture() { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown if ((Object)(object)cachedIconTexture != (Object)null) { return cachedIconTexture; } try { using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("MapValueTracker.Resources.tracker_icon.png"); if (stream != null) { byte[] array = new byte[stream.Length]; stream.Read(array, 0, array.Length); cachedIconTexture = new Texture2D(2, 2, (TextureFormat)4, false); ImageConversion.LoadImage(cachedIconTexture, array); ((Object)cachedIconTexture).name = "MapValueTrackerIcon"; } } catch (Exception arg) { MapValueTracker.Logger.LogWarning((object)$"[MapValueTracker] Could not load embedded tracker_icon.png: {arg}"); } return cachedIconTexture; } private static void ApplyCustomMaterials(GameObject prefab) { //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) Texture2D iconTexture = GetIconTexture(); if ((Object)(object)iconTexture == (Object)null) { return; } Renderer[] componentsInChildren = prefab.GetComponentsInChildren<Renderer>(true); foreach (Renderer val in componentsInChildren) { Material[] materials = val.materials; foreach (Material val2 in materials) { if (!((Object)(object)val2 == (Object)null)) { val2.mainTexture = (Texture)(object)iconTexture; if (val2.HasProperty("_BaseMap")) { val2.SetTexture("_BaseMap", (Texture)(object)iconTexture); } if (val2.HasProperty("_MainTex")) { val2.SetTexture("_MainTex", (Texture)(object)iconTexture); } if (val2.HasProperty("_Color")) { val2.SetColor("_Color", Color.white); } if (val2.HasProperty("_BaseColor")) { val2.SetColor("_BaseColor", Color.white); } } } val.materials = materials; } } public static void UnlockForPlayer(string steamId) { if (string.IsNullOrEmpty(steamId) && (Object)(object)SemiFunc.PlayerAvatarLocal() != (Object)null) { steamId = SemiFunc.PlayerGetSteamID(SemiFunc.PlayerAvatarLocal()); } if (!string.IsNullOrEmpty(steamId)) { playerUpgradeMapValueTracker[steamId] = 1; MapValueTracker.Logger.LogInfo((object)("[MapValueTracker] Unlocked Map Value Tracker for player: " + steamId)); } } public static bool IsTrackerUnlocked() { if (!Configuration.RequireShopUpgrade.Value) { return true; } PlayerAvatar val = SemiFunc.PlayerAvatarLocal(); if ((Object)(object)val != (Object)null) { string text = SemiFunc.PlayerGetSteamID(val); if (!string.IsNullOrEmpty(text) && playerUpgradeMapValueTracker.TryGetValue(text, out var value) && value > 0) { return true; } } if (Configuration.TeamWideUnlock.Value) { foreach (KeyValuePair<string, int> item in playerUpgradeMapValueTracker) { if (item.Value > 0) { return true; } } } return false; } public static void ResetProgress() { playerUpgradeMapValueTracker.Clear(); MapValueTracker.Logger.LogInfo((object)"[MapValueTracker] Upgrade progress reset for new run."); } } [HarmonyPatch(typeof(StatsManager), "Start")] internal static class StatsManagerStartPatch { private static void Postfix(StatsManager __instance) { //IL_0032: 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) //IL_004e: Expected O, but got Unknown if (!__instance.dictionaryOfDictionaries.ContainsKey("playerUpgradeMapValueTracker")) { __instance.dictionaryOfDictionaries.Add("playerUpgradeMapValueTracker", MapValueTrackerUpgradeManager.playerUpgradeMapValueTracker); __instance.upgradesInfo.Add("playerUpgradeMapValueTracker", new UpgradeInfo { displayName = "Map Value Tracker", displayNameLocalized = null }); } } } [HarmonyPatch(typeof(RunManager), "ResetProgress")] internal static class RunManagerResetProgressPatch { private static void Postfix() { MapValueTrackerUpgradeManager.ResetProgress(); } } } 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")] [HarmonyPostfix] public static void GenerateDonePostfix() { MapValueTracker.ResetValues(); MapValueTracker.Logger.LogDebug((object)"Generation done. Computing initial map items."); MapValueTracker.CheckForItems(); MapValueTracker.totalValueInit = MapValueTracker.totalValue; MapValueTracker.Logger.LogDebug((object)("Generation done. Now val is " + MapValueTracker.totalValue + ". Init Value: " + MapValueTracker.totalValueInit)); } } [HarmonyPatch(typeof(PhysGrabObjectImpactDetector), "BreakRPC")] internal static class BreakRPCPatch { private static void Prefix(PhysGrabObjectImpactDetector __instance, out float __state) { __state = (((Object)(object)__instance != (Object)null && (Object)(object)__instance.valuableObject != (Object)null) ? __instance.valuableObject.dollarValueCurrent : 0f); } private static void Postfix(PhysGrabObjectImpactDetector __instance, bool _loseValue, float __state) { if (_loseValue && !((Object)(object)__instance == (Object)null) && SemiFunc.RunIsLevel()) { ValuableObject valuableObject = __instance.valuableObject; if (!((Object)(object)valuableObject == (Object)null)) { float num = Mathf.Max(0f, __state - valuableObject.dollarValueCurrent); MapValueTracker.totalValue = Mathf.Max(0f, MapValueTracker.totalValue - num); MapValueTracker.Logger.LogDebug((object)$"BreakRPC - {((Object)valuableObject).name} lost {num} (now {valuableObject.dollarValueCurrent}). Map Remaining: {MapValueTracker.totalValue}"); } } } } [HarmonyPatch(typeof(PhysGrabObject), "DestroyPhysGrabObjectRPC")] internal static class DestroyPhysGrabObjectPatch { private static void Postfix(PhysGrabObject __instance) { if (!SemiFunc.RunIsLevel() || (Object)(object)__instance == (Object)null) { return; } int instanceID = ((Object)__instance).GetInstanceID(); if (!MapValueTracker.destroyedIds.Add(instanceID) || MapValueTracker.absorbedInBoxIds.Remove(instanceID)) { return; } ItemValuableBox component = ((Component)__instance).GetComponent<ItemValuableBox>(); if ((Object)(object)component != (Object)null) { if (component.CurrentValue > 0f) { MapValueTracker.totalValue = Mathf.Max(0f, MapValueTracker.totalValue - component.CurrentValue); MapValueTracker.Logger.LogDebug((object)$"Valuable Box destroyed/extracted! Val: {component.CurrentValue}. Map Remaining: {MapValueTracker.totalValue}"); } return; } ValuableObject component2 = ((Component)__instance).GetComponent<ValuableObject>(); if ((Object)(object)component2 != (Object)null && component2.dollarValueCurrent > 0f) { MapValueTracker.totalValue = Mathf.Max(0f, MapValueTracker.totalValue - component2.dollarValueCurrent); MapValueTracker.Logger.LogDebug((object)$"Destroyed Valuable Object! {((Object)component2).name} Val: {component2.dollarValueCurrent}. Map Remaining: {MapValueTracker.totalValue}"); } } } [HarmonyPatch(typeof(ItemValuableBox), "StartAbsorbLocal")] internal static class ItemValuableBoxAbsorbPatch { private static void Prefix(PhysGrabObject target) { if ((Object)(object)target != (Object)null) { MapValueTracker.absorbedInBoxIds.Add(((Object)target).GetInstanceID()); } } } [HarmonyPatch(typeof(RoundDirector))] public static class RoundDirectorPatches { private static float lastDisplayedValue; private static bool lastStartingValueOnly; static RoundDirectorPatches() { lastDisplayedValue = -1f; lastStartingValueOnly = false; Configuration.OnUIPositionChanged += UpdateCoordinates; } public static void UpdateCoordinates() { if ((Object)(object)MapValueTracker.textInstance != (Object)null) { RectTransform component = MapValueTracker.textInstance.GetComponent<RectTransform>(); if ((Object)(object)component != (Object)null) { SetCoordinates(component); } } } private static void SetCoordinates(RectTransform component) { //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_004a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: 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_00ca: Unknown result type (might be due to invalid IL or missing references) 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); Vector2 offsetMin = (component.offsetMax = (Vector2)(Configuration.UIPosition.Value switch { Positions.LowerRight => new Vector2(0f, 125f), Positions.BottomRight => new Vector2(0f, 0f), Positions.Custom => Configuration.CustomPositionCoords.Value, _ => new Vector2(0f, 225f), })); component.offsetMin = offsetMin; } [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_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Expected O, but got Unknown //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) if (!SemiFunc.RunIsLevel()) { if ((Object)(object)MapValueTracker.textInstance != (Object)null && MapValueTracker.textInstance.activeSelf) { MapValueTracker.textInstance.SetActive(false); } return; } RoundDirector instance = RoundDirector.instance; if ((Object)(object)instance == (Object)null) { return; } int extractionHaulGoal = instance.extractionHaulGoal; bool allExtractionPointsCompleted = instance.allExtractionPointsCompleted; 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("Value HUD"); MapValueTracker.textInstance.SetActive(false); MapValueTracker.valueText = MapValueTracker.textInstance.AddComponent<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>()); lastDisplayedValue = -1f; } } else if (!MapValueTrackerUpgradeManager.IsTrackerUnlocked()) { MapValueTracker.textInstance.SetActive(false); } else if ((Object)(object)MapValueTracker.valueText != (Object)null && (extractionHaulGoal > 0 || !allExtractionPointsCompleted)) { float num = (Configuration.StartingValueOnly.Value ? MapValueTracker.totalValueInit : MapValueTracker.totalValue); if (Mathf.Abs(num - lastDisplayedValue) > 0.01f || lastStartingValueOnly != Configuration.StartingValueOnly.Value) { lastDisplayedValue = num; lastStartingValueOnly = Configuration.StartingValueOnly.Value; ((TMP_Text)MapValueTracker.valueText).SetText("Map: $" + num.ToString("N0"), true); } bool flag = ((Object)(object)MapToolController.instance != (Object)null && MapToolController.instance.mapToggled) || SemiFunc.InputHold((InputKey)8); switch (Configuration.DisplayMode.Value) { case DisplayModes.AlwaysOn: MapValueTracker.textInstance.SetActive(true); break; case DisplayModes.ValueRatio: { bool flag2 = extractionHaulGoal > 0 && MapValueTracker.totalValue / (float)extractionHaulGoal <= Configuration.ValueRatio.Value; MapValueTracker.textInstance.SetActive(flag2 || flag); break; } default: MapValueTracker.textInstance.SetActive(flag); break; } } else { MapValueTracker.textInstance.SetActive(false); } } } internal static class ValuableSpawnAccounting { public static bool LevelGenerated { get { if ((Object)(object)LevelGenerator.Instance != (Object)null) { return LevelGenerator.Instance.Generated; } return false; } } public static void Add(ValuableObject vo, float value, string source) { MapValueTracker.totalValue += value; MapValueTracker.Logger.LogDebug((object)$"Spawned Valuable Object ({source})! {((Object)vo).name} Val: {value}. Total Val: {MapValueTracker.totalValue}"); } } [HarmonyPatch(typeof(ValuableObject), "DollarValueSetLogic")] internal static class DollarValueSetLogicPatch { private static void Prefix(ValuableObject __instance, out bool __state) { __state = __instance.dollarValueSet; } private static void Postfix(ValuableObject __instance, bool __state) { if (!__state && __instance.dollarValueSet && SemiFunc.IsMasterClientOrSingleplayer() && ValuableSpawnAccounting.LevelGenerated) { ValuableSpawnAccounting.Add(__instance, __instance.dollarValueCurrent, "Logic"); } } } [HarmonyPatch(typeof(ValuableObject), "DollarValueSetRPC")] internal static class DollarValueSetRPCPatch { private static void Prefix(ValuableObject __instance, out bool __state) { __state = __instance.dollarValueSet; } private static void Postfix(ValuableObject __instance, float value, bool __state) { if (!__state && __instance.dollarValueSet && ValuableSpawnAccounting.LevelGenerated) { ValuableSpawnAccounting.Add(__instance, value, "RPC"); } } } } namespace MapValueTracker.Config { public enum DisplayModes { AlwaysOn, OnMapKey, ValueRatio } public enum Positions { Default, LowerRight, BottomRight, Custom } internal class Configuration { public static ConfigEntry<DisplayModes> DisplayMode; public static ConfigEntry<float> ValueRatio; public static ConfigEntry<bool> StartingValueOnly; public static ConfigEntry<Positions> UIPosition; public static ConfigEntry<Vector2> CustomPositionCoords; public static ConfigEntry<bool> RequireShopUpgrade; public static ConfigEntry<bool> TeamWideUnlock; public static event Action OnUIPositionChanged; public static void Init(ConfigFile config) { //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Expected O, but got Unknown //IL_00db: Unknown result type (might be due to invalid IL or missing references) config.SaveOnConfigSet = false; RequireShopUpgrade = config.Bind<bool>("Shop Progression", "RequireShopUpgrade", false, "If true, the Map Value Tracker will only be visible after purchasing the Map Value Tracker upgrade from the Shop ($4,000 - $7,000). Default is false."); TeamWideUnlock = config.Bind<bool>("Shop Progression", "TeamWideUnlock", true, "If true and RequireShopUpgrade is enabled, purchasing the upgrade unlocks the tracker for all players on the team. Default is true."); DisplayMode = config.Bind<DisplayModes>("Display", "DisplayMode", DisplayModes.AlwaysOn, "How the tracker is displayed on screen:\n- AlwaysOn: Always visible on HUD.\n- OnMapKey: Only visible while holding or toggling the Map key (Tab by default).\n- ValueRatio: Automatically appears when remaining map value reaches or drops below the ValueRatio threshold (also appears while holding Map key)."); ValueRatio = config.Bind<float>("Display", "ValueRatio", 2f, new ConfigDescription("Ratio of remaining map value to extraction goal. Used when DisplayMode is set to ValueRatio. (e.g. 2.0 = displays when remaining value is <= 2x the goal).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 5f), Array.Empty<object>())); StartingValueOnly = config.Bind<bool>("Display", "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."); UIPosition = config.Bind<Positions>("Position", "UIPosition", Positions.Default, "Preset position of the Value Tracker UI element on screen."); CustomPositionCoords = config.Bind<Vector2>("Position", "CustomPositionCoords", new Vector2(0f, 0f), "Custom X,Y coordinates when UIPosition is set to Custom. Bottom-right corner is (0, 0). Default is (0, 225)."); MigrateOldConfig(config); UIPosition.SettingChanged += delegate { Configuration.OnUIPositionChanged?.Invoke(); }; CustomPositionCoords.SettingChanged += delegate { Configuration.OnUIPositionChanged?.Invoke(); }; config.Save(); config.SaveOnConfigSet = true; } private static void MigrateOldConfig(ConfigFile cfg) { //IL_01af: Unknown result type (might be due to invalid IL or missing references) PropertyInfo propertyInfo = AccessTools.Property(typeof(ConfigFile), "OrphanedEntries"); if (propertyInfo == null || !(propertyInfo.GetValue(cfg) is Dictionary<ConfigDefinition, string> { Count: not 0 } dictionary)) { return; } bool flag = true; bool flag2 = false; bool flag3 = false; foreach (KeyValuePair<ConfigDefinition, string> item in dictionary) { string section = item.Key.Section; string key = item.Key.Key; string value = item.Value; bool result2; bool result3; float result4; Positions result5; if (section == "Default" && key == "AlwaysOn" && bool.TryParse(value, out var result)) { flag = result; flag3 = true; } else if (section == "Default" && key == "UseValueRatio" && bool.TryParse(value, out result2)) { flag2 = result2; } else if (section == "Default" && key == "StartingValueOnly" && bool.TryParse(value, out result3)) { StartingValueOnly.Value = result3; } else if (section == "Default" && key == "ValueRatio" && float.TryParse(value, out result4)) { ValueRatio.Value = result4; } else if (section == "UIPosition" && key == "UIPosition" && Enum.TryParse<Positions>(value, out result5)) { UIPosition.Value = result5; } else if (section == "UIPosition" && key == "CustomPositionCoords") { try { CustomPositionCoords.Value = (Vector2)TomlTypeConverter.ConvertToValue(value, typeof(Vector2)); } catch { } } } if (flag3) { if (flag) { DisplayMode.Value = DisplayModes.AlwaysOn; } else if (flag2) { DisplayMode.Value = DisplayModes.ValueRatio; } else { DisplayMode.Value = DisplayModes.OnMapKey; } } dictionary.Clear(); } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }