Decompiled source of ExperimentalEnemyInteractions v0.2.6

DLLs/fandovec03.NaturalSelection.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using NaturalSelection.EnemyPatches;
using NaturalSelection.Generics;
using NaturalSelectionLib;
using Unity.Netcode;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("fandovec03.NaturalSelection")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("0.1.3.0")]
[assembly: AssemblyInformationalVersion("0.1.3+a326e440374f6f62dce37af0fde11557d091c29d")]
[assembly: AssemblyProduct("NaturalSelection")]
[assembly: AssemblyTitle("fandovec03.NaturalSelection")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.3.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace NaturalSelection
{
	[BepInPlugin("fandovec03.NaturalSelection", "NaturalSelection", "0.1.3")]
	public class Script : BaseUnityPlugin
	{
		internal static bool stableToggle;

		internal static float clampedAgentRadius;

		public static Script Instance { get; private set; }

		internal static ManualLogSource Logger { get; private set; }

		internal static Harmony? Harmony { get; set; }

		internal static MyModConfig BoundingConfig { get; set; }

		private void Awake()
		{
			Logger = ((BaseUnityPlugin)this).Logger;
			Instance = this;
			BoundingConfig = new MyModConfig(((BaseUnityPlugin)this).Config);
			stableToggle = BoundingConfig.stableMode.Value;
			clampedAgentRadius = Mathf.Clamp(BoundingConfig.agentRadiusModifier.Value, 0.1f, 1f);
			Patch();
			Logger.LogInfo((object)"fandovec03.NaturalSelection v0.1.3 has loaded!");
		}

		internal static void Patch()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			if (Harmony == null)
			{
				Harmony = new Harmony("fandovec03.NaturalSelection");
			}
			Logger.LogInfo((object)"Patching NaturalSelection ...");
			for (int i = 0; i < 100; i++)
			{
				Logger.LogError((object)("LOADING EXPERIMENTAL " + "NaturalSelection".ToUpper() + ", DOWNLOAD NATURAL SELECTION INSTEAD!"));
			}
			Harmony.PatchAll(typeof(AICollisionDetectPatch));
			Harmony.PatchAll(typeof(EnemyAIPatch));
			try
			{
				NaturalSelectionLib.LibrarySetup(Logger, BoundingConfig.spammyLogs.Value, BoundingConfig.debugUnspecified.Value);
				Logger.LogInfo((object)"Library successfully setup!");
			}
			catch
			{
				Logger.LogError((object)"Failed to setup library!");
			}
			Harmony.PatchAll(typeof(RoundManagerPatch));
			if (BoundingConfig.loadSandworms.Value)
			{
				Harmony.PatchAll(typeof(SandWormAIPatch));
			}
			if (BoundingConfig.loadBlob.Value)
			{
				Harmony.PatchAll(typeof(BlobAIPatch));
			}
			if (BoundingConfig.loadHoardingBugs.Value)
			{
				Harmony.PatchAll(typeof(HoarderBugPatch));
			}
			if (BoundingConfig.LoadBees.Value)
			{
				Harmony.PatchAll(typeof(BeeAIPatch));
			}
			if (BoundingConfig.loadGiants.Value)
			{
				Harmony.PatchAll(typeof(ForestGiantPatch));
			}
			if (!stableToggle)
			{
				if (BoundingConfig.loadNutcrackers.Value)
				{
					Harmony.PatchAll(typeof(NutcrackerAIPatch));
				}
				if (BoundingConfig.loadSporeLizard.Value)
				{
					Harmony.PatchAll(typeof(PufferAIPatch));
				}
				if (BoundingConfig.loadSpiders.Value)
				{
					Harmony.PatchAll(typeof(SandSpiderAIPatch));
				}
				Logger.LogInfo((object)"Stable mode off. Loaded all patches.");
			}
			else
			{
				Logger.LogInfo((object)"Stable mode on. Excluded unstable and WIP patches from loading.");
			}
			Logger.LogInfo((object)"Finished patching NaturalSelection !");
		}

		internal static void Unpatch()
		{
			Logger.LogDebug((object)"Unpatching...");
			Harmony? harmony = Harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			Logger.LogDebug((object)"Finished unpatching!");
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "fandovec03.NaturalSelection";

		public const string PLUGIN_NAME = "NaturalSelection";

		public const string PLUGIN_VERSION = "0.1.3";
	}
}
namespace NaturalSelection.Generics
{
	internal class MyModConfig
	{
		public readonly ConfigEntry<bool> delayScriptsOnSpawn;

		public readonly ConfigEntry<float> delay;

		public readonly ConfigEntry<bool> stableMode;

		public readonly ConfigEntry<bool> spiderHuntHoardingbug;

		public readonly ConfigEntry<float> agentRadiusModifier;

		public readonly ConfigEntry<bool> IgnoreImmortalEnemies;

		public readonly ConfigEntry<bool> enableSpider;

		public readonly ConfigEntry<bool> enableSlime;

		public readonly ConfigEntry<bool> enableLeviathan;

		public readonly ConfigEntry<bool> enableSporeLizard;

		public readonly ConfigEntry<bool> enableRedBees;

		public readonly ConfigEntry<bool> enableNutcrackers;

		public readonly ConfigEntry<int> giantExtinguishChance;

		public readonly ConfigEntry<float> beesSetGiantsOnFireMinChance;

		public readonly ConfigEntry<float> beesSetGiantsOnFireMaxChance;

		public readonly ConfigEntry<bool> loadNutcrackers;

		public readonly ConfigEntry<bool> loadSpiders;

		public readonly ConfigEntry<bool> loadSandworms;

		public readonly ConfigEntry<bool> loadGiants;

		public readonly ConfigEntry<bool> loadHoardingBugs;

		public readonly ConfigEntry<bool> loadBlob;

		public readonly ConfigEntry<bool> LoadBees;

		public readonly ConfigEntry<bool> loadSporeLizard;

		public readonly ConfigEntry<bool> debugBool;

		public readonly ConfigEntry<bool> spammyLogs;

		public readonly ConfigEntry<bool> debugTriggerFlags;

		public readonly ConfigEntry<bool> debugRedBees;

		public readonly ConfigEntry<bool> debugSandworms;

		public readonly ConfigEntry<bool> debugHygrodere;

		public readonly ConfigEntry<bool> debugNutcrackers;

		public readonly ConfigEntry<bool> debugSpiders;

		public readonly ConfigEntry<bool> debugGiants;

		public readonly ConfigEntry<bool> debugUnspecified;

		public MyModConfig(ConfigFile cfg)
		{
			cfg.SaveOnConfigSet = false;
			delayScriptsOnSpawn = cfg.Bind<bool>("Experimental Fixes", "Delay enemy scripts on spawn", false, "Delay enemy scripts from taking effect on enemy spawns. Might fix invisible bees");
			delay = cfg.Bind<float>("Experimental Fixes", "Delay", 0.2f, "Set the length of the delay");
			stableMode = cfg.Bind<bool>("General Settings", "Toggle stable mode", true, "When true, the mod will exlude patches that are WIP or are experimental from loading");
			IgnoreImmortalEnemies = cfg.Bind<bool>("General Settings", "Ignore Immortal Enemies", false, "All immortal enemies will be ignored by majority of entities");
			agentRadiusModifier = cfg.Bind<float>("WIP", "Agent radius modifier", 0.6f, "Agent radius multiplier. Agent size is modified to make collisions more reliable. Lower multiplier makes final Agent radius smaller. \n \n [Values not between 0.1 and 1 are Clamped]");
			agentRadiusModifier.Value = Mathf.Clamp(agentRadiusModifier.Value, 0.1f, 1f);
			spiderHuntHoardingbug = cfg.Bind<bool>("WIP", "Spider hunts Hoarding bugs", false, "Bunker spider chases and hunts hoarding bugs. DEV ONLY");
			enableSpider = cfg.Bind<bool>("WIP", "Enable spider", false, "Mod applies changes Bunker Spider. DEV ONLY");
			enableSlime = cfg.Bind<bool>("Entity settings", "Enable slime", true, "Mod applies changes Hygrodere. Slime now damages every entity it passes by.");
			enableLeviathan = cfg.Bind<bool>("Entity settings", "Enable leviathan", true, "Mod applies changes Earth leviathan. Leviathan now targets other creatures aswell.");
			enableSporeLizard = cfg.Bind<bool>("WIP", "Enable SporeLizard", false, "Mod applies changes Spore lizard. It is now mortal!");
			enableRedBees = cfg.Bind<bool>("Entity settings", "Enable Red bees (Circuit bees)", true, "Mod applies changes red bees. They now defend nest from other mobs and kill everything in rampage!");
			enableNutcrackers = cfg.Bind<bool>("WIP", "Enable Nutcrackers", false, "Mod applies changes to nutcrackers. DEV ONLY");
			giantExtinguishChance = cfg.Bind<int>("Entity settings", "(Giant) Extinguish chance", 33, "[Accepts int values between 0 and 100] Chance of giants extinguishing themselves.");
			beesSetGiantsOnFireMinChance = cfg.Bind<float>("Entity settings", "(Bees) Ignite giants min chace", 1.5f, "[Accepts float values between 0 and 100]The minimum chance bees will set giant on fire on hit");
			beesSetGiantsOnFireMaxChance = cfg.Bind<float>("Entity settings", "(Bees) Ignite giants max chace", 8f, "[Accepts float values between 0 and 100]The minimum chance bees will set giant on fire on hit");
			loadSpiders = cfg.Bind<bool>("Initialization settings (Not recommended)", "Load spider patches", true, "Load the spider patches. Do not touch.");
			loadBlob = cfg.Bind<bool>("Initialization settings (Not recommended)", "Load slime patches", true, "Load the slime patches. Do not touch.");
			loadSandworms = cfg.Bind<bool>("Initialization settings (Not recommended)", "Load leviathan patches", true, "Load the leviathan patches. Do not touch.");
			loadGiants = cfg.Bind<bool>("Initialization settings (Not recommended)", "Load giant patches", true, "Load the giant patches. Do not touch.");
			LoadBees = cfg.Bind<bool>("Initialization settings (Not recommended)", "Load circuit bees patches", true, "Load bees patches. Do not touch.");
			loadNutcrackers = cfg.Bind<bool>("Initialization settings (Not recommended)", "Load nutcracker patches", true, "Load the nutcracker patches. Do not touch.");
			loadHoardingBugs = cfg.Bind<bool>("Initialization settings (Not recommended)", "Load hoarding bugs patches", true, "Load the hoarding bug patches. Do not touch.");
			loadSporeLizard = cfg.Bind<bool>("Initialization settings (Not recommended)", "Load spore lizards patches", true, "Load the spore lizard patches. Do not touch.");
			debugBool = cfg.Bind<bool>("Debug", "Debug mode", false, "Enables debug mode for more debug logs.");
			spammyLogs = cfg.Bind<bool>("Debug", "Spammy logs", false, "Enables spammy logs for extra logs.");
			debugTriggerFlags = cfg.Bind<bool>("Debug", "Trigger flags", false, "Enables logs with trigger flag.");
			debugRedBees = cfg.Bind<bool>("Debug", "Log bees", false, "Enables logs for bees.");
			debugSandworms = cfg.Bind<bool>("Debug", "Log sandworms", false, "Enables logs for sandowrms.");
			debugHygrodere = cfg.Bind<bool>("Debug", "Log hydrogere", false, "Enables logs for hydrogere.");
			debugNutcrackers = cfg.Bind<bool>("Debug", "Log nutcrackers", false, "Enables logs for nutcrackers.");
			debugSpiders = cfg.Bind<bool>("Debug", "Log spiders", false, "Enables logs for spiders.");
			debugGiants = cfg.Bind<bool>("Debug", "Log giants", false, "Enables logs for giants.");
			debugUnspecified = cfg.Bind<bool>("Debug", "Log unspecified", false, "Enables logs for unspecified.");
			ClearOrphanedEntries(cfg);
			cfg.Save();
			cfg.SaveOnConfigSet = true;
		}

		public void ClearOrphanedEntries(ConfigFile cfg)
		{
			PropertyInfo propertyInfo = AccessTools.Property(typeof(ConfigFile), "OrphanedEntries");
			Dictionary<ConfigDefinition, string> dictionary = (Dictionary<ConfigDefinition, string>)propertyInfo.GetValue(cfg);
			dictionary.Clear();
		}
	}
	[HarmonyPatch(typeof(RoundManager))]
	internal class RoundManagerPatch
	{
		private static float nextUpdate = 0f;

		private static Dictionary<Type, List<EnemyAI>> checkedTypes = new Dictionary<Type, List<EnemyAI>>();

		public static float updateListInterval = 1f;

		private static bool canUpdate = true;

		private static bool logSpam = Script.BoundingConfig.spammyLogs.Value;

		private static bool logUnspecified = Script.BoundingConfig.debugUnspecified.Value;

		[HarmonyPatch("Update")]
		[HarmonyPrefix]
		private static void UpdatePatch()
		{
			if (!(Time.realtimeSinceStartup >= nextUpdate))
			{
				return;
			}
			foreach (Type item in checkedTypes.Keys.ToList())
			{
				NaturalSelectionLib.UpdateListInsideDictionrary(item, checkedTypes[item]);
			}
			checkedTypes.Clear();
			nextUpdate = Time.realtimeSinceStartup + updateListInterval;
		}

		public static bool RequestUpdate(EnemyAI instance)
		{
			if (!checkedTypes.ContainsKey(((object)instance).GetType()))
			{
				checkedTypes.Add(((object)instance).GetType(), new List<EnemyAI>());
				if (logUnspecified && logSpam)
				{
					Script.Logger.LogMessage((object)("/RoundManager/ request was Accepted. Requested by " + EnemyAIPatch.DebugStringHead(instance) + " at " + Time.realtimeSinceStartup));
				}
				return true;
			}
			if (logUnspecified && logSpam)
			{
				Script.Logger.LogInfo((object)("/RoundManager/ request was Denied. Requested by " + EnemyAIPatch.DebugStringHead(instance) + " at " + Time.realtimeSinceStartup));
			}
			return false;
		}

		public static void ScheduleGlobalListUpdate(EnemyAI instance, List<EnemyAI> list)
		{
			if (checkedTypes.ContainsKey(((object)instance).GetType()))
			{
				checkedTypes[((object)instance).GetType()] = list;
			}
			if (!NaturalSelectionLib.globalEnemyLists.ContainsKey(((object)instance).GetType()))
			{
				Script.Logger.LogError((object)(EnemyAIPatch.DebugStringHead(instance) + "global enemy list for this enemy does not exist! Creating a new one."));
				NaturalSelectionLib.UpdateListInsideDictionrary(((object)instance).GetType(), checkedTypes[((object)instance).GetType()]);
			}
		}
	}
}
namespace NaturalSelection.EnemyPatches
{
	internal class BeeValues
	{
		public bool start = Script.BoundingConfig.delayScriptsOnSpawn.Value;

		public EnemyAI? closestEnemy = null;

		public EnemyAI? targetEnemy = null;

		public Vector3 lastKnownEnemyPosition = Vector3.zero;

		public int customBehaviorStateIndex = 0;

		public float timeSinceHittingEnemy = 0f;

		public float LostLOSOfEnemy = 0f;

		public List<Type> enemyTypes = new List<Type>();

		public float delayTimer = 0.2f;
	}
	[HarmonyPatch(typeof(RedLocustBees))]
	internal class BeeAIPatch
	{
		private static Dictionary<RedLocustBees, BeeValues> beeList = new Dictionary<RedLocustBees, BeeValues>();

		private static bool logBees = Script.BoundingConfig.debugRedBees.Value;

		private static bool debugSpam = Script.BoundingConfig.spammyLogs.Value;

		private static float UpdateTimer = Script.BoundingConfig.delay.Value;

		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		private static void StartPatch(RedLocustBees __instance)
		{
			if (!beeList.ContainsKey(__instance))
			{
				beeList.Add(__instance, new BeeValues());
			}
			BeeValues beeValues = beeList[__instance];
			if (beeValues.enemyTypes.Count < 1)
			{
				beeValues.enemyTypes.Add(typeof(DocileLocustBeesAI));
				beeValues.enemyTypes.Add(typeof(SandWormAI));
			}
		}

		[HarmonyPatch("Update")]
		[HarmonyPostfix]
		private static void UpdatePatch(RedLocustBees __instance)
		{
			BeeValues beeValues = beeList[__instance];
			if (beeValues.delayTimer > 0f)
			{
				beeValues.delayTimer -= Time.deltaTime;
				return;
			}
			if (RoundManagerPatch.RequestUpdate((EnemyAI)(object)__instance))
			{
				RoundManagerPatch.ScheduleGlobalListUpdate((EnemyAI)(object)__instance, EnemyAIPatch.FilterEnemyList(EnemyAIPatch.GetOutsideEnemyList(EnemyAIPatch.GetCompleteList((EnemyAI)(object)__instance), (EnemyAI)(object)__instance), beeList[__instance].enemyTypes, (EnemyAI)(object)__instance, inverseToggle: true, Script.BoundingConfig.IgnoreImmortalEnemies.Value));
			}
			if (NaturalSelectionLib.globalEnemyLists[((object)__instance).GetType()].Contains((EnemyAI)(object)__instance))
			{
				if (logBees && debugSpam)
				{
					Script.Logger.LogError((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + " FOUND ITSELF IN THE EnemyList! Removing..."));
				}
				NaturalSelectionLib.globalEnemyLists[((object)__instance).GetType()].Remove((EnemyAI)(object)__instance);
			}
		}

		[HarmonyPatch("DoAIInterval")]
		[HarmonyPrefix]
		private static bool DoAIIntervalPrefixPatch(RedLocustBees __instance)
		{
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			BeeValues beeValues = beeList[__instance];
			bool flag = true;
			if ((Object)(object)beeValues.targetEnemy != (Object)null && !((EnemyAI)__instance).movingTowardsTargetPlayer && ((EnemyAI)__instance).currentBehaviourStateIndex != 0)
			{
				if (logBees && debugSpam)
				{
					Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "DoAIInterval: Prefix triggered false"));
				}
				if (((EnemyAI)__instance).moveTowardsDestination)
				{
					((EnemyAI)__instance).agent.SetDestination(((EnemyAI)__instance).destination);
				}
				((EnemyAI)__instance).SyncPositionToClients();
				return false;
			}
			if (logBees && debugSpam)
			{
				Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "DoAIInterval: Prefix triggered true"));
			}
			return true;
		}

		[HarmonyPatch("DoAIInterval")]
		[HarmonyPostfix]
		private static void DoAIIntervalPostfixPatch(RedLocustBees __instance)
		{
			//IL_0377: Unknown result type (might be due to invalid IL or missing references)
			//IL_037d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0397: Unknown result type (might be due to invalid IL or missing references)
			//IL_0407: Unknown result type (might be due to invalid IL or missing references)
			//IL_0417: Unknown result type (might be due to invalid IL or missing references)
			//IL_052d: Unknown result type (might be due to invalid IL or missing references)
			//IL_053d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0829: Unknown result type (might be due to invalid IL or missing references)
			//IL_082e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0838: Unknown result type (might be due to invalid IL or missing references)
			//IL_083d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0842: Unknown result type (might be due to invalid IL or missing references)
			//IL_087b: Unknown result type (might be due to invalid IL or missing references)
			//IL_043f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0497: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b50: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b7e: Unknown result type (might be due to invalid IL or missing references)
			//IL_096a: Unknown result type (might be due to invalid IL or missing references)
			//IL_097a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0628: Unknown result type (might be due to invalid IL or missing references)
			//IL_0656: Unknown result type (might be due to invalid IL or missing references)
			//IL_09a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0e03: Unknown result type (might be due to invalid IL or missing references)
			//IL_0dc1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d01: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d06: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d0d: Unknown result type (might be due to invalid IL or missing references)
			//IL_09fa: Unknown result type (might be due to invalid IL or missing references)
			bool flag = true;
			BeeValues beeValues = beeList[__instance];
			switch (((EnemyAI)__instance).currentBehaviourStateIndex)
			{
			case 0:
			{
				EnemyAI val4 = null;
				if (EnemyAIPatch.GetEnemiesInLOS((EnemyAI)(object)__instance, NaturalSelectionLib.globalEnemyLists[((object)__instance).GetType()], 360f, 16, 1f).Count > 0)
				{
					if (NaturalSelectionLib.globalEnemyLists[((object)__instance).GetType()].Contains((EnemyAI)(object)__instance))
					{
						if (logBees && debugSpam)
						{
							Script.Logger.LogError((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + " FOUND ITSELF IN THE EnemyList before LOSEnemy! Removing..."));
						}
						NaturalSelectionLib.globalEnemyLists[((object)__instance).GetType()].Remove((EnemyAI)(object)__instance);
					}
					val4 = EnemyAIPatch.GetEnemiesInLOS((EnemyAI)(object)__instance, NaturalSelectionLib.globalEnemyLists[((object)__instance).GetType()], 360f, 16, 1f).Keys.First();
					if (logBees)
					{
						Script.Logger.LogInfo((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "case0: Checked LOS for enemies. Enemy found: " + EnemyAIPatch.DebugStringHead(val4)));
					}
					if (logBees && debugSpam)
					{
						foreach (KeyValuePair<EnemyAI, float> enemiesInLO in EnemyAIPatch.GetEnemiesInLOS((EnemyAI)(object)__instance, NaturalSelectionLib.globalEnemyLists[((object)__instance).GetType()], 360f, 16, 1f))
						{
							if (logBees && debugSpam)
							{
								Script.Logger.LogError((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + " FOUND ITSELF IN THE EnemyList before LOSEnemy! Removing..."));
							}
							NaturalSelectionLib.globalEnemyLists[((object)__instance).GetType()].Remove((EnemyAI)(object)__instance);
						}
						val4 = EnemyAIPatch.GetEnemiesInLOS((EnemyAI)(object)__instance, NaturalSelectionLib.globalEnemyLists[((object)__instance).GetType()], 360f, 16, 1f).Keys.First();
						if (logBees)
						{
							Script.Logger.LogInfo((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "case0: Checked LOS for enemies. Enemy found: " + EnemyAIPatch.DebugStringHead(val4)));
						}
						if (logBees && debugSpam)
						{
							foreach (KeyValuePair<EnemyAI, float> enemiesInLO2 in EnemyAIPatch.GetEnemiesInLOS((EnemyAI)(object)__instance, NaturalSelectionLib.globalEnemyLists[((object)__instance).GetType()], 360f, 16, 1f))
							{
								Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + " Checking the LOSList: " + EnemyAIPatch.DebugStringHead(enemiesInLO2.Key) + ", Distance: " + enemiesInLO2.Value));
								if ((Object)(object)enemiesInLO2.Key == (Object)(object)__instance)
								{
									Script.Logger.LogError((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + " FOUND ITSELF IN THE LOSList: " + EnemyAIPatch.DebugStringHead(enemiesInLO2.Key) + ", Distance: " + enemiesInLO2.Value));
								}
							}
						}
					}
				}
				if (__instance.wasInChase)
				{
					__instance.wasInChase = false;
				}
				if (Vector3.Distance(((Component)__instance).transform.position, __instance.lastKnownHivePosition) > 2f)
				{
					((EnemyAI)__instance).SetDestinationToPosition(__instance.lastKnownHivePosition, true);
				}
				if (__instance.IsHiveMissing())
				{
					((EnemyAI)__instance).SwitchToBehaviourState(2);
					beeValues.customBehaviorStateIndex = 2;
					if (logBees)
					{
						Script.Logger.LogInfo((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "case0: HIVE IS MISSING! CustomBehaviorStateIndex changed: " + beeValues.customBehaviorStateIndex));
					}
				}
				else if ((Object)(object)val4 != (Object)null && Vector3.Distance(((Component)val4).transform.position, ((Component)__instance.hive).transform.position) < (float)__instance.defenseDistance)
				{
					((EnemyAI)__instance).SetDestinationToPosition(((Component)val4).transform.position, true);
					if (logBees)
					{
						Script.Logger.LogInfo((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "case0: Moving towards " + (object)val4));
					}
					beeValues.customBehaviorStateIndex = 1;
					((EnemyAI)__instance).SwitchToBehaviourState(1);
					__instance.syncedLastKnownHivePosition = false;
					__instance.SyncLastKnownHivePositionServerRpc(__instance.lastKnownHivePosition);
					beeValues.LostLOSOfEnemy = 0f;
					if (logBees)
					{
						Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "case0: CustomBehaviorStateIndex changed: " + beeValues.customBehaviorStateIndex));
					}
				}
				break;
			}
			case 1:
			{
				if (((Object)(object)((EnemyAI)__instance).targetPlayer != (Object)null && ((EnemyAI)__instance).movingTowardsTargetPlayer) || (!((Object)(object)beeValues.targetEnemy == (Object)null) && !beeValues.targetEnemy.isEnemyDead && !(Vector3.Distance(((Component)beeValues.targetEnemy).transform.position, ((Component)__instance.hive).transform.position) > (float)__instance.defenseDistance + 5f)))
				{
					break;
				}
				bool flag3 = false;
				Dictionary<EnemyAI, float> enemiesInLOS2 = EnemyAIPatch.GetEnemiesInLOS((EnemyAI)(object)__instance, NaturalSelectionLib.globalEnemyLists[((object)__instance).GetType()], 360f, 16, 1f);
				EnemyAI val3 = null;
				if (enemiesInLOS2.Count > 0)
				{
					val3 = enemiesInLOS2.Keys.First();
				}
				if (logBees)
				{
					Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "case2: " + ((object)val3)?.ToString() + " is closest to hive."));
				}
				if ((Object)(object)val3 != (Object)null && (Object)(object)beeValues.targetEnemy != (Object)(object)val3)
				{
					flag3 = true;
					__instance.wasInChase = false;
					beeValues.targetEnemy = val3;
					((EnemyAI)__instance).SetDestinationToPosition(((Component)beeValues.targetEnemy).transform.position, true);
					((EnemyAI)__instance).StopSearch(__instance.searchForHive, true);
					__instance.syncedLastKnownHivePosition = false;
					beeValues.LostLOSOfEnemy = 0f;
					__instance.SyncLastKnownHivePositionServerRpc(__instance.lastKnownHivePosition);
					if (logBees)
					{
						Script.Logger.LogInfo((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "case2: Targeting " + ((object)val3)?.ToString() + ". Synced hive position"));
					}
				}
				else
				{
					if (!((Object)(object)beeValues.targetEnemy != (Object)null))
					{
						break;
					}
					((EnemyAI)__instance).agent.acceleration = 16f;
					if (!flag3 && EnemyAIPatch.GetEnemiesInLOS((EnemyAI)(object)__instance, NaturalSelectionLib.globalEnemyLists[((object)__instance).GetType()], 360f, 16, 2f).Count == 0)
					{
						beeValues.targetEnemy = null;
					}
					__instance.wasInChase = false;
					if (__instance.IsHiveMissing())
					{
						beeValues.customBehaviorStateIndex = 2;
						((EnemyAI)__instance).SwitchToBehaviourState(2);
						if (logBees)
						{
							Script.Logger.LogInfo((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "case1: HIVE IS MISSING! CustomBehaviorStateIndex changed: " + beeValues.customBehaviorStateIndex));
						}
					}
					else
					{
						beeValues.customBehaviorStateIndex = 0;
						((EnemyAI)__instance).SwitchToBehaviourState(0);
						if (logBees)
						{
							Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "case1: CustomBehaviorStateIndex changed: " + beeValues.customBehaviorStateIndex));
						}
					}
				}
				break;
			}
			case 2:
			{
				if ((Object)(object)((EnemyAI)__instance).targetPlayer != (Object)null || ((EnemyAI)__instance).movingTowardsTargetPlayer)
				{
					if (logBees && debugSpam)
					{
						Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "case2: target player found or moving towards target player"));
					}
					break;
				}
				if (__instance.IsHivePlacedAndInLOS())
				{
					if (__instance.wasInChase)
					{
						__instance.wasInChase = false;
					}
					__instance.lastKnownHivePosition = ((Component)__instance.hive).transform.position + Vector3.up * 0.5f;
					if (logBees)
					{
						Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "case2: IsHivePlacedAndInLOS triggered"));
					}
					EnemyAI val = null;
					Collider[] array = Physics.OverlapSphere(((Component)__instance.hive).transform.position, (float)__instance.defenseDistance, StartOfRound.Instance.collidersAndRoomMaskAndDefault, (QueryTriggerInteraction)2);
					if (array != null && array.Length != 0)
					{
						for (int i = 0; i < array.Length; i++)
						{
							if (((Component)array[i]).gameObject.tag == "Enemy" && !((Object)(object)((Component)array[i]).gameObject.GetComponent<EnemyAICollisionDetect>().mainScript == (Object)(object)__instance))
							{
								val = ((Component)array[i]).gameObject.GetComponent<EnemyAICollisionDetect>().mainScript;
								if (logBees)
								{
									Script.Logger.LogInfo((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "case2: CollisionArray triggered. Enemy found: " + EnemyAIPatch.DebugStringHead(val)));
								}
								break;
							}
						}
					}
					if ((Object)(object)val != (Object)null && Vector3.Distance(((Component)val).transform.position, ((Component)__instance.hive).transform.position) < (float)__instance.defenseDistance)
					{
						((EnemyAI)__instance).SetDestinationToPosition(((Component)val).transform.position, true);
						if (logBees)
						{
							Script.Logger.LogInfo((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "case2: Moving towards: " + (object)val));
						}
						beeValues.customBehaviorStateIndex = 1;
						((EnemyAI)__instance).SwitchToBehaviourState(1);
						__instance.syncedLastKnownHivePosition = false;
						__instance.SyncLastKnownHivePositionServerRpc(__instance.lastKnownHivePosition);
						beeValues.LostLOSOfEnemy = 0f;
						if (logBees)
						{
							Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "case2: CustomBehaviorStateIndex changed: " + beeValues.customBehaviorStateIndex));
						}
					}
					else
					{
						beeValues.customBehaviorStateIndex = 0;
						((EnemyAI)__instance).SwitchToBehaviourState(0);
						if (logBees)
						{
							Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "case2: CustomBehaviorStateIndex changed: " + beeValues.customBehaviorStateIndex));
						}
					}
					break;
				}
				bool flag2 = false;
				Dictionary<EnemyAI, float> enemiesInLOS = EnemyAIPatch.GetEnemiesInLOS((EnemyAI)(object)__instance, NaturalSelectionLib.globalEnemyLists[((object)__instance).GetType()], 360f, 16, 1f);
				EnemyAI val2 = null;
				if (enemiesInLOS.Count > 0)
				{
					val2 = enemiesInLOS.Keys.First();
				}
				if (logBees)
				{
					Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "case2: " + ((object)val2)?.ToString() + " is closest to hive."));
				}
				if ((Object)(object)val2 != (Object)null && (Object)(object)beeValues.targetEnemy != (Object)(object)val2)
				{
					flag2 = true;
					__instance.wasInChase = false;
					beeValues.targetEnemy = val2;
					((EnemyAI)__instance).SetDestinationToPosition(((Component)beeValues.targetEnemy).transform.position, true);
					((EnemyAI)__instance).StopSearch(__instance.searchForHive, true);
					__instance.syncedLastKnownHivePosition = false;
					beeValues.LostLOSOfEnemy = 0f;
					__instance.SyncLastKnownHivePositionServerRpc(__instance.lastKnownHivePosition);
					if (logBees)
					{
						Script.Logger.LogInfo((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "case2: Targeting " + ((object)val2)?.ToString() + ". Synced hive position"));
					}
					break;
				}
				if ((Object)(object)beeValues.targetEnemy != (Object)null)
				{
					((EnemyAI)__instance).agent.acceleration = 16f;
					if (!flag2 && EnemyAIPatch.GetEnemiesInLOS((EnemyAI)(object)__instance, NaturalSelectionLib.globalEnemyLists[((object)__instance).GetType()], 360f, 16, 2f).Count == 0)
					{
						if (logBees && debugSpam)
						{
							Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "case2: lost LOS of " + ((object)beeValues.targetEnemy)?.ToString() + ", started timer."));
						}
						beeValues.LostLOSOfEnemy += ((EnemyAI)__instance).AIIntervalTime;
						if (beeValues.LostLOSOfEnemy >= 4.5f)
						{
							beeValues.targetEnemy = null;
							beeValues.LostLOSOfEnemy = 0f;
							if (logBees)
							{
								Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "case2: lost LOS of " + ((object)beeValues.targetEnemy)?.ToString() + ", Stopped and reset timer."));
							}
						}
					}
					else
					{
						__instance.wasInChase = true;
						beeValues.lastKnownEnemyPosition = ((Component)beeValues.targetEnemy).transform.position;
						((EnemyAI)__instance).SetDestinationToPosition(beeValues.lastKnownEnemyPosition, true);
						beeValues.LostLOSOfEnemy = 0f;
						if (logBees)
						{
							Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "case2: lost " + (object)beeValues.targetEnemy));
						}
					}
					break;
				}
				((EnemyAI)__instance).agent.acceleration = 13f;
				if (__instance.searchForHive.inProgress)
				{
					break;
				}
				if (logBees)
				{
					Script.Logger.LogInfo((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "case2: set new search for hive"));
				}
				if (__instance.wasInChase)
				{
					((EnemyAI)__instance).StartSearch(beeValues.lastKnownEnemyPosition, __instance.searchForHive);
					if (logBees)
					{
						Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "case2: Started search for hive."));
					}
				}
				else
				{
					((EnemyAI)__instance).StartSearch(((Component)__instance).transform.position, __instance.searchForHive);
					if (logBees)
					{
						Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "case2: Started search for hive."));
					}
				}
				break;
			}
			}
		}

		public static void OnCustomEnemyCollision(RedLocustBees __instance, EnemyAI mainscript2)
		{
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Expected O, but got Unknown
			if (!beeList.ContainsKey(__instance))
			{
				return;
			}
			if ((beeList[__instance].timeSinceHittingEnemy > 1.7f && ((EnemyAI)__instance).currentBehaviourStateIndex > 0) || (beeList[__instance].timeSinceHittingEnemy > 1.3f && ((EnemyAI)__instance).currentBehaviourStateIndex == 2 && !mainscript2.isEnemyDead))
			{
				mainscript2.HitEnemy(1, (PlayerControllerB)null, true, -1);
				beeList[__instance].timeSinceHittingEnemy = 0f;
				if (!(mainscript2 is ForestGiantAI) || mainscript2.currentBehaviourStateIndex == 2)
				{
					return;
				}
				float num = Random.Range(0f, 100f);
				float num2 = 0f;
				num2 = ((((EnemyAI)__instance).currentBehaviourStateIndex == 2) ? Script.BoundingConfig.beesSetGiantsOnFireMaxChance.Value : Script.BoundingConfig.beesSetGiantsOnFireMinChance.Value);
				if (logBees)
				{
					Script.Logger.LogInfo((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "OnCustomEnemyCollision: Giant hit. Chance to set on fire: " + num2));
				}
				if (num <= num2)
				{
					if (logBees)
					{
						Script.Logger.LogInfo((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "OnCustomEnemyCollision: SET GIANT ON FIRE! Random number: " + num));
					}
					ForestGiantAI val = (ForestGiantAI)mainscript2;
					val.timeAtStartOfBurning = Time.realtimeSinceStartup;
					((EnemyAI)val).SwitchToBehaviourState(2);
				}
			}
			else
			{
				beeList[__instance].timeSinceHittingEnemy += Time.deltaTime;
			}
		}
	}
	internal class BlobData
	{
		public float timeSinceHittingLocalMonster = 0f;

		public EnemyAI? closestEnemy = null;
	}
	[HarmonyPatch(typeof(BlobAI))]
	public class BlobAIPatch
	{
		private static List<EnemyAI> whiteList = new List<EnemyAI>();

		private static Dictionary<BlobAI, BlobData> slimeList = new Dictionary<BlobAI, BlobData>();

		private static bool logBlob = Script.BoundingConfig.debugHygrodere.Value;

		[HarmonyPatch("Start")]
		[HarmonyPrefix]
		private static void StartPatch(BlobAI __instance)
		{
			if (!slimeList.ContainsKey(__instance))
			{
				slimeList.Add(__instance, new BlobData());
			}
		}

		[HarmonyPatch("DoAIInterval")]
		[HarmonyPrefix]
		private static bool DoAIIntervalPrefixPatch(BlobAI __instance)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: 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_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			BlobData blobData = slimeList[__instance];
			if ((Object)(object)blobData.closestEnemy != (Object)null && Vector3.Distance(((Component)__instance).transform.position, ((Component)((EnemyAI)__instance).GetClosestPlayer(false, false, false)).transform.position) > Vector3.Distance(((Component)__instance).transform.position, ((Component)blobData.closestEnemy).transform.position))
			{
				if (((EnemyAI)__instance).moveTowardsDestination)
				{
					((EnemyAI)__instance).agent.SetDestination(((EnemyAI)__instance).destination);
				}
				((EnemyAI)__instance).SyncPositionToClients();
				if (((EnemyAI)__instance).movingTowardsTargetPlayer)
				{
					((EnemyAI)__instance).movingTowardsTargetPlayer = false;
				}
				if (__instance.searchForPlayers.inProgress)
				{
					((EnemyAI)__instance).StopSearch(__instance.searchForPlayers, true);
				}
				if ((Object)(object)blobData.closestEnemy != (Object)null)
				{
					((EnemyAI)__instance).SetDestinationToPosition(((Component)blobData.closestEnemy).transform.position, true);
				}
				return false;
			}
			return true;
		}

		[HarmonyPatch("Update")]
		[HarmonyPrefix]
		private static void BlobUpdatePatch(BlobAI __instance)
		{
			BlobData blobData = slimeList[__instance];
			blobData.timeSinceHittingLocalMonster += Time.deltaTime;
			if (RoundManagerPatch.RequestUpdate((EnemyAI)(object)__instance))
			{
				RoundManagerPatch.ScheduleGlobalListUpdate((EnemyAI)(object)__instance, EnemyAIPatch.FilterEnemyList(EnemyAIPatch.GetInsideEnemyList(EnemyAIPatch.GetCompleteList((EnemyAI)(object)__instance, FilterThemselves: true, 1), (EnemyAI)(object)__instance), null, (EnemyAI)(object)__instance));
			}
			blobData.closestEnemy = EnemyAIPatch.FindClosestEnemy(NaturalSelectionLib.globalEnemyLists[((object)__instance).GetType()], blobData.closestEnemy, (EnemyAI)(object)__instance, includeTheDead: true);
		}

		public static void OnCustomEnemyCollision(BlobAI __instance, EnemyAI mainscript2)
		{
			//IL_0038: 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)
			BlobData blobData = slimeList[__instance];
			if (!(blobData.timeSinceHittingLocalMonster > 1.5f))
			{
				return;
			}
			if (mainscript2.isEnemyDead && !IsEnemyImmortal.EnemyIsImmortal(mainscript2) && Vector3.Distance(((Component)__instance).transform.position, ((Component)mainscript2).transform.position) <= 2.8f)
			{
				mainscript2.thisNetworkObject.Despawn(true);
				((EnemyAI)__instance).creatureVoice.PlayOneShot(__instance.killPlayerSFX);
			}
			else
			{
				if (mainscript2.isEnemyDead || mainscript2 is NutcrackerEnemyAI || mainscript2 is CaveDwellerAI)
				{
					return;
				}
				blobData.timeSinceHittingLocalMonster = 0f;
				if (mainscript2 is FlowermanAI)
				{
					FlowermanAI val = (FlowermanAI)(object)((mainscript2 is FlowermanAI) ? mainscript2 : null);
					if ((Object)(object)val != (Object)null)
					{
						float angerMeter = val.angerMeter;
						bool isInAngerMode = val.isInAngerMode;
						((EnemyAI)val).HitEnemy(1, (PlayerControllerB)null, true, -1);
						if (mainscript2.enemyHP <= 0)
						{
							mainscript2.KillEnemyOnOwnerClient(false);
						}
						((EnemyAI)val).targetPlayer = null;
						((EnemyAI)val).movingTowardsTargetPlayer = false;
						val.isInAngerMode = false;
						val.angerMeter = angerMeter;
						val.isInAngerMode = isInAngerMode;
						return;
					}
				}
				if (mainscript2 is HoarderBugAI)
				{
					HoarderBugAI val2 = (HoarderBugAI)(object)((mainscript2 is HoarderBugAI) ? mainscript2 : null);
					if ((Object)(object)val2 != (Object)null)
					{
						HoarderBugPatch.CustomOnHit(1, (EnemyAI)(object)__instance, playHitSFX: true, val2);
						if (mainscript2.enemyHP <= 0)
						{
							mainscript2.KillEnemyOnOwnerClient(false);
						}
					}
				}
				else
				{
					blobData.timeSinceHittingLocalMonster = 0f;
					mainscript2.HitEnemy(1, (PlayerControllerB)null, true, -1);
					if (mainscript2.enemyHP <= 0)
					{
						mainscript2.KillEnemyOnOwnerClient(false);
					}
				}
			}
		}
	}
	public class OnCollideWithUniversal
	{
		private static bool enableSpider = Script.BoundingConfig.enableSpider.Value;

		private static bool enableSlime = Script.BoundingConfig.enableSlime.Value;

		private static bool logUnspecified = Script.BoundingConfig.debugUnspecified.Value;

		private static bool logSpider = Script.BoundingConfig.debugSpiders.Value;

		private static bool debugSpam = Script.BoundingConfig.spammyLogs.Value;

		public static void Collide(string text, EnemyAI? mainscript, EnemyAI? mainscript2)
		{
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Expected O, but got Unknown
			//IL_0229: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Expected O, but got Unknown
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Expected O, but got Unknown
			//IL_0258: Unknown result type (might be due to invalid IL or missing references)
			//IL_0263: Expected O, but got Unknown
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Expected O, but got Unknown
			if (logUnspecified)
			{
				Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead(mainscript) + "Hit collider of " + EnemyAIPatch.DebugStringHead(mainscript2) + ", Tag: " + text));
			}
			if (!((Object)(object)mainscript != (Object)null) || text == "Player")
			{
			}
			if (!((Object)(object)mainscript != (Object)null) || !((Object)(object)mainscript2 != (Object)null))
			{
				return;
			}
			if (mainscript is SandSpiderAI && !(mainscript2 is SandSpiderAI) && (Object)(object)mainscript2 != (Object)null && enableSpider)
			{
				SandSpiderAI val = (SandSpiderAI)mainscript;
				if (logSpider)
				{
					Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead(mainscript) + " timeSinceHittingPlayer: " + val.timeSinceHittingPlayer));
				}
				if (val.timeSinceHittingPlayer > 1f)
				{
					val.timeSinceHittingPlayer = 0f;
					((EnemyAI)val).creatureSFX.PlayOneShot(val.attackSFX);
					if (mainscript2 is HoarderBugAI)
					{
						if (mainscript2.enemyHP > 2)
						{
							mainscript2.HitEnemy(2, (PlayerControllerB)null, true, -1);
						}
						else if (mainscript2.enemyHP > 0)
						{
							mainscript2.HitEnemy(1, (PlayerControllerB)null, true, -1);
						}
					}
					if (mainscript2 is PufferAI)
					{
						if (mainscript2.enemyHP > 2)
						{
							PufferAIPatch.CustomOnHit(2, mainscript, playHitSFX: true, (PufferAI)mainscript2);
						}
						else if (mainscript2.enemyHP > 0)
						{
							PufferAIPatch.CustomOnHit(1, mainscript, playHitSFX: true, (PufferAI)mainscript2);
						}
					}
					if (logSpider)
					{
						Script.Logger.LogMessage((object)(EnemyAIPatch.DebugStringHead(mainscript) + " Hit " + EnemyAIPatch.DebugStringHead(mainscript2) + ", Tag: " + text));
					}
				}
			}
			if (mainscript is BlobAI && !(mainscript2 is BlobAI) && (Object)(object)mainscript2 != (Object)null && enableSlime)
			{
				BlobAIPatch.OnCustomEnemyCollision((BlobAI)mainscript, mainscript2);
			}
			if (mainscript is RedLocustBees && !(mainscript2 is RedLocustBees) && (Object)(object)mainscript2 != (Object)null)
			{
				BeeAIPatch.OnCustomEnemyCollision((RedLocustBees)mainscript, mainscript2);
			}
		}
	}
	[HarmonyPatch(typeof(EnemyAICollisionDetect), "OnTriggerStay")]
	public class AICollisionDetectPatch
	{
		private static bool Prefix(Collider other, EnemyAICollisionDetect __instance)
		{
			EnemyAICollisionDetect component = ((Component)other).gameObject.GetComponent<EnemyAICollisionDetect>();
			if ((Object)(object)__instance != (Object)null)
			{
				if (((Component)other).CompareTag("Player") && !__instance.mainScript.isEnemyDead)
				{
					OnCollideWithUniversal.Collide("Player", null, null);
					return true;
				}
				if (((Component)other).CompareTag("Enemy") && (Object)(object)component != (Object)null && (Object)(object)component.mainScript != (Object)(object)__instance.mainScript && !IsEnemyImmortal.EnemyIsImmortal(component.mainScript) && !__instance.mainScript.isEnemyDead)
				{
					OnCollideWithUniversal.Collide("Enemy", __instance.mainScript, component.mainScript);
					return true;
				}
			}
			return true;
		}
	}
	public class IsEnemyImmortal
	{
		public static bool EnemyIsImmortal(EnemyAI instance)
		{
			if (instance is NutcrackerEnemyAI && instance.currentBehaviourStateIndex == 0)
			{
				return true;
			}
			if (instance is JesterAI)
			{
				return true;
			}
			if (instance is BlobAI)
			{
				return true;
			}
			if (instance is SpringManAI)
			{
				return true;
			}
			if (instance is SandWormAI)
			{
				return true;
			}
			if (instance is ButlerBeesEnemyAI)
			{
				return true;
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(EnemyAI))]
	internal class EnemyAIPatch
	{
		private static bool debugUnspecified = Script.BoundingConfig.debugUnspecified.Value;

		private static bool debugSpam = Script.BoundingConfig.spammyLogs.Value;

		private static bool debugTriggerFlag = Script.BoundingConfig.debugTriggerFlags.Value;

		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		private static void StartPostfix(EnemyAI __instance)
		{
			if (debugSpam && debugUnspecified)
			{
				Script.Logger.LogInfo((object)"Called Setup library!");
			}
			__instance.agent.radius = __instance.agent.radius * Script.clampedAgentRadius;
		}

		public static string DebugStringHead(EnemyAI? instance)
		{
			return NaturalSelectionLib.DebugStringHead(instance);
		}

		public static List<EnemyAI> GetCompleteList(EnemyAI instance, bool FilterThemselves = true, int includeOrReturnThedDead = 0)
		{
			if (debugSpam && debugTriggerFlag && debugUnspecified)
			{
				Script.Logger.LogInfo((object)"Called library GetCompleteList!");
			}
			return NaturalSelectionLib.GetCompleteList(instance, FilterThemselves, includeOrReturnThedDead);
		}

		public static List<EnemyAI> GetOutsideEnemyList(List<EnemyAI> importEnemyList, EnemyAI instance)
		{
			if (debugSpam && debugTriggerFlag && debugUnspecified)
			{
				Script.Logger.LogInfo((object)"Called library GetOutsideEnemyList!");
			}
			return NaturalSelectionLib.GetOutsideEnemyList(importEnemyList, instance);
		}

		public static List<EnemyAI> GetInsideEnemyList(List<EnemyAI> importEnemyList, EnemyAI instance)
		{
			if (debugSpam && debugTriggerFlag && debugUnspecified)
			{
				Script.Logger.LogInfo((object)"Called library GetInsideEnemyList!");
			}
			return NaturalSelectionLib.GetInsideEnemyList(importEnemyList, instance);
		}

		public static EnemyAI? FindClosestEnemy(List<EnemyAI> importEnemyList, EnemyAI? importClosestEnemy, EnemyAI instance, bool includeTheDead = false)
		{
			if (debugSpam && debugTriggerFlag && debugUnspecified)
			{
				Script.Logger.LogInfo((object)"Called library findClosestEnemy!");
			}
			return NaturalSelectionLib.FindClosestEnemy(importEnemyList, importClosestEnemy, instance, includeTheDead);
		}

		public static List<EnemyAI> FilterEnemyList(List<EnemyAI> importEnemyList, List<Type>? targetTypes, EnemyAI instance, bool inverseToggle = false, bool filterOutImmortal = true)
		{
			if (debugSpam && debugTriggerFlag && debugUnspecified)
			{
				Script.Logger.LogInfo((object)"Called library filterEnemyList!");
			}
			return NaturalSelectionLib.FilterEnemyList(importEnemyList, targetTypes, instance, inverseToggle, filterOutImmortal);
		}

		public static Dictionary<EnemyAI, float> GetEnemiesInLOS(EnemyAI instance, List<EnemyAI> importEnemyList, float width = 45f, int importRange = 0, float proximityAwareness = -1f)
		{
			if (debugSpam && debugTriggerFlag && debugUnspecified)
			{
				Script.Logger.LogInfo((object)"Called library GetEnemiesInLOS!");
			}
			return NaturalSelectionLib.GetEnemiesInLOS(instance, importEnemyList, width, importRange, proximityAwareness);
		}

		public static int ReactToHit(int force = 0, EnemyAI? enemyAI = null, PlayerControllerB? player = null)
		{
			if (force > 0)
			{
				return 1;
			}
			if (force > 1)
			{
				return 2;
			}
			return 0;
		}
	}
	public class ReversePatchEnemy : EnemyAI
	{
		public override void Update()
		{
			((EnemyAI)this).Update();
		}
	}
	internal class GiantData
	{
		public bool logGiant = Script.BoundingConfig.debugGiants.Value;

		private static bool debugSpam = Script.BoundingConfig.spammyLogs.Value;

		public bool? extinguish = null;
	}
	[HarmonyPatch(typeof(ForestGiantAI))]
	internal class ForestGiantPatch
	{
		private static Dictionary<ForestGiantAI, GiantData> giantDictionary = new Dictionary<ForestGiantAI, GiantData>();

		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		private static void startPostfix(ForestGiantAI __instance)
		{
			if (!giantDictionary.ContainsKey(__instance))
			{
				giantDictionary.Add(__instance, new GiantData());
			}
		}

		[HarmonyPatch("KillEnemy")]
		[HarmonyPrefix]
		public static void KillEnemyPatchPrefix(ForestGiantAI __instance, out bool __state)
		{
			GiantData giantData = giantDictionary[__instance];
			if (__instance.burningParticlesContainer.activeSelf)
			{
				__state = true;
			}
			else
			{
				__state = false;
			}
			if (giantData.logGiant)
			{
				Script.Logger.LogInfo((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + " state status: " + __state));
			}
		}

		[HarmonyPatch("KillEnemy")]
		[HarmonyPostfix]
		private static void KillEnemyPatchPostfix(ForestGiantAI __instance, bool __state)
		{
			GiantData giantData = giantDictionary[__instance];
			if (__state)
			{
				__instance.burningParticlesContainer.SetActive(true);
			}
			else
			{
				__instance.burningParticlesContainer.SetActive(false);
			}
			if (giantData.logGiant)
			{
				Script.Logger.LogInfo((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + " state status2: " + __state));
			}
		}

		[HarmonyPatch("Update")]
		[HarmonyPrefix]
		private static bool UpdatePrefix(ForestGiantAI __instance)
		{
			GiantData giantData = giantDictionary[__instance];
			if (((EnemyAI)__instance).currentBehaviourStateIndex == 2 && ((NetworkBehaviour)__instance).IsOwner && Time.realtimeSinceStartup - __instance.timeAtStartOfBurning > 9.5f && ((EnemyAI)__instance).enemyHP > 20 && !giantData.extinguish.HasValue)
			{
				int num = Random.Range(0, 100);
				if (num <= 33)
				{
					((EnemyAI)__instance).enemyHP = ((EnemyAI)__instance).enemyHP - 20;
					__instance.burningParticlesContainer.SetActive(false);
					__instance.giantBurningAudio.Stop();
					((EnemyAI)__instance).creatureAnimator.SetBool("burning", false);
					((EnemyAI)__instance).SwitchToBehaviourState(0);
					giantData.extinguish = true;
					if (giantData.logGiant)
					{
						Script.Logger.LogInfo((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + " successfully extinguished itself. Skipping Update. Rolled " + num));
					}
					return false;
				}
				giantData.extinguish = false;
				if (giantData.logGiant)
				{
					Script.Logger.LogInfo((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + " failed to extinguish itself. rolled " + num));
				}
			}
			return true;
		}

		[HarmonyPatch("Update")]
		[HarmonyPostfix]
		private static void UpdatePostfix(ForestGiantAI __instance)
		{
			if (((EnemyAI)__instance).isEnemyDead && Time.realtimeSinceStartup - __instance.timeAtStartOfBurning < 20f && ((EnemyAI)__instance).currentBehaviourStateIndex == 2)
			{
				if (!__instance.giantBurningAudio.isPlaying)
				{
					__instance.giantBurningAudio.Play();
				}
				__instance.giantBurningAudio.volume = Mathf.Min(__instance.giantBurningAudio.volume + Time.deltaTime * 0.5f, 1f);
			}
			else if (((EnemyAI)__instance).isEnemyDead && Time.realtimeSinceStartup - __instance.timeAtStartOfBurning > 26f)
			{
				__instance.burningParticlesContainer.SetActive(false);
			}
		}
	}
	internal class HoarderBugValues
	{
		public EnemyAI? targetEnemy = null;

		public EnemyAI? closestEnemy = null;

		public bool alertedByEnemy = false;

		public List<EnemyAI> enemies = new List<EnemyAI>();

		public List<EnemyAI> enemiesInLOS = new List<EnemyAI>();
	}
	[HarmonyPatch(typeof(HoarderBugAI))]
	internal class HoarderBugPatch
	{
		private static Dictionary<HoarderBugAI, HoarderBugValues> hoarderBugList = new Dictionary<HoarderBugAI, HoarderBugValues>();

		public static void CustomOnHit(int force, EnemyAI enemyWhoHit, bool playHitSFX, HoarderBugAI __instance)
		{
			((EnemyAI)__instance).enemyHP = ((EnemyAI)__instance).enemyHP - force;
			Script.Logger.LogDebug((object)"Hoarderbug CustomHit Triggered");
			((EnemyAI)__instance).creatureVoice.PlayOneShot(__instance.hitPlayerSFX);
			RoundManager.PlayRandomClip(((EnemyAI)__instance).creatureVoice, __instance.angryScreechSFX, true, 1f, 0, 1000);
			((EnemyAI)__instance).SwitchToBehaviourState(1);
			if (((EnemyAI)__instance).enemyHP <= 0)
			{
				((EnemyAI)__instance).KillEnemy(false);
			}
		}
	}
	internal class NutcrackerData
	{
		public EnemyAI? closestEnemy = null;

		public EnemyAI? targetEnemy = null;

		public bool SeeMovingEnemy = false;

		public Vector3 lastSeenEnemyPosition = Vector3.zero;

		public float TimeSinceSeeingMonster = 0f;

		public float TimeSinceHittingMonster = 0f;
	}
	[HarmonyPatch(typeof(NutcrackerEnemyAI))]
	internal class NutcrackerAIPatch
	{
		private static List<EnemyAI> enemyList = new List<EnemyAI>();

		private static Dictionary<NutcrackerEnemyAI, NutcrackerData> NutcrackerData = new Dictionary<NutcrackerEnemyAI, NutcrackerData>();

		private static bool enableNucracker = Script.BoundingConfig.enableNutcrackers.Value;

		private static bool debugSpam = Script.BoundingConfig.spammyLogs.Value;

		private static bool debugNutcrackers = Script.BoundingConfig.debugNutcrackers.Value;

		public static bool CheckLOSForMonsters(Vector3 monsterPosition, NutcrackerEnemyAI __instance, float width = 45f, int range = 60, int proximityAwareness = 60)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: 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_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			if (Vector3.Distance(monsterPosition, ((EnemyAI)__instance).eye.position) < (float)range && !Physics.Linecast(((EnemyAI)__instance).eye.position, monsterPosition, StartOfRound.Instance.collidersAndRoomMaskAndDefault))
			{
				Vector3 val = monsterPosition - ((EnemyAI)__instance).eye.position;
				if (Vector3.Angle(((EnemyAI)__instance).eye.forward, val) < width || (proximityAwareness != -1 && Vector3.Distance(((EnemyAI)__instance).eye.position, monsterPosition) < (float)proximityAwareness))
				{
					return true;
				}
			}
			return false;
		}

		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		private static void UpdatePatch(NutcrackerEnemyAI __instance)
		{
			if (!NutcrackerData.ContainsKey(__instance))
			{
				NutcrackerData.Add(__instance, new NutcrackerData());
			}
		}

		[HarmonyPatch("Update")]
		[HarmonyPostfix]
		private static void NutcrackerUpdatePostfix(NutcrackerEnemyAI __instance)
		{
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_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_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: 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_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0332: Unknown result type (might be due to invalid IL or missing references)
			//IL_0337: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_031a: Unknown result type (might be due to invalid IL or missing references)
			//IL_031f: Unknown result type (might be due to invalid IL or missing references)
			//IL_027e: 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)
			//IL_029e: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a3: Unknown result type (might be due to invalid IL or missing references)
			if (!enableNucracker)
			{
				return;
			}
			NutcrackerData nutcrackerData = NutcrackerData[__instance];
			enemyList = EnemyAIPatch.GetOutsideEnemyList(EnemyAIPatch.GetCompleteList((EnemyAI)(object)__instance), (EnemyAI)(object)__instance);
			nutcrackerData.closestEnemy = EnemyAIPatch.FindClosestEnemy(enemyList, nutcrackerData.closestEnemy, (EnemyAI)(object)__instance);
			Vector3 velocity;
			if (((EnemyAI)__instance).currentBehaviourStateIndex == 1 && (Object)(object)nutcrackerData.closestEnemy != (Object)null)
			{
				if (__instance.isInspecting && CheckLOSForMonsters(((Component)nutcrackerData.closestEnemy).transform.position, __instance, 70f, 60, 1))
				{
					velocity = nutcrackerData.closestEnemy.agent.velocity;
					if (((Vector3)(ref velocity)).magnitude > 0f)
					{
						__instance.isInspecting = false;
						nutcrackerData.SeeMovingEnemy = true;
						__instance.lastSeenPlayerPos = ((Component)nutcrackerData.closestEnemy).transform.position;
					}
				}
			}
			else
			{
				if (((EnemyAI)__instance).currentBehaviourStateIndex != 2)
				{
					return;
				}
				if (nutcrackerData.SeeMovingEnemy)
				{
					__instance.StopInspection();
				}
				((EnemyAI)__instance).SwitchToBehaviourState(2);
				if (__instance.lostPlayerInChase)
				{
					__instance.targetTorsoDegrees = 0;
				}
				else
				{
					__instance.SetTargetDegreesToPosition(nutcrackerData.lastSeenEnemyPosition);
				}
				if (!((Object)(object)nutcrackerData.targetEnemy != (Object)null))
				{
					return;
				}
				if (((EnemyAI)__instance).CheckLineOfSightForPosition(((Component)nutcrackerData.targetEnemy).transform.position, 70f, 60, 1f, (Transform)null))
				{
					nutcrackerData.TimeSinceSeeingMonster = 0f;
					nutcrackerData.lastSeenEnemyPosition = ((Component)nutcrackerData.targetEnemy).transform.position;
					((EnemyAI)__instance).creatureAnimator.SetBool("AimDown", Vector3.Distance(nutcrackerData.lastSeenEnemyPosition, ((Component)__instance).transform.position) < 2f && nutcrackerData.lastSeenEnemyPosition.y < 1f);
				}
				if (!((EnemyAI)__instance).CheckLineOfSightForPosition(((Component)nutcrackerData.targetEnemy).transform.position, 70f, 25, 1f, (Transform)null))
				{
					return;
				}
				if (Object.op_Implicit((Object)(object)nutcrackerData.targetEnemy) && nutcrackerData.TimeSinceSeeingMonster < 8f && __instance.timeSinceSeeingTarget < 8f)
				{
					if (__instance.timeSinceFiringGun > 0.75f && !__instance.reloadingGun && !__instance.aimingGun && nutcrackerData.TimeSinceHittingMonster > 1f && Vector3.Angle(__instance.gun.shotgunRayPoint.forward, ((Component)nutcrackerData.targetEnemy).transform.position - __instance.gun.shotgunRayPoint.position) < 30f)
					{
						__instance.timeSinceFiringGun = 0f;
						((EnemyAI)__instance).agent.speed = 0f;
						__instance.AimGunServerRpc(((Component)__instance).transform.position);
					}
					if (__instance.lostPlayerInChase)
					{
						__instance.SetLostPlayerInChaseServerRpc(false);
					}
					nutcrackerData.TimeSinceSeeingMonster = 0f;
					nutcrackerData.lastSeenEnemyPosition = ((Component)nutcrackerData.targetEnemy).transform.position;
				}
				else
				{
					velocity = nutcrackerData.targetEnemy.agent.velocity;
					if (((Vector3)(ref velocity)).magnitude > 0f)
					{
						nutcrackerData.TimeSinceSeeingMonster = 0f;
					}
				}
			}
		}

		[HarmonyPatch("DoAIInterval")]
		[HarmonyPostfix]
		private static void DoAIIntervalPatch(NutcrackerEnemyAI __instance)
		{
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			if (!enableNucracker)
			{
				return;
			}
			NutcrackerData nutcrackerData = NutcrackerData[__instance];
			if (((EnemyAI)__instance).currentBehaviourStateIndex != 2 || !((Object)(object)nutcrackerData.targetEnemy != (Object)null))
			{
				return;
			}
			if (nutcrackerData.TimeSinceSeeingMonster < 0.5f && __instance.timeSinceSeeingTarget < 0.5f)
			{
				if (__instance.attackSearch.inProgress)
				{
					((EnemyAI)__instance).StopSearch(__instance.attackSearch, true);
				}
				__instance.reachedStrafePosition = false;
				((EnemyAI)__instance).SetDestinationToPosition(((Component)nutcrackerData.targetEnemy).transform.position, false);
				((EnemyAI)__instance).agent.stoppingDistance = 1f;
				((EnemyAI)__instance).moveTowardsDestination = true;
			}
			if (nutcrackerData.TimeSinceSeeingMonster > 12f && __instance.timeSinceSeeingTarget > 12f)
			{
				((EnemyAI)__instance).SwitchToBehaviourState(1);
			}
		}
	}
	internal class PufferData
	{
		public int reactionToHit = 0;

		public EnemyAI? targetEnemy = null;
	}
	[HarmonyPatch(typeof(PufferAI))]
	internal class PufferAIPatch
	{
		private static bool enableSporeLizard = Script.BoundingConfig.enableSporeLizard.Value;

		private static Dictionary<PufferAI, PufferData> pufferList = new Dictionary<PufferAI, PufferData>();

		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		private static void StartPostfix(PufferAI __instance)
		{
			if (!pufferList.ContainsKey(__instance))
			{
				pufferList.Add(__instance, new PufferData());
			}
		}

		[HarmonyPatch("DoAIInterval")]
		[HarmonyPrefix]
		private static bool PrefixAIInterval(PufferAI __instance)
		{
			//IL_002f: 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_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			PufferData pufferData = pufferList[__instance];
			if (((EnemyAI)__instance).currentBehaviourStateIndex == 2 && (Object)(object)pufferData.targetEnemy != (Object)null && Vector3.Distance(((Component)__instance.closestSeenPlayer).transform.position, ((Component)__instance).transform.position) < Vector3.Distance(((Component)pufferData.targetEnemy).transform.position, ((Component)__instance).transform.position))
			{
				if (((EnemyAI)__instance).moveTowardsDestination)
				{
					((EnemyAI)__instance).agent.SetDestination(((EnemyAI)__instance).destination);
				}
				((EnemyAI)__instance).SyncPositionToClients();
				return false;
			}
			return true;
		}

		[HarmonyPatch("DoAIInterval")]
		[HarmonyPostfix]
		private static void PostfixAIInterval(PufferAI __instance)
		{
			//IL_002f: 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_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			PufferData pufferData = pufferList[__instance];
			if (((EnemyAI)__instance).currentBehaviourStateIndex == 2 && (Object)(object)pufferData.targetEnemy != (Object)null && Vector3.Distance(((Component)__instance.closestSeenPlayer).transform.position, ((Component)__instance).transform.position) < Vector3.Distance(((Component)pufferData.targetEnemy).transform.position, ((Component)__instance).transform.position))
			{
				((EnemyAI)__instance).SetDestinationToPosition(((Component)pufferData.targetEnemy).transform.position, true);
			}
			else
			{
				pufferData.reactionToHit = 0;
			}
		}

		public static void CustomOnHit(int force, EnemyAI enemyWhoHit, bool playHitSFX, PufferAI instance)
		{
			if (enableSporeLizard)
			{
				PufferData pufferData = pufferList[instance];
				((EnemyAI)instance).creatureAnimator.SetBool("alerted", true);
				((EnemyAI)instance).enemyHP = ((EnemyAI)instance).enemyHP - force;
				Script.Logger.LogDebug((object)"SpodeLizard CustomHit Triggered");
				HitEnemyTest(force, enemyWhoHit, playHitSFX, instance);
				((EnemyAI)instance).SwitchToBehaviourState(2);
				if (((EnemyAI)instance).enemyHP <= 0)
				{
					((EnemyAI)instance).KillEnemy(true);
				}
			}
		}

		public static void HitEnemyTest(int force, EnemyAI enemyWhoHit, bool playHitSFX, PufferAI instance)
		{
			int num = EnemyAIPatch.ReactToHit(force);
			if (enemyWhoHit is SandSpiderAI)
			{
				pufferList[instance].reactionToHit = 2;
			}
			else
			{
				pufferList[instance].reactionToHit = 1;
			}
		}
	}
	internal class SpiderData
	{
		public EnemyAI? closestEnemy = null;

		public EnemyAI? targetEnemy = null;

		public List<EnemyAI> knownEnemy = new List<EnemyAI>();

		public List<EnemyAI> deadEnemyBodies = new List<EnemyAI>();

		public float LookAtEnemyTimer = 0f;

		public Dictionary<EnemyAI, float> enemiesInLOSDictionary = new Dictionary<EnemyAI, float>();
	}
	[HarmonyPatch]
	internal class Reversepatch
	{
		[HarmonyReversePatch(/*Could not decode attribute arguments.*/)]
		[HarmonyPatch(typeof(EnemyAI), "Update")]
		public static void ReverseUpdate(SandSpiderAI instance)
		{
		}
	}
	[HarmonyPatch(typeof(SandSpiderAI))]
	internal class SandSpiderAIPatch
	{
		private static float refreshCDtimeSpider = 1f;

		private static bool enableSpider = Script.BoundingConfig.enableSpider.Value;

		private static bool spiderHuntHoardingbug = Script.BoundingConfig.spiderHuntHoardingbug.Value;

		private static Dictionary<SandSpiderAI, SpiderData> spiderList = new Dictionary<SandSpiderAI, SpiderData>();

		private static bool debugSpider = Script.BoundingConfig.debugSpiders.Value;

		private static bool debugSpam = Script.BoundingConfig.spammyLogs.Value;

		[HarmonyPatch("Start")]
		[HarmonyPrefix]
		private static void StartPatch(SandSpiderAI __instance)
		{
			if (!spiderList.ContainsKey(__instance))
			{
				spiderList.Add(__instance, new SpiderData());
				SpiderData spiderData = spiderList[__instance];
			}
		}

		[HarmonyPatch("Update")]
		[HarmonyPrefix]
		private static bool UpdatePrefixPatch(SandSpiderAI __instance)
		{
			//IL_0338: Unknown result type (might be due to invalid IL or missing references)
			//IL_040a: Unknown result type (might be due to invalid IL or missing references)
			//IL_041a: Unknown result type (might be due to invalid IL or missing references)
			//IL_047b: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_04fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0613: Unknown result type (might be due to invalid IL or missing references)
			//IL_0626: Unknown result type (might be due to invalid IL or missing references)
			//IL_0631: Unknown result type (might be due to invalid IL or missing references)
			//IL_0641: Unknown result type (might be due to invalid IL or missing references)
			//IL_07aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0695: Unknown result type (might be due to invalid IL or missing references)
			//IL_069a: Unknown result type (might be due to invalid IL or missing references)
			//IL_069d: Unknown result type (might be due to invalid IL or missing references)
			//IL_06de: Unknown result type (might be due to invalid IL or missing references)
			//IL_06ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_08b6: 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_075e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0769: Unknown result type (might be due to invalid IL or missing references)
			//IL_08dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_08e8: Unknown result type (might be due to invalid IL or missing references)
			if (!enableSpider)
			{
				return true;
			}
			SpiderData spiderData = spiderList[__instance];
			if (RoundManagerPatch.RequestUpdate((EnemyAI)(object)__instance))
			{
				RoundManagerPatch.ScheduleGlobalListUpdate((EnemyAI)(object)__instance, EnemyAIPatch.GetInsideEnemyList(EnemyAIPatch.GetCompleteList((EnemyAI)(object)__instance), (EnemyAI)(object)__instance));
			}
			spiderData.enemiesInLOSDictionary = EnemyAIPatch.GetEnemiesInLOS((EnemyAI)(object)__instance, NaturalSelectionLib.globalEnemyLists[((object)__instance).GetType()], 80f, 15, 2f);
			if (spiderData.enemiesInLOSDictionary.Count > 0)
			{
				foreach (KeyValuePair<EnemyAI, float> item in spiderData.enemiesInLOSDictionary)
				{
					if (item.Key.isEnemyDead)
					{
						if (debugSpider)
						{
							Script.Logger.LogWarning((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + " Update Postfix: " + ((object)item.Key)?.ToString() + " is Dead! Checking deadEnemyBodies list and skipping..."));
						}
						if (!spiderData.deadEnemyBodies.Contains(item.Key))
						{
							spiderData.deadEnemyBodies.Add(item.Key);
							if (debugSpider)
							{
								Script.Logger.LogWarning((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + " Update Postfix: " + ((object)item.Key)?.ToString() + " added to deadEnemyBodies list"));
							}
						}
					}
					else if (spiderData.knownEnemy.Contains(item.Key))
					{
						if (debugSpider && debugSpam)
						{
							Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + " Update Postfix: " + ((object)item.Key)?.ToString() + " is already in knownEnemyList"));
						}
					}
					else
					{
						if (debugSpider)
						{
							Script.Logger.LogInfo((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + " Update Postfix: Adding " + ((object)item.Key)?.ToString() + " to knownEnemyList"));
						}
						spiderData.knownEnemy.Add(item.Key);
					}
				}
				for (int i = 0; i < spiderData.knownEnemy.Count; i++)
				{
					if (spiderData.knownEnemy[i].isEnemyDead)
					{
						if (debugSpider)
						{
							Script.Logger.LogWarning((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + " Update Postfix: Removed " + ((object)spiderData.knownEnemy[i])?.ToString() + " from knownEnemyList"));
						}
						spiderData.knownEnemy.Remove(spiderData.knownEnemy[i]);
					}
				}
			}
			__instance.SyncMeshContainerPositionToClients();
			__instance.CalculateMeshMovement();
			switch (((EnemyAI)__instance).currentBehaviourStateIndex)
			{
			case 0:
				spiderData.closestEnemy = EnemyAIPatch.FindClosestEnemy(spiderData.knownEnemy, spiderData.closestEnemy, (EnemyAI)(object)__instance);
				if ((Object)(object)spiderData.closestEnemy != (Object)null && ((EnemyAI)__instance).CheckLineOfSightForPosition(((Component)spiderData.closestEnemy).transform.position, 80f, 15, 2f, ((EnemyAI)__instance).eye) && !spiderData.closestEnemy.isEnemyDead)
				{
					spiderData.targetEnemy = spiderData.closestEnemy;
					if (debugSpider)
					{
						Script.Logger.LogInfo((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "Update Postfix: /case0/ Set " + ((object)spiderData.closestEnemy)?.ToString() + " as TargetEnemy"));
					}
					((EnemyAI)__instance).SwitchToBehaviourState(2);
					if (debugSpider)
					{
						Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "Update Postfix: /case0/ Set state to " + ((EnemyAI)__instance).currentBehaviourStateIndex));
					}
					__instance.chaseTimer = 12.5f;
					__instance.watchFromDistance = Vector3.Distance(((Component)__instance.meshContainer).transform.position, ((Component)spiderData.closestEnemy).transform.position) > 8f;
				}
				break;
			case 2:
				if ((Object)(object)((EnemyAI)__instance).targetPlayer != (Object)null)
				{
					break;
				}
				if ((Object)(object)spiderData.targetEnemy != (Object)(object)spiderData.closestEnemy && (Object)(object)spiderData.closestEnemy != (Object)null && ((EnemyAI)__instance).CheckLineOfSightForPosition(((Component)spiderData.closestEnemy).transform.position, 80f, 15, 2f, ((EnemyAI)__instance).eye))
				{
					if (spiderData.targetEnemy is HoarderBugAI && !(spiderData.closestEnemy is HoarderBugAI) && Vector3.Distance(__instance.meshContainer.position, ((Component)spiderData.targetEnemy).transform.position) * 1.2f < Vector3.Distance(__instance.meshContainer.position, ((Component)spiderData.closestEnemy).transform.position))
					{
						spiderData.targetEnemy = spiderData.closestEnemy;
					}
					else
					{
						spiderData.targetEnemy = spiderData.closestEnemy;
					}
				}
				if ((Object)(object)spiderData.targetEnemy == (Object)null)
				{
					if (debugSpider)
					{
						Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "Update Postfix: /case2-0/ Stopping chasing: " + (object)spiderData.targetEnemy));
					}
					spiderData.targetEnemy = null;
					__instance.StopChasing(false);
					break;
				}
				if (__instance.onWall)
				{
					((EnemyAI)__instance).SetDestinationToPosition(((Component)spiderData.targetEnemy).transform.position, false);
					((EnemyAI)__instance).agent.speed = 4.25f;
					__instance.spiderSpeed = 4.25f;
					if (debugSpider)
					{
						Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "Update Postfix: /case2/ onWall"));
					}
					break;
				}
				if (__instance.watchFromDistance && (Object)(object)((EnemyAI)__instance).GetClosestPlayer(true, false, false) != (Object)null && Vector3.Distance(__instance.meshContainerPosition, ((Component)((EnemyAI)__instance).GetClosestPlayer(true, false, false)).transform.position) > Vector3.Distance(__instance.meshContainerPosition, ((Component)spiderData.targetEnemy).transform.position))
				{
					if (spiderData.LookAtEnemyTimer <= 0f)
					{
						spiderData.LookAtEnemyTimer = 3f;
						((EnemyAI)__instance).movingTowardsTargetPlayer = false;
						__instance.overrideSpiderLookRotation = true;
						Vector3 position = ((Component)spiderData.targetEnemy).transform.position;
						__instance.SetSpiderLookAtPosition(position);
					}
					else
					{
						spiderData.LookAtEnemyTimer -= Time.deltaTime;
					}
					__instance.spiderSpeed = 0f;
					((EnemyAI)__instance).agent.speed = 0f;
					if (Physics.Linecast(__instance.meshContainer.position, ((Component)spiderData.targetEnemy).transform.position, StartOfRound.Instance.collidersAndRoomMaskAndDefault))
					{
						if (debugSpider)
						{
							Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "Update Postfix: /case2-1/ Stopping chasing: " + (object)spiderData.targetEnemy));
						}
						spiderData.targetEnemy = null;
						__instance.StopChasing(false);
					}
					else if (Vector3.Distance(((Component)spiderData.targetEnemy).transform.position, __instance.meshContainer.position) < 5f || ((EnemyAI)__instance).stunNormalizedTimer > 0f)
					{
						__instance.watchFromDistance = false;
					}
					break;
				}
				((EnemyAI)__instance).SetDestinationToPosition(((Component)spiderData.targetEnemy).transform.position, false);
				if ((Object)(object)spiderData.targetEnemy == (Object)null || spiderData.targetEnemy.isEnemyDead)
				{
					if (debugSpider)
					{
						Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "Update Postfix: /case2-2/ Stopping chasing: " + (object)spiderData.targetEnemy));
					}
					if ((Object)(object)spiderData.targetEnemy != (Object)null)
					{
						try
						{
							spiderData.deadEnemyBodies.Add(spiderData.targetEnemy);
							spiderData.knownEnemy.Remove(spiderData.targetEnemy);
							if (debugSpider)
							{
								Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "Update Postfix: /case2-2/ Moved dead enemy to separate list"));
							}
						}
						catch
						{
							Script.Logger.LogError((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "Update Postfix: /case2-2/ Enemy does not exist!"));
						}
					}
					spiderData.targetEnemy = null;
					__instance.StopChasing(false);
				}
				else
				{
					if (!(Vector3.Distance(((Component)spiderData.targetEnemy).transform.position, __instance.homeNode.position) > 12f) || !(Vector3.Distance(((Component)spiderData.targetEnemy).transform.position, __instance.meshContainer.position) > 5f))
					{
						break;
					}
					__instance.chaseTimer -= Time.deltaTime;
					if (__instance.chaseTimer <= 0f)
					{
						if (debugSpider)
						{
							Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "Update Postfix: /case2-3/ Stopping chasing: " + (object)spiderData.targetEnemy));
						}
						spiderData.targetEnemy = null;
						__instance.StopChasing(false);
					}
				}
				break;
			}
			if (refreshCDtimeSpider <= 0f)
			{
				if (debugSpider && debugSpam)
				{
					Script.Logger.LogInfo((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "watchFromDistance: " + __instance.watchFromDistance));
					Script.Logger.LogInfo((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "overrideSpiderLookRotation: " + __instance.overrideSpiderLookRotation));
					Script.Logger.LogInfo((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "moveTowardsDestination: " + ((EnemyAI)__instance).moveTowardsDestination));
					Script.Logger.LogInfo((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "movingTowardsTargetPlayer: " + ((EnemyAI)__instance).movingTowardsTargetPlayer));
				}
				refreshCDtimeSpider = 0.5f;
			}
			else
			{
				refreshCDtimeSpider -= Time.deltaTime;
			}
			if ((Object)(object)spiderData.targetEnemy != (Object)null && !Object.op_Implicit((Object)(object)((EnemyAI)__instance).targetPlayer) && ((EnemyAI)__instance).currentBehaviourStateIndex == 2)
			{
				Reversepatch.ReverseUpdate(__instance);
				if (((EnemyAI)__instance).updateDestinationInterval >= 0f)
				{
					((EnemyAI)__instance).updateDestinationInterval = ((EnemyAI)__instance).updateDestinationInterval - Time.deltaTime;
				}
				else
				{
					((EnemyAI)__instance).updateDestinationInterval = ((EnemyAI)__instance).AIIntervalTime + Random.Range(-0.015f, 0.015f);
					((EnemyAI)__instance).DoAIInterval();
				}
				__instance.timeSinceHittingPlayer += Time.deltaTime;
				return false;
			}
			return true;
		}

		[HarmonyPatch("DoAIInterval")]
		[HarmonyPrefix]
		private static bool DoAIIntervalPrefix(SandSpiderAI __instance)
		{
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			if (!spiderHuntHoardingbug)
			{
				return true;
			}
			SpiderData spiderData = spiderList[__instance];
			if ((Object)(object)spiderData.targetEnemy != (Object)null && !Object.op_Implicit((Object)(object)((EnemyAI)__instance).targetPlayer) && ((EnemyAI)__instance).currentBehaviourStateIndex == 2)
			{
				if (((EnemyAI)__instance).moveTowardsDestination)
				{
					((EnemyAI)__instance).agent.SetDestination(((EnemyAI)__instance).destination);
				}
				((EnemyAI)__instance).SyncPositionToClients();
				if (debugSpider && debugSpam)
				{
					Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "DoAIInterval Prefix: false"));
				}
				return false;
			}
			if (debugSpider && debugSpam)
			{
				Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "DoAIInterval Prefix: true"));
			}
			return true;
		}

		[HarmonyPatch("DoAIInterval")]
		[HarmonyPostfix]
		private static void DoAIIntervalPostfix(SandSpiderAI __instance)
		{
			//IL_02e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: 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_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			SpiderData spiderData = spiderList[__instance];
			switch (((EnemyAI)__instance).currentBehaviourStateIndex)
			{
			case 0:
				if (debugSpider && debugSpam)
				{
					Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "DoAIInterval Postfix: /case0/ nothing"));
				}
				break;
			case 1:
			{
				if (debugSpider && debugSpam)
				{
					Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "DoAIInterval Postfix: /case1/"));
				}
				List<EnemyAI> list = spiderData.enemiesInLOSDictionary.Keys.ToList();
				if (__instance.reachedWallPosition)
				{
					for (int i = 0; i < list.Count; i++)
					{
						if (Vector3.Distance(__instance.meshContainer.position, ((Component)list[i]).transform.position) < 5f || list[i] is HoarderBugAI)
						{
							ChaseEnemy(__instance, list[i]);
							if (debugSpider)
							{
								Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "DoAIInterval Postfix: /case1/ Chasing enemy: " + (object)list[i]));
							}
							break;
						}
						if (Vector3.Distance(__instance.meshContainer.position, ((Component)list[i]).transform.position) < 10f)
						{
							Vector3 position = ((Component)list[i]).transform.position;
							float num = Vector3.Dot(position - __instance.meshContainer.position, __instance.wallNormal);
							Vector3 val = position - num * __instance.wallNormal;
							__instance.meshContainerTargetRotation = Quaternion.LookRotation(val, __instance.wallNormal);
							__instance.overrideSpiderLookRotation = true;
							if (debugSpider)
							{
								Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "DoAIInterval Postfix: /case1/ Moving off-wall to enemy: " + (object)list[i]));
							}
							break;
						}
					}
				}
				__instance.overrideSpiderLookRotation = false;
				break;
			}
			case 2:
				if (!((Object)(object)spiderData.targetEnemy != (Object)null))
				{
					break;
				}
				if (spiderData.targetEnemy.isEnemyDead)
				{
					if (debugSpider)
					{
						Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "DoAIInterval Postfix: /case2/ Stopping chasing: " + (object)spiderData.targetEnemy));
					}
					spiderData.targetEnemy = null;
					__instance.StopChasing(false);
				}
				else if (__instance.watchFromDistance)
				{
					((EnemyAI)__instance).SetDestinationToPosition(((Component)((EnemyAI)__instance).ChooseClosestNodeToPosition(((Component)spiderData.targetEnemy).transform.position, false, 4)).transform.position, false);
					if (debugSpider)
					{
						Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "DoAIInterval Postfix: /case2/ Set destination to: " + (object)spiderData.targetEnemy));
					}
				}
				break;
			}
		}

		private static void ChaseEnemy(SandSpiderAI ins, EnemyAI target, SandSpiderWebTrap? triggeredWeb = null)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			SpiderData spiderData = spiderList[ins];
			if ((((EnemyAI)ins).currentBehaviourStateIndex != 2 && ins.watchFromDistance) || Vector3.Distance(((Component)target).transform.position, ins.homeNode.position) < 25f || Vector3.Distance(ins.meshContainer.position, ((Component)target).transform.position) < 15f)
			{
				ins.watchFromDistance = false;
				spiderData.targetEnemy = target;
				ins.chaseTimer = 12.5f;
				((EnemyAI)ins).SwitchToBehaviourState(2);
				if (debugSpider)
				{
					Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)ins) + "ChaseEnemy: Switched state to: " + ((EnemyAI)ins).currentBehaviourStateIndex));
				}
			}
		}
	}
	internal class SpiderWebValues
	{
		public struct EnemyInfo
		{
			internal EnemyAI enemyAI { get; set; }

			internal float enterAgentSpeed { get; set; }

			internal float enterAnimationSpeed { get; set; }

			public EnemyInfo(EnemyAI enemy, float enterAgentSpeed, float enterAnimationSpeed)
			{
				enemyAI = enemy;
				this.enterAgentSpeed = enterAgentSpeed;
				this.enterAnimationSpeed = enterAnimationSpeed;
			}
		}

		public Dictionary<EnemyAI, EnemyInfo> collidingEnemy = new Dictionary<EnemyAI, EnemyInfo>();
	}
	[HarmonyPatch(typeof(SandSpiderWebTrap))]
	internal class SandSpiderWebTrapPatch
	{
		private static Dictionary<SandSpiderWebTrap, SpiderWebValues> spiderWebs = new Dictionary<SandSpiderWebTrap, SpiderWebValues>();

		[HarmonyPatch("Awake")]
		[HarmonyPostfix]
		private static void AwakePostfix(SandSpiderWebTrap __instance)
		{
			if (!spiderWebs.ContainsKey(__instance))
			{
				spiderWebs.Add(__instance, new SpiderWebValues());
			}
		}

		[HarmonyPatch("OnTriggerStay")]
		[HarmonyPostfix]
		private static void OnTriggerStayPatch(Collider other, SandSpiderWebTrap __instance)
		{
			SpiderWebValues spiderWebValues = spiderWebs[__instance];
			EnemyAI mainScript = ((Component)other).gameObject.GetComponent<EnemyAICollisionDetect>().mainScript;
			if (Script.BoundingConfig.debugSpiders.Value)
			{
				Script.Logger.LogInfo((object)(((object)__instance)?.ToString() + " Triggered"));
			}
			if ((Object)(object)mainScript != (Object)null)
			{
				if (Script.BoundingConfig.debugSpiders.Value)
				{
					Script.Logger.LogInfo((object)(((object)__instance)?.ToString() + " Collided with " + (object)mainScript));
				}
				if (!spiderWebValues.collidingEnemy.ContainsKey(mainScript))
				{
					spiderWebValues.collidingEnemy.Add(mainScript, new SpiderWebValues.EnemyInfo(mainScript, mainScript.agent.speed, mainScript.creatureAnimator.speed));
					if (Script.BoundingConfig.debugSpiders.Value)
					{
						Script.Logger.LogInfo((object)(((object)__instance)?.ToString() + " Added " + ((object)mainScript)?.ToString() + " to collidingEnemy"));
					}
				}
				mainScript.agent.speed = spiderWebValues.collidingEnemy[mainScript].enterAgentSpeed / 3f;
				mainScript.creatureAnimator.speed = spiderWebValues.collidingEnemy[mainScript].enterAnimationSpeed / 3f;
				if (Script.BoundingConfig.debugSpiders.Value)
				{
					Script.Logger.LogInfo((object)(((object)__instance)?.ToString() + " Slowed down " + (object)mainScript));
				}
				if (!__instance.webAudio.isPlaying)
				{
					__instance.webAudio.Play();
					__instance.webAudio.PlayOneShot(__instance.mainScript.hitWebSFX);
				}
			}
			if ((Object)(object)mainScript == (Object)null)
			{
				spiderWebValues.collidingEnemy.Clear();
				if (Script.BoundingConfig.debugSpiders.Value)
				{
					Script.Logger.LogInfo((object)(((object)__instance)?.ToString() + " Cleared " + ((object)mainScript)?.ToString() + " from collidingEnemy"));
				}
				if (__instance.webAudio.isPlaying && (Object)(object)__instance.currentTrappedPlayer == (Object)null)
				{
					__instance.webAudio.Stop();
				}
			}
		}

		[HarmonyPatch("Update")]
		[HarmonyPrefix]
		private static bool UpdatePrefix(SandSpiderWebTrap __instance, out bool __state)
		{
			SpiderWebValues spiderWebValues = spiderWebs[__instance];
			if ((Object)(object)__instance.currentTrappedPlayer != (Object)null)
			{
				__state = false;
				return true;
			}
			if (spiderWebValues.collidingEnemy.Count > 0)
			{
				__state = true;
				return false;
			}
			__state = false;
			return true;
		}

		[HarmonyPatch("Update")]
		[HarmonyPostfix]
		private static void UpdatePostfix(SandSpiderWebTrap __instance, bool __state)
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			if (__state)
			{
				SpiderWebValues spiderWebValues = spiderWebs[__instance];
				if (spiderWebValues.collidingEnemy.Count > 0)
				{
					__instance.leftBone.LookAt(((Component)spiderWebValues.collidingEnemy.First().Key).transform.position);
					__instance.rightBone.LookAt(((Component)spiderWebValues.collidingEnemy.First().Key).transform.position);
				}
				else
				{
					__instance.leftBone.LookAt(__instance.centerOfWeb);
					__instance.rightBone.LookAt(__instance.centerOfWeb);
				}
				((Component)__instance).transform.localScale = Vector3.Lerp(((Component)__instance).transform.localScale, new Vector3(1f, 1f, __instance.zScale), 8f * Time.deltaTime);
			}
		}
	}
	internal class ExtendedSandWormAIData
	{
		public float refreshCDtime = 0.5f;

		public EnemyAI? closestEnemy = null;

		public EnemyAI? targetEnemy = null;

		public int targetingEntity = 0;
	}
	[HarmonyPatch]
	internal class ReversepatchWorm
	{
		[HarmonyReversePatch(/*Could not decode attribute arguments.*/)]
		[HarmonyPatch(typeof(EnemyAI), "Update")]
		public static void WormReverseUpdate(SandWormAI instance)
		{
		}
	}
	[HarmonyPatch(typeof(SandWormAI))]
	internal class SandWormAIPatch
	{
		private static List<Type> targetedTypes = new List<Type>();

		private static bool debugSandworm = Script.BoundingConfig.debugSandworms.Value;

		private static bool debugSpam = Script.BoundingConfig.spammyLogs.Value;

		private static bool triggerFlag = Script.BoundingConfig.debugTriggerFlags.Value;

		private static Dictionary<SandWormAI, ExtendedSandWormAIData> sandworms = new Dictionary<SandWormAI, ExtendedSandWormAIData>();

		[HarmonyPatch("Start")]
		[HarmonyPrefix]
		private static void SandWormStartPatch(SandWormAI __instance)
		{
			if (!sandworms.ContainsKey(__instance))
			{
				sandworms.Add(__instance, new ExtendedSandWormAIData());
				if (targetedTypes.Count == 0)
				{
					targetedTypes.Add(typeof(BaboonBirdAI));
					targetedTypes.Add(typeof(ForestGiantAI));
					targetedTypes.Add(typeof(MouthDogAI));
					targetedTypes.Add(typeof(BushWolfEnemy));
					targetedTypes.Add(typeof(RadMechAI));
				}
			}
		}

		[HarmonyPatch("Update")]
		[HarmonyPrefix]
		private static bool SandWormPrefixUpdatePatch(SandWormAI __instance)
		{
			ExtendedSandWormAIData extendedSandWormAIData = sandworms[__instance];
			if (extendedSandWormAIData.refreshCDtime <= 0f)
			{
				if (RoundManagerPatch.RequestUpdate((EnemyAI)(object)__instance))
				{
					RoundManagerPatch.ScheduleGlobalListUpdate((EnemyAI)(object)__instance, EnemyAIPatch.FilterEnemyList(EnemyAIPatch.GetOutsideEnemyList(EnemyAIPatch.GetCompleteList((EnemyAI)(object)__instance), (EnemyAI)(object)__instance), targetedTypes, (EnemyAI)(object)__instance));
				}
				extendedSandWormAIData.closestEnemy = EnemyAIPatch.FindClosestEnemy(NaturalSelectionLib.globalEnemyLists[((object)__instance).GetType()], extendedSandWormAIData.closestEnemy, (EnemyAI)(object)__instance);
				extendedSandWormAIData.refreshCDtime = 0.2f;
			}
			if (extendedSandWormAIData.refreshCDtime > 0f)
			{
				extendedSandWormAIData.refreshCDtime -= Time.deltaTime;
			}
			switch (extendedSandWormAIData.targetingEntity)
			{
			case 0:
				if (__instance.inEmergingState || __instance.emerged)
				{
					return false;
				}
				break;
			case 1:
				if (!((Object)(object)extendedSandWormAIData.targetEnemy != (Object)null) || ((EnemyAI)__instance).movingTowardsTargetPlayer)
				{
					break;
				}
				if (((EnemyAI)__instance).updateDestinationInterval >= 0f)
				{
					((EnemyAI)__instance).updateDestinationInterval = ((EnemyAI)__instance).updateDestinationInterval - Time.deltaTime;
				}
				else
				{
					if (debugSandworm && debugSpam)
					{
						Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + " calling DoAIInterval"));
					}
					((EnemyAI)__instance).DoAIInterval();
					((EnemyAI)__instance).updateDestinationInterval = ((EnemyAI)__instance).AIIntervalTime + Random.Range(-0.015f, 0.015f);
				}
				return false;
			}
			if (debugSandworm && triggerFlag)
			{
				Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + " Prefix/2/ targetEnemy: " + ((object)extendedSandWormAIData.targetEnemy)?.ToString() + ", target: " + (object)extendedSandWormAIData.targetEnemy));
			}
			return true;
		}

		[HarmonyPatch("Update")]
		[HarmonyPostfix]
		private static void SandWormPostfixUpdatePatch(SandWormAI __instance)
		{
			//IL_0257: Unknown result type (might be due to invalid IL or missing references)
			//IL_0262: Unknown result type (might be due to invalid IL or missing references)
			ExtendedSandWormAIData extendedSandWormAIData = sandworms[__instance];
			if (!Script.BoundingConfig.enableLeviathan.Value)
			{
				return;
			}
			if (debugSandworm && debugSpam)
			{
				Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + " Postfix targetingEntity: " + extendedSandWormAIData.targetingEntity));
			}
			switch (extendedSandWormAIData.targetingEntity)
			{
			case 0:
				if (!((EnemyAI)__instance).movingTowardsTargetPlayer && !__instance.inEmergingState && !__instance.emerged && ((EnemyAI)__instance).creatureSFX.isPlaying)
				{
					((EnemyAI)__instance).creatureSFX.Stop();
					if (debugSandworm)
					{
						Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + " stopping Sounds"));
					}
				}
				break;
			case 1:
				if (debugSandworm && (Object)(object)extendedSandWormAIData.closestEnemy != (Object)null)
				{
					Script.Logger.LogInfo((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "closestEnemy is " + EnemyAIPatch.DebugStringHead(extendedSandWormAIData.closestEnemy) + ", isEnemyDead: " + extendedSandWormAIData.closestEnemy.isEnemyDead + " /3/"));
				}
				if (((EnemyAI)__instance).movingTowardsTargetPlayer)
				{
					break;
				}
				if (!((EnemyAI)__instance).creatureSFX.isPlaying && !__instance.inEmergingState && !__instance.emerged)
				{
					int num = Random.Range(0, __instance.ambientRumbleSFX.Length);
					((EnemyAI)__instance).creatureSFX.clip = __instance.ambientRumbleSFX[num];
					((EnemyAI)__instance).creatureSFX.Play();
					if (debugSandworm)
					{
						Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + " Started playing sounds"));
					}
				}
				if (!((NetworkBehaviour)__instance).IsOwner)
				{
					break;
				}
				if ((Object)(object)extendedSandWormAIData.targetEnemy == (Object)null)
				{
					if (debugSandworm)
					{
						Script.Logger.LogError((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + " TargetEnemy is null! TargetingEntity set to false /Trigger 1/"));
					}
					extendedSandWormAIData.targetingEntity = 0;
					break;
				}
				if (Vector3.Distance(((Component)extendedSandWormAIData.targetEnemy).transform.position, ((Component)__instance).transform.position) > 22f)
				{
					__instance.chaseTimer += Time.deltaTime;
					if (debugSandworm && debugSpam)
					{
						Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + " updated chaseTimer: " + __instance.chaseTimer));
					}
				}
				else
				{
					__instance.chaseTimer = 0f;
					if (debugSandworm)
					{
						Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + " Reset chasetimer"));
					}
				}
				if (__instance.chaseTimer > 6f)
				{
					if (debugSandworm)
					{
						Script.Logger.LogInfo((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + " Chasing for too long. targetEnemy set to null"));
					}
					extendedSandWormAIData.targetingEntity = 0;
					extendedSandWormAIData.targetEnemy = null;
				}
				break;
			}
		}

		[HarmonyPatch("DoAIInterval")]
		[HarmonyPrefix]
		private static bool SandWormDoAIIntervalPrefix(SandWormAI __instance)
		{
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_051d: Unknown result 

DLLs/fandovec03.NaturalSelectionLib.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Fandovec03")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Personal Library with functions for getting, sorting and filtering enemies")]
[assembly: AssemblyFileVersion("0.4.1.0")]
[assembly: AssemblyInformationalVersion("0.4.1-alpha3+fc400a91e6007e7808bd45c22ac5a15d9f39c575")]
[assembly: AssemblyProduct("NaturalSelectionLib")]
[assembly: AssemblyTitle("fandovec03.NaturalSelectionLib")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/Fandovec03/NaturalSelectionLib.git")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.4.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace NaturalSelectionLib
{
	[BepInPlugin("fandovec03.NaturalSelectionLib", "NaturalSelectionLib", "0.4.1-alpha3")]
	public class NaturalSelectionLib : BaseUnityPlugin
	{
		public static bool debugUnspecified = false;

		public static bool debugSpam = false;

		public static ManualLogSource LibraryLogger = new ManualLogSource("NaturalSelectionLib");

		private static Dictionary<Type, List<EnemyAI>> globalEnemyLists = new Dictionary<Type, List<EnemyAI>>();

		public static void UpdateListInsideDictionrary(Type instanceType, List<EnemyAI> list)
		{
			List<Type> list2 = new List<Type>();
			if (!globalEnemyLists.ContainsKey(instanceType))
			{
				globalEnemyLists.Add(instanceType, new List<EnemyAI>());
				if (debugSpam && debugUnspecified)
				{
					LibraryLogger.LogInfo((object)("/updateListInsideDictionary/ created new list for " + instanceType));
				}
			}
			else
			{
				globalEnemyLists[instanceType] = list;
				if (debugSpam && debugUnspecified)
				{
					LibraryLogger.LogInfo((object)("/updateListInsideDictionary/ updating list for " + instanceType));
				}
			}
			if (!list2.Contains(instanceType))
			{
				list2.Add(instanceType);
			}
		}

		public static void LibrarySetup(ManualLogSource importLogger, bool spammyLogs = false, bool Unspecified = false)
		{
			LibraryLogger = importLogger;
			debugSpam = spammyLogs;
			debugUnspecified = Unspecified;
		}

		public static string DebugStringHead(EnemyAI? __instance)
		{
			if (!Object.op_Implicit((Object)(object)__instance))
			{
				return "Unknown instance: ";
			}
			return ((__instance != null) ? ((Object)__instance).name : null) + ", ID: " + ((__instance != null) ? new int?(((Object)__instance).GetInstanceID()) : null) + ": ";
		}

		public static List<EnemyAI> GetCompleteList(EnemyAI instance, bool filterThemselves = true, int includeOrReturnTheDead = 0)
		{
			List<EnemyAI> spawnedEnemies = RoundManager.Instance.SpawnedEnemies;
			for (int i = 0; i < spawnedEnemies.Count; i++)
			{
				if ((Object)(object)spawnedEnemies[i] == (Object)(object)instance)
				{
					if (debugUnspecified && debugSpam)
					{
						LibraryLogger.LogWarning((object)(DebugStringHead(instance) + " Found itself in the list. Removing..."));
					}
					spawnedEnemies.RemoveAt(i);
				}
				else if (((object)spawnedEnemies[i]).GetType() == ((object)instance).GetType() && filterThemselves)
				{
					if (debugUnspecified && debugSpam)
					{
						LibraryLogger.LogWarning((object)(DebugStringHead(instance) + " Found its type in the list. Removing..."));
					}
					spawnedEnemies.RemoveAt(i);
				}
				else
				{
					if (!spawnedEnemies[i].isEnemyDead)
					{
						continue;
					}
					switch (includeOrReturnTheDead)
					{
					case 0:
						if (debugUnspecified && debugSpam)
						{
							LibraryLogger.LogInfo((object)(DebugStringHead(instance) + " Found dead enemy in the list. Removing..."));
						}
						spawnedEnemies.RemoveAt(i);
						break;
					case 1:
						if (debugUnspecified && debugSpam)
						{
							LibraryLogger.LogInfo((object)(DebugStringHead(instance) + " Found dead enemy in the list. Proceeding..."));
						}
						break;
					case 2:
						if (debugUnspecified && debugSpam)
						{
							LibraryLogger.LogInfo((object)(DebugStringHead(instance) + " Found living enemy in the list. Removing.."));
						}
						spawnedEnemies.RemoveAt(i);
						break;
					}
				}
			}
			return spawnedEnemies;
		}

		public static List<EnemyAI> GetOutsideEnemyList(List<EnemyAI> importEnemyList, EnemyAI instance)
		{
			List<EnemyAI> list = new List<EnemyAI>();
			foreach (EnemyAI importEnemy in importEnemyList)
			{
				if (importEnemy.isOutside && (Object)(object)importEnemy != (Object)(object)instance)
				{
					list.Add(importEnemy);
					if (debugUnspecified && debugSpam)
					{
						LibraryLogger.LogDebug((object)(DebugStringHead(instance) + " Added " + DebugStringHead(importEnemy) + "..."));
					}
				}
			}
			return list;
		}

		public static List<EnemyAI> GetInsideEnemyList(List<EnemyAI> importEnemyList, EnemyAI instance)
		{
			List<EnemyAI> list = new List<EnemyAI>();
			foreach (EnemyAI importEnemy in importEnemyList)
			{
				if (!importEnemy.isOutside && (Object)(object)importEnemy != (Object)(object)instance)
				{
					list.Add(importEnemy);
					if (debugUnspecified && debugSpam)
					{
						LibraryLogger.LogDebug((object)(DebugStringHead(instance) + " Added " + DebugStringHead(importEnemy) + "..."));
					}
				}
			}
			return list;
		}

		public static EnemyAI? FindClosestEnemy(List<EnemyAI> importEnemyList, EnemyAI? importClosestEnemy, EnemyAI __instance, bool includeTheDead = false)
		{
			//IL_0453: Unknown result type (might be due to invalid IL or missing references)
			//IL_0465: Unknown result type (might be due to invalid IL or missing references)
			//IL_0475: Unknown result type (might be due to invalid IL or missing references)
			//IL_0480: Unknown result type (might be due to invalid IL or missing references)
			//IL_04bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e1: 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_0575: Unknown result type (might be due to invalid IL or missing references)
			//IL_0580: Unknown result type (might be due to invalid IL or missing references)
			EnemyAI val = importClosestEnemy;
			foreach (EnemyAI importEnemy in importEnemyList)
			{
				if (debugUnspecified)
				{
					LibraryLogger.LogInfo((object)(DebugStringHead(__instance) + "/FindClosestEnemy/ item " + DebugStringHead(importEnemy) + " inside importEnemyList. IsEnemyDead: " + importEnemy.isEnemyDead));
				}
			}
			if (debugUnspecified && (Object)(object)importClosestEnemy != (Object)null)
			{
				LibraryLogger.LogInfo((object)(DebugStringHead(__instance) + "/FindClosestEnemy/ " + DebugStringHead(importClosestEnemy) + " inside importClosestEnemy. IsEnemyDead: " + importClosestEnemy.isEnemyDead));
			}
			if (debugUnspecified)
			{
				LibraryLogger.LogInfo((object)(DebugStringHead(__instance) + "/FindClosestEnemy/ " + DebugStringHead(__instance) + " inside instance."));
			}
			if (importEnemyList.Count < 1)
			{
				if (debugUnspecified)
				{
					LibraryLogger.LogWarning((object)(DebugStringHead(__instance) + "importEnemyList is empty!"));
				}
				if ((Object)(object)importClosestEnemy != (Object)null && importClosestEnemy.isEnemyDead)
				{
					if (!includeTheDead)
					{
						if (debugUnspecified && debugSpam)
						{
							LibraryLogger.LogError((object)(DebugStringHead(__instance) + DebugStringHead(importClosestEnemy) + " is dead and importEnemyList is empty! Setting importClosestEnemy to null..."));
						}
					}
					else if (debugUnspecified && debugSpam)
					{
						LibraryLogger.LogInfo((object)(DebugStringHead(__instance) + DebugStringHead(importClosestEnemy) + " is dead and importEnemyList is empty! The dead enemy will be included. "));
					}
				}
				return null;
			}
			for (int i = 0; i < importEnemyList.Count; i++)
			{
				if ((Object)(object)val == (Object)null)
				{
					if (debugUnspecified && debugSpam)
					{
						LibraryLogger.LogInfo((object)(DebugStringHead(__instance) + "No enemy assigned. Assigning new closestEnemy...."));
					}
					for (int j = i; j < importEnemyList.Count; j++)
					{
						if (importEnemyList[j].isEnemyDead && !includeTheDead)
						{
							if (debugUnspecified && debugSpam)
							{
								LibraryLogger.LogWarning((object)(DebugStringHead(__instance) + "Found dead enemy. Skipping...."));
							}
							continue;
						}
						if (debugUnspecified && debugSpam)
						{
							LibraryLogger.LogInfo((object)(DebugStringHead(__instance) + "New closestEnemy found!"));
						}
						val = importEnemyList[j];
						break;
					}
					continue;
				}
				if (val.isEnemyDead)
				{
					if (!includeTheDead)
					{
						if (debugUnspecified && debugSpam)
						{
							LibraryLogger.LogError((object)(DebugStringHead(__instance) + ", " + DebugStringHead(__instance) + " is dead! Assigning new tempClosestEnemy from importEnemyList..."));
						}
						val = importEnemyList[i];
						continue;
					}
					if (debugUnspecified && debugSpam)
					{
						LibraryLogger.LogInfo((object)(DebugStringHead(__instance) + DebugStringHead(importClosestEnemy) + " is dead! The dead enemy will be included. "));
					}
				}
				if ((Object)(object)val == (Object)(object)importEnemyList[i])
				{
					if (debugUnspecified && debugSpam)
					{
						LibraryLogger.LogWarning((object)(DebugStringHead(__instance) + ((object)importEnemyList[i])?.ToString() + ", ID: " + ((Object)importEnemyList[i]).GetInstanceID() + " is already assigned as closestEnemy"));
					}
				}
				else if ((Object)(object)importEnemyList[i] == (Object)null)
				{
					if (debugUnspecified)
					{
						LibraryLogger.LogError((object)(DebugStringHead(__instance) + "Enemy not found! Skipping..."));
					}
				}
				else if (Vector3.Distance(((Component)__instance).transform.position, ((Component)importEnemyList[i]).transform.position) < Vector3.Distance(((Component)__instance).transform.position, ((Component)val).transform.position))
				{
					val = importEnemyList[i];
					if (debugUnspecified && debugSpam)
					{
						LibraryLogger.LogDebug((object)(Vector3.Distance(((Component)__instance).transform.position, ((Component)importEnemyList[i]).transform.position) < Vector3.Distance(((Component)__instance).transform.position, ((Component)val).transform.position)));
					}
					if (debugUnspecified)
					{
						LibraryLogger.LogInfo((object)(DebugStringHead(__instance) + "Assigned " + ((object)importEnemyList[i])?.ToString() + ", ID: " + ((Object)importEnemyList[i]).GetInstanceID() + " as new closestEnemy. Distance: " + Vector3.Distance(((Component)__instance).transform.position, ((Component)val).transform.position)));
					}
				}
			}
			if (debugUnspecified && debugSpam)
			{
				LibraryLogger.LogWarning((object)(DebugStringHead(__instance) + "findClosestEnemy returning " + DebugStringHead(val)));
			}
			return val;
		}

		public static List<EnemyAI> FilterEnemyList(List<EnemyAI> importEnemyList, List<Type>? targetTypes, EnemyAI instance, bool inverseToggle = false, bool filterOutImmortal = true)
		{
			List<EnemyAI> list = new List<EnemyAI>();
			for (int i = 0; i < importEnemyList.Count; i++)
			{
				if ((Object)(object)importEnemyList[i] == (Object)(object)instance)
				{
					if (debugUnspecified)
					{
						LibraryLogger.LogWarning((object)(DebugStringHead(instance) + "Found itself in importEnemyList! Skipping..."));
					}
					continue;
				}
				if (targetTypes != null && ((!inverseToggle && targetTypes.Contains(((object)importEnemyList[i]).GetType())) || (inverseToggle && !targetTypes.Contains(((object)importEnemyList[i]).GetType()))))
				{
					if (debugUnspecified)
					{
						LibraryLogger.LogDebug((object)(DebugStringHead(instance) + "Enemy of type " + ((object)importEnemyList[i]).GetType()?.ToString() + " passed the filter. inverseToggle: " + inverseToggle));
					}
					list.Add(importEnemyList[i]);
				}
				else if (targetTypes != null && debugUnspecified && debugSpam && debugUnspecified)
				{
					LibraryLogger.LogInfo((object)(DebugStringHead(instance) + "Caught and filtered out Enemy of type " + ((object)importEnemyList[i]).GetType()));
				}
				if (filterOutImmortal && !importEnemyList[i].enemyType.canDie)
				{
					if (debugUnspecified)
					{
						LibraryLogger.LogInfo((object)(DebugStringHead(instance) + "Caught and filtered out immortal Enemy of type " + ((object)importEnemyList[i]).GetType()));
					}
				}
				else if (targetTypes == null)
				{
					list.Add(importEnemyList[i]);
					if (debugUnspecified)
					{
						LibraryLogger.LogInfo((object)(DebugStringHead(instance) + "TargetTypes is empty.  Added enemy of type " + ((object)importEnemyList[i]).GetType()?.ToString() + " to filteredList by default"));
					}
				}
			}
			return list;
		}

		public static Dictionary<EnemyAI, float> GetEnemiesInLOS(EnemyAI instance, List<EnemyAI> importEnemyList, float width = 45f, int importRange = 0, float proximityAwareness = -1f)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Invalid comparison between Unknown and I4
			//IL_019b: 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_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: Unknown result type (might be due to invalid IL or missing references)
			//IL_0237: Unknown result type (might be due to invalid IL or missing references)
			List<EnemyAI> list = new List<EnemyAI>();
			Dictionary<EnemyAI, float> tempDictionary = new Dictionary<EnemyAI, float>();
			float num = importRange;
			if (instance.isOutside && !instance.enemyType.canSeeThroughFog && (int)TimeOfDay.Instance.currentLevelWeather == 3)
			{
				num = Mathf.Clamp(importRange, 0, 30);
			}
			foreach (EnemyAI importEnemy in importEnemyList)
			{
				if (!((Object)(object)importEnemy != (Object)null))
				{
					continue;
				}
				if (debugUnspecified && debugSpam)
				{
					if (importEnemy.isEnemyDead)
					{
						LibraryLogger.LogInfo((object)(DebugStringHead(instance) + "/GetEnemiesInLOS/: " + ((object)importEnemy)?.ToString() + " is dead"));
					}
					LibraryLogger.LogInfo((object)(DebugStringHead(instance) + "/GetEnemiesInLOS/: Added " + ((object)importEnemy)?.ToString() + " to tempList"));
				}
				list.Add(importEnemy);
			}
			if (list != null && list.Count > 0)
			{
				for (int i = 0; i < list.Count; i++)
				{
					if ((Object)(object)list[i] == (Object)null)
					{
						if (debugUnspecified)
						{
							LibraryLogger.LogWarning((object)(DebugStringHead(instance) + "/GetEnemiesInLOS/: Enemy not found! Removing from tempList"));
						}
						list.RemoveAt(i);
						continue;
					}
					Vector3 position = ((Component)list[i]).transform.position;
					if (!(Vector3.Distance(position, instance.eye.position) < num) || Physics.Linecast(instance.eye.position, position, StartOfRound.Instance.collidersAndRoomMaskAndDefault, (QueryTriggerInteraction)1) || !instance.CheckLineOfSightForPosition(position, width, (int)num, proximityAwareness, instance.eye))
					{
						continue;
					}
					if (!tempDictionary.ContainsKey(list[i]))
					{
						tempDictionary.Add(list[i], Vector3.Distance(((Component)instance).transform.position, position));
						if (debugUnspecified && debugSpam && debugUnspecified)
						{
							LibraryLogger.LogDebug((object)(DebugStringHead(instance) + "/GetEnemiesInLOS/: Added " + ((object)list[i])?.ToString() + " to tempDictionary"));
						}
					}
					if (tempDictionary.ContainsKey(list[i]) && debugUnspecified && debugSpam && debugUnspecified)
					{
						LibraryLogger.LogWarning((object)(DebugStringHead(instance) + "/GetEnemiesInLOS/:" + ((object)list[i])?.ToString() + " is already in tempDictionary"));
					}
				}
			}
			if (tempDictionary.Count > 1)
			{
				tempDictionary.OrderBy<KeyValuePair<EnemyAI, float>, Dictionary<EnemyAI, float>.ValueCollection>((KeyValuePair<EnemyAI, float> value) => tempDictionary.Values);
				if (debugUnspecified)
				{
					foreach (KeyValuePair<EnemyAI, float> item in tempDictionary)
					{
						if (debugUnspecified && debugSpam)
						{
							LibraryLogger.LogDebug((object)(DebugStringHead(instance) + "/GetEnemiesInLOS/: Final list: " + tempDictionary[item.Key]));
						}
					}
				}
			}
			return tempDictionary;
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "fandovec03.NaturalSelectionLib";

		public const string PLUGIN_NAME = "NaturalSelectionLib";

		public const string PLUGIN_VERSION = "0.4.1-alpha3";
	}
}