using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Events;
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("Omniscye")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("EnemyHealthBars")]
[assembly: AssemblyTitle("EnemyHealthBars")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
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;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace Empress.EnemyHealthBars
{
[BepInPlugin("Empress.EnemyHealthBars", "Enemy Health Bars", "1.0.1")]
public class EnemyHealthBarsPlugin : BaseUnityPlugin
{
internal static ConfigEntry<bool> AlwaysShow;
internal static ConfigEntry<float> ShowOnDamageSeconds;
internal static ConfigEntry<float> BarWidth;
internal static ConfigEntry<float> BarHeight;
internal static ConfigEntry<float> OffsetPercentOfHeight;
internal static ConfigEntry<float> ExtraOffsetMeters;
internal static ConfigEntry<float> DistanceScaleFactor;
internal static ConfigEntry<float> MinScale;
internal static ConfigEntry<float> MaxScale;
internal static ConfigEntry<bool> OnlyWhenVisible;
internal static ConfigEntry<float> LerpSpeed;
internal static ConfigEntry<bool> UseMeshParentIfAvailable;
internal static ConfigEntry<float> ChipDropSpeed;
internal static ConfigEntry<float> HealCatchupSpeed;
internal static EnemyHealthBarsPlugin Instance { get; private set; }
internal static ManualLogSource Logger => Instance._logger;
private ManualLogSource _logger => ((BaseUnityPlugin)this).Logger;
internal Harmony? Harmony { get; private set; }
private void Awake()
{
Instance = this;
((Component)this).gameObject.transform.parent = null;
((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
AlwaysShow = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "AlwaysShow", true, "If true, health bars are always visible. If false, they show for a short time after damage.");
ShowOnDamageSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("General", "ShowOnDamageSeconds", 2.5f, "Seconds to keep the bar visible after damage when AlwaysShow is false.");
BarWidth = ((BaseUnityPlugin)this).Config.Bind<float>("Style", "BarWidth", 1f, "Base width before distance scaling.");
BarHeight = ((BaseUnityPlugin)this).Config.Bind<float>("Style", "BarHeight", 0.1f, "Bar height.");
OffsetPercentOfHeight = ((BaseUnityPlugin)this).Config.Bind<float>("Position", "OffsetPercentOfHeight", 0.2f, "How far above the top of the model to place the bar as a percentage of the model height.");
ExtraOffsetMeters = ((BaseUnityPlugin)this).Config.Bind<float>("Position", "ExtraOffsetMeters", 0.15f, "Extra vertical meters to add above the top.");
DistanceScaleFactor = ((BaseUnityPlugin)this).Config.Bind<float>("Style", "DistanceScaleFactor", 0.015f, "Scale per meter.");
MinScale = ((BaseUnityPlugin)this).Config.Bind<float>("Style", "MinScale", 0.3f, "Min scale.");
MaxScale = ((BaseUnityPlugin)this).Config.Bind<float>("Style", "MaxScale", 2f, "Max scale.");
OnlyWhenVisible = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "OnlyWhenVisible", true, "Hide the bar when the enemy renderers are not visible to the camera.");
LerpSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Style", "LerpSpeed", 12f, "Front bar heal smoothing speed.");
UseMeshParentIfAvailable = ((BaseUnityPlugin)this).Config.Bind<bool>("Position", "UseMeshParentIfAvailable", true, "Anchor bar to EnemyHealth.meshParent if it's set; otherwise use the enemy root.");
ChipDropSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Style", "ChipDropSpeed", 6f, "Speed the dark-red damage chip falls toward the current health after damage.");
HealCatchupSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Style", "HealCatchupSpeed", 16f, "Speed the damage chip catches up when healing.");
Patch();
Logger.LogInfo((object)$"{((BaseUnityPlugin)this).Info.Metadata.GUID} v{((BaseUnityPlugin)this).Info.Metadata.Version} loaded. Painting them red.");
try
{
Type type = AccessTools.TypeByName("EnemyHealth");
MethodInfo methodInfo = AccessTools.Method(type, "Awake", (Type[])null, (Type[])null);
if (methodInfo != null)
{
Logger.LogInfo((object)"Harmony: EnemyHealth.Awake patched OK");
}
else
{
Logger.LogWarning((object)"Harmony: EnemyHealth.Awake not found - bars will not attach to new spawns");
}
}
catch (Exception ex)
{
Logger.LogWarning((object)("Harmony check failed: " + ex.Message));
}
TryAttachToExisting();
}
internal void Patch()
{
//IL_001a: 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_0021: Expected O, but got Unknown
//IL_0026: Expected O, but got Unknown
if (Harmony == null)
{
Harmony val = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID);
Harmony val2 = val;
Harmony = val;
}
Harmony.PatchAll();
}
internal void Unpatch()
{
Harmony? harmony = Harmony;
if (harmony != null)
{
harmony.UnpatchSelf();
}
}
private void TryAttachToExisting()
{
try
{
MonoBehaviour[] array = Object.FindObjectsOfType<MonoBehaviour>();
MonoBehaviour[] array2 = array;
foreach (MonoBehaviour val in array2)
{
if (!((Object)(object)val == (Object)null))
{
Type type = ((object)val).GetType();
if (type.Name == "EnemyHealth")
{
HealthBarAttacher.AttachTo(val);
}
}
}
}
catch (Exception arg)
{
Logger.LogWarning((object)$"Scan failed: {arg}");
}
}
}
[HarmonyPatch]
internal static class EnemyHealthPatches
{
private static MethodBase TargetMethod()
{
return AccessTools.Method(AccessTools.TypeByName("EnemyHealth"), "Awake", (Type[])null, (Type[])null);
}
[HarmonyPostfix]
private static void Post_Awake(MonoBehaviour __instance)
{
HealthBarAttacher.AttachTo(__instance);
}
}
[HarmonyPatch]
internal static class EnemyHealthAttachFallbackPatches
{
[CompilerGenerated]
private sealed class <TargetMethods>d__0 : IEnumerable<MethodBase>, IEnumerable, IEnumerator<MethodBase>, IEnumerator, IDisposable
{
private int <>1__state;
private MethodBase <>2__current;
private int <>l__initialThreadId;
private Type <t>5__1;
private string[] <names>5__2;
private string[] <>s__3;
private int <>s__4;
private string <n>5__5;
private MethodInfo <m>5__6;
MethodBase IEnumerator<MethodBase>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <TargetMethods>d__0(int <>1__state)
{
this.<>1__state = <>1__state;
<>l__initialThreadId = Environment.CurrentManagedThreadId;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<t>5__1 = null;
<names>5__2 = null;
<>s__3 = null;
<n>5__5 = null;
<m>5__6 = null;
<>1__state = -2;
}
private bool MoveNext()
{
int num = <>1__state;
if (num != 0)
{
if (num != 1)
{
return false;
}
<>1__state = -1;
goto IL_00be;
}
<>1__state = -1;
<t>5__1 = AccessTools.TypeByName("EnemyHealth");
<names>5__2 = new string[2] { "Start", "OnEnable" };
<>s__3 = <names>5__2;
<>s__4 = 0;
goto IL_00db;
IL_00be:
<m>5__6 = null;
<n>5__5 = null;
<>s__4++;
goto IL_00db;
IL_00db:
if (<>s__4 < <>s__3.Length)
{
<n>5__5 = <>s__3[<>s__4];
<m>5__6 = AccessTools.Method(<t>5__1, <n>5__5, (Type[])null, (Type[])null);
if (<m>5__6 != null)
{
<>2__current = <m>5__6;
<>1__state = 1;
return true;
}
goto IL_00be;
}
<>s__3 = null;
return false;
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
[DebuggerHidden]
IEnumerator<MethodBase> IEnumerable<MethodBase>.GetEnumerator()
{
if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
{
<>1__state = 0;
return this;
}
return new <TargetMethods>d__0(0);
}
[DebuggerHidden]
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable<MethodBase>)this).GetEnumerator();
}
}
[IteratorStateMachine(typeof(<TargetMethods>d__0))]
private static IEnumerable<MethodBase> TargetMethods()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <TargetMethods>d__0(-2);
}
[HarmonyPostfix]
private static void Post_AttachFallback(MonoBehaviour __instance)
{
HealthBarAttacher.AttachTo(__instance);
}
}
[HarmonyPatch]
internal static class EnemyHealthEventPatches
{
[CompilerGenerated]
private sealed class <TargetMethods>d__2 : IEnumerable<MethodBase>, IEnumerable, IEnumerator<MethodBase>, IEnumerator, IDisposable
{
private int <>1__state;
private MethodBase <>2__current;
private int <>l__initialThreadId;
private string[] <names>5__1;
private string[] <>s__2;
private int <>s__3;
private string <n>5__4;
private MethodInfo <m>5__5;
MethodBase IEnumerator<MethodBase>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <TargetMethods>d__2(int <>1__state)
{
this.<>1__state = <>1__state;
<>l__initialThreadId = Environment.CurrentManagedThreadId;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<names>5__1 = null;
<>s__2 = null;
<n>5__4 = null;
<m>5__5 = null;
<>1__state = -2;
}
private bool MoveNext()
{
int num = <>1__state;
if (num != 0)
{
if (num != 1)
{
return false;
}
<>1__state = -1;
goto IL_00d5;
}
<>1__state = -1;
<names>5__1 = new string[7] { "Hurt", "HurtRPC", "Heal", "HealRPC", "Death", "DeathRPC", "DeathImpulseRPC" };
<>s__2 = <names>5__1;
<>s__3 = 0;
goto IL_00f2;
IL_00d5:
<m>5__5 = null;
<n>5__4 = null;
<>s__3++;
goto IL_00f2;
IL_00f2:
if (<>s__3 < <>s__2.Length)
{
<n>5__4 = <>s__2[<>s__3];
<m>5__5 = AccessTools.Method(EH, <n>5__4, (Type[])null, (Type[])null);
if (<m>5__5 != null)
{
<>2__current = <m>5__5;
<>1__state = 1;
return true;
}
goto IL_00d5;
}
<>s__2 = null;
return false;
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
[DebuggerHidden]
IEnumerator<MethodBase> IEnumerable<MethodBase>.GetEnumerator()
{
if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
{
<>1__state = 0;
return this;
}
return new <TargetMethods>d__2(0);
}
[DebuggerHidden]
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable<MethodBase>)this).GetEnumerator();
}
}
private static Type EH => AccessTools.TypeByName("EnemyHealth");
[IteratorStateMachine(typeof(<TargetMethods>d__2))]
private static IEnumerable<MethodBase> TargetMethods()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <TargetMethods>d__2(-2);
}
[HarmonyPostfix]
private static void Post_HPEvents(MonoBehaviour __instance)
{
EnemyHealthBar component = ((Component)__instance).GetComponent<EnemyHealthBar>();
if ((Object)(object)component != (Object)null)
{
component.OnHealthTouched();
}
}
}
internal static class HealthBarAttacher
{
internal static void AttachTo(MonoBehaviour enemyHealth)
{
if ((Object)(object)enemyHealth == (Object)null)
{
return;
}
Type type = ((object)enemyHealth).GetType();
if (type.Name != "EnemyHealth" || (Object)(object)((Component)enemyHealth).GetComponent<EnemyHealthBar>() != (Object)null)
{
return;
}
try
{
EnemyHealthBar enemyHealthBar = ((Component)enemyHealth).gameObject.AddComponent<EnemyHealthBar>();
enemyHealthBar.Initialize(enemyHealth);
}
catch (Exception arg)
{
EnemyHealthBarsPlugin.Logger.LogWarning((object)$"Failed to attach health bar: {arg}");
}
}
}
public class EnemyHealthBar : MonoBehaviour
{
private static readonly Type EH = AccessTools.TypeByName("EnemyHealth");
private static readonly FieldInfo F_health = AccessTools.Field(EH, "health");
private static readonly FieldInfo F_healthCurrent = AccessTools.Field(EH, "healthCurrent");
private static readonly FieldInfo F_dead = AccessTools.Field(EH, "dead");
private static readonly FieldInfo F_meshParent = AccessTools.Field(EH, "meshParent");
private static readonly FieldInfo F_onHurt = AccessTools.Field(EH, "onHurt");
private static readonly FieldInfo F_onDeath = AccessTools.Field(EH, "onDeath");
private MonoBehaviour enemyHealth = null;
private int maxHealth;
private int lastHealth;
private bool dead;
private Transform anchor = null;
private readonly List<Renderer> renderers = new List<Renderer>();
private GameObject rootGO = null;
private Canvas canvas = null;
private RectTransform rect = null;
private Image imgFill = null;
private Image imgChip = null;
private Image imgBack = null;
private Text textComp = null;
private float showTimer;
private float currentFill = 1f;
private float chipFill = 1f;
private Camera cachedCam;
private static Sprite whiteSprite;
private bool initialized;
public void Initialize(MonoBehaviour eh)
{
enemyHealth = eh;
maxHealth = SafeGet(F_health, enemyHealth, 100);
lastHealth = SafeGet(F_healthCurrent, enemyHealth, maxHealth);
dead = SafeGet(F_dead, enemyHealth, fallback: false);
Transform val = SafeGet<Transform>(F_meshParent, enemyHealth, null);
anchor = ((EnemyHealthBarsPlugin.UseMeshParentIfAvailable.Value && (Object)(object)val != (Object)null) ? val : ((Component)enemyHealth).transform);
((Component)anchor).GetComponentsInChildren<Renderer>(true, renderers);
if (renderers.Count == 0)
{
((Component)enemyHealth).GetComponentsInChildren<Renderer>(true, renderers);
}
BuildUI();
HookUnityEventsIfPresent();
initialized = true;
}
private void HookUnityEventsIfPresent()
{
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Expected O, but got Unknown
//IL_0061: Unknown result type (might be due to invalid IL or missing references)
//IL_006b: Expected O, but got Unknown
try
{
object? obj = F_onHurt?.GetValue(enemyHealth);
UnityEvent val = (UnityEvent)((obj is UnityEvent) ? obj : null);
if (val != null)
{
val.AddListener(new UnityAction(OnHealthTouched));
}
object? obj2 = F_onDeath?.GetValue(enemyHealth);
UnityEvent val2 = (UnityEvent)((obj2 is UnityEvent) ? obj2 : null);
if (val2 != null)
{
val2.AddListener(new UnityAction(OnDeath));
}
}
catch (Exception ex)
{
EnemyHealthBarsPlugin.Logger.LogDebug((object)("UnityEvent hook skipped: " + ex.Message));
}
}
private void BuildUI()
{
//IL_0088: Unknown result type (might be due to invalid IL or missing references)
//IL_0092: Expected O, but got Unknown
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Expected O, but got Unknown
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
//IL_004b: 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_013b: 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_0164: Expected O, but got Unknown
//IL_0184: Unknown result type (might be due to invalid IL or missing references)
//IL_0190: Unknown result type (might be due to invalid IL or missing references)
//IL_019c: Unknown result type (might be due to invalid IL or missing references)
//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
//IL_020a: Unknown result type (might be due to invalid IL or missing references)
//IL_0211: Expected O, but got Unknown
//IL_0230: Unknown result type (might be due to invalid IL or missing references)
//IL_023d: Unknown result type (might be due to invalid IL or missing references)
//IL_0255: 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_02b8: Unknown result type (might be due to invalid IL or missing references)
//IL_02db: Unknown result type (might be due to invalid IL or missing references)
//IL_02e2: Expected O, but got Unknown
//IL_0301: Unknown result type (might be due to invalid IL or missing references)
//IL_030e: Unknown result type (might be due to invalid IL or missing references)
//IL_031f: Unknown result type (might be due to invalid IL or missing references)
//IL_0332: 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_03d0: Unknown result type (might be due to invalid IL or missing references)
//IL_03d7: Expected O, but got Unknown
//IL_03f6: Unknown result type (might be due to invalid IL or missing references)
//IL_0403: 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_0427: Unknown result type (might be due to invalid IL or missing references)
//IL_0491: Unknown result type (might be due to invalid IL or missing references)
//IL_04c5: Unknown result type (might be due to invalid IL or missing references)
//IL_04cc: Expected O, but got Unknown
//IL_04f5: Unknown result type (might be due to invalid IL or missing references)
//IL_050c: Unknown result type (might be due to invalid IL or missing references)
//IL_0519: Unknown result type (might be due to invalid IL or missing references)
//IL_0526: Unknown result type (might be due to invalid IL or missing references)
//IL_0581: Unknown result type (might be due to invalid IL or missing references)
//IL_05a5: Unknown result type (might be due to invalid IL or missing references)
//IL_05bc: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)whiteSprite == (Object)null)
{
Texture2D val = new Texture2D(1, 1, (TextureFormat)4, false);
val.SetPixel(0, 0, Color.white);
val.Apply();
whiteSprite = Sprite.Create(val, new Rect(0f, 0f, 1f, 1f), new Vector2(0.5f, 0.5f), 100f);
}
rootGO = new GameObject("EmpressHealthBar", new Type[1] { typeof(RectTransform) });
((Object)rootGO).hideFlags = (HideFlags)52;
rootGO.layer = (((Object)(object)anchor != (Object)null) ? ((Component)anchor).gameObject.layer : 0);
Canvas val2 = rootGO.AddComponent<Canvas>();
val2.renderMode = (RenderMode)2;
val2.sortingOrder = 5000;
canvas = val2;
CanvasGroup val3 = rootGO.AddComponent<CanvasGroup>();
val3.interactable = false;
val3.blocksRaycasts = false;
rect = rootGO.GetComponent<RectTransform>();
rect.sizeDelta = new Vector2(EnemyHealthBarsPlugin.BarWidth.Value, EnemyHealthBarsPlugin.BarHeight.Value);
GameObject val4 = new GameObject("Frame", new Type[1] { typeof(RectTransform) });
val4.transform.SetParent(rootGO.transform, false);
RectTransform component = val4.GetComponent<RectTransform>();
component.anchorMin = Vector2.zero;
component.anchorMax = Vector2.one;
component.offsetMin = Vector2.zero;
component.offsetMax = Vector2.zero;
Image val5 = val4.AddComponent<Image>();
val5.sprite = whiteSprite;
val5.type = (Type)0;
((Graphic)val5).color = new Color(0.1f, 0.1f, 0.1f, 1f);
GameObject val6 = new GameObject("Back", new Type[1] { typeof(RectTransform) });
val6.transform.SetParent(val4.transform, false);
RectTransform component2 = val6.GetComponent<RectTransform>();
component2.anchorMin = Vector2.zero;
component2.anchorMax = Vector2.one;
float num = 0.015f;
component2.offsetMin = new Vector2(num, num);
component2.offsetMax = new Vector2(0f - num, 0f - num);
imgBack = val6.AddComponent<Image>();
imgBack.sprite = whiteSprite;
imgBack.type = (Type)0;
((Graphic)imgBack).color = new Color(0.8f, 0.8f, 0.8f, 0.25f);
GameObject val7 = new GameObject("Chip", new Type[1] { typeof(RectTransform) });
val7.transform.SetParent(val4.transform, false);
RectTransform component3 = val7.GetComponent<RectTransform>();
component3.anchorMin = Vector2.zero;
component3.anchorMax = Vector2.one;
component3.offsetMin = new Vector2(num, num);
component3.offsetMax = new Vector2(0f - num, 0f - num);
imgChip = val7.AddComponent<Image>();
imgChip.sprite = whiteSprite;
imgChip.type = (Type)3;
imgChip.fillMethod = (FillMethod)0;
imgChip.fillOrigin = 0;
((Graphic)imgChip).color = new Color(0.9f, 0.7f, 0.1f, 0.95f);
imgChip.fillAmount = 1f;
GameObject val8 = new GameObject("Fill", new Type[1] { typeof(RectTransform) });
val8.transform.SetParent(val4.transform, false);
RectTransform component4 = val8.GetComponent<RectTransform>();
component4.anchorMin = Vector2.zero;
component4.anchorMax = Vector2.one;
component4.offsetMin = new Vector2(num, num);
component4.offsetMax = new Vector2(0f - num, 0f - num);
imgFill = val8.AddComponent<Image>();
imgFill.sprite = whiteSprite;
imgFill.type = (Type)3;
imgFill.fillMethod = (FillMethod)0;
imgFill.fillOrigin = 0;
((Graphic)imgFill).color = new Color(0.9f, 0.1f, 0.1f, 1f);
imgFill.fillAmount = 1f;
GameObject val9 = new GameObject("Text", new Type[1] { typeof(RectTransform) });
val9.transform.SetParent(val4.transform, false);
RectTransform component5 = val9.GetComponent<RectTransform>();
component5.anchorMin = new Vector2(0f, 0f);
component5.anchorMax = new Vector2(1f, 1f);
component5.offsetMin = Vector2.zero;
component5.offsetMax = Vector2.zero;
textComp = val9.AddComponent<Text>();
textComp.font = Resources.GetBuiltinResource<Font>("Arial.ttf");
textComp.alignment = (TextAnchor)4;
textComp.horizontalOverflow = (HorizontalWrapMode)1;
textComp.verticalOverflow = (VerticalWrapMode)0;
((Graphic)textComp).color = Color.white;
textComp.fontSize = 9;
Shadow val10 = val9.AddComponent<Shadow>();
val10.effectColor = Color.black;
val10.effectDistance = new Vector2(1f, -1f);
rootGO.transform.SetParent(((Component)enemyHealth).transform, false);
}
private void OnDestroy()
{
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Expected O, but got Unknown
//IL_0061: Unknown result type (might be due to invalid IL or missing references)
//IL_006b: Expected O, but got Unknown
try
{
object? obj = F_onHurt?.GetValue(enemyHealth);
UnityEvent val = (UnityEvent)((obj is UnityEvent) ? obj : null);
if (val != null)
{
val.RemoveListener(new UnityAction(OnHealthTouched));
}
object? obj2 = F_onDeath?.GetValue(enemyHealth);
UnityEvent val2 = (UnityEvent)((obj2 is UnityEvent) ? obj2 : null);
if (val2 != null)
{
val2.RemoveListener(new UnityAction(OnDeath));
}
}
catch
{
}
}
public void OnHealthTouched()
{
maxHealth = SafeGet(F_health, enemyHealth, maxHealth);
int num = SafeGet(F_healthCurrent, enemyHealth, lastHealth);
lastHealth = num;
showTimer = Mathf.Max(showTimer, EnemyHealthBarsPlugin.ShowOnDamageSeconds.Value);
}
private void OnDeath()
{
dead = true;
if ((Object)(object)rootGO != (Object)null)
{
rootGO.SetActive(false);
}
}
private void Update()
{
if (!initialized || (Object)(object)enemyHealth == (Object)null)
{
return;
}
if ((Object)(object)cachedCam == (Object)null || !((Behaviour)cachedCam).isActiveAndEnabled)
{
cachedCam = FindCamera();
}
if ((Object)(object)cachedCam == (Object)null)
{
if ((Object)(object)rootGO != (Object)null)
{
rootGO.SetActive(false);
}
return;
}
int num = SafeGet(F_healthCurrent, enemyHealth, lastHealth);
int num2 = SafeGet(F_health, enemyHealth, maxHealth);
if (num2 <= 0)
{
num2 = 1;
}
float num3 = Mathf.Clamp01((float)num / (float)num2);
if ((Object)(object)textComp != (Object)null)
{
textComp.text = $"{num} / {num2}";
}
float num4 = currentFill;
bool flag = num3 < num4 - 0.0001f;
bool flag2 = num3 > num4 + 0.0001f;
if (flag)
{
currentFill = num3;
chipFill = Mathf.Max(chipFill, num4);
}
else if (flag2)
{
currentFill = Mathf.Lerp(num4, num3, EnemyHealthBarsPlugin.LerpSpeed.Value * Time.deltaTime);
}
else
{
currentFill = Mathf.Lerp(num4, num3, EnemyHealthBarsPlugin.LerpSpeed.Value * Time.deltaTime);
}
float num5 = currentFill;
float num6 = ((chipFill > num5) ? EnemyHealthBarsPlugin.ChipDropSpeed.Value : EnemyHealthBarsPlugin.HealCatchupSpeed.Value);
chipFill = Mathf.Lerp(chipFill, num5, num6 * Time.deltaTime);
if ((Object)(object)imgFill != (Object)null)
{
imgFill.fillAmount = currentFill;
}
if ((Object)(object)imgChip != (Object)null)
{
imgChip.fillAmount = chipFill;
}
bool flag3 = EnemyHealthBarsPlugin.AlwaysShow.Value;
if (!flag3)
{
showTimer -= Time.deltaTime;
if (showTimer > 0f)
{
flag3 = true;
}
}
if (EnemyHealthBarsPlugin.OnlyWhenVisible.Value && !AnyRendererVisible())
{
flag3 = false;
}
if ((Object)(object)rootGO != (Object)null)
{
rootGO.SetActive(flag3 && !dead);
}
}
private void LateUpdate()
{
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_0045: 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_004d: 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_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_0068: Unknown result type (might be due to invalid IL or missing references)
//IL_0075: Unknown result type (might be due to invalid IL or missing references)
//IL_008c: Unknown result type (might be due to invalid IL or missing references)
//IL_008d: 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_00a2: 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_00b3: Unknown result type (might be due to invalid IL or missing references)
//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
//IL_00d5: 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_00df: 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_0122: Unknown result type (might be due to invalid IL or missing references)
//IL_0168: Unknown result type (might be due to invalid IL or missing references)
//IL_016f: Unknown result type (might be due to invalid IL or missing references)
//IL_0102: Unknown result type (might be due to invalid IL or missing references)
if (initialized && !((Object)(object)rootGO == (Object)null) && !((Object)(object)anchor == (Object)null) && !((Object)(object)cachedCam == (Object)null))
{
Bounds val = ComputeBounds();
Vector3 val2 = ((Bounds)(ref val)).center + Vector3.up * ((Bounds)(ref val)).extents.y;
float num = EnemyHealthBarsPlugin.ExtraOffsetMeters.Value + ((Bounds)(ref val)).size.y * EnemyHealthBarsPlugin.OffsetPercentOfHeight.Value;
Vector3 val3 = val2 + Vector3.up * Mathf.Max(0.01f, num);
rootGO.transform.position = val3;
Vector3 val4 = rootGO.transform.position - ((Component)cachedCam).transform.position;
if (((Vector3)(ref val4)).sqrMagnitude > 0.0001f)
{
rootGO.transform.forward = ((Vector3)(ref val4)).normalized;
}
float num2 = Mathf.Max(0.01f, Vector3.Distance(((Component)cachedCam).transform.position, val3));
float num3 = Mathf.Clamp(1f + num2 * EnemyHealthBarsPlugin.DistanceScaleFactor.Value, EnemyHealthBarsPlugin.MinScale.Value, EnemyHealthBarsPlugin.MaxScale.Value);
rootGO.transform.localScale = Vector3.one * num3;
}
}
private Bounds ComputeBounds()
{
//IL_0009: Unknown result type (might be due to invalid IL or missing references)
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: 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_0181: Unknown result type (might be due to invalid IL or missing references)
//IL_014d: Unknown result type (might be due to invalid IL or missing references)
//IL_0152: Unknown result type (might be due to invalid IL or missing references)
//IL_015c: Unknown result type (might be due to invalid IL or missing references)
//IL_0161: Unknown result type (might be due to invalid IL or missing references)
//IL_0175: Unknown result type (might be due to invalid IL or missing references)
//IL_0185: Unknown result type (might be due to invalid IL or missing references)
//IL_006e: Unknown result type (might be due to invalid IL or missing references)
//IL_005f: Unknown result type (might be due to invalid IL or missing references)
//IL_0064: Unknown result type (might be due to invalid IL or missing references)
//IL_0111: Unknown result type (might be due to invalid IL or missing references)
//IL_0101: Unknown result type (might be due to invalid IL or missing references)
//IL_0106: Unknown result type (might be due to invalid IL or missing references)
Bounds bounds = default(Bounds);
((Bounds)(ref bounds))..ctor(anchor.position, Vector3.one * 0.5f);
bool flag = false;
for (int i = 0; i < renderers.Count; i++)
{
Renderer val = renderers[i];
if (!((Object)(object)val == (Object)null) && val.enabled)
{
if (!flag)
{
bounds = val.bounds;
flag = true;
}
else
{
((Bounds)(ref bounds)).Encapsulate(val.bounds);
}
}
}
if (!flag)
{
renderers.Clear();
((Component)anchor).GetComponentsInChildren<Renderer>(true, renderers);
for (int j = 0; j < renderers.Count; j++)
{
Renderer val2 = renderers[j];
if (!((Object)(object)val2 == (Object)null) && val2.enabled)
{
if (!flag)
{
bounds = val2.bounds;
flag = true;
}
else
{
((Bounds)(ref bounds)).Encapsulate(val2.bounds);
}
}
}
}
if (!flag)
{
((Bounds)(ref bounds))..ctor(anchor.position + Vector3.up * 1f, new Vector3(1f, 2f, 1f));
}
return bounds;
}
private bool AnyRendererVisible()
{
for (int i = 0; i < renderers.Count; i++)
{
Renderer val = renderers[i];
if ((Object)(object)val != (Object)null && val.enabled && val.isVisible)
{
return true;
}
}
return false;
}
private Camera FindCamera()
{
Camera main = Camera.main;
if ((Object)(object)main != (Object)null && ((Behaviour)main).isActiveAndEnabled)
{
return main;
}
Camera[] array = Object.FindObjectsOfType<Camera>();
Camera[] array2 = array;
foreach (Camera val in array2)
{
if ((Object)(object)val != (Object)null && ((Behaviour)val).isActiveAndEnabled)
{
return val;
}
}
return null;
}
private static T SafeGet<T>(FieldInfo fi, object inst, T fallback)
{
try
{
if (fi == null || inst == null)
{
return fallback;
}
object value = fi.GetValue(inst);
if (value is T result)
{
return result;
}
if (value == null)
{
return fallback;
}
return (T)Convert.ChangeType(value, typeof(T));
}
catch
{
return fallback;
}
}
}
}