RUMBLE does not support other mod managers. If you want to use a manager, you must use the RUMBLE Mod Manager, a manager specifically designed for this game.
Decompiled source of HealthDisplayWithFont v0.4.2
Mods/HealthDisplayWithFont.dll
Decompiled 21 hours agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using HarmonyLib; using HealthDisplayWithFont; using Il2CppRUMBLE.Managers; using Il2CppRUMBLE.Players; using Il2CppRUMBLE.Players.Subsystems; using Il2CppRUMBLE.Utilities; using Il2CppSystem.Collections.Generic; using Il2CppTMPro; using MelonLoader; using Microsoft.CodeAnalysis; using RumbleModdingAPI.RMAPI; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: MelonInfo(typeof(HealthDisplayWithFontClass), "HealthDisplayWithFont", "0.4.2", "ninjaguardian", "https://thunderstore.io/c/rumble/p/ninjaguardian/HealthDisplayWithFont")] [assembly: MelonGame("Buckethead Entertainment", "RUMBLE")] [assembly: MelonColor(255, 0, 160, 230)] [assembly: MelonAuthorColor(255, 0, 160, 230)] [assembly: MelonPlatformDomain(/*Could not decode attribute arguments.*/)] [assembly: VerifyLoaderVersion("0.7.2", true)] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")] [assembly: AssemblyCompany("ninjaguardian (github)")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCopyright("Copyright © 2025 ninjaguardian (github), This work is dedicated to the public domain under CC0 1.0.")] [assembly: AssemblyDescription("Shows health above healthbar with a chosen font")] [assembly: AssemblyFileVersion("0.4.2.0")] [assembly: AssemblyInformationalVersion("0.4.2")] [assembly: AssemblyProduct("HealthDisplayWithFont")] [assembly: AssemblyTitle("HealthDisplayWithFont")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/ninjaguardian/HealthDisplayWithFont")] [assembly: AssemblyVersion("0.4.2.0")] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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] [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; } } } namespace HealthDisplayWithFont { public static class HealthDisplayWithFontModInfo { public const string ModName = "HealthDisplayWithFont"; public const string ModVersion = "0.4.2"; public const string MLVersion = "0.7.2"; public const string HealthbarTextName = "HealthText"; } public class HealthDisplayWithFontClass : MelonMod { [HarmonyPatch(typeof(PlayerHealth), "Initialize")] private static class PlayerHealthInitPatch { private static void Postfix(PlayerHealth __instance, PlayerController controller) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) AddHealthbarText(GetHealthbar(((Component)__instance).transform, controller.controllerType), controller); } } [HarmonyPatch(typeof(PlayerHealth), "SetHealthBarPercentage")] private static class SetHealthBarPercentagePatch { private static void Postfix(PlayerHealth __instance, float currentHealth) { Transform? healthbarText = GetHealthbarText(((Component)__instance).transform, ((PlayerControllerSubsystem)__instance).parentController); if (healthbarText != null) { TextMeshPro component = ((Component)healthbarText).GetComponent<TextMeshPro>(); if (component != null) { ((TMP_Text)component).SetText("{0}", currentHealth); } } } } [HarmonyPatch(typeof(PlayerNameTag), "SetPlayerNameTagActive")] private static class SetPlayerNameTagActivePatch { private static void Prefix(PlayerNameTag __instance, bool state) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Invalid comparison between Unknown and I4 if (FadeActive.Contains(__instance)) { return; } PlayerController parentController = ((PlayerControllerSubsystem)__instance).parentController; if (parentController != null && (int)parentController.controllerType == 2 && !((Object)(object)((Component)__instance).transform.parent != (Object)(object)((Component)parentController).transform) && !ControllerIsReplay(parentController)) { Transform? healthbarText = GetHealthbarText(parentController); if (healthbarText != null) { ((Component)healthbarText).gameObject.SetActive(!state); } } } } [HarmonyPatch(typeof(PlayerNameTag), "FadePlayerNameTag")] private static class FadePlayerNameTagPatch { private static void Prefix(PlayerNameTag __instance, bool on) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Invalid comparison between Unknown and I4 PlayerController parentController = ((PlayerControllerSubsystem)__instance).parentController; if (parentController == null || (int)parentController.controllerType != 2 || (Object)(object)((Component)__instance).transform.parent != (Object)(object)((Component)parentController).transform || ControllerIsReplay(parentController)) { return; } Transform healthbar = GetHealthbarText(parentController); Transform obj = healthbar; if ((Object)(object)((obj != null) ? ((Component)obj).gameObject : null) == (Object)null) { return; } if (!on && !((Component)healthbar).gameObject.activeSelf) { ((Component)healthbar).gameObject.SetActive(true); ((TMP_Text)((Component)healthbar).GetComponent<TextMeshPro>()).alpha = 0f; } if (!FadeActive.Add(__instance)) { return; } MelonCoroutines.Start(FadeText(((Component)healthbar).GetComponent<TextMeshPro>(), on ? 0f : 1f, __instance.playerNameFadeOutDuration, on ? ((Action)delegate { Transform obj2 = healthbar; if (obj2 != null) { ((Component)obj2).gameObject.SetActive(false); } FadeActive.Remove(__instance); }) : ((Action)delegate { FadeActive.Remove(__instance); }))); } } private static readonly Dictionary<TMP_FontAsset, TMP_FontAsset> FontToShaderFont = new Dictionary<TMP_FontAsset, TMP_FontAsset>(); private static readonly HashSet<PlayerNameTag> FadeActive = new HashSet<PlayerNameTag>(); private static Func<bool, TMP_FontAsset>? _getFont; private static Func<string, bool, TMP_FontAsset>? _fontFromName; private static Material? _healthbarMaterial; private static void AddHealthbarText(Transform? uiBar, PlayerController controller) { //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Expected O, but got Unknown //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Invalid comparison between Unknown and I4 //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Invalid comparison between Unknown and I4 //IL_0124: 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_0162: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)uiBar == (Object)null) { return; } if ((Object)(object)_healthbarMaterial == (Object)null) { MelonLogger.Error("Something really bad happened! (Context: HealthbarMaterial)", new Exception("Mod detected impossible state")); return; } Transform val = uiBar.Find("HealthText"); if (val != null) { if (ControllerIsReplay(controller)) { ((Component)val).gameObject.SetActive(true); } return; } GameObject val2 = new GameObject("HealthText"); val2.transform.SetParent(uiBar, false); TextMeshPro val3 = val2.AddComponent<TextMeshPro>(); if ((int)controller.controllerType == 1) { val2.transform.localPosition = new Vector3(-1.01f, 0.01f, 0f); val2.transform.localRotation = Quaternion.Euler(63f, 270f, 0f); val2.transform.localScale = new Vector3(0.015f, 0.007f, 0.015f); ((TMP_Text)val3).fontSize = 36f; } else { Transform obj = ((Component)controller).transform.Find("NameTag"); if (obj != null && ((Component)obj).gameObject.activeSelf) { val2.SetActive(false); } val2.transform.localPosition = new Vector3(0f, -0.05f, 0f); val2.transform.localRotation = Quaternion.Euler(0f, 0f, 0f); val2.transform.localScale = new Vector3(-0.1f, 0.1f, 0.1f); val2.GetComponent<RectTransform>().pivot = new Vector2(0.5f, 0f); ((TMP_Text)val3).fontSize = 30f; } ((TMP_Text)val3).SetText("{0}", (float)controller.assignedPlayer.Data.HealthPoints); ((TMP_Text)val3).alignment = (TextAlignmentOptions)514; if (_getFont == null) { return; } if ((int)controller.controllerType == 1) { ((TMP_Text)val3).font = _getFont(arg: true); return; } TMP_FontAsset key = _getFont(arg: true); if (FontToShaderFont.TryGetValue(key, out TMP_FontAsset value)) { ((TMP_Text)val3).font = value; return; } TMP_FontAsset val4 = (((TMP_Text)val3).font = _getFont(arg: false)); _healthbarMaterial.mainTexture = (Texture)(object)val4.atlasTexture; ((TMP_Text)val3).fontMaterial = _healthbarMaterial; ((TMP_Asset)val4).material = _healthbarMaterial; FontToShaderFont[key] = val4; } private static Transform? GetHealthbarText(PlayerController? controller) { return GetHealthbarText((controller != null) ? ((Component)controller).transform.Find("UI") : null, controller); } private static Transform? GetHealthbarText(Transform? ui, PlayerController? controller) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) Transform? healthbar = GetHealthbar(ui, (controller != null) ? new ControllerType?(controller.controllerType) : ((ControllerType?)null)); if (healthbar == null) { return null; } return healthbar.Find("HealthText"); } private static Transform? GetHealthbar(Transform? ui, ControllerType? controllerType) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Invalid comparison between Unknown and I4 //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Invalid comparison between Unknown and I4 if ((Object)(object)ui == (Object)null) { return null; } if (controllerType.HasValue) { ControllerType valueOrDefault = controllerType.GetValueOrDefault(); if ((int)valueOrDefault != 1) { if ((int)valueOrDefault == 2) { Transform child = ui.GetChild(1); if (((child != null) ? ((Object)child).name : null) == "RemoteUI") { return child; } MelonLogger.Warning("Could not get RemoteUI via GetChild"); child = ui.Find("RemoteUI"); if ((Object)(object)child != (Object)null) { return child; } MelonLogger.Error("Could not get RemoteUI via Find"); return null; } MelonLogger.Warning($"Unknown controller type: {controllerType}"); return null; } Transform child2 = ui.GetChild(0); Transform val = ((child2 != null) ? child2.GetChild(1) : null); if (((val != null) ? ((Object)val).name : null) == "Local UI Bar") { return val; } MelonLogger.Warning("Could not get Local Healthbar via GetChild"); val = ui.Find("LocalUI/Local UI Bar"); if ((Object)(object)val != (Object)null) { return val; } MelonLogger.Error("Could not get Local Healthbar via Find"); return null; } return null; } private static bool ControllerIsReplay(PlayerController controller) { Transform parent = ((Component)controller).transform.parent; return ((parent != null) ? ((Object)parent).name : null) == "Replay Players"; } private static IEnumerator FadeText(TextMeshPro text, float endAlpha, float playerNameFadeOutDuration, Action? onEnd = null) { if ((Object)(object)text == (Object)null) { onEnd?.Invoke(); yield break; } float startAlpha = ((TMP_Text)text).alpha; if (playerNameFadeOutDuration <= 0f || Mathf.Approximately(startAlpha, endAlpha)) { ((TMP_Text)text).alpha = endAlpha; onEnd?.Invoke(); yield break; } float elapsed = 0f; while (elapsed < playerNameFadeOutDuration) { elapsed += Time.deltaTime; ((TMP_Text)text).alpha = Mathf.Lerp(startAlpha, endAlpha, Mathf.Clamp01(elapsed / playerNameFadeOutDuration)); yield return null; } ((TMP_Text)text).alpha = endAlpha; onEnd?.Invoke(); } public override void OnInitializeMelon() { _healthbarMaterial = AssetBundles.LoadAssetFromStream<Material>((MelonMod)(object)this, "HealthDisplayWithFont.healthbartextshader", "healthbartext"); ((Object)_healthbarMaterial).hideFlags = (HideFlags)61; ((Object)_healthbarMaterial.shader).hideFlags = (HideFlags)61; Type type = ((object)MelonBase.FindMelon("Fontifier", "ninjaguardian"))?.GetType(); if ((object)type != null) { MethodInfo method = type.GetMethod("RegisterModCopy", BindingFlags.Static | BindingFlags.Public); object[] parameters = new object[2] { ((MelonBase)this).Info.Name, new EventHandler<EventArgs>(FontChanged) }; object obj = method?.Invoke(null, parameters); if (obj == null) { MelonLogger.Error("Something really bad happened! (Context: Fontifier installed, cannot invoke)", new Exception("Mod detected impossible state")); return; } (_getFont, _fontFromName) = ((Func<bool, TMP_FontAsset>, Func<string, bool, TMP_FontAsset>))obj; } } private static void FontChanged(object? sender, EventArgs args) { //IL_02cc: Unknown result type (might be due to invalid IL or missing references) //IL_02d2: Invalid comparison between Unknown and I4 if (_fontFromName == null || (Object)(object)_healthbarMaterial == (Object)null) { MelonLogger.Error($"Something really bad happened! (Context: FontFromName {_fontFromName != null}, HealthbarMaterial {(Object)(object)_healthbarMaterial != (Object)null})", new Exception("Mod detected impossible state")); return; } TMP_FontAsset val = (TMP_FontAsset)_fontFromName(((dynamic)args).Value, true); TMP_FontAsset val2; if (FontToShaderFont.TryGetValue(val, out TMP_FontAsset value)) { val2 = value; } else { val2 = (TMP_FontAsset)_fontFromName(((dynamic)args).Value, false); _healthbarMaterial.mainTexture = (Texture)(object)val2.atlasTexture; ((TMP_Asset)val2).material = _healthbarMaterial; FontToShaderFont[val] = val2; } Enumerator<Player> enumerator = Singleton<PlayerManager>.instance.AllPlayers.GetEnumerator(); while (enumerator.MoveNext()) { Player current = enumerator.Current; Transform? healthbarText = GetHealthbarText(current.Controller); TextMeshPro val3 = ((healthbarText != null) ? ((Component)healthbarText).GetComponent<TextMeshPro>() : null); if (val3 != null) { if ((int)current.Controller.controllerType == 1) { ((TMP_Text)val3).font = val; continue; } ((TMP_Text)val3).font = val2; ((TMP_Text)val3).fontMaterial = _healthbarMaterial; } } } } }