Decompiled source of SoloHUD v1.14.0

SoloHUD.dll

Decompiled 4 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using SoloShared;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.InputSystem.Utilities;
using UnityEngine.Localization;
using UnityEngine.Localization.Settings;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: AssemblyCompany("HappyTheLegend")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright (c) 2026 HappyTheLegend")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+84251d1fd4d525e86e0aca6c86990dfc4637245e")]
[assembly: AssemblyProduct("SoloHUD")]
[assembly: AssemblyTitle("SoloHUD")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.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 SoloShared
{
	internal static class Loc
	{
		private static Dictionary<string, string> _table = new Dictionary<string, string>(StringComparer.Ordinal);

		private static string _folder;

		private static string _mod = "Solo";

		private static string _loaded = "";

		private static float _nextCheck;

		private static Action<string> _log = delegate
		{
		};

		private static Action<string> _warn = delegate
		{
		};

		private static readonly SortedSet<string> _seen = new SortedSet<string>(StringComparer.Ordinal);

		private static bool _collect;

		internal static string Language
		{
			get
			{
				if (_loaded.Length != 0)
				{
					return _loaded;
				}
				return "en";
			}
		}

		internal static void Init(string modName, string dllPath, Action<string> log, Action<string> warn, bool collectStrings = false)
		{
			_mod = modName ?? "Solo";
			_log = log ?? ((Action<string>)delegate
			{
			});
			_warn = warn ?? ((Action<string>)delegate
			{
			});
			_collect = collectStrings;
			try
			{
				_folder = Path.GetDirectoryName(dllPath);
			}
			catch
			{
				_folder = null;
			}
			Reload(CurrentLanguage());
		}

		internal static string T(string english)
		{
			if (string.IsNullOrEmpty(english))
			{
				return english;
			}
			if (_collect)
			{
				lock (_seen)
				{
					_seen.Add(english);
				}
			}
			if (!_table.TryGetValue(english, out var value) || value.Length <= 0)
			{
				return english;
			}
			return value;
		}

		internal static string F(string english, params object[] args)
		{
			string format = T(english);
			try
			{
				return string.Format(format, args);
			}
			catch
			{
				try
				{
					return string.Format(english, args);
				}
				catch
				{
					return english;
				}
			}
		}

		internal static void Tick(float unscaledTime)
		{
			if (!(unscaledTime < _nextCheck))
			{
				_nextCheck = unscaledTime + 2f;
				string text = CurrentLanguage();
				if (text != _loaded)
				{
					Reload(text);
				}
			}
		}

		private static string CurrentLanguage()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Locale selectedLocale = LocalizationSettings.SelectedLocale;
				object obj;
				if (!((Object)(object)selectedLocale != (Object)null))
				{
					obj = "";
				}
				else
				{
					LocaleIdentifier identifier = selectedLocale.Identifier;
					obj = ((LocaleIdentifier)(ref identifier)).Code;
				}
				string text = (string)obj;
				return string.IsNullOrEmpty(text) ? "en" : text;
			}
			catch
			{
				return "en";
			}
		}

		private static void Reload(string code)
		{
			_loaded = code ?? "en";
			Dictionary<string, string> dictionary = new Dictionary<string, string>(StringComparer.Ordinal);
			if (!string.IsNullOrEmpty(_folder) && !_loaded.StartsWith("en", StringComparison.OrdinalIgnoreCase))
			{
				string text = Path.Combine(_folder, "lang");
				foreach (string item in Candidates(_loaded, text))
				{
					string path = Path.Combine(text, item + ".txt");
					if (File.Exists(path))
					{
						int num = Read(path, dictionary);
						_log($"[{_mod}] Language {item}: {num} line(s) from {Path.GetFileName(path)}.");
						break;
					}
				}
			}
			_table = dictionary;
			if (dictionary.Count > 0)
			{
				_log("[" + _mod + "] Following the game's language: " + _loaded + ".");
			}
			if (dictionary.Count == 0 && !_loaded.StartsWith("en", StringComparison.OrdinalIgnoreCase))
			{
				_log("[" + _mod + "] No translation file for '" + _loaded + "' — showing English. Add lang/" + _loaded + ".txt beside the mod to change that.");
			}
		}

		private static IEnumerable<string> Candidates(string code, string dir)
		{
			yield return code;
			string language = code;
			int num = code.IndexOf('-');
			if (num > 0)
			{
				language = code.Substring(0, num);
				yield return language;
			}
			string[] array;
			try
			{
				array = (Directory.Exists(dir) ? Directory.GetFiles(dir, "*.txt") : new string[0]);
			}
			catch
			{
				yield break;
			}
			string[] array2 = array;
			for (int i = 0; i < array2.Length; i++)
			{
				string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(array2[i]);
				if (fileNameWithoutExtension.StartsWith(language + "-", StringComparison.OrdinalIgnoreCase))
				{
					yield return fileNameWithoutExtension;
				}
			}
		}

		private static int Read(string path, Dictionary<string, string> into)
		{
			int num = 0;
			try
			{
				string text = null;
				string[] array = File.ReadAllLines(path, Encoding.UTF8);
				for (int i = 0; i < array.Length; i++)
				{
					string text2 = array[i].Trim();
					if (text2.Length == 0 || text2[0] == '#')
					{
						continue;
					}
					if (text2[0] == '=')
					{
						text = Unescape(text2.Substring(1).Trim());
					}
					else if (text2[0] == '>' && text != null)
					{
						string text3 = Unescape(text2.Substring(1).Trim());
						if (text3.Length > 0)
						{
							into[text] = text3;
							num++;
						}
						text = null;
					}
				}
			}
			catch (Exception ex)
			{
				_warn("[" + _mod + "] Couldn't read " + Path.GetFileName(path) + ": " + ex.Message);
			}
			return num;
		}

		private static string Unescape(string s)
		{
			return s.Replace("\\n", "\n");
		}

		private static string Escape(string s)
		{
			return s.Replace("\n", "\\n");
		}

		internal static void DumpSeen()
		{
			if (!_collect || string.IsNullOrEmpty(_folder))
			{
				return;
			}
			try
			{
				string text = Path.Combine(_folder, "lang");
				Directory.CreateDirectory(text);
				string path = Path.Combine(text, "_english.txt");
				StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.AppendLine("# Every line " + _mod + " has shown this session.");
				stringBuilder.AppendLine("# Copy this file to <language code>.txt and fill in the > lines.");
				stringBuilder.AppendLine("# Leave a > line empty to keep the English.");
				stringBuilder.AppendLine();
				lock (_seen)
				{
					foreach (string item in _seen)
					{
						stringBuilder.Append("= ").AppendLine(Escape(item));
						stringBuilder.AppendLine("> ");
					}
					File.WriteAllText(path, stringBuilder.ToString(), new UTF8Encoding(encoderShouldEmitUTF8Identifier: false));
					_log($"[{_mod}] Wrote {_seen.Count} line(s) to lang/_english.txt.");
				}
			}
			catch (Exception ex)
			{
				_warn("[" + _mod + "] Couldn't write the English list: " + ex.Message);
			}
		}
	}
}
namespace SoloHUD
{
	internal static class HudController
	{
		private static bool _visible = true;

		private static bool _keyWasDown;

		private static bool _fullListHeld;

		private static bool _firstTickLogged;

		private static float _buildWarnTimer;

		private static float _stateLogTimer;

		private static int _lastFrame = -1;

		private static bool _dotsDirty;

		private static readonly HashSet<string> _reportedErrors = new HashSet<string>();

		private static readonly HudData Data = new HudData();

		private static float _scanTimer;

		private const float ScanInterval = 0.25f;

		private static Texture2D _white;

		private static Texture2D _circle;

		private static GameObject _root;

		private static TextMeshProUGUI _infoText;

		private static RawImage _infoBg;

		private static RectTransform _radar;

		private static RawImage _radarBg;

		private static RawImage _mapImage;

		private static RawImage _centerDot;

		private static RawImage _fullBg;

		private static TextMeshProUGUI _fullText;

		private static readonly List<RawImage> _dots = new List<RawImage>();

		private const int MaxDots = 96;

		private static Camera _mapCam;

		private static Texture _mapTex;

		private static Material _mapMat;

		private static float _mapCamSearchTimer;

		private static bool _mapCamLogged;

		private static bool _mapTexIsFallback;

		private static Texture2D White
		{
			get
			{
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0019: Expected O, but got Unknown
				//IL_0020: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)_white == (Object)null)
				{
					_white = new Texture2D(1, 1);
					_white.SetPixel(0, 0, Color.white);
					_white.Apply();
					((Object)_white).hideFlags = (HideFlags)61;
				}
				return _white;
			}
		}

		private static Texture2D Circle
		{
			get
			{
				//IL_0016: Unknown result type (might be due to invalid IL or missing references)
				//IL_0020: Expected O, but got Unknown
				//IL_0038: Unknown result type (might be due to invalid IL or missing references)
				//IL_0047: Unknown result type (might be due to invalid IL or missing references)
				//IL_0076: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)_circle == (Object)null)
				{
					_circle = new Texture2D(32, 32, (TextureFormat)5, false);
					for (int i = 0; i < 32; i++)
					{
						for (int j = 0; j < 32; j++)
						{
							float num = Vector2.Distance(new Vector2((float)j + 0.5f, (float)i + 0.5f), new Vector2(16f, 16f));
							float num2 = Mathf.Clamp01(16f - num);
							_circle.SetPixel(j, i, new Color(1f, 1f, 1f, num2));
						}
					}
					_circle.Apply();
					((Texture)_circle).filterMode = (FilterMode)1;
					((Object)_circle).hideFlags = (HideFlags)61;
				}
				return _circle;
			}
		}

		public static void Tick()
		{
			if (!Plugin.Ready || _lastFrame == Time.frameCount)
			{
				return;
			}
			_lastFrame = Time.frameCount;
			try
			{
				if (!_firstTickLogged)
				{
					_firstTickLogged = true;
					bool flag = Plugin.Instance == null;
					bool flag2 = (Object)(object)Plugin.Instance == (Object)null;
					Plugin.Log.LogInfo((object)($"[SoloHUD] First tick — driver hook is firing. plugin ref-null={flag} " + string.Format("unity-null={0}{1}", flag2, (!flag && flag2) ? "  <- MonoBehaviour was destroyed (expected)" : "")));
				}
				HandleToggle();
				UpdateFullListHeld();
				if ((Object)(object)_root == (Object)null)
				{
					TryBuild();
				}
				if ((Object)(object)_root == (Object)null)
				{
					_buildWarnTimer -= Time.unscaledDeltaTime;
					if (_buildWarnTimer <= 0f)
					{
						_buildWarnTimer = 3f;
						Plugin.Log.LogWarning((object)($"[SoloHUD] Overlay not built yet — HUDCanvas={(Object)(object)HUDCanvas.instance != (Object)null} " + $"HaulUI={(Object)(object)HaulUI.instance != (Object)null}"));
					}
					return;
				}
				_scanTimer -= Time.unscaledDeltaTime;
				if (_scanTimer <= 0f)
				{
					_scanTimer = 0.25f;
					Data.Refresh();
					_dotsDirty = true;
					_stateLogTimer -= 0.25f;
					if (_stateLogTimer <= 0f)
					{
						_stateLogTimer = 15f;
						Plugin.Log.LogInfo((object)($"[SoloHUD] state: InLevel={Data.InLevel} value=${Data.TotalMapValue:n0} " + $"valuables={Data.RawValuableCount} monsterTypes={Data.Monsters.Count} " + $"enemies={Data.RawEnemyCount} players={Data.RawPlayerCount} " + "mapCam=" + (((Object)(object)_mapCam != (Object)null) ? ((Object)_mapCam).name : "none") + " err=" + Data.DiagError));
					}
				}
				if (_visible && Data.InLevel && Plugin.UseGameMap.Value)
				{
					EnsureGameMapLive();
				}
				bool flag3 = (Object)(object)MenuManager.instance != (Object)null && (Object)(object)MenuManager.instance.currentMenuPage != (Object)null;
				bool flag4 = Plugin.HideWhileMapOpen.Value && IsMapToolActive();
				bool flag5 = _visible && !flag3 && !flag4;
				_root.SetActive(flag5);
				if (flag5)
				{
					Render();
				}
			}
			catch (Exception ex)
			{
				if (_reportedErrors.Add(ex.StackTrace ?? ex.Message))
				{
					Plugin.Log.LogError((object)$"[SoloHUD] tick threw {ex.GetType().Name}: {ex.Message}\n{ex}");
				}
			}
		}

		private static void HandleToggle()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			Keyboard current = Keyboard.current;
			if (current == null)
			{
				return;
			}
			Key value = Plugin.ToggleKey.Value;
			KeyControl val = (((int)value == 0) ? null : current[value]);
			int num;
			if (val != null)
			{
				num = (((ButtonControl)val).isPressed ? 1 : 0);
				if (num != 0 && !_keyWasDown)
				{
					_visible = !_visible;
					Plugin.Log.LogInfo((object)("SoloHUD " + (_visible ? "shown" : "hidden") + "."));
				}
			}
			else
			{
				num = 0;
			}
			_keyWasDown = (byte)num != 0;
		}

		private static void UpdateFullListHeld()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: 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)
			Keyboard current = Keyboard.current;
			if (current == null)
			{
				_fullListHeld = false;
				return;
			}
			Key value = Plugin.MonsterListKey.Value;
			KeyControl val = (((int)value == 0) ? null : current[value]);
			_fullListHeld = val != null && ((ButtonControl)val).isPressed;
		}

		private static bool IsMapToolActive()
		{
			MapToolController instance = MapToolController.instance;
			if ((Object)(object)instance != (Object)null)
			{
				return instance.Active;
			}
			return false;
		}

		private static void EnsureGameMapLive()
		{
			Map instance = Map.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				return;
			}
			if (!instance.Active)
			{
				instance.ActiveSet(true);
			}
			if ((Object)(object)_mapTex != (Object)null && (Object)(object)_mapCam != (Object)null && !_mapTexIsFallback)
			{
				return;
			}
			_mapCamSearchTimer -= Time.unscaledDeltaTime;
			if (_mapCamSearchTimer > 0f)
			{
				return;
			}
			_mapCamSearchTimer = 1f;
			if ((Object)(object)_mapCam == (Object)null)
			{
				_mapCam = FindMapCamera(instance);
				if ((Object)(object)_mapCam != (Object)null)
				{
					Plugin.Log.LogInfo((object)($"[SoloHUD] Map camera '{((Object)_mapCam).name}' found (ortho={_mapCam.orthographic}, " + "target=" + (((Object)(object)_mapCam.targetTexture != (Object)null) ? (((Texture)_mapCam.targetTexture).width + "x" + ((Texture)_mapCam.targetTexture).height) : "none") + ")."));
				}
			}
			if ((Object)(object)_mapTex == (Object)null || _mapTexIsFallback)
			{
				Texture val = FindMapTexture();
				if ((Object)(object)val != (Object)null)
				{
					_mapTex = val;
				}
			}
		}

		private static Texture FindMapTexture()
		{
			MapToolController val = MapToolController.instance;
			if ((Object)(object)val == (Object)null)
			{
				MapToolController[] array = Object.FindObjectsOfType<MapToolController>();
				foreach (MapToolController val2 in array)
				{
					if (!((Object)(object)val2 == (Object)null))
					{
						Material val3 = (((Object)(object)val2.DisplayMesh != (Object)null) ? ((Renderer)val2.DisplayMesh).sharedMaterial : null);
						if ((Object)(object)val3 == (Object)null)
						{
							val3 = val2.DisplayMaterial;
						}
						if ((Object)(object)val3 != (Object)null && (Object)(object)FirstRenderTexture(val3) != (Object)null)
						{
							val = val2;
							break;
						}
					}
				}
				if ((Object)(object)val != (Object)null)
				{
					Plugin.Log.LogInfo((object)"[SoloHUD] Map device found by search (instance was null).");
				}
			}
			if ((Object)(object)val != (Object)null)
			{
				Material val4 = null;
				if ((Object)(object)val.DisplayMesh != (Object)null)
				{
					val4 = ((Renderer)val.DisplayMesh).sharedMaterial;
				}
				if ((Object)(object)val4 == (Object)null)
				{
					val4 = val.DisplayMaterial;
				}
				if ((Object)(object)val4 != (Object)null)
				{
					RenderTexture val5 = FirstRenderTexture(val4);
					if ((Object)(object)val5 != (Object)null)
					{
						_mapMat = Object.Instantiate<Material>(val4);
						((Object)_mapMat).hideFlags = (HideFlags)61;
						_mapTexIsFallback = false;
						Plugin.Log.LogInfo((object)($"[SoloHUD] Using map display texture '{((Object)val5).name}' ({((Texture)val5).width}x{((Texture)val5).height}) " + "from material '" + ((Object)val4).name + "' (shader '" + ((Object)val4.shader).name + "')."));
						return (Texture)(object)val5;
					}
					Plugin.Log.LogWarning((object)("[SoloHUD] Map display material '" + ((Object)val4).name + "' has no RenderTexture. Properties: " + string.Join(", ", val4.GetTexturePropertyNames())));
				}
			}
			if ((Object)(object)_mapCam != (Object)null && (Object)(object)_mapCam.targetTexture != (Object)null)
			{
				if (!_mapTexIsFallback)
				{
					Plugin.Log.LogInfo((object)"[SoloHUD] Falling back to the map camera's target texture (no underlay yet) — will keep watching for the map device.");
				}
				_mapTexIsFallback = true;
				return (Texture)(object)_mapCam.targetTexture;
			}
			return null;
		}

		private static RenderTexture FirstRenderTexture(Material mat)
		{
			Texture mainTexture = mat.mainTexture;
			RenderTexture val = (RenderTexture)(object)((mainTexture is RenderTexture) ? mainTexture : null);
			if (val != null)
			{
				return val;
			}
			string[] texturePropertyNames = mat.GetTexturePropertyNames();
			foreach (string text in texturePropertyNames)
			{
				Texture texture = mat.GetTexture(text);
				RenderTexture val2 = (RenderTexture)(object)((texture is RenderTexture) ? texture : null);
				if (val2 != null)
				{
					return val2;
				}
			}
			return null;
		}

		private static Camera FindMapCamera(Map map)
		{
			Camera[] componentsInChildren = ((Component)map).GetComponentsInChildren<Camera>(true);
			Camera[] array = componentsInChildren;
			foreach (Camera val in array)
			{
				if ((Object)(object)val.targetTexture != (Object)null)
				{
					return val;
				}
			}
			if (componentsInChildren.Length != 0)
			{
				return componentsInChildren[0];
			}
			Camera val2 = null;
			Camera[] array2 = Object.FindObjectsOfType<Camera>();
			array = array2;
			foreach (Camera val3 in array)
			{
				if (!((Object)(object)val3.targetTexture == (Object)null) && ((Object)val3).name.ToLowerInvariant().Contains("map"))
				{
					val2 = val3;
					break;
				}
			}
			if ((Object)(object)val2 == (Object)null && !_mapCamLogged)
			{
				_mapCamLogged = true;
				StringBuilder stringBuilder = new StringBuilder("[SoloHUD] No map camera found. Cameras present: ");
				array = array2;
				foreach (Camera val4 in array)
				{
					stringBuilder.Append($"'{((Object)val4).name}'(rt={(Object)(object)val4.targetTexture != (Object)null}) ");
				}
				stringBuilder.Append("— falling back to the dot radar.");
				Plugin.Log.LogWarning((object)stringBuilder.ToString());
			}
			return val2;
		}

		private static bool WorldToMapViewport(Vector3 worldPos, out Vector2 viewport)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: 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_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: 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_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: 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_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: 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_0086: 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_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: 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)
			viewport = Vector2.zero;
			Map instance = Map.Instance;
			Transform val = (((Object)(object)instance != (Object)null) ? instance.OverLayerParent : null);
			if ((Object)(object)instance == (Object)null || (Object)(object)_mapCam == (Object)null || (Object)(object)val == (Object)null)
			{
				return false;
			}
			Vector3 val2 = worldPos * instance.Scale + val.position;
			Vector3 val3 = val.InverseTransformPoint(val2);
			val3.y = 0f;
			val2 = val.TransformPoint(val3);
			Vector3 val4 = _mapCam.WorldToViewportPoint(val2);
			if (val4.z <= 0f)
			{
				return false;
			}
			viewport = new Vector2(val4.x, val4.y);
			return true;
		}

		private static void TryBuild()
		{
			//IL_0060: 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)
			//IL_00bb: 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_00e5: Expected O, but got Unknown
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: 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_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0266: Unknown result type (might be due to invalid IL or missing references)
			//IL_0272: Unknown result type (might be due to invalid IL or missing references)
			//IL_0277: Unknown result type (might be due to invalid IL or missing references)
			//IL_0286: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_030b: Unknown result type (might be due to invalid IL or missing references)
			//IL_033f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0346: Unknown result type (might be due to invalid IL or missing references)
			//IL_0361: Unknown result type (might be due to invalid IL or missing references)
			//IL_0375: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_0408: Unknown result type (might be due to invalid IL or missing references)
			//IL_0426: Unknown result type (might be due to invalid IL or missing references)
			//IL_043a: Unknown result type (might be due to invalid IL or missing references)
			//IL_045f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0493: Unknown result type (might be due to invalid IL or missing references)
			//IL_049a: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_04fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_054a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0583: Unknown result type (might be due to invalid IL or missing references)
			//IL_05bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_05d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_060c: Unknown result type (might be due to invalid IL or missing references)
			Transform val = null;
			if ((Object)(object)HUDCanvas.instance != (Object)null && (Object)(object)HUDCanvas.instance.rect != (Object)null)
			{
				val = (Transform)(object)HUDCanvas.instance.rect;
			}
			else if ((Object)(object)HaulUI.instance != (Object)null)
			{
				val = ((Component)HaulUI.instance).transform.parent;
			}
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			TMP_FontAsset val2 = null;
			Material val3 = null;
			float characterSpacing = 0f;
			FontStyles fontStyle = (FontStyles)0;
			HaulUI instance = HaulUI.instance;
			TextMeshProUGUI val4 = (((Object)(object)instance != (Object)null) ? ((Component)instance).GetComponent<TextMeshProUGUI>() : null);
			if ((Object)(object)val4 == (Object)null)
			{
				val4 = ((Component)val).GetComponentInChildren<TextMeshProUGUI>(true);
			}
			if ((Object)(object)val4 != (Object)null)
			{
				val2 = ((TMP_Text)val4).font;
				val3 = ((TMP_Text)val4).fontSharedMaterial;
				characterSpacing = ((TMP_Text)val4).characterSpacing;
				fontStyle = ((TMP_Text)val4).fontStyle;
			}
			if ((Object)(object)val2 == (Object)null)
			{
				Plugin.Log.LogWarning((object)"[SoloHUD] No TMP font found under the HUD yet; retrying.");
				return;
			}
			_root = new GameObject("SoloHUD_Root");
			RectTransform val5 = _root.AddComponent<RectTransform>();
			_root.transform.SetParent(val, false);
			val5.anchorMin = Vector2.zero;
			val5.anchorMax = Vector2.one;
			val5.offsetMin = Vector2.zero;
			val5.offsetMax = Vector2.zero;
			((Transform)val5).localScale = Vector3.one;
			Vector2 val6 = default(Vector2);
			((Vector2)(ref val6))..ctor(Plugin.PanelOffsetX.Value, Plugin.PanelOffsetY.Value);
			_infoBg = MakeRaw("InfoBg", (Transform)(object)val5, new Color(0f, 0f, 0f, 0f));
			AnchorBottomLeft(((Graphic)_infoBg).rectTransform, val6, new Vector2(380f, 120f));
			GameObject val7 = new GameObject("InfoText");
			val7.transform.SetParent((Transform)(object)val5, false);
			_infoText = val7.AddComponent<TextMeshProUGUI>();
			((TMP_Text)_infoText).font = val2;
			if ((Object)(object)val3 != (Object)null)
			{
				((TMP_Text)_infoText).fontSharedMaterial = val3;
			}
			((TMP_Text)_infoText).characterSpacing = characterSpacing;
			((TMP_Text)_infoText).fontStyle = fontStyle;
			((TMP_Text)_infoText).fontSize = Mathf.Max(6f, Plugin.PanelFontSize.Value);
			((TMP_Text)_infoText).lineSpacing = -8f;
			((Graphic)_infoText).color = Color.white;
			((TMP_Text)_infoText).alignment = (TextAlignmentOptions)1025;
			((TMP_Text)_infoText).enableWordWrapping = false;
			((Graphic)_infoText).raycastTarget = false;
			AnchorBottomLeft(((TMP_Text)_infoText).rectTransform, val6 + new Vector2(8f, 6f), new Vector2(360f, 400f));
			float num = Mathf.Max(60f, Plugin.RadarSize.Value);
			_radarBg = MakeRaw("Radar", (Transform)(object)val5, new Color(0f, 0f, 0f, 0.5f));
			_radar = ((Graphic)_radarBg).rectTransform;
			AnchorBottomRight(_radar, new Vector2(-24f, 24f), new Vector2(num, num));
			_mapImage = MakeRaw("MapRender", (Transform)(object)_radar, Color.white);
			RectTransform rectTransform = ((Graphic)_mapImage).rectTransform;
			RectTransform rectTransform2 = ((Graphic)_mapImage).rectTransform;
			Vector2 val8 = default(Vector2);
			((Vector2)(ref val8))..ctor(0.5f, 0.5f);
			rectTransform2.anchorMax = val8;
			rectTransform.anchorMin = val8;
			((Graphic)_mapImage).rectTransform.pivot = new Vector2(0.5f, 0.5f);
			((Graphic)_mapImage).rectTransform.anchoredPosition = Vector2.zero;
			((Behaviour)_mapImage).enabled = false;
			_centerDot = MakeRaw("You", (Transform)(object)_radar, new Color(0.3f, 1f, 0.4f));
			_centerDot.texture = (Texture)(object)Circle;
			RectTransform rectTransform3 = ((Graphic)_centerDot).rectTransform;
			RectTransform rectTransform4 = ((Graphic)_centerDot).rectTransform;
			((Vector2)(ref val8))..ctor(0.5f, 0.5f);
			rectTransform4.anchorMax = val8;
			rectTransform3.anchorMin = val8;
			((Graphic)_centerDot).rectTransform.pivot = new Vector2(0.5f, 0.5f);
			((Graphic)_centerDot).rectTransform.sizeDelta = new Vector2(7f, 7f);
			((Graphic)_centerDot).rectTransform.anchoredPosition = Vector2.zero;
			_fullBg = MakeRaw("FullListBg", (Transform)(object)val5, new Color(0f, 0f, 0f, 0.82f));
			RectTransform rectTransform5 = ((Graphic)_fullBg).rectTransform;
			RectTransform rectTransform6 = ((Graphic)_fullBg).rectTransform;
			((Vector2)(ref val8))..ctor(0.5f, 0.5f);
			rectTransform6.anchorMax = val8;
			rectTransform5.anchorMin = val8;
			((Graphic)_fullBg).rectTransform.pivot = new Vector2(0.5f, 0.5f);
			((Graphic)_fullBg).rectTransform.anchoredPosition = Vector2.zero;
			((Graphic)_fullBg).rectTransform.sizeDelta = new Vector2(420f, 300f);
			GameObject val9 = new GameObject("FullListText");
			val9.transform.SetParent((Transform)(object)((Graphic)_fullBg).rectTransform, false);
			_fullText = val9.AddComponent<TextMeshProUGUI>();
			((TMP_Text)_fullText).font = val2;
			if ((Object)(object)val3 != (Object)null)
			{
				((TMP_Text)_fullText).fontSharedMaterial = val3;
			}
			((TMP_Text)_fullText).characterSpacing = characterSpacing;
			((TMP_Text)_fullText).fontStyle = fontStyle;
			((TMP_Text)_fullText).fontSize = Mathf.Max(6f, Plugin.PanelFontSize.Value);
			((TMP_Text)_fullText).lineSpacing = -8f;
			((Graphic)_fullText).color = Color.white;
			((TMP_Text)_fullText).alignment = (TextAlignmentOptions)257;
			((TMP_Text)_fullText).enableWordWrapping = false;
			((Graphic)_fullText).raycastTarget = false;
			((TMP_Text)_fullText).rectTransform.anchorMin = Vector2.zero;
			((TMP_Text)_fullText).rectTransform.anchorMax = Vector2.one;
			((TMP_Text)_fullText).rectTransform.offsetMin = new Vector2(16f, 12f);
			((TMP_Text)_fullText).rectTransform.offsetMax = new Vector2(-16f, -12f);
			((Component)_fullBg).gameObject.SetActive(false);
			_dots.Clear();
			Plugin.Log.LogInfo((object)("[SoloHUD] Overlay attached to '" + ((Object)val).name + "' (font: " + ((Object)val2).name + ")."));
		}

		private static RawImage MakeRaw(string name, Transform parent, Color color)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name);
			val.transform.SetParent(parent, false);
			RawImage obj = val.AddComponent<RawImage>();
			obj.texture = (Texture)(object)White;
			((Graphic)obj).color = color;
			((Graphic)obj).raycastTarget = false;
			return obj;
		}

		private static void AnchorBottomLeft(RectTransform rt, Vector2 pos, Vector2 size)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: 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_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(0f, 0f);
			rt.anchorMax = val;
			rt.anchorMin = val;
			rt.pivot = new Vector2(0f, 0f);
			rt.sizeDelta = size;
			rt.anchoredPosition = pos;
			((Transform)rt).localScale = Vector3.one;
		}

		private static void AnchorBottomRight(RectTransform rt, Vector2 pos, Vector2 size)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: 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_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(1f, 0f);
			rt.anchorMax = val;
			rt.anchorMin = val;
			rt.pivot = new Vector2(1f, 0f);
			rt.sizeDelta = size;
			rt.anchoredPosition = pos;
			((Transform)rt).localScale = Vector3.one;
		}

		private static void Render()
		{
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_023b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0254: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_0331: Unknown result type (might be due to invalid IL or missing references)
			//IL_031b: Unknown result type (might be due to invalid IL or missing references)
			RenderFullList();
			bool flag = Plugin.ShowMapValue.Value || Plugin.ShowLooseValue.Value || Plugin.ShowRoomValue.Value || Plugin.ShowMonsterList.Value;
			bool flag2 = Plugin.ShowInfoPanel.Value && Data.InLevel && flag;
			((Component)_infoText).gameObject.SetActive(flag2);
			((Component)_infoBg).gameObject.SetActive(flag2);
			if (flag2)
			{
				float num = Mathf.Max(6f, Plugin.PanelFontSize.Value);
				if (!Mathf.Approximately(((TMP_Text)_infoText).fontSize, num))
				{
					((TMP_Text)_infoText).fontSize = num;
				}
				Rect rect = _root.GetComponent<RectTransform>().rect;
				float num2 = ((Rect)(ref rect)).height;
				if (num2 <= 0f)
				{
					num2 = Screen.height;
				}
				float num3 = num2 * Mathf.Clamp01(Plugin.PanelMaxHeightFraction.Value) - Plugin.PanelOffsetY.Value;
				int num4 = Mathf.Min(Data.Monsters.Count, Mathf.Max(1, Plugin.MonsterListMaxLines.Value));
				float preferredHeight;
				while (true)
				{
					((TMP_Text)_infoText).text = BuildInfoText(num4);
					((TMP_Text)_infoText).ForceMeshUpdate(false, false);
					preferredHeight = ((TMP_Text)_infoText).preferredHeight;
					if (preferredHeight <= num3 || num4 <= 0)
					{
						break;
					}
					num4--;
				}
				float num5 = Mathf.Clamp(((TMP_Text)_infoText).preferredWidth + 20f, 200f, 520f);
				((Graphic)_infoBg).rectTransform.sizeDelta = new Vector2(num5, Mathf.Max(40f, preferredHeight + 16f));
				float num6 = Mathf.Clamp01(Plugin.PanelOpacity.Value);
				((Graphic)_infoBg).color = new Color(0f, 0f, 0f, num6);
				((Behaviour)_infoBg).enabled = num6 > 0f;
			}
			bool flag3 = Plugin.ShowRadar.Value && Data.InLevel && Data.HasLocal;
			((Component)_radarBg).gameObject.SetActive(flag3);
			if (!flag3)
			{
				return;
			}
			float num7 = Mathf.Max(60f, Plugin.RadarSize.Value);
			if (!Mathf.Approximately(_radar.sizeDelta.x, num7))
			{
				_radar.sizeDelta = new Vector2(num7, num7);
			}
			bool flag4 = Plugin.UseGameMap.Value && (Object)(object)_mapTex != (Object)null;
			((Behaviour)_mapImage).enabled = flag4;
			if (flag4)
			{
				_mapImage.texture = _mapTex;
				Material val = (Plugin.UseMapScreenLook.Value ? _mapMat : null);
				if ((Object)(object)((Graphic)_mapImage).material != (Object)(object)val)
				{
					((Graphic)_mapImage).material = val;
				}
				FitToTexture(((Graphic)_mapImage).rectTransform, _mapTex, num7);
			}
			((Component)_centerDot).gameObject.SetActive(!flag4);
			if (!flag4)
			{
				((Graphic)_centerDot).color = (Data.FollowingDeathHead ? new Color(1f, 0.35f, 0.35f) : new Color(0.3f, 1f, 0.4f));
			}
			if (_dotsDirty)
			{
				_dotsDirty = false;
				if (flag4)
				{
					RenderMapDots();
				}
				else
				{
					RenderRadarDots();
				}
			}
		}

		private static void RenderFullList()
		{
			//IL_0092: 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_0100: Unknown result type (might be due to invalid IL or missing references)
			bool flag = _fullListHeld && Data.InLevel;
			if (((Component)_fullBg).gameObject.activeSelf != flag)
			{
				((Component)_fullBg).gameObject.SetActive(flag);
			}
			if (flag)
			{
				float num = Mathf.Max(6f, Plugin.PanelFontSize.Value);
				if (!Mathf.Approximately(((TMP_Text)_fullText).fontSize, num))
				{
					((TMP_Text)_fullText).fontSize = num;
				}
				((TMP_Text)_fullText).text = BuildFullListText();
				((TMP_Text)_fullText).ForceMeshUpdate(false, false);
				Rect rect = _root.GetComponent<RectTransform>().rect;
				float num2 = ((Rect)(ref rect)).height;
				if (num2 <= 0f)
				{
					num2 = Screen.height;
				}
				float num3 = Mathf.Clamp(((TMP_Text)_fullText).preferredWidth + 32f, 300f, 700f);
				float num4 = Mathf.Clamp(((TMP_Text)_fullText).preferredHeight + 24f, 80f, num2 * 0.9f);
				((Graphic)_fullBg).rectTransform.sizeDelta = new Vector2(num3, num4);
			}
		}

		private static string BuildFullListText()
		{
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Expected I4, but got Unknown
			int num = 0;
			foreach (MonsterGroup monster in Data.Monsters)
			{
				num += monster.Total;
			}
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.AppendLine($"<b><color=#FF8A65>All Monsters — {Data.Monsters.Count} types, {num} total</color></b>");
			if (Data.Monsters.Count == 0)
			{
				stringBuilder.Append("<color=#9E9E9E>none on this level</color>");
				return stringBuilder.ToString();
			}
			foreach (MonsterGroup monster2 in Data.Monsters)
			{
				string text = DiffHex(monster2.Difficulty);
				stringBuilder.AppendLine($"<color={text}>[D{monster2.Difficulty + 1}]</color> {monster2.Name} <b>x{monster2.Total}</b>" + "<size=70%><color=#9E9E9E> " + F("({0} active)", monster2.Active) + "</color></size>");
			}
			return stringBuilder.ToString().TrimEnd();
		}

		private static void FitToTexture(RectTransform rt, Texture tex, float box)
		{
			//IL_0043: 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_0051: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)tex == (Object)null) && tex.height > 0)
			{
				float num = (float)tex.width / (float)tex.height;
				float num2 = box;
				float num3 = box;
				if (num >= 1f)
				{
					num3 = box / num;
				}
				else
				{
					num2 = box * num;
				}
				Vector2 val = default(Vector2);
				((Vector2)(ref val))..ctor(num2, num3);
				if (rt.sizeDelta != val)
				{
					rt.sizeDelta = val;
				}
			}
		}

		private static string BuildInfoText(int monsterLines)
		{
			//IL_02aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d7: Expected I4, but got Unknown
			Loc.Tick(Time.unscaledTime);
			StringBuilder stringBuilder = new StringBuilder();
			if (Plugin.ShowMapValue.Value)
			{
				stringBuilder.AppendLine("<b><color=#AED581>" + T("Map Value") + "</color></b>  <color=#DCEDC8>$" + Money(Data.TotalMapValue) + "</color>");
				stringBuilder.AppendLine("<size=70%><color=#9E9E9E>" + T("Goal") + " $" + Money(Data.ExtractionGoal) + "   " + T("In extract") + " $" + Money(Data.CurrentHaul) + "</color></size>");
			}
			if (Plugin.ShowLooseValue.Value)
			{
				stringBuilder.AppendLine("<b><color=#FFD54F>" + T("Still out") + "</color></b>  <color=#FFF3C4>$" + Money(Data.LooseValue) + "</color><size=70%><color=#9E9E9E>  " + T("not in carts or extraction") + "</color></size>");
			}
			if (Plugin.ShowRoomValue.Value)
			{
				stringBuilder.AppendLine("<b><color=#81D4FA>" + T("This room") + "</color></b>  <color=#E1F5FE>$" + Money(Data.RoomValue) + "</color>");
			}
			if (!Plugin.ShowMonsterList.Value)
			{
				return stringBuilder.ToString().TrimEnd();
			}
			int num = 0;
			foreach (MonsterGroup monster in Data.Monsters)
			{
				num += monster.Total;
			}
			stringBuilder.AppendLine("<b><color=#FF8A65>" + F("Monsters ({0} types, {1} total)", Data.Monsters.Count, num) + "</color></b>");
			if (Data.Monsters.Count == 0)
			{
				stringBuilder.Append("<color=#9E9E9E>  " + T("none on this level") + "</color>");
				return stringBuilder.ToString();
			}
			int num2 = Mathf.Clamp(monsterLines, 0, Data.Monsters.Count);
			for (int i = 0; i < num2; i++)
			{
				MonsterGroup monsterGroup = Data.Monsters[i];
				string text = DiffHex(monsterGroup.Difficulty);
				stringBuilder.AppendLine($"  <color={text}>[D{monsterGroup.Difficulty + 1}]</color> {monsterGroup.Name} <b>x{monsterGroup.Total}</b>" + "<size=70%><color=#9E9E9E> " + F("({0} active)", monsterGroup.Active) + "</color></size>");
			}
			if (Data.Monsters.Count > num2)
			{
				stringBuilder.Append("<size=80%><color=#9E9E9E>  " + F("+ {0} more type(s)…", Data.Monsters.Count - num2) + "</color></size>");
			}
			return stringBuilder.ToString();
		}

		private static string T(string english)
		{
			return Loc.T(english);
		}

		private static string F(string english, params object[] args)
		{
			return Loc.F(english, args);
		}

		private static string Money(int amount)
		{
			try
			{
				return SemiFunc.DollarGetString(amount);
			}
			catch
			{
				return amount.ToString("n0");
			}
		}

		private static void RenderMapDots()
		{
			//IL_000a: 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)
			float x = ((Graphic)_mapImage).rectTransform.sizeDelta.x;
			float y = ((Graphic)_mapImage).rectTransform.sizeDelta.y;
			int index = 0;
			foreach (Blip monsterBlip in Data.MonsterBlips)
			{
				PlaceMapDot(ref index, monsterBlip, x, y, 7f);
			}
			HideUnusedDots(index);
		}

		private static void PlaceMapDot(ref int index, Blip b, float w, float h, float dotSize)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: 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_003e: 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_005c: 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_0094: 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)
			if (index < 96 && WorldToMapViewport(b.WorldPos, out var viewport) && !(viewport.x < 0f) && !(viewport.x > 1f) && !(viewport.y < 0f) && !(viewport.y > 1f))
			{
				Vector2 anchoredPosition = default(Vector2);
				((Vector2)(ref anchoredPosition))..ctor((viewport.x - 0.5f) * w, (viewport.y - 0.5f) * h);
				RawImage dot = GetDot(index++);
				((Graphic)dot).color = b.Color;
				((Graphic)dot).rectTransform.sizeDelta = new Vector2(dotSize, dotSize);
				((Graphic)dot).rectTransform.anchoredPosition = anchoredPosition;
				if (!((Component)dot).gameObject.activeSelf)
				{
					((Component)dot).gameObject.SetActive(true);
				}
			}
		}

		private static void RenderRadarDots()
		{
			//IL_0005: 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_008b: 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)
			float num = _radar.sizeDelta.x * 0.5f;
			float num2 = Mathf.Max(1f, Plugin.RadarRange.Value);
			float scale = num / num2;
			float yaw = 0f;
			if (Plugin.RadarRotateWithCamera.Value && (Object)(object)Camera.main != (Object)null)
			{
				yaw = ((Component)Camera.main).transform.eulerAngles.y;
			}
			int index = 0;
			foreach (Blip monsterBlip in Data.MonsterBlips)
			{
				PlaceDot(ref index, monsterBlip, Data.LocalPos, scale, num, yaw, 8f);
			}
			foreach (Blip playerBlip in Data.PlayerBlips)
			{
				PlaceDot(ref index, playerBlip, Data.LocalPos, scale, num, yaw, 7f);
			}
			HideUnusedDots(index);
		}

		private static void HideUnusedDots(int usedCount)
		{
			for (int i = usedCount; i < _dots.Count; i++)
			{
				if (((Component)_dots[i]).gameObject.activeSelf)
				{
					((Component)_dots[i]).gameObject.SetActive(false);
				}
			}
		}

		private static void PlaceDot(ref int index, Blip b, Vector3 origin, float scale, float radius, float yaw, float dotSize)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: 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_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			if (index < 96)
			{
				float num = b.WorldPos.x - origin.x;
				float num2 = b.WorldPos.z - origin.z;
				if (yaw != 0f)
				{
					float num3 = (0f - yaw) * (MathF.PI / 180f);
					float num4 = Mathf.Cos(num3);
					float num5 = Mathf.Sin(num3);
					float num6 = num * num4 - num2 * num5;
					float num7 = num * num5 + num2 * num4;
					num = num6;
					num2 = num7;
				}
				Vector2 anchoredPosition = default(Vector2);
				((Vector2)(ref anchoredPosition))..ctor(num * scale, num2 * scale);
				if (((Vector2)(ref anchoredPosition)).magnitude > radius)
				{
					anchoredPosition = ((Vector2)(ref anchoredPosition)).normalized * radius;
				}
				RawImage dot = GetDot(index++);
				((Graphic)dot).color = b.Color;
				((Graphic)dot).rectTransform.sizeDelta = new Vector2(dotSize, dotSize);
				((Graphic)dot).rectTransform.anchoredPosition = anchoredPosition;
				if (!((Component)dot).gameObject.activeSelf)
				{
					((Component)dot).gameObject.SetActive(true);
				}
			}
		}

		private static RawImage GetDot(int index)
		{
			//IL_000f: 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_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: 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)
			Vector2 val2 = default(Vector2);
			while (_dots.Count <= index)
			{
				RawImage val = MakeRaw("Dot", (Transform)(object)_radar, Color.white);
				val.texture = (Texture)(object)Circle;
				RectTransform rectTransform = ((Graphic)val).rectTransform;
				RectTransform rectTransform2 = ((Graphic)val).rectTransform;
				((Vector2)(ref val2))..ctor(0.5f, 0.5f);
				rectTransform2.anchorMax = val2;
				rectTransform.anchorMin = val2;
				((Graphic)val).rectTransform.pivot = new Vector2(0.5f, 0.5f);
				((Graphic)val).rectTransform.sizeDelta = new Vector2(8f, 8f);
				_dots.Add(val);
			}
			return _dots[index];
		}

		private static string DiffHex(Difficulty d)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			if ((int)d != 1)
			{
				if ((int)d == 2)
				{
					return "#FF4033";
				}
				return "#FFE633";
			}
			return "#FF9933";
		}
	}
	internal struct Blip
	{
		public Vector3 WorldPos;

		public Color Color;
	}
	internal class MonsterGroup
	{
		public string Name;

		public Difficulty Difficulty;

		public int Total;

		public int Active;
	}
	internal class HudData
	{
		public bool InLevel;

		public int TotalMapValue;

		public int LooseValue;

		public int RoomValue;

		private static FieldInfo _bankedField;

		private static bool _bankedLookupDone;

		public int ExtractionGoal;

		public int CurrentHaul;

		private const int MaxBlips = 80;

		public readonly List<MonsterGroup> Monsters = new List<MonsterGroup>();

		public readonly List<Blip> MonsterBlips = new List<Blip>();

		public readonly List<Blip> PlayerBlips = new List<Blip>();

		public Vector3 LocalPos;

		public bool FollowingDeathHead;

		public bool HasLocal;

		public bool DiagRunManagerNull;

		public bool DiagPlayerAvatarNull;

		public bool DiagEnemyDirectorNull;

		public bool DiagRunIsLevel;

		public int RawValuableCount;

		public int RawEnemyCount;

		public int RawPlayerCount;

		public string DiagError;

		private static float CartBankedValue()
		{
			if (!_bankedLookupDone)
			{
				_bankedLookupDone = true;
				try
				{
					Type type = null;
					Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
					for (int i = 0; i < assemblies.Length; i++)
					{
						type = assemblies[i].GetType("SoloHost.CartDimension");
						if (type != null)
						{
							break;
						}
					}
					if (type != null)
					{
						_bankedField = type.GetField("BankedTotalMirror", BindingFlags.Static | BindingFlags.Public);
					}
					Plugin.Log.LogInfo((object)((_bankedField != null) ? "[SoloHUD] Cart-banked value will be included in map value." : "[SoloHUD] SoloHost cart banking not found - map value is valuables only."));
				}
				catch
				{
					_bankedField = null;
				}
			}
			try
			{
				return (_bankedField != null) ? ((float)_bankedField.GetValue(null)) : 0f;
			}
			catch
			{
				return 0f;
			}
		}

		public void Refresh()
		{
			//IL_02a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
			Monsters.Clear();
			MonsterBlips.Clear();
			PlayerBlips.Clear();
			TotalMapValue = 0;
			LooseValue = 0;
			RoomValue = 0;
			ExtractionGoal = 0;
			CurrentHaul = 0;
			HasLocal = false;
			InLevel = false;
			DiagError = null;
			try
			{
				DiagRunManagerNull = (Object)(object)RunManager.instance == (Object)null;
				DiagPlayerAvatarNull = (Object)(object)PlayerAvatar.instance == (Object)null;
				DiagEnemyDirectorNull = (Object)(object)EnemyDirector.instance == (Object)null;
				ValuableObject[] array = Object.FindObjectsOfType<ValuableObject>();
				RawValuableCount = array.Length;
				float num = 0f;
				float num2 = 0f;
				float num3 = 0f;
				HashSet<GameObject> hashSet = new HashSet<GameObject>();
				List<GameObject> list = (((Object)(object)RoundDirector.instance != (Object)null) ? RoundDirector.instance.dollarHaulList : null);
				if (list != null)
				{
					foreach (GameObject item in list)
					{
						if ((Object)(object)item != (Object)null)
						{
							hashSet.Add(item);
						}
					}
				}
				List<RoomVolume> list2 = MyRooms();
				ValuableObject[] array2 = array;
				foreach (ValuableObject val in array2)
				{
					if (!((Object)(object)val == (Object)null))
					{
						float dollarValueCurrent = val.dollarValueCurrent;
						num += dollarValueCurrent;
						PhysGrabObjectImpactDetector val2 = (((Object)(object)val.physGrabObject != (Object)null) ? val.physGrabObject.impactDetector : null);
						if ((!((Object)(object)val2 != (Object)null) || !val2.inCart) && !hashSet.Contains(((Component)val).gameObject))
						{
							num2 += dollarValueCurrent;
						}
						if (list2 != null && SharesRoom(val.roomVolumeCheck, list2))
						{
							num3 += dollarValueCurrent;
						}
					}
				}
				LooseValue = Mathf.RoundToInt(num2);
				RoomValue = Mathf.RoundToInt(num3);
				TotalMapValue = Mathf.RoundToInt(num + CartBankedValue());
				RawEnemyCount = ((!DiagEnemyDirectorNull && EnemyDirector.instance.enemiesSpawned != null) ? EnemyDirector.instance.enemiesSpawned.Count : 0);
				GameDirector instance = GameDirector.instance;
				RawPlayerCount = (((Object)(object)instance != (Object)null && instance.PlayerList != null) ? instance.PlayerList.Count : 0);
				if (!DiagRunManagerNull)
				{
					try
					{
						DiagRunIsLevel = SemiFunc.RunIsLevel();
					}
					catch (Exception ex)
					{
						DiagRunIsLevel = false;
						DiagError = "RunIsLevel: " + ex.Message;
					}
				}
				else
				{
					DiagRunIsLevel = false;
				}
				if (!DiagRunManagerNull && !DiagPlayerAvatarNull && DiagRunIsLevel)
				{
					InLevel = true;
					LocalPos = LocalViewPosition(PlayerAvatar.instance);
					HasLocal = true;
					RefreshMonsters();
					RefreshPlayers();
					RoundDirector instance2 = RoundDirector.instance;
					if ((Object)(object)instance2 != (Object)null)
					{
						CurrentHaul = instance2.currentHaul;
						ExtractionGoal = instance2.haulGoal;
					}
				}
			}
			catch (Exception ex2)
			{
				InLevel = false;
				DiagError = ex2.GetType().Name + ": " + ex2.Message;
				Plugin.Log.LogWarning((object)("SoloHUD scan error: " + DiagError));
			}
		}

		private static List<RoomVolume> MyRooms()
		{
			PlayerAvatar instance = PlayerAvatar.instance;
			if ((Object)(object)instance == (Object)null)
			{
				return null;
			}
			RoomVolumeCheck roomVolumeCheck = instance.RoomVolumeCheck;
			if ((instance.isDisabled || instance.deadSet) && (Object)(object)instance.playerDeathHead != (Object)null && (Object)(object)instance.playerDeathHead.physGrabObject != (Object)null && (Object)(object)instance.playerDeathHead.physGrabObject.roomVolumeCheck != (Object)null)
			{
				roomVolumeCheck = instance.playerDeathHead.physGrabObject.roomVolumeCheck;
			}
			if (!((Object)(object)roomVolumeCheck != (Object)null))
			{
				return null;
			}
			return roomVolumeCheck.CurrentRooms;
		}

		private static bool SharesRoom(RoomVolumeCheck check, List<RoomVolume> rooms)
		{
			if ((Object)(object)check == (Object)null || check.CurrentRooms == null || rooms.Count == 0)
			{
				return false;
			}
			foreach (RoomVolume currentRoom in check.CurrentRooms)
			{
				if ((Object)(object)currentRoom != (Object)null && rooms.Contains(currentRoom))
				{
					return true;
				}
			}
			return false;
		}

		private Vector3 LocalViewPosition(PlayerAvatar me)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			FollowingDeathHead = false;
			if ((Object)(object)me == (Object)null)
			{
				return Vector3.zero;
			}
			bool num = me.isDisabled || me.deadSet;
			PlayerDeathHead playerDeathHead = me.playerDeathHead;
			if (num && (Object)(object)playerDeathHead != (Object)null)
			{
				PhysGrabObject physGrabObject = playerDeathHead.physGrabObject;
				FollowingDeathHead = true;
				if (!((Object)(object)physGrabObject != (Object)null))
				{
					return ((Component)playerDeathHead).transform.position;
				}
				return ((Component)physGrabObject).transform.position;
			}
			return ((Component)me).transform.position;
		}

		private void RefreshMonsters()
		{
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			EnemyDirector instance = EnemyDirector.instance;
			if ((Object)(object)instance == (Object)null || instance.enemiesSpawned == null)
			{
				return;
			}
			Dictionary<string, MonsterGroup> dictionary = new Dictionary<string, MonsterGroup>();
			foreach (EnemyParent item in instance.enemiesSpawned)
			{
				if (!((Object)(object)item == (Object)null))
				{
					string text = (string.IsNullOrEmpty(item.enemyName) ? "Unknown" : item.enemyName);
					if (!dictionary.TryGetValue(text, out var value))
					{
						value = (dictionary[text] = new MonsterGroup
						{
							Name = text,
							Difficulty = item.difficulty
						});
						Monsters.Add(value);
					}
					value.Total++;
					if (item.Spawned)
					{
						value.Active++;
					}
					if (item.Spawned && (Object)(object)item.Enemy != (Object)null && MonsterBlips.Count < 80)
					{
						MonsterBlips.Add(new Blip
						{
							WorldPos = ((Component)item.Enemy).transform.position,
							Color = DifficultyColor(item.difficulty)
						});
					}
				}
			}
			Monsters.Sort(delegate(MonsterGroup a, MonsterGroup b)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0007: Expected I4, but got Unknown
				//IL_000a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0014: Expected I4, but got Unknown
				int num = ((int)b.Difficulty).CompareTo((int)a.Difficulty);
				return (num == 0) ? b.Total.CompareTo(a.Total) : num;
			});
		}

		private void RefreshPlayers()
		{
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			GameDirector instance = GameDirector.instance;
			if ((Object)(object)instance == (Object)null || instance.PlayerList == null)
			{
				return;
			}
			Color color = default(Color);
			foreach (PlayerAvatar player in instance.PlayerList)
			{
				if (!((Object)(object)player == (Object)null) && !player.isDisabled)
				{
					if (player.deadSet)
					{
						((Color)(ref color))..ctor(0.6f, 0.6f, 0.6f);
					}
					else if (player.isLocal)
					{
						((Color)(ref color))..ctor(0.3f, 1f, 0.4f);
					}
					else
					{
						((Color)(ref color))..ctor(0.35f, 0.8f, 1f);
					}
					PlayerBlips.Add(new Blip
					{
						WorldPos = ((Component)player).transform.position,
						Color = color
					});
				}
			}
		}

		internal static Color DifficultyColor(Difficulty d)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			if ((int)d != 1)
			{
				if ((int)d == 2)
				{
					return new Color(1f, 0.25f, 0.2f);
				}
				return new Color(1f, 0.9f, 0.2f);
			}
			return new Color(1f, 0.6f, 0.1f);
		}
	}
	internal static class HudSettings
	{
		[HarmonyPatch(typeof(MenuPageSettingsPage), "Start")]
		internal static class GameplayPagePatch
		{
			private static void Postfix(MenuPageSettingsPage __instance)
			{
				//IL_001e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0024: Invalid comparison between Unknown and I4
				if (!Plugin.Ready || (Object)(object)__instance == (Object)null || !Plugin.ShowInGameSettings.Value || (int)__instance.settingType != 1)
				{
					return;
				}
				try
				{
					((MonoBehaviour)__instance).StartCoroutine(AddTo(__instance));
				}
				catch (Exception ex)
				{
					Plugin.Log.LogWarning((object)("[SoloHUD] Gameplay page hook failed: " + ex.Message));
				}
			}
		}

		[HarmonyPatch(typeof(MenuPageSettingsControls), "Start")]
		internal static class ControlsPagePatch
		{
			private static void Postfix(MenuPageSettingsControls __instance)
			{
				if (!Plugin.Ready || (Object)(object)__instance == (Object)null || !Plugin.ShowInGameSettings.Value)
				{
					return;
				}
				try
				{
					((MonoBehaviour)__instance).StartCoroutine(HudKeyRow.AddTo(__instance));
				}
				catch (Exception ex)
				{
					Plugin.Log.LogWarning((object)("[SoloHUD] Controls page hook failed: " + ex.Message));
				}
			}
		}

		private const string Tag = "SoloHUD Row";

		private const string Prefix = "HUD ";

		private static IEnumerator AddTo(MenuPageSettingsPage page)
		{
			yield return null;
			Loc.Tick(Time.unscaledTime);
			if ((Object)(object)page == (Object)null || ((Component)page).GetComponentsInChildren<Transform>(true).Any((Transform t) => (Object)(object)t != (Object)null && ((Object)t).name == "SoloHUD Row"))
			{
				yield break;
			}
			MenuSlider[] componentsInChildren = ((Component)page).GetComponentsInChildren<MenuSlider>(true);
			MenuSlider sliderTemplate = ((IEnumerable<MenuSlider>)componentsInChildren).FirstOrDefault((Func<MenuSlider, bool>)((MenuSlider s) => (Object)(object)s != (Object)null && !s.hasCustomOptions)) ?? componentsInChildren.FirstOrDefault();
			MenuTwoOptions toggleTemplate = ((Component)page).GetComponentsInChildren<MenuTwoOptions>(true).FirstOrDefault();
			if ((Object)(object)sliderTemplate == (Object)null || (Object)(object)toggleTemplate == (Object)null)
			{
				Plugin.Log.LogWarning((object)($"[SoloHUD] Gameplay page has no row to copy (slider={(Object)(object)sliderTemplate != (Object)null}, " + $"toggle={(Object)(object)toggleTemplate != (Object)null}) — leaving it alone."));
				yield break;
			}
			List<Transform> list = (from t in ((Component)page).GetComponentsInChildren<Transform>(true)
				where (Object)(object)t != (Object)null && ((Object)(object)((Component)t).GetComponent<MenuSlider>() != (Object)null || (Object)(object)((Component)t).GetComponent<MenuTwoOptions>() != (Object)null)
				orderby t.localPosition.y descending
				select t).ToList();
			Transform val = list[list.Count - 1];
			Transform parent = val.parent;
			float gap = ((list.Count > 1) ? Mathf.Abs(list[0].localPosition.y - list[1].localPosition.y) : 34f);
			if (gap < 1f)
			{
				gap = 34f;
			}
			float y = val.localPosition.y;
			int added = 0;
			Heading("SOLOHUD", major: true);
			Heading("Info Panel", major: false);
			Toggle("Info Panel", Plugin.ShowInfoPanel);
			Toggle("Map Value", Plugin.ShowMapValue);
			Toggle("Still Out Value", Plugin.ShowLooseValue);
			Toggle("Room Value", Plugin.ShowRoomValue);
			Toggle("Monster List", Plugin.ShowMonsterList);
			Slider("Monster Lines", Steps(1, 1, 30, ""), () => Plugin.MonsterListMaxLines.Value - 1, delegate(int i)
			{
				Plugin.MonsterListMaxLines.Value = i + 1;
			});
			Slider("Panel Text Size", Steps(8, 1, 23, ""), () => Mathf.RoundToInt(Plugin.PanelFontSize.Value) - 8, delegate(int i)
			{
				Plugin.PanelFontSize.Value = 8 + i;
			});
			Slider("Panel Background", Steps(0, 10, 11, "%"), () => Mathf.RoundToInt(Plugin.PanelOpacity.Value * 10f), delegate(int i)
			{
				Plugin.PanelOpacity.Value = (float)i / 10f;
			});
			Heading("Minimap", major: false);
			Toggle("Minimap", Plugin.ShowRadar);
			Slider("Minimap Size", Steps(60, 20, 13, ""), () => Mathf.RoundToInt((Plugin.RadarSize.Value - 60f) / 20f), delegate(int i)
			{
				Plugin.RadarSize.Value = 60f + (float)i * 20f;
			});
			Slider("Minimap Range", Steps(10, 5, 19, "m"), () => Mathf.RoundToInt((Plugin.RadarRange.Value - 10f) / 5f), delegate(int i)
			{
				Plugin.RadarRange.Value = 10f + (float)i * 5f;
			});
			Toggle("Minimap Real Map", Plugin.UseGameMap);
			Toggle("Minimap Screen Look", Plugin.UseMapScreenLook);
			Toggle("Hide With Tab Map", Plugin.HideWhileMapOpen);
			MenuScrollBox[] componentsInChildren2 = ((Component)page).GetComponentsInChildren<MenuScrollBox>(true);
			foreach (MenuScrollBox val2 in componentsInChildren2)
			{
				if (!((Object)(object)val2 == (Object)null))
				{
					try
					{
						val2.RecalculateScrollHeight();
					}
					catch
					{
					}
				}
			}
			Plugin.Log.LogInfo((object)$"[SoloHUD] Added {added} row(s) to the game's Gameplay settings.");
			void Heading(string text, bool major)
			{
				y -= (major ? (gap * 1.5f) : gap);
				Header((Component)(object)toggleTemplate, TitleOf((Component)(object)toggleTemplate), parent, y, text, major, "SoloHUD Row");
			}
			void Slider(string name, string[] labels, Func<int> read, Action<int> write)
			{
				y -= gap;
				if (AddSlider(sliderTemplate, parent, y, name, labels, read, write))
				{
					added++;
				}
			}
			void Toggle(string name, ConfigEntry<bool> entry)
			{
				y -= gap;
				if (AddToggle(toggleTemplate, parent, y, name, () => entry.Value, delegate(bool v)
				{
					entry.Value = v;
				}))
				{
					added++;
				}
			}
		}

		internal static GameObject CloneDormant(Component template, Transform parent, float y, string tag)
		{
			//IL_003a: 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_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: 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)
			GameObject gameObject = template.gameObject;
			bool activeSelf = gameObject.activeSelf;
			gameObject.SetActive(false);
			GameObject val;
			try
			{
				val = Object.Instantiate<GameObject>(gameObject, parent);
			}
			finally
			{
				gameObject.SetActive(activeSelf);
			}
			((Object)val).name = tag;
			val.transform.localPosition = new Vector3(template.transform.localPosition.x, y, template.transform.localPosition.z);
			val.transform.localScale = template.transform.localScale;
			val.transform.localRotation = template.transform.localRotation;
			MonoBehaviour[] componentsInChildren = val.GetComponentsInChildren<MonoBehaviour>(true);
			foreach (MonoBehaviour val2 in componentsInChildren)
			{
				if (!((Object)(object)val2 == (Object)null) && ((object)val2).GetType().Name.IndexOf("Localize", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					Object.DestroyImmediate((Object)(object)val2);
				}
			}
			return val;
		}

		private static bool AddSlider(MenuSlider template, Transform parent, float y, string name, string[] labels, Func<int> read, Action<int> write)
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Expected O, but got Unknown
			try
			{
				GameObject val = CloneDormant((Component)(object)template, parent, y, "SoloHUD Row");
				MenuSlider component = val.GetComponent<MenuSlider>();
				if ((Object)(object)component == (Object)null)
				{
					Object.DestroyImmediate((Object)(object)val);
					return false;
				}
				Strip<MenuSetting>(val);
				Strip<MenuInputPercentSetting>(val);
				Strip<MenuBigSettingText>(val);
				component.onChange = new UnityEvent();
				component.customOptions = new List<CustomOption>();
				component.hasCustomOptions = false;
				component.hasCustomValues = false;
				component.hasBar = true;
				component.wrapAround = false;
				component.buttonSegmentJump = 1;
				component.pointerSegmentJump = 1;
				component.startValue = 0;
				component.endValue = labels.Length - 1;
				component.stringAtStartOfValue = "";
				component.stringAtEndOfValue = "";
				component.elementName = "HUD " + Loc.T(name);
				int num = Mathf.Clamp(read(), 0, labels.Length - 1);
				component.settingsValue = (float)num / (float)(labels.Length - 1);
				PruneClicks(val, (Component)(object)component, "OnIncrease", "OnDecrease");
				val.AddComponent<HudSliderRow>().Bind(component, "HUD " + Loc.T(name), labels, write);
				val.SetActive(true);
				return true;
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("[SoloHUD] Couldn't add the '" + name + "' row: " + ex.Message));
				return false;
			}
		}

		private static bool AddToggle(MenuTwoOptions template, Transform parent, float y, string name, Func<bool> read, Action<bool> write)
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Expected O, but got Unknown
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Expected O, but got Unknown
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Expected O, but got Unknown
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Expected O, but got Unknown
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Expected O, but got Unknown
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Expected O, but got Unknown
			try
			{
				GameObject val = CloneDormant((Component)(object)template, parent, y, "SoloHUD Row");
				MenuTwoOptions two = val.GetComponent<MenuTwoOptions>();
				if ((Object)(object)two == (Object)null)
				{
					Object.DestroyImmediate((Object)(object)val);
					return false;
				}
				two.onOption1 = new UnityEvent();
				two.onOption2 = new UnityEvent();
				two.fetchSetting = new UnityEvent();
				two.customEvents = true;
				two.customFetch = true;
				two.settingSet = false;
				two.settingName = "HUD " + Loc.T(name);
				two.fetchSetting.AddListener((UnityAction)delegate
				{
					try
					{
						two.startSettingFetch = read();
					}
					catch
					{
					}
				});
				two.onOption1.AddListener((UnityAction)delegate
				{
					try
					{
						write(obj: true);
					}
					catch
					{
					}
				});
				two.onOption2.AddListener((UnityAction)delegate
				{
					try
					{
						write(obj: false);
					}
					catch
					{
					}
				});
				PruneClicks(val, (Component)(object)two, "OnOption1", "OnOption2");
				val.AddComponent<HudToggleRow>().Bind(two, "HUD " + Loc.T(name));
				val.SetActive(true);
				return true;
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("[SoloHUD] Couldn't add the '" + name + "' row: " + ex.Message));
				return false;
			}
		}

		internal static TextMeshProUGUI TitleOf(Component row)
		{
			HashSet<TextMeshProUGUI> exclude = new HashSet<TextMeshProUGUI>();
			MenuTwoOptions val = (MenuTwoOptions)(object)((row is MenuTwoOptions) ? row : null);
			if (val != null)
			{
				exclude.Add(val.option1TextMesh);
				exclude.Add(val.option2TextMesh);
			}
			MenuBigButton component = row.GetComponent<MenuBigButton>();
			if ((Object)(object)component != (Object)null && (Object)(object)component.menuButton != (Object)null)
			{
				exclude.Add(component.menuButton.buttonText);
			}
			return ((IEnumerable<TextMeshProUGUI>)row.GetComponentsInChildren<TextMeshProUGUI>(true)).FirstOrDefault((Func<TextMeshProUGUI, bool>)((TextMeshProUGUI t) => (Object)(object)t != (Object)null && !exclude.Contains(t)));
		}

		internal static void Header(Component row, TextMeshProUGUI title, Transform parent, float y, string text, bool major, string tag)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: 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_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: 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_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0255: Unknown result type (might be due to invalid IL or missing references)
			//IL_0261: Unknown result type (might be due to invalid IL or missing references)
			//IL_026d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0279: Unknown result type (might be due to invalid IL or missing references)
			//IL_0289: Unknown result type (might be due to invalid IL or missing references)
			//IL_0245: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)row == (Object)null || (Object)(object)title == (Object)null || (Object)(object)parent == (Object)null)
			{
				return;
			}
			try
			{
				Vector3 val = parent.InverseTransformPoint(((TMP_Text)title).transform.position);
				float x = val.x;
				float num = val.y - row.transform.localPosition.y;
				GameObject val2 = Object.Instantiate<GameObject>(((Component)title).gameObject, parent);
				((Object)val2).name = tag;
				foreach (Transform item in ((IEnumerable)val2.transform).Cast<Transform>().ToList())
				{
					Object.DestroyImmediate((Object)(object)((Component)item).gameObject);
				}
				Component[] components = val2.GetComponents<Component>();
				foreach (Component val3 in components)
				{
					if (!((Object)(object)val3 == (Object)null) && !(val3 is Transform) && !(val3 is TextMeshProUGUI) && !(val3 is CanvasRenderer))
					{
						Object.DestroyImmediate((Object)(object)val3);
					}
				}
				val2.transform.localPosition = new Vector3(x, y + num, val.z);
				val2.transform.localRotation = ((((TMP_Text)title).transform.rotation == Quaternion.identity) ? Quaternion.identity : (Quaternion.Inverse(parent.rotation) * ((TMP_Text)title).transform.rotation));
				val2.transform.localScale = (Vector3)((((TMP_Text)title).transform.lossyScale.x > 0f && parent.lossyScale.x > 0f) ? new Vector3(((TMP_Text)title).transform.lossyScale.x / parent.lossyScale.x, ((TMP_Text)title).transform.lossyScale.y / parent.lossyScale.y, 1f) : Vector3.one);
				TextMeshProUGUI component = val2.GetComponent<TextMeshProUGUI>();
				text = Loc.T(text);
				((TMP_Text)component).text = (major ? text : ("— " + text + " —"));
				((TMP_Text)component).fontStyle = (FontStyles)1;
				((TMP_Text)component).enableWordWrapping = false;
				((TMP_Text)component).overflowMode = (TextOverflowModes)0;
				if (major)
				{
					((TMP_Text)component).fontSize = ((TMP_Text)title).fontSize * 1.25f;
					((Graphic)component).color = new Color(0.68f, 0.84f, 0.51f, 1f);
				}
				else
				{
					((Graphic)component).color = new Color(((Graphic)component).color.r, ((Graphic)component).color.g, ((Graphic)component).color.b, ((Graphic)component).color.a * 0.75f);
				}
				val2.SetActive(true);
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("[SoloHUD] Couldn't add the '" + text + "' heading: " + ex.Message));
			}
		}

		private static void PruneClicks(GameObject clone, Component keep, params string[] keepMethods)
		{
			MenuButton[] componentsInChildren = clone.GetComponentsInChildren<MenuButton>(true);
			foreach (MenuButton val in componentsInChildren)
			{
				ButtonClickedEvent val2 = (((Object)(object)val != (Object)null && (Object)(object)val.button != (Object)null) ? val.button.onClick : null);
				if (val2 == null)
				{
					continue;
				}
				for (int j = 0; j < ((UnityEventBase)val2).GetPersistentEventCount(); j++)
				{
					if ((object)((UnityEventBase)val2).GetPersistentTarget(j) != keep || Array.IndexOf(keepMethods, ((UnityEventBase)val2).GetPersistentMethodName(j)) < 0)
					{
						((UnityEventBase)val2).SetPersistentListenerState(j, (UnityEventCallState)0);
					}
				}
			}
		}

		private static void Strip<T>(GameObject go) where T : Component
		{
			T[] componentsInChildren = go.GetComponentsInChildren<T>(true);
			foreach (T val in componentsInChildren)
			{
				if ((Object)(object)val != (Object)null)
				{
					Object.DestroyImmediate((Object)(object)val);
				}
			}
		}

		private static string[] Steps(int first, int step, int count, string suffix)
		{
			string[] array = new string[count];
			for (int i = 0; i < count; i++)
			{
				array[i] = first + i * step + suffix;
			}
			return array;
		}
	}
	internal sealed class HudSliderRow : MonoBehaviour
	{
		private MenuSlider _slider;

		private string _name;

		private string[] _labels;

		private Action<int> _write;

		private int _shown = -1;

		public void Bind(MenuSlider slider, string name, string[] labels, Action<int> write)
		{
			_slider = slider;
			_name = name;
			_labels = labels;
			_write = write;
		}

		private void LateUpdate()
		{
			if ((Object)(object)_slider == (Object)null || _labels == null)
			{
				return;
			}
			if ((Object)(object)_slider.elementNameText != (Object)null && ((TMP_Text)_slider.elementNameText).text != _name)
			{
				((TMP_Text)_slider.elementNameText).text = _name;
			}
			int num = Mathf.Clamp(_slider.currentValue, 0, _labels.Length - 1);
			if (_shown < 0)
			{
				_shown = num;
				try
				{
					_slider.SetBarScaleInstant();
				}
				catch
				{
				}
			}
			else if (num != _shown)
			{
				_shown = num;
				try
				{
					_write(num);
				}
				catch (Exception ex)
				{
					Plugin.Log.LogWarning((object)("[SoloHUD] '" + _name + "' failed to apply: " + ex.Message));
				}
			}
			string text = _labels[num];
			if ((Object)(object)_slider.segmentText != (Object)null && ((TMP_Text)_slider.segmentText).text != text)
			{
				((TMP_Text)_slider.segmentText).text = text;
			}
			if ((Object)(object)_slider.segmentMaskText != (Object)null && ((TMP_Text)_slider.segmentMaskText).text != text)
			{
				((TMP_Text)_slider.segmentMaskText).text = text;
			}
		}
	}
	internal sealed class HudToggleRow : MonoBehaviour
	{
		private string _name;

		private TextMeshProUGUI[] _titles = (TextMeshProUGUI[])(object)new TextMeshProUGUI[0];

		public void Bind(MenuTwoOptions two, string name)
		{
			_name = name;
			_titles = (from t in ((Component)two).GetComponentsInChildren<TextMeshProUGUI>(true)
				where (Object)(object)t != (Object)null && (Object)(object)t != (Object)(object)two.option1TextMesh && (Object)(object)t != (Object)(object)two.option2TextMesh
				select t).ToArray();
			LateUpdate();
		}

		private void LateUpdate()
		{
			TextMeshProUGUI[] titles = _titles;
			foreach (TextMeshProUGUI val in titles)
			{
				if ((Object)(object)val != (Object)null && ((TMP_Text)val).text != _name)
				{
					((TMP_Text)val).text = _name;
				}
			}
		}
	}
	internal sealed class HudKeyRow : MonoBehaviour
	{
		private const string Tag = "SoloHUD Key Row";

		private MenuBigButton _big;

		private ConfigEntry<Key> _entry;

		private string _title;

		private TextMeshProUGUI[] _titles = (TextMeshProUGUI[])(object)new TextMeshProUGUI[0];

		private bool _capturing;

		private float _armedAt;

		public void Bind(MenuBigButton big, ConfigEntry<Key> entry, string title)
		{
			_big = big;
			_entry = entry;
			_title = title;
			TextMeshProUGUI keyText = (((Object)(object)big.menuButton != (Object)null) ? big.menuButton.buttonText : null);
			_title = Loc.T(_title);
			_titles = (from t in ((Component)big).GetComponentsInChildren<TextMeshProUGUI>(true)
				where (Object)(object)t != (Object)null && (Object)(object)t != (Object)(object)keyText
				select t).ToArray();
			Show();
		}

		public void BeginCapture()
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			if (!_capturing)
			{
				_capturing = true;
				_armedAt = Time.unscaledTime;
				if ((Object)(object)_big != (Object)null)
				{
					_big.state = (State)1;
				}
				SetText("...");
			}
		}

		private void Update()
		{
			//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_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Invalid comparison between Unknown and I4
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Invalid comparison between Unknown and I4
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Invalid comparison between Unknown and I4
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_big != (Object)null)
			{
				_big.buttonTitle = _title;
			}
			TextMeshProUGUI[] titles = _titles;
			foreach (TextMeshProUGUI val in titles)
			{
				if ((Object)(object)val != (Object)null && ((TMP_Text)val).text != _title)
				{
					((TMP_Text)val).text = _title;
				}
			}
			if (!_capturing)
			{
				Show();
				return;
			}
			Keyboard current = Keyboard.current;
			if (current == null)
			{
				Finish();
			}
			else
			{
				if (Time.unscaledTime - _armedAt < 0.1f)
				{
					return;
				}
				Enumerator<KeyControl> enumerator = current.allKeys.GetEnumerator();
				try
				{
					while (enumerator.MoveNext())
					{
						KeyControl current2 = enumerator.Current;
						if (current2 != null && ((ButtonControl)current2).wasPressedThisFrame)
						{
							if ((int)current2.keyCode == 60)
							{
								Finish();
								break;
							}
							_entry.Value = (Key)(((int)current2.keyCode != 65 && (int)current2.keyCode != 71) ? ((int)current2.keyCode) : 0);
							Plugin.Log.LogInfo((object)$"[SoloHUD] {_title} key set to {_entry.Value} from the game's settings.");
							Finish();
							break;
						}
					}
				}
				finally
				{
					((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
				}
			}
		}

		private void Finish()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			_capturing = false;
			if ((Object)(object)_big != (Object)null)
			{
				_big.state = (State)0;
			}
			Show();
		}

		private void Show()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			SetText(((int)_entry.Value == 0) ? "OFF" : ((object)_entry.Value/*cast due to .constrained prefix*/).ToString());
		}

		private void SetText(string text)
		{
			if (!((Object)(object)_big == (Object)null))
			{
				_big.buttonName = text;
				if ((Object)(object)_big.menuButton != (Object)null && (Object)(object)_big.menuButton.buttonText != (Object)null)
				{
					((TMP_Text)_big.menuButton.buttonText).text = text;
				}
			}
		}

		internal static IEnumerator AddTo(MenuPageSettingsControls page)
		{
			yield return null;
			yield return null;
			if ((Object)(object)page == (Object)null || ((Component)page).GetComponentsInChildren<Transform>(true).Any((Transform t) => (Object)(object)t != (Object)null && ((Object)t).name == "SoloHUD Key Row"))
			{
				yield break;
			}
			MenuKeybind val = ((Component)page).GetComponentsInChildren<MenuKeybind>(true).FirstOrDefault();
			if ((Object)(object)val == (Object)null)
			{
				Plugin.Log.LogWarning((object)"[SoloHUD] No keybind row to copy — leaving the Controls page alone.");
				yield break;
			}
			Transform parent = ((Component)val).transform.parent;
			List<Transform> list = (from b in ((Component)parent).GetComponentsInChildren<MenuBigButton>(true)
				where (Object)(object)b != (Object)null && (Object)(object)((Component)b).transform.parent == (Object)(object)parent
				select ((Component)b).transform into t
				orderby t.localPosition.y descending
				select t).ToList();
			float num = ((list.Count > 1) ? Mathf.Abs(list[0].localPosition.y - list[1].localPosition.y) : 60f);
			if (num < 1f)
			{
				num = 60f;
			}
			float num2 = ((list.Count > 0) ? list[list.Count - 1].localPosition.y : ((Component)val).transform.localPosition.y);
			num2 -= num;
			HudSettings.Header((Component)(object)val, HudSettings.TitleOf((Component)(object)val), parent, num2, "SOLOHUD", major: true, "SoloHUD Key Row");
			num2 -= num;
			Add(val, parent, num2, Plugin.ToggleKey, "SoloHUD Show/Hide");
			num2 -= num;
			Add(val, parent, num2, Plugin.MonsterListKey, "SoloHUD Monster List");
			MenuScrollBox componentInChildren = ((Component)page).GetComponentInChildren<MenuScrollBox>(true);
			if ((Object)(object)componentInChildren != (Object)null)
			{
				try
				{
					componentInChildren.RecalculateScrollHeight();
				}
				catch
				{
				}
			}
			Plugin.Log.LogInfo((object)"[SoloHUD] Added its keys to the game's Controls settings.");
		}

		private static void Add(MenuKeybind template, Transform parent, float y, ConfigEntry<Key> entry, string title)
		{
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Expected O, but got Unknown
			try
			{
				GameObject val = HudSettings.CloneDormant((Component)(object)template, parent, y, "SoloHUD Key Row");
				MenuKeybind component = val.GetComponent<MenuKeybind>();
				if ((Object)(object)component != (Object)null)
				{
					Object.DestroyImmediate((Object)(object)component);
				}
				MenuBigButton component2 = val.GetComponent<MenuBigButton>();
				if ((Object)(object)component2 == (Object)null)
				{
					Object.DestroyImmediate((Object)(object)val);
					return;
				}
				HudKeyRow hudKeyRow = val.AddComponent<HudKeyRow>();
				hudKeyRow.Bind(component2, entry, title);
				Button val2 = (((Object)(object)component2.menuButton != (Object)null) ? component2.menuButton.button : null);
				if ((Object)(object)val2 != (Object)null)
				{
					((UnityEvent)val2.onClick).AddListener(new UnityAction(hudKeyRow.BeginCapture));
				}
				val.SetActive(true);
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("[SoloHUD] Couldn't add the '" + title + "' key row: " + ex.Message));
			}
		}
	}
	[BepInPlugin("com.solo.repo.solohud", "SoloHUD", "1.14.0")]
	public class Plugin : BaseUnityPlugin
	{
		public const string Guid = "com.solo.repo.solohud";

		public const string Name = "SoloHUD";

		public const string Version = "1.14.0";

		internal static ManualLogSource Log;

		internal static bool Ready;

		internal static Plugin Instance;

		internal static ConfigEntry<Key> ToggleKey;

		internal static ConfigEntry<Key> MonsterListKey;

		internal static ConfigEntry<bool> HideWhileMapOpen;

		internal static ConfigEntry<bool> ShowInfoPanel;

		internal static ConfigEntry<bool> ShowRadar;

		internal static ConfigEntry<float> RadarRange;

		internal static ConfigEntry<float> RadarSize;

		internal static ConfigEntry<bool> RadarRotateWithCamera;

		internal static ConfigEntry<bool> UseGameMap;

		internal static ConfigEntry<float> PanelOpacity;

		internal static ConfigEntry<float> PanelOffsetX;

		internal static ConfigEntry<float> PanelOffsetY;

		internal static ConfigEntry<bool> UseMapScreenLook;

		internal static ConfigEntry<int> MonsterListMaxLines;

		internal static ConfigEntry<float> PanelFontSize;

		internal static ConfigEntry<float> PanelMaxHeightFraction;

		internal static ConfigEntry<bool> ShowMapValue;

		internal static ConfigEntry<bool> ShowLooseValue;

		internal static ConfigEntry<bool> ShowRoomValue;

		internal static ConfigEntry<bool> ShowMonsterList;

		internal static ConfigEntry<bool> ShowInGameSettings;

		internal static ConfigEntry<bool> DumpTranslationList;

		private void Awake()
		{
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Expected O, but got Unknown
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Expected O, but got Unknown
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Expected O, but got Unknown
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Expected O, but got Unknown
			//IL_0396: Unknown result type (might be due to invalid IL or missing references)
			//IL_039b: Unknown result type (might be due to invalid IL or missing references)
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			ToggleKey = ((BaseUnityPlugin)this).Config.Bind<Key>("General", "ToggleKey", (Key)94, "Key to show/hide the whole overlay (Unity Input System key name). None switches it off. Also rebindable from the game's Controls settings.");
			MonsterListKey = ((BaseUnityPlugin)this).Config.Bind<Key>("General", "MonsterListKey", (Key)32, "Hold this key to show the FULL monster list (every type, uncapped), like a stat screen. None switches it off. Also rebindable from the game's Controls settings.");
			HideWhileMapOpen = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "HideWhileMapOpen", true, "Hide the overlay while you hold the map (Tab), so it doesn't cover the game's upgrade/stat screen.");
			ShowInfoPanel = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowInfoPanel", true, "Show the top-left info panel (map value + monster roster).");
			ShowRadar = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowRadar", true, "Show the radar with live monster and player positions.");
			PanelOpacity = ((BaseUnityPlugin)this).Config.Bind<float>("General", "PanelOpacity", 0f, new ConfigDescription("Darkness of the plate behind the info panel. 0 = fully transparent (text only).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			PanelOffsetX = ((BaseUnityPlugin)this).Config.Bind<float>("General", "PanelOffsetX", 16f, "Info panel distance from the left edge, in pixels.");
			PanelOffsetY = ((BaseUnityPlugin)this).Config.Bind<float>("General", "PanelOffsetY", 130f, "Info panel distance from the bottom edge. The default clears the game's mission text.");
			MonsterListMaxLines = ((BaseUnityPlugin)this).Config.Bind<int>("General", "MonsterListMaxLines", 8, new ConfigDescription("Max monster TYPES listed in the panel before it collapses to '+N more'. The panel also auto-shrinks this further if needed to stay off the top HUD.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 30), Array.Empty<object>()));
			PanelFontSize = ((BaseUnityPlugin)this).Config.Bind<float>("General", "PanelFontSize", 14f, new ConfigDescription("Font size of the info panel. Lower = more compact / more monsters fit.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(6f, 40f), Array.Empty<object>()));
			PanelMaxHeightFraction = ((BaseUnityPlugin)this).Config.Bind<float>("General", "PanelMaxHeightFraction", 0.55f, new ConfigDescription("Tallest the info panel may grow, as a fraction of screen height. Stops it from reaching the game's health/energy HUD in the top-left; excess monsters collapse to '+N more'.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.2f, 0.95f), Array.Empty<object>()));
			ShowMapValue = ((BaseUnityPlugin)this).Config.Bind<bool>("Values", "ShowMapValue", true, "Show the total value of every valuable in the level, carts and extractions included.");
			ShowLooseValue = ((BaseUnityPlugin)this).Config.Bind<bool>("Values", "ShowLooseValue", true, "Show the value still out there to collect: valuables not riding in a cart and not already in an extraction point.");
			ShowRoomValue = ((BaseUnityPlugin)this).Config.Bind<bool>("Values", "ShowRoomValue", true, "Show the value of the valuables in the room you are standing in.");
			ShowMonsterList = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowMonsterList", true, "Show the monster roster in the info panel. The full list on the hold key works either way.");
			ShowInGameSettings = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowInGameSettings", true, "Add SoloHUD's settings to the game's own Gameplay settings page, and its two keys to the Controls page, so everything can be changed without leaving the game.");
			RadarRange = ((BaseUnityPlugin)this).Config.Bind<float>("Radar", "RangeMeters", 40f, "World distance from you that the radar edge represents. Lower = more zoomed in.");
			RadarSize = ((BaseUnityPlugin)this).Config.Bind<float>("Radar", "SizePixels", 120f, "Minimap size in pixels (at 1080p reference scale). Applies live, no restart needed.");
			RadarRotateWithCamera = ((BaseUnityPlugin)this).Config.Bind<bool>("Radar", "RotateWithCamera", true, "Only used by the fallback dot radar: if true, 'up' is the direction you're facing.");
			UseGameMap = ((BaseUnityPlugin)this).Config.Bind<bool>("Radar", "UseGameMap", true, "Show the real Tab map in the minimap by keeping the game's map render alive. Set false to fall back to the simple dot radar.");
			UseMapScreenLook = ((BaseUnityPlugin)this).Config.Bind<bool>("Radar", "UseMapScreenLook", true, "Draw the minimap through the map device's own screen shader, so it gets the same green CRT tint and scanlines. Set false if the minimap renders wrong.");
			DumpTranslationList = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "WriteTranslationList", false, "Write every line this mod shows to lang/_english.txt as you play, ready to be copied into a new language file. For translating; off otherwise.");
			Loc.Init("SoloHUD", ((BaseUnityPlugin)this).Info.Location, (Action<string>)Log.LogInfo, (Action<string>)Log.LogWarning, DumpTranslationList.Value);
			Ready = true;
			Harmony val = new Harmony("com.solo.repo.solohud");
			val.PatchAll(typeof(Plugin).Assembly);
			int num = 0;
			foreach (MethodBase patchedMethod in val.GetPatchedMethods())
			{
				num++;
				Log.LogInfo((object)("[SoloHUD] patched: " + patchedMethod.DeclaringType?.Name + "." + patchedMethod.Name));
			}
			Log.LogInfo((object)string.Format("{0} v{1} loaded; Harmony applied {2} patches.", "SoloHUD", "1.14.0", num));
			if (num == 0)
			{
				Log.LogError((object)"[SoloHUD] PatchAll applied ZERO patches — hooks will never fire!");
			}
		}
	}
	[HarmonyPatch(typeof(RenderTextureMain), "Update")]
	internal static class RenderTextureMainUpdatePatch
	{
		private static void Postfix()
		{
			HudController.Tick();
		}
	}
	[HarmonyPatch(typeof(RoundDirector), "Update")]
	internal static class RoundDirectorUpdatePatch
	{
		private static void Postfix()
		{
			HudController.Tick();
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		internal IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}