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 HealthPulse v0.1.0
HealthPulse.dll
Decompiled 3 days agousing System; using System.Reflection; using System.Runtime.CompilerServices; using BepInEx; using BepInEx.Configuration; using UnityEngine; using UnityEngine.Audio; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: AssemblyVersion("0.0.0.0")] namespace HealthPulse; [BepInPlugin("j1ga.healthpulse", "HealthPulse", "0.1.0")] public class HealthPulsePlugin : BaseUnityPlugin { public const string Guid = "j1ga.healthpulse"; public const string Name = "HealthPulse"; public const string Version = "0.1.0"; private const string SecGeneral = "01 General"; private const string SecLook = "02 Look"; private const string SecHit = "03 Hit flash"; private const string SecSound = "04 Heartbeat sound"; private const int ConfigVersion = 2; private ConfigEntry<bool> _enabled; private ConfigEntry<float> _threshold; private ConfigEntry<bool> _hideWithHud; private ConfigEntry<float> _maxAlpha; private ConfigEntry<Color> _color; private ConfigEntry<float> _width; private ConfigEntry<float> _bpmMin; private ConfigEntry<float> _bpmMax; private ConfigEntry<bool> _hitFlash; private ConfigEntry<float> _hitStrength; private ConfigEntry<bool> _sound; private ConfigEntry<float> _soundThreshold; private ConfigEntry<float> _soundVolume; private ConfigEntry<int> _configVersion; private Image _image; private GameObject _root; private Texture2D _tex; private Sprite _sprite; private float _texWidth = -1f; private Hud _hud; private AudioSource _audio; private AudioClip _beat; private bool _soundLogged; private float _phase; private float _shown; private float _flash; private float _lastHealth = -1f; private void Awake() { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Expected O, but got Unknown //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Expected O, but got Unknown //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Expected O, but got Unknown //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Expected O, but got Unknown //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Expected O, but got Unknown //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_0211: Expected O, but got Unknown //IL_0267: Unknown result type (might be due to invalid IL or missing references) //IL_0271: Expected O, but got Unknown //IL_02a6: Unknown result type (might be due to invalid IL or missing references) //IL_02b0: Expected O, but got Unknown _enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("01 General", "Enabled", true, "Show the low-health vignette."); _threshold = ((BaseUnityPlugin)this).Config.Bind<float>("01 General", "Threshold", 35f, new ConfigDescription("Health, in percent of the maximum, below which the edges start to glow. The lower the health, the stronger and faster.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 90f), new object[0])); _hideWithHud = ((BaseUnityPlugin)this).Config.Bind<bool>("01 General", "HideWithHud", false, "Hide the vignette too when the HUD is hidden (Ctrl+F3). Off: it stays, as a warning."); _maxAlpha = ((BaseUnityPlugin)this).Config.Bind<float>("02 Look", "MaxStrength", 0.75f, new ConfigDescription("How opaque the edges get at the lowest health (0..1).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 1f), new object[0])); _color = ((BaseUnityPlugin)this).Config.Bind<Color>("02 Look", "Color", new Color(0.75f, 0f, 0f, 1f), "Colour of the vignette."); _width = ((BaseUnityPlugin)this).Config.Bind<float>("02 Look", "Width", 0.45f, new ConfigDescription("How far the glow reaches in from the edges (0.2 a thin frame .. 0.8 most of the screen).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.2f, 0.8f), new object[0])); _bpmMin = ((BaseUnityPlugin)this).Config.Bind<float>("02 Look", "BeatsPerMinuteAtThreshold", 45f, new ConfigDescription("Heart rate of the pulse just below the threshold.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(30f, 200f), new object[0])); _bpmMax = ((BaseUnityPlugin)this).Config.Bind<float>("02 Look", "BeatsPerMinuteAtZero", 80f, new ConfigDescription("Heart rate of the pulse near zero health.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(30f, 220f), new object[0])); _hitFlash = ((BaseUnityPlugin)this).Config.Bind<bool>("03 Hit flash", "Enabled", true, "Flash the edges when you take a hit; the lower the health, the stronger."); _hitStrength = ((BaseUnityPlugin)this).Config.Bind<float>("03 Hit flash", "Strength", 1f, new ConfigDescription("How strong the flash is.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 2f), new object[0])); _sound = ((BaseUnityPlugin)this).Config.Bind<bool>("04 Heartbeat sound", "Enabled", false, "Play a heartbeat with the pulse when health is very low."); _soundThreshold = ((BaseUnityPlugin)this).Config.Bind<float>("04 Heartbeat sound", "Threshold", 15f, new ConfigDescription("Health, in percent, below which the heartbeat is heard.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 90f), new object[0])); _soundVolume = ((BaseUnityPlugin)this).Config.Bind<float>("04 Heartbeat sound", "Volume", 0.8f, new ConfigDescription("Volume of the heartbeat (the game's sound volume applies on top).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), new object[0])); _configVersion = ((BaseUnityPlugin)this).Config.Bind<int>("99 Internal", "ConfigVersion", 0, "Used by the mod to update old defaults once. Do not change."); MigrateConfig(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"HealthPulse 0.1.0 loaded. No Harmony patches are applied."); } private void MigrateConfig() { if (_configVersion.Value < 2) { if (Mathf.Approximately(_bpmMin.Value, 60f)) { _bpmMin.Value = 45f; } if (Mathf.Approximately(_bpmMax.Value, 120f)) { _bpmMax.Value = 80f; } if (Mathf.Approximately(_soundVolume.Value, 0.6f)) { _soundVolume.Value = 0.8f; } _configVersion.Value = 2; } } private void OnDestroy() { if ((Object)(object)_root != (Object)null) { Object.Destroy((Object)(object)_root); } if ((Object)(object)_sprite != (Object)null) { Object.Destroy((Object)(object)_sprite); } if ((Object)(object)_tex != (Object)null) { Object.Destroy((Object)(object)_tex); } if ((Object)(object)_beat != (Object)null) { Object.Destroy((Object)(object)_beat); } } private void Update() { try { Tick(); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("Update failed, the vignette is off for the session: " + ex)); ((Behaviour)this).enabled = false; if ((Object)(object)_image != (Object)null) { ((Behaviour)_image).enabled = false; } } } private void Tick() { //IL_0351: Unknown result type (might be due to invalid IL or missing references) //IL_0356: Unknown result type (might be due to invalid IL or missing references) //IL_0367: Unknown result type (might be due to invalid IL or missing references) Hud instance = Hud.instance; if ((Object)(object)instance == (Object)null) { _hud = null; _image = null; return; } if ((Object)(object)instance != (Object)(object)_hud || (Object)(object)_image == (Object)null) { Attach(instance); } if ((Object)(object)_image == (Object)null) { return; } if (!Mathf.Approximately(_texWidth, _width.Value)) { MakeTexture(); } float unscaledDeltaTime = Time.unscaledDeltaTime; Player localPlayer = Player.m_localPlayer; bool flag = _enabled.Value && (Object)(object)localPlayer != (Object)null && !((Character)localPlayer).IsDead() && !((Character)localPlayer).IsTeleporting() && !localPlayer.IsSleeping() && (!_hideWithHud.Value || !instance.m_userHidden); float num = (((Object)(object)localPlayer != (Object)null) ? ((Character)localPlayer).GetMaxHealth() : 0f); float num2 = (((Object)(object)localPlayer != (Object)null && num > 0f) ? Mathf.Clamp01(((Character)localPlayer).GetHealth() / num) : 1f); float num3 = _threshold.Value / 100f; float num4 = (flag ? Mathf.Clamp01((num3 - num2) / num3) : 0f); bool flag2 = flag && num2 < num3; float num5 = Mathf.Lerp(_bpmMin.Value, _bpmMax.Value, num4); float phase = _phase; _phase += unscaledDeltaTime * num5 / 60f; if (_phase >= 1f) { _phase -= Mathf.Floor(_phase); } bool flag3 = _phase >= 0.02f && (phase < 0.02f || phase > _phase); float num6 = Mathf.Max(Bump(_phase, 0.08f), 0.55f * Bump(_phase, 0.38f)); if (flag && _lastHealth >= 0f && (Object)(object)localPlayer != (Object)null) { float num7 = (_lastHealth - ((Character)localPlayer).GetHealth()) / Mathf.Max(1f, num); if (_hitFlash.Value && num7 > 0.005f) { float num8 = Mathf.Clamp01((num3 * 1.5f - num2) / (num3 * 1.5f)); _flash = Mathf.Min(1f, _flash + (0.35f + num7 * 3f) * num8 * _hitStrength.Value); } } _lastHealth = ((flag && (Object)(object)localPlayer != (Object)null) ? ((Character)localPlayer).GetHealth() : (-1f)); _flash = Mathf.MoveTowards(_flash, 0f, unscaledDeltaTime / 0.45f); float num9 = (flag2 ? ((0.3f + 0.7f * num4) * (0.72f + 0.28f * num6)) : 0f); _shown = Mathf.Lerp(_shown, num9, 1f - Mathf.Exp((0f - unscaledDeltaTime) / 0.12f)); float num10 = Mathf.Clamp01(Mathf.Max(_shown, _flash) * _maxAlpha.Value); Color value = _color.Value; value.a = num10; ((Graphic)_image).color = value; ((Behaviour)_image).enabled = num10 > 0.003f; if (flag3 && _sound.Value && flag && num2 < _soundThreshold.Value / 100f) { PlayBeat(num2); } } private static float Bump(float x, float c) { float num = x - c; if (num > 0.5f) { num -= 1f; } else if (num < -0.5f) { num += 1f; } num /= 0.15f; return Mathf.Exp((0f - num) * num); } private void Attach(Hud hud) { //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Expected O, but got Unknown //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Expected O, but got Unknown //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) _hud = hud; _image = null; if ((Object)(object)_root != (Object)null) { Object.Destroy((Object)(object)_root); } Canvas val = (((Object)(object)hud.m_rootObject != (Object)null) ? hud.m_rootObject.GetComponentInParent<Canvas>() : null); Canvas val2 = (((Object)(object)val != (Object)null) ? val.rootCanvas : null); if ((Object)(object)val2 == (Object)null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"The HUD's canvas was not found; no vignette."); return; } _root = new GameObject("HealthPulse", new Type[1] { typeof(RectTransform) }); _root.layer = ((Component)val2).gameObject.layer; RectTransform val3 = (RectTransform)_root.transform; ((Transform)val3).SetParent(((Component)val2).transform, false); ((Transform)val3).SetAsFirstSibling(); val3.anchorMin = Vector2.zero; val3.anchorMax = Vector2.one; val3.offsetMin = Vector2.zero; val3.offsetMax = Vector2.zero; Canvas val4 = _root.AddComponent<Canvas>(); val4.overrideSorting = true; val4.sortingLayerID = val2.sortingLayerID; val4.sortingOrder = val2.sortingOrder - 1; _image = _root.AddComponent<Image>(); ((Graphic)_image).raycastTarget = false; ((Behaviour)_image).enabled = false; _texWidth = -1f; MakeTexture(); _shown = 0f; _flash = 0f; _lastHealth = -1f; } private void MakeTexture() { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) _texWidth = _width.Value; if ((Object)(object)_tex == (Object)null) { _tex = new Texture2D(256, 256, (TextureFormat)4, false); ((Texture)_tex).wrapMode = (TextureWrapMode)1; ((Texture)_tex).filterMode = (FilterMode)1; } float num = Mathf.Clamp(1f - _texWidth, 0.15f, 0.85f); Color32[] array = (Color32[])(object)new Color32[65536]; for (int i = 0; i < 256; i++) { for (int j = 0; j < 256; j++) { float num2 = ((float)j + 0.5f) / 256f * 2f - 1f; float num3 = ((float)i + 0.5f) / 256f * 2f - 1f; float num4 = Mathf.Pow(Mathf.Pow(Mathf.Abs(num2), 3f) + Mathf.Pow(Mathf.Abs(num3), 3f), 1f / 3f); float num5 = Mathf.Clamp01((num4 - num) / (1.05f - num)); num5 = num5 * num5 * (3f - 2f * num5); ref Color32 reference = ref array[i * 256 + j]; reference = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, (byte)Mathf.RoundToInt(num5 * 255f)); } } _tex.SetPixels32(array); _tex.Apply(false); if ((Object)(object)_sprite == (Object)null) { _sprite = Sprite.Create(_tex, new Rect(0f, 0f, 256f, 256f), new Vector2(0.5f, 0.5f)); } if ((Object)(object)_image != (Object)null) { _image.sprite = _sprite; } } private void PlayBeat(float hp) { if ((Object)(object)_audio == (Object)null) { _audio = ((Component)this).gameObject.AddComponent<AudioSource>(); _audio.playOnAwake = false; _audio.spatialBlend = 0f; AudioMixerGroup val = SfxGroup(); if ((Object)(object)val != (Object)null) { _audio.outputAudioMixerGroup = val; } } if ((Object)(object)_beat == (Object)null) { _beat = MakeBeat(); } _audio.pitch = Mathf.Lerp(1.08f, 0.96f, Mathf.Clamp01(hp / Mathf.Max(0.01f, _soundThreshold.Value / 100f))); _audio.PlayOneShot(_beat, _soundVolume.Value); if (!_soundLogged) { _soundLogged = true; ((BaseUnityPlugin)this).Logger.LogInfo((object)("Heartbeat sound playing (mixer group: " + (((Object)(object)_audio.outputAudioMixerGroup != (Object)null) ? ((Object)_audio.outputAudioMixerGroup).name : "none") + ").")); } } private static AudioMixerGroup SfxGroup() { AudioMan instance = AudioMan.instance; if ((Object)(object)instance == (Object)null) { return null; } if ((Object)(object)instance.m_masterMixer != (Object)null) { AudioMixerGroup[] array = instance.m_masterMixer.FindMatchingGroups("SFX"); if (array != null && array.Length > 0) { return array[0]; } } return instance.m_guiMixer; } private static AudioClip MakeBeat() { int num = 24255; float[] array = new float[num]; Thump(array, 44100, 0f, 1f); Thump(array, 44100, 0.2f, 0.65f); float num2 = 0f; for (int i = 0; i < num; i++) { num2 = Mathf.Max(num2, Mathf.Abs(array[i])); } if (num2 > 0.95f) { for (int j = 0; j < num; j++) { array[j] *= 0.95f / num2; } } AudioClip val = AudioClip.Create("HealthPulseBeat", num, 1, 44100, false); val.SetData(array, 0); return val; } private static void Thump(float[] s, int rate, float at, float gain) { int num = (int)(at * (float)rate); int num2 = (int)(0.25f * (float)rate); double num3 = 0.0; Random random = new Random(7); float num4 = 0f; for (int i = 0; i < num2 && num + i < s.Length; i++) { float num5 = (float)i / (float)rate; float num6 = Mathf.Lerp(110f, 60f, Mathf.Clamp01(num5 / 0.09f)); num3 += Math.PI * 2.0 * (double)num6 / (double)rate; float num7 = Mathf.Clamp01(num5 / 0.004f) * Mathf.Exp((0f - num5) / 0.07f); float num8 = (float)(Math.Sin(num3) + 0.5 * Math.Sin(2.0 * num3) + 0.22 * Math.Sin(3.0 * num3)); num4 += ((float)random.NextDouble() * 2f - 1f - num4) * 0.08f; float num9 = num4 * 2.5f * Mathf.Exp((0f - num5) / 0.012f); s[num + i] += (num8 * num7 + num9) * gain * 0.55f; } } }