Decompiled source of SunnfjordheimGalaxyHUD v1.0.0

BalrondGalaxyHUD.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BalrondGalaxyHUD.Compatibility;
using BalrondGalaxyHUD.Config;
using BalrondGalaxyHUD.Data;
using BalrondGalaxyHUD.Runtime;
using BalrondGalaxyHUD.UI;
using BalrondItemRarity;
using BalrondItemRarity.VFX;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.U2D;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: InternalsVisibleTo("BalrondGalaxyHUD.Tests")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("BalrondGalaxyHUD")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("0.2.3.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("BalrondGalaxyHUD")]
[assembly: AssemblyTitle("BalrondGalaxyHUD")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.2.3.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace BalrondGalaxyHUD
{
	internal static class Constants
	{
		public const string ModGuid = "Balrond.BalrondGalaxyHUD";

		public const string ModName = "Balrond Galaxy HUD";

		public const string ModVersion = "0.2.3";

		public const string DefaultBundleName = "balrondgalaxyhud";

		public const string EmbeddedBundleResourceName = "BalrondGalaxyHUD.balrondgalaxyhud";
	}
	[BepInPlugin("Balrond.BalrondGalaxyHUD", "Balrond Galaxy HUD", "0.2.3")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class BalrondGalaxyHUDPlugin : BaseUnityPlugin
	{
		private float _nextProgressError;

		private PatchInstaller _patches;

		private Coroutine _scheduler;

		internal static ManualLogSource Log { get; private set; }

		internal static GalaxyHudConfig Settings { get; private set; }

		internal static ConfigFile SettingsFile { get; private set; }

		internal static GalaxyHudRuntime Runtime { get; private set; }

		internal static PlayerProgressService Progress { get; private set; }

		private void Awake()
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Invalid comparison between Unknown and I4
			Log = ((BaseUnityPlugin)this).Logger;
			((BaseUnityPlugin)this).Logger.LogInfo((object)"[BGH] Bootstrap started: Balrond Galaxy HUD 0.2.3.");
			SettingsFile = ((BaseUnityPlugin)this).Config;
			((BaseUnityPlugin)this).Config.SaveOnConfigSet = false;
			Settings = new GalaxyHudConfig(((BaseUnityPlugin)this).Config);
			if ((int)SystemInfo.graphicsDeviceType != 4)
			{
				BalrondItemRarityCompat.Initialize(((BaseUnityPlugin)this).Logger);
				Progress = new PlayerProgressService(((BaseUnityPlugin)this).Logger);
				string text = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location) ?? Paths.PluginPath;
				Runtime = new GalaxyHudRuntime(Settings, ((BaseUnityPlugin)this).Logger, text);
				((BaseUnityPlugin)this).Config.SettingChanged += OnSettingChanged;
				((BaseUnityPlugin)this).Logger.LogInfo((object)("[BGH] Runtime created. Mod directory: " + text));
				_patches = new PatchInstaller("Balrond.BalrondGalaxyHUD", ((BaseUnityPlugin)this).Logger);
				try
				{
					_patches.Install();
				}
				catch (Exception arg)
				{
					((BaseUnityPlugin)this).Logger.LogError((object)$"[BGH] Harmony installation had an unexpected fatal error; continuing with scheduler fallback. {arg}");
				}
				_scheduler = ((MonoBehaviour)this).StartCoroutine(SchedulerLoop());
				((BaseUnityPlugin)this).Logger.LogInfo((object)"[BGH] Scheduler started.");
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Balrond Galaxy HUD 0.2.3 loaded (publicized direct API, AssetBundle prefab runtime, adaptive scheduler).");
			}
		}

		private IEnumerator SchedulerLoop()
		{
			WaitForSecondsRealtime wait = new WaitForSecondsRealtime(0.1f);
			while (true)
			{
				if (!((Behaviour)this).isActiveAndEnabled)
				{
					wait.waitTime = 0.2f;
					yield return wait;
					continue;
				}
				try
				{
					Progress?.Tick();
				}
				catch (Exception ex)
				{
					Exception ex2 = ex;
					if (Time.unscaledTime >= _nextProgressError)
					{
						_nextProgressError = Time.unscaledTime + 5f;
						((BaseUnityPlugin)this).Logger.LogError((object)("[BGH] Progress publication failed; will retry. " + ex2));
					}
				}
				GalaxyHudRuntime runtime = Runtime;
				if (runtime != null)
				{
					try
					{
						runtime.Tick();
					}
					catch (Exception ex3)
					{
						((BaseUnityPlugin)this).Logger.LogError((object)("[BGH] HUD update failed; restoring vanilla and disabling GalaxyHUD. " + ex3));
						runtime.SuspendAfterFailure();
					}
					wait.waitTime = runtime.GetRecommendedSchedulerDelay();
				}
				else
				{
					wait.waitTime = 0.25f;
				}
				yield return wait;
			}
		}

		private void OnSettingChanged(object sender, SettingChangedEventArgs args)
		{
			if (args.ChangedSetting.Definition.Section == "VanillaHUD")
			{
				Runtime?.ConfigurationChanged();
			}
		}

		private void OnEnable()
		{
			Runtime?.SetComponentEnabled(enabled: true);
		}

		private void OnDisable()
		{
			Runtime?.SetComponentEnabled(enabled: false);
			Progress?.Dispose();
		}

		private void OnDestroy()
		{
			if (_scheduler != null)
			{
				((MonoBehaviour)this).StopCoroutine(_scheduler);
				_scheduler = null;
			}
			((BaseUnityPlugin)this).Config.SettingChanged -= OnSettingChanged;
			HudLayoutEditor.Current?.Close();
			try
			{
				((BaseUnityPlugin)this).Config.Save();
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)ex.Message);
			}
			_patches?.Uninstall();
			_patches = null;
			Runtime?.Dispose();
			Runtime = null;
			Progress?.Dispose();
			Progress = null;
		}
	}
}
namespace BalrondGalaxyHUD.UI
{
	internal sealed class AssetBundleLoader : IDisposable
	{
		private readonly GalaxyHudConfig _config;

		private readonly ManualLogSource _log;

		private readonly string _modDirectory;

		private AssetBundle _bundle;

		private string _loadedPath;

		private SpriteAtlas[] _atlases;

		private bool _loadAttempted;

		public AssetBundle Bundle => _bundle;

		public string LoadedPath => _loadedPath;

		public AssetBundleLoader(GalaxyHudConfig config, ManualLogSource log, string modDirectory)
		{
			_config = config;
			_log = log;
			_modDirectory = modDirectory ?? string.Empty;
		}

		public bool EnsureLoaded()
		{
			if ((Object)(object)_bundle != (Object)null)
			{
				return true;
			}
			if (_loadAttempted)
			{
				return false;
			}
			_loadAttempted = true;
			string path = (_config.BundleFileName.Value ?? string.Empty).Trim();
			bool flag = _config.EnableBundleHotReload.Value || Path.IsPathRooted(path);
			string text = ResolveExistingBundlePath();
			if (flag && !string.IsNullOrEmpty(text))
			{
				if (TryLoadFromFile(text))
				{
					return true;
				}
				_log.LogWarning((object)"[BGH] External UI AssetBundle override failed; trying embedded bundle.");
			}
			if (TryLoadEmbedded())
			{
				return true;
			}
			if (!flag && !string.IsNullOrEmpty(text) && TryLoadFromFile(text))
			{
				return true;
			}
			string text2 = ResolveExpectedExternalPath();
			_log.LogError((object)("[BGH] UI AssetBundle could not be loaded. Embedded resource 'BalrondGalaxyHUD.balrondgalaxyhud' was unavailable/invalid and no usable external fallback was found (expected '" + text2 + "')."));
			return false;
		}

		private bool TryLoadEmbedded()
		{
			Assembly assembly = typeof(AssetBundleLoader).Assembly;
			string text = FindEmbeddedResourceName(assembly);
			if (string.IsNullOrEmpty(text))
			{
				string[] manifestResourceNames = assembly.GetManifestResourceNames();
				_log.LogError((object)("[BGH] Embedded UI AssetBundle resource not found. Expected 'BalrondGalaxyHUD.balrondgalaxyhud'. " + $"Manifest resource count={manifestResourceNames.Length}."));
				return false;
			}
			try
			{
				using Stream stream = assembly.GetManifestResourceStream(text);
				if (stream == null)
				{
					_log.LogError((object)("[BGH] GetManifestResourceStream returned null for '" + text + "'."));
					return false;
				}
				if (stream.Length <= 0 || stream.Length > int.MaxValue)
				{
					_log.LogError((object)$"[BGH] Embedded UI AssetBundle has invalid size: {stream.Length} bytes.");
					return false;
				}
				byte[] array = new byte[(int)stream.Length];
				int i;
				int num;
				for (i = 0; i < array.Length; i += num)
				{
					num = stream.Read(array, i, array.Length - i);
					if (num <= 0)
					{
						break;
					}
				}
				if (i != array.Length)
				{
					_log.LogError((object)$"[BGH] Embedded UI AssetBundle read was incomplete: {i}/{array.Length} bytes.");
					return false;
				}
				_bundle = AssetBundle.LoadFromMemory(array);
				if ((Object)(object)_bundle == (Object)null)
				{
					_log.LogError((object)("[BGH] AssetBundle.LoadFromMemory failed for embedded resource '" + text + "'. The bundle may need to be rebuilt with the Unity version used by the current Valheim build."));
					return false;
				}
				_loadedPath = "embedded://" + text;
				FinishLoad();
				_log.LogInfo((object)$"[BGH] Loaded embedded UI AssetBundle: {text} ({array.Length} bytes).");
				return true;
			}
			catch (Exception arg)
			{
				_log.LogError((object)$"[BGH] Exception while loading embedded UI AssetBundle '{text}': {arg}");
				_bundle = null;
				_loadedPath = null;
				return false;
			}
		}

		private string FindEmbeddedResourceName(Assembly assembly)
		{
			string[] manifestResourceNames = assembly.GetManifestResourceNames();
			for (int i = 0; i < manifestResourceNames.Length; i++)
			{
				if (string.Equals(manifestResourceNames[i], "BalrondGalaxyHUD.balrondgalaxyhud", StringComparison.Ordinal))
				{
					return manifestResourceNames[i];
				}
			}
			string text = Path.GetFileName((_config.BundleFileName.Value ?? "balrondgalaxyhud").Trim());
			if (string.IsNullOrEmpty(text))
			{
				text = "balrondgalaxyhud";
			}
			string value = "." + text;
			for (int j = 0; j < manifestResourceNames.Length; j++)
			{
				if (string.Equals(manifestResourceNames[j], text, StringComparison.OrdinalIgnoreCase) || manifestResourceNames[j].EndsWith(value, StringComparison.OrdinalIgnoreCase))
				{
					return manifestResourceNames[j];
				}
			}
			return null;
		}

		private bool TryLoadFromFile(string path)
		{
			try
			{
				_bundle = AssetBundle.LoadFromFile(path);
				if ((Object)(object)_bundle == (Object)null)
				{
					_log.LogError((object)("[BGH] AssetBundle.LoadFromFile failed: " + path));
					return false;
				}
				_loadedPath = path;
				FinishLoad();
				_log.LogInfo((object)("[BGH] Loaded external UI AssetBundle: " + path));
				return true;
			}
			catch (Exception arg)
			{
				_log.LogError((object)$"[BGH] Exception while loading external UI AssetBundle '{path}': {arg}");
				_bundle = null;
				_loadedPath = null;
				return false;
			}
		}

		private void FinishLoad()
		{
			_log.LogInfo((object)("[BGH] Bundle assets: " + string.Join(", ", _bundle.GetAllAssetNames())));
			_atlases = _bundle.LoadAllAssets<SpriteAtlas>();
			SpriteAtlasManager.atlasRequested -= OnAtlasRequested;
			SpriteAtlasManager.atlasRequested += OnAtlasRequested;
		}

		private void OnAtlasRequested(string tag, Action<SpriteAtlas> register)
		{
			if (_atlases == null)
			{
				return;
			}
			for (int i = 0; i < _atlases.Length; i++)
			{
				if ((Object)(object)_atlases[i] != (Object)null && _atlases[i].tag == tag)
				{
					register(_atlases[i]);
					break;
				}
			}
		}

		public void Reload()
		{
			Dispose();
			_loadAttempted = false;
			EnsureLoaded();
		}

		private string ResolveExistingBundlePath()
		{
			string text = (_config.BundleFileName.Value ?? string.Empty).Trim();
			if (string.IsNullOrEmpty(text))
			{
				text = "balrondgalaxyhud";
			}
			if (Path.IsPathRooted(text))
			{
				return File.Exists(text) ? text : null;
			}
			string[] array = new string[4]
			{
				Path.Combine(_modDirectory, text),
				Path.Combine(_modDirectory, "Bundles", text),
				Path.Combine(_modDirectory, "Bundle", text),
				Path.Combine(_modDirectory, "BalrondGalaxyHUD", text)
			};
			for (int i = 0; i < array.Length; i++)
			{
				if (File.Exists(array[i]))
				{
					return array[i];
				}
			}
			return null;
		}

		private string ResolveExpectedExternalPath()
		{
			string text = (_config.BundleFileName.Value ?? string.Empty).Trim();
			if (string.IsNullOrEmpty(text))
			{
				text = "balrondgalaxyhud";
			}
			if (Path.IsPathRooted(text))
			{
				return text;
			}
			return Path.Combine(_modDirectory, text);
		}

		public void Dispose()
		{
			SpriteAtlasManager.atlasRequested -= OnAtlasRequested;
			_atlases = null;
			if ((Object)(object)_bundle != (Object)null)
			{
				_bundle.Unload(false);
				_bundle = null;
			}
			_loadedPath = null;
			_loadAttempted = false;
		}
	}
	internal static class BindingPaths
	{
		internal static string Revised(string path)
		{
			return path.Replace("Binding/Slots", "Binding/Hotbar/Slots").Replace("Binding/Context", "Binding/Hotbar/Context");
		}

		internal static Transform Find(Transform root, string path)
		{
			if ((Object)(object)root == (Object)null)
			{
				return null;
			}
			Transform val = root.Find(path);
			if ((Object)(object)val != (Object)null)
			{
				return val;
			}
			if (path.Contains("Binding/Context"))
			{
				Transform val2 = root.Find(path.Replace("Binding/Context", "Binding/Slots/Context"));
				if ((Object)(object)val2 != (Object)null)
				{
					return val2;
				}
			}
			string text = Revised(path);
			return (text != path) ? root.Find(text) : null;
		}
	}
	internal static class BindingValidation
	{
		internal static bool ValidateCatalog(Dictionary<string, GameObject> prefabs, ManualLogSource log)
		{
			bool flag = true;
			flag &= Check<Image>(prefabs, "BGH_Resources", "Binding/Health/Fill", log);
			flag &= Check<TMP_Text>(prefabs, "BGH_Resources", "Binding/Health/Value", log);
			flag &= Check<Image>(prefabs, "BGH_Resources", "Binding/Stamina/Fill", log);
			flag &= Check<TMP_Text>(prefabs, "BGH_Resources", "Binding/Stamina/Value", log);
			flag &= Check<Image>(prefabs, "BGH_Resources", "Binding/Eitr/Fill", log);
			flag &= Check<TMP_Text>(prefabs, "BGH_Resources", "Binding/Eitr/Value", log);
			flag &= Check<Image>(prefabs, "BGH_Resources", "Binding/Adrenaline/Fill", log);
			flag &= Check<TMP_Text>(prefabs, "BGH_Resources", "Binding/Adrenaline/Value", log);
			flag &= Check<RectTransform>(prefabs, "BGH_Hotbar", "Binding/Slots", log);
			flag &= Check<RectTransform>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot1", log);
			flag &= Check<Image>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot1/RarityGlow", log);
			flag &= Check<Image>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot1/Selected", log);
			flag &= Check<Image>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot1/Icon", log);
			flag &= Check<RectTransform>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot1/Panels/Quantity", log);
			flag &= Check<RectTransform>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot1/Panels/Durability", log);
			flag &= Check<TMP_Text>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot1/Panels/Quantity/Count", log);
			flag &= Check<Image>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot1/Panels/Durability/DurabilityBack", log);
			flag &= Check<Image>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot1/Panels/Durability/DurabilityFill", log);
			flag &= Check<RectTransform>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot2", log);
			flag &= Check<Image>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot2/RarityGlow", log);
			flag &= Check<Image>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot2/Selected", log);
			flag &= Check<Image>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot2/Icon", log);
			flag &= Check<RectTransform>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot2/Panels/Quantity", log);
			flag &= Check<RectTransform>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot2/Panels/Durability", log);
			flag &= Check<TMP_Text>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot2/Panels/Quantity/Count", log);
			flag &= Check<Image>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot2/Panels/Durability/DurabilityBack", log);
			flag &= Check<Image>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot2/Panels/Durability/DurabilityFill", log);
			flag &= Check<RectTransform>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot3", log);
			flag &= Check<Image>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot3/RarityGlow", log);
			flag &= Check<Image>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot3/Selected", log);
			flag &= Check<Image>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot3/Icon", log);
			flag &= Check<RectTransform>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot3/Panels/Quantity", log);
			flag &= Check<RectTransform>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot3/Panels/Durability", log);
			flag &= Check<TMP_Text>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot3/Panels/Quantity/Count", log);
			flag &= Check<Image>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot3/Panels/Durability/DurabilityBack", log);
			flag &= Check<Image>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot3/Panels/Durability/DurabilityFill", log);
			flag &= Check<RectTransform>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot4", log);
			flag &= Check<Image>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot4/RarityGlow", log);
			flag &= Check<Image>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot4/Selected", log);
			flag &= Check<Image>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot4/Icon", log);
			flag &= Check<RectTransform>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot4/Panels/Quantity", log);
			flag &= Check<RectTransform>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot4/Panels/Durability", log);
			flag &= Check<TMP_Text>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot4/Panels/Quantity/Count", log);
			flag &= Check<Image>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot4/Panels/Durability/DurabilityBack", log);
			flag &= Check<Image>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot4/Panels/Durability/DurabilityFill", log);
			flag &= Check<RectTransform>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot5", log);
			flag &= Check<Image>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot5/RarityGlow", log);
			flag &= Check<Image>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot5/Selected", log);
			flag &= Check<Image>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot5/Icon", log);
			flag &= Check<RectTransform>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot5/Panels/Quantity", log);
			flag &= Check<RectTransform>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot5/Panels/Durability", log);
			flag &= Check<TMP_Text>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot5/Panels/Quantity/Count", log);
			flag &= Check<Image>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot5/Panels/Durability/DurabilityBack", log);
			flag &= Check<Image>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot5/Panels/Durability/DurabilityFill", log);
			flag &= Check<RectTransform>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot6", log);
			flag &= Check<Image>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot6/RarityGlow", log);
			flag &= Check<Image>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot6/Selected", log);
			flag &= Check<Image>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot6/Icon", log);
			flag &= Check<RectTransform>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot6/Panels/Quantity", log);
			flag &= Check<RectTransform>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot6/Panels/Durability", log);
			flag &= Check<TMP_Text>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot6/Panels/Quantity/Count", log);
			flag &= Check<Image>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot6/Panels/Durability/DurabilityBack", log);
			flag &= Check<Image>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot6/Panels/Durability/DurabilityFill", log);
			flag &= Check<RectTransform>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot7", log);
			flag &= Check<Image>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot7/RarityGlow", log);
			flag &= Check<Image>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot7/Selected", log);
			flag &= Check<Image>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot7/Icon", log);
			flag &= Check<RectTransform>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot7/Panels/Quantity", log);
			flag &= Check<RectTransform>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot7/Panels/Durability", log);
			flag &= Check<TMP_Text>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot7/Panels/Quantity/Count", log);
			flag &= Check<Image>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot7/Panels/Durability/DurabilityBack", log);
			flag &= Check<Image>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot7/Panels/Durability/DurabilityFill", log);
			flag &= Check<RectTransform>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot8", log);
			flag &= Check<Image>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot8/RarityGlow", log);
			flag &= Check<Image>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot8/Selected", log);
			flag &= Check<Image>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot8/Icon", log);
			flag &= Check<RectTransform>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot8/Panels/Quantity", log);
			flag &= Check<RectTransform>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot8/Panels/Durability", log);
			flag &= Check<TMP_Text>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot8/Panels/Quantity/Count", log);
			flag &= Check<Image>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot8/Panels/Durability/DurabilityBack", log);
			flag &= Check<Image>(prefabs, "BGH_Hotbar", "Binding/Slots/Slot8/Panels/Durability/DurabilityFill", log);
			flag &= Check<RectTransform>(prefabs, "BGH_Hotbar", "Binding/ForsakenPower", log);
			flag &= Check<Image>(prefabs, "BGH_Hotbar", "Binding/ForsakenPower/Icon", log);
			flag &= Check<Image>(prefabs, "BGH_Hotbar", "Binding/ForsakenPower/CooldownMask", log);
			flag &= Check<TMP_Text>(prefabs, "BGH_Hotbar", "Binding/ForsakenPower/CooldownText", log);
			flag &= Check<RectTransform>(prefabs, "BGH_Hotbar", "Binding/Context", log);
			flag &= Check<Image>(prefabs, "BGH_Hotbar", "Binding/Context/RarityGlow", log);
			flag &= Check<Image>(prefabs, "BGH_Hotbar", "Binding/Context/Icon", log);
			flag &= Check<RectTransform>(prefabs, "BGH_FoodCarry", "Binding/Food", log);
			flag &= Check<RectTransform>(prefabs, "BGH_FoodCarry", "Binding/Carry", log);
			flag &= Check<Image>(prefabs, "BGH_FoodCarry", "Binding/Food/Slot1/Icon", log);
			flag &= Check<TMP_Text>(prefabs, "BGH_FoodCarry", "Binding/Food/Slot1/Timer", log);
			flag &= Check<Image>(prefabs, "BGH_FoodCarry", "Binding/Food/Slot2/Icon", log);
			flag &= Check<TMP_Text>(prefabs, "BGH_FoodCarry", "Binding/Food/Slot2/Timer", log);
			flag &= Check<Image>(prefabs, "BGH_FoodCarry", "Binding/Food/Slot3/Icon", log);
			flag &= Check<TMP_Text>(prefabs, "BGH_FoodCarry", "Binding/Food/Slot3/Timer", log);
			flag &= Check<TMP_Text>(prefabs, "BGH_FoodCarry", "Binding/Carry/Weight", log);
			flag &= Check<TMP_Text>(prefabs, "BGH_FoodCarry", "Binding/Carry/Slots", log);
			flag &= Check<Image>(prefabs, "BGH_XP", "Binding/Fill", log);
			flag &= Check<TMP_Text>(prefabs, "BGH_XP", "Binding/Level", log);
			flag &= Check<TMP_Text>(prefabs, "BGH_XP", "Binding/Progress", log);
			flag &= Check<RectTransform>(prefabs, "BGH_MinimapOverlay", "Binding/MapFrame", log);
			flag &= Check<RectTransform>(prefabs, "BGH_MinimapOverlay", "Binding/InfoFrame", log);
			flag &= Check<RectTransform>(prefabs, "BGH_MinimapOverlay", "Binding/MapFrame/MapViewport", log);
			flag &= Check<TMP_Text>(prefabs, "BGH_MinimapOverlay", "Binding/InfoFrame/Biome", log);
			flag &= Check<TMP_Text>(prefabs, "BGH_MinimapOverlay", "Binding/InfoFrame/Coordinates", log);
			flag &= Check<TMP_Text>(prefabs, "BGH_MinimapOverlay", "Binding/InfoFrame/WorldTime", log);
			flag &= Check<Image>(prefabs, "BGH_MinimapOverlay", "Binding/InfoFrame/WindIcon", log);
			flag &= Check<RectTransform>(prefabs, "BGH_StatusEffects", "Binding/Content", log);
			flag &= Check<Image>(prefabs, "BGH_StatusEffectEntry", "Binding/Icon", log);
			flag &= Check<TMP_Text>(prefabs, "BGH_StatusEffectEntry", "Binding/Name", log);
			flag &= Check<TMP_Text>(prefabs, "BGH_StatusEffectEntry", "Binding/Timer", log);
			flag &= Check<Image>(prefabs, "BGH_BossHud", "Binding/HealthFill", log);
			flag &= Check<TMP_Text>(prefabs, "BGH_BossHud", "Binding/Name", log);
			flag &= Check<TMP_Text>(prefabs, "BGH_BossHud", "Binding/HealthValue", log);
			flag &= Check<RectTransform>(prefabs, "BGH_BossHud", "Binding/LevelBadge", log);
			flag &= Check<TMP_Text>(prefabs, "BGH_BossHud", "Binding/LevelBadge/Level", log);
			flag &= Check<Image>(prefabs, "BGH_EnemyHud", "Binding/HealthFill", log);
			flag &= Check<TMP_Text>(prefabs, "BGH_EnemyHud", "Binding/Name", log);
			flag &= Check<TMP_Text>(prefabs, "BGH_EnemyHud", "Binding/HealthValue", log);
			flag &= Check<RectTransform>(prefabs, "BGH_EnemyHud", "Binding/LevelBadge", log);
			flag &= Check<TMP_Text>(prefabs, "BGH_EnemyHud", "Binding/LevelBadge/Level", log);
			if (prefabs.TryGetValue("BGH_EnemyHud", out var value))
			{
				WarnIncompleteOptionalPathPanels(value, log);
				WarnOptionalRelationshipOrbs(value, log);
			}
			if (prefabs.TryGetValue("BGH_PlayerHud", out var value2))
			{
				WarnIncompleteOptionalPathPanels(value2, log);
				WarnOptionalRelationshipOrbs(value2, log);
			}
			if (!prefabs.TryGetValue("BGH_Root", out var value3) || (Object)(object)value3.GetComponent<Canvas>() == (Object)null || (Object)(object)value3.GetComponent<CanvasScaler>() == (Object)null)
			{
				log.LogError((object)"BGH_Root must contain Canvas and CanvasScaler.");
				flag = false;
			}
			else
			{
				if ((Object)(object)BindingPaths.Find(value3.transform, "BGH_Resources") == (Object)null)
				{
					log.LogError((object)"BGH_Root missing BGH_Resources");
					flag = false;
				}
				if ((Object)(object)BindingPaths.Find(value3.transform, "BGH_Hotbar") == (Object)null)
				{
					log.LogError((object)"BGH_Root missing BGH_Hotbar");
					flag = false;
				}
				if ((Object)(object)BindingPaths.Find(value3.transform, "BGH_FoodCarry") == (Object)null)
				{
					log.LogError((object)"BGH_Root missing BGH_FoodCarry");
					flag = false;
				}
				if ((Object)(object)BindingPaths.Find(value3.transform, "BGH_XP") == (Object)null)
				{
					log.LogError((object)"BGH_Root missing BGH_XP");
					flag = false;
				}
				if ((Object)(object)BindingPaths.Find(value3.transform, "BGH_MinimapOverlay") == (Object)null)
				{
					log.LogError((object)"BGH_Root missing BGH_MinimapOverlay");
					flag = false;
				}
				if ((Object)(object)BindingPaths.Find(value3.transform, "BGH_StatusEffects") == (Object)null)
				{
					log.LogError((object)"BGH_Root missing BGH_StatusEffects");
					flag = false;
				}
			}
			return flag;
		}

		internal static bool ValidateInstance(GameObject root, ManualLogSource log)
		{
			bool flag = (Object)(object)root != (Object)null && (Object)(object)root.GetComponent<Canvas>() != (Object)null && (Object)(object)root.GetComponent<CanvasScaler>() != (Object)null;
			if (!flag)
			{
				log.LogError((object)"Instantiated BGH_Root lacks Canvas/CanvasScaler.");
				return false;
			}
			if (!Valid<Image>(BindingPaths.Find(root.transform, "BGH_Resources/Binding/Health/Fill"), "Binding/Health/Fill"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Resources/Binding/Health/Fill");
				flag = false;
			}
			if (!Valid<TMP_Text>(BindingPaths.Find(root.transform, "BGH_Resources/Binding/Health/Value"), "Binding/Health/Value"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Resources/Binding/Health/Value");
				flag = false;
			}
			if (!Valid<Image>(BindingPaths.Find(root.transform, "BGH_Resources/Binding/Stamina/Fill"), "Binding/Stamina/Fill"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Resources/Binding/Stamina/Fill");
				flag = false;
			}
			if (!Valid<TMP_Text>(BindingPaths.Find(root.transform, "BGH_Resources/Binding/Stamina/Value"), "Binding/Stamina/Value"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Resources/Binding/Stamina/Value");
				flag = false;
			}
			if (!Valid<Image>(BindingPaths.Find(root.transform, "BGH_Resources/Binding/Eitr/Fill"), "Binding/Eitr/Fill"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Resources/Binding/Eitr/Fill");
				flag = false;
			}
			if (!Valid<TMP_Text>(BindingPaths.Find(root.transform, "BGH_Resources/Binding/Eitr/Value"), "Binding/Eitr/Value"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Resources/Binding/Eitr/Value");
				flag = false;
			}
			if (!Valid<Image>(BindingPaths.Find(root.transform, "BGH_Resources/Binding/Adrenaline/Fill"), "Binding/Adrenaline/Fill"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Resources/Binding/Adrenaline/Fill");
				flag = false;
			}
			if (!Valid<TMP_Text>(BindingPaths.Find(root.transform, "BGH_Resources/Binding/Adrenaline/Value"), "Binding/Adrenaline/Value"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Resources/Binding/Adrenaline/Value");
				flag = false;
			}
			if (!Valid<RectTransform>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots"), "Binding/Slots"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots");
				flag = false;
			}
			if (!Valid<RectTransform>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot1"), "Binding/Slots/Slot1"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot1");
				flag = false;
			}
			if (!Valid<Image>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot1/RarityGlow"), "Binding/Slots/Slot1/RarityGlow"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot1/RarityGlow");
				flag = false;
			}
			if (!Valid<Image>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot1/Selected"), "Binding/Slots/Slot1/Selected"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot1/Selected");
				flag = false;
			}
			if (!Valid<Image>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot1/Icon"), "Binding/Slots/Slot1/Icon"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot1/Icon");
				flag = false;
			}
			if (!Valid<RectTransform>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot1/Panels/Quantity"), "Binding/Slots/Slot1/Panels/Quantity"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot1/Panels/Quantity");
				flag = false;
			}
			if (!Valid<RectTransform>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot1/Panels/Durability"), "Binding/Slots/Slot1/Panels/Durability"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot1/Panels/Durability");
				flag = false;
			}
			if (!Valid<TMP_Text>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot1/Panels/Quantity/Count"), "Binding/Slots/Slot1/Panels/Quantity/Count"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot1/Panels/Quantity/Count");
				flag = false;
			}
			if (!Valid<Image>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot1/Panels/Durability/DurabilityBack"), "Binding/Slots/Slot1/Panels/Durability/DurabilityBack"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot1/Panels/Durability/DurabilityBack");
				flag = false;
			}
			if (!Valid<Image>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot1/Panels/Durability/DurabilityFill"), "Binding/Slots/Slot1/Panels/Durability/DurabilityFill"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot1/Panels/Durability/DurabilityFill");
				flag = false;
			}
			if (!Valid<RectTransform>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot2"), "Binding/Slots/Slot2"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot2");
				flag = false;
			}
			if (!Valid<Image>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot2/RarityGlow"), "Binding/Slots/Slot2/RarityGlow"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot2/RarityGlow");
				flag = false;
			}
			if (!Valid<Image>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot2/Selected"), "Binding/Slots/Slot2/Selected"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot2/Selected");
				flag = false;
			}
			if (!Valid<Image>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot2/Icon"), "Binding/Slots/Slot2/Icon"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot2/Icon");
				flag = false;
			}
			if (!Valid<RectTransform>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot2/Panels/Quantity"), "Binding/Slots/Slot2/Panels/Quantity"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot2/Panels/Quantity");
				flag = false;
			}
			if (!Valid<RectTransform>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot2/Panels/Durability"), "Binding/Slots/Slot2/Panels/Durability"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot2/Panels/Durability");
				flag = false;
			}
			if (!Valid<TMP_Text>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot2/Panels/Quantity/Count"), "Binding/Slots/Slot2/Panels/Quantity/Count"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot2/Panels/Quantity/Count");
				flag = false;
			}
			if (!Valid<Image>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot2/Panels/Durability/DurabilityBack"), "Binding/Slots/Slot2/Panels/Durability/DurabilityBack"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot2/Panels/Durability/DurabilityBack");
				flag = false;
			}
			if (!Valid<Image>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot2/Panels/Durability/DurabilityFill"), "Binding/Slots/Slot2/Panels/Durability/DurabilityFill"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot2/Panels/Durability/DurabilityFill");
				flag = false;
			}
			if (!Valid<RectTransform>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot3"), "Binding/Slots/Slot3"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot3");
				flag = false;
			}
			if (!Valid<Image>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot3/RarityGlow"), "Binding/Slots/Slot3/RarityGlow"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot3/RarityGlow");
				flag = false;
			}
			if (!Valid<Image>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot3/Selected"), "Binding/Slots/Slot3/Selected"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot3/Selected");
				flag = false;
			}
			if (!Valid<Image>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot3/Icon"), "Binding/Slots/Slot3/Icon"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot3/Icon");
				flag = false;
			}
			if (!Valid<RectTransform>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot3/Panels/Quantity"), "Binding/Slots/Slot3/Panels/Quantity"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot3/Panels/Quantity");
				flag = false;
			}
			if (!Valid<RectTransform>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot3/Panels/Durability"), "Binding/Slots/Slot3/Panels/Durability"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot3/Panels/Durability");
				flag = false;
			}
			if (!Valid<TMP_Text>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot3/Panels/Quantity/Count"), "Binding/Slots/Slot3/Panels/Quantity/Count"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot3/Panels/Quantity/Count");
				flag = false;
			}
			if (!Valid<Image>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot3/Panels/Durability/DurabilityBack"), "Binding/Slots/Slot3/Panels/Durability/DurabilityBack"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot3/Panels/Durability/DurabilityBack");
				flag = false;
			}
			if (!Valid<Image>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot3/Panels/Durability/DurabilityFill"), "Binding/Slots/Slot3/Panels/Durability/DurabilityFill"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot3/Panels/Durability/DurabilityFill");
				flag = false;
			}
			if (!Valid<RectTransform>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot4"), "Binding/Slots/Slot4"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot4");
				flag = false;
			}
			if (!Valid<Image>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot4/RarityGlow"), "Binding/Slots/Slot4/RarityGlow"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot4/RarityGlow");
				flag = false;
			}
			if (!Valid<Image>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot4/Selected"), "Binding/Slots/Slot4/Selected"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot4/Selected");
				flag = false;
			}
			if (!Valid<Image>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot4/Icon"), "Binding/Slots/Slot4/Icon"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot4/Icon");
				flag = false;
			}
			if (!Valid<RectTransform>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot4/Panels/Quantity"), "Binding/Slots/Slot4/Panels/Quantity"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot4/Panels/Quantity");
				flag = false;
			}
			if (!Valid<RectTransform>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot4/Panels/Durability"), "Binding/Slots/Slot4/Panels/Durability"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot4/Panels/Durability");
				flag = false;
			}
			if (!Valid<TMP_Text>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot4/Panels/Quantity/Count"), "Binding/Slots/Slot4/Panels/Quantity/Count"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot4/Panels/Quantity/Count");
				flag = false;
			}
			if (!Valid<Image>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot4/Panels/Durability/DurabilityBack"), "Binding/Slots/Slot4/Panels/Durability/DurabilityBack"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot4/Panels/Durability/DurabilityBack");
				flag = false;
			}
			if (!Valid<Image>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot4/Panels/Durability/DurabilityFill"), "Binding/Slots/Slot4/Panels/Durability/DurabilityFill"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot4/Panels/Durability/DurabilityFill");
				flag = false;
			}
			if (!Valid<RectTransform>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot5"), "Binding/Slots/Slot5"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot5");
				flag = false;
			}
			if (!Valid<Image>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot5/RarityGlow"), "Binding/Slots/Slot5/RarityGlow"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot5/RarityGlow");
				flag = false;
			}
			if (!Valid<Image>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot5/Selected"), "Binding/Slots/Slot5/Selected"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot5/Selected");
				flag = false;
			}
			if (!Valid<Image>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot5/Icon"), "Binding/Slots/Slot5/Icon"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot5/Icon");
				flag = false;
			}
			if (!Valid<RectTransform>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot5/Panels/Quantity"), "Binding/Slots/Slot5/Panels/Quantity"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot5/Panels/Quantity");
				flag = false;
			}
			if (!Valid<RectTransform>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot5/Panels/Durability"), "Binding/Slots/Slot5/Panels/Durability"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot5/Panels/Durability");
				flag = false;
			}
			if (!Valid<TMP_Text>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot5/Panels/Quantity/Count"), "Binding/Slots/Slot5/Panels/Quantity/Count"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot5/Panels/Quantity/Count");
				flag = false;
			}
			if (!Valid<Image>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot5/Panels/Durability/DurabilityBack"), "Binding/Slots/Slot5/Panels/Durability/DurabilityBack"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot5/Panels/Durability/DurabilityBack");
				flag = false;
			}
			if (!Valid<Image>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot5/Panels/Durability/DurabilityFill"), "Binding/Slots/Slot5/Panels/Durability/DurabilityFill"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot5/Panels/Durability/DurabilityFill");
				flag = false;
			}
			if (!Valid<RectTransform>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot6"), "Binding/Slots/Slot6"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot6");
				flag = false;
			}
			if (!Valid<Image>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot6/RarityGlow"), "Binding/Slots/Slot6/RarityGlow"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot6/RarityGlow");
				flag = false;
			}
			if (!Valid<Image>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot6/Selected"), "Binding/Slots/Slot6/Selected"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot6/Selected");
				flag = false;
			}
			if (!Valid<Image>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot6/Icon"), "Binding/Slots/Slot6/Icon"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot6/Icon");
				flag = false;
			}
			if (!Valid<RectTransform>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot6/Panels/Quantity"), "Binding/Slots/Slot6/Panels/Quantity"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot6/Panels/Quantity");
				flag = false;
			}
			if (!Valid<RectTransform>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot6/Panels/Durability"), "Binding/Slots/Slot6/Panels/Durability"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot6/Panels/Durability");
				flag = false;
			}
			if (!Valid<TMP_Text>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot6/Panels/Quantity/Count"), "Binding/Slots/Slot6/Panels/Quantity/Count"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot6/Panels/Quantity/Count");
				flag = false;
			}
			if (!Valid<Image>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot6/Panels/Durability/DurabilityBack"), "Binding/Slots/Slot6/Panels/Durability/DurabilityBack"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot6/Panels/Durability/DurabilityBack");
				flag = false;
			}
			if (!Valid<Image>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot6/Panels/Durability/DurabilityFill"), "Binding/Slots/Slot6/Panels/Durability/DurabilityFill"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot6/Panels/Durability/DurabilityFill");
				flag = false;
			}
			if (!Valid<RectTransform>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot7"), "Binding/Slots/Slot7"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot7");
				flag = false;
			}
			if (!Valid<Image>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot7/RarityGlow"), "Binding/Slots/Slot7/RarityGlow"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot7/RarityGlow");
				flag = false;
			}
			if (!Valid<Image>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot7/Selected"), "Binding/Slots/Slot7/Selected"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot7/Selected");
				flag = false;
			}
			if (!Valid<Image>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot7/Icon"), "Binding/Slots/Slot7/Icon"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot7/Icon");
				flag = false;
			}
			if (!Valid<RectTransform>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot7/Panels/Quantity"), "Binding/Slots/Slot7/Panels/Quantity"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot7/Panels/Quantity");
				flag = false;
			}
			if (!Valid<RectTransform>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot7/Panels/Durability"), "Binding/Slots/Slot7/Panels/Durability"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot7/Panels/Durability");
				flag = false;
			}
			if (!Valid<TMP_Text>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot7/Panels/Quantity/Count"), "Binding/Slots/Slot7/Panels/Quantity/Count"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot7/Panels/Quantity/Count");
				flag = false;
			}
			if (!Valid<Image>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot7/Panels/Durability/DurabilityBack"), "Binding/Slots/Slot7/Panels/Durability/DurabilityBack"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot7/Panels/Durability/DurabilityBack");
				flag = false;
			}
			if (!Valid<Image>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot7/Panels/Durability/DurabilityFill"), "Binding/Slots/Slot7/Panels/Durability/DurabilityFill"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot7/Panels/Durability/DurabilityFill");
				flag = false;
			}
			if (!Valid<RectTransform>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot8"), "Binding/Slots/Slot8"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot8");
				flag = false;
			}
			if (!Valid<Image>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot8/RarityGlow"), "Binding/Slots/Slot8/RarityGlow"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot8/RarityGlow");
				flag = false;
			}
			if (!Valid<Image>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot8/Selected"), "Binding/Slots/Slot8/Selected"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot8/Selected");
				flag = false;
			}
			if (!Valid<Image>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot8/Icon"), "Binding/Slots/Slot8/Icon"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot8/Icon");
				flag = false;
			}
			if (!Valid<RectTransform>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot8/Panels/Quantity"), "Binding/Slots/Slot8/Panels/Quantity"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot8/Panels/Quantity");
				flag = false;
			}
			if (!Valid<RectTransform>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot8/Panels/Durability"), "Binding/Slots/Slot8/Panels/Durability"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot8/Panels/Durability");
				flag = false;
			}
			if (!Valid<TMP_Text>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot8/Panels/Quantity/Count"), "Binding/Slots/Slot8/Panels/Quantity/Count"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot8/Panels/Quantity/Count");
				flag = false;
			}
			if (!Valid<Image>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot8/Panels/Durability/DurabilityBack"), "Binding/Slots/Slot8/Panels/Durability/DurabilityBack"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot8/Panels/Durability/DurabilityBack");
				flag = false;
			}
			if (!Valid<Image>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Slots/Slot8/Panels/Durability/DurabilityFill"), "Binding/Slots/Slot8/Panels/Durability/DurabilityFill"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Slots/Slot8/Panels/Durability/DurabilityFill");
				flag = false;
			}
			if (!Valid<RectTransform>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/ForsakenPower"), "Binding/ForsakenPower"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/ForsakenPower");
				flag = false;
			}
			if (!Valid<Image>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/ForsakenPower/Icon"), "Binding/ForsakenPower/Icon"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/ForsakenPower/Icon");
				flag = false;
			}
			if (!Valid<Image>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/ForsakenPower/CooldownMask"), "Binding/ForsakenPower/CooldownMask"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/ForsakenPower/CooldownMask");
				flag = false;
			}
			if (!Valid<TMP_Text>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/ForsakenPower/CooldownText"), "Binding/ForsakenPower/CooldownText"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/ForsakenPower/CooldownText");
				flag = false;
			}
			if (!Valid<RectTransform>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Context"), "Binding/Context"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Context");
				flag = false;
			}
			if (!Valid<Image>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Context/RarityGlow"), "Binding/Context/RarityGlow"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Context/RarityGlow");
				flag = false;
			}
			if (!Valid<Image>(BindingPaths.Find(root.transform, "BGH_Hotbar/Binding/Context/Icon"), "Binding/Context/Icon"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_Hotbar/Binding/Context/Icon");
				flag = false;
			}
			if (!Valid<RectTransform>(BindingPaths.Find(root.transform, "BGH_FoodCarry/Binding/Food"), "Binding/Food"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_FoodCarry/Binding/Food");
				flag = false;
			}
			if (!Valid<RectTransform>(BindingPaths.Find(root.transform, "BGH_FoodCarry/Binding/Carry"), "Binding/Carry"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_FoodCarry/Binding/Carry");
				flag = false;
			}
			if (!Valid<Image>(BindingPaths.Find(root.transform, "BGH_FoodCarry/Binding/Food/Slot1/Icon"), "Binding/Food/Slot1/Icon"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_FoodCarry/Binding/Food/Slot1/Icon");
				flag = false;
			}
			if (!Valid<TMP_Text>(BindingPaths.Find(root.transform, "BGH_FoodCarry/Binding/Food/Slot1/Timer"), "Binding/Food/Slot1/Timer"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_FoodCarry/Binding/Food/Slot1/Timer");
				flag = false;
			}
			if (!Valid<Image>(BindingPaths.Find(root.transform, "BGH_FoodCarry/Binding/Food/Slot2/Icon"), "Binding/Food/Slot2/Icon"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_FoodCarry/Binding/Food/Slot2/Icon");
				flag = false;
			}
			if (!Valid<TMP_Text>(BindingPaths.Find(root.transform, "BGH_FoodCarry/Binding/Food/Slot2/Timer"), "Binding/Food/Slot2/Timer"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_FoodCarry/Binding/Food/Slot2/Timer");
				flag = false;
			}
			if (!Valid<Image>(BindingPaths.Find(root.transform, "BGH_FoodCarry/Binding/Food/Slot3/Icon"), "Binding/Food/Slot3/Icon"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_FoodCarry/Binding/Food/Slot3/Icon");
				flag = false;
			}
			if (!Valid<TMP_Text>(BindingPaths.Find(root.transform, "BGH_FoodCarry/Binding/Food/Slot3/Timer"), "Binding/Food/Slot3/Timer"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_FoodCarry/Binding/Food/Slot3/Timer");
				flag = false;
			}
			if (!Valid<TMP_Text>(BindingPaths.Find(root.transform, "BGH_FoodCarry/Binding/Carry/Weight"), "Binding/Carry/Weight"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_FoodCarry/Binding/Carry/Weight");
				flag = false;
			}
			if (!Valid<TMP_Text>(BindingPaths.Find(root.transform, "BGH_FoodCarry/Binding/Carry/Slots"), "Binding/Carry/Slots"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_FoodCarry/Binding/Carry/Slots");
				flag = false;
			}
			if (!Valid<Image>(BindingPaths.Find(root.transform, "BGH_XP/Binding/Fill"), "Binding/Fill"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_XP/Binding/Fill");
				flag = false;
			}
			if (!Valid<TMP_Text>(BindingPaths.Find(root.transform, "BGH_XP/Binding/Level"), "Binding/Level"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_XP/Binding/Level");
				flag = false;
			}
			if (!Valid<TMP_Text>(BindingPaths.Find(root.transform, "BGH_XP/Binding/Progress"), "Binding/Progress"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_XP/Binding/Progress");
				flag = false;
			}
			if (!Valid<RectTransform>(BindingPaths.Find(root.transform, "BGH_MinimapOverlay/Binding/MapFrame"), "Binding/MapFrame"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_MinimapOverlay/Binding/MapFrame");
				flag = false;
			}
			if (!Valid<RectTransform>(BindingPaths.Find(root.transform, "BGH_MinimapOverlay/Binding/InfoFrame"), "Binding/InfoFrame"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_MinimapOverlay/Binding/InfoFrame");
				flag = false;
			}
			if (!Valid<RectTransform>(BindingPaths.Find(root.transform, "BGH_MinimapOverlay/Binding/MapFrame/MapViewport"), "Binding/MapFrame/MapViewport"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_MinimapOverlay/Binding/MapFrame/MapViewport");
				flag = false;
			}
			if (!Valid<TMP_Text>(BindingPaths.Find(root.transform, "BGH_MinimapOverlay/Binding/InfoFrame/Biome"), "Binding/InfoFrame/Biome"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_MinimapOverlay/Binding/InfoFrame/Biome");
				flag = false;
			}
			if (!Valid<TMP_Text>(BindingPaths.Find(root.transform, "BGH_MinimapOverlay/Binding/InfoFrame/Coordinates"), "Binding/InfoFrame/Coordinates"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_MinimapOverlay/Binding/InfoFrame/Coordinates");
				flag = false;
			}
			if (!Valid<TMP_Text>(BindingPaths.Find(root.transform, "BGH_MinimapOverlay/Binding/InfoFrame/WorldTime"), "Binding/InfoFrame/WorldTime"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_MinimapOverlay/Binding/InfoFrame/WorldTime");
				flag = false;
			}
			if (!Valid<Image>(BindingPaths.Find(root.transform, "BGH_MinimapOverlay/Binding/InfoFrame/WindIcon"), "Binding/InfoFrame/WindIcon"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_MinimapOverlay/Binding/InfoFrame/WindIcon");
				flag = false;
			}
			if (!Valid<RectTransform>(BindingPaths.Find(root.transform, "BGH_StatusEffects/Binding/Content"), "Binding/Content"))
			{
				log.LogError((object)"Invalid instantiated binding: BGH_StatusEffects/Binding/Content");
				flag = false;
			}
			return flag;
		}

		private static void WarnOptionalRelationshipOrbs(GameObject prefab, ManualLogSource log)
		{
			if ((Object)(object)prefab == (Object)null)
			{
				return;
			}
			Transform val = BindingPaths.Find(prefab.transform, "Binding/EnemyOrb");
			Transform val2 = BindingPaths.Find(prefab.transform, "Binding/FriendOrb");
			if (!((Object)(object)val == (Object)null) || !((Object)(object)val2 == (Object)null))
			{
				if ((Object)(object)val == (Object)null || !(val is RectTransform))
				{
					log.LogWarning((object)("[BGH] Optional " + ((Object)prefab).name + "/Binding/EnemyOrb is missing or not a RectTransform."));
				}
				if ((Object)(object)val2 == (Object)null || !(val2 is RectTransform))
				{
					log.LogWarning((object)("[BGH] Optional " + ((Object)prefab).name + "/Binding/FriendOrb is missing or not a RectTransform."));
				}
			}
		}

		private static void WarnIncompleteOptionalPathPanels(GameObject prefab, ManualLogSource log)
		{
			if (!((Object)(object)prefab == (Object)null))
			{
				if ((Object)(object)BindingPaths.Find(prefab.transform, "Binding/EmblemBadge") != (Object)null)
				{
					WarnOptionalPanel<Image>(prefab, "Binding/EmblemBadge", "Binding/EmblemBadge/Icon", log);
				}
				else if ((Object)(object)BindingPaths.Find(prefab.transform, "Binding/ShowEmblem") != (Object)null)
				{
					WarnOptionalPanel<Image>(prefab, "Binding/ShowEmblem", "Binding/ShowEmblem/Icon", log);
				}
				else
				{
					WarnOptionalPanel<Image>(prefab, "Binding/Emblem", "Binding/Emblem/Icon", log);
				}
				if ((Object)(object)BindingPaths.Find(prefab.transform, "Binding/Title") != (Object)null)
				{
					WarnOptionalPanel<TMP_Text>(prefab, "Binding/Title", "Binding/Title", log);
				}
				else if ((Object)(object)BindingPaths.Find(prefab.transform, "Binding/ShowRank") != (Object)null)
				{
					WarnOptionalPanel<TMP_Text>(prefab, "Binding/ShowRank", "Binding/ShowRank/Text", log);
				}
				else
				{
					WarnOptionalPanel<TMP_Text>(prefab, "Binding/Rank", "Binding/Rank/Text", log);
				}
				if ((Object)(object)BindingPaths.Find(prefab.transform, "Binding/FactionFrame") != (Object)null)
				{
					WarnOptionalPanel<TMP_Text>(prefab, "Binding/FactionFrame", "Binding/FactionFrame/FactionText", log);
				}
				else
				{
					WarnOptionalPanel<TMP_Text>(prefab, "Binding/Faction", "Binding/Faction/Text", log);
				}
			}
		}

		private static void WarnOptionalPanel<T>(GameObject prefab, string root, string child, ManualLogSource log) where T : Component
		{
			Transform val = BindingPaths.Find(prefab.transform, root);
			if (!((Object)(object)val == (Object)null))
			{
				Transform val2 = BindingPaths.Find(prefab.transform, child);
				if ((!((Object)(object)val2 != (Object)null) || !((Object)(object)((Component)val2).GetComponent<T>() != (Object)null)) && !((Object)(object)((Component)val).GetComponent<T>() != (Object)null))
				{
					log.LogWarning((object)("[BGH] Optional " + ((Object)prefab).name + "/" + root + " has no " + typeof(T).Name + "; that panel will stay hidden until Unity prefab is corrected."));
				}
			}
		}

		internal static bool ValidatePlayerPrefab(GameObject prefab, ManualLogSource log)
		{
			if ((Object)(object)prefab == (Object)null || (Object)(object)prefab.GetComponent<RectTransform>() == (Object)null)
			{
				return false;
			}
			bool flag = Valid<Image>(BindingPaths.Find(prefab.transform, "Binding/HealthFill"), "Binding/HealthFill") && Valid<TMP_Text>(BindingPaths.Find(prefab.transform, "Binding/Name"), "Binding/Name") && Valid<TMP_Text>(BindingPaths.Find(prefab.transform, "Binding/HealthValue"), "Binding/HealthValue") && Valid<RectTransform>(BindingPaths.Find(prefab.transform, "Binding/LevelBadge"), "Binding/LevelBadge") && Valid<TMP_Text>(BindingPaths.Find(prefab.transform, "Binding/LevelBadge/Level"), "Binding/LevelBadge/Level");
			if (!flag)
			{
				log.LogWarning((object)"[BGH] BGH_PlayerHud does not match the EnemyHud binding contract.");
			}
			return flag;
		}

		private static bool Valid<T>(Transform t, string path) where T : Component
		{
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Invalid comparison between Unknown and I4
			if ((Object)(object)t == (Object)null)
			{
				return false;
			}
			T component = ((Component)t).GetComponent<T>();
			if ((Object)(object)component == (Object)null)
			{
				return false;
			}
			object obj = component;
			TMP_Text val = (TMP_Text)((obj is TMP_Text) ? obj : null);
			if ((Object)(object)val != (Object)null && ((Object)(object)val.font == (Object)null || (Object)(object)val.fontSharedMaterial == (Object)null))
			{
				return false;
			}
			object obj2 = component;
			Image val2 = (Image)((obj2 is Image) ? obj2 : null);
			if ((Object)(object)val2 != (Object)null && (path.EndsWith("Fill", StringComparison.Ordinal) || path.EndsWith("CooldownMask", StringComparison.Ordinal)))
			{
				return (Object)(object)val2.sprite != (Object)null && (int)val2.type == 3;
			}
			return true;
		}

		private static bool Check<T>(Dictionary<string, GameObject> prefabs, string name, string path, ManualLogSource log) where T : Component
		{
			if (prefabs.TryGetValue(name, out var value))
			{
				Transform t = BindingPaths.Find(value.transform, path);
				if (Valid<T>(t, path))
				{
					if (name == "BGH_EnemyHud" || name == "BGH_BossHud" || name == "BGH_StatusEffectEntry")
					{
						return true;
					}
					if (prefabs.TryGetValue("BGH_Root", out var value2))
					{
						Transform t2 = BindingPaths.Find(value2.transform, name + "/" + path);
						if (Valid<T>(t2, path))
						{
							return true;
						}
					}
				}
			}
			log.LogError((object)("Invalid BGH binding: " + name + "/" + path + " requires " + typeof(T).Name));
			return false;
		}
	}
	internal sealed class CachedOverlayPresenter
	{
		private readonly OverlayView _view;

		private readonly GalaxyHudConfig _config;

		private readonly StatusEffectPool _statuses;

		public CachedOverlayPresenter(OverlayView view, GalaxyHudConfig config, PrefabOverlayAssembler assembler)
		{
			_view = view;
			_config = config;
			_statuses = new StatusEffectPool(view, config, assembler);
		}

		public bool ApplyResources(ResourceSnapshot s)
		{
			bool flag = false;
			flag |= ApplyResource(_view.Health, s.Health, s.MaxHealth);
			flag |= ApplyResource(_view.Stamina, s.Stamina, s.MaxStamina);
			flag |= ApplyResource(_view.Eitr, s.Eitr, s.MaxEitr);
			return flag | ApplyResource(_view.Adrenaline, s.Adrenaline, s.MaxAdrenaline);
		}

		private bool ApplyResource(ResourceBarView view, float current, float max)
		{
			if (view == null)
			{
				return false;
			}
			float value = ((max > 0f) ? Mathf.Clamp01(current / max) : 0f);
			bool result = SetFill(view.Fill, ref view.LastFill, value);
			int num = Mathf.CeilToInt(Mathf.Max(0f, current));
			int num2 = Mathf.CeilToInt(Mathf.Max(0f, max));
			bool value2 = _config.ShowExactResourceValues.Value;
			if ((Object)(object)view.Value != (Object)null && (!view.Initialized || view.LastCurrent != num || view.LastMax != num2 || view.LastShowExact != value2))
			{
				view.LastCurrent = num;
				view.LastMax = num2;
				view.LastShowExact = value2;
				view.Value.text = (value2 ? $"{num} / {num2}" : string.Empty);
				result = true;
			}
			view.Initialized = true;
			return result;
		}

		public void ApplyHotbar(HotbarSlotSnapshot[] slots)
		{
			if (slots == null)
			{
				return;
			}
			for (int i = 0; i < _view.Hotbar.Length; i++)
			{
				HotbarSlotView hotbarSlotView = _view.Hotbar[i];
				if (hotbarSlotView == null)
				{
					continue;
				}
				HotbarSlotSnapshot hotbarSlotSnapshot = slots[i];
				if ((Object)(object)hotbarSlotView.Icon != (Object)null && (!hotbarSlotView.Initialized || (Object)(object)hotbarSlotView.LastIcon != (Object)(object)hotbarSlotSnapshot.Icon))
				{
					hotbarSlotView.LastIcon = hotbarSlotSnapshot.Icon;
					hotbarSlotView.Icon.sprite = hotbarSlotSnapshot.Icon;
				}
				if ((Object)(object)hotbarSlotView.Icon != (Object)null)
				{
					bool flag = hotbarSlotSnapshot.HasItem && (Object)(object)hotbarSlotSnapshot.Icon != (Object)null;
					if (!hotbarSlotView.Initialized || ((Behaviour)hotbarSlotView.Icon).enabled != flag)
					{
						((Behaviour)hotbarSlotView.Icon).enabled = flag;
					}
				}
				bool visible = hotbarSlotSnapshot.HasItem && hotbarSlotSnapshot.Stack > 1;
				bool flag2 = hotbarSlotSnapshot.HasItem && hotbarSlotSnapshot.Stack == 1 && hotbarSlotSnapshot.UsesDurability;
				SetPanelVisible(hotbarSlotView.QuantityPanel, visible);
				SetPanelVisible(hotbarSlotView.DurabilityPanel, flag2);
				if ((Object)(object)hotbarSlotView.Count != (Object)null && (!hotbarSlotView.Initialized || hotbarSlotView.LastStack != hotbarSlotSnapshot.Stack || hotbarSlotView.LastHasItem != hotbarSlotSnapshot.HasItem))
				{
					hotbarSlotView.LastStack = hotbarSlotSnapshot.Stack;
					hotbarSlotView.Count.text = ((hotbarSlotSnapshot.HasItem && hotbarSlotSnapshot.Stack > 1) ? hotbarSlotSnapshot.Stack.ToString() : string.Empty);
				}
				if ((Object)(object)hotbarSlotView.SelectedFrame != (Object)null && (!hotbarSlotView.Initialized || hotbarSlotView.LastSelected != hotbarSlotSnapshot.Selected))
				{
					hotbarSlotView.LastSelected = hotbarSlotSnapshot.Selected;
					((Behaviour)hotbarSlotView.SelectedFrame).enabled = hotbarSlotSnapshot.HasItem && hotbarSlotSnapshot.Selected;
				}
				ApplyRarity(hotbarSlotView.RarityGlow, hotbarSlotView.RarityOutline, ref hotbarSlotView.LastRarityVisual, hotbarSlotSnapshot.HasItem ? hotbarSlotSnapshot.Item : null);
				if (flag2 && (Object)(object)hotbarSlotView.DurabilityFill != (Object)null && (!hotbarSlotView.Initialized || Mathf.Abs(hotbarSlotView.LastDurability - hotbarSlotSnapshot.Durability01) > 0.001f))
				{
					hotbarSlotView.LastDurability = hotbarSlotSnapshot.Durability01;
					hotbarSlotView.DurabilityFill.fillAmount = hotbarSlotSnapshot.Durability01;
				}
				hotbarSlotView.LastHasItem = hotbarSlotSnapshot.HasItem;
				hotbarSlotView.Initialized = true;
			}
		}

		private static void SetPanelVisible(RectTransform panel, bool visible)
		{
			if ((Object)(object)panel != (Object)null && ((Component)panel).gameObject.activeSelf != visible)
			{
				((Component)panel).gameObject.SetActive(visible);
			}
		}

		public void ApplyContext(ContextSlotSnapshot data)
		{
			ContextSlotView context = _view.Context;
			if ((Object)(object)context.Root == (Object)null)
			{
				return;
			}
			if (!context.Initialized || context.LastVisible != data.Visible)
			{
				context.LastVisible = data.Visible;
				if (((Component)context.Root).gameObject.activeSelf != data.Visible)
				{
					((Component)context.Root).gameObject.SetActive(data.Visible);
				}
				if ((Object)(object)context.DecorationRoot != (Object)null && ((Component)context.DecorationRoot).gameObject.activeSelf != data.Visible)
				{
					((Component)context.DecorationRoot).gameObject.SetActive(data.Visible);
				}
			}
			if (!data.Visible)
			{
				context.Initialized = true;
				return;
			}
			if ((Object)(object)context.Icon != (Object)null && (!context.Initialized || context.LastItem != data.Item || (Object)(object)context.LastIcon != (Object)(object)data.Icon))
			{
				context.LastItem = data.Item;
				context.LastIcon = data.Icon;
				context.Icon.sprite = data.Icon;
			}
			if ((Object)(object)context.Icon != (Object)null)
			{
				bool flag = (Object)(object)data.Icon != (Object)null;
				if (((Behaviour)context.Icon).enabled != flag)
				{
					((Behaviour)context.Icon).enabled = flag;
				}
			}
			bool flag2 = data.Stack > 1;
			bool flag3 = data.Stack == 1 && data.UsesDurability;
			SetPanelVisible(context.QuantityPanel, flag2);
			SetPanelVisible(context.DurabilityPanel, flag3);
			if ((Object)(object)context.Count != (Object)null && (!context.Initialized || context.LastStack != data.Stack))
			{
				context.LastStack = data.Stack;
				context.Count.text = (flag2 ? data.Stack.ToString() : string.Empty);
			}
			ApplyRarity(context.RarityGlow, context.RarityOutline, ref context.LastRarityVisual, data.Item);
			if ((Object)(object)context.DurabilityBack != (Object)null && ((Behaviour)context.DurabilityBack).enabled != flag3)
			{
				((Behaviour)context.DurabilityBack).enabled = flag3;
			}
			if ((Object)(object)context.DurabilityFill != (Object)null && ((Behaviour)context.DurabilityFill).enabled != flag3)
			{
				((Behaviour)context.DurabilityFill).enabled = flag3;
			}
			if (flag3 && (Object)(object)context.DurabilityFill != (Object)null && (!context.Initialized || Mathf.Abs(context.LastDurability - data.Durability01) > 0.001f))
			{
				context.LastDurability = data.Durability01;
				context.DurabilityFill.fillAmount = data.Durability01;
			}
			context.Initialized = true;
		}

		public void ApplyForsaken(ForsakenPowerSnapshot data)
		{
			ForsakenSlotView forsaken = _view.Forsaken;
			if ((Object)(object)forsaken.Root == (Object)null)
			{
				return;
			}
			if (!forsaken.Initialized || forsaken.LastVisible != data.Visible)
			{
				forsaken.LastVisible = data.Visible;
				if (((Component)forsaken.Root).gameObject.activeSelf != data.Visible)
				{
					((Component)forsaken.Root).gameObject.SetActive(data.Visible);
				}
				if ((Object)(object)forsaken.DecorationRoot != (Object)null && ((Component)forsaken.DecorationRoot).gameObject.activeSelf != data.Visible)
				{
					((Component)forsaken.DecorationRoot).gameObject.SetActive(data.Visible);
				}
			}
			if (!data.Visible)
			{
				forsaken.Initialized = true;
				return;
			}
			Sprite val = (((Object)(object)data.Icon != (Object)null) ? data.Icon : forsaken.FallbackIcon);
			if ((Object)(object)forsaken.Icon != (Object)null && (!forsaken.Initialized || (Object)(object)forsaken.LastIcon != (Object)(object)val))
			{
				forsaken.LastIcon = val;
				forsaken.Icon.sprite = val;
			}
			if ((Object)(object)forsaken.Icon != (Object)null && ((Behaviour)forsaken.Icon).enabled != ((Object)(object)val != (Object)null))
			{
				((Behaviour)forsaken.Icon).enabled = (Object)(object)val != (Object)null;
			}
			float num = ((data.CooldownMaximum > 0.01f) ? data.CooldownMaximum : Mathf.Max(data.CooldownRemaining, 0.01f));
			float num2 = ((data.CooldownRemaining > 0.01f) ? Mathf.Clamp01(data.CooldownRemaining / num) : 0f);
			if ((Object)(object)forsaken.CooldownMask != (Object)null && (!forsaken.Initialized || Mathf.Abs(forsaken.LastMask - num2) > 0.0025f))
			{
				forsaken.LastMask = num2;
				forsaken.CooldownMask.fillAmount = num2;
			}
			bool flag = data.CooldownRemaining > 0.01f;
			if ((Object)(object)forsaken.CooldownMask != (Object)null && ((Behaviour)forsaken.CooldownMask).enabled != flag)
			{
				((Behaviour)forsaken.CooldownMask).enabled = flag;
			}
			int num3 = (flag ? Mathf.CeilToInt(data.CooldownRemaining) : 0);
			if ((Object)(object)forsaken.Timer != (Object)null && (!forsaken.Initialized || forsaken.LastSeconds != num3))
			{
				forsaken.LastSeconds = num3;
				forsaken.Timer.text = (flag ? FormatShortTime(num3) : string.Empty);
			}
			forsaken.Initialized = true;
		}

		public void SyncFoods(FoodSnapshot[] foods)
		{
			if (foods != null && foods.Length >= 3)
			{
				SyncFood(_view.FoodCarry.Slot1, foods[0]);
				SyncFood(_view.FoodCarry.Slot2, foods[1]);
				SyncFood(_view.FoodCarry.Slot3, foods[2]);
			}
		}

		private static void SyncFood(FoodSlotView view, FoodSnapshot data)
		{
			if (view == null)
			{
				return;
			}
			if (!view.Initialized || view.BoundFood != data.Food || (Object)(object)view.LastIcon != (Object)(object)data.Icon || view.LastVisible != data.Visible)
			{
				view.BoundFood = data.Food;
				view.LastIcon = data.Icon;
				view.LastVisible = data.Visible;
				if ((Object)(object)view.Icon != (Object)null)
				{
					view.Icon.sprite = data.Icon;
					((Behaviour)view.Icon).enabled = data.Visible && (Object)(object)data.Icon != (Object)null;
				}
				view.LastSeconds = int.MinValue;
				view.Initialized = true;
			}
			TickFoodTimer(view);
		}

		public void TickFoodTimers()
		{
			TickFoodTimer(_view.FoodCarry.Slot1);
			TickFoodTimer(_view.FoodCarry.Slot2);
			TickFoodTimer(_view.FoodCarry.Slot3);
		}

		private static void TickFoodTimer(FoodSlotView view)
		{
			if (view == null || (Object)(object)view.Timer == (Object)null)
			{
				return;
			}
			Food boundFood = view.BoundFood;
			if (boundFood == null)
			{
				if (!string.IsNullOrEmpty(view.Timer.text))
				{
					view.Timer.text = string.Empty;
				}
				view.LastSeconds = int.MinValue;
				return;
			}
			int num = Mathf.Max(0, Mathf.CeilToInt(boundFood.m_time));
			if (view.LastSeconds != num)
			{
				view.LastSeconds = num;
				view.Timer.text = FormatClock(num);
			}
		}

		public void ApplyCarry(CarrySnapshot data)
		{
			FoodCarryView foodCarry = _view.FoodCarry;
			int num = Mathf.RoundToInt(data.Weight * 10f);
			int num2 = Mathf.RoundToInt(data.MaxWeight * 10f);
			if ((Object)(object)foodCarry.Weight != (Object)null && (foodCarry.LastWeight != num || foodCarry.LastMaxWeight != num2))
			{
				foodCarry.LastWeight = num;
				foodCarry.LastMaxWeight = num2;
				foodCarry.Weight.text = data.Weight.ToString("0.#", CultureInfo.CurrentCulture) + " / " + data.MaxWeight.ToString("0.#", CultureInfo.CurrentCulture) + " kg";
			}
			if ((Object)(object)foodCarry.Slots != (Object)null && (foodCarry.LastOccupiedSlots != data.OccupiedSlots || foodCarry.LastTotalSlots != data.TotalSlots))
			{
				foodCarry.LastOccupiedSlots = data.OccupiedSlots;
				foodCarry.LastTotalSlots = data.TotalSlots;
				foodCarry.Slots.text = $"{data.OccupiedSlots} / {data.TotalSlots}";
			}
		}

		public void ApplyXp(XpSnapshot data)
		{
			XpView xp = _view.Xp;
			int num = (data.Known ? Mathf.RoundToInt(Mathf.Clamp01(data.Progress01) * 10000f) : (-1));
			if (!xp.Initialized || xp.LastLevel != data.Level || xp.LastKnown != data.Known)
			{
				xp.LastLevel = data.Level;
				if ((Object)(object)xp.Level != (Object)null)
				{
					xp.Level.text = (data.Known ? data.Level.ToString() : "--");
				}
			}
			if (!xp.Initialized || xp.LastPercentHundredths != num || xp.LastKnown != data.Known)
			{
				xp.LastPercentHundredths = num;
				if ((Object)(object)xp.Progress != (Object)null)
				{
					xp.Progress.text = (data.Known ? ((data.Progress01 * 100f).ToString("0.00", CultureInfo.CurrentCulture) + "%") : "--");
				}
			}
			SetFill(xp.Fill, ref xp.LastFill, data.Known ? data.Progress01 : 0f);
			xp.LastKnown = data.Known;
			xp.Initialized = true;
		}

		public void ApplyNavigation(NavigationSnapshot data)
		{
			//IL_0287: Unknown result type (might be due to invalid IL or missing references)
			NavigationView navigation = _view.Navigation;
			if ((Object)(object)navigation.Biome != (Object)null)
			{
				bool value = _config.ShowBiome.Value;
				if (((Component)navigation.Biome).gameObject.activeSelf != value)
				{
					((Component)navigation.Biome).gameObject.SetActive(value);
				}
				if (value && !string.Equals(navigation.LastBiome, data.BiomeName, StringComparison.Ordinal))
				{
					navigation.LastBiome = data.BiomeName;
					navigation.Biome.text = data.BiomeName ?? string.Empty;
				}
			}
			if ((Object)(object)navigation.Coordinates != (Object)null)
			{
				bool value2 = _config.ShowCoordinates.Value;
				if (((Component)navigation.Coordinates).gameObject.activeSelf != value2)
				{
					((Component)navigation.Coordinates).gameObject.SetActive(value2);
				}
				if (value2 && (navigation.LastX != data.X || navigation.LastZ != data.Z || navigation.LastY != data.Y))
				{
					navigation.LastX = data.X;
					navigation.LastZ = data.Z;
					navigation.LastY = data.Y;
					navigation.Coordinates.text = $"x: {data.X}  y: {data.Y}  z: {data.Z}";
				}
			}
			if ((Object)(object)navigation.WorldTime != (Object)null && navigation.LastMinute != data.MinuteOfDay)
			{
				navigation.LastMinute = data.MinuteOfDay;
				navigation.WorldTime.text = ((data.MinuteOfDay < 0) ? "--:--" : $"{data.MinuteOfDay / 60:00}:{data.MinuteOfDay % 60:00}");
			}
			if ((Object)(object)navigation.WindIcon != (Object)null && (float.IsNaN(navigation.LastWindAngle) || Mathf.Abs(Mathf.DeltaAngle(navigation.LastWindAngle, data.WindAngle)) > 0.25f))
			{
				navigation.LastWindAngle = data.WindAngle;
				((Transform)((Graphic)navigation.WindIcon).rectTransform).localRotation = Quaternion.Euler(0f, 0f, navigation.AuthoredWindRotation - data.WindAngle);
			}
		}

		public void SyncStatuses(IReadOnlyList<StatusEffect> effects)
		{
			_statuses.Sync(effects);
		}

		public void TickStatusTimers()
		{
			_statuses.TickTimers();
		}

		public void SetHotbarVisible(bool visible)
		{
			if ((Object)(object)_view.HotbarRoot != (Object)null && ((Component)_view.HotbarRoot).gameObject.activeSelf != visible)
			{
				((Component)_view.HotbarRoot).gameObject.SetActive(visible);
			}
		}

		public void SetAllVisible(bool visible)
		{
			if ((Object)(object)_view.Root != (Object)null && _view.Root.activeSelf != visible)
			{
				_view.Root.SetActive(visible);
			}
		}

		private static void ApplyRarity(Image image, Outline outline, ref RarityVisualState previous, ItemData item)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			RarityVisualState visual = BalrondItemRarityCompat.GetVisual(item);
			if (previous.Equals(visual))
			{
				return;
			}
			previous = visual;
			if ((Object)(object)image != (Object)null)
			{
				((Behaviour)image).enabled = visual.Enabled && visual.Gradient.a > 0f;
				if (((Behaviour)image).enabled)
				{
					((Graphic)image).color = visual.Gradient;
				}
			}
			if ((Object)(object)outline != (Object)null)
			{
				((Behaviour)outline).enabled = visual.Enabled && visual.Outline.a > 0f;
				if (((Behaviour)outline).enabled)
				{
					((Shadow)outline).effectColor = visual.Outline;
					((Shadow)outline).effectDistance = visual.Distance;
					((Shadow)outline).useGraphicAlpha = false;
				}
			}
		}

		private static bool SetFill(Image image, ref float cache, float value)
		{
			if ((Object)(object)image == (Object)null)
			{
				return false;
			}
			value = Mathf.Clamp01(value);
			if (cache >= 0f && Mathf.Abs(cache - value) <= 0.001f)
			{
				return false;
			}
			cache = value;
			image.fillAmount = value;
			return true;
		}

		private static string FormatClock(int totalSeconds)
		{
			return $"{totalSeconds / 60}:{totalSeconds % 60:00}";
		}

		private static string FormatShortTime(int totalSeconds)
		{
			return (totalSeconds >= 60) ? FormatClock(totalSeconds) : $"{totalSeconds}s";
		}
	}
	internal sealed class CombatHudAttachmentManager : IDisposable
	{
		private sealed class Binding
		{
			internal Character Character;

			internal HudData HudData;

			internal CombatHudKind Kind;

			internal VanillaVisualMask Mask;

			internal CanvasGroup HostGroup;

			internal float HostAlpha;

			internal bool HostInteractable;

			internal bool HostBlocks;

			internal bool Hidden;

			internal GameObject Instance;

			internal CombatHudVisual Visual;

			internal Vector2 OriginalPosition;

			internal Vector3 OriginalScale;

			internal ConfigEntry<float> X;

			internal ConfigEntry<float> Y;

			internal ConfigEntry<float> Scale;

			internal Image OriginalVorEmblem;

			internal bool OriginalVorEmblemEnabled;
		}

		private readonly GalaxyHudConfig _config;

		private readonly PrefabCatalog _catalog;

		private readonly PrefabViewBinder _binder;

		private readonly ManualLogSource _log;

		private readonly VikingsoldrepublicBridge _vor;

		private GameObject _localHost;

		private GameObject _localInstance;

		private CombatHudVisual _localVisual;

		private Player _localPlayer;

		private Vector2 _localAuthoredPosition;

		private Vector3 _localAuthoredScale;

		private ConfigEntry<float> _localX;

		private ConfigEntry<float> _localY;

		private ConfigEntry<float> _localScale;

		private readonly Dictionary<Character, Binding> _bindings = new Dictionary<Character, Binding>(64);

		private readonly List<Character> _stale = new List<Character>(64);

		private readonly Stack<GameObject>[] _pools = new Stack<GameObject>[3]
		{
			new Stack<GameObject>(32),
			new Stack<GameObject>(4),
			new Stack<GameObject>(16)
		};

		private Transform _poolRoot;

		private bool _enabled;

		private bool _overlayReady;

		private float _nextPoll;

		private static readonly Color Hostile = new Color(1f, 0.08f, 0.16f, 1f);

		private static readonly Color Friendly = new Color(0.18f, 0.92f, 0.32f, 1f);

		public bool HasBindings => _bindings.Count > 0;

		public CombatHudAttachmentManager(GalaxyHudConfig config, PrefabCatalog catalog, PrefabViewBinder binder, ManualLogSource log)
		{
			_config = config;
			_catalog = catalog;
			_binder = binder;
			_log = log;
			_vor = new VikingsoldrepublicBridge(log);
		}

		public void SetEnabled(bool enabled)
		{
			if (_enabled != enabled)
			{
				_enabled = enabled;
				if (!enabled)
				{
					DetachAll(returnToPool: true);
					DestroyLocalPlayer();
				}
				else
				{
					_nextPoll = 0f;
					AttachExisting(EnemyHud.instance);
				}
			}
		}

		public void SetOverlayReady(bool ready)
		{
			if (_overlayReady != ready)
			{
				_overlayReady = ready;
				_nextPoll = 0f;
				if (!ready)
				{
					DestroyLocalPlayer();
				}
			}
		}

		public void Poll(float now)
		{
			if (!_enabled || now < _nextPoll)
			{
				return;
			}
			_nextPoll = now + 1f / Mathf.Clamp(_config.CombatHudHz.Value, 1f, 20f);
			_vor.RefreshAvailability(now);
			RefreshLocalPlayer();
			EnemyHud instance = EnemyHud.instance;
			_stale.Clear();
			foreach (KeyValuePair<Character, Binding> binding in _bindings)
			{
				Binding value = binding.Value;
				if ((Object)(object)value.Character == (Object)null || (Object)(object)value.HudData?.m_gui == (Object)null || (Object)(object)instance == (Object)null || instance.m_huds == null || !instance.m_huds.TryGetValue(binding.Key, out var value2) || value2 != value.HudData)
				{
					_stale.Add(binding.Key);
				}
			}
			for (int i = 0; i < _stale.Count; i++)
			{
				Detach(_stale[i], returnToPool: true);
			}
			AttachExisting(instance);
			foreach (Binding value3 in _bindings.Values)
			{
				if (value3.HudData.m_gui.activeInHierarchy)
				{
					RefreshAll(value3);
				}
			}
		}

		public void AttachExisting(EnemyHud enemyHud)
		{
			if (!_enabled || (Object)(object)enemyHud == (Object)null || enemyHud.m_huds == null)
			{
				return;
			}
			foreach (KeyValuePair<Character, HudData> hud in enemyHud.m_huds)
			{
				Attach(enemyHud, hud.Key);
			}
		}

		public void OnShowHud(EnemyHud enemyHud, Character character)
		{
			if (_enabled)
			{
				Attach(enemyHud, character);
			}
		}

		public void Attach(EnemyHud enemyHud, Character character)
		{
			if (!_enabled || (Object)(object)enemyHud == (Object)null || (Object)(object)character == (Object)null || (Object)(object)character == (Object)(object)Player.m_localPlayer || enemyHud.m_huds == null || !enemyHud.m_huds.TryGetValue(character, out var value) || (Object)(object)value?.m_gui == (Object)null)
			{
				return;
			}
			if (_bindings.TryGetValue(character, out var value2))
			{
				if (value2.HudData == value)
				{
					RefreshVisibility(value2);
					return;
				}
				Detach(character, returnToPool: true);
			}
			CombatHudKind combatHudKind = ((character is Player) ? CombatHudKind.Player : (character.IsBoss() ? CombatHudKind.Boss : CombatHudKind.Enemy));
			bool flag = CombatHudPolicy.Hidden(combatHudKind, _config.HideEnemyHUD.Value, _config.HidePlayerHUD.Value);
			if (_overlayReady || flag)
			{
				CanvasGroup val = value.m_gui.GetComponent<CanvasGroup>();
				if ((Object)(object)val == (Object)null)
				{
					val = value.m_gui.AddComponent<CanvasGroup>();
				}
				string text = "Layout." + combatHudKind switch
				{
					CombatHudKind.Boss => "BGH_BossHud", 
					CombatHudKind.Player => "BGH_PlayerHud", 
					_ => "BGH_EnemyHud", 
				};
				Binding binding = new Binding
				{
					Character = character,
					HudData = value,
					Kind = combatHudKind,
					Mask = new VanillaVisualMask(value.m_gui),
					HostGroup = val,
					HostAlpha = val.alpha,
					HostInteractable = val.interactable,
					HostBlocks = val.blocksRaycasts,
					X = BalrondGalaxyHUDPlugin.SettingsFile.Bind<float>(text, "X", 0f, "Combat HUD horizontal offset."),
					Y = BalrondGalaxyHUDPlugin.SettingsFile.Bind<float>(text, "Y", 0f, "Combat HUD vertical offset."),
					Scale = BalrondGalaxyHUDPlugin.SettingsFile.Bind<float>(text, "Scale", 1f, "Combat HUD scale, 0.25 to 3.")
				};
				_bindings[character] = binding;
				RefreshAll(binding);
			}
		}

		private bool EnsureVisual(Binding b)
		{
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)b.Instance != (Object)null)
			{
				return true;
			}
			if (!_overlayReady || !_catalog.Load())
			{
				return false;
			}
			EnsurePoolRoot(EnemyHud.instance);
			Stack<GameObject> stack = _pools[(int)b.Kind];
			GameObject val = null;
			while (stack.Count > 0 && (Object)(object)val == (Object)null)
			{
				val = stack.Pop();
			}
			if ((Object)(object)val == (Object)null)
			{
				string name = ((b.Kind == CombatHudKind.Player) ? _catalog.PlayerHudPrefabName : ((b.Kind == CombatHudKind.Boss) ? "BGH_BossHud" : "BGH_EnemyHud"));
				val = _catalog.Instantiate(name, b.HudData.m_gui.transform);
				if ((Object)(object)val == (Object)null)
				{
					return false;
				}
				PrefabOverlayAssembler.EnsureNoRaycasts(val);
			}
			else
			{
				val.transform.SetParent(b.HudData.m_gui.transform, false);
			}
			val.transform.SetAsLastSibling();
			b.Instance = val;
			b.Visual = _binder.BindCombatHud(val);
			b.OriginalPosition = (((Object)(object)b.Visual.Root != (Object)null) ? b.Visual.Root.anchoredPosition : Vector2.zero);
			b.OriginalScale = (((Object)(object)b.Visual.Root != (Object)null) ? ((Transform)b.Visual.Root).localScale : Vector3.one);
			return true;
		}

		private void RefreshVisibility(Binding b)
		{
			bool flag = CombatHudPolicy.Hidden(b.Kind, _config.HideEnemyHUD.Value, _config.HidePlayerHUD.Value);
			bool flag2 = _overlayReady && !flag && EnsureVisual(b);
			if (flag || (flag2 && (b.Kind == CombatHudKind.Player || ((b.Kind == CombatHudKind.Boss) ? _config.SuppressVanillaBossHud.Value : _config.SuppressVanillaEnemyHud.Value))))
			{
				b.Mask.Hide();
			}
			else
			{
				RestoreOriginalVor(b);
				b.Mask.Restore();
			}
			if ((Object)(object)b.Instance != (Object)null && b.Instance.activeSelf != flag2)
			{
				b.Instance.SetActive(flag2);
			}
			if (flag)
			{
				if ((Object)(object)b.HostGroup != (Object)null)
				{
					b.HostGroup.alpha = 0f;
					b.HostGroup.interactable = false;
					b.HostGroup.blocksRaycasts = false;
				}
			}
			else if (b.Hidden)
			{
				RestoreHost(b);
			}
			b.Hidden = flag;
		}

		private static void RestoreHost(Binding b)
		{
			if (!((Object)(object)b.HostGroup == (Object)null))
			{
				b.HostGroup.alpha = b.HostAlpha;
				b.HostGroup.interactable = b.HostInteractable;
				b.HostGroup.blocksRaycasts = b.HostBlocks;
			}
		}

		private void RefreshAll(Binding b)
		{
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: 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_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: 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_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)b.Character == (Object)null || (Object)(object)b.HudData?.m_gui == (Object)null)
			{
				return;
			}
			RefreshVisibility(b);
			if (b.Hidden || b.Visual == null || !_overlayReady)
			{
				return;
			}
			CombatHudVisual visual = b.Visual;
			if ((Object)(object)visual.Root != (Object)null)
			{
				Vector2 val = b.OriginalPosition + new Vector2(b.X.Value, b.Y.Value);
				Vector3 val2 = b.OriginalScale * Mathf.Clamp(b.Scale.Value, 0.25f, 3f);
				if (visual.Root.anchoredPosition != val)
				{
					visual.Root.anchoredPosition = val;
				}
				if (((Transform)visual.Root).localScale != val2)
				{
					((Transform)visual.Root).localScale = val2;
				}
			}
			string hoverName = b.Character.GetHoverName();
			if (!visual.Initialized || !string.Equals(visual.LastRawName, hoverName, StringComparison.Ordinal))
			{
				visual.LastRawName = hoverName;
				visual.LastName = DirectPlayerDataSource.Localize(hoverName);
				if ((Object)(object)visual.Name != (Object)null)
				{
					visual.Name.text = visual.LastName;
				}
			}
			RefreshHealth(b);
			RefreshLevel(b);
			RefreshVikingsoldrepublic(b);
			visual.Initialized = true;
		}

		private void RefreshHealth(Binding b)
		{
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Expected O, but got Unknown
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Expected O, but got Unknown
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)b.Character == (Object)null || b.Visual == null || b.Hidden)
			{
				return;
			}
			CombatHudVisual visual = b.Visual;
			float num = Mathf.Max(0f, b.Character.GetHealth());
			float num2 = Mathf.Max(1f, b.Character.GetMaxHealth());
			int num3 = Mathf.CeilToInt(num);
			int num4 = Mathf.CeilToInt(num2);
			float num5 = Mathf.Clamp01(num / num2);
			if (!visual.Initialized || Mathf.Abs(visual.LastFill - num5) > 0.001f)
			{
				visual.LastFill = num5;
				if ((Object)(object)visual.Fill != (Object)null)
				{
					visual.Fill.fillAmount = num5;
				}
			}
			bool flag = false;
			bool tamed = b.Character.IsTamed();
			if (b.Kind == CombatHudKind.Player)
			{
				Player val = (Player)b.Character;
				flag = (Object)(object)((Character)val).m_nview != (Object)null && ((Character)val).m_nview.IsValid() && ((Character)val).IsPVPEnabled();
			}
			Player localPlayer = Player.m_localPlayer;
			bool hostileNpc = (Object)(object)localPlayer != (Object)null && BaseAI.IsEnemy((Character)(object)localPlayer, b.Character);
			bool samePath = b.Kind == CombatHudKind.Player && flag && (Object)(object)localPlayer != (Object)null && _config.EnableVikingsoldrepublic.Value && _vor.AreSamePath(localPlayer, (Player)b.Character);
			bool flag2 = CombatHudPolicy.Friendly(b.Kind, flag, tamed, hostileNpc, samePath);
			ApplyRelationshipVisuals(visual, flag2);
			Color val2 = (flag2 ? Friendly : Hostile);
			if (!visual.Initialized || visual.LastHealthColor != val2)
			{
				visual.LastHealthColor = val2;
				if ((Object)(object)visual.Fill != (Object)null)
				{
					((Graphic)visual.Fill).color = val2;
				}
			}
			bool value = _config.ShowExactEnemyHealth.Value;
			if (!visual.Initialized || visual.LastHealth != num3 || visual.LastMaxHealth != num4 || visual.LastShowExact != value)
			{
				visual.LastHealth = num3;
				visual.LastMaxHealth = num4;
				visual.LastShowExact = value;
				if ((Object)(object)visual.Health != (Object)null)
				{
					visual.Health.text = (value ? $"{num3} / {num4}" : string.Empty);
				}
			}
		}

		private static void ApplyRelationshipVisuals(CombatHudVisual visual, bool friendly)
		{
			if (visual != null)
			{
				Toggle(visual.FriendOrb, friendly);
				Toggle(visual.EnemyOrb, !friendly);
			}
		}

		private void RefreshLevel(Binding b)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Expected O, but got Unknown
			CombatHudVisual visual = b.Visual;
			if (visual == null || (Object)(object)b.Character == (Object)null || b.Hidden)
			{
				return;
			}
			bool flag = true;
			int level;
			if (b.Kind == CombatHudKind.Player)
			{
				flag = PlayerProgressService.TryGetRemoteLevel((Player)b.Character, out level);
			}
			else
			{
				level = Mathf.Max(1, b.Character.GetLevel());
			}
			bool flag2 = ((b.Kind == CombatHudKind.Boss) ? (level > 2) : (b.Kind == CombatHudKind.Player || level > 1 || _config.ShowEnemyLevelAtLevelOne.Value));
			if (!visual.Initialized || visual.LastLevel != level || visual.LastLevelKnown != flag)
			{
				visual.LastLevel = level;
				visual.LastLevelKnown = flag;
				if ((Object)(object)visual.Level != (Object)null)
				{
					visual.Level.text = (flag ? level.ToString() : "--");
				}
			}
			visual.LastLevelVisible = flag2;
			if (b.Kind == CombatHudKind.Boss)
			{
				if ((Object)(object)visual.LevelRoot != (Object)null && !((Component)visual.LevelRoot).gameObject.activeSelf)
				{
					((Component)visual.LevelRoot).gameObject.SetActive(true);
				}
				if ((Object)(object)visual.Level != (Object)null && ((Component)visual.Level).gameObject.activeSelf != flag2)
				{
					((Component)visual.Level).gameObject.SetActive(flag2);
				}
			}
			else if ((Object)(object)visual.LevelRoot != (Object)null && ((Component)visual.LevelRoot).gameObject.activeSelf != flag2)
			{
				((Component)visual.LevelRoot).gameObject.SetActive(flag2);
			}
		}

		private static void Toggle(RectTransform root, bool visible)
		{
			if ((Object)(object)root != (Object)null && ((Component)root).gameObject.activeSelf != visible)
			{
				((Component)root).gameObject.SetActive(visible);
			}
		}

		private void UpdateOptionalVisuals(CombatHudVisual v, Player player)
		{
			if (v != null)
			{
				VikingsoldrepublicBridge.PathVisuals result = default(VikingsoldrepublicBridge.PathVisuals);
				bool flag = _config.EnableVikingsoldrepublic.Value && _vor.TryRead(player, _config.ShowRank.Value && (Object)(object)v.RankRoot != (Object)null && (Object)(object)v.RankText != (Object)null, _config.ShowEmblem.Value && (Object)(object)v.EmblemRoot != (Object)null && (Object)(object)v.EmblemIcon != (Object)null, out result);
				bool flag2 = flag && _config.ShowFaction.Value && (Object)(object)v.FactionRoot != (Object)null && (Object)(object)v.FactionText != (Object)null && !string.IsNullOrWhiteSpace(result.Faction);
				bool flag3 = flag && _config.ShowRank.Value && (Object)(object)v.RankRoot != (Object)null && (Object)(object)v.RankText != (Object)null && !string.IsNullOrWhiteSpace(result.Rank);
				bool flag4 = flag && _config.ShowEmblem.Value && (Object)(object)v.EmblemRoot != (Object)null && (Object)(object)v.EmblemIcon != (Object)null && (Object)(object)result.Emblem != (Object)null;
				if (flag2 && !string.Equals(v.LastFaction, result.Faction, StringComparison.Ordinal))
				{
					v.FactionText.text = result.Faction;
					v.LastFaction = result.Faction;
				}
				if (flag3 && !string.Equals(v.LastRank, result.Rank, StringComparison.Ordinal))
				{
					v.RankText.text = result.Rank;
					v.LastRank = result.Rank;
				}
				if (flag4 && (Object)(object)v.LastEmblem != (Object)(object)result.Emblem)
				{
					v.EmblemIcon.sprite = result.Emblem;
					v.LastEmblem = result.Emblem;
				}
				Toggle(v.FactionRoot, flag2);
				Toggle(v.RankRoot, flag3);
				Toggle(v.EmblemRoot, flag4);
				v.LastFactionVisible = flag2;
				v.LastRankVisible = flag3;
				v.LastEmblemVisible = flag4;
			}
		}

		private void RefreshVikingsoldrepublic(Binding b)
		{
			CombatHudVisual visual = b.Visual;
			Character character = b.Character;
			UpdateOptionalVisuals(visual, (Player)(object)((character is Player) ? character : null));
			bool flag = _config.SuppressOriginalVorEmblem.Value && b.Visual != null && b.Visual.LastEmblemVisible && (Object)(object)b.Instance != (Object)null && b.Instance.activeInHierarchy;
			if (flag && (Object)(object)b.OriginalVorEmblem == (Object)null && (Object)(object)b.HudData?.m_gui != (Object)null)
			{
				Transform val = FindChildByName(b.HudData.m_gui.transform, "VOR_PathEmblem", b.Instance.transform);
				if ((Object)(object)val != (Object)null)
				{
					b.OriginalVorEmblem = ((Component)val).GetComponent<Image>();
					if ((Object)(object)b.OriginalVorEmblem != (Object)null)
					{
						b.OriginalVorEmblemEnabled = ((Behaviour)b.OriginalVorEmblem).enabled;
					}
				}
			}
			if ((Object)(object)b.OriginalVorEmblem != (Object)null)
			{
				if (flag)
				{
					((Behaviour)b.OriginalVorEmblem).enabled = false;
				}
				else
				{
					((Behaviour)b.OriginalVorEmblem).enabled = b.OriginalVorEmblemEnabled;
				}
			}
		}

		private static Transform FindChildByName(Transform root, string name, Transform ignore)
		{
			if ((Object)(object)root == (Object)null || (Object)(object)root == (Object)(object)ignore)
			{
				return null;
			}
			if (string.Equals(((Object)root).name, name, StringComparison.Ordinal))
			{
				return root;
			}
			for (int i = 0; i < root.childCount; i++)
			{
				Transform val = FindChildByName(root.GetChild(i), name, ignore);
				if ((Object)(object)val != (Object)null)
				{
					return val;
				}
			}
			return null;
		}

		private void RestoreOriginalVor(Binding b)
		{
			if ((Object)(object)b.OriginalVorEmblem != (Object)null)
			{
				((Behaviour)b.OriginalVorEmblem).enabled = b.OriginalVorEmblemEnabled;
			}
			b.OriginalVorEmblem = null;
		}

		public void RefreshHealth(Character character)
		{
			if ((Object)(object)character != (Object)null && _bindings.TryGetValue(character, out var value))
			{
				RefreshHealth(value);
			}
		}

		public void RefreshLevel(Character character)
		{
			if ((Object)(object)character != (Object)null && _bindings.TryGetValue(character, out var value))
			{
				RefreshLevel(value);
				RefreshHealth(value);
			}
		}

		public void OnRemoveHud(Character character)
		{
			Detach(character, returnToPool: true);
		}

		public void Detach(Character character, bool returnToPool)
		{
			if (character != null && _bindings.TryGetValue(character, out var value))
			{
				_bindings.Remove(character);
				ReleaseBinding(value, returnToPool);
			}
		}

		private void ReleaseBinding(Binding b, bool pool)
		{
			RestoreHost(b);
			RestoreOriginalVor(b);
			b.Mask.Restore();
			ReleaseVisual(b, pool);
		}

		private void ReleaseVisual(Binding b, bool pool)
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)b.Instance == (Object)null)
			{
				b.Instance = null;
				b.Visual = null;
				return;
			}
			if ((Object)(object)b.Visual?.Root != (Object)null)
			{
				b.Visual.Root.anchoredPosition = b.OriginalPosition;
				((Transform)b.Visual.Root).localScale = b.OriginalScale;
			}
			RestoreOriginalVor(b);
			b.Instance.SetActive(false);
			Stack<GameObject> stack = _pools[(int)b.Kind];
			int num = ((b.Kind == CombatHudKind.Boss) ? 4 : (