using System; using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Threading.Tasks; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using PizzaTowerEscapeMusic.Scripting; using PizzaTowerEscapeMusic.Scripting.Conditions; using PizzaTowerEscapeMusic.Scripting.ScriptEvents; using UnityEngine; using UnityEngine.Networking; [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("PizzaTowerEscapeMusic")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Plays music from Pizza Tower when the early ship leave alert appears")] [assembly: AssemblyFileVersion("2.5.0.0")] [assembly: AssemblyInformationalVersion("2.5.0+0874056d67ccfa01fc54486e73decb76a964d33a")] [assembly: AssemblyProduct("PizzaTowerEscapeMusic")] [assembly: AssemblyTitle("PizzaTowerEscapeMusic")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("2.5.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 PizzaTowerEscapeMusic { public class Configuration { private readonly ConfigFile _config; internal ConfigEntry volumeMaster; internal ConfigEntry scriptingScripts; public Configuration(ConfigFile config) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Expected O, but got Unknown _config = config; scriptingScripts = config.Bind("Scripting", "Scripts", "Default", new ConfigDescription("The names of the JSON script files that will be loaded (Separated by commas, do not put a space after the commas)", (AcceptableValueBase)null, Array.Empty())); volumeMaster = config.Bind("Volume", "Master", 0.5f, new ConfigDescription("The volume of the music as a whole, all volumes are scaled by this value", (AcceptableValueBase)null, Array.Empty())); RemoveObsoleteEntries(); } private void RemoveObsoleteEntry(string section, string key) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown ConfigDefinition val = new ConfigDefinition(section, key); _config.Bind(val, "", (ConfigDescription)null); _config.Remove(val); } private void ReplaceObsoleteEntry(string section, string key, ConfigEntry replacement) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown ConfigDefinition val = new ConfigDefinition(section, key); ConfigEntry val2 = _config.Bind(val, (T)((ConfigEntryBase)replacement).DefaultValue, (ConfigDescription)null); if (!EqualityComparer.Default.Equals(val2.Value, (T)((ConfigEntryBase)replacement).DefaultValue)) { replacement.Value = val2.Value; } _config.Remove(val); } private void RemoveObsoleteEntries() { RemoveObsoleteEntry("Volume", "InsideFacility"); RemoveObsoleteEntry("Volume", "OutsideFacility"); RemoveObsoleteEntry("Volume", "InsideShip"); RemoveObsoleteEntry("Volume", "CrouchingScale"); RemoveObsoleteEntry("Music", "InsideFacility"); RemoveObsoleteEntry("Music", "OutsideFacility"); RemoveObsoleteEntry("Music", "HeavyWeather"); ReplaceObsoleteEntry("Scripting", "Script", scriptingScripts); _config.Save(); } } internal static class CustomManager { public static string GetFilePath(string path, string fallbackPath) { string[] directories = Directory.GetDirectories(Paths.PluginPath); for (int i = 0; i < directories.Length; i++) { string text = directories[i] + "/BGN-PizzaTowerEscapeMusic/" + path; if (File.Exists(text)) { return text; } } string text2 = Paths.PluginPath + "/BGN-PizzaTowerEscapeMusic_Custom/" + path; if (File.Exists(text2)) { return text2; } return Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "/" + fallbackPath; } } public class GameEventListener : MonoBehaviour { private ManualLogSource _logger; public Action OnFrameUpdate = delegate { }; public Action OnSoundManagerCreated = delegate { }; public Action OnSoundManagerDestroyed = delegate { }; public Action OnDungeonDoneGenerating = delegate { }; public Action OnShipLanded = delegate { }; public Action OnShipTakeOff = delegate { }; public Action OnShipReturnToOrbit = delegate { }; public Action OnShipLeavingAlertCalled = delegate { }; public Action OnPlayerDamaged = delegate { }; public Action OnPlayerDeath = delegate { }; public Action OnPlayerEnteredFacility = delegate { }; public Action OnPlayerExitedFacility = delegate { }; public Action OnPlayerEnteredShip = delegate { }; public Action OnPlayerExitedShip = delegate { }; public Action OnApparatusTaken = delegate { }; public Action OnCurrentMoonChanged = delegate { }; private readonly Dictionary _previousValues = new Dictionary(); private static LungProp? _dockedApparatus; private void Awake() { _logger = Logger.CreateLogSource("PizzaTowerEscapeMusic GameEventListener"); OnShipLanded = (Action)Delegate.Combine(OnShipLanded, new Action(FindDockedApparatus)); } private void FindDockedApparatus() { _logger.LogDebug((object)"Checking for docked Apparatus..."); LungProp[] array = Object.FindObjectsOfType(); foreach (LungProp val in array) { if (val.isLungDocked) { _logger.LogDebug((object)"Found docked Apparatus"); _dockedApparatus = val; return; } } _logger.LogDebug((object)"Could not find docked Apparatus"); } public static bool IsApparatusDocked() { return (Object)(object)_dockedApparatus != (Object)null; } private void Update() { if ((Object)(object)SoundManager.Instance != (Object)null) { OnFrameUpdate(); } CheckSoundManager(); CheckDungeonDoneGenerating(); CheckShipLanded(); CheckShipReturnToOrbit(); CheckShipLeavingAlertCalled(); CheckPlayerDamaged(); CheckPlayerDeath(); CheckPlayerInsideFacility(); CheckPlayerInsideShip(); CheckApparatusTaken(); CheckCurrentMoonChanged(); } private T? UpdateCached(string key, T? currentValue, T? defaultValue) { if (!_previousValues.TryGetValue(key, out object value)) { value = defaultValue; } _previousValues[key] = currentValue; return (T)value; } private void CheckSoundManager() { bool flag = (Object)(object)SoundManager.Instance != (Object)null; if (UpdateCached("SoundManager", flag, defaultValue: false) != flag) { if (flag) { _logger.LogDebug((object)"Sound Manager created"); OnSoundManagerCreated(); } else { _logger.LogDebug((object)"Sound Manager destroyed"); OnSoundManagerDestroyed(); } } } private void CheckDungeonDoneGenerating() { bool flag = (Object)(object)RoundManager.Instance != (Object)null && RoundManager.Instance.dungeonCompletedGenerating; bool flag2 = UpdateCached("DungeonDoneGenerating", flag, defaultValue: false); if (flag != flag2 && flag) { _logger.LogDebug((object)"Dungeon done generating"); OnDungeonDoneGenerating(); } } private void CheckShipLanded() { bool flag = (Object)(object)StartOfRound.Instance != (Object)null && StartOfRound.Instance.shipHasLanded; bool flag2 = UpdateCached("ShipLanded", flag, defaultValue: true); if (flag != flag2 && !((Object)(object)StartOfRound.Instance == (Object)null)) { if (flag) { _logger.LogDebug((object)"Ship has landed"); OnShipLanded(); } else { _logger.LogDebug((object)"Ship has taken off"); OnShipTakeOff(); } } } private void CheckShipReturnToOrbit() { bool flag = (Object)(object)StartOfRound.Instance == (Object)null || (!StartOfRound.Instance.shipHasLanded && !StartOfRound.Instance.shipIsLeaving); bool flag2 = UpdateCached("ShipReturnToOrbit", flag, defaultValue: true); if (flag != flag2 && flag) { _logger.LogDebug((object)"Ship returned to orbit"); OnShipReturnToOrbit(); } } private void CheckShipLeavingAlertCalled() { bool flag = (Object)(object)TimeOfDay.Instance != (Object)null && TimeOfDay.Instance.shipLeavingAlertCalled; bool flag2 = UpdateCached("ShipLeavingAlertCalled", flag, defaultValue: false); if (flag != flag2 && flag) { _logger.LogDebug((object)"Ship leaving alert called"); OnShipLeavingAlertCalled(); } } private void CheckPlayerDamaged() { if (!((Object)(object)GameNetworkManager.Instance == (Object)null) && !((Object)(object)GameNetworkManager.Instance.localPlayerController == (Object)null)) { int health = GameNetworkManager.Instance.localPlayerController.health; int num = UpdateCached("PlayerDamaged", health, 100); if (health < num) { _logger.LogDebug((object)$"Player took damage (Health: {GameNetworkManager.Instance.localPlayerController.health})"); OnPlayerDamaged(); } } } private void CheckPlayerDeath() { bool flag = (Object)(object)GameNetworkManager.Instance != (Object)null && (Object)(object)GameNetworkManager.Instance.localPlayerController != (Object)null && GameNetworkManager.Instance.localPlayerController.isPlayerDead; bool flag2 = UpdateCached("PlayerDeath", flag, defaultValue: false); if (flag != flag2 && flag) { _logger.LogDebug((object)"Player has died"); OnPlayerDeath(); } } private void CheckPlayerInsideFacility() { bool flag = (Object)(object)GameNetworkManager.Instance != (Object)null && (Object)(object)GameNetworkManager.Instance.localPlayerController != (Object)null && GameNetworkManager.Instance.localPlayerController.isInsideFactory; bool flag2 = UpdateCached("PlayerInsideFacility", flag, defaultValue: false); if (flag != flag2) { if (flag) { _logger.LogDebug((object)"Player entered facility"); OnPlayerEnteredFacility(); } else { _logger.LogDebug((object)"Player exited facility"); OnPlayerExitedFacility(); } } } private void CheckPlayerInsideShip() { bool flag = (Object)(object)GameNetworkManager.Instance != (Object)null && (Object)(object)GameNetworkManager.Instance.localPlayerController != (Object)null && GameNetworkManager.Instance.localPlayerController.isInHangarShipRoom; bool flag2 = UpdateCached("PlayerInsideShip", flag, defaultValue: false); if (flag != flag2) { if (flag) { _logger.LogDebug((object)"Player entered ship"); OnPlayerEnteredShip(); } else { _logger.LogDebug((object)"Player exited ship"); OnPlayerExitedShip(); } } } private void CheckApparatusTaken() { bool flag = (Object)(object)_dockedApparatus != (Object)null && !_dockedApparatus.isLungDocked; bool flag2 = UpdateCached("ApparatusTaken", flag, defaultValue: false); if (flag != flag2 && flag) { _dockedApparatus = null; _logger.LogDebug((object)"Apparatus was taken"); OnApparatusTaken(); } } private void CheckCurrentMoonChanged() { SelectableLevel val = TimeOfDay.Instance?.currentLevel; SelectableLevel val2 = UpdateCached("CurrentMoon", val, null); if (!((Object)(object)val == (Object)(object)val2)) { _logger.LogDebug((object)("Level has changed to " + val?.PlanetName)); OnCurrentMoonChanged(val); } } } public class MusicManager : MonoBehaviour { private class MusicInstance { public Script script; public ScriptEvent_PlayMusic musicEvent; public AudioSource audioSource; public Script.VolumeGroup volumeGroup; private bool isStopping; private float volume; public float FadeSpeed { get; private set; } public MusicInstance(Script script, ScriptEvent_PlayMusic musicEvent, AudioSource audioSource, AudioClip? musicClip) { this.script = script; this.musicEvent = musicEvent; this.audioSource = audioSource; audioSource.clip = musicClip; audioSource.loop = musicEvent.loop; audioSource.bypassEffects = musicEvent.bypassEffects; audioSource.bypassListenerEffects = musicEvent.bypassEffects; audioSource.bypassReverbZones = musicEvent.bypassEffects; audioSource.Play(); musicInstances.Add(this); if (musicEvent.tag != null) { if (!musicInstancesByTag.TryGetValue(musicEvent.tag, out List value)) { value = new List(1); musicInstancesByTag.Add(musicEvent.tag, value); } value.Add(this); } volumeGroup = script.TryGetVolumeGroupOrDefault(musicEvent.tag); volume = volumeGroup.GetVolume(script); } public void Update(float deltaTime) { float num = (isStopping ? 0f : volumeGroup.GetVolume(script)); float num2 = (isStopping ? volumeGroup.stoppingVolumeLerpSpeed : volumeGroup.volumeLerpSpeed); volume = Mathf.Lerp(volume, num, num2 * deltaTime); audioSource.volume = volume * PizzaTowerEscapeMusicManager.Configuration.volumeMaster.Value; if (!audioSource.isPlaying || (isStopping && audioSource.volume < 0.005f)) { StopCompletely(); } } public void FadeStop() { if (!isStopping) { isStopping = true; FadeSpeed = volumeGroup.stoppingVolumeLerpSpeed; } } public void StopCompletely() { audioSource.Stop(); audioSourcePool.Push(audioSource); musicInstances.Remove(this); if (musicEvent.tag != null && musicInstancesByTag.TryGetValue(musicEvent.tag, out List value)) { value.Remove(this); } } } private ManualLogSource logger; private static readonly List musicInstances = new List(); private static readonly Dictionary> musicInstancesByTag = new Dictionary>(); private static readonly Stack audioSourcePool = new Stack(); private readonly Dictionary loadedMusic = new Dictionary(); private void Awake() { logger = Logger.CreateLogSource("PizzaTowerEscapeMusic MusicManager"); } private void Update() { if ((Object)(object)StartOfRound.Instance == (Object)null) { return; } for (int num = musicInstances.Count - 1; num >= 0; num--) { musicInstances[num].Update(Time.deltaTime); } bool flag = false; foreach (MusicInstance musicInstance in musicInstances) { if (musicInstance.musicEvent.silenceGameMusic) { flag = true; break; } } if (flag) { if (SoundManager.Instance.playingOutsideMusic && GetIsMusicPlaying()) { SoundManager.Instance.playingOutsideMusic = false; logger.LogInfo((object)"Silenced the outside music because alternate music is playing"); } if (TimeOfDay.Instance.TimeOfDayMusic.isPlaying && GetIsMusicPlaying()) { TimeOfDay.Instance.TimeOfDayMusic.Stop(); logger.LogInfo((object)"Silenced the time of day music because alternate music is playing"); } } } public bool GetIsMusicPlaying(string? tag = null) { if (tag == null) { return musicInstances.Count > 0; } if (musicInstancesByTag.TryGetValue(tag, out List value)) { logger.LogDebug((object)$"GetIsMusicPlaying says there's {value.Count} music instance(s) with the tag \"{tag}\""); return value.Count > 0; } logger.LogDebug((object)("GetIsMusicPlaying says there was no music instance list for tag \"" + tag + "\"")); return false; } public void PlayMusic(Script script, ScriptEvent_PlayMusic musicEvent) { logger.LogDebug((object)("PlayMusic called\nTag: " + musicEvent.tag + $"\nOverlap handling: {musicEvent.overlapHandling}" + $"\nAny music playing?: {GetIsMusicPlaying()}" + $"\nAny music playing with tag?: {GetIsMusicPlaying(musicEvent.tag)}")); if (musicEvent.overlapHandling == ScriptEvent_PlayMusic.OverlapHandling.IgnoreAll && GetIsMusicPlaying()) { logger.LogDebug((object)"PlayMusic canceled because other music was playing"); return; } if (musicEvent.overlapHandling == ScriptEvent_PlayMusic.OverlapHandling.IgnoreTag && GetIsMusicPlaying(musicEvent.tag)) { logger.LogDebug((object)("PlayMusic canceled because other music with the tag \"" + musicEvent.tag + "\" was playing")); return; } switch (musicEvent.overlapHandling) { case ScriptEvent_PlayMusic.OverlapHandling.OverrideAll: StopMusic(); break; case ScriptEvent_PlayMusic.OverlapHandling.OverrideTag: StopMusic(musicEvent.tag); break; case ScriptEvent_PlayMusic.OverlapHandling.OverrideFadeAll: FadeStopMusic(); break; case ScriptEvent_PlayMusic.OverlapHandling.OverrideFadeTag: FadeStopMusic(musicEvent.tag); break; } string text = musicEvent.musicNames[Random.Range(0, musicEvent.musicNames.Length)]; loadedMusic.TryGetValue(text, out AudioClip value); if ((Object)(object)value != (Object)null) { new MusicInstance(script, musicEvent, GetAudioSource(), value); logger.LogInfo((object)("Playing music (" + text + ")")); } else { logger.LogWarning((object)("Music (" + text + ") is null, cannot play. Maybe it wasn't loaded correctly?")); } } public void StopMusic(string? targetTag = null) { foreach (MusicInstance item in new List(musicInstances)) { if (targetTag == null || !(item.musicEvent.tag != targetTag)) { item.StopCompletely(); } } } public void FadeStopMusic(string? targetTag = null) { foreach (MusicInstance item in new List(musicInstances)) { if (targetTag == null || !(item.musicEvent.tag != targetTag)) { item.FadeStop(); } } } private AudioSource GetAudioSource() { if (!audioSourcePool.TryPop(out AudioSource result)) { return ((Component)this).gameObject.AddComponent(); } return result; } public async Task LoadNecessaryMusicClips() { if (PizzaTowerEscapeMusicManager.ScriptManager.loadedScripts.Count == 0) { logger.LogError((object)"No scripts are loaded, cannot load their music!"); return; } UnloadMusicClips(); foreach (Script loadedScript in PizzaTowerEscapeMusicManager.ScriptManager.loadedScripts) { ScriptEvent[] scriptEvents = loadedScript.scriptEvents; for (int i = 0; i < scriptEvents.Length; i++) { if (!(scriptEvents[i] is ScriptEvent_PlayMusic scriptEvent_PlayMusic)) { continue; } string[] musicNames = scriptEvent_PlayMusic.musicNames; foreach (string musicName in musicNames) { if (!loadedMusic.ContainsKey(musicName)) { AudioClip val = await LoadMusicClip(musicName); if (!((Object)(object)val == (Object)null)) { loadedMusic.Add(musicName, val); } } } } } logger.LogInfo((object)"Music clips done loading"); } public void UnloadMusicClips() { foreach (AudioClip value in loadedMusic.Values) { value.UnloadAudioData(); } loadedMusic.Clear(); logger.LogInfo((object)"All music clips unloaded"); } private async Task LoadMusicClip(string musicFileName) { InterpretMusicFileName(musicFileName, out AudioType audioType, out string finalFileName); string path = "file:///" + CustomManager.GetFilePath("Music/" + finalFileName, "DefaultMusic/" + finalFileName); UnityWebRequest request = UnityWebRequestMultimedia.GetAudioClip(path, audioType); try { request.SendWebRequest(); while (!request.isDone) { await Task.Delay(50); } if ((int)request.result == 1) { logger.LogInfo((object)("Loaded music (" + musicFileName + ") from file")); AudioClip content = DownloadHandlerAudioClip.GetContent(request); ((Object)content).name = musicFileName; return content; } logger.LogError((object)($"Failed to load music ({musicFileName}) from file as audio type {audioType}, if the file extension and the audio type do not match the file extension may not be supported." + "\n- Path: " + path + "\n- Error: " + request.error)); return null; } finally { ((IDisposable)request)?.Dispose(); } } private void InterpretMusicFileName(string musicFileName, out AudioType audioType, out string finalFileName) { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Expected I4, but got Unknown //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) if (!musicFileName.Contains('.')) { audioType = (AudioType)20; finalFileName = musicFileName + ".wav"; return; } string text = musicFileName.Split('.').Last().ToLower(); AudioType val = ((text == "ogg") ? ((AudioType)14) : ((!(text == "mp3")) ? ((AudioType)20) : ((AudioType)13))); audioType = (AudioType)(int)val; finalFileName = musicFileName; } } public class PizzaTowerEscapeMusicManager : MonoBehaviour { private GameEventListener _gameEventListener; private ManualLogSource _logger; public static Configuration Configuration { get; private set; } public static ScriptManager ScriptManager { get; private set; } public static MusicManager MusicManager { get; private set; } public void Initialise(ManualLogSource logger, ConfigFile config) { _logger = logger; Configuration = new Configuration(config); MusicManager = ((Component)this).gameObject.AddComponent(); _gameEventListener = ((Component)this).gameObject.AddComponent(); GameEventListener gameEventListener = _gameEventListener; gameEventListener.OnSoundManagerCreated = (Action)Delegate.Combine(gameEventListener.OnSoundManagerCreated, (Action)delegate { MusicManager.LoadNecessaryMusicClips(); }); GameEventListener gameEventListener2 = _gameEventListener; gameEventListener2.OnSoundManagerDestroyed = (Action)Delegate.Combine(gameEventListener2.OnSoundManagerDestroyed, (Action)delegate { MusicManager.StopMusic(); }); GameEventListener gameEventListener3 = _gameEventListener; gameEventListener3.OnSoundManagerDestroyed = (Action)Delegate.Combine(gameEventListener3.OnSoundManagerDestroyed, new Action(MusicManager.UnloadMusicClips)); ScriptManager = new ScriptManager(Configuration.scriptingScripts.Value.Split(','), _gameEventListener); GameEventListener gameEventListener4 = _gameEventListener; gameEventListener4.OnSoundManagerDestroyed = (Action)Delegate.Combine(gameEventListener4.OnSoundManagerDestroyed, new Action(ScriptManager.ClearAllScriptTimers)); ((Object)((Component)this).gameObject).hideFlags = (HideFlags)61; logger.LogInfo((object)"Plugin bgn.pizzatowerescapemusic is loaded!"); } private void Update() { ScriptManager.UpdateAllScriptTimers(Time.deltaTime); } } [BepInPlugin("bgn.pizzatowerescapemusic", "PizzaTowerEscapeMusic", "2.5.0")] [BepInProcess("Lethal Company.exe")] public class Plugin : BaseUnityPlugin { public const string Guid = "bgn.pizzatowerescapemusic"; private void Awake() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("PizzaTowerEscapeMusic Manager"); val.AddComponent().Initialise(((BaseUnityPlugin)this).Logger, ((BaseUnityPlugin)this).Config); ((Object)val).hideFlags = (HideFlags)61; } } public static class PluginInfo { public const string PLUGIN_GUID = "PizzaTowerEscapeMusic"; public const string PLUGIN_NAME = "PizzaTowerEscapeMusic"; public const string PLUGIN_VERSION = "2.5.0"; } } namespace PizzaTowerEscapeMusic.Scripting { public class Script { public class VolumeRule { public string comment = string.Empty; [JsonRequired] public float volume; public Condition? condition; } public class VolumeModifier { public string comment = string.Empty; [JsonRequired] public float volumeScale; public Condition? condition; } public class VolumeGroup { public string comment = string.Empty; public string tag = string.Empty; public float volumeLerpSpeed = 1f; public float stoppingVolumeLerpSpeed = 1f; public float masterVolume = 1f; public VolumeRule[] volumeRules = Array.Empty(); public VolumeModifier[] volumeModifiers = Array.Empty(); public float GetVolume(Script script) { float num = 1f; VolumeRule[] array = volumeRules; foreach (VolumeRule volumeRule in array) { if (volumeRule.condition == null || volumeRule.condition.Check(script)) { num = volumeRule.volume; break; } } VolumeModifier[] array2 = volumeModifiers; foreach (VolumeModifier volumeModifier in array2) { if (volumeModifier.condition == null || volumeModifier.condition.Check(script)) { num *= volumeModifier.volumeScale; } } return num * masterVolume; } } public class Timer { public string name; public float time; public Timer(string name) { this.name = name; } } public string comment = string.Empty; public bool isAddon; public VolumeGroup[] volumeGroups = Array.Empty(); [JsonRequired] public ScriptEvent[] scriptEvents = Array.Empty(); [JsonIgnore] public readonly Dictionary> loadedScriptEvents = new Dictionary>(); [JsonIgnore] public readonly Dictionary loadedScriptVolumeGroups = new Dictionary(); [JsonIgnore] public readonly Dictionary activeTimers = new Dictionary(); [JsonIgnore] public static VolumeGroup DefaultVolumeGroup { get; private set; } = new VolumeGroup(); public void Initialise(ManualLogSource logger) { ScriptEvent[] array = scriptEvents; foreach (ScriptEvent scriptEvent in array) { if (!loadedScriptEvents.TryGetValue(scriptEvent.gameEventType, out List value)) { value = new List(1); loadedScriptEvents.Add(scriptEvent.gameEventType, value); } value.Add(scriptEvent); } VolumeGroup[] array2 = volumeGroups; foreach (VolumeGroup volumeGroup in array2) { if (!loadedScriptVolumeGroups.TryAdd(volumeGroup.tag, volumeGroup)) { logger.LogError((object)("Volume group tag \"" + volumeGroup.tag + "\" was already declared, you cannot have two volume groups with the same tag")); } } } public VolumeGroup TryGetVolumeGroupOrDefault(string? tag) { if (tag == null || !loadedScriptVolumeGroups.ContainsKey(tag)) { return DefaultVolumeGroup; } return loadedScriptVolumeGroups[tag]; } public bool TryGetVolumeGroup(string? tag, [NotNullWhen(true)] out VolumeGroup? volumeGroup) { if (tag == null || !loadedScriptVolumeGroups.ContainsKey(tag)) { volumeGroup = null; return false; } volumeGroup = loadedScriptVolumeGroups[tag]; return true; } public void UpdateTimers(float deltaTime) { foreach (Timer value in activeTimers.Values) { value.time += deltaTime; } } public void ClearTimers() { activeTimers.Clear(); } internal void ClearTimer(string timerName) { activeTimers.Remove(timerName); } } public class ScriptManager { public readonly List