Decompiled source of NilsHUD v1.0.6

plugins/NilsHUD.dll

Decompiled 5 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using GameNetcodeStuff;
using HarmonyLib;
using LethalConfig.ConfigItems;
using LethalConfig.ConfigItems.Options;
using Microsoft.CodeAnalysis;
using NilsHUD;
using UnityEngine;
using UnityEngine.SceneManagement;
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: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("NilsHUD")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("NilsHUD")]
[assembly: AssemblyTitle("NilsHUD")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
[HarmonyPatch(typeof(PlayerControllerB), "LateUpdate")]
public static class HealthBarPatch
{
	private static Dictionary<PlayerControllerB, Vector3> lastPlayerPositions = new Dictionary<PlayerControllerB, Vector3>();

	private const float POSITION_THRESHOLD = 0.1f;

	public static void Postfix(PlayerControllerB __instance)
	{
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		//IL_0070: Unknown result type (might be due to invalid IL or missing references)
		if (!PluginConfig.ConfigEnableHealthBar.Value)
		{
			return;
		}
		HealthBar healthBar = HealthBar.GetHealthBar(__instance);
		if ((Object)(object)healthBar != (Object)null)
		{
			Vector3 position = ((Component)__instance).transform.position;
			if (!lastPlayerPositions.ContainsKey(__instance) || Vector3.Distance(position, lastPlayerPositions[__instance]) > 0.1f)
			{
				healthBar.UpdateHealthBarPosition();
				lastPlayerPositions[__instance] = position;
			}
		}
	}
}
public class HealthChangeHelper : MonoBehaviour
{
	private void Awake()
	{
		Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
	}

	public void HandleHealthChange(Image healthBarImage, Image redHealthBarImage, float currentHealth, float maxHealth, float previousHealth)
	{
		Debug.Log((object)$"HandleHealthChange called, healthBarImage: {healthBarImage}, redHealthBarImage: {redHealthBarImage}");
		float num3 = (redHealthBarImage.fillAmount = (healthBarImage.fillAmount = currentHealth / maxHealth));
		if (currentHealth < previousHealth)
		{
			Debug.Log((object)$"Player is being damaged, fillAmount: {num3}");
		}
		else if (currentHealth > previousHealth)
		{
			Debug.Log((object)$"Player is being healed, fillAmount: {num3}");
		}
	}
}
public class HealthBar : MonoBehaviour
{
	[HarmonyPatch(typeof(PlayerControllerB), "Start")]
	public static class AddHealthBarPatch
	{
		public static void Postfix(PlayerControllerB __instance)
		{
			if ((Object)(object)__instance != (Object)(object)PlayerUtils.GetPlayerControllerB() && healthBarList.Count < initialHealthBarCount)
			{
				GetHealthBar(__instance);
			}
		}
	}

	private PlayerControllerB player;

	public Image healthBarImage;

	public Image redHealthBarImage;

	private CanvasGroup healthBarAlpha;

	private CanvasGroup redHealthBarAlpha;

	private bool isLocalPlayer;

	private GameObject healthBarObject;

	private float lastHealth;

	private float fadeOutDelay;

	private float fadeOutTimer = 0f;

	private RectTransform healthBarTransform;

	private RectTransform redHealthBarTransform;

	private RectTransform healthBarFillTransform;

	private static PlayerControllerB localPlayerController;

	private static Queue<HealthBar> healthBarPool = new Queue<HealthBar>();

	private float previousHealth;

	private Transform usernameBillboard;

	private Transform playerGlobalHead;

	private CanvasGroup usernameAlpha;

	private float fadeInRate;

	private float fadeOutRate;

	private HealthChangeHelper healthChangeHelper;

	private static int initialHealthBarCount = 4;

	private static List<HealthBar> healthBarList = new List<HealthBar>();

	private static Dictionary<PlayerControllerB, HealthBar> playerHealthBarMap = new Dictionary<PlayerControllerB, HealthBar>();

	public static HealthBar GetHealthBar(PlayerControllerB player)
	{
		//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e8: Expected O, but got Unknown
		if ((Object)(object)localPlayerController == (Object)null)
		{
			localPlayerController = PlayerUtils.GetPlayerControllerB();
		}
		if ((Object)(object)player == (Object)(object)localPlayerController)
		{
			return null;
		}
		if (playerHealthBarMap.TryGetValue(player, out HealthBar value))
		{
			if ((Object)(object)value != (Object)null && ((Component)value).gameObject.activeSelf)
			{
				return value;
			}
			playerHealthBarMap.Remove(player);
		}
		HealthBar healthBar = healthBarList.Find((HealthBar hb) => !((Component)hb).gameObject.activeSelf);
		if ((Object)(object)healthBar != (Object)null)
		{
			healthBar.player = player;
			((Component)healthBar).gameObject.SetActive(true);
			playerHealthBarMap[player] = healthBar;
			return healthBar;
		}
		GameObject val = new GameObject("HealthBar");
		val.SetActive(false);
		HealthBar healthBar2 = val.AddComponent<HealthBar>();
		healthBar2.player = player;
		healthBar2.InitializeHealthBar();
		val.SetActive(true);
		healthBarList.Add(healthBar2);
		playerHealthBarMap[player] = healthBar2;
		return healthBar2;
	}

	private void Awake()
	{
		//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f0: Expected O, but got Unknown
		if (!PluginConfig.ConfigEnableHealthBar.Value)
		{
			((Component)this).gameObject.SetActive(false);
			return;
		}
		isLocalPlayer = (Object)(object)player == (Object)(object)localPlayerController;
		lastHealth = player.health;
		fadeOutDelay = PluginConfig.ConfigFadeOutDelay.Value;
		usernameBillboard = player.usernameBillboard;
		playerGlobalHead = player.playerGlobalHead;
		usernameAlpha = player.usernameAlpha;
		fadeInRate = 1f / PluginConfig.ConfigFadeInDuration.Value;
		fadeOutRate = 1f / PluginConfig.ConfigFadeOutDuration.Value;
		previousHealth = player.health;
		GameObject val = GameObject.Find("HealthChangeHelper");
		if ((Object)(object)val == (Object)null)
		{
			val = new GameObject("HealthChangeHelper");
			healthChangeHelper = val.AddComponent<HealthChangeHelper>();
			Debug.Log((object)"Created new HealthChangeHelper instance");
		}
		else
		{
			healthChangeHelper = val.GetComponent<HealthChangeHelper>();
			Debug.Log((object)"Found existing HealthChangeHelper instance");
		}
	}

	private void InitializeHealthBar()
	{
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: Expected O, but got Unknown
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_015e: 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_019e: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01de: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_021e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0243: Unknown result type (might be due to invalid IL or missing references)
		//IL_0278: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ac: Unknown result type (might be due to invalid IL or missing references)
		if (PluginConfig.ConfigEnableHealthBar.Value && (Object)(object)healthBarObject == (Object)null)
		{
			healthBarObject = new GameObject("HealthBarObject");
			healthBarObject.transform.SetParent(((Component)player.usernameBillboard).transform, false);
			redHealthBarImage = new GameObject("RedHealthBar").AddComponent<Image>();
			((Component)redHealthBarImage).transform.SetParent(healthBarObject.transform, false);
			redHealthBarAlpha = ((Component)redHealthBarImage).gameObject.AddComponent<CanvasGroup>();
			redHealthBarAlpha.alpha = 0f;
			healthBarImage = new GameObject("HealthBar").AddComponent<Image>();
			((Component)healthBarImage).transform.SetParent(healthBarObject.transform, false);
			healthBarAlpha = ((Component)healthBarImage).gameObject.AddComponent<CanvasGroup>();
			healthBarAlpha.alpha = 0f;
			Debug.Log((object)$"Initialized health bar: healthBarImage={healthBarImage}, redHealthBarImage={redHealthBarImage}");
			redHealthBarTransform = ((Component)redHealthBarImage).GetComponent<RectTransform>();
			healthBarTransform = ((Component)healthBarImage).GetComponent<RectTransform>();
			redHealthBarTransform.anchorMin = new Vector2(0.5f, 0f);
			redHealthBarTransform.anchorMax = new Vector2(0.5f, 0f);
			redHealthBarTransform.sizeDelta = new Vector2(PluginConfig.ConfigRedHealthBarWidth.Value, PluginConfig.ConfigRedHealthBarHeight.Value);
			redHealthBarTransform.anchoredPosition = new Vector2(PluginConfig.ConfigHealthBarPositionX.Value, PluginConfig.ConfigHealthBarPositionY.Value);
			healthBarTransform.anchorMin = new Vector2(0f, 0f);
			healthBarTransform.anchorMax = new Vector2(1f, 0f);
			healthBarTransform.sizeDelta = new Vector2(PluginConfig.ConfigHealthBarWidth.Value, PluginConfig.ConfigHealthBarHeight.Value);
			healthBarTransform.anchoredPosition = new Vector2(PluginConfig.ConfigHealthBarPositionX.Value, PluginConfig.ConfigHealthBarPositionY.Value);
			string value = PluginConfig.ConfigHealthBarColorHex.Value;
			Color color = default(Color);
			if (ColorUtility.TryParseHtmlString("#" + value, ref color))
			{
				((Graphic)healthBarImage).color = color;
			}
			string value2 = PluginConfig.ConfigRedHealthBarColorHex.Value;
			Color color2 = default(Color);
			if (ColorUtility.TryParseHtmlString("#" + value2, ref color2))
			{
				((Graphic)redHealthBarImage).color = color2;
			}
		}
	}

	private void LateUpdate()
	{
		if (PluginConfig.ConfigEnableHealthBar.Value)
		{
			UpdateHealthBarFade();
			if ((float)player.health != lastHealth)
			{
				OnHealthChanged();
			}
		}
	}

	private void OnHealthChanged()
	{
		//IL_00af: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
		if (PluginConfig.ConfigEnableHealthBar.Value)
		{
			float num = player.health;
			float num2 = 100f;
			float num3 = lastHealth;
			Debug.Log((object)$"OnHealthChanged called for player: {((Object)player).name}, currentHealth: {num}, previousHealth: {num3}");
			if ((Object)(object)player != (Object)(object)localPlayerController && num != num3)
			{
				healthChangeHelper.HandleHealthChange(healthBarImage, redHealthBarImage, num, num2, num3);
				float num4 = num / num2;
				healthBarTransform.anchorMax = new Vector2(num4, healthBarTransform.anchorMax.y);
				float num5 = num4 * PluginConfig.ConfigHealthBarWidth.Value;
				healthBarTransform.sizeDelta = new Vector2(num5, healthBarTransform.sizeDelta.y);
				lastHealth = num;
			}
		}
	}

	private void UpdateHealthBarFade()
	{
		if (isLocalPlayer)
		{
			healthBarAlpha.alpha = 0f;
			redHealthBarAlpha.alpha = 0f;
			return;
		}
		if (usernameAlpha.alpha > 0f)
		{
			fadeOutTimer = 0f;
			if (healthBarAlpha.alpha < 1f)
			{
				CanvasGroup obj = healthBarAlpha;
				obj.alpha += Time.deltaTime * fadeInRate;
				healthBarAlpha.alpha = Mathf.Clamp01(healthBarAlpha.alpha);
			}
			if (redHealthBarAlpha.alpha < 1f)
			{
				CanvasGroup obj2 = redHealthBarAlpha;
				obj2.alpha += Time.deltaTime * fadeInRate;
				redHealthBarAlpha.alpha = Mathf.Clamp01(redHealthBarAlpha.alpha);
			}
			return;
		}
		fadeOutTimer += Time.deltaTime;
		if (fadeOutTimer >= fadeOutDelay)
		{
			CanvasGroup obj3 = healthBarAlpha;
			obj3.alpha -= Time.deltaTime * fadeOutRate;
			healthBarAlpha.alpha = Mathf.Clamp01(healthBarAlpha.alpha);
			CanvasGroup obj4 = redHealthBarAlpha;
			obj4.alpha -= Time.deltaTime * fadeOutRate;
			redHealthBarAlpha.alpha = Mathf.Clamp01(redHealthBarAlpha.alpha);
			if (healthBarAlpha.alpha <= 0f && redHealthBarAlpha.alpha <= 0f)
			{
				healthBarPool.Enqueue(this);
				((Component)this).gameObject.SetActive(false);
			}
		}
	}

	public void UpdateHealthBarPosition()
	{
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		if (PluginConfig.ConfigEnableHealthBar.Value)
		{
			Vector3 position = playerGlobalHead.position;
			usernameBillboard.position = new Vector3(position.x, position.y + 0.55f, position.z);
		}
	}
}
[HarmonyPatch(typeof(UnlockableSuit), "SwitchSuitForPlayer")]
public static class UnlockableSuitPatch
{
	public static class SuitColorCache
	{
		private static Dictionary<int, Color> colorCache = new Dictionary<int, Color>();

		private static Texture2D? readableTexture;

		public static Color GetSuitColor(int suitID, Material suitMaterial)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			if (!colorCache.TryGetValue(suitID, out var value))
			{
				value = GetAverageColorFromMaterial(suitMaterial);
				colorCache[suitID] = value;
			}
			return value;
		}

		public static Color GetAverageColorFromMaterial(Material material)
		{
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Expected O, but got Unknown
			if ((Object)(object)material != (Object)null)
			{
				Texture mainTexture = material.mainTexture;
				Texture2D val = (Texture2D)(object)((mainTexture is Texture2D) ? mainTexture : null);
				if (val != null)
				{
					RenderTexture temporary = RenderTexture.GetTemporary(((Texture)val).width, ((Texture)val).height);
					Graphics.Blit((Texture)(object)val, temporary);
					RenderTexture active = RenderTexture.active;
					RenderTexture.active = temporary;
					if ((Object)(object)readableTexture == (Object)null || ((Texture)readableTexture).width != ((Texture)val).width || ((Texture)readableTexture).height != ((Texture)val).height)
					{
						if ((Object)(object)readableTexture != (Object)null)
						{
							Object.Destroy((Object)(object)readableTexture);
						}
						readableTexture = new Texture2D(((Texture)val).width, ((Texture)val).height);
					}
					readableTexture.ReadPixels(new Rect(0f, 0f, (float)((Texture)temporary).width, (float)((Texture)temporary).height), 0, 0);
					readableTexture.Apply();
					Color averageColorFromTexture = GetAverageColorFromTexture(readableTexture);
					RenderTexture.active = active;
					RenderTexture.ReleaseTemporary(temporary);
					return averageColorFromTexture;
				}
			}
			return Color.gray;
		}

		private static Color GetAverageColorFromTexture(Texture2D texture)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			Color32[] pixels = texture.GetPixels32();
			int num = Mathf.Min(pixels.Length, 1000);
			int num2 = pixels.Length / num;
			float num3 = 0f;
			Color val = Color.clear;
			for (int i = 0; i < pixels.Length; i += num2)
			{
				Color32 val2 = pixels[i];
				float num4 = (float)(val2.r + val2.g + val2.b) / 765f;
				float num5 = Mathf.Clamp01(num4 * 2f);
				val += Color32.op_Implicit(val2) * num5;
				num3 += num5;
			}
			if (num3 > 0f)
			{
				Color val3 = val / num3;
				float value = PluginConfig.ConfigSuitOverlayBrightness.Value;
				return Color.Lerp(Color.black, val3, value);
			}
			return Color.gray;
		}
	}

	private static HUDManager? hudManager;

	private static StartOfRound? startOfRound;

	[HarmonyPostfix]
	public static void SwitchSuitForPlayer_Postfix(PlayerControllerB player, int suitID)
	{
		if ((Object)(object)player != (Object)null && PluginConfig.ConfigEnableSuitColorOverlay.Value)
		{
			UpdateHealthOverlayColor(player, suitID);
		}
	}

	public static void UpdateHealthOverlayColor(PlayerControllerB player, int suitID)
	{
		//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_009d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)hudManager == (Object)null)
		{
			hudManager = HUDManager.Instance;
		}
		if (!((Object)(object)hudManager != (Object)null))
		{
			return;
		}
		CanvasGroup selfRedCanvasGroup = hudManager.selfRedCanvasGroup;
		Image val = default(Image);
		if (selfRedCanvasGroup == null || !((Component)selfRedCanvasGroup).TryGetComponent<Image>(ref val))
		{
			return;
		}
		Color color = default(Color);
		if (PluginConfig.ConfigEnableSuitColorOverlay.Value)
		{
			if ((Object)(object)startOfRound == (Object)null)
			{
				startOfRound = StartOfRound.Instance;
			}
			Material suitMaterial = startOfRound.unlockablesList.unlockables[suitID].suitMaterial;
			Color suitColor = SuitColorCache.GetSuitColor(suitID, suitMaterial);
			((Graphic)val).color = suitColor;
		}
		else if (ColorUtility.TryParseHtmlString("#" + PluginConfig.ConfigOverlayColorHex.Value, ref color))
		{
			((Graphic)val).color = color;
		}
		else
		{
			((Graphic)val).color = Color.red;
		}
	}

	public static void PrecomputeSuitColors()
	{
		//IL_008b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0092: Expected O, but got Unknown
		//IL_0096: Unknown result type (might be due to invalid IL or missing references)
		//IL_009b: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)startOfRound == (Object)null)
		{
			startOfRound = StartOfRound.Instance;
		}
		foreach (UnlockableItem unlockable in startOfRound.unlockablesList.unlockables)
		{
			if (((object)unlockable).GetType().Name == "UnlockableSuit")
			{
				int num = (int)((object)unlockable).GetType().GetProperty("suitID").GetValue(unlockable);
				Material suitMaterial = (Material)((object)unlockable).GetType().GetProperty("suitMaterial").GetValue(unlockable);
				Color suitColor = SuitColorCache.GetSuitColor(num, suitMaterial);
				Debug.Log((object)$"Precomputed color for suit ID {num}: {suitColor}");
			}
		}
	}
}
namespace NilsHUD
{
	public static class PlayerUtils
	{
		private static PlayerControllerB? localPlayerController;

		public static PlayerControllerB? GetPlayerControllerB()
		{
			if ((Object)(object)localPlayerController == (Object)null)
			{
				if ((Object)(object)GameNetworkManager.Instance != (Object)null)
				{
					localPlayerController = GameNetworkManager.Instance.localPlayerController;
					PlayerControllerB? obj = localPlayerController;
					Debug.Log((object)("[NilsHUD] GetPlayerControllerB returned: " + (((obj != null) ? ((Object)obj).name : null) ?? "null")));
				}
				else
				{
					Debug.LogError((object)"[NilsHUD] GameNetworkManager.Instance is null.");
				}
			}
			return localPlayerController;
		}
	}
	public static class HUDManagerPatch
	{
		private const string HealFromCriticalTrigger = "HealFromCritical";

		private const string CriticalHitTrigger = "CriticalHit";

		private const string SmallHitTrigger = "SmallHit";

		private const int CriticalHealthThreshold = 20;

		private static bool playerIsCriticallyInjured;

		private static float targetFillAmount;

		[HarmonyPatch(typeof(HUDManager), "Awake")]
		[HarmonyPostfix]
		public static void AwakePostfix()
		{
			InitializeHealthOverlay();
		}

		[HarmonyPatch(typeof(HUDManager), "UpdateHealthUI")]
		[HarmonyPrefix]
		public static bool UpdateHealthUIPrefix(int health, bool hurtPlayer = true)
		{
			HUDManager instance = HUDManager.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				Debug.LogError((object)"HUDManager instance is null!");
				return true;
			}
			if ((Object)(object)instance.selfRedCanvasGroup == (Object)null)
			{
				Debug.LogError((object)"selfRedCanvasGroup is null!");
				return true;
			}
			Image component = ((Component)instance.selfRedCanvasGroup).GetComponent<Image>();
			if ((Object)(object)component == (Object)null)
			{
				Debug.LogError((object)"Image component not found on selfRedCanvasGroup!");
				return false;
			}
			PlayerControllerB playerControllerB = PlayerUtils.GetPlayerControllerB();
			if ((Object)(object)playerControllerB != (Object)null && playerControllerB.isPlayerDead)
			{
				return false;
			}
			if (PluginConfig.ConfigStartFullyFilled.Value)
			{
				targetFillAmount = (100f - (float)health) / 100f;
			}
			else
			{
				targetFillAmount = (float)health / 100f;
			}
			if (!Object.op_Implicit((Object)(object)((Component)instance).gameObject.GetComponent<HealthIndicatorInitializer>()))
			{
				((Component)instance).gameObject.AddComponent<HealthIndicatorInitializer>();
				if (PluginConfig.ConfigStartFullyFilled.Value)
				{
					component.fillAmount = 1f;
				}
				else
				{
					component.fillAmount = 0f;
				}
			}
			float num;
			float num2;
			if (PluginConfig.ConfigStartFullyFilled.Value)
			{
				num = ((component.fillAmount == 0f) ? 1f : component.fillAmount);
				num2 = (float)health / 100f;
			}
			else
			{
				num = component.fillAmount;
				num2 = (100f - (float)health) / 100f;
			}
			if (Mathf.Approximately(num, num2) && !PlayerUtils.GetPlayerControllerB().isPlayerDead)
			{
				return false;
			}
			component.fillAmount = num;
			ConfigureHealthImage(component, health, playerControllerB);
			StartHealthMonitoring(instance);
			StartSmoothFillTransition(instance, component, num);
			if ((Object)(object)instance.HUDAnimator == (Object)null)
			{
				Debug.LogError((object)"HUDAnimator is null!");
				return false;
			}
			HandlePlayerHealthState(instance, health, hurtPlayer);
			return false;
		}

		public static void InitializeHealthOverlay()
		{
			HUDManager instance = HUDManager.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				Debug.LogError((object)"HUDManager instance is null!");
				return;
			}
			if ((Object)(object)instance.selfRedCanvasGroup == (Object)null)
			{
				Debug.LogError((object)"selfRedCanvasGroup is null!");
				return;
			}
			Image component = ((Component)instance.selfRedCanvasGroup).GetComponent<Image>();
			if ((Object)(object)component == (Object)null)
			{
				Debug.LogError((object)"Image component not found on selfRedCanvasGroup!");
				return;
			}
			instance.selfRedCanvasGroup.alpha = 1f;
			PlayerControllerB playerControllerB = PlayerUtils.GetPlayerControllerB();
			int num = (((Object)(object)playerControllerB != (Object)null) ? playerControllerB.health : 100);
			if (PluginConfig.ConfigStartFullyFilled.Value)
			{
				component.fillAmount = ((num == 100) ? 1f : 0f);
				instance.selfRedCanvasGroup.alpha = (float)num / 100f;
			}
			else
			{
				component.fillAmount = (float)num / 100f;
				instance.selfRedCanvasGroup.alpha = (100f - (float)num) / 100f;
			}
			ConfigureHealthImage(component, num, playerControllerB);
		}

		private static void StartHealthMonitoring(HUDManager hudManager)
		{
			if (!Object.op_Implicit((Object)(object)((Component)hudManager).gameObject.GetComponent<HealthMonitorCoroutine>()))
			{
				((Component)hudManager).gameObject.AddComponent<HealthMonitorCoroutine>();
			}
		}

		private static void StartSmoothFillTransition(HUDManager hudManager, Image image, float previousFillAmount)
		{
			if ((Object)(object)hudManager == (Object)null)
			{
				Debug.LogError((object)"HUDManager instance is null!");
				return;
			}
			((MonoBehaviour)hudManager).StopAllCoroutines();
			if (PluginConfig.ConfigEnableFillAnimation.Value)
			{
				float duration = Mathf.Clamp(PluginConfig.ConfigFillTransitionDuration.Value, 0.01f, 1f);
				bool drainEffect = !PluginConfig.ConfigStartFullyFilled.Value;
				((MonoBehaviour)hudManager).StartCoroutine(SmoothFillTransition(image, previousFillAmount, targetFillAmount, duration, drainEffect));
			}
			else
			{
				image.fillAmount = targetFillAmount;
			}
			if (PluginConfig.ConfigEnableFadeOut.Value)
			{
				float fadeOutDuration = Mathf.Clamp(PluginConfig.ConfigFadeOutDuration.Value, 0f, 5f);
				float smoothFillDuration = Mathf.Clamp(PluginConfig.ConfigFillTransitionDuration.Value, 0.01f, 1f);
				((MonoBehaviour)hudManager).StartCoroutine(SmoothFillAndFadeTransition(image, previousFillAmount, targetFillAmount, smoothFillDuration, fadeOutDuration));
			}
		}

		private static IEnumerator StartFadeOutEffect(Image image, float fadeOutDuration)
		{
			float elapsedTime = 0f;
			Color startColor = ((Graphic)image).color;
			float targetAlpha = Mathf.Clamp01(1f - PluginConfig.ConfigFadeOutIntensity.Value);
			Color targetColor = new Color(startColor.r, startColor.g, startColor.b, targetAlpha);
			while (elapsedTime < fadeOutDuration)
			{
				float t = elapsedTime / fadeOutDuration;
				((Graphic)image).color = Color.Lerp(startColor, targetColor, t);
				elapsedTime += Time.deltaTime;
				yield return null;
			}
			((Graphic)image).color = targetColor;
		}

		private static IEnumerator SmoothFillTransition(Image image, float startFillAmount, float targetFillAmount, float duration, bool drainEffect = false)
		{
			float elapsedTime = 0f;
			Debug.LogFormat("Start fill amount: {0}", new object[1] { startFillAmount });
			Debug.LogFormat("Target fill amount: {0}", new object[1] { targetFillAmount });
			Debug.LogFormat("Fill duration: {0}", new object[1] { duration });
			if (Mathf.Approximately(startFillAmount, targetFillAmount))
			{
				duration = Mathf.Max(duration, 0.1f);
			}
			while (elapsedTime < duration)
			{
				float t = elapsedTime / duration;
				float smoothT = Mathf.SmoothStep(0f, 1f, t);
				if (PluginConfig.ConfigStartFullyFilled.Value)
				{
					if (drainEffect)
					{
						image.fillAmount = Mathf.Lerp(startFillAmount, targetFillAmount, smoothT);
					}
					else
					{
						image.fillAmount = Mathf.Lerp(startFillAmount, targetFillAmount, smoothT);
					}
				}
				else if (drainEffect)
				{
					image.fillAmount = Mathf.Lerp(startFillAmount, targetFillAmount, smoothT);
				}
				else
				{
					image.fillAmount = Mathf.Lerp(startFillAmount, targetFillAmount, smoothT);
				}
				elapsedTime += Time.deltaTime;
				yield return null;
			}
			image.fillAmount = targetFillAmount;
		}

		private static IEnumerator SmoothFillAndFadeTransition(Image image, float startFillAmount, float targetFillAmount, float smoothFillDuration, float fadeOutDuration)
		{
			Debug.LogFormat("Start fill amount: {0}", new object[1] { image.fillAmount });
			Debug.LogFormat("Target fill amount: {0}", new object[1] { targetFillAmount });
			Debug.LogFormat("Fill duration: {0}", new object[1] { smoothFillDuration });
			Debug.LogFormat("Fade-out duration: {0}", new object[1] { fadeOutDuration });
			if (Mathf.Approximately(image.fillAmount, targetFillAmount))
			{
				smoothFillDuration = Mathf.Max(smoothFillDuration, 0.1f);
			}
			yield return SmoothFillTransition(image, startFillAmount, targetFillAmount, smoothFillDuration);
			float elapsedTime = 0f;
			Color startColor = ((Graphic)image).color;
			float targetAlpha = Mathf.Clamp01(1f - PluginConfig.ConfigFadeOutIntensity.Value);
			Color targetColor = new Color(startColor.r, startColor.g, startColor.b, targetAlpha);
			Debug.Log((object)$"Starting fade-out effect. Start color: {startColor}, Target color: {targetColor}, Fade-out duration: {fadeOutDuration}");
			while (elapsedTime < fadeOutDuration)
			{
				float t = elapsedTime / fadeOutDuration;
				((Graphic)image).color = Color.Lerp(startColor, targetColor, t);
				Debug.Log((object)$"Fade-out effect progress: {t}, Current color: {((Graphic)image).color}");
				elapsedTime += Time.deltaTime;
				yield return null;
			}
			((Graphic)image).color = targetColor;
			Debug.Log((object)$"Fade-out effect completed. Final color: {((Graphic)image).color}");
		}

		private static void ConfigureHealthImage(Image image, int health, PlayerControllerB controllerInstance)
		{
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Invalid comparison between Unknown and I4
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			if (PluginConfig.ConfigStartFullyFilled.Value)
			{
				targetFillAmount = (float)health / 100f;
				if (health == 100)
				{
					image.fillAmount = 1f;
				}
				else
				{
					image.fillAmount = 0f;
				}
			}
			else
			{
				targetFillAmount = (100f - (float)health) / 100f;
				image.fillAmount = targetFillAmount;
			}
			if ((int)image.type != 3)
			{
				image.type = (Type)3;
				image.fillMethod = (FillMethod)1;
			}
			if (PluginConfig.ConfigFillDirection.Value == FillDirection.TopToBottom)
			{
				image.fillOrigin = 1;
			}
			else
			{
				image.fillOrigin = 0;
			}
			Color color = default(Color);
			if (PluginConfig.ConfigEnableSuitColorOverlay.Value && (Object)(object)controllerInstance != (Object)null)
			{
				int currentSuitID = controllerInstance.currentSuitID;
				Debug.LogFormat("Current Suit ID in HealthIndicatorPatch: {0}", new object[1] { currentSuitID });
				UnlockableSuitPatch.UpdateHealthOverlayColor(controllerInstance, currentSuitID);
				Debug.Log((object)"Health overlay color updated in HealthIndicatorPatch");
			}
			else if (ColorUtility.TryParseHtmlString("#" + PluginConfig.ConfigOverlayColorHex.Value, ref color))
			{
				((Graphic)image).color = color;
			}
			else
			{
				((Graphic)image).color = Color.red;
			}
		}

		private static void HandlePlayerHealthState(HUDManager hudManager, int health, bool hurtPlayer)
		{
			if ((Object)(object)hudManager.selfRedCanvasGroup != (Object)null)
			{
				if (PluginConfig.ConfigStartFullyFilled.Value)
				{
					hudManager.selfRedCanvasGroup.alpha = (float)health / 100f;
				}
				else
				{
					hudManager.selfRedCanvasGroup.alpha = (100f - (float)health) / 100f;
				}
			}
			else
			{
				Debug.LogError((object)"selfRedCanvasGroup is null!");
			}
			if (health >= 20 && playerIsCriticallyInjured)
			{
				playerIsCriticallyInjured = false;
				if ((Object)(object)hudManager.HUDAnimator != (Object)null)
				{
					hudManager.HUDAnimator.SetTrigger("HealFromCritical");
				}
				else
				{
					Debug.LogError((object)"HUDAnimator is null!");
				}
			}
			if (health >= 20 && playerIsCriticallyInjured)
			{
				playerIsCriticallyInjured = false;
				hudManager.HUDAnimator.SetTrigger("HealFromCritical");
			}
			if (hurtPlayer && health > 0)
			{
				ProcessPlayerInjury(hudManager, health);
			}
		}

		private static void ProcessPlayerInjury(HUDManager hudManager, int health)
		{
			if (health < 20)
			{
				playerIsCriticallyInjured = true;
				if (PluginConfig.ConfigEnableCriticalHitEffect.Value)
				{
					if ((Object)(object)hudManager.HUDAnimator != (Object)null)
					{
						hudManager.HUDAnimator.SetTrigger("CriticalHit");
					}
					else
					{
						Debug.LogError((object)"HUDAnimator is null!");
					}
					if ((Object)(object)hudManager.UIAudio != (Object)null && (Object)(object)hudManager.criticalInjury != (Object)null)
					{
						hudManager.UIAudio.PlayOneShot(hudManager.criticalInjury, 1f);
					}
					else
					{
						Debug.LogError((object)"UIAudio or criticalInjury is null!");
					}
				}
			}
			else if (PluginConfig.ConfigEnableSmallHitEffect.Value)
			{
				if ((Object)(object)hudManager.HUDAnimator != (Object)null)
				{
					hudManager.HUDAnimator.SetTrigger("SmallHit");
				}
				else
				{
					Debug.LogError((object)"HUDAnimator is null!");
				}
			}
		}
	}
	public class HealthIndicatorInitializer : MonoBehaviour
	{
		public float StartFillAmount { get; set; }

		public float TargetFillAmount { get; set; }

		public float PreviousStartFillAmount { get; set; }
	}
	public static class PlayerControllerBPatch
	{
		[HarmonyPatch(typeof(PlayerControllerB), "KillPlayer")]
		[HarmonyPrefix]
		public static void KillPlayerPrefix(PlayerControllerB __instance)
		{
			HUDManager instance = HUDManager.Instance;
			if ((Object)(object)instance?.selfRedCanvasGroup == (Object)null)
			{
				Debug.LogError((object)"HUDManager instance or selfRedCanvasGroup is null!");
				return;
			}
			Image component = ((Component)instance.selfRedCanvasGroup).GetComponent<Image>();
			if ((Object)(object)component == (Object)null)
			{
				Debug.LogError((object)"Image component not found on selfRedCanvasGroup!");
				return;
			}
			if ((Object)(object)instance != (Object)null)
			{
				((MonoBehaviour)instance).StopAllCoroutines();
			}
			else
			{
				Debug.LogError((object)"HUDManager instance is null!");
			}
			HealthIndicatorInitializer component2 = ((Component)instance).gameObject.GetComponent<HealthIndicatorInitializer>();
			if ((Object)(object)component2 != (Object)null)
			{
				if (PluginConfig.ConfigStartFullyFilled.Value)
				{
					instance.selfRedCanvasGroup.alpha = 1f;
					component2.StartFillAmount = 1f;
					component2.TargetFillAmount = 1f;
					component.fillAmount = 1f;
				}
				else
				{
					component2.StartFillAmount = 0f;
					component2.TargetFillAmount = 0f;
					component.fillAmount = 0f;
				}
				component2.PreviousStartFillAmount = component2.StartFillAmount;
			}
			Debug.Log((object)"Player died. Setting fill amount to 0 and resetting start/target fill amounts.");
		}
	}
	public class HealthMonitorCoroutine : MonoBehaviour
	{
		private int lastHealth = -1;

		private void Start()
		{
			((MonoBehaviour)this).StartCoroutine(MonitorHealth());
		}

		private IEnumerator MonitorHealth()
		{
			while (true)
			{
				PlayerControllerB playerController = PlayerUtils.GetPlayerControllerB();
				if ((Object)(object)playerController != (Object)null)
				{
					int currentHealth = playerController.health;
					if (currentHealth != lastHealth)
					{
						lastHealth = currentHealth;
						HUDManagerPatch.UpdateHealthUIPrefix(currentHealth, hurtPlayer: false);
					}
				}
				else
				{
					Debug.LogError((object)"PlayerControllerB is null!");
				}
				yield return (object)new WaitForSeconds(0.01f);
			}
		}
	}
	[BepInPlugin("Nilaier.NilsHUD", "NilsHUD", "1.0.6")]
	public class Plugin : BaseUnityPlugin
	{
		private const string AsciiLogoResourceName = "NilsHUD.Resources.ascii_logo.txt";

		private static readonly Assembly ExecutingAssembly = Assembly.GetExecutingAssembly();

		private static readonly string[] ExcludedScenes = new string[5] { "InitScene", "InitSceneLaunchOptions", "InitSceneLANMode", "MainMenu", "ColdOpen1" };

		private Harmony? harmonyInstance;

		private bool isPluginInitialized = false;

		private void Awake()
		{
			try
			{
				DisplayAsciiLogo();
				PluginConfig.BindConfig(((BaseUnityPlugin)this).Config);
				Debug.Log((object)"[NilsHUD] Config loaded.");
				SceneManager.sceneLoaded += OnSceneLoaded;
			}
			catch (Exception ex)
			{
				Debug.LogError((object)("[NilsHUD] Error in Awake: " + ex.Message));
				Debug.LogError((object)("[NilsHUD] Stack trace: " + ex.StackTrace));
			}
		}

		private void DisplayAsciiLogo()
		{
			try
			{
				string text = LoadAsciiLogoFromResource();
				Debug.Log((object)(string.IsNullOrEmpty(text) ? "[NilsHUD] ASCII logo not found or empty." : text));
			}
			catch (Exception ex)
			{
				Debug.LogError((object)("[NilsHUD] Error displaying ASCII logo: " + ex.Message));
				Debug.LogError((object)("[NilsHUD] Stack trace: " + ex.StackTrace));
			}
		}

		private void InitializePlugin()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			try
			{
				harmonyInstance = new Harmony("Nilaier.NilsHUD");
				harmonyInstance.PatchAll(typeof(HUDManagerPatch));
				harmonyInstance.PatchAll(typeof(UnlockableSuitPatch));
				harmonyInstance.PatchAll(typeof(HealthBarPatch));
				harmonyInstance.PatchAll(typeof(PlayerControllerBPatch));
				Debug.Log((object)"[NilsHUD] Harmony patches applied.");
				UnlockableSuitPatch.PrecomputeSuitColors();
				HUDManagerPatch.InitializeHealthOverlay();
			}
			catch (Exception ex)
			{
				Debug.LogError((object)("[NilsHUD] Error in InitializePlugin: " + ex.Message));
				Debug.LogError((object)("[NilsHUD] Stack trace: " + ex.StackTrace));
			}
		}

		private string LoadAsciiLogoFromResource()
		{
			try
			{
				using Stream stream = ExecutingAssembly.GetManifestResourceStream("NilsHUD.Resources.ascii_logo.txt");
				if (stream != null)
				{
					using (StreamReader streamReader = new StreamReader(stream))
					{
						return streamReader.ReadToEnd();
					}
				}
			}
			catch (IOException ex)
			{
				Debug.LogError((object)("[NilsHUD] Error loading ASCII logo: " + ex.Message));
				Debug.LogError((object)("[NilsHUD] Stack trace: " + ex.StackTrace));
			}
			return string.Empty;
		}

		private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			try
			{
				Debug.Log((object)("[NilsHUD] Loaded scene: " + ((Scene)(ref scene)).name));
				if (!isPluginInitialized && !ExcludedScenes.Contains(((Scene)(ref scene)).name))
				{
					InitializePlugin();
					isPluginInitialized = true;
					Debug.Log((object)("[NilsHUD] Plugin initialized in scene: " + ((Scene)(ref scene)).name));
				}
			}
			catch (Exception ex)
			{
				Debug.LogError((object)("[NilsHUD] Error in OnSceneLoaded: " + ex.Message));
				Debug.LogError((object)("[NilsHUD] Stack trace: " + ex.StackTrace));
			}
		}
	}
	public class PluginConfig
	{
		private const string DefaultOverlayColor = "FF0000";

		private const float DefaultFillTransitionDuration = 0.1f;

		private const float DefaultFadeOutDuration = 0.5f;

		private const float DefaultFadeOutIntensity = 0.5f;

		private const string DefaultHealthBarColor = "FF8000";

		private const string DefaultRedHealthBarColor = "FF0000";

		private const float DefaultHealthBarPositionX = 0f;

		private const float DefaultHealthBarPositionY = 30f;

		private const float DefaultFadeInDuration = 0.5f;

		private const float DefaultFadeOutDelay = 1f;

		private const float DefaultHealthBarWidth = 300f;

		private const float DefaultHealthBarHeight = 15f;

		private const float DefaultRedHealthBarWidth = 300f;

		private const float DefaultRedHealthBarHeight = 15f;

		public static ConfigEntry<string>? ConfigOverlayColorHex;

		public static ConfigEntry<bool>? ConfigEnableFillAnimation;

		public static ConfigEntry<FillDirection>? ConfigFillDirection;

		public static ConfigEntry<float>? ConfigFillTransitionDuration;

		public static ConfigEntry<bool>? ConfigStartFullyFilled;

		public static ConfigEntry<bool>? ConfigEnableSuitColorOverlay;

		public static ConfigEntry<float>? ConfigSuitOverlayBrightness;

		public static ConfigEntry<bool>? ConfigEnableFadeOut;

		public static ConfigEntry<float>? ConfigFadeOutDuration;

		public static ConfigEntry<float>? ConfigFadeOutIntensity;

		public static ConfigEntry<bool>? ConfigEnableCriticalHitEffect;

		public static ConfigEntry<bool>? ConfigEnableSmallHitEffect;

		public static ConfigEntry<bool>? ConfigEnableHealthBar;

		public static ConfigEntry<string>? ConfigHealthBarColorHex;

		public static ConfigEntry<string>? ConfigRedHealthBarColorHex;

		public static ConfigEntry<float>? ConfigHealthBarPositionX;

		public static ConfigEntry<float>? ConfigHealthBarPositionY;

		public static ConfigEntry<float>? ConfigFadeInDuration;

		public static ConfigEntry<float>? ConfigFadeOutDelay;

		public static ConfigEntry<float>? ConfigHealthBarWidth;

		public static ConfigEntry<float>? ConfigHealthBarHeight;

		public static ConfigEntry<float>? ConfigRedHealthBarWidth;

		public static ConfigEntry<float>? ConfigRedHealthBarHeight;

		private const string ModIconResourceName = "NilsHUD.Resources.icon.png";

		private static readonly Assembly ExecutingAssembly = Assembly.GetExecutingAssembly();

		public static void BindConfig(ConfigFile config)
		{
			try
			{
				ConfigOverlayColorHex = config.Bind<string>("Overlay", "OverlayColorHex", "FF0000", (ConfigDescription)null);
				ConfigEnableFillAnimation = config.Bind<bool>("Overlay", "EnableFillAnimation", true, (ConfigDescription)null);
				ConfigFillDirection = config.Bind<FillDirection>("Overlay", "FillDirection", FillDirection.BottomToTop, (ConfigDescription)null);
				ConfigFillTransitionDuration = config.Bind<float>("Overlay", "FillTransitionDuration", 0.1f, (ConfigDescription)null);
				ConfigStartFullyFilled = config.Bind<bool>("Overlay", "StartFullyFilled", false, (ConfigDescription)null);
				ConfigEnableSuitColorOverlay = config.Bind<bool>("Overlay", "EnableSuitColorOverlay", false, (ConfigDescription)null);
				ConfigSuitOverlayBrightness = config.Bind<float>("Overlay", "SuitOverlayBrightness", 1f, (ConfigDescription)null);
				ConfigEnableFadeOut = config.Bind<bool>("FadeOut", "EnableFadeOut", true, (ConfigDescription)null);
				ConfigFadeOutDuration = config.Bind<float>("FadeOut", "FadeOutDuration", 0.5f, (ConfigDescription)null);
				ConfigFadeOutIntensity = config.Bind<float>("FadeOut", "FadeOutIntensity", 0.5f, (ConfigDescription)null);
				ConfigEnableCriticalHitEffect = config.Bind<bool>("Effects", "EnableCriticalHitEffect", true, (ConfigDescription)null);
				ConfigEnableSmallHitEffect = config.Bind<bool>("Effects", "EnableSmallHitEffect", true, (ConfigDescription)null);
				ConfigEnableHealthBar = config.Bind<bool>("Experimental", "EnableHealthBar", false, (ConfigDescription)null);
				ConfigHealthBarColorHex = config.Bind<string>("Experimental", "HealthBarColorHex", "FF8000", (ConfigDescription)null);
				ConfigRedHealthBarColorHex = config.Bind<string>("Experimental", "RedHealthBarColorHex", "FF0000", (ConfigDescription)null);
				ConfigHealthBarPositionX = config.Bind<float>("Experimental", "HealthBarPositionX", 0f, (ConfigDescription)null);
				ConfigHealthBarPositionY = config.Bind<float>("Experimental", "HealthBarPositionY", 30f, (ConfigDescription)null);
				ConfigFadeInDuration = config.Bind<float>("Experimental", "FadeInDuration", 0.5f, (ConfigDescription)null);
				ConfigFadeOutDelay = config.Bind<float>("Experimental", "FadeOutDelay", 1f, (ConfigDescription)null);
				ConfigHealthBarWidth = config.Bind<float>("Experimental", "HealthBarWidth", 300f, (ConfigDescription)null);
				ConfigHealthBarHeight = config.Bind<float>("Experimental", "HealthBarHeight", 15f, (ConfigDescription)null);
				ConfigRedHealthBarWidth = config.Bind<float>("Experimental", "RedHealthBarWidth", 300f, (ConfigDescription)null);
				ConfigRedHealthBarHeight = config.Bind<float>("Experimental", "RedHealthBarHeight", 15f, (ConfigDescription)null);
			}
			catch (Exception ex)
			{
				Debug.LogError((object)("[NilsHUD] Error while binding config: " + ex.Message));
				Debug.LogError((object)("[NilsHUD] Stack trace: " + ex.StackTrace));
			}
			try
			{
				Type type = Type.GetType("LethalConfig.LethalConfigManager, LethalConfig");
				if (type != null)
				{
					AddLethalConfigItems();
					SetModIconAndDescription();
				}
				else
				{
					Debug.Log((object)"LethalConfig is not installed. Using default config values.");
				}
			}
			catch (FileNotFoundException)
			{
				Debug.Log((object)"LethalConfig assembly is not found. Using default config values.");
			}
		}

		private static void SetModIconAndDescription()
		{
			try
			{
				Sprite val = LoadModIcon();
				if ((Object)(object)val != (Object)null)
				{
					(Type.GetType("LethalConfig.LethalConfigManager, LethalConfig")?.GetMethod("SetModIcon"))?.Invoke(null, new object[1] { val });
				}
				(Type.GetType("LethalConfig.LethalConfigManager, LethalConfig")?.GetMethod("SetModDescription"))?.Invoke(null, new object[1] { "Better Vanilla-like Health HUD" });
			}
			catch (Exception ex)
			{
				Debug.LogError((object)("[NilsHUD] Error while setting mod icon and description: " + ex.Message));
				Debug.LogError((object)("[NilsHUD] Stack trace: " + ex.StackTrace));
			}
		}

		private static Sprite LoadModIcon()
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected O, but got Unknown
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				using Stream stream = ExecutingAssembly.GetManifestResourceStream("NilsHUD.Resources.icon.png");
				if (stream != null)
				{
					byte[] array = new byte[stream.Length];
					stream.Read(array, 0, array.Length);
					Texture2D val = new Texture2D(2, 2);
					if (ImageConversion.LoadImage(val, array))
					{
						return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f));
					}
				}
			}
			catch (Exception ex)
			{
				Debug.LogError((object)("[NilsHUD] Error loading mod icon: " + ex.Message));
				Debug.LogError((object)("[NilsHUD] Stack trace: " + ex.StackTrace));
			}
			return null;
		}

		private static void AddLethalConfigItems()
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Expected O, but got Unknown
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Expected O, but got Unknown
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Expected O, but got Unknown
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Expected O, but got Unknown
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Expected O, but got Unknown
			//IL_00ca: Expected O, but got Unknown
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Expected O, but got Unknown
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Expected O, but got Unknown
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Expected O, but got Unknown
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Expected O, but got Unknown
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Expected O, but got Unknown
			//IL_013a: Expected O, but got Unknown
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Expected O, but got Unknown
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Expected O, but got Unknown
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Expected O, but got Unknown
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Expected O, but got Unknown
			//IL_018e: Expected O, but got Unknown
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Expected O, but got Unknown
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Expected O, but got Unknown
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Expected O, but got Unknown
			//IL_01c6: Expected O, but got Unknown
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Expected O, but got Unknown
			//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Expected O, but got Unknown
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Expected O, but got Unknown
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			//IL_021b: Expected O, but got Unknown
			//IL_0231: Unknown result type (might be due to invalid IL or missing references)
			//IL_0237: Expected O, but got Unknown
			//IL_024d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0253: Expected O, but got Unknown
			//IL_0268: Unknown result type (might be due to invalid IL or missing references)
			//IL_026d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0278: Expected O, but got Unknown
			//IL_0279: Unknown result type (might be due to invalid IL or missing references)
			//IL_0284: Expected O, but got Unknown
			//IL_028a: Expected O, but got Unknown
			//IL_0285: Unknown result type (might be due to invalid IL or missing references)
			//IL_028b: Expected O, but got Unknown
			//IL_02a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b0: Expected O, but got Unknown
			//IL_02b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bc: Expected O, but got Unknown
			//IL_02c2: Expected O, but got Unknown
			//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c3: Expected O, but got Unknown
			//IL_02d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e8: Expected O, but got Unknown
			//IL_02e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f4: Expected O, but got Unknown
			//IL_02fa: Expected O, but got Unknown
			//IL_02f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fb: Expected O, but got Unknown
			//IL_0310: Unknown result type (might be due to invalid IL or missing references)
			//IL_0315: Unknown result type (might be due to invalid IL or missing references)
			//IL_0320: Expected O, but got Unknown
			//IL_0321: Unknown result type (might be due to invalid IL or missing references)
			//IL_032c: Expected O, but got Unknown
			//IL_0332: Expected O, but got Unknown
			//IL_032d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0333: Expected O, but got Unknown
			//IL_0348: Unknown result type (might be due to invalid IL or missing references)
			//IL_034d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0358: Expected O, but got Unknown
			//IL_0359: Unknown result type (might be due to invalid IL or missing references)
			//IL_0364: Expected O, but got Unknown
			//IL_036a: Expected O, but got Unknown
			//IL_0365: Unknown result type (might be due to invalid IL or missing references)
			//IL_036b: Expected O, but got Unknown
			//IL_0380: Unknown result type (might be due to invalid IL or missing references)
			//IL_0385: Unknown result type (might be due to invalid IL or missing references)
			//IL_0390: Expected O, but got Unknown
			//IL_0391: Unknown result type (might be due to invalid IL or missing references)
			//IL_039c: Expected O, but got Unknown
			//IL_03a2: Expected O, but got Unknown
			//IL_039d: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a3: Expected O, but got Unknown
			//IL_03b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c8: Expected O, but got Unknown
			//IL_03c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d4: Expected O, but got Unknown
			//IL_03da: Expected O, but got Unknown
			//IL_03d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03db: Expected O, but got Unknown
			//IL_03f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0400: Expected O, but got Unknown
			//IL_0401: Unknown result type (might be due to invalid IL or missing references)
			//IL_040c: Expected O, but got Unknown
			//IL_0412: Expected O, but got Unknown
			//IL_040d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0413: Expected O, but got Unknown
			try
			{
				MethodInfo methodInfo = Type.GetType("LethalConfig.LethalConfigManager, LethalConfig")?.GetMethod("AddConfigItem", new Type[1] { typeof(BaseConfigItem) });
				if (methodInfo != null)
				{
					methodInfo.Invoke(null, new object[1] { (object)new TextInputFieldConfigItem(ConfigOverlayColorHex, true) });
					methodInfo.Invoke(null, new object[1] { (object)new BoolCheckBoxConfigItem(ConfigEnableFillAnimation, true) });
					methodInfo.Invoke(null, new object[1]
					{
						new EnumDropDownConfigItem<FillDirection>(ConfigFillDirection, new EnumDropDownOptions())
					});
					object[] array = new object[1];
					ConfigEntry<float>? configFillTransitionDuration = ConfigFillTransitionDuration;
					FloatSliderOptions val = new FloatSliderOptions();
					((BaseRangeOptions<float>)val).Min = 0f;
					((BaseRangeOptions<float>)val).Max = 60f;
					array[0] = (object)new FloatSliderConfigItem(configFillTransitionDuration, val);
					methodInfo.Invoke(null, array);
					methodInfo.Invoke(null, new object[1] { (object)new BoolCheckBoxConfigItem(ConfigStartFullyFilled, true) });
					methodInfo.Invoke(null, new object[1] { (object)new BoolCheckBoxConfigItem(ConfigEnableSuitColorOverlay, true) });
					object[] array2 = new object[1];
					ConfigEntry<float>? configSuitOverlayBrightness = ConfigSuitOverlayBrightness;
					FloatSliderOptions val2 = new FloatSliderOptions();
					((BaseRangeOptions<float>)val2).Min = 0f;
					((BaseRangeOptions<float>)val2).Max = 2f;
					array2[0] = (object)new FloatSliderConfigItem(configSuitOverlayBrightness, val2);
					methodInfo.Invoke(null, array2);
					methodInfo.Invoke(null, new object[1] { (object)new BoolCheckBoxConfigItem(ConfigEnableFadeOut, true) });
					object[] array3 = new object[1];
					ConfigEntry<float>? configFadeOutDuration = ConfigFadeOutDuration;
					FloatSliderOptions val3 = new FloatSliderOptions();
					((BaseRangeOptions<float>)val3).Min = 0f;
					((BaseRangeOptions<float>)val3).Max = 60f;
					array3[0] = (object)new FloatSliderConfigItem(configFadeOutDuration, val3);
					methodInfo.Invoke(null, array3);
					object[] array4 = new object[1];
					ConfigEntry<float>? configFadeOutIntensity = ConfigFadeOutIntensity;
					FloatSliderOptions val4 = new FloatSliderOptions();
					((BaseRangeOptions<float>)val4).Min = 0f;
					((BaseRangeOptions<float>)val4).Max = 1f;
					array4[0] = (object)new FloatSliderConfigItem(configFadeOutIntensity, val4);
					methodInfo.Invoke(null, array4);
					methodInfo.Invoke(null, new object[1] { (object)new BoolCheckBoxConfigItem(ConfigEnableCriticalHitEffect, true) });
					methodInfo.Invoke(null, new object[1] { (object)new BoolCheckBoxConfigItem(ConfigEnableSmallHitEffect, true) });
					methodInfo.Invoke(null, new object[1] { (object)new BoolCheckBoxConfigItem(ConfigEnableHealthBar, true) });
					methodInfo.Invoke(null, new object[1] { (object)new TextInputFieldConfigItem(ConfigHealthBarColorHex, true) });
					methodInfo.Invoke(null, new object[1] { (object)new TextInputFieldConfigItem(ConfigRedHealthBarColorHex, true) });
					object[] array5 = new object[1];
					ConfigEntry<float>? configHealthBarPositionX = ConfigHealthBarPositionX;
					FloatSliderOptions val5 = new FloatSliderOptions();
					((BaseRangeOptions<float>)val5).Min = -500f;
					((BaseRangeOptions<float>)val5).Max = 500f;
					array5[0] = (object)new FloatSliderConfigItem(configHealthBarPositionX, val5);
					methodInfo.Invoke(null, array5);
					object[] array6 = new object[1];
					ConfigEntry<float>? configHealthBarPositionY = ConfigHealthBarPositionY;
					FloatSliderOptions val6 = new FloatSliderOptions();
					((BaseRangeOptions<float>)val6).Min = -500f;
					((BaseRangeOptions<float>)val6).Max = 500f;
					array6[0] = (object)new FloatSliderConfigItem(configHealthBarPositionY, val6);
					methodInfo.Invoke(null, array6);
					object[] array7 = new object[1];
					ConfigEntry<float>? configFadeInDuration = ConfigFadeInDuration;
					FloatSliderOptions val7 = new FloatSliderOptions();
					((BaseRangeOptions<float>)val7).Min = 0f;
					((BaseRangeOptions<float>)val7).Max = 60f;
					array7[0] = (object)new FloatSliderConfigItem(configFadeInDuration, val7);
					methodInfo.Invoke(null, array7);
					object[] array8 = new object[1];
					ConfigEntry<float>? configFadeOutDelay = ConfigFadeOutDelay;
					FloatSliderOptions val8 = new FloatSliderOptions();
					((BaseRangeOptions<float>)val8).Min = 0f;
					((BaseRangeOptions<float>)val8).Max = 60f;
					array8[0] = (object)new FloatSliderConfigItem(configFadeOutDelay, val8);
					methodInfo.Invoke(null, array8);
					object[] array9 = new object[1];
					ConfigEntry<float>? configHealthBarWidth = ConfigHealthBarWidth;
					FloatSliderOptions val9 = new FloatSliderOptions();
					((BaseRangeOptions<float>)val9).Min = 1f;
					((BaseRangeOptions<float>)val9).Max = 500f;
					array9[0] = (object)new FloatSliderConfigItem(configHealthBarWidth, val9);
					methodInfo.Invoke(null, array9);
					object[] array10 = new object[1];
					ConfigEntry<float>? configHealthBarHeight = ConfigHealthBarHeight;
					FloatSliderOptions val10 = new FloatSliderOptions();
					((BaseRangeOptions<float>)val10).Min = 1f;
					((BaseRangeOptions<float>)val10).Max = 500f;
					array10[0] = (object)new FloatSliderConfigItem(configHealthBarHeight, val10);
					methodInfo.Invoke(null, array10);
					object[] array11 = new object[1];
					ConfigEntry<float>? configRedHealthBarWidth = ConfigRedHealthBarWidth;
					FloatSliderOptions val11 = new FloatSliderOptions();
					((BaseRangeOptions<float>)val11).Min = 1f;
					((BaseRangeOptions<float>)val11).Max = 500f;
					array11[0] = (object)new FloatSliderConfigItem(configRedHealthBarWidth, val11);
					methodInfo.Invoke(null, array11);
					object[] array12 = new object[1];
					ConfigEntry<float>? configRedHealthBarHeight = ConfigRedHealthBarHeight;
					FloatSliderOptions val12 = new FloatSliderOptions();
					((BaseRangeOptions<float>)val12).Min = 1f;
					((BaseRangeOptions<float>)val12).Max = 500f;
					array12[0] = (object)new FloatSliderConfigItem(configRedHealthBarHeight, val12);
					methodInfo.Invoke(null, array12);
				}
				else
				{
					Debug.LogError((object)"[NilsHUD] Failed to find AddConfigItem method in LethalConfig.");
				}
			}
			catch (Exception ex)
			{
				Debug.LogError((object)("[NilsHUD] Error while adding LethalConfig items: " + ex.Message));
				Debug.LogError((object)("[NilsHUD] Stack trace: " + ex.StackTrace));
			}
		}
	}
	public enum FillDirection
	{
		BottomToTop,
		TopToBottom
	}
	internal static class PluginInfo
	{
		public const string PLUGIN_GUID = "Nilaier.NilsHUD";

		public const string PLUGIN_NAME = "NilsHUD";

		public const string PLUGIN_VERSION = "1.0.6";
	}
}