Some mods may be broken due to the recent Alloyed Collective update.
Decompiled source of HealthBarViewer v1.0.0
HealthBarViewer.dll
Decompiled a year agousing System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Microsoft.CodeAnalysis; using RoR2; using RoR2.CameraModes; using RoR2.UI; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [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 Local.HealthBar.Viewer { [BepInPlugin("local.healthbar.viewer", "HealthBarViewer", "1.0.0")] public class Plugin : BaseUnityPlugin { private class ConfigValue<T> : ConfigValue<T, T> { public ConfigValue(ConfigEntry<T> entry) : base(entry) { convert = (T _) => _; } public static implicit operator ConfigValue<T>(ConfigEntry<T> entry) { return new ConfigValue<T>(entry); } } private class ConfigValue<T, U> { private readonly ConfigEntry<T> entry; public Func<T, U> convert; public ConfigValue(ConfigEntry<T> entry) { this.entry = entry; base..ctor(); } public static implicit operator ConfigValue<T, U>(ConfigEntry<T> entry) { return new ConfigValue<T, U>(entry); } public static implicit operator U(ConfigValue<T, U> configuration) { return configuration.convert(configuration.entry.Value); } } public const string version = "1.0.0"; public const string identifier = "local.healthbar.viewer"; private static ConfigValue<uint> duration; private static ConfigValue<uint> range; private static ConfigValue<float> threshold; private static ConfigValue<float> alpha; private static ConfigValue<bool> ally; private static ConfigValue<uint, float> delay; private static ConfigValue<uint, float> interval; public void Awake() { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Expected O, but got Unknown //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Expected O, but got Unknown duration = ((BaseUnityPlugin)this).Config.Bind<uint>("General", "Minimum Duration", 10u, "After damage is dealt, the target's health bar will remain visible for this many seconds."); threshold = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Health Threshold", 75f, new ConfigDescription("Enemies at this hit point percentage or below remain visible indefinitely.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>())); threshold.convert = percent; range = ((BaseUnityPlugin)this).Config.Bind<uint>("General", "Maximum Range", 100u, "Remove health bar regardless of health threshold if distance to target exceeds this value in meters. Set to zero for unlimited range."); ally = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Allied Targets", true, "Determines whether allies reveal their target upon dealing damage."); delay = ((BaseUnityPlugin)this).Config.Bind<uint>("Other", "Targeting Delay", 0u, "Aiming directly at an enemy will display their health for this many milliseconds. If target is below the health threshold, minimum duration parameter is used instead."); delay.convert = milliseconds; alpha = ((BaseUnityPlugin)this).Config.Bind<float>("Other", "Alpha Channel", 85f, new ConfigDescription("Use this parameter to adjust transparency/opacity of the health bar interface.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>())); alpha.convert = percent; interval = ((BaseUnityPlugin)this).Config.Bind<uint>("Other", "Refresh Interval", 500u, "How often to check target health/range, in milliseconds. Note that decreasing this value could negatively affect performance."); interval.convert = milliseconds; ReplaceEventHandler(); Harmony.CreateAndPatchAll(typeof(Plugin), (string)null); static float milliseconds(uint input) { return (float)input / 1000f; } static float percent(float input) { return input / 100f; } } private static void ReplaceEventHandler() { try { Type typeFromHandle = typeof(CombatHealthBarViewer); Type typeFromHandle2 = typeof(GlobalEventManager); string name = "onClientDamageNotified"; RuntimeHelpers.RunClassConstructor(typeFromHandle.TypeHandle); EventInfo @event = typeFromHandle2.GetEvent(name); Delegate[] invocationList = (typeFromHandle2.GetField(name, BindingFlags.Static | BindingFlags.NonPublic).GetValue(null) as Delegate).GetInvocationList(); foreach (Delegate @delegate in invocationList) { if (typeFromHandle == @delegate.Method.DeclaringType.DeclaringType) { @event.RemoveEventHandler(null, @delegate); return; } } throw new Exception("Unable to locate original health bar event handler."); } catch (Exception value) { Console.WriteLine(value); } finally { GlobalEventManager.onClientDamageNotified += ShowHealthBar; } } [HarmonyPatch(typeof(CombatHealthBarViewer), "Awake")] [HarmonyPostfix] private static void ApplySettings(CombatHealthBarViewer __instance) { __instance.healthBarDuration = (uint)duration; if ((float)alpha != 1f && Object.op_Implicit((Object)(object)((Component)__instance).gameObject)) { ((Component)__instance).gameObject.AddComponent<CanvasGroup>().alpha = alpha; } } [HarmonyPatch(typeof(CombatHealthBarViewer), "CleanUp")] [HarmonyPrefix] private static bool CheckStatus(CombatHealthBarViewer __instance) { //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) int num = __instance.trackedVictims.Count; while (--num >= 0) { HealthComponent val = __instance.trackedVictims[num]; HealthBarInfo healthBarInfo = __instance.GetHealthBarInfo(val); if (Object.op_Implicit((Object)(object)val) && val.alive && Object.op_Implicit((Object)(object)val.body)) { if (healthBarInfo.endTime > Time.time) { continue; } float num2; if ((uint)range == 0 || !Object.op_Implicit((Object)(object)__instance.viewerBody)) { num2 = (uint)range; } else { Vector3 val2 = __instance.viewerBody.corePosition - val.body.corePosition; num2 = ((Vector3)(ref val2)).magnitude; } float num3 = num2; if (val.combinedHealthFraction <= (float)threshold && num3 <= (float)(uint)range) { healthBarInfo.endTime = Time.time + (float)interval; continue; } } __instance.Remove(num, healthBarInfo); } return false; } private static void ShowHealthBar(DamageDealtMessage message) { //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) if (message.isSilent || !Object.op_Implicit((Object)(object)message.victim) || !Object.op_Implicit((Object)(object)message.attacker)) { return; } HealthComponent component = message.victim.GetComponent<HealthComponent>(); if (!Object.op_Implicit((Object)(object)component) || component.dontShowHealthbar) { return; } foreach (CombatHealthBarViewer instances in CombatHealthBarViewer.instancesList) { if (Object.op_Implicit((Object)(object)instances.viewerBodyObject)) { object obj = instances.viewerBodyObject; object obj2 = message.attacker; if ((bool)ally) { obj = instances.viewerTeamIndex; obj2 = TeamComponent.GetObjectTeam(message.attacker); } if (obj.Equals(obj2)) { instances.HandleDamage(component, TeamComponent.GetObjectTeam(message.victim)); } } } } [HarmonyPatch(typeof(CameraRigController), "SetCameraState")] [HarmonyPostfix] private static void UpdateCrosshair(CameraRigController __instance) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) CameraModeBase cameraMode = __instance.cameraMode; HurtBox val2 = (__instance.lastCrosshairHurtBox = ((InstanceData)(/*isinst with value type is only supported in some contexts*/?)).lastCrosshairHurtBox); if (Object.op_Implicit((Object)(object)__instance.hud)) { CombatHealthBarViewer combatHealthBarViewer = __instance.hud.combatHealthBarViewer; if (Object.op_Implicit((Object)(object)combatHealthBarViewer)) { combatHealthBarViewer.crosshairTarget = (Object.op_Implicit((Object)(object)val2) ? val2.healthComponent : null); } } } [HarmonyPatch(typeof(CombatHealthBarViewer), "Update")] [HarmonyPrefix] private static bool ShowCrosshairTarget(CombatHealthBarViewer __instance) { if (Object.op_Implicit((Object)(object)__instance.crosshairTarget)) { float num = delay; if (__instance.crosshairTarget.combinedHealthFraction <= (float)threshold) { num = (uint)duration; } if (num > 0f) { HealthBarInfo healthBarInfo = __instance.GetHealthBarInfo(__instance.crosshairTarget); healthBarInfo.endTime = Mathf.Max(healthBarInfo.endTime, Time.time + num); } } __instance.SetDirty(); return false; } } }