Some mods target the Mono version of the game, which is available by opting into the Steam beta branch "alternate"
Decompiled source of SimpleHealthBarMono v1.4.0
SimpleHealthBar-Mono.dll
Decompiled a week agousing System; using System.CodeDom.Compiler; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Drawing; using System.Globalization; using System.Linq; using System.Reflection; using System.Resources; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using FishNet; using FishNet.Object; using HarmonyLib; using MelonLoader; using MelonLoader.Preferences; using Microsoft.CodeAnalysis; using ScheduleOne; using ScheduleOne.DevUtilities; using ScheduleOne.ItemFramework; using ScheduleOne.NPCs; using ScheduleOne.PlayerScripts; using ScheduleOne.UI; using ScheduleOne.UI.Phone; using SimpleHealthBar; using SimpleHealthBar.Helpers; using SimpleHealthBar.NPCUtils; using SimpleHealthBar.PlayerUtils; using SimpleHealthBar.UI; 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: MelonInfo(typeof(global::SimpleHealthBar.SimpleHealthBar), "SimpleHealthBar", "1.3.1", "iTidez", "https://www.nexusmods.com/schedule1/mods/1106")] [assembly: MelonColor(1, 255, 0, 0)] [assembly: MelonGame("TVGS", "Schedule I")] [assembly: AssemblyMetadata("NexusModID", "1106")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("SimpleHealthBar-Mono")] [assembly: AssemblyConfiguration("Release Mono")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+ae385750f52fbccfe5033b60d8113469399eff78")] [assembly: AssemblyProduct("SimpleHealthBar-Mono")] [assembly: AssemblyTitle("SimpleHealthBar-Mono")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace SimpleHealthBar { public static class BuildInfo { public const string Name = "SimpleHealthBar"; public const string Description = "Gives you a health bar above your inventory."; public const string Author = "iTidez"; public const string Version = "1.3.1"; public const string DownloadLink = "https://www.nexusmods.com/schedule1/mods/1106"; } public class SimpleHealthBar : MelonMod { [CompilerGenerated] private sealed class <FallbackInit>d__7 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public SimpleHealthBar <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <FallbackInit>d__7(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; ModLogger.Warn("Using fallback initialization - player detection may have failed"); <>2__current = Utils.WaitForSeconds(2f); <>1__state = 1; return true; case 1: <>1__state = -1; if ((Object)(object)Player.Local != (Object)null && (Object)(object)((Component)Player.Local).gameObject != (Object)null) { ModLogger.Info("Player found in fallback - initializing managers"); <>4__this.StartManagers(); } else { ModLogger.Error("Player still not found in fallback - initialization failed"); } 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 <Init>d__5 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public SimpleHealthBar <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <Init>d__5(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; ModLogger.Info("Starting initialization - waiting for player to spawn..."); Utils.LogPlayerState(); <>2__current = Utils.WaitForPlayerSpawned(Utils.ReturnNull()); <>1__state = 1; return true; case 1: <>1__state = -1; ModLogger.Info("Player detected - initializing health bar managers..."); PlayerHealthBarManager.Init(Logger); NPCHealthManager.Init(Logger); MultiplayerHandler.Init(Logger); ModLogger.Info("All health bar managers initialized successfully!"); 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 <SafetyTimer>d__4 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public SimpleHealthBar <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <SafetyTimer>d__4(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 = Utils.WaitForSeconds(10f); <>1__state = 1; return true; case 1: <>1__state = -1; if (!PlayerHealthBarManager.Initialized()) { ModLogger.Warn("Safety timer triggered - managers not initialized, attempting fallback"); ModLogger.Info("Current player state:"); Utils.LogPlayerState(); <>2__current = <>4__this.FallbackInit(); <>1__state = 2; return true; } ModLogger.Info("Safety timer: Managers already initialized successfully"); break; case 2: <>1__state = -1; 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(); } } private static Instance Logger; public override void OnInitializeMelon() { Logger = ((MelonBase)this).LoggerInstance; Preferences.Init(); ModLogger.SetDebugEnabled(Preferences.EnableDebugLogging.Value); ModLogger.Info("SimpleHealthBar initialized successfully"); } public override void OnSceneWasLoaded(int buildIndex, string sceneName) { if (sceneName == "Main") { ModLogger.Debug("Main scene loaded - starting initialization"); MelonCoroutines.Start(Init()); MelonCoroutines.Start(SafetyTimer()); } else if (sceneName == "Menu") { PlayerHealthBarManager.Unload(); NPCHealthManager.Unload(); MultiplayerHandler.Unload(); } } public override void OnUpdate() { PlayerHealthBarManager.OnUpdate(); NPCHealthManager.OnUpdate(); MultiplayerHandler.OnUpdate(); } [IteratorStateMachine(typeof(<SafetyTimer>d__4))] private IEnumerator SafetyTimer() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <SafetyTimer>d__4(0) { <>4__this = this }; } [IteratorStateMachine(typeof(<Init>d__5))] private IEnumerator Init() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <Init>d__5(0) { <>4__this = this }; } private void StartManagers() { PlayerHealthBarManager.Init(Logger); NPCHealthManager.Init(Logger); MultiplayerHandler.Init(Logger); } [IteratorStateMachine(typeof(<FallbackInit>d__7))] private IEnumerator FallbackInit() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <FallbackInit>d__7(0) { <>4__this = this }; } } public static class Preferences { public static MelonPreferences_Category Category; public static MelonPreferences_Entry<bool> FadeOutBar; public static MelonPreferences_Entry<bool> FadeHealthText; public static MelonPreferences_Entry<bool> ShowOnDamage; public static MelonPreferences_Category AnimationCategory; public static MelonPreferences_Entry<float> FadeDelay; public static MelonPreferences_Entry<float> FadeSpeed; public static MelonPreferences_Entry<float> FontSize; public static MelonPreferences_Category NPCHealthBar; public static MelonPreferences_Entry<bool> NPCHealthBarEnabled; public static MelonPreferences_Entry<bool> FadeOutNPCBar; public static MelonPreferences_Entry<float> NPCFadeOutDistance; public static MelonPreferences_Category DebugCategory; public static MelonPreferences_Entry<bool> EnableDebugLogging; public static void Init() { Category = MelonPreferences.CreateCategory("SimpleHealthBar_HealthBar", "Bar Settings"); AnimationCategory = MelonPreferences.CreateCategory("SimpleHealthBar_Animation", "Animation Settings"); DebugCategory = MelonPreferences.CreateCategory("SimpleHealthBar_Debug", "Debug Settings"); FadeOutBar = Category.CreateEntry<bool>("FadeOutBar", true, "Fade Out Health Bar", "Fades the health bar after a few seconds", false, false, (ValueValidator)null, (string)null); FadeHealthText = Category.CreateEntry<bool>("FadeOutHealthText", true, "Fade Out Health Text", "Fades out the text display showing your health", false, false, (ValueValidator)null, (string)null); ShowOnDamage = Category.CreateEntry<bool>("ShowOnDamage", true, "Show Health Bar on Damage", "Shows the health bar when you take damage", false, false, (ValueValidator)null, (string)null); FontSize = Category.CreateEntry<float>("FontSize", 14f, "Font Size", "Configures the font size of the text label HUD element", false, false, (ValueValidator)null, (string)null); FadeDelay = AnimationCategory.CreateEntry<float>("FadeDelay", 5f, "Fade Out Delay", "The amount of time in seconds it takes for the bar and text to disappear", false, false, (ValueValidator)null, (string)null); FadeSpeed = AnimationCategory.CreateEntry<float>("FadeSpeed", 2f, "Fade Speed", "Manages the speed of the fade transition", false, false, (ValueValidator)null, (string)null); NPCHealthBar = MelonPreferences.CreateCategory("SimpleHealthBar_NPCHealthBar", "NPC Health Bar"); NPCHealthBarEnabled = NPCHealthBar.CreateEntry<bool>("NPCBarEnabled", true, "NPC Health Bar Enabled", "Enables the health bar for the nearest NPC", false, false, (ValueValidator)null, (string)null); FadeOutNPCBar = NPCHealthBar.CreateEntry<bool>("FadeOutNPCBar", true, "Fade out NPC Health Bar", "Enables fading out the health bar for the nearest NPC", false, false, (ValueValidator)null, (string)null); NPCFadeOutDistance = NPCHealthBar.CreateEntry<float>("NPCFadeOutDistance", 100f, "Distance from Player to Fade Out Bar", "Sets the distance from the player the NPC health bar should fade out", false, false, (ValueValidator)null, (string)null); EnableDebugLogging = DebugCategory.CreateEntry<bool>("EnableDebugLogging", false, "Enable Debug Logging", "Enables detailed debug logging for troubleshooting", false, false, (ValueValidator)null, (string)null); } } } namespace SimpleHealthBar.UI { public class HealthBar : IDisposable { private GameObject HealthBarObject; private Slider HealthSlider; private Image FillImage; private RectTransform HealthTextDisplay; private TextMeshProUGUI HealthText; private Vector2 AnchorMin; private Vector2 AnchorMax; private Vector2 AnchoredPos; private float LastHealthUpdateTime; private float PauseAccumulated; private float PauseStartTime; private float CurrentFill; private float FadeSpeed = 2f; private float FadeDelay = 4f; private float FontSize = 12f; private bool LastPhoneOpened; private bool IsHidden; private bool IsSpawned; public HealthBarType BarType { get; private set; } public HealthBar(HealthBarType id, Transform interactionCanvas) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Expected O, but got Unknown //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Expected O, but got Unknown //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Expected O, but got Unknown //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_0245: Unknown result type (might be due to invalid IL or missing references) //IL_025c: Unknown result type (might be due to invalid IL or missing references) BarType = id; HealthBarObject = new GameObject(id.ToString() + "HealthBar"); HealthBarObject.transform.SetParent(interactionCanvas, false); RectTransform val = HealthBarObject.AddComponent<RectTransform>(); HealthSlider = HealthBarObject.AddComponent<Slider>(); val.sizeDelta = new Vector2(0f, 2f); HealthSlider.minValue = 0f; HealthSlider.maxValue = 100f; HealthSlider.value = 100f; GameObject val2 = new GameObject(id.ToString() + "HealthBarFill"); val2.transform.SetParent(((Component)val).transform, false); RectTransform val3 = val2.AddComponent<RectTransform>(); FillImage = val2.AddComponent<Image>(); ((Graphic)FillImage).color = Color.red; val3.anchorMin = Vector2.zero; val3.anchorMax = Vector2.one; val3.offsetMin = Vector2.zero; val3.offsetMax = Vector2.zero; HealthSlider.fillRect = val3; GameObject val4 = new GameObject(id.ToString() + "TextGroup"); val4.transform.SetParent(val2.transform, false); HealthTextDisplay = val4.AddComponent<RectTransform>(); HealthTextDisplay.anchorMin = new Vector2(0f, 1f); HealthTextDisplay.anchorMax = new Vector2(0f, 1f); HealthTextDisplay.pivot = new Vector2(0f, 1f); HealthTextDisplay.sizeDelta = new Vector2(400f, 20f); HealthText = val4.AddComponent<TextMeshProUGUI>(); ((TMP_Text)HealthText).alignment = (TextAlignmentOptions)513; ((TMP_Text)HealthText).fontSize = FontSize; SetupCustomDisplay(); Shadow val5 = val4.AddComponent<Shadow>(); val5.effectColor = Color.black; val5.effectDistance = new Vector2(1f, -1f); } public HealthBar(HealthBarType id, Transform interactionCanvas, Vector2 anchoredPos) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Expected O, but got Unknown //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Expected O, but got Unknown //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Expected O, but got Unknown //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_0235: Unknown result type (might be due to invalid IL or missing references) //IL_0236: Unknown result type (might be due to invalid IL or missing references) //IL_024c: Unknown result type (might be due to invalid IL or missing references) //IL_0263: Unknown result type (might be due to invalid IL or missing references) BarType = id; HealthBarObject = new GameObject(id.ToString() + "HealthBar"); HealthBarObject.transform.SetParent(interactionCanvas, false); RectTransform val = HealthBarObject.AddComponent<RectTransform>(); HealthSlider = HealthBarObject.AddComponent<Slider>(); val.sizeDelta = new Vector2(0f, 2f); HealthSlider.minValue = 0f; HealthSlider.maxValue = 100f; HealthSlider.value = 0f; GameObject val2 = new GameObject(id.ToString() + "HealthBarFill"); val2.transform.SetParent(((Component)val).transform, false); RectTransform val3 = val2.AddComponent<RectTransform>(); FillImage = val2.AddComponent<Image>(); ((Graphic)FillImage).color = Color.red; val3.anchorMin = Vector2.zero; val3.anchorMax = Vector2.one; val3.offsetMin = Vector2.zero; val3.offsetMax = Vector2.zero; HealthSlider.fillRect = val3; GameObject val4 = new GameObject(id.ToString() + "TextGroup"); val4.transform.SetParent(val2.transform, false); HealthTextDisplay = val4.AddComponent<RectTransform>(); HealthTextDisplay.anchorMin = new Vector2(0f, 1f); HealthTextDisplay.anchorMax = new Vector2(0f, 1f); HealthTextDisplay.pivot = new Vector2(0f, 1f); HealthTextDisplay.sizeDelta = new Vector2(400f, 20f); HealthText = val4.AddComponent<TextMeshProUGUI>(); ((TMP_Text)HealthText).alignment = (TextAlignmentOptions)513; ((TMP_Text)HealthText).fontSize = FontSize; AnchoredPos = anchoredPos; SetupCustomDisplay(); Shadow val5 = val4.AddComponent<Shadow>(); val5.effectColor = Color.black; val5.effectDistance = new Vector2(1f, -1f); } private void SetupCustomDisplay() { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: 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_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: 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) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: 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_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: 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_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0135: 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_014a: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) RectTransform component = HealthBarObject.GetComponent<RectTransform>(); switch (BarType) { case HealthBarType.Player: AnchorMin = new Vector2(0.235f, 0f); AnchorMax = new Vector2(0.775f, 0f); AnchoredPos = new Vector2(0f, 105f); HealthTextDisplay.anchoredPosition = new Vector2(500f, 20f); ModLogger.Debug("Player Healthbar created at " + ((object)(Vector2)(ref AnchoredPos)).ToString()); break; case HealthBarType.NPC: AnchorMin = new Vector2(0.3f, 0f); AnchorMax = new Vector2(0.7f, 0f); AnchoredPos = new Vector2(5f, 1000f); HealthTextDisplay.anchoredPosition = new Vector2(300f, 20f); ModLogger.Debug("NPC Healthbar created at " + ((object)(Vector2)(ref AnchoredPos)).ToString()); break; case HealthBarType.Multiplayer: AnchorMin = new Vector2(0.8f, 0f); AnchorMax = new Vector2(0.99f, 0f); ((TMP_Text)HealthText).fontSize = 10f; ModLogger.Debug("Multiplayer Healthbar created at " + ((object)(Vector2)(ref AnchoredPos)).ToString()); break; } component.anchorMin = AnchorMin; component.anchorMax = AnchorMax; component.anchoredPosition = AnchoredPos; } public void SetSpawned(bool isSpawned) { IsSpawned = isSpawned; } public bool GetSpawned() { return IsSpawned; } public void SetAnchoredPosition(Vector2 anchoredPosition) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000a: 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) AnchoredPos = anchoredPosition; AnchoredPos = anchoredPosition; RectTransform component = HealthBarObject.GetComponent<RectTransform>(); component.anchoredPosition = anchoredPosition; } public Vector2 GetAnchoredPosition() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return AnchoredPos; } public void SetCurrentHealth(float health) { CurrentFill = health; } public float GetCurrentHealth() { return CurrentFill; } public void Update() { bool flag = (Object)(object)FillImage != (Object)null; bool flag2 = (Object)(object)HealthText != (Object)null; if (flag && flag2) { HealthBarType barType = BarType; HealthBarType healthBarType = barType; if (healthBarType == HealthBarType.NPC) { UpdateNPC(); } } } public void Update(bool var) { switch (BarType) { case HealthBarType.Player: UpdatePlayer(var); break; case HealthBarType.Multiplayer: UpdateMultiplayer(var); break; } } private void UpdatePlayer(bool phoneOpen) { //IL_0051: 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_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) bool flag = (Object)(object)FillImage != (Object)null; bool flag2 = (Object)(object)HealthText != (Object)null; if (phoneOpen) { if (!LastPhoneOpened) { LastHealthUpdateTime = Time.time; } LastPhoneOpened = true; if (flag) { Color color = ((Graphic)FillImage).color; color.a = Mathf.Lerp(color.a, 1f, Time.deltaTime * 2f); ((Graphic)FillImage).color = color; } if (flag2) { ((TMP_Text)HealthText).alpha = Mathf.Lerp(((TMP_Text)HealthText).alpha, 1f, Time.deltaTime * 2f); } return; } if (LastPhoneOpened) { PauseAccumulated += Time.time - PauseStartTime; LastPhoneOpened = false; } float num = Time.time - LastHealthUpdateTime; float value = Mathf.Lerp(HealthSlider.value, CurrentFill, Time.deltaTime * FadeDelay); HealthSlider.value = value; float num2 = 1f; if (Preferences.FadeHealthText.Value) { num2 = (Preferences.ShowOnDamage.Value ? ((num > FadeDelay) ? 0f : 1f) : 0f); } bool value2 = Preferences.FadeOutBar.Value; if (flag) { Color color2 = ((Graphic)FillImage).color; color2.a = Mathf.Lerp(color2.a, num2, Time.deltaTime * FadeSpeed); if (!value2) { color2.a = 1f; } ((Graphic)FillImage).color = color2; } if (flag2) { if (!Preferences.FadeHealthText.Value) { ((TMP_Text)HealthText).alpha = 1f; } else { ((TMP_Text)HealthText).alpha = Mathf.Lerp(((TMP_Text)HealthText).alpha, num2, Time.deltaTime * FadeSpeed); } } } private void UpdateNPC() { //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: 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_00f4: Unknown result type (might be due to invalid IL or missing references) bool flag = (Object)(object)FillImage != (Object)null; bool flag2 = (Object)(object)HealthText != (Object)null; if (!(flag && flag2)) { return; } float value = Mathf.Lerp(HealthSlider.value, CurrentFill, Time.deltaTime * FadeDelay); HealthSlider.value = value; float num = Time.time - LastHealthUpdateTime; float num2 = 1f; if (Preferences.FadeHealthText.Value) { num2 = ((num > FadeDelay) ? 0f : 1f); } bool value2 = Preferences.FadeOutBar.Value; if (flag) { Color color = ((Graphic)FillImage).color; color.a = Mathf.Lerp(color.a, num2, Time.deltaTime * FadeSpeed); if (!value2) { color.a = 1f; } ((Graphic)FillImage).color = color; } if (flag2) { if (!Preferences.FadeHealthText.Value) { ((TMP_Text)HealthText).alpha = 1f; } else { ((TMP_Text)HealthText).alpha = Mathf.Lerp(((TMP_Text)HealthText).alpha, num2, Time.deltaTime * FadeSpeed); } } } private void UpdateMultiplayer(bool isSpawned) { //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) bool flag = (Object)(object)FillImage != (Object)null; bool flag2 = (Object)(object)HealthText != (Object)null; if (isSpawned) { float value = Mathf.Lerp(HealthSlider.value, CurrentFill, Time.deltaTime * FadeDelay); HealthSlider.value = value; bool value2 = Preferences.FadeOutBar.Value; if (flag) { Color color = ((Graphic)FillImage).color; color.a = 1f; ((Graphic)FillImage).color = Color.Lerp(((Graphic)FillImage).color, color, Time.deltaTime * FadeSpeed); } if (flag2) { ((TMP_Text)HealthText).alpha = Mathf.Lerp(((TMP_Text)HealthText).alpha, 1f, Time.deltaTime * FadeSpeed); } } else { Hide(); } } public void UpdateText() { CurrentFill = GetCurrentHealth(); string text = $"{Mathf.FloorToInt(GetCurrentHealth())} / 100 HP"; if (((TMP_Text)HealthText).text != text) { ((TMP_Text)HealthText).text = text; LastHealthUpdateTime = Time.time; } } public void UpdateText(string name) { CurrentFill = GetCurrentHealth(); string text = $"{name} - {Mathf.FloorToInt(GetCurrentHealth())} / 100 HP"; if (CurrentFill == 0f) { ((TMP_Text)HealthText).text = ""; } if (((TMP_Text)HealthText).text != text) { ((TMP_Text)HealthText).text = text; LastHealthUpdateTime = Time.time; } } public void Show() { switch (BarType) { case HealthBarType.Player: ShowPlayer(); break; case HealthBarType.NPC: ShowNPC(); break; case HealthBarType.Multiplayer: ShowMultiplayer(); break; } } public void Hide() { //IL_0027: 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_0045: 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_0057: Unknown result type (might be due to invalid IL or missing references) bool flag = (Object)(object)FillImage != (Object)null; bool flag2 = (Object)(object)HealthText != (Object)null; if (flag) { Color color = ((Graphic)FillImage).color; color.a = 0f; ((Graphic)FillImage).color = Color.Lerp(((Graphic)FillImage).color, color, Time.deltaTime * FadeSpeed); } if (flag2) { ((TMP_Text)HealthText).alpha = Mathf.Lerp(((TMP_Text)HealthText).alpha, 0f, Time.deltaTime * FadeSpeed); } IsHidden = true; } public void ShowPlayer() { //IL_0052: 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) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: 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 (!Preferences.FadeOutBar.Value) { LastHealthUpdateTime = Time.time; PauseAccumulated = 0f; bool flag = (Object)(object)FillImage != (Object)null; bool flag2 = (Object)(object)HealthText != (Object)null; if (flag) { Color color = ((Graphic)FillImage).color; color.a = 1f; ((Graphic)FillImage).color = Color.Lerp(((Graphic)FillImage).color, color, FadeSpeed); } if (flag2) { ((TMP_Text)HealthText).alpha = Mathf.Lerp(((TMP_Text)HealthText).alpha, 1f, FadeSpeed); } } } public void ShowNPC() { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: 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) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) if (Preferences.NPCHealthBarEnabled.Value) { LastHealthUpdateTime = Time.time; if ((Object)(object)FillImage != (Object)null) { Color color = ((Graphic)FillImage).color; color.a = 1f; ((Graphic)FillImage).color = Color.Lerp(((Graphic)FillImage).color, color, FadeSpeed); } if ((Object)(object)HealthText != (Object)null) { ((TMP_Text)HealthText).alpha = Mathf.Lerp(((TMP_Text)HealthText).alpha, 1f, FadeSpeed); } } } public void ShowMultiplayer() { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) if (!Preferences.FadeOutBar.Value) { LastHealthUpdateTime = Time.time; bool flag = (Object)(object)FillImage != (Object)null; bool flag2 = (Object)(object)HealthText != (Object)null; if (flag) { Color color = ((Graphic)FillImage).color; color.a = 1f; ((Graphic)FillImage).color = Color.Lerp(((Graphic)FillImage).color, color, FadeSpeed); } if (flag2) { ((TMP_Text)HealthText).alpha = Mathf.Lerp(((TMP_Text)HealthText).alpha, 1f, FadeSpeed); } } } public void Dispose() { throw new NotImplementedException(); } } public enum HealthBarType { Player, NPC, Multiplayer } } namespace SimpleHealthBar.Properties { [GeneratedCode("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] [DebuggerNonUserCode] [CompilerGenerated] internal class Resources { private static ResourceManager resourceMan; private static CultureInfo resourceCulture; [EditorBrowsable(EditorBrowsableState.Advanced)] internal static ResourceManager ResourceManager { get { if (resourceMan == null) { ResourceManager resourceManager = new ResourceManager("SimpleHealthBar.Properties.Resources", typeof(Resources).Assembly); resourceMan = resourceManager; } return resourceMan; } } [EditorBrowsable(EditorBrowsableState.Advanced)] internal static CultureInfo Culture { get { return resourceCulture; } set { resourceCulture = value; } } internal Resources() { } } } namespace SimpleHealthBar.PlayerUtils { internal class MultiplayerHandler { private static Dictionary<Player, HealthBar> MultiplayerHealthbars = new Dictionary<Player, HealthBar>(); private static bool HasInitialized = false; private static bool IsMultiplayer = false; public static void Init(Instance logger) { foreach (Player player in Player.PlayerList) { if (!((Object)(object)player == (Object)null) && !player.IsLocalPlayer) { HealthBar healthBar = CreatePlayerHealthbar(player); if (healthBar == null) { ModLogger.Error("Failed to create healthbar for player: " + ((Object)player).name); } } } HasInitialized = true; ModLogger.Info("Player Healthbar Initialized!"); } private static HealthBar CreatePlayerHealthbar(Player player) { //IL_005d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null || MultiplayerHealthbars.ContainsKey(player)) { return null; } float num = ((MultiplayerHealthbars.Count > 0) ? ((float)MultiplayerHealthbars.Count * 25f) : 0f) + 105f; HealthBar healthBar = new HealthBar(HealthBarType.Multiplayer, ((Component)Singleton<HUD>.instance).transform, new Vector2(0f, num)); if (healthBar != null) { MultiplayerHealthbars.Add(player, healthBar); } ModLogger.Debug("Creating healthbar for player: " + ((Object)player).name); return healthBar; } public static void OnUpdate() { //IL_0128: Unknown result type (might be due to invalid IL or missing references) if (!HasInitialized || !IsMultiplayerMode()) { return; } CheckCreate(); foreach (Player player in Player.PlayerList) { if (!((Object)(object)player != (Object)null) || player.IsLocalPlayer) { continue; } if (MultiplayerHealthbars.ContainsKey(player)) { HealthBar healthBar = MultiplayerHealthbars[player]; if (healthBar.GetCurrentHealth() != player.Health.CurrentHealth && ((NetworkBehaviour)player).IsSpawned) { healthBar.SetCurrentHealth(player.Health.CurrentHealth); healthBar.UpdateText(((Object)player).name ?? ""); healthBar.Show(); } healthBar.Update(((NetworkBehaviour)player).IsSpawned); } else { float num = ((MultiplayerHealthbars.Count > 0) ? ((float)MultiplayerHealthbars.Count * 25f) : 0f) + 105f; HealthBar healthBar2 = new HealthBar(HealthBarType.Multiplayer, ((Component)Singleton<HUD>.instance).transform, new Vector2(0f, num)); MultiplayerHealthbars.Add(player, healthBar2); healthBar2.SetCurrentHealth(player.Health.CurrentHealth); healthBar2.UpdateText(((Object)player).name ?? ""); healthBar2.Show(); healthBar2.Update(((NetworkBehaviour)player).IsSpawned); } } } public static void CheckCreate() { UpdateLocation(); foreach (Player player in Player.PlayerList) { if ((Object)(object)player == (Object)null || player.IsLocalPlayer) { continue; } if (MultiplayerHealthbars.ContainsKey(player) && ((NetworkBehaviour)player).IsOffline) { MultiplayerHealthbars[player].Dispose(); MultiplayerHealthbars.Remove(player); } if (!MultiplayerHealthbars.ContainsKey(player) && ((NetworkBehaviour)player).IsSpawned) { HealthBar healthBar = CreatePlayerHealthbar(player); if (healthBar != null) { MultiplayerHealthbars.Add(player, healthBar); healthBar.SetCurrentHealth(player.Health.CurrentHealth); healthBar.UpdateText(((Object)player).name ?? ""); healthBar.Show(); } else { ModLogger.Error("Failed to create healthbar for player: " + ((Object)player).name); } } } } public static void UpdateLocation() { //IL_0050: Unknown result type (might be due to invalid IL or missing references) if (!HasInitialized) { return; } int num = 0; foreach (HealthBar value in MultiplayerHealthbars.Values) { if (value != null) { float num2 = (float)num * 25f + 105f; value.SetAnchoredPosition(new Vector2(0f, num2)); num++; } } } public static bool IsMultiplayerMode() { if (HasInitialized) { IsMultiplayer = Player.PlayerList.Count > 1; } return IsMultiplayer; } public static void Unload() { HasInitialized = false; MultiplayerHealthbars.Clear(); } public static bool Initialized() { return HasInitialized; } } internal class PlayerHealthBarManager { private static Player LocalPlayer; private static HealthBar HealthBar; private static bool HasInitialized; public static void Init(Instance logger) { ModLogger.Info("Initializing Player Health Bar"); LocalPlayer = Player.Local; HealthBar = new HealthBar(HealthBarType.Player, ((Component)Singleton<HUD>.instance).transform); HasInitialized = true; ModLogger.Info("Player Healthbar Initialized!"); } public static void OnUpdate() { if (!HasInitialized) { return; } Phone instance = PlayerSingleton<Phone>.Instance; bool var = (Object)(object)instance != (Object)null && instance.IsOpen; if (HealthBar != null && (Object)(object)LocalPlayer != (Object)null) { float currentHealth = LocalPlayer.Health.CurrentHealth; float currentHealth2 = HealthBar.GetCurrentHealth(); if (currentHealth != currentHealth2) { ModLogger.Debug($"Health changed from {currentHealth2} to {currentHealth}"); HealthBar.SetCurrentHealth(currentHealth); HealthBar.UpdateText(); HealthBar.Show(); } HealthBar.Update(var); } } public static void Unload() { HasInitialized = false; HealthBar = null; } public static bool Initialized() { return HasInitialized; } } [HarmonyPatch(typeof(Player))] internal class Player_FixedUpdate { [HarmonyPatch("FixedUpdate")] [HarmonyPrefix] private static void FixedUpdate(Player __instance) { NPCHealthManager.OnUpdate(); PlayerHealthBarManager.OnUpdate(); MultiplayerHandler.OnUpdate(); } } } namespace SimpleHealthBar.NPCUtils { public static class NPCHealthManager { private static NPCManager NPCManager; private static HealthBar HealthBar; private static NPC CurrentNPC; private static bool IsInitialized = false; private static bool IsOutOfSight = true; public static void Init(Instance logger) { IsInitialized = NetworkSingleton<NPCManager>.InstanceExists; if (IsInitialized) { NPCManager = NetworkSingleton<NPCManager>.Instance; HealthBar = new HealthBar(HealthBarType.NPC, ((Component)Singleton<HUD>.instance).transform); ModLogger.Info("NPC Healthbar Initialized!"); } else { ModLogger.Error("NPCManager not found, aborting NPC health reporting!"); } } public static void OnNPCSelected(NPC npc) { if (IsInitialized && (Object)(object)npc != (Object)null && HealthBar != null) { if ((Object)(object)CurrentNPC != (Object)(object)npc) { CurrentNPC = npc; HealthBar.UpdateText(npc.fullName); HealthBar.Show(); } else if (HealthBar.GetCurrentHealth() != npc.Health.Health) { HealthBar.UpdateText(npc.fullName); HealthBar.Show(); } } } private static float GetDistanceFromPlayer() { //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_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: 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) if ((Object)(object)CurrentNPC == (Object)null || (Object)(object)Player.Local == (Object)null) { return float.MaxValue; } Vector3 position = ((Component)CurrentNPC).transform.position; Vector3 val = position - Player.Local.CameraPosition; return ((Vector3)(ref val)).sqrMagnitude; } private static bool CheckDistanceFromPlayer() { bool flag = GetDistanceFromPlayer() < Preferences.NPCFadeOutDistance.Value; if (!flag && !IsOutOfSight) { IsOutOfSight = true; } else if (flag && IsOutOfSight) { IsOutOfSight = false; } return flag; } private static bool CheckDistanceChanged() { if (GetDistanceFromPlayer() < Preferences.NPCFadeOutDistance.Value && IsOutOfSight) { return true; } return false; } public static NPC GetClosestNPC() { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) NPC result = null; float num = float.MaxValue; foreach (NPC item in NPCManager.NPCRegistry) { if ((Object)(object)item == (Object)null) { continue; } Vector3 position = ((Component)item).transform.position; if ((Object)(object)Player.Local != (Object)null) { Vector3 val = position - Player.Local.CameraPosition; float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude; if (sqrMagnitude < num) { num = sqrMagnitude; result = item; } } } return result; } public static void OnUpdate() { if (!IsInitialized) { return; } NPC closestNPC = GetClosestNPC(); if ((Object)(object)closestNPC != (Object)null && (Object)(object)CurrentNPC != (Object)(object)closestNPC) { CurrentNPC = closestNPC; float health = CurrentNPC.Health.Health; ModLogger.Debug($"NPC changed to {closestNPC.fullName} with health {health}"); HealthBar.SetCurrentHealth(health); HealthBar.UpdateText(closestNPC.fullName); HealthBar.Show(); } else if ((Object)(object)CurrentNPC != (Object)null) { float health2 = CurrentNPC.Health.Health; float currentHealth = HealthBar.GetCurrentHealth(); if (currentHealth != health2) { ModLogger.Debug($"NPC health changed from {currentHealth} to {health2}"); HealthBar.SetCurrentHealth(health2); HealthBar.UpdateText(CurrentNPC.fullName); HealthBar.Show(); } } if (HealthBar != null) { HealthBar.Update(); } } public static void Unload() { IsInitialized = false; HealthBar = null; } public static bool Initialized() { return IsInitialized; } } } namespace SimpleHealthBar.Helpers { public static class MelonLoggerExtensions { private static string GetLoggerName(Instance logger) { return typeof(Instance).GetField("Name", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(logger) as string; } private static void InvokeNativeMsg(Color namesectionColor, Color textColor, string nameSection, string message) { typeof(MelonLogger).GetMethod("NativeMsg", BindingFlags.Static | BindingFlags.NonPublic)?.Invoke(null, new object[5] { namesectionColor, textColor, nameSection, message ?? "null", false }); } private static string GetCallerInfo() { StackTrace stackTrace = new StackTrace(); for (int i = 2; i < stackTrace.FrameCount; i++) { StackFrame frame = stackTrace.GetFrame(i); MethodBase method = frame.GetMethod(); if (!(method?.DeclaringType == null)) { return method.DeclaringType.FullName + "." + method.Name; } } return "unknown"; } } public static class ModLogger { private static Instance Logger = new Instance("SimpleHealthBar-ModLogger"); private static bool IsDebugEnabled = false; public static void SetDebugEnabled(bool enabled) { IsDebugEnabled = enabled; } public static void Debug(string message) { if (IsDebugEnabled) { Logger.Msg("[DEBUG] " + message); } } public static void Error(string message) { Logger.Error(message); } public static void Warn(string message) { Logger.Warning(message); } public static void Info(string message) { Logger.Msg(message); } } public static class Il2CppListExtensions { public static IEnumerable<T> AsEnumerable<T>(this List<T> list) { return list ?? new List<T>(); } } public static class Utils { [CompilerGenerated] private sealed class <ReturnNull>d__9 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <ReturnNull>d__9(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; 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 <WaitForNetwork>d__7 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public IEnumerator routine; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <WaitForNetwork>d__7(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; break; case 1: <>1__state = -1; break; } if (!InstanceFinder.IsServer && !InstanceFinder.IsClient) { <>2__current = null; <>1__state = 1; return true; } MelonCoroutines.Start(routine); 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 <WaitForNetworkSingleton>d__11<T> : IEnumerator<object>, IEnumerator, IDisposable where T : notnull, NetworkSingleton<T> { private int <>1__state; private object <>2__current; public IEnumerator coroutine; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <WaitForNetworkSingleton>d__11(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; goto IL_0044; case 1: <>1__state = -1; goto IL_0044; case 2: { <>1__state = -1; return false; } IL_0044: if (!NetworkSingleton<T>.InstanceExists) { <>2__current = null; <>1__state = 1; return true; } <>2__current = coroutine; <>1__state = 2; return true; } } 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 <WaitForNotNull>d__8 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public object obj; public float timeout; public Action onTimeout; public Action onFinish; private float <startTime>5__1; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <WaitForNotNull>d__8(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; <startTime>5__1 = Time.time; break; case 1: <>1__state = -1; break; } if (obj == null) { if (!float.IsNaN(timeout) && Time.time - <startTime>5__1 > timeout) { onTimeout?.Invoke(); return false; } <>2__current = null; <>1__state = 1; return true; } onFinish?.Invoke(); 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 <WaitForPlayer>d__4 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public IEnumerator routine; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <WaitForPlayer>d__4(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; break; case 1: <>1__state = -1; break; } if ((Object)(object)Player.Local == (Object)null || (Object)(object)((Component)Player.Local).gameObject == (Object)null) { <>2__current = null; <>1__state = 1; return true; } MelonCoroutines.Start(routine); 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 <WaitForPlayerSpawned>d__5 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public IEnumerator routine; private float <startTime>5__1; private float <timeout>5__2; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <WaitForPlayerSpawned>d__5(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; <startTime>5__1 = Time.time; <timeout>5__2 = 30f; ModLogger.Info("WaitForPlayerSpawned started - waiting for player to be fully spawned..."); break; case 1: <>1__state = -1; break; } if (Time.time - <startTime>5__1 < <timeout>5__2) { if ((Object)(object)Player.Local != (Object)null && (Object)(object)((Component)Player.Local).gameObject != (Object)null) { if (((Component)Player.Local).gameObject.activeInHierarchy && (Object)(object)Player.Local.Health != (Object)null) { ModLogger.Info("Player fully spawned on Mono - starting initialization"); goto IL_0196; } if ((Object)(object)((Component)Player.Local).gameObject == (Object)null) { ModLogger.Info("Player.Local.gameObject is null"); } else if (!((Component)Player.Local).gameObject.activeInHierarchy) { ModLogger.Info("Player.Local.gameObject is not active"); } else if ((Object)(object)Player.Local.Health == (Object)null) { ModLogger.Info("Player.Local.Health is null"); } } else if ((Object)(object)Player.Local == (Object)null) { ModLogger.Info("Player.Local is null"); } else if ((Object)(object)((Component)Player.Local).gameObject == (Object)null) { ModLogger.Info("Player.Local.gameObject is null"); } <>2__current = WaitForSeconds(0.1f); <>1__state = 1; return true; } goto IL_0196; IL_0196: if (Time.time - <startTime>5__1 >= <timeout>5__2) { ModLogger.Warn("Timeout waiting for player to spawn - proceeding anyway"); } MelonCoroutines.Start(routine); 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 <WaitForSeconds>d__10 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public float seconds; private float <startTime>5__1; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <WaitForSeconds>d__10(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; <startTime>5__1 = Time.time; break; case 1: <>1__state = -1; break; } if (Time.time - <startTime>5__1 < seconds) { <>2__current = null; <>1__state = 1; return true; } 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(); } } public static T FindObjectByName<T>(string objectName) where T : Object { try { T[] array = Resources.FindObjectsOfTypeAll<T>(); foreach (T val in array) { if (!(((Object)val).name != objectName)) { return val; } } return default(T); } catch (Exception ex) { ModLogger.Error("Error finding " + typeof(T).Name + " '" + objectName + "': " + ex.Message); return default(T); } } public static List<T> GetAllComponentsInChildrenRecursive<T>(GameObject obj) where T : Component { List<T> list = new List<T>(); if ((Object)(object)obj == (Object)null) { return list; } T[] components = obj.GetComponents<T>(); if (components.Length != 0) { list.AddRange(components); } for (int i = 0; i < obj.transform.childCount; i++) { Transform child = obj.transform.GetChild(i); list.AddRange(GetAllComponentsInChildrenRecursive<T>(((Component)child).gameObject)); } return list; } public static bool Is<T>(object obj, out T result) where T : class { if (obj is T val) { result = val; return true; } result = null; return false; } public static List<StorableItemDefinition> GetAllStorableItemDefinitions() { List<ItemRegister> list = Singleton<Registry>.Instance.ItemRegistry.ToList(); List<StorableItemDefinition> list2 = new List<StorableItemDefinition>(); foreach (ItemRegister item in list) { if (Is<StorableItemDefinition>(item.Definition, out var result)) { list2.Add(result); } else { ModLogger.Warn("Definition " + ((object)item.Definition)?.GetType().FullName + " is not a StorableItemDefinition"); } } return list2.ToList(); } [IteratorStateMachine(typeof(<WaitForPlayer>d__4))] public static IEnumerator WaitForPlayer(IEnumerator routine) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <WaitForPlayer>d__4(0) { routine = routine }; } [IteratorStateMachine(typeof(<WaitForPlayerSpawned>d__5))] public static IEnumerator WaitForPlayerSpawned(IEnumerator routine) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <WaitForPlayerSpawned>d__5(0) { routine = routine }; } public static void LogPlayerState() { try { if ((Object)(object)Player.Local == (Object)null) { ModLogger.Debug("Player.Local is null"); return; } ModLogger.Info("Player.Local found: " + ((object)Player.Local).GetType().FullName); if ((Object)(object)((Component)Player.Local).gameObject == (Object)null) { ModLogger.Debug("Player.Local.gameObject is null"); return; } ModLogger.Info($"Player.Local.gameObject: {((Object)((Component)Player.Local).gameObject).name} (Active: {((Component)Player.Local).gameObject.activeInHierarchy})"); if ((Object)(object)Player.Local.Health == (Object)null) { ModLogger.Debug("Player.Local.Health is null"); } else { ModLogger.Info("Player.Local.Health: " + ((object)Player.Local.Health).GetType().FullName); } } catch (Exception ex) { ModLogger.Error("Error logging player state: " + ex.Message); } } [IteratorStateMachine(typeof(<WaitForNetwork>d__7))] public static IEnumerator WaitForNetwork(IEnumerator routine) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <WaitForNetwork>d__7(0) { routine = routine }; } [IteratorStateMachine(typeof(<WaitForNotNull>d__8))] public static IEnumerator WaitForNotNull(object? obj, float timeout = float.NaN, Action onTimeout = null, Action onFinish = null) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <WaitForNotNull>d__8(0) { obj = obj, timeout = timeout, onTimeout = onTimeout, onFinish = onFinish }; } [IteratorStateMachine(typeof(<ReturnNull>d__9))] public static IEnumerator ReturnNull() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <ReturnNull>d__9(0); } [IteratorStateMachine(typeof(<WaitForSeconds>d__10))] public static IEnumerator WaitForSeconds(float seconds) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <WaitForSeconds>d__10(0) { seconds = seconds }; } [IteratorStateMachine(typeof(<WaitForNetworkSingleton>d__11<>))] public static IEnumerator WaitForNetworkSingleton<T>(IEnumerator coroutine) where T : NetworkSingleton<T> { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <WaitForNetworkSingleton>d__11<T>(0) { coroutine = coroutine }; } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }