Decompiled source of FairAI v1.5.1

FairAI.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using FairAI;
using FairAI.Component;
using FairAI.Patches;
using GameNetcodeStuff;
using HarmonyLib;
using LethalConfig;
using LethalConfig.ConfigItems;
using LethalThings;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.AI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("FairAI")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("FairAI")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("42deea12-f73e-4d63-81e9-5359e98c8d53")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
internal class TurretAIPatch
{
	public static float viewRadius = 16f;

	public static float viewAngle = 90f;

	public static bool PatchUpdate(ref Turret __instance)
	{
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_019d: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bf: Expected I4, but got Unknown
		//IL_0195: Unknown result type (might be due to invalid IL or missing references)
		//IL_0125: Unknown result type (might be due to invalid IL or missing references)
		//IL_012b: Invalid comparison between Unknown and I4
		//IL_0156: Unknown result type (might be due to invalid IL or missing references)
		//IL_014a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0213: Unknown result type (might be due to invalid IL or missing references)
		//IL_022e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0247: Unknown result type (might be due to invalid IL or missing references)
		//IL_0253: Unknown result type (might be due to invalid IL or missing references)
		//IL_0265: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_02be: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)__instance == (Object)null) && Plugin.AllowFairness(((Component)__instance).transform.position))
		{
			FAIR_AI fAIR_AI = ((Component)__instance).gameObject.GetComponent<FAIR_AI>() ?? ((Component)__instance).gameObject.AddComponent<FAIR_AI>();
			Type typeFromHandle = typeof(Turret);
			FieldInfo field = typeFromHandle.GetField("wasTargetingPlayerLastFrame", BindingFlags.Instance | BindingFlags.NonPublic);
			FieldInfo field2 = typeFromHandle.GetField("rotatingClockwise", BindingFlags.Instance | BindingFlags.NonPublic);
			FieldInfo field3 = typeFromHandle.GetField("rotatingSmoothly", BindingFlags.Instance | BindingFlags.NonPublic);
			MethodInfo method = typeFromHandle.GetMethod("SetTargetToPlayerBody", BindingFlags.Instance | BindingFlags.NonPublic);
			MethodInfo method2 = typeFromHandle.GetMethod("TurnTowardsTargetIfHasLOS", BindingFlags.Instance | BindingFlags.NonPublic);
			if (!__instance.turretActive)
			{
				field.SetValue(__instance, false);
				__instance.turretMode = (TurretMode)0;
				__instance.targetPlayerWithRotation = null;
				fAIR_AI.targetWithRotation = null;
				return false;
			}
			if ((Object)(object)fAIR_AI.targetWithRotation != (Object)null || (Object)(object)__instance.targetPlayerWithRotation != (Object)null)
			{
				if (!(bool)field.GetValue(__instance))
				{
					field.SetValue(__instance, true);
					if ((int)__instance.turretMode == 0)
					{
						if ((Object)(object)fAIR_AI.targetWithRotation != (Object)null)
						{
							__instance.turretMode = (TurretMode)2;
						}
						else
						{
							__instance.turretMode = (TurretMode)1;
						}
					}
				}
				SetTargetToEnemyBody(ref __instance);
				TurnTowardsTargetEnemyIfHasLOS(ref __instance);
			}
			else if ((bool)field.GetValue(__instance))
			{
				field.SetValue(__instance, false);
				__instance.turretMode = (TurretMode)0;
			}
			TurretMode turretMode = __instance.turretMode;
			TurretMode val = turretMode;
			switch ((int)val)
			{
			case 0:
				DetectionFunction(__instance, fAIR_AI);
				break;
			case 1:
				ChargingFunction(__instance, fAIR_AI);
				break;
			case 2:
				FiringFunction(__instance);
				break;
			case 3:
				BerserkFunction(__instance);
				break;
			}
			if ((bool)field2.GetValue(__instance))
			{
				__instance.turnTowardsObjectCompass.localEulerAngles = new Vector3(-180f, __instance.turretRod.localEulerAngles.y - Time.deltaTime * 20f, 180f);
				__instance.turretRod.rotation = Quaternion.RotateTowards(__instance.turretRod.rotation, __instance.turnTowardsObjectCompass.rotation, __instance.rotationSpeed * Time.deltaTime);
				return false;
			}
			if ((bool)field3.GetValue(__instance))
			{
				__instance.turnTowardsObjectCompass.localEulerAngles = new Vector3(-180f, Mathf.Clamp(__instance.targetRotation, 0f - __instance.rotationRange, __instance.rotationRange), 180f);
			}
			__instance.turretRod.rotation = Quaternion.RotateTowards(__instance.turretRod.rotation, __instance.turnTowardsObjectCompass.rotation, __instance.rotationSpeed * Time.deltaTime);
			return false;
		}
		return false;
	}

	public static void DetectionFunction(Turret turret, FAIR_AI turret_ai)
	{
		//IL_0102: Unknown result type (might be due to invalid IL or missing references)
		//IL_010c: Expected O, but got Unknown
		//IL_0371: Unknown result type (might be due to invalid IL or missing references)
		Type typeFromHandle = typeof(Turret);
		FieldInfo field = typeFromHandle.GetField("turretModeLastFrame", BindingFlags.Instance | BindingFlags.NonPublic);
		FieldInfo field2 = typeFromHandle.GetField("rotatingClockwise", BindingFlags.Instance | BindingFlags.NonPublic);
		FieldInfo field3 = typeFromHandle.GetField("fadeBulletAudioCoroutine", BindingFlags.Instance | BindingFlags.NonPublic);
		FieldInfo field4 = typeFromHandle.GetField("rotatingSmoothly", BindingFlags.Instance | BindingFlags.NonPublic);
		FieldInfo field5 = typeFromHandle.GetField("turretInterval", BindingFlags.Instance | BindingFlags.NonPublic);
		FieldInfo field6 = typeFromHandle.GetField("switchRotationTimer", BindingFlags.Instance | BindingFlags.NonPublic);
		FieldInfo field7 = typeFromHandle.GetField("rotatingRight", BindingFlags.Instance | BindingFlags.NonPublic);
		MethodInfo method = typeFromHandle.GetMethod("SwitchTurretMode", BindingFlags.Instance | BindingFlags.NonPublic);
		MethodInfo method2 = typeFromHandle.GetMethod("FadeBulletAudio", BindingFlags.Instance | BindingFlags.NonPublic);
		if ((int)field.GetValue(turret) != 0)
		{
			field.SetValue(turret, (object)(TurretMode)0);
			field2.SetValue(turret, false);
			turret.mainAudio.Stop();
			turret.farAudio.Stop();
			turret.berserkAudio.Stop();
			if (field3.GetValue(turret) != null)
			{
				((MonoBehaviour)turret).StopCoroutine((Coroutine)field3.GetValue(turret));
			}
			field3.SetValue(turret, ((MonoBehaviour)turret).StartCoroutine((IEnumerator)method2.Invoke(turret, new object[0])));
			turret.bulletParticles.Stop(true, (ParticleSystemStopBehavior)1);
			if (Plugin.turretSettings.Count > 7)
			{
				turret.rotationSpeed = Plugin.turretSettings[5];
			}
			else
			{
				turret.rotationSpeed = 28f;
			}
			field4.SetValue(turret, true);
			turret.turretAnimator.SetInteger("TurretMode", 0);
			field5.SetValue(turret, Random.Range(0f, 0.15f));
		}
		if (!((NetworkBehaviour)turret).IsServer)
		{
			return;
		}
		if (Plugin.turretSettings.Count > 7)
		{
			if ((float)field6.GetValue(turret) >= Plugin.turretSettings[3])
			{
				field6.SetValue(turret, 0f);
				bool flag = !(bool)field7.GetValue(turret);
				turret.SwitchRotationClientRpc(flag);
				turret.SwitchRotationOnInterval(flag);
			}
			else
			{
				field6.SetValue(turret, (float)field6.GetValue(turret) + Time.deltaTime);
			}
		}
		else if ((float)field6.GetValue(turret) >= 7f)
		{
			field6.SetValue(turret, 0f);
			bool flag2 = !(bool)field7.GetValue(turret);
			turret.SwitchRotationClientRpc(flag2);
			turret.SwitchRotationOnInterval(flag2);
		}
		else
		{
			field6.SetValue(turret, (float)field6.GetValue(turret) + Time.deltaTime);
		}
		if ((float)field5.GetValue(turret) >= 0.25f)
		{
			field5.SetValue(turret, 0f);
			EnemyAICollisionDetect val = CheckForEnemiesInLineOfSight(turret, 15f);
			if ((Object)(object)val != (Object)null && !val.mainScript.isEnemyDead && Plugin.CanMob("TurretTargetAllMobs", ".Turret Target", val.mainScript.enemyType.enemyName))
			{
				turret_ai.targetWithRotation = val.mainScript;
				turret.turretMode = (TurretMode)2;
				turret.SetToModeClientRpc(2);
				method.Invoke(turret, new object[1] { (object)(TurretMode)2 });
				turret_ai.SwitchedTargetedEnemyClientRpc(turret, val.mainScript);
				Plugin.logger.LogInfo((object)"Detected Enemy!");
				return;
			}
			field5.SetValue(turret, 0f);
			PlayerControllerB val2 = CheckForPlayersInLOS(turret, 1.35f, angleRangeCheck: true);
			if ((Object)(object)val2 != (Object)null && !val2.isPlayerDead)
			{
				turret.targetPlayerWithRotation = val2;
				method.Invoke(turret, new object[1] { 1 });
				turret.SwitchTargetedPlayerClientRpc((int)val2.playerClientId, true);
				Plugin.logger.LogInfo((object)"Detected Player!");
			}
		}
		else
		{
			field5.SetValue(turret, (float)field5.GetValue(turret) + Time.deltaTime);
		}
	}

	public static void ChargingFunction(Turret turret, FAIR_AI turret_ai)
	{
		//IL_0079: Unknown result type (might be due to invalid IL or missing references)
		//IL_007f: Invalid comparison between Unknown and I4
		Type typeFromHandle = typeof(Turret);
		FieldInfo field = typeFromHandle.GetField("hasLineOfSight", BindingFlags.Instance | BindingFlags.NonPublic);
		FieldInfo field2 = typeFromHandle.GetField("turretModeLastFrame", BindingFlags.Instance | BindingFlags.NonPublic);
		FieldInfo field3 = typeFromHandle.GetField("rotatingClockwise", BindingFlags.Instance | BindingFlags.NonPublic);
		FieldInfo field4 = typeFromHandle.GetField("rotatingSmoothly", BindingFlags.Instance | BindingFlags.NonPublic);
		FieldInfo field5 = typeFromHandle.GetField("turretInterval", BindingFlags.Instance | BindingFlags.NonPublic);
		FieldInfo field6 = typeFromHandle.GetField("lostLOSTimer", BindingFlags.Instance | BindingFlags.NonPublic);
		MethodInfo method = typeFromHandle.GetMethod("SwitchTurretMode", BindingFlags.Instance | BindingFlags.NonPublic);
		if ((int)(TurretMode)field2.GetValue(turret) != 1)
		{
			field2.SetValue(turret, (object)(TurretMode)1);
			field3.SetValue(turret, false);
			turret.mainAudio.PlayOneShot(turret.detectPlayerSFX);
			turret.berserkAudio.Stop();
			WalkieTalkie.TransmitOneShotAudio(turret.mainAudio, turret.detectPlayerSFX, 1f);
			if (Plugin.turretSettings.Count > 7)
			{
				turret.rotationSpeed = Plugin.turretSettings[6];
			}
			else
			{
				turret.rotationSpeed = 95f;
			}
			field4.SetValue(turret, false);
			field6.SetValue(turret, 0f);
			turret.turretAnimator.SetInteger("TurretMode", 1);
		}
		if (!((NetworkBehaviour)turret).IsServer)
		{
			return;
		}
		if ((float)field5.GetValue(turret) >= 1.5f)
		{
			field5.SetValue(turret, 0f);
			Plugin.logger.LogInfo((object)"Charging timer is up, setting to firing mode");
			if (!(bool)field.GetValue(turret))
			{
				Plugin.logger.LogInfo((object)"hasLineOfSight is false");
				turret.targetPlayerWithRotation = null;
				turret.RemoveTargetedPlayerClientRpc();
				turret_ai.targetWithRotation = null;
				turret_ai.RemoveTargetedEnemyClientRpc();
			}
			else
			{
				method.Invoke(turret, new object[1] { 2 });
				turret.SetToModeClientRpc(2);
			}
		}
		else
		{
			field5.SetValue(turret, (float)field5.GetValue(turret) + Time.deltaTime);
		}
	}

	public static void FiringFunction(Turret turret)
	{
		//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ac: Invalid comparison between Unknown and I4
		//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_081a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0825: Unknown result type (might be due to invalid IL or missing references)
		//IL_082a: Unknown result type (might be due to invalid IL or missing references)
		//IL_083c: Unknown result type (might be due to invalid IL or missing references)
		//IL_084a: Unknown result type (might be due to invalid IL or missing references)
		//IL_033d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0348: Unknown result type (might be due to invalid IL or missing references)
		//IL_034d: Unknown result type (might be due to invalid IL or missing references)
		//IL_035f: Unknown result type (might be due to invalid IL or missing references)
		//IL_036d: Unknown result type (might be due to invalid IL or missing references)
		//IL_017a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0184: Expected O, but got Unknown
		//IL_08d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_08d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_08f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_08fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_08ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_0904: Unknown result type (might be due to invalid IL or missing references)
		//IL_0912: Unknown result type (might be due to invalid IL or missing references)
		//IL_0917: Unknown result type (might be due to invalid IL or missing references)
		//IL_0870: Unknown result type (might be due to invalid IL or missing references)
		//IL_0892: Unknown result type (might be due to invalid IL or missing references)
		//IL_0897: Unknown result type (might be due to invalid IL or missing references)
		//IL_08a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_08a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_08a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_08aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_08ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_08b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_08c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_077a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0780: Unknown result type (might be due to invalid IL or missing references)
		//IL_03f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_03fb: Unknown result type (might be due to invalid IL or missing references)
		//IL_041b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0420: Unknown result type (might be due to invalid IL or missing references)
		//IL_0422: Unknown result type (might be due to invalid IL or missing references)
		//IL_0427: Unknown result type (might be due to invalid IL or missing references)
		//IL_0435: Unknown result type (might be due to invalid IL or missing references)
		//IL_043a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0393: Unknown result type (might be due to invalid IL or missing references)
		//IL_03b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_03c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_03c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_03cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_03cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_03d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_03d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_03e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_0293: Unknown result type (might be due to invalid IL or missing references)
		//IL_0299: Unknown result type (might be due to invalid IL or missing references)
		//IL_07ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_07f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_0800: Unknown result type (might be due to invalid IL or missing references)
		//IL_0806: Unknown result type (might be due to invalid IL or missing references)
		//IL_07ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_07d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_030f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0319: Unknown result type (might be due to invalid IL or missing references)
		//IL_0323: Unknown result type (might be due to invalid IL or missing references)
		//IL_0329: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_09f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_0519: Unknown result type (might be due to invalid IL or missing references)
		//IL_0a97: Unknown result type (might be due to invalid IL or missing references)
		//IL_05ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_0b26: Unknown result type (might be due to invalid IL or missing references)
		//IL_0649: Unknown result type (might be due to invalid IL or missing references)
		Type typeFromHandle = typeof(Turret);
		FieldInfo field = typeFromHandle.GetField("wasTargetingPlayerLastFrame", BindingFlags.Instance | BindingFlags.NonPublic);
		FieldInfo field2 = typeFromHandle.GetField("turretModeLastFrame", BindingFlags.Instance | BindingFlags.NonPublic);
		FieldInfo field3 = typeFromHandle.GetField("targetingDeadPlayer", BindingFlags.Instance | BindingFlags.NonPublic);
		FieldInfo field4 = typeFromHandle.GetField("fadeBulletAudioCoroutine", BindingFlags.Instance | BindingFlags.NonPublic);
		FieldInfo field5 = typeFromHandle.GetField("rotatingSmoothly", BindingFlags.Instance | BindingFlags.NonPublic);
		FieldInfo field6 = typeFromHandle.GetField("turretInterval", BindingFlags.Instance | BindingFlags.NonPublic);
		FieldInfo field7 = typeFromHandle.GetField("lostLOSTimer", BindingFlags.Instance | BindingFlags.NonPublic);
		FieldInfo field8 = typeFromHandle.GetField("shootRay", BindingFlags.Instance | BindingFlags.NonPublic);
		FieldInfo field9 = typeFromHandle.GetField("hit", BindingFlags.Instance | BindingFlags.NonPublic);
		MethodInfo method = typeFromHandle.GetMethod("SwitchTurretMode", BindingFlags.Instance | BindingFlags.NonPublic);
		if ((int)(TurretMode)field2.GetValue(turret) != 2)
		{
			field2.SetValue(turret, (object)(TurretMode)2);
			turret.berserkAudio.Stop();
			RoundManager.Instance.PlayAudibleNoise(((Component)turret.berserkAudio).transform.position, 15f, 0.9f, 0, false, 0);
			turret.mainAudio.clip = turret.firingSFX;
			turret.mainAudio.Play();
			turret.farAudio.clip = turret.firingFarSFX;
			turret.farAudio.Play();
			turret.bulletParticles.Play(true);
			turret.bulletCollisionAudio.Play();
			if (field4 != null && field4.GetValue(turret) != null)
			{
				((MonoBehaviour)turret).StopCoroutine((Coroutine)field4.GetValue(turret));
			}
			turret.bulletCollisionAudio.volume = 1f;
			field5.SetValue(turret, false);
			field7.SetValue(turret, 0f);
			turret.turretAnimator.SetInteger("TurretMode", 2);
		}
		Ray val5;
		if (Plugin.turretSettings.Count > 7)
		{
			if ((float)field6.GetValue(turret) >= Plugin.turretSettings[1])
			{
				Plugin.logger.LogInfo((object)"Attacking Target");
				field6.SetValue(turret, 0f);
				if ((Object)(object)CheckForPlayersInLOS(turret, 3f) == (Object)(object)GameNetworkManager.Instance.localPlayerController)
				{
					int num = (int)Plugin.turretSettings[0];
					if (num <= 0)
					{
						GameNetworkManager.Instance.localPlayerController.MakeCriticallyInjured(false);
						GameNetworkManager.Instance.localPlayerController.DamagePlayer(num, false, true, (CauseOfDeath)0, 0, false, default(Vector3));
						GameNetworkManager.Instance.localPlayerController.MakeCriticallyInjured(false);
					}
					else if ((float)GameNetworkManager.Instance.localPlayerController.health > Plugin.turretSettings[0])
					{
						GameNetworkManager.Instance.localPlayerController.DamagePlayer(num, true, true, (CauseOfDeath)7, 0, false, default(Vector3));
					}
					else
					{
						GameNetworkManager.Instance.localPlayerController.KillPlayer(turret.aimPoint.forward * 40f, true, (CauseOfDeath)7, 0, default(Vector3));
					}
				}
				field8.SetValue(turret, (object)new Ray(turret.aimPoint.position, turret.aimPoint.forward));
				RaycastHit val = default(RaycastHit);
				if (Physics.Raycast((Ray)field8.GetValue(turret), ref val, 30f, StartOfRound.Instance.collidersAndRoomMask, (QueryTriggerInteraction)1))
				{
					field9.SetValue(turret, val);
					Transform transform = ((Component)turret.bulletCollisionAudio).transform;
					Ray val2 = (Ray)field8.GetValue(turret);
					RaycastHit val3 = (RaycastHit)field9.GetValue(turret);
					Ray val4 = val2;
					val5 = val4;
					transform.position = ((Ray)(ref val5)).GetPoint(((RaycastHit)(ref val3)).distance - 0.5f);
				}
				Vector3 forward = turret.aimPoint.forward;
				forward = Quaternion.Euler(0f, (float)(int)(0f - turret.rotationRange) / 3f, 0f) * forward;
				Plugin.AttackTargets(((Component)turret).GetComponent<FAIR_AI>(), turret.aimPoint.position, forward, 30f);
				FAIR_AI component = ((Component)turret).GetComponent<FAIR_AI>();
				if ((Object)(object)component.targetWithRotation != (Object)null)
				{
					EnemyAICollisionDetect component2 = ((Component)component.targetWithRotation).GetComponent<EnemyAICollisionDetect>();
					if ((Object)(object)component2 != (Object)null && (component2.mainScript.isEnemyDead || component2.mainScript.enemyHP <= 0))
					{
						component.targetWithRotation = null;
						component.RemoveTargetedEnemyClientRpc();
					}
				}
				if ((Object)(object)turret.targetPlayerWithRotation != (Object)null && turret.targetPlayerWithRotation.isPlayerDead)
				{
					turret.targetPlayerWithRotation = null;
					turret.RemoveTargetedPlayerClientRpc();
				}
				if ((Object)(object)turret.targetPlayerWithRotation == (Object)null && (Object)(object)component.targetWithRotation == (Object)null)
				{
					turret.turretMode = (TurretMode)0;
					turret.SetToModeClientRpc(0);
					field.SetValue(turret, false);
					field3.SetValue(turret, true);
					turret.turretAnimator.SetInteger("TurretMode", 0);
					method.Invoke(turret, new object[1] { (object)(TurretMode)0 });
				}
				else
				{
					if (!((Object)(object)turret.targetTransform != (Object)null))
					{
						return;
					}
					if ((Object)(object)((Component)turret.targetTransform).GetComponent<EnemyAI>() != (Object)null)
					{
						if (((Component)turret.targetTransform).GetComponent<EnemyAI>().isEnemyDead)
						{
							turret.turretMode = (TurretMode)0;
							turret.SetToModeClientRpc(0);
							field.SetValue(turret, false);
							field3.SetValue(turret, true);
							turret.turretAnimator.SetInteger("TurretMode", 0);
							method.Invoke(turret, new object[1] { (object)(TurretMode)0 });
						}
					}
					else if (Object.op_Implicit((Object)(object)((Component)turret.targetTransform).GetComponent<EnemyAICollisionDetect>()) && ((Component)turret.targetTransform).GetComponent<EnemyAICollisionDetect>().mainScript.isEnemyDead)
					{
						turret.turretMode = (TurretMode)0;
						turret.SetToModeClientRpc(0);
						field.SetValue(turret, false);
						field3.SetValue(turret, true);
						turret.turretAnimator.SetInteger("TurretMode", 0);
						method.Invoke(turret, new object[1] { (object)(TurretMode)0 });
					}
				}
			}
			else
			{
				field6.SetValue(turret, (float)field6.GetValue(turret) + Time.deltaTime);
			}
		}
		else if ((float)field6.GetValue(turret) >= 0.21f)
		{
			Plugin.logger.LogInfo((object)"Attacking Target");
			field6.SetValue(turret, 0f);
			if ((Object)(object)CheckForPlayersInLOS(turret, 3f) == (Object)(object)GameNetworkManager.Instance.localPlayerController)
			{
				int @int = Plugin.GetInt("TurretConfig", "Player Damage");
				if (@int <= 0)
				{
					GameNetworkManager.Instance.localPlayerController.MakeCriticallyInjured(false);
					GameNetworkManager.Instance.localPlayerController.DamagePlayer(@int, false, true, (CauseOfDeath)0, 0, false, default(Vector3));
					GameNetworkManager.Instance.localPlayerController.MakeCriticallyInjured(false);
				}
				else if (GameNetworkManager.Instance.localPlayerController.health > 50)
				{
					GameNetworkManager.Instance.localPlayerController.DamagePlayer(@int, true, true, (CauseOfDeath)7, 0, false, default(Vector3));
				}
				else
				{
					GameNetworkManager.Instance.localPlayerController.KillPlayer(turret.aimPoint.forward * 40f, true, (CauseOfDeath)7, 0, default(Vector3));
				}
			}
			field8.SetValue(turret, (object)new Ray(turret.aimPoint.position, turret.aimPoint.forward));
			RaycastHit val6 = default(RaycastHit);
			if (Physics.Raycast((Ray)field8.GetValue(turret), ref val6, 30f, StartOfRound.Instance.collidersAndRoomMask, (QueryTriggerInteraction)1))
			{
				field9.SetValue(turret, val6);
				Transform transform2 = ((Component)turret.bulletCollisionAudio).transform;
				Ray val7 = (Ray)field8.GetValue(turret);
				RaycastHit val8 = (RaycastHit)field9.GetValue(turret);
				Ray val9 = val7;
				val5 = val9;
				transform2.position = ((Ray)(ref val5)).GetPoint(((RaycastHit)(ref val8)).distance - 0.5f);
			}
			Vector3 forward2 = turret.aimPoint.forward;
			forward2 = Quaternion.Euler(0f, (float)(int)(0f - turret.rotationRange) / 3f, 0f) * forward2;
			Plugin.AttackTargets(((Component)turret).GetComponent<FAIR_AI>(), turret.aimPoint.position, forward2, 30f);
			FAIR_AI component3 = ((Component)turret).GetComponent<FAIR_AI>();
			if ((Object)(object)component3.targetWithRotation != (Object)null)
			{
				EnemyAICollisionDetect component4 = ((Component)component3.targetWithRotation).GetComponent<EnemyAICollisionDetect>();
				if ((Object)(object)component4 != (Object)null && (component4.mainScript.isEnemyDead || component4.mainScript.enemyHP <= 0))
				{
					component3.targetWithRotation = null;
					component3.RemoveTargetedEnemyClientRpc();
				}
			}
			if ((Object)(object)turret.targetPlayerWithRotation != (Object)null && turret.targetPlayerWithRotation.isPlayerDead)
			{
				turret.targetPlayerWithRotation = null;
				turret.RemoveTargetedPlayerClientRpc();
			}
			if ((Object)(object)turret.targetPlayerWithRotation == (Object)null && (Object)(object)component3.targetWithRotation == (Object)null)
			{
				turret.turretMode = (TurretMode)0;
				turret.SetToModeClientRpc(0);
				field.SetValue(turret, false);
				field3.SetValue(turret, true);
				turret.turretAnimator.SetInteger("TurretMode", 0);
				method.Invoke(turret, new object[1] { (object)(TurretMode)0 });
			}
			else
			{
				if (!((Object)(object)turret.targetTransform != (Object)null))
				{
					return;
				}
				if ((Object)(object)((Component)turret.targetTransform).GetComponent<EnemyAI>() != (Object)null)
				{
					if (((Component)turret.targetTransform).GetComponent<EnemyAI>().isEnemyDead)
					{
						turret.turretMode = (TurretMode)0;
						turret.SetToModeClientRpc(0);
						field.SetValue(turret, false);
						field3.SetValue(turret, true);
						turret.turretAnimator.SetInteger("TurretMode", 0);
						method.Invoke(turret, new object[1] { (object)(TurretMode)0 });
					}
				}
				else if (Object.op_Implicit((Object)(object)((Component)turret.targetTransform).GetComponent<EnemyAICollisionDetect>()) && ((Component)turret.targetTransform).GetComponent<EnemyAICollisionDetect>().mainScript.isEnemyDead)
				{
					turret.turretMode = (TurretMode)0;
					turret.SetToModeClientRpc(0);
					field.SetValue(turret, false);
					field3.SetValue(turret, true);
					turret.turretAnimator.SetInteger("TurretMode", 0);
					method.Invoke(turret, new object[1] { (object)(TurretMode)0 });
				}
			}
		}
		else
		{
			field6.SetValue(turret, (float)field6.GetValue(turret) + Time.deltaTime);
		}
	}

	public static void BerserkFunction(Turret turret)
	{
		//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ca: Invalid comparison between Unknown and I4
		//IL_0298: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a2: Expected O, but got Unknown
		//IL_0682: Unknown result type (might be due to invalid IL or missing references)
		//IL_068d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0692: Unknown result type (might be due to invalid IL or missing references)
		//IL_06a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_06b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_0412: Unknown result type (might be due to invalid IL or missing references)
		//IL_041d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0422: Unknown result type (might be due to invalid IL or missing references)
		//IL_0434: Unknown result type (might be due to invalid IL or missing references)
		//IL_0442: Unknown result type (might be due to invalid IL or missing references)
		//IL_0737: Unknown result type (might be due to invalid IL or missing references)
		//IL_073c: Unknown result type (might be due to invalid IL or missing references)
		//IL_075c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0761: Unknown result type (might be due to invalid IL or missing references)
		//IL_0763: Unknown result type (might be due to invalid IL or missing references)
		//IL_0768: Unknown result type (might be due to invalid IL or missing references)
		//IL_0776: Unknown result type (might be due to invalid IL or missing references)
		//IL_077b: Unknown result type (might be due to invalid IL or missing references)
		//IL_06d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_06fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_06ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_0709: Unknown result type (might be due to invalid IL or missing references)
		//IL_070e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0712: Unknown result type (might be due to invalid IL or missing references)
		//IL_0714: Unknown result type (might be due to invalid IL or missing references)
		//IL_0725: Unknown result type (might be due to invalid IL or missing references)
		//IL_05e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_05e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_04c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_04cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_04ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_04f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_04f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_04f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_0506: Unknown result type (might be due to invalid IL or missing references)
		//IL_050b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0468: Unknown result type (might be due to invalid IL or missing references)
		//IL_048a: Unknown result type (might be due to invalid IL or missing references)
		//IL_048f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0499: Unknown result type (might be due to invalid IL or missing references)
		//IL_049e: Unknown result type (might be due to invalid IL or missing references)
		//IL_04a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_04a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_04b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_0372: Unknown result type (might be due to invalid IL or missing references)
		//IL_0378: Unknown result type (might be due to invalid IL or missing references)
		//IL_0654: Unknown result type (might be due to invalid IL or missing references)
		//IL_065e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0668: Unknown result type (might be due to invalid IL or missing references)
		//IL_066e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0632: Unknown result type (might be due to invalid IL or missing references)
		//IL_0638: Unknown result type (might be due to invalid IL or missing references)
		//IL_03e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_03f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_03fe: Unknown result type (might be due to invalid IL or missing references)
		//IL_03c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_03c8: Unknown result type (might be due to invalid IL or missing references)
		Type typeFromHandle = typeof(Turret);
		FieldInfo field = typeFromHandle.GetField("wasTargetingPlayerLastFrame", BindingFlags.Instance | BindingFlags.NonPublic);
		FieldInfo field2 = typeFromHandle.GetField("turretModeLastFrame", BindingFlags.Instance | BindingFlags.NonPublic);
		FieldInfo field3 = typeFromHandle.GetField("rotatingClockwise", BindingFlags.Instance | BindingFlags.NonPublic);
		FieldInfo field4 = typeFromHandle.GetField("fadeBulletAudioCoroutine", BindingFlags.Instance | BindingFlags.NonPublic);
		FieldInfo field5 = typeFromHandle.GetField("rotatingSmoothly", BindingFlags.Instance | BindingFlags.NonPublic);
		FieldInfo field6 = typeFromHandle.GetField("turretInterval", BindingFlags.Instance | BindingFlags.NonPublic);
		FieldInfo field7 = typeFromHandle.GetField("lostLOSTimer", BindingFlags.Instance | BindingFlags.NonPublic);
		FieldInfo field8 = typeFromHandle.GetField("shootRay", BindingFlags.Instance | BindingFlags.NonPublic);
		FieldInfo field9 = typeFromHandle.GetField("hit", BindingFlags.Instance | BindingFlags.NonPublic);
		FieldInfo field10 = typeFromHandle.GetField("berserkTimer", BindingFlags.Instance | BindingFlags.NonPublic);
		FieldInfo field11 = typeFromHandle.GetField("enteringBerserkMode", BindingFlags.Instance | BindingFlags.NonPublic);
		MethodInfo method = typeFromHandle.GetMethod("SwitchTurretMode", BindingFlags.Instance | BindingFlags.NonPublic);
		if ((int)(TurretMode)field2.GetValue(turret) != 3)
		{
			field2.SetValue(turret, (object)(TurretMode)3);
			turret.turretAnimator.SetInteger("TurretMode", 1);
			field10.SetValue(turret, 1.3f);
			turret.berserkAudio.Play();
			if (Plugin.turretSettings.Count > 7)
			{
				turret.rotationSpeed = Plugin.turretSettings[7];
			}
			else
			{
				turret.rotationSpeed = 77f;
			}
			field11.SetValue(turret, true);
			field5.SetValue(turret, true);
			field7.SetValue(turret, 0f);
			field.SetValue(turret, false);
			turret.targetPlayerWithRotation = null;
		}
		if ((bool)field11.GetValue(turret))
		{
			field10.SetValue(turret, (float)field10.GetValue(turret) - Time.deltaTime);
			if ((float)field10.GetValue(turret) <= 0f)
			{
				field11.SetValue(turret, false);
				field3.SetValue(turret, true);
				field10.SetValue(turret, 9f);
				turret.turretAnimator.SetInteger("TurretMode", 2);
				turret.mainAudio.clip = turret.firingSFX;
				turret.mainAudio.Play();
				turret.farAudio.clip = turret.firingFarSFX;
				turret.farAudio.Play();
				turret.bulletParticles.Play(true);
				turret.bulletCollisionAudio.Play();
				if (field4 != null)
				{
					((MonoBehaviour)turret).StopCoroutine((Coroutine)field4.GetValue(turret));
				}
				turret.bulletCollisionAudio.volume = 1f;
			}
			return;
		}
		Ray val4;
		if (Plugin.turretSettings.Count > 7)
		{
			if ((float)field6.GetValue(turret) >= Plugin.turretSettings[1])
			{
				field6.SetValue(turret, 0f);
				if ((Object)(object)CheckForPlayersInLOS(turret, 3f) == (Object)(object)GameNetworkManager.Instance.localPlayerController)
				{
					int num = (int)Plugin.turretSettings[0];
					if (num <= 0)
					{
						GameNetworkManager.Instance.localPlayerController.MakeCriticallyInjured(false);
						GameNetworkManager.Instance.localPlayerController.DamagePlayer(num, false, true, (CauseOfDeath)0, 0, false, default(Vector3));
						GameNetworkManager.Instance.localPlayerController.MakeCriticallyInjured(false);
					}
					else if (GameNetworkManager.Instance.localPlayerController.health > num)
					{
						GameNetworkManager.Instance.localPlayerController.DamagePlayer(num, true, true, (CauseOfDeath)7, 0, false, default(Vector3));
					}
					else
					{
						GameNetworkManager.Instance.localPlayerController.KillPlayer(turret.aimPoint.forward * 40f, true, (CauseOfDeath)7, 0, default(Vector3));
					}
				}
				field8.SetValue(turret, (object)new Ray(turret.aimPoint.position, turret.aimPoint.forward));
				RaycastHit val = default(RaycastHit);
				if (Physics.Raycast((Ray)field8.GetValue(turret), ref val, 30f, StartOfRound.Instance.collidersAndRoomMask, (QueryTriggerInteraction)1))
				{
					field9.SetValue(turret, val);
					Transform transform = ((Component)turret.bulletCollisionAudio).transform;
					Ray val2 = (Ray)field8.GetValue(turret);
					RaycastHit val3 = (RaycastHit)field9.GetValue(turret);
					val4 = val2;
					transform.position = ((Ray)(ref val4)).GetPoint(((RaycastHit)(ref val3)).distance - 0.5f);
				}
				Vector3 forward = turret.aimPoint.forward;
				forward = Quaternion.Euler(0f, (float)(int)(0f - turret.rotationRange) / 3f, 0f) * forward;
				Plugin.AttackTargets(((Component)turret).GetComponent<FAIR_AI>(), turret.centerPoint.position, forward, 30f);
			}
			else
			{
				field6.SetValue(turret, (float)field6.GetValue(turret) + Time.deltaTime);
			}
		}
		else if ((float)field6.GetValue(turret) >= 0.21f)
		{
			field6.SetValue(turret, 0f);
			if ((Object)(object)CheckForPlayersInLOS(turret, 3f) == (Object)(object)GameNetworkManager.Instance.localPlayerController)
			{
				int @int = Plugin.GetInt("TurretConfig", "Player Damage");
				if (@int <= 0)
				{
					GameNetworkManager.Instance.localPlayerController.MakeCriticallyInjured(false);
					GameNetworkManager.Instance.localPlayerController.DamagePlayer(@int, false, true, (CauseOfDeath)0, 0, false, default(Vector3));
					GameNetworkManager.Instance.localPlayerController.MakeCriticallyInjured(false);
				}
				else if (GameNetworkManager.Instance.localPlayerController.health > 50)
				{
					GameNetworkManager.Instance.localPlayerController.DamagePlayer(@int, true, true, (CauseOfDeath)7, 0, false, default(Vector3));
				}
				else
				{
					GameNetworkManager.Instance.localPlayerController.KillPlayer(turret.aimPoint.forward * 40f, true, (CauseOfDeath)7, 0, default(Vector3));
				}
			}
			field8.SetValue(turret, (object)new Ray(turret.aimPoint.position, turret.aimPoint.forward));
			RaycastHit val5 = default(RaycastHit);
			if (Physics.Raycast((Ray)field8.GetValue(turret), ref val5, 30f, StartOfRound.Instance.collidersAndRoomMask, (QueryTriggerInteraction)1))
			{
				field9.SetValue(turret, val5);
				Transform transform2 = ((Component)turret.bulletCollisionAudio).transform;
				Ray val6 = (Ray)field8.GetValue(turret);
				RaycastHit val7 = (RaycastHit)field9.GetValue(turret);
				val4 = val6;
				transform2.position = ((Ray)(ref val4)).GetPoint(((RaycastHit)(ref val7)).distance - 0.5f);
			}
			Vector3 forward2 = turret.aimPoint.forward;
			forward2 = Quaternion.Euler(0f, (float)(int)(0f - turret.rotationRange) / 3f, 0f) * forward2;
			Plugin.AttackTargets(((Component)turret).GetComponent<FAIR_AI>(), turret.centerPoint.position, forward2, 30f);
		}
		else
		{
			field6.SetValue(turret, (float)field6.GetValue(turret) + Time.deltaTime);
		}
		if (((NetworkBehaviour)turret).IsServer)
		{
			field10.SetValue(turret, (float)field10.GetValue(turret) - Time.deltaTime);
			if ((float)field10.GetValue(turret) <= 0f)
			{
				method.Invoke(turret, new object[1] { 0 });
				turret.SetToModeClientRpc(0);
			}
		}
	}

	public static bool CheckForTargetsInLOS(ref Turret __instance, float radius = 2f, bool angleRangeCheck = false)
	{
		FAIR_AI component = ((Component)__instance).gameObject.GetComponent<FAIR_AI>();
		PlayerControllerB val = CheckForPlayersInLOS(__instance, radius, angleRangeCheck);
		EnemyAICollisionDetect val2 = CheckForEnemiesInLineOfSight(__instance, radius, angleRangeCheck);
		if ((Object)(object)val != (Object)null)
		{
			component.targets = new Dictionary<int, GameObject> { 
			{
				0,
				((Component)val).gameObject
			} };
			return true;
		}
		if ((Object)(object)val2 != (Object)null)
		{
			component.targets = new Dictionary<int, GameObject> { 
			{
				1,
				((Component)val2).gameObject
			} };
			return true;
		}
		return false;
	}

	public static PlayerControllerB CheckForPlayersInLOS(Turret turret, float radius = 2f, bool angleRangeCheck = false)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_008a: Unknown result type (might be due to invalid IL or missing references)
		//IL_008f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_0246: Unknown result type (might be due to invalid IL or missing references)
		//IL_024b: Unknown result type (might be due to invalid IL or missing references)
		//IL_024c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0251: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_019d: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a3: Invalid comparison between Unknown and I4
		//IL_010a: Unknown result type (might be due to invalid IL or missing references)
		//IL_010f: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ac: Invalid comparison between Unknown and I4
		//IL_013b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0140: Unknown result type (might be due to invalid IL or missing references)
		//IL_014a: Unknown result type (might be due to invalid IL or missing references)
		//IL_014f: Unknown result type (might be due to invalid IL or missing references)
		//IL_015a: Unknown result type (might be due to invalid IL or missing references)
		//IL_015f: Unknown result type (might be due to invalid IL or missing references)
		//IL_016a: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_021c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0226: Unknown result type (might be due to invalid IL or missing references)
		Vector3 val = turret.aimPoint.forward;
		val = Quaternion.Euler(0f, (float)(int)(0f - turret.rotationRange) / radius, 0f) * val;
		float num = turret.rotationRange / radius * 2f;
		Type typeFromHandle = typeof(Turret);
		FieldInfo field = typeFromHandle.GetField("shootRay", BindingFlags.Instance | BindingFlags.NonPublic);
		FieldInfo field2 = typeFromHandle.GetField("hit", BindingFlags.Instance | BindingFlags.NonPublic);
		FieldInfo field3 = typeFromHandle.GetField("enteringBerserkMode", BindingFlags.Instance | BindingFlags.NonPublic);
		RaycastHit val2 = default(RaycastHit);
		for (int i = 0; i <= 6; i++)
		{
			field.SetValue(turret, (object)new Ray(turret.centerPoint.position, val));
			if (Physics.Raycast((Ray)field.GetValue(turret), ref val2, 30f, 1051400, (QueryTriggerInteraction)1))
			{
				field2.SetValue(turret, val2);
				RaycastHit val3 = (RaycastHit)field2.GetValue(turret);
				if (((Component)((RaycastHit)(ref val3)).transform).CompareTag("Player"))
				{
					val3 = (RaycastHit)field2.GetValue(turret);
					PlayerControllerB component = ((Component)((RaycastHit)(ref val3)).transform).GetComponent<PlayerControllerB>();
					if (!((Object)(object)component == (Object)null))
					{
						if (angleRangeCheck && Vector3.Angle(((Component)component).transform.position + Vector3.up * 1.75f - turret.centerPoint.position, turret.forwardFacingPos.forward) > turret.rotationRange)
						{
							return null;
						}
						return component;
					}
					continue;
				}
				if ((int)turret.turretMode == 2 || ((int)turret.turretMode == 3 && !(bool)field3.GetValue(turret)))
				{
					val3 = (RaycastHit)field2.GetValue(turret);
					if (((Component)((RaycastHit)(ref val3)).transform).tag.StartsWith("PlayerRagdoll"))
					{
						val3 = (RaycastHit)field2.GetValue(turret);
						Rigidbody component2 = ((Component)((RaycastHit)(ref val3)).transform).GetComponent<Rigidbody>();
						if ((Object)(object)component2 != (Object)null)
						{
							component2.AddForce(((Vector3)(ref val)).normalized * 42f, (ForceMode)1);
						}
					}
				}
			}
			val = Quaternion.Euler(0f, num / 6f, 0f) * val;
		}
		return null;
	}

	public static EnemyAICollisionDetect CheckForEnemiesInLineOfSight(Turret turret, float radius = 2f, bool angleRangeCheck = false)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		Vector3 forward = turret.aimPoint.forward;
		forward = Quaternion.Euler(0f, (float)(int)(0f - turret.rotationRange) / 3f, 0f) * forward;
		List<EnemyAICollisionDetect> enemyTargets = Plugin.GetEnemyTargets(Plugin.GetTargets(((Component)turret).GetComponent<FAIR_AI>(), turret.aimPoint.position, forward, radius));
		if (enemyTargets == null || !enemyTargets.Any())
		{
			return null;
		}
		return enemyTargets[0];
	}

	public static bool SetTargetToEnemyBody(ref Turret __instance)
	{
		if (!((Object)(object)__instance == (Object)null))
		{
			Type typeFromHandle = typeof(Turret);
			FieldInfo field = typeFromHandle.GetField("targetingDeadPlayer", BindingFlags.Instance | BindingFlags.NonPublic);
			FAIR_AI component = ((Component)__instance).gameObject.GetComponent<FAIR_AI>();
			if ((Object)(object)component.targetWithRotation != (Object)null)
			{
				if (!((Object)(object)((Component)component.targetWithRotation).GetComponent<EnemyAICollisionDetect>() != (Object)null))
				{
					if ((Object)(object)__instance.targetPlayerWithRotation != (Object)null)
					{
						if (__instance.targetPlayerWithRotation.isPlayerDead)
						{
							if (!(bool)field.GetValue(__instance))
							{
								field.SetValue(__instance, true);
							}
							if ((Object)(object)__instance.targetPlayerWithRotation.deadBody != (Object)null)
							{
								__instance.targetTransform = ((Component)__instance.targetPlayerWithRotation.deadBody.bodyParts[5]).transform;
							}
						}
						else
						{
							field.SetValue(__instance, false);
							__instance.targetTransform = ((Component)__instance.targetPlayerWithRotation.gameplayCamera).transform;
						}
					}
					return false;
				}
				EnemyAICollisionDetect component2 = ((Component)component.targetWithRotation).GetComponent<EnemyAICollisionDetect>();
				if (component2.mainScript.isEnemyDead)
				{
					if (!(bool)field.GetValue(__instance))
					{
						field.SetValue(__instance, true);
					}
				}
				else if ((Object)(object)__instance.targetPlayerWithRotation == (Object)null)
				{
					field.SetValue(__instance, false);
					__instance.targetTransform = ((Component)component.targetWithRotation).transform;
				}
			}
			else if ((Object)(object)__instance.targetPlayerWithRotation != (Object)null)
			{
				if (__instance.targetPlayerWithRotation.isPlayerDead)
				{
					if (!(bool)field.GetValue(__instance))
					{
						field.SetValue(__instance, true);
					}
					if ((Object)(object)__instance.targetPlayerWithRotation.deadBody != (Object)null)
					{
						__instance.targetTransform = ((Component)__instance.targetPlayerWithRotation.deadBody.bodyParts[5]).transform;
					}
				}
				else
				{
					field.SetValue(__instance, false);
					__instance.targetTransform = ((Component)__instance.targetPlayerWithRotation.gameplayCamera).transform;
				}
			}
		}
		return false;
	}

	public static bool TurnTowardsTargetEnemyIfHasLOS(ref Turret __instance)
	{
		//IL_0092: Unknown result type (might be due to invalid IL or missing references)
		//IL_009e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0149: Unknown result type (might be due to invalid IL or missing references)
		//IL_0160: Unknown result type (might be due to invalid IL or missing references)
		//IL_0165: Unknown result type (might be due to invalid IL or missing references)
		//IL_016f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0174: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0205: Unknown result type (might be due to invalid IL or missing references)
		//IL_0263: Unknown result type (might be due to invalid IL or missing references)
		//IL_027a: Unknown result type (might be due to invalid IL or missing references)
		//IL_027f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0289: Unknown result type (might be due to invalid IL or missing references)
		//IL_028e: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)__instance == (Object)null))
		{
			FAIR_AI component = ((Component)__instance).GetComponent<FAIR_AI>();
			Type typeFromHandle = typeof(Turret);
			FieldInfo field = typeFromHandle.GetField("targetingDeadPlayer", BindingFlags.Instance | BindingFlags.NonPublic);
			FieldInfo field2 = typeFromHandle.GetField("hasLineOfSight", BindingFlags.Instance | BindingFlags.NonPublic);
			FieldInfo field3 = typeFromHandle.GetField("lostLOSTimer", BindingFlags.Instance | BindingFlags.NonPublic);
			bool flag = true;
			if ((Object)(object)__instance.targetTransform != (Object)null && (Object)(object)__instance.centerPoint != (Object)null && (Object)(object)__instance.forwardFacingPos != (Object)null)
			{
				Vector3 val = __instance.targetTransform.position - __instance.centerPoint.position;
				float num = Vector3.Angle(val, __instance.forwardFacingPos.forward);
				if (num > __instance.rotationRange)
				{
					flag = false;
				}
			}
			EnemyAICollisionDetect val2 = CheckForEnemiesInLineOfSight(__instance, 15f);
			if ((Object)(object)val2 == (Object)null)
			{
				flag = false;
			}
			if (flag)
			{
				__instance.targetTransform = ((Component)val2.mainScript).transform;
				field2.SetValue(__instance, true);
				field3.SetValue(__instance, 0f);
				__instance.tempTransform.position = __instance.targetTransform.position;
				Transform tempTransform = __instance.tempTransform;
				tempTransform.position -= Vector3.up * 0.15f;
				__instance.turnTowardsObjectCompass.LookAt(__instance.tempTransform);
				return false;
			}
			bool flag2 = true;
			if ((bool)field.GetValue(__instance) || Vector3.Angle(__instance.targetTransform.position - __instance.centerPoint.position, __instance.forwardFacingPos.forward) > __instance.rotationRange)
			{
				flag2 = false;
			}
			if (Physics.Linecast(__instance.aimPoint.position, __instance.targetTransform.position, StartOfRound.Instance.collidersAndRoomMask, (QueryTriggerInteraction)1))
			{
				flag2 = false;
			}
			if (flag2)
			{
				field2.SetValue(__instance, true);
				field3.SetValue(__instance, 0f);
				__instance.tempTransform.position = __instance.targetTransform.position;
				Transform tempTransform2 = __instance.tempTransform;
				tempTransform2.position -= Vector3.up * 0.15f;
				__instance.turnTowardsObjectCompass.LookAt(__instance.tempTransform);
				return false;
			}
			if ((bool)field2.GetValue(__instance))
			{
				field2.SetValue(__instance, false);
				field3.SetValue(__instance, 0f);
			}
			if (!((NetworkBehaviour)__instance).IsServer)
			{
				return false;
			}
			field3.SetValue(__instance, (float)field3.GetValue(__instance) + Time.deltaTime);
			if ((float)field3.GetValue(__instance) >= 2f)
			{
				field3.SetValue(__instance, 0f);
				Plugin.logger.LogInfo((object)"Turret: LOS timer ended on server. checking for new player target");
				PlayerControllerB val3 = CheckForPlayersInLOS(__instance);
				if ((Object)(object)val3 != (Object)null)
				{
					__instance.targetPlayerWithRotation = val3;
					__instance.SwitchTargetedPlayerClientRpc((int)val3.playerClientId, false);
					Plugin.logger.LogInfo((object)"Turret: Got new player target");
				}
				else
				{
					Plugin.logger.LogInfo((object)"Turret: No new player to target; returning to detection mode.");
					__instance.targetPlayerWithRotation = null;
					__instance.RemoveTargetedPlayerClientRpc();
				}
			}
			if ((Object)(object)__instance.targetPlayerWithRotation != (Object)null)
			{
				return false;
			}
			if ((bool)field2.GetValue(__instance))
			{
				field2.SetValue(__instance, false);
				field3.SetValue(__instance, 0f);
			}
			if (!((NetworkBehaviour)__instance).IsServer)
			{
				return false;
			}
			field3.SetValue(__instance, (float)field3.GetValue(__instance) + Time.deltaTime);
			if ((float)field3.GetValue(__instance) >= 2f)
			{
				field3.SetValue(__instance, 0f);
				Plugin.logger.LogInfo((object)"Turret: LOS timer ended on server. checking for new enemy target");
				EnemyAICollisionDetect val4 = CheckForEnemiesInLineOfSight(__instance, 15f);
				if ((Object)(object)val4 != (Object)null)
				{
					component.targetWithRotation = val4.mainScript;
					component.SwitchedTargetedEnemyClientRpc(__instance, val4.mainScript);
					Plugin.logger.LogInfo((object)"Turret: Got new enemy target");
				}
				else
				{
					Plugin.logger.LogInfo((object)"Turret: No new enemy to target; returning to detection mode.");
					component.targetWithRotation = null;
					component.RemoveTargetedEnemyClientRpc();
				}
			}
		}
		return false;
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}
namespace FairAI
{
	public class FAIR_AI : NetworkBehaviour
	{
		public EnemyAI targetWithRotation;

		public Dictionary<int, GameObject> targets;

		private void Awake()
		{
			targetWithRotation = null;
		}

		[ClientRpc]
		public void SwitchedTargetedEnemyClientRpc(Turret turret, EnemyAI enemy, bool setModeToCharging = false)
		{
			targetWithRotation = enemy;
			if (setModeToCharging)
			{
				Type typeFromHandle = typeof(Turret);
				MethodInfo method = typeFromHandle.GetMethod("SwitchTurretMode", BindingFlags.Instance | BindingFlags.NonPublic);
				method.Invoke(turret, new object[1] { 2 });
			}
		}

		[ClientRpc]
		public void RemoveTargetedEnemyClientRpc()
		{
			targetWithRotation = null;
		}
	}
	[BepInPlugin("GoldenKitten.FairAI", "Fair AI", "1.5.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		private const string modGUID = "GoldenKitten.FairAI";

		private const string modName = "Fair AI";

		private const string modVersion = "1.5.1";

		private Harmony harmony = new Harmony("GoldenKitten.FairAI");

		public static Plugin Instance;

		public static ManualLogSource logger;

		public static List<EnemyType> enemies;

		public static List<Item> items;

		public static List<EnemyType> enemyList;

		public static List<Item> itemList;

		public static List<float> turretSettings;

		public static Dictionary<string, float[]> speeds;

		public static Dictionary<int, Vector3> positions;

		public static Dictionary<int, float> sinkingValues;

		public static Assembly surfacedAssembly;

		public static Assembly turretSettingsAssembly;

		public static PropertyInfo tsBoundConfig;

		public const string ltModID = "evaisa.lethalthings";

		public const string surfacedModID = "Surfaced";

		public static bool playersEnteredInside = false;

		public static bool surfacedEnabled = false;

		public static bool lethalThingsEnabled = false;

		public static bool turretSettingsEnabled = false;

		public static bool lethalConfigEnabled = false;

		public static bool roundHasStarted = false;

		public static int wallsAndEnemyLayerMask = 524288;

		public static int enemyMask = 524288;

		public static int allHittablesMask;

		private static float onMeshThreshold = 3f;

		private async void Awake()
		{
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
			}
			enemies = new List<EnemyType>();
			items = new List<Item>();
			itemList = new List<Item>();
			enemyList = new List<EnemyType>();
			speeds = new Dictionary<string, float[]>();
			positions = new Dictionary<int, Vector3>();
			turretSettings = new List<float>();
			sinkingValues = new Dictionary<int, float>();
			surfacedAssembly = null;
			harmony = new Harmony("GoldenKitten.FairAI");
			logger = Logger.CreateLogSource("GoldenKitten.FairAI");
			harmony.PatchAll(typeof(Plugin));
			CreateHarmonyPatch(harmony, typeof(RoundManager), "Start", null, typeof(RoundManagerPatch), "PatchStart", isPrefix: false);
			CreateHarmonyPatch(harmony, typeof(StartOfRound), "Start", null, typeof(StartOfRoundPatch), "PatchStart", isPrefix: false);
			CreateHarmonyPatch(harmony, typeof(StartOfRound), "Update", null, typeof(StartOfRoundPatch), "PatchUpdate", isPrefix: false);
			CreateHarmonyPatch(harmony, typeof(QuicksandTrigger), "OnTriggerStay", new Type[1] { typeof(Collider) }, typeof(QuickSandPatch), "OnTriggerStayPatch", isPrefix: true);
			CreateHarmonyPatch(harmony, typeof(QuicksandTrigger), "OnTriggerExit", new Type[1] { typeof(Collider) }, typeof(QuickSandPatch), "OnTriggerExitPatch", isPrefix: true);
			CreateHarmonyPatch(harmony, typeof(Turret), "Update", null, typeof(TurretAIPatch), "PatchUpdate", isPrefix: true);
			CreateHarmonyPatch(harmony, typeof(Turret), "CheckForPlayersInLineOfSight", new Type[2]
			{
				typeof(float),
				typeof(bool)
			}, typeof(TurretAIPatch), "CheckForTargetsInLOS", isPrefix: true);
			CreateHarmonyPatch(harmony, typeof(Turret), "SetTargetToPlayerBody", null, typeof(TurretAIPatch), "SetTargetToEnemyBody", isPrefix: true);
			CreateHarmonyPatch(harmony, typeof(Turret), "TurnTowardsTargetIfHasLOS", null, typeof(TurretAIPatch), "TurnTowardsTargetEnemyIfHasLOS", isPrefix: true);
			CreateHarmonyPatch(harmony, typeof(Landmine), "SpawnExplosion", new Type[8]
			{
				typeof(Vector3),
				typeof(bool),
				typeof(float),
				typeof(float),
				typeof(int),
				typeof(float),
				typeof(GameObject),
				typeof(bool)
			}, typeof(MineAIPatch), "PatchSpawnExplosion", isPrefix: false);
			CreateHarmonyPatch(harmony, typeof(Landmine), "OnTriggerEnter", null, typeof(MineAIPatch), "PatchOnTriggerEnter", isPrefix: false);
			CreateHarmonyPatch(harmony, typeof(Landmine), "OnTriggerExit", null, typeof(MineAIPatch), "PatchOnTriggerExit", isPrefix: false);
			CreateHarmonyPatch(harmony, typeof(Landmine), "Detonate", null, typeof(MineAIPatch), "DetonatePatch", isPrefix: false);
			await WaitForProcess(1);
			GetTurretSettings();
			logger.LogInfo((object)"Fair AI initiated!");
		}

		public static void ImmortalAffected()
		{
			if (!GetBool("General", "ImmortalAffected"))
			{
				enemies = (from EnemyType e in Resources.FindObjectsOfTypeAll(typeof(EnemyType))
					where (Object)(object)e != (Object)null && e.canDie
					select e).ToList();
			}
		}

		public static float[] SpeedAndAccelerationEnemyList(EnemyAICollisionDetect enemy)
		{
			if ((Object)(object)enemy != (Object)null)
			{
				EnemyAI mainScript = enemy.mainScript;
				if ((Object)(object)enemy.mainScript != (Object)null)
				{
					EnemyType enemyType = mainScript.enemyType;
					string enemyName = enemyType.enemyName;
					if ((Object)(object)enemyType != (Object)null)
					{
						if (GetSpeeds(enemy) == null)
						{
							NavMeshAgent componentInChildren = ((Component)mainScript).GetComponentInChildren<NavMeshAgent>();
							if ((Object)(object)componentInChildren != (Object)null)
							{
								speeds.Add(enemyType.enemyName, new float[2] { componentInChildren.speed, componentInChildren.acceleration });
								return speeds[enemyType.enemyName];
							}
							speeds.Add(enemyType.enemyName, new float[2] { 1f, 1f });
							return speeds[enemyType.enemyName];
						}
						return speeds[enemyType.enemyName];
					}
				}
				else
				{
					logger.LogWarning((object)"No EnemyAI To Get Speeds!");
				}
			}
			else
			{
				logger.LogWarning((object)"No EnemyCollision To Get Speeds!");
			}
			return new float[2] { 1f, 1f };
		}

		public static float[] GetSpeeds(EnemyAICollisionDetect enemy)
		{
			EnemyType enemyType = enemy.mainScript.enemyType;
			if (speeds.TryGetValue(enemyType.enemyName, out var value))
			{
				return value;
			}
			logger.LogWarning((object)("Speeds missing on: " + enemyType.enemyName));
			return null;
		}

		public static void GetTurretSettings()
		{
			if (turretSettingsEnabled)
			{
				object value = tsBoundConfig.GetValue(null);
				Type type = null;
				if (value != null)
				{
					type = value.GetType();
					if (type == null)
					{
						logger.LogInfo((object)"Bound Config Type not gotten!");
					}
				}
				else
				{
					logger.LogInfo((object)"Unable to get BoundConfig");
				}
				FieldInfo field = type.GetField("turretDamage", BindingFlags.Instance | BindingFlags.Public);
				if (field != null)
				{
					object value2 = field.GetValue(value);
					float item = (int)(value2?.GetType().GetProperty("Value"))?.GetValue(value2);
					turretSettings.Add(item);
				}
				FieldInfo field2 = type.GetField("turretFireRate", BindingFlags.Instance | BindingFlags.Public);
				if (field2 != null)
				{
					object value3 = field2.GetValue(value);
					float item2 = (float)(value3?.GetType().GetProperty("Value"))?.GetValue(value3);
					turretSettings.Add(item2);
				}
				FieldInfo field3 = type.GetField("turretWarmupTime", BindingFlags.Instance | BindingFlags.Public);
				if (field3 != null)
				{
					object value4 = field3.GetValue(value);
					float item3 = (float)(value4?.GetType().GetProperty("Value"))?.GetValue(value4);
					turretSettings.Add(item3);
				}
				FieldInfo field4 = type.GetField("turretRotateTimer", BindingFlags.Instance | BindingFlags.Public);
				if (field4 != null)
				{
					object value5 = field4.GetValue(value);
					float item4 = (float)(value5?.GetType().GetProperty("Value"))?.GetValue(value5);
					turretSettings.Add(item4);
				}
				FieldInfo field5 = type.GetField("turretRotationRange", BindingFlags.Instance | BindingFlags.Public);
				if (field5 != null)
				{
					object value6 = field5.GetValue(value);
					float item5 = (float)(value6?.GetType().GetProperty("Value"))?.GetValue(value6);
					turretSettings.Add(item5);
				}
				FieldInfo field6 = type.GetField("turretIdleRotationSpeed", BindingFlags.Instance | BindingFlags.Public);
				if (field6 != null)
				{
					object value7 = field6.GetValue(value);
					float item6 = (float)(value7?.GetType().GetProperty("Value"))?.GetValue(value7);
					turretSettings.Add(item6);
				}
				FieldInfo field7 = type.GetField("turretFiringRotationSpeed", BindingFlags.Instance | BindingFlags.Public);
				if (field7 != null)
				{
					object value8 = field7.GetValue(value);
					float item7 = (float)(value8?.GetType().GetProperty("Value"))?.GetValue(value8);
					turretSettings.Add(item7);
				}
				FieldInfo field8 = type.GetField("turretBerzerkRotationSpeed", BindingFlags.Instance | BindingFlags.Public);
				if (field8 != null)
				{
					object value9 = field8.GetValue(value);
					float item8 = (float)(value9?.GetType().GetProperty("Value"))?.GetValue(value9);
					turretSettings.Add(item8);
				}
				logger.LogInfo((object)("Got Turret Settings: " + turretSettings.Count));
			}
			else
			{
				turretSettings = new List<float>();
			}
		}

		public static async Task<IEnumerable<int>> WaitForProcess(int waitTime)
		{
			await Task.Delay(waitTime);
			bool done = false;
			while (!done)
			{
				await Instance.DelayedInitialization();
				done = true;
			}
			return new List<int>();
		}

		private async Task DelayedInitialization()
		{
			await Task.Run(delegate
			{
				TryLoadLethalThings();
				TryLoadSurfaced();
				TryLoadTurretSettings();
				TryLoadLethalConfig();
				logger.LogInfo((object)"Optional Components initiated!");
			});
		}

		private void TryLoadLethalThings()
		{
			try
			{
				Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
				Assembly assembly = null;
				Assembly[] array = assemblies;
				foreach (Assembly assembly2 in array)
				{
					if (assembly2.GetName().Name == "LethalThings")
					{
						assembly = assembly2;
						break;
					}
				}
				if (assembly != null)
				{
					Type type = assembly.GetType("LethalThings.RoombaAI");
					if (type != null && BoombaPatch.enabled)
					{
						CreateHarmonyPatch(harmony, type, "Start", null, typeof(BoombaPatch), "PatchStart", isPrefix: false);
						CreateHarmonyPatch(harmony, type, "DoAIInterval", null, typeof(BoombaPatch), "PatchDoAIInterval", isPrefix: false);
						lethalThingsEnabled = true;
						logger.LogInfo((object)"LethalThings Component Initiated!");
					}
				}
				else
				{
					logger.LogWarning((object)"LethalThings assembly not found. Skipping optional patch.");
				}
			}
			catch (Exception ex)
			{
				logger.LogError((object)("An error occurred while trying to apply patches for LethalThings: " + ex.Message));
			}
		}

		private void TryLoadSurfaced()
		{
			try
			{
				Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
				Assembly[] array = assemblies;
				foreach (Assembly assembly in array)
				{
					if (assembly.GetName().Name == "Surfaced")
					{
						surfacedAssembly = assembly;
						break;
					}
				}
				if (surfacedAssembly != null)
				{
					Type type = surfacedAssembly.GetType("Seamine");
					Type type2 = surfacedAssembly.GetType("Bertha");
					if (type != null)
					{
						if (SurfacedMinePatch.enabled)
						{
							CreateHarmonyPatch(harmony, type, "OnTriggerEnter", new Type[1] { typeof(Collider) }, typeof(SurfacedMinePatch), "PatchOnTriggerEnter", isPrefix: false);
							surfacedEnabled = true;
							logger.LogInfo((object)"Surfaced Component Seamine Initiated!");
						}
					}
					else
					{
						logger.LogInfo((object)"Surfaced Component Seamine Not Found!");
					}
					if (type2 != null)
					{
						if (SurfacedMinePatch.enabled)
						{
							CreateHarmonyPatch(harmony, type2, "OnTriggerEnter", new Type[1] { typeof(Collider) }, typeof(SurfacedMinePatch), "PatchBerthaOnTriggerEnter", isPrefix: false);
							surfacedEnabled = true;
							logger.LogInfo((object)"Surfaced Component Bertha Initiated!");
						}
					}
					else
					{
						logger.LogInfo((object)"Surfaced Component Bertha Not Found!");
					}
				}
				else
				{
					logger.LogWarning((object)"Surfaced assembly not found. Skipping optional patch.");
				}
			}
			catch (Exception ex)
			{
				logger.LogError((object)("An error occurred while trying to apply patches for Surfaced: " + ex.Message));
			}
		}

		private void TryLoadTurretSettings()
		{
			try
			{
				Assembly assembly = Assembly.Load("TheNameIsTyler.TurretSettings");
				if (assembly != null)
				{
					turretSettingsAssembly = assembly;
					Type type = turretSettingsAssembly.GetType("TurretSettings.TurretSettings");
					if (type != null)
					{
						PropertyInfo property = type.GetProperty("BoundConfig", BindingFlags.Static | BindingFlags.NonPublic);
						if (property != null)
						{
							tsBoundConfig = property;
							turretSettingsEnabled = true;
							logger.LogInfo((object)"TurretSettings Component Initiated!");
						}
						else
						{
							logger.LogWarning((object)"TurretSettings config not found. Skipping optional patch.");
						}
					}
					else
					{
						logger.LogWarning((object)"TurretSettings type not found. Skipping optional patch.");
					}
				}
				else
				{
					logger.LogWarning((object)"TurretSettings assembly not found. Skipping optional patch.");
				}
			}
			catch (Exception ex)
			{
				logger.LogError((object)("An error occurred while trying to apply patches for TurretSettings: " + ex.Message));
			}
		}

		private void TryLoadLethalConfig()
		{
			try
			{
				Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
				Assembly assembly = null;
				Assembly[] array = assemblies;
				foreach (Assembly assembly2 in array)
				{
					if (assembly2.GetName().Name == "LethalConfig")
					{
						assembly = assembly2;
						break;
					}
				}
				if (assembly != null)
				{
					Type type = assembly.GetType("LethalConfig.LethalConfigManager");
					if (type != null)
					{
						lethalConfigEnabled = true;
						logger.LogInfo((object)"LethalConfig Component Initiated!");
					}
				}
				else
				{
					logger.LogWarning((object)"LethalConfig assembly not found. Skipping optional patch.");
				}
			}
			catch (Exception ex)
			{
				logger.LogError((object)("An error occurred while trying to apply patches for LethalConfig: " + ex.Message));
			}
		}

		public static List<PlayerControllerB> GetActivePlayers()
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
			List<PlayerControllerB> list = new List<PlayerControllerB>();
			PlayerControllerB[] array = allPlayerScripts;
			foreach (PlayerControllerB val in array)
			{
				if ((Object)val != (Object)null && !val.isPlayerDead && ((Behaviour)val).isActiveAndEnabled && val.isPlayerControlled)
				{
					list.Add(val);
				}
			}
			return list;
		}

		public static bool AllowFairness(Vector3 position)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)StartOfRound.Instance != (Object)null && Can("CheckForPlayersInside") && StartOfRound.Instance.shipHasLanded)
			{
				if (IsAPlayersOutside())
				{
					if (!(position.y > -80f))
					{
						Bounds bounds = StartOfRound.Instance.shipInnerRoomBounds.bounds;
						if (!((Bounds)(ref bounds)).Contains(position))
						{
							goto IL_006c;
						}
					}
					return true;
				}
				goto IL_006c;
			}
			return true;
			IL_006c:
			return playersEnteredInside;
		}

		public static bool IsAPlayersOutside()
		{
			if (StartOfRound.Instance.shipHasLanded)
			{
				List<PlayerControllerB> activePlayers = GetActivePlayers();
				for (int i = 0; i < activePlayers.Count; i++)
				{
					PlayerControllerB val = activePlayers[i];
					if (!val.isInsideFactory)
					{
						return true;
					}
				}
			}
			return false;
		}

		public static bool IsAPlayerInsideShip()
		{
			if (StartOfRound.Instance.shipHasLanded)
			{
				List<PlayerControllerB> activePlayers = GetActivePlayers();
				for (int i = 0; i < activePlayers.Count; i++)
				{
					PlayerControllerB val = activePlayers[i];
					if (val.isInHangarShipRoom)
					{
						return true;
					}
				}
			}
			return false;
		}

		public static bool IsAPlayerInsideDungeon()
		{
			if (StartOfRound.Instance.shipHasLanded)
			{
				List<PlayerControllerB> activePlayers = GetActivePlayers();
				for (int i = 0; i < activePlayers.Count; i++)
				{
					PlayerControllerB val = activePlayers[i];
					if (val.isInsideFactory)
					{
						return true;
					}
				}
			}
			return false;
		}

		public static bool CanMob(string parentIdentifier, string identifier, string mobName)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			string text = RemoveInvalidCharacters(mobName).ToUpper();
			if (((BaseUnityPlugin)Instance).Config[new ConfigDefinition("Mobs", parentIdentifier)].BoxedValue.ToString().ToUpper().Equals("TRUE"))
			{
				foreach (ConfigDefinition key in ((BaseUnityPlugin)Instance).Config.Keys)
				{
					if (RemoveInvalidCharacters(key.Key.ToUpper()).Equals(RemoveInvalidCharacters(text + identifier).ToUpper()))
					{
						return ((BaseUnityPlugin)Instance).Config[key].BoxedValue.ToString().ToUpper().Equals("TRUE");
					}
				}
				return false;
			}
			return false;
		}

		public static bool Can(string identifier)
		{
			foreach (ConfigDefinition key in ((BaseUnityPlugin)Instance).Config.Keys)
			{
				if (RemoveInvalidCharacters(key.Key.ToUpper()).Equals(RemoveInvalidCharacters(identifier.ToUpper())))
				{
					return ((BaseUnityPlugin)Instance).Config[key].BoxedValue.ToString().ToUpper().Equals("TRUE");
				}
			}
			return false;
		}

		public static int GetInt(string parentIdentifier, string identifier)
		{
			try
			{
				int.TryParse(((BaseUnityPlugin)Instance).Config[parentIdentifier, identifier].BoxedValue.ToString(), out var result);
				return result;
			}
			catch
			{
				return 1;
			}
		}

		public static float GetFloat(string parentIdentifier, string identifier)
		{
			try
			{
				float.TryParse(((BaseUnityPlugin)Instance).Config[parentIdentifier, identifier].BoxedValue.ToString(), out var result);
				return result;
			}
			catch
			{
				return 1f;
			}
		}

		public static bool GetBool(string parentIdentifier, string identifier)
		{
			string text = RemoveInvalidCharacters(((BaseUnityPlugin)Instance).Config[parentIdentifier, identifier].BoxedValue.ToString()).ToUpper();
			if (text.Equals("TRUE"))
			{
				return true;
			}
			return false;
		}

		public static string RemoveWhitespaces(string source)
		{
			return string.Join("", source.Split((string[]?)null, StringSplitOptions.RemoveEmptyEntries));
		}

		public static string RemoveSpecialCharacters(string source)
		{
			StringBuilder stringBuilder = new StringBuilder();
			foreach (char c in source)
			{
				if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'))
				{
					stringBuilder.Append(c);
				}
			}
			return stringBuilder.ToString();
		}

		public static string RemoveInvalidCharacters(string source)
		{
			return RemoveWhitespaces(RemoveSpecialCharacters(source));
		}

		public static Type FindType(string fullName)
		{
			try
			{
				if ((from a in AppDomain.CurrentDomain.GetAssemblies()
					where !a.IsDynamic
					select a).SelectMany((Assembly a) => a.GetTypes()).FirstOrDefault((Type t) => t.FullName.Equals(fullName)) != null)
				{
					return (from a in AppDomain.CurrentDomain.GetAssemblies()
						where !a.IsDynamic
						select a).SelectMany((Assembly a) => a.GetTypes()).FirstOrDefault((Type t) => t.FullName.Equals(fullName));
				}
			}
			catch
			{
				return null;
			}
			return null;
		}

		public static void CreateHarmonyPatch(Harmony harmony, Type typeToPatch, string methodToPatch, Type[] parameters, Type patchType, string patchMethod, bool isPrefix, bool isTranspiler = false)
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Expected O, but got Unknown
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Expected O, but got Unknown
			if (typeToPatch == null || patchType == null)
			{
				logger.LogInfo((object)"Type is either incorrect or does not exist!");
				return;
			}
			MethodInfo methodInfo = AccessTools.Method(typeToPatch, methodToPatch, parameters, (Type[])null);
			MethodInfo methodInfo2 = AccessTools.Method(patchType, patchMethod, (Type[])null, (Type[])null);
			if (isTranspiler)
			{
				harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null);
			}
			else if (isPrefix)
			{
				harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			else
			{
				harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
		}

		public static bool IsAgentOnNavMesh(GameObject agentObject)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = agentObject.transform.position;
			NavMeshHit val = default(NavMeshHit);
			if (NavMesh.SamplePosition(position, ref val, onMeshThreshold, -1) && Mathf.Approximately(position.x, ((NavMeshHit)(ref val)).position.x) && Mathf.Approximately(position.z, ((NavMeshHit)(ref val)).position.z))
			{
				return position.y >= ((NavMeshHit)(ref val)).position.y;
			}
			return false;
		}

		public static bool AttackTargets(FAIR_AI turret_ai, Vector3 aimPoint, Vector3 forward, float range)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			return HitTargets(GetTargets(turret_ai, aimPoint, forward, range), forward);
		}

		public static List<GameObject> GetTargets(FAIR_AI turret_ai, Vector3 aimPoint, Vector3 forward, float range)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			List<GameObject> list = new List<GameObject>();
			Ray val = default(Ray);
			((Ray)(ref val))..ctor(aimPoint, forward);
			RaycastHit[] array = Physics.RaycastAll(val, range, -5, (QueryTriggerInteraction)2);
			Array.Sort(array, (RaycastHit x, RaycastHit y) => ((RaycastHit)(ref x)).distance.CompareTo(((RaycastHit)(ref y)).distance));
			Vector3 val2 = aimPoint + forward * range;
			IHittable val3 = default(IHittable);
			EnemyAI val6 = default(EnemyAI);
			for (int i = 0; i < array.Length; i++)
			{
				GameObject gameObject = ((Component)((RaycastHit)(ref array[i])).transform).gameObject;
				Transform transform = ((RaycastHit)(ref array[i])).transform;
				if (((Component)transform).TryGetComponent<IHittable>(ref val3))
				{
					EnemyAI val4 = null;
					EnemyAICollisionDetect val5 = (EnemyAICollisionDetect)(object)((val3 is EnemyAICollisionDetect) ? val3 : null);
					if (val5 != null)
					{
						val4 = val5.mainScript;
					}
					if ((Object)(object)val4 != (Object)null && !val4.isEnemyDead && val4.enemyHP > 0)
					{
						list.Add(((Component)transform).gameObject);
					}
					if (!(val3 is EnemyAICollisionDetect) && !(val3 is PlayerControllerB) && !(val3 is SandSpiderWebTrap))
					{
						if (!(val3 is Turret))
						{
							val3.Hit(1, val2, (PlayerControllerB)null, false, -1);
						}
						else if (GetBool("TurretConfig", "HitOtherTurrets"))
						{
							val3.Hit(1, val2, (PlayerControllerB)null, false, -1);
						}
					}
					val2 = ((RaycastHit)(ref array[i])).point;
				}
				else
				{
					if (((Component)transform).TryGetComponent<EnemyAI>(ref val6) && !val6.isEnemyDead && val6.enemyHP > 0)
					{
						list.Add(((Component)val6).gameObject);
						val2 = ((RaycastHit)(ref array[i])).point;
					}
					val2 = ((RaycastHit)(ref array[i])).point;
				}
			}
			return list;
		}

		public static List<EnemyAICollisionDetect> GetEnemyTargets(List<GameObject> originalTargets)
		{
			List<EnemyAICollisionDetect> hits = new List<EnemyAICollisionDetect>();
			originalTargets.ForEach(delegate(GameObject t)
			{
				//IL_0031: Unknown result type (might be due to invalid IL or missing references)
				//IL_0038: Expected O, but got Unknown
				if ((Object)(object)t != (Object)null && t.GetComponent<IHittable>() != null)
				{
					IHittable component = t.GetComponent<IHittable>();
					if (component is EnemyAICollisionDetect)
					{
						EnemyAICollisionDetect item = (EnemyAICollisionDetect)component;
						hits.Add(item);
					}
				}
			});
			return hits;
		}

		public static bool HitTargets(List<GameObject> targets, Vector3 forward)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			bool hits = false;
			if (!targets.Any())
			{
				return hits;
			}
			targets.ForEach(delegate(GameObject t)
			{
				//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
				//IL_00fe: Expected O, but got Unknown
				//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
				//IL_006d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0085: Unknown result type (might be due to invalid IL or missing references)
				//IL_008b: Unknown result type (might be due to invalid IL or missing references)
				//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
				//IL_019a: Unknown result type (might be due to invalid IL or missing references)
				//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
				//IL_0153: Unknown result type (might be due to invalid IL or missing references)
				//IL_0217: Unknown result type (might be due to invalid IL or missing references)
				//IL_0172: Unknown result type (might be due to invalid IL or missing references)
				//IL_0178: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)t != (Object)null)
				{
					if ((Object)(object)t.GetComponent<EnemyAI>() != (Object)null)
					{
						EnemyAI component = t.GetComponent<EnemyAI>();
						int @int = GetInt("TurretConfig", "Enemy Damage");
						if (CanMob("TurretDamageAllMobs", ".Turret Damage", component.enemyType.enemyName))
						{
							if (component is NutcrackerEnemyAI)
							{
								if (((EnemyAI)(NutcrackerEnemyAI)component).currentBehaviourStateIndex > 0)
								{
									component.HitEnemyOnLocalClient(@int, default(Vector3), (PlayerControllerB)null, false, -1);
									hits = true;
								}
							}
							else
							{
								component.HitEnemyOnLocalClient(@int, default(Vector3), (PlayerControllerB)null, false, -1);
								hits = true;
							}
						}
					}
					else if (t.GetComponent<IHittable>() != null)
					{
						IHittable component2 = t.GetComponent<IHittable>();
						if (component2 is EnemyAICollisionDetect)
						{
							EnemyAICollisionDetect val = (EnemyAICollisionDetect)component2;
							int int2 = GetInt("TurretConfig", "Enemy Damage");
							if (CanMob("TurretDamageAllMobs", ".Turret Damage", val.mainScript.enemyType.enemyName))
							{
								if (val.mainScript is NutcrackerEnemyAI)
								{
									if (((EnemyAI)(NutcrackerEnemyAI)val.mainScript).currentBehaviourStateIndex > 0)
									{
										val.mainScript.HitEnemyOnLocalClient(int2, default(Vector3), (PlayerControllerB)null, false, -1);
										hits = true;
									}
								}
								else
								{
									val.mainScript.HitEnemyOnLocalClient(int2, default(Vector3), (PlayerControllerB)null, false, -1);
									hits = true;
								}
							}
						}
						else if (!(component2 is PlayerControllerB))
						{
							if (!(component2 is Turret))
							{
								component2.Hit(1, forward, (PlayerControllerB)null, true, -1);
								hits = true;
							}
							else if (GetBool("TurretConfig", "HitOtherTurrets"))
							{
								component2.Hit(1, forward, (PlayerControllerB)null, true, -1);
								hits = true;
							}
						}
					}
				}
			});
			return hits;
		}
	}
}
namespace FairAI.Patches
{
	public static class BoombaPatch
	{
		private static bool? _enabled;

		public static bool enabled
		{
			get
			{
				if (!_enabled.HasValue)
				{
					_enabled = Chainloader.PluginInfos.ContainsKey("evaisa.lethalthings");
				}
				return _enabled.Value;
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static void PatchStart(ref RoombaAI __instance)
		{
			((Component)__instance).gameObject.AddComponent<BoombaTimer>();
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static void PatchDoAIInterval(ref RoombaAI __instance)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_021e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0224: Unknown result type (might be due to invalid IL or missing references)
			if (!Plugin.AllowFairness(((Component)__instance).transform.position) || !Plugin.IsAgentOnNavMesh(((Component)__instance).gameObject) || (((EnemyAI)__instance).currentSearch == null && !((EnemyAI)__instance).movingTowardsTargetPlayer) || (!__instance.mineAudio.isPlaying && !__instance.mineFarAudio.isPlaying) || !((Component)__instance).GetComponent<BoombaTimer>().IsActiveBomb())
			{
				return;
			}
			Vector3 val = ((Component)__instance).transform.position + Vector3.up;
			Collider[] array = Physics.OverlapSphere(val, 6f, 2621448, (QueryTriggerInteraction)2);
			for (int i = 0; i < array.Length; i++)
			{
				float num = Vector3.Distance(val, ((Component)array[i]).transform.position);
				if ((num > 4f && Physics.Linecast(val, ((Component)array[i]).transform.position + Vector3.up * 0.3f, 256, (QueryTriggerInteraction)1)) || !((Object)(object)((Component)array[i]).gameObject.GetComponent<EnemyAICollisionDetect>() != (Object)null))
				{
					continue;
				}
				EnemyAICollisionDetect component = ((Component)array[i]).gameObject.GetComponent<EnemyAICollisionDetect>();
				if (!((Object)(object)((Component)component.mainScript).gameObject != (Object)(object)((Component)__instance).gameObject) || !Plugin.CanMob("BoombaAllMobs", ".Boomba", component.mainScript.enemyType.enemyName))
				{
					continue;
				}
				if ((Object)(object)component != (Object)null && ((NetworkBehaviour)component.mainScript).IsOwner && !component.mainScript.isEnemyDead)
				{
					Object.Instantiate<GameObject>(StartOfRound.Instance.explosionPrefab, val, Quaternion.Euler(-90f, 0f, 0f), RoundManager.Instance.mapPropsContainer.transform).SetActive(true);
					if (num < 3f)
					{
						component.mainScript.KillEnemyOnOwnerClient(true);
					}
					else if (num < 6f)
					{
						component.mainScript.HitEnemyOnLocalClient(2, default(Vector3), (PlayerControllerB)null, false, -1);
					}
				}
				if (((NetworkBehaviour)__instance).IsServer)
				{
					((EnemyAI)__instance).KillEnemy(true);
				}
				else
				{
					((EnemyAI)__instance).KillEnemyServerRpc(true);
				}
			}
		}
	}
	internal class EnemyAIPatch
	{
	}
	internal class MineAIPatch
	{
		[CompilerGenerated]
		private sealed class <WaitForUpdate>d__3 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public float waitTime;

			public Landmine mine;

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

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

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

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

			private bool MoveNext()
			{
				//IL_0027: Unknown result type (might be due to invalid IL or missing references)
				//IL_0031: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(waitTime);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					if (!((Object)(object)mine == (Object)null))
					{
						if ((Object)(object)((Component)mine).GetComponent<NetworkObject>() != (Object)null)
						{
							((Component)mine).GetComponent<NetworkObject>().Despawn(true);
						}
						else
						{
							Object.Destroy((Object)(object)((Component)mine).gameObject);
						}
					}
					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();
			}
		}

		public static void PatchOnTriggerEnter(ref Landmine __instance, Collider other, ref float ___pressMineDebounceTimer)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			if (Plugin.AllowFairness(((Component)__instance).transform.position))
			{
				EnemyAICollisionDetect component = ((Component)other).gameObject.GetComponent<EnemyAICollisionDetect>();
				if ((Object)(object)component != (Object)null && !component.mainScript.isEnemyDead && Plugin.CanMob("ExplodeAllMobs", ".Mine", component.mainScript.enemyType.enemyName.ToUpper()))
				{
					___pressMineDebounceTimer = 0.5f;
					__instance.PressMineServerRpc();
				}
			}
		}

		public static void PatchOnTriggerExit(ref Landmine __instance, Collider other, ref bool ___sendingExplosionRPC)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			if (Plugin.AllowFairness(((Component)__instance).transform.position))
			{
				EnemyAICollisionDetect component = ((Component)other).gameObject.GetComponent<EnemyAICollisionDetect>();
				if ((Object)(object)component != (Object)null && !component.mainScript.isEnemyDead && Plugin.CanMob("ExplodeAllMobs", ".Mine", component.mainScript.enemyType.enemyName.ToUpper()) && !__instance.hasExploded)
				{
					__instance.SetOffMineAnimation();
					___sendingExplosionRPC = true;
					__instance.ExplodeMineServerRpc();
				}
			}
		}

		public static void DetonatePatch(ref Landmine __instance)
		{
			if (!((Object)(object)__instance == (Object)null))
			{
				((MonoBehaviour)__instance).StartCoroutine(WaitForUpdate(1.5f, __instance));
			}
		}

		[IteratorStateMachine(typeof(<WaitForUpdate>d__3))]
		public static IEnumerator WaitForUpdate(float waitTime, Landmine mine)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <WaitForUpdate>d__3(0)
			{
				waitTime = waitTime,
				mine = mine
			};
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static void PatchSpawnExplosion(Vector3 explosionPosition, bool spawnExplosionEffect = false, float killRange = 1f, float damageRange = 1f, int nonLethalDamage = 50, float physicsForce = 0f, GameObject overridePrefab = null, bool goThroughCar = false)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			bool flag = true;
			Collider[] array = Physics.OverlapSphere(explosionPosition, 6f, 2621448, (QueryTriggerInteraction)2);
			for (int i = 0; i < array.Length; i++)
			{
				float num = Vector3.Distance(explosionPosition, ((Component)array[i]).transform.position);
				if (num > 4f && Physics.Linecast(explosionPosition, ((Component)array[i]).transform.position + Vector3.up * 0.3f, 256, (QueryTriggerInteraction)1))
				{
					continue;
				}
				if (Plugin.surfacedEnabled && Plugin.surfacedAssembly != null)
				{
					Type type = Plugin.surfacedAssembly.GetType("Seamine");
					if (type != null && (Object)(object)((Component)array[i]).gameObject.GetComponent(type) != (Object)null)
					{
						Component component = ((Component)array[i]).gameObject.GetComponent(type);
						FieldInfo field = type.GetField("mineActivated", BindingFlags.Instance | BindingFlags.NonPublic);
						FieldInfo field2 = type.GetField("hasExploded", BindingFlags.Instance | BindingFlags.Public);
						if (!(bool)field2.GetValue(component) || !(bool)field.GetValue(component))
						{
							break;
						}
						if (Plugin.AllowFairness(component.transform.position))
						{
							MethodInfo method = type.GetMethod("TriggerMineOnLocalClientByExiting", BindingFlags.Instance | BindingFlags.NonPublic);
							method.Invoke(component, new object[0]);
						}
					}
				}
				if (!((Object)(object)((Component)array[i]).gameObject.GetComponent<EnemyAICollisionDetect>() != (Object)null))
				{
					continue;
				}
				EnemyAICollisionDetect component2 = ((Component)array[i]).gameObject.GetComponent<EnemyAICollisionDetect>();
				if ((Object)(object)component2 != (Object)null && ((NetworkBehaviour)component2.mainScript).IsOwner && !component2.mainScript.isEnemyDead)
				{
					if (num < killRange)
					{
						component2.mainScript.HitEnemyOnLocalClient(component2.mainScript.enemyHP, default(Vector3), (PlayerControllerB)null, false, -1);
					}
					else if (num < damageRange)
					{
						component2.mainScript.HitEnemyOnLocalClient(Mathf.RoundToInt((float)(component2.mainScript.enemyHP / 2)), default(Vector3), (PlayerControllerB)null, false, -1);
					}
				}
			}
		}
	}
	internal class QuickSandPatch
	{
		public static bool OnTriggerStayPatch(ref QuicksandTrigger __instance, Collider other)
		{
			if (__instance.isWater)
			{
				if (!((Component)other).gameObject.CompareTag("Player") && (Object)(object)((Component)other).gameObject.GetComponent<EnemyAICollisionDetect>() == (Object)null)
				{
					return false;
				}
				if ((Object)(object)((Component)other).gameObject.GetComponent<EnemyAICollisionDetect>() != (Object)null)
				{
					EnemyAICollisionDetect component = ((Component)other).gameObject.GetComponent<EnemyAICollisionDetect>();