using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; 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 TMPro; using UnityEngine; 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(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("REPO_ShowEnemyHealth")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+16aa0046be6243b25b8d3c518bf413179277c854")] [assembly: AssemblyProduct("ShowEnemyHealth Fixed Edition")] [assembly: AssemblyTitle("REPO_ShowEnemyHealth")] [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.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace ShowEnemyHealth { internal static class ConfigManager { public static ConfigFile ConfigFile { get; private set; } public static ConfigEntry ShowEnemyHealth { get; private set; } public static ConfigEntry HealthFontSize { get; private set; } public static ConfigEntry HealthFontColor { get; private set; } public static ConfigEntry ShowEnemyDamage { get; private set; } public static ConfigEntry DamageFontSize { get; private set; } public static ConfigEntry DamageFontHighlightColor { get; private set; } public static ConfigEntry DamageFontColor { get; private set; } public static void Initialize(ConfigFile configFile) { ConfigFile = configFile; BindConfigs(); } private static void BindConfigs() { //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Expected O, but got Unknown //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Expected O, but got Unknown //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Expected O, but got Unknown //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Expected O, but got Unknown //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Expected O, but got Unknown AcceptableValueList val = new AcceptableValueList(new string[10] { "black", "blue", "cyan", "green", "grey", "magenta", "orange", "red", "white", "yellow" }); ShowEnemyHealth = ConfigFile.Bind("Health", "ShowEnemyHealth", true, "Show enemy health text"); HealthFontSize = ConfigFile.Bind("Health", "HealthFontSize", 15f, new ConfigDescription("Health text size", (AcceptableValueBase)(object)new AcceptableValueRange(10f, 50f), Array.Empty())); HealthFontColor = ConfigFile.Bind("Health", "HealthFontColor", "grey", new ConfigDescription("Health text color", (AcceptableValueBase)(object)val, Array.Empty())); ShowEnemyDamage = ConfigFile.Bind("Damage", "ShowEnemyDamage", true, "Show damage text"); DamageFontSize = ConfigFile.Bind("Damage", "DamageFontSize", 25f, new ConfigDescription("Damage text size", (AcceptableValueBase)(object)new AcceptableValueRange(10f, 50f), Array.Empty())); DamageFontHighlightColor = ConfigFile.Bind("Damage", "DamageFontHighlightColor", "red", new ConfigDescription("Damage highlight color", (AcceptableValueBase)(object)val, Array.Empty())); DamageFontColor = ConfigFile.Bind("Damage", "DamageFontColor", "orange", new ConfigDescription("Damage text color", (AcceptableValueBase)(object)val, Array.Empty())); } } internal class CustomDamageTextOcclusion : MonoBehaviour { private WorldSpaceUIValueLost valueLost; private CanvasGroup canvasGroup; private Enemy currEnemy; private EnemyHealth currEnemyHealth; private EnemyRigidbody enemyRigidBody; private int occlusionMask; private bool isOccluded; private bool wasOccluded; private float baseAlpha = 1f; private float nextOcclusionCheckTime; private void Awake() { occlusionMask = Patches.BuildOcclusionMask(); } internal void Initialize(WorldSpaceUIValueLost component, Enemy enemy, EnemyHealth enemyHealth, EnemyRigidbody rigidBody) { valueLost = component; currEnemy = enemy; currEnemyHealth = enemyHealth; enemyRigidBody = rigidBody; EnsureCanvasGroup(); } private void LateUpdate() { //IL_009d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)valueLost == (Object)null) { ((Behaviour)this).enabled = false; return; } EnsureCanvasGroup(); if (!((Object)(object)canvasGroup == (Object)null)) { if (!wasOccluded || canvasGroup.alpha > 0f) { baseAlpha = canvasGroup.alpha; } if (Time.time >= nextOcclusionCheckTime) { nextOcclusionCheckTime = Time.time + 0.1f; isOccluded = IsOccluded(Camera.main, GetWorldPosition()); } canvasGroup.alpha = (isOccluded ? 0f : baseAlpha); wasOccluded = isOccluded; } } private void EnsureCanvasGroup() { if (!((Object)(object)canvasGroup != (Object)null)) { canvasGroup = ((Component)this).GetComponent(); if ((Object)(object)canvasGroup == (Object)null) { canvasGroup = ((Component)this).gameObject.AddComponent(); } } } private Vector3 GetWorldPosition() { //IL_0056: 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_005f: 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_004a: 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) if ((Object)(object)valueLost != (Object)null && Patches.WorldSpaceUIValueLostWorldPositionField != null && Patches.WorldSpaceUIValueLostWorldPositionField.GetValue(valueLost) is Vector3 result) { return result; } return ((Component)this).transform.position; } private bool IsOccluded(Camera mainCamera, Vector3 labelPosition) { //IL_002a: 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) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0031: 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_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0059: 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_007e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)mainCamera == (Object)null || occlusionMask == 0) { return false; } Vector3 position = ((Component)mainCamera).transform.position; Vector3 val = labelPosition - position; float magnitude = ((Vector3)(ref val)).magnitude; if (magnitude <= Mathf.Epsilon) { return false; } RaycastHit[] array = Physics.RaycastAll(position, ((Vector3)(ref val)).normalized, magnitude, occlusionMask, (QueryTriggerInteraction)1); RaycastHit[] array2 = array; for (int i = 0; i < array2.Length; i++) { RaycastHit val2 = array2[i]; if (!((Object)(object)((RaycastHit)(ref val2)).collider == (Object)null) && !IsCurrentEnemyCollider(((RaycastHit)(ref val2)).collider)) { return true; } } return false; } private bool IsCurrentEnemyCollider(Collider collider) { Transform transform = ((Component)collider).transform; return IsInHierarchy(transform, ((Object)(object)currEnemy != (Object)null) ? ((Component)currEnemy).transform : null) || IsInHierarchy(transform, ((Object)(object)enemyRigidBody != (Object)null) ? ((Component)enemyRigidBody).transform : null) || IsInHierarchy(transform, ((Object)(object)currEnemyHealth != (Object)null) ? ((Component)currEnemyHealth).transform : null); } private static bool IsInHierarchy(Transform colliderTransform, Transform ownerTransform) { return (Object)(object)colliderTransform != (Object)null && (Object)(object)ownerTransform != (Object)null && colliderTransform.IsChildOf(ownerTransform); } } [RequireComponent(typeof(RectTransform))] [RequireComponent(typeof(TextMeshProUGUI))] internal class CustomEnemyHealthUI : WorldSpaceUIChild { private Vector3 scale = default(Vector3); internal Vector3 newWorldPosition = default(Vector3); private Enemy currEnemy; private EnemyHealth currEnemyHealth; private EnemyRigidbody enemyRigidBody; private TextMeshProUGUI text; private bool initialized = false; private bool isOccluded = false; private float nextOcclusionCheckTime = 0f; private int occlusionMask; private Vector3 worldspaceOffset = default(Vector3); private Vector3 targetWorldspaceOffset = default(Vector3); public int recalcIntervalFrames = 50; private int frameCounter = 0; public float worldspaceOffsetLerpRate = 5f; private void Awake() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) Patches.SetWorldSpaceUIChildPositionOffset((WorldSpaceUIChild)(object)this, new Vector3(0f, -0.05f, 0f)); scale = Vector3.one; text = ((Component)this).GetComponent(); occlusionMask = BuildOcclusionMask(); } public void Show(EnemyHealth enemyHealth, Vector3 screenspaceOffset) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0061: 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_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) if (!ConfigManager.ShowEnemyHealth.Value) { Patches.RemoveHealthUI(((Object)(object)currEnemyHealth != (Object)null) ? currEnemyHealth : enemyHealth); return; } ((Graphic)text).color = Color.gray; Color32 val = default(Color32); if (ColorUtility.DoTryParseHtmlColor(ConfigManager.HealthFontColor.Value, ref val)) { ((Graphic)text).color = Color32.op_Implicit(val); } ((TMP_Text)text).fontSize = ConfigManager.HealthFontSize.Value; if (!Object.op_Implicit((Object)(object)currEnemy) || !Object.op_Implicit((Object)(object)currEnemyHealth)) { Patches.SetWorldSpaceUIChildPositionOffset((WorldSpaceUIChild)(object)this, screenspaceOffset); currEnemyHealth = enemyHealth; currEnemy = Patches.GetEnemy(enemyHealth); if ((Object)(object)currEnemy == (Object)null) { Patches.RemoveHealthUI(this); return; } newWorldPosition = Patches.GetEnemyPosition(currEnemy, currEnemyHealth); Patches.SetWorldSpaceUIChildPosition((WorldSpaceUIChild)(object)this, newWorldPosition); enemyRigidBody = Patches.GetEnemyRigidbody(currEnemy); UpdateTargetWorldSpaceOffset(); worldspaceOffset = targetWorldspaceOffset; UpdateTextValues(); initialized = true; } } internal void UpdateTargetWorldSpaceOffset() { //IL_001a: 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_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: 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_0078: 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) if ((Object)(object)enemyRigidBody == (Object)null) { return; } Bounds val = default(Bounds); bool flag = false; Collider[] componentsInChildren = ((Component)enemyRigidBody).GetComponentsInChildren(); Collider[] array = componentsInChildren; foreach (Collider val2 in array) { if (!((Object)(object)val2 == (Object)null) && !val2.isTrigger) { if (!flag) { val = val2.bounds; flag = true; } else { ((Bounds)(ref val)).Encapsulate(val2.bounds); } } } if (!flag) { targetWorldspaceOffset = new Vector3(0f, 1f, 0f); return; } float y = Patches.GetEnemyPosition(currEnemy, currEnemyHealth).y; float num = Mathf.Clamp(((Bounds)(ref val)).max.y - y + 0.15f, 0.5f, 12f); targetWorldspaceOffset = new Vector3(0f, num, 0f); } internal void UpdateTextValues() { if (!((Object)(object)currEnemy == (Object)null) && !((Object)(object)currEnemyHealth == (Object)null) && !((Object)(object)text == (Object)null)) { int num = Mathf.Max(0, Patches.GetHealthCurrent(currEnemyHealth)); int health = currEnemyHealth.health; ((TMP_Text)text).text = $"{num}/{health}"; } } protected override void Update() { //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: 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_00c6: 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_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) if (!initialized) { return; } if ((Object)(object)currEnemyHealth == (Object)null || (Object)(object)currEnemy == (Object)null) { Patches.RemoveHealthUI(this); return; } if (!Patches.IsEnemyHealthDisplayable(currEnemyHealth)) { Patches.RemoveHealthUI(currEnemyHealth); return; } ((WorldSpaceUIChild)this).Update(); frameCounter++; if (frameCounter >= recalcIntervalFrames) { frameCounter = 0; UpdateTargetWorldSpaceOffset(); } worldspaceOffset = Vector3.Lerp(worldspaceOffset, targetWorldspaceOffset, Time.deltaTime * worldspaceOffsetLerpRate); Patches.SetWorldSpaceUIChildPosition((WorldSpaceUIChild)(object)this, newWorldPosition + worldspaceOffset); if ((Object)(object)currEnemy != (Object)null) { newWorldPosition = Patches.GetEnemyPosition(currEnemy, currEnemyHealth); } float num = 1f; float num2 = 5f; float num3 = 20f; Camera main = Camera.main; float num4 = (((Object)(object)main != (Object)null) ? Vector3.Distance(((Component)main).transform.position, newWorldPosition) : num2); Vector3 localScale = scale; if (num4 > num2) { num4 = Mathf.Clamp(num4, num2, num3); num = 1f - (num4 - num2) / (num3 - num2); ((Vector3)(ref localScale))..ctor(num, num, num); } if (num4 < num3 && Time.time >= nextOcclusionCheckTime) { nextOcclusionCheckTime = Time.time + 0.1f; isOccluded = IsOccluded(main, newWorldPosition + worldspaceOffset); } else if (num4 >= num3) { isOccluded = false; } ((TMP_Text)text).alpha = (isOccluded ? 0f : num); ((Component)this).transform.localScale = localScale; UpdateTextValues(); } private static int BuildOcclusionMask() { return Patches.BuildOcclusionMask(); } private bool IsOccluded(Camera mainCamera, Vector3 labelPosition) { //IL_002a: 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) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0031: 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_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0059: 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_007e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)mainCamera == (Object)null || occlusionMask == 0) { return false; } Vector3 position = ((Component)mainCamera).transform.position; Vector3 val = labelPosition - position; float magnitude = ((Vector3)(ref val)).magnitude; if (magnitude <= Mathf.Epsilon) { return false; } RaycastHit[] array = Physics.RaycastAll(position, ((Vector3)(ref val)).normalized, magnitude, occlusionMask, (QueryTriggerInteraction)1); RaycastHit[] array2 = array; for (int i = 0; i < array2.Length; i++) { RaycastHit val2 = array2[i]; if (!((Object)(object)((RaycastHit)(ref val2)).collider == (Object)null) && !IsCurrentEnemyCollider(((RaycastHit)(ref val2)).collider)) { return true; } } return false; } private bool IsCurrentEnemyCollider(Collider collider) { Transform transform = ((Component)collider).transform; return IsInHierarchy(transform, ((Object)(object)currEnemy != (Object)null) ? ((Component)currEnemy).transform : null) || IsInHierarchy(transform, ((Object)(object)enemyRigidBody != (Object)null) ? ((Component)enemyRigidBody).transform : null) || IsInHierarchy(transform, ((Object)(object)currEnemyHealth != (Object)null) ? ((Component)currEnemyHealth).transform : null); } private static bool IsInHierarchy(Transform colliderTransform, Transform ownerTransform) { return (Object)(object)colliderTransform != (Object)null && (Object)(object)ownerTransform != (Object)null && colliderTransform.IsChildOf(ownerTransform); } } [HarmonyPatch] public static class Patches { [CompilerGenerated] private sealed class d__46 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public EnemyHealth enemyHealth; private float 5__1; private Enemy 5__2; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__46(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { 5__2 = null; <>1__state = -2; } private bool MoveNext() { //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Invalid comparison between Unknown and I4 //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; 5__1 = Time.realtimeSinceStartup + 3f; break; case 1: <>1__state = -1; goto IL_012e; case 2: { <>1__state = -1; goto IL_012e; } IL_012e: 5__2 = null; break; } if (ConfigManager.ShowEnemyHealth.Value && (Object)(object)enemyHealth != (Object)null && !GetDead(enemyHealth)) { 5__2 = GetEnemy(enemyHealth); if (!((Object)(object)5__2 != (Object)null) || (int)5__2.CurrentState != 11) { if ((Object)(object)WorldSpaceUIParent.instance != (Object)null && (Object)(object)WorldSpaceUIParent.instance.TTSPrefab != (Object)null) { CreateHealthUI(enemyHealth, GetEnemyPosition(5__2, enemyHealth)); if (healthUIElements.ContainsKey(enemyHealth)) { goto IL_016a; } } if (Time.realtimeSinceStartup < 5__1) { <>2__current = null; <>1__state = 1; return true; } <>2__current = (object)new WaitForSeconds(0.5f); <>1__state = 2; return true; } } goto IL_016a; IL_016a: createHealthCoroutines.Remove(enemyHealth); 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(); } } [CompilerGenerated] private sealed class d__43 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public FieldInfo fieldInfo; public object target; public string targetText; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__43(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = null; <>1__state = 1; return true; case 1: <>1__state = -1; if (!TrySetDamageText(fieldInfo, target, targetText)) { <>2__current = null; <>1__state = 2; return true; } break; case 2: <>1__state = -1; TrySetDamageText(fieldInfo, target, targetText); break; } 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(); } } [CompilerGenerated] private sealed class d__45 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public CustomEnemyHealthUI healthUI; public EnemyHealth enemyHealth; public Vector3 offset; private Exception 5__1; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__45(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { 5__1 = null; <>1__state = -2; } private bool MoveNext() { //IL_0068: Unknown result type (might be due to invalid IL or missing references) switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = null; <>1__state = 1; return true; case 1: <>1__state = -1; try { if (!IsEnemyHealthDisplayable(enemyHealth)) { RemoveHealthUI(enemyHealth); return false; } healthUI.Show(enemyHealth, offset); } catch (Exception ex) { 5__1 = ex; Plugin.Logger.LogDebug((object)$"Handling exception in DelayedShowHealthUI: {5__1}"); try { RemoveHealthUI(enemyHealth); } catch { } } 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(); } } internal static readonly Dictionary healthUIElements = new Dictionary(); internal static readonly Dictionary createHealthCoroutines = new Dictionary(); internal static readonly FieldInfo EnemyHealthEnemyField = typeof(EnemyHealth).GetField("enemy", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); internal static readonly FieldInfo EnemyHealthCurrentField = typeof(EnemyHealth).GetField("healthCurrent", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); internal static readonly FieldInfo EnemyHealthDeadField = typeof(EnemyHealth).GetField("dead", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); internal static readonly FieldInfo EnemyHealthField = typeof(Enemy).GetField("Health", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); internal static readonly FieldInfo EnemyEnemyParentField = typeof(Enemy).GetField("EnemyParent", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); internal static readonly FieldInfo EnemyRigidbodyField = typeof(Enemy).GetField("Rigidbody", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); internal static readonly FieldInfo EnemyParentEnemyField = typeof(EnemyParent).GetField("Enemy", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) ?? typeof(EnemyParent).GetField("enemy", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); internal static readonly FieldInfo EnemyBangEnemyField = typeof(EnemyBang).GetField("enemy", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); internal static readonly FieldInfo WorldSpaceUIChildWorldPositionField = typeof(WorldSpaceUIChild).GetField("worldPosition", BindingFlags.Instance | BindingFlags.NonPublic); internal static readonly FieldInfo WorldSpaceUIChildPositionOffsetField = typeof(WorldSpaceUIChild).GetField("positionOffset", BindingFlags.Instance | BindingFlags.NonPublic); internal static readonly FieldInfo WorldSpaceUIValueLostWorldPositionField = typeof(WorldSpaceUIValueLost).GetField("worldPosition", BindingFlags.Instance | BindingFlags.NonPublic); internal static readonly FieldInfo WorldSpaceUIValueLostValueField = typeof(WorldSpaceUIValueLost).GetField("value", BindingFlags.Instance | BindingFlags.NonPublic); internal static readonly FieldInfo WorldSpaceUIValueLostTextField = typeof(WorldSpaceUIValueLost).GetField("text", BindingFlags.Instance | BindingFlags.NonPublic); internal static readonly FieldInfo WorldSpaceUIValueLostTextColorField = typeof(WorldSpaceUIValueLost).GetField("textColor", BindingFlags.Instance | BindingFlags.NonPublic); internal static readonly FieldInfo WorldSpaceUIParentValueLostListField = typeof(WorldSpaceUIParent).GetField("valueLostList", BindingFlags.Instance | BindingFlags.NonPublic); internal static Enemy GetEnemy(EnemyHealth enemyHealth) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown if ((Object)(object)enemyHealth == (Object)null) { return null; } return (Enemy)(EnemyHealthEnemyField?.GetValue(enemyHealth)); } internal static int GetHealthCurrent(EnemyHealth enemyHealth) { if ((Object)(object)enemyHealth == (Object)null) { return 0; } return (int)(EnemyHealthCurrentField?.GetValue(enemyHealth) ?? ((object)0)); } internal static void SetHealthCurrent(EnemyHealth enemyHealth, int value) { if (!((Object)(object)enemyHealth == (Object)null)) { EnemyHealthCurrentField?.SetValue(enemyHealth, value); } } internal static bool GetDead(EnemyHealth enemyHealth) { if ((Object)(object)enemyHealth == (Object)null) { return false; } return (bool)(EnemyHealthDeadField?.GetValue(enemyHealth) ?? ((object)false)); } internal static Vector3 GetEnemyPosition(Enemy enemy, EnemyHealth enemyHealth) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0087: 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_0052: 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_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0077: 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) if ((Object)(object)enemy != (Object)null && (Object)(object)enemy.CenterTransform != (Object)null) { return enemy.CenterTransform.position; } if ((Object)(object)enemy != (Object)null && (Object)(object)((Component)enemy).transform != (Object)null) { return ((Component)enemy).transform.position; } if ((Object)(object)enemyHealth != (Object)null && (Object)(object)((Component)enemyHealth).transform != (Object)null) { return ((Component)enemyHealth).transform.position; } return Vector3.zero; } internal static EnemyRigidbody GetEnemyRigidbody(Enemy enemy) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown if ((Object)(object)enemy == (Object)null) { return null; } return (EnemyRigidbody)(EnemyRigidbodyField?.GetValue(enemy)); } internal static bool IsEnemyHealthDisplayable(EnemyHealth enemyHealth) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Invalid comparison between Unknown and I4 if (!ConfigManager.ShowEnemyHealth.Value || (Object)(object)enemyHealth == (Object)null || GetDead(enemyHealth)) { return false; } Enemy enemy = GetEnemy(enemyHealth); if ((Object)(object)enemy == (Object)null || (int)enemy.CurrentState == 11) { return false; } return true; } internal static int BuildOcclusionMask() { int mask = 0; AddLayerToMask(ref mask, "Default"); AddLayerToMask(ref mask, "StaticGrabObject"); AddLayerToMask(ref mask, "PhysGrabObject"); AddLayerToMask(ref mask, "PhysGrabObjectCart"); AddLayerToMask(ref mask, "PhysGrabObjectHinge"); return mask; } internal static void AddLayerToMask(ref int mask, string layerName) { int num = LayerMask.NameToLayer(layerName); if (num >= 0) { mask |= 1 << num; } } internal static void SetWorldSpaceUIChildPosition(WorldSpaceUIChild child, Vector3 position) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)child == (Object)null) && !(WorldSpaceUIChildWorldPositionField == null)) { WorldSpaceUIChildWorldPositionField.SetValue(child, position); } } internal static void SetWorldSpaceUIChildPositionOffset(WorldSpaceUIChild child, Vector3 offset) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)child == (Object)null) && !(WorldSpaceUIChildPositionOffsetField == null)) { WorldSpaceUIChildPositionOffsetField.SetValue(child, offset); } } [HarmonyPatch(typeof(EnemyHealth), "Awake")] [HarmonyPostfix] public static void CreateEnemyHealthOnAwake(EnemyHealth __instance) { if (!((Object)(object)__instance == (Object)null)) { StartOrRestartCreateHealthCoroutine(__instance); } } [HarmonyPatch(typeof(EnemyHealth), "OnSpawn")] [HarmonyPostfix] public static void CreateEnemyHealthOnSpawn(EnemyHealth __instance) { if (!((Object)(object)__instance == (Object)null)) { RemoveHealthUI(__instance); StartOrRestartCreateHealthCoroutine(__instance); } } [HarmonyPatch(typeof(EnemyHealth), "DeathRPC")] [HarmonyPostfix] public static void RemoveEnemyHealthOnDeath(EnemyHealth __instance) { RemoveHealthUI(__instance); } [HarmonyPatch(typeof(EnemyHealth), "DeathImpulseRPC")] [HarmonyPostfix] public static void RemoveEnemyHealthOnDeathImpulse(EnemyHealth __instance) { RemoveHealthUI(__instance); } [HarmonyPatch(typeof(EnemyHealth), "Hurt")] [HarmonyPostfix] public static void ShowEnemyHealthOnHurt(int _damage, Vector3 _hurtDirection, EnemyHealth __instance) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown //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_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) if (!SemiFunc.IsMasterClientOrSingleplayer()) { return; } try { Enemy enemy = GetEnemy(__instance); if (!((Object)(object)enemy == (Object)null)) { EnemyParent val = (EnemyParent)(EnemyEnemyParentField?.GetValue(enemy)); int healthCurrent = GetHealthCurrent(__instance); bool flag = healthCurrent <= 0 || GetDead(__instance); Vector3 enemyPosition = GetEnemyPosition(enemy, __instance); Plugin.Logger.LogDebug((object)string.Format("{0} HURT by {1}, now has {2}, willDie:{3} ...", val?.enemyName ?? "Enemy", _damage, healthCurrent, flag)); CreateDamageUI(_damage, enemyPosition, enemy, __instance); if (flag) { RemoveHealthUI(__instance); } else { CreateHealthUI(__instance, enemyPosition); } } } catch (Exception arg) { Plugin.Logger.LogError((object)$"LogEnemyHurt failed:\n{arg}"); } } [HarmonyPatch(typeof(EnemyHealth), "HurtRPC")] [HarmonyPostfix] public static void ShowEnemyHealthOnHurtRPC(int _damage, Vector3 _hurtDirection, EnemyHealth __instance) { //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Expected O, but got Unknown //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: 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_0100: Unknown result type (might be due to invalid IL or missing references) if (SemiFunc.IsMasterClientOrSingleplayer() || _damage <= 0) { return; } try { Enemy enemy = GetEnemy(__instance); if (!((Object)(object)enemy == (Object)null)) { EnemyParent val = (EnemyParent)(EnemyEnemyParentField?.GetValue(enemy)); Vector3 enemyPosition = GetEnemyPosition(enemy, __instance); int healthCurrent = GetHealthCurrent(__instance); int num = Math.Max(0, healthCurrent - _damage); SetHealthCurrent(__instance, num); CreateDamageUI(_damage, enemyPosition, enemy, __instance); bool flag = num <= 0 || GetDead(__instance); Plugin.Logger.LogDebug((object)string.Format("{0} HURT by {1}, currHealth: {2}, now has {3}, willDie:{4} ...", val?.enemyName ?? "Enemy", _damage, healthCurrent, num, flag)); if (flag) { RemoveHealthUI(__instance); } else { CreateHealthUI(__instance, enemyPosition); } } } catch (Exception arg) { Plugin.Logger.LogError((object)$"LogEnemyHurt failed:\n{arg}"); } } [HarmonyPatch(typeof(EnemyBang), "ExplodeRPC")] [HarmonyPostfix] public static void HandleBangerExplode(EnemyBang __instance) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Expected O, but got Unknown try { if (!((Object)(object)__instance == (Object)null)) { Enemy val = (Enemy)(EnemyBangEnemyField?.GetValue(__instance)); if (!((Object)(object)val == (Object)null) && !(EnemyHealthField == null)) { EnemyHealth enemyHealth = (EnemyHealth)EnemyHealthField.GetValue(val); RemoveHealthUI(enemyHealth); } } } catch (Exception arg) { Plugin.Logger.LogError((object)$"HandleBangerExplode failed:\n{arg}"); } } [HarmonyPatch(typeof(EnemyParent), "DespawnRPC")] [HarmonyPostfix] public static void RemoveEnemyHealthOnDespawn(EnemyParent __instance) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Expected O, but got Unknown try { if (!((Object)(object)__instance == (Object)null)) { Enemy val = null; if (EnemyParentEnemyField != null) { val = (Enemy)EnemyParentEnemyField.GetValue(__instance); } if ((Object)(object)val == (Object)null) { val = ((Component)__instance).GetComponentInChildren(true); } if (!((Object)(object)val == (Object)null) && !(EnemyHealthField == null)) { EnemyHealth enemyHealth = (EnemyHealth)EnemyHealthField.GetValue(val); RemoveHealthUI(enemyHealth); } } } catch (Exception arg) { Plugin.Logger.LogError((object)$"RemoveEnemyHealthOnDespawn failed:\n{arg}"); } } internal static void StartOrRestartCreateHealthCoroutine(EnemyHealth enemyHealth) { if (!((Object)(object)enemyHealth == (Object)null)) { StopCreateHealthCoroutine(enemyHealth); Coroutine val = Plugin.StartPluginCoroutine(DelayedCreateHealthUI(enemyHealth)); if (val != null) { createHealthCoroutines[enemyHealth] = val; } } } internal static void StopCreateHealthCoroutine(EnemyHealth enemyHealth) { if (!((Object)(object)enemyHealth == (Object)null) && createHealthCoroutines.TryGetValue(enemyHealth, out var value)) { createHealthCoroutines.Remove(enemyHealth); Plugin.StopPluginCoroutine(value); } } internal static void CreateHealthUI(EnemyHealth enemyHealth, Vector3 enemyPosition) { //IL_0046: 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) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_016b: 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_0184: Unknown result type (might be due to invalid IL or missing references) if (!IsEnemyHealthDisplayable(enemyHealth)) { RemoveHealthUI(enemyHealth); } else { if ((Object)(object)WorldSpaceUIParent.instance == (Object)null || (Object)(object)WorldSpaceUIParent.instance.TTSPrefab == (Object)null) { return; } Vector3 val = default(Vector3); val.x = 0f; val.y = 0f; val.z = 0f; Vector3 val2 = val; if (healthUIElements.TryGetValue(enemyHealth, out var value)) { if (!((Object)(object)value == (Object)null) && !((Object)(object)((Component)value).gameObject == (Object)null)) { value.Show(enemyHealth, val2); return; } healthUIElements.Remove(enemyHealth); } if (healthUIElements.ContainsKey(enemyHealth)) { return; } GameObject val3 = Object.Instantiate(WorldSpaceUIParent.instance.TTSPrefab, ((Component)WorldSpaceUIParent.instance).transform.position, ((Component)WorldSpaceUIParent.instance).transform.rotation, ((Component)WorldSpaceUIParent.instance).transform); Object.Destroy((Object)(object)val3.GetComponent()); CustomEnemyHealthUI customEnemyHealthUI = val3.AddComponent(); if (WorldSpaceUIChildWorldPositionField == null) { Object.Destroy((Object)(object)val3); return; } SetWorldSpaceUIChildPosition((WorldSpaceUIChild)(object)customEnemyHealthUI, enemyPosition); healthUIElements.Add(enemyHealth, customEnemyHealthUI); if (Plugin.StartPluginCoroutine(DelayedShowHealthUI(healthUIElements[enemyHealth], enemyHealth, val2)) == null) { try { customEnemyHealthUI.Show(enemyHealth, val2); } catch (Exception arg) { Plugin.Logger.LogDebug((object)$"Handling exception in immediate ShowHealthUI fallback: {arg}"); RemoveHealthUI(enemyHealth); } } } } internal static void RemoveHealthUI(EnemyHealth enemyHealth) { if ((Object)(object)enemyHealth == (Object)null) { CleanupStaleHealthUIEntries(); return; } StopCreateHealthCoroutine(enemyHealth); if (healthUIElements.TryGetValue(enemyHealth, out var value)) { healthUIElements.Remove(enemyHealth); if ((Object)(object)value != (Object)null && (Object)(object)((Component)value).gameObject != (Object)null) { Object.Destroy((Object)(object)((Component)value).gameObject); } } } internal static void RemoveHealthUI(CustomEnemyHealthUI healthUI) { if ((Object)(object)healthUI == (Object)null) { CleanupStaleHealthUIEntries(); return; } EnemyHealth val = null; bool flag = false; foreach (KeyValuePair healthUIElement in healthUIElements) { if ((Object)(object)healthUIElement.Value == (Object)(object)healthUI) { val = healthUIElement.Key; flag = true; break; } } if (flag) { StopCreateHealthCoroutine(val); healthUIElements.Remove(val); } if ((Object)(object)((Component)healthUI).gameObject != (Object)null) { Object.Destroy((Object)(object)((Component)healthUI).gameObject); } } internal static void CleanupStaleHealthUIEntries() { List list = new List(); List list2 = new List(); foreach (KeyValuePair healthUIElement in healthUIElements) { if ((Object)(object)healthUIElement.Key == (Object)null || (Object)(object)healthUIElement.Value == (Object)null || (Object)(object)((Component)healthUIElement.Value).gameObject == (Object)null) { list.Add(healthUIElement.Key); } } foreach (KeyValuePair createHealthCoroutine in createHealthCoroutines) { if ((Object)(object)createHealthCoroutine.Key == (Object)null || createHealthCoroutine.Value == null) { list2.Add(createHealthCoroutine.Key); } } foreach (EnemyHealth item in list2) { createHealthCoroutines.Remove(item); } foreach (EnemyHealth item2 in list) { if (healthUIElements.TryGetValue(item2, out var value) && (Object)(object)value != (Object)null && (Object)(object)((Component)value).gameObject != (Object)null) { Object.Destroy((Object)(object)((Component)value).gameObject); } healthUIElements.Remove(item2); } } internal static void CreateDamageUI(int damage, Vector3 worldPosition, Enemy enemy, EnemyHealth enemyHealth) { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0059: 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) if (!ConfigManager.ShowEnemyDamage.Value) { return; } WorldSpaceUIParent instance = WorldSpaceUIParent.instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance.valueLostPrefab == (Object)null) { return; } GameObject val = Object.Instantiate(instance.valueLostPrefab, ((Component)instance).transform.position, ((Component)instance).transform.rotation, ((Component)instance).transform); WorldSpaceUIValueLost component = val.GetComponent(); if ((Object)(object)component == (Object)null) { Object.Destroy((Object)(object)val); return; } CustomDamageTextOcclusion customDamageTextOcclusion = val.GetComponent() ?? val.AddComponent(); customDamageTextOcclusion.Initialize(component, enemy, enemyHealth, GetEnemyRigidbody(enemy)); WorldSpaceUIValueLostWorldPositionField?.SetValue(component, worldPosition); WorldSpaceUIValueLostValueField?.SetValue(component, damage); if (Plugin.StartPluginCoroutine(DelayedSetText(WorldSpaceUIValueLostTextField, component, $"-{damage}")) == null) { TrySetDamageText(WorldSpaceUIValueLostTextField, component, $"-{damage}"); } ((List)(WorldSpaceUIParentValueLostListField?.GetValue(instance)))?.Add(component); } [IteratorStateMachine(typeof(d__43))] internal static IEnumerator DelayedSetText(FieldInfo fieldInfo, object target, string targetText) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__43(0) { fieldInfo = fieldInfo, target = target, targetText = targetText }; } internal static bool TrySetDamageText(FieldInfo fieldInfo, object target, string targetText) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Expected O, but got Unknown //IL_0041: 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_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0088: 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) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) TextMeshProUGUI val = (TextMeshProUGUI)(fieldInfo?.GetValue(target)); if ((Object)(object)val == (Object)null) { return false; } ((TMP_Text)val).text = targetText; ((TMP_Text)val).fontSize = ConfigManager.DamageFontSize.Value; ((Graphic)val).color = Color.blue; Color32 val2 = default(Color32); if (ColorUtility.DoTryParseHtmlColor(ConfigManager.DamageFontHighlightColor.Value, ref val2)) { ((Graphic)val).color = Color32.op_Implicit(val2); } Color32 val3 = default(Color32); if (ColorUtility.DoTryParseHtmlColor(ConfigManager.DamageFontColor.Value, ref val3)) { Color val4 = Color32.op_Implicit(val3); WorldSpaceUIValueLostTextColorField?.SetValue(target, val4); } else { WorldSpaceUIValueLostTextColorField?.SetValue(target, Color.cyan); } return true; } [IteratorStateMachine(typeof(d__45))] internal static IEnumerator DelayedShowHealthUI(CustomEnemyHealthUI healthUI, EnemyHealth enemyHealth, Vector3 offset) { //IL_0015: 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) //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__45(0) { healthUI = healthUI, enemyHealth = enemyHealth, offset = offset }; } [IteratorStateMachine(typeof(d__46))] internal static IEnumerator DelayedCreateHealthUI(EnemyHealth enemyHealth) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__46(0) { enemyHealth = enemyHealth }; } } [BepInPlugin("REPO_ShowEnemyHealth", "ShowEnemyHealth Fixed Edition", "1.0.0")] public class Plugin : BaseUnityPlugin { internal static ManualLogSource Logger; private Harmony _harmony; internal static Plugin Instance { get; private set; } internal static Coroutine StartPluginCoroutine(IEnumerator routine) { if ((Object)(object)Instance == (Object)null || routine == null || !((Behaviour)Instance).isActiveAndEnabled) { return null; } return ((MonoBehaviour)Instance).StartCoroutine(routine); } internal static void StopPluginCoroutine(Coroutine coroutine) { if (!((Object)(object)Instance == (Object)null) && coroutine != null) { ((MonoBehaviour)Instance).StopCoroutine(coroutine); } } private void Awake() { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown Instance = this; Logger = ((BaseUnityPlugin)this).Logger; Logger.LogInfo((object)"Plugin ShowEnemyHealth Fixed Edition by Rozza is loaded!"); ConfigManager.Initialize(((BaseUnityPlugin)this).Config); _harmony = new Harmony("EnemyHealth"); PatchAll(); } private void PatchAll() { IEnumerable enumerable; try { enumerable = Assembly.GetExecutingAssembly().GetTypes(); } catch (ReflectionTypeLoadException ex) { enumerable = ex.Types.Where((Type t) => t != null); } foreach (Type item in enumerable) { _harmony.PatchAll(item); } } } public static class MyPluginInfo { public const string PLUGIN_GUID = "REPO_ShowEnemyHealth"; public const string PLUGIN_NAME = "ShowEnemyHealth Fixed Edition"; public const string PLUGIN_VERSION = "1.0.0"; } }