Decompiled source of ExpandedHUD v1.3.0

BepInEx/plugins/ExpandedHUD.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
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.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Pigeon;
using Pigeon.Movement;
using TMPro;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("ExpandedHUD")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.0.0.0")]
[assembly: AssemblyInformationalVersion("0.0.0-alpha.0.8+9a85cfa9ae3bf110279278784d1abf1a8e8b7c4e")]
[assembly: AssemblyProduct("ExpandedHUD")]
[assembly: AssemblyTitle("ExpandedHUD")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
[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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
public class Altimeter
{
	private ConfigEntry<bool> enableAltimeterHUD;

	private TextMeshProUGUI altitudeText;

	private GameObject altitudeHudContainer;

	private const float RaycastMaxDistance = 1000f;

	private static readonly Color altitudeGreen = new Color(1f / 85f, 0.6745098f, 0.07450981f);

	private readonly ConfigFile configFile;

	private readonly Harmony harmony;

	public static Altimeter Instance { get; private set; }

	public bool IsActive
	{
		get
		{
			if ((Object)(object)altitudeHudContainer != (Object)null)
			{
				return altitudeHudContainer.activeSelf;
			}
			return false;
		}
	}

	public Vector2 GetSize
	{
		get
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			GameObject obj = altitudeHudContainer;
			if (obj == null)
			{
				return Vector2.zero;
			}
			return obj.GetComponent<RectTransform>().sizeDelta;
		}
	}

	public Altimeter(ConfigFile configFile, Harmony harmony)
	{
		this.configFile = configFile;
		this.harmony = harmony;
		Instance = this;
		enableAltimeterHUD = configFile.Bind<bool>("General", "EnableAltimeterHUD", true, "Enables the Altimeter HUD display showing player altitude above ground.");
		enableAltimeterHUD.SettingChanged += OnEnableAltimeterHUDChanged;
	}

	public void UpdateHudVisibility()
	{
		if ((Object)(object)altitudeHudContainer != (Object)null)
		{
			altitudeHudContainer.SetActive(enableAltimeterHUD.Value);
		}
	}

	private void OnEnableAltimeterHUDChanged(object sender, EventArgs e)
	{
		if (!enableAltimeterHUD.Value && (Object)(object)altitudeHudContainer != (Object)null)
		{
			Object.Destroy((Object)(object)altitudeHudContainer);
			altitudeHudContainer = null;
			altitudeText = null;
		}
		UpdateHudVisibility();
	}

	private void CreateAltimeterHUD()
	{
		//IL_005c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0066: Expected O, but got Unknown
		//IL_008e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a3: 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_00cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00db: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e1: Expected O, but got Unknown
		//IL_011a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0157: Unknown result type (might be due to invalid IL or missing references)
		//IL_0162: Unknown result type (might be due to invalid IL or missing references)
		//IL_0176: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)altitudeHudContainer != (Object)null) && !((Object)(object)Player.LocalPlayer == (Object)null) && !((Object)(object)Player.LocalPlayer.PlayerLook == (Object)null) && !((Object)(object)Player.LocalPlayer.PlayerLook.Reticle == (Object)null))
		{
			RectTransform reticle = Player.LocalPlayer.PlayerLook.Reticle;
			altitudeHudContainer = new GameObject("AltimeterHUD");
			altitudeHudContainer.transform.SetParent((Transform)(object)reticle, false);
			RectTransform obj = altitudeHudContainer.AddComponent<RectTransform>();
			obj.anchorMin = new Vector2(0.2f, 0.95f);
			obj.anchorMax = new Vector2(0.2f, 0.95f);
			obj.anchoredPosition = new Vector2(0f, 0f);
			obj.sizeDelta = new Vector2(300f, 25f);
			GameObject val = new GameObject("AltitudeText");
			val.transform.SetParent(altitudeHudContainer.transform, false);
			altitudeText = val.AddComponent<TextMeshProUGUI>();
			((TMP_Text)altitudeText).fontSize = 18f;
			((Graphic)altitudeText).color = Color.white;
			((TMP_Text)altitudeText).enableWordWrapping = false;
			((TMP_Text)altitudeText).alignment = (TextAlignmentOptions)513;
			((TMP_Text)altitudeText).verticalAlignment = (VerticalAlignmentOptions)512;
			RectTransform component = val.GetComponent<RectTransform>();
			component.anchorMin = Vector2.zero;
			component.anchorMax = Vector2.one;
			component.anchoredPosition = new Vector2(0f, 0f);
			UpdateHudVisibility();
		}
	}

	public void Update()
	{
		//IL_0085: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_0114: Unknown result type (might be due to invalid IL or missing references)
		//IL_0101: Unknown result type (might be due to invalid IL or missing references)
		if (!enableAltimeterHUD.Value)
		{
			return;
		}
		if ((Object)(object)altitudeHudContainer == (Object)null)
		{
			CreateAltimeterHUD();
		}
		else if (!((Object)(object)altitudeText == (Object)null) && !((Object)(object)Player.LocalPlayer == (Object)null))
		{
			float num = CalculateAltitude();
			if (num < 1.3f)
			{
				((TMP_Text)altitudeText).text = "On Ground";
			}
			else if (num >= 1000f)
			{
				((TMP_Text)altitudeText).text = "Too High";
			}
			else
			{
				((TMP_Text)altitudeText).text = $"Altitude: <color=#{ColorUtility.ToHtmlStringRGB(altitudeGreen)}>{num:F1}</color> m";
			}
			if ((Object)(object)altitudeHudContainer != (Object)null)
			{
				RectTransform component = altitudeHudContainer.GetComponent<RectTransform>();
				float num2 = ((Speedometer.Instance != null && Speedometer.Instance.IsActive) ? (0f - Speedometer.Instance.GetSize.y) : 0f) + ((Carnometer.Instance != null && Carnometer.Instance.IsActive) ? (0f - Carnometer.Instance.GetSize.y) : 0f);
				component.anchoredPosition = new Vector2(0f, num2);
			}
		}
	}

	private float CalculateAltitude()
	{
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: 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_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_0059: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)Player.LocalPlayer == (Object)null)
		{
			return 0f;
		}
		Vector3 val = ((Component)Player.LocalPlayer).transform.position + Vector3.up * 0.1f;
		Vector3 down = Vector3.down;
		RaycastHit[] array = Physics.RaycastAll(val, down, 1000f);
		float num = float.MaxValue;
		RaycastHit[] array2 = array;
		for (int i = 0; i < array2.Length; i++)
		{
			RaycastHit val2 = array2[i];
			if ((Object)(object)((Component)((RaycastHit)(ref val2)).collider).gameObject != (Object)(object)((Component)Player.LocalPlayer).gameObject && !((RaycastHit)(ref val2)).collider.isTrigger)
			{
				num = Mathf.Min(num, ((RaycastHit)(ref val2)).distance);
			}
		}
		if (!(num < float.MaxValue))
		{
			return 1000f;
		}
		return num;
	}

	public void OnDestroy()
	{
		if ((Object)(object)altitudeHudContainer != (Object)null)
		{
			Object.Destroy((Object)(object)altitudeHudContainer);
		}
	}
}
public class Carnometer
{
	internal class DPSPatches
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(PlayerData), "OnLocalPlayerDamageTarget")]
		private static bool PrefixDamage(in DamageCallbackData data)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: 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_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: 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)
			if (Instance == null)
			{
				return true;
			}
			if (data.damageData.damage > 0f)
			{
				Instance.totalDamage += data.damageData.damage;
				TargetType type = ((IFollowable)data.target).Type;
				if ((type & 1) != 0 || (type & 2) != 0)
				{
					Instance.damageQueue.Enqueue((Time.time, data.damageData.damage));
				}
				if (((DamageCallbackData)(ref data)).KilledTarget)
				{
					Instance.totalKills++;
					if (typeof(EnemyCore).IsAssignableFrom(((object)data.target).GetType()))
					{
						Instance.totalCoresKilled++;
					}
				}
			}
			return true;
		}
	}

	internal class MissionPatches
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(MissionManager), "SpawnHUD")]
		private static void MissionStart()
		{
			if (Instance != null)
			{
				Instance.totalDamage = 0f;
				Instance.totalKills = 0;
				Instance.totalCoresKilled = 0;
				Instance.damageQueue.Clear();
				Instance.missionStartTime = Time.time;
			}
		}
	}

	private ConfigEntry<bool> enableDamageMeterHUD;

	private ConfigEntry<float> dpsWindowSeconds;

	private GameObject damageMeterHudContainer;

	private TextMeshProUGUI totalDamageText;

	private TextMeshProUGUI fiveSecDamageText;

	private TextMeshProUGUI totalKillsText;

	private TextMeshProUGUI totalCoresText;

	public Queue<(float time, float damage)> damageQueue = new Queue<(float, float)>();

	public float totalDamage;

	public int totalKills;

	public int totalCoresKilled;

	public float missionStartTime;

	private static readonly Color rose = new Color(0.8901961f, 12f / 85f, 0.16862746f);

	private readonly ConfigFile configFile;

	private readonly Harmony harmony;

	public static Carnometer Instance { get; private set; }

	public bool IsActive
	{
		get
		{
			if ((Object)(object)damageMeterHudContainer != (Object)null)
			{
				return damageMeterHudContainer.activeSelf;
			}
			return false;
		}
	}

	public Vector2 GetSize
	{
		get
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			GameObject obj = damageMeterHudContainer;
			if (obj == null)
			{
				return Vector2.zero;
			}
			return obj.GetComponent<RectTransform>().sizeDelta;
		}
	}

	public Carnometer(ConfigFile configFile, Harmony harmony)
	{
		this.configFile = configFile;
		this.harmony = harmony;
		Instance = this;
		enableDamageMeterHUD = configFile.Bind<bool>("General", "EnableDamageMeterHUD", true, "Enable or disable the damage meter functionality.");
		enableDamageMeterHUD.SettingChanged += OnEnableDamageMeterHUDChanged;
		dpsWindowSeconds = configFile.Bind<float>("General", "DPSWindowSeconds", 5f, "Time window (in seconds) for calculating DPS. Higher values smooth out spikes.");
		harmony.PatchAll(typeof(DPSPatches));
		harmony.PatchAll(typeof(MissionPatches));
		missionStartTime = Time.time;
	}

	public void UpdateHudVisibility()
	{
		if ((Object)(object)damageMeterHudContainer != (Object)null)
		{
			damageMeterHudContainer.SetActive(enableDamageMeterHUD.Value);
		}
	}

	private void OnEnableDamageMeterHUDChanged(object sender, EventArgs e)
	{
		UpdateHudVisibility();
	}

	private void CreateDamageMeterHUD()
	{
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0059: Expected O, but got Unknown
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		//IL_0096: 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_00bf: 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_00d4: Expected O, but got Unknown
		//IL_010d: Unknown result type (might be due to invalid IL or missing references)
		//IL_014a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0155: Unknown result type (might be due to invalid IL or missing references)
		//IL_0169: Unknown result type (might be due to invalid IL or missing references)
		//IL_0178: Unknown result type (might be due to invalid IL or missing references)
		//IL_017e: Expected O, but got Unknown
		//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_0213: 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_0228: Expected O, but got Unknown
		//IL_0261: Unknown result type (might be due to invalid IL or missing references)
		//IL_029e: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_02cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d3: Expected O, but got Unknown
		//IL_030e: Unknown result type (might be due to invalid IL or missing references)
		//IL_034c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0357: Unknown result type (might be due to invalid IL or missing references)
		//IL_036b: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)damageMeterHudContainer != (Object)null) && !((Object)(object)Player.LocalPlayer.PlayerLook == (Object)null) && !((Object)(object)Player.LocalPlayer.PlayerLook.Reticle == (Object)null))
		{
			RectTransform reticle = Player.LocalPlayer.PlayerLook.Reticle;
			damageMeterHudContainer = new GameObject("DamageMeterHUD");
			damageMeterHudContainer.transform.SetParent((Transform)(object)reticle, false);
			RectTransform obj = damageMeterHudContainer.AddComponent<RectTransform>();
			obj.anchorMin = new Vector2(0.2f, 0.95f);
			obj.anchorMax = new Vector2(0.2f, 0.95f);
			obj.anchoredPosition = new Vector2(0f, 0f);
			obj.sizeDelta = new Vector2(300f, 100f);
			GameObject val = new GameObject("TotalDamageText");
			val.transform.SetParent(damageMeterHudContainer.transform, false);
			totalDamageText = val.AddComponent<TextMeshProUGUI>();
			((TMP_Text)totalDamageText).fontSize = 18f;
			((Graphic)totalDamageText).color = Color.white;
			((TMP_Text)totalDamageText).enableWordWrapping = false;
			((TMP_Text)totalDamageText).alignment = (TextAlignmentOptions)513;
			((TMP_Text)totalDamageText).verticalAlignment = (VerticalAlignmentOptions)512;
			RectTransform component = val.GetComponent<RectTransform>();
			component.anchorMin = Vector2.zero;
			component.anchorMax = Vector2.one;
			component.anchoredPosition = new Vector2(0f, 0f);
			GameObject val2 = new GameObject("FiveSecDamageText");
			val2.transform.SetParent(damageMeterHudContainer.transform, false);
			fiveSecDamageText = val2.AddComponent<TextMeshProUGUI>();
			((TMP_Text)fiveSecDamageText).fontSize = 18f;
			((Graphic)fiveSecDamageText).color = Color.white;
			((TMP_Text)fiveSecDamageText).enableWordWrapping = false;
			((TMP_Text)fiveSecDamageText).alignment = (TextAlignmentOptions)513;
			((TMP_Text)fiveSecDamageText).verticalAlignment = (VerticalAlignmentOptions)512;
			RectTransform component2 = val2.GetComponent<RectTransform>();
			component2.anchorMin = Vector2.zero;
			component2.anchorMax = Vector2.one;
			component2.anchoredPosition = new Vector2(0f, -25f);
			GameObject val3 = new GameObject("TotalKillsText");
			val3.transform.SetParent(damageMeterHudContainer.transform, false);
			totalKillsText = val3.AddComponent<TextMeshProUGUI>();
			((TMP_Text)totalKillsText).fontSize = 18f;
			((Graphic)totalKillsText).color = Color.white;
			((TMP_Text)totalKillsText).enableWordWrapping = false;
			((TMP_Text)totalKillsText).alignment = (TextAlignmentOptions)513;
			((TMP_Text)totalKillsText).verticalAlignment = (VerticalAlignmentOptions)512;
			RectTransform component3 = val3.GetComponent<RectTransform>();
			component3.anchorMin = Vector2.zero;
			component3.anchorMax = Vector2.one;
			component3.anchoredPosition = new Vector2(0f, -50f);
			GameObject val4 = new GameObject("TotalCoresText");
			val4.transform.SetParent(damageMeterHudContainer.transform, false);
			totalCoresText = val4.AddComponent<TextMeshProUGUI>();
			((TMP_Text)totalCoresText).fontSize = 18f;
			((Graphic)totalCoresText).color = Color.white;
			((TMP_Text)totalCoresText).enableWordWrapping = false;
			((TMP_Text)totalCoresText).alignment = (TextAlignmentOptions)513;
			((TMP_Text)totalCoresText).verticalAlignment = (VerticalAlignmentOptions)512;
			RectTransform component4 = val4.GetComponent<RectTransform>();
			component4.anchorMin = Vector2.zero;
			component4.anchorMax = Vector2.one;
			component4.anchoredPosition = new Vector2(0f, -75f);
			UpdateHudVisibility();
		}
	}

	public void Update()
	{
		if (!enableDamageMeterHUD.Value || (Object)(object)Player.LocalPlayer == (Object)null)
		{
			return;
		}
		if ((Object)(object)damageMeterHudContainer == (Object)null)
		{
			CreateDamageMeterHUD();
			return;
		}
		float time = Time.time;
		float value = dpsWindowSeconds.Value;
		while (damageQueue.Count > 0 && damageQueue.Peek().time < time - value)
		{
			damageQueue.Dequeue();
		}
		float num = 0f;
		foreach (var item in damageQueue)
		{
			num += item.damage;
		}
		float num2 = ((damageQueue.Count > 0) ? (num / value) : 0f);
		float num3 = Time.time - missionStartTime;
		float num4 = ((num3 > 0f) ? (totalDamage / num3) : 0f);
		float num5 = ((num3 > 0f) ? ((float)totalKills / num3) : 0f);
		float num6 = ((num3 > 0f) ? ((float)totalCoresKilled / num3) : 0f);
		((TMP_Text)totalDamageText).text = $"Total Damage: <color=red>{totalDamage:F0}</color> (<color=red>{num4:F1}</color>/s)";
		((TMP_Text)fiveSecDamageText).text = $"Last 5sec Damage: <color=red>{num:F0}</color> (<color=red>{num2:F1}</color>/s)";
		((TMP_Text)totalKillsText).text = $"Targets Killed: <color=red>{totalKills}</color> (<color=red>{num5:F1}</color>/s)";
		((TMP_Text)totalCoresText).text = $"Cores Killed: <color=red>{totalCoresKilled}</color> (<color=red>{num6:F1}</color>/s)";
	}

	public void OnDestroy()
	{
		if ((Object)(object)damageMeterHudContainer != (Object)null)
		{
			Object.Destroy((Object)(object)damageMeterHudContainer);
		}
		harmony.UnpatchSelf();
	}
}
public class ConsumableHotkeys
{
	private class ConsumableStatus
	{
		public bool IsActive { get; set; }

		public int UsesRemaining { get; set; } = -1;


		public int MaxUses { get; set; } = -1;

	}

	private const string PersonalAccessTokenName = "Personal Access Token";

	private const string PremiumLootLicenseName = "Premium Loot License";

	private const string BootlegReplicatorName = "Bootleg Replicator";

	private const string ClearanceCertificateName = "Clearance Certificate";

	private const int ClearanceCertificateMaxUses = 5;

	private ConfigEntry<bool> enableHotkeys;

	private ConfigEntry<bool> enableHUD;

	private ConfigEntry<Key> personalAccessTokenHotkey;

	private ConfigEntry<Key> premiumLootLicenseHotkey;

	private ConfigEntry<Key> bootlegReplicatorHotkey;

	private ConfigEntry<Key> clearanceCertificateHotkey;

	private TextMeshProUGUI hudText;

	private GameObject hudContainer;

	private Dictionary<string, ConsumableStatus> consumableStatuses;

	private readonly ConfigFile configFile;

	private readonly Harmony harmony;

	public static ConsumableHotkeys Instance { get; private set; }

	public ConsumableHotkeys(ConfigFile configFile, Harmony harmony)
	{
		this.configFile = configFile;
		this.harmony = harmony;
		Instance = this;
		try
		{
			SetupConfig();
			InitializeStatuses();
			SetupConfigWatcher();
		}
		catch (Exception ex)
		{
			SparrohPlugin.Logger.LogError((object)("Failed to initialize ConsumableHotkeys: " + ex.Message));
		}
	}

	private void SetupConfig()
	{
		enableHotkeys = configFile.Bind<bool>("Consumables", "EnableHotkeys", true, "Enables hotkey functionality for consumables.");
		enableHUD = configFile.Bind<bool>("Consumables", "EnableHUD", true, "Enables the HUD display for consumable statuses.");
		personalAccessTokenHotkey = configFile.Bind<Key>("Consumables", "PersonalAccessToken_Hotkey", (Key)39, "Hotkey for Personal Access Token.");
		premiumLootLicenseHotkey = configFile.Bind<Key>("Consumables", "PremiumLootLicense_Hotkey", (Key)22, "Hotkey for Premium Loot License.");
		bootlegReplicatorHotkey = configFile.Bind<Key>("Consumables", "BootlegReplicator_Hotkey", (Key)35, "Hotkey for Bootleg Replicator.");
		clearanceCertificateHotkey = configFile.Bind<Key>("Consumables", "ClearanceCertificate_Hotkey", (Key)24, "Hotkey for Clearance Certificate.");
	}

	private void InitializeStatuses()
	{
		consumableStatuses = new Dictionary<string, ConsumableStatus>
		{
			{
				"Personal Access Token",
				new ConsumableStatus()
			},
			{
				"Premium Loot License",
				new ConsumableStatus()
			},
			{
				"Bootleg Replicator",
				new ConsumableStatus()
			},
			{
				"Clearance Certificate",
				new ConsumableStatus
				{
					MaxUses = 5,
					UsesRemaining = 5
				}
			}
		};
	}

	private void Start()
	{
		if (enableHUD.Value)
		{
			CreateHUD();
		}
		UpdateHudVisibility();
	}

	public void UpdateHudVisibility()
	{
		if ((Object)(object)hudContainer != (Object)null)
		{
			hudContainer.SetActive(enableHUD.Value);
		}
	}

	private void CreateHUD()
	{
		//IL_005c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0066: Expected O, but got Unknown
		//IL_008e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d7: Expected O, but got Unknown
		//IL_0110: Unknown result type (might be due to invalid IL or missing references)
		//IL_014d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0158: Unknown result type (might be due to invalid IL or missing references)
		//IL_0162: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)hudContainer != (Object)null) && !((Object)(object)Player.LocalPlayer == (Object)null) && !((Object)(object)Player.LocalPlayer.PlayerLook == (Object)null) && !((Object)(object)Player.LocalPlayer.PlayerLook.Reticle == (Object)null))
		{
			RectTransform reticle = Player.LocalPlayer.PlayerLook.Reticle;
			hudContainer = new GameObject("TicketStatusHUD");
			hudContainer.transform.SetParent((Transform)(object)reticle, false);
			RectTransform obj = hudContainer.AddComponent<RectTransform>();
			obj.anchorMin = new Vector2(0.4f, 0.85f);
			obj.anchorMax = new Vector2(0.4f, 0.85f);
			obj.anchoredPosition = Vector2.zero;
			obj.sizeDelta = new Vector2(400f, 100f);
			GameObject val = new GameObject("StatusText");
			val.transform.SetParent(hudContainer.transform, false);
			hudText = val.AddComponent<TextMeshProUGUI>();
			((TMP_Text)hudText).fontSize = 16f;
			((Graphic)hudText).color = Color.white;
			((TMP_Text)hudText).enableWordWrapping = false;
			((TMP_Text)hudText).alignment = (TextAlignmentOptions)513;
			((TMP_Text)hudText).verticalAlignment = (VerticalAlignmentOptions)256;
			RectTransform component = val.GetComponent<RectTransform>();
			component.anchorMin = Vector2.zero;
			component.anchorMax = Vector2.one;
			component.anchoredPosition = Vector2.zero;
			UpdateHudVisibility();
		}
	}

	public void Update()
	{
		try
		{
			if (enableHUD.Value)
			{
				if ((Object)(object)hudContainer == (Object)null)
				{
					CreateHUD();
				}
				else if (!((Object)(object)hudText == (Object)null) && consumableStatuses != null)
				{
					UpdateHUDText();
					CheckHotkeys();
				}
			}
		}
		catch (Exception ex)
		{
			SparrohPlugin.Logger.LogError((object)("Error in ConsumableHotkeys.Update(): " + ex.Message));
		}
	}

	private void UpdateHUDText()
	{
		string text = "";
		foreach (KeyValuePair<string, ConsumableStatus> consumableStatus in consumableStatuses)
		{
			string text2;
			string text3;
			if (consumableStatus.Key.Contains("Clearance Certificate"))
			{
				int flag = PlayerData.Instance.GetFlag("dur_drops");
				text2 = ((flag == 0) ? "Inactive" : $"{flag}/{consumableStatus.Value.MaxUses} Uses");
				text3 = ((flag > 0) ? "green" : "red");
			}
			else
			{
				text2 = (consumableStatus.Value.IsActive ? "Active" : "Inactive");
				text3 = (consumableStatus.Value.IsActive ? "green" : "red");
			}
			int currentItemCount = GetCurrentItemCount(consumableStatus.Key);
			text += $"<color={text3}>{consumableStatus.Key}: {text2} ({currentItemCount})</color>\n";
		}
		((TMP_Text)hudText).text = text.Trim();
	}

	private int GetCurrentItemCount(string itemName)
	{
		PlayerResource[] playerResources = Global.Instance.PlayerResources;
		foreach (PlayerResource val in playerResources)
		{
			if (val.Name == itemName)
			{
				return PlayerData.Instance.GetResource(val);
			}
		}
		return 0;
	}

	private void CheckHotkeys()
	{
		//IL_0020: 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_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0065: Unknown result type (might be due to invalid IL or missing references)
		if (enableHotkeys.Value)
		{
			Keyboard current = Keyboard.current;
			if (current != null)
			{
				CheckHotkey(current, personalAccessTokenHotkey.Value, "Personal Access Token");
				CheckHotkey(current, premiumLootLicenseHotkey.Value, "Premium Loot License");
				CheckHotkey(current, bootlegReplicatorHotkey.Value, "Bootleg Replicator");
				CheckHotkey(current, clearanceCertificateHotkey.Value, "Clearance Certificate");
			}
		}
	}

	private void CheckHotkey(Keyboard keyboard, Key key, string consumableName)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		if (((ButtonControl)keyboard[key]).wasPressedThisFrame)
		{
			UseConsumable(consumableName);
		}
	}

	private void UseConsumable(string name)
	{
		TryActivateConsumableByName(name);
		UpdateConsumableStatus(name);
	}

	private void TryActivateConsumableByName(string name)
	{
		StorageWindow[] array = Object.FindObjectsOfType<StorageWindow>();
		foreach (StorageWindow storageWindow in array)
		{
			if (TryActivateFromStorageWindow(storageWindow, name))
			{
				return;
			}
		}
		TryDirectActivation(name);
	}

	private bool TryActivateFromStorageWindow(StorageWindow storageWindow, string itemName)
	{
		try
		{
			FieldInfo field = ((object)storageWindow).GetType().GetField("slots", BindingFlags.Instance | BindingFlags.NonPublic);
			if (field == null)
			{
				return false;
			}
			if (!(field.GetValue(storageWindow) is StorageSlot[] array))
			{
				return false;
			}
			StorageSlot[] array2 = array;
			InputAction val4 = default(InputAction);
			string text = default(string);
			foreach (StorageSlot val in array2)
			{
				object? obj = ((object)val).GetType().GetField("item", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(val);
				IInventoryItem val2 = (IInventoryItem)((obj is IInventoryItem) ? obj : null);
				PlayerResource val3 = (PlayerResource)(object)((val2 is PlayerResource) ? val2 : null);
				if (val2 == null || !((Object)(object)val3 != (Object)null) || !(val3.Name == itemName) || val2.ItemCount <= 0 || !((IHoverInfo)val2).GetPrimaryBinding(ref val4, ref text))
				{
					continue;
				}
				FieldInfo field2 = ((object)val3).GetType().GetField("onPrimaryAction", BindingFlags.Instance | BindingFlags.NonPublic);
				if (field2 != null)
				{
					object? value = field2.GetValue(val3);
					UnityEvent val5 = (UnityEvent)((value is UnityEvent) ? value : null);
					if (val5 != null)
					{
						val5.Invoke();
						return true;
					}
				}
			}
		}
		catch (Exception ex)
		{
			SparrohPlugin.Logger.LogError((object)("Error activating " + itemName + " from storage: " + ex.Message));
		}
		return false;
	}

	private void TryDirectActivation(string itemName)
	{
		if (IsConsumableActive(itemName))
		{
			return;
		}
		PlayerResource[] playerResources = Global.Instance.PlayerResources;
		foreach (PlayerResource val in playerResources)
		{
			if (val.Name == itemName)
			{
				if (PlayerData.Instance.GetResource(val) > 0 && PlayerData.Instance.TryRemoveResource(val, 1))
				{
					ActivateConsumableByFlag(itemName);
				}
				break;
			}
		}
	}

	private bool IsConsumableActive(string name)
	{
		if (name.Contains("Personal Access Token"))
		{
			return PlayerData.Instance.GetFlag("pa_token") == 1;
		}
		if (name.Contains("Bootleg Replicator"))
		{
			return PlayerData.Instance.GetFlag("r_replicator") == 1;
		}
		if (name.Contains("Premium Loot License"))
		{
			return PlayerData.Instance.GetFlag("equip_loot") == 1;
		}
		if (name.Contains("Clearance Certificate"))
		{
			return PlayerData.Instance.GetFlag("dur_drops") > 0;
		}
		return false;
	}

	private void ActivateConsumableByFlag(string name)
	{
		if (name.Contains("Personal Access Token"))
		{
			PlayerData.Instance.SetFlag("pa_token", 1);
		}
		else if (name.Contains("Bootleg Replicator"))
		{
			PlayerData.Instance.SetFlag("r_replicator", 1);
		}
		else if (name.Contains("Premium Loot License"))
		{
			PlayerData.Instance.SetFlag("equip_loot", 1);
		}
		else if (name.Contains("Clearance Certificate"))
		{
			PlayerData.Instance.SetFlag("dur_drops", 5);
		}
	}

	private void UpdateConsumableStatus(string name)
	{
		if (consumableStatuses.TryGetValue(name, out var value))
		{
			value.IsActive = IsConsumableActive(name);
			_ = value.IsActive;
		}
	}

	public void UpdateConsumableStatuses()
	{
		foreach (KeyValuePair<string, ConsumableStatus> consumableStatus in consumableStatuses)
		{
			consumableStatus.Value.IsActive = IsConsumableActive(consumableStatus.Key);
		}
		UpdateHUDText();
	}

	private void SetupConfigWatcher()
	{
		string configFilePath = configFile.ConfigFilePath;
		FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(Path.GetDirectoryName(configFilePath), Path.GetFileName(configFilePath));
		fileSystemWatcher.Changed += delegate
		{
			configFile.Reload();
			OnConfigReloaded();
		};
		fileSystemWatcher.EnableRaisingEvents = true;
	}

	private void OnConfigReloaded()
	{
		InitializeStatuses();
		UpdateHudVisibility();
	}

	public void OnDestroy()
	{
		try
		{
			if ((Object)(object)hudContainer != (Object)null)
			{
				Object.Destroy((Object)(object)hudContainer);
			}
		}
		catch (Exception ex)
		{
			SparrohPlugin.Logger.LogError((object)("Error in ConsumableHotkeys.OnDestroy(): " + ex.Message));
		}
	}
}
[HarmonyPatch]
public static class StorageSlotPatches
{
	[HarmonyPostfix]
	[HarmonyPatch(typeof(StorageSlot), "Setup")]
	public static void PostfixSetup(StorageSlot __instance, IInventoryItem item)
	{
		if (item != null)
		{
			IInventoryItem obj = ((item is PlayerResource) ? item : null);
			if (obj != null)
			{
				_ = ((PlayerResource)obj).Name;
			}
			else
				_ = null;
		}
	}
}
[HarmonyPatch]
public static class StorageWindowPatches
{
	[HarmonyPostfix]
	[HarmonyPatch(typeof(StorageWindow), "Refresh")]
	public static void PostfixRefresh(StorageWindow __instance)
	{
		if (!(((object)__instance).GetType().GetField("slots", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(__instance) is StorageSlot[] array))
		{
			return;
		}
		StorageSlot[] array2 = array;
		foreach (StorageSlot val in array2)
		{
			object? obj = ((object)val).GetType().GetField("item", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(val);
			IInventoryItem val2 = (IInventoryItem)((obj is IInventoryItem) ? obj : null);
			if (val2 != null && val2.ItemCount > 0)
			{
				IInventoryItem obj2 = ((val2 is PlayerResource) ? val2 : null);
				if (obj2 != null)
				{
					_ = ((PlayerResource)obj2).Name;
				}
				else
					_ = null;
			}
		}
	}
}
[HarmonyPatch]
public static class DebugPatches
{
	[HarmonyPostfix]
	[HarmonyPatch(typeof(PlayerData), "GetFlag", new Type[] { typeof(string) })]
	public static void PostfixGetFlag(PlayerData __instance, string id, ref int __result)
	{
		if (!id.ToLower().Contains("token") && !id.ToLower().Contains("license") && !id.ToLower().Contains("replicator") && !id.ToLower().Contains("certificate") && !id.ToLower().Contains("clearance") && !id.ToLower().Contains("permit") && !id.ToLower().Contains("document") && !id.ToLower().Contains("upgrade") && !id.ToLower().Contains("dur_") && !id.ToLower().Contains("pa_") && !id.ToLower().Contains("pl_") && !id.ToLower().Contains("cc_") && !id.ToLower().Contains("loot") && !id.ToLower().Contains("premium") && !id.Contains("p_l") && !id.Contains("c_c"))
		{
			id.Contains("r_r");
		}
	}

	[HarmonyPostfix]
	[HarmonyPatch(typeof(PlayerData), "SetFlag", new Type[]
	{
		typeof(string),
		typeof(int)
	})]
	public static void PostfixSetFlag(PlayerData __instance, string id, int value)
	{
		if (!id.ToLower().Contains("token") && !id.ToLower().Contains("license") && !id.ToLower().Contains("replicator") && !id.ToLower().Contains("certificate") && !id.ToLower().Contains("pa_") && !id.ToLower().Contains("pl_") && !id.ToLower().Contains("cc_") && !id.ToLower().Contains("loot") && !id.ToLower().Contains("premium") && !id.Contains("p_l") && !id.Contains("c_c") && !id.Contains("r_r"))
		{
			return;
		}
		switch (id)
		{
		case "pa_token":
		case "r_replicator":
		case "equip_loot":
		case "dur_drops":
			if (value == 0)
			{
				ConsumableHotkeys.Instance?.UpdateConsumableStatuses();
			}
			break;
		}
	}

	[HarmonyPostfix]
	[HarmonyPatch(typeof(PlayerData), "TryRemoveResource", new Type[]
	{
		typeof(PlayerResource),
		typeof(int)
	})]
	public static void PostfixTryRemoveResource(PlayerData __instance, PlayerResource resource, int amount, bool __result)
	{
		if (__result && amount > 0 && !resource.Name.Contains("Personal") && !resource.Name.Contains("Premium") && !resource.Name.Contains("Bootleg"))
		{
			resource.Name.Contains("Clearance");
		}
	}

	[HarmonyPostfix]
	[HarmonyPatch(typeof(PlayerData), "AddResource")]
	public static void PostfixAddResource(PlayerData __instance, PlayerResource resource, int amount)
	{
		if (amount != 0 && !resource.Name.Contains("Personal") && !resource.Name.Contains("Premium") && !resource.Name.Contains("Bootleg"))
		{
			resource.Name.Contains("Clearance");
		}
	}

	[HarmonyPostfix]
	[HarmonyPatch(typeof(MissionManager), "OnUpgradeCollected")]
	public static void PostfixOnUpgradeCollected(UpgradeInstance upgrade)
	{
		if (upgrade.Gear != null)
		{
			int flag = PlayerData.Instance.GetFlag("dur_drops");
			if (flag > 0)
			{
				PlayerData.Instance.SetFlag("dur_drops", flag - 1);
			}
		}
	}
}
[HarmonyPatch]
internal class EndScreenUI
{
	public static string playerName;

	[HarmonyPatch(typeof(MissionStat), "Setup")]
	[HarmonyPrefix]
	public static void StatSetup__Prefix(MissionStat __instance, Player player, ref MissionPlayerData data)
	{
		playerName = ((Object)player).name;
	}

	[HarmonyPatch(typeof(MissionPlayerData), "GetStatText")]
	[HarmonyPostfix]
	public static void GetEndStats__Postfix(MissionPlayerData __instance, out string title, out string description)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		float damageDealt = __instance.damageDealt;
		int enemiesKilled = __instance.enemiesKilled;
		float appliedStatusEffect = __instance.appliedStatusEffect;
		title = string.Empty;
		description = $"Damage Dealt: {damageDealt}\n" + $"Enemies Killed: {enemiesKilled}\n" + $"Elemental Stacks: {appliedStatusEffect}";
	}
}
public class GunDisplay
{
	[HarmonyPatch(typeof(Gun), "Enable")]
	private class GunEnablePatch
	{
		[HarmonyPostfix]
		private static void Postfix(Gun __instance)
		{
			UpdateCurrentGun();
		}
	}

	[HarmonyPatch(typeof(Gun), "Disable")]
	private class GunDisablePatch
	{
		[HarmonyPostfix]
		private static void Postfix(Gun __instance)
		{
			UpdateCurrentGun();
		}
	}

	[HarmonyPatch(typeof(Gun), "OnFiredBullet")]
	private class GunFiredPatch
	{
		[HarmonyPostfix]
		private static void Postfix(Gun __instance, IBullet bullet, BulletFlags flags, int shotIndex, ref BulletData bulletData)
		{
			if ((Object)(object)__instance == (Object)(object)currentGun)
			{
				currentGunActualDamage = bulletData.damage;
			}
		}
	}

	private ConfigEntry<bool> enableGunStatsHUD;

	private float updateTimer;

	private const float UpdateInterval = 0.5f;

	private GameObject gunStatsHudContainer;

	private TextMeshProUGUI gunStatsTitleText;

	private TextMeshProUGUI[] gunStatsStatTexts;

	private const int NUM_STAT_LINES = 25;

	public static Gun currentGun;

	public static float currentGunActualDamage = 0f;

	private static FieldInfo playerField;

	private static PropertyInfo activeProp;

	private static MethodInfo modifyBulletDataMethod;

	private static FieldInfo activeUpgradesField;

	private static readonly Color sky = new Color(0.529f, 0.808f, 0.922f);

	private static readonly Color orchid = new Color(0.855f, 0.439f, 0.839f);

	private static readonly Color rose = new Color(0.8901961f, 12f / 85f, 0.16862746f);

	private static readonly Color macaroon = new Color(83f / 85f, 0.8784314f, 0.4627451f);

	private static readonly Color shamrock = new Color(1f / 85f, 0.6745098f, 0.07450981f);

	private readonly ConfigFile configFile;

	private readonly Harmony harmony;

	public bool IsActive
	{
		get
		{
			if ((Object)(object)gunStatsHudContainer != (Object)null)
			{
				return gunStatsHudContainer.activeSelf;
			}
			return false;
		}
	}

	public Vector2 GetSize
	{
		get
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			GameObject obj = gunStatsHudContainer;
			if (obj == null)
			{
				return Vector2.zero;
			}
			return obj.GetComponent<RectTransform>().sizeDelta;
		}
	}

	public GunDisplay(ConfigFile configFile, Harmony harmony)
	{
		this.configFile = configFile;
		this.harmony = harmony;
		try
		{
			enableGunStatsHUD = configFile.Bind<bool>("General", "EnableGunStatsHUD", true, "If true, the gun stats HUD will be displayed.");
			enableGunStatsHUD.SettingChanged += OnEnableGunStatsHUDChanged;
			playerField = typeof(Gun).GetField("player", BindingFlags.Instance | BindingFlags.NonPublic);
			activeProp = typeof(IGear).GetProperty("Active");
			modifyBulletDataMethod = typeof(Gun).GetMethod("ModifyBulletData", BindingFlags.Instance | BindingFlags.NonPublic);
			activeUpgradesField = typeof(Player).GetField("ActiveUpgrades", BindingFlags.Instance | BindingFlags.NonPublic);
			harmony.PatchAll(typeof(GunEnablePatch));
			harmony.PatchAll(typeof(GunDisablePatch));
			harmony.PatchAll(typeof(GunFiredPatch));
		}
		catch (Exception ex)
		{
			SparrohPlugin.Logger.LogError((object)("Failed to initialize GunDisplay: " + ex.Message));
		}
	}

	public void UpdateHudVisibility()
	{
		if ((Object)(object)gunStatsHudContainer != (Object)null)
		{
			gunStatsHudContainer.SetActive(enableGunStatsHUD.Value);
		}
	}

	private void OnEnableGunStatsHUDChanged(object sender, EventArgs e)
	{
		UpdateHudVisibility();
	}

	private void CreateGunStatsHUD()
	{
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: Expected O, but got Unknown
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_006c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		//IL_0095: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00aa: Expected O, but got Unknown
		//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0120: Unknown result type (might be due to invalid IL or missing references)
		//IL_0135: Unknown result type (might be due to invalid IL or missing references)
		//IL_014a: Unknown result type (might be due to invalid IL or missing references)
		//IL_015e: Unknown result type (might be due to invalid IL or missing references)
		//IL_018c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0192: Expected O, but got Unknown
		//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_0214: Unknown result type (might be due to invalid IL or missing references)
		//IL_0229: Unknown result type (might be due to invalid IL or missing references)
		//IL_0248: Unknown result type (might be due to invalid IL or missing references)
		//IL_025c: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)gunStatsHudContainer != (Object)null))
		{
			RectTransform reticle = Player.LocalPlayer.PlayerLook.Reticle;
			gunStatsHudContainer = new GameObject("GunStatsHUD");
			gunStatsHudContainer.transform.SetParent((Transform)(object)reticle, false);
			RectTransform obj = gunStatsHudContainer.AddComponent<RectTransform>();
			obj.anchorMin = new Vector2(0.18f, 1.14f);
			obj.anchorMax = new Vector2(0.18f, 1.14f);
			obj.anchoredPosition = new Vector2(0f, 0f);
			obj.sizeDelta = new Vector2(350f, 400f);
			GameObject val = new GameObject("TitleText");
			val.transform.SetParent(gunStatsHudContainer.transform, false);
			gunStatsTitleText = val.AddComponent<TextMeshProUGUI>();
			((TMP_Text)gunStatsTitleText).fontSize = 18f;
			((Graphic)gunStatsTitleText).color = Color.white;
			((TMP_Text)gunStatsTitleText).enableWordWrapping = false;
			((TMP_Text)gunStatsTitleText).alignment = (TextAlignmentOptions)513;
			((TMP_Text)gunStatsTitleText).verticalAlignment = (VerticalAlignmentOptions)512;
			RectTransform component = val.GetComponent<RectTransform>();
			component.anchorMin = Vector2.zero;
			component.anchorMax = new Vector2(1f, 0f);
			component.anchoredPosition = new Vector2(0f, 0f);
			component.sizeDelta = new Vector2(0f, 25f);
			gunStatsStatTexts = (TextMeshProUGUI[])(object)new TextMeshProUGUI[25];
			for (int i = 0; i < 25; i++)
			{
				GameObject val2 = new GameObject($"StatText{i}");
				val2.transform.SetParent(gunStatsHudContainer.transform, false);
				gunStatsStatTexts[i] = val2.AddComponent<TextMeshProUGUI>();
				((TMP_Text)gunStatsStatTexts[i]).fontSize = 16f;
				((Graphic)gunStatsStatTexts[i]).color = Color.white;
				((TMP_Text)gunStatsStatTexts[i]).enableWordWrapping = false;
				((TMP_Text)gunStatsStatTexts[i]).alignment = (TextAlignmentOptions)513;
				((TMP_Text)gunStatsStatTexts[i]).verticalAlignment = (VerticalAlignmentOptions)512;
				RectTransform component2 = val2.GetComponent<RectTransform>();
				component2.anchorMin = Vector2.zero;
				component2.anchorMax = new Vector2(1f, 0f);
				component2.anchoredPosition = new Vector2(0f, 0f - ((float)i * 18f + 25f));
				component2.sizeDelta = new Vector2(0f, 18f);
			}
			UpdateHudVisibility();
		}
	}

	public void Update()
	{
		try
		{
			if (enableGunStatsHUD.Value)
			{
				if ((Object)(object)gunStatsHudContainer == (Object)null && (Object)(object)Player.LocalPlayer != (Object)null && (Object)(object)Player.LocalPlayer.PlayerLook != (Object)null && (Object)(object)Player.LocalPlayer.PlayerLook.Reticle != (Object)null)
				{
					CreateGunStatsHUD();
				}
				updateTimer += Time.deltaTime;
				if (updateTimer >= 0.5f)
				{
					updateTimer = 0f;
					UpdateCurrentGun();
					UpdateGunStatsHUD();
				}
				AdjustPosition();
			}
		}
		catch (Exception ex)
		{
			SparrohPlugin.Logger.LogError((object)("Error in GunDisplay.Update(): " + ex.Message));
		}
	}

	public Vector2 GetGunStatsHUDSize()
	{
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)gunStatsHudContainer != (Object)null))
		{
			return Vector2.zero;
		}
		return gunStatsHudContainer.GetComponent<RectTransform>().sizeDelta;
	}

	private void UpdateGunStatsHUD()
	{
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_0079: Expected O, but got Unknown
		//IL_0094: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_0160: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_0227: Unknown result type (might be due to invalid IL or missing references)
		//IL_026b: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_033d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0397: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)gunStatsHudContainer == (Object)null || (Object)(object)gunStatsTitleText == (Object)null || gunStatsStatTexts == null)
		{
			return;
		}
		if ((Object)(object)currentGun == (Object)null)
		{
			((TMP_Text)gunStatsTitleText).text = "No Gun Active";
			for (int i = 0; i < gunStatsStatTexts.Length; i++)
			{
				((TMP_Text)gunStatsStatTexts[i]).text = "";
			}
			return;
		}
		IWeapon val = (IWeapon)(object)currentGun;
		UpgradeStatChanges val2 = new UpgradeStatChanges();
		ref GunData gunData = ref val.GunData;
		Dictionary<string, StatInfo> dictionary = new Dictionary<string, StatInfo>();
		IEnumerator<StatInfo> enumerator = ((IGear)val).EnumeratePrimaryStats(val2);
		while (enumerator.MoveNext())
		{
			dictionary[enumerator.Current.name] = enumerator.Current;
		}
		Dictionary<string, StatInfo> dictionary2 = new Dictionary<string, StatInfo>();
		IEnumerator<StatInfo> enumerator2 = ((IGear)val).EnumerateSecondaryStats(val2);
		while (enumerator2.MoveNext())
		{
			if (enumerator2.Current.name != "Aim Zoom")
			{
				dictionary2[enumerator2.Current.name] = enumerator2.Current;
			}
		}
		if (dictionary2.TryGetValue("Damage", out var value) && currentGunActualDamage > 0f)
		{
			value.value = $"{currentGunActualDamage:F1}";
		}
		List<string> lines = new List<string>();
		lines.Add("Current Gun Stats:");
		AddStatFromEnum(ref lines, dictionary2, "Damage");
		lines.Add($"Bullets per Shot: <color=#{ColorUtility.ToHtmlStringRGB(macaroon)}>{gunData.bulletsPerShot}</color>");
		AddStatFromEnum(ref lines, dictionary, "Damage Type");
		AddStatFromEnum(ref lines, dictionary2, "Fire Rate");
		lines.Add($"Burst Size: <color=#{ColorUtility.ToHtmlStringRGB(macaroon)}>{gunData.burstSize}</color>");
		lines.Add("Burst Interval: <color=#" + ColorUtility.ToHtmlStringRGB(macaroon) + ">" + gunData.burstFireInterval.ToString("F2") + "</color>");
		AddStatFromEnumWithCustomLabel(ref lines, dictionary2, "Ammo Capacity", "Magazine Size");
		lines.Add($"Ammo Capacity: <color=#{ColorUtility.ToHtmlStringRGB(sky)}>{gunData.ammoCapacity}</color>");
		AddStatFromEnum(ref lines, dictionary2, "Reload Duration");
		AddStatFromEnum(ref lines, dictionary2, "Charge Duration");
		lines.Add($"Explosion Size: <color=#{ColorUtility.ToHtmlStringRGB(orchid)}>{Mathf.Round(gunData.hitForce)}</color>");
		AddStatFromEnum(ref lines, dictionary2, "Range");
		lines.Add($"Recoil: <color=#{ColorUtility.ToHtmlStringRGB(shamrock)}>X({Mathf.Round(gunData.recoilData.recoilX.x)}, {Mathf.Round(gunData.recoilData.recoilX.y)}) Y({Mathf.Round(gunData.recoilData.recoilY.x)}, {Mathf.Round(gunData.recoilData.recoilY.y)})</color>");
		lines.Add($"Spread: <color=#{ColorUtility.ToHtmlStringRGB(shamrock)}>Size({Mathf.Round(gunData.spreadData.spreadSize.x)}, {Mathf.Round(gunData.spreadData.spreadSize.y)})</color>");
		lines.Add("Fire Mode: <color=#" + ColorUtility.ToHtmlStringRGB(macaroon) + ">" + ((gunData.automatic == 1) ? "Automatic" : "Semi Automatic") + "</color>");
		((TMP_Text)gunStatsTitleText).text = lines[0];
		for (int j = 1; j < lines.Count && j <= gunStatsStatTexts.Length; j++)
		{
			((TMP_Text)gunStatsStatTexts[j - 1]).text = lines[j];
		}
		for (int k = lines.Count - 1; k < gunStatsStatTexts.Length; k++)
		{
			((TMP_Text)gunStatsStatTexts[k]).text = "";
		}
	}

	private void AddStatFromEnumWithCustomLabel(ref List<string> lines, Dictionary<string, StatInfo> stats, string statName, string displayLabel)
	{
		//IL_0018: 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_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		if (stats.TryGetValue(statName, out var value))
		{
			string text = displayLabel + ":";
			string value2 = value.value;
			Color statValueColor = GetStatValueColor(statName);
			lines.Add(text + " <color=#" + ColorUtility.ToHtmlStringRGB(statValueColor) + ">" + value2 + "</color>");
		}
	}

	private void AddStatFromEnum(ref List<string> lines, Dictionary<string, StatInfo> stats, string statName)
	{
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		//IL_0091: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b7: 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)
		if (stats.TryGetValue(statName, out var value))
		{
			string text = value.name + ":";
			string text2 = value.value;
			if (statName == "Fire Rate" && float.TryParse(value.value, out var result))
			{
				text2 = (result / 60f).ToString("F1") + " /s";
			}
			if (statName == "Damage" && currentGunActualDamage > 0f)
			{
				text2 = $"{currentGunActualDamage:F1}";
			}
			Color val = ((value.name == "Damage Type") ? value.color : GetStatValueColor(value.name));
			lines.Add(text + " <color=#" + ColorUtility.ToHtmlStringRGB(val) + ">" + text2 + "</color>");
		}
	}

	private Color GetStatValueColor(string statName)
	{
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_0086: Unknown result type (might be due to invalid IL or missing references)
		//IL_0058: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		//IL_0065: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: 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_0075: Unknown result type (might be due to invalid IL or missing references)
		//IL_0078: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0080: 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)
		return (Color)(statName switch
		{
			"Damage" => rose, 
			"Fire Rate" => macaroon, 
			"Ammo Capacity" => sky, 
			"Reload Duration" => sky, 
			"Charge Duration" => sky, 
			"Range" => shamrock, 
			_ => Color.white, 
		});
	}

	public static void UpdateCurrentGun()
	{
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Expected O, but got Unknown
		if ((Object)(object)Player.LocalPlayer == (Object)null)
		{
			return;
		}
		Gun[] array = Object.FindObjectsOfType<Gun>();
		foreach (Gun val in array)
		{
			if ((Object)(Player)playerField.GetValue(val) == (Object)(object)Player.LocalPlayer)
			{
				IGear obj = (IGear)(object)val;
				if ((bool)activeProp.GetValue(obj))
				{
					currentGun = val;
					return;
				}
			}
		}
		currentGun = null;
	}

	private void AdjustPosition()
	{
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0097: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: 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)
		if ((Object)(object)gunStatsHudContainer != (Object)null)
		{
			RectTransform component = gunStatsHudContainer.GetComponent<RectTransform>();
			float num = 0f;
			if (Carnometer.Instance != null && Carnometer.Instance.IsActive)
			{
				num -= Carnometer.Instance.GetSize.y;
			}
			if (Speedometer.Instance != null && Speedometer.Instance.IsActive)
			{
				num -= Speedometer.Instance.GetSize.y;
			}
			if (Altimeter.Instance != null && Altimeter.Instance.IsActive)
			{
				num -= Altimeter.Instance.GetSize.y;
			}
			component.anchoredPosition = new Vector2(0f, num);
		}
	}

	public void OnDestroy()
	{
		try
		{
			if ((Object)(object)gunStatsHudContainer != (Object)null)
			{
				Object.Destroy((Object)(object)gunStatsHudContainer);
			}
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}
		catch (Exception ex)
		{
			SparrohPlugin.Logger.LogError((object)("Error in GunDisplay.OnDestroy(): " + ex.Message));
		}
	}
}
[HarmonyPatch]
internal class HealthBarUI
{
	public static HealthMonoUI health_MB;

	public static TextMeshProUGUI healthText;

	public static GameObject healthTextGO;

	public static Player player;

	[HarmonyPatch(typeof(Player), "Start")]
	[HarmonyPrefix]
	public static void GetPlayer__Prefix2(Player __instance)
	{
		if (((NetworkBehaviour)__instance).IsLocalPlayer)
		{
			player = __instance;
		}
	}

	[HarmonyPatch(typeof(CharacterSelectWindow), "SelectCharacter", new Type[] { typeof(Character) })]
	[HarmonyPostfix]
	public static void CreateObject__Postfix2(CharacterSelectWindow __instance, Character character)
	{
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Expected O, but got Unknown
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: Unknown result type (might be due to invalid IL or missing references)
		if (((NetworkBehaviour)player).IsLocalPlayer && !Object.op_Implicit((Object)(object)healthTextGO))
		{
			healthTextGO = new GameObject("HealthText");
			health_MB = healthTextGO.AddComponent<HealthMonoUI>();
			healthTextGO.TryGetComponent<TextMeshProUGUI>(ref healthText);
			healthTextGO.transform.rotation = Quaternion.Euler(0f, 0f, 0f);
			healthTextGO.transform.localRotation = Quaternion.Euler(0f, 0f, 0f);
			healthTextGO.layer = 5;
			health_MB.health = player.Health;
			healthTextGO.SetActive(true);
		}
	}

	[HarmonyPatch(typeof(Player), "OnSyncedHealthChanged")]
	[HarmonyPostfix]
	public static void OwnerHealthChange__Postfix(Player __instance)
	{
		if (((NetworkBehaviour)__instance).IsLocalPlayer && (Object)(object)healthText != (Object)null)
		{
			health_MB.health = __instance.Health;
			health_MB.healthPercent = health_MB.health / __instance.MaxHealth;
			health_MB.isDamaged = true;
		}
	}
}
internal class HealthMonoUI : MonoBehaviour
{
	public static TextMeshProUGUI text;

	public float health;

	public float healthPercent;

	public Color healthColor = Color.white;

	public static Vector3 position = new Vector3(21.2162f, -45.0458f, -5.5684f);

	public static Vector3 position2 = new Vector3(187.9581f, -44.3458f, -5.5684f);

	public static Quaternion rotation = Quaternion.Euler(0f, 0f, 0f);

	public static Vector3 scale = new Vector3(1f, 1f, 1f);

	public bool isDamaged;

	private static FieldInfo playerLookField;

	public void Awake()
	{
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_0066: Unknown result type (might be due to invalid IL or missing references)
		//IL_0084: Unknown result type (might be due to invalid IL or missing references)
		//IL_00aa: 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_00e3: Unknown result type (might be due to invalid IL or missing references)
		if (playerLookField == null)
		{
			playerLookField = typeof(Player).GetField("playerLook", BindingFlags.Instance | BindingFlags.NonPublic);
		}
		Transform defaultHUDParent = (Transform)(object)((PlayerLook)playerLookField.GetValue(Player.LocalPlayer)).DefaultHUDParent;
		text = ((Component)this).gameObject.AddComponent<TextMeshProUGUI>();
		((TMP_Text)text).fontSize = 24f;
		((Graphic)text).color = Color.red;
		((TMP_Text)text).rectTransform.sizeDelta = new Vector2(250f, 50f);
		((Component)this).gameObject.transform.SetParent(defaultHUDParent);
		((Component)this).gameObject.transform.rotation = rotation;
		((Component)this).gameObject.transform.localPosition = new Vector3(0f, 375f, 0f);
		((Component)this).gameObject.transform.localScale = scale;
		((Component)text).gameObject.layer = 5;
		((TMP_Text)text).text = $"100% ({Math.Round(health, 2):F2})";
	}

	public void Update()
	{
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		if (isDamaged)
		{
			((TMP_Text)text).text = $"{(float)((double)healthPercent * 100.0):F2}% ({Math.Round(health, 2):F2})";
			float num = Player.CalculateWeightedHealth(healthPercent);
			((Graphic)text).color = Global.Instance.HealthGradient.Evaluate(num);
			isDamaged = false;
		}
	}
}
[BepInPlugin("sparroh.expandedhud", "ExpandedHUD", "1.2.0")]
[MycoMod(/*Could not decode attribute arguments.*/)]
public class SparrohPlugin : BaseUnityPlugin
{
	public const string PluginGUID = "sparroh.expandedhud";

	public const string PluginName = "ExpandedHUD";

	public const string PluginVersion = "1.2.0";

	internal static ManualLogSource Logger;

	private Harmony harmony;

	private Speedometer speedometer;

	private Carnometer carnometer;

	private GunDisplay gunDisplay;

	private Altimeter altimeter;

	private ConsumableHotkeys consumableHotkeys;

	private RangeFinder rangeFinder;

	private void Awake()
	{
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Expected O, but got Unknown
		Logger = ((BaseUnityPlugin)this).Logger;
		try
		{
			harmony = new Harmony("sparroh.expandedhud");
		}
		catch (Exception ex)
		{
			Logger.LogError((object)("Failed to create Harmony instance: " + ex.Message));
			return;
		}
		ConfigFile configFile = ((BaseUnityPlugin)this).Config;
		try
		{
			FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(Paths.ConfigPath, "sparroh.expandedhud.cfg");
			fileSystemWatcher.Changed += delegate
			{
				configFile.Reload();
			};
			fileSystemWatcher.EnableRaisingEvents = true;
		}
		catch (Exception ex2)
		{
			Logger.LogWarning((object)("Failed to set up config watcher: " + ex2.Message));
		}
		try
		{
			speedometer = new Speedometer(configFile, harmony);
		}
		catch (Exception ex3)
		{
			Logger.LogError((object)("Failed to initialize Speedometer: " + ex3.Message));
		}
		try
		{
			carnometer = new Carnometer(configFile, harmony);
		}
		catch (Exception ex4)
		{
			Logger.LogError((object)("Failed to initialize Carnometer: " + ex4.Message));
		}
		try
		{
			gunDisplay = new GunDisplay(configFile, harmony);
		}
		catch (Exception ex5)
		{
			Logger.LogError((object)("Failed to initialize GunDisplay: " + ex5.Message));
		}
		try
		{
			altimeter = new Altimeter(configFile, harmony);
		}
		catch (Exception ex6)
		{
			Logger.LogError((object)("Failed to initialize Altimeter: " + ex6.Message));
		}
		try
		{
			consumableHotkeys = new ConsumableHotkeys(configFile, harmony);
		}
		catch (Exception ex7)
		{
			Logger.LogError((object)("Failed to initialize ConsumableHotkeys: " + ex7.Message));
		}
		try
		{
			rangeFinder = new RangeFinder(configFile, harmony);
		}
		catch (Exception ex8)
		{
			Logger.LogError((object)("Failed to initialize RangeFinder: " + ex8.Message));
		}
		try
		{
			harmony.PatchAll();
		}
		catch (Exception ex9)
		{
			Logger.LogError((object)("Failed to apply Harmony patches: " + ex9.Message));
		}
		Logger.LogInfo((object)"ExpandedHUD loaded successfully.");
	}

	private void Start()
	{
	}

	private void Update()
	{
		//IL_0282: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			if (gunDisplay != null)
			{
				gunDisplay.UpdateHudVisibility();
			}
		}
		catch (Exception ex)
		{
			Logger.LogError((object)("Error in GunDisplay.UpdateHudVisibility(): " + ex.Message));
		}
		try
		{
			if (carnometer != null)
			{
				carnometer.UpdateHudVisibility();
			}
		}
		catch (Exception ex2)
		{
			Logger.LogError((object)("Error in Carnometer.UpdateHudVisibility(): " + ex2.Message));
		}
		try
		{
			if (speedometer != null)
			{
				speedometer.UpdateHudVisibility();
			}
		}
		catch (Exception ex3)
		{
			Logger.LogError((object)("Error in Speedometer.UpdateHudVisibility(): " + ex3.Message));
		}
		try
		{
			if (altimeter != null)
			{
				altimeter.UpdateHudVisibility();
			}
		}
		catch (Exception ex4)
		{
			Logger.LogError((object)("Error in Altimeter.UpdateHudVisibility(): " + ex4.Message));
		}
		try
		{
			if (consumableHotkeys != null)
			{
				consumableHotkeys.UpdateHudVisibility();
			}
		}
		catch (Exception ex5)
		{
			Logger.LogError((object)("Error in ConsumableHotkeys.UpdateHudVisibility(): " + ex5.Message));
		}
		try
		{
			if (rangeFinder != null)
			{
				rangeFinder.UpdateHudVisibility();
			}
		}
		catch (Exception ex6)
		{
			Logger.LogError((object)("Error in RangeFinder.UpdateHudVisibility(): " + ex6.Message));
		}
		try
		{
			if (gunDisplay != null)
			{
				gunDisplay.Update();
			}
		}
		catch (Exception ex7)
		{
			Logger.LogError((object)("Error in GunDisplay.Update(): " + ex7.Message));
		}
		try
		{
			if (carnometer != null)
			{
				carnometer.Update();
			}
		}
		catch (Exception ex8)
		{
			Logger.LogError((object)("Error in Carnometer.Update(): " + ex8.Message));
		}
		try
		{
			if (speedometer != null)
			{
				speedometer.Update();
			}
		}
		catch (Exception ex9)
		{
			Logger.LogError((object)("Error in Speedometer.Update(): " + ex9.Message));
		}
		try
		{
			if (altimeter != null)
			{
				altimeter.Update();
			}
		}
		catch (Exception ex10)
		{
			Logger.LogError((object)("Error in Altimeter.Update(): " + ex10.Message));
		}
		try
		{
			if (consumableHotkeys != null)
			{
				consumableHotkeys.Update();
			}
		}
		catch (Exception ex11)
		{
			Logger.LogError((object)("Error in ConsumableHotkeys.Update(): " + ex11.Message));
		}
		try
		{
			if (rangeFinder != null)
			{
				rangeFinder.Update();
			}
		}
		catch (Exception ex12)
		{
			Logger.LogError((object)("Error in RangeFinder.Update(): " + ex12.Message));
		}
		try
		{
			if (gunDisplay != null)
			{
				_ = gunDisplay.GetGunStatsHUDSize().y;
				_ = 0f;
			}
		}
		catch (Exception ex13)
		{
			Logger.LogError((object)("Error checking gun stats HUD size: " + ex13.Message));
		}
	}

	private void OnDestroy()
	{
		try
		{
			if (gunDisplay != null)
			{
				gunDisplay.OnDestroy();
			}
		}
		catch (Exception ex)
		{
			Logger.LogError((object)("Error in GunDisplay.OnDestroy(): " + ex.Message));
		}
		try
		{
			if (carnometer != null)
			{
				carnometer.OnDestroy();
			}
		}
		catch (Exception ex2)
		{
			Logger.LogError((object)("Error in Carnometer.OnDestroy(): " + ex2.Message));
		}
		try
		{
			if (speedometer != null)
			{
				speedometer.OnDestroy();
			}
		}
		catch (Exception ex3)
		{
			Logger.LogError((object)("Error in Speedometer.OnDestroy(): " + ex3.Message));
		}
		try
		{
			if (altimeter != null)
			{
				altimeter.OnDestroy();
			}
		}
		catch (Exception ex4)
		{
			Logger.LogError((object)("Error in Altimeter.OnDestroy(): " + ex4.Message));
		}
		try
		{
			if (consumableHotkeys != null)
			{
				consumableHotkeys.OnDestroy();
			}
		}
		catch (Exception ex5)
		{
			Logger.LogError((object)("Error in ConsumableHotkeys.OnDestroy(): " + ex5.Message));
		}
		try
		{
			if (rangeFinder != null)
			{
				rangeFinder.OnDestroy();
			}
		}
		catch (Exception ex6)
		{
			Logger.LogError((object)("Error in RangeFinder.OnDestroy(): " + ex6.Message));
		}
		try
		{
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}
		catch (Exception ex7)
		{
			Logger.LogError((object)("Error unpatching Harmony: " + ex7.Message));
		}
	}
}
public class RangeFinder
{
	[HarmonyPatch]
	public static class RangeFinderPatches
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(MissionHUD), "Start")]
		public static void MissionHUD_Start_Postfix()
		{
			RangeFinderSystem.Initialize();
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(MissionHUD), "Update")]
		public static void MissionHUD_Update_Postfix()
		{
			RangeFinderSystem.UpdateRangeFinder();
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(MissionHUD), "OnDestroy")]
		public static void MissionHUD_OnDestroy_Postfix()
		{
			RangeFinderSystem.Cleanup();
		}
	}

	public static ConfigEntry<bool> enableRangeFinder;

	public static ConfigEntry<float> rangeFinderMaxRange;

	private readonly ConfigFile configFile;

	private readonly Harmony harmony;

	public RangeFinder(ConfigFile configFile, Harmony harmony)
	{
		this.configFile = configFile;
		this.harmony = harmony;
		enableRangeFinder = configFile.Bind<bool>("General", "EnableRangefinderHUD", true, "Enable the rangefinder display");
		rangeFinderMaxRange = configFile.Bind<float>("General", "RangefinderMaxRange", 500f, "Maximum range for rangefinder (meters)");
		enableRangeFinder.SettingChanged += OnEnableRangeFinderChanged;
		harmony.PatchAll(typeof(RangeFinderPatches));
	}

	public void UpdateHudVisibility()
	{
		RangeFinderSystem.SetEnabled(enableRangeFinder.Value);
	}

	public void Update()
	{
		RangeFinderSystem.UpdateRangeFinder();
	}

	public void OnDestroy()
	{
		RangeFinderSystem.Cleanup();
		harmony.UnpatchSelf();
	}

	private void OnEnableRangeFinderChanged(object sender, EventArgs e)
	{
		UpdateHudVisibility();
	}
}
public class RangeFinderHUD : MonoBehaviour
{
	private TextMeshProUGUI rangeText;

	public void Setup()
	{
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0051: Expected O, but got Unknown
		//IL_0074: Unknown result type (might be due to invalid IL or missing references)
		//IL_007e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_00db: 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)
		RectTransform val = ((Component)this).GetComponent<RectTransform>();
		if ((Object)(object)val == (Object)null)
		{
			val = ((Component)this).gameObject.AddComponent<RectTransform>();
		}
		val.sizeDelta = new Vector2(200f, 50f);
		val.anchoredPosition = new Vector2(0f, -50f);
		GameObject val2 = new GameObject("RangeFinderText");
		val2.transform.SetParent(((Component)this).transform, false);
		RectTransform obj = val2.AddComponent<RectTransform>();
		obj.sizeDelta = new Vector2(200f, 50f);
		obj.anchoredPosition = Vector2.zero;
		rangeText = val2.AddComponent<TextMeshProUGUI>();
		((TMP_Text)rangeText).alignment = (TextAlignmentOptions)514;
		((TMP_Text)rangeText).fontSize = 24f;
		((Graphic)rangeText).color = Color.white;
		((TMP_Text)rangeText).text = "--- m";
		Outline obj2 = val2.AddComponent<Outline>();
		((Shadow)obj2).effectColor = Color.black;
		((Shadow)obj2).effectDistance = new Vector2(1f, -1f);
	}

	public void UpdateRange(float distance)
	{
		if (distance >= 1000f)
		{
			((TMP_Text)rangeText).text = "∞ m";
		}
		else if (distance < 0f)
		{
			((TMP_Text)rangeText).text = "--- m";
		}
		else
		{
			((TMP_Text)rangeText).text = $"{distance:F1} m";
		}
	}

	public void SetEnabled(bool enabled)
	{
		if ((Object)(object)rangeText != (Object)null)
		{
			((Component)rangeText).gameObject.SetActive(enabled);
		}
	}
}
internal static class RangeFinderSystem
{
	private static RangeFinderHUD rangeFinderHUD;

	private static bool isInitialized;

	private static LayerMask raycastLayers;

	private static bool EnableRangeFinder => RangeFinder.enableRangeFinder.Value;

	private static float MaxRange => RangeFinder.rangeFinderMaxRange.Value;

	static RangeFinderSystem()
	{
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		raycastLayers = LayerMask.op_Implicit(LayerMask.GetMask(new string[3] { "Default", "Terrain", "Environment" }));
	}

	public static void Initialize()
	{
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		if (isInitialized)
		{
			return;
		}
		try
		{
			GameObject val = Resources.Load<GameObject>("Prefabs/HUDs/GenericHUD");
			if ((Object)(object)val == (Object)null)
			{
				rangeFinderHUD = new GameObject("RangeFinderHUD").AddComponent<RangeFinderHUD>();
				((Component)rangeFinderHUD).transform.SetParent((Transform)(object)PlayerLook.Instance.DefaultHUDParent, false);
			}
			else
			{
				GameObject val2 = Object.Instantiate<GameObject>(val, (Transform)(object)PlayerLook.Instance.DefaultHUDParent);
				rangeFinderHUD = val2.GetComponent<RangeFinderHUD>();
				if ((Object)(object)rangeFinderHUD == (Object)null)
				{
					rangeFinderHUD = val2.AddComponent<RangeFinderHUD>();
				}
			}
			rangeFinderHUD.Setup();
			rangeFinderHUD.SetEnabled(EnableRangeFinder);
			isInitialized = true;
		}
		catch (Exception ex)
		{
			SparrohPlugin.Logger.LogError((object)("Failed to initialize RangeFinder: " + ex.Message));
		}
	}

	public static void UpdateRangeFinder()
	{
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		if (!isInitialized || !EnableRangeFinder || (Object)(object)rangeFinderHUD == (Object)null)
		{
			return;
		}
		try
		{
			RaycastHit val = default(RaycastHit);
			if (Physics.Raycast(Camera.main.ScreenPointToRay(new Vector3((float)Screen.width / 2f, (float)Screen.height / 2f, 0f)), ref val, MaxRange, LayerMask.op_Implicit(raycastLayers)))
			{
				float distance = ((RaycastHit)(ref val)).distance;
				rangeFinderHUD.UpdateRange(distance);
			}
			else
			{
				rangeFinderHUD.UpdateRange(-1f);
			}
		}
		catch (Exception ex)
		{
			SparrohPlugin.Logger.LogError((object)("Error updating rangefinder: " + ex.Message));
			rangeFinderHUD.UpdateRange(-1f);
		}
	}

	public static void SetEnabled(bool enabled)
	{
		if ((Object)(object)rangeFinderHUD != (Object)null)
		{
			rangeFinderHUD.SetEnabled(enabled);
		}
	}

	public static void Cleanup()
	{
		if ((Object)(object)rangeFinderHUD != (Object)null)
		{
			Object.Destroy((Object)(object)((Component)rangeFinderHUD).gameObject);
			rangeFinderHUD = null;
		}
		isInitialized = false;
	}
}
public class Speedometer
{
	private ConfigEntry<bool> enableSpeedometerHUD;

	private TextMeshProUGUI speedText;

	private GameObject speedometerHudContainer;

	private FieldInfo currentMoveSpeedField;

	private FieldInfo vkField;

	private FieldInfo rbField;

	private FieldInfo moveVelocityField;

	private PropertyInfo vkProp;

	private PropertyInfo rbProp;

	private static readonly Color sky = new Color(0.529f, 0.808f, 0.922f);

	private readonly ConfigFile configFile;

	private readonly Harmony harmony;

	public static Speedometer Instance { get; private set; }

	public bool IsActive
	{
		get
		{
			if ((Object)(object)speedometerHudContainer != (Object)null)
			{
				return speedometerHudContainer.activeSelf;
			}
			return false;
		}
	}

	public Vector2 GetSize
	{
		get
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			GameObject obj = speedometerHudContainer;
			if (obj == null)
			{
				return Vector2.zero;
			}
			return obj.GetComponent<RectTransform>().sizeDelta;
		}
	}

	public Speedometer(ConfigFile configFile, Harmony harmony)
	{
		this.configFile = configFile;
		this.harmony = harmony;
		Instance = this;
		try
		{
			enableSpeedometerHUD = configFile.Bind<bool>("General", "EnableSpeedometerHUD", true, "Enables the speedometer HUD display.");
			enableSpeedometerHUD.SettingChanged += OnEnableSpeedometerHUDChanged;
			currentMoveSpeedField = typeof(Player).GetField("currentMoveSpeed", BindingFlags.Instance | BindingFlags.NonPublic);
			vkField = typeof(Player).GetField("velocity", BindingFlags.Instance | BindingFlags.NonPublic) ?? typeof(Player).GetField("velocity", BindingFlags.Instance | BindingFlags.Public);
			if (vkField == null)
			{
				vkProp = typeof(Player).GetProperty("velocity", BindingFlags.Instance | BindingFlags.Public);
			}
			if (vkField == null && vkProp == null)
			{
				rbField = typeof(Player).GetField("rb", BindingFlags.Instance | BindingFlags.NonPublic) ?? typeof(Player).GetField("rb", BindingFlags.Instance | BindingFlags.Public);
			}
			if (rbField == null && vkField == null && vkProp == null)
			{
				rbProp = typeof(Player).GetProperty("rb", BindingFlags.Instance | BindingFlags.Public);
			}
			if (rbField == null && rbProp == null && vkField == null && vkProp == null)
			{
				moveVelocityField = typeof(Player).GetField("moveVelocity", BindingFlags.Instance | BindingFlags.NonPublic) ?? typeof(Player).GetField("moveVelocity", BindingFlags.Instance | BindingFlags.Public);
			}
		}
		catch (Exception ex)
		{
			SparrohPlugin.Logger.LogError((object)("Failed to initialize Speedometer reflection: " + ex.Message));
		}
	}

	public void UpdateHudVisibility()
	{
		if ((Object)(object)speedometerHudContainer != (Object)null)
		{
			speedometerHudContainer.SetActive(enableSpeedometerHUD.Value);
		}
	}

	private void OnEnableSpeedometerHUDChanged(object sender, EventArgs e)
	{
		if (!enableSpeedometerHUD.Value && (Object)(object)speedometerHudContainer != (Object)null)
		{
			Object.Destroy((Object)(object)speedometerHudContainer);
			speedometerHudContainer = null;
			speedText = null;
		}
		UpdateHudVisibility();
	}

	private void CreateSpeedometerHUD()
	{
		//IL_005c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0066: Expected O, but got Unknown
		//IL_008e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a3: 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_00cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00db: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e1: Expected O, but got Unknown
		//IL_011a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0157: Unknown result type (might be due to invalid IL or missing references)
		//IL_0162: Unknown result type (might be due to invalid IL or missing references)
		//IL_0176: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)speedometerHudContainer != (Object)null) && !((Object)(object)Player.LocalPlayer == (Object)null) && !((Object)(object)Player.LocalPlayer.PlayerLook == (Object)null) && !((Object)(object)Player.LocalPlayer.PlayerLook.Reticle == (Object)null))
		{
			RectTransform reticle = Player.LocalPlayer.PlayerLook.Reticle;
			speedometerHudContainer = new GameObject("SpeedometerHUD");
			speedometerHudContainer.transform.SetParent((Transform)(object)reticle, false);
			RectTransform obj = speedometerHudContainer.AddComponent<RectTransform>();
			obj.anchorMin = new Vector2(0.2f, 0.95f);
			obj.anchorMax = new Vector2(0.2f, 0.95f);
			obj.anchoredPosition = new Vector2(0f, 0f);
			obj.sizeDelta = new Vector2(300f, 25f);
			GameObject val = new GameObject("SpeedText");
			val.transform.SetParent(speedometerHudContainer.transform, false);
			speedText = val.AddComponent<TextMeshProUGUI>();
			((TMP_Text)speedText).fontSize = 18f;
			((Graphic)speedText).color = Color.white;
			((TMP_Text)speedText).enableWordWrapping = false;
			((TMP_Text)speedText).alignment = (TextAlignmentOptions)513;
			((TMP_Text)speedText).verticalAlignment = (VerticalAlignmentOptions)512;
			RectTransform component = val.GetComponent<RectTransform>();
			component.anchorMin = Vector2.zero;
			component.anchorMax = Vector2.one;
			component.anchoredPosition = new Vector2(0f, 0f);
			UpdateHudVisibility();
		}
	}

	public void Update()
	{
		//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0151: Unknown result type (might be due to invalid IL or missing references)
		//IL_0156: Unknown result type (might be due to invalid IL or missing references)
		//IL_022e: Unknown result type (might be due to invalid IL or missing references)
		//IL_018d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0192: Unknown result type (might be due to invalid IL or missing references)
		//IL_020c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0211: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_0292: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			if ((Object)(object)speedometerHudContainer == (Object)null)
			{
				CreateSpeedometerHUD();
				return;
			}
			if ((Object)(object)speedometerHudContainer == (Object)null || (Object)(object)speedText == (Object)null || (Object)(object)Player.LocalPlayer == (Object)null)
			{
				if ((Object)(object)speedText != (Object)null)
				{
					((TMP_Text)speedText).text = "No Player";
				}
				return;
			}
			float num = 0f;
			if (vkField != null || vkProp != null)
			{
				if (vkField != null)
				{
					if (vkField.GetValue(Player.LocalPlayer) is Vector3 val)
					{
						num = ((Vector3)(ref val)).magnitude;
					}
				}
				else if (vkProp != null && vkProp.GetValue(Player.LocalPlayer) is Vector3 val2)
				{
					num = ((Vector3)(ref val2)).magnitude;
				}
			}
			else if (rbField != null || rbProp != null)
			{
				Vector3 velocity;
				if (rbField != null)
				{
					object? value = rbField.GetValue(Player.LocalPlayer);
					Rigidbody val3 = (Rigidbody)((value is Rigidbody) ? value : null);
					if (val3 != null)
					{
						velocity = val3.velocity;
						num = ((Vector3)(ref velocity)).magnitude;
					}
				}
				else if (rbProp != null)
				{
					object? value2 = rbProp.GetValue(Player.LocalPlayer);
					Rigidbody val4 = (Rigidbody)((value2 is Rigidbody) ? value2 : null);
					if (val4 != null)
					{
						velocity = val4.velocity;
						num = ((Vector3)(ref velocity)).magnitude;
					}
				}
			}
			if (num == 0f && currentMoveSpeedField != null && currentMoveSpeedField.GetValue(Player.LocalPlayer) is float num2)
			{
				num = num2;
			}
			if (num == 0f && moveVelocityField != null && moveVelocityField.GetValue(Player.LocalPlayer) is Vector3 val5)
			{
				num = ((Vector3)(ref val5)).magnitude;
			}
			if (num > 0f)
			{
				((TMP_Text)speedText).text = $"Speed: <color=#{ColorUtility.ToHtmlStringRGB(sky)}>{num:F1}</color> m/s";
			}
			else
			{
				((TMP_Text)speedText).text = "No Speed Detected";
			}
			if ((Object)(object)speedometerHudContainer != (Object)null)
			{
				RectTransform component = speedometerHudContainer.GetComponent<RectTransform>();
				float num3 = ((Carnometer.Instance != null && Carnometer.Instance.IsActive) ? (0f - Carnometer.Instance.GetSize.y) : 0f);
				component.anchoredPosition = new Vector2(0f, num3);
			}
		}
		catch (Exception ex)
		{
			SparrohPlugin.Logger.LogError((object)("Error in Speedometer.Update(): " + ex.Message));
		}
	}

	public void OnDestroy()
	{
		try
		{
			if ((Object)(object)speedometerHudContainer != (Object)null)
			{
				Object.Destroy((Object)(object)speedometerHudContainer);
			}
		}
		catch (Exception ex)
		{
			SparrohPlugin.Logger.LogError((object)("Error in Speedometer.OnDestroy(): " + ex.Message));
		}
	}
}
[HarmonyPatch]
internal class XPUI
{
	[HarmonyPatch(typeof(GearData), "GetLevelString")]
	[HarmonyPostfix]
	public static void NumericalXP__Postfix2(GearData __instance, ref string __result)
	{
		if (__instance.Level >= __instance.MaxLevel)
		{
			__result = "∞";
		}
		int num = __instance.NextLevelXPCost - __instance.LevelXP;
		__result = $"{TextBlocks.GetNumberString(__instance.Level)} (NEXT LEVEL: {num})";
	}
}
[CompilerGenerated]
[ExcludeFromCodeCoverage]
internal static class GitVersionInformation
{
	public const string AssemblySemFileVer = "0.0.1.0";

	public const string AssemblySemVer = "0.0.1.0";

	public const string BranchName = "master";

	public const string BuildMetaData = "";

	public const string CommitDate = "2025-12-26";

	public const string CommitsSinceVersionSource = "9";

	public const string EscapedBranchName = "master";

	public const string FullBuildMetaData = "Branch.master.Sha.9a85cfa9ae3bf110279278784d1abf1a8e8b7c4e";

	public const string FullSemVer = "0.0.1-9";

	public const string InformationalVersion = "0.0.1-9+Branch.master.Sha.9a85cfa9ae3bf110279278784d1abf1a8e8b7c4e";

	public const string Major = "0";

	public const string MajorMinorPatch = "0.0.1";

	public const string Minor = "0";

	public const string Patch = "1";

	public const string PreReleaseLabel = "";

	public const string PreReleaseLabelWithDash = "";

	public const string PreReleaseNumber = "9";

	public const string PreReleaseTag = "9";

	public const string PreReleaseTagWithDash = "-9";

	public const string SemVer = "0.0.1-9";

	public const string Sha = "9a85cfa9ae3bf110279278784d1abf1a8e8b7c4e";

	public const string ShortSha = "9a85cfa";

	public const string UncommittedChanges = "10";

	public const string VersionSourceSha = "";

	public const string WeightedPreReleaseNumber = "55009";
}
namespace ExpandedHUD
{
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "ExpandedHUD";

		public const string PLUGIN_NAME = "ExpandedHUD";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}