using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using HarmonyLib;
using Peak;
using Photon.Pun;
using Photon.Realtime;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.Networking;
using UnityEngine.SceneManagement;
using Zorro.Core;
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: CompilationRelaxations(8)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace PeakSoundtrackRemastered;
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInPlugin("local.peaksoundtrackremastered", "PEAKsoundtrack remastered", "0.1.5")]
public sealed class Plugin : BaseUnityPlugin
{
internal static Plugin Instance;
private readonly ScoreRules rules = new ScoreRules();
private readonly FallCue fallCue = new FallCue();
private AudioSource meme;
private float lastMeme = -100f;
private float lastWarning = -100f;
private readonly Dictionary<Track, float> resumeTimes = new Dictionary<Track, float>();
private readonly Dictionary<Track, AudioClip> clips = new Dictionary<Track, AudioClip>();
private readonly Dictionary<AudioSource, bool> muted = new Dictionary<AudioSource, bool>();
private readonly HashSet<GhostBall> resolvedGhosts = new HashSet<GhostBall>();
private readonly FieldInfo tornadoCaught = AccessTools.Field(typeof(Tornado), "caughtCharacters");
private readonly FieldInfo ghostHealth = AccessTools.Field(typeof(GhostBall), "burnHealth");
private readonly MethodInfo checkReached = AccessTools.Method(typeof(MountainProgressHandler), "CheckReached", (Type[])null, (Type[])null);
private readonly MethodInfo spawnTornado = AccessTools.Method(typeof(TornadoSpawner), "SpawnTornado", (Type[])null, (Type[])null);
private float nextTestSpawn;
private float noticeUntil;
private string notice = "";
private ConfigEntry<float> volume;
private ConfigEntry<float> fadeSeconds;
private ConfigEntry<bool> enabledMusic;
private ConfigEntry<bool> duckMusic;
private AudioSource source;
private AudioSource tail;
private float tailStart;
private float tailVolume;
private Track tailTrack;
private PropertyInfo afterglowProperty;
private bool lastDead;
private Harmony harmony;
private Character tracked;
private MapHandler trackedMap;
private Track playing;
private bool loaded;
private bool fading;
private bool failed;
private float fadeStart;
private float fadeVolume;
private float nextPoll;
private float nextDuck;
private string root;
private string region = "";
private int dustCount;
private int ghostCount;
private void Awake()
{
//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
//IL_01b5: Expected O, but got Unknown
Instance = this;
root = Path.GetDirectoryName(typeof(Plugin).Assembly.Location);
enabledMusic = ((BaseUnityPlugin)this).Config.Bind<bool>("Music", "Enabled", true, "Enable this local soundtrack.");
volume = ((BaseUnityPlugin)this).Config.Bind<float>("Music", "Volume", 0.65f, "Local soundtrack volume, 0 to 1.");
fadeSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Music", "FadeSeconds", 2f, "Fade after a flare, defeated ghost, departing biome, or leaving a dust devil.");
duckMusic = ((BaseUnityPlugin)this).Config.Bind<bool>("Music", "QuietVanillaMusic", true, "Temporarily mute known vanilla music sources while a replacement track plays. Voice and game effects are untouched.");
try
{
if (tornadoCaught == null || ghostHealth == null || checkReached == null)
{
throw new MissingMemberException("Required game event fields are missing.");
}
source = ((Component)this).gameObject.AddComponent<AudioSource>();
source.playOnAwake = false;
source.spatialBlend = 0f;
source.priority = 64;
tail = ((Component)this).gameObject.AddComponent<AudioSource>();
tail.playOnAwake = false;
tail.spatialBlend = 0f;
tail.priority = 64;
meme = ((Component)this).gameObject.AddComponent<AudioSource>();
meme.playOnAwake = false;
meme.spatialBlend = 0f;
meme.priority = 60;
SceneManager.sceneLoaded += SceneLoaded;
harmony = new Harmony("local.peaksoundtrackremastered");
harmony.PatchAll(typeof(Plugin).Assembly);
((MonoBehaviour)this).StartCoroutine(LoadTracks());
Log("0.1.5 loaded. Local soundtrack; Lost Girl plays for a lone summit arrival.");
}
catch (Exception error)
{
Fail(error);
}
}
private void Log(string message)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)message);
try
{
File.AppendAllText(Path.Combine(root, "soundtrack-diagnostics.log"), DateTime.UtcNow.ToString("o") + " " + message + Environment.NewLine);
}
catch
{
}
}
private IEnumerator LoadTracks()
{
try
{
Track[] array = new Track[14]
{
Track.DustDevils,
Track.Summit,
Track.Nadir,
Track.Ghost,
Track.Citadel,
Track.NadirAmbient,
Track.Finale,
Track.Credits,
Track.Spectating,
Track.Airport,
Track.LoneSummit,
Track.Falling,
Track.Rising,
Track.ScoutChase
};
foreach (Track track in array)
{
string path = Path.Combine(root, "assets/" + track.ToString() + ".wav");
UnityWebRequest request = UnityWebRequestMultimedia.GetAudioClip(new Uri(path).AbsoluteUri, (AudioType)20);
try
{
((DownloadHandlerAudioClip)request.downloadHandler).streamAudio = true;
yield return request.SendWebRequest();
if ((int)request.result != 1)
{
Log(string.Concat("Cannot load ", track, ": ", request.error));
continue;
}
AudioClip clip = DownloadHandlerAudioClip.GetContent(request);
if ((Object)(object)clip == (Object)null || clip.length <= ScoreRules.StartSeconds(track) + 0.1f)
{
Log("Track missing or too short for offset: " + track);
if ((Object)(object)clip != (Object)null)
{
Object.Destroy((Object)(object)clip);
}
continue;
}
clips[track] = clip;
Log(string.Concat("Loaded ", track, ", ", clip.length.ToString("F1"), "s, starts at ", ScoreRules.StartSeconds(track), "s."));
}
finally
{
((IDisposable)request)?.Dispose();
}
}
}
finally
{
}
loaded = true;
}
private bool LocalAlive(Character c)
{
if ((Object)(object)c != (Object)null && (Object)(object)c.data != (Object)null && c.IsLocal && (Object)(object)((MonoBehaviourPun)c).photonView != (Object)null && ((MonoBehaviourPun)c).photonView.IsMine && !c.data.dead)
{
return !c.isBot;
}
return false;
}
private void Update()
{
if (failed)
{
return;
}
try
{
CheckTestKey();
if (!enabledMusic.Value)
{
StopAll();
fallCue.Reset();
rules.RisingWarning = false;
return;
}
UpdateFallCue();
if (Time.unscaledTime >= nextPoll)
{
nextPoll = Time.unscaledTime + 0.25f;
Poll();
}
UpdateTail();
if ((Object)(object)source == (Object)null || playing == Track.None)
{
if ((Object)(object)tail != (Object)null && tail.isPlaying && duckMusic.Value)
{
QuietVanilla();
}
return;
}
if (fading)
{
source.volume = fadeVolume * ScoreRules.FadeGain(Time.unscaledTime - fadeStart, Mathf.Max(0.05f, fadeSeconds.Value));
if (source.volume <= 0.0001f)
{
StopNow();
return;
}
}
else
{
source.volume = Mathf.Clamp01(volume.Value);
}
if (!source.isPlaying && !AudioListener.pause)
{
rules.Finished(playing);
resumeTimes.Remove(playing);
StopNow();
nextPoll = 0f;
}
else if (!duckMusic.Value)
{
RestoreVanilla();
}
else if (Time.unscaledTime >= nextDuck)
{
nextDuck = Time.unscaledTime + 0.5f;
QuietVanilla();
}
}
catch (Exception error)
{
Fail(error);
}
}
private void Notice(string text)
{
notice = text;
noticeUntil = Time.unscaledTime + 4f;
Log(text);
}
private void CheckTestKey()
{
//IL_014c: Unknown result type (might be due to invalid IL or missing references)
//IL_0152: Unknown result type (might be due to invalid IL or missing references)
//IL_0157: Unknown result type (might be due to invalid IL or missing references)
//IL_015c: Unknown result type (might be due to invalid IL or missing references)
Keyboard current = Keyboard.current;
if (current == null || !Application.isFocused || (!((ButtonControl)current.digit6Key).wasPressedThisFrame && !((ButtonControl)current.numpad6Key).wasPressedThisFrame) || (Object)(object)GUIManager.instance == (Object)null || GUIManager.instance.windowBlockingInput || GUIManager.instance.wheelActive)
{
return;
}
Character localCharacter = Character.localCharacter;
MapHandler instance = Singleton<MapHandler>.Instance;
if (!PhotonNetwork.InRoom || !LocalAlive(localCharacter) || !localCharacter.data.fullyConscious || (Object)(object)instance == (Object)null)
{
Notice("Dust-devil test: enter a round as a conscious scout.");
}
else if (!PhotonNetwork.IsMasterClient)
{
Notice("Dust-devil test: only the host can spawn one.");
}
else if (CurrentRegion(localCharacter, instance) != "MESA")
{
Notice("Dust-devil test: you must be in Mesa.");
}
else
{
if (Time.unscaledTime < nextTestSpawn)
{
return;
}
TornadoSpawner val = null;
float num = float.PositiveInfinity;
TornadoSpawner[] array = Object.FindObjectsByType<TornadoSpawner>((FindObjectsSortMode)0);
foreach (TornadoSpawner val2 in array)
{
if ((Object)(object)val2 == (Object)null || !((Behaviour)val2).isActiveAndEnabled)
{
continue;
}
PhotonView component = ((Component)val2).GetComponent<PhotonView>();
Transform val3 = ((Component)val2).transform.Find("TornadoPoints");
if (!((Object)(object)component == (Object)null) && component.ViewID != 0 && !((Object)(object)val3 == (Object)null) && val3.childCount != 0)
{
Vector3 val4 = ((Component)val2).transform.position - localCharacter.Center;
float sqrMagnitude = ((Vector3)(ref val4)).sqrMagnitude;
if (sqrMagnitude < num)
{
num = sqrMagnitude;
val = val2;
}
}
}
if (!((Object)(object)val == (Object)null) && !(spawnTornado == null))
{
nextTestSpawn = Time.unscaledTime + 1f;
try
{
spawnTornado.Invoke(val, null);
nextPoll = 0f;
Notice("Dust devil spawned at a vanilla Mesa spawn point. Everyone can see it.");
return;
}
catch (Exception ex)
{
Notice("Dust-devil test failed: " + ex.GetBaseException().Message);
return;
}
}
Notice("Dust-devil test: no active Mesa spawner with valid spawn points.");
}
}
private void OnGUI()
{
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
if (!(Time.unscaledTime >= noticeUntil))
{
GUI.Box(new Rect((float)Screen.width / 2f - 300f, 35f, 600f, 60f), notice);
}
}
private string CurrentRegion(Character c, MapHandler map)
{
//IL_009f: Unknown result type (might be due to invalid IL or missing references)
//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
//IL_00a8: Invalid comparison between Unknown and I4
//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
//IL_00b2: Invalid comparison between Unknown and I4
//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
if (VoidBiome.VoidBiomeActive)
{
return "NADIR";
}
MountainProgressHandler instance = Singleton<MountainProgressHandler>.Instance;
if ((Object)(object)instance != (Object)null && instance.progressPoints != null)
{
for (int num = instance.progressPoints.Length - 1; num >= 0; num--)
{
ProgressPoint val = instance.progressPoints[num];
if (val != null && (Object)(object)val.transform != (Object)null && (bool)checkReached.Invoke(instance, new object[1] { val }))
{
return (val.title ?? "").Trim().ToUpperInvariant();
}
}
}
if ((Object)(object)map == (Object)null)
{
return "";
}
BiomeType currentBiome = map.GetCurrentBiome();
if ((int)currentBiome == 17)
{
return "NADIR";
}
if ((int)currentBiome == 8)
{
return "GLOOM";
}
return ((object)currentBiome).ToString().ToUpperInvariant();
}
private void Poll()
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0314: Unknown result type (might be due to invalid IL or missing references)
//IL_031a: Unknown result type (might be due to invalid IL or missing references)
Character localCharacter = Character.localCharacter;
MapHandler instance = Singleton<MapHandler>.Instance;
Scene activeScene = SceneManager.GetActiveScene();
if (((Scene)(ref activeScene)).name == "Airport")
{
if (region != "AIRPORT")
{
ResetSession();
region = "AIRPORT";
}
if (loaded)
{
Apply(rules.Select("AIRPORT", alive: true, CountCaptured(localCharacter), 0));
}
return;
}
if (region == "AIRPORT")
{
ResetSession();
}
if (!PhotonNetwork.InRoom)
{
ResetSession();
return;
}
if (rules.InCredits || rules.FinalCutscene)
{
if (loaded)
{
Apply(rules.Select(region, alive: true, 0, 0));
}
return;
}
if ((Object)(object)localCharacter == (Object)null || (Object)(object)instance == (Object)null)
{
ResetSession();
return;
}
if ((Object)(object)tracked != (Object)(object)localCharacter || (Object)(object)trackedMap != (Object)(object)instance)
{
ResetSession();
tracked = localCharacter;
trackedMap = instance;
}
if (!loaded || (Object)(object)localCharacter.data == (Object)null)
{
return;
}
bool dead = localCharacter.data.dead;
if (dead != lastDead)
{
lastDead = dead;
resumeTimes.Clear();
if (dead)
{
Log("Waiting for AFTERGLOW and spectating.");
}
}
if (dead)
{
meme.Stop();
Apply(rules.Select(region, alive: false, 0, 0, AfterglowShowing(), localCharacter.data.deathTimer >= 5f));
return;
}
if (!LocalAlive(localCharacter))
{
BeginFade();
return;
}
string text = CurrentRegion(localCharacter, instance);
if (region != text)
{
resumeTimes.Clear();
region = text;
Log("Local region: " + region);
}
dustCount = 0;
ghostCount = 0;
resolvedGhosts.RemoveWhere((GhostBall g) => (Object)(object)g == (Object)null);
dustCount = CountCaptured(localCharacter);
if (region == "GLOOM")
{
GhostBall[] array = Object.FindObjectsByType<GhostBall>((FindObjectsSortMode)0);
foreach (GhostBall val in array)
{
if ((Object)(object)val != (Object)null && ((Behaviour)val).isActiveAndEnabled && !resolvedGhosts.Contains(val) && (float)ghostHealth.GetValue(val) > 0f)
{
ghostCount++;
}
}
}
bool scoutPresent = rules.ScoutPresent;
rules.ScoutPresent = false;
Scoutmaster[] array2 = Object.FindObjectsByType<Scoutmaster>((FindObjectsSortMode)0);
foreach (Scoutmaster val2 in array2)
{
if ((Object)(object)val2 != (Object)null && ((Behaviour)val2).isActiveAndEnabled && (Object)(object)val2.currentTarget == (Object)(object)localCharacter && Vector3.Distance(((Component)val2).transform.position, localCharacter.Center) < 50f)
{
rules.ScoutPresent = true;
break;
}
}
if (scoutPresent && !rules.ScoutPresent)
{
resumeTimes.Remove(Track.ScoutChase);
}
Apply(rules.Select(region, alive: true, dustCount, ghostCount, afterglow: false, spectating: false, region == "PEAK" && AloneAmongSurvivors(localCharacter)));
}
private void UpdateFallCue()
{
Character localCharacter = Character.localCharacter;
bool flag = PhotonNetwork.InRoom && LocalAlive(localCharacter) && !localCharacter.warping && !localCharacter.data.isClimbingAnything && !localCharacter.data.isInWater && !localCharacter.data.isCarried;
if (fallCue.Step(flag, !flag || localCharacter.data.isGrounded, flag ? localCharacter.data.avarageVelocity.y : 0f, Time.deltaTime))
{
PlayMeme();
}
if ((Object)(object)meme != (Object)null)
{
meme.volume = Mathf.Clamp01(volume.Value);
if (!flag && !LocalAlive(localCharacter))
{
meme.Stop();
}
}
}
internal void PlayMeme()
{
if (!failed && enabledMusic.Value && loaded && PhotonNetwork.InRoom && LocalAlive(Character.localCharacter) && !rules.FinalCutscene && !rules.InCredits && clips.TryGetValue(Track.Falling, out var value) && !meme.isPlaying && !(Time.unscaledTime - lastMeme < 1f))
{
lastMeme = Time.unscaledTime;
meme.clip = value;
meme.loop = false;
meme.volume = Mathf.Clamp01(volume.Value);
meme.Play();
Log("Let Me Know triggered.");
}
}
internal void BugleUsed(Action_CallScoutmaster action)
{
Item val = (((Object)(object)action == (Object)null) ? null : ((Component)action).GetComponent<Item>());
if ((Object)(object)val != (Object)null && (Object)(object)val.holderCharacter == (Object)(object)Character.localCharacter)
{
PlayMeme();
}
}
internal void HazardWarning()
{
if (!failed && enabledMusic.Value && PhotonNetwork.InRoom && LocalAlive(Character.localCharacter) && !rules.FinalCutscene && !rules.InCredits && !(Time.unscaledTime - lastWarning < 5f))
{
lastWarning = Time.unscaledTime;
rules.RisingWarning = true;
nextPoll = 0f;
Log("Rising-hazard warning received.");
}
}
private bool AloneAmongSurvivors(Character local)
{
if (!LocalAlive(local) || !PhotonNetwork.InRoom)
{
return false;
}
Player[] playerList = PhotonNetwork.PlayerList;
foreach (Player val in playerList)
{
if (val == null || val.IsLocal || val.IsInactive)
{
continue;
}
bool flag = false;
foreach (Character allCharacter in Character.AllCharacters)
{
if (!((Object)(object)allCharacter == (Object)null) && !allCharacter.isBot && !((Object)(object)((MonoBehaviourPun)allCharacter).photonView == (Object)null) && ((MonoBehaviourPun)allCharacter).photonView.OwnerActorNr == val.ActorNumber)
{
flag = true;
if (!allCharacter.IsInitialized || (Object)(object)allCharacter.data == (Object)null || !allCharacter.data.dead)
{
return false;
}
}
}
if (!flag)
{
return false;
}
}
return true;
}
private int CountCaptured(Character c)
{
if (!LocalAlive(c))
{
return 0;
}
int num = 0;
Tornado[] array = Object.FindObjectsByType<Tornado>((FindObjectsSortMode)0);
foreach (Tornado val in array)
{
if (!((Object)(object)val == (Object)null) && ((Behaviour)val).isActiveAndEnabled && tornadoCaught.GetValue(val) is List<Character> list && list.Contains(c))
{
num++;
}
}
return num;
}
private void Apply(Track wanted)
{
if (wanted == Track.None)
{
BeginFade();
}
else if (wanted == playing)
{
if (fading)
{
fading = false;
source.volume = Mathf.Clamp01(volume.Value);
}
}
else
{
Play(wanted);
}
}
private void Play(Track track)
{
if (clips.TryGetValue(track, out var value))
{
tail.Stop();
if (source.isPlaying)
{
tail.clip = source.clip;
tail.loop = source.loop;
tail.time = source.time;
tail.volume = source.volume;
tailVolume = source.volume;
tailStart = Time.unscaledTime;
tailTrack = playing;
tail.Play();
}
if ((track == Track.Rising || track == Track.ScoutChase) && playing != Track.None && playing != Track.ScoutChase && source.isPlaying && !fading)
{
resumeTimes[playing] = source.time;
}
source.Stop();
fading = false;
playing = track;
source.clip = value;
source.loop = ScoreRules.Loops(track);
source.volume = Mathf.Clamp01(volume.Value);
source.time = ((resumeTimes.TryGetValue(track, out var value2) && value2 < value.length - 0.1f) ? value2 : ScoreRules.StartSeconds(track));
source.Play();
nextDuck = 0f;
Log(string.Concat("Playing ", track, " from ", ScoreRules.StartSeconds(track), "s."));
}
}
private void BeginFade()
{
if (playing != Track.None && !fading)
{
fading = true;
fadeStart = Time.unscaledTime;
fadeVolume = source.volume;
Log(string.Concat("Fading ", playing, "."));
}
}
private void StopNow()
{
if ((Object)(object)source != (Object)null)
{
source.Stop();
}
playing = Track.None;
fading = false;
if ((Object)(object)tail == (Object)null || !tail.isPlaying)
{
RestoreVanilla();
}
}
private void StopAll()
{
if ((Object)(object)meme != (Object)null)
{
meme.Stop();
}
if ((Object)(object)tail != (Object)null)
{
tail.Stop();
}
StopNow();
}
private void UpdateTail()
{
if ((Object)(object)tail == (Object)null || !tail.isPlaying)
{
return;
}
tail.volume = tailVolume * ScoreRules.FadeGain(Time.unscaledTime - tailStart, Mathf.Max(0.05f, fadeSeconds.Value));
if (tail.volume <= 0.0001f)
{
tail.Stop();
if (playing == Track.None)
{
RestoreVanilla();
}
}
}
private void SceneLoaded(Scene scene, LoadSceneMode mode)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
if ((int)mode == 0)
{
ResetSession();
}
}
private bool AfterglowShowing()
{
if (!Chainloader.PluginInfos.TryGetValue("local.entitiesplus", out var value) || (Object)(object)value.Instance == (Object)null)
{
return false;
}
if (afterglowProperty == null)
{
afterglowProperty = AccessTools.Property(((object)value.Instance).GetType(), "DeathShowing");
}
if (afterglowProperty != null)
{
return (bool)afterglowProperty.GetValue(null, null);
}
return false;
}
internal void EndingEvent(int stage)
{
if (failed || !PhotonNetwork.InRoom)
{
return;
}
if (stage == 1)
{
rules.NadirWon = true;
Log("Nadir completed; fading its music.");
if (playing == Track.Nadir || playing == Track.NadirAmbient)
{
BeginFade();
}
}
if (stage == 2)
{
rules.NadirWon = true;
rules.FinalCutscene = true;
Log("Post-Nadir final cutscene.");
}
if (stage == 3)
{
rules.InCredits = true;
Log("Credits started.");
}
nextPoll = 0f;
}
private void ResetSession()
{
StopAll();
fallCue.Reset();
resumeTimes.Clear();
lastMeme = (lastWarning = -100f);
lastDead = false;
rules.Reset();
tracked = null;
trackedMap = null;
region = "";
resolvedGhosts.Clear();
dustCount = (ghostCount = 0);
}
internal void GhostEnded(GhostBall ghost)
{
if (!failed && !((Object)(object)ghost == (Object)null))
{
resolvedGhosts.Add(ghost);
nextPoll = 0f;
}
}
internal void FlareLit()
{
if (!failed && LocalAlive(Character.localCharacter) && (playing == Track.Summit || playing == Track.LoneSummit || region == "PEAK"))
{
rules.FlareLit();
if (playing == Track.Summit || playing == Track.LoneSummit)
{
BeginFade();
}
}
}
private void Quiet(AudioSource audio)
{
if (!((Object)(object)audio == (Object)null) && !((Object)(object)audio == (Object)(object)source) && !((Object)(object)audio == (Object)(object)tail) && !((Object)(object)audio == (Object)(object)meme))
{
if (!muted.ContainsKey(audio))
{
muted[audio] = audio.mute;
}
audio.mute = true;
}
}
private void QuietRoot(GameObject obj)
{
if ((Object)(object)obj != (Object)null)
{
AudioSource[] componentsInChildren = obj.GetComponentsInChildren<AudioSource>(true);
foreach (AudioSource audio in componentsInChildren)
{
Quiet(audio);
}
}
}
private void QuietVanilla()
{
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
if (region == "AIRPORT")
{
AudioSource[] array = Object.FindObjectsByType<AudioSource>((FindObjectsSortMode)0);
foreach (AudioSource val in array)
{
Scene scene = ((Component)val).gameObject.scene;
if (((Scene)(ref scene)).name == "Airport" && (Object)(object)val.outputAudioMixerGroup != (Object)null && ((Object)val.outputAudioMixerGroup).name.IndexOf("music", StringComparison.OrdinalIgnoreCase) >= 0)
{
Quiet(val);
}
}
}
AmbienceAudio[] array2 = Object.FindObjectsByType<AmbienceAudio>((FindObjectsSortMode)0);
foreach (AmbienceAudio val2 in array2)
{
Quiet(val2.mainMusic);
}
BiomeMusicCheck[] array3 = Object.FindObjectsByType<BiomeMusicCheck>((FindObjectsSortMode)0);
foreach (BiomeMusicCheck val3 in array3)
{
QuietRoot(val3.regularMusic);
QuietRoot(val3.mesaMusic);
}
MyresAmbience[] array4 = Object.FindObjectsByType<MyresAmbience>((FindObjectsSortMode)0);
foreach (MyresAmbience val4 in array4)
{
Quiet(val4.fearMusic);
}
if (region == "NADIR" && !rules.NadirWon)
{
ScoutmasterSoulPillar[] array5 = Object.FindObjectsByType<ScoutmasterSoulPillar>((FindObjectsSortMode)0);
foreach (ScoutmasterSoulPillar val5 in array5)
{
Quiet(val5.music);
}
}
PeakHandler instance = Singleton<PeakHandler>.Instance;
if ((Object)(object)instance != (Object)null && (rules.FinalCutscene || rules.InCredits))
{
QuietCutsceneMusic(instance.endCutscene);
QuietCutsceneMusic(instance.endCutsceneFinal);
QuietCutsceneMusic(instance.endCutsceneFinalSpecialDay);
}
Type type = AccessTools.TypeByName("DeathTunes.DeathTunesPlugin");
PropertyInfo propertyInfo = ((type == null) ? null : AccessTools.Property(type, "AudioSource"));
if (propertyInfo != null && propertyInfo.GetGetMethod(nonPublic: true) != null && propertyInfo.GetGetMethod(nonPublic: true).IsStatic)
{
object? value = propertyInfo.GetValue(null, null);
AudioSource val6 = (AudioSource)((value is AudioSource) ? value : null);
if (playing == Track.Spectating || ((Object)(object)tail != (Object)null && tail.isPlaying && tailTrack == Track.Spectating))
{
Quiet(val6);
}
else if ((Object)(object)val6 != (Object)null && muted.ContainsKey(val6))
{
val6.mute = muted[val6];
muted.Remove(val6);
}
}
}
private void QuietCutsceneMusic(GameObject obj)
{
if ((Object)(object)obj == (Object)null)
{
return;
}
AudioSource[] componentsInChildren = obj.GetComponentsInChildren<AudioSource>(true);
foreach (AudioSource val in componentsInChildren)
{
if ((Object)(object)val.outputAudioMixerGroup != (Object)null && ((Object)val.outputAudioMixerGroup).name.IndexOf("music", StringComparison.OrdinalIgnoreCase) >= 0)
{
Quiet(val);
}
}
}
private void RestoreVanilla()
{
foreach (KeyValuePair<AudioSource, bool> item in muted)
{
if ((Object)(object)item.Key != (Object)null)
{
item.Key.mute = item.Value;
}
}
muted.Clear();
}
private void Fail(Exception error)
{
Log("Soundtrack disabled after error: " + error);
failed = true;
StopAll();
if (harmony != null)
{
harmony.UnpatchSelf();
}
}
private void OnDisable()
{
StopAll();
}
private void OnDestroy()
{
SceneManager.sceneLoaded -= SceneLoaded;
StopAll();
((MonoBehaviour)this).StopAllCoroutines();
if (harmony != null)
{
harmony.UnpatchSelf();
}
foreach (AudioClip value in clips.Values)
{
if ((Object)(object)value != (Object)null)
{
Object.Destroy((Object)(object)value);
}
}
if ((Object)(object)source != (Object)null)
{
Object.Destroy((Object)(object)source);
}
if ((Object)(object)tail != (Object)null)
{
Object.Destroy((Object)(object)tail);
}
if ((Object)(object)meme != (Object)null)
{
Object.Destroy((Object)(object)meme);
}
if ((Object)(object)Instance == (Object)(object)this)
{
Instance = null;
}
}
}
[HarmonyPatch(typeof(Action_CallScoutmaster), "RunAction")]
internal static class BugleCue
{
private static void Postfix(Action_CallScoutmaster __instance)
{
if ((Object)(object)Plugin.Instance != (Object)null)
{
Plugin.Instance.BugleUsed(__instance);
}
}
}
[HarmonyPatch(typeof(GUIManager), "TheFogRises")]
internal static class FogWarningCue
{
private static void Postfix()
{
if ((Object)(object)Plugin.Instance != (Object)null)
{
Plugin.Instance.HazardWarning();
}
}
}
[HarmonyPatch(typeof(GUIManager), "TheGloomRises")]
internal static class GloomWarningCue
{
private static void Postfix()
{
if ((Object)(object)Plugin.Instance != (Object)null)
{
Plugin.Instance.HazardWarning();
}
}
}
[HarmonyPatch(typeof(GUIManager), "TheLavaRises")]
internal static class LavaWarningCue
{
private static void Postfix()
{
if ((Object)(object)Plugin.Instance != (Object)null)
{
Plugin.Instance.HazardWarning();
}
}
}
[HarmonyPatch(typeof(GhostBall), "Explode")]
internal static class GhostExplosion
{
private static void Postfix(GhostBall __instance)
{
if ((Object)(object)Plugin.Instance != (Object)null)
{
Plugin.Instance.GhostEnded(__instance);
}
}
}
[HarmonyPatch(typeof(GhostBall), "OnDestroy")]
internal static class GhostDestroyed
{
private static void Prefix(GhostBall __instance)
{
if ((Object)(object)Plugin.Instance != (Object)null)
{
Plugin.Instance.GhostEnded(__instance);
}
}
}
[HarmonyPatch(typeof(Flare), "LightFlare")]
internal static class FlareIgnition
{
private static void Postfix()
{
if ((Object)(object)Plugin.Instance != (Object)null)
{
Plugin.Instance.FlareLit();
}
}
}
[HarmonyPatch(typeof(Flare), "EnableFlareVisuals")]
internal static class SyncedFlareIgnition
{
private static void Postfix()
{
if ((Object)(object)Plugin.Instance != (Object)null)
{
Plugin.Instance.FlareLit();
}
}
}
[HarmonyPatch(typeof(GlobalEvents), "TriggerSoulFreed")]
internal static class NadirVictory
{
private static void Postfix(int __0)
{
if (__0 >= 1 && (Object)(object)Plugin.Instance != (Object)null)
{
Plugin.Instance.EndingEvent(1);
}
}
}
[HarmonyPatch(typeof(PeakHandler), "EndCutsceneFinal")]
internal static class NadirFinale
{
private static void Postfix()
{
if ((Object)(object)Plugin.Instance != (Object)null)
{
Plugin.Instance.EndingEvent(2);
}
}
}
[HarmonyPatch(typeof(PeakHandler), "EndScreenComplete")]
internal static class CreditsStart
{
private static void Postfix()
{
if ((Object)(object)Plugin.Instance != (Object)null)
{
Plugin.Instance.EndingEvent(3);
}
}
}
public enum Track
{
None,
DustDevils,
Summit,
Nadir,
Ghost,
Citadel,
NadirAmbient,
Finale,
Credits,
Spectating,
Airport,
LoneSummit,
Falling,
Rising,
ScoutChase
}
public sealed class FallCue
{
private float descending;
private bool fired;
public void Reset()
{
descending = 0f;
fired = false;
}
public bool Step(bool eligible, bool grounded, float velocityY, float delta)
{
if (!eligible || grounded)
{
Reset();
return false;
}
if (velocityY > -5f)
{
descending = 0f;
return false;
}
descending += Math.Max(0f, Math.Min(delta, 0.1f));
if (fired || descending < 1f)
{
return false;
}
fired = true;
return true;
}
}
public sealed class ScoreRules
{
private string previous = "";
private bool summitFinished;
private bool nadirFinished;
private bool summitChosen;
private bool loneSummit;
public bool NadirWon;
public bool FinalCutscene;
public bool InCredits;
public bool RisingWarning;
public bool ScoutPresent;
public void Reset()
{
previous = "";
RisingWarning = (ScoutPresent = false);
summitChosen = (loneSummit = (summitFinished = (nadirFinished = (NadirWon = (FinalCutscene = (InCredits = false))))));
}
public Track Select(string region, bool alive, int dustDevils, int ghosts)
{
return Select(region, alive, dustDevils, ghosts, afterglow: false, spectating: false);
}
public Track Select(string region, bool alive, int dustDevils, int ghosts, bool afterglow, bool spectating)
{
return Select(region, alive, dustDevils, ghosts, afterglow, spectating, alone: false);
}
public Track Select(string region, bool alive, int dustDevils, int ghosts, bool afterglow, bool spectating, bool alone)
{
region = (region ?? "").Trim().ToUpperInvariant();
if (region != previous)
{
if (region == "PEAK")
{
summitFinished = false;
summitChosen = false;
}
if (region == "NADIR")
{
nadirFinished = false;
}
previous = region;
}
if (InCredits)
{
return Track.Credits;
}
if (FinalCutscene)
{
return Track.Finale;
}
if (!alive)
{
RisingWarning = (ScoutPresent = false);
if (afterglow || !spectating)
{
return Track.None;
}
return Track.Spectating;
}
if (region == "PEAK" && !summitChosen)
{
summitChosen = true;
loneSummit = alone;
}
if (ScoutPresent)
{
return Track.ScoutChase;
}
if (RisingWarning)
{
return Track.Rising;
}
if (dustDevils > 0)
{
return Track.DustDevils;
}
if (region == "AIRPORT")
{
return Track.Airport;
}
if (region == "GLOOM" && ghosts > 0)
{
return Track.Ghost;
}
if (region == "NADIR" && !NadirWon)
{
if (!nadirFinished)
{
return Track.Nadir;
}
return Track.NadirAmbient;
}
switch (region)
{
case "THE CITADEL":
case "CITADEL":
return Track.Citadel;
case "PEAK":
if (!summitFinished)
{
if (!loneSummit)
{
return Track.Summit;
}
return Track.LoneSummit;
}
break;
}
return Track.None;
}
public void Finished(Track track)
{
if (track == Track.Rising)
{
RisingWarning = false;
}
if (track == Track.Summit || track == Track.LoneSummit)
{
summitFinished = true;
}
if (track == Track.Nadir)
{
nadirFinished = true;
}
}
public void FlareLit()
{
summitFinished = true;
}
public static float StartSeconds(Track track)
{
return track switch
{
Track.Nadir => 26f,
Track.Summit => 181f,
_ => 0f,
};
}
public static bool Loops(Track track)
{
if (track != Track.ScoutChase && track != Track.Airport && track != Track.DustDevils && track != Track.Ghost && track != Track.Citadel && track != Track.NadirAmbient && track != Track.Finale && track != Track.Credits)
{
return track == Track.Spectating;
}
return true;
}
public static float FadeGain(float age, float duration)
{
if (!(duration <= 0f))
{
return Math.Max(0f, Math.Min(1f, 1f - age / duration));
}
return 0f;
}
}