Decompiled source of FishHP v0.1.3

BepInEx/plugins/HowToFish.FishHP/HowToFish.FishHP.dll

Decompiled a day ago
using System;
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Configuration;
using FishNet.Connection;
using FishNet.Object;
using HarmonyLib;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

[assembly: AssemblyCompany("evansvl")]
[assembly: AssemblyDescription("Shows a native-style health bar for the last non-boss creature damaged by the local player.")]
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace HowToFish.FishHP;

[BepInPlugin("community.howtofish.fishhp", "Fish HP", "0.1.3")]
public sealed class Plugin : BaseUnityPlugin
{
	[HarmonyPatch(typeof(Creature), "LocalHit")]
	private static class LocalCreatureHitPatch
	{
		private static void Postfix(Creature __instance, Player player, int damage, bool fromNpc)
		{
			if ((Object)(object)_instance == (Object)null || (Object)(object)__instance == (Object)null || (Object)(object)player == (Object)null || fromNpc || damage <= 0)
			{
				return;
			}
			try
			{
				if (((NetworkBehaviour)player).Owner == (NetworkConnection)null || !((NetworkBehaviour)player).Owner.IsLocalClient)
				{
					return;
				}
			}
			catch
			{
				return;
			}
			_instance.SelectTarget(__instance, damage);
		}
	}

	public const string PluginGuid = "community.howtofish.fishhp";

	public const string PluginName = "Fish HP";

	public const string PluginVersion = "0.1.3";

	private const float ShakeForce = 750f;

	private const float PositionSpring = 1200f;

	private const float PositionDamping = 12f;

	private const float AngularShakeForce = 10f;

	private const float RotationSpring = 120f;

	private const float RotationDamping = 20f;

	private static readonly FieldInfo MainCanvasField = typeof(PlayerUI).GetField("_mainCanvas", BindingFlags.Instance | BindingFlags.NonPublic);

	private static readonly FieldInfo BossNameField = typeof(BossUI).GetField("_bossNameText", BindingFlags.Instance | BindingFlags.NonPublic);

	private static readonly FieldInfo BossMoveField = typeof(BossUI).GetField("_bossHpToMove", BindingFlags.Instance | BindingFlags.NonPublic);

	private static readonly FieldInfo BossRotateField = typeof(BossUI).GetField("_bossHpToRotate", BindingFlags.Instance | BindingFlags.NonPublic);

	private static readonly FieldInfo BossHealthField = typeof(BossUI).GetField("_bossHealth", BindingFlags.Instance | BindingFlags.NonPublic);

	private static readonly FieldInfo BossHealthLerpedField = typeof(BossUI).GetField("_bossHealthLerped", BindingFlags.Instance | BindingFlags.NonPublic);

	private static readonly FieldInfo TimeLeftImageField = typeof(BossUI).GetField("_timeLeftImage", BindingFlags.Instance | BindingFlags.NonPublic);

	private static readonly FieldInfo LocalHpField = typeof(Creature).GetField("_localHp", BindingFlags.Instance | BindingFlags.NonPublic);

	private static Plugin _instance;

	private ConfigEntry<bool> _enabled;

	private ConfigEntry<float> _scale;

	private ConfigEntry<float> _opacity;

	private ConfigEntry<float> _leftOffset;

	private ConfigEntry<float> _topOffset;

	private Harmony _harmony;

	private Creature _target;

	private int _shownHp = -1;

	private int _shownMaxHp = -1;

	private float _predictionUntil;

	private CanvasGroup _mainCanvas;

	private RectTransform _wrapper;

	private CanvasGroup _group;

	private RectTransform _moveRoot;

	private RectTransform _rotateRoot;

	private TextMeshProUGUI _nameText;

	private TextMeshProUGUI _hpText;

	private Image _health;

	private Image _healthLerped;

	private Vector3 _startPosition;

	private Vector3 _velocity;

	private Vector3 _angularVelocity;

	private readonly Vector3[] _barCorners = (Vector3[])(object)new Vector3[4];

	private bool _isFadingOut;

	private void Awake()
	{
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_0061: Expected O, but got Unknown
		//IL_0096: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a0: Expected O, but got Unknown
		//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00df: Expected O, but got Unknown
		//IL_0114: Unknown result type (might be due to invalid IL or missing references)
		//IL_011e: Expected O, but got Unknown
		//IL_0129: Unknown result type (might be due to invalid IL or missing references)
		//IL_0133: Expected O, but got Unknown
		_instance = this;
		_enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("HUD", "Enabled", true, "Show the last non-boss creature damaged by the local player.");
		_scale = ((BaseUnityPlugin)this).Config.Bind<float>("HUD", "Scale", 0.58f, new ConfigDescription("HUD scale relative to the native boss bar.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.35f, 1f), new object[0]));
		_opacity = ((BaseUnityPlugin)this).Config.Bind<float>("HUD", "Opacity", 1f, new ConfigDescription("HUD opacity.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.2f, 1f), new object[0]));
		_leftOffset = ((BaseUnityPlugin)this).Config.Bind<float>("Position", "LeftOffset", 36f, new ConfigDescription("Distance from the left edge of the screen.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 600f), new object[0]));
		_topOffset = ((BaseUnityPlugin)this).Config.Bind<float>("Position", "TopOffset", 54f, new ConfigDescription("Distance from the top edge of the screen.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 500f), new object[0]));
		_harmony = new Harmony("community.howtofish.fishhp");
		_harmony.PatchAll(typeof(LocalCreatureHitPatch));
		((BaseUnityPlugin)this).Logger.LogInfo((object)"Loaded. Fish HP follows local confirmed hits and reproduces the native boss-bar spring response.");
	}

	private void Update()
	{
		if (!_enabled.Value || !IsGameplayHudVisible())
		{
			SetRootVisible(visible: false);
			return;
		}
		if ((Object)(object)_target == (Object)null)
		{
			ClearTarget(destroyHud: false);
			return;
		}
		if (_target.IsDead || _target.Hp <= 0)
		{
			BeginDeathFade();
			return;
		}
		if (!EnsureHud())
		{
			SetRootVisible(visible: false);
			return;
		}
		ApplyLiveSettings();
		UpdateTargetValues();
		SetRootVisible(visible: true);
	}

	private void LateUpdate()
	{
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_005c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0062: 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_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0072: Unknown result type (might be due to invalid IL or missing references)
		//IL_0079: 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_0089: Unknown result type (might be due to invalid IL or missing references)
		//IL_008f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0094: Unknown result type (might be due to invalid IL or missing references)
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b6: 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_00d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)_moveRoot == (Object)null) && !((Object)(object)_rotateRoot == (Object)null) && ((Component)_moveRoot).gameObject.activeInHierarchy)
		{
			float deltaTime = Time.deltaTime;
			if (!(deltaTime <= 0f))
			{
				Vector3 val = _startPosition - ((Transform)_moveRoot).localPosition;
				_velocity += val * 1200f * deltaTime;
				_velocity -= _velocity * 12f * deltaTime;
				RectTransform moveRoot = _moveRoot;
				((Transform)moveRoot).localPosition = ((Transform)moveRoot).localPosition + _velocity * deltaTime;
				Quaternion localRotation = ((Transform)_rotateRoot).localRotation;
				DazedUtils.SimulateSpringRotation(ref localRotation, ref _angularVelocity, Quaternion.identity, 120f, 20f);
				((Transform)_rotateRoot).localRotation = localRotation;
			}
		}
	}

	private static bool IsGameplayHudVisible()
	{
		if (MainMenuManager.IsInMenu || PauseManager.IsPaused || (Object)(object)Player.LocalPlayer == (Object)null)
		{
			return false;
		}
		try
		{
			return !PlayerUI.UIDisabled;
		}
		catch
		{
			return true;
		}
	}

	private void SelectTarget(Creature creature, int damage)
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		if (!_enabled.Value || (Object)(object)creature == (Object)null || creature.IsDead || damage <= 0 || (int)creature.BossType != 0)
		{
			return;
		}
		bool flag = (Object)(object)_target != (Object)(object)creature;
		_target = creature;
		_isFadingOut = false;
		if (EnsureHud())
		{
			LeanTween.cancel(((Component)_group).gameObject);
			_group.alpha = _opacity.Value;
			SetRootVisible(visible: true);
			int num = Math.Max(1, creature.MaxHp);
			int num2 = Math.Max(0, Math.Min(creature.Hp, num));
			int val = ReadLocalHp(creature, num2 - damage);
			val = Math.Max(0, Math.Min(val, num));
			if (flag)
			{
				((TMP_Text)_nameText).text = SafeName(creature);
				float fillAmount = (float)num2 / (float)num;
				_health.fillAmount = fillAmount;
				_healthLerped.fillAmount = fillAmount;
				_shownHp = val;
				_shownMaxHp = num;
			}
			_predictionUntil = Time.unscaledTime + 1f;
			ApplyHealth(val, num, shake: true);
		}
	}

	private static int ReadLocalHp(Creature creature, int fallback)
	{
		if (LocalHpField == null)
		{
			return fallback;
		}
		try
		{
			return (int)LocalHpField.GetValue(creature);
		}
		catch
		{
			return fallback;
		}
	}

	private void UpdateTargetValues()
	{
		int num = Math.Max(1, _target.MaxHp);
		int num2 = Math.Max(0, Math.Min(_target.Hp, num));
		((TMP_Text)_nameText).text = SafeName(_target);
		if (!(Time.unscaledTime < _predictionUntil) || num2 <= _shownHp)
		{
			if (_shownMaxHp != num)
			{
				_shownMaxHp = num;
				_shownHp = num2;
				UpdateHpText(num2, num);
				float fillAmount = (float)num2 / (float)num;
				_health.fillAmount = fillAmount;
				_healthLerped.fillAmount = fillAmount;
			}
			else if (_shownHp != num2)
			{
				ApplyHealth(num2, num, num2 < _shownHp);
			}
		}
	}

	private void ApplyHealth(int current, int maximum, bool shake)
	{
		float num = Mathf.Clamp01((float)current / (float)Math.Max(1, maximum));
		float fillAmount = _health.fillAmount;
		_health.fillAmount = num;
		_shownHp = current;
		_shownMaxHp = maximum;
		UpdateHpText(current, maximum);
		LeanTween.cancel(((Component)_healthLerped).gameObject);
		LeanTween.value(((Component)_healthLerped).gameObject, _healthLerped.fillAmount, num, 0.5f).setDelay(0.25f).setEase((LeanTweenType)9)
			.setOnUpdate((Action<float>)UpdateLerpedHealth);
		if (shake && num < fillAmount)
		{
			ApplyDamageShake(fillAmount - num);
		}
	}

	private void UpdateLerpedHealth(float value)
	{
		if ((Object)(object)_healthLerped != (Object)null)
		{
			_healthLerped.fillAmount = value;
		}
	}

	private void ApplyDamageShake(float healthLostRatio)
	{
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_006c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0084: Unknown result type (might be due to invalid IL or missing references)
		//IL_0089: Unknown result type (might be due to invalid IL or missing references)
		//IL_008e: Unknown result type (might be due to invalid IL or missing references)
		float num = Mathf.Clamp(healthLostRatio, 0.025f, 1f);
		Vector3 insideUnitSphere = Random.insideUnitSphere;
		Vector3 val = ((Vector3)(ref insideUnitSphere)).normalized * num;
		val *= ((Random.Range(0, 2) == 1) ? 1f : (-1f));
		_velocity = val * 750f;
		float num2 = ((Random.Range(0, 2) == 1) ? 1f : (-1f));
		_angularVelocity += new Vector3(0f, 0f, num2 * num * 10f);
	}

	private bool EnsureHud()
	{
		//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_0129: Unknown result type (might be due to invalid IL or missing references)
		//IL_0130: Expected O, but got Unknown
		//IL_0173: Unknown result type (might be due to invalid IL or missing references)
		//IL_0178: Unknown result type (might be due to invalid IL or missing references)
		//IL_0179: Unknown result type (might be due to invalid IL or missing references)
		//IL_0180: Unknown result type (might be due to invalid IL or missing references)
		//IL_0197: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
		//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_026e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0275: Unknown result type (might be due to invalid IL or missing references)
		//IL_0288: Unknown result type (might be due to invalid IL or missing references)
		//IL_0294: Unknown result type (might be due to invalid IL or missing references)
		//IL_02bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_0364: Unknown result type (might be due to invalid IL or missing references)
		//IL_0369: Unknown result type (might be due to invalid IL or missing references)
		//IL_036a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0371: Unknown result type (might be due to invalid IL or missing references)
		//IL_0384: Unknown result type (might be due to invalid IL or missing references)
		//IL_039c: Unknown result type (might be due to invalid IL or missing references)
		//IL_03b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_03be: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_03f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_03f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_03fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_0401: Unknown result type (might be due to invalid IL or missing references)
		//IL_0414: Unknown result type (might be due to invalid IL or missing references)
		//IL_042a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0436: Unknown result type (might be due to invalid IL or missing references)
		//IL_045f: Unknown result type (might be due to invalid IL or missing references)
		//IL_046e: Unknown result type (might be due to invalid IL or missing references)
		//IL_048e: Unknown result type (might be due to invalid IL or missing references)
		//IL_04af: Unknown result type (might be due to invalid IL or missing references)
		//IL_04b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_04d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_04fe: Unknown result type (might be due to invalid IL or missing references)
		//IL_0503: Unknown result type (might be due to invalid IL or missing references)
		//IL_0515: Unknown result type (might be due to invalid IL or missing references)
		//IL_053e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0543: Unknown result type (might be due to invalid IL or missing references)
		//IL_0553: Unknown result type (might be due to invalid IL or missing references)
		//IL_0592: Unknown result type (might be due to invalid IL or missing references)
		//IL_0597: Unknown result type (might be due to invalid IL or missing references)
		//IL_059d: Unknown result type (might be due to invalid IL or missing references)
		//IL_05a2: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)_wrapper != (Object)null && (Object)(object)_health != (Object)null && (Object)(object)_healthLerped != (Object)null && (Object)(object)_nameText != (Object)null && (Object)(object)_hpText != (Object)null)
		{
			return true;
		}
		DestroyHud();
		if (!TryFindTemplates(out var bossUi, out var mainCanvas))
		{
			return false;
		}
		object? value = BossNameField.GetValue(bossUi);
		TextMeshProUGUI val = (TextMeshProUGUI)((value is TextMeshProUGUI) ? value : null);
		object? value2 = BossHealthField.GetValue(bossUi);
		Image val2 = (Image)((value2 is Image) ? value2 : null);
		object? value3 = BossHealthLerpedField.GetValue(bossUi);
		Image val3 = (Image)((value3 is Image) ? value3 : null);
		if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null || (Object)(object)val3 == (Object)null)
		{
			return false;
		}
		Rect rect = ((Graphic)val2).rectTransform.rect;
		Vector2 size = ((Rect)(ref rect)).size;
		if (size.x < 100f)
		{
			size.x = 1065f;
		}
		if (size.y < 12f)
		{
			size.y = 38f;
		}
		_mainCanvas = mainCanvas;
		GameObject val4 = new GameObject("FishHPHUD", new Type[2]
		{
			typeof(RectTransform),
			typeof(CanvasGroup)
		});
		val4.transform.SetParent(((Component)mainCanvas).transform, false);
		_wrapper = val4.GetComponent<RectTransform>();
		_group = val4.GetComponent<CanvasGroup>();
		RectTransform wrapper = _wrapper;
		Vector2 anchorMin = (_wrapper.anchorMax = new Vector2(0f, 1f));
		wrapper.anchorMin = anchorMin;
		_wrapper.pivot = new Vector2(0f, 1f);
		_wrapper.sizeDelta = new Vector2(1200f, 150f);
		_moveRoot = CreateRect("FishHPMove", (Transform)(object)_wrapper);
		StretchToParent(_moveRoot);
		_startPosition = ((Transform)_moveRoot).localPosition;
		_rotateRoot = CreateRect("FishHPRotate", (Transform)(object)_moveRoot);
		StretchToParent(_rotateRoot);
		_nameText = Object.Instantiate<TextMeshProUGUI>(val, (Transform)(object)_rotateRoot);
		((Object)_nameText).name = "FishName";
		((Component)_nameText).gameObject.SetActive(true);
		((Behaviour)_nameText).enabled = true;
		RectTransform rectTransform = ((TMP_Text)_nameText).rectTransform;
		Vector2 anchorMin2 = (rectTransform.anchorMax = new Vector2(0f, 1f));
		rectTransform.anchorMin = anchorMin2;
		rectTransform.pivot = new Vector2(0f, 1f);
		rectTransform.anchoredPosition = Vector2.zero;
		rectTransform.sizeDelta = new Vector2(Mathf.Max(200f, size.x - 340f), 48f);
		((Transform)rectTransform).localScale = Vector3.one;
		((Transform)rectTransform).localRotation = Quaternion.identity;
		_hpText = Object.Instantiate<TextMeshProUGUI>(val, (Transform)(object)_rotateRoot);
		((Object)_hpText).name = "FishHPText";
		((Component)_hpText).gameObject.SetActive(true);
		((Behaviour)_hpText).enabled = true;
		((TMP_Text)_hpText).alignment = (TextAlignmentOptions)260;
		((Graphic)_hpText).raycastTarget = false;
		((TMP_Text)_hpText).text = string.Empty;
		RectTransform rectTransform2 = ((TMP_Text)_hpText).rectTransform;
		Vector2 anchorMin3 = (rectTransform2.anchorMax = new Vector2(0f, 1f));
		rectTransform2.anchorMin = anchorMin3;
		rectTransform2.pivot = new Vector2(1f, 1f);
		rectTransform2.anchoredPosition = new Vector2(size.x, 0f);
		rectTransform2.sizeDelta = new Vector2(320f, 48f);
		((Transform)rectTransform2).localScale = Vector3.one;
		((Transform)rectTransform2).localRotation = Quaternion.identity;
		RectTransform val8 = CreateRect("FishHealthBar", (Transform)(object)_rotateRoot);
		Vector2 anchorMin4 = (val8.anchorMax = new Vector2(0f, 1f));
		val8.anchorMin = anchorMin4;
		val8.pivot = new Vector2(0f, 1f);
		val8.anchoredPosition = new Vector2(0f, -52f);
		val8.sizeDelta = size;
		Image val10 = CreateNativeImage("Border", (Transform)(object)val8, val3, filled: false);
		SetImageRect(((Graphic)val10).rectTransform, new Vector2(-4f, -4f), new Vector2(4f, 4f));
		((Graphic)val10).color = new Color(1f, 1f, 1f, 1f);
		Image val11 = CreateNativeImage("Background", (Transform)(object)val8, val2, filled: false);
		SetImageRect(((Graphic)val11).rectTransform, Vector2.zero, Vector2.zero);
		((Graphic)val11).color = new Color(0.055f, 0.075f, 0.12f, 0.9f);
		_healthLerped = CreateNativeImage("DamageTrail", (Transform)(object)val8, val3, filled: true);
		SetImageRect(((Graphic)_healthLerped).rectTransform, Vector2.zero, Vector2.zero);
		((Graphic)_healthLerped).color = ((Graphic)val3).color;
		_health = CreateNativeImage("Health", (Transform)(object)val8, val2, filled: true);
		SetImageRect(((Graphic)_health).rectTransform, Vector2.zero, Vector2.zero);
		((Graphic)_health).color = GameInfo.RedColor;
		((TMP_Text)_nameText).text = string.Empty;
		((Graphic)_nameText).raycastTarget = false;
		((Graphic)_health).raycastTarget = false;
		((Graphic)_healthLerped).raycastTarget = false;
		_velocity = Vector3.zero;
		_angularVelocity = Vector3.zero;
		ApplyLiveSettings();
		((BaseUnityPlugin)this).Logger.LogInfo((object)"Created independent Fish HP bar from the game's native sprites and text style.");
		return true;
	}

	private void UpdateHpText(int current, int maximum)
	{
		if (!((Object)(object)_hpText == (Object)null))
		{
			((TMP_Text)_hpText).text = FormatHp(current) + " / " + FormatHp(maximum);
		}
	}

	private static string FormatHp(int value)
	{
		return value.ToString("N0", CultureInfo.InvariantCulture);
	}

	private static RectTransform CreateRect(string name, Transform parent)
	{
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Expected O, but got Unknown
		GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) });
		val.transform.SetParent(parent, false);
		return val.GetComponent<RectTransform>();
	}

	private static void StretchToParent(RectTransform rect)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: 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_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		rect.anchorMin = Vector2.zero;
		rect.anchorMax = Vector2.one;
		rect.pivot = new Vector2(0.5f, 0.5f);
		rect.offsetMin = Vector2.zero;
		rect.offsetMax = Vector2.zero;
		((Transform)rect).localScale = Vector3.one;
		((Transform)rect).localRotation = Quaternion.identity;
	}

	private static Image CreateNativeImage(string name, Transform parent, Image template, bool filled)
	{
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Expected O, but got Unknown
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject(name, new Type[3]
		{
			typeof(RectTransform),
			typeof(CanvasRenderer),
			typeof(Image)
		});
		val.transform.SetParent(parent, false);
		Image component = val.GetComponent<Image>();
		component.sprite = template.sprite;
		component.overrideSprite = template.overrideSprite;
		((Graphic)component).material = ((Graphic)template).material;
		component.preserveAspect = false;
		((Graphic)component).raycastTarget = false;
		component.type = (Type)(filled ? 3 : ((int)BorderImageType(template)));
		if (filled)
		{
			component.fillMethod = (FillMethod)0;
			component.fillOrigin = 0;
			component.fillClockwise = true;
			component.fillAmount = 1f;
		}
		return component;
	}

	private static Type BorderImageType(Image template)
	{
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)template.sprite != (Object)null)
		{
			Vector4 border = template.sprite.border;
			if (((Vector4)(ref border)).sqrMagnitude > 0f)
			{
				return (Type)1;
			}
		}
		return (Type)0;
	}

	private static void SetImageRect(RectTransform rect, Vector2 minimumOffset, Vector2 maximumOffset)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: 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_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		rect.anchorMin = Vector2.zero;
		rect.anchorMax = Vector2.one;
		rect.offsetMin = minimumOffset;
		rect.offsetMax = maximumOffset;
		((Transform)rect).localScale = Vector3.one;
		((Transform)rect).localRotation = Quaternion.identity;
	}

	private static bool TryFindTemplates(out BossUI bossUi, out CanvasGroup mainCanvas)
	{
		bossUi = null;
		mainCanvas = null;
		if (MainCanvasField == null || BossNameField == null || BossHealthField == null || BossHealthLerpedField == null)
		{
			return false;
		}
		PlayerUI[] array = Resources.FindObjectsOfTypeAll<PlayerUI>();
		PlayerUI[] array2 = array;
		foreach (PlayerUI val in array2)
		{
			if (!((Object)(object)val == (Object)null) && ((Component)val).gameObject.activeInHierarchy)
			{
				object? value = MainCanvasField.GetValue(val);
				CanvasGroup val2 = (CanvasGroup)((value is CanvasGroup) ? value : null);
				if ((Object)(object)val2 != (Object)null)
				{
					mainCanvas = val2;
					break;
				}
			}
		}
		if ((Object)(object)mainCanvas == (Object)null)
		{
			return false;
		}
		BossUI[] array3 = Resources.FindObjectsOfTypeAll<BossUI>();
		BossUI[] array4 = array3;
		foreach (BossUI val3 in array4)
		{
			if (!((Object)(object)val3 == (Object)null) && ((Component)val3).gameObject.activeInHierarchy && BossNameField.GetValue(val3) != null && BossHealthField.GetValue(val3) != null && BossHealthLerpedField.GetValue(val3) != null)
			{
				bossUi = val3;
				break;
			}
		}
		return (Object)(object)bossUi != (Object)null;
	}

	private void DisableNonHealthVisuals(RectTransform originalMove, Image originalHealth, Image originalLerped, Image originalTime)
	{
		Transform original = FindCommonAncestor(((Component)originalHealth).transform, ((Component)originalLerped).transform, (Transform)(object)originalMove);
		Transform val = FindCloneTransform((Transform)(object)originalMove, original, (Transform)(object)_moveRoot);
		TextMeshProUGUI[] componentsInChildren = ((Component)_moveRoot).GetComponentsInChildren<TextMeshProUGUI>(true);
		TextMeshProUGUI[] array = componentsInChildren;
		foreach (TextMeshProUGUI val2 in array)
		{
			if ((Object)(object)val2 != (Object)(object)_nameText)
			{
				((Behaviour)val2).enabled = false;
			}
		}
		Image[] componentsInChildren2 = ((Component)_moveRoot).GetComponentsInChildren<Image>(true);
		Image[] array2 = componentsInChildren2;
		foreach (Image val3 in array2)
		{
			if (!((Object)(object)val != (Object)null) || (!((Object)(object)((Component)val3).transform == (Object)(object)val) && !((Component)val3).transform.IsChildOf(val)))
			{
				((Behaviour)val3).enabled = false;
			}
		}
		if ((Object)(object)originalTime != (Object)null)
		{
			Transform val4 = FindCloneTransform((Transform)(object)originalMove, ((Component)originalTime).transform, (Transform)(object)_moveRoot);
			if ((Object)(object)val4 != (Object)null && (Object)(object)val4.parent != (Object)null && (Object)(object)val4.parent != (Object)(object)_moveRoot && !ContainsTransform(val4.parent, ((Component)_health).transform) && !ContainsTransform(val4.parent, ((Component)_healthLerped).transform))
			{
				((Component)val4.parent).gameObject.SetActive(false);
			}
			else if ((Object)(object)val4 != (Object)null)
			{
				((Component)val4).gameObject.SetActive(false);
			}
		}
	}

	private void AlignCloneToTopLeft()
	{
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		//IL_0058: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: 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)
		//IL_0084: Unknown result type (might be due to invalid IL or missing references)
		//IL_0089: Unknown result type (might be due to invalid IL or missing references)
		//IL_009a: Unknown result type (might be due to invalid IL or missing references)
		//IL_009f: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)_wrapper == (Object)null) && !((Object)(object)_moveRoot == (Object)null) && !((Object)(object)_health == (Object)null))
		{
			((Graphic)_health).rectTransform.GetWorldCorners(_barCorners);
			Vector3 val = ((Transform)_wrapper).InverseTransformPoint(_barCorners[1]);
			RectTransform moveRoot = _moveRoot;
			((Transform)moveRoot).localPosition = ((Transform)moveRoot).localPosition + new Vector3(0f - val.x, -52f - val.y, 0f);
			_startPosition = ((Transform)_moveRoot).localPosition;
		}
	}

	private static void SetActivePath(Transform child, Transform root)
	{
		Transform val = child;
		while ((Object)(object)val != (Object)null)
		{
			((Component)val).gameObject.SetActive(true);
			if ((Object)(object)val == (Object)(object)root)
			{
				break;
			}
			val = val.parent;
		}
	}

	private static Transform FindCommonAncestor(Transform first, Transform second, Transform limit)
	{
		Transform val = first;
		while ((Object)(object)val != (Object)null)
		{
			if ((Object)(object)second == (Object)(object)val || second.IsChildOf(val))
			{
				return val;
			}
			if ((Object)(object)val == (Object)(object)limit)
			{
				break;
			}
			val = val.parent;
		}
		return limit;
	}

	private static bool ContainsTransform(Transform parent, Transform child)
	{
		if (!((Object)(object)child == (Object)(object)parent))
		{
			return child.IsChildOf(parent);
		}
		return true;
	}

	private static T FindCloneComponent<T>(RectTransform originalRoot, RectTransform original, RectTransform cloneRoot) where T : Component
	{
		Transform val = FindCloneTransform((Transform)(object)originalRoot, (Transform)(object)original, (Transform)(object)cloneRoot);
		if (!((Object)(object)val == (Object)null))
		{
			return ((Component)val).GetComponent<T>();
		}
		return default(T);
	}

	private static Transform FindCloneTransform(Transform originalRoot, Transform original, Transform cloneRoot)
	{
		if ((Object)(object)original == (Object)null)
		{
			return null;
		}
		if ((Object)(object)original == (Object)(object)originalRoot)
		{
			return cloneRoot;
		}
		string text = RelativePath(originalRoot, original);
		if (!string.IsNullOrEmpty(text))
		{
			return cloneRoot.Find(text);
		}
		return cloneRoot;
	}

	private static string RelativePath(Transform root, Transform child)
	{
		string text = ((Object)child).name;
		Transform parent = child.parent;
		while ((Object)(object)parent != (Object)null && (Object)(object)parent != (Object)(object)root)
		{
			text = ((Object)parent).name + "/" + text;
			parent = parent.parent;
		}
		if (!((Object)(object)parent == (Object)(object)root))
		{
			return string.Empty;
		}
		return text;
	}

	private static string SafeName(Creature creature)
	{
		try
		{
			string name = ((Item)creature).GetName();
			return string.IsNullOrEmpty(name) ? "Fish" : name;
		}
		catch
		{
			return "Fish";
		}
	}

	private void ApplyLiveSettings()
	{
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_005a: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)_wrapper == (Object)null) && !((Object)(object)_group == (Object)null))
		{
			_wrapper.anchoredPosition = new Vector2(_leftOffset.Value, 0f - _topOffset.Value);
			((Transform)_wrapper).localScale = Vector3.one * _scale.Value;
			if (!_isFadingOut)
			{
				_group.alpha = _opacity.Value;
			}
		}
	}

	private void BeginDeathFade()
	{
		if ((Object)(object)_group == (Object)null)
		{
			ClearTarget(destroyHud: false);
		}
		else if (!_isFadingOut)
		{
			_isFadingOut = true;
			LeanTween.cancel(((Component)_group).gameObject);
			LeanTween.value(((Component)_group).gameObject, _group.alpha, 0f, 0.5f).setEase((LeanTweenType)2).setOnUpdate((Action<float>)SetGroupAlpha)
				.setOnComplete((Action)FinishDeathFade);
		}
	}

	private void SetGroupAlpha(float value)
	{
		if ((Object)(object)_group != (Object)null)
		{
			_group.alpha = value;
		}
	}

	private void FinishDeathFade()
	{
		ClearTarget(destroyHud: false);
	}

	private void ClearTarget(bool destroyHud)
	{
		_target = null;
		_shownHp = -1;
		_shownMaxHp = -1;
		_predictionUntil = 0f;
		_isFadingOut = false;
		SetRootVisible(visible: false);
		if (destroyHud)
		{
			DestroyHud();
		}
	}

	private void SetRootVisible(bool visible)
	{
		if ((Object)(object)_wrapper != (Object)null && ((Component)_wrapper).gameObject.activeSelf != visible)
		{
			((Component)_wrapper).gameObject.SetActive(visible);
		}
	}

	private void DestroyHud()
	{
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		//IL_0069: Unknown result type (might be due to invalid IL or missing references)
		//IL_006e: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)_wrapper != (Object)null)
		{
			Object.Destroy((Object)(object)((Component)_wrapper).gameObject);
		}
		_mainCanvas = null;
		_wrapper = null;
		_group = null;
		_moveRoot = null;
		_rotateRoot = null;
		_nameText = null;
		_hpText = null;
		_health = null;
		_healthLerped = null;
		_velocity = Vector3.zero;
		_angularVelocity = Vector3.zero;
	}

	private void OnDestroy()
	{
		if (_harmony != null)
		{
			_harmony.UnpatchSelf();
		}
		ClearTarget(destroyHud: true);
		if ((Object)(object)_instance == (Object)(object)this)
		{
			_instance = null;
		}
	}
}