Decompiled source of CS2 OST v1.0.1

com.github.zehsteam.CS2_OST.dll

Decompiled 2 months ago
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>("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)
		{
		}
	}
}