using System;
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Configuration;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
[assembly: AssemblyDescription("Shows the active boss's exact synchronized HP beside the native health bar.")]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyCompany("evansvl")]
[assembly: CompilationRelaxations(8)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace HowToFish.BossHP;
[BepInPlugin("community.howtofish.bosshp", "Boss HP", "0.1.2")]
public sealed class Plugin : BaseUnityPlugin
{
public const string PluginGuid = "community.howtofish.bosshp";
public const string PluginName = "Boss HP";
public const string PluginVersion = "0.1.2";
private static readonly FieldInfo BossHealthField = typeof(BossUI).GetField("_bossHealth", BindingFlags.Instance | BindingFlags.NonPublic);
private static readonly FieldInfo BossNameField = typeof(BossUI).GetField("_bossNameText", BindingFlags.Instance | BindingFlags.NonPublic);
private static readonly FieldInfo BossHpRotateField = typeof(BossUI).GetField("_bossHpToRotate", BindingFlags.Instance | BindingFlags.NonPublic);
private ConfigEntry<bool> _enabled;
private ConfigEntry<bool> _showMaximum;
private ConfigEntry<float> _scale;
private ConfigEntry<float> _opacity;
private ConfigEntry<float> _horizontalOffset;
private ConfigEntry<float> _verticalOffset;
private BossUI _nativeBossUi;
private Image _nativeHealth;
private RectTransform _nativeHudRoot;
private TextMeshProUGUI _text;
private readonly Vector3[] _healthCorners = (Vector3[])(object)new Vector3[4];
private void Awake()
{
//IL_0072: Unknown result type (might be due to invalid IL or missing references)
//IL_007c: Expected O, but got Unknown
//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
//IL_00bb: Expected O, but got Unknown
//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
//IL_00fa: Expected O, but got Unknown
//IL_012f: Unknown result type (might be due to invalid IL or missing references)
//IL_0139: Expected O, but got Unknown
_enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("HUD", "Enabled", true, "Show exact boss HP beside the native boss health bar.");
_showMaximum = ((BaseUnityPlugin)this).Config.Bind<bool>("HUD", "ShowMaximum", true, "Show current and maximum HP instead of current HP only.");
_scale = ((BaseUnityPlugin)this).Config.Bind<float>("HUD", "Scale", 1f, new ConfigDescription("Boss HP text scale.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.6f, 1.8f), new object[0]));
_opacity = ((BaseUnityPlugin)this).Config.Bind<float>("HUD", "Opacity", 1f, new ConfigDescription("Boss HP text opacity.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.2f, 1f), new object[0]));
_horizontalOffset = ((BaseUnityPlugin)this).Config.Bind<float>("Position", "HorizontalOffset", 18f, new ConfigDescription("Distance to the left of the native health bar.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 180f), new object[0]));
_verticalOffset = ((BaseUnityPlugin)this).Config.Bind<float>("Position", "VerticalOffset", 0f, new ConfigDescription("Vertical adjustment relative to the native health bar.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-80f, 80f), new object[0]));
((BaseUnityPlugin)this).Logger.LogInfo((object)"Loaded. Boss HP reads synchronized boss state and attaches text to the native boss health bar.");
}
private void Update()
{
Creature boss = BossManager.Boss;
if (!_enabled.Value || (Object)(object)boss == (Object)null || boss.IsDead || !IsGameplayBossHudVisible())
{
SetVisible(visible: false);
return;
}
if (!EnsureAttached())
{
SetVisible(visible: false);
return;
}
int num = BossManager.BossMaxHp;
if (num <= 0)
{
num = boss.MaxHp;
}
if (num <= 0)
{
SetVisible(visible: false);
return;
}
int value = Math.Max(0, Math.Min(boss.Hp, num));
((TMP_Text)_text).text = (_showMaximum.Value ? (FormatHp(value) + " / " + FormatHp(num)) : FormatHp(value));
ApplyLiveSettings();
SetVisible(visible: true);
}
private static bool IsGameplayBossHudVisible()
{
if (MainMenuManager.IsInMenu || PauseManager.IsPaused)
{
return false;
}
try
{
return PlayerUI.BossCanvasActive;
}
catch
{
return false;
}
}
private bool EnsureAttached()
{
if ((Object)(object)_nativeBossUi != (Object)null && (Object)(object)_nativeHealth != (Object)null && (Object)(object)_nativeHudRoot != (Object)null && (Object)(object)_text != (Object)null)
{
return true;
}
ClearAttachment();
if (BossHealthField == null || BossHpRotateField == null)
{
return false;
}
BossUI[] array = Resources.FindObjectsOfTypeAll<BossUI>();
BossUI[] array2 = array;
foreach (BossUI val in array2)
{
if (!((Object)(object)val == (Object)null) && ((Component)val).gameObject.activeInHierarchy)
{
object? value = BossHealthField.GetValue(val);
Image val2 = (Image)((value is Image) ? value : null);
object? value2 = BossHpRotateField.GetValue(val);
RectTransform val3 = (RectTransform)((value2 is RectTransform) ? value2 : null);
if (!((Object)(object)val2 == (Object)null) && !((Object)(object)((Graphic)val2).rectTransform == (Object)null) && !((Object)(object)val3 == (Object)null))
{
_nativeBossUi = val;
_nativeHealth = val2;
_nativeHudRoot = val3;
CreateText(val3, FindTemplate(val));
((BaseUnityPlugin)this).Logger.LogInfo((object)"Attached numeric HP to the native boss shake-and-rotation transform.");
return (Object)(object)_text != (Object)null;
}
}
}
return false;
}
private void CreateText(RectTransform hudRoot, TextMeshProUGUI template)
{
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
//IL_003a: Expected O, but got Unknown
//IL_0076: Unknown result type (might be due to invalid IL or missing references)
//IL_007b: Unknown result type (might be due to invalid IL or missing references)
//IL_007c: Unknown result type (might be due to invalid IL or missing references)
//IL_0082: Unknown result type (might be due to invalid IL or missing references)
//IL_0093: Unknown result type (might be due to invalid IL or missing references)
//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
//IL_015f: Unknown result type (might be due to invalid IL or missing references)
GameObject val = new GameObject("BossHPText", new Type[3]
{
typeof(RectTransform),
typeof(CanvasRenderer),
typeof(TextMeshProUGUI)
});
val.transform.SetParent((Transform)(object)hudRoot, false);
val.transform.SetAsLastSibling();
_text = val.GetComponent<TextMeshProUGUI>();
RectTransform rectTransform = ((TMP_Text)_text).rectTransform;
Vector2 anchorMin = (rectTransform.anchorMax = new Vector2(0.5f, 0.5f));
rectTransform.anchorMin = anchorMin;
rectTransform.pivot = new Vector2(1f, 0.5f);
rectTransform.sizeDelta = new Vector2(300f, 70f);
if ((Object)(object)template != (Object)null && (Object)(object)((TMP_Text)template).font != (Object)null)
{
((TMP_Text)_text).font = ((TMP_Text)template).font;
if ((Object)(object)((TMP_Text)template).fontSharedMaterial != (Object)null)
{
((TMP_Text)_text).fontSharedMaterial = ((TMP_Text)template).fontSharedMaterial;
}
((TMP_Text)_text).characterSpacing = ((TMP_Text)template).characterSpacing;
}
((TMP_Text)_text).fontSize = 30f;
((TMP_Text)_text).alignment = (TextAlignmentOptions)4100;
((TMP_Text)_text).enableWordWrapping = false;
((TMP_Text)_text).overflowMode = (TextOverflowModes)0;
((Graphic)_text).raycastTarget = false;
((TMP_Text)_text).outlineColor = new Color32((byte)20, (byte)18, (byte)18, byte.MaxValue);
((TMP_Text)_text).outlineWidth = 0.18f;
((TMP_Text)_text).text = string.Empty;
}
private static TextMeshProUGUI FindTemplate(BossUI bossUi)
{
TextMeshProUGUI val = (TextMeshProUGUI)((BossNameField == null) ? null : /*isinst with value type is only supported in some contexts*/);
if ((Object)(object)val != (Object)null && (Object)(object)((TMP_Text)val).font != (Object)null)
{
return val;
}
TextMeshProUGUI[] array = Resources.FindObjectsOfTypeAll<TextMeshProUGUI>();
TextMeshProUGUI[] array2 = array;
foreach (TextMeshProUGUI val2 in array2)
{
if ((Object)(object)val2 != (Object)null && ((TMP_Text)val2).text != null && ((TMP_Text)val2).text.IndexOf("Version", StringComparison.OrdinalIgnoreCase) >= 0)
{
return val2;
}
}
return null;
}
private void ApplyLiveSettings()
{
//IL_002e: 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)
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
//IL_0053: Unknown result type (might be due to invalid IL or missing references)
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_0060: Unknown result type (might be due to invalid IL or missing references)
//IL_008d: Unknown result type (might be due to invalid IL or missing references)
//IL_0098: Unknown result type (might be due to invalid IL or missing references)
//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
RectTransform rectTransform = ((TMP_Text)_text).rectTransform;
((Graphic)_nativeHealth).rectTransform.GetWorldCorners(_healthCorners);
Vector3 val = (_healthCorners[0] + _healthCorners[1]) * 0.5f;
Vector3 val2 = ((Transform)_nativeHudRoot).InverseTransformPoint(val);
((Transform)rectTransform).localPosition = new Vector3(val2.x - _horizontalOffset.Value, val2.y + _verticalOffset.Value, 0f);
((Transform)rectTransform).localScale = Vector3.one * _scale.Value;
((Graphic)_text).color = new Color(1f, 1f, 1f, _opacity.Value);
}
private static string FormatHp(int value)
{
return value.ToString("N0", CultureInfo.InvariantCulture);
}
private void SetVisible(bool visible)
{
if ((Object)(object)_text != (Object)null && ((Behaviour)_text).enabled != visible)
{
((Behaviour)_text).enabled = visible;
}
}
private void ClearAttachment()
{
if ((Object)(object)_text != (Object)null)
{
Object.Destroy((Object)(object)((Component)_text).gameObject);
}
_text = null;
_nativeHealth = null;
_nativeHudRoot = null;
_nativeBossUi = null;
}
private void OnDestroy()
{
ClearAttachment();
}
}