using 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", assetBundle); AudioEventManagerPrefab = LoadAsset("AudioEventManager", assetBundle); } private static T LoadAsset(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(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(string name, AssetBundle assetBundle, out T asset) where T : Object { asset = LoadAsset(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 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 LevelAmbienceBreakers = new List(); [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 { 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 AudioEvents = new List(); 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(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 _enemiesInRadius = new List(); 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 GetSpawnedEnemies() { List list = new List(); 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 d__17 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public FinalExtractEvent <>4__this; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public 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)(() => !<>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)(() => !<>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 d__16 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public FinalExtractEvent <>4__this; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public 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)(() => !<>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(d__16))] private IEnumerator PlayMusicCoroutine() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__16(0) { <>4__this = this }; } [IteratorStateMachine(typeof(d__17))] private IEnumerator EndMusicCoroutine() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new 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 EnemyPowerLevel { get; private set; } = new ValueHistory(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 General_ExtendedLogging { get; private set; } public static ConfigEntry LevelAmbience_ReplaceSounds { get; private set; } public static ConfigEntry Win_MusicVolume { get; private set; } public static ConfigEntry Death_MusicVolume { get; private set; } public static ConfigEntry Lose_MusicVolume { get; private set; } public static ConfigEntry IntensityR_MusicVolume { get; private set; } public static ConfigEntry IntensityR_MusicChance { get; private set; } public static ConfigEntry IntensityR_RollMusicChanceCooldown { get; private set; } public static ConfigEntry IntensityR_PlayNextIntensityChance { get; private set; } public static ConfigEntry IntensityR_PlayCurrentIntensityChance { get; private set; } public static ConfigEntry IntensityR_DecreaseCurrentIntensityChanceAfterEachAttempt { get; private set; } public static ConfigEntry IntensityR_DecreaseCurrentIntensityChanceAmount { get; private set; } public static ConfigEntry IntensityR_MinCurrentIntensityChance { get; private set; } public static ConfigEntry IntensityEP_EnterStateMusicDelay { get; private set; } public static ConfigEntry IntensityEP_MinMusicVolume { get; private set; } public static ConfigEntry IntensityEP_MaxMusicVolume { get; private set; } public static ConfigEntry IntensityEP_MaxMusicVolumeRadius { get; private set; } public static ConfigEntry IntensityEP_EnemyCheckEnterRadius { get; private set; } public static ConfigEntry IntensityEP_EnemyCheckExitRadius { get; private set; } public static ConfigEntry IntensityEP_PowerLevelForLowIntensity { get; private set; } public static ConfigEntry IntensityEP_PowerLevelForMediumIntensity { get; private set; } public static ConfigEntry IntensityEP_PowerLevelForHighIntensity { get; private set; } public static ConfigEntry FinalExtract_MusicVolume { get; private set; } public static ConfigEntry FinalExtract_ExcludeRadius { get; private set; } public static void Initialize(ConfigFile configFile) { ConfigFile = configFile; BindConfigs(); } private static void BindConfigs() { General_ExtendedLogging = ConfigFile.Bind("General", "ExtendedLogging", false, "Enable extended logging."); Win_MusicVolume = ConfigFile.Bind("Win Music", "MusicVolume", 100, "The win music volume.", (AcceptableValueBase)(object)new AcceptableValueRange(0, 100)); Death_MusicVolume = ConfigFile.Bind("Death Music", "MusicVolume", 100, "The death music volume.", (AcceptableValueBase)(object)new AcceptableValueRange(0, 100)); Lose_MusicVolume = ConfigFile.Bind("Lose Music", "MusicVolume", 100, "The lose music volume.", (AcceptableValueBase)(object)new AcceptableValueRange(0, 100)); string text = "Intensity Music - Random"; IntensityR_MusicVolume = ConfigFile.Bind(text, "MusicVolume", 30, "The music volume.", (AcceptableValueBase)(object)new AcceptableValueRange(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(0f, 100f)); IntensityR_RollMusicChanceCooldown = ConfigFile.Bind(text, "RollMusicChanceCooldown", 10f, "The time in seconds between rolling MusicChance.", (AcceptableValueBase)(object)new AcceptableValueRange(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(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(0f, 100f)); IntensityR_DecreaseCurrentIntensityChanceAfterEachAttempt = ConfigFile.Bind(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(0f, 100f)); IntensityR_MinCurrentIntensityChance = ConfigFile.Bind(text, "MinCurrentIntensityChance", 60f, "The minimum value PlayCurrentIntensityChance can be.", (AcceptableValueBase)(object)new AcceptableValueRange(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(5, 100)); IntensityEP_EnemyCheckExitRadius = ConfigFile.Bind(section, "EnemyCheckExitRadius", 25, "The radius in meters to check for nearby enemies exiting.", (AcceptableValueBase)(object)new AcceptableValueRange(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(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(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(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(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(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(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(0, 100)); FinalExtract_MusicVolume = ConfigFile.Bind("Final Extract Music", "MusicVolume", 100, "The final extract music volume.", (AcceptableValueBase)(object)new AcceptableValueRange(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(0, 100)); } } internal static class PowerLevelConfigManager { private static readonly Dictionary> _configEntries; private static readonly Dictionary _presetDefaultValues; private static bool _generatedConfigs; public static IReadOnlyDictionary> ConfigEntries => _configEntries; static PowerLevelConfigManager() { _configEntries = new Dictionary>(); _presetDefaultValues = new Dictionary(); _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 dictionary = new Dictionary(); foreach (EnemySetup enemy in EnemyDirector.instance.GetEnemies()) { if (enemy.TryGetEnemyParent(out var enemyParent)) { dictionary.TryAdd(enemyParent.enemyName, enemy); } } List 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 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(0f, 20f)); _configEntries.Add(enemyName, value2); } } public static float GetPowerLevelForEnemies(IEnumerable enemyParents) { return enemyParents.Sum((Func)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(this List list, T item) { if (list.Contains(item)) { return false; } list.Add(item); return true; } } internal static class ConfigFileExtensions { public static ConfigEntry Bind(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(section, key, defaultValue, description); } return configFile.Bind(section, key, defaultValue, new ConfigDescription(description, acceptableValues, Array.Empty())); } } internal static class EnemyDirectorExtensions { public static List GetEnemies(this EnemyDirector enemyDirector) { List enemiesDifficulty = enemyDirector.enemiesDifficulty1; List enemiesDifficulty2 = enemyDirector.enemiesDifficulty2; List enemiesDifficulty3 = enemyDirector.enemiesDifficulty3; List list = new List(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(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) { } } }