Decompiled source of EnemySoundFixes v1.9.6

EnemySoundFixes.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using DunGen;
using DunGen.Graph;
using GameNetcodeStuff;
using HarmonyLib;
using LobbyCompatibility.Enums;
using LobbyCompatibility.Features;
using Microsoft.CodeAnalysis;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.Audio;
using UnityEngine.Events;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: AssemblyCompany("EnemySoundFixes")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Fixes numerous issues with missing sound effects, or SFX playing when they shouldn't.")]
[assembly: AssemblyFileVersion("1.9.6.0")]
[assembly: AssemblyInformationalVersion("1.9.6+8879bdbb1fcb54dc212a91af8a6789ee4048eaf6")]
[assembly: AssemblyProduct("EnemySoundFixes")]
[assembly: AssemblyTitle("EnemySoundFixes")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.9.6.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace EnemySoundFixes
{
	internal static class LobbyCompatibility
	{
		internal static void Init()
		{
			PluginHelper.RegisterPlugin("butterystancakes.lethalcompany.enemysoundfixes", Version.Parse("1.9.6"), (CompatibilityLevel)0, (VersionStrictness)0);
		}
	}
	internal enum CruiserMute
	{
		Nothing = -1,
		NotRadio,
		All
	}
	[BepInPlugin("butterystancakes.lethalcompany.enemysoundfixes", "Enemy Sound Fixes", "1.9.6")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		internal const string PLUGIN_GUID = "butterystancakes.lethalcompany.enemysoundfixes";

		internal const string PLUGIN_NAME = "Enemy Sound Fixes";

		internal const string PLUGIN_VERSION = "1.9.6";

		internal static ManualLogSource Logger;

		internal static ConfigEntry<bool> configThumperNoThunder;

		internal static ConfigEntry<bool> configBetterMimicSteps;

		internal static ConfigEntry<bool> configFixDoorSounds;

		internal static ConfigEntry<bool> configShootTheDog;

		internal static ConfigEntry<bool> configEclipsesBlockMusic;

		internal static ConfigEntry<bool> configWalkieHearsTalkies;

		internal static ConfigEntry<CruiserMute> configSpaceMutesCruiser;

		internal static ConfigEntry<float> configMusicDopplerLevel;

		private const string GUID_LOBBY_COMPATIBILITY = "BMX.LobbyCompatibility";

		private const string GUID_SOUND_API = "me.loaforc.soundapi";

		private const string GUID_UPTURNED_VARIETY = "butterystancakes.lethalcompany.upturnedvariety";

		internal static bool INSTALLED_SOUND_API;

		internal static bool INSTALLED_UPTURNED_VARIETY;

		private void Awake()
		{
			//IL_0214: Unknown result type (might be due to invalid IL or missing references)
			Logger = ((BaseUnityPlugin)this).Logger;
			if (Chainloader.PluginInfos.ContainsKey("BMX.LobbyCompatibility"))
			{
				Logger.LogInfo((object)"CROSS-COMPATIBILITY - Lobby Compatibility detected");
				LobbyCompatibility.Init();
			}
			if (Chainloader.PluginInfos.ContainsKey("me.loaforc.soundapi"))
			{
				INSTALLED_SOUND_API = true;
				Logger.LogInfo((object)"CROSS-COMPATIBILITY - loaforcsSoundAPI detected");
			}
			if (Chainloader.PluginInfos.ContainsKey("butterystancakes.lethalcompany.upturnedvariety"))
			{
				INSTALLED_UPTURNED_VARIETY = true;
				Logger.LogInfo((object)"CROSS-COMPATIBILITY - Upturned Variety detected");
			}
			configBetterMimicSteps = ((BaseUnityPlugin)this).Config.Bind<bool>("Misc", "BetterMimicSteps", true, "Mimic footstep volume and distance are altered to sound more accurate to actual players.");
			configThumperNoThunder = ((BaseUnityPlugin)this).Config.Bind<bool>("Misc", "ThumperNoThunder", true, "Thumpers no longer play thunder sound effects from their voice when they stop chasing after players.");
			configShootTheDog = ((BaseUnityPlugin)this).Config.Bind<bool>("Misc", "ShootTheDog", true, "Makes eyeless dogs play their stun sound effect on death, rather than falling silently.");
			configSpaceMutesCruiser = ((BaseUnityPlugin)this).Config.Bind<CruiserMute>("Misc", "SpaceMutesCruiser", CruiserMute.NotRadio, "What audio sources should be muted on the Cruiser when in orbit. (Engine sounds, the horn, the radio, etc.)");
			configFixDoorSounds = ((BaseUnityPlugin)this).Config.Bind<bool>("Misc", "FixDoorSounds", true, "Fixes backwards open/close sounds on breaker boxes and storage locker doors. Fixes Rend and Adamance cabin doors using steel door sounds.");
			configEclipsesBlockMusic = ((BaseUnityPlugin)this).Config.Bind<bool>("Misc", "EclipsesBlockMusic", true, "Prevents the morning/afternoon ambience music from playing during Eclipsed weather, which has its own ambient track.");
			configMusicDopplerLevel = ((BaseUnityPlugin)this).Config.Bind<float>("Misc", "MusicDopplerLevel", 0.333f, "Controls how much Unity's simulated \"Doppler effect\" applies to music sources like the dropship, boombox, etc. (This is what causes pitch distortion when moving towards/away from the source of the music)\n1 is the same as vanilla. 0 will disable it completely (so music always plays at the correct pitch)");
			configWalkieHearsTalkies = ((BaseUnityPlugin)this).Config.Bind<bool>("Misc", "WalkieHearsTalkies", true, "Restores a cut sound effect of idle chatter when walkie-talkies are in use. Only audible when standing near a walkie-talkie that is turned on, someone is transmitting their voice, and you do not have a walkie-talkie turned on in your inventory. (This does *not* actually repeat what is being spoken over the line - it's just SFX)");
			((BaseUnityPlugin)this).Config.Bind<bool>("Misc", "DontFixMasks", false, "Legacy setting, doesn't work");
			((BaseUnityPlugin)this).Config.Remove(((BaseUnityPlugin)this).Config["Misc", "DontFixMasks"].Definition);
			((BaseUnityPlugin)this).Config.Bind<bool>("Misc", "FixMasks", true, "Legacy setting, doesn't work");
			((BaseUnityPlugin)this).Config.Remove(((BaseUnityPlugin)this).Config["Misc", "FixMasks"].Definition);
			((BaseUnityPlugin)this).Config.Save();
			new Harmony("butterystancakes.lethalcompany.enemysoundfixes").PatchAll();
			Logger.LogInfo((object)"Enemy Sound Fixes v1.9.6 loaded");
		}
	}
	public class RadioChatter : MonoBehaviour
	{
		internal WalkieTalkie walkieTalkie;

		private AudioSource audio;

		private void Awake()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			audio = new GameObject("EnemySoundFixes_WalkieTalkieTalkingNotHeld").AddComponent<AudioSource>();
			((Component)audio).transform.SetParent(((Component)this).transform, false);
			audio.clip = ((Component)this).GetComponent<WalkieTalkie>().talkingOnWalkieTalkieNotHeldSFX;
			audio.loop = true;
			AudioSource component = ((Component)this).GetComponent<AudioSource>();
			audio.outputAudioMixerGroup = component.outputAudioMixerGroup;
			audio.SetCustomCurve((AudioSourceCurveType)1, component.GetCustomCurve((AudioSourceCurveType)1));
			audio.dopplerLevel = component.dopplerLevel;
			audio.spread = component.spread;
			audio.rolloffMode = (AudioRolloffMode)2;
			audio.SetCustomCurve((AudioSourceCurveType)0, component.GetCustomCurve((AudioSourceCurveType)0));
			audio.maxDistance = component.maxDistance;
		}

		private void Update()
		{
			if ((Object)(object)walkieTalkie == (Object)null)
			{
				walkieTalkie = ((Component)this).GetComponent<WalkieTalkie>();
				if ((Object)(object)walkieTalkie == (Object)null)
				{
					((Behaviour)this).enabled = false;
					return;
				}
			}
			if (!((GrabbableObject)walkieTalkie).isBeingUsed || !Plugin.configWalkieHearsTalkies.Value)
			{
				SetPlaying(play: false);
			}
			else
			{
				if ((Object)(object)GameNetworkManager.Instance?.localPlayerController == (Object)null)
				{
					return;
				}
				if (GameNetworkManager.Instance.localPlayerController.holdingWalkieTalkie || (GameNetworkManager.Instance.localPlayerController.isPlayerDead && (Object)(object)GameNetworkManager.Instance.localPlayerController.spectatedPlayerScript != (Object)null && GameNetworkManager.Instance.localPlayerController.spectatedPlayerScript.holdingWalkieTalkie))
				{
					SetPlaying(play: false);
					return;
				}
				bool playing = false;
				for (int i = 0; i < StartOfRound.Instance.allPlayerScripts.Length; i++)
				{
					if (StartOfRound.Instance.allPlayerScripts[i].holdingWalkieTalkie && StartOfRound.Instance.allPlayerScripts[i].speakingToWalkieTalkie && !((Object)(object)StartOfRound.Instance.allPlayerScripts[i].currentlyHeldObjectServer != (Object)(object)walkieTalkie))
					{
						playing = true;
						break;
					}
				}
				SetPlaying(playing);
			}
		}

		public void SetPlaying(bool play)
		{
			if ((Object)(object)audio == (Object)null)
			{
				return;
			}
			if (play)
			{
				if (!audio.isPlaying)
				{
					audio.pitch = Random.Range(0.94f, 1.06f);
					audio.Play();
					audio.time = Random.Range(0f, audio.clip.length - 0.1f);
				}
			}
			else if (audio.isPlaying)
			{
				audio.Stop();
			}
		}

		private void OnDisable()
		{
			SetPlaying(play: false);
		}
	}
	internal class References
	{
		internal static readonly FieldInfo CREATURE_VOICE = AccessTools.Field(typeof(EnemyAI), "creatureVoice");

		internal static readonly FieldInfo IS_ENEMY_DEAD = AccessTools.Field(typeof(EnemyAI), "isEnemyDead");

		internal static readonly FieldInfo ENGINE_AUDIO_1 = AccessTools.Field(typeof(VehicleController), "engineAudio1");

		internal static readonly MethodInfo REALTIME_SINCE_STARTUP = AccessTools.DeclaredPropertyGetter(typeof(Time), "realtimeSinceStartup");

		internal static readonly MethodInfo PLAY_ONE_SHOT = AccessTools.Method(typeof(AudioSource), "PlayOneShot", new Type[1] { typeof(AudioClip) }, (Type[])null);

		internal static readonly MethodInfo STOP = AccessTools.Method(typeof(AudioSource), "Stop", Array.Empty<Type>(), (Type[])null);

		internal static readonly MethodInfo DAMAGE_PLAYER = AccessTools.Method(typeof(PlayerControllerB), "DamagePlayer", (Type[])null, (Type[])null);

		internal static readonly MethodInfo HIT_ENEMY = AccessTools.Method(typeof(EnemyAI), "HitEnemy", (Type[])null, (Type[])null);

		internal static readonly MethodInfo PLAY_RANDOM_CLIP = AccessTools.Method(typeof(RoundManager), "PlayRandomClip", (Type[])null, (Type[])null);

		internal static AudioClip baboonTakeDamage;

		internal static AudioClip hitEnemyBody;

		internal static AudioClip[] woodenDoorOpen;

		internal static AudioClip[] woodenDoorClose;

		internal static AudioClip cruiserDashboardButton;

		internal static AudioMixerGroup sfx;
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "EnemySoundFixes";

		public const string PLUGIN_NAME = "EnemySoundFixes";

		public const string PLUGIN_VERSION = "1.9.6";
	}
}
namespace EnemySoundFixes.Patches
{
	[HarmonyPatch(typeof(VehicleController))]
	internal static class CruiserPatches
	{
		[CompilerGenerated]
		private sealed class <TwistKey>d__6 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public VehicleController vehicleController;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <TwistKey>d__6(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(0.85f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					if (vehicleController.keyIgnitionCoroutine != null && (Object)(object)vehicleController.currentDriver != (Object)null)
					{
						vehicleController.currentDriver.movementAudio.PlayOneShot(vehicleController.twistKey);
					}
					twistingKey = null;
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		private static Coroutine twistingKey;

		[HarmonyPatch("RevCarClientRpc")]
		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		[HarmonyPatch("SetIgnition")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> VehicleController_Trans_EngineRev(IEnumerable<CodeInstruction> instructions)
		{
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Expected O, but got Unknown
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Expected O, but got Unknown
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Expected O, but got Unknown
			List<CodeInstruction> list = instructions.ToList();
			for (int i = 4; i < list.Count; i++)
			{
				if (list[i].opcode == OpCodes.Callvirt && (MethodInfo)list[i].operand == References.PLAY_ONE_SHOT && list[i - 3].opcode == OpCodes.Ldfld && (FieldInfo)list[i - 3].operand == References.ENGINE_AUDIO_1)
				{
					list.InsertRange(i - 4, new <>z__ReadOnlyArray<CodeInstruction>((CodeInstruction[])(object)new CodeInstruction[3]
					{
						new CodeInstruction(list[i - 4].opcode, list[i - 4].operand),
						new CodeInstruction(OpCodes.Ldfld, (object)References.ENGINE_AUDIO_1),
						new CodeInstruction(OpCodes.Callvirt, (object)References.STOP)
					}));
					Plugin.Logger.LogDebug((object)"Transpiler (Cruiser): Reset engine rev sounds");
					return list;
				}
			}
			Plugin.Logger.LogError((object)"Cruiser transpiler failed");
			return list;
		}

		[HarmonyPatch("SetVehicleAudioProperties")]
		[HarmonyPrefix]
		private static void VehicleController_Pre_SetVehicleAudioProperties(VehicleController __instance, AudioSource audio, ref bool audioActive)
		{
			if (audioActive && (((Object)(object)audio == (Object)(object)__instance.extremeStressAudio && __instance.magnetedToShip) || (((Object)(object)audio == (Object)(object)__instance.rollingAudio || (Object)(object)audio == (Object)(object)__instance.skiddingAudio) && (__instance.magnetedToShip || (!__instance.FrontLeftWheel.isGrounded && !__instance.FrontRightWheel.isGrounded && !__instance.BackLeftWheel.isGrounded && !__instance.BackRightWheel.isGrounded)))))
			{
				audioActive = false;
			}
		}

		[HarmonyPatch("SetVehicleAudioProperties")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> VehicleController_Trans_SetVehicleAudioProperties(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = instructions.ToList();
			MethodInfo methodInfo = AccessTools.DeclaredPropertyGetter(typeof(AudioSource), "volume");
			for (int i = 0; i < list.Count - 2; i++)
			{
				if (list[i].opcode == OpCodes.Callvirt && (MethodInfo)list[i].operand == methodInfo && list[i + 1].opcode == OpCodes.Ldc_R4 && (float)list[i + 1].operand == 0f && list[i - 2].opcode == OpCodes.Bne_Un)
				{
					list[i + 1].operand = 0.001f;
					list[i + 2].opcode = OpCodes.Bge;
					Plugin.Logger.LogDebug((object)"Transpiler (Cruiser): Stop audio source when volume is close enough to zero");
					break;
				}
			}
			return list;
		}

		[HarmonyPatch("LateUpdate")]
		[HarmonyPostfix]
		private static void VehicleController_Post_LateUpdate(VehicleController __instance)
		{
			if (__instance.magnetedToShip && (StartOfRound.Instance.inShipPhase || !StartOfRound.Instance.shipDoorsEnabled) && Plugin.configSpaceMutesCruiser.Value > CruiserMute.Nothing)
			{
				__instance.hornAudio.mute = true;
				__instance.engineAudio1.mute = true;
				__instance.engineAudio2.mute = true;
				__instance.turbulenceAudio.mute = true;
				if (Plugin.configSpaceMutesCruiser.Value == CruiserMute.NotRadio)
				{
					__instance.radioAudio.mute = false;
					__instance.radioInterference.mute = false;
				}
				else
				{
					__instance.radioAudio.mute = true;
					__instance.radioInterference.mute = true;
				}
				__instance.pushAudio.mute = true;
			}
			else
			{
				__instance.hornAudio.mute = false;
				__instance.engineAudio1.mute = false;
				__instance.engineAudio2.mute = false;
				__instance.turbulenceAudio.mute = false;
				__instance.radioAudio.mute = false;
				__instance.radioInterference.mute = false;
				__instance.pushAudio.mute = false;
			}
			if (twistingKey != null && __instance.keyIgnitionCoroutine == null)
			{
				((MonoBehaviour)__instance).StopCoroutine(twistingKey);
				twistingKey = null;
			}
			if (__instance.honkingHorn && __instance.hornAudio.isPlaying && __instance.hornAudio.pitch < 1f)
			{
				__instance.hornAudio.Stop();
			}
		}

		[HarmonyPatch("TryIgnition")]
		[HarmonyPrefix]
		private static void VehicleController_Pre_TryIgnition(VehicleController __instance, bool isLocalDriver)
		{
			if (!__instance.keyIsInIgnition && isLocalDriver && __instance.vehicleID == 0)
			{
				if (twistingKey != null)
				{
					((MonoBehaviour)__instance).StopCoroutine(twistingKey);
				}
				twistingKey = ((MonoBehaviour)__instance).StartCoroutine(TwistKey(__instance));
			}
		}

		[IteratorStateMachine(typeof(<TwistKey>d__6))]
		private static IEnumerator TwistKey(VehicleController vehicleController)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <TwistKey>d__6(0)
			{
				vehicleController = vehicleController
			};
		}

		[HarmonyPatch("Awake")]
		[HarmonyPrefix]
		private static void VehicleController_Post_Awake(VehicleController __instance)
		{
			if (__instance.vehicleID != 0 || (Object)(object)References.cruiserDashboardButton == (Object)null || (Object)(object)References.sfx == (Object)null)
			{
				return;
			}
			Transform val = ((Component)__instance).transform.Find("Triggers");
			if (!((Object)(object)val != (Object)null))
			{
				return;
			}
			Transform[] array = (Transform[])(object)new Transform[2]
			{
				val.Find("ChangeChannel (1)"),
				val.Find("ChangeChannel (2)")
			};
			InteractTrigger val3 = default(InteractTrigger);
			foreach (Transform val2 in array)
			{
				if (!((Object)(object)val2 == (Object)null) && ((Component)val2).TryGetComponent<InteractTrigger>(ref val3) && !((Object)(object)((Component)val2).GetComponent<AudioSource>() != (Object)null))
				{
					AudioSource audioSource = ((Component)val3).gameObject.AddComponent<AudioSource>();
					audioSource.clip = References.cruiserDashboardButton;
					audioSource.outputAudioMixerGroup = References.sfx;
					audioSource.spatialBlend = 1f;
					audioSource.spread = 33f;
					audioSource.rolloffMode = (AudioRolloffMode)1;
					audioSource.minDistance = 4f;
					audioSource.maxDistance = 15f;
					((UnityEvent<PlayerControllerB>)(object)val3.onInteract).AddListener((UnityAction<PlayerControllerB>)delegate
					{
						audioSource.Play();
					});
					Plugin.Logger.LogDebug((object)("Cruiser: Dashboard button (\"" + ((Object)val2).name + "\")"));
				}
			}
		}
	}
	[HarmonyPatch(typeof(DoorLock))]
	internal static class DoorPatches
	{
		[HarmonyPatch("UnlockDoor")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> DoorLock_Trans_UnlockDoor(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = instructions.ToList();
			bool flag = false;
			bool flag2 = false;
			MethodInfo methodInfo = AccessTools.Method(typeof(AudioSource), "Stop", (Type[])null, (Type[])null);
			MethodInfo methodInfo2 = AccessTools.Method(typeof(AudioSource), "PlayOneShot", new Type[1] { typeof(AudioClip) }, (Type[])null);
			FieldInfo fieldInfo = AccessTools.Field(typeof(DoorLock), "doorLockSFX");
			for (int i = 2; i < list.Count && !(list[i].opcode == OpCodes.Brtrue) && !(list[i].opcode == OpCodes.Brtrue_S); i++)
			{
				if (list[i].opcode == OpCodes.Callvirt)
				{
					MethodInfo methodInfo3 = list[i].operand as MethodInfo;
					if (!flag && methodInfo3 == methodInfo && list[i - 1].opcode == OpCodes.Ldfld && (FieldInfo)list[i - 1].operand == fieldInfo)
					{
						list.RemoveRange(i - 2, 3);
						i -= 3;
						flag = true;
						Plugin.Logger.LogDebug((object)"Transpiler (Door): Don't stop SFX");
					}
					else if (!flag2 && methodInfo3 == methodInfo2 && i >= 4 && list[i - 3].opcode == OpCodes.Ldfld && (FieldInfo)list[i - 3].operand == fieldInfo)
					{
						list.RemoveRange(i - 4, 5);
						i -= 5;
						flag2 = true;
						Plugin.Logger.LogDebug((object)"Transpiler (Door): Don't play unlock SFX");
					}
				}
			}
			if (!flag || !flag2)
			{
				Plugin.Logger.LogError((object)"Door transpiler failed");
			}
			return list;
		}

		[HarmonyPatch("UnlockDoor")]
		[HarmonyPrefix]
		private static void DoorLock_Pre_UnlockDoor(DoorLock __instance, ref bool __state)
		{
			__state = __instance.isLocked;
		}

		[HarmonyPatch("UnlockDoor")]
		[HarmonyPostfix]
		private static void DoorLock_Post_UnlockDoor(DoorLock __instance, bool __state)
		{
			if (__state && !__instance.isLocked)
			{
				__instance.doorLockSFX.Stop();
				__instance.doorLockSFX.PlayOneShot(__instance.unlockSFX);
			}
		}
	}
	[HarmonyPatch]
	internal static class GeneralPatches
	{
		internal static bool playHitSound;

		private static bool patchedDoorSfx;

		[HarmonyPatch(typeof(QuickMenuManager), "Start")]
		[HarmonyPostfix]
		private static void QuickMenuManager_Post_Start(QuickMenuManager __instance)
		{
			AudioClip val = null;
			try
			{
				AssetBundle obj = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "enemysoundfixes"));
				val = obj.LoadAsset<AudioClip>("StunFlowerman");
				obj.Unload(false);
			}
			catch
			{
				Plugin.Logger.LogError((object)"Encountered some error loading assets from bundle \"enemysoundfixes\". Did you install the plugin correctly?");
			}
			List<SpawnableEnemyWithRarity> enemies = __instance.testAllEnemiesLevel.Enemies;
			List<SpawnableEnemyWithRarity> outsideEnemies = __instance.testAllEnemiesLevel.OutsideEnemies;
			List<SpawnableEnemyWithRarity> daytimeEnemies = __instance.testAllEnemiesLevel.DaytimeEnemies;
			List<SpawnableEnemyWithRarity> list = new List<SpawnableEnemyWithRarity>(enemies.Count + outsideEnemies.Count + daytimeEnemies.Count);
			list.AddRange(enemies);
			list.AddRange(outsideEnemies);
			list.AddRange(daytimeEnemies);
			EnemyType val2 = null;
			EnemyType val3 = null;
			foreach (SpawnableEnemyWithRarity item in list)
			{
				switch (((Object)item.enemyType).name)
				{
				case "BaboonHawk":
					if ((Object)(object)References.baboonTakeDamage == (Object)null)
					{
						References.baboonTakeDamage = item.enemyType.hitBodySFX;
						Plugin.Logger.LogDebug((object)"Cached baboon hawk damage sound");
					}
					item.enemyType.hitBodySFX = null;
					Plugin.Logger.LogDebug((object)"Overwritten baboon hawk damage sound");
					((EnemyAI)item.enemyType.enemyPrefab.GetComponent<BaboonBirdAI>()).dieSFX = item.enemyType.deathSFX;
					Plugin.Logger.LogDebug((object)"Overwritten missing baboon hawk death sound");
					break;
				case "CadaverGrowths":
					item.enemyType.timeToPlayAudio = 1f;
					item.enemyType.loudnessMultiplier = 0.1f;
					Plugin.Logger.LogDebug((object)"Adjust cadaver vent sounds");
					break;
				case "CaveDweller":
				{
					CaveDwellerAI component2 = item.enemyType.enemyPrefab.GetComponent<CaveDwellerAI>();
					component2.clickingAudio1.volume = 0f;
					component2.clickingAudio2.volume = 0f;
					Plugin.Logger.LogDebug((object)"Fix maneater clicking volume");
					break;
				}
				case "Centipede":
					((EnemyAI)item.enemyType.enemyPrefab.GetComponent<CentipedeAI>()).creatureSFX.loop = true;
					Plugin.Logger.LogDebug((object)"Loop snare flea walking and clinging");
					break;
				case "Crawler":
					if (Plugin.configThumperNoThunder.Value)
					{
						EnemyBehaviourState val5 = ((IEnumerable<EnemyBehaviourState>)((EnemyAI)item.enemyType.enemyPrefab.GetComponent<CrawlerAI>()).enemyBehaviourStates).FirstOrDefault((Func<EnemyBehaviourState, bool>)((EnemyBehaviourState enemyBehaviourState) => enemyBehaviourState.name == "searching"));
						if (val5 != null)
						{
							val5.VoiceClip = null;
							val5.playOneShotVoice = false;
							Plugin.Logger.LogDebug((object)"Remove thunder sound from thumper");
						}
					}
					break;
				case "Flowerman":
					if ((Object)(object)val != (Object)null)
					{
						item.enemyType.stunSFX = val;
						Plugin.Logger.LogDebug((object)"Fix bracken stun sound");
					}
					break;
				case "ForestGiant":
				{
					ForestGiantAI component3 = item.enemyType.enemyPrefab.GetComponent<ForestGiantAI>();
					((EnemyAI)component3).creatureSFX.spatialBlend = 1f;
					Plugin.Logger.LogDebug((object)"Fix forest giant global audio volume");
					item.enemyType.hitBodySFX = ((IEnumerable<FootstepSurface>)StartOfRound.Instance.footstepSurfaces).FirstOrDefault((Func<FootstepSurface, bool>)((FootstepSurface footstepSurface) => footstepSurface.surfaceTag == "Wood")).hitSurfaceSFX;
					Plugin.Logger.LogDebug((object)"Overwritten missing forest giant hit sound");
					component3.giantBurningAudio.volume = 0f;
					Plugin.Logger.LogDebug((object)"Fix forest giant burning volume fade");
					break;
				}
				case "GiantKiwi":
				{
					val3 = item.enemyType;
					GiantKiwiAI component = item.enemyType.enemyPrefab.GetComponent<GiantKiwiAI>();
					object obj3;
					if (component == null)
					{
						obj3 = null;
					}
					else
					{
						GameObject feathersPrefab = component.feathersPrefab;
						obj3 = ((feathersPrefab != null) ? feathersPrefab.GetComponent<AudioSource>() : null);
					}
					AudioSource val4 = (AudioSource)obj3;
					if ((Object)(object)val4 != (Object)null)
					{
						val4.spatialBlend = 1f;
						Plugin.Logger.LogDebug((object)"Fix sapsucker death poof");
					}
					break;
				}
				case "MouthDog":
					val2 = item.enemyType;
					break;
				}
				if ((Object)(object)References.hitEnemyBody == (Object)null && ((Object)item.enemyType.hitBodySFX).name == "HitEnemyBody")
				{
					References.hitEnemyBody = item.enemyType.hitBodySFX;
					Plugin.Logger.LogDebug((object)"Cached generic damage sound");
				}
			}
			if ((Object)(object)References.hitEnemyBody != (Object)null)
			{
				if ((Object)(object)val2 != (Object)null)
				{
					val2.hitBodySFX = References.hitEnemyBody;
					Plugin.Logger.LogDebug((object)"Overwritten missing eyeless dog hit sound");
				}
				if ((Object)(object)val3 != (Object)null)
				{
					val3.hitBodySFX = References.hitEnemyBody;
					Plugin.Logger.LogDebug((object)"Overwritten missing giant sapsucker hit sound");
				}
			}
		}

		[HarmonyPatch(typeof(MouthDogAI), "OnCollideWithEnemy")]
		[HarmonyPatch(typeof(BushWolfEnemy), "OnCollideWithEnemy")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> EnemyAI_Trans_OnCollideWithEnemy(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Expected O, but got Unknown
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Expected O, but got Unknown
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Expected O, but got Unknown
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Expected O, but got Unknown
			List<CodeInstruction> list = instructions.ToList();
			for (int i = 2; i < list.Count; i++)
			{
				if (list[i].opcode == OpCodes.Callvirt && (MethodInfo)list[i].operand == References.HIT_ENEMY)
				{
					list.RemoveAt(i - 2);
					list.InsertRange(i - 2, new <>z__ReadOnlyArray<CodeInstruction>((CodeInstruction[])(object)new CodeInstruction[4]
					{
						new CodeInstruction(OpCodes.Ldarg_2, (object)null),
						new CodeInstruction(OpCodes.Ldfld, (object)References.IS_ENEMY_DEAD),
						new CodeInstruction(OpCodes.Ldc_I4_0, (object)null),
						new CodeInstruction(OpCodes.Ceq, (object)null)
					}));
					Plugin.Logger.LogDebug((object)"Transpiler: Don't play hit sound when attacking dead enemy");
					break;
				}
			}
			return list;
		}

		[HarmonyPatch(typeof(StormyWeather), "PlayThunderEffects")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> StormyWeather_Trans_PlayThunderEffects(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = instructions.ToList();
			FieldInfo fieldInfo = AccessTools.Field(typeof(StartOfRound), "shipCreakSFX");
			for (int i = 5; i < list.Count; i++)
			{
				if (list[i].opcode == OpCodes.Call && (MethodInfo)list[i].operand == References.PLAY_RANDOM_CLIP && list[i - 1].opcode == OpCodes.Ldc_I4 && (int)list[i - 1].operand == 1000 && list[i - 5].opcode == OpCodes.Ldfld && (FieldInfo)list[i - 5].operand == fieldInfo)
				{
					list[i - 1].opcode = OpCodes.Ldc_I4_6;
					Plugin.Logger.LogDebug((object)"Transpiler (Stormy weather): No \"Hey\" when ship is struck");
					break;
				}
			}
			return list;
		}

		[HarmonyPatch(typeof(RoundManager), "FinishGeneratingNewLevelClientRpc")]
		[HarmonyPostfix]
		private static void RoundManager_Post_FinishGeneratingNewLevelClientRpc()
		{
			if (patchedDoorSfx)
			{
				return;
			}
			patchedDoorSfx = true;
			if (!Plugin.configFixDoorSounds.Value)
			{
				return;
			}
			string text = null;
			if (StartOfRound.Instance.currentLevel.sceneName == "Level5Rend")
			{
				text = "/Environment/Map/SnowCabin/FancyDoorMapModel/SteelDoor (1)/DoorMesh/Cube";
			}
			else if (StartOfRound.Instance.currentLevel.sceneName == "Level10Adamance")
			{
				text = "/Environment/SnowCabin/FancyDoorMapModel/SteelDoor (1)/DoorMesh/Cube";
			}
			if (!string.IsNullOrEmpty(text) && References.woodenDoorOpen != null && References.woodenDoorOpen.Length != 0 && References.woodenDoorClose != null && References.woodenDoorClose.Length != 0)
			{
				GameObject obj = GameObject.Find(text);
				AnimatedObjectTrigger val = ((obj != null) ? obj.GetComponent<AnimatedObjectTrigger>() : null);
				if ((Object)(object)val != (Object)null)
				{
					val.boolFalseAudios = References.woodenDoorClose;
					val.boolTrueAudios = References.woodenDoorOpen;
					Plugin.Logger.LogDebug((object)"Overwritten cabin door sounds");
				}
			}
			AnimatedObjectTrigger[] array = Object.FindObjectsByType<AnimatedObjectTrigger>((FindObjectsSortMode)0);
			foreach (AnimatedObjectTrigger val2 in array)
			{
				if ((Object)(object)val2.thisAudioSource != (Object)null)
				{
					Transform parent = ((Component)val2).transform.parent;
					if (parent != null)
					{
						((Component)parent).GetComponent<Renderer>();
					}
					if (((Object)val2).name == "PowerBoxDoor" || ((Object)val2.thisAudioSource).name == "storage door")
					{
						AudioClip[] boolTrueAudios = (AudioClip[])val2.boolFalseAudios.Clone();
						val2.boolFalseAudios = (AudioClip[])val2.boolTrueAudios.Clone();
						val2.boolTrueAudios = boolTrueAudios;
						Plugin.Logger.LogDebug((object)(((Object)val2).name + ": AnimatedObjectTrigger audios"));
					}
				}
			}
		}

		[HarmonyPatch(typeof(StartOfRound), "EndOfGameClientRpc")]
		[HarmonyPatch(typeof(GameNetworkManager), "Disconnect")]
		[HarmonyPostfix]
		private static void ResetLoadState()
		{
			patchedDoorSfx = false;
		}

		[HarmonyPatch(typeof(RoundManager), "Awake")]
		[HarmonyPostfix]
		private static void RoundManager_Post_Awake(RoundManager __instance)
		{
			PatchManorDoors(__instance);
			MineshaftPatches(__instance);
		}

		private static void PatchManorDoors(RoundManager roundManager)
		{
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_047f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0484: Unknown result type (might be due to invalid IL or missing references)
			//IL_0496: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_04bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_04cf: Unknown result type (might be due to invalid IL or missing references)
			AudioMixerGroup outputAudioMixerGroup = null;
			IndoorMapType val = ((IEnumerable<IndoorMapType>)roundManager.dungeonFlowTypes).FirstOrDefault((Func<IndoorMapType, bool>)delegate(IndoorMapType dungeonFlowType)
			{
				DungeonFlow dungeonFlow = dungeonFlowType.dungeonFlow;
				return ((dungeonFlow != null) ? ((Object)dungeonFlow).name : null) == "Level2Flow";
			});
			if (val == null)
			{
				return;
			}
			bool flag = References.woodenDoorOpen == null || References.woodenDoorOpen.Length < 1 || References.woodenDoorClose == null || References.woodenDoorClose.Length < 1;
			foreach (GraphNode node in val.dungeonFlow.Nodes)
			{
				foreach (TileSet tileSet in node.TileSets)
				{
					if (!(((Object)tileSet).name == "Level2CapTiles"))
					{
						continue;
					}
					GameObject val2 = ((IEnumerable<GameObjectChance>)tileSet.TileWeights.Weights).FirstOrDefault((Func<GameObjectChance, bool>)delegate(GameObjectChance weight)
					{
						GameObject value3 = weight.Value;
						return ((value3 != null) ? ((Object)value3).name : null) == "GarageTile";
					})?.Value;
					if (!((Object)(object)val2 != (Object)null))
					{
						continue;
					}
					Transform obj = val2.transform.Find("SpawnInteractables");
					GameObject val3 = ((obj == null) ? null : ((Component)obj).GetComponent<SpawnSyncedObject>()?.spawnPrefab);
					if ((Object)(object)val3 != (Object)null)
					{
						Transform obj2 = val3.transform.Find("GarbageBinContainer/GarbageBin");
						AnimatedObjectTrigger val4 = ((obj2 != null) ? ((Component)obj2).GetComponent<AnimatedObjectTrigger>() : null);
						if ((Object)(object)val4 != (Object)null && !Object.op_Implicit((Object)(object)((Component)val4).GetComponent<AudioSource>()))
						{
							AudioSource thisAudioSource = val4.thisAudioSource;
							val4.thisAudioSource = ((Component)val4).gameObject.AddComponent<AudioSource>();
							outputAudioMixerGroup = thisAudioSource.outputAudioMixerGroup;
							val4.thisAudioSource.outputAudioMixerGroup = outputAudioMixerGroup;
							val4.thisAudioSource.pitch = thisAudioSource.pitch;
							val4.thisAudioSource.spatialBlend = thisAudioSource.spatialBlend;
							val4.thisAudioSource.dopplerLevel = thisAudioSource.dopplerLevel;
							val4.thisAudioSource.spread = thisAudioSource.spread;
							val4.thisAudioSource.rolloffMode = thisAudioSource.rolloffMode;
							val4.thisAudioSource.minDistance = thisAudioSource.minDistance;
							val4.thisAudioSource.maxDistance = thisAudioSource.maxDistance;
						}
					}
				}
			}
			foreach (GraphLine line in val.dungeonFlow.Lines)
			{
				foreach (DungeonArchetype dungeonArchetype in line.DungeonArchetypes)
				{
					foreach (TileSet tileSet2 in dungeonArchetype.TileSets)
					{
						if (((Object)tileSet2).name == "Level2HallwayTilesB")
						{
							if (!flag)
							{
								continue;
							}
							GameObject val5 = ((IEnumerable<GameObjectChance>)tileSet2.TileWeights.Weights).FirstOrDefault((Func<GameObjectChance, bool>)delegate(GameObjectChance weight)
							{
								GameObject value2 = weight.Value;
								return ((value2 != null) ? ((Object)value2).name : null) == "ManorStartRoomSmall";
							})?.Value;
							if (!((Object)(object)val5 != (Object)null))
							{
								continue;
							}
							Transform obj3 = val5.transform.Find("Doorways");
							object obj4;
							if (obj3 == null)
							{
								obj4 = null;
							}
							else
							{
								Doorway componentInChildren = ((Component)obj3).GetComponentInChildren<Doorway>();
								if (componentInChildren == null)
								{
									obj4 = null;
								}
								else
								{
									List<GameObjectWeight> connectorPrefabWeights = componentInChildren.ConnectorPrefabWeights;
									if (connectorPrefabWeights == null)
									{
										obj4 = null;
									}
									else
									{
										GameObjectWeight? obj5 = ((IEnumerable<GameObjectWeight>)connectorPrefabWeights).FirstOrDefault((Func<GameObjectWeight, bool>)((GameObjectWeight prefab) => ((Object)prefab.GameObject).name == "FancyDoorMapSpawn"));
										if (obj5 == null)
										{
											obj4 = null;
										}
										else
										{
											SpawnSyncedObject component = obj5.GameObject.GetComponent<SpawnSyncedObject>();
											if (component == null)
											{
												obj4 = null;
											}
											else
											{
												GameObject spawnPrefab = component.spawnPrefab;
												obj4 = ((spawnPrefab != null) ? spawnPrefab.GetComponentInChildren<AnimatedObjectTrigger>() : null);
											}
										}
									}
								}
							}
							AnimatedObjectTrigger val6 = (AnimatedObjectTrigger)obj4;
							if ((Object)(object)val6 != (Object)null)
							{
								References.woodenDoorClose = val6.boolFalseAudios;
								References.woodenDoorOpen = val6.boolTrueAudios;
								Plugin.Logger.LogDebug((object)"Cached wooden door sounds");
								flag = false;
							}
						}
						else
						{
							if (!(((Object)tileSet2).name == "Level2RoomTiles"))
							{
								continue;
							}
							GameObject val7 = ((IEnumerable<GameObjectChance>)tileSet2.TileWeights.Weights).FirstOrDefault((Func<GameObjectChance, bool>)delegate(GameObjectChance weight)
							{
								GameObject value = weight.Value;
								return ((value != null) ? ((Object)value).name : null) == "GreenhouseTile";
							})?.Value;
							if (!((Object)(object)val7 != (Object)null))
							{
								continue;
							}
							Transform obj6 = val7.transform.Find("GreenhouseSinkContainer/SpawnInteractables");
							GameObject val8 = ((obj6 == null) ? null : ((Component)obj6).GetComponent<SpawnSyncedObject>()?.spawnPrefab);
							if (!((Object)(object)val8 != (Object)null) || !((Object)(object)val8.transform.Find("SwingOpenCabinetAudio") == (Object)null))
							{
								continue;
							}
							GameObject val9 = new GameObject("SwingOpenCabinetAudio");
							val9.transform.SetParent(val8.transform);
							val9.transform.SetLocalPositionAndRotation(new Vector3(-10.515533f, -5.3320847f, 5.7967625f), Quaternion.Euler(0f, 90f, 0f));
							val9.transform.localScale = Vector3.one;
							AudioSource val10 = val9.AddComponent<AudioSource>();
							val10.outputAudioMixerGroup = outputAudioMixerGroup;
							val10.volume = 0.717f;
							val10.pitch = 0.91f;
							val10.spatialBlend = 1f;
							val10.spread = 41f;
							val10.rolloffMode = (AudioRolloffMode)1;
							val10.minDistance = 1f;
							val10.maxDistance = 12f;
							AnimatedObjectTrigger[] componentsInChildren = val8.GetComponentsInChildren<AnimatedObjectTrigger>();
							foreach (AnimatedObjectTrigger val11 in componentsInChildren)
							{
								if ((Object)(object)val11.triggerAnimator != (Object)null && ((Object)val11.triggerAnimator).name.StartsWith("BigCupboard"))
								{
									val11.thisAudioSource = val10;
									Plugin.Logger.LogDebug((object)("Fixed greenhouse door \"" + ((Object)val11).name + "\""));
								}
							}
						}
					}
				}
			}
		}

		private static void MineshaftPatches(RoundManager roundManager)
		{
			IndoorMapType val = ((IEnumerable<IndoorMapType>)roundManager.dungeonFlowTypes).FirstOrDefault((Func<IndoorMapType, bool>)delegate(IndoorMapType dungeonFlowType)
			{
				DungeonFlow dungeonFlow = dungeonFlowType.dungeonFlow;
				return ((dungeonFlow != null) ? ((Object)dungeonFlow).name : null) == "Level3Flow";
			});
			if (val != null)
			{
				PatchMineshaftDoors(val);
				GetButtonAudio(val);
			}
		}

		private static void PatchMineshaftDoors(IndoorMapType mineshaft)
		{
			foreach (GraphLine line in mineshaft.dungeonFlow.Lines)
			{
				foreach (DungeonArchetype dungeonArchetype in line.DungeonArchetypes)
				{
					foreach (TileSet tileSet in dungeonArchetype.TileSets)
					{
						if (!(((Object)tileSet).name == "Level3TunnelTiles"))
						{
							continue;
						}
						GameObject val = ((IEnumerable<GameObjectChance>)tileSet.TileWeights.Weights).FirstOrDefault((Func<GameObjectChance, bool>)delegate(GameObjectChance weight)
						{
							GameObject value = weight.Value;
							return ((value != null) ? ((Object)value).name : null) == "TunnelSplit";
						})?.Value;
						if (!((Object)(object)val != (Object)null))
						{
							continue;
						}
						Transform obj = val.transform.Find("DoorwayPointW");
						object obj2;
						if (obj == null)
						{
							obj2 = null;
						}
						else
						{
							Doorway componentInChildren = ((Component)obj).GetComponentInChildren<Doorway>();
							if (componentInChildren == null)
							{
								obj2 = null;
							}
							else
							{
								List<GameObjectWeight> connectorPrefabWeights = componentInChildren.ConnectorPrefabWeights;
								if (connectorPrefabWeights == null)
								{
									obj2 = null;
								}
								else
								{
									GameObjectWeight? obj3 = ((IEnumerable<GameObjectWeight>)connectorPrefabWeights).FirstOrDefault((Func<GameObjectWeight, bool>)((GameObjectWeight prefab) => ((Object)prefab.GameObject).name == "MineDoorSpawn"));
									if (obj3 == null)
									{
										obj2 = null;
									}
									else
									{
										SpawnSyncedObject componentInChildren2 = obj3.GameObject.GetComponentInChildren<SpawnSyncedObject>();
										if (componentInChildren2 == null)
										{
											obj2 = null;
										}
										else
										{
											GameObject spawnPrefab = componentInChildren2.spawnPrefab;
											obj2 = ((spawnPrefab != null) ? spawnPrefab.transform : null);
										}
									}
								}
							}
						}
						Transform val2 = (Transform)obj2;
						if (!((Object)(object)val2 != (Object)null))
						{
							continue;
						}
						Collider[] componentsInChildren = ((Component)val2).GetComponentsInChildren<Collider>();
						foreach (Collider val3 in componentsInChildren)
						{
							if (((Component)val3).gameObject.layer == 8 && ((Object)val3).name == "LOSBlocker" && ((Object)((Component)val3).transform.parent).name == "MineDoorMesh")
							{
								((Component)val3).gameObject.layer = 11;
								Plugin.Logger.LogDebug((object)"Fixed mineshaft door occlusion");
								return;
							}
						}
					}
				}
			}
		}

		private static void GetButtonAudio(IndoorMapType mineshaft)
		{
			if (!((Object)(object)References.cruiserDashboardButton == (Object)null) && !((Object)(object)References.sfx == (Object)null))
			{
				return;
			}
			foreach (GraphNode node in mineshaft.dungeonFlow.Nodes)
			{
				foreach (TileSet tileSet in node.TileSets)
				{
					if (!(((Object)tileSet).name == "MineshaftStartRooms"))
					{
						continue;
					}
					GameObject val = ((IEnumerable<GameObjectChance>)tileSet.TileWeights.Weights).FirstOrDefault((Func<GameObjectChance, bool>)delegate(GameObjectChance weight)
					{
						GameObject value = weight.Value;
						return ((value != null) ? ((Object)value).name : null) == "MineshaftStartTile";
					})?.Value;
					if (!((Object)(object)val != (Object)null))
					{
						continue;
					}
					Transform obj = val.transform.Find("ElevatorSpawn");
					object obj2;
					if (obj == null)
					{
						obj2 = null;
					}
					else
					{
						SpawnSyncedObject componentInChildren = ((Component)obj).GetComponentInChildren<SpawnSyncedObject>();
						if (componentInChildren == null)
						{
							obj2 = null;
						}
						else
						{
							GameObject spawnPrefab = componentInChildren.spawnPrefab;
							if (spawnPrefab == null)
							{
								obj2 = null;
							}
							else
							{
								Transform obj3 = spawnPrefab.transform.Find("AnimContainer/controlBox/redButton");
								obj2 = ((obj3 != null) ? ((Component)obj3).GetComponent<AnimatedObjectTrigger>() : null);
							}
						}
					}
					AnimatedObjectTrigger val2 = (AnimatedObjectTrigger)obj2;
					if ((Object)(object)val2 != (Object)null && val2.boolFalseAudios != null && val2.boolFalseAudios.Length != 0)
					{
						References.cruiserDashboardButton = val2.boolFalseAudios[0];
						AudioSource component = ((Component)val2).GetComponent<AudioSource>();
						References.sfx = ((component != null) ? component.outputAudioMixerGroup : null);
						Plugin.Logger.LogDebug((object)"Cached dashboard button sound");
						return;
					}
				}
			}
		}

		[HarmonyPatch(typeof(EnemyVent), "OpenVentClientRpc")]
		[HarmonyPostfix]
		private static void EnemyVent_Post_OpenVentClientRpc(EnemyVent __instance)
		{
			__instance.isPlayingAudio = false;
			__instance.ventAudio.Stop();
		}

		[HarmonyPatch(typeof(GrabbableObject), "PlayDropSFX")]
		[HarmonyPrefix]
		private static bool GrabbableObject_Pre_PlayDropSFX(GrabbableObject __instance)
		{
			LockPicker val = (LockPicker)(object)((__instance is LockPicker) ? __instance : null);
			if (val != null)
			{
				return !val.isOnDoor;
			}
			return true;
		}

		[HarmonyPatch(typeof(Landmine), "Detonate")]
		[HarmonyPostfix]
		private static void Landmine_Post_Detonate(Landmine __instance)
		{
			if ((Object)(object)__instance.mineFarAudio != (Object)null && (Object)(object)__instance.mineDetonateFar != (Object)null)
			{
				__instance.mineFarAudio.PlayOneShot(__instance.mineDetonateFar);
			}
		}

		[HarmonyPatch(typeof(ExtensionLadderItem), "StartLadderAnimation")]
		[HarmonyPostfix]
		private static void ExtensionLadderItem_Post_StartLadderAnimation(ExtensionLadderItem __instance)
		{
			if (__instance.ladderBlinkWarning)
			{
				__instance.ladderBlinkWarning = false;
				Plugin.Logger.LogDebug((object)"Fixed broken extension ladder warning");
			}
		}

		[HarmonyPatch(typeof(SoundManager), "PlayRandomOutsideMusic")]
		[HarmonyPrefix]
		private static bool SoundManager_Pre_PlayRandomOutsideMusic(SoundManager __instance)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Invalid comparison between Unknown and I4
			if (Plugin.configEclipsesBlockMusic.Value)
			{
				return (int)StartOfRound.Instance.currentLevel.currentWeather != 5;
			}
			return true;
		}

		[HarmonyPatch(typeof(StartOfRound), "Awake")]
		[HarmonyPostfix]
		[HarmonyWrapSafe]
		private static void StartOfRound_Post_Awake(StartOfRound __instance)
		{
			__instance.speakerAudioSource.dopplerLevel = Plugin.configMusicDopplerLevel.Value;
			__instance.shipDoorAudioSource.dopplerLevel = Plugin.configMusicDopplerLevel.Value;
			Plugin.Logger.LogDebug((object)"Doppler level: Ship speakers");
			((IEnumerable<GameObject>)__instance.VehiclesList).FirstOrDefault((Func<GameObject, bool>)((GameObject vehicle) => ((Object)vehicle).name == "CompanyCruiser")).GetComponent<VehicleController>().radioAudio.dopplerLevel = Plugin.configMusicDopplerLevel.Value;
			Plugin.Logger.LogDebug((object)"Doppler level: Cruiser");
			Transform obj = __instance.elevatorTransform.Find("StickyNoteItem");
			AudioSource val = ((obj != null) ? ((Component)obj).GetComponent<AudioSource>() : null);
			if ((Object)(object)val != (Object)null)
			{
				val.rolloffMode = (AudioRolloffMode)1;
				Plugin.Logger.LogDebug((object)"Audio rolloff: Sticky note");
			}
			Transform obj2 = __instance.elevatorTransform.Find("ClipboardManual");
			AudioSource val2 = ((obj2 != null) ? ((Component)obj2).GetComponent<AudioSource>() : null);
			if ((Object)(object)val2 != (Object)null)
			{
				val2.rolloffMode = (AudioRolloffMode)1;
				Plugin.Logger.LogDebug((object)"Audio rolloff: Clipboard");
			}
			foreach (UnlockableItem unlockable in StartOfRound.Instance.unlockablesList.unlockables)
			{
				switch (unlockable.unlockableName)
				{
				case "Record player":
					unlockable.prefabObject.GetComponentInChildren<AnimatedObjectTrigger>().thisAudioSource.dopplerLevel = Plugin.configMusicDopplerLevel.Value;
					Plugin.Logger.LogDebug((object)"Doppler level: Record player");
					break;
				case "Disco Ball":
					unlockable.prefabObject.GetComponentInChildren<CozyLights>().turnOnAudio.dopplerLevel = 0.92f * Plugin.configMusicDopplerLevel.Value;
					Plugin.Logger.LogDebug((object)"Doppler level: Disco ball");
					break;
				case "Microwave":
					((Component)unlockable.prefabObject.transform.Find("MicrowaveBody")).GetComponent<AudioSource>().playOnAwake = true;
					Plugin.Logger.LogDebug((object)"Audio: Microwave");
					break;
				}
			}
			AudioClip val3 = null;
			AudioClip val4 = null;
			AudioClip val5 = null;
			AudioClip val6 = null;
			AudioClip val7 = null;
			List<Item> list = new List<Item>();
			List<Item> list2 = new List<Item>();
			List<Item> list3 = new List<Item>();
			Item val8 = null;
			foreach (Item items in StartOfRound.Instance.allItemsList.itemsList)
			{
				bool flag = false;
				switch (((Object)items).name)
				{
				case "Boombox":
					items.spawnPrefab.GetComponent<BoomboxItem>().boomboxAudio.dopplerLevel = 0.3f * Plugin.configMusicDopplerLevel.Value;
					Plugin.Logger.LogDebug((object)"Doppler level: Boombox");
					break;
				case "BottleBin":
					val4 = items.grabSFX;
					break;
				case "ToyCube":
				case "Brush":
				case "Phone":
				case "Remote":
				case "SteeringWheel":
					list2.Add(items);
					break;
				case "Candy":
				case "Toothpaste":
					items.grabSFX = null;
					break;
				case "MapDevice":
				case "ZapGun":
				case "Cog1":
					flag = true;
					break;
				case "DustPan":
					val6 = items.dropSFX;
					break;
				case "FancyCup":
					if (!Plugin.INSTALLED_UPTURNED_VARIETY)
					{
						list.Add(items);
					}
					break;
				case "FancyPainting":
					list3.Add(items);
					break;
				case "FishTestProp":
					flag = true;
					break;
				case "GarbageLid":
				case "MetalSheet":
					list.Add(items);
					break;
				case "Mug":
					val5 = items.dropSFX;
					break;
				case "PillBottle":
					val8 = items;
					items.grabSFX = null;
					break;
				case "RedLocustHive":
					flag = true;
					break;
				case "TeaKettle":
					val3 = items.grabSFX;
					break;
				case "TragedyMask":
					val7 = items.grabSFX;
					break;
				case "WalkieTalkie":
				{
					WalkieTalkie component = items.spawnPrefab.GetComponent<WalkieTalkie>();
					((Component)component).gameObject.AddComponent<RadioChatter>().walkieTalkie = component;
					Plugin.Logger.LogDebug((object)"Walkie talkie: Let's make some noise!");
					break;
				}
				case "WeedKillerBottle":
					items.spawnPrefab.GetComponent<SprayPaintItem>().sprayAudio.loop = false;
					Plugin.Logger.LogDebug((object)"Loop: Weed killer");
					break;
				}
				if (flag)
				{
					items.spawnPrefab.GetComponent<AudioSource>().rolloffMode = (AudioRolloffMode)1;
					Plugin.Logger.LogDebug((object)("Audio rolloff: " + items.itemName));
				}
			}
			if ((Object)(object)val3 != (Object)null)
			{
				foreach (Item item in list)
				{
					item.grabSFX = val3;
					Plugin.Logger.LogDebug((object)("Audio: " + item.itemName));
				}
			}
			if ((Object)(object)val4 != (Object)null)
			{
				foreach (Item item2 in list2)
				{
					item2.grabSFX = val4;
					Plugin.Logger.LogDebug((object)("Audio: " + item2.itemName));
					if (((Object)item2).name == "Phone" && (Object)(object)val6 != (Object)null)
					{
						item2.dropSFX = val6;
					}
				}
			}
			if ((Object)(object)val7 != (Object)null)
			{
				foreach (Item item3 in list3)
				{
					item3.grabSFX = val7;
					Plugin.Logger.LogDebug((object)("Audio: " + item3.itemName));
				}
			}
			if ((Object)(object)val8 != (Object)null && (Object)(object)val5 != (Object)null)
			{
				val8.dropSFX = val5;
				Plugin.Logger.LogDebug((object)("Audio: " + val8.itemName));
			}
		}

		[HarmonyPatch(typeof(ItemDropship), "Start")]
		[HarmonyPostfix]
		private static void ItemDropship_Post_Start(ItemDropship __instance)
		{
			Transform val = ((Component)__instance).transform.Find("Music");
			if ((Object)(object)val != (Object)null)
			{
				((Component)val).GetComponent<AudioSource>().dopplerLevel = 0.6f * Plugin.configMusicDopplerLevel.Value;
				Transform obj = val.Find("Music (1)");
				AudioSource val2 = ((obj != null) ? ((Component)obj).GetComponent<AudioSource>() : null);
				if ((Object)(object)val2 != (Object)null)
				{
					val2.dopplerLevel = 0.6f * Plugin.configMusicDopplerLevel.Value;
				}
				Plugin.Logger.LogDebug((object)"Doppler level: Dropship");
			}
		}

		[HarmonyPatch(typeof(MineshaftElevatorController), "OnEnable")]
		[HarmonyPostfix]
		private static void MineshaftElevatorController_Post_OnEnable(MineshaftElevatorController __instance)
		{
			__instance.elevatorJingleMusic.dopplerLevel = 0.58f * Plugin.configMusicDopplerLevel.Value;
			Plugin.Logger.LogDebug((object)"Doppler level: Mineshaft elevator");
		}

		[HarmonyPatch(typeof(Terminal), "Start")]
		[HarmonyPostfix]
		private static void Terminal_Post_Start(Terminal __instance)
		{
			BuyableVehicle val = ((IEnumerable<BuyableVehicle>)__instance.buyableVehicles).FirstOrDefault((Func<BuyableVehicle, bool>)((BuyableVehicle buyableVehicle) => buyableVehicle.vehicleDisplayName == "Cruiser"));
			if (val != null)
			{
				GameObject secondaryPrefab = val.secondaryPrefab;
				AudioSource val2 = ((secondaryPrefab != null) ? ((Component)secondaryPrefab.transform).GetComponent<AudioSource>() : null);
				if ((Object)(object)val2 != (Object)null)
				{
					val2.rolloffMode = (AudioRolloffMode)1;
					Plugin.Logger.LogDebug((object)"Audio rolloff: Clipboard (Cruiser)");
				}
			}
		}

		[HarmonyPatch(typeof(FlashlightItem), "ItemActivate")]
		[HarmonyPrefix]
		private static bool FlashlightItem_Pre_ItemActivate(FlashlightItem __instance, bool used)
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)((GrabbableObject)__instance).itemProperties == (Object)null || ((GrabbableObject)__instance).itemProperties.itemId != 6)
			{
				return true;
			}
			if (__instance.flashlightInterferenceLevel < 2)
			{
				__instance.SwitchFlashlight(used);
			}
			__instance.flashlightAudio.PlayOneShot(__instance.flashlightClips[(!((GrabbableObject)__instance).isBeingUsed) ? 1u : 0u]);
			RoundManager.Instance.PlayAudibleNoise(((Component)__instance).transform.position, 7f, 0.4f, 0, ((GrabbableObject)__instance).isInElevator && StartOfRound.Instance.hangarDoorsClosed, 0);
			return false;
		}
	}
	[HarmonyPatch(typeof(PlayerControllerB))]
	internal static class PlayerPatches
	{
		[HarmonyPatch("DamagePlayer")]
		[HarmonyPrefix]
		private static void PlayerControllerB_Pre_DamagePlayer(CauseOfDeath causeOfDeath, ref bool fallDamage)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Invalid comparison between Unknown and I4
			if ((int)causeOfDeath == 2 && !fallDamage)
			{
				fallDamage = true;
				Plugin.Logger.LogDebug((object)"Player: Treat Gravity damage as fall damage");
			}
		}

		[HarmonyPatch("DamagePlayerFromOtherClientClientRpc")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> PlayerControllerB_Trans_DamagePlayerFromOtherClientClientRpc(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = instructions.ToList();
			for (int i = 3; i < list.Count; i++)
			{
				if (!(list[i].opcode == OpCodes.Call) || !((MethodInfo)list[i].operand == References.DAMAGE_PLAYER))
				{
					continue;
				}
				for (int num = i - 1; num > 0; num--)
				{
					if (list[num].opcode == OpCodes.Ldarg_1 && list[num + 1].opcode == OpCodes.Ldc_I4_1)
					{
						list[num + 1].opcode = OpCodes.Ldc_I4_0;
						Plugin.Logger.LogDebug((object)"Transpiler (Players): Melee weapons don't stack hit sounds");
						break;
					}
				}
			}
			return list;
		}
	}
}
namespace EnemySoundFixes.Patches.Enemies
{
	[HarmonyPatch(typeof(BaboonBirdAI))]
	internal static class BaboonHawkPatches
	{
		[HarmonyPatch("HitEnemy")]
		[HarmonyPostfix]
		private static void BaboonBirdAI_Post_HitEnemy(BaboonBirdAI __instance, bool playHitSFX)
		{
			if (playHitSFX && !((EnemyAI)__instance).isEnemyDead)
			{
				if (!((EnemyAI)__instance).isEnemyDead && (Object)(object)References.baboonTakeDamage != (Object)null)
				{
					((EnemyAI)__instance).creatureVoice.PlayOneShot(References.baboonTakeDamage);
					Plugin.Logger.LogDebug((object)"Baboon hawk: Ouch");
				}
				else if ((Object)(object)References.hitEnemyBody != (Object)null)
				{
					((EnemyAI)__instance).creatureSFX.PlayOneShot(References.hitEnemyBody);
				}
			}
		}

		[HarmonyPatch("OnCollideWithEnemy")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> BaboonBirdAI_Trans_OnCollideWithEnemy(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
		{
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Expected O, but got Unknown
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Expected O, but got Unknown
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Expected O, but got Unknown
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Expected O, but got Unknown
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Expected O, but got Unknown
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Expected O, but got Unknown
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Expected O, but got Unknown
			List<CodeInstruction> list = instructions.ToList();
			MethodInfo methodInfo = AccessTools.Method(typeof(Animator), "ResetTrigger", new Type[1] { typeof(string) }, (Type[])null);
			MethodInfo methodInfo2 = AccessTools.DeclaredPropertyGetter(typeof(RoundManager), "Instance");
			for (int i = 3; i < list.Count; i++)
			{
				if (list[i].opcode == OpCodes.Callvirt && (MethodInfo)list[i].operand == methodInfo)
				{
					for (int j = i + 1; j < list.Count; j++)
					{
						if (list[j].opcode == OpCodes.Call && (MethodInfo)list[j].operand == methodInfo2)
						{
							Label label = generator.DefineLabel();
							list[j].labels.Add(label);
							list.InsertRange(i - 3, new <>z__ReadOnlyArray<CodeInstruction>((CodeInstruction[])(object)new CodeInstruction[3]
							{
								new CodeInstruction(OpCodes.Ldarg_2, (object)null),
								new CodeInstruction(OpCodes.Ldfld, (object)References.IS_ENEMY_DEAD),
								new CodeInstruction(OpCodes.Brtrue, (object)label)
							}));
							Plugin.Logger.LogDebug((object)"Transpiler (Baboon hawk): Don't play hit sound when attacking dead enemy (A)");
							i += 3;
							break;
						}
					}
				}
				else if (list[i].opcode == OpCodes.Callvirt && (MethodInfo)list[i].operand == References.HIT_ENEMY)
				{
					list.RemoveAt(i - 2);
					list.InsertRange(i - 2, new <>z__ReadOnlyArray<CodeInstruction>((CodeInstruction[])(object)new CodeInstruction[4]
					{
						new CodeInstruction(OpCodes.Ldarg_2, (object)null),
						new CodeInstruction(OpCodes.Ldfld, (object)References.IS_ENEMY_DEAD),
						new CodeInstruction(OpCodes.Ldc_I4_0, (object)null),
						new CodeInstruction(OpCodes.Ceq, (object)null)
					}));
					Plugin.Logger.LogDebug((object)"Transpiler (Baboon hawk): Don't play hit sound when attacking dead enemy (B)");
					i += 4;
				}
			}
			return list;
		}
	}
	[HarmonyPatch(typeof(StingrayAI))]
	internal static class BackwaterGunkfishPatches
	{
		[HarmonyPatch("KillEnemy")]
		[HarmonyPostfix]
		private static void StingrayAI_Post_KillEnemy(StingrayAI __instance, bool destroy)
		{
			if (!destroy)
			{
				AudioSource[] array = (AudioSource[])(object)new AudioSource[3] { __instance.floppingAudio, __instance.slidingAudio, __instance.whiningAudio };
				foreach (AudioSource obj in array)
				{
					obj.Stop();
					obj.mute = true;
				}
			}
		}
	}
	[HarmonyPatch(typeof(FlowermanAI))]
	internal static class BrackenPatches
	{
		[HarmonyPatch("HitEnemy")]
		[HarmonyPrefix]
		private static void FlowermanAI_Pre_HitEnemy(FlowermanAI __instance, int force, bool playHitSFX)
		{
			GeneralPatches.playHitSound = playHitSFX && !((EnemyAI)__instance).isEnemyDead && ((EnemyAI)__instance).enemyHP <= force;
		}

		[HarmonyPatch("KillEnemy")]
		[HarmonyPostfix]
		private static void FlowermanAI_Post_KillEnemy(FlowermanAI __instance, bool destroy)
		{
			if (GeneralPatches.playHitSound)
			{
				GeneralPatches.playHitSound = false;
				if (!destroy)
				{
					((EnemyAI)__instance).creatureSFX.PlayOneShot(((EnemyAI)__instance).enemyType.hitBodySFX);
					Plugin.Logger.LogDebug((object)"Bracken: Play hit sound on death");
				}
			}
		}
	}
	[HarmonyPatch(typeof(ButlerEnemyAI))]
	internal static class ButlerPatches
	{
		[HarmonyPatch("Update")]
		[HarmonyPostfix]
		private static void ButlerEnemyAI_Post_Update(ButlerEnemyAI __instance)
		{
			if (((EnemyAI)__instance).isEnemyDead && __instance.buzzingAmbience.isPlaying && ((EnemyAI)__instance).creatureAnimator.GetBool("popFinish"))
			{
				__instance.buzzingAmbience.Stop();
				Plugin.Logger.LogDebug((object)"Butler: Stop buzzing (bugs are free)");
			}
		}
	}
	[HarmonyPatch]
	internal static class CadaverPatches
	{
		private static MoldSpreadManager moldSpreadManager;

		[HarmonyPatch(typeof(CadaverGrowthAI), "Start")]
		[HarmonyPostfix]
		private static void CadaverGrowthAI_Post_Start(CadaverGrowthAI __instance)
		{
			if ((Object)(object)moldSpreadManager == (Object)null)
			{
				moldSpreadManager = Object.FindAnyObjectByType<MoldSpreadManager>();
			}
			if ((Object)(object)moldSpreadManager != (Object)null && (Object)(object)__instance.destroyAudio != (Object)null && (Object)(object)__instance.destroyAudio.clip == (Object)null)
			{
				AudioSource destroyAudio = __instance.destroyAudio;
				AudioSource destroyAudio2 = moldSpreadManager.destroyAudio;
				destroyAudio.clip = ((destroyAudio2 != null) ? destroyAudio2.clip : null);
			}
		}
	}
	[HarmonyPatch(typeof(MouthDogAI))]
	internal static class EyelessDogPatches
	{
		private const float TIME_DROP_CARRIED_BODY = 5.01f;

		private static Dictionary<MouthDogAI, (float Pitch, float Time)> dogPitches = new Dictionary<MouthDogAI, (float, float)>();

		[HarmonyPatch("KillEnemy")]
		[HarmonyPostfix]
		private static void MouthDogAI_Post_KillEnemy(MouthDogAI __instance, bool destroy)
		{
			if (GeneralPatches.playHitSound)
			{
				GeneralPatches.playHitSound = false;
				if (!destroy && (Object)(object)References.hitEnemyBody != (Object)null)
				{
					((EnemyAI)__instance).creatureSFX.PlayOneShot(((EnemyAI)__instance).enemyType.hitBodySFX);
					Plugin.Logger.LogDebug((object)"Mouth dog: Play hit sound on death");
				}
			}
			if (!destroy)
			{
				if (Plugin.configShootTheDog.Value && (Object)(object)((EnemyAI)__instance).enemyType.stunSFX != (Object)null)
				{
					((EnemyAI)__instance).creatureVoice.PlayOneShot(((EnemyAI)__instance).enemyType.stunSFX);
					Plugin.Logger.LogDebug((object)"Eyeless dog: React grievously to agonizing departure");
				}
				else
				{
					((EnemyAI)__instance).creatureVoice.mute = true;
					Plugin.Logger.LogDebug((object)"Eyeless dog: Don't start breathing after death");
				}
			}
		}

		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		private static void MouthDogAI_Post_Start(MouthDogAI __instance)
		{
			Random random = new Random(StartOfRound.Instance.randomMapSeed + (int)((NetworkBehaviour)__instance).NetworkObjectId);
			if (random.Next(10) < 2)
			{
				((EnemyAI)__instance).creatureVoice.pitch = 0.6f + 0.7f * (float)random.NextDouble();
			}
			else
			{
				((EnemyAI)__instance).creatureVoice.pitch = 0.9f + 0.2f * (float)random.NextDouble();
			}
			Plugin.Logger.LogDebug((object)"Eyeless dog: Reroll voice pitch (seeded random)");
		}

		[HarmonyPatch("KillPlayerClientRpc")]
		[HarmonyPrefix]
		private static void MouthDogAI_Pre_KillPlayerClientRpc(MouthDogAI __instance)
		{
			if (!dogPitches.ContainsKey(__instance))
			{
				dogPitches.Add(__instance, (((EnemyAI)__instance).creatureVoice.pitch, Time.timeSinceLevelLoad + 5.01f));
				Plugin.Logger.LogDebug((object)$"Eyeless dog #{((Object)__instance).GetInstanceID()}: Cached {((EnemyAI)__instance).creatureVoice.pitch}x voice pitch (kill animation will start)");
			}
			else
			{
				Plugin.Logger.LogWarning((object)$"Eyeless dog #{((Object)__instance).GetInstanceID()}: Tried to initiate kill animation before ending previous kill animation");
			}
		}

		[HarmonyPatch("Update")]
		[HarmonyPostfix]
		private static void MouthDogAI_Post_Update(MouthDogAI __instance, bool ___inKillAnimation)
		{
			if (!((EnemyAI)__instance).isEnemyDead)
			{
				if (dogPitches.Count > 0 && !___inKillAnimation && dogPitches.TryGetValue(__instance, out (float, float) value) && Time.timeSinceLevelLoad >= value.Item2)
				{
					dogPitches.Remove(__instance);
					Plugin.Logger.LogDebug((object)$"Eyeless dog #{((Object)__instance).GetInstanceID()}: Reset voice pitch now that kill sound is done ({((EnemyAI)__instance).creatureVoice.pitch}x -> {value.Item1}x)");
					((EnemyAI)__instance).creatureVoice.pitch = value.Item1;
				}
				if (!((EnemyAI)__instance).creatureVoice.isPlaying)
				{
					((EnemyAI)__instance).creatureVoice.Play();
				}
			}
		}

		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> MouthDogAI_Trans_EnterChaseMode(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = instructions.ToList();
			for (int i = 1; i < list.Count; i++)
			{
				if (list[i].opcode == OpCodes.Callvirt && (MethodInfo)list[i].operand == References.PLAY_ONE_SHOT && list[i - 1].opcode == OpCodes.Ldfld && (FieldInfo)list[i - 1].operand == AccessTools.Field(typeof(MouthDogAI), "breathingSFX"))
				{
					for (int j = i - 4; j <= i; j++)
					{
						list[j].opcode = OpCodes.Nop;
					}
					Plugin.Logger.LogDebug((object)"Transpiler (Eyeless dog): Fix overlapping breathing");
					break;
				}
			}
			return list;
		}

		[HarmonyPatch(typeof(EnemyAI), "SubtractFromPowerLevel")]
		[HarmonyPostfix]
		private static void EnemyAI_Post_SubtractFromPowerLevel(EnemyAI __instance)
		{
			MouthDogAI val = (MouthDogAI)(object)((__instance is MouthDogAI) ? __instance : null);
			if ((Object)(object)val != (Object)null && dogPitches.Remove(val))
			{
				Plugin.Logger.LogDebug((object)$"Eyeless dog #{((Object)__instance).GetInstanceID()}: Died mid kill animation (clean up cached reference)");
			}
		}

		[HarmonyPatch(typeof(RoundManager), "ResetEnemyVariables")]
		[HarmonyPostfix]
		private static void RoundManager_Post_ResetEnemyVariables()
		{
			dogPitches.Clear();
		}

		[HarmonyPatch("HitEnemy")]
		[HarmonyPrefix]
		private static void MouthDogAI_Pre_HitEnemy(MouthDogAI __instance, int force, bool playHitSFX)
		{
			GeneralPatches.playHitSound = playHitSFX && !((EnemyAI)__instance).isEnemyDead && ((EnemyAI)__instance).enemyHP <= force;
		}
	}
	[HarmonyPatch(typeof(ForestGiantAI))]
	internal static class ForestKeeperPatches
	{
		private const float TIME_PLAY_AUDIO_2 = 2.2f;

		[HarmonyPatch("Update")]
		[HarmonyPostfix]
		private static void ForestGiantAI_Post_Update(ForestGiantAI __instance)
		{
			if (((EnemyAI)__instance).stunNormalizedTimer > 0f || ((EnemyAI)__instance).isEnemyDead || ((EnemyAI)__instance).currentBehaviourStateIndex == 2)
			{
				PlayAudioAnimationEvent component = ((Component)__instance.animationContainer).GetComponent<PlayAudioAnimationEvent>();
				AudioSource audioToPlay = component.audioToPlay;
				if (audioToPlay.isPlaying && (Object)(object)audioToPlay.clip != (Object)null)
				{
					audioToPlay.clip = null;
					audioToPlay.Stop();
					Plugin.Logger.LogDebug((object)"Forest keeper: Stop chewing (eating animation interrupted)");
				}
				ParticleSystem particle = component.particle;
				if (particle.isEmitting)
				{
					particle.Stop();
					Plugin.Logger.LogDebug((object)"Forest keeper: Stop spraying blood from mouth (eating animation interrupted)");
				}
			}
		}

		[HarmonyPatch("StopKillAnimation")]
		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> ForestGiantAI_Trans_Animation(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = instructions.ToList();
			for (int i = 1; i < list.Count - 1; i++)
			{
				if (list[i].opcode == OpCodes.Ldfld && (FieldInfo)list[i].operand == References.CREATURE_VOICE)
				{
					for (int j = i - 1; j <= i + 1; j++)
					{
						list[j].opcode = OpCodes.Nop;
						list[j].operand = null;
					}
					Plugin.Logger.LogDebug((object)"Transpiler (Forest Keeper): Don't interrupt voice");
					break;
				}
			}
			return list;
		}

		[HarmonyPatch("AnimationEventA")]
		[HarmonyPostfix]
		private static void ForestGiantAI_Post_AnimationEventA(ForestGiantAI __instance)
		{
			((EnemyAI)__instance).creatureSFX.PlayOneShot(__instance.giantFall);
			Plugin.Logger.LogDebug((object)"Forest keeper: Fallen down");
		}

		[HarmonyPatch(typeof(PlayAudioAnimationEvent), "PlayAudio2")]
		[HarmonyPrefix]
		private static bool PlayAudioAnimationEvent_Pre_PlayAudio2(PlayAudioAnimationEvent __instance)
		{
			if (((Object)__instance.audioClip2).name == "FGiantEatPlayerSFX")
			{
				EnemyAI mainScript = ((Component)__instance).GetComponent<EnemyAnimationEvent>().mainScript;
				ForestGiantAI val = (ForestGiantAI)(object)((mainScript is ForestGiantAI) ? mainScript : null);
				if ((Object)(object)((EnemyAI)val).inSpecialAnimationWithPlayer != (Object)null && (Object)(object)((EnemyAI)val).inSpecialAnimationWithPlayer.inAnimationWithEnemy == (Object)(object)val)
				{
					__instance.audioToPlay.PlayOneShot(__instance.audioClip2);
					Plugin.Logger.LogDebug((object)"Forest keeper: Play bite sound effect with overlap");
				}
				else
				{
					Plugin.Logger.LogDebug((object)"Forest keeper: Don't bite (player was teleported)");
				}
				return false;
			}
			return true;
		}

		[HarmonyPatch(typeof(PlayAudioAnimationEvent), "PlayParticle")]
		[HarmonyPrefix]
		private static bool PlayAudioAnimationEvent_Pre_PlayParticle(PlayAudioAnimationEvent __instance)
		{
			if ((Object)(object)__instance.audioClip2 != (Object)null && ((Object)__instance.audioClip2).name == "FGiantEatPlayerSFX")
			{
				EnemyAI mainScript = ((Component)__instance).GetComponent<EnemyAnimationEvent>().mainScript;
				if ((Object)(object)mainScript.inSpecialAnimationWithPlayer == (Object)null || (Object)(object)mainScript.inSpecialAnimationWithPlayer.inAnimationWithEnemy != (Object)(object)mainScript)
				{
					Plugin.Logger.LogDebug((object)"Forest keeper: Don't spray blood (player was teleported)");
					return false;
				}
			}
			return true;
		}

		[HarmonyPatch(typeof(EnemyAI), "CancelSpecialAnimationWithPlayer")]
		[HarmonyPrefix]
		private static void EnemyAI_Pre_CancelSpecialAnimationWithPlayer(EnemyAI __instance)
		{
			if (!(__instance is ForestGiantAI) || !((Object)(object)__instance.inSpecialAnimationWithPlayer != (Object)null) || !((Object)(object)__instance.inSpecialAnimationWithPlayer.inAnimationWithEnemy == (Object)(object)__instance) || __instance.inSpecialAnimationWithPlayer.isPlayerDead)
			{
				return;
			}
			PlayAudioAnimationEvent component = ((Component)((ForestGiantAI)((__instance is ForestGiantAI) ? __instance : null)).animationContainer).GetComponent<PlayAudioAnimationEvent>();
			AudioSource audioToPlay = component.audioToPlay;
			if (!audioToPlay.isPlaying)
			{
				return;
			}
			AudioClip clip = audioToPlay.clip;
			if (((clip != null) ? ((Object)clip).name : null) == "Roar" && audioToPlay.time > 2.2f)
			{
				audioToPlay.Stop();
				Plugin.Logger.LogDebug((object)"Forest keeper: Stop chewing (player was teleported)");
				ParticleSystem particle = component.particle;
				if (particle.isEmitting)
				{
					particle.Stop();
					Plugin.Logger.LogDebug((object)"Forest keeper: Stop spraying blood from mouth (player was teleported)");
				}
			}
		}
	}
	[HarmonyPatch(typeof(GiantKiwiAI))]
	internal static class GiantSapsuckerPatches
	{
		[HarmonyPatch("Update")]
		[HarmonyPostfix]
		private static void GiantKiwiAI_Post_Update(GiantKiwiAI __instance)
		{
			if (((EnemyAI)__instance).isEnemyDead && ((EnemyAI)__instance).creatureSFX.isPlaying)
			{
				((EnemyAI)__instance).creatureSFX.Stop();
				Plugin.Logger.LogDebug((object)"Sapsucker: Stop snoring (dead)");
			}
		}
	}
	[HarmonyPatch(typeof(HoarderBugAI))]
	internal static class HoardingBugPatches
	{
		[HarmonyPatch("KillEnemy")]
		[HarmonyPostfix]
		private static void HoarderBugAI_Post_KillEnemy(HoarderBugAI __instance, bool destroy)
		{
			if (GeneralPatches.playHitSound)
			{
				GeneralPatches.playHitSound = false;
				if (!destroy)
				{
					((EnemyAI)__instance).creatureSFX.PlayOneShot(((EnemyAI)__instance).enemyType.hitBodySFX);
					Plugin.Logger.LogDebug((object)"Hoarding bug: Play hit sound on death");
				}
			}
			if (!destroy)
			{
				((EnemyAI)__instance).creatureVoice.PlayOneShot(((EnemyAI)__instance).enemyType.deathSFX);
				Plugin.Logger.LogDebug((object)"Hoarding bug: Played backup death sound");
			}
		}

		[HarmonyPatch("HitEnemy")]
		[HarmonyPrefix]
		private static void HoarderBugAI_Pre_HitEnemy(HoarderBugAI __instance, int force, bool playHitSFX)
		{
			GeneralPatches.playHitSound = playHitSFX && !((EnemyAI)__instance).isEnemyDead && ((EnemyAI)__instance).enemyHP <= force;
		}
	}
	[HarmonyPatch(typeof(BushWolfEnemy))]
	internal static class KidnapperFoxPatches
	{
		[HarmonyPatch("HitTongueLocalClient")]
		[HarmonyPostfix]
		private static void BushWolfEnemy_Post_HitTongueLocalClient(BushWolfEnemy __instance)
		{
			((EnemyAI)__instance).creatureVoice.PlayOneShot(__instance.hitBushWolfSFX);
			Plugin.Logger.LogDebug((object)"Kidnapper fox: Bit my tongue");
		}

		[HarmonyPatch("Update")]
		[HarmonyPostfix]
		private static void BushWolfEnemy_Post_Update(BushWolfEnemy __instance, bool ___dragging)
		{
			if ((!___dragging || ((EnemyAI)__instance).isEnemyDead || ((EnemyAI)__instance).stunNormalizedTimer > 0f) && ((EnemyAI)__instance).creatureVoice.isPlaying && (Object)(object)((EnemyAI)__instance).creatureVoice.clip == (Object)(object)__instance.snarlSFX)
			{
				((EnemyAI)__instance).creatureVoice.clip = null;
				Plugin.Logger.LogDebug((object)"Kidnapper fox: Cancel snarl (failsafe)");
			}
			if (((EnemyAI)__instance).isEnemyDead && __instance.spitParticle.isEmitting)
			{
				__instance.spitParticle.Stop();
				Plugin.Logger.LogDebug((object)"Kidnapper fox: Cancel drool");
			}
		}

		[HarmonyPatch("CancelReelingPlayerIn")]
		[HarmonyPrefix]
		private static void BushWolfEnemy_Pre_CancelReelingPlayerIn(BushWolfEnemy __instance, ref bool ___dragging)
		{
			if (___dragging && ((EnemyAI)__instance).isEnemyDead)
			{
				___dragging = false;
				Plugin.Logger.LogDebug((object)"Kidnapper fox: Don't let dragging interrupt death voice");
			}
		}

		[HarmonyPatch("HitEnemy")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> BushWolfEnemy_Trans_HitEnemy(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
		{
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Expected O, but got Unknown
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Expected O, but got Unknown
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Expected O, but got Unknown
			List<CodeInstruction> list = instructions.ToList();
			MethodInfo methodInfo = AccessTools.Method(typeof(BushWolfEnemy), "CancelReelingPlayerIn", (Type[])null, (Type[])null);
			Label label = generator.DefineLabel();
			list[list.Count - 1].labels.Add(label);
			for (int num = list.Count - 1; num >= 0; num--)
			{
				if (list[num].opcode == OpCodes.Call && (MethodInfo)list[num].operand == methodInfo)
				{
					list.InsertRange(num + 1, new <>z__ReadOnlyArray<CodeInstruction>((CodeInstruction[])(object)new CodeInstruction[3]
					{
						new CodeInstruction(OpCodes.Ldarg_0, (object)null),
						new CodeInstruction(OpCodes.Ldfld, (object)References.IS_ENEMY_DEAD),
						new CodeInstruction(OpCodes.Brtrue, (object)label)
					}));
					Plugin.Logger.LogDebug((object)"Transpiler (Kidnapper fox): Don't cry when dead");
					break;
				}
			}
			return list;
		}
	}
	[HarmonyPatch(typeof(CaveDwellerAI))]
	internal static class ManeaterPatches
	{
		[HarmonyPatch("HitEnemy")]
		[HarmonyPrefix]
		private static void CaveDwellerAI_Pre_HitEnemy(CaveDwellerAI __instance, int force, bool playHitSFX)
		{
			GeneralPatches.playHitSound = playHitSFX && !((EnemyAI)__instance).isEnemyDead && ((EnemyAI)__instance).enemyHP <= 1;
		}

		[HarmonyPatch("KillEnemy")]
		[HarmonyPostfix]
		private static void CaveDwellerAI_Post_KillEnemy(CaveDwellerAI __instance, bool destroy)
		{
			if (destroy)
			{
				return;
			}
			if (GeneralPatches.playHitSound)
			{
				GeneralPatches.playHitSound = false;
				if (!destroy)
				{
					((EnemyAI)__instance).creatureSFX.Stop();
					((EnemyAI)__instance).creatureSFX.PlayOneShot(((EnemyAI)__instance).enemyType.hitBodySFX);
					Plugin.Logger.LogDebug((object)"Maneater: Play hit sound on death");
				}
			}
			AudioSource[] array = (AudioSource[])(object)new AudioSource[5] { __instance.clickingAudio1, __instance.clickingAudio2, __instance.walkingAudio, __instance.screamAudio, __instance.screamAudioNonDiagetic };
			foreach (AudioSource obj in array)
			{
				obj.Stop();
				obj.mute = true;
			}
		}
	}
	[HarmonyPatch(typeof(MaskedPlayerEnemy))]
	internal static class MaskedPatches
	{
		private static EntranceTeleport mainEntranceScript;

		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		private static void MaskedPlayerEnemy_Post_Start(MaskedPlayerEnemy __instance)
		{
			//IL_004f: 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_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			if (!Plugin.configBetterMimicSteps.Value)
			{
				return;
			}
			AudioSource val = GameNetworkManager.Instance?.localPlayerController?.movementAudio;
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			((Component)__instance.movementAudio).transform.localPosition = new Vector3(0f, 0.278f, 0f);
			__instance.movementAudio.volume = val.volume;
			__instance.movementAudio.dopplerLevel = val.dopplerLevel;
			__instance.movementAudio.spread = val.spread;
			__instance.movementAudio.rolloffMode = (AudioRolloffMode)2;
			foreach (AudioSourceCurveType value in Enum.GetValues(typeof(AudioSourceCurveType)))
			{
				__instance.movementAudio.SetCustomCurve(value, val.GetCustomCurve(value));
			}
			Plugin.Logger.LogDebug((object)"Mimic: Footsteps match players");
		}

		[HarmonyPatch("HitEnemy")]
		[HarmonyPrefix]
		private static void MaskedPlayerEnemy_Pre_HitEnemy(MaskedPlayerEnemy __instance, int force, bool playHitSFX)
		{
			GeneralPatches.playHitSound = playHitSFX && !((EnemyAI)__instance).isEnemyDead && ((EnemyAI)__instance).enemyHP <= force;
		}

		[HarmonyPatch("KillEnemy")]
		[HarmonyPostfix]
		private static void MaskedPlayerEnemy_Post_KillEnemy(MaskedPlayerEnemy __instance, bool destroy)
		{
			if (GeneralPatches.playHitSound)
			{
				GeneralPatches.playHitSound = false;
				if (!destroy)
				{
					((EnemyAI)__instance).creatureSFX.PlayOneShot(((EnemyAI)__instance).enemyType.hitBodySFX);
					Plugin.Logger.LogDebug((object)"Mimic: Play hit sound on death");
				}
			}
		}

		[HarmonyPatch("TeleportMaskedEnemy")]
		[HarmonyTranspiler]
		[HarmonyPriority(800)]
		private static IEnumerable<CodeInstruction> MaskedPlayerEnemy_Trans_TeleportMaskedEnemy(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = instructions.ToList();
			MethodInfo methodInfo = AccessTools.Method(typeof(RoundManager), "FindMainEntranceScript", (Type[])null, (Type[])null);
			for (int num = list.Count - 2; num >= 0; num--)
			{
				if (list[num].opcode == OpCodes.Call && (MethodInfo)list[num].operand == methodInfo)
				{
					list.RemoveAt(num);
					list.RemoveAt(num - 1);
					Plugin.Logger.LogDebug((object)"Transpiler (Mimic teleport): Remove old sound code");
					return list;
				}
				list.RemoveAt(num);
			}
			Plugin.Logger.LogError((object)"Mimic teleport transpiler failed");
			return instructions;
		}

		[HarmonyPatch("TeleportMaskedEnemy")]
		[HarmonyPostfix]
		private static void MaskedPlayerEnemy_Post_TeleportMaskedEnemy()
		{
			if ((Object)(object)mainEntranceScript == (Object)null)
			{
				mainEntranceScript = Object.FindObjectsByType<EntranceTeleport>((FindObjectsSortMode)0)?.FirstOrDefault((Func<EntranceTeleport, bool>)((EntranceTeleport entranceTeleport) => entranceTeleport.entranceId == 0));
			}
			if ((Object)(object)mainEntranceScript != (Object)null)
			{
				mainEntranceScript.PlayAudioAtTeleportPositions();
				Plugin.Logger.LogDebug((object)"Mimic: Play door sound");
			}
		}
	}
	[HarmonyPatch(typeof(NutcrackerEnemyAI))]
	internal static class NutcrackerPatches
	{
		[HarmonyPatch("KillEnemy")]
		[HarmonyPostfix]
		private static void NutcrackerEnemyAI_Post_KillEnemy(NutcrackerEnemyAI __instance, bool destroy)
		{
			if (!destroy)
			{
				((EnemyAI)__instance).creatureVoice.loop = false;
				((EnemyAI)__instance).creatureVoice.clip = null;
				((EnemyAI)__instance).creatureVoice.pitch = 1f;
				((EnemyAI)__instance).creatureVoice.PlayOneShot(((EnemyAI)__instance).enemyType.deathSFX);
				Plugin.Logger.LogDebug((object)"Nutcracker: Played death sound");
			}
		}
	}
	[HarmonyPatch(typeof(CentipedeAI))]
	internal static class SnareFleaPatches
	{
		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> CentipedeAI_Trans_delayedShriek(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
		{
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Expected O, but got Unknown
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Expected O, but got Unknown
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Expected O, but got Unknown
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Expected O, but got Unknown
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Expected O, but got Unknown
			List<CodeInstruction> list = instructions.ToList();
			Label label = generator.DefineLabel();
			for (int i = 0; i < list.Count - 1; i++)
			{
				if (list[i].opcode == OpCodes.Ldloc_1 && list[i + 1].opcode == OpCodes.Ldfld && (FieldInfo)list[i + 1].operand == References.CREATURE_VOICE)
				{
					list[i].labels.Add(label);
					list.InsertRange(i, new <>z__ReadOnlyArray<CodeInstruction>((CodeInstruction[])(object)new CodeInstruction[5]
					{
						new CodeInstruction(OpCodes.Ldloc_1, (object)null),
						new CodeInstruction(OpCodes.Ldfld, (object)References.IS_ENEMY_DEAD),
						new CodeInstruction(OpCodes.Brfalse, (object)label),
						new CodeInstruction(OpCodes.Ldc_I4_0, (object)null),
						new CodeInstruction(OpCodes.Ret, (object)null)
					}));
					Plugin.Logger.LogDebug((object)"Transpiler (Snare flea): Don't shriek when dead (A)");
					break;
				}
			}
			return list;
		}

		[HarmonyPatch("Update")]
		[HarmonyPrefix]
		private static void CentipedeAI_Pre_Update(CentipedeAI __instance)
		{
			if (((EnemyAI)__instance).creatureSFX.isPlaying && (Object)(object)((EnemyAI)__instance).creatureSFX.clip == (Object)(object)((EnemyAI)__instance).enemyBehaviourStates[2].SFXClip && (((EnemyAI)__instance).isEnemyDead || ((EnemyAI)__instance).currentBehaviourStateIndex != 2))
			{
				((EnemyAI)__instance).creatureSFX.Stop();
				((EnemyAI)__instance).creatureSFX.clip = null;
				Plugin.Logger.LogDebug((object)"Snare flea: Stop walking while dead, clinging to player, or sneaking away");
			}
		}

		[HarmonyPatch("KillEnemy")]
		[HarmonyPostfix]
		private static void CentipedeAI_Post_KillEnemy(CentipedeAI __instance)
		{
			((EnemyAI)__instance).creatureSFX.clip = null;
		}

		[HarmonyPatch(typeof(EnemyAI), "PlayAudioOfCurrentState")]
		[HarmonyPostfix]
		private static void EnemyAI_Post_PlayAudioOfCurrentState(EnemyAI __instance)
		{
			if (__instance is CentipedeAI && __instance.currentBehaviourStateIndex == 1 && __instance.creatureVoice.pitch > 1f)
			{
				__instance.creatureVoice.pitch = 1f;
				Plugin.Logger.LogDebug((object)"Snare flea: Reset \"voice\" pitch for attacking again");
			}
		}

		[HarmonyPatch("HitEnemy")]
		[HarmonyPrefix]
		private static void CentipedeAI_Pre_HitEnemy(CentipedeAI __instance)
		{
			if (((EnemyAI)__instance).creatureSFX.isPlaying && (Object)(object)((EnemyAI)__instance).creatureSFX.clip == (Object)(object)((EnemyAI)__instance).enemyBehaviourStates[2].SFXClip)
			{
				((EnemyAI)__instance).creatureSFX.Stop();
				((EnemyAI)__instance).creatureSFX.clip = null;
			}
		}

		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> CentipedeAI_Trans_fallFromCeiling(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
		{
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Expected O, but got Unknown
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Expected O, but got Unknown
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Expected O, but got Unknown
			List<CodeInstruction> list = instructions.ToList();
			Label label = generator.DefineLabel();
			FieldInfo fieldInfo = AccessTools.Field(typeof(CentipedeAI), "shriekClips");
			for (int i = 8; i < list.Count - 2; i++)
			{
				if (list[i].opcode == OpCodes.Call && (MethodInfo)list[i].operand == References.PLAY_RANDOM_CLIP && list[i - 5].opcode == OpCodes.Ldfld && (FieldInfo)list[i - 5].operand == fieldInfo)
				{
					list[i + 2].labels.Add(label);
					list.InsertRange(i - 8, new <>z__ReadOnlyArray<CodeInstruction>((CodeInstruction[])(object)new CodeInstruction[3]
					{
						new CodeInstruction(OpCodes.Ldloc_1, (object)null),
						new CodeInstruction(OpCodes.Ldfld, (object)References.IS_ENEMY_DEAD),
						new CodeInstruction(OpCodes.Brtrue, (object)label)
					}));
					Plugin.Logger.LogDebug((object)"Transpiler (Snare flea): Don't shriek when dead (B)");
					break;
				}
			}
			return list;
		}

		[HarmonyPatch("StopClingingToPlayer")]
		[HarmonyPostfix]
		private static void CentipedeAI_Post_StopClingingToPlayer(CentipedeAI __instance)
		{
			__instance.clingingToPlayer2DAudio.Stop();
		}
	}
	[HarmonyPatch(typeof(FlowerSnakeEnemy))]
	internal static class TulipSnakePatches
	{
		[HarmonyPatch("Update")]
		[HarmonyPostfix]
		private static void FlowerSnakeEnemy_Post_Update(FlowerSnakeEnemy __instance, bool ___flapping)
		{
			if (!__instance.flappingAudio.isPlaying)
			{
				return;
			}
			if (((EnemyAI)__instance).isEnemyDead)
			{
				__instance.flappingAudio.Stop();
				__instance.flappingAudio.mute = true;
				Plugin.Logger.LogDebug((object)"Tulip snake: Stop making noise while dead");
			}
			else if (!Plugin.INSTALLED_SOUND_API)
			{
				if ((Object)(object)__instance.flappingAudio.clip == (Object)(object)((EnemyAI)__instance).enemyType.audioClips[9])
				{
					if ((Object)(object)__instance.clingingToPlayer != (Object)null)
					{
						__instance.flappingAudio.Stop();
						Plugin.Logger.LogDebug((object)"Tulip snake: Stop scurrying (latched to player)");
					}
				}
				else if ((Object)(object)__instance.clingingToPlayer == (Object)null)
				{
					__instance.flappingAudio.Stop();
					Plugin.Logger.LogDebug((object)"Tulip snake: Stop flapping (no longer clinging)");
				}
			}
			if (___flapping)
			{
				__instance.flappingAudio.volume = 0.85f;
			}
		}

		[HarmonyPatch("StopLeapOnLocalClient")]
		[HarmonyPostfix]
		private static void FlowerSnakeEnemy_Post_StopLeapOnLocalClient(FlowerSnakeEnemy __instance, bool landOnGround)
		{
			if (landOnGround && !((EnemyAI)__instance).isEnemyDead)
			{
				__instance.flappingAudio.pitch = Random.Range(0.8f, 1.2f);
				Plugin.Logger.LogDebug((object)"Tulip snake: Reroll scurry pitch (landed from leap)");
			}
		}

		[HarmonyPatch("StopClingingOnLocalClient")]
		[HarmonyPostfix]
		private static void FlowerSnakeEnemy_Post_StopClingingOnLocalClient(FlowerSnakeEnemy __instance)
		{
			if (!((EnemyAI)__instance).isEnemyDead)
			{
				__instance.flappingAudio.pitch = Random.Range(0.8f, 1.2f);
				Plugin.Logger.LogDebug((object)"Tulip snake: Reroll scurry pitch (dismounted player)");
			}
		}

		[HarmonyPatch("HitEnemy")]
		[HarmonyPrefix]
		private static void FlowerSnakeEnemy_Pre_HitEnemy(FlowerSnakeEnemy __instance, bool playHitSFX)
		{
			GeneralPatches.playHitSound = playHitSFX && !((EnemyAI)__instance).isEnemyDead;
		}

		[HarmonyPatch("KillEnemy")]
		[HarmonyPostfix]
		private static void FlowerSnakeEnemy_Post_KillEnemy(FlowerSnakeEnemy __instance, bool destroy)
		{
			if (GeneralPatches.playHitSound)
			{
				GeneralPatches.playHitSound = false;
				if (!destroy && (Object)(object)References.hitEnemyBody != (Object)null)
				{
					((EnemyAI)__instance).creatureSFX.PlayOneShot(References.hitEnemyBody);
					Plugin.Logger.LogDebug((object)"Tulip snake: Squish");
				}
			}
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}
[CompilerGenerated]
internal sealed class <>z__ReadOnlyArray<T> : IEnumerable, ICollection, IList, IEnumerable<T>, IReadOnlyCollection<T>, IReadOnlyList<T>, ICollection<T>, IList<T>
{
	int ICollection.Count => _items.Length;

	bool ICollection.IsSynchronized => false;

	object ICollection.SyncRoot => this;

	object IList.this[int index]
	{
		get
		{
			return _items[index];
		}
		set
		{
			throw new NotSupportedException();
		}
	}

	bool IList.IsFixedSize => true;

	bool IList.IsReadOnly => true;

	int IReadOnlyCollection<T>.Count => _items.Length;

	T IReadOnlyList<T>.this[int index] => _items[index];

	int ICollection<T>.Count => _items.Length;

	bool ICollection<T>.IsReadOnly => true;

	T IList<T>.this[int index]
	{
		get
		{
			return _items[index];
		}
		set
		{
			throw new NotSupportedException();
		}
	}

	public <>z__ReadOnlyArray(T[] items)
	{
		_items = items;
	}

	IEnumerator IEnumerable.GetEnumerator()
	{
		return ((IEnumerable)_items).GetEnumerator();
	}

	void ICollection.CopyTo(Array array, int index)
	{
		((ICollection)_items).CopyTo(array, index);
	}

	int IList.Add(object value)
	{
		throw new NotSupportedException();
	}

	void IList.Clear()
	{
		throw new NotSupportedException();
	}

	bool IList.Contains(object value)
	{
		return ((IList)_items).Contains(value);
	}

	int IList.IndexOf(object value)
	{
		return ((IList)_items).IndexOf(value);
	}

	void IList.Insert(int index, object value)
	{
		throw new NotSupportedException();
	}

	void IList.Remove(object value)
	{
		throw new NotSupportedException();
	}

	void IList.RemoveAt(int index)
	{
		throw new NotSupportedException();
	}

	IEnumerator<T> IEnumerable<T>.GetEnumerator()
	{
		return ((IEnumerable<T>)_items).GetEnumerator();
	}

	void ICollection<T>.Add(T item)
	{
		throw new NotSupportedException();
	}

	void ICollection<T>.Clear()
	{
		throw new NotSupportedException();
	}

	bool ICollection<T>.Contains(T item)
	{
		return ((ICollection<T>)_items).Contains(item);
	}

	void ICollection<T>.CopyTo(T[] array, int arrayIndex)
	{
		((ICollection<T>)_items).CopyTo(array, arrayIndex);
	}

	bool ICollection<T>.Remove(T item)
	{
		throw new NotSupportedException();
	}

	int IList<T>.IndexOf(T item)
	{
		return ((IList<T>)_items).IndexOf(item);
	}

	void IList<T>.Insert(int index, T item)
	{
		throw new NotSupportedException();
	}

	void IList<T>.RemoveAt(int index)
	{
		throw new NotSupportedException();
	}
}