Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of ShowEnemyHealth v1.0.3
REPO_ShowEnemyHealth.dll
Decompiled a year agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Reflection.Emit; 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 Photon.Pun; using TMPro; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("REPO_ShowEnemyHealth")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.3.0")] [assembly: AssemblyInformationalVersion("1.0.3+1b27dec367654b521dc41d1a2bb4fbcca648c4e7")] [assembly: AssemblyProduct("ShowEnemyHealth")] [assembly: AssemblyTitle("REPO_ShowEnemyHealth")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.3.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<bool> ShowEnemyHealth { get; private set; } public static ConfigEntry<float> HealthShowTimer { get; private set; } public static ConfigEntry<float> HealthFontSize { get; private set; } public static ConfigEntry<string> HealthFontColor { get; private set; } public static ConfigEntry<bool> ShowEnemyDamage { get; private set; } public static ConfigEntry<float> DamageFontSize { get; private set; } public static ConfigEntry<string> DamageFontHighlightColor { get; private set; } public static ConfigEntry<string> DamageFontColor { get; private set; } public static ConfigEntry<bool> AttemptMultiplayerHealthSync { get; private set; } public static void Initialize(ConfigFile configFile) { ConfigFile = configFile; BindConfigs(); } private static void BindConfigs() { //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Expected O, but got Unknown //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: 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_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Expected O, but got Unknown //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Expected O, but got Unknown //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_01d5: Expected O, but got Unknown AcceptableValueList<string> val = new AcceptableValueList<string>(new string[10] { "black", "blue", "cyan", "green", "grey", "magenta", "orange", "red", "white", "yellow" }); ShowEnemyHealth = ConfigFile.Bind<bool>("General", "ShowEnemyHealth", true, ""); HealthShowTimer = ConfigFile.Bind<float>("General", "HealthShowTimer", 120f, new ConfigDescription("Max seconds to show enemy health", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 600f), Array.Empty<object>())); HealthFontSize = ConfigFile.Bind<float>("General", "HealthFontSize", 15f, new ConfigDescription("Enemy health font size", (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 50f), Array.Empty<object>())); HealthFontColor = ConfigFile.Bind<string>("General", "HealthFontColor", "grey", new ConfigDescription("Enemy health font color", (AcceptableValueBase)(object)val, Array.Empty<object>())); ShowEnemyDamage = ConfigFile.Bind<bool>("General", "ShowEnemyDamage", true, ""); DamageFontSize = ConfigFile.Bind<float>("General", "DamageFontSize", 25f, new ConfigDescription("Damage font size", (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 50f), Array.Empty<object>())); DamageFontHighlightColor = ConfigFile.Bind<string>("General", "DamageFontHighlightColor", "red", new ConfigDescription("Damage font highlight color", (AcceptableValueBase)(object)val, Array.Empty<object>())); DamageFontColor = ConfigFile.Bind<string>("General", "DamageFontColor", "orange", new ConfigDescription("Damage font primary color", (AcceptableValueBase)(object)val, Array.Empty<object>())); AttemptMultiplayerHealthSync = ConfigFile.Bind<bool>("General", "AttemptMultiplayerHealthSync", true, "Sync enemy health across all clients"); } } [RequireComponent(typeof(RectTransform))] [RequireComponent(typeof(TextMeshProUGUI))] internal class CustomEnemyHealthUI : WorldSpaceUIChild { public static CustomEnemyHealthUI instance; private Vector3 scale; internal Vector3 newWorldPosition; private float showTimer; private Enemy currEnemy; private EnemyHealth currEnemyHealth; private EnemyRigidbody enemyRigidBody; private TextMeshProUGUI text; private Vector3 worldspaceOffset; private Vector3 targetWorldspaceOffset; public int recalcIntervalFrames = 50; private int frameCounter; public float worldspaceOffsetLerpRate = 5f; public AnimationCurve curveIntro = new AnimationCurve(); public AnimationCurve curveOutro = new AnimationCurve(); private bool hasDied; internal bool hasExploded; private void Awake() { //IL_002c: 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_0047: Unknown result type (might be due to invalid IL or missing references) typeof(WorldSpaceUIChild).GetField("positionOffset", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(this, (object)new Vector3(0f, -0.05f, 0f)); instance = this; scale = Vector3.one; text = ((Component)this).GetComponent<TextMeshProUGUI>(); } public void Show(EnemyHealth enemyHealth, Vector3 screenspaceOffset) { //IL_002f: 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_0053: 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_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Expected O, but got Unknown //IL_00fd: 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) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Expected O, but got Unknown //IL_0163: 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) if (!ConfigManager.ShowEnemyHealth.Value) { Patches.healthUIElements.Remove(currEnemyHealth); Object.Destroy((Object)(object)((Component)this).gameObject); 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; showTimer = ConfigManager.HealthShowTimer.Value; if (!Object.op_Implicit((Object)(object)currEnemy) || !Object.op_Implicit((Object)(object)currEnemyHealth)) { typeof(WorldSpaceUIChild).GetField("positionOffset", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(this, screenspaceOffset); currEnemyHealth = enemyHealth; currEnemy = (Enemy)((object)enemyHealth).GetType().GetField("enemy", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(enemyHealth); newWorldPosition = ((Component)currEnemy).transform.position; typeof(WorldSpaceUIChild).GetField("worldPosition", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(this, newWorldPosition); enemyRigidBody = (EnemyRigidbody)((object)currEnemy).GetType().GetField("Rigidbody", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(currEnemy); UpdateTargetWorldSpaceOffset(); worldspaceOffset = targetWorldspaceOffset; UpdateTextValues(); } } internal void UpdateTargetWorldSpaceOffset() { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: 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_0029: 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_007a: 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_0044: Unknown result type (might be due to invalid IL or missing references) Bounds bounds = default(Bounds); ((Bounds)(ref bounds))..ctor(Vector3.zero, Vector3.zero); Collider[] componentsInChildren = ((Component)enemyRigidBody).GetComponentsInChildren<Collider>(); if (componentsInChildren.Length != 0) { bounds = componentsInChildren[0].bounds; } Collider[] array = componentsInChildren; foreach (Collider val in array) { if (!val.isTrigger) { ((Bounds)(ref bounds)).Encapsulate(val.bounds); } } float num = ((Bounds)(ref bounds)).max.y / 2f; targetWorldspaceOffset = new Vector3(0f, num, 0f); } internal void UpdateTextValues() { //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Invalid comparison between Unknown and I4 if (!((Object)(object)currEnemy == (Object)null) && !((Object)(object)currEnemyHealth == (Object)null)) { int num = (int)typeof(EnemyHealth).GetField("healthCurrent", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(currEnemyHealth); int health = currEnemyHealth.health; ((TMP_Text)text).text = $"{num}/{health}"; bool num2 = (bool)typeof(EnemyHealth).GetField("dead", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(currEnemyHealth); bool flag = (int)currEnemy.CurrentState == 11; if ((num2 || flag || hasExploded) && !hasDied) { Plugin.Logger.LogDebug((object)"Enemy should have died/despawned, clearing healthbar timer"); showTimer = 0.5f; hasDied = true; } } } protected override void Update() { //IL_0031: 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_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_006f: 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_007d: 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_00ab: 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_00f3: 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_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Expected O, but got Unknown ((WorldSpaceUIChild)this).Update(); frameCounter++; if (frameCounter >= recalcIntervalFrames) { frameCounter = 0; UpdateTargetWorldSpaceOffset(); } worldspaceOffset = Vector3.Lerp(worldspaceOffset, targetWorldspaceOffset, Time.deltaTime * worldspaceOffsetLerpRate); FieldInfo? field = typeof(WorldSpaceUIChild).GetField("worldPosition", BindingFlags.Instance | BindingFlags.NonPublic); _ = (Vector3)field.GetValue(this); field.SetValue(this, newWorldPosition + worldspaceOffset); if ((Object)(object)currEnemy != (Object)null) { newWorldPosition = currEnemy.CenterTransform.position; } if (showTimer > 0f) { showTimer -= Time.deltaTime; float num = 1f; float num2 = 5f; float num3 = 20f; float num4 = Vector3.Distance(((Component)Camera.main).transform.position, newWorldPosition); 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); } ((TMP_Text)text).alpha = num; ((Component)this).transform.localScale = localScale; UpdateTextValues(); } else if (showTimer <= 0f && (Object)(object)currEnemyHealth != (Object)null) { EnemyParent val = (EnemyParent)((object)currEnemy).GetType().GetField("EnemyParent", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(currEnemy); Plugin.Logger.LogDebug((object)("Removing enemy health UI for " + val.enemyName + "...")); Patches.healthUIElements.Remove(currEnemyHealth); Object.Destroy((Object)(object)((Component)this).gameObject); } } } [HarmonyPatch] public static class Patches { [CompilerGenerated] private sealed class <DelayedSetText>d__7 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public FieldInfo fieldInfo; public object target; public string targetText; private TextMeshProUGUI <text>5__2; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <DelayedSetText>d__7(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <text>5__2 = null; <>1__state = -2; } private bool MoveNext() { //IL_00ad: 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_005c: Expected O, but got Unknown //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_013a: 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) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: 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) switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = null; <>1__state = 1; return true; case 1: <>1__state = -1; <text>5__2 = (TextMeshProUGUI)(fieldInfo?.GetValue(target)); if ((Object)(object)<text>5__2 == (Object)null) { <>2__current = null; <>1__state = 2; return true; } break; case 2: <>1__state = -1; break; } ((TMP_Text)<text>5__2).text = targetText; ((TMP_Text)<text>5__2).fontSize = ConfigManager.DamageFontSize.Value; ((Graphic)<text>5__2).color = Color.blue; Color32 val = default(Color32); if (ColorUtility.DoTryParseHtmlColor(ConfigManager.DamageFontHighlightColor.Value, ref val)) { ((Graphic)<text>5__2).color = Color32.op_Implicit(val); } Color32 val2 = default(Color32); if (ColorUtility.DoTryParseHtmlColor(ConfigManager.DamageFontColor.Value, ref val2)) { Color val3 = Color32.op_Implicit(val2); typeof(WorldSpaceUIValueLost).GetField("textColor", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(target, val3); } else { typeof(WorldSpaceUIValueLost).GetField("textColor", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(target, Color.cyan); } 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 <DelayedShowHealthUI>d__8 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public CustomEnemyHealthUI healthBar; public EnemyHealth enemyHealth; public Vector3 offset; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <DelayedShowHealthUI>d__8(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_003b: 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 { healthBar.Show(enemyHealth, offset); } catch (Exception arg) { Plugin.Logger.LogDebug((object)$"Handling exception in DelayedShowHealthBar: {arg}"); try { healthUIElements.Remove(enemyHealth); Object.Destroy((Object)(object)healthBar); } 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<EnemyHealth, CustomEnemyHealthUI> healthUIElements = new Dictionary<EnemyHealth, CustomEnemyHealthUI>(); [HarmonyPatch(typeof(EnemyHealth), "Hurt")] [HarmonyPrefix] public static void ShowEnemyHealthOnHurt(int _damage, Vector3 _hurtDirection, EnemyHealth __instance) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: 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_0075: Expected O, but got Unknown //IL_008d: 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_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) int num = (int)((object)__instance).GetType().GetField("healthCurrent", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(__instance); Enemy val = (Enemy)((object)__instance).GetType().GetField("enemy", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(__instance); Vector3 position = val.CenterTransform.position; int num2 = num - _damage; if (SemiFunc.IsMasterClientOrSingleplayer()) { try { EnemyParent val2 = (EnemyParent)((object)val).GetType().GetField("EnemyParent", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(val); _ = (EnemyRigidbody)((object)val).GetType().GetField("Rigidbody", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(val); bool flag = (bool)typeof(EnemyHealth).GetField("dead", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(__instance); Vector3 val3 = default(Vector3); val3.x = 0f; val3.y = 0f; val3.z = 0f; bool flag2 = num2 <= 0 || flag; Plugin.Logger.LogDebug((object)$"{val2.enemyName} HURT by {_damage}, currHealth: {num}, will have {num - _damage}, willDie:{flag2} ..."); CreateDamageUI(_damage, position); if (!flag2) { CreateHealthUI(__instance, position); } return; } catch (Exception arg) { Plugin.Logger.LogError((object)$"LogEnemyHurt failed:\n{arg}"); return; } } try { CreateDamageUI(_damage, val.CenterTransform.position); } catch (Exception arg2) { Plugin.Logger.LogError((object)$"FAILED TO ADD UI:\n{arg2}"); } } [HarmonyPatch(typeof(EnemyHealth), "HurtRPC")] [HarmonyPrefix] public static void ShowEnemyHealthOnHurtRPC(int _damage, Vector3 _hurtDirection, EnemyHealth __instance) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Expected O, but got Unknown //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: 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) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) if (SemiFunc.IsMasterClientOrSingleplayer()) { return; } bool flag = false; int num = Math.Abs(_damage); if (_damage < 0) { flag = true; } try { Enemy val = (Enemy)((object)__instance).GetType().GetField("enemy", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(__instance); EnemyParent val2 = (EnemyParent)((object)val).GetType().GetField("EnemyParent", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(val); _ = (EnemyRigidbody)((object)val).GetType().GetField("Rigidbody", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(val); bool flag2 = (bool)typeof(EnemyHealth).GetField("dead", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(__instance); Vector3 val3 = default(Vector3); val3.x = 0f; val3.y = 0f; val3.z = 0f; Vector3 position = val.CenterTransform.position; FieldInfo field = ((object)__instance).GetType().GetField("healthCurrent", BindingFlags.Instance | BindingFlags.NonPublic); int num2 = (int)field.GetValue(__instance); int num3 = num2 - num; if (ConfigManager.AttemptMultiplayerHealthSync.Value && flag) { field.SetValue(__instance, num3); CreateDamageUI(num, position); } bool flag3 = num3 <= 0 || flag2; Plugin.Logger.LogDebug((object)$"{val2.enemyName} HURT by {num}, currHealth: {num2}, will have {num3}, willDie:{flag3} ..."); if (!flag3) { CreateHealthUI(__instance, position); } } catch (Exception arg) { Plugin.Logger.LogError((object)$"LogEnemyHurt failed:\n{arg}"); } } [HarmonyPatch(typeof(EnemyBang), "ExplodeRPC")] [HarmonyPostfix] public static void HandleBangerExplode(EnemyBang __instance) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Expected O, but got Unknown try { Enemy obj = (Enemy)typeof(EnemyBang).GetField("enemy", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(__instance); EnemyHealth key = (EnemyHealth)typeof(Enemy).GetField("Health", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(obj); if (healthUIElements.TryGetValue(key, out var value)) { value.hasExploded = true; } } catch (Exception arg) { Plugin.Logger.LogError((object)$"HandleBangerExplode failed:\n{arg}"); } } public static void HurtColliderEnemyHurtHook(EnemyHealth enemyHealth, int damage, Vector3 hurtDirection) { //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) if (SemiFunc.IsNotMasterClient() || !SemiFunc.IsMultiplayer()) { enemyHealth.Hurt(damage, hurtDirection); return; } try { if (ConfigManager.AttemptMultiplayerHealthSync.Value) { ((PhotonView)typeof(EnemyHealth).GetField("photonView", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(enemyHealth)).RPC("HurtRPC", (RpcTarget)0, new object[2] { -damage, hurtDirection }); } } finally { enemyHealth.Hurt(damage, hurtDirection); } } internal static void CreateHealthUI(EnemyHealth enemyHealth, Vector3 enemyPosition) { //IL_0002: 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_002d: 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_0052: 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_009d: 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) Vector3 val = default(Vector3); val.x = 0f; val.y = 0f; val.z = 0f; Vector3 val2 = val; if (!healthUIElements.ContainsKey(enemyHealth)) { GameObject obj = Object.Instantiate<GameObject>(WorldSpaceUIParent.instance.TTSPrefab, ((Component)WorldSpaceUIParent.instance).transform.position, ((Component)WorldSpaceUIParent.instance).transform.rotation, ((Component)WorldSpaceUIParent.instance).transform); Object.Destroy((Object)(object)obj.GetComponent<WorldSpaceUITTS>()); CustomEnemyHealthUI customEnemyHealthUI = obj.AddComponent<CustomEnemyHealthUI>(); typeof(WorldSpaceUIChild).GetField("worldPosition", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(customEnemyHealthUI, enemyPosition); healthUIElements.Add(enemyHealth, customEnemyHealthUI); ((MonoBehaviour)enemyHealth).StartCoroutine(DelayedShowHealthUI(healthUIElements[enemyHealth], enemyHealth, val2)); } else { healthUIElements[enemyHealth].Show(enemyHealth, val2); } } internal static void CreateDamageUI(int damage, Vector3 worldPosition) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_002a: 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) if (ConfigManager.ShowEnemyDamage.Value) { WorldSpaceUIParent instance = WorldSpaceUIParent.instance; WorldSpaceUIValueLost component = Object.Instantiate<GameObject>(instance.valueLostPrefab, ((Component)instance).transform.position, ((Component)instance).transform.rotation, ((Component)instance).transform).GetComponent<WorldSpaceUIValueLost>(); typeof(WorldSpaceUIValueLost).GetField("worldPosition", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(component, worldPosition); typeof(WorldSpaceUIValueLost).GetField("value", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(component, damage); FieldInfo field = typeof(WorldSpaceUIValueLost).GetField("text", BindingFlags.Instance | BindingFlags.NonPublic); ((MonoBehaviour)component).StartCoroutine(DelayedSetText(field, component, $"-{damage}")); ((List<WorldSpaceUIValueLost>)((object)instance).GetType().GetField("valueLostList", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(instance)).Add(component); } } [IteratorStateMachine(typeof(<DelayedSetText>d__7))] internal static IEnumerator DelayedSetText(FieldInfo fieldInfo, object target, string targetText) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <DelayedSetText>d__7(0) { fieldInfo = fieldInfo, target = target, targetText = targetText }; } [IteratorStateMachine(typeof(<DelayedShowHealthUI>d__8))] internal static IEnumerator DelayedShowHealthUI(CustomEnemyHealthUI healthBar, 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 <DelayedShowHealthUI>d__8(0) { healthBar = healthBar, enemyHealth = enemyHealth, offset = offset }; } } [HarmonyPatch(typeof(HurtCollider), "EnemyHurt")] public static class EnemyHurtTranspilerPatch { [CompilerGenerated] private sealed class <Transpiler>d__0 : IEnumerable<CodeInstruction>, IEnumerable, IEnumerator<CodeInstruction>, IDisposable, IEnumerator { private int <>1__state; private CodeInstruction <>2__current; private int <>l__initialThreadId; private IEnumerable<CodeInstruction> instructions; public IEnumerable<CodeInstruction> <>3__instructions; private MethodInfo <targetHurtMethod>5__2; private MethodInfo <hookMethod>5__3; private IEnumerator<CodeInstruction> <>7__wrap3; CodeInstruction IEnumerator<CodeInstruction>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <Transpiler>d__0(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || (uint)(num - 1) <= 1u) { try { } finally { <>m__Finally1(); } } <targetHurtMethod>5__2 = null; <hookMethod>5__3 = null; <>7__wrap3 = null; <>1__state = -2; } private bool MoveNext() { //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Expected O, but got Unknown try { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <targetHurtMethod>5__2 = AccessTools.Method(typeof(EnemyHealth), "Hurt", new Type[2] { typeof(int), typeof(Vector3) }, (Type[])null); <hookMethod>5__3 = AccessTools.Method(typeof(Patches), "HurtColliderEnemyHurtHook", new Type[3] { typeof(EnemyHealth), typeof(int), typeof(Vector3) }, (Type[])null); <>7__wrap3 = instructions.GetEnumerator(); <>1__state = -3; break; case 1: <>1__state = -3; break; case 2: <>1__state = -3; break; } if (<>7__wrap3.MoveNext()) { CodeInstruction current = <>7__wrap3.Current; if (current.opcode == OpCodes.Callvirt && current.operand is MethodInfo methodInfo && methodInfo == <targetHurtMethod>5__2) { <>2__current = new CodeInstruction(OpCodes.Call, (object)<hookMethod>5__3); <>1__state = 1; return true; } <>2__current = current; <>1__state = 2; return true; } <>m__Finally1(); <>7__wrap3 = null; return false; } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; if (<>7__wrap3 != null) { <>7__wrap3.Dispose(); } } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator<CodeInstruction> IEnumerable<CodeInstruction>.GetEnumerator() { <Transpiler>d__0 <Transpiler>d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; <Transpiler>d__ = this; } else { <Transpiler>d__ = new <Transpiler>d__0(0); } <Transpiler>d__.instructions = <>3__instructions; return <Transpiler>d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<CodeInstruction>)this).GetEnumerator(); } } [IteratorStateMachine(typeof(<Transpiler>d__0))] private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <Transpiler>d__0(-2) { <>3__instructions = instructions }; } } [BepInPlugin("REPO_ShowEnemyHealth", "ShowEnemyHealth", "1.0.3")] public class Plugin : BaseUnityPlugin { internal static ManualLogSource Logger; private Harmony _harmony; private void Awake() { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown Logger = ((BaseUnityPlugin)this).Logger; Logger.LogInfo((object)"Plugin ShowEnemyHealth by Rozza is loaded!"); ConfigManager.Initialize(((BaseUnityPlugin)this).Config); _harmony = new Harmony("EnemyHealth"); PatchAll(); } private void PatchAll() { IEnumerable<Type> 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"; public const string PLUGIN_VERSION = "1.0.3"; } }