Decompiled source of LethalUI v0.5.0

LethalUI.dll

Decompiled 2 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using LethalConfig;
using LethalConfig.ConfigItems;
using LethalConfig.ConfigItems.Options;
using LethalUI.Enums;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("LethalUI")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("LethalUI")]
[assembly: AssemblyTitle("LethalUI")]
[assembly: AssemblyMetadata("AI_Assisted_Creation", "Partially created with generative AI (code writing, refactoring and documentation).")]
[assembly: AssemblyMetadata("AI_Model_Vendor", "Anthropic")]
[assembly: AssemblyVersion("1.0.0.0")]
[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 LethalUI
{
	internal class HudGroup
	{
		public readonly string Name;

		public readonly List<CanvasGroup> CanvasGroups = new List<CanvasGroup>();

		public readonly List<CanvasRenderer> Renderers = new List<CanvasRenderer>();

		public readonly List<GameObject> Objects = new List<GameObject>();

		public float LastActive = -999f;

		public float Alpha = 1f;

		private float appliedAlpha = -1f;

		public HudGroup(string name)
		{
			Name = name;
		}

		public void Touch()
		{
			LastActive = Time.time;
		}

		public bool IsActive(float showSeconds)
		{
			return Time.time - LastActive <= showSeconds;
		}

		public void Add(Transform t)
		{
			if ((Object)(object)t != (Object)null)
			{
				Add(((Component)t).gameObject);
			}
		}

		public void Add(GameObject go)
		{
			if (!((Object)(object)go == (Object)null) && !Objects.Any((GameObject o) => (Object)(object)o != (Object)null && go.transform.IsChildOf(o.transform)))
			{
				Objects.Add(go);
				if ((Object)(object)go.GetComponent<CanvasGroup>() != (Object)null)
				{
					Renderers.AddRange(go.GetComponentsInChildren<CanvasRenderer>(true));
					Plugin.logger.LogDebug((object)(Name + ": '" + ((Object)go).name + "' has the game's own CanvasGroup, fading its renderers instead"));
				}
				else
				{
					CanvasGroups.Add(go.AddComponent<CanvasGroup>());
				}
			}
		}

		public void AddChildrenOf(Transform container)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			if ((Object)(object)container == (Object)null)
			{
				return;
			}
			foreach (Transform item in container)
			{
				Transform val = item;
				Add(((Component)val).gameObject);
			}
		}

		public void Apply(HudMode mode, float showSeconds, float floor = 0f)
		{
			float num = mode switch
			{
				HudMode.AlwaysVisible => 1f, 
				HudMode.Hidden => 0f, 
				_ => IsActive(showSeconds) ? 1f : Mathf.Max(Mathf.Clamp01(Plugin.HiddenAlpha.Value), Mathf.Clamp01(floor)), 
			};
			float num2 = ((Plugin.FadeDuration.Value <= 0f) ? 999f : (Time.deltaTime / Plugin.FadeDuration.Value));
			Alpha = Mathf.MoveTowards(Alpha, num, num2);
			if (Alpha != appliedAlpha)
			{
				SetAlpha(Alpha);
			}
		}

		public void SetAlpha(float a)
		{
			appliedAlpha = a;
			foreach (CanvasGroup canvasGroup in CanvasGroups)
			{
				if ((Object)(object)canvasGroup != (Object)null)
				{
					canvasGroup.alpha = a;
				}
			}
			foreach (CanvasRenderer renderer in Renderers)
			{
				if ((Object)(object)renderer != (Object)null)
				{
					renderer.SetAlpha(a);
				}
			}
		}
	}
	[HarmonyPatch(typeof(HUDManager), "Update")]
	internal static class HudHelper
	{
		private class ScaleMember
		{
			public RectTransform Rect;

			public Vector3 OriginalWorld;

			public Vector3 OriginalScale;

			public Vector2 OriginalScreen;
		}

		private class ScaleUnit
		{
			public string Name;

			public Vector2 Anchor;

			public Vector2 Gap;

			public readonly List<ScaleMember> Members = new List<ScaleMember>();
		}

		private static HUDManager boundTo;

		private static HudGroup hotbar;

		private static HudGroup utility;

		private static HudGroup health;

		private static HudGroup stamina;

		private static HudGroup battery;

		private static HudGroup tooltips;

		private static HudGroup[] all = Array.Empty<HudGroup>();

		private static bool loggedError;

		private static bool handedBack;

		private static Component[] tipLines = Array.Empty<Component>();

		private static int lastSlot = -1;

		private static GrabbableObject[] lastItems = Array.Empty<GrabbableObject>();

		private static int lastHealth = -1;

		private static GrabbableObject lastHeld;

		private static float lastCharge = -1f;

		private static string[] lastTipTexts = Array.Empty<string>();

		private static bool haveTipTexts;

		private static Canvas hudCanvas;

		private static readonly List<(string name, List<RectTransform> rects)> unitDefs = new List<(string, List<RectTransform>)>();

		private static readonly List<ScaleUnit> scaleUnits = new List<ScaleUnit>();

		private static bool unitsCaptured;

		private static float bindTime;

		private static Vector2 capturedScreenSize;

		private static float appliedScale = 1f;

		private static float appliedGap = 1f;

		private static readonly Dictionary<Type, PropertyInfo> textProperties = new Dictionary<Type, PropertyInfo>();

		private static Camera HudCamera
		{
			get
			{
				//IL_0012: Unknown result type (might be due to invalid IL or missing references)
				if (!((Object)(object)hudCanvas != (Object)null) || (int)hudCanvas.renderMode == 0)
				{
					return null;
				}
				return hudCanvas.worldCamera;
			}
		}

		[HarmonyPostfix]
		private static void Postfix(HUDManager __instance)
		{
			try
			{
				if ((Object)(object)boundTo != (Object)(object)__instance)
				{
					Bind(__instance);
				}
				ApplyScale();
				PlayerControllerB val = (((Object)(object)GameNetworkManager.Instance != (Object)null) ? GameNetworkManager.Instance.localPlayerController : null);
				if (!Plugin.Enabled.Value || (Object)(object)val == (Object)null || val.isPlayerDead)
				{
					if (!handedBack)
					{
						HudGroup[] array = all;
						foreach (HudGroup obj in array)
						{
							obj.Alpha = 1f;
							obj.SetAlpha(1f);
						}
						handedBack = true;
					}
					ResetState(val);
				}
				else
				{
					handedBack = false;
					DetectHotbar(val);
					utility.LastActive = hotbar.LastActive;
					DetectHealth(val);
					DetectStamina(val);
					DetectBattery(val);
					DetectTooltips();
					hotbar.Apply(Plugin.HotbarMode.Value, Plugin.HotbarShowSeconds.Value);
					utility.Apply(Plugin.UtilityMode.Value, Plugin.HotbarShowSeconds.Value);
					stamina.Apply(Plugin.StaminaMode.Value, Plugin.StaminaShowSecondsAfterSprint.Value);
					bool flag = Plugin.StaminaMode.Value == HudMode.AlwaysVisible || (Plugin.StaminaMode.Value == HudMode.Contextual && stamina.IsActive(Plugin.StaminaShowSecondsAfterSprint.Value));
					health.Apply(Plugin.HealthMode.Value, Plugin.HealthShowSeconds.Value, flag ? Plugin.HealthAlphaWithStamina.Value : 0f);
					battery.Apply(Plugin.BatteryMode.Value, Plugin.BatteryShowSeconds.Value);
					tooltips.Apply(Plugin.TooltipsMode.Value, Plugin.TooltipsShowSeconds.Value);
				}
			}
			catch (Exception arg)
			{
				if (!loggedError)
				{
					Plugin.logger.LogError((object)$"LethalUI error (shown once): {arg}");
					loggedError = true;
				}
			}
		}

		private static void DetectHotbar(PlayerControllerB p)
		{
			bool flag = p.currentItemSlot != lastSlot;
			GrabbableObject[] array = p.ItemSlots ?? Array.Empty<GrabbableObject>();
			if (array.Length != lastItems.Length)
			{
				flag = true;
			}
			else
			{
				for (int i = 0; i < array.Length; i++)
				{
					if ((Object)(object)array[i] != (Object)(object)lastItems[i])
					{
						flag = true;
						break;
					}
				}
			}
			if (flag)
			{
				hotbar.Touch();
				lastSlot = p.currentItemSlot;
				lastItems = (GrabbableObject[])array.Clone();
			}
		}

		private static void DetectHealth(PlayerControllerB p)
		{
			if (lastHealth >= 0)
			{
				if (p.health < lastHealth)
				{
					health.Touch();
				}
				else if (p.health > lastHealth && Plugin.HealthShowOnHeal.Value)
				{
					health.Touch();
				}
			}
			lastHealth = p.health;
			if (Plugin.HealthAlwaysWhenCritical.Value && p.criticallyInjured)
			{
				health.Touch();
			}
		}

		private static void DetectStamina(PlayerControllerB p)
		{
			if (p.isSprinting)
			{
				stamina.Touch();
			}
			if (Plugin.StaminaShowWhileExhausted.Value && p.isExhausted)
			{
				stamina.Touch();
			}
		}

		private static void DetectBattery(PlayerControllerB p)
		{
			GrabbableObject currentlyHeldObjectServer = p.currentlyHeldObjectServer;
			if ((Object)(object)currentlyHeldObjectServer != (Object)null && (Object)(object)currentlyHeldObjectServer.itemProperties != (Object)null && currentlyHeldObjectServer.itemProperties.requiresBattery && currentlyHeldObjectServer.insertedBattery != null)
			{
				if ((Object)(object)currentlyHeldObjectServer != (Object)(object)lastHeld)
				{
					battery.Touch();
				}
				if (currentlyHeldObjectServer.isBeingUsed)
				{
					battery.Touch();
				}
				if (lastCharge >= 0f && (Object)(object)currentlyHeldObjectServer == (Object)(object)lastHeld && Mathf.Abs(currentlyHeldObjectServer.insertedBattery.charge - lastCharge) > 0.0001f)
				{
					battery.Touch();
				}
				lastCharge = currentlyHeldObjectServer.insertedBattery.charge;
			}
			else
			{
				lastCharge = -1f;
			}
			lastHeld = currentlyHeldObjectServer;
		}

		private static void DetectTooltips()
		{
			if (lastTipTexts.Length != tipLines.Length)
			{
				lastTipTexts = new string[tipLines.Length];
				haveTipTexts = false;
			}
			bool flag = false;
			bool flag2 = false;
			for (int i = 0; i < tipLines.Length; i++)
			{
				string text = GetText(tipLines[i]);
				if (!string.IsNullOrWhiteSpace(text))
				{
					flag2 = true;
				}
				if (haveTipTexts && text != lastTipTexts[i])
				{
					flag = true;
				}
				lastTipTexts[i] = text;
			}
			haveTipTexts = true;
			if (flag && flag2)
			{
				tooltips.Touch();
			}
		}

		private static void ResetState(PlayerControllerB p)
		{
			lastSlot = (((Object)(object)p != (Object)null) ? p.currentItemSlot : (-1));
			lastItems = (((Object)(object)p != (Object)null && p.ItemSlots != null) ? ((GrabbableObject[])p.ItemSlots.Clone()) : Array.Empty<GrabbableObject>());
			lastHealth = (((Object)(object)p != (Object)null) ? p.health : (-1));
			lastHeld = null;
			lastCharge = -1f;
			haveTipTexts = false;
		}

		private static void Bind(HUDManager hud)
		{
			//IL_0324: Unknown result type (might be due to invalid IL or missing references)
			//IL_032b: Expected O, but got Unknown
			boundTo = hud;
			hotbar = new HudGroup("Hotbar");
			utility = new HudGroup("Utility");
			health = new HudGroup("Health");
			stamina = new HudGroup("Stamina");
			battery = new HudGroup("Battery");
			tooltips = new HudGroup("Tooltips");
			all = new HudGroup[6] { hotbar, utility, health, stamina, battery, tooltips };
			loggedError = false;
			handedBack = false;
			GameObject val = GetObjects(hud, "HUDContainer").FirstOrDefault();
			Transform parent = (((Object)(object)val != (Object)null) ? val.transform : null);
			Transform parent2 = Find(parent, "TopLeftCorner");
			Transform val2 = Find(parent, "TopRightCorner");
			Transform single = Find(parent, "BottomRightCorner");
			Transform val3 = Find(parent, "BottomMiddle");
			Transform single2 = Find(parent, "Inventory");
			foreach (GameObject @object in GetObjects(hud, "itemSlotIconFrames"))
			{
				hotbar.Add(@object);
			}
			health.Add(Find(parent2, "Self"));
			health.Add(Find(parent2, "SelfRed"));
			health.Add(Find(parent2, "RedGlowBodyParts"));
			stamina.Add(Find(parent2, "SprintMeter"));
			battery.Add(Find(parent2, "Batteries"));
			battery.Add(Find(parent2, "BatteriesOff"));
			utility.Add(Find(parent2, "UtilitySlot"));
			utility.Add(Find(parent2, "WeightUI"));
			tooltips.AddChildrenOf(val2);
			tipLines = (from c in (GetField(hud, "controlTipLines") as Array)?.OfType<Component>()
				where (Object)(object)c != (Object)null
				select c).ToArray() ?? Array.Empty<Component>();
			hudCanvas = (((Object)(object)val != (Object)null) ? val.GetComponentInParent<Canvas>() : null);
			if ((Object)(object)hudCanvas != (Object)null)
			{
				hudCanvas = hudCanvas.rootCanvas;
			}
			unitDefs.Clear();
			AddUnitDef("Player panel", ChildrenExcept(parent2, "Clock", "Compass", "CinematicGraphics"));
			AddUnitDef("Clock", Find(parent2, "Clock"));
			AddUnitDef("Quota", Find(parent, "ProfitQuota"));
			AddUnitDef("Tooltips", val2);
			AddUnitDef("Hotbar", single2);
			AddUnitDef("Bottom right", single);
			if ((Object)(object)val3 != (Object)null)
			{
				foreach (Transform item in val3)
				{
					Transform val4 = item;
					AddUnitDef(((Object)val4).name, val4);
				}
			}
			scaleUnits.Clear();
			unitsCaptured = false;
			bindTime = Time.time;
			appliedScale = 1f;
			appliedGap = 1f;
			ResetState(null);
			Plugin.logger.LogInfo((object)("LethalUI bound: " + string.Join(", ", all.Select((HudGroup g) => $"{g.Name} {g.Objects.Count}")) + $" | {unitDefs.Count} scale units"));
		}

		private static Transform Find(Transform parent, string name)
		{
			if ((Object)(object)parent == (Object)null)
			{
				return null;
			}
			Transform val = parent.Find(name);
			if ((Object)(object)val == (Object)null)
			{
				Plugin.logger.LogWarning((object)("HUD part '" + name + "' not found under '" + ((Object)parent).name + "'"));
			}
			return val;
		}

		private static IEnumerable<Transform> ChildrenExcept(Transform parent, params string[] names)
		{
			if ((Object)(object)parent == (Object)null)
			{
				yield break;
			}
			foreach (Transform item in parent)
			{
				Transform val = item;
				if (!names.Contains(((Object)val).name))
				{
					yield return val;
				}
			}
		}

		private static void AddUnitDef(string name, Transform single)
		{
			if ((Object)(object)single != (Object)null)
			{
				AddUnitDef(name, (IEnumerable<Transform>)(object)new Transform[1] { single });
			}
		}

		private static void AddUnitDef(string name, IEnumerable<Transform> members)
		{
			List<RectTransform> list = (from r in members.OfType<RectTransform>()
				where (Object)(object)r != (Object)null
				select r).ToList();
			if (list.Count > 0)
			{
				unitDefs.Add((name, list));
			}
		}

		private static Rect ScreenRect()
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)hudCanvas != (Object)null))
			{
				return new Rect(0f, 0f, (float)Screen.width, (float)Screen.height);
			}
			return hudCanvas.pixelRect;
		}

		private static void ApplyScale()
		{
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: 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_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)hudCanvas == (Object)null)
			{
				return;
			}
			float num = (Plugin.Enabled.Value ? Mathf.Clamp(Plugin.HudScale.Value, 0.3f, 2f) : 1f);
			float num2 = (Plugin.Enabled.Value ? Mathf.Clamp(Plugin.EdgeGap.Value, 0f, 2f) : 1f);
			bool flag = Mathf.Approximately(num, 1f) && Mathf.Approximately(num2, 1f);
			if (!unitsCaptured)
			{
				if (flag || Time.time - bindTime < 1f)
				{
					return;
				}
				CaptureUnits();
			}
			Rect val = ScreenRect();
			if (((Rect)(ref val)).size != capturedScreenSize)
			{
				RestoreOriginals();
				CaptureUnits();
			}
			if (Mathf.Approximately(num, appliedScale) && Mathf.Approximately(num2, appliedGap))
			{
				return;
			}
			if (flag)
			{
				RestoreOriginals();
			}
			else
			{
				foreach (ScaleUnit scaleUnit in scaleUnits)
				{
					foreach (ScaleMember member in scaleUnit.Members)
					{
						if (!((Object)(object)member.Rect == (Object)null))
						{
							Vector2 screenPos = scaleUnit.Anchor - (scaleUnit.Anchor - member.OriginalScreen) * num + scaleUnit.Gap * num * (num2 - 1f);
							((Transform)member.Rect).localScale = member.OriginalScale * num;
							((Transform)member.Rect).position = ScreenToWorld(screenPos, member.OriginalWorld);
						}
					}
				}
			}
			appliedScale = num;
			appliedGap = num2;
		}

		private static void CaptureUnits()
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: 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_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			scaleUnits.Clear();
			Rect val = ScreenRect();
			foreach (var unitDef in unitDefs)
			{
				if (!TryGetScreenBounds(unitDef.rects, out var bounds))
				{
					continue;
				}
				PickAxis(((Rect)(ref bounds)).xMin, ((Rect)(ref bounds)).xMax, ((Rect)(ref bounds)).center.x, ((Rect)(ref val)).xMin, ((Rect)(ref val)).xMax, out var anchor, out var gap);
				PickAxis(((Rect)(ref bounds)).yMin, ((Rect)(ref bounds)).yMax, ((Rect)(ref bounds)).center.y, ((Rect)(ref val)).yMin, ((Rect)(ref val)).yMax, out var anchor2, out var gap2);
				ScaleUnit scaleUnit = new ScaleUnit
				{
					Name = unitDef.name,
					Anchor = new Vector2(anchor, anchor2),
					Gap = new Vector2(gap, gap2)
				};
				foreach (RectTransform item in unitDef.rects)
				{
					if (!((Object)(object)item == (Object)null))
					{
						scaleUnit.Members.Add(new ScaleMember
						{
							Rect = item,
							OriginalWorld = ((Transform)item).position,
							OriginalScale = ((Transform)item).localScale,
							OriginalScreen = WorldToScreen(((Transform)item).position)
						});
					}
				}
				scaleUnits.Add(scaleUnit);
			}
			capturedScreenSize = ((Rect)(ref val)).size;
			unitsCaptured = true;
			appliedScale = 1f;
			appliedGap = 1f;
			Plugin.logger.LogInfo((object)$"LethalUI scaling: measured {scaleUnits.Count} HUD parts on a {((Rect)(ref val)).width:0}x{((Rect)(ref val)).height:0} screen");
		}

		private static void RestoreOriginals()
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			foreach (ScaleUnit scaleUnit in scaleUnits)
			{
				foreach (ScaleMember member in scaleUnit.Members)
				{
					if (!((Object)(object)member.Rect == (Object)null))
					{
						((Transform)member.Rect).position = member.OriginalWorld;
						((Transform)member.Rect).localScale = member.OriginalScale;
					}
				}
			}
			appliedScale = 1f;
			appliedGap = 1f;
		}

		private static Vector2 WorldToScreen(Vector3 world)
		{
			//IL_0005: 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)
			return RectTransformUtility.WorldToScreenPoint(HudCamera, world);
		}

		private static Vector3 ScreenToWorld(Vector2 screenPos, Vector3 originalWorld)
		{
			//IL_0028: 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_0033: 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_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: 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_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: 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)
			Camera hudCamera = HudCamera;
			if ((Object)(object)hudCamera == (Object)null)
			{
				return new Vector3(screenPos.x, screenPos.y, originalWorld.z);
			}
			Ray val = hudCamera.ScreenPointToRay(Vector2.op_Implicit(screenPos));
			Plane val2 = default(Plane);
			((Plane)(ref val2))..ctor(-((Component)hudCamera).transform.forward, originalWorld);
			float num = default(float);
			if (!((Plane)(ref val2)).Raycast(val, ref num))
			{
				return originalWorld;
			}
			return ((Ray)(ref val)).GetPoint(num);
		}

		private static void PickAxis(float min, float max, float center, float screenMin, float screenMax, out float anchor, out float gap)
		{
			float num = (screenMin + screenMax) * 0.5f;
			float num2 = (center - num) / Mathf.Max(1f, screenMax - screenMin);
			if (Mathf.Abs(num2) < 0.15f)
			{
				anchor = center;
				gap = 0f;
			}
			else if (num2 < 0f)
			{
				anchor = screenMin;
				gap = min - screenMin;
			}
			else
			{
				anchor = screenMax;
				gap = max - screenMax;
			}
		}

		private static bool TryGetScreenBounds(IEnumerable<RectTransform> roots, out Rect bounds)
		{
			//IL_0001: 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_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//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_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			bounds = default(Rect);
			bool flag = false;
			float num = 0f;
			float num2 = 0f;
			float num3 = 0f;
			float num4 = 0f;
			Vector3[] array = (Vector3[])(object)new Vector3[4];
			foreach (RectTransform root in roots)
			{
				if ((Object)(object)root == (Object)null)
				{
					continue;
				}
				CanvasRenderer[] componentsInChildren = ((Component)root).GetComponentsInChildren<CanvasRenderer>(true);
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					Transform transform = ((Component)componentsInChildren[i]).transform;
					RectTransform val = (RectTransform)(object)((transform is RectTransform) ? transform : null);
					if (val == null)
					{
						continue;
					}
					val.GetWorldCorners(array);
					Vector3[] array2 = array;
					for (int j = 0; j < array2.Length; j++)
					{
						Vector2 val2 = WorldToScreen(array2[j]);
						if (!flag)
						{
							num = (num3 = val2.x);
							num2 = (num4 = val2.y);
							flag = true;
						}
						else
						{
							num = Mathf.Min(num, val2.x);
							num3 = Mathf.Max(num3, val2.x);
							num2 = Mathf.Min(num2, val2.y);
							num4 = Mathf.Max(num4, val2.y);
						}
					}
				}
			}
			if (flag)
			{
				bounds = Rect.MinMaxRect(num, num2, num3, num4);
			}
			return flag;
		}

		private static object GetField(object owner, string name)
		{
			if (owner == null)
			{
				return null;
			}
			FieldInfo fieldInfo = AccessTools.Field(owner.GetType(), name);
			if (fieldInfo == null)
			{
				Plugin.logger.LogWarning((object)("Field '" + name + "' not found on " + owner.GetType().Name));
				return null;
			}
			return fieldInfo.GetValue(owner);
		}

		private static IEnumerable<GameObject> GetObjects(object owner, string name)
		{
			object field = GetField(owner, name);
			GameObject val = (GameObject)((field is GameObject) ? field : null);
			if (val != null)
			{
				if ((Object)(object)val != (Object)null)
				{
					yield return val;
				}
				yield break;
			}
			Component val2 = (Component)((field is Component) ? field : null);
			if (val2 != null)
			{
				if ((Object)(object)val2 != (Object)null)
				{
					yield return val2.gameObject;
				}
			}
			else
			{
				if (!(field is Array array))
				{
					yield break;
				}
				foreach (object item in array)
				{
					GameObject val3 = (GameObject)((item is GameObject) ? item : null);
					if (val3 != null && (Object)(object)val3 != (Object)null)
					{
						yield return val3;
						continue;
					}
					Component val4 = (Component)((item is Component) ? item : null);
					if (val4 != null && (Object)(object)val4 != (Object)null)
					{
						yield return val4.gameObject;
					}
				}
			}
		}

		private static string GetText(Component c)
		{
			if ((Object)(object)c == (Object)null)
			{
				return null;
			}
			Type type = ((object)c).GetType();
			if (!textProperties.TryGetValue(type, out var value))
			{
				value = (textProperties[type] = type.GetProperty("text"));
			}
			return value?.GetValue(c) as string;
		}
	}
	internal static class LethalConfigSupport
	{
		internal static void Register()
		{
			LethalConfigManager.SetModDescription("Context-dependent HUD: parts appear only when they matter.");
			LethalConfigManager.SkipAutoGen();
			AddBool(Plugin.Enabled);
			AddSlider(Plugin.HiddenAlpha, 0f, 1f);
			AddSlider(Plugin.FadeDuration, 0f, 3f);
			AddSlider(Plugin.HudScale, 0.3f, 2f);
			AddSlider(Plugin.EdgeGap, 0f, 2f);
			AddMode(Plugin.HotbarMode);
			AddSlider(Plugin.HotbarShowSeconds, 0f, 15f);
			AddMode(Plugin.UtilityMode);
			AddMode(Plugin.HealthMode);
			AddSlider(Plugin.HealthShowSeconds, 0f, 15f);
			AddBool(Plugin.HealthShowOnHeal);
			AddBool(Plugin.HealthAlwaysWhenCritical);
			AddSlider(Plugin.HealthAlphaWithStamina, 0f, 1f);
			AddMode(Plugin.StaminaMode);
			AddSlider(Plugin.StaminaShowSecondsAfterSprint, 0f, 15f);
			AddBool(Plugin.StaminaShowWhileExhausted);
			AddMode(Plugin.BatteryMode);
			AddSlider(Plugin.BatteryShowSeconds, 0f, 15f);
			AddMode(Plugin.TooltipsMode);
			AddSlider(Plugin.TooltipsShowSeconds, 0f, 15f);
			Plugin.logger.LogInfo((object)"LethalConfig menu registered.");
		}

		private static void AddBool(ConfigEntry<bool> entry)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			LethalConfigManager.AddConfigItem((BaseConfigItem)new BoolCheckBoxConfigItem(entry, false));
		}

		private static void AddMode(ConfigEntry<HudMode> entry)
		{
			LethalConfigManager.AddConfigItem((BaseConfigItem)(object)new EnumDropDownConfigItem<HudMode>(entry, false));
		}

		private static void AddSlider(ConfigEntry<float> entry, float min, float max)
		{
			//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_000d: Expected O, but got Unknown
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Expected O, but got Unknown
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			FloatSliderOptions val = new FloatSliderOptions();
			((BaseRangeOptions<float>)val).Min = min;
			((BaseRangeOptions<float>)val).Max = max;
			((BaseOptions)val).RequiresRestart = false;
			LethalConfigManager.AddConfigItem((BaseConfigItem)new FloatSliderConfigItem(entry, val));
		}
	}
	[BepInPlugin("BurgenTrucker.LethalUI", "LethalUI", "0.5.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		private const string modGUID = "BurgenTrucker.LethalUI";

		private const string modName = "LethalUI";

		private const string modVersion = "0.5.0";

		internal static ManualLogSource logger;

		private readonly Harmony harmony = new Harmony("BurgenTrucker.LethalUI");

		internal static ConfigEntry<bool> Enabled;

		internal static ConfigEntry<float> HiddenAlpha;

		internal static ConfigEntry<float> FadeDuration;

		internal static ConfigEntry<float> HudScale;

		internal static ConfigEntry<float> EdgeGap;

		internal static ConfigEntry<HudMode> HotbarMode;

		internal static ConfigEntry<float> HotbarShowSeconds;

		internal static ConfigEntry<HudMode> UtilityMode;

		internal static ConfigEntry<HudMode> HealthMode;

		internal static ConfigEntry<float> HealthShowSeconds;

		internal static ConfigEntry<bool> HealthShowOnHeal;

		internal static ConfigEntry<bool> HealthAlwaysWhenCritical;

		internal static ConfigEntry<float> HealthAlphaWithStamina;

		internal static ConfigEntry<HudMode> StaminaMode;

		internal static ConfigEntry<float> StaminaShowSecondsAfterSprint;

		internal static ConfigEntry<bool> StaminaShowWhileExhausted;

		internal static ConfigEntry<HudMode> BatteryMode;

		internal static ConfigEntry<float> BatteryShowSeconds;

		internal static ConfigEntry<HudMode> TooltipsMode;

		internal static ConfigEntry<float> TooltipsShowSeconds;

		private void Awake()
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Expected O, but got Unknown
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Expected O, but got Unknown
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Expected O, but got Unknown
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Expected O, but got Unknown
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Expected O, but got Unknown
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Expected O, but got Unknown
			//IL_0267: Unknown result type (might be due to invalid IL or missing references)
			//IL_0271: Expected O, but got Unknown
			//IL_02c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ce: Expected O, but got Unknown
			//IL_0341: Unknown result type (might be due to invalid IL or missing references)
			//IL_034b: Expected O, but got Unknown
			//IL_039e: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a8: Expected O, but got Unknown
			logger = ((BaseUnityPlugin)this).Logger;
			Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Turn the whole mod on or off.");
			HiddenAlpha = ((BaseUnityPlugin)this).Config.Bind<float>("General", "HiddenAlpha", 0f, new ConfigDescription("Opacity of contextual parts while hidden (0 = invisible, 0.2 = faint).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			FadeDuration = ((BaseUnityPlugin)this).Config.Bind<float>("General", "FadeDuration", 0.4f, new ConfigDescription("Seconds it takes to fade in or out.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 3f), Array.Empty<object>()));
			HudScale = ((BaseUnityPlugin)this).Config.Bind<float>("General", "HudScale", 1f, new ConfigDescription("Size of the HUD (0.8 = 80%). Each part shrinks toward its own screen corner/edge.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.3f, 2f), Array.Empty<object>()));
			EdgeGap = ((BaseUnityPlugin)this).Config.Bind<float>("General", "EdgeGap", 1f, new ConfigDescription("Space between HUD parts and the screen edges (1 = scaled with the HUD, 0 = flush against the edge).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2f), Array.Empty<object>()));
			HotbarMode = ((BaseUnityPlugin)this).Config.Bind<HudMode>("Hotbar", "Mode", HudMode.Contextual, "Contextual: shows when you switch, pick up or drop items.");
			HotbarShowSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Hotbar", "ShowSeconds", 2.5f, new ConfigDescription("How long the hotbar stays visible after a change.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 15f), Array.Empty<object>()));
			UtilityMode = ((BaseUnityPlugin)this).Config.Bind<HudMode>("Hotbar", "UtilitySlotAndWeightMode", HudMode.Contextual, "The utility/belt slot and the weight display (top left). Contextual: shows together with the hotbar.");
			HealthMode = ((BaseUnityPlugin)this).Config.Bind<HudMode>("Health", "Mode", HudMode.Contextual, "Contextual: shows when you take damage.");
			HealthShowSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Health", "ShowSeconds", 4f, new ConfigDescription("How long health stays visible after it changes.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 15f), Array.Empty<object>()));
			HealthShowOnHeal = ((BaseUnityPlugin)this).Config.Bind<bool>("Health", "ShowOnHeal", true, "Also show health when it goes up.");
			HealthAlwaysWhenCritical = ((BaseUnityPlugin)this).Config.Bind<bool>("Health", "AlwaysShowWhenCritical", true, "Keep health visible while critically injured.");
			HealthAlphaWithStamina = ((BaseUnityPlugin)this).Config.Bind<float>("Health", "OpacityWhileStaminaShown", 0.4f, new ConfigDescription("How visible health is while the stamina meter is showing (0 = stays hidden, 1 = fully visible).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			StaminaMode = ((BaseUnityPlugin)this).Config.Bind<HudMode>("Stamina", "Mode", HudMode.Contextual, "Contextual: shows while you sprint.");
			StaminaShowSecondsAfterSprint = ((BaseUnityPlugin)this).Config.Bind<float>("Stamina", "ShowSecondsAfterSprint", 1.5f, new ConfigDescription("How long it stays visible after you stop sprinting.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 15f), Array.Empty<object>()));
			StaminaShowWhileExhausted = ((BaseUnityPlugin)this).Config.Bind<bool>("Stamina", "ShowWhileExhausted", true, "Keep it visible while you're out of breath.");
			BatteryMode = ((BaseUnityPlugin)this).Config.Bind<HudMode>("Battery", "Mode", HudMode.Contextual, "Contextual: shows while a battery item is switched to, on, or changing charge.");
			BatteryShowSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Battery", "ShowSeconds", 2f, new ConfigDescription("How long it stays visible after switching to or using a battery item.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 15f), Array.Empty<object>()));
			TooltipsMode = ((BaseUnityPlugin)this).Config.Bind<HudMode>("Tooltips", "Mode", HudMode.Contextual, "The control hints in the top right. Contextual: shows when they change.");
			TooltipsShowSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Tooltips", "ShowSeconds", 3f, new ConfigDescription("How long the control hints stay visible after they change.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 15f), Array.Empty<object>()));
			if (Chainloader.PluginInfos.ContainsKey("ainavt.lc.lethalconfig"))
			{
				LethalConfigSupport.Register();
			}
			harmony.PatchAll();
			logger.LogInfo((object)"LethalUI 0.5.0 loaded!");
		}
	}
}
namespace LethalUI.Enums
{
	public enum HudMode
	{
		AlwaysVisible,
		Contextual,
		Hidden
	}
}