Decompiled source of PappyHUDMaster v1.0.1

PappyHUDMaster.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace PappyHUDMaster;

[BepInPlugin("pappy.valheim.hudmaster", "Pappy HUD Master", "1.0.1")]
public sealed class PappyHUDMasterPlugin : BaseUnityPlugin
{
	private sealed class GraphicTarget
	{
		public Graphic Graphic;

		public Color OriginalColor;
	}

	private sealed class HudElement
	{
		public string Name;

		public string PathSuffix;

		public string VisualBoundsRelativePath;

		public bool DefaultEnabled;

		public string[] BackgroundGraphicRelativePaths;

		public bool UseWholeElementOpacity;

		public bool UseMinimapCompositeOpacity;

		public CanvasGroup OpacityCanvasGroup;

		public float OriginalCanvasGroupAlpha = 1f;

		public RawImage NativeMinimapRawImage;

		public RawImage CompositeMinimapRawImage;

		public RenderTexture CompositeMinimapTexture;

		public GameObject CompositeMinimapObject;

		public GameObject CaptureCameraObject;

		public Camera CaptureCamera;

		public GameObject CaptureCanvasObject;

		public Canvas CaptureCanvas;

		public RawImage CaptureMapRawImage;

		public bool MinimapCompositeReady;

		public bool MinimapCompositeFailureLogged;

		public RectTransform Transform;

		public int TransformInstanceId;

		public Vector2 OriginalAnchoredPosition;

		public Vector3 OriginalLocalScale;

		public Vector3 OriginalLocalEuler;

		public bool OriginalCaptured;

		public ConfigEntry<bool> Enabled;

		public ConfigEntry<float> OffsetX;

		public ConfigEntry<float> OffsetY;

		public ConfigEntry<float> Scale;

		public ConfigEntry<float> Rotation;

		public ConfigEntry<float> BackgroundOpacity;

		public string EditX;

		public string EditY;

		public string EditScale;

		public string EditRotation;

		public string EditOpacityPercent;

		public readonly List<GraphicTarget> BackgroundGraphics = new List<GraphicTarget>();
	}

	[HarmonyPriority(0)]
	[HarmonyPatch]
	private static class PlayerControllerTakeInputPatch
	{
		private static IEnumerable<MethodBase> TargetMethods()
		{
			MethodInfo method = AccessTools.Method(typeof(PlayerController), "TakeInput", (Type[])null, (Type[])null);
			if (method != null)
			{
				yield return method;
			}
		}

		private static void Postfix(ref bool __result)
		{
			if (ShouldBlockGameInput())
			{
				__result = false;
			}
		}
	}

	[HarmonyPatch]
	[HarmonyPriority(0)]
	private static class TextInputVisiblePatch
	{
		private static IEnumerable<MethodBase> TargetMethods()
		{
			MethodInfo method = AccessTools.Method(typeof(TextInput), "IsVisible", (Type[])null, (Type[])null);
			if (method != null)
			{
				yield return method;
			}
		}

		private static void Postfix(ref bool __result)
		{
			if (ShouldBlockGameInput())
			{
				__result = true;
			}
		}
	}

	[HarmonyPriority(800)]
	[HarmonyPatch]
	private static class ZInputMouseButtonPatch
	{
		private static IEnumerable<MethodBase> TargetMethods()
		{
			string[] names = new string[5] { "GetMouseButton", "GetMouseButtonDown", "GetMouseButtonUp", "GetRadialTap", "GetRadialMultiTap" };
			for (int i = 0; i < names.Length; i++)
			{
				MethodInfo method = AccessTools.Method(typeof(ZInput), names[i], (Type[])null, (Type[])null);
				if (method != null)
				{
					yield return method;
				}
			}
		}

		private static bool Prefix(ref bool __result)
		{
			if (!ShouldBlockGameInput())
			{
				return true;
			}
			__result = false;
			return false;
		}
	}

	[HarmonyPriority(0)]
	[HarmonyPatch]
	private static class ZInputFloatPatch
	{
		private static IEnumerable<MethodBase> TargetMethods()
		{
			string[] names = new string[7] { "GetMouseScrollWheel", "GetJoyLeftStickX", "GetJoyLeftStickY", "GetJoyRightStickX", "GetJoyRightStickY", "GetJoyRTrigger", "GetJoyLTrigger" };
			for (int i = 0; i < names.Length; i++)
			{
				MethodInfo method = AccessTools.Method(typeof(ZInput), names[i], (Type[])null, (Type[])null);
				if (method != null)
				{
					yield return method;
				}
			}
		}

		private static void Postfix(ref float __result)
		{
			if (ShouldBlockGameInput())
			{
				__result = 0f;
			}
		}
	}

	[HarmonyPatch]
	[HarmonyPriority(0)]
	private static class ZInputMouseDeltaPatch
	{
		private static IEnumerable<MethodBase> TargetMethods()
		{
			MethodInfo method = AccessTools.Method(typeof(ZInput), "GetMouseDelta", (Type[])null, (Type[])null);
			if (method != null)
			{
				yield return method;
			}
		}

		private static void Postfix(ref Vector2 __result)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			if (ShouldBlockGameInput())
			{
				__result = Vector2.zero;
			}
		}
	}

	public const string PluginGuid = "pappy.valheim.hudmaster";

	public const string PluginName = "Pappy HUD Master";

	public const string PluginVersion = "1.0.1";

	private const int VK_F7 = 118;

	private static PappyHUDMasterPlugin Instance;

	private Harmony harmony;

	private bool f7WasDown;

	private readonly List<HudElement> elements = new List<HudElement>();

	private ConfigEntry<KeyCode> editorKey;

	private ConfigEntry<float> nudgeAmount;

	private ConfigEntry<float> largeNudgeAmount;

	private bool editorOpen;

	private Rect editorRect = new Rect(30f, 30f, 680f, 820f);

	private Vector2 scroll;

	private int selectedIndex;

	private bool initialResolveComplete;

	private float nextInitialResolveTime;

	private float nextHudLifetimeCheckTime;

	private int trackedHudInstanceId;

	private GUIStyle titleStyle;

	private GUIStyle selectedStyle;

	private GUIStyle normalStyle;

	private GUIStyle smallStyle;

	private Texture2D outlineTexture;

	private Texture2D editorBackgroundTexture;

	private bool cursorStateCaptured;

	private bool previousCursorVisible;

	private CursorLockMode previousCursorLockMode;

	private bool draggingSelected;

	private Vector2 dragStartParentLocal;

	private float dragStartOffsetX;

	private float dragStartOffsetY;

	private bool textFieldFocused;

	[DllImport("user32.dll")]
	private static extern short GetAsyncKeyState(int vKey);

	private void Awake()
	{
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0016: Expected O, but got Unknown
		Instance = this;
		harmony = new Harmony("pappy.valheim.hudmaster");
		harmony.PatchAll();
		editorKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("General", "EditorKey", (KeyCode)288, "Open or close the Pappy HUD Master editor.");
		nudgeAmount = ((BaseUnityPlugin)this).Config.Bind<float>("General", "NudgeAmount", 5f, "Normal movement amount in UI units.");
		largeNudgeAmount = ((BaseUnityPlugin)this).Config.Bind<float>("General", "LargeNudgeAmount", 25f, "Movement amount while holding Shift.");
		RegisterElements();
		((MonoBehaviour)this).StartCoroutine(EditorCursorGuard());
		((BaseUnityPlugin)this).Logger.LogInfo((object)"[Pappy HUD Master] Loaded 1.0.1");
		((BaseUnityPlugin)this).Logger.LogInfo((object)"[Pappy HUD Master] Press F7 to open the HUD editor.");
	}

	private void RegisterElements()
	{
		Add("Hotbar", "/HUD/hudroot/HotKeyBar", defaultEnabled: true);
		Add("Stamina", "/HUD/hudroot/staminapanel", defaultEnabled: true);
		Add("Adrenaline", "/HUD/hudroot/adrenalinepanel", defaultEnabled: true);
		Add("Eitr", "/HUD/hudroot/eitrpanel", defaultEnabled: true);
		Add("Health + Food", "/HUD/hudroot/healthpanel", defaultEnabled: true);
		Add("Crosshair", "/HUD/hudroot/crosshair", defaultEnabled: true);
		Add("Status Effects", "/HUD/hudroot/StatusEffects", defaultEnabled: true);
		AddMinimapCompositeOpacity("Minimap", "/HUD/hudroot/MiniMap/small", defaultEnabled: true);
		Add("Guardian Power", "/HUD/hudroot/GuardianPower", defaultEnabled: true);
		Add("Event Bar", "/HUD/hudroot/EventBar", defaultEnabled: true);
		Add("Action Progress", "/HUD/hudroot/action_progress", defaultEnabled: true);
		Add("Player Inventory", "/Inventory_screen/root/Player", defaultEnabled: true, new string[2] { "Bkg", "Darken" });
		Add("Inventory Info", "/Inventory_screen/root/Info", defaultEnabled: true, new string[2] { "Bkg", "Darken" });
		Add("Crafting Window", "/Inventory_screen/root/Crafting", defaultEnabled: true, new string[2] { "Bkg", "Darken" });
		Add("Crafting Recipe List", "/Inventory_screen/root/Crafting/RecipeList", defaultEnabled: false);
		Add("Crafting Item Details", "/Inventory_screen/root/Crafting/Decription", defaultEnabled: false);
		Add("Build Menu", "/HUD/hudroot/BuildUIV2/bar", defaultEnabled: true, new string[1] { "SelectionWindow/Background" });
		Add("Boss Health", "/EnemyHud/HudRoot/HudBaseBoss", defaultEnabled: true);
		Add("Center Message", "/HudMessage/MessageCenter", defaultEnabled: true);
		Add("Top Left Message", "/TopLeftMessage/root", defaultEnabled: true);
		AddWithVisualBounds("Chat Window (Enter)", "/Chat_box/root", defaultEnabled: true, "bkg");
		Add("Chat Input Field", "/Chat_box/root/ChatInput", defaultEnabled: false);
		Add("World Chat Bubble", "/Chat/DialogBox", defaultEnabled: false);
		Add("NPC Dialog", "/Chat/NpcDialog", defaultEnabled: true);
		Add("Large NPC Dialog", "/Chat/NpcDialogLarge", defaultEnabled: true);
	}

	private void Add(string name, string pathSuffix, bool defaultEnabled)
	{
		Add(name, pathSuffix, defaultEnabled, null);
	}

	private void AddWithVisualBounds(string name, string pathSuffix, bool defaultEnabled, string visualBoundsRelativePath)
	{
		Add(name, pathSuffix, defaultEnabled, null);
		HudElement hudElement = elements[elements.Count - 1];
		hudElement.VisualBoundsRelativePath = visualBoundsRelativePath;
	}

	private void Add(string name, string pathSuffix, bool defaultEnabled, string[] backgroundGraphicRelativePaths)
	{
		string text = "Element - " + name;
		HudElement hudElement = new HudElement();
		hudElement.Name = name;
		hudElement.PathSuffix = pathSuffix;
		hudElement.DefaultEnabled = defaultEnabled;
		hudElement.BackgroundGraphicRelativePaths = backgroundGraphicRelativePaths;
		hudElement.Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>(text, "Enabled", defaultEnabled, "Allow Pappy HUD Master to control this element.");
		hudElement.OffsetX = ((BaseUnityPlugin)this).Config.Bind<float>(text, "OffsetX", 0f, "Horizontal offset from Valheim's original position.");
		hudElement.OffsetY = ((BaseUnityPlugin)this).Config.Bind<float>(text, "OffsetY", 0f, "Vertical offset from Valheim's original position.");
		hudElement.Scale = ((BaseUnityPlugin)this).Config.Bind<float>(text, "Scale", 1f, "Scale multiplier. 1.0 is Valheim's original size.");
		hudElement.Rotation = ((BaseUnityPlugin)this).Config.Bind<float>(text, "Rotation", 0f, "Additional Z rotation in degrees.");
		if (backgroundGraphicRelativePaths != null && backgroundGraphicRelativePaths.Length > 0)
		{
			hudElement.BackgroundOpacity = ((BaseUnityPlugin)this).Config.Bind<float>(text, "BackgroundOpacity", 1f, "Background opacity from 0.05 to 1.0. Text/icons remain full opacity.");
		}
		SyncEditStrings(hudElement);
		elements.Add(hudElement);
	}

	private void AddWholeOpacity(string name, string pathSuffix, bool defaultEnabled)
	{
		Add(name, pathSuffix, defaultEnabled, null);
		HudElement hudElement = elements[elements.Count - 1];
		hudElement.UseWholeElementOpacity = true;
		string text = "Element - " + name;
		hudElement.BackgroundOpacity = ((BaseUnityPlugin)this).Config.Bind<float>(text, "BackgroundOpacity", 1f, "Whole-element opacity from 0.05 to 1.0.");
		SyncEditStrings(hudElement);
	}

	private void AddMinimapCompositeOpacity(string name, string pathSuffix, bool defaultEnabled)
	{
		Add(name, pathSuffix, defaultEnabled, null);
		HudElement hudElement = elements[elements.Count - 1];
		hudElement.UseMinimapCompositeOpacity = true;
		string text = "Element - " + name;
		hudElement.BackgroundOpacity = ((BaseUnityPlugin)this).Config.Bind<float>(text, "BackgroundOpacity", 1f, "Minimap terrain opacity from 0.05 to 1.0.");
		SyncEditStrings(hudElement);
	}

	private void Update()
	{
		if (EditorTogglePressed())
		{
			SetEditorOpen(!editorOpen);
		}
		if (editorOpen)
		{
			ForceEditorCursor();
			if (!textFieldFocused && elements.Count > 0)
			{
				ProcessKeyboardNudging();
			}
		}
		if (Time.unscaledTime >= nextHudLifetimeCheckTime)
		{
			nextHudLifetimeCheckTime = Time.unscaledTime + 1f;
			CheckHudLifetime();
		}
		if (!initialResolveComplete && Time.unscaledTime >= nextInitialResolveTime)
		{
			nextInitialResolveTime = Time.unscaledTime + 1f;
			TryInitialResolve();
		}
	}

	private bool EditorTogglePressed()
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Invalid comparison between Unknown and I4
		//IL_004d: 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_0018: Invalid comparison between Unknown and I4
		if ((int)editorKey.Value == 288 && (int)Application.platform == 2)
		{
			bool flag = (GetAsyncKeyState(118) & 0x8000) != 0;
			bool result = flag && !f7WasDown;
			f7WasDown = flag;
			return result;
		}
		return Input.GetKeyDown(editorKey.Value);
	}

	private void LateUpdate()
	{
		for (int i = 0; i < elements.Count; i++)
		{
			ApplyElement(elements[i]);
		}
	}

	private IEnumerator EditorCursorGuard()
	{
		WaitForEndOfFrame wait = new WaitForEndOfFrame();
		while (true)
		{
			yield return wait;
			if (editorOpen)
			{
				ForceEditorCursor();
			}
		}
	}

	private void OnDisable()
	{
		if (editorOpen)
		{
			SetEditorOpen(open: false);
		}
		CleanupAllMinimapCompositors();
		if (harmony != null)
		{
			harmony.UnpatchSelf();
		}
		if ((Object)(object)Instance == (Object)(object)this)
		{
			Instance = null;
		}
	}

	private void SetEditorOpen(bool open)
	{
		//IL_006a: 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_0034: Unknown result type (might be due to invalid IL or missing references)
		if (open == editorOpen)
		{
			return;
		}
		editorOpen = open;
		draggingSelected = false;
		if (open)
		{
			if (!cursorStateCaptured)
			{
				previousCursorVisible = Cursor.visible;
				previousCursorLockMode = Cursor.lockState;
				cursorStateCaptured = true;
			}
			ForceEditorCursor();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"[Pappy HUD Master] Editor opened.");
		}
		else
		{
			if (cursorStateCaptured)
			{
				Cursor.visible = previousCursorVisible;
				Cursor.lockState = previousCursorLockMode;
				cursorStateCaptured = false;
			}
			((BaseUnityPlugin)this).Config.Save();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"[Pappy HUD Master] Editor closed.");
		}
	}

	private static void ForceEditorCursor()
	{
		Cursor.lockState = (CursorLockMode)0;
		Cursor.visible = true;
	}

	private void CheckHudLifetime()
	{
		GameObject val = GameObject.Find("_GameMain/LoadingGUI/PixelFix/IngameGui/HUD");
		if ((Object)(object)val == (Object)null)
		{
			if (trackedHudInstanceId != 0)
			{
				trackedHudInstanceId = 0;
				ResetUiResolution("In-game HUD was destroyed; waiting for a new world/UI.");
			}
			return;
		}
		int instanceID = ((Object)val).GetInstanceID();
		if (trackedHudInstanceId == 0)
		{
			trackedHudInstanceId = instanceID;
			if (initialResolveComplete)
			{
				ResetUiResolution("New in-game HUD detected; rebuilding UI cache.");
			}
		}
		else if (trackedHudInstanceId != instanceID)
		{
			trackedHudInstanceId = instanceID;
			ResetUiResolution("In-game HUD instance changed; rebuilding UI cache.");
		}
	}

	private void ResetUiResolution(string reason)
	{
		if (editorOpen)
		{
			SetEditorOpen(open: false);
		}
		CleanupAllMinimapCompositors();
		for (int i = 0; i < elements.Count; i++)
		{
			HudElement hudElement = elements[i];
			if (hudElement != null)
			{
				hudElement.Transform = null;
				hudElement.TransformInstanceId = 0;
				hudElement.OriginalCaptured = false;
				hudElement.BackgroundGraphics.Clear();
				hudElement.OpacityCanvasGroup = null;
			}
		}
		draggingSelected = false;
		initialResolveComplete = false;
		nextInitialResolveTime = 0f;
		((BaseUnityPlugin)this).Logger.LogInfo((object)("[Pappy HUD Master] " + reason));
	}

	private void TryInitialResolve()
	{
		GameObject val = GameObject.Find("_GameMain/LoadingGUI/PixelFix/IngameGui/HUD");
		if (!((Object)(object)val == (Object)null))
		{
			trackedHudInstanceId = ((Object)val).GetInstanceID();
			int num = ResolveAllElementsOnce();
			if (num >= 18)
			{
				initialResolveComplete = true;
				((BaseUnityPlugin)this).Logger.LogInfo((object)("[Pappy HUD Master] Initial UI resolve complete: " + num + "/" + elements.Count + ". Periodic full-scene scanning is disabled."));
			}
		}
	}

	private int ResolveAllElementsOnce()
	{
		RectTransform[] array = Resources.FindObjectsOfTypeAll<RectTransform>();
		RectTransform[] array2 = (RectTransform[])(object)new RectTransform[elements.Count];
		bool[] array3 = new bool[elements.Count];
		foreach (RectTransform val in array)
		{
			if ((Object)(object)val == (Object)null)
			{
				continue;
			}
			string a = NormalizeCloneNames(((Object)val).name);
			string text = null;
			for (int j = 0; j < elements.Count; j++)
			{
				HudElement hudElement = elements[j];
				string leafName = GetLeafName(hudElement.PathSuffix);
				if (!string.Equals(a, leafName, StringComparison.Ordinal))
				{
					continue;
				}
				if (text == null)
				{
					text = NormalizeCloneNames(GetTransformPath((Transform)(object)val));
				}
				if (text.EndsWith(hudElement.PathSuffix, StringComparison.Ordinal))
				{
					bool activeInHierarchy = ((Component)val).gameObject.activeInHierarchy;
					if ((Object)(object)array2[j] == (Object)null || (activeInHierarchy && !array3[j]))
					{
						array2[j] = val;
						array3[j] = activeInHierarchy;
					}
				}
			}
		}
		int num = 0;
		for (int k = 0; k < elements.Count; k++)
		{
			if (!((Object)(object)array2[k] == (Object)null))
			{
				num++;
				AttachTransform(elements[k], array2[k]);
			}
		}
		return num;
	}

	private void RefreshSelectedElement()
	{
		if (elements.Count != 0)
		{
			HudElement hudElement = elements[selectedIndex];
			RectTransform[] all = Resources.FindObjectsOfTypeAll<RectTransform>();
			RectTransform val = FindBestMatch(all, hudElement.PathSuffix);
			if ((Object)(object)val != (Object)null)
			{
				AttachTransform(hudElement, val);
				((BaseUnityPlugin)this).Logger.LogInfo((object)("[Pappy HUD Master] Manual refresh resolved " + hudElement.Name + "."));
			}
			else
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("[Pappy HUD Master] Manual refresh could not find " + hudElement.Name + "."));
			}
		}
	}

	private static string GetLeafName(string suffix)
	{
		int num = suffix.LastIndexOf('/');
		if (num < 0 || num == suffix.Length - 1)
		{
			return suffix;
		}
		return suffix.Substring(num + 1);
	}

	private void AttachTransform(HudElement element, RectTransform found)
	{
		//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_0030: 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_0041: Unknown result type (might be due to invalid IL or missing references)
		if (element.UseMinimapCompositeOpacity)
		{
			CleanupMinimapCompositor(element);
		}
		element.Transform = found;
		element.TransformInstanceId = ((Object)found).GetInstanceID();
		element.OriginalAnchoredPosition = found.anchoredPosition;
		element.OriginalLocalScale = ((Transform)found).localScale;
		element.OriginalLocalEuler = ((Transform)found).localEulerAngles;
		element.OriginalCaptured = true;
		element.BackgroundGraphics.Clear();
		element.OpacityCanvasGroup = null;
		ResolveBackgroundGraphics(element);
		ResolveWholeElementOpacity(element);
		ResolveMinimapCompositor(element);
		((BaseUnityPlugin)this).Logger.LogInfo((object)("[Pappy HUD Master] Found " + element.Name + " -> " + GetTransformPath((Transform)(object)found) + (((Component)found).gameObject.activeInHierarchy ? " [ACTIVE]" : " [inactive]")));
	}

	private static RectTransform FindBestMatch(RectTransform[] all, string suffix)
	{
		RectTransform val = null;
		foreach (RectTransform val2 in all)
		{
			if ((Object)(object)val2 == (Object)null || !string.Equals(NormalizeCloneNames(((Object)val2).name), GetLeafName(suffix), StringComparison.Ordinal))
			{
				continue;
			}
			string text = NormalizeCloneNames(GetTransformPath((Transform)(object)val2));
			if (text.EndsWith(suffix, StringComparison.Ordinal))
			{
				if (((Component)val2).gameObject.activeInHierarchy)
				{
					return val2;
				}
				if ((Object)(object)val == (Object)null)
				{
					val = val2;
				}
			}
		}
		return val;
	}

	private static string NormalizeCloneNames(string path)
	{
		return path.Replace("(Clone)", "");
	}

	private void ResolveBackgroundGraphics(HudElement element)
	{
		//IL_0099: 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)
		if ((Object)(object)element.Transform == (Object)null || element.BackgroundGraphicRelativePaths == null)
		{
			return;
		}
		Graphic[] componentsInChildren = ((Component)element.Transform).GetComponentsInChildren<Graphic>(true);
		for (int i = 0; i < element.BackgroundGraphicRelativePaths.Length; i++)
		{
			string text = element.BackgroundGraphicRelativePaths[i];
			string text2 = NormalizeCloneNames(GetTransformPath((Transform)(object)element.Transform) + "/" + text);
			foreach (Graphic val in componentsInChildren)
			{
				if (!((Object)(object)val == (Object)null))
				{
					string text3 = NormalizeCloneNames(GetTransformPath(((Component)val).transform));
					if (text3 == text2)
					{
						GraphicTarget graphicTarget = new GraphicTarget();
						graphicTarget.Graphic = val;
						graphicTarget.OriginalColor = val.color;
						element.BackgroundGraphics.Add(graphicTarget);
						((BaseUnityPlugin)this).Logger.LogInfo((object)("[Pappy HUD Master] Opacity target for " + element.Name + " -> " + text3));
						break;
					}
				}
			}
		}
	}

	private void ResolveWholeElementOpacity(HudElement element)
	{
		if (element != null && !((Object)(object)element.Transform == (Object)null) && element.UseWholeElementOpacity && element.BackgroundOpacity != null)
		{
			CanvasGroup val = ((Component)element.Transform).GetComponent<CanvasGroup>();
			if ((Object)(object)val == (Object)null)
			{
				val = ((Component)element.Transform).gameObject.AddComponent<CanvasGroup>();
			}
			element.OpacityCanvasGroup = val;
			element.OriginalCanvasGroupAlpha = val.alpha;
			val.interactable = true;
			val.blocksRaycasts = true;
			((BaseUnityPlugin)this).Logger.LogInfo((object)("[Pappy HUD Master] Whole-element opacity target for " + element.Name + " -> " + GetTransformPath((Transform)(object)element.Transform)));
		}
	}

	private void ResolveMinimapCompositor(HudElement element)
	{
		//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ac: Expected O, but got Unknown
		//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fd: 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_012a: 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: Expected O, but got Unknown
		//IL_0191: Unknown result type (might be due to invalid IL or missing references)
		//IL_0198: Expected O, but got Unknown
		//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_0232: Unknown result type (might be due to invalid IL or missing references)
		//IL_0239: Expected O, but got Unknown
		//IL_02b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b8: Expected O, but got Unknown
		//IL_02db: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_02fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0309: Unknown result type (might be due to invalid IL or missing references)
		//IL_0315: Unknown result type (might be due to invalid IL or missing references)
		//IL_0321: Unknown result type (might be due to invalid IL or missing references)
		//IL_032d: Unknown result type (might be due to invalid IL or missing references)
		//IL_034b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0372: Unknown result type (might be due to invalid IL or missing references)
		if (element == null || (Object)(object)element.Transform == (Object)null || !element.UseMinimapCompositeOpacity)
		{
			return;
		}
		Transform val = ((Transform)element.Transform).Find("map");
		if ((Object)(object)val == (Object)null)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)"[Pappy HUD Master] Minimap compositor: small/map was not found.");
			return;
		}
		RawImage component = ((Component)val).GetComponent<RawImage>();
		if ((Object)(object)component == (Object)null)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)"[Pappy HUD Master] Minimap compositor: native RawImage was not found.");
			return;
		}
		element.NativeMinimapRawImage = component;
		GameObject val2 = new GameObject("PappyHUDMaster_MinimapTerrain", new Type[3]
		{
			typeof(RectTransform),
			typeof(CanvasRenderer),
			typeof(RawImage)
		});
		RectTransform component2 = val2.GetComponent<RectTransform>();
		((Transform)component2).SetParent(val, false);
		component2.anchorMin = Vector2.zero;
		component2.anchorMax = Vector2.one;
		component2.pivot = new Vector2(0.5f, 0.5f);
		component2.offsetMin = Vector2.zero;
		component2.offsetMax = Vector2.zero;
		((Transform)component2).localScale = Vector3.one;
		((Transform)component2).localRotation = Quaternion.identity;
		((Transform)component2).SetAsFirstSibling();
		RawImage component3 = val2.GetComponent<RawImage>();
		((Graphic)component3).raycastTarget = false;
		((Graphic)component3).color = Color.white;
		RenderTexture val3 = new RenderTexture(512, 512, 0, (RenderTextureFormat)0);
		((Object)val3).name = "PappyHUDMaster_MinimapComposite";
		((Texture)val3).filterMode = (FilterMode)1;
		((Texture)val3).wrapMode = (TextureWrapMode)1;
		val3.Create();
		component3.texture = (Texture)(object)val3;
		GameObject val4 = new GameObject("PappyHUDMaster_MinimapCaptureCamera", new Type[1] { typeof(Camera) });
		val4.layer = 31;
		Camera component4 = val4.GetComponent<Camera>();
		((Behaviour)component4).enabled = false;
		component4.clearFlags = (CameraClearFlags)2;
		component4.backgroundColor = new Color(0f, 0f, 0f, 0f);
		component4.cullingMask = int.MinValue;
		component4.targetTexture = val3;
		component4.nearClipPlane = 0.01f;
		component4.farClipPlane = 10f;
		GameObject val5 = new GameObject("PappyHUDMaster_MinimapCaptureCanvas", new Type[2]
		{
			typeof(RectTransform),
			typeof(Canvas)
		});
		val5.layer = 31;
		Canvas component5 = val5.GetComponent<Canvas>();
		component5.renderMode = (RenderMode)1;
		component5.worldCamera = component4;
		component5.planeDistance = 1f;
		component5.pixelPerfect = false;
		component5.sortingOrder = 0;
		GameObject val6 = new GameObject("Map", new Type[3]
		{
			typeof(RectTransform),
			typeof(CanvasRenderer),
			typeof(RawImage)
		});
		val6.layer = 31;
		RectTransform component6 = val6.GetComponent<RectTransform>();
		((Transform)component6).SetParent(val5.transform, false);
		component6.anchorMin = Vector2.zero;
		component6.anchorMax = Vector2.one;
		component6.pivot = new Vector2(0.5f, 0.5f);
		component6.offsetMin = Vector2.zero;
		component6.offsetMax = Vector2.zero;
		((Transform)component6).localScale = Vector3.one;
		((Transform)component6).localRotation = Quaternion.identity;
		RawImage component7 = val6.GetComponent<RawImage>();
		((Graphic)component7).raycastTarget = false;
		((Graphic)component7).color = ((Graphic)component).color;
		component7.texture = GetMinimapCaptureSource(component);
		((Graphic)component7).material = ((Graphic)component).material;
		component7.uvRect = component.uvRect;
		element.CompositeMinimapObject = val2;
		element.CompositeMinimapRawImage = component3;
		element.CompositeMinimapTexture = val3;
		element.CaptureCameraObject = val4;
		element.CaptureCamera = component4;
		element.CaptureCanvasObject = val5;
		element.CaptureCanvas = component5;
		element.CaptureMapRawImage = component7;
		element.MinimapCompositeReady = true;
		element.MinimapCompositeFailureLogged = false;
		((Behaviour)component3).enabled = false;
		((Behaviour)component).enabled = true;
		Material material = ((Graphic)component).material;
		string text = "<none>";
		if ((Object)(object)material != (Object)null && (Object)(object)material.shader != (Object)null)
		{
			text = ((Object)material.shader).name;
		}
		Texture minimapCaptureSource = GetMinimapCaptureSource(component);
		string text2 = "<not assigned yet>";
		if ((Object)(object)minimapCaptureSource != (Object)null)
		{
			text2 = ((Object)minimapCaptureSource).name + " (" + minimapCaptureSource.width + "x" + minimapCaptureSource.height + ")";
		}
		((BaseUnityPlugin)this).Logger.LogInfo((object)("[Pappy HUD Master] Minimap UI-capture compositor ready. Native shader: " + text + " | capture source: " + text2 + ". Native material is NOT replaced or modified."));
	}

	private static Texture GetMinimapCaptureSource(RawImage native)
	{
		if ((Object)(object)native == (Object)null)
		{
			return null;
		}
		if ((Object)(object)native.texture != (Object)null)
		{
			return native.texture;
		}
		Material material = ((Graphic)native).material;
		if ((Object)(object)material != (Object)null)
		{
			if (material.HasProperty("_MainTex"))
			{
				Texture texture = material.GetTexture("_MainTex");
				if ((Object)(object)texture != (Object)null)
				{
					return texture;
				}
			}
			if ((Object)(object)material.mainTexture != (Object)null)
			{
				return material.mainTexture;
			}
		}
		return null;
	}

	private void UpdateMinimapComposite(HudElement element, float opacity)
	{
		//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f9: 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_012f: 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_013f: Unknown result type (might be due to invalid IL or missing references)
		if (element == null || !element.UseMinimapCompositeOpacity || !element.MinimapCompositeReady)
		{
			return;
		}
		RawImage nativeMinimapRawImage = element.NativeMinimapRawImage;
		RawImage compositeMinimapRawImage = element.CompositeMinimapRawImage;
		RenderTexture compositeMinimapTexture = element.CompositeMinimapTexture;
		Camera captureCamera = element.CaptureCamera;
		RawImage captureMapRawImage = element.CaptureMapRawImage;
		if ((Object)(object)nativeMinimapRawImage == (Object)null || (Object)(object)compositeMinimapRawImage == (Object)null || (Object)(object)compositeMinimapTexture == (Object)null || (Object)(object)captureCamera == (Object)null || (Object)(object)captureMapRawImage == (Object)null)
		{
			element.MinimapCompositeReady = false;
			return;
		}
		if (opacity >= 0.999f)
		{
			((Behaviour)nativeMinimapRawImage).enabled = true;
			((Behaviour)compositeMinimapRawImage).enabled = false;
			return;
		}
		Material material = ((Graphic)nativeMinimapRawImage).material;
		Texture minimapCaptureSource = GetMinimapCaptureSource(nativeMinimapRawImage);
		if ((Object)(object)material == (Object)null || (Object)(object)minimapCaptureSource == (Object)null)
		{
			((Behaviour)nativeMinimapRawImage).enabled = true;
			((Behaviour)compositeMinimapRawImage).enabled = false;
			if (!element.MinimapCompositeFailureLogged)
			{
				element.MinimapCompositeFailureLogged = true;
				((BaseUnityPlugin)this).Logger.LogWarning((object)"[Pappy HUD Master] Minimap UI-capture compositor: map material or _MainTex source unavailable.");
			}
			return;
		}
		try
		{
			captureMapRawImage.texture = minimapCaptureSource;
			((Graphic)captureMapRawImage).material = material;
			captureMapRawImage.uvRect = nativeMinimapRawImage.uvRect;
			((Graphic)captureMapRawImage).color = ((Graphic)nativeMinimapRawImage).color;
			captureCamera.Render();
			compositeMinimapRawImage.texture = (Texture)(object)compositeMinimapTexture;
			compositeMinimapRawImage.uvRect = new Rect(0f, 0f, 1f, 1f);
			Color white = Color.white;
			white.a = opacity;
			((Graphic)compositeMinimapRawImage).color = white;
			((Behaviour)compositeMinimapRawImage).enabled = true;
			((Behaviour)nativeMinimapRawImage).enabled = false;
			element.MinimapCompositeFailureLogged = false;
		}
		catch (Exception ex)
		{
			((Behaviour)nativeMinimapRawImage).enabled = true;
			((Behaviour)compositeMinimapRawImage).enabled = false;
			if (!element.MinimapCompositeFailureLogged)
			{
				element.MinimapCompositeFailureLogged = true;
				((BaseUnityPlugin)this).Logger.LogWarning((object)("[Pappy HUD Master] Minimap UI-capture compositor failed; restored native map. " + ex.Message));
			}
		}
	}

	private void CleanupAllMinimapCompositors()
	{
		for (int i = 0; i < elements.Count; i++)
		{
			HudElement hudElement = elements[i];
			if (hudElement != null && hudElement.UseMinimapCompositeOpacity)
			{
				CleanupMinimapCompositor(hudElement);
			}
		}
	}

	private void CleanupMinimapCompositor(HudElement element)
	{
		if (element == null)
		{
			return;
		}
		if ((Object)(object)element.NativeMinimapRawImage != (Object)null)
		{
			((Behaviour)element.NativeMinimapRawImage).enabled = true;
		}
		if ((Object)(object)element.CompositeMinimapRawImage != (Object)null)
		{
			((Behaviour)element.CompositeMinimapRawImage).enabled = false;
		}
		if ((Object)(object)element.CaptureCamera != (Object)null)
		{
			element.CaptureCamera.targetTexture = null;
		}
		if ((Object)(object)element.CompositeMinimapTexture != (Object)null)
		{
			try
			{
				if (element.CompositeMinimapTexture.IsCreated())
				{
					element.CompositeMinimapTexture.Release();
				}
			}
			catch
			{
			}
			Object.Destroy((Object)(object)element.CompositeMinimapTexture);
		}
		if ((Object)(object)element.CaptureCanvasObject != (Object)null)
		{
			Object.Destroy((Object)(object)element.CaptureCanvasObject);
		}
		if ((Object)(object)element.CaptureCameraObject != (Object)null)
		{
			Object.Destroy((Object)(object)element.CaptureCameraObject);
		}
		if ((Object)(object)element.CompositeMinimapObject != (Object)null)
		{
			Object.Destroy((Object)(object)element.CompositeMinimapObject);
		}
		element.NativeMinimapRawImage = null;
		element.CompositeMinimapRawImage = null;
		element.CompositeMinimapTexture = null;
		element.CompositeMinimapObject = null;
		element.CaptureCameraObject = null;
		element.CaptureCamera = null;
		element.CaptureCanvasObject = null;
		element.CaptureCanvas = null;
		element.CaptureMapRawImage = null;
		element.MinimapCompositeReady = false;
		element.MinimapCompositeFailureLogged = false;
	}

	private void ApplyElement(HudElement element)
	{
		//IL_0033: 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_0053: 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_00a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
		if (element == null || (Object)(object)element.Transform == (Object)null || !element.OriginalCaptured)
		{
			return;
		}
		try
		{
			if (element.Enabled.Value)
			{
				RectTransform transform = element.Transform;
				transform.anchoredPosition = element.OriginalAnchoredPosition + new Vector2(element.OffsetX.Value, element.OffsetY.Value);
				float num = Mathf.Clamp(element.Scale.Value, 0.25f, 4f);
				((Transform)transform).localScale = new Vector3(element.OriginalLocalScale.x * num, element.OriginalLocalScale.y * num, element.OriginalLocalScale.z);
				Vector3 originalLocalEuler = element.OriginalLocalEuler;
				originalLocalEuler.z = element.OriginalLocalEuler.z + element.Rotation.Value;
				((Transform)transform).localEulerAngles = originalLocalEuler;
			}
			ApplyBackgroundOpacity(element);
		}
		catch
		{
			element.Transform = null;
			element.OriginalCaptured = false;
			element.BackgroundGraphics.Clear();
		}
	}

	private static void ApplyBackgroundOpacity(HudElement element)
	{
		//IL_0091: Unknown result type (might be due to invalid IL or missing references)
		//IL_0096: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
		if (element.BackgroundOpacity == null)
		{
			return;
		}
		float num = Mathf.Clamp(element.BackgroundOpacity.Value, 0.05f, 1f);
		if (element.UseWholeElementOpacity && (Object)(object)element.OpacityCanvasGroup != (Object)null)
		{
			element.OpacityCanvasGroup.alpha = element.OriginalCanvasGroupAlpha * num;
		}
		if (element.UseMinimapCompositeOpacity && (Object)(object)Instance != (Object)null)
		{
			Instance.UpdateMinimapComposite(element, num);
		}
		for (int i = 0; i < element.BackgroundGraphics.Count; i++)
		{
			GraphicTarget graphicTarget = element.BackgroundGraphics[i];
			if (graphicTarget != null && !((Object)(object)graphicTarget.Graphic == (Object)null))
			{
				Color originalColor = graphicTarget.OriginalColor;
				originalColor.a = graphicTarget.OriginalColor.a * num;
				graphicTarget.Graphic.color = originalColor;
			}
		}
	}

	private void ProcessKeyboardNudging()
	{
		HudElement hudElement = elements[selectedIndex];
		float num = ((Input.GetKey((KeyCode)304) || Input.GetKey((KeyCode)303)) ? largeNudgeAmount.Value : nudgeAmount.Value);
		bool flag = false;
		if (Input.GetKeyDown((KeyCode)276))
		{
			ConfigEntry<float> offsetX = hudElement.OffsetX;
			offsetX.Value -= num;
			flag = true;
		}
		if (Input.GetKeyDown((KeyCode)275))
		{
			ConfigEntry<float> offsetX2 = hudElement.OffsetX;
			offsetX2.Value += num;
			flag = true;
		}
		if (Input.GetKeyDown((KeyCode)273))
		{
			ConfigEntry<float> offsetY = hudElement.OffsetY;
			offsetY.Value += num;
			flag = true;
		}
		if (Input.GetKeyDown((KeyCode)274))
		{
			ConfigEntry<float> offsetY2 = hudElement.OffsetY;
			offsetY2.Value -= num;
			flag = true;
		}
		if (Input.GetKeyDown((KeyCode)61) || Input.GetKeyDown((KeyCode)270))
		{
			hudElement.Scale.Value = Mathf.Clamp(hudElement.Scale.Value + 0.05f, 0.25f, 4f);
			flag = true;
		}
		if (Input.GetKeyDown((KeyCode)45) || Input.GetKeyDown((KeyCode)269))
		{
			hudElement.Scale.Value = Mathf.Clamp(hudElement.Scale.Value - 0.05f, 0.25f, 4f);
			flag = true;
		}
		if (Input.GetKeyDown((KeyCode)113))
		{
			ConfigEntry<float> rotation = hudElement.Rotation;
			rotation.Value -= 5f;
			flag = true;
		}
		if (Input.GetKeyDown((KeyCode)101))
		{
			ConfigEntry<float> rotation2 = hudElement.Rotation;
			rotation2.Value += 5f;
			flag = true;
		}
		if (Input.GetKeyDown((KeyCode)114))
		{
			ResetElement(hudElement);
			flag = true;
		}
		if (flag)
		{
			SyncEditStrings(hudElement);
			((BaseUnityPlugin)this).Config.Save();
		}
	}

	private void OnGUI()
	{
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_005c: Expected O, but got Unknown
		//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_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		EnsureStyles();
		if (editorOpen)
		{
			ForceEditorCursor();
			textFieldFocused = false;
			if (TryGetSelectedScreenRect(out var rect))
			{
				DrawOutline(rect, 2f);
				HandleSelectedDrag(rect);
			}
			editorRect = GUI.Window(847211, editorRect, new WindowFunction(DrawEditorWindow), "");
		}
	}

	private void HandleSelectedDrag(Rect selectedRect)
	{
		//IL_009a: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_014b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0151: Invalid comparison between Unknown and I4
		//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cd: Invalid comparison between Unknown and I4
		//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_0102: Unknown result type (might be due to invalid IL or missing references)
		//IL_016a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0114: Unknown result type (might be due to invalid IL or missing references)
		//IL_0115: Unknown result type (might be due to invalid IL or missing references)
		//IL_0178: Unknown result type (might be due to invalid IL or missing references)
		//IL_017b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0180: 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)
		if (elements.Count == 0)
		{
			return;
		}
		HudElement hudElement = elements[selectedIndex];
		if ((Object)(object)hudElement.Transform == (Object)null || !((Component)hudElement.Transform).gameObject.activeInHierarchy || !hudElement.Enabled.Value)
		{
			draggingSelected = false;
			return;
		}
		Rect val = default(Rect);
		((Rect)(ref val))..ctor(((Rect)(ref selectedRect)).x, Mathf.Max(0f, ((Rect)(ref selectedRect)).y - 24f), Mathf.Max(100f, Mathf.Min(((Rect)(ref selectedRect)).width, 180f)), 22f);
		GUI.Box(val, "DRAG " + hudElement.Name, smallStyle);
		Event current = Event.current;
		if (current == null || (!draggingSelected && ((Rect)(ref editorRect)).Contains(current.mousePosition)))
		{
			return;
		}
		if ((int)current.type == 0 && current.button == 0 && ((Rect)(ref val)).Contains(current.mousePosition))
		{
			if (ScreenPointToParentLocal(hudElement.Transform, current.mousePosition, out var localPoint))
			{
				dragStartParentLocal = localPoint;
				dragStartOffsetX = hudElement.OffsetX.Value;
				dragStartOffsetY = hudElement.OffsetY.Value;
				draggingSelected = true;
				current.Use();
			}
		}
		else if ((int)current.type == 3 && current.button == 0 && draggingSelected)
		{
			if (ScreenPointToParentLocal(hudElement.Transform, current.mousePosition, out var localPoint2))
			{
				Vector2 val2 = localPoint2 - dragStartParentLocal;
				hudElement.OffsetX.Value = dragStartOffsetX + val2.x;
				hudElement.OffsetY.Value = dragStartOffsetY + val2.y;
				SyncEditStrings(hudElement);
			}
			current.Use();
		}
		else if ((int)current.type == 1 && current.button == 0 && draggingSelected)
		{
			draggingSelected = false;
			SyncEditStrings(hudElement);
			((BaseUnityPlugin)this).Config.Save();
			current.Use();
		}
	}

	private static bool ScreenPointToParentLocal(RectTransform rt, Vector2 guiMousePosition, out Vector2 localPoint)
	{
		//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_006b: 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)
		localPoint = Vector2.zero;
		if ((Object)(object)rt == (Object)null)
		{
			return false;
		}
		Transform parent = ((Transform)rt).parent;
		RectTransform val = (RectTransform)(object)((parent is RectTransform) ? parent : null);
		if ((Object)(object)val == (Object)null)
		{
			return false;
		}
		Vector2 val2 = default(Vector2);
		((Vector2)(ref val2))..ctor(guiMousePosition.x, (float)Screen.height - guiMousePosition.y);
		Canvas componentInParent = ((Component)rt).GetComponentInParent<Canvas>();
		Camera val3 = null;
		if ((Object)(object)componentInParent != (Object)null && (int)componentInParent.renderMode != 0)
		{
			val3 = componentInParent.worldCamera;
		}
		return RectTransformUtility.ScreenPointToLocalPointInRectangle(val, val2, val3, ref localPoint);
	}

	private RectTransform GetVisualBoundsTransform(HudElement element)
	{
		if (element == null || (Object)(object)element.Transform == (Object)null)
		{
			return null;
		}
		if (!string.IsNullOrEmpty(element.VisualBoundsRelativePath))
		{
			Transform val = ((Transform)element.Transform).Find(element.VisualBoundsRelativePath);
			RectTransform val2 = (RectTransform)(object)((val is RectTransform) ? val : null);
			if ((Object)(object)val2 != (Object)null)
			{
				return val2;
			}
		}
		return element.Transform;
	}

	private bool TryGetSelectedScreenRect(out Rect rect)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00be: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c3: 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)
		//IL_0142: 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)
		rect = default(Rect);
		if (elements.Count == 0)
		{
			return false;
		}
		HudElement hudElement = elements[selectedIndex];
		if ((Object)(object)hudElement.Transform == (Object)null || !((Component)hudElement.Transform).gameObject.activeInHierarchy)
		{
			return false;
		}
		RectTransform visualBoundsTransform = GetVisualBoundsTransform(hudElement);
		if ((Object)(object)visualBoundsTransform == (Object)null || !((Component)visualBoundsTransform).gameObject.activeInHierarchy)
		{
			return false;
		}
		try
		{
			Vector3[] array = (Vector3[])(object)new Vector3[4];
			visualBoundsTransform.GetWorldCorners(array);
			Canvas componentInParent = ((Component)visualBoundsTransform).GetComponentInParent<Canvas>();
			Camera val = null;
			if ((Object)(object)componentInParent != (Object)null && (int)componentInParent.renderMode != 0)
			{
				val = componentInParent.worldCamera;
			}
			Vector2 val2 = RectTransformUtility.WorldToScreenPoint(val, array[0]);
			Vector2 val3 = RectTransformUtility.WorldToScreenPoint(val, array[2]);
			float num = Mathf.Min(val2.x, val3.x);
			float num2 = (float)Screen.height - Mathf.Max(val2.y, val3.y);
			float num3 = Mathf.Abs(val3.x - val2.x);
			float num4 = Mathf.Abs(val3.y - val2.y);
			if (num3 < 2f || num4 < 2f)
			{
				return false;
			}
			rect = new Rect(num, num2, num3, num4);
			return true;
		}
		catch
		{
			return false;
		}
	}

	private void DrawEditorWindow(int windowId)
	{
		//IL_0058: 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_002e: 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_0145: Unknown result type (might be due to invalid IL or missing references)
		//IL_014a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0839: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)editorBackgroundTexture != (Object)null)
		{
			GUI.DrawTexture(new Rect(0f, 0f, ((Rect)(ref editorRect)).width, ((Rect)(ref editorRect)).height), (Texture)(object)editorBackgroundTexture);
		}
		GUI.Box(new Rect(0f, 0f, ((Rect)(ref editorRect)).width, 24f), "Pappy HUD Master 1.0.1");
		if (GUI.Button(new Rect(((Rect)(ref editorRect)).width - 23f, 2f, 20f, 20f), "X"))
		{
			GUI.FocusControl((string)null);
			SetEditorOpen(open: false);
			return;
		}
		GUILayout.Space(26f);
		GUILayout.Label("Valheim 1.0 HUD editor", titleStyle, (GUILayoutOption[])(object)new GUILayoutOption[0]);
		GUILayout.Label("F7 closes | X closes | drag the DRAG handle above the selected UI | arrows move | Shift+arrows = 25 | +/- scale | Q/E rotate | R reset", (GUILayoutOption[])(object)new GUILayoutOption[0]);
		GUILayout.Space(6f);
		GUILayout.BeginHorizontal((GUILayoutOption[])(object)new GUILayoutOption[0]);
		GUILayout.BeginVertical((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(255f) });
		GUILayout.Label("UI Elements", (GUILayoutOption[])(object)new GUILayoutOption[0]);
		scroll = GUILayout.BeginScrollView(scroll, (GUILayoutOption[])(object)new GUILayoutOption[2]
		{
			GUILayout.Width(255f),
			GUILayout.Height(690f)
		});
		for (int i = 0; i < elements.Count; i++)
		{
			HudElement hudElement = elements[i];
			string text = (((Object)(object)hudElement.Transform == (Object)null) ? " [waiting]" : ((!((Component)hudElement.Transform).gameObject.activeInHierarchy) ? " [hidden]" : " [ACTIVE]"));
			GUIStyle val = ((i == selectedIndex) ? selectedStyle : normalStyle);
			if (GUILayout.Button(hudElement.Name + text, val, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(28f) }))
			{
				selectedIndex = i;
				draggingSelected = false;
				SyncEditStrings(hudElement);
			}
		}
		GUILayout.EndScrollView();
		GUILayout.EndVertical();
		GUILayout.BeginVertical((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(390f) });
		if (elements.Count > 0)
		{
			HudElement hudElement2 = elements[selectedIndex];
			GUILayout.Label(hudElement2.Name, titleStyle, (GUILayoutOption[])(object)new GUILayoutOption[0]);
			if ((Object)(object)hudElement2.Transform == (Object)null)
			{
				GUILayout.Label("Status: Waiting for this UI object.", (GUILayoutOption[])(object)new GUILayoutOption[0]);
			}
			else if (((Component)hudElement2.Transform).gameObject.activeInHierarchy)
			{
				GUILayout.Label("Status: ACTIVE - drag handle is shown on screen.", (GUILayoutOption[])(object)new GUILayoutOption[0]);
			}
			else
			{
				GUILayout.Label("Status: Loaded, but Valheim currently has it hidden.", (GUILayoutOption[])(object)new GUILayoutOption[0]);
			}
			if (GUILayout.Button("REFRESH / FIND ACTIVE COPY", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(30f) }))
			{
				RefreshSelectedElement();
				SyncEditStrings(hudElement2);
			}
			bool flag = GUILayout.Toggle(hudElement2.Enabled.Value, "Enable position / scale control", (GUILayoutOption[])(object)new GUILayoutOption[0]);
			if (flag != hudElement2.Enabled.Value)
			{
				hudElement2.Enabled.Value = flag;
				((BaseUnityPlugin)this).Config.Save();
			}
			GUILayout.Space(8f);
			GUILayout.Label("Position - type exact values or use buttons", (GUILayoutOption[])(object)new GUILayoutOption[0]);
			DrawConfigFloatField(hudElement2, "X offset", ref hudElement2.EditX, hudElement2.OffsetX, -10000f, 10000f, "x_" + selectedIndex);
			DrawConfigFloatField(hudElement2, "Y offset", ref hudElement2.EditY, hudElement2.OffsetY, -10000f, 10000f, "y_" + selectedIndex);
			GUILayout.BeginHorizontal((GUILayoutOption[])(object)new GUILayoutOption[0]);
			if (GUILayout.Button("Left 25", (GUILayoutOption[])(object)new GUILayoutOption[0]))
			{
				ConfigEntry<float> offsetX = hudElement2.OffsetX;
				offsetX.Value -= 25f;
				SyncEditStrings(hudElement2);
			}
			if (GUILayout.Button("Right 25", (GUILayoutOption[])(object)new GUILayoutOption[0]))
			{
				ConfigEntry<float> offsetX2 = hudElement2.OffsetX;
				offsetX2.Value += 25f;
				SyncEditStrings(hudElement2);
			}
			GUILayout.EndHorizontal();
			GUILayout.BeginHorizontal((GUILayoutOption[])(object)new GUILayoutOption[0]);
			if (GUILayout.Button("Down 25", (GUILayoutOption[])(object)new GUILayoutOption[0]))
			{
				ConfigEntry<float> offsetY = hudElement2.OffsetY;
				offsetY.Value -= 25f;
				SyncEditStrings(hudElement2);
			}
			if (GUILayout.Button("Up 25", (GUILayoutOption[])(object)new GUILayoutOption[0]))
			{
				ConfigEntry<float> offsetY2 = hudElement2.OffsetY;
				offsetY2.Value += 25f;
				SyncEditStrings(hudElement2);
			}
			GUILayout.EndHorizontal();
			GUILayout.Space(8f);
			DrawConfigFloatField(hudElement2, "Scale", ref hudElement2.EditScale, hudElement2.Scale, 0.25f, 4f, "scale_" + selectedIndex);
			GUILayout.BeginHorizontal((GUILayoutOption[])(object)new GUILayoutOption[0]);
			if (GUILayout.Button("- 0.05", (GUILayoutOption[])(object)new GUILayoutOption[0]))
			{
				hudElement2.Scale.Value = Mathf.Clamp(hudElement2.Scale.Value - 0.05f, 0.25f, 4f);
				SyncEditStrings(hudElement2);
			}
			if (GUILayout.Button("+ 0.05", (GUILayoutOption[])(object)new GUILayoutOption[0]))
			{
				hudElement2.Scale.Value = Mathf.Clamp(hudElement2.Scale.Value + 0.05f, 0.25f, 4f);
				SyncEditStrings(hudElement2);
			}
			GUILayout.EndHorizontal();
			GUILayout.Space(8f);
			DrawConfigFloatField(hudElement2, "Rotation", ref hudElement2.EditRotation, hudElement2.Rotation, -3600f, 3600f, "rotation_" + selectedIndex);
			GUILayout.BeginHorizontal((GUILayoutOption[])(object)new GUILayoutOption[0]);
			if (GUILayout.Button("- 5 deg", (GUILayoutOption[])(object)new GUILayoutOption[0]))
			{
				ConfigEntry<float> rotation = hudElement2.Rotation;
				rotation.Value -= 5f;
				SyncEditStrings(hudElement2);
			}
			if (GUILayout.Button("+ 5 deg", (GUILayoutOption[])(object)new GUILayoutOption[0]))
			{
				ConfigEntry<float> rotation2 = hudElement2.Rotation;
				rotation2.Value += 5f;
				SyncEditStrings(hudElement2);
			}
			GUILayout.EndHorizontal();
			if (hudElement2.BackgroundOpacity != null)
			{
				GUILayout.Space(10f);
				GUILayout.Label("Background transparency", (GUILayoutOption[])(object)new GUILayoutOption[0]);
				DrawOpacityField(hudElement2);
				float num = Mathf.Clamp(hudElement2.BackgroundOpacity.Value, 0.05f, 1f);
				float num2 = GUILayout.HorizontalSlider(num, 0.05f, 1f, (GUILayoutOption[])(object)new GUILayoutOption[0]);
				if (Mathf.Abs(num2 - num) > 0.0001f)
				{
					hudElement2.BackgroundOpacity.Value = num2;
					hudElement2.EditOpacityPercent = (num2 * 100f).ToString("0", CultureInfo.InvariantCulture);
				}
				if (hudElement2.UseMinimapCompositeOpacity)
				{
					GUILayout.Label("Experimental map-only transparency: below 100% the native map is rendered through a real offscreen UI canvas, then faded as a normal image. Pins/text remain separate.", (GUILayoutOption[])(object)new GUILayoutOption[0]);
				}
				else if (hudElement2.UseWholeElementOpacity)
				{
					GUILayout.Label("This fades the complete UI element.", (GUILayoutOption[])(object)new GUILayoutOption[0]);
				}
				else
				{
					GUILayout.Label("Only the panel background is faded; text, icons, recipes and buttons stay readable.", (GUILayoutOption[])(object)new GUILayoutOption[0]);
				}
			}
			GUILayout.Space(12f);
			if (GUILayout.Button("RESET THIS ELEMENT", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(35f) }))
			{
				ResetElement(hudElement2);
			}
			if (GUILayout.Button("SAVE CONFIG", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(32f) }))
			{
				((BaseUnityPlugin)this).Config.Save();
			}
			GUILayout.Space(8f);
			GUILayout.Label("Resolved path:", smallStyle, (GUILayoutOption[])(object)new GUILayoutOption[0]);
			if ((Object)(object)hudElement2.Transform != (Object)null)
			{
				GUILayout.TextArea(GetTransformPath((Transform)(object)hudElement2.Transform), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(55f) });
			}
			else
			{
				GUILayout.TextArea(hudElement2.PathSuffix, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(55f) });
			}
		}
		GUILayout.EndVertical();
		GUILayout.EndHorizontal();
		GUI.DragWindow(new Rect(0f, 0f, ((Rect)(ref editorRect)).width - 26f, 24f));
	}

	private void DrawConfigFloatField(HudElement element, string label, ref string editText, ConfigEntry<float> config, float min, float max, string controlName)
	{
		GUILayout.BeginHorizontal((GUILayoutOption[])(object)new GUILayoutOption[0]);
		GUILayout.Label(label, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(110f) });
		GUI.SetNextControlName(controlName);
		string text = GUILayout.TextField(editText, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(115f) });
		if (GUI.GetNameOfFocusedControl() == controlName)
		{
			textFieldFocused = true;
		}
		if (text != editText)
		{
			editText = text;
			if (TryParseFloat(editText, out var value))
			{
				config.Value = Mathf.Clamp(value, min, max);
			}
		}
		GUILayout.Label("current: " + config.Value.ToString("0.###", CultureInfo.InvariantCulture), (GUILayoutOption[])(object)new GUILayoutOption[0]);
		GUILayout.EndHorizontal();
	}

	private void DrawOpacityField(HudElement element)
	{
		GUILayout.BeginHorizontal((GUILayoutOption[])(object)new GUILayoutOption[0]);
		GUILayout.Label("Opacity %", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(110f) });
		string text = "opacity_" + selectedIndex;
		GUI.SetNextControlName(text);
		string text2 = GUILayout.TextField(element.EditOpacityPercent, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(115f) });
		if (GUI.GetNameOfFocusedControl() == text)
		{
			textFieldFocused = true;
		}
		if (text2 != element.EditOpacityPercent)
		{
			element.EditOpacityPercent = text2;
			if (TryParseFloat(text2, out var value))
			{
				value = Mathf.Clamp(value, 5f, 100f);
				element.BackgroundOpacity.Value = value / 100f;
			}
		}
		GUILayout.Label("current: " + (element.BackgroundOpacity.Value * 100f).ToString("0", CultureInfo.InvariantCulture) + "%", (GUILayoutOption[])(object)new GUILayoutOption[0]);
		GUILayout.EndHorizontal();
	}

	private static bool TryParseFloat(string text, out float value)
	{
		if (float.TryParse(text, NumberStyles.Float, CultureInfo.InvariantCulture, out value))
		{
			return true;
		}
		return float.TryParse(text, NumberStyles.Float, CultureInfo.CurrentCulture, out value);
	}

	private void ResetElement(HudElement e)
	{
		e.OffsetX.Value = 0f;
		e.OffsetY.Value = 0f;
		e.Scale.Value = 1f;
		e.Rotation.Value = 0f;
		e.Enabled.Value = e.DefaultEnabled;
		if (e.BackgroundOpacity != null)
		{
			e.BackgroundOpacity.Value = 1f;
		}
		SyncEditStrings(e);
		((BaseUnityPlugin)this).Config.Save();
	}

	private static void SyncEditStrings(HudElement e)
	{
		e.EditX = e.OffsetX.Value.ToString("0.###", CultureInfo.InvariantCulture);
		e.EditY = e.OffsetY.Value.ToString("0.###", CultureInfo.InvariantCulture);
		e.EditScale = e.Scale.Value.ToString("0.###", CultureInfo.InvariantCulture);
		e.EditRotation = e.Rotation.Value.ToString("0.###", CultureInfo.InvariantCulture);
		if (e.BackgroundOpacity != null)
		{
			e.EditOpacityPercent = (e.BackgroundOpacity.Value * 100f).ToString("0", CultureInfo.InvariantCulture);
		}
	}

	private void DrawOutline(Rect rect, float thickness)
	{
		//IL_004e: 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)
		//IL_009c: 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_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Expected O, but got Unknown
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)outlineTexture == (Object)null)
		{
			outlineTexture = new Texture2D(1, 1);
			outlineTexture.SetPixel(0, 0, Color.white);
			outlineTexture.Apply();
		}
		GUI.DrawTexture(new Rect(((Rect)(ref rect)).x, ((Rect)(ref rect)).y, ((Rect)(ref rect)).width, thickness), (Texture)(object)outlineTexture);
		GUI.DrawTexture(new Rect(((Rect)(ref rect)).x, ((Rect)(ref rect)).yMax - thickness, ((Rect)(ref rect)).width, thickness), (Texture)(object)outlineTexture);
		GUI.DrawTexture(new Rect(((Rect)(ref rect)).x, ((Rect)(ref rect)).y, thickness, ((Rect)(ref rect)).height), (Texture)(object)outlineTexture);
		GUI.DrawTexture(new Rect(((Rect)(ref rect)).xMax - thickness, ((Rect)(ref rect)).y, thickness, ((Rect)(ref rect)).height), (Texture)(object)outlineTexture);
	}

	private void EnsureStyles()
	{
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0016: Expected O, but got Unknown
		//IL_0032: 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_005c: Expected O, but got Unknown
		//IL_008c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0096: Expected O, but got Unknown
		//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b7: Expected O, but got Unknown
		//IL_00da: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e4: Expected O, but got Unknown
		if (titleStyle == null)
		{
			editorBackgroundTexture = new Texture2D(1, 1);
			editorBackgroundTexture.SetPixel(0, 0, new Color(0.035f, 0.035f, 0.035f, 0.9f));
			editorBackgroundTexture.Apply();
			titleStyle = new GUIStyle(GUI.skin.label);
			titleStyle.fontSize = 15;
			titleStyle.fontStyle = (FontStyle)1;
			titleStyle.wordWrap = true;
			normalStyle = new GUIStyle(GUI.skin.button);
			normalStyle.alignment = (TextAnchor)3;
			selectedStyle = new GUIStyle(GUI.skin.button);
			selectedStyle.alignment = (TextAnchor)3;
			selectedStyle.fontStyle = (FontStyle)1;
			smallStyle = new GUIStyle(GUI.skin.box);
			smallStyle.fontSize = 11;
			smallStyle.alignment = (TextAnchor)4;
		}
	}

	private static bool ShouldBlockGameInput()
	{
		if ((Object)(object)Instance != (Object)null)
		{
			return Instance.editorOpen;
		}
		return false;
	}

	private static string GetTransformPath(Transform t)
	{
		if ((Object)(object)t == (Object)null)
		{
			return "<null>";
		}
		List<string> list = new List<string>();
		Transform val = t;
		while ((Object)(object)val != (Object)null)
		{
			list.Add(((Object)val).name);
			val = val.parent;
		}
		list.Reverse();
		return string.Join("/", list.ToArray());
	}
}