Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of CS2 OST v1.0.1
com.github.zehsteam.CS2_OST.dll
Decompiled 2 months agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; 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 BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; using com.github.zehsteam.CS2_OST.Extensions; using com.github.zehsteam.CS2_OST.Helpers; using com.github.zehsteam.CS2_OST.Managers; using com.github.zehsteam.CS2_OST.MonoBehaviours; using com.github.zehsteam.CS2_OST.MonoBehaviours.AudioEvents; using com.github.zehsteam.CS2_OST.Objects; using com.github.zehsteam.CS2_OST.Objects.Intensity; using com.github.zehsteam.CS2_OST.Objects.Intensity.States; using com.github.zehsteam.CS2_OST.Patches; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("Zehs")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyCopyright("Copyright © 2026 Zehs")] [assembly: AssemblyDescription("A dynamic implementation of the Counter-Strike 2 original sound track, featuring dynamic enemy intensity, final extraction music, and some generally cool sound and music additions.")] [assembly: AssemblyFileVersion("1.0.1.0")] [assembly: AssemblyInformationalVersion("1.0.1+323dff19b89b75110959c46dce98309261f773ba")] [assembly: AssemblyProduct("CS2_OST")] [assembly: AssemblyTitle("com.github.zehsteam.CS2_OST")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.1.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.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace com.github.zehsteam.CS2_OST { internal static class Assets { public static AssetBundle AssetBundle { get; private set; } public static SoundRegistry SoundRegistry { get; private set; } public static GameObject AudioEventManagerPrefab { get; private set; } public static void Load() { string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); string text = "cs2_ost_assets"; string text2 = Path.Combine(directoryName, text); if (!File.Exists(text2)) { Logger.LogFatal("Failed to load assets. AssetBundle file could not be found at path \"" + text2 + "\". Make sure the \"" + text + "\" file is in the same folder as the mod's DLL file."); } else { AssetBundle val = AssetBundle.LoadFromFile(text2); if ((Object)(object)val == (Object)null) { Logger.LogFatal("Failed to load assets. AssetBundle is null."); } else { HandleAssetBundleLoaded(val); } } } private static void HandleAssetBundleLoaded(AssetBundle assetBundle) { AssetBundle = assetBundle; SoundRegistry = LoadAsset<SoundRegistry>("SoundRegistry", assetBundle); AudioEventManagerPrefab = LoadAsset<GameObject>("AudioEventManager", assetBundle); } private static T LoadAsset<T>(string name, AssetBundle assetBundle) where T : Object { if (string.IsNullOrWhiteSpace(name)) { Logger.LogError("Failed to load asset of type \"" + typeof(T).Name + "\" from AssetBundle. Name is null or whitespace."); return default(T); } if ((Object)(object)assetBundle == (Object)null) { Logger.LogError("Failed to load asset of type \"" + typeof(T).Name + "\" with name \"" + name + "\" from AssetBundle. AssetBundle is null."); return default(T); } T val = assetBundle.LoadAsset<T>(name); if ((Object)(object)val == (Object)null) { Logger.LogError("Failed to load asset of type \"" + typeof(T).Name + "\" with name \"" + name + "\" from AssetBundle. No asset found with that type and name."); return default(T); } return val; } private static bool TryLoadAsset<T>(string name, AssetBundle assetBundle, out T asset) where T : Object { asset = LoadAsset<T>(name, assetBundle); return (Object)(object)asset != (Object)null; } } internal static class Logger { public static ManualLogSource ManualLogSource { get; private set; } public static void Initialize(ManualLogSource manualLogSource) { ManualLogSource = manualLogSource; } public static void LogDebug(object data) { Log_Internal((LogLevel)32, data); } public static void LogInfo(object data, bool extended = false) { Log_Internal((LogLevel)16, data, extended); } public static void LogMessage(object data, bool extended = false) { Log_Internal((LogLevel)8, data, extended); } public static void LogWarning(object data, bool extended = false) { Log_Internal((LogLevel)4, data, extended); } public static void LogError(object data, bool extended = false) { Log_Internal((LogLevel)2, data, extended); } public static void LogFatal(object data, bool extended = false) { Log_Internal((LogLevel)1, data, extended); } public static void Log(LogLevel logLevel, object data, bool extended = false) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) Log_Internal(logLevel, data, extended); } private static void Log_Internal(LogLevel logLevel, object data, bool extended = false) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) if (!extended || IsExtendedLoggingEnabled()) { ManualLogSource manualLogSource = ManualLogSource; if (manualLogSource != null) { manualLogSource.Log(logLevel, data); } } } public static bool IsExtendedLoggingEnabled() { return ConfigManager.General_ExtendedLogging?.Value ?? false; } } [BepInPlugin("com.github.zehsteam.CS2_OST", "CS2_OST", "1.0.1")] internal class Plugin : BaseUnityPlugin { private readonly Harmony _harmony = new Harmony("com.github.zehsteam.CS2_OST"); public static Plugin Instance { get; private set; } private void Awake() { Instance = this; Logger.Initialize(Logger.CreateLogSource("com.github.zehsteam.CS2_OST")); Logger.LogInfo("CS2_OST has awoken!"); _harmony.PatchAll(typeof(NetworkConnect_Patches)); _harmony.PatchAll(typeof(RunManager_Patches)); _harmony.PatchAll(typeof(EnemyDirector_Patches)); _harmony.PatchAll(typeof(PlayerAvatar_Patches)); _harmony.PatchAll(typeof(ExtractionPoint_Patches)); _harmony.PatchAll(typeof(RoomVolume_Patches)); Assets.Load(); ConfigManager.Initialize(((BaseUnityPlugin)this).Config); AudioEventManager.Spawn(); PowerLevelDetector.Spawn(); } } public static class MyPluginInfo { public const string PLUGIN_GUID = "com.github.zehsteam.CS2_OST"; public const string PLUGIN_NAME = "CS2_OST"; public const string PLUGIN_VERSION = "1.0.1"; } } namespace com.github.zehsteam.CS2_OST.Patches { [HarmonyPatch(typeof(AudioManager))] internal static class AudioManager_Patches { [HarmonyPatch("Awake")] [HarmonyPrefix] private static void Awake_Patch(AudioManager __instance) { if ((Object)(object)Assets.SoundRegistry == (Object)null || ConfigManager.LevelAmbience_ReplaceSounds == null || !ConfigManager.LevelAmbience_ReplaceSounds.Value) { return; } foreach (LevelAmbience levelAmbience in __instance.levelAmbiences) { ReplaceLevelAmbienceBreakers(levelAmbience); } } private static void ReplaceLevelAmbienceBreakers(LevelAmbience levelAmbience) { if (!((Object)(object)levelAmbience == (Object)null) && levelAmbience.breakers != null && levelAmbience.breakers.Count != 0) { List<LevelAmbienceBreaker> levelAmbienceBreakers = Assets.SoundRegistry.LevelAmbienceBreakers; if (levelAmbienceBreakers != null && levelAmbienceBreakers.Count != 0) { levelAmbience.breakers.Clear(); levelAmbience.breakers.AddRange(levelAmbienceBreakers); } } } } [HarmonyPatch(typeof(EnemyDirector))] internal static class EnemyDirector_Patches { [HarmonyPatch("Awake")] [HarmonyPostfix] [HarmonyPriority(0)] private static void Awake() { PowerLevelConfigManager.GenerateConfigs(); } } [HarmonyPatch(typeof(ExtractionPoint))] internal static class ExtractionPoint_Patches { private static bool _activatedFinalExtractMusic; [HarmonyPatch("Update")] [HarmonyPostfix] private static void Start_Update() { _activatedFinalExtractMusic = false; } [HarmonyPatch("Update")] [HarmonyPostfix] private static void Update_Patch(ExtractionPoint __instance) { if (__instance.isShop || !IsCurrentExtractionPoint(__instance) || !IsFinalExtractionPointRemaining() || _activatedFinalExtractMusic || !IsExtractingAndSucking(__instance)) { return; } _activatedFinalExtractMusic = true; if (PlayerUtils.IsLocalPlayerAlive() && !PlayerUtils.IsLocalPlayerInTruck()) { float localPlayerDistanceFromTruck = PlayerUtils.GetLocalPlayerDistanceFromTruck(); if (!(localPlayerDistanceFromTruck <= (float)ConfigManager.FinalExtract_ExcludeRadius.Value)) { AudioEventManager.Instance?.FinalExtractEvent.PlayMusic(); } } } private static bool IsExtractingAndSucking(ExtractionPoint extractionPoint, float minTubeSlamDownEval = 0.8f) { if ((Object)(object)extractionPoint == (Object)null) { return false; } if (!extractionPoint.StateIs((State)6)) { return false; } if (!extractionPoint.tubeHit) { return false; } return extractionPoint.tubeSlamDownEval >= minTubeSlamDownEval; } private static bool IsFinalExtractionPointRemaining() { if ((Object)(object)RoundDirector.instance == (Object)null) { return false; } int extractionPoints = RoundDirector.instance.extractionPoints; int extractionPointsCompleted = RoundDirector.instance.extractionPointsCompleted; int num = extractionPoints - extractionPointsCompleted; return num == 1; } private static bool IsCurrentExtractionPoint(ExtractionPoint extractionPoint) { if ((Object)(object)extractionPoint == (Object)null || (Object)(object)RoundDirector.instance == (Object)null) { return false; } return (Object)(object)extractionPoint == (Object)(object)RoundDirector.instance.extractionPointCurrent; } } [HarmonyPatch(typeof(NetworkConnect))] internal static class NetworkConnect_Patches { [HarmonyPatch("OnDisconnected")] [HarmonyPrefix] private static void OnDisconnected_Patch() { AudioEventManager.Instance?.StopAll(); } } [HarmonyPatch(typeof(PlayerAvatar))] internal static class PlayerAvatar_Patches { private static bool _endedFinalExtractMusic; [HarmonyPatch("PlayerDeath")] [HarmonyPrefix] private static void PlayerDeath_Patch(PlayerAvatar __instance) { if (__instance.isLocal && !__instance.deadSet) { AudioEventManager.Instance?.StopAll(); if (PlayerUtils.GetAlivePlayerCount() > 1) { AudioEventManager.Instance?.DeathEvent.Play(); } } } [HarmonyPatch("Update")] [HarmonyPostfix] private static void Update_Patch(PlayerAvatar __instance) { if (__instance.isLocal && !_endedFinalExtractMusic && (SemiFunc.RunIsLevel() || SemiFunc.RunIsTutorial()) && (!((Object)(object)RoundDirector.instance != (Object)null) || RoundDirector.instance.allExtractionPointsCompleted) && __instance.RoomVolumeCheck.inTruck) { _endedFinalExtractMusic = true; AudioEventManager.Instance?.FinalExtractEvent.EndMusic(); } } public static void OnNewLevel() { _endedFinalExtractMusic = false; } } [HarmonyPatch(typeof(RoomVolume))] internal static class RoomVolume_Patches { public static RoomVolume TruckRoomVolume { get; private set; } [HarmonyPatch("Awake")] [HarmonyPrefix] private static void Awake_Patch(RoomVolume __instance) { if (__instance.Truck) { TruckRoomVolume = __instance; } } } [HarmonyPatch(typeof(RunManager))] internal static class RunManager_Patches { private static bool _wereAllPlayersDead; [HarmonyPatch("Awake")] [HarmonyPrefix] private static void Awake_Patch(RunManager __instance) { if (!((Object)(object)Assets.SoundRegistry == (Object)null)) { AudioClip mainMenuMusic = Assets.SoundRegistry.MainMenuMusic; ReplaceConstantMusicClip(__instance.levelMainMenu, mainMenuMusic); ReplaceConstantMusicClip(__instance.levelLobbyMenu, mainMenuMusic); } } private static void ReplaceConstantMusicClip(Level level, AudioClip audioClip) { if (!((Object)(object)level == (Object)null) && !((Object)(object)audioClip == (Object)null) && !((Object)(object)level.ConstantMusicPreset == (Object)null)) { level.ConstantMusicPreset.clip = audioClip; level.ConstantMusicPreset.volume = 1f; } } [HarmonyPatch("Update")] [HarmonyPrefix] private static void Update_PatchPrefix(RunManager __instance) { _wereAllPlayersDead = __instance.allPlayersDead; } [HarmonyPatch("Update")] [HarmonyPostfix] private static void Update_PatchPostfix(RunManager __instance) { if (__instance.allPlayersDead && !_wereAllPlayersDead) { AudioEventManager.Instance?.LoseEvent.Play(); } } [HarmonyPatch("ChangeLevel")] [HarmonyPostfix] private static void ChangeLevel_Patch(RunManager __instance) { PlayerAvatar_Patches.OnNewLevel(); AudioEventManager.Instance?.OnNewLevel(); TryPlayWinEvent(__instance); } private static void TryPlayWinEvent(RunManager runManager) { if (!((Object)(object)runManager.levelCurrent != (Object)(object)runManager.levelShop)) { AudioEventManager.Instance?.WinEvent.Play(); } } } } namespace com.github.zehsteam.CS2_OST.Objects { [CreateAssetMenu(fileName = "SoundRegistry", menuName = "CS2_OST/SoundRegistry")] public class SoundRegistry : ScriptableObject { public AudioClip MainMenuMusic; [Space(10f)] public List<LevelAmbienceBreaker> LevelAmbienceBreakers = new List<LevelAmbienceBreaker>(); [Space(10f)] public AudioClip WinSFX; public AudioClip DeathSFX; public AudioClip LoseSFX; [Space(10f)] public AudioClip IntensityMusicLow; public AudioClip IntensityMusicLowOutro; public AudioClip IntensityMusicMedium; public AudioClip IntensityMusicMediumOutro; public AudioClip IntensityMusicHigh; public AudioClip IntensityMusicHighOutro; [Space(10f)] public AudioClip FinalExtractMusicStart; public AudioClip FinalExtractMusicLoop; public AudioClip FinalExtractMusicEnd; } public class Timer { public float Value { get; private set; } public float Duration { get; set; } public bool IsFinished => Value > Duration; public Timer(float duration) { Duration = duration; } public void Tick(float deltaTime) { Value += deltaTime; } public void Reset() { Value = 0f; } public void Reset(float duration) { Value = 0f; Duration = duration; } } public class ValueHistory<T> { private T _value; public T Value { get { return _value; } set { if (!object.Equals(value, _value)) { PreviousUniqueValue = value; } PreviousValue = _value; _value = value; } } public T PreviousValue { get; private set; } public T PreviousUniqueValue { get; private set; } public ValueHistory(T defaultValue = default(T)) { _value = defaultValue; } public void Reset() { _value = default(T); PreviousValue = default(T); PreviousUniqueValue = default(T); } } } namespace com.github.zehsteam.CS2_OST.Objects.Intensity { public abstract class IntensityState { public IntensityEvent IntensityEvent { get; private set; } protected IntensityState(IntensityEvent intensityEvent) { IntensityEvent = intensityEvent; } public abstract void OnEnter(); public abstract void OnTick(); public abstract void OnExit(); protected void ChangeState(IntensityState newState) { IntensityEvent?.ChangeState(newState); } protected Coroutine StartCoroutine(IEnumerator routine) { IntensityEvent intensityEvent = IntensityEvent; return ((intensityEvent != null) ? ((MonoBehaviour)intensityEvent).StartCoroutine(routine) : null) ?? null; } protected void StopCoroutine(IEnumerator routine) { IntensityEvent intensityEvent = IntensityEvent; if (intensityEvent != null) { ((MonoBehaviour)intensityEvent).StopCoroutine(routine); } } protected void StopCoroutine(Coroutine coroutine) { if (coroutine != null) { IntensityEvent intensityEvent = IntensityEvent; if (intensityEvent != null) { ((MonoBehaviour)intensityEvent).StopCoroutine(coroutine); } } } } } namespace com.github.zehsteam.CS2_OST.Objects.Intensity.States { public class EnemyProximityState : IntensityState { private float _timeSinceEntered; private bool _skipTickDelay; private bool _isEnding; public EnemyProximityState(IntensityEvent intensityEvent) : base(intensityEvent) { } public override void OnEnter() { _timeSinceEntered = Time.realtimeSinceStartup; _skipTickDelay = !base.IntensityEvent.AudioSource.isPlaying; _isEnding = false; base.IntensityEvent.AudioSource.Stop(); } public override void OnTick() { UpdateMusicVolume(); if (base.IntensityEvent.AudioSource.isPlaying || !IsTickEnabled()) { return; } if (_isEnding) { ChangeState(base.IntensityEvent.IdleState); return; } IntensityEvent.Intensities intensities = base.IntensityEvent.GetIntensityForEnemyPowerLevel(); if (intensities == IntensityEvent.Intensities.None) { EndMusic(); return; } IntensityEvent.Intensities intensity = base.IntensityEvent.Intensity; if (intensities < intensity) { intensities = intensity; } base.IntensityEvent.Intensity = intensities; base.IntensityEvent.PlayIntensityClip(intensities); } public override void OnExit() { } private bool IsTickEnabled() { if (_skipTickDelay) { return true; } float value = ConfigManager.IntensityEP_EnterStateMusicDelay.Value; return Time.realtimeSinceStartup - _timeSinceEntered > value; } private void EndMusic() { _isEnding = true; base.IntensityEvent.PlayIntensityClip(base.IntensityEvent.Intensity, outro: true); } private void UpdateMusicVolume() { float num = (float)ConfigManager.IntensityEP_MinMusicVolume.Value * 0.01f; float num2 = (float)ConfigManager.IntensityEP_MaxMusicVolume.Value * 0.01f; float num3 = ConfigManager.IntensityEP_MaxMusicVolumeRadius.Value; float closestEnemyDistanceToLocalPlayer = EnemyHelper.GetClosestEnemyDistanceToLocalPlayer(); float num4 = ConfigManager.IntensityEP_EnemyCheckExitRadius.Value; if (closestEnemyDistanceToLocalPlayer > num4 || closestEnemyDistanceToLocalPlayer <= -1f) { base.IntensityEvent.AudioSource.volume = num; return; } float volume = Mathf.Lerp(num2, num, Mathf.Clamp01((closestEnemyDistanceToLocalPlayer - num3) / (num4 - num3))); base.IntensityEvent.AudioSource.volume = volume; } } public class IdleState : IntensityState { private Timer _timer = new Timer(10f); public IdleState(IntensityEvent intensityEvent) : base(intensityEvent) { UpdateTimerDuration(); ConfigManager.IntensityR_RollMusicChanceCooldown.SettingChanged += delegate { UpdateTimerDuration(); }; } public override void OnEnter() { _timer.Reset(); } public override void OnTick() { if (base.IntensityEvent.AudioSource.isPlaying) { return; } if (_timer.IsFinished) { _timer.Reset(); float value = ConfigManager.IntensityR_MusicChance.Value; if (Utils.RollPercentChance(value)) { ChangeState(base.IntensityEvent.RandomMusicState); } } else { _timer.Tick(Time.deltaTime); } } public override void OnExit() { } private void UpdateTimerDuration() { _timer.Duration = ConfigManager.IntensityR_RollMusicChanceCooldown.Value; } } public class RandomMusicState : IntensityState { private bool _playingEndMusic; private bool _forceEndMusic; private bool _endToEnemyProximityState; private float _chanceToKeepPlaying; public RandomMusicState(IntensityEvent intensityEvent) : base(intensityEvent) { } public override void OnEnter() { _playingEndMusic = false; _forceEndMusic = false; _endToEnemyProximityState = false; _chanceToKeepPlaying = ConfigManager.IntensityR_PlayCurrentIntensityChance.Value; UpdateMusicVolume(); PlayMusic(IntensityEvent.Intensities.Low); } public override void OnTick() { if (_forceEndMusic && !_playingEndMusic) { EndMusic(); } else { if (base.IntensityEvent.AudioSource.isPlaying) { return; } if (_playingEndMusic) { if (_endToEnemyProximityState) { ChangeState(base.IntensityEvent.EnemyProximityState); } else { ChangeState(base.IntensityEvent.IdleState); } return; } float value = ConfigManager.IntensityR_PlayNextIntensityChance.Value; if (Utils.RollPercentChance(value)) { PlayNextMusic(); } else if (Utils.RollPercentChance(_chanceToKeepPlaying)) { PlayCurrentMusic(); } else { EndMusic(); } } } public override void OnExit() { } private void PlayMusic(IntensityEvent.Intensities intensity) { base.IntensityEvent.Intensity = intensity; UpdateMusicVolume(); base.IntensityEvent.PlayIntensityClip(intensity); } private void PlayCurrentMusic() { if (ConfigManager.IntensityR_DecreaseCurrentIntensityChanceAfterEachAttempt.Value) { float value = ConfigManager.IntensityR_DecreaseCurrentIntensityChanceAmount.Value; float value2 = ConfigManager.IntensityR_MinCurrentIntensityChance.Value; _chanceToKeepPlaying -= value; if (_chanceToKeepPlaying < value2) { _chanceToKeepPlaying = value2; } } PlayMusic(base.IntensityEvent.Intensity); } private void PlayNextMusic() { PlayMusic(base.IntensityEvent.GetNextIntensity(base.IntensityEvent.Intensity)); } private void EndMusic() { _forceEndMusic = false; _playingEndMusic = true; UpdateMusicVolume(); base.IntensityEvent.PlayIntensityClip(base.IntensityEvent.Intensity, outro: true); } private void UpdateMusicVolume() { base.IntensityEvent.AudioSource.volume = (float)ConfigManager.IntensityR_MusicVolume.Value * 0.01f; } public void TransitionToEnemyProximity() { _forceEndMusic = true; _endToEnemyProximityState = true; } } } namespace com.github.zehsteam.CS2_OST.MonoBehaviours { public class AudioEventManager : MonoBehaviour { public List<AudioEvent> AudioEvents = new List<AudioEvent>(); public WinEvent WinEvent; public DeathEvent DeathEvent; public LoseEvent LoseEvent; public IntensityEvent IntensityEvent; public FinalExtractEvent FinalExtractEvent; public static AudioEventManager Instance { get; private set; } public AudioEvent FocusedEvent { get; private set; } public static void Spawn() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)Instance != (Object)null)) { GameObject val = Object.Instantiate<GameObject>(Assets.AudioEventManagerPrefab); val.transform.SetLocalPositionAndRotation(Vector3.zero, Quaternion.identity); ((Object)val).hideFlags = (HideFlags)61; Object.DontDestroyOnLoad((Object)(object)val); } } private void Awake() { if ((Object)(object)Instance != (Object)null && (Object)(object)Instance != (Object)(object)this) { Object.Destroy((Object)(object)((Component)this).gameObject); return; } Instance = this; ((Object)((Component)this).gameObject).name = "CS2_OST AudioEventManager"; Logger.LogInfo("Instantiated \"" + ((Object)((Component)this).gameObject).name + "\"", extended: true); } public void OnNewLevel() { foreach (AudioEvent audioEvent in AudioEvents) { audioEvent.OnNewLevel(); } } public void SetFocus(AudioEvent focusedAudioEvent) { FocusedEvent = focusedAudioEvent; foreach (AudioEvent audioEvent in AudioEvents) { if (!((Object)(object)audioEvent == (Object)(object)focusedAudioEvent)) { audioEvent.OnOtherEventFocused(focusedAudioEvent); } } } public void StopAll() { foreach (AudioEvent audioEvent in AudioEvents) { audioEvent.OnStop(); } } } internal class PowerLevelDetector : MonoBehaviour { private Timer _checkTimer = new Timer(0.25f); private List<EnemyParent> _enemiesInRadius = new List<EnemyParent>(); public static PowerLevelDetector Instance { get; private set; } public static void Spawn() { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown //IL_0037: 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)(object)Instance != (Object)null)) { GameObject val = new GameObject("CS2_OST PowerLevelDetector", new Type[1] { typeof(PowerLevelDetector) }); val.transform.SetLocalPositionAndRotation(Vector3.zero, Quaternion.identity); ((Object)val).hideFlags = (HideFlags)61; Object.DontDestroyOnLoad((Object)(object)val); } } private void Awake() { if ((Object)(object)Instance != (Object)null && (Object)(object)Instance != (Object)(object)this) { Object.Destroy((Object)(object)((Component)this).gameObject); return; } Instance = this; Logger.LogInfo("Instantiated \"" + ((Object)((Component)this).gameObject).name + "\"", extended: true); } private void Update() { if (PlayerUtils.IsLocalPlayerAlive() && LevelHelper.CurrentLevelHasEnemies() && !((Object)(object)AudioEventManager.Instance == (Object)null) && !AudioEventManager.Instance.FinalExtractEvent.IsPlaying) { if (_checkTimer.IsFinished) { _checkTimer.Reset(); CheckEnemiesNearby(); } else { _checkTimer.Tick(Time.deltaTime); } } } private void CheckEnemiesNearby() { float num = ConfigManager.IntensityEP_EnemyCheckEnterRadius.Value; float num2 = ConfigManager.IntensityEP_EnemyCheckExitRadius.Value; foreach (EnemyParent spawnedEnemy in GetSpawnedEnemies()) { float distanceToLocalPlayer = GetDistanceToLocalPlayer(spawnedEnemy); if (distanceToLocalPlayer <= num) { _enemiesInRadius.AddSingle(spawnedEnemy); } } int count = _enemiesInRadius.Count; for (int num3 = count - 1; num3 >= 0; num3--) { EnemyParent val = _enemiesInRadius[num3]; float distanceToLocalPlayer2 = GetDistanceToLocalPlayer(val); if (distanceToLocalPlayer2 > num2) { _enemiesInRadius.Remove(val); } } float powerLevelForEnemies = PowerLevelConfigManager.GetPowerLevelForEnemies(_enemiesInRadius); AudioEventManager.Instance?.IntensityEvent.SetEnemyPowerLevel(powerLevelForEnemies); } private List<EnemyParent> GetSpawnedEnemies() { List<EnemyParent> list = new List<EnemyParent>(); foreach (EnemyParent item in EnemyDirector.instance.enemiesSpawned) { if (item.Spawned && !((Object)(object)item.Enemy == (Object)null) && !((Object)(object)item.Enemy.Rigidbody == (Object)null)) { list.Add(item); } } return list; } private float GetDistanceToLocalPlayer(EnemyParent enemyParent) { //IL_0032: 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) if ((Object)(object)enemyParent == (Object)null) { return float.MaxValue; } Transform transform = ((Component)PlayerAvatar.instance).transform; Transform transform2 = ((Component)enemyParent.Enemy.Rigidbody).transform; return Vector3.Distance(transform.position, transform2.position); } } } namespace com.github.zehsteam.CS2_OST.MonoBehaviours.AudioEvents { public enum AudioEventType { None = 0, Win = 1, Death = 2, Lose = 3, Intensity = 4, FinalExtract = 5, Unknown = 999 } public abstract class AudioEvent : MonoBehaviour { public AudioSource AudioSource; public bool IsPlaying { get { AudioSource audioSource = AudioSource; return audioSource != null && audioSource.isPlaying; } } public abstract AudioEventType Type { get; } public abstract float DefaultVolume01 { get; } protected virtual void Start() { FixAudioMixerGroup(); AudioSource.volume = DefaultVolume01; } private void FixAudioMixerGroup() { if ((Object)(object)AudioManager.instance == (Object)null) { Logger.LogError("FixAudioMixerGroup: Failed to fix audio mixer group. AudioManager instance is null."); } else { AudioSource.outputAudioMixerGroup = AudioManager.instance.MusicMasterGroup; } } protected bool TryStopCoroutine(ref Coroutine coroutine, bool setToNull = true) { if (coroutine == null) { return false; } ((MonoBehaviour)this).StopCoroutine(coroutine); if (setToNull) { coroutine = null; } return true; } public void SetFocus() { AudioEventManager.Instance?.SetFocus(this); } protected virtual float PlayClip(AudioClip clip, bool loop = false, bool skipUpdatingVolume = false) { if ((Object)(object)AudioSource == (Object)null) { LogError("PlayClip: Failed to play clip. AudioSource is null."); return 0f; } if ((Object)(object)clip == (Object)null) { LogError("PlayClip: Failed to play clip. AudioClip is null."); return 0f; } AudioSource.Stop(); if ((Object)(object)AudioSource.clip != (Object)(object)clip) { AudioSource.clip = clip; } AudioSource.loop = loop; if (!skipUpdatingVolume) { AudioSource.volume = DefaultVolume01; } AudioSource.Play(); return clip.length; } public abstract void OnNewLevel(); public abstract void OnOtherEventFocused(AudioEvent audioEvent); public abstract void OnStop(); protected void LogDebug(object data) { Log((LogLevel)32, data); } protected void LogInfo(object data, bool extended = false) { Log((LogLevel)16, data, extended); } protected void LogMessage(object data, bool extended = false) { Log((LogLevel)8, data, extended); } protected void LogWarning(object data, bool extended = false) { Log((LogLevel)4, data, extended); } protected void LogError(object data, bool extended = false) { Log((LogLevel)2, data, extended); } protected void LogFatal(object data, bool extended = false) { Log((LogLevel)1, data, extended); } protected void Log(LogLevel logLevel, object data, bool extended = false) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) string data2 = $"[{((object)this).GetType().Name}] {data}"; Logger.Log(logLevel, data2, extended); } } public class DeathEvent : AudioEvent { public override AudioEventType Type => AudioEventType.Death; public override float DefaultVolume01 => (float)ConfigManager.Death_MusicVolume.Value * 0.01f; public override void OnNewLevel() { } public override void OnOtherEventFocused(AudioEvent audioEvent) { if (audioEvent.Type == AudioEventType.Lose) { AudioSource.Stop(); } } public override void OnStop() { AudioSource.Stop(); } public void Play() { LogInfo("Playing.", extended: true); SetFocus(); PlayClip(Assets.SoundRegistry.DeathSFX); } } public class FinalExtractEvent : AudioEvent { public enum States { None, Starting, Looping, Ending } [CompilerGenerated] private sealed class <EndMusicCoroutine>d__17 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public FinalExtractEvent <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <EndMusicCoroutine>d__17(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Expected O, but got Unknown //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>4__this.LogInfo("EndMusic() called. Waiting for current music clip to finish...", extended: true); <>4__this.State = States.Ending; <>4__this.AudioSource.loop = false; <>2__current = (object)new WaitUntil((Func<bool>)(() => !<>4__this.AudioSource.isPlaying)); <>1__state = 1; return true; case 1: <>1__state = -1; <>4__this.LogInfo("Playing end music.", extended: true); <>4__this.PlayClip(Assets.SoundRegistry.FinalExtractMusicEnd); <>2__current = (object)new WaitUntil((Func<bool>)(() => !<>4__this.AudioSource.isPlaying)); <>1__state = 2; return true; case 2: <>1__state = -1; <>4__this.State = States.None; <>4__this._coroutine = null; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <PlayMusicCoroutine>d__16 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public FinalExtractEvent <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <PlayMusicCoroutine>d__16(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>4__this.State = States.Starting; <>4__this.LogInfo("Playing start music.", extended: true); <>4__this.PlayClip(Assets.SoundRegistry.FinalExtractMusicStart); <>2__current = (object)new WaitUntil((Func<bool>)(() => !<>4__this.AudioSource.isPlaying)); <>1__state = 1; return true; case 1: <>1__state = -1; <>4__this.LogInfo("Playing loop music.", extended: true); <>4__this.State = States.Looping; <>4__this.PlayClip(Assets.SoundRegistry.FinalExtractMusicLoop, loop: true); <>4__this._coroutine = null; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private Coroutine _coroutine; public override AudioEventType Type => AudioEventType.FinalExtract; public override float DefaultVolume01 => (float)ConfigManager.FinalExtract_MusicVolume.Value * 0.01f; public States State { get; private set; } public override void OnNewLevel() { Reset(); } public override void OnOtherEventFocused(AudioEvent audioEvent) { } public override void OnStop() { Reset(); } private void Reset() { TryStopCoroutine(ref _coroutine); AudioSource.Stop(); State = States.None; } public void PlayMusic() { if (State == States.None) { SetFocus(); TryStopCoroutine(ref _coroutine); _coroutine = ((MonoBehaviour)this).StartCoroutine(PlayMusicCoroutine()); } } public void EndMusic() { if (State != 0 && State != States.Ending) { if (TryStopCoroutine(ref _coroutine)) { LogInfo("Stopped coroutine.", extended: true); } _coroutine = ((MonoBehaviour)this).StartCoroutine(EndMusicCoroutine()); } } [IteratorStateMachine(typeof(<PlayMusicCoroutine>d__16))] private IEnumerator PlayMusicCoroutine() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <PlayMusicCoroutine>d__16(0) { <>4__this = this }; } [IteratorStateMachine(typeof(<EndMusicCoroutine>d__17))] private IEnumerator EndMusicCoroutine() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <EndMusicCoroutine>d__17(0) { <>4__this = this }; } } public class IntensityEvent : AudioEvent { public enum Intensities { None, Low, Medium, High } public override AudioEventType Type => AudioEventType.Intensity; public override float DefaultVolume01 => (float)ConfigManager.IntensityR_MusicVolume.Value * 0.01f; public Intensities Intensity { get; set; } public IntensityState CurrentState { get; private set; } public IntensityState PreviousState { get; private set; } public IdleState IdleState { get; private set; } public RandomMusicState RandomMusicState { get; private set; } public EnemyProximityState EnemyProximityState { get; private set; } public ValueHistory<float> EnemyPowerLevel { get; private set; } = new ValueHistory<float>(0f); private void Awake() { IdleState = new IdleState(this); RandomMusicState = new RandomMusicState(this); EnemyProximityState = new EnemyProximityState(this); ChangeState(IdleState); } private void Update() { if (PlayerUtils.IsLocalPlayerAlive() && LevelHelper.CurrentLevelHasEnemies()) { AudioEventManager instance = AudioEventManager.Instance; if (instance == null || !instance.FinalExtractEvent.IsPlaying) { CurrentState?.OnTick(); } } } public void ChangeState(IntensityState newState) { if (CurrentState != newState) { PreviousState = CurrentState; if (newState != null) { string text = PreviousState?.GetType().Name ?? "null"; string text2 = newState?.GetType().Name ?? "null"; LogInfo("Changing state " + text + " -> " + text2, extended: true); } PreviousState?.OnExit(); CurrentState = newState; CurrentState?.OnEnter(); } } public override void OnNewLevel() { Reset(); } public override void OnOtherEventFocused(AudioEvent audioEvent) { if (audioEvent.Type == AudioEventType.FinalExtract) { Reset(); } } public override void OnStop() { Reset(); } private void Reset() { AudioSource.Stop(); ChangeState(IdleState); LogInfo("RESET!", extended: true); } public float PlayIntensityClip(Intensities intensity, bool outro = false) { LogInfo($"PlayIntensityClip: Playing for intensity \"{intensity}\", outro: {outro}", extended: true); return PlayClip(GetClipForIntensity(intensity, outro), loop: false, skipUpdatingVolume: true); } public void SetEnemyPowerLevel(float enemyPowerLevel) { EnemyPowerLevel.Value = enemyPowerLevel; if (GetIntensityForEnemyPowerLevel() != 0 && EnemyPowerLevel.Value != EnemyPowerLevel.PreviousValue) { if (CurrentState is RandomMusicState randomMusicState) { randomMusicState.TransitionToEnemyProximity(); } else { ChangeState(EnemyProximityState); } } } public Intensities GetNextIntensity(Intensities intensity) { if (Intensities.Low > intensity) { return Intensities.Low; } if (Intensities.Medium > intensity) { return Intensities.Medium; } if (Intensities.High == intensity) { return Intensities.High; } return intensity; } public Intensities GetIntensityForEnemyPowerLevel() { return GetIntensityForEnemyPowerLevel(EnemyPowerLevel.Value); } public Intensities GetIntensityForEnemyPowerLevel(float enemyPowerLevel) { float value = ConfigManager.IntensityEP_PowerLevelForHighIntensity.Value; float value2 = ConfigManager.IntensityEP_PowerLevelForMediumIntensity.Value; float value3 = ConfigManager.IntensityEP_PowerLevelForLowIntensity.Value; Intensities result = Intensities.None; if (enemyPowerLevel >= value) { result = Intensities.High; } else if (enemyPowerLevel >= value2) { result = Intensities.Medium; } else if (enemyPowerLevel >= value3) { result = Intensities.Low; } return result; } public AudioClip GetClipForIntensity(Intensities intensity, bool outro = false) { if (1 == 0) { } AudioClip result = (AudioClip)(intensity switch { Intensities.None => null, Intensities.Low => outro ? Assets.SoundRegistry.IntensityMusicLowOutro : Assets.SoundRegistry.IntensityMusicLow, Intensities.Medium => outro ? Assets.SoundRegistry.IntensityMusicMediumOutro : Assets.SoundRegistry.IntensityMusicMedium, Intensities.High => outro ? Assets.SoundRegistry.IntensityMusicHighOutro : Assets.SoundRegistry.IntensityMusicHigh, _ => null, }); if (1 == 0) { } return result; } } public class LoseEvent : AudioEvent { public override AudioEventType Type => AudioEventType.Lose; public override float DefaultVolume01 => (float)ConfigManager.Lose_MusicVolume.Value * 0.01f; public override void OnNewLevel() { } public override void OnOtherEventFocused(AudioEvent audioEvent) { } public override void OnStop() { AudioSource.Stop(); } public void Play() { LogInfo("Playing.", extended: true); SetFocus(); PlayClip(Assets.SoundRegistry.LoseSFX); } } public class WinEvent : AudioEvent { public override AudioEventType Type => AudioEventType.Win; public override float DefaultVolume01 => (float)ConfigManager.Win_MusicVolume.Value * 0.01f; public override void OnNewLevel() { } public override void OnOtherEventFocused(AudioEvent audioEvent) { } public override void OnStop() { AudioSource.Stop(); } public void Play() { LogInfo("Playing.", extended: true); SetFocus(); PlayClip(Assets.SoundRegistry.WinSFX); } } } namespace com.github.zehsteam.CS2_OST.Managers { internal static class ConfigManager { public static ConfigFile ConfigFile { get; private set; } public static ConfigEntry<bool> General_ExtendedLogging { get; private set; } public static ConfigEntry<bool> LevelAmbience_ReplaceSounds { get; private set; } public static ConfigEntry<int> Win_MusicVolume { get; private set; } public static ConfigEntry<int> Death_MusicVolume { get; private set; } public static ConfigEntry<int> Lose_MusicVolume { get; private set; } public static ConfigEntry<int> IntensityR_MusicVolume { get; private set; } public static ConfigEntry<float> IntensityR_MusicChance { get; private set; } public static ConfigEntry<float> IntensityR_RollMusicChanceCooldown { get; private set; } public static ConfigEntry<float> IntensityR_PlayNextIntensityChance { get; private set; } public static ConfigEntry<float> IntensityR_PlayCurrentIntensityChance { get; private set; } public static ConfigEntry<bool> IntensityR_DecreaseCurrentIntensityChanceAfterEachAttempt { get; private set; } public static ConfigEntry<float> IntensityR_DecreaseCurrentIntensityChanceAmount { get; private set; } public static ConfigEntry<float> IntensityR_MinCurrentIntensityChance { get; private set; } public static ConfigEntry<float> IntensityEP_EnterStateMusicDelay { get; private set; } public static ConfigEntry<int> IntensityEP_MinMusicVolume { get; private set; } public static ConfigEntry<int> IntensityEP_MaxMusicVolume { get; private set; } public static ConfigEntry<int> IntensityEP_MaxMusicVolumeRadius { get; private set; } public static ConfigEntry<int> IntensityEP_EnemyCheckEnterRadius { get; private set; } public static ConfigEntry<int> IntensityEP_EnemyCheckExitRadius { get; private set; } public static ConfigEntry<float> IntensityEP_PowerLevelForLowIntensity { get; private set; } public static ConfigEntry<float> IntensityEP_PowerLevelForMediumIntensity { get; private set; } public static ConfigEntry<float> IntensityEP_PowerLevelForHighIntensity { get; private set; } public static ConfigEntry<int> FinalExtract_MusicVolume { get; private set; } public static ConfigEntry<int> FinalExtract_ExcludeRadius { get; private set; } public static void Initialize(ConfigFile configFile) { ConfigFile = configFile; BindConfigs(); } private static void BindConfigs() { General_ExtendedLogging = ConfigFile.Bind<bool>("General", "ExtendedLogging", false, "Enable extended logging."); Win_MusicVolume = ConfigFile.Bind("Win Music", "MusicVolume", 100, "The win music volume.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100)); Death_MusicVolume = ConfigFile.Bind("Death Music", "MusicVolume", 100, "The death music volume.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100)); Lose_MusicVolume = ConfigFile.Bind("Lose Music", "MusicVolume", 100, "The lose music volume.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100)); string text = "Intensity Music - Random"; IntensityR_MusicVolume = ConfigFile.Bind(text, "MusicVolume", 30, "The music volume.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100)); IntensityR_MusicChance = ConfigFile.Bind(text, "MusicChance", 5f, "The percent chance the music will start playing. This chance gets rolled every RollMusicChanceCooldown seconds.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f)); IntensityR_RollMusicChanceCooldown = ConfigFile.Bind(text, "RollMusicChanceCooldown", 10f, "The time in seconds between rolling MusicChance.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 120f)); IntensityR_PlayNextIntensityChance = ConfigFile.Bind(text, "PlayNextIntensityChance", 25f, "The percent chance the next intensity music will play after the current music clip ends.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f)); IntensityR_PlayCurrentIntensityChance = ConfigFile.Bind(text, "PlayCurrentIntensityChance", 90f, "The percent chance the current intensity music will play after the current music clip ends.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f)); IntensityR_DecreaseCurrentIntensityChanceAfterEachAttempt = ConfigFile.Bind<bool>(text, "DecreaseCurrentIntensityChanceAfterEachAttempt", true, "If enabled, will decrease PlayCurrentIntensityChance by DecreaseCurrentIntensityChanceAmount (with a minimum value of MinCurrentIntensityChance) every time the current music is played. PlayCurrentIntensityChance will reset to it's default value when the random music starts playing."); IntensityR_DecreaseCurrentIntensityChanceAmount = ConfigFile.Bind(text, "DecreaseCurrentIntensityChanceAmount", 2f, "The amount to temporarily decrease PlayCurrentIntensityChance by.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f)); IntensityR_MinCurrentIntensityChance = ConfigFile.Bind(text, "MinCurrentIntensityChance", 60f, "The minimum value PlayCurrentIntensityChance can be.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f)); string section = "Intensity Music - Enemy Proximity"; IntensityEP_EnemyCheckEnterRadius = ConfigFile.Bind(section, "EnemyCheckEnterRadius", 20, "The radius in meters to check for nearby enemies entering.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(5, 100)); IntensityEP_EnemyCheckExitRadius = ConfigFile.Bind(section, "EnemyCheckExitRadius", 25, "The radius in meters to check for nearby enemies exiting.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(5, 100)); IntensityEP_PowerLevelForLowIntensity = ConfigFile.Bind(section, "PowerLevelForLowIntensity", 1f, "The minimum amount of combined enemy power level to trigger low intensity music.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 20f)); IntensityEP_PowerLevelForMediumIntensity = ConfigFile.Bind(section, "PowerLevelForMediumIntensity", 2f, "The minimum amount of combined enemy power level to trigger medium intensity music.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 20f)); IntensityEP_PowerLevelForHighIntensity = ConfigFile.Bind(section, "PowerLevelForHighIntensity", 4f, "The minimum amount of combined enemy power level to trigger high intensity music.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 20f)); IntensityEP_EnterStateMusicDelay = ConfigFile.Bind(section, "EnterStateMusicDelay", 2f, "The delay in seconds to wait before starting the enemy proximity intensity music.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10f)); IntensityEP_MinMusicVolume = ConfigFile.Bind(section, "MinMusicVolume", 50, "The minimum music volume. Music volume will be determined by the distance you are from the nearest enemy.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100)); IntensityEP_MaxMusicVolume = ConfigFile.Bind(section, "MaxMusicVolume", 100, "The maximum music volume. Music volume will be determined by the distance you are from the nearest enemy.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100)); IntensityEP_MaxMusicVolumeRadius = ConfigFile.Bind(section, "MaxMusicVolumeRadius", 5, "The maximum distance you have to be from any enemy for the maximum music volume.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100)); FinalExtract_MusicVolume = ConfigFile.Bind("Final Extract Music", "MusicVolume", 100, "The final extract music volume.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100)); FinalExtract_ExcludeRadius = ConfigFile.Bind("Final Extract Music", "ExcludeRadius", 30, "The distance in meters the local player has to be away from the truck for the final extract music to play.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100)); } } internal static class PowerLevelConfigManager { private static readonly Dictionary<string, ConfigEntry<float>> _configEntries; private static readonly Dictionary<string, float> _presetDefaultValues; private static bool _generatedConfigs; public static IReadOnlyDictionary<string, ConfigEntry<float>> ConfigEntries => _configEntries; static PowerLevelConfigManager() { _configEntries = new Dictionary<string, ConfigEntry<float>>(); _presetDefaultValues = new Dictionary<string, float>(); _presetDefaultValues.TryAdd("Peeper", 1f); _presetDefaultValues.TryAdd("Shadow Child", 1f); _presetDefaultValues.TryAdd("Gnome", 0.25f); _presetDefaultValues.TryAdd("Apex Predator", 0.5f); _presetDefaultValues.TryAdd("Spewer", 1f); _presetDefaultValues.TryAdd("Tick", 0.5f); _presetDefaultValues.TryAdd("Birthday Boy", 1f); _presetDefaultValues.TryAdd("Elsa", 0.5f); _presetDefaultValues.TryAdd("Bella", 1.5f); _presetDefaultValues.TryAdd("Rugrat", 1f); _presetDefaultValues.TryAdd("Animal", 0.5f); _presetDefaultValues.TryAdd("Upscream", 1.5f); _presetDefaultValues.TryAdd("Hidden", 1f); _presetDefaultValues.TryAdd("Chef", 1f); _presetDefaultValues.TryAdd("Bowtie", 2f); _presetDefaultValues.TryAdd("Mentalist", 2f); _presetDefaultValues.TryAdd("Banger", 0.34f); _presetDefaultValues.TryAdd("Gambit", 1f); _presetDefaultValues.TryAdd("Heart Hugger", 2f); _presetDefaultValues.TryAdd("Headgrab", 1f); _presetDefaultValues.TryAdd("Oogly", 2f); _presetDefaultValues.TryAdd("Headman", 5f); _presetDefaultValues.TryAdd("Robe", 5f); _presetDefaultValues.TryAdd("Huntsman", 3f); _presetDefaultValues.TryAdd("Reaper", 3f); _presetDefaultValues.TryAdd("Clown", 4f); _presetDefaultValues.TryAdd("Trudge", 5f); _presetDefaultValues.TryAdd("Loom", 5f); _presetDefaultValues.TryAdd("Cleanup Crew", 3f); } public static void GenerateConfigs() { if (_generatedConfigs) { return; } _generatedConfigs = true; if ((Object)(object)EnemyDirector.instance == (Object)null) { Logger.LogError("[PowerLevelConfigManager] Failed to generate configs. EnemyDirector instance is null."); return; } Dictionary<string, EnemySetup> dictionary = new Dictionary<string, EnemySetup>(); foreach (EnemySetup enemy in EnemyDirector.instance.GetEnemies()) { if (enemy.TryGetEnemyParent(out var enemyParent)) { dictionary.TryAdd(enemyParent.enemyName, enemy); } } List<EnemySetup> list = (from kvp in dictionary orderby kvp.Key select kvp.Value).ToList(); foreach (EnemySetup item in list) { GenerateConfigForEnemy(item); } } private static void GenerateConfigForEnemy(EnemySetup enemySetup) { if ((Object)(object)enemySetup == (Object)null || !enemySetup.TryGetEnemyParent(out var enemyParent)) { return; } string enemyName = enemyParent.enemyName; if (!_configEntries.ContainsKey(enemyName)) { float defaultValue = 1f; if (_presetDefaultValues.TryGetValue(enemyName, out var value)) { defaultValue = value; } ConfigEntry<float> value2 = ConfigManager.ConfigFile.Bind("Enemy Power Levels", enemyName, defaultValue, "The power level for " + enemyName + ". When this enemy is in proximity, it will add to the total power level to determine which intensity music level to play.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 20f)); _configEntries.Add(enemyName, value2); } } public static float GetPowerLevelForEnemies(IEnumerable<EnemyParent> enemyParents) { return enemyParents.Sum((Func<EnemyParent, float>)GetPowerLevelForEnemy); } public static float GetPowerLevelForEnemy(EnemyParent enemyParent) { if ((Object)(object)enemyParent == (Object)null) { return 0f; } return GetPowerLevelForEnemy(enemyParent.enemyName); } public static float GetPowerLevelForEnemy(string enemyName) { if (_configEntries.TryGetValue(enemyName, out var value)) { return value.Value; } return 0f; } } } namespace com.github.zehsteam.CS2_OST.Helpers { internal static class EnemyHelper { public static float GetClosestEnemyDistanceToLocalPlayer() { //IL_00a0: 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) if ((Object)(object)EnemyDirector.instance == (Object)null) { return -1f; } float num = float.MaxValue; foreach (EnemyParent item in EnemyDirector.instance.enemiesSpawned) { if (item.Spawned && !((Object)(object)item.Enemy == (Object)null) && !((Object)(object)item.Enemy.Rigidbody == (Object)null)) { Transform transform = ((Component)PlayerAvatar.instance).transform; Transform transform2 = ((Component)item.Enemy.Rigidbody).transform; float num2 = Vector3.Distance(transform.position, transform2.position); if (num2 < num) { num = num2; } } } return num; } } internal static class LevelHelper { public static Level GetCurrentLevel() { return RunManager.instance?.levelCurrent ?? null; } public static bool CurrentLevelHasEnemies() { Level currentLevel = GetCurrentLevel(); if ((Object)(object)currentLevel == (Object)null) { return false; } return currentLevel.HasEnemies; } } internal static class PlayerUtils { public static bool IsLocalPlayerAlive() { if ((Object)(object)PlayerAvatar.instance == (Object)null) { return false; } return !PlayerAvatar.instance.deadSet; } public static bool IsLocalPlayerInTruck() { if ((Object)(object)PlayerAvatar.instance == (Object)null) { return false; } return PlayerAvatar.instance.RoomVolumeCheck.inTruck; } public static int GetAlivePlayerCount() { if ((Object)(object)GameDirector.instance == (Object)null) { return 0; } return GameDirector.instance.PlayerList.Count((PlayerAvatar player) => !player.deadSet); } public static float GetLocalPlayerDistanceFromTruck() { //IL_003f: 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) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) PlayerAvatar instance = PlayerAvatar.instance; if ((Object)(object)instance == (Object)null) { return -1f; } RoomVolume truckRoomVolume = RoomVolume_Patches.TruckRoomVolume; if ((Object)(object)truckRoomVolume == (Object)null) { return -1f; } Vector3 position = ((Component)instance).transform.position; Vector3 val = ((Component)truckRoomVolume).transform.TransformPoint(new Vector3(0.5f, 0f, 1f)); return Vector3.Distance(position, val); } } internal static class Utils { public static bool RollPercentChance(float percent) { if (percent <= 0f) { return false; } if (percent >= 100f) { return true; } return Random.value * 100f <= percent; } } } namespace com.github.zehsteam.CS2_OST.Extensions { internal static class CollectionExtensions { public static bool AddSingle<T>(this List<T> list, T item) { if (list.Contains(item)) { return false; } list.Add(item); return true; } } internal static class ConfigFileExtensions { public static ConfigEntry<T> Bind<T>(this ConfigFile configFile, string section, string key, T defaultValue, string description, AcceptableValueBase acceptableValues) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown if (configFile == null) { Logger.LogError("Failed to bind config entry. ConfigFile is null."); return null; } if (acceptableValues == null) { return configFile.Bind<T>(section, key, defaultValue, description); } return configFile.Bind<T>(section, key, defaultValue, new ConfigDescription(description, acceptableValues, Array.Empty<object>())); } } internal static class EnemyDirectorExtensions { public static List<EnemySetup> GetEnemies(this EnemyDirector enemyDirector) { List<EnemySetup> enemiesDifficulty = enemyDirector.enemiesDifficulty1; List<EnemySetup> enemiesDifficulty2 = enemyDirector.enemiesDifficulty2; List<EnemySetup> enemiesDifficulty3 = enemyDirector.enemiesDifficulty3; List<EnemySetup> list = new List<EnemySetup>(enemiesDifficulty.Count + enemiesDifficulty2.Count + enemiesDifficulty3.Count); list.AddRange(enemiesDifficulty); list.AddRange(enemiesDifficulty2); list.AddRange(enemiesDifficulty3); return list; } } internal static class EnemySetupExtensions { public static EnemyParent GetEnemyParent(this EnemySetup enemySetup) { EnemyParent result = default(EnemyParent); foreach (PrefabRef spawnObject in enemySetup.spawnObjects) { if (spawnObject.Prefab.TryGetComponent<EnemyParent>(ref result)) { return result; } } return null; } public static bool TryGetEnemyParent(this EnemySetup enemySetup, out EnemyParent enemyParent) { enemyParent = enemySetup.GetEnemyParent(); return (Object)(object)enemyParent != (Object)null; } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }