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 CorruptedHealth v1.1.0
CorruptedHealth.dll
Decompiled 3 months agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using HutongGames.PlayMaker; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.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 CorruptedHealth { [BepInPlugin("lagerthon.CorruptedHealth", "CorruptedHealth", "1.1.0")] public class CorruptedHealth : BaseUnityPlugin { public class CachedAudio { public AudioSource source; public AudioLowPassFilter lowPass; } [CompilerGenerated] private sealed class <DelayedFlashHealth>d__15 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public CorruptedHealth <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <DelayedFlashHealth>d__15(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Expected O, but got Unknown //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitUntil((Func<bool>)(() => PlayerData.instance != null)); <>1__state = 1; return true; case 1: <>1__state = -1; <>2__current = (object)new WaitForSecondsRealtime(5f); <>1__state = 2; return true; case 2: <>1__state = -1; firstBench = false; 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 ConfigEntry<float> MaxSpeed; public static ConfigEntry<float> audioModulation; public static ConfigEntry<KeyboardShortcut> flashKey; public static bool keyPressed; public static bool configChanged; public static PlayerData pd; internal static ManualLogSource Log; public static readonly List<CachedAudio> Cached = new List<CachedAudio>(); private static bool firstSpawn = true; private static bool firstBench = true; public static bool flashed = true; private bool wasAtBench = false; private void Awake() { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Expected O, but got Unknown //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Expected O, but got Unknown //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: 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) Log = ((BaseUnityPlugin)this).Logger; MaxSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Max Speed", "Max Speed", 2f, new ConfigDescription("Sets the maximum speed of the game at full health", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1.5f, 2f), Array.Empty<object>())); audioModulation = ((BaseUnityPlugin)this).Config.Bind<float>("Music and Audio", "Modulation intensity", 1f, new ConfigDescription("Adjusts how much the audio will modulate", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>())); flashKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Display Key", "Display Masks", new KeyboardShortcut((KeyCode)306, Array.Empty<KeyCode>()), "Temporarily displays masks (Silk required)"); SceneManager.sceneLoaded += OnSceneLoaded; RebuildAudioCache(SceneManager.GetActiveScene()); pd = PlayerData.instance; keyPressed = false; MaxSpeed.SettingChanged += delegate { configChanged = true; }; audioModulation.SettingChanged += delegate { configChanged = true; }; new Harmony("lagerthon.CorruptedHealth").PatchAll(); Log.LogInfo((object)"Corrupted Health Loaded"); } private void Update() { //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) PlayerData instance = PlayerData.instance; HeroController instance2 = HeroController.instance; if (instance != null && !((Object)(object)instance2 == (Object)null)) { if (firstSpawn) { ((MonoBehaviour)this).StartCoroutine(DelayedFlashHealth()); firstSpawn = false; } bool atBench = instance.atBench; if (atBench && !wasAtBench && !firstBench) { FlashMasks.ForceFlash(instance.maxHealth); flashed = true; } wasAtBench = atBench; KeyboardShortcut value = flashKey.Value; if (((KeyboardShortcut)(ref value)).IsDown() && instance.silk >= 3) { instance2.TakeSilk(3); FlashMasks.ForceFlash(instance.health); keyPressed = true; flashed = true; } FlashMasks.HideMasks(); } } [IteratorStateMachine(typeof(<DelayedFlashHealth>d__15))] private IEnumerator DelayedFlashHealth() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <DelayedFlashHealth>d__15(0) { <>4__this = this }; } private void OnSceneLoaded(Scene scene, LoadSceneMode mode) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) RebuildAudioCache(scene); FlashMasks.ResetAll(); if (((Scene)(ref scene)).name == "Menu_Title") { firstSpawn = true; firstBench = true; keyPressed = false; } } private void OnDestroy() { SceneManager.sceneLoaded -= OnSceneLoaded; FlashMasks.ResetAll(); } private static void RebuildAudioCache(Scene scene) { Cached.Clear(); AudioSource[] array = Resources.FindObjectsOfTypeAll<AudioSource>(); foreach (AudioSource val in array) { if (!((Object)(object)val == (Object)null) && val.loop && !(val.spatialBlend > 0f) && (!((Object)(object)val.clip != (Object)null) || !(val.clip.length < 10f))) { AudioLowPassFilter val2 = ((Component)val).GetComponent<AudioLowPassFilter>(); if ((Object)(object)val2 == (Object)null) { val2 = ((Component)val).gameObject.AddComponent<AudioLowPassFilter>(); } Cached.Add(new CachedAudio { source = val, lowPass = val2 }); } } } } [HarmonyPatch(typeof(ToolItemManager), "GetCurrentEquippedTools")] internal class FracturedMaskPatch { public static int fracturedMask; private static void Postfix(ref List<ToolItem> __result) { fracturedMask = 0; if (__result == null) { return; } foreach (ToolItem item in __result) { if ((Object)(object)item != (Object)null && item.name == "Fractured Mask") { fracturedMask = 1; break; } } } } public static class FlashMasks { private const float HIDE_DELAY = 2f; private static readonly Dictionary<GameObject, float> hideTimers = new Dictionary<GameObject, float>(); public static void HideMasks() { PlayerData instance = PlayerData.instance; if (instance != null && !instance.atBench && (!((Object)(object)GameManager.instance != (Object)null) || !GameManager.instance.isPaused)) { HeroController instance2 = HeroController.instance; if (!((Object)(object)instance2 != (Object)null) || !instance2.controlReqlinquished) { DetectActiveMasks(); UpdateTimers(); } } } private static void DetectActiveMasks() { PlayMakerFSM[] array = Resources.FindObjectsOfTypeAll<PlayMakerFSM>(); foreach (PlayMakerFSM val in array) { if (!((Object)(object)val == (Object)null) && !(val.FsmName != "health_display") && ((Object)((Component)val).gameObject).name.Contains("Health 2+(Clone)") && val.ActiveStateName != "Inactive" && !hideTimers.ContainsKey(((Component)val).gameObject)) { hideTimers[((Component)val).gameObject] = 2f; } } } private static void UpdateTimers() { List<GameObject> list = new List<GameObject>(hideTimers.Keys); foreach (GameObject item in list) { if ((Object)(object)item == (Object)null) { hideTimers.Remove(item); continue; } hideTimers[item] -= Time.unscaledDeltaTime; if (hideTimers[item] <= 0f) { PlayMakerFSM component = item.GetComponent<PlayMakerFSM>(); if ((Object)(object)component != (Object)null) { component.SetState("Inactive"); } hideTimers.Remove(item); } } CorruptedHealth.flashed = false; } public static void ForceFlash(int health) { PlayMakerFSM[] array = Resources.FindObjectsOfTypeAll<PlayMakerFSM>(); foreach (PlayMakerFSM val in array) { if (!((Object)(object)val == (Object)null) && !(val.FsmName != "health_display") && ((Object)((Component)val).gameObject).name.Contains("Health 2+(Clone)")) { FsmInt val2 = val.FsmVariables.FindFsmInt("Health Number"); if (val2 != null && val2.Value <= health) { val.SetState("Idle Enter"); hideTimers[((Component)val).gameObject] = 2f; } } } } public static void ForceHideAll() { PlayMakerFSM[] array = Resources.FindObjectsOfTypeAll<PlayMakerFSM>(); foreach (PlayMakerFSM val in array) { if (!((Object)(object)val == (Object)null) && val.FsmName == "health_display" && ((Object)((Component)val).gameObject).name.Contains("Health 2+(Clone)")) { val.SetState("Inactive"); } } hideTimers.Clear(); } public static void ResetAll() { hideTimers.Clear(); } } [HarmonyPatch(typeof(GameManager), "Update")] internal class Patch_GameManager_Update { private static float currentPitch = 1f; private static float pitchVelocity; private static float targetPitch = 1f; private static float currentTimeScale = 1f; private static float timeScaleVelocity; private static float targetTimeScale = 1f; private static int lastHealth = -1; private static int lastMaxHealth = -1; private static void Postfix() { if ((Object)(object)GameManager.instance != (Object)null && GameManager.instance.isPaused) { return; } PlayerData instance = PlayerData.instance; if (instance == null) { return; } int fracturedMask = FracturedMaskPatch.fracturedMask; int num = instance.health + instance.healthBlue + fracturedMask; int num2 = instance.maxHealth + instance.healthBlue + fracturedMask; if (num != lastHealth || num2 != lastMaxHealth || CorruptedHealth.configChanged) { lastHealth = num; lastMaxHealth = num2; CorruptedHealth.configChanged = false; float num3 = (float)num / (float)num2; targetTimeScale = 1f + (CorruptedHealth.MaxSpeed.Value - 1f) * num3; targetPitch = 1f + (num3 - 0.9f) * CorruptedHealth.audioModulation.Value; } currentTimeScale = Mathf.SmoothDamp(currentTimeScale, targetTimeScale, ref timeScaleVelocity, 0.25f, 5f, Time.unscaledDeltaTime); Time.timeScale = currentTimeScale; currentPitch = Mathf.SmoothDamp(currentPitch, targetPitch, ref pitchVelocity, 0.5f, 2f, Time.unscaledDeltaTime); foreach (CorruptedHealth.CachedAudio item in CorruptedHealth.Cached) { if (!((Object)(object)item.source == (Object)null)) { item.source.pitch = currentPitch; float num4 = Mathf.InverseLerp(0.1f, 1f, (float)instance.health / (float)instance.maxHealth); num4 *= num4; item.lowPass.cutoffFrequency = 22000f - CorruptedHealth.audioModulation.Value * (22000f - 500f * Mathf.Pow(44f, num4)); } } } } }