using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.Globalization; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using NAudio.Wave; using NAudio.Wave.SampleProviders; using RiskOfOptions; using RiskOfOptions.OptionConfigs; using RiskOfOptions.Options; using RoR2; using RoR2.ConVar; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("ButItRefused")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.8.1.0")] [assembly: AssemblyInformationalVersion("1.8.1")] [assembly: AssemblyProduct("ButItRefused")] [assembly: AssemblyTitle("ButItRefused")] [assembly: AssemblyVersion("1.8.1.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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 ButItRefused { [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("com.orz.butitrefused", "But It Refused", "1.8.1")] public class ButItRefusedPlugin : BaseUnityPlugin { public const string PluginGuid = "com.orz.butitrefused"; public const string PluginName = "But It Refused"; public const string PluginVersion = "1.8.1"; internal static ButItRefusedPlugin Instance; internal static ManualLogSource Log; internal static string AssetDir; internal static ConfigEntry Enabled; internal static ConfigEntry DurationScale; internal static ConfigEntry MusicEnabled; internal static ConfigEntry MusicVolume; internal static ConfigEntry MusicStartSeconds; internal static ConfigEntry DuckGameMusic; internal static ConfigEntry MuteGameSounds; internal static ConfigEntry SfxVolume; internal static ConfigEntry TriggerOnShrineAndSkillRevives; internal static ConfigEntry AuraEnabled; internal static ConfigEntry AuraIntensity; internal static Texture2D HeartTex; internal static Texture2D HeartWhiteTex; internal static Texture2D HeartBreakTex; internal static Texture2D[] ShardTexs; internal static Texture2D TextTex; internal static SequenceRunner Runner; private void Awake() { //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Expected O, but got Unknown //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Expected O, but got Unknown //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Expected O, but got Unknown //IL_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_01f9: Expected O, but got Unknown //IL_027e: Unknown result type (might be due to invalid IL or missing references) //IL_0283: Unknown result type (might be due to invalid IL or missing references) //IL_0289: Expected O, but got Unknown //IL_0298: Unknown result type (might be due to invalid IL or missing references) Instance = this; Log = ((BaseUnityPlugin)this).Logger; AssetDir = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location); Enabled = ((BaseUnityPlugin)this).Config.Bind("But It Refused", "Enabled", true, "Enable the But It Refused revive sequence."); DurationScale = ((BaseUnityPlugin)this).Config.Bind("But It Refused", "DurationScale", 1f, new ConfigDescription("Length multiplier for the whole sequence (1 = about 8s before respawn).", (AcceptableValueBase)(object)new AcceptableValueRange(0.5f, 2f), Array.Empty())); TriggerOnShrineAndSkillRevives = ((BaseUnityPlugin)this).Config.Bind("But It Refused", "TriggerOnShrineAndSkillRevives", true, "Also play the sequence for non-item revives (Shrine of Rebirth buff, Seeker self revive)."); MusicEnabled = ((BaseUnityPlugin)this).Config.Bind("But It Refused", "MusicEnabled", true, "Play Finale when the SOUL refuses."); MusicVolume = ((BaseUnityPlugin)this).Config.Bind("But It Refused", "MusicVolume", 0.5f, new ConfigDescription("Finale volume, already matched to the game's music level and to your in game volume settings.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 1f), Array.Empty())); MusicStartSeconds = ((BaseUnityPlugin)this).Config.Bind("But It Refused", "MusicStartSeconds", 0f, "Timestamp (in seconds) inside the bundled music file where playback starts. The bundled file is already trimmed to the 0:58 swell of Finale, so 0 is the intended start."); DuckGameMusic = ((BaseUnityPlugin)this).Config.Bind("But It Refused", "DuckGameMusic", true, "Silence the game music during the sequence, keep it low under Finale, then restore it."); MuteGameSounds = ((BaseUnityPlugin)this).Config.Bind("But It Refused", "MuteGameSounds", true, "Silence the game's sound effects during the sequence, until the respawn."); SfxVolume = ((BaseUnityPlugin)this).Config.Bind("But It Refused", "SfxVolume", 0.8f, new ConfigDescription("Volume of the SOUL break sounds.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 1f), Array.Empty())); AuraEnabled = ((BaseUnityPlugin)this).Config.Bind("But It Refused", "AuraEnabled", true, "After the revive, a glow around you cycles through the 7 SOUL colors until Finale ends."); AuraIntensity = ((BaseUnityPlugin)this).Config.Bind("But It Refused", "AuraIntensity", 2f, new ConfigDescription("Brightness of the SOUL aura.", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 6f), Array.Empty())); HeartTex = LoadTexture("butitrefused_heart.png"); HeartWhiteTex = LoadTexture("butitrefused_heart_white.png"); HeartBreakTex = LoadTexture("butitrefused_heartbreak.png"); ShardTexs = (Texture2D[])(object)new Texture2D[4] { LoadTexture("butitrefused_shard_0.png"), LoadTexture("butitrefused_shard_1.png"), LoadTexture("butitrefused_shard_2.png"), LoadTexture("butitrefused_shard_3.png") }; TextTex = LoadTexture("butitrefused_text.png"); GameObject val = new GameObject("ButItRefusedRunner"); Object.DontDestroyOnLoad((Object)val); Runner = val.AddComponent(); new Harmony("com.orz.butitrefused").PatchAll(typeof(TryReviveOnBodyDeathPatch)); if (RiskOfOptionsCompat.Available) { try { RiskOfOptionsCompat.Init(); } catch (Exception ex) { Log.LogWarning((object)("Risk Of Options integration failed: " + ex.Message)); } } Log.LogInfo((object)"But it refused. (ready)"); } private static Texture2D LoadTexture(string fileName) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown string text = Path.Combine(AssetDir, fileName); if (!File.Exists(text)) { Log.LogError((object)("Missing asset: " + text)); return null; } Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false); if (!ImageConversion.LoadImage(val, File.ReadAllBytes(text))) { Log.LogError((object)("Could not decode: " + text)); return null; } ((Texture)val).filterMode = (FilterMode)0; ((Texture)val).wrapMode = (TextureWrapMode)1; return val; } } internal static class ExtraLifeReflection { internal static readonly Type BehaviorType = typeof(CharacterMaster).GetNestedType("ExtraLifeServerBehavior", BindingFlags.Public | BindingFlags.NonPublic); internal static readonly FieldInfo CompletionTime = BehaviorType?.GetField("completionTime"); internal static readonly FieldInfo SoundTime = BehaviorType?.GetField("soundTime"); } [HarmonyPatch(typeof(CharacterMaster), "TryReviveOnBodyDeath")] internal static class TryReviveOnBodyDeathPatch { private static readonly string[] InvokeRespawnNames = new string[3] { "RespawnExtraLifeShrine", "RespawnSeekerRevive", "RespawnExtraLifeHealAndRevive" }; private static void Postfix(CharacterMaster __instance, CharacterBody body, bool __result) { try { Handle(__instance, body, __result); } catch (Exception ex) { ButItRefusedPlugin.Log.LogError((object)("TryReviveOnBodyDeath postfix: " + ex)); } } internal static bool IsLocalPlayerMaster(CharacterMaster master) { if (!Object.op_Implicit((Object)(object)master)) { return false; } PlayerCharacterMasterController playerCharacterMasterController = master.playerCharacterMasterController; if (!Object.op_Implicit((Object)(object)playerCharacterMasterController)) { return false; } NetworkUser networkUser = playerCharacterMasterController.networkUser; if (Object.op_Implicit((Object)(object)networkUser)) { return networkUser.localUser != null; } return false; } private static void Handle(CharacterMaster master, CharacterBody body, bool revived) { //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_0124: 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_020a: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) if (!revived || !ButItRefusedPlugin.Enabled.Value || !Object.op_Implicit((Object)(object)master) || !IsLocalPlayerMaster(master)) { return; } string text = null; string[] invokeRespawnNames = InvokeRespawnNames; foreach (string text2 in invokeRespawnNames) { if (((MonoBehaviour)master).IsInvoking(text2)) { text = text2; break; } } if ((text == "RespawnExtraLifeShrine" || text == "RespawnSeekerRevive") && !ButItRefusedPlugin.TriggerOnShrineAndSkillRevives.Value) { return; } float num = SequenceRunner.ComputeIntroDuration(); float num2 = Mathf.Max(0.25f, num - 1f); if (text != null) { ((MonoBehaviour)master).CancelInvoke(text); ((MonoBehaviour)master).Invoke(text, num); if (((MonoBehaviour)master).IsInvoking("PlayExtraLifeSFX")) { ((MonoBehaviour)master).CancelInvoke("PlayExtraLifeSFX"); ((MonoBehaviour)master).Invoke("PlayExtraLifeSFX", num2); } } else { Type behaviorType = ExtraLifeReflection.BehaviorType; FieldInfo completionTime = ExtraLifeReflection.CompletionTime; FieldInfo soundTime = ExtraLifeReflection.SoundTime; bool flag = false; if (behaviorType != null && completionTime != null) { Component[] components = ((Component)master).GetComponents(behaviorType); foreach (Component obj in components) { FixedTimeStamp val = (FixedTimeStamp)completionTime.GetValue(obj); if (!((FixedTimeStamp)(ref val)).isPositiveInfinity) { float timeUntil = ((FixedTimeStamp)(ref val)).timeUntil; if (!(timeUntil < -0.5f) && !(timeUntil > 5f)) { completionTime.SetValue(obj, FixedTimeStamp.now + num); soundTime?.SetValue(obj, FixedTimeStamp.now + num2); flag = true; } } } } if (!flag) { ButItRefusedPlugin.Log.LogWarning((object)"Item revive detected but its timer could not be adjusted; keeping the vanilla 2s delay."); num = 2f; } } Vector3 heartWorldPosition = (Object.op_Implicit((Object)(object)body) ? body.corePosition : (master.deathFootPosition + Vector3.up)); Transform corpseTransform = null; if (Object.op_Implicit((Object)(object)body) && Object.op_Implicit((Object)(object)body.modelLocator)) { corpseTransform = body.modelLocator.modelTransform; } if (Object.op_Implicit((Object)(object)ButItRefusedPlugin.Runner)) { ButItRefusedPlugin.Runner.Play(master, heartWorldPosition, corpseTransform, num); } } } public class SequenceRunner : MonoBehaviour { private const float FadeInBase = 1.6f; private const float SplitBase = 1.1f; private const float ShatterBase = 0.9f; private const float StillBase = 0.7f; private const float ReformBase = 0.9f; private const float RestoreBase = 0.4f; private const float TextInBase = 1.1f; private const float HoldBase = 1.3f; private MusicPlayer musicPlayer; private MusicPlayer sfxPlayer; private Coroutine sequenceRoutine; private Coroutine musicRoutine; private Coroutine rtpcRoutine; private Coroutine auraRoutine; private GameObject auraObject; private Light auraLight; private TemporaryOverlayInstance auraOverlay; private CharacterBody auraBody; private Coroutine sfxRtpcRoutine; private bool musicRtpcAltered; private bool sfxRtpcAltered; private float currentMusicRtpc = 100f; private float currentSfxRtpc = 100f; private float userSfxVolume = 100f; private float userMusicVolume = 100f; private int lastPlayFrame = -1; private bool pulseEnabled = true; private float musicPlayed; private float musicPlayable; private float musicUserScale = 1f; private const float MusicLoudnessTrim = 0.42f; private const float SfxLoudnessTrim = 0.7f; private const float MinMusicFollow = 0.45f; private static readonly Color[] SoulColors = (Color[])(object)new Color[7] { new Color(1f, 0f, 0f), new Color(0.26f, 0.99f, 1f), new Color(0.99f, 0.65f, 0f), new Color(0f, 0.24f, 1f), new Color(0.84f, 0.21f, 0.85f), new Color(0f, 0.75f, 0f), new Color(1f, 1f, 0f) }; private GameObject overlayRoot; private CanvasGroup overlayGroup; private Image blackImage; private RectTransform heartRect; private RawImage heartImage; private RawImage heartFlashImage; private RectTransform textRect; private RawImage textImage; private RawImage[] shardImages; private Vector2[] shardDirections; private float[] shardDistances; private Vector2[] shardFrozenPositions; private int heartScale = 4; private int textScale = 3; private static readonly float[] TextCharBounds = new float[15] { 7f, 14f, 21f, 24f, 31f, 38f, 41f, 48f, 55f, 62f, 69f, 76f, 83f, 90f, 92f }; private const float SegmentSumBase = 8f; private float MusicRemainingSeconds { get { if (musicPlayer == null || !musicPlayer.IsPlaying) { return float.MaxValue; } return Mathf.Max(0f, musicPlayable - musicPlayed); } } private static float Scale => Mathf.Clamp(ButItRefusedPlugin.DurationScale.Value, 0.4f, 2.5f); internal static float ComputeIntroDuration() { return Mathf.Max(2.05f, 8f * Scale); } private void Awake() { musicPlayer = new MusicPlayer(); sfxPlayer = new MusicPlayer(); Run.onRunDestroyGlobal += OnRunDestroyed; GlobalEventManager.onCharacterDeathGlobal += OnCharacterDeath; PauseManager.onPauseStartGlobal = (Action)Delegate.Combine(PauseManager.onPauseStartGlobal, new Action(OnPauseStart)); PauseManager.onPauseEndGlobal = (Action)Delegate.Combine(PauseManager.onPauseEndGlobal, new Action(OnPauseEnd)); } private void OnDestroy() { Run.onRunDestroyGlobal -= OnRunDestroyed; GlobalEventManager.onCharacterDeathGlobal -= OnCharacterDeath; PauseManager.onPauseStartGlobal = (Action)Delegate.Remove(PauseManager.onPauseStartGlobal, new Action(OnPauseStart)); PauseManager.onPauseEndGlobal = (Action)Delegate.Remove(PauseManager.onPauseEndGlobal, new Action(OnPauseEnd)); musicPlayer?.Dispose(); sfxPlayer?.Dispose(); } private void OnPauseStart() { musicPlayer?.SetPaused(paused: true); sfxPlayer?.SetPaused(paused: true); } private void OnPauseEnd() { musicPlayer?.SetPaused(paused: false); sfxPlayer?.SetPaused(paused: false); } private void PlaySfx(string fileName) { float num = (sfxRtpcAltered ? userSfxVolume : ReadUserVolume("cvVolumeSfx")); float num2 = Mathf.Clamp01(ButItRefusedPlugin.SfxVolume.Value) * 0.7f * (ReadUserVolume("cvVolumeMaster") / 100f) * (num / 100f); if (num2 <= 0f || sfxPlayer == null) { return; } string path = Path.Combine(ButItRefusedPlugin.AssetDir, fileName); if (!File.Exists(path)) { return; } try { sfxPlayer.Play(path, 0f, num2); } catch (Exception ex) { ButItRefusedPlugin.Log.LogWarning((object)("Sfx failed: " + ex.Message)); } } private void OnCharacterDeath(DamageReport report) { if (report != null && TryReviveOnBodyDeathPatch.IsLocalPlayerMaster(report.victimMaster) && musicPlayer != null && musicPlayer.IsPlaying) { ((MonoBehaviour)this).StartCoroutine(StopMusicUnlessNewSequence()); } } private IEnumerator StopMusicUnlessNewSequence() { int deathFrame = Time.frameCount; yield return null; yield return null; if (lastPlayFrame < deathFrame && musicPlayer != null && musicPlayer.IsPlaying) { if (musicRoutine != null) { ((MonoBehaviour)this).StopCoroutine(musicRoutine); musicRoutine = null; } musicPlayer.Stop(); StopAura(); SetMusicDuck(1f, 1.5f); SetSfxDuck(1f, 1f); } } private void OnRunDestroyed(Run run) { Cleanup(stopMusic: true); } internal void Play(CharacterMaster master, Vector3 heartWorldPosition, Transform corpseTransform, float introDuration) { //IL_007e: Unknown result type (might be due to invalid IL or missing references) Cleanup(stopMusic: false); if (musicRoutine != null) { ((MonoBehaviour)this).StopCoroutine(musicRoutine); musicRoutine = null; } musicPlayer?.Stop(); sfxPlayer?.Stop(); MusicPlayer.StopEverything(); StopAura(); SetMusicDuck(0f, 0.4f); SetSfxDuck(0f, 0.35f); lastPlayFrame = Time.frameCount; sequenceRoutine = ((MonoBehaviour)this).StartCoroutine(Sequence(master, heartWorldPosition, corpseTransform, introDuration)); } private void Cleanup(bool stopMusic) { if (sequenceRoutine != null) { ((MonoBehaviour)this).StopCoroutine(sequenceRoutine); sequenceRoutine = null; } if (Object.op_Implicit((Object)(object)overlayRoot)) { Object.Destroy((Object)(object)overlayRoot); overlayRoot = null; } if (stopMusic) { if (musicRoutine != null) { ((MonoBehaviour)this).StopCoroutine(musicRoutine); musicRoutine = null; } musicPlayer?.Stop(); sfxPlayer?.Stop(); MusicPlayer.StopEverything(); StopAura(); SetMusicDuck(1f, 1.5f); SetSfxDuck(1f, 0.8f); } } private void StopAura() { if (auraRoutine != null) { ((MonoBehaviour)this).StopCoroutine(auraRoutine); auraRoutine = null; } RemoveAuraOverlay(); if (Object.op_Implicit((Object)(object)auraObject)) { Object.Destroy((Object)(object)auraObject); auraObject = null; auraLight = null; } } private void RemoveAuraOverlay() { if (auraOverlay != null) { try { auraOverlay.Destroy(); } catch { } auraOverlay = null; } auraBody = null; } private void AttachAuraOverlay(CharacterBody body, float remainingDuration) { //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: 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_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Expected O, but got Unknown RemoveAuraOverlay(); auraBody = body; try { Transform val = (Object.op_Implicit((Object)(object)body.modelLocator) ? body.modelLocator.modelTransform : null); CharacterModel val2 = (Object.op_Implicit((Object)(object)val) ? ((Component)val).GetComponent() : null); if (Object.op_Implicit((Object)(object)val2)) { TemporaryOverlayInstance val3 = TemporaryOverlayManager.AddOverlay(((Component)val).gameObject); val3.duration = Mathf.Max(1f, remainingDuration); val3.animateShaderAlpha = true; val3.alphaCurve = new AnimationCurve((Keyframe[])(object)new Keyframe[4] { new Keyframe(0f, 0f), new Keyframe(0.05f, 1f), new Keyframe(0.92f, 1f), new Keyframe(1f, 0f) }); val3.destroyComponentOnEnd = true; val3.originalMaterial = LegacyResourcesAPI.Load("Materials/matImmune"); val3.AddToCharacterModel(val2); auraOverlay = val3; } } catch (Exception ex) { ButItRefusedPlugin.Log.LogWarning((object)("Aura overlay failed: " + ex.Message)); auraOverlay = null; } } private void StartAura(CharacterMaster master) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown //IL_008b: Unknown result type (might be due to invalid IL or missing references) StopAura(); float num = MusicRemainingSeconds; if (num > 3600f) { num = 45f; } auraObject = new GameObject("ButItRefusedAura"); Object.DontDestroyOnLoad((Object)(object)auraObject); auraLight = auraObject.AddComponent(); auraLight.type = (LightType)2; auraLight.range = 13f; auraLight.shadows = (LightShadows)0; auraLight.intensity = 0f; auraLight.color = SoulColors[0]; auraLight.renderMode = (LightRenderMode)1; auraRoutine = ((MonoBehaviour)this).StartCoroutine(AuraRoutine(master, num)); } private IEnumerator AuraRoutine(CharacterMaster master, float duration) { float elapsed = 0f; while (!RunIsOver() && Object.op_Implicit((Object)(object)auraLight) && elapsed < duration) { if (!PauseManager.isPaused) { elapsed += Time.unscaledDeltaTime; } CharacterBody val = (Object.op_Implicit((Object)(object)master) ? master.GetBody() : null); if (Object.op_Implicit((Object)(object)val)) { auraObject.transform.position = val.corePosition; if ((Object)(object)val != (Object)(object)auraBody) { AttachAuraOverlay(val, duration - elapsed); } } int num = Mathf.FloorToInt(elapsed / 1.2f) % SoulColors.Length; int num2 = (num + 1) % SoulColors.Length; float num3 = elapsed % 1.2f / 1.2f; float num4 = Mathf.SmoothStep(0f, 1f, Mathf.Clamp01((num3 - 0.65f) / 0.35f)); Color val2 = Color.Lerp(SoulColors[num], SoulColors[num2], num4); auraLight.color = val2; Material val3 = ((auraOverlay != null) ? auraOverlay.materialInstance : null); if (Object.op_Implicit((Object)(object)val3)) { val3.SetColor("_TintColor", val2); } float num5 = Mathf.Clamp01(elapsed / 1.5f); float num6 = Mathf.Clamp01((duration - elapsed) / 3f); auraLight.intensity = Mathf.Clamp(ButItRefusedPlugin.AuraIntensity.Value, 0f, 6f) * 6f * num5 * num6; yield return null; } RemoveAuraOverlay(); float from = (Object.op_Implicit((Object)(object)auraLight) ? auraLight.intensity : 0f); float t2 = 0f; while (Object.op_Implicit((Object)(object)auraLight) && t2 < 0.6f) { t2 += Time.deltaTime; auraLight.intensity = Mathf.Lerp(from, 0f, t2 / 0.6f); yield return null; } if (Object.op_Implicit((Object)(object)auraObject)) { Object.Destroy((Object)(object)auraObject); auraObject = null; auraLight = null; } auraRoutine = null; } private static bool RunIsOver() { return (Object)(object)Run.instance == (Object)null; } private IEnumerator Sequence(CharacterMaster master, Vector3 heartWorldPosition, Transform corpseTransform, float introDuration) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) BuildOverlay(); Renderer corpseRenderer = null; if (Object.op_Implicit((Object)(object)corpseTransform)) { corpseRenderer = (Renderer)(object)((Component)corpseTransform).GetComponentInChildren(); if (!Object.op_Implicit((Object)(object)corpseRenderer)) { corpseRenderer = ((Component)corpseTransform).GetComponentInChildren(); } } float scale = Scale; float fadeIn = 1.6f * scale; float split = 1.1f * scale; float shatter = 0.9f * scale; float still = 0.7f * scale; float reform = 0.9f * scale; float restore = 0.4f * scale; float textIn = 1.1f * scale; float hold = 1.3f * scale; float num = fadeIn + split + shatter + still + reform + restore + textIn + hold; if (introDuration > 0.1f && num > 0.1f) { float num2 = introDuration / num; fadeIn *= num2; split *= num2; shatter *= num2; still *= num2; reform *= num2; restore *= num2; textIn *= num2; hold *= num2; } pulseEnabled = true; Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor((float)Screen.width * 0.5f, (float)Screen.height * 0.5f); Vector2 heartTarget = val + new Vector2(0f, (float)Screen.height * 0.06f); float time = 0f; Bounds bounds; while (time < fadeIn) { if (RunIsOver()) { Cleanup(stopMusic: true); yield break; } time += Time.deltaTime; float num3 = Mathf.Clamp01(time / fadeIn); ((Graphic)blackImage).color = new Color(0f, 0f, 0f, Mathf.SmoothStep(0f, 1f, num3) * 0.85f); float num4 = Mathf.Clamp01((time - fadeIn * 0.15f) / (fadeIn * 0.55f)); SetHeartAlpha(Mathf.SmoothStep(0f, 1f, num4)); if (Object.op_Implicit((Object)(object)corpseRenderer)) { try { bounds = corpseRenderer.bounds; heartWorldPosition = ((Bounds)(ref bounds)).center; } catch { corpseRenderer = null; } } TrackHeartToWorld(heartWorldPosition); PulseHeart(); HandlePauseVisibility(); yield return null; } SetHeartAlpha(1f); PlaySfx("butitrefused_break1.wav"); pulseEnabled = false; if (Object.op_Implicit((Object)(object)heartRect)) { ((Transform)heartRect).localScale = Vector3.one; } SetHeartTexture(ButItRefusedPlugin.HeartBreakTex); time = 0f; while (time < split) { if (RunIsOver()) { Cleanup(stopMusic: true); yield break; } time += Time.deltaTime; float num5 = Mathf.Clamp01(time / split); ((Graphic)blackImage).color = new Color(0f, 0f, 0f, Mathf.Lerp(0.85f, 1f, Mathf.SmoothStep(0f, 1f, num5))); if (Object.op_Implicit((Object)(object)corpseRenderer)) { try { bounds = corpseRenderer.bounds; heartWorldPosition = ((Bounds)(ref bounds)).center; } catch { corpseRenderer = null; } } TrackHeartToWorld(heartWorldPosition); HandlePauseVisibility(); yield return null; } ((Graphic)blackImage).color = Color.black; PlaySfx("butitrefused_break2.wav"); SetHeartAlpha(0f); Vector2 shatterOrigin = (Object.op_Implicit((Object)(object)heartRect) ? heartRect.anchoredPosition : heartTarget); CreateShards(shatterOrigin); time = 0f; while (time < shatter) { if (RunIsOver()) { Cleanup(stopMusic: true); yield break; } time += Time.deltaTime; float num6 = Mathf.Clamp01(time / shatter); float spreadFactor = 1f - Mathf.Pow(1f - num6, 3f); UpdateShards(shatterOrigin, spreadFactor, time); HandlePauseVisibility(); yield return null; } time = 0f; while (time < still) { if (RunIsOver()) { Cleanup(stopMusic: true); yield break; } time += Time.deltaTime; HandlePauseVisibility(); yield return null; } CaptureShardPositions(); time = 0f; while (time < reform) { if (RunIsOver()) { Cleanup(stopMusic: true); yield break; } time += Time.deltaTime; float num7 = Mathf.Clamp01(time / reform); UpdateShardsConverge(heartTarget, num7 * num7, time); HandlePauseVisibility(); yield return null; } DestroyShards(); if (Object.op_Implicit((Object)(object)heartRect)) { heartRect.anchoredPosition = heartTarget; } SetHeartTexture(ButItRefusedPlugin.HeartTex); SetHeartAlpha(1f); pulseEnabled = true; time = 0f; while (time < restore) { if (RunIsOver()) { Cleanup(stopMusic: true); yield break; } time += Time.deltaTime; float num8 = Mathf.Sin(Mathf.Clamp01(time / restore) * MathF.PI); if (Object.op_Implicit((Object)(object)heartFlashImage)) { ((Graphic)heartFlashImage).color = new Color(1f, 1f, 1f, num8); } PulseHeart(); HandlePauseVisibility(); yield return null; } if (Object.op_Implicit((Object)(object)heartFlashImage)) { ((Graphic)heartFlashImage).color = new Color(1f, 1f, 1f, 0f); } StartMusic(); SetTextAlpha(1f); time = 0f; int shownChars = -1; while (time < textIn) { if (RunIsOver()) { Cleanup(stopMusic: true); yield break; } time += Time.deltaTime; int num9 = Mathf.Min(TextCharBounds.Length, Mathf.FloorToInt(Mathf.Clamp01(time / textIn) * (float)(TextCharBounds.Length + 1))); if (num9 != shownChars) { shownChars = num9; RevealTextCharacters(num9); } PulseHeart(); HandlePauseVisibility(); yield return null; } RevealTextCharacters(TextCharBounds.Length); time = 0f; while (time < hold) { if (RunIsOver()) { Cleanup(stopMusic: true); yield break; } time += Time.deltaTime; PulseHeart(); HandlePauseVisibility(); yield return null; } float waited = 0f; bool respawned = false; while (waited < 6f) { if (RunIsOver()) { Cleanup(stopMusic: true); yield break; } waited += Time.deltaTime; CharacterBody val2 = (Object.op_Implicit((Object)(object)master) ? master.GetBody() : null); if (Object.op_Implicit((Object)(object)val2) && Object.op_Implicit((Object)(object)val2.healthComponent) && val2.healthComponent.alive) { respawned = true; break; } PulseHeart(); HandlePauseVisibility(); yield return null; } if (!respawned) { Cleanup(stopMusic: true); yield break; } SetSfxDuck(1f, 1.2f); if (musicPlayer != null && musicPlayer.IsPlaying) { SetMusicDuck(0.1f, 2f); } else { SetMusicDuck(1f, 2f); } if (ButItRefusedPlugin.AuraEnabled.Value && musicPlayer != null && musicPlayer.IsPlaying) { StartAura(master); } time = 0f; while (time < 0.35f) { time += Time.deltaTime; PulseHeart(); HandlePauseVisibility(); yield return null; } float fadeOut = 1.5f; time = 0f; Color heartColor = ((Graphic)heartImage).color; Color textColor = ((Graphic)textImage).color; while (time < fadeOut) { time += Time.deltaTime; float num10 = Mathf.Clamp01(time / fadeOut); ((Graphic)blackImage).color = new Color(0f, 0f, 0f, 1f - Mathf.SmoothStep(0f, 1f, num10)); float num11 = 1f - Mathf.Clamp01(time / (fadeOut * 0.6f)); SetHeartAlpha(num11 * heartColor.a); SetTextAlpha(num11 * textColor.a); PulseHeart(); HandlePauseVisibility(); yield return null; } Object.Destroy((Object)(object)overlayRoot); overlayRoot = null; sequenceRoutine = null; } private void BuildOverlay() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown //IL_0087: 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_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: 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_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Expected O, but got Unknown //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_0218: Unknown result type (might be due to invalid IL or missing references) //IL_021e: Expected O, but got Unknown //IL_0272: Unknown result type (might be due to invalid IL or missing references) //IL_0288: Unknown result type (might be due to invalid IL or missing references) //IL_0293: Unknown result type (might be due to invalid IL or missing references) //IL_029e: Unknown result type (might be due to invalid IL or missing references) //IL_02a8: Unknown result type (might be due to invalid IL or missing references) //IL_02d4: Unknown result type (might be due to invalid IL or missing references) //IL_02da: Expected O, but got Unknown //IL_0333: Unknown result type (might be due to invalid IL or missing references) //IL_0354: Unknown result type (might be due to invalid IL or missing references) //IL_0364: Unknown result type (might be due to invalid IL or missing references) //IL_037e: Unknown result type (might be due to invalid IL or missing references) //IL_03a2: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_03d5: Unknown result type (might be due to invalid IL or missing references) //IL_0423: Unknown result type (might be due to invalid IL or missing references) overlayRoot = new GameObject("ButItRefusedOverlay"); Object.DontDestroyOnLoad((Object)(object)overlayRoot); Canvas obj = overlayRoot.AddComponent(); obj.renderMode = (RenderMode)0; obj.sortingOrder = 30000; overlayGroup = overlayRoot.AddComponent(); overlayGroup.blocksRaycasts = false; overlayGroup.interactable = false; blackImage = CreateChildImage(overlayRoot.transform, "Black"); RectTransform rectTransform = ((Graphic)blackImage).rectTransform; rectTransform.anchorMin = Vector2.zero; rectTransform.anchorMax = Vector2.one; rectTransform.offsetMin = Vector2.zero; rectTransform.offsetMax = Vector2.zero; ((Graphic)blackImage).color = new Color(0f, 0f, 0f, 0f); heartScale = Mathf.Max(2, Mathf.RoundToInt((float)Screen.height / 270f)); GameObject val = new GameObject("Heart"); val.transform.SetParent(overlayRoot.transform, false); heartImage = val.AddComponent(); heartImage.texture = (Texture)(object)ButItRefusedPlugin.HeartTex; ((Graphic)heartImage).raycastTarget = false; ((Graphic)heartImage).color = new Color(1f, 1f, 1f, 0f); heartRect = ((Graphic)heartImage).rectTransform; heartRect.anchorMin = Vector2.zero; heartRect.anchorMax = Vector2.zero; heartRect.pivot = new Vector2(0.5f, 0.5f); if (Object.op_Implicit((Object)(object)ButItRefusedPlugin.HeartTex)) { heartRect.sizeDelta = new Vector2((float)(((Texture)ButItRefusedPlugin.HeartTex).width * heartScale), (float)(((Texture)ButItRefusedPlugin.HeartTex).height * heartScale)); } heartRect.anchoredPosition = new Vector2((float)Screen.width * 0.5f, (float)Screen.height * 0.5f); GameObject val2 = new GameObject("HeartFlash"); val2.transform.SetParent(val.transform, false); heartFlashImage = val2.AddComponent(); heartFlashImage.texture = (Texture)(object)ButItRefusedPlugin.HeartWhiteTex; ((Graphic)heartFlashImage).raycastTarget = false; ((Graphic)heartFlashImage).color = new Color(1f, 1f, 1f, 0f); RectTransform rectTransform2 = ((Graphic)heartFlashImage).rectTransform; rectTransform2.anchorMin = Vector2.zero; rectTransform2.anchorMax = Vector2.one; rectTransform2.offsetMin = Vector2.zero; rectTransform2.offsetMax = Vector2.zero; textScale = Mathf.Max(2, Mathf.RoundToInt((float)Screen.height / 360f)); GameObject val3 = new GameObject("Text"); val3.transform.SetParent(overlayRoot.transform, false); textImage = val3.AddComponent(); textImage.texture = (Texture)(object)ButItRefusedPlugin.TextTex; ((Graphic)textImage).raycastTarget = false; ((Graphic)textImage).color = new Color(1f, 1f, 1f, 0f); textRect = ((Graphic)textImage).rectTransform; textRect.anchorMin = Vector2.zero; textRect.anchorMax = Vector2.zero; textRect.pivot = new Vector2(0f, 0.5f); textImage.uvRect = new Rect(0f, 0f, 0f, 1f); if (Object.op_Implicit((Object)(object)ButItRefusedPlugin.TextTex)) { textRect.sizeDelta = new Vector2(0f, (float)(((Texture)ButItRefusedPlugin.TextTex).height * textScale)); textRect.anchoredPosition = new Vector2((float)Screen.width * 0.5f - (float)(((Texture)ButItRefusedPlugin.TextTex).width * textScale) * 0.5f, (float)Screen.height * 0.5f - (float)Screen.height * 0.08f); } } private void RevealTextCharacters(int count) { //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)textImage) && !((Object)(object)ButItRefusedPlugin.TextTex == (Object)null)) { float num = ((Texture)ButItRefusedPlugin.TextTex).width; float num2 = Mathf.Clamp01(((count <= 0) ? 0f : Mathf.Min(TextCharBounds[Mathf.Min(count, TextCharBounds.Length) - 1], num)) / num); textImage.uvRect = new Rect(0f, 0f, num2, 1f); textRect.sizeDelta = new Vector2(num * (float)textScale * num2, textRect.sizeDelta.y); } } private static Image CreateChildImage(Transform parent, string name) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name); val.transform.SetParent(parent, false); Image obj = val.AddComponent(); ((Graphic)obj).raycastTarget = false; return obj; } private void SetHeartAlpha(float alpha) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)heartImage)) { ((Graphic)heartImage).color = new Color(1f, 1f, 1f, alpha); } } private void SetTextAlpha(float alpha) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)textImage)) { ((Graphic)textImage).color = new Color(1f, 1f, 1f, alpha); } } private void PulseHeart() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)heartRect) && pulseEnabled) { ((Transform)heartRect).localScale = Vector3.one * (1f + 0.045f * Mathf.Sin(Time.unscaledTime * 5.7f)); } } private void SetHeartTexture(Texture2D texture) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)heartImage) && !((Object)(object)texture == (Object)null)) { heartImage.texture = (Texture)(object)texture; heartRect.sizeDelta = new Vector2((float)(((Texture)texture).width * heartScale), (float)(((Texture)texture).height * heartScale)); } } private void CreateShards(Vector2 center) { //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0124: 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) DestroyShards(); Texture2D[] shardTexs = ButItRefusedPlugin.ShardTexs; if (shardTexs != null && !((Object)(object)shardTexs[0] == (Object)null) && Object.op_Implicit((Object)(object)overlayRoot)) { float[] array = new float[6] { 115f, 65f, 155f, 25f, 245f, 295f }; float[] array2 = new float[6] { 26f, 24f, 20f, 21f, 15f, 16f }; shardImages = (RawImage[])(object)new RawImage[array.Length]; shardDirections = (Vector2[])(object)new Vector2[array.Length]; shardDistances = new float[array.Length]; for (int i = 0; i < array.Length; i++) { GameObject val = new GameObject("Shard" + i); val.transform.SetParent(overlayRoot.transform, false); RawImage val2 = val.AddComponent(); val2.texture = (Texture)(object)shardTexs[i % shardTexs.Length]; ((Graphic)val2).raycastTarget = false; RectTransform rectTransform = ((Graphic)val2).rectTransform; rectTransform.anchorMin = Vector2.zero; rectTransform.anchorMax = Vector2.zero; rectTransform.pivot = new Vector2(0.5f, 0.5f); rectTransform.sizeDelta = new Vector2((float)(((Texture)shardTexs[0]).width * heartScale), (float)(((Texture)shardTexs[0]).height * heartScale)); rectTransform.anchoredPosition = center; float num = array[i] * (MathF.PI / 180f); shardDirections[i] = new Vector2(Mathf.Cos(num), Mathf.Sin(num)); shardDistances[i] = array2[i] * (float)heartScale; shardImages[i] = val2; } } } private void UpdateShards(Vector2 center, float spreadFactor, float animTime) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003f: 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_0053: Unknown result type (might be due to invalid IL or missing references) if (shardImages == null) { return; } Texture2D[] shardTexs = ButItRefusedPlugin.ShardTexs; int num = Mathf.FloorToInt(animTime * 12f); for (int i = 0; i < shardImages.Length; i++) { RawImage val = shardImages[i]; if (Object.op_Implicit((Object)(object)val)) { ((Graphic)val).rectTransform.anchoredPosition = center + shardDirections[i] * (shardDistances[i] * spreadFactor); if (shardTexs != null) { val.texture = (Texture)(object)shardTexs[(num + i) % shardTexs.Length]; } } } } private void CaptureShardPositions() { //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 (shardImages == null) { return; } shardFrozenPositions = (Vector2[])(object)new Vector2[shardImages.Length]; for (int i = 0; i < shardImages.Length; i++) { if (Object.op_Implicit((Object)(object)shardImages[i])) { shardFrozenPositions[i] = ((Graphic)shardImages[i]).rectTransform.anchoredPosition; } } } private void UpdateShardsConverge(Vector2 target, float progress, float animTime) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: 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) if (shardImages == null || shardFrozenPositions == null) { return; } Texture2D[] shardTexs = ButItRefusedPlugin.ShardTexs; int num = Mathf.FloorToInt(animTime * 12f); for (int i = 0; i < shardImages.Length; i++) { RawImage val = shardImages[i]; if (Object.op_Implicit((Object)(object)val)) { ((Graphic)val).rectTransform.anchoredPosition = Vector2.Lerp(shardFrozenPositions[i], target, progress); if (shardTexs != null) { val.texture = (Texture)(object)shardTexs[(num + i) % shardTexs.Length]; } } } } private void DestroyShards() { if (shardImages == null) { return; } RawImage[] array = shardImages; foreach (RawImage val in array) { if (Object.op_Implicit((Object)(object)val)) { Object.Destroy((Object)(object)((Component)val).gameObject); } } shardImages = null; shardFrozenPositions = null; } private void HandlePauseVisibility() { if (Object.op_Implicit((Object)(object)overlayGroup)) { overlayGroup.alpha = (PauseManager.isPaused ? 0.35f : 1f); } } private void TrackHeartToWorld(Vector3 worldPosition) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0024: 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_0044: Unknown result type (might be due to invalid IL or missing references) Camera sceneCamera = GetSceneCamera(); if (Object.op_Implicit((Object)(object)sceneCamera) && Object.op_Implicit((Object)(object)heartRect)) { Vector3 val = sceneCamera.WorldToScreenPoint(worldPosition); if (!(val.z <= 0f)) { heartRect.anchoredPosition = new Vector2(val.x, val.y); } } } private static Camera GetSceneCamera() { ReadOnlyCollection readOnlyInstancesList = CameraRigController.readOnlyInstancesList; if (readOnlyInstancesList != null && readOnlyInstancesList.Count > 0 && Object.op_Implicit((Object)(object)readOnlyInstancesList[0]) && Object.op_Implicit((Object)(object)readOnlyInstancesList[0].sceneCam)) { return readOnlyInstancesList[0].sceneCam; } return Camera.main; } private void StartMusic() { if (!ButItRefusedPlugin.MusicEnabled.Value || musicPlayer == null) { return; } string text = Path.Combine(ButItRefusedPlugin.AssetDir, "butitrefused_finale.mp3"); if (!File.Exists(text)) { ButItRefusedPlugin.Log.LogWarning((object)("Missing music file: " + text)); return; } try { musicPlayer.Play(text, ButItRefusedPlugin.MusicStartSeconds.Value); } catch (Exception ex) { ButItRefusedPlugin.Log.LogWarning((object)("Finale playback failed: " + ex)); return; } musicPlayed = 0f; musicPlayable = musicPlayer.PlayableSeconds; float num = ReadUserVolume("cvVolumeMaster") / 100f; float num2 = (musicRtpcAltered ? userMusicVolume : ReadUserVolume("cvVolumeMsx")) / 100f; musicUserScale = num * ((num2 <= 0f) ? 0f : Mathf.Lerp(0.45f, 1f, num2)); if (musicRoutine != null) { ((MonoBehaviour)this).StopCoroutine(musicRoutine); } musicRoutine = ((MonoBehaviour)this).StartCoroutine(MusicRoutine()); } private IEnumerator MusicRoutine() { float time = 0f; while (time < 2.5f && musicPlayer.IsPlaying) { if (!PauseManager.isPaused) { time += Time.unscaledDeltaTime; musicPlayed += Time.unscaledDeltaTime; } musicPlayer.Volume = Mathf.Clamp01(ButItRefusedPlugin.MusicVolume.Value) * 0.42f * musicUserScale * Mathf.Clamp01(time / 2.5f); yield return null; } while (musicPlayer.IsPlaying) { if (!PauseManager.isPaused) { musicPlayed += Time.unscaledDeltaTime; } float num = Mathf.Clamp01(MusicRemainingSeconds / 3f); musicPlayer.Volume = Mathf.Clamp01(ButItRefusedPlugin.MusicVolume.Value) * 0.42f * musicUserScale * num; yield return null; } musicPlayer.Stop(); SetMusicDuck(1f, 2.5f); musicRoutine = null; } private void SetMusicDuck(float fraction, float fadeSeconds) { if ((!(fraction < 1f) || ButItRefusedPlugin.DuckGameMusic.Value) && (!(fraction >= 1f) || musicRtpcAltered)) { if (!musicRtpcAltered) { userMusicVolume = ReadUserVolume("cvVolumeMsx"); currentMusicRtpc = userMusicVolume; } musicRtpcAltered = fraction < 1f; if (rtpcRoutine != null) { ((MonoBehaviour)this).StopCoroutine(rtpcRoutine); } rtpcRoutine = ((MonoBehaviour)this).StartCoroutine(FadeRtpc("Volume_MSX", currentMusicRtpc, userMusicVolume * fraction, fadeSeconds, delegate(float value) { currentMusicRtpc = value; })); } } private void SetSfxDuck(float fraction, float fadeSeconds) { if ((!(fraction < 1f) || ButItRefusedPlugin.MuteGameSounds.Value) && (!(fraction >= 1f) || sfxRtpcAltered)) { if (!sfxRtpcAltered) { userSfxVolume = ReadUserVolume("cvVolumeSfx"); currentSfxRtpc = userSfxVolume; } sfxRtpcAltered = fraction < 1f; if (sfxRtpcRoutine != null) { ((MonoBehaviour)this).StopCoroutine(sfxRtpcRoutine); } sfxRtpcRoutine = ((MonoBehaviour)this).StartCoroutine(FadeRtpc("Volume_SFX", currentSfxRtpc, userSfxVolume * fraction, fadeSeconds, delegate(float value) { currentSfxRtpc = value; })); } } private IEnumerator FadeRtpc(string rtpcName, float from, float to, float duration, Action track) { float time = 0f; while (time < duration) { time += Time.unscaledDeltaTime; float num = Mathf.Lerp(from, to, Mathf.Clamp01(time / duration)); SetRtpc(rtpcName, num); track(num); yield return null; } SetRtpc(rtpcName, to); track(to); } private static void SetRtpc(string rtpcName, float value) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) try { AkSoundEngine.SetRTPCValue(rtpcName, value); } catch { } } private static float ReadUserVolume(string conVarFieldName) { try { object? obj = typeof(AudioManager).GetField(conVarFieldName, BindingFlags.Static | BindingFlags.NonPublic)?.GetValue(null); object? obj2 = ((obj is BaseConVar) ? obj : null); string text = ((obj2 != null) ? ((BaseConVar)obj2).GetString() : null); if (!string.IsNullOrEmpty(text) && float.TryParse(text, NumberStyles.Float, CultureInfo.InvariantCulture, out var result)) { return Mathf.Clamp(result, 0f, 100f); } } catch { } return 100f; } } internal sealed class MusicPlayer : IDisposable { private sealed class GuardedSampleProvider : ISampleProvider { private readonly ISampleProvider inner; public WaveFormat WaveFormat => inner.WaveFormat; public GuardedSampleProvider(ISampleProvider inner) { this.inner = inner; } public int Read(float[] buffer, int offset, int count) { try { return inner.Read(buffer, offset, count); } catch (ObjectDisposedException) { return 0; } catch (NullReferenceException) { return 0; } } } [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static FrameDecompressorBuilder <>9__15_0; internal IMp3FrameDecompressor b__15_0(WaveFormat waveFormat) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown return (IMp3FrameDecompressor)new AcmMp3FrameDecompressor(waveFormat); } } private static readonly List LiveOutputs = new List(); private static readonly object OutputsLock = new object(); private WaveOutEvent output; private WaveStream reader; private VolumeSampleProvider volumeProvider; public bool IsPlaying { get { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Invalid comparison between Unknown and I4 //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Invalid comparison between Unknown and I4 try { if (output == null) { return false; } PlaybackState playbackState = output.PlaybackState; return (int)playbackState == 1 || (int)playbackState == 2; } catch { return false; } } } public float Volume { set { VolumeSampleProvider val = volumeProvider; if (val != null) { val.Volume = Mathf.Clamp01(value); } } } public float PlayableSeconds { get; private set; } internal static void StopEverything() { WaveOutEvent[] array; lock (OutputsLock) { array = LiveOutputs.ToArray(); LiveOutputs.Clear(); } WaveOutEvent[] array2 = array; foreach (WaveOutEvent val in array2) { try { val.Stop(); } catch { } try { val.Dispose(); } catch { } } } public void SetPaused(bool paused) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Invalid comparison between Unknown and I4 //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Invalid comparison between Unknown and I4 try { if (output != null) { if (paused && (int)output.PlaybackState == 1) { output.Pause(); } else if (!paused && (int)output.PlaybackState == 2) { output.Play(); } } } catch { } } private static WaveStream CreateReader(string path) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Expected O, but got Unknown //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown if (!path.EndsWith(".wav", StringComparison.OrdinalIgnoreCase)) { object obj = <>c.<>9__15_0; if (obj == null) { FrameDecompressorBuilder val = (WaveFormat waveFormat) => (IMp3FrameDecompressor)new AcmMp3FrameDecompressor(waveFormat); <>c.<>9__15_0 = val; obj = (object)val; } return (WaveStream)new Mp3FileReaderBase(path, (FrameDecompressorBuilder)obj); } return (WaveStream)new WaveFileReader(path); } public void Play(string path, float startSeconds, float initialVolume = 0f) { //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Expected O, but got Unknown //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Expected O, but got Unknown //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Expected O, but got Unknown Stop(); reader = CreateReader(path); if (startSeconds <= 0f && reader.TotalTime.TotalSeconds > 80.0) { startSeconds = 58f; } if (startSeconds > 0f) { double val = Math.Max(0.0, reader.TotalTime.TotalSeconds - 1.0); reader.CurrentTime = TimeSpan.FromSeconds(Math.Min(Math.Max(startSeconds, 0f), val)); } PlayableSeconds = (float)Math.Max(0.0, (reader.TotalTime - reader.CurrentTime).TotalSeconds); volumeProvider = new VolumeSampleProvider(WaveExtensionMethods.ToSampleProvider((IWaveProvider)(object)reader)) { Volume = Mathf.Clamp01(initialVolume) }; output = new WaveOutEvent { DesiredLatency = 200 }; output.Init((IWaveProvider)new SampleToWaveProvider((ISampleProvider)(object)new GuardedSampleProvider((ISampleProvider)(object)volumeProvider))); lock (OutputsLock) { LiveOutputs.Add(output); } string trackName = Path.GetFileName(path); output.PlaybackStopped += delegate(object s, StoppedEventArgs a) { if (a.Exception == null) { return; } try { ButItRefusedPlugin.Log.LogWarning((object)(trackName + " playback stopped: " + a.Exception.Message)); } catch { } }; output.Play(); } public void Stop() { WaveOutEvent val = output; output = null; if (val != null) { lock (OutputsLock) { LiveOutputs.Remove(val); } try { val.Stop(); } catch { } try { val.Dispose(); } catch { } } try { ((Stream)(object)reader)?.Dispose(); } catch { } reader = null; volumeProvider = null; } public void Dispose() { Stop(); } } internal static class RiskOfOptionsCompat { internal static bool Available => Chainloader.PluginInfos.ContainsKey("com.rune580.riskofoptions"); [MethodImpl(MethodImplOptions.NoInlining)] internal static void Init() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Expected O, but got Unknown //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Expected O, but got Unknown //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_0081: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Expected O, but got Unknown //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Expected O, but got Unknown //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Expected O, but got Unknown //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Expected O, but got Unknown //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Expected O, but got Unknown //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: 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_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Expected O, but got Unknown //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Expected O, but got Unknown //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Expected O, but got Unknown //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Expected O, but got Unknown //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Expected O, but got Unknown ModSettingsManager.SetModDescription("Undertale second chance: when an item revives you, the screen fades to black, your SOUL refuses, and Finale plays."); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(ButItRefusedPlugin.Enabled)); ModSettingsManager.AddOption((BaseOption)new StepSliderOption(ButItRefusedPlugin.DurationScale, new StepSliderConfig { min = 0.5f, max = 2f, increment = 0.05f })); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(ButItRefusedPlugin.TriggerOnShrineAndSkillRevives)); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(ButItRefusedPlugin.MusicEnabled)); ModSettingsManager.AddOption((BaseOption)new StepSliderOption(ButItRefusedPlugin.MusicVolume, new StepSliderConfig { min = 0f, max = 1f, increment = 0.05f })); ModSettingsManager.AddOption((BaseOption)new FloatFieldOption(ButItRefusedPlugin.MusicStartSeconds)); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(ButItRefusedPlugin.DuckGameMusic)); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(ButItRefusedPlugin.MuteGameSounds)); ModSettingsManager.AddOption((BaseOption)new StepSliderOption(ButItRefusedPlugin.SfxVolume, new StepSliderConfig { min = 0f, max = 1f, increment = 0.05f })); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(ButItRefusedPlugin.AuraEnabled)); ModSettingsManager.AddOption((BaseOption)new StepSliderOption(ButItRefusedPlugin.AuraIntensity, new StepSliderConfig { min = 0f, max = 6f, increment = 0.1f })); } } }