Decompiled source of WiresAcoustics v0.2.2

WiresAcoustics.dll

Decompiled 29 minutes ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using System.Threading;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Unity.Collections;
using Unity.Jobs;
using UnityEngine;
using UnityEngine.Animations;
using UnityEngine.Audio;
using UnityEngine.Jobs;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("WiresAcoustics")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+959f78499ddfd10b2bf6a6b5257d222e4522d219")]
[assembly: AssemblyProduct("WiresAcoustics")]
[assembly: AssemblyTitle("WiresAcoustics")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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 WiresAcoustics
{
	internal static class Ambience
	{
		private static readonly FieldRef<AudioMan, AudioSource> AmbientLoop = AccessTools.FieldRefAccess<AudioMan, AudioSource>("m_ambientLoopSource");

		private static readonly FieldRef<AudioMan, AudioSource> WindLoop = AccessTools.FieldRefAccess<AudioMan, AudioSource>("m_windLoopSource");

		private static readonly FieldRef<AudioMan, AudioSource> OceanLoop = AccessTools.FieldRefAccess<AudioMan, AudioSource>("m_oceanAmbientSource");

		private static float s_gain = 1f;

		private static float s_cutoff = 22000f;

		private static float s_open;

		private static float s_pan;

		private static float s_lean;

		private static AudioSource s_leanSrc0;

		private static AudioSource s_leanSrc1;

		private static AcousticFilter s_leanF0;

		private static AcousticFilter s_leanF1;

		private static Vector3 s_openDir;

		internal static void Pan(AudioMan man, Transform listener, float dt)
		{
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			int num;
			float num2;
			if (Plugin.Occlusion.Value && s_open > 0f && Room.Enclosure >= 0.35f)
			{
				num = ((((Vector3)(ref s_openDir)).sqrMagnitude > 0f) ? 1 : 0);
				if (num != 0)
				{
					num2 = Mathf.Clamp01(Room.Enclosure * 1.5f - 0.4f);
					goto IL_0058;
				}
			}
			else
			{
				num = 0;
			}
			num2 = 0f;
			goto IL_0058;
			IL_0058:
			float num3 = num2;
			float num4 = Mathf.Lerp(1f, 0.3f, Room.Enclosure * Room.Enclosure);
			float num5 = s_open * s_open / Mathf.Max(0.0001f, s_open * s_open + num4 * num4);
			float num6 = ((num != 0) ? (Mathf.Clamp(Vector3.Dot(listener.right, s_openDir) * 0.8f, -0.8f, 0.8f) * num3 * num5) : 0f);
			s_pan = Mathf.MoveTowards(s_pan, num6, 2f * dt);
			bool value = Plugin.Hrtf.Value;
			float num7 = (value ? Mathf.MoveTowards(s_lean, num3 * 0.8f * num5, dt) : 0f);
			if (num7 > 0f || s_lean > 0f)
			{
				s_lean = num7;
				Vector3 local = ((((Vector3)(ref s_openDir)).sqrMagnitude > 0f) ? listener.InverseTransformDirection(s_openDir) : Vector3.forward);
				Lean(AmbientLoop.Invoke(man), local);
				Lean(WindLoop.Invoke(man), local);
			}
			float num8 = (value ? 0f : s_pan);
			AudioSource val = AmbientLoop.Invoke(man);
			if (val != null && (Object)(object)val != (Object)null && val.panStereo != num8)
			{
				val.panStereo = num8;
			}
			AudioSource val2 = WindLoop.Invoke(man);
			if (val2 != null && (Object)(object)val2 != (Object)null && val2.panStereo != num8)
			{
				val2.panStereo = num8;
			}
		}

		private static void Lean(AudioSource src, Vector3 local)
		{
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)src == (Object)null)
			{
				return;
			}
			AcousticFilter acousticFilter = (((Object)(object)src == (Object)(object)s_leanSrc0) ? s_leanF0 : (((Object)(object)src == (Object)(object)s_leanSrc1) ? s_leanF1 : null));
			if ((Object)(object)acousticFilter == (Object)null)
			{
				acousticFilter = ((Component)src).GetComponent<AcousticFilter>();
				if ((Object)(object)acousticFilter == (Object)null)
				{
					if (s_lean <= 0.01f)
					{
						return;
					}
					acousticFilter = ((Component)src).gameObject.AddComponent<AcousticFilter>();
				}
				if ((Object)(object)s_leanSrc0 == (Object)null || (Object)(object)s_leanSrc0 == (Object)(object)src)
				{
					s_leanSrc0 = src;
					s_leanF0 = acousticFilter;
				}
				else
				{
					s_leanSrc1 = src;
					s_leanF1 = acousticFilter;
				}
			}
			acousticFilter.Kind = AcousticFilter.Kinds.Ambient;
			acousticFilter.Width = 1f - s_lean;
			acousticFilter.SetDirection(local);
			acousticFilter.Hrtf = s_lean > 0.01f;
			Need(acousticFilter);
		}

		internal static AudioSource Ocean(AudioMan man)
		{
			return OceanLoop.Invoke(man);
		}

		internal static bool IsAmbient(AudioSource src)
		{
			if ((Object)(object)AudioMan.instance != (Object)null && (Object)(object)src.outputAudioMixerGroup != (Object)null)
			{
				return (Object)(object)src.outputAudioMixerGroup == (Object)(object)AudioMan.instance.m_ambientMixer;
			}
			return false;
		}

		internal static void Update(AudioMan man, float enclosure)
		{
			float num = (Plugin.Occlusion.Value ? Mathf.Clamp(Plugin.OcclusionStrength.Value, 0f, 1.5f) : 0f);
			s_open = Portals.Openness(out s_openDir);
			float num2 = enclosure * enclosure * num * (1f - s_open);
			s_gain = Mathf.Clamp(Mathf.Lerp(1f, 0.3f, num2), 0.05f, 1f);
			s_cutoff = Mathf.Clamp(Mathf.Exp(Mathf.Lerp(Mathf.Log(22000f), Mathf.Log(700f), num2)), 200f, 22000f);
			Set(AmbientLoop.Invoke(man));
			Set(WindLoop.Invoke(man));
		}

		private static void Set(AudioSource src)
		{
			if ((Object)(object)src == (Object)null)
			{
				return;
			}
			AcousticFilter acousticFilter = ((Component)src).GetComponent<AcousticFilter>();
			if ((Object)(object)acousticFilter == (Object)null)
			{
				if (s_gain >= 0.999f && !AcousticFilter.GlobalActive)
				{
					return;
				}
				acousticFilter = ((Component)src).gameObject.AddComponent<AcousticFilter>();
			}
			acousticFilter.Kind = AcousticFilter.Kinds.Ambient;
			acousticFilter.Set(s_gain, s_cutoff, snap: false);
			Need(acousticFilter);
		}

		internal static void Apply(GameObject go, bool starting)
		{
			if (starting && s_pan != 0f)
			{
				AudioSource component = go.GetComponent<AudioSource>();
				if (component != null && (Object)(object)component != (Object)null)
				{
					float panStereo = component.panStereo;
					component.panStereo = Mathf.Clamp(panStereo + s_pan * (1f - Mathf.Abs(panStereo)), -1f, 1f);
				}
			}
			AcousticFilter acousticFilter = go.GetComponent<AcousticFilter>();
			if ((Object)(object)acousticFilter == (Object)null)
			{
				if (s_gain >= 0.999f && !AcousticFilter.GlobalActive)
				{
					return;
				}
				acousticFilter = go.AddComponent<AcousticFilter>();
			}
			acousticFilter.Set(s_gain, s_cutoff, starting);
			Need(acousticFilter);
		}

		private static void Need(AcousticFilter f)
		{
			bool active = f.Hrtf || s_gain < 0.999f || s_cutoff < 20000f || AcousticFilter.GlobalActive;
			if (!((Behaviour)f).enabled)
			{
				((Behaviour)f).enabled = true;
			}
			f.Active = active;
		}

		internal static void Reset()
		{
			s_gain = 1f;
			s_cutoff = 22000f;
			s_open = 0f;
			s_lean = 0f;
			if ((Object)(object)AudioMan.instance == (Object)null)
			{
				return;
			}
			s_pan = 0f;
			AudioSource val = AmbientLoop.Invoke(AudioMan.instance);
			if (val != null && (Object)(object)val != (Object)null)
			{
				val.panStereo = 0f;
			}
			AudioSource val2 = WindLoop.Invoke(AudioMan.instance);
			if (val2 != null && (Object)(object)val2 != (Object)null)
			{
				val2.panStereo = 0f;
			}
			AudioSource[] array = (AudioSource[])(object)new AudioSource[3]
			{
				AmbientLoop.Invoke(AudioMan.instance),
				WindLoop.Invoke(AudioMan.instance),
				OceanLoop.Invoke(AudioMan.instance)
			};
			foreach (AudioSource val3 in array)
			{
				if (!((Object)(object)val3 != (Object)null))
				{
					continue;
				}
				AcousticFilter component = ((Component)val3).GetComponent<AcousticFilter>();
				if (component != null)
				{
					component.Set(1f, 22000f, snap: false);
					if (component.Kind == AcousticFilter.Kinds.Ambient)
					{
						component.Hrtf = false;
					}
				}
			}
		}

		internal static string Summary()
		{
			return "ambience gain " + s_gain.ToString("F2") + ", low-pass " + s_cutoff.ToString("F0") + " Hz, openness " + s_open.ToString("F2") + ", pan " + s_pan.ToString("F2");
		}
	}
	internal static class Area
	{
		private struct Shape
		{
			internal Vector3 Center;

			internal Vector3 Half;

			internal bool Valid;
		}

		private static readonly Dictionary<int, Shape> Shapes = new Dictionary<int, Shape>();

		private const float Biggest = 4f;

		internal static void Measure(AcousticFilter f, Transform sound)
		{
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			if (f.AreaKnown)
			{
				return;
			}
			f.AreaKnown = true;
			Transform val = (((Object)(object)f.ShapeRoot != (Object)null) ? f.ShapeRoot : (((Object)(object)sound.parent != (Object)null) ? sound.root : null));
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			int instanceID = ((Object)val).GetInstanceID();
			if (!Shapes.TryGetValue(instanceID, out var value))
			{
				if (Shapes.Count > 8192)
				{
					Shapes.Clear();
				}
				value = Of(val);
				Shapes[instanceID] = value;
			}
			if (value.Valid)
			{
				f.ShapeRoot = val;
				f.ShapeCenter = value.Center;
				f.ShapeHalf = value.Half;
				f.AreaRadius = Mathf.Max(value.Half.x, value.Half.z);
			}
		}

		private static Shape Of(Transform owner)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			Bounds val = default(Bounds);
			bool flag = false;
			if ((Object)(object)((Component)owner).GetComponent<Character>() != (Object)null)
			{
				CapsuleCollider component = ((Component)owner).GetComponent<CapsuleCollider>();
				if (component != null && ((Collider)component).enabled)
				{
					Bounds bounds = ((Collider)component).bounds;
					Vector3 extents = ((Bounds)(ref bounds)).extents;
					if (extents.x > 4f || extents.y > 4f || extents.z > 4f)
					{
						return default(Shape);
					}
					Shape result = default(Shape);
					bounds = ((Collider)component).bounds;
					result.Center = owner.InverseTransformPoint(((Bounds)(ref bounds)).center);
					result.Half = extents;
					result.Valid = true;
					return result;
				}
			}
			Collider[] componentsInChildren = ((Component)owner).GetComponentsInChildren<Collider>();
			foreach (Collider val2 in componentsInChildren)
			{
				if (!((Object)(object)val2 == (Object)null) && !val2.isTrigger && val2.enabled)
				{
					if (!flag)
					{
						val = val2.bounds;
						flag = true;
					}
					else
					{
						((Bounds)(ref val)).Encapsulate(val2.bounds);
					}
				}
			}
			if (!flag)
			{
				return default(Shape);
			}
			Vector3 extents2 = ((Bounds)(ref val)).extents;
			if (extents2.x > 4f || extents2.y > 4f || extents2.z > 4f)
			{
				return default(Shape);
			}
			return new Shape
			{
				Center = owner.InverseTransformPoint(((Bounds)(ref val)).center),
				Half = extents2,
				Valid = true
			};
		}

		internal static int Points(AcousticFilter f, Vector3 listener, Vector3[] into)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: 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)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: 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_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			Transform shapeRoot = f.ShapeRoot;
			if ((Object)(object)shapeRoot == (Object)null || f.AreaRadius <= 0f)
			{
				return 0;
			}
			Vector3 val = shapeRoot.TransformPoint(f.ShapeCenter);
			Vector3 val2 = Vector3.Cross(Vector3.up, val - listener);
			val2 = ((((Vector3)(ref val2)).sqrMagnitude > 0.0001f) ? ((Vector3)(ref val2)).normalized : Vector3.right);
			float num = Mathf.Max(f.ShapeHalf.x, f.ShapeHalf.z) * 0.85f;
			into[0] = val;
			into[1] = val + val2 * num;
			into[2] = val - val2 * num;
			into[3] = val + Vector3.up * f.ShapeHalf.y * 0.85f;
			return 4;
		}

		internal static float WidthAt(float radius, float dist)
		{
			if (!(radius <= 0f))
			{
				return Mathf.Clamp01(2f * Mathf.Atan2(radius, Mathf.Max(0.1f, dist)) / (float)Math.PI);
			}
			return 0f;
		}
	}
	internal static class Batch
	{
		private struct Req
		{
			internal AcousticFilter F;

			internal Vector3 To;

			internal Vector3 Listener;

			internal bool Under;

			internal bool Reverb;

			internal bool Corners;

			internal int An;

			internal Vector3 A0;

			internal Vector3 A1;

			internal Vector3 A2;

			internal Vector3 A3;

			internal int First;

			internal int Routes;

			internal Portals.Portal P0;

			internal Portals.Portal P1;

			internal Vector3 C0;

			internal Vector3 C1;

			internal Vector3 C2;

			internal Vector3 C3;

			internal Vector3 C4;

			internal int Bn;

			internal Bounces.Try B0;

			internal Bounces.Try B1;

			internal Bounces.Try B2;
		}

		private const int MaxHits = 8;

		private static readonly Bounces.Try[] Tried = new Bounces.Try[3];

		private static readonly Vector3[] APts = (Vector3[])(object)new Vector3[4];

		private static readonly List<Req> Queue = new List<Req>(64);

		private static readonly Vector3[] Pts = (Vector3[])(object)new Vector3[5];

		private static Req[] s_flight = new Req[64];

		private static int s_flightCount;

		private static NativeArray<RaycastCommand> s_cmds;

		private static NativeArray<RaycastHit> s_hits;

		private static JobHandle s_job;

		private static bool s_pending;

		private static bool s_shore;

		internal static void Enqueue(AcousticFilter f, Vector3 to, bool under, bool reverb)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			Queue.Add(new Req
			{
				F = f,
				To = to,
				Under = under,
				Reverb = reverb,
				Corners = (f.LastOcc >= 0.3f)
			});
		}

		internal static void Step(Vector3 listener)
		{
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_04de: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_04eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_020c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0211: Unknown result type (might be due to invalid IL or missing references)
			//IL_021e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_0230: Unknown result type (might be due to invalid IL or missing references)
			//IL_0235: Unknown result type (might be due to invalid IL or missing references)
			//IL_024b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0253: Unknown result type (might be due to invalid IL or missing references)
			//IL_0258: Unknown result type (might be due to invalid IL or missing references)
			//IL_0259: Unknown result type (might be due to invalid IL or missing references)
			//IL_028b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0292: Unknown result type (might be due to invalid IL or missing references)
			//IL_0297: Unknown result type (might be due to invalid IL or missing references)
			//IL_0298: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02df: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0300: Unknown result type (might be due to invalid IL or missing references)
			//IL_032f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0334: Unknown result type (might be due to invalid IL or missing references)
			//IL_0341: Unknown result type (might be due to invalid IL or missing references)
			//IL_0346: Unknown result type (might be due to invalid IL or missing references)
			//IL_0353: Unknown result type (might be due to invalid IL or missing references)
			//IL_0358: Unknown result type (might be due to invalid IL or missing references)
			//IL_0365: Unknown result type (might be due to invalid IL or missing references)
			//IL_036a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0377: Unknown result type (might be due to invalid IL or missing references)
			//IL_037c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0391: Unknown result type (might be due to invalid IL or missing references)
			//IL_0396: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03be: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_046a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0471: Unknown result type (might be due to invalid IL or missing references)
			//IL_0476: Unknown result type (might be due to invalid IL or missing references)
			//IL_0477: Unknown result type (might be due to invalid IL or missing references)
			if (s_pending)
			{
				((JobHandle)(ref s_job)).Complete();
				s_pending = false;
				Apply();
			}
			int count = Queue.Count;
			if (count == 0)
			{
				return;
			}
			int num = Mathf.Min(2, Portals.List.Count);
			int num2 = 0;
			foreach (Req item in Queue)
			{
				num2 += 1 + num + (item.Corners ? 13 : 0) + (((Object)(object)item.F != (Object)null && item.F.AreaRadius > 0f) ? 4 : 0);
			}
			if (!s_cmds.IsCreated || s_cmds.Length < num2 || s_flight.Length < count)
			{
				if (s_cmds.IsCreated)
				{
					s_cmds.Dispose();
					s_hits.Dispose();
				}
				int num3 = Mathf.NextPowerOfTwo(Mathf.Max(64, num2));
				s_cmds = new NativeArray<RaycastCommand>(num3, (Allocator)4, (NativeArrayOptions)1);
				s_hits = new NativeArray<RaycastHit>(num3 * 8, (Allocator)4, (NativeArrayOptions)1);
				s_flight = new Req[Mathf.NextPowerOfTwo(Mathf.Max(64, count))];
			}
			QueryParameters q = default(QueryParameters);
			((QueryParameters)(ref q))..ctor(Room.Mask, false, (QueryTriggerInteraction)1, false);
			int num4 = 0;
			for (int i = 0; i < count; i++)
			{
				Req req = Queue[i];
				req.Listener = listener;
				req.First = num4;
				req.Routes = num;
				if (num > 0)
				{
					req.P0 = Portals.List[0];
				}
				if (num > 1)
				{
					req.P1 = Portals.List[1];
				}
				s_cmds[num4++] = Cast(listener, req.To, q);
				req.An = (((Object)(object)req.F != (Object)null) ? Area.Points(req.F, listener, APts) : 0);
				if (req.An > 0)
				{
					req.A0 = APts[0];
					req.A1 = APts[1];
					req.A2 = APts[2];
					req.A3 = APts[3];
				}
				for (int j = 0; j < req.An; j++)
				{
					s_cmds[num4++] = Cast(listener, APts[j], q);
				}
				if (num > 0)
				{
					s_cmds[num4++] = Cast(req.P0.Point, req.To, q);
				}
				if (num > 1)
				{
					s_cmds[num4++] = Cast(req.P1.Point, req.To, q);
				}
				if (req.Corners)
				{
					Vector3 to = req.To;
					float firstHit;
					if (!((Object)(object)req.F != (Object)null))
					{
						Vector3 val = req.To - listener;
						firstHit = ((Vector3)(ref val)).magnitude * 0.5f;
					}
					else
					{
						firstHit = req.F.LastBlockDist;
					}
					Corners.Around(listener, to, firstHit, Pts);
					req.C0 = Pts[0];
					req.C1 = Pts[1];
					req.C2 = Pts[2];
					req.C3 = Pts[3];
					req.C4 = Pts[4];
					Vector3[] pts = Pts;
					foreach (Vector3 val2 in pts)
					{
						s_cmds[num4++] = Cast(listener, val2, q);
						s_cmds[num4++] = Cast(val2, req.To, q);
					}
					req.Bn = Bounces.Pick(listener, req.To, Tried);
					if (req.Bn > 0)
					{
						req.B0 = Tried[0];
					}
					if (req.Bn > 1)
					{
						req.B1 = Tried[1];
					}
					if (req.Bn > 2)
					{
						req.B2 = Tried[2];
					}
					for (int l = 0; l < req.Bn; l++)
					{
						s_cmds[num4++] = Cast(Tried[l].End, req.To, q);
					}
				}
				s_flight[i] = req;
			}
			s_flightCount = count;
			Queue.Clear();
			s_job = RaycastCommand.ScheduleBatch(s_cmds.GetSubArray(0, num4), s_hits.GetSubArray(0, num4 * 8), 8, 8, default(JobHandle));
			JobHandle.ScheduleBatchedJobs();
			s_pending = true;
		}

		private static RaycastCommand Cast(Vector3 from, Vector3 to, QueryParameters q)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = to - from;
			float magnitude = ((Vector3)(ref val)).magnitude;
			if (!(magnitude > 0.6f))
			{
				return new RaycastCommand(from, Vector3.up, q, 0f);
			}
			return new RaycastCommand(from, val / magnitude, q, magnitude - 0.5f);
		}

		private static float Walls(int cmd, Vector3 to, out float first)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: 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)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			float num = 0f;
			first = float.MaxValue;
			for (int i = 0; i < 8; i++)
			{
				RaycastHit val = s_hits[cmd * 8 + i];
				if ((Object)(object)((RaycastHit)(ref val)).collider == (Object)null)
				{
					continue;
				}
				if (s_shore)
				{
					Vector3 val2 = ((RaycastHit)(ref val)).point - to;
					if (((Vector3)(ref val2)).sqrMagnitude < 225f && (Object)(object)((Component)((RaycastHit)(ref val)).collider).GetComponentInParent<Heightmap>() != (Object)null)
					{
						continue;
					}
				}
				float num2 = Occlusion.Counts(((RaycastHit)(ref val)).collider, to);
				if (!(num2 <= 0f))
				{
					num += num2;
					if (((RaycastHit)(ref val)).distance < first)
					{
						first = ((RaycastHit)(ref val)).distance;
					}
				}
			}
			return num;
		}

		private static void Consider(float occ, float lengthGain, Vector3 at, ref float bestGain, ref float bestCutoff, ref float bestOcc, ref Vector3 bestAt)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			Occlusion.Muffle(occ, out var gain, out var cutoff);
			gain *= lengthGain;
			if (!(gain <= bestGain))
			{
				bestGain = gain;
				bestCutoff = cutoff;
				bestOcc = occ;
				bestAt = at;
			}
		}

		private static void Apply()
		{
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0365: Unknown result type (might be due to invalid IL or missing references)
			//IL_036a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_042e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0430: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0247: Unknown result type (might be due to invalid IL or missing references)
			//IL_024c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0250: Unknown result type (might be due to invalid IL or missing references)
			//IL_025e: Unknown result type (might be due to invalid IL or missing references)
			//IL_026c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0271: Unknown result type (might be due to invalid IL or missing references)
			//IL_0274: Unknown result type (might be due to invalid IL or missing references)
			//IL_0280: Unknown result type (might be due to invalid IL or missing references)
			//IL_0285: Unknown result type (might be due to invalid IL or missing references)
			//IL_0288: Unknown result type (might be due to invalid IL or missing references)
			//IL_0292: Unknown result type (might be due to invalid IL or missing references)
			//IL_023f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_030b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0317: Unknown result type (might be due to invalid IL or missing references)
			//IL_031f: Unknown result type (might be due to invalid IL or missing references)
			//IL_032b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0237: Unknown result type (might be due to invalid IL or missing references)
			//IL_022f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			bool value = Plugin.Occlusion.Value;
			for (int i = 0; i < s_flightCount; i++)
			{
				Req req = s_flight[i];
				s_flight[i].F = null;
				AcousticFilter f = req.F;
				if ((Object)(object)f == (Object)null)
				{
					continue;
				}
				float num = 0f;
				float first = 0f;
				Occlusion.Own = (((Object)(object)f.ShapeRoot != (Object)null) ? f.ShapeRoot.root : null);
				s_shore = f.Kind == AcousticFilter.Kinds.Ocean;
				if (value)
				{
					num = Walls(req.First, req.To, out first);
				}
				f.LastOcc = num;
				float lastBlockDist;
				if (!(first < float.MaxValue))
				{
					Vector3 val = req.To - req.Listener;
					lastBlockDist = ((Vector3)(ref val)).magnitude * 0.5f;
				}
				else
				{
					lastBlockDist = first;
				}
				f.LastBlockDist = lastBlockDist;
				float bestGain = 0f;
				float bestCutoff = 22000f;
				float bestOcc = 0f;
				Vector3 bestAt = req.To;
				int num2 = req.First + 1;
				int num3 = 0;
				float first2;
				while (num3 < req.An)
				{
					if (value && num > 0.05f)
					{
						num = Mathf.Min(num, Walls(num2, (Vector3)(num3 switch
						{
							2 => req.A2, 
							1 => req.A1, 
							0 => req.A0, 
							_ => req.A3, 
						}), out first2));
					}
					num3++;
					num2++;
				}
				if (value && num >= 0.3f)
				{
					int num4 = 0;
					while (num4 < req.Routes)
					{
						Portals.Portal p = ((num4 == 0) ? req.P0 : req.P1);
						Consider(Walls(num2, req.To, out first2) + Portals.Bend(p, req.To), Portals.LengthGain(req.Listener, p, req.To), p.Point, ref bestGain, ref bestCutoff, ref bestOcc, ref bestAt);
						num4++;
						num2++;
					}
				}
				else
				{
					num2 += req.Routes;
				}
				if (req.Corners)
				{
					int num5 = 0;
					while (num5 < 5)
					{
						if (value && !(f.LastOcc < 0.3f))
						{
							Vector3 val2 = (Vector3)(num5 switch
							{
								3 => req.C3, 
								2 => req.C2, 
								1 => req.C1, 
								0 => req.C0, 
								_ => req.C4, 
							});
							Consider(Walls(num2, val2, out first2) + Walls(num2 + 1, req.To, out first2) + Corners.Bend(req.Listener, val2, req.To), Corners.LengthGain(req.Listener, val2, req.To), val2, ref bestGain, ref bestCutoff, ref bestOcc, ref bestAt);
						}
						num5++;
						num2 += 2;
					}
				}
				if (req.Corners)
				{
					int num6 = 0;
					while (num6 < req.Bn)
					{
						if (value && !(f.LastOcc < 0.3f))
						{
							Bounces.Try t = num6 switch
							{
								1 => req.B1, 
								0 => req.B0, 
								_ => req.B2, 
							};
							Consider(Walls(num2, req.To, out first2) + Bounces.Cost(t, req.To), Bounces.LengthGain(req.Listener, t, req.To), t.Heard, ref bestGain, ref bestCutoff, ref bestOcc, ref bestAt);
						}
						num6++;
						num2++;
					}
				}
				Occlusion.Muffle(num, out var gain, out var cutoff);
				bool routed = false;
				Vector3 routePoint = req.To;
				if (bestGain > 0f)
				{
					float num7 = gain * gain;
					float num8 = bestGain * bestGain;
					float num9 = num8 / (num7 + num8);
					cutoff = Mathf.Exp((num7 * Mathf.Log(cutoff) + num8 * Mathf.Log(bestCutoff)) / (num7 + num8));
					gain = Mathf.Min(1f, Mathf.Sqrt(num7 + num8));
					num = Mathf.Lerp(num, bestOcc, num9);
					routePoint = Vector3.Lerp(req.To, bestAt, num9);
					routed = num9 > 0.05f;
				}
				Occlusion.Own = null;
				s_shore = false;
				if (req.Under)
				{
					gain *= 0.45f;
					cutoff = Mathf.Min(cutoff, 400f);
				}
				f.Set(gain, cutoff, snap: false);
				f.Routed = routed;
				f.RoutePoint = routePoint;
				if (num > 0.05f && req.Reverb && (Object)(object)f.Source != (Object)null)
				{
					f.Source.reverbZoneMix = Mathf.Max(f.Source.reverbZoneMix, Mathf.Min(1f, 0.3f + 0.25f * num));
				}
			}
			s_flightCount = 0;
		}

		internal static void Flush()
		{
			if (s_pending)
			{
				((JobHandle)(ref s_job)).Complete();
				s_pending = false;
			}
			for (int i = 0; i < s_flightCount; i++)
			{
				s_flight[i].F = null;
			}
			s_flightCount = 0;
			Queue.Clear();
		}

		internal static void Shutdown()
		{
			Flush();
			if (s_cmds.IsCreated)
			{
				s_cmds.Dispose();
				s_hits.Dispose();
			}
		}
	}
	internal static class Bounces
	{
		internal struct Try
		{
			internal Vector3 Heard;

			internal Vector3 End;

			internal Vector3 Mirror;

			internal float Cost;

			internal float Length;
		}

		internal const int Count = 64;

		internal const int Tries = 3;

		internal static readonly Vector3[] P1 = (Vector3[])(object)new Vector3[64];

		internal static readonly Vector3[] P2 = (Vector3[])(object)new Vector3[64];

		internal static readonly Vector3[] R1 = (Vector3[])(object)new Vector3[64];

		internal static readonly Vector3[] R2 = (Vector3[])(object)new Vector3[64];

		internal static readonly float[] A1 = new float[64];

		internal static readonly float[] A2 = new float[64];

		internal static readonly bool[] Has1 = new bool[64];

		internal static readonly bool[] Has2 = new bool[64];

		private static readonly Vector3[] s_p1 = (Vector3[])(object)new Vector3[64];

		private static readonly Vector3[] s_r1 = (Vector3[])(object)new Vector3[64];

		private static readonly float[] s_a1 = new float[64];

		private static readonly bool[] s_has1 = new bool[64];

		private static readonly int[] Label = new int[64];

		private static NativeArray<RaycastCommand> s_cmds;

		private static NativeArray<RaycastHit> s_hits;

		private static JobHandle s_job;

		private static bool s_pending;

		private static int s_cast;

		private const float MaxDistance = 50f;

		internal static Vector3 EchoDir = Vector3.forward;

		internal static float EchoGain;

		internal static float EchoDist = 20f;

		internal static float EchoAbsorb = 0.1f;

		internal static void Schedule(Vector3[] dirs, float covered)
		{
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0265: Unknown result type (might be due to invalid IL or missing references)
			//IL_0261: Unknown result type (might be due to invalid IL or missing references)
			//IL_026a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0271: Unknown result type (might be due to invalid IL or missing references)
			//IL_0276: Unknown result type (might be due to invalid IL or missing references)
			//IL_027a: Unknown result type (might be due to invalid IL or missing references)
			//IL_027f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			if (s_pending)
			{
				((JobHandle)(ref s_job)).Complete();
				s_pending = false;
			}
			if (!s_cmds.IsCreated)
			{
				s_cmds = new NativeArray<RaycastCommand>(64, (Allocator)4, (NativeArrayOptions)1);
				s_hits = new NativeArray<RaycastHit>(64, (Allocator)4, (NativeArrayOptions)1);
			}
			QueryParameters val = default(QueryParameters);
			((QueryParameters)(ref val))..ctor(Room.Mask, false, (QueryTriggerInteraction)1, false);
			int num = 0;
			float num2 = 0f;
			float num3 = 0f;
			float num4 = 0f;
			int num5 = 0;
			Vector3 val2 = Vector3.forward;
			for (int i = 0; i < 64 && i < dirs.Length; i++)
			{
				s_has1[i] = Room.Hit[i];
				if (!s_has1[i])
				{
					continue;
				}
				float num6 = Room.Alpha[i];
				Vector3 val3 = Room.Normal[i];
				s_p1[i] = Room.Point[i] + val3 * 0.1f;
				s_r1[i] = Vector3.Reflect(dirs[i], val3);
				s_a1[i] = num6;
				s_cmds[num] = new RaycastCommand(s_p1[i], s_r1[i], val, 50f);
				Label[num] = i;
				num++;
				float num7 = Vector3.Dot(-dirs[i], val3);
				float num8 = Room.Dist[i];
				if (num8 >= 15f && num7 > 0.7f && dirs[i].y > -0.25f && !Room.Tree[i])
				{
					num5++;
					float num9 = num7 * (1f - num6) / num8;
					if (num9 > num2)
					{
						num2 = num9;
						num3 = num8;
						num4 = num6;
						val2 = dirs[i];
					}
				}
			}
			s_cast = num;
			if (num > 0)
			{
				s_job = RaycastCommand.ScheduleBatch(s_cmds.GetSubArray(0, num), s_hits.GetSubArray(0, num), 16, 1, default(JobHandle));
				JobHandle.ScheduleBatchedJobs();
				s_pending = true;
			}
			float num10 = 0f;
			if (num2 > 0f)
			{
				num10 = Mathf.Clamp01((float)(num5 - 1) / 3f) * (1f - num4) * Mathf.Clamp01(1.4f - 2f * covered);
				if (num10 > 0.005f)
				{
					Vector3 val4 = Vector3.Slerp((EchoGain > 0.005f) ? EchoDir : val2, val2, 0.5f);
					EchoDir = ((Vector3)(ref val4)).normalized;
					EchoDist = Mathf.Lerp((EchoGain > 0.005f) ? EchoDist : num3, num3, 0.5f);
					EchoAbsorb = num4;
				}
			}
			EchoGain = Mathf.Lerp(EchoGain, num10, 0.35f);
			if (EchoGain < 0.003f && num10 <= 0f)
			{
				EchoGain = 0f;
			}
		}

		internal static void Complete()
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			if (!s_pending)
			{
				return;
			}
			((JobHandle)(ref s_job)).Complete();
			s_pending = false;
			for (int i = 0; i < 64; i++)
			{
				Has1[i] = s_has1[i];
				P1[i] = s_p1[i];
				R1[i] = s_r1[i];
				A1[i] = s_a1[i];
				Has2[i] = false;
			}
			for (int j = 0; j < s_cast; j++)
			{
				int num = Label[j];
				if (Room.Surface(P1[num], R1[num], s_hits[j], 50f, out var point, out var normal, out var _, out var alpha, out var _))
				{
					P2[num] = point + normal * 0.1f;
					R2[num] = Vector3.Reflect(R1[num], normal);
					A2[num] = alpha;
					Has2[num] = true;
				}
			}
		}

		internal static void Clear()
		{
			if (s_pending)
			{
				((JobHandle)(ref s_job)).Complete();
				s_pending = false;
			}
			for (int i = 0; i < 64; i++)
			{
				Has1[i] = false;
				Has2[i] = false;
			}
			EchoGain = 0f;
		}

		internal static int Pick(Vector3 listener, Vector3 sound, Try[] into)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: 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)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			int got = 0;
			for (int i = 0; i < 64; i++)
			{
				if (Has1[i])
				{
					Vector3 val = P1[i] - listener;
					float magnitude = ((Vector3)(ref val)).magnitude;
					Consider(into, ref got, new Try
					{
						Heard = P1[i],
						End = P1[i],
						Mirror = R1[i],
						Cost = 1.5f * A1[i],
						Length = magnitude
					}, sound);
					if (Has2[i])
					{
						Try t = new Try
						{
							Heard = P1[i],
							End = P2[i],
							Mirror = R2[i],
							Cost = 1.5f * (A1[i] + A2[i])
						};
						val = P2[i] - P1[i];
						t.Length = magnitude + ((Vector3)(ref val)).magnitude;
						Consider(into, ref got, t, sound);
					}
				}
			}
			return got;
		}

		private static void Consider(Try[] into, ref int got, Try t, Vector3 sound)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			float length = t.Length;
			Vector3 val = sound - t.End;
			float num = length + ((Vector3)(ref val)).magnitude;
			int num2 = -1;
			if (got < 3)
			{
				num2 = got++;
			}
			else
			{
				float num3 = 0f;
				for (int i = 0; i < 3; i++)
				{
					float length2 = into[i].Length;
					val = sound - into[i].End;
					float num4 = length2 + ((Vector3)(ref val)).magnitude;
					if (num4 > num3)
					{
						num3 = num4;
						num2 = i;
					}
				}
				if (num >= num3)
				{
					return;
				}
			}
			into[num2] = t;
		}

		internal static float Cost(Try t, Vector3 sound)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			float cost = t.Cost;
			Vector3 mirror = t.Mirror;
			Vector3 val = sound - t.End;
			return cost + 0.5f * (1f - Vector3.Dot(mirror, ((Vector3)(ref val)).normalized));
		}

		internal static float LengthGain(Vector3 listener, Try t, Vector3 sound)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = sound - listener;
			float magnitude = ((Vector3)(ref val)).magnitude;
			float length = t.Length;
			val = sound - t.End;
			float num = length + ((Vector3)(ref val)).magnitude;
			return Mathf.Clamp(magnitude / Mathf.Max(0.01f, num), 0.25f, 1f);
		}

		internal static string Summary()
		{
			int num = 0;
			int num2 = 0;
			for (int i = 0; i < 64; i++)
			{
				if (Has1[i])
				{
					num++;
				}
				if (Has2[i])
				{
					num2++;
				}
			}
			return "bounces " + num + "+" + num2 + ", echo " + ((EchoGain > 0.003f) ? (EchoGain.ToString("F2") + " from " + EchoDist.ToString("F0") + " m") : "none");
		}

		internal static void Shutdown()
		{
			Clear();
			if (s_cmds.IsCreated)
			{
				s_cmds.Dispose();
				s_hits.Dispose();
			}
		}
	}
	internal static class Budget
	{
		internal const int Most = 32;

		internal const int Least = 4;

		private const float Every = 0.25f;

		private const float High = 0.2f;

		private const float Low = 0.1f;

		private static int s_count = 16;

		private static readonly List<AcousticFilter> Playing = new List<AcousticFilter>(128);

		private static float s_cutoff = float.MaxValue;

		private static float s_next;

		private static float s_load;

		private static float s_nextEchoDrop;

		private static int s_on;

		private static int s_calls;

		private static int s_hrtfCalls;

		private static float s_echoShare;

		private static long s_stamp;

		private static float s_perCall;

		private static readonly Comparison<AcousticFilter> Nearest = (AcousticFilter a, AcousticFilter b) => (a.AlwaysOn != b.AlwaysOn) ? ((!a.AlwaysOn) ? 1 : (-1)) : a.LastDist.CompareTo(b.LastDist);

		private static int s_toggles;

		private static long s_toggleTicks;

		private static long s_toggleWorst;

		private static readonly List<KeyValuePair<float, string>> Levels = new List<KeyValuePair<float, string>>();

		internal static void Note(AcousticFilter f, float dist)
		{
			f.LastDist = dist;
			if (!f.InBudget)
			{
				f.InBudget = true;
				Playing.Add(f);
			}
			if (f.Cue)
			{
				f.Active = false;
				return;
			}
			if (!((Behaviour)f).enabled)
			{
				Toggle(f, on: true);
			}
			if (!f.Active)
			{
				f.Active = true;
				s_on++;
			}
			f.Full = f.AlwaysOn || dist <= s_cutoff;
		}

		private static void Toggle(AcousticFilter f, bool on)
		{
			if (!Plugin.DebugLog.Value)
			{
				((Behaviour)f).enabled = on;
				return;
			}
			long timestamp = Stopwatch.GetTimestamp();
			((Behaviour)f).enabled = on;
			timestamp = Stopwatch.GetTimestamp() - timestamp;
			s_toggles++;
			s_toggleTicks += timestamp;
			if (timestamp > s_toggleWorst)
			{
				s_toggleWorst = timestamp;
			}
		}

		internal static string Toggles()
		{
			double num = 1000.0 / (double)Stopwatch.Frequency;
			string result = "filters switched " + s_toggles + " times (" + ((double)s_toggleTicks * num).ToString("F3") + " ms total, worst " + ((double)s_toggleWorst * num).ToString("F3") + " ms)";
			s_toggles = 0;
			s_toggleTicks = 0L;
			s_toggleWorst = 0L;
			return result;
		}

		internal static void Step(float now)
		{
			if (now < s_next)
			{
				return;
			}
			s_next = now + 0.25f;
			long timestamp = Stopwatch.GetTimestamp();
			long echoTicks;
			long num = AcousticFilter.TakeTicks(out s_calls, out echoTicks, out s_hrtfCalls);
			if (s_stamp != 0L && timestamp > s_stamp)
			{
				s_load = (float)num / (float)(timestamp - s_stamp);
			}
			s_echoShare = ((num > 0) ? ((float)echoTicks / (float)num) : 0f);
			s_perCall = ((s_calls > 0) ? ((float)((double)num * 1000000.0 / (double)Stopwatch.Frequency / (double)s_calls)) : 0f);
			s_stamp = timestamp;
			if (s_load > 0.2f)
			{
				s_count = Mathf.Max(4, s_count * 3 / 4);
			}
			else if (s_load < 0.1f)
			{
				s_count = Mathf.Min(32, s_count + 2);
			}
			for (int num2 = Playing.Count - 1; num2 >= 0; num2--)
			{
				AcousticFilter acousticFilter = Playing[num2];
				if ((Object)(object)acousticFilter == (Object)null || (Object)(object)acousticFilter.Source == (Object)null || !acousticFilter.Source.isPlaying)
				{
					if (acousticFilter != null)
					{
						acousticFilter.InBudget = false;
						if ((Object)(object)acousticFilter != (Object)null && acousticFilter.Kind != AcousticFilter.Kinds.Ambient)
						{
							acousticFilter.Active = false;
						}
					}
					Playing[num2] = Playing[Playing.Count - 1];
					Playing.RemoveAt(Playing.Count - 1);
				}
			}
			Playing.Sort(Nearest);
			int num3 = 0;
			s_on = 0;
			s_cutoff = float.MaxValue;
			foreach (AcousticFilter item in Playing)
			{
				if (!(item.Active = !item.Cue && item.NeedsWork))
				{
					continue;
				}
				s_on++;
				bool full = item.AlwaysOn || num3 < s_count || (item.Full && num3 < s_count + 2);
				if (!item.AlwaysOn)
				{
					if (num3 == s_count - 1)
					{
						s_cutoff = item.LastDist;
					}
					num3++;
				}
				item.Full = full;
			}
			if (num3 < s_count)
			{
				s_cutoff = float.MaxValue;
			}
			if (now >= s_nextEchoDrop)
			{
				s_nextEchoDrop = now + 1f;
				AcousticFilter.DropEchoes();
			}
		}

		internal static void Clear()
		{
			foreach (AcousticFilter item in Playing)
			{
				if (item != null)
				{
					item.InBudget = false;
				}
			}
			Playing.Clear();
			s_on = 0;
			s_cutoff = float.MaxValue;
		}

		internal static string Loudness()
		{
			AcousticFilter.Meter = Plugin.DebugLog.Value;
			double num = 0.0;
			double num2 = 0.0;
			Levels.Clear();
			foreach (AcousticFilter item in Playing)
			{
				if ((Object)(object)item == (Object)null || item.MeterIn <= 1E-09)
				{
					if ((Object)(object)item != (Object)null)
					{
						item.MeterIn = 0.0;
						item.MeterOut = 0.0;
					}
					continue;
				}
				num += item.MeterIn;
				num2 += item.MeterOut;
				float key = (float)(10.0 * Math.Log10(Math.Max(1E-12, item.MeterOut) / item.MeterIn));
				Levels.Add(new KeyValuePair<float, string>(key, ((Object)item).name + " " + key.ToString("+0.0;-0.0") + " dB at " + item.LastDist.ToString("F0") + " m" + (item.Full ? "" : " (light)") + " [" + item.Explain() + "]"));
				item.MeterIn = 0.0;
				item.MeterOut = 0.0;
			}
			if (num <= 1E-09)
			{
				return "level: nothing measured";
			}
			Levels.Sort((KeyValuePair<float, string> a, KeyValuePair<float, string> b) => a.Key.CompareTo(b.Key));
			StringBuilder stringBuilder = new StringBuilder("level after processing " + (10.0 * Math.Log10(num2 / num)).ToString("+0.0;-0.0") + " dB overall; most changed:");
			for (int num3 = 0; num3 < Levels.Count && num3 < 6; num3++)
			{
				stringBuilder.Append(" " + Levels[num3].Value + ";");
			}
			return stringBuilder.ToString();
		}

		internal static string Summary()
		{
			return "processing " + s_on + " of " + Playing.Count + " playing (full HRTF for the nearest " + s_count + "), audio thread " + (s_load * 100f).ToString("F1") + "% in " + s_calls + " callbacks (" + s_hrtfCalls + " with the HRTF), " + s_perCall.ToString("F1") + " us each, echo " + (s_echoShare * 100f).ToString("F0") + "% of it";
		}
	}
	internal static class Corners
	{
		internal const int Count = 5;

		internal static void Around(Vector3 listener, Vector3 sound, float firstHit, Vector3[] into)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: 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)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = sound - listener;
			float magnitude = ((Vector3)(ref val)).magnitude;
			Vector3 val2 = ((magnitude > 0.01f) ? (val / magnitude) : Vector3.forward);
			Vector3 val3 = Vector3.Cross(Vector3.up, val2);
			val3 = ((((Vector3)(ref val3)).sqrMagnitude > 0.0001f) ? ((Vector3)(ref val3)).normalized : Vector3.right);
			Vector3 val4 = listener + val2 * Mathf.Clamp(firstHit, 0.5f, Mathf.Max(0.5f, magnitude - 0.5f));
			into[0] = val4 + val3 * 2.5f;
			into[1] = val4 - val3 * 2.5f;
			into[2] = val4 + val3 * 5f;
			into[3] = val4 - val3 * 5f;
			into[4] = val4 + Vector3.up * 3f;
		}

		internal static float Bend(Vector3 listener, Vector3 p, Vector3 sound)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = p - listener;
			Vector3 normalized = ((Vector3)(ref val)).normalized;
			val = sound - p;
			return 0.3f * (1f - Vector3.Dot(normalized, ((Vector3)(ref val)).normalized));
		}

		internal static float LengthGain(Vector3 listener, Vector3 p, Vector3 sound)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = sound - listener;
			float magnitude = ((Vector3)(ref val)).magnitude;
			val = p - listener;
			float magnitude2 = ((Vector3)(ref val)).magnitude;
			val = sound - p;
			float num = magnitude2 + ((Vector3)(ref val)).magnitude;
			return Mathf.Clamp(magnitude / Mathf.Max(0.01f, num), 0.35f, 1f);
		}
	}
	internal static class Cost
	{
		internal struct Stat
		{
			internal long Total;

			internal long Worst;

			internal int Calls;

			internal bool WorstGc;
		}

		internal static Stat Tick;

		internal static Stat Scan;

		internal static Stat Sound;

		internal static Stat Measure;

		internal static Stat Batch;

		internal static Stat Recheck;

		internal static Stat Follow;

		internal static Stat Dirs;

		internal static Stat Rays;

		internal static Stat Rest;

		internal static Stat Budget;

		internal static Stat Travel;

		internal static long Start()
		{
			if (!Plugin.DebugLog.Value)
			{
				return 0L;
			}
			return Stopwatch.GetTimestamp();
		}

		internal static void Add(ref Stat s, long start)
		{
			if (start != 0L)
			{
				long num = Stopwatch.GetTimestamp() - start;
				s.Total += num;
				s.Calls++;
				if (num > s.Worst)
				{
					s.Worst = num;
				}
			}
		}

		internal static void AddTicks(ref Stat s, long t)
		{
			s.Total += t;
			s.Calls++;
			if (t > s.Worst)
			{
				s.Worst = t;
			}
		}

		internal static void AddTick(long start, int gcBefore)
		{
			if (start != 0L)
			{
				long num = Stopwatch.GetTimestamp() - start;
				Tick.Total += num;
				Tick.Calls++;
				if (num > Tick.Worst)
				{
					Tick.Worst = num;
					Tick.WorstGc = GC.CollectionCount(0) != gcBefore;
				}
			}
		}

		private static string Ms(long ticks)
		{
			return ((double)ticks * 1000.0 / (double)Stopwatch.Frequency).ToString("F3");
		}

		internal static string Report()
		{
			string result = "main thread: room ticks " + Tick.Calls + " (" + Ms(Tick.Total) + " ms total, worst " + Ms(Tick.Worst) + " ms" + (Tick.WorstGc ? ", the garbage collector ran in it" : "") + "), zone scans " + Scan.Calls + " (worst " + Ms(Scan.Worst) + " ms), sound checks " + Sound.Calls + " (" + Ms(Sound.Total) + " ms total, worst " + Ms(Sound.Worst) + " ms); worst per part: measure " + Ms(Measure.Worst) + ", batch " + Ms(Batch.Worst) + ", rechecks " + Ms(Recheck.Worst) + ", following " + Ms(Follow.Worst) + ", directions " + Ms(Dirs.Worst) + ", rays (waiting for their jobs) " + Ms(Rays.Worst) + ", budget " + Ms(Budget.Worst) + ", travel " + Ms(Travel.Worst) + ", the rest " + Ms(Rest.Worst) + " ms";
			Tick = (Scan = (Sound = (Measure = (Batch = (Recheck = (Follow = (Dirs = (Rays = (Rest = (Budget = (Travel = default(Stat))))))))))));
			return result;
		}
	}
	internal static class Directions
	{
		private struct Job : IJobParallelForTransform
		{
			public Vector3 Pos;

			public Quaternion InvRot;

			public NativeArray<Vector4> Dirs;

			public void Execute(int i, TransformAccess t)
			{
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0012: Unknown result type (might be due to invalid IL or missing references)
				//IL_0017: Unknown result type (might be due to invalid IL or missing references)
				//IL_001c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0035: Unknown result type (might be due to invalid IL or missing references)
				//IL_003a: 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)
				//IL_0041: Unknown result type (might be due to invalid IL or missing references)
				//IL_002d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0046: Unknown result type (might be due to invalid IL or missing references)
				//IL_004e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0054: 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_0061: Unknown result type (might be due to invalid IL or missing references)
				if (((TransformAccess)(ref t)).isValid)
				{
					Vector3 val = ((TransformAccess)(ref t)).position - Pos;
					float magnitude = ((Vector3)(ref val)).magnitude;
					Vector3 val2 = ((magnitude > 0.01f) ? (InvRot * (val / magnitude)) : Vector3.forward);
					Dirs[i] = new Vector4(val2.x, val2.y, val2.z, magnitude);
				}
			}
		}

		private static TransformAccessArray s_taa;

		private static NativeArray<Vector4> s_dirs;

		private static readonly List<AcousticFilter> List = new List<AcousticFilter>(256);

		private static readonly List<AcousticFilter> Changed = new List<AcousticFilter>(64);

		private static JobHandle s_job;

		private static bool s_pending;

		internal static void Want(AcousticFilter f)
		{
			if (!f.Queued)
			{
				f.Queued = true;
				Changed.Add(f);
			}
		}

		internal static void Step(Transform listener)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: 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)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: 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_034a: Unknown result type (might be due to invalid IL or missing references)
			//IL_034f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0357: Unknown result type (might be due to invalid IL or missing references)
			//IL_035c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0361: Unknown result type (might be due to invalid IL or missing references)
			//IL_0368: Unknown result type (might be due to invalid IL or missing references)
			//IL_036d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0374: Unknown result type (might be due to invalid IL or missing references)
			//IL_037d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0383: Unknown result type (might be due to invalid IL or missing references)
			//IL_0385: Unknown result type (might be due to invalid IL or missing references)
			//IL_038a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0240: Unknown result type (might be due to invalid IL or missing references)
			//IL_026d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0272: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0303: Unknown result type (might be due to invalid IL or missing references)
			//IL_0307: Unknown result type (might be due to invalid IL or missing references)
			//IL_030c: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f1: Unknown result type (might be due to invalid IL or missing references)
			if (s_pending)
			{
				((JobHandle)(ref s_job)).Complete();
				s_pending = false;
				Vector3 position = listener.position;
				Quaternion rotation = listener.rotation;
				Quaternion val = Quaternion.Inverse(rotation);
				Doppler.Frame(position);
				bool flag = Bounces.EchoGain > 0.003f;
				Vector3 val2 = position + Bounces.EchoDir * Bounces.EchoDist;
				float deltaTime = Time.deltaTime;
				Vector3 val3 = Vector3.zero;
				if ((Object)(object)EnvMan.instance != (Object)null)
				{
					val3 = EnvMan.instance.GetWindDir() * EnvMan.instance.GetWindIntensity();
				}
				Vector3 val6 = default(Vector3);
				for (int i = 0; i < List.Count; i++)
				{
					AcousticFilter acousticFilter = List[i];
					if ((Object)(object)acousticFilter == (Object)null)
					{
						continue;
					}
					Vector4 val4 = s_dirs[i];
					acousticFilter.LastDist = val4.w;
					if (acousticFilter.Placed)
					{
						Doppler.Update(acousticFilter, val4.w, deltaTime);
					}
					Vector3 val5;
					if (flag && acousticFilter.Placed)
					{
						val5 = position + rotation * new Vector3(val4.x, val4.y, val4.z) * val4.w - val2;
						float num = ((Vector3)(ref val5)).magnitude + Bounces.EchoDist;
						acousticFilter.EchoDelay = Mathf.Max(0f, num - val4.w) / 343f;
						acousticFilter.EchoShare = Mathf.Clamp(val4.w / Mathf.Max(0.1f, num), 0f, 0.5f);
					}
					((Vector3)(ref val6))..ctor(val4.x, val4.y, val4.z);
					if (acousticFilter.Placed)
					{
						Vector3 val7 = -(rotation * val6);
						float num2 = 1f + 0.35f * Vector3.Dot(val3, val7) * Mathf.Clamp01((val4.w - 15f) / 60f);
						acousticFilter.DistanceGain = acousticFilter.FadeAt(val4.w) * Mathf.Clamp(num2, 0.65f, 1.3f);
						if (acousticFilter.AreaRadius > 0f)
						{
							acousticFilter.Width = Mathf.Max(acousticFilter.BaseWidth, Area.WidthAt(acousticFilter.AreaRadius, val4.w));
						}
						Transform facing = acousticFilter.Facing;
						if ((Object)(object)facing != (Object)null)
						{
							float num3 = Vector3.Dot(facing.forward, val7);
							acousticFilter.FacingCutoff = ((num3 >= 0f) ? 22000f : Mathf.Exp(Mathf.Lerp(Mathf.Log(22000f), Mathf.Log(5000f), 0f - num3)));
						}
					}
					if (acousticFilter.Placed)
					{
						acousticFilter.AirCutoff = AcousticFilter.AirAt(val4.w);
					}
					if (acousticFilter.Hrtf && acousticFilter.Kind != AcousticFilter.Kinds.Ambient)
					{
						Vector3 direction;
						if (!acousticFilter.Routed)
						{
							direction = val6;
						}
						else
						{
							val5 = acousticFilter.RoutePoint - position;
							direction = val * ((Vector3)(ref val5)).normalized;
						}
						acousticFilter.SetDirection(direction);
					}
				}
			}
			Apply();
			if (List.Count != 0)
			{
				s_job = IJobParallelForTransformExtensions.ScheduleReadOnly<Job>(new Job
				{
					Pos = listener.position,
					InvRot = Quaternion.Inverse(listener.rotation),
					Dirs = s_dirs
				}, s_taa, 16, default(JobHandle));
				JobHandle.ScheduleBatchedJobs();
				s_pending = true;
			}
		}

		private static void Apply()
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			if (Changed.Count == 0)
			{
				return;
			}
			if (!((TransformAccessArray)(ref s_taa)).isCreated)
			{
				s_taa = new TransformAccessArray(256, -1);
			}
			foreach (AcousticFilter item in Changed)
			{
				if (item == null)
				{
					continue;
				}
				item.Queued = false;
				bool flag = (Object)(object)item != (Object)null && item.Tracked;
				if (flag && item.Slot < 0)
				{
					item.Slot = List.Count;
					List.Add(item);
					((TransformAccessArray)(ref s_taa)).Add(((Component)item).transform);
				}
				else if (!flag && item.Slot >= 0)
				{
					int slot = item.Slot;
					int index = List.Count - 1;
					((TransformAccessArray)(ref s_taa)).RemoveAtSwapBack(slot);
					AcousticFilter acousticFilter = List[index];
					List[slot] = acousticFilter;
					if (acousticFilter != null)
					{
						acousticFilter.Slot = slot;
					}
					List.RemoveAt(index);
					item.Slot = -1;
				}
			}
			Changed.Clear();
			if (!s_dirs.IsCreated || s_dirs.Length < List.Count)
			{
				if (s_dirs.IsCreated)
				{
					s_dirs.Dispose();
				}
				s_dirs = new NativeArray<Vector4>(Mathf.NextPowerOfTwo(Mathf.Max(256, List.Count)), (Allocator)4, (NativeArrayOptions)1);
			}
		}

		internal static void Idle()
		{
			Flush();
			Apply();
		}

		internal static void Flush()
		{
			if (s_pending)
			{
				((JobHandle)(ref s_job)).Complete();
				s_pending = false;
			}
		}

		internal static void Shutdown()
		{
			Flush();
			foreach (AcousticFilter item in List)
			{
				if (item != null)
				{
					item.Slot = -1;
				}
			}
			foreach (AcousticFilter item2 in Changed)
			{
				if (item2 != null)
				{
					item2.Queued = false;
				}
			}
			List.Clear();
			Changed.Clear();
			if (((TransformAccessArray)(ref s_taa)).isCreated)
			{
				((TransformAccessArray)(ref s_taa)).Dispose();
			}
			if (s_dirs.IsCreated)
			{
				s_dirs.Dispose();
			}
		}
	}
	internal static class Doppler
	{
		[HarmonyPatch(typeof(ZSFX), "CustomUpdate")]
		private static class Apply
		{
			private static void Postfix(ZSFX __instance, AudioSource ___m_audioSource)
			{
				if (!((Object)(object)___m_audioSource == (Object)null) && ___m_audioSource.isPlaying)
				{
					AcousticFilter component = ((Component)__instance).GetComponent<AcousticFilter>();
					if (!((Object)(object)component == (Object)null) && !(Mathf.Abs(component.Doppler - 1f) < 0.001f))
					{
						float num = BasePitch.Invoke(__instance) * PitchModifier.Invoke(__instance);
						num -= num * MistPitch.Invoke(__instance);
						___m_audioSource.pitch = num * component.Doppler;
					}
				}
			}
		}

		private static readonly FieldRef<ZSFX, float> BasePitch = AccessTools.FieldRefAccess<ZSFX, float>("m_basePitch");

		private static readonly FieldRef<ZSFX, float> PitchModifier = AccessTools.FieldRefAccess<ZSFX, float>("m_pitchModifier");

		private static readonly FieldRef<ZSFX, float> MistPitch = AccessTools.FieldRefAccess<ZSFX, float>("m_reverbPitchModifier");

		private const float MaxSpeed = 50f;

		private const float Jump = 2f;

		private static Vector3 s_lastListener;

		private static bool s_jumped;

		internal static void Frame(Vector3 listener)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = listener - s_lastListener;
			s_jumped = ((Vector3)(ref val)).sqrMagnitude > 4f;
			s_lastListener = listener;
		}

		internal static void Update(AcousticFilter f, float dist, float dt)
		{
			if (f.PrevDist < 0f || s_jumped || dt <= 0.0001f || !Plugin.RealDistance.Value)
			{
				f.PrevDist = dist;
				return;
			}
			float num = Mathf.Clamp((dist - f.PrevDist) / dt, -50f, 50f);
			f.PrevDist = dist;
			f.RadialSpeed = Mathf.Lerp(f.RadialSpeed, num, 0.2f);
			f.Doppler = 343f / (343f + f.RadialSpeed);
		}
	}
	[HarmonyPatch(typeof(Humanoid), "EquipItem")]
	internal static class Equip
	{
		private static void Prefix(Humanoid __instance)
		{
			if (Plugin.Enabled.Value)
			{
				Follow.Owner = ((Component)__instance).transform;
			}
		}

		private static void Finalizer()
		{
			Follow.Owner = null;
		}
	}
	public sealed class AcousticFilter : MonoBehaviour
	{
		internal enum Kinds : byte
		{
			Sfx,
			Voice,
			Ocean,
			Other,
			Menu,
			Ambient
		}

		internal static readonly List<AcousticFilter> Live = new List<AcousticFilter>(256);

		private static int s_rate = 48000;

		private static volatile float s_globalGain = 1f;

		private static volatile float s_globalCutoff = 22000f;

		internal static volatile bool GlobalActive;

		internal static volatile float Strength = 1f;

		private static long s_ticks;

		private static long s_ticksEcho;

		private static int s_calls;

		private static int s_hrtfCalls;

		private static volatile int s_channels;

		private static volatile int s_length;

		private volatile float m_targetGain = 1f;

		private volatile float m_targetCutoff = 22000f;

		private volatile bool m_snap = true;

		private volatile bool m_hrtf;

		private volatile float m_dx;

		private volatile float m_dy;

		private volatile float m_dz = 1f;

		internal float BaseSpread = -1f;

		internal AudioSource Source;

		internal bool Voice;

		internal bool Routed;

		internal Vector3 RoutePoint;

		internal Kinds Kind;

		internal float StartedAt;

		internal float LastOcc;

		internal float LastBlockDist;

		internal float PrevDist = -1f;

		internal float RadialSpeed;

		internal volatile float EchoDelay = 0.1f;

		internal volatile float EchoShare;

		internal volatile float Doppler = 1f;

		internal float LastDist = 1000000f;

		internal bool InBudget;

		internal volatile float Width;

		internal Transform ShapeRoot;

		internal Vector3 ShapeCenter;

		internal Vector3 ShapeHalf;

		internal float AreaRadius;

		internal bool AreaKnown;

		internal float BaseWidth;

		internal volatile bool Stereo = true;

		internal Transform Player;

		internal Transform Facing;

		internal volatile float FacingCutoff = 22000f;

		internal bool Cue;

		internal volatile float DistanceGain = 1f;

		internal volatile float AirCutoff = 22000f;

		private bool m_placed;

		private float m_gain = 1f;

		private float m_cutoff = 22000f;

		private readonly float[] m_state = new float[8];

		private const int Ring = 256;

		private const float HeadRadius = 0.0875f;

		private const float Sound = 343f;

		private readonly float[] m_ring = new float[256];

		private int m_pos;

		private bool m_primed;

		private float m_mono;

		private float m_side;

		private float m_delayL;

		private float m_delayR;

		private float m_headL;

		private float m_headR;

		private float m_backL;

		private float m_backR;

		private float m_gainL = 1f;

		private float m_gainR = 1f;

		private float m_x1L;

		private float m_x2L;

		private float m_y1L;

		private float m_y2L;

		private float m_x1R;

		private float m_x2R;

		private float m_y1R;

		private float m_y2R;

		internal int Slot = -1;

		internal bool Queued;

		private bool m_alive;

		private int m_liveIndex = -1;

		private volatile bool m_active = true;

		private const int EchoRing = 16384;

		private static readonly Stack<float[]> EchoPool = new Stack<float[]>();

		private static volatile float s_echoGain;

		private static volatile float s_echoL = 0.707f;

		private static volatile float s_echoR = 0.707f;

		private static volatile float s_echoCut = 4000f;

		private volatile float[] m_echo;

		private int m_echoPos;

		private float m_echoLevel;

		private float m_echoLp;

		private float m_echoAt;

		private bool m_physical;

		private AudioRolloffMode m_origMode;

		private float m_origMin;

		private float m_origMax;

		private float m_origDoppler;

		internal static volatile bool Meter;

		internal double MeterIn;

		internal double MeterOut;

		internal volatile bool Full = true;

		private bool m_wasFull;

		private bool m_wasFullKnown;

		private float[] m_cross;

		internal bool Hrtf
		{
			get
			{
				return m_hrtf;
			}
			set
			{
				if (m_hrtf != value)
				{
					m_hrtf = value;
					Directions.Want(this);
					Pan();
				}
			}
		}

		internal bool Placed
		{
			get
			{
				return m_placed;
			}
			set
			{
				if (m_placed != value)
				{
					m_placed = value;
					Directions.Want(this);
				}
			}
		}

		internal bool NeedsWork
		{
			get
			{
				if (!m_hrtf && !(m_gain < 0.999f) && !(m_cutoff < 20000f) && !(m_echoLevel > 0.0001f) && !(m_targetGain < 0.999f) && !(m_targetCutoff < 20000f) && !(AirCutoff < 20000f) && !(FacingCutoff < 20000f) && !(DistanceGain < 0.999f) && !(DistanceGain > 1.001f) && !GlobalActive)
				{
					if (s_echoGain > 0.0001f)
					{
						return LastDist <= 50f;
					}
					return false;
				}
				return true;
			}
		}

		internal bool AlwaysOn
		{
			get
			{
				if (!Voice && Kind != Kinds.Ocean && Kind != Kinds.Ambient)
				{
					return Kind == Kinds.Menu;
				}
				return true;
			}
		}

		internal bool Tracked
		{
			get
			{
				if (m_alive)
				{
					if (!m_hrtf)
					{
						return m_placed;
					}
					return true;
				}
				return false;
			}
		}

		internal bool Active
		{
			get
			{
				return m_active;
			}
			set
			{
				if (m_active != value)
				{
					m_active = value;
					if (value)
					{
						m_primed = false;
					}
					Pan();
				}
			}
		}

		internal static void SetGlobal(float gain, float cutoff, bool active)
		{
			s_globalGain = gain;
			s_globalCutoff = cutoff;
			GlobalActive = active;
		}

		internal static long TakeTicks(out int calls, out long echoTicks, out int hrtfCalls)
		{
			calls = Interlocked.Exchange(ref s_calls, 0);
			hrtfCalls = Interlocked.Exchange(ref s_hrtfCalls, 0);
			echoTicks = Interlocked.Exchange(ref s_ticksEcho, 0L);
			return Interlocked.Exchange(ref s_ticks, 0L);
		}

		internal static float AirAt(float dist)
		{
			return Mathf.Max(2500f, 22000f * Mathf.Exp((0f - Mathf.Max(0f, dist - 5f)) / 60f));
		}

		internal float FadeAt(float dist)
		{
			if (!m_physical || m_origMax <= 0f)
			{
				return 1f;
			}
			float num = Mathf.Clamp01((dist - 1.5f * m_origMax) / (1.5f * m_origMax));
			return 1f - num * num * (3f - 2f * num);
		}

		internal void TakePanning(float ownSpread)
		{
			if (!((Object)(object)Source == (Object)null))
			{
				if (BaseSpread < 0f)
				{
					BaseSpread = ownSpread;
					BaseWidth = Mathf.Clamp01((ownSpread - 150f) / 30f);
					Width = BaseWidth;
				}
				Pan();
			}
		}

		private void Pan()
		{
			if (!((Object)(object)Source == (Object)null) && !(BaseSpread < 0f))
			{
				float num = ((m_hrtf && ((Behaviour)this).enabled && m_active) ? 180f : BaseSpread);
				if (Source.spread != num)
				{
					Source.spread = num;
				}
			}
		}

		private void Awake()
		{
			s_rate = AudioSettings.outputSampleRate;
			Source = ((Component)this).GetComponent<AudioSource>();
			if ((Object)(object)((Component)this).GetComponent<ZSFX>() == (Object)null)
			{
				Kind = Kinds.Other;
			}
			m_alive = true;
			m_liveIndex = Live.Count;
			Live.Add(this);
			Directions.Want(this);
		}

		private void OnDestroy()
		{
			m_alive = false;
			if (m_liveIndex >= 0 && m_liveIndex < Live.Count && Live[m_liveIndex] == this)
			{
				int index = Live.Count - 1;
				AcousticFilter acousticFilter = Live[index];
				Live[m_liveIndex] = acousticFilter;
				acousticFilter.m_liveIndex = m_liveIndex;
				Live.RemoveAt(index);
			}
			else
			{
				Live.Remove(this);
			}
			m_liveIndex = -1;
			Directions.Want(this);
			ReleaseEcho();
		}

		private void OnEnable()
		{
			m_primed = false;
			Pan();
		}

		private void OnDisable()
		{
			Pan();
			ReleaseEcho();
		}

		internal static void SetEcho(float gain, Vector3 local)
		{
			//IL_0008: 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)
			s_echoGain = gain;
			float num = Mathf.Clamp(local.x, -1f, 1f);
			s_echoL = Mathf.Sqrt((1f - num) * 0.5f);
			s_echoR = Mathf.Sqrt((1f + num) * 0.5f);
			s_echoCut = Mathf.Lerp(4000f, 2200f, Mathf.Clamp01(0f - local.z));
		}

		internal void EnsureEcho()
		{
			if (m_echo == null && !Cue && ((Behaviour)this).enabled && m_active && !(LastDist > 50f) && (!((Object)(object)Source != (Object)null) || !Source.loop))
			{
				float[] array = ((EchoPool.Count > 0) ? EchoPool.Pop() : new float[16384]);
				Array.Clear(array, 0, array.Length);
				m_echoPos = 0;
				m_echoLevel = 0f;
				m_echoLp = 0f;
				m_echoAt = 0f;
				m_echo = array;
			}
		}

		private void ReleaseEcho()
		{
			float[] echo = m_echo;
			if (echo != null)
			{
				m_echo = null;
				if (EchoPool.Count < 128)
				{
					EchoPool.Push(echo);
				}
			}
		}

		internal static void DropEchoes()
		{
			foreach (AcousticFilter item in Live)
			{
				if ((Object)(object)item != (Object)null && item.m_echo != null && item.m_echoLevel < 0.0001f && (s_echoGain < 0.0001f || !item.m_active))
				{
					item.ReleaseEcho();
				}
			}
		}

		internal void Set(float gain, float cutoff, bool snap)
		{
			m_targetGain = gain;
			m_targetCutoff = cutoff;
			if (snap)
			{
				m_snap = true;
			}
		}

		internal void SetDirection(Vector3 d)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			m_dx = d.x;
			m_dy = d.y;
			m_dz = d.z;
		}

		internal static void ReleaseHrtf()
		{
			foreach (AcousticFilter item in Live)
			{
				if (!((Object)(object)item == (Object)null))
				{
					item.Hrtf = false;
					if (item.BaseSpread >= 0f && (Object)(object)item.Source != (Object)null)
					{
						item.Source.spread = item.BaseSpread;
					}
					item.BaseSpread = -1f;
				}
			}
		}

		internal static void ReleaseAll()
		{
			ReleaseHrtf();
			foreach (AcousticFilter item in Live)
			{
				if (!((Object)(object)item == (Object)null))
				{
					item.Set(1f, 22000f, snap: false);
					item.DistanceGain = 1f;
					item.AirCutoff = 22000f;
					item.Placed = false;
					item.Physical(on: false);
					if (((Behaviour)item).enabled)
					{
						((Behaviour)item).enabled = false;
					}
				}
			}
			Budget.Clear();
		}

		internal string Explain()
		{
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			return "gain " + m_targetGain.ToString("F2") + ", cut " + m_targetCutoff.ToString("F0") + ", air " + AirCutoff.ToString("F0") + ", facing " + FacingCutoff.ToString("F0") + ", distance " + DistanceGain.ToString("F2") + (m_physical ? (" (game's range " + m_origMax.ToString("F0") + " m)") : "") + ", width " + Width.ToString("F2") + (((Object)(object)Source != (Object)null) ? (", " + ((object)Source.rolloffMode/*cast due to .constrained prefix*/).ToString() + " " + Source.minDistance.ToString("F0") + "-" + Source.maxDistance.ToString("F0") + " m") : "");
		}

		internal void Physical(bool on)
		{
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)Source == (Object)null) && on != m_physical)
			{
				if (on)
				{
					m_origMode = Source.rolloffMode;
					m_origMin = Source.minDistance;
					m_origMax = Source.maxDistance;
					m_origDoppler = Source.dopplerLevel;
					Source.dopplerLevel = 0f;
					Source.rolloffMode = (AudioRolloffMode)0;
					Source.minDistance = Mathf.Max(0.5f, m_origMin);
					Source.maxDistance = Mathf.Max(0.5f, m_origMin) * 200f;
				}
				else
				{
					Source.rolloffMode = m_origMode;
					Source.minDistance = m_origMin;
					Source.maxDistance = m_origMax;
					Source.dopplerLevel = m_origDoppler;
					Doppler = 1f;
				}
				m_physical = on;
			}
		}

		internal static string Format()
		{
			return ((s_channels > 0) ? ("filter sees " + s_channels + " channel(s), " + s_length + " samples per buffer at " + s_rate + " Hz") : "filter not run yet") + ", " + Live.Count + " sounds known";
		}

		private static double Energy(float[] d)
		{
			double num = 0.0;
			for (int i = 0; i < d.Length; i++)
			{
				num += (double)(d[i] * d[i]);
			}
			return num;
		}

		private void OnAudioFilterRead(float[] data, int channels)
		{
			if (!m_active)
			{
				m_primed = false;
				m_wasFullKnown = false;
				return;
			}
			long timestamp = Stopwatch.GetTimestamp();
			bool meter = Meter;
			if (meter)
			{
				MeterIn += Energy(data);
			}
			Process(data, channels);
			long timestamp2 = Stopwatch.GetTimestamp();
			Echo(data, channels);
			if (meter)
			{
				MeterOut += Energy(data);
			}
			long timestamp3 = Stopwatch.GetTimestamp();
			Interlocked.Add(ref s_ticks, timestamp3 - timestamp);
			Interlocked.Add(ref s_ticksEcho, timestamp3 - timestamp2);
			Interlocked.Increment(ref s_calls);
			if (m_hrtf && channels >= 2)
			{
				Interlocked.Increment(ref s_hrtfCalls);
			}
		}

		private void Echo(float[] data, int ch)
		{
			float[] echo = m_echo;
			float num = (Full ? (s_echoGain * EchoShare) : 0f);
			if (echo == null || ch < 1)
			{
				return;
			}
			float echoLevel = m_echoLevel;
			if (num < 0.0001f && echoLevel < 0.0001f)
			{
				return;
			}
			int num2 = data.Length / ch;
			if (num2 == 0)
			{
				return;
			}
			int num3 = echo.Length - 1;
			float num4 = Mathf.Clamp(EchoDelay * (float)s_rate, 1f, (float)(echo.Length - 2));
			float num5 = ((m_echoAt > 0f) ? m_echoAt : num4);
			float num6 = (m_echoAt = Mathf.MoveTowards(num5, num4, (float)num2 * 0.02f));
			m_echoLevel = num;
			float num7 = s_echoL;
			float num8 = s_echoR;
			float num9 = 1f - Mathf.Exp((float)Math.PI * -2f * s_echoCut / (float)s_rate);
			int num10 = m_echoPos;
			float num11 = m_echoLp;
			float num12 = 1f / (float)num2;
			float num13 = num6 - num5;
			float num14 = num - echoLevel;
			int num15 = 0;
			int num16 = 0;
			while (num15 < num2)
			{
				float num17 = (float)num15 * num12;
				echo[num10] = ((ch >= 2) ? ((data[num16] + data[num16 + 1]) * 0.5f) : data[num16]);
				float num18 = echo[(num10 - (int)(num5 + num13 * num17)) & num3];
				num10 = (num10 + 1) & num3;
				num11 += num9 * (num18 - num11);
				float num19 = num11 * (echoLevel + num14 * num17);