Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of SoloHUD v1.14.0
SoloHUD.dll
Decompiled 4 days agousing 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) { } } }